Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic tensions on mooring lines #29

Merged
merged 18 commits into from
Sep 9, 2024
Merged

Dynamic tensions on mooring lines #29

merged 18 commits into from
Sep 9, 2024

Conversation

lucas-carmo
Copy link
Collaborator

@lucas-carmo lucas-carmo commented Aug 2, 2024

Purpose

This PR implements dynamic tension on mooring lines based on the amazing work done by @serag-abdulmotaleb. MoorPy can now use a lumped mass approach (with the required added mass, drag, and line mass coefficients provided by a MoorDyn input file) to account for line inertia, hydrodynamic added mass, and hydrodynamic damping (from linearized quadratic drag) acting on the moorings.

This approach provides a much better prediction of dynamic mooring line tension than the quasi-static approach available in MoorPy.

It can also compute the inertia, stiffness, hydrodynamic added mass, and hydrodynamic damping matrices acting on the system. For example, we can now compute the hydrodynamic damping acting on a FOWT due to the mooring lines.

The lumped mass approach requires a MoorDyn input file. I added an example in the examples folder that is a modified/simplified version of one of the tests we made. As this example is meant to show how to use this new functionality only, I didn't check the results of the example case thoroughly.

This new functionality should NOT affect existing code. Please let me know if you find any problem 😁

Type of change

  • Bugfix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (non-backwards-compatible fix or feature)
  • Code style update (formatting, renaming)
  • Refactoring (no functional changes, no API changes)
  • Documentation update
  • Maintenance update
  • Other (please describe)

Testing

Tested locally for several cases. Some examples are given below:

  • Fairlead tension obtained by imposing prescribed motions at the top of a single line of the UMaine VolturnUS-S semisubmersible - MoorPy (using the lumped mass approach implemented in this PR) vs MoorDyn
    image

  • Comparison of RAFT results of the UMaine VolturnUS-S semisubmersible (with both waves and wind) against OpenFAST. 'qs' stands for quasi-static (mooring line acts as a spring, which was the only approach available in MoorPY) and 'dyn' stands for dynamic (lumped mass approach implemented in this PR)
    image

Checklist

Put an x in the boxes that apply.

  • I have run existing tests which pass locally with my changes
  • I have added new tests or examples that prove my fix is effective or that my feature works
  • I have added necessary documentation

serag-abdulmotaleb and others added 18 commits February 5, 2024 16:55
- Edited new Line dynamic methods to streamline passing of arguments
  and to only load the new functions on demand.
- Added Subsystem.getDynamicMatrices method - copied closely from the
  CompositeLine method. This allows the new methods to work with
  Subsystem (all other methods are already inherited from Line).
- Added Subsystem.makeFromSystem method - adapted from CompositeLine
  initialization to allow similar functionality for Subsystem. Not tested.
- Made Examples/dynamic.py script to test some things out simply.
- functions from dynamic_tension_functions.py are now on helpers
- Because the dynamic calculations depend on the number of nodes in the subsystem/line, I slightly modified functions lines2subsystem and makeGeneric to specify the number of segments to be used in addLine.
- I have not used subsystem.makeFromSystem or getNodes yet
Applied the same idea of getSystemStiffnessA to lump the dynamic matrices (inertia, added mass, damping, and stiffness) in 3x3 matrices at the fairlead
- In system.getSystemDynamicMatrices, the effect of other attached points (the loop on point2) is already lumped in point.getDynamicMatrices
-  Replaced np.linalg.inv with np.linalg.pinv (which computes the pseudo-inverse of the matrix) because we can have some cases where rows and columns of the matrix are zero (e.g., when adopting Ca=0 in a given direction)
- The procedure to lump the dynamic matrices in a point involves inverting the matrices twice. If the input matrix is not exactly symmetrical, this can greatly amplify the spurious asymmetry. For this reason, we make the matrices computed with the lumped mass symmetrical.
- For some reason that I don't know yet, the procedure does not work if we use the whole matrix. We need to remove the rows and columns associated with the dofs of the node opposite to the node where we want to lump the matrices.
- Implemented getDynamicMatricesLumped method in the line class that lumps the added mass, inertia, damping, and stiffness matrices of a line at its extremities based on the matrices for each node (applied for a line modeled using a lumped mass model)
- Method getDynamicMatrices in the body class similar to getStiffnessA, but for the dynamic matrices
- Reorganized the code in point.getDynamicMatrices to use the new line.getDynamicMatricesLumped method
- Changed some np.liang.inv for np.linalg.pinv. We need that for cases where the matrices are singular. For instance, the added mass matrix of the line is singular if the axial added mass coefficient is zero.

WIP: There seems to be something wrong in line.getDynamicMatricesLumped if part of the line rests on the seabed, as the resulting stiffness matrix is not consistent with getStiffnessA. The agreement is much better when we totally remove those nodes, but they are still off. Need to figure out what is the correct way of dealing with that.
There is still something weird with the lumped mass approach regarding the nodes on the seabed. I'm still working on it, but for now we get the best results if we neglect those nodes when lumping the matrices at the extremities of the line.
The previous code to remove nodes on the sea bed wasn't working properly for subsystem
- Added number of segments (nSegs) in subsystem.makeGeneric to make sure that we are using the correct number of nodes (i.e., the one specified by the user) in the lumped mass approach
- Initialize any subsystem that is within a system in system.initialize
Removed *args and **kwargs to make the inputs more explicit
Previously, each call of system.getSystemDynamicMatrices() (and other equivalent functions in the body and point classes) would recompute the dynamic matrices of the line (inertia, added mass, damping, and stiffness). That required the sea state and the motions of the line nodes at each call.

Now, we need to precompute the dynamic matrices of each line using line.updateLumpedMass(). The advantages are:
1. Fewer computations
2. It is simpler to integrate the lumped mass approach in RAFT because now it's easier to account for motions of the fairlead

Also, the only matrix that requires the sea state and motions of the line is the damping matrix. So this commit reformulates the system, body, and line usage of the lumped mass approach to be able to provide inertia, added mass, and stiffness matrices without knowledge of the sea state or motions of the line.  I will add some examples, but you just need to call system.updateSystemDynamicMatrices() and then system.getSystemDynamicMatrices()
- The wave amplitude is now 2*Sw*dw (it was missing the factor 2)
- The tension amplitude is now a complex value which is important to get the correct phase for shared moorings
This example is a modified/simplified version of one of the tests we made. As this example is meant to show how to use this new functionality only, I didn't check the results of the example case thoroughly.
@mattEhall mattEhall merged commit 9d33bc9 into dev Sep 9, 2024
20 of 38 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants