30 #ifndef OOMPH_TIME_STEPPERS_HEADER
31 #define OOMPH_TIME_STEPPERS_HEADER
35 #include <oomph-lib-config.h>
50 class ExplicitTimeStepper;
101 unsigned ndt =
Dt.size();
112 unsigned n_dt = dt_.size();
113 for (
unsigned i = 0;
i < n_dt;
i++)
136 double&
dt(
const unsigned&
t = 0)
143 double dt(
const unsigned&
t = 0)
const
150 double time(
const unsigned&
t = 0)
const
155 using namespace StringConversion;
158 error_msg, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
164 for (
unsigned i = 0;
i <
t;
i++)
176 unsigned n_dt =
Dt.size();
183 for (
unsigned i = (n_dt - 1);
i > 0;
i--)
281 Adaptive_Flag(false),
283 Shut_up_in_assign_initial_data_values(false),
284 Predict_by_explicit_step(false)
287 Weight.
resize(max_deriv + 1, tstorage, 0.0);
295 Predictor_storage_index = -1;
297 Explicit_predictor_pt = 0;
303 throw OomphLibError(
"Don't call default constructor for TimeStepper!",
304 OOMPH_CURRENT_FUNCTION,
305 OOMPH_EXCEPTION_LOCATION);
320 return Weight.
nrow() - 1;
334 return Time_pt->
time();
345 error_msg, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
348 return Time_pt->
time();
352 virtual unsigned ndt()
const = 0;
398 return Predict_by_explicit_step;
405 return Explicit_predictor_pt;
412 Explicit_predictor_pt = _pred_pt;
419 Predicted_time = new_time;
426 if (std::abs(time_pt()->
time() - Predicted_time) > 1
e-15)
429 "Predicted values are not from the correct time step",
430 OOMPH_EXCEPTION_LOCATION,
431 OOMPH_CURRENT_FUNCTION);
444 if (Predictor_storage_index > 0)
446 return unsigned(Predictor_storage_index);
450 std::string err =
"Predictor storage index is negative, this probably";
451 err +=
" means it hasn't been set for this timestepper.";
453 err, OOMPH_EXCEPTION_LOCATION, OOMPH_CURRENT_FUNCTION);
456 return unsigned(Predictor_storage_index);
464 Shut_up_in_assign_initial_data_values =
false;
471 Shut_up_in_assign_initial_data_values =
true;
503 Data*
const& data_pt,
507 unsigned nvalue = data_pt->
nvalue();
508 deriv.assign(nvalue, 0.0);
511 for (
unsigned j = 0; j < nvalue; j++)
513 deriv[j] = time_derivative(
i, data_pt, j);
519 Data*
const& data_pt,
523 unsigned n_tstorage = ntstorage();
526 for (
unsigned t = 0;
t < n_tstorage;
t++)
528 deriv += Weight(
i,
t) * data_pt->
value(
t, j);
537 Node*
const& node_pt,
541 unsigned nvalue = node_pt->
nvalue();
542 deriv.assign(nvalue, 0.0);
545 for (
unsigned j = 0; j < nvalue; j++)
547 deriv[j] = time_derivative(
i, node_pt, j);
556 Node*
const& node_pt,
560 unsigned n_tstorage = ntstorage();
563 for (
unsigned t = 0;
t < n_tstorage;
t++)
565 deriv += weight(
i,
t) * node_pt->
value(
t, j);
578 "Time_pt is null, probably because it is a steady time stepper.");
580 error_msg, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
594 virtual double weight(
const unsigned&
i,
const unsigned& j)
const
603 return (Weight.
ncol());
625 return Adaptive_Flag;
679 template<
unsigned NSTEPS>
690 Time_pt = &Dummy_time;
716 unsigned n_value = data_pt->
nvalue();
718 for (
unsigned j = 0; j < n_value; j++)
723 for (
unsigned t = 1;
t <= NSTEPS;
t++)
736 unsigned n_dim = node_pt->
ndim();
741 for (
unsigned i = 0;
i < n_dim;
i++)
746 for (
unsigned k = 0; k < n_position_type; k++)
748 for (
unsigned t = 1;
t <= NSTEPS;
t++)
760 typedef double (*InitialConditionFctPt)(
const double&
t);
769 unsigned n_time_value = ntstorage();
772 unsigned n_value = data_pt->
nvalue();
775 for (
unsigned t = 0;
t < n_time_value;
t++)
778 double time_local = Time_pt->time(
t);
781 for (
unsigned j = 0; j < n_value; j++)
783 data_pt->
set_value(
t, j, initial_value_fct[j](time_local));
794 unsigned n_value = data_pt->
nvalue();
797 for (
unsigned j = 0; j < n_value; j++)
803 for (
unsigned t = NSTEPS;
t > 0;
t--)
816 unsigned n_dim = node_pt->
ndim();
821 for (
unsigned i = 0;
i < n_dim;
i++)
826 for (
unsigned k = 0; k < n_position_type; k++)
829 for (
unsigned t = NSTEPS;
t > 0;
t--)
842 unsigned max_deriv = highest_derivative();
843 for (
unsigned i = 0;
i < max_deriv;
i++)
845 for (
unsigned j = 0; j < NSTEPS; j++)
868 double weight(
const unsigned&
i,
const unsigned& j)
const
870 if ((
i == 0) && (j == 0))
910 template<
unsigned NSTEPS>
937 "Can't remember the order of the Newmark scheme";
938 error_message +=
" -- I think it's 2nd order...\n";
941 error_message,
"Newmark::order()", OOMPH_EXCEPTION_LOCATION);
947 void assign_initial_values_impulsive(
Data*
const& data_pt);
951 void assign_initial_positions_impulsive(
Node*
const& node_pt);
955 typedef double (*InitialConditionFctPt)(
const double&
t);
960 void assign_initial_data_values(
961 Data*
const& data_pt,
971 typedef double (*NodeInitialConditionFctPt)(
const double&
t,
977 void assign_initial_data_values(
978 Node*
const& node_pt,
1005 void assign_initial_data_values_stage1(
const unsigned t_deriv,
1006 Data*
const& data_pt);
1017 void assign_initial_data_values_stage2(
Data*
const& data_pt);
1022 void shift_time_values(
Data*
const& data_pt);
1026 void shift_time_positions(
Node*
const& node_pt);
1072 template<
unsigned NSTEPS>
1081 this->Type =
"NewmarkBDF";
1082 Degrade_to_bdf1_for_first_derivs =
false;
1083 Newmark_veloc_weight.resize(NSTEPS + 3);
1097 void shift_time_values(
Data*
const& data_pt);
1101 void shift_time_positions(
Node*
const& node_pt);
1107 Degrade_to_bdf1_for_first_derivs =
true;
1114 Degrade_to_bdf1_for_first_derivs =
false;
1124 Newmark_veloc_weight[0] = this->Beta1 *
dt * this->Weight(2, 0);
1125 Newmark_veloc_weight[1] = this->Beta1 *
dt * this->Weight(2, 1);
1126 for (
unsigned t = 2;
t <= NSTEPS;
t++)
1128 Newmark_veloc_weight[
t] = 0.0;
1130 Newmark_veloc_weight[NSTEPS + 1] =
1131 1.0 + this->Beta1 *
dt * this->Weight(2, NSTEPS + 1);
1132 Newmark_veloc_weight[NSTEPS + 2] =
1133 dt * (1.0 - this->Beta1) +
1134 this->Beta1 *
dt * this->Weight(2, NSTEPS + 2);
1163 template<
unsigned NSTEPS>
1202 Adaptive_Flag =
true;
1206 Predictor_weight.resize(NSTEPS + 2);
1209 Weight.resize(2, NSTEPS + 3, 0.0);
1212 Predictor_storage_index = NSTEPS + 2;
1237 unsigned n_value = data_pt->
nvalue();
1239 for (
unsigned j = 0; j < n_value; j++)
1244 for (
unsigned t = 1;
t <= NSTEPS;
t++)
1250 if (adaptive_flag())
1266 unsigned n_dim = node_pt->
ndim();
1271 for (
unsigned i = 0;
i < n_dim;
i++)
1278 for (
unsigned k = 0; k < n_position_type; k++)
1281 for (
unsigned t = 1;
t <= NSTEPS;
t++)
1287 if (adaptive_flag())
1290 node_pt->
x_gen(NSTEPS + 1, k,
i) = 0.0;
1292 node_pt->
x_gen(NSTEPS + 2, k,
i) = node_pt->
x_gen(k,
i);
1302 typedef double (*InitialConditionFctPt)(
const double&
t);
1311 unsigned n_time_value = ntstorage();
1314 unsigned n_value = data_pt->
nvalue();
1317 for (
unsigned t = 0;
t < n_time_value;
t++)
1320 double time_local = Time_pt->time(
t);
1323 for (
unsigned j = 0; j < n_value; j++)
1325 data_pt->
set_value(
t, j, initial_value_fct[j](time_local));
1336 unsigned n_value = data_pt->
nvalue();
1341 const unsigned nt_value = nprev_values();
1344 if (adaptive_flag())
1346 time_derivative(1, data_pt, velocity);
1350 for (
unsigned j = 0; j < n_value; j++)
1356 for (
unsigned t = nt_value;
t > 0;
t--)
1362 if (adaptive_flag())
1365 data_pt->
set_value(nt_value + 1, j, velocity[j]);
1376 unsigned n_dim = node_pt->
ndim();
1381 unsigned n_tstorage = ntstorage();
1384 double velocity[n_position_type][n_dim];
1387 if (adaptive_flag())
1390 for (
unsigned i = 0;
i < n_dim;
i++)
1392 for (
unsigned k = 0; k < n_position_type; k++)
1395 velocity[k][
i] = 0.0;
1397 for (
unsigned t = 0;
t < n_tstorage;
t++)
1399 velocity[k][
i] += Weight(1,
t) * node_pt->
x_gen(
t, k,
i);
1406 for (
unsigned i = 0;
i < n_dim;
i++)
1412 for (
unsigned k = 0; k < n_position_type; k++)
1415 for (
unsigned t = NSTEPS;
t > 0;
t--)
1421 if (adaptive_flag())
1423 node_pt->
x_gen(NSTEPS + 1, k,
i) = velocity[k][
i];
////////////////////////////////////////////////////////////////////// //////////////////////////////...
void shift_time_values(Data *const &data_pt)
This function updates the Data's time history so that we can advance to the next timestep....
void calculate_predicted_positions(Node *const &node_pt)
Function to calculate predicted positions at a node.
void assign_initial_positions_impulsive(Node *const &node_pt)
Initialise the time-history for the nodal positions corresponding to an impulsive start.
void calculate_predicted_values(Data *const &data_pt)
Function to calculate predicted data values in a Data object.
BDF(const bool &adaptive=false)
Constructor for the case when we allow adaptive timestepping.
void assign_initial_values_impulsive(Data *const &data_pt)
Initialise the time-history for the Data values, corresponding to an impulsive start.
void set_weights()
Set the weights.
double Error_weight
Private data for the error weight.
unsigned ndt() const
Number of timestep increments that need to be stored by the scheme.
unsigned order() const
Return the actual order of the scheme.
void operator=(const BDF &)=delete
Broken assignment operator.
Vector< double > Predictor_weight
Private data for the predictor weights.
void set_predictor_weights()
Function to set the predictor weights.
double temporal_error_in_value(Data *const &data_pt, const unsigned &i)
Compute the error in the value i in a Data structure.
void shift_time_positions(Node *const &node_pt)
This function advances the time history of the positions at a node.
BDF(const BDF &)=delete
Broken copy constructor.
void assign_initial_data_values(Data *const &data_pt, Vector< InitialConditionFctPt > initial_value_fct)
Initialise the time-history for the Data values, corresponding to given time history,...
double temporal_error_in_position(Node *const &node_pt, const unsigned &i)
Compute the error in the position i at a node.
unsigned nprev_values() const
Number of previous values available.
void set_error_weights()
Function to set the error weights.
A class that represents a collection of data; each Data object may contain many different individual ...
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...
virtual bool is_a_copy() const
Return a boolean to indicate whether the Data objact contains any copied values. A base Data object c...
unsigned nvalue() const
Return number of values stored in data object (incl pinned ones).
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 ...
unsigned long nrow() const
Return the number of rows of the matrix.
unsigned long ncol() const
Return the number of columns of the matrix.
void initialise(const T &val)
Initialize all values in the matrix to val.
void resize(const unsigned long &n)
Resize to a square nxn matrix; any values already present will be transfered.
A Base class for explicit timesteppers.
////////////////////////////////////////////////////////////////////// //////////////////////////////...
void set_weights()
Set weights.
void disable_degrade_first_derivatives_to_bdf1()
Disable degradation to first order BDF.
NewmarkBDF(const NewmarkBDF &)=delete
Broken copy constructor.
bool Degrade_to_bdf1_for_first_derivs
Boolean flag to indicate degradation of scheme to first order BDF (for first derivs/veloc); usually f...
NewmarkBDF()
Constructor: Pass pointer to global time. We set up a timestepping scheme with NSTEPS+2 doubles to re...
void operator=(const NewmarkBDF &)=delete
Broken assignment operator.
Vector< double > Newmark_veloc_weight
Original Newmark weights for velocities (needed when shifting history values – they're used when upda...
void set_newmark_veloc_weights(const double &dt)
Set original Newmark weights for velocities (needed when shifting history values – they're used when ...
void enable_degrade_first_derivatives_to_bdf1()
Degrade scheme to first order BDF (for first derivs/veloc); usually for start-up.
////////////////////////////////////////////////////////////////////// //////////////////////////////...
double Beta2
Second Newmark parameter (usually 0.5)
Newmark()
Constructor: Pass pointer to global time. We set up a timestepping scheme with NSTEPS+2 doubles to re...
unsigned nprev_values() const
Number of previous values available.
unsigned ndt() const
Number of timestep increments that need to be stored by the scheme.
double Beta1
First Newmark parameter (usually 0.5)
unsigned order() const
The actual order (accuracy of the scheme)
void operator=(const Newmark &)=delete
Broken assignment operator.
Newmark(const Newmark &)=delete
Broken copy constructor.
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
double & x_gen(const unsigned &k, const unsigned &i)
Reference to the generalised position x(k,i). ‘Type’: k; Coordinate direction: i.
unsigned ndim() const
Return (Eulerian) spatial dimension of the node.
virtual bool position_is_a_copy() const
Return whether any position coordinate has been copied (always false)
unsigned nposition_type() const
Number of coordinate types needed in the mapping between local and global coordinates.
double value(const unsigned &i) const
Return i-th value (dofs or pinned) at this node either directly or via hanging node representation....
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....
////////////////////////////////////////////////////////////////// //////////////////////////////////...
////////////////////////////////////////////////////////////////////// //////////////////////////////...
void assign_initial_values_impulsive(Data *const &data_pt)
Initialise the time-history for the Data values, corresponding to an impulsive start.
void set_weights()
Set weights.
double weight(const unsigned &i, const unsigned &j) const
Dummy: Access function for j-th weight for the i-th derivative.
void operator=(const Steady &)=delete
Broken assignment operator.
void shift_time_positions(Node *const &node_pt)
This function advances the time history of the positions at a node.
static double One
Static variable to hold the value 1.0.
Steady(const Steady &)=delete
Broken copy constructor.
Steady()
Constructor: Creates storage for NSTEPS previous timesteps and can evaluate up to 2nd derivatives (th...
void assign_initial_data_values(Data *const &data_pt, Vector< InitialConditionFctPt > initial_value_fct)
Initialise the time-history for the Data values, corresponding to given time history,...
void shift_time_values(Data *const &data_pt)
This function updates the Data's time history so that we can advance to the next timestep....
static double Zero
Static variable to hold the value 0.0.
unsigned order() const
Return the actual order of the scheme. Returning zero here – doesn't make much sense,...
unsigned nprev_values() const
Number of previous values available.
void assign_initial_positions_impulsive(Node *const &node_pt)
Initialise the time-history for the nodal positions corresponding to an impulsive start.
unsigned ndt() const
Number of timestep increments that need to be stored by the scheme.
////////////////////////////////////////////////////////////////////// //////////////////////////////...
virtual unsigned ndt() const =0
Number of timestep increments that are required by the scheme.
virtual void shift_time_values(Data *const &data_pt)=0
This function advances the Data's time history so that we can move on to the next timestep.
virtual void set_weights()=0
Function to set the weights for present timestep (don't need to pass present timestep or previous tim...
TimeStepper(const TimeStepper &)=delete
Broken copy constructor.
DenseMatrix< double > Weight
Storage for the weights associated with the timestepper.
virtual unsigned nprev_values() const =0
Number of previous values available: 0 for static, 1 for BDF<1>,...
virtual void calculate_predicted_values(Data *const &data_pt)
Do the predictor step for data stored in a Data object (currently empty – overwrite for specific sche...
bool Shut_up_in_assign_initial_data_values
Boolean to indicate if the timestepper will output warnings when setting possibly an incorrect number...
virtual unsigned order() const
Actual order (accuracy) of the scheme.
virtual double temporal_error_in_value(Data *const &data_pt, const unsigned &i)
Compute the error in the value i in a Data structure zero here – overwrite for specific scheme.
virtual void set_predictor_weights()
Set the weights for the predictor previous timestep (currently empty – overwrite for specific scheme)
virtual void calculate_predicted_positions(Node *const &node_pt)
Do the predictor step for the positions at a node (currently empty — overwrite for a specific scheme)
bool Predict_by_explicit_step
Flag: is adaptivity done by taking a separate step using an ExplicitTimeStepper object?
unsigned predictor_storage_index() const
Return the time-index in each Data where predicted values are stored if the timestepper is adaptive.
Time *& time_pt()
Access function for the pointer to time (can't have a paranoid test for null pointers because this is...
void enable_warning_in_assign_initial_data_values()
Enable the output of warnings due to possible fct pointer vector size mismatch in assign_initial_data...
virtual void actions_before_timestep(Problem *problem_pt)
Interface for any actions that need to be performed before a time step.
void check_predicted_values_up_to_date() const
Check that the predicted values are the ones we want.
Time * Time_pt
Pointer to discrete time storage scheme.
unsigned ntstorage() const
Return the number of doubles required to represent history (one for steady)
std::string Type
String that indicates the type of the timestepper (e.g. "BDF", "Newmark", etc.)
virtual void actions_after_timestep(Problem *problem_pt)
Interface for any actions that need to be performed after a time step.
void time_derivative(const unsigned &i, Node *const &node_pt, Vector< double > &deriv)
Evaluate i-th derivative of all values in Node and return in Vector deriv[] (this can't be simply com...
ExplicitTimeStepper * Explicit_predictor_pt
Pointer to explicit time stepper to use as predictor if Predict_by_explicit_step is set....
virtual double weight(const unsigned &i, const unsigned &j) const
Access function for j-th weight for the i-th derivative.
virtual void shift_time_positions(Node *const &node_pt)=0
This function advances the time history of the positions at a node. The default should be OK,...
bool Is_steady
Bool to indicate if the timestepper is steady, i.e. its time-derivatives evaluate to zero....
virtual unsigned nprev_values_for_value_at_evaluation_time() const
Number of previous values needed to calculate the value at the current time. i.e. how many previous v...
bool adaptive_flag() const
Function to indicate whether the scheme is adaptive (false by default)
TimeStepper()
Broken empty constructor.
void operator=(const TimeStepper &)=delete
Broken assignment operator.
virtual void assign_initial_values_impulsive(Data *const &data_pt)=0
Initialise the time-history for the Data values corresponding to an impulsive start.
void disable_warning_in_assign_initial_data_values()
Disable the output of warnings due to possible fct pointer vector size mismatch in assign_initial_dat...
void time_derivative(const unsigned &i, Data *const &data_pt, Vector< double > &deriv)
Evaluate i-th derivative of all values in Data and return in Vector deriv[].
void make_steady()
Function to make the time stepper temporarily steady. This is trivially achieved by setting all the w...
TimeStepper(const unsigned &tstorage, const unsigned &max_deriv)
Constructor. Pass the amount of storage required by timestepper (present value + history values) and ...
unsigned highest_derivative() const
Highest order derivative that the scheme can compute.
virtual void undo_make_steady()
Reset the is_steady status of a specific TimeStepper to its default and re-assign the weights.
double time() const
Return current value of continous time.
ExplicitTimeStepper * explicit_predictor_pt()
Get the pointer to the explicit timestepper to use as a predictor in adaptivity if Predict_by_explici...
virtual void assign_initial_positions_impulsive(Node *const &node_pt)=0
Initialiset the positions for the node corresponding to an impulsive start.
double time_derivative(const unsigned &i, Data *const &data_pt, const unsigned &j)
Evaluate i-th derivative of j-th value in Data.
double & time()
Return current value of continous time.
void update_predicted_time(const double &new_time)
Set the time that the current predictions apply for, only needed for paranoid checks when doing Predi...
bool predict_by_explicit_step() const
Flag: is adaptivity done by taking a separate step using an ExplicitTimeStepper object?
virtual double temporal_error_in_position(Node *const &node_pt, const unsigned &i)
Compute the error in the position i at a node zero here – overwrite for specific scheme.
const DenseMatrix< double > * weights_pt() const
Get a (const) pointer to the weights.
std::string type() const
Return string that indicates the type of the timestepper (e.g. "BDF", "Newmark", etc....
bool is_steady() const
Flag to indicate if a timestepper has been made steady (possibly temporarily to switch off time-depen...
virtual void set_error_weights()
Set the weights for the error computation, (currently empty – overwrite for specific scheme)
double time_derivative(const unsigned &i, Node *const &node_pt, const unsigned &j)
Evaluate i-th derivative of j-th value in Node. Note the use of the node's value() function so that h...
double Predicted_time
Store the time that the predicted values currently stored are at, to compare for paranoid checks.
Time *const & time_pt() const
Access function for the pointer to time (const version)
int Predictor_storage_index
The time-index in each Data object where predicted values are stored. -1 if not set.
bool Adaptive_Flag
Boolean variable to indicate whether the timestepping scheme can be adaptive.
void set_predictor_pt(ExplicitTimeStepper *_pred_pt)
Set the pointer to the explicit timestepper to use as a predictor in adaptivity if Predict_by_explici...
Class to keep track of discrete/continous time. It is essential to have a single Time object when usi...
double Continuous_time
Pointer to the value of the continuous time.
double & dt(const unsigned &t=0)
Return the value of the t-th stored timestep (t=0: present; t>0: previous).
Time(const Time &)=delete
Broken copy constructor.
void operator=(const Time &)=delete
Broken assignment operator.
Vector< double > Dt
Vector that stores the values of the current and previous timesteps.
double time(const unsigned &t=0) const
Return the value of the continuous time at the t-th previous time level (t=0: current; t>0 previous).
double dt(const unsigned &t=0) const
Return the value of the t-th stored timestep (t=0: present; t>0: previous), const version.
double & time()
Return the current value of the continuous time.
void initialise_dt(const Vector< double > &dt_)
Set the value of the timesteps to be equal to the values passed in a vector.
void shift_dt()
Update all stored values of dt by shifting each value along the array. This function must be called b...
void initialise_dt(const double &dt_)
Set all timesteps to the same value, dt.
unsigned ndt() const
Return the number of timesteps stored.
void resize(const unsigned &n_dt)
Resize the vector holding the number of previous timesteps and initialise the new values to zero.
Time()
Constructor: Do not allocate any storage for previous timesteps, but set the initial value of the tim...
~Time()
Destructor: empty.
Time(const unsigned &ndt)
Constructor: Pass the number of timesteps to be stored and set the initial value of time to zero.
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn't been defined.
double Zero
Static variable to hold the default value for the pseudo-solid's inertia parameter Lambda^2.
std::string to_string(T object, unsigned float_precision=8)
Conversion function that should work for anything with operator<< defined (at least all basic types).
//////////////////////////////////////////////////////////////////// ////////////////////////////////...