File indexing completed on 2026-04-09 07:52:30
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 #include "TimeStepAction.hh"
0030
0031 #include "InterPulseAction.hh"
0032
0033 #include "G4DNAEventScheduler.hh"
0034 #include "G4DNAGillespieDirectMethod.hh"
0035 #include "G4DNAMolecularReactionTable.hh"
0036 #include "G4EventManager.hh"
0037 #include "G4ITLeadingTracks.hh"
0038 #include "G4MoleculeCounter.hh"
0039 #include "G4Scheduler.hh"
0040 #include "G4SystemOfUnits.hh"
0041 #include "G4Track.hh"
0042 #include "G4UnitsTable.hh"
0043 #include "G4VChemistryWorld.hh"
0044 #include "G4VPrimitiveScorer.hh"
0045
0046 TimeStepAction::TimeStepAction(const G4VChemistryWorld* pChemWorld, PulseAction* pPulse)
0047 : G4UserTimeStepAction(), fpPulse(pPulse), fpChemWorld(pChemWorld)
0048 {
0049 fpEventScheduler = std::make_unique<G4DNAEventScheduler>();
0050 fScheduler = G4Scheduler::Instance();
0051 if (dynamic_cast<InterPulseAction*>(fpPulse) != nullptr) {
0052 fPulsePeriod = dynamic_cast<InterPulseAction*>(fpPulse)->GetPulsePeriod();
0053 fNumberOfPulse = dynamic_cast<InterPulseAction*>(fpPulse)->GetNumberOfPulse();
0054 }
0055 }
0056
0057
0058 void TimeStepAction::UserPreTimeStepAction()
0059 {
0060 fpEventScheduler->ParticleBasedCounter();
0061 }
0062
0063
0064
0065 void TimeStepAction::UserPostTimeStepAction()
0066 {
0067 G4double T1 = 5 * CLHEP::ns;
0068 if (fpPulse != nullptr && fpPulse->IsActivedPulse()) {
0069 T1 = fpPulse->GetPulseLarger() + 5 * CLHEP::ns;
0070 if (fNumberOfPulse != 0) {
0071 fPulseID = (floor)(fScheduler->GetGlobalTime() / fPulsePeriod);
0072 T1 = fPulseID * fPulsePeriod + fpPulse->GetPulseLarger() + 5 * CLHEP::ns;
0073 }
0074 }
0075
0076 if (fScheduler->GetGlobalTime() >= T1) {
0077 CompartmentBased();
0078 }
0079 }
0080
0081
0082
0083 void TimeStepAction::UserReactionAction(const G4Track& , const G4Track& ,
0084 const std::vector<G4Track*>* )
0085 {}
0086
0087
0088
0089 void TimeStepAction::EndProcessing()
0090 {
0091 fpEventScheduler->Reset();
0092 }
0093
0094
0095
0096 void TimeStepAction::CompartmentBased()
0097 {
0098 fpEventScheduler->SetStartTime(fScheduler->GetGlobalTime());
0099 fpEventScheduler->SetChangeMesh(true);
0100 fpEventScheduler->Initialize(*fpChemWorld->GetChemistryBoundary(), fPixel);
0101 fpEventScheduler->Run();
0102 }
0103
0104
0105
0106 G4DNAEventScheduler* TimeStepAction::GetEventScheduler() const
0107 {
0108 return fpEventScheduler.get();
0109 }
0110
0111
0112
0113 void TimeStepAction::SetInitialPixel()
0114 {
0115 auto pBoundingBox = fpChemWorld->GetChemistryBoundary();
0116 G4double Box = pBoundingBox->halfSideLengthInX();
0117 if (Box == 4 * 1.6 * um) {
0118 fPixel = 4 * 512;
0119 }
0120 else if (Box == 2 * 1.6 * um) {
0121 fPixel = 2 * 512;
0122 }
0123 else if (Box == 1.6 * um) {
0124 fPixel = 512;
0125 }
0126 else if (Box == 0.8 * um) {
0127 fPixel = 256;
0128 }
0129 else if (Box == 0.4 * um) {
0130 fPixel = 256 / 2;
0131 }
0132 else if (Box == 0.2 * um) {
0133 fPixel = 256 / 4;
0134 }
0135 else {
0136 G4cout << "Box : " << *pBoundingBox << " Pixel : " << fPixel << G4endl;
0137 G4Exception("This chem volume is not optimized and the result may be incorrect.",
0138 "TimeStepAction::TimeStepAction", FatalException, "");
0139 }
0140 }
0141
0142
0143
0144 void TimeStepAction::StartProcessing()
0145 {
0146 auto currentEvent = G4EventManager::GetEventManager();
0147 if (currentEvent->GetConstCurrentEvent()->IsAborted()) {
0148 G4cout << "This event is fully aborted" << G4endl;
0149 fScheduler->Stop();
0150 }
0151 fpEventScheduler->SetVerbose(G4Scheduler::Instance()->GetVerbose());
0152 SetInitialPixel();
0153 fPulseID = 0;
0154 }
0155
0156