Skip to content
Snippets Groups Projects
fixedpointiterator.cc 8.26 KiB
Newer Older
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <dune/common/exceptions.hh>

podlesny's avatar
.  
podlesny committed
#include <dune/matrix-vector/axpy.hh>
#include <dune/solvers/norms/sumnorm.hh>
podlesny's avatar
.  
podlesny committed

#include <dune/tectonic/utils/reductionfactors.hh>
#include "functionalfactory.hh"
#include "nonlinearsolver.hh"
podlesny's avatar
podlesny committed
#include "../utils/debugutils.hh"

podlesny's avatar
podlesny committed
#include "fixedpointiterator.hh"
podlesny's avatar
.  
podlesny committed

void FixedPointIterationCounter::operator+=(
    FixedPointIterationCounter const &other) {
  iterations += other.iterations;
  multigridIterations += other.multigridIterations;
}

podlesny's avatar
podlesny committed
template <class Factory, class NBodyAssembler, class Updaters, class ErrorNorms>
FixedPointIterator<Factory, NBodyAssembler, Updaters, ErrorNorms>::FixedPointIterator(
podlesny's avatar
podlesny committed
    Dune::ParameterTree const &parset,
podlesny's avatar
podlesny committed
    const NBodyAssembler& nBodyAssembler,
podlesny's avatar
.  
podlesny committed
    const IgnoreVector& ignoreNodes,
podlesny's avatar
.  
podlesny committed
    GlobalFriction& globalFriction,
    const std::vector<const BitVector*>& bodywiseNonmortarBoundaries,
podlesny's avatar
.  
podlesny committed
    const ErrorNorms& errorNorms)
podlesny's avatar
podlesny committed
    : parset_(parset),
podlesny's avatar
podlesny committed
      nBodyAssembler_(nBodyAssembler),
podlesny's avatar
.  
podlesny committed
      ignoreNodes_(ignoreNodes),
      globalFriction_(globalFriction),
podlesny's avatar
.  
podlesny committed
      bodywiseNonmortarBoundaries_(bodywiseNonmortarBoundaries),
      fixedPointMaxIterations_(parset.get<size_t>("v.fpi.maximumIterations")),
      fixedPointTolerance_(parset.get<double>("v.fpi.tolerance")),
      lambda_(parset.get<double>("v.fpi.lambda")),
      solverParset_(parset.sub("v.solver")),
podlesny's avatar
.  
podlesny committed
      errorNorms_(errorNorms) {}
template <class Factory, class NBodyAssembler, class Updaters, class ErrorNorms>
bool FixedPointIterator<Factory, NBodyAssembler, Updaters, ErrorNorms>::displacementCriterion(const Updaters& updaters, std::vector<Vector>& last_u) const {
    bool criterion = true;

    std::vector<Vector> u;
    updaters.rate_->extractDisplacement(u);

    const auto& mats = updaters.rate_->getMatrices();

    for (int i=0; i<u.size(); i++) {
        const EnergyNorm<Matrix, Vector> ANorm(*mats.elasticity[i]), MNorm(*mats.mass[i]);
        const SumNorm<Vector> AMNorm(1.0, ANorm, 1.0, MNorm);

        if (u[i].size()==0 || last_u[i].size()==0)
            continue;

        if (AMNorm.diff(u[i], last_u[i]) >= fixedPointTolerance_) {
            criterion = false;
            break;
        }
    }

    last_u = u;

    return criterion;
}

template <class Factory, class NBodyAssembler, class Updaters, class ErrorNorms>
bool FixedPointIterator<Factory, NBodyAssembler, Updaters, ErrorNorms>::stateCriterion(const std::vector<ScalarVector>& alpha, const std::vector<ScalarVector>& newAlpha) const {
    bool criterion = true;
    for (int i=0; i<alpha.size(); i++) {
        if (alpha[i].size()==0 || newAlpha[i].size()==0)
            continue;

        if (errorNorms_[i]->diff(alpha[i], newAlpha[i]) >= fixedPointTolerance_) {
            criterion = false;
            break;
        }
    }

    return criterion;
}

