]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Implement functions to set values in symbol maps
authorJean-Paul Pelteret <jppelteret@gmail.com>
Sat, 4 May 2019 19:57:16 +0000 (21:57 +0200)
committerJean-Paul Pelteret <jppelteret@gmail.com>
Sun, 5 May 2019 13:42:24 +0000 (15:42 +0200)
include/deal.II/differentiation/sd/symengine_scalar_operations.h
include/deal.II/differentiation/sd/symengine_tensor_operations.h
source/differentiation/sd/symengine_scalar_operations.cc

index a2e6a87b1feedd2ca71d7e74eb463fdf46d0b0e2..0c3186baf81d50c86cc03002ec298113ee1765b8 100644 (file)
@@ -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<const SymEngine::Basic> &symbol,
+        const SymEngine::RCP<const SymEngine::Basic> &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 <typename SymbolicType = SD::Expression,
+              typename ValueType,
+              typename = typename std::enable_if<
+                dealii::internal::is_explicitly_convertible<
+                  SymbolicType,
+                  const SymEngine::RCP<const SymEngine::Basic> &>::value &&
+                std::is_constructible<SymbolicType, ValueType>::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 <typename SymbolicType = SD::Expression, typename ValueType>
+    void
+    set_value_in_symbol_map(types::substitution_map &        substitution_map,
+                            const std::vector<SymbolicType> &symbols,
+                            const std::vector<ValueType> &   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 <typename SymbolicType = SD::Expression, typename ValueType>
+    void
+    set_value_in_symbol_map(
+      types::substitution_map &                 substitution_map,
+      const std::pair<SymbolicType, ValueType> &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 <typename SymbolicType = SD::Expression,
+              typename ValueType,
+              typename... Args>
+    void
+    set_value_in_symbol_map(
+      types::substitution_map &                 substitution_map,
+      const std::pair<SymbolicType, ValueType> &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 <typename SymbolicType = SD::Expression, typename ValueType>
+    void
+    set_value_in_symbol_map(
+      types::substitution_map &                              substitution_map,
+      const std::vector<std::pair<SymbolicType, ValueType>> &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 <typename ExpressionType, typename ValueType, typename>
+    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<const SymEngine::Basic> &;
+      internal::set_value_in_symbol_map(substitution_map,
+                                        static_cast<SE_RCP_Basic>(symbol),
+                                        static_cast<SE_RCP_Basic>(
+                                          ExpressionType(value)));
+    }
+
+
+    template <typename SymbolicType, typename ValueType>
+    void
+    set_value_in_symbol_map(types::substitution_map &        substitution_map,
+                            const std::vector<SymbolicType> &symbols,
+                            const std::vector<ValueType> &   values)
+    {
+      Assert(symbols.size() == values.size(),
+             ExcDimensionMismatch(symbols.size(), values.size()));
+
+      typename std::vector<SymbolicType>::const_iterator it_symb =
+        symbols.begin();
+      typename std::vector<ValueType>::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 <typename SymbolicType, typename ValueType>
+    void
+    set_value_in_symbol_map(
+      types::substitution_map &                 substitution_map,
+      const std::pair<SymbolicType, ValueType> &symbol_value)
+    {
+      set_value_in_symbol_map(substitution_map,
+                              symbol_value.first,
+                              symbol_value.second);
+    }
+
+
+    template <typename SymbolicType, typename ValueType, typename... Args>
+    void
+    set_value_in_symbol_map(
+      types::substitution_map &                 substitution_map,
+      const std::pair<SymbolicType, ValueType> &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 <typename SymbolicType, typename ValueType>
+    void
+    set_value_in_symbol_map(
+      types::substitution_map &                              substitution_map,
+      const std::vector<std::pair<SymbolicType, ValueType>> &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 ----------------*/
 
 
index 37939475468e4eed75741796e1a5e5795e9f6e22..c042e119162cd043c356c3e813ba5f2a55b7c03c 100644 (file)
@@ -422,6 +422,37 @@ namespace Differentiation
       types::substitution_map &                     symbol_map,
       const SymmetricTensor<rank, dim, Expression> &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 <int rank, int dim, typename ValueType>
+    void
+    set_value_in_symbol_map(types::substitution_map &substitution_map,
+                            const Tensor<rank, dim, Expression> &symbol_tensor,
+                            const Tensor<rank, dim, ValueType> & 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 <int rank, int dim, typename ValueType>
+    void
+    set_value_in_symbol_map(
+      types::substitution_map &                     substitution_map,
+      const SymmetricTensor<rank, dim, Expression> &symbol_tensor,
+      const SymmetricTensor<rank, dim, ValueType> & value_tensor);
+
     //@}
 
     /**
@@ -908,6 +939,57 @@ namespace Differentiation
 
 
     /* ---------------- Symbol map creation and manipulation --------------*/
+
+
+    namespace internal
+    {
+      template <typename ValueType,
+                int rank,
+                int dim,
+                template <int, int, typename> class TensorType>
+      void
+      tensor_set_value_in_symbol_map(
+        types::substitution_map &                substitution_map,
+        const TensorType<rank, dim, Expression> &symbol_tensor,
+        const TensorType<rank, dim, ValueType> & value_tensor)
+      {
+        TensorType<rank, dim, Expression> out;
+        for (unsigned int i = 0; i < out.n_independent_components; ++i)
+          {
+            const TableIndices<rank> indices(
+              out.unrolled_to_component_indices(i));
+            set_value_in_symbol_map(substitution_map,
+                                    symbol_tensor[indices],
+                                    value_tensor[indices]);
+          }
+      }
+
+
+      template <typename ValueType, int dim>
+      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<dim>(i, j);
+              set_value_in_symbol_map(substitution_map,
+                                      symbol_tensor[indices],
+                                      value_tensor[indices]);
+            }
+      }
+    } // namespace internal
+
+
     template <bool ignore_invalid_symbols,
               int  rank,
               int  dim,
@@ -937,6 +1019,31 @@ namespace Differentiation
     }
 
 
+    template <int rank, int dim, typename ValueType>
+    void
+    set_value_in_symbol_map(types::substitution_map &substitution_map,
+                            const Tensor<rank, dim, Expression> &symbol_tensor,
+                            const Tensor<rank, dim, ValueType> & value_tensor)
+    {
+      internal::tensor_set_value_in_symbol_map(substitution_map,
+                                               symbol_tensor,
+                                               value_tensor);
+    }
+
+
+    template <int rank, int dim, typename ValueType>
+    void
+    set_value_in_symbol_map(
+      types::substitution_map &                     substitution_map,
+      const SymmetricTensor<rank, dim, Expression> &symbol_tensor,
+      const SymmetricTensor<rank, dim, ValueType> & value_tensor)
+    {
+      internal::tensor_set_value_in_symbol_map(substitution_map,
+                                               symbol_tensor,
+                                               value_tensor);
+    }
+
+
     /* ------------------ Symbol substitution map creation ----------------*/
 
 
index da5fd647b89dd9a4dd435b389298f3af8588e257..ae0bfb7c92835a77c2e2d2fcd49559007847101d 100644 (file)
@@ -121,9 +121,49 @@ namespace Differentiation
         return false;
       }
 
+
+      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)
+      {
+        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 ----------------*/
 
 

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.