11 #ifndef OOPS_BASE_MODELSPACECOVARIANCEBASE_H_
12 #define OOPS_BASE_MODELSPACECOVARIANCEBASE_H_
19 #include <boost/make_unique.hpp>
20 #include <boost/noncopyable.hpp>
21 #include <boost/ptr_container/ptr_vector.hpp>
22 #include <boost/range/adaptor/reversed.hpp>
24 #include "eckit/config/LocalConfiguration.h"
25 #include "eckit/exception/Exceptions.h"
32 #include "oops/util/AssociativeContainers.h"
33 #include "oops/util/Logger.h"
34 #include "oops/util/parameters/ConfigurationParameter.h"
35 #include "oops/util/parameters/HasParameters_.h"
36 #include "oops/util/parameters/OptionalParameter.h"
37 #include "oops/util/parameters/Parameters.h"
38 #include "oops/util/parameters/RequiredPolymorphicParameter.h"
39 #include "oops/util/Random.h"
61 template <
typename MODEL>
67 typedef typename boost::ptr_vector<LinearVariableChangeBase_>
ChvarVec_;
68 typedef typename ChvarVec_::iterator
iter_;
69 typedef typename ChvarVec_::const_iterator
icst_;
70 typedef typename ChvarVec_::const_reverse_iterator
ircst_;
76 const Geometry_ &,
const eckit::Configuration &);
95 template <
typename MODEL>
110 template <
typename MODEL>
115 ConfigurationParameter config{
this};
122 template <
typename MODEL>
137 template <
typename MODEL>
161 static std::unique_ptr<ModelSpaceCovarianceParametersBase<MODEL>>
createParameters(
162 const std::string &covarianceModel);
181 virtual std::unique_ptr<ModelSpaceCovarianceParametersBase<MODEL>>
makeParameters()
const = 0;
183 static std::map < std::string, CovarianceFactory<MODEL> * > &
getMakers() {
184 static std::map < std::string, CovarianceFactory<MODEL> * > makers_;
191 template<
class MODEL,
class COVAR>
195 typedef TParameters_IfAvailableElseFallbackType_t<
206 return new COVAR(resol, vars,
207 parametersOrConfiguration<HasParameters_<COVAR>::value>(stronglyTypedParams),
211 std::unique_ptr<ModelSpaceCovarianceParametersBase<MODEL>>
makeParameters()
const override {
212 return boost::make_unique<Parameters_>();
221 template <
typename MODEL>
223 if (getMakers().find(
name) != getMakers().end()) {
224 throw std::runtime_error(
name +
" already registered in covariance factory.");
226 getMakers()[
name] =
this;
231 template <
typename MODEL>
238 Log::trace() <<
"ModelSpaceCovarianceBase type = " <<
id << std::endl;
239 typename std::map<std::string, CovarianceFactory<MODEL>*>::iterator jcov = getMakers().find(
id);
240 if (jcov == getMakers().end()) {
241 Log::error() <<
id <<
" does not exist in CovarianceFactory." << std::endl;
242 Log::error() <<
"CovarianceFactory has " << getMakers().size() <<
" elements:" << std::endl;
244 jj = getMakers().begin(); jj != getMakers().end(); ++jj) {
245 Log::error() <<
"A " << jj->first <<
" B" << std::endl;
247 throw std::runtime_error(
id +
" does not exist in covariance factory.");
254 variableChange.variableChangeParameters;
255 if (variableChangeParameters.
inputVariables.value() != boost::none &&
258 if (!(vars_in == vars_out)) {
259 Log::error() <<
"Input variables: " << vars_in << std::endl;
260 Log::error() <<
"Output variables: " << vars_out << std::endl;
261 throw eckit::BadParameter(
"Sequence of variable changes is not consistent");
266 return (*jcov).second->make(parameters, resol, vars_in, xb, fg);
271 template <
typename MODEL>
273 const eckit::Configuration & conf,
278 parameters.validateAndDeserialize(conf);
284 template <
typename MODEL>
285 std::unique_ptr<ModelSpaceCovarianceParametersBase<MODEL>>
287 const std::string &
name) {
288 typename std::map<std::string, CovarianceFactory<MODEL>*>::iterator it =
289 getMakers().find(
name);
290 if (it == getMakers().end()) {
291 throw std::runtime_error(
name +
" does not exist in CovarianceFactory");
293 return it->second->makeParameters();
298 template <
typename MODEL>
306 bg, fg, resol, variableChange.variableChangeParameters));
313 template <
typename MODEL>
317 const eckit::Configuration & conf)
324 template <
typename MODEL>
327 if (chvars_.size()) {
328 this->doRandomize(dx);
330 for (
icst_ it = chvars_.begin(); it != chvars_.end(); ++it) {
331 dx = it->multiply(dx);
334 this->doRandomize(dx);
340 template <
typename MODEL>
343 if (chvars_.size()) {
345 std::unique_ptr<Increment_> dxchvarin(
new Increment_(dxi));
346 for (
ircst_ it = chvars_.rbegin(); it != chvars_.rend(); ++it) {
347 Increment_ dxchvarout = it->multiplyAD(*dxchvarin);
352 this->doMultiply(*dxchvarin, dxchvarout);
356 for (
icst_ it = chvars_.begin(); it != chvars_.end(); ++it) {
357 Increment_ dxchvarout = it->multiply(*dxchvarin);
362 this->doMultiply(dxi, dxo);
368 template <
typename MODEL>
371 if (chvars_.size()) {
373 std::unique_ptr<Increment_> dxchvarin(
new Increment_(dxi));
374 for (
ircst_ it = chvars_.rbegin(); it != chvars_.rend(); ++it) {
375 Increment_ dxchvarout = it->multiplyInverse(*dxchvarin);
380 this->doInverseMultiply(*dxchvarin, dxchvarout);
384 for (
icst_ it = chvars_.begin(); it != chvars_.end(); ++it) {
385 Increment_ dxchvarout = it->multiplyInverseAD(*dxchvarin);
390 this->doInverseMultiply(dxi, dxo);
396 template <
typename MODEL>
403 for (
size_t ie = 0; ie < randomizationSize_; ++ie) {
408 double rk_var =
static_cast<double>(ie)/
static_cast<double>(ie+1);
409 double rk_mean = 1.0/
static_cast<double>(ie+1);
410 variance.
axpy(rk_var, dxsq,
false);
411 mean.
axpy(rk_mean, dx,
false);
413 double rk_norm = 1.0/
static_cast<double>(randomizationSize_-1);
Geometry< MODEL > Geometry_
CovarMaker(const std::string &name)
ModelSpaceCovarianceBase< MODEL > * make(const ModelSpaceCovarianceParametersBase< MODEL > ¶ms, const Geometry_ &resol, const Variables &vars, const State_ &xb, const State_ &fg) override
TParameters_IfAvailableElseFallbackType_t< COVAR, GenericModelSpaceCovarianceParameters< MODEL > > Parameters_
std::unique_ptr< ModelSpaceCovarianceParametersBase< MODEL > > makeParameters() const override
virtual std::unique_ptr< ModelSpaceCovarianceParametersBase< MODEL > > makeParameters() const =0
Geometry< MODEL > Geometry_
static std::vector< std::string > getMakerNames()
Return the names of all covariance models that can be created by one of the registered makers.
CovarianceFactory(const std::string &name)
Register a maker able to create covariance models of type name.
virtual ModelSpaceCovarianceBase< MODEL > * make(const ModelSpaceCovarianceParametersBase< MODEL > &, const Geometry_ &, const Variables &, const State_ &, const State_ &)=0
virtual ~CovarianceFactory()=default
static std::unique_ptr< ModelSpaceCovarianceParametersBase< MODEL > > createParameters(const std::string &covarianceModel)
Create and return an instance of the subclass of ModelSpaceCovarianceParametersBase storing parameter...
static ModelSpaceCovarianceBase< MODEL > * create(const ModelSpaceCovarianceParametersBase< MODEL > &, const Geometry_ &, const Variables &, const State_ &, const State_ &)
Create and return a new covariance model.
static std::map< std::string, CovarianceFactory< MODEL > * > & getMakers()
A subclass of ModelSpaceCovarianceParametersBase storing the values of all options in a single Config...
Geometry class used in oops; subclass of interface class interface::Geometry.
Increment class used in oops.
LinearVariableChange factory.
Base class of classes storing parameters controlling specific linear variable changes.
OptionalParameter< Variables > outputVariables
OptionalParameter< Variables > inputVariables
Contains a polymorphic parameter holding an instance of a subclass of LinearVariableChangeParametersB...
ChvarVec_::const_reverse_iterator ircst_
Increment< MODEL > Increment_
virtual ~ModelSpaceCovarianceBase()
LinearVariableChangeBase< MODEL > LinearVariableChangeBase_
virtual void doMultiply(const Increment_ &, Increment_ &) const =0
boost::ptr_vector< LinearVariableChangeBase_ > ChvarVec_
void getVariance(Increment_ &) const
Geometry< MODEL > Geometry_
ModelSpaceCovarianceBase(const State_ &, const State_ &, const Geometry_ &, const ModelSpaceCovarianceParametersBase< MODEL > &)
ChvarVec_::const_iterator icst_
void randomize(Increment_ &) const
virtual void doInverseMultiply(const Increment_ &, Increment_ &) const =0
void inverseMultiply(const Increment_ &, Increment_ &) const
ChvarVec_::iterator iter_
virtual void doRandomize(Increment_ &) const =0
size_t randomizationSize_
void multiply(const Increment_ &, Increment_ &) const
Base class for classes storing parameters of a particular model-space error covariance implementation...
Parameter< std::vector< LinearVariableChangeParametersWrapper< MODEL > > > variableChanges
OptionalParameter< std::string > covarianceModel
Covariance model name.
Parameter< size_t > randomizationSize
Contains a polymorphic parameter holding an instance of a subclass of ModelSpaceCovarianceParametersB...
RequiredPolymorphicParameter< ModelSpaceCovarianceParametersBase< MODEL >, CovarianceFactory< MODEL > > covarianceParameters
State class used in oops; subclass of interface class interface::State.
void axpy(const double &w, const Increment &dx, const bool check=true)
void schur_product_with(const Increment &other)
Compute Schur product of this Increment with other, assign to this Increment.
void zero()
Zero out this Increment.
The namespace for the main oops code.