Skip to content
Snippets Groups Projects
Commit eaf14ab5 authored by Elias Pipping's avatar Elias Pipping
Browse files

[Cleanup] Move time stepping logic into parent class

While we're at it, reset postProcessCalled in nextTimeStep()
parent 21a6b769
No related branches found
No related tags found
No related merge requests found
...@@ -4,6 +4,51 @@ ...@@ -4,6 +4,51 @@
#include "timestepping.hh" #include "timestepping.hh"
template <class Vector, class Matrix, class Function, size_t dim>
TimeSteppingScheme<Vector, Matrix, Function, dim>::TimeSteppingScheme(
Matrices<Matrix> const &_matrices, Vector const &_u_initial,
Vector const &_v_initial, Vector const &_a_initial,
Dune::BitSetVector<dim> const &_dirichletNodes,
Function const &_dirichletFunction)
: matrices(_matrices),
u(_u_initial),
v(_v_initial),
a(_a_initial),
dirichletNodes(_dirichletNodes),
dirichletFunction(_dirichletFunction) {}
template <class Vector, class Matrix, class Function, size_t dim>
void TimeSteppingScheme<Vector, Matrix, Function, dim>::nextTimeStep() {
u_o = u;
v_o = v;
a_o = a;
postProcessCalled = false;
}
template <class Vector, class Matrix, class Function, size_t dim>
void TimeSteppingScheme<Vector, Matrix, Function, dim>::extractDisplacement(
Vector &displacement) const {
if (!postProcessCalled)
DUNE_THROW(Dune::Exception, "It seems you forgot to call postProcess!");
displacement = u;
}
template <class Vector, class Matrix, class Function, size_t dim>
void TimeSteppingScheme<Vector, Matrix, Function, dim>::extractVelocity(
Vector &velocity) const {
if (!postProcessCalled)
DUNE_THROW(Dune::Exception, "It seems you forgot to call postProcess!");
velocity = v;
}
template <class Vector, class Matrix, class Function, size_t dim>
void TimeSteppingScheme<Vector, Matrix, Function, dim>::extractOldVelocity(
Vector &oldVelocity) const {
oldVelocity = v_o;
}
#include "timestepping/backward_euler.cc" #include "timestepping/backward_euler.cc"
#include "timestepping/newmark.cc" #include "timestepping/newmark.cc"
......
...@@ -10,18 +10,37 @@ ...@@ -10,18 +10,37 @@
template <class Vector, class Matrix, class Function, size_t dim> template <class Vector, class Matrix, class Function, size_t dim>
class TimeSteppingScheme { class TimeSteppingScheme {
protected:
TimeSteppingScheme(Matrices<Matrix> const &_matrices,
Vector const &_u_initial, Vector const &_v_initial,
Vector const &_a_initial,
Dune::BitSetVector<dim> const &_dirichletNodes,
Function const &_dirichletFunction);
public: public:
void virtual nextTimeStep() = 0; void nextTimeStep();
void virtual setup(Vector const &ell, double _tau, double relativeTime, void virtual setup(Vector const &ell, double _tau, double relativeTime,
Vector &rhs, Vector &iterate, Matrix &AB) = 0; Vector &rhs, Vector &iterate, Matrix &AB) = 0;
void virtual postProcess(Vector const &iterate) = 0; void virtual postProcess(Vector const &iterate) = 0;
void virtual extractDisplacement(Vector &displacement) const = 0; void extractDisplacement(Vector &displacement) const;
void virtual extractVelocity(Vector &velocity) const = 0; void extractVelocity(Vector &velocity) const;
void virtual extractOldVelocity(Vector &velocity) const = 0; void extractOldVelocity(Vector &velocity) const;
std::shared_ptr<TimeSteppingScheme<Vector, Matrix, Function, std::shared_ptr<TimeSteppingScheme<Vector, Matrix, Function,
dim>> virtual clone() const = 0; dim>> virtual clone() const = 0;
protected:
Matrices<Matrix> const &matrices;
Vector u, v, a;
Dune::BitSetVector<dim> const &dirichletNodes;
Function const &dirichletFunction;
double dirichletValue;
Vector u_o, v_o, a_o;
double tau;
bool postProcessCalled = true;
}; };
#include "timestepping/newmark.hh" #include "timestepping/newmark.hh"
...@@ -42,7 +61,7 @@ initTimeStepper(Config::scheme scheme, ...@@ -42,7 +61,7 @@ initTimeStepper(Config::scheme scheme,
case Config::BackwardEuler: case Config::BackwardEuler:
return std::make_shared< return std::make_shared<
BackwardEuler<Vector, Matrix, Function, dimension>>( BackwardEuler<Vector, Matrix, Function, dimension>>(
matrices, u_initial, v_initial, velocityDirichletNodes, matrices, u_initial, v_initial, a_initial, velocityDirichletNodes,
velocityDirichletFunction); velocityDirichletFunction);
default: default:
assert(false); assert(false);
......
...@@ -3,27 +3,19 @@ ...@@ -3,27 +3,19 @@
template <class Vector, class Matrix, class Function, size_t dim> template <class Vector, class Matrix, class Function, size_t dim>
BackwardEuler<Vector, Matrix, Function, dim>::BackwardEuler( BackwardEuler<Vector, Matrix, Function, dim>::BackwardEuler(
Matrices<Matrix> const &_matrices, Vector const &_u_initial, Matrices<Matrix> const &_matrices, Vector const &_u_initial,
Vector const &_v_initial, Dune::BitSetVector<dim> const &_dirichletNodes, Vector const &_v_initial, Vector const &_a_initial,
Dune::BitSetVector<dim> const &_dirichletNodes,
Function const &_dirichletFunction) Function const &_dirichletFunction)
: matrices(_matrices), : TimeSteppingScheme<Vector, Matrix, Function, dim>(
u(_u_initial), _matrices, _u_initial, _v_initial, _a_initial, _dirichletNodes,
v(_v_initial), _dirichletFunction) {}
dirichletNodes(_dirichletNodes),
dirichletFunction(_dirichletFunction) {}
template <class Vector, class Matrix, class Function, size_t dim>
void BackwardEuler<Vector, Matrix, Function, dim>::nextTimeStep() {
v_o = v;
u_o = u;
}
template <class Vector, class Matrix, class Function, size_t dim> template <class Vector, class Matrix, class Function, size_t dim>
void BackwardEuler<Vector, Matrix, Function, dim>::setup( void BackwardEuler<Vector, Matrix, Function, dim>::setup(
Vector const &ell, double _tau, double relativeTime, Vector &rhs, Vector const &ell, double _tau, double relativeTime, Vector &rhs,
Vector &iterate, Matrix &AM) { Vector &iterate, Matrix &AM) {
postProcessCalled = false; this->dirichletFunction.evaluate(relativeTime, this->dirichletValue);
dirichletFunction.evaluate(relativeTime, dirichletValue); this->tau = _tau;
tau = _tau;
/* We start out with the formulation /* We start out with the formulation
...@@ -48,66 +40,47 @@ void BackwardEuler<Vector, Matrix, Function, dim>::setup( ...@@ -48,66 +40,47 @@ void BackwardEuler<Vector, Matrix, Function, dim>::setup(
// set up LHS (for fixed tau, we'd only really have to do this once) // set up LHS (for fixed tau, we'd only really have to do this once)
{ {
Dune::MatrixIndexSet indices(matrices.elasticity.N(), Dune::MatrixIndexSet indices(this->matrices.elasticity.N(),
matrices.elasticity.M()); this->matrices.elasticity.M());
indices.import(matrices.elasticity); indices.import(this->matrices.elasticity);
indices.import(matrices.mass); indices.import(this->matrices.mass);
indices.import(matrices.damping); indices.import(this->matrices.damping);
indices.exportIdx(AM); indices.exportIdx(AM);
} }
AM = 0.0; AM = 0.0;
Arithmetic::addProduct(AM, 1.0 / tau, matrices.mass); Arithmetic::addProduct(AM, 1.0 / this->tau, this->matrices.mass);
Arithmetic::addProduct(AM, 1.0, matrices.damping); Arithmetic::addProduct(AM, 1.0, this->matrices.damping);
Arithmetic::addProduct(AM, tau, matrices.elasticity); Arithmetic::addProduct(AM, this->tau, this->matrices.elasticity);
// set up RHS // set up RHS
{ {
rhs = ell; rhs = ell;
Arithmetic::addProduct(rhs, 1.0 / tau, matrices.mass, v_o); Arithmetic::addProduct(rhs, 1.0 / this->tau, this->matrices.mass,
Arithmetic::subtractProduct(rhs, matrices.elasticity, u_o); this->v_o);
Arithmetic::subtractProduct(rhs, this->matrices.elasticity, this->u_o);
} }
iterate = v_o; iterate = this->v_o;
for (size_t i = 0; i < dirichletNodes.size(); ++i) for (size_t i = 0; i < this->dirichletNodes.size(); ++i)
for (size_t j = 0; j < dim; ++j) for (size_t j = 0; j < dim; ++j)
if (dirichletNodes[i][j]) if (this->dirichletNodes[i][j])
iterate[i][j] = (j == 0) ? dirichletValue : 0; iterate[i][j] = (j == 0) ? this->dirichletValue : 0;
} }
template <class Vector, class Matrix, class Function, size_t dim> template <class Vector, class Matrix, class Function, size_t dim>
void BackwardEuler<Vector, Matrix, Function, dim>::postProcess( void BackwardEuler<Vector, Matrix, Function, dim>::postProcess(
Vector const &iterate) { Vector const &iterate) {
postProcessCalled = true; this->postProcessCalled = true;
v = iterate; this->v = iterate;
u = u_o; this->u = this->u_o;
Arithmetic::addProduct(u, tau, v); Arithmetic::addProduct(this->u, this->tau, this->v);
}
template <class Vector, class Matrix, class Function, size_t dim> this->a = this->v;
void BackwardEuler<Vector, Matrix, Function, dim>::extractDisplacement( this->a -= this->v_o;
Vector &displacement) const { this->a /= this->tau;
if (!postProcessCalled)
DUNE_THROW(Dune::Exception, "It seems you forgot to call postProcess!");
displacement = u;
}
template <class Vector, class Matrix, class Function, size_t dim>
void BackwardEuler<Vector, Matrix, Function, dim>::extractVelocity(
Vector &velocity) const {
if (!postProcessCalled)
DUNE_THROW(Dune::Exception, "It seems you forgot to call postProcess!");
velocity = v;
}
template <class Vector, class Matrix, class Function, size_t dim>
void BackwardEuler<Vector, Matrix, Function, dim>::extractOldVelocity(
Vector &velocity) const {
velocity = v_o;
} }
template <class Vector, class Matrix, class Function, size_t dim> template <class Vector, class Matrix, class Function, size_t dim>
......
...@@ -5,34 +5,17 @@ template <class Vector, class Matrix, class Function, size_t dim> ...@@ -5,34 +5,17 @@ template <class Vector, class Matrix, class Function, size_t dim>
class BackwardEuler : public TimeSteppingScheme<Vector, Matrix, Function, dim> { class BackwardEuler : public TimeSteppingScheme<Vector, Matrix, Function, dim> {
public: public:
BackwardEuler(Matrices<Matrix> const &_matrices, Vector const &_u_initial, BackwardEuler(Matrices<Matrix> const &_matrices, Vector const &_u_initial,
Vector const &_v_initial, Vector const &_v_initial, Vector const &_a_initial,
Dune::BitSetVector<dim> const &_dirichletNodes, Dune::BitSetVector<dim> const &_dirichletNodes,
Function const &_dirichletFunction); Function const &_dirichletFunction);
void nextTimeStep() override;
void setup(Vector const &, double, double, Vector &, Vector &, void setup(Vector const &, double, double, Vector &, Vector &,
Matrix &) override; Matrix &) override;
void postProcess(Vector const &) override; void postProcess(Vector const &) override;
void extractDisplacement(Vector &) const override;
void extractVelocity(Vector &) const override;
void extractOldVelocity(Vector &) const override;
std::shared_ptr<TimeSteppingScheme<Vector, Matrix, Function, dim>> clone() std::shared_ptr<TimeSteppingScheme<Vector, Matrix, Function, dim>> clone()
const; const;
private: private:
Matrices<Matrix> const &matrices;
Vector u;
Vector v;
Dune::BitSetVector<dim> const &dirichletNodes;
Function const &dirichletFunction;
double dirichletValue;
Vector u_o;
Vector v_o;
double tau;
bool postProcessCalled = true;
}; };
#endif #endif
...@@ -6,19 +6,9 @@ Newmark<Vector, Matrix, Function, dim>::Newmark( ...@@ -6,19 +6,9 @@ Newmark<Vector, Matrix, Function, dim>::Newmark(
Vector const &_v_initial, Vector const &_a_initial, Vector const &_v_initial, Vector const &_a_initial,
Dune::BitSetVector<dim> const &_dirichletNodes, Dune::BitSetVector<dim> const &_dirichletNodes,
Function const &_dirichletFunction) Function const &_dirichletFunction)
: matrices(_matrices), : TimeSteppingScheme<Vector, Matrix, Function, dim>(
u(_u_initial), _matrices, _u_initial, _v_initial, _a_initial, _dirichletNodes,
v(_v_initial), _dirichletFunction) {}
a(_a_initial),
dirichletNodes(_dirichletNodes),
dirichletFunction(_dirichletFunction) {}
template <class Vector, class Matrix, class Function, size_t dim>
void Newmark<Vector, Matrix, Function, dim>::nextTimeStep() {
a_o = a;
v_o = v;
u_o = u;
}
template <class Vector, class Matrix, class Function, size_t dim> template <class Vector, class Matrix, class Function, size_t dim>
void Newmark<Vector, Matrix, Function, dim>::setup(Vector const &ell, void Newmark<Vector, Matrix, Function, dim>::setup(Vector const &ell,
...@@ -26,9 +16,8 @@ void Newmark<Vector, Matrix, Function, dim>::setup(Vector const &ell, ...@@ -26,9 +16,8 @@ void Newmark<Vector, Matrix, Function, dim>::setup(Vector const &ell,
double relativeTime, double relativeTime,
Vector &rhs, Vector &iterate, Vector &rhs, Vector &iterate,
Matrix &AM) { Matrix &AM) {
postProcessCalled = false; this->dirichletFunction.evaluate(relativeTime, this->dirichletValue);
dirichletFunction.evaluate(relativeTime, dirichletValue); this->tau = _tau;
tau = _tau;
/* We start out with the formulation /* We start out with the formulation
...@@ -54,76 +43,54 @@ void Newmark<Vector, Matrix, Function, dim>::setup(Vector const &ell, ...@@ -54,76 +43,54 @@ void Newmark<Vector, Matrix, Function, dim>::setup(Vector const &ell,
// set up LHS (for fixed tau, we'd only really have to do this once) // set up LHS (for fixed tau, we'd only really have to do this once)
{ {
Dune::MatrixIndexSet indices(matrices.elasticity.N(), Dune::MatrixIndexSet indices(this->matrices.elasticity.N(),
matrices.elasticity.M()); this->matrices.elasticity.M());
indices.import(matrices.elasticity); indices.import(this->matrices.elasticity);
indices.import(matrices.mass); indices.import(this->matrices.mass);
indices.import(matrices.damping); indices.import(this->matrices.damping);
indices.exportIdx(AM); indices.exportIdx(AM);
} }
AM = 0.0; AM = 0.0;
Arithmetic::addProduct(AM, 2.0 / tau, matrices.mass); Arithmetic::addProduct(AM, 2.0 / this->tau, this->matrices.mass);
Arithmetic::addProduct(AM, 1.0, matrices.damping); Arithmetic::addProduct(AM, 1.0, this->matrices.damping);
Arithmetic::addProduct(AM, tau / 2.0, matrices.elasticity); Arithmetic::addProduct(AM, this->tau / 2.0, this->matrices.elasticity);
// set up RHS // set up RHS
{ {
rhs = ell; rhs = ell;
Arithmetic::addProduct(rhs, 2.0 / tau, matrices.mass, v_o); Arithmetic::addProduct(rhs, 2.0 / this->tau, this->matrices.mass,
Arithmetic::addProduct(rhs, matrices.mass, a_o); this->v_o);
Arithmetic::subtractProduct(rhs, tau / 2.0, matrices.elasticity, v_o); Arithmetic::addProduct(rhs, this->matrices.mass, this->a_o);
Arithmetic::subtractProduct(rhs, matrices.elasticity, u_o); Arithmetic::subtractProduct(rhs, this->tau / 2.0, this->matrices.elasticity,
this->v_o);
Arithmetic::subtractProduct(rhs, this->matrices.elasticity, this->u_o);
} }
iterate = v_o; iterate = this->v_o;
for (size_t i = 0; i < dirichletNodes.size(); ++i) for (size_t i = 0; i < this->dirichletNodes.size(); ++i)
for (size_t j = 0; j < dim; ++j) for (size_t j = 0; j < dim; ++j)
if (dirichletNodes[i][j]) if (this->dirichletNodes[i][j])
iterate[i][j] = (j == 0) ? dirichletValue : 0; iterate[i][j] = (j == 0) ? this->dirichletValue : 0;
} }
template <class Vector, class Matrix, class Function, size_t dim> template <class Vector, class Matrix, class Function, size_t dim>
void Newmark<Vector, Matrix, Function, dim>::postProcess( void Newmark<Vector, Matrix, Function, dim>::postProcess(
Vector const &iterate) { Vector const &iterate) {
postProcessCalled = true; this->postProcessCalled = true;
v = iterate; this->v = iterate;
// u1 = tau/2 ( v1 + v0 ) + u0 // u1 = tau/2 ( v1 + v0 ) + u0
u = u_o; this->u = this->u_o;
Arithmetic::addProduct(u, tau / 2.0, v); Arithmetic::addProduct(this->u, this->tau / 2.0, this->v);
Arithmetic::addProduct(u, tau / 2.0, v_o); Arithmetic::addProduct(this->u, this->tau / 2.0, this->v_o);
// a1 = 2/tau ( v1 - v0 ) - a0 // a1 = 2/tau ( v1 - v0 ) - a0
a = 0; this->a = 0.0;
Arithmetic::addProduct(a, 2.0 / tau, v); Arithmetic::addProduct(this->a, 2.0 / this->tau, this->v);
Arithmetic::subtractProduct(a, 2.0 / tau, v_o); Arithmetic::subtractProduct(this->a, 2.0 / this->tau, this->v_o);
Arithmetic::subtractProduct(a, 1.0, a_o); Arithmetic::subtractProduct(this->a, 1.0, this->a_o);
}
template <class Vector, class Matrix, class Function, size_t dim>
void Newmark<Vector, Matrix, Function, dim>::extractDisplacement(
Vector &displacement) const {
if (!postProcessCalled)
DUNE_THROW(Dune::Exception, "It seems you forgot to call postProcess!");
displacement = u;
}
template <class Vector, class Matrix, class Function, size_t dim>
void Newmark<Vector, Matrix, Function, dim>::extractVelocity(
Vector &velocity) const {
if (!postProcessCalled)
DUNE_THROW(Dune::Exception, "It seems you forgot to call postProcess!");
velocity = v;
}
template <class Vector, class Matrix, class Function, size_t dim>
void Newmark<Vector, Matrix, Function, dim>::extractOldVelocity(
Vector &velocity) const {
velocity = v_o;
} }
template <class Vector, class Matrix, class Function, size_t dim> template <class Vector, class Matrix, class Function, size_t dim>
......
...@@ -9,32 +9,11 @@ class Newmark : public TimeSteppingScheme<Vector, Matrix, Function, dim> { ...@@ -9,32 +9,11 @@ class Newmark : public TimeSteppingScheme<Vector, Matrix, Function, dim> {
Dune::BitSetVector<dim> const &_dirichletNodes, Dune::BitSetVector<dim> const &_dirichletNodes,
Function const &_dirichletFunction); Function const &_dirichletFunction);
void nextTimeStep() override;
void setup(Vector const &, double, double, Vector &, Vector &, void setup(Vector const &, double, double, Vector &, Vector &,
Matrix &) override; Matrix &) override;
void postProcess(Vector const &) override; void postProcess(Vector const &) override;
void extractDisplacement(Vector &) const override;
void extractVelocity(Vector &) const override;
void extractOldVelocity(Vector &) const override;
std::shared_ptr<TimeSteppingScheme<Vector, Matrix, Function, dim>> clone() std::shared_ptr<TimeSteppingScheme<Vector, Matrix, Function, dim>> clone()
const; const;
private:
Matrices<Matrix> const &matrices;
Vector u;
Vector v;
Vector a;
Dune::BitSetVector<dim> const &dirichletNodes;
Function const &dirichletFunction;
double dirichletValue;
Vector u_o;
Vector v_o;
Vector a_o;
double tau;
bool postProcessCalled = true;
}; };
#endif #endif
...@@ -8,5 +8,6 @@ ...@@ -8,5 +8,6 @@
using Function = Dune::VirtualFunction<double, double>; using Function = Dune::VirtualFunction<double, double>;
template class TimeSteppingScheme<Vector, Matrix, Function, MY_DIM>;
template class Newmark<Vector, Matrix, Function, MY_DIM>; template class Newmark<Vector, Matrix, Function, MY_DIM>;
template class BackwardEuler<Vector, Matrix, Function, MY_DIM>; template class BackwardEuler<Vector, Matrix, Function, MY_DIM>;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment