Time-Parallel Frame Discrete Elastic Rods
Anonymized, Anonymized

Introduction

In this document, we showcase how IHeartLA improves the clarity of a paper with numerous varibles. Discrete Elastic Rods is a perfect example of how we can boost productivity with IHeartLA. Compare to the original [Bergou et al. 2008], this document describes a model of discrete elastic rod using time-parallel frame [Bergou et al. 2010] instead of space-parallel frame and adds a stretching energy term.

Discretization

Let there be $nv$ is the number of vertices , and that implies $ne$ is the number of edges/segments , where $ne = nv - 1$.

On every segment, there is a orthogonal frame indicating the direction/orientation/twist of that segment where ${\prosedeflabel{energy}{{d_1}}}$ and ${\prosedeflabel{energy}{{d_2}}}$ are orthogonal directors of every segment on the center-line , and $t$ is the unit normal .

To simulate the dynamics, we need to define the rest state of the rod. Intuitively, we need to save rest state configuration of the rod, which composes of rest position $\bar{x}$ , rest orthogonal directors ${\prosedeflabel{energy}{{\bar{d_1}}}}$ and ${\prosedeflabel{energy}{{\bar{d_2}}}}$ . Note that we want the save the whole orthogonal frame so we can have rest rotational information, but we can recover rest unit normal the rest center-line position $\bar{x}$.

For every segment, we assume the cross-section to be an oval. In this note, we include ${\prosedeflabel{energy}{{a}}}_i$ and ${\prosedeflabel{energy}{{b}}}_i$ as the two axies of the ellipse at the $i^{th}$ segment , but we also assume ${\proselabel{energy}{{a}}}_i = {\proselabel{energy}{{b}}}_i = r$ so that the cross-section is a circle. Therefore, we have the area of the node cross-section ${\prosedeflabel{energy}{{A}}}_i$ ,

$$\DeclareMathOperator*{\argmax}{arg\,max} \DeclareMathOperator*{\argmin}{arg\,min} \begin{align*} \idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, 'A', 'energy', 'def', false, '')", "id":"energy-A", "sym":"A", "func":"energy", "localFunc":"", "type":"def", "case":"equation"} }{ {\mathit{A}} }_{ \mathit{i} } & = \pi\idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, 'a', 'energy', 'use', false, '')", "id":"energy-a", "sym":"a", "func":"energy", "localFunc":"", "type":"use", "case":"equation"} }{ {\mathit{a}} }_{ \mathit{i} }\idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, 'b', 'energy', 'use', false, '')", "id":"energy-b", "sym":"b", "func":"energy", "localFunc":"", "type":"use", "case":"equation"} }{ {\mathit{b}} }_{ \mathit{i} }\\\eqlabel{ {"onclick":"event.stopPropagation(); onClickEq(this, 'energy', ['b', 'a', 'A'], false, [], [], 'QV9pID0gz4AgYV9pIGJfaQ==');"} }{} \end{align*} \tag{1}\label{1}$$

Discrete Energy

To accurately model a rod, we need to consider its response to bending and stretching. In addition, we also need a rotational energy, or twist energy, to model twists accumulated across the rod. In this section, we show the three energy equation in discrete settings:

Bending Energy

Define bending energy ${\prosedeflabel{energy}{{E_b}}}$

