From ec2064185952ec11d113692d8990e2cacfbc630a Mon Sep 17 00:00:00 2001
From: Oliver Sander <sander@igpm.rwth-aachen.de>
Date: Mon, 31 Jan 2011 16:57:51 +0000
Subject: [PATCH] moved the part of the Steklov-Poincare step that can handle
 continuum--continuum contact into a separate class and file

[[Imported from SVN: r6918]]
---
 .../rodcontinuumsteklovpoincarestep.hh        | 442 +-----------------
 1 file changed, 4 insertions(+), 438 deletions(-)

diff --git a/dune/gfe/coupling/rodcontinuumsteklovpoincarestep.hh b/dune/gfe/coupling/rodcontinuumsteklovpoincarestep.hh
index bde6316a..df60cdc5 100644
--- a/dune/gfe/coupling/rodcontinuumsteklovpoincarestep.hh
+++ b/dune/gfe/coupling/rodcontinuumsteklovpoincarestep.hh
@@ -14,10 +14,6 @@
 #include <dune/fufem/assemblers/boundaryfunctionalassembler.hh>
 #include <dune/fufem/assemblers/localassemblers/neumannboundaryassembler.hh>
 
-#if HAVE_DUNE_CONTACT
-#include <dune/contact/nbodyassembler.hh>
-#endif
-
 #include <dune/gfe/coupling/rodcontinuumcomplex.hh>
 
 
@@ -146,19 +142,7 @@ public:
      */
     void iterate(std::map<std::pair<std::string,std::string>, RigidBodyMotion<3> >& lambda);
 
-#if HAVE_DUNE_CONTACT
-    /** \brief Do one Steklov-Poincare step
-     * \param[in,out] lambda The old and new iterate
-     */
-    void iterateWithContact(std::map<std::pair<std::string,std::string>, RigidBodyMotion<3> >& lambda,
-                            LoopSolver<VectorType>* contactSolver,
-                            const MatrixType* totalStiffnessMatrix,
-                            const NBodyAssembler<ContinuumGridType, VectorType>* contactAssembler,
-                            const std::vector<std::string>& continuumName
-                           );
-#endif
-
-private:
+protected:
     
     std::map<std::pair<std::string,std::string>,RigidBodyMotion<3>::TangentVector> 
         rodDirichletToNeumannMap(const std::string& rodName, 
@@ -222,7 +206,7 @@ private:
     
 public:
     double neumannRegularization_;
-private:
+protected:
     
     //////////////////////////////////////////////////////////////////
     //  Data members related to the rod problems
@@ -253,7 +237,7 @@ private:
 public:    
     /** \todo Should be part of RodData, too */
     mutable std::map<std::string, RodConfigurationType> rodSubdomainSolutions_;
-private:
+protected:
     //////////////////////////////////////////////////////////////////
     //  Data members related to the continuum problems
     //////////////////////////////////////////////////////////////////
@@ -286,7 +270,7 @@ private:
 public:
     /** \todo Should be part of ContinuumData, too */
     mutable std::map<std::string, ContinuumConfigurationType> continuumSubdomainSolutions_;
-private:
+
 };
 
 
@@ -1060,422 +1044,4 @@ iterate(std::map<std::pair<std::string,std::string>, RigidBodyMotion<3> >& lambd
     }
 }
 
