Nanoparticle distribution


I am trying to distribute nanoparticles by volume. I use the function G4VPVParameterisation ().

As a result, it was possible to distribute nanoparticles along the X and Y coordinates, I can’t distribute the nanoparticles of the Z coordinates.

Can someone help me?

: G4VPVParameterisation()
for (auto copyNo=0; copyNo<kNofEmCells; copyNo++) {
auto column = copyNo / kNofEmRows ;
auto row = copyNo % kNofEmRows;

// регулировать расположение точек по Х и У
fXCell[copyNo] = (column-1)1mm -1.*mm;
fYCell[copyNo] = (row-1)1mm - 1.*mm;}}


void AgParameterisation::ComputeTransformation(
const G4int copyNo,G4VPhysicalVolume *physVol) const


// copy Au
// задаем размеры наночастицы
G4Sphere *nAu2 = new G4Sphere(“nAu2”,
0 * cm,
0.1 * mm,
0. * deg,
360. * deg,
0. * deg,
360. * deg);

G4LogicalVolume *LnAu2= new G4LogicalVolume(nAu, Mat(“G4_Au”), “nAu”);

G4VPVParameterisation* AuParam = new AuParameterisation();
new G4PVParameterised(“cellPhysical”,LnAu,LDetPhBox,


Dear I got your question is very interesting, have you got an idea how to distribute the NPs in 3D (volume) uniformly? I tried by the problem of overlap.

Nanoparticles can be generated without use of G4PVParameterised. Just generate points inside a bounding box of the volume where the nanoparticles supposed to be, and select only those points which are inside the solid.

Тo avoid clashes with other nanoparticles, you will also need to calculate the distances to the already selected points.

Yes, dear I try to distribute without G4PVParameterised but I faced the problem of overlap since my NPs about 5e^12. My challenge how I can distribute in a volume of 2cm x 2cm x 2cm cube as shown below. Would you please explain this “Just generate points inside a bounding box of the volume where the nanoparticles supposed to be, and select only those points which are inside the solid.”
G4Box* fabsorb = new G4Box(“fabsorb”, 1cm, 1cm, 1*cm);

G4LogicalVolume* logicAbsorb = new G4LogicalVolume(absorb, world_mat, “logicAbsorb”);

G4VPhysicalVolume* physAbsorb = new G4PVPlacement(0, G4ThreeVector(0, 2*cm, 0), logicAbsorb, “physAbsorb”, logicPhantom, false, 0, checkOverlaps);

Below is an example of how to generate one hundred small spheres randomly distributed inside a cylinder:

 constexpr G4int NP = 100;        // number of spheres                                                                  
 constexpr G4double r = 0.5*cm;   // radius of a sphere                                                                 
 constexpr G4double DMIN = 3*r;   // min distance between two spheres                                                   
 constexpr G4double Rcyl = 10*cm; // radius of the cylinder                                                             
 constexpr G4double Zcyl = 20*cm; // half length of the cylinder                                                        

 // create a logical volumes for cylinder                                                                               
 G4Material* cyl_material = nist->FindOrBuildMaterial("G4_WATER");
 G4Tubs* cylinder =
   new G4Tubs("Cylinder", 0., Rcyl, Zcyl, 0., CLHEP::twopi);
 G4LogicalVolume* cyl_logical =
   new G4LogicalVolume(cylinder, cyl_material, "Cylinder");

 // generate positions inside cylinder                                                                                  
 G4ThreeVector bmin, bmax;
 cylinder->BoundingLimits(bmin, bmax); // get bounding box of the cylinder                                              
 std::vector<G4ThreeVector> position;
 while (position.size() < NP) {
   G4double x = bmin.x() + (bmax.x() - bmin.x())*G4UniformRand();
   G4double y = bmin.y() + (bmax.y() - bmin.y())*G4UniformRand();
   G4double z = bmin.z() + (bmax.z() - bmin.z())*G4UniformRand();
   G4ThreeVector p(x, y, z);
   // check position                                                                                                    
   if (cylinder->Inside(p) != kInside) continue;
   if (cylinder->DistanceToOut(p) < 0.5*DMIN) continue;
   G4int size = position.size();
   G4int k = 0;
   for ( ; k < size; ++k) {
     if ((position[k] - p).mag() < DMIN) break;
   if (k == size) position.push_back(p); // add position to the list                                                    

 // create a logical volume for spheres                                                                                 
 G4Material* sph_material = nist->FindOrBuildMaterial("G4_AU");
 G4Orb* sphere = new G4Orb("Sphere", r);
 G4LogicalVolume* sph_logical =
   new G4LogicalVolume(sphere,sph_material,"Sphere");

 // create physical volumes for spheres                                                                                 
 for (G4int i = 0; i < NP; ++i) {
   new G4PVPlacement(0, position[i], sph_logical, "Partical", cyl_logical,
                     false, 0, checkOverlaps);

 // create physical volume for cylinder                                                                                 
 new G4PVPlacement(0, G4ThreeVector(), cyl_logical, "Cylinder", logicWorld,
                   false, 0, checkOverlaps);

1 Like

Thank you very much dear!

Dear, depending your recommendation and suggestion I distribute the Nanoparticles and works well, but as the number of Nanoparticles increases the Geometry didn’t open. however it gives result with
WARNING: Trajectory storing has been requested. This action may be

  • reversed with “/tracking/storeTrajectory 0”.*
    WARNING: The vis manager will keep up to 100 events.
  • This may use a lot of memory.*
  • It may be changed with, e.g., “/vis/scene/endOfEventAction accumulate 10”.*
  • Changing export format to “jpg”*
    You may need to issue “/vis/viewer/update”.
    would you please specify the reason why it so?

This warning message is related to visualisation. Graphic mode is useful at initial steps to check that the model is set correctly. To run a production in graphic mode is not a good idea - this is the meaning of the warning.

Example B1 can be run in a batch mode without graphics, please see run1.mac, run2.mac

Thank you a lot once again Dear!

Dear evc
I face a challenge in running the code, start with the batch mode with the command below

/score/create/cylindericalMesh BM

the voxels are 2 mm wide.

/score/mesh/cylindericalSize 3.25. 7.5. cm
/score/mesh/nBin 37 70 70
/score/quantity/doseDeposit dose

and show with the error as shown below in the snapshot.

Would you please give me a hint where I made the mistake?

I am not an expert in scoring, however I would advise you to check the spelling of the commands, namely cylindrical instead of cylinderical

Dear evc, depending on your sampled code to distribute the Nano particles inters of G4int NP =,

Dear evc, how are you doing? depending on your sample code I distributed the nano particles using G4double =; rather than G4int =; as shown below. I try to run with 1*10^8 histories and it is run. Now spent at least 7 days but still it in check of geometry. I scared may be I make a mistake, it takes this much of days to check the geometry?

Thank you

Value 1.8x10^10 is too big for int, you should use long int. However, the real problem is the number of nanoparticles, it is really huge. Just to fill std::vector with positions, it should take 180x3x8 = 4320 Gb of memory. I doubt that it can be simulated.

Please consider a significant (>1000 times) reduction in the number of nanoparticles.

Thank you very much dear, yes for sure it is very huge number. First I was propose to simulate the Nano particles in a solution form but I could`t get an option that gives to me a clue how to distribute the NPs interns of concentration. Then what I did was, converting the solution in to the number of NPs. That is 18mg/g of gold NPs concentration is the same with 1.8*10^10 Au NPs.