PISM, A Parallel Ice Sheet Model 2.3.0-79cae578d committed by Constantine Khrulev on 2026-03-22
Loading...
Searching...
No Matches
LingleClark.cc
Go to the documentation of this file.
1// Copyright (C) 2010--2025 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#include "pism/earth/LingleClark.hh"
20
21#include "BedDef.hh"
22#include "pism/util/io/File.hh"
23#include "pism/util/Grid.hh"
24#include "pism/util/Config.hh"
25#include "pism/util/error_handling.hh"
26#include "pism/util/pism_utilities.hh"
27#include "pism/util/fftw_utilities.hh"
28#include "pism/earth/LingleClarkSerial.hh"
29#include "pism/util/Context.hh"
30#include <memory>
31
32namespace pism {
33namespace bed {
34
35LingleClark::LingleClark(std::shared_ptr<const Grid> grid)
36 : BedDef(grid, "Lingle-Clark"),
37 m_total_displacement(m_grid, "bed_displacement"),
38 m_relief(m_grid, "bed_relief"),
39 m_elastic_displacement(grid, "elastic_bed_displacement") {
40
41 // A work vector. This storage is used to put thickness change on rank 0 and to get the plate
42 // displacement change back.
44 .long_name(
45 "total (viscous and elastic) displacement in the Lingle-Clark bed deformation model")
46 .units("meters");
47
49
51 .long_name("bed relief relative to the modeled bed displacement")
52 .units("meters");
53
54 bool use_elastic_model = m_config->get_flag("bed_deformation.lc.elastic_model");
55
57 .long_name(
58 "elastic part of the displacement in the Lingle-Clark bed deformation model; see :cite:`BLKfastearth`")
59 .units("meters");
61
62 const int
63 Mx = m_grid->Mx(),
64 My = m_grid->My(),
65 Z = m_config->get_number("bed_deformation.lc.grid_size_factor"),
66 Nx = Z*(Mx - 1) + 1,
67 Ny = Z*(My - 1) + 1;
68
69 const double
70 Lx = Z * (m_grid->x0() - m_grid->x(0)),
71 Ly = Z * (m_grid->y0() - m_grid->y(0));
72
73 m_extended_grid = Grid::Shallow(m_grid->ctx(), Lx, Ly, m_grid->x0(), m_grid->y0(), Nx, Ny,
75
77 std::make_shared<array::Scalar>(m_extended_grid, "viscous_bed_displacement");
78 m_viscous_displacement->metadata(0)
79 .long_name(
80 "bed displacement in the viscous half-space bed deformation model; see BuelerLingleBrown")
81 .units("meters");
82
83 // coordinate variables of the extended grid should have different names
84 m_viscous_displacement->metadata().dimension("x").set_name("x_lc");
85 m_viscous_displacement->metadata().dimension("y").set_name("y_lc");
86
87 // do not point to auxiliary coordinates "lon" and "lat".
88 m_viscous_displacement->metadata()["coordinates"] = "";
89
90 m_viscous_displacement0 = m_viscous_displacement->allocate_proc0_copy();
91
92 ParallelSection rank0(m_grid->com);
93 try {
94 if (m_grid->rank() == 0) {
95 m_serial_model.reset(new LingleClarkSerial(m_log, *m_config, use_elastic_model,
96 Mx, My,
97 m_grid->dx(), m_grid->dy(),
98 Nx, Ny));
99 }
100 } catch (...) {
101 rank0.failed();
102 }
103 rank0.check();
104}
105
107 // empty, but implemented here instead of using "= default" in the header to be able to
108 // use the forward declaration of LingleClarkSerial in LingleClark.hh
109}
110
111/*!
112 * Initialize the model by computing the viscous bed displacement using uplift and the elastic
113 * response using ice thickness.
114 *
115 * Then compute the bed relief as the difference between bed elevation and total bed displacement.
116 *
117 * This method has to initialize m_viscous_displacement, m_elastic_displacement,
118 * m_total_displacement, and m_relief.
119 */
121 const array::Scalar &bed_uplift,
122 const array::Scalar &ice_thickness,
123 const array::Scalar &sea_level_elevation) {
124
125 auto load_proc0 = m_load.allocate_proc0_copy();
126
128
129 // initialize the plate displacement
130 {
131 auto &uplift_proc0 = *m_work0;
132 bed_uplift.put_on_proc0(uplift_proc0);
133
134 m_load.set(0.0);
135 accumulate_load(bed_elevation, ice_thickness, sea_level_elevation, 1.0, m_load);
136 m_load.put_on_proc0(*load_proc0);
137
138 ParallelSection rank0(m_grid->com);
139 try {
140 if (m_grid->rank() == 0) {
141 PetscErrorCode ierr = 0;
142
143 m_serial_model->bootstrap(*load_proc0, uplift_proc0);
144
145 ierr = VecCopy(m_serial_model->total_displacement(), total_displacement);
146 PISM_CHK(ierr, "VecCopy");
147
148 ierr = VecCopy(m_serial_model->viscous_displacement(), *m_viscous_displacement0);
149 PISM_CHK(ierr, "VecCopy");
150
151 ierr = VecCopy(m_serial_model->elastic_displacement(), *m_elastic_displacement0);
152 PISM_CHK(ierr, "VecCopy");
153 }
154 } catch (...) {
155 rank0.failed();
156 }
157 rank0.check();
158 }
159
161
163
165
166 // compute bed relief
168}
169
170/*!
171 * Return the load response matrix for the elastic response.
172 *
173 * This method is used for testing only.
174 */
175std::shared_ptr<array::Scalar> LingleClark::elastic_load_response_matrix() const {
176 std::shared_ptr<array::Scalar> result(new array::Scalar(m_extended_grid, "lrm"));
177
178 int
179 Nx = m_extended_grid->Mx(),
180 Ny = m_extended_grid->My();
181
182 auto lrm0 = result->allocate_proc0_copy();
183
184 {
185 ParallelSection rank0(m_grid->com);
186 try {
187 if (m_grid->rank() == 0) {
188 std::vector<std::complex<double> > array(Nx * Ny);
189
190 m_serial_model->compute_load_response_matrix((fftw_complex*)array.data());
191
192 get_real_part((fftw_complex*)array.data(), 1.0, Nx, Ny, Nx, Ny, 0, 0, *lrm0);
193 }
194 } catch (...) {
195 rank0.failed();
196 }
197 rank0.check();
198 }
199
200 result->get_from_proc0(*lrm0);
201
202 return result;
203}
204
205/*! Initialize the Lingle-Clark bed deformation model.
206 *
207 * Inputs:
208 *
209 * - bed topography,
210 * - ice thickness,
211 * - plate displacement (either read from a file or bootstrapped using uplift) and
212 * possibly re-gridded.
213 */
214void LingleClark::init_impl(const InputOptions &opts, const array::Scalar &ice_thickness,
215 const array::Scalar &sea_level_elevation) {
216 if (opts.type == INIT_RESTART) {
217 // Set viscous displacement by reading from the input file.
218 m_viscous_displacement->read(opts.filename, opts.record);
219 // Set elastic displacement by reading from the input file.
221 } else if (opts.type == INIT_BOOTSTRAP) {
222 this->bootstrap(m_topg, m_uplift, ice_thickness, sea_level_elevation);
223 } else {
224 // do nothing
225 }
226
227 // Try re-gridding plate_displacement.
228 regrid("Lingle-Clark bed deformation model",
230 regrid("Lingle-Clark bed deformation model",
232
233 // Now that viscous displacement and elastic displacement are finally initialized,
234 // put them on rank 0 and initialize the serial model itself.
235 {
238
239 ParallelSection rank0(m_grid->com);
240 try {
241 if (m_grid->rank() == 0) { // only processor zero does the work
242 PetscErrorCode ierr = 0;
243
245
246 ierr = VecCopy(m_serial_model->total_displacement(), *m_work0);
247 PISM_CHK(ierr, "VecCopy");
248 }
249 } catch (...) {
250 rank0.failed();
251 }
252 rank0.check();
253 }
254
256
257 // compute bed relief
259}
260
261/*!
262 * Get total bed displacement on the PISM grid.
263 */
267
271
275
277 return m_relief;
278}
279
280void LingleClark::step(const array::Scalar &load_thickness,
281 double dt) {
282
283 load_thickness.put_on_proc0(*m_work0);
284
285 ParallelSection rank0(m_grid->com);
286 try {
287 if (m_grid->rank() == 0) { // only processor zero does the step
288 PetscErrorCode ierr = 0;
289
290 m_serial_model->step(dt, *m_work0);
291
292 ierr = VecCopy(m_serial_model->total_displacement(), *m_work0);
293 PISM_CHK(ierr, "VecCopy");
294
295 ierr = VecCopy(m_serial_model->viscous_displacement(), *m_viscous_displacement0);
296 PISM_CHK(ierr, "VecCopy");
297
298 ierr = VecCopy(m_serial_model->elastic_displacement(), *m_elastic_displacement0);
299 PISM_CHK(ierr, "VecCopy");
300 }
301 } catch (...) {
302 rank0.failed();
303 }
304 rank0.check();
305
307
309
311
312 // Update bed elevation using bed displacement and relief.
314}
315
316//! Update the Lingle-Clark bed deformation model.
317void LingleClark::update_impl(const array::Scalar &load, double /*t*/, double dt) {
318 step(load, dt);
319 // mark m_topg as "modified"
321}
322
323std::set<VariableMetadata> LingleClark::state_impl() const {
325
326 return pism::combine(variables, BedDef::state_impl());
327}
328
329void LingleClark::write_state_impl(const OutputFile &output) const {
331
332 m_viscous_displacement->write(output);
334}
335
337 DiagnosticList result = {
338 {"viscous_bed_displacement", Diagnostic::wrap(*m_viscous_displacement)},
339 {"elastic_bed_displacement", Diagnostic::wrap(m_elastic_displacement)},
340 };
342}
343
344} // end of namespace bed
345} // end of namespace pism
std::shared_ptr< const Config > m_config
configuration database used by this component
Definition Component.hh:160
const std::shared_ptr< const Grid > m_grid
grid used by this component
Definition Component.hh:158
void regrid(const std::string &module_name, array::Array &variable, RegriddingFlag flag=NO_REGRID_WITHOUT_REGRID_VARS)
Definition Component.cc:152
std::shared_ptr< const Logger > m_log
logger (for easy access)
Definition Component.hh:164
static Ptr wrap(const T &input)
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
void failed()
Indicates a failure of a parallel section.
VariableMetadata & long_name(const std::string &input)
VariableMetadata & units(const std::string &input)
void add(double alpha, const Array2D< T > &x)
Definition Array2D.hh:93
void read(const std::string &filename, unsigned int time)
Definition Array.cc:753
void write(const OutputFile &file) const
Definition Array.cc:859
void get_from_proc0(petsc::Vec &onp0)
Gets a local Array2 from processor 0.
Definition Array.cc:1079
void set(double c)
Result: v[j] <- c for all j.
Definition Array.cc:659
void inc_state_counter()
Increment the object state counter.
Definition Array.cc:153
std::shared_ptr< petsc::Vec > allocate_proc0_copy() const
Definition Array.cc:947
void put_on_proc0(petsc::Vec &onp0) const
Puts a local array::Scalar on processor 0.
Definition Array.cc:1036
VariableMetadata & metadata(unsigned int N=0)
Returns a reference to the VariableMetadata object containing metadata for the compoment N.
Definition Array.cc:467
virtual DiagnosticList spatial_diagnostics_impl() const
Definition BedDef.cc:107
virtual void write_state_impl(const OutputFile &output) const
The default (empty implementation).
Definition BedDef.cc:96
void bootstrap(const array::Scalar &bed_elevation, const array::Scalar &bed_uplift, const array::Scalar &ice_thickness, const array::Scalar &sea_level_elevation)
Initialize using provided bed elevation and uplift.
Definition BedDef.cc:188
array::Scalar2 m_topg
current bed elevation
Definition BedDef.hh:78
array::Scalar m_uplift
bed uplift rate
Definition BedDef.hh:87
const array::Scalar & bed_elevation() const
Definition BedDef.cc:74
array::Scalar m_load
Definition BedDef.hh:83
virtual std::set< VariableMetadata > state_impl() const
Definition BedDef.cc:82
PISM bed deformation model (base class).
Definition BedDef.hh:37
Class implementing the bed deformation model described in [BLKfastearth].
std::shared_ptr< petsc::Vec > m_elastic_displacement0
rank 0 storage for the elastic displacement
void bootstrap_impl(const array::Scalar &bed_elevation, const array::Scalar &bed_uplift, const array::Scalar &ice_thickness, const array::Scalar &sea_level_elevation)
void init_impl(const InputOptions &opts, const array::Scalar &ice_thickness, const array::Scalar &sea_level_elevation)
std::shared_ptr< petsc::Vec > m_work0
array::Scalar m_elastic_displacement
Elastic bed displacement (part of the model state)
const array::Scalar & elastic_displacement() const
std::shared_ptr< Grid > m_extended_grid
extended grid for the viscous plate displacement
virtual std::set< VariableMetadata > state_impl() const
void update_impl(const array::Scalar &load, double t, double dt)
Update the Lingle-Clark bed deformation model.
std::shared_ptr< array::Scalar > m_viscous_displacement
Viscous displacement on the extended grid (part of the model state).
array::Scalar m_relief
Bed relief relative to the bed displacement.
std::shared_ptr< petsc::Vec > m_viscous_displacement0
rank 0 storage using the extended grid
const array::Scalar & relief() const
void step(const array::Scalar &load_thickness, double dt)
LingleClark(std::shared_ptr< const Grid > g)
DiagnosticList spatial_diagnostics_impl() const
std::unique_ptr< LingleClarkSerial > m_serial_model
Serial viscoelastic bed deformation model.
const array::Scalar & total_displacement() const
array::Scalar m_total_displacement
Total (viscous and elastic) bed displacement.
const array::Scalar & viscous_displacement() const
std::shared_ptr< array::Scalar > elastic_load_response_matrix() const
virtual void write_state_impl(const OutputFile &output) const
The default (empty implementation).
#define PISM_CHK(errcode, name)
std::set< VariableMetadata > metadata(std::initializer_list< const Array * > vecs)
Definition Array.cc:1244
void accumulate_load(const array::Scalar &bed_elevation, const array::Scalar &ice_thickness, const array::Scalar &sea_level_elevation, double C, array::Scalar &result)
Definition BedDef.cc:310
@ INIT_BOOTSTRAP
Definition Component.hh:56
@ INIT_RESTART
Definition Component.hh:56
std::map< std::string, Diagnostic::Ptr > DiagnosticList
T combine(const T &a, const T &b)
void get_real_part(fftw_complex *input, double normalization, int Mx, int My, int Nx, int Ny, int i0, int j0, petsc::Vec &output)
Get the real part of input and put it in output.
InitializationType type
initialization type
Definition Component.hh:61
std::string filename
name of the input file (if applicable)
Definition Component.hh:63
unsigned int record
index of the record to re-start from
Definition Component.hh:65