Skip to content

ColloidBoundaryConditions

Sebastian Schmieschek edited this page Aug 12, 2015 · 2 revisions

Colloid Boundary Conditions

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

Collision Detection

For each particle

  1. 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));

  2. 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);

  3. 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 ); }

  4. 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) }

Clone this wiki locally