diff --git a/src/spatial-solving/solverfactory.cc b/src/spatial-solving/solverfactory.cc index b289e96e01d807dfdd8b918a5f303e3dc17a8bd7..e0fa8ec1968ab6ed398baaa9d521e18e54a93188 100644 --- a/src/spatial-solving/solverfactory.cc +++ b/src/spatial-solving/solverfactory.cc @@ -6,54 +6,73 @@ #undef HAVE_IPOPT #endif +#include <dune/common/bitsetvector.hh> + #include <dune/fufem/assemblers/transferoperatorassembler.hh> #include <dune/solvers/solvers/solver.hh> #include "solverfactory.hh" -template <size_t dim, class BlockProblem, class DeformedGrid> -SolverFactory<dim, BlockProblem, DeformedGrid>::SolverFactory( +template <class DeformedGridTEMPLATE, class MatrixType, class VectorType> +SolverFactory<DeformedGrid, Matrix, Vector>::SolverFactory( Dune::ParameterTree const &parset, const Dune::Contact::NBodyAssembler<DeformedGrid, Vector>& nBodyAssembler, Dune::BitSetVector<dim> const &ignoreNodes) : nBodyAssembler_(nBodyAssembler), - baseEnergyNorm(linearBaseSolverStep), - linearBaseSolver(&linearBaseSolverStep, + baseEnergyNorm_(baseSolverStep_), + baseSolver_(&baseSolverStep_, parset.get<size_t>("linear.maxiumumIterations"), - parset.get<double>("linear.tolerance"), &baseEnergyNorm, - Solver::QUIET)/*, - transferOperators(grid.maxLevel()), - multigridStep(std::make_shared<Step>(linearIterationStep, nonlinearSmoother))*/ { - - // linear iteration step - linearIterationStep.setMGType(parset.get<int>("linear.cycle"), - parset.get<int>("linear.pre"), - parset.get<int>("linear.post")); - //linearIterationStep.basesolver_ = &linearBaseSolver; - linearIterationStep.setSmoother(&linearPresmoother, &linearPostsmoother); - - // transfer operators - for (auto &&x : transferOperators) - x = new CompressedMultigridTransfer<Vector>; - TransferOperatorAssembler<DeformedGrid>(grid).assembleOperatorPointerHierarchy(transferOperators); - linearIterationStep.setTransferOperators(transferOperators); + parset.get<double>("linear.tolerance"), &baseEnergyNorm_, + Solver::QUIET), + transferOperators_(nBodyAssembler.getGrids().at(0)->maxLevel()) { // tnnmg iteration step - /*multigridStep->setSmoothingSteps(parset.get<int>("main.pre"), - parset.get<int>("main.multi"), - parset.get<int>("main.post")); */ - multigridStep->ignoreNodes_ = &ignoreNodes; + multigridStep_->setMGType(parset.get<int>("main.multi"), parset.get<int>("main.pre"), parset.get<int>("main.post")); + multigridStep_->setIgnore(ignoreNodes); + multigridStep_->setBaseSolver(baseSolver_); + multigridStep_->setSmoother(&presmoother_, &postsmoother_); + multigridStep_->setHasObstacle(nBodyAssembler_.totalHasObstacle_); + multigridStep_->setObstacles(nBodyAssembler_.totalObstacles_); + + // create the transfer operators + const int nCouplings = nBodyAssembler_.nCouplings(); + const auto grids = nBodyAssembler_.getGrids(); + for (size_t i=0; i<transferOperators_.size(); i++) { + std::vector<const Dune::BitSetVector<1>*> coarseHasObstacle(nCouplings); + std::vector<const Dune::BitSetVector<1>*> fineHasObstacle(nCouplings); + + std::vector<const Matrix*> mortarTransfer(nCouplings); + std::vector<std::array<int,2> > gridIdx(nCouplings); + + for (int j=0; j<nCouplings; j++) { + coarseHasObstacle[j] = nBodyAssembler_.nonmortarBoundary_[j][i].getVertices(); + fineHasObstacle[j] = nBodyAssembler_.nonmortarBoundary_[j][i+1].getVertices(); + + mortarTransfer[j] = &nBodyAssembler_.contactCoupling_[j].mortarLagrangeMatrix(i); + gridIdx[j] = nBodyAssembler_.coupling_[j].gridIdx_; + } + + transferOperators_[i] = new Dune::Contact::ContactMGTransfer<Vector>; + transferOperators_[i]->setup(grids, i, i+1, + nBodyAssembler_.localCoordSystems_[i], + nBodyAssembler_.localCoordSystems_[i+1], + coarseHasObstacle, fineHasObstacle, + mortarTransfer, + gridIdx); + } + + multigridStep_->setTransferOperators(transferOperators_); } -template <size_t dim, class BlockProblem, class DeformedGrid> -SolverFactory<dim, BlockProblem, DeformedGrid>::~SolverFactory() { - for (auto &&x : transferOperators) +template <class DeformedGridTEMPLATE, class MatrixType, class VectorType> +SolverFactory<DeformedGrid, Matrix, Vector>::~SolverFactory() { + for (auto &&x : transferOperators_) delete x; } -template <size_t dim, class BlockProblem, class DeformedGrid> -auto SolverFactory<dim, BlockProblem, DeformedGrid>::getStep() +template <class DeformedGridTEMPLATE, class MatrixType, class VectorType> +auto SolverFactory<DeformedGrid, Matrix, Vector>::getStep() -> std::shared_ptr<Step> { - return multigridStep; + return multigridStep_; } #include "solverfactory_tmpl.cc" diff --git a/src/spatial-solving/solverfactory.hh b/src/spatial-solving/solverfactory.hh index 464ae5392a2b07eac6339bb91aca27a3c9f84935..ad6dbde284eda07e0d85364dfaf30beca03c257e 100644 --- a/src/spatial-solving/solverfactory.hh +++ b/src/spatial-solving/solverfactory.hh @@ -5,33 +5,37 @@ #include <dune/common/parametertree.hh> #include <dune/solvers/iterationsteps/multigridstep.hh> -#include <dune/solvers/iterationsteps/truncatedblockgsstep.hh> +#include <dune/solvers/iterationsteps/projectedblockgsstep.hh> #include <dune/solvers/norms/energynorm.hh> #include <dune/solvers/solvers/loopsolver.hh> -#include <dune/solvers/transferoperators/compressedmultigridtransfer.hh> -#include <dune/tnnmg/iterationsteps/genericnonlineargs.hh> +//#include <dune/solvers/transferoperators/compressedmultigridtransfer.hh> +//#include <dune/tnnmg/iterationsteps/genericnonlineargs.hh> //#include <dune/tnnmg/iterationsteps/tnnmgstep.hh> #include <dune/contact/assemblers/nbodyassembler.hh> +#include <dune/contact/estimators/hierarchiccontactestimator.hh> +#include <dune/contact/solvers/nsnewtonmgstep.hh> +#include <dune/contact/solvers/contacttransfer.hh> +#include <dune/contact/solvers/contactobsrestrict.hh> +#include <dune/contact/solvers/contacttransferoperatorassembler.hh> +#include <dune/contact/solvers/nsnewtoncontacttransfer.hh> + #define USE_OLD_TNNMG //needed for old bisection.hh in tnnmg -template <size_t dim, class BlockProblemTEMPLATE, class DeformedGridTEMPLATE> +template <class DeformedGridTEMPLATE, class MatrixType, class VectorType> class SolverFactory { +protected: + const size_t dim = DeformedGrid::dimension; + public: - using BlockProblem = BlockProblemTEMPLATE; - using ConvexProblem = typename BlockProblem::ConvexProblemType; - using Vector = typename BlockProblem::VectorType; - using Matrix = typename BlockProblem::MatrixType; + using Vector = VectorType; + using Matrix = MatrixType; using DeformedGrid = DeformedGridTEMPLATE; -private: - using NonlinearSmoother = GenericNonlinearGS<BlockProblem>; - public: - using Step = NonlinearSmoother; - //TruncatedNonsmoothNewtonMultigrid<BlockProblem, NonlinearSmoother>; + using Step = Dune::Contact::NonSmoothNewtonMGStep<Matrix, Vector>; SolverFactory(Dune::ParameterTree const &parset, const Dune::Contact::NBodyAssembler<DeformedGrid, Vector>& nBodyAssembler, Dune::BitSetVector<dim> const &ignoreNodes); @@ -43,14 +47,14 @@ class SolverFactory { private: const Dune::Contact::NBodyAssembler<DeformedGrid, Vector>& nBodyAssembler_; - TruncatedBlockGSStep<Matrix, Vector> linearBaseSolverStep; - EnergyNorm<Matrix, Vector> baseEnergyNorm; - LoopSolver<Vector> linearBaseSolver; - TruncatedBlockGSStep<Matrix, Vector> linearPresmoother; - TruncatedBlockGSStep<Matrix, Vector> linearPostsmoother; - MultigridStep<Matrix, Vector> linearIterationStep; - std::vector<CompressedMultigridTransfer<Vector> *> transferOperators; - NonlinearSmoother nonlinearSmoother; - std::shared_ptr<Step> multigridStep; + ProjectedBlockGSStep<Matrix, Vector> baseSolverStep_; + EnergyNorm<Matrix, Vector> baseEnergyNorm_; + LoopSolver<Vector> baseSolver_; + + ProjectedBlockGSStep<Matrix, Vector> presmoother_; + ProjectedBlockGSStep<Matrix, Vector> postsmoother_; + std::shared_ptr<Step> multigridStep_; + + std::vector<Dune::Contact::ContactMGTransfer<Vector>* > transferOperators_; }; #endif