6#include <deal.II/base/config.h>
7#include <deal.II/base/exceptions.h>
8#include <deal.II/base/mpi.h>
9#include <deal.II/base/point.h>
10#include <deal.II/base/tensor.h>
11#include <deal.II/base/vectorization.h>
12#include <deal.II/matrix_free/evaluation_flags.h>
14#include <boost/range/algorithm.hpp>
15#include <boost/range/algorithm_ext.hpp>
19#include <prismspf/config.h>
23#include <unordered_map>
33 [[maybe_unused]]
const unsigned int max_num_threads =
34 dealii::numbers::invalid_unsigned_int)
35 : dealii::Utilities::MPI::MPI_InitFinalize(argc, argv, 1)
41 const unsigned int max_num_threads = dealii::numbers::invalid_unsigned_int)
50template <
typename Type>
53 const std::unordered_map<std::string, Type> &table)
55 auto iterator = table.find(
string);
56 AssertThrow(iterator != table.end(),
57 dealii::ExcMessage(
"Unknown table entry: " +
string));
58 return iterator->second;
78template <
typename Type,
typename OtherType>
79std::pair<OtherType, Type>
81 const std::string &
string,
82 const std::unordered_map<std::string, Type> &table,
83 const std::unordered_map<std::string, OtherType> &other_table,
84 const std::pair<char, char> &delimiters = {
'(',
')'})
87 const auto opening_delimiter_position =
string.find(delimiters.first);
88 const auto closing_delimiter_position =
string.find(delimiters.second);
90 bool has_opening_delimiter = opening_delimiter_position != std::string_view::npos;
91 bool has_closing_delimiter = closing_delimiter_position != std::string_view::npos;
94 AssertThrow(closing_delimiter_position >= opening_delimiter_position,
96 "Opening delimiter must precede the closing delimiter. You had " +
98 AssertThrow(has_closing_delimiter == has_opening_delimiter,
99 dealii::ExcMessage(
"You must either have a delimiter pair or not. You seem "
100 "to only have one delimiter. You had " +
104 if (!has_closing_delimiter && !has_opening_delimiter)
108 return {first_type, second_type};
112 AssertThrow(closing_delimiter_position ==
string.size() - 1,
114 "Closing delimiter must be at the end of the string. You had " +
string));
117 std::string_view input_view {
string};
118 std::string_view outer_string = input_view.substr(0, opening_delimiter_position);
119 std::string_view inner_string =
120 input_view.substr(opening_delimiter_position + 1,
121 closing_delimiter_position - opening_delimiter_position - 1);
123 AssertThrow(!outer_string.empty() && !inner_string.empty(),
125 "Inner and outer map entries must not be empty. You had " +
string));
131 const auto second_type =
string_to_type(std::string(outer_string), table);
132 const auto first_type =
string_to_type(std::string(inner_string), other_table);
133 return {first_type, second_type};
140template <
typename Number>
141inline DEAL_II_ALWAYS_INLINE Number
142pmod(
const Number &value,
const Number &modulus)
150template <
unsigned int dim>
157template <
unsigned int dim,
typename T>
158inline DEAL_II_ALWAYS_INLINE
void
163 stress = elasticity_tensor * strain;
170template <
unsigned int dim,
typename T>
171inline DEAL_II_ALWAYS_INLINE
void
173 const dealii::Tensor<2, dim, T> &strain,
174 dealii::Tensor<2, dim, T> &stress)
176 dealii::Tensor<1, voigt_tensor_size<dim>, T> sigma;
177 dealii::Tensor<1, voigt_tensor_size<dim>, T> epsilon;
179 if constexpr (dim == 3)
181 const int xx_dir = 0;
182 const int yy_dir = 1;
183 const int zz_dir = 2;
184 const int yz_dir = 3;
185 const int xz_dir = 4;
186 const int xy_dir = 5;
188 epsilon[xx_dir] = strain[xx_dir][xx_dir];
189 epsilon[yy_dir] = strain[yy_dir][yy_dir];
190 epsilon[zz_dir] = strain[zz_dir][zz_dir];
192 epsilon[yz_dir] = strain[yy_dir][zz_dir] + strain[zz_dir][yy_dir];
193 epsilon[xz_dir] = strain[xx_dir][zz_dir] + strain[zz_dir][xx_dir];
194 epsilon[xy_dir] = strain[xx_dir][yy_dir] + strain[yy_dir][xx_dir];
197 sigma = elasticity_tensor * epsilon;
199 stress[xx_dir][xx_dir] = sigma[xx_dir];
200 stress[yy_dir][yy_dir] = sigma[yy_dir];
201 stress[zz_dir][zz_dir] = sigma[zz_dir];
203 stress[yy_dir][zz_dir] = sigma[yz_dir];
204 stress[zz_dir][yy_dir] = sigma[yz_dir];
206 stress[xx_dir][zz_dir] = sigma[xz_dir];
207 stress[zz_dir][xx_dir] = sigma[xz_dir];
209 stress[xx_dir][yy_dir] = sigma[xy_dir];
210 stress[yy_dir][xx_dir] = sigma[xy_dir];
212 else if constexpr (dim == 2)
214 const int xx_dir = 0;
215 const int yy_dir = 1;
216 const int xy_dir = 2;
218 epsilon[xx_dir] = strain[xx_dir][xx_dir];
219 epsilon[yy_dir] = strain[yy_dir][yy_dir];
221 epsilon[xy_dir] = strain[xx_dir][yy_dir] + strain[yy_dir][xx_dir];
224 sigma = elasticity_tensor * epsilon;
226 stress[xx_dir][xx_dir] = sigma[xx_dir];
227 stress[yy_dir][yy_dir] = sigma[yy_dir];
228 stress[xx_dir][yy_dir] = sigma[xy_dir];
229 stress[yy_dir][xx_dir] = sigma[xy_dir];
233 const int xx_dir = 0;
235 stress[xx_dir][xx_dir] = elasticity_tensor[xx_dir][xx_dir] * strain[xx_dir][xx_dir];
245 std::string text = _text;
246 boost::range::remove_erase_if(text, ::isspace);
256 return boolean ?
"true" :
"false";
267 if ((flag & dealii::EvaluationFlags::EvaluationFlags::values) != 0U)
271 if ((flag & dealii::EvaluationFlags::EvaluationFlags::gradients) != 0U)
277 result +=
"gradients";
279 if ((flag & dealii::EvaluationFlags::EvaluationFlags::hessians) != 0U)
285 result +=
"hessians";
296template <
unsigned int dim,
typename number>
297inline DEAL_II_ALWAYS_INLINE std::vector<number>
300 static_assert(dim < 4,
"We only allow 3 space dimensions");
302 std::vector<number> vec(3, 0.0);
306 for (
unsigned int i = 0; i < dim; ++i)
316PRISMS_PF_END_NAMESPACE
MPI_InitFinalize(int &argc, char **&argv, const unsigned int max_num_threads=dealii::numbers::invalid_unsigned_int)
Definition utilities.h:38
Definition conditional_ostreams.cc:20
inline ::dealii::VectorizedArray< Number, width > fmod(const ::dealii::VectorizedArray< Number, width > &numer, const Number denom)
Definition vectorized_operations.h:54
Type
Factory function to create appropriate reader based on input file type not a member of ReadFieldBase ...
Definition read_field_factory.h:30
std::string strip_whitespace(const std::string &_text)
Remove whitespace from strings.
Definition utilities.h:243
std::pair< OtherType, Type > string_to_type_pair_with_delimiters(const std::string &string, const std::unordered_map< std::string, Type > &table, const std::unordered_map< std::string, OtherType > &other_table, const std::pair< char, char > &delimiters={'(', ')'})
Helper function that converts a string to some type pair, given two mappings and a set of delimiters.
Definition utilities.h:80
Type string_to_type(const std::string &string, const std::unordered_map< std::string, Type > &table)
Helper function that converts a string to some type, given a mapping.
Definition utilities.h:52
std::string eval_flags_to_string(dealii::EvaluationFlags::EvaluationFlags flag)
Convert evaluation flags to string.
Definition utilities.h:263
DEAL_II_ALWAYS_INLINE void compute_stress(const dealii::Tensor< 2, voigt_tensor_size< dim >, T > &elasticity_tensor, const dealii::Tensor< 1, voigt_tensor_size< dim >, T > &strain, dealii::Tensor< 1, voigt_tensor_size< dim >, T > &stress)
Compute the stress with a given displacement and elasticity tensor. This assumes that the provided pa...
Definition utilities.h:159
constexpr unsigned int voigt_tensor_size
Voigt notation index range.
Definition utilities.h:151
DEAL_II_ALWAYS_INLINE std::vector< number > dealii_point_to_vector(const dealii::Point< dim, number > &point)
Definition utilities.h:298
DEAL_II_ALWAYS_INLINE Number pmod(const Number &value, const Number &modulus)
Positive moldulo (remainder) returns the normal remainder. (c++ fmod is defined abnormally for negati...
Definition utilities.h:142
const char * bool_to_string(bool boolean)
Convert bool to string.
Definition utilities.h:254