rectangle_with_hole_mesh.template.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: 1194 $
7 //LIC//
8 //LIC// $LastChangedDate: 2016-05-27 08:44:43 +0100 (Fri, 27 May 2016) $
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 #ifndef OOMPH_RECTANGLE_WITH_HOLE_MESH_HEADER
31 #define OOMPH_RECTANGLE_WITH_HOLE_MESH_HEADER
32 
33 // Config header generated by autoconfig
34 #ifdef HAVE_CONFIG_H
35  #include <oomph-lib-config.h>
36 #endif
37 
38 // OOMPH-LIB headers
39 #include "../generic/mesh.h"
40 #include "../generic/quadtree.h"
41 #include "../generic/quad_mesh.h"
42 #include "../generic/refineable_quad_mesh.h"
44 
45 namespace oomph
46 {
47 
48 
49 
50 //=============================================================
51 /// Domain-based mesh for rectangular mesh with circular hole
52 //=============================================================
53 template<class ELEMENT>
54 class RectangleWithHoleMesh : public virtual Mesh
55 {
56 
57 public:
58 
59 
60  /// \short Constructor: Pass pointer to geometric object that
61  /// represents the cylinder, the length and height of the domain.
62  /// The GeomObject must be parametrised such that
63  /// \f$\zeta \in [0,2\pi]\f$ sweeps around the circumference
64  /// in anticlockwise direction. Timestepper defaults to Steady
65  /// default timestepper.
67  const double &length,
68  TimeStepper* time_stepper_pt=
70  {
71  //Create the domain
72  Domain_pt = new RectangleWithHoleDomain(cylinder_pt,
73  length);
74 
75  //Initialise the node counter
76  unsigned long node_count=0;
77 
78  //Vectors used to get data from domains
79  Vector<double> s(2),r(2);
80 
81  //Setup temporary storage for the Node
82  Vector<Node*> Tmp_node_pt;
83 
84  //Now blindly loop over the macro elements and associate and finite
85  //element with each
86  unsigned nmacro_element = Domain_pt->nmacro_element();
87  for(unsigned e=0;e<nmacro_element;e++)
88  {
89  //Create the FiniteElement and add to the Element_pt Vector
90  Element_pt.push_back(new ELEMENT);
91 
92  //Read out the number of linear points in the element
93  unsigned np =
94  dynamic_cast<ELEMENT*>(finite_element_pt(e))->nnode_1d();
95 
96  //Loop over nodes in the column
97  for(unsigned l1=0;l1<np;l1++)
98  {
99  //Loop over the nodes in the row
100  for(unsigned l2=0;l2<np;l2++)
101  {
102  //Allocate the memory for the node
103  Tmp_node_pt.push_back(finite_element_pt(e)->
104  construct_node(l1*np+l2,time_stepper_pt));
105 
106  //Read out the position of the node from the macro element
107  s[0] = -1.0 + 2.0*(double)l2/(double)(np-1);
108  s[1] = -1.0 + 2.0*(double)l1/(double)(np-1);
110 
111  //Set the position of the node
112  Tmp_node_pt[node_count]->x(0) = r[0];
113  Tmp_node_pt[node_count]->x(1) = r[1];
114 
115  //Increment the node number
116  node_count++;
117  }
118  }
119  } //End of loop over macro elements
120 
121 
122 
123  //Now the elements have been created, but there will be nodes in
124  //common, need to loop over the common edges and sort it, by reassigning
125  //pointers and the deleting excess nodes
126 
127  //Read out the number of linear points in the element
128  unsigned np=dynamic_cast<ELEMENT*>(finite_element_pt(0))->nnode_1d();
129 
130  //Edge between Elements 0 and 1
131  for(unsigned n=0;n<np;n++)
132  {
133  //Set the nodes in element 1 to be the same as in element 0
134  finite_element_pt(1)->node_pt(n*np)
135  = finite_element_pt(0)->node_pt((np-1)*np+np-1-n);
136 
137  //Remove the nodes in element 1 from the temporary node list
138  delete Tmp_node_pt[np*np + n*np];
139  Tmp_node_pt[np*np + n*np] = 0;
140  }
141 
142  //Edge between Elements 0 and 3
143  for(unsigned n=0;n<np;n++)
144  {
145  //Set the nodes in element 3 to be the same as in element 0
146  finite_element_pt(3)->node_pt(n*np)
147  = finite_element_pt(0)->node_pt(n);
148 
149  //Remove the nodes in element 3 from the temporary node list
150  delete Tmp_node_pt[3*np*np + n*np];
151  Tmp_node_pt[3*np*np + n*np] = 0;
152  }
153 
154  //Edge between Element 1 and 2
155  for(unsigned n=0;n<np;n++)
156  {
157  //Set the nodes in element 2 to be the same as in element 1
158  finite_element_pt(2)->node_pt(np*(np-1)+n)
159  = finite_element_pt(1)->node_pt(np*n+np-1);
160 
161  //Remove the nodes in element 2 from the temporary node list
162  delete Tmp_node_pt[2*np*np + np*(np-1)+n];
163  Tmp_node_pt[2*np*np + np*(np-1)+n] = 0;
164  }
165 
166 
167  //Edge between Element 3 and 2
168  for(unsigned n=0;n<np;n++)
169  {
170  //Set the nodes in element 2 to be the same as in element 3
172  = finite_element_pt(3)->node_pt(np*(np-n-1)+np-1);
173 
174  //Remove the nodes in element 2 from the temporary node list
175  delete Tmp_node_pt[2*np*np + n];
176  Tmp_node_pt[2*np*np + n] = 0;
177  }
178 
179 
180  //Now set the actual true nodes
181  for(unsigned long n=0;n<node_count;n++)
182  {
183  if(Tmp_node_pt[n]!=0) {Node_pt.push_back(Tmp_node_pt[n]);}
184  }
185 
186  //Finally set the nodes on the boundaries
187  set_nboundary(5);
188 
189  for(unsigned n=0;n<np;n++)
190  {
191  //Left hand side
192  Node* nod_pt=finite_element_pt(0)->node_pt(n*np);
193  convert_to_boundary_node(nod_pt);
194  add_boundary_node(3,nod_pt);
195 
196  //Right hand side
197  nod_pt=finite_element_pt(2)->node_pt(n*np+np-1);
198  convert_to_boundary_node(nod_pt);
199  add_boundary_node(1,nod_pt);
200 
201  //First part of lower boundary
202  nod_pt=finite_element_pt(3)->node_pt(n);
203  convert_to_boundary_node(nod_pt);
204  add_boundary_node(0,nod_pt);
205 
206  //First part of upper boundary
207  nod_pt=finite_element_pt(1)->node_pt(np*(np-1)+n);
208  convert_to_boundary_node(nod_pt);
209  add_boundary_node(2,nod_pt);
210 
211  //First part of hole boundary
212  nod_pt=finite_element_pt(3)->node_pt(np*(np-1)+n);
213  convert_to_boundary_node(nod_pt);
214  add_boundary_node(4,nod_pt);
215  }
216 
217  for(unsigned n=1;n<np;n++)
218  {
219  //Next part of hole
220  Node* nod_pt=finite_element_pt(2)->node_pt(n*np);
221  convert_to_boundary_node(nod_pt);
222  add_boundary_node(4,nod_pt);
223  }
224 
225  for(unsigned n=1;n<np;n++)
226  {
227  //Next part of hole
228  Node* nod_pt=finite_element_pt(1)->node_pt(np-n-1);
229  convert_to_boundary_node(nod_pt);
230  add_boundary_node(4,nod_pt);
231  }
232 
233  for(unsigned n=1;n<np-1;n++)
234  {
235  //Final part of hole
236  Node* nod_pt=finite_element_pt(0)->node_pt(np*(np-n-1)+np-1);
237  convert_to_boundary_node(nod_pt);
238  add_boundary_node(4,nod_pt);
239  }
240  }
241 
242  /// Access function to the domain
244 
245 protected:
246 
247  /// Pointer to the domain
249 
250 };
251 
252 
253 //////////////////////////////////////////////////////////////////////////
254 //////////////////////////////////////////////////////////////////////////
255 //////////////////////////////////////////////////////////////////////////
256 
257 
258 //===================================================================
259 /// Refineable version of RectangleWithHoleMesh. For some reason
260 /// this needs on uniform refinement to work...
261 //===================================================================
262 template<class ELEMENT>
264  public RectangleWithHoleMesh<ELEMENT>, public RefineableQuadMesh<ELEMENT>
265 {
266 
267 public:
268 
269 /// \short Constructor. Pass pointer to geometric object that
270 /// represents the cylinder, the length and height of the domain.
271 /// The GeomObject must be parametrised such that
272 /// \f$\zeta \in [0,2\pi]\f$ sweeps around the circumference
273 /// in anticlockwise direction. Timestepper defaults to Steady
274 /// default timestepper.
276  const double &length,
277  TimeStepper* time_stepper_pt=
279  RectangleWithHoleMesh<ELEMENT>(cylinder_pt,length,time_stepper_pt)
280  {
281 
282  // Nodal positions etc. were created in constructor for
283  // Cylinder...<...>. Need to setup adaptive information.
284 
285  // Loop over all elements and set macro element pointer
286  for (unsigned e=0;e<4;e++)
287  {
288  dynamic_cast<ELEMENT*>(this->element_pt(e))->
289  set_macro_elem_pt(this->Domain_pt->macro_element_pt(e));
290  }
291 
292  // Setup boundary element lookup schemes
294 
295  // Nodal positions etc. were created in constructor for
296  // RectangularMesh<...>. Only need to setup quadtree forest
297  this->setup_quadtree_forest();
298  }
299 
300  /// \short Destructor: Empty
302 
303 };
304 
305 
306 }
307 
308 
309 #endif
unsigned nmacro_element()
Number of macro elements in domain.
Definition: domain.h:107
Rectangular domain with circular whole.
Vector< Node * > Node_pt
Vector of pointers to nodes.
Definition: mesh.h:194
void add_boundary_node(const unsigned &b, Node *const &node_pt)
Add a (pointer to) a node to the b-th boundary.
Definition: mesh.cc:246
static Steady< 0 > Default_TimeStepper
Default Steady Timestepper, to be used in default arguments to Mesh constructors. ...
Definition: mesh.h:85
void setup_quadtree_forest()
Set up QuadTreeForest. Wipes any existing tree structure below the minimum refinement level and regar...
FiniteElement * finite_element_pt(const unsigned &e) const
Upcast (downcast?) to FiniteElement (needed to access FiniteElement member functions).
Definition: mesh.h:477
RectangleWithHoleMesh(GeomObject *cylinder_pt, const double &length, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass pointer to geometric object that represents the cylinder, the length and height of ...
RectangleWithHoleDomain * Domain_pt
Pointer to the domain.
MacroElement * macro_element_pt(const unsigned &i)
Access to i-th macro element.
Definition: domain.h:100
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
Definition: nodes.h:852
e
Definition: cfortran.h:575
void convert_to_boundary_node(Node *&node_pt, const Vector< FiniteElement * > &finite_element_pt)
A function that upgrades an ordinary node to a boundary node We shouldn't ever really use this...
Definition: mesh.cc:2334
RectangleWithHoleDomain * domain_pt()
Access function to the domain.
Domain-based mesh for rectangular mesh with circular hole.
static char t char * s
Definition: cfortran.h:572
void set_nboundary(const unsigned &nbound)
Set the number of boundaries in the mesh.
Definition: mesh.h:505
const Vector< GeneralisedElement * > & element_pt() const
Return reference to the Vector of elements.
Definition: mesh.h:470
void macro_map(const Vector< double > &s, Vector< double > &r)
The mapping from local to global coordinates at the current time : r(s)
Vector< GeneralisedElement * > Element_pt
Vector of pointers to generalised elements.
Definition: mesh.h:197
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Definition: elements.h:2097
virtual void setup_boundary_element_info()
Interface for function that is used to setup the boundary information (Empty virtual function – imple...
Definition: mesh.h:288
Base class for time-stepping schemes. Timestepper provides an approximation of the temporal derivativ...
Definition: timesteppers.h:219
RefineableRectangleWithHoleMesh(GeomObject *cylinder_pt, const double &length, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor. Pass pointer to geometric object that represents the cylinder, the length and height of ...
A general mesh class.
Definition: mesh.h:74