PISM, A Parallel Ice Sheet Model  stable v2.1-1-g6902d5502 committed by Ed Bueler on 2023-12-20 08:38:27 -0800
timestepping.cc
Go to the documentation of this file.
1 /* Copyright (C) 2016, 2017, 2020, 2022, 2023 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 
29 namespace pism {
30 
32  u_max = 0.0;
33  v_max = 0.0;
34  w_max = 0.0;
35 }
36 
37 //! Compute the maximum velocities for time-stepping and reporting to user.
38 /*!
39 Computes the maximum magnitude of the components \f$u,v,w\f$ of the 3D velocity.
40 
41 Under BOMBPROOF there is no CFL condition for the vertical advection.
42 The maximum vertical velocity is computed but it does not affect the output.
43  */
45  const array::CellType &cell_type,
46  const array::Array3D &u3,
47  const array::Array3D &v3,
48  const array::Array3D &w3) {
49 
50  auto grid = ice_thickness.grid();
51  Config::ConstPtr config = grid->ctx()->config();
52 
53  double dt_max = config->get_number("time_stepping.maximum_time_step", "seconds");
54 
55  array::AccessScope list{&ice_thickness, &u3, &v3, &w3, &cell_type};
56 
57  // update global max of abs of velocities for CFL; only velocities under surface
58  const double
59  one_over_dx = 1.0 / grid->dx(),
60  one_over_dy = 1.0 / grid->dy();
61 
62  double u_max = 0.0, v_max = 0.0, w_max = 0.0;
63  ParallelSection loop(grid->com);
64  try {
65  for (auto p = grid->points(); p; p.next()) {
66  const int i = p.i(), j = p.j();
67 
68  if (cell_type.icy(i, j)) {
69  const int ks = grid->kBelowHeight(ice_thickness(i, j));
70  const double
71  *u = u3.get_column(i, j),
72  *v = v3.get_column(i, j),
73  *w = w3.get_column(i, j);
74 
75  for (int k = 0; k <= ks; ++k) {
76  const double
77  u_abs = fabs(u[k]),
78  v_abs = fabs(v[k]);
79  u_max = std::max(u_max, u_abs);
80  v_max = std::max(v_max, v_abs);
81  const double denom = fabs(u_abs * one_over_dx) + fabs(v_abs * one_over_dy);
82  if (denom > 0.0) {
83  dt_max = std::min(dt_max, 1.0 / denom);
84  }
85  }
86 
87  for (int k = 0; k <= ks; ++k) {
88  w_max = std::max(w_max, fabs(w[k]));
89  }
90  }
91  }
92  } catch (...) {
93  loop.failed();
94  }
95  loop.check();
96 
97  CFLData result;
98 
99  result.u_max = GlobalMax(grid->com, u_max);
100  result.v_max = GlobalMax(grid->com, v_max);
101  result.w_max = GlobalMax(grid->com, w_max);
102  result.dt_max = MaxTimestep(GlobalMin(grid->com, dt_max));
103 
104  return result;
105 }
106 
107 //! Compute the CFL constant associated to first-order upwinding for the sliding contribution to mass continuity.
108 /*!
109  This procedure computes the maximum horizontal speed in the icy
110  areas. In particular it computes CFL constant for the upwinding, in
111  GeometryEvolution::step(), which applies to the basal component of mass
112  flux.
113 
114  That is, because the map-plane mass continuity is advective in the
115  sliding case we have a CFL condition.
116  */
118  const array::CellType &cell_type,
119  const array::Vector &velocity) {
120 
121  auto grid = ice_thickness.grid();
122  Config::ConstPtr config = grid->ctx()->config();
123 
124  double dt_max = config->get_number("time_stepping.maximum_time_step", "seconds");
125 
126  const double
127  dx = grid->dx(),
128  dy = grid->dy();
129 
130  array::AccessScope list{&velocity, &cell_type};
131 
132  double u_max = 0.0, v_max = 0.0;
133  for (auto p = grid->points(); p; p.next()) {
134  const int i = p.i(), j = p.j();
135 
136  if (cell_type.icy(i, j)) {
137  const double
138  u_abs = fabs(velocity(i, j).u),
139  v_abs = fabs(velocity(i, j).v);
140 
141  u_max = std::max(u_max, u_abs);
142  v_max = std::max(v_max, v_abs);
143 
144  const double denom = u_abs / dx + v_abs / dy;
145  if (denom > 0.0) {
146  dt_max = std::min(dt_max, 1.0 / denom);
147  }
148  }
149  }
150 
151  CFLData result;
152 
153  result.u_max = GlobalMax(grid->com, u_max);
154  result.v_max = GlobalMax(grid->com, v_max);
155  result.w_max = 0.0;
156  result.dt_max = MaxTimestep(GlobalMin(grid->com, dt_max));
157 
158  return result;
159 }
160 
161 MaxTimestep max_timestep_diffusivity(double D_max, double dx, double dy,
162  double adaptive_timestepping_ratio) {
163  if (D_max > 0.0) {
164  double grid_factor = 1.0 / (dx * dx) + 1.0 / (dy * dy);
165  return MaxTimestep(adaptive_timestepping_ratio * 2.0 / (D_max * grid_factor), "diffusivity");
166  }
167 
168  return {};
169 }
170 
171 } // 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...
Definition: MaxTimestep.hh:31
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:65
double * get_column(int i, int j)
Definition: Array3D.cc:120
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:132
bool icy(int i, int j) const
Definition: CellType.hh:42
"Cell type" mask. Adds convenience methods to array::Scalar.
Definition: CellType.hh:30
double max(const array::Scalar &input)
Finds maximum over all the values in an array::Scalar object. Ignores ghosts.
Definition: Scalar.cc:165
double min(const array::Scalar &input)
Finds minimum over all the values in an array::Scalar object. Ignores ghosts.
Definition: Scalar.cc:193
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.
Definition: timestepping.cc:44
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
Definition: timestepping.hh:39