]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Add a new muParser function base class.
authorDavid Wells <drwells@email.unc.edu>
Sat, 21 May 2022 03:23:13 +0000 (23:23 -0400)
committerDavid Wells <drwells@email.unc.edu>
Sat, 21 May 2022 19:45:42 +0000 (15:45 -0400)
include/deal.II/base/function_parser.h
include/deal.II/base/mu_parser_internal.h
include/deal.II/base/tensor_function_parser.h
source/base/function_parser.cc
source/base/tensor_function_parser.cc

index 2e0934baf432453e285d511de9b5154acdf34d39..da8d955e58d6ceedcfad323b5586877b94df37bb 100644 (file)
@@ -24,6 +24,7 @@
 #include <deal.II/base/point.h>
 #include <deal.II/base/tensor.h>
 #include <deal.II/base/thread_local_storage.h>
+#include <deal.II/base/mu_parser_internal.h>
 
 #include <map>
 #include <memory>
@@ -37,22 +38,6 @@ template <typename>
 class Vector;
 #endif
 
-namespace internal
-{
-  /**
-   * deal.II uses muParser as a purely internal dependency. To this end, we do
-   * not include any muParser headers in this file (and the bundled version of
-   * the dependency does not install its headers or compile a separate muparser
-   * library). Hence, to interface with muParser, we use the PIMPL idiom here to
-   * wrap a pointer to mu::Parser objects.
-   */
-  class muParserBase
-  {
-  public:
-    virtual ~muParserBase() = default;
-  };
-} // namespace internal
-
 /**
  * This class implements a function object that gets its value by parsing a
  * string describing this function. It is a wrapper class for the muparser
@@ -396,48 +381,12 @@ public:
   //@}
 
 private:
-  /**
-   * Class containing the mutable state required by muParser.
-   *
-   * @note For performance reasons it is best to put all mutable state in a
-   * single object so that, for each function call, we only need to get
-   * thread-local data exactly once.
-   */
-  struct ParserData
-  {
-    /**
-     * Default constructor. Threads::ThreadLocalStorage requires that objects be
-     * either default- or copy-constructible: make sure we satisfy the first
-     * case by declaring it here.
-     */
-    ParserData() = default;
-
-    /**
-     * std::is_copy_constructible gives the wrong answer for containers with
-     * non-copy constructible types (e.g., std::vector<std::unique_ptr<int>>) -
-     * for more information, see the documentation of
-     * Threads::ThreadLocalStorage. Hence, to avoid compilation failures, just
-     * delete the copy constructor completely.
-     */
-    ParserData(const ParserData &) = delete;
-
-    /**
-     * Scratch array used to set independent variables (i.e., x, y, and t)
-     * before each muParser call.
-     */
-    std::vector<double> vars;
-
-    /**
-     * The actual muParser parser objects (hidden with PIMPL).
-     */
-    std::vector<std::unique_ptr<internal::muParserBase>> parsers;
-  };
-
   /**
    * The muParser objects (hidden with the PIMPL idiom) for each thread (and one
    * for each component).
    */
-  mutable Threads::ThreadLocalStorage<ParserData> parser_data;
+  mutable Threads::ThreadLocalStorage<internal::FunctionParser::ParserData>
+    parser_data;
 
   /**
    * An array to keep track of all the constants, required to initialize fp in
index d068ccd895c37862854b5e779b6ff473d0745242..46a7d6c77cb443c07a8ccf6f399b385b5b0505bc 100644 (file)
@@ -35,6 +35,56 @@ namespace internal
 {
   namespace FunctionParser
   {
+    /**
+     * deal.II uses muParser as a purely internal dependency. To this end, we do
+     * not include any muParser headers in our own headers (and the bundled
+     * version of the dependency does not install its headers or compile a
+     * separate muparser library). Hence, to interface with muParser, we use the
+     * PIMPL idiom here to wrap a pointer to mu::Parser objects.
+     */
+    class muParserBase
+    {
+    public:
+      virtual ~muParserBase() = default;
+    };
+
+    /**
+     * Class containing the mutable state required by muParser.
+     *
+     * @note For performance reasons it is best to put all mutable state in a
+     * single object so that, for each function call, we only need to get
+     * thread-local data exactly once.
+     */
+    struct ParserData
+    {
+      /**
+       * Default constructor. Threads::ThreadLocalStorage requires that objects
+       * be either default- or copy-constructible: make sure we satisfy the
+       * first case by declaring it here.
+       */
+      ParserData() = default;
+
+      /**
+       * std::is_copy_constructible gives the wrong answer for containers with
+       * non-copy constructible types (e.g., std::vector<std::unique_ptr<int>>)
+       * - for more information, see the documentation of
+       * Threads::ThreadLocalStorage. Hence, to avoid compilation failures, just
+       * delete the copy constructor completely.
+       */
+      ParserData(const ParserData &) = delete;
+
+      /**
+       * Scratch array used to set independent variables (i.e., x, y, and t)
+       * before each muParser call.
+       */
+      std::vector<double> vars;
+
+      /**
+       * The actual muParser parser objects (hidden with PIMPL).
+       */
+      std::vector<std::unique_ptr<muParserBase>> parsers;
+    };
+
     int
     mu_round(double val);
 
