1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2020 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17 
18 
19 
20 #ifndef LIBMESH_PATCH_RECOVERY_ERROR_ESTIMATOR_H
21 #define LIBMESH_PATCH_RECOVERY_ERROR_ESTIMATOR_H
22 
23 // Local Includes
24 #include "libmesh/error_estimator.h"
25 #include "libmesh/patch.h"
26 #include "libmesh/point.h"
27 #include "libmesh/elem_range.h"
28 
29 #ifdef LIBMESH_FORWARD_DECLARE_ENUMS
30 namespace libMesh
31 {
32 enum Order : int;
33 }
34 #else
35 #include "libmesh/enum_order.h"
36 #endif
37 
38 // C++ includes
39 #include <cstddef>
40 #include <vector>
41 
42 namespace libMesh
43 {
44 
45 // Forward Declarations
46 class Elem;
47 
48 /**
49  * This class implements the Patch Recovery error indicator.
50  *
51  * \author Varis Carey
52  * \author Benjamin S. Kirk
53  * \date 2004
54  */
55 class PatchRecoveryErrorEstimator : public ErrorEstimator
56 {
57 public:
58 
59   /**
60    * Constructor.  Defaults to H1 seminorm.  All Hilbert norms and
61    * seminorms should be supported now.  W1,p and W2,p norms would
62    * be natural to support if any contributors make the effort.
63    */
64   PatchRecoveryErrorEstimator();
65 
66   /**
67    * Copy/move ctor, copy/move assignment operator, and destructor are
68    * all explicitly defaulted for this class.
69    */
70   PatchRecoveryErrorEstimator (const PatchRecoveryErrorEstimator &) = default;
71   PatchRecoveryErrorEstimator (PatchRecoveryErrorEstimator &&) = default;
72   PatchRecoveryErrorEstimator & operator= (const PatchRecoveryErrorEstimator &) = default;
73   PatchRecoveryErrorEstimator & operator= (PatchRecoveryErrorEstimator &&) = default;
74   virtual ~PatchRecoveryErrorEstimator() = default;
75 
76   /**
77    * This function uses the Patch Recovery error
78    * estimate to estimate the error on each cell.
79    * The estimated error is output in the vector
80    * \p error_per_cell
81    */
82   virtual void estimate_error (const System & system,
83                                ErrorVector & error_per_cell,
84                                const NumericVector<Number> * solution_vector = nullptr,
85                                bool estimate_parent_error = false) override;
86 
87   /**
88    * The PatchErrorEstimator will build patches of at least this many
89    * elements to perform estimates
90    */
91   unsigned int target_patch_size;
92 
93   /**
94    * The PatchErrorEstimator will use this pointer to a Patch member
95    * function when growing patches.  The default strategy used is
96    * Patch::add_local_face_neighbors.
97    * Patch::add_local_point_neighbors may be more reliable but slower.
98    */
99   Patch::PMF patch_growth_strategy;
100 
101   void set_patch_reuse (bool);
102 
103   virtual ErrorEstimatorType type() const override;
104 
105 protected:
106 
107   /**
108    * \returns The spectral polynomial basis function values at a point (x,y,z).
109    */
110   static std::vector<Real> specpoly(const unsigned int dim,
111                                     const Order order,
112                                     const Point p,
113                                     const unsigned int matsize);
114 
115   bool patch_reuse;
116 
117 private:
118 
119   /**
120    * Class to compute the error contribution for a range
121    * of elements. May be executed in parallel on separate threads.
122    */
123   class EstimateError
124   {
125   public:
EstimateError(const System & sys,const PatchRecoveryErrorEstimator & ee,ErrorVector & epc)126     EstimateError (const System & sys,
127                    const PatchRecoveryErrorEstimator & ee,
128                    ErrorVector & epc) :
129       system(sys),
130       error_estimator(ee),
131       error_per_cell(epc)
132     {}
133 
134     void operator()(const ConstElemRange & range) const;
135 
136   private:
137     const System & system;
138     const PatchRecoveryErrorEstimator & error_estimator;
139     ErrorVector & error_per_cell;
140   };
141 
142   friend class EstimateError;
143 };
144 
145 
146 } // namespace libMesh
147 
148 
149 #endif // LIBMESH_PATCH_RECOVERY_ERROR_ESTIMATOR_H
150