ATLAS Offline Software
Loading...
Searching...
No Matches
Geo2G4MaterialFactory.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
9
10#include "GeoModelKernel/GeoMaterial.h"
13
14#include "G4Material.hh"
15
16#include <mutex>
17#include <unordered_map>
18
19namespace {
20 typedef std::unordered_map<const GeoMaterial* , G4Material*> matList;
21 typedef std::unordered_map<std::string, const GeoMaterial*> matNames;
22}
23
25 AthMessaging("Geo2G4MaterialFactory")
26{
27}
28
29G4Material* Geo2G4MaterialFactory::Build(const GeoMaterial* geoMaterial)
30{
31 // Material caches and mutex
32 static matList geoMaterialToG4Material ATLAS_THREAD_SAFE;
33 static matNames geoMaterialNameToObject ATLAS_THREAD_SAFE;
34
35 // For now just use a global lock. If this turns out to be a bottleneck
36 // switch to a concurrent map or similar.
37 static std::mutex matLock;
38 std::scoped_lock lock(matLock);
39
40 //
41 // Check if this material has already been defined.
42 //
43 const auto itr = geoMaterialToG4Material.find(geoMaterial);
44 if(itr != geoMaterialToG4Material.end()) {
45 return itr->second;
46 }
47
48 const std::string& geoMaterialName = geoMaterial->getName();
49 const int nelements = geoMaterial->getNumElements();
50
51 // Different actions depending whether we are dealing with
52 // standard or extended materials
53
54 const GeoExtendedMaterial* extMat = dynamic_cast<const GeoExtendedMaterial*>(geoMaterial);
55 G4Material* g4Material{};
56
57 if(extMat) {
58 G4State state = kStateUndefined;
59
60 switch(extMat->getState())
61 {
62 case stateUndefined:
63 state = kStateUndefined;
64 break;
65 case stateSolid:
66 state = kStateSolid;
67 break;
68 case stateLiquid:
69 state = kStateLiquid;
70 break;
71 case stateGas:
72 state = kStateGas;
73 break;
74 default:
75 break;
76 }
77
78 const double temperature = extMat->getTemperature();
79 const double pressure = extMat->getPressure();
80
81 g4Material= new G4Material(geoMaterialName,
82 extMat->getDensity(),
83 nelements,
84 state,
85 temperature,
86 pressure);
87
88 // Build G4MaterialPropertiesTable if needed
89 const GeoMaterialPropertiesTable* geoPropTable = extMat->GetMaterialPropertiesTable();
90
91 if(geoPropTable) {
93 G4MaterialPropertiesTable* g4PropTable = tFactory.Build(geoPropTable);
94 if(g4PropTable) {
95 g4Material->SetMaterialPropertiesTable(g4PropTable);
96 }
97 }
98 }
99 else {
100 g4Material= new G4Material(geoMaterialName,
101 geoMaterial->getDensity(),
102 nelements);
103 }
104
105 static Geo2G4ElementFactory eFactory ATLAS_THREAD_SAFE; // locked above
106 for (int ii = 0; ii< nelements; ii++) {
107 G4Element* g4Element = eFactory.Build(geoMaterial->getElement(ii));
108 g4Material->AddElement(g4Element, geoMaterial->getFraction(ii));
109 }
110
111 const G4MaterialTable & theMaterialTable = *(g4Material->GetMaterialTable());
112 const G4String& g4MaterialName = g4Material->GetName();
113 std::vector<size_t> copyIndex{};
114 for(size_t i=0; i< theMaterialTable.size(); ++i) {
115 if(theMaterialTable[i]->GetName() == g4MaterialName) {
116 copyIndex.push_back(i);
117 }
118 }
119 if ( copyIndex.size() > 1 ) {
120 ATH_MSG_WARNING ( "Details of all G4Materials named " << g4MaterialName << " in the G4MaterialTable.");
121 for (size_t index : copyIndex) {
122 ATH_MSG_WARNING ( "G4Material at position "<< index<<" in the G4MaterialTable: \n" << *(theMaterialTable[index]));
123 }
124 }
125
126
127 geoMaterialToG4Material[geoMaterial]=g4Material;
128
129 // Check if we have the situation when on GeoModel side two different
130 // materials share the same name.
131 // Print a WARNING message if so.
132 const auto [it, inserted] = geoMaterialNameToObject.try_emplace(geoMaterialName, geoMaterial);
133 if(!inserted) {
134 ATH_MSG_WARNING ( "!!! On GeoModel side two different materials share the name: " << geoMaterialName );
135 }
136
137 return g4Material;
138}
#define ATH_MSG_WARNING(x)
@ stateLiquid
@ stateUndefined
@ stateSolid
Define macros for attributes used to control the static checker.
std::atomic_flag m_initialized ATLAS_THREAD_SAFE
Messaging initialized (initMessaging)
AthMessaging(IMessageSvc *msgSvc, const std::string &name)
Constructor.
G4MaterialPropertiesTable * Build(const GeoMaterialPropertiesTable *)
G4Material * Build(const GeoMaterial *)
const GeoMaterialState & getState() const
const double & getTemperature() const
GeoMaterialPropertiesTable * GetMaterialPropertiesTable()
const double & getPressure() const
Definition index.py:1