geom_objects.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-2024 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 #ifndef OOMPH_GEOM_OBJECTS_HEADER
27 #define OOMPH_GEOM_OBJECTS_HEADER
28 
29 
30 // Config header generated by autoconfig
31 #ifdef HAVE_CONFIG_H
32 #include <oomph-lib-config.h>
33 #endif
34 
35 // oomph-lib headers
36 #include "nodes.h"
37 #include "timesteppers.h"
38 
39 
40 namespace oomph
41 {
42  /// /////////////////////////////////////////////////////////////////////
43  /// /////////////////////////////////////////////////////////////////////
44  // Geometric object
45  /// /////////////////////////////////////////////////////////////////////
46  /// /////////////////////////////////////////////////////////////////////
47 
48 
49  //========================================================================
50  /// A geometric object is an object that provides a parametrised
51  /// description of its shape via the function GeomObject::position(...).
52  ///
53  /// The minimum functionality is: The geometric object has
54  /// a number of Lagrangian (intrinsic) coordinates that parametrise
55  /// the (Eulerian) position vector, whose dimension might
56  /// differ from the number of Lagrangian (intrinsic) coordinates (e.g.
57  /// for shell-like objects).
58  ///
59  /// We might also need the derivatives of the position
60  /// Vector w.r.t. to the Lagrangian (intrinsic) coordinates and interfaces
61  /// for this functionality are provided.
62  /// [Note: For some geometric objects it might be too tedious to work out
63  /// the derivatives and they might not be needed anyway. In other
64  /// cases we might always need the position vector and all
65  /// derivatives at the same time. We provide suitable interfaces
66  /// for these cases in virtual but broken (rather than pure virtual) form
67  /// so the user can (but doesn't have to) provide the required versions
68  /// by overloading.]
69  ///
70  /// The shape of a geometric object is usually determined by a number
71  /// of parameters whose value might have to be determined as part
72  /// of the overall solution (e.g. for geometric objects that represent
73  /// elastic walls). The geometric object
74  /// therefore has a vector of (pointers to) geometric Data,
75  /// which can be free/pinned and have a time history, etc. This makes
76  /// it possible to `upgrade' GeomObjects to GeneralisedElements -- in this
77  /// case the geometric Data plays the role of internal Data in the
78  /// GeneralisedElement. Conversely, FiniteElements, in which a geometry
79  /// (spatial coordinate) has been defined, inherit from GeomObjects,
80  /// which is particularly useful in FSI computations:
81  /// Meshing of moving domains is typically performed by representing the
82  /// domain as an object of type Domain and, by default, Domain boundaries are
83  /// represented by GeomObjects. In FSI computations, the boundary
84  /// of the fluid domain is represented by a number of solid mechanics
85  /// elements. These elements are, in fact, GeomObjects via inheritance so
86  /// that the we can use the standard interfaces of the GeomObject class for
87  /// mesh generation. An example is the class \c FSIHermiteBeamElement which is
88  /// derived from the class \c HermiteBeamElement (a `normal' beam element) and
89  /// the \c GeomObject class.
90  ///
91  /// The shape of a geometric object can have an explicit time-dependence, for
92  /// instance in cases where a domain boundary is performing
93  /// prescribed motions. We provide access to the `global'
94  /// time by giving the object a pointer to a timestepping scheme.
95  /// [Note that, within the overall FE code, time is only ever evaluated at
96  /// discrete instants (which are accessible via the timestepper),
97  /// never in continuous form]. The timestepper is also needed to evaluate
98  /// time-derivatives if the geometric Data carries a time history.
99  //========================================================================
101  {
102  public:
103  /// Default constructor.
105 
106  /// Constructor: Pass dimension of geometric object (# of Eulerian
107  /// coords = # of Lagrangian coords; no time history available/needed)
108  GeomObject(const unsigned& ndim)
110  {
111  }
112 
113 
114  /// Constructor: pass # of Eulerian and Lagrangian coordinates.
115  /// No time history available/needed
116  GeomObject(const unsigned& nlagrangian, const unsigned& ndim)
118  {
119 #ifdef PARANOID
120  if (nlagrangian > ndim)
121  {
122  std::ostringstream error_message;
123  error_message << "# of Lagrangian coordinates " << nlagrangian
124  << " cannot be bigger than # of Eulerian ones " << ndim
125  << std::endl;
126 
127  throw OomphLibError(error_message.str(),
128  OOMPH_CURRENT_FUNCTION,
129  OOMPH_EXCEPTION_LOCATION);
130  }
131 #endif
132  }
133 
134  /// Constructor: pass # of Eulerian and Lagrangian coordinates
135  /// and pointer to time-stepper which is used to handle the
136  /// position at previous timesteps and allows the evaluation
137  /// of veloc/acceleration etc. in cases where the GeomData
138  /// varies with time.
139  GeomObject(const unsigned& nlagrangian,
140  const unsigned& ndim,
143  Ndim(ndim),
145  {
146 #ifdef PARANOID
147  if (nlagrangian > ndim)
148  {
149  std::ostringstream error_message;
150  error_message << "# of Lagrangian coordinates " << nlagrangian
151  << " cannot be bigger than # of Eulerian ones " << ndim
152  << std::endl;
153 
154  throw OomphLibError(error_message.str(),
155  OOMPH_CURRENT_FUNCTION,
156  OOMPH_EXCEPTION_LOCATION);
157  }
158 #endif
159  }
160 
161  /// Broken copy constructor
162  GeomObject(const GeomObject& dummy) = delete;
163 
164  /// Broken assignment operator
165  void operator=(const GeomObject&) = delete;
166 
167  /// (Empty) destructor
168  virtual ~GeomObject() {}
169 
170  /// Access function to # of Lagrangian coordinates
171  unsigned nlagrangian() const
172  {
173  return NLagrangian;
174  }
175 
176  /// Access function to # of Eulerian coordinates
177  unsigned ndim() const
178  {
179  return Ndim;
180  }
181 
182  /// Set # of Lagrangian and Eulerian coordinates
183  void set_nlagrangian_and_ndim(const unsigned& n_lagrangian,
184  const unsigned& n_dim)
185  {
186  NLagrangian = n_lagrangian;
187  Ndim = n_dim;
188  }
189 
190  /// Access function for pointer to time stepper: Null if object is
191  /// not time-dependent
193  {
195  }
196 
197  /// Access function for pointer to time stepper: Null if object is
198  /// not time-dependent. Const version
200  {
202  }
203 
204  /// How many items of Data does the shape of the object depend on?
205  /// This is implemented as a broken virtual function. You must overload
206  /// this for GeomObjects that contain geometric Data, i.e. GeomObjects
207  /// whose shape depends on Data that may contain unknowns in the
208  /// overall Problem.
209  virtual unsigned ngeom_data() const
210  {
211  std::ostringstream error_message;
212  error_message
213  << "GeomObject::ngeom_data() is a broken virtual function.\n"
214  << "Please implement it (and its companion "
215  "GeomObject::geom_data_pt())\n"
216  << "for any GeomObject whose shape depends on Data whose values may \n"
217  << "be unknowns in the global Problem. \n"
218  << "If you have arrived here in a parallel job then it may be the case "
219  "\n"
220  << "that you have not set the keep_all_elements_as_halos() flag to "
221  "true \n"
222  << "for the MeshAsGeomObject representing the lower-dimensional mesh \n"
223  << "in a problem with multiple meshes. \n";
224  throw OomphLibError(
225  error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
226  }
227 
228  /// Return pointer to the j-th Data item that the object's
229  /// shape depends on. This is implemented as a broken virtual function.
230  /// You must overload this for GeomObjects that contain geometric Data,
231  /// i.e. GeomObjects whose shape depends on Data that may contain
232  /// unknowns in the overall Problem.
233  virtual Data* geom_data_pt(const unsigned& j)
234  {
235  std::ostringstream error_message;
236  error_message
237  << "GeomObject::geom_data_pt() is a broken virtual function.\n"
238  << "Please implement it (and its companion GeomObject::ngeom_data())\n"
239  << "for any GeomObject whose shape depends on Data whose values may \n"
240  << "be unknowns in the global Problem. \n"
241  << "If you have arrived here in a parallel job then it may be the case "
242  "\n"
243  << "that you have not set the keep_all_elements_as_halos() flag to "
244  "true \n"
245  << "for the MeshAsGeomObject representing the lower-dimensional mesh \n"
246  << "in a problem with multiple meshes. \n";
247  throw OomphLibError(
248  error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
249  }
250 
251  /// Parametrised position on object at current time: r(zeta).
252  virtual void position(const Vector<double>& zeta,
253  Vector<double>& r) const = 0;
254 
255  /// Parametrised position on object: r(zeta). Evaluated at
256  /// previous timestep. t=0: current time; t>0: previous
257  /// timestep. Works for t=0 but needs to be overloaded
258  /// if genuine time-dependence is required.
259  virtual void position(const unsigned& t,
260  const Vector<double>& zeta,
261  Vector<double>& r) const
262  {
263  if (t != 0)
264  {
265  throw OomphLibError(
266  "Calling steady position() from discrete unsteady position()",
267  OOMPH_CURRENT_FUNCTION,
268  OOMPH_EXCEPTION_LOCATION);
269  }
270  position(zeta, r);
271  }
272 
273 
274  /// Parametrised position on object: r(zeta). Evaluated at
275  /// the continuous time value, t.
276  virtual void position(const double& t,
277  const Vector<double>& zeta,
278  Vector<double>& r) const
279  {
280  std::ostringstream error_message;
281  error_message << "GeomObject::position() is a broken virtual function.\n"
282  << "Please implement it for any GeomObject whose shape\n"
283  << "is time-dependent and will be used in the extrusion\n"
284  << "of a mesh (in the time direction).\n";
285  throw OomphLibError(
286  error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
287  }
288 
289 
290  /// j-th time-derivative on object at current time:
291  /// \f$ \frac{d^{j} r(\zeta)}{dt^j} \f$.
292  virtual void dposition_dt(const Vector<double>& zeta,
293  const unsigned& j,
294  Vector<double>& drdt)
295  {
296  // If the index is zero the return the position
297  if (j == 0)
298  {
299  position(zeta, drdt);
300  }
301  // Otherwise assume that the geometric object is static
302  // and return zero after throwing a warning
303  else
304  {
305  std::ostringstream warning_stream;
306  warning_stream
307  << "Using default (static) assignment " << j
308  << "-th time derivative in GeomObject::dposition_dt(...) is zero\n"
309  << "Overload for your specific geometric object if this is not \n"
310  << "appropriate. \n";
311  OomphLibWarning(warning_stream.str(),
312  "GeomObject::dposition_dt()",
313  OOMPH_EXCEPTION_LOCATION);
314 
315  unsigned n = drdt.size();
316  for (unsigned i = 0; i < n; i++)
317  {
318  drdt[i] = 0.0;
319  }
320  }
321  }
322 
323 
324  /// Derivative of position Vector w.r.t. to coordinates:
325  /// \f$ \frac{dR_i}{d \zeta_\alpha}\f$ = drdzeta(alpha,i).
326  /// Evaluated at current time.
327  virtual void dposition(const Vector<double>& zeta,
328  DenseMatrix<double>& drdzeta) const
329  {
330  throw OomphLibError(
331  "You must specify dposition() for your own object! \n",
332  OOMPH_CURRENT_FUNCTION,
333  OOMPH_EXCEPTION_LOCATION);
334  }
335 
336 
337  /// 2nd derivative of position Vector w.r.t. to coordinates:
338  /// \f$ \frac{d^2R_i}{d \zeta_\alpha d \zeta_\beta}\f$ =
339  /// ddrdzeta(alpha,beta,i).
340  /// Evaluated at current time.
341  virtual void d2position(const Vector<double>& zeta,
342  RankThreeTensor<double>& ddrdzeta) const
343  {
344  throw OomphLibError(
345  "You must specify d2position() for your own object! \n",
346  OOMPH_CURRENT_FUNCTION,
347  OOMPH_EXCEPTION_LOCATION);
348  }
349 
350 
351  /// Posn Vector and its 1st & 2nd derivatives
352  /// w.r.t. to coordinates:
353  /// \f$ \frac{dR_i}{d \zeta_\alpha}\f$ = drdzeta(alpha,i).
354  /// \f$ \frac{d^2R_i}{d \zeta_\alpha d \zeta_\beta}\f$ =
355  /// ddrdzeta(alpha,beta,i).
356  /// Evaluated at current time.
357  virtual void d2position(const Vector<double>& zeta,
358  Vector<double>& r,
359  DenseMatrix<double>& drdzeta,
360  RankThreeTensor<double>& ddrdzeta) const
361  {
362  throw OomphLibError(
363  "You must specify d2position() for your own object! \n",
364  OOMPH_CURRENT_FUNCTION,
365  OOMPH_EXCEPTION_LOCATION);
366  }
367 
368  /// A geometric object may be composed of may sub-objects (e.g.
369  /// a finite-element representation of a boundary). In order to implement
370  /// sparse update functions, it is necessary to know the sub-object
371  /// and local coordinate within
372  /// that sub-object at a given intrinsic coordinate, zeta. Note that only
373  /// one sub-object can "cover" any given intrinsic position. If the position
374  /// is at an "interface" between sub-objects, either one can be returned.
375  /// The default implementation merely returns, the pointer to the "entire"
376  /// GeomObject and the coordinate, zeta
377  /// The optional boolean flag only applies if a Newton method is used to
378  /// find the value of zeta, and if true the value of the coordinate
379  /// s is used as the initial guess for the method. If the flag is false
380  /// (the default) a value of s=0 is used as the initial guess.
381  virtual void locate_zeta(
382  const Vector<double>& zeta,
383  GeomObject*& sub_geom_object_pt,
384  Vector<double>& s,
385  const bool& use_coordinate_as_initial_guess = false)
386  {
387  // By default, the local coordinate is intrinsic coordinate
388  s = zeta;
389  // The sub_object is the entire object
390  sub_geom_object_pt = this;
391  }
392 
393  /// A geometric object may be composed of many sub-objects
394  /// each with their own local coordinate. This function returns the
395  /// "global" intrinsic coordinate zeta (within the compound object), at
396  /// a given local coordinate s (i.e. the intrinsic coordinate of the
397  /// sub-GeomObject. In simple (non-compound) GeomObjects, the local
398  /// intrinsic coordinate is the global intrinsic coordinate
399  /// and so the function merely returns s. To make it less likely
400  /// that the default implementation is called in error (because
401  /// it is not overloaded in a derived GeomObject where the default
402  /// is not appropriate, we do at least check that s and zeta
403  /// have the same size if called in PARANOID mode.
404  virtual void interpolated_zeta(const Vector<double>& s,
405  Vector<double>& zeta) const
406  {
407 #ifdef PARANOID
408  if (zeta.size() != s.size())
409  {
410  std::ostringstream error_message;
411  error_message << "You've called the default implementation of "
412  << "GeomObject::interpolated_zeta() \n"
413  << "but zeta.size()=" << zeta.size()
414  << "and s.size()=" << s.size() << std::endl
415  << "This doesn't make sense! You probably have to \n"
416  << "overload this function in your specific GeomObject\n";
417  throw OomphLibError(error_message.str(),
418  OOMPH_CURRENT_FUNCTION,
419  OOMPH_EXCEPTION_LOCATION);
420  }
421 #endif
422  // By default the global intrinsic coordinate is equal to the local one
423  zeta = s;
424  }
425 
426  protected:
427  /// Number of Lagrangian (intrinsic) coordinates
428  unsigned NLagrangian;
429 
430  /// Number of Eulerian coordinates
431  unsigned Ndim;
432 
433  /// Timestepper (used to handle access to geometry
434  /// at previous timesteps)
436  };
437 
438 
439  /// ////////////////////////////////////////////////////////////////////
440  /// ////////////////////////////////////////////////////////////////////
441  // Straight line as geometric object
442  /// ////////////////////////////////////////////////////////////////////
443  /// ////////////////////////////////////////////////////////////////////
444 
445 
446  //=========================================================================
447  /// Steady, straight 1D line in 2D space
448  /// \f[ x = \zeta \f]
449  /// \f[ y = H \f]
450  //=========================================================================
451  class StraightLine : public GeomObject
452  {
453  public:
454  /// Constructor: One item of geometric data:
455  /// \code
456  /// Geom_data_pt[0]->value(0) = height
457  /// \endcode
459  {
460 #ifdef PARANOID
461  if (geom_data_pt.size() != 1)
462  {
463  std::ostringstream error_message;
464  error_message << "geom_data_pt should have size 1, not "
465  << geom_data_pt.size() << std::endl;
466 
467  if (geom_data_pt[0]->nvalue() != 1)
468  {
469  error_message << "geom_data_pt[0] should have 1 value, not "
470  << geom_data_pt[0]->nvalue() << std::endl;
471  }
472 
473  throw OomphLibError(error_message.str(),
474  OOMPH_CURRENT_FUNCTION,
475  OOMPH_EXCEPTION_LOCATION);
476  }
477 #endif
478  Geom_data_pt.resize(1);
479  Geom_data_pt[0] = geom_data_pt[0];
480 
481  // Data has been created externally: Must not clean up
482  Must_clean_up = false;
483  }
484 
485  /// Constructor: Pass height (pinned by default)
486  StraightLine(const double& height) : GeomObject(1, 2)
487  {
488  // Create Data for straight-line object: The only geometric data is the
489  // height which is pinned
490  Geom_data_pt.resize(1);
491 
492  // Create data: One value, no timedependence, free by default
493  Geom_data_pt[0] = new Data(1);
494 
495  // I've created the data, I need to clean up
496  Must_clean_up = true;
497 
498  // Pin the data
499  Geom_data_pt[0]->pin(0);
500 
501  // Give it a value: Initial height
502  Geom_data_pt[0]->set_value(0, height);
503  }
504 
505 
506  /// Broken copy constructor
507  StraightLine(const StraightLine& dummy) = delete;
508 
509  /// Broken assignment operator
510  void operator=(const StraightLine&) = delete;
511 
512  /// Destructor: Clean up if necessary
514  {
515  // Do I need to clean up?
516  if (Must_clean_up)
517  {
518  delete Geom_data_pt[0];
519  Geom_data_pt[0] = 0;
520  }
521  }
522 
523 
524  /// Position Vector at Lagrangian coordinate zeta
525  void position(const Vector<double>& zeta, Vector<double>& r) const
526  {
527  // Position Vector
528  r[0] = zeta[0];
529  r[1] = Geom_data_pt[0]->value(0);
530  }
531 
532 
533  /// Parametrised position on object: r(zeta). Evaluated at
534  /// previous timestep. t=0: current time; t>0: previous
535  /// timestep.
536  void position(const unsigned& t,
537  const Vector<double>& zeta,
538  Vector<double>& r) const
539  {
540 #ifdef PARANOID
541  if (t > Geom_data_pt[0]->time_stepper_pt()->nprev_values())
542  {
543  std::ostringstream error_message;
544  error_message << "t > nprev_values() " << t << " "
545  << Geom_data_pt[0]->time_stepper_pt()->nprev_values()
546  << std::endl;
547 
548  throw OomphLibError(error_message.str(),
549  OOMPH_CURRENT_FUNCTION,
550  OOMPH_EXCEPTION_LOCATION);
551  }
552 #endif
553 
554  // Position Vector at time level t
555  r[0] = zeta[0];
556  r[1] = Geom_data_pt[0]->value(t, 0);
557  }
558 
559 
560  /// Derivative of position Vector w.r.t. to coordinates:
561  /// \f$ \frac{dR_i}{d \zeta_\alpha}\f$ = drdzeta(alpha,i).
562  /// Evaluated at current time.
563  virtual void dposition(const Vector<double>& zeta,
564  DenseMatrix<double>& drdzeta) const
565  {
566  // Tangent vector
567  drdzeta(0, 0) = 1.0;
568  drdzeta(0, 1) = 0.0;
569  }
570 
571 
572  /// 2nd derivative of position Vector w.r.t. to coordinates:
573  /// \f$ \frac{d^2R_i}{d \zeta_\alpha d \zeta_\beta}\f$ =
574  /// ddrdzeta(alpha,beta,i). Evaluated at current time.
575  virtual void d2position(const Vector<double>& zeta,
576  RankThreeTensor<double>& ddrdzeta) const
577  {
578  // Derivative of tangent vector
579  ddrdzeta(0, 0, 0) = 0.0;
580  ddrdzeta(0, 0, 1) = 0.0;
581  }
582 
583 
584  /// Posn Vector and its 1st & 2nd derivatives
585  /// w.r.t. to coordinates:
586  /// \f$ \frac{dR_i}{d \zeta_\alpha}\f$ = drdzeta(alpha,i).
587  /// \f$ \frac{d^2R_i}{d \zeta_\alpha d \zeta_\beta}\f$ =
588  /// ddrdzeta(alpha,beta,i).
589  /// Evaluated at current time.
590  virtual void d2position(const Vector<double>& zeta,
591  Vector<double>& r,
592  DenseMatrix<double>& drdzeta,
593  RankThreeTensor<double>& ddrdzeta) const
594  {
595  // Position Vector
596  r[0] = zeta[0];
597  r[1] = Geom_data_pt[0]->value(0);
598 
599  // Tangent vector
600  drdzeta(0, 0) = 1.0;
601  drdzeta(0, 1) = 0.0;
602 
603  // Derivative of tangent vector
604  ddrdzeta(0, 0, 0) = 0.0;
605  ddrdzeta(0, 0, 1) = 0.0;
606  }
607 
608 
609  /// How many items of Data does the shape of the object depend on?
610  unsigned ngeom_data() const
611  {
612  return Geom_data_pt.size();
613  }
614 
615  /// Return pointer to the j-th Data item that the object's
616  /// shape depends on
617  Data* geom_data_pt(const unsigned& j)
618  {
619  return Geom_data_pt[j];
620  }
621 
622  private:
623  /// Vector of pointers to Data items that affects the object's shape
625 
626  /// Do I need to clean up?
628  };
629 
630 
631  /// ////////////////////////////////////////////////////////////////////
632  /// ////////////////////////////////////////////////////////////////////
633  // Ellipse as geometric object
634  /// ////////////////////////////////////////////////////////////////////
635  /// ////////////////////////////////////////////////////////////////////
636 
637 
638  //=========================================================================
639  /// Steady ellipse with half axes A and B as geometric object:
640  /// \f[ x = A \cos(\zeta) \f]
641  /// \f[ y = B \sin(\zeta) \f]
642  //=========================================================================
643  class Ellipse : public GeomObject
644  {
645  public:
646  /// Constructor: 1 Lagrangian coordinate, 2 Eulerian coords. Pass
647  /// half axes as Data:
648  /// \code
649  /// Geom_data_pt[0]->value(0) = A
650  /// Geom_data_pt[0]->value(1) = B
651  /// \endcode
653  {
654 #ifdef PARANOID
655  if (geom_data_pt.size() != 1)
656  {
657  std::ostringstream error_message;
658  error_message << "geom_data_pt should have size 1, not "
659  << geom_data_pt.size() << std::endl;
660 
661  if (geom_data_pt[0]->nvalue() != 2)
662  {
663  error_message << "geom_data_pt[0] should have 2 values, not "
664  << geom_data_pt[0]->nvalue() << std::endl;
665  }
666 
667  throw OomphLibError(error_message.str(),
668  OOMPH_CURRENT_FUNCTION,
669  OOMPH_EXCEPTION_LOCATION);
670  }
671 #endif
672  Geom_data_pt.resize(1);
673  Geom_data_pt[0] = geom_data_pt[0];
674 
675  // Data has been created externally: Must not clean up
676  Must_clean_up = false;
677  }
678 
679 
680  /// Constructor: 1 Lagrangian coordinate, 2 Eulerian coords. Pass
681  /// half axes A and B; both pinned.
682  Ellipse(const double& A, const double& B) : GeomObject(1, 2)
683  {
684  // Resize Data for ellipse object:
685  Geom_data_pt.resize(1);
686 
687  // Create data: Two values, no timedependence, free by default
688  Geom_data_pt[0] = new Data(2);
689 
690  // I've created the data, I need to clean up
691  Must_clean_up = true;
692 
693  // Pin the data
694  Geom_data_pt[0]->pin(0);
695  Geom_data_pt[0]->pin(1);
696 
697  // Set half axes
698  Geom_data_pt[0]->set_value(0, A);
699  Geom_data_pt[0]->set_value(1, B);
700  }
701 
702  /// Broken copy constructor
703  Ellipse(const Ellipse& dummy) = delete;
704 
705  /// Broken assignment operator
706  void operator=(const Ellipse&) = delete;
707 
708  /// Destructor: Clean up if necessary
710  {
711  // Do I need to clean up?
712  if (Must_clean_up)
713  {
714  delete Geom_data_pt[0];
715  Geom_data_pt[0] = 0;
716  }
717  }
718 
719  /// Set horizontal half axis
720  void set_A_ellips(const double& a)
721  {
722  Geom_data_pt[0]->set_value(0, a);
723  }
724 
725  /// Set vertical half axis
726  void set_B_ellips(const double& b)
727  {
728  Geom_data_pt[0]->set_value(1, b);
729  }
730 
731  /// Access function for horizontal half axis
732  double a_ellips()
733  {
734  return Geom_data_pt[0]->value(0);
735  }
736 
737  /// Access function for vertical half axis
738  double b_ellips()
739  {
740  return Geom_data_pt[0]->value(1);
741  }
742 
743 
744  /// Position Vector at Lagrangian coordinate zeta
745  void position(const Vector<double>& zeta, Vector<double>& r) const
746  {
747  // Position Vector
748  r[0] = Geom_data_pt[0]->value(0) * cos(zeta[0]);
749  r[1] = Geom_data_pt[0]->value(1) * sin(zeta[0]);
750  }
751 
752 
753  /// Parametrised position on object: r(zeta). Evaluated at
754  /// previous timestep. t=0: current time; t>0: previous
755  /// timestep.
756  void position(const unsigned& t,
757  const Vector<double>& zeta,
758  Vector<double>& r) const
759  {
760  // If we have done the construction, it's a Steady Ellipse,
761  // so all time-history values of the position are equal to the position
762  if (Must_clean_up)
763  {
764  position(zeta, r);
765  return;
766  }
767 
768  // Otherwise check that the value of t is within range
769 #ifdef PARANOID
770  if (t > Geom_data_pt[0]->time_stepper_pt()->nprev_values())
771  {
772  std::ostringstream error_message;
773  error_message << "t > nprev_values() " << t << " "
774  << Geom_data_pt[0]->time_stepper_pt()->nprev_values()
775  << std::endl;
776 
777  throw OomphLibError(error_message.str(),
778  OOMPH_CURRENT_FUNCTION,
779  OOMPH_EXCEPTION_LOCATION);
780  }
781 #endif
782 
783  // Position Vector
784  r[0] = Geom_data_pt[0]->value(t, 0) * cos(zeta[0]);
785  r[1] = Geom_data_pt[0]->value(t, 1) * sin(zeta[0]);
786  }
787 
788 
789  /// Derivative of position Vector w.r.t. to coordinates:
790  /// \f$ \frac{dR_i}{d \zeta_\alpha}\f$ = drdzeta(alpha,i).
791  void dposition(const Vector<double>& zeta,
792  DenseMatrix<double>& drdzeta) const
793  {
794  // Components of the single tangent Vector
795  drdzeta(0, 0) = -Geom_data_pt[0]->value(0) * sin(zeta[0]);
796  drdzeta(0, 1) = Geom_data_pt[0]->value(1) * cos(zeta[0]);
797  }
798 
799 
800  /// 2nd derivative of position Vector w.r.t. to coordinates:
801  /// \f$ \frac{d^2R_i}{d \zeta_\alpha d \zeta_\beta}\f$ =
802  /// ddrdzeta(alpha,beta,i).
803  /// Evaluated at current time.
804  void d2position(const Vector<double>& zeta,
805  RankThreeTensor<double>& ddrdzeta) const
806  {
807  // Components of the derivative of the tangent Vector
808  ddrdzeta(0, 0, 0) = -Geom_data_pt[0]->value(0) * cos(zeta[0]);
809  ddrdzeta(0, 0, 1) = -Geom_data_pt[0]->value(1) * sin(zeta[0]);
810  }
811 
812  /// Position Vector and 1st and 2nd derivs to coordinates:
813  /// \f$ \frac{dR_i}{d \zeta_\alpha}\f$ = drdzeta(alpha,i).
814  /// \f$ \frac{d^2R_i}{d \zeta_\alpha d \zeta_\beta}\f$ =
815  /// ddrdzeta(alpha,beta,i).
816  /// Evaluated at current time.
817  void d2position(const Vector<double>& zeta,
818  Vector<double>& r,
819  DenseMatrix<double>& drdzeta,
820  RankThreeTensor<double>& ddrdzeta) const
821  {
822  double a = Geom_data_pt[0]->value(0);
823  double b = Geom_data_pt[0]->value(1);
824  // Position Vector
825  r[0] = a * cos(zeta[0]);
826  r[1] = b * sin(zeta[0]);
827 
828  // Components of the single tangent Vector
829  drdzeta(0, 0) = -a * sin(zeta[0]);
830  drdzeta(0, 1) = b * cos(zeta[0]);
831 
832  // Components of the derivative of the tangent Vector
833  ddrdzeta(0, 0, 0) = -a * cos(zeta[0]);
834  ddrdzeta(0, 0, 1) = -b * sin(zeta[0]);
835  }
836 
837 
838  /// How many items of Data does the shape of the object depend on?
839  unsigned ngeom_data() const
840  {
841  return Geom_data_pt.size();
842  }
843 
844  /// Return pointer to the j-th Data item that the object's
845  /// shape depends on
846  Data* geom_data_pt(const unsigned& j)
847  {
848  return Geom_data_pt[j];
849  }
850 
851  private:
852  /// Vector of pointers to Data items that affects the object's shape
854 
855  /// Do I need to clean up?
857  };
858 
859 
860  /// ////////////////////////////////////////////////////////////////////
861  /// ////////////////////////////////////////////////////////////////////
862  // Circle as geometric object
863  /// ////////////////////////////////////////////////////////////////////
864  /// ////////////////////////////////////////////////////////////////////
865 
866 
867  //=========================================================================
868  /// Circle in 2D space.
869  /// \f[ x = X_c + R \cos(\zeta) \f]
870  /// \f[ y = Y_c + R \sin(\zeta) \f]
871  //=========================================================================
872  class Circle : public GeomObject
873  {
874  public:
875  /// Constructor: Pass x and y-coords of centre and radius (all pinned)
876  Circle(const double& x_c, const double& y_c, const double& r)
877  : GeomObject(1, 2)
878  {
879  // Create Data:
880  Geom_data_pt.resize(1);
881  Geom_data_pt[0] = new Data(3);
882 
883  // No time-dependence
884  Is_time_dependent = false;
885 
886  // Assign data: X_c; no timedependence, free by default
887 
888  // Pin the data
889  Geom_data_pt[0]->pin(0);
890  // Give it a value:
891  Geom_data_pt[0]->set_value(0, x_c);
892 
893  // Assign data: Y_c; no timedependence, free by default
894 
895  // Pin the data
896  Geom_data_pt[0]->pin(1);
897  // Give it a value:
898  Geom_data_pt[0]->set_value(1, y_c);
899 
900  // Assign data: R; no timedependence, free by default
901 
902  // Pin the data
903  Geom_data_pt[0]->pin(2);
904  // Give it a value:
905  Geom_data_pt[0]->set_value(2, r);
906 
907  // I've created the data, I need to clean up
908  Must_clean_up = true;
909  }
910 
911 
912  /// Constructor: Pass x and y-coords of centre and radius (all
913  /// pinned) Circle is static but can be used in time-dependent runs with
914  /// specified timestepper.
915  Circle(const double& x_c,
916  const double& y_c,
917  const double& r,
919  : GeomObject(1, 2, time_stepper_pt)
920  {
921  // Create Data:
922  Geom_data_pt.resize(1);
923  Geom_data_pt[0] = new Data(time_stepper_pt, 3);
924 
925  // We have time-dependence
926  Is_time_dependent = true;
927 
928  // Assign data: X_c; no timedependence, free by default
929 
930  // Pin the data
931  Geom_data_pt[0]->pin(0);
932  // Give it a value:
933  Geom_data_pt[0]->set_value(0, x_c);
934 
935  // Assign data: Y_c; no timedependence, free by default
936 
937  // Pin the data
938  Geom_data_pt[0]->pin(1);
939  // Give it a value:
940  Geom_data_pt[0]->set_value(1, y_c);
941 
942  // Assign data: R; no timedependence, free by default
943 
944  // Pin the data
945  Geom_data_pt[0]->pin(2);
946  // Give it a value:
947  Geom_data_pt[0]->set_value(2, r);
948 
949  // "Impulsive" start because there isn't any time-dependence
951 
952  // I've created the data, I need to clean up
953  Must_clean_up = true;
954  }
955 
956 
957  /// Constructor: Pass x and y-coords of centre and radius
958  /// (all as Data)
959  /// \code
960  /// Geom_data_pt[0]->value(0) = X_c;
961  /// Geom_data_pt[0]->value(1) = Y_c;
962  /// Geom_data_pt[0]->value(2) = R;
963  /// \endcode
965  {
966 #ifdef PARANOID
967  if (geom_data_pt.size() != 1)
968  {
969  std::ostringstream error_message;
970  error_message << "geom_data_pt should have size 1, not "
971  << geom_data_pt.size() << std::endl;
972 
973  if (geom_data_pt[0]->nvalue() != 3)
974  {
975  error_message << "geom_data_pt[0] should have 3 values, not "
976  << geom_data_pt[0]->nvalue() << std::endl;
977  }
978 
979  throw OomphLibError(error_message.str(),
980  OOMPH_CURRENT_FUNCTION,
981  OOMPH_EXCEPTION_LOCATION);
982  }
983 #endif
984 
985  // We have time-dependence
986  if (geom_data_pt[0]->time_stepper_pt()->nprev_values() > 0)
987  {
988  Is_time_dependent = true;
989  }
990  else
991  {
992  Is_time_dependent = false;
993  }
994 
995  Geom_data_pt.resize(1);
996  Geom_data_pt[0] = geom_data_pt[0];
997 
998  // Data has been created externally: Must not clean up
999  Must_clean_up = false;
1000  }
1001 
1002  /// Broken copy constructor
1003  Circle(const Circle& dummy) = delete;
1004 
1005  /// Broken assignment operator
1006  void operator=(const Circle&) = delete;
1007 
1008  /// Destructor: Clean up if necessary
1009  virtual ~Circle()
1010  {
1011  // Do I need to clean up?
1012  if (Must_clean_up)
1013  {
1014  unsigned ngeom_data = Geom_data_pt.size();
1015  for (unsigned i = 0; i < ngeom_data; i++)
1016  {
1017  delete Geom_data_pt[i];
1018  Geom_data_pt[i] = 0;
1019  }
1020  }
1021  }
1022 
1023  /// Position Vector at Lagrangian coordinate zeta
1024  void position(const Vector<double>& zeta, Vector<double>& r) const
1025  {
1026  // Extract data
1027  double X_c = Geom_data_pt[0]->value(0);
1028  double Y_c = Geom_data_pt[0]->value(1);
1029  double R = Geom_data_pt[0]->value(2);
1030 
1031  // Position Vector
1032  r[0] = X_c + R * cos(zeta[0]);
1033  r[1] = Y_c + R * sin(zeta[0]);
1034  }
1035 
1036 
1037  /// Parametrised position on object: r(zeta). Evaluated at
1038  /// previous timestep. t=0: current time; t>0: previous
1039  /// timestep.
1040  void position(const unsigned& t,
1041  const Vector<double>& zeta,
1042  Vector<double>& r) const
1043  {
1044  // Genuine time-dependence?
1045  if (!Is_time_dependent)
1046  {
1047  position(zeta, r);
1048  }
1049  else
1050  {
1051 #ifdef PARANOID
1052  if (t > Geom_data_pt[0]->time_stepper_pt()->nprev_values())
1053  {
1054  std::ostringstream error_message;
1055  error_message << "t > nprev_values() " << t << " "
1056  << Geom_data_pt[0]->time_stepper_pt()->nprev_values()
1057  << std::endl;
1058 
1059  throw OomphLibError(error_message.str(),
1060  OOMPH_CURRENT_FUNCTION,
1061  OOMPH_EXCEPTION_LOCATION);
1062  }
1063 #endif
1064 
1065  // Extract data
1066  double X_c = Geom_data_pt[0]->value(t, 0);
1067  double Y_c = Geom_data_pt[0]->value(t, 1);
1068  double R = Geom_data_pt[0]->value(t, 2);
1069 
1070  // Position Vector
1071  r[0] = X_c + R * cos(zeta[0]);
1072  r[1] = Y_c + R * sin(zeta[0]);
1073  }
1074  }
1075 
1076  /// Access function to x-coordinate of centre of circle
1077  double& x_c()
1078  {
1079  return *Geom_data_pt[0]->value_pt(0);
1080  }
1081 
1082  /// Access function to y-coordinate of centre of circle
1083  double& y_c()
1084  {
1085  return *Geom_data_pt[0]->value_pt(1);
1086  }
1087 
1088  /// Access function to radius of circle
1089  double& R()
1090  {
1091  return *Geom_data_pt[0]->value_pt(2);
1092  }
1093 
1094  /// How many items of Data does the shape of the object depend on?
1095  unsigned ngeom_data() const
1096  {
1097  return Geom_data_pt.size();
1098  }
1099 
1100  /// Return pointer to the j-th Data item that the object's
1101  /// shape depends on
1102  Data* geom_data_pt(const unsigned& j)
1103  {
1104  return Geom_data_pt[j];
1105  }
1106 
1107  protected:
1108  /// Vector of pointers to Data items that affects the object's shape
1110 
1111  /// Do I need to clean up?
1113 
1114  /// Genuine time-dependence?
1116  };
1117 
1118 
1119  /// ////////////////////////////////////////////////////////////////////
1120  /// ////////////////////////////////////////////////////////////////////
1121  /// ////////////////////////////////////////////////////////////////////
1122 
1123 
1124  //===========================================================
1125  /// Elliptical tube with half axes a and b.
1126  ///
1127  /// \f[ {\bf r} = ( a \cos(\zeta_1), b \sin(zeta_1), \zeta_0)^T \f]
1128  ///
1129  //===========================================================
1131  {
1132  public:
1133  /// Constructor: Specify radius
1134  EllipticalTube(const double& a, const double& b)
1135  : GeomObject(2, 3), A(a), B(b)
1136  {
1137  }
1138 
1139  /// Broken copy constructor
1140  EllipticalTube(const EllipticalTube& node) = delete;
1141 
1142  /// Broken assignment operator
1143  void operator=(const EllipticalTube&) = delete;
1144 
1145  /// Access function to x-half axis
1146  double& a()
1147  {
1148  return A;
1149  }
1150 
1151  /// Access function to y-half axis
1152  double& b()
1153  {
1154  return B;
1155  }
1156 
1157  /// Position vector
1158  void position(const Vector<double>& zeta, Vector<double>& r) const
1159  {
1160  r[0] = A * cos(zeta[1]);
1161  r[1] = B * sin(zeta[1]);
1162  r[2] = zeta[0];
1163  }
1164 
1165 
1166  /// Position vector (dummy unsteady version returns steady version)
1167  void position(const unsigned& t,
1168  const Vector<double>& zeta,
1169  Vector<double>& r) const
1170  {
1171  position(zeta, r);
1172  }
1173 
1174  /// How many items of Data does the shape of the object depend on?
1175  virtual unsigned ngeom_data() const
1176  {
1177  return 0;
1178  }
1179 
1180  /// Position Vector and 1st and 2nd derivs w.r.t. zeta.
1181  void d2position(const Vector<double>& zeta,
1182  RankThreeTensor<double>& ddrdzeta) const
1183  {
1184  ddrdzeta(0, 0, 0) = 0.0;
1185  ddrdzeta(0, 0, 1) = 0.0;
1186  ddrdzeta(0, 0, 2) = 0.0;
1187 
1188  ddrdzeta(1, 1, 0) = -A * cos(zeta[1]);
1189  ddrdzeta(1, 1, 1) = -B * sin(zeta[1]);
1190  ddrdzeta(1, 1, 2) = 0.0;
1191 
1192  ddrdzeta(0, 1, 0) = ddrdzeta(1, 0, 0) = 0.0;
1193  ddrdzeta(0, 1, 1) = ddrdzeta(1, 0, 1) = 0.0;
1194  ddrdzeta(0, 1, 2) = ddrdzeta(1, 0, 2) = 0.0;
1195  }
1196 
1197  /// Position Vector and 1st and 2nd derivs w.r.t. zeta.
1198  void d2position(const Vector<double>& zeta,
1199  Vector<double>& r,
1200  DenseMatrix<double>& drdzeta,
1201  RankThreeTensor<double>& ddrdzeta) const
1202  {
1203  // Let's just do a simple tube
1204  r[0] = A * cos(zeta[1]);
1205  r[1] = B * sin(zeta[1]);
1206  r[2] = zeta[0];
1207 
1208  // Do the azetaal derivatives
1209  drdzeta(0, 0) = 0.0;
1210  drdzeta(0, 1) = 0.0;
1211  drdzeta(0, 2) = 1.0;
1212 
1213  // Do the azimuthal derivatives
1214  drdzeta(1, 0) = -A * sin(zeta[1]);
1215  drdzeta(1, 1) = B * cos(zeta[1]);
1216  drdzeta(1, 2) = 0.0;
1217 
1218  // Now let's do the second derivatives
1219  ddrdzeta(0, 0, 0) = 0.0;
1220  ddrdzeta(0, 0, 1) = 0.0;
1221  ddrdzeta(0, 0, 2) = 0.0;
1222 
1223  ddrdzeta(1, 1, 0) = -A * cos(zeta[1]);
1224  ddrdzeta(1, 1, 1) = -B * sin(zeta[1]);
1225  ddrdzeta(1, 1, 2) = 0.0;
1226 
1227  // Mixed derivatives
1228  ddrdzeta(0, 1, 0) = ddrdzeta(1, 0, 0) = 0.0;
1229  ddrdzeta(0, 1, 1) = ddrdzeta(1, 0, 1) = 0.0;
1230  ddrdzeta(0, 1, 2) = ddrdzeta(1, 0, 2) = 0.0;
1231  }
1232 
1233  private:
1234  /// x-half axis
1235  double A;
1236 
1237  /// x-half axis
1238  double B;
1239  };
1240 
1241 } // namespace oomph
1242 
1243 #endif
static char t char * s
Definition: cfortran.h:568
cstr elem_len * i
Definition: cfortran.h:603
char t
Definition: cfortran.h:568
////////////////////////////////////////////////////////////////////
Definition: geom_objects.h:873
double & y_c()
Access function to y-coordinate of centre of circle.
void operator=(const Circle &)=delete
Broken assignment operator.
Circle(const Circle &dummy)=delete
Broken copy constructor.
void position(const unsigned &t, const Vector< double > &zeta, Vector< double > &r) const
Parametrised position on object: r(zeta). Evaluated at previous timestep. t=0: current time; t>0: pre...
Circle(const double &x_c, const double &y_c, const double &r, TimeStepper *time_stepper_pt)
Constructor: Pass x and y-coords of centre and radius (all pinned) Circle is static but can be used i...
Definition: geom_objects.h:915
virtual ~Circle()
Destructor: Clean up if necessary.
Vector< Data * > Geom_data_pt
Vector of pointers to Data items that affects the object's shape.
unsigned ngeom_data() const
How many items of Data does the shape of the object depend on?
bool Must_clean_up
Do I need to clean up?
double & x_c()
Access function to x-coordinate of centre of circle.
bool Is_time_dependent
Genuine time-dependence?
void position(const Vector< double > &zeta, Vector< double > &r) const
Position Vector at Lagrangian coordinate zeta.
Data * geom_data_pt(const unsigned &j)
Return pointer to the j-th Data item that the object's shape depends on.
Circle(const Vector< Data * > &geom_data_pt)
Constructor: Pass x and y-coords of centre and radius (all as Data)
Definition: geom_objects.h:964
Circle(const double &x_c, const double &y_c, const double &r)
Constructor: Pass x and y-coords of centre and radius (all pinned)
Definition: geom_objects.h:876
double & R()
Access function to radius of circle.
A class that represents a collection of data; each Data object may contain many different individual ...
Definition: nodes.h:86
unsigned nvalue() const
Return number of values stored in data object (incl pinned ones).
Definition: nodes.h:483
////////////////////////////////////////////////////////////////////
Definition: geom_objects.h:644
void d2position(const Vector< double > &zeta, RankThreeTensor< double > &ddrdzeta) const
2nd derivative of position Vector w.r.t. to coordinates: = ddrdzeta(alpha,beta,i)....
Definition: geom_objects.h:804
Ellipse(const double &A, const double &B)
Constructor: 1 Lagrangian coordinate, 2 Eulerian coords. Pass half axes A and B; both pinned.
Definition: geom_objects.h:682
Ellipse(const Vector< Data * > &geom_data_pt)
Constructor: 1 Lagrangian coordinate, 2 Eulerian coords. Pass half axes as Data:
Definition: geom_objects.h:652
void d2position(const Vector< double > &zeta, Vector< double > &r, DenseMatrix< double > &drdzeta, RankThreeTensor< double > &ddrdzeta) const
Position Vector and 1st and 2nd derivs to coordinates: = drdzeta(alpha,i). = ddrdzeta(alpha,...
Definition: geom_objects.h:817
void operator=(const Ellipse &)=delete
Broken assignment operator.
void set_A_ellips(const double &a)
Set horizontal half axis.
Definition: geom_objects.h:720
Ellipse(const Ellipse &dummy)=delete
Broken copy constructor.
unsigned ngeom_data() const
How many items of Data does the shape of the object depend on?
Definition: geom_objects.h:839
void position(const unsigned &t, const Vector< double > &zeta, Vector< double > &r) const
Parametrised position on object: r(zeta). Evaluated at previous timestep. t=0: current time; t>0: pre...
Definition: geom_objects.h:756
void set_B_ellips(const double &b)
Set vertical half axis.
Definition: geom_objects.h:726
Data * geom_data_pt(const unsigned &j)
Return pointer to the j-th Data item that the object's shape depends on.
Definition: geom_objects.h:846
double b_ellips()
Access function for vertical half axis.
Definition: geom_objects.h:738
void position(const Vector< double > &zeta, Vector< double > &r) const
Position Vector at Lagrangian coordinate zeta.
Definition: geom_objects.h:745
~Ellipse()
Destructor: Clean up if necessary.
Definition: geom_objects.h:709
bool Must_clean_up
Do I need to clean up?
Definition: geom_objects.h:856
double a_ellips()
Access function for horizontal half axis.
Definition: geom_objects.h:732
Vector< Data * > Geom_data_pt
Vector of pointers to Data items that affects the object's shape.
Definition: geom_objects.h:853
void dposition(const Vector< double > &zeta, DenseMatrix< double > &drdzeta) const
Derivative of position Vector w.r.t. to coordinates: = drdzeta(alpha,i).
Definition: geom_objects.h:791
//////////////////////////////////////////////////////////////////// ////////////////////////////////...
void position(const unsigned &t, const Vector< double > &zeta, Vector< double > &r) const
Position vector (dummy unsteady version returns steady version)
double B
x-half axis
EllipticalTube(const EllipticalTube &node)=delete
Broken copy constructor.
void operator=(const EllipticalTube &)=delete
Broken assignment operator.
void d2position(const Vector< double > &zeta, Vector< double > &r, DenseMatrix< double > &drdzeta, RankThreeTensor< double > &ddrdzeta) const
Position Vector and 1st and 2nd derivs w.r.t. zeta.
double & a()
Access function to x-half axis.
EllipticalTube(const double &a, const double &b)
Constructor: Specify radius.
double A
x-half axis
double & b()
Access function to y-half axis.
void d2position(const Vector< double > &zeta, RankThreeTensor< double > &ddrdzeta) const
Position Vector and 1st and 2nd derivs w.r.t. zeta.
virtual unsigned ngeom_data() const
How many items of Data does the shape of the object depend on?
void position(const Vector< double > &zeta, Vector< double > &r) const
Position vector.
/////////////////////////////////////////////////////////////////////
Definition: geom_objects.h:101
TimeStepper * time_stepper_pt() const
Access function for pointer to time stepper: Null if object is not time-dependent....
Definition: geom_objects.h:199
unsigned ndim() const
Access function to # of Eulerian coordinates.
Definition: geom_objects.h:177
virtual void d2position(const Vector< double > &zeta, RankThreeTensor< double > &ddrdzeta) const
2nd derivative of position Vector w.r.t. to coordinates: = ddrdzeta(alpha,beta,i)....
Definition: geom_objects.h:341
virtual void position(const Vector< double > &zeta, Vector< double > &r) const =0
Parametrised position on object at current time: r(zeta).
unsigned NLagrangian
Number of Lagrangian (intrinsic) coordinates.
Definition: geom_objects.h:428
TimeStepper * Geom_object_time_stepper_pt
Timestepper (used to handle access to geometry at previous timesteps)
Definition: geom_objects.h:435
virtual unsigned ngeom_data() const
How many items of Data does the shape of the object depend on? This is implemented as a broken virtua...
Definition: geom_objects.h:209
virtual void interpolated_zeta(const Vector< double > &s, Vector< double > &zeta) const
A geometric object may be composed of many sub-objects each with their own local coordinate....
Definition: geom_objects.h:404
void set_nlagrangian_and_ndim(const unsigned &n_lagrangian, const unsigned &n_dim)
Set # of Lagrangian and Eulerian coordinates.
Definition: geom_objects.h:183
TimeStepper *& time_stepper_pt()
Access function for pointer to time stepper: Null if object is not time-dependent.
Definition: geom_objects.h:192
virtual void d2position(const Vector< double > &zeta, Vector< double > &r, DenseMatrix< double > &drdzeta, RankThreeTensor< double > &ddrdzeta) const
Posn Vector and its 1st & 2nd derivatives w.r.t. to coordinates: = drdzeta(alpha,...
Definition: geom_objects.h:357
void operator=(const GeomObject &)=delete
Broken assignment operator.
GeomObject(const unsigned &ndim)
Constructor: Pass dimension of geometric object (# of Eulerian coords = # of Lagrangian coords; no ti...
Definition: geom_objects.h:108
unsigned Ndim
Number of Eulerian coordinates.
Definition: geom_objects.h:431
GeomObject(const unsigned &nlagrangian, const unsigned &ndim, TimeStepper *time_stepper_pt)
Constructor: pass # of Eulerian and Lagrangian coordinates and pointer to time-stepper which is used ...
Definition: geom_objects.h:139
virtual void locate_zeta(const Vector< double > &zeta, GeomObject *&sub_geom_object_pt, Vector< double > &s, const bool &use_coordinate_as_initial_guess=false)
A geometric object may be composed of may sub-objects (e.g. a finite-element representation of a boun...
Definition: geom_objects.h:381
virtual void dposition(const Vector< double > &zeta, DenseMatrix< double > &drdzeta) const
Derivative of position Vector w.r.t. to coordinates: = drdzeta(alpha,i). Evaluated at current time.
Definition: geom_objects.h:327
virtual void dposition_dt(const Vector< double > &zeta, const unsigned &j, Vector< double > &drdt)
j-th time-derivative on object at current time: .
Definition: geom_objects.h:292
virtual ~GeomObject()
(Empty) destructor
Definition: geom_objects.h:168
virtual void position(const unsigned &t, const Vector< double > &zeta, Vector< double > &r) const
Parametrised position on object: r(zeta). Evaluated at previous timestep. t=0: current time; t>0: pre...
Definition: geom_objects.h:259
virtual Data * geom_data_pt(const unsigned &j)
Return pointer to the j-th Data item that the object's shape depends on. This is implemented as a bro...
Definition: geom_objects.h:233
GeomObject(const unsigned &nlagrangian, const unsigned &ndim)
Constructor: pass # of Eulerian and Lagrangian coordinates. No time history available/needed.
Definition: geom_objects.h:116
unsigned nlagrangian() const
Access function to # of Lagrangian coordinates.
Definition: geom_objects.h:171
virtual void position(const double &t, const Vector< double > &zeta, Vector< double > &r) const
Parametrised position on object: r(zeta). Evaluated at the continuous time value, t.
Definition: geom_objects.h:276
GeomObject(const GeomObject &dummy)=delete
Broken copy constructor.
GeomObject()
Default constructor.
Definition: geom_objects.h:104
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....
////////////////////////////////////////////////////////////////// //////////////////////////////////...
Definition: matrices.h:1370
////////////////////////////////////////////////////////////////////
Definition: geom_objects.h:452
virtual void dposition(const Vector< double > &zeta, DenseMatrix< double > &drdzeta) const
Derivative of position Vector w.r.t. to coordinates: = drdzeta(alpha,i). Evaluated at current time.
Definition: geom_objects.h:563
StraightLine(const StraightLine &dummy)=delete
Broken copy constructor.
StraightLine(const Vector< Data * > &geom_data_pt)
Constructor: One item of geometric data:
Definition: geom_objects.h:458
~StraightLine()
Destructor: Clean up if necessary.
Definition: geom_objects.h:513
Vector< Data * > Geom_data_pt
Vector of pointers to Data items that affects the object's shape.
Definition: geom_objects.h:624
StraightLine(const double &height)
Constructor: Pass height (pinned by default)
Definition: geom_objects.h:486
bool Must_clean_up
Do I need to clean up?
Definition: geom_objects.h:627
void position(const Vector< double > &zeta, Vector< double > &r) const
Position Vector at Lagrangian coordinate zeta.
Definition: geom_objects.h:525
virtual void d2position(const Vector< double > &zeta, Vector< double > &r, DenseMatrix< double > &drdzeta, RankThreeTensor< double > &ddrdzeta) const
Posn Vector and its 1st & 2nd derivatives w.r.t. to coordinates: = drdzeta(alpha,...
Definition: geom_objects.h:590
unsigned ngeom_data() const
How many items of Data does the shape of the object depend on?
Definition: geom_objects.h:610
Data * geom_data_pt(const unsigned &j)
Return pointer to the j-th Data item that the object's shape depends on.
Definition: geom_objects.h:617
virtual void d2position(const Vector< double > &zeta, RankThreeTensor< double > &ddrdzeta) const
2nd derivative of position Vector w.r.t. to coordinates: = ddrdzeta(alpha,beta,i)....
Definition: geom_objects.h:575
void operator=(const StraightLine &)=delete
Broken assignment operator.
void position(const unsigned &t, const Vector< double > &zeta, Vector< double > &r) const
Parametrised position on object: r(zeta). Evaluated at previous timestep. t=0: current time; t>0: pre...
Definition: geom_objects.h:536
////////////////////////////////////////////////////////////////////// //////////////////////////////...
Definition: timesteppers.h:231
virtual void assign_initial_values_impulsive(Data *const &data_pt)=0
Initialise the time-history for the Data values corresponding to an impulsive start.
//////////////////////////////////////////////////////////////////// ////////////////////////////////...