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