From 2b72f61ab1a3b986adf35bc29a6b54d2bac26d1e Mon Sep 17 00:00:00 2001
From: Oliver Sander <sander@igpm.rwth-aachen.de>
Date: Fri, 5 Feb 2010 17:27:55 +0000
Subject: [PATCH] Make rodobstacle use the RigidBodyMotion class

[[Imported from SVN: r5493]]
---
 rodobstacle.cc            | 51 +++++++++++++++++++++------------------
 src/planarrodassembler.cc | 36 +++++++++++++--------------
 src/planarrodassembler.hh |  8 +++---
 src/rodwriter.hh          | 12 ++++-----
 4 files changed, 55 insertions(+), 52 deletions(-)

diff --git a/rodobstacle.cc b/rodobstacle.cc
index 693b402b..9b2492e8 100644
--- a/rodobstacle.cc
+++ b/rodobstacle.cc
@@ -20,7 +20,6 @@
 #include "src/planarrodassembler.hh"
 
 
-// Number of degrees of freedom: 
 // 3 (x, y, theta) for a planar rod
 const int blocksize = 3;
 
@@ -70,7 +69,8 @@ int main (int argc, char *argv[]) try
 {
     // Some types that I need
     typedef BCRSMatrix<FieldMatrix<double, blocksize, blocksize> > MatrixType;
-    typedef BlockVector<FieldVector<double, blocksize> >     VectorType;
+    typedef BlockVector<FieldVector<double, blocksize> >           CorrectionType;
+    typedef std::vector<RigidBodyMotion<2> >                       SolutionType;
 
     // parse data file
     ConfigParser parameterSet;
@@ -106,21 +106,21 @@ int main (int argc, char *argv[]) try
     // ////////////////////////////////
 
     // First create a gauss-seidel base solver
-    ProjectedBlockGSStep<MatrixType, VectorType> baseSolverStep;
+    ProjectedBlockGSStep<MatrixType, CorrectionType> baseSolverStep;
 
-    EnergyNorm<MatrixType, VectorType> baseEnergyNorm(baseSolverStep);
+    EnergyNorm<MatrixType, CorrectionType> baseEnergyNorm(baseSolverStep);
 
-    LoopSolver<VectorType> baseSolver(&baseSolverStep,
+    LoopSolver<CorrectionType> baseSolver(&baseSolverStep,
                                                        baseIt,
                                                        baseTolerance,
                                                        &baseEnergyNorm,
                                                        Solver::QUIET);
 
     // Make pre and postsmoothers
-    ProjectedBlockGSStep<MatrixType, VectorType> presmoother;
-    ProjectedBlockGSStep<MatrixType, VectorType> postsmoother;
+    ProjectedBlockGSStep<MatrixType, CorrectionType> presmoother;
+    ProjectedBlockGSStep<MatrixType, CorrectionType> postsmoother;
 
-    MonotoneMGStep<MatrixType, VectorType> multigridStep(1);
+    MonotoneMGStep<MatrixType, CorrectionType> multigridStep(1);
 
     multigridStep.setMGType(mu, nu1, nu2);
     multigridStep.ignoreNodes_       = &dirichletNodes[0];
@@ -129,12 +129,12 @@ int main (int argc, char *argv[]) try
     multigridStep.hasObstacle_       = &hasObstacle;
     multigridStep.obstacles_         = &trustRegionObstacles;
     multigridStep.verbosity_         = Solver::QUIET;
-    multigridStep.obstacleRestrictor_ = new MandelObstacleRestrictor<VectorType>;
+    multigridStep.obstacleRestrictor_ = new MandelObstacleRestrictor<CorrectionType>;
 
 
-    EnergyNorm<MatrixType, VectorType> energyNorm(multigridStep);
+    EnergyNorm<MatrixType, CorrectionType> energyNorm(multigridStep);
 
-    LoopSolver<VectorType> solver(&multigridStep,
+    LoopSolver<CorrectionType> solver(&multigridStep,
                                                    numIt,
                                                    tolerance,
                                                    &energyNorm,
@@ -142,18 +142,18 @@ int main (int argc, char *argv[]) try
 
     double trustRegionRadius = 0.1;
 
-    VectorType rhs;
-    VectorType x(grid.size(0,1));
-    VectorType corr;
+    CorrectionType rhs;
+    SolutionType x(grid.size(0,1));
+    CorrectionType corr;
 
     // //////////////////////////
     //   Initial solution
     // //////////////////////////
 
     for (int i=0; i<x.size(); i++) {
-        x[i][0] = 1.0/(x.size()-1);
-        x[i][1] = 0;
-        x[i][2] = 0;
+        x[i].r[0] = double(i)/(x.size()-1);
+        x[i].r[1] = 0;
+        x[i].q    = Rotation<2,double>::identity();
     }
 
 
@@ -216,7 +216,7 @@ int main (int argc, char *argv[]) try
         for (int i=0; i<trueObstacles[toplevel].size(); i++) {
             trueObstacles[toplevel][i].clear();
             //trueObstacles[toplevel][i].val[0] =     - x[i][0];
-            trueObstacles[toplevel][i].upper(0) = 0.1 - x[i][0];
+            trueObstacles[toplevel][i].upper(0) = 0.1 - x[i].r[0];
         }
         
 
@@ -233,7 +233,7 @@ int main (int argc, char *argv[]) try
         multigridStep.mgTransfer_.resize(toplevel);
 
         for (int i=0; i<multigridStep.mgTransfer_.size(); i++){
-            TruncatedCompressedMGTransfer<VectorType>* newTransferOp = new TruncatedCompressedMGTransfer<VectorType>;
+            TruncatedCompressedMGTransfer<CorrectionType>* newTransferOp = new TruncatedCompressedMGTransfer<CorrectionType>;
             newTransferOp->setup(grid,i,i+1);
             multigridStep.mgTransfer_[i] = newTransferOp;
         }
@@ -262,7 +262,7 @@ int main (int argc, char *argv[]) try
                                     trueObstacles[toplevel],
                                     dirichletNodes[toplevel]);
 
-            dynamic_cast<MultigridStep<MatrixType,VectorType>*>(solver.iterationStep_)->setProblem(hessianMatrix, corr, rhs, toplevel+1);
+            dynamic_cast<MultigridStep<MatrixType,CorrectionType>*>(solver.iterationStep_)->setProblem(hessianMatrix, corr, rhs, toplevel+1);
 
             solver.preprocess();
 
@@ -285,8 +285,10 @@ int main (int argc, char *argv[]) try
              // ////////////////////////////////////////////////////
              //   Check whether trust-region step can be accepted
              // ////////////////////////////////////////////////////
-             /** \todo Faster with expression templates */
-             VectorType newIterate = x;  newIterate += corr;
+
+             SolutionType newIterate = x;
+             for (int j=0; j<newIterate.size(); j++) 
+                 newIterate[j] = RigidBodyMotion<2>::exp(newIterate[j], corr[j]);
 
              /** \todo Don't always recompute oldEnergy */
              double oldEnergy = rodAssembler.computeEnergy(x); 
@@ -296,7 +298,8 @@ int main (int argc, char *argv[]) try
                  DUNE_THROW(SolverError, "Richtung ist keine Abstiegsrichtung!");
                  
              //  Add correction to the current solution
-             x += corr;
+             for (int j=0; j<x.size(); j++) 
+                 x[j] = RigidBodyMotion<2>::exp(x[j], corr[j]);
 
              // Subtract correction from the current obstacle
              for (int k=0; k<corr.size(); k++)
@@ -314,7 +317,7 @@ int main (int argc, char *argv[]) try
         std::string lagrangeFilename = "pressure/lagrange_" + levelAsAscii.str();
         std::ofstream lagrangeFile(lagrangeFilename.c_str());
         
-        VectorType lagrangeMultipliers;
+        CorrectionType lagrangeMultipliers;
         rodAssembler.assembleGradient(x, lagrangeMultipliers);
         lagrangeFile << lagrangeMultipliers << std::endl;
         
diff --git a/src/planarrodassembler.cc b/src/planarrodassembler.cc
index 2c305a76..f1b57829 100644
--- a/src/planarrodassembler.cc
+++ b/src/planarrodassembler.cc
@@ -43,7 +43,7 @@ getNeighborsPerVertex(MatrixIndexSet& nb) const
 
 template <class GridType, int polOrd>
 void Dune::PlanarRodAssembler<GridType, polOrd>::
-assembleMatrix(const BlockVector<FieldVector<double, blocksize> >& sol,
+assembleMatrix(const std::vector<RigidBodyMotion<2> >& sol,
                BCRSMatrix<MatrixBlock>& matrix)
 {
     const typename GridType::Traits::LevelIndexSet& indexSet = grid_->levelIndexSet(grid_->maxLevel());
@@ -68,7 +68,7 @@ assembleMatrix(const BlockVector<FieldVector<double, blocksize> >& sol,
         mat.setSize(numOfBaseFct, numOfBaseFct);
 
         // Extract local solution
-        BlockVector<FieldVector<double, blocksize> > localSolution(numOfBaseFct);
+        std::vector<RigidBodyMotion<2> > localSolution(numOfBaseFct);
         
         for (int i=0; i<numOfBaseFct; i++)
             localSolution[i] = sol[indexSet.subIndex(*it,i,gridDim)];
@@ -102,7 +102,7 @@ template <class GridType, int polOrd>
 template <class MatrixType>
 void Dune::PlanarRodAssembler<GridType, polOrd>::
 getLocalMatrix( EntityType &entity, 
-                const BlockVector<FieldVector<double, blocksize> >& localSolution,
+                const std::vector<RigidBodyMotion<2> >& localSolution,
                 const int matSize, MatrixType& localMat) const
 {
     const typename GridType::Traits::LevelIndexSet& indexSet = grid_->levelIndexSet(grid_->maxLevel());
@@ -162,10 +162,10 @@ getLocalMatrix( EntityType &entity,
         //   Interpolate
         // //////////////////////////////////
         
-        double x_s     = localSolution[0][0]*shapeGrad[0][0] + localSolution[1][0]*shapeGrad[1][0];
-        double y_s     = localSolution[0][1]*shapeGrad[0][0] + localSolution[1][1]*shapeGrad[1][0];
+        double x_s     = localSolution[0].r[0]*shapeGrad[0][0] + localSolution[1].r[0]*shapeGrad[1][0];
+        double y_s     = localSolution[0].r[1]*shapeGrad[0][0] + localSolution[1].r[1]*shapeGrad[1][0];
 
-        double theta   = localSolution[0][2]*shapeFunction[0] + localSolution[1][2]*shapeFunction[1];
+        double theta   = localSolution[0].q.angle_*shapeFunction[0] + localSolution[1].q.angle_*shapeFunction[1];
 
         for (int i=0; i<matSize; i++) {
 
@@ -262,7 +262,7 @@ getLocalMatrix( EntityType &entity,
 
 template <class GridType, int polOrd>
 void Dune::PlanarRodAssembler<GridType, polOrd>::
-assembleGradient(const BlockVector<FieldVector<double, blocksize> >& sol,
+assembleGradient(const std::vector<RigidBodyMotion<2> >& sol,
                  BlockVector<FieldVector<double, blocksize> >& grad) const
 {
     const typename GridType::Traits::LevelIndexSet& indexSet = grid_->levelIndexSet(grid_->maxLevel());
@@ -285,7 +285,7 @@ assembleGradient(const BlockVector<FieldVector<double, blocksize> >& sol,
             = Dune::LagrangeShapeFunctions<double, double, gridDim>::general(it->geometry().type(), elementOrder);
         const int numOfBaseFct = baseSet.size();  
         
-        FieldVector<double, blocksize> localSolution[numOfBaseFct];
+        RigidBodyMotion<2> localSolution[numOfBaseFct];
         
         for (int i=0; i<numOfBaseFct; i++)
             localSolution[i] = sol[indexSet.subIndex(*it,i,gridDim)];
@@ -329,11 +329,11 @@ assembleGradient(const BlockVector<FieldVector<double, blocksize> >& sol,
             //   Interpolate
             // //////////////////////////////////
 
-            double x_s     = localSolution[0][0]*shapeGrad[0][0] + localSolution[1][0]*shapeGrad[1][0];
-            double y_s     = localSolution[0][1]*shapeGrad[0][0] + localSolution[1][1]*shapeGrad[1][0];
-            double theta_s = localSolution[0][2]*shapeGrad[0][0] + localSolution[1][2]*shapeGrad[1][0];
+            double x_s     = localSolution[0].r[0]*shapeGrad[0][0] + localSolution[1].r[0]*shapeGrad[1][0];
+            double y_s     = localSolution[0].r[1]*shapeGrad[0][0] + localSolution[1].r[1]*shapeGrad[1][0];
+            double theta_s = localSolution[0].q.angle_*shapeGrad[0][0] + localSolution[1].q.angle_*shapeGrad[1][0];
 
-            double theta   = localSolution[0][2]*shapeFunction[0] + localSolution[1][2]*shapeFunction[1];
+            double theta   = localSolution[0].q.angle_*shapeFunction[0] + localSolution[1].q.angle_*shapeFunction[1];
 
             // /////////////////////////////////////////////
             //   Sum it all up
@@ -371,7 +371,7 @@ assembleGradient(const BlockVector<FieldVector<double, blocksize> >& sol,
 
 template <class GridType, int polOrd>
 double Dune::PlanarRodAssembler<GridType, polOrd>::
-computeEnergy(const BlockVector<FieldVector<double, blocksize> >& sol) const
+computeEnergy(const std::vector<RigidBodyMotion<2> >& sol) const
 {
     const int maxlevel = grid_->maxLevel();
     double energy = 0;
@@ -392,7 +392,7 @@ computeEnergy(const BlockVector<FieldVector<double, blocksize> >& sol) const
             = Dune::LagrangeShapeFunctions<double, double, gridDim>::general(it->geometry().type(), elementOrder);
         int numOfBaseFct = baseSet.size();
 
-        FieldVector<double, blocksize> localSolution[numOfBaseFct];
+        RigidBodyMotion<2> localSolution[numOfBaseFct];
         
         for (int i=0; i<numOfBaseFct; i++)
             localSolution[i] = sol[indexSet.subIndex(*it,i,gridDim)];
@@ -440,11 +440,11 @@ computeEnergy(const BlockVector<FieldVector<double, blocksize> >& sol) const
             //   Interpolate
             // //////////////////////////////////
 
-            double x_s     = localSolution[0][0]*shapeGrad[0][0] + localSolution[1][0]*shapeGrad[1][0];
-            double y_s     = localSolution[0][1]*shapeGrad[0][0] + localSolution[1][1]*shapeGrad[1][0];
-            double theta_s = localSolution[0][2]*shapeGrad[0][0] + localSolution[1][2]*shapeGrad[1][0];
+            double x_s     = localSolution[0].r[0]*shapeGrad[0][0] + localSolution[1].r[0]*shapeGrad[1][0];
+            double y_s     = localSolution[0].r[1]*shapeGrad[0][0] + localSolution[1].r[1]*shapeGrad[1][0];
+            double theta_s = localSolution[0].q.angle_*shapeGrad[0][0] + localSolution[1].q.angle_*shapeGrad[1][0];
 
-            double theta   = localSolution[0][2]*shapeFunction[0] + localSolution[1][2]*shapeFunction[1];
+            double theta   = localSolution[0].q.angle_*shapeFunction[0] + localSolution[1].q.angle_*shapeFunction[1];
 
             // /////////////////////////////////////////////
             //   Sum it all up
diff --git a/src/planarrodassembler.hh b/src/planarrodassembler.hh
index 5989f4b1..6da3797c 100644
--- a/src/planarrodassembler.hh
+++ b/src/planarrodassembler.hh
@@ -57,14 +57,14 @@ namespace Dune
 
         /** \brief Assemble the tangent stiffness matrix and the right hand side
          */
-        void assembleMatrix(const BlockVector<FieldVector<double, blocksize> >& sol,
+        void assembleMatrix(const std::vector<RigidBodyMotion<2> >& sol,
                             BCRSMatrix<MatrixBlock>& matrix);
         
-        void assembleGradient(const BlockVector<FieldVector<double, blocksize> >& sol,
+        void assembleGradient(const std::vector<RigidBodyMotion<2> >& sol,
                               BlockVector<FieldVector<double, blocksize> >& grad) const;
 
         /** \brief Compute the energy of a deformation state */
-        double computeEnergy(const BlockVector<FieldVector<double, blocksize> >& sol) const;
+        double computeEnergy(const std::vector<RigidBodyMotion<2> >& sol) const;
 
         void getNeighborsPerVertex(MatrixIndexSet& nb) const;
         
@@ -73,7 +73,7 @@ namespace Dune
         /** \brief Compute the element tangent stiffness matrix  */
         template <class MatrixType>
         void getLocalMatrix( EntityType &entity, 
-                             const BlockVector<FieldVector<double, blocksize> >& localSolution, 
+                             const std::vector<RigidBodyMotion<2> >& localSolution, 
                              const int matSize, MatrixType& mat) const;
 
         
diff --git a/src/rodwriter.hh b/src/rodwriter.hh
index 08686984..7e506308 100644
--- a/src/rodwriter.hh
+++ b/src/rodwriter.hh
@@ -10,7 +10,7 @@
 
 /** \brief Write a planar rod
  */
-void writeRod(const Dune::BlockVector<Dune::FieldVector<double,3> >& rod, 
+void writeRod(const std::vector<RigidBodyMotion<2> >& rod, 
               const std::string& filename)
 {
     int nLines = rod.size() + 1 + 3*rod.size();
@@ -69,18 +69,18 @@ void writeRod(const Dune::BlockVector<Dune::FieldVector<double,3> >& rod,
 
     // The center axis
     for (int i=0; i<rod.size(); i++)
-        outfile << rod[i][0] << "  " << rod[i][1] << "  0" << std::endl;
+        outfile << rod[i].r[0] << "  " << rod[i].r[1] << "  0" << std::endl;
 
     // The directors
     for (int i=0; i<rod.size(); i++) {
 
         Dune::FieldVector<double, 2> director;
-        director[0] = -cos(rod[i][2]);
-        director[1] = sin(rod[i][2]);
+        director[0] = -cos(rod[i].q.angle_);
+        director[1] = sin(rod[i].q.angle_);
         director *= directorLength;
 
-        outfile << rod[i][0]+director[0] << "  " << rod[i][1]+director[1] << "  0 " << std::endl;
-        outfile << rod[i][0]-director[0] << "  " << rod[i][1]-director[1] << "  0 " << std::endl;
+        outfile << rod[i].r[0]+director[0] << "  " << rod[i].r[1]+director[1] << "  0 " << std::endl;
+        outfile << rod[i].r[0]-director[0] << "  " << rod[i].r[1]-director[1] << "  0 " << std::endl;
 
     }
 
-- 
GitLab