Newer
Older

Oliver Sander
committed
#include "config.h"
#include <dune/grid/uggrid.hh>
#include <dune/grid/geometrygrid.hh>
#include <dune/grid/io/file/vtk.hh>
#include <dune/localfunctions/lagrange/p1.hh>
#include <dune/localfunctions/lagrange/p2.hh>
#include <dune/functions/functionspacebases/pq1nodalbasis.hh>
#include <dune/functions/gridfunctions/discretescalarglobalbasisfunction.hh>

Oliver Sander
committed
#include <dune/gfe/unitvector.hh>
#include <dune/gfe/localgeodesicfefunction.hh>
#include <dune/gfe/localprojectedfefunction.hh>
#include <dune/gfe/localtangentfefunction.hh>

Oliver Sander
committed
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
using namespace Dune;
/** \brief Encapsulates the grid deformation for the GeometryGrid class */
template <class HostGridView>
class DeformationFunction
: public Dune :: DiscreteCoordFunction< double, 3, DeformationFunction<HostGridView> >
{
typedef DeformationFunction<HostGridView> This;
typedef Dune :: DiscreteCoordFunction< double, 3, This > Base;
static const int dim = HostGridView::dimension;
public:
DeformationFunction(const HostGridView& gridView,
const std::vector<FieldVector<double,3> >& deformedPosition)
: gridView_(gridView),
deformedPosition_(deformedPosition)
{}
void evaluate (const typename HostGridView::template Codim<dim>::Entity& hostEntity, unsigned int corner,
Dune::FieldVector<double,3> &y ) const
{
const typename HostGridView::IndexSet& indexSet = gridView_.indexSet();
int idx = indexSet.index(hostEntity);
y = deformedPosition_[idx];
}
void evaluate (const typename HostGridView::template Codim<0>::Entity& hostEntity, unsigned int corner,
Dune::FieldVector<double,3> &y ) const
{
const typename HostGridView::IndexSet& indexSet = gridView_.indexSet();
int idx = indexSet.subIndex(hostEntity, corner,dim);
y = deformedPosition_[idx];
}
private:
HostGridView gridView_;
const std::vector<FieldVector<double,3> > deformedPosition_;
};
/** \brief
*
* \param partialDerivative The dof with respect to which we are computing the variation
*/

