Skip to content

Merge rc-5.0.1 to dev (maintenance) - #3474

Merged
andrew-platt merged 34 commits into
devfrom
m/501_dev_Sept26
Sep 24, 2026
Merged

andrew-platt merged 34 commits into
devfrom
m/501_dev_Sept26

Conversation

@andrew-platt

Copy link
Copy Markdown
Collaborator

Ready to merge

Feature or improvement description

Cross-merge of rc-5.0.1 into dev (maintenance). This brings forward the 9 pull requests
merged to rc-5.0.1 since the last cross-merge (dda62d29c, 2026-08-18, merge base d7efb44df),
plus one direct commit. 32 commits total.

OLAF / FVW

AeroDyn / InflowWind

Build / CI

Direct commit (no PR)

Related issue, if one exists

N/A — maintenance cross-merge.

Impacted areas of the software

  • AeroDyn — AeroDyn.f90, OLAF/FVW (FVW.f90, FVW_Subs.f90, FVW_BiotSavart.f90,
    FVW_VortexTools.f90, FVW_IO.f90)
  • InflowWind — IfW_FlowField.f90
  • LinDyn, MoorDyn, NWTC Library, ServoDyn/StrucCtrl — whitespace only (tab removal, F/gh action tab check #3469)
  • Build system — cmake/OpenfastFortranOptions.cmake
  • CI — new tab-check GitHub action
  • reg_tests/r-test — submodule pointer updated

Additional supporting information

Two changes need attention during verification:

The reg_tests/r-test submodule conflict was resolved with a real submodule merge commit
(fbe583ae), whose parents are the dev pointer (8aefcb0e) and the rc-5.0.1 pointer
(2aa16648).

Note that the tab-check workflow added by #3469 now runs against dev for the first time.

Generative AI usage
Claude Code (Opus 5) was used to analyze the commit ranges and assemble this pull request summary.
No source code was generated by AI in this merge.

Co-authored-by: Anthropic Claude [email protected]

Test results, if applicable

  • r-test branch merging required

luwang00 and others added 30 commits August 14, 2026 16:23
…MP data race

FVW treecode: the wake path used Tree%DistanceDirect = 2*mean(RegParam), averaged over an over-allocated array whose sentinel tail drove it negative during wake buildup, disabling the near-core direct-evaluation fallback. Replace it with a per-node maxRegParam (max eps over the cell's particles); each branch now uses distDirect = BranchFactor*radius + 2*maxRegParam so control points inside a regularization core fall back to direct evaluation. Applied to both the particle and segment trees.

TwrInflArray: make FirstWarn_TowerStrike firstprivate and ErrStat2/ErrMsg2 private in the OpenMP loop to avoid a data race.

Co-authored-by: Copilot <[email protected]>
Co-authored-by: Claude Opus <[email protected]>
In ui_part_nograd_11 the idRegExp mollifier (1-exp(-(r/rc)^3))/r^3 differs from 1/r^3 by <exp(-8)~3.4e-4 once r>2*rc, which is exactly the accuracy the far-field multipole already accepts at its BranchFactor*radius+2*maxRegParam floor. Treat the mollifier as 1 beyond that boundary (new PART_REG_NRAD/PART_REG_CUT3 params) so the near-field direct kernel and the far-field multipole share the same 2*rc cutoff. Since most near-field tree pairs have r>>rc, this skips exp() for the majority of evaluations, giving ~25-32 percent serial speedup on the treecode path with the output unchanged to ~1.8e-5 relative. Also caches r^2/r^3/rc^3 to drop redundant ** intrinsics; the compact-support branch is refactored identically (bit-for-bit).

FVW_Subs: scope the DEV_VERSION NaN/sentinel checks in SegmentsToPartWrap to the active particles (1:nPart); the preallocated tail intentionally keeps its sentinel and must not trip the check.

Co-authored-by: Copilot <[email protected]>

Co-authored-by: Claude Opus <[email protected]>
OLAF: fix source-panel filename parsing (relative path)
SoilDyn initialization crash: stack overflow with MinGW
…d dispatch to select case

Remove always-zero T_Tree%DistanceDirect field and its assignments; the two wake-path reads now pass 0.0_ReKi literally (regularization floor is applied per node via node%maxRegParam). Convert the if/elseif velocity-method dispatch in FVW_InitRegularization, InducedVelocitiesAll_Init/Calc/End and LiftingLineInducedVelocities to select case, adding case default fatal for unhandled methods. Blade-path DistanceDirect (MaxWingLength*2.2) is unchanged.

Co-authored-by: Copilot <[email protected]>

Co-authored-by: Claude Opus <[email protected]>
Fix OLAF wake time-step detection losing precision over many time steps
AD: fix OLAF treecode near-core regularization floor and TwrInfl OpenMP data race
OpenFAST style requires 3 space indentation in Fortran source; tab
characters are not allowed because they render inconsistently across
editors and break continuation-line alignment.

Add a workflow that scans every git-tracked *.f90 / *.F90 file and
reports the file, line, and column of each tab found, failing the job
if any are present. Findings are also emitted as GitHub annotations so
they appear inline on the pull request diff.

Registry-generated *_Types.f90 files are excluded from the scan, since
they are produced by the OpenFAST Registry rather than edited by hand.

Also remove the 7 pre-existing tab characters so the check passes on a
clean tree. All were in comments or whitespace-only lines, so there is
no change in behavior.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
The omega_P description in StrucCtrl_Registry.txt contained tab
characters, which the Registry copied verbatim into the generated
Doxygen comment in StrucCtrl_Types.f90. Replace them with spaces,
matching the alignment of the neighboring alpha_P entry, and
regenerate StrucCtrl_Types.f90.

Comment text only; no change in behavior.

Assisted-by: LLM [Claude Code] [Copilot]
Two issues raised in review of the tab check script:

- The repository-root guard was ineffective. When "git rev-parse
  --show-toplevel" fails it produces no output, and "cd ''" returns 0
  and stays in the current directory, so the "|| exit 1" never fired
  and the script ran on whatever directory it was invoked from.
  Capture the root first and test that command's status directly.

- "grep ... || continue" treated an I/O error (exit 2) the same as
  "no match" (exit 1), so a file that failed to scan was silently
  skipped and the job still passed. Skip only on exit 1 and abort on
  any other non-zero status.

Introduce a distinct exit status so a check that could not run never
resembles a clean pass: 0 no tabs, 1 tabs found, 2 check could not run.

Assisted-by: LLM [Claude Code] [Copilot]
In PackPanelsToSegments, the ground-mirror block reflected segment
points and negated circulation but never assigned SegEpsilon for the
mirrored half. The image segments therefore kept the -999999 sentinel
core size from allocation, which silently disabled or corrupted their
Biot-Savart contribution (segment/particle kernels collapse to ~0 for a
negative core, and the treecode MAC floor degenerates), so ground effect
under ShearModel=1 was under-delivered rather than crashing.

Copy the regularization core from each real segment to its image
(SegEpsilon(iMirror) = SegEpsilon(i)), which is physically exact since an
image vortex shares the core size of its source.

Co-authored-by: GitHub Copilot <[email protected]>
Co-authored-by: Claude <[email protected]>
Fix missing regularization core on mirrored FVW segments (ShearModel=1)
Two further issues raised in review:

- Excluding files by the "*_Types.f90" name pattern was wrong in both
  directions. It skipped six hand-maintained sources that happen to use
  that name, among them TurbSim_Types.f90 and ModMesh_Types.f90, so
  tabs in them could never be caught; and it still scanned
  NWTC_Library_IncSubs.f90, which is Registry-generated but does not
  match the pattern. Drop the exclusion and scan every tracked *.f90 /
  *.F90 file. When a tab is found in a file carrying the Registry
  marker, the report now says so and points at the registry .txt input,
  since that is where such a tab has to be fixed.

- The reported column could be wrong. "awk -v" decodes backslash
  escapes in the assigned value, so any line containing a backslash --
  Doxygen markup such as \f$ or \end{}, or a format string -- shifted
  the computed index. Compute the column with parameter expansion
  instead, which does no decoding. Line numbers were never affected.

Coverage goes from 267 to 329 scanned files.

Assisted-by: LLM [Claude Code] [Copilot]
The workflow header still claimed that Registry-generated *_Types.f90
files are excluded by the check script. That has not been true since
718f1df, which dropped the exclusion because the name pattern also
skipped six hand-maintained sources. Comment only; no change to the
workflow's behavior.

Assisted-by: LLM [Claude Code] [Copilot]
OLAF: Redundant wake reconstruction for multiple VTK grid outputs
Fix InflowWind Grid3DField fatal error for round-off just below t = 0
@andrew-platt
andrew-platt requested a lite review from Copilot September 24, 2026 19:34
@andrew-platt andrew-platt self-assigned this Sep 24, 2026
@andrew-platt andrew-platt added the Code-dev: cross-merges and maintenance Cross-merges between development branches. This is mostly code development maintenance. label Sep 24, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

A critical missing T_Tree import prevents compilation, and heterogeneous regularization behavior lacks regression coverage.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 High severity

Open (1)
What changed in this PR

Maintenance cross-merge of rc-5.0.1 into dev, covering OLAF, AeroDyn, InflowWind, build, CI, and formatting updates.

Changes:

  • Improves OLAF regularization, tree reuse, mirroring, and path handling.
  • Updates AeroDyn and InflowWind behavior.
  • Adds tab-check CI and MinGW stack configuration.
File Description
modules/​servodyn/​src/​StrucCtrl_Types.f90 Removes generated-source tabs.
modules/​servodyn/​src/​StrucCtrl_Registry.txt Cleans registry formatting.
modules/​nwtc-library/​src/​NWTC_Num.f90 Removes documentation tabs.
modules/​nwtc-library/​Old_test/​Test_MeshMapping/​Test_MeshMapping_Mod.f90 Cleans whitespace.
modules/​moordyn/​src/​MoorDyn_Line.f90 Removes comment tabs.
modules/​lindyn/​src/​LinDyn.f90 Removes comment tabs.
modules/​inflowwind/​src/​IfW_FlowField.f90 Adjusts periodic time-bound handling.
modules/​aerodyn/​src/​FVW.f90 Reuses wake trees and updates timing tolerance.
modules/​aerodyn/​src/​FVW_VortexTools.f90 Adds per-node regularization limits and related testing.
modules/​aerodyn/​src/​FVW_Subs.f90 Updates mirrored segments and velocity dispatch.
modules/​aerodyn/​src/​FVW_IO.f90 Fixes relative source-panel path parsing.
modules/​aerodyn/​src/​FVW_BiotSavart.f90 Optimizes particle regularization.
modules/​aerodyn/​src/​AeroDyn.f90 Updates OpenMP handling and linearization rotations.
cmake/​OpenfastFortranOptions.cmake Increases the MinGW stack size.
.github/​workflows/​check-tabs.yml Adds the tab-check workflow.
.github/​scripts/​check_tabs.sh Implements tab scanning and annotations.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread modules/aerodyn/src/FVW.f90
WriteVTKOutputs declares type(T_Tree), which currently resolves only
indirectly through the bare `use FVW_Subs`, which in turn does a bare
`use FVW_VortexTools`. That works today, but breaks at a distance if
FVW_Subs ever gains a private default or narrows its own use clause.

Add T_Tree to the existing only-list so the dependency is explicit.
No functional change.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
@andrew-platt
andrew-platt merged commit 222645e into dev Sep 24, 2026
32 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Code-dev: cross-merges and maintenance Cross-merges between development branches. This is mostly code development maintenance.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants