FV3 Bundle
src/lorenz95/TLML95.cc
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2009-2016 ECMWF.
3  *
4  * This software is licensed under the terms of the Apache Licence Version 2.0
5  * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
6  * In applying this licence, ECMWF does not waive the privileges and immunities
7  * granted to it by virtue of its status as an intergovernmental organisation nor
8  * does it submit to any jurisdiction.
9  */
10 
11 #include "lorenz95/TLML95.h"
12 
13 #include "eckit/config/LocalConfiguration.h"
14 #include "lorenz95/FieldL95.h"
15 #include "lorenz95/IncrementL95.h"
16 #include "lorenz95/L95Traits.h"
17 #include "lorenz95/ModelBias.h"
19 #include "lorenz95/ModelL95.h"
21 #include "lorenz95/Resolution.h"
22 #include "lorenz95/StateL95.h"
23 #include "oops/util/abor1_cpp.h"
24 #include "oops/util/DateTime.h"
25 #include "oops/util/Duration.h"
26 #include "oops/util/Logger.h"
27 
28 namespace lorenz95 {
29 // -----------------------------------------------------------------------------
31 // -----------------------------------------------------------------------------
32 TLML95::TLML95(const Resolution & resol, const eckit::Configuration & tlConf)
33  : resol_(resol), tstep_(util::Duration(tlConf.getString("tstep"))),
34  dt_(tstep_.toSeconds()/432000.0), traj_(),
35  lrmodel_(resol_, eckit::LocalConfiguration(tlConf, "trajectory")),
36  vars_(tlConf)
37 {
38  oops::Log::info() << "TLML95: resol = " << resol_ << ", tstep = " << tstep_ << std::endl;
39  oops::Log::trace() << "TLML95::TLML95 created" << std::endl;
40 }
41 // -----------------------------------------------------------------------------
43  for (trajIter jtra = traj_.begin(); jtra != traj_.end(); ++jtra) {
44  delete jtra->second;
45  }
46  oops::Log::trace() << "TLML95::~TLML95 destructed" << std::endl;
47 }
48 // -----------------------------------------------------------------------------
49 void TLML95::setTrajectory(const StateL95 & xx, StateL95 &, const ModelBias & bias) {
50  ASSERT(traj_.find(xx.validTime()) == traj_.end());
51  ModelTrajectory * traj = new ModelTrajectory();
52 // Interpolate xx to xlr here
53  FieldL95 zz(xx.getField());
54  lrmodel_.stepRK(zz, bias, *traj);
55  traj_[xx.validTime()] = traj;
56 }
57 // -----------------------------------------------------------------------------
58 const ModelTrajectory * TLML95::getTrajectory(const util::DateTime & tt) const {
59  trajICst itra = traj_.find(tt);
60  if (itra == traj_.end()) {
61  oops::Log::error() << "TLML95: trajectory not available at time " << tt << std::endl;
62  ABORT("TLML95: trajectory not available");
63  }
64  return itra->second;
65 }
66 // -----------------------------------------------------------------------------
67 /// Run TLM and its adjoint
68 // -----------------------------------------------------------------------------
73 // -----------------------------------------------------------------------------
74 void TLML95::stepTL(IncrementL95 & xx, const ModelBiasCorrection & bias) const {
75  FieldL95 dx(xx.getField(), false);
76  FieldL95 zz(xx.getField(), false);
77  FieldL95 dz(xx.getField(), false);
78  const ModelTrajectory * traj = this->getTrajectory(xx.validTime());
79 
80  zz = xx.getField();
81  this->tendenciesTL(zz, bias.bias(), traj->get(1), dz);
82  dx = dz;
83 
84  zz = xx.getField();
85  zz.axpy(0.5, dz);
86  this->tendenciesTL(zz, bias.bias(), traj->get(2), dz);
87  dx.axpy(2.0, dz);
88 
89  zz = xx.getField();
90  zz.axpy(0.5, dz);
91  this->tendenciesTL(zz, bias.bias(), traj->get(3), dz);
92  dx.axpy(2.0, dz);
93 
94  zz = xx.getField();
95  zz += dz;
96  this->tendenciesTL(zz, bias.bias(), traj->get(4), dz);
97  dx += dz;
98 
99  const double zt = 1.0/6.0;
100  xx.getField().axpy(zt, dx);
101  xx.validTime() += tstep_;
102 }
103 // -----------------------------------------------------------------------------
105  FieldL95 dx(xx.getField(), false);
106  FieldL95 zz(xx.getField(), false);
107  FieldL95 dz(xx.getField(), false);
108 
109  xx.validTime() -= tstep_;
110  const ModelTrajectory * traj = this->getTrajectory(xx.validTime());
111 
112  const double zt = 1.0/6.0;
113  dx = xx.getField();
114  dx *= zt;
115 
116  dz = dx;
117  this->tendenciesAD(zz, bias.bias(), traj->get(4), dz);
118  xx.getField() += zz;
119  dz = zz;
120 
121  dz.axpy(2.0, dx);
122  this->tendenciesAD(zz, bias.bias(), traj->get(3), dz);
123  xx.getField() += zz;
124  dz = zz;
125  dz *= 0.5;
126 
127  dz.axpy(2.0, dx);
128  this->tendenciesAD(zz, bias.bias(), traj->get(2), dz);
129  xx.getField() += zz;
130  dz = zz;
131  dz *= 0.5;
132 
133  dz += dx;
134  this->tendenciesAD(zz, bias.bias(), traj->get(1), dz);
135  xx.getField() += zz;
136 }
137 // -----------------------------------------------------------------------------
138 void TLML95::tendenciesTL(const FieldL95 & xx, const double & bias,
139  const FieldL95 & xtraj, FieldL95 & dx) const {
140  const int nn = resol_.npoints();
141  for (int jj = 0; jj < nn; ++jj) {
142  int jm2 = jj - 2;
143  int jm1 = jj - 1;
144  int jp1 = jj + 1;
145  if (jm2 < 0) jm2 += nn;
146  if (jm1 < 0) jm1 += nn;
147  if (jp1 >= nn) jp1 -= nn;
148  const double dxdt = - xx[jm2] * xtraj[jm1] - xtraj[jm2] * xx[jm1]
149  + xx[jm1] * xtraj[jp1] + xtraj[jm1] * xx[jp1]
150  - xx[jj] - bias;
151  dx[jj] = dt_ * dxdt;
152  }
153 }
154 // -----------------------------------------------------------------------------
155 void TLML95::tendenciesAD(FieldL95 & xx, double & bias,
156  const FieldL95 & xtraj, const FieldL95 & dx) const {
157  const int nn = resol_.npoints();
158  xx.zero();
159  for (int jj = 0; jj < nn; ++jj) {
160  int jm2 = jj - 2;
161  int jm1 = jj - 1;
162  int jp1 = jj + 1;
163  if (jm2 < 0) jm2 += nn;
164  if (jm1 < 0) jm1 += nn;
165  if (jp1 >= nn) jp1 -= nn;
166  const double dxdt = dt_ * dx[jj];
167  xx[jm2] -= dxdt * xtraj[jm1];
168  xx[jm1] -= dxdt * xtraj[jm2];
169  xx[jm1] += dxdt * xtraj[jp1];
170  xx[jp1] += dxdt * xtraj[jm1];
171  xx[jj] -= dxdt;
172  bias -= dxdt;
173  }
174 }
175 // -----------------------------------------------------------------------------
176 void TLML95::print(std::ostream & os) const {
177  os << "TLML95: resol = " << resol_ << ", tstep = " << tstep_;
178  os << "L95 Model Trajectory, nstep=" << traj_.size() << "\n";
179  typedef std::map< util::DateTime, ModelTrajectory * >::const_iterator trajICst;
180  if (traj_.size() > 0) {
181  os << "L95 Model Trajectory: times are:";
182  for (trajICst jtra = traj_.begin(); jtra != traj_.end(); ++jtra) {
183  os << " " << jtra->first;
184  }
185  }
186 }
187 // -----------------------------------------------------------------------------
188 } // namespace lorenz95
void stepAD(IncrementL95 &, ModelBiasCorrection &) const override
const util::Duration tstep_
Definition: TLML95.h:80
Increment Class: Difference between two states.
Definition: IncrementL95.h:51
void stepRK(FieldL95 &, const ModelBias &, ModelTrajectory &) const
const util::DateTime & validTime() const
Definition: StateL95.h:81
std::map< util::DateTime, ModelTrajectory *>::const_iterator trajICst
Definition: TLML95.h:76
const FieldL95 & getField() const
Definition: StateL95.h:71
void tendenciesAD(FieldL95 &, double &, const FieldL95 &, const FieldL95 &) const
void finalizeAD(IncrementL95 &) const override
const double dt_
Definition: TLML95.h:81
const ModelTrajectory * getTrajectory(const util::DateTime &) const
void tendenciesTL(const FieldL95 &, const double &, const FieldL95 &, FieldL95 &) const
Handles resolution.
Definition: Resolution.h:25
const FieldL95 & get(const int) const
Get trajectory.
void zero()
Linear algebra.
Definition: FieldL95.cc:56
const FieldL95 & getField() const
Access to data.
Definition: IncrementL95.h:97
const ModelL95 lrmodel_
Definition: TLML95.h:83
void finalizeTL(IncrementL95 &) const override
std::map< util::DateTime, ModelTrajectory *>::iterator trajIter
Definition: TLML95.h:75
int npoints() const
Definition: Resolution.h:37
subroutine, public info(self)
void stepTL(IncrementL95 &, const ModelBiasCorrection &) const override
integer error
Definition: mpp.F90:1310
The namespace for the L95 model.
void print(std::ostream &) const override
void setTrajectory(const StateL95 &, StateL95 &, const ModelBias &) override
Model trajectory computation.
std::map< util::DateTime, ModelTrajectory *> traj_
Definition: TLML95.h:82
Model error for Lorenz 95 model.
void initializeTL(IncrementL95 &) const override
Run TLM and its adjoint.
L95 model trajectory.
const Resolution resol_
Definition: TLML95.h:79
L95 model state.
Definition: StateL95.h:50
void initializeAD(IncrementL95 &) const override
const util::DateTime & validTime() const
Definition: IncrementL95.h:92
TLML95(const Resolution &, const eckit::Configuration &)
static oops::LinearModelMaker< L95Traits, TLML95 > makerTLML95_("L95TLM")
void axpy(const double &, const FieldL95 &)
Definition: FieldL95.cc:125
Class to represent fields for the L95 model.
Definition: FieldL95.h:36