single_layer_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// Copyright (C) 2006-2022 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#ifndef OOMPH_SINGLE_LAYER_SPINE_MESH_TEMPLATE_CC
27#define OOMPH_SINGLE_LAYER_SPINE_MESH_TEMPLATE_CC
28
31
32
33namespace oomph
34{
35 //===========================================================================
36 /// Constructor for spine 2D mesh: Pass number of elements in x-direction,
37 /// number of elements in y-direction, axial length and height of layer,
38 /// and pointer to timestepper (defaults to Static timestepper).
39 ///
40 /// The mesh must be called with spinified elements and it
41 /// constructs the spines and contains the information on how to update
42 /// the nodal positions within the mesh as a function of the spine lengths.
43 /// Equations that determine the spine heights (even if they are pinned)
44 /// must be specified externally or else there will be problems.
45
46 //===========================================================================
47 template<class ELEMENT>
49 const unsigned& nx,
50 const unsigned& ny,
51 const double& lx,
52 const double& h,
53 TimeStepper* time_stepper_pt)
54 : RectangularQuadMesh<ELEMENT>(
55 nx, ny, 0.0, lx, 0.0, h, false, false, time_stepper_pt)
56 {
57 // Mesh can only be built with 2D Qelements.
58 MeshChecker::assert_geometric_element<QElementGeometricBase, ELEMENT>(2);
59
60 // Mesh can only be built with spine elements
61 MeshChecker::assert_geometric_element<SpineFiniteElement, ELEMENT>(2);
62
63 // We've called the "generic" constructor for the RectangularQuadMesh
64 // which doesn't do much...
65
66 // Now build the mesh:
67 build_single_layer_mesh(time_stepper_pt);
68 }
69
70
71 //===========================================================================
72 /// Constuctor for spine 2D mesh: Pass number of elements in x-direction,
73 /// number of elements in y-direction, axial length and height of layer,
74 /// a boolean flag to make the mesh periodic in the x-direction,
75 /// and pointer to timestepper (defaults to Static timestepper).
76 ///
77 /// The mesh must be called with spinified elements and it
78 /// constructs the spines and contains the information on how to update
79 /// the nodal positions within the mesh as a function of the spine lengths.
80 /// Equations that determine the spine heights (even if they are pinned)
81 /// must be specified externally or else there will be problems.
82 //===========================================================================
83 template<class ELEMENT>
85 const unsigned& nx,
86 const unsigned& ny,
87 const double& lx,
88 const double& h,
89 const bool& periodic_in_x,
90 TimeStepper* time_stepper_pt)
91 : RectangularQuadMesh<ELEMENT>(
92 nx, ny, 0.0, lx, 0.0, h, periodic_in_x, false, time_stepper_pt)
93 {
94 // Mesh can only be built with 2D Qelements.
95 MeshChecker::assert_geometric_element<QElementGeometricBase, ELEMENT>(2);
96
97 // Mesh can only be built with spine elements
98 MeshChecker::assert_geometric_element<SpineFiniteElement, ELEMENT>(2);
99
100
101 // We've called the "generic" constructor for the RectangularQuadMesh
102 // which doesn't do much...
103
104 // Now build the mesh:
105 build_single_layer_mesh(time_stepper_pt);
106 }
107
108
109 //===========================================================================
110 /// Helper function that actually builds the single-layer spine mesh
111 /// based on the parameters set in the various constructors
112 //===========================================================================
113 template<class ELEMENT>
115 TimeStepper* time_stepper_pt)
116 {
117 // Mesh can only be built with 2D Qelements.
118 MeshChecker::assert_geometric_element<QElementGeometricBase, ELEMENT>(2);
119
120 // Build the underlying quad mesh:
122
123 // Read out the number of elements in the x-direction
124 unsigned n_x = this->Nx;
125 unsigned n_y = this->Ny;
126
127 // Allocate memory for the spines and fractions along spines
128 //---------------------------------------------------------
129
130 // Read out number of linear points in the element
131 unsigned n_p = dynamic_cast<ELEMENT*>(finite_element_pt(0))->nnode_1d();
132
133 // Allocate store for the spines:
134 if (this->Xperiodic)
135 {
136 Spine_pt.reserve((n_p - 1) * n_x);
137 }
138 else
139 {
140 Spine_pt.reserve((n_p - 1) * n_x + 1);
141 }
142
143
144 // FIRST SPINE
145 //-----------
146
147 // Element 0
148 // Node 0
149 // Assign the new spine with unit length
150 Spine* new_spine_pt = new Spine(1.0);
151 Spine_pt.push_back(new_spine_pt);
152
153
154 // Get pointer to node
155 SpineNode* nod_pt = element_node_pt(0, 0);
156 // Set the pointer to the spine
157 nod_pt->spine_pt() = new_spine_pt;
158 // Set the fraction
159 nod_pt->fraction() = 0.0;
160 // Pointer to the mesh that implements the update fct
161 nod_pt->spine_mesh_pt() = this;
162
163 // Loop vertically along the spine
164 // Loop over the elements
165 for (unsigned long i = 0; i < n_y; i++)
166 {
167 // Loop over the vertical nodes, apart from the first
168 for (unsigned l1 = 1; l1 < n_p; l1++)
169 {
170 // Get pointer to node
171 SpineNode* nod_pt = element_node_pt(i * n_x, l1 * n_p);
172 // Set the pointer to the spine
173 nod_pt->spine_pt() = new_spine_pt;
174 // Set the fraction
175 nod_pt->fraction() =
176 (double(i) + double(l1) / double(n_p - 1)) / double(n_y);
177 // Pointer to the mesh that implements the update fct
178 nod_pt->spine_mesh_pt() = this;
179 }
180 }
181
182
183 // LOOP OVER OTHER SPINES
184 //----------------------
185
186 // Now loop over the elements horizontally
187 for (unsigned long j = 0; j < n_x; j++)
188 {
189 // Loop over the nodes in the elements horizontally, ignoring
190 // the first column
191
192 // Last spine needs special treatment in x-periodic meshes:
193 unsigned n_pmax = n_p;
194 if ((this->Xperiodic) && (j == n_x - 1)) n_pmax = n_p - 1;
195
196 for (unsigned l2 = 1; l2 < n_pmax; l2++)
197 {
198 // Assign the new spine with unit height
199 new_spine_pt = new Spine(1.0);
200 Spine_pt.push_back(new_spine_pt);
201
202 // Get the node
203 SpineNode* nod_pt = element_node_pt(j, l2);
204 // Set the pointer to spine
205 nod_pt->spine_pt() = new_spine_pt;
206 // Set the fraction
207 nod_pt->fraction() = 0.0;
208 // Pointer to the mesh that implements the update fct
209 nod_pt->spine_mesh_pt() = this;
210
211 // Loop vertically along the spine
212 // Loop over the elements
213 for (unsigned long i = 0; i < n_y; i++)
214 {
215 // Loop over the vertical nodes, apart from the first
216 for (unsigned l1 = 1; l1 < n_p; l1++)
217 {
218 // Get the node
219 SpineNode* nod_pt = element_node_pt(i * n_x + j, l1 * n_p + l2);
220 // Set the pointer to the spine
221 nod_pt->spine_pt() = new_spine_pt;
222 // Set the fraction
223 nod_pt->fraction() =
224 (double(i) + double(l1) / double(n_p - 1)) / double(n_y);
225 // Pointer to the mesh that implements the update fct
226 nod_pt->spine_mesh_pt() = this;
227 }
228 }
229 }
230 }
231
232
233 // Last spine needs special treatment for periodic meshes
234 // because it's the same as the first one...
235 if (this->Xperiodic)
236 {
237 // Last spine is the same as first one...
238 Spine* final_spine_pt = Spine_pt[0];
239
240 // Get the node
241 SpineNode* nod_pt = element_node_pt((n_x - 1), (n_p - 1));
242
243 // Set the pointer for the first node
244 nod_pt->spine_pt() = final_spine_pt;
245 // Set the fraction to be the same as for the nodes on the first row
246 nod_pt->fraction() = element_node_pt(0, 0)->fraction();
247 // Pointer to the mesh that implements the update fct
248 nod_pt->spine_mesh_pt() = element_node_pt(0, 0)->spine_mesh_pt();
249
250 // Now loop vertically along the spine
251 for (unsigned i = 0; i < n_y; i++)
252 {
253 // Loop over the vertical nodes, apart from the first
254 for (unsigned l1 = 1; l1 < n_p; l1++)
255 {
256 // Get the node
257 SpineNode* nod_pt =
258 element_node_pt(i * n_x + (n_x - 1), l1 * n_p + (n_p - 1));
259
260 // Set the pointer to the spine
261 nod_pt->spine_pt() = final_spine_pt;
262 // Set the fraction to be the same as in first row
263 nod_pt->fraction() = element_node_pt(i * n_x, l1 * n_p)->fraction();
264 // Pointer to the mesh that implements the update fct
265 nod_pt->spine_mesh_pt() =
266 element_node_pt(i * n_x, l1 * n_p)->spine_mesh_pt();
267 }
268 }
269 }
270 }
271
272} // namespace oomph
273#endif
cstr elem_len * i
Definition: cfortran.h:603
RectangularQuadMesh is a two-dimensional mesh of Quad elements with Nx elements in the "x" (horizonal...
void build_mesh(TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Generic mesh construction function: contains all the hard work.
SingleLayerSpineMesh(const unsigned &nx, const unsigned &ny, const double &lx, const double &h, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass number of elements in x-direction, number of elements in y-direction,...
virtual void build_single_layer_mesh(TimeStepper *time_stepper_pt)
Helper function to actually build the single-layer spine mesh (called from various constructors)
Class for nodes that live on spines. The assumption is that each Node lies at a fixed fraction on a s...
Definition: spines.h:328
double & fraction()
Set reference to fraction along spine.
Definition: spines.h:378
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:391
Spine *& spine_pt()
Access function to spine.
Definition: spines.h:372
Spines are used for algebraic node update operations in free-surface fluid problems: They form the ba...
Definition: spines.h:64
////////////////////////////////////////////////////////////////////// //////////////////////////////...
Definition: timesteppers.h:231
//////////////////////////////////////////////////////////////////// ////////////////////////////////...