OGS
CreateProcessData.cpp
Go to the documentation of this file.
1
11#include <range/v3/algorithm/contains.hpp>
12
13#include "BaseLib/Algorithm.h"
14#include "BaseLib/ConfigTree.h"
16#ifdef USE_PETSC
18#endif // USE_PETSC
19#include "CreateProcessData.h"
21
22namespace ProcessLib
23{
24static std::unique_ptr<ProcessData> makeProcessData(
25 std::unique_ptr<NumLib::TimeStepAlgorithm>&& timestepper,
26 NumLib::NonlinearSolverBase& nonlinear_solver, int const process_id,
27 std::string process_name, Process& process,
28 std::unique_ptr<NumLib::TimeDiscretization>&& time_disc,
29 std::unique_ptr<NumLib::ConvergenceCriterion>&& conv_crit,
30 bool const compensate_non_equilibrium_initial_residuum)
31{
33
34 if (auto* nonlinear_solver_picard =
36 &nonlinear_solver))
37 {
38 nonlinear_solver_picard->compensateNonEquilibriumInitialResiduum(
39 compensate_non_equilibrium_initial_residuum);
40 return std::make_unique<ProcessData>(
41 std::move(timestepper), Tag::Picard, *nonlinear_solver_picard,
42 std::move(conv_crit), std::move(time_disc), process_id,
43 std::move(process_name), process);
44 }
45 if (auto* nonlinear_solver_newton =
47 &nonlinear_solver))
48 {
49 nonlinear_solver_newton->compensateNonEquilibriumInitialResiduum(
50 compensate_non_equilibrium_initial_residuum);
51 return std::make_unique<ProcessData>(
52 std::move(timestepper), Tag::Newton, *nonlinear_solver_newton,
53 std::move(conv_crit), std::move(time_disc), process_id,
54 std::move(process_name), process);
55 }
56#ifdef USE_PETSC
57 if (auto* nonlinear_solver_petsc =
58 dynamic_cast<NumLib::PETScNonlinearSolver*>(&nonlinear_solver))
59 {
60 return std::make_unique<ProcessData>(
61 std::move(timestepper), Tag::Newton, *nonlinear_solver_petsc,
62 std::move(conv_crit), std::move(time_disc), process_id,
63 std::move(process_name), process);
64 }
65#endif // USE_PETSC
66
67 OGS_FATAL("Encountered unknown nonlinear solver type. Aborting");
68}
69
70std::vector<std::unique_ptr<ProcessData>> createPerProcessData(
71 BaseLib::ConfigTree const& config,
72 std::vector<std::unique_ptr<Process>> const& processes,
73 std::map<std::string, std::unique_ptr<NumLib::NonlinearSolverBase>> const&
74 nonlinear_solvers,
75 bool const compensate_non_equilibrium_initial_residuum,
76 std::vector<double> const& fixed_times_for_output)
77{
78 std::vector<std::unique_ptr<ProcessData>> per_process_data;
79 std::vector<std::string> process_names;
80 int process_id = 0;
81
83 for (auto pcs_config : config.getConfigSubtreeList("process"))
84 {
86 auto const pcs_name = pcs_config.getConfigAttribute<std::string>("ref");
87 auto& pcs = *BaseLib::getIfOrError(
88 processes,
89 [&pcs_name](std::unique_ptr<Process> const& p)
90 { return p->name == pcs_name; },
91 "A process with the given name has not been defined.");
92
93 auto const process_name =
95 pcs_config.getConfigParameter<std::string>("process_name", "");
96 if (process_name != "")
97 {
98 if (ranges::contains(process_names, process_name))
99 {
100 OGS_FATAL(
101 "The given process name is not unique! Please check the "
102 "element "
103 "'time_loop/process/name' in the project file. Found "
104 "duplicate "
105 "process name '{:s}'.",
106 process_name);
107 }
108 process_names.emplace_back(process_name);
109 }
110
111 auto const nl_slv_name =
113 pcs_config.getConfigParameter<std::string>("nonlinear_solver");
114 auto& nl_slv = *BaseLib::getOrError(
115 nonlinear_solvers, nl_slv_name,
116 "A nonlinear solver with the given name has not been defined.");
117
118 auto time_disc = NumLib::createTimeDiscretization(
120 pcs_config.getConfigSubtree("time_discretization"));
121
122 auto timestepper = NumLib::createTimeStepper(
124 pcs_config.getConfigSubtree("time_stepping"),
125 fixed_times_for_output);
126
127 auto conv_crit = NumLib::createConvergenceCriterion(
129 pcs_config.getConfigSubtree("convergence_criterion"));
130
132 auto output = pcs_config.getConfigSubtreeOptional("output");
133 if (output)
134 {
135 OGS_FATAL(
136 "In order to make the specification of output in the project "
137 "file consistent, the variables output tags were moved from "
138 "xpath "
139 "'//OpenGeoSysProject/time_loop/processes/process/output' to "
140 "the global output section, i.e., to the xpath "
141 "'//OpenGeoSysProject/time_loop/output'. This has to be done "
142 "in the current project file!");
143 }
144
145 per_process_data.emplace_back(makeProcessData(
146 std::move(timestepper), nl_slv, process_id, std::move(process_name),
147 pcs, std::move(time_disc), std::move(conv_crit),
148 compensate_non_equilibrium_initial_residuum));
149 ++process_id;
150 }
151
152 if (per_process_data.size() != processes.size())
153 {
154 if (processes.size() > 1)
155 {
156 OGS_FATAL(
157 "Some processes have not been configured to be solved by this "
158 "time loop.");
159 }
160 else
161 {
162 INFO(
163 "The equations of the coupled processes will be solved by the "
164 "staggered scheme.");
165 }
166 }
167
168 return per_process_data;
169}
170} // namespace ProcessLib
#define OGS_FATAL(...)
Definition Error.h:26
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:35
Range< SubtreeIterator > getConfigSubtreeList(std::string const &root) const
NonlinearSolverTag
Tag used to specify which nonlinear solver will be used.
Definition Types.h:20
OGS_NO_DANGLING Container::value_type const & getIfOrError(Container const &container, Predicate &&predicate, std::string const &error_message)
Definition Algorithm.h:163
OGS_NO_DANGLING Map::mapped_type & getOrError(Map &map, Key const &key, std::string const &error_message)
Definition Algorithm.h:118
std::unique_ptr< TimeDiscretization > createTimeDiscretization(BaseLib::ConfigTree const &config)
std::unique_ptr< TimeStepAlgorithm > createTimeStepper(BaseLib::ConfigTree const &config, std::vector< double > const &fixed_times_for_output)
std::unique_ptr< ConvergenceCriterion > createConvergenceCriterion(const BaseLib::ConfigTree &config)
Creates a convergence criterion from the given configuration.
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)
static std::unique_ptr< ProcessData > makeProcessData(std::unique_ptr< NumLib::TimeStepAlgorithm > &&timestepper, NumLib::NonlinearSolverBase &nonlinear_solver, int const process_id, std::string process_name, Process &process, std::unique_ptr< NumLib::TimeDiscretization > &&time_disc, std::unique_ptr< NumLib::ConvergenceCriterion > &&conv_crit, bool const compensate_non_equilibrium_initial_residuum)