4#ifndef user_constants_h
5#define user_constants_h
7#include <deal.II/base/tensor.h>
8#include <deal.II/base/utilities.h>
10#include <boost/algorithm/string/predicate.hpp>
11#include <boost/range/algorithm_ext/erase.hpp>
12#include <boost/variant.hpp>
14#include <prismspf/config.h>
15#include <prismspf/core/conditional_ostreams.h>
16#include <prismspf/core/exceptions.h>
17#include <prismspf/core/type_enums.h>
22PRISMS_PF_BEGIN_NAMESPACE
31 using InputVariant = boost::variant<double,
34 dealii::Tensor<1, dim>,
35 dealii::Tensor<2, dim>,
36 dealii::Tensor<2, (2 * dim) - 1 + (dim / 3)>>;
77 [[nodiscard]] dealii::Tensor<1, dim>
86 [[nodiscard]] dealii::Tensor<2, dim>
95 [[nodiscard]] dealii::Tensor<2, (2 * dim) - 1 + (dim / 3)>
99 std::map<std::string, InputVariant> model_constants;
106 compute_tensor_parentheses(
const unsigned int &n_elements,
107 const std::vector<std::string> &tensor_elements);
113 remove_parentheses(std::vector<std::string> &tensor_elements);
118 dealii::Tensor<1, dim>
119 compute_rank_1_tensor_constant(
const unsigned int &n_elements,
120 const std::vector<std::string> &tensor_elements);
125 dealii::Tensor<2, dim>
126 compute_rank_2_tensor_constant(
const unsigned int &n_elements,
127 const std::vector<std::string> &tensor_elements);
133 primitive_model_constant(std::vector<std::string> &model_constants_strings);
135 [[nodiscard]] dealii::Tensor<2, (2 * dim) - 1 + (dim / 3)>
136 get_Cij_tensor(std::vector<double> elastic_constants,
137 const std::string &elastic_const_symmetry)
const;
139 dealii::Tensor<2, (2 * dim) - 1 + (dim / 3)>
140 getCIJMatrix(
const elasticityModel &model,
const std::vector<double> &constants)
const;
147 Assert(model_constants.find(constant_name) != model_constants.end(),
149 "Mismatch between constants in parameters.prm and customPDE.h. The constant "
150 "that you attempted to access was " +
151 constant_name +
"."));
153 return boost::get<double>(model_constants.at(constant_name));
160 Assert(model_constants.find(constant_name) != model_constants.end(),
162 "Mismatch between constants in parameters.prm and customPDE.h. The constant "
163 "that you attempted to access was " +
164 constant_name +
"."));
166 return boost::get<int>(model_constants.at(constant_name));
173 Assert(model_constants.find(constant_name) != model_constants.end(),
175 "Mismatch between constants in parameters.prm and customPDE.h. The constant "
176 "that you attempted to access was " +
177 constant_name +
"."));
179 return boost::get<bool>(model_constants.at(constant_name));
183inline dealii::Tensor<1, dim>
185 const std::string &constant_name)
const
187 Assert(model_constants.find(constant_name) != model_constants.end(),
189 " Mismatch between constants in parameters.prm and "
190 "customPDE.h. The constant that you attempted to access was " +
191 constant_name +
"."));
193 return boost::get<dealii::Tensor<1, dim>>(model_constants.at(constant_name));
197inline dealii::Tensor<2, dim>
199 const std::string &constant_name)
const
201 Assert(model_constants.find(constant_name) != model_constants.end(),
203 "Mismatch between constants in parameters.prm and customPDE.h. The constant "
204 "that you attempted to access was " +
205 constant_name +
"."));
207 return boost::get<dealii::Tensor<2, dim>>(model_constants.at(constant_name));
211inline dealii::Tensor<2, (2 * dim) - 1 + (dim / 3)>
213 const std::string &constant_name)
const
215 Assert(model_constants.find(constant_name) != model_constants.end(),
217 "Mismatch between constants in parameters.prm and customPDE.h. The constant "
218 "that you attempted to access was " +
219 constant_name +
"."));
221 return boost::get<dealii::Tensor<2, (2 * dim) - 1 + (dim / 3)>>(
222 model_constants.at(constant_name));
228 const unsigned int &n_elements,
229 const std::vector<std::string> &tensor_elements)
231 unsigned int open_parentheses = 0;
232 unsigned int close_parentheses = 0;
234 for (
unsigned int element = 0; element < n_elements; element++)
236 for (
const char character : tensor_elements.at(element))
238 if (character ==
'(')
242 else if (character ==
')')
249 if (open_parentheses != close_parentheses)
252 dealii::ExcMessage(
"User-defined elastic constant list does not have "
253 "the same number of open and close parentheses."));
256 return open_parentheses;
263 for (std::string &element : tensor_elements)
265 boost::range::remove_erase(element,
'(');
266 boost::range::remove_erase(element,
'(');
271inline dealii::Tensor<1, dim>
273 const unsigned int &n_elements,
274 const std::vector<std::string> &tensor_elements)
276 AssertThrow(n_elements == dim,
277 dealii::ExcMessage(
"The columns in user-defined constant tensors must be "
278 "equal to the number of dimensions."));
280 dealii::Tensor<1, dim> temp;
281 for (
unsigned int i = 0; i < dim; i++)
283 temp[i] = dealii::Utilities::string_to_double(tensor_elements.at(i));
290inline dealii::Tensor<2, dim>
292 const unsigned int &n_elements,
293 const std::vector<std::string> &tensor_elements)
295 AssertThrow(n_elements == (dim * dim),
297 "User-defined constant tensor does not have the "
298 "correct number of elements, matrices must be 2x2 or 3x3."));
300 const unsigned int row_length = dim;
302 dealii::Tensor<2, dim> temp;
303 for (
unsigned int i = 0; i < dim; i++)
305 for (
unsigned int j = 0; j < dim; j++)
308 dealii::Utilities::string_to_double(tensor_elements.at((i * row_length) + j));
316inline typename userConstants<dim>::InputVariant
318 std::vector<std::string> &model_constants_strings)
322 model_constants_strings.size() > 1,
324 "At least two fields are required for user-defined variables (value and type)."));
326 std::vector<std::string> model_constants_type_strings =
327 dealii::Utilities::split_string_list(model_constants_strings.at(
328 model_constants_strings.size() - 1),
331 if (model_constants_strings.size() == 2)
333 return primitive_model_constant(model_constants_strings);
336 if (boost::iequals(model_constants_type_strings.at(0),
"tensor"))
338 const unsigned int n_elements = model_constants_strings.size() - 1;
340 const unsigned int open_parentheses =
341 compute_tensor_parentheses(n_elements, model_constants_strings);
343 AssertThrow(open_parentheses < 4,
344 FeatureNotImplemented(
"3rd rank tensors and above"));
346 remove_parentheses(model_constants_strings);
349 if (open_parentheses == 1)
351 return compute_rank_1_tensor_constant(n_elements, model_constants_strings);
354 return compute_rank_2_tensor_constant(n_elements, model_constants_strings);
356 if (boost::iequals(model_constants_type_strings.at(1),
"elastic") &&
357 boost::iequals(model_constants_type_strings.at(2),
"constants"))
359 const unsigned int n_elements = model_constants_strings.size() - 1;
361 remove_parentheses(model_constants_strings);
364 std::vector<double> temp_elastic_constants;
365 for (
unsigned int i = 0; i < n_elements; i++)
367 temp_elastic_constants.push_back(
368 dealii::Utilities::string_to_double(model_constants_strings.at(i)));
371 const std::string &elastic_const_symmetry = model_constants_type_strings.at(0);
372 dealii::Tensor<2, (2 * dim) - 1 + (dim / 3)> temp =
373 get_Cij_tensor(temp_elastic_constants, elastic_const_symmetry);
379 "Only user-defined constant tensors may have multiple elements."));
384inline typename userConstants<dim>::InputVariant
386 std::vector<std::string> &model_constants_strings)
388 std::vector<std::string> model_constants_type_strings =
389 dealii::Utilities::split_string_list(model_constants_strings.at(
390 model_constants_strings.size() - 1),
393 if (boost::iequals(model_constants_type_strings.at(0),
"double"))
395 return dealii::Utilities::string_to_double(model_constants_strings.at(0));
397 if (boost::iequals(model_constants_type_strings.at(0),
"int"))
399 return dealii::Utilities::string_to_int(model_constants_strings.at(0));
401 if (boost::iequals(model_constants_type_strings.at(0),
"bool"))
403 return boost::iequals(model_constants_strings.at(0),
"true");
408 "The type for user-defined variables must be `double`, `int`, "
409 "`bool`, `tensor`, or `elastic constants`."));
414inline dealii::Tensor<2, (2 * dim) - 1 + (dim / 3)>
416 const std::string &elastic_const_symmetry)
const
419 elasticityModel mat_model = ISOTROPIC;
420 if (elastic_const_symmetry ==
"isotropic")
422 mat_model = elasticityModel::ISOTROPIC;
424 else if (elastic_const_symmetry ==
"transverse")
426 mat_model = elasticityModel::TRANSVERSE;
428 else if (elastic_const_symmetry ==
"orthotropic")
430 mat_model = elasticityModel::ORTHOTROPIC;
432 else if (elastic_const_symmetry ==
"anisotropic")
434 mat_model = elasticityModel::ANISOTROPIC;
438 AssertThrow(
false, dealii::ExcMessage(
"Invalid elasticity tensor type"));
444 constexpr unsigned int max_number = 21;
445 if ((mat_model == ANISOTROPIC) && (dim == 2) && elastic_constants.size() == max_number)
447 std::vector<double> elastic_constants_temp = elastic_constants;
448 elastic_constants.clear();
449 const std::vector<unsigned int> indices_2D = {0, 1, 5, 6, 10, 14};
450 for (
const auto &index : indices_2D)
452 elastic_constants.push_back(elastic_constants_temp.at(index));
456 return getCIJMatrix(mat_model, elastic_constants);
460inline dealii::Tensor<2, (2 * dim) - 1 + (dim / 3)>
462 const std::vector<double> &constants)
const
464 dealii::Tensor<2, (2 * dim) - 1 + (dim / 3)> CIJ;
480 AssertThrow(
false, dealii::ExcMessage(
"Invalid elasticity model type"));
493 AssertThrow(
false, dealii::ExcMessage(
"Invalid elasticity model type"));
508 AssertThrow(
false, dealii::ExcMessage(
"Invalid elasticity model type"));
515 Assert(
false, UnreachableCode());
522PRISMS_PF_END_NAMESPACE
Class the stores and manages user-defined constants.
Definition user_constants.h:29
int get_model_constant_int(const std::string &constant_name) const
Retrieve the int from the model_constants that are defined from the parameters.prm parser....
Definition user_constants.h:158
dealii::Tensor< 1, dim > get_model_constant_rank_1_tensor(const std::string &constant_name) const
Retrieve the rank 1 tensor from the model_constants that are defined from the parameters....
Definition user_constants.h:184
dealii::Tensor< 2, dim > get_model_constant_rank_2_tensor(const std::string &constant_name) const
Retrieve the rank 2 tensor from the model_constants that are defined from the parameters....
Definition user_constants.h:198
InputVariant construct_user_constant(std::vector< std::string > &model_constants_strings)
Assign the specified user constant to whatever type.
Definition user_constants.h:317
bool get_model_constant_bool(const std::string &constant_name) const
Retrieve the bool from the model_constants that are defined from the parameters.prm parser....
Definition user_constants.h:171
double get_model_constant_double(const std::string &constant_name) const
Retrieve the double from the model_constants that are defined from the parameters....
Definition user_constants.h:145
dealii::Tensor< 2,(2 *dim) - 1+(dim/3)> get_model_constant_elasticity_tensor(const std::string &constant_name) const
Retrieve the elasticity tensor from the model_constants that are defined from the parameters....
Definition user_constants.h:212