OGS
ogs.cpp File Reference
#include <spdlog/spdlog.h>
#include <tclap/CmdLine.h>
#include <chrono>
#include <sstream>
#include <cfenv>
#include <vtkMPIController.h>
#include <vtkSmartPointer.h>
#include "Applications/ApplicationsLib/LinearSolverLibrarySetup.h"
#include "Applications/ApplicationsLib/ProjectData.h"
#include "Applications/ApplicationsLib/TestDefinition.h"
#include "Applications/InSituLib/Adaptor.h"
#include "BaseLib/ConfigTreeUtil.h"
#include "BaseLib/DateTools.h"
#include "BaseLib/FileTools.h"
#include "BaseLib/RunTime.h"
#include "InfoLib/CMakeInfo.h"
#include "InfoLib/GitInfo.h"
#include "NumLib/NumericsConfig.h"
#include "ProcessLib/TimeLoop.h"
#include "filesystem.h"
#include "ogs_embedded_python.h"
Include dependency graph for ogs.cpp:

Go to the source code of this file.

Functions

int main (int argc, char *argv[])
 Implementation of OpenGeoSys simulation application. More...
 

Function Documentation

◆ main()

int main ( int  argc,
char *  argv[] 
)

Implementation of OpenGeoSys simulation application.

Date
2014-08-04
Input File Parameter:
prj__test_definition
Input File Parameter:
prj__insitu
Input File Parameter:
prj__insitu__scripts

Definition at line 53 of file ogs.cpp.

