PISM, A Parallel Ice Sheet Model  stable v2.1-1-g6902d5502 committed by Ed Bueler on 2023-12-20 08:38:27 -0800
ssa_testi.cc
Go to the documentation of this file.
1 // Copyright (C) 2010--2018, 2021, 2022, 2023 Ed Bueler, Constantine Khroulev, and David Maxwell
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 static char help[] =
20  "\nSSA_TESTI\n"
21  " Testing program for the finite element implementation of the SSA.\n"
22  " Does a time-independent calculation. Does not run IceModel or a derived\n"
23  " class thereof. Uses verification test I. Also may be used in a PISM\n"
24  " software (regression) test.\n\n";
25 
26 #include "pism/basalstrength/basal_resistance.hh" // IceBasalResistancePlasticLaw
27 #include "pism/stressbalance/ssa/SSAFD.hh"
28 #include "pism/stressbalance/ssa/SSAFEM.hh"
29 #include "pism/stressbalance/ssa/SSATestCase.hh"
30 #include "pism/util/Context.hh"
31 #include "pism/util/VariableMetadata.hh"
32 #include "pism/util/error_handling.hh"
33 #include "pism/util/io/File.hh"
34 #include "pism/util/petscwrappers/PetscInitializer.hh"
35 #include "pism/util/pism_utilities.hh"
36 #include "pism/util/pism_options.hh"
37 #include "pism/verification/tests/exactTestsIJ.h"
38 
39 namespace pism {
40 namespace stressbalance {
41 
42 const double m_schoof = 10; // (pure number)
43 const double L_schoof = 40e3; // meters
44 const double aspect_schoof = 0.05; // (pure)
45 const double H0_schoof = aspect_schoof * L_schoof;
46  // = 2000 m THICKNESS
47 const double B_schoof = 3.7e8; // Pa s^{1/3}; hardness
48  // given on p. 239 of Schoof; why so big?
49 
50 class SSATestCaseI: public SSATestCase {
51 public:
52  SSATestCaseI(std::shared_ptr<Context> ctx, int Mx, int My, SSAFactory ssafactory)
53  : SSATestCase(ctx,
54  Mx, My,
55  std::max(60.0e3, ((Mx - 1) / 2) * (2.0 * (3.0 * L_schoof) / (My - 1))),
56  3.0 * L_schoof,
57  grid::CELL_CORNER,
58  grid::NOT_PERIODIC) {
60 
61  m_config->set_flag("basal_resistance.pseudo_plastic.enabled", false);
62 
63  m_config->set_string("stress_balance.ssa.flow_law", "isothermal_glen");
64  m_config->set_number("flow_law.isothermal_Glen.ice_softness", pow(B_schoof, -m_config->get_number("stress_balance.ssa.Glen_exponent")));
65 
66  m_ssa = ssafactory(m_grid);
67  }
68 
69 protected:
70  virtual void initializeSSACoefficients();
71 
72  virtual void exactSolution(int i, int j,
73  double x, double y, double *u, double *v);
74 
75 };
76 
78 
79  m_bc_mask.set(0);
81 
82  double enth0 = m_enthalpyconverter->enthalpy(273.15, 0.01, 0.0); // 0.01 water fraction
83  m_ice_enthalpy.set(enth0);
84 
85  // ssa->strength_extension->set_min_thickness(2*H0_schoof);
86 
87  // The finite difference code uses the following flag to treat the non-periodic grid correctly.
88  m_config->set_flag("stress_balance.ssa.compute_surface_gradient_inward", true);
89  m_config->set_number("stress_balance.ssa.epsilon", 0.0); // don't use this lower bound
90 
92 
93  for (auto p = m_grid->points(); p; p.next()) {
94  const int i = p.i(), j = p.j();
95 
96  // Evaluate the exact solution and yield stress. Exact u, v will only be used at the
97  // grid edge.
98  auto I = exactI(m_schoof, m_grid->x(i), m_grid->y(j));
99 
100  m_geometry.bed_elevation(i, j) = I.bed;
101 
102  m_tauc(i,j) = I.tauc;
103 
104  if (grid::domain_edge(*m_grid, i, j)) {
105  m_bc_mask(i, j) = 1;
106  m_bc_values(i, j) = { I.u, I.v };
107  }
108  }
109 
111 
115 }
116 
117 
118 void SSATestCaseI::exactSolution(int /*i*/, int /*j*/,
119  double x, double y,
120  double *u, double *v) {
121  auto I = exactI(m_schoof, x, y);
122  *u = I.u;
123  *v = I.v;
124 }
125 
126 } // end of namespace stressbalance
127 } // end of namespace pism
128 
129 int main(int argc, char *argv[]) {
130 
131  using namespace pism;
132  using namespace pism::stressbalance;
133 
134  MPI_Comm com = MPI_COMM_WORLD;
135  petsc::Initializer petsc(argc, argv, help);
136 
137  com = PETSC_COMM_WORLD;
138 
139  /* This explicit scoping forces destructors to be called before PetscFinalize() */
140  try {
141  std::shared_ptr<Context> ctx = context_from_options(com, "ssa_testi");
142  Config::Ptr config = ctx->config();
143 
144  std::string usage = "\n"
145  "usage of SSA_TESTi:\n"
146  " run ssa_testi -Mx <number> -My <number> -ssa_method <fd|fem>\n"
147  "\n";
148 
149  bool stop = show_usage_check_req_opts(*ctx->log(), "ssa_testi", {}, usage);
150 
151  if (stop) {
152  return 0;
153  }
154 
155  // Parameters that can be overridden by command line options
156  unsigned int Mx = config->get_number("grid.Mx");
157  unsigned int My = config->get_number("grid.My");
158 
159  auto method = config->get_string("stress_balance.ssa.method");
160  auto output_file = config->get_string("output.file");
161 
162  bool write_output = config->get_string("output.size") != "none";
163 
164  // Determine the kind of solver to use.
165  SSAFactory ssafactory = NULL;
166  if (method == "fem") {
167  ssafactory = SSAFEMFactory;
168  } else if (method == "fd") {
169  ssafactory = SSAFDFactory;
170  } else {
171  /* can't happen */
172  }
173 
174  SSATestCaseI testcase(ctx, Mx, My, ssafactory);
175  testcase.init();
176  testcase.run();
177  testcase.report("I");
178  if (write_output) {
179  testcase.write(output_file);
180  }
181  }
182  catch (...) {
183  handle_fatal_errors(com);
184  return 1;
185  }
186 
187  return 0;
188 }
std::shared_ptr< Config > Ptr
std::shared_ptr< EnthalpyConverter > Ptr
Converts between specific enthalpy and temperature or liquid content.
void ensure_consistency(double ice_free_thickness_threshold)
Definition: Geometry.cc:112
array::Scalar2 ice_surface_elevation
Definition: Geometry.hh:57
array::Scalar2 ice_thickness
Definition: Geometry.hh:51
array::Scalar2 bed_elevation
Definition: Geometry.hh:47
Makes sure that we call begin_access() and end_access() for all accessed array::Arrays.
Definition: Array.hh:65
void set(double c)
Result: v[j] <- c for all j.
Definition: Array.cc:707
void update_ghosts()
Updates ghost points.
Definition: Array.cc:693
SSATestCaseI(std::shared_ptr< Context > ctx, int Mx, int My, SSAFactory ssafactory)
Definition: ssa_testi.cc:52
virtual void exactSolution(int i, int j, double x, double y, double *u, double *v)
Definition: ssa_testi.cc:118
virtual void initializeSSACoefficients()
Set up the coefficient variables as appropriate for the test case.
Definition: ssa_testi.cc:77
virtual void init()
Initialize the test case at the start of a run.
Definition: SSATestCase.cc:94
EnthalpyConverter::Ptr m_enthalpyconverter
Definition: SSATestCase.hh:102
std::shared_ptr< Grid > m_grid
Definition: SSATestCase.hh:94
virtual void report(const std::string &testname)
Report on the generated solution.
Definition: SSATestCase.cc:121
virtual void run()
Solve the SSA.
Definition: SSATestCase.cc:103
virtual void write(const std::string &filename)
Save the computation and data to a file.
Definition: SSATestCase.cc:296
struct TestIParameters exactI(const double m, const double x, const double y)
Definition: exactTestsIJ.c:29
double max(const array::Scalar &input)
Finds maximum over all the values in an array::Scalar object. Ignores ghosts.
Definition: Scalar.cc:165
@ NOT_PERIODIC
Definition: Grid.hh:51
@ CELL_CORNER
Definition: Grid.hh:53
bool domain_edge(const Grid &grid, int i, int j)
Definition: Grid.hh:396
const double B_schoof
Definition: ssa_testi.cc:47
SSA * SSAFDFactory(std::shared_ptr< const Grid > g)
Constructs a new SSAFD.
Definition: SSAFD.cc:49
SSA *(* SSAFactory)(std::shared_ptr< const Grid >)
Definition: SSA.hh:77
const double m_schoof
Definition: ssa_testi.cc:42
const double aspect_schoof
Definition: ssa_testi.cc:44
const double L_schoof
Definition: ssa_testi.cc:43
SSA * SSAFEMFactory(std::shared_ptr< const Grid > g)
Factory function for constructing a new SSAFEM.
Definition: SSAFEM.cc:112
const double H0_schoof
Definition: ssa_testi.cc:45
Stress balance models and related diagnostics.
Definition: Isochrones.hh:31
std::shared_ptr< Context > context_from_options(MPI_Comm com, const std::string &prefix, bool print)
Create a default context using options.
Definition: Context.cc:170
void handle_fatal_errors(MPI_Comm com)
bool show_usage_check_req_opts(const Logger &log, const std::string &execname, const std::vector< std::string > &required_options, const std::string &usage)
In a single call a driver program can provide a usage string to the user and check if required option...
Definition: pism_options.cc:51
int main(int argc, char *argv[])
Definition: ssa_testi.cc:129
static char help[]
Definition: ssa_testi.cc:19
const int I[]
Definition: ssafd_code.cc:24