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 <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 
58 namespace Opm {
62 template <class TypeTag>
63 static 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) {
78  Parameters::endRegistration();
79  }
80 }
81 
91 template <class TypeTag>
92 static 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 =
119  Parameters::parseCommandLineOptions(argc,
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 
201 template <class TypeTag>
202 static 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";
324  resetTerminal();
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";
334  resetTerminal();
335  }
336 
337  return 3;
338  }
339 }
340 
341 } // namespace Opm
342 
343 #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:108
static void registerParameters()
Registers all runtime parameters used by the simulation.
Definition: simulator.hh:214
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition: blackoilbioeffectsmodules.hh:45
void resetTerminal()
Resets the current TTY to a usable state if the program was aborted.
Definition: terminal.cpp:123
int getTtyWidth()
Get the width of the tty we are attached to.
Definition: terminal.cpp:90
std::string breakLines(const std::string &msg, int indentWidth, int maxWidth)
Break up a string in lines suitable for terminal output.
Definition: terminal.cpp:39
The Opm property system, traits with inheritance.