11 #ifndef OOPS_ASSIMILATION_COSTFUNCTION_H_ 12 #define OOPS_ASSIMILATION_COSTFUNCTION_H_ 17 #include <boost/noncopyable.hpp> 18 #include <boost/ptr_container/ptr_vector.hpp> 19 #include <boost/scoped_ptr.hpp> 20 #include <boost/shared_ptr.hpp> 22 #include "eckit/config/LocalConfiguration.h" 40 #include "oops/util/abor1_cpp.h" 41 #include "oops/util/DateTime.h" 42 #include "oops/util/dot_product.h" 43 #include "oops/util/Duration.h" 44 #include "oops/util/Logger.h" 56 template<
typename MODEL>
class CostFunction :
private boost::noncopyable {
74 const eckit::Configuration & config = eckit::LocalConfiguration(),
81 const bool idModel =
false)
const = 0;
84 const bool idModel =
false)
const = 0;
105 void setupTerms(
const eckit::Configuration &);
122 boost::scoped_ptr<const CtrlVar_>
xb_;
123 boost::scoped_ptr<JbTotal_>
jb_;
125 boost::ptr_vector<LinearModel_>
tlm_;
135 template <
typename MODEL>
149 static std::map < std::string, CostFactory<MODEL> * > &
getMakers() {
150 static std::map < std::string, CostFactory<MODEL> * > makers_;
155 template<
class MODEL,
class FCT>
162 {
return new FCT(config, resol,
model);}
172 template <
typename MODEL>
174 if (getMakers().find(
name) != getMakers().
end()) {
175 Log::error() <<
name <<
" already registered in cost function factory." << std::endl;
176 ABORT(
"Element already registered in CostFactory.");
178 getMakers()[
name] =
this;
183 template <
typename MODEL>
186 std::string
id = config.getString(
"cost_type");
187 Log::trace() <<
"Variational Assimilation Type=" <<
id << std::endl;
188 typename std::map<std::string, CostFactory<MODEL>*>::iterator
j = getMakers().find(
id);
189 if (
j == getMakers().
end()) {
190 Log::error() <<
id <<
" does not exist in cost function factory." << std::endl;
191 ABORT(
"Element does not exist in CostFactory.");
193 Log::trace() <<
"CostFactory::create found cost function type" << std::endl;
194 return (*j).second->make(config, resol,
model);
201 template<
typename MODEL>
204 : resol_(resol), model_(
model), jb_(), jterms_(), tlm_(), anvars_(config)
206 Log::trace() <<
"CostFunction:created" << std::endl;
211 template<
typename MODEL>
213 Log::trace() <<
"CostFunction::setupTerms start" << std::endl;
216 eckit::LocalConfiguration joconf(config,
"Jo");
218 jterms_.push_back(jo);
219 Log::trace() <<
"CostFunction::setupTerms Jo added" << std::endl;
222 const eckit::LocalConfiguration jbConf(config,
"Jb");
223 xb_.reset(
new CtrlVar_(eckit::LocalConfiguration(jbConf,
"Background"), anvars_, resol_));
224 jb_.reset(
new JbTotal_(*xb_, this->newJb(jbConf, resol_, *xb_), jbConf, resol_));
225 Log::trace() <<
"CostFunction::setupTerms Jb added" << std::endl;
228 std::vector<eckit::LocalConfiguration> jcs;
229 config.get(
"Jc", jcs);
230 for (
size_t jj = 0; jj < jcs.size(); ++jj) {
232 jterms_.push_back(jc);
234 Log::trace() <<
"CostFunction::setupTerms done" << std::endl;
239 template<
typename MODEL>
241 const eckit::Configuration & config,
243 Log::trace() <<
"CostFunction::evaluate start" << std::endl;
248 for (
unsigned jj = 0; jj < jterms_.size(); ++jj) {
254 this->runNL(mfguess, pp);
257 eckit::LocalConfiguration diagnostic;
258 if (config.has(
"diagnostics")) {
259 diagnostic = eckit::LocalConfiguration(config,
"diagnostics");
262 costJb_ = jb_->finalize(jq);
265 for (
unsigned jj = 0; jj < jterms_.size(); ++jj) {
266 costJoJc_ += jterms_[jj].finalize(diagnostic);
269 Log::test() <<
"CostFunction: Nonlinear J = " << zzz << std::endl;
270 Log::trace() <<
"CostFunction::evaluate done" << std::endl;
276 template<
typename MODEL>
278 const eckit::Configuration & innerConf,
280 Log::trace() <<
"CostFunction::linearize start" << std::endl;
282 const eckit::LocalConfiguration resConf(innerConf,
"resolution");
289 for (
unsigned jj = 0; jj < jterms_.size(); ++jj) {
290 pptraj.
enrollProcessor(jterms_[jj].initializeTraj(fguess, lowres, innerConf));
295 const eckit::LocalConfiguration tlmConf(innerConf,
"linearmodel");
301 double zzz = this->evaluate(fguess, innerConf, pp);
304 jb_->finalizeTraj(jq);
305 for (
unsigned jj = 0; jj < jterms_.size(); ++jj) {
306 jterms_[jj].finalizeTraj();
310 this->doLinearize(lowres, innerConf, *xb_, fguess);
312 Log::trace() <<
"CostFunction::linearize done" << std::endl;
318 template<
typename MODEL>
320 Log::trace() <<
"CostFunction::computeGradientFG start" << std::endl;
325 for (
unsigned jj = 0; jj < jterms_.size(); ++jj) {
326 boost::shared_ptr<const GeneralizedDepartures>
tmp(jterms_[jj].newGradientFG());
330 this->runADJ(grad, costad, pp);
331 Log::trace() <<
"CostFunction::computeGradientFG done" << std::endl;
336 template<
typename MODEL>
339 Log::trace() <<
"CostFunction::addIncrement start" << std::endl;
340 Log::info() <<
"CostFunction::addIncrement: First guess:" << xx << std::endl;
341 Log::info() <<
"CostFunction::addIncrement: Increment:" << dx << std::endl;
345 this->addIncr(xx, dx, post);
347 Log::info() <<
"CostFunction::addIncrement: Analysis: " << xx << std::endl;
348 Log::test() <<
"CostFunction::addIncrement: Analysis: " << xx << std::endl;
349 Log::trace() <<
"CostFunction::addIncrement done" << std::endl;
354 template<
typename MODEL>
356 Log::trace() <<
"CostFunction::resetLinearization start" << std::endl;
357 for (
unsigned jj = 0; jj < jterms_.size(); ++jj) {
358 jterms_[jj].resetLinearization();
361 Log::trace() <<
"CostFunction::resetLinearization done" << std::endl;
368 #endif // OOPS_ASSIMILATION_COSTFUNCTION_H_
CostTermBase< MODEL > CostBase_
const JbTotal_ & jb() const
Access .
virtual CostJbState< MODEL > * newJb(const eckit::Configuration &, const Geometry_ &, const CtrlVar_ &) const =0
boost::ptr_vector< LinearModel_ > tlm_
void addIncrement(CtrlVar_ &, const CtrlInc_ &, PostProcessor< Increment_ > post=PostProcessor< Increment_ >()) const
CostMaker(const std::string &name)
double linearize(const CtrlVar_ &, const eckit::Configuration &, PostProcessor< State_ > post=PostProcessor< State_ >())
virtual CostTermBase< MODEL > * newJc(const eckit::Configuration &, const Geometry_ &) const =0
LinearModel< MODEL > LinearModel_
boost::ptr_vector< CostBase_ > jterms_
ObsAuxIncr_ & obsVar()
Get augmented observation control variable.
ModelAuxIncr_ & modVar()
Get augmented model control variable.
************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! MPP_TRANSMIT !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! subroutine MPP_TRANSMIT_(put_data, put_len, to_pe, get_data, get_len, from_pe, block, tag, recv_request, send_request)!a message-passing routine intended to be reminiscent equally of both MPI and SHMEM!put_data and get_data are contiguous MPP_TYPE_ arrays!at each call, your put_data array is put to to_pe 's get_data! your get_data array is got from from_pe 's put_data!i.e we assume that typically(e.g updating halo regions) each PE performs a put _and_ a get!special PE designations:! NULL_PE:to disable a put or a get(e.g at boundaries)! ANY_PE:if remote PE for the put or get is to be unspecific! ALL_PES:broadcast and collect operations(collect not yet implemented)!ideally we would not pass length, but this f77-style call performs better(arrays passed by address, not descriptor)!further, this permits< length > contiguous words from an array of any rank to be passed(avoiding f90 rank conformance check)!caller is responsible for completion checks(mpp_sync_self) before and after integer, intent(in) ::put_len, to_pe, get_len, from_pe MPP_TYPE_, intent(in) ::put_data(*) MPP_TYPE_, intent(out) ::get_data(*) logical, intent(in), optional ::block integer, intent(in), optional ::tag integer, intent(out), optional ::recv_request, send_request logical ::block_comm integer ::i MPP_TYPE_, allocatable, save ::local_data(:) !local copy used by non-parallel code(no SHMEM or MPI) integer ::comm_tag integer ::rsize if(.NOT.module_is_initialized) call mpp_error(FATAL, 'MPP_TRANSMIT:You must first call mpp_init.') if(to_pe.EQ.NULL_PE .AND. from_pe.EQ.NULL_PE) return block_comm=.true. if(PRESENT(block)) block_comm=block if(debug) then call SYSTEM_CLOCK(tick) write(stdout_unit,'(a, i18, a, i6, a, 2i6, 2i8)')&'T=', tick, ' PE=', pe, ' MPP_TRANSMIT begin:to_pe, from_pe, put_len, get_len=', to_pe, from_pe, put_len, get_len end if comm_tag=DEFAULT_TAG if(present(tag)) comm_tag=tag!do put first and then get if(to_pe.GE.0 .AND. to_pe.LT.npes) then!use non-blocking sends if(debug .and.(current_clock.NE.0)) call SYSTEM_CLOCK(start_tick)!z1l:truly non-blocking send.! if(request(to_pe).NE.MPI_REQUEST_NULL) then !only one message from pe-> to_pe in queue *PE waiting for to_pe ! call error else get_len so only do gets but you cannot have a pure get with MPI call a get means do a wait to ensure put on remote PE is complete error call increase mpp_nml request_multiply call MPP_TRANSMIT end
const LinearModel_ & getTLM(const unsigned isub=0) const
CostFunction< MODEL > * make(const eckit::Configuration &config, const Geometry_ &resol, const Model_ &model) override
virtual void runTLM(CtrlInc_ &, PostProcessorTLAD< MODEL > &, PostProcessor< Increment_ > post=PostProcessor< Increment_ >(), const bool idModel=false) const =0
Encapsulates the model state.
Save trajectory during forecast run.
Geometry< MODEL > Geometry_
l_size ! loop over number of fields ke do j
void computeGradientFG(CtrlInc_ &) const
Compute cost function gradient at first guess (without Jb).
const Model_ & getModel() const
The namespace for the main oops code.
virtual void runADJ(CtrlInc_ &, PostProcessorTLAD< MODEL > &, PostProcessor< Increment_ > post=PostProcessor< Increment_ >(), const bool idModel=false) const =0
JqTermTLAD< MODEL > JqTermTLAD_
Geometry< MODEL > Geometry_
Increment< MODEL > Increment_
ModelAux_ & modVar()
Get augmented model control variable.
subroutine, private initialize
Geometry< MODEL > Geometry_
subroutine, public info(self)
Control variable increment.
Control model post processing.
Encapsulates the nonlinear forecast model.
void enrollProcessor(PostBaseTLAD_ *pp)
boost::scoped_ptr< const CtrlVar_ > xb_
Jb Cost Function Base Class.
static std::map< std::string, CostFactory< MODEL > *> & getMakers()
virtual CostJo< MODEL > * newJo(const eckit::Configuration &) const =0
const double getCostJb() const
CostJbTotal< MODEL > JbTotal_
CostFunction(const eckit::Configuration &, const Geometry_ &, const Model_ &)
ControlVariable< MODEL > CtrlVar_
Increment Class: Difference between two states.
Base Class for Cost Function Terms.
virtual void addIncr(CtrlVar_ &, const CtrlInc_ &, PostProcessor< Increment_ > &) const =0
boost::scoped_ptr< JbTotal_ > jb_
virtual void doLinearize(const Geometry_ &, const eckit::Configuration &, const CtrlVar_ &, const CtrlVar_ &)=0
void resetLinearization()
ControlIncrement< MODEL > CtrlInc_
Control model post processing.
const double getCostJoJc() const
static CostFunction< MODEL > * create(const eckit::Configuration &, const Geometry_ &, const Model_ &)
virtual CostFunction< MODEL > * make(const eckit::Configuration &, const Geometry_ &, const Model_ &)=0
void initialize(const FLDS &xx, const util::DateTime &end, const util::Duration &tstep)
Setup.
double evaluate(const CtrlVar_ &, const eckit::Configuration &config=eckit::LocalConfiguration(), PostProcessor< State_ > post=PostProcessor< State_ >()) const
CostFactory(const std::string &)
void initializeTraj(const State_ &xx, const util::DateTime &end, const util::Duration &step)
Set linearization state.
void setupTerms(const eckit::Configuration &)
Encapsulates the linear forecast model.
ObsAuxCtrl_ & obsVar()
Get augmented observation control variable.
virtual void runNL(CtrlVar_ &, PostProcessor< State_ > &) const =0
void enrollProcessor(PostBase_ *pp)
const CostBase_ & jterm(const unsigned ii) const
Access terms of the cost function other than .
virtual void zeroAD(CtrlInc_ &) const =0