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 
35 #include "parametersystem.hh"
36 
37 #include <ewoms/version.hh>
41 #include <ewoms/common/timer.hh>
42 
43 #include <opm/common/Valgrind.hpp>
44 
45 #include <opm/common/ResetLocale.hpp>
46 
47 #include <dune/grid/io/file/dgfparser/dgfparser.hh>
48 #include <dune/common/version.hh>
49 #include <dune/common/parametertreeparser.hh>
50 #include <dune/common/parallel/mpihelper.hh>
51 
52 #if HAVE_DUNE_FEM
53 #include <dune/fem/misc/mpimanager.hh>
54 #endif
55 
56 #include <fstream>
57 #include <iostream>
58 #include <sstream>
59 #include <string>
60 #include <locale>
61 
62 #include <stdio.h>
63 #include <unistd.h>
64 #include <time.h>
65 #include <signal.h>
66 #include <string.h>
67 
68 #if HAVE_MPI
69 #include <mpi.h>
70 #endif
71 
72 namespace Ewoms {
73 // forward declaration of property tags
74 namespace Properties {
75 NEW_PROP_TAG(Scalar);
76 NEW_PROP_TAG(Simulator);
77 NEW_PROP_TAG(ThreadManager);
78 NEW_PROP_TAG(PrintProperties);
79 NEW_PROP_TAG(PrintParameters);
80 NEW_PROP_TAG(ParameterFile);
81 } // namespace Properties
82 } // namespace Ewoms
84 
85 namespace Ewoms {
93 template <class TypeTag>
94 static inline int setupParameters_(int argc, char **argv)
95 {
96  typedef typename GET_PROP_TYPE(TypeTag, Simulator) Simulator;
97  typedef typename GET_PROP_TYPE(TypeTag, ThreadManager) ThreadManager;
98  typedef typename GET_PROP(TypeTag, ParameterMetaData) ParameterMetaData;
99 
100  // first, get the MPI rank of the current process
101  int myRank = 0;
102 #if HAVE_MPI
103  MPI_Comm_rank(MPI_COMM_WORLD, &myRank);
104 #endif
105 
107  // Register all parameters
109  EWOMS_REGISTER_PARAM(TypeTag, std::string, ParameterFile,
110  "An .ini file which contains a set of run-time "
111  "parameters");
112  EWOMS_REGISTER_PARAM(TypeTag, int, PrintProperties,
113  "Print the values of the compile time properties at "
114  "the start of the simulation");
115  EWOMS_REGISTER_PARAM(TypeTag, int, PrintParameters,
116  "Print the values of the run-time parameters at the "
117  "start of the simulation");
118 
121 
123  // set the parameter values
125 
126  // fill the parameter tree with the options from the command line
127  std::string s = Parameters::parseCommandLineOptions<TypeTag>(argc, argv, /*handleHelp=*/myRank == 0);
128  if (!s.empty()) {
129  return /*status=*/1;
130  }
131 
132  std::string paramFileName = EWOMS_GET_PARAM_(TypeTag, std::string, ParameterFile);
133  if (paramFileName != "") {
135  // add the parameters specified using an .ini file
137 
138  // check whether the parameter file is readable.
139  std::ifstream tmp;
140  tmp.open(paramFileName.c_str());
141  if (!tmp.is_open()) {
142  std::ostringstream oss;
143  if (myRank == 0) {
144  oss << "Parameter file \"" << paramFileName
145  << "\" does not exist or is not readable.";
146  Parameters::printUsage<TypeTag>(argv[0], oss.str());
147  }
148  return /*status=*/1;
149  }
150 
151  // read the parameter file.
152  Dune::ParameterTreeParser::readINITree(paramFileName,
153  ParameterMetaData::tree(),
154  /*overwrite=*/false);
155  }
156 
158 
159  return /*status=*/0;
160 }
161 
166 static inline void resetTerminal_(int signum)
167 {
168  // first thing to do when a nuke hits: restore the default signal handler
169  signal(signum, SIG_DFL);
170  std::cout << "\n\nReceived signal " << signum
171  << " (\"" << strsignal(signum) << "\")."
172  << " Trying to reset the terminal.\n";
173 
174  // this requires the 'stty' command to be available in the command search path. on
175  // most linux systems, is the case. (but even if the system() function fails, the
176  // worst thing which can happen is that the TTY stays potentially choked up...)
177  if (system("stty sane") != 0)
178  std::cout << "Executing the 'stty' command failed."
179  << " Terminal might be left in an undefined state!\n";
180 
181  // after we did our best to clean the pedestrian way, re-raise the signal
182  raise(signum);
183 }
185 
197 template <class TypeTag>
198 static inline int start(int argc, char **argv)
199 {
200  typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
201  typedef typename GET_PROP_TYPE(TypeTag, Simulator) Simulator;
202  typedef typename GET_PROP_TYPE(TypeTag, ThreadManager) ThreadManager;
203 
204  // set the signal handlers to reset the TTY to a well defined state on unexpected
205  // program aborts
206  if (isatty(STDIN_FILENO)) {
207  signal(SIGINT, resetTerminal_);
208  signal(SIGHUP, resetTerminal_);
209  signal(SIGABRT, resetTerminal_);
210  signal(SIGFPE, resetTerminal_);
211  signal(SIGSEGV, resetTerminal_);
212  signal(SIGPIPE, resetTerminal_);
213  signal(SIGTERM, resetTerminal_);
214  }
215 
216  Opm::resetLocale();
217 
218  // initialize MPI, finalize is done automatically on exit
219 #if HAVE_DUNE_FEM
220  Dune::Fem::MPIManager::initialize(argc, argv);
221  const int myRank = Dune::Fem::MPIManager::rank();
222 #else
223  const int myRank = Dune::MPIHelper::instance(argc, argv).rank();
224 #endif
225 
226  try
227  {
228  int paramStatus = setupParameters_<TypeTag>(argc, argv);
229  if (paramStatus == 1)
230  return 1;
231  if (paramStatus == 2)
232  return 0;
233 
234  ThreadManager::init();
235 
236  // read the initial time step and the end time
237  Scalar endTime = EWOMS_GET_PARAM(TypeTag, Scalar, EndTime);
238  if (endTime < -1e50) {
239  if (myRank == 0)
240  Parameters::printUsage<TypeTag>(argv[0],
241  "Mandatory parameter '--end-time' not specified!");
242  return 1;
243  }
244 
245  Scalar initialTimeStepSize = EWOMS_GET_PARAM(TypeTag, Scalar, InitialTimeStepSize);
246  if (initialTimeStepSize < -1e50) {
247  if (myRank == 0)
248  Parameters::printUsage<TypeTag>(argv[0],
249  "Mandatory parameter '--initial-time-step-size' "
250  "not specified!");
251  return 1;
252  }
253 
254 
255  if (myRank == 0)
256  std::cout << "eWoms " << Ewoms::versionString()
257  << " will now start the trip. "
258  << "Please sit back, relax and enjoy the ride.\n"
259  << std::flush;
260 
261  // print the parameters if requested
262  int printParams = EWOMS_GET_PARAM(TypeTag, int, PrintParameters);
263  if (myRank == 0) {
264  std::string endParametersSeparator("# [end of parameters]\n");
265  if (printParams) {
266  bool printSeparator = false;
267  if (printParams == 1 || !isatty(fileno(stdout))) {
268  Ewoms::Parameters::printValues<TypeTag>();
269  printSeparator = true;
270  }
271  else
272  // always print the list of specified but unused parameters
273  printSeparator =
274  printSeparator ||
275  Ewoms::Parameters::printUnused<TypeTag>();
276  if (printSeparator)
277  std::cout << endParametersSeparator;
278  }
279  else
280  // always print the list of specified but unused parameters
281  if (Ewoms::Parameters::printUnused<TypeTag>())
282  std::cout << endParametersSeparator;
283  }
284 
285  // print the properties if requested
286  int printProps = EWOMS_GET_PARAM(TypeTag, int, PrintProperties);
287  if (printProps && myRank == 0) {
288  if (printProps == 1 || !isatty(fileno(stdout)))
289  Ewoms::Properties::printValues<TypeTag>();
290  }
291 
292  // instantiate and run the concrete problem. make sure to
293  // deallocate the problem and before the time manager and the
294  // grid
295  Simulator simulator;
296  simulator.run();
297 
298  if (myRank == 0) {
299  std::cout << "eWoms reached the destination. If it is not the one that was intended, "
300  << "change the booking and try again.\n"
301  << std::flush;
302  }
303  return 0;
304  }
305  catch (std::exception& e)
306  {
307  if (myRank == 0)
308  std::cout << e.what() << ". Abort!\n" << std::flush;
309  return 1;
310  }
311 #if ! DUNE_VERSION_NEWER(DUNE_COMMON, 2,5)
312  catch (Dune::Exception& e)
313  {
314  if (myRank == 0)
315  std::cout << "Dune reported an error: " << e.what() << std::endl << std::flush;
316  return 2;
317  }
318 #endif
319  catch (...)
320  {
321  if (myRank == 0)
322  std::cout << "Unknown exception thrown!\n" << std::flush;
323  return 3;
324  }
325 }
326 
327 } // namespace Ewoms
328 
329 #endif
#define EWOMS_END_PARAM_REGISTRATION(TypeTag)
Indicate that all parameters are registered for a given type tag.
Definition: parametersystem.hh:81
Manages the initializing and running of time dependent problems.
Definition: baseauxiliarymodule.hh:37
int signum(Scalar val)
Template function which returns the sign of a floating point value.
Definition: signum.hh:40
static void registerParameters()
Registers all runtime parameters used by the simulation.
Definition: simulator.hh:151
#define GET_PROP_TYPE(TypeTag, PropTagName)
Access the type attribute of a property for a type tag.
Definition: propertysystem.hh:486
#define EWOMS_REGISTER_PARAM(TypeTag, ParamType, ParamName, Description)
Register a run-time parameter.
Definition: parametersystem.hh:68
This file provides the infrastructure to retrieve run-time parameters.
#define EWOMS_GET_PARAM(TypeTag, ParamType, ParamName)
Retrieve a runtime parameter.
Definition: parametersystem.hh:99
Provides an encapsulation to measure the system time.
Provides the magic behind the eWoms property system.
#define NEW_PROP_TAG(PTagName)
Define a property tag.
Definition: propertysystem.hh:247
#define GET_PROP(TypeTag, PropTagName)
Retrieve a property for a type tag.
Definition: propertysystem.hh:454
static void registerParameters()
Register all run-time parameters of the thread manager.
Definition: threadmanager.hh:67