From 9a075dfedb4d25f2b8d11271d3119efd9cdec573 Mon Sep 17 00:00:00 2001 From: Jonathan Youett <youett@math.fu-berlin.de> Date: Tue, 23 Feb 2016 15:25:16 +0100 Subject: [PATCH] Mandel restriction now also works if DenseMultigridTransfer is used. By introducing a template helper method that gets a possibly blocked restriction matrix, this class can now also be used together with the DenseMultigridStep. This is used for example in the case of large deformation contact problems. --- .../transferoperators/mandelobsrestrictor.cc | 47 +++++++++++++------ .../transferoperators/mandelobsrestrictor.hh | 12 +++++ 2 files changed, 44 insertions(+), 15 deletions(-) diff --git a/dune/solvers/transferoperators/mandelobsrestrictor.cc b/dune/solvers/transferoperators/mandelobsrestrictor.cc index 2593b433..50f31679 100644 --- a/dune/solvers/transferoperators/mandelobsrestrictor.cc +++ b/dune/solvers/transferoperators/mandelobsrestrictor.cc @@ -2,6 +2,7 @@ // vi: set et ts=8 sw=4 sts=4: #include <dune/solvers/transferoperators/compressedmultigridtransfer.hh> +#include <dune/solvers/transferoperators/densemultigridtransfer.hh> template <class VectorType> void MandelObstacleRestrictor<VectorType>:: @@ -12,43 +13,59 @@ restrict(const std::vector<BoxConstraint<field_type, blocksize> >&f, const MultigridTransfer<VectorType>& transfer, const Dune::BitSetVector<blocksize>& critical) { - if (!(dynamic_cast<const CompressedMultigridTransfer<VectorType>*>(&transfer))) - DUNE_THROW(Dune::NotImplemented, "Implementation assumes transfer to be of type CompressedMultigridTransfer!"); - const Dune::BCRSMatrix<Dune::FieldMatrix<field_type, 1, 1> >& transferMat = - dynamic_cast<const CompressedMultigridTransfer<VectorType>*>(&transfer)->getMatrix(); + if (dynamic_cast<const CompressedMultigridTransfer<VectorType>*>(&transfer)) + restrict(f,t,fHasObstacle,tHasObstacle, + dynamic_cast<const CompressedMultigridTransfer<VectorType>*>(&transfer)->getMatrix(),critical); + else if (dynamic_cast<const DenseMultigridTransfer<VectorType>*>(&transfer)) + restrict(f,t,fHasObstacle,tHasObstacle, + dynamic_cast<const DenseMultigridTransfer<VectorType>*>(&transfer)->getMatrix(),critical); + else + DUNE_THROW(Dune::NotImplemented, "Implementation assumes transfer to be of type CompressedMultigridTransfer" + "or DenseMultigridTransfer!"); +} + +template <class VectorType> +template <int dim> +void MandelObstacleRestrictor<VectorType>:: +restrict(const std::vector<BoxConstraint<field_type, blocksize> >&f, + std::vector<BoxConstraint<field_type, blocksize> > &t, + const Dune::BitSetVector<blocksize>& fHasObstacle, + const Dune::BitSetVector<blocksize>& tHasObstacle, + const Dune::BCRSMatrix<Dune::FieldMatrix<field_type,dim,dim> >& transferMat, + const Dune::BitSetVector<blocksize>& critical) +{ + // dim should be either 1 for the compressed transfer or dim + assert(dim==blocksize || dim==1); t.resize(transferMat.M()); for (size_t i=0; i<t.size(); i++) t[i].clear(); // We use the multigrid transfer matrix to find all relevant fine grid dofs - typedef typename Dune::BCRSMatrix<Dune::FieldMatrix<field_type,1,1> >::row_type RowType; - typedef typename RowType::ConstIterator ColumnIterator; - // Loop over all coarse grid dofs for (size_t i=0; i<transferMat.N(); i++) { if (fHasObstacle[i].none()) continue; - const RowType& row = transferMat[i]; - - ColumnIterator cIt = row.begin(); - ColumnIterator cEndIt = row.end(); + const auto& row = transferMat[i]; // Loop over all fine grid base functions in the support of tObsIt - for(; cIt!=cEndIt; ++cIt) { + for(auto cIt=row.begin(); cIt != row.end(); ++cIt) { if (tHasObstacle[cIt.index()].none()) continue; // Sort out spurious entries due to numerical dirt - if ((*cIt)[0][0] < 1e-3) - continue; + // initialise with the first entry to ensure to handle the case dim==1 + std::vector<bool> truncated(blocksize,((*cIt)[0][0]<1e-3)); + for (int j=1; j<dim; j++) + truncated[j] = ((*cIt)[j][j] < 1e-3); + for (int j=0; j<blocksize; j++) - if (!critical[i][j] && fHasObstacle[i][j] && tHasObstacle[cIt.index()][j]) { + if (not truncated[j] and not critical[i][j]) { t[cIt.index()].lower(j) = std::max(t[cIt.index()].lower(j), f[i].lower(j)); t[cIt.index()].upper(j) = std::min(t[cIt.index()].upper(j), f[i].upper(j)); } diff --git a/dune/solvers/transferoperators/mandelobsrestrictor.hh b/dune/solvers/transferoperators/mandelobsrestrictor.hh index 5a41c098..03f0f8dc 100644 --- a/dune/solvers/transferoperators/mandelobsrestrictor.hh +++ b/dune/solvers/transferoperators/mandelobsrestrictor.hh @@ -4,6 +4,8 @@ #define DUNE_SOLVERS_TRANSFEROPERATORS_MANDEL_OBSTACLE_RESTRICTOR_HH #include <dune/common/bitsetvector.hh> +#include <dune/common/fmatrix.hh> +#include <dune/istl/bcrsmatrix.hh> #include <dune/solvers/transferoperators/obstaclerestrictor.hh> #include <dune/solvers/transferoperators/multigridtransfer.hh> #include <dune/solvers/common/boxconstraint.hh> @@ -32,6 +34,16 @@ public: const Dune::BitSetVector<blocksize>& tHasObstacle, const MultigridTransfer<VectorType>& transfer, const Dune::BitSetVector<blocksize>& critical); + +private: + //! Helper method that allows to use the restrictor for both compressed and cense transfer operator + template <int dim> + void restrict(const std::vector<BoxConstraint<field_type,blocksize> >& f, + std::vector<BoxConstraint<field_type,blocksize> >& t, + const Dune::BitSetVector<blocksize>& fHasObstacle, + const Dune::BitSetVector<blocksize>& tHasObstacle, + const Dune::BCRSMatrix<Dune::FieldMatrix<field_type,dim,dim> >& transferMat, + const Dune::BitSetVector<blocksize>& critical); }; // include implementation -- GitLab