45G4DNAIndependentReactionTimeStepper::Utils::Utils(
const G4Track& trackA,
63 fSampledPositions.clear();
67void G4DNAIndependentReactionTimeStepper::InitializeForNewTrack()
74 fHasAlreadyReachedNullTime =
false;
81 InitializeForNewTrack();
88 G4cout <<
"________________________________________________________________"
91 G4cout <<
"G4DNAIndependentReactionTimeStepper::CalculateStep" <<
G4endl;
92 G4cout <<
"Check done for molecule : " << pMoleculeA->GetName() <<
" ("
97 auto pMolConfA = pMoleculeA->GetMolecularConfiguration();
99 const auto pReactantList = fMolecularReactionTable->
CanReactWith(pMolConfA);
101 if(pReactantList ==
nullptr)
108 G4cout <<
"G4DNAIndependentReactionTimeStepper::CalculateStep will "
110 "for the reaction because the molecule "
111 << pMoleculeA->GetName()
112 <<
" does not have any reactants given in the reaction table."
120 G4int nbReactives = (
G4int)pReactantList->size();
130 G4cout <<
"G4DNAIndependentReactionTimeStepper::CalculateStep will "
132 "for the reaction because the molecule "
133 << pMoleculeA->GetName()
134 <<
" does not have any reactants given in the reaction table."
135 <<
"This message can also result from a wrong implementation of "
136 "the reaction table."
143 fReactants = std::make_shared<vector<G4Track*>>();
144 fReactionModel->
Initialise(pMolConfA, trackA);
145 for(
G4int i = 0; i < nbReactives; ++i)
147 auto pMoleculeB = (*pReactantList)[i];
148 G4int key = pMoleculeB->GetMoleculeID();
155 std::vector<std::pair<G4TrackList::iterator, G4double>> resultIndices;
156 resultIndices.clear();
158 trackA, key, fRCutOff, resultIndices);
160 if(resultIndices.empty())
164 for(
auto& it : resultIndices)
166 G4Track* pTrackB = *(std::get<0>(it));
168 if(pTrackB == &trackA)
172 if(pTrackB ==
nullptr)
175 exceptionDescription <<
"No trackB no valid";
179 exceptionDescription);
182 if(fCheckedTracks.find(pTrackB->
GetTrackID()) != fCheckedTracks.end())
187 Utils utils(trackA, *pTrackB);
190 auto pMolConfB = pMolB->GetMolecularConfiguration();
192 if(distance * distance < Reff * Reff)
200 if(!fHasAlreadyReachedNullTime)
203 fHasAlreadyReachedNullTime =
true;
206 CheckAndRecordResults(utils);
212 G4double tempMinET = GetTimeToEncounter(trackA, *pTrackB);
223 CheckAndRecordResults(utils);
232 G4cout <<
"G4DNAIndependentReactionTimeStepper::CalculateStep will finally "
238 G4cout <<
"Selected reactants for trackA: " << pMoleculeA->GetName()
241 vector<G4Track*>::iterator it;
255void G4DNAIndependentReactionTimeStepper::CheckAndRecordResults(
258 if(utils.fTrackB.GetTrackStatus() !=
fAlive)
263 if(&utils.fTrackB == &utils.fTrackA)
266 exceptionDescription <<
"A track is reacting with itself"
267 " (which is impossible) ie fpTrackA == trackB"
269 exceptionDescription <<
"Molecule A is of type : "
270 << utils.fpMoleculeA->GetName()
271 <<
" with trackID : " << utils.fTrackA.GetTrackID()
272 <<
" and B : " << utils.fpMoleculeB->GetName()
273 <<
" with trackID : " << utils.fTrackB.GetTrackID()
275 G4Exception(
"G4DNAIndependentReactionTimeStepper::RetrieveResults",
277 exceptionDescription);
280 if(fabs(utils.fTrackB.GetGlobalTime() - utils.fTrackA.GetGlobalTime()) >
281 utils.fTrackA.GetGlobalTime() * (1. - 1. / 100))
286 <<
"The interacting tracks are not synchronized in time" <<
G4endl;
288 <<
"trackB->GetGlobalTime() != fpTrackA.GetGlobalTime()" <<
G4endl;
290 exceptionDescription <<
"fpTrackA : trackID : "
291 << utils.fTrackA.GetTrackID()
292 <<
"\t Name :" << utils.fpMoleculeA->GetName()
293 <<
"\t fpTrackA->GetGlobalTime() = "
294 <<
G4BestUnit(utils.fTrackA.GetGlobalTime(),
"Time")
297 exceptionDescription <<
"trackB : trackID : " << utils.fTrackB.GetTrackID()
298 <<
"\t Name :" << utils.fpMoleculeB->GetName()
299 <<
"\t trackB->GetGlobalTime() = "
300 <<
G4BestUnit(utils.fTrackB.GetGlobalTime(),
"Time")
303 G4Exception(
"G4DNAIndependentReactionTimeStepper::RetrieveResults",
305 exceptionDescription);
310std::unique_ptr<G4ITReactionChange>
316 if(pReactionSet ==
nullptr)
322 if(reactionPerTime.empty())
327 for(
auto reaction_i = reactionPerTime.begin();
328 reaction_i != reactionPerTime.end(); reaction_i = reactionPerTime.begin())
330 G4Track* pTrackA = (*reaction_i)->GetReactants().first;
335 G4Track* pTrackB = (*reaction_i)->GetReactant(pTrackA);
341 if(pTrackB == pTrackA)
344 exceptionDescription <<
"The IT reaction process sent back a reaction "
345 "between trackA and trackB. ";
346 exceptionDescription <<
"The problem is trackA == trackB";
347 G4Exception(
"G4DNAIndependentReactionTimeStepper::FindReaction",
349 exceptionDescription);
352 if(fpReactionProcess !=
nullptr &&
356 if((fSampledPositions.find(pTrackA->
GetTrackID()) ==
357 fSampledPositions.end() &&
358 (fSampledPositions.find(pTrackB->
GetTrackID()) ==
359 fSampledPositions.end())))
363 <<
"The positions of trackA and trackB have no counted ";
364 G4Exception(
"G4DNAIndependentReactionTimeStepper::FindReaction",
365 "G4DNAIndependentReactionTimeStepper0001",
371 auto pReactionChange =
373 if(pReactionChange ==
nullptr)
377 return pReactionChange;
386 fReactionModel = pReactionModel;
391 return fReactionModel;
399G4double G4DNAIndependentReactionTimeStepper::GetTimeToEncounter(
404 ->GetTimeToEncounter(trackA, trackB);
405 return timeToReaction;
411 fpReactionProcess = pReactionProcess;
417 fCheckedTracks.clear();
419 for(
auto pTrack : *fpTrackContainer->
GetMainList())
421 if(pTrack ==
nullptr)
424 exceptionDescription <<
"No track found.";
425 G4Exception(
"G4DNAIndependentReactionTimeStepper::CalculateMinTimeStep",
426 "G4DNAIndependentReactionTimeStepper006",
440 if(sampledMinTimeStep < fTSTimeStep)
442 fTSTimeStep = sampledMinTimeStep;
449 fSampledPositions[pTrack->GetTrackID()] = pTrack->GetPosition();
454 fSampledPositions[pTrackB->GetTrackID()] = pTrackB->GetPosition();
459 else if(fTSTimeStep == sampledMinTimeStep &&
G4bool(reactants))
464 fSampledPositions[pTrack->GetTrackID()] = pTrack->GetPosition();
469 fSampledPositions[pTrackB->GetTrackID()] = pTrackB->GetPosition();
#define BuildChemicalMoleculeFinder()
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
G4shared_ptr< std::vector< G4Track * > > G4TrackVectorHandle
std::multiset< G4ITReactionPtr, compReactionPerTime > G4ITReactionPerTime
G4Molecule * GetMolecule(const G4Track &track)
G4GLOB_DLL std::ostream G4cout
G4double CalculateStep(const G4Track &, const G4double &) override
G4DNAIndependentReactionTimeStepper()
G4VDNAReactionModel * GetReactionModel()
void SetReactionModel(G4VDNAReactionModel *)
G4double CalculateMinTimeStep(G4double, G4double) override
std::unique_ptr< G4ITReactionChange > FindReaction(G4ITReactionSet *pReactionSet, const G4double ¤tStepTime=0, const G4double &previousStepTime=0, const G4bool &reachedUserStepTimeLimit=false)
void SetReactionProcess(G4VITReactionProcess *pReactionProcess)
Data * GetReactionData(Reactant *, Reactant *) const
const ReactantList * CanReactWith(Reactant *) const
static G4double GetRCutOff()
void SelectThisReaction(G4ITReactionPtr reaction)
void AddReactions(G4double time, G4Track *trackA, G4TrackVectorHandle reactants)
G4ITReactionPerTime & GetReactionsPerTime()
G4TrackList * GetMainList(Key)
const G4String & GetName() const
static G4OctreeFinder * Instance()
void FindNearestInRange(const G4Track &track, const int &key, G4double R, std::vector< std::pair< typename CONTAINER::iterator, G4double > > &result, G4bool isSort=false) const
static G4Scheduler * Instance()
G4double GetGlobalTime() const
G4double GetStartTime() const
G4TrackStatus GetTrackStatus() const
void SetPosition(const G4ThreeVector &aValue)
const G4ThreeVector & GetPosition() const
virtual void Initialise(const G4MolecularConfiguration *, const G4Track &)
virtual G4double GetReactionRadius(const G4MolecularConfiguration *, const G4MolecularConfiguration *)=0
virtual std::unique_ptr< G4ITReactionChange > MakeReaction(const G4Track &, const G4Track &)=0
virtual G4bool TestReactibility(const G4Track &, const G4Track &, double, bool)=0
G4TrackVectorHandle fReactants
G4TrackVectorHandle GetReactants()
virtual void ResetReactants()
static G4ThreadLocal G4double fUserMinTimeStep
G4double fSampledMinTimeStep