Python Example

Static Configuration

This example will be run against the baseline input file. The water depth is \(350\) meters. The space preceeding the repeat 120 240 solver option flag is removed to enable duplication of the mooring geometry twice with \(120^\circ\) and \(240^\circ\) offsets about the \(Z\) axis.

#! /usr/bin/env python
# -*- coding: utf-8 -*-

'''
Copyright (C) 2015 
map[dot]plus[dot]plus[dot]help[at]gmail                     
License: http://www.apache.org/licenses/LICENSE-2.0                 
'''  

from mapsys import *
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
np.set_printoptions(precision=2)
np.set_printoptions(suppress=True)


if __name__ == '__main__':      
    mooring_1 = Map()
    
    mooring_1.map_set_sea_depth(350)      # m
    mooring_1.map_set_gravity(9.81)       # m/s^2
    mooring_1.map_set_sea_density(1025.0) # kg/m^3
    
    mooring_1.read_file("../test/baseline_2.map") 
    mooring_1.summary_file('summary_file.txt')

    mooring_1.init( )
    
    epsilon = 1e-3 # finite difference epsilon
    K = mooring_1.linear(epsilon)    
    print "\nLinearized stiffness matrix with 0.0 vessel displacement:\n"
    print np.array(K)
     
    surge = 5.0 # 5 meter surge displacements
    mooring_1.displace_vessel(surge,0,0,0,0,0)
    mooring_1.update_states(0.0,0)
     
    K = mooring_1.linear(epsilon)    
    print "\nLinearized stiffness matrix with %2.2f surge vessel displacement:\n"%(surge)
    print np.array(K)

    # We need to call update states after linearization to find the equilibrium
    mooring_1.update_states(0.0,0)
    
    line_number = 0
    H,V = mooring_1.get_fairlead_force_2d(line_number)    
    print "Line %d: H = %2.2f [N]  V = %2.2f [N]"%(line_number, H, V)
      
    fx,fy,fz = mooring_1.get_fairlead_force_3d(line_number)    
    print "Line %d: Fx = %2.2f [N]  Fy = %2.2f [N]  Fz = %2.2f [N]\n"%(line_number, fx, fy, fz)

    print "These values come from the output buffer as defined in the 'LINE PROPERTIES' portion of the input file"
    print "Labels : ", mooring_1.get_output_labels()[0:6]
    print "Units  : ", mooring_1.get_output_units()[0:6]
    v = mooring_1.get_output_buffer()[0:6]
    print "Values : ", ["{0:0.2f}".format(i) for i in v]
    
    fig = plt.figure()
    ax = Axes3D(fig)
    num_points = 20
    for i in range(0,mooring_1.size_lines()):
        x = mooring_1.plot_x(i, num_points)
        y = mooring_1.plot_y(i, num_points)
        z = mooring_1.plot_z(i, num_points)        
        ax.plot(x,y,z,'b-')
     
    ax.set_xlabel('X [m]')
    ax.set_ylabel('Y [m]')
    ax.set_zlabel('Z [m]')        
     
    plt.show()
    
    mooring_1.end( )

Output

Two outputs are produced executing the stript above. Information explicitly requested is printed to the command line:

MAP++ (Mooring Analysis Program++) Ver. 1.20.10 Mar-22-2016
MAP++ environment properties (set externally)...
    Gravity constant          [m/s^2]  : 9.81
    Sea density               [kg/m^3] : 1025.00
    Water depth               [m]      : 350.00
    Vessel reference position [m]      : 0.00 , 0.00 , 0.00

Linearized stiffness matrix with 0.0 vessel displacement:

[[  1.99e+04  -3.78e-03   5.19e-03  -4.89e-02  -2.00e+05  -1.77e-02]
 [  1.18e-03   1.99e+04  -1.06e-02   2.00e+05   3.50e-02  -6.17e-01]
 [  2.49e-03  -1.01e-03   2.27e+04   2.21e-03   2.23e-01  -2.12e-01]
 [  1.95e-03   2.00e+05  -7.14e-03   2.17e+08   1.10e-02  -5.23e+01]
 [ -2.00e+05   3.33e-04   4.85e-01  -4.89e-02   2.17e+08  -2.19e-02]
 [  8.83e-04  -5.59e-01   1.12e-03  -8.53e+01  -7.90e-02   1.41e+08]]

Linearized stiffness matrix with 5.00 surge vessel displacement:

