"dune/tectonic/time-stepping/rate/backward_euler.cc" did not exist on "307cab67eb3d8e19432fcef77a2e8d8db41719fc"
Newer
Older
template <class VectorType, class MatrixType, class FunctionType, int dim>
BackwardEuler<VectorType, MatrixType, FunctionType, dim>::BackwardEuler(
MatrixType const &_A, MatrixType const &_M, VectorType const &_u_initial,
VectorType const &_v_initial,
Dune::BitSetVector<dim> const &_dirichletNodes,
FunctionType const &_dirichletFunction)
: A(_A),
u(_u_initial),
v(_v_initial),
dirichletNodes(_dirichletNodes),
dirichletFunction(_dirichletFunction) {}
template <class VectorType, class MatrixType, class FunctionType, int dim>
void BackwardEuler<VectorType, MatrixType, FunctionType, dim>::nextTimeStep() {
}
template <class VectorType, class MatrixType, class FunctionType, int dim>
void BackwardEuler<VectorType, MatrixType, FunctionType, dim>::setup(
VectorType const &ell, double _tau, double time, VectorType &problem_rhs,
VectorType &problem_iterate, MatrixType &problem_AM) {
postProcessCalled = false;
tau = _tau;
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
MatrixType const &C = A;
double const wc = 0.0;
/* We start out with the formulation
M a + C v + A u = ell
Backward Euler means
a1 = 1.0/tau ( v1 - v0 )
u1 = tau v1 + u0
in summary, we get at time t=1
M [1.0/tau ( v1 - v0 )] + C v1
+ A [tau v1 + u0] = ell
or
1.0/tau M v1 + C v1 + tau A v1
= [1.0/tau M + C + tau A] v1
= ell + 1.0/tau M v0 - A u0
*/
// set up LHS (for fixed tau, we'd only really have to do this once)
{
Dune::MatrixIndexSet indices(A.N(), A.M());
indices.import(A);
indices.import(M);
indices.import(C);
indices.exportIdx(problem_AM);
}
problem_AM = 0.0;
Arithmetic::addProduct(problem_AM, (1.0 - wc) / tau, M);
Arithmetic::addProduct(problem_AM, wc, C);
Arithmetic::addProduct(problem_AM, tau, A);
// set up RHS
{
problem_rhs = ell;
Arithmetic::addProduct(problem_rhs, (1.0 - wc) / tau, M, v_o);
Arithmetic::subtractProduct(problem_rhs, A, u_o);
}
// v_o makes a good initial iterate; we could use anything, though
for (size_t i = 0; i < dirichletNodes.size(); ++i)
switch (dirichletNodes[i].count()) {
case 0:
continue;
case dim:
problem_iterate[i] = 0;
dirichletFunction.evaluate(time, problem_iterate[i][0]);
break;
case 1:
if (dirichletNodes[i][0]) {
dirichletFunction.evaluate(time, problem_iterate[i][0]);
break;
}
if (dirichletNodes[i][1]) {
problem_iterate[i][1] = 0;
break;
}
assert(false);
default:
assert(false);
}
}
template <class VectorType, class MatrixType, class FunctionType, int dim>
void BackwardEuler<VectorType, MatrixType, FunctionType, dim>::postProcess(
VectorType const &problem_iterate) {
postProcessCalled = true;
v = problem_iterate;
Arithmetic::addProduct(u, tau, v);
}
template <class VectorType, class MatrixType, class FunctionType, int dim>
void BackwardEuler<VectorType, MatrixType, FunctionType,
dim>::extractDisplacement(VectorType &displacement) const {
if (!postProcessCalled)
DUNE_THROW(Dune::Exception, "It seems you forgot to call postProcess!");
displacement = u;
}
template <class VectorType, class MatrixType, class FunctionType, int dim>
void BackwardEuler<VectorType, MatrixType, FunctionType, dim>::extractVelocity(
VectorType &velocity) const {
if (!postProcessCalled)
DUNE_THROW(Dune::Exception, "It seems you forgot to call postProcess!");
velocity = v;
}