spines.cc
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 // Functions for the SpineNode/SpineElement/SpineMesh classes
27 // oomph-lib headers
28 
29 #include "spines.h"
30 #include <cstdlib>
31 
32 namespace oomph
33 {
34  /// ////////////////////////////////////////////////////////////////
35  /// ////////////////////////////////////////////////////////////////
36  // Functions for the SpineNode class
37  /// ////////////////////////////////////////////////////////////////
38  /// ////////////////////////////////////////////////////////////////
39 
40 
41  //===================================================================
42  /// Update function, call the update function in the Node's SpineMesh.
43  //===================================================================
44  void SpineNode::node_update(const bool& update_all_time_levels_for_new_node)
45  {
47 
48  // Perform any auxiliary updates (i.e. reseting boundary conditions)
49  if (Aux_node_update_fct_pt != 0)
50  {
52  }
53  }
54 
55 
56  /// ////////////////////////////////////////////////////////////////
57  /// ////////////////////////////////////////////////////////////////
58  // Functions for the SpineMesh class
59  /// ////////////////////////////////////////////////////////////////
60  /// ////////////////////////////////////////////////////////////////
61 
62 
63  //=============================================================
64  /// Destructor to clean up the memory allocated to the spines
65  //=============================================================
67  {
68  // Set the range of Spine_pt
69  unsigned long Spine_pt_range = Spine_pt.size();
70  // Loop over the entries in reverse and free memory
71  for (unsigned long i = Spine_pt_range; i > 0; i--)
72  {
73  delete Spine_pt[i - 1];
74  Spine_pt[i - 1] = 0;
75  }
76  }
77 
78  //============================================================
79  /// Update function to update all nodes of mesh.
80  /// [Doesn't make sense to use this mesh with SolidElements anyway,
81  /// so we buffer the case if update_all_solid_nodes (which defaults
82  /// to false) is set to true.]
83  //============================================================
84  void SpineMesh::node_update(const bool& update_all_solid_nodes)
85  {
86 #ifdef PARANOID
87  if (update_all_solid_nodes)
88  {
89  std::string error_message =
90  "Doesn't make sense to use an SpineMesh with\n";
91  error_message +=
92  "SolidElements so specifying update_all_solid_nodes=true\n";
93  error_message += "doesn't make sense either\n";
94 
95  throw OomphLibError(
96  error_message, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
97  }
98 #endif
99 
100  // Loop over all the nodes
101  unsigned long Node_pt_range = Node_pt.size();
102  for (unsigned long l = 0; l < Node_pt_range; l++)
103  {
104 #ifdef PARANOID
105  if (!dynamic_cast<SpineNode*>(Node_pt[l]))
106  {
107  std::ostringstream error_stream;
108  error_stream << "Error: Node " << l << "is a "
109  << typeid(Node_pt[l]).name() << ", not a SpineNode"
110  << std::endl;
111  throw OomphLibError(
112  error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
113  }
114 #endif
115 
116  // Need to cast to spine node to get to update function
117  dynamic_cast<SpineNode*>(Node_pt[l])->node_update();
118  }
119  }
120 
121  //====================================================================
122  /// Assign (global) equation numbers to spines, nodes and elements
123  //====================================================================
125  Vector<double*>& Dof_pt)
126  {
127  // Find the current number of dofs
128  unsigned long equation_number = Dof_pt.size();
129 
130  // Loop over spines and set global equation numbers for the spine heights
131  // (they are the only Data items whose global eqn numbers are assigned
132  // here)
133  unsigned long Spine_pt_range = Spine_pt.size();
134  for (unsigned long i = 0; i < Spine_pt_range; i++)
135  {
136  Spine_pt[i]->spine_height_pt()->assign_eqn_numbers(equation_number,
137  Dof_pt);
138  }
139 
140  // Return the total number of equations
141  return (equation_number);
142  }
143 
144  //====================================================================
145  /// Function to describe the dofs of the Spine. The ostream
146  /// specifies the output stream to which the description
147  /// is written; the string stores the currently
148  /// assembled output that is ultimately written to the
149  /// output stream by Data::describe_dofs(...); it is typically
150  /// built up incrementally as we descend through the
151  /// call hierarchy of this function when called from
152  /// Problem::describe_dofs(...)
153  //====================================================================
154  void SpineMesh::describe_spine_dofs(std::ostream& out,
155  const std::string& current_string) const
156  {
157  // Describe spine heights.
158  unsigned long Spine_pt_range = Spine_pt.size();
159  for (unsigned long i = 0; i < Spine_pt_range; i++)
160  {
161  std::stringstream conversion;
162  conversion << " of Spine Height " << i << current_string;
163  std::string in(conversion.str());
164  Spine_pt[i]->spine_height_pt()->describe_dofs(out, in);
165  }
166  }
167 
168  //====================================================================
169  /// Assign time stepper to spines data
170  //====================================================================
171  void SpineMesh::set_spine_time_stepper(TimeStepper* const& time_stepper_pt,
172  const bool& preserve_existing_data)
173  {
174  // Loop over spines and set the time stepper for the spine heights
175  // (they are the only Data that are additional to the standard nodal and
176  // elemental)
177  const unsigned long n_spine = this->nspine();
178  for (unsigned long i = 0; i < n_spine; i++)
179  {
180  this->Spine_pt[i]->spine_height_pt()->set_time_stepper(
181  time_stepper_pt, preserve_existing_data);
182  }
183  }
184 
185  //====================================================================
186  /// Set the data associated with pinned spine values to be consistent
187  /// for continuation when using the continuation storage scheme
188  //====================================================================
190  ContinuationStorageScheme* const& continuation_stepper_pt)
191  {
192  // Loop over spines and set consistent values by using the function
193  // provided by the continuation storage scheme
194  const unsigned long n_spine = this->nspine();
195  for (unsigned long i = 0; i < n_spine; i++)
196  {
197  continuation_stepper_pt->set_consistent_pinned_values(
198  this->Spine_pt[i]->spine_height_pt());
199  }
200  }
201 
202 
203  //=====================================================================
204  /// Return true if the pointer addresses data stored within the spines,
205  /// false if not.
206  //=====================================================================
208  double* const& parameter_pt)
209  {
210  // Loop over spines and check their data
211  const unsigned long n_spine = this->nspine();
212  for (unsigned long i = 0; i < n_spine; i++)
213  {
214  if (this->Spine_pt[i]
215  ->spine_height_pt()
216  ->does_pointer_correspond_to_value(parameter_pt))
217  {
218  return true;
219  }
220  }
221 
222  // If we haven't found it yet, then it's not present in the spine data
223  return false;
224  }
225 
226  //=======================================================================
227  /// Overload the dump function so that the spine data is also dumped
228  //=======================================================================
229  void SpineMesh::dump(std::ofstream& dump_file) const
230  {
231  // Call the standard mesh dump function
232  Mesh::dump(dump_file);
233 
234  // Now loop over the spine data and dump the spine height data
235  // The ASSUMPTION is that the geometric data is stored elsewhere and will
236  // be dumped elsewhere
237 
238  // Find the number of spines
239  unsigned long n_spine = nspine();
240  // Doc number of spines
241  dump_file << n_spine << " # number of spines " << std::endl;
242 
243  // Loop over the spines
244  for (unsigned long s = 0; s < n_spine; s++)
245  {
246  spine_pt(s)->spine_height_pt()->dump(dump_file);
247  }
248  }
249 
250  //========================================================================
251  /// Overload the read function so that the spine data is also read
252  //========================================================================
253  void SpineMesh::read(std::ifstream& restart_file)
254  {
255  // Call the standard mesh read function
256  Mesh::read(restart_file);
257 
258  // Now loop over the spine data and dump the spine height data
259  // The ASSUMPTION is that the geometric data is stored elsewhere and will
260  // be dumped elsewhere
261 
262  // Get the number of spines
263  unsigned long n_spine = nspine();
264 
265  std::string input_string;
266  // Read line up to termination sign
267  getline(restart_file, input_string, '#');
268  // Ignore the restr of the line
269  restart_file.ignore(80, '\n');
270 
271  // check the number of spines
272  unsigned long check_n_spine = atoi(input_string.c_str());
273 
274  if (check_n_spine != n_spine)
275  {
276  std::ostringstream error_stream;
277  error_stream << "Number of spines in the restart file, " << check_n_spine
278  << std::endl
279  << "does not equal the number of spines in the mesh "
280  << n_spine << std::endl;
281 
282  throw OomphLibError(
283  error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
284  }
285 
286  // Loop over the spines and read the data
287  for (unsigned long s = 0; s < n_spine; s++)
288  {
289  spine_pt(s)->spine_height_pt()->read(restart_file);
290  }
291  }
292 
293 } // namespace oomph
static char t char * s
Definition: cfortran.h:568
cstr elem_len * i
Definition: cfortran.h:603
GeneralisedTimestepper used to store the arclength derivatives and pervious solutions required in con...
void set_consistent_pinned_values(Data *const &data_pt)
Set consistent values of the derivatives and current value when the data is pinned....
void dump(std::ostream &dump_file) const
Dump the data object to a file.
Definition: nodes.cc:645
void read(std::ifstream &restart_file)
Read data object from a file.
Definition: nodes.cc:672
Vector< Node * > Node_pt
Vector of pointers to nodes.
Definition: mesh.h:183
virtual void read(std::ifstream &restart_file)
Read solution from restart file.
Definition: mesh.cc:1130
virtual void dump(std::ofstream &dump_file, const bool &use_old_ordering=true) const
Dump the data in the mesh into a file for restart.
Definition: mesh.cc:1088
AuxNodeUpdateFctPt Aux_node_update_fct_pt
Pointer to auxiliary update function – this can be used to update any nodal values following the upda...
Definition: nodes.h:967
An OomphLibError object which should be thrown when an run-time error is encountered....
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
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
Vector< Spine * > Spine_pt
A Spine mesh contains a Vector of pointers to spines.
Definition: spines.h:616
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
unsigned long assign_global_spine_eqn_numbers(Vector< double * > &Dof_pt)
Assign spines to Spine_pt vector of element.
Definition: spines.cc:124
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
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
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
Data *& spine_height_pt()
Access function to Data object that stores the spine height.
Definition: spines.h:156
////////////////////////////////////////////////////////////////////// //////////////////////////////...
Definition: timesteppers.h:231
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn't been defined.
//////////////////////////////////////////////////////////////////// ////////////////////////////////...