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