34 #ifndef OOMPH_TIME_STEPPERS_HEADER 35 #define OOMPH_TIME_STEPPERS_HEADER 39 #include <oomph-lib-config.h> 55 class ExplicitTimeStepper;
81 Time() : Continuous_time(0.0) {}
85 Time(
const unsigned &
ndt) : Continuous_time(0.0)
106 void resize(
const unsigned &n_dt) {Dt.resize(n_dt,0.0);}
111 unsigned ndt = Dt.size();
122 unsigned n_dt=dt_.size();
123 for (
unsigned i=0;
i<n_dt;
i++) {Dt[
i]=dt_[
i];}
133 unsigned ndt()
const {
return Dt.size();}
137 double&
dt(
const unsigned &
t=0) {
return Dt[
t];}
141 double dt(
const unsigned &
t=0)
const {
return Dt[
t];}
145 double time(
const unsigned &
t=0)
const 150 using namespace StringConversion;
153 OOMPH_EXCEPTION_LOCATION);
159 for (
unsigned i=0;
i<
t;
i++) {time_local -= Dt[
i];}
168 unsigned n_dt=Dt.size();
170 if(n_dt == 0) {
return;}
172 for (
unsigned i=(n_dt-1);
i>0;
i--) {Dt[
i]=Dt[
i-1];}
272 Adaptive_Flag(false),
274 Shut_up_in_assign_initial_data_values(false),
275 Predict_by_explicit_step(false)
278 Weight.
resize(max_deriv+1,tstorage,0.0);
286 Predictor_storage_index = -1;
288 Explicit_predictor_pt = 0;
294 throw OomphLibError(
"Don't call default constructor for TimeStepper!",
295 OOMPH_CURRENT_FUNCTION,
296 OOMPH_EXCEPTION_LOCATION);
316 {
return Weight.
nrow()-1;}
319 virtual unsigned order()
const {
return 0;}
334 OOMPH_EXCEPTION_LOCATION);
337 return Time_pt->
time();
341 virtual unsigned ndt()
const=0;
351 virtual unsigned nprev_values()
const=0;
356 virtual void set_weights()=0;
384 return Predict_by_explicit_step;
395 Explicit_predictor_pt = _pred_pt;
402 Predicted_time = new_time;
409 if(std::abs(time_pt()->
time() - Predicted_time) > 1
e-15)
411 throw OomphLibError(
"Predicted values are not from the correct time step",
412 OOMPH_EXCEPTION_LOCATION,
413 OOMPH_CURRENT_FUNCTION);
426 if(Predictor_storage_index > 0)
428 return unsigned(Predictor_storage_index);
432 std::string err =
"Predictor storage index is negative, this probably";
433 err +=
" means it hasn't been set for this timestepper.";
435 OOMPH_CURRENT_FUNCTION);
438 return unsigned(Predictor_storage_index);
445 {Shut_up_in_assign_initial_data_values=
false;}
450 {Shut_up_in_assign_initial_data_values=
true;}
478 unsigned nvalue=data_pt->
nvalue();
479 deriv.assign(nvalue, 0.0);
482 for(
unsigned j=0;j<nvalue;j++)
484 deriv[j]=time_derivative(i, data_pt, j);
493 unsigned n_tstorage = ntstorage();
496 for(
unsigned t=0;
t<n_tstorage;
t++)
498 deriv+=Weight(i,
t)*data_pt->
value(
t,j);
510 unsigned nvalue = node_pt->
nvalue();
511 deriv.assign(nvalue, 0.0);
514 for(
unsigned j=0;j<nvalue;j++)
516 deriv[j]=time_derivative(i, node_pt, j);
528 unsigned n_tstorage = ntstorage();
531 for(
unsigned t=0;
t<n_tstorage;
t++)
533 deriv+=weight(i,
t)*node_pt->
value(
t,j);
544 std::string error_msg(
"Time_pt is null, probably because it is a steady time stepper.");
546 OOMPH_EXCEPTION_LOCATION);
557 virtual double weight(
const unsigned &
i,
const unsigned &j)
const 558 {
return Weight(i,j);}
563 {
return (Weight.
ncol());}
567 virtual void assign_initial_values_impulsive(
Data*
const &data_pt)=0;
571 virtual void assign_initial_positions_impulsive(
Node*
const &node_pt)=0;
575 virtual void shift_time_values(
Data*
const &data_pt)=0;
579 virtual void shift_time_positions(
Node*
const &node_pt)=0;
632 template<
unsigned NSTEPS>
674 unsigned n_value = data_pt->
nvalue();
676 for(
unsigned j=0;j<n_value;j++)
681 for(
unsigned t=1;
t<=NSTEPS;
t++)
694 unsigned n_dim = node_pt->
ndim();
699 for(
unsigned i=0;
i<n_dim;
i++)
704 for(
unsigned k=0;k<n_position_type;k++)
706 for(
unsigned t=1;
t<=NSTEPS;
t++)
718 typedef double (*InitialConditionFctPt)(
const double&
t);
728 unsigned n_time_value = ntstorage();
731 unsigned n_value = data_pt->
nvalue();
734 for(
unsigned t=0;
t<n_time_value;
t++)
737 double time_local=Time_pt->time(
t);
740 for(
unsigned j=0;j<n_value;j++)
742 data_pt->
set_value(
t,j,initial_value_fct[j](time_local));
753 unsigned n_value = data_pt->
nvalue();
756 for(
unsigned j=0;j<n_value;j++)
762 for(
unsigned t=NSTEPS;
t>0;
t--)
775 unsigned n_dim = node_pt->
ndim();
780 for(
unsigned i=0;
i<n_dim;
i++)
785 for(
unsigned k=0;k<n_position_type;k++)
788 for(
unsigned t=NSTEPS;
t>0;
t--)
801 unsigned max_deriv=highest_derivative();
802 for (
unsigned i=0;
i<max_deriv;
i++)
804 for (
unsigned j=0;j<NSTEPS;j++)
818 unsigned ndt()
const {
return NSTEPS;}
821 double weight(
const unsigned &
i,
const unsigned &j)
const 867 template<
unsigned NSTEPS>
902 "Can't remember the order of the Newmark scheme";
903 error_message +=
" -- I think it's 2nd order...\n";
906 OOMPH_EXCEPTION_LOCATION);
912 void assign_initial_values_impulsive(
Data*
const &data_pt);
916 void assign_initial_positions_impulsive(
Node*
const &node_pt);
920 typedef double (*InitialConditionFctPt)(
const double&
t);
925 void assign_initial_data_values(
Data*
const & data_pt,
938 typedef double (*NodeInitialConditionFctPt)(
const double&
t,
944 void assign_initial_data_values(
Node*
const & node_pt,
974 void assign_initial_data_values_stage1(
const unsigned t_deriv,
975 Data*
const &data_pt);
986 void assign_initial_data_values_stage2(
Data*
const &data_pt);
991 void shift_time_values(
Data*
const &data_pt);
995 void shift_time_positions(
Node*
const &node_pt);
1004 unsigned ndt()
const {
return NSTEPS;}
1038 template<
unsigned NSTEPS>
1048 this->Type=
"NewmarkBDF";
1049 Degrade_to_bdf1_for_first_derivs=
false;
1050 Newmark_veloc_weight.resize(NSTEPS+3);
1070 void shift_time_values(
Data*
const &data_pt);
1074 void shift_time_positions(
Node*
const &node_pt);
1080 Degrade_to_bdf1_for_first_derivs=
true;
1087 Degrade_to_bdf1_for_first_derivs=
false;
1099 Newmark_veloc_weight[0]=this->Beta1*dt*this->Weight(2,0);
1100 Newmark_veloc_weight[1]=this->Beta1*dt*this->Weight(2,1);
1101 for (
unsigned t=2;
t<=NSTEPS;
t++)
1103 Newmark_veloc_weight[
t]=0.0;
1105 Newmark_veloc_weight[NSTEPS+1]=
1106 1.0+this->Beta1*dt*this->Weight(2,NSTEPS+1);
1107 Newmark_veloc_weight[NSTEPS+2]=
1108 dt*(1.0-this->Beta1)+this->Beta1*dt*this->Weight(2,NSTEPS+2);
1140 template<
unsigned NSTEPS>
1181 Adaptive_Flag =
true;
1185 Predictor_weight.resize(NSTEPS+2);
1188 Weight.resize(2, NSTEPS+3, 0.0);
1191 Predictor_storage_index = NSTEPS + 2;
1219 unsigned n_value = data_pt->
nvalue();
1221 for(
unsigned j=0;j<n_value;j++)
1226 for(
unsigned t=1;
t<=NSTEPS;
t++)
1248 unsigned n_dim = node_pt->
ndim();
1253 for(
unsigned i=0;
i<n_dim;
i++)
1260 for(
unsigned k=0;k<n_position_type;k++)
1263 for(
unsigned t=1;
t<=NSTEPS;
t++)
1272 node_pt->
x_gen(NSTEPS+1,k,
i) = 0.0;
1284 typedef double (*InitialConditionFctPt)(
const double&
t);
1294 unsigned n_time_value = ntstorage();
1297 unsigned n_value = data_pt->
nvalue();
1300 for(
unsigned t=0;
t<n_time_value;
t++)
1304 double time_local=Time_pt->time(
t);
1307 for(
unsigned j=0;j<n_value;j++)
1309 data_pt->
set_value(
t,j,initial_value_fct[j](time_local));
1320 unsigned n_value = data_pt->
nvalue();
1325 const unsigned nt_value = nprev_values();
1328 if(adaptive_flag()) {time_derivative(1,data_pt,velocity);}
1331 for(
unsigned j=0;j<n_value;j++)
1337 for(
unsigned t=nt_value;
t>0;
t--)
1346 data_pt->
set_value(nt_value+1, j, velocity[j]);
1357 unsigned n_dim = node_pt->
ndim();
1362 unsigned n_tstorage = ntstorage();
1365 double velocity[n_position_type][n_dim];
1371 for(
unsigned i=0;
i<n_dim;
i++)
1373 for(
unsigned k=0;k<n_position_type;k++)
1376 velocity[k][
i] =0.0;
1378 for(
unsigned t=0;
t<n_tstorage;
t++)
1380 velocity[k][
i] += Weight(1,
t)*node_pt->
x_gen(
t,k,
i);
1387 for(
unsigned i=0;
i<n_dim;
i++)
1393 for(
unsigned k=0;k<n_position_type;k++)
1396 for(
unsigned t=NSTEPS;
t>0;
t--)
1404 node_pt->
x_gen(NSTEPS+1,k,
i) = velocity[k][
i];
1418 unsigned ndt()
const {
return NSTEPS;}
1421 void set_predictor_weights();
1424 void calculate_predicted_positions(
Node*
const &node_pt);
1427 void calculate_predicted_values(
Data*
const &data_pt);
1430 void set_error_weights();
1433 double temporal_error_in_position(
Node*
const &node_pt,
1437 double temporal_error_in_value(
Data*
const &data_pt,
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 assign_initial_positions_impulsive(Node *const &node_pt)
Initialise the time-history for the nodal positions corresponding to an impulsive start...
void enable_degrade_first_derivatives_to_bdf1()
Degrade scheme to first order BDF (for first derivs/veloc); usually for start-up. ...
void make_steady()
Function to make the time stepper temporarily steady. This is trivially achieved by setting all the w...
virtual double temporal_error_in_value(Data *const &data_pt, const unsigned &i)
Vector< double > Predictor_weight
Private data for the predictor weights.
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 ...
virtual double temporal_error_in_position(Node *const &node_pt, const unsigned &i)
void broken_copy(const std::string &class_name)
Issue error message and terminate execution.
void operator=(const BDF &)
Broken assignment operator.
TimeStepper()
Broken empty constructor.
unsigned long nrow() const
Return the number of rows of the matrix.
Steady(const Steady &)
Broken copy constructor.
virtual void actions_after_timestep(Problem *problem_pt)
Newmark(const Newmark &)
Broken copy constructor.
void initialise(const T &val)
Initialize all values in the matrix to val.
void operator=(const NewmarkBDF &)
Broken assignment operator.
bool Shut_up_in_assign_initial_data_values
Boolean to indicate if the timestepper will output warnings when setting possibly an incorrect number...
BDF(const BDF &)
Broken copy constructor.
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)...
unsigned long ncol() const
Return the number of columns of the matrix.
double Error_weight
Private data for the error weight.
Newmark()
Constructor: Pass pointer to global time. We set up a timestepping scheme with NSTEPS+2 doubles to re...
unsigned ndt() const
Number of timestep increments that need to be stored by the scheme.
Time(const Time &)
Broken copy constructor.
double Beta1
First Newmark parameter (usually 0.5)
static double Zero
Static variable to hold the value 0.0.
virtual void set_predictor_weights()
Set the weights for the predictor previous timestep (currently empty – overwrite for specific scheme...
double & time()
Return current value of continous time.
Class to keep track of discrete/continous time. It is essential to have a single Time object when usi...
std::string Type
String that indicates the type of the timestepper (e.g. "BDF", "Newmark", etc.)
unsigned nprev_values() const
Number of previous values available.
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. For BDF schemes, we simply push the values backwards...
ExplicitTimeStepper * Explicit_predictor_pt
void shift_dt()
Update all stored values of dt by shifting each value along the array. This function must be called b...
Vector< double > Newmark_veloc_weight
Original Newmark weights for velocities (needed when shifting history values – they're used when upd...
unsigned order() const
The actual order (accuracy of the scheme)
unsigned order() const
Return the actual order of the scheme.
void check_predicted_values_up_to_date() const
Check that the predicted values are the ones we want.
void shift_time_positions(Node *const &node_pt)
This function advances the time history of the positions at a node.
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
Templated class for BDF-type time-steppers with fixed or variable timestep. 1st time derivative recov...
Time(const unsigned &ndt)
Constructor: Pass the number of timesteps to be stored and set the initial value of time to zero...
int Predictor_storage_index
The time-index in each Data object where predicted values are stored. -1 if not set.
static double One
Static variable to hold the value 1.0.
unsigned nvalue() const
Return number of values stored in data object (incl pinned ones).
NewmarkBDF()
Constructor: Pass pointer to global time. We set up a timestepping scheme with NSTEPS+2 doubles to re...
const DenseMatrix< double > * weights_pt() const
Get a (const) pointer to the weights.
bool Predict_by_explicit_step
Flag: is adaptivity done by taking a separate step using an ExplicitTimeStepper object?
void operator=(const Newmark &)
Broken assignment operator.
double Beta2
Second Newmark parameter (usually 0.5)
bool Is_steady
Bool to indicate if the timestepper is steady, i.e. its time-derivatives evaluate to zero...
Newmark scheme for second time deriv. Stored data represents.
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...
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, specified by Vector of function pointers.
unsigned ndim() const
Return (Eulerian) spatial dimension of the node.
void shift_time_positions(Node *const &node_pt)
This function advances the time history of the positions at a node.
double dt(const unsigned &t=0) const
DenseMatrix< double > Weight
Storage for the weights associated with the timestepper.
unsigned ndt() const
Number of timestep increments that need to be stored by the scheme.
double Zero
Static variable to hold the default value for the pseudo-solid's inertia parameter Lambda^2...
void initialise_dt(const Vector< double > &dt_)
Set the value of the timesteps to be equal to the values passed in a vector.
void set_weights()
Set weights.
void set_newmark_veloc_weights(const double &dt)
Set original Newmark weights for velocities (needed when shifting history values – they're used when...
ExplicitTimeStepper * explicit_predictor_pt()
bool adaptive_flag() const
Function to indicate whether the scheme is adaptive (false by default)
void set_predictor_pt(ExplicitTimeStepper *_pred_pt)
void update_predicted_time(const double &new_time)
TimeStepper(const unsigned &tstorage, const unsigned &max_deriv)
Constructor. Pass the amount of storage required by timestepper (present value + history values) and ...
TimeStepper(const TimeStepper &)
Broken copy constructor.
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...
double & dt(const unsigned &t=0)
unsigned nposition_type() const
Number of coordinate types needed in the mapping between local and global coordinates.
virtual void actions_before_timestep(Problem *problem_pt)
void operator=(const TimeStepper &)
Broken assignment operator.
Time()
Constructor: Do not allocate any storage for previous timesteps, but set the initial value of the tim...
Time * Time_pt
Pointer to discrete time storage scheme.
bool predict_by_explicit_step() const
Flag: is adaptivity done by taking a separate step using an ExplicitTimeStepper object?
unsigned ndt() const
Return the number of timesteps stored.
A class that represents a collection of data; each Data object may contain many different individual ...
double & x_gen(const unsigned &k, const unsigned &i)
Reference to the generalised position x(k,i).
void operator=(const Steady &)
Broken assignment operator.
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...
unsigned highest_derivative() const
Highest order derivative that the scheme can compute.
BDF(const bool &adaptive=false)
Constructor for the case when we allow adaptive timestepping.
void assign_initial_positions_impulsive(Node *const &node_pt)
Initialise the time-history for the nodal positions corresponding to an impulsive start...
double & time()
Return the current value of the continuous time.
virtual unsigned order() const
Actual order (accuracy) of the scheme.
double weight(const unsigned &i, const unsigned &j) const
Dummy: Access function for j-th weight for the i-th derivative.
unsigned order() const
Return the actual order of the scheme. Returning zero here – doesn't make much sense, though.
unsigned ntstorage() const
Return the number of doubles required to represent history (one for steady)
virtual void undo_make_steady()
Reset the is_steady status of a specific TimeStepper to its default and re-assign the weights...
bool Adaptive_Flag
Boolean variable to indicate whether the timestepping scheme can be adaptive.
Vector< double > Dt
Vector that stores the values of the current and previous timesteps.
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, specified by Vector of function pointers.
~Time()
Destructor: empty.
std::string type() const
Return string that indicates the type of the timestepper (e.g. "BDF", "Newmark", etc.)
void broken_assign(const std::string &class_name)
Issue error message and terminate execution.
void initialise_dt(const double &dt_)
Set all timesteps to the same value, dt.
Newmark scheme for second time deriv with first derivatives calculated using BDF. ...
double time_derivative(const unsigned &i, Data *const &data_pt, const unsigned &j)
Evaluate i-th derivative of j-th value in Data.
void assign_initial_values_impulsive(Data *const &data_pt)
Initialise the time-history for the Data values, corresponding to an impulsive start.
void resize(const unsigned &n_dt)
Resize the vector holding the number of previous timesteps and initialise the new values to zero...
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...
unsigned ndt() const
Number of timestep increments that need to be stored by the scheme.
Time *const & time_pt() const
Access function for the pointer to time (const version)
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. As for BDF schemes, we simply push the values backwards...
bool Degrade_to_bdf1_for_first_derivs
Boolean flag to indicate degradation of scheme to first order BDF (for first derivs/veloc); usually f...
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn't been defined.
unsigned nprev_values() const
Number of previous values available.
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 sch...
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...
virtual bool position_is_a_copy() const
Return whether any position coordinate has been copied (always false)
double time() const
Return current value of continous time.
unsigned nprev_values() const
Number of previous values available.
NewmarkBDF(const NewmarkBDF &)
Broken copy constructor.
bool is_steady() const
Flag to indicate if a timestepper has been made steady (possibly temporarily to switch off time-depen...
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[].
unsigned predictor_storage_index() const
Return the time-index in each Data where predicted values are stored if the timestepper is adaptive...
virtual bool is_a_copy() const
Return a boolean to indicate whether the Data objact contains any copied values. A base Data object c...
A Base class for explicit timesteppers.
double Continuous_time
Pointer to the value of the continuous time.
Base class for time-stepping schemes. Timestepper provides an approximation of the temporal derivativ...
virtual double weight(const unsigned &i, const unsigned &j) const
Access function for j-th weight for the i-th derivative.
void operator=(const Time &)
Broken assignment operator.
virtual void set_error_weights()
Set the weights for the error computation, (currently empty – overwrite for specific scheme) ...
double value(const unsigned &i) const
Return i-th value (dofs or pinned) at this node either directly or via hanging node representation...
Steady()
Constructor: Creates storage for NSTEPS previous timesteps and can evaluate up to 2nd derivatives (th...
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)...
void assign_initial_values_impulsive(Data *const &data_pt)
Initialise the time-history for the Data values, corresponding to an impulsive start.
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...
void disable_degrade_first_derivatives_to_bdf1()
Disable degradation to first order BDF.
void resize(const unsigned long &n)