Capsule

Capsule (Wikipedia) is a cylinder with hemispherical ends, or a sphere swept along a segment. It is defined by shaft (the length of the segment, noted \(a\)) and radius (\(r\)). The segment is always oriented along the local \(x\)-axis.

../../_images/capsule_geometry-wikipedia.svg

Fig. 9 Geometry of a capsule particle.

Particle of this shapes are useful, among others, in the pharmaceutical industry or geomechanics.

../../_images/capsules.jpg

Fig. 10 Pharmaceutical capsules (image courtesy of wikipedia).

Properties

The volume is computed as

\[V=V_c+V_a=\frac{4}{3}\pi r^3+\pi r^2 a.\]

Inertia is the sum of caps’ (hemispheres) and shaft’s (cylinder) inertia, applying Parallel Axes Theorem along \(y\) and \(z\) axes:

\begin{align*} I_{xx}&=\rho\left[\frac{2}{5}V_c r^2 + \frac{1}{2}V_a r^2\right], \\ I_{yy}=I_{zz}&=\rho\left[\frac{83}{320}V_c r^2+V_c\left(\frac{a}{2}+\frac{3}{8}r\right)^2+\frac{1}{12}V_a(3r^2+a^2) \right]. \end{align*}

The centroid is always in the middle of the shaft due to symmetries. The radius of the bounding sphere is \(r+a/2\).

Capsule-capsule contact

This algorithm is implemented by woo.dem.Cg2_Capsule_Capsule_L6Geom. Determination of the contact is equivalent to finding minimum distance \(d\) between segments of both capsules. Each segment’s endpoints \(A_i\), \(B_i\) are computed by multiplying local \(x\)-axis by \(\pm a_i/2\). The algorithm is described in [Ebe99].

The normal overlap is based directly on the distance as

\[u_N=d-(r_1+r_2).\]

Determining contact point and normal purely geometrically would be discontinuous (small movement of the capsule would result in abrupt change); the reason is that the shaft (cylinder) is not convex and conforming contacts can be formed with other flat particles (such as Capsule or woo.dem.Wall). The algorithm determines the distance between endpoints and the opposite capsule, filters out those without geometrical overlap. There are 16 possible combinations.

If there is one overlap, the purely geometrical contact point and normal applies. Otherwise, all overlaps are assigned weight \(w_i=d_i-(r_1+r_2)\), and contact points \(\vec{c}_i\) and normals \(\vec{n}_i\) are computed normally (middle point of the segment in the intersection volume) and interpolated between as in

\begin{align*} \vec{n}&=\frac{\sum w_i \vec{n}_i }{\sum w_i}, & \vec{c}&=\frac{\sum w_i \vec{c}_i}{\sum w_i}. \end{align*}

Note

The overlap \(u_N\) is used in conjunction with contact point and normal which may not correspond geometrically to the place where \(u_N\) occurs. This can lead to strange consequences, such as L6Geom.vel[0] not being the derivative of uN. The advantages of this approach (that the movement of the contact point and the normal is continuous, and that we still meaningfully represent the contact by one point) seem to outweight such inconveniences.

Wall-capsule contact

This algorithm is implemented by woo.dem.Cg2_Wall_Capsule_L6Geom and is similar to the capsule-capsule contact above; there is interpolation between max. two endpoints of the capsule touching the wall:

../../_images/capsule-wall.png

import math, woo, woo.core, woo.dem, woo.utils, woo.gl
from minieigen import *

S=woo.master.scene=woo.core.Scene(dtSafety=.1,throttle=0.01,fields=[woo.dem.DemField(gravity=(0,0,-10))])
mat=woo.dem.FrictMat(young=1e6,ktDivKn=.2,density=3e3)
S.dem.par.add([woo.dem.Capsule.make((0,0,.5),radius=.3,shaft=.8,ori=Quaternion((0,1,0),-math.pi/8.),wire=True,mat=mat),woo.utils.wall(0,axis=2,sense=1,mat=mat)])
S.engines=woo.dem.DemField.minimalEngines(dynDtPeriod=100,damping=.4)
S.saveTmp()

# view setup
woo.gl.Gl1_DemField.cPhys=True
woo.gl.Gl1_CPhys.relMaxRad=.1
woo.gl.Renderer.allowFast=False
woo.gl.Renderer.iniViewDir=(0,-1,0)
woo.gl.Gl1_Capsule.smooth=True

Tip

Report issues or inclarities to github.