Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hollowconical Frustum with cutout #4179

Merged
merged 15 commits into from
Apr 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion doc/sphinx/constraints.rst
Original file line number Diff line number Diff line change
Expand Up @@ -440,14 +440,20 @@ HollowConicalFrustum

:class:`espressomd.shapes.HollowConicalFrustum`

A hollow cone with round corners. The specific parameters
A hollow cone with round corners.
Can include an opening in the side (see figures below). The specific parameters
are described in the shape's class :class:`espressomd.shapes.HollowConicalFrustum`.

.. figure:: figures/shape-conical_frustum.png
:alt: Visualization of a constraint with a HollowConicalFrustum shape.
:align: center
:height: 6.00000cm

.. figure:: figures/shape-hollowconicalfrustum_central_angle.png
:alt: Visualization a HollowConicalFrustum shape with central angle
:align: center
:height: 6.00000cm

.. figure:: figures/conical_frustum.png
:alt: Schematic for the HollowConicalFrustum shape with labeled geometrical parameters.
:align: center
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
from espressomd import lb
from espressomd.lbboundaries import LBBoundary
import espressomd.shapes

import espressomd.math

# Setup constants

Expand Down Expand Up @@ -90,9 +90,12 @@
ORAD = (DIAMETER - IRAD) / np.sin(ANGLE)
SHIFT = 0.25 * ORAD * np.cos(ANGLE)

ctp = espressomd.math.CylindricalTransformationParameters(
axis=[-1, 0, 0], center=[BOX_L[0] / 2.0 - 1.3 * SHIFT, BOX_L[1] / 2.0, BOX_L[2] / 2.0])

hollow_cone = LBBoundary(shape=espressomd.shapes.HollowConicalFrustum(
center=[BOX_L[0] / 2.0 - 1.3 * SHIFT, BOX_L[1] / 2.0, BOX_L[2] / 2.0],
axis=[-1, 0, 0], r1=ORAD, r2=IRAD, thickness=2.0, length=18,
cyl_transform_params=ctp,
r1=ORAD, r2=IRAD, thickness=2.0, length=18,
direction=1))
system.lbboundaries.add(hollow_cone)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import espressomd
from espressomd import assert_features
import espressomd.shapes
import espressomd.math


assert_features(["ENGINE", "LENNARD_JONES", "ROTATION", "MASS"])
Expand Down Expand Up @@ -119,6 +120,7 @@ def a2quat(phi, theta):
system.constraints.add(shape=wall, particle_type=1)

# Setup cone
ctp = espressomd.math.CylindricalTransformationParameters(...)
hollow_cone = espressomd.shapes.HollowConicalFrustum(...)
system.constraints.add(shape=hollow_cone, particle_type=1)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
from espressomd import lb
from espressomd.lbboundaries import LBBoundary
import espressomd.shapes
import espressomd.math


# Setup constants
Expand Down Expand Up @@ -91,9 +92,12 @@
ORAD = (DIAMETER - IRAD) / np.sin(ANGLE)
SHIFT = 0.25 * ORAD * np.cos(ANGLE)

ctp = espressomd.math.CylindricalTransformationParameters(
axis=[-1, 0, 0], center=[BOX_L[0] / 2.0 - 1.3 * SHIFT, BOX_L[1] / 2.0, BOX_L[2] / 2.0])

hollow_cone = LBBoundary(shape=espressomd.shapes.HollowConicalFrustum(
center=[BOX_L[0] / 2.0 - 1.3 * SHIFT, BOX_L[1] / 2.0, BOX_L[2] / 2.0],
axis=[-1, 0, 0], r1=ORAD, r2=IRAD, thickness=2.0, length=18,
cyl_transform_params=ctp,
r1=ORAD, r2=IRAD, thickness=2.0, length=18,
direction=1))
system.lbboundaries.add(hollow_cone)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import espressomd
from espressomd import assert_features
import espressomd.shapes
import espressomd.math


assert_features(["ENGINE", "LENNARD_JONES", "ROTATION", "MASS"])
Expand Down Expand Up @@ -118,9 +119,12 @@ def a2quat(phi, theta):
ORAD = (DIAMETER - IRAD) / np.sin(ANGLE)
SHIFT = 0.25 * ORAD * np.cos(ANGLE)

