57fpReactionModel(nullptr),
152 G4double sqrt_2Dt = sqrt(2 *
D * time_step);
161 it_begin->SetGlobalTime(
timeMax);
200 const vector<const G4MolecularConfiguration*>* reactivesVector =
203 if(reactivesVector ==
nullptr)
return;
219 std::vector<G4Track*> spaceBin =
spaceBinned[ii][jj][kk];
221 if(!spaceBin[
n] || track == spaceBin[
n])
continue;
230 auto it = std::find(reactivesVector->begin(), reactivesVector->end(), molConfB);
231 if(it == reactivesVector->end())
continue;
241 sigma = std::sqrt(2.0 * diffusionCoefficient * dt);
248 }
else if(dt < 0)
continue;
254 if(irt>=0 && irt<
timeMax - globalTime)
257 if(irt < minTime) minTime = irt;
274 for(
size_t u=0; u<fReactionDatas->size();++u){
279 G4double kObs = (*fReactionDatas)[u]->GetObservedReactionRateConstant();
280 if(kObs == 0)
continue;
282 if( time < minTime && time >= globalTime && time <
timeMax){
291 G4cout<<
"scavenged: "<<minTime<<
'\t'<<molConfA->
GetName()<<it_begin->GetTrackID()<<
'\n';
304 if(touchable ==
nullptr)
return;
313 G4double search_range = 2*sqrt(2*
D*time_step);
315 std::vector<G4VPhysicalVolume*> result_pv;
322 if(result_pv.empty())
return;
324 for(
auto physicalVolume : result_pv){
329 auto it = std::find(reactivesVector->begin(), reactivesVector->end(), dna_molConf);
330 if(it == reactivesVector->end())
continue;
338 if(irt>=0 && irt<
timeMax - globalTime)
352 DNATrack = DNAMol->BuildTrack(globalTime,globalPos_DNA);
355 positionMap.push_back(std::make_pair(globalPos_DNA,DNATrack));
361 if(irt < minTime) minTime = irt;
372 const auto pMoleculeA = molA;
373 const auto pMoleculeB = molB;
377 if(r0 == 0) r0 += 1e-3*
nm;
381 if(
D == 0)
D += 1e-20*(
m2/
s);
382 G4double rc = fReactionData->GetOnsagerRadius();
384 if ( reactionType == 0){
385 G4double sigma = fReactionData->GetEffectiveReactionRadius();
387 if(sigma > r0)
return 0;
388 if( rc != 0) r0 = -rc / (1-std::exp(rc/r0));
393 if ( W > 0 && W < Winf ) irt = (0.25/
D) * std::pow( (r0-sigma)/
erfc->
erfcInv(r0*W/sigma), 2 );
397 else if ( reactionType == 1 ){
398 G4double sigma = fReactionData->GetReactionRadius();
399 G4double kact = fReactionData->GetActivationRateConstant();
400 G4double kdif = fReactionData->GetDiffusionRateConstant();
401 G4double kobs = fReactionData->GetObservedReactionRateConstant();
406 a = 1/sigma * kact / kobs;
407 b = (r0 - sigma) / 2;
411 a = 4*pow(sigma,2)*
alpha/(
D*pow(rc,2))*pow(sinh(rc/(2*sigma)),2);
412 b = rc/4*(cosh(rc/(2*r0))/sinh(rc/(2*r0))-cosh(rc/(2*sigma))/sinh(rc/(2*sigma)));
413 r0 = -rc/(1-std::exp(rc/r0));
414 sigma = fReactionData->GetEffectiveReactionRadius();
418 if(fReactionData->GetProbability() >
G4UniformRand())
return 0;
421 Winf = sigma / r0 * kobs / kdif;
435 else if ( value >= xmax)
438 bin =
G4int(
n * ( value - xmin )/( xmax - xmin ) );
440 if ( bin < 0 ) bin = 0;
441 if ( bin >=
n ) bin =
n-1;
448 G4double p = 2.0 * std::sqrt(2.0*b/a);
449 G4double q = 2.0 / std::sqrt(2.0*b/a);
459 if ( U < p/(p + q *
M) ) X = pow(U * (p + q *
M) / 2, 2);
460 else X = pow(2/((1-U)*(p+q*
M)/
M),2);
464 lambdax = std::exp(-b*b/X) * ( 1.0 - a * std::sqrt(
CLHEP::pi * X) *
erfc->
erfcx(b/std::sqrt(X) + a*std::sqrt(X)));
466 if ((X <= 2.0*b/a && U <= lambdax) ||
467 (X >= 2.0*b/a && U*
M/X <= lambdax))
break;
471 if ( ntrials > 10000 ){
472 G4cout<<
"Totally rejected"<<
'\n';
484 pChanges->Initialize(trackA, trackB);
491 G4double effectiveReactionRadius = pReactionData->GetEffectiveReactionRadius();
493 const G4double D1 = pMoleculeA->GetDiffusionCoefficient();
494 const G4double D2 = pMoleculeB->GetDiffusionCoefficient();
505 S1.
setMag(effectiveReactionRadius);
509 if(dt != 0 && (D1 + D2) != 0 && r0 != 0){
512 if(s12 == 0) r2 = r1;
513 else if(s22 == 0) r1 = r2;
515 G4double alpha = effectiveReactionRadius * r0 / (2*(D1 + D2)*dt);
523 r1 = (D1 * S1 + D2 * S2) / (D1 + D2);
524 r2 = D2 * (S2 - S1) / (D1 + D2);
528 auto pTrackA =
const_cast<G4Track*
>(pChanges->GetTrackA());
529 auto pTrackB =
const_cast<G4Track*
>(pChanges->GetTrackB());
532 pTrackB->SetPosition(r2);
534 pTrackA->SetGlobalTime(globalTime);
535 pTrackB->SetGlobalTime(globalTime);
540 const G4int nbProducts = pReactionData->GetNbProducts();
544 const G4double sqrD1 = D1 == 0. ? 0. : std::sqrt(D1);
545 const G4double sqrD2 = D2 == 0. ? 0. : std::sqrt(D2);
546 const G4double inv_numerator = 1./(sqrD1 + sqrD2);
550 std::vector<G4ThreeVector>
position;
554 }
else if(nbProducts == 2){
557 }
else if (nbProducts == 3){
563 for(
G4int u = 0; u < nbProducts; ++u){
565 auto product =
new G4Molecule(pReactionData->GetProduct(u));
566 auto productTrack = product->BuildTrack(globalTime,
569 productTrack->SetTrackStatus(
fAlive);
572 pChanges->AddSecondary(productTrack);
585 pChanges->KillParents(
true);
596 std::vector<std::unique_ptr<G4ITReactionChange>> fReactionInfo;
597 fReactionInfo.clear();
599 if (pReactionSet ==
nullptr)
601 return fReactionInfo;
605 assert(fReactionsetInTime.begin() != fReactionsetInTime.end());
607 auto it_begin = fReactionsetInTime.begin();
608 while(it_begin != fReactionsetInTime.end())
610 G4double irt = it_begin->get()->GetTime();
612 if(fGlobalTime < irt)
break;
616 G4Track* pTrackA = it_begin->get()->GetReactants().first;
617 G4Track* pTrackB = it_begin->get()->GetReactants().second;
618 auto pReactionChange =
MakeReaction(*pTrackA, *pTrackB);
621 fReactionInfo.push_back(std::move(pReactionChange));
625 it_begin = fReactionsetInTime.begin();
628 return fReactionInfo;
G4double D(G4double temp)
static const G4double pos
static const G4double alpha
G4Molecule * GetMolecule(const G4Track &track)
ReturnType & reference_cast(OriginalType &source)
static constexpr double nm
static constexpr double rad
static constexpr double s
static constexpr double ps
static constexpr double m2
CLHEP::Hep3Vector G4ThreeVector
G4GLOB_DLL std::ostream G4cout
std::vector< std::pair< G4ThreeVector, G4Track * > > positionMap
G4ITTrackHolder * fTrackHolder
G4VDNAMolecularGeometry * fGeometry
void SetReactionModel(G4VDNAReactionModel *)
G4double GetIndependentReactionTime(const G4MolecularConfiguration *, const G4MolecularConfiguration *, G4double)
G4double SamplePDC(G4double, G4double)
std::map< G4int, std::map< G4int, std::map< G4int, std::vector< G4Track * > > > > spaceBinned
std::vector< std::unique_ptr< G4ITReactionChange > > FindReaction(G4ITReactionSet *, const G4double, const G4double, const G4bool) override
G4VDNAReactionModel * fpReactionModel
std::unique_ptr< G4ITReactionChange > MakeReaction(const G4Track &, const G4Track &) override
G4bool TestReactibility(const G4Track &, const G4Track &, G4double, G4bool) override
~G4DNAIRT_geometries() override
const G4DNAMolecularReactionTable *& fMolReactionTable
G4ITReactionSet * fReactionSet
G4int FindBin(G4int, G4double, G4double, G4double)
void Initialize() override
G4MolecularConfiguration * GetMolecularConfiguration(const G4Material *) const
static G4DNAMolecularMaterial * Instance()
G4int GetReactionType() const
Reactant * GetReactant2() const
Data * GetReactionData(Reactant *, Reactant *) const
const ReactantList * CanReactWith(Reactant *) const
G4VDNAMolecularGeometry * GetGeometry() const
static G4double erfcx(G4double x)
static G4double erfcInv(G4double x)
void AddReaction(G4double time, G4Track *trackA, G4Track *trackB)
static G4ITReactionSet * Instance()
void SelectThisReaction(G4ITReactionPtr reaction)
G4ITReactionPerTime & GetReactionsPerTime()
G4TrackList * GetMainList(Key)
virtual void Push(G4Track *)
void MergeSecondariesWithMainList()
static G4ITTrackHolder * Instance()
const G4String & GetName() const
G4double GetDiffusionCoefficient() const
static G4MoleculeTable * Instance()
static G4Molecule * GetMolecule(const G4Track *)
const G4MolecularConfiguration * GetMolecularConfiguration() const
G4Track * BuildTrack(G4double globalTime, const G4ThreeVector &Position)
G4double GetDiffusionCoefficient() const
const G4AffineTransform & GetTopTransform() const
static G4Scheduler * Instance()
G4double GetEndTime() const
G4double GetPreviousTimeStep() const
G4double GetGlobalTime() const
G4double GetStartTime() const
void SetTrackStatus(const G4TrackStatus aTrackStatus)
void SetPosition(const G4ThreeVector &aValue)
const G4ThreeVector & GetPosition() const
G4double GetGlobalTime() const
const G4VTouchable * GetTouchable() const
virtual void FindNearbyMolecules(const G4LogicalVolume *, const G4ThreeVector &, std::vector< G4VPhysicalVolume * > &, G4double)
G4LogicalVolume * GetLogicalVolume() const
virtual const G4NavigationHistory * GetHistory() const
virtual G4VPhysicalVolume * GetVolume(G4int depth=0) const
static constexpr double pi
ThreeVector shoot(const G4int Ap, const G4int Af)
T max(const T t1, const T t2)
brief Return the largest of the two arguments
T min(const T t1, const T t2)
brief Return the smallest of the two arguments