|
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 "SSB_Modifier.hh" 00020 00021 PetscErrorCode SSB_Modifier::allocate() { 00022 PetscErrorCode ierr; 00023 00024 ierr = u.create(grid, "uvel", true); CHKERRQ(ierr); 00025 ierr = u.set_attrs("diagnostic", "horizontal velocity of ice in the X direction", 00026 "m s-1", "land_ice_x_velocity"); CHKERRQ(ierr); 00027 ierr = u.set_glaciological_units("m year-1"); CHKERRQ(ierr); 00028 u.write_in_glaciological_units = true; 00029 00030 ierr = v.create(grid, "vvel", true); CHKERRQ(ierr); 00031 ierr = v.set_attrs("diagnostic", "horizontal velocity of ice in the Y direction", 00032 "m s-1", "land_ice_y_velocity"); CHKERRQ(ierr); 00033 ierr = v.set_glaciological_units("m year-1"); CHKERRQ(ierr); 00034 v.write_in_glaciological_units = true; 00035 00036 ierr = Sigma.create(grid, "strainheat", false); CHKERRQ(ierr); // never diff'ed in hor dirs 00037 ierr = Sigma.set_attrs("internal", 00038 "rate of strain heating in ice (dissipation heating)", 00039 "W m-3", ""); CHKERRQ(ierr); 00040 ierr = Sigma.set_glaciological_units("mW m-3"); CHKERRQ(ierr); 00041 00042 ierr = diffusive_flux.create(grid, "diffusive_flux", true, 1); CHKERRQ(ierr); 00043 ierr = diffusive_flux.set_attrs("internal", 00044 "diffusive (SIA) flux components on the staggered grid", 00045 "", ""); CHKERRQ(ierr); 00046 00047 return 0; 00048 } 00049 00050 PetscErrorCode SSB_Modifier::extend_the_grid(PetscInt old_Mz) { 00051 PetscErrorCode ierr; 00052 00053 ierr = u.extend_vertically(old_Mz, 0.0); CHKERRQ(ierr); 00054 ierr = v.extend_vertically(old_Mz, 0.0); CHKERRQ(ierr); 00055 ierr = Sigma.extend_vertically(old_Mz, 0.0); CHKERRQ(ierr); 00056 00057 return 0; 00058 } 00059 00060 PetscErrorCode SSBM_Trivial::init(PISMVars &vars) { 00061 PetscErrorCode ierr; 00062 00063 ierr = SSB_Modifier::init(vars); CHKERRQ(ierr); 00064 00065 enthalpy = dynamic_cast<IceModelVec3*>(vars.get("enthalpy")); 00066 if (enthalpy == NULL) SETERRQ(1, "enthalpy is not available"); 00067 00068 thickness = dynamic_cast<IceModelVec2S*>(vars.get("land_ice_thickness")); 00069 if (thickness == NULL) SETERRQ(1, "land_ice_thickness is not available"); 00070 00071 return 0; 00072 } 00073 00074 00076 00084 PetscErrorCode SSBM_Trivial::update(IceModelVec2V *vel_input, 00085 IceModelVec2S *D2_input, 00086 bool fast) { 00087 PetscErrorCode ierr; 00088 00089 if (fast) 00090 return 0; 00091 00092 // horizontal velocity and its maximum: 00093 ierr = u.begin_access(); CHKERRQ(ierr); 00094 ierr = v.begin_access(); CHKERRQ(ierr); 00095 ierr = vel_input->begin_access(); CHKERRQ(ierr); 00096 PetscReal my_u_max = 0, my_v_max = 0; 00097 for (PetscInt i = grid.xs; i < grid.xs+grid.xm; ++i) { 00098 for (PetscInt j = grid.ys; j < grid.ys+grid.ym; ++j) { 00099 ierr = u.setColumn(i,j, (*vel_input)(i,j).u); CHKERRQ(ierr); 00100 ierr = v.setColumn(i,j, (*vel_input)(i,j).v); CHKERRQ(ierr); 00101 00102 my_u_max = PetscMax(my_u_max, PetscAbs((*vel_input)(i,j).u)); 00103 my_v_max = PetscMax(my_v_max, PetscAbs((*vel_input)(i,j).u)); 00104 } 00105 } 00106 ierr = vel_input->end_access(); CHKERRQ(ierr); 00107 ierr = v.end_access(); CHKERRQ(ierr); 00108 ierr = u.end_access(); CHKERRQ(ierr); 00109 00110 ierr = PetscGlobalMax(&my_u_max, &u_max, grid.com); CHKERRQ(ierr); 00111 ierr = PetscGlobalMax(&my_v_max, &v_max, grid.com); CHKERRQ(ierr); 00112 00113 // diffusive flux and maximum diffusivity 00114 ierr = diffusive_flux.set(0.0); CHKERRQ(ierr); 00115 D_max = 0.0; 00116 00117 // strain heating 00118 ierr = compute_sigma(D2_input, Sigma); CHKERRQ(ierr); 00119 00120 return 0; 00121 } 00122 00123 00125 00132 PetscErrorCode SSBM_Trivial::compute_sigma(IceModelVec2S *D2_input, IceModelVec3 &result) { 00133 PetscErrorCode ierr; 00134 PetscScalar *E, *sigma; 00135 const PetscReal 00136 n_glen = ice.exponent(), 00137 Sig_pow = (1.0 + n_glen) / (2.0 * n_glen), 00138 enhancement_factor = config.get("enhancement_factor"), 00139 standard_gravity = config.get("standard_gravity"); 00140 00141 ierr = enthalpy->begin_access(); CHKERRQ(ierr); 00142 ierr = result.begin_access(); CHKERRQ(ierr); 00143 ierr = thickness->begin_access(); CHKERRQ(ierr); 00144 ierr = D2_input->begin_access(); CHKERRQ(ierr); 00145 00146 for (PetscInt i = grid.xs; i < grid.xs+grid.xm; ++i) { 00147 for (PetscInt j = grid.ys; j < grid.ys+grid.ym; ++j) { 00148 ierr = enthalpy->getInternalColumn(i,j,&E); CHKERRQ(ierr); 00149 ierr = result.getInternalColumn(i,j,&sigma); CHKERRQ(ierr); 00150 00151 PetscReal thk = (*thickness)(i,j); 00152 // in the ice: 00153 PetscInt ks = grid.kBelowHeight(thk); 00154 for (PetscInt k=0; k<ks; ++k) { 00155 // Use hydrostatic pressure; presumably this is not quite right in context 00156 // of shelves and streams; here we hard-wire the Glen law 00157 PetscReal depth = thk - grid.zlevels[k], 00158 pressure = ice.rho * standard_gravity * depth, // FIXME task #7297 00159 // Account for the enhancement factor. 00160 // Note, enhancement factor is not used in SSA anyway. 00161 // Should we get rid of it completely? If not, what is most consistent here? 00162 BofT = ice.hardnessParameter_from_enth(E[k], pressure) * pow(enhancement_factor,-1/n_glen); 00163 sigma[k] = 2.0 * BofT * pow((*D2_input)(i,j), Sig_pow); 00164 } 00165 00166 // above the ice: 00167 for (PetscInt k=ks+1; k<grid.Mz; ++k) { 00168 sigma[k] = 0.0; 00169 } 00170 } 00171 } 00172 00173 ierr = D2_input->end_access(); CHKERRQ(ierr); 00174 ierr = thickness->end_access(); CHKERRQ(ierr); 00175 ierr = result.end_access(); CHKERRQ(ierr); 00176 ierr = enthalpy->end_access(); CHKERRQ(ierr); 00177 00178 return 0; 00179 }
1.7.3