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-2023 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_TUBE_DOMAIN_HEADER
28#define OOMPH_TUBE_DOMAIN_HEADER
29
30// Generic oomph-lib includes
31#include "../generic/quadtree.h"
32#include "../generic/domain.h"
33#include "../generic/geom_objects.h"
34
35namespace oomph
36{
37 //=================================================================
38 /// Tube as a domain. The entire domain must be defined by
39 /// a GeomObject with the following convention: zeta[0] is the coordinate
40 /// along the centreline, zeta[1] is the theta coordinate around the tube
41 /// wall and zeta[2] is the radial coordinate.
42 /// The outer boundary must lie at zeta[2] = 1.
43 ///
44 /// The domain is
45 /// parametrised by five macro elements (a central box surrounded by
46 /// four curved elements) in each of the nlayer slices. The labelling
47 /// of the macro elements is as follows with the zeta[0] coordinate
48 /// coming out of the page.
49 ///
50 /// ----------------------------
51 /// |\ /|
52 /// | \ Macro / |
53 /// | 3 Element 3 2 |
54 /// | \ / |
55 /// | \----------------/ |
56 /// | | | |
57 /// | 4 | Macro | |
58 /// | | Element 0 | 2 |
59 /// | | | |
60 /// | ----------------- |
61 /// | / \ |
62 /// | 0 Macro 1 |
63 /// | / Element 1 \ |
64 /// | / \|
65 /// |/-------------------------|
66 ///
67 ///
68 //=================================================================
69 class TubeDomain : public Domain
70 {
71 public:
72 /// Constructor: Pass geometric object; start and end limit of the
73 /// centreline coordinate; the theta locations marking the division between
74 /// the elements of the outer ring, labelled from the lower left to the
75 /// upper left in order, theta should be in the range \f$-\pi\f$ to
76 /// \f$\pi\f$; the corresponding fractions of the
77 /// radius at which the central box is to be placed; and the number of
78 /// layers in the domain
83 const unsigned& nlayer)
89 {
90 // There are five macro elements
91 const unsigned n_macro = 5 * nlayer;
93
94 // Create the macro elements
95 for (unsigned i = 0; i < n_macro; i++)
96 {
98 }
99 }
100
101 /// Broken copy constructor
102 TubeDomain(const TubeDomain&) = delete;
103
104 /// Broken assignment operator
105 void operator=(const TubeDomain&) = delete;
106
107 /// Destructor: Empty; cleanup done in base class
109
110 /// Vector representation of the i_macro-th macro element
111 /// boundary i_direct (L/R/D/U/B/F) at time level t
112 /// (t=0: present; t>0: previous):
113 /// f(s).
114 void macro_element_boundary(const unsigned& t,
115 const unsigned& i_macro,
116 const unsigned& i_direct,
117 const Vector<double>& s,
119
120 private:
121 /// Storage for the limits of the centreline coordinate
123
124 /// Storage for the dividing lines on the boundary
125 /// starting from the lower left and proceeding anticlockwise to
126 /// the upper left
128
129 /// Storage for the fraction of the radius at which the central box
130 /// should be located corresponding to the chosen values of theta.
132
133 /// Number of axial layers
134 unsigned Nlayer;
135
136 /// Pointer to geometric object that represents the domain
138
139 /// A very little linear interpolation helper.
140 /// Interpolate from the low
141 /// point to the high point using the coordinate s which is
142 /// assumed to run from -1 to 1.
144 const Vector<double>& high,
145 const double& s,
147 {
148 // Loop over all coordinates
149 for (unsigned i = 0; i < 3; i++)
150 {
151 f[i] = low[i] + (high[i] - low[i]) * 0.5 * (s + 1.0);
152 }
153 }
154 };
155
156
157 /// //////////////////////////////////////////////////////////////////////
158 /// //////////////////////////////////////////////////////////////////////
159 /// //////////////////////////////////////////////////////////////////////
160
161
162 //=================================================================
163 /// Vector representation of the imacro-th macro element
164 /// boundary idirect (L/R/D/U/B/F) at time level t
165 /// (t=0: present; t>0: previous): f(s)
166 //=================================================================
168 const unsigned& imacro,
169 const unsigned& idirect,
170 const Vector<double>& s,
172 {
173 using namespace OcTreeNames;
174
175#ifdef WARN_ABOUT_SUBTLY_CHANGED_OOMPH_INTERFACES
176 // Warn about time argument being moved to the front
178 "Order of function arguments has changed between versions 0.8 and 0.85",
179 "TubeDomain::macro_element_boundary(...)",
181#endif
182
183 // Get the number of the layer
184 unsigned ilayer = unsigned(imacro / 5);
185
186 // Get all required coordinates of the corners of the box
187 // at each end of the layer
189
190 // Get the centreline coordinates at the ends of the layer
192 // Storage for position in the volume
194
195 // Loop over the layers
196 for (unsigned i = 0; i < 2; i++)
197 {
198 // Resize the storage
199 Box[i].resize(4);
200
201 // Get the centreline coordinate
202 zeta_centre[i] =
203 Centreline_limits[0] + (ilayer + i) *
205 (double)(Nlayer);
206
207 // Now get the coordinates of each corner
208 zeta[0] = zeta_centre[i];
209
210 // Loop over the angles
211 for (unsigned j = 0; j < 4; j++)
212 {
213 // Set up the storage
214 Box[i][j].resize(3);
215
216 // Set the other values of zeta
217 zeta[1] = Theta_positions[j];
218 zeta[2] = Radius_box[j];
219
220 // Now get the values
221 Volume_pt->position(t, zeta, Box[i][j]);
222 }
223 }
224
225 // Local storage for positions on the boundaries
227
228 const double pi = MathematicalConstants::Pi;
229
230 // Which macro element?
231 // --------------------
232 switch (imacro % 5)
233 {
234 // Macro element 0: Central box
235 case 0:
236
237 // Choose a direction
238 switch (idirect)
239 {
240 case L:
241 // Need to get the position from the domain
242 // Get the centreline position
243 zeta[0] = zeta_centre[0] +
244 (zeta_centre[1] - zeta_centre[0]) * 0.5 * (s[1] + 1.0);
245 // Get the lower corner
246 zeta[1] = Theta_positions[0];
247 zeta[2] = Radius_box[0];
248 Volume_pt->position(t, zeta, pos_1);
249
250 // Get the upper corner
251 zeta[1] = Theta_positions[3];
252 zeta[2] = Radius_box[3];
253 Volume_pt->position(t, zeta, pos_2);
254
255 // Now interpolate between the two corner positions
257 break;
258
259 case R:
260 // Need to get the position from the domain
261 // Get the centreline position
262 zeta[0] = zeta_centre[0] +
263 (zeta_centre[1] - zeta_centre[0]) * 0.5 * (s[1] + 1.0);
264 // Get the lower corner
265 zeta[1] = Theta_positions[1];
266 zeta[2] = Radius_box[1];
267 Volume_pt->position(t, zeta, pos_1);
268
269 // Get the upper corner
270 zeta[1] = Theta_positions[2];
271 zeta[2] = Radius_box[2];
272 Volume_pt->position(t, zeta, pos_2);
273
274 // Now interpolate between the positions
276 break;
277
278 case D:
279 // Need to get the position from the domain
280 // Get the centreline position
281 zeta[0] = zeta_centre[0] +
282 (zeta_centre[1] - zeta_centre[0]) * 0.5 * (s[1] + 1.0);
283 // Get the left corner
284 zeta[1] = Theta_positions[0];
285 zeta[2] = Radius_box[0];
286 Volume_pt->position(t, zeta, pos_1);
287
288 // Get the right corner
289 zeta[1] = Theta_positions[1];
290 zeta[2] = Radius_box[1];
291 Volume_pt->position(t, zeta, pos_2);
292 // Now interpolate between the positions
294 break;
295
296 case U:
297 // Need to get the position from the domain
298 // Get the centreline position
299 zeta[0] = zeta_centre[0] +
300 (zeta_centre[1] - zeta_centre[0]) * 0.5 * (s[1] + 1.0);
301 // Get the left corner
302 zeta[1] = Theta_positions[3];
303 zeta[2] = Radius_box[3];
304 Volume_pt->position(t, zeta, pos_1);
305
306 // Get the right corner
307 zeta[1] = Theta_positions[2];
308 zeta[2] = Radius_box[2];
309 Volume_pt->position(t, zeta, pos_2);
310
311 // Now interpolate between the positions
313 break;
314
315 case B:
316 // Linearly interpolate between lower left and lower right corners
317 lin_interpolate(Box[0][0], Box[0][1], s[0], pos_1);
318 // Linearly interpolate between upper left and upper right corners
319 lin_interpolate(Box[0][3], Box[0][2], s[0], pos_2);
320 // Finally, linearly interpolate between the upper and lower
321 // positions
323 break;
324
325 case F:
326 // Linearly interpolate between lower left and lower right corners
327 lin_interpolate(Box[1][0], Box[1][1], s[0], pos_1);
328 // Linearly interpolate between upper left and upper right corners
329 lin_interpolate(Box[1][3], Box[1][2], s[0], pos_2);
330 // Finally, linearly interpolate between the upper and lower
331 // positions
333 break;
334
335 default:
336 std::ostringstream error_stream;
337 error_stream << "idirect is " << idirect
338 << " not one of L, R, D, U, B, F" << std::endl;
339
340 throw OomphLibError(error_stream.str(),
343 break;
344 }
345
346 break;
347
348
349 // Macro element 1: Bottom
350 case 1:
351
352 // Choose a direction
353 switch (idirect)
354 {
355 case L:
356 // Get the position on the wall
357 zeta[0] = zeta_centre[0] +
358 (zeta_centre[1] - zeta_centre[0]) * 0.5 * (s[1] + 1.0);
359 zeta[1] = Theta_positions[0];
360 zeta[2] = 1.0;
361 Volume_pt->position(t, zeta, pos_1);
362
363 // Get the position on the box
364 zeta[2] = Radius_box[0];
365 Volume_pt->position(t, zeta, pos_2);
366
367 // Now linearly interpolate between the two
369 break;
370
371 case R:
372 // Get the position on the wall
373 zeta[0] = zeta_centre[0] +
374 (zeta_centre[1] - zeta_centre[0]) * 0.5 * (s[1] + 1.0);
375 zeta[1] = Theta_positions[1];
376 zeta[2] = 1.0;
377 Volume_pt->position(t, zeta, pos_1);
378
379 // Get the position from the box
380 zeta[2] = Radius_box[1];
381 Volume_pt->position(t, zeta, pos_2);
382
383 // Now linearly interpolate between the two
385 break;
386
387 case D:
388 // This is entrirly on the wall
389 zeta[0] = zeta_centre[0] +
390 (zeta_centre[1] - zeta_centre[0]) * 0.5 * (s[1] + 1.0);
391 zeta[1] =
392 Theta_positions[0] +
393 (Theta_positions[1] - Theta_positions[0]) * 0.5 * (s[0] + 1.0);
394 zeta[2] = 1.0;
395 Volume_pt->position(t, zeta, f);
396 break;
397
398 case U:
399 // Need to get the position from the domain
400 // Get the centreline position
401 zeta[0] = zeta_centre[0] +
402 (zeta_centre[1] - zeta_centre[0]) * 0.5 * (s[1] + 1.0);
403 // Get the left corner
404 zeta[1] = Theta_positions[0];
405 zeta[2] = Radius_box[0];
406 Volume_pt->position(t, zeta, pos_1);
407
408 // Get the right corner
409 zeta[1] = Theta_positions[1];
410 zeta[2] = Radius_box[1];
411 Volume_pt->position(t, zeta, pos_2);
412 // Now interpolate between the positions
414 break;
415
416 case B:
417 // Get the position on the wall
418 zeta[0] = zeta_centre[0];
419 zeta[1] =
420 Theta_positions[0] +
421 (Theta_positions[1] - Theta_positions[0]) * 0.5 * (s[0] + 1.0);
422 zeta[2] = 1.0;
423 Volume_pt->position(t, zeta, pos_1);
424
425 // Now linearly interpolate the position on the box
426 lin_interpolate(Box[0][0], Box[0][1], s[0], pos_2);
427
428 // Now linearly interpolate between the two
430 break;
431
432 case F:
433 // Get the position on the wall
434 zeta[0] = zeta_centre[1];
435 zeta[1] =
436 Theta_positions[0] +
437 (Theta_positions[1] - Theta_positions[0]) * 0.5 * (s[0] + 1.0);
438 zeta[2] = 1.0;
439 Volume_pt->position(t, zeta, pos_1);
440
441 // Now linearly interpolate the position on the box
442 lin_interpolate(Box[1][0], Box[1][1], s[0], pos_2);
443
444 // Now linearly interpolate between the two
446 break;
447
448
449 default:
450
451 std::ostringstream error_stream;
452 error_stream << "idirect is " << idirect
453 << " not one of L, R, D, U, B, F" << std::endl;
454
455 throw OomphLibError(error_stream.str(),
458 break;
459 }
460
461
462 break;
463
464 // Macro element 2:Right
465 case 2:
466
467 // Which direction?
468 switch (idirect)
469 {
470 case L:
471 // Need to get the position from the domain
472 // Get the centreline position
473 zeta[0] = zeta_centre[0] +
474 (zeta_centre[1] - zeta_centre[0]) * 0.5 * (s[1] + 1.0);
475 // Get the lower corner
476 zeta[1] = Theta_positions[1];
477 zeta[2] = Radius_box[1];
478 Volume_pt->position(t, zeta, pos_1);
479
480 // Get the upper corner
481 zeta[1] = Theta_positions[2];
482 zeta[2] = Radius_box[2];
483 Volume_pt->position(t, zeta, pos_2);
484 // Now interpolate between the positions
486 break;
487
488 case R:
489 // Entirely on the wall
490 zeta[0] = zeta_centre[0] +
491 (zeta_centre[1] - zeta_centre[0]) * 0.5 * (s[1] + 1.0);
492 zeta[1] =
493 Theta_positions[1] +
494 (Theta_positions[2] - Theta_positions[1]) * 0.5 * (s[0] + 1.0);
495 zeta[2] = 1.0;
496 Volume_pt->position(t, zeta, f);
497 break;
498
499 case U:
500 // Get the position on the wall
501 zeta[0] = zeta_centre[0] +
502 (zeta_centre[1] - zeta_centre[0]) * 0.5 * (s[1] + 1.0);
503 zeta[1] = Theta_positions[2];
504 zeta[2] = 1.0;
505 Volume_pt->position(t, zeta, pos_1);
506
507 // Get the position of the box
508 zeta[2] = Radius_box[2];
509 Volume_pt->position(t, zeta, pos_2);
510
511 // Now linearly interpolate between the two
513 break;
514
515 case D:
516 // Get the position on the wall
517 zeta[0] = zeta_centre[0] +
518 (zeta_centre[1] - zeta_centre[0]) * 0.5 * (s[1] + 1.0);
519 zeta[1] = Theta_positions[1];
520 zeta[2] = 1.0;
521 Volume_pt->position(t, zeta, pos_1);
522
523 // Get the position of the box
524 zeta[2] = Radius_box[1];
525 Volume_pt->position(t, zeta, pos_2);
526
527 // Now linearly interpolate between the two
529 break;
530
531 case B:
532 // Get the position on the wall
533 zeta[0] = zeta_centre[0];
534 zeta[1] =
535 Theta_positions[1] +
536 (Theta_positions[2] - Theta_positions[1]) * 0.5 * (s[1] + 1.0);
537 zeta[2] = 1.0;
538 Volume_pt->position(t, zeta, pos_1);
539
540 // Now linearly interpolate the position on the box
541 lin_interpolate(Box[0][1], Box[0][2], s[1], pos_2);
542
543 // Now linearly interpolate between the two
545 break;
546
547 case F:
548 // Get the position on the wall
549 zeta[0] = zeta_centre[1];
550 zeta[1] =
551 Theta_positions[1] +
552 (Theta_positions[2] - Theta_positions[1]) * 0.5 * (s[1] + 1.0);
553 zeta[2] = 1.0;
554 Volume_pt->position(t, zeta, pos_1);
555
556 // Now linearly interpolate the position on the box
557 lin_interpolate(Box[1][1], Box[1][2], s[1], pos_2);
558
559 // Now linearly interpolate between the two
561 break;
562
563
564 default:
565 std::ostringstream error_stream;
566 error_stream << "idirect is " << idirect
567 << " not one of L, R, D, U, B, F" << std::endl;
568
569 throw OomphLibError(error_stream.str(),
572 }
573
574 break;
575
576 // Macro element 3: Top
577 case 3:
578
579 // Which direction?
580 switch (idirect)
581 {
582 case L:
583 // Get the position on the wall
584 zeta[0] = zeta_centre[0] +
585 (zeta_centre[1] - zeta_centre[0]) * 0.5 * (s[1] + 1.0);
586 zeta[1] = Theta_positions[3];
587 zeta[2] = 1.0;
588 Volume_pt->position(t, zeta, pos_1);
589
590 // Get the position on the box
591 zeta[2] = Radius_box[3];
592 Volume_pt->position(t, zeta, pos_2);
593
594
595 // Now linearly interpolate between the two
597 break;
598
599 case R:
600 // Get the position on the wall
601 zeta[0] = zeta_centre[0] +
602 (zeta_centre[1] - zeta_centre[0]) * 0.5 * (s[1] + 1.0);
603 zeta[1] = Theta_positions[2];
604 zeta[2] = 1.0;
605 Volume_pt->position(t, zeta, pos_1);
606
607 // Get the position on the box
608 zeta[2] = Radius_box[2];
609 Volume_pt->position(t, zeta, pos_2);
610
611
612 // Now linearly interpolate between the two
614 break;
615
616 case D:
617 // This is entirely on the box
618 // Need to get the position from the domain
619 // Get the centreline position
620 zeta[0] = zeta_centre[0] +
621 (zeta_centre[1] - zeta_centre[0]) * 0.5 * (s[1] + 1.0);
622 zeta[1] = Theta_positions[3];
623 zeta[2] = Radius_box[3];
624 // Get the lower corner
625 Volume_pt->position(t, zeta, pos_2);
626
627 // Get the upper corner
628 zeta[1] = Theta_positions[2];
629 zeta[2] = Radius_box[2];
630 // Get the upper corner
631 Volume_pt->position(t, zeta, pos_1);
632 // Now interpolate between the positions
634 break;
635
636 case U:
637 // This is entirely on the wall
638 zeta[0] = zeta_centre[0] +
639 (zeta_centre[1] - zeta_centre[0]) * 0.5 * (s[1] + 1.0);
640 zeta[1] =
641 Theta_positions[3] +
642 (Theta_positions[2] - Theta_positions[3]) * 0.5 * (s[0] + 1.0);
643 zeta[2] = 1.0;
644 Volume_pt->position(t, zeta, f);
645 break;
646
647 case B:
648 // Get the position on the wall
649 zeta[0] = zeta_centre[0];
650 zeta[1] =
651 Theta_positions[3] +
652 (Theta_positions[2] - Theta_positions[3]) * 0.5 * (s[0] + 1.0);
653 zeta[2] = 1.0;
654 Volume_pt->position(t, zeta, pos_1);
655
656 // Now linearly interpolate the position on the box
657 lin_interpolate(Box[0][3], Box[0][2], s[0], pos_2);
658
659 // Now linearly interpolate between the two
661 break;
662
663 case F:
664 // Get the position on the wall
665 zeta[0] = zeta_centre[1];
666 zeta[1] =
667 Theta_positions[3] +
668 (Theta_positions[2] - Theta_positions[3]) * 0.5 * (s[0] + 1.0);
669 zeta[2] = 1.0;
670 Volume_pt->position(t, zeta, pos_1);
671
672 // Now linearly interpolate the position on the box
673 lin_interpolate(Box[1][3], Box[1][2], s[0], pos_2);
674
675 // Now linearly interpolate between the two
677 break;
678
679
680 default:
681 std::ostringstream error_stream;
682 error_stream << "idirect is " << idirect
683 << " not one of L, R, D, U, B, F" << std::endl;
684
685 throw OomphLibError(error_stream.str(),
688 }
689
690 break;
691
692
693 // Macro element 4: Left
694 case 4:
695
696 // Which direction?
697 switch (idirect)
698 {
699 case L:
700 // Entirely on the wall, Need to be careful
701 // because this is the point at which theta passes through the
702 // branch cut
703 zeta[0] = zeta_centre[0] +
704 (zeta_centre[1] - zeta_centre[0]) * 0.5 * (s[1] + 1.0);
705 zeta[1] = Theta_positions[0] + 2.0 * pi +
706 (Theta_positions[3] - (Theta_positions[0] + 2.0 * pi)) *
707 0.5 * (s[0] + 1.0);
708 zeta[2] = 1.0;
709 Volume_pt->position(t, zeta, f);
710 break;
711
712 case R:
713 // Entirely on the box
714 // Need to get the position from the domain
715 // Get the centreline position
716 zeta[0] = zeta_centre[0] +
717 (zeta_centre[1] - zeta_centre[0]) * 0.5 * (s[1] + 1.0);
718 zeta[1] = Theta_positions[0];
719 zeta[2] = Radius_box[0];
720 // Get the lower corner
721 Volume_pt->position(t, zeta, pos_2);
722
723 // Get the upper corner
724 zeta[1] = Theta_positions[3];
725 zeta[2] = Radius_box[3];
726 // Get the upper corner
727 Volume_pt->position(t, zeta, pos_1);
728
730 break;
731
732 case D:
733 // Get the position on the wall
734 zeta[0] = zeta_centre[0] +
735 (zeta_centre[1] - zeta_centre[0]) * 0.5 * (s[1] + 1.0);
736 zeta[1] = Theta_positions[0];
737 zeta[2] = 1.0;
738 Volume_pt->position(t, zeta, pos_1);
739
740
741 // Get the position on the box
742 zeta[2] = Radius_box[0];
743 Volume_pt->position(t, zeta, pos_2);
744
745
746 // Now linearly interpolate between the two
748 break;
749
750 case U:
751 // Get the position on the wall
752 zeta[0] = zeta_centre[0] +
753 (zeta_centre[1] - zeta_centre[0]) * 0.5 * (s[1] + 1.0);
754 zeta[1] = Theta_positions[3];
755 zeta[2] = 1.0;
756 Volume_pt->position(t, zeta, pos_1);
757
758 // Get the position on the box
759 zeta[2] = Radius_box[3];
760 Volume_pt->position(t, zeta, pos_2);
761
762 // Now linearly interpolate between the two
764 break;
765
766 case B:
767 // Get the position on the wall
768 // Again be careful of the branch cut
769 zeta[0] = zeta_centre[0];
770 zeta[1] = Theta_positions[0] + 2.0 * pi +
771 (Theta_positions[3] - (Theta_positions[0] + 2.0 * pi)) *
772 0.5 * (s[1] + 1.0);
773 zeta[2] = 1.0;
774 Volume_pt->position(t, zeta, pos_1);
775
776 // Now linearly interpolate the position on the box
777 lin_interpolate(Box[0][0], Box[0][3], s[1], pos_2);
778
779 // Now linearly interpolate between the two
781 break;
782
783
784 case F:
785 // Get the position on the wall
786 // Again be careful of the branch cut
787 zeta[0] = zeta_centre[1];
788 zeta[1] = Theta_positions[0] + 2.0 * pi +
789 (Theta_positions[3] - (Theta_positions[0] + 2.0 * pi)) *
790 0.5 * (s[1] + 1.0);
791 zeta[2] = 1.0;
792 Volume_pt->position(t, zeta, pos_1);
793
794 // Now linearly interpolate the position on the box
795 lin_interpolate(Box[1][0], Box[1][3], s[1], pos_2);
796
797 // Now linearly interpolate between the two
799 break;
800
801
802 default:
803 std::ostringstream error_stream;
804 error_stream << "idirect is " << idirect
805 << " not one of L, R, D, U, B, F" << std::endl;
806
807 throw OomphLibError(error_stream.str(),
810 }
811 break;
812
813
814 default:
815 // Error
816 std::ostringstream error_stream;
817 error_stream << "Wrong imacro " << imacro << std::endl;
818 throw OomphLibError(
820 }
821 }
822
823} // namespace oomph
824
825#endif
/////////////////////////////////////////////////////////////////// /////////////////////////////////...
Tube as a domain. The entire domain must be defined by a GeomObject with the following convention: ze...
Definition tube_domain.h:70
TubeDomain(GeomObject *volume_geom_object_pt, const Vector< double > &centreline_limits, const Vector< double > &theta_positions, const Vector< double > &radius_box, const unsigned &nlayer)
Constructor: Pass geometric object; start and end limit of the centreline coordinate; the theta locat...
Definition tube_domain.h:79
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...
TubeDomain(const TubeDomain &)=delete
Broken copy constructor.
Vector< double > Centreline_limits
Storage for the limits of the centreline coordinate.
void operator=(const TubeDomain &)=delete
Broken assignment operator.
void lin_interpolate(const Vector< double > &low, const Vector< double > &high, const double &s, Vector< double > &f)
A very little linear interpolation helper. Interpolate from the low point to the high point using the...
GeomObject * Volume_pt
Pointer to geometric object that represents the domain.
unsigned Nlayer
Number of axial layers.
Vector< double > Theta_positions
Storage for the dividing lines on the boundary starting from the lower left and proceeding anticlockw...
Vector< double > Radius_box
Storage for the fraction of the radius at which the central box should be located corresponding to th...
~TubeDomain()
Destructor: Empty; cleanup done in base class.
////////////////////////////////////////////////////////////////////// //////////////////////////////...