22 #include <gsl/gsl_interp.h>
27 #include "pism/util/ConfigInterface.hh"
28 #include "pism/util/Grid.hh"
29 #include "pism/util/error_handling.hh"
30 #include "pism/pism_config.hh"
31 #include "pism/util/Context.hh"
32 #include "pism/util/Logger.hh"
33 #include "pism/util/Vars.hh"
34 #include "pism/util/io/File.hh"
35 #include "pism/util/petscwrappers/DM.hh"
36 #include "pism/util/projection.hh"
37 #include "pism/util/pism_options.hh"
38 #include "pism/util/pism_utilities.hh"
39 #include "pism/util/io/IO_Flags.hh"
41 #if (Pism_USE_PIO == 1)
51 Impl(std::shared_ptr<const Context> context);
53 std::shared_ptr<petsc::DM>
create_dm(
int da_dof,
int stencil_width)
const;
55 const std::vector<unsigned int> &
procs_y);
59 std::shared_ptr<const Context>
ctx;
77 std::vector<double>
x;
79 std::vector<double>
y;
81 std::vector<double>
z;
107 std::map<std::array<unsigned int, 2>, std::weak_ptr<petsc::DM> >
dms;
127 : ctx(context), mapping_info(
"mapping", ctx->unit_system()) {
135 double x0,
double y0,
unsigned int Mx,
unsigned int My,
149 double Lz =
ctx->config()->get_number(
"grid.Lz");
150 p.
z = { 0.0, 0.5 *
Lz,
Lz };
154 return std::make_shared<Grid>(
ctx, p);
190 int stencil_width = (int)context->config()->get_number(
"grid.max_stencil_width");
193 std::shared_ptr<petsc::DM> tmp = this->
get_dm(1, stencil_width);
223 static std::shared_ptr<Grid>
Grid_FromFile(std::shared_ptr<const Context> ctx,
const File &file,
226 const Logger &log = *ctx->log();
233 if (p.
z.size() < 2) {
234 double Lz = ctx->config()->get_number(
"grid.Lz");
236 "WARNING: Can't determine vertical grid information using '%s' in %s'\n"
237 " Using 2 levels and Lz of %3.3fm\n",
238 var_name.c_str(), file.
filename().c_str(), Lz);
246 return std::make_shared<Grid>(ctx, p);
248 e.
add_context(
"initializing computational grid from variable \"%s\" in \"%s\"",
249 var_name.c_str(), file.
filename().c_str());
256 const std::string &filename,
257 const std::vector<std::string> &var_names,
262 for (
const auto &name : var_names) {
269 "file %s does not have any of %s."
270 " Cannot initialize the grid.",
271 filename.c_str(),
join(var_names,
",").c_str());
277 #if (Pism_USE_PIO == 1)
279 int ierr = PIOc_freedecomp(
m_impl->
ctx->pio_iosys_id(), p.second);
280 if (ierr != PIO_NOERR) {
281 m_impl->
ctx->log()->message(1,
"Failed to de-allocate a ParallelIO decomposition");
293 const double eps = 1.0e-6;
294 if (height < 0.0 - eps) {
296 "height = %5.4f is below base of ice"
297 " (height must be non-negative)\n",
301 if (height >
Lz() + eps) {
303 "height = %5.4f is above top of computational"
304 " grid Lz = %5.4f\n",
312 static void compute_nprocs(
unsigned int Mx,
unsigned int My,
unsigned int size,
unsigned int &Nx,
319 Nx = (
unsigned int)(0.5 + sqrt(((
double)Mx) * ((
double)size) / ((
double)My)));
328 if (Nx * Ny == (
unsigned int)size) {
334 if (Mx > My and Nx < Ny) {
343 "Can't split %d grid points into %d parts (X-direction).", Mx,
349 "Can't split %d grid points into %d parts (Y-direction).", My,
359 std::vector<unsigned int> result(Nx);
361 for (
unsigned int i = 0; i < Nx; i++) {
362 result[i] = Mx / Nx +
static_cast<unsigned int>((Mx % Nx) > i);
369 const std::vector<unsigned int> &input_procs_y) {
370 if (input_procs_x.size() * input_procs_y.size() != (
size_t)
size) {
374 procs_x.resize(input_procs_x.size());
375 for (
unsigned int k = 0;
k < input_procs_x.size(); ++
k) {
376 procs_x[
k] =
static_cast<PetscInt
>(input_procs_x[
k]);
379 procs_y.resize(input_procs_y.size());
380 for (
unsigned int k = 0;
k < input_procs_y.size(); ++
k) {
381 procs_y[
k] =
static_cast<PetscInt
>(input_procs_y[
k]);
386 std::vector<unsigned int>
x,
y;
395 unsigned int Nx_default, Ny_default;
399 options::Integer Nx(
"-Nx",
"Number of processors in the x direction", Nx_default);
400 options::Integer Ny(
"-Ny",
"Number of processors in the y direction", Ny_default);
406 "Can't split %d grid points into %d parts (X-direction).",
Mx,
412 "Can't split %d grid points into %d parts (Y-direction).",
My,
416 if (Nx * Ny != (
int)
size) {
424 if (procs_x.is_set()) {
425 if (procs_x->size() != (
unsigned int)Nx) {
429 result.
x.resize(procs_x->size());
430 for (
unsigned int k = 0;
k < procs_x->size(); ++
k) {
431 result.
x[
k] = procs_x[
k];
438 if (procs_y.is_set()) {
439 if (procs_y->size() != (
unsigned int)Ny) {
443 result.
y.resize(procs_y->size());
444 for (
unsigned int k = 0;
k < procs_y->size(); ++
k) {
445 result.
y[
k] = procs_y[
k];
451 if (result.
x.size() * result.
y.size() !=
size) {
461 return 2.0 * half_width / M;
464 return 2.0 * half_width / (M - 1);
469 double v_max,
bool cell_centered) {
470 std::vector<double> result(M);
476 for (
unsigned int i = 0; i < M; ++i) {
477 result[i] = v_min + (i + 0.5) * delta;
479 result[M - 1] = v_max - 0.5 * delta;
481 for (
unsigned int i = 0; i < M; ++i) {
482 result[i] = v_min + i * delta;
484 result[M - 1] = v_max;
514 double x_min =
x0 -
Lx, x_max =
x0 +
Lx;
518 double y_min =
y0 -
Ly, y_max =
y0 +
Ly;
529 log.
message(2,
"computational domain and grid:\n");
534 log.
message(2,
" grid size %d x %d x %d\n",
Mx(),
My(),
Mz());
537 log.
message(2,
" spatial domain %.2f km x %.2f km x %.2f m\n", km(2 *
Lx()),
541 const double one_km = 1000.0;
543 log.
message(2,
" horizontal grid cell %.2f km x %.2f km\n", km(
dx()), km(
dy()));
545 log.
message(2,
" horizontal grid cell %.0f m x %.0f m\n",
dx(),
dy());
548 log.
message(2,
" vertical spacing in ice dz = %.3f m (equal spacing)\n",
dz_min());
550 log.
message(2,
" vertical spacing in ice uneven, %d levels, %.3f m < dz < %.3f m\n",
Mz(),
556 log.
message(3,
" Grid parameters:\n");
557 log.
message(3,
" Lx = %6.2f km, Ly = %6.2f km, Lz = %6.2f m, \n", km(
Lx()), km(
Ly()),
559 log.
message(3,
" x0 = %6.2f km, y0 = %6.2f km, (coordinates of center)\n", km(
x0()),
561 log.
message(3,
" Mx = %d, My = %d, Mz = %d, \n",
Mx(),
My(),
Mz());
562 log.
message(3,
" dx = %6.3f km, dy = %6.3f km, \n", km(
dx()), km(
dy()));
566 log.
message(3,
" Registration: %s\n",
568 log.
message(3,
" Periodicity: %s\n",
573 log.
message(5,
" REALLY verbose output on Grid:\n");
574 log.
message(5,
" vertical levels in ice (Mz=%d, Lz=%5.4f): ",
Mz(),
Lz());
575 for (
unsigned int k = 0;
k <
Mz();
k++) {
606 i_right = i_left + 1;
607 j_top = j_bottom + 1;
623 int i_left, i_right, j_bottom, j_top;
625 return { i_left, i_right, j_bottom, j_top };
632 int i_left = 0, i_right = 0, j_bottom = 0, j_top = 0;
634 double alpha = 0.0, beta = 0.0;
638 if (i_left != i_right) {
643 if (j_bottom != j_top) {
648 return { (1.0 - alpha) * (1.0 - beta), alpha * (1.0 - beta), alpha * beta, (1.0 - alpha) * beta };
653 std::shared_ptr<petsc::DM>
Grid::get_dm(
unsigned int dm_dof,
unsigned int stencil_width)
const {
655 std::array<unsigned int, 2> key{ dm_dof, stencil_width };
691 ctx->log()->message(3,
"* Creating a DM with dof=%d and stencil_width=%d...\n", da_dof,
695 PetscErrorCode ierr =
696 DMDACreate2d(
ctx->com(), DM_BOUNDARY_PERIODIC, DM_BOUNDARY_PERIODIC, DMDA_STENCIL_BOX,
Mx,
My,
697 (PetscInt)procs_x.size(), (PetscInt)procs_y.size(), da_dof, stencil_width,
698 procs_x.data(), procs_y.data(),
702 #if PETSC_VERSION_GE(3, 8, 0)
703 ierr = DMSetUp(result);
707 return std::make_shared<petsc::DM>(result);
811 double result =
m_impl->
z.back();
812 for (
unsigned int k = 0;
k <
m_impl->
z.size() - 1; ++
k) {
822 for (
unsigned int k = 0;
k <
m_impl->
z.size() - 1; ++
k) {
894 std::vector<double> result(new_Mz);
899 double dz = new_Lz / ((double)new_Mz - 1);
902 for (
unsigned int k = 0;
k < new_Mz - 1;
k++) {
903 result[
k] = dz * ((double)
k);
905 result[new_Mz - 1] = new_Lz;
910 for (
unsigned int k = 0;
k < new_Mz - 1;
k++) {
911 const double zeta = ((double)
k) / ((double)new_Mz - 1);
912 result[
k] = new_Lz * ((zeta / lambda) * (1.0 + (lambda - 1.0) * zeta));
914 result[new_Mz - 1] = new_Lz;
926 if (keyword ==
"none") {
930 if (keyword ==
"x") {
934 if (keyword ==
"y") {
938 if (keyword ==
"xy") {
963 if (keyword ==
"quadratic") {
967 if (keyword ==
"equal") {
987 if (keyword ==
"center") {
991 if (keyword ==
"corner") {
1009 void InputGridInfo::reset() {
1028 log.
message(threshold,
" x: %5d points, [%10.3f, %10.3f] km, x0 = %10.3f km, Lx = %10.3f km\n",
1029 (
int)this->
x.size(), km(this->
x0 - this->
Lx), km(this->
x0 + this->
Lx), km(this->
x0),
1032 log.
message(threshold,
" y: %5d points, [%10.3f, %10.3f] km, y0 = %10.3f km, Ly = %10.3f km\n",
1033 (
int)this->
y.size(), km(this->
y0 - this->
Ly), km(this->
y0 + this->
Ly), km(this->
y0),
1036 log.
message(threshold,
" z: %5d points, [%10.3f, %10.3f] m\n", (
int)this->
z.size(), this->z_min,
1039 log.
message(threshold,
" t: %5d records\n\n", this->t_len);
1042 InputGridInfo::InputGridInfo(
const File &file,
const std::string &variable,
1048 variable_name = variable;
1053 if (not var.exists) {
1060 bool time_dimension_processed =
false;
1061 for (
const auto &dimension_name : dimensions) {
1071 this->
x0 = 0.5 * (x_min + x_max);
1072 this->
Lx = 0.5 * (x_max - x_min);
1074 const double dx = this->
x[1] - this->
x[0];
1075 this->
Lx += 0.5 *
dx;
1082 this->
y0 = 0.5 * (y_min + y_max);
1083 this->
Ly = 0.5 * (y_max - y_min);
1085 const double dy = this->
y[1] - this->
y[0];
1086 this->
Ly += 0.5 *
dy;
1097 if (time_dimension_processed) {
1103 time_dimension_processed =
false;
1115 e.
add_context(
"getting grid information using variable '%s' in '%s'", variable.c_str(),
1121 Parameters::Parameters(
const Config &config) {
1128 Mx =
static_cast<unsigned int>(config.
get_number(
"grid.Mx"));
1129 My =
static_cast<unsigned int>(config.
get_number(
"grid.My"));
1136 double lambda = config.
get_number(
"grid.lambda");
1142 void Parameters::ownership_ranges_from_options(
unsigned int size) {
1151 MPI_Comm_size(
ctx.com(), &
size);
1159 Mx = input_grid.
x.size();
1160 My = input_grid.
y.size();
1165 Parameters::Parameters(
const Context &
ctx,
const File &file,
const std::string &variable_name,
1167 init_from_file(
ctx, file, variable_name, r);
1170 Parameters::Parameters(
const Context &
ctx,
const std::string &filename,
1173 init_from_file(
ctx, file, variable_name, r);
1177 void Parameters::horizontal_size_from_options() {
1182 void Parameters::horizontal_extent_from_options(std::shared_ptr<units::System> unit_system) {
1185 const double km = 1000.0;
1186 Lx = km *
options::Real(unit_system,
"-Lx",
"Half of the grid extent in the Y direction, in km",
1188 Ly = km *
options::Real(unit_system,
"-Ly",
"Half of the grid extent in the X direction, in km",
1197 if (x_range.is_set() and y_range.is_set()) {
1198 if (x_range->size() != 2 or y_range->size() != 2) {
1201 x0 = (x_range[0] + x_range[1]) / 2.0;
1202 y0 = (y_range[0] + y_range[1]) / 2.0;
1203 Lx = (x_range[1] - x_range[0]) / 2.0;
1204 Ly = (y_range[1] - y_range[0]) / 2.0;
1210 double Lz = (not
z.empty()) ?
z.back() : config->get_number(
"grid.Lz");
1211 int Mz = (not
z.empty()) ?
z.size() : config->get_number(
"grid.Mz");
1215 config->get_number(
"grid.lambda"));
1218 void Parameters::validate()
const {
1221 "Mx = %d is invalid (has to be 3 or greater)",
Mx);
1226 "My = %d is invalid (has to be 3 or greater)",
My);
1245 if (
z.back() < 0.0) {
1249 if (std::accumulate(procs_x.begin(), procs_x.end(), 0.0) !=
Mx) {
1253 if (std::accumulate(procs_y.begin(), procs_y.end(), 0.0) !=
My) {
1264 auto config =
ctx->config();
1266 auto input_file = config->get_string(
"input.file");
1267 bool bootstrap = config->get_flag(
"input.bootstrap");
1271 auto log =
ctx->log();
1273 if (not input_file.empty() and (not bootstrap)) {
1278 if (not input_file.empty() and bootstrap) {
1284 bool grid_info_found =
false;
1288 for (
const auto *name : {
"land_ice_thickness",
"bedrock_altitude",
"thk",
"topg" }) {
1291 if (not grid_info_found) {
1297 if (grid_info_found) {
1303 if (not grid_info_found) {
1305 input_file.c_str());
1315 auto result = std::make_shared<Grid>(
ctx, input_grid);
1322 " setting computational box for ice from '%s' and\n"
1323 " user options: [%6.2f km, %6.2f km] x [%6.2f km, %6.2f km] x [0 m, %6.2f m]\n",
1324 input_file.c_str(), km(result->x0() - result->Lx()),
1325 km(result->x0() + result->Lx()), km(result->y0() - result->Ly()),
1326 km(result->y0() + result->Ly()), result->Lz());
1342 return std::make_shared<Grid>(
ctx, P);
1363 #if (Pism_USE_PIO == 1)
1365 std::array<int, 2> key{ dof, output_datatype };
1371 int ndims = dof < 2 ? 2 : 3;
1374 std::vector<int> gdimlen{(int)
My(), (int)
Mx(), dof};
1375 std::vector<long int> start{
ys(),
xs(), 0},
count{
ym(),
xm(), dof};
1377 int stat = PIOc_InitDecomp_bc(
m_impl->
ctx->pio_iosys_id(),
1378 output_datatype, ndims, gdimlen.data(),
1379 start.data(),
count.data(), &result);
1381 if (stat != PIO_NOERR) {
1383 "Failed to create a ParallelIO I/O decomposition");
1389 (void) output_datatype;
1395 m_i_first = grid.
xs() - stencil_width;
1396 m_i_last = grid.
xs() + grid.
xm() + stencil_width - 1;
1397 m_j_first = grid.
ys() - stencil_width;
1398 m_j_last = grid.
ys() + grid.
ym() + stencil_width - 1;
1408 return sqrt(grid.
x(i) * grid.
x(i) + grid.
y(j) * grid.
y(j));
double get_number(const std::string &name, UseFlag flag=REMEMBER_THIS_USE) const
std::shared_ptr< const Config > ConstPtr
std::string get_string(const std::string &name, UseFlag flag=REMEMBER_THIS_USE) const
A class for storing and accessing PISM configuration flags and parameters.
AxisType dimension_type(const std::string &name, units::System::Ptr unit_system) const
Get the "type" of a dimension.
VariableLookupData find_variable(const std::string &short_name, const std::string &std_name) const
Find a variable using its standard name and/or short name.
std::string filename() const
unsigned int dimension_length(const std::string &name) const
Get the length of a dimension.
std::vector< double > read_dimension(const std::string &name) const
Get dimension data (a coordinate variable).
std::vector< std::string > dimensions(const std::string &variable_name) const
High-level PISM I/O class.
double y0() const
Y-coordinate of the center of the domain.
const std::vector< double > & x() const
X-coordinates.
const std::vector< double > & y() const
Y-coordinates.
unsigned int kBelowHeight(double height) const
Return the index k into zlevels[] so that zlevels[k] <= height < zlevels[k+1] and k < Mz.
unsigned int Mz() const
Number of vertical levels.
double Ly() const
Half-width of the computational domain.
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.
int ys() const
Global starting index of this processor's subset.
Grid(std::shared_ptr< const Context > context, const grid::Parameters &p)
Create a PISM distributed computational grid.
grid::Periodicity periodicity() const
Return grid periodicity.
int max_patch_size() const
double Lx() const
Half-width of the computational domain.
double dx() const
Horizontal grid spacing.
const std::vector< double > & z() const
Z-coordinates within the ice.
int rank() const
MPI rank.
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.
Vars & variables()
Dictionary of variables (2D and 3D fields) associated with this grid.
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...
unsigned int My() const
Total grid size in the Y direction.
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).
int pio_io_decomposition(int dof, int output_datatype) const
void report_parameters() const
Report grid parameters.
std::vector< double > interpolation_weights(double x, double y) const
Compute 4 interpolation weights necessary for linear interpolation from the current grid....
double x0() const
X-coordinate of the center of the domain.
grid::Registration registration() const
std::shared_ptr< const Context > ctx() const
Return execution context this grid corresponds to.
unsigned int Mx() const
Total grid size in the X direction.
const MappingInfo & get_mapping_info() const
unsigned int size() const
MPI communicator size.
std::vector< int > point_neighbors(double X, double Y) const
double Lz() const
Height of the computational domain.
double dz_min() const
Minimum vertical spacing.
double dz_max() const
Maximum vertical spacing.
double dy() const
Horizontal grid spacing.
int xs() const
Global starting index of this processor's subset.
void set_mapping_info(const MappingInfo &info)
static std::shared_ptr< Grid > FromOptions(std::shared_ptr< const Context > ctx)
Create a grid using command-line options and (possibly) an input file.
int xm() const
Width of this processor's sub-domain.
int ym() const
Width of this processor's sub-domain.
Describes the PISM grid and the distribution of data across processors.
void message(int threshold, const char format[],...) const __attribute__((format(printf
Print a message to the log.
PointsWithGhosts(const Grid &grid, unsigned int stencil_width=1)
void add_context(const std::string &message)
Add a message providing some context. This way we can (sort of) get a stack trace even though C++ exc...
static RuntimeError formatted(const ErrorLocation &location, const char format[],...) __attribute__((format(printf
build a RuntimeError with a formatted message
A class for passing PISM variables from the core to other parts of the code (such as climate couplers...
Periodicity periodicity
Grid periodicity.
std::vector< double > z
Vertical levels.
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.
void vertical_grid_from_options(std::shared_ptr< const Config > config)
Process -Mz and -Lz; set z;.
double y0
Domain center in the Y direction.
double x0
Domain center in the X direction.
std::vector< unsigned int > procs_y
Processor ownership ranges in the Y direction.
void ownership_ranges_from_options(unsigned int size)
Re-compute ownership ranges. Uses current values of Mx and My.
std::vector< unsigned int > procs_x
Processor ownership ranges in the X direction.
Registration registration
Grid registration.
void validate() const
Validate data members.
unsigned int Mx
Number of grid points in the X direction.
double Ly
Domain half-width in the Y direction.
double Lx
Domain half-width in the X direction.
unsigned int My
Number of grid points in the Y direction.
void horizontal_size_from_options()
Process -Mx and -My; set Mx and My.
Grid parameters; used to collect defaults before an Grid is allocated.
std::shared_ptr< System > Ptr
#define PISM_CHK(errcode, name)
#define PISM_ERROR_LOCATION
double max(const array::Scalar &input)
Finds maximum over all the values in an array::Scalar object. Ignores ghosts.
double min(const array::Scalar &input)
Finds minimum over all the values in an array::Scalar object. Ignores ghosts.
std::string periodicity_to_string(Periodicity p)
Convert Periodicity to a STL string.
VerticalSpacing string_to_spacing(const std::string &keyword)
Convert an STL string to SpacingType.
Registration string_to_registration(const std::string &keyword)
Periodicity string_to_periodicity(const std::string &keyword)
Convert a string to Periodicity.
std::string spacing_to_string(VerticalSpacing s)
Convert SpacingType to an STL string.
std::string registration_to_string(Registration registration)
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),...
@ PISM_READONLY
open an existing file for reading only
static std::vector< AxisType > dimension_types(const File &file, const std::string &var_name, std::shared_ptr< units::System > unit_system)
bool is_increasing(const std::vector< double > &a)
Checks if a vector of doubles is strictly increasing.
static OwnershipRanges compute_ownership_ranges(unsigned int Mx, unsigned int My, unsigned int size)
static void compute_nprocs(unsigned int Mx, unsigned int My, unsigned int size, unsigned int &Nx, unsigned int &Ny)
Computes the number of processors in the X- and Y-directions.
void GlobalMax(MPI_Comm comm, double *local, double *result, int count)
static std::vector< double > compute_coordinates(unsigned int M, double delta, double v_min, double v_max, bool cell_centered)
Compute grid coordinates for one direction (X or Y).
static double compute_horizontal_spacing(double half_width, unsigned int M, bool cell_centered)
Compute horizontal grid spacing. See compute_horizontal_coordinates() for more.
double vector_min(const std::vector< double > &input)
static std::shared_ptr< Grid > Grid_FromFile(std::shared_ptr< const Context > ctx, const File &file, const std::string &var_name, grid::Registration r)
Create a grid from a file, get information from variable var_name.
static std::vector< unsigned int > ownership_ranges(unsigned int Mx, unsigned int Nx)
Computes processor ownership ranges corresponding to equal area distribution among processors.
std::string join(const std::vector< std::string > &strings, const std::string &separator)
Concatenate strings, inserting separator between elements.
double vector_max(const std::vector< double > &input)
Vars variables
A dictionary with pointers to array::Arrays, for passing them from the one component to another (e....
double cell_area
cell area (meters^2)
void set_ownership_ranges(const std::vector< unsigned int > &procs_x, const std::vector< unsigned int > &procs_y)
Set processor ownership ranges. Takes care of type conversion (unsigned int -> PetscInt).
std::shared_ptr< petsc::DM > create_dm(int da_dof, int stencil_width) const
Create a DM with the given number of dof (degrees of freedom per grid point) and stencil width.
std::vector< PetscInt > procs_y
array containing lenghts (in the y-direction) of processor sub-domains
std::map< std::array< int, 2 >, int > io_decompositions
ParallelIO I/O decompositions.
std::shared_ptr< const Context > ctx
std::vector< double > z
vertical grid levels in the ice; correspond to the storage grid
double dx
horizontal grid spacing
unsigned int Mx
number of grid points in the x-direction
std::shared_ptr< petsc::DM > dm_scalar_global
std::vector< double > y
y-coordinates of grid points
std::vector< PetscInt > procs_x
array containing lenghts (in the x-direction) of processor sub-domains
grid::Periodicity periodicity
void compute_horizontal_coordinates()
Compute horizontal spacing parameters dx and dy and grid coordinates using Mx, My,...
std::map< std::array< unsigned int, 2 >, std::weak_ptr< petsc::DM > > dms
double x0
x-coordinate of the grid center
double dy
horizontal grid spacing
grid::Registration registration
double Ly
half width of the ice model grid in y-direction (m)
unsigned int My
number of grid points in the y-direction
double Lx
half width of the ice model grid in x-direction (m)
std::vector< double > x
x-coordinates of grid points
Impl(std::shared_ptr< const Context > context)
double y0
y-coordinate of the grid center
gsl_interp_accel * bsearch_accel
GSL binary search accelerator used to speed up kBelowHeight().
Internal structures of Grid.
std::vector< unsigned int > y
std::vector< unsigned int > x