Skip to content
Snippets Groups Projects
Commit 18d9ad99 authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

Merge branch 'feature/curvedgeometry3' into 'master'

Curved Geometry from LocalFunction

See merge request iwr/dune-curvedsurfacegrid!5
parents 3123de92 c3a618bf
No related branches found
No related tags found
1 merge request!5Curved Geometry from LocalFunction
Showing
with 1819 additions and 1822 deletions
from sympy import *
import numpy as np
import collections
x, y, z = symbols("x y z")
a, b, c = symbols("a b c")
# simplify entries of an array
def simplify_all(A):
if isinstance(A, collections.Iterable):
return list(map(lambda a: simplify_all(a), A))
else:
return simplify(A)
def add(A,B):
if isinstance(A, collections.Iterable):
return list(map(lambda a,b: add(a,b), A,B))
else:
return A + B
def negate(A):
if isinstance(A, collections.Iterable):
return list(map(lambda a: negate(a), A))
else:
return -A
X = [x,y,z]
# normal vector
div = sqrt(b**4*c**4*x**2 + a**4*c**4*y**2 + a**4*b**4**z**2)
N = [b**2*c**2*x/div, a**2*c**2*y/div, a**2*b**2*z/div]
print("N = ")
print("return {")
for i in range(3):
print(" ",ccode(N[i]),",")
print("};")
print("")
# projection
P = [[ (1 if i==j else 0) - N[i]*N[j] for j in range(3)] for i in range(3)]
# parametrization
nrm_X = sqrt(x**2 + y**2 + z**2)
X0 = [x/nrm_X, y/nrm_X, z/nrm_X]
u = atan(X0[1]/X0[0])
v = acos(X0[2])
X1 = [a*cos(u)*sin(v), b*sin(u)*sin(v), c*cos(v)]
# jacobian of parametrization
J = [[diff(X1[i],X[j]) for i in range(3)] for j in range(3)]
print("J = ")
print("return {")
for i in range(3):
print(" {")
for j in range(3):
print(" ",ccode(simplify(J[i][j])),",")
print(" },")
print("};")
print("")
# P(F)_j
def project1(F):
return simplify_all([
np.sum([
P[i][j] * F[i]
for i in range(3)])
for j in range(3)])
# P(F)_kl
def project2(F):
return simplify_all([[
np.sum([np.sum([
P[i][k] * P[j][l] * F[i][j]
for j in range(3)]) for i in range(3)])
for l in range(3)] for k in range(3)])
# P(F)_lmn
def project3(F):
return simplify_all([[[
np.sum([np.sum([np.sum([
P[i][l] * P[j][m] * P[k][n] * F[i][j][k]
for k in range(3)]) for j in range(3)]) for i in range(3)])
for n in range(3)] for m in range(3)] for l in range(3)])
# P(F)_mnop
def project4(F):
return simplify_all([[[[
np.sum([np.sum([np.sum([np.sum([
P[i][m] * P[j][n] * P[k][o] * P[l][p] * F[i][j][k][l]
for l in range(3)]) for k in range(3)]) for j in range(3)]) for i in range(3)])
for p in range(3)] for o in range(3)] for n in range(3)] for m in range(3)])
# Euclidean gradient
def Grad0(f):
return simplify_all([
diff(f, X[i])
for i in range(3)])
# surface gradient (covariant derivative of scalars)
def grad0(f):
return project1(Grad0(f))
def Grad1(T):
return simplify_all([[
diff(T[i], X[j])
for j in range(3)] for i in range(3)])
# surface shape operator
#B = negate(project2(Grad1(N)))
# covariant derivative of vector field
def grad1(T):
return simplify_all(add(project2(Grad1(T)), [[
np.sum([
B[i][j] * T[k] * N[k]
for k in range(3)])
for j in range(3)] for i in range(3)]))
def Grad2(T):
return simplify_all([[[
diff(T[i][j], X[k])
for k in range(3)] for j in range(3)] for i in range(3)])
def grad2(T):
return simplify_all([[[
np.sum([np.sum([np.sum([
P[L1][I1] * P[L2][I2] * P[L3][K] * diff(T[L1][L2], X[L3])
for L3 in range(3)]) for L2 in range(3)]) for L1 in range(3)]) +
np.sum([np.sum([
B[K][I1] * P[J2][I2] * T[L][J2] * N[L]
for J2 in range(3)]) for L in range(3)]) +
np.sum([np.sum([
B[K][I2] * P[J1][I1] * T[J1][L] * N[L]
for J1 in range(3)]) for L in range(3)])
for K in range(3)] for I2 in range(3)] for I1 in range(3)])
def Grad3(T):
return simplify_all([[[[
diff(T[i][j][k], X[l])
for l in range(3)] for k in range(3)] for j in range(3)] for i in range(3)])
def grad3(T):
return simplify_all(add(project4(Grad3(T)), [[[[
np.sum([np.sum([np.sum([
B[K][I1] * P[J2][I2] * P[J3][I3] * T[L][J2][J3] * N[L]
for J2 in range(3)]) for J3 in range(3)]) for L in range(3)]) +
np.sum([np.sum([np.sum([
B[K][I2] * P[J1][I1] * P[J3][I3] * T[J1][L][J3] * N[L]
for J1 in range(3)]) for J3 in range(3)]) for L in range(3)]) +
np.sum([np.sum([np.sum([
B[K][I3] * P[J1][I1] * P[J2][I2] * T[J1][J2][L] * N[L]
for J1 in range(3)]) for J2 in range(3)]) for L in range(3)])
for K in range(3)] for I3 in range(3)] for I2 in range(3)] for I1 in range(3)]))
# normal-rotation of scalar field
def rot0(f):
return [diff(f*N[2],y) - diff(f*N[1],z),
diff(f*N[0],z) - diff(f*N[2],x),
diff(f*N[1],x) - diff(f*N[0],y)]
def Div1(F):
return diff(F[0],x) + diff(F[1],y) + diff(F[2],z)
def div1(F):
return Div1(project1(F))
# def div2(t):
# F = Matrix([div1(t.row(0).T), div1(t.row(1).T), div1(t.row(2).T)])
# return P*F
# div(T)_I1,I2
def div3(T):
return simplify_all([[
np.sum([np.sum([np.sum([np.sum([np.sum([
P[L1][I1] * P[L2][I2] * P[L3][K] * P[L4][K] * diff(T[L1][L2][L3],X[L4])
for K in range(3)]) for L4 in range(3)]) for L3 in range(3)]) for L2 in range(3)]) for L1 in range(3)]) +
np.sum([np.sum([
B[I3][I1] * T[L][I2][I3] * N[L] +
B[I3][I2] * T[I1][L][I3] * N[L] +
B[I3][I3] * T[I1][I2][L] * N[L]
for I3 in range(3)]) for L in range(3)])
for I2 in range(3)] for I1 in range(3)])
#p0 = simplify_all( rot0(x*y*z) ) # => vector
#print("p0 = ", p0)
# p1 = simplify_all( grad1(p0) ) # => 2-tensor
# print("p1 = ", p1)
# f = simplify_all( add(negate(div3(grad2(p1))), p1) )
# print("f = ", f)
#F = simplify( -div2(grad1(p0)) + p0 )
#print("F = ", F)
#print("F*N = ", simplify(F.dot(N)))
\ No newline at end of file
......@@ -7,5 +7,5 @@ Module: dune-curvedsurfacegrid
Version: 0.1.0
Maintainer: florian.stenger@tu-dresden.de
#depending on
Depends: dune-common dune-geometry dune-grid dune-localfunctions dune-curvilineargeometry
Depends: dune-common dune-geometry dune-grid dune-localfunctions dune-curvedgeometry dune-functions
Suggests: dune-alugrid dune-foamgrid
add_subdirectory(surfacedistance)
add_subdirectory(test)
set(HEADERS
install(FILES
backuprestore.hh
capabilities.hh
concepts.hh
coordfunctionimplementations.hh
coordprovider.hh
curvedsurfacegrid.hh
datahandle.hh
declaration.hh
......@@ -20,7 +18,9 @@ set(HEADERS
intersection.hh
intersectioniterator.hh
iterator.hh
)
install(FILES ${HEADERS}
localgeometrywrapper.hh
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dune/curvedsurfacegrid)
add_subdirectory(gridfunctions)
add_subdirectory(surfacedistance)
add_subdirectory(test)
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_CRVSRF_BACKUPRESTORE_HH
#define DUNE_CRVSRF_BACKUPRESTORE_HH
#ifndef DUNE_CURVED_SURFACE_GRID_BACKUPRESTORE_HH
#define DUNE_CURVED_SURFACE_GRID_BACKUPRESTORE_HH
#include <dune/grid/common/backuprestore.hh>
......@@ -9,84 +9,80 @@
namespace Dune
{
namespace crvsrf
namespace Curved
{
// BackupRestoreFacilities
// -----------------------
template< class Grid, bool hasBackupRestoreFacilities = Capabilities::hasBackupRestoreFacilities< Grid > ::v >
template< class Grid, bool hasBackupRestoreFacilities = Capabilities::hasBackupRestoreFacilities<Grid> ::v >
class BackupRestoreFacilities
{};
template< class Grid >
class BackupRestoreFacilities< Grid, true >
class BackupRestoreFacilities<Grid, true>
{
typedef BackupRestoreFacilities< Grid, true > This;
using Self = BackupRestoreFacilities<Grid, true>;
protected:
BackupRestoreFacilities ()
{}
private:
BackupRestoreFacilities ( const This & );
This &operator= ( const This & );
BackupRestoreFacilities (const Self&);
Self& operator= (const Self&);
protected:
const Grid &asImp () const
const Grid& asImp () const
{
return static_cast< const Grid & >( *this );
return static_cast<const Grid&>(*this);
}
Grid &asImp ()
Grid& asImp ()
{
return static_cast< Grid & >( *this );
return static_cast<Grid&>(*this);
}
};
} // namespace crvsrf
} // namespace Curved
// BackupRestoreFacility for CurvedSurfaceGrid
// -------------------------------------------
template< class HostGrid, class CoordFunction, int order, bool geoCaching, class Allocator >
struct BackupRestoreFacility< CurvedSurfaceGrid< HostGrid, CoordFunction, order, geoCaching, Allocator > >
template< class GridFunction, int order >
struct BackupRestoreFacility<CurvedSurfaceGrid<GridFunction, order>>
{
typedef CurvedSurfaceGrid< HostGrid, CoordFunction, order, geoCaching, Allocator > Grid;
typedef BackupRestoreFacility< HostGrid > HostBackupRestoreFacility;
using Grid = CurvedSurfaceGrid<GridFunction, order>;
using HostGrid = typename Grid::HostGrid;
using HostBackupRestoreFacility = BackupRestoreFacility<HostGrid>;
static void backup ( const Grid &grid, const std::string &filename )
static void backup (const Grid& grid, const std::string& filename)
{
// notice: We should also backup the coordinate function
HostBackupRestoreFacility::backup( grid.hostGrid(), filename );
HostBackupRestoreFacility::backup(grid.hostGrid(), filename);
}
static void backup ( const Grid &grid, const std::ostream &stream )
static void backup (const Grid& grid, const std::ostream& stream)
{
// notice: We should also backup the coordinate function
HostBackupRestoreFacility::backup( grid.hostGrid(), stream );
HostBackupRestoreFacility::backup(grid.hostGrid(), stream);
}
static Grid *restore ( const std::string &filename )
static Grid* restore (const std::string& filename)
{
// notice: We should also restore the coordinate function
HostGrid *hostGrid = HostBackupRestoreFacility::restore( filename );
CoordFunction *coordFunction = new CoordFunction();
return new Grid( hostGrid, coordFunction );
assert(false && "Restore not yet implemented for CurvedSurfaceGrid");
return nullptr;
}
static Grid *restore ( const std::istream &stream )
static Grid* restore (const std::istream& stream)
{
// notice: We should also restore the coordinate function
HostGrid *hostGrid = HostBackupRestoreFacility::restore( stream );
CoordFunction *coordFunction = new CoordFunction();
return new Grid( hostGrid, coordFunction );
assert(false && "Restore not yet implemented for CurvedSurfaceGrid");
return nullptr;
}
};
} // namespace Dune
#endif // #ifndef DUNE_CRVSRF_BACKUPRESTORE_HH
#endif // DUNE_CURVED_SURFACE_GRID_BACKUPRESTORE_HH
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_CRVSRF_CAPABILITIES_HH
#define DUNE_CRVSRF_CAPABILITIES_HH
#ifndef DUNE_CURVED_SURFACE_GRID_CAPABILITIES_HH
#define DUNE_CURVED_SURFACE_GRID_CAPABILITIES_HH
#include <cassert>
......@@ -11,6 +11,7 @@
#include <dune/grid/common/capabilities.hh>
#include <dune/grid/geometrygrid/capabilities.hh>
#include <dune/curvedsurfacegrid/declaration.hh>
#include <dune/curvedsurfacegrid/gridfunctions/gridfunction.hh>
namespace Dune
{
......@@ -24,61 +25,66 @@ namespace Dune
// Capabilities from dune-grid
// ---------------------------
template< class HostGrid, class CoordFunction, int order, bool geoCaching, class Allocator >
struct hasSingleGeometryType< CurvedSurfaceGrid< HostGrid, CoordFunction, order, geoCaching, Allocator > >
template< class GridFunction, int order >
struct hasSingleGeometryType< CurvedSurfaceGrid<GridFunction,order> >
{
using HostGrid = GridOf_t<GridFunction>;
static const bool v = hasSingleGeometryType< HostGrid > :: v;
static const unsigned int topologyId = hasSingleGeometryType< HostGrid > :: topologyId;
};
template< class HostGrid, class CoordFunction, int order, bool geoCaching, class Allocator, int codim >
struct hasEntity< CurvedSurfaceGrid< HostGrid, CoordFunction, order, geoCaching, Allocator >, codim >
template< class GridFunction, int order, int codim >
struct hasEntity< CurvedSurfaceGrid<GridFunction,order>, codim >
{
static const bool v = true;
};
template< class HostGrid, class CoordFunction, int order, bool geoCaching, class Allocator, int codim >
struct hasEntityIterator< CurvedSurfaceGrid< HostGrid, CoordFunction, order, geoCaching, Allocator >, codim >
template< class GridFunction, int order, int codim >
struct hasEntityIterator< CurvedSurfaceGrid<GridFunction,order>, codim >
{
static const bool v = true;
};
template< class HostGrid, class CoordFunction, int order, bool geoCaching, class Allocator, int codim >
struct canCommunicate< CurvedSurfaceGrid< HostGrid, CoordFunction, order, geoCaching, Allocator >, codim >
template< class GridFunction, int order, int codim >
struct canCommunicate< CurvedSurfaceGrid<GridFunction,order>, codim >
{
using HostGrid = GridOf_t<GridFunction>;
static const bool v = canCommunicate< HostGrid, codim >::v && hasEntity< HostGrid, codim >::v;
};
template< class HostGrid, class CoordFunction, int order, bool geoCaching, class Allocator >
struct hasBackupRestoreFacilities< CurvedSurfaceGrid< HostGrid, CoordFunction, order, geoCaching, Allocator > >
template< class GridFunction, int order >
struct hasBackupRestoreFacilities< CurvedSurfaceGrid<GridFunction,order> >
{
using HostGrid = GridOf_t<GridFunction>;
static const bool v = hasBackupRestoreFacilities< HostGrid >::v;
};
template< class HostGrid, class CoordFunction, int order, bool geoCaching, class Allocator >
struct isLevelwiseConforming< CurvedSurfaceGrid< HostGrid, CoordFunction, order, geoCaching, Allocator > >
template< class GridFunction, int order >
struct isLevelwiseConforming< CurvedSurfaceGrid<GridFunction,order> >
{
using HostGrid = GridOf_t<GridFunction>;
static const bool v = isLevelwiseConforming< HostGrid >::v;
};
template< class HostGrid, class CoordFunction, int order, bool geoCaching, class Allocator >
struct isLeafwiseConforming< CurvedSurfaceGrid< HostGrid, CoordFunction, order, geoCaching, Allocator > >
template< class GridFunction, int order >
struct isLeafwiseConforming< CurvedSurfaceGrid<GridFunction,order> >
{
using HostGrid = GridOf_t<GridFunction>;
static const bool v = isLeafwiseConforming< HostGrid >::v;
};
template< class HostGrid, class CoordFunction, int order, bool geoCaching, class Allocator >
struct threadSafe< CurvedSurfaceGrid< HostGrid, CoordFunction, order, geoCaching, Allocator > >
template< class GridFunction, int order >
struct threadSafe< CurvedSurfaceGrid<GridFunction,order> >
{
static const bool v = false;
};
template< class HostGrid, class CoordFunction, int order, bool geoCaching, class Allocator >
struct viewThreadSafe< CurvedSurfaceGrid< HostGrid, CoordFunction, order, geoCaching, Allocator > >
template< class GridFunction, int order >
struct viewThreadSafe< CurvedSurfaceGrid<GridFunction,order> >
{
static const bool v = false;
};
......@@ -88,9 +94,10 @@ namespace Dune
// hasHostEntity
// -------------
template< class HostGrid, class CoordFunction, int order, bool geoCaching, class Allocator, int codim >
struct hasHostEntity< CurvedSurfaceGrid< HostGrid, CoordFunction, order, geoCaching, Allocator >, codim >
template< class GridFunction, int order, int codim >
struct hasHostEntity< CurvedSurfaceGrid<GridFunction,order>, codim >
{
using HostGrid = GridOf_t<GridFunction>;
static const bool v = hasEntity< HostGrid, codim >::v;
};
......@@ -98,4 +105,4 @@ namespace Dune
} // namespace Dune
#endif // #ifndef DUNE_CRVSRF_CAPABILITIES_HH
#endif // DUNE_CURVED_SURFACE_GRID_CAPABILITIES_HH
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_CURVED_SURFACE_GRID_CONCEPTS_HH
#define DUNE_CURVED_SURFACE_GRID_CONCEPTS_HH
#include <dune/common/concept.hh>
#include <dune/curvedsurfacegrid/gridfunctions/gridentityset.hh>
#include <dune/functions/common/functionconcepts.hh>
namespace Dune {
namespace Concept {
template< class LocalContext >
struct LocalFunction
{
using LocalCoordinate = typename LocalContext::Geometry::LocalCoordinate;
template< class LF >
auto require(LF&& lf) -> decltype(
lf.bind(std::declval<LocalContext>()),
lf.unbind(),
lf.localContext(),
requireConcept<Dune::Functions::Concept::Callable<LocalCoordinate>>(lf),
requireConvertible<LocalContext>(lf.localContext())
);
};
template< class LF, class LocalContext >
constexpr bool isLocalFunction()
{ return models<Concept::LocalFunction<LocalContext>, LF>(); }
template< class HostGrid >
struct GridFunction
{
using EntitySet = GridEntitySet<HostGrid,0>;
using LocalContext = typename EntitySet::Element;
using GlobalCoordinate = typename EntitySet::GlobalCoordinate;
template< class GF >
auto require(GF&& gf) -> decltype(
localFunction(gf),
gf.entitySet(),
requireConcept<Dune::Functions::Concept::Callable<GlobalCoordinate>>(gf),
requireConcept<LocalFunction<LocalContext>>(localFunction(gf))
);
};
template< class GF, class HostGrid >
constexpr bool isGridFunction()
{ return models<Concept::GridFunction<HostGrid>, GF>(); }
} // end namespace Concept
} // end namespace Dune
#endif // DUNE_CURVED_SURFACE_GRID_CONCEPTS_HH
\ No newline at end of file
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_CRVSRF_COORDFUNCTIONIMPLEMENTATIONS_HH
#define DUNE_CRVSRF_COORDFUNCTIONIMPLEMENTATIONS_HH
#ifndef DUNE_CURVED_SURFACE_GRID_COORDFUNCTIONIMPLEMENTATIONS_HH
#define DUNE_CURVED_SURFACE_GRID_COORDFUNCTIONIMPLEMENTATIONS_HH
#include <dune/curvedsurfacegrid/surfacedistance/surfacedistance.hh>
#include <dune/curvedsurfacegrid/surfacedistance/vertexmap.hh>
#include <dune/curvedsurfacegrid/surfacedistance/vtureader.hh>
#include <dune/grid/geometrygrid/coordfunction.hh>
#include <cfloat>
#define COLLECTOR_BENCHMARK 0
......@@ -30,11 +29,11 @@ namespace Dune
//convertDuneGridToCrvsrfMesh
template<class GridPtr>
crvsrf::Mesh *convertDuneGridToCrvsrfMesh(GridPtr &grid){
Curved::Mesh *convertDuneGridToCrvsrfMesh(GridPtr &grid){
auto gridView = grid->leafGridView();
//determine coordinate-extrema
crvsrf::Vertex minc(DBL_MAX, DBL_MAX, DBL_MAX), maxc(-DBL_MAX, -DBL_MAX, -DBL_MAX);
Curved::Vertex minc(DBL_MAX, DBL_MAX, DBL_MAX), maxc(-DBL_MAX, -DBL_MAX, -DBL_MAX);
for(const auto &vertexEntity : vertices(gridView)){
const auto &vertex = vertexEntity.geometry().corner(0);
for(int i = 0; i < grid->dimensionworld; ++i){
......@@ -43,19 +42,19 @@ namespace Dune
}
}
crvsrf::Mesh *surface_mesh = new crvsrf::Mesh(grid->dimension, grid->dimensionworld);
crvsrf::VertexMap<int> vmap(minc, maxc, grid->dimensionworld);
Curved::Mesh *surface_mesh = new Curved::Mesh(grid->dimension, grid->dimensionworld);
Curved::VertexMap<int> vmap(minc, maxc, grid->dimensionworld);
//build mesh
int next_index = 0;
for(const auto &element : elements(gridView)){
if(element.geometry().corners() != 3){
crvsrf::error("Element is not a triangle in convertDuneGridToCrvsrfMesh.");
Curved::error("Element is not a triangle in convertDuneGridToCrvsrfMesh.");
}
int32_t el[grid->dimension + 1];
for(int i = 0; i <= grid->dimension; ++i){
auto coords = element.geometry().corner(i);
crvsrf::Vertex v(coords[0], coords[1], coords[2]);
Curved::Vertex v(coords[0], coords[1], coords[2]);
if(!vmap.find_3d(v, el[i])){
surface_mesh->add_vertex(v);
el[i] = next_index;
......@@ -93,7 +92,7 @@ namespace Dune
input *= radius_ / input.two_norm();
}
double run_time = dbl_time() - start_time;
std::cout << "csphere time: " << crvsrf::ft(run_time, 11, 9)
std::cout << "csphere time: " << Curved::ft(run_time, 11, 9)
<< ", count: " << inputs.size() << std::endl;
}
#endif
......@@ -135,7 +134,7 @@ namespace Dune
for(int i = 0; i < 3; ++i) input[i] = center_[i] + direction[i] * factor;
}
double run_time = dbl_time() - start_time;
std::cout << "sphere time: " << crvsrf::ft(run_time, 11, 9)
std::cout << "sphere time: " << Curved::ft(run_time, 11, 9)
<< ", count: " << inputs.size() << std::endl;
}
#endif
......@@ -162,29 +161,29 @@ namespace Dune
SurfaceDistanceCoordFunction(const GridPtr &gridPtr,
double expansion_width=-1.0, bool no_scaling=false) : cache(nullptr){
if(gridPtr->dimension != 2 || gridPtr->dimensionworld != 3){
crvsrf::error("SurfaceDistanceCoordFunction needs a triangle-surface-mesh!");
Curved::error("SurfaceDistanceCoordFunction needs a triangle-surface-mesh!");
}
surface_mesh = convertDuneGridToCrvsrfMesh(gridPtr);
backgrid = new crvsrf::BackGrid(*surface_mesh, expansion_width, no_scaling);
backgrid = new Curved::BackGrid(*surface_mesh, expansion_width, no_scaling);
if(cached){
crvsrf::Vertex c_begin, c_end;
Curved::Vertex c_begin, c_end;
surface_mesh->determine_coordinate_extrema(c_begin, c_end);
crvsrf::Vertex c_expansion = (c_end - c_begin) * 0.1;
cache = new crvsrf::VertexMap<crvsrf::Vertex>(c_begin - c_expansion, c_end + c_expansion, 3);
Curved::Vertex c_expansion = (c_end - c_begin) * 0.1;
cache = new Curved::VertexMap<Curved::Vertex>(c_begin - c_expansion, c_end + c_expansion, 3);
}
}
//constructor using vtu-reader to read "file"
SurfaceDistanceCoordFunction(const char *file,
double expansion_width=-1.0, bool no_scaling=false) : cache(nullptr){
surface_mesh = new crvsrf::Mesh(2, 3);
surface_mesh = new Curved::Mesh(2, 3);
read_vtu_file(file, *surface_mesh);
backgrid = new crvsrf::BackGrid(*surface_mesh, expansion_width, no_scaling);
backgrid = new Curved::BackGrid(*surface_mesh, expansion_width, no_scaling);
if(cached){
crvsrf::Vertex c_begin, c_end;
Curved::Vertex c_begin, c_end;
surface_mesh->determine_coordinate_extrema(c_begin, c_end);
crvsrf::Vertex c_expansion = (c_end - c_begin) * 0.1;
cache = new crvsrf::VertexMap<crvsrf::Vertex>(c_begin - c_expansion, c_end + c_expansion, 3);
Curved::Vertex c_expansion = (c_end - c_begin) * 0.1;
cache = new Curved::VertexMap<Curved::Vertex>(c_begin - c_expansion, c_end + c_expansion, 3);
}
}
......@@ -202,18 +201,18 @@ namespace Dune
}
//resetCache
void resetCache(crvsrf::Vertex begin = crvsrf::Vertex(),
crvsrf::Vertex end = crvsrf::Vertex(),
void resetCache(Curved::Vertex begin = Curved::Vertex(),
Curved::Vertex end = Curved::Vertex(),
double expansion_factor = 0.1){
if(cached){
delete cache;
if(begin.is_origin() && end.is_origin()){
surface_mesh->determine_coordinate_extrema(begin, end);
}
crvsrf::Vertex c_expansion = (end - begin) * expansion_factor;
cache = new crvsrf::VertexMap<crvsrf::Vertex>(begin - c_expansion, end + c_expansion, 3);
Curved::Vertex c_expansion = (end - begin) * expansion_factor;
cache = new Curved::VertexMap<Curved::Vertex>(begin - c_expansion, end + c_expansion, 3);
}else{
crvsrf::error("Cannot reset cache in uncached SurfaceDistanceCoordFunction!");
Curved::error("Cannot reset cache in uncached SurfaceDistanceCoordFunction!");
}
}
......@@ -227,13 +226,25 @@ namespace Dune
#if COLLECTOR_BENCHMARK != 0
void collectorBenchmark(bool fresh_cache){
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//! $debug: output vertex-list
/*std::ofstream out("vertex_list.txt", std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
int v_cnt = inputs.size();
out.write(reinterpret_cast<char*>(&v_cnt), 4);
for(auto &input : inputs){
out.write(reinterpret_cast<char*>(&input[0]), 8);
out.write(reinterpret_cast<char*>(&input[1]), 8);
out.write(reinterpret_cast<char*>(&input[2]), 8);
}
out.close();*/
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
if(cached){
if(fresh_cache) cache->clear();
int uncached_cnt = 0;
double start_time = dbl_time();
for(auto &input : inputs){
crvsrf::Vertex hit_vertex;
crvsrf::Vertex v(input[0], input[1], input[2]);
Curved::Vertex hit_vertex;
Curved::Vertex v(input[0], input[1], input[2]);
if(!cache->find_3d(v, hit_vertex)){
backgrid->distance_to_surface_3d(v, hit_vertex);
cache->insert(v, hit_vertex);
......@@ -241,17 +252,17 @@ namespace Dune
}
}
double run_time = dbl_time() - start_time;
std::cout << "surfdist time: " << crvsrf::ft(run_time, 11, 9) << ", count: "<< inputs.size()
std::cout << "surfdist time: " << Curved::ft(run_time, 11, 9) << ", count: "<< inputs.size()
<< ", uncached: " << uncached_cnt << std::endl;
}else{ //uncached
double start_time = dbl_time();
for(auto &input : inputs){
crvsrf::Vertex hit_vertex;
crvsrf::Vertex v(input[0], input[1], input[2]);
Curved::Vertex hit_vertex;
Curved::Vertex v(input[0], input[1], input[2]);
backgrid->distance_to_surface_3d(v, hit_vertex);
}
double run_time = dbl_time() - start_time;
std::cout << "surfdist time: " << crvsrf::ft(run_time, 11, 9)
std::cout << "surfdist time: " << Curved::ft(run_time, 11, 9)
<< ", count: "<< inputs.size() << std::endl;
}
}
......@@ -262,16 +273,16 @@ namespace Dune
if(cached){
cache->debug_output_statistics();
}else{
crvsrf::error("Cannot output vertexmap-statistics in "
Curved::error("Cannot output vertexmap-statistics in "
"uncached SurfaceDistanceCoordFunction!");
}
}
#endif
private:
crvsrf::Mesh *surface_mesh;
crvsrf::BackGrid *backgrid;
crvsrf::VertexMap<crvsrf::Vertex> *cache;
Curved::Mesh *surface_mesh;
Curved::BackGrid *backgrid;
Curved::VertexMap<Curved::Vertex> *cache;
#if COLLECTOR_BENCHMARK != 0
mutable std::vector<FieldVector<double, 3> > inputs;
#endif
......@@ -284,8 +295,8 @@ namespace Dune
#if COLLECTOR_BENCHMARK != 0
inputs.push_back(x);
#endif
crvsrf::Vertex hit_vertex;
crvsrf::Vertex v(x[0], x[1], x[2]);
Curved::Vertex hit_vertex;
Curved::Vertex v(x[0], x[1], x[2]);
if(!cache->find_3d(v, hit_vertex)){
backgrid->distance_to_surface_3d(v, hit_vertex);
cache->insert(v, hit_vertex);
......@@ -301,12 +312,12 @@ namespace Dune
#if COLLECTOR_BENCHMARK != 0
inputs.push_back(x);
#endif
crvsrf::Vertex hit_vertex;
crvsrf::Vertex v(x[0], x[1], x[2]);
Curved::Vertex hit_vertex;
Curved::Vertex v(x[0], x[1], x[2]);
backgrid->distance_to_surface_3d(v, hit_vertex);
return {hit_vertex[0], hit_vertex[1], hit_vertex[2]};
}
} // namespace Dune
#endif // #ifndef DUNE_CRVSRF_COORDFUNCTIONIMPLEMENTATIONS_HH
#endif // DUNE_CURVED_SURFACE_GRID_COORDFUNCTIONIMPLEMENTATIONS_HH
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_CRVSRF_COORDPROVIDER_HH
#define DUNE_CRVSRF_COORDPROVIDER_HH
#include <array>
namespace Dune
{
namespace crvsrf
{
template< class Coordinate>
Coordinate edgeCenter(Coordinate gc1, const Coordinate &gc2)
{
for(typename Coordinate::size_type i = 0, end = gc1.size(); i < end; ++i)
{
gc1[i] = (gc1[i] + gc2[i]) / 2.0;
}
return gc1;
}
template< class Coordinate>
Coordinate edgeVertex(Coordinate gc1, const Coordinate &gc2, double factor)
{
for(typename Coordinate::size_type i = 0, end = gc1.size(); i < end; ++i)
{
gc1[i] = gc1[i] + (gc2[i] - gc1[i]) * factor;
}
return gc1;
}
template< class Coordinate>
Coordinate faceVertex(Coordinate gc1, const Coordinate &gc2, const Coordinate &gc3,
double coeff1, double coeff2, double coeff3)
{
for(typename Coordinate::size_type i = 0, end = gc1.size(); i < end; ++i)
{
gc1[i] = coeff1 * gc1[i] + coeff2 * gc2[i] + coeff3 * gc3[i];
}
return gc1;
}
// InterpolatoryVerticesGenerator
// ------------------------------
template< class Coordinate, int mydim, int order >
struct InterpolatoryVerticesGenerator;
//Vertex
template< class Coordinate, int order >
struct InterpolatoryVerticesGenerator< Coordinate, 0, order >
{
static void generate(const std::array<Coordinate, 1> &corners, std::vector<Coordinate> &vertices)
{
vertices.resize(1);
vertices[0] = corners[0];
}
};
//Edge
template< class Coordinate, int order >
struct InterpolatoryVerticesGenerator< Coordinate, 1, order >
{
static void generate(const std::array<Coordinate, 2> &corners, std::vector<Coordinate> &vertices)
{
vertices.resize(order + 1);
vertices[0] = corners[0];
for(int i = 1; i < order; ++i)
{
vertices[i] = edgeVertex(corners[0], corners[1], (double)i / order);
}
vertices[order] = corners[1];
}
};
//Triangle (order 1)
template< class Coordinate >
struct InterpolatoryVerticesGenerator< Coordinate, 2, 1 >
{
static void generate(const std::array<Coordinate, 4> &corners, std::vector<Coordinate> &vertices)
{
vertices.resize(3);
vertices[0] = corners[0];
vertices[1] = corners[1];
vertices[2] = corners[2];
}
};
//Triangle (order 2)
template< class Coordinate >
struct InterpolatoryVerticesGenerator< Coordinate, 2, 2 >
{
static void generate(const std::array<Coordinate, 4> &corners, std::vector<Coordinate> &vertices)
{
vertices.resize(6);
vertices[0] = corners[0];
vertices[1] = edgeCenter(corners[0], corners[1]);
vertices[2] = corners[1];
vertices[3] = edgeCenter(corners[0], corners[2]);
vertices[4] = edgeCenter(corners[1], corners[2]);
vertices[5] = corners[2];
}
};
//Triangle (order 3)
template< class Coordinate >
struct InterpolatoryVerticesGenerator< Coordinate, 2, 3 >
{
static void generate(const std::array<Coordinate, 4> &corners, std::vector<Coordinate> &vertices)
{
static const double cf1 = 1.0 / 3.0;
static const double cf2 = 2.0 / 3.0;
vertices.resize(10);
vertices[0] = corners[0];
vertices[1] = edgeVertex(corners[0], corners[1], cf1);
vertices[2] = edgeVertex(corners[0], corners[1], cf2);
vertices[3] = corners[1];
vertices[4] = edgeVertex(corners[0], corners[2], cf1);
vertices[5] = faceVertex(corners[0], corners[1], corners[2], cf1, cf1, cf1);
vertices[6] = edgeVertex(corners[1], corners[2], cf1);
vertices[7] = edgeVertex(corners[0], corners[2], cf2);
vertices[8] = edgeVertex(corners[1], corners[2], cf2);
vertices[9] = corners[2];
}
};
//Triangle (order 4)
template< class Coordinate >
struct InterpolatoryVerticesGenerator< Coordinate, 2, 4 >
{
static void generate(const std::array<Coordinate, 4> &corners, std::vector<Coordinate> &vertices)
{
static const double cf1 = 1.0 / 4.0;
static const double cf2 = 2.0 / 4.0;
static const double cf3 = 3.0 / 4.0;
vertices.resize(15);
vertices[0] = corners[0];
vertices[1] = edgeVertex(corners[0], corners[1], cf1);
vertices[2] = edgeCenter(corners[0], corners[1]);
vertices[3] = edgeVertex(corners[0], corners[1], cf3);
vertices[4] = corners[1];
vertices[5] = edgeVertex(corners[0], corners[2], cf1);
vertices[6] = faceVertex(corners[0], corners[1], corners[2], cf2, cf1, cf1);
vertices[7] = faceVertex(corners[0], corners[1], corners[2], cf1, cf2, cf1);
vertices[8] = edgeVertex(corners[1], corners[2], cf1);
vertices[9] = edgeCenter(corners[0], corners[2]);
vertices[10] = faceVertex(corners[0], corners[1], corners[2], cf1, cf1, cf2);
vertices[11] = edgeCenter(corners[1], corners[2]);
vertices[12] = edgeVertex(corners[0], corners[2], cf3);
vertices[13] = edgeVertex(corners[1], corners[2], cf3);
vertices[14] = corners[2];
}
};
//Triangle (order 5)
template< class Coordinate >
struct InterpolatoryVerticesGenerator< Coordinate, 2, 5 >
{
static void generate(const std::array<Coordinate, 4> &corners, std::vector<Coordinate> &vertices)
{
static const double cf1 = 1.0 / 5.0;
static const double cf2 = 2.0 / 5.0;
static const double cf3 = 3.0 / 5.0;
static const double cf4 = 4.0 / 5.0;
vertices.resize(21);
vertices[0] = corners[0];
vertices[1] = edgeVertex(corners[0], corners[1], cf1);
vertices[2] = edgeVertex(corners[0], corners[1], cf2);
vertices[3] = edgeVertex(corners[0], corners[1], cf3);
vertices[4] = edgeVertex(corners[0], corners[1], cf4);
vertices[5] = corners[1];
vertices[6] = edgeVertex(corners[0], corners[2], cf1);
vertices[7] = faceVertex(corners[0], corners[1], corners[2], cf3, cf1, cf1);
vertices[8] = faceVertex(corners[0], corners[1], corners[2], cf2, cf2, cf1);
vertices[9] = faceVertex(corners[0], corners[1], corners[2], cf1, cf3, cf1);
vertices[10] = edgeVertex(corners[1], corners[2], cf1);
vertices[11] = edgeVertex(corners[0], corners[2], cf2);
vertices[12] = faceVertex(corners[0], corners[1], corners[2], cf2, cf1, cf2);
vertices[13] = faceVertex(corners[0], corners[1], corners[2], cf1, cf2, cf2);
vertices[14] = edgeVertex(corners[1], corners[2], cf2);
vertices[15] = edgeVertex(corners[0], corners[2], cf3);
vertices[16] = faceVertex(corners[0], corners[1], corners[2], cf1, cf1, cf3);
vertices[17] = edgeVertex(corners[1], corners[2], cf3);
vertices[18] = edgeVertex(corners[0], corners[2], cf4);
vertices[19] = edgeVertex(corners[1], corners[2], cf4);
vertices[20] = corners[2];
}
};
// CoordProvider (adapted CoordVector from GeometryGrid)
// -----------------------------------------------------
template< int mydim, class Grid, bool fake >
class CoordProvider;
//CoordProvider (real)
template< int mydim, class Grid >
class CoordProvider< mydim, Grid, false >
{
typedef typename std::remove_const< Grid >::type::Traits Traits;
typedef typename Traits::ctype ctype;
static const int dimension = Traits::dimension;
static const int mydimension = mydim;
static const int codimension = dimension - mydimension;
static const int dimensionworld = Traits::dimensionworld;
typedef FieldVector< ctype, dimensionworld > Coordinate;
typedef typename Traits::HostGrid HostGrid;
typedef typename Traits::CoordFunction CoordFunction;
typedef typename HostGrid::template Codim< codimension >::Entity HostEntity;
public:
CoordProvider ( const HostEntity &hostEntity,
const CoordFunction &coordFunction )
: coordFunction_(coordFunction),
hostEntity_(hostEntity)
{}
void calculate ( std::vector< Coordinate > &vertices ) const
{
const std::size_t numCorners = hostEntity_.geometry().corners();
std::array<Coordinate, (1 << mydim)> corners;
for( std::size_t i = 0; i < numCorners; ++i )
corners[i] = hostEntity_.geometry().corner(i);
InterpolatoryVerticesGenerator<Coordinate, mydim, Grid::order>::generate(corners, vertices);
for(auto &v : vertices) coordFunction_.evaluate(v, v);
}
private:
const CoordFunction &coordFunction_;
const HostEntity &hostEntity_;
};
//CoordProvider (fake)
template< int mydim, class Grid >
class CoordProvider< mydim, Grid, true >
{
typedef typename std::remove_const< Grid > :: type :: Traits Traits;
typedef typename Traits::ctype ctype;
static const int dimension = Traits::dimension;
static const int mydimension = mydim;
static const int codimension = dimension - mydimension;
static const int dimensionworld = Traits::dimensionworld;
typedef FieldVector< ctype, dimensionworld > Coordinate;
typedef typename Traits::HostGrid HostGrid;
typedef typename Traits::CoordFunction CoordFunction;
typedef typename HostGrid::template Codim< 0 >::Entity HostElement;
public:
CoordProvider ( const HostElement &hostElement,
const unsigned int subEntity,
const CoordFunction &coordFunction )
: coordFunction_(coordFunction),
hostElement_(hostElement),
subEntity_( subEntity )
{}
void calculate ( std::vector< Coordinate > &vertices ) const
{
const GeometryType type = hostElement_.geometry().type();
auto refElement = referenceElement< ctype, dimension >( type );
const std::size_t numCorners = refElement.size( subEntity_, codimension, dimension );
std::array<Coordinate, (1 << mydim)> corners;
for( std::size_t i = 0; i < numCorners; ++i )
{
const std::size_t j = refElement.subEntity( subEntity_, codimension, i, dimension );
corners[i] = hostElement_.geometry().corner(j);
}
InterpolatoryVerticesGenerator<Coordinate, mydim, Grid::order>::generate(corners, vertices);
for(auto &v : vertices) coordFunction_.evaluate(v, v);
}
private:
const CoordFunction &coordFunction_;
const HostElement &hostElement_;
const unsigned int subEntity_;
};
// IntersectionCoordProvider
// -----------------------
template< class Grid >
class IntersectionCoordProvider
{
typedef typename std::remove_const< Grid >::type::Traits Traits;
typedef typename Traits::ctype ctype;
static const int dimension = Traits::dimension;
static const int codimension = 1;
static const int mydimension = dimension-codimension;
static const int dimensionworld = Traits::dimensionworld;
typedef FieldVector< ctype, dimensionworld > Coordinate;
typedef typename Traits::HostGrid HostGrid;
typedef typename Traits::CoordFunction CoordFunction;
typedef typename Traits::template Codim< 0 >::GeometryImpl ElementGeometryImpl;
typedef typename Traits::template Codim< codimension >::LocalGeometry HostLocalGeometry;
public:
IntersectionCoordProvider ( const ElementGeometryImpl &elementGeometry,
const HostLocalGeometry &hostLocalGeometry,
const CoordFunction &coordFunction )
: coordFunction_(coordFunction),
elementGeometry_( elementGeometry ),
hostLocalGeometry_( hostLocalGeometry )
{}
void calculate ( std::vector< Coordinate > &vertices ) const
{
const std::size_t numCorners = hostLocalGeometry_.corners();
std::array<Coordinate, (1 << mydimension)> corners;
// $flo: coordFunction is applied here which is in contrast to GeomentryGrid's behaviour!
for( std::size_t i = 0; i < numCorners; ++i )
corners[ i ] = elementGeometry_.global( hostLocalGeometry_.corner( i ) );
InterpolatoryVerticesGenerator<Coordinate, mydimension, Grid::order>::generate(corners, vertices);
for(auto &v : vertices) coordFunction_.evaluate(v, v);
}
template< unsigned int numCorners >
void calculate ( Coordinate (&corners)[ numCorners ] ) const
{
assert( numCorners == hostLocalGeometry_.corners() );
}
private:
const CoordFunction &coordFunction_;
const ElementGeometryImpl &elementGeometry_;
HostLocalGeometry hostLocalGeometry_;
};
} // namespace crvsrf
} // namespace Dune
#endif // #ifndef DUNE_CRVSRF_COORDPROVIDER_HH
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_CRVSRF_DATAHANDLE_HH
#define DUNE_CRVSRF_DATAHANDLE_HH
#ifndef DUNE_CURVED_SURFACE_GRID_DATAHANDLE_HH
#define DUNE_CURVED_SURFACE_GRID_DATAHANDLE_HH
#include <dune/common/typetraits.hh>
......@@ -11,8 +11,7 @@
namespace Dune
{
namespace crvsrf
namespace Curved
{
// CommDataHandle
......@@ -20,69 +19,69 @@ namespace Dune
template< class Grid, class WrappedHandle >
class CommDataHandle
: public CommDataHandleIF< CommDataHandle< Grid, WrappedHandle >, typename WrappedHandle::DataType >
: public CommDataHandleIF<CommDataHandle<Grid, WrappedHandle>, typename WrappedHandle::DataType>
{
typedef typename std::remove_const< Grid >::type::Traits Traits;
using Traits = typename std::remove_const_t<Grid>::Traits;
public:
CommDataHandle ( const Grid &grid, WrappedHandle &handle )
: grid_( grid ),
wrappedHandle_( handle )
CommDataHandle (const Grid& grid, WrappedHandle& handle)
: grid_(grid)
, wrappedHandle_(handle)
{}
bool contains ( int dim, int codim ) const
bool contains (int dim, int codim) const
{
const bool contains = wrappedHandle_.contains( dim, codim );
if( contains )
assertHostEntity( dim, codim );
const bool contains = wrappedHandle_.contains(dim, codim);
if (contains)
assertHostEntity(dim, codim);
return contains;
}
bool fixedSize ( int dim, int codim ) const
bool fixedSize (int dim, int codim) const
{
return wrappedHandle_.fixedSize( dim, codim );
return wrappedHandle_.fixedSize(dim, codim);
}
template< class HostEntity >
size_t size ( const HostEntity &hostEntity ) const
std::size_t size (const HostEntity& hostEntity) const
{
typedef typename Grid::Traits::template Codim< HostEntity::codimension >::Entity Entity;
typedef typename Grid::Traits::template Codim< HostEntity::codimension >::EntityImpl EntityImpl;
Entity entity( EntityImpl( grid_, hostEntity ) );
return wrappedHandle_.size( entity );
using Entity = typename Grid::Traits::template Codim<HostEntity::codimension>::Entity;
using EntityImpl = typename Grid::Traits::template Codim<HostEntity::codimension>::EntityImpl;
Entity entity(EntityImpl(grid_.gridFunction(), hostEntity));
return wrappedHandle_.size(entity);
}
template< class MessageBuffer, class HostEntity >
void gather ( MessageBuffer &buffer, const HostEntity &hostEntity ) const
void gather (MessageBuffer& buffer, const HostEntity& hostEntity) const
{
typedef typename Grid::Traits::template Codim< HostEntity::codimension >::Entity Entity;
typedef typename Grid::Traits::template Codim< HostEntity::codimension >::EntityImpl EntityImpl;
Entity entity( EntityImpl( grid_, hostEntity ) );
wrappedHandle_.gather( buffer, entity );
using Entity = typename Grid::Traits::template Codim<HostEntity::codimension>::Entity;
using EntityImpl = typename Grid::Traits::template Codim<HostEntity::codimension>::EntityImpl;
Entity entity(EntityImpl(grid_.gridFunction(), hostEntity));
wrappedHandle_.gather(buffer, entity);
}
template< class MessageBuffer, class HostEntity >
void scatter ( MessageBuffer &buffer, const HostEntity &hostEntity, size_t size )
void scatter (MessageBuffer& buffer, const HostEntity& hostEntity, std::size_t size)
{
typedef typename Grid::Traits::template Codim< HostEntity::codimension >::Entity Entity;
typedef typename Grid::Traits::template Codim< HostEntity::codimension >::EntityImpl EntityImpl;
Entity entity( EntityImpl( grid_, hostEntity ) );
wrappedHandle_.scatter( buffer, entity, size );
using Entity = typename Grid::Traits::template Codim< HostEntity::codimension >::Entity;
using EntityImpl = typename Grid::Traits::template Codim< HostEntity::codimension >::EntityImpl;
Entity entity(EntityImpl(grid_.gridFunction(), hostEntity));
wrappedHandle_.scatter(buffer, entity, size);
}
private:
static void assertHostEntity ( int dim, int codim )
static void assertHostEntity (int dim, int codim)
{
if( !Capabilities::CodimCache< Grid >::hasHostEntity( codim ) )
DUNE_THROW( NotImplemented, "Host grid has no entities for codimension " << codim << "." );
if (!Capabilities::CodimCache<Grid>::hasHostEntity(codim))
DUNE_THROW(NotImplemented, "Host grid has no entities for codimension " << codim << ".");
}
const Grid &grid_;
WrappedHandle &wrappedHandle_;
private:
const Grid& grid_;
WrappedHandle& wrappedHandle_;
};
} // namespace crvsrf
} // namespace Curved
} // namespace Dune
#endif // #ifndef DUNE_CRVSRF_DATAHANDLE_HH
#endif // DUNE_CURVED_SURFACE_GRID_DATAHANDLE_HH
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_CRVSRF_DECLARATION_HH
#define DUNE_CRVSRF_DECLARATION_HH
#ifndef DUNE_CURVED_SURFACE_GRID_DECLARATION_HH
#define DUNE_CURVED_SURFACE_GRID_DECLARATION_HH
namespace Dune
{
template< class HostGrid, class CoordFunction, int interpolatoryOrder, bool geoCaching, class Allocator >
template< class GridFunction, int order >
class CurvedSurfaceGrid;
} // namespace Dune
#endif // #ifndef DUNE_CRVSRF_DECLARATION_HH
#endif // DUNE_CURVED_SURFACE_GRID_DECLARATION_HH
This diff is collapsed.
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_CRVSRF_ENTITYSEED_HH
#define DUNE_CRVSRF_ENTITYSEED_HH
#ifndef DUNE_CURVED_SURFACE_GRID_ENTITYSEED_HH
#define DUNE_CURVED_SURFACE_GRID_ENTITYSEED_HH
#include <dune/common/typetraits.hh>
......@@ -10,109 +10,47 @@
namespace Dune
{
namespace crvsrf
namespace Curved
{
// Internal Forward Declarations
// -----------------------------
template< int codim, class Grid, bool fake = !(Capabilities::hasHostEntity< Grid, codim >::v) >
class EntitySeed;
// EntitySeed
// ----------
// EntitySeed (real)
// -----------------
template< int codim, class Grd >
class EntitySeed< codim, Grd, false >
template< int codim, class G >
class EntitySeed
{
typedef typename std::remove_const< Grd >::type::Traits Traits;
using Traits = typename std::remove_const_t<G>::Traits;
using HostGrid = typename Traits::HostGrid;
using HostEntitySeed = typename HostGrid::template Codim<codim>::EntitySeed;
public:
static const int codimension = codim;
static const int dimension = Traits::dimension;
static const int mydimension = dimension - codimension;
static const int dimensionworld = Traits::dimensionworld;
static const bool fake = false;
typedef typename Traits::Grid Grid;
typedef typename Traits::template Codim< codim >::Entity Entity;
typedef typename Traits::HostGrid HostGrid;
typedef typename HostGrid::template Codim< codim >::EntitySeed HostEntitySeed;
//! default construct an invalid entity seed
EntitySeed ( )
{}
EntitySeed () = default;
explicit EntitySeed ( const HostEntitySeed &hostEntitySeed )
: hostEntitySeed_( hostEntitySeed )
//! construct the entity-seed from a host-entity seed
explicit EntitySeed (const HostEntitySeed& hostEntitySeed)
: hostEntitySeed_(hostEntitySeed)
{}
//! check whether the EntitySeed refers to a valid Entity
bool isValid() const
bool isValid () const
{
return hostEntitySeed_.isValid();
}
const HostEntitySeed &hostEntitySeed () const { return hostEntitySeed_; }
private:
HostEntitySeed hostEntitySeed_;
};
// EntitySeed (fake)
// -----------------
template< int codim, class Grd >
class EntitySeed< codim, Grd, true >
{
typedef typename std::remove_const< Grd >::type::Traits Traits;
public:
static const int codimension = codim;
static const int dimension = Traits::dimension;
static const int mydimension = dimension - codimension;
static const int dimensionworld = Traits::dimensionworld;
static const bool fake = true;
typedef typename Traits::Grid Grid;
typedef typename Traits::template Codim< codim >::Entity Entity;
typedef typename Traits::HostGrid HostGrid;
typedef typename HostGrid::template Codim< 0 >::EntitySeed HostElementSeed;
//! default construct an invalid entity seed
EntitySeed ( )
{}
explicit EntitySeed ( const HostElementSeed &hostElementSeed, unsigned int subEntity )
: hostElementSeed_( hostElementSeed ),
subEntity_( subEntity )
{}
//! check whether the EntitySeed refers to a valid Entity
bool isValid() const
//! return the entity seed of the host-entity
const HostEntitySeed& hostEntitySeed () const
{
return hostElementSeed_.isValid();
return hostEntitySeed_;
}
const HostElementSeed &hostElementSeed () const { return hostElementSeed_; }
unsigned int subEntity () const { return subEntity_; }
private:
HostElementSeed hostElementSeed_;
unsigned int subEntity_;
HostEntitySeed hostEntitySeed_ = {};
};
} // namespace crvsrf
} // namespace Curved
} // namespace Dune
#endif // #ifndef DUNE_CRVSRF_ENTITYSEED_HH
#endif // DUNE_CURVED_SURFACE_GRID_ENTITYSEED_HH
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_CRVSRF_GEOMETRY_HH
#define DUNE_CRVSRF_GEOMETRY_HH
#include <utility>
#ifndef DUNE_CURVED_SURFACE_GRID_GEOMETRY_HH
#define DUNE_CURVED_SURFACE_GRID_GEOMETRY_HH
#include <cassert>
#include <functional>
#include <iterator>
#include <limits>
#include <vector>
#include <dune/common/diagonalmatrix.hh>
#include <dune/common/fmatrix.hh>
#include <dune/common/fvector.hh>
#include <dune/common/typetraits.hh>
#include <dune/common/std/optional.hh>
#include <dune/common/std/type_traits.hh>
#include <dune/curvilineargeometry/curvilineargeometry.hh>
#include <dune/curvedgeometry/curvedgeometry.hh>
#include <dune/curvedgeometry/localfunctiongeometry.hh>
#include <dune/geometry/affinegeometry.hh>
#include <dune/geometry/multilineargeometry.hh>
#include <dune/geometry/quadraturerules.hh>
#include <dune/geometry/referenceelements.hh>
#include <dune/geometry/type.hh>
#include <dune/grid/common/capabilities.hh>
#include <dune/curvedsurfacegrid/coordprovider.hh>
#include "localgeometrywrapper.hh"
namespace Dune
{
namespace crvsrf
namespace Curved
{
// InferHasSingleGeometryType
// --------------------------
template< class hasSingleGeometryType, int dim, int mydim >
struct InferHasSingleGeometryType
/// \brief Curved geometry implementation based on local basis function parametrization
/**
* Parametrization of the geometry by a differentiable localFunction
*
* \tparam LF localFunction parametrizing the geometry
* \tparam LG localGeometry for coordinate transform from subEntity to element,
* see \ref Impl::DefaultLocalGeometry and \ref Impl::LocalGeometryInterface
* \tparam ORDER Polynomial order of lagrange parametrization. If order < 0 use localFunction.
*/
template <class ct, int mydim, int cdim, class LF, class LG, int ORDER = -1>
class Geometry
: public LagrangeCurvedGeometry<ct, mydim, cdim, (ORDER > 0 ? ORDER : 1)>
{
private:
static const unsigned int id = hasSingleGeometryType::topologyId;
static const unsigned int idMask = (1u << mydim) - 1u;
using Super = LagrangeCurvedGeometry<ct, mydim, cdim, (ORDER > 0 ? ORDER : 1)>;
public:
static const bool v = hasSingleGeometryType::v && ((mydim == dim) || ((id | 1u) == 1u) || ((id | 1u) == idMask));
static const unsigned int topologyId = (v ? id & idMask : ~0u);
};
//! type of the localFunction representation the geometry parametrization
using LocalFunction = LF;
template< class hasSingleGeometryType, int dim >
struct InferHasSingleGeometryType< hasSingleGeometryType, dim, 1 >
{
static const bool v = true;
static const unsigned int topologyId = Impl::CubeTopology< 1 >::type::id;
};
//! type of coordinate transformation for subEntities to codim=0 entities
using LocalGeometry = LG;
template< class hasSingleGeometryType, int dim >
struct InferHasSingleGeometryType< hasSingleGeometryType, dim, 0 >
{
static const bool v = true;
static const unsigned int topologyId = Impl::CubeTopology< 0 >::type::id;
/// type of reference element
using ReferenceElements = Dune::ReferenceElements<ct, mydim>;
using ReferenceElement = typename ReferenceElements::ReferenceElement;
public:
/// \brief constructor from localFunction to parametrize the geometry
/**
* \param[in] refElement reference element for the geometry
* \param[in] localFunction localFunction for the parametrization of the geometry
* (stored by value)
* \param[in] args... argument to construct the local geometry
*
*/
template <class... Args>
Geometry (const ReferenceElement& refElement, const LocalFunction& localFunction, Args&&... args)
: Super(refElement, [localFunction, localGeometry=LocalGeometry{std::forward<Args>(args)...}](auto const& local)
{
return localFunction(localGeometry.global(local));
})
{}
/// \brief constructor, forwarding to the other constructor that take a reference-element
/**
* \param[in] gt geometry type
* \param[in] localFunction localFunction for the parametrization of the geometry
* (stored by value)
* \param[in] args... argument to construct the local geometry
*/
template <class... Args>
Geometry (Dune::GeometryType gt, const LocalFunction& localFunction, Args&&... args)
: Geometry(ReferenceElements::general(gt), localFunction, std::forward<Args>(args)...)
{}
};
// GeometryTraits
// --------------
template< class Grid >
struct GeometryTraits
// Specialization for the case that ORDER < 0: Use LocalFunction `LF` directly as parametrization
template <class ct, int mydim, int cdim, class LF, class LG>
class Geometry<ct,mydim,cdim,LF,LG,-1>
: public LocalFunctionGeometry<LF,LG>
{
typedef typename std::remove_const< Grid >::type::Traits Traits;
using Super = LocalFunctionGeometry<LF,LG>;
typedef typename Traits::ctype ctype;
//! type of the localFunction representation the geometry parametrization
using LocalFunction = LF;
typedef Impl::FieldMatrixHelper< ctype > MatrixHelper;
//! type of coordinate transformation for subEntities to codim=0 entities
using LocalGeometry = LG;
static ctype tolerance () { return 16 * std::numeric_limits< ctype >::epsilon(); }
/// type of reference element
using ReferenceElements = Dune::ReferenceElements<ct, mydim>;
using ReferenceElement = typename ReferenceElements::ReferenceElement;
template< int mydim >
struct hasSingleGeometryType
: public InferHasSingleGeometryType< Capabilities::hasSingleGeometryType< Grid >, Traits::dimension, mydim >
{};
public:
/// \brief constructor from localFunction to parametrize the geometry
/**
* \param[in] refElement reference element for the geometry
* \param[in] localFunction localFunction for the parametrization of the geometry
* (stored by value)
* \param[in] args... argument to construct the local geometry
*
*/
template <class... Args>
Geometry (const ReferenceElement& refElement, const LocalFunction& localFunction, Args&&... args)
: Super(refElement, localFunction, LocalGeometry{std::forward<Args>(args)...})
{}
/// \brief constructor, forwarding to the other constructor that take a reference-element
/**
* \param[in] gt geometry type
* \param[in] localFunction localFunction for the parametrization of the geometry
* (stored by value)
* \param[in] args... argument to construct the local geometry
*/
template <class... Args>
Geometry (Dune::GeometryType gt, const LocalFunction& localFunction, Args&&... args)
: Super(gt, localFunction, LocalGeometry{std::forward<Args>(args)...})
{}
};
#ifndef DOXYGEN
// Geometry
// --------
template< int mydim, int cdim, class Grid >
class Geometry
// Specialization for vertex geometries
template <class ct, int cdim, class LF, class LG>
class VertexGeometry
: public AffineGeometry<ct,0,cdim>
{
typedef Geometry< mydim, cdim, Grid > This;
typedef typename std::remove_const< Grid >::type::Traits Traits;
template< int, int, class > friend class Geometry;
public:
typedef typename Traits::ctype ctype;
using Super = AffineGeometry<ct,0,cdim>;
static const int mydimension = mydim;
static const int coorddimension = cdim;
static const int dimension = Traits::dimension;
static const int codimension = dimension - mydimension;
using LocalFunction = LF;
using LocalGeometry = LG;
protected:
typedef CachedCurvilinearGeometry<ctype, mydimension, coorddimension> BasicMapping;
struct Mapping
: public BasicMapping
{
typedef typename BasicMapping::GlobalCoordinate GlobalCoordinate;
template< class CoordVector >
Mapping ( const GeometryType &type, const CoordVector &coords )
: BasicMapping( type, coords, Grid::order ),
refCount_( 0 )
{}
//! tolerance to numerical algorithms
static ct tolerance () { return ct(16) * std::numeric_limits<ct>::epsilon(); }
void addReference () { ++refCount_; }
bool removeReference () { return (--refCount_ == 0); }
private:
unsigned int refCount_;
};
struct Construct {};
public:
typedef typename Mapping::LocalCoordinate LocalCoordinate;
typedef typename Mapping::GlobalCoordinate GlobalCoordinate;
typedef typename Mapping::JacobianTransposed JacobianTransposed;
typedef typename Mapping::JacobianInverseTransposed JacobianInverseTransposed;
Geometry () : grid_( nullptr ), mapping_( nullptr ) {}
/// type of reference element
using ReferenceElements = Dune::ReferenceElements<ct, 0>;
using ReferenceElement = typename ReferenceElements::ReferenceElement;
explicit Geometry ( const Grid &grid ) : grid_( &grid ), mapping_( nullptr ) {}
/// type of local coordinates
using LocalCoordinate = FieldVector<ct, 0>;
template< class CoordVector >
Geometry ( const Grid &grid, const GeometryType &type, const CoordVector &coords )
: grid_( &grid )
{
assert( int( type.dim() ) == mydimension );
std::vector<GlobalCoordinate> vertices;
coords.calculate( vertices );
void *mappingStorage = grid.allocateStorage( sizeof( Mapping ) );
mapping_ = new( mappingStorage ) Mapping( type, vertices );
mapping_->addReference();
}
Geometry ( const This &other )
: grid_( other.grid_ ),
mapping_( other.mapping_ )
{
if( mapping_ )
mapping_->addReference();
}
/// type of global coordinates
using GlobalCoordinate = FieldVector<ct, cdim>;
Geometry ( This&& other )
: grid_( other.grid_ ),
mapping_( other.mapping_ )
{
other.grid_ = nullptr;
other.mapping_ = nullptr;
}
protected:
VertexGeometry (Construct, const ReferenceElement& refElement, const LocalFunction& localFunction,
const LocalGeometry& lg)
: Super(refElement, std::vector<GlobalCoordinate>{localFunction(lg.global(refElement.position(0,0)))})
{}
~Geometry ()
public:
template <class... Args>
VertexGeometry (const ReferenceElement& refElement, const LocalFunction& lf, Args&&... args)
: VertexGeometry(Construct{}, refElement, lf, LocalGeometry(std::forward<Args>(args)...))
{}
template <class... Args>
VertexGeometry (Dune::GeometryType gt, const LocalFunction& lf, Args&&... args)
: VertexGeometry(Construct{}, ReferenceElements::general(gt), lf,
LocalGeometry(std::forward<Args>(args)...))
{}
Std::optional<LocalCoordinate> checkedLocal (const GlobalCoordinate& globalCoord) const
{
if( mapping_ && mapping_->removeReference() )
destroyMapping();
}
auto localCoord = Super::local(globalCoord);
if ((globalCoord - Super::global(localCoord)).two_norm2() > tolerance())
return {};
const This &operator= ( const This &other )
{
if( other.mapping_ )
other.mapping_->addReference();
if( mapping_ && mapping_->removeReference() )
destroyMapping();
grid_ = other.grid_;
mapping_ = other.mapping_;
return *this;
return localCoord;
}
const This &operator= ( This&& other )
GlobalCoordinate normal (const LocalCoordinate& local) const
{
using std::swap;
swap( grid_, other.grid_ );
swap( mapping_, other.mapping_ );
return *this;
DUNE_THROW(Dune::NotImplemented,
"ERROR: normal() method only defined for edges in 2D and faces in 3D");
return GlobalCoordinate(0);
}
explicit operator bool () const { return bool( mapping_ ); }
bool affine () const { return mapping_->affine(); }
GeometryType type () const { return mapping_->type(); }
std::vector<GlobalCoordinate> interpolatoryVertices() const { return mapping_->vertexSet(); }
int corners () const { return mapping_->nCorner(); }
GlobalCoordinate corner ( const int i ) const { return mapping_->corner( i ); }
GlobalCoordinate center () const { return mapping_->center(); }
GlobalCoordinate global ( const LocalCoordinate &local ) const { return mapping_->global( local ); }
LocalCoordinate local ( const GlobalCoordinate &global ) const
{
LocalCoordinate l;
DUNE_UNUSED bool b = mapping_->local( global, l );
assert(b);
return l;
}
GlobalCoordinate normal ( const LocalCoordinate &local ) const { return mapping_->normal( local ); }
ctype integrationElement ( const LocalCoordinate &local ) const { return mapping_->integrationElement( local ); }
ctype volume () const { return mapping_->volume(std::numeric_limits<ctype>::epsilon()); }
JacobianTransposed jacobianTransposed ( const LocalCoordinate &local ) const { return mapping_->jacobianTransposed( local ); }
JacobianInverseTransposed jacobianInverseTransposed ( const LocalCoordinate &local ) const { return mapping_->jacobianInverseTransposed( local ); }
private:
VertexGeometry const& flatGeometry () const { return *this; }
};
const Grid &grid () const { assert( grid_ ); return *grid_; }
private:
void destroyMapping ()
{
mapping_->~Mapping();
grid().deallocateStorage( mapping_, sizeof( Mapping ) );
}
// Specialization for vertex geometries
template <class ct, int cdim, class LF, class LG, int order>
class Geometry<ct,0,cdim,LF,LG,order>
: public VertexGeometry<ct,cdim,LF,LG>
{
using Super = VertexGeometry<ct,cdim,LF,LG>;
public:
using Super::Super;
};
const Grid *grid_;
Mapping* mapping_;
template <class ct, int cdim, class LF, class LG>
class Geometry<ct,0,cdim,LF,LG,-1>
: public VertexGeometry<ct,cdim,LF,LG>
{
using Super = VertexGeometry<ct,cdim,LF,LG>;
public:
using Super::Super;
};
} // namespace crvsrf
#endif // DOXYGEN
} // end namespace Curved
} // namespace Dune
#endif // #ifndef DUNE_CRVSRF_GEOMETRY_HH
#endif // DUNE_CURVED_SURFACE_GRID_GEOMETRY_HH
This diff is collapsed.
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_CRVSRF_GRIDFAMILY_HH
#define DUNE_CRVSRF_GRIDFAMILY_HH
#ifndef DUNE_CURVED_SURFACE_GRID_GRIDFAMILY_HH
#define DUNE_CURVED_SURFACE_GRID_GRIDFAMILY_HH
#include <type_traits>
#include <dune/grid/common/grid.hh>
#include <dune/curvedsurfacegrid/capabilities.hh>
......@@ -14,106 +16,134 @@
#include <dune/curvedsurfacegrid/iterator.hh>
#include <dune/curvedsurfacegrid/idset.hh>
#include <dune/curvedsurfacegrid/indexsets.hh>
#include <dune/curvedsurfacegrid/localgeometrywrapper.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
{
/** \brief namespace containing the implementations of CurvedSurfaceGrid
* \ingroup crvsrf
* \ingroup CurvedGeo
*/
namespace crvsrf
namespace Curved
{
// ExportParams
// ------------
template< class HG, class CF >
class ExportParams
template< class GF >
struct DimRange
{
static const bool isCoordFunction = GeoGrid::isCoordFunctionInterface< typename CF::Interface >::value;
static_assert(isCoordFunction, "Invalid CoordFunction.");
public:
typedef HG HostGrid;
typedef CF CoordFunction;
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 LocalContext = typename EntitySet::Element;
using Range = typename Functions::SignatureTraits<GF>::Range;
using LocalSignature = Range(typename EntitySet::LocalCoordinate);
static const bool value = Functions::Concept::isDifferentiableLocalFunction<LF,LocalSignature,LocalContext,Functions::LocalDerivativeTraits<EntitySet>::template Traits>();
};
// GridFamily
// ----------
template< class HG, class CF, int order, bool geoCaching, class Allocator >
template< class GF, int order >
struct GridFamily
{
struct Traits
{
typedef CurvedSurfaceGrid< HG, CF, order, geoCaching, Allocator > Grid;
using Grid = CurvedSurfaceGrid<GF,order>;
using HostGrid = GridOf_t<GF>;
using GridFunction = GF;
using LocalFunction = std::decay_t<decltype(localFunction(std::declval<GF const&>()))>;
typedef HG HostGrid;
typedef CF CoordFunction;
static const bool differentiableLocalFunction = DifferentiableLocalFunction<GF, LocalFunction>::value;
static_assert((differentiableLocalFunction || order>0), "Either provide a differentiable GridFunction or set ORDER > 0");
typedef typename HostGrid::ctype ctype;
using ctype = typename HostGrid::ctype;
static const int dimension = HostGrid::dimension;
static const int dimensionworld = CoordFunction::dimRange;
static const int dimensionworld = DimRange<GridFunction>::value;
typedef Dune::Intersection< const Grid, crvsrf::Intersection< const Grid, typename HostGrid::LeafIntersection > > LeafIntersection;
typedef Dune::Intersection< const Grid, crvsrf::Intersection< const Grid, typename HostGrid::LevelIntersection > > LevelIntersection;
using LeafIntersection
= Dune::Intersection<const Grid, Curved::Intersection<const Grid, typename HostGrid::LeafIntersection>>;
using LevelIntersection
= Dune::Intersection<const Grid, Curved::Intersection<const Grid, typename HostGrid::LevelIntersection>>;
typedef Dune::IntersectionIterator
< const Grid, crvsrf::IntersectionIterator< const Grid, typename HostGrid::LeafIntersectionIterator >, crvsrf::Intersection< const Grid, typename HostGrid::LeafIntersection > >
LeafIntersectionIterator;
typedef Dune::IntersectionIterator
< const Grid, crvsrf::IntersectionIterator< const Grid, typename HostGrid::LevelIntersectionIterator >, crvsrf::Intersection< const Grid, typename HostGrid::LevelIntersection > >
LevelIntersectionIterator;
using LeafIntersectionIterator
= Dune::IntersectionIterator<const Grid, Curved::IntersectionIterator<const Grid, typename HostGrid::LeafIntersectionIterator>, Curved::Intersection<const Grid, typename HostGrid::LeafIntersection> >;
using LevelIntersectionIterator
= Dune::IntersectionIterator<const Grid, Curved::IntersectionIterator<const Grid, typename HostGrid::LevelIntersectionIterator >, Curved::Intersection<const Grid, typename HostGrid::LevelIntersection> >;
typedef Dune::EntityIterator< 0, const Grid, crvsrf::HierarchicIterator< const Grid > >
HierarchicIterator;
using HierarchicIterator
= Dune::EntityIterator<0, const Grid, Curved::HierarchicIterator<const Grid>>;
template< int codim >
struct Codim
{
typedef Dune::crvsrf::Geometry< dimension-codim, dimensionworld, const Grid > GeometryImpl;
typedef Dune::Geometry< dimension-codim, dimensionworld, const Grid, Dune::crvsrf::Geometry > Geometry;
typedef typename HostGrid::template Codim< codim >::LocalGeometry LocalGeometry;
using LocalGeometry = typename HostGrid::template Codim<codim>::LocalGeometry;
using LocalTransformation = std::conditional_t<(codim == 0),
DefaultLocalGeometry<ctype, dimension, dimension>,
Curved::LocalGeometryWrapper<LocalGeometry>>;
typedef crvsrf::Entity< codim, dimension, const Grid > EntityImpl;
typedef Dune::Entity< codim, dimension, const Grid, crvsrf::Entity > Entity;
template < int mydim, int cdim, class GridImpl >
using GeometryImplTemplate
= Curved::Geometry<ctype, mydim, cdim, LocalFunction, LocalTransformation, order>;
typedef Dune::EntitySeed< const Grid, crvsrf::EntitySeed< codim, const Grid > > EntitySeed;
// geometry types
using GeometryImpl = GeometryImplTemplate<dimension-codim, dimensionworld, const Grid>;
using Geometry = Dune::Geometry<dimension-codim, dimensionworld, const Grid, GeometryImplTemplate>;
// entity types
using EntityImpl = Curved::Entity<codim, dimension, const Grid>;
using Entity = Dune::Entity<codim, dimension, const Grid, Curved::Entity>;
using EntitySeed = Dune::EntitySeed<const Grid, Curved::EntitySeed<codim, const Grid> >;
template< PartitionIteratorType pitype >
struct Partition
{
typedef crvsrf::Iterator< typename HostGrid::LeafGridView, codim, pitype, const Grid > LeafIteratorImp;
typedef Dune::EntityIterator< codim, const Grid, LeafIteratorImp > LeafIterator;
using LeafIteratorImp
= Curved::Iterator<typename HostGrid::LeafGridView, codim, pitype, const Grid>;
using LeafIterator = Dune::EntityIterator<codim, const Grid, LeafIteratorImp>;
typedef crvsrf::Iterator< typename HostGrid::LevelGridView, codim, pitype, const Grid > LevelIteratorImp;
typedef Dune::EntityIterator< codim, const Grid, LevelIteratorImp > LevelIterator;
using LevelIteratorImp
= Curved::Iterator<typename HostGrid::LevelGridView, codim, pitype, const Grid>;
using LevelIterator = Dune::EntityIterator<codim, const Grid, LevelIteratorImp>;
};
typedef typename Partition< All_Partition >::LeafIterator LeafIterator;
typedef typename Partition< All_Partition >::LevelIterator LevelIterator;
using LeafIterator = typename Partition< All_Partition >::LeafIterator;
using LevelIterator = typename Partition< All_Partition >::LevelIterator;
};
typedef crvsrf::IndexSet< const Grid, typename HostGrid::Traits::LeafIndexSet > LeafIndexSet;
typedef crvsrf::IndexSet< const Grid, typename HostGrid::Traits::LevelIndexSet > LevelIndexSet;
// index-sets
using LeafIndexSet = Curved::IndexSet<const Grid, typename HostGrid::Traits::LeafIndexSet>;
using LevelIndexSet = Curved::IndexSet<const Grid, typename HostGrid::Traits::LevelIndexSet>;
typedef crvsrf::IdSet< const Grid, typename HostGrid::Traits::GlobalIdSet >
GlobalIdSet;
typedef crvsrf::IdSet< const Grid, typename HostGrid::Traits::LocalIdSet >
LocalIdSet;
// id-sets
using GlobalIdSet = Curved::IdSet<const Grid, typename HostGrid::Traits::GlobalIdSet>;
using LocalIdSet = Curved::IdSet<const Grid, typename HostGrid::Traits::LocalIdSet>;
typedef typename HostGrid::Traits::CollectiveCommunication CollectiveCommunication;
using CollectiveCommunication = typename HostGrid::Traits::CollectiveCommunication;
typedef Dune::GridView< crvsrf::GridViewTraits< typename HostGrid::LeafGridView, CoordFunction, order, geoCaching, Allocator > > LeafGridView;
typedef Dune::GridView< crvsrf::GridViewTraits< typename HostGrid::LevelGridView, CoordFunction, order, geoCaching, Allocator > > LevelGridView;
// grid views
using LeafGridView
= Dune::GridView<Curved::GridViewTraits<typename HostGrid::LeafGridView, GF, order>>;
using LevelGridView
= Dune::GridView<Curved::GridViewTraits<typename HostGrid::LevelGridView, GF, order>>;
};
};
} // namespace crvsrf
} // namespace Curved
} // namespace Dune
#endif // #ifndef DUNE_CRVSRF_GRIDFAMILY_HH
#endif // DUNE_CURVED_SURFACE_GRID_GRIDFAMILY_HH
install(FILES
analyticgridfunction.hh
discretegridviewfunction.hh
gridentityset.hh
gridfunction.hh
normalgridviewfunction.hh
spheregridfunction.hh
torusgridfunction.hh
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dune/curvedsurfacegrid/gridfunctions)
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_CURVED_SURFACE_GRID_ANALYTIC_GRIDFUNCTION_HH
#define DUNE_CURVED_SURFACE_GRID_ANALYTIC_GRIDFUNCTION_HH
#include <type_traits>
#include <utility>
#include <dune/common/typeutilities.hh>
#include <dune/common/std/optional.hh>
#include "gridentityset.hh"
namespace Dune
{
//! LocalFunction associated to the \ref AnalyticGridFunction
/**
* \tparam LocalContext Context this localFunction can be bound to, e.g. a grid element
* \tparam F Type of a function that can be evaluated in global coordinates.
**/
template< class LocalContext, class F >
class LocalAnalyticGridFunction;
//! Generator for \ref LocalAnalyticGridFunction
/**
* \param ff Function that can be evaluated at global coordinates of the \ref LocalContext
* \tparam LocalContext Context this localFunction can be bound to, e.g. a grid element
**/
template< class LocalContext, class FF >
auto localAnalyticGridFunction (FF&& ff)
{
using F = std::decay_t<FF>;
return LocalAnalyticGridFunction<LocalContext, F>{std::forward<FF>(ff)};
}
template< class LC, class Functor >
class LocalAnalyticGridFunction
{
public:
using LocalContext = LC;
using Geometry = typename LocalContext::Geometry;
using Domain = typename Geometry::GlobalCoordinate;
using LocalDomain = typename Geometry::LocalCoordinate;
using Range = std::result_of_t<Functor(Domain)>;
using Signature = Range(LocalDomain);
public:
//! Constructor. Stores the functor f by value
template< class FF,
disableCopyMove<LocalAnalyticGridFunction, FF> = 0>
LocalAnalyticGridFunction (FF&& f)
: f_(std::forward<FF>(f))
{}
//! bind the LocalFunction to the local context
/**
* Stores the localContext and its geometry in a cache variable
**/
void bind (const LocalContext& localContext)
{
localContext_.emplace(localContext);
geometry_.emplace(localContext.geometry());
}
//! unbind the localContext from the localFunction
/**
* Reset the geometry
**/
void unbind ()
{
geometry_.reset();
localContext_.reset();
}
//! evaluate the stored function in local coordinates
/**
* Transform the local coordinates to global coordinates first,
* then evalute the stored functor.
**/
Range operator() (const LocalDomain& x) const
{
assert(!!geometry_);
return f_(geometry_->global(x));
}
//! return the bound localContext.
const LocalContext& localContext () const
{
assert(!!localContext_);
return *localContext_;
}
//! obtain the functor
const Functor& f () const
{
return f_;
}
private:
Functor f_;
// some caches
Std::optional<LocalContext> localContext_;
Std::optional<Geometry> geometry_;
};
//! Derivative of a \ref LocalAnalyticGridFunction
/**
* Participates in overload resolution only if the functor `F` is differentiable
**/
template< class LC, class F >
auto derivative (const LocalAnalyticGridFunction<LC,F>& t)
-> decltype(localAnalyticGridFunction<LC>(derivative(t.f())))
{
return localAnalyticGridFunction<LC>(derivative(t.f()));
}
//! GridFunction associated to the mapping F
/**
* \tparam Grid The grid type with elements the corresponding LocalFunction can be bound to
* \tparam F Type of a function that can be evaluated in global coordinates.
**/
template< class Grid, class F >
class AnalyticGridFunction;
//! Generator for \ref AnalyticGridFunction
/**
* \param ff Function that can be evaluated at global coordinates of the \ref Grid
* \tparam Grid The grid type with elements the corresponding LocalFunction can be bound to
**/
template< class Grid, class FF >
auto analyticGridFunction (FF&& ff)
{
using F = std::decay_t<FF>;
return AnalyticGridFunction<Grid, F>{std::forward<FF>(ff)};
}
template< class GridType, class Functor >
class AnalyticGridFunction
{
public:
using Grid = GridType;
using EntitySet = GridEntitySet<Grid,0>;
using Domain = typename EntitySet::GlobalCoordinate;
using Range = std::result_of_t<Functor(Domain)>;
using Signature = Range(Domain);
public:
//! Constructor. Stores the functor f by value
template< class FF,
disableCopyMove<AnalyticGridFunction, FF> = 0>
AnalyticGridFunction (FF&& f)
: f_(std::forward<FF>(f))
{}
//! evaluate the stored function in global coordinates
Range operator() (const Domain& x) const
{
return f_(x);
}
//! construct the \ref LocalAnalyticGridFunction
using LocalFunction = LocalAnalyticGridFunction<typename EntitySet::Element, Functor>;
friend LocalFunction localFunction (const AnalyticGridFunction& t)
{
return LocalFunction(t.f_);
}
//! obtain the stored \ref GridEntitySet
const EntitySet& entitySet () const
{
return entitySet_;
}
//! obtain the functor
const Functor& f () const
{
return f_;
}
private:
Functor f_;
EntitySet entitySet_;
};
//! Derivative of an \ref AnalyticGridFunction
/**
* Participates in overload resolution only if the functor `F` is differentiable
**/
template< class Grid, class F >
auto derivative (const AnalyticGridFunction<Grid,F>& t)
-> decltype(analyticGridFunction<Grid>(derivative(t.f())))
{
return analyticGridFunction<Grid>(derivative(t.f()));
}
} // end namespace Dune
#endif // DUNE_CURVED_SURFACE_GRID_ANALYTIC_GRIDFUNCTION_HH
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_CURVED_SURFACE_GRID_DISCRETE_GRIDVIEWFUNCTION_HH
#define DUNE_CURVED_SURFACE_GRID_DISCRETE_GRIDVIEWFUNCTION_HH
#include <array>
#include <vector>
#include <dune/common/fvector.hh>
#include <dune/functions/backends/istlvectorbackend.hh>
#include <dune/functions/common/defaultderivativetraits.hh>
#include <dune/functions/functionspacebases/basistags.hh>
#include <dune/functions/functionspacebases/defaultglobalbasis.hh>
#include <dune/functions/functionspacebases/lagrangebasis.hh>
#include <dune/functions/functionspacebases/powerbasis.hh>
#include <dune/functions/gridfunctions/gridviewentityset.hh>
#include <dune/functions/gridfunctions/localderivativetraits.hh>
#include <dune/grid/utility/hierarchicsearch.hh>
#include <dune/istl/bvector.hh>
namespace Dune
{
namespace Impl
{
template <class Sig, int degree, template <class> class Traits>
struct DerivativeRangeType;
template <class R, class D, int degree, template <class> class DerivativeTraits>
struct DerivativeRangeType<R(D), degree, DerivativeTraits>
{
using DerivativeRange = typename DerivativeTraits<R(D)>::Range;
using type = typename DerivativeRangeType<DerivativeRange(D), degree-1, DerivativeTraits>::type;
};
template <class R, class D, template <class> class Traits>
struct DerivativeRangeType<R(D), 0, Traits>
{
using type = R;
};
}
//! Grid-view function representing a coordinate map from a reference grid to world
/**
* \tparam GridView The grid-view type this coordinate function is defined on
* \tparam dow Dimension of the world this coordfunction mapps into
* \tparam ORDER Polynomial order of the local parametrization
* \tparam T Type of the basis range-type and coefficient type
**/
template< class GridView, int dow = GridView::dimensionworld, int ORDER = -1, class T = double >
class DiscreteGridViewFunction;
//! Generator for \ref DiscreteGridViewFunction
/**
* \param gridView Function that can be evaluated at global coordinates of the \ref Grid
* \param order Polynomial order of the local parametrization [ORDER]
*
* \tparam ORDER Polynomial order of the local parametrization [-1]
* \tparam T Range-type of the basis and coefficient value-type [double]
**/
template< int dow, int ORDER = -1, class T = double, class GridView >
auto discreteGridViewFunction (const GridView& gridView, int order = ORDER)
{
return DiscreteGridViewFunction<GridView,dow,ORDER,T>{gridView, order};
}
template< class GridView, int dow, int ORDER, class T >
class DiscreteGridViewFunction
{
static auto makeBasis (const GridView& gridView, int order)
{
namespace BF = Functions::BasisFactory;
return BF::makeBasis(gridView, BF::power<dow>(BF::lagrange<T>(order), BF::blockedInterleaved()));
}
using Basis = decltype(makeBasis(std::declval<GridView>(), ORDER));
public:
using EntitySet = Functions::GridViewEntitySet<GridView,0>;
using Domain = typename EntitySet::GlobalCoordinate;
using Range = FieldVector<T,dow>;
using Signature = Range(Domain);
private:
using VectorType = BlockVector<Range>;
template< int derivativeOrder = 0 >
class LocalFunction
{
using LocalView = typename Basis::LocalView;
using LocalFiniteElement = typename LocalView::Tree::ChildType::FiniteElement;
using LocalBasis = typename LocalFiniteElement::Traits::LocalBasisType;
template <class Sig>
using DerivativeTraits = typename Functions::LocalDerivativeTraits<EntitySet, Functions::DefaultDerivativeTraits>::template Traits<Sig>;
public:
using LocalContext = typename LocalView::Element;
using Geometry = typename LocalContext::Geometry;
using RangeType = typename DiscreteGridViewFunction::Range;
using Domain = typename EntitySet::LocalCoordinate;
template <int degree>
using DerivativeRange = typename Impl::DerivativeRangeType<RangeType(Domain), degree, DerivativeTraits>::type;
using Range = DerivativeRange<derivativeOrder>;
using Signature = Range(Domain);
public:
template <class LV>
LocalFunction (LV&& localView, const VectorType& coords)
: localView_(std::forward<LV>(localView))
, coords_(coords)
{}
//! Collect the coords from all element DOFs into a local
//! vector that can be accessed in the operator() for interpolation
void bind (const LocalContext& element)
{
localView_.bind(element);
const auto& leafNode = localView_.tree().child(0);
localCoords_.resize(leafNode.size());
// collect local coordinate vectors
for (std::size_t i = 0; i < localCoords_.size(); ++i) {
auto idx = localView_.index(leafNode.localIndex(i));
localCoords_[i] = coords_[idx[0]];
}
if constexpr (derivativeOrder == 1)
geometry_.emplace(element.geometry());
bound_ = true;
}
void unbind ()
{
localView_.unbind();
bound_ = false;
}
LocalContext const& localContext () const
{
assert(bound_);
return localView_.element();
}
//! Evaluate coordinates in local coordinates
//! by interpolation of stored coords in \ref localCoords_.
Range operator() (const Domain& local) const
{
static_assert(derivativeOrder < 2, "Higher-order derivatives not implemented");
if constexpr (derivativeOrder == 0)
return evaluateFunction(local);
else if constexpr (derivativeOrder == 1)
return evaluateJacobian(local);
return Range(0);
}
friend LocalFunction<derivativeOrder+1> derivative (LocalFunction const& lf)
{
return LocalFunction<derivativeOrder+1>{lf.localView_, lf.coords_};
}
private:
DerivativeRange<0> evaluateFunction (const Domain& local) const
{
assert(bound_);
const auto& leafNode = localView_.tree().child(0);
const auto& lfe = leafNode.finiteElement();
// evaluate basis functions in local coordinate
lfe.localBasis().evaluateFunction(local, shapeValues_);
assert(localCoords_.size() == shapeValues_.size());
DerivativeRange<0> x(0);
for (std::size_t i = 0; i < localCoords_.size(); ++i)
x.axpy(shapeValues_[i], localCoords_[i]);
return x;
}
DerivativeRange<1> evaluateJacobian (const Domain& local) const
{
assert(bound_);
const auto& leafNode = localView_.tree().child(0);
const auto& lfe = leafNode.finiteElement();
// evaluate basis functions in local coordinate
lfe.localBasis().evaluateJacobian(local, shapeGradients_);
assert(localCoords_.size() == shapeGradients_.size());
// transform gradients to global coordinates
auto jit = geometry_->jacobianInverseTransposed(local);
gradients_.resize(shapeGradients_.size());
for (std::size_t i = 0; i < shapeGradients_.size(); ++i)
jit.mv(shapeGradients_[i][0], gradients_[i]);
DerivativeRange<1> J(0);
for (std::size_t i = 0; i < localCoords_.size(); ++i)
for (int j = 0; j < J.N(); ++j)
J[j].axpy(localCoords_[i][j], gradients_[i]);
return J;
}
private:
LocalView localView_;
const VectorType& coords_;
std::vector<RangeType> localCoords_;
Std::optional<Geometry> geometry_;
mutable std::vector<typename LocalBasis::Traits::RangeType> shapeValues_;
mutable std::vector<typename LocalBasis::Traits::JacobianType> shapeGradients_;
mutable std::vector<DerivativeRange<0>> gradients_;
bool bound_ = false;
};
public:
//! Constructor.
DiscreteGridViewFunction (const GridView& gridView, int order = (ORDER > 0 ? ORDER : 1))
: entitySet_(gridView)
, basis_(makeBasis(gridView, order))
{
update(gridView);
}
void update (const GridView& gridView)
{
entitySet_ = EntitySet{gridView};
basis_.update(gridView);
coords_.resize(basis_.size());
}
//! evaluate in global coordinates
Range operator() (const Domain& x) const
{
using Grid = typename GridView::Grid;
using IS = typename GridView::IndexSet;
const auto& gv = entitySet_.gridView();
HierarchicSearch<Grid,IS> hsearch{gv.grid(), gv.indexSet()};
auto element = hsearch.findEntity(x);
auto geometry = element.geometry();
auto localFct = localFunction(*this);
localFct.bind(element);
return localFct(geometry.local(x));
}
//! Create a local function of this grifunction
friend LocalFunction<0> localFunction (const DiscreteGridViewFunction& gf)
{
return LocalFunction<0>{gf.basis_.localView(), gf.coords_};
}
//! obtain the stored \ref GridViewEntitySet
const EntitySet& entitySet () const
{
return entitySet_;
}
const Basis& basis () const
{
return basis_;
}
const VectorType& coefficients () const
{
return coords_;
}
VectorType& coefficients ()
{
return coords_;
}
private:
EntitySet entitySet_;
Basis basis_;
VectorType coords_;
};
} // end namespace Dune
#endif // DUNE_CURVED_SURFACE_GRID_DISCRETE_GRIDVIEWFUNCTION_HH
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_CURVED_SURFACE_GRID_SPHERE_GRIDFUNCTION_HH
#define DUNE_CURVED_SURFACE_GRID_SPHERE_GRIDFUNCTION_HH
#include <type_traits>
#include <dune/common/math.hh>
#include <dune/functions/common/defaultderivativetraits.hh>
#include "analyticgridfunction.hh"
namespace Dune
{
// Ellipsoid functor
template< class T >
class EllipsoidProjection
{
T a_;
T b_;
T c_;
public:
//! Constructor of ellipsoid by major axes
EllipsoidProjection (T a, T b, T c)
: a_(a)
, b_(b)
, c_(c)
{}
//! project the coordinate to the ellipsoid
// NOTE: This is not a closes-point projection, but a spherical-coordinate projection
template< class Domain >
Domain operator() (const Domain& X) const
{
using std::sin; using std::cos;
auto [phi,theta] = angles(X);
return {a_*cos(phi)*sin(theta), b_*sin(phi)*sin(theta), c_*cos(theta)};
}
//! derivative of the projection
friend auto derivative (const EllipsoidProjection& ellipsoid)
{
return [a=ellipsoid.a_,b=ellipsoid.b_,c=ellipsoid.c_](auto const& X)
{
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 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 {
{
a*x*nrm3*(y2 + z2)/nrm5 ,
-b*y*nrm0/(nrm3*nrm5) ,
-c*z*x/nrm4
},
{
-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
template< class Domain >
Domain normal (const Domain& X) const
{
using std::sqrt;
T x = X[0], y = X[1], z = X[2];
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);
return {b2*c2*x/div, a2*c2*y/div, a2*b2*z/div};
}
//! Mean curvature
template< class Domain >
T mean_curvature (const Domain& X) const
{
using std::sqrt; using std::abs;
T x = X[0], y = X[1], z = X[2];
T a2 = a_*a_, b2 = b_*b_, c2 = c_*c_;
auto div = 2*a2*b2*c2*power(sqrt(x*x/(a2*a2) + y*y/(b2*b2) + z*z/(c2*c2)), 3);
return abs(x*x + y*y + z*z - a2 - b2 - c2)/div;
}
//! Gaussian curvature
template< class Domain >
T gauss_curvature (const Domain& X) const
{
T x = X[0], y = X[1], z = X[2];
T a2 = a_*a_, b2 = b_*b_, c2 = c_*c_;
auto div = a2*b2*c2*power(x*x/(a2*a2) + y*y/(b2*b2) + z*z/(c2*c2), 2);
return T(1)/div;
}
private:
FieldVector<T,2> angles (Domain x) const
{
using std::acos; using std::atan2;
x /= x.two_norm();
return {atan2(x[1], x[0]), acos(x[2])};
}
};
//! construct a grid function representing a sphere parametrization
template< class Grid, class T >
auto ellipsoidGridFunction (T a, T b, T c)
{
return analyticGridFunction<Grid>(EllipsoidProjection<T>{a,b,c});
}
} // end namespace Dune
#endif // DUNE_CURVED_SURFACE_GRID_SPHERE_GRIDFUNCTION_HH
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_CURVED_SURFACE_GRID_GRID_ENTITYSET_HH
#define DUNE_CURVED_SURFACE_GRID_GRID_ENTITYSET_HH
namespace Dune
{
//! A set of entities of given `codim` of a `Grid`
/**
* \tparam GridType The grid type
* \tparam codim Codimension of the entities to define the set of.
*
* \note This entityset just defines types
**/
template< class GridType, int codim >
class GridEntitySet
{
public:
//! Type of the grid
using Grid = GridType;
//! Type of Elements contained in this EntitySet
using Element = typename Grid::template Codim<codim>::Entity;
//! Type of local coordinates with respect to the Element
using LocalCoordinate = typename Element::Geometry::LocalCoordinate;
//! Type of global coordinates with respect to the Element
using GlobalCoordinate = typename Element::Geometry::GlobalCoordinate;
};
} // end namespace Dune
#endif // DUNE_CURVED_SURFACE_GRID_GRID_ENTITYSET_HH
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment