|
PISM, A Parallel Ice Sheet Model stable 0.4.1779
|
00001 // Copyright (C) 2004-2011 Jed Brown, Nathan Shemonski, Ed Bueler and 00002 // Constantine Khroulev 00003 // 00004 // This file is part of PISM. 00005 // 00006 // PISM is free software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the Free Software 00008 // Foundation; either version 2 of the License, or (at your option) any later 00009 // version. 00010 // 00011 // PISM is distributed in the hope that it will be useful, but WITHOUT ANY 00012 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00013 // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 00014 // details. 00015 // 00016 // You should have received a copy of the GNU General Public License 00017 // along with PISM; if not, write to the Free Software 00018 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00019 00020 #include "iceModel.hh" 00021 #include "PISMIO.hh" 00022 00024 00029 PetscErrorCode IceModel::bootstrapFromFile(const char *filename) { 00030 PetscErrorCode ierr; 00031 00032 // Bootstrap 2D fields: 00033 ierr = bootstrap_2d(filename); CHKERRQ(ierr); 00034 00035 // Regrid 2D fields: 00036 ierr = regrid(2); CHKERRQ(ierr); 00037 00038 // Check the consistency of geometry fields: 00039 ierr = updateSurfaceElevationAndMask(); CHKERRQ(ierr); 00040 00041 // Update couplers (because heuristics in bootstrap_3d() might need boundary 00042 // conditions provided by couplers): 00043 if (surface != NULL) { 00044 ierr = surface->update(grid.year, 0); CHKERRQ(ierr); 00045 } else SETERRQ(1, "surface == NULL"); 00046 if (ocean != NULL) { 00047 ierr = ocean->update(grid.year, 0); CHKERRQ(ierr); 00048 } else SETERRQ(1, "ocean == NULL"); 00049 00050 // Fill 3D fields using heuristics: 00051 ierr = bootstrap_3d(); CHKERRQ(ierr); 00052 00053 ierr = regrid(3); CHKERRQ(ierr); 00054 00055 ierr = verbPrintf(2, grid.com, "done reading %s; bootstrapping done\n",filename); CHKERRQ(ierr); 00056 00057 return 0; 00058 } 00059 00060 PetscErrorCode IceModel::bootstrap_2d(const char *filename) { 00061 PetscErrorCode ierr; 00062 00063 PISMIO nc(&grid); 00064 ierr = nc.open_for_reading(filename); CHKERRQ(ierr); 00065 00066 ierr = verbPrintf(2, grid.com, 00067 "bootstrapping by PISM default method from file %s\n",filename); CHKERRQ(ierr); 00068 00069 // report on resulting computational box, rescale grid, actually create a 00070 // local interpolation context 00071 ierr = verbPrintf(2, grid.com, 00072 " rescaling computational box for ice from -boot_file file and\n" 00073 " user options to dimensions:\n" 00074 " [-%6.2f km, %6.2f km] x [-%6.2f km, %6.2f km] x [0 m, %6.2f m]\n", 00075 grid.Lx/1000.0,grid.Lx/1000.0,grid.Ly/1000.0,grid.Ly/1000.0,grid.Lz); 00076 CHKERRQ(ierr); 00077 00078 bool hExists=false, maskExists=false; 00079 ierr = nc.find_variable("usurf", "surface_altitude", NULL, hExists); CHKERRQ(ierr); 00080 ierr = nc.find_variable("mask", NULL, maskExists); CHKERRQ(ierr); 00081 ierr = nc.close(); CHKERRQ(ierr); 00082 00083 // now work through all the 2d variables, regridding if present and otherwise 00084 // setting to default values appropriately 00085 00086 if (maskExists) { 00087 ierr = verbPrintf(2, grid.com, 00088 " WARNING: 'mask' found; IGNORING IT!\n"); CHKERRQ(ierr); 00089 } 00090 if (hExists) { 00091 ierr = verbPrintf(2, grid.com, 00092 " WARNING: surface elevation 'usurf' found; IGNORING IT!\n"); 00093 CHKERRQ(ierr); 00094 } 00095 00096 ierr = verbPrintf(2, grid.com, 00097 " reading 2D model state variables by regridding ...\n"); CHKERRQ(ierr); 00098 00099 ierr = vLongitude.regrid(filename, false); CHKERRQ(ierr); 00100 ierr = vLatitude.regrid(filename, false); CHKERRQ(ierr); 00101 ierr = vH.regrid(filename, 00102 config.get("bootstrapping_H_value_no_var")); CHKERRQ(ierr); 00103 ierr = vbed.regrid(filename, 00104 config.get("bootstrapping_bed_value_no_var")); CHKERRQ(ierr); 00105 ierr = vHmelt.regrid(filename, 00106 config.get("bootstrapping_Hmelt_value_no_var")); CHKERRQ(ierr); 00107 ierr = vbmr.regrid(filename, 00108 config.get("bootstrapping_bmelt_value_no_var")); CHKERRQ(ierr); 00109 ierr = vGhf.regrid(filename, 00110 config.get("bootstrapping_geothermal_flux_value_no_var")); 00111 CHKERRQ(ierr); 00112 ierr = vuplift.regrid(filename, 00113 config.get("bootstrapping_uplift_value_no_var")); CHKERRQ(ierr); 00114 00115 if (config.get_flag("part_grid")) { 00116 // if part_grid is "on", set fields tracking contents of partially-filled 00117 // cells to zero. Note that the contents of these fields are 00118 // grid-dependent, so we don't want to read them from a bootstrapping file 00119 // using linear interpolation. 00120 //ierr = vHav.set(0.0); CHKERRQ(ierr); 00121 ierr = vHref.set(0.0); CHKERRQ(ierr); 00122 if (config.get_flag("part_redist")) { ierr = vHresidual.set(0.0); CHKERRQ(ierr); } 00123 } 00124 00125 if (config.get_flag("kill_icebergs")) { 00126 // will be updated in updateSurfaceElevationAndMask() 00127 ierr = vIcebergMask.set(ICEBERGMASK_NOT_SET); CHKERRQ(ierr); 00128 } 00129 00130 if (config.get_flag("do_eigen_calving")) { 00131 // will be updated in updateSurfaceElevationAndMask() 00132 ierr = vPrinStrain1.set(0.0); CHKERRQ(ierr); 00133 ierr = vPrinStrain2.set(0.0); CHKERRQ(ierr); 00134 } 00135 00136 if (config.get_flag("dirichlet_bc")) { 00137 ierr = vBCMask.regrid(filename, 00138 config.get("bootstrapping_BCMask_value_no_var")); CHKERRQ(ierr); 00139 ierr = vBCvel.regrid(filename, 00140 config.get("bootstrapping_BCvel_value_no_var")); CHKERRQ(ierr); 00141 } 00142 00143 00144 00145 bool Lz_set; 00146 ierr = PISMOptionsIsSet("-Lz", Lz_set); CHKERRQ(ierr); 00147 if ( !Lz_set ) { 00148 PetscReal thk_min, thk_max; 00149 ierr = vH.range(thk_min, thk_max); CHKERRQ(ierr); 00150 00151 ierr = verbPrintf(2, grid.com, 00152 " Setting Lz to 1.5 * max(ice thickness) = %3.3f meters...\n", 00153 1.5 * thk_max); 00154 00155 00156 grid.Lz = 1.5 * thk_max; 00157 00158 ierr = grid.compute_vertical_levels(); 00159 00160 CHKERRQ(ierr); 00161 } 00162 00163 return 0; 00164 } 00165 00166 PetscErrorCode IceModel::bootstrap_3d() { 00167 PetscErrorCode ierr; 00168 00169 // set the initial age of the ice if appropriate 00170 if (config.get_flag("do_age")) { 00171 ierr = verbPrintf(2, grid.com, 00172 " setting initial age to %.4f years\n", config.get("initial_age_of_ice_years")); 00173 CHKERRQ(ierr); 00174 tau3.set(config.get("initial_age_of_ice_years") * secpera); 00175 } 00176 00177 ierr = verbPrintf(2, grid.com, 00178 " filling in ice and bedrock temperatures using surface temps and quartic guess\n"); 00179 CHKERRQ(ierr); 00180 ierr = putTempAtDepth(); CHKERRQ(ierr); 00181 00182 if (config.get_flag("do_cold_ice_methods") == false) { 00183 ierr = verbPrintf(2, grid.com, 00184 " ice enthalpy set from temperature, as cold ice (zero liquid fraction)\n"); 00185 CHKERRQ(ierr); 00186 } 00187 00188 return 0; 00189 } 00190 00192 00223 PetscErrorCode IceModel::putTempAtDepth() { 00224 PetscErrorCode ierr; 00225 00226 PetscScalar *T = new PetscScalar[grid.Mz]; 00227 const bool do_cold = config.get_flag("do_cold_ice_methods"); 00228 00229 if (surface != NULL) { 00230 ierr = surface->ice_surface_temperature(artm); CHKERRQ(ierr); 00231 } else { 00232 SETERRQ(1, "PISM ERROR: surface == NULL"); 00233 } 00234 00235 IceModelVec3 *result; 00236 if (do_cold) 00237 result = &T3; 00238 else 00239 result = &Enth3; 00240 00241 ierr = artm.begin_access(); CHKERRQ(ierr); 00242 ierr = vH.begin_access(); CHKERRQ(ierr); 00243 ierr = vbed.begin_access(); CHKERRQ(ierr); 00244 ierr = vGhf.begin_access(); CHKERRQ(ierr); 00245 00246 ierr = result->begin_access(); CHKERRQ(ierr); 00247 for (PetscInt i=grid.xs; i<grid.xs+grid.xm; ++i) { 00248 for (PetscInt j=grid.ys; j<grid.ys+grid.ym; ++j) { 00249 const PetscScalar HH = vH(i,j); 00250 const PetscInt ks = grid.kBelowHeight(HH); 00251 00252 // within ice 00253 const PetscScalar g = vGhf(i,j); 00254 const PetscScalar beta = (4.0/21.0) * (g / (2.0 * ice->k * HH * HH * HH)); 00255 const PetscScalar alpha = (g / (2.0 * HH * ice->k)) - 2.0 * HH * HH * beta; 00256 for (PetscInt k = 0; k < ks; k++) { 00257 const PetscScalar depth = HH - grid.zlevels[k]; 00258 const PetscScalar Tpmp = ice->melting_point_temp - ice->beta_CC_grad * depth; 00259 const PetscScalar d2 = depth * depth; 00260 00261 T[k] = PetscMin(Tpmp,artm(i,j) + alpha * d2 + beta * d2 * d2); 00262 00263 } 00264 for (PetscInt k = ks; k < grid.Mz; k++) // above ice 00265 T[k] = artm(i,j); 00266 00267 if (!do_cold) { 00268 for (PetscInt k = 0; k < grid.Mz; ++k) { 00269 const PetscScalar depth = HH - grid.zlevels[k]; 00270 const PetscScalar pressure = 00271 EC->getPressureFromDepth(depth); 00272 // reuse T to store enthalpy; assume that the ice is cold 00273 ierr = EC->getEnthPermissive(T[k], 0.0, pressure, T[k]); CHKERRQ(ierr); 00274 } 00275 } 00276 00277 ierr = result->setInternalColumn(i,j,T); CHKERRQ(ierr); 00278 00279 } 00280 } 00281 ierr = vH.end_access(); CHKERRQ(ierr); 00282 ierr = vbed.end_access(); CHKERRQ(ierr); 00283 ierr = vGhf.end_access(); CHKERRQ(ierr); 00284 ierr = result->end_access(); CHKERRQ(ierr); 00285 ierr = artm.end_access(); CHKERRQ(ierr); 00286 00287 delete [] T; 00288 00289 ierr = result->beginGhostComm(); CHKERRQ(ierr); 00290 ierr = result->endGhostComm(); CHKERRQ(ierr); 00291 00292 if (do_cold) { 00293 ierr = compute_enthalpy_cold(T3, Enth3); CHKERRQ(ierr); 00294 } 00295 00296 return 0; 00297 } 00298
1.7.3