]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Implement functions that add scalar & tensor valued symbols to symbol maps
authorJean-Paul Pelteret <jppelteret@gmail.com>
Sat, 4 May 2019 19:54:28 +0000 (21:54 +0200)
committerJean-Paul Pelteret <jppelteret@gmail.com>
Sat, 4 May 2019 21:24:30 +0000 (23:24 +0200)
include/deal.II/differentiation/sd/symengine_scalar_operations.h
include/deal.II/differentiation/sd/symengine_tensor_operations.h

index cb7b716bcc3e9e69ad9c0b03e57ef098f6609b3f..69adbca82ffbd6715eca6b07a3c72d658b76f341 100644 (file)
@@ -148,6 +148,151 @@ namespace Differentiation
       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);
+
     //@}
 
     /**
@@ -605,7 +750,85 @@ namespace Differentiation
 {
   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>
index 210ac2799f0d7cb905e3dce38ba7027740cc8708..37939475468e4eed75741796e1a5e5795e9f6e22 100644 (file)
@@ -366,6 +366,64 @@ namespace Differentiation
 
     //@}
 
+    /**
+     * @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
      */
@@ -849,7 +907,37 @@ namespace Differentiation
     }
 
 
-    /* ---------------- 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>

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.