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