Skip to content

Phase 2 faithfulness: CrespoHernandez c, None rotor for WeightedSum, Zong eps_coeff#4

Merged
bjarketol merged 1 commit into
flow-model-chainfrom
pywake-faithful-phase2
Jun 8, 2026
Merged

Phase 2 faithfulness: CrespoHernandez c, None rotor for WeightedSum, Zong eps_coeff#4
bjarketol merged 1 commit into
flow-model-chainfrom
pywake-faithful-phase2

Conversation

@bjarketol

Copy link
Copy Markdown
Owner

Phase 2 — closes the last two structural faithfulness gaps (Niayifar 2016, Zong 2020) vs py_wake.literature.

Fix C — CrespoHernandez calibration coefficients

_configure_turbulence_model honors a c array (new windIO turbulence_model.c field). When given, it builds CrespoHernandez(c=..., ct2a=ct2a_mom1d, addedTurbulenceSuperpositionModel=SqrMaxSum()) — the literature recipe. Without c, the PyWake default is unchanged. (PyWake's default c[2] even has the opposite sign to the papers' calibration.)

Fix D — none rotor averaging for WeightedSum

  • _configure_rotor_averaging adds "none"None.
  • The WeightedSum guard now accepts None (rotor centre, which PyWake allows) in addition to node models. Zong (2020) uses rotorAvgModel=None; WIFA forcing GridRotorAvg was a ~24% error. An explicit center is still rejected (PyWake asserts).

Zong eps_coeff

ceps now maps to Zong's eps_coeff (PyWake's name for its near-wake epsilon, default 0.3535 vs the paper's 0.35), instead of being dropped.

Verification

Behavioral check against py_wake.literature: Niayifar2016 and Zong2020 now match to 0.000% per-turbine power. tests/test_pywake_submodels.py + tests/test_pywake.py: 217 passed (+6 new). Depends on bjarketol/windIO flow-model-chain (the c / none schema fields, already merged).

🤖 Generated with Claude Code

…edSum, Zong eps_coeff

Closes the Niayifar (2016) and Zong (2020) gaps vs py_wake.literature:

- Fix C: CrespoHernandez honors a `c` coefficient array from the turbulence
  config; when given it builds CrespoHernandez(c=..., ct2a=ct2a_mom1d,
  addedTurbulenceSuperpositionModel=SqrMaxSum()) — the literature recipe.
  Without `c`, the PyWake default is unchanged.
- Fix D: a "none" rotor-averaging option returns None, and the WeightedSum
  guard now accepts None (rotor centre, which PyWake allows) in addition to
  node models. Zong (2020) uses rotorAvgModel=None; forcing GridRotorAvg was a
  ~24% error.
- ceps now maps to Zong's `eps_coeff` (PyWake's name for its near-wake epsilon),
  instead of being dropped.

Verified against py_wake.literature: Niayifar2016 and Zong2020 now match to
0.000% per-turbine power. Adds unit tests for all three.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@bjarketol bjarketol merged commit b26ea07 into flow-model-chain Jun 8, 2026
3 of 4 checks passed
@bjarketol bjarketol deleted the pywake-faithful-phase2 branch June 8, 2026 19:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant