OGS
CreateTimeLoop.cpp
Go to the documentation of this file.
1
11#include "CreateTimeLoop.h"
12
13#include <algorithm>
14#include <range/v3/algorithm/any_of.hpp>
15#include <string>
16
17#include "BaseLib/ConfigTree.h"
24#include "TimeLoop.h"
25
26namespace ProcessLib
27{
28std::unique_ptr<TimeLoop> createTimeLoop(
29 BaseLib::ConfigTree const& config, std::string const& output_directory,
30 const std::vector<std::unique_ptr<Process>>& processes,
31 const std::map<std::string, std::unique_ptr<NumLib::NonlinearSolverBase>>&
32 nonlinear_solvers,
33 std::vector<std::unique_ptr<MeshLib::Mesh>>& meshes,
34 bool const compensate_non_equilibrium_initial_residuum)
35{
37 auto output_config_tree = config.getConfigSubtreeOptional("output");
38 if (!output_config_tree)
39 {
40 INFO("No output section found.");
41 }
42 auto outputs =
43 output_config_tree
44 ? createOutput(*output_config_tree, output_directory, meshes)
46 : createOutputs(config.getConfigSubtree("outputs"),
47 output_directory, meshes);
48 auto const fixed_times_for_output =
50
51 if (auto const submesh_residuum_output_config_tree =
53 config.getConfigSubtreeOptional("submesh_residuum_output");
54 submesh_residuum_output_config_tree)
55 {
57 *submesh_residuum_output_config_tree, output_directory, meshes);
58
59 for (auto& process : processes)
60 {
61 auto const& residuum_vector_names =
62 process->initializeAssemblyOnSubmeshes(smroc.meshes);
63
64 for (auto const& name : residuum_vector_names)
65 {
66 smroc.output.doNotProjectFromBulkMeshToSubmeshes(
68 }
69 }
70
71 outputs.push_back(std::move(smroc.output));
72 }
73 else
74 {
75 // Submesh assembly must always be initialized.
76 for (auto& process : processes)
77 {
78 process->initializeAssemblyOnSubmeshes({});
79 }
80 }
81
82 auto per_process_data = createPerProcessData(
84 config.getConfigSubtree("processes"), processes, nonlinear_solvers,
85 compensate_non_equilibrium_initial_residuum, fixed_times_for_output);
86
87 const bool use_staggered_scheme =
88 ranges::any_of(processes.begin(), processes.end(),
89 [](auto const& process)
90 { return !(process->isMonolithicSchemeUsed()); });
91
92 std::unique_ptr<NumLib::StaggeredCoupling> staggered_coupling = nullptr;
93 if (use_staggered_scheme)
94 {
95 staggered_coupling = NumLib::createStaggeredCoupling<ProcessData>(
96 config, per_process_data);
97 }
98 else
99 {
100 if (per_process_data.size() > 1)
101 {
102 OGS_FATAL(
103 "The monolithic scheme is used. However more than one "
104 "process data tags (by name \"process\") inside tag "
105 "\"time_loop\" are defined for the staggered scheme. If you "
106 "want to use staggered scheme, please set the element of tag "
107 "\"<coupling_scheme>\" to \"staggered\".");
108 }
109 }
110
111 const auto minmax_iter =
112 std::minmax_element(per_process_data.begin(),
113 per_process_data.end(),
114 [](std::unique_ptr<ProcessData> const& a,
115 std::unique_ptr<ProcessData> const& b) {
116 return (a->timestep_algorithm->end() <
117 b->timestep_algorithm->end());
118 });
119 const double start_time =
120 per_process_data[minmax_iter.first - per_process_data.begin()]
121 ->timestep_algorithm->begin();
122 const double end_time =
123 per_process_data[minmax_iter.second - per_process_data.begin()]
124 ->timestep_algorithm->end();
125
126 return std::make_unique<TimeLoop>(
127 std::move(outputs), std::move(per_process_data),
128 std::move(staggered_coupling), start_time, end_time);
129}
130} // namespace ProcessLib
#define OGS_FATAL(...)
Definition Error.h:26
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:35
std::optional< ConfigTree > getConfigSubtreeOptional(std::string const &root) const
ConfigTree getConfigSubtree(std::string const &root) const
SubmeshResiduumOutputConfig createSubmeshResiduumOutputConfig(BaseLib::ConfigTree const &config, std::string const &output_directory, std::vector< std::unique_ptr< MeshLib::Mesh > > &meshes)
std::vector< std::unique_ptr< ProcessData > > createPerProcessData(BaseLib::ConfigTree const &config, std::vector< std::unique_ptr< Process > > const &processes, std::map< std::string, std::unique_ptr< NumLib::NonlinearSolverBase > > const &nonlinear_solvers, bool const compensate_non_equilibrium_initial_residuum, std::vector< double > const &fixed_times_for_output)
Output createOutput(OutputConfig &&oc, std::string const &output_directory, std::vector< std::unique_ptr< MeshLib::Mesh > > const &meshes)
std::unique_ptr< TimeLoop > createTimeLoop(BaseLib::ConfigTree const &config, std::string const &output_directory, const std::vector< std::unique_ptr< Process > > &processes, const std::map< std::string, std::unique_ptr< NumLib::NonlinearSolverBase > > &nonlinear_solvers, std::vector< std::unique_ptr< MeshLib::Mesh > > &meshes, bool const compensate_non_equilibrium_initial_residuum)
Builds a TimeLoop from the given configuration.
std::vector< double > calculateUniqueFixedTimesForAllOutputs(std::vector< Output > const &outputs)
Definition Output.cpp:432
std::vector< Output > createOutputs(const BaseLib::ConfigTree &output_configs, std::string const &output_directory, std::vector< std::unique_ptr< MeshLib::Mesh > > &meshes)