PISM, A Parallel Ice Sheet Model 2.2.1-cd005eec8 committed by Constantine Khrulev on 2025-03-07
Loading...
Searching...
No Matches
timestepping.cc
Go to the documentation of this file.
1/* Copyright (C) 2016, 2017, 2020, 2022, 2023, 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/stressbalance/timestepping.hh"
21#include "pism/util/Grid.hh"
22#include "pism/util/array/Array3D.hh"
23#include "pism/util/array/Scalar.hh"
24#include "pism/util/array/CellType.hh"
25#include "pism/util/array/Vector.hh"
26#include "pism/util/pism_utilities.hh"
27#include "pism/util/Context.hh"
28#include <vector>
29
30namespace pism {
31
33 u_max = 0.0;
34 v_max = 0.0;
35 w_max = 0.0;
36}
37
38//! Compute the maximum velocities for time-stepping and reporting to user.
39/*!
40Computes the maximum magnitude of the components \f$u,v,w\f$ of the 3D velocity.
41
42Under BOMBPROOF there is no CFL condition for the vertical advection.
43The maximum vertical velocity is computed but it does not affect the output.
44 */
46 const array::CellType &cell_type,
47 const array::Array3D &u3,
48 const array::Array3D &v3,
49 const array::Array3D &w3) {
50
51 auto grid = ice_thickness.grid();
52 Config::ConstPtr config = grid->ctx()->config();
53
54 double dt_max = config->get_number("time_stepping.maximum_time_step", "seconds");
55
56 array::AccessScope list{&ice_thickness, &u3, &v3, &w3, &cell_type};
57
58 // update global max of abs of velocities for CFL; only velocities under surface
59 const double
60 one_over_dx = 1.0 / grid->dx(),
61 one_over_dy = 1.0 / grid->dy();
62
63 double u_max = 0.0, v_max = 0.0, w_max = 0.0;
64 ParallelSection loop(grid->com);
65 try {
66 for (auto p = grid->points(); p; p.next()) {
67 const int i = p.i(), j = p.j();
68
69 if (cell_type.icy(i, j)) {
70 const int ks = grid->kBelowHeight(ice_thickness(i, j));
71 const double
72 *u = u3.get_column(i, j),
73 *v = v3.get_column(i, j),
74 *w = w3.get_column(i, j);
75
76 for (int k = 0; k <= ks; ++k) {
77 const double
78 u_abs = fabs(u[k]),
79 v_abs = fabs(v[k]);
80 u_max = std::max(u_max, u_abs);
81 v_max = std::max(v_max, v_abs);
82 const double denom = fabs(u_abs * one_over_dx) + fabs(v_abs * one_over_dy);
83 if (denom > 0.0) {
84 dt_max = std::min(dt_max, 1.0 / denom);
85 }
86 }
87
88 for (int k = 0; k <= ks; ++k) {
89 w_max = std::max(w_max, fabs(w[k]));
90 }
91 }
92 }
93 } catch (...) {
94 loop.failed();
95 }
96 loop.check();
97
98 CFLData result;
99
100 std::vector<double> data = {u_max, v_max, w_max}, tmp(3, 0.0);
101 GlobalMax(grid->com, data.data(), tmp.data(), 3);
102 result.u_max = tmp[0];
103 result.v_max = tmp[1];
104 result.w_max = tmp[2];
105 result.dt_max = MaxTimestep(GlobalMin(grid->com, dt_max));
106
107 return result;
108}
109
110//! Compute the CFL constant associated to first-order upwinding for the sliding contribution to mass continuity.
111/*!
112 This procedure computes the maximum horizontal speed in the icy
113 areas. In particular it computes CFL constant for the upwinding, in
114 GeometryEvolution::step(), which applies to the basal component of mass
115 flux.
116
117 That is, because the map-plane mass continuity is advective in the
118 sliding case we have a CFL condition.
119 */
121 const array::CellType &cell_type,
122 const array::Vector &velocity) {
123
124 auto grid = ice_thickness.grid();
125 Config::ConstPtr config = grid->ctx()->config();
126
127 double dt_max = config->get_number("time_stepping.maximum_time_step", "seconds");
128
129 const double
130 dx = grid->dx(),
131 dy = grid->dy();
132
133 array::AccessScope list{&velocity, &cell_type};
134
135 double u_max = 0.0, v_max = 0.0;
136 for (auto p = grid->points(); p; p.next()) {
137 const int i = p.i(), j = p.j();
138
139 if (cell_type.icy(i, j)) {
140 const double
141 u_abs = fabs(velocity(i, j).u),
142 v_abs = fabs(velocity(i, j).v);
143
144 u_max = std::max(u_max, u_abs);
145 v_max = std::max(v_max, v_abs);
146
147 const double denom = u_abs / dx + v_abs / dy;
148 if (denom > 0.0) {
149 dt_max = std::min(dt_max, 1.0 / denom);
150 }
151 }
152 }
153
154 CFLData result;
155
156 std::vector<double> data = {u_max, v_max}, tmp(2, 0.0);
157 GlobalMax(grid->com, data.data(), tmp.data(), 2);
158 result.u_max = tmp[0];
159 result.v_max = tmp[1];
160 result.w_max = 0.0;
161 result.dt_max = MaxTimestep(GlobalMin(grid->com, dt_max));
162
163 return result;
164}
165
166MaxTimestep max_timestep_diffusivity(double D_max, double dx, double dy,
167 double adaptive_timestepping_ratio) {
168 if (D_max > 0.0) {
169 double grid_factor = 1.0 / (dx * dx) + 1.0 / (dy * dy);
170 return MaxTimestep(adaptive_timestepping_ratio * 2.0 / (D_max * grid_factor), "diffusivity");
171 }
172
173 return {};
174}
175
176} // end of namespace pism
std::shared_ptr< const Config > ConstPtr
Combines the max. time step with the flag indicating if a restriction is active. Makes is possible to...
void failed()
Indicates a failure of a parallel section.
Makes sure that we call begin_access() and end_access() for all accessed array::Arrays.
Definition Array.hh:64
double * get_column(int i, int j)
Definition Array3D.cc:121
A virtual class collecting methods common to ice and bedrock 3D fields.
Definition Array3D.hh:33
std::shared_ptr< const Grid > grid() const
Definition Array.cc:131
bool icy(int i, int j) const
Definition CellType.hh:42
"Cell type" mask. Adds convenience methods to array::Scalar.
Definition CellType.hh:30
CFLData max_timestep_cfl_2d(const array::Scalar &ice_thickness, const array::CellType &cell_type, const array::Vector &velocity)
Compute the CFL constant associated to first-order upwinding for the sliding contribution to mass con...
void GlobalMax(MPI_Comm comm, double *local, double *result, int count)
static const double k
Definition exactTestP.cc:42
CFLData max_timestep_cfl_3d(const array::Scalar &ice_thickness, const array::CellType &cell_type, const array::Array3D &u3, const array::Array3D &v3, const array::Array3D &w3)
Compute the maximum velocities for time-stepping and reporting to user.
MaxTimestep max_timestep_diffusivity(double D_max, double dx, double dy, double adaptive_timestepping_ratio)
void GlobalMin(MPI_Comm comm, double *local, double *result, int count)
MaxTimestep dt_max