diff --git a/hoomd/hpmc/ExternalFieldWall.h b/hoomd/hpmc/ExternalFieldWall.h index 8c33bfcf49..2c51b83f27 100644 --- a/hoomd/hpmc/ExternalFieldWall.h +++ b/hoomd/hpmc/ExternalFieldWall.h @@ -481,6 +481,86 @@ inline bool test_confined(const CylinderWall& wall, return accept; } +// Cylindrical Walls and Convex Spheropolyhedra +DEVICE inline bool test_confined(const CylinderWall& wall, + const ShapeSpheropolyhedron& shape, + const vec3& position, + const vec3& box_origin, + const BoxDim& box) + { + bool accept = true; + Scalar3 t = vec_to_scalar3(position - box_origin); + t.x = t.x - wall.origin.x; + t.y = t.y - wall.origin.y; + t.z = t.z - wall.origin.z; + vec3 shifted_pos(box.minImage(t)); + + vec3 dist_vec + = cross(shifted_pos, + wall.orientation); // find the component of the shifted position that is + // perpendicular to the normalized orientation vector + Scalar max_dist = sqrt(dot(dist_vec, dist_vec)); + if (wall.inside) + { + max_dist += (shape.getCircumsphereDiameter() / Scalar(2.0)); + } + else + { + max_dist -= (shape.getCircumsphereDiameter() / Scalar(2.0)); + if (max_dist < 0) + { + max_dist = 0; + } + + } + + bool check_verts + = wall.inside ? (wall.rsq <= max_dist * max_dist) + : (wall.rsq >= max_dist * max_dist); // condition to check vertices, dependent + // on inside or outside container + + if (check_verts) + { + if (shape.verts.N) + { + if (wall.inside) + { + for (unsigned int v = 0; v < shape.verts.N && accept; v++) + { + vec3 pos(shape.verts.x[v], shape.verts.y[v], shape.verts.z[v]); + vec3 rotated_pos = rotate(shape.orientation, pos); + rotated_pos += shifted_pos; + + dist_vec = cross(rotated_pos, wall.orientation); + max_dist = sqrt(dot(dist_vec, dist_vec)); + Scalar max_tot_dist = max_dist + shape.verts.sweep_radius; + + accept = wall.inside ? (wall.rsq > max_tot_dist * max_tot_dist) + : (wall.rsq < max_tot_dist * max_tot_dist); + } + } + else + { + // build a sphero-polyhedron and for the wall and the convex polyhedron + quat q; // default is (1, 0, 0, 0) + unsigned int err = 0; + ShapeSpheropolyhedron wall_shape(q, *wall.verts); + ShapeSpheropolyhedron part_shape(shape.orientation, shape.verts); + + accept = !test_overlap(shifted_pos, wall_shape, part_shape, err); + } + } + // Edge case; pure sphere. In this case, check_verts implies that the + // sphere will be outside. + // Note from gabs: I don't fully understand this edge case + else + { + accept = false; + } + } + return accept; + } + // Plane Walls and Spheres template<> inline bool test_confined(const PlaneWall& wall, diff --git a/hoomd/hpmc/external/wall.py b/hoomd/hpmc/external/wall.py index ea8b33f5c0..952c5b414c 100644 --- a/hoomd/hpmc/external/wall.py +++ b/hoomd/hpmc/external/wall.py @@ -57,7 +57,10 @@ class _HPMCWallsMetaList(_WallsMetaList): hoomd.wall.Cylinder, hoomd.wall.Plane, ], - hpmc.integrate.ConvexSpheropolyhedron: [hoomd.wall.Sphere, hoomd.wall.Plane], + hpmc.integrate.ConvexSpheropolyhedron: [ + hoomd.wall.Sphere, + hoomd.wall.Cylinder, + hoomd.wall.Plane], } def _check_wall_compatibility(self, wall): diff --git a/hoomd/hpmc/integrate.py b/hoomd/hpmc/integrate.py index ffadcd42a0..9ad5cb8640 100644 --- a/hoomd/hpmc/integrate.py +++ b/hoomd/hpmc/integrate.py @@ -1676,8 +1676,7 @@ class ConvexSpheropolyhedron(HPMCIntegrator): .. rubric:: Wall support. - `ConvexSpheropolyhedron` supports the `hoomd.wall.Sphere` and - `hoomd.wall.Plane` geometries. + `ConvexSpheropolyhedron` supports all `hoomd.wall` geometries. Example::