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-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_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"
34
35namespace oomph
36{
37 //===========start_of_fish_domain=======================================
38 /// Fish shaped domain, represented by four
39 /// MacroElements. Shape is parametrised by GeomObject
40 /// that represents the fish's back.
41 //=======================================================================
42 class FishDomain : public Domain
43 {
44 public:
45 /// Constructor: Pass pointer to GeomObject that represents the
46 /// (upper) curved boundary of the fish's body, and the start and end values
47 /// of the Lagrangian coordinates along the GeomObject.
49 const double& xi_nose,
50 const double& xi_tail)
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;
63
64 // Build them
65 for (unsigned i = 0; i < nmacro; i++)
66 {
68 }
69 } // end of constructor
70
71 /// Broken copy constructor
72 FishDomain(const FishDomain&) = delete;
73
74 /// Broken assignment operator
75 void operator=(const FishDomain&) = delete;
76
77 /// Destructor for FishDomain: Empty; cleanup done in base class
78 virtual ~FishDomain() {}
79
80 /// x-position of fin tip
81 double& x_fin()
82 {
83 return X_fin;
84 }
85
86 /// y-position of fin tip
87 double& y_fin()
88 {
89 return Y_fin;
90 }
91
92 /// x-position of mouth
93 double& x_mouth()
94 {
95 return X_mouth;
96 }
97
98 /// Start coordinate on wall (near nose)
99 double& xi_nose()
100 {
101 return Xi_nose;
102 }
103
104 /// End coordinate on wall (near tail)
105 double& xi_tail()
106 {
107 return Xi_tail;
108 }
109
110 /// Vector representation of the i_macro-th macro element
111 /// boundary i_direct (N/S/W/E) at the discrete time level t
112 /// (t=0: present; t>0: previous): \f$ {\bf r}({\bf zeta}) \f$
113 /// Note that the local coordinate \b zeta is a 1D
114 /// Vector rather than a scalar -- this is unavoidable because
115 /// this function implements the pure virtual function in the
116 /// Domain base class.
117 void macro_element_boundary(const unsigned& t,
118 const unsigned& i_macro,
119 const unsigned& i_direct,
120 const Vector<double>& zeta,
122
123 private:
124 /// "Nose" limit for the (1D) coordinates along the wall
125 double Xi_nose;
126
127 /// "Tail" limit for the (1D) coordinates along the wall
128 double Xi_tail;
129
130 /// X coordinate of fin tip
131 double X_fin;
132
133 /// Y coordinate of fin tip
134 double Y_fin;
135
136 /// X coordinate of corner of mouth
137 double X_mouth;
138
139 /// Pointer to the fish's back
141
142 /// Boundary of upper body macro element zeta \f$ \in [-1,1] \f$
143 void r_upper_body_N(const unsigned& t,
144 const Vector<double>& zeta,
145 Vector<double>& f);
146
147 /// Boundary of upper body macro element zeta \f$ \in [-1,1] \f$
148 void r_upper_body_W(const unsigned& t,
149 const Vector<double>& zeta,
150 Vector<double>& f);
151
152 /// Boundary of upper body macro element zeta \f$ \in [-1,1] \f$
153 void r_upper_body_S(const unsigned& t,
154 const Vector<double>& zeta,
155 Vector<double>& f);
156
157 /// Boundary of upper body macro element zeta \f$ \in [-1,1] \f$
158 void r_upper_body_E(const unsigned& t,
159 const Vector<double>& zeta,
160 Vector<double>& f);
161
162 /// Boundary of upper fin macro element zeta \f$ \in [-1,1] \f$
163 void r_upper_fin_N(const unsigned& t,
164 const Vector<double>& zeta,
165 Vector<double>& f);
166
167 /// Boundary of upper fin macro element zeta \f$ \in [-1,1] \f$
168 void r_upper_fin_W(const unsigned& t,
169 const Vector<double>& zeta,
170 Vector<double>& f);
171
172 /// Boundary of upper fin macro element zeta \f$ \in [-1,1] \f$
173 void r_upper_fin_S(const unsigned& t,
174 const Vector<double>& zeta,
175 Vector<double>& f);
176
177 /// Boundary of upper fin macro element zeta \f$ \in [-1,1] \f$
178 void r_upper_fin_E(const unsigned& t,
179 const Vector<double>& zeta,
180 Vector<double>& f);
181
182
183 /// Boundary of lower body macro element zeta \f$ \in [-1,1] \f$
184 void r_lower_body_N(const unsigned& t,
185 const Vector<double>& zeta,
187 {
188 // North of lower body is element is south of upper one.
189 // Direction of the coordinate stays the same.
190 r_upper_body_S(t, zeta, f);
191 // Reflect vertical position
192 f[1] = -f[1];
193 }
194
195
196 /// Boundary of lower body macro element zeta \f$ \in [-1,1] \f$
197 void r_lower_body_W(const unsigned& t,
198 const Vector<double>& zeta,
200 {
201 // West of lower body is element is west of upper one.
202 // Direction of the coordinate is inverted
204 zeta_new[0] = -zeta[0];
206 // Vertical coordinate is reflected
207 f[1] = -f[1];
208 }
209
210 /// Southern boundary of lower body macro element zeta \f$\in [-1,1] \f$
211 void r_lower_body_S(const unsigned& t,
212 const Vector<double>& zeta,
214 {
215 // South of lower body is element is north of upper one.
216 // Direction of the coordinate stays the same.
217 r_upper_body_N(t, zeta, f);
218 // Reflect vertical position
219 f[1] = -f[1];
220 }
221
222 /// Boundary of lower body macro element zeta \f$ \in [-1,1] \f$
223 void r_lower_body_E(const unsigned& t,
224 const Vector<double>& zeta,
226 {
227 // East of lower body is element is east of upper one.
228 // Direction of the coordinate is inverted.
230 zeta_new[0] = -zeta[0];
232 // Vertical coordinate is reflected
233 f[1] = -f[1];
234 }
235
236
237 /// Boundary of lower fin macro element zeta \f$ \in [-1,1] \f$
238 void r_lower_fin_N(const unsigned& t,
239 const Vector<double>& zeta,
241 {
242 // North of lower fin is element is south of upper one.
243 // Direction of the coordinate stays the same.
244 r_upper_fin_S(t, zeta, f);
245 // Reflect vertical position
246 f[1] = -f[1];
247 }
248
249
250 /// Boundary of lower fin macro element zeta \f$ \in [-1,1] \f$
251 void r_lower_fin_W(const unsigned& t,
252 const Vector<double>& zeta,
254 {
255 // West of lower fin is element is west of upper one.
256 // Direction of the coordinate is inverted
258 zeta_new[0] = -zeta[0];
260 // Vertical coordinate is reflected
261 f[1] = -f[1];
262 }
263
264 /// Boundary of lower fin macro element zeta \f$ \in [-1,1] \f$
265 void r_lower_fin_S(const unsigned& t,
266 const Vector<double>& zeta,
268 {
269 // South of lower fin is element is north of upper one.
270 // Direction of the coordinate stays the same.
271 r_upper_fin_N(t, zeta, f);
272 // Reflect vertical position
273 f[1] = -f[1];
274 }
275
276 /// Boundary of lower fin macro element zeta \f$ \in [-1,1] \f$
277 void r_lower_fin_E(const unsigned& t,
278 const Vector<double>& zeta,
280 {
281 // East of lower fin is element is east of upper one.
282 // Direction of the coordinate is inverted.
284 zeta_new[0] = -zeta[0];
286 // Vertical coordinate is reflected
287 f[1] = -f[1];
288 }
289 };
290
291
292 /////////////////////////////////////////////////////////////////////////
293 /////////////////////////////////////////////////////////////////////////
294 /////////////////////////////////////////////////////////////////////////
295
296 //==========start_of_macro_element_boundary========================
297 /// Vector representation of the imacro-th macro element
298 /// boundary idirect (N/S/W/E) at time level t
299 /// (t=0: present; t>0: previous): \f$ {\bf r}({\bf zeta}) \f$
300 /// Note that the local coordinate \b zeta is a 1D
301 /// Vector rather than a scalar -- this is unavoidable because
302 /// this function implements the pure virtual function in the
303 /// Domain base class.
304 //=================================================================
306 const unsigned& imacro,
307 const unsigned& idirect,
308 const Vector<double>& zeta,
310 {
311 using namespace QuadTreeNames;
312
313#ifdef WARN_ABOUT_SUBTLY_CHANGED_OOMPH_INTERFACES
314 // Warn about time argument being moved to the front
316 "Order of function arguments has changed between versions 0.8 and 0.85",
317 "FishDomain::macro_element_boundary(...)",
319#endif
320
321 // Which macro element?
322 // --------------------
323 switch (imacro)
324 {
325 // Macro element 0: Lower body
326 case 0:
327
328 // Which direction?
329 if (idirect == N)
330 {
332 }
333 else if (idirect == S)
334 {
336 }
337 else if (idirect == W)
338 {
340 }
341 else if (idirect == E)
342 {
344 }
345 else
346 {
347 std::ostringstream error_stream;
348 error_stream << "idirect is " << idirect << " not one of N, S, E, W"
349 << std::endl;
350
351 throw OomphLibError(error_stream.str(),
354 }
355
356 break;
357
358 // Macro element 1: Lower Fin
359 case 1:
360
361 // Which direction?
362 if (idirect == N)
363 {
365 }
366 else if (idirect == S)
367 {
369 }
370 else if (idirect == W)
371 {
373 }
374 else if (idirect == E)
375 {
377 }
378 else
379 {
380 std::ostringstream error_stream;
381 error_stream << "idirect is " << idirect << " not one of N, S, E, W"
382 << std::endl;
383
384 throw OomphLibError(error_stream.str(),
387 }
388
389 break;
390
391 // Macro element 2: Upper body
392 case 2:
393
394 // Which direction?
395 if (idirect == N)
396 {
398 }
399 else if (idirect == S)
400 {
402 }
403 else if (idirect == W)
404 {
406 }
407 else if (idirect == E)
408 {
410 }
411 else
412 {
413 std::ostringstream error_stream;
414 error_stream << "idirect is " << idirect << " not one of N, S, E, W"
415 << std::endl;
416
417 throw OomphLibError(error_stream.str(),
420 }
421
422 break;
423
424 // Macro element 3: Upper Fin
425 case 3:
426
427 // Which direction?
428 if (idirect == N)
429 {
431 }
432 else if (idirect == S)
433 {
435 }
436 else if (idirect == W)
437 {
439 }
440 else if (idirect == E)
441 {
443 }
444 else
445 {
446 std::ostringstream error_stream;
447 error_stream << "idirect is " << idirect << " not one of N, S, E, W"
448 << std::endl;
449
450 throw OomphLibError(error_stream.str(),
453 }
454
455 break;
456
457 default:
458
459 // Error
460 std::ostringstream error_stream;
461 error_stream << "Wrong imacro " << imacro << std::endl;
462
463 throw OomphLibError(
465 }
466
467 } // end of macro_element_boundary
468
469 //=================================================================
470 /// Northern edge of upper fin macro element; \f$ \zeta \in [-1,1] \f$
471 //=================================================================
472 void FishDomain::r_upper_fin_N(const unsigned& t,
473 const Vector<double>& zeta,
475 {
476 // Right end of fish back
477 Vector<double> x(1);
478 x[0] = Xi_tail;
480 Back_pt->position(t, x, r_fish);
481
482 // Top end of fin
484 r_fin[0] = X_fin;
485 r_fin[1] = Y_fin;
486
487 // Straight line along upper fin
488 r[0] = r_fish[0] + (r_fin[0] - r_fish[0]) * 0.5 * (zeta[0] + 1.0);
489 r[1] = r_fish[1] + (r_fin[1] - r_fish[1]) * 0.5 * (zeta[0] + 1.0);
490 }
491
492 //=================================================================
493 /// Western edge of upper fin macro element; \f$ \zeta \in [-1,1] \f$
494 //=================================================================
495 void FishDomain::r_upper_fin_W(const unsigned& t,
496 const Vector<double>& zeta,
498 {
499 // Right end of fish back
500 Vector<double> x(1);
501 x[0] = Xi_tail;
503 Back_pt->position(t, x, r_fish);
504
505 r[0] = r_fish[0];
506 r[1] = r_fish[1] * 0.5 * (zeta[0] + 1.0);
507 }
508
509 //=================================================================
510 /// Southern edge of upper fin macro element; \f$ \zeta \in [-1,1] \f$
511 //=================================================================
512 void FishDomain::r_upper_fin_S(const unsigned& t,
513 const Vector<double>& zeta,
515 {
516 // Right end of fish back
517 Vector<double> x(1);
518 x[0] = Xi_tail;
520 Back_pt->position(t, x, r_fish);
521
522 r[0] = r_fish[0] * 0.5 * (zeta[0] + 1.0);
523 r[1] = 0.0;
524 }
525
526 //=================================================================
527 /// Eastern edge of upper fin macro element; \f$ \zeta \in [-1,1] \f$
528 //=================================================================
529 void FishDomain::r_upper_fin_E(const unsigned& t,
530 const Vector<double>& zeta,
532 {
533 // Straight vertical line from top of fin
534 r[0] = X_fin;
535 r[1] = Y_fin * 0.5 * (zeta[0] + 1.0);
536 }
537
538 //===============start_of_r_upper_body_N==============================
539 /// Northern edge of upper body macro element; \f$ \zeta \in [-1,1] \f$
540 //=====================================================================
541 void FishDomain::r_upper_body_N(const unsigned& t,
542 const Vector<double>& zeta,
544 {
545 // Lagrangian coordinate along curved "back"
546 Vector<double> x(1);
547 x[0] = Xi_nose + (Xi_tail - Xi_nose) * 0.5 * (zeta[0] + 1.0);
548
549 // Get position on curved back
550 Back_pt->position(t, x, r);
551
552 } // end of r_upper_body_N
553
554 //================start_of_r_upper_body_E=============================
555 /// Eastern edge of upper body macro element; \f$ \zeta \in [-1,1] \f$
556 //=====================================================================
557 void FishDomain::r_upper_body_E(const unsigned& t,
558 const Vector<double>& zeta,
560 {
561 // Top right corner (tail end) of body
563 Vector<double> x(1);
564 x[0] = Xi_tail;
565 Back_pt->position(t, x, r_top);
566
567 // Corresponding point on the x-axis
569 r_back[0] = r_top[0];
570 r_back[1] = 0.0;
571
572 r[0] = r_back[0] + (r_top[0] - r_back[0]) * 0.5 * (zeta[0] + 1.0);
573 r[1] = r_back[1] + (r_top[1] - r_back[1]) * 0.5 * (zeta[0] + 1.0);
574
575 } // end of r_upper_body_E
576
577 //==================start_of_r_upper_body_S============================
578 /// Southern edge of upper body macro element; \f$ \zeta \in [-1,1] \f$
579 //=====================================================================
580 void FishDomain::r_upper_body_S(const unsigned& t,
581 const Vector<double>& zeta,
583 {
584 // Top right (tail) corner of fish body
586 Vector<double> x(1);
587 x[0] = Xi_tail;
588 Back_pt->position(t, x, r_top);
589
590 // Straight line from mouth to start of fin (=end of body)
591 r[0] = X_mouth + (r_top[0] - X_mouth) * 0.5 * (zeta[0] + 1.0);
592 r[1] = 0.0;
593
594 } // end of r_upper_body_S
595
596 //===============start_of_r_upper_body_W==============================
597 /// Western edge of upper body macro element; \f$ \zeta \in [-1,1] \f$
598 //====================================================================
599 void FishDomain::r_upper_body_W(const unsigned& t,
600 const Vector<double>& zeta,
602 {
603 // Top left (mouth) corner of curved boundary of upper body
605 Vector<double> x(1);
606 x[0] = Xi_nose;
607 Back_pt->position(t, x, r_top);
608
609 // The "mouth"
611 r_mouth[0] = X_mouth;
612 r_mouth[1] = 0.0;
613
614 // Straight line from mouth to leftmost corner on curved boundary
615 // of upper body
616 r[0] = r_mouth[0] + (r_top[0] - r_mouth[0]) * 0.5 * (zeta[0] + 1.0);
617 r[1] = r_mouth[1] + (r_top[1] - r_mouth[1]) * 0.5 * (zeta[0] + 1.0);
618
619 } // end of r_upper_body_W
620
621} // namespace oomph
622
623#endif
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
Fish shaped domain, represented by four MacroElements. Shape is parametrised by GeomObject that repre...
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 .
double Y_fin
Y coordinate of fin tip.
void r_lower_fin_S(const unsigned &t, const Vector< double > &zeta, Vector< double > &f)
Boundary of lower fin macro element zeta .
double & xi_nose()
Start coordinate on wall (near nose)
Definition fish_domain.h:99
void macro_element_boundary(const unsigned &t, const unsigned &i_macro, const unsigned &i_direct, const Vector< double > &zeta, Vector< double > &r)
Vector representation of the i_macro-th macro element boundary i_direct (N/S/W/E) at the discrete tim...
double Xi_tail
"Tail" limit for the (1D) coordinates along the wall
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 .
void r_upper_body_N(const unsigned &t, const Vector< double > &zeta, Vector< double > &f)
Boundary of upper body macro element zeta .
void r_upper_body_E(const unsigned &t, const Vector< double > &zeta, Vector< double > &f)
Boundary of upper body macro element zeta .
void r_upper_fin_N(const unsigned &t, const Vector< double > &zeta, Vector< double > &f)
Boundary of upper fin macro element zeta .
void r_lower_fin_N(const unsigned &t, const Vector< double > &zeta, Vector< double > &f)
Boundary of lower fin macro element zeta .
void r_upper_fin_W(const unsigned &t, const Vector< double > &zeta, Vector< double > &f)
Boundary of upper fin macro element zeta .
void r_lower_body_N(const unsigned &t, const Vector< double > &zeta, Vector< double > &f)
Boundary of lower body macro element zeta .
FishDomain(const FishDomain &)=delete
Broken copy constructor.
double & y_fin()
y-position of fin tip
Definition fish_domain.h:87
void r_lower_fin_E(const unsigned &t, const Vector< double > &zeta, Vector< double > &f)
Boundary of lower fin macro element zeta .
double & x_mouth()
x-position of mouth
Definition fish_domain.h:93
FishDomain(GeomObject *back_pt, const double &xi_nose, const double &xi_tail)
Constructor: Pass pointer to GeomObject that represents the (upper) curved boundary of the fish's bod...
Definition fish_domain.h:48
double X_mouth
X coordinate of corner of mouth.
void r_lower_body_S(const unsigned &t, const Vector< double > &zeta, Vector< double > &f)
Southern boundary of lower body macro element zeta .
void r_lower_fin_W(const unsigned &t, const Vector< double > &zeta, Vector< double > &f)
Boundary of lower fin macro element zeta .
virtual ~FishDomain()
Destructor for FishDomain: Empty; cleanup done in base class.
Definition fish_domain.h:78
void r_lower_body_E(const unsigned &t, const Vector< double > &zeta, Vector< double > &f)
Boundary of lower body macro element zeta .
void r_upper_body_W(const unsigned &t, const Vector< double > &zeta, Vector< double > &f)
Boundary of upper body macro element zeta .
void r_upper_fin_S(const unsigned &t, const Vector< double > &zeta, Vector< double > &f)
Boundary of upper fin macro element zeta .
double & x_fin()
x-position of fin tip
Definition fish_domain.h:81
GeomObject * Back_pt
Pointer to the fish's back.
double X_fin
X coordinate of fin tip.
void r_upper_body_S(const unsigned &t, const Vector< double > &zeta, Vector< double > &f)
Boundary of upper body macro element zeta .
double Xi_nose
"Nose" limit for the (1D) coordinates along the wall
double & xi_tail()
End coordinate on wall (near tail)
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....
TAdvectionDiffusionReactionElement<NREAGENT,DIM,NNODE_1D> elements are isoparametric triangular DIM-d...
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).