[[  1.96e+04  -2.58e-05   1.17e+03   9.61e-03  -2.15e+05  -1.67e-01]
 [ -4.57e-04   2.07e+04   1.41e-03   1.81e+05  -5.24e-02   1.72e+03]
 [  1.17e+03  -3.32e-04   2.32e+04  -5.38e-03  -1.19e+04   1.12e-03]
 [  1.05e-03   2.00e+05   1.51e-03   2.17e+08   4.25e-02  -5.21e+01]
 [ -2.00e+05  -8.91e-05   4.79e-01   5.43e-03   2.17e+08   6.60e-02]
 [  2.10e-03  -5.60e-01   5.77e-03  -8.52e+01   1.07e-01   1.41e+08]]
Line 0: H = 597513.33 [N]  V = 1143438.75 [N]
Line 0: Fx = -597513.33 [N]  Fy = -0.00 [N]  Fz = 1143438.75 [N]

These values come from the output buffer as defined in the 'LINE PROPERTIES' portion of the input file
Labels :  ['l[1]', 'alpha[1]', 'T[2]', 'l[4]', 'alpha[4]', 'T[5]']
Units  :  ['[m]', '[rad]', '[N]', '[m]', '[rad]', '[N]']
Values :  ['338.18', '1.07', '711942.60', '338.18', '1.07', '711942.39']

A figure is also produced to show the mooring geometry with a \(5\) meter vessel offset:

Note

The default units for the linearized stiffness matrix are [N/m], [N/rad], [Nm/m], and [Nm/rad]. See the section on the linearized stiffness matrix in the FAQ for more information.

_images/example.png

Fig. 7

Vessel kinematic breakdown to describe fairlead position relative to the origin.

Time-Marching for Dynamics Simulation

#! /usr/bin/env python
# -*- coding: utf-8 -*-

'''
Copyright (C) 2015 
map[dot]plus[dot]plus[dot]help[at]gmail                     
License: http://www.apache.org/licenses/LICENSE-2.0                 
'''  

from mapsys import *
import math
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.ticker as mtick
from matplotlib import rcParams
import numpy as np 
np.set_printoptions(precision=2)
np.set_printoptions(suppress=True)
rcParams.update({'figure.autolayout': True})


# user function to plot the mooring profile and footprint
def plot_mooring_system(mooring_data):
    # plot the mooring profile
    fig = plt.figure(1)
    ax = Axes3D(fig)
    colors = ['b','g','r','c']
    for i in xrange(mooring_data.size_lines()):
        x = mooring_data.plot_x( i, 20 ) # i is the the line number, and 20 is the number of points plotted on the line 
        y = mooring_data.plot_y( i, 20)
        z = mooring_data.plot_z( i, 20)        
        ax.plot(x,y,z,colors[i]+'-')     
    ax.set_xlabel('X [m]')
    ax.set_ylabel('Y [m]')
    ax.set_zlabel('Z [m]')        


