PISM, A Parallel Ice Sheet Model stable 0.4.1779

src/base/stressbalance/SSATestCase.cc

Go to the documentation of this file.
00001 // Copyright (C) 2009--2011 Ed Bueler, Constantine Khroulev, and David Maxwell
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 "SSATestCase.hh"
00020 #include "PISMIO.hh"
00021 
00022 #include "SSAFD.hh"
00023 #include "SSAFEM.hh"
00024 
00025 
00028 PetscErrorCode SSATestCase::buildSSACoefficients()
00029 {
00030   PetscErrorCode ierr;
00031 
00032   const PetscInt WIDE_STENCIL = 2;
00033   
00034   // ice surface elevation
00035   ierr = surface.create(grid, "usurf", true, WIDE_STENCIL); CHKERRQ(ierr);
00036   ierr = surface.set_attrs("diagnostic", "ice upper surface elevation", "m", 
00037                                       "surface_altitude"); CHKERRQ(ierr);
00038   ierr = vars.add(surface); CHKERRQ(ierr);
00039   
00040   // land ice thickness
00041   ierr = thickness.create(grid, "thk", true, WIDE_STENCIL); CHKERRQ(ierr);
00042   ierr = thickness.set_attrs("model_state", "land ice thickness", "m", 
00043                                   "land_ice_thickness"); CHKERRQ(ierr);
00044   ierr = thickness.set_attr("valid_min", 0.0); CHKERRQ(ierr);
00045   ierr = vars.add(thickness); CHKERRQ(ierr);
00046 
00047   // bedrock surface elevation
00048   ierr = bed.create(grid, "topg", true, WIDE_STENCIL); CHKERRQ(ierr);
00049   ierr = bed.set_attrs("model_state", "bedrock surface elevation", "m", 
00050                                           "bedrock_altitude"); CHKERRQ(ierr);
00051   ierr = vars.add(bed); CHKERRQ(ierr);
00052 
00053   // yield stress for basal till (plastic or pseudo-plastic model)
00054   ierr = tauc.create(grid, "tauc", true, WIDE_STENCIL); CHKERRQ(ierr);
00055   ierr = tauc.set_attrs("diagnostic",  
00056   "yield stress for basal till (plastic or pseudo-plastic model)", "Pa", "");
00057       CHKERRQ(ierr);
00058   ierr = vars.add(tauc); CHKERRQ(ierr);
00059 
00060   // enthalpy
00061   ierr = enthalpy.create(grid, "enthalpy", true, WIDE_STENCIL); CHKERRQ(ierr);
00062   ierr = enthalpy.set_attrs("model_state",
00063               "ice enthalpy (includes sensible heat, latent heat, pressure)",
00064               "J kg-1", ""); CHKERRQ(ierr);
00065   ierr = vars.add(enthalpy); CHKERRQ(ierr);
00066 
00067 
00068   // dirichlet boundary condition (FIXME: perhaps unused!)
00069   ierr = vel_bc.create(grid, "_bc", true,WIDE_STENCIL); CHKERRQ(ierr); // u_bc and v_bc
00070   ierr = vel_bc.set_attrs("intent", 
00071             "X-component of the SSA velocity boundary conditions", 
00072             "m s-1", "", 0); CHKERRQ(ierr);
00073   ierr = vel_bc.set_attrs("intent", 
00074             "Y-component of the SSA velocity boundary conditions", 
00075             "m s-1", "", 1); CHKERRQ(ierr);
00076   ierr = vel_bc.set_glaciological_units("m year-1"); CHKERRQ(ierr);
00077   ierr = vel_bc.set_attr("valid_min", convert(-1e6, "m/year", "m/second"), 0); CHKERRQ(ierr);
00078   ierr = vel_bc.set_attr("valid_max", convert( 1e6, "m/year", "m/second"), 0); CHKERRQ(ierr);
00079   ierr = vel_bc.set_attr("valid_min", convert(-1e6, "m/year", "m/second"), 1); CHKERRQ(ierr);
00080   ierr = vel_bc.set_attr("valid_max", convert( 1e6, "m/year", "m/second"), 1); CHKERRQ(ierr);
00081   ierr = vel_bc.set_attr("_FillValue",convert( 2e6, "m/year", "m/second"), 0); CHKERRQ(ierr);
00082   ierr = vel_bc.set_attr("_FillValue",convert( 2e6, "m/year", "m/second"), 1); CHKERRQ(ierr);
00083   vel_bc.write_in_glaciological_units = true;
00084   ierr = vel_bc.set(convert(2e6, "m/year", "m/second")); CHKERRQ(ierr);
00085   
00086   // grounded_dragging_floating integer mask
00087   ierr = ice_mask.create(grid, "mask", true, WIDE_STENCIL); CHKERRQ(ierr);
00088   ierr = ice_mask.set_attrs("model_state", 
00089           "grounded_dragging_floating integer mask", "", ""); CHKERRQ(ierr);
00090   vector<double> mask_values(4);
00091   mask_values[0] = MASK_ICE_FREE_BEDROCK;
00092   mask_values[1] = MASK_GROUNDED;
00093   mask_values[2] = MASK_FLOATING;
00094   mask_values[3] = MASK_ICE_FREE_OCEAN;
00095   ierr = ice_mask.set_attr("flag_values", mask_values); CHKERRQ(ierr);
00096   ierr = ice_mask.set_attr("flag_meanings",
00097                            "ice_free_bedrock grounded_ice floating_ice ice_free_ocean");
00098   CHKERRQ(ierr);
00099   ice_mask.output_data_type = NC_BYTE;
00100   ierr = vars.add(ice_mask); CHKERRQ(ierr);
00101 
00102   ierr = ice_mask.set(MASK_GROUNDED); CHKERRQ(ierr);
00103 
00104   // Dirichlet B.C. mask
00105   ierr = bc_mask.create(grid, "bc_mask", true, WIDE_STENCIL); CHKERRQ(ierr);
00106   ierr = bc_mask.set_attrs("model_state", 
00107           "grounded_dragging_floating integer mask", "", ""); CHKERRQ(ierr);
00108   mask_values.resize(2);
00109   mask_values[0] = 0;
00110   mask_values[1] = 1;
00111   ierr = bc_mask.set_attr("flag_values", mask_values); CHKERRQ(ierr);
00112   ierr = bc_mask.set_attr("flag_meanings",
00113                           "no_data dirichlet_bc_location"); CHKERRQ(ierr);
00114   bc_mask.output_data_type = NC_BYTE;
00115   ierr = vars.add(bc_mask); CHKERRQ(ierr);
00116   
00117   return 0;
00118 }
00119 
00120 
00122 PetscErrorCode SSATestCase::init(PetscInt Mx, PetscInt My, SSAFactory ssafactory)
00123 {
00124   PetscErrorCode ierr;
00125 
00126   // Set options from command line.  
00127   // FIXME (DAM 2/17/11):  These are currently only looked at by the finite difference solver.
00128   ierr = config.scalar_from_option("ssa_eps",  "epsilon_ssafd"); CHKERRQ(ierr);
00129   ierr = config.scalar_from_option("ssa_maxi", "max_iterations_ssafd"); CHKERRQ(ierr);
00130   ierr = config.scalar_from_option("ssa_rtol", "ssafd_relative_convergence"); CHKERRQ(ierr);
00131   
00132   // Subclass builds grid.
00133   ierr = initializeGrid(Mx,My);
00134   
00135   // Subclass builds ice flow law, basal resistance, etc.
00136   ierr = initializeSSAModel(); CHKERRQ(ierr);
00137 
00138   // We setup storage for the coefficients.
00139   ierr = buildSSACoefficients(); CHKERRQ(ierr);
00140 
00141   // Allocate the actual SSA solver.
00142   ssa = ssafactory(grid, *basal, *ice, *enthalpyconverter, config);
00143   ierr = ssa->init(vars); CHKERRQ(ierr); // vars was setup preivouisly with buildSSACoefficients
00144 
00145   // Allow the subclass to setup the coefficients.
00146   ierr = initializeSSACoefficients(); CHKERRQ(ierr);
00147 
00148   return 0;
00149 }
00150 
00152 PetscErrorCode SSATestCase::run()
00153 {
00154   PetscErrorCode ierr;
00155   // Solve (fast==true means "no update"):
00156   ierr = verbPrintf(2,grid.com,"* Solving the SSA stress balance ...\n"); CHKERRQ(ierr);
00157 
00158   bool fast = false;
00159   ierr = ssa->update(fast); CHKERRQ(ierr);
00160 
00161   return 0;
00162 }
00163 
00165 PetscErrorCode SSATestCase::report()
00166 {
00167   PetscErrorCode  ierr;
00168     
00169   string ssa_stdout;
00170   ierr = ssa->stdout_report(ssa_stdout); CHKERRQ(ierr);
00171   ierr = verbPrintf(3,grid.com,ssa_stdout.c_str()); CHKERRQ(ierr);
00172   
00173   PetscScalar maxvecerr = 0.0, avvecerr = 0.0, 
00174     avuerr = 0.0, avverr = 0.0, maxuerr = 0.0, maxverr = 0.0;
00175   PetscScalar gmaxvecerr = 0.0, gavvecerr = 0.0, gavuerr = 0.0, gavverr = 0.0,
00176     gmaxuerr = 0.0, gmaxverr = 0.0;
00177 
00178   if (config.get_flag("do_pseudo_plastic_till")) {
00179     ierr = verbPrintf(1,grid.com, 
00180                     "WARNING: numerical errors not valid for pseudo-plastic till\n"); CHKERRQ(ierr);
00181   }
00182   ierr = verbPrintf(1,grid.com, 
00183                     "NUMERICAL ERRORS in velocity relative to exact solution:\n"); CHKERRQ(ierr);
00184 
00185 
00186   IceModelVec2V *vel_ssa;
00187   ierr = ssa->get_advective_2d_velocity(vel_ssa); CHKERRQ(ierr);
00188   ierr = vel_ssa->begin_access(); CHKERRQ(ierr);
00189 
00190   PetscScalar exactvelmax = 0, gexactvelmax = 0;
00191   for (PetscInt i=grid.xs; i<grid.xs+grid.xm; i++) {
00192     for (PetscInt j=grid.ys; j<grid.ys+grid.ym; j++) {
00193       PetscScalar uexact, vexact;
00194       PetscScalar myx = grid.x[i], myy = grid.y[j];
00195 
00196       exactSolution(i,j,myx,myy,&uexact,&vexact);
00197 
00198       PetscScalar exactnormsq=sqrt(uexact*uexact+vexact*vexact);
00199       exactvelmax = PetscMax(exactnormsq,exactvelmax);
00200 
00201       // compute maximum errors
00202       const PetscScalar uerr = PetscAbsReal((*vel_ssa)(i,j).u - uexact);
00203       const PetscScalar verr = PetscAbsReal((*vel_ssa)(i,j).v - vexact);
00204       avuerr = avuerr + uerr;
00205       avverr = avverr + verr;
00206       maxuerr = PetscMax(maxuerr,uerr);
00207       maxverr = PetscMax(maxverr,verr);
00208       const PetscScalar vecerr = sqrt(uerr * uerr + verr * verr);
00209       maxvecerr = PetscMax(maxvecerr,vecerr);
00210       avvecerr = avvecerr + vecerr;
00211     }
00212   }
00213   ierr = vel_ssa->end_access(); CHKERRQ(ierr);
00214 
00215 
00216   ierr = PetscGlobalMax(&exactvelmax, &gexactvelmax,grid.com); CHKERRQ(ierr);
00217   ierr = PetscGlobalMax(&maxuerr, &gmaxuerr, grid.com); CHKERRQ(ierr);
00218   ierr = PetscGlobalMax(&maxverr, &gmaxverr, grid.com); CHKERRQ(ierr);
00219   ierr = PetscGlobalSum(&avuerr, &gavuerr, grid.com); CHKERRQ(ierr);
00220   gavuerr = gavuerr/(grid.Mx*grid.My);
00221   ierr = PetscGlobalSum(&avverr, &gavverr, grid.com); CHKERRQ(ierr);
00222   gavverr = gavverr/(grid.Mx*grid.My);
00223   ierr = PetscGlobalMax(&maxvecerr, &gmaxvecerr, grid.com); CHKERRQ(ierr);
00224   ierr = PetscGlobalSum(&avvecerr, &gavvecerr, grid.com); CHKERRQ(ierr);
00225   gavvecerr = gavvecerr/(grid.Mx*grid.My);
00226 
00227   ierr = verbPrintf(1,grid.com, 
00228                     "velocity  :  maxvector   prcntavvec      maxu      maxv       avu       avv\n");
00229   CHKERRQ(ierr);
00230   ierr = verbPrintf(1,grid.com, 
00231                     "           %11.4f%13.5f%10.4f%10.4f%10.4f%10.4f\n", 
00232                     gmaxvecerr*report_velocity_scale, (gavvecerr/gexactvelmax)*100.0,
00233                     gmaxuerr*report_velocity_scale, gmaxverr*report_velocity_scale, gavuerr*report_velocity_scale, 
00234                     gavverr*report_velocity_scale); CHKERRQ(ierr);
00235 
00236   ierr = verbPrintf(1,grid.com, "NUM ERRORS DONE\n");  CHKERRQ(ierr);
00237 
00238   return 0;
00239 }
00240 
00241 PetscErrorCode SSATestCase::exactSolution(PetscInt /*i*/, PetscInt /*j*/, 
00242                                           PetscReal /*x*/, PetscReal /*y*/,
00243                                           PetscReal *u, PetscReal *v )
00244 {
00245   *u=0; *v=0;
00246   return 0;
00247 }
00248 
00250 PetscErrorCode SSATestCase::write(const string &filename)
00251 {
00252   PetscErrorCode ierr;
00253 
00254   // Write results to an output file:
00255   PISMIO pio(&grid);
00256   ierr = pio.open_for_writing(filename, false, true); CHKERRQ(ierr);
00257   ierr = pio.append_time(0.0); CHKERRQ(ierr);
00258   ierr = pio.close(); CHKERRQ(ierr);
00259 
00260   ierr = surface.write(filename.c_str()); CHKERRQ(ierr);
00261   ierr = thickness.write(filename.c_str()); CHKERRQ(ierr);
00262   ierr = bc_mask.write(filename.c_str()); CHKERRQ(ierr);
00263   ierr = tauc.write(filename.c_str()); CHKERRQ(ierr);
00264   ierr = bed.write(filename.c_str()); CHKERRQ(ierr);
00265   ierr = enthalpy.write(filename.c_str()); CHKERRQ(ierr);
00266   ierr = vel_bc.write(filename.c_str()); CHKERRQ(ierr);
00267 
00268   IceModelVec2V *vel_ssa;
00269   ierr = ssa->get_advective_2d_velocity(vel_ssa); CHKERRQ(ierr);
00270   ierr = vel_ssa->write(filename.c_str()); CHKERRQ(ierr);
00271 
00272   IceModelVec2V exact;
00273   ierr = exact.create(grid, "_exact", false); CHKERRQ(ierr);
00274   ierr = exact.set_attrs("diagnostic", 
00275             "X-component of the SSA exact solution", 
00276             "m s-1", "", 0); CHKERRQ(ierr);
00277   ierr = exact.set_attrs("diagnostic", 
00278             "Y-component of the SSA exact solution", 
00279             "m s-1", "", 1); CHKERRQ(ierr);
00280   ierr = exact.set_glaciological_units("m year-1"); CHKERRQ(ierr);
00281 
00282   ierr = exact.begin_access(); CHKERRQ(ierr);
00283   for (PetscInt i=grid.xs; i<grid.xs+grid.xm; i++) {
00284     for (PetscInt j=grid.ys; j<grid.ys+grid.ym; j++) {
00285       PetscScalar myx = grid.x[i], myy = grid.y[j];
00286       exactSolution(i,j,myx,myy,&(exact(i,j).u),&(exact(i,j).v));
00287     }
00288   }
00289   ierr = exact.end_access(); CHKERRQ(ierr);
00290   ierr = exact.write(filename.c_str()); CHKERRQ(ierr);
00291 
00292   return 0;
00293 }
00294 
00295 
00298 PetscErrorCode init_shallow_grid(IceGrid &grid, PetscReal Lx, 
00299                                       PetscReal Ly, PetscInt Mx, PetscInt My, Periodicity p)
00300 {
00301   PetscErrorCode ierr;
00302   
00303   grid.Lx = Lx;
00304   grid.Ly = Ly;
00305   grid.periodicity = p;
00306   grid.start_year = grid.year = 0.0;
00307   grid.Mx = Mx; grid.My=My; grid.Mz = 3;
00308   
00309   grid.compute_nprocs();
00310   grid.compute_ownership_ranges();
00311   ierr = grid.compute_vertical_levels(); CHKERRQ(ierr);
00312   ierr = grid.compute_horizontal_spacing(); CHKERRQ(ierr);
00313   ierr = grid.createDA(); CHKERRQ(ierr);
00314 
00315   return 0;
00316 }
00317 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines