Add a compact-support core regularization function for OLAF particle methods - #3457
Add a compact-support core regularization function for OLAF particle methods#3457luwang00 wants to merge 11 commits into
Conversation
…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>
…nput and update r-test pointer
…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
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>
There was a problem hiding this comment.
🟡 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
RegFunctionPartinput 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.
| **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`. |
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>
This PR is not ready to be merged until the following prerequisites are met:
rc-5.0.1rc-5.0.1intodev.devinto the PR branch and resolver-testconflicts.api_change.rstfor 5.1.0 release.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-olafdoc changes for details on the compact-support regularization function.This PR also adds a new input
RegFunctionParton 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 byRegFunctionon the line above. Currently, the choices forRegFunctionPartare0for no regularization,1for exponential core function (also thedefaultoption), and2for the new compact-support core.The compact-support core regularization appears to have very limited impact on the rotor loads. The
ad_BAR_OLAFtest modified to useRegFunctionPart=2passed without issue with the existing reference solution generated withRegFunctionPart=1.Wake with exponential core

RegFunctionPart=1:Wake with compact core

RegFunctionPart=2:Comparison of time-averaged normalized streamwise wake velocity:

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.