hp_refineable_elements.h
Go to the documentation of this file.
1 // LIC// ====================================================================
2 // LIC// This file forms part of oomph-lib, the object-oriented,
3 // LIC// multi-physics finite-element library, available
4 // LIC// at http://www.oomph-lib.org.
5 // LIC//
6 // LIC// Copyright (C) 2006-2023 Matthias Heil and Andrew Hazel
7 // LIC//
8 // LIC// This library is free software; you can redistribute it and/or
9 // LIC// modify it under the terms of the GNU Lesser General Public
10 // LIC// License as published by the Free Software Foundation; either
11 // LIC// version 2.1 of the License, or (at your option) any later version.
12 // LIC//
13 // LIC// This library is distributed in the hope that it will be useful,
14 // LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // LIC// Lesser General Public License for more details.
17 // LIC//
18 // LIC// You should have received a copy of the GNU Lesser General Public
19 // LIC// License along with this library; if not, write to the Free Software
20 // LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 // LIC// 02110-1301 USA.
22 // LIC//
23 // LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
24 // LIC//
25 // LIC//====================================================================
26 // Header file for classes that define hp-refineable element objects
27 
28 // Include guard to prevent multiple inclusions of the header
29 #ifndef OOMPH_HP_REFINEABLE_ELEMENTS_HEADER
30 #define OOMPH_HP_REFINEABLE_ELEMENTS_HEADER
31 
32 // Config header generated by autoconfig
33 #ifdef HAVE_CONFIG_H
34 #include <oomph-lib-config.h>
35 #endif
36 
37 #include "refineable_elements.h"
41 #include "mesh.h"
42 
43 namespace oomph
44 {
45  //======================================================================
46  /// p-refineable version of RefineableQElement<1,INITIAL_NNODE_1D>.
47  /// Generic class definitions
48  //======================================================================
49  template<unsigned INITIAL_NNODE_1D>
50  class PRefineableQElement<1, INITIAL_NNODE_1D>
51  : public RefineableQElement<1>,
52  public virtual QElement<1, INITIAL_NNODE_1D>,
53  public virtual PRefineableElement
54  {
55  public:
56  /// Constructor
58 
59  /// Destructor
60  virtual ~PRefineableQElement() {}
61 
62  /// Initial setup of element (set the correct p-order and
63  /// integration scheme) If an adopted father is specified, information
64  /// from this is used instead of using the father found from the tree.
65  void initial_setup(Tree* const& adopted_father_pt = 0,
66  const unsigned& initial_p_order = 0);
67 
68  /// Pre-build (search father for required nodes which may already
69  /// exist)
70  void pre_build(Mesh*& mesh_pt, Vector<Node*>& new_node_pt);
71 
72  /// p-refine the element (refine if inc>0, unrefine if inc<0).
73  void p_refine(const int& inc,
74  Mesh* const& mesh_pt,
75  GeneralisedElement* const& clone_pt);
76 
77  /// Overload the shape functions
78  void shape(const Vector<double>& s, Shape& psi) const;
79 
80  void dshape_local(const Vector<double>& s, Shape& psi, DShape& dpsi) const;
81 
82  void d2shape_local(const Vector<double>& s,
83  Shape& psi,
84  DShape& dpsids,
85  DShape& d2psids) const;
86 
87  /// Perform additional hanging node procedures for variables
88  /// that are not interpolated by all nodes (e.g. lower order interpolations
89  /// for the pressure in Taylor Hood).
91 
92  /// Returns the number of nodes along each edge of the element.
93  /// Overloaded to return the (variable) p-order rather than the template
94  /// argument.
95  unsigned nnode_1d() const
96  {
97  return this->p_order();
98  }
99 
100  /// Get the initial P_order
101  unsigned initial_p_order() const
102  {
103  return INITIAL_NNODE_1D;
104  }
105 
106  // Overloaded from QElement<1,NNODE_1D> to use nnode_1d() instead of
107  // template argument.
108  Node* get_node_at_local_coordinate(const Vector<double>& s) const;
109 
110  Node* node_created_by_son_of_neighbour(const Vector<double>& s_fraction,
111  bool& is_periodic);
112 
113  // Overload nodal positions -- these elements have GLL-spaced nodes.
114  /// Get local coordinates of node j in the element; vector sets its own size
115  void local_coordinate_of_node(const unsigned& n, Vector<double>& s) const;
116 
117  /// Get the local fractino of node j in the element
118  void local_fraction_of_node(const unsigned& n, Vector<double>& s_fraction);
119 
120  /// The local one-d fraction is the same
121  double local_one_d_fraction_of_node(const unsigned& n1d, const unsigned& i);
122 
123  /// Rebuild the element. This needs to find any nodes in the sons which
124  /// are still required.
125  void rebuild_from_sons(Mesh*& mesh_pt);
126 
127  /// Check the integrity of interpolated values across element
128  /// boundaries.
129  void check_integrity(double& max_error);
130 
131  protected:
132  /// Set up hanging node information. Empty for 1D elements.
133  void binary_hang_helper(const int& value_id,
134  const int& my_edge,
135  std::ofstream& output_hangfile);
136  };
137 
138  //=======================================================================
139  /// p-refineable version of RefineableQElement<2,INITIAL_NNODE_1D>.
140  //=======================================================================
141  template<unsigned INITIAL_NNODE_1D>
142  class PRefineableQElement<2, INITIAL_NNODE_1D>
143  : public RefineableQElement<2>,
144  public virtual QElement<2, INITIAL_NNODE_1D>,
145  public virtual PRefineableElement
146  {
147  public:
148  /// Constructor
150 
151  /// Destructor
152  virtual ~PRefineableQElement() {}
153 
154  /// Initial setup of element (set the correct p-order and
155  /// integration scheme) If an adopted father is specified, information
156  /// from this is used instead of using the father found from the tree.
157  void initial_setup(Tree* const& adopted_father_pt = 0,
158  const unsigned& initial_p_order = 0);
159 
160  /// Pre-build (search father for required nodes which may already
161  /// exist)
162  void pre_build(Mesh*& mesh_pt, Vector<Node*>& new_node_pt);
163 
164  /// p-refine the element (refine if inc>0, unrefine if inc<0).
165  void p_refine(const int& inc,
166  Mesh* const& mesh_pt,
167  GeneralisedElement* const& clone_pt);
168 
169  /// Overload the shape functions
170  void shape(const Vector<double>& s, Shape& psi) const;
171 
172  void dshape_local(const Vector<double>& s, Shape& psi, DShape& dpsi) const;
173 
174  void d2shape_local(const Vector<double>& s,
175  Shape& psi,
176  DShape& dpsids,
177  DShape& d2psids) const;
178 
179  /// Perform additional hanging node procedures for variables
180  /// that are not interpolated by all nodes (e.g. lower order interpolations
181  /// for the pressure in Taylor Hood).
183 
184  /// Returns the number of nodes along each edge of the element.
185  /// Overloaded to return the (variable) p-order rather than the template
186  /// argument.
187  unsigned nnode_1d() const
188  {
189  return this->p_order();
190  }
191 
192  /// Get the initial P_order
193  unsigned initial_p_order() const
194  {
195  return INITIAL_NNODE_1D;
196  }
197 
198  // Overloaded from QElement<2,NNODE_1D> to use nnode_1d() instead of
199  // template argument.
200  Node* get_node_at_local_coordinate(const Vector<double>& s) const;
201 
202  Node* node_created_by_neighbour(const Vector<double>& s_fraction,
203  bool& is_periodic);
204 
205  Node* node_created_by_son_of_neighbour(const Vector<double>& s_fraction,
206  bool& is_periodic);
207 
208  // Overload nodal positions -- these elements have GLL-spaced nodes.
209  /// Get local coordinates of node j in the element; vector sets its own size
210  void local_coordinate_of_node(const unsigned& n, Vector<double>& s) const;
211 
212  /// Get the local fractino of node j in the element
213  void local_fraction_of_node(const unsigned& n, Vector<double>& s_fraction);
214 
215  /// The local one-d fraction is the same
216  double local_one_d_fraction_of_node(const unsigned& n1d, const unsigned& i);
217 
218  /// Rebuild the element. This needs to find any nodes in the sons which
219  /// are still required.
220  void rebuild_from_sons(Mesh*& mesh_pt);
221 
222  /// Check the integrity of interpolated values across element
223  /// boundaries.
224  /// Note: with the mortar method, continuity is enforced weakly across non-
225  /// conforming element boundaries, so it makes no sense to check the
226  /// continuity of interpolated values across these boundaries.
227  void check_integrity(double& max_error);
228 
229  protected:
230  /// Set up hanging node information.
231  /// Overloaded to implement the mortar method rather than constrained
232  /// approximation. This enforces continuity weakly via an integral matching
233  /// condition at non-conforming element boundaries.
234  void quad_hang_helper(const int& value_id,
235  const int& my_edge,
236  std::ofstream& output_hangfile);
237  };
238 
239  //=======================================================================
240  /// p-refineable version of RefineableQElement<3,INITIAL_NNODE_1D>.
241  //=======================================================================
242  template<unsigned INITIAL_NNODE_1D>
243  class PRefineableQElement<3, INITIAL_NNODE_1D>
244  : public RefineableQElement<3>,
245  public virtual QElement<3, INITIAL_NNODE_1D>,
246  public virtual PRefineableElement
247  {
248  public:
249  /// Constructor
251 
252  /// Destructor
253  virtual ~PRefineableQElement() {}
254 
255  /// Initial setup of element (set the correct p-order and
256  /// integration scheme) If an adopted father is specified, information
257  /// from this is used instead of using the father found from the tree.
258  void initial_setup(Tree* const& adopted_father_pt = 0,
259  const unsigned& initial_p_order = 0);
260 
261  /// Pre-build (search father for required nodes which may already
262  /// exist)
263  void pre_build(Mesh*& mesh_pt, Vector<Node*>& new_node_pt);
264 
265  /// p-refine the element (refine if inc>0, unrefine if inc<0).
266  void p_refine(const int& inc,
267  Mesh* const& mesh_pt,
268  GeneralisedElement* const& clone_pt);
269 
270  /// Overload the shape functions
271  void shape(const Vector<double>& s, Shape& psi) const;
272 
273  void dshape_local(const Vector<double>& s, Shape& psi, DShape& dpsi) const;
274 
275  void d2shape_local(const Vector<double>& s,
276  Shape& psi,
277  DShape& dpsids,
278  DShape& d2psids) const;
279 
280  /// Perform additional hanging node procedures for variables
281  /// that are not interpolated by all nodes (e.g. lower order interpolations
282  /// for the pressure in Taylor Hood).
284 
285  /// Returns the number of nodes along each edge of the element.
286  /// Overloaded to return the (variable) p-order rather than the template
287  /// argument.
288  unsigned nnode_1d() const
289  {
290  return this->p_order();
291  }
292 
293  /// Get the initial P_order
294  unsigned initial_p_order() const
295  {
296  return INITIAL_NNODE_1D;
297  }
298 
299  // Overloaded from QElement<3,NNODE_1D> to use nnode_1d() instead of
300  // template argument.
301  Node* get_node_at_local_coordinate(const Vector<double>& s) const;
302 
303  Node* node_created_by_neighbour(const Vector<double>& s_fraction,
304  bool& is_periodic);
305 
306  Node* node_created_by_son_of_neighbour(const Vector<double>& s_fraction,
307  bool& is_periodic);
308 
309  // Overload nodal positions -- these elements have GLL-spaced nodes.
310  /// Get local coordinates of node j in the element; vector sets its own size
311  void local_coordinate_of_node(const unsigned& n, Vector<double>& s) const;
312 
313  /// Get the local fractino of node j in the element
314  void local_fraction_of_node(const unsigned& n, Vector<double>& s_fraction);
315 
316  /// The local one-d fraction is the same
317  double local_one_d_fraction_of_node(const unsigned& n1d, const unsigned& i);
318 
319  /// Rebuild the element. This needs to find any nodes in the sons which
320  /// are still required.
321  void rebuild_from_sons(Mesh*& mesh_pt);
322 
323  /// Check the integrity of interpolated values across element
324  /// boundaries.
325  /// Note: with the mortar method, continuity is enforced weakly across non-
326  /// conforming element boundaries, so it makes no sense to check the
327  /// continuity of interpolated values across these boundaries.
328  void check_integrity(double& max_error);
329 
330  protected:
331  /// Set up hanging node information.
332  /// Overloaded to implement the mortar method rather than constrained
333  /// approximation. This enforces continuity weakly via an integral matching
334  /// condition at non-conforming element boundaries.
335  void oc_hang_helper(const int& value_id,
336  const int& my_face,
337  std::ofstream& output_hangfile);
338  };
339 
340 } // namespace oomph
341 
342 #endif
static char t char * s
Definition: cfortran.h:568
cstr elem_len * i
Definition: cfortran.h:603
A Class for the derivatives of shape functions The class design is essentially the same as Shape,...
Definition: shape.h:278
A Generalised Element class.
Definition: elements.h:73
A general mesh class.
Definition: mesh.h:67
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
Definition: nodes.h:906
/////////////////////////////////////////////////////////////////// /////////////////////////////////...
unsigned initial_p_order() const
Get the initial P_order.
void further_setup_hanging_nodes()
Perform additional hanging node procedures for variables that are not interpolated by all nodes (e....
unsigned nnode_1d() const
Returns the number of nodes along each edge of the element. Overloaded to return the (variable) p-ord...
void further_setup_hanging_nodes()
Perform additional hanging node procedures for variables that are not interpolated by all nodes (e....
unsigned nnode_1d() const
Returns the number of nodes along each edge of the element. Overloaded to return the (variable) p-ord...
unsigned initial_p_order() const
Get the initial P_order.
void further_setup_hanging_nodes()
Perform additional hanging node procedures for variables that are not interpolated by all nodes (e....
unsigned initial_p_order() const
Get the initial P_order.
unsigned nnode_1d() const
Returns the number of nodes along each edge of the element. Overloaded to return the (variable) p-ord...
A class that is used to template the p-refineable Q elements by dimension. It's really nothing more t...
Definition: Qelements.h:2274
/////////////////////////////////////////////////////////////////////// /////////////////////////////...
Definition: Qelements.h:459
A class that is used to template the refineable Q elements by dimension. It's really nothing more tha...
Definition: Qelements.h:2259
A Class for shape functions. In simple cases, the shape functions have only one index that can be tho...
Definition: shape.h:76
A generalised tree base class that abstracts the common functionality between the quad- and octrees u...
Definition: tree.h:74
A slight extension to the standard template vector class so that we can include "graceful" array rang...
Definition: Vector.h:58
void shape(const double &s, double *Psi)
Definition for 1D Lagrange shape functions. The value of all the shape functions at the local coordin...
Definition: shape.h:564
//////////////////////////////////////////////////////////////////// ////////////////////////////////...