Newer
Older
#include <dune/localfunctions/lagrange/pqkfactory.hh>
#include <dune/gfe/unitvector.hh>
#include <dune/gfe/harmonicenergystiffness.hh>
const int dim = 2;
typedef UnitVector<3> TargetSpace;
using namespace Dune;
template <class GridType>
void testEnergy(const GridType* grid, const std::vector<TargetSpace>& coefficients) {
PQkLocalFiniteElementCache<double,double,GridType::dimension,1> feCache;
typedef typename PQkLocalFiniteElementCache<double,double,GridType::dimension,1>::FiniteElementType LocalFiniteElement;
//LocalGeodesicFEFunction<domainDim,double,LocalFiniteElement,TargetSpace> f(feCache.get(element),corners);
HarmonicEnergyLocalStiffness<typename GridType::LeafGridView,LocalFiniteElement,TargetSpace> assembler;
std::vector<TargetSpace> rotatedCoefficients(coefficients.size());
for (int i=0; i<10; i++) {
Rotation<3,double> rotation(FieldVector<double,3>(1), double(i));
FieldMatrix<double,3,3> matrix;
rotation.matrix(matrix);
for (size_t j=0; j<coefficients.size(); j++) {
FieldVector<double,3> tmp;
matrix.mv(coefficients[j].globalCoordinates(), tmp);
rotatedCoefficients[j] = tmp;
}
std::cout << "energy: " << assembler.energy(*grid->template leafbegin<0>(),
feCache.get(grid->template leafbegin<0>()->type()),
std::vector<typename TargetSpace::EmbeddedTangentVector> rotatedGradient;
assembler.assembleEmbeddedGradient(*grid->template leafbegin<0>(),
rotatedCoefficients,
rotatedGradient);
for (size_t j=0; j<coefficients.size(); j++) {
FieldVector<double,3> tmp;
matrix.mtv(rotatedGradient[j], tmp);
std::cout << "gradient: " << tmp << std::endl;
}
}
template <class GridType>
void testGradientOfEnergy(const GridType* grid, const std::vector<TargetSpace>& coefficients)
{
PQkLocalFiniteElementCache<double,double,GridType::dimension,1> feCache;
typedef typename PQkLocalFiniteElementCache<double,double,GridType::dimension,1>::FiniteElementType LocalFiniteElement;
//LocalGeodesicFEFunction<domainDim,double,LocalFiniteElement,TargetSpace> f(feCache.get(element),corners);
HarmonicEnergyLocalStiffness<typename GridType::LeafGridView,LocalFiniteElement,TargetSpace> assembler;
std::vector<typename TargetSpace::EmbeddedTangentVector> gradient;
assembler.assembleEmbeddedGradient(*grid->template leafbegin<0>(),
coefficients,
gradient);
////////////////////////////////////////////////////////////////////////////////////////
// Assemble finite difference approximation of the gradient
////////////////////////////////////////////////////////////////////////////////////////
std::vector<typename TargetSpace::EmbeddedTangentVector> fdGradient;
assembler.assembleEmbeddedFDGradient(*grid->template leafbegin<0>(),
coefficients,
fdGradient);
double diff = 0;
for (size_t i=0; i<fdGradient.size(); i++)
diff = std::max(diff, (gradient[i] - fdGradient[i]).infinity_norm());
if (diff > 1e-6) {
std::cout << "gradient: " << std::endl;
for (size_t i=0; i<gradient.size(); i++)
std::cout << gradient[i] << std::endl;
std::cout << "fd gradient: " << std::endl;
for (size_t i=0; i<fdGradient.size(); i++)
std::cout << fdGradient[i] << std::endl;
}
}
template <int domainDim>
void testUnitVector3d()
{
// ////////////////////////////////////////////////////////
// Make a test grid consisting of a single simplex
// ////////////////////////////////////////////////////////
GridFactory<GridType> factory;
FieldVector<double,dim> pos(0);
factory.insertVertex(pos);
for (int i=0; i<domainDim+1; i++) {
pos = 0;
pos[i] = 1;
factory.insertVertex(pos);
}
std::vector<unsigned int> v(domainDim+1);
for (int i=0; i<domainDim+1; i++)
v[i] = i;
factory.insertElement(GeometryType(GeometryType::simplex,dim), v);
const GridType* grid = factory.createGrid();
// //////////////////////////////////////////////////////////
// Test whether the energy is invariant under isometries
// //////////////////////////////////////////////////////////
int nTestPoints = 10;
double testPoints[10][3] = {{1,0,0}, {0,1,0}, {-0.838114,0.356751,-0.412667},
{-0.490946,-0.306456,0.81551},{-0.944506,0.123687,-0.304319},
{-0.6,0.1,-0.2},{0.45,0.12,0.517},
{-0.1,0.3,-0.1},{-0.444506,0.123687,0.104319},{-0.7,-0.123687,-0.304319}};
// Set up elements of S^2
std::vector<TargetSpace> coefficients(dim+1);
MultiIndex index(dim+1, nTestPoints);
int numIndices = index.cycle();
for (int i=0; i<numIndices; i++, ++index) {
for (int j=0; j<dim+1; j++) {
Dune::array<double,3> w = {testPoints[index[j]][0], testPoints[index[j]][1], testPoints[index[j]][2]};
coefficients[j] = UnitVector<3>(w);
}
testEnergy<GridType>(grid, coefficients);
testGradientOfEnergy(grid, coefficients);
int main(int argc, char** argv)
{
testUnitVector3d<2>();
}