19 #include "pism/stressbalance/ssa/SSATestCase.hh"
20 #include "pism/stressbalance/StressBalance.hh"
21 #include "pism/util/Context.hh"
22 #include "pism/util/interpolation.hh"
23 #include "pism/util/io/File.hh"
24 #include "pism/util/io/io_helpers.hh"
25 #include "pism/util/pism_options.hh"
26 #include "pism/util/pism_utilities.hh"
29 namespace stressbalance {
35 m_config(ctx->config()),
36 m_grid(
Grid::Shallow(m_ctx, Lx, Ly, 0.0, 0.0, Mx, My, registration, periodicity)),
37 m_sys(ctx->unit_system()),
38 m_stencil_width(m_config->get_number(
"grid.max_stencil_width")),
39 m_tauc(m_grid,
"tauc"),
40 m_ice_enthalpy(m_grid,
"enthalpy", array::
WITH_GHOSTS, m_grid->z(), m_stencil_width),
41 m_bc_values(m_grid,
"_bc"),
42 m_bc_mask(m_grid,
"bc_mask"),
49 .
long_name(
"yield stress for basal till (plastic or pseudo-plastic model)")
54 .
long_name(
"ice enthalpy (includes sensible heat, latent heat, pressure)")
59 .
long_name(
"X-component of the SSA velocity boundary conditions")
63 .
long_name(
"Y-component of the SSA velocity boundary conditions")
70 units::convert(sys, config->get_number(
"output.fill_value"),
"m year-1",
"m second-1");
104 m_ctx->log()->message(2,
"* Solving the SSA stress balance ...\n");
116 bool full_update =
true;
125 double maxvecerr = 0.0, avvecerr = 0.0, avuerr = 0.0, avverr = 0.0, maxuerr = 0.0, maxverr = 0.0;
126 double gmaxvecerr = 0.0, gavvecerr = 0.0, gavuerr = 0.0, gavverr = 0.0, gmaxuerr = 0.0,
129 if (
m_config->get_flag(
"basal_resistance.pseudo_plastic.enabled") &&
130 m_config->get_number(
"basal_resistance.pseudo_plastic.q") != 1.0) {
131 m_ctx->log()->message(1,
"WARNING: numerical errors not valid for pseudo-plastic till\n");
133 m_ctx->log()->message(1,
"NUMERICAL ERRORS in velocity relative to exact solution:\n");
139 double exactvelmax = 0, gexactvelmax = 0;
140 for (
auto p =
m_grid->points(); p; p.next()) {
141 const int i = p.i(), j = p.j();
143 double uexact, vexact;
148 double exactnormsq = sqrt(uexact * uexact + vexact * vexact);
149 exactvelmax =
std::max(exactnormsq, exactvelmax);
152 const double uerr = fabs(vel_ssa(i, j).u - uexact);
153 const double verr = fabs(vel_ssa(i, j).v - vexact);
154 avuerr = avuerr + uerr;
155 avverr = avverr + verr;
158 const double vecerr = sqrt(uerr * uerr + verr * verr);
159 maxvecerr =
std::max(maxvecerr, vecerr);
160 avvecerr = avvecerr + vecerr;
169 gavuerr = gavuerr / N;
171 gavverr = gavverr / N;
174 gavvecerr = gavvecerr / N;
178 m_ctx->log()->message(
179 1,
"velocity : maxvector prcntavvec maxu maxv avu avv\n");
180 m_ctx->log()->message(1,
" %11.4f%13.5f%10.4f%10.4f%10.4f%10.4f\n",
182 (gavvecerr / gexactvelmax) * 100.0,
188 m_ctx->log()->message(1,
"NUM ERRORS DONE\n");
191 (gavvecerr / gexactvelmax) * 100.0,
199 double max_u,
double max_v,
double avg_u,
double avg_v) {
200 auto sys =
m_grid->ctx()->unit_system();
206 if (not filename.
is_set()) {
210 m_ctx->log()->message(2,
"Also writing errors to '%s'...\n", filename->c_str());
212 bool append =
options::Bool(
"-append",
"Append the NetCDF error report");
219 global_attributes[
"source"] = std::string(
"PISM ") + pism::revision;
252 max_velocity.
long_name(
"maximum ice velocity magnitude error").
units(
"m year-1");
258 rel_velocity.
long_name(
"relative ice velocity magnitude error").
units(
"percent");
264 maximum_u.
long_name(
"maximum error in the X-component of the ice velocity").
units(
"m year-1");
270 maximum_v.
long_name(
"maximum error in the Y-component of the ice velocity").
units(
"m year-1");
276 average_u.
long_name(
"average error in the X-component of the ice velocity").
units(
"m year-1");
282 average_v.
long_name(
"average error in the Y-component of the ice velocity").
units(
"m year-1");
315 .
long_name(
"X-component of the SSA exact solution")
318 .
long_name(
"Y-component of the SSA exact solution")
322 for (
auto p =
m_grid->points(); p; p.next()) {
323 const int i = p.i(), j = p.j();
326 &(exact(i,j).u), &(exact(i,j).v));
std::shared_ptr< const Config > ConstPtr
unsigned int dimension_length(const std::string &name) const
Get the length of a dimension.
High-level PISM I/O class.
void ensure_consistency(double ice_free_thickness_threshold)
array::Scalar2 ice_surface_elevation
array::Scalar2 ice_thickness
array::Scalar2 bed_elevation
Describes the PISM grid and the distribution of data across processors.
Makes sure that we call begin_access() and end_access() for all accessed array::Arrays.
void set_interpolation_type(InterpolationType type)
void write(const std::string &filename) const
void set(double c)
Result: v[j] <- c for all j.
SpatialVariableMetadata & metadata(unsigned int N=0)
Returns a reference to the SpatialVariableMetadata object containing metadata for the compoment N.
virtual void init()
Initialize the test case at the start of a run.
const units::System::Ptr m_sys
array::Array3D m_ice_enthalpy
std::shared_ptr< Grid > m_grid
virtual void initializeSSACoefficients()=0
Set up the coefficient variables as appropriate for the test case.
void report_netcdf(const std::string &testname, double max_vector, double rel_vector, double max_u, double max_v, double avg_u, double avg_v)
array::Vector2 m_bc_values
virtual void exactSolution(int i, int j, double x, double y, double *u, double *v)
const std::shared_ptr< Context > m_ctx
SSATestCase(std::shared_ptr< Context > ctx, int Mx, int My, double Lx, double Ly, grid::Registration registration, grid::Periodicity periodicity)
virtual void report(const std::string &testname)
Report on the generated solution.
virtual void run()
Solve the SSA.
const Config::Ptr m_config
virtual void write(const std::string &filename)
Save the computation and data to a file.
virtual void update(const Inputs &inputs, bool full_update)
Update the SSA solution.
virtual std::string stdout_report() const
Produce a report string for the standard output.
const array::Vector1 & velocity() const
Get the thickness-advective 2D velocity.
std::shared_ptr< System > Ptr
double max(const array::Scalar &input)
Finds maximum over all the values in an array::Scalar object. Ignores ghosts.
void append_time(const File &file, const Config &config, double time_seconds)
Prepare a file for output.
@ PISM_READWRITE_MOVE
create a file for writing, move foo.nc to foo.nc~ if present
@ PISM_READWRITE
open an existing file for reading and writing
void write_attributes(const File &file, const VariableMetadata &variable, io::Type nctype)
Write variable attributes to a NetCDF file.
void write_timeseries(const File &file, const VariableMetadata &metadata, size_t t_start, const std::vector< double > &data)
Write a time-series data to a file.
void define_time(const File &file, const Context &ctx)
Prepare a file for output.
void define_timeseries(const VariableMetadata &var, const std::string &dimension_name, const File &file, io::Type nctype)
Define a NetCDF variable corresponding to a time-series.
bool Bool(const std::string &option, const std::string &description)
double convert(System::Ptr system, double input, const std::string &spec1, const std::string &spec2)
Convert a quantity from unit1 to unit2.
void GlobalMax(MPI_Comm comm, double *local, double *result, int count)
void GlobalSum(MPI_Comm comm, double *local, double *result, int count)