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: CCalMaterialFactory.cc 28 // Description: CCalMaterialFactory is a factory class to vuild G4Material 29 // from CCalMaterial and CCalAmaterial 30 /////////////////////////////////////////////////////////////////////////////// 31 #include <fstream> 32 #include <stdlib.h> 33 34 #include "CCalMaterialFactory.hh" 35 #include "CCalutils.hh" 36 37 #include "G4PhysicalConstants.hh" 38 #include "G4SystemOfUnits.hh" 39 #include "G4Material.hh" 40 41 //#define ddebug 42 //#define debug 43 44 typedef CCalMaterial* ptrCCalMaterial; 45 typedef CCalAMaterial* ptrCCalAMaterial; 46 47 48 CCalMaterialFactory * CCalMaterialFactory::instance = 0; 49 G4String CCalMaterialFactory::elementfile = ""; 50 G4String CCalMaterialFactory::mixturefile = ""; 51 52 53 CCalMaterialFactory* CCalMaterialFactory::getInstance(const G4String& matfile, 54 const G4String& mixfile){ 55 if ((matfile=="" || matfile==elementfile) && 56 (mixfile=="" || mixfile==mixturefile)) 57 return getInstance(); 58 else if ((matfile != "" && elementfile != "" && matfile != elementfile) || 59 (mixfile != "" && mixturefile != "" && mixfile != mixturefile)) { 60 G4cerr << "ERROR: Trying to get materials from " << matfile << " and " 61 << mixfile << " while previously were retrieved from " 62 << elementfile << " and " << mixturefile << "." << G4endl; 63 return 0; 64 } else { 65 if (elementfile == "") 66 elementfile=matfile; 67 if (mixturefile == "") 68 mixturefile=mixfile; 69 return getInstance(); 70 } 71 } 72 73 74 CCalMaterialFactory* CCalMaterialFactory::getInstance(const G4String& matfile){ 75 return getInstance(matfile,matfile); 76 } 77 78 79 CCalMaterialFactory* CCalMaterialFactory::getInstance(){ 80 if (elementfile=="" || mixturefile=="") { 81 G4cerr << "ERROR: You haven't defined files to be used for materials in " 82 << "CCalMaterialFactory::getInstance(const G4String&,const G4String&)" 83 << G4endl; 84 return 0; 85 } 86 87 if (instance==0) { 88 instance = new CCalMaterialFactory; 89 return instance; 90 } 91 else 92 return instance; 93 } 94 95 96 CCalMaterialFactory::~CCalMaterialFactory(){ 97 CCalMaterialTable::iterator ite; 98 for(ite = theCCalMaterials.begin(); ite != theCCalMaterials.end(); ite++ ){ 99 delete *ite; 100 } 101 theCCalMaterials.clear(); 102 CCalAMaterialTable::iterator itea; 103 for(itea = theCCalAMaterials.begin(); itea != theCCalAMaterials.end(); 104 itea++ ){ 105 delete *itea; 106 } 107 theCCalAMaterials.clear(); 108 } 109 110 111 G4Material* CCalMaterialFactory::findMaterial(const G4String & mat) const { 112 G4Material* theMat=findG4Material(mat); 113 114 if (theMat) { 115 #ifdef ddebug 116 G4cout << "Material " << mat << " already defined. Returning previous " 117 << "instance." << G4endl; 118 #endif 119 return theMat; 120 } else { 121 CCalMaterial* CCalmat=findCCalMaterial(mat); 122 if (CCalmat){ 123 G4Material* G4Mat = new G4Material(CCalmat->Name(), 124 CCalmat->Density()*g/cm3, 125 CCalmat->NElements()); 126 for(G4int i=0; i<CCalmat->NElements(); i++) { 127 G4Element* elem = findElement(CCalmat->Element(i)); 128 if (!elem) { 129 G4ExceptionDescription ed; 130 ed << " Could not build material " << mat << "." << G4endl; 131 G4Exception("CCalMaterialFactory::findMaterial()","ccal001", 132 FatalException,ed); 133 } 134 G4Mat->AddElement(elem, CCalmat->Weight(i)); 135 } 136 #ifdef ddebug 137 G4cout << "Material " << mat << " has been built successfully." << G4endl; 138 #endif 139 return G4Mat; 140 } else { 141 G4cerr << "ERROR: Material " << mat << " not found in CCal database!!!" 142 << G4endl; 143 return 0; 144 } 145 } 146 } 147 148 149 G4Element* CCalMaterialFactory::findElement(const G4String & mat) const { 150 const G4ElementTable theElements = *(G4Element::GetElementTable()); 151 for (unsigned int i=0; i<theElements.size(); i++) 152 if (theElements[i]->GetName()==mat){ 153 #ifdef ddebug 154 G4cout << "Element " << mat << " found!" << G4endl; 155 #endif 156 return theElements[i]; 157 } 158 return 0; 159 } 160 161 162 G4Element* CCalMaterialFactory::addElement(const G4String & name, 163 const G4String & symbol, 164 G4double Z, G4double A, 165 G4double density) { 166 167 G4Element* theEl = new G4Element(name, symbol, Z, A*g/mole); 168 //Make it also as a material. 169 CCalAMaterial* theMat = new CCalAMaterial(name,A,density); 170 theCCalAMaterials.push_back(theMat); 171 172 #ifdef ddebug 173 G4cout << "Element " << name << " created!" << G4endl; 174 #endif 175 return theEl; 176 } 177 178 179 G4Material* CCalMaterialFactory::addMaterial(const G4String& name, 180 G4double density, 181 G4int nconst, 182 G4String mats[], 183 G4double prop[], 184 MatDescription md){ 185 addCCalMaterial(name, density, nconst, mats, prop, md); 186 return findMaterial(name); 187 } 188 189 190 void CCalMaterialFactory::readElements(const G4String& matfile) { 191 192 G4String path = "NULL"; 193 if (std::getenv("CCAL_GLOBALPATH")) 194 path = std::getenv("CCAL_GLOBALPATH"); 195 196 G4cout << " ==> Opening file " << matfile << " to read elements..." << G4endl; 197 std::ifstream is; 198 G4bool ok = openGeomFile(is, path, matfile); 199 if (!ok) { 200 G4cerr << "ERROR: Could not open file " << matfile << G4endl; 201 return; 202 } 203 204 // Find *DO GMAT 205 findDO(is, G4String("GMAT")); 206 207 readElements(is); 208 209 is.close(); 210 } 211 212 213 void CCalMaterialFactory::readMaterials(const G4String& matfile) { 214 215 G4String path = "NULL"; 216 if (std::getenv("CCAL_GLOBALPATH")) 217 path = std::getenv("CCAL_GLOBALPATH"); 218 219 G4cout << " ==> Opening file " << matfile << " to read materials..." << G4endl; 220 std::ifstream is; 221 bool ok = openGeomFile(is, path, matfile); 222 if (!ok) { 223 G4cerr << "ERROR: Could not open file " << matfile << G4endl; 224 return; 225 } 226 227 // Find *DO GMIX 228 findDO(is, G4String("GMIX")); 229 230 readMaterials(is); 231 232 is.close(); 233 } 234 235 236 //=========================================================================== 237 // Protected & private methods ============================================== 238 239 240 G4Material* CCalMaterialFactory::findG4Material(const G4String & mat) const { 241 const G4MaterialTable theG4Materials = *(G4Material::GetMaterialTable()); 242 for (unsigned int i=0; i<theG4Materials.size(); i++) { 243 if (theG4Materials[i]->GetName()==mat){ 244 return theG4Materials[i]; 245 } 246 } 247 return 0; 248 } 249 250 251 CCalMaterial* CCalMaterialFactory::findCCalMaterial(const G4String & mat) 252 const { 253 for (unsigned int i=0; i<theCCalMaterials.size(); i++) 254 if (theCCalMaterials[i]->Name()==mat){ 255 #ifdef ddebug 256 G4cout << "CCalMaterial " << mat << " found!" << G4endl; 257 #endif 258 return theCCalMaterials[i]; 259 } 260 return (CCalMaterial*) findCCalAMaterial(mat); 261 } 262 263 264 CCalAMaterial* CCalMaterialFactory::findCCalAMaterial(const G4String & mat) 265 const { 266 for (unsigned int i=0; i<theCCalAMaterials.size(); i++) 267 if (theCCalAMaterials[i]->Name()==mat){ 268 #ifdef ddebug 269 G4cout << "CCalMaterial " << mat << " found!" << G4endl; 270 #endif 271 return theCCalAMaterials[i]; 272 } 273 return 0; 274 } 275 276 277 CCalMaterial* CCalMaterialFactory::addCCalMaterial(const G4String& name, 278 G4double density, 279 G4int nconst, 280 G4String mats[], 281 G4double prop[], 282 MatDescription md){ 283 ptrCCalMaterial* matcol=0; 284 ptrCCalAMaterial* amatcol=0; 285 286 if (md==byAtomic) 287 amatcol = new ptrCCalAMaterial[nconst]; 288 else 289 matcol = new ptrCCalMaterial[nconst]; 290 291 for (G4int i=0; i<nconst; i++){ 292 if (md==byAtomic) { 293 CCalAMaterial* amat = findCCalAMaterial(mats[i]); 294 if (amat) 295 amatcol[i]=amat; 296 else { 297 G4cerr << "ERROR: Trying to build" << name << " out of unknown " 298 << mats[i] << "." << G4endl 299 << "Skiping this material!" << G4endl; 300 delete[] amatcol; 301 return 0; 302 } 303 } //by Atomic fractions 304 else { 305 CCalMaterial* mat = findCCalMaterial(mats[i]); 306 if (mat) 307 matcol[i]=mat; 308 else { 309 G4cerr << "ERROR: Trying to build" <<name << " out of unknown " 310 << mats[i] << "." << G4endl 311 << "Skiping this material!" << G4endl; 312 delete[] matcol; 313 return 0; 314 } 315 } 316 } //for 317 318 //Let's do the CCalMaterial! 319 if (md==byAtomic) { 320 CCalAMaterial* amaterial = new CCalAMaterial(name, density, nconst, 321 amatcol, prop); 322 delete[] amatcol; 323 theCCalAMaterials.push_back(amaterial); 324 #ifdef ddebug 325 G4cout << *amaterial << G4endl; 326 #endif 327 return amaterial; 328 } else { 329 CCalMaterial::FractionType ft; 330 if (md == byWeight) 331 ft=CCalMaterial::FTWeight; 332 else 333 ft=CCalMaterial::FTVolume; 334 CCalMaterial* material = new CCalMaterial(name, density, nconst, 335 matcol, prop, ft); 336 delete[] matcol; 337 theCCalMaterials.push_back(material); 338 #ifdef ddebug 339 G4cout << *material << G4endl; 340 #endif 341 return material; 342 } 343 } 344 345 346 void CCalMaterialFactory::readElements(std::ifstream& is){ 347 G4String name, symbol; 348 349 G4cout << " ==> Reading elements... " << G4endl; 350 #ifdef debug 351 G4cout << " Element \tsymbol\tA\tZ\tdensity\tX_0 abs_l"<< G4endl; 352 #endif 353 //There should come the list of materials. #. Defines a comment 354 //*DO defines the beguining of the Mixes block. 355 356 readName(is,name); 357 while (name != "*ENDDO") { 358 //It should be an element definition 359 G4double A, Z, density; 360 is >> symbol >> A >> Z >> density >> jump; 361 #ifdef debug 362 G4cout << " " << name << " \t" << symbol << "\t" 363 << A << "\t" << Z << "\t" << density << G4endl; 364 #endif 365 addElement(name, symbol, Z, A, density); 366 readName(is,name); 367 }; 368 G4cout << " " << G4Element::GetElementTable()->size() 369 << " elements read from file" << G4endl << G4endl; 370 } 371 372 373 void CCalMaterialFactory::readMaterials(std::ifstream& is){ 374 G4String name, matname; 375 376 G4cout << " ==> Reading materials... " << G4endl; 377 378 //Take into account the special case of vacuum... 379 #ifdef debug 380 G4cout <<" \"Vacuum\"" << G4endl; 381 #endif 382 G4double density = universe_mean_density; //from PhysicalConstants.h 383 G4double pressure = 1.E-19*pascal; 384 G4double temperature = 0.1*kelvin; 385 new G4Material("Vacuum", /*Z=*/ 1., /*A=*/ 1.01*g/mole, 386 density, kStateGas, temperature, pressure); 387 388 //There should come the list of materials. #. Defines a comment 389 //*ENDDO defines the block. 390 readName(is,name); 391 while (name != "*ENDDO") { 392 //It should be a material definition 393 matname=name; 394 G4int nElem; 395 G4double dens; 396 is >> nElem >> dens >> jump; 397 398 #ifdef debug 399 G4cout <<" " << matname 400 << " made of " << nElem 401 << " elements. Density=" << dens 402 << G4endl; 403 #endif 404 405 G4int absnelem = std::abs(nElem); 406 407 G4String* mats = new G4String[absnelem]; 408 G4double* weights = new G4double[absnelem]; 409 410 G4double prop; 411 for(int i=0; i<absnelem; i++) { 412 readName(is, name); 413 is >> prop >> jump; 414 mats[i]=name; 415 weights[i]=std::abs(prop); 416 } //for... 417 MatDescription md; 418 if (nElem>0 && prop<0) 419 md = byAtomic; 420 else if (nElem>0) 421 md = byWeight; 422 else 423 md = byVolume; 424 425 addCCalMaterial(matname, dens, absnelem, mats, weights, md); 426 delete[] mats; 427 delete[] weights; 428 429 readName(is,name); 430 }; //while 431 432 G4cout << " " << theCCalMaterials.size() << " materials read from " 433 << mixturefile << G4endl << G4endl; 434 } 435 436 437 CCalMaterialFactory::CCalMaterialFactory() { 438 readElements (elementfile); 439 readMaterials(mixturefile); 440 } 441