16#ifndef dealii_differentiation_sd_symengine_tensor_operations_h
17#define dealii_differentiation_sd_symengine_tensor_operations_h
21#ifdef DEAL_II_WITH_SYMENGINE
85 template <
int rank,
int dim>
108 template <
int rank,
int dim>
156 template <
int rank,
int dim>
181 template <
int rank,
int dim>
184 const std::string & symbol,
203 template <
int rank,
int dim>
216 template <
int rank,
int dim>
230 template <
int rank,
int dim>
244 template <
int rank,
int dim>
258 template <
int rank,
int dim>
272 template <
int rank,
int dim>
287 template <
int rank,
int dim>
303 template <
int rank,
int dim>
318 template <
int rank_1,
int rank_2,
int dim>
335 template <
int rank_1,
int rank_2,
int dim>
350 template <
int rank_1,
int rank_2,
int dim>
365 template <
int rank_1,
int rank_2,
int dim>
401 template <
bool ignore_invalid_symbols =
false,
402 typename ValueType = double,
405 typename SymbolicType>
434 template <
bool ignore_invalid_symbols =
false,
435 typename ValueType = double,
438 typename SymbolicType>
464 template <
int rank,
int dim,
typename SymbolicType,
typename ValueType>
491 template <
int rank,
int dim,
typename SymbolicType,
typename ValueType>
526 template <
int rank,
int dim,
typename ExpressionType,
typename ValueType>
553 template <
int rank,
int dim,
typename ExpressionType,
typename ValueType>
592 template <
bool ignore_invalid_symbols =
false,
595 typename ExpressionType,
628 template <
bool ignore_invalid_symbols =
false,
631 typename ExpressionType,
665 template <
int rank,
int dim>
689 template <
int rank,
int dim>
720 template <
typename ValueType,
int rank,
int dim>
752 template <
typename ValueType,
int rank,
int dim>
780 make_rank_4_tensor_indices(
const unsigned int idx_i,
781 const unsigned int idx_j)
794 template <
int rank_1,
int rank_2>
800 for (
unsigned int i = 0; i < rank_1; ++i)
801 indices_out[i] = indices_1[i];
802 for (
unsigned int j = 0; j < rank_2; ++j)
803 indices_out[rank_1 + j] = indices_2[j];
824 template <
int rank,
int dim,
typename ValueType>
833 template <
int rank,
int dim,
typename ValueType>
839 rank == 0 || rank == 2,
840 "Querying symmetric component for non rank-2 symmetric tensor index is not allowed.");
845 template <
int dim,
typename ValueType>
850 return table_indices[0] != table_indices[1];
855 typename ValueType = Expression,
856 template <
int,
int,
typename>
858 TensorType<0, dim, ValueType>
859 scalar_diff_tensor(
const ValueType & func,
860 const TensorType<0, dim, ValueType> &op)
868 typename ValueType = Expression,
869 template <
int,
int,
typename>
871 TensorType<rank, dim, ValueType>
872 scalar_diff_tensor(
const ValueType & func,
873 const TensorType<rank, dim, ValueType> &op)
875 TensorType<rank, dim, ValueType> out;
876 for (
unsigned int i = 0; i < out.n_independent_components; ++i)
879 out.unrolled_to_component_indices(i));
882 if (is_symmetric_component(indices, op))
892 typename ValueType = Expression,
893 template <
int,
int,
typename>
895 TensorType<rank, dim, ValueType>
896 tensor_diff_tensor(
const TensorType<0, dim, ValueType> & func,
897 const TensorType<rank, dim, ValueType> &op)
899 TensorType<rank, dim, ValueType> out;
900 for (
unsigned int i = 0; i < out.n_independent_components; ++i)
903 out.unrolled_to_component_indices(i));
906 if (is_symmetric_component(indices, op))
915 typename ValueType = Expression,
916 template <
int,
int,
typename>
918 TensorType<rank, dim, ValueType>
919 tensor_diff_scalar(
const TensorType<rank, dim, ValueType> &funcs,
920 const ValueType & op)
922 TensorType<rank, dim, ValueType> out;
923 for (
unsigned int i = 0; i < out.n_independent_components; ++i)
926 out.unrolled_to_component_indices(i));
936 typename ValueType = Expression,
937 template <
int,
int,
typename>
939 TensorType<rank, dim, ValueType>
940 tensor_diff_tensor(
const TensorType<rank, dim, ValueType> &funcs,
941 const TensorType<0, dim, ValueType> & op)
943 TensorType<rank, dim, ValueType> out;
944 for (
unsigned int i = 0; i < out.n_independent_components; ++i)
947 out.unrolled_to_component_indices(i));
955 template <
int rank_1,
958 typename ValueType = Expression,
959 template <
int,
int,
typename>
961 TensorType<rank_1 + rank_2, dim, ValueType>
962 tensor_diff_tensor(
const TensorType<rank_1, dim, ValueType> &funcs,
963 const TensorType<rank_2, dim, ValueType> &op)
965 TensorType<rank_1 + rank_2, dim, ValueType> out;
966 for (
unsigned int i = 0; i < funcs.n_independent_components; ++i)
969 funcs.unrolled_to_component_indices(i));
970 for (
unsigned int j = 0; j < op.n_independent_components; ++j)
973 op.unrolled_to_component_indices(j));
975 concatenate_indices(indices_i, indices_j);
980 if (is_symmetric_component(indices_j, op))
981 out[indices_out] *= 0.5;
992 template <
int rank_1,
995 typename ValueType = Expression,
996 template <
int,
int,
typename>
998 template <
int,
int,
typename>
1001 tensor_diff_tensor(
const TensorType_1<rank_1, dim, ValueType> &funcs,
1002 const TensorType_2<rank_2, dim, ValueType> &op)
1005 for (
unsigned int i = 0; i < funcs.n_independent_components; ++i)
1008 funcs.unrolled_to_component_indices(i));
1009 for (
unsigned int j = 0; j < op.n_independent_components; ++j)
1012 op.unrolled_to_component_indices(j));
1014 concatenate_indices(indices_i, indices_j);
1019 if (is_symmetric_component(indices_j, op))
1020 out[indices_out] *= 0.5;
1023 if (std::is_same<TensorType_1<rank_1, dim, ValueType>,
1028 concatenate_indices(transpose_indices(indices_i),
1030 out[indices_out_t] = out[indices_out];
1032 else if (std::is_same<TensorType_2<rank_2, dim, ValueType>,
1037 concatenate_indices(indices_i,
1038 transpose_indices(indices_j));
1039 out[indices_out_t] = out[indices_out];
1046 "Expect mixed tensor differentiation to have at least "
1047 "one component stemming from a symmetric tensor."));
1057 template <
int rank,
int dim>
1062 return internal::scalar_diff_tensor(func, op);
1066 template <
int rank,
int dim>
1071 return internal::scalar_diff_tensor(func, op);
1075 template <
int rank,
int dim>
1080 return internal::scalar_diff_tensor(func, op);
1084 template <
int rank,
int dim>
1091 const Expression tmp = func;
1092 return internal::scalar_diff_tensor(tmp, op);
1096 template <
int rank,
int dim>
1099 const Expression & op)
1101 return internal::tensor_diff_scalar(symbol_tensor, op);
1105 template <
int rank,
int dim>
1110 return internal::tensor_diff_scalar(symbol_tensor, op);
1114 template <
int rank,
int dim>
1117 const Expression & op)
1119 return internal::tensor_diff_scalar(symbol_tensor, op);
1123 template <
int rank,
int dim>
1128 return internal::tensor_diff_scalar(symbol_tensor, op);
1132 template <
int rank_1,
int rank_2,
int dim>
1137 return internal::tensor_diff_tensor(symbol_tensor, op);
1141 template <
int rank_1,
int rank_2,
int dim>
1146 return internal::tensor_diff_tensor(symbol_tensor, op);
1150 template <
int rank_1,
int rank_2,
int dim>
1155 return internal::tensor_diff_tensor(symbol_tensor, op);
1159 template <
int rank_1,
int rank_2,
int dim>
1164 return internal::tensor_diff_tensor(symbol_tensor, op);
1173 template <
typename SymbolicType,
1177 template <
int,
int,
typename>
1180 set_tensor_value_in_symbol_map(
1182 const TensorType<rank, dim, SymbolicType> &symbol_tensor,
1183 const TensorType<rank, dim, ValueType> & value_tensor)
1185 TensorType<rank, dim, Expression> out;
1186 for (
unsigned int i = 0; i < out.n_independent_components; ++i)
1189 out.unrolled_to_component_indices(i));
1191 symbol_tensor[indices],
1192 value_tensor[indices]);
1197 template <
typename SymbolicType,
typename ValueType,
int dim>
1199 set_tensor_value_in_symbol_map(
1205 for (
unsigned int i = 0;
1206 i < SymmetricTensor<2, dim>::n_independent_components;
1208 for (
unsigned int j = 0;
1209 j < SymmetricTensor<2, dim>::n_independent_components;
1213 make_rank_4_tensor_indices<dim>(i, j);
1215 symbol_tensor[indices],
1216 value_tensor[indices]);
1222 template <
bool ignore_invalid_symbols,
1226 typename SymbolicType>
1232 add_to_substitution_map<ignore_invalid_symbols>(
1237 template <
bool ignore_invalid_symbols,
1241 typename SymbolicType>
1248 add_to_substitution_map<ignore_invalid_symbols>(
1253 template <
int rank,
int dim,
typename SymbolicType,
typename ValueType>
1260 internal::set_tensor_value_in_symbol_map(substitution_map,
1266 template <
int rank,
int dim,
typename SymbolicType,
typename ValueType>
1273 internal::set_tensor_value_in_symbol_map(substitution_map,
1282 template <
int rank,
int dim,
typename ExpressionType,
typename ValueType>
1294 template <
int rank,
int dim,
typename ExpressionType,
typename ValueType>
1313 typename ExpressionType,
1315 template <
int,
int,
typename>
1317 std::vector<std::pair<ExpressionType, ValueType>>
1318 make_tensor_entries_for_substitution_map(
1319 const TensorType<rank, dim, ExpressionType> &symbol_tensor,
1320 const TensorType<rank, dim, ValueType> & value_tensor)
1322 std::vector<std::pair<ExpressionType, ValueType>> symbol_values;
1323 for (
unsigned int i = 0; i < symbol_tensor.n_independent_components;
1327 symbol_tensor.unrolled_to_component_indices(i));
1328 symbol_values.push_back(
1329 std::make_pair(symbol_tensor[indices], value_tensor[indices]));
1331 return symbol_values;
1335 template <
int dim,
typename ExpressionType,
typename ValueType>
1336 std::vector<std::pair<ExpressionType, ValueType>>
1337 make_tensor_entries_for_substitution_map(
1341 const ExpressionType &expression = symbol_tensor;
1342 const ValueType &
value = value_tensor;
1343 return {std::make_pair(expression, value)};
1347 template <
int dim,
typename ExpressionType,
typename ValueType>
1348 std::vector<std::pair<ExpressionType, ValueType>>
1349 make_tensor_entries_for_substitution_map(
1353 std::vector<std::pair<ExpressionType, ValueType>> symbol_values;
1354 for (
unsigned int i = 0;
1355 i < SymmetricTensor<2, dim>::n_independent_components;
1357 for (
unsigned int j = 0;
1358 j < SymmetricTensor<2, dim>::n_independent_components;
1362 make_rank_4_tensor_indices<dim>(i, j);
1363 symbol_values.push_back(
1364 std::make_pair(symbol_tensor[indices], value_tensor[indices]));
1366 return symbol_values;
1371 template <
bool ignore_invalid_symbols,
1374 typename ExpressionType,
1382 add_to_substitution_map<ignore_invalid_symbols>(
1384 internal::make_tensor_entries_for_substitution_map(symbol_tensor,
1389 template <
bool ignore_invalid_symbols,
1392 typename ExpressionType,
1400 add_to_substitution_map<ignore_invalid_symbols>(
1402 internal::make_tensor_entries_for_substitution_map(symbol_tensor,
1414 template <
int,
int,
typename>
1416 TensorType<rank, dim, Expression>
1418 const TensorType<rank, dim, Expression> &expression_tensor,
1421 TensorType<rank, dim, Expression> out;
1422 for (
unsigned int i = 0; i < out.n_independent_components; ++i)
1425 out.unrolled_to_component_indices(i));
1427 substitute(expression_tensor[indices], substitution_map);
1438 const Expression &expression = expression_tensor;
1439 return substitute(expression, substitution_map);
1450 for (
unsigned int i = 0;
1451 i < SymmetricTensor<2, dim>::n_independent_components;
1453 for (
unsigned int j = 0;
1454 j < SymmetricTensor<2, dim>::n_independent_components;
1458 make_rank_4_tensor_indices<dim>(i, j);
1460 substitute(expression_tensor[indices], substitution_map);
1466 template <
typename ValueType,
1469 template <
int,
int,
typename>
1471 TensorType<rank, dim, ValueType>
1472 substitute_and_evaluate_tensor(
1473 const TensorType<rank, dim, Expression> &expression_tensor,
1476 TensorType<rank, dim, ValueType> out;
1477 for (
unsigned int i = 0; i < out.n_independent_components; ++i)
1480 out.unrolled_to_component_indices(i));
1482 substitute_and_evaluate<ValueType>(expression_tensor[indices],
1489 template <
typename ValueType,
int dim>
1491 substitute_and_evaluate_tensor(
1495 const Expression &expression = expression_tensor;
1496 return substitute_and_evaluate<ValueType>(expression, substitution_map);
1500 template <
typename ValueType,
int dim>
1502 substitute_and_evaluate_tensor(
1507 for (
unsigned int i = 0;
1508 i < SymmetricTensor<2, dim>::n_independent_components;
1510 for (
unsigned int j = 0;
1511 j < SymmetricTensor<2, dim>::n_independent_components;
1515 make_rank_4_tensor_indices<dim>(i, j);
1517 substitute_and_evaluate<ValueType>(expression_tensor[indices],
1525 template <
int rank,
int dim>
1530 return internal::substitute_tensor(expression_tensor, substitution_map);
1534 template <
int rank,
int dim>
1539 return internal::substitute_tensor(expression_tensor, substitution_map);
1543 template <
typename ValueType,
int rank,
int dim>
1549 return internal::substitute_and_evaluate_tensor<ValueType>(
1550 expression_tensor, substitution_map);
1554 template <
typename ValueType,
int rank,
int dim>
1560 return internal::substitute_and_evaluate_tensor<ValueType>(
1561 expression_tensor, substitution_map);
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
#define Assert(cond, exc)
static ::ExceptionBase & ExcMessage(std::string arg1)
void set_value_in_symbol_map(types::substitution_map &substitution_map, const SymEngine::RCP< const SymEngine::Basic > &symbol, const SymEngine::RCP< const SymEngine::Basic > &value)
std::map< SD::Expression, SD::Expression, internal::ExpressionKeyLess > substitution_map
Tensor< rank, dim, Expression > make_tensor_of_symbols(const std::string &symbol)
Expression differentiate(const Expression &f, const Expression &x)
ValueType substitute_and_evaluate(const Expression &expression, const types::substitution_map &substitution_map)
SymmetricTensor< rank, dim, Expression > make_symmetric_tensor_of_symbols(const std::string &symbol)
Tensor< 1, dim, Expression > make_vector_of_symbolic_functions(const std::string &symbol, const types::substitution_map &arguments)
void set_value_in_symbol_map(types::substitution_map &substitution_map, const Expression &symbol, const Expression &value)
SymmetricTensor< rank, dim, Expression > make_symmetric_tensor_of_symbolic_functions(const std::string &symbol, const types::substitution_map &arguments)
void add_to_symbol_map(types::substitution_map &symbol_map, const Expression &symbol)
Tensor< 1, dim, Expression > make_vector_of_symbols(const std::string &symbol)
void add_to_substitution_map(types::substitution_map &substitution_map, const Expression &symbol, const Expression &value)
Expression substitute(const Expression &expression, const types::substitution_map &substitution_map)
Tensor< rank, dim, Expression > make_tensor_of_symbolic_functions(const std::string &symbol, const types::substitution_map &arguments)
types::substitution_map make_substitution_map(const Expression &symbol, const Expression &value)