How can I make Geant abort the simulation when there is an overlap of volumes (G4Exception)?

Hi there,

I have MC simulation batches that run for hours or days, although there are warnings like the following at the very beginning when constructing the geometry:

Checking overlaps for volume Tankwall:0 (G4Tubs) ... 
-------- WWWW ------- G4Exception-START -------- WWWW -------
*** G4Exception : GeomVol1002
      issued by : G4PVPlacement::CheckOverlaps()
Overlap with volume already placed !
          Overlap is detected for volume Tankwall:0 (G4Tubs) with Detector0:100000 (G4Tubs)
          overlap at local point (-86.2826,-53.5501,-57.493) by 450.487 um  (max of 1 cases)
NOTE: Reached maximum fixed number -1- of overlaps reports for this volume !
*** This is just a warning message. ***
-------- WWWW -------- G4Exception-END --------- WWWW -------

Why does Geant consider these exceptions as mere warnings and continue with the simulation?

I want Geant to actually throw that exception, so that I can catch it and abort the simulation, instead of wasting hours of simulation time on a non-sense geometry.

How can I achieve that?

Dear Joerg,

I suggest you to check geometry overlapping when you place the geometry in ‘DetectionConstruction.cc’.

For example,

#include “G4RunManager.hh”

G4RunManager* runManager = G4RunManager::GetRunManager();
G4VPhysicalVolume*
pGeo = new G4PVPlacement(0, //no rotation
G4ThreeVector(0.,0.,0.), //at (0,0,0)
fLogical, //logical volume
“World”, //name
0, //mother volume
false, //no boolean operation
0);

if(pGeo->CheckOverlaps()==True) runManager-> AbortRun();

I think there may have error but you can fix it!

Best regards,
Jaeyoung Jeong

Thank you.
Would G4PVPlacement::CheckOverlaps() also generate the console output?

Is there a way to actually make Geant THROW the G4Exception? That would be easier for our setup, since the Exception would contain the detailed error message about what went wrong in the geometry.

Also your suggestion means that the overlap has to be computed twice. Once internally by Geant and once by me manually. This seems to be unnecessary overhead.

How about write a new “G4PVPlacement.cc”?

In G4PVPlacement::CheckOverlaps() function, it calls G4Exception class like below.

G4Exception(“G4PVPlacement::CheckOverlaps()”, “GeomVol1002”, JustWarning, message);

Then, you can write exact same G4PVPlacement.cc but with a different level of severity in the above code line.

G4Exception(“G4PVPlacement::CheckOverlaps()”, “GeomVol1002”, RunMustBeAborted, message);

G4PVPlacement::CheckOverlaps() is the method which will be in invoked by the G4PVPlacement contructor if the overlap check is requested. You can switch off the overlap check by setting the last parameter in the G4PVPlacement constructor equal to false (btw, pSurfChk = false is the default).

The overlap check, in case if it is requested, is done at the initialisation time, when the geometry model is constructed. It is assumed that the overlap check is used for checking geometry correctness. If you are happy with the geometry, then you can switch it off.

BTW, in your case the overlap is very tiny, and very probably will not affect the result of simulation.

G4PVPlacement::CheckOverlaps() returns true if an overlap detected, false otherwise. So, instead of asking G4PVPlacement to perform the check, you can call CheckOverlaps() explicitly and stop the execution of the program in case of overlap.

Thank you for your answer. I will look into this.
However, due to our software architecture, I will probably not be able to call CheckOverlaps() explicitly, because the geometry construction and placement is abstracted away in some software component.

It would really be helpful if Geant had a global setting that makes the G4PVPlacement throw the G4Exception properly. In fact, I would like Geant to throw ALL G4Exceptions and not swallow any of them.

Just to be a bit more clear what I mean:

G4bool checkOverlaps = true;
...
G4PVPlacement* physVolume = new G4PVPlacement(..., false);
if (checkOverlaps)
{
  if (physVolume->CheckOverlaps()) ... // stop execution
}

You can customise the behaviour of G4Exception by implementing your own exception handler derived from G4VExceptionHandler and registering it to the G4StateManager before G4RunManager is created in your application.
You just need to implement the Notify virtual method of the handler and define the behaviour you want.

@evc and @gcosmo thanks for your advices. I will look into both solutions.

@gcosmo is there any documentation, tutorial, example or code snippet about using G4VExceptionHandler?

There’s no explicit documentation on that and I agree it should be added…
The mechanism is anyhow simple, here you find the definition of the base class G4VExceptionHandler:

https://geant4.kek.jp/lxr/source//global/management/include/G4VExceptionHandler.hh

For a concrete implementation of it, you can look at default exception handler:

https://geant4.kek.jp/lxr/source//run/include/G4ExceptionHandler.hh
https://geant4.kek.jp/lxr/source//run/src/G4ExceptionHandler.cc

Your custom handler could have a Notify method like this:

G4bool ExceptionHandler::Notify(const char* origin, const char* code,
                                G4ExceptionSeverity sev, const char* des)
{
  // Enable diagnostics from default handler
  G4ExceptionHandler defaultHandler;
  defaultHandler.Notify(origin, code, sev, des);

  // Add here whatever... throw... etc...

  // Returning true will force abort
  return true;
}

You will then register your custom handler in your main() before creating the run-manager:

G4StateManager::GetStateManager()->SetExceptionHandler(new ExceptionHandler());

Thanks, I will give it a go.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.