tContext.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
---
tContext.cc (4972B)
---
1 /* Copyright (C) 2014, 2015, 2017, 2019 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 "Context.hh"
21 #include "Profiling.hh"
22 #include "Units.hh"
23 #include "Config.hh"
24 #include "Time.hh"
25 #include "Logger.hh"
26 #include "pism/util/EnthalpyConverter.hh"
27 #include "pism/util/error_handling.hh"
28 #include "pism/pism_config.hh"
29
30 #if (Pism_USE_PIO==1)
31 // Why do I need this???
32 #define _NETCDF
33 #include <pio.h>
34 #endif
35
36 namespace pism {
37
38 class Context::Impl {
39 public:
40 Impl(MPI_Comm c,
41 UnitsSystemPtr sys,
42 ConfigPtr conf,
43 EnthalpyConverterPtr EC,
44 TimePtr t,
45 LoggerPtr log,
46 const std::string &p)
47 : com(c), unit_system(sys), config(conf), enthalpy_converter(EC), time(t), prefix(p),
48 logger(log), pio_iosys_id(-1) {
49 // empty
50 }
51 MPI_Comm com;
52 UnitsSystemPtr unit_system;
53 ConfigPtr config;
54 EnthalpyConverterPtr enthalpy_converter;
55 TimePtr time;
56 std::string prefix;
57 Profiling profiling;
58 LoggerPtr logger;
59 int pio_iosys_id;
60 };
61
62 Context::Context(MPI_Comm c, UnitsSystemPtr sys,
63 ConfigPtr config, EnthalpyConverterPtr EC, TimePtr t,
64 LoggerPtr L,
65 const std::string &p)
66 : m_impl(new Impl(c, sys, config, EC, t, L, p)) {
67 // empty
68 }
69
70 Context::~Context() {
71
72 #if (Pism_USE_PIO==1)
73 if (m_impl->pio_iosys_id != -1 and
74 PIOc_free_iosystem(m_impl->pio_iosys_id) != PIO_NOERR) {
75 m_impl->logger->message(1, "Error: failed to de-allocate a ParallelIO I/O system\n");
76 }
77 #endif
78
79 delete m_impl;
80 }
81
82 MPI_Comm Context::com() const {
83 return m_impl->com;
84 }
85
86 int Context::size() const {
87 int S = 0;
88 MPI_Comm_size(m_impl->com, &S);
89 return S;
90 }
91
92 int Context::rank() const {
93 int R = 0;
94 MPI_Comm_rank(m_impl->com, &R);
95 return R;
96 }
97
98 Context::UnitsSystemPtr Context::unit_system() const {
99 return m_impl->unit_system;
100 }
101
102 Context::ConfigPtr Context::config() {
103 return m_impl->config;
104 }
105
106 Context::ConstConfigPtr Context::config() const {
107 return m_impl->config;
108 }
109
110 Context::EnthalpyConverterPtr Context::enthalpy_converter() const {
111 return m_impl->enthalpy_converter;
112 }
113
114 Context::TimePtr Context::time() {
115 return m_impl->time;
116 }
117
118 Context::ConstTimePtr Context::time() const {
119 return m_impl->time;
120 }
121
122 const std::string& Context::prefix() const {
123 return m_impl->prefix;
124 }
125
126 const Profiling& Context::profiling() const {
127 return m_impl->profiling;
128 }
129
130 Context::ConstLoggerPtr Context::log() const {
131 return m_impl->logger;
132 }
133
134 Context::LoggerPtr Context::log() {
135 return m_impl->logger;
136 }
137
138 /*!
139 * I/O system id (the ParallelIO library)
140 */
141 int Context::pio_iosys_id() const {
142 #if (Pism_USE_PIO==1)
143 if (m_impl->pio_iosys_id == -1) {
144 int ierr = PIOc_set_iosystem_error_handling(PIO_DEFAULT, PIO_BCAST_ERROR, NULL);
145 if (ierr != 0) {
146 throw RuntimeError::formatted(PISM_ERROR_LOCATION, "Failed to initialize ParallelIO");
147 }
148
149 int
150 base = config()->get_number("output.pio.base"),
151 stride = config()->get_number("output.pio.stride"),
152 n_writers = config()->get_number("output.pio.n_writers");
153
154 if (n_writers > this->size()) {
155 throw RuntimeError::formatted(PISM_ERROR_LOCATION,
156 "number of ParallelIO writers (%d)"
157 " exceeds the communicator size (%d)",
158 n_writers, this->size());
159 }
160
161 ierr = PIOc_Init_Intracomm(m_impl->com, n_writers, stride, base, PIO_REARR_BOX,
162 &m_impl->pio_iosys_id);
163 if (ierr != 0) {
164 throw RuntimeError::formatted(PISM_ERROR_LOCATION, "Failed to initialize ParallelIO");
165 }
166 }
167 #endif
168 return m_impl->pio_iosys_id;
169 }
170
171 Context::Ptr context_from_options(MPI_Comm com, const std::string &prefix) {
172 // unit system
173 units::System::Ptr sys(new units::System);
174
175 // logger
176 Logger::Ptr logger = logger_from_options(com);
177
178 // configuration parameters
179 Config::Ptr config = config_from_options(com, *logger, sys);
180 print_config(*logger, 3, *config);
181
182 // time manager
183 Time::Ptr time = time_from_options(com, config, sys);
184
185 // enthalpy converter
186 EnthalpyConverter::Ptr EC(new EnthalpyConverter(*config));
187
188 return Context::Ptr(new Context(com, sys, config, EC, time, logger, prefix));
189 }
190
191
192 } // end of namespace pism