PISM, A Parallel Ice Sheet Model  stable v2.1-1-g6902d5502 committed by Ed Bueler on 2023-12-20 08:38:27 -0800
Grid.hh
Go to the documentation of this file.
1 // Copyright (C) 2004-2023 Jed Brown, Ed Bueler and Constantine Khroulev
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 #ifndef PISM_GRID_H
20 #define PISM_GRID_H
21 
22 #include "io/File.hh"
23 #include <cassert>
24 #include <memory> // shared_ptr
25 #include <string>
26 #include <vector>
27 #include <map>
28 
29 #include <mpi.h> // MPI_Comm
30 
31 namespace pism {
32 
33 class Config;
34 class Context;
35 class File;
36 class Logger;
37 class MappingInfo;
38 class Vars;
39 
40 namespace petsc {
41 class DM;
42 } // end of namespace petsc
43 
44 namespace units {
45 class System;
46 }
47 
48 namespace grid {
49 
50 typedef enum {UNKNOWN = 0, EQUAL, QUADRATIC} VerticalSpacing;
51 typedef enum {NOT_PERIODIC = 0, X_PERIODIC = 1, Y_PERIODIC = 2, XY_PERIODIC = 3} Periodicity;
52 
54 
55 Registration string_to_registration(const std::string &keyword);
56 std::string registration_to_string(Registration registration);
57 
58 Periodicity string_to_periodicity(const std::string &keyword);
59 std::string periodicity_to_string(Periodicity p);
60 
61 VerticalSpacing string_to_spacing(const std::string &keyword);
62 std::string spacing_to_string(VerticalSpacing s);
63 
64 //! @brief Contains parameters of an input file grid.
66 public:
67  InputGridInfo(const File &file, const std::string &variable,
68  std::shared_ptr<units::System> unit_system, Registration registration);
69  void report(const Logger &log, int threshold, std::shared_ptr<units::System> s) const;
70  // dimension lengths
71  unsigned int t_len;
72  //! x-coordinate of the domain center
73  double x0;
74  //! y-coordinate of the domain center
75  double y0;
76  //! domain half-width
77  double Lx;
78  //! domain half-height
79  double Ly;
80  //! minimal value of the z dimension
81  double z_min;
82  //! maximal value of the z dimension
83  double z_max;
84 
85  //! x coordinates
86  std::vector<double> x;
87  //! y coordinates
88  std::vector<double> y;
89  //! z coordinates
90  std::vector<double> z;
91 
92  std::string filename;
93 
94  /*!
95  * Variable name *found in the file*, which may not match the one expected by PISM.
96  */
97  std::string variable_name;
98 
99  std::map<std::string, AxisType> dimension_types;
100 
101 private:
102  void reset();
103 };
104 
105 //! Grid parameters; used to collect defaults before an Grid is allocated.
106 /* Make sure that all of
107  - `horizontal_size_from_options()`
108  - `horizontal_extent_from_options()`
109  - `vertical_grid_from_options()`
110  - `ownership_ranges_from_options()`
111 
112  are called *or* all data members (`Lx`, `Ly`, `x0`, `y0`, `Mx`, `My`, `z`, `periodicity`,
113  `procs_x`, `procs_y`) are set manually before using an instance of GridParameters.
114 
115  Call `validate()` to check current parameters.
116 */
117 class Parameters {
118 public:
119  //! Initialize grid defaults from a configuration database.
120  Parameters(const Config &config);
121 
122  //! Initialize grid defaults from a configuration database and a NetCDF variable.
123  Parameters(const Context &ctx, const std::string &filename, const std::string &variable_name,
124  Registration r);
125  //! Initialize grid defaults from a configuration database and a NetCDF variable.
126  Parameters(const Context &ctx, const File &file, const std::string &variable_name,
127  Registration r);
128 
129  //! Process -Mx and -My; set Mx and My.
131  //! Process -Lx, -Ly, -x0, -y0, -x_range, -y_range; set Lx, Ly, x0, y0.
132  void horizontal_extent_from_options(std::shared_ptr<units::System> unit_system);
133  //! Process -Mz and -Lz; set z;
134  void vertical_grid_from_options(std::shared_ptr<const Config> config);
135  //! Re-compute ownership ranges. Uses current values of Mx and My.
136  void ownership_ranges_from_options(unsigned int size);
137 
138  //! Validate data members.
139  void validate() const;
140 
141  //! Domain half-width in the X direction.
142  double Lx;
143  //! Domain half-width in the Y direction.
144  double Ly;
145  //! Domain center in the X direction.
146  double x0;
147  //! Domain center in the Y direction.
148  double y0;
149  //! Number of grid points in the X direction.
150  unsigned int Mx;
151  //! Number of grid points in the Y direction.
152  unsigned int My;
153  //! Grid registration.
155  //! Grid periodicity.
157  //! Vertical levels.
158  std::vector<double> z;
159  //! Processor ownership ranges in the X direction.
160  std::vector<unsigned int> procs_x;
161  //! Processor ownership ranges in the Y direction.
162  std::vector<unsigned int> procs_y;
163 
164 private:
165  void init_from_file(const Context &ctx, const File &file, const std::string &variable_name,
166  Registration r);
167 };
168 } // namespace grid
169 
170 class Grid;
171 
172 /** Iterator class for traversing the grid, including ghost points.
173  *
174  * Usage:
175  *
176  * `for (PointsWithGhosts p(grid, stencil_width); p; p.next()) { ... }`
177  */
179 public:
180  PointsWithGhosts(const Grid &grid, unsigned int stencil_width = 1);
181 
182  int i() const {
183  return m_i;
184  }
185  int j() const {
186  return m_j;
187  }
188 
189  void next() {
190  assert(not m_done);
191  m_i += 1;
192  if (m_i > m_i_last) {
193  m_i = m_i_first; // wrap around
194  m_j += 1;
195  }
196  if (m_j > m_j_last) {
197  m_j = m_j_first; // ensure that indexes are valid
198  m_done = true;
199  }
200  }
201 
202  operator bool() const {
203  return not m_done;
204  }
205 private:
206  int m_i, m_j;
208  bool m_done;
209 };
210 
211 /** Iterator class for traversing the grid (without ghost points).
212  *
213  * Usage:
214  *
215  * `for (Points p(grid); p; p.next()) { int i = p.i(), j = p.j(); ... }`
216  */
217 class Points : public PointsWithGhosts {
218 public:
219  Points(const Grid &g) : PointsWithGhosts(g, 0) {}
220 };
221 
222 
223 //! Describes the PISM grid and the distribution of data across processors.
224 /*!
225  This class holds parameters describing the grid, including the vertical
226  spacing and which part of the horizontal grid is owned by the processor. It
227  contains the dimensions of the PISM (4-dimensional, x*y*z*time) computational
228  box. The vertical spacing can be quite arbitrary.
229 
230  It creates and destroys a two dimensional `PETSc` `DA` (distributed array).
231  The creation of this `DA` is the point at which PISM gets distributed across
232  multiple processors.
233 
234  \section computational_grid Organization of PISM's computational grid
235 
236  PISM uses the class Grid to manage computational grids and their
237  parameters.
238 
239  Computational grids PISM can use are
240  - rectangular,
241  - equally spaced in the horizintal (X and Y) directions,
242  - distributed across processors in horizontal dimensions only (every column
243  is stored on one processor only),
244  - are periodic in both X and Y directions (in the topological sence).
245 
246  Each processor "owns" a rectangular patch of `xm` times `ym` grid points with
247  indices starting at `xs` and `ys` in the X and Y directions respectively.
248 
249  The typical code performing a point-wise computation will look like
250 
251  \code
252  for (Points p(grid); p; p.next()) {
253  const int i = p.i(), j = p.j();
254  field(i,j) = value;
255  }
256  \endcode
257 
258  For finite difference (and some other) computations we often need to know
259  values at map-plane neighbors of a grid point.
260 
261  We say that a patch owned by a processor is surrounded by a strip of "ghost"
262  grid points belonging to patches next to the one in question. This lets us to
263  access (read) values at all the eight neighbors of a grid point for *all*
264  the grid points, including ones at an edge of a processor patch *and* at an
265  edge of a computational domain.
266 
267  All the values *written* to ghost points will be lost next time ghost values
268  are updated.
269 
270  Sometimes it is beneficial to update ghost values locally (for instance when
271  a computation A uses finite differences to compute derivatives of a quantity
272  produced using a purely local (point-wise) computation B). In this case the
273  loop above can be modified to look like
274 
275  \code
276  for (PointsWithGhosts p(grid, ghost_width); p; p.next()) {
277  const int i = p.i(), j = p.j();
278  field(i,j) = value;
279  }
280  \endcode
281 */
282 class Grid {
283 public:
284  ~Grid();
285 
286  Grid(std::shared_ptr<const Context> context, const grid::Parameters &p);
287 
288  static std::shared_ptr<Grid> Shallow(std::shared_ptr<const Context> ctx, double Lx, double Ly,
289  double x0, double y0, unsigned int Mx, unsigned int My,
291 
292  static std::shared_ptr<Grid> FromFile(std::shared_ptr<const Context> ctx,
293  const std::string &filename,
294  const std::vector<std::string> &var_names,
296 
297  static std::shared_ptr<Grid> FromOptions(std::shared_ptr<const Context> ctx);
298 
299  std::shared_ptr<petsc::DM> get_dm(unsigned int dm_dof, unsigned int stencil_width) const;
300 
301  void report_parameters() const;
302 
303  void compute_point_neighbors(double X, double Y,
304  int &i_left, int &i_right,
305  int &j_bottom, int &j_top) const;
306  std::vector<int> point_neighbors(double X, double Y) const;
307  std::vector<double> interpolation_weights(double x, double y) const;
308 
309  unsigned int kBelowHeight(double height) const;
310 
311  int max_patch_size() const;
312 
313  std::shared_ptr<const Context> ctx() const;
314 
315  int xs() const;
316  int xm() const;
317  int ys() const;
318  int ym() const;
319 
320  const std::vector<double>& x() const;
321  double x(size_t i) const;
322 
323  const std::vector<double>& y() const;
324  double y(size_t i) const;
325 
326  const std::vector<double>& z() const;
327  double z(size_t i) const;
328 
329  double dx() const;
330  double dy() const;
331  double cell_area() const;
332 
333  unsigned int Mx() const;
334  unsigned int My() const;
335  unsigned int Mz() const;
336 
337  double Lx() const;
338  double Ly() const;
339  double Lz() const;
340  double x0() const;
341  double y0() const;
342 
343  const MappingInfo& get_mapping_info() const;
344  void set_mapping_info(const MappingInfo &info);
345 
346  double dz_min() const;
347  double dz_max() const;
348 
351 
352  unsigned int size() const;
353  int rank() const;
354 
355  const MPI_Comm com;
356 
357  Vars& variables();
358  const Vars& variables() const;
359 
360  int pio_io_decomposition(int dof, int output_datatype) const;
361 
362  PointsWithGhosts points(unsigned int stencil_width = 0) const {
363  return {*this, stencil_width};
364  }
365 
366 private:
367  struct Impl;
369 
370  // Hide copy constructor / assignment operator.
371  Grid(const Grid &);
372  Grid & operator=(const Grid &);
373 };
374 
375 namespace grid {
376 
377 std::vector<double> compute_vertical_levels(double new_Lz, unsigned int new_Mz,
378  grid::VerticalSpacing spacing, double Lambda = 0.0);
379 
380 //! Returns the distance from the point (i,j) to the origin.
381 double radius(const Grid &grid, int i, int j);
382 
383 //! @brief Check if a point `(i,j)` is in the strip of `stripwidth` meters around the edge
384 //! of the computational domain.
385 inline bool in_null_strip(const Grid& grid, int i, int j, double strip_width) {
386  return (strip_width > 0.0 &&
387  (grid.x(i) <= grid.x(0) + strip_width ||
388  grid.x(i) >= grid.x(grid.Mx()-1) - strip_width ||
389  grid.y(j) <= grid.y(0) + strip_width ||
390  grid.y(j) >= grid.y(grid.My()-1) - strip_width));
391 }
392 
393 /*!
394  * Return `true` if a point `(i, j)` is at an edge of the domain defined by the `grid`.
395  */
396 inline bool domain_edge(const Grid &grid, int i, int j) {
397  return ((j == 0) or (j == (int)grid.My() - 1) or (i == 0) or (i == (int)grid.Mx() - 1));
398 }
399 
400 } // namespace grid
401 
402 } // end of namespace pism
403 
404 #endif /* PISM_GRID_H */
A class for storing and accessing PISM configuration flags and parameters.
High-level PISM I/O class.
Definition: File.hh:56
double y0() const
Y-coordinate of the center of the domain.
Definition: Grid.cc:850
const std::vector< double > & x() const
X-coordinates.
Definition: Grid.cc:766
const std::vector< double > & y() const
Y-coordinates.
Definition: Grid.cc:776
unsigned int kBelowHeight(double height) const
Return the index k into zlevels[] so that zlevels[k] <= height < zlevels[k+1] and k < Mz.
Definition: Grid.cc:291
unsigned int Mz() const
Number of vertical levels.
Definition: Grid.cc:761
Grid & operator=(const Grid &)
double cell_area() const
Definition: Grid.cc:805
double Ly() const
Half-width of the computational domain.
Definition: Grid.cc:835
static std::shared_ptr< Grid > FromFile(std::shared_ptr< const Context > ctx, const std::string &filename, const std::vector< std::string > &var_names, grid::Registration r)
Create a grid using one of variables in var_names in file.
Definition: Grid.cc:255
int ys() const
Global starting index of this processor's subset.
Definition: Grid.cc:736
Grid(std::shared_ptr< const Context > context, const grid::Parameters &p)
Create a PISM distributed computational grid.
Definition: Grid.cc:162
grid::Periodicity periodicity() const
Return grid periodicity.
Definition: Grid.cc:674
int max_patch_size() const
Definition: Grid.cc:857
double Lx() const
Half-width of the computational domain.
Definition: Grid.cc:830
~Grid()
Definition: Grid.cc:274
PointsWithGhosts points(unsigned int stencil_width=0) const
Definition: Grid.hh:362
double dx() const
Horizontal grid spacing.
Definition: Grid.cc:796
const std::vector< double > & z() const
Z-coordinates within the ice.
Definition: Grid.cc:786
int rank() const
MPI rank.
Definition: Grid.cc:711
static std::shared_ptr< Grid > Shallow(std::shared_ptr< const Context > ctx, double Lx, double Ly, double x0, double y0, unsigned int Mx, unsigned int My, grid::Registration r, grid::Periodicity p)
Initialize a uniform, shallow (3 z-levels) grid with half-widths (Lx,Ly) and Mx by My nodes.
Definition: Grid.cc:134
Vars & variables()
Dictionary of variables (2D and 3D fields) associated with this grid.
Definition: Grid.cc:721
std::shared_ptr< petsc::DM > get_dm(unsigned int dm_dof, unsigned int stencil_width) const
Get a PETSc DM ("distributed array manager") object for given dof (number of degrees of freedom per g...
Definition: Grid.cc:653
unsigned int My() const
Total grid size in the Y direction.
Definition: Grid.cc:756
void compute_point_neighbors(double X, double Y, int &i_left, int &i_right, int &j_bottom, int &j_top) const
Computes indices of grid points to the lower left and upper right from (X,Y).
Definition: Grid.cc:601
int pio_io_decomposition(int dof, int output_datatype) const
Definition: Grid.cc:1361
void report_parameters() const
Report grid parameters.
Definition: Grid.cc:524
std::vector< double > interpolation_weights(double x, double y) const
Compute 4 interpolation weights necessary for linear interpolation from the current grid....
Definition: Grid.cc:631
double x0() const
X-coordinate of the center of the domain.
Definition: Grid.cc:845
grid::Registration registration() const
Definition: Grid.cc:678
Impl * m_impl
Definition: Grid.hh:367
std::shared_ptr< const Context > ctx() const
Return execution context this grid corresponds to.
Definition: Grid.cc:683
unsigned int Mx() const
Total grid size in the X direction.
Definition: Grid.cc:751
const MappingInfo & get_mapping_info() const
Definition: Grid.cc:1346
unsigned int size() const
MPI communicator size.
Definition: Grid.cc:716
std::vector< int > point_neighbors(double X, double Y) const
Definition: Grid.cc:622
const MPI_Comm com
Definition: Grid.hh:355
double Lz() const
Height of the computational domain.
Definition: Grid.cc:840
double dz_min() const
Minimum vertical spacing.
Definition: Grid.cc:810
double dz_max() const
Maximum vertical spacing.
Definition: Grid.cc:820
Grid(const Grid &)
double dy() const
Horizontal grid spacing.
Definition: Grid.cc:801
int xs() const
Global starting index of this processor's subset.
Definition: Grid.cc:731
void set_mapping_info(const MappingInfo &info)
Definition: Grid.cc:1350
static std::shared_ptr< Grid > FromOptions(std::shared_ptr< const Context > ctx)
Create a grid using command-line options and (possibly) an input file.
Definition: Grid.cc:1263
int xm() const
Width of this processor's sub-domain.
Definition: Grid.cc:741
int ym() const
Width of this processor's sub-domain.
Definition: Grid.cc:746
Describes the PISM grid and the distribution of data across processors.
Definition: Grid.hh:282
A basic logging class.
Definition: Logger.hh:40
int j() const
Definition: Grid.hh:185
int i() const
Definition: Grid.hh:182
PointsWithGhosts(const Grid &grid, unsigned int stencil_width=1)
Definition: Grid.cc:1394
Points(const Grid &g)
Definition: Grid.hh:219
A class for passing PISM variables from the core to other parts of the code (such as climate couplers...
Definition: Vars.hh:40
std::vector< double > y
y coordinates
Definition: Grid.hh:88
double Lx
domain half-width
Definition: Grid.hh:77
double z_min
minimal value of the z dimension
Definition: Grid.hh:81
unsigned int t_len
Definition: Grid.hh:71
std::string filename
Definition: Grid.hh:92
InputGridInfo(const File &file, const std::string &variable, std::shared_ptr< units::System > unit_system, Registration registration)
Definition: Grid.cc:1042
double Ly
domain half-height
Definition: Grid.hh:79
double y0
y-coordinate of the domain center
Definition: Grid.hh:75
double x0
x-coordinate of the domain center
Definition: Grid.hh:73
std::vector< double > z
z coordinates
Definition: Grid.hh:90
double z_max
maximal value of the z dimension
Definition: Grid.hh:83
std::vector< double > x
x coordinates
Definition: Grid.hh:86
std::map< std::string, AxisType > dimension_types
Definition: Grid.hh:99
std::string variable_name
Definition: Grid.hh:97
void report(const Logger &log, int threshold, std::shared_ptr< units::System > s) const
Definition: Grid.cc:1025
Contains parameters of an input file grid.
Definition: Grid.hh:65
Periodicity periodicity
Grid periodicity.
Definition: Grid.hh:156
std::vector< double > z
Vertical levels.
Definition: Grid.hh:158
void horizontal_extent_from_options(std::shared_ptr< units::System > unit_system)
Process -Lx, -Ly, -x0, -y0, -x_range, -y_range; set Lx, Ly, x0, y0.
Definition: Grid.cc:1182
void vertical_grid_from_options(std::shared_ptr< const Config > config)
Process -Mz and -Lz; set z;.
Definition: Grid.cc:1209
double y0
Domain center in the Y direction.
Definition: Grid.hh:148
double x0
Domain center in the X direction.
Definition: Grid.hh:146
std::vector< unsigned int > procs_y
Processor ownership ranges in the Y direction.
Definition: Grid.hh:162
void ownership_ranges_from_options(unsigned int size)
Re-compute ownership ranges. Uses current values of Mx and My.
Definition: Grid.cc:1142
std::vector< unsigned int > procs_x
Processor ownership ranges in the X direction.
Definition: Grid.hh:160
Registration registration
Grid registration.
Definition: Grid.hh:154
void validate() const
Validate data members.
Definition: Grid.cc:1218
Parameters(const Config &config)
Initialize grid defaults from a configuration database.
Definition: Grid.cc:1121
unsigned int Mx
Number of grid points in the X direction.
Definition: Grid.hh:150
double Ly
Domain half-width in the Y direction.
Definition: Grid.hh:144
double Lx
Domain half-width in the X direction.
Definition: Grid.hh:142
unsigned int My
Number of grid points in the Y direction.
Definition: Grid.hh:152
void horizontal_size_from_options()
Process -Mx and -My; set Mx and My.
Definition: Grid.cc:1177
void init_from_file(const Context &ctx, const File &file, const std::string &variable_name, Registration r)
Definition: Grid.cc:1148
Grid parameters; used to collect defaults before an Grid is allocated.
Definition: Grid.hh:117
double radius(const Grid &grid, int i, int j)
Returns the distance from the point (i,j) to the origin.
Definition: Grid.cc:1407
VerticalSpacing
Definition: Grid.hh:50
@ EQUAL
Definition: Grid.hh:50
@ UNKNOWN
Definition: Grid.hh:50
@ QUADRATIC
Definition: Grid.hh:50
std::string periodicity_to_string(Periodicity p)
Convert Periodicity to a STL string.
Definition: Grid.cc:947
VerticalSpacing string_to_spacing(const std::string &keyword)
Convert an STL string to SpacingType.
Definition: Grid.cc:962
Periodicity
Definition: Grid.hh:51
@ XY_PERIODIC
Definition: Grid.hh:51
@ Y_PERIODIC
Definition: Grid.hh:51
@ X_PERIODIC
Definition: Grid.hh:51
@ NOT_PERIODIC
Definition: Grid.hh:51
Registration string_to_registration(const std::string &keyword)
Definition: Grid.cc:986
Registration
Definition: Grid.hh:53
@ CELL_CENTER
Definition: Grid.hh:53
@ CELL_CORNER
Definition: Grid.hh:53
Periodicity string_to_periodicity(const std::string &keyword)
Convert a string to Periodicity.
Definition: Grid.cc:925
bool in_null_strip(const Grid &grid, int i, int j, double strip_width)
Check if a point (i,j) is in the strip of stripwidth meters around the edge of the computational doma...
Definition: Grid.hh:385
bool domain_edge(const Grid &grid, int i, int j)
Definition: Grid.hh:396
std::string spacing_to_string(VerticalSpacing s)
Convert SpacingType to an STL string.
Definition: Grid.cc:976
std::string registration_to_string(Registration registration)
Definition: Grid.cc:999
std::vector< double > compute_vertical_levels(double new_Lz, unsigned int new_Mz, grid::VerticalSpacing spacing, double lambda)
Set the vertical levels in the ice according to values in Mz (number of levels), Lz (domain height),...
Definition: Grid.cc:879
static const double g
Definition: exactTestP.cc:36
Internal structures of Grid.
Definition: Grid.cc:50