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/ConfigInterface.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/io/io_helpers.hh"
53 #include "pism/util/pism_options.hh"
54 #include "pism/util/pism_utilities.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_flag(
"energy.enabled",
true);
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_flag(
"energy.enabled",
false);
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_flag(
"energy.enabled",
false);
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);
152 m_config->set_flag(
"energy.temperature_based",
true);
160 .
long_name(
"rate of compensatory strain heating in ice")
171 bool biiSet =
options::Bool(
"-bedrock_is_ice",
"set bedrock properties to those of ice");
174 m_log->message(1,
"setting material properties of bedrock to those of ice in Test K\n");
175 m_config->set_number(
"energy.bedrock_thermal.density",
176 m_config->get_number(
"constants.ice.density"));
177 m_config->set_number(
"energy.bedrock_thermal.conductivity",
178 m_config->get_number(
"constants.ice.thermal_conductivity"));
179 m_config->set_number(
"energy.bedrock_thermal.specific_heat_capacity",
180 m_config->get_number(
"constants.ice.specific_heat_capacity"));
184 1,
"IceCompModel WARNING: option -bedrock_is_ice ignored; only applies to Test K\n");
193 m_config->set_number(
"energy.bedrock_thermal.density",
194 m_config->get_number(
"constants.ice.density"));
195 m_config->set_number(
"energy.bedrock_thermal.conductivity",
196 m_config->get_number(
"constants.ice.thermal_conductivity"));
197 m_config->set_number(
"energy.bedrock_thermal.specific_heat_capacity",
198 m_config->get_number(
"constants.ice.specific_heat_capacity"));
203 if (bed_vertical_grid.Mbz > 1) {
204 m_btu = std::make_shared<energy::BTU_Verification>(
m_grid, bed_vertical_grid,
207 m_btu = std::make_shared<energy::BTU_Minimal>(
m_grid);
219 m_log->message(2,
"# Allocating an energy balance model...\n");
222 bool bedrock_is_ice =
options::Bool(
"-bedrock_is_ice",
"set bedrock properties to those of ice");
224 m_energy_model = std::make_shared<energy::TemperatureModel_Verification>(
236 m_f =
m_config->get_number(
"constants.ice.density") /
m_config->get_number(
"bed_deformation.mantle_density");
238 std::string bed_def_model =
m_config->get_string(
"bed_deformation.model");
240 if ((
m_testname ==
'H') && bed_def_model !=
"iso") {
242 "IceCompModel WARNING: Test H should be run with option\n"
243 " '-bed_def iso' for the reported errors to be correct.\n");
267 m_log->message(3,
"initializing Test %c from formulas ...\n",
m_testname);
310 const double time =
m_time->current();
318 for (
auto p =
m_grid->points(); p; p.next()) {
319 const int i = p.i(), j = p.j();
381 m_log->message(2,
"* Initializing ice thickness and bed topography for test L...\n");
387 std::vector<rgrid> rrv(MM);
389 for (
auto p =
m_grid->points(); p; p.next()) {
390 const int i = p.i(), j = p.j();
402 std::vector<double> rr(MM), HH(MM), bb(MM), aa(MM);
404 for (
k = 0;
k < MM;
k++) {
415 for (
k = 0;
k < MM;
k++) {
434 const double LforAE = 750e3;
438 for (
auto p =
m_grid->points(); p; p.next()) {
439 const int i = p.i(), j = p.j();
450 double &gdomeHexact,
double &volerr,
451 double &areaerr,
double &gmaxHerr,
452 double &gavHerr,
double &gmaxetaerr,
453 double ¢erHerr) {
456 const double time =
m_time->current();
476 seawater_density =
m_config->get_number(
"constants.sea_water.density"),
477 ice_density =
m_config->get_number(
"constants.ice.density"),
478 Glen_n =
m_config->get_number(
"stress_balance.sia.Glen_exponent"),
479 standard_gravity =
m_config->get_number(
"constants.standard_gravity");
482 const double a =
m_grid->dx() *
m_grid->dy() * 1e-3 * 1e-3;
483 const double m = (2.0 * Glen_n + 2.0) / Glen_n;
487 for (
auto p =
m_grid->points(); p; p.next()) {
488 const int i = p.i(), j = p.j();
513 std::vector<double> z(1, 0.0);
522 std::vector<double> z(1, 0.0);
543 C = pow(ice_density * standard_gravity * (1.0 - ice_density/seawater_density) / (4 *
B0), 3);
545 Hexact = pow(4 *
C / Q0 * xx + 1/pow(
H0, 4), -0.25);
549 throw RuntimeError(
PISM_ERROR_LOCATION,
"test must be A, B, C, D, F, G, H, K, L, or O");
554 volexact += a * Hexact * 1e-3;
556 if (i == ((
int)
m_grid->Mx() - 1)/2 and
557 j == ((
int)
m_grid->My() - 1)/2) {
573 double gvol, garea, gdomeH;
580 volerr = fabs(gvol - gvolexact);
581 areaerr = fabs(garea - gareaexact);
589 centerHerr = fabs(gdomeH - gdomeHexact);
605 const char *units,
const char *long_name,
double value,
609 v[
"long_name"] = long_name;
647 bool no_report =
options::Bool(
"-no_report",
"Don't report numerical errors");
653 double maxbmelterr, minbmelterr, volexact, areaexact, domeHexact,
654 volerr, areaerr, maxHerr, avHerr, maxetaerr, centerHerr;
655 double maxTerr, avTerr, basemaxTerr, baseavTerr, basecenterTerr, maxTberr, avTberr;
656 double max_strain_heating_error, av_strain_heating_error;
657 double maxUerr, avUerr, maxWerr, avWerr;
667 "pismv WARNING: flow law must be cold part of Paterson-Budd ('-siafd_flow_law arr')\n"
668 " for reported errors in test %c to be meaningful!\n",
673 "NUMERICAL ERRORS evaluated at final time (relative to exact solution):\n");
679 volerr,areaerr,maxHerr,avHerr,maxetaerr,centerHerr);
681 "geometry : prcntVOL maxH avH relmaxETA\n");
682 m_log->message(1,
" %12.6f%12.6f%12.6f%12.6f\n",
683 100*volerr/volexact, maxHerr, avHerr,
684 maxetaerr/pow(domeHexact,m));
693 "temp : maxT avT basemaxT baseavT\n");
694 m_log->message(1,
" %12.6f%12.6f%12.6f%12.6f\n",
695 maxTerr, avTerr, basemaxTerr, baseavTerr);
700 "temp : maxT avT maxTb avTb\n");
701 m_log->message(1,
" %12.6f%12.6f%12.6f%12.6f\n",
702 maxTerr, avTerr, maxTberr, avTberr);
710 "Sigma : maxSig avSig\n");
711 m_log->message(1,
" %12.6f%12.6f\n",
712 max_strain_heating_error*1.0e6, av_strain_heating_error*1.0e6);
719 "surf vels : maxUvec avUvec maxW avW\n");
721 " %12.6f%12.6f%12.6f%12.6f\n",
731 if (maxbmelterr != minbmelterr) {
733 "IceCompModel WARNING: unexpected Test O situation: max and min of bmelt error\n"
734 " are different: maxbmelterr = %f, minbmelterr = %f\n",
739 "basal melt: max\n");
740 m_log->message(1,
" %11.5f\n",
745 m_log->message(1,
"NUM ERRORS DONE\n");
747 options::String report_file(
"-report_file",
"NetCDF error report file");
748 bool append =
options::Bool(
"-append",
"Append the NetCDF error report");
752 if (report_file.
is_set()) {
754 m_log->message(2,
"Also writing errors to '%s'...\n", report_file->c_str());
764 write(
m_sys, file, start,
"N",
"1",
"run number", start + 1);
775 write(
m_sys, file, start,
"relative_volume",
"1",
"relative volume error", 100*volerr/volexact);
776 write(
m_sys, file, start,
"relative_max_eta",
"1",
"relative $\\eta$ error", maxetaerr/pow(domeHexact,m));
777 write(
m_sys, file, start,
"maximum_thickness",
"meters",
"maximum ice thickness error", maxHerr);
778 write(
m_sys, file, start,
"average_thickness",
"meters",
"average ice thickness error", avHerr);
782 write(
m_sys, file, start,
"maximum_temperature",
"Kelvin",
"maximum ice temperature error", maxTerr);
783 write(
m_sys, file, start,
"average_temperature",
"Kelvin",
"average ice temperature error", avTerr);
784 write(
m_sys, file, start,
"maximum_basal_temperature",
"Kelvin",
"maximum basal temperature error", basemaxTerr);
785 write(
m_sys, file, start,
"average_basal_temperature",
"Kelvin",
"average basal temperature error", baseavTerr);
789 write(
m_sys, file, start,
"maximum_sigma",
"1e6 J s-1 m-3",
"maximum strain heating error", c(max_strain_heating_error));
790 write(
m_sys, file, start,
"average_sigma",
"1e6 J s-1 m-3",
"average strain heating error", c(av_strain_heating_error));
795 write(
m_sys, file, start,
"maximum_surface_velocity",
"m year-1",
"maximum ice surface horizontal velocity error", c(maxUerr));
796 write(
m_sys, file, start,
"average_surface_velocity",
"m year-1",
"average ice surface horizontal velocity error", c(avUerr));
797 write(
m_sys, file, start,
"maximum_surface_w",
"m year-1",
"maximum ice surface vertical velocity error", c(maxWerr));
798 write(
m_sys, file, start,
"average_surface_w",
"m year-1",
"average ice surface vertical velocity error", c(avWerr));
803 write(
m_sys, file, start,
"maximum_temperature",
"Kelvin",
"maximum ice temperature error", maxTerr);
804 write(
m_sys, file, start,
"average_temperature",
"Kelvin",
"average ice temperature error", avTerr);
805 write(
m_sys, file, start,
"maximum_bedrock_temperature",
"Kelvin",
"maximum bedrock temperature error", maxTberr);
806 write(
m_sys, file, start,
"average_bedrock_temperature",
"Kelvin",
"average bedrock temperature error", avTberr);
811 write(
m_sys, file, start,
"maximum_basal_melt_rate",
"m year -1",
"maximum basal melt rate error", c(maxbmelterr));
857 double upstream_velocity =
convert(
m_sys, 300.0,
"m year-1",
"m second-1"),
858 upstream_thk = 600.0;
864 for (
auto p =
m_grid->points(); p; p.next()) {
865 const int i = p.i(), j = p.j();
std::shared_ptr< EnthalpyConverter > Ptr
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.
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
virtual void print_summary(bool tempAndAge)
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
const Config::Ptr m_config
Configuration flags and parameters.
const Time::Ptr m_time
Time manager.
const std::shared_ptr< Context > m_ctx
Execution context.
const Logger::Ptr m_log
Logger.
virtual void print_summary(bool tempAndAge)
VariableMetadata m_output_global_attributes
stores global attributes saved in a PISM output file
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
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.
SpatialVariableMetadata & metadata(unsigned int N=0)
Returns a reference to the SpatialVariableMetadata 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.
std::shared_ptr< System > Ptr
#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 max(const array::Scalar &input)
Finds maximum over all the values in an array::Scalar object. Ignores ghosts.
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
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_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)
bool FlowLawIsPatersonBuddCold(const FlowLaw &flow_law, const Config &config, EnthalpyConverter::Ptr EC)
double convert(System::Ptr system, double input, const std::string &spec1, const std::string &spec2)
Convert a quantity from unit1 to unit2.
static void write(units::System::Ptr sys, const File &file, size_t start, const char *name, const char *units, const char *long_name, double value, io::Type type=io::PISM_DOUBLE)
void GlobalMax(MPI_Comm comm, double *local, double *result, int count)
TestFGParameters exactFG(double t, double r, const std::vector< double > &z, double Cp)
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.