quarter_pipe_domain.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// Include guards
27#ifndef OOMPH_QUARTER_PIPE_DOMAIN_HEADER
28#define OOMPH_QUARTER_PIPE_DOMAIN_HEADER
29
30// Generic oomph-lib includes
31#include "generic/octree.h"
32#include "generic/domain.h"
34
35namespace oomph
36{
37 //================================================================
38 /// Domain representing a quarter pipe
39 //================================================================
41 {
42 public:
43 /// Constructor: Pass number of elements in various directions,
44 /// the inner and outer radius and the length of the tube
45 QuarterPipeDomain(const unsigned& ntheta,
46 const unsigned& nr,
47 const unsigned& nz,
48 const double& rmin,
49 const double& rmax,
50 const double& length)
51 : Ntheta(ntheta),
52 Nr(nr),
53 Nz(nz),
54 Rmin(rmin),
55 Rmax(rmax),
58 {
59 // Number of macroelements
60 unsigned nmacro = nr * ntheta * nz;
61
62 // Resize
64
65 // Create macro elements
66 for (unsigned i = 0; i < nmacro; i++)
67 {
69 }
70
71 // Make geom object representing the outer and inner boundaries of
72 // the cross section
75 }
76
77 /// Broken copy constructor
79
80 /// Broken assignment operator
81 void operator=(const QuarterPipeDomain&) = delete;
82
83 /// Destructor:
85 {
86 // Note: macro elements are cleaned up in base class...
89 }
90
91 /// Typedef for function pointer for function that implements
92 /// axial spacing of macro elements
93 typedef double (*AxialSpacingFctPt)(const double& xi);
94
95 /// Function pointer for function that implements
96 /// axial spacing of macro elements
101
102 /// Function that implements
103 /// axial spacing of macro elements
104 double axial_spacing_fct(const double& xi)
105 {
106 return Axial_spacing_fct_pt(xi);
107 }
108
109 /// Vector representation of the i_macro-th macro element
110 /// boundary i_direct (U/D/L/R/F/B) at time level t
111 /// (t=0: present; t>0: previous): f(s).
112 void macro_element_boundary(const unsigned& t,
113 const unsigned& i_macro,
114 const unsigned& i_direct,
115 const Vector<double>& s,
116 Vector<double>& f);
117
118 private:
119 /// Number of elements azimuthal direction
120 unsigned Ntheta;
121
122 /// Number of elements radial direction
123 unsigned Nr;
124
125 /// Number of elements axial direction
126 unsigned Nz;
127
128 /// Inner radius
129 double Rmin;
130
131 /// Outer radius
132 double Rmax;
133
134 /// Length
135 double Length;
136
137 /// Geom object representing the outer boundary of
138 /// the cross section
140
141 /// Geom object representing the inner boundary of
142 /// the cross section
144
145 /// Function pointer for function that implements
146 /// axial spacing of macro elements
148
149 /// Default for function that implements
150 /// axial spacing of macro elements
151 static double default_axial_spacing_fct(const double& xi)
152 {
153 return xi;
154 }
155
156 /// Boundary of macro element zeta \f$ \in [-1,1]x[-1,1] \f$
157 void r_U(const unsigned& t,
158 const Vector<double>& zeta,
160 const double& rmin,
161 const double& rmax,
162 const double& thetamin,
163 const double& thetamax,
164 const double& zmin,
165 const double& zmax);
166
167 /// Boundary of macro element zeta \f$ \in [-1,1]x[-1,1] \f$
168 void r_L(const unsigned& t,
169 const Vector<double>& zeta,
171 const double& rmin,
172 const double& rmax,
173 const double& thetamin,
174 const double& thetamax,
175 const double& zmin,
176 const double& zmax);
177
178 /// Boundary of macro element zeta \f$ \in [-1,1]x[-1,1] \f$
179 void r_D(const unsigned& t,
180 const Vector<double>& zeta,
182 const double& rmin,
183 const double& rmax,
184 const double& thetamin,
185 const double& thetamax,
186 const double& zmin,
187 const double& zmax);
188
189 /// Boundary of macro element zeta \f$ \in [-1,1]x[-1,1] \f$
190 void r_R(const unsigned& t,
191 const Vector<double>& zeta,
193 const double& rmin,
194 const double& rmax,
195 const double& thetamin,
196 const double& thetamax,
197 const double& zmin,
198 const double& zmax);
199
200 /// Boundary of macro element zeta \f$ \in [-1,1]x[-1,1] \f$
201 void r_F(const unsigned& t,
202 const Vector<double>& zeta,
204 const double& rmin,
205 const double& rmax,
206 const double& thetamin,
207 const double& thetamax,
208 const double& zmin,
209 const double& zmax);
210
211 /// Boundary of macro element zeta \f$ \in [-1,1]x[-1,1] \f$
212 void r_B(const unsigned& t,
213 const Vector<double>& zeta,
215 const double& rmin,
216 const double& rmax,
217 const double& thetamin,
218 const double& thetamax,
219 const double& zmin,
220 const double& zmax);
221
222 }; // endofclass
223
224 //=================================================================
225 /// Vector representation of the imacro-th macro element
226 /// boundary idirect (U/D/L/R/F/B) at time level t:
227 /// f(s)
228 //=================================================================
230 const unsigned& imacro,
231 const unsigned& idirect,
232 const Vector<double>& s,
234 {
235 using namespace OcTreeNames;
236
237 const double pi = MathematicalConstants::Pi;
238
239 // Match the elements number with the position
240 unsigned num_z = imacro / (Nr * Ntheta);
241 unsigned num_y = (imacro % (Nr * Ntheta)) / Ntheta;
242 unsigned num_x = imacro % Ntheta;
243
244 // Define the extreme coordinates
245
246 // radial direction
247 double rmin = Rmin + (Rmax - Rmin) * double(num_y) / double(Nr);
248 double rmax = Rmin + (Rmax - Rmin) * double(num_y + 1) / double(Nr);
249
250 // theta direction
251 double thetamin = (pi / 2.0) * (1.0 - double(num_x + 1) / double(Ntheta));
252 double thetamax = (pi / 2.0) * (1.0 - double(num_x) / double(Ntheta));
253
254 // zdirection (tube)
255 double zmin = double(num_z) * Length / double(Nz);
256 double zmax = double(num_z + 1) * Length / double(Nz);
257
258 // Which direction?
259 if (idirect == U)
260 {
261 r_U(t, s, f, rmin, rmax, thetamin, thetamax, zmin, zmax);
262 }
263 else if (idirect == D)
264 {
265 r_D(t, s, f, rmin, rmax, thetamin, thetamax, zmin, zmax);
266 }
267 else if (idirect == L)
268 {
269 r_L(t, s, f, rmin, rmax, thetamin, thetamax, zmin, zmax);
270 }
271 else if (idirect == R)
272 {
273 r_R(t, s, f, rmin, rmax, thetamin, thetamax, zmin, zmax);
274 }
275 else if (idirect == F)
276 {
277 r_F(t, s, f, rmin, rmax, thetamin, thetamax, zmin, zmax);
278 }
279 else if (idirect == B)
280 {
281 r_B(t, s, f, rmin, rmax, thetamin, thetamax, zmin, zmax);
282 }
283 else
284 {
285 std::ostringstream error_stream;
286 error_stream << "idirect is " << idirect << " not one of U, D, L, R, F, B"
287 << std::endl;
288
289 throw OomphLibError(
291 }
292
293 // Now redistribute points in the axial direction
294 double z_frac = f[2] / Length;
296 }
297
298 //=================================================================
299 /// Left face of a macro element \f$ s \in [-1,1]*[-1,1] \f$
300 //=================================================================
301 void QuarterPipeDomain::r_L(const unsigned& t,
302 const Vector<double>& s,
304 const double& rmin,
305 const double& rmax,
306 const double& thetamin,
307 const double& thetamax,
308 const double& zmin,
309 const double& zmax)
310 {
311 Vector<double> x(1);
312 x[0] = thetamax;
313
314 // Point on outer wall
317
318 // Point on inner wall
321
322 // Get layer boundaries
325 for (unsigned i = 0; i < 2; i++)
326 {
327 r_top[i] =
328 r_inner[i] + (r_outer[i] - r_inner[i]) * (rmax - Rmin) / (Rmax - Rmin);
329 r_bot[i] =
330 r_inner[i] + (r_outer[i] - r_inner[i]) * (rmin - Rmin) / (Rmax - Rmin);
331 }
332
333 // Compute coordinates
334 f[0] = r_bot[0] + (0.5 * (s[0] + 1.0)) * (r_top[0] - r_bot[0]);
335 f[1] = r_bot[1] + (0.5 * (s[0] + 1.0)) * (r_top[1] - r_bot[1]);
336 f[2] = zmin + (zmax - zmin) * (0.5 * (s[1] + 1.0));
337 }
338
339 //=================================================================
340 /// Right face of a macro element \f$ s \in [-1,1]*[-1,1] \f$
341 //=================================================================
342 void QuarterPipeDomain::r_R(const unsigned& t,
343 const Vector<double>& s,
345 const double& rmin,
346 const double& rmax,
347 const double& thetamin,
348 const double& thetamax,
349 const double& zmin,
350 const double& zmax)
351 {
352 Vector<double> x(1);
353 x[0] = thetamin;
354
355 // Point on outer wall
358
359 // Point on inner wall
362
363 // Get layer boundaries
366 for (unsigned i = 0; i < 2; i++)
367 {
368 r_top[i] =
369 r_inner[i] + (r_outer[i] - r_inner[i]) * (rmax - Rmin) / (Rmax - Rmin);
370 r_bot[i] =
371 r_inner[i] + (r_outer[i] - r_inner[i]) * (rmin - Rmin) / (Rmax - Rmin);
372 }
373
374 // Compute coordinates
375 f[0] = r_bot[0] + (0.5 * (s[0] + 1.0)) * (r_top[0] - r_bot[0]);
376 f[1] = r_bot[1] + (0.5 * (s[0] + 1.0)) * (r_top[1] - r_bot[1]);
377 f[2] = zmin + (zmax - zmin) * (0.5 * (s[1] + 1.0));
378 }
379
380 //=================================================================
381 /// Left face of a macro element \f$s \in [-1,1]*[-1,1] \f$
382 //=================================================================
383 void QuarterPipeDomain::r_D(const unsigned& t,
384 const Vector<double>& s,
386 const double& rmin,
387 const double& rmax,
388 const double& thetamin,
389 const double& thetamax,
390 const double& zmin,
391 const double& zmax)
392 {
393 Vector<double> x(1);
394 x[0] = thetamax + (0.5 * (s[0] + 1.0)) * (thetamin - thetamax);
395
396 // Point on outer wall
399
400 // Point on inner wall
403
404 // Get layer
405 for (unsigned i = 0; i < 2; i++)
406 {
407 f[i] =
408 r_inner[i] + (r_outer[i] - r_inner[i]) * (rmin - Rmin) / (Rmax - Rmin);
409 }
410 f[2] = zmin + (zmax - zmin) * (0.5 * (s[1] + 1.0));
411 }
412
413 //=================================================================
414 /// Right face of a macro element \f$ s \in [-1,1]*[-1,1] \f$
415 //=================================================================
416 void QuarterPipeDomain::r_U(const unsigned& t,
417 const Vector<double>& s,
419 const double& rmin,
420 const double& rmax,
421 const double& thetamin,
422 const double& thetamax,
423 const double& zmin,
424 const double& zmax)
425 {
426 Vector<double> x(1);
427 x[0] = thetamax + (0.5 * (s[0] + 1.0)) * (thetamin - thetamax);
428
429 // Point on outer wall
432
433 // Point on inner wall
436
437 // Get layer
438 for (unsigned i = 0; i < 2; i++)
439 {
440 f[i] =
441 r_inner[i] + (r_outer[i] - r_inner[i]) * (rmax - Rmin) / (Rmax - Rmin);
442 }
443 f[2] = zmin + (zmax - zmin) * (0.5 * (s[1] + 1.0));
444 }
445
446 //=================================================================
447 /// Front face of a macro element \f$ s \in [-1,1]*[-1,1] \f$
448 //=================================================================
449 void QuarterPipeDomain::r_F(const unsigned& t,
450 const Vector<double>& s,
452 const double& rmin,
453 const double& rmax,
454 const double& thetamin,
455 const double& thetamax,
456 const double& zmin,
457 const double& zmax)
458 {
459 Vector<double> x(1);
460 x[0] = thetamax + (0.5 * (s[0] + 1.0)) * (thetamin - thetamax);
461
462 // Point on outer wall
465
466 // Point on inner wall
469
470 // Get layer
471 double rad = rmin + (0.5 * (s[1] + 1.0)) * (rmax - rmin);
472 for (unsigned i = 0; i < 2; i++)
473 {
474 f[i] =
475 r_inner[i] + (r_outer[i] - r_inner[i]) * (rad - Rmin) / (Rmax - Rmin);
476 }
477 f[2] = zmax;
478 }
479
480 //=================================================================
481 /// Back face of a macro element \f$ s \in [-1,1]*[-1,1] \f$
482 //=================================================================
483 void QuarterPipeDomain::r_B(const unsigned& t,
484 const Vector<double>& s,
486 const double& rmin,
487 const double& rmax,
488 const double& thetamin,
489 const double& thetamax,
490 const double& zmin,
491 const double& zmax)
492 {
493 Vector<double> x(1);
494 x[0] = thetamax + (0.5 * (s[0] + 1.0)) * (thetamin - thetamax);
495
496 // Point on outer wall
499
500 // Point on inner wall
503
504 // Get layer
505 double rad = rmin + (0.5 * (s[1] + 1.0)) * (rmax - rmin);
506 for (unsigned i = 0; i < 2; i++)
507 {
508 f[i] =
509 r_inner[i] + (r_outer[i] - r_inner[i]) * (rad - Rmin) / (Rmax - Rmin);
510 }
511 f[2] = zmin;
512 }
513
514} // namespace oomph
515
516#endif
static char t char * s
Definition cfortran.h:568
cstr elem_len * i
Definition cfortran.h:603
char t
Definition cfortran.h:568
Base class for Domains with curvilinear and/or time-dependent boundaries. Domain boundaries are typic...
Definition domain.h:67
Vector< MacroElement * > Macro_element_pt
Vector of pointers to macro elements.
Definition domain.h:301
Steady ellipse with half axes A and B as geometric object:
A geometric object is an object that provides a parametrised description of its shape via the functio...
virtual void position(const Vector< double > &zeta, Vector< double > &r) const =0
Parametrised position on object at current time: r(zeta).
An OomphLibError object which should be thrown when an run-time error is encountered....
Domain representing a quarter pipe.
double axial_spacing_fct(const double &xi)
Function that implements axial spacing of macro elements.
unsigned Nr
Number of elements radial direction.
void r_L(const unsigned &t, const Vector< double > &zeta, Vector< double > &f, const double &rmin, const double &rmax, const double &thetamin, const double &thetamax, const double &zmin, const double &zmax)
Boundary of macro element zeta .
GeomObject * Inner_boundary_cross_section_pt
Geom object representing the inner boundary of the cross section.
static double default_axial_spacing_fct(const double &xi)
Default for function that implements axial spacing of macro elements.
double(* AxialSpacingFctPt)(const double &xi)
Typedef for function pointer for function that implements axial spacing of macro elements.
void r_U(const unsigned &t, const Vector< double > &zeta, Vector< double > &f, const double &rmin, const double &rmax, const double &thetamin, const double &thetamax, const double &zmin, const double &zmax)
Boundary of macro element zeta .
QuarterPipeDomain(const QuarterPipeDomain &)=delete
Broken copy constructor.
void r_F(const unsigned &t, const Vector< double > &zeta, Vector< double > &f, const double &rmin, const double &rmax, const double &thetamin, const double &thetamax, const double &zmin, const double &zmax)
Boundary of macro element zeta .
unsigned Nz
Number of elements axial direction.
void r_R(const unsigned &t, const Vector< double > &zeta, Vector< double > &f, const double &rmin, const double &rmax, const double &thetamin, const double &thetamax, const double &zmin, const double &zmax)
Boundary of macro element zeta .
void operator=(const QuarterPipeDomain &)=delete
Broken assignment operator.
void r_B(const unsigned &t, const Vector< double > &zeta, Vector< double > &f, const double &rmin, const double &rmax, const double &thetamin, const double &thetamax, const double &zmin, const double &zmax)
Boundary of macro element zeta .
AxialSpacingFctPt & axial_spacing_fct_pt()
Function pointer for function that implements axial spacing of macro elements.
AxialSpacingFctPt Axial_spacing_fct_pt
Function pointer for function that implements axial spacing of macro elements.
GeomObject * Outer_boundary_cross_section_pt
Geom object representing the outer boundary of the cross section.
void macro_element_boundary(const unsigned &t, const unsigned &i_macro, const unsigned &i_direct, const Vector< double > &s, Vector< double > &f)
Vector representation of the i_macro-th macro element boundary i_direct (U/D/L/R/F/B) at time level t...
void r_D(const unsigned &t, const Vector< double > &zeta, Vector< double > &f, const double &rmin, const double &rmax, const double &thetamin, const double &thetamax, const double &zmin, const double &zmax)
Boundary of macro element zeta .
unsigned Ntheta
Number of elements azimuthal direction.
QuarterPipeDomain(const unsigned &ntheta, const unsigned &nr, const unsigned &nz, const double &rmin, const double &rmax, const double &length)
Constructor: Pass number of elements in various directions, the inner and outer radius and the length...
TAdvectionDiffusionReactionElement<NREAGENT,DIM,NNODE_1D> elements are isoparametric triangular DIM-d...
const double Pi
50 digits from maple
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).