I am filling a large sphere with non-overlapping smaller spheres at random positions by putting the placement of the G4Orbs in a loop and checking the overlap with CheckOverlaps(). If there is an overlap detected a new position is tried. But now I get a lot of warnings and it is driving me crazy. I already set the verbosity in CheckOverlaps() to false but without success. Can anyone help?
In case if your model consists only of spheres, then overlap check can be easily done without invoking the CheckOverlaps() function.
You should check that:
there is no overlap between “daughter” volumes
“daugther” volumes do not intersect the surface of the “mother” volume
In first case you should check that the distance between the centres of two spheres is more than sum of their radiuses:
(Ci - Ck).mag() > Ri + Rk
where (Ci,Ri) - the position and the radius of the sphere number i (Ck,Rk) - the position and the radius of the sphere number k
In the second case you should check that the distance to the centre of the mother sphere is less than difference between radiuses of the mother and the sphere in question:
Ci.mag() > R0 - Ri
where R0 is the radius of the mother sphere, the centre of the mother is in the origin
When the model will be completed, you can make additional check using the CheckOverlaps() function.
Below is an example of a function that adds a random position of a small sphere (radius r) inside bigger sphere (radius R0) to the vector of positions pos
G4bool addSphere(G4double R0, G4double r, std::vector<G4ThreeVector>& pos)
{
// check parameters
if (R0 <= 0. || r <= 0.) return false;
// generate new sphere (100k tries)
for (G4int i=0; i<100000; ++i)
{
// generate random position
G4double x = R0*(2.*G4UniformRand() - 1.);
G4double y = R0*(2.*G4UniformRand() - 1.);
G4double z = R0*(2.*G4UniformRand() - 1.);
G4ThreeVector p(x,y,z);
// Check that new sphere is inside mother
if (p.mag() >= R0 - r) continue; // next try
// Check that there is no overlap with other spheres
G4bool overlap = false;
G4int npos = pos.size();
for (G4int k=0; k<npos; ++k)
{
if ((pos[k] - p).mag() > (r + r)) continue;
overlap = true;
break;
}
if (overlap) continue; // next try
// add new position to the vector of positions
pos.push_back(p);
return true;
}
return false; // all tries failed
}
Perfect! Much cleaner than what I had written and faster as well. The radius of the smaller spheres slightly varies so I added another vector of radii in addition to the vector of positions. Works very well and most of all, no more overlap warnings (even when pSurfChk = true) .
Thank you very much