OGS 6.2.0-97-g4a610c866
CreatePhaseFieldProcess.cpp
Go to the documentation of this file.
1 
11 
12 #include <cassert>
13 
16 #include "ParameterLib/Utils.h"
19 
20 #include "PhaseFieldProcess.h"
21 #include "PhaseFieldProcessData.h"
22 
23 namespace ProcessLib
24 {
25 namespace PhaseField
26 {
27 template <int DisplacementDim>
28 std::unique_ptr<Process> createPhaseFieldProcess(
29  MeshLib::Mesh& mesh,
30  std::unique_ptr<ProcessLib::AbstractJacobianAssembler>&& jacobian_assembler,
31  std::vector<ProcessVariable> const& variables,
32  std::vector<std::unique_ptr<ParameterLib::ParameterBase>> const& parameters,
33  boost::optional<ParameterLib::CoordinateSystem> const&
34  local_coordinate_system,
35  unsigned const integration_order,
36  BaseLib::ConfigTree const& config)
37 {
39  config.checkConfigParameter("type", "PHASE_FIELD");
40  DBUG("Create PhaseFieldProcess.");
41 
42  auto const staggered_scheme =
44  config.getConfigParameterOptional<std::string>("coupling_scheme");
45  const bool use_monolithic_scheme =
46  !(staggered_scheme && (*staggered_scheme == "staggered"));
47 
48  // Process variable.
49 
51  auto const pv_config = config.getConfigSubtree("process_variables");
52 
53  ProcessVariable* variable_ph;
54  ProcessVariable* variable_u;
55  std::vector<std::vector<std::reference_wrapper<ProcessVariable>>>
56  process_variables;
57  if (use_monolithic_scheme) // monolithic scheme.
58  {
59  OGS_FATAL("Monolithic implementation is not available.");
60  }
61  else // staggered scheme.
62  {
63  using namespace std::string_literals;
64  for (
65  auto const& variable_name :
66  {
67  "displacement"s,
69  "phasefield"s})
70  {
71  auto per_process_variables =
72  findProcessVariables(variables, pv_config, {variable_name});
73  process_variables.push_back(std::move(per_process_variables));
74  }
75  variable_u = &process_variables[0][0].get();
76  variable_ph = &process_variables[1][0].get();
77  }
78 
79  DBUG("Associate displacement with process variable '%s'.",
80  variable_u->getName().c_str());
81 
82  if (variable_u->getNumberOfComponents() != DisplacementDim)
83  {
84  OGS_FATAL(
85  "Number of components of the process variable '%s' is different "
86  "from the displacement dimension: got %d, expected %d",
87  variable_u->getName().c_str(),
88  variable_u->getNumberOfComponents(),
89  DisplacementDim);
90  }
91 
92  DBUG("Associate phase field with process variable '%s'.",
93  variable_ph->getName().c_str());
94  if (variable_ph->getNumberOfComponents() != 1)
95  {
96  OGS_FATAL(
97  "Phasefield process variable '%s' is not a scalar variable but has "
98  "%d components.",
99  variable_ph->getName().c_str(),
100  variable_ph->getNumberOfComponents());
101  }
102 
103  auto solid_constitutive_relations =
104  MaterialLib::Solids::createConstitutiveRelations<DisplacementDim>(
105  parameters, local_coordinate_system, config);
106 
107  auto const phasefield_parameters_config =
109  config.getConfigSubtree("phasefield_parameters");
110 
111  // Residual stiffness
112  auto& residual_stiffness = ParameterLib::findParameter<double>(
113  phasefield_parameters_config,
115  "residual_stiffness", parameters, 1);
116  DBUG("Use '%s' as residual stiffness.", residual_stiffness.name.c_str());
117 
118  // Crack resistance
119  auto& crack_resistance = ParameterLib::findParameter<double>(
120  phasefield_parameters_config,
122  "crack_resistance", parameters, 1);
123  DBUG("Use '%s' as crack resistance.", crack_resistance.name.c_str());
124 
125  // Crack length scale
126  auto& crack_length_scale = ParameterLib::findParameter<double>(
127  phasefield_parameters_config,
129  "crack_length_scale", parameters, 1);
130  DBUG("Use '%s' as crack length scale.", crack_length_scale.name.c_str());
131 
132  // Kinetic coefficient
133  auto& kinetic_coefficient = ParameterLib::findParameter<double>(
134  phasefield_parameters_config,
136  "kinetic_coefficient", parameters, 1);
137  DBUG("Use '%s' as kinetic coefficient.", kinetic_coefficient.name.c_str());
138 
139  // Solid density
140  auto& solid_density = ParameterLib::findParameter<double>(
141  config,
143  "solid_density", parameters, 1);
144  DBUG("Use '%s' as solid density parameter.", solid_density.name.c_str());
145 
146  // History field
147  auto& history_field = ParameterLib::findParameter<double>(
148  phasefield_parameters_config,
150  "history_field", parameters, 1);
151  DBUG("Use '%s' as history field.", history_field.name.c_str());
152 
153  // Specific body force
154  Eigen::Matrix<double, DisplacementDim, 1> specific_body_force;
155  {
156  std::vector<double> const b =
158  config.getConfigParameter<std::vector<double>>(
159  "specific_body_force");
160  if (b.size() != DisplacementDim)
161  {
162  OGS_FATAL(
163  "The size of the specific body force vector does not match the "
164  "displacement dimension. Vector size is %d, displacement "
165  "dimension is %d",
166  b.size(), DisplacementDim);
167  }
168 
169  std::copy_n(b.data(), b.size(), specific_body_force.data());
170  }
171 
172  auto const crack_scheme =
174  config.getConfigParameterOptional<std::string>("hydro_crack_scheme");
175  if (crack_scheme &&
176  ((*crack_scheme != "propagating") && (*crack_scheme != "static")))
177  {
178  OGS_FATAL(
179  "hydro_crack_scheme must be 'propagating' or 'static' but "
180  "'%s' was given",
181  crack_scheme->c_str());
182  }
183 
184  const bool propagating_crack =
185  (crack_scheme && (*crack_scheme == "propagating"));
186  const bool crack_pressure =
187  (crack_scheme &&
188  ((*crack_scheme == "propagating") || (*crack_scheme == "static")));
189 
191  materialIDs(mesh), std::move(solid_constitutive_relations),
192  residual_stiffness, crack_resistance,
193  crack_length_scale, kinetic_coefficient,
194  solid_density, history_field,
195  specific_body_force, propagating_crack,
196  crack_pressure};
197 
198  SecondaryVariableCollection secondary_variables;
199 
200  NumLib::NamedFunctionCaller named_function_caller(
201  {"PhaseField_displacement"});
202 
203  ProcessLib::createSecondaryVariables(config, secondary_variables,
204  named_function_caller);
205 
206  return std::make_unique<PhaseFieldProcess<DisplacementDim>>(
207  mesh, std::move(jacobian_assembler), parameters, integration_order,
208  std::move(process_variables), std::move(process_data),
209  std::move(secondary_variables), std::move(named_function_caller),
210  use_monolithic_scheme);
211 }
212 
213 template std::unique_ptr<Process> createPhaseFieldProcess<2>(
214  MeshLib::Mesh& mesh,
215  std::unique_ptr<ProcessLib::AbstractJacobianAssembler>&& jacobian_assembler,
216  std::vector<ProcessVariable> const& variables,
217  std::vector<std::unique_ptr<ParameterLib::ParameterBase>> const& parameters,
218  boost::optional<ParameterLib::CoordinateSystem> const&
219  local_coordinate_system,
220  unsigned const integration_order,
221  BaseLib::ConfigTree const& config);
222 
223 template std::unique_ptr<Process> createPhaseFieldProcess<3>(
224  MeshLib::Mesh& mesh,
225  std::unique_ptr<ProcessLib::AbstractJacobianAssembler>&& jacobian_assembler,
226  std::vector<ProcessVariable> const& variables,
227  std::vector<std::unique_ptr<ParameterLib::ParameterBase>> const& parameters,
228  boost::optional<ParameterLib::CoordinateSystem> const&
229  local_coordinate_system,
230  unsigned const integration_order,
231  BaseLib::ConfigTree const& config);
232 
233 } // namespace PhaseField
234 } // namespace ProcessLib
std::unique_ptr< Process > createPhaseFieldProcess(MeshLib::Mesh &mesh, std::unique_ptr< ProcessLib::AbstractJacobianAssembler > &&jacobian_assembler, std::vector< ProcessVariable > const &variables, std::vector< std::unique_ptr< ParameterLib::ParameterBase >> const &parameters, boost::optional< ParameterLib::CoordinateSystem > const &local_coordinate_system, unsigned const integration_order, BaseLib::ConfigTree const &config)
void createSecondaryVariables(BaseLib::ConfigTree const &config, SecondaryVariableCollection &secondary_variables, NumLib::NamedFunctionCaller &named_function_caller)
T getConfigParameter(std::string const &param) const
std::vector< std::reference_wrapper< ProcessVariable > > findProcessVariables(std::vector< ProcessVariable > const &variables, BaseLib::ConfigTree const &pv_config, std::initializer_list< std::string > tags)
template std::unique_ptr< Process > createPhaseFieldProcess< 2 >(MeshLib::Mesh &mesh, std::unique_ptr< ProcessLib::AbstractJacobianAssembler > &&jacobian_assembler, std::vector< ProcessVariable > const &variables, std::vector< std::unique_ptr< ParameterLib::ParameterBase >> const &parameters, boost::optional< ParameterLib::CoordinateSystem > const &local_coordinate_system, unsigned const integration_order, BaseLib::ConfigTree const &config)
template std::unique_ptr< Process > createPhaseFieldProcess< 3 >(MeshLib::Mesh &mesh, std::unique_ptr< ProcessLib::AbstractJacobianAssembler > &&jacobian_assembler, std::vector< ProcessVariable > const &variables, std::vector< std::unique_ptr< ParameterLib::ParameterBase >> const &parameters, boost::optional< ParameterLib::CoordinateSystem > const &local_coordinate_system, unsigned const integration_order, BaseLib::ConfigTree const &config)
Builds expression trees of named functions dynamically at runtime.
void checkConfigParameter(std::string const &param, T const &value) const
std::string const & getName() const
int getNumberOfComponents() const
Returns the number of components of the process variable.
PropertyVector< int > const * materialIDs(Mesh const &mesh)
Definition: Mesh.cpp:403
ConfigTree getConfigSubtree(std::string const &root) const
Definition: ConfigTree.cpp:150
Handles configuration of several secondary variables from the project file.
boost::optional< T > getConfigParameterOptional(std::string const &param) const
#define OGS_FATAL(fmt,...)
Definition: Error.h:63