diff --git a/src/data-structures/program_state.hh b/src/data-structures/program_state.hh index e9db4febf7871c3cfdbb9aae21e5c3209ccd4f83..6fbc95c173549a5a73470dae08e0a95b5c8e0583 100644 --- a/src/data-structures/program_state.hh +++ b/src/data-structures/program_state.hh @@ -25,6 +25,12 @@ #include "../spatial-solving/tnnmg/zerononlinearity.hh" #include "../utils/debugutils.hh" + +#include <dune/solvers/iterationsteps/truncatedblockgsstep.hh> +#include <dune/solvers/iterationsteps/multigridstep.hh> + +#include "../spatial-solving/preconditioners/nbodycontacttransfer.hh" + template <class VectorTEMPLATE, class ScalarVectorTEMPLATE> class BodyState { public: using Vector = VectorTEMPLATE; @@ -98,8 +104,17 @@ template <class VectorTEMPLATE, class ScalarVectorTEMPLATE> class ProgramState { const auto& preconditionerParset = parset.sub("solver.tnnmg.linear.preconditioner"); + std::cout << "-- setupInitialConditions --" << std::endl; + std::cout << "----------------------------" << std::endl; + + /* + std::cout << "Building preconditioner..." << std::endl; using Preconditioner = MultilevelPatchPreconditioner<ContactNetwork, Matrix, Vector>; Dune::BitSetVector<1> activeLevels(contactNetwork.nLevels(), true); + /*Dune::BitSetVector<1> activeLevels(contactNetwork.nLevels(), false); + activeLevels.back() = true; + activeLevels[activeLevels.size()-2] = true;*/ + /*print(activeLevels, "activeLevels:"); Preconditioner preconditioner(preconditionerParset, contactNetwork, activeLevels); preconditioner.build(); @@ -110,7 +125,31 @@ template <class VectorTEMPLATE, class ScalarVectorTEMPLATE> class ProgramState { linearSolverStep.setPreconditioner(preconditioner); EnergyNorm<Matrix, Vector> energyNorm(linearSolverStep); - LinearSolver linearSolver(linearSolverStep, parset.get<size_t>("solver.tnnmg.linear.maximumIterations"), parset.get<double>("solver.tnnmg.linear.tolerance"), energyNorm, Solver::QUIET); + LinearSolver linearSolver(linearSolverStep, parset.get<size_t>("solver.tnnmg.linear.maximumIterations"), parset.get<double>("solver.tnnmg.linear.tolerance"), energyNorm, Solver::FULL); + */ + using LinearSolver = typename Dune::Solvers::LoopSolver<Vector, BitVector>; + using TransferOperator = NBodyContactTransfer<ContactNetwork, Vector>; + using TransferOperators = std::vector<std::shared_ptr<TransferOperator>>; + + TransferOperators transfer(contactNetwork.nLevels()-1); + for (size_t i=0; i<transfer.size(); i++) { + transfer[i] = std::make_shared<TransferOperator>(); + transfer[i]->setup(contactNetwork, i, i+1); + } + + // Remove any recompute filed so that initially the full transferoperator is assembled + for (size_t i=0; i<transfer.size(); i++) + std::dynamic_pointer_cast<TruncatedMGTransfer<Vector> >(transfer[i])->setRecomputeBitField(nullptr); + + auto smoother = TruncatedBlockGSStep<Matrix, Vector>{}; + auto linearMultigridStep = std::make_shared<Dune::Solvers::MultigridStep<Matrix, Vector> >(); + linearMultigridStep->setMGType(1, 3, 3); + linearMultigridStep->setSmoother(&smoother); + linearMultigridStep->setTransferOperators(transfer); + + EnergyNorm<Matrix, Vector> mgNorm(*linearMultigridStep); + LinearSolver mgSolver(linearMultigridStep, parset.get<size_t>("solver.tnnmg.linear.maximumIterations"), parset.get<double>("solver.tnnmg.linear.tolerance"), mgNorm, Solver::FULL); + // Solving a linear problem with a multigrid solver auto const solveLinearProblem = [&]( @@ -177,7 +216,8 @@ template <class VectorTEMPLATE, class ScalarVectorTEMPLATE> class ProgramState { // set up TNMMG solver using Factory = SolverFactory<Functional, BitVector>; - Factory factory(parset.sub("solver.tnnmg"), J, linearSolver, _dirichletNodes); + //Factory factory(parset.sub("solver.tnnmg"), J, linearSolver, _dirichletNodes); + Factory factory(parset.sub("solver.tnnmg"), J, mgSolver, _dirichletNodes); /* std::vector<BitVector> bodyDirichletNodes; nBodyAssembler.postprocess(_dirichletNodes, bodyDirichletNodes); @@ -270,10 +310,12 @@ template <class VectorTEMPLATE, class ScalarVectorTEMPLATE> class ProgramState { } }*/ + std::cout << "solving linear problem for u..." << std::endl; + solveLinearProblem(dirichletNodes, contactNetwork.matrices().elasticity, ell0, u, parset.sub("u0.solver")); - print(u, "initial u:"); + //print(u, "initial u:"); // Initial acceleration: Computed in agreement with Ma = ell0 - Au // (without Dirichlet constraints), again assuming dPhi(v = 0) = 0 @@ -300,11 +342,13 @@ template <class VectorTEMPLATE, class ScalarVectorTEMPLATE> class ProgramState { Dune::MatrixVector::subtractProduct(accelerationRHS[i], *body->matrices().elasticity, u[i]); } + std::cout << "solving linear problem for a..." << std::endl; + BitVector noNodes(dirichletNodes.size(), false); solveLinearProblem(noNodes, contactNetwork.matrices().mass, accelerationRHS, a, parset.sub("a0.solver")); - print(a, "initial a:"); + //print(a, "initial a:"); } private: diff --git a/src/multi-body-problem-2D.cfg b/src/multi-body-problem-2D.cfg index c0b758a8abf73e4ff14785138db64bf7afd2a99b..4fc63ee9679dee491c37c99fd18ea8694f476fa1 100644 --- a/src/multi-body-problem-2D.cfg +++ b/src/multi-body-problem-2D.cfg @@ -21,4 +21,4 @@ tolerance = 1e-5 tolerance = 1e-10 [solver.tnnmg.linear.preconditioner] -tolerance = 1e-10 +tolerance = 1e-8 diff --git a/src/multi-body-problem.cc b/src/multi-body-problem.cc index 4215f278ae91870ffba03d7c21cd2eddf3a26e90..f7ef93e5d7857bff2473da67f5a0ff87385107d7 100644 --- a/src/multi-body-problem.cc +++ b/src/multi-body-problem.cc @@ -190,7 +190,7 @@ int main(int argc, char *argv[]) { } contactNetwork.setDeformation(def);*/ - const auto & coarseContactNetwork = *contactNetwork.level(3); + /* const auto & coarseContactNetwork = *contactNetwork.level(3); const auto & fineContactNetwork = *contactNetwork.level(4); // SupportPatchFactory<typename ContactNetwork::LevelContactNetwork> supportPatchFactory(coarseContactNetwork, fineContactNetwork); size_t bodyID = 2; @@ -222,7 +222,7 @@ int main(int argc, char *argv[]) { dofs[j] = j; } writeToVTK(gv, dofs, "", "body_" + std::to_string(i) + "_fine"); - } + } */ /* using Patch = typename SupportPatchFactory<typename ContactNetwork::LevelContactNetwork>::Patch; @@ -267,9 +267,6 @@ int main(int argc, char *argv[]) { } } */ - std::cout << "Done! :)" << std::endl; - //return 1; - //printMortarBasis<Vector>(contactNetwork.nBodyAssembler()); // ----------------- @@ -417,7 +414,7 @@ int main(int argc, char *argv[]) { } }*/ - print(totalDirichletNodes, "totalDirichletNodes:"); + //print(totalDirichletNodes, "totalDirichletNodes:"); using Functional = Functional<Matrix&, Vector&, GlobalFriction<Matrix, Vector>&, Vector&, Vector&, field_type>; using NonlinearFactory = SolverFactory<Functional, BitVector>; @@ -433,18 +430,18 @@ int main(int argc, char *argv[]) { BoundaryNodes dirichletNodes; contactNetwork.boundaryNodes("dirichlet", dirichletNodes); - for (size_t i=0; i<dirichletNodes.size(); i++) { + /*for (size_t i=0; i<dirichletNodes.size(); i++) { for (size_t j=0; j<dirichletNodes[i].size(); j++) { print(*dirichletNodes[i][j], "dirichletNodes_body_" + std::to_string(i) + "_boundary_" + std::to_string(j)); } - } + }*/ std::vector<const Dune::BitSetVector<1>*> frictionNodes; contactNetwork.frictionNodes(frictionNodes); - for (size_t i=0; i<frictionNodes.size(); i++) { + /*for (size_t i=0; i<frictionNodes.size(); i++) { print(*frictionNodes[i], "frictionNodes_body_" + std::to_string(i)); - } + }*/ Updaters current( initRateUpdater( @@ -508,7 +505,7 @@ int main(int argc, char *argv[]) { std::signal(SIGINT, handleSignal); std::signal(SIGTERM, handleSignal); - /* +/* // set patch preconditioner for linear correction in TNNMG method using PatchSolver = typename Dune::Solvers::LoopSolver<Vector, BitVector>; using Preconditioner = MultilevelPatchPreconditioner<ContactNetwork, PatchSolver, Matrix, Vector>; @@ -527,21 +524,21 @@ int main(int argc, char *argv[]) { Preconditioner preconditioner(contactNetwork, activeLevels, preconditionerParset.get<Preconditioner::Mode>("mode")); preconditioner.setPatchSolver(patchSolver); preconditioner.setPatchDepth(preconditionerParset.get<size_t>("patchDepth")); - +*/ // set adaptive time stepper typename ContactNetwork::ExternalForces externalForces; contactNetwork.externalForces(externalForces); - AdaptiveTimeStepper<NonlinearFactory, std::decay_t<decltype(nBodyAssembler)>, Updaters, std::decay_t<decltype(stateEnergyNorms)>> - adaptiveTimeStepper(parset, nBodyAssembler, totalDirichletNodes, globalFriction, frictionNodes, current, + AdaptiveTimeStepper<NonlinearFactory, std::decay_t<decltype(contactNetwork)>, Updaters, std::decay_t<decltype(stateEnergyNorms)>> + adaptiveTimeStepper(parset, contactNetwork, totalDirichletNodes, globalFriction, frictionNodes, current, programState.relativeTime, programState.relativeTau, externalForces, stateEnergyNorms, mustRefine); while (!adaptiveTimeStepper.reachedEnd()) { programState.timeStep++; - preconditioner.build(); - iterationCount = adaptiveTimeStepper.advance(preconditioner); + //preconditioner.build(); + iterationCount = adaptiveTimeStepper.advance(); programState.relativeTime = adaptiveTimeStepper.relativeTime_; programState.relativeTau = adaptiveTimeStepper.relativeTau_; @@ -559,6 +556,8 @@ int main(int argc, char *argv[]) { report(); + break; + if (programState.timeStep==50) { std::cout << "limit of timeSteps reached!" << std::endl; break; // TODO remove after debugging @@ -569,7 +568,7 @@ int main(int argc, char *argv[]) { break; } } - */ + std::cout.rdbuf(coutbuf); //reset to standard output again diff --git a/src/multi-body-problem.cfg b/src/multi-body-problem.cfg index 8678a5ddf21e17c9da8fabd9253dee59868ae1d2..7188eed1b5851c795b2903d8000846c4a89c6450 100644 --- a/src/multi-body-problem.cfg +++ b/src/multi-body-problem.cfg @@ -11,7 +11,7 @@ vtk.write = true [problem] finalTime = 100 # [s] #1000 -bodyCount = 4 +bodyCount = 2 [body] bulkModulus = 0.5e5 # [Pa] @@ -49,11 +49,11 @@ relativeTau = 1e-4 # 1e-6 scheme = newmark [u0.solver] -maximumIterations = 10000 +maximumIterations = 100 verbosity = full [a0.solver] -maximumIterations = 10000 +maximumIterations = 100 verbosity = full [v.solver] diff --git a/src/spatial-solving/fixedpointiterator.cc b/src/spatial-solving/fixedpointiterator.cc index 99456a3be28ad70481fda8cd4b59703215eae5f5..633eb1aa03df1c5bf50630d0a948b6ebbe2a0d5e 100644 --- a/src/spatial-solving/fixedpointiterator.cc +++ b/src/spatial-solving/fixedpointiterator.cc @@ -30,6 +30,11 @@ #include "../utils/tobool.hh" #include "../utils/debugutils.hh" +#include <dune/solvers/solvers/loopsolver.hh> +#include <dune/solvers/iterationsteps/truncatedblockgsstep.hh> +#include <dune/solvers/iterationsteps/multigridstep.hh> + +#include "../spatial-solving/preconditioners/nbodycontacttransfer.hh" void FixedPointIterationCounter::operator+=( FixedPointIterationCounter const &other) { @@ -37,16 +42,16 @@ void FixedPointIterationCounter::operator+=( multigridIterations += other.multigridIterations; } -template <class Factory, class NBodyAssembler, class Updaters, class ErrorNorms> -FixedPointIterator<Factory, NBodyAssembler, Updaters, ErrorNorms>::FixedPointIterator( +template <class Factory, class ContactNetwork, class Updaters, class ErrorNorms> +FixedPointIterator<Factory, ContactNetwork, Updaters, ErrorNorms>::FixedPointIterator( Dune::ParameterTree const &parset, - NBodyAssembler& nBodyAssembler, + const ContactNetwork& contactNetwork, const IgnoreVector& ignoreNodes, GlobalFriction& globalFriction, const std::vector<const BitVector*>& bodywiseNonmortarBoundaries, const ErrorNorms& errorNorms) : parset_(parset), - nBodyAssembler_(nBodyAssembler), + contactNetwork_(contactNetwork), ignoreNodes_(ignoreNodes), globalFriction_(globalFriction), bodywiseNonmortarBoundaries_(bodywiseNonmortarBoundaries), @@ -58,17 +63,18 @@ FixedPointIterator<Factory, NBodyAssembler, Updaters, ErrorNorms>::FixedPointIte verbosity_(parset.get<Solver::VerbosityMode>("v.solver.verbosity")), errorNorms_(errorNorms) {} -template <class Factory, class NBodyAssembler, class Updaters, class ErrorNorms> -template <class Preconditioner> +template <class Factory, class ContactNetwork, class Updaters, class ErrorNorms> FixedPointIterationCounter -FixedPointIterator<Factory, NBodyAssembler, Updaters, ErrorNorms>::run( - Updaters updaters, Preconditioner&& preconditioner, +FixedPointIterator<Factory, ContactNetwork, Updaters, ErrorNorms>::run( + Updaters updaters, const std::vector<Matrix>& velocityMatrices, const std::vector<Vector>& velocityRHSs, std::vector<Vector>& velocityIterates) { std::cout << "FixedPointIterator::run()" << std::endl; - const auto nBodies = nBodyAssembler_.nGrids(); + const auto& nBodyAssembler = contactNetwork_.nBodyAssembler(); + + const auto nBodies = nBodyAssembler.nGrids(); std::vector<const Matrix*> matrices_ptr(nBodies); for (int i=0; i<nBodies; i++) { @@ -77,17 +83,17 @@ FixedPointIterator<Factory, NBodyAssembler, Updaters, ErrorNorms>::run( // assemble full global contact problem Matrix bilinearForm; - nBodyAssembler_.assembleJacobian(matrices_ptr, bilinearForm); + nBodyAssembler.assembleJacobian(matrices_ptr, bilinearForm); //print(bilinearForm, "bilinearForm:"); Vector totalRhs; - nBodyAssembler_.assembleRightHandSide(velocityRHSs, totalRhs); + nBodyAssembler.assembleRightHandSide(velocityRHSs, totalRhs); //print(totalRhs, "totalRhs:"); // get lower and upper obstacles - const auto& totalObstacles = nBodyAssembler_.totalObstacles_; + const auto& totalObstacles = nBodyAssembler.totalObstacles_; Vector lower(totalObstacles.size()); Vector upper(totalObstacles.size()); @@ -101,10 +107,10 @@ FixedPointIterator<Factory, NBodyAssembler, Updaters, ErrorNorms>::run( } } - print(totalObstacles, "totalObstacles:"); + //print(totalObstacles, "totalObstacles:"); - print(lower, "lower obstacles:"); - print(upper, "upper obstacles:"); + //print(lower, "lower obstacles:"); + //print(upper, "upper obstacles:"); // comput velocity obstacles Vector vLower, vUpper; @@ -113,20 +119,44 @@ FixedPointIterator<Factory, NBodyAssembler, Updaters, ErrorNorms>::run( updaters.rate_->extractOldDisplacement(u0); Vector totalu0, totalv0; - nBodyAssembler_.concatenateVectors(u0, totalu0); - nBodyAssembler_.concatenateVectors(v0, totalv0); + nBodyAssembler.concatenateVectors(u0, totalu0); + nBodyAssembler.concatenateVectors(v0, totalv0); updaters.rate_->velocityObstacles(totalu0, lower, totalv0, vLower); updaters.rate_->velocityObstacles(totalu0, upper, totalv0, vUpper); - print(vLower, "vLower obstacles:"); - print(vUpper, "vUpper obstacles:"); + //print(vLower, "vLower obstacles:"); + //print(vUpper, "vUpper obstacles:"); std::cout << "- Problem assembled: success" << std::endl; + using LinearSolver = typename Dune::Solvers::LoopSolver<Vector, IgnoreVector>; + using TransferOperator = NBodyContactTransfer<ContactNetwork, Vector>; + using TransferOperators = std::vector<std::shared_ptr<TransferOperator>>; + + TransferOperators transfer(contactNetwork_.nLevels()-1); + for (size_t i=0; i<transfer.size(); i++) { + transfer[i] = std::make_shared<TransferOperator>(); + transfer[i]->setup(contactNetwork_, i, i+1); + } + + // Remove any recompute filed so that initially the full transferoperator is assembled + for (size_t i=0; i<transfer.size(); i++) + std::dynamic_pointer_cast<TruncatedMGTransfer<Vector> >(transfer[i])->setRecomputeBitField(nullptr); + + auto smoother = TruncatedBlockGSStep<Matrix, Vector>{}; + auto linearMultigridStep = std::make_shared<Dune::Solvers::MultigridStep<Matrix, Vector> >(); + linearMultigridStep->setMGType(1, 3, 3); + linearMultigridStep->setSmoother(&smoother); + linearMultigridStep->setTransferOperators(transfer); + + EnergyNorm<Matrix, Vector> mgNorm(*linearMultigridStep); + LinearSolver mgSolver(linearMultigridStep, parset_.get<size_t>("solver.tnnmg.linear.maximumIterations"), parset_.get<double>("solver.tnnmg.linear.tolerance"), mgNorm, Solver::QUIET); + + // set up functional and TNMMG solver Functional J(bilinearForm, totalRhs, globalFriction_, vLower, vUpper); - Factory solverFactory(parset_.sub("solver.tnnmg"), J, std::forward<Preconditioner>(preconditioner), ignoreNodes_); + Factory solverFactory(parset_.sub("solver.tnnmg"), J, mgSolver, ignoreNodes_); auto step = solverFactory.step(); std::cout << "- Functional and TNNMG step setup: success" << std::endl; @@ -147,7 +177,7 @@ FixedPointIterator<Factory, NBodyAssembler, Updaters, ErrorNorms>::run( globalFriction_.updateAlpha(alpha); Vector totalVelocityIterate; - nBodyAssembler_.nodalToTransformed(velocityIterates, totalVelocityIterate); + nBodyAssembler.nodalToTransformed(velocityIterates, totalVelocityIterate); //print(velocityIterates, "velocityIterates:"); //print(totalVelocityIterate, "totalVelocityIterate:"); @@ -164,8 +194,8 @@ FixedPointIterator<Factory, NBodyAssembler, Updaters, ErrorNorms>::run( std::cout << "-- Solved" << std::endl; const auto& tnnmgSol = step->getSol(); - nBodyAssembler_.postprocess(tnnmgSol, velocityIterates); - //nBodyAssembler_.postprocess(totalVelocityIterate, velocityIterates); + nBodyAssembler.postprocess(tnnmgSol, velocityIterates); + //nBodyAssembler.postprocess(totalVelocityIterate, velocityIterates); //print(totalVelocityIterate, "totalVelocityIterate:"); //print(velocityIterates, "velocityIterates:"); @@ -239,13 +269,14 @@ std::ostream &operator<<(std::ostream &stream, << ")"; } -template <class Factory, class NBodyAssembler, class Updaters, class ErrorNorms> -void FixedPointIterator<Factory, NBodyAssembler, Updaters, ErrorNorms>::relativeVelocities( +template <class Factory, class ContactNetwork, class Updaters, class ErrorNorms> +void FixedPointIterator<Factory, ContactNetwork, Updaters, ErrorNorms>::relativeVelocities( const Vector& v, std::vector<Vector>& v_rel) const { - const size_t nBodies = nBodyAssembler_.nGrids(); - // const auto& contactCouplings = nBodyAssembler_.getContactCouplings(); + const auto& nBodyAssembler = contactNetwork_.nBodyAssembler(); + const size_t nBodies = nBodyAssembler.nGrids(); + // const auto& contactCouplings = nBodyAssembler.getContactCouplings(); size_t globalIdx = 0; v_rel.resize(nBodies); diff --git a/src/spatial-solving/fixedpointiterator.hh b/src/spatial-solving/fixedpointiterator.hh index c7c74189131f7cb053e85c223bdafe73639a4c92..c4d59c3dfdc1ff88ca850dba527077be7a65dbcf 100644 --- a/src/spatial-solving/fixedpointiterator.hh +++ b/src/spatial-solving/fixedpointiterator.hh @@ -23,7 +23,7 @@ struct FixedPointIterationCounter { std::ostream &operator<<(std::ostream &stream, FixedPointIterationCounter const &fpic); -template <class Factory, class NBodyAssembler, class Updaters, class ErrorNorms> +template <class Factory, class ContactNetwork, class Updaters, class ErrorNorms> class FixedPointIterator { using Functional = typename Factory::Functional; using ScalarVector = typename Updaters::StateUpdater::ScalarVector; @@ -46,22 +46,20 @@ class FixedPointIterator { public: FixedPointIterator(const Dune::ParameterTree& parset, - NBodyAssembler& nBodyAssembler, + const ContactNetwork& contactNetwork, const IgnoreVector& ignoreNodes, GlobalFriction& globalFriction, const std::vector<const BitVector*>& bodywiseNonmortarBoundaries, const ErrorNorms& errorNorms); - template <class Preconditioner> FixedPointIterationCounter run(Updaters updaters, - Preconditioner&& preconditioner, const std::vector<Matrix>& velocityMatrices, const std::vector<Vector>& velocityRHSs, std::vector<Vector>& velocityIterates); private: const Dune::ParameterTree& parset_; - NBodyAssembler& nBodyAssembler_; + const ContactNetwork& contactNetwork_; const IgnoreVector& ignoreNodes_; GlobalFriction& globalFriction_; diff --git a/src/spatial-solving/fixedpointiterator_tmpl.cc b/src/spatial-solving/fixedpointiterator_tmpl.cc index 33acfce6a619c1be6a75b7c590503fb0b7beae44..5f4b30cff6d376cb6550cb2388b1b176a61df764 100644 --- a/src/spatial-solving/fixedpointiterator_tmpl.cc +++ b/src/spatial-solving/fixedpointiterator_tmpl.cc @@ -14,7 +14,6 @@ #include "../time-stepping/state/stateupdater.hh" #include "../time-stepping/updaters.hh" -using NBodyAssembler = typename MyContactNetwork::NBodyAssembler; using BoundaryNodes = typename MyContactNetwork::BoundaryNodes; using BoundaryFunctions = typename MyContactNetwork::BoundaryFunctions; @@ -25,4 +24,4 @@ using MyUpdaters = Updaters<MyRateUpdater, MyStateUpdater>; using ErrorNorms = typename MyContactNetwork::StateEnergyNorms; -template class FixedPointIterator<MySolverFactory, NBodyAssembler, MyUpdaters, ErrorNorms>; +template class FixedPointIterator<MySolverFactory, MyContactNetwork, MyUpdaters, ErrorNorms>; diff --git a/src/spatial-solving/preconditioners/levelpatchpreconditioner.hh b/src/spatial-solving/preconditioners/levelpatchpreconditioner.hh index bd5ff1a28e970d3c38ac1c2565fe601cba7813cc..93612ee520b8a60f0efd1d309b94c11f93c75133 100644 --- a/src/spatial-solving/preconditioners/levelpatchpreconditioner.hh +++ b/src/spatial-solving/preconditioners/levelpatchpreconditioner.hh @@ -13,6 +13,7 @@ #include "../../data-structures/levelcontactnetwork.hh" #include "supportpatchfactory.hh" +#include "../tnnmg/localproblem.hh" #include <dune/localfunctions/lagrange/pqkfactory.hh> @@ -108,6 +109,8 @@ class LevelPatchPreconditioner : public LinearIterationStep<MatrixType, VectorTy for (size_t bodyIdx=0; bodyIdx<levelContactNetwork_.nBodies(); bodyIdx++) { const auto& gridView = levelContactNetwork_.body(bodyIdx)->gridView(); + //printDofLocation(gridView); + for (const auto& e : elements(gridView)) { const auto& refElement = Dune::ReferenceElements<double, dim>::general(e.type()); @@ -117,6 +120,27 @@ class LevelPatchPreconditioner : public LinearIterationStep<MatrixType, VectorTy if (!vertexVisited[globalIdx][0]) { vertexVisited[globalIdx][0] = true; patchFactory_.build(bodyIdx, e, i, patches_[globalIdx], patchDepth_); + + /*print(patches_[globalIdx], "patch:"); + + size_t c = 0; + for (size_t j=0; j<levelContactNetwork_.nBodies(); j++) { + const auto& gv = fineContactNetwork_.body(j)->gridView(); + + printDofLocation(gv); + + Dune::BlockVector<Dune::FieldVector<ctype, 1>> patchVec(gv.size(dim)); + for (size_t l=0; l<patchVec.size(); l++) { + if (patches_[globalIdx][c++][0]) { + patchVec[l][0] = 1; + } + } + + //print(patchVec, "patchVec"); + + // output patch + writeToVTK(gv, patchVec, "", "level_" + std::to_string(level_) + "_patch_" + std::to_string(globalIdx) + "_body_" + std::to_string(j)); + }*/ } } } @@ -160,6 +184,7 @@ class LevelPatchPreconditioner : public LinearIterationStep<MatrixType, VectorTy for (const auto& p : patches_) { x = 0; + /* auto& step = patchSolver_->getIterationStep(); dynamic_cast<LinearIterationStep<MatrixType, VectorType>&>(step).setProblem(*this->mat_, x, *this->rhs_); step.setIgnore(p); @@ -168,7 +193,29 @@ class LevelPatchPreconditioner : public LinearIterationStep<MatrixType, VectorTy patchSolver_->preprocess(); patchSolver_->solve(); - *(this->x_) += step.getSol(); + *(this->x_) += step.getSol();*/ + + auto ignore = this->ignore(); + for (size_t i=0; i<ignore.size(); i++) { + for (size_t d=0; d<dim; d++) { + if (p[i][d]) + ignore[i][d] = true; + } + } + + LocalProblem<MatrixType, VectorType> localProblem(*this->mat_, *this->rhs_, ignore); + Vector newR; + localProblem.getLocalRhs(x, newR); + + /* print(ignore, "ignore:"); + print(*this->mat_, "Mat:"); + print(localProblem.getMat(), "localMat:");*/ + + patchSolver_->setProblem(localProblem.getMat(), x, newR); + patchSolver_->preprocess(); + patchSolver_->solve(); + + *(this->x_) += x; } } diff --git a/src/spatial-solving/preconditioners/multilevelpatchpreconditioner.hh b/src/spatial-solving/preconditioners/multilevelpatchpreconditioner.hh index d16c2a652dffd03247141e5a308c7ad85ef639ab..68fa9b43f98bafdd3c6aa293f81981874b5f26b4 100644 --- a/src/spatial-solving/preconditioners/multilevelpatchpreconditioner.hh +++ b/src/spatial-solving/preconditioners/multilevelpatchpreconditioner.hh @@ -10,20 +10,27 @@ #include <dune/solvers/norms/energynorm.hh> #include <dune/solvers/solvers/loopsolver.hh> +#include <dune/solvers/solvers/umfpacksolver.hh> #include <dune/solvers/iterationsteps/blockgssteps.hh> +//#include <dune/solvers/iterationsteps/blockgsstep.hh> #include <dune/solvers/iterationsteps/cgstep.hh> #include <dune/solvers/iterationsteps/lineariterationstep.hh> #include "nbodycontacttransfer.hh" #include "levelpatchpreconditioner.hh" +#include "../../utils/debugutils.hh" + template <class ContactNetwork, class MatrixType, class VectorType> class MultilevelPatchPreconditioner : public LinearIterationStep<MatrixType, VectorType> { public: //struct Mode { enum ModeType {additive, multiplicative}; }; private: - using PatchSolver = typename Dune::Solvers::LoopSolver<Vector, BitVector>; + using Base = LinearIterationStep<MatrixType, VectorType>; + + //using PatchSolver = typename Dune::Solvers::LoopSolver<Vector, BitVector>; + using PatchSolver = Dune::Solvers::UMFPackSolver<MatrixType, VectorType>; using LevelContactNetwork = typename ContactNetwork::LevelContactNetwork; using LevelPatchPreconditioner = LevelPatchPreconditioner<LevelContactNetwork, PatchSolver, MatrixType, VectorType>; @@ -44,10 +51,14 @@ class MultilevelPatchPreconditioner : public LinearIterationStep<MatrixType, Vec std::vector<VectorType> levelX_; std::vector<VectorType> levelRhs_; + std::vector<BitVector> ignoreHierarchy_; + + std::vector<std::shared_ptr<EnergyNorm<MatrixType, VectorType>>> levelErrorNorms_; + std::vector<std::shared_ptr<LinearIterationStep<MatrixType, VectorType>>> levelItSteps_; std::vector<std::shared_ptr<PatchSolver>> levelSolvers_; std::vector<BitVector> recompute_; - std::vector<BitVector> truncation_; + //std::vector<BitVector> truncation_; std::vector<std::shared_ptr<MGTransfer>> mgTransfer_; //TODO public: @@ -84,29 +95,36 @@ class MultilevelPatchPreconditioner : public LinearIterationStep<MatrixType, Vec } } + levelMat_.resize(size()-1); levelX_.resize(size()); levelRhs_.resize(size()); // init patch solvers levelSolvers_.resize(size()); - auto coarseStep = Dune::Solvers::BlockGSStepFactory<MatrixType, VectorType>::create(Dune::Solvers::BlockGS::LocalSolvers::direct(0.0)); - EnergyNorm<MatrixType, VectorType> coarseEnergyNorm(coarseStep); - levelSolvers_[0] = std::make_shared<PatchSolver>(coarseStep, + levelItSteps_.resize(size()); + levelErrorNorms_.resize(size()); + //auto coarseStep = + levelItSteps_[0] = Dune::Solvers::BlockGSStepFactory<MatrixType, VectorType>::createPtr(Dune::Solvers::BlockGS::LocalSolvers::direct(0.0)); + levelErrorNorms_[0] = std::make_shared<EnergyNorm<MatrixType, VectorType>>(*levelItSteps_[0].get()); + levelSolvers_[0] = /*std::make_shared<PatchSolver>(*levelItSteps_[0].get(), parset.get<size_t>("maximumIterations"), parset.get<double>("tolerance"), - coarseEnergyNorm, + *levelErrorNorms_[0].get(), parset.get<Solver::VerbosityMode>("verbosity"), - false); // absolute error + false); // absolute error */ + std::make_shared<PatchSolver>(); for (size_t i=1; i<levelSolvers_.size(); i++) { - auto gsStep = Dune::Solvers::BlockGSStepFactory<MatrixType, VectorType>::create(Dune::Solvers::BlockGS::LocalSolvers::direct(0.0)); - EnergyNorm<MatrixType, VectorType> energyNorm(gsStep); - levelSolvers_[i] = std::make_shared<PatchSolver>(gsStep, + //auto gsStep = Dune::Solvers::BlockGSStepFactory<MatrixType, VectorType>::create(Dune::Solvers::BlockGS::LocalSolvers::direct(0.0)); + levelItSteps_[i] = Dune::Solvers::BlockGSStepFactory<MatrixType, VectorType>::createPtr(Dune::Solvers::BlockGS::LocalSolvers::direct(0.0)); + levelErrorNorms_[i] = std::make_shared<EnergyNorm<MatrixType, VectorType>>(*levelItSteps_[i].get()); + levelSolvers_[i] = /*std::make_shared<PatchSolver>(*levelItSteps_[i].get(), parset.get<size_t>("maximumIterations"), parset.get<double>("tolerance"), - energyNorm, + *levelErrorNorms_[i].get(), parset.get<Solver::VerbosityMode>("verbosity"), - false); // absolute error + false); // absolute error */ + std::make_shared<PatchSolver>(); levelPatchPreconditioners_[i]->setPatchSolver(levelSolvers_[i]); } @@ -118,37 +136,90 @@ class MultilevelPatchPreconditioner : public LinearIterationStep<MatrixType, Vec mgTransfer_[i]->setup(contactNetwork_, levelPatchPreconditioners_[i+1]->level(), levelPatchPreconditioners_[i+1]->fineLevel()); } - //TODO - //mgTransfer_.push_back(std::make_shared<MGTransfer>(coarseGlobalPreconditioner_->basis(), *allFaultBasis_)); - // Remove any recompute filed so that initially the full transferoperator is assembled for (size_t i=0; i<mgTransfer_.size(); i++) std::dynamic_pointer_cast<TruncatedMGTransfer<VectorType> >(mgTransfer_[i])->setRecomputeBitField(nullptr); // specify the subset of entries to be reassembled at each iteration - recompute_.resize(size()); + /* recompute_.resize(size()); recompute_[recompute_.size()-1] = contactNetwork_.nBodyAssembler().totalHasObstacle_; for (int i=mgTransfer_.size()-1; i>=0; i--) { std::dynamic_pointer_cast<TruncatedMGTransfer<VectorType> >(mgTransfer_[i])->restrict(recompute_[i+1], recompute_[i]); // std::dynamic_pointer_cast<DenseMultigridTransfer<VectorType, BitVector, MatrixType> >(mgTransfer_[i])->restrict(recompute_[i+1], recompute_[i]); std::dynamic_pointer_cast<TruncatedMGTransfer<VectorType> >(mgTransfer_[i])->setRecomputeBitField(&recompute_[i]); - } + print(recompute_[i], "recompute: "); + }*/ } + void setMatrix(const MatrixType& mat) override { + Base::setMatrix(mat); + + ignoreHierarchy_.resize(size()); + ignoreHierarchy_.back() = Base::ignore(); + for (int i=mgTransfer_.size()-1; i>=0; i--) { + std::dynamic_pointer_cast<TruncatedMGTransfer<VectorType> >(mgTransfer_[i])->restrictToFathers(ignoreHierarchy_[i+1], ignoreHierarchy_[i]); + } + + /* truncation_.resize(size()); + truncation_[size()-1] = Base::ignore(); + print(truncation_.back(), "truncation: "); + for (int i=mgTransfer_.size()-1; i>=0; i--) { + std::dynamic_pointer_cast<TruncatedMGTransfer<VectorType> >(mgTransfer_[i])->restrict(truncation_[i+1], truncation_[i]); + std::dynamic_pointer_cast<TruncatedMGTransfer<VectorType> >(mgTransfer_[i])->setCriticalBitField(&truncation_[i+1]); + print(truncation_[i], "truncation: "); + }*/ + + size_t maxLevel = levelPatchPreconditioners_.size()-1; + levelPatchPreconditioners_[maxLevel]->setMatrix(mat); + + //print(mat, "levelMat_" + std::to_string(maxLevel) + ":"); + + for (int i=levelPatchPreconditioners_.size()-2; i>0; i--) { + const auto& transfer = *mgTransfer_[i]; + + //print(*levelPatchPreconditioners_[i+1]->getMatrix(), "levelMat:"); + //print(levelMat_[i], "coarseMat:"); - void setIgnore(const BitVector& ignore) { - this->setIgnore(ignore); + transfer.galerkinRestrictSetOccupation(*levelPatchPreconditioners_[i+1]->getMatrix(), levelMat_[i]); + transfer.galerkinRestrict(*levelPatchPreconditioners_[i+1]->getMatrix(), levelMat_[i]); + levelPatchPreconditioners_[i]->setMatrix(levelMat_[i]); + + //print(levelMat_[i], "levelMat_" + std::to_string(i) + ":"); + + // Set solution vector sizes for the lower levels + Dune::MatrixVector::resize(levelX_[i], levelMat_[i]); + //Dune::MatrixVector::resize(levelRhs_[i], levelMat_[i]); + } + + // set coarse global problem + const auto& coarseTransfer = *mgTransfer_[0]; + const auto& fineMat = *levelPatchPreconditioners_[1]->getMatrix(); + coarseTransfer.galerkinRestrictSetOccupation(fineMat, levelMat_[0]); + coarseTransfer.galerkinRestrict(fineMat, levelMat_[0]); + + //print(levelMat_[0], "levelMat_0:"); + + /*dynamic_cast<Base&>(levelSolvers_[0]->getIterationStep()).setMatrix(levelMat_[0]); */ + + Dune::MatrixVector::resize(levelX_[0], levelMat_[0]); + //Dune::MatrixVector::resize(levelRhs_[0], levelMat_[0]); + } + + void setTruncation(const BitVector& truncation) { + std::dynamic_pointer_cast<TruncatedMGTransfer<VectorType> >(mgTransfer_.back())->setCriticalBitField(&truncation); + } + + /*void setProblem(const MatrixType& mat, VectorType& x, const VectorType& rhs) override { + LinearIterationStep<MatrixType, VectorType>::setProblem(mat, x, rhs); truncation_.resize(size()); - truncation_[size()-1] = ignore; + truncation_[size()-1] = this->ignore(); + print(truncation_.back(), "truncation: "); for (int i=mgTransfer_.size()-1; i>=0; i--) { std::dynamic_pointer_cast<TruncatedMGTransfer<VectorType> >(mgTransfer_[i])->restrict(truncation_[i+1], truncation_[i]); std::dynamic_pointer_cast<TruncatedMGTransfer<VectorType> >(mgTransfer_[i])->setCriticalBitField(&truncation_[i]); + print(truncation_[i], "truncation: "); } - } - - void setProblem(const MatrixType& mat, VectorType& x, const VectorType& rhs) override { - this->setProblem(mat, x, rhs); size_t maxLevel = levelPatchPreconditioners_.size()-1; levelX_[maxLevel] = x; @@ -176,10 +247,31 @@ class MultilevelPatchPreconditioner : public LinearIterationStep<MatrixType, Vec // EnergyNorm<MatrixType, VectorType> coarseErrorNorm(levelSolvers_[0]->getIterationStep()); // levelSolvers_[0]->setErrorNorm(coarseErrorNorm); - } - + } */ void iterate() { + size_t maxLevel = levelPatchPreconditioners_.size()-1; + levelX_[maxLevel] = *this->getIterate(); + levelRhs_[maxLevel] = *Base::rhs_; + + for (int i=levelPatchPreconditioners_.size()-2; i>0; i--) { + const auto& transfer = *mgTransfer_[i]; + + /*print(levelX_[i+1], "levelX_:"); + print(levelX_[i], "levelX_:"); + print(levelRhs_[i+1], "levelRhs_:"); + print(levelRhs_[i], "levelRhs_:");*/ + + transfer.restrict(levelX_[i+1], levelX_[i]); + transfer.restrict(levelRhs_[i+1], levelRhs_[i]); + } + + // set coarse global problem + const auto& coarseTransfer = *mgTransfer_[0]; + coarseTransfer.restrict(levelX_[1], levelX_[0]); + coarseTransfer.restrict(levelRhs_[1], levelRhs_[0]); + + if (mode_ == additive) iterateAdd(); else @@ -187,26 +279,46 @@ class MultilevelPatchPreconditioner : public LinearIterationStep<MatrixType, Vec } void iterateAdd() { + //print(this->ignore(), "ignore: "); + *(this->x_) = 0; VectorType x; + /* // solve coarse global problem auto& coarseSolver = levelSolvers_[0]; - coarseSolver->getIterationStep().setIgnore(truncation_[0]); + //coarseSolver->getIterationStep().setIgnore(ignoreHierarchy_[0]); + + dynamic_cast<LinearIterationStep<MatrixType, VectorType>&>(levelSolvers_[0]->getIterationStep()).setProblem(levelMat_[0], levelX_[0], levelRhs_[0]); coarseSolver->check(); coarseSolver->preprocess(); coarseSolver->solve(); - mgTransfer_[0]->prolong(coarseSolver->getIterationStep().getSol(), x); + mgTransfer_[0]->prolong(coarseSolver->getIterationStep().getSol(), x); */ - for (size_t i=1; i<levelPatchPreconditioners_.size(); i++) { + + BitVector emptyIgnore0(levelX_[0].size(), false); + LocalProblem<MatrixType, VectorType> localProblem(levelMat_[0], levelRhs_[0], ignoreHierarchy_[0]); + Vector newR; + localProblem.getLocalRhs(levelX_[0], newR); + + auto& coarseSolver = levelSolvers_[0]; + coarseSolver->setProblem(localProblem.getMat(), levelX_[0], newR); + coarseSolver->preprocess(); + coarseSolver->solve(); + + mgTransfer_[0]->prolong(levelX_[0], x); + + //print(x, "MultilevelPatchPreconditioner: x0"); + + for (size_t i=1; i<levelPatchPreconditioners_.size()-1; i++) { const auto& transfer = *mgTransfer_[i]; auto& preconditioner = *levelPatchPreconditioners_[i]; - preconditioner.setIgnore(truncation_[i]); - preconditioner.iterate(); + preconditioner.setIgnore(ignoreHierarchy_[i]); + preconditioner.apply(levelX_[i], levelRhs_[i]); x += preconditioner.getSol(); @@ -214,8 +326,30 @@ class MultilevelPatchPreconditioner : public LinearIterationStep<MatrixType, Vec transfer.prolong(x, newX); x = newX; + //print(x, "MultilevelPatchPreconditioner: x" + std::to_string(i)); } + auto& preconditioner = *levelPatchPreconditioners_.back(); + + preconditioner.setIgnore(ignoreHierarchy_.back()); + preconditioner.apply(levelX_.back(), levelRhs_.back()); + + x += preconditioner.getSol(); + + //print(x, "MultilevelPatchPreconditioner: xmax"); + + + BitVector emptyIgnore(this->x_->size(), false); + LocalProblem<MatrixType, VectorType> globalProblem(*this->mat_.get(), *this->rhs_, emptyIgnore); + globalProblem.getLocalRhs(*this->x_, newR); + VectorType totalX = *(this->x_); + auto& globalSolver = levelSolvers_.back(); + globalSolver->setProblem(globalProblem.getMat(), totalX, newR); + globalSolver->preprocess(); + globalSolver->solve(); + + //print(totalX, "MultilevelPatchPreconditioner: totalX"); + *(this->x_) = x; } diff --git a/src/spatial-solving/preconditioners/supportpatchfactory.hh b/src/spatial-solving/preconditioners/supportpatchfactory.hh index 153480970d3ad79f6336703c6ea365205d3d05a4..761e1eae193e8d14a2c01fb3eac9f25d2f8179bb 100644 --- a/src/spatial-solving/preconditioners/supportpatchfactory.hh +++ b/src/spatial-solving/preconditioners/supportpatchfactory.hh @@ -538,7 +538,7 @@ class SupportPatchFactory std::set<size_t> isDofs; intersectionDofs(fineIndices_, is, bodyID, isDofs); - addToPatchBoundary(isDofs, patchBoundary, patchDofs); + addToPatch(isDofs, patchBoundary, patchDofs); } } } diff --git a/src/spatial-solving/solverfactory.cc b/src/spatial-solving/solverfactory.cc index 77c31c1ce766266a8d833fbc8976037df6c90403..6b9a3119d186cdddee89dcb83f469a9a5b06fd55 100644 --- a/src/spatial-solving/solverfactory.cc +++ b/src/spatial-solving/solverfactory.cc @@ -20,6 +20,9 @@ SolverFactory<Functional, BitVector>::SolverFactory( nonlinearSmoother_ = std::make_shared<NonlinearSmoother>(*J_, dummyIterate_, LocalSolver()); auto linearSolver_ptr = Dune::Solvers::wrap_own_share<std::decay_t<LinearSolver>>(std::forward<LinearSolver>(linearSolver)); + + //tnnmgStep_ = std::make_shared<Step>(*J_, dummyIterate_, nonlinearSmoother_, linearSolver_ptr, 10, DefectProjection(), LineSearchSolver()); + tnnmgStep_ = std::make_shared<Step>(*J_, dummyIterate_, nonlinearSmoother_, linearSolver_ptr, DefectProjection(), LineSearchSolver()); tnnmgStep_->setPreSmoothingSteps(parset.get<int>("main.pre")); tnnmgStep_->setIgnore(ignoreNodes); diff --git a/src/spatial-solving/tnnmg/functional.hh b/src/spatial-solving/tnnmg/functional.hh index 761359448bfcc5fd192fd4b6c1ff57f2545c52af..4bad3e3feb7f37f5ea4d9073f7ce6b3269e070c0 100644 --- a/src/spatial-solving/tnnmg/functional.hh +++ b/src/spatial-solving/tnnmg/functional.hh @@ -97,8 +97,9 @@ class DirectionalRestriction : { phi_.directionalDomain(origin_, direction_, domain_); - std::cout << domain_[0] << " " << domain_[1] << "Phi domain:" << std::endl; - std::cout << this->defectLower_ << " " << this->defectUpper_ << "defect obstacles:" << std::endl; + //std::cout << domain_[0] << " " << domain_[1] << "Phi domain:" << std::endl; + //std::cout << this->defectLower_ << " " << this->defectUpper_ << "defect obstacles:" << std::endl; + if (domain_[0] < this->defectLower_) { domain_[0] = this->defectLower_; } @@ -401,7 +402,7 @@ class Functional : public Dune::TNNMG::BoxConstrainedQuadraticFunctional<M, V, L Range operator()(const Vector& v) const { if (Dune::TNNMG::checkInsideBox(v, this->lower_.get(), this->upper_.get())) - return Base::Base::operator()(v) + phi_.get().operator()(v); + return Dune::TNNMG::QuadraticFunctional<M,V,R>::operator()(v) + phi_.get().operator()(v); return std::numeric_limits<Range>::max(); } diff --git a/src/spatial-solving/tnnmg/linearcorrection.hh b/src/spatial-solving/tnnmg/linearcorrection.hh index 2f99d1adfc6fb1a6d80613add41d39659facfd09..2b1d575232a2646a0f98d49583f7f4e16d8d97f2 100644 --- a/src/spatial-solving/tnnmg/linearcorrection.hh +++ b/src/spatial-solving/tnnmg/linearcorrection.hh @@ -9,6 +9,10 @@ #include <dune/solvers/solvers/linearsolver.hh> #include <dune/solvers/common/canignore.hh> +#include <dune/solvers/common/resize.hh> +#include <dune/solvers/solvers/umfpacksolver.hh> +#include "localproblem.hh" + /** * \brief linear correction step for use by \ref TNNMGStep * @@ -44,7 +48,25 @@ LinearCorrection<Matrix, Vector> makeLinearCorrection(std::shared_ptr< Dune::Solvers::IterativeSolver<Vector> > iterativeSolver) { return [=](const Matrix& A, Vector& x, const Vector& b, const Dune::Solvers::DefaultBitVector_t<Vector>& ignore) { - using LinearIterationStep = Dune::Solvers::LinearIterationStep<Matrix, Vector>; + + // compute reference solution directly + LocalProblem<Matrix, Vector> localProblem(A, b, ignore); + Vector newR, directX; + Dune::Solvers::resizeInitializeZero(directX, b); + localProblem.getLocalRhs(directX, newR); + + /*print(*this->ignoreNodes_, "ignoreNodes:"); + print(A, "A:"); + print(localProblem.getMat(), "localMat:");*/ + + auto directSolver = std::make_shared<Dune::Solvers::UMFPackSolver<Matrix, Vector>>(); + + directSolver->setProblem(localProblem.getMat(), directX, newR); + directSolver->preprocess(); + directSolver->solve(); + + x = directX; + /* using LinearIterationStep = Dune::Solvers::LinearIterationStep<Matrix, Vector>; auto linearIterationStep = dynamic_cast<LinearIterationStep*>(&iterativeSolver->getIterationStep()); if (not linearIterationStep) @@ -53,7 +75,13 @@ makeLinearCorrection(std::shared_ptr< Dune::Solvers::IterativeSolver<Vector> > i linearIterationStep->setIgnore(ignore); linearIterationStep->setProblem(A, x, b); iterativeSolver->preprocess(); - iterativeSolver->solve(); + iterativeSolver->solve();*/ + + /* + const auto& norm = iterativeSolver->getErrorNorm(); + auto error = norm.diff(linearIterationStep->getSol(), directX); + + std::cout << "CG Solver iterations: " << iterativeSolver->getResult().iterations << " Error: " << error << std::endl;*/ }; } diff --git a/src/spatial-solving/tnnmg/linearization.hh b/src/spatial-solving/tnnmg/linearization.hh index 8dcecd1513f664bcb0ce8e7a68d7267eb92fc614..bc6095a8cb03395cfa236332a269f419962ea203 100644 --- a/src/spatial-solving/tnnmg/linearization.hh +++ b/src/spatial-solving/tnnmg/linearization.hh @@ -145,10 +145,8 @@ class Linearization { negativeGradient_ *= -1; // truncate gradient and hessian - // truncateVector(negativeGradient_, truncationFlags_); - // truncateMatrix(hessian_, truncationFlags_, truncationFlags_); - - // the actual truncation is done by the solver of linearized problem + truncateVector(negativeGradient_, truncationFlags_); + truncateMatrix(hessian_, truncationFlags_, truncationFlags_); } diff --git a/src/spatial-solving/tnnmg/tnnmgstep.hh b/src/spatial-solving/tnnmg/tnnmgstep.hh index dc2ca30d6d8da342a664bc76ec141f0675ac6bb9..84d7e9147aca29bee78359c1558b34a245ade778 100644 --- a/src/spatial-solving/tnnmg/tnnmgstep.hh +++ b/src/spatial-solving/tnnmg/tnnmgstep.hh @@ -125,6 +125,15 @@ class TNNMGStep : preSmoothingSteps_ = i; } + auto energy(const Vector& v) const { + Vector temp; + Dune::Solvers::resizeInitializeZero(temp, v); + f_->quadraticPart().umv(v, temp); + temp *= 0.5; + temp -= f_->linearPart(); + return temp*v; + } + /** * \brief Do one TNNMG step */ @@ -141,12 +150,14 @@ class TNNMGStep : //print(f.linearPart(), "f.linearPart():"); + //std::cout << "-- energy before smoothing: " << energy(x) << std::endl; + // Nonlinear presmoothing for (std::size_t i=0; i<preSmoothingSteps_; ++i) nonlinearSmoother_->iterate(); - std::cout << "- nonlinear presmoothing: success" << std::endl; - print(x, "TNNMG iterate after smoothing:"); + //std::cout << "- nonlinear presmoothing: success" << std::endl; + //print(x, "TNNMG iterate after smoothing:"); // Compute constraint/truncated linearization if (not linearization_) @@ -157,48 +168,46 @@ class TNNMGStep : auto&& A = linearization_->hessian(); auto&& r = linearization_->negativeGradient(); - //print(A, "TNNMG Linear problem matrix:"); - //print(r, "TNNMG Linear problem rhs:"); + /*print(A, "TNNMG Linear problem matrix:"); + print(r, "TNNMG Linear problem rhs:"); + print(ignore, "ignore:"); + print(linearization_->truncated(), "truncation:");*/ // Compute inexact solution of the linearized problem Solvers::resizeInitializeZero(correction_, x); Solvers::resizeInitializeZero(constrainedCorrection_, r); - // std::cout << "- computing linear correction..." << std::endl; + //std::cout << "-- energy after presmoothing: " << energy(x) << std::endl; - linearCorrection_(A, constrainedCorrection_, r, linearization_->truncated()); + //print(constrainedCorrection_compare, "direct solver solution:"); - LocalProblem<ConstrainedMatrix, ConstrainedVector> localProblem(A, r, linearization_->truncated()); - Vector newR, constrainedCorrection_compare; - Solvers::resizeInitializeZero(constrainedCorrection_compare, r); - localProblem.getLocalRhs(constrainedCorrection_compare, newR); + //std::cout << "- computing linear correction..." << std::endl; - /*print(*this->ignoreNodes_, "ignoreNodes:"); - print(A, "A:"); - print(localProblem.getMat(), "localMat:");*/ - auto directSolver = std::make_shared<Dune::Solvers::UMFPackSolver<ConstrainedMatrix, ConstrainedVector>>(); + linearCorrection_(A, constrainedCorrection_, r, ignore); - directSolver->setProblem(localProblem.getMat(), constrainedCorrection_compare, newR); - directSolver->preprocess(); - directSolver->solve(); + //DUNE_THROW(Dune::Exception, "TNNMGStep: Just need to terminate here!"); // linearCorrection_(A, constrainedCorrection_, r); - std::cout << "- linear correction: success" << std::endl; + //std::cout << "- linear correction: success" << std::endl; //print(constrainedCorrection_, "contrained correction:"); linearization_->extendCorrection(constrainedCorrection_, correction_); - std::cout << "- extended correction: success" << std::endl; - print(correction_, "correction:"); + /*Vector h = x; + h += correction_; + std::cout << "-- energy after linear correction: " << energy(h) << std::endl;*/ + + //std::cout << "- extended correction: success" << std::endl; + //print(correction_, "correction:"); // Project onto admissible set projection_(f, x, correction_); - std::cout << "- projection onto admissible set: success" << std::endl; + //std::cout << "- projection onto admissible set: success" << std::endl; - print(correction_, "correction:"); + //print(correction_, "correction:"); double const correctionNorm = correction_.two_norm(); correction_ /= correctionNorm; @@ -221,7 +230,11 @@ class TNNMGStep : dampingFactor_ = 0; correction_ *= dampingFactor_; + //std::cout << "damping factor: " << dampingFactor_ << std::endl; + x += correction_; + + //std::cout << "-- energy after correction: " << energy(x) << std::endl; } /** diff --git a/src/time-stepping/adaptivetimestepper.cc b/src/time-stepping/adaptivetimestepper.cc index fae06ed6b14302b5f4edbf2e41cca0dda6e4e337..c1869aa83726cbddc3f22a4fa27e52e61d873154 100644 --- a/src/time-stepping/adaptivetimestepper.cc +++ b/src/time-stepping/adaptivetimestepper.cc @@ -17,10 +17,10 @@ void IterationRegister::reset() { finalCount = FixedPointIterationCounter(); } -template <class Factory, class NBodyAssembler, class Updaters, class ErrorNorms> -AdaptiveTimeStepper<Factory, NBodyAssembler, Updaters, ErrorNorms>::AdaptiveTimeStepper( +template <class Factory, class ContactNetwork, class Updaters, class ErrorNorms> +AdaptiveTimeStepper<Factory, ContactNetwork, Updaters, ErrorNorms>::AdaptiveTimeStepper( Dune::ParameterTree const &parset, - NBodyAssembler& nBodyAssembler, + const ContactNetwork& contactNetwork, const IgnoreVector& ignoreNodes, GlobalFriction& globalFriction, const std::vector<const BitVector*>& bodywiseNonmortarBoundaries, @@ -34,7 +34,7 @@ AdaptiveTimeStepper<Factory, NBodyAssembler, Updaters, ErrorNorms>::AdaptiveTime relativeTau_(relativeTau), finalTime_(parset.get<double>("problem.finalTime")), parset_(parset), - nBodyAssembler_(nBodyAssembler), + contactNetwork_(contactNetwork), ignoreNodes_(ignoreNodes), globalFriction_(globalFriction), bodywiseNonmortarBoundaries_(bodywiseNonmortarBoundaries), @@ -44,14 +44,13 @@ AdaptiveTimeStepper<Factory, NBodyAssembler, Updaters, ErrorNorms>::AdaptiveTime mustRefine_(mustRefine), errorNorms_(errorNorms) {} -template <class Factory, class NBodyAssembler, class Updaters, class ErrorNorms> -bool AdaptiveTimeStepper<Factory, NBodyAssembler, Updaters, ErrorNorms>::reachedEnd() { +template <class Factory, class ContactNetwork, class Updaters, class ErrorNorms> +bool AdaptiveTimeStepper<Factory, ContactNetwork, Updaters, ErrorNorms>::reachedEnd() { return relativeTime_ >= 1.0; } -template <class Factory, class NBodyAssembler, class Updaters, class ErrorNorms> -template <class Preconditioner> -IterationRegister AdaptiveTimeStepper<Factory, NBodyAssembler, Updaters, ErrorNorms>::advance(Preconditioner&& preconditioner) { +template <class Factory, class ContactNetwork, class Updaters, class ErrorNorms> +IterationRegister AdaptiveTimeStepper<Factory, ContactNetwork, Updaters, ErrorNorms>::advance() { /* | C | We check here if making the step R1 of size tau is a | R1 | R2 | good idea. To check if we can coarsen, we compare @@ -64,7 +63,7 @@ IterationRegister AdaptiveTimeStepper<Factory, NBodyAssembler, Updaters, ErrorNo std::cout << "AdaptiveTimeStepper::advance()" << std::endl; if (R1_.updaters == Updaters()) - R1_ = step(current_, relativeTime_, relativeTau_, std::forward<Preconditioner>(preconditioner)); + R1_ = step(current_, relativeTime_, relativeTau_); std::cout << "AdaptiveTimeStepper Step 1" << std::endl; @@ -74,9 +73,9 @@ IterationRegister AdaptiveTimeStepper<Factory, NBodyAssembler, Updaters, ErrorNo UpdatersWithCount R2; UpdatersWithCount C; while (relativeTime_ + relativeTau_ <= 1.0) { - R2 = step(R1_.updaters, relativeTime_ + relativeTau_, relativeTau_, std::forward<Preconditioner>(preconditioner)); + R2 = step(R1_.updaters, relativeTime_ + relativeTau_, relativeTau_); std::cout << "AdaptiveTimeStepper R2 computed!" << std::endl << std::endl; - C = step(current_, relativeTime_, 2 * relativeTau_, std::forward<Preconditioner>(preconditioner)); + C = step(current_, relativeTime_, 2 * relativeTau_); std::cout << "AdaptiveTimeStepper C computed!" << std::endl << std::endl; if (mustRefine_(R2.updaters, C.updaters)) break; @@ -91,10 +90,10 @@ IterationRegister AdaptiveTimeStepper<Factory, NBodyAssembler, Updaters, ErrorNo UpdatersWithCount F2; if (!didCoarsen) { while (true) { - F1 = step(current_, relativeTime_, relativeTau_ / 2.0, std::forward<Preconditioner>(preconditioner)); + F1 = step(current_, relativeTime_, relativeTau_ / 2.0); std::cout << "AdaptiveTimeStepper F1 computed!" << std::endl << std::endl; F2 = step(F1.updaters, relativeTime_ + relativeTau_ / 2.0, - relativeTau_ / 2.0, std::forward<Preconditioner>(preconditioner)); + relativeTau_ / 2.0); std::cout << "AdaptiveTimeStepper F2 computed!" << std::endl << std::endl; if (!mustRefine_(F2.updaters, R1_.updaters)) { std::cout << "Sufficiently refined!" << std::endl; @@ -122,17 +121,16 @@ IterationRegister AdaptiveTimeStepper<Factory, NBodyAssembler, Updaters, ErrorNo return iterationRegister_; } -template <class Factory, class NBodyAssembler, class Updaters, class ErrorNorms> -template <class Preconditioner> -typename AdaptiveTimeStepper<Factory, NBodyAssembler, Updaters, ErrorNorms>::UpdatersWithCount -AdaptiveTimeStepper<Factory, NBodyAssembler, Updaters, ErrorNorms>::step( - Updaters const &oldUpdaters, double rTime, double rTau, Preconditioner&& preconditioner) { +template <class Factory, class ContactNetwork, class Updaters, class ErrorNorms> +typename AdaptiveTimeStepper<Factory, ContactNetwork, Updaters, ErrorNorms>::UpdatersWithCount +AdaptiveTimeStepper<Factory, ContactNetwork, Updaters, ErrorNorms>::step( + Updaters const &oldUpdaters, double rTime, double rTau) { UpdatersWithCount newUpdatersAndCount = {oldUpdaters.clone(), {}}; newUpdatersAndCount.count = - MyCoupledTimeStepper(finalTime_, parset_, nBodyAssembler_, ignoreNodes_, globalFriction_, bodywiseNonmortarBoundaries_, + MyCoupledTimeStepper(finalTime_, parset_, contactNetwork_, ignoreNodes_, globalFriction_, bodywiseNonmortarBoundaries_, newUpdatersAndCount.updaters, errorNorms_, externalForces_) - .step(rTime, rTau, std::forward<Preconditioner>(preconditioner)); + .step(rTime, rTau); iterationRegister_.registerCount(newUpdatersAndCount.count); return newUpdatersAndCount; } diff --git a/src/time-stepping/adaptivetimestepper.hh b/src/time-stepping/adaptivetimestepper.hh index 3e48b2218a06a954903e9c2d4d63d0fe0642c18c..ce090c012658d23ff9b34dd9f182ffe2421df013 100644 --- a/src/time-stepping/adaptivetimestepper.hh +++ b/src/time-stepping/adaptivetimestepper.hh @@ -15,7 +15,7 @@ struct IterationRegister { FixedPointIterationCounter finalCount; }; -template <class Factory, class NBodyAssembler, class Updaters, class ErrorNorms> +template <class Factory, class ContactNetwork, class Updaters, class ErrorNorms> class AdaptiveTimeStepper { struct UpdatersWithCount { Updaters updaters; @@ -27,7 +27,7 @@ class AdaptiveTimeStepper { //using ConvexProblem = typename Factory::ConvexProblem; //using Nonlinearity = typename Factory::Nonlinearity; - using MyCoupledTimeStepper = CoupledTimeStepper<Factory, NBodyAssembler, Updaters, ErrorNorms>; + using MyCoupledTimeStepper = CoupledTimeStepper<Factory, ContactNetwork, Updaters, ErrorNorms>; using GlobalFriction = typename MyCoupledTimeStepper::GlobalFriction; using BitVector = typename MyCoupledTimeStepper::BitVector; @@ -36,7 +36,7 @@ class AdaptiveTimeStepper { public: AdaptiveTimeStepper( Dune::ParameterTree const &parset, - NBodyAssembler& nBodyAssembler, + const ContactNetwork& contactNetwork, const IgnoreVector& ignoreNodes, GlobalFriction& globalFriction, const std::vector<const BitVector*>& bodywiseNonmortarBoundaries, @@ -49,20 +49,18 @@ class AdaptiveTimeStepper { bool reachedEnd(); - template <class Preconditioner> - IterationRegister advance(Preconditioner&& preconditioner); + IterationRegister advance(); double relativeTime_; double relativeTau_; private: - template <class Preconditioner> UpdatersWithCount step(Updaters const &oldUpdaters, double rTime, - double rTau, Preconditioner&& preconditioner); + double rTau); double finalTime_; Dune::ParameterTree const &parset_; - NBodyAssembler& nBodyAssembler_; + const ContactNetwork& contactNetwork_; const IgnoreVector& ignoreNodes_; GlobalFriction& globalFriction_; diff --git a/src/time-stepping/adaptivetimestepper_tmpl.cc b/src/time-stepping/adaptivetimestepper_tmpl.cc index bda3c4c774b1db0d13f12e4004465a6df0fa00f7..ff76be34499f936cd42839472ecc7207d81ebea5 100644 --- a/src/time-stepping/adaptivetimestepper_tmpl.cc +++ b/src/time-stepping/adaptivetimestepper_tmpl.cc @@ -14,7 +14,6 @@ #include "state/stateupdater.hh" #include "updaters.hh" -using NBodyAssembler = typename MyContactNetwork::NBodyAssembler; using BoundaryNodes = typename MyContactNetwork::BoundaryNodes; using BoundaryFunctions = typename MyContactNetwork::BoundaryFunctions; @@ -24,6 +23,6 @@ using MyUpdaters = Updaters<MyRateUpdater, MyStateUpdater>; using ErrorNorms = typename MyContactNetwork::StateEnergyNorms; -using MyAdaptiveTimeStepper = AdaptiveTimeStepper<MySolverFactory, NBodyAssembler, MyUpdaters, ErrorNorms>; +using MyAdaptiveTimeStepper = AdaptiveTimeStepper<MySolverFactory, MyContactNetwork, MyUpdaters, ErrorNorms>; -template class AdaptiveTimeStepper<MySolverFactory, NBodyAssembler, MyUpdaters, ErrorNorms>; +template class AdaptiveTimeStepper<MySolverFactory, MyContactNetwork, MyUpdaters, ErrorNorms>; diff --git a/src/time-stepping/coupledtimestepper.cc b/src/time-stepping/coupledtimestepper.cc index 6b9daac7bef9458d91fff57ca8da2e68c775b9bb..1df547741bee8de1cfb4e2b339f77b72badc8308 100644 --- a/src/time-stepping/coupledtimestepper.cc +++ b/src/time-stepping/coupledtimestepper.cc @@ -4,10 +4,10 @@ #include "coupledtimestepper.hh" -template <class Factory, class NBodyAssembler, class Updaters, class ErrorNorms> -CoupledTimeStepper<Factory, NBodyAssembler, Updaters, ErrorNorms>::CoupledTimeStepper( +template <class Factory, class ContactNetwork, class Updaters, class ErrorNorms> +CoupledTimeStepper<Factory, ContactNetwork, Updaters, ErrorNorms>::CoupledTimeStepper( double finalTime, Dune::ParameterTree const &parset, - NBodyAssembler& nBodyAssembler, + const ContactNetwork& contactNetwork, const IgnoreVector& ignoreNodes, GlobalFriction& globalFriction, const std::vector<const BitVector*>& bodywiseNonmortarBoundaries, @@ -16,7 +16,7 @@ CoupledTimeStepper<Factory, NBodyAssembler, Updaters, ErrorNorms>::CoupledTimeSt ExternalForces& externalForces) : finalTime_(finalTime), parset_(parset), - nBodyAssembler_(nBodyAssembler), + contactNetwork_(contactNetwork), ignoreNodes_(ignoreNodes), globalFriction_(globalFriction), bodywiseNonmortarBoundaries_(bodywiseNonmortarBoundaries), @@ -24,11 +24,10 @@ CoupledTimeStepper<Factory, NBodyAssembler, Updaters, ErrorNorms>::CoupledTimeSt externalForces_(externalForces), errorNorms_(errorNorms) {} -template <class Factory, class NBodyAssembler, class Updaters, class ErrorNorms> -template <class Preconditioner> +template <class Factory, class ContactNetwork, class Updaters, class ErrorNorms> FixedPointIterationCounter -CoupledTimeStepper<Factory, NBodyAssembler, Updaters, ErrorNorms>::step(double relativeTime, - double relativeTau, Preconditioner&& preconditioner) { +CoupledTimeStepper<Factory, ContactNetwork, Updaters, ErrorNorms>::step(double relativeTime, + double relativeTau) { std::cout << "CoupledTimeStepper::step()" << std::endl; @@ -50,8 +49,8 @@ CoupledTimeStepper<Factory, NBodyAssembler, Updaters, ErrorNorms>::step(double r updaters_.rate_->setup(ell, tau, newRelativeTime, velocityRHS, velocityIterate, velocityMatrix); FixedPointIterator fixedPointIterator( - parset_, nBodyAssembler_, ignoreNodes_, globalFriction_, bodywiseNonmortarBoundaries_, errorNorms_); - auto const iterations = fixedPointIterator.run(updaters_, std::forward<Preconditioner>(preconditioner), + parset_, contactNetwork_, ignoreNodes_, globalFriction_, bodywiseNonmortarBoundaries_, errorNorms_); + auto const iterations = fixedPointIterator.run(updaters_, velocityMatrix, velocityRHS, velocityIterate); return iterations; } diff --git a/src/time-stepping/coupledtimestepper.hh b/src/time-stepping/coupledtimestepper.hh index 0b2ac4689e334de1d14ff78edde65d3186c23e05..fc619036f26c54137f0d7a2c48d53f4fb593d6d4 100644 --- a/src/time-stepping/coupledtimestepper.hh +++ b/src/time-stepping/coupledtimestepper.hh @@ -8,12 +8,12 @@ #include "../spatial-solving/fixedpointiterator.hh" -template <class Factory, class NBodyAssembler, class Updaters, class ErrorNorms> +template <class Factory, class ContactNetwork, class Updaters, class ErrorNorms> class CoupledTimeStepper { using Vector = typename Factory::Vector; using Matrix = typename Factory::Matrix; using IgnoreVector = typename Factory::BitVector; - using FixedPointIterator = FixedPointIterator<Factory, NBodyAssembler, Updaters, ErrorNorms>; + using FixedPointIterator = FixedPointIterator<Factory, ContactNetwork, Updaters, ErrorNorms>; public: using GlobalFriction = typename FixedPointIterator::GlobalFriction; @@ -23,7 +23,7 @@ class CoupledTimeStepper { public: CoupledTimeStepper(double finalTime, Dune::ParameterTree const &parset, - NBodyAssembler& nBodyAssembler, + const ContactNetwork& contactNetwork, const IgnoreVector& ignoreNodes, GlobalFriction& globalFriction, const std::vector<const BitVector*>& bodywiseNonmortarBoundaries, @@ -31,13 +31,12 @@ class CoupledTimeStepper { const ErrorNorms& errorNorms, ExternalForces& externalForces); - template <class Preconditioner> - FixedPointIterationCounter step(double relativeTime, double relativeTau, Preconditioner&& preconditioner); + FixedPointIterationCounter step(double relativeTime, double relativeTau); private: double finalTime_; Dune::ParameterTree const &parset_; - NBodyAssembler& nBodyAssembler_; + const ContactNetwork& contactNetwork_; const IgnoreVector& ignoreNodes_; GlobalFriction& globalFriction_; diff --git a/src/time-stepping/coupledtimestepper_tmpl.cc b/src/time-stepping/coupledtimestepper_tmpl.cc index 4d9f7f8eb062de3f2731ad3c7205631fa9799ef7..3df79591219c4b017965e642c088cc922b676025 100644 --- a/src/time-stepping/coupledtimestepper_tmpl.cc +++ b/src/time-stepping/coupledtimestepper_tmpl.cc @@ -14,7 +14,6 @@ #include "state/stateupdater.hh" #include "updaters.hh" -using NBodyAssembler = typename MyContactNetwork::NBodyAssembler; using BoundaryNodes = typename MyContactNetwork::BoundaryNodes; using BoundaryFunctions = typename MyContactNetwork::BoundaryFunctions; @@ -25,4 +24,4 @@ using MyUpdaters = Updaters<MyRateUpdater, MyStateUpdater>; using ErrorNorms = typename MyContactNetwork::StateEnergyNorms; -template class CoupledTimeStepper<MySolverFactory, NBodyAssembler, MyUpdaters, ErrorNorms>; +template class CoupledTimeStepper<MySolverFactory, MyContactNetwork, MyUpdaters, ErrorNorms>; diff --git a/src/time-stepping/rate/newmark.cc b/src/time-stepping/rate/newmark.cc index a3b3638529c8a75a09f633a5ea6a26b9ef6eb867..dec66b98d732c2589b7bc79c4c371a47de336714 100644 --- a/src/time-stepping/rate/newmark.cc +++ b/src/time-stepping/rate/newmark.cc @@ -95,20 +95,20 @@ void Newmark<Vector, Matrix, BoundaryFunctions, BoundaryNodes>::setup( double dirichletValue; bodyDirichletFunctions[bc]->evaluate(relativeTime, dirichletValue); - std::cout << "dirichletValue: " << dirichletValue << std::endl; + //std::cout << "dirichletValue: " << dirichletValue << std::endl; for (size_t k=0; k<bcDirichletNodes.size() ; ++k) { for (size_t j=0; j<dim; ++j) { if (bcDirichletNodes[k][j]) { - std::cout << k << " " << j << std::endl; + //std::cout << k << " " << j << std::endl; bodyIterate[k][j] = dirichletValue; } } } } } - print(iterate, "iterate:"); + //print(iterate, "iterate:"); } template <class Vector, class Matrix, class BoundaryFunctions, class BoundaryNodes>