From 94faae82e8396bc9edb55bedea10ce45d1475397 Mon Sep 17 00:00:00 2001 From: Travis Sluka Date: Mon, 28 Aug 2023 13:01:06 -0600 Subject: [PATCH 1/3] change one 3dvar test, it will break --- test/testinput/3dvar_godas.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/test/testinput/3dvar_godas.yml b/test/testinput/3dvar_godas.yml index 1852d0d24..ebb8baf7b 100644 --- a/test/testinput/3dvar_godas.yml +++ b/test/testinput/3dvar_godas.yml @@ -192,7 +192,13 @@ cost function: obsfile: data_static/obs/prof.nc simulated variables: [waterTemperature] obs operator: - name: InsituTemperature + name: VertInterp + observation alias file: testinput/obsop_name_map.yml + variables: + - waterTemperature + vertical coordinate: sea_water_depth + observation vertical coordinate: depth + interpolation method: linear obs error: covariance model: diagonal obs filters: From 01bf1fb3defb36c16438883d9796e582a3ab4c34 Mon Sep 17 00:00:00 2001 From: Travis Sluka Date: Mon, 2 Oct 2023 15:27:30 -0600 Subject: [PATCH 2/3] add vader to linearvariable change --- .../LinearModel2GeoVaLs.F90 | 35 +++-- .../LinearVariableChange.cc | 120 ++++++++++++++++-- .../LinearVariableChange.h | 5 + 3 files changed, 140 insertions(+), 20 deletions(-) diff --git a/src/soca/LinearVariableChange/LinearModel2GeoVaLs/LinearModel2GeoVaLs.F90 b/src/soca/LinearVariableChange/LinearModel2GeoVaLs/LinearModel2GeoVaLs.F90 index 390db804d..c8ddfb8fb 100644 --- a/src/soca/LinearVariableChange/LinearModel2GeoVaLs/LinearModel2GeoVaLs.F90 +++ b/src/soca/LinearVariableChange/LinearModel2GeoVaLs/LinearModel2GeoVaLs.F90 @@ -46,18 +46,29 @@ subroutine soca_model2geovals_linear_changevar_f90(c_key_geom, c_key_dxin, c_key ! identity operators do i=1, size(dxout%fields) - call dxin%get(dxout%fields(i)%metadata%name, field) - if (dxout%fields(i)%name == field%metadata%name .or. & - dxout%fields(i)%name == field%metadata%getval_name) then - dxout%fields(i)%val(:,:,:) = field%val(:,:,:) !< full field - elseif (field%metadata%getval_name_surface == dxout%fields(i)%name) then - dxout%fields(i)%val(:,:,1) = field%val(:,:,1) !< surface only of a 3D field - - else - call abor1_ftn( 'error in soca_model2geovals_linear_changevar_f90 processing ' & - // dxout%fields(i)%name ) - endif - + select case (dxout%fields(i)%name) + case ( 'latitude' ) + dxout%fields(i)%val(:,:,1) = real(geom%lat, kind=kind_real) + + case ( 'longitude' ) + dxout%fields(i)%val(:,:,1) = real(geom%lon, kind=kind_real) + + case ( 'sea_water_depth') + call geom%thickness2depth(geom%h, dxout%fields(i)%val) + + case default + call dxin%get(dxout%fields(i)%metadata%name, field) + if (dxout%fields(i)%name == field%metadata%name .or. & + dxout%fields(i)%name == field%metadata%getval_name) then + dxout%fields(i)%val(:,:,:) = field%val(:,:,:) !< full field + elseif (field%metadata%getval_name_surface == dxout%fields(i)%name) then + dxout%fields(i)%val(:,:,1) = field%val(:,:,1) !< surface only of a 3D field + + else + call abor1_ftn( 'error in soca_model2geovals_linear_changevar_f90 processing ' & + // dxout%fields(i)%name ) + endif + end select end do end subroutine diff --git a/src/soca/LinearVariableChange/LinearVariableChange.cc b/src/soca/LinearVariableChange/LinearVariableChange.cc index f4ef49436..03b3e8e59 100644 --- a/src/soca/LinearVariableChange/LinearVariableChange.cc +++ b/src/soca/LinearVariableChange/LinearVariableChange.cc @@ -5,10 +5,12 @@ * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. */ +#include #include #include #include "soca/LinearVariableChange/LinearVariableChange.h" +#include "soca/VariableChange/Model2GeoVaLs/Model2GeoVaLs.h" #include "soca/Geometry/Geometry.h" #include "soca/Increment/Increment.h" @@ -22,10 +24,26 @@ namespace soca { // ----------------------------------------------------------------------------- +std::map> SocaLinVaderCookbook { + {"sea_water_temperature", {"SeaWaterTemperature_A"}}, +}; + +// ----------------------------------------------------------------------------- + LinearVariableChange::LinearVariableChange(const Geometry & geom, const eckit::Configuration & config) - : geom_(geom), params_(), linVarChas_() { + : geom_(geom), params_(), linVarChas_(), vader_(), default_(false) { params_.deserialize(config); + + // setup vader + eckit::LocalConfiguration vaderConfig, vaderCookbookConfig; + for (auto kv : SocaLinVaderCookbook) vaderCookbookConfig.set(kv.first, kv.second); + vaderConfig.set(vader::configCookbookKey, vaderCookbookConfig); + vader_.reset(new vader::Vader(params_.vader, vaderConfig)); + + const boost::optional> & + linVarChgs = params_.linearVariableChangesWrapper; + default_ = linVarChgs == boost::none; } // ----------------------------------------------------------------------------- @@ -36,14 +54,53 @@ LinearVariableChange::~LinearVariableChange() {} void LinearVariableChange::changeVarTraj(const State & xfg, const oops::Variables & vars) { - Log::trace() << "LinearVariableChange::setTrajectory starting" << std::endl; + Log::trace() << "LinearVariableChange::changeVarTraj starting, default: "<{ + "latitude", + "longitude", + "sea_water_potential_temperature", + "sea_water_salinity", + "sea_water_depth"}); + preVaderVars += xfg.variables(); + xfg2.updateFields(preVaderVars); + Model2GeoVaLs m2gv(xfg.geometry(), params_.toConfiguration()); + m2gv.changeVar(xfg, xfg2); + Log::debug() << "LinearVariableChange::changeVarTraj variables after var change: " + << xfg2.variables() << std::endl; + } - // TODO(travis): do something with vars? + // call Vader + // ---------------------------------------------------------------------------- + Log::debug() << "LinearVariableChange::changeVarTraj VADER variable changes. " << std::endl; + oops::Variables varsFilled = xfg2.variables(); + oops::Variables varsVader = vars; + varsVader -= varsFilled; // pass only the needed variables + atlas::FieldSet xfs; + xfg2.toFieldSet(xfs); + varsFilled += vader_->changeVarTraj(xfs, varsVader); + xfg2.updateFields(varsFilled); + xfg2.fromFieldSet(xfs); + Log::debug() << "LinearVariableChange::changeVarTraj variables after var change: " + << xfg2.variables() << std::endl; // TODO(travis): this is not ideal. We are saving the first trajectory and // assuming it is the background. This should all get ripped out when the // variable changes that rely on the background are dealt with properly. - if (!bkg_) { bkg_.reset(new State(xfg)); } + if (!bkg_) { bkg_.reset(new State(xfg2)); } const boost::optional> & linVarChgs = params_.linearVariableChangesWrapper; @@ -59,13 +116,13 @@ void LinearVariableChange::changeVarTraj(const State & xfg, linVarChaParWra.linearVariableChangeParameters; // Add linear variable change to vector linVarChas_.push_back( - LinearVariableChangeFactory::create(*bkg_, xfg, geom_, linVarChaPar)); + LinearVariableChangeFactory::create(*bkg_, xfg2, geom_, linVarChaPar)); } - } else { + } else { // No variable changes were specified, use the default (LinearModel2GeoVaLs) eckit::LocalConfiguration conf; conf.set("linear variable change name", "default"); - linVarChas_.push_back(LinearVariableChangeFactory::create(*bkg_, xfg, geom_, + linVarChas_.push_back(LinearVariableChangeFactory::create(*bkg_, xfg2, geom_, oops::validateAndDeserialize( conf))); } @@ -76,7 +133,54 @@ void LinearVariableChange::changeVarTraj(const State & xfg, void LinearVariableChange::changeVarTL(Increment & dx, const oops::Variables & vars) const { - Log::trace() << "LinearVariableChange::multiply starting" << std::endl; + Log::trace() << "LinearVariableChange::changeVarTL starting, default: " << default_ << std::endl; + + Log::debug() << "LinearVariableChange::changeVarTL vars in: " + << dx.variables() << std::endl; + Log::debug() << "LinearVariableChange::changeVarTL vars out: " + << vars << std::endl; + + + // The following is TEMPORARY. + // ---------------------------------------------------------------------------- + // We need to do some variable renaming BEFORE we run VADER. + // Eventually, we will internally rename these variables when they are + // first loaded in so that we won't have to worry about it here. + if (default_ && vars.has("sea_water_temperature")) { + Log::debug() << "LinearVariableChange::changeVarTL Pre-VADER variable changes. " << std::endl; + oops::Variables preVaderVars(std::vector{ + "latitude", + "longitude", + "sea_water_potential_temperature", + "sea_water_salinity", + "sea_water_depth"}); + preVaderVars += dx.variables(); + Increment preVader(dx.geometry(), preVaderVars, dx.time()); + + for (icst_ it = linVarChas_.begin(); it != linVarChas_.end(); ++it) { + it->multiply(dx, preVader); + dx.updateFields(preVaderVars); + dx = preVader; + } + Log::debug() << "LinearVariableChange::changeVarTL variables after var change: " + << dx.variables() << std::endl; + } + + + // call Vader + // ---------------------------------------------------------------------------- + Log::debug() << "LinearVariableChange::changeVarTL VADER variable changes. " << std::endl; + atlas::FieldSet xfs; + dx.toFieldSet(xfs); + oops::Variables varsFilled = dx.variables(); + oops::Variables varsVader = vars; + varsVader -= varsFilled; + varsFilled += vader_->changeVarTL(xfs, varsVader); + Log::debug() << "DBG " << varsFilled <> linearVariableChangesWrapper{"linear variable changes", this}; + oops::Parameter vader{"vader", {}, this}; }; // ----------------------------------------------------------------------------- @@ -68,6 +71,8 @@ class LinearVariableChange : public util::Printable { const Geometry & geom_; std::unique_ptr bkg_; LinVarChaVec_ linVarChas_; + std::unique_ptr vader_; + bool default_; }; // ----------------------------------------------------------------------------- From e30ac92d30e791fde7f35860ca6e979106a45c98 Mon Sep 17 00:00:00 2001 From: Travis Sluka Date: Tue, 3 Oct 2023 10:38:56 -0600 Subject: [PATCH 3/3] linearvariable change working for adjoint --- .../LinearModel2GeoVaLs.F90 | 13 ++-- .../LinearVariableChange.cc | 63 +++++++++++++------ .../LinearVariableChange.h | 2 + src/soca/VariableChange/VariableChange.cc | 3 +- 4 files changed, 55 insertions(+), 26 deletions(-) diff --git a/src/soca/LinearVariableChange/LinearModel2GeoVaLs/LinearModel2GeoVaLs.F90 b/src/soca/LinearVariableChange/LinearModel2GeoVaLs/LinearModel2GeoVaLs.F90 index c8ddfb8fb..7ba0e20bb 100644 --- a/src/soca/LinearVariableChange/LinearModel2GeoVaLs/LinearModel2GeoVaLs.F90 +++ b/src/soca/LinearVariableChange/LinearModel2GeoVaLs/LinearModel2GeoVaLs.F90 @@ -47,14 +47,17 @@ subroutine soca_model2geovals_linear_changevar_f90(c_key_geom, c_key_dxin, c_key ! identity operators do i=1, size(dxout%fields) select case (dxout%fields(i)%name) - case ( 'latitude' ) - dxout%fields(i)%val(:,:,1) = real(geom%lat, kind=kind_real) + ! TODO: These should NOT be needed in an increment. Need to make some changes to vader... + case ( 'sea_area_fraction' ) + dxout%fields(i)%val(:,:,1) = 0.0 + case ( 'latitude' ) + dxout%fields(i)%val(:,:,1) = 0.0 case ( 'longitude' ) - dxout%fields(i)%val(:,:,1) = real(geom%lon, kind=kind_real) - + dxout%fields(i)%val(:,:,1) = 0.0 case ( 'sea_water_depth') - call geom%thickness2depth(geom%h, dxout%fields(i)%val) + dxout%fields(i)%val(:,:,1) = 0.0 + ! call geom%thickness2depth(geom%h, dxout%fields(i)%val) case default call dxin%get(dxout%fields(i)%metadata%name, field) diff --git a/src/soca/LinearVariableChange/LinearVariableChange.cc b/src/soca/LinearVariableChange/LinearVariableChange.cc index 03b3e8e59..cbf49e8c1 100644 --- a/src/soca/LinearVariableChange/LinearVariableChange.cc +++ b/src/soca/LinearVariableChange/LinearVariableChange.cc @@ -74,7 +74,9 @@ void LinearVariableChange::changeVarTraj(const State & xfg, "longitude", "sea_water_potential_temperature", "sea_water_salinity", - "sea_water_depth"}); + "sea_water_depth", + "sea_area_fraction", + }); preVaderVars += xfg.variables(); xfg2.updateFields(preVaderVars); Model2GeoVaLs m2gv(xfg.geometry(), params_.toConfiguration()); @@ -91,7 +93,8 @@ void LinearVariableChange::changeVarTraj(const State & xfg, varsVader -= varsFilled; // pass only the needed variables atlas::FieldSet xfs; xfg2.toFieldSet(xfs); - varsFilled += vader_->changeVarTraj(xfs, varsVader); + varsVaderPopulates_ = vader_->changeVarTraj(xfs, varsVader); + varsFilled += varsVaderPopulates_; xfg2.updateFields(varsFilled); xfg2.fromFieldSet(xfs); Log::debug() << "LinearVariableChange::changeVarTraj variables after var change: " @@ -153,7 +156,8 @@ void LinearVariableChange::changeVarTL(Increment & dx, "longitude", "sea_water_potential_temperature", "sea_water_salinity", - "sea_water_depth"}); + "sea_water_depth", + "sea_area_fraction"}); preVaderVars += dx.variables(); Increment preVader(dx.geometry(), preVaderVars, dx.time()); @@ -176,21 +180,11 @@ void LinearVariableChange::changeVarTL(Increment & dx, oops::Variables varsVader = vars; varsVader -= varsFilled; varsFilled += vader_->changeVarTL(xfs, varsVader); - Log::debug() << "DBG " << varsFilled <{ + "sea_water_potential_temperature"}); + oops::Variables varsToDrop(std::vector{ + "sea_water_temperature"}); + + // run Vader + oops::Variables vaderVars = dx.variables(); + vaderVars += varsToAdj; + dx.updateFields(vaderVars); + + atlas::FieldSet xfs; + dx.toFieldSet(xfs); + + oops::Variables varsVaderWillAdjoint = varsVaderPopulates_; + vader_->changeVarAD(xfs, varsVaderWillAdjoint); + ASSERT(varsVaderWillAdjoint.size() == 0); + + vaderVars -= varsToDrop; + dx.updateFields(vaderVars); + dx.fromFieldSet(xfs); + Log::debug() << "LinearVariableChange::changeVarTL variables after var change: " + << dx.variables() << std::endl; + } + + Increment dxout(dx.geometry(), vars, dx.time()); // Call variable change(s) diff --git a/src/soca/LinearVariableChange/LinearVariableChange.h b/src/soca/LinearVariableChange/LinearVariableChange.h index bad638158..a54170f50 100644 --- a/src/soca/LinearVariableChange/LinearVariableChange.h +++ b/src/soca/LinearVariableChange/LinearVariableChange.h @@ -71,7 +71,9 @@ class LinearVariableChange : public util::Printable { const Geometry & geom_; std::unique_ptr bkg_; LinVarChaVec_ linVarChas_; + std::unique_ptr vader_; + oops::Variables varsVaderPopulates_; bool default_; }; diff --git a/src/soca/VariableChange/VariableChange.cc b/src/soca/VariableChange/VariableChange.cc index 34f899438..1d84139f7 100644 --- a/src/soca/VariableChange/VariableChange.cc +++ b/src/soca/VariableChange/VariableChange.cc @@ -76,7 +76,8 @@ void VariableChange::changeVar(State & x, const oops::Variables & vars) const { "longitude", "sea_water_potential_temperature", "sea_water_salinity", - "sea_water_depth"}); + "sea_water_depth", + "sea_area_fraction"}); preVaderVars += x.variables(); State preVader(x.geometry(), preVaderVars, x.time()); variableChange_->changeVar(x, preVader);