From 0e34d2640ba99a97d680f9449904394e67d8e877 Mon Sep 17 00:00:00 2001 From: Oliver Sander <sander@igpm.rwth-aachen.de> Date: Wed, 6 Apr 2011 09:19:15 +0000 Subject: [PATCH] Implement test for the derivative of function gradients wrt coefficients. This test itself is not tested yet and may still contain bugs. Also, I out-commented the permutation-invariance test. I have to make sure somehow that test points are close enough together. [[Imported from SVN: r7100]] --- test/localgeodesicfefunctiontest.cc | 68 ++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 2 deletions(-) diff --git a/test/localgeodesicfefunctiontest.cc b/test/localgeodesicfefunctiontest.cc index 08e8babd..1470414e 100644 --- a/test/localgeodesicfefunctiontest.cc +++ b/test/localgeodesicfefunctiontest.cc @@ -129,6 +129,68 @@ void testDerivative(const std::vector<TargetSpace>& corners) } } +template <class TargetSpace> +void testDerivativeOfGradientWRTCoefficients(const std::vector<TargetSpace>& corners) +{ + // Make local fe function to be tested + LocalGeodesicFEFunction<2,double,TargetSpace> f(corners); + + // A quadrature rule as a set of test points + int quadOrder = 3; + + const Dune::QuadratureRule<double, dim>& quad + = Dune::QuadratureRules<double, dim>::rule(GeometryType(GeometryType::simplex,dim), quadOrder); + + for (size_t pt=0; pt<quad.size(); pt++) { + + const Dune::FieldVector<double,dim>& quadPos = quad[pt].position(); + + // loop over the coefficients + for (size_t i=0; i<corners.size(); i++) { + + // evaluate actual derivative + Tensor3<double, TargetSpace::EmbeddedTangentVector::size, TargetSpace::EmbeddedTangentVector::size, dim> derivative; + f.evaluateDerivativeOfGradientWRTCoefficient(quadPos, i, derivative); + + // evaluate fd approximation of derivative + Tensor3<double, TargetSpace::EmbeddedTangentVector::size, TargetSpace::EmbeddedTangentVector::size, dim> fdDerivative; + + for (int j=0; j<TargetSpace::EmbeddedTangentVector::size; j++) { + + std::vector<TargetSpace> cornersPlus = corners; + std::vector<TargetSpace> cornersMinus = corners; + FieldVector<double,dim> aPlus = corners[i].globalCoordinates(); + FieldVector<double,dim> aMinus = corners[i].globalCoordinates(); + aPlus[j] += eps; + aMinus[j] -= eps; + cornersPlus[i] = TargetSpace(aPlus); + cornersMinus[i] = TargetSpace(aMinus); + LocalGeodesicFEFunction<2,double,TargetSpace> fPlus(cornersPlus); + LocalGeodesicFEFunction<2,double,TargetSpace> fMinus(cornersMinus); + + FieldMatrix<double,TargetSpace::EmbeddedTangentVector::size,dim> hPlus = fPlus.evaluateDerivative(quadPos); + FieldMatrix<double,TargetSpace::EmbeddedTangentVector::size,dim> hMinus = fMinus.evaluateDerivative(quadPos); + + fdDerivative[j] = hPlus; + fdDerivative[j] -= hMinus; + fdDerivative[j] /= 2*eps; + + } + + if ( (derivative - fdDerivative).infinity_norm() > eps ) { + std::cout << className(corners[0]) << ": Analytical derivative of gradient does not match fd approximation." << std::endl; + std::cout << "Analytical: " << derivative << std::endl; + std::cout << "FD : " << fdDerivative << std::endl; + } + + //testDerivativeTangentiality(f.evaluate(quadPos), derivative); + + } + + } +} + + void testRealTuples() { std::cout << " --- Testing RealTuple<1> ---" << std::endl; @@ -174,8 +236,9 @@ void testUnitVector2d() or UnitVector<2>::distance(corners[2],corners[0]) > M_PI*0.98) continue; - testPermutationInvariance(corners); + //testPermutationInvariance(corners); testDerivative(corners); + testDerivativeOfGradientWRTCoefficients(corners); } } @@ -211,8 +274,9 @@ void testUnitVector3d() Dune::array<double,3> w2 = {testPoints[k][0], testPoints[k][1], testPoints[k][2]}; corners[2] = UnitVector<3>(w2); - testPermutationInvariance(corners); + //testPermutationInvariance(corners); testDerivative(corners); + testDerivativeOfGradientWRTCoefficients(corners); } } -- GitLab