|
PISM, A Parallel Ice Sheet Model stable 0.4.1779
|
00001 // Copyright (C) 2008-2011 Ed Bueler, Constantine Khroulev, Ricarda Winkelmann, 00002 // Gudfinna Adalgeirsdottir, Andy Aschwanden and Torsten Albrecht 00003 // 00004 // This file is part of PISM. 00005 // 00006 // PISM is free software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the Free Software 00008 // Foundation; either version 2 of the License, or (at your option) any later 00009 // version. 00010 // 00011 // PISM is distributed in the hope that it will be useful, but WITHOUT ANY 00012 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00013 // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 00014 // details. 00015 // 00016 // You should have received a copy of the GNU General Public License 00017 // along with PISM; if not, write to the Free Software 00018 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00019 00020 #include "PISMOcean.hh" 00021 00022 POConstantPIK::POConstantPIK(IceGrid &g, const NCConfigVariable &conf) 00023 : PISMOceanModel(g, conf) { 00024 00025 shelfbmassflux.init_2d("shelfbmassflux", g); 00026 shelfbmassflux.set_string("pism_intent", "climate_state"); 00027 shelfbmassflux.set_string("long_name", 00028 "ice mass flux from ice shelf base (positive flux is loss from ice shelf)"); 00029 shelfbmassflux.set_units("m s-1"); 00030 shelfbmassflux.set_glaciological_units("m year-1"); 00031 00032 shelfbtemp.init_2d("shelfbtemp", g); 00033 shelfbtemp.set_string("pism_intent", "climate_state"); 00034 shelfbtemp.set_string("long_name", 00035 "absolute temperature at ice shelf base"); 00036 shelfbtemp.set_units("Kelvin"); 00037 } 00038 00039 PetscErrorCode POConstantPIK::init(PISMVars &vars) { 00040 PetscErrorCode ierr; 00041 00042 if (!config.get_flag("is_dry_simulation")) { 00043 ierr = verbPrintf(2, grid.com, "* Initializing the constant ocean model...\n"); CHKERRQ(ierr); 00044 } 00045 00046 ice_thickness = dynamic_cast<IceModelVec2S*>(vars.get("land_ice_thickness")); 00047 if (!ice_thickness) { SETERRQ(1, "ERROR: ice thickness is not available"); } 00048 00049 return 0; 00050 } 00051 00052 PetscErrorCode POConstantPIK::sea_level_elevation(PetscReal &result) { 00053 result = sea_level; 00054 return 0; 00055 } 00056 00057 PetscErrorCode POConstantPIK::shelf_base_temperature(IceModelVec2S &result) { 00058 PetscErrorCode ierr; 00059 00060 const PetscScalar T0 = config.get("water_melting_point_temperature"), // K 00061 beta_CC_grad = config.get("beta_CC") * config.get("ice_density") * config.get("standard_gravity"), // K m-1 00062 ice_rho = config.get("ice_density"), 00063 sea_water_rho = config.get("sea_water_density"); 00064 00065 PetscScalar **H; 00066 ierr = ice_thickness->get_array(H); CHKERRQ(ierr); 00067 ierr = result.begin_access(); CHKERRQ(ierr); 00068 for (PetscInt i=grid.xs; i<grid.xs+grid.xm; ++i) { 00069 for (PetscInt j=grid.ys; j<grid.ys+grid.ym; ++j) { 00070 const PetscScalar shelfbaseelev = - ( ice_rho / sea_water_rho ) * H[i][j]; // FIXME task #7297 00071 // temp is set to melting point at depth 00072 result(i,j) = T0 + beta_CC_grad * shelfbaseelev; // base elev negative here so is below T0 00073 } 00074 } 00075 ierr = ice_thickness->end_access(); CHKERRQ(ierr); 00076 ierr = result.end_access(); CHKERRQ(ierr); 00077 00078 return 0; 00079 } 00080 00082 PetscErrorCode POConstantPIK::shelf_base_mass_flux(IceModelVec2S &result) { 00083 PetscErrorCode ierr; 00084 00085 PetscReal L = config.get("water_latent_heat_fusion"), 00086 rho_ocean = config.get("sea_water_density"), 00087 rho_ice = config.get("ice_density"); 00088 //beta_CC_grad = config.get("beta_CC") * config.get("ice_density") * config.get("standard_gravity"); 00089 // K/m Clausius-Clapeyron gradient 00090 const PetscScalar c_p_ocean = 3974.0, // J/(K*kg), specific heat capacity of ocean mixed layer 00091 gamma_T = 1e-4; // m/s, thermal exchange velocity //FIXME gamma_T should be a function of the friction velocity, not a const 00092 00093 PetscScalar T_water = -1.7, //Default in PISM-PIK 00094 T_ocean = 273.15 + T_water; 00095 00096 // following has units: J m-2 s-1 / (J kg-1 * kg m-3) = m s-1 00097 // PetscReal meltrate = config.get("ocean_sub_shelf_heat_flux_into_ice") / (L * rho_ice); // m s-1 00098 00099 PetscReal meltfactor = 1e-4;; //default, will be set via option 00100 00101 PetscScalar **H; 00102 ierr = ice_thickness->get_array(H); CHKERRQ(ierr); 00103 ierr = result.begin_access(); CHKERRQ(ierr); 00104 00105 00106 for (PetscInt i=grid.xs; i<grid.xs+grid.xm; ++i) { 00107 for (PetscInt j=grid.ys; j<grid.ys+grid.ym; ++j) { 00108 00109 // compute T_f[i][j] according to beckmann_goosse03, which has the meaning of the freezing temperature of the ocean water directly under the shelf, (of salinity 35psu) [this is related to the Pressure Melting Temperature, see beckmann_goosse03 eq. 2 for details] 00110 PetscScalar shelfbaseelev = - (rho_ice / rho_ocean) * H[i][j], 00111 T_f= 273.15+ (0.0939 -0.057 * 35.0 + 7.64e-4 * shelfbaseelev); // add 273.15 to get it in Kelvin... 35 is the salinity 00112 00113 // compute ocean_heat_flux according to beckmann_goosse03 00114 // positive, if T_oc > T_ice ==> heat flux FROM ocean TO ice 00115 PetscScalar oceanheatflux = meltfactor * rho_ocean * c_p_ocean * gamma_T * (T_ocean - T_f); // in W/m^2 //TODO T_ocean -> field! 00116 00117 // shelfbmassflux is positive if ice is freezing on; here it is always negative: 00118 // same sign as OceanHeatFlux... positive if massflux FROM ice TO ocean 00119 //result(i,j) = oceanheatflux / (L * rho_ice) * secpera; // m a-1 00120 result(i,j) = oceanheatflux / (L * rho_ice); // m s-1 00121 00122 } 00123 } 00124 00125 ierr = ice_thickness->end_access(); CHKERRQ(ierr); 00126 ierr = result.end_access(); CHKERRQ(ierr); 00127 00128 return 0; 00129 } 00130 00131 void POConstantPIK::add_vars_to_output(string keyword, set<string> &result) { 00132 if (keyword != "small") { 00133 result.insert("shelfbtemp"); 00134 result.insert("shelfbmassflux"); 00135 } 00136 } 00137 00138 PetscErrorCode POConstantPIK::define_variables(set<string> vars, const NCTool &nc, 00139 nc_type nctype) { 00140 PetscErrorCode ierr; 00141 int varid; 00142 00143 if (set_contains(vars, "shelfbtemp")) { 00144 ierr = shelfbtemp.define(nc, varid, nctype, true); CHKERRQ(ierr); 00145 } 00146 00147 if (set_contains(vars, "shelfbmassflux")) { 00148 ierr = shelfbmassflux.define(nc, varid, nctype, true); CHKERRQ(ierr); 00149 } 00150 00151 return 0; 00152 } 00153 00154 PetscErrorCode POConstantPIK::write_variables(set<string> vars, string filename) { 00155 PetscErrorCode ierr; 00156 IceModelVec2S tmp; 00157 00158 if (set_contains(vars, "shelfbtemp")) { 00159 if (!tmp.was_created()) { 00160 ierr = tmp.create(grid, "tmp", false); CHKERRQ(ierr); 00161 } 00162 00163 ierr = tmp.set_metadata(shelfbtemp, 0); CHKERRQ(ierr); 00164 ierr = shelf_base_temperature(tmp); CHKERRQ(ierr); 00165 ierr = tmp.write(filename.c_str()); CHKERRQ(ierr); 00166 } 00167 00168 if (set_contains(vars, "shelfbmassflux")) { 00169 if (!tmp.was_created()) { 00170 ierr = tmp.create(grid, "tmp", false); CHKERRQ(ierr); 00171 } 00172 00173 ierr = tmp.set_metadata(shelfbmassflux, 0); CHKERRQ(ierr); 00174 ierr = shelf_base_mass_flux(tmp); CHKERRQ(ierr); 00175 ierr = tmp.write(filename.c_str()); CHKERRQ(ierr); 00176 } 00177 00178 return 0; 00179 }
1.7.3