Skip to content

Release v4.6.0 - #41

Merged
gdifiore merged 26 commits into
mainfrom
development
May 31, 2026
Merged

gdifiore merged 26 commits into
mainfrom
development

Conversation

@gdifiore

Copy link
Copy Markdown
Owner

Pluggable

  • Integrator interface for the flight phases.
  • Configurable BallProperties — no longer pinned to STD_BALL_*.
  • Gravity wired through integration (was inert).

Packaging

  • Installable CMake package, golf::golf alias, PUBLIC includes. find_package works; README snippet added.

Correctness / quality

  • Continuous default Cd at the low-Re threshold.
  • Reference-ball constants moved to physics_constants (drops the context → default-model dependency).
  • AerialPhase de-nested from BouncePhase.
  • MIN_VELOCITY_THRESHOLD split into MIN_SPEED / MIN_SPIN / MIN_LENGTH.
  • AtmosphericData defaults to a sea-level standard day.

Build

  • Flight accel field built once per phase, not per step.
  • Dropped redundant CMAKE_CXX_FLAGS_RELEASE override.

gdifiore added 24 commits May 30, 2026 11:27
…tants

ShotPhysicsContext derived c0 by reaching into DefaultAerodynamicModel for DRAG_FORCE_CONST, REF_BALL_MASS_OZ, and REF_BALL_CIRC_IN — a model-agnostic layer depending on one concrete model. Those constants describe the reference ball the empirical drag fit was taken against; they are a derivation input, not a model tunable, so they belong in physics_constants.

ShotPhysicsContext no longer includes DefaultAerodynamicModel. The model retains the names as aliases to the shared constants for inspection by derived models.
Introduce a BallProperties struct (mass, circumference, derived radius) whose defaults reproduce a standard golf ball. Thread it through the FlightSimulator constructors into ShotPhysicsContext — where mass and circumference now drive c0, the surface spin speed, and the Reynolds reference — and into the three phases, which hand its radius to the aero, bounce, and roll model states in place of the hardcoded standard-ball constant.

All new parameters default to a standard ball, so existing call sites are unchanged. Documents the seam in how.md and moves ball properties out of the 'what isn't pluggable' list.
The low-Re branch returned bare CD_LOW while the adjacent linear branch evaluated to CD_LOW + CD_SPIN*S at the boundary, so the spin-drag term appeared as a step at Re=0.5e5. Carry CD_SPIN*S through the low-Re branch: Cd is now continuous across the threshold and the spin contribution to drag is present at low Re as it is everywhere else.
MIN_VELOCITY_THRESHOLD served as a speed floor, a spin-magnitude floor, and a vector-length floor at once — three dimensionally distinct concepts sharing one constant. Split into MIN_SPEED (ft/s), MIN_SPIN (rad/s), and MIN_LENGTH (ft) and route each call site to the matching floor. Values are identical today, so behaviour is unchanged; the floors can now be retuned independently.
AtmosphericData had no field defaults, so the common standard-day case still forced callers to fill all seven fields. Give each field a default (59°F, sea level, no wind, dry air, 29.92 inHg) so AtmosphericData{} is a usable baseline and designated initializers need only override what differs — matching GroundSurface's existing ergonomics.
BallState::fromLaunchParameters accepted a gravity value but AerialPhase::calculateAccel overwrote acceleration each step with the hardcoded earth constant, and FlightSimulator always passed earth — so the knob did nothing past step 1 and was unreachable through the main API.

Add a gravity parameter (default earth) to the FlightSimulator constructors, thread it into AerialPhase and BouncePhase for the per-step aerial acceleration, and route the same value into fromLaunchParameters. The default keeps every existing call unchanged. Documents the seam and the roll-model caveat in how.md.
The library used directory-scoped include_directories() and installed only the archive, so downstream projects could not resolve headers and find_package(golf) was unsupported. Switch to target_include_directories(golf PUBLIC ...) with BUILD/INSTALL interface paths, add a golf::golf alias, and install an exported golfTargets plus a generated golfConfig/golfConfigVersion. Consumers can now find_package(golf) and link golf::golf, or add_subdirectory and link the same target. README documents the find_package path.
…in BouncePhase

BouncePhase embedded an AerialPhase that was never initialize()d and carried cached scalars meaningless in the bounce context; it worked only because calculateAccelerations recomputed everything and only state.acceleration escaped. Extract the wind snapshot and the aero-plus-gravity computation into stateless helpers shared by both phases, give BouncePhase its own model/atmosphere/gravity members, and drop the nested phase. Removes the duplicate calculateAccel/calculateAccelerations naming. Behaviour is unchanged.
The aerial and between-bounce integration was hardwired into the phases, leaving the integration scheme the one flight stage a user could not replace. Add an Integrator interface that advances position and velocity given an acceleration field it can sample at trial states, plus a DefaultIntegrator implementing the existing semi-implicit Euler scheme. AerialPhase and BouncePhase now delegate stepping to it, and FlightSimulator exposes it as a trailing constructor parameter.

AerodynamicModel and AerodynamicState are unchanged, so this is additive. The default reproduces existing trajectories exactly. Documents the seam in how.md and corrects the AerodynamicModel note that said the integrator could not be swapped.
The acceleration field handed to the Integrator was rebuilt as a fresh std::function every step. Its captures exceed the std::function small-buffer size, so each flight step heap-allocated. Build it once per phase and read the per-step spin through a shared cell the phase mutates in place.
gdifiore added 2 commits May 30, 2026 14:17
  - Set INSTALL_GTEST OFF so a test-configured build's `cmake --install` ships only libgolf + its package config, not gtest/gmock.
  - Document why Release builds must not add -ffast-math: it folds NaN comparisons and breaks the convergence guards.
@gdifiore
gdifiore merged commit 3a83a59 into main May 31, 2026
9 checks passed
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