From 8b28d182b4d0be259447c864800b8116972fd330 Mon Sep 17 00:00:00 2001 From: Oliver Sander <sander@igpm.rwth-aachen.de> Date: Thu, 12 Jan 2012 10:28:20 +0000 Subject: [PATCH] Reimplement method secondDerivativeOfDistanceSquaredWRTFirstAndSecondArgument The new implementation properly handles the double-sheet structure [[Imported from SVN: r8372]] --- dune/gfe/rotation.hh | 45 ++++++++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 12 deletions(-) diff --git a/dune/gfe/rotation.hh b/dune/gfe/rotation.hh index 1ec6fa94..0a1ac0ba 100644 --- a/dune/gfe/rotation.hh +++ b/dune/gfe/rotation.hh @@ -658,19 +658,40 @@ public: return A; } - /** \brief Compute the mixed second derivate \partial d^2 / \partial da db - - Unlike the distance itself the squared distance is differentiable at zero - */ + /** \brief Compute the mixed second derivate \partial d^2 / \partial dp dq */ static Dune::FieldMatrix<T,4,4> secondDerivativeOfDistanceSquaredWRTFirstAndSecondArgument(const Rotation<T,3>& p, const Rotation<T,3>& q) { - // use the functionality from the unitvector class - Dune::FieldMatrix<T,4,4> result = UnitVector<T,4>::secondDerivativeOfDistanceSquaredWRTFirstAndSecondArgument(p.globalCoordinates(), - q.globalCoordinates()); - // The unit quaternions form a double cover of SO(3). That means going once around the unit sphere (2\pi) - // means going twice around SO(3) (4\pi). Hence there is a factor 2, which in addition we need to square, - // because we are considering the squared distance. - result *= 4; - return result; + + T sp = p.globalCoordinates() * q.globalCoordinates(); + + // Compute vector A (see notes) + Dune::FieldMatrix<T,1,4> row; + row[0] = q.projectOntoTangentSpace(p.globalCoordinates()); + + EmbeddedTangentVector tmp = p.projectOntoTangentSpace(q.globalCoordinates()); + Dune::FieldMatrix<T,4,1> column; + for (int i=0; i<4; i++) // turn row vector into column vector + column[i] = tmp[i]; + + Dune::FieldMatrix<T,4,4> A; + // A = row * column + Dune::FMatrixHelp::multMatrix(column,row,A); + A *= 4 * UnitVector<T,4>::secondDerivativeOfArcCosSquared(std::fabs(sp)); + + // Compute matrix B (see notes) + Dune::FieldMatrix<T,4,4> Pp, Pq; + for (int i=0; i<4; i++) + for (int j=0; j<4; j++) { + Pp[i][j] = (i==j) - p.globalCoordinates()[i]*p.globalCoordinates()[j]; + Pq[i][j] = (i==j) - q.globalCoordinates()[i]*q.globalCoordinates()[j]; + } + + Dune::FieldMatrix<T,4,4> B; + Dune::FMatrixHelp::multMatrix(Pp,Pq,B); + + // Bring it all together + A.axpy(4 * ( (sp<0) ? -1 : 1) * UnitVector<T,4>::derivativeOfArcCosSquared(std::fabs(sp)), B); + + return A; } /** \brief Compute the third derivative \partial d^3 / \partial dq^3 -- GitLab