diff --git a/test/interillustration.cc b/test/interillustration.cc new file mode 100644 index 0000000000000000000000000000000000000000..16af3cce36208c236a0d0090e192eb720cdb634c --- /dev/null +++ b/test/interillustration.cc @@ -0,0 +1,173 @@ +#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/gfe/unitvector.hh> +#include <dune/gfe/localgeodesicfefunction.hh> +#include <dune/gfe/localprojectedfefunction.hh> +#include <dune/gfe/localtangentfefunction.hh> + +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_; + +}; + + +template <class TargetSpace, class LocalFEFunctionType> +void interpolate(std::vector<TargetSpace> coefficients, + 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(6); + + typedef GridType::LeafGridView GridView; + GridView gridView = grid->leafGridView(); + + ////////////////////////////////////////////////////////////// + // Set up an interpolation function on the sphere + ////////////////////////////////////////////////////////////// + + typedef P1LocalFiniteElement<double,double,dim> LocalFiniteElement; + LocalFiniteElement localFiniteElement; + + LocalFEFunctionType localGeodesicFEFunction(localFiniteElement,coefficients); + + /////////////////////////////////////////////////////////////// + // 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 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); + Dune::VTKWriter<typename DeformedGridType::LeafGridView> vtkWriter(deformedGrid.leafGridView()); + vtkWriter.addCellData(colors, "colors"); + vtkWriter.write("sphere-patch-" + nameSuffix); + +} + +int main(int argc, char* argv[]) try +{ + static const int dim = 2; + + ////////////////////////////////////////////////////////////// + // Set up an interpolation function on the sphere + ////////////////////////////////////////////////////////////// + + typedef UnitVector<double,3> TargetSpace; + + 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 P1LocalFiniteElement<double,double,dim> LocalFiniteElement; + typedef LocalGeodesicFEFunction<dim, double, LocalFiniteElement, TargetSpace> LocalGFEFunctionType; + typedef GFE::LocalProjectedFEFunction<dim, double, LocalFiniteElement, TargetSpace> LocalProjectedFEFunctionType; + typedef GFE::LocalTangentFEFunction<dim, double, LocalFiniteElement, TargetSpace> LocalTangentFEFunctionType; + + interpolate<TargetSpace,LocalGFEFunctionType>(coefficients, "riemannian"); + interpolate<TargetSpace,LocalProjectedFEFunctionType>(coefficients, "projected"); + interpolate<TargetSpace,LocalTangentFEFunctionType>(coefficients, "tangent"); + + std::vector<RealTuple<double,3> > flatCoefficients(3); + + flatCoefficients[0] = RealTuple<double,3>(FieldVector<double,3>({0,0,0})); + flatCoefficients[1] = RealTuple<double,3>(FieldVector<double,3>({1,0,0})); + flatCoefficients[2] = RealTuple<double,3>(FieldVector<double,3>({0,1,0})); + + typedef GFE::LocalProjectedFEFunction<dim, double, LocalFiniteElement, RealTuple<double,3> > RealTupleProjectedFEFunctionType; + interpolate<RealTuple<double,3>, RealTupleProjectedFEFunctionType>(flatCoefficients, "flat"); +} catch (Exception e) { + + std::cout << e << std::endl; + +}