FV3 Bundle
src/lorenz95/ObsVec1D.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/ObsVec1D.h"
12 
13 #include <math.h>
14 #include <random>
15 
16 #include <boost/foreach.hpp>
17 
18 #include "eckit/config/Configuration.h"
19 #include "eckit/exception/Exceptions.h"
20 #include "lorenz95/GomL95.h"
21 #include "lorenz95/ObsTable.h"
22 #include "oops/util/DateTime.h"
23 #include "oops/util/Duration.h"
24 #include "oops/util/Logger.h"
25 
26 namespace lorenz95 {
27 // -----------------------------------------------------------------------------
28 ObsVec1D::ObsVec1D(const ObsTable & ot): obsdb_(ot), data_(ot.nobs())
29 {
30  BOOST_FOREACH(double & val, data_) val = 0.0;
31 }
32 // -----------------------------------------------------------------------------
33 ObsVec1D::ObsVec1D(const ObsVec1D & other, const bool copy)
34  : obsdb_(other.obsdb_), data_(other.data_.size())
35 {
36  if (copy) {
37  data_ = other.data_;
38  } else {
39  BOOST_FOREACH(double & val, data_) val = 0.0;
40  }
41 }
42 // -----------------------------------------------------------------------------
44  ASSERT(data_.size() == rhs.data_.size());
45  data_ = rhs.data_;
46  return *this;
47 }
48 // -----------------------------------------------------------------------------
49 ObsVec1D & ObsVec1D::operator*= (const double & zz) {
50  BOOST_FOREACH(double & val, data_) val *= zz;
51  return *this;
52 }
53 // -----------------------------------------------------------------------------
55  ASSERT(data_.size() == rhs.data_.size());
56  for (unsigned int jj = 0; jj < data_.size(); ++jj) data_[jj] += rhs.data_[jj];
57  return *this;
58 }
59 // -----------------------------------------------------------------------------
61  ASSERT(data_.size() == rhs.data_.size());
62  for (unsigned int jj = 0; jj < data_.size(); ++jj) data_[jj] -= rhs.data_[jj];
63  return *this;
64 }
65 // -----------------------------------------------------------------------------
67  ASSERT(data_.size() == rhs.data_.size());
68  for (unsigned int jj = 0; jj < data_.size(); ++jj) data_[jj] *= rhs.data_[jj];
69  return *this;
70 }
71 // -----------------------------------------------------------------------------
73  ASSERT(data_.size() == rhs.data_.size());
74  for (unsigned int jj = 0; jj < data_.size(); ++jj) data_[jj] /= rhs.data_[jj];
75  return *this;
76 }
77 // -----------------------------------------------------------------------------
79  BOOST_FOREACH(double & val, data_) val = 0.0;
80 }
81 // -----------------------------------------------------------------------------
83  BOOST_FOREACH(double & val, data_) val = 1.0/val;
84 }
85 // -----------------------------------------------------------------------------
86 void ObsVec1D::axpy(const double & zz, const ObsVec1D & rhs) {
87  ASSERT(data_.size() == rhs.data_.size());
88  for (unsigned int jj = 0; jj < data_.size(); ++jj) data_[jj] += zz * rhs.data_[jj];
89 }
90 // -----------------------------------------------------------------------------
92  static std::mt19937 generator(2);
93  static std::normal_distribution<double> distribution(0.0, 1.0);
94  for (unsigned int jj = 0; jj < data_.size(); ++jj) data_[jj] = distribution(generator);
95 }
96 // -----------------------------------------------------------------------------
97 double ObsVec1D::dot_product_with(const ObsVec1D & other) const {
98  ASSERT(data_.size() == other.data_.size());
99  double zz = 0.0;
100  for (unsigned int jj = 0; jj < data_.size(); ++jj) zz += data_[jj] * other.data_[jj];
101  return zz;
102 }
103 // -----------------------------------------------------------------------------
104 double ObsVec1D::rms() const {
105  double zz = 0.0;
106  for (unsigned int jj = 0; jj < data_.size(); ++jj) zz += data_[jj] * data_[jj];
107  zz = sqrt(zz/data_.size());
108  return zz;
109 }
110 // -----------------------------------------------------------------------------
111 void ObsVec1D::read(const std::string & name) {
113 }
114 // -----------------------------------------------------------------------------
115 void ObsVec1D::save(const std::string & name) const {
117 }
118 // -----------------------------------------------------------------------------
119 void ObsVec1D::print(std::ostream & os) const {
120  ASSERT(data_.size() > 0);
121  double zmin = data_[0];
122  double zmax = data_[0];
123  double zavg = 0.0;
124  BOOST_FOREACH(const double & val, data_) {
125  if (val < zmin) zmin = val;
126  if (val > zmax) zmax = val;
127  zavg += val;
128  }
129  zavg /= data_.size();
130  os << "Lorenz 95 nobs= " << data_.size() << " Min=" << zmin << ", Max=" << zmax
131  << ", Average=" << zavg;
132 }
133 // -----------------------------------------------------------------------------
134 } // namespace lorenz95
void axpy(const double &, const ObsVec1D &)
void print(std::ostream &) const
ObsVec1D & operator/=(const ObsVec1D &)
ObsVec1D & operator=(const ObsVec1D &)
ObsVec1D & operator+=(const ObsVec1D &)
subroutine, public copy(self, rhs)
void read(const std::string &)
void putdb(const std::string &, const std::vector< double > &) const
character(len=32) name
ObsVec1D & operator*=(const double &)
Vector in observation space.
Definition: ObsVec1D.h:32
void getdb(const std::string &, std::vector< double > &) const
The namespace for the L95 model.
std::vector< double > data_
Definition: ObsVec1D.h:67
ObsVec1D(const ObsTable &)
ObsVec1D & operator-=(const ObsVec1D &)
double dot_product_with(const ObsVec1D &) const
A Simple Observation Data Handler.
Definition: ObsTable.h:39
************************************************************************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:! ***********************************************************************subroutine READ_RECORD_CORE_(unit, field, nwords, data, start, axsiz) integer, intent(in) ::unit type(fieldtype), intent(in) ::field integer, intent(in) ::nwords MPP_TYPE_, intent(inout) ::data(nwords) integer, intent(in) ::start(:), axsiz(:) integer(SHORT_KIND) ::i2vals(nwords)!rab used in conjunction with transfer intrinsic to determine size of a variable integer(KIND=1) ::one_byte(8) integer ::word_sz!#ifdef __sgi integer(INT_KIND) ::ivals(nwords) real(FLOAT_KIND) ::rvals(nwords)!#else! integer ::ivals(nwords)! real ::rvals(nwords)!#endif real(DOUBLE_KIND) ::r8vals(nwords) pointer(ptr1, i2vals) pointer(ptr2, ivals) pointer(ptr3, rvals) pointer(ptr4, r8vals) if(mpp_io_stack_size< nwords) call mpp_io_set_stack_size(nwords) call mpp_error(FATAL, 'MPP_READ currently requires use_netCDF option') end subroutine READ_RECORD_CORE_ subroutine READ_RECORD_(unit, field, nwords, data, time_level, domain, position, tile_count, start_in, axsiz_in)!routine that is finally called by all mpp_read routines to perform the read!a non-netCDF record contains:! field ID! a set of 4 coordinates(is:ie, js:je) giving the data subdomain! a timelevel and a timestamp(=NULLTIME if field is static)! 3D real data(stored as 1D)!if you are using direct access I/O, the RECL argument to OPEN must be large enough for the above!in a global direct access file, record position on PE is given by %record.!Treatment of timestamp:! We assume that static fields have been passed without a timestamp.! Here that is converted into a timestamp of NULLTIME.! For non-netCDF fields, field is treated no differently, but is written! with a timestamp of NULLTIME. There is no check in the code to prevent! the user from repeatedly writing a static field. integer, intent(in) ::unit, nwords type(fieldtype), intent(in) ::field MPP_TYPE_, intent(inout) ::data(nwords) integer, intent(in), optional ::time_level type(domain2D), intent(in), optional ::domain integer, intent(in), optional ::position, tile_count integer, intent(in), optional ::start_in(:), axsiz_in(:) integer, dimension(size(field%axes(:))) ::start, axsiz integer ::tlevel !, subdomain(4) integer ::i, error, is, ie, js, je, isg, ieg, jsg, jeg type(domain2d), pointer ::io_domain=> tlevel if(PRESENT(start_in) .AND. PRESENT(axsiz_in)) then if(size(start(! the data domain and compute domain must refer to the subdomain being passed ! In this ! since that attempts to gather all data on PE size(field%axes(:)) axsiz(i)
const ObsTable & obsdb_
Definition: ObsVec1D.h:66
void save(const std::string &) const