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