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_HP_COARSENTEST_H
21 #define LIBMESH_HP_COARSENTEST_H
22 
23 // Local Includes
24 #include "libmesh/dense_matrix.h"
25 #include "libmesh/dense_vector.h"
26 #include "libmesh/hp_selector.h"
27 #include "libmesh/id_types.h"
28 #include "libmesh/libmesh_common.h"
29 #include "libmesh/fe.h"         // MipsPro requires fe.h and quadrature.h
30 #include "libmesh/quadrature.h" // Required for inline deletion std::unique_ptrs<> in destructor
31 
32 // C++ includes
33 #include <vector>
34 #include <memory>
35 
36 #ifdef LIBMESH_ENABLE_AMR
37 
38 namespace libMesh
39 {
40 
41 // Forward Declarations
42 class Elem;
43 class Point;
44 class System;
45 template <typename T> class TensorValue;
46 template <typename T> class VectorValue;
47 typedef VectorValue<Real> RealVectorValue;
48 typedef TensorValue<Real> RealTensorValue;
49 typedef RealVectorValue RealGradient;
50 typedef RealTensorValue RealTensor;
51 
52 
53 /**
54  * This class uses the error estimate given by different types of
55  * derefinement (h coarsening or p reduction) to choose between h
56  * refining and p elevation.
57  * Currently we assume that a set of elements has already been flagged
58  * for h refinement, and we may want to change some of those elements
59  * to be flagged for p refinement.
60  *
61  * This code is currently experimental and will not produce optimal
62  * hp meshes without significant improvement.
63  *
64  * \author Roy H. Stogner
65  * \date 2006
66  */
67 class HPCoarsenTest : public HPSelector
68 {
69 public:
70 
71   /**
72    * Constructor.
73    */
HPCoarsenTest()74   HPCoarsenTest() : p_weight(1.0)
75   {
76     libmesh_experimental();
77   }
78 
79   /**
80    * This class cannot be (default) copy constructed/assigned because
81    * it has unique_ptr members. Explicitly deleting these functions is
82    * the best way to document this fact.
83    */
84   HPCoarsenTest (const HPCoarsenTest &) = delete;
85   HPCoarsenTest & operator= (const HPCoarsenTest &) = delete;
86 
87   /**
88    * Defaulted move ctor, move assignment operator, and destructor.
89    */
90   HPCoarsenTest (HPCoarsenTest &&) = default;
91   HPCoarsenTest & operator= (HPCoarsenTest &&) = default;
92   virtual ~HPCoarsenTest() = default;
93 
94   /**
95    * This pure virtual function must be redefined
96    * in derived classes to take a mesh flagged for h
97    * refinement and potentially change the desired
98    * refinement type.
99    */
100   virtual void select_refinement (System & system) override;
101 
102   /**
103    * Because the coarsening test seems to always choose p refinement, we're
104    * providing an option to make h refinement more likely
105    */
106   Real p_weight;
107 
108 protected:
109   /**
110    * The helper function which adds individual fine element data to
111    * the coarse element projection
112    */
113   void add_projection(const System &, const Elem *, unsigned int var);
114 
115   /**
116    * The coarse element on which a solution projection is cached
117    */
118   Elem * coarse;
119 
120   /**
121    * Global DOF indices for fine elements
122    */
123   std::vector<dof_id_type> dof_indices;
124 
125   /**
126    * The finite element objects for fine and coarse elements
127    */
128   std::unique_ptr<FEBase> fe, fe_coarse;
129 
130   /**
131    * The shape functions and their derivatives
132    */
133   const std::vector<std::vector<Real>> * phi, * phi_coarse;
134   const std::vector<std::vector<RealGradient>> * dphi, * dphi_coarse;
135   const std::vector<std::vector<RealTensor>> * d2phi, * d2phi_coarse;
136 
137   /**
138    * Mapping jacobians
139    */
140   const std::vector<Real> * JxW;
141 
142   /**
143    * Quadrature locations
144    */
145   const std::vector<Point> * xyz_values;
146   std::vector<Point> coarse_qpoints;
147 
148   /**
149    * The quadrature rule for the fine element
150    */
151   std::unique_ptr<QBase> qrule;
152 
153   /**
154    * Linear system for projections
155    */
156   DenseMatrix<Number> Ke;
157   DenseVector<Number> Fe;
158   /**
159    * Coefficients for projected coarse and projected
160    * p-derefined solutions
161    */
162   DenseVector<Number> Uc;
163   DenseVector<Number> Up;
164 };
165 
166 } // namespace libMesh
167 
168 #endif // #ifdef LIBMESH_ENABLE_AMR
169 
170 #endif // LIBMESH_HP_COARSENTEST_H
171