single_layer_cubic_spine_mesh.template.cc
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 #ifndef OOMPH_SINGLE_LAYER_CUBIC_SPINE_MESH_TEMPLATE_CC
31 #define OOMPH_SINGLE_LAYER_CUBIC_SPINE_MESH_TEMPLATE_CC
32 
35 
36 namespace oomph
37 {
38 
39 //===========================================================================
40 /// Constructor for spine 3D mesh: Pass number of elements in x-direction,
41 /// number of elements in y-direction, number elements in z-direction,
42 /// length, width and height of layer,
43 /// and pointer to timestepper (defaults to Static timestepper).
44 //===========================================================================
45 template<class ELEMENT>
48  const unsigned &nx, const unsigned &ny, const unsigned &nz,
49  const double &lx, const double &ly, const double &h,
50  TimeStepper* time_stepper_pt) :
51  SimpleCubicMesh<ELEMENT >(nx,ny,nz,lx,ly,h,time_stepper_pt)
52 {
53  // Mesh can only be built with 3D Qelements.
54  MeshChecker::assert_geometric_element<QElementGeometricBase,ELEMENT>(3);
55 
56  //Mesh can only be built with spine elements
57  MeshChecker::assert_geometric_element<SpineFiniteElement,ELEMENT>(3);
58 
59  // Now build the single layer mesh on top of the existing mesh
60  build_single_layer_mesh(time_stepper_pt);
61 }
62 
63 //===========================================================================
64 /// Helper function that actually builds the single-layer spine mesh
65 /// based on the parameters set in the various constructors
66 //===========================================================================
67 template<class ELEMENT>
70  TimeStepper* time_stepper_pt)
71 {
72  //Read out the number of elements in the x-direction
73  unsigned n_x = this->Nx;
74  //Read out the number of elements in the y-direction
75  unsigned n_y = this->Ny;
76  //Read out the number of elements in the z-direction
77  unsigned n_z = this->Nz;
78 
79  //Allocate memory for the spines and fractions along spines
80 
81  //Read out number of linear points in the element
82  unsigned n_p = dynamic_cast<ELEMENT*>(finite_element_pt(0))->nnode_1d();
83 
84  //Allocate store for the spines: (different in the case of periodic meshes !!)
85  Spine_pt.reserve(((n_p-1)*n_x+1)*((n_p-1)*n_y+1));
86 
87  //Now we loop over all the elements and attach the spines
88 
89  // FIRST ELEMENT: Element 0
90  //Loop over the nodes on the base of the element
91  for(unsigned l1=0;l1<n_p;l1++) //y loop over the nodes
92  {
93  for(unsigned l2=0;l2<n_p;l2++) //x loop over the nodes
94  {
95  //Assign the new spine with length h
96  Spine* new_spine_pt=new Spine(1.0);
97  Spine_pt.push_back(new_spine_pt);
98 
99  // Get pointer to node
100  SpineNode* nod_pt = element_node_pt(0, l2 + l1*n_p);
101  //Set the pointer to the spine
102  nod_pt->spine_pt() = new_spine_pt;
103  //Set the fraction
104  nod_pt->fraction() = 0.0;
105  // Pointer to the mesh that implements the update fct
106  nod_pt->spine_mesh_pt() = this;
107 
108  //Loop vertically along the spine
109  //Loop over the elements
110  for(unsigned long k=0;k<n_z;k++)
111  {
112  //Loop over the vertical nodes, apart from the first
113  for(unsigned l3=1;l3<n_p;l3++)
114  {
115  // Get pointer to node
116  SpineNode* nod_pt=element_node_pt(k*n_x*n_y,l3*n_p*n_p+l2+l1*n_p);
117  //Set the pointer to the spine
118  nod_pt->spine_pt() = new_spine_pt;
119  //Set the fraction
120  nod_pt->fraction()=(double(k)+double(l3)/double(n_p-1))/double(n_z);
121  // Pointer to the mesh that implements the update fct
122  nod_pt->spine_mesh_pt() = this;
123  }
124  }
125 
126  }
127  }
128 
129 
130  //LOOP OVER OTHER ELEMENTS IN THE FIRST ROW
131  //-----------------------------------------
132 
133 // The procedure is the same but we have to identify the
134 // before defined spines for not defining them two times
135 
136  for(unsigned j=1;j<n_x;j++) //loop over the elements in the first row
137  {
138  for(unsigned l1=0;l1<n_p;l1++) //y loop over the nodes
139  {
140  // First we copy the last row of nodes into the
141  // first row of the new element (and extend to the third dimension)
142  for(unsigned l2=1;l2<n_p;l2++) //x loop over the nodes
143  {
144  //Node j + i*np
145  //Assign the new spine with unit length
146  Spine* new_spine_pt=new Spine(1.0);
147  Spine_pt.push_back(new_spine_pt);
148 
149  // Get pointer to node
150  SpineNode* nod_pt=element_node_pt(j,l2+l1*n_p);
151 
152  //Set the pointer to the spine
153  nod_pt->spine_pt() = new_spine_pt;
154  //Set the fraction
155  nod_pt->fraction() = 0.0;
156  // Pointer to the mesh that implements the update fct
157  nod_pt->spine_mesh_pt() = this;
158 
159  //Loop vertically along the spine
160  //Loop over the elements
161  for(unsigned long k=0;k<n_z;k++)
162  {
163  //Loop over the vertical nodes, apart from the first
164  for(unsigned l3=1;l3<n_p;l3++)
165  {
166  // Get pointer to node
167  SpineNode* nod_pt=element_node_pt(j+k*n_x*n_y,l3*n_p*n_p+l2+l1*n_p);
168  //Set the pointer to the spine
169  nod_pt->spine_pt() = new_spine_pt;
170  //Set the fraction
171  nod_pt->fraction()=(double(k)+double(l3)/double(n_p-1))/double(n_z);
172  // Pointer to the mesh that implements the update fct
173  nod_pt->spine_mesh_pt() = this;
174  }
175  }
176 
177 
178  }
179  }
180  }
181 
182  //REST OF THE ELEMENTS
183  // Now we loop over the rest of the elements.
184  //We will separate the first of each row being al the rest equal
185  for(unsigned long i=1;i<n_y;i++)
186 {
187 //FIRST ELEMENT OF THE ROW
188 
189  //First line of nodes is copied from the element of the bottom
190  for(unsigned l1=1;l1<n_p;l1++) //y loop over the nodes
191  {
192 
193  for(unsigned l2=0;l2<n_p;l2++) //x loop over the nodes
194  {
195 
196  //Node j + i*np
197  //Assign the new spine with unit length
198  Spine* new_spine_pt=new Spine(1.0);
199  Spine_pt.push_back(new_spine_pt);
200 
201 
202  // Get pointer to node
203  // Element i*n_x; node l2 + l1*n_p
204  SpineNode* nod_pt=element_node_pt(i*n_x,l2+l1*n_p);
205  //Set the pointer to the spine
206  nod_pt->spine_pt() = new_spine_pt;
207  //Set the fraction
208  nod_pt->fraction() = 0.0;
209  // Pointer to the mesh that implements the update fct
210  nod_pt->spine_mesh_pt() = this;
211 
212  //Loop vertically along the spine
213  //Loop over the elements
214  for(unsigned long k=0;k<n_z;k++)
215  {
216  //Loop over the vertical nodes, apart from the first
217  for(unsigned l3=1;l3<n_p;l3++)
218  {
219  // Get pointer to node
220  SpineNode* nod_pt=
221  element_node_pt(i*n_x+k*n_x*n_y,l3*n_p*n_p+l2+l1*n_p);
222  //Set the pointer to the spine
223  nod_pt->spine_pt() = new_spine_pt;
224  //Set the fraction
225  nod_pt->fraction()=(double(k)+double(l3)/double(n_p-1))/double(n_z);
226  // Pointer to the mesh that implements the update fct
227  nod_pt->spine_mesh_pt() = this;
228  }
229  }
230 
231 
232  }
233  }
234 
235 
236 
237 
238 
239  // REST OF THE ELEMENTS OF THE ROW
240  for(unsigned j=1;j<n_x;j++)
241  {
242 
243 
244 //First line of nodes is copied from the element of the bottom
245  for(unsigned l1=1;l1<n_p;l1++) //y loop over the nodes
246  {
247  for(unsigned l2=1;l2<n_p;l2++) //x loop over the nodes
248  {
249 
250  //Node j + i*np
251  //Assign the new spine with unit length
252  Spine* new_spine_pt=new Spine(1.0);
253  Spine_pt.push_back(new_spine_pt);
254 
255 
256  // Get pointer to node
257  // Element j + i*n_x; node l2 + l1*n_p
258  SpineNode* nod_pt=element_node_pt(j+i*n_x,l2+l1*n_p);
259  //Set the pointer to the spine
260  nod_pt->spine_pt() = new_spine_pt;
261  //Set the fraction
262  nod_pt->fraction() = 0.0;
263  // Pointer to the mesh that implements the update fct
264  nod_pt->spine_mesh_pt() = this;
265 
266  //Loop vertically along the spine
267  //Loop over the elements
268  for(unsigned long k=0;k<n_z;k++)
269  {
270  //Loop over the vertical nodes, apart from the first
271  for(unsigned l3=1;l3<n_p;l3++)
272  {
273  // Get pointer to node
274  SpineNode* nod_pt=
275  element_node_pt(j+i*n_x+k*n_x*n_y,l3*n_p*n_p+l2+l1*n_p);
276  //Set the pointer to the spine
277  nod_pt->spine_pt() = new_spine_pt;
278  //Set the fraction
279  nod_pt->fraction()=(double(k)+double(l3)/double(n_p-1))/double(n_z);
280  // Pointer to the mesh that implements the update fct
281  nod_pt->spine_mesh_pt() = this;
282  }
283  }
284 
285 
286  }
287  }
288 
289  }
290 
291 }
292 
293 
294 }
295 
296 }
297 #endif
unsigned Ny
Number of elements in y direction.
unsigned Nx
Number of elements in x direction.
Simple cubic 3D Brick mesh class.
cstr elem_len * i
Definition: cfortran.h:607
double & fraction()
Set reference to fraction along spine.
Definition: spines.h:350
unsigned Nz
Number of elements in y direction.
FiniteElement * finite_element_pt(const unsigned &e) const
Upcast (downcast?) to FiniteElement (needed to access FiniteElement member functions).
Definition: mesh.h:477
SpineNode * element_node_pt(const unsigned long &e, const unsigned &n)
Return the n-th local SpineNode in element e. This is required to cast the nodes in a spine mesh to b...
Definition: spines.h:614
SingleLayerCubicSpineMesh(const unsigned &nx, const unsigned &ny, const unsigned &nz, const double &lx, const double &ly, const double &h, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass number of elements in x-direction, number of elements in y-direction, number of elements in z-direction, lengths in x- and y- directions, height of layer, and pointer to timestepper (defaults to Steady timestepper)
virtual void build_single_layer_mesh(TimeStepper *time_stepper_pt)
Helper function to actually build the single-layer spine mesh (called from various constructors) ...
Spine *& spine_pt()
Access function to spine.
Definition: spines.h:347
SpineMesh *& spine_mesh_pt()
Access function to Pointer to SpineMesh that this node is a part of and which implements the node upd...
Definition: spines.h:357
Base class for time-stepping schemes. Timestepper provides an approximation of the temporal derivativ...
Definition: timesteppers.h:219
Vector< Spine * > Spine_pt
A Spine mesh contains a Vector of pointers to spines.
Definition: spines.h:570