ctp = espressomd.math.CylindricalTransformationParameters(
axis=[-1, 0, 0], center=[BOX_L[0] / 2.0 - 1.3 * SHIFT, BOX_L[1] / 2.0, BOX_L[2] / 2.0])

hollow_cone = espressomd.shapes.HollowConicalFrustum(
center=[BOX_L[0] / 2.0 - 1.3 * SHIFT, BOX_L[1] / 2.0, BOX_L[2] / 2.0],
axis=[-1, 0, 0], r1=ORAD, r2=IRAD, thickness=2.0, length=18,
cyl_transform_params=ctp,
r1=ORAD, r2=IRAD, thickness=2.0, length=18,
direction=1)
system.constraints.add(shape=hollow_cone, particle_type=1)

Expand Down
5 changes: 4 additions & 1 deletion samples/visualization_constraints.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import argparse

import espressomd
import espressomd.math
import espressomd.shapes
import espressomd.visualization_opengl

Expand Down Expand Up @@ -96,9 +97,11 @@
particle_type=0, penetrable=True)

elif args.shape == "HollowConicalFrustum":
ctp = espressomd.math.CylindricalTransformationParameters(
axis=1 / np.sqrt(2) * np.array([0.0, 1.0, 1.0]), center=[25, 25, 25], orientation=[1, 0, 0])
system.constraints.add(shape=espressomd.shapes.HollowConicalFrustum(
r1=12, r2=8, length=15.0, thickness=3,
axis=[0.0, 1.0, 1.0], center=[25, 25, 25], direction=1),
cyl_transform_params=ctp, direction=1, central_angle=np.pi / 2),
particle_type=0, penetrable=True)

elif args.shape == "Torus":
Expand Down
5 changes: 5 additions & 0 deletions src/python/espressomd/math.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,10 @@ class CylindricalTransformationParameters(ScriptInterfaceHelper):
Orientation vector of the ``z``-axis of the cylindrical coordinate system.
orientation: (3,) array_like of :obj:`float`, default = [1, 0, 0]
The axis on which ``phi = 0``.

Notes
-----
If you provide no arguments, the defaults above are set.
If you provide only a ``center`` and an ``axis``, an ``orientation`` will be automatically generated that is orthogonal to ``axis``.
"""
_so_name = "CylindricalTransformationParameters"
13 changes: 9 additions & 4 deletions src/python/espressomd/shapes.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,16 +231,21 @@ class HollowConicalFrustum(Shape, ScriptInterfaceHelper):

Attributes
----------
cyl_transform_params : :class:`espressomd.math.CylindricalTransformationParameters`,
Parameters of the spacial orientation of the frustum. Contained must be parameters for ``center`` and ``axis``. ``orientation`` has no effect, unless ``central_angle != 0``
r1: :obj:`float`
Radius r1.
r2: :obj:`float`
Radius r2.
length: :obj:`float`
Length of the conical frustum along ``axis``.
axis: (3,) array_like of :obj:`float`
Symmetry axis.
center: (3,) array_like of :obj:`float`
Position of the center.
thickness: float
The thickness of the frustum. Also determines the rounding radius of the edges
direction: :obj:`int`, optional
Surface orientation, for +1 the normal points
out of the mantel, for -1 it points inside of the shape. Defaults to 1
cantral_angle: :obj:`float`, optional
A ``central_angle`` creates an opening in the frustum along the side, centered symmetrically around the ``direction`` of ``cyl_transform_params``. Must be between ``0`` and ``2 pi``. Defaults to 0.


.. image:: figures/conical_frustum.png
Expand Down
17 changes: 10 additions & 7 deletions src/python/espressomd/visualization_opengl.py
Original file line number Diff line number Diff line change
Expand Up @@ -1977,20 +1977,23 @@ def __init__(self, shape, particle_type, color, material,
quality, box_l, rasterize_resolution, rasterize_pointsize):
super().__init__(shape, particle_type, color, material,
quality, box_l, rasterize_resolution, rasterize_pointsize)
self.center = np.array(self.shape.get_parameter('center'))
self.radius_1 = np.array(self.shape.get_parameter('r1'))
self.radius_2 = np.array(self.shape.get_parameter('r2'))
self.length = np.array(self.shape.get_parameter('length'))
self.thickness = np.array(self.shape.get_parameter('thickness'))
self.axis = np.array(self.shape.get_parameter('axis'))
ctp = self.shape.get_parameter('cyl_transform_params')
self.center = np.array(ctp.center)
self.axis = np.array(ctp.axis)
self.orientation = np.array(ctp.orientation)
self.radius_1 = self.shape.get_parameter('r1')
self.radius_2 = self.shape.get_parameter('r2')
self.length = self.shape.get_parameter('length')
self.thickness = self.shape.get_parameter('thickness')
self.central_angle = self.shape.get_parameter('central_angle')

def draw(self):
"""
Draw using OpenGL Extrusion library, if available.
Use rasterization of base class, otherwise.

