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-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 // 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 
35 namespace oomph
36 {
37  //=================================================================
68  //=================================================================
69  class TubeDomain : public Domain
70  {
71  public:
79  TubeDomain(GeomObject* volume_geom_object_pt,
80  const Vector<double>& centreline_limits,
81  const Vector<double>& theta_positions,
82  const Vector<double>& radius_box,
83  const unsigned& nlayer)
84  : Centreline_limits(centreline_limits),
85  Theta_positions(theta_positions),
86  Radius_box(radius_box),
87  Nlayer(nlayer),
88  Volume_pt(volume_geom_object_pt)
89  {
90  // There are five macro elements
91  const unsigned n_macro = 5 * nlayer;
92  Macro_element_pt.resize(n_macro);
93 
94  // Create the macro elements
95  for (unsigned i = 0; i < n_macro; i++)
96  {
97  Macro_element_pt[i] = new QMacroElement<3>(this, i);
98  }
99  }
100 
102  TubeDomain(const TubeDomain&) = delete;
103 
105  void operator=(const TubeDomain&) = delete;
106 
109 
114  void macro_element_boundary(const unsigned& t,
115  const unsigned& i_macro,
116  const unsigned& i_direct,
117  const Vector<double>& s,
118  Vector<double>& f);
119 
120  private:
123 
128 
132 
134  unsigned Nlayer;
135 
138 
144  const Vector<double>& high,
145  const double& s,
146  Vector<double>& f)
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 
160 
161 
162  //=================================================================
166  //=================================================================
167  void TubeDomain::macro_element_boundary(const unsigned& t,
168  const unsigned& imacro,
169  const unsigned& idirect,
170  const Vector<double>& s,
171  Vector<double>& f)
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
191  Vector<double> zeta_centre(2);
192  // Storage for position in the volume
193  Vector<double> zeta(3);
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
226  Vector<double> pos_1(3), pos_2(3);
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
256  lin_interpolate(pos_1, pos_2, s[0], f);
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
275  lin_interpolate(pos_1, pos_2, s[0], f);
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
293  lin_interpolate(pos_1, pos_2, s[0], f);
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
312  lin_interpolate(pos_1, pos_2, s[0], f);
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
322  lin_interpolate(pos_1, pos_2, s[1], f);
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
332  lin_interpolate(pos_1, pos_2, s[1], f);
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
368  lin_interpolate(pos_1, pos_2, s[0], f);
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
384  lin_interpolate(pos_1, pos_2, s[0], f);
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
413  lin_interpolate(pos_1, pos_2, s[0], f);
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
429  lin_interpolate(pos_1, pos_2, s[1], f);
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
445  lin_interpolate(pos_1, pos_2, s[1], f);
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
485  lin_interpolate(pos_1, pos_2, s[0], f);
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
512  lin_interpolate(pos_2, pos_1, s[0], f);
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
528  lin_interpolate(pos_2, pos_1, s[0], f);
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
544  lin_interpolate(pos_2, pos_1, s[0], f);
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
560  lin_interpolate(pos_2, pos_1, s[0], f);
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
596  lin_interpolate(pos_2, pos_1, s[0], f);
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
613  lin_interpolate(pos_2, pos_1, s[0], f);
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
633  lin_interpolate(pos_2, pos_1, s[0], f);
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
660  lin_interpolate(pos_2, pos_1, s[1], f);
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
676  lin_interpolate(pos_2, pos_1, s[1], f);
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 
729  lin_interpolate(pos_2, pos_1, s[0], f);
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
747  lin_interpolate(pos_1, pos_2, s[0], f);
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
763  lin_interpolate(pos_1, pos_2, s[0], f);
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
780  lin_interpolate(pos_1, pos_2, s[0], f);
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
798  lin_interpolate(pos_1, pos_2, s[0], f);
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(
819  error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
820  }
821  }
822 
823 } // namespace oomph
824 
825 #endif
int i
Definition: BiCGSTAB_step_by_step.cpp:9
dominoes D
Definition: Domino.cpp:55
MatrixXd L
Definition: LLT_example.cpp:6
@ R
Definition: StatisticsVector.h:21
Matrix< SCALARB, Dynamic, Dynamic, opt_B > B
Definition: bench_gemm.cpp:48
Definition: Box.h:12
Definition: domain.h:67
Vector< MacroElement * > Macro_element_pt
Vector of pointers to macro elements.
Definition: domain.h:301
Definition: geom_objects.h:101
virtual void position(const Vector< double > &zeta, Vector< double > &r) const =0
Parametrised position on object at current time: r(zeta).
Definition: oomph_definitions.h:222
Definition: oomph_definitions.h:267
Definition: macro_element.h:373
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)
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)
Definition: tube_domain.h:167
TubeDomain(const TubeDomain &)=delete
Broken copy constructor.
Vector< double > Centreline_limits
Storage for the limits of the centreline coordinate.
Definition: tube_domain.h:122
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)
Definition: tube_domain.h:143
GeomObject * Volume_pt
Pointer to geometric object that represents the domain.
Definition: tube_domain.h:137
unsigned Nlayer
Number of axial layers.
Definition: tube_domain.h:134
Vector< double > Theta_positions
Definition: tube_domain.h:127
Vector< double > Radius_box
Definition: tube_domain.h:131
~TubeDomain()
Destructor: Empty; cleanup done in base class.
Definition: tube_domain.h:108
static int f(const TensorMap< Tensor< int, 3 > > &tensor)
Definition: cxx11_tensor_map.cpp:237
RealScalar s
Definition: level1_cplx_impl.h:130
EIGEN_STRONG_INLINE const Eigen::CwiseBinaryOp< Eigen::internal::scalar_zeta_op< typename DerivedX::Scalar >, const DerivedX, const DerivedQ > zeta(const Eigen::ArrayBase< DerivedX > &x, const Eigen::ArrayBase< DerivedQ > &q)
Definition: SpecialFunctionsArrayAPI.h:152
double U
Swimming speed.
Definition: two_d_variable_diff_adapt.cc:53
const Mdouble pi
Definition: ExtendedMath.h:23
const double Pi
50 digits from maple
Definition: oomph_utilities.h:157
@ F
Definition: octree.h:74
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).
Definition: AnisotropicHookean.h:10
t
Definition: plotPSD.py:36
#define OOMPH_EXCEPTION_LOCATION
Definition: oomph_definitions.h:61
#define OOMPH_CURRENT_FUNCTION
Definition: oomph_definitions.h:86
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2