46 fpEventSet = pEventSet;
51G4double G4DNAGillespieDirectMethod::VolumeOfNode(
const Voxel& voxel)
53 auto box = std::get<1>(voxel);
54 auto LengthY = box.Getyhi() - box.Getylo();
55 auto LengthX = box.Getxhi() - box.Getxlo();
56 auto LengthZ = box.Getzhi() - box.Getzlo();
57 G4double V = LengthY * LengthX * LengthZ;
61 exceptionDescription <<
"V > 0 !! ";
62 G4Exception(
"G4DNAGillespieDirectMethod::VolumeOfNode",
64 exceptionDescription);
75 const auto& node = std::get<2>(voxel);
76 const auto& box = std::get<1>(voxel);
79 auto it = node.find(moleType);
82 auto LengthY = box.Getyhi() - box.Getylo();
83 G4double d = it->first->GetDiffusionCoefficient() / std::pow(LengthY, 2);
84 alpha = d * it->second;
87 G4cout << it->first->GetName() <<
" " << it->second
88 <<
" D : " << it->first->GetDiffusionCoefficient()
89 <<
" LengthY : " << LengthY <<
" PropensityFunction : " << alpha
103 auto typeANumber = FindScavenging(voxel, ConfA, scavengerNumber)
105 : ComputeNumberInNode(voxel, ConfA);
107 auto typeBNumber = FindScavenging(voxel, ConfB, scavengerNumber)
109 : ComputeNumberInNode(voxel, ConfB);
111 if(typeANumber == 0 || typeBNumber == 0)
120 value = typeANumber * (typeBNumber - 1) * k;
124 value = typeANumber * typeBNumber * k;
131 <<
"G4DNAGillespieDirectMethod::PropensityFunction for : "
132 << ConfA->GetName() <<
"(" << typeANumber <<
") + " << ConfB->GetName()
133 <<
"(" << typeBNumber <<
") : propensity : " << value
134 <<
" GetObservedReactionRateConstant : "
136 <<
" GetEffectiveReactionRadius : "
138 <<
" k : " << k <<
" volume : " << VolumeOfNode(voxel) <<
G4endl;
139 G4Exception(
"G4DNAGillespieDirectMethod::PropensityFunction",
141 exceptionDescription);
146 G4cout <<
"G4DNAGillespieDirectMethod::PropensityFunction for : "
147 << ConfA->GetName() <<
"(" << typeANumber <<
") + "
148 << ConfB->GetName() <<
"(" << typeBNumber
149 <<
") : propensity : " << value
150 <<
" Time to Reaction : " <<
G4BestUnit(timeToReaction,
"Time")
151 <<
" k : " << k <<
" Index : " << index <<
G4endl;
162 fEquilibriumProcesses.emplace(
163 std::make_pair(6, std::make_unique<G4ChemEquilibrium>(6, 10 * CLHEP::us)));
164 fEquilibriumProcesses.emplace(
165 std::make_pair(7, std::make_unique<G4ChemEquilibrium>(7, 10 * CLHEP::us)));
166 fEquilibriumProcesses.emplace(
167 std::make_pair(8, std::make_unique<G4ChemEquilibrium>(8, 10 * CLHEP::us)));
168 for(
auto& it : fEquilibriumProcesses)
170 it.second->Initialize();
171 it.second->SetVerbose(fVerbose);
177 auto begin = fpMesh->
begin();
178 auto end = fpMesh->
end();
179 for(; begin != end; begin++)
181 auto index = std::get<0>(*begin);
191 fTimeStep = stepTime;
195 const auto& voxel = fpMesh->
GetVoxel(index);
196 if(std::get<2>(voxel).empty())
199 exceptionDescription <<
"This voxel : " << index
200 <<
" is not ready to make event" <<
G4endl;
201 G4Exception(
"G4DNAGillespieDirectMethod::CreateEvent",
203 exceptionDescription);
207 G4double dAlpha0 = DiffusiveJumping(voxel);
209 G4double alphaTotal = dAlpha0 + rAlpha0;
215 auto timeStep = ((1.0 / (alphaTotal)) * std::log(1.0 / r1)) + fTimeStep;
218 G4cout <<
"r2 : " << r2 <<
" rAlpha0 : " << rAlpha0
219 <<
" dAlpha0 : " << dAlpha0 <<
" rAlpha0 / (dAlpha0 + rAlpha0) : "
220 << rAlpha0 / (dAlpha0 + rAlpha0) <<
G4endl;
222 if(r2 < rAlpha0 / alphaTotal)
226 G4cout <<
"=>>>>reaction at : " << timeStep <<
" timeStep : "
227 <<
G4BestUnit(((1.0 / alphaTotal) * std::log(1.0 / r1)),
"Time")
230 auto rSelectedIter = fReactionDataMap.upper_bound(r2 * alphaTotal);
231 fpEventSet->
CreateEvent(timeStep, index, rSelectedIter->second);
237 G4cout <<
"=>>>>jumping at : " << timeStep <<
" timeStep : "
238 <<
G4BestUnit(((1.0 / alphaTotal) * std::log(1.0 / r1)),
"Time")
242 auto dSelectedIter = fJumpingDataMap.upper_bound(r2 * alphaTotal - rAlpha0);
244 std::make_unique<std::pair<MolType, Index>>(dSelectedIter->second);
245 fpEventSet->
CreateEvent(timeStep, index, std::move(pDSelected));
252G4double G4DNAGillespieDirectMethod::Reaction(
const Voxel& voxel)
254 fReactionDataMap.clear();
256 const auto& dataList =
261 exceptionDescription <<
"MolecularReactionTable empty" <<
G4endl;
262 G4Exception(
"G4DNAGillespieDirectMethod::Reaction",
264 exceptionDescription);
267 for(
const auto& it : dataList)
269 if(!IsEquilibrium(it->GetReactionType()))
278 alpha0 += propensity;
279 fReactionDataMap[alpha0] = it;
287G4double G4DNAGillespieDirectMethod::DiffusiveJumping(
const Voxel& voxel)
289 fJumpingDataMap.clear();
291 auto index = std::get<0>(voxel);
293 if(NeighboringVoxels.empty())
300 const auto* conf = iter.value();
306 for(
const auto& it_Neighbor : NeighboringVoxels)
308 alpha0 += propensity;
309 fJumpingDataMap[alpha0] = std::make_pair(conf, it_Neighbor);
311 G4cout <<
"mole : " << conf->GetName()
312 <<
" number : " << ComputeNumberInNode(index, conf)
313 <<
" propensity : " << propensity <<
" alpha0 : " << alpha0
319 G4cout <<
"DiffusiveJumping :alpha0 : " << alpha0 <<
G4endl;
324G4double G4DNAGillespieDirectMethod::ComputeNumberInNode(
325 const Voxel& voxel, MolType type)
327 if(type->GetDiffusionCoefficient() != 0)
329 const auto& node = std::get<2>(voxel);
330 const auto& it = node.find(type);
331 return (it != node.end()) ? (it->second) : 0;
336G4bool G4DNAGillespieDirectMethod::FindScavenging(
const Voxel& voxel,
340 numberOfScavenger = 0;
341 if(fpScavengerMaterial ==
nullptr)
345 auto volumeOfNode = VolumeOfNode(voxel);
348 auto factor = Avogadro * volumeOfNode;
349 numberOfScavenger = factor;
361 G4double numberInDouble = volumeOfNode * std::floor(totalNumber) /
363 auto numberInInterg = (int64_t) (std::floor(numberInDouble));
364 G4double change = numberInDouble - numberInInterg;
365 G4UniformRand() > change ? numberOfScavenger = numberInInterg
366 : numberOfScavenger = numberInInterg + 1;
370G4bool G4DNAGillespieDirectMethod::IsEquilibrium(
const G4int& reactionType)
const
372 auto reaction = fEquilibriumProcesses.find(reactionType);
373 if(reaction == fEquilibriumProcesses.end())
378 return (reaction->second->GetEquilibriumStatus());
385 for(
auto& it : fEquilibriumProcesses)
387 it.second->SetGlobalTime(fTimeStep);
388 it.second->SetEquilibrium(pReaction);
389 if(it.second->IsStatusChanged())
return true;
396 for(
auto& it : fEquilibriumProcesses)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
G4GLOB_DLL std::ostream G4cout
void CreateEvent(const G4double &time, const Index &index, Event::ReactionData *pReactionData)
~G4DNAGillespieDirectMethod()
G4bool SetEquilibrium(const G4DNAMolecularReactionData *pReaction)
void CreateEvent(const Index &index)
void SetEventSet(G4DNAEventSet *)
G4double PropensityFunction(const Voxel &voxel, ReactionData *data)
void SetTimeStep(const G4double &stepTime)
G4DNAGillespieDirectMethod()
void PrintVoxel(const Index &index)
Voxel & GetVoxel(const Index &index)
const G4DNABoundingBox & GetBoundingBox() const
std::vector< Index > FindNeighboringVoxels(const Index &index) const
Reactant * GetReactant1() const
G4double GetEffectiveReactionRadius() const
Reactant * GetReactant2() const
G4double GetObservedReactionRateConstant() const
DataList GetVectorOfReactionData()
G4double GetNumberMoleculePerVolumeUnitForMaterialConf(MolType) const
G4double GetDiffusionCoefficient() const
static G4MoleculeTable * Instance()
G4ConfigurationIterator GetConfigurationIterator()
static G4Scheduler * Instance()
G4VScavengerMaterial * GetScavengerMaterial() const