rod::Rod_blob_interface Struct Reference

#include <rod_blob_interface.h>

Public Member Functions

 Rod_blob_interface (Rod *set_connected_rod, Blob *set_connected_blob, bool set_ends_at_rod, int set_to_index, int set_from_index, int face_nodes[3], float rotation[3], float node_weighting[3], int order)
 
void set_initial_values ()
 
void update_internal_state (bool update_edge_vecs, bool update_tet)
 
void update_J_0 ()
 
void set_edge_vecs ()
 
void get_attachment_node (OUT float attachment_node[3], float attachment_node_pos[3], bool equil)
 
void get_attachment_node_pos (float attachment_node_pos[3], bool equil)
 
void get_initial_material_axis ()
 
void get_attachment_material_axis (float attachment_node[3], OUT float attachment_material_axis[3])
 
void get_tet_rotation_matrix (float tet_points_before[12], float tet_points_after[12])
 
void make_tet ()
 
void set_tet (tetra_element_linear *tet)
 
void reorientate_connection (float attachment_element_orig[3], float attachment_material_axis_orig[3], OUT float new_attachment_element[3], float new_attachment_material_axis[3])
 
void position_rod_from_blob (bool use_equil)
 
void position_blob_from_rod ()
 
void get_face (OUT float face_node_1[3], float face_node_2[3], float face_node_3[3])
 
void select_face_nodes (OUT int face_node_indices[3])
 
int get_element_id (int nodes[3])
 
void get_node_energy (int node_index, float attachment_node_equil[3], float attachment_material_axis_equil[3], float attachment_node[3], float attachment_material_axis[3], float displacement, float energy[6])
 
void position_rod_ends (float attachment_node_pos[3])
 
void do_connection_timestep ()
 

Data Fields

Rodconnected_rod
 
Blobconnected_blob
 
Faceconnected_face
 
tetra_element_linearconnected_tet
 
bool ends_at_rod = true
 
int to_index
 
int from_index
 
int face_index
 
int order
 
int face_nodes [3]
 
float node_weighting [3] = {0.333333333333333, 0.333333333333333, 0.333333333333333}
 
float euler_angles [3] = {0, 0, 0}
 
float tet_origin [3]
 
float edge_vecs [3][3]
 
mesh_nodedeformed_tet_nodes [4]
 
int face_node_indices [3]
 
float J_inv_0 [9]
 
float attachment_node_equil [3]
 
float attachment_m_equil [3]
 
float attachment_node [3]
 
float attachment_node_pos [3]
 
float attachment_m [3]
 

Constructor & Destructor Documentation

◆ Rod_blob_interface()

rod::Rod_blob_interface::Rod_blob_interface ( Rod set_connected_rod,
Blob set_connected_blob,
bool  set_ends_at_rod,
int  set_to_index,
int  set_from_index,
int  blob_node_ids[3],
float  rotation[3],
float  node_weighting[3],
int  order 
)

Rod_blob_interface constructor. Requires pointers to fully-initialized rod and blob objects. Parameters:

  • set_ends_at_rod: if true, the connection goes from blob to rod. If false, it goes from rod to blob. This affects the index of the rod element which is connected.
  • set_to_index: index of the source element (via blob->get_element).
  • set_from_index: index of the destination element (via blob->get_element).
  • set_blob_node_ids: the indices of the three linear nodes on the blob which make up the face that the interface is orientated relative to.
  • rotation: an euler rotation matrix, which determines the rotation of the attachment element relative to the face it's attached to.
  • node_weighting: how much each of the first three edge vectors is weighted to determine the position of the attachment node inside the tetrahedron. You can also set them all to -1 to make the thing just go in the center of the element.
  • order: I think this is just here for reference, but it refers to the order the connection was resolved in (e.g. in a system of multiple connections, which one gets set up first) Anyway this is a boring constructor, all it does is set member variables, allocate a bit of memory for the internal tetrahedron, set the initial internal state (that's the edge vectors and internal tetrahedron) and set the indices of the face nodes relative to the tetrahedron.

Member Function Documentation

◆ do_connection_timestep()

void rod::Rod_blob_interface::do_connection_timestep ( )

This is the interface equivalent to the FFEA_rod 'do_timestep' function, and does largely the same things. 1) Update the geometric state of the interface to account for how the blob has moved. 2) Compute the energy gradient resulting from the interface at each tetrahedron node 3) Compute the force on each tetrahedron node as if it were a rod node, and apply that force to the node No params or return values for this one, though you need to have a correctly initialized rod-blob interface, which means you have to have run set_initial_values. In regular FFEA dynamics, this happens after the dynamics of the rod/blob, though it's kind of arbitrary when to run it.

