Geant4-11
G4DNAEventScheduler.cc
Go to the documentation of this file.
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//
27#include <memory>
30#include "G4SystemOfUnits.hh"
31#include "G4UnitsTable.hh"
34#include "G4Timer.hh"
35#include "G4Scheduler.hh"
36#include "G4UserMeshAction.hh"
37#include "G4MoleculeCounter.hh"
39
41 G4int pixel)
43 , fVerbose(0)
44 , fInitialized(false)
45 , fStartTime(1 * ps)
46 , fEndTime(10000 * s)
47 , fStepNumber(0)
48 , fMaxStep(INT_MAX)
49 , fRunning(true)
50 , fTimeStep(DBL_MAX)
51 , fGlobalTime(fStartTime)
52 , fJumpingNumber(0)
53 , fReactionNumber(0)
54 , fPixel(pixel)
55 , fIsChangeMesh(false)
56 , fSetChangeMesh(true)
57 , fStepNumberInMesh(0)
58 , fInitialPixels(fPixel)
59 , fpMesh(new G4DNAMesh(boundingBox, fPixel))
60 , fpGillespieReaction(new G4DNAGillespieDirectMethod())
61 , fpEventSet(new G4DNAEventSet())
62 , fpUpdateSystem(new G4DNAUpdateSystemModel())
63 , fpUserMeshAction(nullptr)
64{
65 if(!CheckingReactionRadius(fpMesh->GetResolution()))
66 {
67 G4String WarMessage = "resolution is not good : " +
68 std::to_string(fpMesh->GetResolution() / nm);
69 G4Exception("G4DNAEventScheduler::InitializeInMesh()", "WrongResolution",
70 JustWarning, WarMessage);
71 }
72}
73
75{
76 fCounterMap.clear();
77 if(fTimeToRecord.empty())
78 {
79 G4cout << "fTimeToRecord is empty " << G4endl;
80 }
82
83 if(G4VMoleculeCounter::Instance()->InUse()) // copy from MoleculeCounter
84 {
87 if(species.get() == nullptr)
88 {
89 return;
90 }
91 else if(species->empty())
92 {
94 return;
95 }
96 for(auto time_mol : fTimeToRecord)
97 {
98 if(time_mol > fStartTime)
99 {
100 continue;
101 }
102
103 for(auto molecule : *species)
104 {
106 molecule, time_mol);
107
108 if(n_mol < 0)
109 {
110 G4cerr << "G4DNAEventScheduler::ClearAndReChargeCounter() ::N "
111 "molecules not valid < 0 "
112 << G4endl;
113 G4Exception("", "N<0", FatalException, "");
114 }
115 fCounterMap[time_mol][molecule] = n_mol;
116 }
117
119 }
121 G4MoleculeCounter::Instance()->Use(false); // no more used
122 }
123}
124
125[[maybe_unused]] void G4DNAEventScheduler::AddTimeToRecord(const G4double& time)
126{
127 if(fTimeToRecord.find(time) == fTimeToRecord.end())
128 {
129 fTimeToRecord.insert(time);
130 }
131}
132
134
136{
137 auto pMainList = G4ITTrackHolder::Instance()->GetMainList();
138 std::map<G4DNAMesh::Key, MapList> TrackKeyMap;
139 for(auto track : *pMainList)
140 {
141 auto molType = GetMolecule(track)->GetMolecularConfiguration();
142
143 auto pScavengerMaterial = dynamic_cast<G4DNAScavengerMaterial*>(
145 if(pScavengerMaterial != nullptr &&
146 pScavengerMaterial->find(molType)) // avoid voxelize the scavenger
147 {
148 continue;
149 }
150
151 auto key = fpMesh->GetKey(track->GetPosition());
152 if(TrackKeyMap.find(key) != TrackKeyMap.end())
153 {
154 std::map<MolType, size_t>& TrackTypeMap = TrackKeyMap[key];
155 if(TrackTypeMap.find(molType) != TrackTypeMap.end())
156 {
157 TrackTypeMap[molType]++;
158 }
159 else
160 {
161 TrackTypeMap[molType] = 1;
162 }
163 }
164 else
165 {
166 TrackKeyMap[key][molType] = 1;
167 }
168 }
169
170 for(auto& it : TrackKeyMap)
171 {
172 fpMesh->SetVoxelMapList(it.first, std::move(it.second));
173 }
174}
175
177{
178 fPixel = pixel;
179 auto newMesh = new G4DNAMesh(fpMesh->GetBoundingBox(), fPixel);
180
181 auto begin = fpMesh->begin();
182 auto end = fpMesh->end();
183 std::map<G4DNAMesh::Key, MapList> TrackKeyMap;
184 for(; begin != end; begin++)
185 {
186 auto index = fpMesh->GetIndex(begin->first);
187 auto newKey = newMesh->GetKey(fpMesh->GetIndex(index, fPixel));
188 auto node = begin->second;
189 // if (node == nullptr) continue;
190 if(TrackKeyMap.find(newKey) == TrackKeyMap.end())
191 {
192 TrackKeyMap[newKey] = node->GetMapList();
193 }
194 else
195 {
196 for(const auto& it : node->GetMapList())
197 {
198 TrackKeyMap[newKey][it.first] += it.second;
199 }
200 if(fVerbose > 1)
201 {
202 G4cout << "key : " << begin->first << " index : " << index
203 << " new index : " << fpMesh->GetIndex(index, fPixel)
204 << " new key : " << newKey
205 << " number: " << node->GetMapList().begin()->second << G4endl;
206 }
207 }
208 }
209 fpMesh.reset(newMesh);
210
211 for(auto& it : TrackKeyMap)
212 {
213 fpMesh->SetVoxelMapList(it.first, std::move(it.second));
214 }
215}
217{
218 // find another solultion
220
221 //
222 // RecordTime();//Last register for counter
223
224 if(fVerbose > 0)
225 {
226 G4cout << "End Processing and reset Gird, ScavengerTable, EventSet for new "
227 "simulation!!!!"
228 << G4endl;
229 }
230 fInitialized = false;
231 fTimeStep = 0;
232 fStepNumber = 0;
234 fRunning = true;
235 fReactionNumber = 0;
236 fJumpingNumber = 0;
237
238 fpEventSet->RemoveEventSet();
239 fpMesh->Reset();
240}
241
243{
244 if(!fInitialized)
245 {
247 fpMesh = std::make_unique<G4DNAMesh>(fpMesh->GetBoundingBox(), fPixel);
248
249 // Scavenger();
250
251 auto pScavengerMaterial = dynamic_cast<G4DNAScavengerMaterial*>(
253 if(pScavengerMaterial == nullptr)
254 {
255 G4cout << "pScavengerMaterial == nullptr" << G4endl;
256 }
257 else
258 {
259 if(fVerbose > 1)
260 {
261 pScavengerMaterial->PrintInfo();
262 }
263 }
264
265 Voxelizing();
266 fpGillespieReaction->SetVoxelMesh(*fpMesh);
267 fpGillespieReaction->SetEventSet(fpEventSet.get());
268 fpGillespieReaction->SetTimeStep(
269 0); // reset fTimeStep = 0 in fpGillespieReaction
270 fpGillespieReaction->Initialize();
271 fpUpdateSystem->SetMesh(fpMesh.get());
273 fInitialized = true;
274 }
275
276 if(fVerbose > 0)
277 {
278 fpUpdateSystem->SetVerbose(1);
279 }
280
281 if(fVerbose > 2)
282 {
283 fpMesh->PrintMesh();
284 }
285}
287{
288 if(fPixel <= 1)
289 {
290 fRunning = false;
291 return;
292 }
293 // TEST /3
294 ReVoxelizing(fPixel / 2); //
295 // ReVoxelizing(fPixel/3);//
296
297 fpGillespieReaction->SetVoxelMesh(*fpMesh);
298 fpUpdateSystem->SetMesh(fpMesh.get());
299 fpGillespieReaction->Initialize();
300}
301
303{
304 if(fVerbose > 0)
305 {
306 G4cout
307 << "*** End Processing In Mesh and reset Mesh, EventSet for new Mesh!!!!"
308 << G4endl;
309 }
310 fpEventSet->RemoveEventSet();
311 fInitialized = false;
312 fIsChangeMesh = false;
313 fReactionNumber = 0;
314 fJumpingNumber = 0;
316}
317
319
321
322[[maybe_unused]] G4double G4DNAEventScheduler::GetTimeStep() const { return fTimeStep; }
323
325
327
329{
330 fStartTime = time;
331}
332
335{
336 G4Timer localtimer;
337 if(fVerbose > 0)
338 {
339 localtimer.Start();
340 G4cout << "***G4DNAEventScheduler::Run*** for Pixel : " << fPixel << G4endl;
341 }
342 while(fEndTime > fGlobalTime && fRunning)
343 {
344 RunInMesh();
345 }
346 if(fVerbose > 0)
347 {
348 if(!fRunning)
349 {
350 G4cout << " StepNumber(" << fStepNumber << ") = MaxStep(" << fMaxStep
351 << ")" << G4endl;
352 }
353 else if(fEndTime <= fGlobalTime)
354 {
355 G4cout << " GlobalTime(" << fGlobalTime << ") > EndTime(" << fEndTime
356 << ")"
357 << " StepNumber : " << fStepNumber << G4endl;
358 }
359 localtimer.Stop();
360 G4cout << "***G4DNAEventScheduler::Ending::"
361 << G4BestUnit(fGlobalTime, "Time")
362 << " Events left : " << fpEventSet->size() << G4endl;
363 if(fVerbose > 1) {
364 fpMesh->PrintMesh();
365 }
366 G4cout << " Computing Time : " << localtimer << G4endl;
367 }
368 Reset();
369}
370
372{
373 if(!fInitialized)
374 {
376 }
377 G4Timer localtimerInMesh;
378 // if (fVerbose > 0)
379 {
380 localtimerInMesh.Start();
381 G4double C = 20;
383 ->GetConfiguration("H2O2")
385 G4double transferTime = std::pow(fpMesh->GetResolution(), 2) * C / (6 * D);
386 G4cout << "***G4DNAEventScheduler::RunInMesh*** for Pixel : " << fPixel
387 << " transferTime : " << G4BestUnit(transferTime, "Time") << G4endl;
388 G4cout << " resolution : " << G4BestUnit(fpMesh->GetResolution(), "Length")
389 << G4endl;
390 }
391
392 if(fVerbose > 2)
393 {
394 fpMesh->PrintMesh();
395 }
396
397 if(fpUserMeshAction != nullptr)
398 {
399 fpUserMeshAction->BeginOfMesh(fpMesh.get(), fGlobalTime);
400 }
401
402 // if diffusive jumping is avaiable, EventSet is never empty
403 while(!fpEventSet->Empty() && !fIsChangeMesh && fEndTime > fGlobalTime)
404 {
405 Stepping();
407
408 if(fpUserMeshAction != nullptr)
409 {
410 fpUserMeshAction->InMesh(fpMesh.get(), fGlobalTime);
411 }
412
413 if(fVerbose > 2)
414 {
415 G4cout << "fGlobalTime : " << G4BestUnit(fGlobalTime, "Time")
416 << " fTimeStep : " << G4BestUnit(fTimeStep, "Time") << G4endl;
417 }
418
419 G4double C = 20;
421 ->GetConfiguration("H2O2")
423 if(D == 0)
424 {
425 G4ExceptionDescription exceptionDescription;
426 exceptionDescription << "D == 0";
427 G4Exception("G4DNAEventScheduler::RunInMesh", "G4DNAEventScheduler001",
428 FatalErrorInArgument, exceptionDescription);
429 }
430 G4double transferTime = std::pow(fpMesh->GetResolution(), 2) * C / (6 * D);
431
432 // if(fStepNumberInMesh > 40000 && fPixel != 1)
433 if(transferTime < fTimeStep &&
434 fPixel != 1) // dont change Mesj if fPixel == 1
435 {
436 if(fVerbose > 1)
437 {
438 G4cout << " Pixels : " << fPixel << " resolution : "
439 << G4BestUnit(fpMesh->GetResolution(), "Length")
440 << " fStepNumberInMesh : " << fStepNumberInMesh
441 << " at fGlobalTime : " << G4BestUnit(fGlobalTime, "Time")
442 << " at fTimeStep : " << G4BestUnit(fTimeStep, "Time")
443 << " fReactionNumber : " << fReactionNumber
444 << " transferTime : " << G4BestUnit(transferTime, "Time")
445 << G4endl;
446 }
448 {
449 fIsChangeMesh = true;
450 }
451 }
452 }
453
454 if(fVerbose > 1)
455 {
456 localtimerInMesh.Stop();
457 G4cout << "***G4DNAEventScheduler::Ending::"
458 << G4BestUnit(fGlobalTime, "Time")
459 << " Event left : " << fpEventSet->size() << G4endl;
460 G4cout << " Computing Time : " << localtimerInMesh << " Due to : ";
461 if(fpEventSet->Empty())
462 {
463 G4cout << "EventSet is Empty" << G4endl;
464 }
465 else if(fIsChangeMesh)
466 {
467 G4cout << "Changing Mesh from : " << fPixel
468 << " pixels to : " << fPixel / 2 << " pixels" << G4endl;
469 G4cout << "Info : ReactionNumber : " << fReactionNumber
470 << " JumpingNumber : " << fJumpingNumber << G4endl;
471 }
472 else if(fEndTime > fGlobalTime)
473 {
474 G4cout << " GlobalTime(" << fGlobalTime << ") > EndTime(" << fEndTime
475 << ")"
476 << " StepNumber : " << fStepNumber << G4endl;
477 }
478 if(fVerbose > 2)
479 {
480 fpMesh->PrintMesh();
481 }
482 G4cout << G4endl;
483 }
484
485 if(fpUserMeshAction != nullptr)
486 {
487 fpUserMeshAction->EndOfMesh(fpMesh.get(), fGlobalTime);
488 }
489 ResetInMesh();
490}
491
492void G4DNAEventScheduler::Stepping() // this event loop
493{
495
496 if(fpEventSet->size() > fpMesh->size())
497 {
498 G4ExceptionDescription exceptionDescription;
499 exceptionDescription << "fpEventSet->size() > fpMesh->size()";
500 G4Exception("G4DNAEventScheduler::Stepping", "G4DNAEventScheduler002",
501 FatalErrorInArgument, exceptionDescription);
502 };
503
504 auto selected = fpEventSet->begin();
505 const auto& key = (*selected)->GetKey();
506 auto index = fpMesh->GetIndex(key);
507
508 if(fVerbose > 1)
509 {
510 G4cout << "G4DNAEventScheduler::Stepping()*********************************"
511 "*******"
512 << G4endl;
513 (*selected)->PrintEvent();
514 }
515
516 // get selected time step
517 fTimeStep = (*selected)->GetTime();
518
519 // selected data
520 auto pJumping = (*selected)->GetJumpingData();
521 auto pReaction = (*selected)->GetReactionData();
522
523 fpUpdateSystem->SetGlobalTime(fTimeStep +
524 fStartTime); // this is just for printing
525
526 if(pJumping == nullptr && pReaction == nullptr)
527 {
528 G4ExceptionDescription exceptionDescription;
529 exceptionDescription << "pJumping == nullptr && pReaction == nullptr";
530 G4Exception("G4DNAEventScheduler::Stepping", "G4DNAEventScheduler003",
531 FatalErrorInArgument, exceptionDescription);
532 }
533
534 fpGillespieReaction->SetTimeStep(fTimeStep);
535
536 if(pJumping == nullptr)
537 {
538 fpUpdateSystem->UpdateSystem(index, *pReaction);
539
540 fpEventSet->RemoveEvent(selected);
541 // create new event
542 fpGillespieReaction->CreateEvent(key);
544
545 // recordTime in reaction
546 RecordTime();
547 }
548 else if(pReaction == nullptr)
549 {
550 // dont change this
551 fpUpdateSystem->UpdateSystem(index, *pJumping);
552 auto jumpingKey = fpMesh->GetKey(pJumping->second);
553 fpEventSet->RemoveEvent(selected);
554
555 // create new event
556 // should create Jumping before key
557 fpGillespieReaction->CreateEvent(jumpingKey);
558 fpGillespieReaction->CreateEvent(key);
559
561 }
562 if(fVerbose > 1)
563 {
564 G4cout << "G4DNAEventScheduler::Stepping::end "
565 "Print***********************************"
566 << G4endl;
567 G4cout << G4endl;
568 }
570}
571
573{
574 fEndTime = endTime;
575}
576
578{
579 auto recordTime = *fLastRecoredTime;
580 if(fGlobalTime >= recordTime && fCounterMap[recordTime].empty())
581 {
582 auto begin = fpMesh->begin();
583 auto end = fpMesh->end();
584 for(; begin != end; begin++)
585 {
586 auto node = begin->second;
587 if(node == nullptr) {
588 continue;
589 }
590 for(const auto& it : node->GetMapList())
591 {
592 fCounterMap[recordTime][it.first] += it.second;
593 }
594 }
596
597#ifdef DEBUG
599 G4MoleculeTable* pMoleculeTable = G4MoleculeTable::Instance();
600 auto iter = pMoleculeTable->GetConfigurationIterator();
601 iter.reset();
602 while(iter())
603 {
604 auto conf = iter.value();
605
606 G4cout << "GlobalTime : " << G4BestUnit(fGlobalTime, "Time")
607 << " recordTime : " << G4BestUnit(recordTime, "Time") << " "
608 << conf->GetName()
609 << " number : " << fCounterMap[recordTime][conf]
610 << " MoleculeCounter : "
611 << G4MoleculeCounter::Instance()->GetCurrentNumberOf(conf)
612 << G4endl;
613
614 assert(G4MoleculeCounter::Instance()->GetCurrentNumberOf(conf) ==
615 fCounterMap[recordTime][conf]);
616 }
617#endif
618 }
619}
620
622{
623 G4cout << "fCounterMap.size : " << fCounterMap.size() << G4endl;
624
625 for(const auto& i : fCounterMap)
626 {
627 auto map = i.second;
628 auto begin = map.begin(); //
629 auto end = map.end(); //
630 for(; begin != end; begin++)
631 {
632 auto molecule = begin->first;
633 auto number = begin->second;
634 if(number == 0)
635 {
636 continue;
637 }
638 G4cout << "molecule : " << molecule->GetName() << " number : " << number
639 << G4endl;
640 }
641 }
642}
643
646{
647 return fCounterMap;
648}
649
651 std::unique_ptr<G4UserMeshAction> pUserMeshAction)
652{
653 fpUserMeshAction = std::move(pUserMeshAction);
654}
655
657
659
661{
662 auto pMolecularReactionTable = G4DNAMolecularReactionTable::Instance();
663 auto reactionDataList = pMolecularReactionTable->GetVectorOfReactionData();
664 if(reactionDataList.empty())
665 {
666 G4cout << "reactionDataList.empty()" << G4endl;
667 return true;
668 }
669 else
670 {
671 for(auto it : reactionDataList)
672 {
673 if(it->GetEffectiveReactionRadius() >= resolution / CLHEP::pi)
674 {
675 G4cout << it->GetReactant1()->GetName() << " + "
676 << it->GetReactant2()->GetName() << G4endl;
677 G4cout << "G4DNAEventScheduler::ReactionRadius : "
678 << G4BestUnit(it->GetEffectiveReactionRadius(), "Length")
679 << G4endl;
680 G4cout << "resolution : " << G4BestUnit(resolution, "Length") << G4endl;
681 return false;
682 }
683 }
684 return true;
685 }
686}
G4double C(G4double temp)
G4double D(G4double temp)
@ JustWarning
@ FatalException
@ FatalErrorInArgument
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
std::ostringstream G4ExceptionDescription
Definition: G4Exception.hh:40
G4Molecule * GetMolecule(const G4Track &track)
Definition: G4Molecule.cc:76
static constexpr double nm
Definition: G4SIunits.hh:92
static constexpr double s
Definition: G4SIunits.hh:154
static constexpr double ps
Definition: G4SIunits.hh:157
#define G4BestUnit(a, b)
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
G4GLOB_DLL std::ostream G4cerr
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
std::unique_ptr< G4DNAMesh > fpMesh
std::unique_ptr< G4DNAGillespieDirectMethod > fpGillespieReaction
static G4bool CheckingReactionRadius(G4double resolution)
std::unique_ptr< G4DNAUpdateSystemModel > fpUpdateSystem
G4DNAEventScheduler(const G4DNABoundingBox &boundingBox, G4int pixel)
void SetUserMeshAction(std::unique_ptr< G4UserMeshAction >)
std::map< G4double, MapCounter > GetCounterMap() const
void SetEndTime(const G4double &)
std::map< G4double, MapCounter > fCounterMap
std::unique_ptr< G4DNAEventSet > fpEventSet
G4double GetTimeStep() const
G4double GetEndTime() const
~G4DNAEventScheduler() override
std::set< G4double > fTimeToRecord
G4DNAMesh * GetMesh() const
G4double GetStartTime() const
void SetStartTime(G4double time)
std::map< MolType, G4int > MapCounter
void AddTimeToRecord(const G4double &time)
std::set< G4double >::iterator fLastRecoredTime
std::unique_ptr< G4UserMeshAction > fpUserMeshAction
static G4DNAMolecularReactionTable * Instance()
G4TrackList * GetMainList(Key)
static G4ITTrackHolder * Instance()
std::unique_ptr< ReactantList > RecordedMolecules
static G4MoleculeCounter * Instance()
void ResetCounter() override
int GetNMoleculesAtTime(Reactant *molecule, double time)
RecordedMolecules GetRecordedMolecules()
G4MolecularConfiguration * GetConfiguration(const G4String &, bool mustExist=true)
static G4MoleculeTable * Instance()
G4ConfigurationIterator GetConfigurationIterator()
const G4MolecularConfiguration * GetMolecularConfiguration() const
Definition: G4Molecule.cc:532
static G4Scheduler * Instance()
Definition: G4Scheduler.cc:101
G4VScavengerMaterial * GetScavengerMaterial() const
Definition: G4Scheduler.hh:194
void Stop()
void Start()
static void Use(G4bool flag=true)
static G4VMoleculeCounter * Instance()
static constexpr double pi
Definition: SystemOfUnits.h:55
T max(const T t1, const T t2)
brief Return the largest of the two arguments
#define INT_MAX
Definition: templates.hh:90
#define DBL_MAX
Definition: templates.hh:62