Skip to content

fix: handle still-air AeroDyn linearization - #3479

Open
RanaPriyansh wants to merge 2 commits into
OpenFAST:devfrom
RanaPriyansh:fix/3439-still-air-linearization
Open

RanaPriyansh wants to merge 2 commits into
OpenFAST:devfrom
RanaPriyansh:fix/3439-still-air-linearization

Conversation

@RanaPriyansh

@RanaPriyansh RanaPriyansh commented Sep 28, 2026 •

Copy link
Copy Markdown

Feature or improvement description

AeroDyn linearization dereferences an absent flow field when CompInflow=0. Register extended wind inputs only when the field exists, and preserve general-support inflow when no field is available.

Related issue, if one exists

Fixes #3439.

Impacted areas of the software

AeroDyn input registration, general-support wind calculation, and regression tests.

Additional supporting information

Still-air linearization omits unavailable wind coordinates while retaining mechanical aerodynamic derivatives. The enabled-wind control preserves channel ordering, dimensions, operating points, and matrix values.

Generative AI usage

Codex used.

Test results, if applicable

  • Both new regressions fail on the unmodified baseline and pass with this repair.
  • Registered still-air linearization CTest and AeroDyn unit tests pass.
  • Retained still-air control fixtures used LinInputs=1. Corrected private controls for modes 0, 1, and 2 remain unrun.
  • All five enabled-wind linearization files match baseline numeric data exactly.
  • Fortran tab check, Python compilation, and whitespace check pass.
  • The full repository suite, MHK wave runtime path, and hosted CI have not been verified.
  • r-test branch merging required

@RanaPriyansh
RanaPriyansh marked this pull request as ready for review September 28, 2026 12:36

@andrew-platt andrew-platt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Thanks!

@andrew-platt

Copy link
Copy Markdown
Collaborator

Thanks @RanaPriyansh!

I ran this through Claude code specifically to check if there might be potential side effects that could be a problem later.

Line numbers below are from the current dev tree, not the PR head.

1. The FlowField check happens only once, during AD_Init

The PR passes associated(p%FlowField) into AD_InitVars during AD_Init. Any caller that attaches the FlowField after AD_Init returns will silently get no extended wind inputs. Two callers do this today:

  • ExternalInflow (modules/openfast-library/src/FAST_Subs.f90:875): AD%p%FlowField => Init%OutData_ExtInfw%FlowField runs after AD is initialized. This is harmless now, because linearization with ExternalInflow is already a fatal error (FAST_Subs.f90:2170).
  • AeroMap (modules/openfast-library/src/FAST_AeroMap.f90:134): IfW_SteadyFlowField_Init(T%AD%p%FlowField, ...) runs after FAST_InitializeAll. After this PR, AeroMap no longer registers the three wind inputs. Its Jacobians use only VF_AeroMap-flagged variables (FAST_AeroMap.f90:174), and these inputs never had that flag, so AeroMap output should not change. The PR only verified the five linearization baselines, so the AeroMap regression tests should pass in CI before merge.

Neither case causes a problem today. The risk is that a future caller doing linearization, or code that relies on these inputs, attaches the FlowField after init and quietly loses them, with no error.

Suggestion: either

  • add a comment at the AD_InitVars call (AeroDyn.f90:624) saying the FlowField must be attached before AD_Init to get extended inputs, or
  • check at run time instead of at init: keep the variables registered, but skip them in AD_VarsPackExtInput and in the FlowField copy and perturbation in RotJacobianPInput when .not. associated(p_AD%FlowField). This removes the ordering trap.

2. The GS and rotor wind routines now handle a missing FlowField differently

AD_CalcWind_Rotor returns as soon as there is no FlowField (AeroDyn.f90:2151), before its MHK wave branch. After this PR, AD_CalcWind_GS (AeroDyn.f90:2297-2316) behaves differently:

  • With MHK waves on (p%MHK /= MHK_None .and. p_AD%CompSeaSt), it still evaluates waves without a FlowField.
  • Otherwise, it skips the InflowWind call, leaves GSInflow%InflowVel unchanged, and still advances StartNode.

So in an MHK case with SeaState but no FlowField, the support structure would see wave kinematics while the rotor sees none. MHK normally runs with InflowWind (current), so this is unlikely in practice, but the two routines now disagree.

Suggestion: make the two routines consistent. Either give AD_CalcWind_Rotor the same structure (wave branch first, InflowWind branch guarded), or have AD_CalcWind_GS return early like the rotor routine while still advancing StartNode.

@andrew-platt

Copy link
Copy Markdown
Collaborator

One other change before this can be merged:

  • drop the new python test reg_tests/test_compinflow0_linearization.py. This is an unnecessary case and not exactly in line with the intent of the case sets in that location.

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.

OpenFAST linearization cases segfault with AeroDyn and no InflowWind

2 participants