BLCollectiveComputation.hh

Go to the documentation of this file.
00001 //      BLCollectiveComputation.hh
00002 /*
00003 This source file is part of G4beamline, http://g4beamline.muonsinc.com
00004 Copyright (C) 2003,2004,2005,2006 by Tom Roberts, all rights reserved.
00005 
00006 This program is free software; you can redistribute it and/or
00007 modify it under the terms of the GNU General Public License
00008 as published by the Free Software Foundation; either version 2
00009 of the License, or (at your option) any later version.
00010 
00011 This program is distributed in the hope that it will be useful,
00012 but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 GNU General Public License for more details.
00015 
00016 http://www.gnu.org/copyleft/gpl.html
00017 */
00018 
00019 #ifndef BLCOLLECTIVECOMPUTATION_H
00020 #define BLCOLLECTIVECOMPUTATION_H
00021 
00022 #include "G4Event.hh"
00023 #include "G4Track.hh"
00024 
00025 /**     struct BLTrackData -- data related to a track (for collective tracking)
00026  **/
00027 struct BLTrackData {
00028         G4Event *event;
00029         G4Track *track;
00030 public:
00031         /// Constructor.
00032         BLTrackData(G4Event *e, G4Track *t) { event = e;  track=t; }
00033 
00034         /// destructor. DOES NOT DELETE ANY OTHER OBJECTS.
00035         ~BLTrackData() { }
00036 };
00037 
00038 /**     class BLCollectiveComputation -- base class for a collective computation
00039  *
00040  *      Normally a command class that implements a collective computation 
00041  *      will be derived from this class as well as BLCommand.
00042  *      Its command() function should register itself with
00043  *          BLRunManager::getObject()->registerCollectiveComputation(this);
00044  *      and then call
00045  *          BLRunManager::getObject()->setCollectiveMode(true);
00046  *
00047  *      If steps in time are also desired, it should call
00048  *          BLRunManager::getObject()->setDeltaT(0.1*ns);
00049  *      (with desired delta-T). Note that steps in time are not exact, so
00050  *      the computation should probably check that the variation in time
00051  *      among the tracks is small enough (in practive, 1 ps accuracy is
00052  *      normal).
00053  *
00054  *      Note that setDeltaT() can be called at any time, and will affect the
00055  *      next step. It is probably desirable to adjust deltaT depending on the
00056  *      importance of the collective computation (when the bunch is diffuse,
00057  *      bigger deltaT won't affect the accuracy but will reduce the CPU time).
00058  *      Caveat: if steps in time are to be used, setDeltaT() must be called
00059  *      before tracking begins, and should never be <= 0.0 (values <= 0.0
00060  *      means each track takes individual steps in space, which is probably
00061  *      not useful).
00062  *
00063  *      Note that runmanager->rejectCollectiveStep() can be called during
00064  *      tracking or in collectiveStep() to reject the current step and 
00065  *      re-process it. This only makes sense if setDeltaT() has been
00066  *      called with a smaller value of deltaT. Attempts to reject the very
00067  *      first step are silently ignored (that step is used to process all
00068  *      tracks to the same time).
00069  *
00070  *      The basic sequence of collective tracking, including callbacks from
00071  *      BLRunManger to each registered collective computation is:
00072  *
00073  *      (generate beam tracks from beam commands, filling trackVector)
00074  *      stepTime = (largest time from beam tracks)
00075  *      beginCollectiveTracking()
00076  *      first=true
00077  *      loop over steps {
00078  *              rejected=false
00079  *              nActive=0
00080  *              loop over tracks in trackVector {
00081  *                      if(rejected && !first) break;
00082  *                      beginTrack()
00083  *                      (discard remaining secondaries, if any)
00084  *                      process track to stepTime or killed
00085  *                      if(track is active) ++nActive
00086  *                      if(keepSecondaries)
00087  *                              append secondaries to trackVector
00088  *                      else
00089  *                              discard secondaries
00090  *              }
00091  *              if(!rejected || first) collectiveStep()
00092  *              if(rejected && !first) {
00093  *                      restore saved tracks and stepTime
00094  *              } else {
00095  *                      save tracks and stepTime
00096  *                      stepTime += deltaT
00097  *              }
00098  *              first=false
00099  *      } while(nActive > 0)
00100  *      endCollectiveTracking()
00101  *
00102  *      Note: if multiple BLCollectiveComputation instances are registered
00103  *      with BLRUnManager, the callbacks to them will occur in the order
00104  *      in which they were registered (normally the order in which their
00105  *      commands appear in the input file).
00106  *
00107  **/
00108 class BLCollectiveComputation {
00109 public:
00110         BLCollectiveComputation() { };
00111         virtual ~BLCollectiveComputation() { }
00112 
00113         /// beginCollectiveTracking() is called after the track vector is 
00114         /// constructed but before trackng begins.
00115         /// Can be used to allocate internal arrays or create NTuple-s.
00116         /// Note that additional tracks can be added to v as tracking proceeds;
00117         /// no tracks are ever removed (but they will change status).
00118         /// The vector v will not change during the run.
00119         virtual void beginCollectiveTracking(std::vector<BLTrackData>& v) { }
00120 
00121         /// beginTrack() is called just before the track v[index] is
00122         /// tracked for the next step. Note that the user class can be
00123         /// derived from G4UserTrackingAction and registered to be called
00124         /// at the start and end of tracking for each track. The difference
00125         /// is this routine relates the track to the entry in v[], and
00126         /// also: BLRunManager::processOneTrack() can be called here, but
00127         /// not in PreUserTrackingAction().
00128         virtual void beginTrack(std::vector<BLTrackData>& v, int index) { }
00129 
00130         /// collectiveStep() is called after each collective step
00131         /// to perform the computation.
00132         /// It can store data for later use, and can modify the tracks.
00133         /// Note that collectiveStep() is not called until after the
00134         /// first step is taken, so you might want to call your
00135         /// collectiveStep() function at the end of beginCollectiveTracking()
00136         /// to store the state of tracks at the earliest time.
00137         /// Note: collectiveStep() can call runmanager->rejectCollectiveStep(),
00138         /// in which case the tracking since the previous return from
00139         /// collectiveStep() will be discarded and re-done; for this to make
00140         /// sense, runmanager->setDeltaT() should also be called with a
00141         /// smaller value -- this is one way to adapt deltaT dynamically.
00142         virtual void collectiveStep(std::vector<BLTrackData>& v) = 0;
00143 
00144         /// endCollectiveTracking() is called after tracking is complete.
00145         /// Can be used to delete internal arrays and print a summary.
00146         virtual void endCollectiveTracking(std::vector<BLTrackData>& v) { }
00147 };
00148 
00149 #endif // BLCOLLECTIVECOMPUTATION_H
g4beamline