fish_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_FISH_DOMAIN_HEADER
28 #define OOMPH_FISH_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  //===========start_of_fish_domain=======================================
41  //=======================================================================
42  class FishDomain : public Domain
43  {
44  public:
49  const double& xi_nose,
50  const double& xi_tail)
51  : Xi_nose(xi_nose), Xi_tail(xi_tail), Back_pt(back_pt)
52  {
53  // Set values for private data members that are describe
54  // geometric features of the fish: x-coordinate of the fin,
55  // (half-)height of the fin, and x-position of the mouth.
56  X_fin = 1.7;
57  Y_fin = 0.9;
58  X_mouth = 0.0;
59 
60  // There are four macro elements
61  unsigned nmacro = 4;
62  Macro_element_pt.resize(nmacro);
63 
64  // Build them
65  for (unsigned i = 0; i < nmacro; i++)
66  {
67  Macro_element_pt[i] = new QMacroElement<2>(this, i);
68  }
69  } // end of constructor
70 
71 
73  FishDomain(const FishDomain&) = delete;
74 
76  void operator=(const FishDomain&) = delete;
77 
79  virtual ~FishDomain() {}
80 
81 
83  double& x_fin()
84  {
85  return X_fin;
86  }
87 
89  double& y_fin()
90  {
91  return Y_fin;
92  }
93 
95  double& x_mouth()
96  {
97  return X_mouth;
98  }
99 
101  double& xi_nose()
102  {
103  return Xi_nose;
104  }
105 
107  double& xi_tail()
108  {
109  return Xi_tail;
110  }
111 
119  void macro_element_boundary(const unsigned& t,
120  const unsigned& i_macro,
121  const unsigned& i_direct,
122  const Vector<double>& zeta,
123  Vector<double>& r);
124 
125  private:
127  double Xi_nose;
128 
130  double Xi_tail;
131 
133  double X_fin;
134 
136  double Y_fin;
137 
139  double X_mouth;
140 
143 
145  void r_upper_body_N(const unsigned& t,
146  const Vector<double>& zeta,
147  Vector<double>& f);
148 
150  void r_upper_body_W(const unsigned& t,
151  const Vector<double>& zeta,
152  Vector<double>& f);
153 
155  void r_upper_body_S(const unsigned& t,
156  const Vector<double>& zeta,
157  Vector<double>& f);
158 
160  void r_upper_body_E(const unsigned& t,
161  const Vector<double>& zeta,
162  Vector<double>& f);
163 
165  void r_upper_fin_N(const unsigned& t,
166  const Vector<double>& zeta,
167  Vector<double>& f);
168 
170  void r_upper_fin_W(const unsigned& t,
171  const Vector<double>& zeta,
172  Vector<double>& f);
173 
175  void r_upper_fin_S(const unsigned& t,
176  const Vector<double>& zeta,
177  Vector<double>& f);
178 
180  void r_upper_fin_E(const unsigned& t,
181  const Vector<double>& zeta,
182  Vector<double>& f);
183 
184 
186  void r_lower_body_N(const unsigned& t,
187  const Vector<double>& zeta,
188  Vector<double>& f)
189  {
190  // North of lower body is element is south of upper one.
191  // Direction of the coordinate stays the same.
192  r_upper_body_S(t, zeta, f);
193  // Reflect vertical position
194  f[1] = -f[1];
195  }
196 
197 
199  void r_lower_body_W(const unsigned& t,
200  const Vector<double>& zeta,
201  Vector<double>& f)
202  {
203  // West of lower body is element is west of upper one.
204  // Direction of the coordinate is inverted
205  Vector<double> zeta_new(1);
206  zeta_new[0] = -zeta[0];
207  r_upper_body_W(t, zeta_new, f);
208  // Vertical coordinate is reflected
209  f[1] = -f[1];
210  }
211 
213  void r_lower_body_S(const unsigned& t,
214  const Vector<double>& zeta,
215  Vector<double>& f)
216  {
217  // South of lower body is element is north of upper one.
218  // Direction of the coordinate stays the same.
219  r_upper_body_N(t, zeta, f);
220  // Reflect vertical position
221  f[1] = -f[1];
222  }
223 
225  void r_lower_body_E(const unsigned& t,
226  const Vector<double>& zeta,
227  Vector<double>& f)
228  {
229  // East of lower body is element is east of upper one.
230  // Direction of the coordinate is inverted.
231  Vector<double> zeta_new(1);
232  zeta_new[0] = -zeta[0];
233  r_upper_body_E(t, zeta_new, f);
234  // Vertical coordinate is reflected
235  f[1] = -f[1];
236  }
237 
238 
240  void r_lower_fin_N(const unsigned& t,
241  const Vector<double>& zeta,
242  Vector<double>& f)
243  {
244  // North of lower fin is element is south of upper one.
245  // Direction of the coordinate stays the same.
246  r_upper_fin_S(t, zeta, f);
247  // Reflect vertical position
248  f[1] = -f[1];
249  }
250 
251 
253  void r_lower_fin_W(const unsigned& t,
254  const Vector<double>& zeta,
255  Vector<double>& f)
256  {
257  // West of lower fin is element is west of upper one.
258  // Direction of the coordinate is inverted
259  Vector<double> zeta_new(1);
260  zeta_new[0] = -zeta[0];
261  r_upper_fin_W(t, zeta_new, f);
262  // Vertical coordinate is reflected
263  f[1] = -f[1];
264  }
265 
267  void r_lower_fin_S(const unsigned& t,
268  const Vector<double>& zeta,
269  Vector<double>& f)
270  {
271  // South of lower fin is element is north of upper one.
272  // Direction of the coordinate stays the same.
273  r_upper_fin_N(t, zeta, f);
274  // Reflect vertical position
275  f[1] = -f[1];
276  }
277 
279  void r_lower_fin_E(const unsigned& t,
280  const Vector<double>& zeta,
281  Vector<double>& f)
282  {
283  // East of lower fin is element is east of upper one.
284  // Direction of the coordinate is inverted.
285  Vector<double> zeta_new(1);
286  zeta_new[0] = -zeta[0];
287  r_upper_fin_E(t, zeta_new, f);
288  // Vertical coordinate is reflected
289  f[1] = -f[1];
290  }
291  };
292 
293 
297 
298 
299  //==========start_of_macro_element_boundary========================
307  //=================================================================
308  void FishDomain::macro_element_boundary(const unsigned& t,
309  const unsigned& imacro,
310  const unsigned& idirect,
311  const Vector<double>& zeta,
312  Vector<double>& r)
313  {
314  using namespace QuadTreeNames;
315 
316 
317 #ifdef WARN_ABOUT_SUBTLY_CHANGED_OOMPH_INTERFACES
318  // Warn about time argument being moved to the front
320  "Order of function arguments has changed between versions 0.8 and 0.85",
321  "FishDomain::macro_element_boundary(...)",
323 #endif
324 
325 
326  // Which macro element?
327  // --------------------
328  switch (imacro)
329  {
330  // Macro element 0: Lower body
331  case 0:
332 
333  // Which direction?
334  if (idirect == N)
335  {
337  }
338  else if (idirect == S)
339  {
341  }
342  else if (idirect == W)
343  {
345  }
346  else if (idirect == E)
347  {
349  }
350  else
351  {
352  std::ostringstream error_stream;
353  error_stream << "idirect is " << idirect << " not one of N, S, E, W"
354  << std::endl;
355 
356  throw OomphLibError(error_stream.str(),
359  }
360 
361  break;
362 
363  // Macro element 1: Lower Fin
364  case 1:
365 
366  // Which direction?
367  if (idirect == N)
368  {
370  }
371  else if (idirect == S)
372  {
374  }
375  else if (idirect == W)
376  {
378  }
379  else if (idirect == E)
380  {
382  }
383  else
384  {
385  std::ostringstream error_stream;
386  error_stream << "idirect is " << idirect << " not one of N, S, E, W"
387  << std::endl;
388 
389  throw OomphLibError(error_stream.str(),
392  }
393 
394  break;
395 
396 
397  // Macro element 2: Upper body
398  case 2:
399 
400  // Which direction?
401  if (idirect == N)
402  {
404  }
405  else if (idirect == S)
406  {
408  }
409  else if (idirect == W)
410  {
412  }
413  else if (idirect == E)
414  {
416  }
417  else
418  {
419  std::ostringstream error_stream;
420  error_stream << "idirect is " << idirect << " not one of N, S, E, W"
421  << std::endl;
422 
423  throw OomphLibError(error_stream.str(),
426  }
427 
428  break;
429 
430 
431  // Macro element 3: Upper Fin
432  case 3:
433 
434  // Which direction?
435  if (idirect == N)
436  {
438  }
439  else if (idirect == S)
440  {
442  }
443  else if (idirect == W)
444  {
446  }
447  else if (idirect == E)
448  {
450  }
451  else
452  {
453  std::ostringstream error_stream;
454  error_stream << "idirect is " << idirect << " not one of N, S, E, W"
455  << std::endl;
456 
457  throw OomphLibError(error_stream.str(),
460  }
461 
462  break;
463 
464  default:
465 
466  // Error
467  std::ostringstream error_stream;
468  error_stream << "Wrong imacro " << imacro << std::endl;
469 
470  throw OomphLibError(
471  error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
472  }
473 
474  } // end of macro_element_boundary
475 
476 
477  //=================================================================
479  //=================================================================
480  void FishDomain::r_upper_fin_N(const unsigned& t,
481  const Vector<double>& zeta,
482  Vector<double>& r)
483  {
484  // Right end of fish back
485  Vector<double> x(1);
486  x[0] = Xi_tail;
487  Vector<double> r_fish(2);
488  Back_pt->position(t, x, r_fish);
489 
490  // Top end of fin
491  Vector<double> r_fin(2);
492  r_fin[0] = X_fin;
493  r_fin[1] = Y_fin;
494 
495 
496  // Straight line along upper fin
497  r[0] = r_fish[0] + (r_fin[0] - r_fish[0]) * 0.5 * (zeta[0] + 1.0);
498  r[1] = r_fish[1] + (r_fin[1] - r_fish[1]) * 0.5 * (zeta[0] + 1.0);
499  }
500 
501 
502  //=================================================================
504  //=================================================================
505  void FishDomain::r_upper_fin_W(const unsigned& t,
506  const Vector<double>& zeta,
507  Vector<double>& r)
508  {
509  // Right end of fish back
510  Vector<double> x(1);
511  x[0] = Xi_tail;
512  Vector<double> r_fish(2);
513  Back_pt->position(t, x, r_fish);
514 
515  r[0] = r_fish[0];
516  r[1] = r_fish[1] * 0.5 * (zeta[0] + 1.0);
517  }
518 
519 
520  //=================================================================
522  //=================================================================
523  void FishDomain::r_upper_fin_S(const unsigned& t,
524  const Vector<double>& zeta,
525  Vector<double>& r)
526  {
527  // Right end of fish back
528  Vector<double> x(1);
529  x[0] = Xi_tail;
530  Vector<double> r_fish(2);
531  Back_pt->position(t, x, r_fish);
532 
533 
534  r[0] = r_fish[0] * 0.5 * (zeta[0] + 1.0);
535  r[1] = 0.0;
536  }
537 
538 
539  //=================================================================
541  //=================================================================
542  void FishDomain::r_upper_fin_E(const unsigned& t,
543  const Vector<double>& zeta,
544  Vector<double>& r)
545  {
546  // Straight vertical line from top of fin
547  r[0] = X_fin;
548  r[1] = Y_fin * 0.5 * (zeta[0] + 1.0);
549  }
550 
551 
552  //===============start_of_r_upper_body_N==============================
554  //=====================================================================
555  void FishDomain::r_upper_body_N(const unsigned& t,
556  const Vector<double>& zeta,
557  Vector<double>& r)
558  {
559  // Lagrangian coordinate along curved "back"
560  Vector<double> x(1);
561  x[0] = Xi_nose + (Xi_tail - Xi_nose) * 0.5 * (zeta[0] + 1.0);
562 
563  // Get position on curved back
564  Back_pt->position(t, x, r);
565 
566  } // end of r_upper_body_N
567 
568 
569  //================start_of_r_upper_body_E=============================
571  //=====================================================================
572  void FishDomain::r_upper_body_E(const unsigned& t,
573  const Vector<double>& zeta,
574  Vector<double>& r)
575  {
576  // Top right corner (tail end) of body
577  Vector<double> r_top(2);
578  Vector<double> x(1);
579  x[0] = Xi_tail;
580  Back_pt->position(t, x, r_top);
581 
582  // Corresponding point on the x-axis
583  Vector<double> r_back(2);
584  r_back[0] = r_top[0];
585  r_back[1] = 0.0;
586 
587  r[0] = r_back[0] + (r_top[0] - r_back[0]) * 0.5 * (zeta[0] + 1.0);
588  r[1] = r_back[1] + (r_top[1] - r_back[1]) * 0.5 * (zeta[0] + 1.0);
589 
590 
591  } // end of r_upper_body_E
592 
593 
594  //==================start_of_r_upper_body_S============================
596  //=====================================================================
597  void FishDomain::r_upper_body_S(const unsigned& t,
598  const Vector<double>& zeta,
599  Vector<double>& r)
600  {
601  // Top right (tail) corner of fish body
602  Vector<double> r_top(2);
603  Vector<double> x(1);
604  x[0] = Xi_tail;
605  Back_pt->position(t, x, r_top);
606 
607  // Straight line from mouth to start of fin (=end of body)
608  r[0] = X_mouth + (r_top[0] - X_mouth) * 0.5 * (zeta[0] + 1.0);
609  r[1] = 0.0;
610 
611  } // end of r_upper_body_S
612 
613 
614  //===============start_of_r_upper_body_W==============================
616  //====================================================================
617  void FishDomain::r_upper_body_W(const unsigned& t,
618  const Vector<double>& zeta,
619  Vector<double>& r)
620  {
621  // Top left (mouth) corner of curved boundary of upper body
622  Vector<double> r_top(2);
623  Vector<double> x(1);
624  x[0] = Xi_nose;
625  Back_pt->position(t, x, r_top);
626 
627  // The "mouth"
628  Vector<double> r_mouth(2);
629  r_mouth[0] = X_mouth;
630  r_mouth[1] = 0.0;
631 
632  // Straight line from mouth to leftmost corner on curved boundary
633  // of upper body
634  r[0] = r_mouth[0] + (r_top[0] - r_mouth[0]) * 0.5 * (zeta[0] + 1.0);
635  r[1] = r_mouth[1] + (r_top[1] - r_mouth[1]) * 0.5 * (zeta[0] + 1.0);
636 
637  } // end of r_upper_body_W
638 
639 
640 } // namespace oomph
641 
642 #endif
int i
Definition: BiCGSTAB_step_by_step.cpp:9
Definition: domain.h:67
Vector< MacroElement * > Macro_element_pt
Vector of pointers to macro elements.
Definition: domain.h:301
Definition: fish_domain.h:43
void r_upper_fin_E(const unsigned &t, const Vector< double > &zeta, Vector< double > &f)
Boundary of upper fin macro element zeta .
Definition: fish_domain.h:542
double Y_fin
Y coordinate of fin tip.
Definition: fish_domain.h:136
void r_lower_fin_S(const unsigned &t, const Vector< double > &zeta, Vector< double > &f)
Boundary of lower fin macro element zeta .
Definition: fish_domain.h:267
void macro_element_boundary(const unsigned &t, const unsigned &i_macro, const unsigned &i_direct, const Vector< double > &zeta, Vector< double > &r)
Definition: fish_domain.h:308
double Xi_tail
"Tail" limit for the (1D) coordinates along the wall
Definition: fish_domain.h:130
void operator=(const FishDomain &)=delete
Broken assignment operator.
void r_lower_body_W(const unsigned &t, const Vector< double > &zeta, Vector< double > &f)
Boundary of lower body macro element zeta .
Definition: fish_domain.h:199
void r_upper_body_N(const unsigned &t, const Vector< double > &zeta, Vector< double > &f)
Boundary of upper body macro element zeta .
Definition: fish_domain.h:555
void r_upper_body_E(const unsigned &t, const Vector< double > &zeta, Vector< double > &f)
Boundary of upper body macro element zeta .
Definition: fish_domain.h:572
void r_upper_fin_N(const unsigned &t, const Vector< double > &zeta, Vector< double > &f)
Boundary of upper fin macro element zeta .
Definition: fish_domain.h:480
void r_lower_fin_N(const unsigned &t, const Vector< double > &zeta, Vector< double > &f)
Boundary of lower fin macro element zeta .
Definition: fish_domain.h:240
void r_upper_fin_W(const unsigned &t, const Vector< double > &zeta, Vector< double > &f)
Boundary of upper fin macro element zeta .
Definition: fish_domain.h:505
void r_lower_body_N(const unsigned &t, const Vector< double > &zeta, Vector< double > &f)
Boundary of lower body macro element zeta .
Definition: fish_domain.h:186
double & xi_nose()
Start coordinate on wall (near nose)
Definition: fish_domain.h:101
FishDomain(const FishDomain &)=delete
Broken copy constructor.
void r_lower_fin_E(const unsigned &t, const Vector< double > &zeta, Vector< double > &f)
Boundary of lower fin macro element zeta .
Definition: fish_domain.h:279
FishDomain(GeomObject *back_pt, const double &xi_nose, const double &xi_tail)
Definition: fish_domain.h:48
double X_mouth
X coordinate of corner of mouth.
Definition: fish_domain.h:139
void r_lower_body_S(const unsigned &t, const Vector< double > &zeta, Vector< double > &f)
Southern boundary of lower body macro element zeta .
Definition: fish_domain.h:213
void r_lower_fin_W(const unsigned &t, const Vector< double > &zeta, Vector< double > &f)
Boundary of lower fin macro element zeta .
Definition: fish_domain.h:253
virtual ~FishDomain()
Destructor for FishDomain: Empty; cleanup done in base class.
Definition: fish_domain.h:79
void r_lower_body_E(const unsigned &t, const Vector< double > &zeta, Vector< double > &f)
Boundary of lower body macro element zeta .
Definition: fish_domain.h:225
void r_upper_body_W(const unsigned &t, const Vector< double > &zeta, Vector< double > &f)
Boundary of upper body macro element zeta .
Definition: fish_domain.h:617
void r_upper_fin_S(const unsigned &t, const Vector< double > &zeta, Vector< double > &f)
Boundary of upper fin macro element zeta .
Definition: fish_domain.h:523
double & x_mouth()
x-position of mouth
Definition: fish_domain.h:95
double & y_fin()
y-position of fin tip
Definition: fish_domain.h:89
double & xi_tail()
End coordinate on wall (near tail)
Definition: fish_domain.h:107
double & x_fin()
x-position of fin tip
Definition: fish_domain.h:83
GeomObject * Back_pt
Pointer to the fish's back.
Definition: fish_domain.h:142
double X_fin
X coordinate of fin tip.
Definition: fish_domain.h:133
void r_upper_body_S(const unsigned &t, const Vector< double > &zeta, Vector< double > &f)
Boundary of upper body macro element zeta .
Definition: fish_domain.h:597
double Xi_nose
"Nose" limit for the (1D) coordinates along the wall
Definition: fish_domain.h:127
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:279
@ N
Definition: constructor.cpp:22
static int f(const TensorMap< Tensor< int, 3 > > &tensor)
Definition: cxx11_tensor_map.cpp:237
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 E
Elastic modulus.
Definition: TwenteMeshGluing.cpp:68
r
Definition: UniformPSDSelfTest.py:20
@ S
Definition: quadtree.h:62
@ W
Definition: quadtree.h:63
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).
Definition: AnisotropicHookean.h:10
list x
Definition: plotDoE.py:28
t
Definition: plotPSD.py:36
#define OOMPH_EXCEPTION_LOCATION
Definition: oomph_definitions.h:61
#define OOMPH_CURRENT_FUNCTION
Definition: oomph_definitions.h:86