Repository navigation
Conversation
…-vector helper Morison_CalcOutput only consumed the axial unit vector k_hat from GetOrientationAngles; its tilt/heading trig outputs were unused. Replace that routine with a slim GetElementAxialVec(p1,p2,k_hat,...) that returns only k_hat and keeps the zero-length-element fatal guard (do not assume rigid structure). Convert the marine-growth weight moments F_WMG(4)/F_WMG(5) from sinPhi*sinBeta / sinPhi*cosBeta to the exact identities k_hat(2)/k_hat(1), update all four call sites, and drop the now-dead trig locals. Co-authored-by: GitHub Copilot <copilot@github.com> Co-authored-by: Claude <noreply@anthropic.com>
…helper Collapse the three duplicated external end-plate buoyancy blocks into a single contained AddEndBuoyancy subroutine, replace the brittle EqualRealNos partial-wetting arc test with the secStat classification returned by GetSectionFreeSurfaceIntersects_Cyl, drop the dead SetErrStat after that call, and convert the section-geometry branch to SELECT CASE. Co-authored-by: GitHub Copilot <copilot@github.com> Co-authored-by: Claude <noreply@anthropic.com>
Convert bare SetErrStat propagation sites to 'if (Failed()) return' so fatal errors from sub-calls abort instead of continuing with bad data. Fixes two lost-error cases: paired GetTotalWaveElev calls that shared one SetErrStat (first status overwritten), and the VisMesh Transfer_Point_to_Line2 call that passed ErrStat/ErrMsg directly and clobbered accumulated errors. Co-authored-by: GitHub Copilot <copilot@github.com> Co-authored-by: Claude <noreply@anthropic.com>
…tput Co-authored-by: GitHub Copilot <copilot@github.com> Co-authored-by: Claude <noreply@anthropic.com>
Store each member's undisplaced section direction-cosine matrix as member%CMatrix at initialization instead of recomputing it every step via Morison_DirCosMtrx inside Morison_CalcOutput and getMemBallastHiPt. The reference DCM is constant per (straight) member, so the per-step calls built from the static u%Mesh%Position were redundant. CMatrix is computed once in SetMemberProperties_Cyl (spin 0, axisymmetric) and SetMemberProperties_Rec (spin = MSpinOrient), then combined with the instantaneous u%Mesh%Orientation at each use site, preserving results bit-for-bit. - Add CMatrix(3,3) to Morison_MemberType (registry + regenerated types). - YawMember now yaw-rotates x_hat/y_hat for all section geometries, and deliberately leaves CMatrix in the undisplaced frame since it is composed with the full nodal orientation downstream. - Remove dead Morison_DirCosMtrx calls, unused CMatrix/CMatrix0 locals, and the redundant MSecGeom checks in SetMemberProperties_Rec and YawMember. Co-authored-by: GitHub Copilot <copilot@github.com> Co-authored-by: Claude <noreply@anthropic.com>
Delete dead code with no callers: Morison_DirCosMtrx_noSpin (generic interface collapsed to Morison_DirCosMtrx), ElementCentroid, ElementVolume, FindInterpFactor, InterpWrappedStpInt, InterpWrappedStpLogical, DistributeElementLoads, and AddEndLoad, plus stale commented references. Co-authored-by: GitHub Copilot <copilot@github.com> Co-authored-by: Claude <noreply@anthropic.com>
Replace the trig-based incline angle (phi/sinPhi/cosPhi via acos/sin/cos) in member initialization with direct axial-unit-vector expressions, remove the now-redundant cosPhi_ref member field (consumers use k(3)), and guard the inclination-threshold checks with ABS(cosPhi) so a reversed member is still treated as vertical. Co-authored-by: GitHub Copilot <copilot@github.com> Co-authored-by: Claude <noreply@anthropic.com>
Replace the yaw-only YawMember/YawJoint helpers with RotateMemberNode and RotateJoint, which rotate reference-configuration member and joint properties to either the reference-yaw orientation (WaveDisp=0) or the full instantaneous node orientation (WaveDisp=1). Rotate per node in all three hydrodynamic loops (smoothing, no-smoothing, UpdateDiscState) and at the free-surface-crossing element, reading from the pristine parameter copy to avoid compounding. Keep hydrostatic loads on exact orientation. Remove the input constraint forbidding PtfmYMod=1 with WaveDisp=0 and clean up error handling in Morison_UpdateDiscState. Co-authored-by: GitHub Copilot <copilot@github.com> Co-authored-by: Claude <noreply@anthropic.com>
Add a PtfmRefXY pipeline so strip-theory (Morison) members translate with the low-frequency / instantaneous horizontal drift of the HydroDyn origin when WaveDisp=0, mirroring the existing PtfmRefY reference-yaw treatment and the WAMIT ExctnDisp filter. The drift follows the user-specified ExctnDisp/ExctnCutOff regardless of whether potential-flow bodies are present: the raw ExctnDisp is captured into p%PtfmXYMod before HydroDynInput_ProcessInitData may force it to 0 for the WAMIT grid, and the ExctnCutOff>0 validation is checked beforehand and broadened to ExctnDisp=2. Co-authored-by: GitHub Copilot <copilot@github.com> Co-authored-by: Claude <noreply@anthropic.com>
Update the WaveDisp input comment and documentation to reflect the clearer interpretation: WaveDisp=0 places strip-theory members/joints at a potential-flow-consistent reference configuration (reference yaw plus horizontal x-y drift governed by ExctnDisp/ExctnCutOff), and WaveDisp=1 uses the exact instantaneous displaced position and orientation. Updates input_files.rst, appendix.rst, api_change.rst, and the FAST_writer.py comment string. Co-authored-by: GitHub Copilot <copilot@github.com> Co-authored-by: Claude <noreply@anthropic.com>
…heory Remove the hidden logic that dropped the vertical (Z) displacement of strip-theory member nodes when wave stretching was disabled. The member submergence status now checks every node (members are no longer assumed rigid/straight), and load smoothing is applied for right-side-up members crossing the free surface once whenever wave stretching is enabled or WaveDisp=1, since both can drive nodes in and out of the water. Smoothing is skipped only when WaveStMod=0 and WaveDisp=0. Update input_files.rst to drop the obsolete Z-displacement explanation. Co-authored-by: GitHub Copilot <copilot@github.com> Co-authored-by: Claude <noreply@anthropic.com>
…d loads The AMMod switch selected whether the distributed strip-theory added-mass force was evaluated only up to the SWL (0) or followed the instantaneous wetted section (1). With the improved solver stability in 5.1.0 the SWL-only option is no longer needed, so AMMod is removed and the added-mass force is now computed the same way as the other distributed loads: up to the instantaneous free surface when wave stretching is enabled (WaveStMod > 0) and up to the SWL otherwise. Removes AMMod from the Morison registry/types, HydroDyn input parsing and validation, the Python reader/writer, and the documentation (with an api_change.rst entry). Bumps the r-test pointer to the input files with the AMMod line removed (required because HydroDyn uses fixed-form line-position input parsing). Co-authored-by: GitHub Copilot <copilot@github.com> Co-authored-by: Claude <noreply@anthropic.com>
…thing Use the SWL (z=0) as the free surface when wave stretching is disabled in the smoothing loop, matching how nodeInWater/MemSubStat are determined. Previously the instantaneous wave elevation was used to locate the crossing element while in-water status used the SWL, so the WaveStMod=0 + WaveDisp=1 combination could leave FSElem unset (-1) and segfault when indexing arrays. Also add a fatal-error guard if no free-surface-crossing element is found. Co-authored-by: GitHub Copilot <copilot@github.com> Co-authored-by: Claude <noreply@anthropic.com>
andrew-platt
requested review from
jjonkman
and
a balanced review from Copilot
October 8, 2026 20:18
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Input validation and documentation still conflict with the newly introduced WaveDisp and ExctnDisp behavior.
3 open findings
What changed in this PR
Refactors HydroDyn strip theory to support consistent reference or full instantaneous member motion while simplifying added-mass handling.
Changes:
- Redefines
WaveDispfor full position/orientation handling. - Removes
AMModand consolidates Morison load logic. - Updates serialization, Python I/O, and documentation.
| File | Description |
|---|---|
openfast_io/openfast_io/FAST_writer.py |
Writes the revised strip-theory format. |
openfast_io/openfast_io/FAST_reader.py |
Reads HydroDyn files without AMMod. |
modules/hydrodyn/src/Morison.txt |
Updates Morison Registry types. |
modules/hydrodyn/src/Morison.f90 |
Refactors displacement, rotation, and load calculations. |
modules/hydrodyn/src/Morison_Types.f90 |
Updates generated Morison types and serialization. |
modules/hydrodyn/src/HydroDyn.txt |
Adds horizontal reference-drift state definitions. |
modules/hydrodyn/src/HydroDyn.f90 |
Computes and propagates reference XY drift. |
modules/hydrodyn/src/HydroDyn_Types.f90 |
Adds drift states and parameters. |
modules/hydrodyn/src/HydroDyn_Input.f90 |
Removes AMMod parsing and revises validation. |
docs/source/user/hydrodyn/input_files.rst |
Documents revised strip-theory behavior. |
docs/source/user/hydrodyn/appendix.rst |
Updates the example HydroDyn input. |
docs/source/user/api_change.rst |
Records the input/API changes. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+1507
to
+1509
| if ( InputFileData%WAMIT%ExctnDisp == 2 .and. InputFileData%WAMIT%ExctnCutOff <= 0.0 ) then | ||
| CALL SetErrStat( ErrID_Fatal,'ExctnCutOff must be greater than zero.',ErrStat,ErrMsg,RoutineName) | ||
| end if |
Comment on lines
+324
to
+325
| Note that **PtfmYMod** and **PtfmRefY** also affect the strip-theory | ||
| hydrodynamic load when **WaveDisp** = 0. In that mode, the displacement |
| # | ||
| typedef ^ InputType MeshType Mesh - - - "Kinematics of each node input mesh" - | ||
| typedef ^ ^ ReKi PtfmRefY - - - "Reference platform yaw offset" (rad) | ||
| typedef ^ ^ ReKi PtfmRefXY {2} - - "x,y drift of the HydroDyn origin (PRP), consistent with potential-flow body ExctnDisp. Used to displace the Morison members when WaveDisp=0" (m) |
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.


