Mapping dynamics
While sifting through some of my files yesterday, I found a spread-sheet 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 realised 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, “Pre-loading 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]]