Need advice how to create Hexagonal prism

Good morning,

@weller, a solution is easier - just use odd/even number of hexagons per set (see below)

@Helen23, you are progressing well! Let make yet another step. Please make little rearrangement of the code, namely place

G4int nhex = 10;
G4double d = SizeXY/nhex;
G4double r = d/std::sqrt(3.);
G4double dR = 0.9*r; 

just before the code, where you create a solid for hexagon.

The calls to PlaceHexagons() after that should look like the following:

PlaceHexagons(d,  -3.*r, nhex,   logicHexagon, logicLV);
PlaceHexagons(d, -1.5*r, nhex-1, logicHexagon, logicLV);
PlaceHexagons(d,   0.*r, nhex,   logicHexagon, logicLV);
PlaceHexagons(d,  1.5*r, nhex-1, logicHexagon, logicLV);
PlaceHexagons(d,   3.*r, nhex,   logicHexagon, logicLV);
2 Likes

Dear Evc and weller,

perfect thank you a lot!!! I finally did it thanks to you!

But I would like to ask finally one last thing… how can I have an id for each hexagon? I would like to find after I run the simulation specific details for each hexagon… With replica specific id is given automatically but now since I placed it with for loop I guess I have to find a way to id them?

thank you
Helen

You can assign to the hexagons different copy numbers:

static G4int id = 0;
bool checkOverlaps = true;
  for (int i=0; i<nhex; ++i) {
    G4ThreeVector pos(xc, d*(i - (nhex-1)*0.5), 0.);
    new G4PVPlacement(0,              // no rotation                                                                    
                      pos,            // position                                                                       
                      logHexagon,     // logical volume                                                                 
                      "Hexagon",      // its name                                                                       
                      logMother,      // its mother  volume                                                             
                      false,          // no boolean operation                                                           
                      id++,           // copy number                                                                    
                      checkOverlaps); //overlaps checking
  }

Ok perfect! thank you for one more time!

But the copy id corresponds to only 1 id of each hexagon (i.e. 1, 2, 3, 4, 5 etc)? So it is an array?

Is there a way to have in each hexagon (x,y) position so we can have a matrix?

Thank you
Helen

No, but you can get that from the placement itself: In your stepping action, you have access to the G4Step. Get the G4Touchable from the post-step point, and from that get the placement transform. You can then query the transform for the position of the center of the volume.

For the details of how to write the code, you can look at existing examples as well as both the Developer’s Guide and the class .hh files.

You can create a vector of hexagon positions. For that it will require to add an additional parameter in PlaceHexagons().

void PlaceHexagons(double d, double xc, double yc, int nhex, G4LogicalVolume* logHexagon,  G4LogicalVolume* logMother, std::vector<G4TwoVector>& positions)
{
  static G4int id = 0;
  bool checkOverlaps = true;
  for (int i=0; i<nhex; ++i) {
    G4double x = xc;
    G4double y = d*(i - (nhex-1)*0.5);
    positions.push_back(G4TwoVector(x, y));
    new G4PVPlacement(0,              // no rotation                                                                    
                      G4ThreeVector(x, y, 0.),  // position                                                                       
                      logHexagon,     // logical volume                                                                 
                      "Hexagon",      // its name                                                                       
                      logMother,      // its mother  volume                                                             
                      false,          // no boolean operation                                                           
                      id++,           // copy number                                                                    
                      checkOverlaps); //overlaps checking                                                               
  }
}
1 Like

Dear Evc,

Thank you a lot once more for your time.

But if I write it like this, then how I will call the function instead of this:

PlaceHexagons(d,  -3.*r, nhex,   logicHexagon, logicLV)

?

What I will have to add to yc and to

std::vector<G4TwoVector>& positions

?
Thank you a lot again I deeply appreciate your help.

Best
Helen

Dear Helen,

The parameter yc was added to the definition of the function by mistake, the correct definition is as follows:

void PlaceHexagons(double d, double xc, int nhex, G4LogicalVolume* logHexagon,  G4LogicalVolume* logMother, std::vector<G4TwoVector>& positions)

positions is an output vector of (x,y) positions, you should declare it before to call PlaceHexagons():

std::vector<G4TwoVector> positions;
PlaceHexagons(d,  -3.*r, nhex,  logicHexagon, logicLV, positions);

Hello Evc,

Thank you a lot for your answer. Now everything looks ok. But one finally last question.

Since we make placement of the volumes: Is this optimal? Will it work for instance for 2000x2000 hexagones and more?
I tried to run with only 100x100 and it takes a lot of time… Will I have to find eventually a totally different way to create the hexagons (i.e. with replica) if I want to make so many?

Thanks once again
Helen

Doing individual placements for this kind of layout definitely doesn’t scale. Each placement occupies memory, and you’ll eventually blow away your system. I would strongly recommend either a replica or a Parametrised placement. It’s quite simple to write, and you’ve already got the hard part (the math for each hexagon position) done.

I have no experience with replicas and I may be wrong, but applying replica in your case does not seam easy. The Geant4 documentation says:

G4PVReplica represents nReplicas volumes differing only in their positioning, and completely filling the containing mother volume. Consequently if a G4PVReplica is ‘positioned’ inside a given mother it MUST be the mother’s only daughter volume. Replica’s correspond to divisions or slices that completely fill the mother volume and have no offsets. For Cartesian axes, slices are considered perpendicular to the axis of replication.

So, to fill the mother volume (which is a box) using replica, it will need first to construct a volume like below:

hexagon_replica

Relative to the performance of your program. It is not clear what is slow, the time of the geometry construction or running the simulation itself. I guess the first one, and the reason is the overlap check. To fix the issue just set

bool checkOverlaps = false;
1 Like

Hello mkelsey,

As evc wrote to do a replica in the geometry I want is also not possible since i would like a geometry like in the figure below.
With the replica it will not be fulled completely.
Do you think that parametrised placement would work for this kind of geometry?
Thank you Helen

Hello Evc,
thank you a lot for your answer again.
Yes I agree with you. I searched it and I also think that I cannot use replica for this and it will not fill the space properly.

I have already added the

bool checkOverlaps = false;

Is it even possible to create the geometry of your figure?

Thank you once more
Helen

The volume on the picture consist of 7 solids, one full hexagon and 6 half hexagons. All these solids can be defined as G4ExtrudedSolid.

Ok perfect thank you. But is it possible to id them? at least to give an id to the half hexagon?

And for the half hexagon i can process the code for the hexagon from extruded solid?

Thank you
Helen

An id can be assign to the volume using the copy number parameter. Then combining this id with the id of the mother volume it will be possible to identify the hexagon where the point is located.

Sure. The code for a hexagon calculates six points which then can used to set up the vertices of the half hexagon.

Yes, I am certain that parameterised placement will work for this. In our experiment, we have cylindrical detectors which have tiny sensors (superconducting aluminum pads) placed all over the top and bottom faces (nearly 11,000 of them in one case!).

I use a G4PVParameterised placement, passing in a single G4LV corresponding to one pad, and a G4VPVParameterisation subclass which computes the position and orientation of each pad given the copy number.

Here’s what one of our detector faces looks like. Each of those little white blobs is a sensor pad. The whole pattern is the G4PVParametrised.

1 Like