Skip to content
Snippets Groups Projects
Commit e1f4a012 authored by Christoph Rettinger's avatar Christoph Rettinger
Browse files

Added support for vectorial dx to overlap fraction computation

parent 9d28f33b
Branches
Tags
No related merge requests found
...@@ -30,13 +30,12 @@ namespace geometry { ...@@ -30,13 +30,12 @@ namespace geometry {
template<> template<>
inline real_t overlapFraction ( const AABB & body, const Vector3<real_t> & cellMidpoint, real_t dx, uint_t ) inline real_t overlapFraction ( const AABB & body, const Vector3<real_t> & cellMidpoint, const Vector3<real_t> & dx, uint_t )
{ {
const real_t dx2 = real_t( 0.5 ) * dx; AABB box = AABB::createFromMinMaxCorner( cellMidpoint[0] - real_t(0.5)*dx[0], cellMidpoint[1] - real_t(0.5)*dx[1], cellMidpoint[2] - real_t(0.5)*dx[2],
AABB box ( cellMidpoint[0] - dx2, cellMidpoint[1] - dx2, cellMidpoint[2] - dx2, cellMidpoint[0] + real_t(0.5)*dx[0], cellMidpoint[1] + real_t(0.5)*dx[1], cellMidpoint[2] + real_t(0.5)*dx[2]);
cellMidpoint[0] + dx2, cellMidpoint[1] + dx2, cellMidpoint[2] + dx2 );
return body.intersectionVolume( box ) / ( dx * dx * dx ); return body.intersectionVolume( box ) / ( dx[0] * dx[1] * dx[2] );
} }
......
...@@ -61,16 +61,17 @@ namespace geometry { ...@@ -61,16 +61,17 @@ namespace geometry {
* *
* \param body the body object * \param body the body object
* \param cellMidpoint midpoint of the cell in global coordinates * \param cellMidpoint midpoint of the cell in global coordinates
* \param dx the edge length of the cell, cell is assumed to be cubic * \param dx the edge length(s) of the cell, dx or (dx, dy, dz)
* \param maxDepth sub sampling depth: the cell edge is divided in half \p maxDepth+1 times. * \param maxDepth sub sampling depth: the cell edge is divided in half \p maxDepth+1 times.
* Values less than zero result in no subdivisions, making this function behave like contains(). * Values less than zero result in no subdivisions, making this function behave like contains().
********************************************************************************************************************/ ********************************************************************************************************************/
template <typename Body> real_t overlapFraction ( const Body & body, const Vector3<real_t> & cellMidpoint, template <typename Body> real_t overlapFraction ( const Body & body, const Vector3<real_t> & cellMidpoint,
real_t dx, uint_t maxDepth=4 ); real_t dx, uint_t maxDepth=4 );
template <typename Body> real_t overlapFraction ( const Body & body, const Vector3<real_t> & cellMidpoint, template <typename Body> real_t overlapFraction ( const Body & body, const Vector3<real_t> & cellMidpoint,
real_t dx, int maxDepth ); real_t dx, int maxDepth );
template <typename Body> real_t overlapFraction ( const Body & body, const Vector3<real_t> & cellMidpoint,
const Vector3<real_t> & dx, uint_t maxDepth=4 );
/****************************************************************************************************************//** /****************************************************************************************************************//**
...@@ -99,8 +100,7 @@ namespace geometry { ...@@ -99,8 +100,7 @@ namespace geometry {
* Determines in a fast way (bounding box etc) if a body and a block overlap * Determines in a fast way (bounding box etc) if a body and a block overlap
* when no fast computation is possible return DONT_KNOW * when no fast computation is possible return DONT_KNOW
********************************************************************************************************************/ ********************************************************************************************************************/
template <typename Body> FastOverlapResult fastOverlapCheck ( const Body & body, template <typename Body> FastOverlapResult fastOverlapCheck ( const Body & body, const Vector3<real_t> & cellMidpoint, const Vector3<real_t> & dx );
const Vector3<real_t> & cellMidpoint, real_t dx );
......
...@@ -34,7 +34,7 @@ namespace geometry { ...@@ -34,7 +34,7 @@ namespace geometry {
template <typename Body> template <typename Body>
FastOverlapResult fastOverlapCheck ( const Body & /*body*/, FastOverlapResult fastOverlapCheck ( const Body & /*body*/,
const Vector3<real_t> & /*cellMidpoint*/, const Vector3<real_t> & /*cellMidpoint*/,
real_t /*dx*/ ) const Vector3<real_t> & /*dx*/ )
{ {
// Default implementation has to fastOverlapCheck // Default implementation has to fastOverlapCheck
return DONT_KNOW; return DONT_KNOW;
...@@ -42,7 +42,7 @@ namespace geometry { ...@@ -42,7 +42,7 @@ namespace geometry {
template< typename Body> template< typename Body>
real_t cellSupersampling( const Vector3<real_t> & cellMidpoint, real_t dx, const Body & body, uint_t maxDepth=4, uint_t depth = uint_t(0u) ) real_t cellSupersampling( const Vector3<real_t> & cellMidpoint, const Vector3<real_t> & dx, const Body & body, uint_t maxDepth=4, uint_t depth = uint_t(0u) )
{ {
FastOverlapResult r = fastOverlapCheck( body, cellMidpoint, dx ); FastOverlapResult r = fastOverlapCheck( body, cellMidpoint, dx );
if ( r == CONTAINED_INSIDE_BODY ) if ( r == CONTAINED_INSIDE_BODY )
...@@ -56,9 +56,9 @@ namespace geometry { ...@@ -56,9 +56,9 @@ namespace geometry {
for( int signZ = -1; signZ <= 1; signZ += 2 ) for( int signZ = -1; signZ <= 1; signZ += 2 )
{ {
// epsilon is subtracted due to symmetry reasons ( i.e. a sphere on a cell boundary should be symmetric) // epsilon is subtracted due to symmetry reasons ( i.e. a sphere on a cell boundary should be symmetric)
const Vector3<real_t> corner( cellMidpoint[0] + real_c(signX) * dx * (real_t(0.5) - real_comparison::Epsilon<real_t>::value ), const Vector3<real_t> corner( cellMidpoint[0] + real_c(signX) * dx[0] * (real_t(0.5) - real_comparison::Epsilon<real_t>::value ),
cellMidpoint[1] + real_c(signY) * dx * (real_t(0.5) - real_comparison::Epsilon<real_t>::value ), cellMidpoint[1] + real_c(signY) * dx[1] * (real_t(0.5) - real_comparison::Epsilon<real_t>::value ),
cellMidpoint[2] + real_c(signZ) * dx * (real_t(0.5) - real_comparison::Epsilon<real_t>::value ) ); cellMidpoint[2] + real_c(signZ) * dx[2] * (real_t(0.5) - real_comparison::Epsilon<real_t>::value ) );
if ( contains( body, corner ) ) if ( contains( body, corner ) )
++nrCornerPointsInBody; ++nrCornerPointsInBody;
} }
...@@ -76,7 +76,7 @@ namespace geometry { ...@@ -76,7 +76,7 @@ namespace geometry {
for( int signY = -1; signY <= 1; signY += 2 ) for( int signY = -1; signY <= 1; signY += 2 )
for( int signZ = -1; signZ <= 1; signZ += 2 ) for( int signZ = -1; signZ <= 1; signZ += 2 )
{ {
const Vector3<real_t> offsetVec ( real_c(signX) * real_t(0.25) * dx, real_c(signY) * real_t(0.25) * dx, real_c(signZ) * real_t(0.25) * dx ); const Vector3<real_t> offsetVec ( real_c(signX) * real_t(0.25) * dx[0], real_c(signY) * real_t(0.25) * dx[1], real_c(signZ) * real_t(0.25) * dx[2] );
fraction += cellSupersampling( cellMidpoint + offsetVec, dx*real_t(0.5), body, maxDepth, depth+uint_t(1u) ); fraction += cellSupersampling( cellMidpoint + offsetVec, dx*real_t(0.5), body, maxDepth, depth+uint_t(1u) );
} }
fraction *= real_t(0.125); fraction *= real_t(0.125);
...@@ -89,14 +89,7 @@ namespace geometry { ...@@ -89,14 +89,7 @@ namespace geometry {
template < typename Body > template < typename Body >
real_t overlapFraction ( const Body & body, const Vector3<real_t> & cellMidpoint, real_t dx, uint_t maxDepth ) real_t overlapFraction ( const Body & body, const Vector3<real_t> & cellMidpoint, real_t dx, uint_t maxDepth )
{ {
FastOverlapResult r = fastOverlapCheck( body, cellMidpoint, dx ); return overlapFraction<Body>(body, cellMidpoint, Vector3<real_t>(dx), maxDepth);
if ( r == CONTAINED_INSIDE_BODY )
return real_t(1);
else if ( r == COMPLETELY_OUTSIDE )
return real_t(0);
// default: fall-back to super-sampling
return cellSupersampling( cellMidpoint, dx, body, maxDepth );
} }
template < typename Body > template < typename Body >
...@@ -109,6 +102,22 @@ namespace geometry { ...@@ -109,6 +102,22 @@ namespace geometry {
return real_t(0); return real_t(0);
} }
template < typename Body >
real_t overlapFraction ( const Body & body, const Vector3<real_t> & cellMidpoint, const Vector3<real_t> & dx, uint_t maxDepth )
{
FastOverlapResult r = fastOverlapCheck( body, cellMidpoint, dx );
if ( r == CONTAINED_INSIDE_BODY )
return real_t(1);
else if ( r == COMPLETELY_OUTSIDE )
return real_t(0);
// default: fall-back to super-sampling
real_t overlapFractionBySuperSampling = cellSupersampling( cellMidpoint, dx, body, maxDepth );
WALBERLA_ASSERT_GREATER_EQUAL(overlapFractionBySuperSampling, real_t(0));
WALBERLA_ASSERT_LESS_EQUAL(overlapFractionBySuperSampling, real_t(1));
return overlapFractionBySuperSampling;
}
} // namespace geometry } // namespace geometry
} // namespace walberla } // namespace walberla
......
...@@ -32,7 +32,7 @@ class AbstractBody { ...@@ -32,7 +32,7 @@ class AbstractBody {
public: public:
virtual ~AbstractBody() = default; virtual ~AbstractBody() = default;
virtual bool contains (const Vector3<real_t> & point ) const = 0; virtual bool contains (const Vector3<real_t> & point ) const = 0;
virtual FastOverlapResult fastOverlapCheck ( const Vector3<real_t> & cellMidpoint, real_t dx ) const = 0; virtual FastOverlapResult fastOverlapCheck ( const Vector3<real_t> & cellMidpoint, const Vector3<real_t> & dx ) const = 0;
virtual FastOverlapResult fastOverlapCheck ( const AABB & box ) const = 0; virtual FastOverlapResult fastOverlapCheck ( const AABB & box ) const = 0;
}; };
...@@ -44,11 +44,12 @@ public: ...@@ -44,11 +44,12 @@ public:
DynamicBody( const Body & b ) DynamicBody( const Body & b )
: body_(b) : body_(b)
{} {}
virtual bool contains (const Vector3<real_t> & point ) const virtual bool contains (const Vector3<real_t> & point ) const
{ {
return geometry::contains( body_, point ); return geometry::contains( body_, point );
} }
virtual FastOverlapResult fastOverlapCheck ( const Vector3<real_t> & cellMidpoint, real_t dx ) const virtual FastOverlapResult fastOverlapCheck ( const Vector3<real_t> & cellMidpoint, const Vector3<real_t> & dx ) const
{ {
return geometry::fastOverlapCheck( body_, cellMidpoint, dx ); return geometry::fastOverlapCheck( body_, cellMidpoint, dx );
} }
...@@ -80,7 +81,7 @@ inline FastOverlapResult fastOverlapCheck ( const AbstractBody & body, const AAB ...@@ -80,7 +81,7 @@ inline FastOverlapResult fastOverlapCheck ( const AbstractBody & body, const AAB
} }
template<> template<>
inline FastOverlapResult fastOverlapCheck ( const AbstractBody & body, const Vector3<real_t> & cellMidpoint, real_t dx ) inline FastOverlapResult fastOverlapCheck ( const AbstractBody & body, const Vector3<real_t> & cellMidpoint, const Vector3<real_t> & dx )
{ {
return body.fastOverlapCheck( cellMidpoint, dx ); return body.fastOverlapCheck( cellMidpoint, dx );
} }
......
...@@ -99,10 +99,10 @@ namespace geometry { ...@@ -99,10 +99,10 @@ namespace geometry {
} }
template<> template<>
FastOverlapResult fastOverlapCheck ( const Ellipsoid & ellipsoid, const Vector3<real_t> & cellMidpoint, real_t dx ) FastOverlapResult fastOverlapCheck ( const Ellipsoid & ellipsoid, const Vector3<real_t> & cellMidpoint, const Vector3<real_t> & dx )
{ {
AABB box = AABB::createFromMinMaxCorner( cellMidpoint[0] - real_t(0.5)*dx, cellMidpoint[1] - real_t(0.5)*dx, cellMidpoint[2] - real_t(0.5)*dx, AABB box = AABB::createFromMinMaxCorner( cellMidpoint[0] - real_t(0.5)*dx[0], cellMidpoint[1] - real_t(0.5)*dx[1], cellMidpoint[2] - real_t(0.5)*dx[2],
cellMidpoint[0] + real_t(0.5)*dx, cellMidpoint[1] + real_t(0.5)*dx, cellMidpoint[2] + real_t(0.5)*dx); cellMidpoint[0] + real_t(0.5)*dx[0], cellMidpoint[1] + real_t(0.5)*dx[1], cellMidpoint[2] + real_t(0.5)*dx[2]);
if ( ! ellipsoid.boundingBox().intersects( box ) ) if ( ! ellipsoid.boundingBox().intersects( box ) )
return COMPLETELY_OUTSIDE; return COMPLETELY_OUTSIDE;
...@@ -114,7 +114,8 @@ namespace geometry { ...@@ -114,7 +114,8 @@ namespace geometry {
const real_t midPointDistSq = (ellipsoid.midpoint() - cellMidpoint).sqrLength(); const real_t midPointDistSq = (ellipsoid.midpoint() - cellMidpoint).sqrLength();
// Check against inner circle of box // Check against inner circle of box
const real_t dist2 = ellipsoid.minRadius() - sqrt3half * dx; const real_t dxMax = dx.max();
const real_t dist2 = ellipsoid.minRadius() - sqrt3half * dxMax;
if ( midPointDistSq < dist2 * dist2 ) if ( midPointDistSq < dist2 * dist2 )
return CONTAINED_INSIDE_BODY; return CONTAINED_INSIDE_BODY;
......
...@@ -91,7 +91,7 @@ namespace geometry { ...@@ -91,7 +91,7 @@ namespace geometry {
// Body concept // Body concept
template<> FastOverlapResult fastOverlapCheck ( const Ellipsoid & e, const AABB & box ); template<> FastOverlapResult fastOverlapCheck ( const Ellipsoid & e, const AABB & box );
template<> FastOverlapResult fastOverlapCheck ( const Ellipsoid & e, const Vector3<real_t> & cellMidpoint, real_t dx ); template<> FastOverlapResult fastOverlapCheck ( const Ellipsoid & e, const Vector3<real_t> & cellMidpoint, const Vector3<real_t> & dx );
template<> bool contains ( const Ellipsoid & ellipsoid, const Vector3<real_t> & point ); template<> bool contains ( const Ellipsoid & ellipsoid, const Vector3<real_t> & point );
......
...@@ -70,19 +70,20 @@ namespace geometry { ...@@ -70,19 +70,20 @@ namespace geometry {
} }
template<> template<>
FastOverlapResult fastOverlapCheck ( const Sphere & sphere, const Vector3<real_t> & cellMidpoint, real_t dx ) FastOverlapResult fastOverlapCheck ( const Sphere & sphere, const Vector3<real_t> & cellMidpoint, const Vector3<real_t> & dx )
{ {
static const real_t sqrt3half = std::sqrt( real_t(3) ) / real_t(2); static const real_t sqrt3half = std::sqrt( real_t(3) ) / real_t(2);
const real_t midPointDistSq = (sphere.midpoint() - cellMidpoint).sqrLength(); const real_t midPointDistSq = (sphere.midpoint() - cellMidpoint).sqrLength();
const real_t dxMax = dx.max();
// Check against outer circle of box // Check against outer circle of box
const real_t dist1 = sphere.radius() + sqrt3half * dx; const real_t dist1 = sphere.radius() + sqrt3half * dxMax;
if ( midPointDistSq > dist1 * dist1 ) if ( midPointDistSq > dist1 * dist1 )
return COMPLETELY_OUTSIDE; return COMPLETELY_OUTSIDE;
// Check against inner circle of box // Check against inner circle of box
const real_t dist2 = sphere.radius() - sqrt3half * dx; const real_t dist2 = sphere.radius() - sqrt3half * dxMax;
if ( midPointDistSq < dist2 * dist2 ) if ( midPointDistSq < dist2 * dist2 )
return CONTAINED_INSIDE_BODY; return CONTAINED_INSIDE_BODY;
......
...@@ -76,7 +76,7 @@ namespace geometry { ...@@ -76,7 +76,7 @@ namespace geometry {
// Body concept // Body concept
template<> FastOverlapResult fastOverlapCheck ( const Sphere & sphere, const AABB & box ); template<> FastOverlapResult fastOverlapCheck ( const Sphere & sphere, const AABB & box );
template<> FastOverlapResult fastOverlapCheck ( const Sphere & sphere, const Vector3<real_t> & cellMidpoint, real_t dx ); template<> FastOverlapResult fastOverlapCheck ( const Sphere & sphere, const Vector3<real_t> & cellMidpoint, const Vector3<real_t> & dx );
template<> bool contains ( const Sphere & sphere, const Vector3<real_t> & point ); template<> bool contains ( const Sphere & sphere, const Vector3<real_t> & point );
......
...@@ -140,6 +140,7 @@ namespace initializer { ...@@ -140,6 +140,7 @@ namespace initializer {
const real_t dx = structuredBlockStorage_.dx(); const real_t dx = structuredBlockStorage_.dx();
const real_t dy = structuredBlockStorage_.dy(); const real_t dy = structuredBlockStorage_.dy();
const real_t dz = structuredBlockStorage_.dz(); const real_t dz = structuredBlockStorage_.dz();
const Vector3<real_t> dxVec(dx, dy, dz);
for( auto blockIt = structuredBlockStorage_.begin(); blockIt != structuredBlockStorage_.end(); ++blockIt ) for( auto blockIt = structuredBlockStorage_.begin(); blockIt != structuredBlockStorage_.end(); ++blockIt )
{ {
...@@ -170,7 +171,7 @@ namespace initializer { ...@@ -170,7 +171,7 @@ namespace initializer {
currentMidpoint[0] = firstCellMidpoint[0]; currentMidpoint[0] = firstCellMidpoint[0];
for( cell_idx_t x = -gl; x < cell_idx_c(ff->xSize())+gl; ++x, currentMidpoint[0] += dx ) for( cell_idx_t x = -gl; x < cell_idx_c(ff->xSize())+gl; ++x, currentMidpoint[0] += dx )
{ {
real_t overlap = overlapFraction( body, currentMidpoint, dx, superSamplingDepth ); real_t overlap = overlapFraction( body, currentMidpoint, dxVec, superSamplingDepth );
real_t & val = ff->get(x,y,z); real_t & val = ff->get(x,y,z);
WALBERLA_ASSERT( val >=0 && val <= 1); WALBERLA_ASSERT( val >=0 && val <= 1);
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment