Skip to content

Conversation

@RyanDavies19
Copy link
Collaborator

@RyanDavies19 RyanDavies19 commented Mar 12, 2025

This is the flexstate compatible version of #290. Thanks for all the help @sanguinariojoe!

New Features

This work contains two new features. Theory papers will be linked to this PR when publicly available.

  1. The first is a vortex-induced-vibration model based on the work of Thorsen et al.. We have a paper submitted for this and when a preprint is released I will link it here. The semi-empirical model gives an oscillating lift force on each node. As part of this implementation, there is a synchronization model that looks at changes between the lift force phase and line motion phase. This model requires knowledge of the lines current acceleration (which we approximate by the previously calculated value) and an additional state variable that is integrated every time step. We validated this approach against the results in the original theory paper using rk4. We did not test this approach with implicit integration schemes, though my hope with the acceleration approximation was that it would work in that case. I will add a warning that requires users to use explicit schemes.
  2. The second is a pair of viscoelastic models that have been implemented in MoorDyn-F to simulate non-linear rope behavior. They are based on the idea of dividing a segment into a spring-dashpot in parallel in series with a second spring-dashpot in parallel (the Kelvin representation of the standard linear solid model in the case where dynamic damping = 0). A constant dynamic stiffness approach is explained in this paper. The mean-load dependent dynamic stiffness model builds off this work by changing the dynamic stiffness as a function of mean load. Test results for this are shown in the MoorDyn-F PR (MD: Adding Load dependent dynamic stiffness OpenFAST/openfast#2459). Both of these require an additional state to handle the length of one of the springs in the subdivided segment. Long term, it would be great to allow for n-number of spring damper parallel components attached in series, which would require n more states per node. This would give us access to the true generalized Kelvin model. (A similar approach could be done with the generalized Maxwell viscoelastic model, also requiring n number of additional states per node). The mean-load dependent viscoelastic model internalizes the process of calculating the dynamic stiffness as a function of mean load. Add the possibility to set the constant EA on real time #194 introduced an API entry to enable this by using an external caller (as demonstrated in the polyester test), but that requires knowledge of the current tension to find the current stiffness and then adjusting the unstretched lengths of the segments. This approach allows the user to just provide the constant and load dependent terms of the viscoelastic equation as coefficients while MoorDyn internally handles the rest (without changing the unstretched length).

The documentation updates reflect the input file changes that enable these new features. Other minor changes are:

  1. # is now a comment character in the input file and all text on a line after # is ignored. This matches MD-F
  2. Added space before messages output by WaterKin to make the terminal output more clear
  3. The VIV force and the line curvature at each node are additional line output flags

State Approach

See #291. A note on the size of the line state instance: This implementation means that when simulating viscoelastic only, the line state instance is Nx7, when simulating VIV only N-1x7 and when simulating both VIV and viscoelastic Nx8. This does introduce unused spaces in the matrix, notably with the viscoelastic model. Indexing of the matrix is as follows (from comments in Line::setState):

	// ----- State Instance Structure for Line -----
	// Each row corresponds to an internal node. When the viscoelastic case is 
	// activated the last column corresponds to the viscoelastic state for each segment. 
	// This means indexing the rows for the viscoelastic state is shifted by one.
	//
	// Normal case:
	//  - N-1 rows
	//	- row[i] = [rix, riy, riz, rdix, rdiy, rdiz]
	// VIV case:
	//  - N-1 rows
	//	- row[i] = [rix, riy, riz, rdix, rdiy, rdiz, phii]
	// Viscoelastic case:
	//  - N rows
	//	- row[i] = [rix, riy, riz, rdix, rdiy, rdiz, ldot_1i]
	//  - note there will be 6 unused values in the last row
	// VIV and viscoelastic case:
	//  - N rows
	//	- row[i] = [rix, riy, riz, rdix, rdiy, rdiz, phii, ldot_1i]
	//  - note there will be 7 unused values in the last row

This addresses the conversation started in #261 and #269 (comment).

Viscoelastic Verification

To verify the viscoelastic model, we replicated the results seen in OpenFAST/openfast#2459. This test introduced sinusoidal oscillations at different displacements to test the dynamic stiffness response. The figures below show the strain as a function of time and the stress strain curve from this test. The viscoelastic model impact on the dynamic stiffness is clear, at larger strains the line has a higher dynamic stiffness. This test has been added to the polyester tests.
mdc_strain
mdc_stress_strain

TODO:

  • Resolve the failing tests
  • Develop test for VIV
  • Warning for users when using explicit schemes
  • Develop test for viscoelastic models
  • Clean up and adapt to new state approach
  • Clean up commit history to remove duplicates
  • Ensure performance is retained with new state approach
  • Handle defaults for viscoelastic and VIV states when loading in exported states (from MoorPy, Map++, or MoorDyn)

@RyanDavies19
Copy link
Collaborator Author

Some more notes: I disabled all output time printing for the tests so that the logs are much easier to read. Also I adjusted spacing in messages printed by wavekin.

@RyanDavies19 RyanDavies19 marked this pull request as ready for review March 18, 2025 20:28
@RyanDavies19
Copy link
Collaborator Author

@sanguinariojoe, this is ready for review when you get a chance. Also, any ideas of why tests are failing on Windows and Ubuntu but passing on MacOS? I am assuming some compiler differences, could it be an uninitialized variable or something similar?

@sanguinariojoe
Copy link
Collaborator

@sanguinariojoe, this is ready for review when you get a chance. Also, any ideas of why tests are failing on Windows and Ubuntu but passing on MacOS? I am assuming some compiler differences, could it be an uninitialized variable or something similar?

Yep, you have memory errors. I am checking them

@sanguinariojoe
Copy link
Collaborator

@RyanDavies19 I marked you all the memory errors I have found. After fixing them, all the tests are completely clean of mem errors.

Regarding the time_schemes test, I would say it is just machine epsilon level errors. I have been prompting the states of the offending time integrator every single iteration, and everything is identical up to t = 0.0377 (29 steps).
The problem is that we are so close to the stability limit on that test... Just changing https://github.com/RyanDavies19/MoorDynC_ryan/blob/viv_flexstate/tests/time_schemes.cpp#L82 by

"1.2E-3", // BEuler15

fixes the problem on Linux.

@RyanDavies19
Copy link
Collaborator Author

By some form of dark magic I don't understand, a5aacc3 seemed to fix the failing windows test.

This is ready to merge after you review @sanguinariojoe.

@sanguinariojoe
Copy link
Collaborator

Everything looks fine on my side. I was just checking that the IC is not messing up, but it seems that you have it well controlled with the IC_gen and t_old vars.

So green light from my side, you can merge

@RyanDavies19 RyanDavies19 changed the title WIP Vortex Induced Vibrations and Viscoelastic model for MoorDyn-C Vortex Induced Vibrations and Viscoelastic model for MoorDyn-C Mar 25, 2025
@RyanDavies19
Copy link
Collaborator Author

Everything looks fine on my side. I was just checking that the IC is not messing up, but it seems that you have it well controlled with the IC_gen and t_old vars.

So green light from my side, you can merge

Great thanks, merging! Yeah without the IC_gen flag and t_old it would never initialize in steady state because of the quasi-chaotic nature of the model (especially when currents were involved). It does mean that the first few seconds of a simulation with VIV will show the model kicking in and the system approaching a lock-in state.

@RyanDavies19 RyanDavies19 merged commit 5360de7 into FloatingArrayDesign:dev Mar 25, 2025
7 of 8 checks passed
@RyanDavies19 RyanDavies19 deleted the viv_flexstate branch March 25, 2025 14:23
@RyanDavies19
Copy link
Collaborator Author

Linking the pre-print of the theory paper for the VIV model: https://dx.doi.org/10.2139/ssrn.5445966

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants