From: Jean-Paul Pelteret Date: Sat, 4 May 2019 19:57:16 +0000 (+0200) Subject: Implement functions to set values in symbol maps X-Git-Tag: v9.1.0-rc1~68^2~8 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dc757e6dcc5cf7834fcb1d943be7dab79d7a3558;p=dealii.git Implement functions to set values in symbol maps --- diff --git a/include/deal.II/differentiation/sd/symengine_scalar_operations.h b/include/deal.II/differentiation/sd/symengine_scalar_operations.h index a2e6a87b1f..0c3186baf8 100644 --- a/include/deal.II/differentiation/sd/symengine_scalar_operations.h +++ b/include/deal.II/differentiation/sd/symengine_scalar_operations.h @@ -146,6 +146,21 @@ namespace Differentiation */ bool is_valid_substitution_symbol(const SymEngine::Basic &entry); + + /** + * A convenience function to set the @p value associated with + * the @p symbol in the @p substitution_map. + * + * Using this function ensures that the @p symbol is one that is + * valid specifically for the purpose of symbolic substitution. + * It must therefore represent a symbol or symbolic derivative, + * otherwise an error will be thrown. + */ + void + set_value_in_symbol_map( + types::substitution_map & substitution_map, + const SymEngine::RCP &symbol, + const SymEngine::RCP &value); } // namespace internal /** @@ -331,6 +346,117 @@ namespace Differentiation const SymbolicType & symbol, const Args &... other_symbols); + /** + * Find the input @p symbol in the @p substitution_map and set its + * corresponding @p value. + * + * This function may be used to safely transform an existing or null + * symbolic map (one with uninitialized entries) into one that can be used + * to conduct symbolic substitution operations (i.e., a substitution map). + */ + void + set_value_in_symbol_map(types::substitution_map &substitution_map, + const Expression & symbol, + const Expression & value); + + /** + * Find the input @p symbol in the @p substitution_map and set its + * corresponding @p value. + * + * This function may be used to safely transform an existing or null + * symbolic map (one with uninitialized entries) into one that can be used + * to conduct symbolic substitution operations (i.e., a substitution map). + */ + template &>::value && + std::is_constructible::value>::type> + void + set_value_in_symbol_map(types::substitution_map &substitution_map, + const SymbolicType & symbol, + const ValueType & value); + + /** + * Find the input @p symbols in the @p substitution_map and set their + * corresponding @p values. + * + * This function may be used to safely transform an existing or null + * symbolic map (one with uninitialized entries) into one that can be used + * to conduct symbolic substitution operations (i.e., a substitution map). + */ + template + void + set_value_in_symbol_map(types::substitution_map & substitution_map, + const std::vector &symbols, + const std::vector & values); + + /** + * Find the input @p symbols in the @p substitution_map and set their + * corresponding @p values. The modified symbol will have the key given by + * the first element of @p symbol_value and the value given by its second + * element. + * + * This function may be used to safely transform an existing or null + * symbolic map (one with uninitialized entries) into one that can be used + * to conduct symbolic substitution operations (i.e., a substitution map). + */ + template + void + set_value_in_symbol_map( + types::substitution_map & substitution_map, + const std::pair &symbol_value); + + /** + * Find the input @p symbols in the @p substitution_map and set their + * corresponding @p values, followed by the same operation for the + * @p other_symbol_values. + * + * This function may be used to safely transform an existing or null + * symbolic map (one with uninitialized entries) into one that can be used + * to conduct symbolic substitution operations (i.e., a substitution map). + */ + template + void + set_value_in_symbol_map( + types::substitution_map & substitution_map, + const std::pair &symbol_value, + const Args &... other_symbol_values); + + /** + * Find the input @p symbols in the @p substitution_map and set their + * corresponding @p values. The modified symbol will have the key given by + * the first element of each paired entry in the @p symbol_values vector + * and the value given by its respective second element. + * + * This function may be used to safely transform an existing or null + * symbolic map (one with uninitialized entries) into one that can be used + * to conduct symbolic substitution operations (i.e., a substitution map). + */ + template + void + set_value_in_symbol_map( + types::substitution_map & substitution_map, + const std::vector> &symbol_values); + + /** + * Find the input @p symbols in the @p substitution_map and set their + * corresponding @p values. The modified symbol will have the key given by + * the each element the @p symbol_values map and the value given by its + * respective mapped element. + * + * This function may be used to safely transform an existing or null + * symbolic map (one with uninitialized entries) into one that can be used + * to conduct symbolic substitution operations (i.e., a substitution map). + */ + void + set_value_in_symbol_map(types::substitution_map & substitution_map, + const types::substitution_map &symbol_values); + //@} /** @@ -886,6 +1012,77 @@ namespace Differentiation } + template + void + set_value_in_symbol_map(types::substitution_map &substitution_map, + const ExpressionType & symbol, + const ValueType & value) + { + // Call the above function + using SE_RCP_Basic = const SymEngine::RCP &; + internal::set_value_in_symbol_map(substitution_map, + static_cast(symbol), + static_cast( + ExpressionType(value))); + } + + + template + void + set_value_in_symbol_map(types::substitution_map & substitution_map, + const std::vector &symbols, + const std::vector & values) + { + Assert(symbols.size() == values.size(), + ExcDimensionMismatch(symbols.size(), values.size())); + + typename std::vector::const_iterator it_symb = + symbols.begin(); + typename std::vector::const_iterator it_val = values.begin(); + for (; it_symb != symbols.end(); ++it_symb, ++it_val) + { + Assert(it_val != values.end(), ExcInternalError()); + set_value_in_symbol_map(substitution_map, *it_symb, *it_val); + } + } + + + template + void + set_value_in_symbol_map( + types::substitution_map & substitution_map, + const std::pair &symbol_value) + { + set_value_in_symbol_map(substitution_map, + symbol_value.first, + symbol_value.second); + } + + + template + void + set_value_in_symbol_map( + types::substitution_map & substitution_map, + const std::pair &symbol_value, + const Args &... other_symbol_values) + { + set_value_in_symbol_map(substitution_map, symbol_value); + set_value_in_symbol_map(substitution_map, other_symbol_values...); + } + + + template + void + set_value_in_symbol_map( + types::substitution_map & substitution_map, + const std::vector> &symbol_values) + { + // Call the above function + for (const auto &entry : symbol_values) + set_value_in_symbol_map(substitution_map, entry.first, entry.second); + } + + /* ------------------ Symbol substitution map creation ----------------*/ diff --git a/include/deal.II/differentiation/sd/symengine_tensor_operations.h b/include/deal.II/differentiation/sd/symengine_tensor_operations.h index 3793947546..c042e11916 100644 --- a/include/deal.II/differentiation/sd/symengine_tensor_operations.h +++ b/include/deal.II/differentiation/sd/symengine_tensor_operations.h @@ -422,6 +422,37 @@ namespace Differentiation types::substitution_map & symbol_map, const SymmetricTensor &symbol_tensor); + /** + * Find the input @p symbols in the @p substitution_map and set the entries + * corresponding to the key values given by @p symbol_tensor to the values + * given by @p value_tensor. + * + * This function may be used to safely transform an existing or null + * symbolic map (one with uninitialized entries) into one that can be used + * to conduct symbolic substitution operations (i.e., a substitution map). + */ + template + void + set_value_in_symbol_map(types::substitution_map &substitution_map, + const Tensor &symbol_tensor, + const Tensor & value_tensor); + + /** + * Find the input @p symbols in the @p substitution_map and set the entries + * corresponding to the key values given by @p symbol_tensor to the values + * given by @p value_tensor. + * + * This function may be used to safely transform an existing or null + * symbolic map (one with uninitialized entries) into one that can be used + * to conduct symbolic substitution operations (i.e., a substitution map). + */ + template + void + set_value_in_symbol_map( + types::substitution_map & substitution_map, + const SymmetricTensor &symbol_tensor, + const SymmetricTensor & value_tensor); + //@} /** @@ -908,6 +939,57 @@ namespace Differentiation /* ---------------- Symbol map creation and manipulation --------------*/ + + + namespace internal + { + template class TensorType> + void + tensor_set_value_in_symbol_map( + types::substitution_map & substitution_map, + const TensorType &symbol_tensor, + const TensorType & value_tensor) + { + TensorType out; + for (unsigned int i = 0; i < out.n_independent_components; ++i) + { + const TableIndices indices( + out.unrolled_to_component_indices(i)); + set_value_in_symbol_map(substitution_map, + symbol_tensor[indices], + value_tensor[indices]); + } + } + + + template + void + tensor_set_value_in_symbol_map( + types::substitution_map & substitution_map, + const SymmetricTensor<4, dim, Expression> &symbol_tensor, + const SymmetricTensor<4, dim, ValueType> & value_tensor) + { + SymmetricTensor<4, dim, Expression> out; + for (unsigned int i = 0; + i < SymmetricTensor<2, dim>::n_independent_components; + ++i) + for (unsigned int j = 0; + j < SymmetricTensor<2, dim>::n_independent_components; + ++j) + { + const TableIndices<4> indices = + make_rank_4_tensor_indices(i, j); + set_value_in_symbol_map(substitution_map, + symbol_tensor[indices], + value_tensor[indices]); + } + } + } // namespace internal + + template + void + set_value_in_symbol_map(types::substitution_map &substitution_map, + const Tensor &symbol_tensor, + const Tensor & value_tensor) + { + internal::tensor_set_value_in_symbol_map(substitution_map, + symbol_tensor, + value_tensor); + } + + + template + void + set_value_in_symbol_map( + types::substitution_map & substitution_map, + const SymmetricTensor &symbol_tensor, + const SymmetricTensor & value_tensor) + { + internal::tensor_set_value_in_symbol_map(substitution_map, + symbol_tensor, + value_tensor); + } + + /* ------------------ Symbol substitution map creation ----------------*/ diff --git a/source/differentiation/sd/symengine_scalar_operations.cc b/source/differentiation/sd/symengine_scalar_operations.cc index da5fd647b8..ae0bfb7c92 100644 --- a/source/differentiation/sd/symengine_scalar_operations.cc +++ b/source/differentiation/sd/symengine_scalar_operations.cc @@ -121,9 +121,49 @@ namespace Differentiation return false; } + + void + set_value_in_symbol_map( + types::substitution_map & substitution_map, + const SymEngine::RCP &symbol, + const SymEngine::RCP &value) + { + Assert( + internal::is_valid_substitution_symbol(*symbol), + ExcMessage( + "Substitution with a number that does not represent a symbol or symbolic derivative")); + + types::substitution_map::iterator it_sym = + substitution_map.find(Expression(symbol)); + Assert(it_sym != substitution_map.end(), + ExcMessage("Did not find this symbol in the map.")); + + it_sym->second = Expression(value); + } + } // namespace internal + void + set_value_in_symbol_map(types::substitution_map &substitution_map, + const Expression & symbol, + const Expression & value) + { + internal::set_value_in_symbol_map(substitution_map, + symbol.get_RCP(), + value.get_RCP()); + } + + + void + set_value_in_symbol_map(types::substitution_map & substitution_map, + const types::substitution_map &symbol_values) + { + for (const auto &entry : symbol_values) + set_value_in_symbol_map(substitution_map, entry.first, entry.second); + } + + /* ------------------ Symbol substitution map creation ----------------*/