OGS
ogs.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
4#include <pybind11/pybind11.h>
5#include <spdlog/spdlog.h>
6#include <tclap/CmdLine.h>
7
8#include <algorithm>
9#include <chrono>
10#include <csignal>
11#include <iostream>
12#include <sstream>
13
15
16#ifndef _WIN32
17#ifdef __APPLE__
18#ifdef __SSE__
19#include <xmmintrin.h>
20#endif // __SSE__
21#else
22#include <cfenv>
23#endif // __APPLE__
24#endif // _WIN32
25
28#include "BaseLib/ConfigTree.h"
29#include "BaseLib/DateTools.h"
30#include "BaseLib/Error.h"
31#include "BaseLib/FileTools.h"
32#include "BaseLib/Logging.h"
33#include "BaseLib/RunTime.h"
34#include "InfoLib/GitInfo.h"
35
36#ifndef _WIN32 // On windows this command line option is not present.
38{
39#ifdef __APPLE__
40#ifdef __SSE__
41 _MM_SET_EXCEPTION_MASK(_MM_GET_EXCEPTION_MASK() & ~_MM_MASK_INVALID);
42#endif // __SSE__
43#else
44 feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
45#endif // __APPLE__
46}
47#endif // _WIN32
48
49#include <spdlog/sinks/null_sink.h>
50#include <spdlog/sinks/stdout_color_sinks.h>
51
52#include "BaseLib/MPI.h"
53
54void signalHandler(int signum)
55{
56 auto const end_time = std::chrono::system_clock::now();
57 auto const time_str = BaseLib::formatDate(end_time);
58
59 ERR("Simulation aborted on {:s}. Received signal: {:d}.", time_str, signum);
60 exit(signum);
61}
62
63void initializeLogger([[maybe_unused]] bool const all_ranks_log)
64{
65#if defined(USE_PETSC)
66 int mpi_rank;
67 MPI_Comm_rank(BaseLib::MPI::OGS_COMM_WORLD, &mpi_rank);
68 int world_size;
69 MPI_Comm_size(BaseLib::MPI::OGS_COMM_WORLD, &world_size);
70
71 if (all_ranks_log)
72 {
73 if (world_size > 1)
74 {
75 spdlog::set_pattern(fmt::format("[{}] %^%l:%$ %v", mpi_rank));
76 }
77 // else untouched
78 }
79 else // only rank 0 logs
80 {
81 // set_pattern is untouched
82 spdlog::drop_all();
83 if (mpi_rank > 0)
84 {
85 BaseLib::console = spdlog::create<spdlog::sinks::null_sink_st>(
86 "ogs"); // do not log
87 }
88 else // rank 0
89 {
90 auto console = BaseLib::console =
91 spdlog::stdout_color_st("ogs"); // st for performance
92 }
93 }
94
95 {
96 auto const start_time = std::chrono::system_clock::now();
97 auto const time_str = BaseLib::formatDate(start_time);
98 INFO("OGS started on {:s} with MPI. MPI processes: {:d}.", time_str,
99 world_size);
100 }
101
102#else // defined(USE_PETSC)
103
104 {
105 auto const start_time = std::chrono::system_clock::now();
106 auto const time_str = BaseLib::formatDate(start_time);
107 INFO("OGS started on {:s} in serial mode.", time_str);
108 }
109
110#endif
111}
112
113int main(int argc, char* argv[])
114{
116
117 // Initialize MPI
118 // also in python hook
119 // check tools
120 BaseLib::MPI::Setup mpi_setup(argc, argv);
123
124 signal(SIGINT, signalHandler); // CTRL+C
125 signal(SIGTERM, signalHandler); // pkill -SIGTERM <process_id> , It is NOT
126 // possible to catch SIGKILL
127
128#ifndef _WIN32 // TODO: On windows floating point exceptions are not handled
129 if (cli_arg.enable_fpe_is_set)
130 {
132 }
133#endif // _WIN32
134
135 INFO(
136 "This is OpenGeoSys-6 version {:s}. Log version: {:d}, Log level: "
137 "{:s}.",
140
141 std::optional<ApplicationsLib::TestDefinition> test_definition{
142 std::nullopt};
143 auto ogs_status = EXIT_SUCCESS;
144
145 try
146 {
147 Simulation simulation(argc, argv);
148
149 BaseLib::RunTime run_time;
150 run_time.start();
151
152 bool solver_succeeded = false;
153 try
154 {
155 simulation.initializeDataStructures(
156 std::move(cli_arg.project),
157 std::move(cli_arg.xml_patch_file_names),
158 cli_arg.reference_path_is_set,
159 std::move(cli_arg.reference_path), cli_arg.nonfatal,
160 std::move(cli_arg.outdir), std::move(cli_arg.mesh_dir),
161 std::move(cli_arg.script_dir), cli_arg.write_prj);
162 solver_succeeded = simulation.executeSimulation();
163 simulation.outputLastTimeStep();
164 test_definition = simulation.getTestDefinition();
165 }
166 catch (pybind11::error_already_set const& e)
167 {
168 OGS_FATAL("Python exception thrown: {}", e.what());
169 }
170 if (solver_succeeded)
171 {
172 INFO("[time] Simulation completed. It took {:g} s.",
173 run_time.elapsed());
174 }
175 else
176 {
177 INFO("[time] Simulation failed. It took {:g} s.",
178 run_time.elapsed());
179 }
180
181 ogs_status = solver_succeeded ? EXIT_SUCCESS : EXIT_FAILURE;
182 }
183 catch (std::exception& e)
184 {
185 ERR("{}", e.what());
186 ogs_status = EXIT_FAILURE;
187 }
188
189 // Check for swallowed ConfigTree errors after Simulation destructor runs.
190 // This catches configuration errors in objects destroyed at end of scope.
191 try
192 {
194 }
195 catch (std::exception& e)
196 {
197 ERR("{}", e.what());
198 ogs_status = EXIT_FAILURE;
199 }
200
201 if (ogs_status == EXIT_FAILURE)
202 {
203 auto const end_time = std::chrono::system_clock::now();
204 auto const time_str = BaseLib::formatDate(end_time);
205 ERR("OGS terminated with error on {:s}.", time_str);
206 return EXIT_FAILURE;
207 }
208
209 return Simulation::runTestDefinitions(test_definition);
210}
CommandLineArguments parseCommandLineArguments(int argc, char *argv[], bool const exit_on_exception)
#define OGS_FATAL(...)
Definition Error.h:19
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:28
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:40
void signalHandler(int signum)
static void assertNoSwallowedErrors()
Asserts that there have not been any errors reported in the destructor.
Count the running time.
Definition RunTime.h:18
double elapsed() const
Get the elapsed time in seconds.
Definition RunTime.h:31
void start()
Start the timer.
Definition RunTime.h:21
OGS_EXPORT_SYMBOL bool executeSimulation()
OGS_EXPORT_SYMBOL std::optional< ApplicationsLib::TestDefinition > getTestDefinition() const
static OGS_EXPORT_SYMBOL int runTestDefinitions(std::optional< ApplicationsLib::TestDefinition > &test_definition)
OGS_EXPORT_SYMBOL void initializeDataStructures(std::string const &project, std::vector< std::string > const &xml_patch_file_names, bool reference_path_is_set, std::string const &reference_path, bool nonfatal, std::string const &outdir, std::string const &mesh_dir, std::string const &script_dir, bool write_prj)
OGS_EXPORT_SYMBOL void outputLastTimeStep() const
MPI_Comm OGS_COMM_WORLD
Definition MPI.cpp:9
void initOGSLogger(std::string const &log_level)
Definition Logging.cpp:56
std::string formatDate(std::chrono::time_point< std::chrono::system_clock > const &time)
std::shared_ptr< spdlog::logger > console
Definition Logging.cpp:37
bool createOutputDirectory(std::string const &dir)
GITINFOLIB_EXPORT const std::string ogs_version
int main(int argc, char *argv[])
Definition ogs.cpp:113
void signalHandler(int signum)
Definition ogs.cpp:54
void enableFloatingPointExceptions()
Definition ogs.cpp:37
void initializeLogger(bool const all_ranks_log)
Definition ogs.cpp:63
std::vector< std::string > xml_patch_file_names