PISM, A Parallel Ice Sheet Model  stable v2.1-1-g6902d5502 committed by Ed Bueler on 2023-12-20 08:38:27 -0800
ssa_test_cfbc.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_TESTCFBC\n"
21  " Testing program for PISM's implementations of the SSA.\n"
22  " Does a time-independent calculation. Does not run IceModel or a derived\n"
23  " class thereof. Uses the van der Veen flow-line shelf geometry. Also may be\n"
24  " used in a PISM 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/SSAFD_diagnostics.hh"
29 #include "pism/stressbalance/ssa/SSATestCase.hh"
30 #include "pism/stressbalance/ssa/SSAFEM.hh"
31 #include "pism/util/Mask.hh"
32 #include "pism/util/Context.hh"
33 #include "pism/util/VariableMetadata.hh"
34 #include "pism/util/error_handling.hh"
35 #include "pism/util/io/File.hh"
36 #include "pism/util/petscwrappers/PetscInitializer.hh"
37 #include "pism/util/pism_utilities.hh"
38 #include "pism/util/pism_options.hh"
39 
40 namespace pism {
41 namespace stressbalance {
42 
43 // thickness profile in the van der Veen solution
44 static double H_exact(double V0, double H0, double C, double x) {
45  const double Q0 = V0*H0;
46  return pow(4 * C / Q0 * x + 1/pow(H0, 4), -0.25);
47 }
48 
49 // velocity profile; corresponds to constant flux
50 static double u_exact(double V0, double H0, double C, double x) {
51  const double Q0 = V0*H0;
52  return Q0 / H_exact(V0, H0, C, x);
53 }
54 
56 public:
57  SSATestCaseCFBC(std::shared_ptr<Context> ctx, int Mx, int My, SSAFactory ssafactory)
58  : SSATestCase(ctx, Mx, My, 250e3, 250e3, grid::CELL_CENTER, grid::Y_PERIODIC) {
59  V0 = units::convert(ctx->unit_system(), 300.0, "m year-1", "m second-1");
60  H0 = 600.0; // meters
61  C = 2.45e-18;
62 
63  m_config->set_number("flow_law.isothermal_Glen.ice_softness",
64  pow(1.9e8, -m_config->get_number("stress_balance.ssa.Glen_exponent")));
65  m_config->set_flag("stress_balance.ssa.compute_surface_gradient_inward", false);
66  m_config->set_flag("stress_balance.calving_front_stress_bc", true);
67  m_config->set_flag("stress_balance.ssa.fd.flow_line_mode", true);
68  m_config->set_flag("stress_balance.ssa.fd.extrapolate_at_margins", false);
69  m_config->set_string("stress_balance.ssa.flow_law", "isothermal_glen");
70 
72 
73  m_ssa = ssafactory(m_grid);
74  }
75 
76  virtual void write_nuH(const std::string &filename);
77 
78 protected:
79  virtual void initializeSSACoefficients();
80 
81  virtual void exactSolution(int i, int j,
82  double x, double y, double *u, double *v);
83 
84  double V0, //!< grounding line vertically-averaged velocity
85  H0, //!< grounding line thickness (meters)
86  C; //!< "typical constant ice parameter"
87 };
88 
89 void SSATestCaseCFBC::write_nuH(const std::string &filename) {
90 
91  SSAFD *ssafd = dynamic_cast<SSAFD*>(m_ssa);
92  if (ssafd != NULL) {
93  SSAFD_nuH(ssafd).compute()->write(filename);
94  }
95 }
96 
98 
99  m_tauc.set(0.0); // irrelevant
100  m_geometry.bed_elevation.set(-1000.0); // assures shelf is floating
101 
102  double enth0 = m_enthalpyconverter->enthalpy(273.15, 0.01, 0.0); // 0.01 water fraction
103  m_ice_enthalpy.set(enth0);
104 
107 
108  const double x_min = m_grid->x(0);
109 
110  for (auto p = m_grid->points(); p; p.next()) {
111  const int i = p.i(), j = p.j();
112 
113  const double x = m_grid->x(i);
114 
115  if (i != (int)m_grid->Mx() - 1) {
116  m_geometry.ice_thickness(i, j) = H_exact(V0, H0, C, x - x_min);
117  } else {
118  m_geometry.ice_thickness(i, j) = 0.0;
119  }
120 
121  if (i == 0) {
122  m_bc_mask(i, j) = 1;
123  m_bc_values(i, j) = {V0, 0.0};
124  } else {
125  m_bc_mask(i, j) = 0;
126  m_bc_values(i, j) = {0.0, 0.0};
127  }
128  }
129 
130  // communicate what we have set
132 
135 }
136 
137 void SSATestCaseCFBC::exactSolution(int i, int /*j*/,
138  double x, double /*y*/,
139  double *u, double *v) {
140  const double x_min = m_grid->x(0);
141 
142  if (i != (int)m_grid->Mx() - 1) {
143  *u = u_exact(V0, H0, C, x - x_min);
144  } else {
145  *u = 0;
146  }
147 
148  *v = 0;
149 }
150 
151 } // end of namespace stressbalance
152 } // end of namespace pism
153 
154 int main(int argc, char *argv[]) {
155 
156  using namespace pism;
157  using namespace pism::stressbalance;
158 
159  MPI_Comm com = MPI_COMM_WORLD;
160  petsc::Initializer petsc(argc, argv, help);
161 
162  com = PETSC_COMM_WORLD;
163 
164  /* This explicit scoping forces destructors to be called before PetscFinalize() */
165  try {
166  std::shared_ptr<Context> ctx = context_from_options(com, "ssa_test_cfbc");
167  Config::Ptr config = ctx->config();
168 
169  std::string usage = "\n"
170  "usage of SSA_TEST_CFBC:\n"
171  " run ssa_test_cfbc -Mx <number> -My <number>\n"
172  "\n";
173 
174  bool stop = show_usage_check_req_opts(*ctx->log(), "ssa_test_cfbc", {}, usage);
175 
176  if (stop) {
177  return 0;
178  }
179 
180  // Parameters that can be overridden by command line options
181  unsigned int Mx = config->get_number("grid.Mx");
182  unsigned int My = config->get_number("grid.My");
183 
184  auto method = config->get_string("stress_balance.ssa.method");
185  auto output_file = config->get_string("output.file");
186 
187  bool write_output = config->get_string("output.size") != "none";
188 
189  // Determine the kind of solver to use.
190  SSAFactory ssafactory = NULL;
191  if (method == "fem") {
192  ssafactory = SSAFEMFactory;
193  } else if (method == "fd") {
194  ssafactory = SSAFDFactory;
195  } else {
196  /* can't happen */
197  }
198 
199  SSATestCaseCFBC testcase(ctx, Mx, My, ssafactory);
200  testcase.init();
201  testcase.run();
202  testcase.report("V");
203  if (write_output) {
204  testcase.write(output_file);
205  testcase.write_nuH(output_file);
206  }
207  }
208  catch (...) {
209  handle_fatal_errors(com);
210  return 1;
211  }
212 
213  return 0;
214 }
std::shared_ptr< Config > Ptr
std::shared_ptr< array::Array > compute() const
Compute a diagnostic quantity and return a pointer to a newly-allocated Array.
Definition: Diagnostic.cc:131
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::CellType2 cell_type
Definition: Geometry.hh:55
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
Reports the nuH (viscosity times thickness) product on the staggered grid.
PISM's SSA solver: the finite difference implementation.
Definition: SSAFD.hh:35
double H0
grounding line thickness (meters)
SSATestCaseCFBC(std::shared_ptr< Context > ctx, int Mx, int My, SSAFactory ssafactory)
virtual void exactSolution(int i, int j, double x, double y, double *u, double *v)
double C
"typical constant ice parameter"
virtual void initializeSSACoefficients()
Set up the coefficient variables as appropriate for the test case.
double V0
grounding line vertically-averaged velocity
virtual void write_nuH(const std::string &filename)
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
const double H0
Definition: exactTestK.c:37
@ Y_PERIODIC
Definition: Grid.hh:51
@ CELL_CENTER
Definition: Grid.hh:53
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
static double H_exact(double V0, double H0, double C, double x)
SSA * SSAFEMFactory(std::shared_ptr< const Grid > g)
Factory function for constructing a new SSAFEM.
Definition: SSAFEM.cc:112
static double u_exact(double V0, double H0, double C, double x)
Stress balance models and related diagnostics.
Definition: Isochrones.hh:31
double convert(System::Ptr system, double input, const std::string &spec1, const std::string &spec2)
Convert a quantity from unit1 to unit2.
Definition: Units.cc:70
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[])
static char help[]
const int C[]
Definition: ssafd_code.cc:44