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
31// the following header is not required here, but it must be included before
32// dune/common/densematrix.hh because of some c++ ideosyncrasies
33#include <opm/material/densead/Evaluation.hpp>
34
38
40
41#include <opm/material/common/ResetLocale.hpp>
42
43#include <dune/common/parallel/mpihelper.hh>
44
45#if HAVE_DUNE_FEM
46#include <dune/fem/misc/mpimanager.hh>
47#endif
48
49#include <iostream>
50#include <sstream>
51#include <string>
52
53#include <unistd.h>
54
55#if HAVE_MPI
56#include <mpi.h>
57#endif
58
60
61namespace Opm {
65template <class TypeTag>
66static inline void registerAllParameters_(bool finalizeRegistration = true)
67{
68 using Simulator = GetPropType<TypeTag, Properties::Simulator>;
69 using TM = GetPropType<TypeTag, Properties::ThreadManager>;
70
71 Parameters::Register<Parameters::ParameterFile>
72 ("An .ini file which contains a set of run-time parameters");
73 Parameters::Register<Parameters::PrintParameters>
74 ("Print the values of the run-time parameters at the "
75 "start of the simulation");
76
77 TM::registerParameters();
79
80 if (finalizeRegistration) {
82 }
83}
84
94template <class TypeTag>
95static inline int setupParameters_(int argc,
96 const char **argv,
97 bool registerParams=true,
98 bool allowUnused=false,
99 bool handleHelp = true)
100{
101 using Problem = GetPropType<TypeTag, Properties::Problem>;
102
103 // first, get the MPI rank of the current process
104 int myRank = 0;
105
107 // Register all parameters
109 if (registerParams)
110 registerAllParameters_<TypeTag>();
111
113 // set the parameter values
115
116 // fill the parameter tree with the options from the command line
117 const auto& positionalParamCallback = Problem::handlePositionalParameter;
118 std::string helpPreamble = ""; // print help if non-empty!
119 if (myRank == 0 && handleHelp)
120 helpPreamble = Problem::helpPreamble(argc, argv);
121 std::string s =
123 argv,
124 positionalParamCallback,
125 helpPreamble);
126 if (!s.empty())
127 {
128 int status = 1;
129 if (s == "Help called") // only on master process
130 status = -1; // Use negative values to indicate --help argument
131#if HAVE_MPI
132 // Force -1 if the master process has that.
133 int globalStatus;
134 MPI_Allreduce(&status, &globalStatus, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD);
135 return globalStatus;
136#endif
137 return status;
138 }
139
140 const std::string paramFileName = Parameters::Get<Parameters::ParameterFile>(false);
141 if (!paramFileName.empty()) {
143 // add the parameters specified using an .ini file
145
146 // check whether the parameter file is readable.
147 if (!Parameters::parseParameterFile(paramFileName, /*overwrite=*/false)) {
148 std::ostringstream oss;
149 if (myRank == 0) {
150 oss << "Parameter file \"" << paramFileName
151 << "\" does not exist or is not readable.";
152 Parameters::printUsage(argv[0], std::cerr, oss.str());
153 }
154 return /*status=*/1;
155 }
156 }
157
158 // make sure that no unknown parameters are encountered
159 using ParamList = std::vector<Parameters::Parameter>;
160
161 ParamList usedParams;
162 ParamList unusedParams;
163
164 Parameters::getLists(usedParams, unusedParams);
165 if (!allowUnused && !unusedParams.empty()) {
166 if (myRank == 0) {
167 if (unusedParams.size() == 1)
168 std::cerr << "The following explicitly specified parameter is unknown:\n";
169 else
170 std::cerr << "The following " << unusedParams.size()
171 << " explicitly specified parameters are unknown:\n";
172
173 std::cerr << "\n";
174 for (const auto& keyValue : unusedParams)
175 std::cerr << " " << keyValue << "\n";
176 std::cerr << "\n";
177
178 std::cerr << "Use\n"
179 << "\n"
180 << " " << argv[0] << " --help\n"
181 << "\n"
182 <<"to obtain the list of recognized command line parameters.\n\n";
183 }
184 return /*status=*/1;
185 }
186
187 return /*status=*/0;
188}
189
201template <class TypeTag>
202static inline int start(int argc, char **argv, bool registerParams=true)
203{
204 using Scalar = GetPropType<TypeTag, Properties::Scalar>;
205 using Simulator = GetPropType<TypeTag, Properties::Simulator>;
206 using Problem = GetPropType<TypeTag, Properties::Problem>;
207 using TM = GetPropType<TypeTag, Properties::ThreadManager>;
208
210
211 resetLocale();
212
213 int myRank = 0;
214 try
215 {
216 int paramStatus = setupParameters_<TypeTag>(argc, const_cast<const char**>(argv), registerParams);
217 if (paramStatus == 1)
218 return 1;
219 if (paramStatus == 2)
220 return 0;
221
222 TM::init();
223
224 // initialize MPI, finalize is done automatically on exit
225#if HAVE_DUNE_FEM
226 Dune::Fem::MPIManager::initialize(argc, argv);
227 myRank = Dune::Fem::MPIManager::rank();
228#else
229 myRank = Dune::MPIHelper::instance(argc, argv).rank();
230#endif
231 // setting up backend for STDCOUT logger
232 if (myRank == 0) {
233 setupStreamLogging("STDOUT_LOGGER");
234 }
235
236 // read the initial time step and the end time
237 Scalar endTime = Parameters::Get<Parameters::EndTime<Scalar>>();
238 if (endTime < -1e50) {
239 if (myRank == 0) {
240 Parameters::printUsage(argv[0], std::cerr,
241 "Mandatory parameter '--end-time' not specified!");
242 }
243 return 1;
244 }
245
246 Scalar initialTimeStepSize = Parameters::Get<Parameters::InitialTimeStepSize<Scalar>>();
247 if (initialTimeStepSize < -1e50) {
248 if (myRank == 0) {
249 Parameters::printUsage(argv[0], std::cerr,
250 "Mandatory parameter '--initial-time-step-size' "
251 "not specified!");
252 }
253 return 1;
254 }
255
256 if (myRank == 0) {
257#ifdef EWOMS_VERSION
258 std::string versionString = EWOMS_VERSION;
259#else
260 std::string versionString = "";
261#endif
262 const std::string briefDescription = Problem::briefDescription();
263 if (!briefDescription.empty()) {
264 std::string tmp = breakLines(briefDescription,
265 /*indentWidth=*/0,
266 getTtyWidth());
267 std::cout << tmp << std::endl << std::endl;
268 }
269 else
270 std::cout << "opm models " << versionString
271 << " will now start the simulation. " << std::endl;
272 }
273
274 // print the parameters if requested
275 int printParams = Parameters::Get<Parameters::PrintParameters>();
276 if (myRank == 0) {
277 std::string endParametersSeparator("# [end of parameters]\n");
278 if (printParams) {
279 bool printSeparator = false;
280 if (printParams == 1 || !isatty(fileno(stdout))) {
281 Parameters::printValues(std::cout);
282 printSeparator = true;
283 }
284 else
285 // always print the list of specified but unused parameters
286 printSeparator =
287 printSeparator ||
288 Parameters::printUnused(std::cout);
289 if (printSeparator)
290 std::cout << endParametersSeparator;
291 }
292 else
293 // always print the list of specified but unused parameters
294 if (Parameters::printUnused(std::cout))
295 std::cout << endParametersSeparator;
296 }
297
298 // instantiate and run the concrete problem. make sure to
299 // deallocate the problem and before the time manager and the
300 // grid
301 Simulator simulator;
302 simulator.run();
303
304 if (myRank == 0) {
305 std::cout << "Simulation completed" << std::endl;
306 }
307 return 0;
308 }
309 catch (std::exception& e)
310 {
311 if (myRank == 0) {
312 std::cout << e.what() << ". Abort!\n" << std::flush;
313
314 std::cout << "Trying to reset TTY.\n";
316 }
317
318 return 1;
319 }
320 catch (...)
321 {
322 if (myRank == 0) {
323 std::cout << "Unknown exception thrown!\n" << std::flush;
324
325 std::cout << "Trying to reset TTY.\n";
327 }
328
329 return 3;
330 }
331}
332
333} // namespace Opm
334
335#endif
static void registerParameters()
Registers all runtime parameters used by the simulation.
Definition: simulator.hh:240
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.
Definition: blackoilboundaryratevector.hh:37
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.