opm-simulators
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 
37 #include <opm/models/utils/terminal.hpp>
39 
40 #include <opm/simulators/utils/readDeck.hpp>
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 
59 namespace Opm {
63 template <class TypeTag>
64 static 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) {
79  Parameters::endRegistration();
80  }
81 }
82 
92 template <class TypeTag>
93 static 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 =
120  Parameters::parseCommandLineOptions(argc,
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 
213 template <class TypeTag>
214 static 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
229  Dune::Fem::MPIManager::initialize(argc, argv);
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";
336  resetTerminal();
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";
346  resetTerminal();
347  }
348 
349  return 3;
350  }
351 }
352 
353 } // namespace Opm
354 
355 #endif
Manages the initializing and running of time dependent problems.
This file provides the infrastructure to retrieve run-time parameters.
void assignResetTerminalSignalHandlers()
Assign signal handlers that reset the terminal on errors.
Definition: terminal.cpp:128
static void registerParameters()
Registers all runtime parameters used by the simulation.
Definition: simulator.hh:215
Structs needed for tpfalinearizer and its gpuparams struct extracted to be defined in one place that ...
Definition: blackoilbioeffectsmodules.hh:45
void resetTerminal()
Resets the current TTY to a usable state if the program was aborted.
Definition: terminal.cpp:143
int getTtyWidth()
Get the width of the tty we are attached to.
Definition: terminal.cpp:110
std::string breakLines(const std::string &msg, int indentWidth, int maxWidth)
Break up a string in lines suitable for terminal output.
Definition: terminal.cpp:59
The Opm property system, traits with inheritance.