Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
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{
86 ComputeEffectiveRadius();
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);
106 ComputeEffectiveRadius();
107}
108
110{
111 fProducts.clear();
112}
113
114void G4DNAMolecularReactionData::ComputeEffectiveRadius()
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 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 , fpMessenger(new G4ReactionTableMessenger(this))
386{
387}
388
390
392{
393 const auto pReactant1 = pReactionData->GetReactant1();
394 const auto pReactant2 = pReactionData->GetReactant2();
395
396 fReactionData[pReactant1][pReactant2] = pReactionData;
397 fReactantsMV[pReactant1].push_back(pReactant2);
398 fReactionDataMV[pReactant1].push_back(pReactionData);
399
400 if (pReactant1 != pReactant2)
401 {
402 fReactionData[pReactant2][pReactant1] = pReactionData;
403 fReactantsMV[pReactant2].push_back(pReactant1);
404 fReactionDataMV[pReactant2].push_back(pReactionData);
405 }
406
407 fVectorOfReactionData.emplace_back(pReactionData);
408 pReactionData->SetReactionID(fVectorOfReactionData.size());
409}
410
411//_____________________________________________________________________________________
412
414 Reactant* pReactant1,
415 Reactant* pReactant2)
416{
417 auto reactionData = new G4DNAMolecularReactionData(reactionRate, pReactant1, pReactant2);
418 SetReaction(reactionData);
419}
420
421//_____________________________________________________________________________________
422
424{
425 // Print Reactions and Interaction radius for jump step = 3ps
426
427 G4IosFlagsSaver iosfs(G4cout);
428
429 if (pReactionModel && !(pReactionModel->GetReactionTable()))
430 {
431 pReactionModel->SetReactionTable(this);
432 }
433
434 ReactivesMV::iterator itReactives;
435
436 std::map<Reactant*, std::map<Reactant*, G4bool>> alreadyPrint;
437
438 G4cout << "Number of chemical species involved in reactions = "
439 << fReactantsMV.size() << G4endl;
440
441 G4int nbPrintable = fReactantsMV.size() * fReactantsMV.size();
442
443 G4String* outputReaction = new G4String[nbPrintable];
444 G4String* outputReactionRate = new G4String[nbPrintable];
445 G4String* outputRange = new G4String[nbPrintable];
446 G4int n = 0;
447
448 for (itReactives = fReactantsMV.begin(); itReactives != fReactantsMV.end();
449 itReactives++)
450 {
451 Reactant* moleculeA = (Reactant*)itReactives->first;
452 const vector<Reactant*>* reactivesVector = CanReactWith(moleculeA);
453
454 if (pReactionModel) pReactionModel->InitialiseToPrint(moleculeA);
455
456 G4int nbReactants = fReactantsMV[itReactives->first].size();
457
458 for (G4int iReact = 0; iReact < nbReactants; iReact++)
459 {
460 auto moleculeB = (Reactant*)(*reactivesVector)[iReact];
461
462 Data* reactionData = fReactionData[moleculeA][moleculeB];
463
464 //-----------------------------------------------------------
465 // Name of the reaction
466 if (!alreadyPrint[moleculeA][moleculeB])
467 {
468 outputReaction[n] = moleculeA->GetName() + " + " + moleculeB->GetName();
469
470 G4int nbProducts = reactionData->GetNbProducts();
471
472 if (nbProducts)
473 {
474 outputReaction[n] += " -> " + reactionData->GetProduct(0)->GetName();
475
476 for (G4int j = 1; j < nbProducts; j++)
477 {
478 outputReaction[n] += " + " + reactionData->GetProduct(j)->GetName();
479 }
480 }
481 else
482 {
483 outputReaction[n] += " -> No product";
484 }
485
486 //-----------------------------------------------------------
487 // Interaction Rate
488 outputReactionRate[n] = G4UIcommand::ConvertToString(
489 reactionData->GetObservedReactionRateConstant() / (1e-3 * m3 / (mole * s)));
490
491 //-----------------------------------------------------------
492 // Calculation of the Interaction Range
493 G4double interactionRange = -1;
494 if (pReactionModel) interactionRange =
495 pReactionModel->GetReactionRadius(iReact);
496
497 if (interactionRange != -1)
498 {
499 outputRange[n] = G4UIcommand::ConvertToString(
500 interactionRange / nanometer);
501 }
502 else
503 {
504 outputRange[n] = "";
505 }
506
507 alreadyPrint[moleculeB][moleculeA] = TRUE;
508 n++;
509 }
510 }
511 }
512 // G4cout<<"Number of possible reactions: "<< n << G4endl;
513
514 ////////////////////////////////////////////////////////////////////
515 // Tableau dynamique en fonction du nombre de caractere maximal dans
516 // chaque colonne
517 ////////////////////////////////////////////////////////////////////
518
519 G4int maxlengthOutputReaction = -1;
520 G4int maxlengthOutputReactionRate = -1;
521
522 for (G4int i = 0; i < n; i++)
523 {
524 if (maxlengthOutputReaction < (G4int)outputReaction[i].length())
525 {
526 maxlengthOutputReaction = outputReaction[i].length();
527 }
528 if (maxlengthOutputReactionRate < (G4int)outputReactionRate[i].length())
529 {
530 maxlengthOutputReactionRate = outputReactionRate[i].length();
531 }
532 }
533
534 maxlengthOutputReaction += 2;
535 maxlengthOutputReactionRate += 2;
536
537 if (maxlengthOutputReaction < 10) maxlengthOutputReaction = 10;
538 if (maxlengthOutputReactionRate < 30) maxlengthOutputReactionRate = 30;
539
540 G4String* title;
541
542 if (pReactionModel) title = new G4String[3];
543 else title = new G4String[2];
544
545 title[0] = "Reaction";
546 title[1] = "Reaction Rate [dm3/(mol*s)]";
547
548 if (pReactionModel) title[2] =
549 "Interaction Range for chosen reaction model [nm]";
550
551 G4cout << setfill(' ') << setw(maxlengthOutputReaction) << left << title[0]
552 << setw(maxlengthOutputReactionRate) << left << title[1];
553
554 if (pReactionModel) G4cout << setw(2) << left << title[2];
555
556 G4cout << G4endl;
557
558 G4cout.fill('-');
559 if (pReactionModel) G4cout.width(
560 maxlengthOutputReaction + 2 + maxlengthOutputReactionRate + 2
561 + (G4int)title[2].length());
562 else G4cout.width(maxlengthOutputReaction + 2 + maxlengthOutputReactionRate);
563 G4cout << "-" << G4endl;
564 G4cout.fill(' ');
565
566 for (G4int i = 0; i < n; i++)
567 {
568 G4cout << setw(maxlengthOutputReaction) << left << outputReaction[i]
569 << setw(maxlengthOutputReactionRate) << left
570 << outputReactionRate[i];
571
572 if (pReactionModel) G4cout << setw(2) << left << outputRange[i];
573
574 G4cout << G4endl;
575
576 G4cout.fill('-');
577 if (pReactionModel) G4cout.width(
578 maxlengthOutputReaction + 2 + maxlengthOutputReactionRate + 2
579 + (G4int)title[2].length());
580 else G4cout.width(
581 maxlengthOutputReaction + 2 + maxlengthOutputReactionRate);
582 G4cout << "-" << G4endl;
583 G4cout.fill(' ');
584 }
585
586 delete[] title;
587 delete[] outputReaction;
588 delete[] outputReactionRate;
589 delete[] outputRange;
590}
591
592//______________________________________________________________________________
593// Get/Set methods
594
597 Reactant* pReactant2) const
598{
599 if (fReactionData.empty())
600 {
601 G4String errMsg = "No reaction table was implemented";
602 G4Exception("G4MolecularInteractionTable::GetReactionData", "",
603 FatalErrorInArgument, errMsg);
604 }
605
606 auto it1 = fReactionData.find(pReactant1);
607
608 if (it1 == fReactionData.end())
609 {
610 G4String errMsg =
611 "No reaction table was implemented for this molecule Definition : " + pReactant1
612 ->GetName();
613 G4Exception("G4MolecularInteractionTable::GetReactionData", "",
614 FatalErrorInArgument, errMsg);
615 }
616
617 ReactionDataMap::mapped_type::const_iterator it2 = it1->second.find(pReactant2);
618
619 if (it2 == it1->second.end())
620 {
621 G4cout << "Name : " << pReactant2->GetName() << G4endl;
622 G4String errMsg = "No reaction table was implemented for this molecule : "
623 + pReactant2->GetName();
624 G4Exception("G4MolecularInteractionTable::GetReactionData", "", FatalErrorInArgument, errMsg);
625 }
626
627 return (it2->second);
628}
629
631{
632 return fReactionData;
633}
634
636{
637 DataList dataList;
638
639 for (const auto& pData : fVectorOfReactionData)
640 {
641 dataList.emplace_back(pData.get());
642 }
643
644 return dataList;
645}
646
647//______________________________________________________________________________
648
651{
652 if (fReactantsMV.empty())
653 {
654 G4String errMsg = "No reaction table was implemented";
655 G4Exception("G4MolecularInteractionTable::CanReactWith", "",
656 FatalErrorInArgument, errMsg);
657 return 0;
658 }
659
660 auto itReactivesMap = fReactantsMV.find(pMolecule);
661
662 if (itReactivesMap == fReactantsMV.end())
663 {
664#ifdef G4VERBOSE
665 if (fVerbose)
666 {
667 G4String errMsg = "No reaction table was implemented for this molecule : "
668 + pMolecule->GetName();
669 // G4Exception("G4MolecularInteractionTable::CanReactWith","",FatalErrorInArgument, errMsg);
670 G4cout << "--- G4MolecularInteractionTable::GetReactionData ---" << G4endl;
671 G4cout << errMsg << G4endl;
672 }
673#endif
674 return nullptr;
675 }
676
677 if (fVerbose)
678 {
679 G4cout << " G4MolecularInteractionTable::CanReactWith :" << G4endl;
680 G4cout << "You are checking reactants for : " << pMolecule->GetName() << G4endl;
681 G4cout << " the number of reactants is : " << itReactivesMap->second.size() << G4endl;
682
683 auto itProductsVector = itReactivesMap->second.cbegin();
684
685 for (; itProductsVector != itReactivesMap->second.end(); itProductsVector++)
686 {
687 G4cout << (*itProductsVector)->GetName() << G4endl;
688 }
689 }
690 return &(itReactivesMap->second);
691}
692
693//______________________________________________________________________________
694
697{
698 if (fReactionData.empty())
699 {
700 G4String errMsg = "No reaction table was implemented";
701 G4Exception("G4MolecularInteractionTable::CanInteractWith", "",
702 FatalErrorInArgument, errMsg);
703 }
704
705 ReactionDataMap::const_iterator itReactivesMap = fReactionData.find(molecule);
706
707 if (itReactivesMap == fReactionData.end())
708 {
709 return nullptr;
710 }
711
712 if (fVerbose)
713 {
714 G4cout << " G4MolecularInteractionTable::CanReactWith :" << G4endl;
715 G4cout << "You are checking reactants for : " << molecule->GetName() << G4endl;
716 G4cout << " the number of reactants is : " << itReactivesMap->second.size() << G4endl;
717
718 SpecificDataList::const_iterator itProductsVector = itReactivesMap->second.begin();
719
720 for (; itProductsVector != itReactivesMap->second.end(); itProductsVector++)
721 {
722 G4cout << itProductsVector->first->GetName() << G4endl;
723 }
724 }
725 return &(itReactivesMap->second);
726}
727
728//______________________________________________________________________________
729
732{
733 if (fReactionDataMV.empty())
734 {
735 G4String errMsg = "No reaction table was implemented";
736 G4Exception("G4MolecularInteractionTable::CanInteractWith", "",
737 FatalErrorInArgument, errMsg);
738 }
739 auto it = fReactionDataMV.find(molecule);
740
741 if (it == fReactionDataMV.end())
742 {
743 G4String errMsg = "No reaction table was implemented for this molecule Definition : "
744 + molecule->GetName();
745 G4Exception("G4MolecularInteractionTable::GetReactionData", "", FatalErrorInArgument, errMsg);
746 }
747
748 return &(it->second);
749}
750
751//______________________________________________________________________________
752
754 const G4String& mol2) const
755{
756 const auto pConf1 = G4MoleculeTable::GetMoleculeTable()->GetConfiguration(mol1);
757 const auto pConf2 = G4MoleculeTable::GetMoleculeTable()->GetConfiguration(mol2);
758 return GetReactionData(pConf1, pConf2);
759}
760
761//______________________________________________________________________________
762
763void
765{
766 fRateParam = std::bind(PolynomialParam, std::placeholders::_1, P);
767}
768
769//______________________________________________________________________________
770
772 double E_R)
773{
774 std::vector<double> P = { A0, E_R };
775 fRateParam = std::bind(ArrehniusParam, std::placeholders::_1, P);
776}
777
778//______________________________________________________________________________
779
781 double rateCste)
782{
784 std::placeholders::_1,
785 temperature_K,
786 rateCste);
787}
788
789//______________________________________________________________________________
790
792{
793 for (const auto& pData : fVectorOfReactionData)
794 {
795 const_cast<G4DNAMolecularReactionData*>(pData.get())->ScaleForNewTemperature(temp_K);
796 }
797}
798
799//______________________________________________________________________________
800
802{
803 if (fRateParam)
804 {
806 }
807}
808
809//______________________________________________________________________________
810
813{
814 for (auto& pData : fVectorOfReactionData)
815 {
816 if (pData->GetReactionID() == reactionID)
817 {
818 return pData.get();
819 }
820 }
821 return nullptr;
822}
823
825{
826 return fVectorOfReactionData.size();
827}
@ FatalErrorInArgument
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
Definition: G4Exp.hh:179
double G4double
Definition: G4Types.hh:83
int G4int
Definition: G4Types.hh:85
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
#define TRUE
Definition: Globals.hh:27
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
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:430
virtual void InitialiseToPrint(const G4MolecularConfiguration *)=0
const G4DNAMolecularReactionTable * GetReactionTable()
void SetReactionTable(const G4DNAMolecularReactionTable *)
virtual G4double GetReactionRadius(const G4MolecularConfiguration *, const G4MolecularConfiguration *)=0