// // ******************************************************************** // * License and Disclaimer * // * * // * The Geant4 software is copyright of the Copyright Holders of * // * the Geant4 Collaboration. It is provided under the terms and * // * conditions of the Geant4 Software License, included in the file * // * LICENSE and available at http://cern.ch/geant4/license . These * // * include a list of copyright holders. * // * * // * Neither the authors of this software system, nor their employing * // * institutes,nor the agencies providing financial support for this * // * work make any representation or warranty, express or implied, * // * regarding this software system or assume any liability for its * // * use. Please see the license in the file LICENSE and URL above * // * for the full disclaimer and the limitation of liability. * // * * // * This code implementation is the result of the scientific and * // * technical work of the GEANT4 collaboration. * // * By using, copying, modifying or distributing the software (or * // * any work based on the software) you agree to acknowledge its * // * use in resulting scientific publications, and indicate your * // * acceptance of all terms of the Geant4 Software license. * // ******************************************************************** // /// \file GarfieldDetectorConstruction.cc /// \brief Implementation of the GarfieldDetectorConstruction class #include "GarfieldDetectorConstruction.hh" #include "G4AutoDelete.hh" #include "G4Box.hh" #include "G4Colour.hh" #include "G4GeometryManager.hh" #include "G4GlobalMagFieldMessenger.hh" #include "G4LogicalVolume.hh" #include "G4LogicalVolumeStore.hh" #include "G4Material.hh" #include "G4NistManager.hh" #include "G4PVPlacement.hh" #include "G4PVReplica.hh" #include "G4PhysicalConstants.hh" #include "G4PhysicalVolumeStore.hh" #include "G4RunManager.hh" #include "G4SolidStore.hh" #include "G4SystemOfUnits.hh" #include "G4Tubs.hh" #include "G4VisAttributes.hh" #include "GarfieldG4FastSimulationModel.hh" #include "GarfieldMessenger.hh" //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... GarfieldDetectorConstruction::GarfieldDetectorConstruction() : G4VUserDetectorConstruction() { fGarfieldMessenger = new GarfieldMessenger(this); } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... GarfieldDetectorConstruction::~GarfieldDetectorConstruction() { delete fGarfieldMessenger; } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... G4VPhysicalVolume* GarfieldDetectorConstruction::Construct() { // Define materials DefineMaterials(); // Define volumes return DefineVolumes(); } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... void GarfieldDetectorConstruction::DefineMaterials() { G4bool isotopes = false; G4NistManager* nistManager = G4NistManager::Instance(); // Load commonly used materials nistManager->FindOrBuildMaterial("G4_AIR"); // Ensure G4_AIR is available nistManager->FindOrBuildMaterial("G4_STAINLESS-STEEL"); // PRC outer shell material nistManager->FindOrBuildMaterial("G4_W"); // Tungsten wire material // Create P10 gas (90% Argon, 10% Methane) G4Element* Ar = nistManager->FindOrBuildElement("Ar", isotopes); G4Element* C = nistManager->FindOrBuildElement("C", isotopes); G4Element* H = nistManager->FindOrBuildElement("H", isotopes); G4Material* CH4 = new G4Material("CH4", 0.667 * CLHEP::mg / CLHEP::cm3, 2); CH4->AddElement(C, 1); CH4->AddElement(H, 4); G4Material* P10 = new G4Material("P10", 1.5 * CLHEP::mg / CLHEP::cm3, 2); P10->AddElement(Ar, 90 * perCent); P10->AddMaterial(CH4, 10 * perCent); // Log materials table for verification G4cout << *(G4Material::GetMaterialTable()) << G4endl; } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... G4VPhysicalVolume* GarfieldDetectorConstruction::DefineVolumes() { // Geometry parameters G4double worldSize = 10 * m; G4double prcLength = 6 * m; G4double prcWidth = 0.1 * m; G4double prcHeight = 0.1 * m; G4double wallThickness = 0.23 * cm; G4double wireRadius = 0.05 * mm; // Get materials G4Material* defaultMaterial = G4Material::GetMaterial("G4_AIR"); G4Material* cathodeMaterial = G4Material::GetMaterial("G4_STAINLESS-STEEL"); G4Material* wireMaterial = G4Material::GetMaterial("G4_W"); G4Material* gasMaterial = G4Material::GetMaterial("P10"); if (!defaultMaterial || !cathodeMaterial || !wireMaterial || !gasMaterial) { G4ExceptionDescription msg; msg << "Cannot retrieve materials already defined."; G4Exception("GarfieldDetectorConstruction::DefineVolumes()", "MyCode0001", FatalException, msg); } // World G4VSolid* worldS = new G4Box("World", worldSize / 2, worldSize / 2, worldSize / 2); G4LogicalVolume* worldLV = new G4LogicalVolume(worldS, defaultMaterial, "World"); G4VPhysicalVolume* worldPV = new G4PVPlacement(0, G4ThreeVector(), worldLV, "World", 0, false, 0, fCheckOverlaps); // PRC Outer Shell G4VSolid* prcOuterS = new G4Box("PRCOuter", prcWidth / 2, prcHeight / 2, prcLength / 2); G4LogicalVolume* prcOuterLV = new G4LogicalVolume(prcOuterS, cathodeMaterial, "PRCOuter"); new G4PVPlacement(0, G4ThreeVector(), prcOuterLV, "PRCOuter", worldLV, false, 0, fCheckOverlaps); // PRC Inner (Gas) G4VSolid* prcInnerS = new G4Box("PRCInner", (prcWidth - 2 * wallThickness) / 2, (prcHeight - 2 * wallThickness) / 2, prcLength / 2); G4LogicalVolume* prcInnerLV = new G4LogicalVolume(prcInnerS, gasMaterial, "PRCInner"); new G4PVPlacement(0, G4ThreeVector(), prcInnerLV, "PRCInner", prcOuterLV, false, 0, fCheckOverlaps); // Anode Wire G4VSolid* wireS = new G4Tubs("AnodeWire", 0, wireRadius, prcLength / 2, 0, 2 * pi); G4LogicalVolume* wireLV = new G4LogicalVolume(wireS, wireMaterial, "AnodeWire"); new G4PVPlacement(0, G4ThreeVector(), wireLV, "AnodeWire", prcInnerLV, false, 0, fCheckOverlaps); // Visualization worldLV->SetVisAttributes(G4VisAttributes::GetInvisible()); G4VisAttributes* visPRC = new G4VisAttributes(G4Colour(0.0, 0.0, 1.0)); // Mild steel G4VisAttributes* visGas = new G4VisAttributes(G4Colour(0.0, 1.0, 0.0)); // Gas G4VisAttributes* visWire = new G4VisAttributes(G4Colour(1.0, 0.0, 0.0)); // Tungsten wire prcOuterLV->SetVisAttributes(visPRC); prcInnerLV->SetVisAttributes(visGas); wireLV->SetVisAttributes(visWire); G4Region* regionGarfield = new G4Region("RegionGarfield"); regionGarfield->AddRootLogicalVolume(prcInnerLV); G4Region* regionWire = new G4Region("RegionWire"); regionWire->AddRootLogicalVolume(wireLV); fGarfieldG4FastSimulationModel = new GarfieldG4FastSimulationModel( "GarfieldG4FastSimulationModel", regionGarfield); fGarfieldG4FastSimulationModel->WriteGeometryToGDML(fGasPV); // Return the physical world return worldPV; } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... G4Material* GarfieldDetectorConstruction::AbsorberMaterialWithSingleIsotope( G4String name, G4String symbol, G4double density, G4int Z, G4int A) { // define a material from an isotope // G4int ncomponents; G4double abundance, massfraction; G4Isotope* isotope = new G4Isotope(symbol, Z, A); G4Element* element = new G4Element(name, symbol, ncomponents = 1); element->AddIsotope(isotope, abundance = 100. * perCent); G4Material* material = new G4Material(name, density, ncomponents = 1); material->AddElement(element, massfraction = 100. * perCent); return material; } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... void GarfieldDetectorConstruction::SetAbsorberMaterial( G4String materialChoice) { // search the material by its name G4Material* newMaterial = G4NistManager::Instance()->FindOrBuildMaterial(materialChoice); if (newMaterial) { if (fAbsorberMaterial != newMaterial) { fAbsorberMaterial = newMaterial; if (fAbsorberLV) { fAbsorberLV->SetMaterial(fAbsorberMaterial); } G4RunManager::GetRunManager()->PhysicsHasBeenModified(); } } else { G4cout << "\n--> warning from GarfieldDetectorConstruction::SetMaterial : " << materialChoice << " not found" << G4endl; } } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......