Newer
Older
#include <config.h>
#include <iostream>
#include <dune/common/fvector.hh>
#include <dune/grid/common/quadraturerules.hh>
#include <dune/gfe/rotation.hh>
#include <dune/gfe/realtuple.hh>
#include <dune/gfe/unitvector.hh>
#include <dune/gfe/localgeodesicfefunction.hh>
// Domain dimension
const int dim = 2;
using namespace Dune;
/** \brief Test whether interpolation is invariant under permutation of the simplex vertices
*/
template <class TargetSpace>
void testPoint(const std::vector<TargetSpace>& corners,
const std::vector<double>& weights,
const TargetSpace& argument)
{
// create the assembler
AverageDistanceAssembler<TargetSpace> assembler(corners, weights);
// test the functional
double value = assembler.value(argument);
assert(!std::isnan(value));
assert(value >= 0);
// test the gradient
typename TargetSpace::TangentVector gradient;
assembler.assembleGradient(argument, gradient);
// test the hessian
FieldMatrix<double, TargetSpace::TangentVector::dimension, TargetSpace::TangentVector::dimension> hessian;

Oliver Sander
committed
FieldMatrix<double, TargetSpace::TangentVector::dimension, TargetSpace::TangentVector::dimension> hessianApproximation(0);
assembler.assembleHessian(argument, hessian);

Oliver Sander
committed
//assembler.assembleHessianApproximation(argument, hessianApproximation);
for (size_t i=0; i<hessian.N(); i++)
for (size_t j=0; j<hessian.M(); j++) {
assert(!std::isnan(hessian[i][j]));
assert(!std::isnan(hessianApproximation[i][j]));
}

Oliver Sander
committed
std::cout << "WARNING: no approximation of the Hessian available, not testing" << std::endl;
return;
FieldMatrix<double, TargetSpace::TangentVector::dimension, TargetSpace::TangentVector::dimension> diff = hessian;
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
diff -= hessianApproximation;
std::cout << "Matrix inf diff: " << diff.infinity_norm() << std::endl;
}
template <class TargetSpace>
void testWeightSet(const std::vector<TargetSpace>& corners,
const TargetSpace& argument)
{
// 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();
// local to barycentric coordinates
std::vector<double> weights(dim+1);
weights[0] = 1;
for (int i=0; i<dim; i++) {
weights[0] -= quadPos[i];
weights[i+1] = quadPos[i];
}
testPoint(corners, weights, argument);
}
}
void testRealTuples()
{

Oliver Sander
committed
typedef RealTuple<double,1> TargetSpace;
std::vector<TargetSpace> corners = {TargetSpace(1),
TargetSpace(2),
TargetSpace(3)};
TargetSpace argument = corners[0];
testWeightSet(corners, argument);
argument = corners[1];
testWeightSet(corners, argument);
argument = corners[2];
testWeightSet(corners, argument);
}
void testUnitVectors()
{

Oliver Sander
committed
typedef UnitVector<double,3> TargetSpace;
std::vector<TargetSpace> corners(dim+1);
FieldVector<double,3> input;
input[0] = 1; input[1] = 0; input[2] = 0;
corners[0] = input;
input[0] = 0; input[1] = 1; input[2] = 0;
corners[1] = input;
input[0] = 0; input[1] = 0; input[2] = 1;
corners[2] = input;
TargetSpace argument = corners[0];
testWeightSet(corners, argument);
argument = corners[1];
testWeightSet(corners, argument);
argument = corners[2];
testWeightSet(corners, argument);
}
void testRotations()
{

Oliver Sander
committed
typedef Rotation<double,3> TargetSpace;
FieldVector<double,3> xAxis(0);
xAxis[0] = 1;
FieldVector<double,3> yAxis(0);
yAxis[1] = 1;
FieldVector<double,3> zAxis(0);
zAxis[2] = 1;
std::vector<TargetSpace> corners(dim+1);

Oliver Sander
committed
corners[0] = Rotation<double,3>(xAxis,0.1);
corners[1] = Rotation<double,3>(yAxis,0.1);
corners[2] = Rotation<double,3>(zAxis,0.1);
TargetSpace argument = corners[0];
testWeightSet(corners, argument);
argument = corners[1];
testWeightSet(corners, argument);
argument = corners[2];
testWeightSet(corners, argument);
}
int main()
{
testRealTuples();
testUnitVectors();
//testRotations();
}