feat(target): implement 2026 BDF target design - #76
Conversation
Replace the legacy target (19 Ta-clad disks in an Inconel vessel with steel enclosure) with the 2026 BDF design extracted from CATIA model ST1A07710_01_AB.02, simplified to axisymmetric shapes: - 33 solid tungsten disks (30..455 mm thick, r 125 mm; 455 mm rear block with r 157 mm), separated by 4-5 mm He slits, 1460 mm total - steel core as a single polycone (bore r 125 -> 157, outer r 195 -> 207 -> 190) with the serpentine He cooling grooves subtracted as tube segments (61 deg arcs staggered top/bottom, plus a 49 deg groove around the rear block) - steel jacket tube (r 217-225) with front and rear flanges and a He annulus between core and jacket - domed rear endcap (8 mm shell) as a single polycone The He container spans z -35.8..1509.7 mm with r 237 mm; all target z coordinates are measured from the front face of the first disk (the SHiP global origin), unchanged from the previous implementation. Matches the FairShip TGeo implementation of the same design (ShipSoft/FairShip#1361).
📝 WalkthroughWalkthroughThe Target subsystem was migrated from the previous 19-slab design to the 2026 BDF target: 33 tungsten disks in a grooved Steel316L core with helium volume, jacket, flanges, and endcap. Documentation, geometry construction, constants, and tests were updated accordingly. Changes2026 BDF Target Geometry
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant TargetFactory
participant HeVolume
participant SteelCoreShape
participant TargetComponents
TargetFactory->>HeVolume: create and place helium volume
HeVolume->>TargetComponents: place 33 tungsten disks
HeVolume->>SteelCoreShape: create grooved steel core
SteelCoreShape->>TargetComponents: subtract cooling grooves
HeVolume->>TargetComponents: add jacket, flanges, and endcap
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (3)
subsystems/Target/src/TargetFactory.cpp (1)
68-79: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueHoist
heCentreZinto a header constant.The same derived value is recomputed at line 179 in
createHeVolume(). Astatic constexpr double s_heCentreZ = 0.5 * (s_heZMin + s_heZMax);next to the He bounds keeps the two placements provably consistent.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@subsystems/Target/src/TargetFactory.cpp` around lines 68 - 79, Define a static constexpr s_heCentreZ beside the existing helium bounds constants, then replace the local heCentreZ calculation in the placement code and the duplicate computation inside createHeVolume() with this shared constant. Preserve both existing placement calculations while ensuring they use the same derived center value.subsystems/Target/include/Target/TargetFactory.h (1)
117-132: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winTie the array extent to
s_numDisks.
createHeVolume()loops tos_numDisksand indexess_diskZ[i], so a future edit to one and not the other becomes a silent out-of-bounds read instead of a compile error. Values themselves check out (33 entries, 1330 mm W, 0–1460 mm span).♻️ Proposed change
- static constexpr std::array<std::array<double, 2>, 33> s_diskZ = {{ + static constexpr std::array<std::array<double, 2>, static_cast<std::size_t>(s_numDisks)> + s_diskZ = {{Or keep the literal and add
static_assert(s_diskZ.size() == static_cast<std::size_t>(s_numDisks));.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@subsystems/Target/include/Target/TargetFactory.h` around lines 117 - 132, Tie the s_diskZ array extent directly to s_numDisks so createHeVolume() cannot iterate beyond its declared storage after future edits. Replace the hard-coded extent in s_diskZ with the existing s_numDisks symbol, or add a static_assert comparing s_diskZ.size() with s_numDisks if the literal must remain.subsystems/Target/test_target.cpp (1)
58-59: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winConsider asserting the jacket/flange/endcap children too.
Children 34–37 are currently only covered by the count check. A few assertions on jacket
RMin/RMax(217/225), the flange z spans, and the endcap polycone plane count/last-plane z would lock down the He-annulus and rear-closure numbers introduced here.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@subsystems/Target/test_target.cpp` around lines 58 - 59, Extend the assertions near the existing heVolume child-count check to validate children 34–37 individually: assert the jacket RMin/RMax values of 217/225, verify both flange z spans, and check the endcap polycone plane count and final-plane z. Keep the existing child-count assertion and use the established child-volume access and geometry APIs.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@subsystems/Target/include/Target/TargetFactory.h`:
- Around line 117-132: Tie the s_diskZ array extent directly to s_numDisks so
createHeVolume() cannot iterate beyond its declared storage after future edits.
Replace the hard-coded extent in s_diskZ with the existing s_numDisks symbol, or
add a static_assert comparing s_diskZ.size() with s_numDisks if the literal must
remain.
In `@subsystems/Target/src/TargetFactory.cpp`:
- Around line 68-79: Define a static constexpr s_heCentreZ beside the existing
helium bounds constants, then replace the local heCentreZ calculation in the
placement code and the duplicate computation inside createHeVolume() with this
shared constant. Preserve both existing placement calculations while ensuring
they use the same derived center value.
In `@subsystems/Target/test_target.cpp`:
- Around line 58-59: Extend the assertions near the existing heVolume
child-count check to validate children 34–37 individually: assert the jacket
RMin/RMax values of 217/225, verify both flange z spans, and check the endcap
polycone plane count and final-plane z. Keep the existing child-count assertion
and use the established child-volume access and geometry APIs.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 64f31197-1673-47af-85c1-5ac6f93edb41
📒 Files selected for processing (5)
README.mdsubsystems/Target/README.mdsubsystems/Target/include/Target/TargetFactory.hsubsystems/Target/src/TargetFactory.cppsubsystems/Target/test_target.cpp
Summary
Implements the 2026 BDF/SHiP target design, extracted from CATIA model
ST1A07710_01_AB.02, replacing the legacy target (19 Ta-clad disks in an Inconel vessel with steel enclosure). This is the GeoModel counterpart of the FairShip TGeo implementation in ShipSoft/FairShip#1361; the two are numerically identical.GeoPcon(bore r 125 → 157 mm, outer r 195 → 207 → 190 mm) with the serpentine He cooling grooves subtracted asGeoTubssegments (61° arcs staggered between the upper and lower half, plus a 49° groove around the rear block); the removed volume fills with the parent heliumGeoPconThe GeoModel mapping is more compact than the TGeo one: the stepped core and the endcap are single polycones instead of boolean unions/cone stacks, leaving only the 10 groove subtractions as boolean nodes.
Design
Cross-sections of the implemented geometry (drawings from the FairShip PR; z = 0 at the first disk front face, dimensions in mm):
x–y section (z ≈ 420 mm)
z–x section (horizontal plane, no grooves)
z–y section (vertical plane, staggered cooling grooves)
Simplifications relative to the CAD model: bolt lugs, key-ways, pipe stubs, fasteners and survey hardware omitted; the endcap dome approximated by three cone segments; the flange/jacket boundary placed at the end of the core front step (55.2 mm instead of the CAD's stepped flange bore at 64.2 mm).
Verification
OverlapCheckand new target unit tests (disk table positions/radii, tungsten volume sum, He container dimensions, groove subtraction present)build_geometry+validate_geometrysucceed; polycone planes and groove tube segments verified in the SQLite output against the CAD extractionpixi run gdml) succeeds, confirming Geant4-compatible shapesSummary by CodeRabbit
New Features
Tests