start.hh
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3/*
4 This file is part of the Open Porous Media project (OPM).
5
6 OPM is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 2 of the License, or
9 (at your option) any later version.
10
11 OPM is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with OPM. If not, see <http://www.gnu.org/licenses/>.
18
19 Consult the COPYING file in the top-level source directory of this
20 module for the precise wording of the license and the list of
21 copyright holders.
22*/
27#ifndef EWOMS_START_HH
28#define EWOMS_START_HH
29
30#include <dune/common/parallel/mpihelper.hh>
31
32#include <opm/material/common/ResetLocale.hpp>
33
35
39
41
42#if HAVE_DUNE_FEM
43#include <dune/fem/misc/mpimanager.hh>
44#endif
45
46#include <cstdlib>
47#include <iostream>
48#include <sstream>
49#include <string>
50#include <unistd.h>
51#include <vector>
52
53#if HAVE_MPI
54#include <mpi.h>
55#endif
56
58
59namespace Opm {
63template <class TypeTag>
64static inline void registerAllParameters_(bool finalizeRegistration)
65{
66 using Simulator = GetPropType<TypeTag, Properties::Simulator>;
67 using TM = GetPropType<TypeTag, Properties::ThreadManager>;
68
69 Parameters::Register<Parameters::ParameterFile>
70 ("An .ini file which contains a set of run-time parameters");
71 Parameters::Register<Parameters::PrintParameters>
72 ("Print the values of the run-time parameters at the "
73 "start of the simulation");
74
75 TM::registerParameters();
77
78 if (finalizeRegistration) {
80 }
81}
82
92template <class TypeTag>
93static inline int setupParameters_(int argc,
94 const char **argv,
95 bool registerParams,
96 bool allowUnused,
97 bool handleHelp,
98 const int myRank)
99{
100 using Problem = GetPropType<TypeTag, Properties::Problem>;
101
103 // Register all parameters
105 if (registerParams) {
106 registerAllParameters_<TypeTag>(true);
107 }
108
110 // set the parameter values
112
113 // fill the parameter tree with the options from the command line
114 const auto& positionalParamCallback = Problem::handlePositionalParameter;
115 std::string helpPreamble; // print help if non-empty!
116 if (myRank == 0 && handleHelp) {
117 helpPreamble = Problem::helpPreamble(argc, argv);
118 }
119 const std::string s =
121 argv,
122 positionalParamCallback,
123 helpPreamble);
124 if (!s.empty()) {
125 int status = 1;
126 if (s == "Help called") { // only on master process
127 status = -1; // Use negative values to indicate --help argument
128 }
129#if HAVE_MPI
130 // Force -1 if the master process has that.
131 int globalStatus;
132 MPI_Allreduce(&status, &globalStatus, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD);
133 return globalStatus;
134#endif
135 return status;
136 }
137
138 const std::string paramFileName = Parameters::Get<Parameters::ParameterFile>(false);
139 if (!paramFileName.empty()) {
141 // add the parameters specified using an .ini file
143
144 // check whether the parameter file is readable.
145 if (!Parameters::parseParameterFile(paramFileName, /*overwrite=*/false)) {
146 std::ostringstream oss;
147 if (myRank == 0) {
148 oss << "Parameter file \"" << paramFileName
149 << "\" does not exist or is not readable.";
150 Parameters::printUsage(argv[0], std::cerr, oss.str());
151 }
152 return /*status=*/1;
153 }
154 }
155
156 {
157 const char* home = std::getenv("HOME");
158 if (home != nullptr) {
159 const std::string userRcFilename = std::string(home) + "/.config/OpmFlow/user_parameters.param";
160 const bool readFromUserRc = Parameters::parseParameterFile(userRcFilename, /*overwrite=*/false);
161 if (readFromUserRc && myRank == 0) {
162 std::cerr << "Read parameters from " << userRcFilename << ".\n";
163 }
164 }
165 }
166
167 // make sure that no unknown parameters are encountered
168 using ParamList = std::vector<Parameters::Parameter>;
169
170 ParamList usedParams;
171 ParamList unusedParams;
172
173 Parameters::getLists(usedParams, unusedParams);
174 if (!allowUnused && !unusedParams.empty()) {
175 if (myRank == 0) {
176 if (unusedParams.size() == 1) {
177 std::cerr << "The following explicitly specified parameter is unknown:\n";
178 }
179 else {
180 std::cerr << "The following " << unusedParams.size()
181 << " explicitly specified parameters are unknown:\n";
182 }
183
184 std::cerr << "\n";
185 for (const auto& keyValue : unusedParams) {
186 std::cerr << " " << keyValue << "\n";
187 }
188 std::cerr << "\n";
189
190 std::cerr << "Use\n"
191 << "\n"
192 << " " << argv[0] << " --help\n"
193 << "\n"
194 <<"to obtain the list of recognized command line parameters.\n\n";
195 }
196 return /*status=*/1;
197 }
198
199 return /*status=*/0;
200}
201
213template <class TypeTag>
214static inline int start(int argc, char **argv, bool registerParams)
215{
216 using Scalar = GetPropType<TypeTag, Properties::Scalar>;
217 using Simulator = GetPropType<TypeTag, Properties::Simulator>;
218 using Problem = GetPropType<TypeTag, Properties::Problem>;
219 using TM = GetPropType<TypeTag, Properties::ThreadManager>;
220
222
223 resetLocale();
224
225 int myRank = 0;
226 try {
227 // initialize MPI, finalize is done automatically on exit
228#if HAVE_DUNE_FEM
230 myRank = Dune::Fem::MPIManager::rank();
231#else
232 myRank = Dune::MPIHelper::instance(argc, argv).rank();
233#endif
234 const int paramStatus =
235 setupParameters_<TypeTag>(argc,
236 const_cast<const char**>(argv),
237 registerParams,
238 false,
239 true,
240 myRank);
241 if (paramStatus == 1) {
242 return 1;
243 }
244 if (paramStatus == 2) {
245 return 0;
246 }
247
248 TM::init();
249
250 // setting up backend for STDCOUT logger
251 if (myRank == 0) {
252 setupStreamLogging("STDOUT_LOGGER");
253 }
254
255 // read the initial time step and the end time
256 const Scalar endTime = Parameters::Get<Parameters::EndTime<Scalar>>();
257 if (endTime < -1e50) {
258 if (myRank == 0) {
259 Parameters::printUsage(argv[0], std::cerr,
260 "Mandatory parameter '--end-time' not specified!");
261 }
262 return 1;
263 }
264
265 const Scalar initialTimeStepSize = Parameters::Get<Parameters::InitialTimeStepSize<Scalar>>();
266 if (initialTimeStepSize < -1e50) {
267 if (myRank == 0) {
268 Parameters::printUsage(argv[0], std::cerr,
269 "Mandatory parameter '--initial-time-step-size' "
270 "not specified!");
271 }
272 return 1;
273 }
274
275 if (myRank == 0) {
276#ifdef EWOMS_VERSION
277 const std::string versionString = EWOMS_VERSION;
278#else
279 const std::string versionString;
280#endif
281 const std::string briefDescription = Problem::briefDescription();
282 if (!briefDescription.empty()) {
283 const std::string tmp = breakLines(briefDescription,
284 /*indentWidth=*/0,
285 getTtyWidth());
286 std::cout << tmp << std::endl << std::endl;
287 }
288 else {
289 std::cout << "opm models " << versionString
290 << " will now start the simulation. " << std::endl;
291 }
292 }
293
294 // print the parameters if requested
295 const int printParams = Parameters::Get<Parameters::PrintParameters>();
296 if (myRank == 0) {
297 const std::string endParametersSeparator("# [end of parameters]\n");
298 if (printParams) {
299 bool printSeparator = false;
300 if (printParams == 1 || !isatty(fileno(stdout))) {
301 Parameters::printValues(std::cout);
302 printSeparator = true;
303 }
304 else {
305 // always print the list of specified but unused parameters
306 printSeparator = printSeparator || Parameters::printUnused(std::cout);
307 }
308 if (printSeparator) {
309 std::cout << endParametersSeparator;
310 }
311 }
312 else {
313 // always print the list of specified but unused parameters
314 if (Parameters::printUnused(std::cout)) {
315 std::cout << endParametersSeparator;
316 }
317 }
318 }
319
320 // instantiate and run the concrete problem. make sure to
321 // deallocate the problem and before the time manager and the
322 // grid
323 Simulator simulator;
324 simulator.run();
325
326 if (myRank == 0) {
327 std::cout << "Simulation completed" << std::endl;
328 }
329 return 0;
330 }
331 catch (std::exception& e) {
332 if (myRank == 0) {
333 std::cout << e.what() << ". Abort!\n" << std::flush;
334
335 std::cout << "Trying to reset TTY.\n";
337 }
338
339 return 1;
340 }
341 catch (...) {
342 if (myRank == 0) {
343 std::cout << "Unknown exception thrown!\n" << std::flush;
344
345 std::cout << "Trying to reset TTY.\n";
347 }
348
349 return 3;
350 }
351}
352
353} // namespace Opm
354
355#endif
static void registerParameters()
Registers all runtime parameters used by the simulation.
Definition: simulator.hh:215
std::string parseCommandLineOptions(int argc, const char **argv, const PositionalArgumentCallback &posArgCallback, const std::string &helpPreamble="")
Parse the parameters provided on the command line.
void printValues(std::ostream &os)
Print values of the run-time parameters.
void endRegistration()
Indicate that all parameters are registered for a given type tag.
bool parseParameterFile(const std::string &fileName, bool overwrite=true)
Read the parameters from an INI-style file.
void getLists(std::vector< Parameter > &usedParams, std::vector< Parameter > &unusedParams)
Retrieves the lists of parameters specified at runtime and their values.
void printUsage(const std::string &helpPreamble, std::ostream &os, const std::string &errorMsg="", const bool showAll=false)
Print a usage message for all run-time parameters.
bool printUnused(std::ostream &os)
Print the list of unused run-time parameters.
void initialize(bool use_gpu_backend)
Initialize the Hypre library and set memory/execution policy.
Definition: hypreinterface/HypreSetup.hpp:84
Definition: blackoilbioeffectsmodules.hh:45
void resetTerminal()
Resets the current TTY to a usable state if the program was aborted.
void setupStreamLogging(const std::string &stdout_log_id)
std::string breakLines(const std::string &msg, int indentWidth, int maxWidth)
Break up a string in lines suitable for terminal output.
void assignResetTerminalSignalHandlers()
Assign signal handlers that reset the terminal on errors.
int getTtyWidth()
Get the width of the tty we are attached to.
This file provides the infrastructure to retrieve run-time parameters.
The Opm property system, traits with inheritance.