Skip to content

Add a compact-support core regularization function for OLAF particle methods - #3457

Open
luwang00 wants to merge 11 commits into
OpenFAST:devfrom
luwang00:f/OLAF
Open

Add a compact-support core regularization function for OLAF particle methods#3457
luwang00 wants to merge 11 commits into
OpenFAST:devfrom
luwang00:f/OLAF

Conversation

@luwang00

@luwang00 luwang00 commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

This PR is not ready to be merged until the following prerequisites are met:

Feature or improvement description
This PR adds a compact-support C2 core regularization function to speed up OLAF runs after the fix to core-regularization floor in PR #3430. Based on a preliminary test, the computing time nearly halved with the new compact-support core function compared to the exponential core function with the example from @RBergua shown in PR #3430.

See aerodyn-olaf doc changes for details on the compact-support regularization function.

This PR also adds a new input RegFunctionPart on line 26 of the OLAF input file that allows the user to select a regularization function for the vortex particles separate from the regularization function for the segments controlled by RegFunction on the line above. Currently, the choices for RegFunctionPart are 0 for no regularization, 1 for exponential core function (also the default option), and 2 for the new compact-support core.

The compact-support core regularization appears to have very limited impact on the rotor loads. The ad_BAR_OLAF test modified to use RegFunctionPart=2 passed without issue with the existing reference solution generated with RegFunctionPart=1.

Wake with exponential core RegFunctionPart=1:
image

Wake with compact core RegFunctionPart=2:
image

Comparison of time-averaged normalized streamwise wake velocity:
image
The wake deficit is generally consistent between the two regularization functions with more difference observed further downstream at 8D.

Related issue, if one exists
The changes aim to partially negate the increased computing time after PR #3430.

Impacted areas of the software
OLAF, openfast_io, r-test

Generative AI usage
Co-authored-by: Microsoft Copilot copilot@microsoft.com
Co-authored-by: Anthropic Claude claude@anthropic.com

Test results, if applicable
No change to existing r-test results because all OLAF cases use the old exponential regularization. Should introduce a new test that uses the compact regularization. r-test merging is still required because of the new OLAF input.

  • r-test branch merging required

luwang00 and others added 9 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 <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Claude Opus <noreply@anthropic.com>
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 <198982749+Copilot@users.noreply.github.com>

Co-authored-by: Claude Opus <noreply@anthropic.com>
Item 1: true finite-support compact-C2 particle regularization kernel with
kernel-aware treecode near-core floor.
- FVW_BiotSavart.f90: PART_REG_C2=1.6 param; PartRegFloorFactor(RegFunction);
  rewrite idRegCompact case in ui_part_nograd_11 as (1-rho^2)^2 blob with the
  1.6 core-equivalence factor baked into the kernel (RegParam/seeding unchanged).
- FVW_VortexTools.f90: particle tree near-core floor uses PartRegFloorFactor;
  segment tree floor unchanged.

Item 2: make idRegCompact selectable via a new RegFunctionPart input so the
particle kernel can be A/B tested against the exponential kernel.
- FVW_Registry.txt / FVW_Types.f90: new RegFunctionPart field in Param and
  InputFile types (Types regenerated).
- FVW_IO.f90: read RegFunctionPart (default Exponential) plus validation.
- FVW.f90: copy RegFunctionPart into parameters.
- FVW_Subs.f90: route RegFunctionPart through SegmentsToPartWrap and the
  particle-velocity call sites, replacing the previously forced idRegExp.

Default RegFunctionPart=Exponential preserves existing behavior. Core spreading
is unchanged (it acts upstream on filament cores).

Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Claude Opus <noreply@anthropic.com>
…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 <198982749+Copilot@users.noreply.github.com>

Co-authored-by: Claude Opus <noreply@anthropic.com>
# Conflicts:
#	modules/aerodyn/src/FVW_Subs.f90
#	reg_tests/r-test
@luwang00
luwang00 marked this pull request as draft September 9, 2026 16:18
@luwang00 luwang00 added the ai assisted AI written with strong human guidance. label Sep 9, 2026
@luwang00 luwang00 added this to the v5.1.0 milestone Sep 9, 2026
Clarify the existing regularization functions apply to vortex segments, and add a Particle regularization functions section covering the segment-to-particle conversion, the regularized point-vortex kernel, and the exponential and compact-support functions (RegFunctionPart). Also document the RegFunctionPart input in the OLAF input file reference.

Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>

