-
Notifications
You must be signed in to change notification settings - Fork 12
ColloidBoundaryConditions
Uses the publisher/subscriber design pattern: handlers register with a central manager.
- Derivatives of the abstract base class BoundaryCondition are created for each boundary algorithm, e.g. BounceBackBoundaryCondition
- These handler objects are registered with a BoundaryConditions manager static class
- When boundary conditions must be applied, the BoundaryConditions manager is given each particle in turn
- The BoundaryConditions manager determines which handlers to call, if any, by simple collision detection (see below)
- Each of the registered handlers for the type of boundary discovered, if any, is called in turn and passed a non-const reference to the particle
- Each BoundaryCondition modifies the particle according to its particular algorithm, e.g. by setting the velocity or by adding a force
For each particle
-
calculate global coordinates of lattice location nearest to the globalPosition of the particle
const util::Vector3D<site_t> siteGlobalPosition( (site_t)(0.5+globalPosition.x), (site_t)(0.5+globalPosition.y), (site_t)(0.5+globalPosition.z));
-
determine the nature of the site at that location, if any
proc_t procId; site_t localContiguousId; const bool isLocalFluid = latticeData->GetContiguousSiteId(siteGlobalPosition, procId, localContiguousId); if (isLocalFluid) break;
const geometry::ConstSite site = latticeData->GetSite(localContiguousId); if (site == NULL) break; const geometry::SiteData siteData = site.GetSiteData(); if (siteData == NULL) break; const geometry::SiteType siteType = siteData.GetSiteType()
const bool isNearWall = siteData.IsEdge() const bool isNearInlet = (siteType == INLET_TYPE); const bool isNearOutlet = (siteType == OUTLET_TYPE);
-
determine distance to wall (for wall boundaries only) a. EITHER calculate a single vector from the wall to the particle (for wall boundaries only)
std::vector siteToWallVectors; const LatticeInfo& latticeInfo = latticeData.GetLatticeInfo(); double shortestDistance = 100.0; int shortestDirection = 0; for (Direction direction = 1; direction < latticeInfo.GetNumVectors(); ++direction) { double thisDistance = site.GetWallDistance(direction); if (0.0 =< thisDistance && thisDistance < shortestDistance) { shortestDistance = thisDistance; shortestDirection = direction; } } // cap distance at 0.5 to avoid particles getting too near solid sites if (shortestDistance > 0.5) shortestDistance = 0.5; siteToWallVectors.add( latticeInfo.GetVector(shortestDirection).Normalise() * shortestDistance ); a. OR calculate a multiple orthogonal vectors from the wall to the particle (for wall boundaries only)
std::vector siteToWallVectors; for (Direction direction = 1; direction <= 6; ++direction) { double thisDistance = site.GetWallDistance(direction); if (0.0 =< thisDistance) { siteToWallVectors.add( latticeInfo.GetVector(direction) * min(0.5, thisDistance) ); } } a. do some geometry to produce wallToParticleVectors
std::vector wallToParticleVectors;
LatticePosition p = particleGlobalPosition; LatticePosition s = siteGlobalPosition;
foreach (LatticePosition w in siteToWallVector) { // EITHER (from point on wall nearest to site, not normal to wall) ... wallToParticleVectors.add( w + s - p );
// OR (parallel to siteToWallVector and assuming wall is locally flat) ... wallToParticleVectors.add( w.Normalised().Dot(s - p) * w.Normalised() + w ); }
-
choose appropriate boundary handlers
if (isNearWall) { // do handlers registered for wall boundaries (pass wallToParticleVectors) } if (isNearInlet) { // do handlers registered for inlet boundaries (pass empty std::vector) } if (isNearOutlet) { // do handlers registered for outlet boundaries (pass empty std::vector) }