Loading [MathJax]/extensions/tex2jax.js
PISM, A Parallel Ice Sheet Model 2.2.1-cd005eec8 committed by Constantine Khrulev on 2025-03-07
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
InputInterpolation.cc
Go to the documentation of this file.
1/* Copyright (C) 2024 PISM Authors
2 *
3 * This file is part of PISM.
4 *
5 * PISM is free software; you can redistribute it and/or modify it under the
6 * terms of the GNU General Public License as published by the Free Software
7 * Foundation; either version 3 of the License, or (at your option) any later
8 * version.
9 *
10 * PISM is distributed in the hope that it will be useful, but WITHOUT ANY
11 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 * details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with PISM; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include "pism/util/InputInterpolation.hh"
21#include "pism/util/Interpolation1D.hh"
22#include "pism/util/io/LocalInterpCtx.hh"
23#include "pism/pism_config.hh"
24#include "pism/util/Context.hh"
25#include "pism/util/Grid.hh"
26#include "pism/util/VariableMetadata.hh"
27#include "pism/util/io/File.hh"
28#include "pism/util/io/IO_Flags.hh"
29#include "pism/util/io/io_helpers.hh"
30#include "pism/util/petscwrappers/Vec.hh"
31#include "pism/util/pism_utilities.hh"
32#include "pism/util/projection.hh"
33#include "pism/util/Logger.hh"
34
35#if (Pism_USE_YAC_INTERPOLATION == 1)
37#endif
38
39#include <memory>
40
41namespace pism {
42
44 int record_index, const Grid &grid, petsc::Vec &output) const {
45 if (record_index == -1) {
46 auto nrecords =
47 file.nrecords(metadata.get_name(), metadata["standard_name"], metadata.unit_system());
48
49 record_index = (int)nrecords - 1;
50 }
51
52 return regrid_impl(metadata, file, record_index, grid, output);
53}
54
58
60 const std::vector<double> &levels,
61 const File &input_file, const std::string &variable_name,
62 InterpolationType type) {
63
64 auto log = target_grid.ctx()->log();
65 auto unit_system = target_grid.ctx()->unit_system();
66
67 auto name = grid_name(input_file, variable_name, unit_system,
68 type == PIECEWISE_CONSTANT);
69
70 log->message(2, "* Initializing bi- or tri-linear interpolation from '%s' to the internal grid...\n",
71 name.c_str());
72
73 grid::InputGridInfo input_grid(input_file, variable_name, unit_system,
74 target_grid.registration());
75
76 input_grid.report(*log, 4, unit_system);
77
78 io::check_input_grid(input_grid, target_grid, levels);
79
80 m_interp_context = std::make_shared<LocalInterpCtx>(input_grid, target_grid, levels, type);
81}
82
83
85 const pism::File &file,
86 int record_index,
87 const Grid &target_grid,
88 petsc::Vec &output) const {
89
90 petsc::VecArray output_array(output);
91
92 double start = get_time(target_grid.com);
93 {
95 context.start[T_AXIS] = record_index;
96
97 io::regrid_spatial_variable(metadata, target_grid, context, file,
98 output_array.get());
99 }
100 double end = get_time(target_grid.com);
101
102 return end - start;
103}
104
105
106std::shared_ptr<InputInterpolation>
108 const std::vector<double> &levels, const File &input_file,
109 const std::string &variable_name, InterpolationType type) {
110
111#if (Pism_USE_YAC_INTERPOLATION == 1)
112 {
113 auto source_projection =
114 MappingInfo::FromFile(input_file, variable_name, target_grid.ctx()->unit_system())
116
117 auto target_projection = target_grid.get_mapping_info().proj_string;
118
119 bool use_yac =
120 (levels.size() < 2 and (not source_projection.empty()) and (not target_projection.empty()));
121
122 // Avoid expensive interpolation if source and target grid size, center, and extent are
123 // equal.
124 if (source_projection == target_projection) {
125 grid::InputGridInfo source_grid(input_file, variable_name, target_grid.ctx()->unit_system(),
126 target_grid.registration());
127
128 bool size_matches =
129 (source_grid.x.size() == target_grid.Mx() and source_grid.y.size() == target_grid.My());
130
131 bool center_matches =
132 (source_grid.x0 == target_grid.x0() and source_grid.y0 == target_grid.y0());
133
134 bool extent_matches =
135 (source_grid.Lx == target_grid.Lx() and source_grid.Ly == target_grid.Ly());
136
137 if (size_matches and center_matches and extent_matches) {
138 use_yac = false;
139 }
140
141 double dx_source = source_grid.x[1] - source_grid.x[0];
142 double dy_source = source_grid.y[1] - source_grid.y[0];
143
144 // use YAC to interpolate from grids using decreasing coordinates
145 if (dx_source < 0 or dy_source < 0) {
146 use_yac = true;
147 }
148 }
149
150 if (use_yac) {
151 return std::make_shared<InputInterpolationYAC>(target_grid, input_file, variable_name, type);
152 }
153 }
154#endif
155
156 return std::make_shared<InputInterpolation3D>(target_grid, levels, input_file, variable_name,
157 type);
158}
159
160
161} // namespace pism
unsigned int nrecords() const
Get the number of records. Uses the length of an unlimited dimension.
Definition File.cc:280
High-level PISM I/O class.
Definition File.hh:55
double y0() const
Y-coordinate of the center of the domain.
Definition Grid.cc:707
double Ly() const
Half-width of the computational domain.
Definition Grid.cc:692
double Lx() const
Half-width of the computational domain.
Definition Grid.cc:687
unsigned int My() const
Total grid size in the Y direction.
Definition Grid.cc:613
double x0() const
X-coordinate of the center of the domain.
Definition Grid.cc:702
grid::Registration registration() const
Definition Grid.cc:535
std::shared_ptr< const Context > ctx() const
Return execution context this grid corresponds to.
Definition Grid.cc:540
unsigned int Mx() const
Total grid size in the X direction.
Definition Grid.cc:608
const MappingInfo & get_mapping_info() const
Definition Grid.cc:1577
const MPI_Comm com
Definition Grid.hh:370
Describes the PISM grid and the distribution of data across processors.
Definition Grid.hh:290
double regrid_impl(const SpatialVariableMetadata &metadata, const pism::File &file, int record_index, const Grid &grid, petsc::Vec &output) const
std::shared_ptr< LocalInterpCtx > m_interp_context
InputInterpolation3D(const Grid &target_grid, const std::vector< double > &levels, const File &input_file, const std::string &variable_name, InterpolationType type)
virtual double regrid_impl(const SpatialVariableMetadata &metadata, const pism::File &file, int record_index, const Grid &grid, petsc::Vec &output) const =0
double regrid(const SpatialVariableMetadata &metadata, const pism::File &file, int record_index, const Grid &grid, petsc::Vec &output) const
static std::shared_ptr< InputInterpolation > create(const Grid &target_grid, const std::vector< double > &levels, const File &input_file, const std::string &variable_name, InterpolationType type)
std::string proj_string
a projection definition string in a format recognized by PROJ 6.x+
Definition projection.hh:72
static MappingInfo FromFile(const File &input_file, const std::string &variable_name, units::System::Ptr unit_system)
Get projection info from a file.
Spatial NetCDF variable (corresponding to a 2D or 3D scalar field).
units::System::Ptr unit_system() const
std::string get_name() const
std::vector< double > y
y coordinates
Definition Grid.hh:93
double Lx
domain half-width
Definition Grid.hh:82
double Ly
domain half-height
Definition Grid.hh:84
double y0
y-coordinate of the domain center
Definition Grid.hh:80
double x0
x-coordinate of the domain center
Definition Grid.hh:78
std::vector< double > x
x coordinates
Definition Grid.hh:91
void report(const Logger &log, int threshold, std::shared_ptr< units::System > s) const
Definition Grid.cc:885
Contains parameters of an input file grid.
Definition Grid.hh:68
double * get()
Definition Vec.cc:54
Wrapper around VecGetArray and VecRestoreArray.
Definition Vec.hh:44
void check_input_grid(const grid::InputGridInfo &input_grid, const Grid &internal_grid, const std::vector< double > &internal_z_levels)
Check that x, y, and z coordinates of the input grid are strictly increasing.
void regrid_spatial_variable(const SpatialVariableMetadata &variable, const Grid &target_grid, const LocalInterpCtx &interp_context, const File &file, double *output)
Regrid from a NetCDF file into a distributed array output.
double get_time(MPI_Comm comm)
@ T_AXIS
Definition IO_Flags.hh:33
@ PIECEWISE_CONSTANT
std::string grid_name(const pism::File &file, const std::string &variable_name, pism::units::System::Ptr sys, bool piecewise_constant)