Loading [MathJax]/extensions/tex2jax.js
OGS
CreateTH2MProcess.cpp
Go to the documentation of this file.
1 
11 #include "CreateTH2MProcess.h"
12 
13 #include <cassert>
14 
17 #include "MaterialLib/MPL/Medium.h"
20 #include "ParameterLib/Utils.h"
23 #include "TH2MProcess.h"
24 #include "TH2MProcessData.h"
25 
26 namespace ProcessLib
27 {
28 namespace TH2M
29 {
30 std::unique_ptr<PhaseTransitionModel> createPhaseTransitionModel(
31  std::map<int, std::shared_ptr<MaterialPropertyLib::Medium>> const& media)
32 {
33  // the approach here is that the number of phase components determines the
34  // nature of the phase transition: If the gas phase consists of two or more
35  // components, evaporation is involved; if the water phase consists of at
36  // least two components, gas can be dissolved in water.
37 
38  // Fluid phases are always defined in the first medium of the media vector,
39  // thus media.begin() points to the right medium.
40  const bool evaporation =
41  media.begin()->second->phase("Gas").numberOfComponents() > 1;
42 
43  const bool dissolution =
44  media.begin()->second->phase("AqueousLiquid").numberOfComponents() > 1;
45 
46  if (evaporation && dissolution)
47  {
48  return std::make_unique<PhaseTransitionFull>(media);
49  }
50 
51  if (evaporation && !dissolution)
52  {
53  return std::make_unique<PhaseTransitionEvaporation>(media);
54  }
55 
56  if (!evaporation && dissolution)
57  {
58  return std::make_unique<PhaseTransitionDissolution>(media);
59  }
60 
61  return std::make_unique<PhaseTransitionNone>(media);
62 }
63 
64 template <int DisplacementDim>
65 std::unique_ptr<Process> createTH2MProcess(
66  std::string name, MeshLib::Mesh& mesh,
67  std::unique_ptr<ProcessLib::AbstractJacobianAssembler>&& jacobian_assembler,
68  std::vector<ProcessVariable> const& variables,
69  std::vector<std::unique_ptr<ParameterLib::ParameterBase>> const& parameters,
70  std::optional<ParameterLib::CoordinateSystem> const&
71  local_coordinate_system,
72  unsigned const integration_order, BaseLib::ConfigTree const& config,
73  std::map<int, std::shared_ptr<MaterialPropertyLib::Medium>> const& media)
74 {
76  config.checkConfigParameter("type", "TH2M");
77  DBUG("Create TH2M Process.");
78  DBUG(" ");
79  WARN("Attention! TH2M process has not yet been fully tested!");
80  WARN("Check its results critically and report any bugs to");
81  WARN(" https://gitlab.opengeosys.org/ogs/ogs/-/issues ");
82  WARN(" ");
83 
84  auto const coupling_scheme =
86  config.getConfigParameterOptional<std::string>("coupling_scheme");
87  const bool use_monolithic_scheme =
88  !(coupling_scheme && (*coupling_scheme == "staggered"));
89 
90  // Process variable.
92  auto const pv_config = config.getConfigSubtree("process_variables");
93 
94  ProcessVariable* variable_pGR;
95  ProcessVariable* variable_pCap;
96  ProcessVariable* variable_T;
97  ProcessVariable* variable_u;
98  std::vector<std::vector<std::reference_wrapper<ProcessVariable>>>
99  process_variables;
100  if (use_monolithic_scheme) // monolithic scheme.
101  {
102  auto per_process_variables = findProcessVariables(
103  variables, pv_config,
104  {
105  "gas_pressure",
107  "capillary_pressure",
109  "temperature",
111  "displacement"});
112  variable_pGR = &per_process_variables[0].get();
113  variable_pCap = &per_process_variables[1].get();
114  variable_T = &per_process_variables[2].get();
115  variable_u = &per_process_variables[3].get();
116  process_variables.push_back(std::move(per_process_variables));
117  }
118  else // staggered scheme.
119  {
120  OGS_FATAL("A Staggered version of TH2M is not implemented.");
121 
122  using namespace std::string_literals;
123  for (auto const& variable_name :
124  {"gas_pressure"s, "capillary_pressure"s, "temperature"s,
125  "displacement"s})
126  {
127  auto per_process_variables =
128  findProcessVariables(variables, pv_config, {variable_name});
129  process_variables.push_back(std::move(per_process_variables));
130  }
131  variable_pGR = &process_variables[0][0].get();
132  variable_pCap = &process_variables[1][0].get();
133  variable_T = &process_variables[2][0].get();
134  variable_u = &process_variables[3][0].get();
135  }
136 
137  DBUG("Associate displacement with process variable '{:s}'.",
138  variable_u->getName());
139 
140  if (variable_u->getNumberOfGlobalComponents() != DisplacementDim)
141  {
142  OGS_FATAL(
143  "Number of components of the process variable '{:s}' is different "
144  "from the displacement dimension: got {:d}, expected {:d}",
145  variable_u->getName(),
146  variable_u->getNumberOfGlobalComponents(),
147  DisplacementDim);
148  }
149 
150  DBUG("Associate gas pressure with process variable '{:s}'.",
151  variable_pGR->getName());
152  if (variable_pGR->getNumberOfGlobalComponents() != 1)
153  {
154  OGS_FATAL(
155  "Gas pressure process variable '{:s}' is not a scalar variable but "
156  "has "
157  "{:d} components.",
158  variable_pGR->getName(),
159  variable_pGR->getNumberOfGlobalComponents());
160  }
161 
162  DBUG("Associate capillary pressure with process variable '{:s}'.",
163  variable_pCap->getName());
164  if (variable_pCap->getNumberOfGlobalComponents() != 1)
165  {
166  OGS_FATAL(
167  "Capillary pressure process variable '{:s}' is not a scalar "
168  "variable but has "
169  "{:d} components.",
170  variable_pCap->getName(),
171  variable_pCap->getNumberOfGlobalComponents());
172  }
173 
174  DBUG("Associate temperature with process variable '{:s}'.",
175  variable_T->getName());
176  if (variable_T->getNumberOfGlobalComponents() != 1)
177  {
178  OGS_FATAL(
179  "temperature process variable '{:s}' is not a scalar variable but "
180  "has {:d} components.",
181  variable_T->getName(),
182  variable_T->getNumberOfGlobalComponents());
183  }
184 
185  auto solid_constitutive_relations =
186  MaterialLib::Solids::createConstitutiveRelations<DisplacementDim>(
187  parameters, local_coordinate_system, config);
188 
189  // reference temperature
190  const auto& reference_temperature = ParameterLib::findParameter<double>(
191  config,
193  "reference_temperature", parameters, 1, &mesh);
194  DBUG("Use '{:s}' as reference temperature parameter.",
195  reference_temperature.name);
196 
197  // Specific body force
198  Eigen::Matrix<double, DisplacementDim, 1> specific_body_force;
199  {
200  std::vector<double> const b =
202  config.getConfigParameter<std::vector<double>>(
203  "specific_body_force");
204  if (b.size() != DisplacementDim)
205  {
206  OGS_FATAL(
207  "The size of the specific body force vector does not match the "
208  "displacement dimension. Vector size is {:d}, displacement "
209  "dimension is {:d}",
210  b.size(), DisplacementDim);
211  }
212 
213  std::copy_n(b.data(), b.size(), specific_body_force.data());
214  }
215 
216  // Initial stress conditions
217  auto const initial_stress = ParameterLib::findOptionalTagParameter<double>(
219  config, "initial_stress", parameters,
220  // Symmetric tensor size, 4 or 6, not a Kelvin vector.
222  &mesh);
223 
224  auto const mass_lumping =
226  config.getConfigParameter<bool>("mass_lumping", false);
227 
228  auto media_map =
230 
231  auto phase_transition_model = createPhaseTransitionModel(media);
233  materialIDs(mesh),
234  std::move(media_map),
235  std::move(solid_constitutive_relations),
236  std::move(phase_transition_model),
238  initial_stress,
239  specific_body_force,
240  mass_lumping};
241 
242  SecondaryVariableCollection secondary_variables;
243 
244  ProcessLib::createSecondaryVariables(config, secondary_variables);
245 
246  return std::make_unique<TH2MProcess<DisplacementDim>>(
247  std::move(name), mesh, std::move(jacobian_assembler), parameters,
248  integration_order, std::move(process_variables),
249  std::move(process_data), std::move(secondary_variables),
250  use_monolithic_scheme);
251 }
252 
253 template std::unique_ptr<Process> createTH2MProcess<2>(
254  std::string name,
255  MeshLib::Mesh& mesh,
256  std::unique_ptr<ProcessLib::AbstractJacobianAssembler>&& jacobian_assembler,
257  std::vector<ProcessVariable> const& variables,
258  std::vector<std::unique_ptr<ParameterLib::ParameterBase>> const& parameters,
259  std::optional<ParameterLib::CoordinateSystem> const&
260  local_coordinate_system,
261  unsigned const integration_order,
262  BaseLib::ConfigTree const& config,
263  std::map<int, std::shared_ptr<MaterialPropertyLib::Medium>> const& media);
264 
265 template std::unique_ptr<Process> createTH2MProcess<3>(
266  std::string name,
267  MeshLib::Mesh& mesh,
268  std::unique_ptr<ProcessLib::AbstractJacobianAssembler>&& jacobian_assembler,
269  std::vector<ProcessVariable> const& variables,
270  std::vector<std::unique_ptr<ParameterLib::ParameterBase>> const& parameters,
271  std::optional<ParameterLib::CoordinateSystem> const&
272  local_coordinate_system,
273  unsigned const integration_order,
274  BaseLib::ConfigTree const& config,
275  std::map<int, std::shared_ptr<MaterialPropertyLib::Medium>> const& media);
276 } // namespace TH2M
277 } // namespace ProcessLib
#define OGS_FATAL(...)
Definition: Error.h:26
void DBUG(char const *fmt, Args const &... args)
Definition: Logging.h:27
void WARN(char const *fmt, Args const &... args)
Definition: Logging.h:37
void checkConfigParameter(std::string const &param, T const &value) const
std::optional< T > getConfigParameterOptional(std::string const &param) const
T getConfigParameter(std::string const &param) const
ConfigTree getConfigSubtree(std::string const &root) const
Definition: ConfigTree.cpp:146
std::string const & getName() const
int getNumberOfGlobalComponents() const
Returns the number of components of the process variable.
Handles configuration of several secondary variables from the project file.
std::unique_ptr< MaterialSpatialDistributionMap > createMaterialSpatialDistributionMap(std::map< int, std::shared_ptr< Medium >> const &media, MeshLib::Mesh const &mesh)
constexpr int kelvin_vector_dimensions(int const displacement_dim)
Kelvin vector dimensions for given displacement dimension.
Definition: KelvinVector.h:23
PropertyVector< int > const * materialIDs(Mesh const &mesh)
Definition: Mesh.cpp:258
std::unique_ptr< PhaseTransitionModel > createPhaseTransitionModel(std::map< int, std::shared_ptr< MaterialPropertyLib::Medium >> const &media)
template std::unique_ptr< Process > createTH2MProcess< 3 >(std::string name, MeshLib::Mesh &mesh, std::unique_ptr< ProcessLib::AbstractJacobianAssembler > &&jacobian_assembler, std::vector< ProcessVariable > const &variables, std::vector< std::unique_ptr< ParameterLib::ParameterBase >> const &parameters, std::optional< ParameterLib::CoordinateSystem > const &local_coordinate_system, unsigned const integration_order, BaseLib::ConfigTree const &config, std::map< int, std::shared_ptr< MaterialPropertyLib::Medium >> const &media)
template std::unique_ptr< Process > createTH2MProcess< 2 >(std::string name, MeshLib::Mesh &mesh, std::unique_ptr< ProcessLib::AbstractJacobianAssembler > &&jacobian_assembler, std::vector< ProcessVariable > const &variables, std::vector< std::unique_ptr< ParameterLib::ParameterBase >> const &parameters, std::optional< ParameterLib::CoordinateSystem > const &local_coordinate_system, unsigned const integration_order, BaseLib::ConfigTree const &config, std::map< int, std::shared_ptr< MaterialPropertyLib::Medium >> const &media)
std::unique_ptr< Process > createTH2MProcess(std::string name, MeshLib::Mesh &mesh, std::unique_ptr< ProcessLib::AbstractJacobianAssembler > &&jacobian_assembler, std::vector< ProcessVariable > const &variables, std::vector< std::unique_ptr< ParameterLib::ParameterBase >> const &parameters, std::optional< ParameterLib::CoordinateSystem > const &local_coordinate_system, unsigned const integration_order, BaseLib::ConfigTree const &config, std::map< int, std::shared_ptr< MaterialPropertyLib::Medium >> const &media)
std::vector< std::reference_wrapper< ProcessVariable > > findProcessVariables(std::vector< ProcessVariable > const &variables, BaseLib::ConfigTree const &pv_config, std::initializer_list< std::string > tags)
void createSecondaryVariables(BaseLib::ConfigTree const &config, SecondaryVariableCollection &secondary_variables)