I am trying to put a pyramid on a cube. I would like to create G4Union solid by merging these two. However (as I was warned in the manual), this is creating some glitchy situations, due to a fictional surface existing between the pyramid and the cube.
The most obvious example is the DistanceToOut() method for the solid returning me the distance to the surface shared by the two original solids (cube and pyramid).
Is there any way to create this solid in a sensible way?
In this particular case you can use G4Polyhedra.
Unfortunately I presented a too basic example for my actual application. In reality I want to stick several pyramids on the face of the cube to simulate a rough surface, with no symmetry, so I am not sure I could make G4Polyhedra work.
If you can build the union volume with the cube’s surface as a Cartesian plane (e.g., the +Z surface), you can most easily minimize the “roundoff gaps” problem. Create your pyramids just slightly larger (by a micron or so) than you really want them. Put them into the union with a Z placement that same micron or so below where you really want them; that gets the pyramid base embedded below the top of the cube, and the union won’t see any gaps.
The tolerance parameter for G4 to identify surfaces as separate is 1e-9 mm (1 pm), so a 1 um overlap is easily large enough to compensate.
Also, for your actual application, I strongly recommend
G4MultiUnion. That will give you a single-depth boolean solid, rather than a deep cascade of (((((((cube + pyramid) + pyramid) + pyramid) + pyramid) + … ). The later really messes with G4 at initialization and visualization time.
You can also consider an option to keep the cube and the pyramids as a separate objects. From simulation point of view the results will be similar, but the execution will be faster.
Thank you for your suggestions! The volumes were actually initially separated. The only reason I decided to merge them was to take advantage of the DistanceToOut() method.
I intend infact to generate primaries inside the merged volumes but only at a certain distance from each surface of the merged volume.
However I am not sure if I would need to completely reevaluate this approach. Even in the most basic examples I see the DistanceToOut() method not working correctly with G4MultiUnion (I might be executing it incorrectly though). Is the DistanceToOut() method correctly evaluating the normal for this type of boolean solid?
Sorry, I will be a bit more clear, this occurs:
As you can see the points that should be <1mm away from the surface appear at the union of the two solids.
In this case I created this with G4MultiUnion and moved the pyramid a bit back (there’s a very small overlap, of few cm, between cube and pyramid base which have 10m width dimensions), but I still see this weird effect.
P.S:. I rotated the solid in 3d, they do occur at the center and more than 1mm away from any allowed surface.
I would suggest to introduce inside the cube and the pyramids auxiliary daughter volumes to create a gap of 1mm where it is necessary. In such case primaries should be generated only in the points that are outside daughters but inside mother volumes.