Co-authored-by: Claude Opus <noreply@anthropic.com>
@luwang00
luwang00 marked this pull request as ready for review September 10, 2026 00:29
@luwang00
luwang00 requested a lite review from Copilot September 10, 2026 00:29

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.

🟡 Changes recommended

The openfast_io OLAF reader/writer changes are not robust to older OLAF input variants (risk of silent mis-parse/KeyError), and the particle tree floor-factor helper can impose unnecessary direct-evaluation work for RegFunctionPart=0, plus the PR prerequisite api_change.rst entry is still missing.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR extends AeroDyn/OLAF to support a separate particle regularization function (RegFunctionPart) and introduces a new compact-support C2 particle core to improve OLAF performance for particle-based velocity methods (direct and tree-accelerated), with corresponding documentation updates.

Changes:

  • Add RegFunctionPart input plumbing across OLAF IO/types and openfast_io read/write paths.
  • Implement a compact-support particle regularization kernel and align the particle tree’s near-core direct-evaluation floor with kernel support.
  • Update OLAF user documentation and example input file to describe and demonstrate the new particle regularization options.
File summaries
File Description
openfast_io/openfast_io/FAST_writer.py Writes new RegFunctionPart line into OLAF input files and clarifies RegFunction as segment regularization.
openfast_io/openfast_io/FAST_reader.py Reads new RegFunctionPart from OLAF input files into fst_vt.
modules/aerodyn/src/FVW.f90 Propagates RegFunctionPart from input-file data into runtime parameters.
modules/aerodyn/src/FVW_VortexTools.f90 Tracks maxRegParam per tree node and uses kernel-aware distance floors for particle tree direct evaluation.
modules/aerodyn/src/FVW_Types.f90 Adds RegFunctionPart to parameter/input-file derived types and pack/unpack/copy routines.
modules/aerodyn/src/FVW_Subs.f90 Uses RegFunctionPart for particle conversion and refactors velocity-method logic to select case.
modules/aerodyn/src/FVW_Registry.txt Registers RegFunctionPart so it flows through the registry/type generation system.
modules/aerodyn/src/FVW_IO.f90 Reads/validates RegFunctionPart from OLAF input with a default.
modules/aerodyn/src/FVW_BiotSavart.f90 Adds compact-support particle kernel, exp fast-path cutoff, and PartRegFloorFactor helper.
modules/aerodyn/src/AeroDyn.f90 OpenMP scoping fix/comment for TwrInflArray loop variables.
docs/source/user/aerodyn-olaf/OLAFTheory.rst Documents particle regularization functions, including compact-support kernel details.
docs/source/user/aerodyn-olaf/InputFiles.rst Documents new RegFunctionPart input and behavior/performance implications.
docs/source/user/aerodyn-olaf/ExampleFiles/ExampleFile--OLAF.dat Adds RegFunctionPart to the OLAF example input file.
Review details
  • Files reviewed: 14/14 changed files
  • Comments generated: 4
  • Review effort level: Lite

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

Comment thread openfast_io/openfast_io/FAST_reader.py
Comment thread openfast_io/openfast_io/FAST_writer.py
Comment on lines +188 to +193
**RegFunctionPart** [switch] specifies the regularization function used for the
vortex particles, which are used when a particle-based velocity method is
selected (*VelocityMethod* = *[2,3]*). There are three options: 1) no
correction *[0]*, 2) the exponential method *[1]*, and 3) the compact-support
method *[2]*. The functions are given in
:numref:`sec:RegularizationFunctionPart`.
Comment thread modules/aerodyn/src/FVW_BiotSavart.f90
PartRegFloorFactor now returns 0 for idRegNone since the singular point-vortex kernel has no core region; accuracy is governed solely by the Barnes-Hut opening criterion. Avoids inflating the direct-evaluation region unnecessarily.

Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>

Co-authored-by: Claude Opus <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai assisted AI written with strong human guidance. Module: OLAF Type: Enhancement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants