refineable_line_element.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// Version 1.0; svn revision $LastChangedRevision$
7 //LIC//
8 //LIC// $LastChangedDate$
9 //LIC//
10 //LIC// Copyright (C) 2006-2016 Matthias Heil and Andrew Hazel
11 //LIC//
12 //LIC// This library is free software; you can redistribute it and/or
13 //LIC// modify it under the terms of the GNU Lesser General Public
14 //LIC// License as published by the Free Software Foundation; either
15 //LIC// version 2.1 of the License, or (at your option) any later version.
16 //LIC//
17 //LIC// This library is distributed in the hope that it will be useful,
18 //LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
19 //LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 //LIC// Lesser General Public License for more details.
21 //LIC//
22 //LIC// You should have received a copy of the GNU Lesser General Public
23 //LIC// License along with this library; if not, write to the Free Software
24 //LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 //LIC// 02110-1301 USA.
26 //LIC//
27 //LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
28 //LIC//
29 //LIC//====================================================================
30 // Header file for RefineableQElement<1> class
31 #ifndef OOMPH_REFINEABLE_LINE_ELEMENT_HEADER
32 #define OOMPH_REFINEABLE_LINE_ELEMENT_HEADER
33 
34 // Config header generated by autoconfig
35 #ifdef HAVE_CONFIG_H
36  #include <oomph-lib-config.h>
37 #endif
38 
39 // oomph-lib headers
40 #include "binary_tree.h"
41 #include "macro_element.h"
42 #include "refineable_elements.h"
43 #include "Qelements.h"
44 
45 namespace oomph
46 {
47 
48  //Forward definition for mesh.
49  class Mesh;
50 
51  //=======================================================================
52  /// Refineable version of QElement<1,NNODE_1D>.
53  ///
54  /// Refinement is performed by binary tree procedures. When the element
55  /// is subdivided, the geometry of its sons is established by calls to
56  /// their father's \c get_x(...) function which refers to:
57  /// - the father element's geometric FE mapping (this is the default)
58  /// or
59  /// - a MacroElement's MacroElement::macro_map (if the pointer to the
60  /// macro element is non-NULL)
61  ///
62  /// The class provides a generic RefineableQElement<1>::build() function
63  /// which deals with generic isoparametric QElements in which all values
64  /// are associated with nodes. The RefineableQElement<1>::further_build()
65  /// function provides an interface for any element-specific non-generic
66  /// build operations.
67  //=======================================================================
68  template<>
69  class RefineableQElement<1> : public virtual RefineableElement,
70  public virtual LineElementBase
71  {
72 
73  public:
74 
75  /// \short Shorthand for pointer to an argument-free void member
76  /// function of the refineable element
77  typedef void (RefineableQElement<1>::*VoidMemberFctPt)();
78 
79  /// Constructor: Pass refinement level (default 0 = root)
81  {
82 #ifdef LEAK_CHECK
83  LeakCheckNames::RefineableQElement<1>_build+=1;
84 #endif
85  }
86 
87  /// Broken copy constructor
89  {
90  BrokenCopy::broken_copy("RefineableQElement<1>");
91  }
92 
93  /// Broken assignment operator
94 //Commented out broken assignment operator because this can lead to a conflict warning
95 //when used in the virtual inheritence hierarchy. Essentially the compiler doesn't
96 //realise that two separate implementations of the broken function are the same and so,
97 //quite rightly, it shouts.
98  /*void operator=(const RefineableQElement<1>&)
99  {
100  BrokenCopy::broken_assign("RefineableQElement<1>");
101  }*/
102 
103  /// Destructor
105  {
106 #ifdef LEAK_CHECK
107  LeakCheckNames::RefineableQElement<1>_build-=1;
108 #endif
109  }
110 
111  /// A refineable line element has two sons
112  unsigned required_nsons() const { return 2; }
113 
114  /// \short If a neighbouring element has already created a node at a
115  /// position corresponding to the local fractional position within the
116  /// present element, s_fraction, return a pointer to that node. If
117  /// not, return NULL (0). If the node is on a periodic boundary the
118  /// flag is_periodic is true, otherwise it will be false.
119  Node* node_created_by_neighbour(const Vector<double> &s_fraction,
120  bool &is_periodic);
121 
122  /// \short If a neighbouring element has already created a node at a
123  /// position corresponding to the local fractional position within the
124  /// present element, s_fraction, return a pointer to that node. If
125  /// not, return NULL (0). If the node is on a periodic boundary the
126  /// flag is_periodic is true, otherwise it will be false.
128  bool &is_periodic)
129  {
130  // It is impossible for this situation to arise in meshes
131  // containing elements of uniform p-order. This is here so
132  // that it can be overloaded for p-refineable elements.
133  return 0;
134  }
135 
136  /// \short Build the element, i.e. give it nodal positions, apply BCs,
137  /// etc. Pointers to any new nodes will be returned in new_node_pt.
138  /// If it is open, the positions of the new nodes will be written to
139  /// the file stream new_nodes_file.
140  virtual void build(Mesh*& mesh_pt, Vector<Node*>& new_node_pt,
141  bool& was_already_built,
142  std::ofstream &new_nodes_file);
143 
144  /// \short Check the integrity of the element: ensure that the position
145  /// and values are continuous across the element edges.
146  void check_integrity(double& max_error);
147 
148  /// Print corner nodes, using colour
149  void output_corners(std::ostream& outfile, const std::string& colour) const;
150 
151  /// Pointer to binary tree representation of this element
153  { return dynamic_cast<BinaryTree*>(Tree_pt); }
154 
155  /// Pointer to binary tree representation of this element (const version)
157  { return dynamic_cast<BinaryTree*>(Tree_pt); }
158 
159  /// Line elements have no hanging nodes so this is deliberately left empty
161 
162  protected:
163 
164  /// \short Coincidence between son nodal points and father boundaries:
165  /// Father_bound[node_1d](jnod_son,son_type) = {L/R/OMEGA}
166  static std::map<unsigned, DenseMatrix<int> > Father_bound;
167 
168  /// \short Setup static matrix for coincidence between son nodal points
169  /// and father boundaries
170  void setup_father_bounds();
171 
172  /// Line elements have no hanging nodes so this is deliberately left empty
173  void setup_hang_for_value(const int &value_id) {}
174 
175  /// Line elements have no hanging nodes so this is deliberately left empty
176  void binary_hang_helper(const int &value_id,
177  const int &my_edge, std::ofstream &output_hangfile)
178  {}
179 
180  };
181 
182 
183  //=======================================================================
184  /// Refineable version of Solid line elements
185  //=======================================================================
186  template<>
187  class RefineableSolidQElement<1> : public virtual RefineableQElement<1>,
188  public virtual RefineableSolidElement,
189  public virtual QSolidElementBase
190  {
191 
192  public:
193 
194  /// Constructor, just call the constructor of the RefineableQElement<1>
197  {
198  // Issue a warning about this class
199  std::string warning_message =
200  "The class RefinableSolidQElement<1> has not been implemented or\n";
201  warning_message +=
202  "tested. It is safest to assume that all functions do not do what\n";
203  warning_message +=
204  "they claim to. The `build()' function is deliberately broken.";
205 
206  throw OomphLibWarning(
207  warning_message,
208  "RefineableSolidQElement<1>::RefineableSolidQElement()",
209  OOMPH_EXCEPTION_LOCATION);
210  }
211 
212  /// Broken copy constructor
214  {
215  BrokenCopy::broken_copy("RefineableSolidQElement<1>");
216  }
217 
218  /// Broken assignment operator
219  /*void operator=(const RefineableSolidQElement<1>&)
220  {
221  BrokenCopy::broken_assign("RefineableSolidQElement<1>");
222  }*/
223 
224  /// Virtual Destructor
226 
227 
228  /// \short Final over-ride: Use version in QSolidElementBase
229  void set_macro_elem_pt(MacroElement* macro_elem_pt)
230  {
232  }
233 
234  /// \short Final over-ride: Use version in QSolidElementBase
235  void set_macro_elem_pt(MacroElement* macro_elem_pt,
236  MacroElement* undeformed_macro_elem_pt)
237  {
239  undeformed_macro_elem_pt);
240  }
241 
242  /// \short Use the generic finite difference routine defined in
243  /// RefineableSolidElement to calculate the Jacobian matrix
244  void get_jacobian(Vector<double> &residuals,
245  DenseMatrix<double> &jacobian)
246  { RefineableSolidElement::get_jacobian(residuals,jacobian); }
247 
248  /// \short Build the element, i.e. give it nodal positions, apply BCs, etc.
249  /// Incl. documention into new_nodes_file
250  // NOTE: FOR SOME REASON THIS NEEDS TO LIVE IN *.H TO WORK ON INTEL
251  void build(Mesh*& mesh_pt, Vector<Node*> &new_node_pt,
252  bool& was_already_built,
253  std::ofstream &new_nodes_file)
254  {
255  throw OomphLibError("This function has not been implemented yet:",
256  OOMPH_CURRENT_FUNCTION,
257  OOMPH_EXCEPTION_LOCATION);
258  }
259 
260  };
261 
262 } // End of namespace
263 
264 #endif
void set_macro_elem_pt(MacroElement *macro_elem_pt, MacroElement *undeformed_macro_elem_pt)
Final over-ride: Use version in QSolidElementBase.
Base class for all line elements.
Definition: Qelements.h:492
void broken_copy(const std::string &class_name)
Issue error message and terminate execution.
virtual ~RefineableSolidQElement()
Broken assignment operator.
RefineableSolidQElement()
Constructor, just call the constructor of the RefineableQElement<1>
virtual void get_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Calculate the elemental Jacobian matrix "d equation / d variable".
Definition: elements.h:984
Refineable version of Solid line elements.
void setup_hanging_nodes(Vector< std::ofstream *> &output_stream)
Line elements have no hanging nodes so this is deliberately left empty.
Base class for Solid Qelements.
Definition: Qelements.h:359
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
Definition: nodes.h:852
virtual ~RefineableQElement()
Broken assignment operator.
void build(Mesh *&mesh_pt, Vector< Node *> &new_node_pt, bool &was_already_built, std::ofstream &new_nodes_file)
Build the element, i.e. give it nodal positions, apply BCs, etc. Incl. documention into new_nodes_fil...
RefineableSolidQElement(const RefineableSolidQElement< 1 > &dummy)
Broken copy constructor.
virtual void set_macro_elem_pt(MacroElement *macro_elem_pt)
Broken assignment operator.
Definition: Qelements.h:386
unsigned required_nsons() const
A refineable line element has two sons.
void set_macro_elem_pt(MacroElement *macro_elem_pt)
Final over-ride: Use version in QSolidElementBase.
void get_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Use the generic finite difference routine defined in RefineableSolidElement to calculate the Jacobian...
RefineableQElement()
Constructor: Pass refinement level (default 0 = root)
Node * node_created_by_son_of_neighbour(const Vector< double > &s_fraction, bool &is_periodic)
If a neighbouring element has already created a node at a position corresponding to the local fractio...
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn&#39;t been defined.
RefineableQElement(const RefineableQElement< 1 > &dummy)
Broken copy constructor.
void setup_hang_for_value(const int &value_id)
Line elements have no hanging nodes so this is deliberately left empty.
Vector< std::string > colour
Tecplot colours.
long RefineableQElement< 2 > _build
void binary_hang_helper(const int &value_id, const int &my_edge, std::ofstream &output_hangfile)
Line elements have no hanging nodes so this is deliberately left empty.
BinaryTree * binary_tree_pt() const
Pointer to binary tree representation of this element (const version)
A general mesh class.
Definition: mesh.h:74
BinaryTree * binary_tree_pt()
Pointer to binary tree representation of this element.
static std::map< unsigned, DenseMatrix< int > > Father_bound
Coincidence between son nodal points and father boundaries: Father_bound[node_1d](jnod_son,son_type) = {L/R/OMEGA}.