PISM, A Parallel Ice Sheet Model stable 0.4.1779

src/base/iMreport.cc

Go to the documentation of this file.
00001 // Copyright (C) 2004-2011 Jed Brown, Ed Bueler and 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 <cstring>
00020 #include "iceModel.hh"
00021 #include "Mask.hh"
00022 
00023 #include <petscsys.h>
00024 #include <stdarg.h>
00025 #include <stdlib.h>
00026 
00028 
00035 PetscErrorCode IceModel::volumeArea(PetscScalar& gvolume, PetscScalar& garea,
00036                                     PetscScalar& gvolSIA, PetscScalar& gvolstream, 
00037                                     PetscScalar& gvolshelf) {
00038 
00039   PetscErrorCode  ierr;
00040   PetscScalar     volume=0.0, area=0.0, volSIA=0.0, volstream=0.0, volshelf=0.0;
00041   
00042   ierr = vH.begin_access(); CHKERRQ(ierr);
00043   ierr = vMask.begin_access(); CHKERRQ(ierr);
00044   ierr = cell_area.begin_access(); CHKERRQ(ierr);
00045   MaskQuery mask(vMask);
00046   for (PetscInt i=grid.xs; i<grid.xs+grid.xm; ++i) {
00047     for (PetscInt j=grid.ys; j<grid.ys+grid.ym; ++j) {
00048       if (vH(i,j) > 0) {
00049         area += cell_area(i,j);
00050         const PetscScalar dv = cell_area(i,j) * vH(i,j);
00051         volume += dv;
00052 
00053         if (mask.ocean(i,j))   volshelf += dv;
00054       }
00055     }
00056   }  
00057 
00058   ierr = cell_area.end_access(); CHKERRQ(ierr);
00059   ierr = vMask.end_access(); CHKERRQ(ierr);
00060   ierr = vH.end_access(); CHKERRQ(ierr);
00061 
00062   ierr = PetscGlobalSum(&volume, &gvolume, grid.com); CHKERRQ(ierr);
00063   ierr = PetscGlobalSum(&area, &garea, grid.com); CHKERRQ(ierr);
00064   ierr = PetscGlobalSum(&volSIA, &gvolSIA, grid.com); CHKERRQ(ierr);
00065   ierr = PetscGlobalSum(&volstream, &gvolstream, grid.com); CHKERRQ(ierr);
00066   ierr = PetscGlobalSum(&volshelf, &gvolshelf, grid.com); CHKERRQ(ierr);
00067   return 0;
00068 }
00069 
00070 
00077 PetscErrorCode IceModel::energyStats(PetscScalar iarea, PetscScalar &gmeltfrac,
00078                                      PetscScalar &gtemp0) {
00079   PetscErrorCode    ierr;
00080   PetscScalar       meltarea = 0.0, temp0 = 0.0;
00081   const PetscScalar a = grid.dx * grid.dy * 1e-3 * 1e-3; // area unit (km^2)
00082   
00083   ierr = vH.begin_access(); CHKERRQ(ierr);
00084 
00085   // use Enth3 to get stats
00086   ierr = Enth3.getHorSlice(vWork2d[0], 0.0); CHKERRQ(ierr);  // z=0 slice
00087   PetscScalar **Enthbase;
00088   ierr = vWork2d[0].get_array(Enthbase); CHKERRQ(ierr);
00089   for (PetscInt i=grid.xs; i<grid.xs+grid.xm; ++i) {
00090     for (PetscInt j=grid.ys; j<grid.ys+grid.ym; ++j) {
00091       if (vH(i,j) > 0) {
00092         // accumulate area of base which is at melt point
00093         if (EC->isTemperate(Enthbase[i][j], EC->getPressureFromDepth(vH(i,j)) )) // FIXME task #7297
00094           meltarea += a;
00095       }
00096       // if you happen to be at center, record absolute basal temp there
00097       if (i == (grid.Mx - 1)/2 && j == (grid.My - 1)/2) {
00098         ierr = EC->getAbsTemp(Enthbase[i][j],EC->getPressureFromDepth(vH(i,j)), temp0); // FIXME task #7297
00099         CHKERRQ(ierr);
00100       }
00101     }
00102   }
00103   ierr = vWork2d[0].end_access(); CHKERRQ(ierr);
00104 
00105   ierr = vH.end_access(); CHKERRQ(ierr);
00106 
00107   // communication
00108   ierr = PetscGlobalSum(&meltarea, &gmeltfrac, grid.com); CHKERRQ(ierr);
00109   ierr = PetscGlobalMax(&temp0,    &gtemp0,    grid.com); CHKERRQ(ierr);
00110 
00111   // normalize fraction correctly
00112   if (iarea > 0.0)   gmeltfrac = gmeltfrac / iarea;
00113   else gmeltfrac = 0.0;
00114 
00115   return 0;
00116 }
00117 
00118 
00123 PetscErrorCode IceModel::ageStats(PetscScalar ivol, PetscScalar &gorigfrac) {
00124   PetscErrorCode  ierr;
00125 
00126   gorigfrac = -1.0;  // result value if not do_age
00127 
00128   if (!config.get_flag("do_age")) 
00129     return 0;  // leave now
00130 
00131   const PetscScalar  a = grid.dx * grid.dy * 1e-3 * 1e-3, // area unit (km^2)
00132     currtime = grid.year * secpera; // seconds
00133 
00134   PetscScalar *tau, origvol = 0.0;
00135   ierr = vH.begin_access(); CHKERRQ(ierr);
00136   ierr = tau3.begin_access(); CHKERRQ(ierr);
00137 
00138   // compute local original volume
00139   for (PetscInt i=grid.xs; i<grid.xs+grid.xm; ++i) {
00140     for (PetscInt j=grid.ys; j<grid.ys+grid.ym; ++j) {
00141       if (vH(i,j) > 0) {
00142         // accumulate volume of ice which is original
00143         ierr = tau3.getInternalColumn(i,j,&tau); CHKERRQ(ierr);
00144         const PetscInt  ks = grid.kBelowHeight(vH(i,j));
00145         for (PetscInt k=1; k<=ks; k++) {
00146           // ice in segment is original if it is as old as one year less than current time
00147           if (0.5*(tau[k-1]+tau[k]) > currtime - secpera)
00148             origvol += a * 1.0e-3 * (grid.zlevels[k] - grid.zlevels[k-1]);
00149         }
00150       }
00151     }
00152   }
00153 
00154   ierr = vH.end_access(); CHKERRQ(ierr);
00155   ierr = tau3.end_access(); CHKERRQ(ierr);
00156 
00157   // communicate to turn into global original fraction
00158   ierr = PetscGlobalSum(&origvol,  &gorigfrac, grid.com); CHKERRQ(ierr);
00159 
00160   // normalize fraction correctly
00161   if (ivol > 0.0)    gorigfrac = gorigfrac / ivol;
00162   else gorigfrac = 0.0;
00163 
00164   return 0;
00165 }
00166 
00167 
00168 PetscErrorCode IceModel::summary(bool tempAndAge) {
00169   PetscErrorCode  ierr;
00170   PetscScalar     divideH;
00171   PetscScalar     gdivideH, gdivideT, gvolume, garea;
00172   PetscScalar     gvolSIA, gvolstream, gvolshelf;
00173   PetscScalar     meltfrac = 0.0, origfrac = 0.0;
00174 
00175   // get volumes in m^3 and areas in m^2
00176   ierr = volumeArea(gvolume, garea, gvolSIA, gvolstream, gvolshelf); CHKERRQ(ierr);
00177   
00178   // get thick0 = gdivideH
00179   ierr = vH.begin_access(); CHKERRQ(ierr);
00180   divideH = 0;
00181   for (PetscInt i=grid.xs; i<grid.xs+grid.xm; ++i) {
00182     for (PetscInt j=grid.ys; j<grid.ys+grid.ym; ++j) {
00183       if (i == (grid.Mx - 1)/2 && j == (grid.My - 1)/2) {
00184         divideH = vH(i,j);
00185       }
00186     }
00187   }  
00188   ierr = vH.end_access(); CHKERRQ(ierr);
00189   ierr = PetscGlobalMax(&divideH, &gdivideH, grid.com); CHKERRQ(ierr);
00190 
00191   if (tempAndAge || (getVerbosityLevel() >= 3)) {
00192     ierr = energyStats(garea, meltfrac, gdivideT); CHKERRQ(ierr);
00193   }
00194 
00195   if ((tempAndAge || (getVerbosityLevel() >= 3)) && (config.get_flag("do_age"))) {
00196     ierr = ageStats(gvolume, origfrac); CHKERRQ(ierr);
00197   }
00198 
00199   // report CFL violations
00200   if (CFLviolcount > 0.0) {
00201     const PetscScalar CFLviolpercent = 100.0 * CFLviolcount / (grid.Mx * grid.Mz * grid.Mz);
00202     // at default verbosity level, only report CFL viols if above:
00203     const PetscScalar CFLVIOL_REPORT_VERB2_PERCENT = 0.1;
00204     if (   (CFLviolpercent > CFLVIOL_REPORT_VERB2_PERCENT) 
00205         || (getVerbosityLevel() > 2) ) {
00206       char tempstr[90] = "";
00207       snprintf(tempstr,90,
00208               "  [!CFL#=%1.0f (=%5.2f%% of 3D grid)] ",
00209               CFLviolcount,CFLviolpercent);
00210       stdout_flags = tempstr + stdout_flags;
00211     }
00212   }
00213    
00214   // main report: 'S' line
00215   ierr = summaryPrintLine(PETSC_FALSE,(PetscTruth)tempAndAge,grid.year,dt,
00216                           gvolume,garea,meltfrac,gdivideH,gdivideT); CHKERRQ(ierr);
00217 
00218   return 0;
00219 }
00220 
00221 
00223 
00259 PetscErrorCode IceModel::summaryPrintLine(
00260      PetscTruth printPrototype,  bool tempAndAge,
00261      PetscScalar year,  PetscScalar delta_t,
00262      PetscScalar volume,  PetscScalar area,
00263      PetscScalar /* meltfrac */,  PetscScalar H0,  PetscScalar T0) {
00264 
00265   PetscErrorCode ierr;
00266   const bool do_energy = config.get_flag("do_energy");
00267 
00268   const int log10scale = static_cast<int>(config.get("summary_volarea_scale_factor_log10"));
00269   const double scale = pow(10.0, static_cast<double>(log10scale));
00270   char  volscalestr[10] = "     ", // for special case: blank when 10^0 = 1 scaling
00271         areascalestr[10] = "   ";  // ditto
00272   if (log10scale != 0) {
00273     snprintf(volscalestr, sizeof(volscalestr), "10^%1d_", log10scale);
00274     strcpy(areascalestr,volscalestr);
00275   }
00276 
00277   // this version keeps track of what has been done so as to minimize stdout:
00278   static string stdout_flags_count0;
00279   static int    mass_cont_sub_counter = 0;  
00280   static double mass_cont_sub_dtsum = 0.0;
00281   
00282   if (printPrototype == PETSC_TRUE) {
00283     if (do_energy) {
00284       ierr = verbPrintf(2,grid.com,
00285           "P         YEAR:     ivol   iarea     thick0     temp0\n");
00286       ierr = verbPrintf(2,grid.com,
00287           "U        years %skm^3 %skm^2        m         K\n",
00288           volscalestr,areascalestr);
00289     } else {
00290       ierr = verbPrintf(2,grid.com,
00291           "P         YEAR:     ivol   iarea     thick0\n");
00292       ierr = verbPrintf(2,grid.com,
00293           "U        years %skm^3 %skm^2        m\n",
00294           volscalestr,areascalestr);
00295     }
00296   } else {
00297     if (mass_cont_sub_counter == 0)
00298       stdout_flags_count0 = stdout_flags;
00299     if (delta_t > 0.0) {
00300       mass_cont_sub_counter++;      
00301       mass_cont_sub_dtsum += delta_t;
00302     }
00303     if ((tempAndAge == PETSC_TRUE) || (!do_energy) || (getVerbosityLevel() > 2)) {
00304       char tempstr[90] = "";
00305       const PetscScalar major_dt_years = mass_cont_sub_dtsum / secpera;
00306       if (mass_cont_sub_counter == 1) {
00307         snprintf(tempstr,90, " (dt=%.5f)", major_dt_years);
00308       } else {
00309         snprintf(tempstr,90, " (dt=%.5f in %d substeps; av dt_sub_mass_cont=%.5f)",
00310           major_dt_years, mass_cont_sub_counter, major_dt_years / mass_cont_sub_counter);
00311       }
00312       stdout_flags_count0 += tempstr;
00313       if (delta_t > 0.0) { // avoids printing an empty line if we have not done anything
00314         stdout_flags_count0 += "\n";
00315         ierr = verbPrintf(2,grid.com, stdout_flags_count0.c_str()); CHKERRQ(ierr);
00316       }
00317       if (stdout_ssa.length() > 0) {
00318         stdout_ssa += "\n";
00319         ierr = verbPrintf(2,grid.com, stdout_ssa.c_str()); CHKERRQ(ierr);
00320       }
00321       if (do_energy) {
00322         ierr = verbPrintf(2,grid.com, 
00323           "S %12.5f: %8.5f %7.4f %10.3f %9.4f\n",
00324           year, volume/(scale*1.0e9), area/(scale*1.0e6), H0, T0); CHKERRQ(ierr);
00325       } else {
00326         ierr = verbPrintf(2,grid.com, 
00327           "S %12.5f: %8.5f %7.4f %10.3f\n",
00328           year, volume/(scale*1.0e9), area/(scale*1.0e6), H0); CHKERRQ(ierr);
00329       }
00330       mass_cont_sub_counter = 0;      
00331       mass_cont_sub_dtsum = 0.0;
00332     }
00333   }
00334   return 0;
00335 }
00336 
00338 PetscErrorCode IceModel::compute_ice_volume(PetscScalar &result) {
00339   PetscErrorCode ierr;
00340   PetscScalar     volume=0.0;
00341   
00342   ierr = vH.begin_access(); CHKERRQ(ierr);
00343   ierr = cell_area.begin_access(); CHKERRQ(ierr);
00344   for (PetscInt i=grid.xs; i<grid.xs+grid.xm; ++i) {
00345     for (PetscInt j=grid.ys; j<grid.ys+grid.ym; ++j) {
00346       if (vH(i,j) > 0)
00347         volume += vH(i,j) * cell_area(i,j);
00348     }
00349   }  
00350   ierr = cell_area.end_access(); CHKERRQ(ierr);
00351   ierr = vH.end_access(); CHKERRQ(ierr);
00352 
00353   ierr = PetscGlobalSum(&volume, &result, grid.com); CHKERRQ(ierr);
00354   return 0;
00355 }
00356 
00357 
00359 PetscErrorCode IceModel::compute_ice_volume_temperate(PetscScalar &result) {
00360   PetscErrorCode ierr;
00361   PetscScalar     volume=0.0;
00362   
00363   PetscScalar *Enth;  // do NOT delete this pointer: space returned by
00364                       //   getInternalColumn() is allocated already
00365   ierr = vH.begin_access(); CHKERRQ(ierr);
00366   ierr = Enth3.begin_access(); CHKERRQ(ierr);
00367   ierr = cell_area.begin_access(); CHKERRQ(ierr);
00368   for (PetscInt i=grid.xs; i<grid.xs+grid.xm; ++i) {
00369     for (PetscInt j=grid.ys; j<grid.ys+grid.ym; ++j) {
00370       if (vH(i,j) > 0) {
00371         const PetscInt ks = grid.kBelowHeight(vH(i,j));
00372         ierr = Enth3.getInternalColumn(i,j,&Enth); CHKERRQ(ierr);
00373         for (PetscInt k=0; k<ks; ++k) {   
00374           if (EC->isTemperate(Enth[k],EC->getPressureFromDepth(vH(i,j)))) { // FIXME task #7297
00375             volume += (grid.zlevels[k+1] - grid.zlevels[k]) * cell_area(i,j);
00376           }
00377         }
00378         if (EC->isTemperate(Enth[ks],EC->getPressureFromDepth(vH(i,j)))) { // FIXME task #7297
00379           volume += (vH(i,j) - grid.zlevels[ks]) * cell_area(i,j);
00380         }
00381       }
00382     }
00383   }  
00384   ierr = cell_area.end_access(); CHKERRQ(ierr);
00385   ierr = Enth3.end_access(); CHKERRQ(ierr);
00386   ierr = vH.end_access(); CHKERRQ(ierr);
00387 
00388   ierr = PetscGlobalSum(&volume, &result, grid.com); CHKERRQ(ierr);
00389   return 0;
00390 }
00391 
00393 PetscErrorCode IceModel::compute_ice_volume_cold(PetscScalar &result) {
00394   PetscErrorCode ierr;
00395   PetscScalar     volume=0.0;
00396   
00397   PetscScalar *Enth;  // do NOT delete this pointer: space returned by
00398                       //   getInternalColumn() is allocated already
00399   ierr = vH.begin_access(); CHKERRQ(ierr);
00400   ierr = Enth3.begin_access(); CHKERRQ(ierr);
00401   ierr = cell_area.begin_access(); CHKERRQ(ierr);
00402   for (PetscInt i=grid.xs; i<grid.xs+grid.xm; ++i) {
00403     for (PetscInt j=grid.ys; j<grid.ys+grid.ym; ++j) {
00404       if (vH(i,j) > 0) {
00405         const PetscInt ks = grid.kBelowHeight(vH(i,j));
00406         ierr = Enth3.getInternalColumn(i,j,&Enth); CHKERRQ(ierr);
00407         for (PetscInt k=0; k<ks; ++k) {   
00408           if (!EC->isTemperate(Enth[k],EC->getPressureFromDepth(vH(i,j)))) { // FIXME task #7297
00409             volume += (grid.zlevels[k+1] - grid.zlevels[k]) * cell_area(i,j);
00410           }
00411         }
00412         if (!EC->isTemperate(Enth[ks],EC->getPressureFromDepth(vH(i,j)))) { // FIXME task #7297
00413           volume += (vH(i,j) - grid.zlevels[ks]) * cell_area(i,j);
00414         }
00415       }
00416     }
00417   }  
00418   ierr = cell_area.end_access(); CHKERRQ(ierr);
00419   ierr = Enth3.end_access(); CHKERRQ(ierr);
00420   ierr = vH.end_access(); CHKERRQ(ierr);
00421 
00422   ierr = PetscGlobalSum(&volume, &result, grid.com); CHKERRQ(ierr);
00423   return 0;
00424 }
00425 
00427 PetscErrorCode IceModel::compute_ice_area(PetscScalar &result) {
00428   PetscErrorCode ierr;
00429   PetscScalar     area=0.0;
00430   
00431   ierr = vH.begin_access(); CHKERRQ(ierr);
00432   ierr = cell_area.begin_access(); CHKERRQ(ierr);
00433   for (PetscInt i=grid.xs; i<grid.xs+grid.xm; ++i) {
00434     for (PetscInt j=grid.ys; j<grid.ys+grid.ym; ++j) {
00435       if (vH(i,j) > 0)
00436         area += cell_area(i,j);
00437     }
00438   }  
00439   ierr = cell_area.end_access(); CHKERRQ(ierr);
00440   ierr = vH.end_access(); CHKERRQ(ierr);
00441 
00442   ierr = PetscGlobalSum(&area, &result, grid.com); CHKERRQ(ierr);
00443   return 0;
00444 }
00445 
00447 PetscErrorCode IceModel::compute_ice_area_temperate(PetscScalar &result) {
00448   PetscErrorCode ierr;
00449   PetscScalar     area=0.0;
00450   
00451   ierr = Enth3.getHorSlice(vWork2d[0], 0.0); CHKERRQ(ierr);  // z=0 slice
00452   PetscScalar **Enthbase;
00453   ierr = vWork2d[0].get_array(Enthbase); CHKERRQ(ierr);
00454 
00455   ierr = vH.begin_access(); CHKERRQ(ierr);
00456   ierr = cell_area.begin_access(); CHKERRQ(ierr);
00457   for (PetscInt i=grid.xs; i<grid.xs+grid.xm; ++i) {
00458     for (PetscInt j=grid.ys; j<grid.ys+grid.ym; ++j) {
00459       if ( (vH(i,j) > 0) && (EC->isTemperate(Enthbase[i][j],EC->getPressureFromDepth(vH(i,j)))) ) // FIXME task #7297
00460         area += cell_area(i,j);
00461     }
00462   }  
00463   ierr = cell_area.end_access(); CHKERRQ(ierr);
00464   ierr = vH.end_access(); CHKERRQ(ierr);
00465 
00466   ierr = PetscGlobalSum(&area, &result, grid.com); CHKERRQ(ierr);
00467   return 0;
00468 }
00469 
00471 PetscErrorCode IceModel::compute_ice_area_cold(PetscScalar &result) {
00472   PetscErrorCode ierr;
00473   PetscScalar     area=0.0;
00474   
00475   ierr = Enth3.getHorSlice(vWork2d[0], 0.0); CHKERRQ(ierr);  // z=0 slice
00476   PetscScalar **Enthbase;
00477   ierr = vWork2d[0].get_array(Enthbase); CHKERRQ(ierr);
00478 
00479   ierr = vH.begin_access(); CHKERRQ(ierr);
00480   ierr = cell_area.begin_access(); CHKERRQ(ierr);
00481   for (PetscInt i=grid.xs; i<grid.xs+grid.xm; ++i) {
00482     for (PetscInt j=grid.ys; j<grid.ys+grid.ym; ++j) {
00483       if ( (vH(i,j) > 0) && (!EC->isTemperate(Enthbase[i][j],EC->getPressureFromDepth(vH(i,j)))) ) // FIXME task #7297
00484         area += cell_area(i,j);
00485     }
00486   }  
00487   ierr = cell_area.end_access(); CHKERRQ(ierr);
00488   ierr = vH.end_access(); CHKERRQ(ierr);
00489 
00490   ierr = PetscGlobalSum(&area, &result, grid.com); CHKERRQ(ierr);
00491   return 0;
00492 }
00493 
00495 PetscErrorCode IceModel::compute_ice_area_grounded(PetscScalar &result) {
00496   PetscErrorCode ierr;
00497   PetscScalar     area=0.0;
00498 
00499   MaskQuery mask(vMask);
00500 
00501   ierr = vMask.begin_access(); CHKERRQ(ierr);
00502   ierr = cell_area.begin_access(); CHKERRQ(ierr);
00503   for (PetscInt i=grid.xs; i<grid.xs+grid.xm; ++i) {
00504     for (PetscInt j=grid.ys; j<grid.ys+grid.ym; ++j) {
00505       if (mask.grounded_ice(i,j))
00506         area += cell_area(i,j);
00507     }
00508   }  
00509   ierr = cell_area.end_access(); CHKERRQ(ierr);
00510   ierr = vMask.end_access(); CHKERRQ(ierr);
00511 
00512   ierr = PetscGlobalSum(&area, &result, grid.com); CHKERRQ(ierr);
00513   return 0;
00514 }
00515 
00517 PetscErrorCode IceModel::compute_ice_area_floating(PetscScalar &result) {
00518   PetscErrorCode ierr;
00519   PetscScalar     area=0.0;
00520 
00521   MaskQuery mask(vMask);
00522   
00523   ierr = vMask.begin_access(); CHKERRQ(ierr);
00524   ierr = cell_area.begin_access(); CHKERRQ(ierr);
00525   for (PetscInt i=grid.xs; i<grid.xs+grid.xm; ++i) {
00526     for (PetscInt j=grid.ys; j<grid.ys+grid.ym; ++j) {
00527       if (mask.floating_ice(i,j))
00528         area += cell_area(i,j);
00529     }
00530   }  
00531   ierr = cell_area.end_access(); CHKERRQ(ierr);
00532   ierr = vMask.end_access(); CHKERRQ(ierr);
00533 
00534   ierr = PetscGlobalSum(&area, &result, grid.com); CHKERRQ(ierr);
00535   return 0;
00536 }
00537 
00538 
00540 
00546 PetscErrorCode IceModel::compute_ice_enthalpy(PetscScalar &result) {
00547   PetscErrorCode ierr;
00548   PetscScalar enthalpysum = 0.0;
00549 
00550   PetscScalar *Enth;  // do NOT delete this pointer: space returned by
00551                       //   getInternalColumn() is allocated already
00552   ierr = vH.begin_access(); CHKERRQ(ierr);
00553   ierr = Enth3.begin_access(); CHKERRQ(ierr);
00554   for (PetscInt i=grid.xs; i<grid.xs+grid.xm; ++i) {
00555     for (PetscInt j=grid.ys; j<grid.ys+grid.ym; ++j) {
00556       if (vH(i,j) > 0) {
00557         const PetscInt ks = grid.kBelowHeight(vH(i,j));
00558         ierr = Enth3.getInternalColumn(i,j,&Enth); CHKERRQ(ierr);
00559         for (PetscInt k=0; k<ks; ++k) {
00560           enthalpysum += Enth[k] * (grid.zlevels[k+1] - grid.zlevels[k]);
00561         }
00562         enthalpysum += Enth[ks] * (vH(i,j) - grid.zlevels[ks]);
00563       }
00564     }
00565   }
00566   ierr = vH.end_access(); CHKERRQ(ierr);  
00567   ierr = Enth3.end_access(); CHKERRQ(ierr);
00568   
00569   enthalpysum *= config.get("ice_density") * (grid.dx * grid.dy);
00570   
00571   ierr = PetscGlobalSum(&enthalpysum, &result, grid.com); CHKERRQ(ierr);
00572   return 0;
00573 }
00574 
00576 PetscErrorCode IceModel::compute_by_name(string name, PetscScalar &result) {
00577   PetscErrorCode ierr, errcode = 1;
00578 
00579   if (name == "ivol") {
00580     errcode = 0;
00581     ierr = compute_ice_volume(result); CHKERRQ(ierr);
00582   }
00583 
00584   if (name == "ivoltemp") {
00585     errcode = 0;
00586     ierr = compute_ice_volume_temperate(result); CHKERRQ(ierr);
00587   }
00588 
00589   if (name == "ivoltempf") {
00590     errcode = 0;
00591     PetscScalar ivol;
00592     ierr = compute_ice_volume(ivol); CHKERRQ(ierr);
00593     ierr = compute_ice_volume_temperate(result); CHKERRQ(ierr);
00594     result /= ivol;
00595   }
00596 
00597   if (name == "ivolcold") {
00598     errcode = 0;
00599     ierr = compute_ice_volume_cold(result); CHKERRQ(ierr);
00600   }
00601 
00602   if (name == "ivolcoldf") {
00603     errcode = 0;
00604     PetscScalar ivol;
00605     ierr = compute_ice_volume(ivol); CHKERRQ(ierr);
00606     ierr = compute_ice_volume_cold(result); CHKERRQ(ierr);
00607     result /= ivol;
00608   }
00609 
00610   if (name == "imass") {
00611     errcode = 0;
00612     PetscScalar ice_density = config.get("ice_density");
00613     ierr = compute_ice_volume(result); CHKERRQ(ierr);
00614     result *= ice_density;
00615   }
00616 
00617   if (name == "iarea") {
00618     errcode = 0;
00619     ierr = compute_ice_area(result); CHKERRQ(ierr);
00620   }
00621 
00622   if (name == "iareatemp") {
00623     errcode = 0;
00624     ierr = compute_ice_area_temperate(result); CHKERRQ(ierr);
00625   }
00626 
00627   if (name == "iareatempf") {
00628     errcode = 0;
00629     PetscScalar iarea;
00630     ierr = compute_ice_area(iarea); CHKERRQ(ierr);
00631     ierr = compute_ice_area_temperate(result); CHKERRQ(ierr);
00632     result /= iarea;
00633   }
00634 
00635   if (name == "iareacold") {
00636     errcode = 0;
00637     ierr = compute_ice_area_cold(result); CHKERRQ(ierr);
00638   }
00639 
00640   if (name == "iareacoldf") {
00641     errcode = 0;
00642     PetscScalar iarea;
00643     ierr = compute_ice_area(iarea); CHKERRQ(ierr);
00644     ierr = compute_ice_area_cold(result); CHKERRQ(ierr);
00645     result /= iarea;
00646   }
00647 
00648   if (name == "iareag") {
00649     errcode = 0;
00650     ierr = compute_ice_area_grounded(result); CHKERRQ(ierr);
00651   }
00652 
00653   if (name == "iareaf") {
00654     errcode = 0;
00655     ierr = compute_ice_area_floating(result); CHKERRQ(ierr);
00656   }
00657 
00658   if (name == "dt") {
00659     errcode = 0;
00660     result = dt;
00661   }
00662 
00663   if (name == "divoldt") {
00664     errcode = 0;
00665     result = dvoldt;
00666   }
00667 
00668   if (name == "dimassdt") {
00669     errcode = 0;
00670     PetscScalar ice_density = config.get("ice_density");
00671     result = dvoldt * ice_density;
00672   }
00673 
00674   if (name == "ienthalpy") {
00675     errcode = 0;
00676     ierr = compute_ice_enthalpy(result); CHKERRQ(ierr);
00677   }
00678 
00679   if (name == "basal_ice_flux") {
00680     errcode = 0;
00681     result = total_basal_ice_flux;
00682   }
00683 
00684   if (name == "surface_ice_flux") {
00685     errcode = 0;
00686     result = total_surface_ice_flux;
00687   }
00688 
00689   if (name == "sub_shelf_ice_flux") {
00690     errcode = 0;
00691     result = total_sub_shelf_ice_flux;
00692   }
00693 
00694   if (name == "nonneg_rule_flux") {
00695     errcode = 0;
00696     result = nonneg_rule_flux;
00697   }
00698 
00699   if (name == "ocean_kill_flux") {
00700     errcode = 0;
00701     result = ocean_kill_flux;
00702   }
00703 
00704   if (name == "float_kill_flux") {
00705     errcode = 0;
00706     result = float_kill_flux;
00707   }
00708 
00709   return errcode;
00710 }
00711 
00712 
00732 PetscErrorCode IceModel::ice_mass_bookkeeping() {
00733   PetscErrorCode ierr;
00734 
00735   bool include_bmr_in_continuity = config.get_flag("include_bmr_in_continuity");
00736 
00737   // note acab and shelfbmassflux are IceModelVec2S owned by IceModel
00738   if (surface != PETSC_NULL) {
00739     ierr = surface->ice_surface_mass_flux(acab);
00740     CHKERRQ(ierr);
00741   } else { SETERRQ(2,"PISM ERROR: surface == PETSC_NULL"); }
00742 
00743   if (ocean != PETSC_NULL) {
00744     ierr = ocean->shelf_base_mass_flux(shelfbmassflux);
00745     CHKERRQ(ierr);
00746   } else { SETERRQ(2,"PISM ERROR: ocean == PETSC_NULL"); }
00747 
00748   PetscScalar my_total_surface_ice_flux = 0.0, my_total_basal_ice_flux = 0.0,
00749     my_total_sub_shelf_ice_flux = 0.0;
00750 
00751   ierr = acab.begin_access(); CHKERRQ(ierr);
00752   ierr = cell_area.begin_access(); CHKERRQ(ierr);
00753   ierr = shelfbmassflux.begin_access(); CHKERRQ(ierr);
00754   ierr = vH.begin_access(); CHKERRQ(ierr);
00755   ierr = vMask.begin_access(); CHKERRQ(ierr);
00756   ierr = vbmr.begin_access(); CHKERRQ(ierr);
00757 
00758   MaskQuery mask(vMask);
00759 
00760   for (PetscInt i=grid.xs; i<grid.xs+grid.xm; ++i) {
00761     for (PetscInt j=grid.ys; j<grid.ys+grid.ym; ++j) {
00762       // ignore ice-free cells:
00763       if (mask.ice_free(i,j))
00764         continue;
00765 
00766       my_total_surface_ice_flux += acab(i,j) * cell_area(i,j); // note the "+="!
00767 
00768       if (include_bmr_in_continuity) {
00769         if (mask.ocean(i,j)) {
00770           my_total_sub_shelf_ice_flux -= shelfbmassflux(i,j) * cell_area(i,j); // note the "-="!
00771         } else {
00772           my_total_basal_ice_flux -= vbmr(i,j) * cell_area(i,j); // note the "-="!
00773         }
00774       }
00775 
00776     }   // j
00777   } // i
00778 
00779   ierr = acab.end_access(); CHKERRQ(ierr);
00780   ierr = cell_area.end_access(); CHKERRQ(ierr);
00781   ierr = shelfbmassflux.end_access(); CHKERRQ(ierr);
00782   ierr = vH.end_access(); CHKERRQ(ierr);
00783   ierr = vMask.end_access(); CHKERRQ(ierr);
00784   ierr = vbmr.end_access(); CHKERRQ(ierr);
00785 
00786   PetscScalar ice_density = config.get("ice_density");
00787   my_total_surface_ice_flux     *= ice_density;
00788   my_total_sub_shelf_ice_flux   *= ice_density;
00789   my_total_basal_ice_flux       *= ice_density;
00790 
00791   ierr = PetscGlobalSum(&my_total_surface_ice_flux,   &total_surface_ice_flux,   grid.com); CHKERRQ(ierr);
00792   ierr = PetscGlobalSum(&my_total_sub_shelf_ice_flux, &total_sub_shelf_ice_flux, grid.com); CHKERRQ(ierr);
00793   ierr = PetscGlobalSum(&my_total_basal_ice_flux,     &total_basal_ice_flux,     grid.com); CHKERRQ(ierr);
00794 
00795   return 0;
00796 }
00797 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines