Improvement to hydrodynamic capabilities - Mostly MacCamy-Fuchs and second-order loads#48
Conversation
The slender-body approximation adopted in RAFT to compute QTFs is too restrictive in terms of wave length for some hull geometries (e.g., the slow surge motion of the OC4-DeepCwind and the UMaine VolturnUS-S semisubmersibles). This commit introduces a workaround that is based on the analytical solution for the second-order diffraction wave loads on a bottom-mounted surface-piercing vertical circular cylinder. This correction is in the same spirit as the MacCamy-Fuch correction for first-order wave loads but applied to second-order wave loads.
Before this commit, RAFT computed different QTFs for each sea state. Even though this might be strictly more correct, this is a somewhat gray area. Theoretically, the QTFs should not depend on the sea state, as first-order motions are linear, but this gets tricky once we include the linearized drag. In any case, the differences for each sea state are not worth the cost of recomputing the QTFs. Most software, such as OpenFAST, OrcaFlex and so on just use the same QTFs for all their analyses. Hence, this commit moves the calculation of the QTFs to be before the solution of system dynamics. The RAOs are computed using a white-noise wave with unit amplitude. To avoid code overlap with solveDynamics (within raft_model.py), this commit also moves part of that code to a function called calcMotions within raft_fowt.py
- MacCamy and Fuchs correction for vertical cylinders - The "unit" wave spectrum is now called "constant" with an user-specified amplitude. Currently, this amplitude is set to the wave height specified in the input file, but this is kind of weird to me.
- Basically reverted commit 49079c9. I had moved the QTFs to be computed before solving for the different sea states, but this can be achieved by precomputing the QTFs with a previous RAFT run and using that as if the QTFs were computed from WAMIT. So, the QTFs are back to being computed for each sea state. This is more computationally expensive, but more versatile. The user have both options and can decide which one they prefer. - MacCamy-Fuchs correction and Kim and Yue correction (MCF for second-order) are less strict now. They just required the member to be cylindrical. It can be inclined, tapered, or submerged. Clearly, they work worse for cases that are far from the original hypothesis of a vertical surface piercing circular cylinder. - Moved Kim and Yue correction to member class - Output name for the QTFs and RAOs now include Case and head in the name We still need to include the mean drift for the second-order force component due to the quadratic acceleration.
- The QTFs computed by RAFT now include the case number and the turbine number. Similar to other parts of the code, the case number starts at 1. The turbine number starts at 0, but perhaps we should changed that across the code for consistency. - The correction for second-order wave diffraction (based on the paper by Kim and Yue, 1990) now also includes the mean drift. It is a simple addition, we just needed to do a limit for a term that goes to 0/0 when w1-w2=0 - We changed the way that the second-order load motions are included in the linearization loop. Now, we perform the linearization twice. First, we perform the linearization loop WITHOUT the second-order loads/motions. After the loop converges, we compute the QTFs, the second-order loads, and then the motions. Since these motions may be very relevant, we redo the linearization loop including the second-order motions. This is only done for the first wave of the case, like before.
- We now include the second-order mean wave loads (wave mean drift) in model.solveStatics() - For compatibility with the message output to the console, now the case number in the output files starts at 1
We need the wave spectrum to be saved as a member of the fowt class for the computation of second-order wave loads, but it was being defined locally when the wave spectrum was of 'constant' type. This is fixed now.
- There was a MCF flag in test_data/VOlturnUS-S.yaml that wasn't used for anything, but now it affects the results. Turned it to false. We should add something in test_member.py to test MCF. - Included the unit spectrum to avoid breaking other peoples cases. The constant spectrum with height 1 is the same as the unit spectrum.
gbarter
reviewed
Apr 11, 2024
Member
gbarter
left a comment
There was a problem hiding this comment.
@lucas-carmo - This is a very impressive PR submission! I am well beyond any modicum of expertise in the hydrodynamics, so defer to Matt there.
The failure of the RAFT CI tests on Windows is due to pyhams, and also something we are seeing in many of our fortran on Windows packages. I think it is safe to proceed without it and I will hunt down the larger culprit.
I am going to leave it commented in case we want this output in the future
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Purpose
This PR implements the following improvements to the hydrodynamic capabilities of RAFT (a more detailed description is given below):
The first-order strip-theory solution can now apply the MacCamy-Fuchs correction (MCF) similarly to OpenFAST .
The computation of the QTFs using the slender-body approximation can now use a "sort of MCF". This is based on the analytical solution for the second-order diffraction problem of a bottom-mounted, surface piercing, vertical, circular cylinder . In the code, I am calling this "Kim And Yue correction" (KAY). With this, we now have a more reasonable mean and slow drift of the platform than purely using the slender-body approach implemented in Second-order wave loads in RAFT #37
Because some users might be interested in using RAFT to generate QTF matrices to use in other tools, I added an example called 'example-RAFT_QTF.py' that computes the QTFs of the OC4-DeepCwind platform. This is also useful for cases where you want to compute the QTFs only once and make RAFT use these QTFs for all cases that will be analyzed.
Other changes
Added a "constant" wave spectrum that behaves similar to 'unit', but with a user-specified magnitude. Note that this is the magnitude of the SPECTRUM across all frequencies, not the wave height or amplitude. I confess this bothers me a little, because the input file says "wave height". I thought of considering the input as the "significant wave height" of the spectrum, but this would mean that the magnitude of the spectrum for a given frequency would change depending on the frequency range specified by the user.
Changed the way that the second-order motions are included in the linearization loop of the quadratic drag when potSecOrder=1. Now, we perform the linearization twice. First, we perform the linearization loop WITHOUT the second-order loads/motions. After the loop converges, we compute the QTFs, the second-order loads, and then we recompute the motions. Since the motions induced by second-order wave loads may be very relevant, we redo the linearization loop including the second-order motions. This is only done for the first wave of the case, like before. Note that this is only the case when we compute the QTFs in RAFT (potSecOrder=1). For potSecOrder=0 (no second-order loads) or potSecOrder=2 (read precomputed QTFs from a .12d file), the linearization loop is computed only once.
Within model.analyzeCases(), we now call model.solveStatics() twice if the analysis includes second-order wave loads: once before and once after model.solveDynamics(). In principle, this would only be needed for cases where the QTFs are computed in RAFT within model.solveDynamics() (potSecOrder=1), but we currently need to do that even when using external QTFs (potSecOrder=2) because the wave computations are performed within model.solveDynamics(). We could reorganize that in the future.
To avoid code repetition, I included a calcImat() function in raft_member.py. It computes Imat with or without the MCF correction depending on the inputs and flags of the member.
Other things that I wanted to implement but wasn't able yet
More detailed description of points 1 and 2
This does not change the added mass matrix of the floater, only the inertial excitation in Morison's equation.
Below, a comparison of the first-order surge force RAO of the VolturnUS obtained with WAMIT, an OpenFAST model with strip-theory only, and RAFT. As expected, MCF reduces the surge force as the wave length becomes comparable to the diameter of the cylinder. Though the results are not the same as OpenFAST (which follows a different approach because it is in time domain), the MCF in RAFT seems to be good enough to avoid unrealistically large forces in short waves.
Even with this limitation, this correction for diffraction effects is already a good improvement. This correction is activated using the same flag as MCF, i.e. it is activated if:
- the user requests the computation of the QTFs in RAFT (potSecOrder: 1)
- the user specifies the MCF correction (MCF: 1)
Different from MCF, KAY does not work by scaling the inertia coefficient. It works by summing the real part of the force computed with the analytical solution (which is related to wave scattering) with the force computed with the slender-body approximation adopted in RAFT. This ensures that we do not double count force terms.
Below, an example of the surge force QTF of the OC4-DeepCwind platform computed using RAFT with and without the KAY correction (only the main and the first diagonal of the QTF matrix is shown).
We probably still need to fix some bugs, but I wanted to open this PR to make this capability available to other users. Also, it is already very long 😅
Type of change
What types of change is it?
Select the appropriate type(s) that describe this PR
Testing
Added 'example-RAFT_QTF' that computes the QTFs in RAFT using the slender-body approximation with the Kim and Yue correction.
Tests are passing locally, but GitHub actions is not working well for windows-latest. Only tests that use pyHAMS are breaking, and it seems that pyHAMS is not being installed correctly on windows-latest. Tests pass normally on ubuntu-latest and macos-latest.
Checklist
Put an
xin the boxes that apply.