Commit 2133b97f authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

grid implementation cleaned up

parent 18d9ad99
...@@ -47,6 +47,12 @@ X0 = [x/nrm_X, y/nrm_X, z/nrm_X] ...@@ -47,6 +47,12 @@ X0 = [x/nrm_X, y/nrm_X, z/nrm_X]
u = atan(X0[1]/X0[0]) u = atan(X0[1]/X0[0])
v = acos(X0[2]) v = acos(X0[2])
X1 = [a*cos(u)*sin(v), b*sin(u)*sin(v), c*cos(v)] X1 = [a*cos(u)*sin(v), b*sin(u)*sin(v), c*cos(v)]
print("X1 = ")
print("return {")
for i in range(3):
print(" ",ccode(X1[i]),",")
print("};")
print("")
# jacobian of parametrization # jacobian of parametrization
J = [[diff(X1[i],X[j]) for i in range(3)] for j in range(3)] J = [[diff(X1[i],X[j]) for i in range(3)] for j in range(3)]
......
...@@ -29,68 +29,64 @@ namespace Dune ...@@ -29,68 +29,64 @@ namespace Dune
struct hasSingleGeometryType< CurvedSurfaceGrid<GridFunction,order> > struct hasSingleGeometryType< CurvedSurfaceGrid<GridFunction,order> >
{ {
using HostGrid = GridOf_t<GridFunction>; using HostGrid = GridOf_t<GridFunction>;
static const bool v = hasSingleGeometryType< HostGrid > :: v; static const bool v = hasSingleGeometryType<HostGrid>::v;
static const unsigned int topologyId = hasSingleGeometryType< HostGrid > :: topologyId; static const unsigned int topologyId = hasSingleGeometryType<HostGrid>::topologyId;
}; };
template< class GridFunction, int order, int codim > template< class GridFunction, int order, int codim >
struct hasEntity< CurvedSurfaceGrid<GridFunction,order>, codim > struct hasEntity< CurvedSurfaceGrid<GridFunction,order>, codim >
{ {
static const bool v = true; using HostGrid = GridOf_t<GridFunction>;
static const bool v = hasEntity<HostGrid,codim>::v;
}; };
template< class GridFunction, int order, int codim > template< class GridFunction, int order, int codim >
struct hasEntityIterator< CurvedSurfaceGrid<GridFunction,order>, codim > struct hasEntityIterator< CurvedSurfaceGrid<GridFunction,order>, codim >
{ {
static const bool v = true; using HostGrid = GridOf_t<GridFunction>;
static const bool v = hasEntityIterator<HostGrid,codim>::v;
}; };
//! Implements geometry only for codim=0 entity
template< class GridFunction, int order, int codim > template< class GridFunction, int order, int codim >
struct canCommunicate< CurvedSurfaceGrid<GridFunction,order>, codim > struct hasGeometry< CurvedSurfaceGrid<GridFunction,order>, codim >
{ {
using HostGrid = GridOf_t<GridFunction>; static const bool v = (codim == 0);
static const bool v = canCommunicate< HostGrid, codim >::v && hasEntity< HostGrid, codim >::v;
}; };
template< class GridFunction, int order, int codim >
template< class GridFunction, int order > struct canCommunicate< CurvedSurfaceGrid<GridFunction,order>, codim >
struct hasBackupRestoreFacilities< CurvedSurfaceGrid<GridFunction,order> >
{ {
using HostGrid = GridOf_t<GridFunction>; using HostGrid = GridOf_t<GridFunction>;
static const bool v = hasBackupRestoreFacilities< HostGrid >::v; static const bool v = canCommunicate<HostGrid, codim>::v && hasEntity<HostGrid, codim>::v;
}; };
//! Conformity of the grid is not guaranteed since it depends on the GridFunction that
//! must be continuous in that case.
template< class GridFunction, int order > template< class GridFunction, int order >
struct isLevelwiseConforming< CurvedSurfaceGrid<GridFunction,order> > struct isLevelwiseConforming< CurvedSurfaceGrid<GridFunction,order> >
{ {
using HostGrid = GridOf_t<GridFunction>; static const bool v = false;
static const bool v = isLevelwiseConforming< HostGrid >::v;
}; };
//! Conformity of the grid is not guaranteed since it depends on the GridFunction that
//! must be continuous in that case.
template< class GridFunction, int order > template< class GridFunction, int order >
struct isLeafwiseConforming< CurvedSurfaceGrid<GridFunction,order> > struct isLeafwiseConforming< CurvedSurfaceGrid<GridFunction,order> >
{
using HostGrid = GridOf_t<GridFunction>;
static const bool v = isLeafwiseConforming< HostGrid >::v;
};
template< class GridFunction, int order >
struct threadSafe< CurvedSurfaceGrid<GridFunction,order> >
{ {
static const bool v = false; static const bool v = false;
}; };
//! Implements only partial backup-restore facilities, since the gridfunction is not
//! backuped automatically.
template< class GridFunction, int order > template< class GridFunction, int order >
struct viewThreadSafe< CurvedSurfaceGrid<GridFunction,order> > struct hasBackupRestoreFacilities< CurvedSurfaceGrid<GridFunction,order> >
{ {
static const bool v = false; using HostGrid = GridOf_t<GridFunction>;
static const bool v = hasBackupRestoreFacilities<HostGrid>::v;
}; };
// hasHostEntity // hasHostEntity
// ------------- // -------------
...@@ -98,7 +94,7 @@ namespace Dune ...@@ -98,7 +94,7 @@ namespace Dune
struct hasHostEntity< CurvedSurfaceGrid<GridFunction,order>, codim > struct hasHostEntity< CurvedSurfaceGrid<GridFunction,order>, codim >
{ {
using HostGrid = GridOf_t<GridFunction>; using HostGrid = GridOf_t<GridFunction>;
static const bool v = hasEntity< HostGrid, codim >::v; static const bool v = hasEntity<HostGrid, codim>::v;
}; };
} // namespace Capabilities } // namespace Capabilities
......
...@@ -4,51 +4,68 @@ ...@@ -4,51 +4,68 @@
#define DUNE_CURVED_SURFACE_GRID_CONCEPTS_HH #define DUNE_CURVED_SURFACE_GRID_CONCEPTS_HH
#include <dune/common/concept.hh> #include <dune/common/concept.hh>
#include <dune/curvedsurfacegrid/gridfunctions/gridentityset.hh>
#include <dune/functions/common/functionconcepts.hh>
namespace Dune { namespace Dune {
namespace Concept { namespace Concept {
//! Concept: objects that can be called with given argument list `Args...`
template< class... Args >
struct Callable
{
template< class F >
auto require (F&& f) -> decltype(
f(std::declval<Args>()...)
);
};
//! Check if `F` models the `Callable` concept with the given arguments `Args...`
template< class F, class... Args >
constexpr auto isCallable ()
{ return models<Concept::Callable<Args...>, F>(); }
//! Concept: function associated to the `LocalContext` that can be evaluated in local coordinates
template< class LocalContext > template< class LocalContext >
struct LocalFunction struct LocalFunction
{ {
using LocalCoordinate = typename LocalContext::Geometry::LocalCoordinate; using LocalCoordinate = typename LocalContext::Geometry::LocalCoordinate;
template< class LF > template< class LF >
auto require(LF&& lf) -> decltype( auto require (LF&& lf) -> decltype(
lf.bind(std::declval<LocalContext>()), lf.bind(std::declval<LocalContext>()),
lf.unbind(), lf.unbind(),
lf.localContext(), lf.localContext(),
requireConcept<Dune::Functions::Concept::Callable<LocalCoordinate>>(lf), requireConcept<Concept::Callable<LocalCoordinate>>(lf),
requireConvertible<LocalContext>(lf.localContext()) requireConvertible<LocalContext>(lf.localContext())
); );
}; };
//! Check if `LF` models the `LocalFunction` concept on the given `LocalContext`
template< class LF, class LocalContext > template< class LF, class LocalContext >
constexpr bool isLocalFunction() constexpr bool isLocalFunction ()
{ return models<Concept::LocalFunction<LocalContext>, LF>(); } { return models<Concept::LocalFunction<LocalContext>, LF>(); }
template< class HostGrid > //! Concept: function associated to the `Grid` that can be evaluated in global coordinates
template< class Grid >
struct GridFunction struct GridFunction
{ {
using EntitySet = GridEntitySet<HostGrid,0>; using LocalContext = typename Grid::template Codim<0>::Entity;
using LocalContext = typename EntitySet::Element; using GlobalCoordinate = typename LocalContext::Geometry::GlobalCoordinate;
using GlobalCoordinate = typename EntitySet::GlobalCoordinate;
template< class GF > template< class GF >
auto require(GF&& gf) -> decltype( auto require (GF&& gf) -> decltype(
localFunction(gf), localFunction(gf),
gf.entitySet(), gf.entitySet(),
requireConcept<Dune::Functions::Concept::Callable<GlobalCoordinate>>(gf), requireConcept<Concept::Callable<GlobalCoordinate>>(gf),
requireConcept<LocalFunction<LocalContext>>(localFunction(gf)) requireConcept<Concept::LocalFunction<LocalContext>>(localFunction(gf))
); );
}; };
template< class GF, class HostGrid > //! Check if `GF` models the `GridFunction` concept on the given `Grid`
constexpr bool isGridFunction() template< class GF, class Grid >
{ return models<Concept::GridFunction<HostGrid>, GF>(); } constexpr bool isGridFunction ()
{ return models<Concept::GridFunction<Grid>, GF>(); }
} // end namespace Concept } // end namespace Concept
} // end namespace Dune } // end namespace Dune
......
...@@ -5,6 +5,4 @@ ...@@ -5,6 +5,4 @@
#include <dune/curvedsurfacegrid/grid.hh> #include <dune/curvedsurfacegrid/grid.hh>
#include <dune/grid/geometrygrid/persistentcontainer.hh> #include <dune/grid/geometrygrid/persistentcontainer.hh>
// add your classes here
#endif // DUNE_CURVEDSURFACEGRID_HH #endif // DUNE_CURVEDSURFACEGRID_HH
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
#include <dune/curvedsurfacegrid/datahandle.hh> #include <dune/curvedsurfacegrid/datahandle.hh>
#include <dune/curvedsurfacegrid/gridfunctions/analyticgridfunction.hh> #include <dune/curvedsurfacegrid/gridfunctions/analyticgridfunction.hh>
#include <dune/curvedsurfacegrid/gridfunctions/gridfunction.hh> #include <dune/curvedsurfacegrid/gridfunctions/gridfunction.hh>
#include <dune/functions/common/functionconcepts.hh>
#include <dune/grid/geometrygrid/identity.hh> #include <dune/grid/geometrygrid/identity.hh>
#include <dune/grid/geometrygrid/persistentcontainer.hh> #include <dune/grid/geometrygrid/persistentcontainer.hh>
#include <dune/grid/geometrygrid/grid.hh> #include <dune/grid/geometrygrid/grid.hh>
...@@ -60,7 +59,7 @@ namespace Dune ...@@ -60,7 +59,7 @@ namespace Dune
//! Generator for CurvedSurfaceGrid from a grid-functions //! Generator for CurvedSurfaceGrid from a grid-functions
template< class HostGrid, class GF, int ORDER = -1, template< class HostGrid, class GF, int ORDER = -1,
std::enable_if_t<Dune::Concept::isGridFunction<GF, HostGrid>(), int> = 0> std::enable_if_t<Concept::isGridFunction<GF, HostGrid>(), int> = 0>
auto curedSurfaceGrid (HostGrid& hostGrid, GF&& gridFunction) auto curedSurfaceGrid (HostGrid& hostGrid, GF&& gridFunction)
{ {
static_assert(std::is_same<HostGrid, GridOf_t<std::decay_t<GF>>>::value, "GridFunction must be defined on the HostGrid"); static_assert(std::is_same<HostGrid, GridOf_t<std::decay_t<GF>>>::value, "GridFunction must be defined on the HostGrid");
...@@ -69,11 +68,11 @@ namespace Dune ...@@ -69,11 +68,11 @@ namespace Dune
//! Generator for CurvedSurfaceGrid from a callable //! Generator for CurvedSurfaceGrid from a callable
template< class HostGrid, class F, int ORDER = -1, template< class HostGrid, class F, int ORDER = -1,
std::enable_if_t<not Dune::Concept::isGridFunction<F, HostGrid>(), int> = 0> std::enable_if_t<not Concept::isGridFunction<F, HostGrid>(), int> = 0>
auto curedSurfaceGrid (HostGrid& hostGrid, F&& callable) auto curedSurfaceGrid (HostGrid& hostGrid, F&& callable)
{ {
using GlobalCoordinate = typename GridEntitySet<HostGrid,0>::GlobalCoordinate; using GlobalCoordinate = typename GridEntitySet<HostGrid,0>::GlobalCoordinate;
static_assert(Functions::Concept::isCallable<F, GlobalCoordinate>(), "Function must be callable"); static_assert(Concept::isCallable<F, GlobalCoordinate>(), "Function must be callable");
auto gridFct = analyticGridFunction<HostGrid>(std::forward<F>(callable)); auto gridFct = analyticGridFunction<HostGrid>(std::forward<F>(callable));
return CurvedSurfaceGrid<decltype(gridFct),ORDER>{hostGrid, std::move(gridFct)}; return CurvedSurfaceGrid<decltype(gridFct),ORDER>{hostGrid, std::move(gridFct)};
} }
......
...@@ -19,10 +19,6 @@ ...@@ -19,10 +19,6 @@
#include <dune/curvedsurfacegrid/localgeometrywrapper.hh> #include <dune/curvedsurfacegrid/localgeometrywrapper.hh>
#include <dune/curvedsurfacegrid/gridfunctions/gridfunction.hh> #include <dune/curvedsurfacegrid/gridfunctions/gridfunction.hh>
#include <dune/functions/common/functionconcepts.hh>
#include <dune/functions/common/signature.hh>
#include <dune/functions/gridfunctions/localderivativetraits.hh>
namespace Dune namespace Dune
{ {
...@@ -33,22 +29,11 @@ namespace Dune ...@@ -33,22 +29,11 @@ namespace Dune
{ {
template< class GF > template< class GF >
struct DimRange struct DimRange
{
using SigTraits = Functions::SignatureTraits<GF>;
using Range = typename SigTraits::RawRange;
static const int value = Range::size();
};
template< class GF, class LF >
struct DifferentiableLocalFunction
{ {
using EntitySet = typename GF::EntitySet; using EntitySet = typename GF::EntitySet;
using LocalContext = typename EntitySet::Element; using Range = std::result_of_t<GF(typename EntitySet::GlobalCoordinate)>;
using RawRange = std::decay_t<Range>;
using Range = typename Functions::SignatureTraits<GF>::Range; static const int value = RawRange::size();
using LocalSignature = Range(typename EntitySet::LocalCoordinate);
static const bool value = Functions::Concept::isDifferentiableLocalFunction<LF,LocalSignature,LocalContext,Functions::LocalDerivativeTraits<EntitySet>::template Traits>();
}; };
// GridFamily // GridFamily
...@@ -65,9 +50,6 @@ namespace Dune ...@@ -65,9 +50,6 @@ namespace Dune
using GridFunction = GF; using GridFunction = GF;
using LocalFunction = std::decay_t<decltype(localFunction(std::declval<GF const&>()))>; using LocalFunction = std::decay_t<decltype(localFunction(std::declval<GF const&>()))>;
static const bool differentiableLocalFunction = DifferentiableLocalFunction<GF, LocalFunction>::value;
static_assert((differentiableLocalFunction || order>0), "Either provide a differentiable GridFunction or set ORDER > 0");
using ctype = typename HostGrid::ctype; using ctype = typename HostGrid::ctype;
static const int dimension = HostGrid::dimension; static const int dimension = HostGrid::dimension;
......
install(FILES install(FILES
analyticgridfunction.hh analyticgridfunction.hh
discretegridviewfunction.hh discretegridviewfunction.hh
ellipsoidgridfunction.hh
gridentityset.hh gridentityset.hh
gridfunction.hh gridfunction.hh
normalgridviewfunction.hh normalgridviewfunction.hh
......
...@@ -3,11 +3,11 @@ ...@@ -3,11 +3,11 @@
#ifndef DUNE_CURVED_SURFACE_GRID_ANALYTIC_GRIDFUNCTION_HH #ifndef DUNE_CURVED_SURFACE_GRID_ANALYTIC_GRIDFUNCTION_HH
#define DUNE_CURVED_SURFACE_GRID_ANALYTIC_GRIDFUNCTION_HH #define DUNE_CURVED_SURFACE_GRID_ANALYTIC_GRIDFUNCTION_HH
#include <optional>
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
#include <dune/common/typeutilities.hh> #include <dune/common/typeutilities.hh>
#include <dune/common/std/optional.hh>
#include "gridentityset.hh" #include "gridentityset.hh"
...@@ -102,8 +102,8 @@ namespace Dune ...@@ -102,8 +102,8 @@ namespace Dune
Functor f_; Functor f_;
// some caches // some caches
Std::optional<LocalContext> localContext_; std::optional<LocalContext> localContext_;
Std::optional<Geometry> geometry_; std::optional<Geometry> geometry_;
}; };
//! Derivative of a \ref LocalAnalyticGridFunction //! Derivative of a \ref LocalAnalyticGridFunction
......
...@@ -6,6 +6,10 @@ ...@@ -6,6 +6,10 @@
#include <array> #include <array>
#include <vector> #include <vector>
#if !HAVE_DUNE_FUNCTIONS
#error "Need dune-functions for the definition of the DiscreteGridViewFunction"
#endif
#include <dune/common/fvector.hh> #include <dune/common/fvector.hh>
#include <dune/functions/backends/istlvectorbackend.hh> #include <dune/functions/backends/istlvectorbackend.hh>
#include <dune/functions/common/defaultderivativetraits.hh> #include <dune/functions/common/defaultderivativetraits.hh>
......
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2: // vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_CURVED_SURFACE_GRID_SPHERE_GRIDFUNCTION_HH #ifndef DUNE_CURVED_SURFACE_GRID_ELLIPSOID_GRIDFUNCTION_HH
#define DUNE_CURVED_SURFACE_GRID_SPHERE_GRIDFUNCTION_HH #define DUNE_CURVED_SURFACE_GRID_ELLIPSOID_GRIDFUNCTION_HH
#include <type_traits> #include <cmath>
#include <dune/common/fmatrix.hh>
#include <dune/common/fvector.hh>
#include <dune/common/math.hh> #include <dune/common/math.hh>
#include <dune/functions/common/defaultderivativetraits.hh>
#include "analyticgridfunction.hh" #include "analyticgridfunction.hh"
namespace Dune namespace Dune
...@@ -16,6 +16,9 @@ namespace Dune ...@@ -16,6 +16,9 @@ namespace Dune
template< class T > template< class T >
class EllipsoidProjection class EllipsoidProjection
{ {
using Domain = FieldVector<T,3>;
using Jacobian = FieldMatrix<T,3,3>;
T a_; T a_;
T b_; T b_;
T c_; T c_;
...@@ -29,58 +32,35 @@ namespace Dune ...@@ -29,58 +32,35 @@ namespace Dune
{} {}
//! project the coordinate to the ellipsoid //! project the coordinate to the ellipsoid
// NOTE: This is not a closes-point projection, but a spherical-coordinate projection // NOTE: This is not a closest-point projection, but a spherical-coordinate projection
template< class Domain >
Domain operator() (const Domain& X) const Domain operator() (const Domain& X) const
{ {
using std::sin; using std::cos; using std::sqrt;
auto [phi,theta] = angles(X); T x = X[0], y = X[1], z = X[2];
return {a_*cos(phi)*sin(theta), b_*sin(phi)*sin(theta), c_*cos(theta)}; T nrm = sqrt(x*x + y*y + z*z);
return { a_*x/nrm , b_*y/nrm , c_*z/nrm };
} }
//! derivative of the projection //! derivative of the projection
friend auto derivative (const EllipsoidProjection& ellipsoid) friend auto derivative (const EllipsoidProjection& ellipsoid)
{ {
return [a=ellipsoid.a_,b=ellipsoid.b_,c=ellipsoid.c_](auto const& X) return [a=ellipsoid.a_,b=ellipsoid.b_,c=ellipsoid.c_](Domain const& X)
{ {
using std::sqrt; using std::sqrt;
using Domain = std::decay_t<decltype(X)>;
using DerivativeTraits = Functions::DefaultDerivativeTraits<Domain(Domain)>;
typename DerivativeTraits::Range out;
T x = X[0], y = X[1], z = X[2]; T x = X[0], y = X[1], z = X[2];
T x2 = x*x, y2 = y*y, z2 = z*z; T x2 = x*x, y2 = y*y, z2 = z*z;
T x5 = x2*x2*x;
T nrm0 = x2 + y2;
T nrm1 = x2 + y2 + z2;
T nrm2 = sqrt(nrm0/nrm1);
T nrm3 = sqrt(nrm0/x2);
T nrm4 = sqrt(nrm1)*nrm1;
T nrm5 = sqrt(nrm0)*nrm4;
return { T nrm2 = x2 + y2 + z2;
{ T nrm3 = sqrt(nrm2)*nrm2;
a*x*nrm3*(y2 + z2)/nrm5 , return Jacobian{
-b*y*nrm0/(nrm3*nrm5) , { a*(y2 + z2)/nrm3 , -b*y*x/nrm3 , -c*z*x/nrm3 },
-c*z*x/nrm4 {-a*x*y/nrm3 , b*(x2 + z2)/nrm3 , -c*z*y/nrm3 },
}, {-a*x*z/nrm3 , -b*y*z/nrm3 , c*(x2 + y2)/nrm3 }
{
-a*x2*y*nrm3/nrm5 ,
b*nrm0*nrm0*nrm0*(x2 + z2)/(x5*power(nrm3, 5)*nrm5) ,
-c*y*z/nrm4
},
{
-a*z*nrm0/(nrm3*nrm5) ,
-b*y*z*nrm0/(x*nrm3*nrm5) ,
c*(x2 + y2)/nrm4
}
}; };
}; };
} }
//! Normal vector //! Normal vector
template< class Domain >
Domain normal (const Domain& X) const Domain normal (const Domain& X) const
{ {
using std::sqrt; using std::sqrt;
...@@ -88,39 +68,39 @@ namespace Dune ...@@ -88,39 +68,39 @@ namespace Dune
T a2 = a_*a_, b2 = b_*b_, c2 = c_*c_; T a2 = a_*a_, b2 = b_*b_, c2 = c_*c_;
auto div = sqrt(b2*b2*c2*c2*x*x + a2*a2*c2*c2*y*y + a2*a2*b2*b2*z*z); auto div = sqrt(b2*b2*c2*c2*x*x + a2*a2*c2*c2*y*y + a2*a2*b2*b2*z*z);
return {b2*c2*x/div, a2*c2*y/div, a2*b2*z/div}; return { b2*c2*x/div , a2*c2*y/div , a2*b2*z/div };