4#include "G4Material.hh"
9bool G4World::createG4Material(
const std::shared_ptr<GMaterial> &gmaterial) {
10 auto NISTman = G4NistManager::Instance();
11 auto materialName = gmaterial->getName();
14 auto g4material = NISTman->FindMaterial(materialName);
15 if (g4material !=
nullptr) {
16 log->
info(2,
"Material <", materialName,
"> already exists in G4NistManager");
20 auto components = gmaterial->getComponents();
21 auto amounts = gmaterial->getAmounts();
22 bool isChemical = gmaterial->isChemicalFormula();
26 for (
auto &componentName: components) {
28 if (NISTman->FindOrBuildElement(componentName) ==
nullptr) {
29 log->
info(2,
"Element <", componentName,
">, needed by ", materialName,
", not found yet");
31 }
else {
log->
info(2,
"Element <", componentName,
"> needed by ", materialName,
" now found"); }
33 if (NISTman->FindOrBuildMaterial(componentName) ==
nullptr) {
34 log->
info(2,
"Material <", componentName,
">, needed by ", materialName,
", not found yet");
36 }
else {
log->
info(2,
"Material <", componentName,
"> needed by ", materialName,
" now found"); }
41 auto density = gmaterial->getDensity();
42 g4materialsMap[materialName] =
new G4Material(materialName, density * CLHEP::g / CLHEP::cm3,
43 static_cast<G4int
>(components.size()));
46 log->
info(2,
"Building material <", materialName,
"> with components:");
47 for (
size_t i = 0; i < components.size(); i++) {
48 log->
info(2,
"element <", components[i],
"> with amount: ", amounts[i]);
51 for (
size_t i = 0; i < components.size(); i++) {
52 auto element = NISTman->FindOrBuildElement(components[i]);
53 g4materialsMap[materialName]->AddElement(element,
static_cast<G4int
>(amounts[i]));
56 log->
info(2,
"Building material <", materialName,
"> with components:");
57 for (
size_t i = 0; i < components.size(); i++) {
58 log->
info(2,
"material <", components[i],
"> with fractional mass: ", amounts[i]);
61 for (
size_t i = 0; i < components.size(); i++) {
62 auto material = NISTman->FindOrBuildMaterial(components[i]);
63 g4materialsMap[materialName]->AddMaterial(material, amounts[i]);
68 auto photonEnergy = gmaterial->getPhotonEnergy();
69 if (!photonEnergy.empty()) {
70 auto *materialPropertiesTable =
new G4MaterialPropertiesTable();
71 bool hasOpticalProperties =
false;
73 auto addProperty = [&](
const char *propertyName,
const std::vector<double> &values) {
74 if (values.empty()) {
return; }
75 if (values.size() != photonEnergy.size()) {
76 log->
error(ERR_GMATERIALOPTICALPROPERTYMISMATCH,
77 "material <", materialName,
"> optical property <", propertyName,
"> has ",
78 values.size(),
" entries but photonEnergy has ", photonEnergy.size());
80 materialPropertiesTable->AddProperty(propertyName, photonEnergy, values);
81 hasOpticalProperties =
true;
84 auto addConstantProperty = [&](
const char *propertyName,
double value,
bool isSet) {
85 if (!isSet) {
return; }
86 materialPropertiesTable->AddConstProperty(propertyName, value);
87 hasOpticalProperties =
true;
91 addProperty(
"RINDEX", gmaterial->getIndexOfRefraction());
92 addProperty(
"ABSLENGTH", gmaterial->getAbsorptionLength());
93 addProperty(
"REFLECTIVITY", gmaterial->getReflectivity());
94 addProperty(
"EFFICIENCY", gmaterial->getEfficiency());
96 addProperty(
"SCINTILLATIONCOMPONENT1", gmaterial->getFastComponent());
97 addProperty(
"SCINTILLATIONCOMPONENT2", gmaterial->getSlowComponent());
100 addConstantProperty(
"SCINTILLATIONYIELD", gmaterial->getScintillationYield(),
101 gmaterial->hasScintillationYield());
102 addConstantProperty(
"RESOLUTIONSCALE", gmaterial->getResolutionScale(),
103 gmaterial->hasResolutionScale());
105 addConstantProperty(
"SCINTILLATIONTIMECONSTANT1", gmaterial->getFasttimeConstant() * CLHEP::ns,
106 gmaterial->hasFasttimeConstant());
107 addConstantProperty(
"SCINTILLATIONTIMECONSTANT2", gmaterial->getSlowtimeConstant() * CLHEP::ns,
108 gmaterial->hasSlowtimeConstant());
109 addConstantProperty(
"SCINTILLATIONYIELD1", gmaterial->getYieldratio(),
110 gmaterial->hasYieldratio());
112 double getBirksConstant = gmaterial->getBirksConstant();
113 if (gmaterial->hasBirksConstant()) {
114 g4materialsMap[materialName]->GetIonisation()->SetBirksConstant(getBirksConstant);
115 hasOpticalProperties =
true;
119 addProperty(
"RAYLEIGH", gmaterial->getRayleigh());
121 if (hasOpticalProperties) {
122 g4materialsMap[materialName]->SetMaterialPropertiesTable(materialPropertiesTable);
123 log->
info(2,
"Attached optical material properties table to material <", materialName,
">");
124 }
else {
delete materialPropertiesTable; }
131void G4World::buildDefaultMaterialsElementsAndIsotopes() {
140 if (G4NistManager::Instance()->FindMaterial(
HGAS_MATERIAL) ==
nullptr) {
142 a = 1.01 * CLHEP::g / CLHEP::mole;
143 d = 0.00275 * CLHEP::g / CLHEP::cm3;
144 T = 50.0 * CLHEP::kelvin;
153 log->
info(2,
"G4World: Hydrogen gas material <",
HGAS_MATERIAL,
"> created with density <", d,
">");
158 if (G4NistManager::Instance()->FindOrBuildElement(
DEUTERIUM_ELEMENT) ==
nullptr) {
161 a = 2.0141018 * CLHEP::g / CLHEP::mole;
166 Deuterium->AddIsotope(Deuteron, 1);
172 d = 0.000452 * CLHEP::g / CLHEP::cm3;
173 T = 294.25 * CLHEP::kelvin;
184 if (G4NistManager::Instance()->FindMaterial(
LD2_MATERIAL) ==
nullptr) {
185 d = 0.169 * CLHEP::g / CLHEP::cm3;
186 T = 22.0 * CLHEP::kelvin;
194 log->
info(2,
"G4World: Liquid Deuterium material <",
LD2_MATERIAL,
"> created with density <", d,
">");
197 if (G4NistManager::Instance()->FindMaterial(
ND3_MATERIAL) ==
nullptr) {
199 a = 14.01 * CLHEP::g / CLHEP::mole;
200 d = 1.007 * CLHEP::g / CLHEP::cm3;
201 T = 1.0 * CLHEP::kelvin;
211 log->
info(2,
"G4World: Ammonia material <",
ND3_MATERIAL,
"> created with density <", d,
">");
216 if (G4NistManager::Instance()->FindOrBuildElement(
HELIUM3_ELEMENT) ==
nullptr) {
219 a = 3.0160293 * CLHEP::g / CLHEP::mole;
224 Helium3->AddIsotope(Helion, 1);
231 d = 0.1650 * CLHEP::mg / CLHEP::cm3;
232 T = 294.25 * CLHEP::kelvin;
245 if (G4NistManager::Instance()->FindOrBuildElement(
TRITIUM_ELEMENT) ==
nullptr) {
248 a = 3.0160492 * CLHEP::g / CLHEP::mole;
252 Tritium->AddIsotope(Triton, 1);
258 d = 0.0034 * CLHEP::g / CLHEP::cm3;
259 T = 40.0 * CLHEP::kelvin;
std::shared_ptr< GLogger > log
void info(int level, Args &&... args) const
void error(int exit_code, Args &&... args) const
#define DEUTERIUM_ELEMENT
#define DEUTERIUMGAS_MATERIAL
#define HELIUM3GAS_MATERIAL
#define TRITIUMGAS_MATERIAL
High-level builder that turns a GEMC world description into Geant4 geometry.