Geant4 Cross Reference |
1 // 1 2 // ******************************************* 3 // * License and Disclaimer 4 // * 5 // * The Geant4 software is copyright of th 6 // * the Geant4 Collaboration. It is provided 7 // * conditions of the Geant4 Software License 8 // * LICENSE and available at http://cern.ch/ 9 // * include a list of copyright holders. 10 // * 11 // * Neither the authors of this software syst 12 // * institutes,nor the agencies providing fin 13 // * work make any representation or warran 14 // * regarding this software system or assum 15 // * use. Please see the license in the file 16 // * for the full disclaimer and the limitatio 17 // * 18 // * This code implementation is the result 19 // * technical work of the GEANT4 collaboratio 20 // * By using, copying, modifying or distri 21 // * any work based on the software) you ag 22 // * use in resulting scientific publicati 23 // * acceptance of all terms of the Geant4 Sof 24 // ******************************************* 25 // 26 // ------------------------------------------- 27 // =============== Begin Documentation Commen 28 //! 29 //! \file FFDetectorConstruction.cc 30 //! \author B. Wendt (brycen.linn.wendt@ce 31 //! \date June 06, 2014 32 //! 33 //! \brief Implementation of the FFDetect 34 //! 35 //! \details The model simulated is based o 36 //! with 20% enriched meat 37 //! 38 // ================ End Documentation Comment 39 // 40 // Modified: 41 // 42 // 23-06-14 43 // Fixed issue with the automatic placement o 44 // was to use the correct units "inch" in 45 // Coincidentally eliminated the need to usin 46 // "cmath" library. 47 // Implemented method "PlaceFuelPlates" 48 // 49 // ------------------------------------------- 50 51 #include "FFDetectorConstruction.hh" 52 53 #include "G4Box.hh" 54 #include "G4Element.hh" 55 #include "G4Isotope.hh" 56 #include "G4LogicalVolume.hh" 57 #include "G4NistManager.hh" 58 #include "G4PVPlacement.hh" 59 #include "G4SystemOfUnits.hh" 60 #include "G4Tubs.hh" 61 #include "G4VPhysicalVolume.hh" 62 #include "globals.hh" 63 64 static const G4double inch = 2.54 * cm; 65 66 //....oooOO0OOooo........oooOO0OOooo........oo 67 FFDetectorConstruction::FFDetectorConstruction 68 { 69 DefineMaterials(); 70 } 71 72 //....oooOO0OOooo........oooOO0OOooo........oo 73 G4VPhysicalVolume* FFDetectorConstruction::Con 74 { 75 G4ThreeVector position; 76 #ifdef NDEBUG 77 G4bool const overlapChecking = false; 78 #else 79 G4bool const overlapChecking = true; 80 #endif // NDEBUG 81 82 // 83 // Create the world 84 // 85 const G4double worldSize = 40.0 * inch; 86 G4Box* const solidWorld = new G4Box("World", 87 worldSiz 88 worldSiz 89 worldSiz 90 G4LogicalVolume* const logicalWorld = new G4 91 92 93 // Center at the origin 94 position.set(0.0, 0.0, 0.0); 95 G4VPhysicalVolume* const physicalWorld = 96 new G4PVPlacement(NULL, // no rotation 97 position, // must be at 98 logicalWorld, // the lo 99 logicalWorld->GetName(), 100 NULL, // no mother volu 101 false, // no boolean op 102 0, // copy number 103 overlapChecking); // ch 104 105 // 106 // Create the graphite pile that the subcrit 107 // 108 const G4double floorH = 30.0 * inch; 109 const G4ThreeVector floorPosition(0.0, 0.0, 110 G4Box* const solidFloor = new G4Box("Floor", 111 worldSiz 112 worldSiz 113 floorH * 114 G4LogicalVolume* const logicalFloor = new G4 115 116 117 // Shift down so the top is at the origin 118 position.set(0.0, 0.0, -floorH * 0.5); 119 new G4PVPlacement(NULL, // no rotation 120 position, // position 121 logicalFloor, // the logi 122 logicalFloor->GetName(), 123 logicalWorld, // the moth 124 false, // no boolean ops 125 0, // copy number 126 overlapChecking); // chec 127 128 // 129 // Create the tank 130 // 131 const G4double tankWallThickness = 0.25 * in 132 const G4double tankOR = 18.0 * inch; 133 const G4double tankH = 39.0 * inch; 134 G4Tubs* const solidTank = new G4Tubs("Tank_W 135 0.0, / 136 tankOR, 137 tankH * 138 0.0 * d 139 360.0 * 140 G4LogicalVolume* const logicalTank = new G4L 141 142 143 // Shift up so the base is at the origin 144 position.set(0.0, 0.0, tankH * 0.5); 145 new G4PVPlacement(NULL, // no rotation 146 position, // shift up 147 logicalTank, // the logic 148 logicalTank->GetName(), / 149 logicalWorld, // the moth 150 false, // no boolean ops 151 0, // copy number 152 overlapChecking); // chec 153 // Top 3 inches are air 154 const G4double tankAirH = 3.0 * inch; 155 G4Tubs* const solidTankAir = new G4Tubs("Tan 156 0.0, 157 tank 158 tank 159 0.0 160 360. 161 G4LogicalVolume* const logicalTankAir = new 162 163 164 // Shift up so that the top of the air is th 165 position.set(0.0, 0.0, (tankH - tankAirH) * 166 new G4PVPlacement(NULL, // no rotation 167 position, // shift ip 168 logicalTankAir, // the lo 169 logicalTankAir->GetName(), 170 logicalTank, // the mothe 171 false, // no boolean ops 172 0, // copy number 173 overlapChecking); // chec 174 // Fill remaining area with water 175 const G4double tankH2OH = (tankH - (tankAirH 176 G4Tubs* const solidTankH2O = new G4Tubs("Tan 177 0.0, 178 tank 179 tank 180 0.0 181 360. 182 G4LogicalVolume* const logicalTankH2O = new 183 184 185 // Shift up so that the top of the water is 186 const G4double centerOfH2O = (tankH - tankH2 187 position.set(0.0, 0.0, centerOfH2O); 188 new G4PVPlacement(NULL, // no rotation 189 position, // shift to ori 190 logicalTankH2O, // the lo 191 logicalTankH2O->GetName(), 192 logicalTank, // the mothe 193 false, // no boolean ops 194 0, // copy number 195 overlapChecking); // chec 196 197 // 198 // Fuel plates 199 // 200 const G4double plateX = 3.0 * inch; 201 const G4double plateY = 0.08 * inch; 202 const G4double plateZ = 26.0 * inch; 203 const G4double meatX = 2.75 * inch; 204 const G4double meatY = 0.04 * inch; 205 const G4double meatZ = 24.0 * inch; 206 const G4double xSpacing = 5.0 * inch; 207 const G4double ySpacing = 0.3 * inch; 208 const G4double plateRadius = 12.0 * inch; 209 // Define the aluminim claddiing 210 G4Box* const solidPlate = new G4Box("Plate_C 211 plateX * 212 plateY * 213 plateZ * 214 G4LogicalVolume* const logicalPlate = new G4 215 216 217 // Place the meat inside the cladding 218 G4Box* const solidMeat = new G4Box("Plate_Me 219 meatX * 0 220 meatY * 0 221 meatZ * 0 222 G4LogicalVolume* const logicalMeat = new G4L 223 224 225 // The meat goes into the exact center of th 226 position.set(0.0, 0.0, 0.0); 227 new G4PVPlacement(NULL, // no rotation 228 position, // position 229 logicalMeat, // the logic 230 logicalMeat->GetName(), / 231 logicalPlate, // the moth 232 false, // no boolean ops 233 0, // copy number 234 overlapChecking); // chec 235 // The plate will be centered in the z-direc 236 // Simulate a subcritical assembly loading w 237 bool placeMe; 238 239 position.setZ(0.0); 240 fCopyNumber = 0; 241 for (double x = 0.0; x <= plateRadius; x += 242 // 5 rows of plates 243 for (double y = 0.0; y <= plateRadius; y + 244 placeMe = false; 245 246 // Fuel plate must be completely within 247 if (std::sqrt(x * x + y * y) < plateRadi 248 // Leave a 1 inch radius opening in th 249 // source 250 if (std::sqrt(x * x + y * y) > 1.0 * i 251 placeMe = true; 252 } 253 } 254 255 if (placeMe) { 256 PlaceFuelPlate(x, y, logicalPlate, log 257 PlaceFuelPlate(x, -y, logicalPlate, lo 258 if (x > 0.0) { 259 PlaceFuelPlate(-x, y, logicalPlate, 260 PlaceFuelPlate(-x, -y, logicalPlate, 261 } 262 } 263 } 264 } 265 G4cout << fCopyNumber << " plates were added 266 267 // 268 // Neutron Source 269 // 270 // TODO create the AmBe material in DefineMa 271 // For now steel is used, but the logic 272 // PrimaryGeneratorAction to know where 273 const G4double sourceH = 2 * inch; 274 const G4double sourceR = 0.2 * inch; 275 G4Tubs* const solidSource = new G4Tubs("Neut 276 0.0, 277 sourc 278 sourc 279 0.0 * 280 360.0 281 G4LogicalVolume* const logicalSource = new G 282 283 284 // Place in the exact center of the water ta 285 position.set(0.0, 0.0, 0.0); 286 new G4PVPlacement(NULL, // no rotation 287 position, // shift to ori 288 logicalSource, // the log 289 logicalSource->GetName(), 290 logicalTankH2O, // the mo 291 false, // no boolean ops 292 0, // copy number 293 overlapChecking); // chec 294 295 // 296 // Detector Tower 297 // 298 const G4double polyS = 3.0 * inch; 299 const G4double polyH = 18.0 * inch; 300 G4Box* const solidPoly = new G4Box("Poly", 301 polyS, / 302 polyS, / 303 polyH); 304 G4LogicalVolume* const logicalPoly = new G4L 305 306 307 // The polyethylene detector tower goes just 308 G4double radiusToPolyCenter = (tankOR / std: 309 position.set(-radiusToPolyCenter, radiusToPo 310 new G4PVPlacement(NULL, // no rotation 311 position, // position 312 logicalPoly, // the logic 313 logicalPoly->GetName(), / 314 logicalWorld, // the moth 315 false, // no boolean ops 316 0, // copy number 317 overlapChecking); // chec 318 // Create the detector shell 319 G4double shellR = 0.3 * inch; 320 G4double shellH = 6.5 * inch; 321 G4Tubs* const solidShell = new G4Tubs("Detec 322 0.0, 323 shellR 324 shellH 325 0.0 * 326 360.0 327 G4LogicalVolume* const logicalShell = new G4 328 329 330 // Place in the exact center of the polyethy 331 position.set(0.0, 0.0, 0.0); 332 new G4PVPlacement(NULL, // no rotation 333 position, // shift to ori 334 logicalShell, // the logi 335 logicalShell->GetName(), 336 logicalPoly, // the mothe 337 false, // no boolean ops 338 0, // copy number 339 overlapChecking); // chec 340 // Create the BF3 detector 341 G4double BF3R = 0.2 * inch; 342 G4double BF3H = 6.0 * inch; 343 G4Tubs* const solidBF3 = new G4Tubs("Detecto 344 0.0, // 345 BF3R, / 346 BF3H * 0 347 0.0 * de 348 360.0 * 349 G4LogicalVolume* const logicalBF3 = new G4Lo 350 351 352 // Place in the exact center of the shell 353 position.set(0.0, 0.0, 0.0); 354 new G4PVPlacement(NULL, // no rotation 355 position, // shift to ori 356 logicalBF3, // the logica 357 logicalBF3->GetName(), // 358 logicalShell, // the moth 359 false, // no boolean ops 360 0, // copy number 361 overlapChecking); // chec 362 363 return physicalWorld; 364 } 365 366 //....oooOO0OOooo........oooOO0OOooo........oo 367 void FFDetectorConstruction::DefineMaterials(v 368 { 369 static G4NistManager* const nist = G4NistMan 370 371 fAir = nist->FindOrBuildMaterial("G4_AIR"); 372 fAluminum = nist->FindOrBuildMaterial("G4_Al 373 fGraphite = nist->FindOrBuildMaterial("G4_GR 374 fPolyethylene = nist->FindOrBuildMaterial("G 375 fStainlessSteel = nist->FindOrBuildMaterial( 376 fWater = nist->FindOrBuildMaterial("G4_WATER 377 378 /*// List available materials 379 std::vector< G4String > materials = nist->Ge 380 for(unsigned int i = 0; 381 i < materials.size(); 382 ++i) 383 { 384 G4cout << materials[i] << G4endl; 385 }*/ 386 387 // 388 // Define the 20% enriched UO2 389 // 390 // First we need to start by creating the is 391 G4double const U235Enrichment = 0.2; 392 G4double const U238Enrichment = 0.8; 393 G4Isotope* const iU235 = new G4Isotope("iU23 394 92, 395 235, 396 235.0 397 G4Isotope* const iU238 = new G4Isotope("iU23 398 92, 399 238, 400 238.0 401 // Now create the elements and add the isoto 402 G4Element* const U235 = new G4Element("U235" 403 "U235" 404 1); / 405 U235->AddIsotope(iU235, // isotope 406 1.0); // abundance 407 G4Element* const U238 = new G4Element("U238" 408 "U238" 409 1); / 410 U238->AddIsotope(iU238, // isotope 411 1.0); // abundance 412 G4Element* const oxygen = nist->FindOrBuildE 413 // Calculate the mass fractions 414 const G4double UO2MolecularWeight = 415 U235->GetA() * U235Enrichment + U238->GetA 416 const G4double U235MassFraction = (U235->Get 417 const G4double U238MassFraction = (U238->Get 418 const G4double oxygenMassFraction = (oxygen- 419 // create the material and add the elements 420 fUO2_20E = new G4Material("UO2_20E", // nam 421 10.97 * (g / cm3), 422 3); // number of 423 fUO2_20E->AddElement(U235, // element 424 U235MassFraction); // 425 fUO2_20E->AddElement(U238, // element 426 U238MassFraction); // 427 fUO2_20E->AddElement(oxygen, // element 428 oxygenMassFraction); / 429 430 // 431 // Define the BF3 432 // 433 // The BF3 is B-10 enriched 434 // http://www.orau.org/ptp/collection/propor 435 G4double const B10Enrichment = 0.96; 436 G4double const B11Enrichment = 0.04; 437 G4Isotope* const iB10 = new G4Isotope("iB10" 438 5, // 439 10, / 440 10.012 441 G4Isotope* const iB11 = new G4Isotope("iB11" 442 5, // 443 11, / 444 11.009 445 // Now create the elements and add the isoto 446 G4Element* const B10 = new G4Element("B10", 447 "B10", 448 1); // 449 B10->AddIsotope(iB10, // isotope 450 1.0); // abundance 451 G4Element* const B11 = new G4Element("B11", 452 "B11", 453 1); // 454 B11->AddIsotope(iB11, // isotope 455 1.0); // abundance 456 G4Element* const flouride = nist->FindOrBuil 457 // Calculate the mass fractions 458 const G4double BF3MolecularWeight = 459 B10->GetA() * B10Enrichment + B11->GetA() 460 const G4double B10MassFraction = (B10->GetA( 461 const G4double B11MassFraction = (B11->GetA( 462 const G4double flourideMassFraction = (flour 463 // create the material and add the elements 464 fBF3_96E = new G4Material("BF3_96E", // nam 465 2.5 * (kg / m3), 466 3); // number of 467 fBF3_96E->AddElement(B10, // element 468 B10MassFraction); // m 469 fBF3_96E->AddElement(B11, // element 470 B11MassFraction); // m 471 fBF3_96E->AddElement(flouride, // element 472 flourideMassFraction); 473 } 474 475 //....oooOO0OOooo........oooOO0OOooo........oo 476 void FFDetectorConstruction::PlaceFuelPlate(do 477 G4 478 G4 479 { 480 G4ThreeVector position(x, y); 481 std::ostringstream copyName; 482 copyName << "Plate@Location X:" << std::s 483 484 new G4PVPlacement(NULL, // no rotation 485 position, // position 486 myLogicalVolume, // the l 487 copyName.str(), // the na 488 parentLogicalVolume, // t 489 false, // no boolean ops 490 fCopyNumber++, // copy nu 491 true); // check for overl 492 } 493 494 //....oooOO0OOooo........oooOO0OOooo........oo 495 FFDetectorConstruction::~FFDetectorConstructio 496 { 497 // Nothing here 498 } 499