quarter_tube_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_TUBE_DOMAIN_HEADER
28#define OOMPH_QUARTER_TUBE_DOMAIN_HEADER
29
30// Generic oomph-lib includes
31#include "generic/quadtree.h"
32#include "generic/domain.h"
34
35namespace oomph
36{
37 //=================================================================
38 /// Quarter tube as domain. Domain is bounded by
39 /// curved boundary which is represented by a GeomObject. Domain is
40 /// parametrised by three macro elements in each of the nlayer slices
41 //=================================================================
43 {
44 public:
45 /// Constructor: Pass boundary object and start and end coordinates
46 /// and fraction along boundary object where outer ring is divided.
47 /// We form nlayer axial slices.
48 QuarterTubeDomain(GeomObject* boundary_geom_object_pt,
49 const Vector<double>& xi_lo,
50 const double& fract_mid,
51 const Vector<double>& xi_hi,
52 const unsigned& nlayer)
53 : Xi_lo(xi_lo),
55 Xi_hi(xi_hi),
57 Wall_pt(boundary_geom_object_pt),
60 {
61 // There are three macro elements
62 unsigned nmacro = 3 * nlayer;
63
64 // Resize
66
67 // Create macro elements
68 for (unsigned i = 0; i < nmacro; i++)
69 {
71 }
72 }
73
74 /// Broken copy constructor
76
77 /// Broken assignment operator
78 void operator=(const QuarterTubeDomain&) = delete;
79
80 /// Destructor: empty; cleanup done in base class
82
83 /// Typedef for function pointer for function that squashes
84 /// the outer two macro elements towards
85 /// the wall by mapping the input value of the "radial" macro element
86 /// coordinate to the return value
87 typedef double (*BLSquashFctPt)(const double& s);
88
89
90 /// Function pointer for function that squashes
91 /// the outer two macro elements towards
92 /// the wall by mapping the input value of the "radial" macro element
93 /// coordinate to the return value
98
99
100 /// Function that squashes the outer two macro elements towards
101 /// the wall by mapping the input value of the "radial" macro element
102 /// coordinate to the return value.
103 double s_squashed(const double& s)
104 {
105 return BL_squash_fct_pt(s);
106 }
107
108
109 /// Typedef for function pointer for function that implements
110 /// axial spacing of macro elements
111 typedef double (*AxialSpacingFctPt)(const double& xi);
112
113
114 /// Function pointer for function that implements
115 /// axial spacing of macro elements
120
121 /// Function that implements
122 /// axial spacing of macro elements
123 double axial_spacing_fct(const double& xi)
124 {
125 return Axial_spacing_fct_pt(xi);
126 }
127
128
129 /// Vector representation of the i_macro-th macro element
130 /// boundary i_direct (L/R/D/U/B/F) at time level t
131 /// (t=0: present; t>0: previous):
132 /// f(s).
133 void macro_element_boundary(const unsigned& t,
134 const unsigned& i_macro,
135 const unsigned& i_direct,
136 const Vector<double>& s,
137 Vector<double>& f);
138
139 private:
140 /// Lower limit for the coordinates along the wall
142
143 /// Fraction along wall where outer ring is to be divided
144 double Fract_mid;
145
146 /// Upper limit for the coordinates along the wall
148
149 /// Number of layers
150 unsigned Nlayer;
151
152 /// Pointer to geometric object that represents the curved wall
154
155
156 /// Function pointer for function that squashes
157 /// the outer two macro elements towards
158 /// the wall by mapping the input value of the "radial" macro element
159 /// coordinate to the return value
161
162
163 /// Default for function that squashes
164 /// the outer two macro elements towards
165 /// the wall by mapping the input value of the "radial" macro element
166 /// coordinate to the return value: Identity.
167 static double default_BL_squash_fct(const double& s)
168 {
169 return s;
170 }
171
172
173 /// Function pointer for function that implements
174 /// axial spacing of macro elements
176
177
178 /// Default for function that implements
179 /// axial spacing of macro elements
180 static double default_axial_spacing_fct(const double& xi)
181 {
182 return xi;
183 }
184
185
186 /// Boundary of central box macro element in layer i_layer
187 /// zeta \f$ \in [-1,1]^2 \f$
188 void r_centr_L(const unsigned& t,
189 const Vector<double>& zeta,
190 const unsigned& i_layer,
191 Vector<double>& f);
192
193 /// Boundary of central box macro element in layer i_layer
194 /// zeta \f$ \in [-1,1]^2 \f$
195 void r_centr_R(const unsigned& t,
196 const Vector<double>& zeta,
197 const unsigned& i_layer,
198 Vector<double>& f);
199
200 /// Boundary of central box macro element in layer i_layer
201 /// zeta \f$ \in [-1,1]^2 \f$
202 void r_centr_D(const unsigned& t,
203 const Vector<double>& zeta,
204 const unsigned& i_layer,
205 Vector<double>& f);
206
207 /// Boundary of central box macro element in layer i_layer
208 /// zeta \f$ \in [-1,1]^2 \f$
209 void r_centr_U(const unsigned& t,
210 const Vector<double>& zeta,
211 const unsigned& i_layer,
212 Vector<double>& f);
213
214 /// Boundary of central box macro element in layer i_layer
215 /// zeta \f$ \in [-1,1]^2 \f$
216 void r_centr_B(const unsigned& t,
217 const Vector<double>& zeta,
218 const unsigned& i_layer,
219 Vector<double>& f);
220
221 /// Boundary of central box macro element in layer i_layer
222 /// zeta \f$ \in [-1,1]^2 \f$
223 void r_centr_F(const unsigned& t,
224 const Vector<double>& zeta,
225 const unsigned& i_layer,
226 Vector<double>& f);
227
228
229 /// Boundary of bottom right box macro element in layer i_layer
230 /// zeta \f$ \in [-1,1]^2 \f$
231 void r_bot_right_L(const unsigned& t,
232 const Vector<double>& zeta,
233 const unsigned& i_layer,
234 Vector<double>& f);
235
236 /// Boundary of bottom right box macro element in layer i_layer
237 /// zeta \f$ \in [-1,1]^2 \f$
238 void r_bot_right_R(const unsigned& t,
239 const Vector<double>& zeta,
240 const unsigned& i_layer,
241 Vector<double>& f);
242
243 /// Boundary of bottom right box macro element in layer i_layer
244 /// zeta \f$ \in [-1,1]^2 \f$
245 void r_bot_right_D(const unsigned& t,
246 const Vector<double>& zeta,
247 const unsigned& i_layer,
248 Vector<double>& f);
249
250 /// Boundary of bottom right box macro element in layer i_layer
251 /// zeta \f$ \in [-1,1]^2 \f$
252 void r_bot_right_U(const unsigned& t,
253 const Vector<double>& zeta,
254 const unsigned& i_layer,
255 Vector<double>& f);
256
257 /// Boundary of bottom right box macro element in layer i_layer
258 /// zeta \f$ \in [-1,1]^2 \f$
259 void r_bot_right_B(const unsigned& t,
260 const Vector<double>& zeta,
261 const unsigned& i_layer,
262 Vector<double>& f);
263
264 /// Boundary of bottom right box macro element in layer i_layer
265 /// zeta \f$ \in [-1,1]^2 \f$
266 void r_bot_right_F(const unsigned& t,
267 const Vector<double>& zeta,
268 const unsigned& i_layer,
269 Vector<double>& f);
270
271
272 /// Boundary of top left box macro element in layer i_layer
273 /// zeta \f$ \in [-1,1]^2 \f$
274 void r_top_left_L(const unsigned& t,
275 const Vector<double>& zeta,
276 const unsigned& i_layer,
277 Vector<double>& f);
278
279 /// Boundary of top left box macro element in layer i_layer
280 /// zeta \f$ \in [-1,1]^2 \f$
281 void r_top_left_R(const unsigned& t,
282 const Vector<double>& zeta,
283 const unsigned& i_layer,
284 Vector<double>& f);
285
286 /// Boundary of top left box macro element in layer i_layer
287 /// zeta \f$ \in [-1,1]^2 \f$
288 void r_top_left_D(const unsigned& t,
289 const Vector<double>& zeta,
290 const unsigned& i_layer,
291 Vector<double>& f);
292
293 /// Boundary of top left box macro element in layer i_layer
294 /// zeta \f$ \in [-1,1]^2 \f$
295 void r_top_left_U(const unsigned& t,
296 const Vector<double>& zeta,
297 const unsigned& i_layer,
298 Vector<double>& f);
299
300 /// Boundary of top left box macro element in layer i_layer
301 /// zeta \f$ \in [-1,1]^2 \f$
302 void r_top_left_B(const unsigned& t,
303 const Vector<double>& zeta,
304 const unsigned& i_layer,
305 Vector<double>& f);
306
307 /// Boundary of top left box macro element in layer i_layer
308 /// zeta \f$ \in [-1,1]^2 \f$
309 void r_top_left_F(const unsigned& t,
310 const Vector<double>& zeta,
311 const unsigned& i_layer,
312 Vector<double>& f);
313 };
314
315
316 /////////////////////////////////////////////////////////////////////////
317 /////////////////////////////////////////////////////////////////////////
318 /////////////////////////////////////////////////////////////////////////
319
320 //=================================================================
321 /// Vector representation of the imacro-th macro element
322 /// boundary idirect (L/R/D/U/B/F) at time level t
323 /// (t=0: present; t>0: previous): f(s)
324 //=================================================================
326 const unsigned& imacro,
327 const unsigned& idirect,
328 const Vector<double>& s,
330 {
331 using namespace OcTreeNames;
332
333#ifdef WARN_ABOUT_SUBTLY_CHANGED_OOMPH_INTERFACES
334 // Warn about time argument being moved to the front
336 "Order of function arguments has changed between versions 0.8 and 0.85",
337 "QuarterTubeDomain::macro_element_boundary(...)",
339#endif
340
341 unsigned ilayer = unsigned(imacro / 3);
342
343 // Which macro element?
344 // --------------------
345 switch (imacro % 3)
346 {
347 // Macro element 0: Central box
348 case 0:
349
350 // Which direction?
351 if (idirect == L)
352 {
353 r_centr_L(t, s, ilayer, f);
354 }
355 else if (idirect == R)
356 {
357 r_centr_R(t, s, ilayer, f);
358 }
359 else if (idirect == D)
360 {
361 r_centr_D(t, s, ilayer, f);
362 }
363 else if (idirect == U)
364 {
365 r_centr_U(t, s, ilayer, f);
366 }
367 else if (idirect == B)
368 {
369 r_centr_B(t, s, ilayer, f);
370 }
371 else if (idirect == F)
372 {
373 r_centr_F(t, s, ilayer, f);
374 }
375 else
376 {
377 std::ostringstream error_stream;
378 error_stream << "idirect is " << idirect
379 << " not one of L, R, D, U, B, F" << std::endl;
380
381 throw OomphLibError(error_stream.str(),
384 }
385
386 break;
387
388 // Macro element 1: Bottom right
389 case 1:
390
391 // Which direction?
392 if (idirect == L)
393 {
394 r_bot_right_L(t, s, ilayer, f);
395 }
396 else if (idirect == R)
397 {
398 r_bot_right_R(t, s, ilayer, f);
399 }
400 else if (idirect == D)
401 {
402 r_bot_right_D(t, s, ilayer, f);
403 }
404 else if (idirect == U)
405 {
406 r_bot_right_U(t, s, ilayer, f);
407 }
408 else if (idirect == B)
409 {
410 r_bot_right_B(t, s, ilayer, f);
411 }
412 else if (idirect == F)
413 {
414 r_bot_right_F(t, s, ilayer, f);
415 }
416 else
417 {
418 std::ostringstream error_stream;
419 error_stream << "idirect is " << idirect
420 << " not one of L, R, D, U, B, F" << std::endl;
421
422 throw OomphLibError(error_stream.str(),
425 }
426
427 break;
428
429 // Macro element 2:Top left
430 case 2:
431
432 // Which direction?
433 if (idirect == L)
434 {
435 r_top_left_L(t, s, ilayer, f);
436 }
437 else if (idirect == R)
438 {
439 r_top_left_R(t, s, ilayer, f);
440 }
441 else if (idirect == D)
442 {
443 r_top_left_D(t, s, ilayer, f);
444 }
445 else if (idirect == U)
446 {
447 r_top_left_U(t, s, ilayer, f);
448 }
449 else if (idirect == B)
450 {
451 r_top_left_B(t, s, ilayer, f);
452 }
453 else if (idirect == F)
454 {
455 r_top_left_F(t, s, ilayer, f);
456 }
457 else
458 {
459 std::ostringstream error_stream;
460 error_stream << "idirect is " << idirect
461 << " not one of L, R, D, U, B, F" << std::endl;
462
463 throw OomphLibError(error_stream.str(),
466 }
467
468 break;
469
470 default:
471
472 // Error
473 std::ostringstream error_stream;
474 error_stream << "Wrong imacro " << imacro << std::endl;
475 throw OomphLibError(
477 }
478 }
479
480 //=======================================================================
481 /// Boundary of central box macro element in layer i_layer
482 /// zeta \f$ \in [-1,1]^2 \f$
483 //=======================================================================
484 void QuarterTubeDomain::r_centr_L(const unsigned& t,
485 const Vector<double>& zeta,
486 const unsigned& i_layer,
488 {
489 // Wall coordinates along top edge of wall
490 Vector<double> x(2);
491 x[0] =
492 Xi_lo[0] + (Xi_hi[0] - Xi_lo[0]) *
493 axial_spacing_fct((0.5 * (1.0 + zeta[1]) + double(i_layer)) /
494 double(Nlayer));
495 x[1] = Xi_hi[1];
496
497 // Get position vector to upper edge of wall
499 Wall_pt->position(t, x, r_top);
500
501 // Scale it down to half the height
502 f[0] = r_top[0];
503 f[1] = r_top[1] * 0.25 * (1.0 + zeta[0]);
504 // Warp it:
505 double rho = 0.0; // 0.25*(1.0+zeta[0]);
506 f[2] = x[0] + rho * (r_top[2] - x[0]);
507
508 // f[2]=r_top[2];
509 }
510
511 //=======================================================================
512 /// Boundary of central box macro element in layer i_layer
513 /// zeta \f$ \in [-1,1]^2 \f$
514 //=======================================================================
515 void QuarterTubeDomain::r_centr_R(const unsigned& t,
516 const Vector<double>& zeta,
517 const unsigned& i_layer,
519 {
520 // Note the repetition in the calculation, there is some scope
521 // for optimisation
522
523 // Wall coordinates along top edge of wall
524 Vector<double> x(2);
525 x[0] =
526 Xi_lo[0] + (Xi_hi[0] - Xi_lo[0]) *
527 axial_spacing_fct((0.5 * (1.0 + zeta[1]) + double(i_layer)) /
528 double(Nlayer));
529 x[1] = Xi_hi[1];
530
531 // Get position vector to upper edge of wall
533 Wall_pt->position(t, x, r_top);
534
535 // Wall coordinates along bottom edge of wall
536 x[0] =
537 Xi_lo[0] + (Xi_hi[0] - Xi_lo[0]) *
538 axial_spacing_fct((0.5 * (1.0 + zeta[1]) + double(i_layer)) /
539 double(Nlayer));
540 x[1] = Xi_lo[1];
541
542 // Get position vector to bottom edge of wall
545
546 // Scale it down to half the height, halfway across width
547 f[0] = 0.5 * r_bottom[0];
548 f[1] = r_top[1] * 0.25 * (1.0 + zeta[0]);
549
550 // Warp it:
551 double rho = 0.0; // 0.25*(1.0+zeta[0]);
552 f[2] = x[0] + rho * (r_top[2] - x[0]);
553 // f[2]=r_top[2];
554 }
555
556 //=======================================================================
557 /// Boundary of central box macro element in layer i_layer
558 /// zeta \f$ \in [-1,1]^2 \f$
559 //=======================================================================
560 void QuarterTubeDomain::r_centr_D(const unsigned& t,
561 const Vector<double>& zeta,
562 const unsigned& i_layer,
564 {
565 // Wall coordinates along bottom edge of wall
566 Vector<double> x(2);
567 x[0] =
568 Xi_lo[0] + (Xi_hi[0] - Xi_lo[0]) *
569 axial_spacing_fct((0.5 * (1.0 + zeta[1]) + double(i_layer)) /
570 double(Nlayer));
571 x[1] = Xi_lo[1];
572
573 // Get position vector to bottom edge of wall
576
577 // Scale it down to half the width
578 f[0] = r_bottom[0] * 0.25 * (1.0 + zeta[0]);
579 f[1] = r_bottom[1];
580
581 // Warp it:
582 double rho = 0.0; // 0.25*(1.0+zeta[0]);
583 f[2] = x[0] + rho * (r_bottom[2] - x[0]);
584 // f[2]=r_bottom[2];
585 }
586
587 //=======================================================================
588 /// Boundary of central box macro element in layer i_layer
589 /// zeta \f$ \in [-1,1]^2 \f$
590 //=======================================================================
591 void QuarterTubeDomain::r_centr_U(const unsigned& t,
592 const Vector<double>& zeta,
593 const unsigned& i_layer,
595 {
596 // Wall coordinates along top edge of wall
597 Vector<double> x(2);
598 x[0] =
599 Xi_lo[0] + (Xi_hi[0] - Xi_lo[0]) *
600 axial_spacing_fct((0.5 * (1.0 + zeta[1]) + double(i_layer)) /
601 double(Nlayer));
602 x[1] = Xi_hi[1];
603
604 // Get position vector to upper edge of wall
606 Wall_pt->position(t, x, r_top);
607
608 // Wall coordinates along bottom edge of wall
609 x[0] =
610 Xi_lo[0] + (Xi_hi[0] - Xi_lo[0]) *
611 axial_spacing_fct((0.5 * (1.0 + zeta[1]) + double(i_layer)) /
612 double(Nlayer));
613 x[1] = Xi_lo[1];
614
615 // Get position vector to bottom edge of wall
618
619 // Scale it down to half the width
620 f[0] = r_bottom[0] * 0.25 * (1.0 + zeta[0]);
621 f[1] = 0.5 * r_top[1];
622
623 // Warp it:
624 double rho = 0.0; // 0.25*(1.0+zeta[0]);
625 f[2] = x[0] + rho * (r_bottom[2] - x[0]);
626 // f[2]=r_bottom[2];
627 }
628
629 //=======================================================================
630 /// Boundary of central box macro element in layer i_layer
631 /// zeta \f$ \in [-1,1]^2 \f$
632 //=======================================================================
633 void QuarterTubeDomain::r_centr_B(const unsigned& t,
634 const Vector<double>& zeta,
635 const unsigned& i_layer,
637 {
638 // Wall coordinates along bottom edge of wall
639 Vector<double> x(2);
640 x[0] = Xi_lo[0] + (Xi_hi[0] - Xi_lo[0]) *
642 x[1] = Xi_lo[1];
643
644 // Get position vector to bottom edge of wall
647
648 // Wall coordinates along top edge of wall
649 x[0] = Xi_lo[0] + (Xi_hi[0] - Xi_lo[0]) *
651 x[1] = Xi_hi[1];
652
653 // Get position vector to top edge of wall
655 Wall_pt->position(t, x, r_top);
656
657 // Map it
658 f[0] = r_bottom[0] * 0.25 * (1.0 + zeta[0]);
659 f[1] = r_top[1] * 0.25 * (1.0 + zeta[1]);
660
661 // Warp it:
662 double rho = 0.0; // 0.25*(1.0+zeta[1]);
663 f[2] = x[0] + rho * (r_top[2] - x[0]);
664 // f[2]=r_top[2];
665 }
666
667 //=======================================================================
668 /// Boundary of central box macro element in layer i_layer
669 /// zeta \f$ \in [-1,1]^2 \f$
670 //=======================================================================
671 void QuarterTubeDomain::r_centr_F(const unsigned& t,
672 const Vector<double>& zeta,
673 const unsigned& i_layer,
675 {
676 // Wall coordinates along bottom edge of wall
677 Vector<double> x(2);
678 x[0] = Xi_lo[0] + (Xi_hi[0] - Xi_lo[0]) *
679 axial_spacing_fct(double(1 + i_layer) / double(Nlayer));
680 x[1] = Xi_lo[1];
681
682 // Get position vector to bottom edge of wall
685
686 // Wall coordinates along top edge of wall
687 x[0] = Xi_lo[0] + (Xi_hi[0] - Xi_lo[0]) *
688 axial_spacing_fct(double(1 + i_layer) / double(Nlayer));
689 x[1] = Xi_hi[1];
690
691 // Get position vector to top edge of wall
693 Wall_pt->position(t, x, r_top);
694
695 // Map it
696 f[0] = r_bottom[0] * 0.25 * (1.0 + zeta[0]);
697 f[1] = r_top[1] * 0.25 * (1.0 + zeta[1]);
698
699 // Warp it:
700 double rho = 0.0; // 0.25*(1.0+zeta[1]);
701 f[2] = x[0] + rho * (r_top[2] - x[0]);
702 // f[2]=r_top[2];
703 }
704
705 // #####################################################################
706
707 //=======================================================================
708 /// Boundary of bottom right box macro element in layer i_layer
709 /// zeta \f$ \in [-1,1]^2 \f$
710 //=======================================================================
712 const Vector<double>& zeta,
713 const unsigned& i_layer,
715 {
716 r_centr_R(t, zeta, i_layer, f);
717 }
718
719 //=======================================================================
720 /// Boundary of bottom right box macro element in layer i_layer
721 /// zeta \f$ \in [-1,1]^2 \f$
722 //=======================================================================
724 const Vector<double>& zeta,
725 const unsigned& i_layer,
727 {
728 // Wall coordinates
729 Vector<double> x(2);
730 x[0] =
731 Xi_lo[0] + (Xi_hi[0] - Xi_lo[0]) *
732 axial_spacing_fct((0.5 * (1.0 + zeta[1]) + double(i_layer)) /
733 double(Nlayer));
734 x[1] = Xi_lo[1] + Fract_mid * (Xi_hi[1] - Xi_lo[1]) * 0.5 * (1.0 + zeta[0]);
735
736 // Get position vector on wall
737 Wall_pt->position(t, x, f);
738 }
739
740 //=======================================================================
741 /// Boundary of bottom right box macro element in layer i_layer
742 /// zeta \f$ \in [-1,1]^2 \f$
743 //=======================================================================
745 const Vector<double>& zeta,
746 const unsigned& i_layer,
748 {
749 // Wall coordinates along bottom edge of wall
750 Vector<double> x(2);
751 x[0] =
752 Xi_lo[0] + (Xi_hi[0] - Xi_lo[0]) *
753 axial_spacing_fct((0.5 * (1.0 + zeta[1]) + double(i_layer)) /
754 double(Nlayer));
755 x[1] = Xi_lo[1];
756
757 // Get position vector to bottom edge of wall
760
761 // Scale it down to half the width
762 f[0] = 0.5 * r_bottom[0] * (1.0 + s_squashed(0.5 * (1.0 + zeta[0])));
763 f[1] = r_bottom[1];
764
765 // Warp it:
766 double rho = s_squashed(0.5 * (1.0 + zeta[0]));
767 f[2] = x[0] + rho * (r_bottom[2] - x[0]);
768 // f[2]=r_bottom[2];
769 }
770
771 //=======================================================================
772 /// Boundary of bottom right box macro element in layer i_layer
773 /// zeta \f$ \in [-1,1]^2 \f$
774 //=======================================================================
776 const Vector<double>& zeta,
777 const unsigned& i_layer,
779 {
780 // Wall coordinates of dividing line
781 Vector<double> x(2);
782 x[0] =
783 Xi_lo[0] + (Xi_hi[0] - Xi_lo[0]) *
784 axial_spacing_fct((0.5 * (1.0 + zeta[1]) + double(i_layer)) /
785 double(Nlayer));
786 x[1] = Xi_lo[1] + Fract_mid * (Xi_hi[1] - Xi_lo[1]);
787
788 // Get position vector on dividing line
790 Wall_pt->position(t, x, r_div);
791
792 // Position vector to corner of central box
795 zeta_central[0] = 1.0;
796 zeta_central[1] = zeta[1];
798
799 // Straight line across
800 f[0] = r_central[0] +
801 (r_div[0] - r_central[0]) * s_squashed(0.5 * (1.0 + zeta[0]));
802 f[1] = r_central[1] +
803 (r_div[1] - r_central[1]) * s_squashed(0.5 * (1.0 + zeta[0]));
804 f[2] = r_central[2] +
805 (r_div[2] - r_central[2]) * s_squashed(0.5 * (1.0 + zeta[0]));
806 }
807
808 //=======================================================================
809 /// Boundary of bottom right box macro element in layer i_layer
810 /// zeta \f$ \in [-1,1]^2 \f$
811 //=======================================================================
813 const Vector<double>& zeta,
814 const unsigned& i_layer,
816 {
817 // Wall coordinates
818 Vector<double> x(2);
819 x[0] = Xi_lo[0] + (Xi_hi[0] - Xi_lo[0]) *
821 x[1] = Xi_lo[1] + Fract_mid * (Xi_hi[1] - Xi_lo[1]) * 0.5 * (1.0 + zeta[1]);
822
823 // Get position vector to wall
825 Wall_pt->position(t, x, r_wall);
826
827 // Get position vector on central box
830 zeta_central[0] = zeta[1];
831 zeta_central[1] = -1.0;
833
834 // Straight line across
835 f[0] = r_central[0] +
836 (r_wall[0] - r_central[0]) * s_squashed(0.5 * (1.0 + zeta[0]));
837 f[1] = r_central[1] +
838 (r_wall[1] - r_central[1]) * s_squashed(0.5 * (1.0 + zeta[0]));
839 f[2] = r_central[2] +
840 (r_wall[2] - r_central[2]) * s_squashed(0.5 * (1.0 + zeta[0]));
841 }
842
843 //=======================================================================
844 /// Boundary of bottom right box macro element in layer i_layer
845 /// zeta \f$ \in [-1,1]^2 \f$
846 //=======================================================================
848 const Vector<double>& zeta,
849 const unsigned& i_layer,
851 {
852 // Wall coordinates
853 Vector<double> x(2);
854 x[0] = Xi_lo[0] + (Xi_hi[0] - Xi_lo[0]) *
855 axial_spacing_fct(double(1 + i_layer) / double(Nlayer));
856 x[1] = Xi_lo[1] + Fract_mid * (Xi_hi[1] - Xi_lo[1]) * 0.5 * (1.0 + zeta[1]);
857
858 // Get position vector to wall
860 Wall_pt->position(t, x, r_wall);
861
862 // Get position vector on central box
865 zeta_central[0] = zeta[1];
866 zeta_central[1] = 1.0;
868
869 // Straight line across
870 f[0] = r_central[0] +
871 (r_wall[0] - r_central[0]) * s_squashed(0.5 * (1.0 + zeta[0]));
872 f[1] = r_central[1] +
873 (r_wall[1] - r_central[1]) * s_squashed(0.5 * (1.0 + zeta[0]));
874 f[2] = r_central[2] +
875 (r_wall[2] - r_central[2]) * s_squashed(0.5 * (1.0 + zeta[0]));
876 }
877
878 // #####################################################################
879
880 //=======================================================================
881 /// Boundary of top left box macro element in layer i_layer
882 /// zeta \f$ \in [-1,1]^2 \f$
883 //=======================================================================
884 void QuarterTubeDomain::r_top_left_L(const unsigned& t,
885 const Vector<double>& zeta,
886 const unsigned& i_layer,
888 {
889 // Wall coordinates along top edge of wall
890 Vector<double> x(2);
891 x[0] =
892 Xi_lo[0] + (Xi_hi[0] - Xi_lo[0]) *
893 axial_spacing_fct((0.5 * (1.0 + zeta[1]) + double(i_layer)) /
894 double(Nlayer));
895 x[1] = Xi_hi[1];
896
897 // Get position vector to upper edge of wall
899 Wall_pt->position(t, x, r_top);
900
901 // Scale it down to half the height
902 f[0] = r_top[0];
903 f[1] = 0.5 * r_top[1] * (1.0 + s_squashed(0.5 * (1.0 + zeta[0])));
904
905 // Warp it:
906 double rho = s_squashed(0.5 * (1.0 + zeta[0]));
907 f[2] = x[0] + rho * (r_top[2] - x[0]);
908 // f[2]=r_top[2];
909 }
910
911 //=======================================================================
912 /// Boundary of top left box macro element in layer i_layer
913 /// zeta \f$ \in [-1,1]^2 \f$
914 //=======================================================================
915 void QuarterTubeDomain::r_top_left_R(const unsigned& t,
916 const Vector<double>& zeta,
917 const unsigned& i_layer,
919 {
920 // Swap coordinates
922 zeta_br[0] = zeta[0];
923 zeta_br[1] = zeta[1];
925 }
926
927 //=======================================================================
928 /// Boundary of top left box macro element in layer i_layer
929 /// zeta \f$ \in [-1,1]^2 \f$
930 //=======================================================================
931 void QuarterTubeDomain::r_top_left_D(const unsigned& t,
932 const Vector<double>& zeta,
933 const unsigned& i_layer,
935 {
936 r_centr_U(t, zeta, i_layer, f);
937 }
938
939 //=======================================================================
940 /// Boundary of top left box macro element in layer i_layer
941 /// zeta \f$ \in [-1,1]^2 \f$
942 //=======================================================================
943 void QuarterTubeDomain::r_top_left_U(const unsigned& t,
944 const Vector<double>& zeta,
945 const unsigned& i_layer,
947 {
948 // Wall coordinates
949 Vector<double> x(2);
950 x[0] =
951 Xi_lo[0] + (Xi_hi[0] - Xi_lo[0]) *
952 axial_spacing_fct((0.5 * (1.0 + zeta[1]) + double(i_layer)) /
953 double(Nlayer));
954 x[1] = Xi_hi[1] +
955 (Xi_lo[1] - Xi_hi[1]) * (1 - Fract_mid) * 0.5 * (1.0 + zeta[0]);
956
957 // Get position vector on wall
958 Wall_pt->position(t, x, f);
959 }
960
961 //=======================================================================
962 /// Boundary of top left box macro element in layer i_layer
963 /// zeta \f$ \in [-1,1]^2 \f$
964 //=======================================================================
965 void QuarterTubeDomain::r_top_left_B(const unsigned& t,
966 const Vector<double>& zeta,
967 const unsigned& i_layer,
969 {
970 // Wall coordinates
971 Vector<double> x(2);
972 x[0] = Xi_lo[0] + (Xi_hi[0] - Xi_lo[0]) *
974 x[1] = Xi_hi[1] +
975 (Xi_lo[1] - Xi_hi[1]) * (1.0 - Fract_mid) * 0.5 * (1.0 + zeta[0]);
976
977 // Get position vector to wall
979 Wall_pt->position(t, x, r_wall);
980
981 // Get position vector on central box
984 zeta_central[0] = zeta[0];
985 zeta_central[1] = -1.0;
987
988 // Straight line across
989 f[0] = r_central[0] +
990 (r_wall[0] - r_central[0]) * s_squashed(0.5 * (1.0 + zeta[1]));
991 f[1] = r_central[1] +
992 (r_wall[1] - r_central[1]) * s_squashed(0.5 * (1.0 + zeta[1]));
993 f[2] = r_central[2] +
994 (r_wall[2] - r_central[2]) * s_squashed(0.5 * (1.0 + zeta[1]));
995 }
996
997 //=======================================================================
998 /// Boundary of top left box macro element in layer i_layer
999 /// zeta \f$ \in [-1,1]^2 \f$
1000 //=======================================================================
1002 const Vector<double>& zeta,
1003 const unsigned& i_layer,
1004 Vector<double>& f)
1005 {
1006 // Wall coordinates
1007 Vector<double> x(2);
1008 x[0] = Xi_lo[0] + (Xi_hi[0] - Xi_lo[0]) *
1009 axial_spacing_fct(double(1 + i_layer) / double(Nlayer));
1010 x[1] = Xi_hi[1] +
1011 (Xi_lo[1] - Xi_hi[1]) * (1.0 - Fract_mid) * 0.5 * (1.0 + zeta[0]);
1012
1013 // Get position vector to wall
1015 Wall_pt->position(t, x, r_wall);
1016
1017 // Get position vector on central box
1020 zeta_central[0] = zeta[0];
1021 zeta_central[1] = 1.0;
1023
1024 // Straight line across
1025 f[0] = r_central[0] +
1026 (r_wall[0] - r_central[0]) * s_squashed(0.5 * (1.0 + zeta[1]));
1027 f[1] = r_central[1] +
1028 (r_wall[1] - r_central[1]) * s_squashed(0.5 * (1.0 + zeta[1]));
1029 f[2] = r_central[2] +
1030 (r_wall[2] - r_central[2]) * s_squashed(0.5 * (1.0 + zeta[1]));
1031 }
1032
1033} // namespace oomph
1034
1035#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
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....
An OomphLibWarning object which should be created as a temporary object to issue a warning....
Quarter tube as domain. Domain is bounded by curved boundary which is represented by a GeomObject....
QuarterTubeDomain(const QuarterTubeDomain &)=delete
Broken copy constructor.
BLSquashFctPt & bl_squash_fct_pt()
Function pointer for function that squashes the outer two macro elements towards the wall by mapping ...
void r_top_left_D(const unsigned &t, const Vector< double > &zeta, const unsigned &i_layer, Vector< double > &f)
Boundary of top left box macro element in layer i_layer zeta .
void r_top_left_L(const unsigned &t, const Vector< double > &zeta, const unsigned &i_layer, Vector< double > &f)
Boundary of top left box macro element in layer i_layer zeta .
~QuarterTubeDomain()
Destructor: empty; cleanup done in base class.
void r_top_left_R(const unsigned &t, const Vector< double > &zeta, const unsigned &i_layer, Vector< double > &f)
Boundary of top left box macro element in layer i_layer zeta .
void r_bot_right_L(const unsigned &t, const Vector< double > &zeta, const unsigned &i_layer, Vector< double > &f)
Boundary of bottom right box macro element in layer i_layer zeta .
BLSquashFctPt BL_squash_fct_pt
Function pointer for function that squashes the outer two macro elements towards the wall by mapping ...
void r_centr_B(const unsigned &t, const Vector< double > &zeta, const unsigned &i_layer, Vector< double > &f)
Boundary of central box macro element in layer i_layer zeta .
double axial_spacing_fct(const double &xi)
Function that implements axial spacing of macro elements.
AxialSpacingFctPt & axial_spacing_fct_pt()
Function pointer for function that implements axial spacing of macro elements.
double(* BLSquashFctPt)(const double &s)
Typedef for function pointer for function that squashes the outer two macro elements towards the wall...
static double default_BL_squash_fct(const double &s)
Default for function that squashes the outer two macro elements towards the wall by mapping the input...
void r_centr_D(const unsigned &t, const Vector< double > &zeta, const unsigned &i_layer, Vector< double > &f)
Boundary of central box macro element in layer i_layer zeta .
QuarterTubeDomain(GeomObject *boundary_geom_object_pt, const Vector< double > &xi_lo, const double &fract_mid, const Vector< double > &xi_hi, const unsigned &nlayer)
Constructor: Pass boundary object and start and end coordinates and fraction along boundary object wh...
Vector< double > Xi_lo
Lower limit for the coordinates along the wall.
unsigned Nlayer
Number of layers.
double s_squashed(const double &s)
Function that squashes the outer two macro elements towards the wall by mapping the input value of th...
void r_bot_right_F(const unsigned &t, const Vector< double > &zeta, const unsigned &i_layer, Vector< double > &f)
Boundary of bottom right box macro element in layer i_layer zeta .
void r_bot_right_D(const unsigned &t, const Vector< double > &zeta, const unsigned &i_layer, Vector< double > &f)
Boundary of bottom right box macro element in layer i_layer zeta .
void r_bot_right_U(const unsigned &t, const Vector< double > &zeta, const unsigned &i_layer, Vector< double > &f)
Boundary of bottom right box macro element in layer i_layer zeta .
Vector< double > Xi_hi
Upper limit for the coordinates along the wall.
void r_top_left_B(const unsigned &t, const Vector< double > &zeta, const unsigned &i_layer, Vector< double > &f)
Boundary of top left box macro element in layer i_layer zeta .
void r_top_left_U(const unsigned &t, const Vector< double > &zeta, const unsigned &i_layer, Vector< double > &f)
Boundary of top left box macro element in layer i_layer zeta .
void r_bot_right_R(const unsigned &t, const Vector< double > &zeta, const unsigned &i_layer, Vector< double > &f)
Boundary of bottom right box macro element in layer i_layer zeta .
void r_centr_F(const unsigned &t, const Vector< double > &zeta, const unsigned &i_layer, Vector< double > &f)
Boundary of central box macro element in layer i_layer zeta .
AxialSpacingFctPt Axial_spacing_fct_pt
Function pointer for function that implements axial spacing of macro elements.
void r_centr_L(const unsigned &t, const Vector< double > &zeta, const unsigned &i_layer, Vector< double > &f)
Boundary of central box macro element in layer i_layer zeta .
void operator=(const QuarterTubeDomain &)=delete
Broken assignment operator.
double(* AxialSpacingFctPt)(const double &xi)
Typedef for function pointer for function that implements axial spacing of macro elements.
static double default_axial_spacing_fct(const double &xi)
Default for function that implements axial spacing of macro elements.
void r_centr_R(const unsigned &t, const Vector< double > &zeta, const unsigned &i_layer, Vector< double > &f)
Boundary of central box macro element in layer i_layer zeta .
double Fract_mid
Fraction along wall where outer ring is to be divided.
void r_top_left_F(const unsigned &t, const Vector< double > &zeta, const unsigned &i_layer, Vector< double > &f)
Boundary of top left box macro element in layer i_layer zeta .
void r_bot_right_B(const unsigned &t, const Vector< double > &zeta, const unsigned &i_layer, Vector< double > &f)
Boundary of bottom right box macro element in layer i_layer zeta .
GeomObject * Wall_pt
Pointer to geometric object that represents the curved wall.
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 (L/R/D/U/B/F) at time level t...
void r_centr_U(const unsigned &t, const Vector< double > &zeta, const unsigned &i_layer, Vector< double > &f)
Boundary of central box macro element in layer i_layer zeta .
TAdvectionDiffusionReactionElement<NREAGENT,DIM,NNODE_1D> elements are isoparametric triangular DIM-d...
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).