|
PISM, A Parallel Ice Sheet Model stable 0.4.1779
|
00001 // Copyright (C) 2004--2011 Jed Brown, Ed Bueler and Constantine Khroulev 00002 // 00003 // This file is part of PISM. 00004 // 00005 // PISM is free software; you can redistribute it and/or modify it under the 00006 // terms of the GNU General Public License as published by the Free Software 00007 // Foundation; either version 2 of the License, or (at your option) any later 00008 // version. 00009 // 00010 // PISM is distributed in the hope that it will be useful, but WITHOUT ANY 00011 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00012 // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 00013 // details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with PISM; if not, write to the Free Software 00017 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00018 00019 #include <cstring> 00020 #include <cmath> 00021 #include <sstream> 00022 #include <set> 00023 #include "iceModel.hh" 00024 00026 00041 PetscErrorCode IceModel::setFromOptions() { 00042 PetscErrorCode ierr; 00043 00044 bool flag, myssaSystemToASCIIMatlab, realageSet; 00045 00046 ierr = verbPrintf(3, grid.com, 00047 "Processing physics-related command-line options...\n"); CHKERRQ(ierr); 00048 00049 ierr = PetscOptionsBegin(grid.com, "", "Options overriding config flags and parameters", ""); CHKERRQ(ierr); 00050 00051 /* 00052 note on pass-by-reference for options: 00053 For the last argument "flag" to PetscOptionsXXXX(....,&flag), the flag always indicates 00054 whether the option has been set. Therefore "flag" is altered by this function call. 00055 For other arguments "value" to PetscOptionsXXXX(....,&value,&flag), the value of "value" 00056 is only set if the user specified the option. Therefore "flag" should always be given a 00057 local PetscTruth variable if we want to preserve previously set IceModel flags. By 00058 contrast, for various parameters "value" we can use the IceModel parameter itself 00059 without fear of overwriting defaults unless, of course, the user wants them overwritten. 00060 It is also o.k. to have a local variable for "value", and then proceed to set the IceModel 00061 member accordingly. 00062 */ 00063 00064 ierr = config.scalar_from_option("adapt_ratio", 00065 "adaptive_timestepping_ratio"); CHKERRQ(ierr); 00066 00067 ierr = config.flag_from_option("age", "do_age"); CHKERRQ(ierr); 00068 00069 ierr = config.flag_from_option("sia", "do_sia"); CHKERRQ(ierr); 00070 00071 ierr = config.scalar_from_option("bed_smoother_range", "bed_smoother_range"); CHKERRQ(ierr); 00072 00073 // see getBasalWaterPressure() 00074 ierr = config.flag_from_option("bmr_enhance", "bmr_enhance_basal_water_pressure"); 00075 CHKERRQ(ierr); 00076 // in units m a-1 : 00077 ierr = config.scalar_from_option("bmr_enhance_scale", "bmr_enhance_scale"); CHKERRQ(ierr); 00078 00079 ierr = config.flag_from_option("bmr_in_cont", "include_bmr_in_continuity"); CHKERRQ(ierr); 00080 00081 ierr = config.scalar_from_option("calving_at_thickness", "calving_at_thickness"); CHKERRQ(ierr); 00082 ierr = PISMOptionsIsSet("-calving_at_thickness", flag); CHKERRQ(ierr); 00083 if (flag) config.set_flag("do_thickness_calving", true); 00084 00085 ierr = config.flag_from_option("cfbc", "calving_front_stress_boundary_condition"); CHKERRQ(ierr); 00086 00087 // if set, use old IceModel::temperatureStep(), and set enthalpy as though 00088 // ice is cold 00089 ierr = config.flag_from_option("cold", "do_cold_ice_methods"); CHKERRQ(ierr); 00090 00091 ierr = config.flag_from_option("count_steps", "count_time_steps"); CHKERRQ(ierr); 00092 00093 ierr = config.scalar_from_option("e", "enhancement_factor"); CHKERRQ(ierr); 00094 00095 ierr = config.scalar_from_option("e_ssa", "ssa_enhancement_factor"); CHKERRQ(ierr); 00096 ierr = PISMOptionsIsSet("-e_ssa", flag); CHKERRQ(ierr); 00097 if (flag) config.set_flag("do_ssa_enhancement", true); 00098 00099 ierr = config.scalar_from_option("eigen_calving", "eigen_calving"); CHKERRQ(ierr); 00100 ierr = PISMOptionsIsSet("-eigen_calving", flag); CHKERRQ(ierr); 00101 if (flag) config.set_flag("do_eigen_calving", true); 00102 00103 ierr = config.flag_from_option("dirichlet_bc", "dirichlet_bc"); CHKERRQ(ierr); 00104 00105 00106 bool gradient_set; 00107 string keyword; 00108 set<string> choices; 00109 choices.insert("eta"); 00110 choices.insert("haseloff"); 00111 choices.insert("mahaffy"); 00112 ierr = PISMOptionsList(grid.com, "-gradient", "Surface gradient computation method.", 00113 choices, "haseloff", keyword, gradient_set); CHKERRQ(ierr); 00114 if (gradient_set) config.set_string("surface_gradient_method", keyword); 00115 00116 // related old options 00117 ierr = check_old_option_and_stop(grid.com, "-eta", "-gradient"); CHKERRQ(ierr); 00118 ierr = check_old_option_and_stop(grid.com, "-no_eta", "-gradient"); CHKERRQ(ierr); 00119 00120 ierr = config.flag_from_option("f3d", "force_full_diagnostics"); CHKERRQ(ierr); 00121 00122 // whether or not to kill ice (zero thickness) if it is (or becomes) floating 00123 ierr = config.flag_from_option("float_kill", "floating_ice_killed"); CHKERRQ(ierr); 00124 00125 // note "-gk" is used for specifying Goldsby-Kohlstedt ice 00126 // this form allows a constant value of grain size to be input in mm 00127 ierr = config.scalar_from_option("gk", "constant_grain_size"); CHKERRQ(ierr); 00128 00129 ierr = PISMOptionsIsSet("-gk", flag); CHKERRQ(ierr); 00130 if (flag) { 00131 ierr = iceFactory.setType(ICE_HYBRID);CHKERRQ(ierr); 00132 } 00133 00134 // note "-gk_age" is also used for specifying Goldsby-Kohlstedt ice; 00135 ierr = PISMOptionsIsSet("-gk_age", flag); CHKERRQ(ierr); 00136 if (flag) { 00137 config.set_flag("compute_grain_size_using_age", true); 00138 ierr = iceFactory.setType(ICE_HYBRID);CHKERRQ(ierr); 00139 } 00140 00141 ierr = PISMOptionsInt("-id", "Specifies the sounding row", id, flag); CHKERRQ(ierr); 00142 00143 bool initfromT, initfromTandOm; 00144 ierr = PISMOptionsIsSet("-init_from_temp", initfromT); CHKERRQ(ierr); 00145 ierr = PISMOptionsIsSet("-init_from_temp_and_liqfrac", initfromTandOm); CHKERRQ(ierr); 00146 00147 ierr = PISMOptionsInt("-jd", "Specifies the sounding column", jd, flag); CHKERRQ(ierr); 00148 00149 ierr = config.flag_from_option("kill_icebergs", "kill_icebergs"); CHKERRQ(ierr); 00150 00151 ierr = config.scalar_from_option("low_temp", "global_min_allowed_temp"); CHKERRQ(ierr); 00152 ierr = config.scalar_from_option("max_low_temps", "max_low_temp_count"); CHKERRQ(ierr); 00153 00154 ierr = config.scalar_from_option("max_dt", "maximum_time_step_years"); CHKERRQ(ierr); 00155 00156 if (config.get("maximum_time_step_years") <= 0) { 00157 PetscPrintf(grid.com, "PISM ERROR: maximum_time_step_years has to be greater than 0.\n"); 00158 PISMEnd(); 00159 } 00160 00161 ierr = config.scalar_from_option("mu_sliding", "mu_sliding"); CHKERRQ(ierr); 00162 00163 ierr = config.flag_from_option("mass", "do_mass_conserve"); CHKERRQ(ierr); 00164 00165 // implements an option e.g. described in \ref Greve that is the 00166 // enhancement factor is coupled to the age of the ice with 00167 // e = 1 (A < 11'000 years), e = 3 otherwise 00168 ierr = PISMOptionsIsSet("-e_age_coupling", flag); CHKERRQ(ierr); 00169 if (flag) { 00170 config.set_flag("do_age", true); 00171 config.set_flag("do_e_age_coupling", true); 00172 ierr = verbPrintf(2, grid.com, 00173 " setting age-dependent enhancement factor: " 00174 "e=1 if A<11'000 years, e=3 otherwise\n"); CHKERRQ(ierr); 00175 00176 } else { 00177 config.set_flag("do_e_age_coupling", false); 00178 } 00179 00180 // note "-o" is in use for output file name; see iMIO.cc 00181 00182 // whether or not to kill ice at locations where mask=FLOATING_OCEAN0; 00183 // also determines if mask=FLOATING_OCEAN0 or mask=FLOATING 00184 // at bootstrapping (-boot_file), if original condition was ice-free ocean 00185 ierr = config.flag_from_option("ocean_kill", "ocean_kill"); CHKERRQ(ierr); 00186 00187 ierr = config.flag_from_option("part_grid", "part_grid"); CHKERRQ(ierr); 00188 00189 ierr = config.flag_from_option("part_redist", "part_redist"); CHKERRQ(ierr); 00190 00191 // option "-pik" turns on a suite of PISMPIK effects (but not -eigen_calving) 00192 ierr = PISMOptionsIsSet("-pik", "enable suite of PISM-PIK mechanisms", flag); CHKERRQ(ierr); 00193 if (flag) { 00194 config.set_flag("calving_front_stress_boundary_condition", true); 00195 config.set_flag("part_grid", true); 00196 config.set_flag("part_redist", true); 00197 config.set_flag("kill_icebergs", true); 00198 } 00199 00200 // plastic_till_c_0 is a parameter in the computation of the till yield stress tau_c 00201 // from the thickness of the basal melt water; see updateYieldStressFromHmelt() 00202 // Note: option is given in kPa. 00203 ierr = config.scalar_from_option("plastic_c0", "till_c_0"); CHKERRQ(ierr); 00204 00205 // till_pw_fraction is a parameter in the computation of the till yield stress tau_c 00206 // from the thickness of the basal melt water; see updateYieldStressFromHmelt() 00207 // option a pure number (a fraction); no conversion 00208 ierr = config.scalar_from_option("plastic_pwfrac", "till_pw_fraction"); CHKERRQ(ierr); 00209 00210 // controls regularization of plastic basal sliding law 00211 ierr = config.scalar_from_option("plastic_reg", "plastic_regularization"); CHKERRQ(ierr); 00212 00213 // "friction angle" in degrees 00214 ierr = config.scalar_from_option("plastic_phi", "default_till_phi"); CHKERRQ(ierr); 00215 00216 // use pseudo plastic instead of pure plastic; see iMbasal.cc 00217 ierr = config.flag_from_option("pseudo_plastic", "do_pseudo_plastic_till"); CHKERRQ(ierr); 00218 00219 // power in denominator on pseudo_plastic_uthreshold; typical is q=0.25; q=0 is pure plastic 00220 ierr = config.scalar_from_option("pseudo_plastic_q", "pseudo_plastic_q"); CHKERRQ(ierr); 00221 ierr = PISMOptionsIsSet("-pseudo_plastic_q", flag); CHKERRQ(ierr); 00222 if (flag) config.set_flag("do_pseudo_plastic_till", true); 00223 00224 // threshold; at this velocity tau_c is basal shear stress 00225 ierr = config.scalar_from_option("pseudo_plastic_uthreshold", "pseudo_plastic_uthreshold"); CHKERRQ(ierr); 00226 ierr = PISMOptionsIsSet("-pseudo_plastic_uthreshold", flag); CHKERRQ(ierr); 00227 if (flag) config.set_flag("do_pseudo_plastic_till", true); 00228 00229 // see updateGrainSizeNow(); option to choose modeled age vtau instead of pseudo age in 00230 // computing grainsize through Vostok core correlation 00231 ierr = PISMOptionsIsSet("-real_age_grainsize", realageSet); CHKERRQ(ierr); 00232 //if (realageSet == PETSC_TRUE) realAgeForGrainSize = PETSC_TRUE; 00233 if (realageSet == PETSC_TRUE) { 00234 ierr = PetscPrintf(grid.com, 00235 "PISM ERROR: -real_age_grainsize (sets realAgeForGrainSize) not implemented\n"); 00236 CHKERRQ(ierr); 00237 PISMEnd(); 00238 } 00239 00240 // check -ssa_floating_only 00241 ierr = PISMOptionsIsSet("-ssa_floating_only", flag); CHKERRQ(ierr); 00242 if (flag) { 00243 config.set_flag("use_ssa_velocity", true); 00244 config.set_flag("use_ssa_when_grounded", false); 00245 } 00246 00247 // Decide on the algorithm for solving the SSA 00248 set<string> ssa_choices; 00249 ssa_choices.insert("fem"); 00250 ssa_choices.insert("fd"); 00251 ssa_choices.insert("fd_pik"); 00252 string ssa_method; 00253 bool ssa_method_set; 00254 ierr = PISMOptionsList(grid.com, "-ssa_method", "Algorithm for computing the SSA solution", 00255 ssa_choices, ssa_method, ssa_method, ssa_method_set); CHKERRQ(ierr); 00256 if (ssa_method_set) { 00257 config.set_string("ssa_method",ssa_method); 00258 } 00259 00260 // check -ssa_sliding 00261 ierr = PISMOptionsIsSet("-ssa_sliding", flag); CHKERRQ(ierr); 00262 if (flag) { 00263 config.set_flag("use_ssa_velocity", true); 00264 config.set_flag("use_ssa_when_grounded", true); 00265 } 00266 00267 ierr = check_old_option_and_stop(grid.com, "-ssa", 00268 "-ssa_sliding' or '-ssa_floating_only"); CHKERRQ(ierr); 00269 ierr = check_old_option_and_stop(grid.com, "-plastic", "-ssa_sliding"); CHKERRQ(ierr); 00270 00271 ierr = config.scalar_from_option("ssa_eps", "epsilon_ssafd"); CHKERRQ(ierr); 00272 ierr = config.scalar_from_option("ssa_maxi", "max_iterations_ssafd"); CHKERRQ(ierr); 00273 ierr = config.scalar_from_option("ssa_rtol", "ssafd_relative_convergence"); CHKERRQ(ierr); 00274 00275 // option to save linear system in Matlab-readable ASCII format at end of each 00276 // numerical solution of SSA equations; can be given with or without filename prefix 00277 // (i.e. "-ssa_matlab " or "-ssa_matlab foo" are both legal; in former case get 00278 // "pism_SSA_[year].m" if "pism_SSA" is default prefix, and in latter case get "foo_[year].m") 00279 string tempPrefix; 00280 ierr = PISMOptionsString("-ssa_matlab", "Save linear system in Matlab-readable ASCII format", 00281 tempPrefix, myssaSystemToASCIIMatlab); CHKERRQ(ierr); 00282 if (myssaSystemToASCIIMatlab == PETSC_TRUE) 00283 config.set_flag("write_ssa_system_to_matlab", true); 00284 00285 /* This allows more than one mass continuity step per temperature/age and SSA 00286 computation */ 00287 ierr = config.scalar_from_option("skip", "skip_max"); CHKERRQ(ierr); 00288 ierr = config.flag_from_option("skip", "do_skip"); CHKERRQ(ierr); 00289 00290 ierr = config.scalar_from_option("summary_volarea_scale_factor_log10", 00291 "summary_volarea_scale_factor_log10"); CHKERRQ(ierr); 00292 00293 ierr = config.flag_from_option("energy", "do_energy"); CHKERRQ(ierr); 00294 00295 // if set, makes the thickness affect the pore_pressure; near margin there 00296 // is a reduction in basal water pressure, a conceptual drainage mechanism 00297 ierr = config.flag_from_option("thk_eff", "thk_eff_basal_water_pressure"); CHKERRQ(ierr); 00298 // next two in m : 00299 ierr = config.scalar_from_option("thk_eff_H_high","thk_eff_H_high"); CHKERRQ(ierr); 00300 ierr = config.scalar_from_option("thk_eff_H_low","thk_eff_H_low"); CHKERRQ(ierr); 00301 // pure number : 00302 ierr = config.scalar_from_option("thk_eff_reduced","thk_eff_reduced"); CHKERRQ(ierr); 00303 00304 ierr = config.string_from_option("title", "run_title"); CHKERRQ(ierr); 00305 ierr = config.string_from_option("institution", "institution"); CHKERRQ(ierr); 00306 00307 ierr = PetscOptionsEnd(); CHKERRQ(ierr); 00308 00309 global_attributes.set_string("title", config.get_string("run_title")); 00310 global_attributes.set_string("institution", config.get_string("institution")); 00311 global_attributes.set_string("command", pism_args_string()); 00312 00313 if (!config.get_flag("do_mass_conserve") && config.get_flag("do_skip")) { 00314 ierr = verbPrintf(2, grid.com, 00315 "PISM WARNING: Both -skip and -no_mass are set.\n" 00316 " -skip only makes sense in runs updating ice geometry.\n"); CHKERRQ(ierr); 00317 00318 } 00319 00320 return 0; 00321 } 00322 00324 PetscErrorCode IceModel::set_output_size(string option, 00325 string description, 00326 string default_value, 00327 set<string> &result) { 00328 PetscErrorCode ierr; 00329 set<string> choices; 00330 string keyword; 00331 bool flag; 00332 00333 choices.insert("small"); 00334 choices.insert("medium"); 00335 choices.insert("big"); 00336 00337 ierr = PISMOptionsList(grid.com, option, 00338 description, choices, 00339 default_value, keyword, flag); CHKERRQ(ierr); 00340 00341 result.clear(); 00342 00343 // Add all the model-state variables: 00344 set<string> vars = variables.keys(); 00345 00346 set<string>::iterator i = vars.begin(); 00347 while (i != vars.end()) { 00348 IceModelVec *var = variables.get(*i); 00349 00350 string intent = var->string_attr("pism_intent"); 00351 if ((intent == "model_state") || (intent == "mapping") || (intent == "climate_steady")) { 00352 result.insert(*i); 00353 } 00354 i++; 00355 } 00356 00357 if (config.get_flag("do_age")) 00358 result.insert("age"); 00359 00360 if (config.get_flag("ocean_kill")) 00361 result.insert("ocean_kill_mask"); 00362 00363 if (config.get_flag("force_full_diagnostics")) 00364 keyword = "big"; 00365 00366 if (beddef != NULL) 00367 beddef->add_vars_to_output(keyword, result); 00368 00369 if (btu != NULL) 00370 btu->add_vars_to_output(keyword, result); 00371 00372 if (basal_yield_stress != NULL) 00373 basal_yield_stress->add_vars_to_output(keyword, result); 00374 00375 // Ask the stress balance module to add more variables: 00376 if (stress_balance != NULL) 00377 stress_balance->add_vars_to_output(keyword, result); 00378 00379 // Ask ocean and surface models to add more variables to the list: 00380 if (ocean != NULL) 00381 ocean->add_vars_to_output(keyword, result); 00382 00383 if (surface != NULL) 00384 surface->add_vars_to_output(keyword, result); 00385 00386 if (keyword == "small") { 00387 // only model-state variables are saved; we're done 00388 return 0; 00389 00390 } else if (keyword == "medium") { 00391 // add all the variables listed in the config file ("medium" size): 00392 string tmp = config.get_string("output_medium"); 00393 istringstream list(tmp); 00394 00395 // split the list; note that this also removes any duplicate entries 00396 while (getline(list, tmp, ' ')) { 00397 if (!tmp.empty()) // this ignores multiple spaces separating variable names 00398 result.insert(tmp); 00399 } 00400 return 0; 00401 00402 } else if (keyword == "big") { 00403 // add all the variables listed in the config file ("big" size): 00404 string tmp = config.get_string("output_big"); 00405 istringstream list(tmp); 00406 00407 // split the list; note that this also removes any duplicate entries 00408 while (getline(list, tmp, ' ')) { 00409 if (!tmp.empty()) // this ignores multiple spaces separating variable names 00410 result.insert(tmp); 00411 } 00412 00413 if (!config.get_flag("do_age")) 00414 result.erase("age"); 00415 00416 return 0; 00417 } else { 00418 SETERRQ(1, "can't happen"); 00419 } 00420 00421 return 0; 00422 } 00423
1.7.3