54 {
55  // Parse CLI arguments.
56  TCLAP::CmdLine cmd(
57  "OpenGeoSys-6 software.\n"
58  "Copyright (c) 2012-2021, OpenGeoSys Community "
59  "(http://www.opengeosys.org) "
60  "Distributed under a Modified BSD License. "
61  "See accompanying file LICENSE.txt or "
62  "http://www.opengeosys.org/project/license\n"
63  "version: " +
65  "CMake arguments: " + CMakeInfoLib::CMakeInfo::cmake_args,
66  ' ',
68  "CMake arguments: " + CMakeInfoLib::CMakeInfo::cmake_args);
69 
70  TCLAP::ValueArg<std::string> reference_path_arg(
71  "r", "reference",
72  "Run output result comparison after successful simulation comparing to "
73  "all files in the given path. This requires test definitions to be "
74  "present in the project file.",
75  false, "", "PATH");
76  cmd.add(reference_path_arg);
77 
78  TCLAP::UnlabeledValueArg<std::string> project_arg(
79  "project-file",
80  "Path to the ogs6 project file.",
81  true,
82  "",
83  "PROJECT_FILE");
84  cmd.add(project_arg);
85 
86  TCLAP::MultiArg<std::string> xml_patch_files(
87  "p", "xml-patch",
88  "the xml patch file(s) which is (are) applied (in the given order) to "
89  "the PROJECT_FILE",
90  false, "");
91  cmd.add(xml_patch_files);
92 
93  TCLAP::ValueArg<std::string> outdir_arg("o", "output-directory",
94  "the output directory to write to",
95  false, "", "PATH");
96  cmd.add(outdir_arg);
97 
98  TCLAP::ValueArg<std::string> log_level_arg(
99  "l", "log-level",
100  "the verbosity of logging messages: none, error, warn, info, debug, "
101  "all",
102  false,
103 #ifdef NDEBUG
104  "info",
105 #else
106  "all",
107 #endif
108  "LOG_LEVEL");
109  cmd.add(log_level_arg);
110 
111  TCLAP::SwitchArg nonfatal_arg("",
112  "config-warnings-nonfatal",
113  "warnings from parsing the configuration "
114  "file will not trigger program abortion");
115  cmd.add(nonfatal_arg);
116 
117  TCLAP::SwitchArg unbuffered_cout_arg("", "unbuffered-std-out",
118  "use unbuffered standard output");
119  cmd.add(unbuffered_cout_arg);
120 
121 #ifndef _WIN32 // TODO: On windows floating point exceptions are not handled
122  // currently
123  TCLAP::SwitchArg enable_fpe_arg("", "enable-fpe",
124  "enables floating point exceptions");
125  cmd.add(enable_fpe_arg);
126 #endif // _WIN32
127 
128  cmd.parse(argc, argv);
129 
130  // deactivate buffer for standard output if specified
131  if (unbuffered_cout_arg.isSet())
132  {
133  std::cout.setf(std::ios::unitbuf);
134  }
135 
136  BaseLib::setConsoleLogLevel(log_level_arg.getValue());
137  spdlog::set_pattern("%^%l:%$ %v");
138  spdlog::set_error_handler(
139  [](const std::string& msg)
140  {
141  std::cerr << "spdlog error: " << msg << std::endl;
142  OGS_FATAL("spdlog logger error occurred.");
143  });
144 
145  INFO("This is OpenGeoSys-6 version {:s}.",
147 
148 #ifndef _WIN32 // On windows this command line option is not present.
149  // Enable floating point exceptions
150  if (enable_fpe_arg.isSet())
151  {
152 #ifdef __APPLE__
153 #ifdef __SSE__
154  _MM_SET_EXCEPTION_MASK(_MM_GET_EXCEPTION_MASK() & ~_MM_MASK_INVALID);
155 #endif // __SSE__
156 #else
157  feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
158 #endif // __APPLE__
159  }
160 #endif // _WIN32
161 
162 #ifdef OGS_USE_PYTHON
163  pybind11::scoped_interpreter guard = ApplicationsLib::setupEmbeddedPython();
164  (void)guard;
165 #endif
166 
167  BaseLib::RunTime run_time;
168 
169  {
170  auto const start_time = std::chrono::system_clock::now();
171  auto const time_str = BaseLib::formatDate(start_time);
172  INFO("OGS started on {:s}.", time_str);
173  }
174 
175  std::unique_ptr<ApplicationsLib::TestDefinition> test_definition;
176  auto ogs_status = EXIT_SUCCESS;
177 
178  try
179  {
180  bool solver_succeeded = false;
181  {
183  linear_solver_library_setup(argc, argv);
184 #if defined(USE_PETSC)
185  vtkSmartPointer<vtkMPIController> controller =
186  vtkSmartPointer<vtkMPIController>::New();
187  controller->Initialize(&argc, &argv, 1);
188  vtkMPIController::SetGlobalController(controller);
189 
190  { // Can be called only after MPI_INIT.
191  int mpi_rank;
192  MPI_Comm_rank(PETSC_COMM_WORLD, &mpi_rank);
193  spdlog::set_pattern(fmt::format("[{}] %^%l:%$ %v", mpi_rank));
194  }
195 #endif
196 
197  run_time.start();
198 
199  auto project_config = BaseLib::makeConfigTree(
200  project_arg.getValue(), !nonfatal_arg.getValue(),
201  "OpenGeoSysProject", xml_patch_files.getValue());
202 
204  BaseLib::extractPath(project_arg.getValue()));
205 
206  ProjectData project(*project_config,
208  outdir_arg.getValue());
209 
210  if (!reference_path_arg.isSet())
211  { // Ignore the test_definition section.
212  project_config->ignoreConfigParameter("test_definition");
213  }
214  else
215  {
216  test_definition =
217  std::make_unique<ApplicationsLib::TestDefinition>(
219  project_config->getConfigSubtree("test_definition"),
220  reference_path_arg.getValue(),
221  outdir_arg.getValue());
222  if (test_definition->numberOfTests() == 0)
223  {
224  OGS_FATAL(
225  "No tests were constructed from the test definitions, "
226  "but reference solutions path was given.");
227  }
228 
229  INFO("Cleanup possible output files before running ogs.");
230  BaseLib::removeFiles(test_definition->getOutputFiles());
231  }
232 #ifdef USE_INSITU
233  auto isInsituConfigured = false;
235  if (auto t = project_config->getConfigSubtreeOptional("insitu"))
236  {
239  t->getConfigSubtree("scripts"),
240  BaseLib::extractPath(project_arg.getValue()));
241  isInsituConfigured = true;
242  }
243 #else
244  project_config->ignoreConfigParameter("insitu");
245 #endif
246 
247  INFO("Initialize processes.");
248  for (auto& p : project.getProcesses())
249  {
250  p->initialize();
251  }
252 
253  // Check intermediately that config parsing went fine.
254  project_config.checkAndInvalidate();
256 
258 
260 
261  INFO("Solve processes.");
262 
263  auto& time_loop = project.getTimeLoop();
264  time_loop.initialize();
265  solver_succeeded = time_loop.loop();
266 
267 #ifdef USE_INSITU
268  if (isInsituConfigured)
270 #endif
271  INFO("[time] Execution took {:g} s.", run_time.elapsed());
272 
273 #if defined(USE_PETSC)
274  controller->Finalize(1);
275 #endif
276  } // This nested scope ensures that everything that could possibly
277  // possess a ConfigTree is destructed before the final check below is
278  // done.
279 
281 
282  ogs_status = solver_succeeded ? EXIT_SUCCESS : EXIT_FAILURE;
283  }
284  catch (std::exception& e)
285  {
286  ERR(e.what());
287  ogs_status = EXIT_FAILURE;
288  }
289 
290  {
291  auto const end_time = std::chrono::system_clock::now();
292  auto const time_str = BaseLib::formatDate(end_time);
293  INFO("OGS terminated on {:s}.", time_str);
294  }
295 
296  if (ogs_status == EXIT_FAILURE)
297  {
298  ERR("OGS terminated with error.");
299  return EXIT_FAILURE;
300  }
301 
302  if (test_definition == nullptr)
303  {
304  // There are no tests, so just exit;
305  return ogs_status;
306  }
307 
308  INFO("");
309  INFO("##########################################");
310  INFO("# Running tests #");
311  INFO("##########################################");
312  INFO("");
313  if (!test_definition->runTests())
314  {
315  ERR("One of the tests failed.");
316  return EXIT_FAILURE;
317  }
318  return EXIT_SUCCESS;
319 }
#define OGS_FATAL(...)
Definition: Error.h:26
void INFO(char const *fmt, Args const &... args)
Definition: Logging.h:32
void ERR(char const *fmt, Args const &... args)
Definition: Logging.h:42
static void assertNoSwallowedErrors()
Asserts that there have not been any errors reported in the destructor.
Definition: ConfigTree.cpp:239
Count the running time.
Definition: RunTime.h:29
double elapsed() const
Get the elapsed time in seconds.
Definition: RunTime.h:42
void start()
Start the timer.
Definition: RunTime.h:32
pybind11::scoped_interpreter setupEmbeddedPython()
std::string const & getProjectDirectory()
Returns the directory where the prj file resides.
Definition: FileTools.cpp:217
void setConsoleLogLevel(std::string const &level_string)
Definition: Logging.cpp:34
std::string extractPath(std::string const &pathname)
Definition: FileTools.cpp:207
std::string formatDate(std::chrono::time_point< std::chrono::system_clock > const &time)
Definition: DateTools.cpp:137
std::string format(const char *format_str,...)
Definition: StringTools.cpp:85
void setProjectDirectory(std::string const &dir)
Sets the project directory.
Definition: FileTools.cpp:226
ConfigTreeTopLevel makeConfigTree(const std::string &filepath, const bool be_ruthless, const std::string &toplevel_tag, const std::vector< std::string > &patch_files)
void removeFiles(std::vector< std::string > const &files)
Definition: FileTools.cpp:245
GITINFOLIB_EXPORT const std::string ogs_version
void Initialize(BaseLib::ConfigTree const &scripts_config, std::string const &path)
Definition: Adaptor.cpp:27
void Finalize()
Definition: Adaptor.cpp:59
static const double p

References BaseLib::ConfigTree::assertNoSwallowedErrors(), BaseLib::RunTime::elapsed(), ERR(), BaseLib::extractPath(), InSituLib::Finalize(), BaseLib::format(), BaseLib::formatDate(), ProjectData::getProcesses(), BaseLib::getProjectDirectory(), ProjectData::getTimeLoop(), INFO(), ProcessLib::TimeLoop::initialize(), InSituLib::Initialize(), BaseLib::makeConfigTree(), OGS_FATAL, GitInfoLib::GitInfo::ogs_version, MathLib::p, BaseLib::removeFiles(), BaseLib::setConsoleLogLevel(), BaseLib::setProjectDirectory(), ApplicationsLib::setupEmbeddedPython(), and BaseLib::RunTime::start().