Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/run/include/G4AdjointSimManager.hh

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  1 //
  2 // ********************************************************************
  3 // * License and Disclaimer                                           *
  4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.                             *
 10 // *                                                                  *
 11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                                                  *
 18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // ********************************************************************
 25 //
 26 // G4AdjointSimManager
 27 //
 28 // Class description:
 29 //
 30 // This class represents the Manager of an adjoint/reverse MC simulation.
 31 // An adjoint run is divided in a serie of alternative adjoint and forward
 32 // tracking of adjoint and normal particles.
 33 //
 34 //   Reverse tracking phase:
 35 //   -----------------------
 36 // An adjoint particle of a given type  (adjoint_e-, adjoint_gamma,...) is
 37 // first generated on the so called adjoint source with a random energy (1/E
 38 // distribution) and direction. The adjoint source is the external surface
 39 // of a user defined volume or of a user defined sphere. The adjoint source
 40 // should contain one or several sensitive volumes and should be small compared
 41 // to the entire geometry. The user can set the min and max energy of the
 42 // adjoint source. After its generation the adjoint primary  particle is tracked
 43 // bacward in the geometry till a user  defined external surface (spherical or
 44 // boundary of a volume) or is killed before if it reaches a user defined
 45 // upper energy limit that represents the maximum energy of the external
 46 // source. During the reverse tracking, reverse processes take place where
 47 // the adjoint particle being tracked can be either scattered or transformed
 48 // in another type of adjoint paticle. During the reverse tracking the
 49 // G4SimulationManager replaces the user defined Primary, Run, ... actions, by
 50 // its own actions.
 51 //
 52 //   Forward tracking phase
 53 //   -----------------------
 54 // When an adjoint particle reaches the external surface its weight,type,
 55 // position, and directions are registered and a normal primary particle
 56 // with a type equivalent to the last generated primary adjoint is generated
 57 // with the same energy, position but opposite direction and is tracked
 58 // normally in the sensitive region as in a fwd MC simulation. During this
 59 // forward tracking phase the event, stacking, stepping, tracking actions
 60 // defined by the user for its general fwd application are used. By this clear
 61 // separation between adjoint and fwd tracking phases, the code of the user
 62 // developed for a fwd simulation should be only slightly modified to adapt it
 63 // for an adjoint simulation. Indeed  the computation of the signal is done by
 64 // the same actions or classes that the one used in the fwd simulation mode.
 65 //
 66 //   Modification to bring in an existing G4 application to use the ReverseMC
 67 //   ------------------------------------------------------------------------
 68 // In order to be able to use the ReverseMC method in his simulation, the
 69 // user should modify its code as such:
 70 //  1) Adapt its physics list to use ReverseProcesses for adjoint particles.
 71 //     An example of such physics list is provided in an extended example.
 72 //  2) Create an instance of G4AdjointSimManager somewhere in the main code.
 73 //  3) Modify the analysis part of the code to normalise the signal computed
 74 //     during the fwd phase to the weight of the last adjoint particle that
 75 //     reaches the external surface. This is done by using the following
 76 //     method of G4AdjointSimManager:
 77 //
 78 //     G4int GetIDOfLastAdjParticleReachingExtSource()
 79 //     G4ThreeVector GetPositionAtEndOfLastAdjointTrack()
 80 //     G4ThreeVector GetDirectionAtEndOfLastAdjointTrack()
 81 //     G4double GetEkinAtEndOfLastAdjointTrack()
 82 //     G4double GetEkinNucAtEndOfLastAdjointTrack()
 83 //     G4double GetWeightAtEndOfLastAdjointTrack()
 84 //     G4double GetCosthAtEndOfLastAdjointTrack()
 85 //     G4String GetFwdParticleNameAtEndOfLastAdjointTrack()
 86 //     G4int GetFwdParticlePDGEncodingAtEndOfLastAdjointTrack()
 87 //     G4int GetFwdParticleIndexAtEndOfLastAdjointTrack().
 88 //
 89 // In order to have a code working for both forward and adjoint simulation
 90 // mode, the extra code needed in user actions for the adjoint simulation
 91 // mode can be separated from the code needed only for the normal forward
 92 // simulation by using the following method:
 93 //   G4bool GetAdjointSimMode()
 94 // that returns true if an adjoint simulation is running and false if not!
 95 //
 96 //   Example of modification in the analysis part of the code
 97 //   --------------------------------------------------------
 98 // Let's say that in the forward simulation a G4 application computes the
 99 // energy deposited in a volume. The user wants to normalise its results for an
