full_circle_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 
27 #ifndef OOMPH_FULL_CIRCLE_DOMAIN_HEADER
28 #define OOMPH_FULL_CIRCLE_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  //=================================================================
67  //=================================================================
68  class FullCircleDomain : public Domain
69  {
70  public:
77  FullCircleDomain(GeomObject* area_geom_object_pt,
78  const Vector<double>& theta_positions,
79  const Vector<double>& radius_box)
80  : Theta_positions(theta_positions),
81  Radius_box(radius_box),
82  Area_pt(area_geom_object_pt)
83  {
84  // There are five macro elements
85  const unsigned n_macro = 5;
86  Macro_element_pt.resize(n_macro);
87 
88  // Create the macro elements
89  for (unsigned i = 0; i < n_macro; i++)
90  {
91  Macro_element_pt[i] = new QMacroElement<2>(this, i);
92  }
93  }
94 
97 
99  void operator=(const FullCircleDomain&) = delete;
100 
101 
104 
105 
110  void macro_element_boundary(const unsigned& t,
111  const unsigned& i_macro,
112  const unsigned& i_direct,
113  const Vector<double>& s,
114  Vector<double>& f);
115 
116  private:
121 
125 
128 
134  const Vector<double>& high,
135  const double& s,
136  Vector<double>& f)
137  {
138  // Loop over all coordinates (we are working in 2D)
139  for (unsigned i = 0; i < 2; i++)
140  {
141  f[i] = low[i] + (high[i] - low[i]) * 0.5 * (s + 1.0);
142  }
143  }
144  };
145 
146 
150 
151 
152  //=================================================================
156  //=================================================================
158  const unsigned& imacro,
159  const unsigned& idirect,
160  const Vector<double>& s,
161  Vector<double>& f)
162  {
163  using namespace QuadTreeNames;
164 
165  // Get the coordinates of the corners of the box
167  // Get the corresponding coordinates on the boundary
169 
170  // Storage for position in the area
171  Vector<double> zeta(2);
172 
173  // Loop over the angles
174  for (unsigned j = 0; j < 4; j++)
175  {
176  // Set up the storage
177  Box[j].resize(2);
178  Wall[j].resize(2);
179 
180  // Set the other values of zeta
181  zeta[0] = Radius_box[j];
182  zeta[1] = Theta_positions[j];
183  // Now get the values
184  Area_pt->position(t, zeta, Box[j]);
185 
186  // Now get the position on the boundary
187  zeta[0] = 1.0;
188  Area_pt->position(t, zeta, Wall[j]);
189  }
190 
191  // Define pi
192  const double pi = MathematicalConstants::Pi;
193 
194  // Which macro element?
195  // --------------------
196  switch (imacro)
197  {
198  // Macro element 0: Central box
199  case 0:
200 
201  // Choose a direction
202  switch (idirect)
203  {
204  case N:
205  // Linearly interpolate between the two corners of the box
206  lin_interpolate(Box[3], Box[2], s[0], f);
207  break;
208 
209  case S:
210  // Linearly interpolate between the two corners of the box
211  lin_interpolate(Box[0], Box[1], s[0], f);
212 
213  case W:
214  // Linearly interpolate between the two corners of the box
215  lin_interpolate(Box[0], Box[3], s[0], f);
216  break;
217 
218  case E:
219  // Linearly interpolate between the two corners of the box
220  lin_interpolate(Box[1], Box[2], s[0], f);
221  break;
222 
223  default:
224  std::ostringstream error_stream;
225  error_stream << "idirect is " << idirect << " not one of N, S, E, W"
226  << std::endl;
227 
228  throw OomphLibError(error_stream.str(),
231  break;
232  }
233 
234  break;
235 
236  // Macro element 1: Bottom
237  case 1:
238 
239  // Choose a direction
240  switch (idirect)
241  {
242  case N:
243  // Linearly interpolate between the two corners of the box
244  lin_interpolate(Box[0], Box[1], s[0], f);
245  break;
246 
247  case S:
248  // Get the position on the wall by linearly interpolating in theta
249  zeta[0] = 1.0;
250  zeta[1] =
251  Theta_positions[0] +
252  (Theta_positions[1] - Theta_positions[0]) * 0.5 * (s[0] + 1.0);
253 
254  Area_pt->position(t, zeta, f);
255  break;
256 
257  case W:
258  // Now linearly interpolate between the wall and the box
259  lin_interpolate(Wall[0], Box[0], s[0], f);
260  break;
261 
262  case E:
263  // Linearly interpolate between the wall and the box
264  lin_interpolate(Wall[1], Box[1], s[0], f);
265  break;
266 
267  default:
268 
269  std::ostringstream error_stream;
270  error_stream << "idirect is " << idirect << " not one of N, S, E, W"
271  << std::endl;
272 
273  throw OomphLibError(error_stream.str(),
276  break;
277  }
278 
279 
280  break;
281 
282  // Macro element 2:Right
283  case 2:
284 
285  // Which direction?
286  switch (idirect)
287  {
288  case N:
289  // Linearly interpolate between the box and the wall
290  lin_interpolate(Box[2], Wall[2], s[0], f);
291  break;
292 
293  case S:
294  // Linearly interpolate between the box and the wall
295  lin_interpolate(Box[1], Wall[1], s[0], f);
296  break;
297 
298  case W:
299  // Linearly interpolate between the two corners of the box
300  lin_interpolate(Box[1], Box[2], s[0], f);
301  break;
302 
303  case E:
304  // Get the position on the wall by linearly interpolating in theta
305  zeta[0] = 1.0;
306  zeta[1] =
307  Theta_positions[1] +
308  (Theta_positions[2] - Theta_positions[1]) * 0.5 * (s[0] + 1.0);
309 
310  Area_pt->position(t, zeta, f);
311  break;
312 
313  default:
314  std::ostringstream error_stream;
315  error_stream << "idirect is " << idirect << " not one of N, S, W, E"
316  << std::endl;
317 
318  throw OomphLibError(error_stream.str(),
321  }
322 
323  break;
324 
325  // Macro element 3: Top
326  case 3:
327 
328  // Which direction?
329  switch (idirect)
330  {
331  case N:
332  // Get the position on the wall by linearly interpolating in theta
333  zeta[0] = 1.0;
334  zeta[1] =
335  Theta_positions[3] +
336  (Theta_positions[2] - Theta_positions[3]) * 0.5 * (s[0] + 1.0);
337 
338  Area_pt->position(t, zeta, f);
339  break;
340 
341  case S:
342  // Linearly interpolate between the two corners of the box
343  lin_interpolate(Box[3], Box[1], s[0], f);
344  break;
345 
346  case W:
347  // Linearly interpolate between the box and the wall
348  lin_interpolate(Box[3], Wall[3], s[0], f);
349  break;
350 
351  case E:
352  // Linearly interpolate between the box and the wall
353  lin_interpolate(Box[2], Wall[2], s[0], f);
354  break;
355 
356  default:
357  std::ostringstream error_stream;
358  error_stream << "idirect is " << idirect << " not one of N, S, E, W"
359  << std::endl;
360 
361  throw OomphLibError(error_stream.str(),
364  }
365 
366  break;
367 
368 
369  // Macro element 4: Left
370  case 4:
371 
372  // Which direction?
373  switch (idirect)
374  {
375  case N:
376  // Linearly interpolate between the wall and the box
377  lin_interpolate(Wall[3], Box[3], s[0], f);
378  break;
379 
380  case S:
381  // Linearly interpolate between the wall and the box
382  lin_interpolate(Wall[0], Box[0], s[0], f);
383  break;
384 
385  case W:
386  // Entirely on the wall, Need to be careful
387  // because this is the point at which theta passes through the
388  //"branch cut"
389  zeta[0] = 1.0;
390  zeta[1] = Theta_positions[0] + 2.0 * pi +
391  (Theta_positions[3] - (Theta_positions[0] + 2.0 * pi)) *
392  0.5 * (s[0] + 1.0);
393 
394  Area_pt->position(t, zeta, f);
395  break;
396 
397  case E:
398  // Linearly interpolate between the two corners of the box
399  lin_interpolate(Box[0], Box[3], s[0], f);
400  break;
401 
402  default:
403  std::ostringstream error_stream;
404  error_stream << "idirect is " << idirect << " not one of N, S, W, E"
405  << std::endl;
406 
407  throw OomphLibError(error_stream.str(),
410  }
411  break;
412 
413 
414  default:
415  // Error
416  std::ostringstream error_stream;
417  error_stream << "Wrong imacro " << imacro << std::endl;
418  throw OomphLibError(
419  error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
420  }
421  }
422 
423 } // namespace oomph
424 
425 #endif
int i
Definition: BiCGSTAB_step_by_step.cpp:9
Definition: Box.h:12
Definition: SpeedTestWallInteractions.cpp:16
Definition: domain.h:67
Vector< MacroElement * > Macro_element_pt
Vector of pointers to macro elements.
Definition: domain.h:301
Definition: full_circle_domain.h:69
FullCircleDomain(const FullCircleDomain &)=delete
Broken copy constructor.
FullCircleDomain(GeomObject *area_geom_object_pt, const Vector< double > &theta_positions, const Vector< double > &radius_box)
Definition: full_circle_domain.h:77
GeomObject * Area_pt
Pointer to geometric object that represents the domain.
Definition: full_circle_domain.h:127
void lin_interpolate(const Vector< double > &low, const Vector< double > &high, const double &s, Vector< double > &f)
Definition: full_circle_domain.h:133
void macro_element_boundary(const unsigned &t, const unsigned &i_macro, const unsigned &i_direct, const Vector< double > &s, Vector< double > &f)
Definition: full_circle_domain.h:157
Vector< double > Radius_box
Definition: full_circle_domain.h:124
void operator=(const FullCircleDomain &)=delete
Broken assignment operator.
Vector< double > Theta_positions
Definition: full_circle_domain.h:120
~FullCircleDomain()
Destructor: Empty; cleanup done in base class.
Definition: full_circle_domain.h:103
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: macro_element.h:279
@ N
Definition: constructor.cpp:22
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 E
Elastic modulus.
Definition: TwenteMeshGluing.cpp:68
const Mdouble pi
Definition: ExtendedMath.h:23
const double Pi
50 digits from maple
Definition: oomph_utilities.h:157
@ S
Definition: quadtree.h:62
@ W
Definition: quadtree.h:63
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