Referenced by World::run().

◆ get_attachment_material_axis()

void rod::Rod_blob_interface::get_attachment_material_axis ( float  attachment_node[3],
OUT float  attachment_material_axis[3] 
)

Once the attachment node has been obtained, this sets the initial direction of the attachment material axis. Note that the initial direction is arbitray - by default it is set such that there is no energy between the attachment axis and the first rod material axis. Only run this function for initialisation! When the simulation is running, you need to update the orientation of this thing using this->reorientate_connection.

Referenced by ffea_test::connection_energy(), ffea_test::connection_energy_2(), ffea_test::connection_propagation(), ffea_test::connection_test(), and set_initial_values().

◆ get_attachment_node()

void rod::Rod_blob_interface::get_attachment_node ( OUT float  attachment_node[3],
float  attachment_node_pos[3],
bool  equil 
)

Get the position and direction vectors for the current attachment node. Note: this function is great for initialisation, but once the connection is initialised, there's no need to run this. Instead, use 'reorientate connection'. The reason is that this function sets the material axis arbitrarily, whereas reorientate_connection will update the material axis based on the rotation of the tetrahedorn.

Referenced by ffea_test::connection_energy(), ffea_test::connection_energy_2(), ffea_test::connection_propagation(), ffea_test::connection_test(), ffea_test::identify_face(), position_blob_from_rod(), position_rod_from_blob(), ffea_test::recover_normal(), and set_initial_values().

◆ get_attachment_node_pos()

void rod::Rod_blob_interface::get_attachment_node_pos ( float  attachment_node_pos[3],
bool  equil 
)

Get the position vector for the attachment node. Absolute, not relative to the tetrahedron or anything. Uses the weighting that the object was initialised with.

Referenced by do_connection_timestep(), get_node_energy(), and position_blob_from_rod().

◆ get_element_id()

int rod::Rod_blob_interface::get_element_id ( int  nodes[3])

Similar to the above function, but it instead gets the ID of an element given 3 nodes inside it.

Referenced by Rod_blob_interface().

◆ get_face()

void rod::Rod_blob_interface::get_face ( OUT float  face_node_1[3],
float  face_node_2[3],
float  face_node_3[3] 
)

◆ get_initial_material_axis()

void rod::Rod_blob_interface::get_initial_material_axis ( )

◆ get_node_energy()

void rod::Rod_blob_interface::get_node_energy ( int  node_index,
float  attachment_node_equil[3],
float  attachment_material_axis_equil[3],
float  attachment_node[3],
float  attachment_material_axis[3],
float  displacement,
float  energy[6] 
)

This is the rod-blob interface equivalent of get_perturbation_energy. It does one-half of the dynamics necessary for the connection to work, namely it works out the forces being transferred from the rod to the nodes of the connected tetrahedron. Params:

  • node_index, the index (relative to the element) of the node that we're getting the energies for
  • attachment_node_equil - equilibrium position of the attachment node (when I say 'equilibrium' I mean 'with the tetrahedron in its current state, unaltered')
  • attachment_material_axis - same, but material axis
  • displacement - how much the node is being moved. I would suggest this->connected_rod->perturbation_amount
  • energy - this is the output listing the energy associated with that perturbation in the following axes: [+x +y +z -x -y -z].

Referenced by ffea_test::connection_energy(), ffea_test::connection_energy_2(), ffea_test::connection_propagation(), and do_connection_timestep().

◆ get_tet_rotation_matrix()

void rod::Rod_blob_interface::get_tet_rotation_matrix ( float  tet_points_before[12],
float  tet_points_after[12] 
)

◆ make_tet()

void rod::Rod_blob_interface::make_tet ( )

◆ position_blob_from_rod()

void rod::Rod_blob_interface::position_blob_from_rod ( )

This one is fairly normal, in contrast to rod_form_blob. It gets the rotation matrix that aligns the attachment element with the rod element at the end of the rod, then applies that to the blob. Like position_rod_from_blob, it's called during initialisation from world.cpp.

Referenced by World::read_and_build_system().

◆ position_rod_ends()

void rod::Rod_blob_interface::position_rod_ends ( float  attachment_node_pos[3])

Fix the position of the final rod node at the interface node position. Also, update the material axis associated with the end element, the same way as it's done in the rod dynamics (using update_m1_matrix). The energies about this end node are actually what transmit forces from the blob to the rod, so they're important!

Referenced by do_connection_timestep(), and get_node_energy().

◆ position_rod_from_blob()

void rod::Rod_blob_interface::position_rod_from_blob ( bool  use_equil)

