The messenger for materials and radius didn't work

Geant4 Version:11.1.1
Operating System:MacOS
Compiler/Version:clang 15.0.0
CMake Version: 3.26.5

Question

/NP/det/SetWorldMat G4_AIR

This mac didn’t work!

Code

1. DetectorConstruction

/*********************************************************
 * @function: DefineMaterials
 * @brief: Define the materials for AuNP , cell , world
*********************************************************/
void DetectorConstruction::DefineMaterials() {
    // World: Vacuum
    G4NistManager *nist_manager = G4NistManager::Instance();
    nist_manager->FindOrBuildMaterial("G4_Galactic");
    nist_manager->FindOrBuildMaterial("G4_AIR");

    // Cell
    nist_manager->FindOrBuildMaterial("G4_WATER");

    // nucleus
    nist_manager->BuildMaterialWithNewDensity("Nucleus", "G4_WATER", 1.74 * g/cm3);

    // AuNP
    nist_manager->FindOrBuildMaterial("G4_Au");   
}

void DetectorConstruction::SetWorldMaterial(G4String val) {
    G4Material *material = G4Material::GetMaterial(val);
    if(material) world_mat = material; 
    G4RunManager::GetRunManager()->PhysicsHasBeenModified(); 
}
DetectorConstruction::DetectorConstruction() : G4VUserDetectorConstruction(), 
    world_mat(nullptr), cell_mat(nullptr), nucleus_mat(nullptr), NP_mat(nullptr),
    cell_radius(15 * um), nucleus_radius(5.5 * um),
    addAuNP(false), number_of_NPs(0), radius_of_NPs(0.), dis_type("Uniform") { 
    radius_of_NPs = 15 * nm;
    number_of_NPs = 1000;
    DefineMaterials();
    SetCellMaterial("G4_WATER");
    SetNucleusMaterial("Nucleus");
    SetNPMaterial("G4_Au");
    det_messenger = std::make_unique<DetectorConstructionMessenger>(this); 
}

2. DetectorConstructionMessenger

DetectorConstructionMessenger::DetectorConstructionMessenger(DetectorConstruction *pDet) : G4UImessenger(), det(pDet) {
    NP_dir = std::make_unique<G4UIdirectory>("/NP/");
    NP_dir->SetGuidance("UI command specific to this Nano particle setup");

    det_dir = std::make_unique<G4UIdirectory>("/NP/det/");
    det_dir->SetGuidance("Detector construction commands");

    world_mat_cmd = std::make_unique<G4UIcmdWithAString>("/NP/det/SetWorldMat", this);
    world_mat_cmd->SetGuidance("Set World Material");
    world_mat_cmd->AvailableForStates(G4State_PreInit, G4State_Idle);
    world_mat_cmd->SetToBeBroadcasted(false);

    cell_mat_cmd = std::make_unique<G4UIcmdWithAString>("/NP/det/SetCellMat", this);
    cell_mat_cmd->SetGuidance("Set World Material");
    cell_mat_cmd->AvailableForStates(G4State_PreInit, G4State_Idle);
    cell_mat_cmd->SetToBeBroadcasted(false);

    add_NPs_cmd = std::make_unique<G4UIcmdWithABool>("/NP/det/addNP", this);
    add_NPs_cmd->SetGuidance("If add NPs");
    add_NPs_cmd->AvailableForStates(G4State_PreInit,G4State_Idle);
    add_NPs_cmd->SetToBeBroadcasted(false);

    NP_number_cmd = std::make_unique<G4UIcmdWithAnInteger>("/NP/det/SetN", this);
    NP_number_cmd->SetGuidance("Set Number of NPs");
    NP_number_cmd->SetParameterName("N", false);
    NP_number_cmd->SetRange("N>0");
    NP_number_cmd->AvailableForStates(G4State_PreInit,G4State_Idle);
    NP_number_cmd->SetToBeBroadcasted(false);

    NP_radius_cmd = std::make_unique<G4UIcmdWithADouble>("/NP/det/SetNPR",this);
    NP_radius_cmd->SetGuidance("Set radius of NPs");
    NP_radius_cmd->SetParameterName("Radius",false);
    NP_radius_cmd->SetRange("Radius>0.");
    NP_radius_cmd->AvailableForStates(G4State_PreInit,G4State_Idle);
    NP_radius_cmd->SetToBeBroadcasted(false);
}

DetectorConstructionMessenger::~DetectorConstructionMessenger() = default;

