Read a new Gdml file Between Runs

Dear Geant4 Experts:
I am trying to read the new gdml file through the method below. But when i call this method through user defined command, I got warning saying duplicate material definition and the geometry is not changed. What is the correct way ?

void NeutronSimDetectorConstruction::SetGdml(const G4String& s){
    std::ifstream f(s.data());
    if(f.good()){
        fParser.Clear();
        fParser.Read(s);
        G4RunManager::GetRunManager()->GeometryHasBeenModified();
        G4UImanager* ui = G4UImanager::GetUIpointer();
        if(ui){
            ui->ApplyCommand("/vis/drawVolume");
            ui->ApplyCommand("/vis/viewer/refresh");
        }
    }
    else G4cout << s <<" Doesn't Exist!"<<G4endl;
}

The duplicate material definition should be benign, so long as both your GDML files use the same name for the same actual material (density, composition, etc.). If you change what “aluminum” actually means between the two files, that’s not going to work.

The GeometryHasBeenModified() call only sets a flag; it doesn’t build the new geometry until /run/initialize, so in your code above, the old geometry is still built at the point where you call /vis/drawVolume. You can trigger the building yourself by adding the line

G4RunManager::GetRunManager()->InitializeGeometry();

mkelsey, Thanks for your reply. That should be the solution.
But I encounter this exception later, saying the old sd object should be deleted.

-------- WWWW ------- G4Exception-START -------- WWWW -------
*** G4Exception : DET1010
      issued by : G4SDStructure::AddNewDetector()
Tracker had already been stored in /. Object pointer is overwitten.
It's users' responsibility to delete the old sensitive detector object.
*** This is just a warning message. ***
-------- WWWW -------- G4Exception-END --------- WWWW -------

I tried to delete the object like below, but it doesn’t work.

delete G4SDManager::GetSDMpointer()->FindSensitiveDetector("Tracker");

By the way, the duplicate warning seems can be solved by calling

G4Material::GetMaterialTable()->clear()

How to delete a Registered Sensitive detector?

I am not sure how to deal with this properly when re-reading a GDML geometry. In our framework, we build the geometry in C++, using macro commands to allow the user to choose the geometry configuration dynamically. In our code, we have the ConstructSDandField() function that can call down to the individual components.

At the level where an SD should be created, we call G4SDManager::FindSensitiveDetector("name",false), which either returns a pointer for the already existing SD, or null, in which case we create and register a new SD.

I don’t see a way to deregister an SD from the manager. Once registered, they seem to persist for the whole job.