$$\DeclareMathOperator*{\argmax}{arg\,max} \DeclareMathOperator*{\argmin}{arg\,min} \begin{align*} \idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, 'E_b', 'energy', 'def', false, '')", "id":"energy-E_b", "sym":"E_b", "func":"energy", "localFunc":"", "type":"def", "case":"equation"} }{ {E_b} } & = \frac{1}{2}\sum_{\mathit{i}} \frac{1}{\idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, '\\\\bar{l}', 'energy', 'use', false, '')", "id":"energy-\\\\bar{l}", "sym":"\\\\bar{l}", "func":"energy", "localFunc":"", "type":"use", "case":"equation"} }{ {\bar{l}} }_{ \mathit{i} }}\left( \idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, 'B', 'energy', 'use', false, '')", "id":"energy-B", "sym":"B", "func":"energy", "localFunc":"", "type":"use", "case":"equation"} }{ {\mathit{B}} }_{ \mathit{i}, 1, 1}{\left( \idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, 'κ_2', 'energy', 'use', false, '')", "id":"energy-κ_2", "sym":"κ_2", "func":"energy", "localFunc":"", "type":"use", "case":"equation"} }{ {κ_2} }_{ \mathit{i} } - \idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, '\\\\bar{κ}_2', 'energy', 'use', false, '')", "id":"energy-\\\\bar{κ}_2", "sym":"\\\\bar{κ}_2", "func":"energy", "localFunc":"", "type":"use", "case":"equation"} }{ {\bar{κ}_2} }_{ \mathit{i} } \right)}^{2} + \idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, 'B', 'energy', 'use', false, '')", "id":"energy-B", "sym":"B", "func":"energy", "localFunc":"", "type":"use", "case":"equation"} }{ {\mathit{B}} }_{ \mathit{i}, 2, 2}{\left( \idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, 'κ_1', 'energy', 'use', false, '')", "id":"energy-κ_1", "sym":"κ_1", "func":"energy", "localFunc":"", "type":"use", "case":"equation"} }{ {κ_1} }_{ \mathit{i} } - \idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, '\\\\bar{κ}_1', 'energy', 'use', false, '')", "id":"energy-\\\\bar{κ}_1", "sym":"\\\\bar{κ}_1", "func":"energy", "localFunc":"", "type":"use", "case":"equation"} }{ {\bar{κ}_1} }_{ \mathit{i} } \right)}^{2} \right)\\\eqlabel{ {"onclick":"event.stopPropagation(); onClickEq(this, 'energy', ['\\\\bar{κ}_1', '\\\\bar{l}', 'κ_2', 'κ_1', 'B', '\\\\bar{κ}_2', 'E_b'], false, [], [], 'YEVfYmAgPSAxLzIg4oiRX2kgMS9gXGJhcntsfWBfaShCX2ksMSwxIChgzrpfMmBfaSAtIGBcYmFye866fV8yYF9pKV4yICsgQl9pLDIsMiAoYM66XzFgX2kgLSBgXGJhcnvOun1fMWBfaSleMik=');"} }{} \end{align*} \tag{2}\label{2}$$

