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