Skip to content
Snippets Groups Projects
Select Git revision
  • 6e7f46a6190e155ef5610c7b7ccf39b06487b400
  • 2016-PippingKornhuberRosenauOncken default
  • 2022-Strikeslip-Benchmark
  • 2021-GraeserKornhuberPodlesny
  • Dissertation2021 protected
  • separate-deformation
  • AverageCrosspoints
  • old_solver_new_datastructure
  • last_working
  • 2014-Dissertation-Pipping
  • 2013-PippingSanderKornhuber
11 results

timestepping.cc

Blame
  • Forked from agnumpde / dune-tectonic
    Source project has a limited visibility.
    Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    timestepping.cc 10.32 KiB
    #ifdef HAVE_CONFIG_H
    #include "config.h"
    #endif
    
    #include <dune/fufem/arithmetic.hh>
    #include "timestepping.hh"
    
    template <class VectorType, class MatrixType, class FunctionType, int dim>
    ImplicitEuler<VectorType, MatrixType, FunctionType, dim>::ImplicitEuler(
        MatrixType const &_A, VectorType const &_u_initial,
        VectorType const &_ud_initial,
        Dune::BitSetVector<dim> const &_dirichletNodes,
        FunctionType const &_dirichletFunction)
        : A(_A),
          u(_u_initial),
          ud(_ud_initial),
          dirichletNodes(_dirichletNodes),
          dirichletFunction(_dirichletFunction) {}
    
    template <class VectorType, class MatrixType, class FunctionType, int dim>
    void ImplicitEuler<VectorType, MatrixType, FunctionType, dim>::nextTimeStep() {
      ud_old = ud;
      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_A) {
      postProcessCalled = false;
    
      tau = _tau;
    
      problem_rhs = ell;
      A.mmv(u_old, problem_rhs);
    
      // For fixed tau, we'd only really have to do this once
      problem_A = A;
      problem_A *= tau;
    
      // ud_old makes a good initial iterate; we could use anything, though
      problem_iterate = ud_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;
    
      ud = problem_iterate;
    
      u = u_old;
      Arithmetic::addProduct(u, tau, ud);
    }
    
    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 = ud;
    }
    
    template <class VectorType, class MatrixType, class FunctionType, int dim>
    TimeSteppingScheme<VectorType, MatrixType, FunctionType, dim> *
    ImplicitEuler<VectorType, MatrixType, FunctionType, dim>::clone() {
      return new ImplicitEuler<VectorType, MatrixType, FunctionType, dim>(*this);
    }
    template <class VectorType, class MatrixType, class FunctionType, int dim>
    ImplicitTwoStep<VectorType, MatrixType, FunctionType, dim>::ImplicitTwoStep(
        MatrixType const &_A, VectorType const &_u_initial,
        VectorType const &_ud_initial,
        Dune::BitSetVector<dim> const &_dirichletNodes,
        FunctionType const &_dirichletFunction)
        : A(_A),
          u(_u_initial),
          ud(_ud_initial),
          dirichletNodes(_dirichletNodes),
          dirichletFunction(_dirichletFunction) {}
    
    template <class VectorType, class MatrixType, class FunctionType, int dim>
    void
    ImplicitTwoStep<VectorType, MatrixType, FunctionType, dim>::nextTimeStep() {
      u_old_old = u_old;
      ud_old = ud;
      u_old = u;
    }
    
    template <class VectorType, class MatrixType, class FunctionType, int dim>
    void ImplicitTwoStep<VectorType, MatrixType, FunctionType, dim>::setup(
        VectorType const &ell, double _tau, double time, VectorType &problem_rhs,
        VectorType &problem_iterate, MatrixType &problem_A) {
      postProcessCalled = false;
    
      tau = _tau;
    
      switch (state) {
        // Perform an implicit Euler step since we lack information
        case NO_SETUP:
          state = FIRST_SETUP;
    
          problem_rhs = ell;
          A.mmv(u_old, problem_rhs);
    
          problem_A = A;
          problem_A *= tau;
          break;
        case FIRST_SETUP:
          state = SECOND_SETUP;
        // FALLTHROUGH
        case SECOND_SETUP:
          problem_rhs = ell;
          A.usmv(-4.0 / 3.0, u_old, problem_rhs);
          A.usmv(+1.0 / 3.0, u_old_old, problem_rhs);
    
          // For fixed tau, we'd only really have to do this once
          problem_A = A;
          problem_A *= 2.0 / 3.0 * tau;
          break;
        default:
          assert(false);
      }
    
      // ud_old makes a good initial iterate; we could use anything, though
      problem_iterate = ud_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 ImplicitTwoStep<VectorType, MatrixType, FunctionType, dim>::postProcess(
        VectorType const &problem_iterate) {
      postProcessCalled = true;
    
      ud = problem_iterate;
    
      switch (state) {
        case FIRST_SETUP:
          u = u_old;
          Arithmetic::addProduct(u, tau, ud);
          break;
        case SECOND_SETUP:
          u = 0.0;
          Arithmetic::addProduct(u, tau, ud);
          Arithmetic::addProduct(u, 2.0, u_old);
          Arithmetic::addProduct(u, -.5, u_old_old);
          u *= 2.0 / 3.0;
          break;
        default:
          assert(false);
      }
    }
    
    template <class VectorType, class MatrixType, class FunctionType, int dim>
    void ImplicitTwoStep<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 ImplicitTwoStep<VectorType, MatrixType, FunctionType,
                         dim>::extractVelocity(VectorType &velocity) const {
      if (!postProcessCalled)
        DUNE_THROW(Dune::Exception, "It seems you forgot to call postProcess!");
    
      velocity = ud;
    }
    
    template <class VectorType, class MatrixType, class FunctionType, int dim>
    TimeSteppingScheme<VectorType, MatrixType, FunctionType, dim> *
    ImplicitTwoStep<VectorType, MatrixType, FunctionType, dim>::clone() {
      return new ImplicitTwoStep<VectorType, MatrixType, FunctionType, dim>(*this);
    }
    template <class VectorType, class MatrixType, class FunctionType, int dim>
    Newmark<VectorType, MatrixType, FunctionType, dim>::Newmark(
        MatrixType const &_A, MatrixType const &_B, VectorType const &_u_initial,
        VectorType const &_ud_initial, VectorType const &_udd_initial,
        Dune::BitSetVector<dim> const &_dirichletNodes,
        FunctionType const &_dirichletFunction)
        : A(_A),
          B(_B),
          u(_u_initial),
          ud(_ud_initial),
          udd(_udd_initial),
          dirichletNodes(_dirichletNodes),
          dirichletFunction(_dirichletFunction) {}
    
    template <class VectorType, class MatrixType, class FunctionType, int dim>
    void Newmark<VectorType, MatrixType, FunctionType, dim>::nextTimeStep() {
      udd_old = udd;
      ud_old = ud;
      u_old = u;
    }
    
    template <class VectorType, class MatrixType, class FunctionType, int dim>
    void Newmark<VectorType, MatrixType, FunctionType, dim>::setup(
        VectorType const &ell, double _tau, double time, VectorType &problem_rhs,
        VectorType &problem_iterate, MatrixType &problem_A) {
      postProcessCalled = false;
    
      tau = _tau;
    
      problem_rhs = ell;
      B.usmv(2.0 / tau, ud_old, problem_rhs);
      B.usmv(1.0, udd_old, problem_rhs);
      A.usmv(-1.0, u_old, problem_rhs);
      A.usmv(-tau / 2.0, ud_old, problem_rhs);
    
      // For fixed tau, we'd only really have to do this once
      problem_A = A;
      problem_A *= tau / 2.0;
      Arithmetic::addProduct(problem_A, 2.0 / tau, B);
    
      // ud_old makes a good initial iterate; we could use anything, though
      problem_iterate = ud_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 Newmark<VectorType, MatrixType, FunctionType, dim>::postProcess(
        VectorType const &problem_iterate) {
      postProcessCalled = true;
    
      ud = problem_iterate;
    
      u = u_old;
      Arithmetic::addProduct(u, tau / 2.0, ud);
      Arithmetic::addProduct(u, tau / 2.0, ud_old);
    
      udd = 0;
      Arithmetic::addProduct(udd, 2.0 / tau, ud);
      Arithmetic::addProduct(udd, -2.0 / tau, ud_old);
      Arithmetic::addProduct(udd, -1.0, udd_old);
    }
    
    template <class VectorType, class MatrixType, class FunctionType, int dim>
    void Newmark<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 Newmark<VectorType, MatrixType, FunctionType, dim>::extractVelocity(
        VectorType &velocity) const {
      if (!postProcessCalled)
        DUNE_THROW(Dune::Exception, "It seems you forgot to call postProcess!");
    
      velocity = ud;
    }
    
    template <class VectorType, class MatrixType, class FunctionType, int dim>
    TimeSteppingScheme<VectorType, MatrixType, FunctionType, dim> *
    Newmark<VectorType, MatrixType, FunctionType, dim>::clone() {
      return new Newmark<VectorType, MatrixType, FunctionType, dim>(*this);
    }
    
    #include "timestepping_tmpl.cc"