where
$$\DeclareMathOperator*{\argmax}{arg\,max} \DeclareMathOperator*{\argmin}{arg\,min} \begin{align*} \idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, 'κ_1', 'energy', 'def', false, '')", "id":"energy-κ_1", "sym":"κ_1", "func":"energy", "localFunc":"", "type":"def", "case":"equation"} }{ {κ_1} }_{ \mathit{i} } & = \frac{\idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, 'κb', 'energy', 'use', false, '')", "id":"energy-κb", "sym":"κb", "func":"energy", "localFunc":"", "type":"use", "case":"equation"} }{ {\mathit{κb}} }_{ \mathit{i} } \cdot \left( \idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, '\\\\tilde{d_2}', 'energy', 'use', false, '')", "id":"energy-\\\\tilde{d_2}", "sym":"\\\\tilde{d_2}", "func":"energy", "localFunc":"", "type":"use", "case":"equation"} }{ {\tilde{d_2}} }_{ \mathit{i} } + \idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, 'd_2', 'energy', 'use', false, '')", "id":"energy-d_2", "sym":"d_2", "func":"energy", "localFunc":"", "type":"use", "case":"equation"} }{ {d_2} }_{ \mathit{i} } \right)}{2}\\\eqlabel{ {"onclick":"event.stopPropagation(); onClickEq(this, 'energy', ['\\\\tilde{d_2}', 'κb', 'd_2', 'κ_1'], false, [], [], 'YM66XzFgX2kgPSBgzrpiYF9pIOKLhSAoYFx0aWxkZXtkXzJ9YF9pICsgYGRfMmBfaSkvMg==');"} }{} \idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, 'κ_2', 'energy', 'def', false, '')", "id":"energy-κ_2", "sym":"κ_2", "func":"energy", "localFunc":"", "type":"def", "case":"equation"} }{ {κ_2} }_{ \mathit{i} } & = -\frac{\idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, 'κb', 'energy', 'use', false, '')", "id":"energy-κb", "sym":"κb", "func":"energy", "localFunc":"", "type":"use", "case":"equation"} }{ {\mathit{κb}} }_{ \mathit{i} } \cdot \left( \idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, '\\\\tilde{d_1}', 'energy', 'use', false, '')", "id":"energy-\\\\tilde{d_1}", "sym":"\\\\tilde{d_1}", "func":"energy", "localFunc":"", "type":"use", "case":"equation"} }{ {\tilde{d_1}} }_{ \mathit{i} } + \idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, 'd_1', 'energy', 'use', false, '')", "id":"energy-d_1", "sym":"d_1", "func":"energy", "localFunc":"", "type":"use", "case":"equation"} }{ {d_1} }_{ \mathit{i} } \right)}{2}\\\eqlabel{ {"onclick":"event.stopPropagation(); onClickEq(this, 'energy', ['κb', 'd_1', '\\\\tilde{d_1}', 'κ_2'], false, [], [], 'YM66XzJgX2kgPSAtYM66YmBfaSDii4UgKGBcdGlsZGV7ZF8xfWBfaSArIGBkXzFgX2kpLzI=');"} }{} \idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, '\\\\bar{κ}_1', 'energy', 'def', false, '')", "id":"energy-\\\\bar{κ}_1", "sym":"\\\\bar{κ}_1", "func":"energy", "localFunc":"", "type":"def", "case":"equation"} }{ {\bar{κ}_1} }_{ \mathit{i} } & = \frac{\idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, '\\\\bar{κb}', 'energy', 'use', false, '')", "id":"energy-\\\\bar{κb}", "sym":"\\\\bar{κb}", "func":"energy", "localFunc":"", "type":"use", "case":"equation"} }{ {\bar{κb}} }_{ \mathit{i} } \cdot \left( \idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, '\\\\bar{\\\\tilde{d_2}}', 'energy', 'use', false, '')", "id":"energy-\\\\bar{\\\\tilde{d_2}}", "sym":"\\\\bar{\\\\tilde{d_2}}", "func":"energy", "localFunc":"", "type":"use", "case":"equation"} }{ {\bar{\tilde{d_2}}} }_{ \mathit{i} } + \idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, '\\\\bar{d_2}', 'energy', 'use', false, '')", "id":"energy-\\\\bar{d_2}", "sym":"\\\\bar{d_2}", "func":"energy", "localFunc":"", "type":"use", "case":"equation"} }{ {\bar{d_2}} }_{ \mathit{i} } \right)}{2}\\\eqlabel{ {"onclick":"event.stopPropagation(); onClickEq(this, 'energy', ['\\\\bar{\\\\tilde{d_2}}', '\\\\bar{d_2}', '\\\\bar{κb}', '\\\\bar{κ}_1'], false, [], [], 'YFxiYXJ7zrp9XzFgX2kgPSBgXGJhcnvOumJ9YF9pIOKLhSAoYFxiYXJ7XHRpbGRle2RfMn19YF9pICsgYFxiYXJ7ZF8yfWBfaSkvMg==');"} }{} \idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, '\\\\bar{κ}_2', 'energy', 'def', false, '')", "id":"energy-\\\\bar{κ}_2", "sym":"\\\\bar{κ}_2", "func":"energy", "localFunc":"", "type":"def", "case":"equation"} }{ {\bar{κ}_2} }_{ \mathit{i} } & = -\frac{\idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, '\\\\bar{κb}', 'energy', 'use', false, '')", "id":"energy-\\\\bar{κb}", "sym":"\\\\bar{κb}", "func":"energy", "localFunc":"", "type":"use", "case":"equation"} }{ {\bar{κb}} }_{ \mathit{i} } \cdot \left( \idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, '\\\\bar{\\\\tilde{d_1}}', 'energy', 'use', false, '')", "id":"energy-\\\\bar{\\\\tilde{d_1}}", "sym":"\\\\bar{\\\\tilde{d_1}}", "func":"energy", "localFunc":"", "type":"use", "case":"equation"} }{ {\bar{\tilde{d_1}}} }_{ \mathit{i} } + \idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, '\\\\bar{d_1}', 'energy', 'use', false, '')", "id":"energy-\\\\bar{d_1}", "sym":"\\\\bar{d_1}", "func":"energy", "localFunc":"", "type":"use", "case":"equation"} }{ {\bar{d_1}} }_{ \mathit{i} } \right)}{2}\\\eqlabel{ {"onclick":"event.stopPropagation(); onClickEq(this, 'energy', ['\\\\bar{d_1}', '\\\\bar{\\\\tilde{d_1}}', '\\\\bar{κb}', '\\\\bar{κ}_2'], false, [], [], 'YFxiYXJ7zrp9XzJgX2kgPSAtYFxiYXJ7zrpifWBfaSDii4UgKGBcYmFye1x0aWxkZXtkXzF9fWBfaSArIGBcYmFye2RfMX1gX2kpLzI=');"} }{} \end{align*} \tag{3}\label{3}$$

${\prosedeflabel{energy}{{κb}}}$ being curvature binormal , ${\prosedeflabel{energy}{{\bar{κb}}}}$ being rest curvature binormal , ${\prosedeflabel{energy}{{κ_1}}}$ and ${\prosedeflabel{energy}{{κ_2}}}$ being curvature vectors , ${\prosedeflabel{energy}{{\bar{κ}_1}}}$ and ${\prosedeflabel{energy}{{\bar{κ}_2}}}$ being rest curvature vectors , ${\prosedeflabel{energy}{{B}}}$ is the bending stiffness matrix , which $\DeclareMathOperator*{\argmax}{arg\,max} \DeclareMathOperator*{\argmin}{arg\,min} \begin{align*} \idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, 'B', 'energy', 'def', false, '')", "id":"energy-B", "sym":"B", "func":"energy", "localFunc":"", "type":"def", "case":"equation"} }{ {\mathit{B}} }_{ \mathit{i} } & = \frac{\idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, 'E', 'energy', 'use', false, '')", "id":"energy-E", "sym":"E", "func":"energy", "localFunc":"", "type":"use", "case":"equation"} }{ {\mathit{E}} }\idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, 'A', 'energy', 'use', false, '')", "id":"energy-A", "sym":"A", "func":"energy", "localFunc":"", "type":"use", "case":"equation"} }{ {\mathit{A}} }_{ \mathit{i} }}{4}\begin{bmatrix} {\idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, 'a', 'energy', 'use', false, '')", "id":"energy-a", "sym":"a", "func":"energy", "localFunc":"", "type":"use", "case":"equation"} }{ {\mathit{a}} }_{ \mathit{i} }}^{2} & 0\\ 0 & {\idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, 'b', 'energy', 'use', false, '')", "id":"energy-b", "sym":"b", "func":"energy", "localFunc":"", "type":"use", "case":"equation"} }{ {\mathit{b}} }_{ \mathit{i} }}^{2}\\ \end{bmatrix}\\\eqlabel{ {"onclick":"event.stopPropagation(); onClickEq(this, 'energy', ['b', 'a', 'A', 'E', 'B'], false, [], [], 'Ql9pID0gRUFfaS80IFthX2leMiAwOyAwIGJfaV4yXQ==');"} }{} \end{align*} $, ${\prosedeflabel{energy}{{\bar{l}}}}$ is the voronoi length , and ${\prosedeflabel{energy}{{E}}}$ is the Young’s modulus .

Twisting Energy

Define twisting energy ${\prosedeflabel{energy}{{E_t}}}$

$$\DeclareMathOperator*{\argmax}{arg\,max} \DeclareMathOperator*{\argmin}{arg\,min} \begin{align*} \idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, 'E_t', 'energy', 'def', false, '')", "id":"energy-E_t", "sym":"E_t", "func":"energy", "localFunc":"", "type":"def", "case":"equation"} }{ {E_t} } & = \frac{1}{2}\sum_{\mathit{i}} \frac{\idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, 'β', 'energy', 'use', false, '')", "id":"energy-β", "sym":"β", "func":"energy", "localFunc":"", "type":"use", "case":"equation"} }{ {\mathit{β}} }_{ \mathit{i} }}{\idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, '\\\\bar{l}', 'energy', 'use', false, '')", "id":"energy-\\\\bar{l}", "sym":"\\\\bar{l}", "func":"energy", "localFunc":"", "type":"use", "case":"equation"} }{ {\bar{l}} }_{ \mathit{i} }}{\left( \idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, 'm', 'energy', 'use', false, '')", "id":"energy-m", "sym":"m", "func":"energy", "localFunc":"", "type":"use", "case":"equation"} }{ {\mathit{m}} }_{ \mathit{i} } - \idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, '\\\\bar{m}', 'energy', 'use', false, '')", "id":"energy-\\\\bar{m}", "sym":"\\\\bar{m}", "func":"energy", "localFunc":"", "type":"use", "case":"equation"} }{ {\bar{m}} }_{ \mathit{i} } \right)}^{2}\\\eqlabel{ {"onclick":"event.stopPropagation(); onClickEq(this, 'energy', ['m', '\\\\bar{l}', '\\\\bar{m}', 'β', 'E_t'], false, [], [], 'YEVfdGAgPSAxLzIg4oiRX2kgzrJfaS9gXGJhcntsfWBfaShtX2kgLSBgXGJhcnttfWBfaSleMg==');"} }{} \idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, 'β', 'energy', 'def', false, '')", "id":"energy-β", "sym":"β", "func":"energy", "localFunc":"", "type":"def", "case":"equation"} }{ {\mathit{β}} }_{ \mathit{i} } & = \frac{\idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, 'G', 'energy', 'use', false, '')", "id":"energy-G", "sym":"G", "func":"energy", "localFunc":"", "type":"use", "case":"equation"} }{ {\mathit{G}} }\idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, 'A', 'energy', 'use', false, '')", "id":"energy-A", "sym":"A", "func":"energy", "localFunc":"", "type":"use", "case":"equation"} }{ {\mathit{A}} }_{ \mathit{i} }\left( {\idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, 'a', 'energy', 'use', false, '')", "id":"energy-a", "sym":"a", "func":"energy", "localFunc":"", "type":"use", "case":"equation"} }{ {\mathit{a}} }_{ \mathit{i} }}^{2} + {\idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, 'b', 'energy', 'use', false, '')", "id":"energy-b", "sym":"b", "func":"energy", "localFunc":"", "type":"use", "case":"equation"} }{ {\mathit{b}} }_{ \mathit{i} }}^{2} \right)}{4}\\\eqlabel{ {"onclick":"event.stopPropagation(); onClickEq(this, 'energy', ['G', 'b', 'a', 'A', 'β'], false, [], [], 'zrJfaSA9IEdBX2koYV9pXjIrYl9pXjIpLzQ=');"} }{} \end{align*} \tag{4}\label{4}$$

