URI: 
       tutilities.cc - pism - [fork] customized build of PISM, the parallel ice sheet model (tillflux branch)
  HTML git clone git://src.adamsgaard.dk/pism
   DIR Log
   DIR Files
   DIR Refs
   DIR LICENSE
       ---
       tutilities.cc (4955B)
       ---
            1 // Copyright (C) 2004-2019 Jed Brown, Ed Bueler and Constantine Khroulev
            2 //
            3 // This file is part of PISM.
            4 //
            5 // PISM is free software; you can redistribute it and/or modify it under the
            6 // terms of the GNU General Public License as published by the Free Software
            7 // Foundation; either version 3 of the License, or (at your option) any later
            8 // version.
            9 //
           10 // PISM is distributed in the hope that it will be useful, but WITHOUT ANY
           11 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
           12 // FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
           13 // details.
           14 //
           15 // You should have received a copy of the GNU General Public License
           16 // along with PISM; if not, write to the Free Software
           17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
           18 
           19 #include <cstring>
           20 #include <petscsys.h>
           21 
           22 #include "IceModel.hh"
           23 
           24 #include "pism/util/IceGrid.hh"
           25 #include "pism/util/ConfigInterface.hh"
           26 #include "pism/util/Time.hh"
           27 #include "pism/util/io/File.hh"
           28 #include "pism/util/pism_utilities.hh"
           29 #include "pism/util/projection.hh"
           30 #include "pism/util/pism_signal.h"
           31 
           32 namespace pism {
           33 
           34 //! Catch signals -USR1, -USR2 and -TERM.
           35 /*!
           36 Signal `SIGTERM` makes PISM end, saving state under original `-o` name
           37 (or default name).  We also add an indication to the history attribute
           38 of the output NetCDF file.
           39 
           40 Signal `SIGUSR1` makes PISM save state under a filename based on the
           41 the name of the executable (e.g. `pismr` or `pismv`) and the current
           42 model year.  In addition the time series (`-ts_file`, etc.) is flushed out
           43 There is no indication of these actions in the history attribute of the output (`-o`)
           44 NetCDF file because there is no effect on it, but there is an indication at `stdout`.
           45 
           46 Signal `SIGUSR2` makes PISM flush time-series, without saving model state.
           47  */
           48 int IceModel::process_signals() {
           49 
           50   if (pism_signal == SIGTERM) {
           51     m_log->message(1,
           52        "\ncaught signal SIGTERM:  EXITING EARLY and saving with original filename.\n");
           53 
           54     prepend_history(pism::printf("EARLY EXIT caused by signal SIGTERM. Completed timestep at time=%s.",
           55                                  m_time->date().c_str()));
           56     // Tell the caller that the user requested an early termination of
           57     // the run.
           58     return 1;
           59   }
           60 
           61   if (pism_signal == SIGUSR1) {
           62     char file_name[PETSC_MAX_PATH_LEN];
           63     snprintf(file_name, PETSC_MAX_PATH_LEN, "pism-%s.nc",
           64              m_time->date().c_str());
           65     m_log->message(1,
           66        "\ncaught signal SIGUSR1:  Writing intermediate file `%s' and flushing time series.\n\n",
           67        file_name);
           68     pism_signal = 0;
           69 
           70     File file(m_grid->com,
           71               file_name,
           72               string_to_backend(m_config->get_string("output.format")),
           73               PISM_READWRITE_MOVE,
           74               m_ctx->pio_iosys_id());
           75     save_variables(file, INCLUDE_MODEL_STATE, m_output_vars, m_time->current());
           76 
           77     // flush all the time-series buffers:
           78     flush_timeseries();
           79   }
           80 
           81   if (pism_signal == SIGUSR2) {
           82     m_log->message(1,
           83        "\ncaught signal SIGUSR2:  Flushing time series.\n\n");
           84     pism_signal = 0;
           85 
           86     // flush all the time-series buffers:
           87     flush_timeseries();
           88   }
           89 
           90   return 0;
           91 }
           92 
           93 
           94 void IceModel::update_run_stats() {
           95 
           96   // timing stats
           97   // MYPPH stands for "model years per processor hour"
           98   double
           99     wall_clock_hours = pism::wall_clock_hours(m_grid->com, m_start_time),
          100     proc_hours       = m_grid->size() * wall_clock_hours,
          101     model_years      = units::convert(m_sys, m_time->current() - m_time->start(),
          102                                       "seconds", "years");
          103 
          104   m_run_stats.set_number("wall_clock_hours", wall_clock_hours);
          105   m_run_stats.set_number("processor_hours", proc_hours);
          106   m_run_stats.set_number("model_years_per_processor_hour", model_years / proc_hours);
          107 }
          108 
          109 //! Get time and user/host name and add it to the given string.
          110 void  IceModel::prepend_history(const std::string &str) {
          111   m_output_global_attributes.set_string("history",
          112                                         username_prefix(m_grid->com) + (str + "\n") +
          113                                         m_output_global_attributes.get_string("history"));
          114 }
          115 
          116 //! Check if the thickness of the ice is too large.
          117 /*! Return true if the ice thickness exceeds the height of the computational domain.
          118  */
          119 bool check_maximum_ice_thickness(const IceModelVec2S &ice_thickness) {
          120   IceGrid::ConstPtr grid = ice_thickness.grid();
          121 
          122   const double Lz = grid->Lz();
          123 
          124   IceModelVec::AccessList list(ice_thickness);
          125 
          126   unsigned int counter = 0;
          127   for (Points p(*grid); p; p.next()) {
          128     const int i = p.i(), j = p.j();
          129 
          130     if (ice_thickness(i, j) > Lz) {
          131       counter += 1;
          132     }
          133   }
          134 
          135   if (GlobalSum(grid->com, counter) > 0) {
          136     return true;
          137   } else {
          138     return false;
          139   }
          140 }
          141 
          142 //! Return the grid used by this model.
          143 IceGrid::Ptr IceModel::grid() const {
          144   return m_grid;
          145 }
          146 
          147 //! Return the context this model is running in.
          148 Context::Ptr IceModel::ctx() const {
          149   return m_ctx;
          150 }
          151 
          152 } // end of namespace pism