100 // external isotropic source of e- with differential spectrum given by f(E). A
101 // possible modification of the code where the deposited energy Edep during an
102 // event is registered would be the following:
103 //
104 //   G4AdjointSimManager* theAdjSimManager = G4AdjointSimManager::GetInstance();
105 //   if (theAdjSimManager->GetAdjointSimMode())
106 //   {
107 //     // code of the user that should be consider only for forward simulation
108 //     G4double normalised_edep = 0.;
109 //     if (theAdjSimManager->GetFwdParticleNameAtEndOfLastAdjointTrack()=="e-")
110 //     {
111 //       G4double ekin_prim =
112 //         theAdjSimManager->GetEkinAtEndOfLastAdjointTrack();
113 //       G4double weight_prim =
114 //         theAdjSimManager->GetWeightAtEndOfLastAdjointTrack();
115 //       normalised_edep = weight_prim*f(ekin_prim);
116 //     }
117 //     // then follow the code where normalised_edep is printed, or registered
118 //     // or whatever ....
119 //   }
120 //   else
121 //   {
122 //     // code that should be considered only for forward simulation
123 //   }
124 //
125 // Note that in this example a normalisation to only primary e- with only
126 // one spectrum f(E) is considered. The example code could be easily
127 // adapted for a normalisation to several spectra and several types of
128 // primary particles in the same simulation.
129 
130 // --------------------------------------------------------------------
131 //      Class Name:        G4AdjointSimManager
132 //        Author:               L. Desorgher, 2007-2009
133 //         Organisation:         SpaceIT GmbH
134 //        Contract:        ESA contract 21435/08/NL/AT
135 //         Customer:             ESA/ESTEC
136 // --------------------------------------------------------------------
137 #ifndef G4AdjointSimManager_hh
138 #define G4AdjointSimManager_hh 1
139 
140 #include "G4ThreeVector.hh"
141 #include "G4UserRunAction.hh"
142 #include "globals.hh"
143 
144 #include <vector>
145 
146 class G4UserEventAction;
147 class G4VUserPrimaryGeneratorAction;
148 class G4UserTrackingAction;
149 class G4UserSteppingAction;
150 class G4UserStackingAction;
151 class G4AdjointRunAction;
152 class G4AdjointPrimaryGeneratorAction;
153 class G4AdjointSteppingAction;
154 class G4AdjointEventAction;
155 class G4AdjointStackingAction;
156 class G4AdjointTrackingAction;
157 class G4ParticleDefinition;
158 class G4AdjointSimMessenger;
159 class G4PhysicsLogVector;
160 class G4Run;
161 
162 class G4AdjointSimManager : public G4UserRunAction
163 {
164   public:
165     static G4AdjointSimManager* GetInstance();
166 
167     void BeginOfRunAction(const G4Run* aRun) override;
168     void EndOfRunAction(const G4Run* aRun) override;
169     void RunAdjointSimulation(G4int nb_evt);
170 
171     inline G4int GetNbEvtOfLastRun() { return nb_evt_of_last_run; }
172 
173     void SetAdjointTrackingMode(G4bool aBool);
174     G4bool GetAdjointTrackingMode();
175     // true if an adjoint track is being processed
176 
177     inline G4bool GetAdjointSimMode()
178     {
179       return adjoint_sim_mode;
180     }  // true if an adjoint simulation is running
181 
182     G4bool GetDidAdjParticleReachTheExtSource();
183     void RegisterAtEndOfAdjointTrack();
184     void RegisterAdjointPrimaryWeight(G4double aWeight);
185     void ResetDidOneAdjPartReachExtSourceDuringEvent();
186 
187     inline G4int GetIDOfLastAdjParticleReachingExtSource()
188     {
189       return ID_of_last_particle_that_reach_the_ext_source;
190     }
191 
192     G4ThreeVector GetPositionAtEndOfLastAdjointTrack(std::size_t i = 0);
193     G4ThreeVector GetDirectionAtEndOfLastAdjointTrack(std::size_t i = 0);
194     G4double GetEkinAtEndOfLastAdjointTrack(std::size_t i = 0);
195     G4double GetEkinNucAtEndOfLastAdjointTrack(std::size_t i = 0);
196     G4double GetWeightAtEndOfLastAdjointTrack(std::size_t i = 0);
197     G4double GetCosthAtEndOfLastAdjointTrack(std::size_t i = 0);
198     const G4String& GetFwdParticleNameAtEndOfLastAdjointTrack();
199     G4int GetFwdParticlePDGEncodingAtEndOfLastAdjointTrack(std::size_t i = 0);
200     G4int GetFwdParticleIndexAtEndOfLastAdjointTrack(std::size_t i = 0);
201     std::size_t GetNbOfAdointTracksReachingTheExternalSurface();
202     void ClearEndOfAdjointTrackInfoVectors();
203     G4ParticleDefinition* GetLastGeneratedFwdPrimaryParticle();
204 
205     std::vector<G4ParticleDefinition*>* GetListOfPrimaryFwdParticles();
206     std::size_t GetNbOfPrimaryFwdParticles();
207 
208     G4bool DefineSphericalExtSource(G4double radius, G4ThreeVector pos);
209     G4bool DefineSphericalExtSourceWithCentreAtTheCentreOfAVolume(G4double radius,
210                                                                   const G4String& volume_name);
211     G4bool DefineExtSourceOnTheExtSurfaceOfAVolume(const G4String& volume_name);
212     void SetExtSourceEmax(G4double Emax);
213 
214     // Definition of adjoint source
215     //----------------------------
216     G4bool DefineSphericalAdjointSource(G4double radius, G4ThreeVector pos);
217     G4bool DefineSphericalAdjointSourceWithCentreAtTheCentreOfAVolume(G4double radius,
218                                                                       const G4String& volume_name);
219     G4bool DefineAdjointSourceOnTheExtSurfaceOfAVolume(const G4String& volume_name);
220     void SetAdjointSourceEmin(G4double Emin);
221     void SetAdjointSourceEmax(G4double Emax);
222     inline G4double GetAdjointSourceArea() { return area_of_the_adjoint_source; }
223     void ConsiderParticleAsPrimary(const G4String& particle_name);
224     void NeglectParticleAsPrimary(const G4String& particle_name);
225     void SetPrimaryIon(G4ParticleDefinition* adjointIon, G4ParticleDefinition* fwdIon);
226     const G4String& GetPrimaryIonName();
227 
228     inline void SetNormalisationMode(G4int n) { normalisation_mode = n; }
229     inline G4int GetNormalisationMode() { return normalisation_mode; }
230     inline G4double GetNumberNucleonsInIon() { return nb_nuc; }
231 
232     // Definition of user actions for the adjoint tracking phase
233     //----------------------------
234     void SetAdjointEventAction(G4UserEventAction* anAction);
235     void SetAdjointSteppingAction(G4UserSteppingAction* anAction);
236     void SetAdjointStackingAction(G4UserStackingAction* anAction);
237     void SetAdjointRunAction(G4UserRunAction* anAction);
238 
239     // Set methods for user run actions
240     //--------------------------------
241     inline void UseUserStackingActionInFwdTrackingPhase(G4bool aBool)
242     {
243       use_user_StackingAction = aBool;
244     }
245     inline void UseUserTrackingActionInFwdTrackingPhase(G4bool aBool)
246     {
247       use_user_TrackingAction = aBool;
248     }
249 
250     // Set nb of primary fwd gamma
251     void SetNbOfPrimaryFwdGammasPerEvent(G4int);
252 
253     // Set nb of adjoint primaries for reverse splitting
254     void SetNbAdjointPrimaryGammasPerEvent(G4int);
255     void SetNbAdjointPrimaryElectronsPerEvent(G4int);
256 
257     // Convergence test
258     //-----------------------
259     /*
260      void RegisterSignalForConvergenceTest(G4double aSignal);
261      void DefineExponentialPrimarySpectrumForConvergenceTest(
262           G4ParticleDefinition* aPartDef, G4double E0);
263      void DefinePowerLawPrimarySpectrumForConvergenceTest(
264           G4ParticleDefinition* aPartDef, G4double alpha);
265     */
266 
267     void SwitchToAdjointSimulationMode();
268     void BackToFwdSimulationMode();
269 
270   private:  // methods
271     static G4ThreadLocal G4AdjointSimManager* instance;
272 
273     void SetRestOfAdjointActions();
274     void SetAdjointPrimaryRunAndStackingActions();
275     void SetAdjointActions();
276     void ResetRestOfUserActions();
277     void ResetUserPrimaryRunAndStackingActions();
278     void ResetUserActions();
279     void DefineUserActions();
280 
281     // private constructor and destructor
282     G4AdjointSimManager();
283     ~G4AdjointSimManager() override;
284 
285   private:  // attributes
286     // Messenger
287     //----------
288     G4AdjointSimMessenger* theMessenger = nullptr;
289 
290     // user defined actions for the normal fwd simulation.
291     // Taken from the G4RunManager
292     //-------------------------------------------------
293     G4bool user_action_already_defined = false;
294     G4UserRunAction* fUserRunAction = nullptr;
295     G4UserEventAction* fUserEventAction = nullptr;
296     G4VUserPrimaryGeneratorAction* fUserPrimaryGeneratorAction = nullptr;
297     G4UserTrackingAction* fUserTrackingAction = nullptr;
298     G4UserSteppingAction* fUserSteppingAction = nullptr;
299     G4UserStackingAction* fUserStackingAction = nullptr;
300     G4bool use_user_StackingAction = false;  // only for fwd part of adjoint sim
301     G4bool use_user_TrackingAction = false;
302 
303     // action for adjoint simulation
304     //-----------------------------
305     G4UserRunAction* theAdjointRunAction = nullptr;
306     G4UserEventAction* theAdjointEventAction = nullptr;
307     G4AdjointPrimaryGeneratorAction* theAdjointPrimaryGeneratorAction = nullptr;
308     G4AdjointTrackingAction* theAdjointTrackingAction = nullptr;
309     G4AdjointSteppingAction* theAdjointSteppingAction = nullptr;
310     G4AdjointStackingAction* theAdjointStackingAction = nullptr;
311 
312     // adjoint mode
313     //-------------
314     G4bool adjoint_tracking_mode = false;
315     G4bool adjoint_sim_mode = false;
316 
317     // adjoint particle information on the external surface
318     //-----------------------------
319     std::vector<G4ThreeVector> last_pos_vec;
320     std::vector<G4ThreeVector> last_direction_vec;
321     std::vector<G4double> last_ekin_vec;
322     std::vector<G4double> last_ekin_nuc_vec;
323     std::vector<G4double> last_cos_th_vec;
324     std::vector<G4double> last_weight_vec;
325     std::vector<G4int> last_fwd_part_PDGEncoding_vec;
326     std::vector<G4int> last_fwd_part_index_vec;
327     std::vector<G4int> ID_of_last_particle_that_reach_the_ext_source_vec;
328 
329     G4ThreeVector last_pos;
330     G4ThreeVector last_direction;
331     G4double last_ekin = 0.0, last_ekin_nuc = 0.0;
332     // last_ekin_nuc=last_ekin/nuc, nuc is 1 if not a nucleus
333     G4double last_cos_th = 0.0;
334     G4String last_fwd_part_name;
335     G4int last_fwd_part_PDGEncoding = 0;
336     G4int last_fwd_part_index = 0;
337     G4double last_weight = 0.0;
338     G4int ID_of_last_particle_that_reach_the_ext_source = 0;
339 
340     G4int nb_evt_of_last_run = 0;
341     G4int normalisation_mode = 3;
342 
343     // Adjoint source
344     //--------------
345     G4double area_of_the_adjoint_source = 0.0;
346     G4double nb_nuc = 1.0;
347     G4double theAdjointPrimaryWeight = 0.0;
348 
349     G4bool welcome_message = true;
350 };
351 
352 #endif
353