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-2022 Matthias Heil and Andrew Hazel
7 // LIC//
8 // LIC// This library is free software; you can redistribute it and/or
9 // LIC// modify it under the terms of the GNU Lesser General Public
10 // LIC// License as published by the Free Software Foundation; either
11 // LIC// version 2.1 of the License, or (at your option) any later version.
12 // LIC//
13 // LIC// This library is distributed in the hope that it will be useful,
14 // LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // LIC// Lesser General Public License for more details.
17 // LIC//
18 // LIC// You should have received a copy of the GNU Lesser General Public
19 // LIC// License along with this library; if not, write to the Free Software
20 // LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 // LIC// 02110-1301 USA.
22 // LIC//
23 // LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
24 // LIC//
25 // LIC//====================================================================
26 #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 {
44  // Geometric object
47 
48 
49  //========================================================================
99  //========================================================================
101  {
102  public:
105 
108  GeomObject(const unsigned& ndim)
110  {
111  }
112 
113 
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(),
130  }
131 #endif
132  }
133 
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(),
157  }
158 #endif
159  }
160 
162  GeomObject(const GeomObject& dummy) = delete;
163 
165  void operator=(const GeomObject&) = delete;
166 
168  virtual ~GeomObject() {}
169 
171  unsigned nlagrangian() const
172  {
173  return NLagrangian;
174  }
175 
177  unsigned ndim() const
178  {
179  return Ndim;
180  }
181 
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 
193  {
195  }
196 
200  {
202  }
203 
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 
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 
252  virtual void position(const Vector<double>& zeta,
253  Vector<double>& r) const = 0;
254 
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()",
269  }
270  position(zeta, r);
271  }
272 
273 
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 
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()",
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 
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",
334  }
335 
336 
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",
348  }
349 
350 
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",
366  }
367 
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 
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(),
420  }
421 #endif
422  // By default the global intrinsic coordinate is equal to the local one
423  zeta = s;
424  }
425 
426  protected:
428  unsigned NLagrangian;
429 
431  unsigned Ndim;
432 
436  };
437 
438 
441  // Straight line as geometric object
444 
445 
446  //=========================================================================
450  //=========================================================================
451  class StraightLine : public GeomObject
452  {
453  public:
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(),
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 
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 
507  StraightLine(const StraightLine& dummy) = delete;
508 
510  void operator=(const StraightLine&) = delete;
511 
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 
526  {
527  // Position Vector
528  r[0] = zeta[0];
529  r[1] = Geom_data_pt[0]->value(0);
530  }
531 
532 
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(),
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 
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 
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 
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 
610  unsigned ngeom_data() const
611  {
612  return Geom_data_pt.size();
613  }
614 
617  Data* geom_data_pt(const unsigned& j)
618  {
619  return Geom_data_pt[j];
620  }
621 
622  private:
625 
628  };
629 
630 
633  // Ellipse as geometric object
636 
637 
638  //=========================================================================
642  //=========================================================================
643  class Ellipse : public GeomObject
644  {
645  public:
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(),
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 
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 
703  Ellipse(const Ellipse& dummy) = delete;
704 
706  void operator=(const Ellipse&) = delete;
707 
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 
720  void set_A_ellips(const double& a)
721  {
722  Geom_data_pt[0]->set_value(0, a);
723  }
724 
726  void set_B_ellips(const double& b)
727  {
728  Geom_data_pt[0]->set_value(1, b);
729  }
730 
732  double a_ellips()
733  {
734  return Geom_data_pt[0]->value(0);
735  }
736 
738  double b_ellips()
739  {
740  return Geom_data_pt[0]->value(1);
741  }
742 
743 
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 
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(),
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 
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 
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 
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 
839  unsigned ngeom_data() const
840  {
841  return Geom_data_pt.size();
842  }
843 
846  Data* geom_data_pt(const unsigned& j)
847  {
848  return Geom_data_pt[j];
849  }
850 
851  private:
854 
857  };
858 
859 
862  // Circle as geometric object
865 
866 
867  //=========================================================================
871  //=========================================================================
872  class Circle : public GeomObject
873  {
874  public:
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 
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 
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(),
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 
1003  Circle(const Circle& dummy) = delete;
1004 
1006  void operator=(const Circle&) = delete;
1007 
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 
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 
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(),
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 
1077  double& x_c()
1078  {
1079  return *Geom_data_pt[0]->value_pt(0);
1080  }
1081 
1083  double& y_c()
1084  {
1085  return *Geom_data_pt[0]->value_pt(1);
1086  }
1087 
1089  double& R()
1090  {
1091  return *Geom_data_pt[0]->value_pt(2);
1092  }
1093 
1095  unsigned ngeom_data() const
1096  {
1097  return Geom_data_pt.size();
1098  }
1099 
1102  Data* geom_data_pt(const unsigned& j)
1103  {
1104  return Geom_data_pt[j];
1105  }
1106 
1107  protected:
1110 
1113 
1116  };
1117 
1118 
1122 
1123 
1124  //===========================================================
1129  //===========================================================
1131  {
1132  public:
1134  EllipticalTube(const double& a, const double& b)
1135  : GeomObject(2, 3), A(a), B(b)
1136  {
1137  }
1138 
1140  EllipticalTube(const EllipticalTube& node) = delete;
1141 
1143  void operator=(const EllipticalTube&) = delete;
1144 
1146  double& a()
1147  {
1148  return A;
1149  }
1150 
1152  double& b()
1153  {
1154  return B;
1155  }
1156 
1159  {
1160  r[0] = A * cos(zeta[1]);
1161  r[1] = B * sin(zeta[1]);
1162  r[2] = zeta[0];
1163  }
1164 
1165 
1167  void position(const unsigned& t,
1168  const Vector<double>& zeta,
1169  Vector<double>& r) const
1170  {
1171  position(zeta, r);
1172  }
1173 
1175  virtual unsigned ngeom_data() const
1176  {
1177  return 0;
1178  }
1179 
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 
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:
1235  double A;
1236 
1238  double B;
1239  };
1240 
1241 } // namespace oomph
1242 
1243 #endif
AnnoyingScalar cos(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:136
AnnoyingScalar sin(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:137
int i
Definition: BiCGSTAB_step_by_step.cpp:9
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
Scalar * b
Definition: benchVecAdd.cpp:17
The matrix class, also used for vectors and row-vectors.
Definition: Eigen/Eigen/src/Core/Matrix.h:186
Definition: geom_objects.h:873
double & y_c()
Access function to y-coordinate of centre of circle.
Definition: geom_objects.h:1083
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
Definition: geom_objects.h:1040
Circle(const double &x_c, const double &y_c, const double &r, TimeStepper *time_stepper_pt)
Definition: geom_objects.h:915
virtual ~Circle()
Destructor: Clean up if necessary.
Definition: geom_objects.h:1009
Vector< Data * > Geom_data_pt
Vector of pointers to Data items that affects the object's shape.
Definition: geom_objects.h:1109
unsigned ngeom_data() const
How many items of Data does the shape of the object depend on?
Definition: geom_objects.h:1095
bool Must_clean_up
Do I need to clean up?
Definition: geom_objects.h:1112
double & x_c()
Access function to x-coordinate of centre of circle.
Definition: geom_objects.h:1077
bool Is_time_dependent
Genuine time-dependence?
Definition: geom_objects.h:1115
void position(const Vector< double > &zeta, Vector< double > &r) const
Position Vector at Lagrangian coordinate zeta.
Definition: geom_objects.h:1024
Data * geom_data_pt(const unsigned &j)
Definition: geom_objects.h:1102
Circle(const Vector< Data * > &geom_data_pt)
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.
Definition: geom_objects.h:1089
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
Definition: geom_objects.h:804
Ellipse(const double &A, const double &B)
Definition: geom_objects.h:682
Ellipse(const Vector< Data * > &geom_data_pt)
Definition: geom_objects.h:652
void d2position(const Vector< double > &zeta, Vector< double > &r, DenseMatrix< double > &drdzeta, RankThreeTensor< double > &ddrdzeta) const
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
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)
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
Definition: geom_objects.h:791
Definition: geom_objects.h:1131
void position(const unsigned &t, const Vector< double > &zeta, Vector< double > &r) const
Position vector (dummy unsteady version returns steady version)
Definition: geom_objects.h:1167
double B
x-half axis
Definition: geom_objects.h:1238
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.
Definition: geom_objects.h:1198
double & a()
Access function to x-half axis.
Definition: geom_objects.h:1146
EllipticalTube(const double &a, const double &b)
Constructor: Specify radius.
Definition: geom_objects.h:1134
double A
x-half axis
Definition: geom_objects.h:1235
double & b()
Access function to y-half axis.
Definition: geom_objects.h:1152
void d2position(const Vector< double > &zeta, RankThreeTensor< double > &ddrdzeta) const
Position Vector and 1st and 2nd derivs w.r.t. zeta.
Definition: geom_objects.h:1181
virtual unsigned ngeom_data() const
How many items of Data does the shape of the object depend on?
Definition: geom_objects.h:1175
void position(const Vector< double > &zeta, Vector< double > &r) const
Position vector.
Definition: geom_objects.h:1158
Definition: geom_objects.h:101
TimeStepper * time_stepper_pt() const
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
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
Definition: geom_objects.h:435
virtual unsigned ngeom_data() const
Definition: geom_objects.h:209
virtual void interpolated_zeta(const Vector< double > &s, Vector< double > &zeta) const
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()
Definition: geom_objects.h:192
virtual void d2position(const Vector< double > &zeta, Vector< double > &r, DenseMatrix< double > &drdzeta, RankThreeTensor< double > &ddrdzeta) const
Definition: geom_objects.h:357
void operator=(const GeomObject &)=delete
Broken assignment operator.
GeomObject(const unsigned &ndim)
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)
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)
Definition: geom_objects.h:381
virtual void dposition(const Vector< double > &zeta, DenseMatrix< double > &drdzeta) const
Definition: geom_objects.h:327
virtual void dposition_dt(const Vector< double > &zeta, const unsigned &j, Vector< double > &drdt)
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
Definition: geom_objects.h:259
virtual Data * geom_data_pt(const unsigned &j)
Definition: geom_objects.h:233
GeomObject(const unsigned &nlagrangian, const unsigned &ndim)
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
Definition: geom_objects.h:276
GeomObject(const GeomObject &dummy)=delete
Broken copy constructor.
GeomObject()
Default constructor.
Definition: geom_objects.h:104
Definition: matrices.h:74
Definition: oomph_definitions.h:222
Definition: oomph_definitions.h:267
A Rank 3 Tensor class.
Definition: matrices.h:1370
Definition: geom_objects.h:452
virtual void dposition(const Vector< double > &zeta, DenseMatrix< double > &drdzeta) const
Definition: geom_objects.h:563
StraightLine(const StraightLine &dummy)=delete
Broken copy constructor.
StraightLine(const Vector< Data * > &geom_data_pt)
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
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)
Definition: geom_objects.h:617
virtual void d2position(const Vector< double > &zeta, RankThreeTensor< double > &ddrdzeta) const
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
Definition: geom_objects.h:536
Definition: timesteppers.h:231
virtual void assign_initial_values_impulsive(Data *const &data_pt)=0
RealScalar s
Definition: level1_cplx_impl.h:130
const Scalar * a
Definition: level2_cplx_impl.h:32
EIGEN_STRONG_INLINE const Eigen::CwiseBinaryOp< Eigen::internal::scalar_zeta_op< typename DerivedX::Scalar >, const DerivedX, const DerivedQ > zeta(const Eigen::ArrayBase< DerivedX > &x, const Eigen::ArrayBase< DerivedQ > &q)
Definition: SpecialFunctionsArrayAPI.h:152
double height(const double &x)
Height of domain.
Definition: simple_spine_channel.cc:429
double Y_c
... OR THESE...
Definition: heated_linear_solid_contact_with_gravity.cc:2846
r
Definition: UniformPSDSelfTest.py:20
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).
Definition: AnisotropicHookean.h:10
t
Definition: plotPSD.py:36
#define OOMPH_EXCEPTION_LOCATION
Definition: oomph_definitions.h:61
#define OOMPH_CURRENT_FUNCTION
Definition: oomph_definitions.h:86
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2