Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ if ( oops_FOUND )
add_subdirectory( ioda-stats )
add_subdirectory( ioda-summary )
add_subdirectory( ioda-dump )
add_subdirectory(gsi_varbc)
add_subdirectory( gsi_varbc )
add_subdirectory( add_increment )
endif()
19 changes: 19 additions & 0 deletions src/add_increment/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
if(CMAKE_PROJECT_NAME)
set(serial_target_name "${CMAKE_PROJECT_NAME}_fv3jedi_add_increment.x")
set(ensemble_target_name "${CMAKE_PROJECT_NAME}_fv3jedi_ensemble_add_increment.x")
else()
set(serial_target_name "fv3jedi_add_increment.x")
set(ensemble_target_name "fv3jedi_ensemble_add_increment.x")
endif()

# AddIncrement
ecbuild_add_executable( TARGET ${serial_target_name}
SOURCES fv3jedi_add_increment.cc add_increment.h)
target_compile_features( ${serial_target_name} PUBLIC cxx_std_17)
target_link_libraries( ${serial_target_name} PUBLIC NetCDF::NetCDF_CXX oops fv3jedi)

# Ensemble AddIncrement
ecbuild_add_executable( TARGET ${ensemble_target_name}
SOURCES fv3jedi_ensemble_add_increment.cc add_increment.h)
target_compile_features( ${ensemble_target_name} PUBLIC cxx_std_17)
target_link_libraries( ${ensemble_target_name} PUBLIC NetCDF::NetCDF_CXX oops fv3jedi)
119 changes: 119 additions & 0 deletions src/add_increment/add_increment.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/*
* (C) Copyright 2026 NOAA
*
* This software is licensed under the terms of the Apache Licence Version 2.0
* which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
*/

#ifndef OOPS_RUNS_ADDINCREMENT_H_
#define OOPS_RUNS_ADDINCREMENT_H_

#include <string>
#include <vector>

#include "oops/base/Geometry.h"
#include "oops/base/Increment.h"
#include "oops/base/State.h"
#include "oops/base/Variables.h"
#include "oops/interface/VariableChange.h"
#include "oops/mpi/mpi.h"
#include "oops/runs/Application.h"
#include "oops/util/DateTime.h"
#include "oops/util/Duration.h"
#include "oops/util/Logger.h"

namespace dautils {

/// Application that adds an increment to a state and writes the sum to a file.
///
/// The increment may optionally be multiplied by a scaling factor and have a different resolution
/// than the state.
template <typename MODEL> class AddIncrement : public oops::Application {
typedef oops::Geometry<MODEL> Geometry_;
typedef oops::State<MODEL> State_;
typedef oops::Increment<MODEL> Increment_;
typedef oops::VariableChange<MODEL> VariableChange_;

public:
// -----------------------------------------------------------------------------
explicit AddIncrement(const eckit::mpi::Comm & comm = oops::mpi::world()) : Application(comm) {}
// -----------------------------------------------------------------------------
virtual ~AddIncrement() {}
// -----------------------------------------------------------------------------
int execute(const eckit::Configuration & fullConfig) const override {
// Setup resolution
const Geometry_ stateResol(eckit::LocalConfiguration(fullConfig, "state geometry"),
this->getComm());

const Geometry_ incResol(eckit::LocalConfiguration(fullConfig, "increment geometry"),
this->getComm());

// Read state
State_ xx(stateResol, eckit::LocalConfiguration(fullConfig, "state"));
oops::Log::test() << "State: " << xx << std::endl;

// Read increment
const eckit::LocalConfiguration incParams(fullConfig, "increment");
oops::Variables addedVars(incParams, "added variables");
Increment_ dx(incResol, addedVars, xx.validTime());
dx.read(incParams);
oops::Log::test() << "Increment: " << dx << std::endl;

// Scale increment
if (incParams.has("scaling factor")) {
dx *= incParams.getDouble("scaling factor");
oops::Log::test() << "Scaled the increment: " << dx << std::endl;
}

// Assertions on state versus increment
ASSERT(xx.validTime() == dx.validTime());

// Add increment to state
xx += dx;

// Optional variable change to recomputed chosen state variables in final state
// This is useful if, for example, the state has both delp and ps but the increment only has
// delp. Simple increment addition of just delp to the state would result in an incorrect ps
// value since ps is a function of delp. ps would need to be recalculated after the increment addition.
if ( fullConfig.has("variable change") ) {
// Setup variable change
const eckit::LocalConfiguration varChangeConfig(fullConfig, "variable change");
std::unique_ptr<VariableChange_> vc;
vc.reset(new VariableChange_(varChangeConfig, stateResol));

// Get additional variables to be derived by variable change
oops::Variables varsChanged(varChangeConfig, "recalculated variables");

// Save state variables with and without variable change variables
oops::Variables stateVarsReduced = xx.variables();
oops::Variables stateVarsExpanded = xx.variables();
stateVarsReduced -= varsChanged;
stateVarsExpanded += varsChanged;

// Change state to reduced set of variables
// This is necessary since a variable needs to be missing from the state in order
// for it to be computed by the final variable change.
vc->changeVar(xx, stateVarsReduced);

// Change variables to expanded set of variables
// This step actually computes the variables we want
vc->changeVar(xx, stateVarsExpanded);
}

// Write state
xx.write(eckit::LocalConfiguration(fullConfig, "output"));

oops::Log::test() << "State plus increment: " << xx << std::endl;

return 0;
}
// -----------------------------------------------------------------------------
private:
std::string appname() const override {
return "dautils::AddIncrement<" + MODEL::name() + ">";
}
// -----------------------------------------------------------------------------
};

} // namespace oops
#endif // OOPS_RUNS_ADDINCREMENT_H_
11 changes: 11 additions & 0 deletions src/add_increment/fv3jedi_add_increment.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include "add_increment.h"

#include "fv3jedi/Utilities/Traits.h"

#include "oops/runs/Run.h"

int main(int argc, char ** argv) {
oops::Run run(argc, argv);
dautils::AddIncrement<fv3jedi::Traits> addIncrement;
return run.execute(addIncrement);
}
12 changes: 12 additions & 0 deletions src/add_increment/fv3jedi_ensemble_add_increment.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include "add_increment.h"

#include "fv3jedi/Utilities/Traits.h"

#include "oops/runs/EnsembleApplication.h"
#include "oops/runs/Run.h"

int main(int argc, char ** argv) {
oops::Run run(argc, argv);
oops::EnsembleApplication<dautils::AddIncrement<fv3jedi::Traits>> addIncrement;
return run.execute(addIncrement);
}
Loading