podlesny's avatar
podlesny committed
template <class Factory, class NBodyAssembler, class Updaters, class ErrorNorms>
template <class LinearSolver>
Elias Pipping's avatar
Elias Pipping committed
FixedPointIterationCounter
podlesny's avatar
podlesny committed
FixedPointIterator<Factory, NBodyAssembler, Updaters, ErrorNorms>::run(
    Updaters updaters, std::shared_ptr<LinearSolver>& linearSolver,
podlesny's avatar
.  
podlesny committed
    const std::vector<Matrix>& velocityMatrices, const std::vector<Vector>& velocityRHSs,
podlesny's avatar
.  
podlesny committed
    std::vector<Vector>& velocityIterates) {

    // debugging
    /*const auto& contactCouplings = nBodyAssembler_.getContactCouplings();
    for (size_t i=0; i<contactCouplings.size(); i++) {
      print(*contactCouplings[i]->nonmortarBoundary().getVertices(), "nonmortarBoundaries:");
    }*/
podlesny's avatar
.  
podlesny committed

  const auto nBodies = nBodyAssembler_.nGrids();

  FunctionalFactory<std::decay_t<decltype(nBodyAssembler_)>, decltype(globalFriction_), Matrix, Vector> functionalFactory(nBodyAssembler_, globalFriction_, velocityMatrices, velocityRHSs);
  functionalFactory.build();
  auto functional = functionalFactory.functional();
podlesny's avatar
podlesny committed

  NonlinearSolver<std::remove_reference_t<decltype(*functional)>, IgnoreVector> solver(parset_.sub("solver.tnnmg"), linearSolver, functional, ignoreNodes_);
podlesny's avatar
.  
podlesny committed

  size_t fixedPointIteration;
  size_t multigridIterations = 0;

  std::vector<Vector> last_u;
  updaters.rate_->extractOldDisplacement(last_u);

podlesny's avatar
.  
podlesny committed
  std::vector<ScalarVector> alpha(nBodies);
  updaters.state_->extractAlpha(alpha);
  std::vector<Vector> v_o;
  updaters.rate_->extractOldVelocity(v_o);

  Vector total_v_o;
  nBodyAssembler_.nodalToTransformed(v_o, total_v_o);

  Vector total_v;
  nBodyAssembler_.nodalToTransformed(velocityIterates, total_v);
podlesny's avatar
podlesny committed
  //print(velocityIterates, "velocityIterates start:");
  for (fixedPointIteration = 0; fixedPointIteration < fixedPointMaxIterations_;
       ++fixedPointIteration) {
podlesny's avatar
.  
podlesny committed

podlesny's avatar
.  
podlesny committed
    globalFriction_.updateAlpha(alpha);

    // solve rate problem
    auto res = solver.solve(solverParset_, total_v);
    multigridIterations += res.iterations;
    Vector v_m = total_v_o;
podlesny's avatar
podlesny committed
    v_m *= 1.0 - lambda_;
    Dune::MatrixVector::addProduct(v_m, lambda_, total_v);
podlesny's avatar
.  
podlesny committed

podlesny's avatar
.  
podlesny committed
    // extract relative velocities in mortar basis
    std::vector<Vector> v_rel;
podlesny's avatar
podlesny committed
    split(v_m, v_rel);
    // solve state problem
podlesny's avatar
.  
podlesny committed
    updaters.state_->solve(v_rel);
podlesny's avatar
.  
podlesny committed
    std::vector<ScalarVector> newAlpha(nBodies);
podlesny's avatar
.  
podlesny committed
    updaters.state_->extractAlpha(newAlpha);

    nBodyAssembler_.postprocess(total_v, velocityIterates);
    //Rprint(velocityIterates, "velocityIterates loop:");
    updaters.rate_->postProcess(velocityIterates);
    bool breakCriterion = stateCriterion(alpha, newAlpha); //displacementCriterion(updaters, last_u); //stateCriterion(alpha, newAlpha);
    //printRegularityTruncation(globalFriction_, total_v);
podlesny's avatar
.  
podlesny committed
    if (lambda_ < 1e-12 or breakCriterion) {
      fixedPointIteration++;
    /*if (res.iterations>200) {
        std::cout << "FixedPointIterator: TNNMG did not converge, iterations: " << res.iterations << std::endl;
        //DUNE_THROW(Dune::Exception, "FixedPointIterator: TNNMG did not converge");
        break;
podlesny's avatar
.  
podlesny committed
    alpha = newAlpha;
podlesny's avatar
.  
podlesny committed

  if (fixedPointIteration == fixedPointMaxIterations_)
    DUNE_THROW(Dune::Exception, "FPI failed to converge");

  nBodyAssembler_.postprocess(total_v, velocityIterates);
podlesny's avatar
.  
podlesny committed
  updaters.rate_->postProcess(velocityIterates);
podlesny's avatar
podlesny committed
  //print(velocityIterates, "velocityIterates end:");
  // Cannot use return { fixedPointIteration, multigridIterations };
  // with gcc 4.9.2, see also http://stackoverflow.com/a/37777814/179927
  FixedPointIterationCounter ret;
  ret.iterations = fixedPointIteration;
  ret.multigridIterations = multigridIterations;
  return ret;
podlesny's avatar
podlesny committed
/*std::ostream &operator<<(std::ostream &stream,
                         FixedPointIterationCounter const &fpic) {
  return stream << "(" << fpic.iterations << "," << fpic.multigridIterations
                << ")";
podlesny's avatar
podlesny committed
}*/
podlesny's avatar
podlesny committed
template <class Factory, class NBodyAssembler, class Updaters, class ErrorNorms>
podlesny's avatar
podlesny committed
void FixedPointIterator<Factory, NBodyAssembler, Updaters, ErrorNorms>::split(
podlesny's avatar
.  
podlesny committed
    const Vector& v,
podlesny's avatar
podlesny committed
    std::vector<Vector>& splitV) const {
podlesny's avatar
.  
podlesny committed

podlesny's avatar
podlesny committed
    const size_t nBodies = nBodyAssembler_.nGrids();
podlesny's avatar
.  
podlesny committed

podlesny's avatar
.  
podlesny committed
    size_t globalIdx = 0;
podlesny's avatar
podlesny committed
    splitV.resize(nBodies);
podlesny's avatar
.  
podlesny committed
    for (size_t bodyIdx=0; bodyIdx<nBodies; bodyIdx++) {
podlesny's avatar
podlesny committed
        auto& splitV_ = splitV[bodyIdx];
podlesny's avatar
.  
podlesny committed

podlesny's avatar
podlesny committed
        splitV_.resize(nBodyAssembler_.grids_[bodyIdx]->size(dims));
podlesny's avatar
.  
podlesny committed

podlesny's avatar
podlesny committed
        for (size_t i=0; i<splitV_.size(); i++) {
            splitV_[i] = v[globalIdx];
podlesny's avatar
.  
podlesny committed
            globalIdx++;
        }
    }

podlesny's avatar
.  
podlesny committed

podlesny's avatar
.  
podlesny committed
   /*
podlesny's avatar
.  
podlesny committed
        boundaryNodes =
podlesny's avatar
.  
podlesny committed

podlesny's avatar
.  
podlesny committed
        const auto gridView = contactCouplings[couplingIndices[0]]->nonmortarBoundary().gridView();
podlesny's avatar
.  
podlesny committed

podlesny's avatar
.  
podlesny committed
        Dune::MultipleCodimMultipleGeomTypeMapper<
            decltype(gridView), Dune::MCMGVertexLayout> const vertexMapper(gridView, Dune::mcmgVertexLayout());
podlesny's avatar
.  
podlesny committed

podlesny's avatar
.  
podlesny committed
        for (auto it = gridView.template begin<block_size>(); it != gridView.template end<block_size>(); ++it) {
            const auto i = vertexMapper.index(*it);
podlesny's avatar
.  
podlesny committed

podlesny's avatar
.  
podlesny committed
            for (size_t j=0; j<couplingIndices.size(); j++) {
                const auto couplingIdx = couplingIndices[j];
podlesny's avatar
.  
podlesny committed

podlesny's avatar
.  
podlesny committed
                if (not contactCouplings[couplingIdx]->nonmortarBoundary().containsVertex(i))
                  continue;
podlesny's avatar
.  
podlesny committed

podlesny's avatar
.  
podlesny committed
                localToGlobal_.emplace_back(i);
                restrictions_.emplace_back(weights[bodyIdx][i], weightedNormalStress[bodyIdx][i],
                                          couplings[i]->frictionData()(geoToPoint(it->geometry())));
                break;
podlesny's avatar
.  
podlesny committed
            }

podlesny's avatar
.  
podlesny committed
            globalIdx++;
podlesny's avatar
.  
podlesny committed
        }
podlesny's avatar
.  
podlesny committed
        maxIndex_[bodyIdx] = globalIdx;
    }*/
podlesny's avatar
.  
podlesny committed
}

#include "fixedpointiterator_tmpl.cc"