Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4DNAMolecularReactionTable.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 (kara (AT) cenbg . in2p3 . fr)
28//
29// WARNING : This class is released as a prototype.
30// It might strongly evolve or even disapear in the next releases.
31//
32// History:
33// -----------
34// 10 Oct 2011 M.Karamitros created
35//
36// -------------------------------------------------------------------
37
38#include <iomanip>
39
42#include "G4SystemOfUnits.hh"
43#include "G4UIcommand.hh"
46#include "G4MoleculeTable.hh"
49#include "G4IosFlagsSaver.hh"
50#include "G4Exp.hh"
51
52using namespace std;
53
55
57 : fpReactant1(nullptr)
58 , fpReactant2(nullptr)
59 , fObservedReactionRate(0.)
60 , fActivationRate(0.)
61 , fDiffusionRate(0.)
62 , fOnsagerRadius(0.)
63 , fReactionRadius(0.)
64 , fEffectiveReactionRadius(0.)
65 , fProbability(0.)
66 , fType(0)
67 , fReactionID(0)
68{
69}
70
72 Reactant* pReactant1,
73 Reactant* pReactant2)
74 : fpReactant1(pReactant1)
75 , fpReactant2(pReactant2)
76 , fObservedReactionRate(reactionRate)
77 , fActivationRate(0.)
78 , fDiffusionRate(0.)
79 , fOnsagerRadius(0.)
80 , fReactionRadius(0.)
81 , fEffectiveReactionRadius(0.)
82 , fProbability(0.)
83 , fType(0)
84 , fReactionID(0)
85{
87}
88
90 const G4String& reactant1,
91 const G4String& reactant2)
92 : fpReactant1(nullptr)
93 , fpReactant2(nullptr)
94 , fObservedReactionRate(reactionRate)
95 , fActivationRate(0.)
96 , fDiffusionRate(0.)
97 , fOnsagerRadius(0.)
98 , fReactionRadius(0.)
99 , fEffectiveReactionRadius(0.)
100 , fProbability(0.)
101 , fType(0)
102 , fReactionID(0)
103{
104 SetReactant1(reactant1);
105 SetReactant2(reactant2);
107}
108
110{
111 fProducts.clear();
112}
113
115{
116 G4double sumDiffCoeff = 0.;
117
119 {
120 sumDiffCoeff = fpReactant1->GetDiffusionCoefficient();
121 fEffectiveReactionRadius = fObservedReactionRate / (4. * CLHEP::pi * sumDiffCoeff * CLHEP::Avogadro);
122 }
123 else
124 {
125 sumDiffCoeff = fpReactant1->GetDiffusionCoefficient()
127 fEffectiveReactionRadius = fObservedReactionRate / (4. * CLHEP::pi * sumDiffCoeff * CLHEP::Avogadro);
128 }
129
130 fReactionID = 0;
132 fOnsagerRadius = (fpReactant1->GetCharge() * fpReactant2->GetCharge())/(4*pi*epsilon0*k_Boltzmann) / (293.15 * 80.1) ;
133 fProbability = 1;
134
135}
136
138{
139 return fReactionID;
140}
141
143{
144 fReactionID = ID;
145}
146
148{
149 fpReactant1 = pReactive;
150}
151
153{
154 fpReactant2 = pReactive;
155}
156
158 Reactant* pReactant2)
159{
160 fpReactant1 = pReactant1;
161 fpReactant2 = pReactant2;
162}
163
165{
166 fProducts.push_back(pMolecule);
167}
168
170{
171 return (G4int)fProducts.size();
172}
173
175{
176 return fProducts[i];
177}
178
180{
181 return &fProducts;
182}
183
185{
186 fProducts.clear();
187}
188
190{
192}
194{
196}
198 const G4String& reactant2)
199{
202}
203
205{
206 return std::make_pair(fpReactant1, fpReactant2);
207}
208
210{
211 return fpReactant1;
212}
213
215{
216 return fpReactant2;
217}
218
220{
222}
223
225{
227}
228
230{
231 return fActivationRate;
232}
233
235{
236 return fDiffusionRate;
237}
238
240{
241 fReactionRadius = radius;
243}
244
246{
247 return fReactionRadius;
248}
249
251{
253}
254
256{
258}
259
261{
262 return fOnsagerRadius;
263}
264
266{
267 return fProbability;
268}
269
271{
272 fProbability = prob;
273}
274
276{
277 G4double sumDiffCoeff = 0.;
278
279 if(type == 1)
280 {
281
282 sumDiffCoeff = fpReactant1->GetDiffusionCoefficient() +
284
287
288 G4double Rs = 0.29 * nm;
289 if(fOnsagerRadius == 0) // Type II
290 {
292 fDiffusionRate = 4 * pi * sumDiffCoeff * fReactionRadius * Avogadro;
296
297 }else{ // Type IV
299 fDiffusionRate = 4 * pi * sumDiffCoeff * fEffectiveReactionRadius * Avogadro;
301
304 }
305 }
306
307 fType = type;
308}
309
311{
312 return fType;
313}
314
316{
317 fProducts.push_back(G4MoleculeTable::Instance()->GetConfiguration(molecule));
318}
319
320double G4DNAMolecularReactionData::PolynomialParam(double temp_K, std::vector<double> P)
321{
322 double inv_temp = 1. / temp_K;
323
324 return pow(10,
325 P[0] + P[1] * inv_temp + P[2] * pow(inv_temp, 2)
326 + P[3] * pow(inv_temp, 3) + P[4] * pow(inv_temp, 4))
327 * (1e-3 * CLHEP::m3 / (CLHEP::mole * CLHEP::s));
328}
329
330double G4DNAMolecularReactionData::ArrehniusParam(double temp_K, std::vector<double> P)
331{
332 return P[0] * G4Exp(P[1] / temp_K)*
333 (1e-3 * CLHEP::m3 / (CLHEP::mole * CLHEP::s));
334}
335
337 double temp_init,
338 double rateCste_init)
339{
340 double D0 = G4MolecularConfiguration::DiffCoeffWater(temp_init);
342 return Df * rateCste_init / D0;
343}
344
345//==============================================================================
346// REACTION TABLE
347//==============================================================================
348
350{
351 if (!fpInstance)
352 {
354 }
355 return fpInstance;
356}
357
358//_____________________________________________________________________________________
359
361{
362 if (!fpInstance)
363 {
365 }
366 return fpInstance;
367}
368
369//_____________________________________________________________________________________
370
372{
373 if (fpInstance)
374 {
375 delete fpInstance;
376 }
377 fpInstance = nullptr;
378}
379
380//_____________________________________________________________________________________
381
384 , fVerbose(false)
385 , fGeometry(nullptr)
386 , fpMessenger(new G4ReactionTableMessenger(this))
387{
388}
389
391
393{
394 const auto pReactant1 = pReactionData->GetReactant1();
395 const auto pReactant2 = pReactionData->GetReactant2();
396
397 fReactionData[pReactant1][pReactant2] = pReactionData;
398 fReactantsMV[pReactant1].push_back(pReactant2);
399 fReactionDataMV[pReactant1].push_back(pReactionData);
400
401 if (pReactant1 != pReactant2)
402 {
403 fReactionData[pReactant2][pReactant1] = pReactionData;
404 fReactantsMV[pReactant2].push_back(pReactant1);
405 fReactionDataMV[pReactant2].push_back(pReactionData);
406 }
407
408 fVectorOfReactionData.emplace_back(pReactionData);
409 pReactionData->SetReactionID((G4int)fVectorOfReactionData.size());
410}
411
412//_____________________________________________________________________________________
413
415 Reactant* pReactant1,
416 Reactant* pReactant2)
417{
418 auto reactionData = new G4DNAMolecularReactionData(reactionRate, pReactant1, pReactant2);
419 SetReaction(reactionData);
420}
421
422//_____________________________________________________________________________________
423
425{
426 // Print Reactions and Interaction radius for jump step = 3ps
427
428 G4IosFlagsSaver iosfs(G4cout);
429
430 if (pReactionModel && !(pReactionModel->GetReactionTable()))
431 {
432 pReactionModel->SetReactionTable(this);
433 }
434
435 ReactivesMV::iterator itReactives;
436
437 std::map<Reactant*, std::map<Reactant*, G4bool>> alreadyPrint;
438
439 G4cout << "Number of chemical species involved in reactions = "
440 << fReactantsMV.size() << G4endl;
441
442 std::size_t nbPrintable = fReactantsMV.size() * fReactantsMV.size();
443
444 G4String* outputReaction = new G4String[nbPrintable];
445 G4String* outputReactionRate = new G4String[nbPrintable];
446 G4String* outputRange = new G4String[nbPrintable];
447 G4int n = 0;
448
449 for (itReactives = fReactantsMV.begin(); itReactives != fReactantsMV.end();
450 ++itReactives)
451 {
452 Reactant* moleculeA = (Reactant*)itReactives->first;
453 const vector<Reactant*>* reactivesVector = CanReactWith(moleculeA);
454
455 if (pReactionModel) pReactionModel->InitialiseToPrint(moleculeA);
456
457 G4int nbReactants = (G4int)fReactantsMV[itReactives->first].size();
458
459 for (G4int iReact = 0; iReact < nbReactants; iReact++)
460 {
461 auto moleculeB = (Reactant*)(*reactivesVector)[iReact];
462
463 Data* reactionData = fReactionData[moleculeA][moleculeB];
464
465 //-----------------------------------------------------------
466 // Name of the reaction
467 if (!alreadyPrint[moleculeA][moleculeB])
468 {
469 outputReaction[n] = moleculeA->GetName() + " + " + moleculeB->GetName();
470
471 G4int nbProducts = reactionData->GetNbProducts();
472
473 if (nbProducts)
474 {
475 outputReaction[n] += " -> " + reactionData->GetProduct(0)->GetName();
476
477 for (G4int j = 1; j < nbProducts; j++)
478 {
479 outputReaction[n] += " + " + reactionData->GetProduct(j)->GetName();
480 }
481 }
482 else
483 {
484 outputReaction[n] += " -> No product";
485 }
486
487 //-----------------------------------------------------------
488 // Interaction Rate
489 outputReactionRate[n] = G4UIcommand::ConvertToString(
490 reactionData->GetObservedReactionRateConstant() / (1e-3 * m3 / (mole * s)));
491
492 //-----------------------------------------------------------
493 // Calculation of the Interaction Range
494 G4double interactionRange = -1;
495 if (pReactionModel) interactionRange =
496 pReactionModel->GetReactionRadius(iReact);
497
498 if (interactionRange != -1)
499 {
500 outputRange[n] = G4UIcommand::ConvertToString(
501 interactionRange / nanometer);
502 }
503 else
504 {
505 outputRange[n] = "";
506 }
507
508 alreadyPrint[moleculeB][moleculeA] = TRUE;
509 n++;
510 }
511 }
512 }
513 // G4cout<<"Number of possible reactions: "<< n << G4endl;
514
515 ////////////////////////////////////////////////////////////////////
516 // Tableau dynamique en fonction du nombre de caractere maximal dans
517 // chaque colonne
518 ////////////////////////////////////////////////////////////////////
519
520 G4int maxlengthOutputReaction = -1;
521 G4int maxlengthOutputReactionRate = -1;
522
523 for (G4int i = 0; i < n; ++i)
524 {
525 if (maxlengthOutputReaction < (G4int)outputReaction[i].length())
526 {
527 maxlengthOutputReaction = (G4int)outputReaction[i].length();
528 }
529 if (maxlengthOutputReactionRate < (G4int)outputReactionRate[i].length())
530 {
531 maxlengthOutputReactionRate = (G4int)outputReactionRate[i].length();
532 }
533 }
534
535 maxlengthOutputReaction += 2;
536 maxlengthOutputReactionRate += 2;
537
538 if (maxlengthOutputReaction < 10) maxlengthOutputReaction = 10;
539 if (maxlengthOutputReactionRate < 30) maxlengthOutputReactionRate = 30;
540
541 G4String* title;
542
543 if (pReactionModel) title = new G4String[3];
544 else title = new G4String[2];
545
546 title[0] = "Reaction";
547 title[1] = "Reaction Rate [dm3/(mol*s)]";
548
549 if (pReactionModel) title[2] =
550 "Interaction Range for chosen reaction model [nm]";
551
552 G4cout << setfill(' ') << setw(maxlengthOutputReaction) << left << title[0]
553 << setw(maxlengthOutputReactionRate) << left << title[1];
554
555 if (pReactionModel) G4cout << setw(2) << left << title[2];
556
557 G4cout << G4endl;
558
559 G4cout.fill('-');
560 if (pReactionModel) G4cout.width(
561 maxlengthOutputReaction + 2 + maxlengthOutputReactionRate + 2
562 + (G4int)title[2].length());
563 else G4cout.width(maxlengthOutputReaction + 2 + maxlengthOutputReactionRate);
564 G4cout << "-" << G4endl;
565 G4cout.fill(' ');
566
567 for (G4int i = 0; i < n; i++)
568 {
569 G4cout << setw(maxlengthOutputReaction) << left << outputReaction[i]
570 << setw(maxlengthOutputReactionRate) << left
571 << outputReactionRate[i];
572
573 if (pReactionModel) G4cout << setw(2) << left << outputRange[i];
574
575 G4cout << G4endl;
576
577 G4cout.fill('-');
578 if (pReactionModel) G4cout.width(
579 maxlengthOutputReaction + 2 + maxlengthOutputReactionRate + 2
580 + (G4int)title[2].length());
581 else G4cout.width(
582 maxlengthOutputReaction + 2 + maxlengthOutputReactionRate);
583 G4cout << "-" << G4endl;
584 G4cout.fill(' ');
585 }
586
587 delete[] title;
588 delete[] outputReaction;
589 delete[] outputReactionRate;
590 delete[] outputRange;
591}
592
593//______________________________________________________________________________
594// Get/Set methods
595
597{
598 return fGeometry;
599}
600
603 Reactant* pReactant2) const
604{
605 if (fReactionData.empty())
606 {
607 G4String errMsg = "No reaction table was implemented";
608 G4Exception("G4MolecularInteractionTable::GetReactionData", "",
609 FatalErrorInArgument, errMsg);
610 }
611
612 auto it1 = fReactionData.find(pReactant1);
613
614 if (it1 == fReactionData.end())
615 {
616 G4String errMsg =
617 "No reaction table was implemented for this molecule Definition : " + pReactant1
618 ->GetName();
619 G4Exception("G4MolecularInteractionTable::GetReactionData", "",
620 FatalErrorInArgument, errMsg);
621 }
622
623 ReactionDataMap::mapped_type::const_iterator it2 = it1->second.find(pReactant2);
624
625 if (it2 == it1->second.end())
626 {
627 G4cout << "Name : " << pReactant2->GetName() << G4endl;
628 G4String errMsg = "No reaction table was implemented for this molecule : "
629 + pReactant2->GetName();
630 G4Exception("G4MolecularInteractionTable::GetReactionData", "", FatalErrorInArgument, errMsg);
631 }
632
633 return (it2->second);
634}
635
637{
638 return fReactionData;
639}
640
642{
643 DataList dataList;
644
645 for (const auto& pData : fVectorOfReactionData)
646 {
647 dataList.emplace_back(pData.get());
648 }
649
650 return dataList;
651}
652
653//______________________________________________________________________________
654
657{
658 if (fReactantsMV.empty())
659 {
660 G4String errMsg = "No reaction table was implemented";
661 G4Exception("G4MolecularInteractionTable::CanReactWith", "",
662 FatalErrorInArgument, errMsg);
663 return 0;
664 }
665
666 auto itReactivesMap = fReactantsMV.find(pMolecule);
667
668 if (itReactivesMap == fReactantsMV.end())
669 {
670#ifdef G4VERBOSE
671 if (fVerbose)
672 {
673 G4String errMsg = "No reaction table was implemented for this molecule : "
674 + pMolecule->GetName();
675 // G4Exception("G4MolecularInteractionTable::CanReactWith","",FatalErrorInArgument, errMsg);
676 G4cout << "--- G4MolecularInteractionTable::GetReactionData ---" << G4endl;
677 G4cout << errMsg << G4endl;
678 }
679#endif
680 return nullptr;
681 }
682
683 if (fVerbose)
684 {
685 G4cout << " G4MolecularInteractionTable::CanReactWith :" << G4endl;
686 G4cout << "You are checking reactants for : " << pMolecule->GetName() << G4endl;
687 G4cout << " the number of reactants is : " << itReactivesMap->second.size() << G4endl;
688
689 auto itProductsVector = itReactivesMap->second.cbegin();
690
691 for (; itProductsVector != itReactivesMap->second.end(); itProductsVector++)
692 {
693 G4cout << (*itProductsVector)->GetName() << G4endl;
694 }
695 }
696 return &(itReactivesMap->second);
697}
698
699//______________________________________________________________________________
700
703{
704 if (fReactionData.empty())
705 {
706 G4String errMsg = "No reaction table was implemented";
707 G4Exception("G4MolecularInteractionTable::CanInteractWith", "",
708 FatalErrorInArgument, errMsg);
709 }
710
711 ReactionDataMap::const_iterator itReactivesMap = fReactionData.find(molecule);
712
713 if (itReactivesMap == fReactionData.end())
714 {
715 return nullptr;
716 }
717
718 if (fVerbose)
719 {
720 G4cout << " G4MolecularInteractionTable::CanReactWith :" << G4endl;
721 G4cout << "You are checking reactants for : " << molecule->GetName() << G4endl;
722 G4cout << " the number of reactants is : " << itReactivesMap->second.size() << G4endl;
723
724 SpecificDataList::const_iterator itProductsVector = itReactivesMap->second.begin();
725
726 for (; itProductsVector != itReactivesMap->second.end(); itProductsVector++)
727 {
728 G4cout << itProductsVector->first->GetName() << G4endl;
729 }
730 }
731 return &(itReactivesMap->second);
732}
733
734//______________________________________________________________________________
735
738{
739 if (fReactionDataMV.empty())
740 {
741 G4String errMsg = "No reaction table was implemented";
742 G4Exception("G4MolecularInteractionTable::CanInteractWith", "",
743 FatalErrorInArgument, errMsg);
744 }
745 auto it = fReactionDataMV.find(molecule);
746
747 if (it == fReactionDataMV.end())
748 {
749 G4String errMsg = "No reaction table was implemented for this molecule Definition : "
750 + molecule->GetName();
751 G4Exception("G4MolecularInteractionTable::GetReactionData", "", FatalErrorInArgument, errMsg);
752 }
753
754 return &(it->second);
755}
756
757//______________________________________________________________________________
758
760 const G4String& mol2) const
761{
762 const auto pConf1 = G4MoleculeTable::GetMoleculeTable()->GetConfiguration(mol1);
763 const auto pConf2 = G4MoleculeTable::GetMoleculeTable()->GetConfiguration(mol2);
764 return GetReactionData(pConf1, pConf2);
765}
766
767//______________________________________________________________________________
768
769void
771{
772 fRateParam = std::bind(PolynomialParam, std::placeholders::_1, P);
773}
774
775//______________________________________________________________________________
776
778 double E_R)
779{
780 std::vector<double> P = { A0, E_R };
781 fRateParam = std::bind(ArrehniusParam, std::placeholders::_1, P);
782}
783
784//______________________________________________________________________________
785
787 double rateCste)
788{
790 std::placeholders::_1,
791 temperature_K,
792 rateCste);
793}
794
795//______________________________________________________________________________
796
798{
799 for (const auto& pData : fVectorOfReactionData)
800 {
801 const_cast<G4DNAMolecularReactionData*>(pData.get())->ScaleForNewTemperature(temp_K);
802 }
803}
804
805//______________________________________________________________________________
806
808{
809 if (fRateParam)
810 {
812 }
813}
814
815//______________________________________________________________________________
816
819{
820 for (auto& pData : fVectorOfReactionData)
821 {
822 if (pData->GetReactionID() == reactionID)
823 {
824 return pData.get();
825 }
826 }
827 return nullptr;
828}
829
831{
832 return fVectorOfReactionData.size();
833}
834
836{
837 fReactionData.clear();
838 fReactantsMV.clear();
839 fReactionDataMV.clear();
840 fVectorOfReactionData.clear();
841}
@ FatalErrorInArgument
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:59
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
Definition: G4Exp.hh:180
double G4double
Definition: G4Types.hh:83
int G4int
Definition: G4Types.hh:85
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
Reactant * GetProduct(G4int i) const
void SetPolynomialParameterization(const std::vector< double > &P)
std::pair< Reactant *, Reactant * > ReactantPair
static double ArrehniusParam(double temp_K, std::vector< double > P)
void SetEffectiveReactionRadius(G4double radius)
void SetArrehniusParameterization(double A0, double E_R)
std::vector< Reactant * > ReactionProducts
void SetReactants(Reactant *reactive1, Reactant *reactive2)
const ReactionProducts * GetProducts() const
void SetObservedReactionRateConstant(G4double rate)
static double PolynomialParam(double temp_K, std::vector< double > P)
void SetScaledParameterization(double temperature_K, double rateCste)
static double ScaledParameterization(double temp_K, double temp_init, double rateCste_init)
std::map< Reactant *, Data * > SpecificDataList
static G4DNAMolecularReactionTable * GetReactionTable()
std::vector< Reactant * > ReactantList
Data * GetReactionData(Reactant *, Reactant *) const
static G4DNAMolecularReactionTable * Instance()
const ReactantList * CanReactWith(Reactant *) const
std::map< Reactant *, SpecificDataList > ReactionDataMap
Data * GetReaction(int reactionID) const
const SpecificDataList * GetReativesNData(const G4MolecularConfiguration *) const
G4VDNAMolecularGeometry * GetGeometry() const
void PrintTable(G4VDNAReactionModel *=0)
std::vector< std::unique_ptr< Data > > fVectorOfReactionData
const ReactionDataMap & GetAllReactionData()
static G4DNAMolecularReactionTable * fpInstance
void SetReaction(G4double observedReactionRate, Reactant *reactive1, Reactant *reactive2)
void ScaleReactionRateForNewTemperature(double temp_K)
virtual ~G4DNAMolecularReactionTable()
const G4String & GetName() const
static double DiffCoeffWater(double temperature_K)
static G4MoleculeTable * GetMoleculeTable()
G4MolecularConfiguration * GetConfiguration(const G4String &, bool mustExist=true)
static G4MoleculeTable * Instance()
static G4String ConvertToString(G4bool boolVal)
Definition: G4UIcommand.cc:446
virtual void InitialiseToPrint(const G4MolecularConfiguration *)=0
const G4DNAMolecularReactionTable * GetReactionTable()
void SetReactionTable(const G4DNAMolecularReactionTable *)
virtual G4double GetReactionRadius(const G4MolecularConfiguration *, const G4MolecularConfiguration *)=0
#define TRUE
Definition: globals.hh:41