Gamma dose in air

Please fill out the following information to help in answering your question, and also see tips for posting code snippets. If you don’t provide this information it will take more time to help with your problem!

_Geant4 Version:_11.3.0
_Operating System:_ubuntu24.04.02
Compiler/Version:
_CMake Version:_3.28


Hello experts,
I met a similar question.I attempted to calculate the absorbed dose of gamma rays in air.Some parameters are as follows.
radioactive source: Co60 of 1132Ci (point source)
distance: 30cm
run/beamOn : 100000000
But the simulated value differs greatly from the theoretical caculated value.I don’t know how to solve it.
the simulated value :22 Gy/h
the theoretical value: 142Gy/h
I do it based on exampleB1.

This is hard to answer without more details of your actual scripts. B1 uses the QBBC physics list by default, which I don’t think has the radioactive decay physics you’d want for Co60. Compare B1 to the physics lists in rdecay01 and rdecay02, for example. Also how are you calculating dose? Exposure is more typical for air measurements.

Thank you for your advice.
I don’t use Decay.This is my Primarygenerator code.

//code in Primarygenerator
PrimaryGeneratorAction::PrimaryGeneratorAction()
{
  G4int n_particle = 1;
  fParticleGun = new G4ParticleGun(n_particle);
  // default particle kinematic
  G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable();
  G4String particleName;
  G4ParticleDefinition* particle = particleTable->FindParticle(particleName = "gamma");
  fParticleGun->SetParticleDefinition(particle);
  fParticleGun->SetParticlePosition(G4ThreeVector((27.5-30)*cm, 0, 0));
}

//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......

PrimaryGeneratorAction::~PrimaryGeneratorAction()
{
  delete fParticleGun;
}

//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......

void PrimaryGeneratorAction::GeneratePrimaries(G4Event* event)
{
    // 随机选择Co-60的两个伽马能量之一
    G4double energy = (G4UniformRand() < 0.5) ? 1.17 * MeV : 1.33 * MeV;
    fParticleGun->SetParticleEnergy(energy);
    // 随机生成单位球面上的方向向量(各向同性)
    G4double costheta = 2.0 * G4UniformRand() - 1.0;
    G4double sintheta = std::sqrt(1.0 - costheta * costheta);
    G4double phi = 2.0 * CLHEP::pi * G4UniformRand();

    G4double dx = sintheta * std::cos(phi);
    G4double dy = sintheta * std::sin(phi);
    G4double dz = costheta;
    fParticleGun->SetParticleMomentumDirection(G4ThreeVector(dx, dy, dz));


  fParticleGun->GeneratePrimaryVertex(event);
}

And then in Runaction.cc

