Skip to content
Snippets Groups Projects
Forked from agnumpde / dune-tectonic
405 commits behind the upstream repository.
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
impliciteuler.cc 2.71 KiB
template <class VectorType, class MatrixType, class FunctionType, int dim>
ImplicitEuler<VectorType, MatrixType, FunctionType, dim>::ImplicitEuler(
    MatrixType const &_A, 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 ImplicitEuler<VectorType, MatrixType, FunctionType, dim>::nextTimeStep() {
  v_old = v;
  u_old = u;
}

template <class VectorType, class MatrixType, class FunctionType, int dim>
void ImplicitEuler<VectorType, MatrixType, FunctionType, dim>::setup(
    VectorType const &ell, double _tau, double time, VectorType &problem_rhs,
    VectorType &problem_iterate, MatrixType &problem_AB) {
  postProcessCalled = false;

  tau = _tau;

  problem_rhs = ell;
  Arithmetic::addProduct(problem_rhs, -1.0, A, u_old);

  // For fixed tau, we'd only really have to do this once
  problem_AB = A;
  problem_AB *= tau;

  // v_old makes a good initial iterate; we could use anything, though
  problem_iterate = v_old;

  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 ImplicitEuler<VectorType, MatrixType, FunctionType, dim>::postProcess(
    VectorType const &problem_iterate) {
  postProcessCalled = true;

  v = problem_iterate;

  u = u_old;
  Arithmetic::addProduct(u, tau, v);
}
template <class VectorType, class MatrixType, class FunctionType, int dim>
void ImplicitEuler<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 ImplicitEuler<VectorType, MatrixType, FunctionType, dim>::extractVelocity(
    VectorType &velocity) const {
  if (!postProcessCalled)
    DUNE_THROW(Dune::Exception, "It seems you forgot to call postProcess!");

  velocity = v;
}