PISM, A Parallel Ice Sheet Model 2.3.0-79cae578d committed by Constantine Khrulev on 2026-03-22
Loading...
Searching...
No Matches
Grid.hh
Go to the documentation of this file.
1// Copyright (C) 2004-2025 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 "VariableMetadata.hh"
23#include "io/File.hh"
24#include <cassert>
25#include <memory> // shared_ptr
26#include <string>
27#include <vector>
28#include <map>
29
30#include <mpi.h> // MPI_Comm
31
32#include "pism/util/Interpolation1D.hh"
33#include "pism/util/GridInfo.hh"
34
35namespace pism {
36
37class Config;
38class Context;
39class File;
40class InputInterpolation;
41class Logger;
42class Vars;
43class VariableMetadata;
44
45namespace petsc {
46class DM;
47} // end of namespace petsc
48
49namespace units {
50class System;
51}
52
53namespace grid {
54
56
57VerticalSpacing string_to_spacing(const std::string &keyword);
59
60class InputGridInfo : public GridInfo {
61public:
62 InputGridInfo(const File &file, const std::string &variable,
63 std::shared_ptr<units::System> unit_system, Registration registration);
64
65 void report(const Logger &log, int threshold, std::shared_ptr<units::System> s) const;
66
67 // dimension lengths
68 unsigned int t_len;
69
70 std::string filename;
71
72 /*!
73 * Variable name *found in the file*, which may not match the one expected by PISM.
74 */
75 std::string variable_name;
76
77 std::map<std::string, AxisType> dimension_types;
78
80
81 //! z coordinates: input grids may be 3-dimensional
82 std::vector<double> z;
83private:
84 void reset();
85};
86
87
88//! Grid parameters; used to collect defaults before an Grid is allocated.
89/* Make sure that all of
90 - `horizontal_size_from_options()`
91 - `horizontal_extent_from_options()`
92 - `vertical_grid_from_options()`
93 - `ownership_ranges_from_options()`
94
95 are called *or* all data members (`Lx`, `Ly`, `x0`, `y0`, `Mx`, `My`, `z`, `periodicity`,
96 `procs_x`, `procs_y`) are set manually before using an instance of GridParameters.
97
98 Call `validate()` to check current parameters.
99*/
101public:
102 //! Initialize grid defaults from a configuration database.
103 Parameters(const Config &config);
104
105 //! Initialize grid defaults from a configuration database, but set Mx and My explicitly.
106 Parameters(const Config &config, unsigned Mx_, unsigned My_, double Lx, double Ly);
107
108 //! Initialize grid defaults from a NetCDF variable.
109 Parameters(std::shared_ptr<units::System> unit_system, const File &file,
110 const std::string &variable_name, Registration r);
111
112 static Parameters FromGridDefinition(std::shared_ptr<units::System> unit_system, const File &file,
113 const std::string &variable_name, Registration registration);
114
115 //! Process -Lx, -Ly, -x0, -y0; set Lx, Ly, x0, y0.
117 //! Process -Mz and -Lz; set z;
118 void vertical_grid_from_options(const Config &config);
119 //! Re-compute ownership ranges. Uses current values of Mx and My.
120 void ownership_ranges_from_options(const Config &config, unsigned int size);
121
122 //! Validate data members.
123 void validate() const;
124
125 //! Domain half-width in the X direction
126 double Lx;
127 //! Domain half-width in the Y direction
128 double Ly;
129 //! Domain center in the X direction
130 double x0;
131 //! Domain center in the Y direction
132 double y0;
133 //! Number of grid points in the X direction
134 unsigned int Mx;
135 //! Number of grid points in the Y direction
136 unsigned int My;
137 //! Grid registration
139 //! Grid periodicity
141 //! Vertical levels
142 std::vector<double> z;
143 //! Processor ownership ranges in the X direction
144 std::vector<unsigned int> procs_x;
145 //! Processor ownership ranges in the Y direction
146 std::vector<unsigned int> procs_y;
147
148 //! Name of the variable used to initialize the instance (empty if not used)
149 std::string variable_name;
150private:
151 Parameters();
152};
153} // namespace grid
154
155class Grid;
156
158public:
159 GridPoint() : GridPoint(0, 0, 0, 0) {
160 }
161
162 GridPoint(int i_, int j_, int i_first, int i_last) {
163 m_i = i_;
164 m_j = j_;
165 m_i_first = i_first;
166 m_i_last = i_last;
167 }
168
170 m_i += 1;
171 if (m_i > m_i_last) {
172 m_i = m_i_first; // wrap around
173 m_j += 1;
174 }
175
176 return *this;
177 }
178
180 return *this;
181 }
182
183 inline bool operator!=(GridPoint &other) const {
184 return (m_j != other.m_j) or (m_i != other.m_i);
185 }
186
187 inline int i() const {
188 return m_i;
189 }
190
191 inline int j() const {
192 return m_j;
193 }
194
195private:
196 int m_i, m_j;
199};
200
201/** Iterator class for traversing the grid, including ghost points.
202 *
203 * Usage:
204 *
205 * `for (auto p : grid.points()) { ... }`
206 */
208public:
209 GridPoints(const Grid &grid, unsigned int stencil_width = 0);
210
211 GridPoints(std::shared_ptr<const Grid> grid, unsigned int stencil_width = 0);
212
213 GridPoints(const grid::DistributedGridInfo &grid, unsigned int stencil_width = 0);
214
216 return m_begin;
217 }
219 return m_end;
220 }
221private:
224};
225
226//! Describes the PISM grid and the distribution of data across processors.
227/*!
228 This class holds parameters describing the grid, including the vertical
229 spacing and which part of the horizontal grid is owned by the processor. It
230 contains the dimensions of the PISM (4-dimensional, x*y*z*time) computational
231 box. The vertical spacing can be quite arbitrary.
232
233 It creates and destroys a two dimensional `PETSc` `DA` (distributed array).
234 The creation of this `DA` is the point at which PISM gets distributed across
235 multiple processors.
236
237 \section computational_grid Organization of PISM's computational grid
238
239 PISM uses the class Grid to manage computational grids and their
240 parameters.
241
242 Computational grids PISM can use are
243 - rectangular,
244 - equally spaced in the horizintal (X and Y) directions,
245 - distributed across processors in horizontal dimensions only (every column
246 is stored on one processor only),
247 - are periodic in both X and Y directions (in the topological sence).
248
249 Each processor "owns" a rectangular patch of `xm` times `ym` grid points with
250 indices starting at `xs` and `ys` in the X and Y directions respectively.
251
252 The typical code performing a point-wise computation will look like
253
254 \code
255 for (Points p(grid); p; p.next()) {
256 const int i = p.i(), j = p.j();
257 field(i,j) = value;
258 }
259 \endcode
260
261 For finite difference (and some other) computations we often need to know
262 values at map-plane neighbors of a grid point.
263
264 We say that a patch owned by a processor is surrounded by a strip of "ghost"
265 grid points belonging to patches next to the one in question. This lets us to
266 access (read) values at all the eight neighbors of a grid point for *all*
267 the grid points, including ones at an edge of a processor patch *and* at an
268 edge of a computational domain.
269
270 All the values *written* to ghost points will be lost next time ghost values
271 are updated.
272
273 Sometimes it is beneficial to update ghost values locally (for instance when
274 a computation A uses finite differences to compute derivatives of a quantity
275 produced using a purely local (point-wise) computation B). In this case the
276 loop above can be modified to look like
277
278 \code
279 for (PointsWithGhosts p(grid, ghost_width); p; p.next()) {
280 const int i = p.i(), j = p.j();
281 field(i,j) = value;
282 }
283 \endcode
284*/
285class Grid {
286public:
287 ~Grid();
288
289 Grid(std::shared_ptr<const Context> context, const grid::Parameters &p);
290
291 static std::shared_ptr<Grid> Shallow(std::shared_ptr<const Context> ctx, double Lx, double Ly,
292 double x0, double y0, unsigned int Mx, unsigned int My,
294
295 static std::shared_ptr<Grid> FromFile(std::shared_ptr<const Context> ctx,
296 const File &file,
297 const std::vector<std::string> &var_names,
299
300 static std::shared_ptr<Grid> FromOptions(std::shared_ptr<const Context> ctx);
301
302 std::shared_ptr<petsc::DM> get_dm(unsigned int dm_dof, unsigned int stencil_width) const;
303
304 std::shared_ptr<InputInterpolation> get_interpolation(const std::vector<double> &levels,
305 const File &input_file,
306 const std::string &variable_name,
307 InterpolationType type) const;
308
310
311 void report_parameters() const;
312
313 void compute_point_neighbors(double X, double Y,
314 int &i_left, int &i_right,
315 int &j_bottom, int &j_top) const;
316 std::vector<int> point_neighbors(double X, double Y) const;
317 std::vector<double> interpolation_weights(double x, double y) const;
318
319 unsigned int kBelowHeight(double height) const;
320
321 int max_patch_size() const;
322
323 std::shared_ptr<const Context> ctx() const;
324
325 const grid::DistributedGridInfo& info() const;
326
327 int xs() const;
328 int xm() const;
329 int ys() const;
330 int ym() const;
331
332 const std::vector<double>& x() const;
333 double x(size_t i) const;
334
335 const std::vector<double>& y() const;
336 double y(size_t i) const;
337
338 const std::vector<double>& z() const;
339 double z(size_t i) const;
340
341 double dx() const;
342 double dy() const;
343 double cell_area() const;
344
345 unsigned int Mx() const;
346 unsigned int My() const;
347 unsigned int Mz() const;
348
349 double Lx() const;
350 double Ly() const;
351 double Lz() const;
352 double x0() const;
353 double y0() const;
354
355 const VariableMetadata& get_mapping_info() const;
357
358 double dz_min() const;
359 double dz_max() const;
360
363
364 unsigned int size() const;
365 int rank() const;
366
367 const MPI_Comm com;
368
369 Vars& variables();
370 const Vars& variables() const;
371
373 return {*this, 0};
374 }
375
376 GridPoints points_with_ghosts(unsigned int stencil_width) const {
377 return {*this, stencil_width};
378 }
379
380private:
381 struct Impl;
383
384 // Hide copy constructor / assignment operator.
385 Grid(const Grid &);
386 Grid & operator=(const Grid &);
387};
388
389namespace grid {
390
391std::vector<double> compute_vertical_levels(double new_Lz, size_t new_Mz,
392 grid::VerticalSpacing spacing, double Lambda = 0.0);
393
394//! Returns the distance from the point (i,j) to the origin.
395double radius(const Grid &grid, int i, int j);
396
397//! @brief Check if a point `(i,j)` is in the strip of `stripwidth` meters around the edge
398//! of the computational domain.
399inline bool in_null_strip(const Grid& grid, int i, int j, double strip_width) {
400 return (strip_width > 0.0 &&
401 (grid.x(i) <= grid.x(0) + strip_width ||
402 grid.x(i) >= grid.x(grid.Mx()-1) - strip_width ||
403 grid.y(j) <= grid.y(0) + strip_width ||
404 grid.y(j) >= grid.y(grid.My()-1) - strip_width));
405}
406
407/*!
408 * Return `true` if a point `(i, j)` is at an edge of the domain defined by the `grid`.
409 */
410inline bool domain_edge(const Grid &grid, int i, int j) {
411 return ((j == 0) or (j == (int)grid.My() - 1) or (i == 0) or (i == (int)grid.Mx() - 1));
412}
413
414std::array<unsigned, 2> nprocs(unsigned int size, unsigned int Mx,
415 unsigned int My);
416
417std::vector<unsigned int> ownership_ranges(unsigned int Mx, unsigned int Nx);
418
419} // namespace grid
420
421} // end of namespace pism
422
423#endif /* PISM_GRID_H */
A class for storing and accessing PISM configuration flags and parameters.
Definition Config.hh:56
High-level PISM I/O class.
Definition File.hh:57
GridPoint & operator++()
Definition Grid.hh:169
GridPoint & operator*()
Definition Grid.hh:179
GridPoint(int i_, int j_, int i_first, int i_last)
Definition Grid.hh:162
bool operator!=(GridPoint &other) const
Definition Grid.hh:183
int j() const
Definition Grid.hh:191
int i() const
Definition Grid.hh:187
GridPoint & begin()
Definition Grid.hh:215
GridPoint m_end
Definition Grid.hh:223
GridPoint & end()
Definition Grid.hh:218
GridPoint m_begin
Definition Grid.hh:222
double y0() const
Y-coordinate of the center of the domain.
Definition Grid.cc:680
const std::vector< double > & x() const
X-coordinates.
Definition Grid.cc:594
const std::vector< double > & y() const
Y-coordinates.
Definition Grid.cc:604
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:241
unsigned int Mz() const
Number of vertical levels.
Definition Grid.cc:589
double cell_area() const
Definition Grid.cc:633
double Ly() const
Half-width of the computational domain.
Definition Grid.cc:665
int ys() const
Global starting index of this processor's subset.
Definition Grid.cc:564
GridPoints points() const
Definition Grid.hh:372
grid::Periodicity periodicity() const
Return grid periodicity.
Definition Grid.cc:498
int max_patch_size() const
Definition Grid.cc:687
double Lx() const
Half-width of the computational domain.
Definition Grid.cc:660
double dx() const
Horizontal grid spacing.
Definition Grid.cc:624
const grid::DistributedGridInfo & info() const
Definition Grid.cc:511
const std::vector< double > & z() const
Z-coordinates within the ice.
Definition Grid.cc:614
int rank() const
MPI rank.
Definition Grid.cc:539
static std::shared_ptr< Grid > FromFile(std::shared_ptr< const Context > ctx, const File &file, 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:216
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:100
Vars & variables()
Dictionary of variables (2D and 3D fields) associated with this grid.
Definition Grid.cc:549
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:477
unsigned int My() const
Total grid size in the Y direction.
Definition Grid.cc:584
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:425
void report_parameters() const
Report grid parameters.
Definition Grid.cc:350
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:455
double x0() const
X-coordinate of the center of the domain.
Definition Grid.cc:675
grid::Registration registration() const
Definition Grid.cc:502
const VariableMetadata & get_mapping_info() const
Definition Grid.cc:1567
Impl * m_impl
Definition Grid.hh:382
std::shared_ptr< const Context > ctx() const
Return execution context this grid corresponds to.
Definition Grid.cc:507
unsigned int Mx() const
Total grid size in the X direction.
Definition Grid.cc:579
unsigned int size() const
MPI communicator size.
Definition Grid.cc:544
std::shared_ptr< InputInterpolation > get_interpolation(const std::vector< double > &levels, const File &input_file, const std::string &variable_name, InterpolationType type) const
Definition Grid.cc:1576
std::vector< int > point_neighbors(double X, double Y) const
Definition Grid.cc:446
const MPI_Comm com
Definition Grid.hh:367
Grid & operator=(const Grid &)
double Lz() const
Height of the computational domain.
Definition Grid.cc:670
double dz_min() const
Minimum vertical spacing.
Definition Grid.cc:638
GridPoints points_with_ghosts(unsigned int stencil_width) const
Definition Grid.hh:376
double dz_max() const
Maximum vertical spacing.
Definition Grid.cc:649
Grid(const Grid &)
void set_mapping_info(const VariableMetadata &info)
Definition Grid.cc:1571
double dy() const
Horizontal grid spacing.
Definition Grid.cc:629
int xs() const
Global starting index of this processor's subset.
Definition Grid.cc:559
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:1431
int xm() const
Width of this processor's sub-domain.
Definition Grid.cc:569
int ym() const
Width of this processor's sub-domain.
Definition Grid.cc:574
void forget_interpolations()
Definition Grid.cc:1595
Describes the PISM grid and the distribution of data across processors.
Definition Grid.hh:285
A basic logging class.
Definition Logger.hh:40
A class for passing PISM variables from the core to other parts of the code (such as climate couplers...
Definition Vars.hh:42
unsigned int t_len
Definition Grid.hh:68
std::string filename
Definition Grid.hh:70
std::vector< double > z
z coordinates: input grids may be 3-dimensional
Definition Grid.hh:82
std::map< std::string, AxisType > dimension_types
Definition Grid.hh:77
std::string variable_name
Definition Grid.hh:75
void report(const Logger &log, int threshold, std::shared_ptr< units::System > s) const
Definition Grid.cc:855
Periodicity periodicity
Grid periodicity.
Definition Grid.hh:140
std::vector< double > z
Vertical levels.
Definition Grid.hh:142
std::string variable_name
Name of the variable used to initialize the instance (empty if not used)
Definition Grid.hh:149
void vertical_grid_from_options(const Config &config)
Process -Mz and -Lz; set z;.
Definition Grid.cc:1316
double y0
Domain center in the Y direction.
Definition Grid.hh:132
double x0
Domain center in the X direction.
Definition Grid.hh:130
std::vector< unsigned int > procs_y
Processor ownership ranges in the Y direction.
Definition Grid.hh:146
void ownership_ranges_from_options(const Config &config, unsigned int size)
Re-compute ownership ranges. Uses current values of Mx and My.
Definition Grid.cc:1181
std::vector< unsigned int > procs_x
Processor ownership ranges in the X direction.
Definition Grid.hh:144
void horizontal_size_and_extent_from_options(const Config &config)
Process -Lx, -Ly, -x0, -y0; set Lx, Ly, x0, y0.
Definition Grid.cc:1288
Registration registration
Grid registration.
Definition Grid.hh:138
static Parameters FromGridDefinition(std::shared_ptr< units::System > unit_system, const File &file, const std::string &variable_name, Registration registration)
Definition Grid.cc:1024
void validate() const
Validate data members.
Definition Grid.cc:1325
unsigned int Mx
Number of grid points in the X direction.
Definition Grid.hh:134
double Ly
Domain half-width in the Y direction.
Definition Grid.hh:128
double Lx
Domain half-width in the X direction.
Definition Grid.hh:126
unsigned int My
Number of grid points in the Y direction.
Definition Grid.hh:136
Grid parameters; used to collect defaults before an Grid is allocated.
Definition Grid.hh:100
VerticalSpacing
Definition Grid.hh:55
@ EQUAL
Definition Grid.hh:55
@ UNKNOWN
Definition Grid.hh:55
@ QUADRATIC
Definition Grid.hh:55
VerticalSpacing string_to_spacing(const std::string &keyword)
Convert an STL string to SpacingType.
Definition Grid.cc:793
std::vector< unsigned int > ownership_ranges(unsigned int Mx, unsigned int Nx)
Computes processor ownership ranges corresponding to equal area distribution among processors.
Definition Grid.cc:1416
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:399
bool domain_edge(const Grid &grid, int i, int j)
Definition Grid.hh:410
std::string spacing_to_string(VerticalSpacing s)
Convert SpacingType to an STL string.
Definition Grid.cc:807
std::vector< double > compute_vertical_levels(double new_Lz, size_t 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:710
std::array< unsigned, 2 > nprocs(unsigned int size, unsigned int Mx, unsigned int My)
Computes the number of processors in the X- and Y-directions.
Definition Grid.cc:1372
std::shared_ptr< Grid > grid(std::shared_ptr< Context > ctx)
Definition pism.cc:173
Internal structures of Grid.
Definition Grid.cc:53
const double radius
Definition test_cube.c:18