|
PISM, A Parallel Ice Sheet Model stable 0.4.1779
|
00001 // Copyright (C) 2009-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 #include "iceModel.hh" 00020 #include <sstream> 00021 #include <algorithm> 00022 #include "PISMIO.hh" 00023 00025 PetscErrorCode IceModel::init_timeseries() { 00026 PetscErrorCode ierr; 00027 bool ts_file_set, ts_times_set, ts_vars_set; 00028 string times, vars; 00029 bool append; 00030 00031 ierr = PetscOptionsBegin(grid.com, "", "Options controlling scalar diagnostic time-series", ""); CHKERRQ(ierr); 00032 { 00033 ierr = PISMOptionsString("-ts_file", "Specifies the time-series output file name", 00034 ts_filename, ts_file_set); CHKERRQ(ierr); 00035 00036 ierr = PISMOptionsString("-ts_times", "Specifies a MATLAB-style range or a list of requested times", 00037 times, ts_times_set); CHKERRQ(ierr); 00038 00039 ierr = PISMOptionsString("-ts_vars", "Specifies a comma-separated list of veriables to save", 00040 vars, ts_vars_set); CHKERRQ(ierr); 00041 00042 // default behavior is to move the file aside if it exists already; option allows appending 00043 ierr = PISMOptionsIsSet("-ts_append", append); CHKERRQ(ierr); 00044 } 00045 ierr = PetscOptionsEnd(); CHKERRQ(ierr); 00046 00047 00048 if (ts_file_set ^ ts_times_set) { 00049 ierr = PetscPrintf(grid.com, 00050 "PISM ERROR: you need to specity both -ts_file and -ts_times to save" 00051 "diagnostic time-series.\n"); 00052 CHKERRQ(ierr); 00053 PISMEnd(); 00054 } 00055 00056 // If neither -ts_filename nor -ts_times is set, we're done. 00057 if (!ts_file_set && !ts_times_set) { 00058 save_ts = false; 00059 return 0; 00060 } 00061 00062 save_ts = true; 00063 00064 ierr = parse_times(grid.com, times, ts_times); 00065 if (ierr != 0) { 00066 ierr = PetscPrintf(grid.com, "PISM ERROR: parsing the -ts_times argument failed.\n"); CHKERRQ(ierr); 00067 PISMEnd(); 00068 } 00069 00070 if (ts_times.size() == 0) { 00071 PetscPrintf(grid.com, "PISM ERROR: no argument for -ts_times option.\n"); 00072 PISMEnd(); 00073 } 00074 00075 ierr = verbPrintf(2, grid.com, "saving scalar time-series to '%s'; ", 00076 ts_filename.c_str()); CHKERRQ(ierr); 00077 00078 ierr = verbPrintf(2, grid.com, "times requested: %s\n", times.c_str()); CHKERRQ(ierr); 00079 00080 current_ts = 0; 00081 00082 00083 string var_name; 00084 if (ts_vars_set) { 00085 ierr = verbPrintf(2, grid.com, "variables requested: %s\n", vars.c_str()); CHKERRQ(ierr); 00086 istringstream arg(vars); 00087 00088 while (getline(arg, var_name, ',')) 00089 ts_vars.insert(var_name); 00090 00091 } else { 00092 var_name = config.get_string("ts_default_variables"); 00093 istringstream arg(var_name); 00094 00095 while (getline(arg, var_name, ' ')) { 00096 if (!var_name.empty()) // this ignores multiple spaces separating variable names 00097 ts_vars.insert(var_name); 00098 } 00099 } 00100 00101 00102 PISMIO nc(&grid); 00103 ierr = nc.open_for_writing(ts_filename.c_str(), (append==PETSC_TRUE), false); CHKERRQ(ierr); 00104 ierr = nc.close(); CHKERRQ(ierr); 00105 00106 ierr = create_timeseries(); CHKERRQ(ierr); 00107 00108 return 0; 00109 } 00110 00113 PetscErrorCode IceModel::create_timeseries() { 00114 00115 string time_units = "years since " + config.get_string("reference_date"); 00116 00117 if (find(ts_vars.begin(), ts_vars.end(), "ivol") != ts_vars.end()) { 00118 DiagnosticTimeseries *ivol = new DiagnosticTimeseries(&grid, "ivol", "t"); 00119 00120 ivol->set_units("m3", ""); 00121 ivol->set_dimension_units(time_units, ""); 00122 ivol->output_filename = ts_filename; 00123 00124 ivol->set_attr("long_name", "total ice volume"); 00125 ivol->set_attr("valid_min", 0.0); 00126 00127 timeseries.push_back(ivol); 00128 } 00129 00130 if (find(ts_vars.begin(), ts_vars.end(), "ivoltemp") != ts_vars.end()) { 00131 DiagnosticTimeseries *ivoltemp = new DiagnosticTimeseries(&grid, "ivoltemp", "t"); 00132 00133 ivoltemp->set_units("m3", ""); 00134 ivoltemp->set_dimension_units(time_units, ""); 00135 ivoltemp->output_filename = ts_filename; 00136 00137 ivoltemp->set_attr("long_name", "temperate ice volume"); 00138 ivoltemp->set_attr("valid_min", 0.0); 00139 00140 timeseries.push_back(ivoltemp); 00141 } 00142 00143 if (find(ts_vars.begin(), ts_vars.end(), "ivoltempf") != ts_vars.end()) { 00144 DiagnosticTimeseries *ivoltempf = new DiagnosticTimeseries(&grid, "ivoltempf", "t"); 00145 00146 ivoltempf->set_units("1", ""); 00147 ivoltempf->set_dimension_units(time_units, ""); 00148 ivoltempf->output_filename = ts_filename; 00149 00150 ivoltempf->set_attr("long_name", "temperate ice volume fraction"); 00151 ivoltempf->set_attr("valid_min", 0.0); 00152 00153 timeseries.push_back(ivoltempf); 00154 } 00155 00156 if (find(ts_vars.begin(), ts_vars.end(), "ivolcold") != ts_vars.end()) { 00157 DiagnosticTimeseries *ivolcold = new DiagnosticTimeseries(&grid, "ivolcold", "t"); 00158 00159 ivolcold->set_units("m3", ""); 00160 ivolcold->set_dimension_units(time_units, ""); 00161 ivolcold->output_filename = ts_filename; 00162 00163 ivolcold->set_attr("long_name", "cold ice volume"); 00164 ivolcold->set_attr("valid_min", 0.0); 00165 00166 timeseries.push_back(ivolcold); 00167 } 00168 00169 if (find(ts_vars.begin(), ts_vars.end(), "ivolcoldf") != ts_vars.end()) { 00170 DiagnosticTimeseries *ivolcoldf = new DiagnosticTimeseries(&grid, "ivolcoldf", "t"); 00171 00172 ivolcoldf->set_units("1", ""); 00173 ivolcoldf->set_dimension_units(time_units, ""); 00174 ivolcoldf->output_filename = ts_filename; 00175 00176 ivolcoldf->set_attr("long_name", "cold ice volume fraction"); 00177 ivolcoldf->set_attr("valid_min", 0.0); 00178 00179 timeseries.push_back(ivolcoldf); 00180 } 00181 00182 if (find(ts_vars.begin(), ts_vars.end(), "ienthalpy") != ts_vars.end()) { 00183 DiagnosticTimeseries *ienthalpy = new DiagnosticTimeseries(&grid, "ienthalpy", "t"); 00184 00185 ienthalpy->set_units("J", ""); 00186 ienthalpy->set_dimension_units(time_units, ""); 00187 ienthalpy->output_filename = ts_filename; 00188 00189 ienthalpy->set_attr("long_name", "total ice enthalpy"); 00190 ienthalpy->set_attr("valid_min", 0.0); 00191 00192 timeseries.push_back(ienthalpy); 00193 } 00194 00195 if (find(ts_vars.begin(), ts_vars.end(), "imass") != ts_vars.end()) { 00196 DiagnosticTimeseries *imass = new DiagnosticTimeseries(&grid, "imass", "t"); 00197 00198 imass->set_units("kg", ""); 00199 imass->set_dimension_units(time_units, ""); 00200 imass->output_filename = ts_filename; 00201 00202 imass->set_attr("long_name", "total ice mass"); 00203 imass->set_attr("valid_min", 0.0); 00204 00205 timeseries.push_back(imass); 00206 } 00207 00208 if (find(ts_vars.begin(), ts_vars.end(), "iarea") != ts_vars.end()) { 00209 DiagnosticTimeseries *iarea = new DiagnosticTimeseries(&grid, "iarea", "t"); 00210 00211 iarea->set_units("m2", ""); 00212 iarea->set_dimension_units(time_units, ""); 00213 iarea->output_filename = ts_filename; 00214 00215 iarea->set_attr("long_name", "ice area"); 00216 iarea->set_attr("valid_min", 0.0); 00217 00218 timeseries.push_back(iarea); 00219 } 00220 00221 if (find(ts_vars.begin(), ts_vars.end(), "iareatemp") != ts_vars.end()) { 00222 DiagnosticTimeseries *iareatemp = new DiagnosticTimeseries(&grid, "iareatemp", "t"); 00223 00224 iareatemp->set_units("m2", ""); 00225 iareatemp->set_dimension_units(time_units, ""); 00226 iareatemp->output_filename = ts_filename; 00227 00228 iareatemp->set_attr("long_name", "ice area temperate"); 00229 iareatemp->set_attr("valid_min", 0.0); 00230 00231 timeseries.push_back(iareatemp); 00232 } 00233 00234 if (find(ts_vars.begin(), ts_vars.end(), "iareatempf") != ts_vars.end()) { 00235 DiagnosticTimeseries *iareatempf = new DiagnosticTimeseries(&grid, "iareatempf", "t"); 00236 00237 iareatempf->set_units("1", ""); 00238 iareatempf->set_dimension_units(time_units, ""); 00239 iareatempf->output_filename = ts_filename; 00240 00241 iareatempf->set_attr("long_name", "ice area temperate fraction"); 00242 iareatempf->set_attr("valid_min", 0.0); 00243 00244 timeseries.push_back(iareatempf); 00245 } 00246 00247 if (find(ts_vars.begin(), ts_vars.end(), "iareacold") != ts_vars.end()) { 00248 DiagnosticTimeseries *iareacold = new DiagnosticTimeseries(&grid, "iareacold", "t"); 00249 00250 iareacold->set_units("m2", ""); 00251 iareacold->set_dimension_units(time_units, ""); 00252 iareacold->output_filename = ts_filename; 00253 00254 iareacold->set_attr("long_name", "ice area cold"); 00255 iareacold->set_attr("valid_min", 0.0); 00256 00257 timeseries.push_back(iareacold); 00258 } 00259 00260 if (find(ts_vars.begin(), ts_vars.end(), "iareacoldf") != ts_vars.end()) { 00261 DiagnosticTimeseries *iareacoldf = new DiagnosticTimeseries(&grid, "iareacoldf", "t"); 00262 00263 iareacoldf->set_units("1", ""); 00264 iareacoldf->set_dimension_units(time_units, ""); 00265 iareacoldf->output_filename = ts_filename; 00266 00267 iareacoldf->set_attr("long_name", "ice area cold fraction"); 00268 iareacoldf->set_attr("valid_min", 0.0); 00269 00270 timeseries.push_back(iareacoldf); 00271 } 00272 00273 if (find(ts_vars.begin(), ts_vars.end(), "iareag") != ts_vars.end()) { 00274 DiagnosticTimeseries *iareag = new DiagnosticTimeseries(&grid, "iareag", "t"); 00275 00276 iareag->set_units("m2", ""); 00277 iareag->set_dimension_units(time_units, ""); 00278 iareag->output_filename = ts_filename; 00279 00280 iareag->set_attr("long_name", "grounded ice area"); 00281 iareag->set_attr("valid_min", 0.0); 00282 00283 timeseries.push_back(iareag); 00284 } 00285 00286 if (find(ts_vars.begin(), ts_vars.end(), "iareaf") != ts_vars.end()) { 00287 DiagnosticTimeseries *iareaf = new DiagnosticTimeseries(&grid, "iareaf", "t"); 00288 00289 iareaf->set_units("m2", ""); 00290 iareaf->set_dimension_units(time_units, ""); 00291 iareaf->output_filename = ts_filename; 00292 00293 iareaf->set_attr("long_name", "floating ice area"); 00294 iareaf->set_attr("valid_min", 0.0); 00295 00296 timeseries.push_back(iareaf); 00297 } 00298 00299 if (find(ts_vars.begin(), ts_vars.end(), "dt") != ts_vars.end()) { 00300 DiagnosticTimeseries *delta_t = new DiagnosticTimeseries(&grid, "dt", "t"); 00301 00302 delta_t->set_units("s", "years"); 00303 delta_t->set_dimension_units(time_units, ""); 00304 delta_t->output_filename = ts_filename; 00305 00306 delta_t->set_attr("long_name", "mass continuity time-step"); 00307 delta_t->set_attr("valid_min", 0.0); 00308 00309 timeseries.push_back(delta_t); 00310 } 00311 00312 // The following are in config.get("ts_bad_set") list. 00313 00314 if (find(ts_vars.begin(), ts_vars.end(), "divoldt") != ts_vars.end()) { 00315 DiagnosticTimeseries *divoldt = new DiagnosticTimeseries(&grid, "divoldt", "t"); 00316 00317 divoldt->set_units("m3 s-1", ""); 00318 divoldt->set_dimension_units(time_units, ""); 00319 divoldt->output_filename = ts_filename; 00320 00321 divoldt->set_attr("long_name", "total ice volume rate of change"); 00322 00323 timeseries.push_back(divoldt); 00324 } 00325 00326 if (find(ts_vars.begin(), ts_vars.end(), "dimassdt") != ts_vars.end()) { 00327 DiagnosticTimeseries *dimassdt = new DiagnosticTimeseries(&grid, "dimassdt", "t"); 00328 00329 dimassdt->set_units("kg s-1", ""); 00330 dimassdt->set_dimension_units(time_units, ""); 00331 dimassdt->output_filename = ts_filename; 00332 00333 dimassdt->set_attr("long_name", "total ice mass rate of change"); 00334 00335 timeseries.push_back(dimassdt); 00336 } 00337 00338 if (find(ts_vars.begin(), ts_vars.end(), "surface_ice_flux") != ts_vars.end()) { 00339 DiagnosticTimeseries *tsif = new DiagnosticTimeseries(&grid, "surface_ice_flux", "t"); 00340 00341 tsif->set_units("kg s-1", ""); 00342 tsif->set_dimension_units(time_units, ""); 00343 tsif->output_filename = ts_filename; 00344 00345 tsif->set_attr("long_name", "total over ice domain of top surface ice mass flux"); 00346 tsif->set_attr("comment", "positive means ice gain"); 00347 00348 timeseries.push_back(tsif); 00349 } 00350 00351 if (find(ts_vars.begin(), ts_vars.end(), "basal_ice_flux") != ts_vars.end()) { 00352 DiagnosticTimeseries *tbif = new DiagnosticTimeseries(&grid, "basal_ice_flux", "t"); 00353 00354 tbif->set_units("kg s-1", ""); 00355 tbif->set_dimension_units(time_units, ""); 00356 tbif->output_filename = ts_filename; 00357 00358 tbif->set_attr("long_name", "total over ice domain of basal surface ice mass flux"); 00359 tbif->set_attr("comment", "positive means ice gain"); 00360 00361 timeseries.push_back(tbif); 00362 } 00363 00364 if (find(ts_vars.begin(), ts_vars.end(), "sub_shelf_ice_flux") != ts_vars.end()) { 00365 DiagnosticTimeseries *tssif = new DiagnosticTimeseries(&grid, "sub_shelf_ice_flux", "t"); 00366 00367 tssif->set_units("kg s-1", ""); 00368 tssif->set_dimension_units(time_units, ""); 00369 tssif->output_filename = ts_filename; 00370 00371 tssif->set_attr("long_name", "total over ice domain of sub-ice-shelf ice mass flux"); 00372 tssif->set_attr("comment", "positive means ice gain"); 00373 00374 timeseries.push_back(tssif); 00375 } 00376 00377 if (find(ts_vars.begin(), ts_vars.end(), "nonneg_rule_flux") != ts_vars.end()) { 00378 DiagnosticTimeseries *ts = new DiagnosticTimeseries(&grid, "nonneg_rule_flux", "t"); 00379 00380 ts->set_units("kg s-1", ""); 00381 ts->set_dimension_units(time_units, ""); 00382 ts->output_filename = ts_filename; 00383 00384 ts->set_attr("long_name", "total over ice domain of ice mass gain by application of non-negative thickness rule"); 00385 ts->set_attr("comment", "positive means ice gain"); 00386 00387 timeseries.push_back(ts); 00388 } 00389 00390 if (find(ts_vars.begin(), ts_vars.end(), "ocean_kill_flux") != ts_vars.end()) { 00391 DiagnosticTimeseries *ts = new DiagnosticTimeseries(&grid, "ocean_kill_flux", "t"); 00392 00393 ts->set_units("kg s-1", ""); 00394 ts->set_dimension_units(time_units, ""); 00395 ts->output_filename = ts_filename; 00396 00397 ts->set_attr("long_name", "total over ice domain of ice mass gain by calving by application of -ocean_kill mechanism"); 00398 ts->set_attr("comment", "positive means ice gain"); 00399 00400 timeseries.push_back(ts); 00401 } 00402 00403 if (find(ts_vars.begin(), ts_vars.end(), "float_kill_flux") != ts_vars.end()) { 00404 DiagnosticTimeseries *ts = new DiagnosticTimeseries(&grid, "float_kill_flux", "t"); 00405 00406 ts->set_units("kg s-1", ""); 00407 ts->set_dimension_units(time_units, ""); 00408 ts->output_filename = ts_filename; 00409 00410 ts->set_attr("long_name", "total over ice domain of ice mass gain by calving by application of -float_kill mechanism"); 00411 ts->set_attr("comment", "positive means ice gain"); 00412 00413 timeseries.push_back(ts); 00414 } 00415 00416 // as noted above, the variables listed in the bad_set may require a user to 00417 // very carefully interpret; thus the need to add a warning 00418 string warning = config.get_string("ts_bad_set_warning"), 00419 tmp; 00420 istringstream arg(config.get_string("ts_bad_set_variables")); // string becomes stream 00421 set<string> bad_vars; 00422 while (getline(arg, tmp, ' ')) { 00423 if (!tmp.empty()) // this ignores multiple spaces separating variable names 00424 bad_vars.insert(tmp); 00425 } 00426 for (size_t i = 0; i < timeseries.size(); i++) { 00427 if (set_contains(bad_vars,timeseries[i]->short_name)) { 00428 timeseries[i]->set_attr("interpretation_warning", warning); 00429 } 00430 } 00431 00432 return 0; 00433 } 00434 00436 PetscErrorCode IceModel::write_timeseries() { 00437 PetscErrorCode ierr; 00438 vector<DiagnosticTimeseries*>::iterator i; 00439 00440 // return if no time-series requested 00441 if (!save_ts) return 0; 00442 00443 // return if wrote all the records already 00444 if (current_ts == ts_times.size()) 00445 return 0; 00446 00447 // return if did not yet reach the time we need to save at 00448 if (ts_times[current_ts] > grid.year) 00449 return 0; 00450 00451 // compute values of requested scalar quantities: 00452 for (i = timeseries.begin(); i < timeseries.end(); ++i) { 00453 PetscScalar tmp; 00454 00455 ierr = compute_by_name((*i)->short_name, tmp); CHKERRQ(ierr); 00456 00457 (*i)->append(grid.year, tmp); 00458 } 00459 00460 // Interpolate to put them on requested times: 00461 while ((current_ts < ts_times.size()) && 00462 (ts_times[current_ts] <= grid.year)) { 00463 00464 for (i = timeseries.begin(); i < timeseries.end(); ++i) { 00465 ierr = (*i)->interp(ts_times[current_ts]); CHKERRQ(ierr); 00466 } 00467 00468 current_ts++; 00469 } 00470 00471 return 0; 00472 } 00473 00474 00476 PetscErrorCode IceModel::init_extras() { 00477 PetscErrorCode ierr; 00478 bool split, times_set, file_set, save_vars; 00479 string times, vars; 00480 current_extra = 0; 00481 00482 ierr = PetscOptionsBegin(grid.com, "", "Options controlling 2D and 3D diagnostic output", ""); CHKERRQ(ierr); 00483 { 00484 ierr = PISMOptionsString("-extra_file", "Specifies the output file", 00485 extra_filename, file_set); CHKERRQ(ierr); 00486 00487 ierr = PISMOptionsString("-extra_times", "Specifies times to save at", 00488 times, times_set); CHKERRQ(ierr); 00489 00490 ierr = PISMOptionsString("-extra_vars", "Spacifies a comma-separated list of variables to save", 00491 vars, save_vars); CHKERRQ(ierr); 00492 00493 ierr = PISMOptionsIsSet("-extra_split", "Specifies whether to save to separate files", 00494 split); CHKERRQ(ierr); 00495 } 00496 ierr = PetscOptionsEnd(); CHKERRQ(ierr); 00497 00498 if (file_set ^ times_set) { 00499 PetscPrintf(grid.com, 00500 "PISM ERROR: you need to specify both -extra_file and -extra_times to save spatial time-series.\n"); 00501 PISMEnd(); 00502 } 00503 00504 if (!file_set && !times_set) { 00505 save_extra = false; 00506 return 0; 00507 } 00508 00509 ierr = parse_times(grid.com, times, extra_times); 00510 if (ierr != 0) { 00511 PetscPrintf(grid.com, "PISM ERROR: parsing the -extra_times argument failed.\n"); 00512 PISMEnd(); 00513 } 00514 if (extra_times.size() == 0) { 00515 PetscPrintf(grid.com, "PISM ERROR: no argument for -extra_times option.\n"); 00516 PISMEnd(); 00517 } 00518 00519 save_extra = true; 00520 extra_file_is_ready = false; 00521 split_extra = false; 00522 00523 if (split) { 00524 split_extra = true; 00525 } else if (!ends_with(extra_filename, ".nc")) { 00526 ierr = verbPrintf(2, grid.com, 00527 "PISM WARNING: spatial time-series file name '%s' does not have the '.nc' suffix!\n", 00528 extra_filename.c_str()); 00529 CHKERRQ(ierr); 00530 } 00531 00532 if (split) { 00533 ierr = verbPrintf(2, grid.com, "saving spatial time-series to '%s+year.nc'; ", 00534 extra_filename.c_str()); CHKERRQ(ierr); 00535 } else { 00536 ierr = verbPrintf(2, grid.com, "saving spatial time-series to '%s'; ", 00537 extra_filename.c_str()); CHKERRQ(ierr); 00538 } 00539 00540 if (extra_times.size() > 500) { 00541 ierr = verbPrintf(2, grid.com, 00542 "PISM WARNING: more than 500 times requested. This might fill your hard-drive!\n"); 00543 CHKERRQ(ierr); 00544 } 00545 00546 ierr = verbPrintf(2, grid.com, "times requested: %s\n", times.c_str()); CHKERRQ(ierr); 00547 00548 string var_name; 00549 if (save_vars) { 00550 ierr = verbPrintf(2, grid.com, "variables requested: %s\n", vars.c_str()); CHKERRQ(ierr); 00551 istringstream arg(vars); 00552 00553 while (getline(arg, var_name, ',')) 00554 extra_vars.insert(var_name); 00555 00556 } else { 00557 ierr = verbPrintf(2, grid.com, "PISM WARNING: -extra_vars was not set." 00558 " Writing model_state, mapping and climate_steady variables...\n"); CHKERRQ(ierr); 00559 00560 set<string> vars_set = variables.keys(); 00561 00562 set<string>::iterator i = vars_set.begin(); 00563 while (i != vars_set.end()) { 00564 IceModelVec *var = variables.get(*i); 00565 00566 string intent = var->string_attr("pism_intent"); 00567 if ((intent == "model_state") || 00568 (intent == "mapping") || 00569 (intent == "climate_steady")) { 00570 extra_vars.insert(*i); 00571 } 00572 i++; 00573 } 00574 00575 if (stress_balance) 00576 stress_balance->add_vars_to_output("small", extra_vars); 00577 00578 } 00579 if (extra_vars.size() == 0) { 00580 ierr = verbPrintf(2, grid.com, 00581 "PISM WARNING: no variables list after -extra_vars ... writing empty file ...\n"); CHKERRQ(ierr); 00582 } 00583 00584 return 0; 00585 } 00586 00588 PetscErrorCode IceModel::write_extras() { 00589 PetscErrorCode ierr; 00590 PISMIO nc(&grid); 00591 double saving_after = -1.0e30; // initialize to avoid compiler warning; this 00592 // value is never used, because saving_after 00593 // is only used if save_now == true, and in 00594 // this case saving_after is guaranteed to be 00595 // initialized. See the code below. 00596 char filename[PETSC_MAX_PATH_LEN]; 00597 00598 // determine if the user set the -save_at and -save_to options 00599 if (!save_extra) 00600 return 0; 00601 00602 // do we need to save *now*? 00603 if ( current_extra < extra_times.size() && grid.year >= extra_times[current_extra] ) { 00604 saving_after = extra_times[current_extra]; 00605 00606 while (current_extra < extra_times.size() && extra_times[current_extra] <= grid.year) 00607 current_extra++; 00608 } else { 00609 // we don't need to save now, so just return 00610 return 0; 00611 } 00612 00613 if (saving_after < grid.start_year) { 00614 // Suppose a user tells PISM to write data at times 0:1000:10000. Suppose 00615 // also that PISM writes a backup file at year 2500 and gets stopped. 00616 // 00617 // When restarted, PISM will decide that it's time to write data for time 00618 // 2000, but 00619 // * that record was written already and 00620 // * PISM will end up writing at year 2500, producing a file containing one 00621 // more record than necessary. 00622 // 00623 // This check makes sure that this never happens. 00624 return 0; 00625 } 00626 00627 if (split_extra) { 00628 extra_file_is_ready = false; // each time-series record is written to a separate file 00629 snprintf(filename, PETSC_MAX_PATH_LEN, "%s-%06.0f.nc", 00630 extra_filename.c_str(), grid.year); 00631 } else { 00632 strncpy(filename, extra_filename.c_str(), PETSC_MAX_PATH_LEN); 00633 } 00634 00635 ierr = verbPrintf(3, grid.com, 00636 "\nsaving spatial time-series to %s at %.5f a\n\n", 00637 filename, grid.year); 00638 CHKERRQ(ierr); 00639 00640 // create line for history in .nc file, including time of write 00641 string date_str = pism_timestamp(); 00642 char tmp[TEMPORARY_STRING_LENGTH]; 00643 snprintf(tmp, TEMPORARY_STRING_LENGTH, 00644 "%s: %s saving spatial time-series record at %10.5f a\n", 00645 date_str.c_str(), executable_short_name.c_str(), grid.year); 00646 00647 if (!extra_file_is_ready) { 00648 00649 // default behavior is to move the file aside if it exists already; option allows appending 00650 bool append; 00651 ierr = PISMOptionsIsSet("-extra_append", append); CHKERRQ(ierr); 00652 00653 // Prepare the file: 00654 ierr = nc.open_for_writing(filename, (append==PETSC_TRUE), true); CHKERRQ(ierr); // check_dims == true 00655 ierr = nc.close(); CHKERRQ(ierr); 00656 00657 ierr = write_metadata(filename); CHKERRQ(ierr); 00658 00659 extra_file_is_ready = true; 00660 } 00661 00662 ierr = nc.open_for_writing(filename, true, true); CHKERRQ(ierr); 00663 // append == true, check_dims == true 00664 ierr = nc.append_time(grid.year); CHKERRQ(ierr); 00665 ierr = nc.write_history(tmp); CHKERRQ(ierr); // append the history 00666 ierr = nc.close(); CHKERRQ(ierr); 00667 00668 ierr = write_variables(filename, extra_vars, NC_FLOAT); CHKERRQ(ierr); 00669 00670 return 0; 00671 } 00672 00674 00677 PetscErrorCode IceModel::extras_max_timestep(double t_years, double& dt_years) { 00678 00679 if (!save_extra) { 00680 dt_years = -1; 00681 return 0; 00682 } 00683 00684 bool force_times; 00685 force_times = config.get_flag("force_output_times"); 00686 00687 if (!force_times) { 00688 dt_years = -1; 00689 return 0; 00690 } 00691 00692 vector<double>::iterator j; 00693 j = upper_bound(extra_times.begin(), extra_times.end(), t_years); 00694 00695 if (j == extra_times.end()) { 00696 dt_years = -1; 00697 return 0; 00698 } 00699 00700 dt_years = *j - t_years; 00701 return 0; 00702 } 00703 00705 00708 PetscErrorCode IceModel::ts_max_timestep(double t_years, double& dt_years) { 00709 00710 if (!save_ts) { 00711 dt_years = -1; 00712 return 0; 00713 } 00714 00715 bool force_times; 00716 force_times = config.get_flag("force_output_times"); 00717 00718 if (!force_times) { 00719 dt_years = -1; 00720 return 0; 00721 } 00722 00723 vector<double>::iterator j; 00724 j = upper_bound(ts_times.begin(), ts_times.end(), t_years); 00725 00726 if (j == ts_times.end()) { 00727 dt_years = -1; 00728 return 0; 00729 } 00730 00731 dt_years = *j - t_years; 00732 return 0; 00733 } 00734 00736 PetscErrorCode IceModel::flush_timeseries() { 00737 // flush all the time-series buffers: 00738 vector<DiagnosticTimeseries*>::iterator i; 00739 for (i = timeseries.begin(); i < timeseries.end(); ++i) { 00740 (*i)->flush(); 00741 } 00742 00743 return 0; 00744 }
1.7.3