Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4DNAChemistryManager.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// Author: Mathieu Karamitros ([email protected])
28//
29// WARNING : This class is released as a prototype.
30// It might strongly evolve or even disappear in the next releases.
31//
32// History:
33// -----------
34// 10 Oct 2011 M.Karamitros created
35//
36// -------------------------------------------------------------------
37
39
40#include "G4Scheduler.hh"
41#include "G4SystemOfUnits.hh"
42#include "G4Molecule.hh"
43#include "G4VITTrackHolder.hh"
44#include "G4H2O.hh"
48#include "G4Electron_aq.hh"
50#include "G4VMoleculeCounter.hh"
52#include "G4AutoLock.hh"
53#include "G4UIcmdWithABool.hh"
57#include "G4GeometryManager.hh"
58#include "G4StateManager.hh"
59#include "G4MoleculeFinder.hh"
60#include "G4MoleculeTable.hh"
61#include "G4PhysChemIO.hh"
62
63
64G4DNAChemistryManager* G4DNAChemistryManager::fgInstance = nullptr;
65
66G4ThreadLocal G4DNAChemistryManager::ThreadLocalData*
67 G4DNAChemistryManager::fpThreadData = nullptr;
68
70
71//------------------------------------------------------------------------------
72
73G4DNAChemistryManager::ThreadLocalData::ThreadLocalData()
74{
75 fpPhysChemIO = nullptr;
76 fThreadInitialized = false;
77}
78
79//------------------------------------------------------------------------------
80
81G4DNAChemistryManager::ThreadLocalData::~ThreadLocalData()
82{
83 fpThreadData = nullptr;
84}
85
86//------------------------------------------------------------------------------
87
88void G4DNAChemistryManager::SetPhysChemIO(std::unique_ptr<G4VPhysChemIO> pPhysChemIO)
89{
90 fpThreadData->fpPhysChemIO = std::move(pPhysChemIO);
91}
92
93//------------------------------------------------------------------------------
94
95//------------------------------------------------------------------------------
96/*
97 * The chemistry manager is shared between threads
98 * It is initialized both on the master thread and on the worker threads
99 */
100//------------------------------------------------------------------------------
102 : G4UImessenger()
104 , fpChemDNADirectory(new G4UIdirectory("/chem/"))
105 , fpActivateChem(new G4UIcmdWithABool("/chem/activate", this))
106 , fpRunChem(new G4UIcmdWithAnInteger("/chem/run", this))
107 , fpSkipReactionsFromChemList(new G4UIcmdWithoutParameter("/chem/skipReactionsFromChemList", this))
108 , fpScaleForNewTemperature(new G4UIcmdWithADoubleAndUnit("/chem/temperature", this))
109 , fpInitChem(new G4UIcmdWithoutParameter("/chem/init", this))
110 , fActiveChemistry(false)
111 , fMasterInitialized(false)
112 , fForceThreadReinitialization(false)
113 , fpExcitationLevel(nullptr)
114 , fpIonisationLevel(nullptr)
115 , fpUserChemistryList(nullptr)
116 , fOwnChemistryList(false)
117 , fUseInStandalone(false)
118 , fPhysicsTableBuilt(false)
119 , fSkipReactions(false)
120 , fGeometryClosed(false)
121 , fVerbose(0)
122 , fResetCounterWhenRunEnds(true)
123{
124 fpRunChem->SetParameterName("Number of runs to execute for the chemistry module"
125 "(this works when used in standalone", true, true);
126 fpRunChem->SetDefaultValue(1);
127 fpScaleForNewTemperature->SetUnitCategory("Temperature");
128}
129
130//------------------------------------------------------------------------------
131
133{
134 if (fgInstance == nullptr)
135 {
137 if (fgInstance == nullptr) // MT : double check at initialisation
138 {
139 fgInstance = new G4DNAChemistryManager();
140 }
141 lock.unlock();
142 }
143
144 // make sure thread local data is initialized for all threads
145 if (fpThreadData == nullptr)
146 {
147 fpThreadData = new ThreadLocalData();
148 }
149
150 assert(fpThreadData != nullptr);
151
152 return fgInstance;
153}
154
155//------------------------------------------------------------------------------
156
158{
159 return fgInstance;
160}
161
162//------------------------------------------------------------------------------
163
165{
166 Clear();
167 fgInstance = nullptr;
168}
169
170//------------------------------------------------------------------------------
171
173{
174 fpIonisationLevel.reset();
175 fpExcitationLevel.reset();
176
177 if (fpUserChemistryList)
178 {
179 Deregister(*fpUserChemistryList);
180 }
181
182 fpChemDNADirectory.reset();
183 fpActivateChem.reset();
184 fpRunChem.reset();
185
186 fpSkipReactionsFromChemList.reset();
187 fpInitChem.reset();
188
189 if (fpThreadData != nullptr)
190 {
191 delete fpThreadData;
192 fpThreadData = nullptr;
193 }
194
198}
199
200//------------------------------------------------------------------------------
201
203{
205
206 if (fgInstance != nullptr)
207 {
208 G4DNAChemistryManager* pDeleteMe = fgInstance;
209 fgInstance = nullptr;
210 lock.unlock();
211 delete pDeleteMe;
212 }
213 else
214 {
215 G4cerr << "G4DNAChemistryManager already deleted" << G4endl;
216 }
217 lock.unlock();
218}
219
220//------------------------------------------------------------------------------
221
223{
224 if (requestedState == G4State_Quit)
225 {
226 if (fVerbose)
227 {
228 G4cout << "G4DNAChemistryManager::Notify ---> received G4State_Quit"
229 << G4endl;
230 }
231 Clear();
232 }
233 else if (requestedState == G4State_GeomClosed)
234 {
235 fGeometryClosed = true;
236 }
237 else if (requestedState == G4State_Idle)
238 {
240 }
241
242 return true;
243}
244
245//------------------------------------------------------------------------------
246
248{
249 if (pCommand == fpActivateChem.get())
250 {
252 }
253 else if (pCommand == fpRunChem.get())
254 {
255 int nbExec = value.empty() ? 1 : G4UIcommand::ConvertToInt(value);
256 for (int i = 0 ; i < nbExec ; ++i)
257 {
258 Run();
259 }
260 }
261 else if (pCommand == fpSkipReactionsFromChemList.get())
262 {
263 fSkipReactions = true;
264 }
265 else if (pCommand == fpScaleForNewTemperature.get())
266 {
267 SetGlobalTemperature(fpScaleForNewTemperature->ConvertToDimensionedDouble(value));
268 }
269 else if (pCommand == fpInitChem.get())
270 {
271 Initialize();
273 }
274}
275
276//------------------------------------------------------------------------------
277
279{
280 if (pCommand == fpActivateChem.get())
281 {
282 return G4UIcmdWithABool::ConvertToString(fActiveChemistry);
283 }
284 else if (pCommand == fpScaleForNewTemperature.get())
285 {
286 return fpScaleForNewTemperature->ConvertToStringWithBestUnit(G4MolecularConfiguration::GetGlobalTemperature());
287 }
288 else if (pCommand == fpSkipReactionsFromChemList.get())
289 {
290 return G4UIcmdWithABool::ConvertToString(fSkipReactions);
291 }
292
293 return "";
294}
295
296//------------------------------------------------------------------------------
297
299{
301 {
302 return;
303 }
304
307}
308
309//------------------------------------------------------------------------------
311{
312 if (!fActiveChemistry)
313 {
314 return;
315 }
316
318
319 if (!fMasterInitialized)
320 {
321 G4ExceptionDescription description;
322 description << "Global components were not initialized.";
323 G4Exception("G4DNAChemistryManager::Run", "MASTER_INIT", FatalException,
324 description);
325 }
326
327 if (!fpThreadData->fThreadInitialized)
328 {
329 G4ExceptionDescription description;
330 description << "Thread local components were not initialized.";
331 G4Exception("G4DNAChemistryManager::Run", "THREAD_INIT", FatalException,
332 description);
333 }
334
337 if (fResetCounterWhenRunEnds)
338 {
340 }
341 CloseFile();
342}
343
344//------------------------------------------------------------------------------
345
347{
348 fUseInStandalone = flag;
349}
350
351//------------------------------------------------------------------------------
352
354{
355 G4Scheduler::Instance()->SetGun(pChemGun);
356}
357
358//------------------------------------------------------------------------------
359
361{
362 //===========================================================================
363 // MT MODE
364 //===========================================================================
366 {
367 //==========================================================================
368 // ON WORKER THREAD
369 //==========================================================================
371 {
372 InitializeThread(); // Will create and initialize G4Scheduler
373 return;
374 }
375 //==========================================================================
376 // ON MASTER THREAD
377 //==========================================================================
378 else
379 {
382 return;
383 }
384 }
385 //===========================================================================
386 // IS NOT IN MT MODE
387 //===========================================================================
388 else
389 {
392 // In this case: InitializeThread is called when Run() is called
393 return;
394 }
395}
396
397//------------------------------------------------------------------------------
398
400{
401 if (fMasterInitialized)
402 {
403 return;
404 }
405
406 if (fVerbose)
407 {
408 G4cout << "G4DNAChemistryManager::InitializeMaster() is called" << G4endl;
409 }
410
411
412 if (fpUserChemistryList == nullptr)
413 {
414 G4ExceptionDescription description;
415 description << "No user chemistry list has been provided.";
416 G4Exception("G4DNAChemistryManager::InitializeMaster", "NO_CHEM_LIST",
417 FatalException, description);
418 }else
419 {
420 fpUserChemistryList->ConstructDissociationChannels();
421 if (!fSkipReactions)
422 {
423 fpUserChemistryList->ConstructReactionTable(G4DNAMolecularReactionTable::GetReactionTable());
424 }
425 else
426 {
428 }
429 }
430
432 // creates a concrete object of the scheduler
433 fMasterInitialized = true;
434}
435
436//------------------------------------------------------------------------------
437
439{
440 if (!fUseInStandalone || fPhysicsTableBuilt)
441 {
442 return;
443 }
444
445 if (fVerbose)
446 {
447 G4cout << "G4DNAChemistryManager: Build the physics tables for "
448 "molecule definition only."
449 << G4endl;
450 }
451
452 fpUserChemistryList->BuildPhysicsTable();
453
454 if (!fGeometryClosed)
455 {
456 if (fVerbose)
457 {
458 G4cout << "G4DNAChemistryManager: Close geometry" << G4endl;
459 }
460
462 pGeomManager->OpenGeometry();
463 pGeomManager->CloseGeometry(true, true);
464 fGeometryClosed = true;
465 }
466
467 fPhysicsTableBuilt = true;
468}
469
470//------------------------------------------------------------------------------
471
473{
474 if (fpThreadData->fThreadInitialized && !fForceThreadReinitialization)
475 {
476 return;
477 }
478
479 if (fpUserChemistryList == nullptr)
480 {
481 G4ExceptionDescription description;
482 description << "No user chemistry list has been provided.";
483 G4Exception("G4DNAChemistryManager::InitializeThread", "NO_CHEM_LIST",
484 FatalException, description);
485 }else
486 {
487 HandleStandaloneInitialization();// To make coverty happy
488 fpUserChemistryList->ConstructTimeStepModel(G4DNAMolecularReactionTable::GetReactionTable());
489 }
490
491 if (fVerbose)
492 {
493 G4cout << "G4DNAChemistryManager::InitializeThread() is called"
494 << G4endl;
495 }
496
498
499 fpThreadData->fThreadInitialized = true;
500
502
504}
505
506//------------------------------------------------------------------------------
507
509{
510 if (fVerbose)
511 {
512 G4cout << "G4DNAChemistryManager::InitializeFile() is called"
513 << G4endl;
514 }
515
516 if (fpThreadData->fpPhysChemIO)
517 {
518 fpThreadData->fpPhysChemIO->InitializeFile();
519 }
520}
521
522//------------------------------------------------------------------------------
523
525{
526 return fgInstance ? fgInstance->IsChemistryActivated() : false;
527}
528
529//------------------------------------------------------------------------------
530
532{
533 return fActiveChemistry;
534}
535
536//------------------------------------------------------------------------------
537
539{
540 fActiveChemistry = flag;
541}
542
543//------------------------------------------------------------------------------
544
546 std::ios_base::openmode mode)
547{
548 if (fVerbose)
549 {
550 G4cout << "G4DNAChemistryManager: Write chemical stage into "
551 << output.data() << G4endl;
552 }
553
554 if (!fpThreadData->fpPhysChemIO)
555 {
556 fpThreadData->fpPhysChemIO.reset(new G4PhysChemIO::FormattedText());
557 }
558
559 fpThreadData->fpPhysChemIO->WriteInto(output, mode);
560
561}
562
563//------------------------------------------------------------------------------
564
566{
567 if (fpThreadData->fpPhysChemIO)
568 {
569 fpThreadData->fpPhysChemIO->AddEmptyLineInOutputFile();
570 }
571}
572
573//------------------------------------------------------------------------------
574
576{
577 if (fpThreadData->fpPhysChemIO)
578 {
579 fpThreadData->fpPhysChemIO->CloseFile();
580 }
581}
582
583//------------------------------------------------------------------------------
584
586{
587 if (!fpExcitationLevel)
588 {
589 fpExcitationLevel.reset(new G4DNAWaterExcitationStructure);
590 }
591 return fpExcitationLevel.get();
592}
593
594//------------------------------------------------------------------------------
595
597{
598 if (!fpIonisationLevel)
599 {
600 fpIonisationLevel.reset(new G4DNAWaterIonisationStructure);
601 }
602 return fpIonisationLevel.get();
603}
604
605//------------------------------------------------------------------------------
606
608 G4int electronicLevel,
609 const G4Track* pIncomingTrack)
610{
611 if (fpThreadData->fpPhysChemIO)
612 {
613 G4double energy = -1.;
614
615 switch (modification)
616 {
618 energy = 0.;
619 break;
620 case eExcitedMolecule:
621 energy = GetExcitationLevel()->ExcitationEnergy(electronicLevel);
622 break;
623 case eIonizedMolecule:
624 energy = GetIonisationLevel()->IonisationEnergy(electronicLevel);
625 break;
626 }
627
628 fpThreadData->fpPhysChemIO->CreateWaterMolecule(modification,
629 4 - electronicLevel,
630 energy,
631 pIncomingTrack);
632 }
633
634 if (fActiveChemistry)
635 {
636 G4Molecule* pH2OMolecule = new G4Molecule(G4H2O::Definition());
637
638 switch (modification)
639 {
641 pH2OMolecule->AddElectron(5, 1);
642 break;
643 case eExcitedMolecule:
644 pH2OMolecule->ExciteMolecule(4 - electronicLevel);
645 break;
646 case eIonizedMolecule:
647 pH2OMolecule->IonizeMolecule(4 - electronicLevel);
648 break;
649 }
650
651 G4Track* pH2OTrack = pH2OMolecule->BuildTrack(picosecond,
652 pIncomingTrack->GetPosition());
653
654 pH2OTrack->SetParentID(pIncomingTrack->GetTrackID());
655 pH2OTrack->SetTrackStatus(fStopButAlive);
656 pH2OTrack->SetKineticEnergy(0.);
657 PushTrack(pH2OTrack);
658 }
659}
660
661//------------------------------------------------------------------------------
662// pFinalPosition is optional
664 G4ThreeVector* pFinalPosition)
665{
666 if (fpThreadData->fpPhysChemIO)
667 {
668 fpThreadData->fpPhysChemIO->CreateSolvatedElectron(pIncomingTrack,
669 pFinalPosition);
670 }
671
672 if (fActiveChemistry)
673 {
674 PushMolecule(std::unique_ptr<G4Molecule>(new G4Molecule(G4Electron_aq::Definition())),
675 picosecond,
676 pFinalPosition ? *pFinalPosition : pIncomingTrack->GetPosition(),
677 pIncomingTrack->GetTrackID());
678 }
679}
680
681//------------------------------------------------------------------------------
682
683void G4DNAChemistryManager::PushMolecule(std::unique_ptr<G4Molecule> pMolecule,
684 double time,
685 const G4ThreeVector& position,
686 int parentID)
687{
688 assert(fActiveChemistry
689 && "To inject chemical species, the chemistry must be activated. "
690 "Check chemistry activation before injecting species.");
691 G4Track* pTrack = pMolecule->BuildTrack(time, position);
692 pTrack->SetTrackStatus(fAlive);
693 pTrack->SetParentID(parentID);
694 pMolecule.release();
695 PushTrack(pTrack);
696}
697
698//------------------------------------------------------------------------------
699
701{
704}
705
706//------------------------------------------------------------------------------
707// [[deprecated]] : chemistry list should never be nullptr
709{
710 fpUserChemistryList.reset(pChemistryList);
711 fOwnChemistryList = false;
713}
714
716{
717 fpUserChemistryList.reset(&chemistryList);
718 fOwnChemistryList = false;
720}
721
722void G4DNAChemistryManager::SetChemistryList(std::unique_ptr<G4VUserChemistryList> pChemistryList)
723{
724 fpUserChemistryList = std::move(pChemistryList);
725 fOwnChemistryList = true;
727}
728
729//------------------------------------------------------------------------------
730
732{
733 if (fpUserChemistryList.get() == &chemistryList)
734 {
735 if (!fpUserChemistryList->IsPhysicsConstructor() || fOwnChemistryList)
736 {
737 fpUserChemistryList.reset();
738 }
739
740 fpUserChemistryList.release();
741 }
742}
743
744//------------------------------------------------------------------------------
745
747{
749}
750
751//------------------------------------------------------------------------------
752
754{
755 fVerbose = verbose;
756}
757
758//------------------------------------------------------------------------------
759
761{
762 return fResetCounterWhenRunEnds;
763}
764
765//------------------------------------------------------------------------------
766
768{
769 fResetCounterWhenRunEnds = resetCounterWhenRunEnds;
770}
771
772//------------------------------------------------------------------------------
773
775{
776 fPhysicsTableBuilt = false;
777}
778
779//------------------------------------------------------------------------------
780
782{
783 fMasterInitialized = false;
785}
786
787//------------------------------------------------------------------------------
788
790{
791 fForceThreadReinitialization = true;
792}
793
794//------------------------------------------------------------------------------
795
797{
798 fpThreadData->fThreadInitialized = false;
799}
G4ApplicationState
@ G4State_Idle
@ G4State_Quit
@ G4State_GeomClosed
G4Mutex chemManExistence
ElectronicModification
@ eIonizedMolecule
@ eDissociativeAttachment
@ eExcitedMolecule
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:59
std::ostringstream G4ExceptionDescription
Definition: G4Exception.hh:40
std::mutex G4Mutex
Definition: G4Threading.hh:81
@ fAlive
@ fStopButAlive
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
void SetPhysChemIO(std::unique_ptr< G4VPhysChemIO > pPhysChemIO)
G4String GetCurrentValue(G4UIcommand *pCommand) override
G4bool IsCounterResetWhenRunEnds() const
void CreateSolvatedElectron(const G4Track *, G4ThreeVector *pFinalPosition=nullptr)
static G4DNAChemistryManager * GetInstanceIfExists()
static G4DNAChemistryManager * Instance()
void UseAsStandalone(G4bool flag)
void SetChemistryList(G4VUserChemistryList &)
void PushMolecule(std::unique_ptr< G4Molecule > pMolecule, G4double time, const G4ThreeVector &position, G4int parentID)
void ResetCounterWhenRunEnds(G4bool resetCounterWhenRunEnds)
void SetGlobalTemperature(G4double temperatureKelvin)
void SetGun(G4ITGun *pChemSpeciesGun)
Inject custom species to the simulation.
G4DNAWaterIonisationStructure * GetIonisationLevel()
void Deregister(G4VUserChemistryList &)
G4DNAWaterExcitationStructure * GetExcitationLevel()
void SetNewValue(G4UIcommand *, G4String) override
G4bool Notify(G4ApplicationState requestedState) override
void SetVerbose(G4int verbose)
void WriteInto(const G4String &, std::ios_base::openmode mode=std::ios_base::out)
void CreateWaterMolecule(ElectronicModification, G4int, const G4Track *)
static G4DNAMolecularReactionTable * GetReactionTable()
static G4DNAMolecularReactionTable * Instance()
void ScaleReactionRateForNewTemperature(double temp_K)
static G4Electron_aq * Definition()
static G4GeometryManager * GetInstance()
G4bool CloseGeometry(G4bool pOptimise=true, G4bool verbose=false, G4VPhysicalVolume *vol=nullptr)
void OpenGeometry(G4VPhysicalVolume *vol=nullptr)
static G4H2O * Definition()
Definition: G4H2O.cc:42
virtual void Push(G4Track *)
static G4ITTrackHolder * Instance()
static void SetGlobalTemperature(G4double)
void Finalize(G4MoleculeDefinition *)
void PrepareMolecularConfiguration()
static G4MoleculeTable * Instance()
void IonizeMolecule(G4int)
Definition: G4Molecule.cc:306
void AddElectron(G4int orbit, G4int n=1)
Definition: G4Molecule.cc:313
G4Track * BuildTrack(G4double globalTime, const G4ThreeVector &Position)
Definition: G4Molecule.cc:371
void ExciteMolecule(G4int)
Definition: G4Molecule.cc:299
void SetGun(G4ITGun *)
Definition: G4Scheduler.hh:431
static G4Scheduler * Instance()
Definition: G4Scheduler.cc:101
void Process()
Definition: G4Scheduler.cc:379
void Initialize()
Definition: G4Scheduler.cc:284
void SetTrackStatus(const G4TrackStatus aTrackStatus)
G4int GetTrackID() const
const G4ThreeVector & GetPosition() const
void SetKineticEnergy(const G4double aValue)
void SetParentID(const G4int aValue)
static G4bool GetNewBoolValue(const char *paramString)
static G4String ConvertToString(G4bool boolVal)
Definition: G4UIcommand.cc:446
static G4int ConvertToInt(const char *st)
Definition: G4UIcommand.cc:561
static void InitializeInstance()
static void DeleteInstance()
static G4VMoleculeCounter * Instance()
virtual void ResetCounter()=0
G4bool IsWorkerThread()
Definition: G4Threading.cc:123
G4bool IsMultithreadedApplication()
Definition: G4Threading.cc:130
G4bool IsMasterThread()
Definition: G4Threading.cc:124
#define G4ThreadLocal
Definition: tls.hh:77