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-2025 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
32namespace 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 //===================================================================
45 {
47
48 // Perform any auxiliary updates (i.e. reseting boundary conditions)
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 //============================================================
85 {
86#ifdef PARANOID
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(
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(
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 //====================================================================
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 //====================================================================
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
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 {
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
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(
284 }
285
286 // Loop over the spines and read the data
287 for (unsigned long s = 0; s < n_spine; s++)
288 {
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 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
double size() const
Calculate the size of the element (length, area, volume,...) in Eulerian computational coordinates....
Definition elements.cc:4320
void describe_dofs(std::ostream &out, const std::string &current_string) const
Function to describe the dofs of the element. The ostream specifies the output stream to which the de...
Definition elements.cc:556
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
Spine *& spine_pt(const unsigned long &i)
Return the i-th spine in the mesh.
Definition spines.h:623
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.
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
TAdvectionDiffusionReactionElement<NREAGENT,DIM,NNODE_1D> elements are isoparametric triangular DIM-d...
Base class for time-stepping schemes. Timestepper provides an approximation of the temporal derivativ...
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).