Skip to content

Commit 74a185c

Browse files
[MID] Add superconducting magnet/cryostat geometry to simulation
1 parent c0fe351 commit 74a185c

3 files changed

Lines changed: 149 additions & 1 deletion

File tree

Detectors/MUON/MID/Simulation/src/Geometry.cxx

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <TGeoManager.h>
2727
#include <TGeoShape.h>
2828
#include <TGeoCompositeShape.h>
29+
#include <TGeoTube.h>
2930

3031
namespace o2
3132
{
@@ -344,10 +345,125 @@ TGeoVolume* createChamber(int iChamber)
344345
return chamber;
345346
}
346347

348+
349+
/// Magnet geometry variant selector
350+
enum class MagnetVariant {
351+
AluminiumWalls, ///< 11 cm cryostat, Al inner/outer walls
352+
SteelWalls ///< 10 cm cryostat, Fe inner/outer walls
353+
};
354+
355+
/// Creates the MID magnet/cryostat geometry
356+
/// Port of GEANT4 simulation by Ian Perez Garcia (ICN-UNAM)
357+
/// Reference: github.com/IanPG/MID-Geometry-Studies
358+
void createMagnetGeometry(TGeoVolume& topVolume,
359+
MagnetVariant variant = MagnetVariant::AluminiumWalls)
360+
{
361+
const float R_cryostat_inner = 140.0f;
362+
const float R_cryostat_outer = 200.0f;
363+
const float R_coil_inner = 160.0f;
364+
const float magnetHalfLength = 400.0f;
365+
366+
const float thick_actual_coil = 4.8f;
367+
const float thick_mli = 0.2f;
368+
const float thick_coil_support = 2.0f;
369+
370+
float thick_inner_wall;
371+
float thick_outer_wall;
372+
int wallMedium;
373+
const char* variantTag;
374+
375+
if (variant == MagnetVariant::AluminiumWalls) {
376+
thick_inner_wall = 2.5f;
377+
thick_outer_wall = 1.5f;
378+
wallMedium = Medium::Aluminium;
379+
variantTag = "Al";
380+
} else {
381+
thick_inner_wall = 1.5f;
382+
thick_outer_wall = 1.5f;
383+
wallMedium = Medium::Iron;
384+
variantTag = "Steel";
385+
}
386+
387+
const float R_inner_wall_outer = R_cryostat_inner + thick_inner_wall;
388+
const float R_coil_outer = R_coil_inner + thick_actual_coil;
389+
const float R_mli_inner = R_coil_outer;
390+
const float R_mli_outer = R_mli_inner + thick_mli;
391+
const float R_coil_support_inner = R_mli_outer;
392+
const float R_coil_support_outer = R_coil_support_inner + thick_coil_support;
393+
const float R_outer_wall_inner = R_cryostat_outer - thick_outer_wall;
394+
395+
// Mother volume (contains all cryostat layers)
396+
auto magnetMotherShape = new TGeoTube(Form("MIDMagnetMother_%s_S", variantTag),
397+
R_cryostat_inner, R_cryostat_outer, magnetHalfLength);
398+
auto magnetMotherVol = new TGeoVolume(Form("MIDMagnetMother_%s", variantTag),
399+
magnetMotherShape, assertMedium(Medium::Vacuum));
400+
magnetMotherVol->SetVisibility(kFALSE);
401+
topVolume.AddNode(magnetMotherVol, 1, new TGeoTranslation(0., 0., -1155.));
402+
403+
// Layer 1: Inner wall (Al or Fe)
404+
auto innerWallVol = new TGeoVolume(Form("MIDInnerWall_%s", variantTag),
405+
new TGeoTube(Form("MIDInnerWall_%s_S", variantTag),
406+
R_cryostat_inner, R_inner_wall_outer, magnetHalfLength),
407+
assertMedium(wallMedium));
408+
innerWallVol->SetLineColor((variant == MagnetVariant::AluminiumWalls) ? kCyan+1 : kRed+1);
409+
magnetMotherVol->AddNode(innerWallVol, 1, nullptr);
410+
411+
// Layer 2: Inner vacuum gap
412+
auto vacGap1Vol = new TGeoVolume(Form("MIDVacGap1_%s", variantTag),
413+
new TGeoTube(Form("MIDVacGap1_%s_S", variantTag),
414+
R_inner_wall_outer, R_coil_inner, magnetHalfLength),
415+
assertMedium(Medium::Vacuum));
416+
magnetMotherVol->AddNode(vacGap1Vol, 1, nullptr);
417+
418+
// Layer 3: Winding Pack (NbTi+Cu+Al, density=2.96 g/cm3)
419+
auto coilVol = new TGeoVolume(Form("MIDCoil_%s", variantTag),
420+
new TGeoTube(Form("MIDCoil_%s_S", variantTag),
421+
R_coil_inner, R_coil_outer, magnetHalfLength),
422+
assertMedium(Medium::WindingPack));
423+
coilVol->SetLineColor(kRed);
424+
magnetMotherVol->AddNode(coilVol, 1, nullptr);
425+
426+
// Layer 4: MLI - Multi-Layer Insulation (2mm Al)
427+
auto mliVol = new TGeoVolume(Form("MIDMLI_%s", variantTag),
428+
new TGeoTube(Form("MIDMLI_%s_S", variantTag),
429+
R_mli_inner, R_mli_outer, magnetHalfLength),
430+
assertMedium(Medium::Aluminium));
431+
mliVol->SetLineColor(kYellow);
432+
magnetMotherVol->AddNode(mliVol, 1, nullptr);
433+
434+
// Layer 5: A-5083 Support cylinder (20mm Al)
435+
auto supportVol = new TGeoVolume(Form("MIDCoilSupport_%s", variantTag),
436+
new TGeoTube(Form("MIDCoilSupport_%s_S", variantTag),
437+
R_coil_support_inner, R_coil_support_outer, magnetHalfLength),
438+
assertMedium(Medium::Aluminium));
439+
supportVol->SetLineColor(kBlue-7);
440+
magnetMotherVol->AddNode(supportVol, 1, nullptr);
441+
442+
// Layer 6: Outer vacuum gap
443+
auto vacGap2Vol = new TGeoVolume(Form("MIDVacGap2_%s", variantTag),
444+
new TGeoTube(Form("MIDVacGap2_%s_S", variantTag),
445+
R_coil_support_outer, R_outer_wall_inner, magnetHalfLength),
446+
assertMedium(Medium::Vacuum));
447+
magnetMotherVol->AddNode(vacGap2Vol, 1, nullptr);
448+
449+
// Layer 7: Outer wall (Al or Fe)
450+
auto outerWallVol = new TGeoVolume(Form("MIDOuterWall_%s", variantTag),
451+
new TGeoTube(Form("MIDOuterWall_%s_S", variantTag),
452+
R_outer_wall_inner, R_cryostat_outer, magnetHalfLength),
453+
assertMedium(wallMedium));
454+
outerWallVol->SetLineColor((variant == MagnetVariant::AluminiumWalls) ? kCyan+1 : kRed+1);
455+
magnetMotherVol->AddNode(outerWallVol, 1, nullptr);
456+
}
457+
347458
void createGeometry(TGeoVolume& topVolume)
348459
{
349460
createMaterials();
350461

462+
// Add magnet/cryostat geometry (Francisco Esquivel, June 2026)
463+
printf("[MID] Calling createMagnetGeometry...\n");
464+
createMagnetGeometry(topVolume, MagnetVariant::AluminiumWalls);
465+
printf("[MID] createMagnetGeometry done. Top volume nodes: %d\n", topVolume.GetNdaughters());
466+
351467
// create and place the trigger chambers
352468
for (int iCh = 0; iCh < detparams::NChambers; iCh++) {
353469

Detectors/MUON/MID/Simulation/src/Materials.cxx

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,35 @@ void createMaterials()
169169
mgr.Mixture(kModuleName, ++imat, "Nomex", aNomex, zNomex, dNomex, -nNomex, wNomex);
170170
mgr.Medium(kModuleName, Medium::Nomex, "Nomex", imat, 0, fieldType, maxField, kMaxfd, kStemax,
171171
kDeemax, kEpsil, kStmin);
172+
/// Iron (pure Fe) - absorber and steel cryostat walls
173+
/// G4 equivalent: G4_Fe, density = 7.874 g/cm3
174+
const float kZIron_pure = 26.;
175+
const float kAIron_pure = 55.845;
176+
const float kDensIron = 7.874;
177+
mgr.Material(kModuleName, ++imat, "Iron", kAIron_pure, kZIron_pure, kDensIron, 0., 0.);
178+
mgr.Medium(kModuleName, Medium::Iron, "Iron", imat, 0, fieldType, maxField,
179+
kMaxfd, kStemax, kDeemax, kEpsil, kStmin);
180+
181+
/// WindingPack - superconducting coil (NbTi + Cu + Al)
182+
/// Mass fractions: NbTi=8.10%, Cu=11.18%, Al=80.72%, density=2.96 g/cm3
183+
const float kZNiobium = 41.;
184+
const float kANiobium = 92.90638;
185+
const float kZTitanium = 22.;
186+
const float kATitanium = 47.867;
187+
const int nWP = 4;
188+
float aWP[nWP] = {kANiobium, kATitanium, kACopper, kAAluminium};
189+
float zWP[nWP] = {kZNiobium, kZTitanium, kZCopper, kZAluminium};
190+
float wWP[nWP] = {0.0405, 0.0405, 0.1118, 0.8072};
191+
float dWP = 2.96;
192+
mgr.Mixture(kModuleName, ++imat, "WindingPack", aWP, zWP, dWP, nWP, wWP);
193+
mgr.Medium(kModuleName, Medium::WindingPack, "WindingPack", imat, 0, fieldType, maxField,
194+
kMaxfd, kStemax, kDeemax, kEpsil, kStmin);
195+
196+
/// Vacuum - thermal insulation gaps inside cryostat
197+
mgr.Material(kModuleName, ++imat, "Vacuum", 1e-16, 1e-16, 1e-16, 0., 0.);
198+
mgr.Medium(kModuleName, Medium::Vacuum, "Vacuum", imat, 0, fieldType, maxField,
199+
kMaxfd, kStemax, kDeemax, kEpsil, kStmin);
200+
172201
}
173202

174203
TGeoMedium* assertMedium(int imed)

Detectors/MUON/MID/Simulation/src/Materials.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,10 @@ enum Medium {
3333
Copper,
3434
Mylar,
3535
Styrofoam,
36-
Nomex
36+
Nomex,
37+
Iron,
38+
WindingPack,
39+
Vacuum
3740
};
3841

3942
// Return a pointer to the mid medium number imed.

0 commit comments

Comments
 (0)