24#include <gsl/gsl_interp.h>
33#include "pism/util/Config.hh"
34#include "pism/util/Context.hh"
35#include "pism/util/Grid.hh"
36#include "pism/util/GridInfo.hh"
37#include "pism/util/InputInterpolation.hh"
38#include "pism/util/Interpolation1D.hh"
39#include "pism/util/Logger.hh"
40#include "pism/util/VariableMetadata.hh"
41#include "pism/util/Vars.hh"
42#include "pism/util/error_handling.hh"
43#include "pism/util/io/File.hh"
44#include "pism/util/io/IO_Flags.hh"
45#include "pism/util/io/io_helpers.hh"
46#include "pism/util/petscwrappers/DM.hh"
47#include "pism/util/pism_utilities.hh"
48#include "pism/util/projection.hh"
54 Impl(std::shared_ptr<const Context> context);
56 std::shared_ptr<petsc::DM>
create_dm(
unsigned int da_dof,
unsigned int stencil_width)
const;
58 const std::vector<unsigned int> &
procs_y);
62 std::shared_ptr<const Context>
ctx;
71 std::map<std::array<unsigned int, 2>, std::weak_ptr<petsc::DM> >
dms;
86 std::map<std::string, std::shared_ptr<InputInterpolation>>
regridding_2d;
89 std::vector<double>
z;
93 : ctx(context), mapping_info(
"mapping", ctx->unit_system()) {
101 double x0,
double y0,
unsigned int Mx,
unsigned int My,
111 double Lz =
ctx->config()->get_number(
"grid.Lz");
112 p.
z = { 0.0, 0.5 *
Lz,
Lz };
116 return std::make_shared<Grid>(
ctx, p);
152 int stencil_width = (
int)context->config()->get_number(
"grid.max_stencil_width");
155 auto tmp = this->
get_dm(1, stencil_width);
188 const Logger &log = *ctx->log();
195 if (p.
z.size() < 2) {
196 double Lz = ctx->config()->get_number(
"grid.Lz");
198 "WARNING: Can't determine vertical grid information using '%s' in %s'\n"
199 " Using 2 levels and Lz of %3.3fm\n",
200 var_name.c_str(), file.
name().c_str(), Lz);
207 return std::make_shared<Grid>(ctx, p);
209 e.
add_context(
"initializing computational grid from variable \"%s\" in \"%s\"",
210 var_name.c_str(), file.
name().c_str());
218 const std::vector<std::string> &var_names,
221 for (
const auto &name : var_names) {
228 "file %s does not have any of %s."
229 " Cannot initialize the grid.",
230 file.
name().c_str(),
join(var_names,
",").c_str());
243 const double eps = 1.0e-6;
244 if (height < 0.0 - eps) {
246 "height = %5.4f is below base of ice"
247 " (height must be non-negative)\n",
251 if (height >
Lz() + eps) {
253 "height = %5.4f is above top of computational"
254 " grid Lz = %5.4f\n",
265 const std::vector<unsigned int> &input_procs_y) {
266 if (input_procs_x.size() * input_procs_y.size() != (
size_t)
size) {
270 procs_x.resize(input_procs_x.size());
271 for (
unsigned int k = 0;
k < input_procs_x.size(); ++
k) {
272 procs_x[
k] =
static_cast<PetscInt
>(input_procs_x[
k]);
275 procs_y.resize(input_procs_y.size());
276 for (
unsigned int k = 0;
k < input_procs_y.size(); ++
k) {
277 procs_y[
k] =
static_cast<PetscInt
>(input_procs_y[
k]);
283 auto M = std::floor(2 * half_width /
dx) + (cell_centered ? 0 : 1);
285 return static_cast<unsigned int>(M);
291 return 2.0 * half_width / M;
294 return 2.0 * half_width / (M - 1);
299 double v_max,
bool cell_centered) {
301 double offset = cell_centered ? 0.5 : 0.0;
306 std::vector<double> result(M);
307 for (
unsigned int i = 0; i < M; ++i) {
308 result[i] = v_min + (i + offset) * delta;
310 result[M - 1] = v_max - offset * delta;
340 double x_min =
x0 -
Lx, x_max =
x0 +
Lx;
344 double y_min =
y0 -
Ly, y_max =
y0 +
Ly;
358 log.
message(2,
" grid size %d x %d x %d\n",
Mx(),
My(),
Mz());
361 log.
message(2,
" spatial domain %.2f km x %.2f km x %.2f m\n", km(2 *
Lx()),
365 const double one_km = 1000.0;
366 if (std::min(
dx(),
dy()) > one_km) {
367 log.
message(2,
" horizontal grid cell %.2f km x %.2f km\n", km(
dx()), km(
dy()));
369 log.
message(2,
" horizontal grid cell %.0f m x %.0f m\n",
dx(),
dy());
372 log.
message(2,
" vertical spacing in ice dz = %.3f m (equal spacing)\n",
dz_min());
374 log.
message(2,
" vertical spacing in ice uneven, %d levels, %.3f m < dz < %.3f m\n",
Mz(),
380 log.
message(3,
" Grid parameters:\n");
381 log.
message(3,
" Lx = %6.2f km, Ly = %6.2f km, Lz = %6.2f m, \n", km(
Lx()), km(
Ly()),
383 log.
message(3,
" x0 = %6.2f km, y0 = %6.2f km, (coordinates of center)\n", km(
x0()),
385 log.
message(3,
" Mx = %d, My = %d, Mz = %d, \n",
Mx(),
My(),
Mz());
386 log.
message(3,
" dx = %6.3f km, dy = %6.3f km, \n", km(
dx()), km(
dy()));
390 log.
message(3,
" Registration: %s\n",
392 log.
message(3,
" Periodicity: %s\n",
397 log.
message(5,
" REALLY verbose output on Grid:\n");
398 log.
message(5,
" vertical levels in ice (Mz=%d, Lz=%5.4f): ",
Mz(),
Lz());
399 for (
unsigned int k = 0;
k <
Mz();
k++) {
430 i_right = i_left + 1;
431 j_top = j_bottom + 1;
433 i_left = std::max(i_left, 0);
434 i_right = std::max(i_right, 0);
436 i_left = std::min(i_left, (
int)
m_impl->
Mx - 1);
437 i_right = std::min(i_right, (
int)
m_impl->
Mx - 1);
439 j_bottom = std::max(j_bottom, 0);
440 j_top = std::max(j_top, 0);
442 j_bottom = std::min(j_bottom, (
int)
m_impl->
My - 1);
443 j_top = std::min(j_top, (
int)
m_impl->
My - 1);
447 int i_left, i_right, j_bottom, j_top;
449 return { i_left, i_right, j_bottom, j_top };
456 int i_left = 0, i_right = 0, j_bottom = 0, j_top = 0;
458 double alpha = 0.0, beta = 0.0;
462 if (i_left != i_right) {
467 if (j_bottom != j_top) {
472 return { (1.0 - alpha) * (1.0 - beta), alpha * (1.0 - beta), alpha * beta, (1.0 - alpha) * beta };
477std::shared_ptr<petsc::DM>
Grid::get_dm(
unsigned int dm_dof,
unsigned int stencil_width)
const {
479 std::array<unsigned int, 2> key{ dm_dof, stencil_width };
519 ctx->log()->message(3,
"* Creating a DM with dof=%d and stencil_width=%d...\n", da_dof,
523 PetscErrorCode ierr = DMDACreate2d(
524 ctx->com(), DM_BOUNDARY_PERIODIC, DM_BOUNDARY_PERIODIC, DMDA_STENCIL_BOX, (PetscInt)
Mx,
525 (PetscInt)
My, (PetscInt)procs_x.size(), (PetscInt)procs_y.size(), (PetscInt)da_dof,
526 (PetscInt)stencil_width, procs_x.data(), procs_y.data(),
530#if PETSC_VERSION_GE(3, 8, 0)
531 ierr = DMSetUp(result);
535 return std::make_shared<petsc::DM>(result);
640 double result =
z.back();
641 for (
unsigned int k = 0;
k <
z.size() - 1; ++
k) {
642 const double dz =
z[
k + 1] -
z[
k];
643 result = std::min(dz, result);
652 for (
unsigned int k = 0;
k <
z.size() - 1; ++
k) {
653 const double dz =
z[
k + 1] -
z[
k];
654 result = std::max(dz, result);
721 if (spacing == grid::QUADRATIC and lambda <= 0) {
725 std::vector<double> result(new_Mz);
730 double dz = new_Lz / ((
double)new_Mz - 1);
733 for (
unsigned int k = 0; k < new_Mz - 1; k++) {
734 result[k] = dz * ((
double)k);
736 result[new_Mz - 1] = new_Lz;
739 case grid::QUADRATIC: {
741 for (
unsigned int k = 0; k < new_Mz - 1; k++) {
743 result[k] = new_Lz * ((zeta / lambda) * (1.0 + (lambda - 1.0) * zeta));
745 result[new_Mz - 1] = new_Lz;
757 if (keyword ==
"none") {
761 if (keyword ==
"x") {
765 if (keyword ==
"y") {
769 if (keyword ==
"xy") {
773 throw RuntimeError::formatted(
PISM_ERROR_LOCATION,
"grid periodicity type '%s' is invalid.",
794 if (keyword ==
"quadratic") {
798 if (keyword ==
"equal") {
802 throw RuntimeError::formatted(
PISM_ERROR_LOCATION,
"ice vertical spacing type '%s' is invalid.",
818 if (keyword ==
"center") {
822 if (keyword ==
"corner") {
831 switch (registration) {
840void InputGridInfo::reset() {
852 longitude_latitude =
false;
856 if (longitude_latitude) {
858 " lon: %5d points, [%7.3f, %7.3f] degree, x0 = %7.3f degree, Lx = %7.3f degree\n",
859 (
int)this->x.size(), this->x0 - this->Lx, this->x0 + this->Lx, this->x0, this->Lx);
861 " lat: %5d points, [%7.3f, %7.3f] degree, y0 = %7.3f degree, Ly = %7.3f degree\n",
862 (
int)this->y.size(), this->y0 - this->Ly, this->y0 + this->Ly, this->y0, this->Ly);
867 " x: %5d points, [%10.3f, %10.3f] km, x0 = %10.3f km, Lx = %10.3f km\n",
868 (
int)this->x.size(), km(this->x0 - this->Lx), km(this->x0 + this->Lx), km(this->x0),
872 " y: %5d points, [%10.3f, %10.3f] km, y0 = %10.3f km, Ly = %10.3f km\n",
873 (
int)this->y.size(), km(this->y0 - this->Ly), km(this->y0 + this->Ly), km(this->y0),
880 log.
message(threshold,
" z: %5d points, [%10.3f, %10.3f] m\n", (
int)this->z.size(),
884 log.
message(threshold,
" t: %5d records\n\n", this->t_len);
887InputGridInfo::InputGridInfo(
const File &file,
const std::string &variable,
892 filename = file.
name();
893 variable_name = variable;
898 if (not var.exists) {
905 bool time_dimension_processed =
false;
906 for (
const auto &dimension_name : file.
dimensions(var.name)) {
910 std::vector<double> data;
911 double center, half_width, v_min, v_max;
916 std::string units =
"meters";
919 if (mapping.get_string(
"grid_mapping_name") ==
"rotated_latitude_longitude" or
920 set_member(std_name, {
"grid_latitude",
"grid_longitude" }) or
921 set_member(dimension_name, {
"rlat",
"rlon" })) {
923 longitude_latitude =
true;
928 if (std_name ==
"longitude" or
set_member(dimension_name, {
"lon",
"longitude"})) {
929 units =
"degree_east";
930 longitude_latitude =
true;
932 if (std_name ==
"latitude" or
set_member(dimension_name, {
"lat",
"latitude"})) {
933 units =
"degree_north";
934 longitude_latitude =
true;
937 data = io::read_1d_variable(file, dimension_name, units, unit_system);
938 if (data.size() < 2) {
940 "length(%s) in %s has to be at least 2",
941 dimension_name.c_str(), file.
name().c_str());
944 data = io::read_1d_variable(file, dimension_name,
"meters", unit_system);
949 center = 0.5 * (v_min + v_max);
951 half_width = 0.5 * (v_max - v_min);
953 auto spacing = std::abs(data[1] - data[0]);
954 half_width += 0.5 * spacing;
960 this->dimension_types[dimension_name] = dimtype;
966 this->Lx = half_width;
972 this->Ly = half_width;
980 if (time_dimension_processed) {
986 time_dimension_processed =
true;
998 e.
add_context(
"getting grid information using variable '%s' in '%s'", variable.c_str(),
999 file.
name().c_str());
1008 for (
unsigned int k = 0; k < n_variables; ++k) {
1013 for (
unsigned int a = 0; a < n_attributes; ++a) {
1020 throw RuntimeError::formatted(
PISM_ERROR_LOCATION,
"failed to find a domain variable in '%s",
1021 file.
name().c_str());
1024Parameters Parameters::FromGridDefinition(std::shared_ptr<units::System> unit_system,
1025 const File &file,
const std::string &variable_name,
1035 std::vector<std::string> dimensions;
1037 if (variable_name.empty()) {
1044 if (not dimension_list.empty()) {
1045 dimensions =
split(dimension_list,
' ');
1051 for (
const auto &dimension_name : dimensions) {
1055 unsigned int length = 0;
1056 double half_width = 0.0;
1058 auto dimension_type = file.
dimension_type(dimension_name, unit_system);
1060 if (not(dimension_type ==
X_AXIS or dimension_type ==
Y_AXIS)) {
1066 if (not bounds_name.empty()) {
1067 auto bounds = io::read_bounds(file, bounds_name,
"meters", unit_system);
1069 if (bounds.size() < 2) {
1071 "length(%s) in '%s' has to be at least 2",
1072 bounds_name.c_str(), file.
name().c_str());
1077 length =
static_cast<unsigned int>(bounds.size()) / 2;
1079 half_width = (v_max - v_min) / 2.0;
1081 auto dimension = io::read_1d_variable(file, dimension_name,
"meters", unit_system);
1083 if (dimension.size() < 2) {
1085 "length(%s) in '%s' has to be at least 2",
1086 dimension_name.c_str(), file.
name().c_str());
1091 length =
static_cast<unsigned int>(dimension.size());
1093 half_width = (v_max - v_min) / 2.0;
1096 auto spacing = std::abs(dimension[1] - dimension[0]);
1097 half_width += 0.5 * spacing;
1101 double center = (v_min + v_max) / 2.0;
1103 switch (dimension_type) {
1106 result.
Lx = half_width;
1112 result.
Ly = half_width;
1122 if (result.
Mx == 0) {
1124 "failed to initialize the X grid dimension from '%s' in '%s'",
1128 if (result.
My == 0) {
1130 "failed to initialize the Y grid dimension from '%s' in '%s'",
1137Parameters::Parameters() {
1183 unsigned int Nx = 0;
1184 unsigned int Ny = 0;
1186 Nx =
static_cast<unsigned int>(config.
get_number(
"grid.Nx"));
1187 Ny =
static_cast<unsigned int>(config.
get_number(
"grid.Ny"));
1196 std::vector<unsigned> px, py;
1200 if ((
Mx / Nx) < 2) {
1202 "Can't split %d grid points into %d parts (X-direction).",
Mx,
1206 if ((
My / Ny) < 2) {
1208 "Can't split %d grid points into %d parts (Y-direction).",
My,
1212 if (Nx * Ny != size) {
1220 if (not grid_procs_x.empty()) {
1221 if (grid_procs_x.size() != (
unsigned int)Nx) {
1225 px.resize(grid_procs_x.size());
1226 for (
unsigned int k = 0;
k < Nx; ++
k) {
1227 px[
k] = grid_procs_x[
k];
1234 if (not grid_procs_y.empty()) {
1235 if (grid_procs_y.size() != (
unsigned int)Ny) {
1240 for (
unsigned int k = 0;
k < Ny; ++
k) {
1241 py[
k] = grid_procs_y[
k];
1247 if (px.size() * py.size() != size) {
1265 Mx = input_grid.
x.size();
1266 My = input_grid.
y.size();
1274template <
typename T>
1281 if (units !=
nullptr) {
1282 output =
static_cast<T
>(config.
get_number(name, units));
1284 output =
static_cast<T
>(config.
get_number(name));
1296 double dx = config.
get_number(
"grid.dx",
"m");
1297 double dy = config.
get_number(
"grid.dy",
"m");
1307 Lx = (
Mx - 1) * dx / 2.0;
1308 Ly = (
My - 1) * dy / 2.0;
1317 double Lz = (not
z.empty()) ?
z.back() : config.
get_number(
"grid.Lz");
1318 size_t Mz = (not
z.empty()) ?
z.size() :
static_cast<size_t>(config.
get_number(
"grid.Mz"));
1328 "Mx = %d is invalid (has to be 3 or greater)",
Mx);
1333 "My = %d is invalid (has to be 3 or greater)",
My);
1354 if (
z.back() < 0.0) {
1368 return sqrt(grid.x(i) * grid.x(i) + grid.y(j) * grid.y(j));
1372std::array<unsigned, 2>
nprocs(
unsigned int size,
unsigned int Mx,
1379 unsigned int Nx = (
unsigned int)(0.5 + sqrt(((
double)Mx) * ((
double)size) / ((
double)My)));
1380 unsigned int Ny = 0;
1388 if (Nx * Ny == (
unsigned int)size) {
1394 if (Mx > My and Nx < Ny) {
1399 if ((Mx / Nx) < 2) {
1401 "Can't split %d grid points into %d parts (X-direction).", Mx,
1405 if ((My / Ny) < 2) {
1407 "Can't split %d grid points into %d parts (Y-direction).", My,
1418 std::vector<unsigned int> result(Nx);
1420 for (
unsigned int i = 0; i < Nx; i++) {
1421 result[i] = Mx / Nx +
static_cast<unsigned int>((Mx % Nx) > i);
1432 auto config =
ctx->config();
1433 auto unit_system =
ctx->unit_system();
1434 auto log =
ctx->log();
1438 bool bootstrap = config->get_flag(
"input.bootstrap");
1440 auto grid_file_name = config->get_string(
"grid.file");
1441 if (bootstrap and not grid_file_name.empty()) {
1442 auto parts =
split(grid_file_name,
':');
1443 auto file_name = parts[0];
1444 std::string variable_name = parts.size() == 2 ? parts[1] :
"";
1452 P.horizontal_size_and_extent_from_options(*config);
1454 P.vertical_grid_from_options(*config);
1456 P.ownership_ranges_from_options(*config,
ctx->size());
1458 auto result = std::make_shared<Grid>(
ctx, P);
1461 result->set_mapping_info(mapping_info);
1467 " setting computational box for ice from variable '%s' in grid definition file '%s'\n"
1468 " and user options: [%6.2f km, %6.2f km] x [%6.2f km, %6.2f km] x [0 m, %6.2f m]\n",
1469 P.variable_name.c_str(), grid_file_name.c_str(), km(result->x0() - result->Lx()),
1470 km(result->x0() + result->Lx()), km(result->y0() - result->Ly()),
1471 km(result->y0() + result->Ly()), result->Lz());
1476 auto input_file_name = config->get_string(
"input.file");
1478 if (not input_file_name.empty()) {
1482 std::vector<std::string> candidates = {
"enthalpy",
"temp" };
1484 candidates = {
"land_ice_thickness",
"bedrock_altitude",
"thk",
"topg" };
1488 std::string variable_name;
1489 for (
const auto &name : candidates) {
1492 variable_name = V.
name;
1498 if (variable_name.empty()) {
1502 input_file_name.c_str(), list.c_str());
1519 auto result = std::make_shared<Grid>(
ctx, input_grid);
1526 result->set_mapping_info(grid_mapping);
1531 " setting computational box for ice from variable '%s' in '%s'\n"
1532 " and user options: [%6.2f km, %6.2f km] x [%6.2f km, %6.2f km] x [0 m, %6.2f m]\n",
1533 variable_name.c_str(), input_file_name.c_str(), km(result->x0() - result->Lx()),
1534 km(result->x0() + result->Lx()), km(result->y0() - result->Ly()),
1535 km(result->y0() + result->Ly()), result->Lz());
1547 result->set_mapping_info(grid_mapping);
1563 return std::make_shared<Grid>(
ctx, P);
1577 const File &input_file,
1578 const std::string &variable_name,
1583 if (levels.size() < 2) {
1608 int W =
static_cast<int>(stencil_width);
1609 int i_first = grid.xs - W;
1610 int i_last = grid.xs + grid.xm + W - 1;
1612 int j_first = grid.ys - W;
1613 int j_last = grid.ys + grid.ym + W - 1;
double get_number(const std::string &name, UseFlag flag=REMEMBER_THIS_USE) const
bool is_valid_number(const std::string &name) const
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.
unsigned int nvariables() const
std::string attribute_name(const std::string &var_name, unsigned int n) const
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 variable_name(unsigned int id) const
bool variable_exists(const std::string &short_name) const
Checks if a variable exists.
unsigned int nattributes(const std::string &var_name) const
unsigned int dimension_length(const std::string &name) const
Get the length of a dimension.
std::vector< std::string > dimensions(const std::string &variable_name) const
std::string read_text_attribute(const std::string &var_name, const std::string &att_name) const
Get a text attribute.
High-level PISM I/O class.
GridPoints(const Grid &grid, unsigned int stencil_width=0)
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.
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 grid::DistributedGridInfo & info() const
const std::vector< double > & z() const
Z-coordinates within the ice.
int rank() const
MPI rank.
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.
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).
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
const VariableMetadata & get_mapping_info() 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.
unsigned int size() const
MPI communicator size.
std::shared_ptr< InputInterpolation > get_interpolation(const std::vector< double > &levels, const File &input_file, const std::string &variable_name, InterpolationType type) const
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.
void set_mapping_info(const VariableMetadata &info)
double dy() const
Horizontal grid spacing.
int xs() const
Global starting index of this processor's subset.
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.
void forget_interpolations()
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.
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...
int max_patch_size
Number of grid points in the largest patch (max(xm*ym) over all MPI ranks)
double dx
Grid spacing in the X direction.
unsigned int Mx
Total number of grid points in the X direction.
unsigned int ys
Starting index of the patch owned by the current MPI rank (X direction)
int rank
Current MPI rank.
double cell_area
Cell area (meters^2) (same as dx*dy)
grid::Periodicity periodicity
Grid periodicity in X and Y directions.
double dy
Grid spacing in the Y direction.
int size
MPI Communicator size.
unsigned int xs
Starting index (in the X direction) of the patch owned by the current MPI rank.
unsigned int My
Total number of grid points in the Y direction.
grid::Registration registration
Grid registration (cell center or cell corner)
double Lx
domain half-width in the X direction
std::vector< double > y
y coordinates
double y0
y-coordinate of the domain center
double x0
x-coordinate of the domain center
std::vector< double > x
x coordinates
double Ly
domain half-width in the Y direction
Periodicity periodicity
Grid periodicity.
std::vector< double > z
Vertical levels.
std::string variable_name
Name of the variable used to initialize the instance (empty if not used)
void vertical_grid_from_options(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(const Config &config, 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.
void horizontal_size_and_extent_from_options(const Config &config)
Process -Lx, -Ly, -x0, -y0; set Lx, Ly, x0, y0.
Registration registration
Grid registration.
static Parameters FromGridDefinition(std::shared_ptr< units::System > unit_system, const File &file, const std::string &variable_name, Registration 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.
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
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.
std::vector< unsigned int > ownership_ranges(unsigned int Mx, unsigned int Nx)
Computes processor ownership ranges corresponding to equal area distribution among processors.
Registration string_to_registration(const std::string &keyword)
std::string get_domain_variable(const File &file)
Get a list of dimensions from a grid definition file.
Periodicity string_to_periodicity(const std::string &keyword)
Convert a string to Periodicity.
static void maybe_override(const Config &config, const char *name, const char *units, T &output)
std::string spacing_to_string(VerticalSpacing s)
Convert SpacingType to an STL string.
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),...
std::string registration_to_string(Registration registration)
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.
@ PISM_READONLY
open an existing file for reading only
bool is_increasing(const std::vector< double > &a)
Checks if a vector of doubles is strictly increasing.
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).
std::vector< long > parse_integer_list(const std::string &input)
void GlobalMax(MPI_Comm comm, double *local, double *result, int count)
static double compute_horizontal_spacing(double half_width, unsigned int M, bool cell_centered)
Compute horizontal grid spacing. See compute_horizontal_coordinates() for more.
static unsigned int compute_horizontal_grid_size(double half_width, double dx, bool cell_centered)
Compute horizontal grid size. See compute_horizontal_coordinates() for more.
double vector_min(const std::vector< double > &input)
VariableMetadata mapping_info_from_file(const File &input_file, const std::string &variable_name, units::System::Ptr unit_system)
std::string grid_name(const pism::File &file, const std::string &variable_name, pism::units::System::Ptr sys, bool piecewise_constant)
std::string join(const std::vector< std::string > &strings, const std::string &separator)
Concatenate strings, inserting separator between elements.
bool set_member(const std::string &string, const std::set< std::string > &set)
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.
double vector_max(const std::vector< double > &input)
std::vector< std::string > split(const std::string &input, char separator)
Transform a separator-separated list (a string) into a vector of strings.
Vars variables
A dictionary with pointers to array::Arrays, for passing them from the one component to another (e....
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::map< std::string, std::shared_ptr< InputInterpolation > > regridding_2d
std::shared_ptr< petsc::DM > create_dm(unsigned int da_dof, unsigned 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::shared_ptr< const Context > ctx
std::vector< double > z
z coordinates within the ice
std::shared_ptr< petsc::DM > dm_scalar_global
std::vector< PetscInt > procs_x
array containing lenghts (in the x-direction) of processor sub-domains
VariableMetadata mapping_info
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
Impl(std::shared_ptr< const Context > context)
gsl_interp_accel * bsearch_accel
GSL binary search accelerator used to speed up kBelowHeight().
Internal structures of Grid.