From 276bd9377310bd17ca3f353c3d6223ceeb5fb047 Mon Sep 17 00:00:00 2001
From: Oliver Sander <sander@igpm.rwth-aachen.de>
Date: Thu, 11 Aug 2011 13:24:23 +0000
Subject: [PATCH] Hack around an inconsistency between Rotation<3> and other
 target spaces, notably the almost-equivalent UnitVector<4>: A vector with
 three entries is interpreted by the UnitVector<4> class as a tangent vector
 given in the basis returned by orthonormalFrame.  That is correct as it works
 for all kinds of manifolds.  On the other hand, the Rotation<3> class
 interprets as a 3x3 skew matrix (a tangent vector at the identity in the
 matrix representation) even though the implementation used quaternion
 coordinates.

To trick around this the use of exp methods with FieldVector<3> is avoided
by this patch.  A real fix would involve introducing a SkewMatrix class
and using that in Rotation<3>.

[[Imported from SVN: r7575]]
---
 dune/gfe/riemanniantrsolver.cc   | 9 +++++++++
 dune/gfe/targetspacertrsolver.cc | 8 ++++++++
 2 files changed, 17 insertions(+)

diff --git a/dune/gfe/riemanniantrsolver.cc b/dune/gfe/riemanniantrsolver.cc
index 2da1c75d..d2c61777 100644
--- a/dune/gfe/riemanniantrsolver.cc
+++ b/dune/gfe/riemanniantrsolver.cc
@@ -342,8 +342,17 @@ void RiemannianTrustRegionSolver<GridType,TargetSpace>::solve()
         // ////////////////////////////////////////////////////
         
         SolutionType newIterate = x_;
+#if 0   // out-commented until the Rotation class can distinguish skew-symmetric matrices from three-vectors
         for (int j=0; j<newIterate.size(); j++) 
             newIterate[j] = TargetSpace::exp(newIterate[j], corr[j]);
+#else
+        for (int j=0; j<newIterate.size(); j++) {
+            Dune::FieldMatrix<double,TargetSpace::TangentVector::size,TargetSpace::EmbeddedTangentVector::size> B = x_[j].orthonormalFrame();
+            Dune::FieldVector<double,TargetSpace::EmbeddedTangentVector::size> embeddedCorr(0);
+            B.mtv(corr[j], embeddedCorr);
+            newIterate[j] = TargetSpace::exp(newIterate[j], embeddedCorr);
+        }
+#endif
         
         double energy    = assembler_->computeEnergy(newIterate); 
         
diff --git a/dune/gfe/targetspacertrsolver.cc b/dune/gfe/targetspacertrsolver.cc
index 4cc9caa8..f80f4bcd 100644
--- a/dune/gfe/targetspacertrsolver.cc
+++ b/dune/gfe/targetspacertrsolver.cc
@@ -107,7 +107,15 @@ void TargetSpaceRiemannianTRSolver<TargetSpace,N>::solve()
         // ////////////////////////////////////////////////////
         
         TargetSpace newIterate = x_;
+#if 0   // out-commented until the Rotation class can distinguish skew-symmetric matrices from three-vectors
         newIterate = TargetSpace::exp(newIterate, corr[0]);
+#else
+        Dune::FieldMatrix<double,TargetSpace::TangentVector::size,TargetSpace::EmbeddedTangentVector::size> B = x_.orthonormalFrame();
+        Dune::FieldVector<double,TargetSpace::EmbeddedTangentVector::size> embeddedCorr(0);
+        B.mtv(corr[0], embeddedCorr);
+   
+        newIterate = TargetSpace::exp(newIterate, embeddedCorr);
+#endif
         
         /** \todo Don't always recompute oldEnergy */
         double oldEnergy = assembler_->value(x_);
-- 
GitLab