From 5b5aeb8e93449097823662281aa1d6242d841f53 Mon Sep 17 00:00:00 2001
From: Oliver Sander <sander@igpm.rwth-aachen.de>
Date: Wed, 15 Aug 2007 09:46:13 +0000
Subject: [PATCH] a method to compute the gradient by fd approximation

[[Imported from SVN: r1524]]
---
 src/rodassembler.cc | 100 ++++++++++++++++++++++++++++++++++++++++++++
 src/rodassembler.hh |  10 ++---
 2 files changed, 103 insertions(+), 7 deletions(-)

diff --git a/src/rodassembler.cc b/src/rodassembler.cc
index bb09d1e1..93a525cc 100644
--- a/src/rodassembler.cc
+++ b/src/rodassembler.cc
@@ -1183,6 +1183,106 @@ assembleGradient(const std::vector<Configuration>& sol,
 
 }
 
+template <class GridType>
+void RodAssembler<GridType>::
+assembleGradientFD(const std::vector<Configuration>& sol,
+                 Dune::BlockVector<Dune::FieldVector<double, blocksize> >& grad) const
+{
+    double eps = 1e-2;
+    if (grad.size() != sol.size())
+        grad.resize(sol.size());
+
+    // ///////////////////////////////////////////////////////////
+    //   Compute gradient by finite-difference approximation
+    // ///////////////////////////////////////////////////////////
+    std::vector<Configuration> forwardSolution = sol;
+    std::vector<Configuration> backwardSolution = sol;
+
+    // ////////////////////////////////////////////////////
+    //   Create local assembler
+    // ////////////////////////////////////////////////////
+
+    Dune::array<double,3> K = {K_[0], K_[1], K_[2]};
+    Dune::array<double,3> A = {A_[0], A_[1], A_[2]};
+    RodLocalStiffness<GridType,double> localStiffness(K, A);
+
+    // //////////////////////////////////////////////////////////////////
+    //   Store pointers to all elements so we can access them by index
+    // //////////////////////////////////////////////////////////////////
+
+    const typename GridType::Traits::LeafIndexSet& indexSet = grid_->leafIndexSet();
+
+    std::vector<EntityPointer> elements(grid_->size(0),grid_->template leafbegin<0>());
+    
+    typename GridType::template Codim<0>::LeafIterator eIt    = grid_->template leafbegin<0>();
+    typename GridType::template Codim<0>::LeafIterator eEndIt = grid_->template leafend<0>();
+
+    for (; eIt!=eEndIt; ++eIt)
+        elements[indexSet.index(*eIt)] = eIt;
+
+    std::vector<Configuration> localReferenceConfiguration(2);
+    std::vector<Configuration> localSolution(2);
+
+    // ///////////////////////////////////////////////////////////////
+    //   Loop over all blocks of the outer matrix
+    // ///////////////////////////////////////////////////////////////
+    for (size_t i=0; i<sol.size(); i++) {
+
+        for (int j=0; j<6; j++) {
+
+            double forwardEnergy = 0;
+            double backwardEnergy = 0;
+            
+            infinitesimalVariation(forwardSolution[i], eps, j);
+            infinitesimalVariation(backwardSolution[i], -eps, j);
+            
+            if (i != grid_->size(1)-1) {
+                
+                localReferenceConfiguration[0] = referenceConfiguration_[i];
+                localReferenceConfiguration[1] = referenceConfiguration_[i+1];
+                
+                localSolution[0] = forwardSolution[i];
+                localSolution[1] = forwardSolution[i+1];
+                
+                forwardEnergy += localStiffness.energy(elements[i], localSolution, localReferenceConfiguration);
+                
+                localSolution[0] = backwardSolution[i];
+                localSolution[1] = backwardSolution[i+1];
+                
+                backwardEnergy += localStiffness.energy(elements[i], localSolution, localReferenceConfiguration);
+                
+            } 
+            
+            if (i != 0) {
+                
+                localReferenceConfiguration[0] = referenceConfiguration_[i-1];
+                localReferenceConfiguration[1] = referenceConfiguration_[i];
+                
+                localSolution[0] = forwardSolution[i-1];
+                localSolution[1] = forwardSolution[i];
+                
+                forwardEnergy += localStiffness.energy(elements[i-1], localSolution, localReferenceConfiguration);
+                
+                localSolution[0] = backwardSolution[i-1];
+                localSolution[1] = backwardSolution[i];
+                
+                backwardEnergy += localStiffness.energy(elements[i-1], localSolution, localReferenceConfiguration);
+                
+            } 
+            
+            // Second derivative
+            grad[i][j] = (forwardEnergy - backwardEnergy) / (2*eps);
+            
+            forwardSolution[i]  = sol[i];
+            backwardSolution[i] = sol[i];
+            
+        }
+
+    }
+
+
+}
+
 
 template <class GridType>
 double RodAssembler<GridType>::
diff --git a/src/rodassembler.hh b/src/rodassembler.hh
index d35dbc51..eaecc939 100644
--- a/src/rodassembler.hh
+++ b/src/rodassembler.hh
@@ -108,13 +108,6 @@ public:
         return u;
     }
         
-
-    //! should allow to assmble boundary conditions only
-//     template<typename Tag>
-//     void assembleBoundaryCondition (const Entity& e, int k=1)
-//     {
-//     }
-    
 };
 
 
@@ -253,6 +246,9 @@ public:
         void assembleGradient(const std::vector<Configuration>& sol,
                               Dune::BlockVector<Dune::FieldVector<double, blocksize> >& grad) const;
 
+        void assembleGradientFD(const std::vector<Configuration>& sol,
+                                Dune::BlockVector<Dune::FieldVector<double, blocksize> >& grad) const;
+
         /** \brief Compute the energy of a deformation state */
         double computeEnergy(const std::vector<Configuration>& sol) const;
 
-- 
GitLab