PISM, A Parallel Ice Sheet Model  stable v2.1-1-g6902d5502 committed by Ed Bueler on 2023-12-20 08:38:27 -0800
Delta_P.cc
Go to the documentation of this file.
1 // Copyright (C) 2011--2023 PISM Authors
2 //
3 // This file is part of PISM.
4 //
5 // PISM is free software; you can redistribute it and/or modify it under the
6 // terms of the GNU General Public License as published by the Free Software
7 // Foundation; either version 3 of the License, or (at your option) any later
8 // version.
9 //
10 // PISM is distributed in the hope that it will be useful, but WITHOUT ANY
11 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 // details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with PISM; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 
19 #include "pism/coupler/atmosphere/Delta_P.hh"
20 
21 #include "pism/util/ConfigInterface.hh"
22 #include "pism/util/ScalarForcing.hh"
23 #include "pism/coupler/util/options.hh"
24 #include "pism/util/array/Forcing.hh"
25 
26 namespace pism {
27 namespace atmosphere {
28 
29 Delta_P::Delta_P(std::shared_ptr<const Grid> grid, std::shared_ptr<AtmosphereModel> in)
30  : AtmosphereModel(grid, std::move(in)) {
31 
32  std::string
33  prefix = "atmosphere.delta_P",
34  variable_name = "delta_P",
35  long_name = "precipitation offsets",
36  units = "kg m-2 second-1",
37  external_units = "kg m-2 year-1";
38 
39  ForcingOptions opt(*m_grid->ctx(), prefix);
40 
41  // will be closed at the end of scope
43 
44  // Assume that we are expected to use 1D scaling if the input file contains a scalar
45  // time-series.
46  bool scalar = input.dimensions(variable_name).size() == 1;
47 
48  if (scalar) {
49  m_1d_offsets.reset(new ScalarForcing(*grid->ctx(),
50  prefix,
51  variable_name,
52  units, external_units,
53  long_name));
54  } else {
55  auto buffer_size = m_config->get_number("input.forcing.buffer_size");
56 
57  m_2d_offsets = std::make_shared<array::Forcing>(m_grid,
58  input,
59  variable_name,
60  "", // no standard name
61  static_cast<unsigned int>(buffer_size),
62  opt.periodic);
63 
64  m_2d_offsets->metadata()
65  .long_name(long_name)
66  .units(units)
67  .output_units(external_units);
68  }
69 
71 }
72 
73 void Delta_P::init_impl(const Geometry &geometry) {
74  m_input_model->init(geometry);
75 
76  m_log->message(2,
77  "* Initializing precipitation forcing using scalar offsets...\n");
78 
79  if (m_2d_offsets) {
80  ForcingOptions opt(*m_grid->ctx(), "atmosphere.delta_P");
81  m_2d_offsets->init(opt.filename, opt.periodic);
82  }
83 
84 }
85 
86 void Delta_P::init_timeseries_impl(const std::vector<double> &ts) const {
88 
89  m_offset_values.resize(ts.size());
90 
91  if (m_1d_offsets) {
92  for (unsigned int k = 0; k < ts.size(); ++k) {
93  m_offset_values[k] = m_1d_offsets->value(ts[k]);
94  }
95  }
96 
97  if (m_2d_offsets) {
98  m_2d_offsets->init_interpolation(ts);
99  }
100 }
101 
103  m_input_model->begin_pointwise_access();
104 
105  if (m_2d_offsets) {
106  m_2d_offsets->begin_access();
107  }
108 }
109 
111  m_input_model->end_pointwise_access();
112 
113  if (m_2d_offsets) {
114  m_2d_offsets->end_access();
115  }
116 }
117 
118 void Delta_P::update_impl(const Geometry &geometry, double t, double dt) {
119  m_input_model->update(geometry, t, dt);
120  m_precipitation->copy_from(m_input_model->precipitation());
121 
122  if (m_1d_offsets) {
123  m_precipitation->shift(m_1d_offsets->value(t + 0.5 * dt));
124  }
125 
126  if (m_2d_offsets) {
127  m_2d_offsets->update(t, dt);
128  m_2d_offsets->average(t, dt);
129 
130  auto &P = *m_precipitation;
131  const auto &delta = *m_2d_offsets;
132 
133  array::AccessScope list{&P, &delta};
134 
135  for (auto p = m_grid->points(); p; p.next()) {
136  const int i = p.i(), j = p.j();
137 
138  P(i, j) += delta(i, j);
139  }
140  }
141 }
142 
144  return *m_precipitation;
145 }
146 
147 void Delta_P::precip_time_series_impl(int i, int j, std::vector<double> &result) const {
148  m_input_model->precip_time_series(i, j, result);
149 
150  if (m_2d_offsets) {
151  // m_offset_values was resized in init_interpolation and so it should have enough
152  // elements
153  m_2d_offsets->interp(i, j, m_offset_values);
154  } else if (m_1d_offsets) {
155  // empty: m_offset_values were set in init_timeseries_impl()
156  }
157 
158  for (size_t k = 0; k < result.size(); ++k) {
159  result[k] += m_offset_values[k];
160  }
161 }
162 
163 } // end of namespace atmosphere
164 } // end of namespace pism
std::shared_ptr< const Grid > grid() const
Definition: Component.cc:105
const Config::ConstPtr m_config
configuration database used by this component
Definition: Component.hh:158
const Logger::ConstPtr m_log
logger (for easy access)
Definition: Component.hh:162
const std::shared_ptr< const Grid > m_grid
grid used by this component
Definition: Component.hh:156
std::vector< std::string > dimensions(const std::string &variable_name) const
Definition: File.cc:425
High-level PISM I/O class.
Definition: File.hh:56
Makes sure that we call begin_access() and end_access() for all accessed array::Arrays.
Definition: Array.hh:65
virtual void init_timeseries_impl(const std::vector< double > &ts) const
std::shared_ptr< AtmosphereModel > m_input_model
static std::shared_ptr< array::Scalar > allocate_precipitation(std::shared_ptr< const Grid > grid)
A purely virtual class defining the interface of a PISM Atmosphere Model.
void precip_time_series_impl(int i, int j, std::vector< double > &result) const
Definition: Delta_P.cc:147
void init_timeseries_impl(const std::vector< double > &ts) const
Definition: Delta_P.cc:86
const array::Scalar & precipitation_impl() const
Definition: Delta_P.cc:143
void end_pointwise_access_impl() const
Definition: Delta_P.cc:110
void init_impl(const Geometry &geometry)
Definition: Delta_P.cc:73
void begin_pointwise_access_impl() const
Definition: Delta_P.cc:102
std::shared_ptr< ScalarForcing > m_1d_offsets
Definition: Delta_P.hh:49
std::vector< double > m_offset_values
Definition: Delta_P.hh:47
std::shared_ptr< array::Forcing > m_2d_offsets
Definition: Delta_P.hh:51
void update_impl(const Geometry &geometry, double t, double dt)
Definition: Delta_P.cc:118
Delta_P(std::shared_ptr< const Grid > g, std::shared_ptr< AtmosphereModel > in)
Definition: Delta_P.cc:29
std::shared_ptr< array::Scalar > m_precipitation
Definition: Delta_P.hh:53
@ PISM_GUESS
Definition: IO_Flags.hh:56
@ PISM_READONLY
open an existing file for reading only
Definition: IO_Flags.hh:72
static const double k
Definition: exactTestP.cc:42
std::string filename
Definition: options.hh:33