Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/electromagnetic/dna/models/src/G4DNAIRT.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /processes/electromagnetic/dna/models/src/G4DNAIRT.cc (Version 11.3.0) and /processes/electromagnetic/dna/models/src/G4DNAIRT.cc (Version 10.7.p3)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
 26 /*                                                 26 /*
 27  * G4DNAIRT.cc                                     27  * G4DNAIRT.cc
 28  *                                                 28  *
 29  *  Created on: Jul 23, 2019                       29  *  Created on: Jul 23, 2019
 30  *      Author: W. G. Shin                         30  *      Author: W. G. Shin
 31  *              J. Ramos-Mendez and B. Faddego     31  *              J. Ramos-Mendez and B. Faddegon
 32 */                                                 32 */
 33                                                    33 
 34                                                    34 
 35 #include "G4DNAIRT.hh"                             35 #include "G4DNAIRT.hh"
 36 #include "G4ErrorFunction.hh"                      36 #include "G4ErrorFunction.hh"
 37 #include "G4SystemOfUnits.hh"                      37 #include "G4SystemOfUnits.hh"
 38 #include "G4PhysicalConstants.hh"                  38 #include "G4PhysicalConstants.hh"
 39 #include "Randomize.hh"                            39 #include "Randomize.hh"
 40 #include "G4DNAMolecularReactionTable.hh"          40 #include "G4DNAMolecularReactionTable.hh"
 41 #include "G4MolecularConfiguration.hh"             41 #include "G4MolecularConfiguration.hh"
 42 #include "G4Molecule.hh"                           42 #include "G4Molecule.hh"
 43 #include "G4ITReactionChange.hh"                   43 #include "G4ITReactionChange.hh"
 44 #include "G4ITTrackHolder.hh"                      44 #include "G4ITTrackHolder.hh"
 45 #include "G4ITReaction.hh"                         45 #include "G4ITReaction.hh"
 46 #include "G4Scheduler.hh"                          46 #include "G4Scheduler.hh"
 47                                                    47 
 48 using namespace std;                               48 using namespace std;
 49                                                    49 
 50 G4DNAIRT::G4DNAIRT()  :                            50 G4DNAIRT::G4DNAIRT()  :
                                                   >>  51 G4VITReactionProcess(),
 51 fMolReactionTable(reference_cast<const G4DNAMo     52 fMolReactionTable(reference_cast<const G4DNAMolecularReactionTable*>(fpReactionTable)),
 52 fpReactionModel(nullptr),                          53 fpReactionModel(nullptr),
 53 fTrackHolder(G4ITTrackHolder::Instance()),         54 fTrackHolder(G4ITTrackHolder::Instance()),
 54 fReactionSet(nullptr)                          <<  55 fReactionSet(0)
 55 {                                                  56 {
 56   timeMin = G4Scheduler::Instance()->GetStartT     57   timeMin = G4Scheduler::Instance()->GetStartTime();
 57   timeMax = G4Scheduler::Instance()->GetEndTim     58   timeMax = G4Scheduler::Instance()->GetEndTime();
 58                                                    59 
 59   fXMin = 1e9*nm;                                  60   fXMin = 1e9*nm;
 60   fYMin = 1e9*nm;                                  61   fYMin = 1e9*nm;
 61   fZMin = 1e9*nm;                                  62   fZMin = 1e9*nm;
 62                                                    63 
 63   fXMax = 0e0*nm;                                  64   fXMax = 0e0*nm;
 64   fYMax = 0e0*nm;                                  65   fYMax = 0e0*nm;
 65   fZMax = 0e0*nm;                                  66   fZMax = 0e0*nm;
 66                                                    67 
 67   fNx = 0;                                         68   fNx = 0;
 68   fNy = 0;                                         69   fNy = 0;
 69   fNz = 0;                                         70   fNz = 0;
 70                                                    71 
 71   xiniIndex = 0, yiniIndex = 0, ziniIndex = 0;     72   xiniIndex = 0, yiniIndex = 0, ziniIndex = 0;
 72   xendIndex = 0, yendIndex = 0, zendIndex = 0;     73   xendIndex = 0, yendIndex = 0, zendIndex = 0;
 73                                                    74 
 74   fRCutOff =                                       75   fRCutOff =
 75     1.45 * nm + 2 * std::sqrt(8*9.46e9*nm*nm/s     76     1.45 * nm + 2 * std::sqrt(8*9.46e9*nm*nm/s * timeMax); // 95% confidence level
 76                                                    77 
 77   erfc = new G4ErrorFunction();                    78   erfc = new G4ErrorFunction();
 78 }                                                  79 }
 79                                                    80 
 80                                                    81 
 81 G4DNAIRT::G4DNAIRT(G4VDNAReactionModel* pReact     82 G4DNAIRT::G4DNAIRT(G4VDNAReactionModel* pReactionModel)
 82   : G4DNAIRT()                                     83   : G4DNAIRT()
 83 {                                                  84 {
 84   fpReactionModel = pReactionModel;                85   fpReactionModel = pReactionModel;
 85 }                                                  86 }
 86                                                    87 
 87 G4DNAIRT::~G4DNAIRT()                              88 G4DNAIRT::~G4DNAIRT()
 88 {                                                  89 {
 89   delete erfc;                                     90   delete erfc;
 90 }                                                  91 }
 91                                                    92 
 92 void G4DNAIRT::Initialize(){                       93 void G4DNAIRT::Initialize(){
 93                                                    94 
 94   fTrackHolder = G4ITTrackHolder::Instance();      95   fTrackHolder = G4ITTrackHolder::Instance();
 95                                                    96 
 96   fReactionSet = G4ITReactionSet::Instance();      97   fReactionSet = G4ITReactionSet::Instance();
 97   fReactionSet->CleanAllReaction();                98   fReactionSet->CleanAllReaction();
 98   fReactionSet->SortByTime();                      99   fReactionSet->SortByTime();
 99                                                   100 
100   spaceBinned.clear();                            101   spaceBinned.clear();
101                                                   102 
102   timeMin = G4Scheduler::Instance()->GetStartT    103   timeMin = G4Scheduler::Instance()->GetStartTime();
103   timeMax = G4Scheduler::Instance()->GetEndTim    104   timeMax = G4Scheduler::Instance()->GetEndTime();
104                                                   105 
105   xiniIndex = 0;                                  106   xiniIndex = 0;
106   yiniIndex = 0;                                  107   yiniIndex = 0;
107   ziniIndex = 0;                                  108   ziniIndex = 0;
108   xendIndex = 0;                                  109   xendIndex = 0;
109   yendIndex = 0;                                  110   yendIndex = 0;
110   zendIndex = 0;                                  111   zendIndex = 0;
111                                                   112 
112   fXMin = 1e9*nm;                                 113   fXMin = 1e9*nm;
113   fYMin = 1e9*nm;                                 114   fYMin = 1e9*nm;
114   fZMin = 1e9*nm;                                 115   fZMin = 1e9*nm;
115                                                   116 
116   fXMax = 0e0*nm;                                 117   fXMax = 0e0*nm;
117   fYMax = 0e0*nm;                                 118   fYMax = 0e0*nm;
118   fZMax = 0e0*nm;                                 119   fZMax = 0e0*nm;
119                                                   120 
120   fNx = 0;                                        121   fNx = 0;
121   fNy = 0;                                        122   fNy = 0;
122   fNz = 0;                                        123   fNz = 0;
123                                                   124 
124   SpaceBinning();   // 1. binning the space       125   SpaceBinning();   // 1. binning the space
125   IRTSampling();    // 2. Sampling of the IRT     126   IRTSampling();    // 2. Sampling of the IRT
126                                                   127 
127   //hoang : if the first IRTSampling won't giv << 
128   if(fReactionSet->Empty())                    << 
129   {                                            << 
130     for (auto pTrack : *fTrackHolder->GetMainL << 
131     {                                          << 
132       pTrack->SetGlobalTime(G4Scheduler::Insta << 
133     }                                          << 
134   }                                            << 
135 }                                                 128 }
136                                                   129 
137 void G4DNAIRT::SpaceBinning(){                    130 void G4DNAIRT::SpaceBinning(){
138   auto it_begin = fTrackHolder->GetMainList()-    131   auto it_begin = fTrackHolder->GetMainList()->begin();
139   while(it_begin != fTrackHolder->GetMainList(    132   while(it_begin != fTrackHolder->GetMainList()->end()){
140                                                   133 
141     G4ThreeVector position = it_begin->GetPosi    134     G4ThreeVector position = it_begin->GetPosition();
142                                                   135 
143     if ( fXMin > position.x() ) fXMin = positi    136     if ( fXMin > position.x() ) fXMin = position.x(); 
144     if ( fYMin > position.y() ) fYMin = positi    137     if ( fYMin > position.y() ) fYMin = position.y();
145     if ( fZMin > position.z() ) fZMin = positi    138     if ( fZMin > position.z() ) fZMin = position.z();
146                                                   139 
147     if ( fXMax < position.x() ) fXMax = positi    140     if ( fXMax < position.x() ) fXMax = position.x();
148     if ( fYMax < position.y() ) fYMax = positi    141     if ( fYMax < position.y() ) fYMax = position.y();
149     if ( fZMax < position.z() ) fZMax = positi    142     if ( fZMax < position.z() ) fZMax = position.z();
150                                                   143 
151     ++it_begin;                                   144     ++it_begin;
152   }                                               145   }
153                                                   146 
154   fNx = G4int((fXMax-fXMin)/fRCutOff) == 0 ? 1    147   fNx = G4int((fXMax-fXMin)/fRCutOff) == 0 ? 1 : G4int((fXMax-fXMin)/fRCutOff);
155   fNy = G4int((fYMax-fYMin)/fRCutOff) == 0 ? 1    148   fNy = G4int((fYMax-fYMin)/fRCutOff) == 0 ? 1 : G4int((fYMax-fYMin)/fRCutOff);
156   fNz = G4int((fZMax-fZMin)/fRCutOff) == 0 ? 1    149   fNz = G4int((fZMax-fZMin)/fRCutOff) == 0 ? 1 : G4int((fZMax-fZMin)/fRCutOff);
157                                                   150 
158 }                                                 151 }
159                                                   152 
160 void G4DNAIRT::IRTSampling(){                     153 void G4DNAIRT::IRTSampling(){
161                                                   154 
162   auto it_begin = fTrackHolder->GetMainList()-    155   auto it_begin = fTrackHolder->GetMainList()->begin();
163   while(it_begin != fTrackHolder->GetMainList(    156   while(it_begin != fTrackHolder->GetMainList()->end()){
164     G4int I = FindBin(fNx, fXMin, fXMax, it_be    157     G4int I = FindBin(fNx, fXMin, fXMax, it_begin->GetPosition().x());
165     G4int J = FindBin(fNy, fYMin, fYMax, it_be    158     G4int J = FindBin(fNy, fYMin, fYMax, it_begin->GetPosition().y());
166     G4int K = FindBin(fNz, fZMin, fZMax, it_be    159     G4int K = FindBin(fNz, fZMin, fZMax, it_begin->GetPosition().z());
167                                                   160 
168     spaceBinned[I][J][K].push_back(*it_begin);    161     spaceBinned[I][J][K].push_back(*it_begin);
169                                                   162 
170     Sampling(*it_begin);                          163     Sampling(*it_begin);
171     ++it_begin;                                   164     ++it_begin;
172   }                                               165   }
173 }                                                 166 }
174                                                   167 
175 void G4DNAIRT::Sampling(G4Track* track){          168 void G4DNAIRT::Sampling(G4Track* track){
176   G4Molecule* molA = G4Molecule::GetMolecule(t    169   G4Molecule* molA = G4Molecule::GetMolecule(track);
177   const G4MolecularConfiguration* molConfA = m    170   const G4MolecularConfiguration* molConfA = molA->GetMolecularConfiguration();
178   if(molConfA->GetDiffusionCoefficient() == 0)    171   if(molConfA->GetDiffusionCoefficient() == 0) return;
179                                                   172 
180   const vector<const G4MolecularConfiguration*    173   const vector<const G4MolecularConfiguration*>* reactivesVector =
181     fMolReactionTable->CanReactWith(molConfA);    174     fMolReactionTable->CanReactWith(molConfA);
182                                                   175 
183   if(reactivesVector == nullptr) return;          176   if(reactivesVector == nullptr) return;
184                                                   177 
185   G4double globalTime = G4Scheduler::Instance(    178   G4double globalTime = G4Scheduler::Instance()->GetGlobalTime();
186   G4double minTime = timeMax;                     179   G4double minTime = timeMax;
187                                                   180 
188   xiniIndex = FindBin(fNx, fXMin, fXMax, track    181   xiniIndex = FindBin(fNx, fXMin, fXMax, track->GetPosition().x()-fRCutOff);
189   xendIndex = FindBin(fNx, fXMin, fXMax, track    182   xendIndex = FindBin(fNx, fXMin, fXMax, track->GetPosition().x()+fRCutOff);
190   yiniIndex = FindBin(fNy, fYMin, fYMax, track    183   yiniIndex = FindBin(fNy, fYMin, fYMax, track->GetPosition().y()-fRCutOff);
191   yendIndex = FindBin(fNy, fYMin, fYMax, track    184   yendIndex = FindBin(fNy, fYMin, fYMax, track->GetPosition().y()+fRCutOff);
192   ziniIndex = FindBin(fNz, fZMin, fZMax, track    185   ziniIndex = FindBin(fNz, fZMin, fZMax, track->GetPosition().z()-fRCutOff);
193   zendIndex = FindBin(fNz, fZMin, fZMax, track    186   zendIndex = FindBin(fNz, fZMin, fZMax, track->GetPosition().z()+fRCutOff);
194                                                   187 
195   for ( int ii = xiniIndex; ii <= xendIndex; i    188   for ( int ii = xiniIndex; ii <= xendIndex; ii++ ) {
196     for ( int jj = yiniIndex; jj <= yendIndex;    189     for ( int jj = yiniIndex; jj <= yendIndex; jj++ ) {
197       for ( int kk = ziniIndex; kk <= zendInde    190       for ( int kk = ziniIndex; kk <= zendIndex; kk++ ) {
198                                                   191 
199         std::vector<G4Track*> spaceBin = space    192         std::vector<G4Track*> spaceBin = spaceBinned[ii][jj][kk];
200         for ( int n = 0; n < (int)spaceBinned[    193         for ( int n = 0; n < (int)spaceBinned[ii][jj][kk].size(); n++ ) {
201           if((spaceBin[n] == nullptr) || track << 194           if(!spaceBin[n] || track == spaceBin[n]) continue;
202           if(spaceBin[n]->GetTrackStatus() ==     195           if(spaceBin[n]->GetTrackStatus() == fStopButAlive) continue;
203                                                   196 
204           G4Molecule* molB = G4Molecule::GetMo    197           G4Molecule* molB = G4Molecule::GetMolecule(spaceBin[n]);
205           if(molB == nullptr) continue;        << 198           if(!molB) continue;
206                                                   199 
207           const G4MolecularConfiguration* molC    200           const G4MolecularConfiguration* molConfB = molB->GetMolecularConfiguration();
208           if(molConfB->GetDiffusionCoefficient    201           if(molConfB->GetDiffusionCoefficient() == 0) continue;
209                                                   202 
210           auto it = std::find(reactivesVector-    203           auto it = std::find(reactivesVector->begin(), reactivesVector->end(), molConfB);
211           if(it == reactivesVector->end()) con    204           if(it == reactivesVector->end()) continue;
212                                                   205 
213           G4ThreeVector orgPosB = spaceBin[n]-    206           G4ThreeVector orgPosB = spaceBin[n]->GetPosition();
214           G4double dt = track->GetGlobalTime()    207           G4double dt = track->GetGlobalTime() - spaceBin[n]->GetGlobalTime();
215           G4ThreeVector newPosB = orgPosB;        208           G4ThreeVector newPosB = orgPosB;
216                                                   209 
217           if(dt > 0){                             210           if(dt > 0){
218             G4double sigma, x, y, z;              211             G4double sigma, x, y, z;
219             G4double diffusionCoefficient = G4    212             G4double diffusionCoefficient = G4Molecule::GetMolecule(spaceBin[n])->GetDiffusionCoefficient();
220                                                   213 
221             sigma = std::sqrt(2.0 * diffusionC    214             sigma = std::sqrt(2.0 * diffusionCoefficient * dt);
222                                                   215 
223             x = G4RandGauss::shoot(0., 1.0)*si    216             x = G4RandGauss::shoot(0., 1.0)*sigma;
224             y = G4RandGauss::shoot(0., 1.0)*si    217             y = G4RandGauss::shoot(0., 1.0)*sigma;
225             z = G4RandGauss::shoot(0., 1.0)*si    218             z = G4RandGauss::shoot(0., 1.0)*sigma;
226                                                   219 
227             newPosB = orgPosB + G4ThreeVector(    220             newPosB = orgPosB + G4ThreeVector(x,y,z);
228           }else if(dt < 0) continue;              221           }else if(dt < 0) continue;
229                                                   222 
230           G4double r0 = (newPosB - track->GetP    223           G4double r0 = (newPosB - track->GetPosition()).mag();
231           G4double irt = GetIndependentReactio    224           G4double irt = GetIndependentReactionTime(molConfA,
232                                                   225                                                     molConfB,
233                                                   226                                                     r0);
234           if(irt>=0 && irt<timeMax - globalTim    227           if(irt>=0 && irt<timeMax - globalTime)
235           {                                       228           {
236             irt += globalTime;                    229             irt += globalTime;
237             if(irt < minTime) minTime = irt;      230             if(irt < minTime) minTime = irt;
238 #ifdef DEBUG                                      231 #ifdef DEBUG
239             G4cout<<irt<<'\t'<<molConfA->GetNa    232             G4cout<<irt<<'\t'<<molConfA->GetName()<<" "<<track->GetTrackID()<<'\t'<<molConfB->GetName()<<" "<<spaceBin[n]->GetTrackID()<<'\n';
240 #endif                                            233 #endif
241             fReactionSet->AddReaction(irt,trac    234             fReactionSet->AddReaction(irt,track,spaceBin[n]);
242           }                                       235           }
243         }                                         236         }
244         spaceBin.clear();                         237         spaceBin.clear();
245       }                                           238       }
246     }                                             239     }
247   }                                               240   }
248                                                   241 
249 // Scavenging & first order reactions             242 // Scavenging & first order reactions
250                                                   243 
251   auto fReactionDatas = fMolReactionTable->Get    244   auto fReactionDatas = fMolReactionTable->GetReactionData(molConfA);
252   G4double index = -1;                            245   G4double index = -1;
253   //change the scavenging filter of the IRT be << 
254   if(timeMax > 1*us)                           << 
255   {                                            << 
256     minTime = timeMax;                         << 
257   }                                            << 
258   //                                           << 
259                                                   246 
260   for(size_t u=0; u<fReactionDatas->size();u++    247   for(size_t u=0; u<fReactionDatas->size();u++){
261     if((*fReactionDatas)[u]->GetReactant2()->G    248     if((*fReactionDatas)[u]->GetReactant2()->GetDiffusionCoefficient() == 0){
262       G4double kObs = (*fReactionDatas)[u]->Ge    249       G4double kObs = (*fReactionDatas)[u]->GetObservedReactionRateConstant();
263       if(kObs == 0) continue;                  << 
264       G4double time = -(std::log(1.0 - G4Unifo    250       G4double time = -(std::log(1.0 - G4UniformRand())/kObs) + globalTime;
265       if( time < minTime && time >= globalTime    251       if( time < minTime && time >= globalTime && time < timeMax){
266         minTime = time;                           252         minTime = time;
267         index = (G4int)u;                      << 253         index = (int) u;
268       }                                           254       }
269     }                                             255     }
270   }                                               256   }
271                                                   257 
272   if(index != -1){                                258   if(index != -1){
273 #ifdef DEBUG                                      259 #ifdef DEBUG
274     G4cout<<"scavenged: "<<minTime<<'\t'<<molC    260     G4cout<<"scavenged: "<<minTime<<'\t'<<molConfA->GetName()<<it_begin->GetTrackID()<<'\n';
275 #endif                                            261 #endif
276     auto  fakeMol = new G4Molecule((*fReaction << 262     G4Molecule* fakeMol = new G4Molecule((*fReactionDatas)[index]->GetReactant2());
277     G4Track* fakeTrack = fakeMol->BuildTrack(g    263     G4Track* fakeTrack = fakeMol->BuildTrack(globalTime,track->GetPosition());
278     fTrackHolder->Push(fakeTrack);                264     fTrackHolder->Push(fakeTrack);
279     fReactionSet->AddReaction(minTime, track,     265     fReactionSet->AddReaction(minTime, track, fakeTrack);
280   }                                               266   }
281 }                                                 267 }
282                                                   268 
283                                                   269 
284 G4double G4DNAIRT::GetIndependentReactionTime(    270 G4double G4DNAIRT::GetIndependentReactionTime(const G4MolecularConfiguration* molA, const G4MolecularConfiguration* molB, G4double distance) {
285   const auto pMoleculeA = molA;                   271   const auto pMoleculeA = molA;
286   const auto pMoleculeB = molB;                   272   const auto pMoleculeB = molB;
287   auto fReactionData = fMolReactionTable->GetR    273   auto fReactionData = fMolReactionTable->GetReactionData(pMoleculeA, pMoleculeB);
288   G4int reactionType = fReactionData->GetReact    274   G4int reactionType = fReactionData->GetReactionType();
289   G4double r0 = distance;                         275   G4double r0 = distance;
290   if(r0 == 0) r0 += 1e-3*nm;                      276   if(r0 == 0) r0 += 1e-3*nm;
291   G4double irt = -1 * ps;                         277   G4double irt = -1 * ps;
292   G4double D = molA->GetDiffusionCoefficient()    278   G4double D = molA->GetDiffusionCoefficient() +
293                molB->GetDiffusionCoefficient()    279                molB->GetDiffusionCoefficient();
294   if(D == 0) D += 1e-20*(m2/s);                << 
295   G4double rc = fReactionData->GetOnsagerRadiu    280   G4double rc = fReactionData->GetOnsagerRadius();
296                                                   281 
297   if ( reactionType == 0){                        282   if ( reactionType == 0){
298     G4double sigma = fReactionData->GetEffecti    283     G4double sigma = fReactionData->GetEffectiveReactionRadius();
299                                                   284 
300     if(sigma > r0) return 0; // contact reacti << 
301     if( rc != 0) r0 = -rc / (1-std::exp(rc/r0)    285     if( rc != 0) r0 = -rc / (1-std::exp(rc/r0));
                                                   >> 286     if(sigma > r0) return 0; // contact reaction
302                                                   287 
303     G4double Winf = sigma/r0;                     288     G4double Winf = sigma/r0;
304     G4double W = G4UniformRand();                 289     G4double W = G4UniformRand();
305                                                   290 
306     if ( W > 0 && W < Winf ) irt = (0.25/D) *  << 291     if ( W < Winf ) irt = (0.25/D) * std::pow( (r0-sigma)/erfc->erfcInv(r0*W/sigma), 2 );
307                                                   292 
308     return irt;                                   293     return irt;
309   }                                               294   }
310   if ( reactionType == 1 ){                    << 295   else if ( reactionType == 1 ){
311     G4double sigma = fReactionData->GetReactio    296     G4double sigma = fReactionData->GetReactionRadius();
312     G4double kact = fReactionData->GetActivati    297     G4double kact = fReactionData->GetActivationRateConstant();
313     G4double kdif = fReactionData->GetDiffusio    298     G4double kdif = fReactionData->GetDiffusionRateConstant();
314     G4double kobs = fReactionData->GetObserved    299     G4double kobs = fReactionData->GetObservedReactionRateConstant();
315                                                   300 
316     G4double a, b, Winf;                          301     G4double a, b, Winf;
317                                                   302 
318     if ( rc == 0 ) {                              303     if ( rc == 0 ) {
319       a = 1/sigma * kact / kobs;                  304       a = 1/sigma * kact / kobs;
320       b = (r0 - sigma) / 2;                       305       b = (r0 - sigma) / 2;
321     } else {                                      306     } else {
322       G4double v = kact/Avogadro/(4*CLHEP::pi*    307       G4double v = kact/Avogadro/(4*CLHEP::pi*pow(sigma,2) * exp(-rc / sigma));
323       G4double alpha = v+rc*D/(pow(sigma,2)*(1    308       G4double alpha = v+rc*D/(pow(sigma,2)*(1-exp(-rc/sigma)));
324       a = 4*pow(sigma,2)*alpha/(D*pow(rc,2))*p    309       a = 4*pow(sigma,2)*alpha/(D*pow(rc,2))*pow(sinh(rc/(2*sigma)),2);
325       b = rc/4*(cosh(rc/(2*r0))/sinh(rc/(2*r0)    310       b = rc/4*(cosh(rc/(2*r0))/sinh(rc/(2*r0))-cosh(rc/(2*sigma))/sinh(rc/(2*sigma)));
326       r0 = -rc/(1-std::exp(rc/r0));               311       r0 = -rc/(1-std::exp(rc/r0));
327       sigma = fReactionData->GetEffectiveReact    312       sigma = fReactionData->GetEffectiveReactionRadius();
328     }                                             313     }
329                                                   314 
330     if(sigma > r0){                               315     if(sigma > r0){
331       if(fReactionData->GetProbability() > G4U    316       if(fReactionData->GetProbability() > G4UniformRand()) return 0;
332       return irt;                              << 317       else return irt;
333     }                                             318     }
334     Winf = sigma / r0 * kobs / kdif;              319     Winf = sigma / r0 * kobs / kdif;
335                                                   320 
336     if(Winf > G4UniformRand()) irt = SamplePDC    321     if(Winf > G4UniformRand()) irt = SamplePDC(a,b)/D;
337     return irt;                                << 322       return irt;
338   }                                            << 323     }
339                                                   324 
340   return -1 * ps;                                 325   return -1 * ps;
341 }                                                 326 }
342                                                   327 
343 G4int G4DNAIRT::FindBin(G4int n, G4double xmin    328 G4int G4DNAIRT::FindBin(G4int n, G4double xmin, G4double xmax, G4double value) {
344                                                   329 
345   G4int bin = -1;                                 330   G4int bin = -1;
346   if ( value <= xmin )                            331   if ( value <= xmin )
347     bin = 0; //1;                                 332     bin = 0; //1;
348   else if ( value >= xmax)  //!(xmax < value)     333   else if ( value >= xmax)  //!(xmax < value) ) //value >= xmax )
349     bin = n-1; //n;                               334     bin = n-1; //n;
350   else                                            335   else
351     bin = G4int( n * ( value - xmin )/( xmax -    336     bin = G4int( n * ( value - xmin )/( xmax - xmin ) ); //bin = 1 + G4int( n * ( value - xmin )/( xmax - xmin ) );
352                                                   337 
353   if ( bin < 0 ) bin = 0;                         338   if ( bin < 0 ) bin = 0;
354   if ( bin >= n ) bin = n-1;                      339   if ( bin >= n ) bin = n-1;
355                                                   340 
356   return bin;                                     341   return bin;
357 }                                                 342 }
358                                                   343 
359 G4double G4DNAIRT::SamplePDC(G4double a, G4dou    344 G4double G4DNAIRT::SamplePDC(G4double a, G4double b) {
360                                                   345 
361   G4double p = 2.0 * std::sqrt(2.0*b/a);          346   G4double p = 2.0 * std::sqrt(2.0*b/a);
362   G4double q = 2.0 / std::sqrt(2.0*b/a);          347   G4double q = 2.0 / std::sqrt(2.0*b/a);
363   G4double M = max(1.0/(a*a),3.0*b/a);            348   G4double M = max(1.0/(a*a),3.0*b/a);
364                                                   349 
365   G4double X, U, lambdax;                         350   G4double X, U, lambdax;
366                                                   351 
367   G4int ntrials = 0;                              352   G4int ntrials = 0;
368   while(true) {                                << 353   while(1) {
369                                                   354 
370     // Generate X                                 355     // Generate X
371     U = G4UniformRand();                          356     U = G4UniformRand();
372     if ( U < p/(p + q * M) ) X = pow(U * (p +     357     if ( U < p/(p + q * M) ) X = pow(U * (p + q * M) / 2, 2);
373     else X = pow(2/((1-U)*(p+q*M)/M),2);          358     else X = pow(2/((1-U)*(p+q*M)/M),2);
374                                                   359 
375     U = G4UniformRand();                          360     U = G4UniformRand();
376                                                   361 
377     lambdax = std::exp(-b*b/X) * ( 1.0 - a * s    362     lambdax = std::exp(-b*b/X) * ( 1.0 - a * std::sqrt(CLHEP::pi * X) * erfc->erfcx(b/std::sqrt(X) + a*std::sqrt(X)));
378                                                   363 
379     if ((X <= 2.0*b/a && U <= lambdax) ||         364     if ((X <= 2.0*b/a && U <= lambdax) ||
380         (X >= 2.0*b/a && U*M/X <= lambdax)) br    365         (X >= 2.0*b/a && U*M/X <= lambdax)) break;
381                                                   366 
382     ntrials++;                                    367     ntrials++;
383                                                   368 
384     if ( ntrials > 10000 ){                       369     if ( ntrials > 10000 ){
385       G4cout<<"Totally rejected"<<'\n';           370       G4cout<<"Totally rejected"<<'\n';
386       return -1.0;                                371       return -1.0;
387     }                                             372     }
388   }                                               373   }
389   return X;                                       374   return X;
390 }                                                 375 }
391                                                   376 
392 std::unique_ptr<G4ITReactionChange> G4DNAIRT::    377 std::unique_ptr<G4ITReactionChange> G4DNAIRT::MakeReaction(const G4Track& trackA,
393                                                   378                                                          const G4Track& trackB)
394 {                                                 379 {
395                                                   380 
396   std::unique_ptr<G4ITReactionChange> pChanges    381   std::unique_ptr<G4ITReactionChange> pChanges(new G4ITReactionChange());
397   pChanges->Initialize(trackA, trackB);           382   pChanges->Initialize(trackA, trackB);
398                                                   383 
399   const auto pMoleculeA = GetMolecule(trackA)-    384   const auto pMoleculeA = GetMolecule(trackA)->GetMolecularConfiguration();
400   const auto pMoleculeB = GetMolecule(trackB)-    385   const auto pMoleculeB = GetMolecule(trackB)->GetMolecularConfiguration();
401   const auto pReactionData = fMolReactionTable    386   const auto pReactionData = fMolReactionTable->GetReactionData(pMoleculeA, pMoleculeB);
402                                                   387 
403   G4double globalTime = G4Scheduler::Instance(    388   G4double globalTime = G4Scheduler::Instance()->GetGlobalTime();
404   G4double effectiveReactionRadius = pReaction    389   G4double effectiveReactionRadius = pReactionData->GetEffectiveReactionRadius();
405                                                   390 
406   const G4double D1 = pMoleculeA->GetDiffusion    391   const G4double D1 = pMoleculeA->GetDiffusionCoefficient();
407   const G4double D2 = pMoleculeB->GetDiffusion    392   const G4double D2 = pMoleculeB->GetDiffusionCoefficient();
408                                                   393 
409   G4ThreeVector r1 = trackA.GetPosition();        394   G4ThreeVector r1 = trackA.GetPosition();
410   G4ThreeVector r2 = trackB.GetPosition();        395   G4ThreeVector r2 = trackB.GetPosition();
411                                                   396 
412   if(r1 == r2) r2 += G4ThreeVector(0,0,1e-3*nm    397   if(r1 == r2) r2 += G4ThreeVector(0,0,1e-3*nm);
413                                                   398 
414   G4ThreeVector S1 = r1 - r2;                     399   G4ThreeVector S1 = r1 - r2;
415                                                   400 
416   G4double r0 = S1.mag();                         401   G4double r0 = S1.mag();
417                                                   402 
418   S1.setMag(effectiveReactionRadius);             403   S1.setMag(effectiveReactionRadius);
419                                                   404 
420   G4double dt = globalTime - trackA.GetGlobalT    405   G4double dt = globalTime - trackA.GetGlobalTime();
421                                                   406 
422   if(dt != 0 && (D1 + D2) != 0 && r0 != 0){    << 407   if(dt != 0){
423     G4double s12 = 2.0 * D1 * dt;                 408     G4double s12 = 2.0 * D1 * dt;
424     G4double s22 = 2.0 * D2 * dt;                 409     G4double s22 = 2.0 * D2 * dt;
425     if(s12 == 0) r2 = r1;                         410     if(s12 == 0) r2 = r1;
426     else if(s22 == 0) r1 = r2;                    411     else if(s22 == 0) r1 = r2;
427     else{                                         412     else{
428       G4double alpha = effectiveReactionRadius    413       G4double alpha = effectiveReactionRadius * r0 / (2*(D1 + D2)*dt);
429       G4ThreeVector S2 = (r1 + (s12 / s22)*r2)    414       G4ThreeVector S2 = (r1 + (s12 / s22)*r2) + G4ThreeVector(G4RandGauss::shoot(0, s12 + s22 * s22 / s12),
430                                                   415                                                                G4RandGauss::shoot(0, s12 + s22 * s22 / s12),
431                                                   416                                                                G4RandGauss::shoot(0, s12 + s22 * s22 / s12));
432                                                   417 
433       if(alpha == 0){                          << 
434         return pChanges;                       << 
435       }                                        << 
436       S1.setPhi(rad * G4UniformRand() * 2.0 *     418       S1.setPhi(rad * G4UniformRand() * 2.0 * CLHEP::pi);
437       S1.setTheta(rad * std::acos(1.0 + 1./alp    419       S1.setTheta(rad * std::acos(1.0 + 1./alpha * std::log(1.0 - G4UniformRand() * (1 - std::exp(-2.0 * alpha)))));
438                                                   420 
439       r1 = (D1 * S1 + D2 * S2) / (D1 + D2);       421       r1 = (D1 * S1 + D2 * S2) / (D1 + D2);
440       r2 = D2 * (S2 - S1) / (D1 + D2);            422       r2 = D2 * (S2 - S1) / (D1 + D2);
441     }                                             423     }
442   }                                               424   }
443                                                   425 
444   auto pTrackA = const_cast<G4Track*>(pChanges    426   auto pTrackA = const_cast<G4Track*>(pChanges->GetTrackA());
445   auto pTrackB = const_cast<G4Track*>(pChanges    427   auto pTrackB = const_cast<G4Track*>(pChanges->GetTrackB());
446                                                   428 
447   pTrackA->SetPosition(r1);                       429   pTrackA->SetPosition(r1);
448   pTrackB->SetPosition(r2);                       430   pTrackB->SetPosition(r2);
449                                                   431 
450   pTrackA->SetGlobalTime(globalTime);             432   pTrackA->SetGlobalTime(globalTime);
451   pTrackB->SetGlobalTime(globalTime);             433   pTrackB->SetGlobalTime(globalTime);
452                                                   434 
453   pTrackA->SetTrackStatus(fStopButAlive);         435   pTrackA->SetTrackStatus(fStopButAlive);
454   pTrackB->SetTrackStatus(fStopButAlive);         436   pTrackB->SetTrackStatus(fStopButAlive);
455                                                   437 
456   const G4int nbProducts = pReactionData->GetN    438   const G4int nbProducts = pReactionData->GetNbProducts();
457                                                   439 
458   if(nbProducts != 0){                         << 440   if(nbProducts){
459                                                   441 
460     const G4double sqrD1 = D1 == 0. ? 0. : std    442     const G4double sqrD1 = D1 == 0. ? 0. : std::sqrt(D1);
461     const G4double sqrD2 = D2 == 0. ? 0. : std    443     const G4double sqrD2 = D2 == 0. ? 0. : std::sqrt(D2);
462     if((sqrD1 + sqrD2) == 0){                  << 
463       return pChanges;                         << 
464     }                                          << 
465     const G4double inv_numerator = 1./(sqrD1 +    444     const G4double inv_numerator = 1./(sqrD1 + sqrD2);
466     const G4ThreeVector reactionSite = sqrD2 *    445     const G4ThreeVector reactionSite = sqrD2 * inv_numerator * trackA.GetPosition()
467                                      + sqrD1 *    446                                      + sqrD1 * inv_numerator * trackB.GetPosition();
468                                                   447 
469     std::vector<G4ThreeVector> position;          448     std::vector<G4ThreeVector> position;
470                                                   449 
471     if(nbProducts == 1){                          450     if(nbProducts == 1){
472       position.push_back(reactionSite);           451       position.push_back(reactionSite);
473     }else if(nbProducts == 2){                    452     }else if(nbProducts == 2){
474       position.push_back(trackA.GetPosition())    453       position.push_back(trackA.GetPosition());
475       position.push_back(trackB.GetPosition())    454       position.push_back(trackB.GetPosition());
476     }else if (nbProducts == 3){                   455     }else if (nbProducts == 3){
477       position.push_back(reactionSite);           456       position.push_back(reactionSite);
478       position.push_back(trackA.GetPosition())    457       position.push_back(trackA.GetPosition());
479       position.push_back(trackB.GetPosition())    458       position.push_back(trackB.GetPosition());
480     }                                             459     }
481                                                   460 
482     for(G4int u = 0; u < nbProducts; u++){        461     for(G4int u = 0; u < nbProducts; u++){
483                                                   462 
484       auto product = new G4Molecule(pReactionD    463       auto product = new G4Molecule(pReactionData->GetProduct(u));
485       auto productTrack = product->BuildTrack(    464       auto productTrack = product->BuildTrack(globalTime,
486                                                   465                                               position[u]);
487                                                   466 
488       productTrack->SetTrackStatus(fAlive);       467       productTrack->SetTrackStatus(fAlive);
489       fTrackHolder->Push(productTrack);           468       fTrackHolder->Push(productTrack);
490                                                   469 
491       pChanges->AddSecondary(productTrack);       470       pChanges->AddSecondary(productTrack);
492                                                   471 
493       G4int I = FindBin(fNx, fXMin, fXMax, pos    472       G4int I = FindBin(fNx, fXMin, fXMax, position[u].x());
494       G4int J = FindBin(fNy, fYMin, fYMax, pos    473       G4int J = FindBin(fNy, fYMin, fYMax, position[u].y());
495       G4int K = FindBin(fNz, fZMin, fZMax, pos    474       G4int K = FindBin(fNz, fZMin, fZMax, position[u].z());
496                                                   475 
497       spaceBinned[I][J][K].push_back(productTr    476       spaceBinned[I][J][K].push_back(productTrack);
498                                                   477 
499       Sampling(productTrack);                     478       Sampling(productTrack);
500     }                                             479     }
501   }                                               480   }
502                                                   481 
503   fTrackHolder->MergeSecondariesWithMainList()    482   fTrackHolder->MergeSecondariesWithMainList();
504   pChanges->KillParents(true);                    483   pChanges->KillParents(true);
505   return pChanges;                                484   return pChanges;
506 }                                                 485 }
507                                                   486 
508                                                   487 
509 std::vector<std::unique_ptr<G4ITReactionChange    488 std::vector<std::unique_ptr<G4ITReactionChange>> G4DNAIRT::FindReaction(
510   G4ITReactionSet* pReactionSet,                  489   G4ITReactionSet* pReactionSet,
511   const G4double /*currentStepTime*/,          << 490   const double /*currentStepTime*/,
512   const G4double fGlobalTime,                  << 491   const double fGlobalTime,
513   const G4bool /*reachedUserStepTimeLimit*/)   << 492   const bool /*reachedUserStepTimeLimit*/)
514 {                                                 493 {
515   std::vector<std::unique_ptr<G4ITReactionChan    494   std::vector<std::unique_ptr<G4ITReactionChange>> fReactionInfo;
516   fReactionInfo.clear();                          495   fReactionInfo.clear();
517                                                   496 
518   if (pReactionSet == nullptr)                    497   if (pReactionSet == nullptr)
519   {                                               498   {
520     return fReactionInfo;                         499     return fReactionInfo;
521   }                                               500   }
522                                                   501 
523   auto fReactionsetInTime = pReactionSet->GetR    502   auto fReactionsetInTime = pReactionSet->GetReactionsPerTime();
524   assert(fReactionsetInTime.begin() != fReacti    503   assert(fReactionsetInTime.begin() != fReactionsetInTime.end());
525                                                   504 
526   auto it_begin = fReactionsetInTime.begin();     505   auto it_begin = fReactionsetInTime.begin();
527   while(it_begin != fReactionsetInTime.end())     506   while(it_begin != fReactionsetInTime.end())
528   {                                               507   {
529     G4double irt = it_begin->get()->GetTime();    508     G4double irt = it_begin->get()->GetTime();
530                                                   509 
531     if(fGlobalTime < irt) break;                  510     if(fGlobalTime < irt) break;
532                                                   511 
533     pReactionSet->SelectThisReaction(*it_begin    512     pReactionSet->SelectThisReaction(*it_begin);
534                                                   513 
535     G4Track* pTrackA = it_begin->get()->GetRea    514     G4Track* pTrackA = it_begin->get()->GetReactants().first;
536     G4Track* pTrackB = it_begin->get()->GetRea    515     G4Track* pTrackB = it_begin->get()->GetReactants().second;
537     auto pReactionChange = MakeReaction(*pTrac    516     auto pReactionChange = MakeReaction(*pTrackA, *pTrackB);
538                                                   517 
539     if(pReactionChange){                          518     if(pReactionChange){
540       fReactionInfo.push_back(std::move(pReact    519       fReactionInfo.push_back(std::move(pReactionChange));
541     }                                             520     }
542                                                   521 
543     fReactionsetInTime = pReactionSet->GetReac    522     fReactionsetInTime = pReactionSet->GetReactionsPerTime();
544     it_begin = fReactionsetInTime.begin();        523     it_begin = fReactionsetInTime.begin();
545   }                                               524   }
546                                                   525 
547   return fReactionInfo;                           526   return fReactionInfo;
548 }                                                 527 }
549                                                   528 
550 G4bool G4DNAIRT::TestReactibility(const G4Trac    529 G4bool G4DNAIRT::TestReactibility(const G4Track& /*trackA*/,
551   const G4Track& /*trackB*/,                      530   const G4Track& /*trackB*/,
552   G4double /*currentStepTime*/,                << 531   double /*currentStepTime*/,
553   G4bool /*userStepTimeLimit*/) /*const*/      << 532   bool /*userStepTimeLimit*/) /*const*/
554 {                                                 533 {
555   return true;                                    534   return true;
556 }                                                 535 }
557                                                   536 
558 void G4DNAIRT::SetReactionModel(G4VDNAReaction    537 void G4DNAIRT::SetReactionModel(G4VDNAReactionModel* model)
559 {                                                 538 {
560   fpReactionModel = model;                        539   fpReactionModel = model;
561 }                                                 540 }
562                                                   541