FV3 Bundle
FieldL95.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/FieldL95.h"
12 
13 #include <cmath>
14 #include <fstream>
15 #include <limits>
16 #include <random>
17 #include <string>
18 
19 #include "eckit/config/Configuration.h"
20 #include "lorenz95/GomL95.h"
21 #include "lorenz95/LocsL95.h"
22 #include "lorenz95/Resolution.h"
24 #include "oops/util/abor1_cpp.h"
25 #include "oops/util/Logger.h"
26 
27 // -----------------------------------------------------------------------------
28 namespace lorenz95 {
29 // -----------------------------------------------------------------------------
31  : resol_(resol.npoints()), x_(resol_)
32 {
33  ASSERT(resol_ > 0);
34  for (int jj = 0; jj < resol_; ++jj) x_[jj] = 0.0;
35 }
36 // -----------------------------------------------------------------------------
37 FieldL95::FieldL95(const FieldL95 & other, const Resolution & resol)
38  : resol_(resol.npoints()), x_(resol_)
39 {
40  ASSERT(resol_ > 0);
41  ASSERT(other.resol_ == resol_);
42  for (int jj = 0; jj < resol_; ++jj) x_[jj] = other.x_[jj];
43 }
44 // -----------------------------------------------------------------------------
45 FieldL95::FieldL95(const FieldL95 & other, const bool copy)
46  : resol_(other.resol_), x_(resol_)
47 {
48  ASSERT(resol_ > 0);
49  if (copy) {
50  for (int jj = 0; jj < resol_; ++jj) x_[jj] = other.x_[jj];
51  } else {
52  for (int jj = 0; jj < resol_; ++jj) x_[jj] = 0.0;
53  }
54 }
55 // -----------------------------------------------------------------------------
57  for (int jj = 0; jj < resol_; ++jj) x_[jj] = 0.0;
58 }
59 // -----------------------------------------------------------------------------
60 void FieldL95::dirac(const eckit::Configuration & config) {
61 // Get Diracs position
62  std::vector<int> ixdir(config.getIntVector("ixdir"));
63 
64 // Check
65  ASSERT(ixdir.size() > 0);
66  for (unsigned int jj = 0; jj < ixdir.size(); ++jj) {
67  ASSERT(ixdir[jj] < resol_);
68  }
69 
70 // Setup Dirac
71  for (int jj = 0; jj < resol_; ++jj) x_[jj] = 0.0;
72  for (unsigned int jj = 0; jj < ixdir.size(); ++jj) x_[ixdir[jj]] = 1.0;
73 }
74 // -----------------------------------------------------------------------------
75 void FieldL95::generate(const eckit::Configuration & conf) {
76  for (int jj = 0; jj < resol_; ++jj) x_[jj] = 0.0;
77  if (conf.has("mean")) {
78  const double zz = conf.getDouble("mean");
79  for (int jj = 0; jj < resol_; ++jj) x_[jj] = zz;
80  }
81  if (conf.has("sinus")) {
82  const double zz = conf.getDouble("sinus");
83  const double pi = std::acos(-1.0);
84  const double dx = 2.0 * pi / static_cast<double>(resol_);
85  for (int jj = 0; jj < resol_; ++jj) x_[jj] += zz * std::sin(static_cast<double>(jj) * dx);
86  }
87  if (conf.has("dirac")) {
88  const int ii = conf.getInt("dirac");
89  x_[ii] += 1.0;
90  }
91  oops::Log::trace() << "FieldL95::generate " << x_[28] << ", " << x_[29] << std::endl;
92 }
93 // -----------------------------------------------------------------------------
95  ASSERT(rhs.resol_ == resol_);
96  for (int jj = 0; jj < resol_; ++jj) x_[jj] = rhs.x_[jj];
97  return *this;
98 }
99 // -----------------------------------------------------------------------------
101  ASSERT(rhs.resol_ == resol_);
102  for (int jj = 0; jj < resol_; ++jj) x_[jj] += rhs.x_[jj];
103  return *this;
104 }
105 // -----------------------------------------------------------------------------
107  ASSERT(rhs.resol_ == resol_);
108  for (int jj = 0; jj < resol_; ++jj) x_[jj] -= rhs.x_[jj];
109  return *this;
110 }
111 // -----------------------------------------------------------------------------
112 FieldL95 & FieldL95::operator*= (const double & fact) {
113  for (int jj = 0; jj < resol_; ++jj) x_[jj] *= fact;
114  return *this;
115 }
116 // -----------------------------------------------------------------------------
117 void FieldL95::diff(const FieldL95 & x1, const FieldL95 & x2) {
118  ASSERT(x1.resol_ == resol_);
119  ASSERT(x2.resol_ == resol_);
120  for (int jj = 0; jj < resol_; ++jj) {
121  x_[jj] = x1.x_[jj] - x2.x_[jj];
122  }
123 }
124 // -----------------------------------------------------------------------------
125 void FieldL95::axpy(const double & zz, const FieldL95 & rhs) {
126  ASSERT(rhs.resol_ == resol_);
127  for (int jj = 0; jj < resol_; ++jj) x_[jj] += zz * rhs.x_[jj];
128 }
129 // -----------------------------------------------------------------------------
130 double FieldL95::dot_product_with(const FieldL95 & other) const {
131  ASSERT(other.resol_ == resol_);
132  double zz = 0.0;
133  for (int jj = 0; jj < resol_; ++jj) zz += x_[jj] * other.x_[jj];
134  return zz;
135 }
136 // -----------------------------------------------------------------------------
137 void FieldL95::schur(const FieldL95 & rhs) {
138  ASSERT(rhs.resol_ == resol_);
139  for (int jj = 0; jj < resol_; ++jj) x_[jj] *= rhs.x_[jj];
140 }
141 // -----------------------------------------------------------------------------
143  static std::mt19937 generator(1);
144  static std::normal_distribution<double> distribution(0.0, 1.0);
145  for (int jj = 0; jj < resol_; ++jj) x_[jj] = distribution(generator);
146 }
147 // -----------------------------------------------------------------------------
148 void FieldL95::interp(const LocsL95 & locs, GomL95 & gom) const {
149  const double dres = static_cast<double>(resol_);
150  for (size_t jobs = 0; jobs < locs.size(); ++jobs) {
151  int ii = round(locs[jobs] * dres);
152  ASSERT(ii >= 0 && ii <= resol_);
153  if (ii == resol_) ii = 0;
154  gom[gom.current()+jobs] = x_[ii];
155  }
156  gom.current() += locs.size();
157 }
158 // -----------------------------------------------------------------------------
159 void FieldL95::interpAD(const LocsL95 & locs, const GomL95 & gom) {
160  const double dres = static_cast<double>(resol_);
161  if (gom.current() == 0) gom.current() = gom.size();
162  gom.current() -= locs.size();
163  for (size_t jobs = 0; jobs < locs.size(); ++jobs) {
164  int ii = round(locs[jobs] * dres);
165  ASSERT(ii >= 0 && ii <= resol_);
166  if (ii == resol_) ii = 0;
167  x_[ii] += gom[gom.current()+jobs];
168  }
169 }
170 // -----------------------------------------------------------------------------
171 void FieldL95::ug_coord(oops::UnstructuredGrid & ug, const int & colocated) const {
172  ABORT("FieldL95 unstructured grid setup not implemented.");
173 }
174 // -----------------------------------------------------------------------------
175 void FieldL95::field_to_ug(oops::UnstructuredGrid & ug, const int & colocated) const {
176  ABORT("FieldL95 conversion to unstructured grid not implemented.");
177 }
178 // -----------------------------------------------------------------------------
180  ABORT("FieldL95 conversion from unstructured grid not implemented.");
181 }
182 // -----------------------------------------------------------------------------
183 void FieldL95::read(std::ifstream & fin) {
184  for (int jj = 0; jj < resol_; ++jj) fin >> x_[jj];
185 }
186 // -----------------------------------------------------------------------------
187 void FieldL95::write(std::ofstream & fout) const {
188  fout.precision(std::numeric_limits<double>::digits10);
189  for (int jj = 0; jj < resol_; ++jj) fout << x_[jj] << " ";
190 }
191 // -----------------------------------------------------------------------------
192 double FieldL95::rms() const {
193  double zz = 0.0;
194  for (int jj = 0; jj < resol_; ++jj) zz += x_[jj] * x_[jj];
195  zz = sqrt(zz/resol_);
196  return zz;
197 }
198 // -----------------------------------------------------------------------------
199 void FieldL95::print(std::ostream & os) const {
200  double zmin = x_[0];
201  double zmax = x_[0];
202  double zavg = 0.0;
203  for (int jj = 0; jj < resol_; ++jj) {
204  if (x_[jj] < zmin) zmin = x_[jj];
205  if (x_[jj] > zmax) zmax = x_[jj];
206  zavg += x_[jj];
207  }
208  zavg /= resol_;
209  os << " Min=" << zmin << ", Max=" << zmax << ", Average=" << zavg;
210 }
211 // -----------------------------------------------------------------------------
212 
213 } // namespace lorenz95
GomL95 class to handle locations for L95 model.
Definition: GomL95.h:32
void interp(const LocsL95 &, GomL95 &) const
Interpolate to given location.
Definition: FieldL95.cc:148
void ug_coord(oops::UnstructuredGrid &, const int &) const
Unstructured grid.
Definition: FieldL95.cc:171
void field_to_ug(oops::UnstructuredGrid &, const int &) const
Definition: FieldL95.cc:175
FieldL95 & operator-=(const FieldL95 &)
Definition: FieldL95.cc:106
FieldL95(const Resolution &)
Constructors and basic operators.
Definition: FieldL95.cc:30
subroutine, public copy(self, rhs)
void diff(const FieldL95 &, const FieldL95 &)
Definition: FieldL95.cc:117
void interpAD(const LocsL95 &, const GomL95 &)
Definition: FieldL95.cc:159
Definition: conf.py:1
void print(std::ostream &) const
Definition: FieldL95.cc:199
void dirac(const eckit::Configuration &)
Definition: FieldL95.cc:60
LocsL95 class to handle locations for L95 model.
Definition: LocsL95.h:28
Handles resolution.
Definition: Resolution.h:25
void field_from_ug(const oops::UnstructuredGrid &)
Definition: FieldL95.cc:179
void zero()
Linear algebra.
Definition: FieldL95.cc:56
double rms() const
Definition: FieldL95.cc:192
void read(std::ifstream &)
Utilities.
Definition: FieldL95.cc:183
The namespace for the L95 model.
void schur(const FieldL95 &)
Definition: FieldL95.cc:137
double dot_product_with(const FieldL95 &) const
Definition: FieldL95.cc:130
FieldL95 & operator*=(const double &)
Definition: FieldL95.cc:112
FieldL95 & operator+=(const FieldL95 &)
Definition: FieldL95.cc:100
void generate(const eckit::Configuration &)
Definition: FieldL95.cc:75
const int resol_
Definition: FieldL95.h:83
size_t size() const
Definition: GomL95.h:56
std::vector< double > x_
Definition: FieldL95.h:84
void write(std::ofstream &) const
Definition: FieldL95.cc:187
void axpy(const double &, const FieldL95 &)
Definition: FieldL95.cc:125
FieldL95 & operator=(const FieldL95 &)
Definition: FieldL95.cc:94
size_t size() const
Definition: LocsL95.h:37
int & current() const
Definition: GomL95.h:60
Class to represent fields for the L95 model.
Definition: FieldL95.h:36