-
Oliver Sander authored
[[Imported from SVN: r5669]]
Oliver Sander authored[[Imported from SVN: r5669]]
averagedistanceassemblertest.cc 4.21 KiB
#include <config.h>
#include <iostream>
#include <dune/common/fvector.hh>
#include <dune/grid/common/quadraturerules.hh>
#include <dune/src/rotation.hh>
#include <dune/src/realtuple.hh>
#include <dune/src/unitvector.hh>
#include <dune/src/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::size, TargetSpace::TangentVector::size> hessian;
FieldMatrix<double, TargetSpace::TangentVector::size, TargetSpace::TangentVector::size> hessianApproximation;
assembler.assembleHessian(argument, hessian);
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]));
}
FieldMatrix<double, TargetSpace::TangentVector::size, TargetSpace::TangentVector::size> diff = hessian;
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()
{
typedef RealTuple<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()
{
typedef UnitVector<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()
{
typedef Rotation<3,double> 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);
corners[0] = Rotation<3,double>(xAxis,0.1);
corners[1] = Rotation<3,double>(yAxis,0.1);
corners[2] = Rotation<3,double>(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();
}