Rods
Contents
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, volume, mass, dissipation_constant_for_forces, dissipation_constant_for_torques, 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, damping_forces, damping_torques)[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: numpy.ndarray
2D (dim, n_nodes) array containing data with ‘float’ type. Array containing node position vectors.
 velocity_collection: numpy.ndarray
2D (dim, n_nodes) array containing data with ‘float’ type. Array containing node velocity vectors.
 acceleration_collection: numpy.ndarray
2D (dim, n_nodes) array containing data with ‘float’ type. Array containing node acceleration vectors.
 omega_collection: numpy.ndarray
2D (dim, n_elems) array containing data with ‘float’ type. Array containing element angular velocity vectors.
 alpha_collection: numpy.ndarray
2D (dim, n_elems) array containing data with ‘float’ type. Array contining element angular acceleration vectors.
 director_collection: numpy.ndarray
3D (dim, dim, n_elems) array containing data with ‘float’ type. Array containing element director matrices.
 rest_lengths: numpy.ndarray
1D (n_elems) array containing data with ‘float’ type. Rod element lengths at rest configuration.
 density: numpy.ndarray
1D (n_elems) array containing data with ‘float’ type. Rod elements densities.
 volume: numpy.ndarray
1D (n_elems) array containing data with ‘float’ type. Rod element volumes.
 mass: numpy.ndarray
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: numpy.ndarray
3D (dim, dim, n_elems) array containing data with ‘float’ type. Rod element mass second moment of interia.
 inv_mass_second_moment_of_inertia: numpy.ndarray
3D (dim, dim, n_elems) array containing data with ‘float’ type. Rod element inverse mass moment of inertia.
 dissipation_constant_for_forces: numpy.ndarray
1D (n_elems) array containing data with ‘float’ type. Rod element dissipation coefficient (nu).
 dissipation_constant_for_torques: numpy.ndarray
1D (n_elems) array containing data with ‘float’ type. Rod element dissipation (nu). Can be customized by passing ‘nu_for_torques’.
 rest_voronoi_lengths: numpy.ndarray
1D (n_voronoi) array containing data with ‘float’ type. Rod lengths on the voronoi domain at the rest configuration.
 internal_forces: numpy.ndarray
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: numpy.ndarray
2D (dim, n_elems) array containing data with ‘float’ type. Rod element internal torques.
 external_forces: numpy.ndarray
2D (dim, n_nodes) array containing data with ‘float’ type. External forces acting on rod nodes.
 external_torques: numpy.ndarray
2D (dim, n_elems) array containing data with ‘float’ type. External torques acting on rod elements.
 lengths: numpy.ndarray
1D (n_elems) array containing data with ‘float’ type. Rod element lengths.
 tangents: numpy.ndarray
2D (dim, n_elems) array containing data with ‘float’ type. Rod element tangent vectors.
 radius: numpy.ndarray
1D (n_elems) array containing data with ‘float’ type. Rod element radius.
 dilatation: numpy.ndarray
1D (n_elems) array containing data with ‘float’ type. Rod element dilatation.
 voronoi_dilatation: numpy.ndarray
1D (n_voronoi) array containing data with ‘float’ type. Rod dilatation on voronoi domain.
 dilatation_rate: numpy.ndarray
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, youngs_modulus, *args, **kwargs)[source]#
Cosserat rod constructor for straightrod geometry.
 Parameters
 n_elementsint
Number of element. Must be greater than 3. Generarally recommended to start with 4050, and adjust the resolution.
 startNDArray[3, float]
Starting coordinate in 3D
 directionNDArray[3, float]
Direction of the rod in 3D
 normalNDArray[3, float]
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
 *argstuple
Additional arguments should be passed as keyward arguments. (e.g. shear_modulus, poisson_ratio)
 **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.
 compute_velocity_center_of_mass()[source]#
Compute velocity center of mass of the rod at the instance.
 compute_position_center_of_mass()[source]#
Compute position center of mass of the rod at the instance.
 compute_link(type_of_additional_segment='next_tangent')#
See Knot Theory (Mixin) for the detail.
 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.
 compute_twist()#
See Knot Theory (Mixin) for the detail.
 compute_writhe(type_of_additional_segment='next_tangent')#
See Knot Theory (Mixin) for the detail.
 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.
Knot Theory (Mixin)#
This script is for computing the linkwrithetwist (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.KnotTheoryCompatibleProtocol(*args, **kwargs)[source]#
Required properties to use KnotTheory mixin
 class elastica.rod.knot_theory.KnotTheory[source]#
This mixin should be used in RodBasederived 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 rodclass based on RodBase:
class MyRod(RodBase, KnotTheory): def __init__(self): super().__init__() rod = MyRod(...) total_twist = rod.compute_twist() total_link = rod.compute_link()
There are few alternative way of handling edgecondition 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.
 compute_writhe(type_of_additional_segment='next_tangent')[source]#
See Knot Theory (Mixin) for the detail.
 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.
 compute_link(type_of_additional_segment='next_tangent')[source]#
See Knot Theory (Mixin) for the detail.
 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.
 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.
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 postprocessing 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_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 postprocessing 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" )
 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
 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 postprocessing stage.:
import elastica ... elastica.compute_writhe( center_line, # shape (time, 3, n_nodes) segment_length, type_of_additional_segment="next_tangent" )
 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