|
PISM, A Parallel Ice Sheet Model stable 0.4.1779
|
00001 // Copyright (C) 2011 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 // Implementation of surface and atmosphere models reading spatially-variable 00020 // time-dependent B.C. data from a file (-surface given and -atmosphere given). 00021 00022 #ifndef _PASDIRECTFORCING_H_ 00023 #define _PASDIRECTFORCING_H_ 00024 00025 #include "PISMSurface.hh" 00026 #include "PISMAtmosphere.hh" 00027 #include "iceModelVec2T.hh" 00028 00029 template <class Model> 00030 class PDirectForcing : public Model 00031 { 00032 public: 00033 PDirectForcing(IceGrid &g, const NCConfigVariable &conf) 00034 : Model(g, conf) {} 00035 00036 virtual ~PDirectForcing() {} 00037 00038 virtual PetscErrorCode max_timestep(PetscReal t_years, PetscReal &dt_years) 00039 { 00040 PetscReal max_dt = -1; 00041 00042 // "Periodize" the climate: 00043 t_years = my_mod(t_years); 00044 00045 dt_years = temp.max_timestep(t_years); 00046 00047 max_dt = smb.max_timestep(t_years); 00048 00049 if (dt_years > 0) { 00050 if (max_dt > 0) 00051 dt_years = PetscMin(max_dt, dt_years); 00052 } 00053 else dt_years = max_dt; 00054 00055 // If the user asked for periodized climate, limit time-steps so that PISM 00056 // never tries to average data over an interval that begins in one period and 00057 // ends in the next one. 00058 if (bc_period > 1e-6) 00059 dt_years = PetscMin(dt_years, bc_period - t_years); 00060 00061 return 0; 00062 } 00063 00064 virtual void add_vars_to_output(string keyword, set<string> &result) 00065 { 00066 if (keyword != "small") { 00067 result.insert(temp_name); 00068 result.insert(smb_name); 00069 } 00070 } 00071 00072 virtual PetscErrorCode define_variables(set<string> vars, const NCTool &nc, nc_type nctype) 00073 { 00074 PetscErrorCode ierr; 00075 00076 if (set_contains(vars, temp_name)) { 00077 ierr = temp.define(nc, nctype); CHKERRQ(ierr); 00078 } 00079 00080 if (set_contains(vars, smb_name)) { 00081 ierr = smb.define(nc, nctype); CHKERRQ(ierr); 00082 } 00083 00084 return 0; 00085 } 00086 00087 virtual PetscErrorCode write_variables(set<string> vars, string fname) 00088 { 00089 PetscErrorCode ierr; 00090 00091 if (set_contains(vars, temp_name)) { 00092 ierr = temp.write(fname.c_str()); CHKERRQ(ierr); 00093 } 00094 00095 if (set_contains(vars, smb_name)) { 00096 ierr = smb.write(fname.c_str()); CHKERRQ(ierr); 00097 } 00098 00099 return 0; 00100 } 00101 00102 protected: 00103 IceModelVec2T temp, smb; 00104 string filename, temp_name, smb_name; 00105 00106 PetscReal bc_period, bc_reference_year; 00107 bool enable_time_averaging; 00108 00109 PetscErrorCode process_options() 00110 { 00111 PetscErrorCode ierr; 00112 bool bc_file_set, bc_period_set, bc_ref_year_set; 00113 00114 bc_period = 0; 00115 bc_reference_year = 0; 00116 enable_time_averaging = false; 00117 00118 ierr = PetscOptionsBegin(Model::grid.com, "", "Direct forcing options", ""); CHKERRQ(ierr); 00119 { 00120 ierr = PISMOptionsString("-bc_file", "Specifies a file with top-surface boundary conditions", 00121 filename, bc_file_set); CHKERRQ(ierr); 00122 ierr = PISMOptionsReal("-bc_period", "Specifies the length of the climate data period", 00123 bc_period, bc_period_set); CHKERRQ(ierr); 00124 ierr = PISMOptionsReal("-bc_reference_year", "Boundary condition reference year", 00125 bc_reference_year, bc_ref_year_set); CHKERRQ(ierr); 00126 ierr = PISMOptionsIsSet("-bc_time_average", "Enable time-averaging of boundary condition data", 00127 enable_time_averaging); CHKERRQ(ierr); 00128 } 00129 ierr = PetscOptionsEnd(); CHKERRQ(ierr); 00130 00131 if (bc_file_set == false) { 00132 PetscPrintf(Model::grid.com, "PISM ERROR: option -bc_file is required.\n"); 00133 PISMEnd(); 00134 } 00135 00136 return 0; 00137 } 00138 00139 PetscErrorCode set_vec_parameters(string temp_std_name, string smb_std_name) 00140 { 00141 PetscErrorCode ierr; 00142 unsigned int buffer_size = (unsigned int) Model::config.get("climate_forcing_buffer_size"), 00143 temp_n_records = 1, smb_n_records = 1; 00144 00145 NCTool nc(Model::grid.com, Model::grid.rank); 00146 ierr = nc.open_for_reading(filename); CHKERRQ(ierr); 00147 ierr = nc.get_nrecords(temp_name, temp_std_name, temp_n_records); CHKERRQ(ierr); 00148 ierr = nc.get_nrecords(smb_name, smb_std_name, smb_n_records); CHKERRQ(ierr); 00149 ierr = nc.close(); CHKERRQ(ierr); 00150 00151 temp_n_records = PetscMin(temp_n_records, buffer_size); 00152 smb_n_records = PetscMin(smb_n_records, buffer_size); 00153 00154 if (temp_n_records < 1) { 00155 PetscPrintf(Model::grid.com, "PISM ERROR: Can't find '%s' (%s) in %s.\n", 00156 temp_name.c_str(), temp_std_name.c_str(), filename.c_str()); 00157 PISMEnd(); 00158 00159 } 00160 00161 if (smb_n_records < 1) { 00162 PetscPrintf(Model::grid.com, "PISM ERROR: Can't find '%s' (%s) in %s.\n", 00163 smb_name.c_str(), smb_std_name.c_str(), filename.c_str()); 00164 PISMEnd(); 00165 00166 } 00167 00168 temp.set_n_records(temp_n_records); 00169 smb.set_n_records(smb_n_records); 00170 00171 temp.strict_timestep_limit = ! enable_time_averaging; 00172 smb.strict_timestep_limit = ! enable_time_averaging; 00173 00174 return 0; 00175 } 00176 00177 virtual PetscErrorCode update_internal(PetscReal t_years, PetscReal dt_years) 00178 { 00179 PetscErrorCode ierr; 00180 00181 // "Periodize" the climate: 00182 t_years = my_mod(t_years); 00183 00184 if ((fabs(t_years - Model::t) < 1e-12) && 00185 (fabs(dt_years - Model::dt) < 1e-12)) 00186 return 0; 00187 00188 Model::t = t_years; 00189 Model::dt = dt_years; 00190 00191 ierr = temp.update(Model::t, Model::dt); CHKERRQ(ierr); 00192 ierr = smb.update(Model::t, Model::dt); CHKERRQ(ierr); 00193 00194 return 0; 00195 } 00196 00197 PetscReal my_mod(PetscReal input) 00198 { 00199 if (bc_period < 0.01) return input; 00200 00201 // compute time since the reference year: 00202 PetscReal delta = input - bc_reference_year; 00203 00204 // compute delta mod bc_period: 00205 return delta - floor(delta / bc_period) * bc_period; 00206 } 00207 }; 00208 00209 class PSDirectForcing : public PDirectForcing<PISMSurfaceModel> 00210 { 00211 public: 00212 PSDirectForcing(IceGrid &g, const NCConfigVariable &conf) 00213 : PDirectForcing<PISMSurfaceModel>(g, conf) 00214 { 00215 temp_name = "artm"; 00216 smb_name = "acab"; 00217 } 00218 virtual ~PSDirectForcing() {} 00219 00220 virtual void attach_atmosphere_model(PISMAtmosphereModel *input) 00221 { delete input; } 00222 00223 virtual PetscErrorCode init(PISMVars &vars); 00224 virtual PetscErrorCode update(PetscReal t_years, PetscReal dt_years); 00225 00226 virtual PetscErrorCode ice_surface_mass_flux(IceModelVec2S &result); 00227 virtual PetscErrorCode ice_surface_temperature(IceModelVec2S &result); 00228 }; 00229 00230 class PADirectForcing : public PDirectForcing<PISMAtmosphereModel> 00231 { 00232 public: 00233 PADirectForcing(IceGrid &g, const NCConfigVariable &conf) 00234 : PDirectForcing<PISMAtmosphereModel>(g, conf) 00235 { 00236 temp_name = "artm"; 00237 smb_name = "precip"; 00238 } 00239 00240 virtual ~PADirectForcing() {} 00241 00242 virtual PetscErrorCode init(PISMVars &vars); 00243 virtual PetscErrorCode update(PetscReal t_years, PetscReal dt_years); 00244 00245 virtual PetscErrorCode mean_precip(IceModelVec2S &result); 00246 virtual PetscErrorCode mean_annual_temp(IceModelVec2S &result); 00247 virtual PetscErrorCode temp_snapshot(IceModelVec2S &result); 00248 00249 virtual PetscErrorCode begin_pointwise_access(); 00250 virtual PetscErrorCode end_pointwise_access(); 00251 virtual PetscErrorCode temp_time_series(int i, int j, int N, 00252 PetscReal *ts, PetscReal *values); 00253 }; 00254 00255 #endif /* _PASDIRECTFORCING_H_ */
1.7.3