FV3 Bundle
src/lorenz95/GomL95.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/GomL95.h"
12 
13 #include <cmath>
14 #include <cstdlib>
15 #include <fstream>
16 #include <limits>
17 #include <random>
18 
19 #include "eckit/config/Configuration.h"
20 #include "lorenz95/LocsL95.h"
21 #include "lorenz95/ObsTable.h"
22 #include "oops/util/abor1_cpp.h"
23 #include "oops/util/Logger.h"
24 
25 namespace oops {
26 class Variables;
27 }
28 
29 namespace lorenz95 {
30 
31 // -----------------------------------------------------------------------------
32 GomL95::GomL95(const LocsL95 & locs, const oops::Variables &)
33  : size_(0), iobs_(), locval_(), current_(0)
34 {
35  oops::Log::trace() << "GomL95::GomL95 starting " << std::endl;
36  size_ = locs.size();
37  iobs_.resize(size_);
38  locval_.resize(size_);
39  for (size_t jj = 0; jj < size_; ++jj) iobs_[jj] = locs.globalIndex(jj);
40  for (size_t jj = 0; jj < size_; ++jj) locval_[jj] = locs[jj];
41 }
42 // -----------------------------------------------------------------------------
43 /*! Constructor with Configuration */
44 GomL95::GomL95(const eckit::Configuration & conf, const oops::Variables &)
45  : size_(0), iobs_(), locval_(), current_(0)
46 {
47  this->read(conf);
48 }
49 // -----------------------------------------------------------------------------
50 GomL95::GomL95(const GomL95 & other)
51  : size_(other.size_), iobs_(other.iobs_), locval_(other.locval_), current_(0)
52 {
53  oops::Log::trace() << "GomL95::GomL95 copied" << std::endl;
54 }
55 // -----------------------------------------------------------------------------
57 // -----------------------------------------------------------------------------
58 GomL95 & GomL95::operator*=(const double & zz) {
59  for (size_t jj = 0; jj < size_; ++jj) locval_[jj] *= zz;
60  return *this;
61 }
62 // -----------------------------------------------------------------------------
64 {
65  for (size_t jj = 0; jj < size_; ++jj) locval_[jj] += rhs.locval_[jj];
66  return *this;
67 }
68 // -----------------------------------------------------------------------------
70 {
71  for (size_t jj = 0; jj < size_; ++jj) locval_[jj] -= rhs.locval_[jj];
72  return *this;
73 }
74 // -----------------------------------------------------------------------------
76 {
77  for (size_t jj = 0; jj < size_; ++jj) locval_[jj] /= rhs.locval_[jj];
78  return *this;
79 }
80 // -----------------------------------------------------------------------------
81 void GomL95::abs() {
82  for (size_t jj = 0; jj < size_; ++jj) locval_[jj] = std::abs(locval_[jj]);
83 }
84 // -----------------------------------------------------------------------------
85 void GomL95::zero() {
86  for (size_t jj = 0; jj < size_; ++jj) locval_[jj] = 0.0;
87 }
88 // -----------------------------------------------------------------------------
89 double GomL95::norm() const {
90  double xnorm(0.0);
91  for (size_t jj = 0; jj < size_; ++jj) xnorm += locval_[jj] * locval_[jj];
92  return sqrt(xnorm/static_cast<double>(size_));
93 }
94 // -----------------------------------------------------------------------------
96  static std::mt19937 generator(5);
97  static std::normal_distribution<double> distribution(0.0, 1.0);
98  for (size_t jj = 0; jj < size_; ++jj) locval_[jj] = distribution(generator);
99 }
100 // -----------------------------------------------------------------------------
101 double GomL95::dot_product_with(const GomL95 & gom) const {
102  double zz = 0.0;
103  for (size_t jj = 0; jj < size_; ++jj) zz += locval_[jj] * gom.locval_[jj];
104  return zz;
105 }
106 // -----------------------------------------------------------------------------
107 void GomL95::read(const eckit::Configuration & conf) {
108  const std::string filename(conf.getString("filename"));
109  oops::Log::trace() << "GomL95::read opening " << filename << std::endl;
110  std::ifstream fin(filename.c_str());
111  if (!fin.is_open()) ABORT("GomL95::read: Error opening file");
112 
113  size_t size;
114  fin >> size;
115 
116  if (size_ != size) {
117  size_ = size;
118  iobs_.resize(size_);
119  locval_.resize(size_);
120  }
121 
122  for (size_t jj = 0; jj < size_; ++jj) fin >> iobs_[jj];
123  for (size_t jj = 0; jj < size_; ++jj) fin >> locval_[jj];
124 
125  fin.close();
126  oops::Log::trace() << "GomL95::read: file closed." << std::endl;
127 }
128 // -----------------------------------------------------------------------------
129 void GomL95::write(const eckit::Configuration & conf) const {
130  const std::string filename(conf.getString("filename"));
131  oops::Log::trace() << "GomL95::write opening " << filename << std::endl;
132  std::ofstream fout(filename.c_str());
133  if (!fout.is_open()) ABORT("GomL95::write: Error opening file");
134 
135  fout << size_ << std::endl;
136  for (size_t jj = 0; jj < size_; ++jj) fout << iobs_[jj] << " ";
137  fout << std::endl;
138  fout.precision(std::numeric_limits<double>::digits10);
139  for (size_t jj = 0; jj < size_; ++jj) fout << locval_[jj] << " ";
140  fout << std::endl;
141 
142  fout.close();
143  oops::Log::trace() << "GomL95::write file closed." << std::endl;
144 }
145 // -----------------------------------------------------------------------------
146 /*! GomL95 analytic initialization */
147 
148 void GomL95::analytic_init(const LocsL95 & locs, const eckit::Configuration & conf)
149 {
150  oops::Log::trace() << "GomL95::GomL95 analytic init " << std::endl;
151 
152  // analytic init for testing interpolation
153  for (size_t jj = 0; jj < size_; ++jj) locval_[jj] = 0.0;
154  if (conf.has("mean")) {
155  const double zz = conf.getDouble("mean");
156  for (size_t jj = 0; jj < size_; ++jj) locval_[jj] = zz;
157  }
158  if (conf.has("sinus")) {
159  const double zz = conf.getDouble("sinus");
160  const double pi = std::acos(-1.0);
161  for (size_t jj = 0; jj < size_; ++jj)
162  locval_[jj] += zz * std::sin(2.0*pi*locs[jj]);
163  }
164  oops::Log::trace() << "GomL95::GomL95 analytic init finished" << std::endl;
165 }
166 // -----------------------------------------------------------------------------
167 void GomL95::print(std::ostream & os) const {
168  double zmin = locval_[0];
169  double zmax = locval_[0];
170  size_t jmax = 0;
171  double zavg = 0.0;
172  for (size_t jj = 0; jj < size_; ++jj) {
173  if (locval_[jj] < zmin) zmin = locval_[jj];
174  if (locval_[jj] > zmax) {
175  zmax = locval_[jj];
176  jmax = jj;
177  }
178  zavg += locval_[jj];
179  }
180  zavg /= size_;
181  os << size_ << "values, Min=" << zmin << ", Max=" << zmax << ", Average=" << zavg;
182 
183  // If the min value across all variables is positive, then this may be an
184  // error measurement. If so, print the location where the maximum occurs
185  // to the debug stream, for use in debugging
186 
187  if (zmin >= 0.0)
188  oops::Log::debug() << std::endl << "GomL95: Maximum Value = " << std::setprecision(4)
189  << zmax << " at location = " << jmax << std::endl;
190 }
191 
192 } // namespace lorenz95
const int & globalIndex(const size_t ii) const
Definition: LocsL95.h:39
GomL95 class to handle locations for L95 model.
Definition: GomL95.h:32
size_t size_
Definition: GomL95.h:63
Definition: conf.py:1
GomL95 & operator*=(const double &)
void print(std::ostream &) const
std::vector< int > iobs_
Definition: GomL95.h:64
LocsL95 class to handle locations for L95 model.
Definition: LocsL95.h:28
GomL95(const LocsL95 &, const oops::Variables &)
The namespace for the main oops code.
void analytic_init(const LocsL95 &, const eckit::Configuration &)
GomL95 analytic initialization.
logical debug
Definition: mpp.F90:1297
GomL95 & operator-=(const GomL95 &)
The namespace for the L95 model.
void read(const eckit::Configuration &)
std::vector< double > locval_
Definition: GomL95.h:65
size_t size() const
Definition: GomL95.h:56
double dot_product_with(const GomL95 &) const
void write(const eckit::Configuration &) const
size_t size() const
Definition: LocsL95.h:37
GomL95 & operator/=(const GomL95 &)
GomL95 & operator+=(const GomL95 &)