|
PISM, A Parallel Ice Sheet Model
stable v0.5
|
00001 // Copyright (C) 2010, 2011, 2012 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 "pism_options.hh" 00020 #include "iceModel_diagnostics.hh" 00021 #include "PISMDiagnostic.hh" 00022 #include "Mask.hh" 00023 00024 #include "PISMBedDef.hh" 00025 #include "PISMYieldStress.hh" 00026 #include "PISMStressBalance.hh" 00027 #include "PISMSurface.hh" 00028 #include "PISMOcean.hh" 00029 #include "enthalpyConverter.hh" 00030 #include "ShallowStressBalance.hh" 00031 #include "SSB_Modifier.hh" 00032 #include "bedrockThermalUnit.hh" 00033 00034 PetscErrorCode IceModel::init_diagnostics() { 00035 00036 // Add IceModel diagnostics: 00037 diagnostics["cts"] = new IceModel_cts(this, grid, variables); 00038 diagnostics["enthalpybase"] = new IceModel_enthalpybase(this, grid, variables); 00039 diagnostics["enthalpysurf"] = new IceModel_enthalpysurf(this, grid, variables); 00040 diagnostics["hardav"] = new IceModel_hardav(this, grid, variables); 00041 diagnostics["liqfrac"] = new IceModel_liqfrac(this, grid, variables); 00042 diagnostics["proc_ice_area"] = new IceModel_proc_ice_area(this, grid, variables); 00043 diagnostics["rank"] = new IceModel_rank(this, grid, variables); 00044 diagnostics["temp"] = new IceModel_temp(this, grid, variables); 00045 diagnostics["temp_pa"] = new IceModel_temp_pa(this, grid, variables); 00046 diagnostics["tempbase"] = new IceModel_tempbase(this, grid, variables); 00047 diagnostics["tempicethk"] = new IceModel_tempicethk(this, grid, variables); 00048 diagnostics["tempicethk_basal"] = new IceModel_tempicethk_basal(this, grid, variables); 00049 diagnostics["temppabase"] = new IceModel_temppabase(this, grid, variables); 00050 diagnostics["tempsurf"] = new IceModel_tempsurf(this, grid, variables); 00051 diagnostics["dHdt"] = new IceModel_dHdt(this, grid, variables); 00052 00053 if (config.get_flag("compute_cumulative_acab")) { 00054 diagnostics["acab_cumulative"] = new IceModel_acab_cumulative(this, grid, variables); 00055 } 00056 00057 ts_diagnostics["ivol"] = new IceModel_ivol(this, grid, variables); 00058 ts_diagnostics["slvol"] = new IceModel_slvol(this, grid, variables); 00059 ts_diagnostics["divoldt"] = new IceModel_divoldt(this, grid, variables); 00060 ts_diagnostics["iarea"] = new IceModel_iarea(this, grid, variables); 00061 ts_diagnostics["imass"] = new IceModel_imass(this, grid, variables); 00062 ts_diagnostics["dimassdt"] = new IceModel_dimassdt(this, grid, variables); 00063 ts_diagnostics["ivoltemp"] = new IceModel_ivoltemp(this, grid, variables); 00064 ts_diagnostics["ivoltempf"] = new IceModel_ivoltempf(this, grid, variables); 00065 ts_diagnostics["ivolcold"] = new IceModel_ivolcold(this, grid, variables); 00066 ts_diagnostics["ivolcoldf"] = new IceModel_ivolcoldf(this, grid, variables); 00067 ts_diagnostics["ivolg"] = new IceModel_ivolg(this, grid, variables); 00068 ts_diagnostics["ivolf"] = new IceModel_ivolf(this, grid, variables); 00069 ts_diagnostics["iareatemp"] = new IceModel_iareatemp(this, grid, variables); 00070 ts_diagnostics["iareatempf"] = new IceModel_iareatempf(this, grid, variables); 00071 ts_diagnostics["iareacold"] = new IceModel_iareacold(this, grid, variables); 00072 ts_diagnostics["iareacoldf"] = new IceModel_iareacoldf(this, grid, variables); 00073 ts_diagnostics["iareag"] = new IceModel_iareag(this, grid, variables); 00074 ts_diagnostics["iareaf"] = new IceModel_iareaf(this, grid, variables); 00075 ts_diagnostics["dt"] = new IceModel_dt(this, grid, variables); 00076 ts_diagnostics["max_diffusivity"] = new IceModel_max_diffusivity(this, grid, variables); 00077 ts_diagnostics["ienthalpy"] = new IceModel_ienthalpy(this, grid, variables); 00078 ts_diagnostics["max_hor_vel"] = new IceModel_max_hor_vel(this, grid, variables); 00079 00080 00081 ts_diagnostics["surface_ice_flux"] = new IceModel_surface_flux(this, grid, variables); 00082 ts_diagnostics["cumulative_surface_ice_flux"] = new IceModel_cumulative_surface_flux(this, grid, variables); 00083 ts_diagnostics["basal_ice_flux"] = new IceModel_basal_flux(this, grid, variables); 00084 ts_diagnostics["cumulative_basal_ice_flux"] = new IceModel_cumulative_basal_flux(this, grid, variables); 00085 ts_diagnostics["sub_shelf_ice_flux"] = new IceModel_sub_shelf_flux(this, grid, variables); 00086 ts_diagnostics["cumulative_sub_shelf_ice_flux"] = new IceModel_cumulative_sub_shelf_flux(this, grid, variables); 00087 ts_diagnostics["nonneg_rule_flux"] = new IceModel_nonneg_flux(this, grid, variables); 00088 ts_diagnostics["cumulative_nonneg_rule_flux"] = new IceModel_cumulative_nonneg_flux(this, grid, variables); 00089 ts_diagnostics["ocean_kill_flux"] = new IceModel_ocean_kill_flux(this, grid, variables); 00090 ts_diagnostics["cumulative_ocean_kill_flux"] = new IceModel_cumulative_ocean_kill_flux(this, grid, variables); 00091 ts_diagnostics["float_kill_flux"] = new IceModel_float_kill_flux(this, grid, variables); 00092 ts_diagnostics["cumulative_float_kill_flux"] = new IceModel_cumulative_float_kill_flux(this, grid, variables); 00093 ts_diagnostics["discharge_flux"] = new IceModel_discharge_flux(this, grid, variables); 00094 ts_diagnostics["cumulative_discharge_flux"] = new IceModel_cumulative_discharge_flux(this, grid, variables); 00095 00096 00097 // Get diagnostics supported by the stress balance object: 00098 stress_balance->get_diagnostics(diagnostics); 00099 00100 // Get diagnostics supported by the surface model: 00101 surface->get_diagnostics(diagnostics); 00102 00103 // Get diagnostics supported by the ocean model: 00104 ocean->get_diagnostics(diagnostics); 00105 00106 // Get diagnostics supported by the bed deformation model: 00107 if (beddef) { 00108 beddef->get_diagnostics(diagnostics); 00109 } 00110 00111 if (basal_yield_stress) { 00112 basal_yield_stress->get_diagnostics(diagnostics); 00113 } 00114 00115 bool print_list_and_stop = false; 00116 00117 PetscErrorCode ierr = PISMOptionsIsSet("-list_diagnostics", 00118 "List available diagnostic quantities and stop", 00119 print_list_and_stop); CHKERRQ(ierr); 00120 if (print_list_and_stop) { 00121 ierr = list_diagnostics(); CHKERRQ(ierr); 00122 00123 PISMEnd(); 00124 } 00125 00126 return 0; 00127 } 00128 00129 PetscErrorCode IceModel::list_diagnostics() { 00130 00131 PetscPrintf(grid.com, "\n"); 00132 00133 // quantities with dedicated storage 00134 { 00135 map<string, NCSpatialVariable> list; 00136 set<string> vars = variables.keys(); 00137 00138 set<string>::iterator i = vars.begin(); 00139 while (i != vars.end()) { 00140 list[*i] = variables.get(*i)->get_metadata(); 00141 ++i; 00142 } 00143 00144 00145 if (beddef != NULL) 00146 beddef->add_vars_to_output("big", list); 00147 00148 if (btu != NULL) 00149 btu->add_vars_to_output("big", list); 00150 00151 if (basal_yield_stress != NULL) 00152 basal_yield_stress->add_vars_to_output("big", list); 00153 00154 if (stress_balance != NULL) 00155 stress_balance->add_vars_to_output("big", list); 00156 00157 if (ocean != NULL) 00158 ocean->add_vars_to_output("big", list); 00159 00160 if (surface != NULL) 00161 surface->add_vars_to_output("big", list); 00162 00163 for (int d = 3; d > 1; --d) { 00164 00165 PetscPrintf(grid.com, 00166 "======== Available %dD quantities with dedicated storage ========\n", 00167 d); 00168 00169 map<string,NCSpatialVariable>::iterator j = list.begin(); 00170 while(j != list.end()) { 00171 00172 if ((j->second).get_ndims() == d) { 00173 NCSpatialVariable var = j->second; 00174 00175 string name = j->first, 00176 units = var.get_string("units"), 00177 glaciological_units = var.get_string("glaciological_units"), 00178 long_name = var.get_string("long_name"); 00179 00180 if (glaciological_units.empty() == false) 00181 units = glaciological_units; 00182 00183 PetscPrintf(grid.com, 00184 " Name: %s [%s]\n" 00185 " - %s\n\n", name.c_str(), units.c_str(), long_name.c_str()); 00186 } 00187 00188 ++j; 00189 } 00190 } 00191 00192 } 00193 00194 // 2D and 3D diagnostics 00195 for (int d = 3; d > 1; --d) { 00196 00197 PetscPrintf(grid.com, 00198 "======== Available %dD diagnostic quantities ========\n", 00199 d); 00200 00201 map<string, PISMDiagnostic*>::iterator j = diagnostics.begin(); 00202 while (j != diagnostics.end()) { 00203 PISMDiagnostic *diag = j->second; 00204 00205 string name = j->first, 00206 units = diag->get_metadata().get_string("units"), 00207 glaciological_units = diag->get_metadata().get_string("glaciological_units"); 00208 00209 if (glaciological_units.empty() == false) 00210 units = glaciological_units; 00211 00212 if (diag->get_metadata().get_ndims() == d) { 00213 00214 PetscPrintf(grid.com, " Name: %s [%s]\n", name.c_str(), units.c_str()); 00215 00216 for (int k = 0; k < diag->get_nvars(); ++k) { 00217 NCSpatialVariable var = diag->get_metadata(k); 00218 00219 string long_name = var.get_string("long_name"); 00220 00221 PetscPrintf(grid.com, " - %s\n", long_name.c_str()); 00222 } 00223 00224 PetscPrintf(grid.com, "\n"); 00225 00226 } 00227 00228 ++j; 00229 } 00230 } 00231 00232 // scalar time-series 00233 PetscPrintf(grid.com, "======== Available time-series ========\n"); 00234 00235 map<string, PISMTSDiagnostic*>::iterator j = ts_diagnostics.begin(); 00236 while (j != ts_diagnostics.end()) { 00237 PISMTSDiagnostic *diag = j->second; 00238 00239 string name = j->first, 00240 long_name = diag->get_string("long_name"), 00241 units = diag->get_string("units"), 00242 glaciological_units = diag->get_string("glaciological_units"); 00243 00244 if (glaciological_units.empty() == false) 00245 units = glaciological_units; 00246 00247 PetscPrintf(grid.com, 00248 " Name: %s [%s]\n" 00249 " - %s\n\n", 00250 name.c_str(), units.c_str(), long_name.c_str()); 00251 00252 ++j; 00253 } 00254 00255 return 0; 00256 } 00257 00258 00259 00260 IceModel_hardav::IceModel_hardav(IceModel *m, IceGrid &g, PISMVars &my_vars) 00261 : PISMDiag<IceModel>(m, g, my_vars) { 00262 00263 // set metadata: 00264 vars[0].init_2d("hardav", grid); 00265 00266 const PetscScalar power = 1.0 / model->config.get("Glen_exponent"); 00267 char unitstr[TEMPORARY_STRING_LENGTH]; 00268 snprintf(unitstr, sizeof(unitstr), "Pa s%f", power); 00269 00270 set_attrs("vertical average of ice hardness", "", 00271 unitstr, unitstr, 0); 00272 00273 vars[0].set("valid_min", 0); 00274 vars[0].set("_FillValue", -0.01); 00275 } 00276 00278 PetscErrorCode IceModel_hardav::compute(IceModelVec* &output) { 00279 PetscErrorCode ierr; 00280 const PetscScalar fillval = -0.01; 00281 PetscScalar *Eij; // columns of enthalpy values 00282 00283 IceFlowLaw *flow_law = model->stress_balance->get_stressbalance()->get_flow_law(); 00284 if (flow_law == NULL) { 00285 flow_law = model->stress_balance->get_ssb_modifier()->get_flow_law(); 00286 if (flow_law == NULL) { 00287 PetscPrintf(grid.com, "ERROR: Can't compute vertically-averaged hardness: no flow law is used.\n"); 00288 PISMEnd(); 00289 } 00290 } 00291 00292 IceModelVec2S *result = new IceModelVec2S; 00293 ierr = result->create(grid, "hardav", false); CHKERRQ(ierr); 00294 ierr = result->set_metadata(vars[0], 0); CHKERRQ(ierr); 00295 00296 ierr = model->Enth3.begin_access(); CHKERRQ(ierr); 00297 ierr = model->vH.begin_access(); CHKERRQ(ierr); 00298 ierr = result->begin_access(); CHKERRQ(ierr); 00299 for (PetscInt i=grid.xs; i<grid.xs+grid.xm; ++i) { 00300 for (PetscInt j=grid.ys; j<grid.ys+grid.ym; ++j) { 00301 ierr = model->Enth3.getInternalColumn(i,j,&Eij); CHKERRQ(ierr); 00302 const PetscScalar H = model->vH(i,j); 00303 if (H > 0.0) { 00304 (*result)(i,j) = flow_law->averaged_hardness(H, grid.kBelowHeight(H), 00305 &grid.zlevels[0], Eij); 00306 } else { // put negative value below valid range 00307 (*result)(i,j) = fillval; 00308 } 00309 } 00310 } 00311 ierr = model->Enth3.end_access(); CHKERRQ(ierr); 00312 ierr = model->vH.end_access(); CHKERRQ(ierr); 00313 ierr = result->end_access(); CHKERRQ(ierr); 00314 00315 output = result; 00316 return 0; 00317 } 00318 00319 00320 IceModel_rank::IceModel_rank(IceModel *m, IceGrid &g, PISMVars &my_vars) 00321 : PISMDiag<IceModel>(m, g, my_vars) { 00322 00323 // set metadata: 00324 vars[0].init_2d("rank", grid); 00325 00326 set_attrs("processor rank", "", "", "", 0); 00327 vars[0].time_independent = true; 00328 } 00329 00330 PetscErrorCode IceModel_rank::compute(IceModelVec* &output) { 00331 PetscErrorCode ierr; 00332 00333 IceModelVec2S *result = new IceModelVec2S; 00334 ierr = result->create(grid, "rank", false); CHKERRQ(ierr); 00335 ierr = result->set_metadata(vars[0], 0); CHKERRQ(ierr); 00336 00337 ierr = result->begin_access(); CHKERRQ(ierr); 00338 for (PetscInt i=grid.xs; i<grid.xs+grid.xm; ++i) 00339 for (PetscInt j=grid.ys; j<grid.ys+grid.ym; ++j) 00340 (*result)(i,j) = grid.rank; 00341 ierr = result->end_access(); 00342 00343 output = result; 00344 return 0; 00345 } 00346 00347 00348 IceModel_cts::IceModel_cts(IceModel *m, IceGrid &g, PISMVars &my_vars) 00349 : PISMDiag<IceModel>(m, g, my_vars) { 00350 00351 // set metadata: 00352 vars[0].init_3d("cts", grid, g.zlevels); 00353 00354 set_attrs("cts = E/E_s(p), so cold-temperate transition surface is at cts = 1", "", 00355 "", "", 0); 00356 } 00357 00358 PetscErrorCode IceModel_cts::compute(IceModelVec* &output) { 00359 PetscErrorCode ierr; 00360 00361 // update vertical levels (in case the grid was extended 00362 vars[0].set_levels(grid.zlevels); 00363 00364 IceModelVec3 *result = new IceModelVec3; 00365 ierr = result->create(grid, "cts", false); CHKERRQ(ierr); 00366 ierr = result->set_metadata(vars[0], 0); CHKERRQ(ierr); 00367 00368 ierr = model->setCTSFromEnthalpy(*result); CHKERRQ(ierr); 00369 00370 output = result; 00371 return 0; 00372 } 00373 00374 IceModel_proc_ice_area::IceModel_proc_ice_area(IceModel *m, IceGrid &g, PISMVars &my_vars) 00375 : PISMDiag<IceModel>(m, g, my_vars) { 00376 00377 // set metadata: 00378 vars[0].init_2d("proc_ice_area", grid); 00379 00380 set_attrs("number of cells containing ice in a processor's domain", "", 00381 "", "", 0); 00382 vars[0].time_independent = true; 00383 } 00384 00385 PetscErrorCode IceModel_proc_ice_area::compute(IceModelVec* &output) { 00386 PetscErrorCode ierr; 00387 IceModelVec2S *thickness; 00388 00389 thickness = dynamic_cast<IceModelVec2S*>(variables.get("land_ice_thickness")); 00390 if (thickness == NULL) SETERRQ(grid.com, 1, "land_ice_thickness is not available"); 00391 00392 IceModelVec2S *result = new IceModelVec2S; 00393 ierr = result->create(grid, "proc_ice_area", false); CHKERRQ(ierr); 00394 ierr = result->set_metadata(vars[0], 0); CHKERRQ(ierr); 00395 00396 PetscInt ice_filled_cells = 0; 00397 00398 ierr = thickness->begin_access(); CHKERRQ(ierr); 00399 for (PetscInt i=grid.xs; i<grid.xs+grid.xm; ++i) 00400 for (PetscInt j=grid.ys; j<grid.ys+grid.ym; ++j) 00401 if ((*thickness)(i,j) > 0) { 00402 ice_filled_cells += 1; 00403 } 00404 ierr = thickness->end_access(); CHKERRQ(ierr); 00405 00406 ierr = result->begin_access(); CHKERRQ(ierr); 00407 for (PetscInt i=grid.xs; i<grid.xs+grid.xm; ++i) 00408 for (PetscInt j=grid.ys; j<grid.ys+grid.ym; ++j) 00409 (*result)(i,j) = ice_filled_cells; 00410 ierr = result->end_access(); 00411 00412 output = result; 00413 return 0; 00414 } 00415 00416 00417 IceModel_temp::IceModel_temp(IceModel *m, IceGrid &g, PISMVars &my_vars) 00418 : PISMDiag<IceModel>(m, g, my_vars) { 00419 00420 // set metadata: 00421 vars[0].init_3d("temp", grid, g.zlevels); 00422 00423 set_attrs("ice temperature", "land_ice_temperature", "K", "K", 0); 00424 vars[0].set("valid_min", 0); 00425 } 00426 00427 PetscErrorCode IceModel_temp::compute(IceModelVec* &output) { 00428 PetscErrorCode ierr; 00429 00430 // update vertical levels (in case the grid was extended 00431 vars[0].set_levels(grid.zlevels); 00432 00433 IceModelVec3 *result = new IceModelVec3; 00434 ierr = result->create(grid, "temp", false); CHKERRQ(ierr); 00435 ierr = result->set_metadata(vars[0], 0); CHKERRQ(ierr); 00436 00437 IceModelVec2S *thickness; 00438 IceModelVec3 *enthalpy; 00439 00440 thickness = dynamic_cast<IceModelVec2S*>(variables.get("land_ice_thickness")); 00441 if (thickness == NULL) SETERRQ(grid.com, 1, "land_ice_thickness is not available"); 00442 00443 enthalpy = dynamic_cast<IceModelVec3*>(variables.get("enthalpy")); 00444 if (enthalpy == NULL) SETERRQ(grid.com, 1, "enthalpy is not available"); 00445 00446 PetscScalar *Tij, *Enthij; // columns of these values 00447 ierr = result->begin_access(); CHKERRQ(ierr); 00448 ierr = enthalpy->begin_access(); CHKERRQ(ierr); 00449 ierr = thickness->begin_access(); CHKERRQ(ierr); 00450 for (PetscInt i=grid.xs; i<grid.xs+grid.xm; ++i) { 00451 for (PetscInt j=grid.ys; j<grid.ys+grid.ym; ++j) { 00452 ierr = result->getInternalColumn(i,j,&Tij); CHKERRQ(ierr); 00453 ierr = enthalpy->getInternalColumn(i,j,&Enthij); CHKERRQ(ierr); 00454 for (PetscInt k=0; k<grid.Mz; ++k) { 00455 const PetscScalar depth = (*thickness)(i,j) - grid.zlevels[k]; 00456 ierr = model->EC->getAbsTemp(Enthij[k], 00457 model->EC->getPressureFromDepth(depth), 00458 Tij[k]); 00459 if (ierr) { 00460 PetscPrintf(grid.com, 00461 "\n\nEnthalpyConverter.getAbsTemp() error at i=%d,j=%d,k=%d\n\n", 00462 i,j,k); 00463 } 00464 CHKERRQ(ierr); 00465 } 00466 } 00467 } 00468 ierr = enthalpy->end_access(); CHKERRQ(ierr); 00469 ierr = result->end_access(); CHKERRQ(ierr); 00470 ierr = thickness->end_access(); CHKERRQ(ierr); 00471 00472 output = result; 00473 return 0; 00474 } 00475 00476 00477 IceModel_temp_pa::IceModel_temp_pa(IceModel *m, IceGrid &g, PISMVars &my_vars) 00478 : PISMDiag<IceModel>(m, g, my_vars) { 00479 00480 // set metadata: 00481 vars[0].init_3d("temp_pa", grid, g.zlevels); 00482 00483 set_attrs("pressure-adjusted ice temperature (degrees above pressure-melting point)", "", 00484 "deg_C", "deg_C", 0); 00485 vars[0].set("valid_max", 0); 00486 } 00487 00488 PetscErrorCode IceModel_temp_pa::compute(IceModelVec* &output) { 00489 PetscErrorCode ierr; 00490 bool cold_mode = model->config.get_flag("do_cold_ice_methods"); 00491 PetscReal melting_point_temp = model->config.get("water_melting_point_temperature"); 00492 00493 // update vertical levels (in case the grid was extended 00494 vars[0].set_levels(grid.zlevels); 00495 00496 IceModelVec3 *result = new IceModelVec3; 00497 ierr = result->create(grid, "temp_pa", false); CHKERRQ(ierr); 00498 ierr = result->set_metadata(vars[0], 0); CHKERRQ(ierr); 00499 00500 IceModelVec2S *thickness; 00501 IceModelVec3 *enthalpy; 00502 00503 thickness = dynamic_cast<IceModelVec2S*>(variables.get("land_ice_thickness")); 00504 if (thickness == NULL) SETERRQ(grid.com, 1, "land_ice_thickness is not available"); 00505 00506 enthalpy = dynamic_cast<IceModelVec3*>(variables.get("enthalpy")); 00507 if (enthalpy == NULL) SETERRQ(grid.com, 1, "enthalpy is not available"); 00508 00509 PetscScalar *Tij, *Enthij; // columns of these values 00510 ierr = result->begin_access(); CHKERRQ(ierr); 00511 ierr = enthalpy->begin_access(); CHKERRQ(ierr); 00512 ierr = thickness->begin_access(); CHKERRQ(ierr); 00513 for (PetscInt i=grid.xs; i<grid.xs+grid.xm; ++i) { 00514 for (PetscInt j=grid.ys; j<grid.ys+grid.ym; ++j) { 00515 ierr = result->getInternalColumn(i,j,&Tij); CHKERRQ(ierr); 00516 ierr = enthalpy->getInternalColumn(i,j,&Enthij); CHKERRQ(ierr); 00517 for (PetscInt k=0; k<grid.Mz; ++k) { 00518 const PetscScalar depth = (*thickness)(i,j) - grid.zlevels[k], 00519 p = model->EC->getPressureFromDepth(depth); 00520 ierr = model->EC->getPATemp(Enthij[k], p, Tij[k]); 00521 if (ierr) { 00522 PetscPrintf(grid.com, 00523 "\n\nEnthalpyConverter.getAbsTemp() error at i=%d,j=%d,k=%d\n\n", 00524 i,j,k); 00525 } 00526 CHKERRQ(ierr); 00527 00528 if (cold_mode) { // if ice is temperate then its pressure-adjusted temp 00529 // is 273.15 00530 if ( model->EC->isTemperate(Enthij[k],p) && ((*thickness)(i,j) > 0)) { 00531 Tij[k] = melting_point_temp; 00532 } 00533 } 00534 00535 } 00536 } 00537 } 00538 ierr = enthalpy->end_access(); CHKERRQ(ierr); 00539 ierr = result->end_access(); CHKERRQ(ierr); 00540 ierr = thickness->end_access(); CHKERRQ(ierr); 00541 00542 ierr = result->shift(-melting_point_temp); CHKERRQ(ierr); 00543 00544 output = result; 00545 return 0; 00546 } 00547 00548 IceModel_temppabase::IceModel_temppabase(IceModel *m, IceGrid &g, PISMVars &my_vars) 00549 : PISMDiag<IceModel>(m, g, my_vars) { 00550 00551 // set metadata: 00552 vars[0].init_2d("temppabase", grid); 00553 00554 set_attrs("pressure-adjusted ice temperature at the base of ice", "", 00555 "Celsius", "Celsius", 0); 00556 } 00557 00558 PetscErrorCode IceModel_temppabase::compute(IceModelVec* &output) { 00559 PetscErrorCode ierr; 00560 00561 bool cold_mode = model->config.get_flag("do_cold_ice_methods"); 00562 PetscReal melting_point_temp = model->config.get("water_melting_point_temperature"); 00563 00564 IceModelVec2S *result = new IceModelVec2S; 00565 ierr = result->create(grid, "temp_pa_base", false); CHKERRQ(ierr); 00566 ierr = result->set_metadata(vars[0], 0); CHKERRQ(ierr); 00567 00568 IceModelVec2S *thickness; 00569 IceModelVec3 *enthalpy; 00570 00571 thickness = dynamic_cast<IceModelVec2S*>(variables.get("land_ice_thickness")); 00572 if (thickness == NULL) SETERRQ(grid.com, 1, "land_ice_thickness is not available"); 00573 00574 enthalpy = dynamic_cast<IceModelVec3*>(variables.get("enthalpy")); 00575 if (enthalpy == NULL) SETERRQ(grid.com, 1, "enthalpy is not available"); 00576 00577 PetscScalar *Enthij; // columns of these values 00578 ierr = result->begin_access(); CHKERRQ(ierr); 00579 ierr = enthalpy->begin_access(); CHKERRQ(ierr); 00580 ierr = thickness->begin_access(); CHKERRQ(ierr); 00581 for (PetscInt i=grid.xs; i<grid.xs+grid.xm; ++i) { 00582 for (PetscInt j=grid.ys; j<grid.ys+grid.ym; ++j) { 00583 ierr = enthalpy->getInternalColumn(i,j,&Enthij); CHKERRQ(ierr); 00584 00585 const PetscScalar depth = (*thickness)(i,j), 00586 p = model->EC->getPressureFromDepth(depth); 00587 ierr = model->EC->getPATemp(Enthij[0], p, 00588 (*result)(i,j)); 00589 if (ierr) { 00590 PetscPrintf(grid.com, 00591 "\n\nEnthalpyConverter.getAbsTemp() error at i=%d,j=%d\n\n", 00592 i,j); 00593 } 00594 CHKERRQ(ierr); 00595 00596 if (cold_mode) { // if ice is temperate then its pressure-adjusted temp 00597 // is 273.15 00598 if ( model->EC->isTemperate(Enthij[0],p) && ((*thickness)(i,j) > 0)) { 00599 (*result)(i,j) = melting_point_temp; 00600 } 00601 } 00602 } 00603 } 00604 ierr = enthalpy->end_access(); CHKERRQ(ierr); 00605 ierr = result->end_access(); CHKERRQ(ierr); 00606 ierr = thickness->end_access(); CHKERRQ(ierr); 00607 00608 ierr = result->shift(-melting_point_temp); CHKERRQ(ierr); 00609 00610 output = result; 00611 return 0; 00612 } 00613 00614 IceModel_enthalpysurf::IceModel_enthalpysurf(IceModel *m, IceGrid &g, PISMVars &my_vars) 00615 : PISMDiag<IceModel>(m, g, my_vars) { 00616 00617 // set metadata: 00618 vars[0].init_2d("enthalpysurf", grid); 00619 00620 set_attrs("ice enthalpy at 1m below the ice surface", "", 00621 "J kg-1", "J kg-1", 0); 00622 vars[0].set("_FillValue", -0.01); 00623 } 00624 00625 PetscErrorCode IceModel_enthalpysurf::compute(IceModelVec* &output) { 00626 PetscErrorCode ierr; 00627 00628 IceModelVec2S *result = new IceModelVec2S; 00629 ierr = result->create(grid, "enthalpysurf", false); CHKERRQ(ierr); 00630 ierr = result->set_metadata(vars[0], 0); CHKERRQ(ierr); 00631 00632 PetscScalar fill_value = -0.01; 00633 00634 // compute levels corresponding to 1 m below the ice surface: 00635 00636 ierr = model->vH.begin_access(); CHKERRQ(ierr); 00637 ierr = result->begin_access(); CHKERRQ(ierr); 00638 for (PetscInt i=grid.xs; i<grid.xs+grid.xm; ++i) { 00639 for (PetscInt j=grid.ys; j<grid.ys+grid.ym; ++j) { 00640 (*result)(i,j) = PetscMax(model->vH(i,j) - 1.0, 0.0); 00641 } 00642 } 00643 ierr = result->end_access(); CHKERRQ(ierr); 00644 00645 ierr = model->Enth3.getSurfaceValues(*result, *result); CHKERRQ(ierr); // z=0 slice 00646 00647 ierr = result->begin_access(); CHKERRQ(ierr); 00648 for (PetscInt i=grid.xs; i<grid.xs+grid.xm; ++i) { 00649 for (PetscInt j=grid.ys; j<grid.ys+grid.ym; ++j) { 00650 if (model->vH(i,j) <= 1.0) 00651 (*result)(i,j) = fill_value; 00652 } 00653 } 00654 ierr = result->end_access(); CHKERRQ(ierr); 00655 ierr = model->vH.end_access(); CHKERRQ(ierr); 00656 00657 00658 output = result; 00659 return 0; 00660 } 00661 00662 IceModel_enthalpybase::IceModel_enthalpybase(IceModel *m, IceGrid &g, PISMVars &my_vars) 00663 : PISMDiag<IceModel>(m, g, my_vars) { 00664 00665 // set metadata: 00666 vars[0].init_2d("enthalpybase", grid); 00667 00668 set_attrs("ice enthalpy at the base of ice", "", 00669 "J kg-1", "J kg-1", 0); 00670 vars[0].set("_FillValue", -0.01); 00671 } 00672 00673 PetscErrorCode IceModel_enthalpybase::compute(IceModelVec* &output) { 00674 PetscErrorCode ierr; 00675 00676 IceModelVec2S *result = new IceModelVec2S; 00677 ierr = result->create(grid, "enthalpybase", false); CHKERRQ(ierr); 00678 ierr = result->set_metadata(vars[0], 0); CHKERRQ(ierr); 00679 00680 ierr = model->Enth3.getHorSlice(*result, 0.0); CHKERRQ(ierr); // z=0 slice 00681 00682 ierr = result->mask_by(model->vH, -0.01); CHKERRQ(ierr); 00683 00684 output = result; 00685 return 0; 00686 } 00687 00688 00689 IceModel_tempbase::IceModel_tempbase(IceModel *m, IceGrid &g, PISMVars &my_vars) 00690 : PISMDiag<IceModel>(m, g, my_vars) { 00691 00692 // set metadata: 00693 vars[0].init_2d("tempbase", grid); 00694 00695 set_attrs("ice temperature at the base of ice", "", 00696 "K", "K", 0); 00697 vars[0].set("_FillValue", -0.01); 00698 } 00699 00700 PetscErrorCode IceModel_tempbase::compute(IceModelVec* &output) { 00701 PetscErrorCode ierr; 00702 00703 IceModelVec2S *result, *thickness; 00704 00705 IceModel_enthalpybase enth(model, grid, variables); 00706 00707 ierr = enth.compute(output); CHKERRQ(ierr); 00708 result = dynamic_cast<IceModelVec2S*>(output); 00709 if (result == NULL) SETERRQ(grid.com, 1, "dynamic_cast failure"); 00710 00711 // result contains basal enthalpy; note that it is allocated by 00712 // enth.compute(). 00713 00714 thickness = dynamic_cast<IceModelVec2S*>(variables.get("land_ice_thickness")); 00715 if (thickness == NULL) SETERRQ(grid.com, 1, "land_ice_thickness is not available"); 00716 00717 ierr = result->begin_access(); CHKERRQ(ierr); 00718 ierr = thickness->begin_access(); CHKERRQ(ierr); 00719 00720 for (PetscInt i = grid.xs; i < grid.xs+grid.xm; ++i) { 00721 for (PetscInt j = grid.ys; j < grid.ys+grid.ym; ++j) { 00722 PetscReal depth = (*thickness)(i,j), 00723 pressure = model->EC->getPressureFromDepth(depth); 00724 if (depth > 0) { 00725 ierr = model->EC->getAbsTemp((*result)(i,j), 00726 pressure, 00727 (*result)(i,j)); 00728 CHKERRQ(ierr); 00729 } else { 00730 (*result)(i,j) = -0.01; 00731 } 00732 } 00733 } 00734 00735 ierr = thickness->end_access(); CHKERRQ(ierr); 00736 ierr = result->end_access(); CHKERRQ(ierr); 00737 00738 ierr = result->set_metadata(vars[0], 0); CHKERRQ(ierr); 00739 output = result; 00740 return 0; 00741 } 00742 00743 IceModel_tempsurf::IceModel_tempsurf(IceModel *m, IceGrid &g, PISMVars &my_vars) 00744 : PISMDiag<IceModel>(m, g, my_vars) { 00745 00746 // set metadata: 00747 vars[0].init_2d("tempsurf", grid); 00748 00749 set_attrs("ice temperature at 1m below the ice surface", "", 00750 "K", "K", 0); 00751 vars[0].set("_FillValue", -0.01); 00752 } 00753 00754 PetscErrorCode IceModel_tempsurf::compute(IceModelVec* &output) { 00755 PetscErrorCode ierr; 00756 00757 IceModelVec2S *result, *thickness; 00758 00759 thickness = dynamic_cast<IceModelVec2S*>(variables.get("land_ice_thickness")); 00760 if (thickness == NULL) SETERRQ(grid.com, 1, "land_ice_thickness is not available"); 00761 00762 IceModel_enthalpysurf enth(model, grid, variables); 00763 00764 ierr = enth.compute(output); CHKERRQ(ierr); 00765 result = dynamic_cast<IceModelVec2S*>(output); 00766 if (result == NULL) SETERRQ(grid.com, 1, "dynamic_cast failure"); 00767 00768 // result contains surface enthalpy; note that it is allocated by 00769 // enth.compute(). 00770 00771 ierr = result->begin_access(); CHKERRQ(ierr); 00772 ierr = thickness->begin_access(); CHKERRQ(ierr); 00773 00774 PetscReal depth = 1.0, 00775 pressure = model->EC->getPressureFromDepth(depth); 00776 for (PetscInt i = grid.xs; i < grid.xs+grid.xm; ++i) { 00777 for (PetscInt j = grid.ys; j < grid.ys+grid.ym; ++j) { 00778 if ((*thickness)(i,j) > 1) { 00779 ierr = model->EC->getAbsTemp((*result)(i,j), 00780 pressure, 00781 (*result)(i,j)); CHKERRQ(ierr); 00782 } else { 00783 (*result)(i,j) = -0.01; 00784 } 00785 } 00786 } 00787 00788 ierr = thickness->end_access(); CHKERRQ(ierr); 00789 ierr = result->end_access(); CHKERRQ(ierr); 00790 00791 ierr = result->set_metadata(vars[0], 0); CHKERRQ(ierr); 00792 output = result; 00793 return 0; 00794 } 00795 00796 00797 IceModel_liqfrac::IceModel_liqfrac(IceModel *m, IceGrid &g, PISMVars &my_vars) 00798 : PISMDiag<IceModel>(m, g, my_vars) { 00799 00800 // set metadata: 00801 vars[0].init_3d("liqfrac", grid, g.zlevels); 00802 00803 set_attrs("liquid water fraction in ice (between 0 and 1)", "", 00804 "1", "1", 0); 00805 vars[0].set("valid_min", 0); 00806 vars[0].set("valid_max", 1); 00807 } 00808 00809 PetscErrorCode IceModel_liqfrac::compute(IceModelVec* &output) { 00810 PetscErrorCode ierr; 00811 00812 // update vertical levels (in case the grid was extended 00813 vars[0].set_levels(grid.zlevels); 00814 00815 IceModelVec3 *result = new IceModelVec3; 00816 ierr = result->create(grid, "liqfrac", false); CHKERRQ(ierr); 00817 ierr = result->set_metadata(vars[0], 0); CHKERRQ(ierr); 00818 00819 bool cold_mode = model->config.get_flag("do_cold_ice_methods"); 00820 00821 if (cold_mode) { 00822 ierr = result->set(0.0); CHKERRQ(ierr); 00823 } else { 00824 ierr = model->compute_liquid_water_fraction(model->Enth3, *result); CHKERRQ(ierr); 00825 } 00826 00827 output = result; 00828 return 0; 00829 } 00830 00831 IceModel_tempicethk::IceModel_tempicethk(IceModel *m, IceGrid &g, PISMVars &my_vars) 00832 : PISMDiag<IceModel>(m, g, my_vars) { 00833 PetscScalar fill_value = -0.01; 00834 00835 // set metadata: 00836 vars[0].init_2d("tempicethk", grid); 00837 00838 set_attrs("temperate ice thickness (total column content)", "", 00839 "m", "m", 0); 00840 vars[0].set("_FillValue", fill_value); 00841 } 00842 00843 PetscErrorCode IceModel_tempicethk::compute(IceModelVec* &output) { 00844 PetscErrorCode ierr; 00845 00846 IceModelVec2S *result = new IceModelVec2S; 00847 ierr = result->create(grid, "tempicethk", false); CHKERRQ(ierr); 00848 ierr = result->set_metadata(vars[0], 0); CHKERRQ(ierr); 00849 00850 PetscScalar *Enth; 00851 00852 ierr = result->begin_access(); CHKERRQ(ierr); 00853 ierr = model->Enth3.begin_access(); CHKERRQ(ierr); 00854 ierr = model->vH.begin_access(); CHKERRQ(ierr); 00855 for (PetscInt i=grid.xs; i<grid.xs+grid.xm; ++i) { 00856 for (PetscInt j=grid.ys; j<grid.ys+grid.ym; ++j) { 00857 if (model->vH(i,j) > 0.) { 00858 ierr = model->Enth3.getInternalColumn(i,j,&Enth); CHKERRQ(ierr); 00859 PetscScalar tithk = 0.; 00860 const PetscInt ks = grid.kBelowHeight(model->vH(i,j)); 00861 00862 for (PetscInt k=0; k<ks; ++k) { // FIXME issue #15 00863 PetscReal pressure = model->EC->getPressureFromDepth(model->vH(i,j) - grid.zlevels[k]); 00864 00865 if (model->EC->isTemperate(Enth[k], pressure)) { 00866 tithk += grid.zlevels[k+1] - grid.zlevels[k]; 00867 } 00868 } 00869 00870 PetscReal pressure = model->EC->getPressureFromDepth(model->vH(i,j) - grid.zlevels[ks]); 00871 if (model->EC->isTemperate(Enth[ks], pressure)) { 00872 tithk += model->vH(i,j) - grid.zlevels[ks]; 00873 } 00874 00875 (*result)(i,j) = tithk; 00876 } 00877 } 00878 } 00879 ierr = model->Enth3.end_access(); CHKERRQ(ierr); 00880 ierr = model->vH.end_access(); CHKERRQ(ierr); 00881 ierr = result->end_access(); CHKERRQ(ierr); 00882 00883 PetscScalar fill_value = -0.01; 00884 ierr = result->mask_by(model->vH, fill_value); CHKERRQ(ierr); 00885 00886 output = result; 00887 return 0; 00888 } 00889 00890 IceModel_tempicethk_basal::IceModel_tempicethk_basal(IceModel *m, IceGrid &g, PISMVars &my_vars) 00891 : PISMDiag<IceModel>(m, g, my_vars) { 00892 PetscScalar fill_value = -0.01; 00893 00894 // set metadata: 00895 vars[0].init_2d("tempicethk_basal", grid); 00896 00897 set_attrs("thickness of the basal layer of temperate ice", "", 00898 "m", "m", 0); 00899 vars[0].set("_FillValue", fill_value); 00900 } 00901 00905 PetscErrorCode IceModel_tempicethk_basal::compute(IceModelVec* &output) { 00906 PetscErrorCode ierr; 00907 00908 IceModelVec2S *result = new IceModelVec2S; 00909 ierr = result->create(grid, "tempicethk_basal", false); CHKERRQ(ierr); 00910 ierr = result->set_metadata(vars[0], 0); CHKERRQ(ierr); 00911 00912 PetscScalar *Enth, fill_value = -0.01; 00913 EnthalpyConverter *EC = model->EC; 00914 00915 ierr = result->begin_access(); CHKERRQ(ierr); 00916 ierr = model->vH.begin_access(); CHKERRQ(ierr); 00917 ierr = model->Enth3.begin_access(); CHKERRQ(ierr); 00918 for (PetscInt i = grid.xs; i < grid.xs+grid.xm; ++i) { 00919 for (PetscInt j = grid.ys; j < grid.ys+grid.ym; ++j) { 00920 PetscReal thk = model->vH(i,j); 00921 00922 // if we have no ice, go on to the next grid point (this cell will be 00923 // marked as "missing" later) 00924 if (thk < 0.1) 00925 continue; 00926 00927 ierr = model->Enth3.getInternalColumn(i,j,&Enth); CHKERRQ(ierr); 00928 PetscReal pressure; 00929 PetscInt ks = grid.kBelowHeight(thk), 00930 k = 0; 00931 00932 while (k <= ks) { // FIXME issue #15 00933 pressure = EC->getPressureFromDepth(thk - grid.zlevels[k]); 00934 00935 if (EC->isTemperate(Enth[k],pressure)) 00936 k++; 00937 else 00938 break; 00939 } 00940 // after this loop 'pressure' is equal to the pressure at the first level 00941 // that is cold 00942 00943 // no temperate ice at all; go to the next grid point 00944 if (k == 0) { 00945 (*result)(i,j) = 0; 00946 continue; 00947 } 00948 00949 // the whole column is temperate (except, possibly, some ice between 00950 // zlevels[ks] and the total thickness; we ignore it) 00951 if (k == ks + 1) { 00952 (*result)(i,j) = grid.zlevels[ks]; 00953 continue; 00954 } 00955 00956 PetscReal 00957 pressure_0 = EC->getPressureFromDepth(thk - grid.zlevels[k-1]), 00958 dz = grid.zlevels[k] - grid.zlevels[k-1], 00959 slope1 = (Enth[k] - Enth[k-1]) / dz, 00960 slope2 = (EC->getEnthalpyCTS(pressure) - EC->getEnthalpyCTS(pressure_0)) / dz; 00961 00962 if (slope1 != slope2) { 00963 (*result)(i,j) = grid.zlevels[k-1] + 00964 (EC->getEnthalpyCTS(pressure_0) - Enth[k-1]) / (slope1 - slope2); 00965 00966 // check if the resulting thickness is valid: 00967 (*result)(i,j) = PetscMax((*result)(i,j), grid.zlevels[k-1]); 00968 (*result)(i,j) = PetscMin((*result)(i,j), grid.zlevels[k]); 00969 } else { 00970 SETERRQ4(grid.com, 1, "This should never happen: (i=%d, j=%d, k=%d, ks=%d)\n", 00971 i, j, k, ks); 00972 } 00973 } 00974 } 00975 ierr = model->Enth3.end_access(); CHKERRQ(ierr); 00976 ierr = model->vH.end_access(); CHKERRQ(ierr); 00977 ierr = result->end_access(); CHKERRQ(ierr); 00978 00979 ierr = result->mask_by(model->vH, fill_value); CHKERRQ(ierr); 00980 00981 output = result; 00982 return 0; 00983 } 00984 00985 IceModel_acab_cumulative::IceModel_acab_cumulative(IceModel *m, IceGrid &g, PISMVars &my_vars) 00986 : PISMDiag<IceModel>(m, g, my_vars) { 00987 00988 // set metadata: 00989 vars[0].init_2d("cumulative_climatic_mass_balance", grid); 00990 00991 set_attrs("cumulative ice-equivalent climatic mass balance", "", 00992 "m", "m", 0); 00993 } 00994 00995 PetscErrorCode IceModel_acab_cumulative::compute(IceModelVec* &output) { 00996 PetscErrorCode ierr; 00997 00998 IceModelVec2S *result = new IceModelVec2S; 00999 ierr = result->create(grid, "acab_cumulative", false); CHKERRQ(ierr); 01000 ierr = result->set_metadata(vars[0], 0); CHKERRQ(ierr); 01001 result->write_in_glaciological_units = true; 01002 01003 ierr = result->copy_from(model->acab_cumulative); CHKERRQ(ierr); 01004 01005 output = result; 01006 return 0; 01007 } 01008 01009 IceModel_ivol::IceModel_ivol(IceModel *m, IceGrid &g, PISMVars &my_vars) 01010 : PISMTSDiag<IceModel>(m, g, my_vars) { 01011 01012 // set metadata: 01013 ts = new DiagnosticTimeseries(&grid, "ivol", time_dimension_name); 01014 01015 ts->set_units("m3", ""); 01016 ts->set_dimension_units(time_units, ""); 01017 01018 ts->set_attr("long_name", "total ice volume"); 01019 ts->set_attr("valid_min", 0.0); 01020 } 01021 01022 PetscErrorCode IceModel_ivol::update(PetscReal a, PetscReal b) { 01023 PetscErrorCode ierr; 01024 PetscReal value; 01025 01026 ierr = model->compute_ice_volume(value); CHKERRQ(ierr); 01027 01028 ierr = ts->append(value, a, b); CHKERRQ(ierr); 01029 01030 return 0; 01031 } 01032 01033 IceModel_slvol::IceModel_slvol(IceModel *m, IceGrid &g, PISMVars &my_vars) 01034 : PISMTSDiag<IceModel>(m, g, my_vars) { 01035 01036 // set metadata: 01037 ts = new DiagnosticTimeseries(&grid, "slvol", time_dimension_name); 01038 01039 ts->set_units("m", ""); 01040 ts->set_dimension_units(time_units, ""); 01041 01042 ts->set_attr("long_name", "total sea-level relevant ice IN SEA-LEVEL EQUIVALENT"); 01043 ts->set_attr("valid_min", 0.0); 01044 } 01045 01046 PetscErrorCode IceModel_slvol::update(PetscReal a, PetscReal b) { 01047 PetscErrorCode ierr; 01048 PetscReal value; 01049 01050 ierr = model->compute_sealevel_volume(value); CHKERRQ(ierr); 01051 01052 ierr = ts->append(value, a, b); CHKERRQ(ierr); 01053 01054 return 0; 01055 } 01056 01057 IceModel_divoldt::IceModel_divoldt(IceModel *m, IceGrid &g, PISMVars &my_vars) 01058 : PISMTSDiag<IceModel>(m, g, my_vars) { 01059 01060 // set metadata: 01061 // set metadata: 01062 ts = new DiagnosticTimeseries(&grid, "divoldt", time_dimension_name); 01063 01064 ts->set_units("m3 s-1", ""); 01065 ts->set_dimension_units(time_units, ""); 01066 ts->rate_of_change = true; 01067 01068 ts->set_attr("long_name", "total ice volume rate of change"); 01069 } 01070 01071 PetscErrorCode IceModel_divoldt::update(PetscReal a, PetscReal b) { 01072 PetscErrorCode ierr; 01073 PetscReal value; 01074 01075 ierr = model->compute_ice_volume(value); CHKERRQ(ierr); 01076 01077 // note that "value" below *should* be the ice volume 01078 ts->append(value, a, b); 01079 01080 return 0; 01081 } 01082 01083 01084 IceModel_iarea::IceModel_iarea(IceModel *m, IceGrid &g, PISMVars &my_vars) 01085 : PISMTSDiag<IceModel>(m, g, my_vars) { 01086 01087 // set metadata: 01088 // set metadata: 01089 ts = new DiagnosticTimeseries(&grid, "iarea", time_dimension_name); 01090 01091 ts->set_units("m2", ""); 01092 ts->set_dimension_units(time_units, ""); 01093 ts->set_attr("long_name", "total ice area"); 01094 ts->set_attr("valid_min", 0.0); 01095 } 01096 01097 PetscErrorCode IceModel_iarea::update(PetscReal a, PetscReal b) { 01098 PetscErrorCode ierr; 01099 PetscReal value; 01100 01101 ierr = model->compute_ice_area(value); CHKERRQ(ierr); 01102 01103 ierr = ts->append(value, a, b); CHKERRQ(ierr); 01104 01105 return 0; 01106 } 01107 01108 IceModel_imass::IceModel_imass(IceModel *m, IceGrid &g, PISMVars &my_vars) 01109 : PISMTSDiag<IceModel>(m, g, my_vars) { 01110 01111 // set metadata: 01112 // set metadata: 01113 ts = new DiagnosticTimeseries(&grid, "imass", time_dimension_name); 01114 01115 ts->set_units("kg", ""); 01116 ts->set_dimension_units(time_units, ""); 01117 ts->set_attr("long_name", "total ice mass"); 01118 ts->set_attr("valid_min", 0.0); 01119 } 01120 01121 PetscErrorCode IceModel_imass::update(PetscReal a, PetscReal b) { 01122 PetscErrorCode ierr; 01123 PetscReal value; 01124 01125 ierr = model->compute_ice_volume(value); CHKERRQ(ierr); 01126 01127 ierr = ts->append(value * grid.config.get("ice_density"), a, b); CHKERRQ(ierr); 01128 01129 return 0; 01130 } 01131 01132 01133 IceModel_dimassdt::IceModel_dimassdt(IceModel *m, IceGrid &g, PISMVars &my_vars) 01134 : PISMTSDiag<IceModel>(m, g, my_vars) { 01135 01136 // set metadata: 01137 // set metadata: 01138 ts = new DiagnosticTimeseries(&grid, "dimassdt", time_dimension_name); 01139 01140 ts->set_units("kg s-1", ""); 01141 ts->set_dimension_units(time_units, ""); 01142 ts->set_attr("long_name", "total ice mass rate of change"); 01143 01144 ts->rate_of_change = true; 01145 } 01146 01147 PetscErrorCode IceModel_dimassdt::update(PetscReal a, PetscReal b) { 01148 PetscErrorCode ierr; 01149 PetscReal value; 01150 01151 ierr = model->compute_ice_volume(value); CHKERRQ(ierr); 01152 01153 ierr = ts->append(value * grid.config.get("ice_density"), a, b); CHKERRQ(ierr); 01154 01155 return 0; 01156 } 01157 01158 01159 IceModel_ivoltemp::IceModel_ivoltemp(IceModel *m, IceGrid &g, PISMVars &my_vars) 01160 : PISMTSDiag<IceModel>(m, g, my_vars) { 01161 01162 // set metadata: 01163 // set metadata: 01164 ts = new DiagnosticTimeseries(&grid, "ivoltemp", time_dimension_name); 01165 01166 ts->set_units("m3", ""); 01167 ts->set_dimension_units(time_units, ""); 01168 ts->set_attr("long_name", "total volume of temperate ice"); 01169 ts->set_attr("valid_min", 0.0); 01170 } 01171 01172 PetscErrorCode IceModel_ivoltemp::update(PetscReal a, PetscReal b) { 01173 PetscErrorCode ierr; 01174 PetscReal value; 01175 01176 ierr = model->compute_ice_volume_temperate(value); CHKERRQ(ierr); 01177 01178 ierr = ts->append(value, a, b); CHKERRQ(ierr); 01179 01180 return 0; 01181 } 01182 01183 IceModel_ivoltempf::IceModel_ivoltempf(IceModel *m, IceGrid &g, PISMVars &my_vars) 01184 : PISMTSDiag<IceModel>(m, g, my_vars) { 01185 01186 // set metadata: 01187 // set metadata: 01188 ts = new DiagnosticTimeseries(&grid, "ivoltempf", time_dimension_name); 01189 01190 ts->set_units("1", ""); 01191 ts->set_dimension_units(time_units, ""); 01192 ts->set_attr("long_name", "temperate ice volume fraction"); 01193 ts->set_attr("valid_min", 0.0); 01194 ts->set_attr("valid_max", 1.0); 01195 } 01196 01197 PetscErrorCode IceModel_ivoltempf::update(PetscReal a, PetscReal b) { 01198 PetscErrorCode ierr; 01199 PetscReal value, ivol; 01200 01201 ierr = model->compute_ice_volume(ivol); CHKERRQ(ierr); 01202 ierr = model->compute_ice_volume_temperate(value); CHKERRQ(ierr); 01203 01204 if (ivol > 0) { 01205 value /= ivol; 01206 } else { 01207 value = 0; 01208 } 01209 01210 ierr = ts->append(value, a, b); CHKERRQ(ierr); 01211 01212 return 0; 01213 } 01214 01215 IceModel_ivolcold::IceModel_ivolcold(IceModel *m, IceGrid &g, PISMVars &my_vars) 01216 : PISMTSDiag<IceModel>(m, g, my_vars) { 01217 01218 // set metadata: 01219 // set metadata: 01220 ts = new DiagnosticTimeseries(&grid, "ivolcold", time_dimension_name); 01221 01222 ts->set_units("m3", ""); 01223 ts->set_dimension_units(time_units, ""); 01224 ts->set_attr("long_name", "total volume of cold ice"); 01225 ts->set_attr("valid_min", 0.0); 01226 } 01227 01228 PetscErrorCode IceModel_ivolcold::update(PetscReal a, PetscReal b) { 01229 PetscErrorCode ierr; 01230 PetscReal value; 01231 01232 ierr = model->compute_ice_volume_cold(value); CHKERRQ(ierr); 01233 01234 ierr = ts->append(value, a, b); CHKERRQ(ierr); 01235 01236 return 0; 01237 } 01238 01239 IceModel_ivolcoldf::IceModel_ivolcoldf(IceModel *m, IceGrid &g, PISMVars &my_vars) 01240 : PISMTSDiag<IceModel>(m, g, my_vars) { 01241 01242 // set metadata: 01243 // set metadata: 01244 ts = new DiagnosticTimeseries(&grid, "ivolcoldf", time_dimension_name); 01245 01246 ts->set_units("1", ""); 01247 ts->set_dimension_units(time_units, ""); 01248 ts->set_attr("long_name", "cold ice volume fraction"); 01249 ts->set_attr("valid_min", 0.0); 01250 ts->set_attr("valid_max", 1.0); 01251 } 01252 01253 PetscErrorCode IceModel_ivolcoldf::update(PetscReal a, PetscReal b) { 01254 PetscErrorCode ierr; 01255 PetscReal value, ivol; 01256 01257 ierr = model->compute_ice_volume(ivol); CHKERRQ(ierr); 01258 ierr = model->compute_ice_volume_cold(value); CHKERRQ(ierr); 01259 01260 if (ivol > 0) { 01261 value /= ivol; 01262 } else { 01263 value = 0; 01264 } 01265 01266 ierr = ts->append(value, a, b); CHKERRQ(ierr); 01267 01268 return 0; 01269 } 01270 IceModel_iareatemp::IceModel_iareatemp(IceModel *m, IceGrid &g, PISMVars &my_vars) 01271 : PISMTSDiag<IceModel>(m, g, my_vars) { 01272 01273 // set metadata: 01274 // set metadata: 01275 ts = new DiagnosticTimeseries(&grid, "iareatemp", time_dimension_name); 01276 01277 ts->set_units("m2", ""); 01278 ts->set_dimension_units(time_units, ""); 01279 ts->set_attr("long_name", "ice-covered area where basal ice is temperate"); 01280 ts->set_attr("valid_min", 0.0); 01281 } 01282 01283 PetscErrorCode IceModel_iareatemp::update(PetscReal a, PetscReal b) { 01284 PetscErrorCode ierr; 01285 PetscReal value; 01286 01287 ierr = model->compute_ice_area_temperate(value); CHKERRQ(ierr); 01288 01289 ierr = ts->append(value, a, b); CHKERRQ(ierr); 01290 01291 return 0; 01292 } 01293 01294 IceModel_iareatempf::IceModel_iareatempf(IceModel *m, IceGrid &g, PISMVars &my_vars) 01295 : PISMTSDiag<IceModel>(m, g, my_vars) { 01296 01297 // set metadata: 01298 // set metadata: 01299 ts = new DiagnosticTimeseries(&grid, "iareatempf", time_dimension_name); 01300 01301 ts->set_units("1", ""); 01302 ts->set_dimension_units(time_units, ""); 01303 ts->set_attr("long_name", "fraction of ice-covered area where basal ice is temperate"); 01304 ts->set_attr("valid_min", 0.0); 01305 ts->set_attr("valid_max", 1.0); 01306 } 01307 01308 PetscErrorCode IceModel_iareatempf::update(PetscReal a, PetscReal b) { 01309 PetscErrorCode ierr; 01310 PetscReal value, iarea; 01311 01312 ierr = model->compute_ice_area(iarea); CHKERRQ(ierr); 01313 ierr = model->compute_ice_area_temperate(value); CHKERRQ(ierr); 01314 01315 if (iarea > 0) { 01316 value /= iarea; 01317 } else { 01318 value = 0; 01319 } 01320 01321 ierr = ts->append(value, a, b); CHKERRQ(ierr); 01322 01323 return 0; 01324 } 01325 01326 IceModel_iareacold::IceModel_iareacold(IceModel *m, IceGrid &g, PISMVars &my_vars) 01327 : PISMTSDiag<IceModel>(m, g, my_vars) { 01328 01329 // set metadata: 01330 // set metadata: 01331 ts = new DiagnosticTimeseries(&grid, "iareacold", time_dimension_name); 01332 01333 ts->set_units("m2", ""); 01334 ts->set_dimension_units(time_units, ""); 01335 ts->set_attr("long_name", "ice-covered area where basal ice is cold"); 01336 ts->set_attr("valid_min", 0.0); 01337 } 01338 01339 PetscErrorCode IceModel_iareacold::update(PetscReal a, PetscReal b) { 01340 PetscErrorCode ierr; 01341 PetscReal value; 01342 01343 ierr = model->compute_ice_area_cold(value); CHKERRQ(ierr); 01344 01345 ierr = ts->append(value, a, b); CHKERRQ(ierr); 01346 01347 return 0; 01348 } 01349 01350 IceModel_iareacoldf::IceModel_iareacoldf(IceModel *m, IceGrid &g, PISMVars &my_vars) 01351 : PISMTSDiag<IceModel>(m, g, my_vars) { 01352 01353 // set metadata: 01354 // set metadata: 01355 ts = new DiagnosticTimeseries(&grid, "iareacoldf", time_dimension_name); 01356 01357 ts->set_units("1", ""); 01358 ts->set_dimension_units(time_units, ""); 01359 ts->set_attr("long_name", "fraction of ice-covered area where basal ice is cold"); 01360 ts->set_attr("valid_min", 0.0); 01361 ts->set_attr("valid_max", 1.0); 01362 } 01363 01364 PetscErrorCode IceModel_iareacoldf::update(PetscReal a, PetscReal b) { 01365 PetscErrorCode ierr; 01366 PetscReal value, iarea; 01367 01368 ierr = model->compute_ice_area(iarea); CHKERRQ(ierr); 01369 ierr = model->compute_ice_area_cold(value); CHKERRQ(ierr); 01370 01371 if (iarea > 0) { 01372 value /= iarea; 01373 } else { 01374 value = 0; 01375 } 01376 01377 ierr = ts->append(value, a, b); CHKERRQ(ierr); 01378 01379 return 0; 01380 } 01381 01382 IceModel_ienthalpy::IceModel_ienthalpy(IceModel *m, IceGrid &g, PISMVars &my_vars) 01383 : PISMTSDiag<IceModel>(m, g, my_vars) { 01384 01385 // set metadata: 01386 ts = new DiagnosticTimeseries(&grid, "ienthalpy", time_dimension_name); 01387 01388 ts->set_units("J", ""); 01389 ts->set_dimension_units(time_units, ""); 01390 ts->set_attr("long_name", "total ice enthalpy"); 01391 ts->set_attr("valid_min", 0.0); 01392 } 01393 01394 PetscErrorCode IceModel_ienthalpy::update(PetscReal a, PetscReal b) { 01395 PetscErrorCode ierr; 01396 PetscReal value; 01397 01398 ierr = model->compute_ice_enthalpy(value); CHKERRQ(ierr); 01399 01400 ierr = ts->append(value, a, b); CHKERRQ(ierr); 01401 01402 return 0; 01403 } 01404 01405 IceModel_iareag::IceModel_iareag(IceModel *m, IceGrid &g, PISMVars &my_vars) 01406 : PISMTSDiag<IceModel>(m, g, my_vars) { 01407 01408 // set metadata: 01409 ts = new DiagnosticTimeseries(&grid, "iareag", time_dimension_name); 01410 01411 ts->set_units("m2", ""); 01412 ts->set_dimension_units(time_units, ""); 01413 ts->set_attr("long_name", "total grounded ice area"); 01414 } 01415 01416 PetscErrorCode IceModel_iareag::update(PetscReal a, PetscReal b) { 01417 PetscErrorCode ierr; 01418 PetscReal value; 01419 01420 ierr = model->compute_ice_area_grounded(value); CHKERRQ(ierr); 01421 01422 ierr = ts->append(value, a, b); CHKERRQ(ierr); 01423 01424 return 0; 01425 } 01426 01427 IceModel_iareaf::IceModel_iareaf(IceModel *m, IceGrid &g, PISMVars &my_vars) 01428 : PISMTSDiag<IceModel>(m, g, my_vars) { 01429 01430 // set metadata: 01431 ts = new DiagnosticTimeseries(&grid, "iareaf", time_dimension_name); 01432 01433 ts->set_units("m2", ""); 01434 ts->set_dimension_units(time_units, ""); 01435 ts->set_attr("long_name", "total floating ice area"); 01436 } 01437 01438 PetscErrorCode IceModel_iareaf::update(PetscReal a, PetscReal b) { 01439 PetscErrorCode ierr; 01440 PetscReal value; 01441 01442 ierr = model->compute_ice_area_floating(value); CHKERRQ(ierr); 01443 01444 ierr = ts->append(value, a, b); CHKERRQ(ierr); 01445 01446 return 0; 01447 } 01448 01449 IceModel_dt::IceModel_dt(IceModel *m, IceGrid &g, PISMVars &my_vars) 01450 : PISMTSDiag<IceModel>(m, g, my_vars) { 01451 01452 // set metadata: 01453 ts = new DiagnosticTimeseries(&grid, "dt", time_dimension_name); 01454 01455 ts->set_units("second", "year"); 01456 ts->set_dimension_units(time_units, ""); 01457 ts->set_attr("long_name", "mass continuity time step"); 01458 } 01459 01460 PetscErrorCode IceModel_dt::update(PetscReal a, PetscReal b) { 01461 PetscErrorCode ierr; 01462 01463 ierr = ts->append(model->dt, a, b); CHKERRQ(ierr); 01464 01465 return 0; 01466 } 01467 01468 IceModel_max_diffusivity::IceModel_max_diffusivity(IceModel *m, IceGrid &g, PISMVars &my_vars) 01469 : PISMTSDiag<IceModel>(m, g, my_vars) { 01470 01471 // set metadata: 01472 ts = new DiagnosticTimeseries(&grid, "max_diffusivity", time_dimension_name); 01473 01474 ts->set_units("m2 s-1", ""); 01475 ts->set_dimension_units(time_units, ""); 01476 ts->set_attr("long_name", "maximum diffusivity"); 01477 } 01478 01479 PetscErrorCode IceModel_max_diffusivity::update(PetscReal a, PetscReal b) { 01480 PetscErrorCode ierr; 01481 PetscReal value; 01482 01483 ierr = model->stress_balance->get_max_diffusivity(value); CHKERRQ(ierr); 01484 01485 ierr = ts->append(value, a, b); CHKERRQ(ierr); 01486 01487 return 0; 01488 } 01489 01490 IceModel_surface_flux::IceModel_surface_flux(IceModel *m, IceGrid &g, PISMVars &my_vars) 01491 : PISMTSDiag<IceModel>(m, g, my_vars) { 01492 01493 // set metadata: 01494 ts = new DiagnosticTimeseries(&grid, "surface_ice_flux", time_dimension_name); 01495 01496 ts->set_units("kg s-1", ""); 01497 ts->set_dimension_units(time_units, ""); 01498 ts->set_attr("long_name", "total over ice domain of top surface ice mass flux"); 01499 ts->rate_of_change = true; 01500 } 01501 01502 PetscErrorCode IceModel_surface_flux::update(PetscReal a, PetscReal b) { 01503 PetscErrorCode ierr; 01504 PetscReal value; 01505 01506 value = model->cumulative_surface_ice_flux; 01507 01508 ierr = ts->append(value, a, b); CHKERRQ(ierr); 01509 01510 return 0; 01511 } 01512 01513 IceModel_cumulative_surface_flux::IceModel_cumulative_surface_flux(IceModel *m, IceGrid &g, PISMVars &my_vars) 01514 : PISMTSDiag<IceModel>(m, g, my_vars) { 01515 01516 // set metadata: 01517 ts = new DiagnosticTimeseries(&grid, "cumulative_surface_ice_flux", time_dimension_name); 01518 01519 ts->set_units("kg", ""); 01520 ts->set_dimension_units(time_units, ""); 01521 ts->set_attr("long_name", "cumulative total over ice domain of top surface ice mass flux"); 01522 } 01523 01524 PetscErrorCode IceModel_cumulative_surface_flux::update(PetscReal a, PetscReal b) { 01525 PetscErrorCode ierr; 01526 PetscReal value; 01527 01528 value = model->cumulative_surface_ice_flux; 01529 01530 ierr = ts->append(value, a, b); CHKERRQ(ierr); 01531 01532 return 0; 01533 } 01534 01535 IceModel_basal_flux::IceModel_basal_flux(IceModel *m, IceGrid &g, PISMVars &my_vars) 01536 : PISMTSDiag<IceModel>(m, g, my_vars) { 01537 01538 // set metadata: 01539 ts = new DiagnosticTimeseries(&grid, "basal_ice_flux", time_dimension_name); 01540 01541 ts->set_units("kg s-1", ""); 01542 ts->set_dimension_units(time_units, ""); 01543 ts->set_attr("long_name", "total basal ice flux"); 01544 ts->rate_of_change = true; 01545 } 01546 01547 PetscErrorCode IceModel_basal_flux::update(PetscReal a, PetscReal b) { 01548 PetscErrorCode ierr; 01549 PetscReal value; 01550 01551 value = model->cumulative_basal_ice_flux; 01552 01553 ierr = ts->append(value, a, b); CHKERRQ(ierr); 01554 01555 return 0; 01556 } 01557 01558 IceModel_cumulative_basal_flux::IceModel_cumulative_basal_flux(IceModel *m, IceGrid &g, PISMVars &my_vars) 01559 : PISMTSDiag<IceModel>(m, g, my_vars) { 01560 01561 // set metadata: 01562 ts = new DiagnosticTimeseries(&grid, "cumulative_basal_ice_flux", time_dimension_name); 01563 01564 ts->set_units("kg", ""); 01565 ts->set_dimension_units(time_units, ""); 01566 ts->set_attr("long_name", "cumulative total basal ice flux"); 01567 } 01568 01569 PetscErrorCode IceModel_cumulative_basal_flux::update(PetscReal a, PetscReal b) { 01570 PetscErrorCode ierr; 01571 PetscReal value; 01572 01573 value = model->cumulative_basal_ice_flux; 01574 01575 ierr = ts->append(value, a, b); CHKERRQ(ierr); 01576 01577 return 0; 01578 } 01579 01580 IceModel_sub_shelf_flux::IceModel_sub_shelf_flux(IceModel *m, IceGrid &g, PISMVars &my_vars) 01581 : PISMTSDiag<IceModel>(m, g, my_vars) { 01582 01583 // set metadata: 01584 ts = new DiagnosticTimeseries(&grid, "sub_shelf_ice_flux", time_dimension_name); 01585 01586 ts->set_units("kg s-1", ""); 01587 ts->set_dimension_units(time_units, ""); 01588 ts->set_attr("long_name", "total sub-shelf ice flux"); 01589 ts->rate_of_change = true; 01590 } 01591 01592 PetscErrorCode IceModel_sub_shelf_flux::update(PetscReal a, PetscReal b) { 01593 PetscErrorCode ierr; 01594 PetscReal value; 01595 01596 value = model->cumulative_sub_shelf_ice_flux; 01597 01598 ierr = ts->append(value, a, b); CHKERRQ(ierr); 01599 01600 return 0; 01601 } 01602 01603 IceModel_cumulative_sub_shelf_flux::IceModel_cumulative_sub_shelf_flux(IceModel *m, IceGrid &g, PISMVars &my_vars) 01604 : PISMTSDiag<IceModel>(m, g, my_vars) { 01605 01606 // set metadata: 01607 ts = new DiagnosticTimeseries(&grid, "cumulative_sub_shelf_ice_flux", time_dimension_name); 01608 01609 ts->set_units("kg", ""); 01610 ts->set_dimension_units(time_units, ""); 01611 ts->set_attr("long_name", "cumulative total sub-shelf ice flux"); 01612 } 01613 01614 PetscErrorCode IceModel_cumulative_sub_shelf_flux::update(PetscReal a, PetscReal b) { 01615 PetscErrorCode ierr; 01616 PetscReal value; 01617 01618 value = model->cumulative_sub_shelf_ice_flux; 01619 01620 ierr = ts->append(value, a, b); CHKERRQ(ierr); 01621 01622 return 0; 01623 } 01624 01625 IceModel_nonneg_flux::IceModel_nonneg_flux(IceModel *m, IceGrid &g, PISMVars &my_vars) 01626 : PISMTSDiag<IceModel>(m, g, my_vars) { 01627 01628 // set metadata: 01629 ts = new DiagnosticTimeseries(&grid, "nonneg_flux", time_dimension_name); 01630 01631 ts->set_units("kg s-1", ""); 01632 ts->set_dimension_units(time_units, ""); 01633 ts->set_attr("long_name", "'numerical' ice flux resulting from enforcing the 'thk >= 0' rule"); 01634 ts->rate_of_change = true; 01635 } 01636 01637 PetscErrorCode IceModel_nonneg_flux::update(PetscReal a, PetscReal b) { 01638 PetscErrorCode ierr; 01639 PetscReal value; 01640 01641 value = model->cumulative_nonneg_rule_flux; 01642 01643 ierr = ts->append(value, a, b); CHKERRQ(ierr); 01644 01645 return 0; 01646 } 01647 01648 IceModel_cumulative_nonneg_flux::IceModel_cumulative_nonneg_flux(IceModel *m, IceGrid &g, PISMVars &my_vars) 01649 : PISMTSDiag<IceModel>(m, g, my_vars) { 01650 01651 // set metadata: 01652 ts = new DiagnosticTimeseries(&grid, "cumulative_nonneg_flux", time_dimension_name); 01653 01654 ts->set_units("kg", ""); 01655 ts->set_dimension_units(time_units, ""); 01656 ts->set_attr("long_name", "cumulative 'numerical' ice flux resulting from enforcing the 'thk >= 0' rule"); 01657 } 01658 01659 PetscErrorCode IceModel_cumulative_nonneg_flux::update(PetscReal a, PetscReal b) { 01660 PetscErrorCode ierr; 01661 PetscReal value; 01662 01663 value = model->cumulative_nonneg_rule_flux; 01664 01665 ierr = ts->append(value, a, b); CHKERRQ(ierr); 01666 01667 return 0; 01668 } 01669 01670 IceModel_ocean_kill_flux::IceModel_ocean_kill_flux(IceModel *m, IceGrid &g, PISMVars &my_vars) 01671 : PISMTSDiag<IceModel>(m, g, my_vars) { 01672 01673 // set metadata: 01674 ts = new DiagnosticTimeseries(&grid, "ocean_kill_flux", time_dimension_name); 01675 01676 ts->set_units("kg s-1", ""); 01677 ts->set_dimension_units(time_units, ""); 01678 ts->set_attr("long_name", "-ocean_kill flux"); 01679 ts->rate_of_change = true; 01680 } 01681 01682 PetscErrorCode IceModel_ocean_kill_flux::update(PetscReal a, PetscReal b) { 01683 PetscErrorCode ierr; 01684 PetscReal value; 01685 01686 value = model->cumulative_ocean_kill_flux; 01687 01688 ierr = ts->append(value, a, b); CHKERRQ(ierr); 01689 01690 return 0; 01691 } 01692 01693 IceModel_cumulative_ocean_kill_flux::IceModel_cumulative_ocean_kill_flux(IceModel *m, IceGrid &g, PISMVars &my_vars) 01694 : PISMTSDiag<IceModel>(m, g, my_vars) { 01695 01696 // set metadata: 01697 ts = new DiagnosticTimeseries(&grid, "cumulative_ocean_kill_flux", time_dimension_name); 01698 01699 ts->set_units("kg", ""); 01700 ts->set_dimension_units(time_units, ""); 01701 ts->set_attr("long_name", "cumulative -ocean_kill flux"); 01702 } 01703 01704 PetscErrorCode IceModel_cumulative_ocean_kill_flux::update(PetscReal a, PetscReal b) { 01705 PetscErrorCode ierr; 01706 PetscReal value; 01707 01708 value = model->cumulative_ocean_kill_flux; 01709 01710 ierr = ts->append(value, a, b); CHKERRQ(ierr); 01711 01712 return 0; 01713 } 01714 01715 IceModel_float_kill_flux::IceModel_float_kill_flux(IceModel *m, IceGrid &g, PISMVars &my_vars) 01716 : PISMTSDiag<IceModel>(m, g, my_vars) { 01717 01718 // set metadata: 01719 ts = new DiagnosticTimeseries(&grid, "float_kill_flux", time_dimension_name); 01720 01721 ts->set_units("kg s-1", ""); 01722 ts->set_dimension_units(time_units, ""); 01723 ts->set_attr("long_name", "-float_kill flux"); 01724 ts->rate_of_change = true; 01725 } 01726 01727 PetscErrorCode IceModel_float_kill_flux::update(PetscReal a, PetscReal b) { 01728 PetscErrorCode ierr; 01729 PetscReal value; 01730 01731 value = model->cumulative_float_kill_flux; 01732 01733 ierr = ts->append(value, a, b); CHKERRQ(ierr); 01734 01735 return 0; 01736 } 01737 01738 IceModel_cumulative_float_kill_flux::IceModel_cumulative_float_kill_flux(IceModel *m, IceGrid &g, PISMVars &my_vars) 01739 : PISMTSDiag<IceModel>(m, g, my_vars) { 01740 01741 // set metadata: 01742 ts = new DiagnosticTimeseries(&grid, "cumulative_float_kill_flux", time_dimension_name); 01743 01744 ts->set_units("kg", ""); 01745 ts->set_dimension_units(time_units, ""); 01746 ts->set_attr("long_name", "cumulative -float_kill flux"); 01747 } 01748 01749 PetscErrorCode IceModel_cumulative_float_kill_flux::update(PetscReal a, PetscReal b) { 01750 PetscErrorCode ierr; 01751 PetscReal value; 01752 01753 value = model->cumulative_float_kill_flux; 01754 01755 ierr = ts->append(value, a, b); CHKERRQ(ierr); 01756 01757 return 0; 01758 } 01759 01760 IceModel_discharge_flux::IceModel_discharge_flux(IceModel *m, IceGrid &g, PISMVars &my_vars) 01761 : PISMTSDiag<IceModel>(m, g, my_vars) { 01762 01763 // set metadata: 01764 ts = new DiagnosticTimeseries(&grid, "discharge_flux", time_dimension_name); 01765 01766 ts->set_units("kg s-1", ""); 01767 ts->set_dimension_units(time_units, ""); 01768 ts->set_attr("long_name", "discharge (calving & icebergs) flux"); 01769 ts->rate_of_change = true; 01770 } 01771 01772 PetscErrorCode IceModel_discharge_flux::update(PetscReal a, PetscReal b) { 01773 PetscErrorCode ierr; 01774 PetscReal value; 01775 01776 value = model->cumulative_discharge_flux; 01777 01778 ierr = ts->append(value, a, b); CHKERRQ(ierr); 01779 01780 return 0; 01781 } 01782 01783 IceModel_cumulative_discharge_flux::IceModel_cumulative_discharge_flux(IceModel *m, IceGrid &g, PISMVars &my_vars) 01784 : PISMTSDiag<IceModel>(m, g, my_vars) { 01785 01786 // set metadata: 01787 ts = new DiagnosticTimeseries(&grid, "cumulative_discharge_flux", time_dimension_name); 01788 01789 ts->set_units("kg", ""); 01790 ts->set_dimension_units(time_units, ""); 01791 ts->set_attr("long_name", "cumulative discharge (calving etc.) flux"); 01792 } 01793 01794 PetscErrorCode IceModel_cumulative_discharge_flux::update(PetscReal a, PetscReal b) { 01795 PetscErrorCode ierr; 01796 PetscReal value; 01797 01798 value = model->cumulative_discharge_flux; 01799 01800 ierr = ts->append(value, a, b); CHKERRQ(ierr); 01801 01802 return 0; 01803 } 01804 01805 IceModel_dHdt::IceModel_dHdt(IceModel *m, IceGrid &g, PISMVars &my_vars) 01806 : PISMDiag<IceModel>(m, g, my_vars) { 01807 01808 // set metadata: 01809 vars[0].init_2d("dHdt", grid); 01810 01811 set_attrs("ice thickness rate of change", "tendency_of_land_ice_thickness", 01812 "m s-1", "m year-1", 0); 01813 01814 vars[0].set("valid_min", convert(-1e6, "m/year", "m/s")); 01815 vars[0].set("valid_max", convert( 1e6, "m/year", "m/s")); 01816 vars[0].set("_FillValue", convert( 2e6, "m/year", "m/s")); 01817 vars[0].set_string("cell_methods", "time: mean"); 01818 01819 last_ice_thickness.create(grid, "last_ice_thickness", false); 01820 last_ice_thickness.set_attrs("internal", 01821 "ice thickness at the time of the last report of dHdt", 01822 "m", "land_ice_thickness"); 01823 01824 last_report_time = GSL_NAN; 01825 } 01826 01827 PetscErrorCode IceModel_dHdt::compute(IceModelVec* &output) { 01828 PetscErrorCode ierr; 01829 01830 IceModelVec2S *result = new IceModelVec2S; 01831 ierr = result->create(grid, "dHdt", false); CHKERRQ(ierr); 01832 ierr = result->set_metadata(vars[0], 0); CHKERRQ(ierr); 01833 result->write_in_glaciological_units = true; 01834 01835 if (gsl_isnan(last_report_time)) { 01836 ierr = result->set(convert(2e6, "m/year", "m/s")); CHKERRQ(ierr); 01837 } else { 01838 01839 ierr = result->begin_access(); CHKERRQ(ierr); 01840 ierr = last_ice_thickness.begin_access(); CHKERRQ(ierr); 01841 ierr = model->vH.begin_access(); CHKERRQ(ierr); 01842 01843 PetscReal dt = grid.time->current() - last_report_time; 01844 for (PetscInt i = grid.xs; i < grid.xs+grid.xm; ++i) { 01845 for (PetscInt j = grid.ys; j < grid.ys+grid.ym; ++j) { 01846 (*result)(i, j) = (model->vH(i, j) - last_ice_thickness(i, j)) / dt; 01847 } 01848 } 01849 01850 ierr = model->vH.end_access(); CHKERRQ(ierr); 01851 ierr = last_ice_thickness.end_access(); CHKERRQ(ierr); 01852 ierr = result->end_access(); CHKERRQ(ierr); 01853 01854 } 01855 01856 // Save the ice thickness and the corresponding time: 01857 ierr = this->update_cumulative(); CHKERRQ(ierr); 01858 01859 output = result; 01860 return 0; 01861 } 01862 01863 PetscErrorCode IceModel_dHdt::update_cumulative() { 01864 PetscErrorCode ierr; 01865 ierr = model->vH.begin_access(); CHKERRQ(ierr); 01866 ierr = last_ice_thickness.begin_access(); CHKERRQ(ierr); 01867 01868 for (PetscInt i = grid.xs; i < grid.xs+grid.xm; ++i) { 01869 for (PetscInt j = grid.ys; j < grid.ys+grid.ym; ++j) { 01870 last_ice_thickness(i, j) = model->vH(i, j); 01871 } 01872 } 01873 01874 ierr = last_ice_thickness.end_access(); CHKERRQ(ierr); 01875 ierr = model->vH.end_access(); CHKERRQ(ierr); 01876 01877 last_report_time = grid.time->current(); 01878 01879 return 0; 01880 } 01881 01882 IceModel_ivolg::IceModel_ivolg(IceModel *m, IceGrid &g, PISMVars &my_vars) 01883 : PISMTSDiag<IceModel>(m, g, my_vars) { 01884 01885 // set metadata: 01886 ts = new DiagnosticTimeseries(&grid, "ivolg", time_dimension_name); 01887 01888 ts->set_units("m3", ""); 01889 ts->set_dimension_units(time_units, ""); 01890 ts->set_attr("long_name", "total grounded ice volume"); 01891 } 01892 01893 PetscErrorCode IceModel_ivolg::update(PetscReal a, PetscReal b) { 01894 PetscErrorCode ierr; 01895 PetscReal volume=0.0, value; 01896 01897 MaskQuery mask(model->vMask); 01898 01899 ierr = model->vH.begin_access(); CHKERRQ(ierr); 01900 ierr = model->vMask.begin_access(); CHKERRQ(ierr); 01901 ierr = model->cell_area.begin_access(); CHKERRQ(ierr); 01902 for (PetscInt i=grid.xs; i<grid.xs+grid.xm; ++i) { 01903 for (PetscInt j=grid.ys; j<grid.ys+grid.ym; ++j) { 01904 if (mask.grounded_ice(i,j)) 01905 volume += model->cell_area(i,j) * model->vH(i,j);; 01906 } 01907 } 01908 ierr = model->cell_area.end_access(); CHKERRQ(ierr); 01909 ierr = model->vMask.end_access(); CHKERRQ(ierr); 01910 ierr = model->vH.end_access(); CHKERRQ(ierr); 01911 01912 ierr = PISMGlobalSum(&volume, &value, grid.com); CHKERRQ(ierr); 01913 01914 ierr = ts->append(value, a, b); CHKERRQ(ierr); 01915 01916 return 0; 01917 } 01918 01919 IceModel_ivolf::IceModel_ivolf(IceModel *m, IceGrid &g, PISMVars &my_vars) 01920 : PISMTSDiag<IceModel>(m, g, my_vars) { 01921 01922 // set metadata: 01923 ts = new DiagnosticTimeseries(&grid, "ivolf", time_dimension_name); 01924 01925 ts->set_units("m3", ""); 01926 ts->set_dimension_units(time_units, ""); 01927 ts->set_attr("long_name", "total floating ice volume"); 01928 } 01929 01930 PetscErrorCode IceModel_ivolf::update(PetscReal a, PetscReal b) { 01931 PetscErrorCode ierr; 01932 PetscReal volume=0.0, value; 01933 01934 MaskQuery mask(model->vMask); 01935 01936 ierr = model->vH.begin_access(); CHKERRQ(ierr); 01937 ierr = model->vMask.begin_access(); CHKERRQ(ierr); 01938 ierr = model->cell_area.begin_access(); CHKERRQ(ierr); 01939 for (PetscInt i=grid.xs; i<grid.xs+grid.xm; ++i) { 01940 for (PetscInt j=grid.ys; j<grid.ys+grid.ym; ++j) { 01941 if (mask.floating_ice(i,j)) 01942 volume += model->cell_area(i,j) * model->vH(i,j);; 01943 } 01944 } 01945 ierr = model->cell_area.end_access(); CHKERRQ(ierr); 01946 ierr = model->vMask.end_access(); CHKERRQ(ierr); 01947 ierr = model->vH.end_access(); CHKERRQ(ierr); 01948 01949 ierr = PISMGlobalSum(&volume, &value, grid.com); CHKERRQ(ierr); 01950 01951 ierr = ts->append(value, a, b); CHKERRQ(ierr); 01952 01953 return 0; 01954 } 01955 01957 01967 IceModel_max_hor_vel::IceModel_max_hor_vel(IceModel *m, IceGrid &g, PISMVars &my_vars) 01968 : PISMTSDiag<IceModel>(m, g, my_vars) { 01969 01970 // set metadata: 01971 ts = new DiagnosticTimeseries(&grid, "max_hor_vel", time_dimension_name); 01972 01973 ts->set_units("m/second", "m/year"); 01974 ts->set_dimension_units(time_units, ""); 01975 ts->set_attr("long_name", "maximum abs component of horizontal ice velocity over grid in last time step during time-series reporting interval"); 01976 } 01977 01978 PetscErrorCode IceModel_max_hor_vel::update(PetscReal a, PetscReal b) { 01979 PetscErrorCode ierr; 01980 01981 double gmaxu = model->gmaxu, gmaxv = model->gmaxv; 01982 01983 ierr = ts->append(gmaxu > gmaxv ? gmaxu : gmaxv, a, b); CHKERRQ(ierr); 01984 01985 return 0; 01986 }
1.7.5.1