OGS
ogs_python_module.cpp
Go to the documentation of this file.
1
13#include <pybind11/pybind11.h>
14#include <pybind11/stl.h>
15#include <spdlog/spdlog.h>
16#include <tclap/CmdLine.h>
17
18#include <algorithm>
19
23#include "BaseLib/DateTools.h"
24#include "BaseLib/Error.h"
25#include "BaseLib/FileTools.h"
26#include "BaseLib/Logging.h"
27#include "BaseLib/RunTime.h"
29#include "InfoLib/GitInfo.h"
30#include "ogs_embedded_python.h"
31
32static constexpr int EXIT_ARGPARSE_FAILURE = 3; // "mangled" TCLAP status
33static constexpr int EXIT_ARGPARSE_EXIT_OK = 2; // "mangled" TCLAP status
34static_assert(EXIT_FAILURE == 1);
35static_assert(EXIT_SUCCESS == 0);
36
37int checkCommandLineArguments(std::vector<std::string>& argv_str)
38{
39 INFO("Parsing the OGS commandline ...");
40 int argc = argv_str.size();
41 char** argv = new char*[argc];
42 for (int i = 0; i < argc; ++i)
43 {
44 argv[i] = argv_str[i].data();
45 }
46
47 CommandLineArguments cli_args;
48 try
49 {
50 cli_args = parseCommandLineArguments(argc, argv, false);
51 }
52 catch (TCLAP::ArgException const& e)
53 {
54 ERR("Parsing the OGS commandline failed: {}", e.what());
56
57 // "mangle" TCLAP's status
59 }
60 catch (TCLAP::ExitException const& e)
61 {
62 if (e.getExitStatus() == 0)
63 {
66 }
67
69 // "mangle" TCLAP's status
71 }
72
73 INFO("Parsing the OGS commandline passed");
75 return EXIT_SUCCESS;
76}
77
78// Needs to be exported, see
79// https://pybind11.readthedocs.io/en/stable/advanced/misc.html#partitioning-code-over-multiple-extension-modules
80class PYBIND11_EXPORT OGSSimulation
81{
82public:
83 explicit OGSSimulation(std::vector<std::string>& argv_str)
84 {
85 int argc = argv_str.size();
86 char** argv = new char*[argc];
87 for (int i = 0; i < argc; ++i)
88 {
89 argv[i] = argv_str[i].data();
90 }
91
92 CommandLineArguments cli_args;
93 try
94 {
95 cli_args = parseCommandLineArguments(argc, argv, false);
96 }
97 catch (TCLAP::ArgException const& e)
98 {
99 std::cerr << "Parsing the OGS commandline failed: " << e.what()
100 << '\n';
101
102 // "mangle" TCLAP's status
103 throw(e);
104 }
105 catch (TCLAP::ExitException const& e)
106 {
107 throw(e);
108 }
109
111
112 DBUG("OGSSimulation::OGSSimulation(std::vector<std::string>&)");
113
114 INFO(
115 "This is OpenGeoSys-6 version {:s}. Log version: {:d}, Log level: "
116 "{:s}.",
118
120
121 {
122 auto const start_time = std::chrono::system_clock::now();
123 auto const time_str = BaseLib::formatDate(start_time);
124 // todo ask Tobias: started vs starts
125 INFO("OGS starts on {:s} in serial mode / Python embedded mode.",
126 time_str);
127 }
128 try
129 {
130 simulation = std::make_unique<Simulation>(argc, argv);
131 simulation->initializeDataStructures(
132 std::move(cli_args.project),
133 std::move(cli_args.xml_patch_file_names),
134 cli_args.reference_path_is_set,
135 std::move(cli_args.reference_path), cli_args.nonfatal,
136 std::move(cli_args.outdir), std::move(cli_args.mesh_dir),
137 std::move(cli_args.script_dir), cli_args.write_prj);
138 }
139 catch (std::exception& e)
140 {
141 ERR("{}", e.what());
142 ogs_status = EXIT_FAILURE;
144 throw(e);
145 }
146 INFO("OpenGeoSys is now initialized.");
147 }
148
150 {
151 BaseLib::RunTime run_time;
152
153 {
154 auto const start_time = std::chrono::system_clock::now();
155 auto const time_str = BaseLib::formatDate(start_time);
156 INFO("OGS started on {:s} in serial mode.", time_str);
157 }
158
159 std::optional<ApplicationsLib::TestDefinition> test_definition{
160 std::nullopt};
161
162 try
163 {
164 run_time.start();
165 bool solver_succeeded = simulation->executeSimulation();
166 simulation->outputLastTimeStep();
167 test_definition = simulation->getTestDefinition();
168
169 if (solver_succeeded)
170 {
171 INFO("[time] Simulation completed. It took {:g} s.",
172 run_time.elapsed());
173 }
174 else
175 {
176 INFO("[time] Simulation failed. It took {:g} s.",
177 run_time.elapsed());
178 }
179 ogs_status = solver_succeeded ? EXIT_SUCCESS : EXIT_FAILURE;
180 }
181 catch (std::exception& e)
182 {
183 ERR("{}", e.what());
184 ogs_status = EXIT_FAILURE;
185 }
186
187 if (ogs_status == EXIT_FAILURE)
188 {
189 auto const end_time = std::chrono::system_clock::now();
190 auto const time_str = BaseLib::formatDate(end_time);
191 ERR("OGS terminated with error on {:s}.", time_str);
192 return EXIT_FAILURE;
193 }
194
195 return Simulation::runTestDefinitions(test_definition);
196 }
197
199 {
200 auto ogs_status = EXIT_SUCCESS;
201 try
202 {
203 bool solver_succeeded = simulation->executeTimeStep();
204 ogs_status = solver_succeeded ? EXIT_SUCCESS : EXIT_FAILURE;
205 }
206 catch (std::exception& e)
207 {
208 ERR("{}", e.what());
209 ogs_status = EXIT_FAILURE;
210 }
211 return ogs_status;
212 }
213
214 double currentTime() const { return simulation->currentTime(); }
215
216 double endTime() const { return simulation->endTime(); }
217
218 OGSMesh& getMesh(std::string const& name)
219 {
220 auto const mesh_it = mesh_mapping.find(name);
221 if (mesh_it != mesh_mapping.end())
222 {
223 INFO("found OGSMesh '{}' with address: {}", name,
224 fmt::ptr(&(mesh_it->second)));
225 return mesh_it->second;
226 }
227
228 auto const& [it, success] =
229 mesh_mapping.insert({name, OGSMesh(simulation->getMesh(name))});
230 if (!success)
231 {
232 OGS_FATAL("Could not access mesh '{}'.", name);
233 }
234 INFO("insert OGSMesh '{}' with address: {}", name,
235 fmt::ptr(&(it->second)));
236 return it->second;
237 }
238
239 std::vector<std::string> getMeshNames() const
240 {
241 return simulation->getMeshNames();
242 }
243
244 void finalize()
245 {
246 simulation->outputLastTimeStep();
247 simulation.reset(nullptr);
248
249 // Unset project dir to make multiple OGS runs in one Python session
250 // possible.
252 }
253
254private:
255 int ogs_status = EXIT_SUCCESS;
256
257 std::unique_ptr<Simulation> simulation;
258 std::map<std::string, OGSMesh> mesh_mapping;
259};
260
267PYBIND11_MODULE(OGSSimulator, m)
268{
270 m.attr("__name__") = "ogs.OGSSimulator";
271 m.doc() = "pybind11 ogs plugin";
272
273 m.def("check_command_line_arguments", &checkCommandLineArguments,
274 "check the command line arguments");
275
276 pybind11::class_<OGSSimulation>(m, "OGSSimulation")
277 .def(pybind11::init<std::vector<std::string>&>())
278 .def("current_time", &OGSSimulation::currentTime,
279 "get current OGS time")
280 .def("end_time", &OGSSimulation::endTime, "get end OGS time")
281 .def("execute_simulation", &OGSSimulation::executeSimulation,
282 "execute OGS simulation")
283 .def("execute_time_step", &OGSSimulation::executeTimeStep,
284 "execute OGS time step")
285 .def("mesh", &OGSSimulation::getMesh,
286 pybind11::return_value_policy::automatic_reference,
287 pybind11::arg("name"), "get unstructured grid from ogs")
288 .def("mesh_names", &OGSSimulation::getMeshNames,
289 "get names of all meshes from ogs")
290 .def("close", &OGSSimulation::finalize, "finalize OGS simulation");
291}
CommandLineArguments parseCommandLineArguments(int argc, char *argv[], bool const exit_on_exception)
Declaration of CommandLineArgumentParser.
Definition of date helper functions.
#define OGS_FATAL(...)
Definition Error.h:26
Filename manipulation routines.
Git information.
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:36
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:30
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:48
Definition of the RunTime class.
Declaration of class Simulation.
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
std::map< std::string, OGSMesh > mesh_mapping
OGSMesh & getMesh(std::string const &name)
std::unique_ptr< Simulation > simulation
double endTime() const
OGSSimulation(std::vector< std::string > &argv_str)
double currentTime() const
std::vector< std::string > getMeshNames() const
static OGS_EXPORT_SYMBOL int runTestDefinitions(std::optional< ApplicationsLib::TestDefinition > &test_definition)
void initOGSLogger(std::string const &log_level)
Definition Logging.cpp:64
std::string formatDate(std::chrono::time_point< std::chrono::system_clock > const &time)
void unsetProjectDirectory()
Unsets the project directory.
bool createOutputDirectory(std::string const &dir)
GITINFOLIB_EXPORT const std::string ogs_version
static constexpr int EXIT_ARGPARSE_EXIT_OK
int checkCommandLineArguments(std::vector< std::string > &argv_str)
PYBIND11_MODULE(OGSSimulator, m)
static constexpr int EXIT_ARGPARSE_FAILURE
std::vector< std::string > xml_patch_file_names