Geant4 11.4.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
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.)
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()
126 + fpReactant2->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() +
283 fpReactant2->GetDiffusionCoefficient();
284
285 fReactionRadius = fpReactant1->GetVanDerVaalsRadius() +
286 fpReactant2->GetVanDerVaalsRadius();
287
288 G4double Rs = 0.29 * nm;
289 if(fOnsagerRadius == 0) // Type II
290 {
292 fDiffusionRate = 4 * pi * sumDiffCoeff * fReactionRadius * Avogadro;
295 if(fActivationRate > 0) {
297 Rs / (Rs + (fDiffusionRate / fActivationRate) * (fReactionRadius + Rs));
298 }
299 }else{ // Type IV
301 fDiffusionRate = 4 * pi * sumDiffCoeff * fEffectiveReactionRadius * Avogadro;
303
305 if(fActivationRate > 0) {
308 }
309 }
310 }
311
312 fType = type;
313}
314
319
321{
322 fProducts.push_back(G4MoleculeTable::Instance()->GetConfiguration(molecule));
323}
324
325double G4DNAMolecularReactionData::PolynomialParam(double temp_K, std::vector<double> P)
326{
327 double inv_temp = 1. / temp_K;
328
329 return pow(10,
330 P[0] + P[1] * inv_temp + P[2] * pow(inv_temp, 2)
331 + P[3] * pow(inv_temp, 3) + P[4] * pow(inv_temp, 4))
332 * (1e-3 * CLHEP::m3 / (CLHEP::mole * CLHEP::s));
333}
334
335double G4DNAMolecularReactionData::ArrehniusParam(double temp_K, std::vector<double> P)
336{
337 return P[0] * G4Exp(P[1] / temp_K)*
338 (1e-3 * CLHEP::m3 / (CLHEP::mole * CLHEP::s));
339}
340
342 double temp_init,
343 double rateCste_init)
344{
345 double D0 = G4MolecularConfiguration::DiffCoeffWater(temp_init);
347 return Df * rateCste_init / D0;
348}
349
350//==============================================================================
351// REACTION TABLE
352//==============================================================================
353
362
363//_____________________________________________________________________________________
364
373
374//_____________________________________________________________________________________
375
377{
378
379
380 delete fpInstance;
381
382 fpInstance = nullptr;
383}
384
385//_____________________________________________________________________________________
386
392
394
396{
397 const auto pReactant1 = pReactionData->GetReactant1();
398 const auto pReactant2 = pReactionData->GetReactant2();
399
400 fReactionData[pReactant1][pReactant2] = pReactionData;
401 fReactantsMV[pReactant1].push_back(pReactant2);
402 fReactionDataMV[pReactant1].push_back(pReactionData);
403
404 if (pReactant1 != pReactant2)
405 {
406 fReactionData[pReactant2][pReactant1] = pReactionData;
407 fReactantsMV[pReactant2].push_back(pReactant1);
408 fReactionDataMV[pReactant2].push_back(pReactionData);
409 }
410
411 fVectorOfReactionData.emplace_back(pReactionData);
412 pReactionData->SetReactionID((G4int)fVectorOfReactionData.size());
413}
414
415//_____________________________________________________________________________________
416
418 Reactant* pReactant1,
419 Reactant* pReactant2)
420{
421 auto reactionData = new G4DNAMolecularReactionData(reactionRate, pReactant1, pReactant2);
422 SetReaction(reactionData);
423}
424
425//_____________________________________________________________________________________
426
428{
429 // Print Reactions and Interaction radius for jump step = 3ps
430
431 G4IosFlagsSaver iosfs(G4cout);
432
433 if ((pReactionModel != nullptr) && ((pReactionModel->GetReactionTable()) == nullptr))
434 {
435 pReactionModel->SetReactionTable(this);
436 }
437
438 ReactivesMV::iterator itReactives;
439
440 std::map<Reactant*, std::map<Reactant*, G4bool>> alreadyPrint;
441
442 G4cout << "Number of chemical species involved in reactions = "
443 << fReactantsMV.size() << G4endl;
444
445 std::size_t nbPrintable = fReactantsMV.size() * fReactantsMV.size();
446
447 auto outputReaction = new G4String[nbPrintable];
448 auto outputReactionRate = new G4String[nbPrintable];
449 auto outputRange = new G4String[nbPrintable];
450 G4int n = 0;
451
452 for (itReactives = fReactantsMV.begin(); itReactives != fReactantsMV.end();
453 ++itReactives)
454 {
455 auto moleculeA = (Reactant*)itReactives->first;
456 const vector<Reactant*>* reactivesVector = CanReactWith(moleculeA);
457
458 if (pReactionModel != nullptr) pReactionModel->InitialiseToPrint(moleculeA);
459
460 auto nbReactants = (G4int)fReactantsMV[itReactives->first].size();
461
462 for (G4int iReact = 0; iReact < nbReactants; iReact++)
463 {
464 auto moleculeB = (Reactant*)(*reactivesVector)[iReact];
465
466 Data* reactionData = fReactionData[moleculeA][moleculeB];
467
468 //-----------------------------------------------------------
469 // Name of the reaction
470 if (!alreadyPrint[moleculeA][moleculeB])
471 {
472 outputReaction[n] = moleculeA->GetName() + " + " + moleculeB->GetName();
473
474 G4int nbProducts = reactionData->GetNbProducts();
475
476 if (nbProducts != 0)
477 {
478 outputReaction[n] += " -> " + reactionData->GetProduct(0)->GetName();
479
480 for (G4int j = 1; j < nbProducts; j++)
481 {
482 outputReaction[n] += " + " + reactionData->GetProduct(j)->GetName();
483 }
484 }
485 else
486 {
487 outputReaction[n] += " -> No product";
488 }
489
490 //-----------------------------------------------------------
491 // Interaction Rate
492 outputReactionRate[n] = G4UIcommand::ConvertToString(
493 reactionData->GetObservedReactionRateConstant() / (1e-3 * m3 / (mole * s)));
494
495 //-----------------------------------------------------------
496 // Calculation of the Interaction Range
497 G4double interactionRange = -1;
498 if (pReactionModel != nullptr) interactionRange =
499 pReactionModel->GetReactionRadius(iReact);
500
501 if (interactionRange != -1)
502 {
503 outputRange[n] = G4UIcommand::ConvertToString(
504 interactionRange / nanometer);
505 }
506 else
507 {
508 outputRange[n] = "";
509 }
510
511 alreadyPrint[moleculeB][moleculeA] = TRUE;
512 n++;
513 }
514 }
515 }
516 // G4cout<<"Number of possible reactions: "<< n << G4endl;
517
518 ////////////////////////////////////////////////////////////////////
519 // Tableau dynamique en fonction du nombre de caractere maximal dans
520 // chaque colonne
521 ////////////////////////////////////////////////////////////////////
522
523 G4int maxlengthOutputReaction = -1;
524 G4int maxlengthOutputReactionRate = -1;
525
526 for (G4int i = 0; i < n; ++i)
527 {
528 if (maxlengthOutputReaction < (G4int)outputReaction[i].length())
529 {
530 maxlengthOutputReaction = (G4int)outputReaction[i].length();
531 }
532 if (maxlengthOutputReactionRate < (G4int)outputReactionRate[i].length())
533 {
534 maxlengthOutputReactionRate = (G4int)outputReactionRate[i].length();
535 }
536 }
537
538 maxlengthOutputReaction += 2;
539 maxlengthOutputReactionRate += 2;
540
541 if (maxlengthOutputReaction < 10) maxlengthOutputReaction = 10;
542 if (maxlengthOutputReactionRate < 30) maxlengthOutputReactionRate = 30;
543
544 G4String* title;
545
546 if (pReactionModel != nullptr) title = new G4String[3];
547 else title = new G4String[2];
548
549 title[0] = "Reaction";
550 title[1] = "Reaction Rate [dm3/(mol*s)]";
551
552 if (pReactionModel != nullptr) title[2] =
553 "Interaction Range for chosen reaction model [nm]";
554
555 G4cout << setfill(' ') << setw(maxlengthOutputReaction) << left << title[0]
556 << setw(maxlengthOutputReactionRate) << left << title[1];
557
558 if (pReactionModel != nullptr) G4cout << setw(2) << left << title[2];
559
560 G4cout << G4endl;
561
562 G4cout.fill('-');
563 if (pReactionModel != nullptr) G4cout.width(
564 maxlengthOutputReaction + 2 + maxlengthOutputReactionRate + 2
565 + (G4int)title[2].length());
566 else G4cout.width(maxlengthOutputReaction + 2 + maxlengthOutputReactionRate);
567 G4cout << "-" << G4endl;
568 G4cout.fill(' ');
569
570 for (G4int i = 0; i < n; i++)
571 {
572 G4cout << setw(maxlengthOutputReaction) << left << outputReaction[i]
573 << setw(maxlengthOutputReactionRate) << left
574 << outputReactionRate[i];
575
576 if (pReactionModel != nullptr) G4cout << setw(2) << left << outputRange[i];
577
578 G4cout << G4endl;
579
580 G4cout.fill('-');
581 if (pReactionModel != nullptr) G4cout.width(
582 maxlengthOutputReaction + 2 + maxlengthOutputReactionRate + 2
583 + (G4int)title[2].length());
584 else G4cout.width(
585 maxlengthOutputReaction + 2 + maxlengthOutputReactionRate);
586 G4cout << "-" << G4endl;
587 G4cout.fill(' ');
588 }
589
590 delete[] title;
591 delete[] outputReaction;
592 delete[] outputReactionRate;
593 delete[] outputRange;
594}
595
596//______________________________________________________________________________
597// Get/Set methods
598
603
606 Reactant* pReactant2) const
607{
608 if (fReactionData.empty())
609 {
610 G4String errMsg = "No reaction table was implemented";
611 G4Exception("G4MolecularInteractionTable::GetReactionData", "",
612 FatalErrorInArgument, errMsg);
613 }
614
615 auto it1 = fReactionData.find(pReactant1);
616
617 if (it1 == fReactionData.end())
618 {
619 if (fVerbose) {
621 errMsg << "No reaction table was implemented for this molecule Definition : "
622 + pReactant1->GetName();
623 G4Exception(G4String("G4MolecularInteractionTable::GetReactionData"),
624 "", JustWarning, errMsg);
625 }
626 return nullptr;
627 }
628
629 auto it2 = it1->second.find(pReactant2);
630
631 if (it2 == it1->second.end())
632 {
633 //no reactant should return nullptr reaction data (not an exception).
634 //This helps UI chemistry
635 return nullptr;
636 }
637
638 return (it2->second);
639}
640
645
647{
648 DataList dataList;
649
650 for (const auto& pData : fVectorOfReactionData)
651 {
652 dataList.emplace_back(pData.get());
653 }
654
655 return dataList;
656}
657
658//______________________________________________________________________________
659
662{
663 if (fReactantsMV.empty())
664 {
665 G4String errMsg = "No reaction table was implemented";
666 G4Exception("G4MolecularInteractionTable::CanReactWith", "",
667 FatalErrorInArgument, errMsg);
668 return nullptr;
669 }
670
671 auto itReactivesMap = fReactantsMV.find(pMolecule);
672
673 if (itReactivesMap == fReactantsMV.end())
674 {
675#ifdef G4VERBOSE
676 if (fVerbose)
677 {
678 G4String errMsg = "No reaction table was implemented for this molecule : "
679 + pMolecule->GetName();
680 // G4Exception("G4MolecularInteractionTable::CanReactWith","",FatalErrorInArgument, errMsg);
681 G4cout << "--- G4MolecularInteractionTable::GetReactionData ---" << G4endl;
682 G4cout << errMsg << G4endl;
683 }
684#endif
685 return nullptr;
686 }
687
688 if (fVerbose)
689 {
690 G4cout << " G4MolecularInteractionTable::CanReactWith :" << G4endl;
691 G4cout << "You are checking reactants for : " << pMolecule->GetName() << G4endl;
692 G4cout << " the number of reactants is : " << itReactivesMap->second.size() << G4endl;
693
694 auto itProductsVector = itReactivesMap->second.cbegin();
695
696 for (; itProductsVector != itReactivesMap->second.end(); itProductsVector++)
697 {
698 G4cout << (*itProductsVector)->GetName() << G4endl;
699 }
700 }
701 return &(itReactivesMap->second);
702}
703
704//______________________________________________________________________________
705
708{
709 if (fReactionData.empty())
710 {
711 G4String errMsg = "No reaction table was implemented";
712 G4Exception("G4MolecularInteractionTable::CanInteractWith", "",
713 FatalErrorInArgument, errMsg);
714 }
715
716 auto itReactivesMap = fReactionData.find(molecule);
717
718 if (itReactivesMap == fReactionData.end())
719 {
720 return nullptr;
721 }
722
723 if (fVerbose)
724 {
725 G4cout << " G4MolecularInteractionTable::CanReactWith :" << G4endl;
726 G4cout << "You are checking reactants for : " << molecule->GetName() << G4endl;
727 G4cout << " the number of reactants is : " << itReactivesMap->second.size() << G4endl;
728
729 auto itProductsVector = itReactivesMap->second.begin();
730
731 for (; itProductsVector != itReactivesMap->second.end(); itProductsVector++)
732 {
733 G4cout << itProductsVector->first->GetName() << G4endl;
734 }
735 }
736 return &(itReactivesMap->second);
737}
738
739//______________________________________________________________________________
740
743{
744 if (fReactionDataMV.empty())
745 {
746 G4String errMsg = "No reaction table was implemented";
747 G4Exception("G4MolecularInteractionTable::CanInteractWith", "",
748 FatalErrorInArgument, errMsg);
749 }
750 auto it = fReactionDataMV.find(molecule);
751
752 if (it == fReactionDataMV.end())
753 {
754 if (fVerbose) {
756 errMsg << "No reaction table was implemented for this molecule Definition : "
757 + molecule->GetName();
758 G4Exception(G4String("G4MolecularInteractionTable::GetReactionData"),
759 "", JustWarning, errMsg);
760 }
761 return nullptr;
762 }
763
764 return &(it->second);
765}
766
767//______________________________________________________________________________
768
770 const G4String& mol2) const
771{
772 const auto pConf1 = G4MoleculeTable::GetMoleculeTable()->GetConfiguration(mol1);
773 const auto pConf2 = G4MoleculeTable::GetMoleculeTable()->GetConfiguration(mol2);
774 return GetReactionData(pConf1, pConf2);
775}
776
777//______________________________________________________________________________
778
779void
781{
782 fRateParam = std::bind(PolynomialParam, std::placeholders::_1, P);
783}
784
785//______________________________________________________________________________
786
788 double E_R)
789{
790 std::vector<double> P = { A0, E_R };
791 fRateParam = std::bind(ArrehniusParam, std::placeholders::_1, P);
792}
793
794//______________________________________________________________________________
795
797 double rateCste)
798{
800 std::placeholders::_1,
801 temperature_K,
802 rateCste);
803}
804
805//______________________________________________________________________________
806
808{
809 for (const auto& pData : fVectorOfReactionData)
810 {
811 const_cast<G4DNAMolecularReactionData*>(pData.get())->ScaleForNewTemperature(temp_K);
812 }
813}
814
815//______________________________________________________________________________
816
824
825//______________________________________________________________________________
826
829{
830 for (auto& pData : fVectorOfReactionData)
831 {
832 if (pData->GetReactionID() == reactionID)
833 {
834 return pData.get();
835 }
836 }
837 return nullptr;
838}
839
841{
842 return fVectorOfReactionData.size();
843}
844
846{
847 fReactionData.clear();
848 fReactantsMV.clear();
849 fReactionDataMV.clear();
850 fVectorOfReactionData.clear();
851}
@ JustWarning
@ FatalErrorInArgument
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
Definition G4Exp.hh:132
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
const G4MolecularConfiguration Reactant
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 G4MolecularConfiguration Reactant
const ReactantList * CanReactWith(Reactant *) const
std::map< Reactant *, SpecificDataList > ReactionDataMap
Data * GetReaction(int reactionID) const
const SpecificDataList * GetReativesNData(const G4MolecularConfiguration *) const
G4VDNAMolecularGeometry * GetGeometry() const
std::unique_ptr< G4ReactionTableMessenger > fpMessenger
~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)
const G4DNAMolecularReactionData Data
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