annular_mesh.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-2025 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
27#ifndef OOMPH_ANNULAR_MESH_HEADER
28#define OOMPH_ANNULAR_MESH_HEADER
29
30// Headers
32
33// Include the headers file for domain
34#include "annular_domain.h"
35
36namespace oomph
37{
38 //===================================================================
39 /// 2D annular mesh with a unit circle in the middle and a layer
40 /// of thickness h surrounding it.
41 //==================================================================
42 template<class ELEMENT>
43 class TwoDAnnularMesh : public virtual RectangularQuadMesh<ELEMENT>
44 {
45 public:
46 /// Constructor
48 const double& azimuthal_fraction,
49 const unsigned& ntheta,
50 const unsigned& nr,
51 const double& a,
52 const double& h,
53 TimeStepper* time_stepper_pt = &Mesh::Default_TimeStepper)
54 : RectangularQuadMesh<ELEMENT>(
55 ntheta, nr, 1.0, 1.0, periodic, time_stepper_pt)
56 {
57 // Mesh can only be built with 2D Qelements.
58 MeshChecker::assert_geometric_element<QElementGeometricBase, ELEMENT>(2);
59
60 // Wrap mesh into annular shape
61 double phi = 0.0;
63 }
64
65 /// Constructor; rotate mesh by angle phi.
67 const double& azimuthal_fraction,
68 const unsigned& ntheta,
69 const unsigned& nr,
70 const double& a,
71 const double& h,
72 const double& phi,
73 TimeStepper* time_stepper_pt = &Mesh::Default_TimeStepper)
74 : RectangularQuadMesh<ELEMENT>(
75 ntheta, nr, 1.0, 1.0, periodic, time_stepper_pt)
76 {
77 // Mesh can only be built with 2D Qelements.
78 MeshChecker::assert_geometric_element<QElementGeometricBase, ELEMENT>(2);
79
80 // Wrap mesh into annular shape
82 }
83
84 private:
85 /// Wrap mesh into annular shape
86 void wrap_into_annular_shape(const double& a,
87 const double& h,
88 const double& azimuthal_fraction,
89 const double& phi);
90 };
91
92
93 //////////////////////////////////////////////////////////////////////
94 //////////////////////////////////////////////////////////////////////
95 //////////////////////////////////////////////////////////////////////
96
97 //===================================================================
98 /// Refineable 2D annular mesh with a unit circle in the middle and a layer
99 /// of thickness h surrounding it.
100 //==================================================================
101 template<class ELEMENT>
102 class RefineableTwoDAnnularMesh : public virtual TwoDAnnularMesh<ELEMENT>,
103 public virtual RefineableQuadMesh<ELEMENT>
104 {
105 public:
106 /// Constructor
108 const bool& periodic,
109 const double& azimuthal_fraction,
110 const unsigned& ntheta,
111 const unsigned& nr,
112 const double& a,
113 const double& h,
114 TimeStepper* time_stepper_pt = &Mesh::Default_TimeStepper)
115 : RectangularQuadMesh<ELEMENT>(
116 ntheta, nr, 1.0, 1.0, periodic, time_stepper_pt),
117 TwoDAnnularMesh<ELEMENT>(
118 periodic, azimuthal_fraction, ntheta, nr, a, h, time_stepper_pt)
119 {
120 // Mesh can only be built with 2D Qelements.
121 MeshChecker::assert_geometric_element<QElementGeometricBase, ELEMENT>(2);
122
123 // Build macro element-based domain
124 double phi = 0.0;
126
127 // Loop over all elements and set macro element pointer
128 unsigned nel = this->nelement();
129 for (unsigned ielem = 0; ielem < nel; ielem++)
130 {
131 dynamic_cast<RefineableQElement<2>*>(this->element_pt(ielem))
132 ->set_macro_elem_pt(this->Domain_pt->macro_element_pt(ielem));
133 }
134
135 // Update nodal positions based on macro-element representation
136 this->node_update();
137
138 // Nodal positions etc. were created in constructor for
139 // RectangularMesh<...>. Only need to setup quadtree forest
140 this->setup_quadtree_forest();
141
142 // Setup the periodic neighbour information of the TreeRoots
143 // Cast to specific elements
144 if (periodic)
145 {
148 for (unsigned i = 0; i < nr; i++)
149 {
150 left_root_pt[i] = dynamic_cast<ELEMENT*>(this->element_pt(i * ntheta))
151 ->tree_pt()
152 ->root_pt();
153
155 dynamic_cast<ELEMENT*>(this->element_pt((i + 1) * ntheta - 1))
156 ->tree_pt()
157 ->root_pt();
158 }
159
160 // Set the neighbour and periodicity
161 using namespace QuadTreeNames;
162 for (unsigned i = 0; i < nr; i++)
163 {
164 left_root_pt[i]->neighbour_pt(W) = right_root_pt[i];
165 left_root_pt[i]->set_neighbour_periodic(W);
166
167 right_root_pt[i]->neighbour_pt(E) = left_root_pt[i];
168 right_root_pt[i]->set_neighbour_periodic(E);
169 }
170 }
171 }
172
173 /// Constructor; rotate mesh by angle phi
175 const bool& periodic,
176 const double& azimuthal_fraction,
177 const unsigned& ntheta,
178 const unsigned& nr,
179 const double& a,
180 const double& h,
181 const double& phi,
182 TimeStepper* time_stepper_pt = &Mesh::Default_TimeStepper)
183 : RectangularQuadMesh<ELEMENT>(
184 ntheta, nr, 1.0, 1.0, periodic, time_stepper_pt),
185 TwoDAnnularMesh<ELEMENT>(
186 periodic, azimuthal_fraction, ntheta, nr, a, h, phi, time_stepper_pt)
187 {
188 // Mesh can only be built with 2D Qelements.
189 MeshChecker::assert_geometric_element<QElementGeometricBase, ELEMENT>(2);
190
191 // Build macro element-based domain
193
194 // Loop over all elements and set macro element pointer
195 unsigned nel = this->nelement();
196 for (unsigned ielem = 0; ielem < nel; ielem++)
197 {
198 dynamic_cast<RefineableQElement<2>*>(this->element_pt(ielem))
199 ->set_macro_elem_pt(this->Domain_pt->macro_element_pt(ielem));
200 }
201
202 // Update nodal positions based on macro-element representation
203 this->node_update();
204
205 // Nodal positions etc. were created in constructor for
206 // RectangularMesh<...>. Only need to setup quadtree forest
207 this->setup_quadtree_forest();
208
209 // Setup the periodic neighbour information of the TreeRoots
210 // Cast to specific elements
211 if (periodic)
212 {
215 for (unsigned i = 0; i < nr; i++)
216 {
217 left_root_pt[i] = dynamic_cast<ELEMENT*>(this->element_pt(i * ntheta))
218 ->tree_pt()
219 ->root_pt();
220
222 dynamic_cast<ELEMENT*>(this->element_pt((i + 1) * ntheta - 1))
223 ->tree_pt()
224 ->root_pt();
225 }
226
227 // Set the neighbour and periodicity
228 using namespace QuadTreeNames;
229 for (unsigned i = 0; i < nr; i++)
230 {
231 left_root_pt[i]->neighbour_pt(W) = right_root_pt[i];
232 left_root_pt[i]->set_neighbour_periodic(W);
233
234 right_root_pt[i]->neighbour_pt(E) = left_root_pt[i];
235 right_root_pt[i]->set_neighbour_periodic(E);
236 }
237 }
238 }
239
240 private:
241 /// Pointer to domain
243 };
244
245} // namespace oomph
246
248#endif
cstr elem_len * i
Definition cfortran.h:603
Annular domain.
MacroElement * macro_element_pt(const unsigned &i)
Access to i-th macro element.
Definition domain.h:116
static Steady< 0 > Default_TimeStepper
Default Steady Timestepper, to be used in default arguments to Mesh constructors.
Definition mesh.h:75
virtual void node_update(const bool &update_all_solid_nodes=false)
Update nodal positions in response to changes in the domain shape. Uses the FiniteElement::get_x(....
Definition mesh.cc:287
const Vector< GeneralisedElement * > & element_pt() const
Return reference to the Vector of elements.
Definition mesh.h:464
unsigned long nelement() const
Return number of elements in the mesh.
Definition mesh.h:598
RectangularQuadMesh is a two-dimensional mesh of Quad elements with Nx elements in the "x" (horizonal...
Intermediate mesh class that implements the mesh adaptation functions specified in the TreeBasedRefin...
void setup_quadtree_forest()
Set up QuadTreeForest. Wipes any existing tree structure below the minimum refinement level and regar...
Refineable 2D annular mesh with a unit circle in the middle and a layer of thickness h surrounding it...
RefineableTwoDAnnularMesh(const bool &periodic, const double &azimuthal_fraction, const unsigned &ntheta, const unsigned &nr, const double &a, const double &h, const double &phi, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor; rotate mesh by angle phi.
AnnularDomain * Domain_pt
Pointer to domain.
RefineableTwoDAnnularMesh(const bool &periodic, const double &azimuthal_fraction, const unsigned &ntheta, const unsigned &nr, const double &a, const double &h, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor.
TAdvectionDiffusionReactionElement<NREAGENT,DIM,NNODE_1D> elements are isoparametric triangular DIM-d...
Base class for time-stepping schemes. Timestepper provides an approximation of the temporal derivativ...
2D annular mesh with a unit circle in the middle and a layer of thickness h surrounding it.
TwoDAnnularMesh(const bool &periodic, const double &azimuthal_fraction, const unsigned &ntheta, const unsigned &nr, const double &a, const double &h, const double &phi, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor; rotate mesh by angle phi.
TwoDAnnularMesh(const bool &periodic, const double &azimuthal_fraction, const unsigned &ntheta, const unsigned &nr, const double &a, const double &h, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor.
void wrap_into_annular_shape(const double &a, const double &h, const double &azimuthal_fraction, const double &phi)
Wrap mesh into annular shape.
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).