Skip to content

Commit da2037a

Browse files
authored
Update ExternalFieldWall.h
Added cylinder-spheropolyhedra overlap method
1 parent 3ce1ebc commit da2037a

File tree

1 file changed

+80
-0
lines changed

1 file changed

+80
-0
lines changed

hoomd/hpmc/ExternalFieldWall.h

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,86 @@ inline bool test_confined(const CylinderWall& wall,
481481
return accept;
482482
}
483483

484+
// Cylindrical Walls and Convex Spheropolyhedra
485+
DEVICE inline bool test_confined(const CylinderWall& wall,
486+
const ShapeSpheropolyhedron& shape,
487+
const vec3<Scalar>& position,
488+
const vec3<Scalar>& box_origin,
489+
const BoxDim& box)
490+
{
491+
bool accept = true;
492+
Scalar3 t = vec_to_scalar3(position - box_origin);
493+
t.x = t.x - wall.origin.x;
494+
t.y = t.y - wall.origin.y;
495+
t.z = t.z - wall.origin.z;
496+
vec3<Scalar> shifted_pos(box.minImage(t));
497+
498+
vec3<Scalar> dist_vec
499+
= cross(shifted_pos,
500+
wall.orientation); // find the component of the shifted position that is
501+
// perpendicular to the normalized orientation vector
502+
Scalar max_dist = sqrt(dot(dist_vec, dist_vec));
503+
if (wall.inside)
504+
{
505+
max_dist += (shape.getCircumsphereDiameter() / Scalar(2.0));
506+
}
507+
else
508+
{
509+
max_dist -= (shape.getCircumsphereDiameter() / Scalar(2.0));
510+
if (max_dist < 0)
511+
{
512+
max_dist = 0;
513+
}
514+
515+
}
516+
517+
bool check_verts
518+
= wall.inside ? (wall.rsq <= max_dist * max_dist)
519+
: (wall.rsq >= max_dist * max_dist); // condition to check vertices, dependent
520+
// on inside or outside container
521+
522+
if (check_verts)
523+
{
524+
if (shape.verts.N)
525+
{
526+
if (wall.inside)
527+
{
528+
for (unsigned int v = 0; v < shape.verts.N && accept; v++)
529+
{
530+
vec3<Scalar> pos(shape.verts.x[v], shape.verts.y[v], shape.verts.z[v]);
531+
vec3<Scalar> rotated_pos = rotate(shape.orientation, pos);
532+
rotated_pos += shifted_pos;
533+
534+
dist_vec = cross(rotated_pos, wall.orientation);
535+
max_dist = sqrt(dot(dist_vec, dist_vec));
536+
Scalar max_tot_dist = max_dist + shape.verts.sweep_radius;
537+
538+
accept = wall.inside ? (wall.rsq > max_tot_dist * max_tot_dist)
539+
: (wall.rsq < max_tot_dist * max_tot_dist);
540+
}
541+
}
542+
else
543+
{
544+
// build a sphero-polyhedron and for the wall and the convex polyhedron
545+
quat<Scalar> q; // default is (1, 0, 0, 0)
546+
unsigned int err = 0;
547+
ShapeSpheropolyhedron wall_shape(q, *wall.verts);
548+
ShapeSpheropolyhedron part_shape(shape.orientation, shape.verts);
549+
550+
accept = !test_overlap(shifted_pos, wall_shape, part_shape, err);
551+
}
552+
}
553+
// Edge case; pure sphere. In this case, check_verts implies that the
554+
// sphere will be outside.
555+
// Note from gabs: I don't fully understand this edge case
556+
else
557+
{
558+
accept = false;
559+
}
560+
}
561+
return accept;
562+
}
563+
484564
// Plane Walls and Spheres
485565
template<>
486566
inline bool test_confined<PlaneWall, ShapeSphere>(const PlaneWall& wall,

0 commit comments

Comments
 (0)