Initialisation function. This will set the position of the rod relative to the blob. For some reason, it does it in this really arcane way, in which it gets a rotation matrix to the attachment node, applies it to each node and then repositions each element at the end of the previous element. One parameter: use_equil, if true it'll do it for the equilibrium rod instead of the current rod. This member function is called from world.cpp during intialisation.

Referenced by World::read_and_build_system().

◆ reorientate_connection()

void rod::Rod_blob_interface::reorientate_connection ( float  attachment_element_orig[3],
float  attachment_material_axis_orig[3],
OUT float  new_attachment_element[3],
float  new_attachment_material_axis[3] 
)

For a given attachment element and material axis, get a new material axis and attachment element based on the rotation matrix found from the QR decomposition of the gradient deformation matrix. Run this every timestep!

Referenced by ffea_test::connection_test(), do_connection_timestep(), and get_node_energy().

◆ select_face_nodes()

void rod::Rod_blob_interface::select_face_nodes ( OUT int  face_node_indices[3])

Given the indices of the face nodes relative to the entire blob, this will give you the indices of the face nodes relative just to one tetrahedron. I say 'given indices of face nodes' but that's really given as a parameter in the constructor. Note: do not read the body of this function, just move on

Referenced by Rod_blob_interface().

◆ set_edge_vecs()

void rod::Rod_blob_interface::set_edge_vecs ( )

Recompute te edge vectors for a tetrahedron. These are not automatically updated when the nodes are moved. If you do something to the attachment tetrahedron, consider running Rod_blob_interface->update_internal_state().

Referenced by update_internal_state().

◆ set_initial_values()

void rod::Rod_blob_interface::set_initial_values ( )

◆ set_tet()

void rod::Rod_blob_interface::set_tet ( tetra_element_linear tet)

Overwrite the internal tetrahedron nodes with the nodes from a tetra_element_linear object. Only run this after the connection has been reorientated

Referenced by update_internal_state().

◆ update_internal_state()

void rod::Rod_blob_interface::update_internal_state ( bool  update_edge_vecs,
bool  update_tet 
)

Update the internal state of the rod-blob interface. The update_edge_vecs parameter will reconstruct the edges, which are need for certain mathematical operations, including updating the position of the attachment node. update_tet updates the cached tetrahedron object stored by the interface.

If you've deformed the tetrahedron somehow, you should leave this alone until you've computed the gradient deformation matrix, as you need 'before' and 'after' tetrahedra to make that work. If you're doing some numerical integraion, you should use the rod_blob_interface tetrahedron as the one you deform, because you can just update_tet as soon as you're done with it.

Referenced by ffea_test::connection_energy(), ffea_test::connection_energy_2(), ffea_test::connection_propagation(), ffea_test::connection_test(), do_connection_timestep(), get_attachment_node(), get_attachment_node_pos(), World::init(), position_blob_from_rod(), World::read_and_build_system(), Rod_blob_interface(), and update_J_0().

◆ update_J_0()

void rod::Rod_blob_interface::update_J_0 ( )

Referenced by World::init().

Field Documentation

◆ attachment_m

float rod::Rod_blob_interface::attachment_m[3]

◆ attachment_m_equil

float rod::Rod_blob_interface::attachment_m_equil[3]

◆ attachment_node

float rod::Rod_blob_interface::attachment_node[3]

◆ attachment_node_equil

float rod::Rod_blob_interface::attachment_node_equil[3]

◆ attachment_node_pos

float rod::Rod_blob_interface::attachment_node_pos[3]

◆ connected_blob

◆ connected_face

Face* rod::Rod_blob_interface::connected_face

◆ connected_rod

◆ connected_tet

◆ deformed_tet_nodes

◆ edge_vecs

◆ ends_at_rod

◆ euler_angles

float rod::Rod_blob_interface::euler_angles[3] = {0, 0, 0}

◆ face_index

int rod::Rod_blob_interface::face_index

◆ face_node_indices

◆ face_nodes

int rod::Rod_blob_interface::face_nodes[3]

◆ from_index

int rod::Rod_blob_interface::from_index

Referenced by Rod_blob_interface().

◆ J_inv_0

◆ node_weighting

float rod::Rod_blob_interface::node_weighting[3] = {0.333333333333333, 0.333333333333333, 0.333333333333333}

◆ order

int rod::Rod_blob_interface::order

◆ tet_origin

float rod::Rod_blob_interface::tet_origin[3]

◆ to_index

int rod::Rod_blob_interface::to_index

Referenced by Rod_blob_interface().


The documentation for this struct was generated from the following files: