Geant4 Cross Reference |
1 // 2 // ******************************************************************** 3 // * License and Disclaimer * 4 // * * 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. * 10 // * * 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitation of liability. * 17 // * * 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************************************** 25 // 26 /////////////////////////////////////////////////////////////////////////////// 27 // File: CCalMaterial.cc 28 // Description: CCalMaterial transient class to store information from 29 // material table (database) which is used to make a G4Material 30 /////////////////////////////////////////////////////////////////////////////// 31 #include "CCalMaterial.hh" 32 33 //#define debug 34 35 CCalMaterial::CCalMaterial(G4String mat, G4double dens, G4int nconst, 36 CCalMaterial** constituents, G4double* weights, 37 FractionType ft): name(mat), density(dens) { 38 nElem = 0; 39 40 G4int i=0; 41 for (i=0; i<nconst; i++) 42 nElem += constituents[i]->NElements(); 43 44 theElements = new G4String[nElem]; 45 theWeights = new G4double[nElem]; 46 47 G4double factor; 48 G4int nelem=0; 49 for (i=0; i<nconst; i++) { 50 if (ft==FTWeight) 51 factor=1.0; 52 else 53 factor=constituents[i]->Density(); 54 for (G4int j=0; j<constituents[i]->NElements(); j++) { 55 theElements[nelem] = constituents[i]->Element(j); 56 theWeights[nelem] = constituents[i]->Weight(j)* weights[i] * factor; 57 nelem++; 58 } 59 } 60 61 if (density<0) { //Let's compute density 62 computeDensity(nconst, constituents, weights, ft); 63 } 64 closeMaterial(); 65 } 66 67 CCalMaterial::CCalMaterial(const CCalMaterial& mat): 68 name(mat.name), density(mat.density), nElem(mat.nElem) { 69 theElements = new G4String[nElem]; 70 theWeights = new G4double[nElem]; 71 for (G4int i=0; i<nElem; i++){ 72 theElements[i]=mat.theElements[i]; 73 theWeights[i]=mat.theWeights[i]; 74 } 75 } 76 77 CCalMaterial::~CCalMaterial() { 78 if (theElements) 79 delete[] theElements; 80 if (theWeights) 81 delete[] theWeights; 82 } 83 84 void CCalMaterial::computeDensity(G4int nconst, 85 CCalMaterial** constituents, 86 G4double* weights, FractionType ft) { 87 G4double mass=0; 88 G4double volume=0; 89 for (G4int i=0; i<nconst; i++) { 90 if (ft==FTWeight) { 91 mass+=weights[i]; 92 volume+=(weights[i]/constituents[i]->Density()); 93 } 94 else { //by volume 95 mass+=(weights[i]*constituents[i]->Density()); 96 volume+=weights[i]; 97 } 98 } 99 density=mass/volume; 100 } 101 102 CCalMaterial& CCalMaterial::operator=(const CCalMaterial& mat){ 103 if(theElements) 104 delete[] theElements; 105 if(theWeights) 106 delete[] theWeights; 107 108 name=mat.name; 109 density=mat.density; 110 nElem=mat.nElem; 111 112 theElements = new G4String[nElem]; 113 theWeights = new G4double[nElem]; 114 for (G4int i=0; i<nElem; i++){ 115 theElements[i]=mat.theElements[i]; 116 theWeights[i]=mat.theWeights[i]; 117 } 118 return *this; 119 } 120 121 G4bool CCalMaterial::operator==(const CCalMaterial& mat) const{ 122 return (name==mat.name); 123 } 124 125 G4bool CCalMaterial::operator!=(const CCalMaterial& mat) const{ 126 return (name!=mat.name); 127 } 128 129 void CCalMaterial::closeMaterial() { 130 G4int trueConst=0; 131 132 G4double norm=0; 133 134 for (G4int i=0; i<nElem; i++) { 135 norm+=theWeights[i]; 136 if (theElements[i]!="") { 137 trueConst++; 138 for (G4int j=i+1; j<nElem; j++) { 139 if(theElements[i]==theElements[j]){ 140 theWeights[i]+=theWeights[j]; 141 theElements[j]=""; 142 } 143 }//for j 144 } //if 145 }//for i 146 147 if (trueConst != nElem) { 148 G4String* newConst = new G4String[trueConst]; 149 G4double* newWeight = new G4double[trueConst]; 150 151 G4int newi=0; 152 for(G4int i=0; i<nElem; i++){ 153 if (theElements[i]!="") { 154 newConst[newi] = theElements[i]; 155 newWeight[newi] = theWeights[i]/norm; 156 newi++; 157 } 158 } 159 160 #ifdef debug 161 G4cout << "\tGoing from " << nElem <<" constituents to " << trueConst << G4endl; 162 #endif 163 nElem=trueConst; 164 165 delete[] theElements; 166 delete[] theWeights; 167 168 theElements=newConst; 169 theWeights=newWeight; 170 } 171 else { //Let's normalize the weights 172 for (G4int i=0; i<nElem; i++) 173 theWeights[i] = theWeights[i]/norm; 174 } 175 } 176 177 std::ostream& operator<<(std::ostream& os, const CCalMaterial& mat) { 178 os << mat.name << G4endl; 179 os << "Density= " << mat.density << " g/cm3. Number of Elements: " 180 << mat.nElem << G4endl; 181 for (G4int i=0; i<mat.nElem; i++) 182 os << '\t' << mat.theElements[i] << '\t' << mat.theWeights[i] << G4endl; 183 return os; 184 } 185