Oliver Sander
committed
template <class TargetSpace, class LocalFEFunctionType>
void interpolate(const LocalFEFunctionType& localGeodesicFEFunction,
int partialDerivative,

Oliver Sander
committed
const std::string& nameSuffix)
{
static const int dim = 2;
typedef UGGrid<dim> GridType;
GridFactory<GridType> factory;
factory.insertVertex({0,0});
factory.insertVertex({1,0});
factory.insertVertex({0,1});
GeometryType triangle;
triangle.makeTriangle();
factory.insertElement(triangle, {0,1,2});
shared_ptr<GridType> grid = shared_ptr<GridType>(factory.createGrid());
grid->globalRefine(3);

Oliver Sander
committed
typedef GridType::LeafGridView GridView;
GridView gridView = grid->leafGridView();
///////////////////////////////////////////////////////////////
// Sample the interpolating function on the grid
///////////////////////////////////////////////////////////////
std::vector<typename TargetSpace::CoordinateType> samples(gridView.size(dim));
for (auto v=gridView.begin<dim>(); v!=gridView.end<dim>(); ++v)
samples[gridView.indexSet().index(*v)] = localGeodesicFEFunction.evaluate(v->geometry().corner(0)).globalCoordinates();
// Sample a variation vector field
std::vector<typename TargetSpace::EmbeddedTangentVector> variation0(gridView.size(dim));
std::vector<typename TargetSpace::EmbeddedTangentVector> variation1(gridView.size(dim));
for (const auto& v : vertices(gridView))
{
FieldMatrix<double,3,3> derivative;
localGeodesicFEFunction.evaluateDerivativeOfValueWRTCoefficient(v.geometry().corner(0),

Sander, Oliver
committed
partialDerivative, // select the Lagrange node
derivative);

Sander, Oliver
committed
Dune::FieldMatrix<double,2,3> basis = localGeodesicFEFunction.coefficient(partialDerivative).orthonormalFrame();
derivative.mtv(basis[0], variation0[gridView.indexSet().index(v)]);
derivative.mtv(basis[1], variation1[gridView.indexSet().index(v)]);
}

Oliver Sander
committed
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
// sample a checkerboard pattern for nicer pictures
uint pattern = 8;
std::vector<double> colors(gridView.size(0));
for (auto e=gridView.begin<0>(); e!=gridView.end<0>(); ++e)
{
FieldVector<double,dim> center = e->geometry().center();
uint i = pattern * center[0];
uint j = pattern * center[1];
FieldVector<double,dim> local;
local[0] = (center[0] - (i/double(pattern)))*pattern;
local[1] = (center[1] - (j/double(pattern)))*pattern;
colors[gridView.indexSet().index(*e)] = (local[0] + local[1] <= 1);
}
///////////////////////////////////////////////////////////////
// Write a grid with the interpolated positions
///////////////////////////////////////////////////////////////
typedef Dune::GeometryGrid<GridType,DeformationFunction<typename GridType::LeafGridView> > DeformedGridType;
DeformationFunction<GridView> deformationFunction(gridView, samples);
// stupid, can't instantiate deformedGrid with a const grid
DeformedGridType deformedGrid(const_cast<GridType&>(*grid), deformationFunction);
typedef Functions::PQ1NodalBasis<typename DeformedGridType::LeafGridView > FEBasis;
FEBasis feBasis(deformedGrid.leafGridView());
Functions::DiscreteScalarGlobalBasisFunction<decltype(feBasis),decltype(variation0)> variation0Function(feBasis,variation0);
Functions::DiscreteScalarGlobalBasisFunction<decltype(feBasis),decltype(variation1)> variation1Function(feBasis,variation1);
auto localVariation0Function = localFunction(variation0Function);
auto localVariation1Function = localFunction(variation1Function);

Oliver Sander
committed
Dune::VTKWriter<typename DeformedGridType::LeafGridView> vtkWriter(deformedGrid.leafGridView());
vtkWriter.addCellData(colors, "colors");
vtkWriter.addVertexData(localVariation0Function, VTK::FieldInfo("variation 0", VTK::FieldInfo::Type::scalar, variation0[0].size()));
vtkWriter.addVertexData(localVariation1Function, VTK::FieldInfo("variation 1", VTK::FieldInfo::Type::scalar, variation1[0].size()));
vtkWriter.write("sphere-patch-" + nameSuffix);

Oliver Sander
committed
}
int main(int argc, char* argv[]) try
{
static const int dim = 2;
typedef UnitVector<double,3> TargetSpace;

Oliver Sander
committed
//////////////////////////////////////////////////////////////
// Set up a first-order interpolation function on the sphere

Oliver Sander
committed
//////////////////////////////////////////////////////////////
std::vector<TargetSpace> coefficients(3);
coefficients[0] = TargetSpace(FieldVector<double,3>({1,0,0}));
coefficients[1] = TargetSpace(FieldVector<double,3>({0,1,0}));
coefficients[2] = TargetSpace(FieldVector<double,3>({0,0,1}));
typedef LocalGeodesicFEFunction<dim, double, P1LocalFiniteElement<double,double,dim>, TargetSpace> P1LocalGFEFunctionType;
//typedef GFE::LocalProjectedFEFunction<dim, double, LocalFiniteElement, TargetSpace> LocalProjectedFEFunctionType;
//typedef GFE::LocalTangentFEFunction<dim, double, LocalFiniteElement, TargetSpace> LocalTangentFEFunctionType;
P1LocalFiniteElement<double,double,dim> localFiniteElement;
P1LocalGFEFunctionType localGeodesicFEFunction(localFiniteElement,coefficients);
interpolate<TargetSpace, P1LocalGFEFunctionType>(localGeodesicFEFunction, 0, "riemannian-p1");
//interpolate<TargetSpace,LocalProjectedFEFunctionType>(coefficients, "projected");
//interpolate<TargetSpace,LocalTangentFEFunctionType>(coefficients, "tangent");
//////////////////////////////////////////////////////////////
// Set up a second-order interpolation function on the sphere
//////////////////////////////////////////////////////////////
coefficients.resize(6);
coefficients[0] = TargetSpace(FieldVector<double,3>({1,0,0}));

Sander, Oliver
committed
coefficients[1] = TargetSpace(FieldVector<double,3>({0.5,0.5,0.15}));
coefficients[2] = TargetSpace(FieldVector<double,3>({0,1,0}));

Sander, Oliver
committed
coefficients[3] = TargetSpace(FieldVector<double,3>({0.5,0.15,0.5}));
coefficients[4] = TargetSpace(FieldVector<double,3>({0.15,0.5,0.5}));
coefficients[5] = TargetSpace(FieldVector<double,3>({0,0,1}));

Oliver Sander
committed
typedef LocalGeodesicFEFunction<dim, double, P2LocalFiniteElement<double,double,dim>, TargetSpace> P2LocalGFEFunctionType;
//typedef GFE::LocalProjectedFEFunction<dim, double, LocalFiniteElement, TargetSpace> LocalProjectedFEFunctionType;
//typedef GFE::LocalTangentFEFunction<dim, double, LocalFiniteElement, TargetSpace> LocalTangentFEFunctionType;

Oliver Sander
committed
P2LocalFiniteElement<double,double,dim> p2LocalFiniteElement;
P2LocalGFEFunctionType p2LocalGeodesicFEFunction(p2LocalFiniteElement,coefficients);
interpolate<TargetSpace, P2LocalGFEFunctionType>(p2LocalGeodesicFEFunction, 0, "riemannian-p2-vertex");
interpolate<TargetSpace, P2LocalGFEFunctionType>(p2LocalGeodesicFEFunction, 1, "riemannian-p2-edge");

Oliver Sander
committed
//interpolate<TargetSpace,LocalProjectedFEFunctionType>(coefficients, "projected");
//interpolate<TargetSpace,LocalTangentFEFunctionType>(coefficients, "tangent");

Oliver Sander
committed
} catch (Exception e) {
std::cout << e << std::endl;
}