PISM, A Parallel Ice Sheet Model 2.3.0-79cae578d committed by Constantine Khrulev on 2026-03-22
Loading...
Searching...
No Matches
InputInterpolation.cc
Go to the documentation of this file.
1/* Copyright (C) 2024, 2025, 2026 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#include "pism/util/Config.hh"
35#include <string>
36#include <vector>
37
38#if (Pism_USE_YAC == 1)
40#endif
41
42#include <memory>
43
44namespace pism {
45
46double InputInterpolation::regrid(const VariableMetadata &metadata, const pism::File &file,
47 int record_index, const Grid &grid, petsc::Vec &output) const {
48 if (record_index == -1) {
49 auto nrecords =
50 file.nrecords(metadata.get_name(), metadata["standard_name"], metadata.unit_system());
51
52 record_index = (int)nrecords - 1;
53 }
54
55 return regrid_impl(metadata, file, record_index, grid, output);
56}
57
61
63 const std::vector<double> &levels,
64 const File &input_file, const std::string &variable_name,
65 InterpolationType type) {
66
67 auto log = target_grid.ctx()->log();
68 auto unit_system = target_grid.ctx()->unit_system();
69
70 auto name = grid_name(input_file, variable_name, unit_system,
71 type == PIECEWISE_CONSTANT);
72
73 log->message(2, "* Initializing bi- or tri-linear interpolation from '%s' to the internal grid...\n",
74 name.c_str());
75
76 grid::InputGridInfo input_grid(input_file, variable_name, unit_system,
77 target_grid.registration());
78
79 input_grid.report(*log, 4, unit_system);
80
81 bool allow_extrapolation = target_grid.ctx()->config()->get_flag("grid.allow_extrapolation");
82 io::check_input_grid(input_grid, target_grid.info(), levels, allow_extrapolation);
83
84 m_interp_context = std::make_shared<LocalInterpCtx>(input_grid, target_grid.info(), levels, type);
85}
86
87
89 const pism::File &file,
90 int record_index,
91 const Grid &target_grid,
92 petsc::Vec &output) const {
93
94 petsc::VecArray output_array(output);
95
96 double start = get_time(target_grid.com);
97 {
99 context.start[T_AXIS] = record_index;
100
101 io::regrid_spatial_variable(metadata, target_grid, context, file,
102 *target_grid.ctx()->log(),
103 output_array.get());
104 }
105 double end = get_time(target_grid.com);
106
107 return end - start;
108}
109
110
111std::shared_ptr<InputInterpolation>
113 const std::vector<double> &levels, const File &input_file,
114 const std::string &variable_name, InterpolationType type) {
115
116#if (Pism_USE_YAC == 1)
117 {
118 std::string source_projection = mapping_info_from_file(
119 input_file, variable_name, target_grid.ctx()->unit_system())["proj_params"];
120
121 std::string target_projection = target_grid.get_mapping_info()["proj_params"];
122
123 bool use_yac =
124 (levels.size() < 2 and (not source_projection.empty()) and (not target_projection.empty()));
125
126 // Avoid expensive interpolation if source and target grid size, center, and extent are
127 // equal.
128 if (source_projection == target_projection) {
129 grid::InputGridInfo source_grid(input_file, variable_name, target_grid.ctx()->unit_system(),
130 target_grid.registration());
131
132 bool size_matches =
133 (source_grid.x.size() == target_grid.Mx() and source_grid.y.size() == target_grid.My());
134
135 bool center_matches =
136 (source_grid.x0 == target_grid.x0() and source_grid.y0 == target_grid.y0());
137
138 bool extent_matches =
139 (source_grid.Lx == target_grid.Lx() and source_grid.Ly == target_grid.Ly());
140
141 if (size_matches and center_matches and extent_matches) {
142 use_yac = false;
143 }
144
145 double dx_source = source_grid.x[1] - source_grid.x[0];
146 double dy_source = source_grid.y[1] - source_grid.y[0];
147
148 // use YAC to interpolate from grids using decreasing coordinates
149 if (dx_source < 0 or dy_source < 0) {
150 use_yac = true;
151 }
152 }
153
154 if (use_yac) {
155 return std::make_shared<InputInterpolationYAC>(target_grid, input_file, variable_name, type);
156 }
157 }
158#endif
159
160 std::vector<double> fake_levels = { 0.0 };
161 return std::make_shared<InputInterpolation3D>(target_grid, levels.empty() ? fake_levels : levels,
162 input_file, variable_name, type);
163}
164
165
166} // 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:57
double y0() const
Y-coordinate of the center of the domain.
Definition Grid.cc:680
double Ly() const
Half-width of the computational domain.
Definition Grid.cc:665
double Lx() const
Half-width of the computational domain.
Definition Grid.cc:660
const grid::DistributedGridInfo & info() const
Definition Grid.cc:511
unsigned int My() const
Total grid size in the Y direction.
Definition Grid.cc:584
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
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
const MPI_Comm com
Definition Grid.hh:367
Describes the PISM grid and the distribution of data across processors.
Definition Grid.hh:285
double regrid_impl(const VariableMetadata &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 VariableMetadata &metadata, const pism::File &file, int record_index, const Grid &grid, petsc::Vec &output) const =0
double regrid(const VariableMetadata &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)
double Lx
domain half-width in the X direction
Definition GridInfo.hh:46
std::vector< double > y
y coordinates
Definition GridInfo.hh:53
double y0
y-coordinate of the domain center
Definition GridInfo.hh:44
double x0
x-coordinate of the domain center
Definition GridInfo.hh:42
std::vector< double > x
x coordinates
Definition GridInfo.hh:51
double Ly
domain half-width in the Y direction
Definition GridInfo.hh:48
void report(const Logger &log, int threshold, std::shared_ptr< units::System > s) const
Definition Grid.cc:855
double * get()
Definition Vec.cc:55
Wrapper around VecGetArray and VecRestoreArray.
Definition Vec.hh:47
void check_input_grid(const grid::InputGridInfo &input_grid, const grid::DistributedGridInfo &internal_grid, const std::vector< double > &internal_z_levels, bool allow_extrapolation)
Check that x, y, and z coordinates of the input grid are strictly increasing.
void regrid_spatial_variable(const VariableMetadata &variable, const Grid &target_grid, const LocalInterpCtx &interp_context, const File &file, const Logger &log, double *output)
Regrid from a NetCDF file into a distributed array output.
double get_time(MPI_Comm comm)
@ T_AXIS
Definition IO_Flags.hh:34
@ PIECEWISE_CONSTANT
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)