From 264d819beb154a215e87394fa61b6e763c920bc5 Mon Sep 17 00:00:00 2001 From: Oliver Sander <sander@igpm.rwth-aachen.de> Date: Thu, 4 Jan 2007 14:48:58 +0000 Subject: [PATCH] moved interpolation of derivatives to the quaternion class [[Imported from SVN: r1116]] --- src/quaternion.hh | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/rodassembler.cc | 18 ++++++------------ 2 files changed, 50 insertions(+), 12 deletions(-) diff --git a/src/quaternion.hh b/src/quaternion.hh index dec08c50..211acbc6 100644 --- a/src/quaternion.hh +++ b/src/quaternion.hh @@ -121,9 +121,20 @@ public: return result; } + /** \brief Invert the quaternion */ + void invert() { + + (*this)[0] *= -1; + (*this)[1] *= -1; + (*this)[2] *= -1; + + (*this) /= this->two_norm2(); + } + /** \brief Interpolate between two rotations */ static Quaternion<T> interpolate(const Quaternion<T>& a, const Quaternion<T>& b, double omega) { +#if 0 // Interpolation in H plus normalization Quaternion<T> result; for (int i=0; i<4; i++) @@ -131,6 +142,39 @@ public: result.normalize(); + return result; +#else // Interpolation on the geodesic in SO(3) from a to b + + Quaternion<T> diff = a; + diff.invert(); + diff.mult(b); + + T dist = 2*std::acos(diff[3]); + + T invSinc = (dist < 1e-4) ? 1/(0.5+(dist*dist/48)) : dist / std::sin(dist/2); + + // Compute difference on T_a SO(3) + Dune::FieldVector<double,3> v; + v[0] = diff[0] * invSinc; + v[1] = diff[1] * invSinc; + v[2] = diff[2] * invSinc; + + v *= omega; + + return a.mult(exp(v[0], v[1], v[2])); +#endif + + } + + /** \brief Interpolate between two rotations */ + static Quaternion<T> interpolateDerivative(const Quaternion<T>& a, const Quaternion<T>& b, + double omega, double intervallLength) { + + Quaternion<T> result; + + for (int i=0; i<4; i++) + result[i] = a[i] / (-intervallLength) + b[i] / intervallLength; + return result; } diff --git a/src/rodassembler.cc b/src/rodassembler.cc index 8f15337e..1cd3c083 100644 --- a/src/rodassembler.cc +++ b/src/rodassembler.cc @@ -303,9 +303,8 @@ getLocalMatrix( EntityPointer &entity, } // Get the derivative of the rotation at the quadrature point by interpolating in $H$ - Quaternion<double> hatq_s; - for (int i=0; i<4; i++) - hatq_s[i] = localSolution[0].q[i]*shapeGrad[0] + localSolution[1].q[i]*shapeGrad[1]; + Quaternion<double> hatq_s = Quaternion<double>::interpolateDerivative(localSolution[0].q, localSolution[1].q, + quadPos, 1/shapeGrad[1]); // The current strain FieldVector<double,blocksize> strain = getStrain(globalSolution, entity, quadPos); @@ -402,7 +401,6 @@ getLocalMatrix( EntityPointer &entity, // \partial W^2 \partial v^i_j \partial v^k_l // All other derivatives are zero - //double sum = duLocal_dvij[k][l][m] * (duCan_dvij[i][j] * hatq.director(m) + darbouxCan*dd_dvj[m][j]*shapeFunction[i]); double sum = du_dvij[k][l][m] * du_dvij[i][j][m]; sum += (strain[m+3] - referenceStrain[m+3]) * du_dvij_dvkl[i][j][k][l][m]; @@ -501,9 +499,8 @@ assembleGradient(const std::vector<Configuration>& sol, Quaternion<double> hatq = Quaternion<double>::interpolate(localSolution[0].q, localSolution[1].q,quadPos[0]); // Get the derivative of the rotation at the quadrature point by interpolating in $H$ - Quaternion<double> hatq_s; - for (int i=0; i<4; i++) - hatq_s[i] = localSolution[0].q[i]*shapeGrad[0] + localSolution[1].q[i]*shapeGrad[1]; + Quaternion<double> hatq_s = Quaternion<double>::interpolateDerivative(localSolution[0].q, localSolution[1].q, + quadPos, 1/shapeGrad[1]); // The current strain FieldVector<double,blocksize> strain = getStrain(sol, it, quadPos); @@ -811,11 +808,8 @@ Dune::FieldVector<double, 6> Dune::RodAssembler<GridType>::getStrain(const std:: Quaternion<double> q = Quaternion<double>::interpolate(localSolution[0].q, localSolution[1].q, pos); // Get the derivative of the rotation at the quadrature point by interpolating in $H$ - Quaternion<double> q_s; - q_s[0] = localSolution[0].q[0]*shapeGrad[0][0] + localSolution[1].q[0]*shapeGrad[1][0]; - q_s[1] = localSolution[0].q[1]*shapeGrad[0][0] + localSolution[1].q[1]*shapeGrad[1][0]; - q_s[2] = localSolution[0].q[2]*shapeGrad[0][0] + localSolution[1].q[2]*shapeGrad[1][0]; - q_s[3] = localSolution[0].q[3]*shapeGrad[0][0] + localSolution[1].q[3]*shapeGrad[1][0]; + Quaternion<double> q_s = Quaternion<double>::interpolateDerivative(localSolution[0].q, localSolution[1].q, + pos, 1/shapeGrad[1]); // ///////////////////////////////////////////// // Sum it all up -- GitLab