53fpReactionModel(nullptr),
72 xiniIndex = 0, yiniIndex = 0, ziniIndex = 0;
73 xendIndex = 0, yendIndex = 0, zendIndex = 0;
76 1.45 * nm + 2 * std::sqrt(8*9.46e9*nm*nm/s * timeMax);
147 fNx =
G4int((fXMax-fXMin)/fRCutOff) == 0 ? 1 :
G4int((fXMax-fXMin)/fRCutOff);
148 fNy =
G4int((fYMax-fYMin)/fRCutOff) == 0 ? 1 :
G4int((fYMax-fYMin)/fRCutOff);
149 fNz =
G4int((fZMax-fZMin)/fRCutOff) == 0 ? 1 :
G4int((fZMax-fZMin)/fRCutOff);
157 G4int I =
FindBin(fNx, fXMin, fXMax, it_begin->GetPosition().x());
158 G4int J =
FindBin(fNy, fYMin, fYMax, it_begin->GetPosition().y());
159 G4int K =
FindBin(fNz, fZMin, fZMax, it_begin->GetPosition().z());
161 spaceBinned[I][J][K].push_back(*it_begin);
173 const vector<const G4MolecularConfiguration*>* reactivesVector =
176 if(reactivesVector ==
nullptr)
return;
188 for (
int ii = xiniIndex; ii <= xendIndex; ii++ ) {
189 for (
int jj = yiniIndex; jj <= yendIndex; jj++ ) {
190 for (
int kk = ziniIndex; kk <= zendIndex; kk++ ) {
192 std::vector<G4Track*> spaceBin = spaceBinned[ii][jj][kk];
193 for (
int n = 0; n < (int)spaceBinned[ii][jj][kk].size(); n++ ) {
194 if(!spaceBin[n] || track == spaceBin[n])
continue;
203 auto it = std::find(reactivesVector->begin(), reactivesVector->end(), molConfB);
204 if(it == reactivesVector->end())
continue;
214 sigma = std::sqrt(2.0 * diffusionCoefficient * dt);
216 x = G4RandGauss::shoot(0., 1.0)*sigma;
217 y = G4RandGauss::shoot(0., 1.0)*sigma;
218 z = G4RandGauss::shoot(0., 1.0)*sigma;
221 }
else if(dt < 0)
continue;
227 if(irt>=0 && irt<timeMax - globalTime)
230 if(irt < minTime) minTime = irt;
247 for(
size_t u=0; u<fReactionDatas->size();u++){
248 if((*fReactionDatas)[u]->GetReactant2()->GetDiffusionCoefficient() == 0){
251 if( time < minTime && time >= globalTime && time < timeMax){
260 G4cout<<
"scavenged: "<<minTime<<
'\t'<<molConfA->
GetName()<<it_begin->GetTrackID()<<
'\n';
264 fTrackHolder->
Push(fakeTrack);
265 fReactionSet->
AddReaction(minTime, track, fakeTrack);
271 const auto pMoleculeA = molA;
272 const auto pMoleculeB = molB;
276 if(r0 == 0) r0 += 1e-3*nm;
280 G4double rc = fReactionData->GetOnsagerRadius();
282 if ( reactionType == 0){
283 G4double sigma = fReactionData->GetEffectiveReactionRadius();
285 if( rc != 0) r0 = -rc / (1-std::exp(rc/r0));
286 if(sigma > r0)
return 0;
291 if ( W < Winf ) irt = (0.25/
D) * std::pow( (r0-sigma)/erfc->
erfcInv(r0*W/sigma), 2 );
295 else if ( reactionType == 1 ){
296 G4double sigma = fReactionData->GetReactionRadius();
297 G4double kact = fReactionData->GetActivationRateConstant();
298 G4double kdif = fReactionData->GetDiffusionRateConstant();
299 G4double kobs = fReactionData->GetObservedReactionRateConstant();
304 a = 1/sigma * kact / kobs;
305 b = (r0 - sigma) / 2;
307 G4double v = kact/Avogadro/(4*CLHEP::pi*pow(sigma,2) * exp(-rc / sigma));
308 G4double alpha = v+rc*
D/(pow(sigma,2)*(1-exp(-rc/sigma)));
309 a = 4*pow(sigma,2)*alpha/(
D*pow(rc,2))*pow(sinh(rc/(2*sigma)),2);
310 b = rc/4*(cosh(rc/(2*r0))/sinh(rc/(2*r0))-cosh(rc/(2*sigma))/sinh(rc/(2*sigma)));
311 r0 = -rc/(1-std::exp(rc/r0));
312 sigma = fReactionData->GetEffectiveReactionRadius();
316 if(fReactionData->GetProbability() >
G4UniformRand())
return 0;
319 Winf = sigma / r0 * kobs / kdif;
333 else if ( value >= xmax)
336 bin =
G4int( n * ( value - xmin )/( xmax - xmin ) );
338 if ( bin < 0 ) bin = 0;
339 if ( bin >= n ) bin = n-1;
346 G4double p = 2.0 * std::sqrt(2.0*b/a);
347 G4double q = 2.0 / std::sqrt(2.0*b/a);
348 G4double M = max(1.0/(a*a),3.0*b/a);
357 if ( U < p/(p + q * M) ) X = pow(U * (p + q * M) / 2, 2);
358 else X = pow(2/((1-U)*(p+q*M)/M),2);
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)));
364 if ((X <= 2.0*b/a && U <= lambdax) ||
365 (X >= 2.0*b/a && U*M/X <= lambdax))
break;
369 if ( ntrials > 10000 ){
370 G4cout<<
"Totally rejected"<<
'\n';
382 pChanges->Initialize(trackA, trackB);
389 G4double effectiveReactionRadius = pReactionData->GetEffectiveReactionRadius();
391 const G4double D1 = pMoleculeA->GetDiffusionCoefficient();
392 const G4double D2 = pMoleculeB->GetDiffusionCoefficient();
403 S1.
setMag(effectiveReactionRadius);
410 if(s12 == 0) r2 = r1;
411 else if(s22 == 0) r1 = r2;
413 G4double alpha = effectiveReactionRadius * r0 / (2*(D1 + D2)*dt);
415 G4RandGauss::shoot(0, s12 + s22 * s22 / s12),
416 G4RandGauss::shoot(0, s12 + s22 * s22 / s12));
419 S1.
setTheta(rad * std::acos(1.0 + 1./alpha * std::log(1.0 -
G4UniformRand() * (1 - std::exp(-2.0 * alpha)))));
421 r1 = (D1 * S1 + D2 * S2) / (D1 + D2);
422 r2 = D2 * (S2 - S1) / (D1 + D2);
426 auto pTrackA =
const_cast<G4Track*
>(pChanges->GetTrackA());
427 auto pTrackB =
const_cast<G4Track*
>(pChanges->GetTrackB());
430 pTrackB->SetPosition(r2);
432 pTrackA->SetGlobalTime(globalTime);
433 pTrackB->SetGlobalTime(globalTime);
438 const G4int nbProducts = pReactionData->GetNbProducts();
442 const G4double sqrD1 = D1 == 0. ? 0. : std::sqrt(D1);
443 const G4double sqrD2 = D2 == 0. ? 0. : std::sqrt(D2);
444 const G4double inv_numerator = 1./(sqrD1 + sqrD2);
448 std::vector<G4ThreeVector>
position;
452 }
else if(nbProducts == 2){
455 }
else if (nbProducts == 3){
461 for(
G4int u = 0; u < nbProducts; u++){
463 auto product =
new G4Molecule(pReactionData->GetProduct(u));
464 auto productTrack = product->BuildTrack(globalTime,
467 productTrack->SetTrackStatus(
fAlive);
468 fTrackHolder->
Push(productTrack);
470 pChanges->AddSecondary(productTrack);
476 spaceBinned[I][J][K].push_back(productTrack);
483 pChanges->KillParents(
true);
491 const double fGlobalTime,
494 std::vector<std::unique_ptr<G4ITReactionChange>> fReactionInfo;
495 fReactionInfo.clear();
497 if (pReactionSet ==
nullptr)
499 return fReactionInfo;
503 assert(fReactionsetInTime.begin() != fReactionsetInTime.end());
505 auto it_begin = fReactionsetInTime.begin();
506 while(it_begin != fReactionsetInTime.end())
508 G4double irt = it_begin->get()->GetTime();
510 if(fGlobalTime < irt)
break;
514 G4Track* pTrackA = it_begin->get()->GetReactants().first;
515 G4Track* pTrackB = it_begin->get()->GetReactants().second;
516 auto pReactionChange =
MakeReaction(*pTrackA, *pTrackB);
519 fReactionInfo.push_back(std::move(pReactionChange));
523 it_begin = fReactionsetInTime.begin();
526 return fReactionInfo;
G4Molecule * GetMolecule(const G4Track &track)
ReturnType & reference_cast(OriginalType &source)
CLHEP::Hep3Vector G4ThreeVector
G4GLOB_DLL std::ostream G4cout
void SetReactionModel(G4VDNAReactionModel *)
G4double SamplePDC(G4double, G4double)
const G4DNAMolecularReactionTable *& fMolReactionTable
void Initialize() override
G4int FindBin(G4int, G4double, G4double, G4double)
G4double GetIndependentReactionTime(const G4MolecularConfiguration *, const G4MolecularConfiguration *, G4double)
std::unique_ptr< G4ITReactionChange > MakeReaction(const G4Track &, const G4Track &) override
std::vector< std::unique_ptr< G4ITReactionChange > > FindReaction(G4ITReactionSet *, const double, const double, const bool) override
G4bool TestReactibility(const G4Track &, const G4Track &, double, bool) override
G4VDNAReactionModel * fpReactionModel
G4int GetReactionType() const
G4double GetObservedReactionRateConstant() const
Data * GetReactionData(Reactant *, Reactant *) const
const ReactantList * CanReactWith(Reactant *) const
static G4double erfcx(G4double x)
static G4double erfcInv(G4double x)
static G4ITReactionSet * Instance()
void SelectThisReaction(G4ITReactionPtr reaction)
void AddReaction(double time, G4Track *trackA, G4Track *trackB)
G4ITReactionPerTime & GetReactionsPerTime()
G4TrackList * GetMainList(Key)
virtual void Push(G4Track *)
void MergeSecondariesWithMainList()
static G4ITTrackHolder * Instance()
const G4String & GetName() const
G4double GetDiffusionCoefficient() const
static G4Molecule * GetMolecule(const G4Track *)
const G4MolecularConfiguration * GetMolecularConfiguration() const
G4Track * BuildTrack(G4double globalTime, const G4ThreeVector &Position)
G4double GetDiffusionCoefficient() const
static G4Scheduler * Instance()
G4double GetEndTime() const
G4double GetGlobalTime() const
G4double GetStartTime() const
void SetPosition(const G4ThreeVector &aValue)
const G4ThreeVector & GetPosition() const
G4double GetGlobalTime() const