namespace B1
{


//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......

RunAction::RunAction()
{
  // add new units for dose
  //
  const G4double milligray = 1.e-3 * gray;
  const G4double microgray = 1.e-6 * gray;
  const G4double nanogray = 1.e-9 * gray;
  const G4double picogray = 1.e-12 * gray;
  new G4UnitDefinition("milligray", "milliGy", "Dose", milligray);
  new G4UnitDefinition("microgray", "microGy", "Dose", microgray);
  new G4UnitDefinition("nanogray", "nanoGy", "Dose", nanogray);
  new G4UnitDefinition("picogray", "picoGy", "Dose", picogray);
  // Register accumulable to the accumulable manager
  G4AccumulableManager* accumulableManager = G4AccumulableManager::Instance();
  accumulableManager->Register(fEdep);
}

//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......

void RunAction::BeginOfRunAction(const G4Run*)
{
  // inform the runManager to save random number seed
  G4RunManager::GetRunManager()->SetRandomNumberStore(false);
  // reset accumulables to their initial values
  G4AccumulableManager* accumulableManager = G4AccumulableManager::Instance();
  accumulableManager->Reset();
}

//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......

void RunAction::EndOfRunAction(const G4Run* run)
{
  G4int nofEvents = run->GetNumberOfEvent();
  if (nofEvents == 0) return;

  // Merge accumulables
  G4AccumulableManager* accumulableManager = G4AccumulableManager::Instance();
  accumulableManager->Merge();
  // Compute dose = total energy deposit in a run and its variance
  //
  G4double edep = fEdep.GetValue();

  const auto detConstruction = static_cast<const DetectorConstruction*>(
    G4RunManager::GetRunManager()->GetUserDetectorConstruction());
  G4double mass = detConstruction->GetScoringVolume()->GetMass();
  G4double dose = edep / mass;
  // Print
  //
  if (IsMaster()) {
    // 计算剂量
    G4double c=1132*3.7*std::pow(10,10)*3600/nofEvents*dose*2; //Co60 product two gamma in one radiodecay
    G4cout  << "--------------------End of Global Run-----------------------"<< G4endl;
    G4cout << " The run consists of " << nofEvents << " primaries." << G4endl;
    G4cout << " Energy deposit in scoring volume: " << G4BestUnit(edep, "Energy") << G4endl;
    G4cout << " Dose in scoring volume: " << G4BestUnit(c, "Dose") << G4endl;
    G4cout << "------------------------------------------------------------" << G4endl;
  }
}

//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......

void RunAction::AddEdep(G4double edep)
{
  fEdep += edep;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......

}  // namespace B1

of course I should provide my detector.

G4VPhysicalVolume* DetectorConstruction::Construct()
{
  // Get nist material manager
  G4NistManager* nist = G4NistManager::Instance();
  // Option to switch on/off checking of volumes overlaps
  //
  G4bool checkOverlaps = true;

  //
  // World
  //
  G4double world_sizeXY = 2.*m, world_sizeZ =20* cm;
  G4Material* world_mat = nist->FindOrBuildMaterial("G4_AIR");


  auto solidWorld =
    new G4Box("World",  // its name
              0.5 * world_sizeXY, 0.5 * world_sizeZ, 0.5 * world_sizeZ);  // its size

  auto logicWorld = new G4LogicalVolume(solidWorld,  // its solid
                                        world_mat,  // its material
                                        "World");  // its name

  auto physWorld = new G4PVPlacement(nullptr,  // no rotation
                                     G4ThreeVector(),  // at (0,0,0)
                                     logicWorld,  // its logical volume
                                     "World",  // its name
                                     nullptr,  // its mother  volume
                                     false,  // no boolean operation
                                     0,  // copy number
                                     checkOverlaps);  // overlaps checking
//
// 探测小块
//
G4double size1_r = 10 * cm;
G4double size1_h = 10 * cm;

G4ThreeVector pos_tance = G4ThreeVector(27.5 * cm, 0 * cm, 0 * cm);

auto solidtan = new G4Tubs("tance",  // its name
                           0 * cm, 0.5 * size1_r, 0.5 * size1_h, 0, 360 * deg);  // its size

auto logictan = new G4LogicalVolume(solidtan,  // its solid
                                    world_mat,  // its material
                                    "tance");  // its name

G4RotationMatrix* rotation = new G4RotationMatrix();
rotation->rotateY(90 * deg);  // 绕 y 轴旋转 90 度

new G4PVPlacement(rotation,  // 应用旋转
                  pos_tance,  // 放置位置
                  logictan,  // 逻辑体
                  "tance",  // 名称
                  logicWorld,  // 母体逻辑体
                  false,  // 不进行布尔操作
                  1,  // 副本编号
                  checkOverlaps);  // 检查重叠

  // Set Shape2 as scoring volume
  //
  fScoringVolume = logictan;
  //
  // always return the physical World
  //
  return physWorld;
}

Other code is same to exampleB1.
I don’t kown why the result differ so much from thoretical value.

Not that I doubt your ability to emulate Co60 but its probably best to just use the rdecay01/02 physics lists and radioactive decay to make it a one liner in a macro to create that source. Your scoring volume is also a solid cylinder when you want a hollow cylinder of 30 cm +/- some small epsilon. If you are not simulating any environment, such as the ground, you could do a hollow sphere to make everything cleaner.

What about your hits/sensitive detector class?

OK,Thanks for your advice.
I’ve just started learning geant4.I do all based on B1.I just accumulated energydeposit when particle reached my fScoringVolume.This fscoringvolume is a cylinder fulled of air.I think it is like my “sensitive”.