PISM, A Parallel Ice Sheet Model  stable v2.1-1-g6902d5502 committed by Ed Bueler on 2023-12-20 08:38:27 -0800
Context.cc
Go to the documentation of this file.
1 /* Copyright (C) 2014, 2015, 2017, 2019, 2021, 2023 PISM Authors
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 
20 #include "pism/util/Context.hh"
21 #include "pism/util/Profiling.hh"
22 #include "pism/util/Units.hh"
23 #include "pism/util/Time.hh"
24 #include "pism/util/Logger.hh"
25 #include "pism/util/EnthalpyConverter.hh"
26 #include "pism/util/error_handling.hh"
27 #include "pism/pism_config.hh"
28 
29 #if (Pism_USE_PIO==1)
30 // Why do I need this???
31 #define _NETCDF
32 #include <pio.h>
33 #endif
34 
35 namespace pism {
36 
38 public:
39  Impl(MPI_Comm c,
40  std::shared_ptr<units::System> sys,
41  std::shared_ptr<Config> conf,
42  std::shared_ptr<EnthalpyConverter> EC,
43  std::shared_ptr<Time> t,
44  std::shared_ptr<Logger> log,
45  const std::string &p)
46  : com(c), unit_system(sys), config(conf), enthalpy_converter(EC), time(t), prefix(p),
47  logger(log), pio_iosys_id(-1) {
48  // empty
49  }
50  MPI_Comm com;
51  std::shared_ptr<units::System> unit_system;
52  std::shared_ptr<Config> config;
53  std::shared_ptr<EnthalpyConverter> enthalpy_converter;
54  std::shared_ptr<Time> time;
55  std::string prefix;
57  std::shared_ptr<Logger> logger;
59 };
60 
61 Context::Context(MPI_Comm c, std::shared_ptr<units::System> sys,
62  std::shared_ptr<Config> config, std::shared_ptr<EnthalpyConverter> EC, std::shared_ptr<Time> t,
63  std::shared_ptr<Logger> L,
64  const std::string &p)
65  : m_impl(new Impl(c, sys, config, EC, t, L, p)) {
66  // empty
67 }
68 
70 
71 #if (Pism_USE_PIO==1)
72  if (m_impl->pio_iosys_id != -1 and
73  PIOc_free_iosystem(m_impl->pio_iosys_id) != PIO_NOERR) {
74  m_impl->logger->message(1, "Error: failed to de-allocate a ParallelIO I/O system\n");
75  }
76 #endif
77 
78  delete m_impl;
79 }
80 
81 MPI_Comm Context::com() const {
82  return m_impl->com;
83 }
84 
85 int Context::size() const {
86  int S = 0;
87  MPI_Comm_size(m_impl->com, &S);
88  return S;
89 }
90 
91 int Context::rank() const {
92  int R = 0;
93  MPI_Comm_rank(m_impl->com, &R);
94  return R;
95 }
96 
97 std::shared_ptr<units::System> Context::unit_system() const {
98  return m_impl->unit_system;
99 }
100 
101 std::shared_ptr<Config> Context::config() {
102  return m_impl->config;
103 }
104 
105 std::shared_ptr<const Config> Context::config() const {
106  return m_impl->config;
107 }
108 
109 std::shared_ptr<EnthalpyConverter> Context::enthalpy_converter() const {
110  return m_impl->enthalpy_converter;
111 }
112 
113 std::shared_ptr<Time> Context::time() {
114  return m_impl->time;
115 }
116 
117 std::shared_ptr<const Time> Context::time() const {
118  return m_impl->time;
119 }
120 
121 const std::string& Context::prefix() const {
122  return m_impl->prefix;
123 }
124 
126  return m_impl->profiling;
127 }
128 
129 std::shared_ptr<const Logger> Context::log() const {
130  return m_impl->logger;
131 }
132 
133 std::shared_ptr<Logger> Context::log() {
134  return m_impl->logger;
135 }
136 
137 /*!
138  * I/O system id (the ParallelIO library)
139  */
141 #if (Pism_USE_PIO==1)
142  if (m_impl->pio_iosys_id == -1) {
143  int ierr = PIOc_set_iosystem_error_handling(PIO_DEFAULT, PIO_BCAST_ERROR, NULL);
144  if (ierr != 0) {
145  throw RuntimeError::formatted(PISM_ERROR_LOCATION, "Failed to initialize ParallelIO");
146  }
147 
148  int
149  base = config()->get_number("output.pio.base"),
150  stride = config()->get_number("output.pio.stride"),
151  n_writers = config()->get_number("output.pio.n_writers");
152 
153  if (n_writers > this->size()) {
155  "number of ParallelIO writers (%d)"
156  " exceeds the communicator size (%d)",
157  n_writers, this->size());
158  }
159 
160  ierr = PIOc_Init_Intracomm(m_impl->com, n_writers, stride, base, PIO_REARR_BOX,
161  &m_impl->pio_iosys_id);
162  if (ierr != 0) {
163  throw RuntimeError::formatted(PISM_ERROR_LOCATION, "Failed to initialize ParallelIO");
164  }
165  }
166 #endif
167  return m_impl->pio_iosys_id;
168 }
169 
170 std::shared_ptr<Context> context_from_options(MPI_Comm com,
171  const std::string &prefix,
172  bool print) {
173  // unit system
175 
176  // logger
177  Logger::Ptr logger = logger_from_options(com);
178 
179  // configuration parameters
180  Config::Ptr config = config_from_options(com, *logger, sys);
181 
182  if (print) {
183  print_config(*logger, 3, *config);
184  }
185 
186  // time manager
187  Time::Ptr time = std::make_shared<Time>(com, config, *logger, sys);
188 
189  // enthalpy converter
190  EnthalpyConverter::Ptr EC(new EnthalpyConverter(*config));
191 
192  return std::shared_ptr<Context>(new Context(com, sys, config, EC, time, logger, prefix));
193 }
194 
195 
196 } // end of namespace pism
std::shared_ptr< Config > Ptr
Profiling profiling
Definition: Context.cc:56
std::shared_ptr< Config > config
Definition: Context.cc:52
std::shared_ptr< Logger > logger
Definition: Context.cc:57
Impl(MPI_Comm c, std::shared_ptr< units::System > sys, std::shared_ptr< Config > conf, std::shared_ptr< EnthalpyConverter > EC, std::shared_ptr< Time > t, std::shared_ptr< Logger > log, const std::string &p)
Definition: Context.cc:39
std::string prefix
Definition: Context.cc:55
std::shared_ptr< Time > time
Definition: Context.cc:54
std::shared_ptr< EnthalpyConverter > enthalpy_converter
Definition: Context.cc:53
std::shared_ptr< units::System > unit_system
Definition: Context.cc:51
MPI_Comm com() const
Definition: Context.cc:81
Context(MPI_Comm c, std::shared_ptr< units::System > sys, std::shared_ptr< Config > conf, std::shared_ptr< EnthalpyConverter > EC, std::shared_ptr< Time > t, std::shared_ptr< Logger > log, const std::string &p)
Definition: Context.cc:61
Impl * m_impl
Definition: Context.hh:65
std::shared_ptr< const Config > config() const
Definition: Context.cc:105
int pio_iosys_id() const
Definition: Context.cc:140
const std::string & prefix() const
Definition: Context.cc:121
int size() const
Definition: Context.cc:85
const Profiling & profiling() const
Definition: Context.cc:125
std::shared_ptr< const Logger > log() const
Definition: Context.cc:129
std::shared_ptr< units::System > unit_system() const
Definition: Context.cc:97
int rank() const
Definition: Context.cc:91
std::shared_ptr< const Time > time() const
Definition: Context.cc:117
std::shared_ptr< EnthalpyConverter > enthalpy_converter() const
Definition: Context.cc:109
std::shared_ptr< EnthalpyConverter > Ptr
Converts between specific enthalpy and temperature or liquid content.
std::shared_ptr< Logger > Ptr
Definition: Logger.hh:45
static RuntimeError formatted(const ErrorLocation &location, const char format[],...) __attribute__((format(printf
build a RuntimeError with a formatted message
std::shared_ptr< Time > Ptr
Definition: Time.hh:62
std::shared_ptr< System > Ptr
Definition: Units.hh:47
#define PISM_ERROR_LOCATION
static const double L
Definition: exactTestL.cc:40
std::shared_ptr< Context > context_from_options(MPI_Comm com, const std::string &prefix, bool print)
Create a default context using options.
Definition: Context.cc:170
Logger::Ptr logger_from_options(MPI_Comm com)
Definition: Logger.cc:107
Config::Ptr config_from_options(MPI_Comm com, const Logger &log, units::System::Ptr unit_system)
Create a configuration database using command-line options.
void print_config(const Logger &log, int verbosity_threshhold, const Config &config)
Report configuration parameters to stdout.
static double S(unsigned n)
Definition: test_cube.c:58