"""
if bool(OpenGL.GLE.gleSpiral):
if bool(OpenGL.GLE.gleSpiral) and self.central_angle == 0.:
self._draw_using_gle()
else:
super().draw()
Expand Down
33 changes: 25 additions & 8 deletions src/script_interface/CylindricalTransformationParameters.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#ifndef SCRIPT_INTERFACE_CYL_TRANSFORM_PARAMS_HPP
#define SCRIPT_INTERFACE_CYL_TRANSFORM_PARAMS_HPP

#include <stdexcept>

#include "script_interface/ScriptInterface.hpp"

#include "utils/math/cylindrical_transformation_parameters.hpp"
Expand All @@ -44,14 +46,29 @@ class CylindricalTransformationParameters
return m_transform_params;
}
void do_construct(VariantMap const &params) override {
m_transform_params =
std::make_shared<Utils::CylindricalTransformationParameters>(
get_value_or<Utils::Vector3d>(params, "center",
Utils::Vector3d{{0, 0, 0}}),
get_value_or<Utils::Vector3d>(params, "axis",
Utils::Vector3d{{0, 0, 1}}),
get_value_or<Utils::Vector3d>(params, "orientation",
Utils::Vector3d{{1, 0, 0}}));
auto n_params = params.size();
switch (n_params) {
case 0:
m_transform_params =
std::make_shared<Utils::CylindricalTransformationParameters>();
break;
case 2:
m_transform_params =
std::make_shared<Utils::CylindricalTransformationParameters>(
get_value<Utils::Vector3d>(params, "center"),
get_value<Utils::Vector3d>(params, "axis"));
break;
case 3:
m_transform_params =
std::make_shared<Utils::CylindricalTransformationParameters>(
get_value<Utils::Vector3d>(params, "center"),
get_value<Utils::Vector3d>(params, "axis"),
get_value<Utils::Vector3d>(params, "orientation"));
break;
default:
throw std::runtime_error("Provide either no arguments, center and axis, "
"or center and axis and orientation");
}
}

private:
Expand Down
39 changes: 26 additions & 13 deletions src/script_interface/shapes/HollowConicalFrustum.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,26 +20,17 @@
#ifndef ESPRESSO_HOLLOW_CONICAL_FRUSTUM_HPP
#define ESPRESSO_HOLLOW_CONICAL_FRUSTUM_HPP
#include "Shape.hpp"
#include <script_interface/CylindricalTransformationParameters.hpp>
#include <shapes/HollowConicalFrustum.hpp>

namespace ScriptInterface {
namespace Shapes {

class HollowConicalFrustum : public Shape {
public:
HollowConicalFrustum()
: m_hollow_conical_frustum(new ::Shapes::HollowConicalFrustum()) {
HollowConicalFrustum() {
add_parameters(
{{"center",
[this](Variant const &v) {
m_hollow_conical_frustum->set_center(get_value<Utils::Vector3d>(v));
},
[this]() { return m_hollow_conical_frustum->center(); }},
{"axis",
[this](Variant const &v) {
m_hollow_conical_frustum->set_axis(get_value<Utils::Vector3d>(v));
},
[this]() { return m_hollow_conical_frustum->axis(); }},
{{"cyl_transform_params", m_cyl_transform_params},
{"r1",
[this](Variant const &v) {
m_hollow_conical_frustum->set_r1(get_value<double>(v));
Expand All @@ -64,7 +55,28 @@ class HollowConicalFrustum : public Shape {
[this](Variant const &v) {
m_hollow_conical_frustum->set_direction(get_value<int>(v));
},
[this]() { return m_hollow_conical_frustum->direction(); }}});
[this]() { return m_hollow_conical_frustum->direction(); }},
{"central_angle",
[this](Variant const &v) {
m_hollow_conical_frustum->set_central_angle(get_value<double>(v));
},
[this]() { return m_hollow_conical_frustum->central_angle(); }}});
}

void do_construct(VariantMap const &params) override {
set_from_args(m_cyl_transform_params, params, "cyl_transform_params");

if (m_cyl_transform_params)
m_hollow_conical_frustum =
std::make_shared<::Shapes::HollowConicalFrustum>(
get_value<double>(params, "r1"), get_value<double>(params, "r2"),
get_value<double>(params, "length"),
get_value_or<double>(params, "thickness", 0.),
get_value_or<int>(params, "direction", 1),
get_value_or<double>(params, "central_angle", 0.),
m_cyl_transform_params->cyl_transform_params()

);
}

std::shared_ptr<::Shapes::Shape> shape() const override {
Expand All @@ -73,6 +85,7 @@ class HollowConicalFrustum : public Shape {

private:
std::shared_ptr<::Shapes::HollowConicalFrustum> m_hollow_conical_frustum;
std::shared_ptr<CylindricalTransformationParameters> m_cyl_transform_params;
};

} /* namespace Shapes */
Expand Down
43 changes: 21 additions & 22 deletions src/shapes/include/shapes/HollowConicalFrustum.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@
#define SHAPES_CONICAL_FRUSTUM_HPP

#include "Shape.hpp"
#include "utils/math/cylindrical_transformation_parameters.hpp"
#include <utils/Vector.hpp>
#include <utils/math/orthonormal_vec.hpp>

#include <list>
#include <memory>
#include <utility>

namespace Shapes {

Expand All @@ -48,40 +50,37 @@ namespace Shapes {
*/
class HollowConicalFrustum : public Shape {
public:
HollowConicalFrustum()
: m_r1(0.0), m_r2(0.0), m_length(0.0), m_thickness(0.0),
m_direction(1), m_center{Utils::Vector3d{}}, m_axis{Utils::Vector3d{
0., 0., 1.}},
m_orientation{Utils::Vector3d{1., 0., 0.}} {}
HollowConicalFrustum(
double const r1, double const r2, double const length,
double const thickness, int const direction, double const central_angle,
std::shared_ptr<Utils::CylindricalTransformationParameters>
cyl_transform_params)
: m_r1(r1), m_r2(r2), m_length(length), m_thickness(thickness),
m_direction(direction), m_central_angle(central_angle),
m_cyl_transform_params(std::move(cyl_transform_params)) {}

void set_r1(double const radius) { m_r1 = radius; }
void set_r2(double const radius) { m_r2 = radius; }
void set_length(double const length) { m_length = length; }
void set_thickness(double const thickness) { m_thickness = thickness; }
void set_direction(int const dir) { m_direction = dir; }
void set_axis(Utils::Vector3d const &axis) {
m_axis = axis;
// Even though the HCF is cylinder-symmetric, it needs a well defined phi=0
// orientation for the coordinate transformation.
m_orientation = Utils::calc_orthonormal_vector(axis);
void set_central_angle(double const central_angle) {
m_central_angle = central_angle;
}
void set_center(Utils::Vector3d const &center) { m_center = center; }

/// Get radius 1 perpendicular to axis.
double radius1() const { return m_r1; }
/// Get radius 2 perpendicular to axis.
double radius2() const { return m_r2; }
/// Get length of the frustum (modulo thickness).
/// Get length of the frustum (without thickness).
double length() const { return m_length; }
/// Get thickness of the frustum.
double thickness() const { return m_thickness; }
/// Get the direction of the shape. If -1, distance is positive within the
/// enclosed volume of the frustum.
/// Get direction
int direction() const { return m_direction; }
/// Get center of symmetry.
Utils::Vector3d const &center() const { return m_center; }
/// Get symmetry axis.
Utils::Vector3d const &axis() const { return m_axis; }
/// Get central angle
double central_angle() const { return m_central_angle; }

/**
* @brief Calculate the distance vector and its norm between a given position
* and the cone.
Expand All @@ -98,9 +97,9 @@ class HollowConicalFrustum : public Shape {
double m_length;
double m_thickness;
int m_direction;
Utils::Vector3d m_center;
Utils::Vector3d m_axis;
Utils::Vector3d m_orientation;
double m_central_angle;
std::shared_ptr<Utils::CylindricalTransformationParameters>
m_cyl_transform_params;
};
} // namespace Shapes

Expand Down
Loading