From 04fa78b66110b306f7f513d0cefe8e350de9551e Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Fri, 4 Sep 2026 14:08:14 +0200 Subject: [PATCH] Place the L3 coil turns explicitly instead of dividing the polyhedra This fixes a problem in navigation with multithreaded native Geant4 and leaves the material unchanged. - The 168 coil turns were made with TGeoPgon::Divide. Geant4's G4ParameterisationPolyhedraZ rebuilds the shared master solid while navigating and allocates the new sides' thread-split data on worker threads, so a multithreaded run segfaults in the G4PolyhedraSide constructor. - L3CM is the only divided polyhedra in ALICE. The other 24 divisions are box divisions in HMPID, ZDC and FIT and are not affected. https://its.cern.ch/jira/browse/O2-7153 Co-Authored-By: Claude Opus 5 (1M context) --- Detectors/Passive/src/Magnet.cxx | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/Detectors/Passive/src/Magnet.cxx b/Detectors/Passive/src/Magnet.cxx index 0c2c6efed8d48..b39adfeeb866f 100644 --- a/Detectors/Passive/src/Magnet.cxx +++ b/Detectors/Passive/src/Magnet.cxx @@ -225,8 +225,19 @@ void Magnet::ConstructGeometry() // Coils TGeoVolume* voCoilMother = new TGeoVolume("L3CM", shCoilMother, medAir); voBMother->AddNode(voCoilMother, 1, new TGeoTranslation(0., 0., 0.)); - // Divide into the 168 turns - TGeoVolume* voCoilTurn = voCoilMother->Divide("L3CD", 3, 168, 0., 0.); + // The 168 turns, placed explicitly rather than as a TGeoPgon division. + // Geant4's G4ParameterisationPolyhedraZ rebuilds the shared master solid while + // navigating, so a divided polyhedra crashes a multithreaded native-Geant4 run. + const Int_t kNCoilTurns = 168; + const Float_t kDzCoilTurn = kLCoil / kNCoilTurns; + TGeoPgon* shCoilTurn = new TGeoPgon(kStartAngle, kFullAngle, kNSides, 2); + shCoilTurn->DefineSection(0, -kDzCoilTurn, kRCoilInner - 2. * kRCoolingOuter, kRCoilOuter + 2. * kRCoolingOuter); + shCoilTurn->DefineSection(1, kDzCoilTurn, kRCoilInner - 2. * kRCoolingOuter, kRCoilOuter + 2. * kRCoolingOuter); + TGeoVolume* voCoilTurn = new TGeoVolume("L3CD", shCoilTurn, medAir); + for (Int_t iTurn = 0; iTurn < kNCoilTurns; ++iTurn) { + voCoilMother->AddNode(voCoilTurn, iTurn + 1, + new TGeoTranslation(0., 0., -kLCoil + (2 * iTurn + 1) * kDzCoilTurn)); + } TGeoPgon* shCoils = new TGeoPgon(kStartAngle, kFullAngle, kNSides, 2); shCoils->DefineSection(0, -3., kRCoilInner, kRCoilOuter); shCoils->DefineSection(1, 3., kRCoilInner, kRCoilOuter);