26#include "pism/verification/tests/exactTestH.h"
27#include "pism/verification/tests/exactTestL.hh"
28#include "pism/verification/tests/exactTestsABCD.h"
29#include "pism/verification/tests/exactTestsFG.hh"
31#include "pism/verification/BTU_Verification.hh"
32#include "pism/verification/PSVerification.hh"
33#include "pism/verification/TemperatureModel_Verification.hh"
34#include "pism/verification/iceCompModel.hh"
35#include "pism/coupler/SeaLevel.hh"
36#include "pism/coupler/ocean/Constant.hh"
37#include "pism/earth/BedDef.hh"
38#include "pism/energy/BTU_Minimal.hh"
39#include "pism/rheology/PatersonBuddCold.hh"
40#include "pism/stressbalance/ShallowStressBalance.hh"
41#include "pism/stressbalance/StressBalance.hh"
42#include "pism/stressbalance/sia/SIAFD.hh"
43#include "pism/util/Config.hh"
44#include "pism/util/Context.hh"
45#include "pism/util/EnthalpyConverter.hh"
46#include "pism/util/Grid.hh"
47#include "pism/util/Logger.hh"
48#include "pism/util/Mask.hh"
49#include "pism/util/Time.hh"
50#include "pism/util/error_handling.hh"
51#include "pism/util/io/File.hh"
52#include "pism/util/pism_options.hh"
53#include "pism/util/pism_utilities.hh"
54#include "pism/util/io/IO_Flags.hh"
63 m_HexactL(m_grid,
"HexactL"),
64 m_strain_heating3_comp(m_grid,
"strain_heating_comp", array::WITHOUT_GHOSTS, m_grid->z()),
65 m_bedrock_is_ice_forK(false) {
70 m_config->set_number(
"stress_balance.sia.enhancement_factor", 1.0);
72 m_config->set_number(
"stress_balance.sia.bed_smoother.range", 0.0);
75 m_config->set_flag(
"geometry.update.enabled",
true);
76 m_config->set_flag(
"geometry.update.use_basal_melt_rate",
false);
86 m_config->set_string(
"stress_balance.sia.flow_law",
"isothermal_glen");
87 const double year = convert(
m_sys, 1.0,
"year",
"seconds");
88 m_config->set_number(
"flow_law.isothermal_Glen.ice_softness", 1.0e-16 / year);
92 m_config->set_string(
"stress_balance.ssa.flow_law",
"isothermal_glen");
93 const double hardness = 1.9e8,
95 pow(hardness, -
m_config->get_number(
"stress_balance.ssa.Glen_exponent"));
96 m_config->set_number(
"flow_law.isothermal_Glen.ice_softness", softness);
104 m_config->set_string(
"stress_balance.sia.flow_law",
"arr");
110 m_config->set_string(
"bed_deformation.model",
"iso");
112 m_config->set_string(
"bed_deformation.model",
"none");
116 m_config->set_string(
"energy.model",
"cold");
119 m_config->set_number(
"energy.minimum_allowed_temperature", 0.0);
120 m_config->set_number(
"energy.max_low_temperature_count", 1000000);
122 m_config->set_string(
"energy.model",
"none");
126 m_config->set_number(
"sea_level.constant.value", -1e4);
130 m_config->set_flag(
"energy.allow_temperature_above_melting",
false);
133 m_config->set_flag(
"energy.allow_temperature_above_melting",
true);
138 m_config->set_flag(
"geometry.update.use_basal_melt_rate",
false);
141 m_config->set_string(
"energy.model",
"none");
144 m_config->set_string(
"stress_balance_model",
"ssa");
147 m_config->set_number(
"sea_level.constant.value", 0.0);
149 m_config->set_flag(
"stress_balance.ssa.dirichlet_bc",
true);
158 .
long_name(
"rate of compensatory strain heating in ice")
169 bool biiSet =
options::Bool(
"-bedrock_is_ice",
"set bedrock properties to those of ice");
172 m_log->message(1,
"setting material properties of bedrock to those of ice in Test K\n");
173 m_config->set_number(
"energy.bedrock_thermal.density",
174 m_config->get_number(
"constants.ice.density"));
175 m_config->set_number(
"energy.bedrock_thermal.conductivity",
176 m_config->get_number(
"constants.ice.thermal_conductivity"));
177 m_config->set_number(
"energy.bedrock_thermal.specific_heat_capacity",
178 m_config->get_number(
"constants.ice.specific_heat_capacity"));
182 1,
"IceCompModel WARNING: option -bedrock_is_ice ignored; only applies to Test K\n");
191 m_config->set_number(
"energy.bedrock_thermal.density",
192 m_config->get_number(
"constants.ice.density"));
193 m_config->set_number(
"energy.bedrock_thermal.conductivity",
194 m_config->get_number(
"constants.ice.thermal_conductivity"));
195 m_config->set_number(
"energy.bedrock_thermal.specific_heat_capacity",
196 m_config->get_number(
"constants.ice.specific_heat_capacity"));
201 if (bed_vertical_grid.Mbz > 1) {
202 m_btu = std::make_shared<energy::BTU_Verification>(
m_grid, bed_vertical_grid,
205 m_btu = std::make_shared<energy::BTU_Minimal>(
m_grid);
217 m_log->message(2,
"# Allocating an energy balance model...\n");
220 bool bedrock_is_ice =
options::Bool(
"-bedrock_is_ice",
"set bedrock properties to those of ice");
222 m_energy_model = std::make_shared<energy::TemperatureModel_Verification>(
234 m_f =
m_config->get_number(
"constants.ice.density") /
m_config->get_number(
"bed_deformation.mantle_density");
236 std::string bed_def_model =
m_config->get_string(
"bed_deformation.model");
238 if ((
m_testname ==
'H') && bed_def_model !=
"iso") {
240 "IceCompModel WARNING: Test H should be run with option\n"
241 " '-bed_def iso' for the reported errors to be correct.\n");
246 auto EC =
m_ctx->enthalpy_converter();
261 "PISM does not support bootstrapping in verification mode.");
265 m_log->message(3,
"initializing Test %c from formulas ...\n",
m_testname);
308 const double time =
m_time->current();
316 for (
auto p :
m_grid->points()) {
317 const int i = p.i(), j = p.j();
379 m_log->message(2,
"* Initializing ice thickness and bed topography for test L...\n");
385 std::vector<rgrid> rrv(MM);
387 for (
auto p :
m_grid->points()) {
388 const int i = p.i(), j = p.j();
400 std::vector<double> rr(MM), HH(MM), bb(MM), aa(MM);
402 for (
k = 0;
k < MM;
k++) {
413 for (
k = 0;
k < MM;
k++) {
432 const double LforAE = 750e3;
436 for (
auto p :
m_grid->points()) {
437 const int i = p.i(), j = p.j();
448 double &gdomeHexact,
double &volerr,
449 double &areaerr,
double &gmaxHerr,
450 double &gavHerr,
double &gmaxetaerr,
451 double ¢erHerr) {
454 const double time =
m_time->current();
474 seawater_density =
m_config->get_number(
"constants.sea_water.density"),
475 ice_density =
m_config->get_number(
"constants.ice.density"),
476 Glen_n =
m_config->get_number(
"stress_balance.sia.Glen_exponent"),
477 standard_gravity =
m_config->get_number(
"constants.standard_gravity");
480 const double a =
m_grid->dx() *
m_grid->dy() * 1e-3 * 1e-3;
481 const double m = (2.0 * Glen_n + 2.0) / Glen_n;
485 for (
auto p :
m_grid->points()) {
486 const int i = p.i(), j = p.j();
511 std::vector<double> z(1, 0.0);
520 std::vector<double> z(1, 0.0);
538 v0 = convert(
m_sys, 300.0,
"m year-1",
"m second-1"),
541 C = pow(ice_density * standard_gravity * (1.0 - ice_density/seawater_density) / (4 *
B0), 3);
543 Hexact = pow(4 * C / Q0 * xx + 1/pow(
H0, 4), -0.25);
547 throw RuntimeError(
PISM_ERROR_LOCATION,
"test must be A, B, C, D, F, G, H, K, L, or O");
552 volexact += a * Hexact * 1e-3;
554 if (i == ((
int)
m_grid->Mx() - 1)/2 and
555 j == ((
int)
m_grid->My() - 1)/2) {
571 double gvol, garea, gdomeH;
578 volerr = fabs(gvol - gvolexact);
579 areaerr = fabs(garea - gareaexact);
587 centerHerr = fabs(gdomeH - gdomeHexact);
602static void write(
const File &file,
unsigned int start,
const char *name,
const char *units,
603 const char *long_name,
double value) {
646 bool no_report =
options::Bool(
"-no_report",
"Don't report numerical errors");
652 double maxbmelterr = 0.0, minbmelterr = 0.0, volexact = 0.0, areaexact = 0.0, domeHexact = 0.0,
653 volerr = 0.0, areaerr = 0.0, maxHerr = 0.0, avHerr = 0.0, maxetaerr = 0.0,
655 double maxTerr = 0.0, avTerr = 0.0, basemaxTerr = 0.0, baseavTerr = 0.0, basecenterTerr = 0.0,
656 maxTberr = 0.0, avTberr = 0.0;
657 double max_strain_heating_error = 0.0, av_strain_heating_error = 0.0;
658 double maxUerr = 0.0, avUerr = 0.0, maxWerr = 0.0, avWerr = 0.0;
663 auto EC =
m_ctx->enthalpy_converter();
666 not FlowLawIsPatersonBuddCold(flow_law, *
m_config, EC)) {
668 "WARNING: flow law must be cold part of Paterson-Budd ('-siafd_flow_law arr')\n"
669 " for reported errors in test %c to be meaningful!\n",
674 "NUMERICAL ERRORS evaluated at final time (relative to exact solution):\n");
680 volerr,areaerr,maxHerr,avHerr,maxetaerr,centerHerr);
682 "geometry : prcntVOL maxH avH relmaxETA\n");
683 m_log->message(1,
" %12.6f%12.6f%12.6f%12.6f\n",
684 100*volerr/volexact, maxHerr, avHerr,
685 maxetaerr/pow(domeHexact,m));
694 "temp : maxT avT basemaxT baseavT\n");
695 m_log->message(1,
" %12.6f%12.6f%12.6f%12.6f\n",
696 maxTerr, avTerr, basemaxTerr, baseavTerr);
701 "temp : maxT avT maxTb avTb\n");
702 m_log->message(1,
" %12.6f%12.6f%12.6f%12.6f\n",
703 maxTerr, avTerr, maxTberr, avTberr);
711 "Sigma : maxSig avSig\n");
712 m_log->message(1,
" %12.6f%12.6f\n",
713 max_strain_heating_error*1.0e6, av_strain_heating_error*1.0e6);
720 "surf vels : maxUvec avUvec maxW avW\n");
722 " %12.6f%12.6f%12.6f%12.6f\n",
723 convert(
m_sys, maxUerr,
"m second-1",
"m year-1"),
724 convert(
m_sys, avUerr,
"m second-1",
"m year-1"),
725 convert(
m_sys, maxWerr,
"m second-1",
"m year-1"),
726 convert(
m_sys, avWerr,
"m second-1",
"m year-1"));
732 if (maxbmelterr != minbmelterr) {
734 "IceCompModel WARNING: unexpected Test O situation: max and min of bmelt error\n"
735 " are different: maxbmelterr = %f, minbmelterr = %f\n",
736 convert(
m_sys, maxbmelterr,
"m second-1",
"m year-1"),
737 convert(
m_sys, minbmelterr,
"m second-1",
"m year-1"));
740 "basal melt: max\n");
741 m_log->message(1,
" %11.5f\n",
742 convert(
m_sys, maxbmelterr,
"m second-1",
"m year-1"));
746 m_log->message(1,
"NUM ERRORS DONE\n");
748 options::String report_file(
"-report_file",
"NetCDF error report file");
749 bool append =
options::Bool(
"-append",
"Append the NetCDF error report");
753 if (report_file.
is_set()) {
755 m_log->message(2,
"Also writing errors to '%s'...\n", report_file->c_str());
767 write(file, start,
"N",
"1",
"run number", start + 1);
770 write(file, start,
"dx",
"meter",
"grid spacing",
m_grid->dx());
771 write(file, start,
"dy",
"meter",
"grid spacing",
m_grid->dy());
772 write(file, start,
"dz",
"meter",
"grid spacing",
m_grid->dz_max());
778 write(file, start,
"relative_volume",
"1",
"relative volume error", 100*volerr/volexact);
779 write(file, start,
"relative_max_eta",
"1",
"relative $\\eta$ error", maxetaerr/pow(domeHexact,m));
780 write(file, start,
"maximum_thickness",
"meters",
"maximum ice thickness error", maxHerr);
781 write(file, start,
"average_thickness",
"meters",
"average ice thickness error", avHerr);
785 write(file, start,
"maximum_temperature",
"kelvin",
"maximum ice temperature error", maxTerr);
786 write(file, start,
"average_temperature",
"kelvin",
"average ice temperature error", avTerr);
787 write(file, start,
"maximum_basal_temperature",
"kelvin",
"maximum basal temperature error", basemaxTerr);
788 write(file, start,
"average_basal_temperature",
"kelvin",
"average basal temperature error", baseavTerr);
792 write(file, start,
"maximum_sigma",
"1e6 J s-1 m-3",
"maximum strain heating error", c(max_strain_heating_error));
793 write(file, start,
"average_sigma",
"1e6 J s-1 m-3",
"average strain heating error", c(av_strain_heating_error));
798 write(file, start,
"maximum_surface_velocity",
"m year-1",
"maximum ice surface horizontal velocity error", c(maxUerr));
799 write(file, start,
"average_surface_velocity",
"m year-1",
"average ice surface horizontal velocity error", c(avUerr));
800 write(file, start,
"maximum_surface_w",
"m year-1",
"maximum ice surface vertical velocity error", c(maxWerr));
801 write(file, start,
"average_surface_w",
"m year-1",
"average ice surface vertical velocity error", c(avWerr));
806 write(file, start,
"maximum_temperature",
"kelvin",
"maximum ice temperature error", maxTerr);
807 write(file, start,
"average_temperature",
"kelvin",
"average ice temperature error", avTerr);
808 write(file, start,
"maximum_bedrock_temperature",
"kelvin",
"maximum bedrock temperature error", maxTberr);
809 write(file, start,
"average_bedrock_temperature",
"kelvin",
"average bedrock temperature error", avTberr);
814 write(file, start,
"maximum_basal_melt_rate",
"m year -1",
"maximum basal melt rate error", c(maxbmelterr));
860 double upstream_velocity = convert(
m_sys, 300.0,
"m year-1",
"m second-1"),
861 upstream_thk = 600.0;
867 for (
auto p :
m_grid->points()) {
868 const int i = p.i(), j = p.j();
void define_dimension(const std::string &name, size_t length) const
void write_variable(const std::string &variable_name, const std::vector< unsigned int > &start, const std::vector< unsigned int > &count, const double *op) const
void define_variable(const std::string &name, io::Type nctype, const std::vector< std::string > &dims) const
Define a variable.
void write_attribute(const std::string &var_name, const std::string &att_name, io::Type nctype, const std::vector< double > &values) const
Write a multiple-valued double attribute.
unsigned int dimension_length(const std::string &name) const
Get the length of a dimension.
High-level PISM I/O class.
array::Scalar1 sea_level_elevation
array::CellType2 cell_type
array::Scalar2 ice_thickness
array::Scalar2 bed_elevation
virtual void allocate_bed_deformation()
void compute_strain_heating_errors(double &gmax_strain_heating_err, double &gav_strain_heating_err)
virtual void post_step_hook()
Virtual. Does nothing in IceModel. Derived classes can do more computation in each time step.
void reset_thickness_test_A()
Tests A and E have a thickness B.C. (ice_thickness == 0 outside a circle of radius 750km).
void bootstrap_2d(const File &input_file) __attribute__((noreturn))
virtual void allocate_couplers()
virtual void allocate_bedrock_thermal_unit()
Decide which bedrock thermal unit to use.
virtual void print_summary(bool tempAndAge, double dt)
array::Array3D m_strain_heating3_comp
void test_V_init()
Initialize test V.
virtual void initialize_2d()
void computeSurfaceVelocityErrors(double &gmaxUerr, double &gavUerr, double &gmaxWerr, double &gavWerr)
bool m_bedrock_is_ice_forK
virtual void allocate_energy_model()
void computeIceBedrockTemperatureErrors(double &gmaxTerr, double &gavTerr, double &gmaxTberr, double &gavTberr)
virtual void allocate_storage()
Allocate all Arrays defined in IceModel.
void computeTemperatureErrors(double &gmaxTerr, double &gavTerr)
void computeGeometryErrors(double &gvolexact, double &gareaexact, double &gdomeHexact, double &volerr, double &areaerr, double &gmaxHerr, double &gavHerr, double &gmaxetaerr, double ¢erHerr)
static const double m_LforFG
IceCompModel(std::shared_ptr< Grid > g, std::shared_ptr< Context > ctx, int mytest)
void computeBasalMeltRateErrors(double &gmaxbmelterr, double &gminbmelterr)
static const double m_ApforG
void computeBasalTemperatureErrors(double &gmaxTerr, double &gavTerr, double ¢erTerr)
std::map< std::string, const Component * > m_submodels
the list of sub-models, for writing model states and obtaining diagnostics
virtual void allocate_bed_deformation()
std::shared_ptr< stressbalance::StressBalance > m_stress_balance
std::shared_ptr< ocean::OceanModel > m_ocean
std::shared_ptr< surface::SurfaceModel > m_surface
std::shared_ptr< Config > m_config
Configuration flags and parameters.
std::shared_ptr< Context > m_ctx
Execution context.
std::shared_ptr< Logger > m_log
Logger.
VariableMetadata m_output_global_attributes
stores global attributes saved in a PISM output file
std::shared_ptr< Time > m_time
Time manager.
virtual void allocate_storage()
Allocate all Arrays defined in IceModel.
array::Scalar2 m_velocity_bc_mask
mask to determine Dirichlet boundary locations for the sliding velocity
std::shared_ptr< energy::BedThermalUnit > m_btu
array::Scalar1 m_ice_thickness_bc_mask
Mask prescribing locations where ice thickness is held constant.
const units::System::Ptr m_sys
Unit system.
array::Vector2 m_velocity_bc_values
Dirichlet boundary velocities.
std::shared_ptr< ocean::sea_level::SeaLevel > m_sea_level
virtual void print_summary(bool tempAndAge, double dt)
std::shared_ptr< energy::EnergyModel > m_energy_model
const std::shared_ptr< Grid > m_grid
Computational grid.
std::shared_ptr< bed::BedDef > m_beddef
void failed()
Indicates a failure of a parallel section.
void add(const PetscAccessible &v)
Makes sure that we call begin_access() and end_access() for all accessed array::Arrays.
void copy_from(const Array2D< T > &source)
void scale(double alpha)
Result: v <- v * alpha. Calls VecScale.
void set(double c)
Result: v[j] <- c for all j.
void update_ghosts()
Updates ghost points.
VariableMetadata & metadata(unsigned int N=0)
Returns a reference to the VariableMetadata object containing metadata for the compoment N.
A class implementing a constant (in terms of the ocean inputs) ocean model. Uses configuration parame...
Class used initTestL() in generating sorted list for ODE solver.
Climate inputs for verification tests.
#define PISM_ERROR_LOCATION
struct TestHParameters exactH(const double f, const double t, const double r)
ExactLParameters exactL(const std::vector< double > &r)
struct TestABCDParameters exactB(const double t, const double r)
struct TestABCDParameters exactD(const double t, const double r)
struct TestABCDParameters exactA(double r)
struct TestABCDParameters exactC(const double t, const double r)
double radius(const Grid &grid, int i, int j)
Returns the distance from the point (i,j) to the origin.
@ 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
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)
TestFGParameters exactFG(double t, double r, const std::vector< double > &z, double Cp)
static void write(const File &file, unsigned int start, const char *name, const char *units, const char *long_name, double value)
void GlobalSum(MPI_Comm comm, double *local, double *result, int count)
static BTUGrid FromOptions(std::shared_ptr< const Context > ctx)
bool operator()(rgrid a, rgrid b)
Comparison used initTestL() in generating sorted list for ODE solver.