51 template<
unsigned NSTEPS>
54 template<
unsigned NSTEPS>
57 template<
unsigned NSTEPS>
82 double dt = Time_pt->dt(0);
83 Weight(1, 0) = 1.0 / dt;
84 Weight(1, 1) = -1.0 / dt;
97 double dt = Time_pt->dt(0);
100 Predictor_weight[0] = 0.0;
101 Predictor_weight[1] = 1.0;
104 Predictor_weight[2] = dt;
121 unsigned n_value = data_pt->
nvalue();
123 for (
unsigned j = 0; j < n_value; j++)
129 double predicted_value = 0.0;
132 for (
unsigned i = 1;
i < 3;
i++)
134 predicted_value += data_pt->
value(
i, j) * Predictor_weight[
i];
137 data_pt->
set_value(Predictor_storage_index, j, predicted_value);
154 unsigned n_dim = node_pt->
ndim();
156 for (
unsigned j = 0; j < n_dim; j++)
162 double predicted_value = 0.0;
165 for (
unsigned i = 1;
i < 3;
i++)
167 predicted_value += node_pt->
x(
i, j) * Predictor_weight[
i];
170 node_pt->
x(Predictor_storage_index, j) = predicted_value;
196 return Error_weight *
197 (node_pt->
x(
i) - node_pt->
x(Predictor_storage_index,
i));
216 return Error_weight *
217 (data_pt->
value(
i) - data_pt->
value(Predictor_storage_index,
i));
234 double dt = Time_pt->dt(0);
235 double dtprev = Time_pt->dt(1);
236 Weight(1, 0) = 1.0 / dt + 1.0 / (dt + dtprev);
237 Weight(1, 1) = -(dt + dtprev) / (dt * dtprev);
238 Weight(1, 2) = dt / ((dt + dtprev) * dtprev);
259 double dt = Time_pt->dt(0);
260 double dtprev = Time_pt->dt(1);
263 Predictor_weight[0] = 0.0;
264 Predictor_weight[1] = 1.0 - (dt * dt) / (dtprev * dtprev);
265 Predictor_weight[2] = (dt * dt) / (dtprev * dtprev);
267 Predictor_weight[3] = (1.0 + dt / dtprev) * dt;
283 unsigned n_value = data_pt->
nvalue();
285 for (
unsigned j = 0; j < n_value; j++)
291 double predicted_value = 0.0;
294 for (
unsigned i = 1;
i < 4;
i++)
296 predicted_value += data_pt->
value(
i, j) * Predictor_weight[
i];
300 data_pt->
set_value(Predictor_storage_index, j, predicted_value);
316 unsigned n_dim = node_pt->
ndim();
318 for (
unsigned j = 0; j < n_dim; j++)
324 double predicted_value = 0.0;
327 for (
unsigned i = 1;
i < 4;
i++)
329 predicted_value += node_pt->
x(
i, j) * Predictor_weight[
i];
332 node_pt->
x(Predictor_storage_index, j) = predicted_value;
347 double dt = Time_pt->dt(0);
348 double dtprev = Time_pt->dt(1);
351 pow((1.0 + dtprev / dt), 2.0) /
352 (1.0 + 3.0 * (dtprev / dt) + 4.0 * pow((dtprev / dt), 2.0) +
353 2.0 * pow((dtprev / dt), 3.0));
368 return Error_weight *
369 (node_pt->
x(
i) - node_pt->
x(Predictor_storage_index,
i));
388 return Error_weight *
389 (data_pt->
value(
i) - data_pt->
value(Predictor_storage_index,
i));
405 double dt0 = Time_pt->dt(0);
406 for (
unsigned i = 0;
i < Time_pt->ndt();
i++)
408 if (dt0 != Time_pt->dt(
i))
410 throw OomphLibError(
"BDF4 currently only works for fixed timesteps \n",
411 OOMPH_CURRENT_FUNCTION,
412 OOMPH_EXCEPTION_LOCATION);
416 double dt = Time_pt->dt(0);
417 Weight(1, 0) = 25.0 / 12.0 / dt;
418 Weight(1, 1) = -48.0 / 12.0 / dt;
419 Weight(1, 2) = 36.0 / 12.0 / dt;
420 Weight(1, 3) = -16.0 / 12.0 / dt;
421 Weight(1, 4) = 3.0 / 12.0 / dt;
436 "Not implemented yet", OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
448 "Not implemented yet", OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
456 "Not implemented yet", OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
464 "Not implemented yet", OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
475 "Not implemented yet", OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
488 "Not implemented yet", OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
502 template<
unsigned NSTEPS>
506 unsigned n_value = data_pt->
nvalue();
509 for (
unsigned j = 0; j < n_value; j++)
514 for (
unsigned t = 1;
t <= NSTEPS;
t++)
531 template<
unsigned NSTEPS>
535 unsigned n_dim = node_pt->
ndim();
540 for (
unsigned i = 0;
i < n_dim;
i++)
546 for (
unsigned k = 0; k < n_position_type; k++)
549 for (
unsigned t = 1;
t <= NSTEPS;
t++)
555 node_pt->
x_gen(NSTEPS + 1, k,
i) = 0.0;
556 node_pt->
x_gen(NSTEPS + 2, k,
i) = 0.0;
568 template<
unsigned NSTEPS>
570 Data*
const& data_pt,
580 if (initial_value_fct.size() != initial_veloc_fct.size() ||
581 initial_value_fct.size() != initial_accel_fct.size())
583 throw OomphLibError(
"The Vectors of fcts for values, velocities and "
584 "acceleration must be the same size",
585 OOMPH_CURRENT_FUNCTION,
586 OOMPH_EXCEPTION_LOCATION);
591 unsigned n_fcts = initial_value_fct.size();
596 unsigned n_value = data_pt->
nvalue();
597 if (n_value > n_fcts && !Shut_up_in_assign_initial_data_values)
599 std::stringstream message;
600 message <<
"There are more data values than initial value fcts.\n";
601 message <<
"Only the first " << n_fcts <<
" data values will be set\n";
603 message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
608 for (
unsigned j = 0; j < n_fcts; j++)
610 if (initial_value_fct[j] == 0)
613 if (!Shut_up_in_assign_initial_data_values)
615 std::stringstream message;
616 message <<
"Ignoring value " << j <<
" in assignment of ic.\n";
618 "Newmark<NSTEPS>::assign_initial_data_values",
619 OOMPH_EXCEPTION_LOCATION);
626 for (
unsigned t = 0;
t <= NSTEPS;
t++)
628 double time_local = Time_pt->time(
t);
629 data_pt->
set_value(
t, j, initial_value_fct[j](time_local));
639 double time_ = Time_pt->time();
640 double U = initial_value_fct[j](time_);
643 time_ = Time_pt->time(1);
644 double U0 = initial_value_fct[j](time_);
648 time_ = Time_pt->time(0);
649 double Udot = initial_veloc_fct[j](time_);
653 time_ = Time_pt->time(0);
654 double Udotdot = initial_accel_fct[j](time_);
657 vect[0] = Udotdot - Weight(2, 0) *
U - Weight(2, 1) * U0;
658 vect[1] = Udot - Weight(1, 0) *
U - Weight(1, 1) * U0;
661 matrix(0, 0) = Weight(2, NSTEPS + 1);
662 matrix(0, 1) = Weight(2, NSTEPS + 2);
663 matrix(1, 0) = Weight(1, NSTEPS + 1);
664 matrix(1, 1) = Weight(1, NSTEPS + 2);
671 data_pt->
set_value(NSTEPS + 1, j, vect[0]);
676 data_pt->
set_value(NSTEPS + 2, j, vect[1]);
687 template<
unsigned NSTEPS>
689 Node*
const& node_pt,
700 if (initial_value_fct.size() != initial_veloc_fct.size() ||
701 initial_value_fct.size() != initial_accel_fct.size())
703 throw OomphLibError(
"The Vectors of fcts for values, velocities and "
704 "acceleration must be the same size",
705 "Newmark<NSTEPS>::assign_initial_data_values",
706 OOMPH_EXCEPTION_LOCATION);
711 unsigned n_fcts = initial_value_fct.size();
716 unsigned n_value = node_pt->
nvalue();
717 if (n_value > n_fcts && !Shut_up_in_assign_initial_data_values)
719 std::stringstream message;
720 message <<
"There are more nodal values than initial value fcts.\n";
721 message <<
"Only the first " << n_fcts <<
" nodal values will be set\n";
723 message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
728 unsigned n_dim = node_pt->
ndim();
730 for (
unsigned i = 0;
i < n_dim;
i++) x[
i] = node_pt->
x(
i);
733 for (
unsigned j = 0; j < n_fcts; j++)
735 if (initial_value_fct[j] == 0)
738 if (!Shut_up_in_assign_initial_data_values)
740 std::stringstream message;
741 message <<
"Ignoring value " << j <<
" in assignment of ic.\n";
743 message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
750 for (
unsigned t = 0;
t <= NSTEPS;
t++)
752 double time_local = Time_pt->time(
t);
753 node_pt->
set_value(
t, j, initial_value_fct[j](time_local, x));
763 double time_ = Time_pt->time();
764 double U = initial_value_fct[j](time_, x);
767 time_ = Time_pt->time(1);
768 double U0 = initial_value_fct[j](time_, x);
772 time_ = Time_pt->time(0);
773 double Udot = initial_veloc_fct[j](time_, x);
777 time_ = Time_pt->time(0);
778 double Udotdot = initial_accel_fct[j](time_, x);
781 vect[0] = Udotdot - Weight(2, 0) *
U - Weight(2, 1) * U0;
782 vect[1] = Udot - Weight(1, 0) *
U - Weight(1, 1) * U0;
785 matrix(0, 0) = Weight(2, NSTEPS + 1);
786 matrix(0, 1) = Weight(2, NSTEPS + 2);
787 matrix(1, 0) = Weight(1, NSTEPS + 1);
788 matrix(1, 1) = Weight(1, NSTEPS + 2);
795 node_pt->
set_value(NSTEPS + 1, j, vect[0]);
800 node_pt->
set_value(NSTEPS + 2, j, vect[1]);
830 template<
unsigned NSTEPS>
832 const unsigned t_deriv,
Data*
const& data_pt)
835 unsigned n_value = data_pt->
nvalue();
838 for (
unsigned j = 0; j < n_value; j++)
865 std::ostringstream error_message_stream;
866 error_message_stream <<
"t_deriv " << t_deriv
867 <<
" is not possible with a Newmark scheme "
871 OOMPH_CURRENT_FUNCTION,
872 OOMPH_EXCEPTION_LOCATION);
888 template<
unsigned NSTEPS>
892 unsigned n_value = data_pt->
nvalue();
895 for (
unsigned j = 0; j < n_value; j++)
902 double U = data_pt->
value(1, j);
905 double U0 = data_pt->
value(0, j);
908 double Udot = data_pt->
value(NSTEPS + 1, j);
911 double Udotdot = data_pt->
value(NSTEPS + 2, j);
914 vect[0] = Udotdot - Weight(2, 0) *
U - Weight(2, 1) * U0;
915 vect[1] = Udot - Weight(1, 0) *
U - Weight(1, 1) * U0;
918 matrix(0, 0) = Weight(2, NSTEPS + 1);
919 matrix(0, 1) = Weight(2, NSTEPS + 2);
920 matrix(1, 0) = Weight(1, NSTEPS + 1);
921 matrix(1, 1) = Weight(1, NSTEPS + 2);
937 data_pt->
set_value(NSTEPS + 1, j, vect[0]);
940 data_pt->
set_value(NSTEPS + 2, j, vect[1]);
949 template<
unsigned NSTEPS>
953 unsigned n_value = data_pt->
nvalue();
956 time_derivative(1, data_pt, veloc);
959 time_derivative(2, data_pt, accel);
962 for (
unsigned j = 0; j < n_value; j++)
968 for (
unsigned t = NSTEPS;
t > 0;
t--)
972 data_pt->
set_value(NSTEPS + 1, j, veloc[j]);
973 data_pt->
set_value(NSTEPS + 2, j, accel[j]);
982 template<
unsigned NSTEPS>
986 unsigned n_dim = node_pt->
ndim();
991 double veloc[n_position_type][n_dim];
992 double accel[n_position_type][n_dim];
995 unsigned n_tstorage = ntstorage();
998 for (
unsigned i = 0;
i < n_dim;
i++)
1000 for (
unsigned k = 0; k < n_position_type; k++)
1002 veloc[k][
i] = accel[k][
i] = 0.0;
1004 for (
unsigned t = 0;
t < n_tstorage;
t++)
1006 veloc[k][
i] += weight(1,
t) * node_pt->
x_gen(
t, k,
i);
1007 accel[k][
i] += weight(2,
t) * node_pt->
x_gen(
t, k,
i);
1013 for (
unsigned i = 0;
i < n_dim;
i++)
1019 for (
unsigned k = 0; k < n_position_type; k++)
1023 for (
unsigned t = NSTEPS;
t > 0;
t--)
1028 node_pt->
x_gen(NSTEPS + 1, k,
i) = veloc[k][
i];
1029 node_pt->
x_gen(NSTEPS + 2, k,
i) = accel[k][
i];
1038 template<
unsigned NSTEPS>
1041 double dt = Time_pt->dt(0);
1044 Weight(2, 0) = 2.0 / (Beta2 * dt * dt);
1045 Weight(2, 1) = -2.0 / (Beta2 * dt * dt);
1046 for (
unsigned t = 2;
t <= NSTEPS;
t++)
1050 Weight(2, NSTEPS + 1) = -2.0 / (dt * Beta2);
1051 Weight(2, NSTEPS + 2) = (Beta2 - 1.0) / Beta2;
1054 Weight(1, 0) = Beta1 * dt * Weight(2, 0);
1055 Weight(1, 1) = Beta1 * dt * Weight(2, 1);
1056 for (
unsigned t = 2;
t <= NSTEPS;
t++)
1060 Weight(1, NSTEPS + 1) = 1.0 + Beta1 * dt * Weight(2, NSTEPS + 1);
1061 Weight(1, NSTEPS + 2) =
1062 dt * (1.0 - Beta1) + Beta1 * dt * Weight(2, NSTEPS + 2);
1081 template<
unsigned NSTEPS>
1085 unsigned n_value = data_pt->
nvalue();
1092 unsigned n_tstorage = this->ntstorage();
1095 for (
unsigned i = 0;
i < n_value;
i++)
1098 for (
unsigned t = 0;
t < n_tstorage;
t++)
1100 veloc[
i] += Newmark_veloc_weight[
t] * data_pt->
value(
t,
i);
1101 accel[
i] += this->weight(2,
t) * data_pt->
value(
t,
i);
1107 for (
unsigned j = 0; j < n_value; j++)
1113 for (
unsigned t = NSTEPS;
t > 0;
t--)
1117 data_pt->
set_value(NSTEPS + 1, j, veloc[j]);
1118 data_pt->
set_value(NSTEPS + 2, j, accel[j]);
1127 template<
unsigned NSTEPS>
1131 unsigned n_dim = node_pt->
ndim();
1136 double veloc[n_position_type][n_dim];
1137 double accel[n_position_type][n_dim];
1140 unsigned n_tstorage = this->ntstorage();
1143 for (
unsigned i = 0;
i < n_dim;
i++)
1145 for (
unsigned k = 0; k < n_position_type; k++)
1147 veloc[k][
i] = accel[k][
i] = 0.0;
1149 for (
unsigned t = 0;
t < n_tstorage;
t++)
1151 veloc[k][
i] += Newmark_veloc_weight[
t] * node_pt->
x_gen(
t, k,
i);
1152 accel[k][
i] += this->weight(2,
t) * node_pt->
x_gen(
t, k,
i);
1158 for (
unsigned i = 0;
i < n_dim;
i++)
1164 for (
unsigned k = 0; k < n_position_type; k++)
1168 for (
unsigned t = NSTEPS;
t > 0;
t--)
1173 node_pt->
x_gen(NSTEPS + 1, k,
i) = veloc[k][
i];
1174 node_pt->
x_gen(NSTEPS + 2, k,
i) = accel[k][
i];
1188 double dt = Time_pt->dt(0);
1189 Weight(2, 0) = 2.0 / (Beta2 * dt * dt);
1190 Weight(2, 1) = -2.0 / (Beta2 * dt * dt);
1191 Weight(2, 2) = -2.0 / (dt * Beta2);
1192 Weight(2, 3) = (Beta2 - 1.0) / Beta2;
1195 Weight(1, 0) = 1.0 / dt;
1196 Weight(1, 1) = -1.0 / dt;
1201 set_newmark_veloc_weights(dt);
1211 double dt = Time_pt->dt(0);
1212 Weight(2, 0) = 2.0 / (Beta2 * dt * dt);
1213 Weight(2, 1) = -2.0 / (Beta2 * dt * dt);
1215 Weight(2, 3) = -2.0 / (dt * Beta2);
1216 Weight(2, 4) = (Beta2 - 1.0) / Beta2;
1219 if (Degrade_to_bdf1_for_first_derivs)
1221 this->Weight(1, 0) = 1.0 / dt;
1222 this->Weight(1, 1) = -1.0 / dt;
1223 unsigned nweights = this->Weight.ncol();
1224 for (
unsigned i = 2;
i < nweights;
i++)
1226 this->Weight(1,
i) = 0.0;
1231 double dtprev = Time_pt->dt(1);
1232 Weight(1, 0) = 1.0 / dt + 1.0 / (dt + dtprev);
1233 Weight(1, 1) = -(dt + dtprev) / (dt * dtprev);
1234 Weight(1, 2) = dt / ((dt + dtprev) * dtprev);
1240 set_newmark_veloc_weights(dt);
1250 double dt = Time_pt->dt(0);
1251 Weight(2, 0) = 2.0 / (Beta2 * dt * dt);
1252 Weight(2, 1) = -2.0 / (Beta2 * dt * dt);
1256 Weight(2, 5) = -2.0 / (dt * Beta2);
1257 Weight(2, 6) = (Beta2 - 1.0) / Beta2;
1261 for (
unsigned i = 0;
i < Time_pt->ndt();
i++)
1263 if (dt != Time_pt->dt(
i))
1265 throw OomphLibError(
"BDF4 currently only works for fixed timesteps \n",
1266 OOMPH_CURRENT_FUNCTION,
1267 OOMPH_EXCEPTION_LOCATION);
1273 if (Degrade_to_bdf1_for_first_derivs)
1275 this->Weight(1, 0) = 1.0 / dt;
1276 this->Weight(1, 1) = -1.0 / dt;
1277 unsigned nweights = this->Weight.ncol();
1278 for (
unsigned i = 2;
i < nweights;
i++)
1280 this->Weight(1,
i) = 0.0;
1285 Weight(1, 0) = 25.0 / 12.0 / dt;
1286 Weight(1, 1) = -48.0 / 12.0 / dt;
1287 Weight(1, 2) = 36.0 / 12.0 / dt;
1288 Weight(1, 3) = -16.0 / 12.0 / dt;
1289 Weight(1, 4) = 3.0 / 12.0 / dt;
1295 set_newmark_veloc_weights(dt);
void calculate_predicted_positions(Node *const &node_pt)
Function to calculate predicted positions at a node.
void calculate_predicted_values(Data *const &data_pt)
Function to calculate predicted data values in a Data object.
void set_weights()
Set the 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.
double temporal_error_in_position(Node *const &node_pt, const unsigned &i)
Compute the error in the position i at a node.
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 ...
Class of matrices containing doubles, and stored as a DenseMatrix<double>, but with solving functiona...
void solve(DoubleVector &rhs)
Complete LU solve (replaces matrix by its LU decomposition and overwrites RHS with solution)....
////////////////////////////////////////////////////////////////////// //////////////////////////////...
void set_weights()
Set weights.
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 shift_time_positions(Node *const &node_pt)
This function updates a nodal time history so that we can advance to the next timestep.
////////////////////////////////////////////////////////////////////// //////////////////////////////...
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 assign_initial_data_values_stage1(const unsigned t_deriv, Data *const &data_pt)
First step in a two-stage procedure to assign the history values for the Newmark scheme so that the v...
void assign_initial_data_values_stage2(Data *const &data_pt)
Second step in a two-stage procedure to assign the history values for the Newmark scheme so that the ...
void assign_initial_positions_impulsive(Node *const &node_pt)
Initialise the time-history for the values, corresponding to an impulsive start.
void assign_initial_values_impulsive(Data *const &data_pt)
Initialise the time-history for the values, corresponding to an impulsive start.
void assign_initial_data_values(Data *const &data_pt, Vector< InitialConditionFctPt > initial_value_fct, Vector< InitialConditionFctPt > initial_veloc_fct, Vector< InitialConditionFctPt > initial_accel_fct)
Initialise the time-history for the Data values, so that the Newmark representations for current velo...
void set_weights()
Set weights.
void shift_time_positions(Node *const &node_pt)
This function updates a nodal time history so that we can advance to the next timestep.
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
double & x(const unsigned &i)
Return the i-th nodal coordinate.
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.
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....
////////////////////////////////////////////////////////////////////// //////////////////////////////...
virtual ~TimeStepper()
virtual destructor
ExplicitTimeStepper * Explicit_predictor_pt
Pointer to explicit time stepper to use as predictor if Predict_by_explicit_step is set....
Class to keep track of discrete/continous time. It is essential to have a single Time object when usi...
A slight extension to the standard template vector class so that we can include "graceful" array rang...
//////////////////////////////////////////////////////////////////// ////////////////////////////////...