Rods#
Base class for rods
- class elastica.rod.rod_base.RodBase[source]#
Base class for all rods.
Notes
All new rod classes must be derived from this RodBase class.
Cosserat Rod#
On Nodes (+1) |
On Elements (n_elements) |
On Voronoi (-1) |
|
|---|---|---|---|
Geometry |
position |
director, tangents
length, rest_length
radius
volume
dilatation
|
rest voronoi length
voronoi dilatation
|
Kinematics |
velocity
acceleration
external forces
damping forces
|
angular velocity (omega)
angular acceleration (alpha)
mass second moment of inertia
+inverse
dilatation rates
external torques
damping torques
|
|
Elasticity |
internal forces |
shear matrix (modulus)
shear/stretch strain (sigma)
rest shear/stretch strain
internal torques
internal stress
|
bend matrix (modulus)
bend/twist strain (kappa)
rest bend/twist strain
internal couple
|
Material |
mass |
density
dissipation constant (force, torque)
|
Rod classes and implementation details
- class elastica.rod.cosserat_rod.CosseratRod(n_elements, position, velocity, omega, acceleration, angular_acceleration, directors, radius, mass_second_moment_of_inertia, inv_mass_second_moment_of_inertia, shear_matrix, bend_matrix, density_array, volume, mass, internal_forces, internal_torques, external_forces, external_torques, lengths, rest_lengths, tangents, dilatation, dilatation_rate, voronoi_dilatation, rest_voronoi_lengths, sigma, kappa, rest_sigma, rest_kappa, internal_stress, internal_couple, ring_rod_flag)[source]#
Cosserat Rod class. This is the preferred class for rods because it is derived from some of the essential base classes.
- Attributes:
- n_elems: int
The number of elements of the rod.
- position_collection: NDArray[np.float64]
2D (dim, n_nodes) array containing data with ‘float’ type. Array containing node position vectors.
- velocity_collection: NDArray[np.float64]
2D (dim, n_nodes) array containing data with ‘float’ type. Array containing node velocity vectors.
- acceleration_collection: NDArray[np.float64]
2D (dim, n_nodes) array containing data with ‘float’ type. Array containing node acceleration vectors.
- omega_collection: NDArray[np.float64]
2D (dim, n_elems) array containing data with ‘float’ type. Array containing element angular velocity vectors.
- alpha_collection: NDArray[np.float64]
2D (dim, n_elems) array containing data with ‘float’ type. Array contining element angular acceleration vectors.
- director_collection: NDArray[np.float64]
3D (dim, dim, n_elems) array containing data with ‘float’ type. Array containing element director matrices.
- rest_lengths: NDArray[np.float64]
1D (n_elems) array containing data with ‘float’ type. Rod element lengths at rest configuration.
- density: NDArray[np.float64]
1D (n_elems) array containing data with ‘float’ type. Rod elements densities.
- volume: NDArray[np.float64]
1D (n_elems) array containing data with ‘float’ type. Rod element volumes.
- mass: NDArray[np.float64]
1D (n_nodes) array containing data with ‘float’ type. Rod node masses. Note that masses are stored on the nodes, not on elements.
- mass_second_moment_of_inertia: NDArray[np.float64]
3D (dim, dim, n_elems) array containing data with ‘float’ type. Rod element mass second moment of interia.
- inv_mass_second_moment_of_inertia: NDArray[np.float64]
3D (dim, dim, n_elems) array containing data with ‘float’ type. Rod element inverse mass moment of inertia.
- rest_voronoi_lengths: NDArray[np.float64]
1D (n_voronoi) array containing data with ‘float’ type. Rod lengths on the voronoi domain at the rest configuration.
- internal_forces: NDArray[np.float64]
2D (dim, n_nodes) array containing data with ‘float’ type. Rod node internal forces. Note that internal forces are stored on the node, not on elements.
- internal_torques: NDArray[np.float64]
2D (dim, n_elems) array containing data with ‘float’ type. Rod element internal torques.
- external_forces: NDArray[np.float64]
2D (dim, n_nodes) array containing data with ‘float’ type. External forces acting on rod nodes.
- external_torques: NDArray[np.float64]
2D (dim, n_elems) array containing data with ‘float’ type. External torques acting on rod elements.
- lengths: NDArray[np.float64]
1D (n_elems) array containing data with ‘float’ type. Rod element lengths.
- tangents: NDArray[np.float64]
2D (dim, n_elems) array containing data with ‘float’ type. Rod element tangent vectors.
- radius: NDArray[np.float64]
1D (n_elems) array containing data with ‘float’ type. Rod element radius.
- dilatation: NDArray[np.float64]
1D (n_elems) array containing data with ‘float’ type. Rod element dilatation.
- voronoi_dilatation: NDArray[np.float64]
1D (n_voronoi) array containing data with ‘float’ type. Rod dilatation on voronoi domain.
- dilatation_rate: NDArray[np.float64]
1D (n_elems) array containing data with ‘float’ type. Rod element dilatation rates.
- classmethod straight_rod(n_elements, start, direction, normal, base_length, base_radius, density, *, nu=None, youngs_modulus, **kwargs)[source]#
Cosserat rod constructor for straight-rod geometry.
- Return type:
Self- Parameters:
- n_elementsint
Number of element. Must be greater than 3. Generally recommended to start with 40-50, and adjust the resolution.
- startNDArray[np.float64]
Starting coordinate in 3D
- directionNDArray[np.float64]
Direction of the rod in 3D
- normalNDArray[np.float64]
Normal vector of the rod in 3D
- base_lengthfloat
Total length of the rod
- base_radiusfloat
Uniform radius of the rod
- densityfloat
Density of the rod
- nufloat
Damping coefficient for Rayleigh damping
- youngs_modulusfloat
Young’s modulus
- **kwargsdict, optional
The “position” and/or “directors” can be overrided by passing “position” and “directors” argument. Remember, the shape of the “position” is (3,n_elements+1) and the shape of the “directors” is (3,3,n_elements).
- Returns:
- CosseratRod
Notes
Since we expect the Cosserat Rod to simulate soft rod, Poisson’s ratio is set to 0.5 by default. It is possible to give additional argument “shear_modulus” or “poisson_ratio” to specify extra modulus.
- classmethod ring_rod(n_elements, ring_center_position, direction, normal, base_length, base_radius, density, *, nu=None, youngs_modulus, **kwargs)[source]#
Cosserat rod constructor for straight-rod geometry.
- Return type:
Self- Parameters:
- n_elementsint
Number of element. Must be greater than 3. Generarally recommended to start with 40-50, and adjust the resolution.
- ring_center_positionNDArray[np.float64]
Center coordinate for ring rod in 3D
- directionNDArray[np.float64]
Direction of the rod in 3D
- normalNDArray[np.float64]
Normal vector of the rod in 3D
- base_lengthfloat
Total length of the rod
- base_radiusfloat
Uniform radius of the rod
- densityfloat
Density of the rod
- nufloat | None
Damping coefficient for Rayleigh damping
- youngs_modulusfloat
Young’s modulus
- **kwargsdict, optional
The “position” and/or “directors” can be overrided by passing “position” and “directors” argument. Remember, the shape of the “position” is (3,n_elements+1) and the shape of the “directors” is (3,3,n_elements).
- Returns:
- CosseratRod
Notes
Since we expect the Cosserat Rod to simulate soft rod, Poisson’s ratio is set to 0.5 by default. It is possible to give additional argument “shear_modulus” or “poisson_ratio” to specify extra modulus.
- compute_translational_energy()[source]#
Compute total translational energy of the rod at the instance.
- Return type:
ndarray[Any,dtype[float64]]
- compute_rotational_energy()[source]#
Compute total rotational energy of the rod at the instance.
- Return type:
ndarray[Any,dtype[float64]]
- compute_velocity_center_of_mass()[source]#
Compute velocity center of mass of the rod at the instance.
- Return type:
ndarray[Any,dtype[float64]]
- compute_position_center_of_mass()[source]#
Compute position center of mass of the rod at the instance.
- Return type:
ndarray[Any,dtype[float64]]
- compute_bending_energy()[source]#
Compute total bending energy of the rod at the instance.
- Return type:
ndarray[Any,dtype[float64]]
- compute_shear_energy()[source]#
Compute total shear energy of the rod at the instance.
- Return type:
ndarray[Any,dtype[float64]]
- compute_link(type_of_additional_segment='next_tangent', alpha=1.0)#
See Knot Theory (Mixin) for the detail.
- Return type:
ndarray[Any,dtype[float64]]- Parameters:
- type_of_additional_segmentstr
Determines the method to compute new segments (elements) added to the rod. Valid inputs are “next_tangent”, “end_to_end”, “net_tangent”, otherwise program uses the center line.
- alphafloat
Empirical factor to scale the segment length, where segment length is the rest length of the rod. Depending on the error between Lk-(Tw+Wr), alpha value can be increased to reduce the error. Default is 1.0.
- compute_twist()#
See Knot Theory (Mixin) for the detail.
- Return type:
ndarray[Any,dtype[float64]]
- compute_writhe(type_of_additional_segment='next_tangent', alpha=1.0)#
See Knot Theory (Mixin) for the detail.
- Return type:
ndarray[Any,dtype[float64]]- Parameters:
- type_of_additional_segmentstr
Determines the method to compute new segments (elements) added to the rod. Valid inputs are “next_tangent”, “end_to_end”, “net_tangent”, otherwise program uses the center line.
- alphafloat
Empirical factor to scale the segment length, where segment length is the rest length of the rod. Depending on the error between Lk-(Tw+Wr), alpha value can be increased to reduce the error. Default is 1.0.
Knot Theory (Mixin)#
This script is for computing the link-writhe-twist (LWT) of a rod using the method from Klenin & Langowski 2000 paper. Algorithms are adapted from section S2 of Charles et. al. PRL 2019 paper.
Following example cases includes computing LWT quantities to study the bifurcation:
The details discussion is included in N Charles et. al. PRL (2019).
- class elastica.rod.knot_theory.KnotTheory[source]#
This mixin should be used in RodBase-derived class that satisfies KnotCompatibleProtocol. The theory behind this module is based on the method from Klenin & Langowski 2000 paper.
KnotTheory can be mixed with any rod-class based on RodBase:
class MyRod(RodBase, KnotTheory): def __init__(self) -> None: super().__init__() rod = MyRod(...) total_twist = rod.compute_twist() total_link = rod.compute_link()
There are few alternative way of handling edge-condition in computing Link and Writhe. Here, we provide three methods: “next_tangent”, “end_to_end”, and “net_tangent”. The default type_of_additional_segment is set to “next_tangent.”
type_of_additional_segment
Description
next_tangent
Adds a two new point at the begining and end of the center line.Distance of these points are given in segment_length.Direction of these points are computed using the rod tangents atthe begining and end.end_to_end
Adds a two new point at the begining and end of the center line.Distance of these points are given in segment_length.Direction of these points are computed using the rod node endpositions.net_tangent
Adds a two new point at the begining and end of the center line.Distance of these points are given in segment_length. Direction ofthese points are point wise avarege of nodes at the first andsecond half of the rod.- compute_twist()[source]#
See Knot Theory (Mixin) for the detail.
- Return type:
ndarray[Any,dtype[float64]]
- compute_writhe(type_of_additional_segment='next_tangent', alpha=1.0)[source]#
See Knot Theory (Mixin) for the detail.
- Return type:
ndarray[Any,dtype[float64]]- Parameters:
- type_of_additional_segmentstr
Determines the method to compute new segments (elements) added to the rod. Valid inputs are “next_tangent”, “end_to_end”, “net_tangent”, otherwise program uses the center line.
- alphafloat
Empirical factor to scale the segment length, where segment length is the rest length of the rod. Depending on the error between Lk-(Tw+Wr), alpha value can be increased to reduce the error. Default is 1.0.
- compute_link(type_of_additional_segment='next_tangent', alpha=1.0)[source]#
See Knot Theory (Mixin) for the detail.
- Return type:
ndarray[Any,dtype[float64]]- Parameters:
- type_of_additional_segmentstr
Determines the method to compute new segments (elements) added to the rod. Valid inputs are “next_tangent”, “end_to_end”, “net_tangent”, otherwise program uses the center line.
- alphafloat
Empirical factor to scale the segment length, where segment length is the rest length of the rod. Depending on the error between Lk-(Tw+Wr), alpha value can be increased to reduce the error. Default is 1.0.
- elastica.rod.knot_theory.compute_twist(center_line, normal_collection)[source]#
Compute the twist of a rod, using center_line and normal collection.
Methods used in this function is adapted from method 2a Klenin & Langowski 2000 paper. :rtype:
tuple[ndarray[Any,dtype[float64]],ndarray[Any,dtype[float64]]]Warning
If center line is straight, although the normals of each element is pointing different direction computed twist will be zero.
Typical runtime of this function is longer than simulation steps. While we provide a function to compute topological quantities at every timesteps, we highly recommend to compute LWT during the post-processing stage.:
import elastica ... normal_collection = director_collection[:,0,...] # shape of director (time, 3, 3, n_elems) elastica.compute_twist( center_line, # shape (time, 3, n_nodes) normal_collection # shape (time, 3, n_elems) )
- Parameters:
- center_linenumpy.ndarray
3D (time, 3, n_nodes) array containing data with ‘float’ type. Time history of rod node positions.
- normal_collectionnumpy.ndarray
3D (time, 3, n_elems) array containing data with ‘float’ type. Time history of rod elements normal direction.
- Returns:
- total_twistnumpy.ndarray
- local_twistnumpy.ndarray
- elastica.rod.knot_theory.compute_writhe(center_line, segment_length, type_of_additional_segment)[source]#
This function computes the total writhe history of a rod.
Equations used are from method 1a from Klenin & Langowski 2000 paper.
Typical runtime of this function is longer than simulation steps. While we provide a function to compute topological quantities at every timesteps, we highly recommend to compute LWT during the post-processing stage.:
import elastica ... elastica.compute_writhe( center_line, # shape (time, 3, n_nodes) segment_length, type_of_additional_segment="next_tangent" )
- Return type:
ndarray[Any,dtype[float64]]- Parameters:
- center_linenumpy.ndarray
3D (time, 3, n_nodes) array containing data with ‘float’ type. Time history of rod node positions.
- segment_lengthfloat
Length of added segments.
- type_of_additional_segmentstr
Determines the method to compute new segments (elements) added to the rod. Valid inputs are “next_tangent”, “end_to_end”, “net_tangent”, otherwise program uses the center line.
- Returns:
- total_writhenumpy.ndarray
- elastica.rod.knot_theory.compute_link(center_line, normal_collection, radius, segment_length, type_of_additional_segment)[source]#
This function computes the total link history of a rod.
Equations used are from method 1a from Klenin & Langowski 2000 paper.
Typical runtime of this function is longer than simulation steps. While we provide a function to compute topological quantities at every timesteps, we highly recommend to compute LWT during the post-processing stage.:
import elastica ... normal_collection = director_collection[:,0,...] # shape of director (time, 3, 3, n_elems) elastica.compute_link( center_line, # shape (time, 3, n_nodes) normal_collection, # shape (time 3, n_elems) radius, # shape (time, n_elems) segment_length, type_of_additional_segment="next_tangent" )
- Return type:
ndarray[Any,dtype[float64]]- Parameters:
- center_linenumpy.ndarray
3D (time, 3, n_nodes) array containing data with ‘float’ type. Time history of rod node positions.
- normal_collectionnumpy.ndarray
3D (time, 3, n_elems) array containing data with ‘float’ type. Time history of rod elements normal direction.
- radiusnumpy.ndarray
2D (time, n_elems) array containing data with ‘float’ type. Time history of rod element radius.
- segment_lengthfloat
Length of added segments.
- type_of_additional_segmentstr
Determines the method to compute new segments (elements) added to the rod. Valid inputs are “next_tangent”, “end_to_end”, “net_tangent”, otherwise program uses the center line.
- Returns:
- total_linknumpy.ndarray