dsmc-0.1.0.1: DSMC library for rarefied gas dynamics

Safe HaskellNone

DSMC.Traceables

Contents

Description

Ray-casting routines for constructive solid geometry.

This module provides constructors for complex bodies as well as routines to compute intersections of such bodies with ray. In DSMC it is used to calculate points at which particles hit the body surface.

Gas-surface interactions are not handled by this module, see Surface instead.

Synopsis

Bodies

data Body Source

CSG body is a recursive composition of primitive objects or other bodies.

Instances

Primitives

plane :: Point -> Vec3 -> BodySource

A half-space defined by arbitary point on the boundary plane and outward normal (not necessarily a unit vector).

sphere :: Vec3 -> Double -> BodySource

A sphere defined by center point and radius.

cylinder :: Point -> Point -> Double -> BodySource

An infinite circular cylinder defined by two arbitary points on axis and radius.

cylinderFrustum :: Point -> Point -> Double -> BodySource

A finite right circular cylinder defined by two points on its top and bottom and radius.

cone :: Vec3 -> Point -> Double -> BodySource

An infinite right circular cone defined by outward axis vector, apex point and angle between generatrix and axis (in degrees, less than 90).

coneFrustum :: (Point, Double) -> (Point, Double) -> BodySource

A conical frustum given by two points on its axis with radii at that points. One of radii may be zero (in which case one of frustum ends will be the apex).

Compositions

intersect :: Body -> Body -> BodySource

Intersection of two bodies.

unite :: Body -> Body -> BodySource

Union of two bodies.

complement :: Body -> BodySource

Complement to a body (normals flipped).

Ray casting

data HitPoint Source

Time when particle hits the surface with normal at the hit point. If hit is in infinity, then normal is Nothing.

Note that this datatype is strict only on first argument: we do not compare normals when classifying traces.

Constructors

HitPoint !Double (Maybe Vec3) 

hitPoint :: Time -> Body -> Particle -> Maybe HitPointSource

If the particle has hit the body during last time step, calculate the first corresponding HitPoint. Note that the time at which the hit occured will be negative. This is the primary function to calculate ray-body intersections.

type HitSegment = Pair HitPoint HitPointSource

A segment on time line when particle is inside the body.

Using strict tuple performs better: 100 traces for 350K particles perform roughly 7s against 8s with common datatypes.

type Trace = [HitSegment]Source

Trace of a linearly-moving particle on a body is a list of time segments/intervals during which the particle is inside the body.

                       # - particle
                        \
                         \
                          o------------
                      ---/ *           \---
                    -/      *              \-
                   /         *               \
                  (           *  - trace      )
                   \           *             /
                    -\          *          /-
       primitive -  ---\         *     /---
                          --------o----
                                   \
                                    \
                                    _\/
                                      \

For example, since a ray intersects a plane only once, a half-space primitive defined by this plane results in a half-interval trace of a particle:

                                          /
                                         /
                                        /
              #------------------------o*****************>
              |                       /                  |
           particle                  /            goes to infinity
                                    /
                                   /
                                  /
                                 / - surface of half-space

Ends of segments or intervals are calculated by intersecting the trajectory ray of a particle and the surface of the primitive. This may be done by substituting the equation of trajectory X(t) = X_o + V*t into the equation which defines the surface and solving it for t. If the body is a composition, traces from primitives are then classified according to operators used to define the body (union, intersection or complement).

Although only convex primitives are used in current implementation, compositions may result in concave bodies, which is why trace is defined as a list of segments.

In this example, body is an intersection of a sphere and sphere complement:

                                /|\
                                 |
                                 |
                                 |
                   -----------   |
              ----/           \--o-
            -/                   * \-
          -/               hs2 - *   \
        -/                       * ---/
       /                         o/
      /                        -/|
     /                        /  |
     |                       /   |
    /                        |   |
    |                       /    |
    |                       |    |
    |                       \    |
    \                        |   |
     |                       \   |
     \                        \  |
      \                        -\|
       \                         o\
        -\                       * ---\
          -\               hs1 - *   /
            -\                   * /-
              ----\           /--o-
                   -----------   |
                                 |
                                 |
                                 # - particle

If only intersections of concave primitives were allowed, then trace type might be simplified to be just single HitSegment.

trace :: Body -> Particle -> TraceSource

Calculate a trace of a particle on a body.

Body membership

inside :: Body -> Particle -> BoolSource

True if particle is in inside the body.