This PR is ready to be merged.
Feature or improvement description
This PR includes various improvements to the strip-theory code within HydroDyn. The changes include simple clean-up and refactoring, streamlining the formulation and internal logic, and upgrades for unrestricted strip-theory member rotation. These changes were made to prepare HydroDyn for planned upcoming upgrades and new features. Key changes are listed below.
Strip-theory member displacement (
WaveDisp)Strip-theory member displacements are controlled by the
WaveDispsetting. Previously:WaveDisp=0held the strip-theory members at the fixed reference position. The only displacement was due to a static floater yaw orientation offset given byPtfmRefYwithPtfmYMod=0. Because the strip-theory members were fixed in place,WaveDisp=0could not be used with a dynamic reference yaw position (PtfmYMod=1). OpenFAST would error out with this input combination.WaveDisp=1, a mixed approach was used: the strip-theory member nodes and joints were allowed to move following the instantaneous motion of the structure, except that any vertical displacement was ignored when wave stretching was disabled (WaveStMod=0). The wave kinematics and dynamic pressure were computed at the displaced nodal/joint positions. However, the member and joint orientations were only updated based on the reference platform low-frequency yaw offsetPtfmRefY(static or dynamic) when computing the strip-theory loads. This implementation was adopted to maintain some geometric consistency with the potential-flow bodies, which only have XY-plane drift and low-frequency yaw corrections.The previous formulation was somewhat convoluted, opaque, and not fully consistent. For example, it used instantaneous nodal displacements for wave kinematics but corrected member/joint orientations only for low-frequency yaw drift. With the present upgrade, the strip-theory member displacement is reformulated and the
WaveDispswitch reinterpreted in a more intuitive fashion.WaveDisp=0now positions and orients strip-theory members and joints in a way that is strictly geometrically consistent with the potential-flow bodies. Both the nodal positions (at which wave kinematics and dynamic pressure are computed) and the member/joint orientations are updated only according to the platform reference yaw (PtfmRefY) and platform XY-drift following the sameExctnDispandExctnCutoffsettings used by the potential-flow bodies. This implies only 3-DOF horizontal-plane displacements (surge, sway, and yaw).WaveDisp=1now positions strip-theory members/joints based on the full, exact instantaneous displacement of the structure. Both nodal positions and joint/member orientations are updated based on the 6-DOF motion of the structure with nonlinear rotation. This means a strip-theory-only model no longer places any constraint on body rotation, and HydroDyn can be used to model, e.g., the upending of a spar where the structure rolls/pitches by 90 deg. Furthermore, the full displacement in all three directions is now included regardless ofWaveStMod. Load smoothing is enabled when eitherWaveStMod>0orWaveDisp=1for suitable surface-piercing members, since either option can cause nodes to enter/exit the water. Additionally, withWaveDisp=1, HydroDyn no longer assumes rigid/straight members, which can be useful when coupled with other structural solvers.Added mass (
AMMod)Previously, an
AMModswitch was included in the primary HydroDyn input file. SettingAMMod=0forced HydroDyn to always compute the distributed added-mass force up to the still-water level while neglecting structure Z-displacement. This was added to address numerical stability issues with some hydroelastic models.With the general improvement to core solver stability since OpenFAST v5, this is deemed no longer necessary, and it is hardly ever used based on user feedback. Therefore, the
AMModinput option is removed here to further streamline the internal logic. Added mass is now computed with the same wetted-section logic as the drag/inertia components (up to the instantaneous free surface whenWaveStMod>0, SWL otherwise), eliminating the separateAMModcode paths.Code cleanup
CMatrix).SELECT CASE.AddEndBuoyancyhelper subroutine.Morison.f90.Interface / input changes
Removed
AMModfrom the HydroDyn primary input file and modifiedWaveDispinput comment (seeapi_change.rstand updated HydroDyn user docs).openfast_ioreader and writer are also updated accordingly.Documentation
Updated HydroDyn
input_files.rst,appendix.rst, andapi_change.rst: rewroteWaveDispsemantics, removed the obsolete vertical-displacement explanation, and documented theAMModremoval.Impacted areas of the software
HydroDyn, openfast_io, docs, r-test
Generative AI usage
Co-authored-by: Anthropic Claude claude@anthropic.com
Assisted by: GitHub Copilot support@github.com
Test results, if applicable
Due to the changes to
WaveDisp=1behavior, the results of the following three tests changed slightly:hd_5MW_ITIBarge_DLL_WTurb_WavesIrr5MW_ITIBarge_DLL_WTurb_WavesIrr5MW_MRSemi_DLL_WSt_WavesIrrThe changes are expected and small (differences relative to the previous baseline are of the same order of magnitude as the tolerance threshold).