## Mapping motion induced dynamics

While sifting through some of my files yesterday, I found a spreadsheet using Gaussian elimination technique, refreshing old memories. In 2004, we were engineering a spar + topside — the first of its kind for the region. For transport, we designed the topside to straddle atop two lean barges — like a catamaran. This enabled the topside to be floated over, and mate with the spar. (Image courtesy: Offshore Kinematics Inc. OTC 19639 paper offers more details on installation.)

We quickly realized that the catamaran arrangement was a stiffness hog for the topside during tow (racking moments resulting from quartering seas) — driving the need for more steel in the topside, far more than in its in-service conditions. (Michael Luo’s US 8312828 B2 patent titled, “Preloading to reduce loads and save steel on topsides and grillage of catamaran systems” describes the measures we took to save steel.)

Marine team furnished motion-induced dynamic loads of the catamaran barge ensemble (from motion responses) for topside stress check during its fourteen-day tow. To transfer these on to the topside as inertia loads, we did the following:

- First, we converted the dynamic loads into topside coordinate system along with sign conventions.
- Then, we generated inertia loads on topside corresponding to 1.0⋅g of linear (surge, sway, heave) and angular accelerations (roll, pitch, yaw), which resulted in a load case each — six in total, with each containing loads (Fx, Fy, Fz) and moments (Mx, My, Mz).
- From the two above, the idea was to get suitable factor to apply to the loads generated in step 2 to match the dynamic loads received from the Marine team — using the Gaussian elimination technique.

Upon solving the following grid, we’d end up with six load factors to multiply with our set of six inertia load sets respectively.

```
+- -+
| Fx1 Fx2 Fx3 Fx4 Fx5 Fx6 | Fx |
| Fy1 Fy2 Fy3 Fy4 Fy5 Fy6 | Fy |
| Fz1 Fz2 Fz3 Fz4 Fz5 Fz6 | Fz |
| Mx1 Mx2 Mx3 Mx4 Mx5 Mx6 | Mx |
| My1 My2 My3 My4 My5 My6 | My |
| Mz1 Mz2 Mz3 Mz4 Mz5 Mz6 | Mz |
+- -+
```

Back to the spreadsheet, I noticed that we had actually generated a multiple pivot-eliminate routines through iterations, until all coefficients (except the principal diagonal) were decomposed, and coefficients in the principal diagonal contained 1 each — as is done in the technique.

Matrices are now available in most modern computing software. Gaussian elimination, on the other hand, was perhaps from an era of logarithms and radians — designed to simplify computational complexity when done by hand. So, I am not sure why we used this technique, in lieu of matrix functions in Excel or MathCAD available at our disposal.

Following the classic recipe of solving linear equations (`A . x = B`

) for x, a column matrix of load factors, where `A`

is a square matrix of inertia loads — corresponding to 1.0⋅g, and `B`

is a column matrix of dynamic loads from catamaran’s motion responses, I punched in the two arrays to see if I could get the same set of `x`

. Here’s how simple it is with `numpy`

:

```
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
mat.py -- 2015 ckunte.
"""
import numpy
def main():
# Inertia matrix, A, corresponds to 1.0g in surge, sway,
# heave, roll, pitch, and yaw.
A = numpy.mat("[-11364.0, 0.0, 0.0, 0.0, -412.3, -9.1; \
0.0, -11364.0, 0.0, 412.3, 0.0, -9.9; \
0.0, 0.0, -11364.0, 9.1, 9.9, 0.0; \
0.0, 231661.7, 5129.7, -11569.7, 322.5, 266.6; \
-231661.7, 0.0, 5574.3, 322.5, -15050.3, -239.8; \
-5129.7, -5574.3, 0.0, 266.6, -239.8, -8929.5]")
# Motion-induced dynamic loads (one of numerous cases)
B = numpy.mat("[-2961.0; -1358.0; -40613.0; 119921.5; \
-68588.5; 210347.9]")
# getI() is the matrix inverse function from numpy.
x = A.getI() * B
print x
if __name__ == '__main__':
main()
```

The output looks like below — matching the result we’d obtained from Gaussian elimination method:

```
$ python mat.py
[[ 0.16090823]
[ -0.71351288]
[ 3.55783674]
[-23.53602482]
[ 3.27622169]
[-23.99421225]]
```