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