PISM, A Parallel Ice Sheet Model stable 0.4.1779

src/base/stressbalance/PISMStressBalance.cc

Go to the documentation of this file.
00001 // Copyright (C) 2010, 2011 Constantine Khroulev and Ed Bueler
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.hh"
00020 
00021 PISMStressBalance::PISMStressBalance(IceGrid &g,
00022                                      ShallowStressBalance *sb,
00023                                      SSB_Modifier *ssb_mod,
00024                                      PISMOceanModel *ocean_model,
00025                                      const NCConfigVariable &conf)
00026   : PISMComponent_Diag(g, conf), stress_balance(sb), modifier(ssb_mod), ocean(ocean_model) {
00027 
00028   basal_melt_rate = NULL;
00029   variables = NULL;
00030 
00031   allocate();
00032 }
00033 
00034 PISMStressBalance::~PISMStressBalance() {
00035   delete stress_balance;
00036   delete modifier;
00037 }
00038 
00039 PetscErrorCode PISMStressBalance::allocate() {
00040   PetscErrorCode ierr;
00041 
00042   // allocate the vertical velocity field:
00043   ierr = w.create(grid, "wvel_rel", false); CHKERRQ(ierr);
00044   ierr = w.set_attrs("diagnostic",
00045                      "vertical velocity of ice, relative to base of ice directly below",
00046                      "m s-1", ""); CHKERRQ(ierr);
00047   w.time_independent = false;
00048   ierr = w.set_glaciological_units("m year-1"); CHKERRQ(ierr);
00049   w.write_in_glaciological_units = true;
00050 
00051   return 0;
00052 }
00053 
00055 PetscErrorCode PISMStressBalance::init(PISMVars &vars) {
00056   PetscErrorCode ierr;
00057 
00058   variables = &vars;
00059 
00060   ierr = stress_balance->init(vars); CHKERRQ(ierr);   
00061   ierr = modifier->init(vars); CHKERRQ(ierr); 
00062 
00063   return 0;
00064 }
00065 
00066 PetscErrorCode PISMStressBalance::set_boundary_conditions(IceModelVec2Int &locations,
00067                                                           IceModelVec2V &velocities) {
00068   PetscErrorCode ierr;
00069   ierr = stress_balance->set_boundary_conditions(locations, velocities); CHKERRQ(ierr);
00070   return 0;
00071 }
00072 
00075 PetscErrorCode PISMStressBalance::set_basal_melt_rate(IceModelVec2S *bmr_input) {
00076   basal_melt_rate = bmr_input;
00077   return 0;
00078 }
00079 
00081 PetscErrorCode PISMStressBalance::update(bool fast) {
00082   PetscErrorCode ierr;
00083   IceModelVec2V *velocity_2d;
00084   IceModelVec2S *D2;
00085   IceModelVec3  *u, *v;
00086 
00087   // Tell the ShallowStressBalance object about the current sea level:
00088   if (ocean) {
00089     PetscReal sea_level;
00090     ierr = ocean->sea_level_elevation(sea_level); CHKERRQ(ierr);
00091     stress_balance->set_sea_level_elevation(sea_level);
00092   }
00093 
00094   ierr = stress_balance->update(fast); CHKERRQ(ierr);
00095 
00096   ierr = stress_balance->get_advective_2d_velocity(velocity_2d); CHKERRQ(ierr); 
00097   ierr = stress_balance->get_D2(D2); CHKERRQ(ierr);
00098 
00099   ierr = modifier->update(velocity_2d, D2, fast); CHKERRQ(ierr);
00100 
00101   if (!fast) {
00102     ierr = modifier->get_horizontal_3d_velocity(u, v); CHKERRQ(ierr);
00103 
00104     ierr = compute_vertical_velocity(u, v, basal_melt_rate, w); CHKERRQ(ierr); 
00105   }
00106 
00107   return 0;
00108 }
00109 
00110 PetscErrorCode PISMStressBalance::get_advective_2d_velocity(IceModelVec2V* &result) {
00111   PetscErrorCode ierr;
00112   ierr = stress_balance->get_advective_2d_velocity(result); CHKERRQ(ierr);
00113   return 0;
00114 }
00115 
00116 PetscErrorCode PISMStressBalance::get_diffusive_flux(IceModelVec2Stag* &result) {
00117   PetscErrorCode ierr;
00118   ierr = modifier->get_diffusive_flux(result); CHKERRQ(ierr);
00119   return 0;
00120 }
00121 
00122 PetscErrorCode PISMStressBalance::get_max_diffusivity(PetscReal &D) {
00123   PetscErrorCode ierr;
00124   ierr = modifier->get_max_diffusivity(D); CHKERRQ(ierr);  
00125   return 0;
00126 }
00127 
00128 PetscErrorCode PISMStressBalance::get_max_2d_velocity(PetscReal &u_max, PetscReal &v_max) {
00129   PetscErrorCode ierr;
00130   ierr = stress_balance->get_max_2d_velocity(u_max, v_max); CHKERRQ(ierr);
00131   return 0;
00132 }
00133 
00134 PetscErrorCode PISMStressBalance::get_3d_velocity(IceModelVec3* &u, IceModelVec3* &v, IceModelVec3* &w_out) {
00135   PetscErrorCode ierr;
00136   ierr = modifier->get_horizontal_3d_velocity(u, v); CHKERRQ(ierr);
00137   w_out = &w;
00138   return 0;
00139 }
00140 
00141 PetscErrorCode PISMStressBalance::get_max_3d_velocity(PetscReal &u, PetscReal &v, PetscReal &w_out) {
00142   PetscErrorCode ierr;
00143   ierr = modifier->get_max_horizontal_velocity(u, v); CHKERRQ(ierr);
00144   w_out = w_max;
00145   return 0;
00146 }
00147 
00148 PetscErrorCode PISMStressBalance::get_basal_frictional_heating(IceModelVec2S* &result) {
00149   PetscErrorCode ierr;
00150   ierr = stress_balance->get_basal_frictional_heating(result); CHKERRQ(ierr); 
00151   return 0;
00152 }
00153 
00154 PetscErrorCode PISMStressBalance::get_volumetric_strain_heating(IceModelVec3* &result) {
00155   PetscErrorCode ierr;
00156   ierr = modifier->get_volumetric_strain_heating(result); CHKERRQ(ierr);
00157   return 0;
00158 }
00159 
00160 PetscErrorCode PISMStressBalance::get_principal_strain_rates(
00161                 IceModelVec2S &result_e1, IceModelVec2S &result_e2) {
00162   PetscErrorCode ierr;
00163   ierr = stress_balance->compute_principal_strain_rates(result_e1, result_e2); CHKERRQ(ierr);
00164   return 0;
00165 }
00166 
00167 
00169 PetscErrorCode PISMStressBalance::extend_the_grid(PetscInt old_Mz) {
00170   PetscErrorCode ierr;
00171 
00172   ierr = w.extend_vertically(old_Mz, 0.0); CHKERRQ(ierr);
00173 
00174   ierr = stress_balance->extend_the_grid(old_Mz); CHKERRQ(ierr);
00175 
00176   ierr = modifier->extend_the_grid(old_Mz); CHKERRQ(ierr);
00177 
00178   return 0;
00179 }
00180 
00182 
00211 PetscErrorCode PISMStressBalance::compute_vertical_velocity(IceModelVec3 *u, IceModelVec3 *v,
00212                                                             IceModelVec2S *bmr,
00213                                                             IceModelVec3 &result) {
00214   PetscErrorCode ierr;
00215   const PetscScalar dx = grid.dx, dy = grid.dy;
00216 
00217   ierr = u->begin_access(); CHKERRQ(ierr);
00218   ierr = v->begin_access(); CHKERRQ(ierr);
00219   ierr = result.begin_access(); CHKERRQ(ierr);
00220 
00221   if (bmr) {
00222     ierr = bmr->begin_access(); CHKERRQ(ierr);
00223   }
00224 
00225   PetscScalar *w_ij, *u_im1, *u_ip1, *v_jm1, *v_jp1;
00226 
00227   PetscReal my_w_max = 0.0;
00228   for (PetscInt i=grid.xs; i<grid.xs+grid.xm; ++i) {
00229     for (PetscInt j=grid.ys; j<grid.ys+grid.ym; ++j) {
00230       ierr = result.getInternalColumn(i,j,&w_ij); CHKERRQ(ierr);
00231 
00232       ierr = u->getInternalColumn(i-1,j,&u_im1); CHKERRQ(ierr);
00233       ierr = u->getInternalColumn(i+1,j,&u_ip1); CHKERRQ(ierr);
00234 
00235       ierr = v->getInternalColumn(i,j-1,&v_jm1); CHKERRQ(ierr);
00236       ierr = v->getInternalColumn(i,j+1,&v_jp1); CHKERRQ(ierr);
00237 
00238       // at the base:
00239       if (bmr) {
00240         w_ij[0] = - (*bmr)(i,j);
00241       } else {
00242         w_ij[0] = 0.0;
00243       }
00244       my_w_max = PetscMax(my_w_max, PetscAbs(w_ij[0]));
00245       
00246       // within the ice and above:
00247       PetscScalar OLDintegrand
00248              = (u_ip1[0] - u_im1[0]) / (2.0*dx) + (v_jp1[0] - v_jm1[0]) / (2.0*dy);
00249       for (PetscInt k = 1; k < grid.Mz; ++k) {
00250         const PetscScalar NEWintegrand
00251              = (u_ip1[k] - u_im1[k]) / (2.0*dx) + (v_jp1[k] - v_jm1[k]) / (2.0*dy);
00252         const PetscScalar dz = grid.zlevels[k] - grid.zlevels[k-1];
00253         w_ij[k] = w_ij[k-1] - 0.5 * (NEWintegrand + OLDintegrand) * dz;
00254         OLDintegrand = NEWintegrand;
00255 
00256         my_w_max = PetscMax(my_w_max, PetscAbs(w_ij[k]));
00257       }
00258     }
00259   }
00260 
00261   if (bmr) {
00262     ierr = bmr->end_access(); CHKERRQ(ierr);
00263   }
00264 
00265   ierr = u->end_access(); CHKERRQ(ierr);
00266   ierr = v->end_access(); CHKERRQ(ierr);
00267   ierr = result.end_access(); CHKERRQ(ierr);
00268 
00269   ierr = PetscGlobalMax(&my_w_max, &w_max, grid.com); CHKERRQ(ierr);
00270   
00271   return 0;
00272 }
00273 
00274 PetscErrorCode PISMStressBalance::stdout_report(string &result) {
00275   PetscErrorCode ierr;
00276   string tmp1, tmp2;
00277   
00278   ierr = stress_balance->stdout_report(tmp1); CHKERRQ(ierr);
00279 
00280   ierr = modifier->stdout_report(tmp2); CHKERRQ(ierr);
00281 
00282   result = tmp1 + tmp2;
00283 
00284   return 0;
00285 }
00286 
00287 PetscErrorCode PISMStressBalance::write_variables(set<string> vars, string filename) {
00288   PetscErrorCode ierr;
00289 
00290   ierr = stress_balance->write_variables(vars, filename); CHKERRQ(ierr);
00291   ierr = modifier->write_variables(vars, filename); CHKERRQ(ierr);
00292 
00293   return 0;
00294 }
00295 
00296 void PISMStressBalance::add_vars_to_output(string keyword, set<string> &result) {
00297 
00298   stress_balance->add_vars_to_output(keyword, result);
00299   modifier->add_vars_to_output(keyword, result);
00300 
00301 }
00302 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines