|
PISM, A Parallel Ice Sheet Model stable 0.4.1779
|
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
1.7.3