void DetectorConstructionMessenger::SetNewValue(G4UIcommand *command, G4String newValue) {
    if(command == world_mat_cmd.get()) {
        det->SetWorldMaterial(newValue);
    } 
    if(command == cell_mat_cmd.get()) {
        det->SetCellMaterial(newValue);
    }
    if(command == add_NPs_cmd.get()) {
        det->SetAddNP(add_NPs_cmd->GetNewBoolValue(newValue));
    }
    if(command == NP_number_cmd.get()) {
        det->SetNumberOfNP(NP_number_cmd->GetNewIntValue(newValue));
    }
    if(command == NP_radius_cmd.get()) {
        det->SetRadiusOfNP(NP_radius_cmd->GetNewDoubleValue(newValue));
    }
}

How to solve it?

Hi ! Have you tried using the method “GeometryHasBeenModified” instead of “PhysicsHasBeenModified” in your “SetWorldMaterial” method ?

Hi,

you may want to do as in this example,

void DetectorConstruction::SetDetectorThickness(G4double value)
{
  fDetectorThickness = value;
  G4RunManager::GetRunManager()->ReinitializeGeometry();
}

Best,
Alvaro

Is it better to use GeometryHasBeenModified() instead? Since ReinitializeGeometry() triggers a new call to Construct(), it seems to me that this would be expensive if the user has multiple macro commands to change different parameters. Wouldn’t you just want to tell the RunManager “something has change”, and let it do the rebuild at beamOn time?

Hi Michael,

I have changed the code to GeometryHasBeenModified(). This is my Debug information:

> lldb ./AuNP
(lldb) target create "./AuNP"
Current executable set to '/Users/zk/Desktop/Work/suda/doseEnhancement/version2/build/AuNP' (arm64).
(lldb) b DetectorConstruction::Print
Breakpoint 1: where = AuNP`DetectorConstruction::Print() + 24 at DetectorConstruction.cpp:138:5, address = 0x00000001000152cc
(lldb) r run.mac
Process 74379 launched: '/Users/zk/Desktop/Work/suda/doseEnhancement/version2/build/AuNP' (arm64)

**************************************************************
 Geant4 version Name: geant4-11-02-beta-01 [MT]   (30-June-2023)
  << in Multi-threaded mode >>
                       Copyright : Geant4 Collaboration
                      References : NIM A 506 (2003), 250-303
                                 : IEEE-TNS 53 (2006), 270-278
                                 : NIM A 835 (2016), 186-225
                             WWW : http://geant4.org/
**************************************************************

<<< Reference Physics List QBBC
Process 74379 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #0: 0x00000001000152cc AuNP`DetectorConstruction::Print(this=0x0000600001de8630) at DetectorConstruction.cpp:138:5
   135 	***********************************************************************************************************/
   136
   137 	void DetectorConstruction::Print() {
-> 138 	    G4cout << "----------------------------Detector Construction Parameters--------------------------" << G4endl;
   139 	    G4cout << "World Material is " << world_mat->GetName() << ":" << world_mat << G4endl;
   140 	    G4cout << G4endl;
   141 	    G4cout << "Cell Material is " << this->GetCellMaterial()->GetName() << ":" << this->GetCellMaterial() << G4endl;
Target 0: (AuNP) stopped.
(lldb) s
----------------------------Detector Construction Parameters--------------------------
Process 74379 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = step in
    frame #0: 0x00000001000152f0 AuNP`DetectorConstruction::Print(this=0x0000600001de8630) at DetectorConstruction.cpp:139:5
   136
   137 	void DetectorConstruction::Print() {
   138 	    G4cout << "----------------------------Detector Construction Parameters--------------------------" << G4endl;
-> 139 	    G4cout << "World Material is " << world_mat->GetName() << ":" << world_mat << G4endl;
   140 	    G4cout << G4endl;
   141 	    G4cout << "Cell Material is " << this->GetCellMaterial()->GetName() << ":" << this->GetCellMaterial() << G4endl;
   142 	    G4cout << G4endl;
Target 0: (AuNP) stopped.
(lldb) p world_mat->GetName()
(const G4String)  (std::__1::string = "G4_AIR")

And This is my mac

/NP/det/SetWorldMat G4_Galactic
/NP/det/addNP true
/NP/det/SetN  2000

/run/initialize
/tracking/verbose 1
/run/beamOn 1

How to solve it?
Best

I’m not sure it’s related to your problem but as far I know, this method doesn’t work in multithread mode. For changing a material in my simulation I use the “ReinitializeGeometry” method, it’s works pretty well.

For changing the geometry size, for my simulation I delete all pointers related to logical and physical volume before changing the size for the solid. After that I reconstruct logical and physical volume. Maybe not the most clever solution but I didn’t find anything better…

Can confirm, all my messengers which update geometry parameters (sizes, materials, limits, etc.) stopped working in Geant 4.11 (at least from a visual point of view, particles interact with updated geometry which is invisible).

When I am building my project with a Geant4 version older than 10.7.p3, it works fine, in multithreaded mode as well.

Possibly it’s related to the new logic of how RunManager distributes tasks between threads.