spines.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-2023 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 // Header file for spine nodes, elements and meshes
27 
28 // Include guards to prevent multiple inclusion of the header
29 #ifndef OOMPH_SPINES_HEADER
30 #define OOMPH_SPINES_HEADER
31 
32 
33 #include <string>
34 
35 // oomph-lib headers
36 #include "nodes.h"
37 #include "elements.h"
38 #include "mesh.h"
39 #include "geom_objects.h"
41 
42 namespace oomph
43 {
44  //=================================================================
45  /// Spines are used for algebraic node update operations in free-surface
46  /// fluid problems: They form the back-bones along which nodes in a
47  /// a free-surface mesh are located. Typically, the free surface is
48  /// located at the "end" of the spine; the nodes in the interior
49  /// of the mesh are located at fixed fractions along the spine. The
50  /// key Data member of the Spine object is its "height" --
51  /// usually an unknown in the problem -- which is used by the
52  /// SpineNode's node update function to update the SpineNode's position.
53  ///
54  /// In more complex problems (such as the case where a fluid layer is
55  /// deposited on an elastic body), the node update function can depend on
56  /// additional information, such as the GeomObject representation of the
57  /// elastic body, and additional Data objects wich
58  /// specify the position on the GeomObject from which the Spine
59  /// emanates. The Spine class therefore provides storage for
60  /// pointers to GeomObjects and storage for any additional geometric
61  /// Data that may be required during node update operations.
62  //=================================================================
63  class Spine
64  {
65  public:
66  /// Default constructor: Create the Spine and initialise its
67  /// height to zero.
69  {
70  Geom_data_pt.resize(1);
71  // Create Data for height. By default it's free
72  Geom_data_pt[0] = new Data(1);
73  }
74 
75  /// Constructor: Create the Spine and initialise its
76  /// height to the specified value
77  Spine(const double& height)
78  {
79  Geom_data_pt.resize(1);
80  // Create Data for height. By default it's free
81  Geom_data_pt[0] = new Data(1);
82  // Set value
83  Geom_data_pt[0]->set_value(0, height);
84  }
85 
86  /// Constructor: Create the Spine and initialise its
87  /// height to the specified value. Store the vector of (pointers to)
88  /// the additional geometric Data that is required during
89  /// the node update operation for this Spine.
90  Spine(const double& height, const Vector<Data*>& geom_data_pt)
91  {
92  // Find the number of geometric data passed
93  const unsigned n_geom_data = geom_data_pt.size();
94  // Now allocate enough storage for the spine height and additional
95  // geometric data
96  Geom_data_pt.resize(n_geom_data + 1);
97 
98  // Create Data for height. By default it's free
99  Geom_data_pt[0] = new Data(1);
100  // Set value
101  Geom_data_pt[0]->set_value(0, height);
102  // Add the additional geometric data
103  for (unsigned i = 0; i < n_geom_data; i++)
104  {
105  Geom_data_pt[i + 1] = geom_data_pt[i];
106  }
107  }
108 
109  /// Constructor: Create the Spine and initialise its
110  /// height to the specified value. Store the vector of (pointers to)
111  /// the additional geometric Data that is required during
112  /// the node update operation; also store vector of (pointers to)
113  /// GeomObjects that is required during the node update operation
114  /// for this Spine
115  Spine(const double& height,
119  {
120  // Find the number of geometric data passed
121  const unsigned n_geom_data = geom_data_pt.size();
122  // Now allocate enough storage for the spine height and additional
123  // geometric data
124  Geom_data_pt.resize(n_geom_data + 1);
125 
126  // Create Data for height. By default it's free
127  Geom_data_pt[0] = new Data(1);
128  // Set value
129  Geom_data_pt[0]->set_value(0, height);
130  // Add the additional geometric data
131  for (unsigned i = 0; i < n_geom_data; i++)
132  {
133  Geom_data_pt[i + 1] = geom_data_pt[i];
134  }
135  }
136 
137 
138  /// Destructor: Wipe Data object that stores the
139  /// Spine height. All other objects (geometric Data and
140  /// geometric objects) were created outside the Spine
141  /// and must be deleted there.
143  {
144  // Kill spine height
145  delete Geom_data_pt[0];
146  }
147 
148 
149  /// Access function to spine height
150  double& height()
151  {
152  return *(Geom_data_pt[0]->value_pt(0));
153  }
154 
155  /// Access function to Data object that stores the spine height
157  {
158  return Geom_data_pt[0];
159  }
160 
161  /// Access function to Data object that stores the spine height
162  /// (const version)
164  {
165  return Geom_data_pt[0];
166  }
167 
168 
169  /// Number of geometric Data that is involved in the
170  /// node update operations for this Spine
171  unsigned ngeom_data()
172  {
173  return Geom_data_pt.size();
174  }
175 
176  /// Set vector of (pointers to) geometric Data that is
177  /// involved in the node update operations for this Spine.
178  /// Wipes any previously existing geometric Data.
180  {
181  unsigned n_geom_data = geom_data_pt.size();
182  Geom_data_pt.resize(n_geom_data + 1);
183  for (unsigned i = 1; i < n_geom_data; i++)
184  {
185  Geom_data_pt[i + 1] = geom_data_pt[i];
186  }
187  }
188 
189  /// Add (pointer to) geometric Data that is
190  /// involved in the node update operations for this Spine
192  {
193  Geom_data_pt.push_back(geom_data_pt);
194  }
195 
196  /// Return i-th geometric Data that is involved in the
197  /// node update operations for this Spine
198  Data*& geom_data_pt(const unsigned& i)
199  {
200  return Geom_data_pt[i];
201  }
202 
203  /// Return i-th geometric Data that is involved in the
204  /// node update operations for this Spine. Const version
205  Data* geom_data_pt(const unsigned& i) const
206  {
207  return Geom_data_pt[i];
208  }
209 
210  /// Return the vector of geometric data
212  {
213  return Geom_data_pt;
214  }
215 
216  /// Number of geometric objects that is involved in the
217  /// node update operations for this Spine
218  unsigned ngeom_object()
219  {
220  return Geom_object_pt.size();
221  }
222 
223  /// Set vector of (pointers to) geometric objects that is
224  /// involved in the node update operations for this Spine
226  {
227  unsigned n_geom_object = geom_object_pt.size();
228  Geom_object_pt.resize(n_geom_object);
229  for (unsigned i = 0; i < n_geom_object; i++)
230  {
232  }
233  }
234 
235  /// Add (pointer to) geometric object that is
236  /// involved in the node update operations for this Spine
238  {
239  Geom_object_pt.push_back(geom_object_pt);
240  }
241 
242  /// Return i-th geometric object that is involved in the
243  /// node update operations for this Spine
244  GeomObject*& geom_object_pt(const unsigned& i)
245  {
246  return Geom_object_pt[i];
247  }
248 
249  /// Return i-th geometric object that is involved in the
250  /// node update operations for this Spine. Const version
251  GeomObject* geom_object_pt(const unsigned& i) const
252  {
253  return Geom_object_pt[i];
254  }
255 
256  /// Return the vector of all geometric objects that affect this
257  /// spine
259  {
260  return Geom_object_pt;
261  }
262 
263  /// Number of geometric parameters that are involved in the
264  /// node update operations for this Spine
265  unsigned ngeom_parameter()
266  {
267  return Geom_parameter.size();
268  }
269 
270  /// Set vector of geometric parameters that are
271  /// involved in the node update operations for this Spine.
272  /// Wipes any previously existing geometric parameters
274  {
276  }
277 
278  /// Add geometric parameter
279  /// involved in the node update operations for this Spine
280  void add_geom_parameter(const double& geom_parameter)
281  {
282  Geom_parameter.push_back(geom_parameter);
283  }
284 
285  /// Return i-th geometric parameter that is involved in the
286  /// node update operations for this Spine
287  double& geom_parameter(const unsigned& i)
288  {
289  return Geom_parameter[i];
290  }
291 
292  /// Return i-th geometric parameter that is involved in the
293  /// node update operations for this Spine. Const version
294  const double& geom_parameter(const unsigned& i) const
295  {
296  return Geom_parameter[i];
297  }
298 
299 
300  private:
301  /// Data that stores the spine height
302  // Data* Spine_height_pt;
303 
304  /// Vector that stores the pointers to additional geometric Data
306 
307  /// Vector that stores the pointers to geometric objects that is
308  /// involved in the node update operation
310 
311  /// Vector that stores doubles that are used in the geometric updates
313  };
314 
315 
316  // Forward declaration
317  class SpineMesh;
318 
319 
320  //=====================================================================
321  /// Class for nodes that live on spines. The assumption is that each Node
322  /// lies at a fixed fraction on a single spine (although more complex
323  /// behaviour could be included by adding more variables to the spine).
324  /// In general, more complex node updating should be handled by the classes
325  /// implemented for algebraic node updates.
326  //=====================================================================
327  class SpineNode : public Node
328  {
329  private:
330  /// Private internal data pointer to a spine
332 
333  /// Private double that represents the fixed fraction along the spine
334  double Fraction;
335 
336  /// Pointer to SpineMesh that this node is a part of.
337  /// (The mesh implements the node update function(s))
339 
340  /// ID of node update function (within specific mesh -- useful if there
341  /// are multiple node update functions, e.g. in two-layer problems.
343 
344 
345  public:
346  /// Steady Constructor, initialise pointers to zero
347  SpineNode(const unsigned& n_dim,
348  const unsigned& n_position_type,
349  const unsigned& initial_nvalue)
350  : Node(n_dim, n_position_type, initial_nvalue),
351  Spine_pt(0),
352  Fraction(0),
353  Spine_mesh_pt(0),
355  {
356  }
357 
358  /// Unsteady Constructor, initialise pointers to zero
360  const unsigned& n_dim,
361  const unsigned& n_position_type,
362  const unsigned& initial_nvalue)
363  : Node(time_stepper_pt, n_dim, n_position_type, initial_nvalue),
364  Spine_pt(0),
365  Fraction(0),
366  Spine_mesh_pt(0),
368  {
369  }
370 
371  /// Access function to spine
373  {
374  return Spine_pt;
375  }
376 
377  /// Set reference to fraction along spine
378  double& fraction()
379  {
380  return Fraction;
381  }
382 
383  /// Access function to ID of node update function (within specific mesh)
384  unsigned& node_update_fct_id()
385  {
386  return Node_update_fct_id;
387  }
388 
389  /// Access function to Pointer to SpineMesh that this node is a part
390  /// of and which implements the node update function(s)
392  {
393  return Spine_mesh_pt;
394  }
395 
396  /// Access function to spine height
397  double& h()
398  {
399  return Spine_pt->height();
400  }
401 
402  /// Overload thet node update function, call
403  /// the update function in the Node's SpineMesh
404  void node_update(const bool& update_all_time_levels_for_new_node = false);
405 
406  /// Return the number of geometric data, zero if no spine.
407  unsigned ngeom_data() const
408  {
409  if (Spine_pt)
410  {
411  return Spine_pt->ngeom_data();
412  }
413  else
414  {
415  return 0;
416  }
417  }
418 
419  /// Return the number of geometric objects, zero if no spine.
420  unsigned ngeom_object() const
421  {
422  if (Spine_pt)
423  {
424  return Spine_pt->ngeom_object();
425  }
426  else
427  {
428  return 0;
429  }
430  }
431 
432  /// Return the vector of all geometric data
434  {
435  return &(Spine_pt->geom_data_pt(0));
436  }
437 
438  /// Return the vector of all geometric objects
440  {
441  return &(Spine_pt->geom_object_pt(0));
442  }
443  };
444 
445 
446  /// ////////////////////////////////////////////////////////////////////
447  /// ////////////////////////////////////////////////////////////////////
448  /// ////////////////////////////////////////////////////////////////////
449 
450 
451  //=======================================================================
452  /// A policy class that serves only to establish the interface for
453  /// assigning the spine equation numbers
454  //=======================================================================
456  {
457  public:
458  /// Empty constructor
460 
461  /// Emtpty virtual destructor
462  virtual ~SpineFiniteElement() {}
463  };
464 
465 
466  //========================================================================
467  /// The SpineElement<ELEMENT> class takes an existing element as a
468  /// template parameter and adds the necessary additional functionality to
469  /// allow the element to be update using the Method of Spines.
470  /// A vector of pointers to spines and storage for the local equation
471  /// numbers associated with the spines are added to the element.
472  //========================================================================
473  template<class ELEMENT>
475  : public ElementWithSpecificMovingNodes<ELEMENT, SpineNode>,
476  public SpineFiniteElement
477  {
478  private:
479  /// Array to hold the index of the geometric data associated with
480  /// the spine height of the spine that affects the n-th node
482 
483  /// Complete the setup of additional dependencies. Overloads
484  /// empty virtual function in GeneralisedElement to determine the "geometric
485  /// Data", i.e. the Data that affects the element's shape.
486  /// This function is called (for all elements) at the very beginning of the
487  /// equation numbering procedure to ensure that all dependencies
488  /// are accounted for.
490 
491 
492  public:
493  /// Constructor, call the constructor of the base element
498  {
499  }
500 
501  /// Constructor used for spine face elements
502  SpineElement(FiniteElement* const& element_pt, const int& face_index)
503  : ElementWithSpecificMovingNodes<ELEMENT, SpineNode>(element_pt,
504  face_index),
507  {
508  }
509 
510  /// Destructor, clean up the storage allocated to the local equation numbers
512  {
514  {
515  delete[] Spine_geometric_index;
516  }
517  }
518 
519  /// Return the local equation number corresponding to the height
520  /// of the spine at the n-th node
521  inline int spine_local_eqn(const unsigned& n)
522  {
523 #ifdef RANGE_CHECKING
524  const unsigned n_node = this->nnode();
525  if (n >= n_node)
526  {
527  std::ostringstream error_message;
528  error_message << "Range Error: Node number " << n
529  << " is not in the range (0," << n_node - 1 << ")";
530  throw OomphLibError(error_message.str(),
531  OOMPH_CURRENT_FUNCTION,
532  OOMPH_EXCEPTION_LOCATION);
533  }
534 #endif
535 
536 #ifdef PARANOID
537  // If there is no spine then you can't get the local equation
538  if (Spine_geometric_index[n] == this->ngeom_data())
539  {
540  std::ostringstream error_stream;
541  error_stream << "SpineNode " << n
542  << " does not have a Spine attached,\n"
543  << "so you can't get its local equation number.\n"
544  << "Check that the Mesh is correctly associating Spines "
545  "with is Nodes\n";
546  throw OomphLibError(
547  error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
548  }
549 #endif
550  return this->geometric_data_local_eqn(Spine_geometric_index[n], 0);
551  }
552  };
553 
554  //=======================================================================
555  /// Explicit definition of the face geometry for spine elements:
556  /// The same as the face geometry of the underlying element
557  //=======================================================================
558  template<class ELEMENT>
559  class FaceGeometry<SpineElement<ELEMENT>>
560  : public virtual FaceGeometry<ELEMENT>
561  {
562  public:
563  /// Constructor
564  FaceGeometry() : FaceGeometry<ELEMENT>() {}
565 
566  protected:
567  };
568 
569  //=====================================================================
570  /// Explicit definition of the face geometry for spine elements:
571  /// The same as the face geometry of the underlying element
572  //=======================================================================
573  template<class ELEMENT>
575  : public virtual FaceGeometry<FaceGeometry<ELEMENT>>
576  {
577  public:
578  /// Constructor
580 
581  protected:
582  };
583 
584  //=====================================================================
585  /// Explicit definition of the face geometry for spine elements:
586  /// The same as the face geometry of the underlying element
587  //=======================================================================
588  template<class ELEMENT>
590  : public virtual FaceGeometry<FaceGeometry<ELEMENT>>
591  {
592  public:
593  /// Constructor
595 
596  protected:
597  };
598 
599 
600  /// ///////////////////////////////////////////////////////////////////////
601  /// ///////////////////////////////////////////////////////////////////////
602  /// ///////////////////////////////////////////////////////////////////////
603 
604 
605  //========================================================================
606  /// General SpineMesh class.
607  ///
608  /// Derived from Mesh with virtual so that
609  /// spine meshes can be derived from general meshes, without
610  /// multiple copies of Mesh objects.
611  //========================================================================
612  class SpineMesh : public virtual Mesh
613  {
614  protected:
615  /// A Spine mesh contains a Vector of pointers to spines
617 
618  public:
619  /// Destructor to clean up the memory allocated to the spines
620  virtual ~SpineMesh();
621 
622  /// Return the i-th spine in the mesh
623  Spine*& spine_pt(const unsigned long& i)
624  {
625  return Spine_pt[i];
626  }
627 
628  /// Return the i-th spine in the mesh (const version)
629  const Spine* spine_pt(const unsigned long& i) const
630  {
631  return Spine_pt[i];
632  }
633 
634  /// Return the number of spines in the mesh
635  unsigned long nspine() const
636  {
637  return Spine_pt.size();
638  }
639 
640  /// Add a spine to the mesh
642  {
643  Spine_pt.push_back(spine_pt);
644  }
645 
646  /// Return a pointer to the n-th global SpineNode
647  // Can safely cast the nodes to SpineNodes
648  SpineNode* node_pt(const unsigned long& n)
649  {
650 #ifdef PARANOID
651  if (!dynamic_cast<SpineNode*>(Node_pt[n]))
652  {
653  std::ostringstream error_message;
654  error_message << "Node " << n << "is a " << typeid(Node_pt[n]).name()
655  << ", not a SpineNode" << std::endl;
656 
657  throw OomphLibError(error_message.str(),
658  OOMPH_CURRENT_FUNCTION,
659  OOMPH_EXCEPTION_LOCATION);
660  }
661 #endif
662  // Return a cast to the pointer to the node
663  return (dynamic_cast<SpineNode*>(Node_pt[n]));
664  }
665 
666  /// Return the n-th local SpineNode in element e.
667  /// This is required to cast the nodes in a spine mesh to be
668  /// SpineNodes and therefore allow access to the extra SpineNode data
669  SpineNode* element_node_pt(const unsigned long& e, const unsigned& n)
670  {
671 #ifdef PARANOID
672  // Try to cast to FiniteElement
673  FiniteElement* el_pt = dynamic_cast<FiniteElement*>(Element_pt[e]);
674  if (el_pt == 0)
675  {
676  throw OomphLibError(
677  "Can't execute element_node_pt(...) for non FiniteElements",
678  OOMPH_CURRENT_FUNCTION,
679  OOMPH_EXCEPTION_LOCATION);
680  }
681  if (!dynamic_cast<SpineNode*>(el_pt->node_pt(n)))
682  {
683  std::ostringstream error_message;
684  error_message << "Node " << n << "is a "
685  << typeid(el_pt->node_pt(n)).name() << ", not a SpineNode"
686  << std::endl;
687 
688  throw OomphLibError(error_message.str(),
689  OOMPH_CURRENT_FUNCTION,
690  OOMPH_EXCEPTION_LOCATION);
691  }
692 #endif
693  // Return a cast to the node pointer
694  return (dynamic_cast<SpineNode*>(
695  dynamic_cast<FiniteElement*>(Element_pt[e])->node_pt(n)));
696  }
697 
698  /// Assign spines to Spine_pt vector of element
699  // N.B.: Since SpineElement<ELEMENT>'s are templated, we need the template
700  // in this function so that we can do the dynamic cast to a
701  // SpineElement<ELEMENT> template<class ELEMENT> void
702  // add_spine_to_element(const unsigned long &e, Spine* spine)
703  // {dynamic_cast<ELEMENT*>(Element_pt[e])->add_spine(spine);}
704 
705  /// Assign equation numbers for spines
706  unsigned long assign_global_spine_eqn_numbers(Vector<double*>& Dof_pt);
707 
708  /// Function to describe the dofs of the Spine. The ostream
709  /// specifies the output stream to which the description
710  /// is written; the string stores the currently
711  /// assembled output that is ultimately written to the
712  /// output stream by Data::describe_dofs(...); it is typically
713  /// built up incrementally as we descend through the
714  /// call hierarchy of this function when called from
715  /// Problem::describe_dofs(...)
716  void describe_spine_dofs(std::ostream& out,
717  const std::string& current_string) const;
718 
719  /// Overload the mesh_level timestepper function to set the
720  /// timestepper data for the spines
721  void set_mesh_level_time_stepper(TimeStepper* const& time_stepper_pt,
722  const bool& preserve_existing_data)
723  {
724  this->set_spine_time_stepper(time_stepper_pt, preserve_existing_data);
725  }
726 
727  /// Set the time stepper forthe spine data that is stored in
728  /// the mesh.
729  void set_spine_time_stepper(TimeStepper* const& time_stepper_pt,
730  const bool& preserve_existing_data);
731 
732  /// Set any pinned spine "history" values to be consistent for
733  /// continuation problems
735  ContinuationStorageScheme* const& continuation_stepper_pt);
736 
737 
738  /// Check whether the pointer parameter_pt addresses data stored
739  /// in the spines
740  bool does_pointer_correspond_to_spine_data(double* const& parameter_pt);
741 
742  /// Update function to update all nodes of mesh
743  /// [Doesn't make sense to use this mesh with SolidElements anyway,
744  /// so we buffer the case if update_all_solid_nodes is set to
745  /// true.]
746  void node_update(const bool& update_all_solid_nodes = false);
747 
748  /// Update function for given spine node -- this must be implemented
749  /// by all specific SpineMeshes.
750  virtual void spine_node_update(SpineNode* spine_node_pt) = 0;
751 
752 #ifdef __clang__
753 #pragma clang diagnostic push
754 #pragma clang diagnostic ignored "-Woverloaded-virtual"
755 #endif
756 
757  /// Overload the dump function so that the spine data is dumped
758  void dump(std::ofstream& dump_file) const;
759 
760 #ifdef __clang__
761 #pragma clang diagnostic pop
762 #endif
763 
764  /// Overload the read function so that the spine data is read
765  /// from the restart file
766  void read(std::ifstream& restart_file);
767  };
768 
769 
770  /// ////////////////////////////////////////////////////////////////
771  /// ////////////////////////////////////////////////////////////////
772  // Functions for the SpineElement class
773  /// ////////////////////////////////////////////////////////////////
774  /// ////////////////////////////////////////////////////////////////
775 
776 
777  //=================================================================
778  /// Construct and fill the node_update_data vector
779  //=================================================================
780  template<class ELEMENT>
782  {
783  // Call function of underlying element
785  SpineNode>::complete_setup_of_dependencies();
786 
787  // Sort out the spine index stuff
788  // Find the data that correspond to spine heights
789  {
790  const unsigned n_node = this->nnode();
791  // Allocate memory
792  if (Spine_geometric_index)
793  {
794  delete[] Spine_geometric_index;
795  }
796  Spine_geometric_index = new unsigned[n_node];
797 
798  // Now loop over data and find out where it fits
799  for (unsigned n = 0; n < n_node; n++)
800  {
801  // Find pointer to the spine
802  Spine* const spine_pt =
803  static_cast<SpineNode*>(this->node_pt(n))->spine_pt();
804 
805  // If there is a spine then find the pointer to the data
806  if (spine_pt)
807  {
808  // Find the pointer to the data
809  Data* spine_height_data_pt = spine_pt->spine_height_pt();
810 
811  // Now find the index of the corresponding spine
812  const unsigned n_node_update_data = this->ngeom_data();
813  for (unsigned i = 0; i < n_node_update_data; i++)
814  {
815  if (this->Geom_data_pt[i] == spine_height_data_pt)
816  {
817  Spine_geometric_index[n] = i;
818  break;
819  }
820  }
821  }
822  // Otherwise issue a warning
823  else
824  {
825  // Set the spine_geometric_index out of range,
826  // which will cause the spine_local_eqn to return a pinned value
827  Spine_geometric_index[n] = this->ngeom_data();
828  }
829  }
830  }
831  }
832 
833 } // namespace oomph
834 
835 #endif
e
Definition: cfortran.h:571
cstr elem_len * i
Definition: cfortran.h:603
GeneralisedTimestepper used to store the arclength derivatives and pervious solutions required in con...
A class that represents a collection of data; each Data object may contain many different individual ...
Definition: nodes.h:86
TimeStepper *& time_stepper_pt()
Return the pointer to the timestepper.
Definition: nodes.h:238
int geometric_data_local_eqn(const unsigned &n, const unsigned &i)
Return the local equation number corresponding to the i-th value at the n-th geometric data object.
unsigned ngeom_data() const
Return the number of geometric data upon which the shape of the element depends.
Specific implementation of the class for specified element and node type.
//////////////////////////////////////////////////////////////////// ////////////////////////////////...
Definition: elements.h:4998
A general Finite Element class.
Definition: elements.h:1313
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Definition: elements.h:2175
unsigned nnode() const
Return the number of nodes.
Definition: elements.h:2210
/////////////////////////////////////////////////////////////////////
Definition: geom_objects.h:101
A general mesh class.
Definition: mesh.h:67
Vector< Node * > Node_pt
Vector of pointers to nodes.
Definition: mesh.h:183
Vector< GeneralisedElement * > Element_pt
Vector of pointers to generalised elements.
Definition: mesh.h:186
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
Definition: nodes.h:906
An OomphLibError object which should be thrown when an run-time error is encountered....
The SpineElement<ELEMENT> class takes an existing element as a template parameter and adds the necess...
Definition: spines.h:477
unsigned * Spine_geometric_index
Array to hold the index of the geometric data associated with the spine height of the spine that affe...
Definition: spines.h:481
~SpineElement()
Destructor, clean up the storage allocated to the local equation numbers.
Definition: spines.h:511
void complete_setup_of_dependencies()
Complete the setup of additional dependencies. Overloads empty virtual function in GeneralisedElement...
Definition: spines.h:781
int spine_local_eqn(const unsigned &n)
Return the local equation number corresponding to the height of the spine at the n-th node.
Definition: spines.h:521
SpineElement(FiniteElement *const &element_pt, const int &face_index)
Constructor used for spine face elements.
Definition: spines.h:502
SpineElement()
Constructor, call the constructor of the base element.
Definition: spines.h:494
//////////////////////////////////////////////////////////////////// ////////////////////////////////...
Definition: spines.h:456
SpineFiniteElement()
Empty constructor.
Definition: spines.h:459
virtual ~SpineFiniteElement()
Emtpty virtual destructor.
Definition: spines.h:462
/////////////////////////////////////////////////////////////////////// /////////////////////////////...
Definition: spines.h:613
void set_consistent_pinned_spine_values_for_continuation(ContinuationStorageScheme *const &continuation_stepper_pt)
Set any pinned spine "history" values to be consistent for continuation problems.
Definition: spines.cc:189
const Spine * spine_pt(const unsigned long &i) const
Return the i-th spine in the mesh (const version)
Definition: spines.h:629
void read(std::ifstream &restart_file)
Overload the read function so that the spine data is read from the restart file.
Definition: spines.cc:253
void dump(std::ofstream &dump_file) const
Overload the dump function so that the spine data is dumped.
Definition: spines.cc:229
void add_spine_pt(Spine *const &spine_pt)
Add a spine to the mesh.
Definition: spines.h:641
Vector< Spine * > Spine_pt
A Spine mesh contains a Vector of pointers to spines.
Definition: spines.h:616
SpineNode * node_pt(const unsigned long &n)
Return a pointer to the n-th global SpineNode.
Definition: spines.h:648
bool does_pointer_correspond_to_spine_data(double *const &parameter_pt)
Check whether the pointer parameter_pt addresses data stored in the spines.
Definition: spines.cc:207
unsigned long nspine() const
Return the number of spines in the mesh.
Definition: spines.h:635
void describe_spine_dofs(std::ostream &out, const std::string &current_string) const
Function to describe the dofs of the Spine. The ostream specifies the output stream to which the desc...
Definition: spines.cc:154
void set_spine_time_stepper(TimeStepper *const &time_stepper_pt, const bool &preserve_existing_data)
Set the time stepper forthe spine data that is stored in the mesh.
Definition: spines.cc:171
virtual void spine_node_update(SpineNode *spine_node_pt)=0
Update function for given spine node – this must be implemented by all specific SpineMeshes.
Spine *& spine_pt(const unsigned long &i)
Return the i-th spine in the mesh.
Definition: spines.h:623
void node_update(const bool &update_all_solid_nodes=false)
Update function to update all nodes of mesh [Doesn't make sense to use this mesh with SolidElements a...
Definition: spines.cc:84
virtual ~SpineMesh()
Destructor to clean up the memory allocated to the spines.
Definition: spines.cc:66
void set_mesh_level_time_stepper(TimeStepper *const &time_stepper_pt, const bool &preserve_existing_data)
Overload the mesh_level timestepper function to set the timestepper data for the spines.
Definition: spines.h:721
unsigned long assign_global_spine_eqn_numbers(Vector< double * > &Dof_pt)
Assign spines to Spine_pt vector of element.
Definition: spines.cc:124
SpineNode * element_node_pt(const unsigned long &e, const unsigned &n)
Return the n-th local SpineNode in element e. This is required to cast the nodes in a spine mesh to b...
Definition: spines.h:669
Class for nodes that live on spines. The assumption is that each Node lies at a fixed fraction on a s...
Definition: spines.h:328
Data ** all_geom_data_pt()
Return the vector of all geometric data.
Definition: spines.h:433
SpineNode(TimeStepper *const &time_stepper_pt, const unsigned &n_dim, const unsigned &n_position_type, const unsigned &initial_nvalue)
Unsteady Constructor, initialise pointers to zero.
Definition: spines.h:359
GeomObject ** all_geom_object_pt()
Return the vector of all geometric objects.
Definition: spines.h:439
unsigned ngeom_data() const
Return the number of geometric data, zero if no spine.
Definition: spines.h:407
double & h()
Access function to spine height.
Definition: spines.h:397
SpineMesh *& spine_mesh_pt()
Access function to Pointer to SpineMesh that this node is a part of and which implements the node upd...
Definition: spines.h:391
SpineMesh * Spine_mesh_pt
Pointer to SpineMesh that this node is a part of. (The mesh implements the node update function(s))
Definition: spines.h:338
double Fraction
Private double that represents the fixed fraction along the spine.
Definition: spines.h:334
Spine * Spine_pt
Private internal data pointer to a spine.
Definition: spines.h:331
unsigned Node_update_fct_id
ID of node update function (within specific mesh – useful if there are multiple node update functions...
Definition: spines.h:342
Spine *& spine_pt()
Access function to spine.
Definition: spines.h:372
unsigned & node_update_fct_id()
Access function to ID of node update function (within specific mesh)
Definition: spines.h:384
double & fraction()
Set reference to fraction along spine.
Definition: spines.h:378
SpineNode(const unsigned &n_dim, const unsigned &n_position_type, const unsigned &initial_nvalue)
Steady Constructor, initialise pointers to zero.
Definition: spines.h:347
unsigned ngeom_object() const
Return the number of geometric objects, zero if no spine.
Definition: spines.h:420
void node_update(const bool &update_all_time_levels_for_new_node=false)
Overload thet node update function, call the update function in the Node's SpineMesh.
Definition: spines.cc:44
Spines are used for algebraic node update operations in free-surface fluid problems: They form the ba...
Definition: spines.h:64
~Spine()
Destructor: Wipe Data object that stores the Spine height. All other objects (geometric Data and geom...
Definition: spines.h:142
Spine(const double &height, const Vector< Data * > &geom_data_pt, const Vector< GeomObject * > &geom_object_pt)
Constructor: Create the Spine and initialise its height to the specified value. Store the vector of (...
Definition: spines.h:115
Data * spine_height_pt() const
Access function to Data object that stores the spine height (const version)
Definition: spines.h:163
GeomObject * geom_object_pt(const unsigned &i) const
Return i-th geometric object that is involved in the node update operations for this Spine....
Definition: spines.h:251
void set_geom_data_pt(const Vector< Data * > &geom_data_pt)
Set vector of (pointers to) geometric Data that is involved in the node update operations for this Sp...
Definition: spines.h:179
void add_geom_data_pt(Data *geom_data_pt)
Add (pointer to) geometric Data that is involved in the node update operations for this Spine.
Definition: spines.h:191
unsigned ngeom_object()
Number of geometric objects that is involved in the node update operations for this Spine.
Definition: spines.h:218
Vector< Data * > Geom_data_pt
Data that stores the spine height.
Definition: spines.h:305
void set_geom_object_pt(const Vector< GeomObject * > &geom_object_pt)
Set vector of (pointers to) geometric objects that is involved in the node update operations for this...
Definition: spines.h:225
void add_geom_parameter(const double &geom_parameter)
Add geometric parameter involved in the node update operations for this Spine.
Definition: spines.h:280
GeomObject *& geom_object_pt(const unsigned &i)
Return i-th geometric object that is involved in the node update operations for this Spine.
Definition: spines.h:244
unsigned ngeom_data()
Number of geometric Data that is involved in the node update operations for this Spine.
Definition: spines.h:171
void set_geom_parameter(const Vector< double > &geom_parameter)
Set vector of geometric parameters that are involved in the node update operations for this Spine....
Definition: spines.h:273
double & height()
Access function to spine height.
Definition: spines.h:150
Spine(const double &height)
Constructor: Create the Spine and initialise its height to the specified value.
Definition: spines.h:77
unsigned ngeom_parameter()
Number of geometric parameters that are involved in the node update operations for this Spine.
Definition: spines.h:265
Data * geom_data_pt(const unsigned &i) const
Return i-th geometric Data that is involved in the node update operations for this Spine....
Definition: spines.h:205
double & geom_parameter(const unsigned &i)
Return i-th geometric parameter that is involved in the node update operations for this Spine.
Definition: spines.h:287
Vector< Data * > & vector_geom_data_pt()
Return the vector of geometric data.
Definition: spines.h:211
Spine()
Default constructor: Create the Spine and initialise its height to zero.
Definition: spines.h:68
Vector< double > Geom_parameter
Vector that stores doubles that are used in the geometric updates.
Definition: spines.h:312
Vector< GeomObject * > Geom_object_pt
Vector that stores the pointers to geometric objects that is involved in the node update operation.
Definition: spines.h:309
Data *& geom_data_pt(const unsigned &i)
Return i-th geometric Data that is involved in the node update operations for this Spine.
Definition: spines.h:198
Data *& spine_height_pt()
Access function to Data object that stores the spine height.
Definition: spines.h:156
Vector< GeomObject * > & vector_geom_object_pt()
Return the vector of all geometric objects that affect this spine.
Definition: spines.h:258
const double & geom_parameter(const unsigned &i) const
Return i-th geometric parameter that is involved in the node update operations for this Spine....
Definition: spines.h:294
void add_geom_object_pt(GeomObject *geom_object_pt)
Add (pointer to) geometric object that is involved in the node update operations for this Spine.
Definition: spines.h:237
Spine(const double &height, const Vector< Data * > &geom_data_pt)
Constructor: Create the Spine and initialise its height to the specified value. Store the vector of (...
Definition: spines.h:90
////////////////////////////////////////////////////////////////////// //////////////////////////////...
Definition: timesteppers.h:231
A slight extension to the standard template vector class so that we can include "graceful" array rang...
Definition: Vector.h:58
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn't been defined.
//////////////////////////////////////////////////////////////////// ////////////////////////////////...