PISM, A Parallel Ice Sheet Model stable 0.4.1779

src/base/iMbootstrap.cc

Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines