|
PISM, A Parallel Ice Sheet Model stable 0.4.1779
|
00001 // Copyright (C) 2011 Andy Aschwanden and 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 "PSElevation.hh" 00020 #include "PISMIO.hh" 00021 00022 00024 00025 PetscErrorCode PSElevation::init(PISMVars &vars) { 00026 PetscErrorCode ierr; 00027 00028 ierr = verbPrintf(2, grid.com, 00029 "* Initializing the constant-in-time surface processes model PSElevation. Setting...\n"); CHKERRQ(ierr); 00030 00031 ierr = PetscOptionsBegin(grid.com, "", "Elevation-dependent surface model options", ""); CHKERRQ(ierr); 00032 { 00033 PetscInt Nartmparam= 4; 00034 PetscReal artmarray[4] = {-5,0,1325,1350}; 00035 00036 ierr = PetscOptionsGetRealArray(PETSC_NULL, "-artm", artmarray, &Nartmparam, &elev_artm_set); 00037 CHKERRQ(ierr); 00038 00039 artm_min = convert(artmarray[0],"Celsius","Kelvin"); 00040 artm_max = convert(artmarray[1],"Celsius","Kelvin"); 00041 z_artm_min = artmarray[2]; 00042 z_artm_max = artmarray[3]; 00043 00044 PetscInt Nacabparam= 5; 00045 PetscReal acabarray[5] = {-3,4,1100,1450,1700}; 00046 00047 ierr = PetscOptionsGetRealArray(PETSC_NULL, "-acab", acabarray, &Nacabparam, &elev_acab_set); 00048 CHKERRQ(ierr); 00049 00050 acab_min = convert(acabarray[0],"m year-1","m s-1"); 00051 acab_max = convert(acabarray[1],"m year-1","m s-1"); 00052 z_acab_min = acabarray[2]; 00053 z_ELA = acabarray[3]; 00054 z_acab_max = acabarray[4]; 00055 00056 PetscInt Nlimitsparam= 2; 00057 PetscReal limitsarray[2] = {0,0}; 00058 00059 ierr = PetscOptionsGetRealArray(PETSC_NULL, "-acab_limits", limitsarray, &Nlimitsparam, &acab_limits_set); 00060 CHKERRQ(ierr); 00061 00062 if (acab_limits_set) 00063 { 00064 acab_limit_min = convert(limitsarray[0],"m year-1","m s-1"); 00065 acab_limit_max = convert(limitsarray[1],"m year-1","m s-1"); 00066 } 00067 else 00068 { 00069 acab_limit_min = acab_min; 00070 acab_limit_max = acab_max; 00071 } 00072 00073 } 00074 ierr = PetscOptionsEnd(); CHKERRQ(ierr); 00075 00076 ierr = verbPrintf(3, grid.com, 00077 " temperature at %.0f m a.s.l. = %.2f deg C\n" 00078 " temperature at %.0f m a.s.l. = %.2f deg C\n" 00079 " mass balance below %.0f m a.s.l. = %.2f m/a\n" 00080 " mass balance at %.0f m a.s.l. = %.2f m/a\n" 00081 " mass balance at %.0f m a.s.l. = %.2f m/a\n" 00082 " mass balance above %.0f m a.s.l. = %.2f m/a\n" 00083 " equilibrium line altitude z_ELA = %.2f m a.s.l.\n", 00084 z_artm_min, artm_min, z_artm_max, artm_max, z_acab_min, convert(acab_limit_min,"m s-1","m year-1"), z_acab_min, acab_min, z_acab_max, convert(acab_max,"m s-1","m year-1"), z_acab_max, convert(acab_limit_max,"m s-1","m year-1"), z_ELA); CHKERRQ(ierr); 00085 00086 // get access to ice upper surface elevation 00087 usurf = dynamic_cast<IceModelVec2S*>(vars.get("surface_altitude")); 00088 if (!usurf) SETERRQ(12, "ERROR: 'usurf' is not available or is wrong type in dictionary"); 00089 00090 00091 // allocate NCSpatialVariables for storing temperature and surface mass balance fields 00092 00093 acab.init_2d("acab", grid); 00094 acab.set_string("pism_intent", "diagnostic"); 00095 acab.set_string("long_name", 00096 "ice-equivalent surface mass balance (accumulation/ablation) rate"); 00097 acab.set_string("standard_name", 00098 "land_ice_surface_specific_mass_balance"); 00099 ierr = acab.set_units("m s-1"); CHKERRQ(ierr); 00100 ierr = acab.set_glaciological_units("m year-1"); CHKERRQ(ierr); 00101 00102 artm.init_2d("artm", grid); 00103 artm.set_string("pism_intent", "diagnostic"); 00104 artm.set_string("long_name", 00105 "ice temperature at the ice surface"); 00106 ierr = artm.set_units("K"); CHKERRQ(ierr); 00107 00108 // parameterizing the ice surface temperature 'artm' 00109 ierr = verbPrintf(2, grid.com," - parameterizing the ice surface temperature 'artm' ... \n"); CHKERRQ(ierr); 00110 ierr = verbPrintf(2, grid.com, 00111 " ice temperature at the ice surface (artm) is piecewise-linear function\n" 00112 " of surface altitude (usurf):\n" 00113 " / %2.2f K for usurf < %.f m\n" 00114 " artm = | %5.2f K + %5.3f * (usurf - %.f m) for %.f m < usurf < %.f m\n" 00115 " \\ %5.2f K for %.f m < usurf\n", 00116 artm_min, z_artm_min, 00117 artm_min, (artm_max-artm_min)/(z_artm_max-z_artm_min), z_artm_min, z_artm_min, z_artm_max, 00118 artm_max, z_artm_max); CHKERRQ(ierr); 00119 00120 // parameterizing the ice surface mass balance 'acab' 00121 ierr = verbPrintf(2, grid.com," - parameterizing the ice surface mass balance 'acab' ... \n"); CHKERRQ(ierr); 00122 00123 if (acab_limits_set) 00124 { 00125 ierr = verbPrintf(2, grid.com," - option '-acab_limits' seen, limiting upper and lower bounds ... \n"); CHKERRQ(ierr); 00126 } 00127 00128 ierr = verbPrintf(2, grid.com, 00129 " surface mass balance (acab) is piecewise-linear function\n" 00130 " of surface altitue (usurf):\n" 00131 " / %5.2f m/a for usurf < %3.f m\n" 00132 " acab = | %5.3f 1/a * (usurf-%.0f m) for %3.f m < usurf < %3.f m\n" 00133 " \\ %5.3f 1/a * (usurf-%.0f m) for %3.f m < usurf < %3.f m\n" 00134 " \\ %5.2f m/a for %3.f m < usurf\n", 00135 convert(acab_limit_min,"m s-1","m year-1"), z_acab_min, 00136 convert(-acab_min,"m s-1","m year-1")/(z_ELA - z_acab_min),z_ELA, z_acab_min, z_ELA, 00137 convert(acab_max,"m s-1","m year-1")/(z_acab_max - z_ELA),z_ELA, z_ELA, z_acab_max, 00138 convert(acab_limit_max,"m s-1","m year-1"), z_acab_max); CHKERRQ(ierr); 00139 00140 00141 return 0; 00142 } 00143 00144 PetscErrorCode PSElevation::ice_surface_mass_flux(IceModelVec2S &result) { 00145 PetscErrorCode ierr; 00146 PetscReal dabdz = -acab_min/(z_ELA - z_acab_min); 00147 PetscReal dacdz = acab_max/(z_acab_max - z_ELA); 00148 string history = "elevation-dependent surface mass balance\n"; 00149 00150 ierr = result.begin_access(); CHKERRQ(ierr); 00151 ierr = usurf->begin_access(); CHKERRQ(ierr); 00152 for (PetscInt i=grid.xs; i<grid.xs+grid.xm; ++i) { 00153 for (PetscInt j=grid.ys; j<grid.ys+grid.ym; ++j) { 00154 PetscReal z = (*usurf)(i,j); 00155 if (z < z_acab_min) 00156 { 00157 result(i,j) = acab_limit_min; 00158 } 00159 else if ((z >= z_acab_min) && (z < z_ELA)) 00160 { 00161 result(i,j) = dabdz * (z - z_ELA); 00162 } 00163 else if ((z >= z_ELA) && (z <= z_acab_max)) 00164 { 00165 result(i,j) = dacdz * (z - z_ELA); 00166 } 00167 else if (z > z_acab_max) 00168 { 00169 result(i,j) = acab_limit_max; 00170 } 00171 else 00172 { 00173 SETERRQ(1,"HOW DID I GET HERE? ... ending...\n"); 00174 } 00175 ierr = verbPrintf(5, grid.com,"!!!!! z=%.2f, acab=%.2f\n",z,result(i,j)*secpera); CHKERRQ(ierr); 00176 } 00177 } 00178 ierr = usurf->end_access(); CHKERRQ(ierr); 00179 ierr = result.end_access(); CHKERRQ(ierr); 00180 00181 ierr = result.set_attr("history", history); CHKERRQ(ierr); 00182 00183 return 0; 00184 } 00185 00186 PetscErrorCode PSElevation::ice_surface_temperature(IceModelVec2S &result) { 00187 PetscErrorCode ierr; 00188 string history = "elevation-dependent ice surface temperature \n"; 00189 00190 ierr = result.begin_access(); CHKERRQ(ierr); 00191 ierr = usurf->begin_access(); CHKERRQ(ierr); 00192 PetscReal dTdz = (artm_max - artm_min)/(z_artm_max - z_artm_min); 00193 for (PetscInt i=grid.xs; i<grid.xs+grid.xm; ++i) { 00194 for (PetscInt j=grid.ys; j<grid.ys+grid.ym; ++j) { 00195 PetscReal z = (*usurf)(i,j); 00196 if (z <= z_artm_min) 00197 { 00198 result(i,j) = artm_min; 00199 } 00200 else if ((z > z_artm_min) && (z < z_artm_max)) 00201 { 00202 result(i,j) = artm_min + dTdz * (z - z_artm_min); 00203 } 00204 else if (z >= z_artm_max) 00205 { 00206 result(i,j) = artm_max; 00207 } 00208 else 00209 { 00210 SETERRQ(1,"HOW DID I GET HERE? ... ending...\n"); 00211 } 00212 ierr = verbPrintf(5, grid.com,"!!!!! z=%.2f, artm_min=%.2f, dTdz=%.2f, dz=%.2f, artm=%.2f\n",z,artm_min,dTdz,z - z_artm_min,result(i,j)); CHKERRQ(ierr); 00213 } 00214 } 00215 ierr = usurf->end_access(); CHKERRQ(ierr); 00216 ierr = result.end_access(); CHKERRQ(ierr); 00217 00218 ierr = result.set_attr("history", history); CHKERRQ(ierr); 00219 00220 return 0; 00221 } 00222 00223 void PSElevation::add_vars_to_output(string keyword, set<string> &result) { 00224 if (keyword != "small") { 00225 result.insert("artm"); 00226 result.insert("acab"); 00227 } 00228 } 00229 00230 PetscErrorCode PSElevation::define_variables(set<string> vars, const NCTool &nc, nc_type nctype) { 00231 PetscErrorCode ierr; 00232 int varid; 00233 00234 ierr = PISMSurfaceModel::define_variables(vars, nc, nctype); CHKERRQ(ierr); 00235 00236 if (set_contains(vars, "artm")) { 00237 ierr = artm.define(nc, varid, nctype, true); CHKERRQ(ierr); 00238 } 00239 00240 if (set_contains(vars, "acab")) { 00241 ierr = acab.define(nc, varid, nctype, true); CHKERRQ(ierr); 00242 } 00243 00244 return 0; 00245 } 00246 00247 PetscErrorCode PSElevation::write_variables(set<string> vars, string filename) { 00248 PetscErrorCode ierr; 00249 00250 if (set_contains(vars, "artm")) { 00251 IceModelVec2S tmp; 00252 ierr = tmp.create(grid, "artm", false); CHKERRQ(ierr); 00253 ierr = tmp.set_metadata(artm, 0); CHKERRQ(ierr); 00254 00255 ierr = ice_surface_temperature(tmp); CHKERRQ(ierr); 00256 00257 ierr = tmp.write(filename.c_str()); CHKERRQ(ierr); 00258 } 00259 00260 if (set_contains(vars, "acab")) { 00261 IceModelVec2S tmp; 00262 ierr = tmp.create(grid, "acab", false); CHKERRQ(ierr); 00263 ierr = tmp.set_metadata(acab, 0); CHKERRQ(ierr); 00264 00265 ierr = ice_surface_mass_flux(tmp); CHKERRQ(ierr); 00266 tmp.write_in_glaciological_units = true; 00267 ierr = tmp.write(filename.c_str()); CHKERRQ(ierr); 00268 } 00269 00270 return 0; 00271 }
1.7.3