Simulation crash problem

Hi,
I am to simulate a lightguide which will have coating. One of the designs I am to implement is that of a trapezoid using G4Trd. First I create the correct sized solid for the wrapping and the lightguide. Then the bigger side of the lightguide is joined to a G4Box with similar sized sided. The joined solid is subtracted from the wrapping. This is done in order to not leave any small residues at the border if only the lightguide solid itself were to be subtracted from the wrapping. After this first subtraction of the wrapping, another subtraction is made to the smaller end, again to remove any possible leftovers of the boundary. The code is provided below:

 G4Trd* solidLightguideWrappingPre = new G4Trd(
          "solidLightguideWrappingPre",
          width_lightguide+thick_wrapping,
          endWidth_lightguide+thick_wrapping,
          height_lightguide+thick_wrapping,
          endHeight_lightguide+thick_wrapping,
          length_lightguide);

  G4Trd* solidLightguide = new G4Trd(
          "solidLightguide",
          width_lightguide,
          endWidth_lightguide,
          height_lightguide,
          endHeight_lightguide,
          length_lightguide);

  G4Box* solidLightguideCutBox = new G4Box(
          "solidLightguideCutBox",
          width_lightguide,
          height_lightguide,
          1*Units::cm);

  G4Box* solidLightguideCutBox2 = new G4Box(
          "solidLightguideCutBox2",
          endWidth_lightguide,
          endHeight_lightguide,
          1*Units::cm);

  G4UnionSolid* solidLightguideCutPre2 = new G4UnionSolid(
          "solidLightguideCutPre2",
          solidLightguide,
          solidLightguideCutBox,
          0,
          G4ThreeVector(0,0,-(length_lightguide+1*Units::cm)));

 G4SubtractionSolid* solidLightguideWrappingPre2 = new G4SubtractionSolid(
          "solidLightguideWrappingPre2",
          solidLightguideWrappingPre,
          solidLightguideCutPre2,
          0,
          G4ThreeVector(0,0,0));
  
  G4SubtractionSolid* solidLightguideWrapping = new G4SubtractionSolid(
          "solidLightguideWrapping",
          solidLightguideWrappingPre2,
          solidLightguideCutBox2,
          0,
          G4ThreeVector(0,0,length_lightguide+0.9*Units::cm));

  G4LogicalVolume* logicLightguideWrapping = new G4LogicalVolume(
          solidLightguideWrapping,
          mat_wrapping_opt,
          "logicLightguideWrapping");
  
  auto lightguideWrappingVol=new G4PVPlacement(
          0,
          G4ThreeVector(0,0,length_lightguide+displacement),
          logicLightguideWrapping,
          "lightguideWrapping",
          lvWorld,false,0,true);

  G4LogicalVolume* logicLightguide = new G4LogicalVolume(
          solidLightguide,
          mat_lightguide_opt,
          "logicLightguide");
  
  auto lightguideVol=new G4PVPlacement(
          0,
          G4ThreeVector(0,0,length_lightguide+displacement),
          logicLightguide,
          "lightguide",lvWorld,false,0,true);

The following variables are used (mm):
width_lightguide=100,
height_lightguide=150,
length_lightguide=200
thick_wrapping=0.01

When endWidth_lightguide<=1.31 or endHeight_lightguide<=1.47 the startup of the simulation is stopped with:
“RuntimeError: G4OSG::g4solid2Geometry error : GetPolyhedron on solid returns null ptr (polyhedronisation not available?)”

One of the additional printouts highlights the problematic solid:
"Viewer ERROR: Could not get polyhedron from the following solid:

*** Dump for Boolean solid - solidLightguideWrapping ***"

How can this problem be solved?

This is curious. There is no such class or error message in Geant4 source. Are you using some sort of wrapper?

Anyway, in standard Geant4, which uses BooleanProcessor, sometimes the “polyhedronisation” of Boolean solids fails (it’s a computationally tough problem). Sometimes a small tweak in position solves it. Avoid coincident surfaces (e.g., make the subtracting solid bigger).

polyhedronisation is only used for visualisation. It does not affect the tracking. In standard Geant4, if polyhedronisation fails, it draws the solid in “cloud” style. It seems your wrapper intercepts the problem before the standard graphics system can solve it.

Thanks for your reply!

I realised after I posted that one of the printouts I supplied includes “G4OSG”. This should be related to the viewer (Open Scene Graph) used with the ESS Framework of Geant4.

What you wrote about polyhedronisation used only for visualisation made me try to launch the simulation with the same parameters causing a crash, but without the graphical viewer. As one would expect from your explanation, no problem is reported. So, if I don’t misunderstand you, that means that the geometry is correct in the actual simulation?

Interesting, by “coincident” surfaces, do you mean just touching not going into one another? By changing the z-positioning of the G4UnionSolid solidLightguideCutPre2 into -(length_lightguide+0.5*Units::cm) the viewer starts. However, this does of course change my geometry in a way not intended. Is there any other smart way of hollowing out a G4Trd?

Ah! Interesting. Let’s get together and bring the OSG driver into G4. Are you the developer?

Still somewhat puzzled. The “standard graphics system” solves the null polyhedron problem at a low (I mean, base class) level, so does OSG by-pass this? What version of Geant4 are you using?

You are right, the tracking should be OK. As you say, “the geometry is correct in the actual simulation”.

By coincident surfaces I meant coincident in both position and orientation.

Changing your geometry by just a nanometer or micrometre might be enough (length_lightguide+0.5*Units::um). “Units” - is that another ESS thing? In standard G4 it’s CLHEP::um - or if you #include "G4SystemOfUnits.hh", just um.

Not looked in detail at your geometry, but a volume can be “hollowed out” simply by placing a “daughter” volume. The daughter replaces the mother’s material. That’s a basic in Geant4 (and GEANT3,…)

Hope this helps.

Sorry for the late reply, I’ve been off for some days.

I run geant4-10-04-patch-03. I am not the developer, but I could probably get you in contact with someone. Regarding the “Units”, unfortunately not entirely sure, it was the way I was taught. But, as you say, it is possible to do without.

Yes, the daughter placement would perhaps be the better alternative. I did not use it because I was unsure about one thing. If I place a daughter volume with smaller radius, but same length, inside the G4Trd, does it still hollow out entirely at the bottom and top?

This highlights (hopefully!) what I was trying to convey with my question. And as a bonus you get to see the viewer I talked about :).

The purple volume represents the daughter volume (i.e., the lightguide). You can see two dots, one red and one blue. One of them is placed on the surface of the bottom of this G4Trd. The other dot is placed on the surface of the bottom of the mother volume, i.e. the lightguideWrapping. The measurement between these surfaces planes is 19.35 fm according to the printout.

So, since the two volumes are defined with two different materials, will this “left-over” reflect introduce a problem when light go from air into that surface? Or is there some built in safeguard in Geant4 which deals with this?

That is quite an old version - 2017? I think.

You must always use units of some sort - CLHEP::um or just um is usual. Maybe, in your case, Units is a synonym for CLHEP.

A daughter replaces the material of the mother. It must not overlap the mother. (You can check that at the point of creation (see G4PVPlacement(...,G4bool pSurfChk)) or with /geometry/test (see guidance thereof (with the help command) and of related commands.)

Regarding the rest of you questions, it’s not easy for me to check. It’s up to you to check with debug and/or visualisation, given the mother-daughter properties above.

That is quite an old version - 2017? I think.<

Patch 3 is from 2019 though. I guess that might be the tradeoff you sometimes have to do when you work with a framework.

You must always use units of some sort - CLHEP::um or just um is usual. Maybe, in your case, Units is a synonym for CLHEP.<

Yes, I meant without “*Units::um” and only using “*um”.

Thanks for your input regarding mother/daughter volumes. I am quite familiar with those and use the “G4bool pSurfChk” set to true as a standard. It is just this “edge” issue that concerns me, when the daughter volume is placed so that it touches one (or more) outer surfaces of the mother volume (without protruding). My question is really if such a placement will replace the material of the mother volume completely so that the material surrounding the mother volume (e.g. vacuum) is in contact with the daughter volume at that side? (Sorry if I repeat myself, just trying to make sure I understand things correcty).

I did a small test of 1 million events (optical photons) for the “cut-out case” and the “mother/daughter case”. At a detection surface at the end of the lightguide, almost 20000 photons were detected. The difference in the number of counts between the two cases was around 1 %.

Thanks for you input!
Cheers,
Markus

There will always be two surfaces to navigate, even if they are notionally coincident. Geant4 has the concept of surface tolerance, which allows it to navigate such situations, and I guess there will be some uncertainty due to computational rounding errors, etc., about which “next volume” a particle finishes up in. We recommend users avoid coincident surfaces, but Geant4 normally copes well anyway. Normally this doesn’t matter - it does not affect tracking and particle interactions - but optical photons are unusual in that processes happen at the surface, so it matters which surface it finds. If you want the optical photon to reflect/refract/scatter of what we are calling the daughter, then perhaps it should not be a daughter. You could make a daughter-sized hole in the Trd with a Boolean operation, and place the “daughter” in it at the same level, i.e., not as a daughter of the Trd but a daughter of the surrounding vacuum. And maybe allow a micrometre or two between it and the Trd (which would be there in practice anyway).

1 Like

Thanks a lot for that clarification Allison!
Seems like it makes sense to continue with the boolean operations.
Cheers,
Markus