diff --git a/src/data-structures/program_state.hh b/src/data-structures/program_state.hh index 1e8f679d15ac84017312e38b4f7a4df33d800834..22a2ddfe452e08650f608f86f744e04d51ab3ed6 100644 --- a/src/data-structures/program_state.hh +++ b/src/data-structures/program_state.hh @@ -10,11 +10,17 @@ #include <dune/contact/assemblers/nbodyassembler.hh> +#include <dune/solvers/norms/energynorm.hh> +#include <dune/solvers/solvers/loopsolver.hh> +#include <dune/solvers/iterationsteps/cgstep.hh> +#include <dune/solvers/iterationsteps/blockgssteps.hh> + #include <dune/tectonic/bodydata.hh> #include "../assemblers.hh" #include "contactnetwork.hh" #include "matrices.hh" +#include "../spatial-solving/preconditioners/multilevelpatchpreconditioner.hh" #include "../spatial-solving/solverfactory.hh" #include "../spatial-solving/tnnmg/functional.hh" #include "../spatial-solving/tnnmg/zerononlinearity.hh" @@ -51,6 +57,7 @@ template <class VectorTEMPLATE, class ScalarVectorTEMPLATE> class ProgramState { using LocalVector = typename Vector::block_type; //using LocalMatrix = typename Matrix::block_type; const static int dims = LocalVector::dimension; + using BitVector = Dune::BitSetVector<dims>; public: ProgramState(const std::vector<size_t>& leafVertexCounts) @@ -85,14 +92,43 @@ template <class VectorTEMPLATE, class ScalarVectorTEMPLATE> class ProgramState { } // Set up initial conditions - template <class GridType> - void setupInitialConditions(const Dune::ParameterTree& parset, const ContactNetwork<GridType, Vector>& contactNetwork) { - using Matrix = typename ContactNetwork<GridType, Vector>::Matrix; + template <class ContactNetwork> + void setupInitialConditions(const Dune::ParameterTree& parset, const ContactNetwork& contactNetwork) { + using Matrix = typename ContactNetwork::Matrix; const auto& nBodyAssembler = contactNetwork.nBodyAssembler(); + // set patch preconditioner for linear correction in TNNMG method + using PatchSolver = typename Dune::Solvers::LoopSolver<Vector, BitVector>; + using Preconditioner = MultilevelPatchPreconditioner<ContactNetwork, PatchSolver, Matrix, Vector>; + + const auto& preconditionerParset = parset.sub("solver.tnnmg.linear.preconditioner"); + + auto gsStep = Dune::Solvers::BlockGSStepFactory<Matrix, Vector>::create(Dune::Solvers::BlockGS::LocalSolvers::direct(0.0)); + PatchSolver patchSolver(gsStep, + preconditionerParset.get<size_t>("maximumIterations"), + preconditionerParset.get<double>("tolerance"), + nullptr, + preconditionerParset.get<Solver::VerbosityMode>("verbosity"), + false); // absolute error + + Dune::BitSetVector<1> activeLevels(contactNetwork.nLevels(), true); + Preconditioner preconditioner(contactNetwork, activeLevels, preconditionerParset.get<MPPMode>("mode")); + preconditioner.setPatchSolver(std::forward<PatchSolver>(patchSolver)); + preconditioner.setPatchDepth(preconditionerParset.get<size_t>("patchDepth")); + preconditioner.build(); + + using LinearSolver = typename Dune::Solvers::LoopSolver<Vector, BitVector>; + using LinearSolverStep = typename Dune::Solvers::CGStep<Matrix, Vector, BitVector>; + + LinearSolverStep linearSolverStep; + linearSolverStep.setPreconditioner(preconditioner); + + EnergyNorm<Matrix, Vector> energyNorm(linearSolverStep); + LinearSolver linearSolver(linearSolverStep, parset.get<size_t>("linear.maximumIterations"), parset.get<double>("linear.tolerance"), energyNorm, Solver::QUIET); + // Solving a linear problem with a multigrid solver auto const solveLinearProblem = [&]( - const Dune::BitSetVector<dims>& _dirichletNodes, const std::vector<std::shared_ptr<Matrix>>& _matrices, + const BitVector& _dirichletNodes, const std::vector<std::shared_ptr<Matrix>>& _matrices, const std::vector<Vector>& _rhs, std::vector<Vector>& _x, Dune::ParameterTree const &_localParset) { @@ -149,14 +185,15 @@ template <class VectorTEMPLATE, class ScalarVectorTEMPLATE> class ProgramState { print(lower, "lower"); print(upper, "upper");*/ - // set up functional and TNMMG solver + // set up functional using Functional = Functional<Matrix&, Vector&, ZeroNonlinearity&, Vector&, Vector&, typename Matrix::field_type>; Functional J(bilinearForm, totalRhs, ZeroNonlinearity(), lower, upper); //TODO - // using Factory = SolverFactory<Functional, Dune::BitSetVector<dims>>; - // Factory factory(parset.sub("solver.tnnmg"), J, _dirichletNodes); + // set up TNMMG solver + using Factory = SolverFactory<Functional, BitVector>; + Factory factory(parset.sub("solver.tnnmg"), J, linearSolver, _dirichletNodes); - /* std::vector<Dune::BitSetVector<dims>> bodyDirichletNodes; + /* std::vector<BitVector> bodyDirichletNodes; nBodyAssembler.postprocess(_dirichletNodes, bodyDirichletNodes); for (size_t i=0; i<bodyDirichletNodes.size(); i++) { print(bodyDirichletNodes[i], "bodyDirichletNodes_" + std::to_string(i) + ": "); @@ -166,7 +203,7 @@ template <class VectorTEMPLATE, class ScalarVectorTEMPLATE> class ProgramState { print(totalX, "totalX: "); print(totalRhs, "totalRhs: ");*/ - /* auto tnnmgStep = factory.step(); + auto tnnmgStep = factory.step(); factory.setProblem(totalX); const EnergyNorm<Matrix, Vector> norm(bilinearForm); @@ -184,7 +221,7 @@ template <class VectorTEMPLATE, class ScalarVectorTEMPLATE> class ProgramState { Vector res = totalRhs; bilinearForm.mmv(tnnmgStep->getSol(), res); - std::cout << "TNNMG Res - energy norm: " << norm.operator ()(res) << std::endl; */ + std::cout << "TNNMG Res - energy norm: " << norm.operator ()(res) << std::endl; // TODO: remove after debugging /* using DeformedGridType = typename LevelContactNetwork<GridType, dims>::DeformedGridType; @@ -233,7 +270,7 @@ template <class VectorTEMPLATE, class ScalarVectorTEMPLATE> class ProgramState { // Initial displacement: Start from a situation of minimal stress, // which is automatically attained in the case [v = 0 = a]. // Assuming dPhi(v = 0) = 0, we thus only have to solve Au = ell0 - Dune::BitSetVector<dims> dirichletNodes; + BitVector dirichletNodes; contactNetwork.totalNodes("dirichlet", dirichletNodes); /*for (size_t i=0; i<dirichletNodes.size(); i++) { bool val = false; @@ -262,7 +299,7 @@ template <class VectorTEMPLATE, class ScalarVectorTEMPLATE> class ProgramState { // Initial normal stress const auto& body = contactNetwork.body(i); - std::vector<std::shared_ptr<typename ContactNetwork<GridType, Vector>::LeafBody::BoundaryCondition>> frictionBoundaryConditions; + std::vector<std::shared_ptr<typename ContactNetwork::LeafBody::BoundaryCondition>> frictionBoundaryConditions; body->boundaryConditions("friction", frictionBoundaryConditions); for (size_t j=0; j<frictionBoundaryConditions.size(); j++) { ScalarVector frictionBoundaryStress(weightedNormalStress[i].size()); @@ -277,7 +314,7 @@ template <class VectorTEMPLATE, class ScalarVectorTEMPLATE> class ProgramState { Dune::MatrixVector::subtractProduct(accelerationRHS[i], *body->matrices().elasticity, u[i]); } - Dune::BitSetVector<dims> noNodes(dirichletNodes.size(), false); + BitVector noNodes(dirichletNodes.size(), false); solveLinearProblem(noNodes, contactNetwork.matrices().mass, accelerationRHS, a, parset.sub("a0.solver")); diff --git a/src/spatial-solving/preconditioners/levelpatchpreconditioner.hh b/src/spatial-solving/preconditioners/levelpatchpreconditioner.hh index a8216abd0169da350d749f166e868b4c709f7fb6..0b0f6b59cb7de6490be85202f89dc28dc7052335 100644 --- a/src/spatial-solving/preconditioners/levelpatchpreconditioner.hh +++ b/src/spatial-solving/preconditioners/levelpatchpreconditioner.hh @@ -8,6 +8,7 @@ #include <dune/common/bitsetvector.hh> #include <dune/solvers/iterationsteps/lineariterationstep.hh> +#include <dune/solvers/common/numproc.hh> #include "../../data-structures/levelcontactnetwork.hh" @@ -60,7 +61,7 @@ class LevelPatchPreconditioner : public LinearIterationStep<MatrixType, VectorTy patchFactory_(levelContactNetwork_, fineContactNetwork_) { setPatchDepth(); - this->verbosity_ = QUIET; + this->verbosity_ = NumProc::QUIET; } // build support patches @@ -74,7 +75,7 @@ class LevelPatchPreconditioner : public LinearIterationStep<MatrixType, VectorTy // init local fine level corrections Dune::Timer timer; - if (this->verbosity_ == FULL) { + if (this->verbosity_ == NumProc::FULL) { std::cout << std::endl; std::cout << "---------------------------------------------" << std::endl; std::cout << "Initializing local fine grid corrections! Level: " << level_ << std::endl; @@ -106,14 +107,14 @@ class LevelPatchPreconditioner : public LinearIterationStep<MatrixType, VectorTy } } - if (this->verbosity_ == FULL) { + if (this->verbosity_ == NumProc::FULL) { std::cout << std::endl; std::cout << "Total setup time: " << timer.elapsed() << " seconds." << std::endl; std::cout << "---------------------------------------------" << std::endl; timer.stop(); } - if (this->verbosity_ != QUIET) { + if (this->verbosity_ != NumProc::QUIET) { std::cout << "Level: " << level_ << " LevelPatchPreconditioner::build() - SUCCESS" << std::endl; } } @@ -126,7 +127,7 @@ class LevelPatchPreconditioner : public LinearIterationStep<MatrixType, VectorTy patchDepth_ = patchDepth; } - void setVerbosity(VerbosityMode verbosity) { + void setVerbosity(NumProc::VerbosityMode verbosity) { this->verbosity_ = verbosity; } diff --git a/src/spatial-solving/preconditioners/multilevelpatchpreconditioner.hh b/src/spatial-solving/preconditioners/multilevelpatchpreconditioner.hh index 9bab0af77022e1af2c08cc6cac40d027ca00cf74..6e4ef3bf8ea2c3b3c50e67e37580e50b16849c3b 100644 --- a/src/spatial-solving/preconditioners/multilevelpatchpreconditioner.hh +++ b/src/spatial-solving/preconditioners/multilevelpatchpreconditioner.hh @@ -12,15 +12,16 @@ #include "nbodycontacttransfer.hh" #include "levelpatchpreconditioner.hh" +enum MPPMode {additive, multiplicative}; + template <class ContactNetwork, class PatchSolver, class MatrixType, class VectorType> class MultilevelPatchPreconditioner : public LinearIterationStep<MatrixType, VectorType> { public: - enum Mode {additive, multiplicative}; + //struct Mode { enum ModeType {additive, multiplicative}; }; private: using LevelContactNetwork = typename ContactNetwork::LevelContactNetwork; using LevelPatchPreconditioner = LevelPatchPreconditioner<LevelContactNetwork, PatchSolver, MatrixType, VectorType>; - using LevelGlobalPreconditioner = LevelPatchPreconditioner<LevelContactNetwork, PatchSolver, MatrixType, VectorType>; using BitVector = typename LinearIterationStep<MatrixType, VectorType>::BitVector; using MGTransfer = NBodyContactTransfer<ContactNetwork, VectorType>; @@ -30,7 +31,7 @@ class MultilevelPatchPreconditioner : public LinearIterationStep<MatrixType, Vec const ContactNetwork& contactNetwork_; const Dune::BitSetVector<1>& activeLevels_; - const Mode mode_; + const MPPMode mode_; std::vector<std::shared_ptr<LevelPatchPreconditioner>> levelPatchPreconditioners_; @@ -39,15 +40,16 @@ class MultilevelPatchPreconditioner : public LinearIterationStep<MatrixType, Vec std::vector<VectorType> levelRhs_; std::vector<BitVector> levelIgnore_; - PatchSolver coarseSolver_; + std::unique_ptr<PatchSolver> coarseSolver_; std::vector<BitVector> recompute_; + std::vector<BitVector> truncation_; std::vector<std::shared_ptr<MGTransfer>> mgTransfer_; //TODO public: MultilevelPatchPreconditioner(const ContactNetwork& contactNetwork, const Dune::BitSetVector<1>& activeLevels, - const Mode mode = MultilevelPatchPreconditioner::Mode::additive) : + const MPPMode mode = additive) : contactNetwork_(contactNetwork), activeLevels_(activeLevels), mode_(mode) { @@ -55,15 +57,12 @@ class MultilevelPatchPreconditioner : public LinearIterationStep<MatrixType, Vec assert(activeLevels.size() == contactNetwork_.nLevels()); // init level patch preconditioners and multigrid transfer - levelPatchPreconditioners_.resize(0); + levelPatchPreconditioners_.resize(1); + levelPatchPreconditioners_[0] = nullptr; // blank level representing global coarse problem to make further indexing easier int maxLevel = -1; for (size_t i=0; i<activeLevels_.size(); i++) { if (activeLevels_[i][0]) { - // init global problem on coarsest level - const auto& levelNetwork = *contactNetwork_.level(i); - coarseGlobalPreconditioner_ = std::make_shared<LevelGlobalPreconditioner>(levelNetwork); - maxLevel = i; break; } @@ -71,16 +70,16 @@ class MultilevelPatchPreconditioner : public LinearIterationStep<MatrixType, Vec const int coarsestLevel = maxLevel; - typename LevelPatchPreconditioner::Mode levelMode = LevelPatchPreconditioner::Mode::additive; + MPPMode levelMode = additive; if (mode_ != additive){ - levelMode = LevelPatchPreconditioner::Mode::multiplicative; + levelMode = multiplicative; } for (size_t i=maxLevel+1; i<activeLevels_.size(); i++) { if (activeLevels_[i][0]) { // init local patch preconditioners on each level const auto& fineNetwork = contactNetwork_.level(i); - levelPatchPreconditioners_.push_back(std::make_shared<LevelPatchPreconditioner(*contactNetwork_.level(maxLevel), fineNetwork, levelMode)); + levelPatchPreconditioners_.push_back(std::make_shared<LevelPatchPreconditioner>(*contactNetwork_.level(maxLevel), fineNetwork, levelMode)); maxLevel = i; } @@ -90,14 +89,14 @@ class MultilevelPatchPreconditioner : public LinearIterationStep<MatrixType, Vec levelRhs_.resize(size()); // init multigrid transfer - mgTransfer_.resize(levelPatchPreconditioners_.size()); + mgTransfer_.resize(levelPatchPreconditioners_.size()-1); for (size_t i=0; i<mgTransfer_.size(); i++) { mgTransfer_[i] = std::make_shared<MGTransfer>(); - mgTransfer_.setup(contactNetwork_, levelPatchPreconditioners_[i]->level(), levelPatchPreconditioners_[i]->fineLevel()); + mgTransfer_[i]->setup(contactNetwork_, levelPatchPreconditioners_[i+1]->level(), levelPatchPreconditioners_[i+1]->fineLevel()); } //TODO - mgTransfer_.push_back(std::make_shared<MGTransfer>(coarseGlobalPreconditioner_->basis(), *allFaultBasis_)); + //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++) @@ -106,49 +105,51 @@ class MultilevelPatchPreconditioner : public LinearIterationStep<MatrixType, Vec // specify the subset of entries to be reassembled at each iteration recompute_.resize(size()); recompute_[recompute_.size()-1] = contactNetwork_.nBodyAssembler().totalHasObstacle_; - for (size_t i=mgTransfer_.size(); i>=1; i--) - mgTransfer_[i-1]->restrict(recompute_[i], recompute_[i-1]); - - for (size_t i=0; i<this->mgTransfer_.size(); i++) + 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]); - + } } - void setIgnore(const BitVector& i) override { - this->setIgnore(i); + void setIgnore(const BitVector& ignore) { + this->setIgnore(ignore); - auto mgTransfer = std::dynamic_pointer_cast<TruncatedMGTransfer<VectorType> >(this->mgTransfer_[level-1]); - mgTransfer->setCriticalBitField(&critical); + truncation_.resize(size()); + truncation_[size()-1] = ignore; + 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]); + } } void setProblem(const MatrixType& mat, VectorType& x, const VectorType& rhs) override { this->setProblem(mat, x, rhs); - for (size_t i=0; i<levelPatchPreconditioners_.size(); i++) { + size_t maxLevel = levelPatchPreconditioners_.size()-1; + levelX_[maxLevel] = x; + levelRhs_[maxLevel] = rhs; + levelPatchPreconditioners_[maxLevel]->setProblem(mat, levelX_[maxLevel], levelRhs_[maxLevel]); + + for (int i=levelPatchPreconditioners_.size()-2; i>0; i--) { const auto& transfer = *mgTransfer_[i]; - auto& _x = levelX_[i]; - auto& _rhs = levelRhs_[i]; - auto& _mat = levelMat_[i]; - transfer.restrict(x, _x); - transfer.restrict(rhs, _rhs); - transfer.galerkinRestrict(mat, _mat); + transfer.restrict(levelX_[i+1], levelX_[i]); + transfer.restrict(levelRhs_[i+1], levelRhs_[i]); + transfer.galerkinRestrict(*levelPatchPreconditioners_[i+1]->getMatrix(), levelMat_[i]); - levelPatchPreconditioners_[i]->setProblem(_mat, _x, _rhs); + levelPatchPreconditioners_[i]->setProblem(levelMat_[i], levelX_[i], levelRhs_[i]); } // set coarse global problem - const auto& coarseTransfer = *mgTransfer_.back(); - auto& coarseX = levelX_.back(); - auto& coarseRhs = levelRhs_.back(); - auto& coarseMat = levelMat_.back(); + const auto& coarseTransfer = *mgTransfer_[0]; - coarseTransfer.restrict(x, coarseX); - coarseTransfer.restrict(rhs, coarseRhs); - coarseTransfer.galerkinRestrict(mat, coarseMat); + coarseTransfer.restrict(levelX_[1], levelX_[0]); + coarseTransfer.restrict(levelRhs_[1], levelRhs_[0]); + coarseTransfer.galerkinRestrict(levelMat_[1], levelMat_[0]); - coarseSolver_.getIterationStep().setProblem(coarseMat, coarseX, coarseRhs); + coarseSolver_.getIterationStep().setProblem(levelMat_[0], levelX_[0], levelRhs_[0]); } @@ -237,19 +238,18 @@ class MultilevelPatchPreconditioner : public LinearIterationStep<MatrixType, Vec } void build() { - coarseGlobalPreconditioner_->build(); - for (size_t i=0; i<levelPatchPreconditioners_.size(); i++) { levelPatchPreconditioners_[i]->build(); } } - void setPatchSolver(PatchSolver&& patchSolver) { + void setPatchSolver(PatchSolver&& patchSolver) { //TODO create copies of patch solver for each level for (size_t i=0; i<levelPatchPreconditioners_.size(); i++) { levelPatchPreconditioners_[i]->setPatchSolver(std::forward<PatchSolver>(patchSolver)); } - coarseGlobalPreconditioner_->setPatchSolver(std::forward<PatchSolver>(patchSolver)); - }; + + coarseSolver_ = Dune::Solvers::wrap_own_share<PatchSolver>(std::forward<PatchSolver>(patchSolver)); + } void setPatchDepth(const size_t patchDepth = 0) { for (size_t i=0; i<levelPatchPreconditioners_.size(); i++) { @@ -258,7 +258,7 @@ class MultilevelPatchPreconditioner : public LinearIterationStep<MatrixType, Vec } size_t size() const { - return levelPatchPreconditioners_.size()+1; + return levelPatchPreconditioners_.size(); } }; diff --git a/src/spatial-solving/preconditioners/nbodycontacttransfer.cc b/src/spatial-solving/preconditioners/nbodycontacttransfer.cc index 0f0a58c5236c55a7b1b64d53fa37d9e0645f376b..8fba1420da21e8fabda0c1459b29a0a4ece5121e 100644 --- a/src/spatial-solving/preconditioners/nbodycontacttransfer.cc +++ b/src/spatial-solving/preconditioners/nbodycontacttransfer.cc @@ -1,6 +1,7 @@ #include <dune/common/fvector.hh> #include <dune/common/exceptions.hh> #include <dune/istl/bdmatrix.hh> +#include <dune/istl/matrixindexset.hh> #include <dune/fufem/assemblers/transferoperatorassembler.hh> #include <dune/matrix-vector/blockmatrixview.hh> @@ -41,7 +42,7 @@ void NBodyContactTransfer<ContactNetwork, VectorType>::setup(const ContactNetwor } else { // gridTransfer is identity if coarse and fine level coincide for body - BDMatrix<MatrixBlock>* newMatrix = new BDMatrix<MatrixBlock>(coarseContactNetwork.body(i)->nVertices()); + Dune::BDMatrix<MatrixBlock>* newMatrix = new Dune::BDMatrix<MatrixBlock>(coarseContactNetwork.body(i)->nVertices()); for (size_t j=0; j<newMatrix->N(); j++) for (int k=0; k<blocksize; k++) @@ -75,7 +76,7 @@ void NBodyContactTransfer<ContactNetwork, VectorType>::setup(const ContactNetwor const auto& contactCouplings = nBodyAssembler.getContactCouplings(); const std::vector<const MatrixType*> mortarTransferOperators(nBodyAssembler.nCouplings()); - const std::vector<const BitSetVector<1>*> fineHasObstacle(nBodyAssembler.nCouplings()); + const std::vector<const Dune::BitSetVector<1>*> fineHasObstacle(nBodyAssembler.nCouplings()); const std::vector<std::array<int,2> > gridIdx(nBodyAssembler.nCouplings()); for (size_t i=0; i<nBodyAssembler.nCouplings(); i++) { @@ -173,11 +174,11 @@ void NBodyContactTransfer<VectorType>::setupHierarchy(std::vector<std::shared_pt } */ -template<class VectorType> -void NBodyContactTransfer<VectorType>::combineSubMatrices(const std::vector<const MatrixType*>& submat, +template<class ContactNetwork, class VectorType> +void NBodyContactTransfer<ContactNetwork, VectorType>::combineSubMatrices(const std::vector<const MatrixType*>& submat, const std::vector<const MatrixType*>& mortarTransferOperator, const CoordSystemVector& fineLocalCoordSystems, - const std::vector<const BitSetVector<1>*>& fineHasObstacle, + const std::vector<const Dune::BitSetVector<1>*>& fineHasObstacle, const std::vector<std::array<int,2> >& gridIdx) { // /////////////////////////////////// @@ -189,7 +190,7 @@ void NBodyContactTransfer<VectorType>::combineSubMatrices(const std::vector<cons Dune::MatrixVector::BlockMatrixView<MatrixType> view(submat); - MatrixIndexSet totalIndexSet(view.nRows(), view.nCols()); + Dune::MatrixIndexSet totalIndexSet(view.nRows(), view.nCols()); // import indices of canonical transfer operator for (size_t i=0; i<nGrids; i++) diff --git a/src/spatial-solving/preconditioners/nbodycontacttransfer.hh b/src/spatial-solving/preconditioners/nbodycontacttransfer.hh index 7cc8ae010efccb6b58026845c1e30126f0133414..61d4e7c06d5c157786fccf01964ad95018284910 100644 --- a/src/spatial-solving/preconditioners/nbodycontacttransfer.hh +++ b/src/spatial-solving/preconditioners/nbodycontacttransfer.hh @@ -58,12 +58,8 @@ class NBodyContactTransfer : public TruncatedDenseMGTransfer<VectorType> { * \param fineHasObstacle Bitfields determining for each coupling which fine grid nodes belong to the nonmortar boundary. * \param gridIdx For each coupling store the indices of the nonmortar and mortar grid. */ - template <class GridType> - void setup(const std::vector<const GridType*>& grids, int colevel, - const std::vector<const MatrixType*>& mortarTransferOper, - const CoordSystemVector& fineLocalCoordSystems, - const std::vector<const BitSetVector<1>*>& fineHasObstacle, - const std::vector<std::array<int,2> >& gridIdx); + void setup(const ContactNetwork& contactNetwork, const int coarseLevel, const int fineLevel); + protected: /** \brief Combine all the standard prolongation and mortar operators to one big matrix. @@ -78,7 +74,7 @@ class NBodyContactTransfer : public TruncatedDenseMGTransfer<VectorType> { void combineSubMatrices(const std::vector<const MatrixType*>& submat, const std::vector<const MatrixType*>& mortarTransferOperator, const CoordSystemVector& fineLocalCoordSystems, - const std::vector<const BitSetVector<1>*>& fineHasObstacle, + const std::vector<const Dune::BitSetVector<1>*>& fineHasObstacle, const std::vector<std::array<int,2> >& gridIdx); }; diff --git a/src/spatial-solving/solverfactory.cc b/src/spatial-solving/solverfactory.cc index 6196d3ea69f3207149285cbfc357a7add0793995..7b6875ce48eb1f4cfec7303629cf0e4d236261fd 100644 --- a/src/spatial-solving/solverfactory.cc +++ b/src/spatial-solving/solverfactory.cc @@ -11,22 +11,18 @@ #include "../utils/debugutils.hh" template <class Functional, class BitVector> -template <class Preconditioner> +template <class LinearSolver> SolverFactory<Functional, BitVector>::SolverFactory( const Dune::ParameterTree& parset, Functional& J, - Preconditioner&& preconditioner, + LinearSolver&& linearSolver, const BitVector& ignoreNodes) : J_(Dune::Solvers::wrap_own_share<const Functional>(std::forward<Functional>(J))) { nonlinearSmoother_ = std::make_shared<NonlinearSmoother>(*J_, dummyIterate_, LocalSolver()); - linearSolverStep_ = std::make_shared<LinearSolverStep>(); - linearSolverStep_.setPreconditioner(std::forward<Preconditioner>(preconditioner)); - energyNorm_ = std::make_shared<EnergyNorm<Matrix, Vector>>(*linearSolverStep_); - linearSolver_ = std::make_shared<LinearSolver>(*linearSolverStep_, parset.get<size_t>("linear.maximumIterations"), parset.get<double>("linear.tolerance"), *energyNorm_, Solver::QUIET); - - tnnmgStep_ = std::make_shared<Step>(*J_, dummyIterate_, nonlinearSmoother_, linearSolver_, DefectProjection(), LineSearchSolver()); + auto linearSolver = Dune::Solvers::wrap_own_share<LinearSolver>(std::forward<LinearSolver>(linearSolver)); + tnnmgStep_ = std::make_shared<Step>(*J_, dummyIterate_, nonlinearSmoother_, linearSolver, DefectProjection(), LineSearchSolver()); tnnmgStep_->setPreSmoothingSteps(parset.get<int>("main.pre")); tnnmgStep_->setIgnore(ignoreNodes); } diff --git a/src/spatial-solving/solverfactory.hh b/src/spatial-solving/solverfactory.hh index 458b54d7b98331bf1a01fad804e96c23020fbab8..05235798fd608925bded68104f37e11f66c0fe19 100644 --- a/src/spatial-solving/solverfactory.hh +++ b/src/spatial-solving/solverfactory.hh @@ -13,7 +13,6 @@ //#include <dune/tnnmg/iterationsteps/tnnmgstep.hh> #include <dune/tnnmg/iterationsteps/nonlineargsstep.hh> #include <dune/tnnmg/projections/obstacledefectprojection.hh> -#include <dune/tnnmg/linearsolvers/fastamgsolver.hh> #include "tnnmg/tnnmgstep.hh" #include "tnnmg/linearization.hh" @@ -35,13 +34,11 @@ class SolverFactory { using Step = typename Dune::TNNMG::TNNMGStep<Functional, BitVector, Linearization, DefectProjection, LineSearchSolver>; - using LinearSolverStep = typename Dune::Solvers::CGStep<Matrix, Vector, BitVector>; - using LinearSolver = typename Dune::Solvers::LoopSolver<Vector, BitVector>; - template <class Preconditioner> + template <class LinearSolver> SolverFactory(Dune::ParameterTree const &, Functional&, - Preconditioner&& preconditioner, + LinearSolver&&, const BitVector&); void setProblem(Vector& x); @@ -55,11 +52,6 @@ class SolverFactory { // nonlinear smoother std::shared_ptr<NonlinearSmoother> nonlinearSmoother_; - // linear solver - std::shared_ptr<LinearSolverStep> linearSolverStep_; - std::shared_ptr<EnergyNorm<Matrix, Vector>> energyNorm_; - std::shared_ptr<LinearSolver> linearSolver_; - // TNNMGStep std::shared_ptr<Step> tnnmgStep_; }; diff --git a/src/spatial-solving/solverfactory_tmpl.cc b/src/spatial-solving/solverfactory_tmpl.cc index 1355a1fe359e43beebf60264207a0f9e10977222..8e3b2a153e3ec91877c0c6d2b8f78f4e19d601cc 100644 --- a/src/spatial-solving/solverfactory_tmpl.cc +++ b/src/spatial-solving/solverfactory_tmpl.cc @@ -5,6 +5,8 @@ #include "../explicitgrid.hh" #include "../explicitvectors.hh" +#include <dune/solvers/solvers/loopsolver.hh> + #include "../../dune/tectonic/globalfriction.hh" #include "tnnmg/functional.hh" #include "tnnmg/zerononlinearity.hh" @@ -15,5 +17,16 @@ using MyFunctional = Functional<Matrix&, Vector&, MyGlobalFriction&, Vector&, Ve using MyZeroFunctional = Functional<Matrix&, Vector&, ZeroNonlinearity&, Vector&, Vector&, double>; using MySolverFactory = SolverFactory<MyFunctional, BitVector>; +using MyLinearSolver = Dune::Solvers::LoopSolver<Vector, BitVector>; + template class SolverFactory<MyFunctional, BitVector>; +template SolverFactory<MyFunctional, BitVector>::SolverFactory(Dune::ParameterTree const &, + MyFunctional&, + MyLinearSolver&&, + const BitVector&); + template class SolverFactory<MyZeroFunctional, BitVector>; +template SolverFactory<MyZeroFunctional, BitVector>::SolverFactory(Dune::ParameterTree const &, + MyZeroFunctional&, + MyLinearSolver&&, + const BitVector&);