|
PISM, A Parallel Ice Sheet Model stable 0.4.1779
|
00001 // Copyright (C) 2008-2011 Ed Bueler, Constantine Khroulev, Ricarda Winkelmann, 00002 // Gudfinna Adalgeirsdottir and Andy Aschwanden 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 // Implementation of forcing using spatially-variable time-dependent air 00021 // temperature and precipitaiton anomalies (-atmosphere ...,forcing). 00022 00023 #include "PISMAtmosphere.hh" 00024 00025 PAForcing::PAForcing(IceGrid &g, const NCConfigVariable &conf, PISMAtmosphereModel *input) 00026 : PAModifier(g, conf, input) { 00027 temp_anomaly = NULL; 00028 precip_anomaly = NULL; 00029 } 00030 00031 PAForcing::~PAForcing() { 00032 delete temp_anomaly; 00033 delete precip_anomaly; 00034 } 00035 00036 PetscErrorCode PAForcing::init(PISMVars &vars) { 00037 PetscErrorCode ierr; 00038 PetscTruth temp_anomaly_set, precip_anomaly_set; 00039 char temp_anomalies_file[PETSC_MAX_PATH_LEN], 00040 precip_anomalies_file[PETSC_MAX_PATH_LEN]; 00041 00042 ierr = input_model->init(vars); CHKERRQ(ierr); 00043 00044 ierr = verbPrintf(2, grid.com, 00045 "* Initializing air temperature and precipitation forcing...\n"); CHKERRQ(ierr); 00046 00047 ierr = PetscOptionsBegin(grid.com, "", 00048 "Air temperature and precipitation forcing", ""); CHKERRQ(ierr); 00049 00050 ierr = PetscOptionsString("-anomaly_temp", 00051 "Specifies the air temperature anomalies file", 00052 "", "", 00053 temp_anomalies_file, PETSC_MAX_PATH_LEN, &temp_anomaly_set); 00054 CHKERRQ(ierr); 00055 ierr = PetscOptionsString("-anomaly_precip", 00056 "Specifies the precipitation anomalies file", 00057 "", "", 00058 precip_anomalies_file, PETSC_MAX_PATH_LEN, &precip_anomaly_set); 00059 CHKERRQ(ierr); 00060 00061 ierr = PetscOptionsEnd(); CHKERRQ(ierr); 00062 00063 if (! (temp_anomaly_set || precip_anomaly_set) ) { 00064 ierr = verbPrintf(2, grid.com, " NOTE: Forcing is inactive...\n"); CHKERRQ(ierr); 00065 } 00066 00067 // check on whether we should read temperature anomalies 00068 if (temp_anomaly_set) { 00069 00070 ierr = verbPrintf(2,grid.com, 00071 " reading air temperature anomalies from %s ...\n", 00072 temp_anomalies_file); CHKERRQ(ierr); 00073 temp_anomaly = new IceModelVec2T; 00074 temp_anomaly->set_n_records((unsigned int) config.get("climate_forcing_buffer_size")); 00075 ierr = temp_anomaly->create(grid, "temp_anomaly", false); CHKERRQ(ierr); 00076 ierr = temp_anomaly->set_attrs("climate_forcing", 00077 "near-surface temperature anomalies", 00078 "Kelvin", ""); CHKERRQ(ierr); 00079 ierr = temp_anomaly->init(temp_anomalies_file); CHKERRQ(ierr); 00080 } 00081 00082 // check on whether we should read precipitation anomalies 00083 if (precip_anomaly_set) { 00084 ierr = verbPrintf(2,grid.com, 00085 " reading ice-equivalent precipitation rate anomalies from %s ...\n", 00086 precip_anomalies_file); CHKERRQ(ierr); 00087 00088 precip_anomaly = new IceModelVec2T; 00089 precip_anomaly->set_n_records((unsigned int) config.get("climate_forcing_buffer_size")); 00090 ierr = precip_anomaly->create(grid, "precip_anomaly", false); CHKERRQ(ierr); 00091 ierr = precip_anomaly->set_attrs("climate_forcing", 00092 "anomalies of ice-equivalent precipitation rate", 00093 "m s-1", ""); CHKERRQ(ierr); 00094 ierr = precip_anomaly->init(precip_anomalies_file); CHKERRQ(ierr); 00095 ierr = precip_anomaly->set_glaciological_units("m year-1"); 00096 precip_anomaly->write_in_glaciological_units = true; 00097 } 00098 00099 airtemp_var.init_2d("airtemp_plus_forcing", grid); 00100 airtemp_var.set_string("pism_intent", "diagnostic"); 00101 airtemp_var.set_string("long_name", 00102 "snapshot of the near-surface air temperature (including forcing)"); 00103 ierr = airtemp_var.set_units("K"); CHKERRQ(ierr); 00104 00105 return 0; 00106 } 00107 00108 PetscErrorCode PAForcing::max_timestep(PetscReal t_years, 00109 PetscReal &dt_years) { 00110 PetscErrorCode ierr; 00111 PetscReal max_dt = -1; 00112 00113 ierr = input_model->max_timestep(t_years, dt_years); CHKERRQ(ierr); 00114 00115 if (temp_anomaly != NULL) { 00116 max_dt = temp_anomaly->max_timestep(t_years); 00117 00118 if (dt_years > 0) { 00119 if (max_dt > 0) 00120 dt_years = PetscMin(max_dt, dt_years); 00121 } 00122 else dt_years = max_dt; 00123 } 00124 00125 if (precip_anomaly != NULL) { 00126 dt_years = precip_anomaly->max_timestep(t_years); 00127 00128 if (dt_years > 0) { 00129 if (max_dt > 0) 00130 dt_years = PetscMin(max_dt, dt_years); 00131 } 00132 else dt_years = max_dt; 00133 } 00134 00135 return 0; 00136 } 00137 00138 void PAForcing::add_vars_to_output(string keyword, set<string> &result) { 00139 if (keyword == "big") { 00140 result.insert("airtemp_plus_forcing"); 00141 00142 if (temp_anomaly != NULL) 00143 result.insert("temp_anomaly"); 00144 00145 if (precip_anomaly != NULL) 00146 result.insert("precip_anomaly"); 00147 } 00148 00149 input_model->add_vars_to_output(keyword, result); 00150 } 00151 00152 PetscErrorCode PAForcing::define_variables(set<string> vars, const NCTool &nc, nc_type nctype) { 00153 PetscErrorCode ierr; 00154 int varid; 00155 00156 ierr = input_model->define_variables(vars, nc, nctype); CHKERRQ(ierr); 00157 00158 if (set_contains(vars, "airtemp_plus_forcing")) { 00159 ierr = airtemp_var.define(nc, varid, nctype, false); CHKERRQ(ierr); 00160 } 00161 00162 if (temp_anomaly != NULL) { 00163 if (set_contains(vars, "temp_anomaly")) { 00164 ierr = temp_anomaly->define(nc, nctype); CHKERRQ(ierr); 00165 } 00166 } 00167 00168 if (precip_anomaly != NULL) { 00169 if (set_contains(vars, "precip_anomaly")) { 00170 ierr = precip_anomaly->define(nc, nctype); CHKERRQ(ierr); 00171 } 00172 } 00173 00174 return 0; 00175 } 00176 00177 00178 PetscErrorCode PAForcing::write_variables(set<string> vars, string filename) { 00179 PetscErrorCode ierr; 00180 double T = t + 0.5 * dt; 00181 00182 if (set_contains(vars, "airtemp_plus_forcing")) { 00183 IceModelVec2S airtemp; 00184 ierr = airtemp.create(grid, "airtemp_plus_forcing", false); CHKERRQ(ierr); 00185 ierr = airtemp.set_metadata(airtemp_var, 0); CHKERRQ(ierr); 00186 00187 ierr = temp_snapshot(airtemp); CHKERRQ(ierr); 00188 00189 ierr = airtemp.write(filename.c_str()); CHKERRQ(ierr); 00190 vars.erase("airtemp_plus_forcing"); 00191 } 00192 00193 if (temp_anomaly != NULL) { 00194 if (set_contains(vars, "temp_anomaly")) { 00195 ierr = temp_anomaly->update(T, 0); CHKERRQ(ierr); 00196 ierr = temp_anomaly->interp(T); CHKERRQ(ierr); 00197 ierr = temp_anomaly->write(filename.c_str()); CHKERRQ(ierr); 00198 vars.erase("temp_anomaly"); 00199 } 00200 } 00201 00202 if (precip_anomaly != NULL) { 00203 if (set_contains(vars, "precip_anomaly")) { 00204 ierr = precip_anomaly->update(T, 0); CHKERRQ(ierr); 00205 ierr = precip_anomaly->interp(T); CHKERRQ(ierr); 00206 ierr = precip_anomaly->write(filename.c_str()); CHKERRQ(ierr); 00207 vars.erase("precip_anomaly"); 00208 } 00209 00210 } 00211 00212 ierr = input_model->write_variables(vars, filename); CHKERRQ(ierr); 00213 00214 return 0; 00215 } 00216 00217 PetscErrorCode PAForcing::update(PetscReal t_years, PetscReal dt_years) { 00218 PetscErrorCode ierr; 00219 00220 if ((fabs(t_years - t) < 1e-12) && 00221 (fabs(dt_years - dt) < 1e-12)) 00222 return 0; 00223 00224 t = t_years; 00225 dt = dt_years; 00226 00227 ierr = input_model->update(t_years, dt_years); CHKERRQ(ierr); 00228 00229 if (temp_anomaly != NULL) { 00230 ierr = temp_anomaly->update(t_years, dt_years); CHKERRQ(ierr); 00231 } 00232 00233 if (precip_anomaly != NULL) { 00234 ierr = precip_anomaly->update(t_years, dt_years); CHKERRQ(ierr); 00235 } 00236 00237 return 0; 00238 } 00239 00240 PetscErrorCode PAForcing::mean_precip(IceModelVec2S &result) { 00241 PetscErrorCode ierr; 00242 00243 ierr = input_model->mean_precip(result); CHKERRQ(ierr); 00244 00245 if (precip_anomaly != NULL) { 00246 string history = "added average over time-step of precipitation anomalies\n" + result.string_attr("history"); 00247 00248 double anomaly; 00249 00250 ierr = precip_anomaly->begin_access(); CHKERRQ(ierr); 00251 ierr = result.begin_access(); CHKERRQ(ierr); 00252 for (PetscInt i = grid.xs; i<grid.xs+grid.xm; ++i) { 00253 for (PetscInt j = grid.ys; j<grid.ys+grid.ym; ++j) { 00254 ierr = precip_anomaly->average(i, j, t, dt, anomaly); CHKERRQ(ierr); 00255 result(i,j) += anomaly; 00256 } 00257 } 00258 ierr = result.end_access(); CHKERRQ(ierr); 00259 ierr = precip_anomaly->end_access(); CHKERRQ(ierr); 00260 00261 ierr = result.set_attr("history", history); CHKERRQ(ierr); 00262 } 00263 00264 return 0; 00265 } 00266 00267 PetscErrorCode PAForcing::mean_annual_temp(IceModelVec2S &result) { 00268 PetscErrorCode ierr; 00269 00270 ierr = input_model->mean_annual_temp(result); CHKERRQ(ierr); 00271 00272 if (temp_anomaly != NULL) { 00273 string history = "added annual average of temperature anomalies\n" 00274 + result.string_attr("history"); 00275 // if the temperature anomaly has sub-annual cycle we need to average it 00276 // FIXME: if the anomaly is provided with a flag indicating it is already 00277 // mean annual, then we could save some work 00278 00279 // average over the year starting at t 00280 ierr = temp_anomaly->update(t, 1.0); CHKERRQ(ierr); 00281 PetscScalar av_ij; 00282 ierr = temp_anomaly->begin_access(); CHKERRQ(ierr); 00283 ierr = result.begin_access(); CHKERRQ(ierr); 00284 for (PetscInt i = grid.xs; i<grid.xs+grid.xm; ++i) { 00285 for (PetscInt j = grid.ys; j<grid.ys+grid.ym; ++j) { 00286 ierr = temp_anomaly->average(i,j,t,1.0,av_ij); CHKERRQ(ierr); 00287 result(i,j) += av_ij; 00288 } 00289 } 00290 ierr = temp_anomaly->end_access(); CHKERRQ(ierr); 00291 ierr = result.end_access(); CHKERRQ(ierr); 00292 00293 ierr = result.set_attr("history", history); CHKERRQ(ierr); 00294 } 00295 00296 return 0; 00297 } 00298 00299 PetscErrorCode PAForcing::begin_pointwise_access() { 00300 PetscErrorCode ierr; 00301 00302 ierr = input_model->begin_pointwise_access(); CHKERRQ(ierr); 00303 00304 if (temp_anomaly != NULL) { 00305 ierr = temp_anomaly->begin_access(); CHKERRQ(ierr); 00306 } 00307 00308 return 0; 00309 } 00310 00311 PetscErrorCode PAForcing::end_pointwise_access() { 00312 PetscErrorCode ierr; 00313 00314 ierr = input_model->end_pointwise_access(); CHKERRQ(ierr); 00315 00316 if (temp_anomaly != NULL) { 00317 ierr = temp_anomaly->end_access(); CHKERRQ(ierr); 00318 } 00319 00320 return 0; 00321 } 00322 00323 PetscErrorCode PAForcing::temp_time_series(int i, int j, int N, 00324 PetscReal *ts, PetscReal *values) { 00325 PetscErrorCode ierr; 00326 00327 ierr = input_model->temp_time_series(i, j, N, ts, values); CHKERRQ(ierr); 00328 00329 if (temp_anomaly != NULL) { 00330 PetscScalar *tmp = new PetscScalar[N]; 00331 00332 ierr = temp_anomaly->interp(i, j, N, ts, tmp); CHKERRQ(ierr); 00333 00334 for (PetscInt k = 0; k < N; k++) 00335 values[k] += tmp[k]; 00336 00337 delete tmp; 00338 } 00339 00340 return 0; 00341 } 00342 00343 PetscErrorCode PAForcing::temp_snapshot(IceModelVec2S &result) { 00344 PetscErrorCode ierr; 00345 00346 ierr = input_model->temp_snapshot(result); CHKERRQ(ierr); 00347 00348 if (temp_anomaly != NULL) { 00349 string history = "added temperature anomalies at midpoint of time-step\n" 00350 + result.string_attr("history"); 00351 00352 ierr = temp_anomaly->update(t, dt); CHKERRQ(ierr); 00353 ierr = temp_anomaly->interp(t); CHKERRQ(ierr); 00354 ierr = result.add(1.0, *temp_anomaly); CHKERRQ(ierr); 00355 00356 ierr = result.set_attr("history", history); CHKERRQ(ierr); 00357 } 00358 00359 return 0; 00360 }
1.7.3