File indexing completed on 2025-10-13 08:27:56
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039 #include "DetectorConstruction.hh"
0040
0041 #include "G4Box.hh"
0042 #include "G4Ellipsoid.hh"
0043 #include "G4LogicalVolume.hh"
0044 #include "G4NistManager.hh"
0045 #include "G4Orb.hh"
0046 #include "G4PVPlacement.hh"
0047 #include "G4PhysicalConstants.hh"
0048 #include "G4PhysicalVolumeStore.hh"
0049 #include "G4SystemOfUnits.hh"
0050 #include "G4VPhysicalVolume.hh"
0051 #include "Randomize.hh"
0052
0053 G4VPhysicalVolume* DetectorConstruction::Construct()
0054 {
0055
0056 auto man = G4NistManager::Instance();
0057 auto water = man->FindOrBuildMaterial("G4_WATER");
0058
0059
0060
0061
0062 const G4double worldXYZ = 1 * m;
0063
0064 auto solidWorld = new G4Box("World", 0.5 * worldXYZ, 0.5 * worldXYZ, 0.5 * worldXYZ);
0065 auto lvWorld = new G4LogicalVolume(solidWorld, water, "World");
0066 auto pvWorld =
0067 new G4PVPlacement(nullptr, G4ThreeVector(), lvWorld, "World", nullptr, false, 0, true);
0068
0069
0070
0071 ConstructCell(pvWorld);
0072
0073
0074 return pvWorld;
0075 }
0076
0077 void DetectorConstruction::ConstructCell(G4VPhysicalVolume* pvWorld)
0078 {
0079 const G4double cellRadius = 7 * um;
0080 const G4double nucleusRadius = 4 * um;
0081
0082 const G4int nMitochondria = 100;
0083 const G4double mitoA = 0.55 * micrometer;
0084 const G4double mitoB = 0.25 * micrometer;
0085 const G4double mitoC = 0.90 * micrometer;
0086
0087 auto solidCell = new G4Orb("Cell", cellRadius);
0088 auto lvCell = new G4LogicalVolume(
0089 solidCell, G4NistManager::Instance()->FindOrBuildMaterial("G4_WATER"), "Cell");
0090 auto pvCell =
0091 new G4PVPlacement(nullptr, G4ThreeVector(), "Cell", lvCell, pvWorld, false, 0, true);
0092
0093 auto solidNucleus = new G4Orb("Nucleus", nucleusRadius);
0094 auto lvNucleus = new G4LogicalVolume(
0095 solidNucleus, G4NistManager::Instance()->FindOrBuildMaterial("G4_WATER"), "Nucleus");
0096
0097 new G4PVPlacement(nullptr, G4ThreeVector(), "Nucleus", lvNucleus, pvCell, false, 0, true);
0098
0099 auto solidMito = new G4Ellipsoid("Mitochondria", mitoA, mitoB, mitoC);
0100 auto lvMito = new G4LogicalVolume(
0101 solidMito, G4NistManager::Instance()->FindOrBuildMaterial("G4_WATER"), "Mitochondria");
0102
0103 for (auto i = 0; i < nMitochondria; ++i) {
0104 G4bool overlap = true;
0105 do {
0106 auto u = twopi * G4UniformRand();
0107 auto v = std::acos(2 * G4UniformRand() - 1);
0108 auto dr = G4UniformRand() * cellRadius;
0109 auto x = dr * std::cos(u) * std::sin(v);
0110 auto y = dr * std::sin(u) * std::sin(v);
0111 auto z = dr * std::cos(v);
0112 auto pos = G4ThreeVector(x, y, z);
0113
0114 auto phi = G4UniformRand() * 2 * pi;
0115 auto psi = G4UniformRand() * 2 * pi;
0116 auto rot = new G4RotationMatrix();
0117 rot->rotateX(psi);
0118 rot->rotateY(phi);
0119
0120 auto pvMito = new G4PVPlacement(rot, pos, "Mitochondria", lvMito, pvCell, false, i, false);
0121
0122 overlap = pvMito->CheckOverlaps(1000, 0, false);
0123 if (overlap) {
0124 G4PhysicalVolumeStore::DeRegister(pvMito);
0125 }
0126 } while (overlap);
0127 }
0128 }
0129