|
PISM, A Parallel Ice Sheet Model stable 0.4.1779
|
00001 // Copyright (C) 2010, 2011 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 "PISMStressBalance_diagnostics.hh" 00020 #include "Mask.hh" 00021 00022 void PISMStressBalance::get_diagnostics(map<string, PISMDiagnostic*> &dict) { 00023 00024 dict["bfrict"] = new PSB_bfrict(this, grid, *variables); 00025 dict["bueler_brown_f"] = new PSB_bueler_brown_f(this, grid, *variables); 00026 00027 dict["cbar"] = new PSB_cbar(this, grid, *variables); 00028 dict["cflx"] = new PSB_cflx(this, grid, *variables); 00029 dict["cbase"] = new PSB_cbase(this, grid, *variables); 00030 dict["csurf"] = new PSB_csurf(this, grid, *variables); 00031 00032 dict["uvel"] = new PSB_uvel(this, grid, *variables); 00033 dict["vvel"] = new PSB_vvel(this, grid, *variables); 00034 00035 dict["velbar"] = new PSB_velbar(this, grid, *variables); 00036 dict["velbase"] = new PSB_velbase(this, grid, *variables); 00037 dict["velsurf"] = new PSB_velsurf(this, grid, *variables); 00038 00039 dict["wvel"] = new PSB_wvel(this, grid, *variables); 00040 dict["wvelbase"] = new PSB_wvelbase(this, grid, *variables); 00041 dict["wvelsurf"] = new PSB_wvelsurf(this, grid, *variables); 00042 dict["wvel_rel"] = new PSB_wvel_rel(this, grid, *variables); 00043 dict["taud_mag"] = new PSB_taud_mag(this, grid, *variables); 00044 00045 00046 stress_balance->get_diagnostics(dict); 00047 modifier->get_diagnostics(dict); 00048 } 00049 00050 PSB_velbar::PSB_velbar(PISMStressBalance *m, IceGrid &g, PISMVars &my_vars) 00051 : PISMDiag<PISMStressBalance>(m, g, my_vars) { 00052 00053 dof = 2; 00054 vars.resize(dof); 00055 00056 // set metadata: 00057 vars[0].init_2d("ubar", grid); 00058 vars[1].init_2d("vbar", grid); 00059 00060 set_attrs("vertical mean of horizontal ice velocity in the X direction", 00061 "land_ice_vertical_mean_x_velocity", 00062 "m s-1", "m year-1", 0); 00063 set_attrs("vertical mean of horizontal ice velocity in the Y direction", 00064 "land_ice_vertical_mean_y_velocity", 00065 "m s-1", "m year-1", 1); 00066 } 00067 00068 PetscErrorCode PSB_velbar::compute(IceModelVec* &output) { 00069 PetscErrorCode ierr; 00070 00071 IceModelVec3 *u3, *v3, *w3; 00072 IceModelVec2S *thickness; 00073 IceModelVec2V *result; 00074 PetscScalar *u_ij, *v_ij; 00075 00076 result = new IceModelVec2V; 00077 ierr = result->create(grid, "bar", false); CHKERRQ(ierr); 00078 ierr = result->set_metadata(vars[0], 0); CHKERRQ(ierr); 00079 ierr = result->set_metadata(vars[1], 1); CHKERRQ(ierr); 00080 00081 thickness = dynamic_cast<IceModelVec2S*>(variables.get("land_ice_thickness")); 00082 if (thickness == NULL) SETERRQ(1, "land_ice_thickness is not available"); 00083 00084 ierr = model->get_3d_velocity(u3, v3, w3); CHKERRQ(ierr); 00085 00086 ierr = u3->begin_access(); CHKERRQ(ierr); 00087 ierr = v3->begin_access(); CHKERRQ(ierr); 00088 ierr = thickness->begin_access(); CHKERRQ(ierr); 00089 ierr = result->begin_access(); CHKERRQ(ierr); 00090 00091 for (PetscInt i = grid.xs; i < grid.xs+grid.xm; ++i) { 00092 for (PetscInt j = grid.ys; j < grid.ys+grid.ym; ++j) { 00093 PetscReal u_sum = 0, v_sum = 0, 00094 thk = (*thickness)(i,j); 00095 PetscInt ks = grid.kBelowHeight(thk); 00096 00097 // an "ice-free" cell: 00098 if (thk < 0.1) { 00099 (*result)(i,j).u = 0; 00100 (*result)(i,j).v = 0; 00101 continue; 00102 } 00103 00104 // an ice-filled cell: 00105 ierr = u3->getInternalColumn(i, j, &u_ij); CHKERRQ(ierr); 00106 ierr = v3->getInternalColumn(i, j, &v_ij); CHKERRQ(ierr); 00107 00108 if (thk <= grid.zlevels[1]) { 00109 (*result)(i,j).u = u_ij[0]; 00110 (*result)(i,j).v = v_ij[0]; 00111 continue; 00112 } 00113 00114 for (int k = 1; k <= ks; ++k) { 00115 u_sum += (grid.zlevels[k] - grid.zlevels[k-1]) * (u_ij[k] + u_ij[k-1]); 00116 v_sum += (grid.zlevels[k] - grid.zlevels[k-1]) * (v_ij[k] + v_ij[k-1]); 00117 } 00118 00119 // Finish the trapezoidal rule integration (times 1/2) and turn this 00120 // integral into a vertical average. Note that we ignore the ice between 00121 // zlevels[ks] and the surface, so in order to have a true average we 00122 // divide by zlevels[ks] and not thk. 00123 (*result)(i,j).u = 0.5 * u_sum / grid.zlevels[ks]; 00124 (*result)(i,j).v = 0.5 * v_sum / grid.zlevels[ks]; 00125 } 00126 } 00127 00128 ierr = result->end_access(); CHKERRQ(ierr); 00129 ierr = thickness->end_access(); CHKERRQ(ierr); 00130 ierr = v3->end_access(); CHKERRQ(ierr); 00131 ierr = u3->end_access(); CHKERRQ(ierr); 00132 00133 output = result; 00134 return 0; 00135 } 00136 00137 PSB_cbar::PSB_cbar(PISMStressBalance *m, IceGrid &g, PISMVars &my_vars) 00138 : PISMDiag<PISMStressBalance>(m, g, my_vars) { 00139 00140 // set metadata: 00141 vars[0].init_2d("cbar", grid); 00142 00143 set_attrs("magnitude of vertically-integrated horizontal velocity of ice", "", 00144 "m s-1", "m year-1", 0); 00145 vars[0].set("_FillValue", convert(-0.01, "m/year", "m/second")); 00146 vars[0].set("valid_min", 0.0); 00147 } 00148 00149 PetscErrorCode PSB_cbar::compute(IceModelVec* &output) { 00150 PetscErrorCode ierr; 00151 IceModelVec *tmp; 00152 IceModelVec2V *velbar_vec; 00153 IceModelVec2S *thickness, *result; 00154 00155 // get the thickness 00156 thickness = dynamic_cast<IceModelVec2S*>(variables.get("land_ice_thickness")); 00157 if (thickness == NULL) SETERRQ(1, "land_ice_thickness is not available"); 00158 00159 result = new IceModelVec2S; 00160 ierr = result->create(grid, "cbar", false); 00161 ierr = result->set_metadata(vars[0], 0); CHKERRQ(ierr); 00162 00163 // compute vertically-averaged horizontal velocity: 00164 PSB_velbar velbar(model, grid, variables); 00165 ierr = velbar.compute(tmp); CHKERRQ(ierr); 00166 00167 velbar_vec = dynamic_cast<IceModelVec2V*>(tmp); 00168 if (velbar_vec == NULL) SETERRQ(1, "dynamic cast failure"); 00169 00170 // compute its magnitude: 00171 ierr = velbar_vec->magnitude(*result); CHKERRQ(ierr); 00172 00173 // mask out ice-free areas: 00174 ierr = result->mask_by(*thickness, convert(-0.01, "m/year", "m/second")); CHKERRQ(ierr); 00175 00176 delete tmp; 00177 output = result; 00178 return 0; 00179 } 00180 00181 PSB_cflx::PSB_cflx(PISMStressBalance *m, IceGrid &g, PISMVars &my_vars) 00182 : PISMDiag<PISMStressBalance>(m, g, my_vars) { 00183 00184 // set metadata: 00185 vars[0].init_2d("cflx", grid); 00186 00187 set_attrs("magnitude of vertically-integrated horizontal flux of ice", "", 00188 "m2 s-1", "m2 year-1", 0); 00189 vars[0].set("_FillValue", convert(-0.01, "m2/year", "m2/second")); 00190 vars[0].set("valid_min", 0.0); 00191 } 00192 00193 PetscErrorCode PSB_cflx::compute(IceModelVec* &output) { 00194 PetscErrorCode ierr; 00195 IceModelVec2S *thickness, *result; 00196 IceModelVec *tmp; 00197 00198 // get the thickness 00199 thickness = dynamic_cast<IceModelVec2S*>(variables.get("land_ice_thickness")); 00200 if (thickness == NULL) SETERRQ(1, "land_ice_thickness is not available"); 00201 00202 // Compute the vertically-average horizontal ice velocity: 00203 PSB_cbar cbar(model, grid, variables); 00204 ierr = cbar.compute(tmp); CHKERRQ(ierr); 00205 // NB: the call above allocates memory 00206 00207 result = dynamic_cast<IceModelVec2S*>(tmp); 00208 if (result == NULL) SETERRQ(1, "dynamic_cast failure"); 00209 00210 ierr = thickness->begin_access(); CHKERRQ(ierr); 00211 ierr = result->begin_access(); CHKERRQ(ierr); 00212 00213 for (PetscInt i = grid.xs; i < grid.xs+grid.xm; ++i) 00214 for (PetscInt j = grid.ys; j < grid.ys+grid.ym; ++j) 00215 (*result)(i,j) *= (*thickness)(i,j); 00216 00217 ierr = result->end_access(); CHKERRQ(ierr); 00218 ierr = thickness->end_access(); CHKERRQ(ierr); 00219 00220 ierr = result->mask_by(*thickness, convert(-0.01, "m2/year", "m2/second")); CHKERRQ(ierr); 00221 00222 ierr = result->set_metadata(vars[0], 0); CHKERRQ(ierr); 00223 00224 output = result; 00225 return 0; 00226 } 00227 00228 PSB_cbase::PSB_cbase(PISMStressBalance *m, IceGrid &g, PISMVars &my_vars) 00229 : PISMDiag<PISMStressBalance>(m, g, my_vars) { 00230 00231 // set metadata: 00232 vars[0].init_2d("cbase", grid); 00233 00234 set_attrs("magnitude of horizontal velocity of ice at base of ice", "", 00235 "m s-1", "m year-1", 0); 00236 vars[0].set("_FillValue", convert(-0.01, "m/year", "m/second")); 00237 vars[0].set("valid_min", 0.0); 00238 } 00239 00240 PetscErrorCode PSB_cbase::compute(IceModelVec* &output) { 00241 PetscErrorCode ierr; 00242 PetscScalar fill_value = convert(-0.01, "m/year", "m/second"); 00243 IceModelVec3 *u3, *v3, *w3; 00244 IceModelVec2S tmp, *result, *thickness; 00245 00246 ierr = tmp.create(grid, "tmp", false); CHKERRQ(ierr); 00247 00248 result = new IceModelVec2S; 00249 ierr = result->create(grid, "cbase", false); CHKERRQ(ierr); 00250 ierr = result->set_metadata(vars[0], 0); CHKERRQ(ierr); 00251 00252 ierr = model->get_3d_velocity(u3, v3, w3); CHKERRQ(ierr); 00253 00254 thickness = dynamic_cast<IceModelVec2S*>(variables.get("land_ice_thickness")); 00255 if (thickness == NULL) SETERRQ(1, "land_ice_thickness is not available"); 00256 00257 ierr = u3->getHorSlice(*result, 0.0); CHKERRQ(ierr); // result = u_{z=0} 00258 ierr = v3->getHorSlice(tmp, 0.0); CHKERRQ(ierr); // tmp = v_{z=0} 00259 00260 ierr = result->set_to_magnitude(*result, tmp); CHKERRQ(ierr); 00261 00262 ierr = result->mask_by(*thickness, fill_value); CHKERRQ(ierr); // mask out ice-free areas 00263 00264 output = result; 00265 return 0; 00266 } 00267 00268 PSB_csurf::PSB_csurf(PISMStressBalance *m, IceGrid &g, PISMVars &my_vars) 00269 : PISMDiag<PISMStressBalance>(m, g, my_vars) { 00270 PetscReal fill_value = convert(-0.01, "m/year", "m/second"); 00271 // set metadata: 00272 vars[0].init_2d("csurf", grid); 00273 00274 set_attrs("magnitude of horizontal velocity of ice at ice surface", "", 00275 "m s-1", "m year-1", 0); 00276 vars[0].set("_FillValue", fill_value); 00277 vars[0].set("valid_min", 0.0); 00278 } 00279 00280 PetscErrorCode PSB_csurf::compute(IceModelVec* &output) { 00281 PetscErrorCode ierr; 00282 PetscReal fill_value = convert(-0.01, "m/year", "m/second"); 00283 00284 IceModelVec3 *u3, *v3, *w3; 00285 IceModelVec2S tmp, *result, *thickness; 00286 00287 ierr = tmp.create(grid, "tmp", false); CHKERRQ(ierr); 00288 00289 result = new IceModelVec2S; 00290 ierr = result->create(grid, "csurf", false); CHKERRQ(ierr); 00291 ierr = result->set_metadata(vars[0], 0); CHKERRQ(ierr); 00292 00293 ierr = model->get_3d_velocity(u3, v3, w3); CHKERRQ(ierr); 00294 00295 thickness = dynamic_cast<IceModelVec2S*>(variables.get("land_ice_thickness")); 00296 if (thickness == NULL) SETERRQ(1, "land_ice_thickness is not available"); 00297 00298 ierr = u3->getSurfaceValues(*result, *thickness); CHKERRQ(ierr); 00299 ierr = v3->getSurfaceValues(tmp, *thickness); CHKERRQ(ierr); 00300 00301 ierr = result->set_to_magnitude(*result, tmp); CHKERRQ(ierr); 00302 00303 ierr = result->mask_by(*thickness, fill_value); CHKERRQ(ierr); // mask out ice-free areas 00304 00305 output = result; 00306 return 0; 00307 } 00308 00309 00310 PSB_velsurf::PSB_velsurf(PISMStressBalance *m, IceGrid &g, PISMVars &my_vars) 00311 : PISMDiag<PISMStressBalance>(m, g, my_vars) { 00312 00313 // set metadata: 00314 dof = 2; 00315 vars.resize(dof); 00316 00317 vars[0].init_2d("uvelsurf", grid); 00318 vars[1].init_2d("vvelsurf", grid); 00319 00320 set_attrs("x-component of the horizontal velocity of ice at ice surface", "", 00321 "m s-1", "m year-1", 0); 00322 set_attrs("y-component of the horizontal velocity of ice at ice surface", "", 00323 "m s-1", "m year-1", 1); 00324 00325 vars[0].set("valid_min", convert(-1e6, "m/year", "m/second")); 00326 vars[0].set("valid_max", convert(1e6, "m/year", "m/second")); 00327 00328 vars[1].set("valid_min", convert(-1e6, "m/year", "m/second")); 00329 vars[1].set("valid_max", convert(1e6, "m/year", "m/second")); 00330 } 00331 00332 PetscErrorCode PSB_velsurf::compute(IceModelVec* &output) { 00333 PetscErrorCode ierr; 00334 IceModelVec2V *result; 00335 IceModelVec3 *u3, *v3, *w3; 00336 IceModelVec2S *thickness, tmp; 00337 00338 result = new IceModelVec2V; 00339 ierr = result->create(grid, "surf", false); CHKERRQ(ierr); 00340 ierr = result->set_metadata(vars[0], 0); CHKERRQ(ierr); 00341 ierr = result->set_metadata(vars[1], 1); CHKERRQ(ierr); 00342 00343 ierr = tmp.create(grid, "tmp", false); CHKERRQ(ierr); 00344 00345 ierr = model->get_3d_velocity(u3, v3, w3); CHKERRQ(ierr); 00346 00347 thickness = dynamic_cast<IceModelVec2S*>(variables.get("land_ice_thickness")); 00348 if (thickness == NULL) SETERRQ(1, "land_ice_thickness is not available"); 00349 00350 ierr = u3->getSurfaceValues(tmp, *thickness); CHKERRQ(ierr); 00351 ierr = result->set_component(0, tmp); CHKERRQ(ierr); 00352 00353 ierr = v3->getSurfaceValues(tmp, *thickness); CHKERRQ(ierr); 00354 ierr = result->set_component(1, tmp); CHKERRQ(ierr); 00355 00356 output = result; 00357 return 0; 00358 } 00359 00360 PSB_wvel::PSB_wvel(PISMStressBalance *m, IceGrid &g, PISMVars &my_vars) 00361 : PISMDiag<PISMStressBalance>(m, g, my_vars) { 00362 00363 // set metadata: 00364 vars[0].init_3d("wvel", grid, g.zlevels); 00365 00366 set_attrs("vertical velocity of ice, relative to geoid", "", 00367 "m s-1", "m year-1", 0); 00368 vars[0].set("valid_min", convert(-1e6, "m/year", "m/second")); 00369 vars[0].set("valid_max", convert(1e6, "m/year", "m/second")); 00370 } 00371 00372 PetscErrorCode PSB_wvel::compute(IceModelVec* &output) { 00373 PetscErrorCode ierr; 00374 IceModelVec3 *result, *u3, *v3, *w3; 00375 IceModelVec2S *bed, *uplift; 00376 PetscScalar *u, *v, *w, *res; 00377 00378 result = new IceModelVec3; 00379 ierr = result->create(grid, "wvel", false); CHKERRQ(ierr); 00380 ierr = result->set_metadata(vars[0], 0); CHKERRQ(ierr); 00381 00382 bed = dynamic_cast<IceModelVec2S*>(variables.get("bedrock_altitude")); 00383 if (bed == NULL) SETERRQ(1, "bedrock_altitude is not available"); 00384 00385 uplift = dynamic_cast<IceModelVec2S*>(variables.get("tendency_of_bedrock_altitude")); 00386 if (uplift == NULL) SETERRQ(1, "tendency_of_bedrock_altitude is not available"); 00387 00388 ierr = model->get_3d_velocity(u3, v3, w3); CHKERRQ(ierr); 00389 00390 ierr = bed->begin_access(); CHKERRQ(ierr); 00391 ierr = u3->begin_access(); CHKERRQ(ierr); 00392 ierr = v3->begin_access(); CHKERRQ(ierr); 00393 ierr = w3->begin_access(); CHKERRQ(ierr); 00394 ierr = uplift->begin_access(); CHKERRQ(ierr); 00395 ierr = result->begin_access(); CHKERRQ(ierr); 00396 00397 for (PetscInt i=grid.xs; i<grid.xs+grid.xm; ++i) { 00398 for (PetscInt j=grid.ys; j<grid.ys+grid.ym; ++j) { 00399 ierr = u3->getInternalColumn(i, j, &u); CHKERRQ(ierr); 00400 ierr = v3->getInternalColumn(i, j, &v); CHKERRQ(ierr); 00401 ierr = w3->getInternalColumn(i, j, &w); CHKERRQ(ierr); 00402 ierr = result->getInternalColumn(i, j, &res); CHKERRQ(ierr); 00403 00404 for (PetscInt k = 0; k < grid.Mz; ++k) 00405 res[k] = w[k] + (*uplift)(i,j) + u[k] * bed->diff_x_p(i,j) + v[k] * bed->diff_y_p(i,j); 00406 } 00407 } 00408 00409 ierr = result->end_access(); CHKERRQ(ierr); 00410 ierr = uplift->end_access(); CHKERRQ(ierr); 00411 ierr = w3->end_access(); CHKERRQ(ierr); 00412 ierr = v3->end_access(); CHKERRQ(ierr); 00413 ierr = u3->end_access(); CHKERRQ(ierr); 00414 ierr = bed->end_access(); CHKERRQ(ierr); 00415 00416 output = result; 00417 return 0; 00418 } 00419 00420 PSB_wvelsurf::PSB_wvelsurf(PISMStressBalance *m, IceGrid &g, PISMVars &my_vars) 00421 : PISMDiag<PISMStressBalance>(m, g, my_vars) { 00422 00423 // set metadata: 00424 vars[0].init_2d("wvelsurf", grid); 00425 00426 set_attrs("vertical velocity of ice at ice surface, relative to the geoid", "", 00427 "m s-1", "m year-1", 0); 00428 vars[0].set("valid_min", convert(-1e6, "m/year", "m/second")); 00429 vars[0].set("valid_max", convert(1e6, "m/year", "m/second")); 00430 } 00431 00432 PetscErrorCode PSB_wvelsurf::compute(IceModelVec* &output) { 00433 PetscErrorCode ierr; 00434 IceModelVec *tmp; 00435 IceModelVec3 *w3; 00436 IceModelVec2S *result, *thickness; 00437 00438 result = new IceModelVec2S; 00439 ierr = result->create(grid, "wvelsurf", false); CHKERRQ(ierr); 00440 ierr = result->set_metadata(vars[0], 0); CHKERRQ(ierr); 00441 00442 PSB_wvel wvel(model, grid, variables); 00443 00444 ierr = wvel.compute(tmp); CHKERRQ(ierr); 00445 00446 w3 = dynamic_cast<IceModelVec3*>(tmp); 00447 if (tmp == NULL) SETERRQ(1, "dynamic_cast failure"); 00448 00449 thickness = dynamic_cast<IceModelVec2S*>(variables.get("land_ice_thickness")); 00450 if (thickness == NULL) SETERRQ(1, "land_ice_thickness is not available"); 00451 00452 ierr = w3->getSurfaceValues(*result, *thickness); CHKERRQ(ierr); 00453 00454 delete tmp; 00455 output = result; 00456 return 0; 00457 } 00458 00459 PSB_wvelbase::PSB_wvelbase(PISMStressBalance *m, IceGrid &g, PISMVars &my_vars) 00460 : PISMDiag<PISMStressBalance>(m, g, my_vars) { 00461 00462 // set metadata: 00463 vars[0].init_2d("wvelbase", grid); 00464 00465 set_attrs("vertical velocity of ice at the base of ice, relative to the geoid", "", 00466 "m s-1", "m year-1", 0); 00467 vars[0].set("valid_min", convert(-1e6, "m/year", "m/second")); 00468 vars[0].set("valid_max", convert(1e6, "m/year", "m/second")); 00469 } 00470 00471 PetscErrorCode PSB_wvelbase::compute(IceModelVec* &output) { 00472 PetscErrorCode ierr; 00473 IceModelVec *tmp; 00474 IceModelVec3 *w3; 00475 IceModelVec2S *result; 00476 00477 result = new IceModelVec2S; 00478 ierr = result->create(grid, "wvelbase", false); CHKERRQ(ierr); 00479 ierr = result->set_metadata(vars[0], 0); CHKERRQ(ierr); 00480 00481 PSB_wvel wvel(model, grid, variables); 00482 00483 ierr = wvel.compute(tmp); CHKERRQ(ierr); 00484 00485 w3 = dynamic_cast<IceModelVec3*>(tmp); 00486 if (tmp == NULL) SETERRQ(1, "dynamic_cast failure"); 00487 00488 ierr = w3->getHorSlice(*result, 0.0); CHKERRQ(ierr); 00489 00490 delete tmp; 00491 output = result; 00492 return 0; 00493 } 00494 00495 PSB_velbase::PSB_velbase(PISMStressBalance *m, IceGrid &g, PISMVars &my_vars) 00496 : PISMDiag<PISMStressBalance>(m, g, my_vars) { 00497 00498 // set metadata: 00499 dof = 2; 00500 vars.resize(dof); 00501 00502 vars[0].init_2d("uvelbase", grid); 00503 vars[1].init_2d("vvelbase", grid); 00504 00505 set_attrs("x-component of the horizontal velocity of ice at the base of ice", "", 00506 "m s-1", "m year-1", 0); 00507 set_attrs("y-component of the horizontal velocity of ice at the base of ice", "", 00508 "m s-1", "m year-1", 1); 00509 00510 vars[0].set("valid_min", convert(-1e6, "m/year", "m/second")); 00511 vars[0].set("valid_max", convert(1e6, "m/year", "m/second")); 00512 00513 vars[1].set("valid_min", convert(-1e6, "m/year", "m/second")); 00514 vars[1].set("valid_max", convert(1e6, "m/year", "m/second")); 00515 } 00516 00517 PetscErrorCode PSB_velbase::compute(IceModelVec* &output) { 00518 PetscErrorCode ierr; 00519 IceModelVec2V *result; 00520 IceModelVec3 *u3, *v3, *w3; 00521 IceModelVec2S tmp; // will be de-allocated automatically 00522 00523 result = new IceModelVec2V; 00524 ierr = result->create(grid, "base", false); CHKERRQ(ierr); 00525 ierr = result->set_metadata(vars[0], 0); CHKERRQ(ierr); 00526 ierr = result->set_metadata(vars[1], 1); CHKERRQ(ierr); 00527 00528 ierr = tmp.create(grid, "tmp", false); CHKERRQ(ierr); 00529 00530 ierr = model->get_3d_velocity(u3, v3, w3); CHKERRQ(ierr); 00531 00532 ierr = u3->getHorSlice(tmp, 0.0); CHKERRQ(ierr); 00533 ierr = result->set_component(0, tmp); CHKERRQ(ierr); 00534 00535 ierr = v3->getHorSlice(tmp, 0.0); CHKERRQ(ierr); 00536 ierr = result->set_component(1, tmp); CHKERRQ(ierr); 00537 00538 output = result; 00539 return 0; 00540 } 00541 00542 PSB_bueler_brown_f::PSB_bueler_brown_f(PISMStressBalance *m, IceGrid &g, PISMVars &my_vars) 00543 : PISMDiag<PISMStressBalance>(m, g, my_vars) { 00544 00545 // set metadata: 00546 vars[0].init_2d("bueler_brown_f", grid); 00547 set_attrs("f(|v|) in Bueler and Brown (2009), equation 22", "", 00548 "", "", 0); 00549 vars[0].set("valid_min", 0); 00550 vars[0].set("valid_max", 1); 00551 vars[0].set("_FillValue", -0.01); 00552 } 00553 00555 static PetscScalar bueler_brown_f(PetscScalar v_squared) { 00556 const PetscScalar inC_fofv = 1.0e-4 * PetscSqr(secpera), 00557 outC_fofv = 2.0 / pi; 00558 00559 return 1.0 - outC_fofv * atan(inC_fofv * v_squared); 00560 } 00561 00562 PetscErrorCode PSB_bueler_brown_f::compute(IceModelVec* &output) { 00563 PetscErrorCode ierr; 00564 IceModelVec2V *vel_ssa; 00565 IceModelVec2S *thickness; 00566 PetscReal fill_value = -0.01; 00567 00568 thickness = dynamic_cast<IceModelVec2S*>(variables.get("land_ice_thickness")); 00569 if (thickness == NULL) SETERRQ(1, "land_ice_thickness is not available"); 00570 00571 IceModelVec2S *result = new IceModelVec2S; 00572 ierr = result->create(grid, "bueler_brown_f", false); CHKERRQ(ierr); 00573 ierr = result->set_metadata(vars[0], 0); CHKERRQ(ierr); 00574 00575 ierr = model->get_advective_2d_velocity(vel_ssa); CHKERRQ(ierr); 00576 00577 ierr = vel_ssa->begin_access(); CHKERRQ(ierr); 00578 ierr = result->begin_access(); CHKERRQ(ierr); 00579 00580 for (PetscInt i = grid.xs; i < grid.xs+grid.xm; ++i) 00581 for (PetscInt j = grid.ys; j < grid.ys+grid.ym; ++j) 00582 (*result)(i,j) = bueler_brown_f((*vel_ssa)(i,j).magnitude_squared()); 00583 00584 ierr = result->end_access(); CHKERRQ(ierr); 00585 ierr = vel_ssa->end_access(); CHKERRQ(ierr); 00586 00587 ierr = result->mask_by(*thickness, fill_value); CHKERRQ(ierr); 00588 00589 output = result; 00590 return 0; 00591 } 00592 00593 PSB_bfrict::PSB_bfrict(PISMStressBalance *m, IceGrid &g, PISMVars &my_vars) 00594 : PISMDiag<PISMStressBalance>(m, g, my_vars) { 00595 00596 // set metadata: 00597 vars[0].init_2d("bfrict", grid); 00598 00599 set_attrs("basal frictional heating", "", 00600 "W m-2", "W m-2", 0); 00601 } 00602 00603 PetscErrorCode PSB_bfrict::compute(IceModelVec* &output) { 00604 PetscErrorCode ierr; 00605 00606 IceModelVec2S *result = new IceModelVec2S; 00607 ierr = result->create(grid, "bfrict", false); CHKERRQ(ierr); 00608 ierr = result->set_metadata(vars[0], 0); CHKERRQ(ierr); 00609 00610 IceModelVec2S *bfrict; 00611 ierr = model->get_basal_frictional_heating(bfrict); CHKERRQ(ierr); 00612 00613 ierr = bfrict->copy_to(*result); CHKERRQ(ierr); 00614 00615 output = result; 00616 return 0; 00617 } 00618 00619 00620 PSB_uvel::PSB_uvel(PISMStressBalance *m, IceGrid &g, PISMVars &my_vars) 00621 : PISMDiag<PISMStressBalance>(m, g, my_vars) { 00622 00623 // set metadata: 00624 vars[0].init_3d("uvel", grid, g.zlevels); 00625 00626 set_attrs("horizontal velocity of ice in the X direction", "land_ice_x_velocity", 00627 "m s-1", "m year-1", 0); 00628 } 00629 00630 PetscErrorCode PSB_uvel::compute(IceModelVec* &output) { 00631 PetscErrorCode ierr; 00632 00633 IceModelVec3 *result = new IceModelVec3; 00634 ierr = result->create(grid, "uvel", false); CHKERRQ(ierr); 00635 ierr = result->set_metadata(vars[0], 0); CHKERRQ(ierr); 00636 00637 IceModelVec2S *thickness; 00638 thickness = dynamic_cast<IceModelVec2S*>(variables.get("land_ice_thickness")); 00639 if (thickness == NULL) SETERRQ(1, "land_ice_thickness is not available"); 00640 00641 IceModelVec3 *u3, *v3, *w3; 00642 ierr = model->get_3d_velocity(u3, v3, w3); CHKERRQ(ierr); 00643 00644 ierr = u3->begin_access(); CHKERRQ(ierr); 00645 ierr = result->begin_access(); CHKERRQ(ierr); 00646 ierr = thickness->begin_access(); CHKERRQ(ierr); 00647 00648 PetscScalar *u_ij, *u_out_ij; 00649 for (PetscInt i = grid.xs; i < grid.xs+grid.xm; ++i) { 00650 for (PetscInt j = grid.ys; j < grid.ys+grid.ym; ++j) { 00651 int ks = grid.kBelowHeight((*thickness)(i,j)); 00652 00653 ierr = u3->getInternalColumn(i,j,&u_ij); CHKERRQ(ierr); 00654 ierr = result->getInternalColumn(i,j,&u_out_ij); CHKERRQ(ierr); 00655 00656 // in the ice: 00657 for (int k = 0; k <= ks ; k++) { 00658 u_out_ij[k] = u_ij[k]; 00659 } 00660 // above the ice: 00661 for (int k = ks+1; k < grid.Mz ; k++) { 00662 u_out_ij[k] = 0.0; 00663 } 00664 } 00665 } 00666 00667 ierr = thickness->end_access(); CHKERRQ(ierr); 00668 ierr = result->end_access(); CHKERRQ(ierr); 00669 ierr = u3->end_access(); CHKERRQ(ierr); 00670 00671 output = result; 00672 return 0; 00673 } 00674 00675 PSB_vvel::PSB_vvel(PISMStressBalance *m, IceGrid &g, PISMVars &my_vars) 00676 : PISMDiag<PISMStressBalance>(m, g, my_vars) { 00677 00678 // set metadata: 00679 vars[0].init_3d("vvel", grid, g.zlevels); 00680 00681 set_attrs("horizontal velocity of ice in the Y direction", "land_ice_y_velocity", 00682 "m s-1", "m year-1", 0); 00683 } 00684 00685 PetscErrorCode PSB_vvel::compute(IceModelVec* &output) { 00686 PetscErrorCode ierr; 00687 00688 IceModelVec3 *result = new IceModelVec3; 00689 ierr = result->create(grid, "vvel", false); CHKERRQ(ierr); 00690 ierr = result->set_metadata(vars[0], 0); CHKERRQ(ierr); 00691 00692 IceModelVec2S *thickness; 00693 thickness = dynamic_cast<IceModelVec2S*>(variables.get("land_ice_thickness")); 00694 if (thickness == NULL) SETERRQ(1, "land_ice_thickness is not available"); 00695 00696 IceModelVec3 *u3, *v3, *w3; 00697 ierr = model->get_3d_velocity(u3, v3, w3); CHKERRQ(ierr); 00698 00699 ierr = v3->begin_access(); CHKERRQ(ierr); 00700 ierr = result->begin_access(); CHKERRQ(ierr); 00701 ierr = thickness->begin_access(); CHKERRQ(ierr); 00702 00703 PetscScalar *v_ij, *v_out_ij; 00704 for (PetscInt i = grid.xs; i < grid.xs+grid.xm; ++i) { 00705 for (PetscInt j = grid.ys; j < grid.ys+grid.ym; ++j) { 00706 int ks = grid.kBelowHeight((*thickness)(i,j)); 00707 00708 ierr = v3->getInternalColumn(i,j,&v_ij); CHKERRQ(ierr); 00709 ierr = result->getInternalColumn(i,j,&v_out_ij); CHKERRQ(ierr); 00710 00711 // in the ice: 00712 for (int k = 0; k <= ks ; k++) { 00713 v_out_ij[k] = v_ij[k]; 00714 } 00715 // above the ice: 00716 for (int k = ks+1; k < grid.Mz ; k++) { 00717 v_out_ij[k] = 0.0; 00718 } 00719 } 00720 } 00721 00722 ierr = thickness->end_access(); CHKERRQ(ierr); 00723 ierr = result->end_access(); CHKERRQ(ierr); 00724 ierr = v3->end_access(); CHKERRQ(ierr); 00725 00726 output = result; 00727 return 0; 00728 } 00729 00730 PSB_wvel_rel::PSB_wvel_rel(PISMStressBalance *m, IceGrid &g, PISMVars &my_vars) 00731 : PISMDiag<PISMStressBalance>(m, g, my_vars) { 00732 00733 // set metadata: 00734 vars[0].init_3d("wvel_rel", grid, g.zlevels); 00735 00736 set_attrs("vertical velocity of ice, relative to base of ice directly below", "", 00737 "m s-1", "m year-1", 0); 00738 } 00739 00740 PetscErrorCode PSB_wvel_rel::compute(IceModelVec* &output) { 00741 PetscErrorCode ierr; 00742 00743 IceModelVec3 *result = new IceModelVec3; 00744 ierr = result->create(grid, "wvel_rel", false); CHKERRQ(ierr); 00745 ierr = result->set_metadata(vars[0], 0); CHKERRQ(ierr); 00746 00747 IceModelVec2S *thickness; 00748 thickness = dynamic_cast<IceModelVec2S*>(variables.get("land_ice_thickness")); 00749 if (thickness == NULL) SETERRQ(1, "land_ice_thickness is not available"); 00750 00751 IceModelVec3 *u3, *v3, *w3; 00752 ierr = model->get_3d_velocity(u3, v3, w3); CHKERRQ(ierr); 00753 00754 ierr = w3->begin_access(); CHKERRQ(ierr); 00755 ierr = result->begin_access(); CHKERRQ(ierr); 00756 ierr = thickness->begin_access(); CHKERRQ(ierr); 00757 00758 PetscScalar *w_ij, *w_out_ij; 00759 for (PetscInt i = grid.xs; i < grid.xs+grid.xm; ++i) { 00760 for (PetscInt j = grid.ys; j < grid.ys+grid.ym; ++j) { 00761 int ks = grid.kBelowHeight((*thickness)(i,j)); 00762 00763 ierr = w3->getInternalColumn(i,j,&w_ij); CHKERRQ(ierr); 00764 ierr = result->getInternalColumn(i,j,&w_out_ij); CHKERRQ(ierr); 00765 00766 // in the ice: 00767 for (int k = 0; k <= ks ; k++) { 00768 w_out_ij[k] = w_ij[k]; 00769 } 00770 // above the ice: 00771 for (int k = ks+1; k < grid.Mz ; k++) { 00772 w_out_ij[k] = 0.0; 00773 } 00774 } 00775 } 00776 00777 ierr = thickness->end_access(); CHKERRQ(ierr); 00778 ierr = result->end_access(); CHKERRQ(ierr); 00779 ierr = w3->end_access(); CHKERRQ(ierr); 00780 00781 output = result; 00782 return 0; 00783 } 00784 00785 PSB_taud_mag::PSB_taud_mag(PISMStressBalance *m, IceGrid &g, PISMVars &my_vars) 00786 : PISMDiag<PISMStressBalance>(m, g, my_vars) { 00787 00788 // set metadata: 00789 vars[0].init_2d("taud_mag", grid); 00790 00791 set_attrs("magnitude of the driving shear stress at the base of ice", "", 00792 "Pa", "Pa", 0); 00793 } 00794 00795 PetscErrorCode PSB_taud_mag::compute(IceModelVec* &output) { 00796 PetscErrorCode ierr; 00797 00798 // Allocate memory: 00799 IceModelVec2S *result = new IceModelVec2S; 00800 ierr = result->create(grid, "taud_mag", false); CHKERRQ(ierr); 00801 ierr = result->set_metadata(vars[0], 0); CHKERRQ(ierr); 00802 result->write_in_glaciological_units = true; 00803 00804 IceModelVec2S *thickness, *surface, *bed; 00805 IceModelVec2Int *mask; 00806 00807 thickness = dynamic_cast<IceModelVec2S*>(variables.get("land_ice_thickness")); 00808 if (thickness == NULL) SETERRQ(1, "land_ice_thickness is not available"); 00809 00810 surface = dynamic_cast<IceModelVec2S*>(variables.get("surface_altitude")); 00811 if (surface == NULL) SETERRQ(1, "surface_altitude is not available"); 00812 00813 bed = dynamic_cast<IceModelVec2S*>(variables.get("bedrock_altitude")); 00814 if (bed == NULL) SETERRQ(1, "bedrock_altitude is not available"); 00815 00816 mask = dynamic_cast<IceModelVec2Int*>(variables.get("mask")); 00817 if (mask == NULL) SETERRQ(1, "mask is not available"); 00818 00819 IceModelVec2S &thk = *thickness; // to improve readability (below) 00820 00821 const PetscScalar n = model->config.get("Glen_exponent"), // frequently n = 3 00822 etapow = (2.0 * n + 2.0)/n, // = 8/3 if n = 3 00823 invpow = 1.0 / etapow, // = 3/8 00824 dinvpow = (- n - 2.0) / (2.0 * n + 2.0); // = -5/8 00825 const PetscScalar minThickEtaTransform = 5.0; // m 00826 const PetscScalar dx=grid.dx, dy=grid.dy; 00827 00828 PetscReal standard_gravity = model->config.get("standard_gravity"), 00829 ice_density = model->config.get("ice_density"); 00830 bool use_eta = (model->config.get_string("surface_gradient_method") == "eta"); 00831 00832 MaskQuery M(*mask); 00833 00834 ierr = surface->begin_access(); CHKERRQ(ierr); 00835 ierr = bed->begin_access(); CHKERRQ(ierr); 00836 ierr = mask->begin_access(); CHKERRQ(ierr); 00837 ierr = thk.begin_access(); CHKERRQ(ierr); 00838 00839 ierr = result->begin_access(); CHKERRQ(ierr); 00840 00841 PetscReal result_ij_u, result_ij_v; 00842 for (PetscInt i=grid.xs; i<grid.xs+grid.xm; ++i) { 00843 for (PetscInt j=grid.ys; j<grid.ys+grid.ym; ++j) { 00844 const PetscScalar pressure = ice_density * standard_gravity * thk(i,j); 00845 if (pressure <= 0.0) { 00846 result_ij_u = 0.0; 00847 result_ij_v = 0.0; 00848 } else { 00849 PetscScalar h_x = 0.0, h_y = 0.0; 00850 // FIXME: we need to handle grid periodicity correctly. 00851 if (M.grounded(i,j) && (use_eta == true)) { 00852 // in grounded case, differentiate eta = H^{8/3} by chain rule 00853 if (thk(i,j) > 0.0) { 00854 const PetscScalar myH = (thk(i,j) < minThickEtaTransform ? 00855 minThickEtaTransform : thk(i,j)); 00856 const PetscScalar eta = pow(myH, etapow), factor = invpow * pow(eta, dinvpow); 00857 h_x = factor * (pow(thk(i+1,j),etapow) - pow(thk(i-1,j),etapow)) / (2*dx); 00858 h_y = factor * (pow(thk(i,j+1),etapow) - pow(thk(i,j-1),etapow)) / (2*dy); 00859 } 00860 // now add bed slope to get actual h_x,h_y 00861 // FIXME: there is no reason to assume user's bed is periodized 00862 h_x += bed->diff_x(i,j); 00863 h_y += bed->diff_y(i,j); 00864 } else { // floating or eta transformation is not used 00865 h_x = surface->diff_x(i,j); 00866 h_y = surface->diff_y(i,j); 00867 } 00868 00869 result_ij_u = - pressure * h_x; 00870 result_ij_v = - pressure * h_y; 00871 } 00872 00873 (*result)(i,j) = sqrt(PetscSqr(result_ij_u) + PetscSqr(result_ij_v)); 00874 } 00875 } 00876 00877 ierr = thk.end_access(); CHKERRQ(ierr); 00878 ierr = bed->end_access(); CHKERRQ(ierr); 00879 ierr = surface->end_access(); CHKERRQ(ierr); 00880 ierr = mask->end_access(); CHKERRQ(ierr); 00881 ierr = result->end_access(); CHKERRQ(ierr); 00882 00883 output = result; 00884 return 0; 00885 }
1.7.3