generalised_timesteppers.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_GENERALISED_TIMESTEPPERS_HEADER
27#define OOMPH_GENERALISED_TIMESTEPPERS_HEADER
28
29#include <typeinfo>
30
31// Config header generated by autoconfig
32#ifdef HAVE_CONFIG_H
33#include <oomph-lib-config.h>
34#endif
35
36// OOMPH-LIB headers
37#include "timesteppers.h"
38
39namespace oomph
40{
41 //======================================================================
42 /// Generalised timestepper that can serve a variety of purposes
43 /// in continuation, bifurcation detection and periodic-orbit computations.
44 /// The key generalisation is that more than one of the entries is actually
45 /// a degree of freedom in the problem. These are distinct from our
46 /// standard (implict) Timesteppers in which the only dof is the current
47 /// value (first entry in the storage scheme). These objects will typically
48 /// be used to replace exisiting timesteppers for specific tasks.
49 //====================================================================
51 {
52 protected:
53 // Set the number of entries that correspond to dof storage
55
56 // Vector that represents the storage entries
57 // Vector<unsigned> Dof_storage_index;
58
59 /// Constructor that can only be called by derived objects.
60 /// Pass the information directly through to the TimeStepper object
61 GeneralisedTimeStepper(const unsigned& n_tstorage,
62 const unsigned& max_deriv,
63 const unsigned& ndof_storage_entries = 1)
64 : TimeStepper(n_tstorage, max_deriv),
66 {
67 // Dof_storage_index.resize(1,0.0);
68 }
69
70 /// Broken empty constructor
72
73 /// Broken copy constructor
75
76 /// Broken assignment operator
77 void operator=(const GeneralisedTimeStepper&) = delete;
78
79 public:
80 /// Return the number of entries that correspond to dof storage
81 unsigned ndof_storage_entries() const
82 {
84 }
85
86 /// Return the i-th storage index
87 // unsigned dof_storage_index(const unsigned &i) {return
88 // Dof_storage_index[i];}
89 };
90
91 //========================================================================
92 /// GeneralisedTimestepper used to store the arclength derivatives
93 /// and pervious solutions required in continuation problems. The data
94 /// is stored as auxilliary data in the (fake) TimeStepper so that
95 /// spatial adaptivity will be handled automatically through our standard
96 /// mechanisms. The adopted storage scheme is that the continuation
97 /// derivatives will be stored at the first auxilliary value and
98 /// the previous value will be the second auixilliary value
99 //====================================================================
101 {
102 // Store the offset for the derivatives
104
105 // Store the offset for the current values of the dofs
107
108 public:
109 /// Constructor for the case when we allow adaptive continuation
110 /// It can evaulate up to second derivatives, but doesn't do anything
111 /// the time-derivatives evaluate to zero.
116 {
117 Type = "ContinuationStorageScheme";
118 Is_steady = true;
119 }
120
121
122 /// Broken copy constructor
124
125 /// Modify the scheme based on the underlying timestepper
126 void modify_storage(GeneralisedTimeStepper* const& time_stepper_pt)
127 {
128 // Get the number of "dofs" in the existing timestepper
129 this->Ndof_storage_entries = time_stepper_pt->ndof_storage_entries();
130 // Get the current amount of storage
131 unsigned n_tstorage = time_stepper_pt->ntstorage();
132
133 // Find the offsets which is always relative to the number of dofs stored
134 // in the existing timestepper
135 Dof_derivative_offset = n_tstorage;
136 Dof_current_offset = n_tstorage + this->Ndof_storage_entries;
137
138 // Set the new amount of storage twice the dofs to store parameter
139 // derivatives and initial values plus the original storage
140 unsigned n_new_tstorage = 2 * this->Ndof_storage_entries + n_tstorage;
141
142 // Resize the weights accordingly
143 Weight.resize(3, n_new_tstorage, 0.0);
144 // Set the weight for the zero-th derivative which is always 1.0
145 Weight(0, 0) = 1.0;
146 }
147
148
149 /// Broken assignment operator
151
152 /// Return the actual order of the scheme. It's a steady
153 /// scheme so it's zero, but that doesn't really make sense.
154 unsigned order() const
155 {
156 return 0;
157 }
158
159 /// This is a steady scheme, so you can't do this
161 {
162 Is_steady = true;
163 }
164
165 /// Broken initialisation the time-history for the Data values
166 /// corresponding to an impulsive start.
168 {
170 "Cannot perform impulsive start for ContinuationStorageScheme",
171 OOMPH_CURRENT_FUNCTION,
172 OOMPH_EXCEPTION_LOCATION);
173 }
174
175 /// Broken initialisation of
176 /// the positions for the node corresponding to an impulsive start
178 {
180 "Cannot perform impulsive start for ContinuationStorageScheme",
181 OOMPH_CURRENT_FUNCTION,
182 OOMPH_EXCEPTION_LOCATION);
183 }
184
185 /// Broken shifting of time values
186 void shift_time_values(Data* const& data_pt)
187 {
188 throw OomphLibError(
189 "Cannot shift time values forContinuationStorageScheme",
190 OOMPH_CURRENT_FUNCTION,
191 OOMPH_EXCEPTION_LOCATION);
192 }
193
194 /// Broken shifting of time positions
195 void shift_time_positions(Node* const& node_pt)
196 {
197 throw OomphLibError(
198 "Cannot shift time positions forContinuationStorageScheme",
199 OOMPH_CURRENT_FUNCTION,
200 OOMPH_EXCEPTION_LOCATION);
201 }
202
203 /// Set the weights (Do nothing)
204 void set_weights() {}
205
206 /// Number of previous values available.
207 unsigned nprev_values() const
208 {
209 return 0;
210 }
211
212 /// Number of timestep increments that need to be stored by the scheme
213 unsigned ndt() const
214 {
215 return 0;
216 }
217
218 /// Set consistent values of the derivatives and current value when
219 /// the data is pinned. This must be done by the "timestepper" because only
220 /// it knows the local storage scheme
221 void set_consistent_pinned_values(Data* const& data_pt)
222 {
223#ifdef PARANOID
224 // If the data is not associated with the continuation time stepper then
225 // complain
226 if (this != data_pt->time_stepper_pt())
227 {
228 std::ostringstream error_stream;
229 error_stream
230 << "Data object " << data_pt << " has timestepper of type "
231 << typeid(data_pt->time_stepper_pt()).name() << "\n"
232 << "Please set the data's timestepper to be a "
233 << "ContinuationStorageScheme before calling this function\n";
234 throw OomphLibError(
235 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
236 }
237#endif
238
239 // Loop over the values in the data object
240 const unsigned n_value = data_pt->nvalue();
241 for (unsigned i = 0; i < n_value; ++i)
242 {
243 // Only bother to do anything if the value is pinned and not a copy
244 if (data_pt->is_pinned(i) && (data_pt->is_a_copy(i) == false))
245 {
246 // ASSUMPTION storage is always at the "front"
247 for (unsigned t = 0; t < this->Ndof_storage_entries; t++)
248 {
249 // Set the stored derivatve to be zero
250 data_pt->set_value(Dof_derivative_offset + t, i, 0.0);
251 // Set the stored current value to be the same as the present value
252 data_pt->set_value(Dof_current_offset + t, i, data_pt->value(t, i));
253 }
254 }
255 }
256 }
257
258 /// Set consistent values of the derivatives and current value when
259 /// the Nodes position is pinned. This must be done by the "timestepper"
260 /// because only it knows the local storage scheme
262 {
263 // Only need to do anything if this is a solid node
264 if (SolidNode* const solid_node_pt = dynamic_cast<SolidNode*>(node_pt))
265 {
266#ifdef PARANOID
267 // If the data is not associated with the continuation time stepper then
268 // complain
269 if (this != node_pt->position_time_stepper_pt())
270 {
271 std::ostringstream error_stream;
272 error_stream
273 << "Node object " << node_pt << " has position timestepper of type "
274 << typeid(node_pt->position_time_stepper_pt()).name() << "\n"
275 << "Please set the Node's position timestepper to be a "
276 << "ContinuationStorageScheme before calling this function\n";
277 throw OomphLibError(error_stream.str(),
278 OOMPH_CURRENT_FUNCTION,
279 OOMPH_EXCEPTION_LOCATION);
280 }
281#endif
282
283 // Find the number of coordinates
284 const unsigned n_dim = solid_node_pt->ndim();
285 // Find the number of position types
286 const unsigned n_position_type = solid_node_pt->nposition_type();
287
288 // Loop over physical coordinates
289 for (unsigned i = 0; i < n_dim; i++)
290 {
291 // Set the appropriate values if it's not a copy
292 if (solid_node_pt->position_is_a_copy(i) == false)
293 {
294 // Loop over generalised dofs
295 for (unsigned k = 0; k < n_position_type; k++)
296 {
297 // If it's pinned then set the "history" values
298 if (solid_node_pt->position_is_pinned(k, i))
299 {
300 for (unsigned t = 0; t < Ndof_storage_entries; t++)
301 {
302 // Set the derivative to 0
303 solid_node_pt->x_gen(Dof_derivative_offset + t, k, i) = 0.0;
304 // Set the stored current value to the present value
305 solid_node_pt->x_gen(Dof_current_offset + t, k, i) =
306 solid_node_pt->x_gen(t, k, i);
307 }
308 }
309 }
310 }
311 }
312 }
313 }
314
315 // Return the stored derivative offset
317 {
319 }
320
321 // Return the offset for the current values
323 {
324 return Dof_current_offset;
325 }
326 };
327
328} // namespace oomph
329
330#endif
cstr elem_len * i
Definition: cfortran.h:603
char t
Definition: cfortran.h:568
GeneralisedTimestepper used to store the arclength derivatives and pervious solutions required in con...
void operator=(const ContinuationStorageScheme &)=delete
Broken assignment operator.
void shift_time_positions(Node *const &node_pt)
Broken shifting of time positions.
void assign_initial_values_impulsive(Data *const &data_pt)
Broken initialisation the time-history for the Data values corresponding to an impulsive start.
void set_consistent_pinned_values(Data *const &data_pt)
Set consistent values of the derivatives and current value when the data is pinned....
ContinuationStorageScheme(const ContinuationStorageScheme &)=delete
Broken copy constructor.
void modify_storage(GeneralisedTimeStepper *const &time_stepper_pt)
Modify the scheme based on the underlying timestepper.
void set_weights()
Set the weights (Do nothing)
void assign_initial_positions_impulsive(Node *const &node_pt)
Broken initialisation of the positions for the node corresponding to an impulsive start.
void shift_time_values(Data *const &data_pt)
Broken shifting of time values.
unsigned nprev_values() const
Number of previous values available.
unsigned order() const
Return the actual order of the scheme. It's a steady scheme so it's zero, but that doesn't really mak...
void set_consistent_pinned_positions(Node *const &node_pt)
Set consistent values of the derivatives and current value when the Nodes position is pinned....
void undo_make_steady()
This is a steady scheme, so you can't do this.
unsigned ndt() const
Number of timestep increments that need to be stored by the scheme.
ContinuationStorageScheme()
Constructor for the case when we allow adaptive continuation It can evaulate up to second derivatives...
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
void set_value(const unsigned &i, const double &value_)
Set the i-th stored data value to specified value. The only reason that we require an explicit set fu...
Definition: nodes.h:271
virtual bool is_a_copy() const
Return a boolean to indicate whether the Data objact contains any copied values. A base Data object c...
Definition: nodes.h:253
unsigned nvalue() const
Return number of values stored in data object (incl pinned ones).
Definition: nodes.h:483
double value(const unsigned &i) const
Return i-th stored value. This function is not virtual so that it can be inlined. This means that if ...
Definition: nodes.h:293
bool is_pinned(const unsigned &i) const
Test whether the i-th variable is pinned (1: true; 0: false).
Definition: nodes.h:417
void resize(const unsigned long &n)
Resize to a square nxn matrix; any values already present will be transfered.
Definition: matrices.h:498
Generalised timestepper that can serve a variety of purposes in continuation, bifurcation detection a...
unsigned ndof_storage_entries() const
Return the number of entries that correspond to dof storage.
void operator=(const GeneralisedTimeStepper &)=delete
Broken assignment operator.
GeneralisedTimeStepper(const GeneralisedTimeStepper &)=delete
Broken copy constructor.
GeneralisedTimeStepper()
Broken empty constructor.
GeneralisedTimeStepper(const unsigned &n_tstorage, const unsigned &max_deriv, const unsigned &ndof_storage_entries=1)
Constructor that can only be called by derived objects. Pass the information directly through to the ...
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
Definition: nodes.h:906
TimeStepper *& position_time_stepper_pt()
Return a pointer to the position timestepper.
Definition: nodes.h:1022
An OomphLibError object which should be thrown when an run-time error is encountered....
An OomphLibWarning object which should be created as a temporary object to issue a warning....
A Class for nodes that deform elastically (i.e. position is an unknown in the problem)....
Definition: nodes.h:1686
////////////////////////////////////////////////////////////////////// //////////////////////////////...
Definition: timesteppers.h:231
DenseMatrix< double > Weight
Storage for the weights associated with the timestepper.
Definition: timesteppers.h:237
unsigned ntstorage() const
Return the number of doubles required to represent history (one for steady)
Definition: timesteppers.h:601
std::string Type
String that indicates the type of the timestepper (e.g. "BDF", "Newmark", etc.)
Definition: timesteppers.h:241
bool Is_steady
Bool to indicate if the timestepper is steady, i.e. its time-derivatives evaluate to zero....
Definition: timesteppers.h:251
//////////////////////////////////////////////////////////////////// ////////////////////////////////...