def start():
    """
    Step 1) First initialize an instance of a mooring system

    Step 2) Assume that (X, Y, Z, phi, theta, psi) are the translation and rotation displacement of the vessel. 
    These displacements are fed into MAP as an argument to displace the fairlead. With the fairlead(s) 
    rigidly connected to the vessel, the (X, Y, Z, phi, theta, psi) directly manifests into the fairlead
    position in the global frame. 
    
    For the time being, assume a sinusoidal displacement of the vessel

    Step 3) This for-loop emulates the time-stepping procedure. You want to loop through the length of 
    the arrays (X,Y,Z,phi,theta,psi) to retrieve the fairlead force

    Step 4) update the MAP state. The arguments in displace_vessel are the displace displacements and rotations about the reference origin. 
    In this case, the reference origin is (0,0,0). 
    They can be set to a different potision using a run-time argument (this is an advanced feature).

    Step 5) get the fairlead tension. The get_fairlead_force_3d returns the fairlead force in 
    X, Y Z coordinates. This must be called at each time-step, and then stored into an array. We append 
    the empty lists created on lines 84-88.

    .. Note::

       MAP does *NOT* return the mooring restoring moment, The user must calculate this 
       themself using the cross-product between the WEC reference origin and the mooring attached
       point, i.e.,
    
       :math:`\mathbf{Moment} = \mathbf{r} \times \mathbf{F}`
    """

    # Step 1
    mooring = Map() 
    mooring.map_set_sea_depth(120)        # m
    mooring.map_set_gravity(9.81)         # m/s^2
    mooring.map_set_sea_density(1020.0)   # kg/m^2
    mooring.read_file('../test/baseline_1.map')   # input file
    mooring.summary_file('summary_file.sum.txt') # output summary file name at the conclusion of initialization
    
    mooring.init()                # solve the cable equilibrium profile
    plot_mooring_system(mooring) # Optional: call the user function to illustrate the mooring equilibrium profile
    

    # initialize list to zero (this is artificial. This would be prescribed the by vessel program)
    X,Y,Z,phi,theta,psi = ([0.0 for i in xrange(500)] for _ in xrange(6))
    time = []

    # variable to specify the amplitude of surge oscillation and period factor
    dt = 0.1
    amplitude = 10.0

    # prescribe artificial surge and pitch displacement. Again, this should be supplied based on the WEC motion or from time-marching routine
    for i in xrange(len(X)):
        time.append(i*dt)
        X[i] = (amplitude)*(math.sin(i*0.05))
        theta[i] = (amplitude)*(math.sin(i*0.025))

    # create an empty list of the line tension. We will store result from MAP in these lists
    line1_fx, line1_fy, line1_fz = ([] for _ in xrange(3))
    line2_fx, line2_fy, line2_fz = ([] for _ in xrange(3))
    line3_fx, line3_fy, line3_fz = ([] for _ in xrange(3))
    line4_fx, line4_fy, line4_fz = ([] for _ in xrange(3))

    # Step 3) Time marching
    for i in xrange(len(X)):        
        # Step 4) 

        # displace the vessel, X,Y,X are in units of m, and phi, theta, psi are in units of degrees
        mooring.displace_vessel(X[i], Y[i], Z[i], phi[i], theta[i], psi[i]) 

        # first argument is the current time. Second argument is the coupling interval (used in FAST)
        mooring.update_states(time[i], 0)                                   

        # Step 5) 
        # line 1 tensions in X, Y and Z. Note that python is indexed started at zero
        fx, fy, fz = mooring.get_fairlead_force_3d(0) # arugment is the line number
        line1_fx.append(fx)
        line1_fy.append(fy)
        line1_fz.append(fz)        

        # line 2 tensions in X, Y and Z.
        fx, fy, fz = mooring.get_fairlead_force_3d(1)
        line2_fx.append(fx)
        line2_fy.append(fy)
        line2_fz.append(fz)        

        # line 3 tensions in X, Y and Z.
        fx, fy, fz = mooring.get_fairlead_force_3d(2)
        line3_fx.append(fx)
        line3_fy.append(fy)
        line3_fz.append(fz)        

        # line 4 tensions in X, Y and Z.
        fx, fy, fz = mooring.get_fairlead_force_3d(3)
        line4_fx.append(fx)
        line4_fy.append(fy)
        line4_fz.append(fz)        

    # Optional: plot the vessel displacement (surge=X and pitch=theta) as a function of time
    plt.figure(2)
    plt.plot(time,X,lw=2,label='Surge displacement')
    plt.plot(time,theta,lw=2,label='Pitch displacement')
    plt.title('Vessel Translation/Rotation')
    plt.ylabel('Amplitude [m,deg]')
    plt.xlabel('Time [sec]')
    plt.legend()

    # Optional: plot line tension time history
    plt.figure(3)
    ax=plt.subplot(3,1,1)
    plt.plot(time,line1_fx,label='Line 1')
    plt.plot(time,line2_fx,label='Line 2')
    plt.plot(time,line3_fx,label='Line 3')
    plt.plot(time,line4_fx,label='Line 4')
    ax.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.2e'))
    plt.ylabel('X Fairlead Force [N]')
    plt.legend()

    ax = plt.subplot(3,1,2)
    ax.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.2e'))
    plt.plot(time,line1_fy)
    plt.plot(time,line2_fy)
    plt.plot(time,line3_fy)
    plt.plot(time,line4_fy)
    plt.ylabel('Y Fairlead Force [N]')

    ax = plt.subplot(3,1,3)
    ax.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.2e'))
    plt.plot(time,line1_fz)
    plt.plot(time,line2_fz)
    plt.plot(time,line3_fz)
    plt.plot(time,line4_fz)
    plt.ylabel('Z Fairlead Force [N]')
    plt.xlabel('Time [sec]')

    plt.show()

if __name__ == '__main__':      
    start()

Output

_images/time_domain_1.png

Fig. 8

Mooring footprint
_images/time_domain_2.png

Fig. 9

Precribed displacement of the vessel fed to MAP++.
_images/time_domain_3.png

Fig. 10

Fairlead line tensions for the respective lines.