11 #ifndef OOPS_ASSIMILATION_COSTFCTWEAK_H_ 12 #define OOPS_ASSIMILATION_COSTFCTWEAK_H_ 16 #include "eckit/config/LocalConfiguration.h" 31 #include "oops/util/DateTime.h" 32 #include "oops/util/Duration.h" 33 #include "oops/util/Logger.h" 60 const bool idModel =
false)
const override;
63 const bool idModel =
false)
const override;
92 template<
typename MODEL>
96 tlforcing_(
false), ctlvars_(config), an2model_()
98 windowLength_ = util::Duration(config.getString(
"window_length"));
99 windowBegin_ = util::DateTime(config.getString(
"window_begin"));
101 windowSub_ = util::Duration(config.getString(
"window_sub"));
106 if (config.has(
"tlforcing")) {
107 if (config.getString(
"tlforcing") ==
"on")
tlforcing_ =
true;
111 Log::trace() <<
"CostFctWeak constructed" << std::endl;
116 template <
typename MODEL>
120 return new CostJbJq<MODEL>(jbConf, resol, ctlvars_, windowSub_,
xb.state(), tlforcing_);
125 template <
typename MODEL>
127 return new CostJo<MODEL>(joConf, windowBegin_, windowEnd_, util::Duration(0),
true);
132 template <
typename MODEL>
135 const eckit::LocalConfiguration jcdfi(jcConf,
"jcdfi");
136 const util::DateTime
vt(windowBegin_ + windowLength_/2);
142 template <
typename MODEL>
145 State_ xm(xx.
state()[0].geometry(), CostFct_::getModel().variables(), windowBegin_);
146 for (
unsigned int jsub = 0; jsub < nsubwin_; ++jsub) {
147 util::DateTime bgn(windowBegin_ + jsub*windowSub_);
148 util::DateTime
end(bgn + windowSub_);
150 ASSERT(xx.
state()[jsub].validTime() == bgn);
151 xm = xx.
state()[jsub];
152 CostFct_::getModel().forecast(xm, xx.
modVar(), windowSub_, post);
153 xx.
state()[jsub] = xm;
154 ASSERT(xx.
state()[jsub].validTime() ==
end);
160 template<
typename MODEL>
162 const eckit::Configuration & innerConf,
164 Log::trace() <<
"CostFctWeak::doLinearize start" << std::endl;
165 eckit::LocalConfiguration
conf(innerConf,
"linearmodel");
168 an2model_->setInputVariables(ctlvars_);
169 an2model_->setOutputVariables(CostFct_::getTLM().variables());
170 Log::trace() <<
"CostFctWeak::doLinearize done" << std::endl;
175 template <
typename MODEL>
179 const bool idModel)
const {
183 util::DateTime bgn(windowBegin_ + jsub*windowSub_);
184 util::DateTime
end(bgn + windowSub_);
186 ASSERT(dx.
state()[jsub].validTime() == bgn);
187 if (tlforcing_ && jsub > 0) dx.
state()[jsub] += dx.
state()[jsub-1];
188 an2model_->multiply(dx.
state()[jsub], dxmodel);
189 CostFct_::getTLM(jsub).forecastTL(dxmodel, dx.
modVar(), windowSub_, post, cost, idModel);
190 an2model_->multiplyInverse(dxmodel, dx.
state()[jsub]);
191 ASSERT(dx.
state()[jsub].validTime() ==
end);
197 template <
typename MODEL>
205 util::DateTime bgn(windowBegin_ + jsub*windowSub_);
206 util::DateTime
end(bgn + windowSub_);
207 ASSERT(dx.
state()[jsub].validTime() == bgn);
210 dx.
state()[jsub].updateTime(windowSub_);
212 an2model_->multiply(dx.
state()[jsub], dxmodel);
213 CostFct_::getTLM(jsub).forecastTL(dxmodel, dx.
modVar(), windowSub_, post, cost);
214 an2model_->multiplyInverse(dxmodel, dx.
state()[jsub]);
217 ASSERT(dx.
state()[jsub].validTime() ==
end);
225 template <
typename MODEL>
228 util::DateTime
end(windowBegin_ + (jsub+1)*windowSub_);
237 template <
typename MODEL>
241 const bool idModel)
const {
244 util::DateTime bgn(windowBegin_ + jsub*windowSub_);
245 util::DateTime
end(bgn + windowSub_);
247 ASSERT(dx.
state()[jsub].validTime() ==
end);
248 an2model_->multiplyInverseAD(dx.
state()[jsub], dxmodel);
249 CostFct_::getTLM(jsub).forecastAD(dxmodel, dx.
modVar(), windowSub_, post, cost, idModel);
250 an2model_->multiplyAD(dxmodel, dx.
state()[jsub]);
251 if (tlforcing_ && jsub > 0) dx.
state()[jsub-1] += dx.
state()[jsub];
252 ASSERT(dx.
state()[jsub].validTime() == bgn);
258 template <
typename MODEL>
268 util::DateTime bgn(windowBegin_ + jsub*windowSub_);
269 util::DateTime
end(bgn + windowSub_);
270 ASSERT(dx.
state()[jsub].validTime() ==
end);
273 dx.
state()[jsub].updateTime(-windowSub_);
275 an2model_->multiplyInverseAD(dx.
state()[jsub], dxmodel);
276 CostFct_::getTLM(jsub).forecastAD(dxmodel, dx.
modVar(), windowSub_, post, cost);
277 an2model_->multiplyAD(dxmodel, dx.
state()[jsub]);
280 ASSERT(dx.
state()[jsub].validTime() == bgn);
286 template<
typename MODEL>
292 for (
unsigned int jsub = 0; jsub < nsubwin_; ++jsub) {
293 if (jsub > 0) xi += dx.
state()[jsub];
294 xx.
state()[jsub] += xi;
295 if (jsub < nsubwin_-1) {
296 an2model_->multiply(xi, dxmodel);
297 CostFct_::getTLM(jsub).forecastTL(dxmodel, dx.
modVar(), windowSub_, post);
298 an2model_->multiplyInverse(dxmodel, xi);
302 for (
unsigned int jsub = 0; jsub < nsubwin_; ++jsub) {
312 #endif // OOPS_ASSIMILATION_COSTFCTWEAK_H_
CostJo< MODEL > * newJo(const eckit::Configuration &) const override
State4D_ & state()
Get state control variable.
util::Duration windowSub_
void zeroAD(CtrlInc_ &) const override
boost::scoped_ptr< ChangeVar_ > an2model_
util::Duration windowLength_
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
void addIncr(CtrlVar_ &, const CtrlInc_ &, PostProcessor< Increment_ > &) const override
CostFunction< MODEL > CostFct_
Encapsulates the model state.
integer(long), parameter false
LinearVariableChangeBase< MODEL > ChangeVar_
Geometry< MODEL > Geometry_
The namespace for the main oops code.
ModelAux_ & modVar()
Get augmented model control variable.
void runTLM(CtrlInc_ &, PostProcessorTLAD< MODEL > &, PostProcessor< Increment_ >, const bool idModel=false) const override
CostFctWeak(const eckit::Configuration &, const Geometry_ &, const Model_ &)
real, dimension(:,:,:), allocatable vt
Weak Constraint 4D-Var Cost Function.
Increment4D_ & state()
Get state control variable.
void runADJ(CtrlInc_ &, PostProcessorTLAD< MODEL > &, PostProcessor< Increment_ >, const bool idModel=false) const override
void doLinearize(const Geometry_ &, const eckit::Configuration &, const CtrlVar_ &, const CtrlVar_ &) override
void runNL(CtrlVar_ &, PostProcessor< State_ > &) const override
LinearVariableChangeFactory Factory.
Control model post processing.
Base class for generic variable transform.
Encapsulates the nonlinear forecast model.
CostJbJq< MODEL > * newJb(const eckit::Configuration &, const Geometry_ &, const CtrlVar_ &) const override
Increment Class: Difference between two states.
Base Class for Cost Function Terms.
Geometry_ geometry() const
Get geometry.
Increment< MODEL > Increment_
ControlVariable< MODEL > CtrlVar_
Control model post processing.
ControlIncrement< MODEL > CtrlInc_
void setupTerms(const eckit::Configuration &)
util::DateTime windowBegin_
void shift_forward()
To be removed.
CostTermBase< MODEL > * newJc(const eckit::Configuration &, const Geometry_ &) const override
util::DateTime windowEnd_