Geant4 11.1.1
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{
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