where ${\prosedeflabel{energy}{{G}}}$ is the shear modulus , ${\prosedeflabel{energy}{{β}}}_i$ is the twisting modulus , ${\prosedeflabel{energy}{{m}}}$ is the twist , ${\prosedeflabel{energy}{{\bar{m}}}}$ is the rest twist , ${\prosedeflabel{energy}{{\bar{m}}}}$ is the rest twist , and $\overline{l}_i$ being the voronoi length .

Stretching Energy

Define stretching energy ${\prosedeflabel{energy}{{E_s}}}$

$$\DeclareMathOperator*{\argmax}{arg\,max} \DeclareMathOperator*{\argmin}{arg\,min} \begin{align*} \idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, 'E_s', 'energy', 'def', false, '')", "id":"energy-E_s", "sym":"E_s", "func":"energy", "localFunc":"", "type":"def", "case":"equation"} }{ {E_s} } & = \frac{1}{2}\sum_{\mathit{j}} \idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, 'k_s', 'energy', 'use', false, '')", "id":"energy-k_s", "sym":"k_s", "func":"energy", "localFunc":"", "type":"use", "case":"equation"} }{ {k_s} }{\left( \frac{\left\|\idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, 'e', 'energy', 'use', false, '')", "id":"energy-e", "sym":"e", "func":"energy", "localFunc":"", "type":"use", "case":"equation"} }{ {\mathit{e}} }_{ \mathit{j} }\right\|}{\left\|\idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, '\\\\bar{e}', 'energy', 'use', false, '')", "id":"energy-\\\\bar{e}", "sym":"\\\\bar{e}", "func":"energy", "localFunc":"", "type":"use", "case":"equation"} }{ {\bar{e}} }_{ \mathit{j} }\right\|} - 1 \right)}^{2}\left\|\idlabel{ {"onclick":"event.stopPropagation(); onClickSymbol(this, '\\\\bar{e}', 'energy', 'use', false, '')", "id":"energy-\\\\bar{e}", "sym":"\\\\bar{e}", "func":"energy", "localFunc":"", "type":"use", "case":"equation"} }{ {\bar{e}} }_{ \mathit{j} }\right\|\\\eqlabel{ {"onclick":"event.stopPropagation(); onClickEq(this, 'energy', ['k_s', '\\\\bar{e}', 'e', 'E_s'], false, [], [], 'YEVfc2AgPSAxLzIg4oiRX2ogYGtfc2AgKOKAlmVfauKAliAvIOKAlmBcYmFye2V9YF9q4oCWIC0gMSleMiDigJZgXGJhcntlfWBfauKAlg==');"} }{} \end{align*} \tag{5}\label{5}$$

where ${\prosedeflabel{energy}{{k_s}}}$ is the stretching coefficient , ${\prosedeflabel{energy}{{e}}}$ being the edge length , and ${\prosedeflabel{energy}{{\bar{e}}}}$ being the rest edge length .

REFERENCE

M. Bergou, M. Wardetzky, S. Robinson, B. Audoly and E. Grinspun. 2008. {Discrete elastic rods}.

M. Bergou, B. Audoly, E. Vouga, M. Wardetzky and E. Grinspun. 2010. {Discrete Viscous Threads}.