-
-#if HAVE_DUNE_CONTACT
-/** \brief One preconditioned Richardson step plus a continuum contact problem
-*/
-template <class RodGridType, class ContinuumGridType>
-void RodContinuumSteklovPoincareStep<RodGridType,ContinuumGridType>::
-iterateWithContact(std::map<std::pair<std::string,std::string>, RigidBodyMotion<3> >& lambda,
-                   LoopSolver<VectorType>* contactSolver,
-                   const MatrixType* totalStiffnessMatrix,
-                   const NBodyAssembler<ContinuumGridType, VectorType>* contactAssembler,
-                   const std::vector<std::string>& continuumName
-)
-{
-    ///////////////////////////////////////////////////////////////////
-    //  Evaluate the Dirichlet-to-Neumann maps for the rods
-    ///////////////////////////////////////////////////////////////////
-
-    std::map<std::pair<std::string,std::string>, RigidBodyMotion<3>::TangentVector> rodForceTorque;
-    
-    for (RodIterator it = rods_.begin(); it != rods_.end(); ++it) {
-        
-        const std::string& rodName = it->first;
-    
-        std::map<std::pair<std::string,std::string>, RigidBodyMotion<3>::TangentVector> forceTorque = rodDirichletToNeumannMap(rodName, lambda);
-
-        insert(rodForceTorque, forceTorque);
-        
-    }
-
-    std::cout << "resultant rod forces and torques: "  << std::endl;
-    typedef typename std::map<std::pair<std::string,std::string>, RigidBodyMotion<3>::TangentVector>::iterator ForceIterator;
-    for (ForceIterator it = rodForceTorque.begin(); it != rodForceTorque.end(); ++it)
-        std::cout << "    [" << it->first.first << ", " << it->first.second << "] -- "
-                  << it->second << std::endl;
-
-    ///////////////////////////////////////////////////////////////////
-    //  Evaluate the Dirichlet-to-Neumann map for the continuum
-    ///////////////////////////////////////////////////////////////////
-    
-    std::map<std::pair<std::string,std::string>, RigidBodyMotion<3>::TangentVector> continuumForceTorque; 
-    
-    LinearIterationStep<MatrixType,VectorType>* multigridStep = dynamic_cast<LinearIterationStep<MatrixType,VectorType>*>(contactSolver->iterationStep_);
-
-    // Make initial iterate: we start from zero
-    for (typename RodContinuumComplex<RodGridType,ContinuumGridType>::ConstContinuumIterator it = complex_.continua_.begin();
-         it != complex_.continua_.end(); ++it) {
-        
-        // Copy the true Dirichlet values into it
-        const LeafBoundaryPatch<ContinuumGridType>& dirichletBoundary = complex_.continuum(it->first).dirichletBoundary_;
-        const VectorType& dirichletValues = complex_.continuum(it->first).dirichletValues_;
-
-        VectorType& thisX = continuumSubdomainSolutions_[it->first];
-        
-        thisX.resize(dirichletValues.size());
-        thisX = 0;
-        
-        for (size_t i=0; i<thisX.size(); i++)
-        if (dirichletBoundary.containsVertex(i))
-            thisX[i] = dirichletValues[i];
-        
-    }
-    
-    typename std::map<std::pair<std::string,std::string>,RigidBodyMotion<3> >::const_iterator it = lambda.begin();
-    for (; it!=lambda.end(); ++it) {
-        
-        const std::pair<std::string,std::string>& couplingName = it->first;
-
-        // Turn \lambda \in TSE(3) into a Dirichlet value for the continuum
-        const LeafBoundaryPatch<ContinuumGridType>& interfaceBoundary = complex_.coupling(couplingName).continuumInterfaceBoundary_;
-        const RigidBodyMotion<dim>& referenceInterface = complex_.coupling(couplingName).referenceInterface_;
-        
-        setRotation(interfaceBoundary, continuumSubdomainSolutions_[couplingName.second], referenceInterface, it->second);
-    
-    }
-
-    VectorType totalX3d;
-    std::vector<VectorType> xVector(continuumName.size());
-    for (int i=0; i<continuumName.size(); i++)
-        xVector[i] = continuumSubdomainSolutions_[continuumName[i]];
-    NBodyAssembler<ContinuumGridType, VectorType>::concatenateVectors(xVector, totalX3d);
-    
-    // Make the set off all Dirichlet nodes
-    Dune::BitSetVector<dim> totalDirichletNodes(totalStiffnessMatrix->N());
-
-    int offset = 0;
-    for (int i=0; i<continuumName.size(); i++) {
-        const Dune::BitSetVector<dim>& ignoreNodes = continuum(continuumName[i]).dirichletAndCouplingNodes_;
-        for (int j=0; j<ignoreNodes.size(); j++)
-            totalDirichletNodes[offset + j] = ignoreNodes[j];
-        offset += ignoreNodes.size();
-    }
-
-
-    // separate, untransformed weak volume and Neumann terms
-    /** \todo Not implemented yet */
-    std::map<std::string,VectorType> rhs3d;
-    for (size_t i=0; i<continuumName.size(); i++) {
-        rhs3d[continuumName[i]].resize(continuum(continuumName[i]).stiffnessMatrix_->N());
-        rhs3d[continuumName[i]] = 0;
-    }
-    VectorType totalRhs3d(totalStiffnessMatrix->N());
-    totalRhs3d = 0;
-    
-    multigridStep->setProblem(*totalStiffnessMatrix, totalX3d, totalRhs3d);
-    multigridStep->ignoreNodes_ = &totalDirichletNodes;
-    
-    contactSolver->preprocess();
-            
-    contactSolver->solve();
-            
-    totalX3d = multigridStep->getSol();
-
-    // Separate 3d solution vector
-    std::vector<VectorType> x3d(continuumName.size());
-    contactAssembler->postprocess(totalX3d, x3d);
-    
-    // the subdomain solutions in canonical coordinates, stored in a map
-    for (size_t i=0; i<x3d.size(); i++)
-        continuumSubdomainSolutions_[continuumName[i]] = x3d[i];
-    
-    //////////////////////////////////////////////////////////////////////////////
-    //  Extract the residual stresses
-    //////////////////////////////////////////////////////////////////////////////
-
-    // compute the residual for each continuum
-    std::map<std::string,VectorType> residual = rhs3d;
-    for (typename std::map<std::string,VectorType>::iterator it = residual.begin(); it != residual.end(); ++it)
-        continuum(it->first).stiffnessMatrix_->mmv(continuumSubdomainSolutions_[it->first], it->second);
-    
-    // Integrate over the residual on the coupling boundary to obtain
-    // an element of T^*SE.
-    for (typename std::map<std::pair<std::string,std::string>, RigidBodyMotion<3> >::iterator it = lambda.begin(); it!=lambda.end(); ++it) {
-        
-        const std::pair<std::string,std::string>& couplingName = it->first;
-        
-        const LeafBoundaryPatch<ContinuumGridType>& interfaceBoundary = complex_.coupling(couplingName).continuumInterfaceBoundary_;
-
-        VectorType neumannForces(residual[it->first.second].size());
-        neumannForces = 0;
-        
-        weakToStrongBoundaryStress(interfaceBoundary, residual[it->first.second], neumannForces);
-  
-        /** \todo Is referenceInterface.r the correct center of rotation? */
-        const RigidBodyMotion<dim>& referenceInterface = complex_.coupling(couplingName).referenceInterface_;
-
-        Dune::FieldVector<double,3> continuumForce, continuumTorque;
-            
-        computeTotalForceAndTorque(interfaceBoundary, 
-                                   neumannForces, 
-                                   complex_.coupling(couplingName).referenceInterface_.r,
-                                   continuumForce, continuumTorque);
-
-        continuumForceTorque[couplingName][0] = continuumForce[0];
-        continuumForceTorque[couplingName][1] = continuumForce[1];
-        continuumForceTorque[couplingName][2] = continuumForce[2];
-        continuumForceTorque[couplingName][3] = continuumTorque[0];
-        continuumForceTorque[couplingName][4] = continuumTorque[1];
-        continuumForceTorque[couplingName][5] = continuumTorque[2];
-    
-    }
-
-
-    std::cout << "resultant continuum force and torque: " << std::endl;
-    for (ForceIterator it = continuumForceTorque.begin(); it != continuumForceTorque.end(); ++it)
-        std::cout << "    [" << it->first.first << ", " << it->first.second << "] -- "
-                  << it->second << std::endl;
-
-    ///////////////////////////////////////////////////////////////
-    //  Compute the overall Steklov-Poincare residual
-    ///////////////////////////////////////////////////////////////
-
-    // Flip orientation of all rod forces, to account for opposing normals.
-    for (ForceIterator it = rodForceTorque.begin(); it != rodForceTorque.end(); ++it)
-        it->second *= -1;
-
-    std::map<std::pair<std::string,std::string>, RigidBodyMotion<3>::TangentVector> residualForceTorque = rodForceTorque;
-    
-    for (ForceIterator it = residualForceTorque.begin(), it2 = continuumForceTorque.begin(); 
-         it != residualForceTorque.end(); 
-         ++it, ++it2) {
-        assert(it->first == it2->first);
-        it->second += it2->second;
-    }
-            
-    ///////////////////////////////////////////////////////////////
-    //  Apply the preconditioner
-    ///////////////////////////////////////////////////////////////
-            
-    std::map<std::pair<std::string,std::string>, RigidBodyMotion<3>::TangentVector> continuumCorrection;
-    std::map<std::pair<std::string,std::string>, RigidBodyMotion<3>::TangentVector> rodCorrection;
-            
-    if (preconditioner_=="DirichletNeumann" or preconditioner_=="NeumannNeumann") {
-                
-        ////////////////////////////////////////////////////////////////////
-        //  Preconditioner is the linearized Neumann-to-Dirichlet map
-        //  of the continuum.
-        ////////////////////////////////////////////////////////////////////
-
-        // Make initial iterate: we start from zero
-        std::map<std::string,VectorType> x;
-        for (typename RodContinuumComplex<RodGridType,ContinuumGridType>::ConstContinuumIterator it = complex_.continua_.begin();
-            it != complex_.continua_.end(); ++it) {
-        
-            // Copy the true Dirichlet values into it
-            const LeafBoundaryPatch<ContinuumGridType>& dirichletBoundary = complex_.continuum(it->first).dirichletBoundary_;
-            const VectorType& dirichletValues = complex_.continuum(it->first).dirichletValues_;
-
-            VectorType& thisX = x[it->first];
-        
-            thisX.resize(dirichletValues.size());
-            thisX = 0;
-    
-            for (size_t i=0; i<thisX.size(); i++)
-            if (dirichletBoundary.containsVertex(i))
-                thisX[i] = dirichletValues[i];
-        
-        }
-    
-        VectorType totalX3d;
-        std::vector<VectorType> xVector(continuumName.size());
-        for (int i=0; i<continuumName.size(); i++)
-            xVector[i] = x[continuumName[i]];
-        NBodyAssembler<ContinuumGridType, VectorType>::concatenateVectors(xVector, totalX3d);
-    
-        // Make the set off all Dirichlet nodes
-        totalDirichletNodes.unsetAll();
-
-        int offset = 0;
-        for (int i=0; i<continuumName.size(); i++) {
-            const LeafBoundaryPatch<ContinuumGridType>& dirichletBoundary = complex_.continuum(continuumName[i]).dirichletBoundary_;
-            int nGridVertices = dirichletBoundary.gridView().indexSet().size(dim);
-            for (int j=0; j<nGridVertices; j++)
-                totalDirichletNodes[offset + j] = dirichletBoundary.containsVertex(j);
-            offset += nGridVertices;
-        }
-
-
-        // separate, untransformed weak volume and Neumann terms
-        /** \todo Not implemented yet */
-        std::map<std::string,VectorType> rhs3d;
-        for (size_t i=0; i<continuumName.size(); i++) {
-            rhs3d[continuumName[i]].resize(continuum(continuumName[i]).stiffnessMatrix_->N());
-            rhs3d[continuumName[i]] = 0;
-        }
-        
-        for (ForceIterator it = residualForceTorque.begin(); it!=residualForceTorque.end(); ++it) {
-        
-            const std::pair<std::string,std::string>& couplingName = it->first;
-
-            // Use 'forceTorque' as a Neumann value for the rod
-            const LeafBoundaryPatch<ContinuumGridType>& interfaceBoundary = complex_.coupling(couplingName).continuumInterfaceBoundary_;
-        
-            // 
-            VectorType localNeumannValues;
-            computeAveragePressure<typename ContinuumGridType::LeafGridView>(it->second, 
-                                            interfaceBoundary, 
-                                            lambda.find(couplingName)->second.r,  // center of torque
-                                            localNeumannValues);
-        
-            typedef P1NodalBasis<typename ContinuumGridType::LeafGridView,double> P1Basis;
-            P1Basis basis(interfaceBoundary.gridView());
-
-            BoundaryFunctionalAssembler<P1Basis> boundaryFunctionalAssembler(basis, interfaceBoundary);
-            BasisGridFunction<P1Basis,VectorType> neumannValuesFunction(basis,localNeumannValues);
-            NeumannBoundaryAssembler<ContinuumGridType, Dune::FieldVector<double,3> > localNeumannAssembler(neumannValuesFunction);
-            boundaryFunctionalAssembler.assemble(localNeumannAssembler, rhs3d[couplingName.second], false);
-
-        }
-        
-        std::vector<VectorType> rhsVector(continuumName.size());
-        for (size_t i=0; i<continuumName.size(); i++)
-            rhsVector[i] = rhs3d[continuumName[i]];
-
-        NBodyAssembler<ContinuumGridType,VectorType>::concatenateVectors(rhsVector, totalRhs3d);
-    
-        multigridStep->setProblem(*totalStiffnessMatrix, totalX3d, totalRhs3d);
-        
-        multigridStep->ignoreNodes_ = &totalDirichletNodes;
-            
-        contactSolver->preprocess();
-            
-        contactSolver->solve();
-            
-        totalX3d = multigridStep->getSol();
-
-        // Separate 3d solution vector
-        std::vector<VectorType> x3d(continuumName.size());
-        contactAssembler->postprocess(totalX3d, x3d);
-    
-        // the subdomain solutions in canonical coordinates, stored in a map
-        for (size_t i=0; i<x3d.size(); i++)
-            x[continuumName[i]] = x3d[i];
-
-        /////////////////////////////////////////////////////////////////////////////////
-        //  Average the continuum displacement on the coupling boundary
-        /////////////////////////////////////////////////////////////////////////////////
-
-        for (typename RodContinuumComplex<RodGridType,ContinuumGridType>::ConstCouplingIterator it = complex_.couplings_.begin(); 
-             it!=complex_.couplings_.end(); ++it) {
-        
-            const std::pair<std::string,std::string>& couplingName = it->first;
-
-            // Use 'forceTorque' as a Neumann value for the rod
-            const LeafBoundaryPatch<ContinuumGridType>& interfaceBoundary = complex_.coupling(couplingName).continuumInterfaceBoundary_;
-        
-            RigidBodyMotion<3> averageInterface;
-            computeAverageInterface(interfaceBoundary, x[couplingName.second], averageInterface);
-        
-            // Compute the linearization
-            /** \todo We could loop directly over interfaceCorrection (and save the name lookup)
-            * if we could be sure that interfaceCorrection contains all possible entries already
-            */
-            continuumCorrection[couplingName][0] = averageInterface.r[0];
-            continuumCorrection[couplingName][1] = averageInterface.r[1];
-            continuumCorrection[couplingName][2] = averageInterface.r[2];
-        
-            Dune::FieldVector<double,3> infinitesimalRotation = Rotation<3,double>::expInv(averageInterface.q);
-            continuumCorrection[couplingName][3] = infinitesimalRotation[0];
-            continuumCorrection[couplingName][4] = infinitesimalRotation[1];
-            continuumCorrection[couplingName][5] = infinitesimalRotation[2];
-        
-        }
-
-
-        std::cout << "resultant continuum interface corrections: " << std::endl;
-        for (ForceIterator it = continuumCorrection.begin(); it != continuumCorrection.end(); ++it)
-        std::cout << "    [" << it->first.first << ", " << it->first.second << "] -- "
-                  << it->second << std::endl;
-
-
-    } 
-    
-    if (preconditioner_=="NeumannDirichlet" or preconditioner_=="NeumannNeumann") {
-            
-        ////////////////////////////////////////////////////////////////////
-        //  Preconditioner is the linearized Neumann-to-Dirichlet map
-        //  of the rod.
-        ////////////////////////////////////////////////////////////////////
-        
-        for (RodIterator it = rods_.begin(); it != rods_.end(); ++it) {
-        
-            const std::string& rodName = it->first;
-    
-            std::map<std::pair<std::string,std::string>, RigidBodyMotion<3>::TangentVector> rodInterfaceCorrection
-                    = linearizedRodNeumannToDirichletMap(rodName,
-                                                         rodSubdomainSolutions_[rodName], 
-                                                         residualForceTorque,
-                                                         lambda);
-
-            insert(rodCorrection, rodInterfaceCorrection);
-        
-        }
-
-        std::cout << "resultant rod interface corrections: " << std::endl;
-        for (ForceIterator it = rodCorrection.begin(); it != rodCorrection.end(); ++it)
-        std::cout << "    [" << it->first.first << ", " << it->first.second << "] -- "
-                  << it->second << std::endl;
-
-    } 
-    
-    std::map<std::pair<std::string,std::string>, RigidBodyMotion<3>::TangentVector> interfaceCorrection;
-
-    if (preconditioner_=="DirichletNeumann") {
-        
-        interfaceCorrection = continuumCorrection;
-        
-    } else if (preconditioner_=="NeumannDirichlet") {
-    
-        interfaceCorrection = rodCorrection;
-        
-    } else if (preconditioner_=="NeumannNeumann") {
-            
-        ////////////////////////////////////////////////////////////////////
-        //  Preconditioner is a convex combination of the linearized
-        //  Neumann-to-Dirichlet map of the continuum and the linearized
-        //  Neumann-to-Dirichlet map of the rod.
-        ////////////////////////////////////////////////////////////////////
-
-        std::cout << "resultant interface corrections: " << std::endl;
-        for (ForceIterator it = rodCorrection.begin(); it != rodCorrection.end(); ++it) {
-
-            const std::pair<std::string,std::string> interfaceName = it->first;
-        
-            std::cout << "    [" << interfaceName.first << ", " << interfaceName.second << "]"
-                      << "  -- " << it->second 
-                      << "  -- " << continuumCorrection[interfaceName] << std::endl;
-
-            // Compute weighted combination of both
-            RigidBodyMotion<3>::TangentVector& correction = interfaceCorrection[interfaceName];
-            for (int j=0; j<6; j++)
-                correction[j] = (alpha_[0] * continuumCorrection[interfaceName][j] + alpha_[1] * rodCorrection[interfaceName][j])
-                                            / (alpha_[0] + alpha_[1]);
-                                            
-        }
-        
-    } else if (preconditioner_=="RobinRobin") {
-            
-        DUNE_THROW(Dune::NotImplemented, "Robin-Robin preconditioner not implemented yet");
-                
-    } else
-        DUNE_THROW(Dune::NotImplemented, preconditioner_ << " is not a known preconditioner");
-            
-    ///////////////////////////////////////////////////////////////////////////////
-    //  Apply the damped correction to the current interface value
-    ///////////////////////////////////////////////////////////////////////////////
-                
-    
-    ForceIterator fIt = interfaceCorrection.begin();
-    for (typename std::map<std::pair<std::string,std::string>,RigidBodyMotion<3> >::iterator it = lambda.begin(); 
-         it!=lambda.end(); 
-         ++it, ++fIt) {
-        assert(it->first == fIt->first);
-        fIt->second *= richardsonDamping_;
-        it->second = RigidBodyMotion<3>::exp(it->second, fIt->second);
-    }
-}
-#endif   // HAVE_DUNE_CONTACT
-
 #endif
-- 
GitLab