pismv.cc (6556B)
1 // Copyright (C) 2004-2017, 2019 Jed Brown, Ed Bueler and Constantine Khroulev 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 "Ice sheet driver for PISM (SIA and SSA) verification. Uses exact solutions\n" 21 " to various coupled subsystems. Computes difference between exact solution\n" 22 " and numerical solution.\n" 23 " Currently implements tests A, B, C, D, E, F, G, H, K, L.\n\n"; 24 25 #include <string> 26 27 #include "pism/util/IceGrid.hh" 28 #include "pism/util/Config.hh" 29 #include "pism/util/error_handling.hh" 30 #include "pism/util/petscwrappers/PetscInitializer.hh" 31 #include "pism/util/pism_options.hh" 32 #include "pism/verification/iceCompModel.hh" 33 #include "pism/util/Context.hh" 34 #include "pism/util/Logger.hh" 35 #include "pism/util/Time.hh" 36 #include "pism/util/EnthalpyConverter.hh" 37 38 using namespace pism; 39 40 //! Allocate the PISMV (verification) context. Uses ColdEnthalpyConverter. 41 Context::Ptr pismv_context(MPI_Comm com, const std::string &prefix) { 42 // unit system 43 units::System::Ptr sys(new units::System); 44 45 // logger 46 Logger::Ptr logger = logger_from_options(com); 47 48 // configuration parameters 49 Config::Ptr config = config_from_options(com, *logger, sys); 50 51 config->set_string("time.calendar", "none"); 52 config->set_string("grid.periodicity", "none"); 53 config->set_string("grid.registration", "corner"); 54 55 set_config_from_options(*config); 56 57 print_config(*logger, 3, *config); 58 59 Time::Ptr time = time_from_options(com, config, sys); 60 61 EnthalpyConverter::Ptr EC = EnthalpyConverter::Ptr(new ColdEnthalpyConverter(*config)); 62 63 return Context::Ptr(new Context(com, sys, config, EC, time, logger, prefix)); 64 } 65 66 GridParameters pismv_grid_defaults(Config::Ptr config, 67 char testname) { 68 // This sets the defaults for each test; command-line options can override this. 69 70 GridParameters P; 71 72 // use the cell corner grid registration 73 P.registration = CELL_CORNER; 74 // use the non-periodic grid: 75 P.periodicity = NOT_PERIODIC; 76 // equal spacing is the default for all the tests except K 77 P.Lx = config->get_number("grid.Lx"); 78 P.Ly = config->get_number("grid.Ly"); 79 80 P.Mx = config->get_number("grid.Mx"); 81 P.My = config->get_number("grid.My"); 82 83 SpacingType spacing = EQUAL; 84 double Lz = config->get_number("grid.Lz"); 85 unsigned int Mz = config->get_number("grid.Mz"); 86 87 switch (testname) { 88 case 'A': 89 case 'B': 90 case 'H': 91 // use 2400km by 2400km by 4000m rectangular domain 92 P.Lx = 1200e3; 93 P.Ly = P.Lx; 94 Lz = 4000; 95 break; 96 case 'C': 97 case 'D': 98 // use 2000km by 2000km by 4000m rectangular domain 99 P.Lx = 1000e3; 100 P.Ly = P.Lx; 101 Lz = 4000; 102 break; 103 case 'F': 104 case 'G': 105 case 'L': 106 // use 1800km by 1800km by 4000m rectangular domain 107 P.Lx = 900e3; 108 P.Ly = P.Lx; 109 Lz = 4000; 110 break; 111 case 'K': 112 case 'O': 113 // use 2000km by 2000km by 4000m rectangular domain, but make truely periodic 114 config->set_number("grid.Mbz", 2); 115 config->set_number("grid.Lbz", 1000); 116 P.Lx = 1000e3; 117 P.Ly = P.Lx; 118 Lz = 4000; 119 P.periodicity = XY_PERIODIC; 120 spacing = QUADRATIC; 121 break; 122 case 'V': 123 P.My = 3; // it's a flow-line setup 124 P.Lx = 500e3; // 500 km long 125 P.periodicity = Y_PERIODIC; 126 break; 127 default: 128 throw RuntimeError(PISM_ERROR_LOCATION, "desired test not implemented\n"); 129 } 130 131 P.z = IceGrid::compute_vertical_levels(Lz, Mz, spacing, 132 config->get_number("grid.lambda")); 133 return P; 134 } 135 136 IceGrid::Ptr pismv_grid(Context::Ptr ctx, char testname) { 137 auto config = ctx->config(); 138 139 auto input_file = config->get_string("input.file"); 140 141 if (config->get_flag("input.bootstrap")) { 142 throw RuntimeError(PISM_ERROR_LOCATION, "pisms does not support bootstrapping"); 143 } 144 145 if (not input_file.empty()) { 146 GridRegistration r = string_to_registration(ctx->config()->get_string("grid.registration")); 147 148 // get grid from a PISM input file 149 return IceGrid::FromFile(ctx, input_file, {"enthalpy", "temp"}, r); 150 } else { 151 // use defaults set by pismv_grid_defaults() 152 GridParameters P = pismv_grid_defaults(ctx->config(), testname); 153 P.horizontal_size_from_options(); 154 P.horizontal_extent_from_options(); 155 P.vertical_grid_from_options(ctx->config()); 156 P.ownership_ranges_from_options(ctx->size()); 157 158 return IceGrid::Ptr(new IceGrid(ctx, P)); 159 } 160 } 161 162 int main(int argc, char *argv[]) { 163 MPI_Comm com = MPI_COMM_WORLD; 164 165 petsc::Initializer petsc(argc, argv, help); 166 com = PETSC_COMM_WORLD; 167 168 /* This explicit scoping forces destructors to be called before PetscFinalize() */ 169 try { 170 Context::Ptr ctx = pismv_context(com, "pismv"); 171 Logger::Ptr log = ctx->log(); 172 173 std::string usage = 174 " pismv -test x [-no_report] [OTHER PISM & PETSc OPTIONS]\n" 175 "where:\n" 176 " -test x SIA-type verification test (x = A|B|C|D|F|G|H|K|L)\n" 177 " -no_report do not give error report at end of run\n" 178 "(see User's Manual for tests I and J).\n"; 179 180 std::vector<std::string> required(1, "-test"); 181 182 bool done = show_usage_check_req_opts(*log, "PISMV (verification mode)", required, usage); 183 if (done) { 184 return 0; 185 } 186 187 Config::Ptr config = ctx->config(); 188 189 // determine test (and whether to report error) 190 std::string testname = options::Keyword("-test", "Specifies PISM verification test", 191 "A,B,C,D,F,G,H,K,L,V", "A"); 192 193 IceGrid::Ptr g = pismv_grid(ctx, testname[0]); 194 195 IceCompModel m(g, ctx, testname[0]); 196 197 m.init(); 198 199 m.run(); 200 log->message(2, "done with run\n"); 201 202 m.reportErrors(); 203 204 // provide a default output file name if no -o option is given. 205 m.save_results(); 206 207 print_unused_parameters(*log, 3, *config); 208 } 209 catch (...) { 210 handle_fatal_errors(com); 211 return 1; 212 } 213 214 return 0; 215 } 216