Repository navigation
feat(rods): pinned and coupled-pinned rods on the coupled route - #22
Conversation
The coupled aggregate (CompMooring = 5) refused Pinned rods, because its
staggered rod march only integrates free rods, and every deck refused
MoorDyn-F's CoupledPinned/VesselPinned rods, whose pin translation the
host prescribes while the rod turns freely about it.
A pinned rod's step now advances only its rotation and snaps the rod
back to its pin. The rotation equation takes the pin acceleration, as
MoorDyn-F's does (MoorDyn_Rod.f90), and the force the rod puts on its
pin. A CoupledPinned rod takes its pin's position, velocity and
acceleration from the host, ignores the host orientation, and returns a
force and no moment; an output probe re-solves its angular acceleration
at the probed pin acceleration, as MoorDyn-F's CalcOutput re-evaluates
its state derivative. The pin moves linearly within a sub-step from the
committed start values, so a restart is bit-identical, and the
sub-step estimate includes pinned rods through their rotational inertia
about the pin. PtfmInit carries CoupledPinned rods, the static initial
condition treats them as pinned, and a rod end without a line no longer
needs a Rod<N>A/B point on the coupled route. Standalone decks refuse
CoupledPinned by name ("requires a coupled host"), FAST.Farm still
refuses rods, and linearisation still refuses rods.
Tests: a pinned pendulum against the elliptic period (1.6e-4); a
CoupledPinned rod on a held host bit-identical to the pinned one, with
zero moment and the analytic pin reaction (2e-13 m g); a constant pin
acceleration giving atan(a/g) and the period with the effective
gravity; harmonic base excitation converging at second order; coarse
against fine sub-steps; the probe's -m (Ic/Ip) a_p; snapshot, probe and
restart bit-identity; PtfmInit with the static initial condition; and
the standalone refusal. In an OpenFAST build, an IEA-15 MW chain hung
from a 4 m CoupledPinned rod runs 60 s in waves, a checkpoint restart is
bit-identical and NumCrctn = 1 equals 0. The theory page no longer says
MoorDyn-F's pinned-rod rotation omits the pin acceleration.
Signed-off-by: Jae Hoon Seo <jaehoon.seo@inha.ac.kr>
- The pin force of an output evaluation (CD_Rod_HostWrench) corrected the line-end acceleration with the condensed line mass, which assumes the line interior responds; an output evaluation freezes it, so a changed End-B acceleration moved the pin force by 0.57 N where the exact value moves 2e-11 N. It now uses the coupled-end mass of the frozen interior (CD_Calc_Model_CoupledEndMass, frozen_interior of CD_Calc_System_CoupledAccelDerivative); the step's corrector keeps the condensed mass, so step results are unchanged. - The rod state carries its step-start pin, set at init, after every step, on a mirror restore and on a host transfer that does not advance, so the first-step staging and the sub-step interpolation no longer depend on the caller passing the start pose. - Only Pinned and CoupledPinned rods may leave an end without a line or POINT row; any other rod end without one is refused by name, as before this branch. - The restart test compares loads before the next step as well; docs state the linear sub-step interpolation's order and that a pinned rod without a line keeps its deck orientation in statics. Signed-off-by: Jae Hoon Seo <jaehoon.seo@inha.ac.kr>
- theory: the starting angular acceleration of a pinned rod's first step is solved on the aggregate and the C API; under OpenFAST the rod mirror reloaded at the initial output call carries the accelerations of the initial condition (zero for the static start), so a start out of equilibrium begins from rest acceleration, as a free rod does. - VALIDATION: a held CoupledPinned node reproduces the Pinned rod to round-off (the test's 1e-12 bound), not bit for bit. - CHANGELOG: reflowed paragraph. Signed-off-by: Jae Hoon Seo <jaehoon.seo@inha.ac.kr>
|
@codex review |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8fedfffcc9
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
The coupled rod march sized its sub-steps for a pinned rod from the attached line springs only. A pinned rod with no line therefore always got omega^2 = 0 and one sub-step, although its weight and buoyancy make it a compound pendulum (omega^2 about 3g/(2L) when dry), so a short rod or a large coupling step could exceed the explicit central-difference limit or skip the accuracy sub-cycling. The estimate now adds the rod's swing about the pin. The vertical weight and buoyancy loads have the first moment P = sum f_i p_i about the pin, whose length |W d_g - B d_b| is the swing stiffness at the bottom of the swing in any pose; the buoyancy comes from the current wet distribution, now returned by rod_environment_force. The pin acceleration adds |a_p| |G|, with G the first moment of the rod's translational inertia (structural and added) about the pin, m d_g for a dry rod, taken with the larger of the step-start and end-of-step pin accelerations. The sum over the smaller rotational inertia about the pin across the rod axis adds to the line estimate of omega^2. Free rods, Rigid6 bodies and the multibody march are unchanged. Across the full test suite only the new test changes a sub-step count, so the existing pinned-rod results are bit-identical. A new case in openfast_pinned_rod runs a 1 m line-less Pinned rod, dry and hanging, and buoyant and upright under water, at a 0.6 s step (omega0 dt 2.29 and 3.42): it now takes 6 and 9 sub-steps, equals the run at the sub-step size bit for bit, stays within its release angle, and keeps the elliptic-integral period to 6.0e-3 and 5.9e-3. Taken whole, the same step turns the rod over. Signed-off-by: Jae Hoon Seo <jaehoon.seo@inha.ac.kr>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fe4f653b08
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
The host places a CoupledPinned rod's pin at t + dt before the rod march sizes its sub-steps, so the swing estimate saw only the end-of-step wetting. A pin that crosses the free surface within one coupling step could therefore take its sub-step count from the wrong wet state: a light rod lifted out of the water got the dry weight frequency, although its early sub-steps carry the much larger buoyancy restoring, and could exceed the central-difference stability limit. For a host-pinned rod the swing is now also evaluated with the rod at its step-start pin (pin0, committed orientation), and the estimate takes the larger swing stiffness and the smaller inertia of the two poses. The sub-steps move the pin along a straight line, so at the rod's orientation, with the surface held over the step, every slice's clearance to the surface changes monotonically and in the same sense: the wetting, the moment W d_g - B d_b and the added mass are bounded by the two ends, a surface-crossing step included. Fixed Pinned rods are unchanged. Across the full test suite only the two crossing steps of the new test change their sub-step count, so every other result is bit-identical. The new case in openfast_pinned_rod moves a line-less CoupledPinned rod across the surface in one step at constant velocity: a 1 kg/m rod lifted from submerged to dry in 0.1 s (omega dt 2.13 wet) and a 33 kg/m rod lowered from dry to submerged in 0.6 s (2.29 dry). Both now take 6 sub-steps and equal six steps at the sub-step size bit for bit; with the end-of-step wetting alone they take one and miss the angle by 0.20 and 0.69 rad. Signed-off-by: Jae Hoon Seo <jaehoon.seo@inha.ac.kr>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 796ee97722
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
The staggered march of free and pinned rods and Rigid6 bodies applies the seabed penalty springs explicitly, but sized its sub-steps from the line springs, the hydrostatic restoring and, for a pinned rod, its swing only. A rod or body resting on a stiff seabed could therefore keep one sub-step at a large coupling step while its contact mode exceeded the central-difference stability limit, and be thrown off the bed. This affected the coupled OpenFAST and C API routes, standalone rod decks and bodyScheme staggered; the monolithic scheme carries the contact in its Jacobian and is unchanged. The estimate now adds the contact springs that act within the coming step, as rod_seabed_contact and rigid6_seabed_contact apply them: kBot d dl at each rod contact station and kBot over 1 m^2 at a body's reference point (kBot per unit contact area, N/m^3). A station counts when its penetration plus its reach over the step, dt |v_z| + dt^2 max(|a_z|, g)/2, is positive, so an object about to land is covered as well as one already on the bed, including a first step without a committed acceleration. A spring k at arm a adds k in heave and k a_y^2, k a_x^2 in roll and pitch about the reference point; for a pinned rod the angular stiffness sum k |a x e_z|^2 about the pin is added to its swing stiffness, at both pin poses for a host pin. The normal damper is applied implicitly and sets no limit; the regularised friction is bounded by mu times the normal load. Across the full test suite and the shipped examples with bodies or rods, only the new test changes a sub-step count, so every existing result is bit-identical. A new case in openfast_pinned_rod puts a Pinned rod with its far end on a stiff seabed (kBot 1e7, 0.1 s step) and a Free rod lying on it (0.05 s step). They now take 20 to 25 and 26 sub-steps, stay at rest on the bed over 5 s and end within 1.6e-5 and 8e-8 of a run at a tenth of the step; with the previous counts of 1 and 4 they are thrown off the bed. Signed-off-by: Jae Hoon Seo <jaehoon.seo@inha.ac.kr>
Two explicit object marches took no sub-step estimate when no line was attached. A standalone deck without lines marched its bodies and rods by the central difference at dtM with no sub-steps at all, and the bodyScheme staggered multibody march skipped its bodies and rods in the estimate when the deck had no EI=0 line (finite-EI cables only). A short pinned rod or a body on a stiff seabed could therefore exceed the explicit stability limit there. The deck without lines now sub-cycles each step from the objects' own terms (objects_substep_count): a body's hydrostatic restoring and seabed contact over its mass and inertia as in step_rigid6_system, a free rod's seabed contact, and a pinned rod's swing about its pin with its contact as in step_rod_system. The staggered multibody march now includes its bodies and rods with or without lines, and adds a pinned rod's swing and its contact about the pin. A single sub-step keeps the previous step exactly, and the monolithic scheme is unchanged. Across the full test suite and every shipped example only the new test changes a sub-step count, so every existing result is bit-identical. A new case in bodies_rods runs a 1 m dry pinned rod at dtM = 0.6 s (omega0 dt = 2.29) on a deck without lines and on the staggered multibody march beside a finite-EI cable: both take 6 sub-steps, equal a dtM = 0.1 s run at every output row, stay within the release angle and keep the elliptic-integral period to 0.6 %. With one sub-step the rod turns over. Signed-off-by: Jae Hoon Seo <jaehoon.seo@inha.ac.kr>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f82f6ee269
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
The contact reach of the sub-step estimate looked only straight down: a station counted when its penetration plus dt |v_z| + dt^2 max(|a_z|, g)/2 was positive, against the floor at its current (x, y). A rod sliding or turning towards a shallower part of a bathymetry grid, or a station driven by rotation (w x s, and the centripetal w x (w x s) the old term left out), could therefore meet the stiff penalty bed within a step that the estimate had sized without its spring. contact_within_reach now bounds the travel of every contact point from its complete rigid-body motion: the reach dt |v + w x s| + dt^2 (|a| + |alpha x s| + |w|^2 |s| + g)/2 applies in every direction, and the point counts when its height above the highest floor within that horizontal distance is at most the reach plus the rod radius. On a flat seabed that floor is the depth; on a bathymetry grid the new CD_Bathymetry_Max_Floor returns the highest node of the cells the box around the disk overlaps, raised by CD_BATHY_CREASE_FRACTION times their range, which bounds the crease rounding. The rule serves every site of the estimate: free and pinned rods, Rigid6 reference points and the rods fixed to bodies (now with the body's centripetal term), the line-free march and the staggered multibody march. Across the full test suite and every shipped example the only changed sub-step counts are those of this branch's own seabed case in openfast_pinned_rod: its pinned rod now takes 34 to 36 sub-steps (was 20 to 25) and its dt/10 run 4 (was 2), and it ends within 1.9e-6 of that run (was 1.6e-5). Every other result is bit-identical. A new case in body_rod_physics carries a neutrally buoyant rod 0.5 m above a 10 m bed by a 2 m/s current onto a 45 degree ramp up 0.8 m at dtM = 0.2 s, out of vertical reach: a Free rod drifting onto it and a Pinned rod turning about its pin, whose stations reach the ramp only through rotation. Both stay out of the bed, below z = -8 m and within 0.2 m of a dtM = 0.05 s run; with the previous reach rule the Free rod ends 3 m from that run and the Pinned rod sinks 14 cm into the ramp and is thrown up to z = -7.7 m. Signed-off-by: Jae Hoon Seo <jaehoon.seo@inha.ac.kr>
Several loads of the explicit object marches were missing from the sub-step estimate or applied explicitly although stiff. Waterplane stiffness: rod_hydrostatic_stiffness adds, for a rod near the free surface, rhoW g D dl at each station whose section can cross the (held or wave) surface within the step and rhoW g pi D^2/4 where its axis can cross it, which together bound the elliptical waterplane of any crossing; the rod then takes its dry inertia, since its added mass changes as it crosses. It applies to free rods, pinned rods (about the pin, which also covers an articulated column) and the rods fixed to a Rigid6 body. A shared rod_estimate_terms now gives every route the same rod terms. Finite-EI cables: the staggered multibody march returns a cable's end force explicitly, so mb_cable_k6 adds its attachment spring, EA/L along the end force and T/L across, at its arm on the body or rod. Body-pinned rods: the staggered march takes the parent body's pin acceleration and a reduced-mass lower bound m m_b/(m + m_b) of the inertia about the pin, and sizes a pinned rod from its pin as the coupled route does. Seabed friction: the regularised friction -mu N v/sqrt(v^2 + vreg^2) is a damper of up to mu N/vreg, far stiffer than any practical step, and was evaluated explicitly, so a rod or body resting on a frictional bed chattered. rod_seabed_contact and rigid6_seabed_contact now return its secant coefficient in the implicit velocity derivative; the tangent would vanish where the trapezoidal acceleration rings. This changes the results of decks with rods or bodies on a frictional bed. The sub-step cap of 256 now warns once per run when a step needs more. The monolithic scheme is unchanged. Against 2e62a9c, every shipped example output is byte-identical. Of the existing tests only the staggered pinned-cable deck of clamped_cable_ends changes its sub-step count (10 steps now take 2 to 5 sub-steps; printed results unchanged), and the near-surface pinned cases of openfast_pinned_rod add waterplane sub-steps: the buoyant upright swing moves to 15 m depth, out of the surface's reach, and the surface-crossing steps are compared with a run at a sixtieth of the step (5e-5 and 3e-4 rad). New cases: a floating 5 cm rod at a 0.1 s step (omega dt 2.2) keeps its 5 mm heave (38 mm without the waterplane term); a rod held by friction in a cross current holds still, creeping at 1.3e-4 m/s with 2.5e-4 N of net load (5.3e-3 m/s and 75 N before); a pinned rod on a stiff finite-EI cable at 0.05 s stays within 0.4 mm and matches a dt/10 run to 6e-6 m (0.97 m off before). Signed-off-by: Jae Hoon Seo <jaehoon.seo@inha.ac.kr>
|
A systematic pass over every stiffness acting on an explicitly stepped rod or body found further gaps in the sub-step estimate and the explicit friction; all are fixed in 0463a0a:
All 101 shipped-example output files are byte-identical; |
|
@codex review |
|
Codex Review: Didn't find any major issues. Chef's kiss. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Summary
The coupled aggregate (
CompMooring = 5) refusedPinnedrods, because its staggered rod march integrated only free rods. Every deck refused MoorDyn-F'sCoupledPinned/VesselPinnedrods, whose pin translation the host prescribes while the rod turns freely about it. Both now run on the coupled route.MoorDyn_Rod.f90).CoupledPinned/VesselPinned.CD_Calc_Model_CoupledEndMass), so it no longer depends on the probed end accelerations: 2e-11 N, against 0.57 N with the condensed mass. The step itself keeps the condensed mass, so step results are unchanged.PtfmInitcarriesCoupledPinnedrods, and the static initial condition treats them as pinned.PinnedorCoupledPinnedrod that carries no line needs noRod<N>A/BPOINT row on the coupled route. Any other bare rod end is refused by name, as before.CoupledPinnedon standalone decks and in the C API ("requires a coupled host");CoupledPinnedbodies.Tests
openfast_pinned_rodon the aggregate:dt = T/100CoupledPinnednodePinnedrod to round-off, zero moment, analytic pin reaction to 2e-13m gatan(a/g)to 1e-6 rad; period with the effective gravity-m (I_c/I_p) a_pPtfmInitwith the static startC API:
Pinnedrod decks run;CoupledPinnedis refused.OpenFAST (IEA-15 MW UMaine, JONSWAP Hs 6 m, 60 s,
dtM = DT = 0.025 s), with line 1 hung from a 4 mCoupledPinnedrod at its fairlead:openfast -restartat 30 s, every OpenFAST output row is bit-identical, forNumCrctn0 and 1;NumCrctn = 1equalsNumCrctn = 0bit for bit;Coupledpoint.Full suite (Windows, gfortran, Release, slow tier included): 265/265. Python: 2007 passed.
pre-commit run --all-filesand the Sphinx build with-Wpass, and the OpenFAST module builds.Checklist
pre-commit run --all-filespassesctest --test-dir build --output-on-failurepassespython -m pytest tests python/testspasses (if Python or validation records changed)[Unreleased](heading added if missing) for user-visible changesdoc/updated for changed inputs, options, or outputsfeat:,fix:,docs:, ...)git commit -s) under theDeveloper Certificate of Origin