A C++ implementation of FFEA_rod is provided within the FFEA software package. The relevant files are:
In addition, FFEA_rod depends upon RngStream.h by Pierre L'Ecuyer and Richard Simard, OpenMP, and Boost. If you wish to build FFEA_rod outside of FFEA, the files listed above and these three libraries should be enough for FFEA_rod to compile.
All rod functions and objects live inside the rod:: namespace. The FFEA_rod object and data structure stores information specific to a particular rod, but not global simulation parameters (e.g. an instance of RNGstreams or the temperature). To create a rod object, use
For a rod to function properly, the following global simulation parameters must be set:
In FFEA, these quantities come from the global world parameters specified in the .ffea script file. In FFEA, multiple rods can be specified to run in a single simulation. They are parallel per node, not per rod.
To run a step of rod dynamics, use
Where 'rng' is an array of pointers to rngstream objects. This array should be at least as large as the environment variable 'OMP_NUM_THREADS'.
Finally, to write the current state of the rod to the rod trajectory file, use
By default, this will write the trajectory out to the same file that was read in. There is no differece between rod input and output files (other than the fact that the rod output file contains multiple frames). It is often convenient to make the rod write the trajectroy to another file, and keep our input file as-is:
Translate the rod:
Rotate the rod:
Unfortunately, rod-blob connections are tightly coupled to the existing FFEA data structures and also have a lot of state, so be careful when creating or using them.
Rod-blob connections (called 'interfaces' in the code) are initialised after the rods and the blobs have been created. The pointers to the FFEA_rod and FFEA_blob objects are given as parameters. ends_at_rod is a bool, if true then the connection is blob_to_rod, if false it's rod_to_blob. to_index and from_index are integers, the indices of the rod nodes/blob elements in the connection, the blob node ids is an array of three integers (the nodes on the connected face), rotation is an array of floats specifying the euler angles, node_weighting is an array of floats specifying the position of the connection within the element, and order is initialisation order ID, another integer.
You can't use a rod-blob connection right after connecting it. First, in order of order, update the internal state of the connection. Updating the internal state copies the state of the tetrahedron from the blob to the rod. This copying is necessary because the state of the tetrahedron is actually different when calculating the energies in the rod-blob connection.
If, for any reason, the connection is repositioned, this function must run. That includes relative positioning and situating objects in the simulation box, which happens later in the init process.
Then, position the connection. If the connection goes blob-to-rod (e.g. if ends_at_rod==true), then
Or, if ends_at_rod=false:
Finally, set the initial values. This includes the initial positions of the connection node and element, and the equilibrium jacobian of the tetrahedron. This should be done right before the simulation starts running.
Luckily, actually running the dynamics of the connection is a lot easier. It doesn't matter to much when you do them, but by default, they happen just after the rod dynamics, the very last thing that's done in a timestep.