6#include <deal.II/base/tensor.h>
7#include <deal.II/base/utilities.h>
9#include <boost/algorithm/string/predicate.hpp>
10#include <boost/range/algorithm_ext/erase.hpp>
11#include <boost/variant.hpp>
17#include <prismspf/config.h>
26template <
unsigned int dim>
33 dealii::Tensor<1, dim>,
34 dealii::Tensor<2, dim>,
35 dealii::Tensor<2, (2 * dim) - 1 + (dim / 3)>>;
50 get_double(
const std::string &constant_name)
const;
59 get_int(
const std::string &constant_name)
const;
68 get_bool(
const std::string &constant_name)
const;
76 [[nodiscard]] dealii::Tensor<1, dim>
85 [[nodiscard]] dealii::Tensor<2, dim>
94 [[nodiscard]] dealii::Tensor<2, (2 * dim) - 1 + (dim / 3)>
102 std::vector<std::string> &model_constants_strings)
119 const std::vector<std::string> &tensor_elements);
130 dealii::Tensor<1, dim>
132 const std::vector<std::string> &tensor_elements);
137 dealii::Tensor<2, dim>
139 const std::vector<std::string> &tensor_elements);
147 [[nodiscard]] dealii::Tensor<2, (2 * dim) - 1 + (dim / 3)>
149 const std::string &elastic_const_symmetry)
const;
151 [[nodiscard]] dealii::Tensor<2, (2 * dim) - 1 + (dim / 3)>
153 const std::vector<double> &constants)
const;
188 for (
unsigned int i = 0; i < dim; ++i)
198 for (
unsigned int i = 0; i < dim; ++i)
200 for (
unsigned int j = 0; j < dim; ++j)
207 template <
unsigned int D = dim>
209 operator()(
const dealii::Tensor<2, (2 * D) - 1 + (D / 3)> &value)
const
210 requires((D != ((2 * D) - 1 + (D / 3))))
212 constexpr unsigned int dimension = (2 * D) - 1 + (D / 3);
214 for (
unsigned int i = 0; i < dimension; ++i)
216 for (
unsigned int j = 0; j < dimension; ++j)
225template <
unsigned int dim>
231 "Mismatch between constants in parameters.prm and CustomPDE.h. The constant "
232 "that you attempted to access was " +
233 constant_name +
"."));
238template <
unsigned int dim>
244 "Mismatch between constants in parameters.prm and CustomPDE.h. The constant "
245 "that you attempted to access was " +
246 constant_name +
"."));
251template <
unsigned int dim>
257 "Mismatch between constants in parameters.prm and CustomPDE.h. The constant "
258 "that you attempted to access was " +
259 constant_name +
"."));
264template <
unsigned int dim>
265inline dealii::Tensor<1, dim>
270 " Mismatch between constants in parameters.prm and "
271 "CustomPDE.h. The constant that you attempted to access was " +
272 constant_name +
"."));
274 return boost::get<dealii::Tensor<1, dim>>(
model_constants.at(constant_name));
277template <
unsigned int dim>
278inline dealii::Tensor<2, dim>
283 "Mismatch between constants in parameters.prm and CustomPDE.h. The constant "
284 "that you attempted to access was " +
285 constant_name +
"."));
287 return boost::get<dealii::Tensor<2, dim>>(
model_constants.at(constant_name));
290template <
unsigned int dim>
291inline dealii::Tensor<2, (2 * dim) - 1 + (dim / 3)>
296 "Mismatch between constants in parameters.prm and CustomPDE.h. The constant "
297 "that you attempted to access was " +
298 constant_name +
"."));
300 return boost::get<dealii::Tensor<2, (2 * dim) - 1 + (dim / 3)>>(
304template <
unsigned int dim>
307 const unsigned int &n_elements,
308 const std::vector<std::string> &tensor_elements)
310 unsigned int open_parentheses = 0;
311 unsigned int close_parentheses = 0;
313 for (
unsigned int element = 0; element < n_elements; element++)
315 for (
const char character : tensor_elements.at(element))
317 if (character ==
'(')
321 else if (character ==
')')
328 if (open_parentheses != close_parentheses)
331 dealii::ExcMessage(
"User-defined elastic constant list does not have "
332 "the same number of open and close parentheses."));
335 return open_parentheses;
338template <
unsigned int dim>
342 for (std::string &element : tensor_elements)
344 boost::range::remove_erase(element,
'(');
345 boost::range::remove_erase(element,
')');
349template <
unsigned int dim>
350inline dealii::Tensor<1, dim>
352 const unsigned int &n_elements,
353 const std::vector<std::string> &tensor_elements)
355 AssertThrow(n_elements == 3,
356 dealii::ExcMessage(
"The columns in user-defined constant tensors must be "
357 "equal to the maximum number of dimensions."));
359 dealii::Tensor<1, dim> temp;
360 for (
unsigned int i = 0; i < dim; i++)
362 temp[i] = dealii::Utilities::string_to_double(tensor_elements.at(i));
368template <
unsigned int dim>
369inline dealii::Tensor<2, dim>
371 const unsigned int &n_elements,
372 const std::vector<std::string> &tensor_elements)
374 AssertThrow(n_elements == 9,
375 dealii::ExcMessage(
"User-defined constant tensor does not have the "
376 "correct number of elements, matrices must be 3x3."));
378 const unsigned int row_length = 3;
380 dealii::Tensor<2, dim> temp;
381 for (
unsigned int i = 0; i < dim; i++)
383 for (
unsigned int j = 0; j < dim; j++)
386 dealii::Utilities::string_to_double(tensor_elements.at((i * row_length) + j));
393template <
unsigned int dim>
396 std::vector<std::string> &model_constants_strings)
400 model_constants_strings.size() > 1,
402 "At least two fields are required for user-defined variables (value and type)."));
404 std::vector<std::string> model_constants_type_strings =
405 dealii::Utilities::split_string_list(model_constants_strings.at(
406 model_constants_strings.size() - 1),
409 if (model_constants_strings.size() == 2)
414 if (boost::iequals(model_constants_type_strings.at(0),
"tensor"))
416 const unsigned int n_elements = model_constants_strings.size() - 1;
418 const unsigned int open_parentheses =
421 AssertThrow(open_parentheses <= 4,
422 FeatureNotImplemented(
"3rd rank tensors and above"));
427 if (open_parentheses == 1)
434 if (boost::iequals(model_constants_type_strings.at(1),
"elastic") &&
435 boost::iequals(model_constants_type_strings.at(2),
"constants"))
437 const unsigned int n_elements = model_constants_strings.size() - 1;
442 std::vector<double> temp_elastic_constants(n_elements);
443 for (
unsigned int i = 0; i < n_elements; i++)
445 temp_elastic_constants[i] =
446 dealii::Utilities::string_to_double(model_constants_strings.at(i));
448 const std::string &elastic_const_symmetry = model_constants_type_strings.at(0);
449 dealii::Tensor<2, (2 * dim) - 1 + (dim / 3)> temp =
456 "Only user-defined constant tensors may have multiple elements."));
460template <
unsigned int dim>
463 std::vector<std::string> &model_constants_strings)
465 std::vector<std::string> model_constants_type_strings =
466 dealii::Utilities::split_string_list(model_constants_strings.at(
467 model_constants_strings.size() - 1),
470 if (boost::iequals(model_constants_type_strings.at(0),
"double"))
472 return dealii::Utilities::string_to_double(model_constants_strings.at(0));
474 if (boost::iequals(model_constants_type_strings.at(0),
"int"))
476 return dealii::Utilities::string_to_int(model_constants_strings.at(0));
478 if (boost::iequals(model_constants_type_strings.at(0),
"bool"))
480 return boost::iequals(model_constants_strings.at(0),
"true");
485 "The type for user-defined variables must be `double`, `int`, "
486 "`bool`, `tensor`, or `elastic constants`."));
490template <
unsigned int dim>
491inline dealii::Tensor<2, (2 * dim) - 1 + (dim / 3)>
493 const std::string &elastic_const_symmetry)
const
497 if (elastic_const_symmetry ==
"isotropic")
501 else if (elastic_const_symmetry ==
"transverse")
505 else if (elastic_const_symmetry ==
"orthotropic")
509 else if (elastic_const_symmetry ==
"anisotropic")
515 AssertThrow(
false, dealii::ExcMessage(
"Invalid elasticity tensor type"));
521 constexpr unsigned int max_number = 21;
522 if ((mat_model ==
Anisotropic) && (dim == 2) && elastic_constants.size() == max_number)
524 std::vector<double> elastic_constants_temp = elastic_constants;
525 elastic_constants.clear();
526 const std::vector<unsigned int> indices_2d = {0, 1, 5, 6, 10, 14};
527 std::transform(indices_2d.begin(),
529 std::back_inserter(elastic_constants),
530 [&elastic_constants_temp](
unsigned int index)
532 return elastic_constants_temp.at(index);
539template <
unsigned int dim>
540inline dealii::Tensor<2, (2 * dim) - 1 + (dim / 3)>
542 const std::vector<double> &constants)
const
545 dealii::Tensor<2, (2 * dim) - 1 + (dim / 3)> compliance;
551 const int xx_dir = 0;
562 const double modulus = constants.at(0);
564 compliance[xx_dir][xx_dir] = modulus;
570 "Invalid elasticity model type for 1D. We only accept "
571 "isotropic elasticity tensors."));
578 const int xx_dir = 0;
579 const int yy_dir = 1;
580 const int xy_dir = 2;
595 const double modulus = constants.at(0);
596 const double poisson = constants.at(1);
598 const double shear_modulus = modulus / (2 * (1 + poisson));
599 const double lambda =
600 poisson * modulus / ((1 + poisson) * (1 - 2 * poisson));
602 compliance[xx_dir][xx_dir] = compliance[yy_dir][yy_dir] =
603 lambda + 2 * shear_modulus;
604 compliance[xy_dir][xy_dir] = shear_modulus;
605 compliance[xx_dir][yy_dir] = compliance[yy_dir][xx_dir] = lambda;
616 compliance[xx_dir][xx_dir] = constants.at(0);
617 compliance[yy_dir][yy_dir] = constants.at(1);
618 compliance[xy_dir][xy_dir] = constants.at(2);
619 compliance[xx_dir][yy_dir] = compliance[yy_dir][xx_dir] =
621 compliance[xx_dir][xy_dir] = compliance[xy_dir][xx_dir] =
623 compliance[yy_dir][xy_dir] = compliance[xy_dir][yy_dir] =
630 AssertThrow(
false, dealii::ExcMessage(
"Invalid elasticity model type"));
636 const int xx_dir = 0;
637 const int yy_dir = 1;
638 const int zz_dir = 2;
639 const int yz_dir = 3;
640 const int xz_dir = 4;
641 const int xy_dir = 5;
654 const double modulus = constants.at(0);
655 const double poisson = constants.at(1);
657 const double shear_modulus = modulus / (2 * (1 + poisson));
658 const double lambda =
659 poisson * modulus / ((1 + poisson) * (1 - 2 * poisson));
661 compliance[xx_dir][xx_dir] = compliance[yy_dir][yy_dir] =
662 compliance[zz_dir][zz_dir] = lambda + 2 * shear_modulus;
663 compliance[yz_dir][yz_dir] = compliance[xz_dir][xz_dir] =
664 compliance[xy_dir][xy_dir] = shear_modulus;
665 compliance[xx_dir][yy_dir] = compliance[yy_dir][xx_dir] =
666 compliance[xx_dir][zz_dir] = compliance[zz_dir][xx_dir] =
667 compliance[yy_dir][zz_dir] = compliance[zz_dir][yy_dir] = lambda;
678 compliance[xx_dir][xx_dir] = constants[0];
679 compliance[yy_dir][yy_dir] = constants[1];
680 compliance[zz_dir][zz_dir] = constants[2];
681 compliance[yz_dir][yz_dir] = constants[3];
682 compliance[xz_dir][xz_dir] = constants[4];
683 compliance[xy_dir][xy_dir] = constants[5];
684 compliance[xx_dir][yy_dir] = compliance[yy_dir][xx_dir] = constants[6];
685 compliance[xx_dir][zz_dir] = compliance[zz_dir][xx_dir] = constants[7];
686 compliance[xx_dir][yz_dir] = compliance[yz_dir][xx_dir] = constants[8];
687 compliance[xx_dir][xz_dir] = compliance[xz_dir][xx_dir] = constants[9];
688 compliance[xx_dir][xy_dir] = compliance[xy_dir][xx_dir] = constants[10];
689 compliance[yy_dir][zz_dir] = compliance[zz_dir][yy_dir] = constants[11];
690 compliance[yy_dir][yz_dir] = compliance[yz_dir][yy_dir] = constants[12];
691 compliance[yy_dir][xz_dir] = compliance[xz_dir][yy_dir] = constants[13];
692 compliance[yy_dir][xy_dir] = compliance[xy_dir][yy_dir] = constants[14];
693 compliance[zz_dir][yz_dir] = compliance[yz_dir][zz_dir] = constants[15];
694 compliance[zz_dir][xz_dir] = compliance[xz_dir][zz_dir] = constants[16];
695 compliance[zz_dir][xy_dir] = compliance[xy_dir][zz_dir] = constants[17];
696 compliance[yz_dir][xz_dir] = compliance[xz_dir][yz_dir] = constants[18];
697 compliance[yz_dir][xy_dir] = compliance[xy_dir][yz_dir] = constants[19];
698 compliance[xz_dir][xy_dir] = compliance[xy_dir][xz_dir] = constants[20];
708 AssertThrow(
false, dealii::ExcMessage(
"Invalid elasticity model type"));
714 Assert(
false, UnreachableCode());
721template <
unsigned int dim>
728 <<
"================================================\n"
729 <<
" User Constants\n"
730 <<
"================================================\n";
742PRISMS_PF_END_NAMESPACE
static dealii::ConditionalOStream & pout_summary()
Log output stream for writing a summary.log file.
Definition conditional_ostreams.cc:35
Class for printing of variant types. This is bad practice and should be fixed.
Definition user_constants.h:164
void operator()(bool value) const
Definition user_constants.h:179
void operator()(int value) const
Definition user_constants.h:173
void operator()(double value) const
Definition user_constants.h:167
void operator()(const dealii::Tensor< 2, dim > &value) const
Definition user_constants.h:195
void operator()(const dealii::Tensor< 2,(2 *D) - 1+(D/3)> &value) const
Definition user_constants.h:209
void operator()(const dealii::Tensor< 1, dim > &value) const
Definition user_constants.h:185
Class the stores and manages user-defined constants.
Definition user_constants.h:28
InputVariant construct_user_constant(std::vector< std::string > &model_constants_strings)
Assign the specified user constant to whatever type.
Definition user_constants.h:395
int get_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:240
dealii::Tensor< 2,(2 *dim) - 1+(dim/3)> get_cij_matrix(const ElasticityModel &model, const std::vector< double > &constants) const
Definition user_constants.h:541
dealii::Tensor< 1, dim > get_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:266
void add_user_constant(const std::string &constant_name, std::vector< std::string > &model_constants_strings)
Print all user-specified constants.
Definition user_constants.h:101
std::map< std::string, InputVariant > model_constants
List of user-defined constants.
Definition user_constants.h:158
boost::variant< double, int, bool, dealii::Tensor< 1, dim >, dealii::Tensor< 2, dim >, dealii::Tensor< 2,(2 *dim) - 1+(dim/3)> > InputVariant
Definition user_constants.h:30
InputVariant primitive_model_constant(std::vector< std::string > &model_constants_strings)
Assign the primitive user constants (e.g., int, double, bool).
Definition user_constants.h:462
double get_double(const std::string &constant_name) const
Retrieve the double from the model_constants that are defined from the parameters....
Definition user_constants.h:227
dealii::Tensor< 2,(2 *dim) - 1+(dim/3)> get_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:292
dealii::Tensor< 2, dim > get_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:279
dealii::Tensor< 2,(2 *dim) - 1+(dim/3)> get_cij_tensor(std::vector< double > elastic_constants, const std::string &elastic_const_symmetry) const
Definition user_constants.h:492
dealii::Tensor< 1, dim > compute_rank_1_tensor_constant(const unsigned int &n_elements, const std::vector< std::string > &tensor_elements)
Compute a 1st rank tensor from user inputs .
Definition user_constants.h:351
dealii::Tensor< 2, dim > compute_rank_2_tensor_constant(const unsigned int &n_elements, const std::vector< std::string > &tensor_elements)
Compute a 2nd rank tensor from user inputs .
Definition user_constants.h:370
unsigned int compute_tensor_parentheses(const unsigned int &n_elements, const std::vector< std::string > &tensor_elements)
Compute the number of tensor rows.
Definition user_constants.h:306
void print() const
Print all user-specified constants.
Definition user_constants.h:723
bool get_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:253
void remove_parentheses(std::vector< std::string > &tensor_elements)
Remove and leading and trailing parentheses.
Definition user_constants.h:340
Definition conditional_ostreams.cc:20
ElasticityModel
Symmetry of elastic tensor.
Definition type_enums.h:62
@ Transverse
Definition type_enums.h:64
@ Anisotropic
Definition type_enums.h:66
@ Orthotropic
Definition type_enums.h:65
@ Isotropic
Definition type_enums.h:63