Geant4 11.2.2
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
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
141
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
173
178
183
188
203
208
213
218
223
228
233
238
244
249
254
259
264
269
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
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
357
358//_____________________________________________________________________________________
359
368
369//_____________________________________________________________________________________
370
372{
373
374
375 delete fpInstance;
376
377 fpInstance = nullptr;
378}
379
380//_____________________________________________________________________________________
381
387
389
391{
392 const auto pReactant1 = pReactionData->GetReactant1();
393 const auto pReactant2 = pReactionData->GetReactant2();
394
395 fReactionData[pReactant1][pReactant2] = pReactionData;
396 fReactantsMV[pReactant1].push_back(pReactant2);
397 fReactionDataMV[pReactant1].push_back(pReactionData);
398
399 if (pReactant1 != pReactant2)
400 {
401 fReactionData[pReactant2][pReactant1] = pReactionData;
402 fReactantsMV[pReactant2].push_back(pReactant1);
403 fReactionDataMV[pReactant2].push_back(pReactionData);
404 }
405
406 fVectorOfReactionData.emplace_back(pReactionData);
407 pReactionData->SetReactionID((G4int)fVectorOfReactionData.size());
408}
409
410//_____________________________________________________________________________________
411
413 Reactant* pReactant1,
414 Reactant* pReactant2)
415{
416 auto reactionData = new G4DNAMolecularReactionData(reactionRate, pReactant1, pReactant2);
417 SetReaction(reactionData);
418}
419
420//_____________________________________________________________________________________
421
423{
424 // Print Reactions and Interaction radius for jump step = 3ps
425
426 G4IosFlagsSaver iosfs(G4cout);
427
428 if ((pReactionModel != nullptr) && ((pReactionModel->GetReactionTable()) == nullptr))
429 {
430 pReactionModel->SetReactionTable(this);
431 }
432
433 ReactivesMV::iterator itReactives;
434
435 std::map<Reactant*, std::map<Reactant*, G4bool>> alreadyPrint;
436
437 G4cout << "Number of chemical species involved in reactions = "
438 << fReactantsMV.size() << G4endl;
439
440 std::size_t nbPrintable = fReactantsMV.size() * fReactantsMV.size();
441
442 auto outputReaction = new G4String[nbPrintable];
443 auto outputReactionRate = new G4String[nbPrintable];
444 auto outputRange = new G4String[nbPrintable];
445 G4int n = 0;
446
447 for (itReactives = fReactantsMV.begin(); itReactives != fReactantsMV.end();
448 ++itReactives)
449 {
450 auto moleculeA = (Reactant*)itReactives->first;
451 const vector<Reactant*>* reactivesVector = CanReactWith(moleculeA);
452
453 if (pReactionModel != nullptr) pReactionModel->InitialiseToPrint(moleculeA);
454
455 auto nbReactants = (G4int)fReactantsMV[itReactives->first].size();
456
457 for (G4int iReact = 0; iReact < nbReactants; iReact++)
458 {
459 auto moleculeB = (Reactant*)(*reactivesVector)[iReact];
460
461 Data* reactionData = fReactionData[moleculeA][moleculeB];
462
463 //-----------------------------------------------------------
464 // Name of the reaction
465 if (!alreadyPrint[moleculeA][moleculeB])
466 {
467 outputReaction[n] = moleculeA->GetName() + " + " + moleculeB->GetName();
468
469 G4int nbProducts = reactionData->GetNbProducts();
470
471 if (nbProducts != 0)
472 {
473 outputReaction[n] += " -> " + reactionData->GetProduct(0)->GetName();
474
475 for (G4int j = 1; j < nbProducts; j++)
476 {
477 outputReaction[n] += " + " + reactionData->GetProduct(j)->GetName();
478 }
479 }
480 else
481 {
482 outputReaction[n] += " -> No product";
483 }
484
485 //-----------------------------------------------------------
486 // Interaction Rate
487 outputReactionRate[n] = G4UIcommand::ConvertToString(
488 reactionData->GetObservedReactionRateConstant() / (1e-3 * m3 / (mole * s)));
489
490 //-----------------------------------------------------------
491 // Calculation of the Interaction Range
492 G4double interactionRange = -1;
493 if (pReactionModel != nullptr) interactionRange =
494 pReactionModel->GetReactionRadius(iReact);
495
496 if (interactionRange != -1)
497 {
498 outputRange[n] = G4UIcommand::ConvertToString(
499 interactionRange / nanometer);
500 }
501 else
502 {
503 outputRange[n] = "";
504 }
505
506 alreadyPrint[moleculeB][moleculeA] = TRUE;
507 n++;
508 }
509 }
510 }
511 // G4cout<<"Number of possible reactions: "<< n << G4endl;
512
513 ////////////////////////////////////////////////////////////////////
514 // Tableau dynamique en fonction du nombre de caractere maximal dans
515 // chaque colonne
516 ////////////////////////////////////////////////////////////////////
517
518 G4int maxlengthOutputReaction = -1;
519 G4int maxlengthOutputReactionRate = -1;
520
521 for (G4int i = 0; i < n; ++i)
522 {
523 if (maxlengthOutputReaction < (G4int)outputReaction[i].length())
524 {
525 maxlengthOutputReaction = (G4int)outputReaction[i].length();
526 }
527 if (maxlengthOutputReactionRate < (G4int)outputReactionRate[i].length())
528 {
529 maxlengthOutputReactionRate = (G4int)outputReactionRate[i].length();
530 }
531 }
532
533 maxlengthOutputReaction += 2;
534 maxlengthOutputReactionRate += 2;
535
536 if (maxlengthOutputReaction < 10) maxlengthOutputReaction = 10;
537 if (maxlengthOutputReactionRate < 30) maxlengthOutputReactionRate = 30;
538
539 G4String* title;
540
541 if (pReactionModel != nullptr) title = new G4String[3];
542 else title = new G4String[2];
543
544 title[0] = "Reaction";
545 title[1] = "Reaction Rate [dm3/(mol*s)]";
546
547 if (pReactionModel != nullptr) title[2] =
548 "Interaction Range for chosen reaction model [nm]";
549
550 G4cout << setfill(' ') << setw(maxlengthOutputReaction) << left << title[0]
551 << setw(maxlengthOutputReactionRate) << left << title[1];
552
553 if (pReactionModel != nullptr) G4cout << setw(2) << left << title[2];
554
555 G4cout << G4endl;
556
557 G4cout.fill('-');
558 if (pReactionModel != nullptr) G4cout.width(
559 maxlengthOutputReaction + 2 + maxlengthOutputReactionRate + 2
560 + (G4int)title[2].length());
561 else G4cout.width(maxlengthOutputReaction + 2 + maxlengthOutputReactionRate);
562 G4cout << "-" << G4endl;
563 G4cout.fill(' ');
564
565 for (G4int i = 0; i < n; i++)
566 {
567 G4cout << setw(maxlengthOutputReaction) << left << outputReaction[i]
568 << setw(maxlengthOutputReactionRate) << left
569 << outputReactionRate[i];
570
571 if (pReactionModel != nullptr) G4cout << setw(2) << left << outputRange[i];
572
573 G4cout << G4endl;
574
575 G4cout.fill('-');
576 if (pReactionModel != nullptr) G4cout.width(
577 maxlengthOutputReaction + 2 + maxlengthOutputReactionRate + 2
578 + (G4int)title[2].length());
579 else G4cout.width(
580 maxlengthOutputReaction + 2 + maxlengthOutputReactionRate);
581 G4cout << "-" << G4endl;
582 G4cout.fill(' ');
583 }
584
585 delete[] title;
586 delete[] outputReaction;
587 delete[] outputReactionRate;
588 delete[] outputRange;
589}
590
591//______________________________________________________________________________
592// Get/Set methods
593
598
601 Reactant* pReactant2) const
602{
603 if (fReactionData.empty())
604 {
605 G4String errMsg = "No reaction table was implemented";
606 G4Exception("G4MolecularInteractionTable::GetReactionData", "",
607 FatalErrorInArgument, errMsg);
608 }
609
610 auto it1 = fReactionData.find(pReactant1);
611
612 if (it1 == fReactionData.end())
613 {
614 G4String errMsg =
615 "No reaction table was implemented for this molecule Definition : " + pReactant1
616 ->GetName();
617 G4Exception("G4MolecularInteractionTable::GetReactionData", "",
618 FatalErrorInArgument, errMsg);
619 // Though the above is Fatal and will terminate program, put return in to quieten Coverity
620 return nullptr;
621 }
622
623 auto 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
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 nullptr;
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 auto 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 auto 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 // Though the above is Fatal and will terminate program, put return in to quieten Coverity
753 return nullptr;
754 }
755
756 return &(it->second);
757}
758
759//______________________________________________________________________________
760
762 const G4String& mol2) const
763{
764 const auto pConf1 = G4MoleculeTable::GetMoleculeTable()->GetConfiguration(mol1);
765 const auto pConf2 = G4MoleculeTable::GetMoleculeTable()->GetConfiguration(mol2);
766 return GetReactionData(pConf1, pConf2);
767}
768
769//______________________________________________________________________________
770
771void
773{
774 fRateParam = std::bind(PolynomialParam, std::placeholders::_1, P);
775}
776
777//______________________________________________________________________________
778
780 double E_R)
781{
782 std::vector<double> P = { A0, E_R };
783 fRateParam = std::bind(ArrehniusParam, std::placeholders::_1, P);
784}
785
786//______________________________________________________________________________
787
789 double rateCste)
790{
792 std::placeholders::_1,
793 temperature_K,
794 rateCste);
795}
796
797//______________________________________________________________________________
798
800{
801 for (const auto& pData : fVectorOfReactionData)
802 {
803 const_cast<G4DNAMolecularReactionData*>(pData.get())->ScaleForNewTemperature(temp_K);
804 }
805}
806
807//______________________________________________________________________________
808
816
817//______________________________________________________________________________
818
821{
822 for (auto& pData : fVectorOfReactionData)
823 {
824 if (pData->GetReactionID() == reactionID)
825 {
826 return pData.get();
827 }
828 }
829 return nullptr;
830}
831
833{
834 return fVectorOfReactionData.size();
835}
836
838{
839 fReactionData.clear();
840 fReactantsMV.clear();
841 fReactionDataMV.clear();
842 fVectorOfReactionData.clear();
843}
@ FatalErrorInArgument
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
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:67
G4GLOB_DLL std::ostream G4cout
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()
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
~G4DNAMolecularReactionTable() override
std::vector< std::unique_ptr< Data > > fVectorOfReactionData
const ReactionDataMap & GetAllReactionData()
static G4DNAMolecularReactionTable * fpInstance
void SetReaction(G4double observedReactionRate, Reactant *reactive1, Reactant *reactive2)
void PrintTable(G4VDNAReactionModel *=nullptr)
void ScaleReactionRateForNewTemperature(double temp_K)
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)
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