Go to the documentation of this file.
8 #ifndef OOPS_ASSIMILATION_LOCALENSEMBLESOLVER_H_
9 #define OOPS_ASSIMILATION_LOCALENSEMBLESOLVER_H_
15 #include "eckit/config/LocalConfiguration.h"
27 #include "oops/util/Logger.h"
28 #include "oops/util/Timer.h"
33 template <
typename MODEL,
typename OBS>
48 static const std::string
classname() {
return "oops::LocalEnsembleSolver";}
52 const eckit::Configuration & config,
size_t nens);
77 template <
typename MODEL,
typename OBS>
80 const eckit::Configuration & config,
size_t nens)
81 : obsconf_(config), obspaces_(obspaces),
82 hofx_(obspaces, geometry, config),
83 omb_(obspaces_), Yb_(obspaces_, nens)
89 template <
typename MODEL,
typename OBS>
91 size_t iteration,
bool readFromDisk) {
92 util::Timer timer(classname(),
"computeHofX");
94 ASSERT(ens_xx.
size() == Yb_.size());
96 const size_t nens = ens_xx.
size();
98 std::shared_ptr<QCData_> qc;
102 Log::debug() <<
"Read H(X) from disk" << std::endl;
103 for (
size_t jj = 0; jj < nens; ++jj) {
104 obsens[jj].read(
"hofx"+std::to_string(iteration)+
"_"+std::to_string(jj+1));
105 Log::test() <<
"H(x) for member " << jj+1 <<
":" << std::endl << obsens[jj] << std::endl;
107 qc.reset(
new QCData_(obspaces_,
"EffectiveQC",
"EffectiveError"));
111 Log::debug() <<
"Computing H(X) online" << std::endl;
112 for (
size_t jj = 0; jj < nens; ++jj) {
113 obsens[jj] = hofx_.compute(ens_xx[jj]);
114 Log::test() <<
"H(x) for member " << jj+1 <<
":" << std::endl << obsens[jj] << std::endl;
115 obsens[jj].save(
"hofx"+std::to_string(iteration)+
"_"+std::to_string(jj+1));
120 hofx_.saveQcFlags(
"EffectiveQC");
121 hofx_.maskObsErrors(*qc);
122 hofx_.saveObsErrors(
"EffectiveError");
129 for (
size_t iens = 0; iens < nens; ++iens) {
130 Yb_[iens] = obsens[iens] - yb_mean;
136 omb_ = yobs - yb_mean;
145 template <
typename MODEL,
typename OBS>
150 for (
size_t itime=0; itime < bkg_pert[0].
size(); ++itime) {
151 for (
size_t iens=0; iens < bkg_pert.
size(); ++iens) {
153 ana_pert[iens][itime].setLocal(gp, i);
161 template <
typename MODEL,
typename OBS>
167 const eckit::Configuration &,
174 const eckit::Configuration &,
size_t) = 0;
175 static std::map < std::string, LocalEnsembleSolverFactory<MODEL, OBS> * > &
getMakers() {
176 static std::map < std::string, LocalEnsembleSolverFactory<MODEL, OBS> * > makers_;
183 template<
class MODEL,
class OBS,
class T>
189 const eckit::Configuration & conf,
size_t nens)
190 {
return new T(obspaces, geometry, conf, nens); }
198 template <
typename MODEL,
typename OBS>
200 if (getMakers().find(name) != getMakers().end()) {
201 throw std::runtime_error(name +
" already registered in local ensemble solver factory.");
203 getMakers()[name] =
this;
208 template <
typename MODEL,
typename OBS>
209 std::unique_ptr<LocalEnsembleSolver<MODEL, OBS>>
211 const eckit::Configuration & conf,
size_t nens) {
212 Log::trace() <<
"LocalEnsembleSolver<MODEL, OBS>::create starting" << std::endl;
213 const std::string
id = conf.getString(
"local ensemble DA.solver");
214 typename std::map<std::string, LocalEnsembleSolverFactory<MODEL, OBS>*>::iterator
215 jloc = getMakers().find(
id);
216 if (jloc == getMakers().end()) {
217 Log::error() <<
id <<
" does not exist in local ensemble solver factory." << std::endl;
218 Log::error() <<
"LETKF solver Factory has " << getMakers().size() <<
" elements:" << std::endl;
220 jj = getMakers().begin(); jj != getMakers().end(); ++jj) {
221 Log::error() <<
"A " << jj->first <<
" LocalEnsembleSolver" << std::endl;
223 throw std::runtime_error(
id +
" does not exist in local ensemble solver factory.");
225 std::unique_ptr<LocalEnsembleSolver<MODEL, OBS>>
226 ptr(jloc->second->make(obspaces, geometry, conf, nens));
227 Log::trace() <<
"LocalEnsembleSolver<MODEL, OBS>::create done" << std::endl;
234 #endif // OOPS_ASSIMILATION_LOCALENSEMBLESOLVER_H_
The namespace for the main oops code.
CalcHofX< MODEL, OBS > CalcHofX_
container for QC-related things (flags & obserrors)
const ObsSpaces_ & obspaces_
ObsEnsemble< OBS > ObsEnsemble_
factory for LETKF solvers
Computes observation operator (while running model, or with State4D)
ObsSpaces< OBS > ObsSpaces_
static std::unique_ptr< LocalEnsembleSolver< MODEL, OBS > > create(ObsSpaces_ &, const Geometry_ &, const eckit::Configuration &, size_t)
IncrementEnsemble4D< MODEL > IncrementEnsemble4D_
unsigned int size() const
Accessors.
Observations< OBS > Observations_
GeometryIterator< MODEL > GeometryIterator_
Geometry< MODEL > Geometry_
static std::map< std::string, LocalEnsembleSolverFactory< MODEL, OBS > * > & getMakers()
ObsSpaces< OBS > ObsSpaces_
Departures< OBS > Departures_
virtual void measurementUpdate(const IncrementEnsemble4D_ &bg, const GeometryIterator_ &i, IncrementEnsemble4D_ &an)=0
update background ensemble bg to analysis ensemble an at a grid point location i
Base class for LETKF-type solvers.
LocalEnsembleSolver(ObsSpaces_ &obspaces, const Geometry_ &geometry, const eckit::Configuration &config, size_t nens)
initialize solver with obspaces, geometry, full config and nens ensemble size
Difference between two observation vectors.
static const std::string classname()
virtual LocalEnsembleSolver< MODEL, OBS > * make(ObsSpaces_ &, const Geometry_ &, const eckit::Configuration &, size_t)=0
StateEnsemble4D< MODEL > StateEnsemble4D_
DeparturesEnsemble< OBS > DeparturesEnsemble_
Geometry< MODEL > Geometry_
virtual void copyLocalIncrement(const IncrementEnsemble4D_ &bg, const GeometryIterator_ &i, IncrementEnsemble4D_ &an) const
copy an[i] = bg i \a
virtual Observations_ computeHofX(const StateEnsemble4D_ &xx, size_t iteration, bool readFromDisk)
computes ensemble H(xx), returns mean H(xx), saves as hofx iteration
unsigned int size() const
Accessors.
Ensemble of 4D inrements.
Geometry class used in oops; subclass of interface class above.
Ensemble of observations (can hold ensemble of H(x))
Geometry< MODEL > Geometry_
Ensemble of Departures (can hold ensemble perturbations in the observation space)
LocalEnsembleSolverFactory(const std::string &)
virtual ~LocalEnsembleSolver()=default
const eckit::LocalConfiguration obsconf_
Observations_ mean() const
Compute ensemble mean.
LocalEnsembleSolverMaker(const std::string &name)
virtual ~LocalEnsembleSolverFactory()=default
virtual LocalEnsembleSolver< MODEL, OBS > * make(ObsSpaces_ &obspaces, const Geometry_ &geometry, const eckit::Configuration &conf, size_t nens)
ObsSpaces< OBS > ObsSpaces_