index d86377ee44c49270ea26890ef9258e3ce6dc2e39..eba3e486e56e04377754231d413d95a9c34cbbd1 100644 (file)
@@ -25,6 +25,7 @@
 #include <deal.II/base/tensor.h>
 #include <deal.II/base/tensor_function.h>
 #include <deal.II/base/thread_local_storage.h>
+#include <deal.II/base/mu_parser_internal.h>
 
 #include <map>
 #include <memory>
@@ -262,48 +263,12 @@ public:
   //@}
 
 private:
-  /**
-   * Class containing the mutable state required by muParser.
-   *
-   * @note For performance reasons it is best to put all mutable state in a
-   * single object so that, for each function call, we only need to get
-   * thread-local data exactly once.
-   */
-  struct ParserData
-  {
-    /**
-     * Default constructor. Threads::ThreadLocalStorage requires that objects be
-     * either default- or copy-constructible: make sure we satisfy the first
-     * case by declaring it here.
-     */
-    ParserData() = default;
-
-    /**
-     * std::is_copy_constructible gives the wrong answer for containers with
-     * non-copy constructible types (e.g., std::vector<std::unique_ptr<int>>) -
-     * for more information, see the documentation of
-     * Threads::ThreadLocalStorage. Hence, to avoid compilation failures, just
-     * delete the copy constructor completely.
-     */
-    ParserData(const ParserData &) = delete;
-
-    /**
-     * Scratch array used to set independent variables (i.e., x, y, and t)
-     * before each muParser call.
-     */
-    std::vector<double> vars;
-
-    /**
-     * The actual muParser parser objects (hidden with PIMPL).
-     */
-    std::vector<std::unique_ptr<internal::muParserBase>> parsers;
-  };
-
   /**
    * The muParser objects (hidden with the PIMPL idiom) for each thread (and one
    * for each component).
    */
-  mutable Threads::ThreadLocalStorage<ParserData> parser_data;
+  mutable Threads::ThreadLocalStorage<internal::FunctionParser::ParserData>
+    parser_data;
 
   /**
    * An array to keep track of all the constants, required to initialize tfp in
index 973bb569d39d0556e56f2d83c904d0e27880f56f..c45d69f70f8e1cf6dfb23061064dc190b638c97d 100644 (file)
@@ -130,7 +130,7 @@ namespace internal
       /**
        * PIMPL for mu::Parser.
        */
-      class Parser : public internal::muParserBase
+      class Parser : public internal::FunctionParser::muParserBase
       {
       public:
         operator mu::Parser &()
@@ -158,7 +158,7 @@ FunctionParser<dim>::init_muparser() const
   // check that we have not already initialized the parser on the
   // current thread, i.e., that the current function is only called
   // once per thread
-  ParserData &data = parser_data.get();
+  internal::FunctionParser::ParserData &data = parser_data.get();
   Assert(data.parsers.size() == 0 && data.vars.size() == 0, ExcInternalError());
 
   // initialize the objects for the current thread
@@ -280,7 +280,7 @@ FunctionParser<dim>::value(const Point<dim> & p,
   AssertIndexRange(component, this->n_components);
 
   // initialize the parser if that hasn't happened yet on the current thread
-  ParserData &data = parser_data.get();
+  internal::FunctionParser::ParserData &data = parser_data.get();
   if (data.vars.size() == 0)
     init_muparser();
 
@@ -327,7 +327,7 @@ FunctionParser<dim>::vector_value(const Point<dim> &p,
 
 
   // initialize the parser if that hasn't happened yet on the current thread
-  ParserData &data = parser_data.get();
+  internal::FunctionParser::ParserData &data = parser_data.get();
   if (data.vars.size() == 0)
     init_muparser();
 
index c6d6aa0fdd5639576dce7838f0c2a60e70e7d492..2447d7b501dd7049a1d2e0bf2849a24b7c363f61 100644 (file)
@@ -144,7 +144,7 @@ namespace internal
       /**
        * PIMPL for mu::Parser.
        */
-      class Parser : public internal::muParserBase
+      class Parser : public internal::FunctionParser::muParserBase
       {
       public:
         operator mu::Parser &()
@@ -173,7 +173,7 @@ TensorFunctionParser<rank, dim, Number>::init_muparser() const
   // check that we have not already initialized the parser on the
   // current thread, i.e., that the current function is only called
   // once per thread
-  ParserData &data = parser_data.get();
+  internal::FunctionParser::ParserData &data = parser_data.get();
   Assert(data.parsers.size() == 0 && data.vars.size() == 0, ExcInternalError());
 
   // initialize the objects for the current thread
@@ -294,7 +294,7 @@ TensorFunctionParser<rank, dim, Number>::value(const Point<dim> &p) const
   Assert(initialized == true, ExcNotInitialized());
 
   // initialize the parser if that hasn't happened yet on the current thread
-  ParserData &data = parser_data.get();
+  internal::FunctionParser::ParserData &data = parser_data.get();
   if (data.vars.size() == 0)
     init_muparser();
 

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.