is_valid_substitution_symbol(const SymEngine::Basic &entry);
} // namespace internal
+ /**
+ * A convenience function for an adding empty entry, with the key value
+ * given by @p symbol, to the symbolic map @p substitution_map.
+ *
+ * This function is guaranteed to create an ordering that is identical
+ * to the typical add_to_substitution_map() call that is used when
+ * constructing a map to to perform symbol substitution.
+ * It exists primarily to create an initial map that can be used in the
+ * optimize() call to a BatchOptimizer, specifically if the values that
+ * are to be substituted into the map are not known at the time that the
+ * symbols used to construct symbolic expressions are defined.
+ * This helps one conform to the requirement that the arguments sent into
+ * lambda and LLVM JIT compiled functions (created by optimizing symbolic
+ * expressions) (i) be the same, and (ii) have a constant ordering.
+ *
+ * @tparam ignore_invalid_symbols A template parameter that enforces whether
+ * or not the @p symbol has to be a valid one or not. In the
+ * overwhelming majority of cases, the default value of
+ * <tt>false</tt> should be selected, with the result that an
+ * exception will be thrown if the input @p symbolic is, in fact,
+ * not a symbolic value or expression.
+ * An exceptional case is, for example, when performing symbolic
+ * assembly on a finite element level. When extracting the symbolic
+ * equivalent of the shape function gradients using FEExtractors,
+ * the returned tensor will have some <em>a priori</em> determined
+ * zero-valued components. These trivial components are not valid
+ * symbols (as they are not symbolic expressions), and we would
+ * typically wish to guard against their (erroneous) inclusion. In
+ * this scenario, for convenience, one could set
+ * @p ignore_invalid_symbols to <tt>true</tt> and these zero-valued
+ * entries would be skipped over and ignored.
+ *
+ * @note In this function, the @p ValueType is somewhat arbitrary as
+ * it is only used to create dummy values.
+ */
+ template <bool ignore_invalid_symbols = false, typename ValueType = double>
+ void
+ add_to_symbol_map(types::substitution_map &symbol_map,
+ const Expression & symbol);
+
+ /**
+ * A convenience function for an adding empty entry, with the key value
+ * given by @p symbol, to the symbolic map @p substitution_map.
+ *
+ * For more context which this function is used, see the other
+ * \ref add_to_symbol_map(types::substitution_map &,const
+ * Expression &) function.
+ *
+ * @tparam ignore_invalid_symbols See the other
+ * \ref add_to_symbol_map(types::substitution_map &,const
+ * Expression &) function for a detailed discussion on the role of this
+ * template argument.
+ *
+ * @note In this function, the @p ValueType is somewhat arbitrary as
+ * it is only used to create dummy values.
+ */
+ template <bool ignore_invalid_symbols = false,
+ typename SymbolicType = SD::Expression,
+ typename ValueType = double,
+ typename = typename std::enable_if<
+ !std::is_base_of<Expression, SymbolicType>::value &&
+ dealii::internal::is_explicitly_convertible<
+ SymbolicType,
+ const SymEngine::RCP<const SymEngine::Basic> &>::value>::type>
+ void
+ add_to_symbol_map(types::substitution_map &symbol_map,
+ const SymbolicType & symbol);
+
+ /**
+ * A convenience function for adding empty entries, with the key values
+ * equal to the entries in @p symbols, to the symbolic map @p symbol_map.
+ * It is expected that all entries in the input vector @p symbols be
+ * of @p SymbolicType, compatible with the other add_to_symbol_map()
+ * functions.
+ *
+ * For more context which this function is used, see the other
+ * \ref add_to_symbol_map(types::substitution_map &,const
+ * Expression &) function.
+ *
+ * @tparam ignore_invalid_symbols See the other
+ * \ref add_to_symbol_map(types::substitution_map &,const
+ * Expression &) function for a detailed discussion on the role of this
+ * template argument.
+ */
+ template <bool ignore_invalid_symbols = false, typename SymbolicType>
+ void
+ add_to_symbol_map(types::substitution_map & symbol_map,
+ const std::vector<SymbolicType> &symbols);
+
+ /**
+ * A convenience function for adding empty entries, with the key values
+ * equal to the key entries in @p other_symbols, to the symbolic
+ * map @p symbol_map.
+ *
+ * For more context which this function is used, see the other
+ * \ref add_to_symbol_map(types::substitution_map &,const
+ * Expression &) function.
+ *
+ * @tparam ignore_invalid_symbols See the other
+ * \ref add_to_symbol_map(types::substitution_map &,const
+ * Expression &) function for a detailed discussion on the role of this
+ * template argument.
+ */
+ template <bool ignore_invalid_symbols = false>
+ void
+ add_to_symbol_map(types::substitution_map & symbol_map,
+ const types::substitution_map &other_symbols);
+
+ /**
+ * A convenience function for adding empty entries, with the key values
+ * equal to the entries in @p symbol plus @p other_symbols, to the symbolic
+ * map @p symbol_map.
+ * It is expected that all entries in @p symbol and @p other_symbols be
+ * of a @p SymbolicType, compatible with the other add_to_symbol_map()
+ * functions.
+ *
+ * For more context which this function is used, see the other
+ * \ref add_to_symbol_map(types::substitution_map &,const
+ * Expression &) function.
+ *
+ * With this function it is possible to add entries from different types
+ * to a symbolic map. An example may be as follows:
+ *
+ * @code
+ * types::substitution_map symbol_map = ...;
+ * add_to_symbol_map(
+ * symbol_map,
+ * Expression(...),
+ * Tensor<1,dim,Expression>(...),
+ * SymmetricTensor<2,dim,Expression>(...));
+ * @endcode
+ *
+ * @tparam ignore_invalid_symbols See the other
+ * \ref add_to_symbol_map(types::substitution_map &,const
+ * Expression &) function for a detailed discussion on the role of this
+ * template argument.
+ */
+ template <bool ignore_invalid_symbols = false,
+ typename SymbolicType,
+ typename... Args>
+ void
+ add_to_symbol_map(types::substitution_map &symbol_map,
+ const SymbolicType & symbol,
+ const Args &... other_symbols);
+
//@}
/**
{
namespace SD
{
- /* ---------------- Symbolic substitution map creation --------------*/
+ /* ---------------- Symbol map creation and manipulation --------------*/
+
+
+ template <bool ignore_invalid_symbols, typename ValueType>
+ void
+ add_to_symbol_map(types::substitution_map &symbol_map,
+ const Expression & symbol)
+ {
+ // Call the above function
+ add_to_substitution_map<ignore_invalid_symbols>(
+ symbol_map,
+ symbol,
+ dealii::internal::NumberType<ValueType>::value(0.0));
+ }
+
+
+ template <bool ignore_invalid_symbols,
+ typename SymbolicType,
+ typename ValueType,
+ typename>
+ void
+ add_to_symbol_map(types::substitution_map &symbol_map,
+ const SymbolicType & symbol)
+ {
+ // Call the above function
+ using SE_RCP_Basic = const SymEngine::RCP<const SymEngine::Basic> &;
+ add_to_substitution_map<ignore_invalid_symbols>(
+ symbol_map,
+ static_cast<SE_RCP_Basic>(symbol),
+ dealii::internal::NumberType<ValueType>::value(0.0));
+ }
+
+
+ template <bool ignore_invalid_symbols, typename SymbolicType>
+ void
+ add_to_symbol_map(types::substitution_map & symbol_map,
+ const std::vector<SymbolicType> &symbols)
+ {
+ for (const auto &symbol : symbols)
+ add_to_symbol_map<ignore_invalid_symbols>(symbol_map, symbol);
+ }
+
+
+ template <bool ignore_invalid_symbols>
+ void
+ add_to_symbol_map(types::substitution_map & symbol_map,
+ const types::substitution_map &other_symbols)
+ {
+ // We should be cautious as to whether or not the user has
+ // hand-made the other_symbols map to be "merged" in.
+ // So instead of blindly merging using the merge_substitution_maps()
+ // function, we do it by hand and check for invalid symbols
+ // if required.
+ for (types::substitution_map::const_iterator it = other_symbols.begin();
+ it != other_symbols.end();
+ ++it)
+ {
+ Assert(symbol_map.find(it->first) == symbol_map.end(),
+ ExcMessage("Entry already exists in symbol map"));
+ add_to_symbol_map<ignore_invalid_symbols>(symbol_map,
+ Expression(it->first));
+ }
+ }
+
+
+ template <bool ignore_invalid_symbols,
+ typename SymbolicType,
+ typename... Args>
+ void
+ add_to_symbol_map(types::substitution_map &symbol_map,
+ const SymbolicType & symbol,
+ const Args &... other_symbols)
+ {
+ add_to_symbol_map<ignore_invalid_symbols>(symbol_map, symbol);
+ add_to_symbol_map<ignore_invalid_symbols>(symbol_map, other_symbols...);
+ }
+
+
+ /* ------------------ Symbol substitution map creation ----------------*/
template <typename ValueType>
//@}
+ /**
+ * @name Symbol map creation and manipulation
+ */
+ //@{
+
+ /**
+ * A convenience function for adding empty entries, with the key values
+ * equal to the entries in the @p symbol_tensor, to the symbolic
+ * map @p symbol_map.
+ *
+ * For more context which this function is used, see the other
+ * \ref add_to_symbol_map(types::substitution_map &,const
+ * Expression &) function.
+ *
+ * @tparam ignore_invalid_symbols See the other
+ * \ref add_to_symbol_map(types::substitution_map &,const
+ * Expression &) function for a detailed discussion on the role of this
+ * template argument.
+ *
+ * @note In this function, the @p ValueType is somewhat arbitrary as
+ * it is only used to create dummy values.
+ */
+ template <bool ignore_invalid_symbols = false,
+ int rank,
+ int dim,
+ typename ValueType = double>
+ void
+ add_to_symbol_map(types::substitution_map & symbol_map,
+ const Tensor<rank, dim, Expression> &symbol_tensor);
+
+ /**
+ * A convenience function for adding empty entries, with the key values
+ * equal to the entries in the @p symbol_tensor, to the symbolic
+ * map @p symbol_map.
+ *
+ * For more context which this function is used, see the other
+ * \ref add_to_symbol_map(types::substitution_map &,const
+ * Expression &) function.
+ *
+ * @tparam ignore_invalid_symbols See the other
+ * \ref add_to_symbol_map(types::substitution_map &,const
+ * Expression &) function for a detailed discussion on the role of this
+ * template argument.
+ *
+ * @note In this function, the @p ValueType is somewhat arbitrary as
+ * it is only used to create dummy values.
+ */
+ template <bool ignore_invalid_symbols = false,
+ int rank,
+ int dim,
+ typename ValueType = double>
+ void
+ add_to_symbol_map(
+ types::substitution_map & symbol_map,
+ const SymmetricTensor<rank, dim, Expression> &symbol_tensor);
+
+ //@}
+
/**
* @name Symbol substitution map creation
*/
}
- /* ---------------- Symbolic substitution map creation --------------*/
+ /* ---------------- Symbol map creation and manipulation --------------*/
+ template <bool ignore_invalid_symbols,
+ int rank,
+ int dim,
+ typename ValueType>
+ void
+ add_to_symbol_map(types::substitution_map & symbol_map,
+ const Tensor<rank, dim, Expression> &symbol_tensor)
+ {
+ // Call the above function
+ add_to_substitution_map<ignore_invalid_symbols>(
+ symbol_map, symbol_tensor, Tensor<rank, dim, ValueType>());
+ }
+
+
+ template <bool ignore_invalid_symbols,
+ int rank,
+ int dim,
+ typename ValueType>
+ void
+ add_to_symbol_map(
+ types::substitution_map & symbol_map,
+ const SymmetricTensor<rank, dim, Expression> &symbol_tensor)
+ {
+ // Call the above function
+ add_to_substitution_map<ignore_invalid_symbols>(
+ symbol_map, symbol_tensor, SymmetricTensor<rank, dim, ValueType>());
+ }
+
+
+ /* ------------------ Symbol substitution map creation ----------------*/
template <int rank, int dim, typename ValueType>