Geant4 Cross Reference |
1 // ******************************************* 1 2 // * License and Disclaimer 3 // * 4 // * The Geant4 software is copyright of th 5 // * the Geant4 Collaboration. It is provided 6 // * conditions of the Geant4 Software License 7 // * LICENSE and available at http://cern.ch/ 8 // * include a list of copyright holders. 9 // * 10 // * Neither the authors of this software syst 11 // * institutes,nor the agencies providing fin 12 // * work make any representation or warran 13 // * regarding this software system or assum 14 // * use. Please see the license in the file 15 // * for the full disclaimer and the limitatio 16 // * 17 // * This code implementation is the result 18 // * technical work of the GEANT4 collaboratio 19 // * By using, copying, modifying or distri 20 // * any work based on the software) you ag 21 // * use in resulting scientific publicati 22 // * acceptance of all terms of the Geant4 Sof 23 // ******************************************* 24 // 25 26 #include "G4DNAGillespieDirectMethod.hh" 27 #include "Randomize.hh" 28 #include "G4PhysicalConstants.hh" 29 #include <memory> 30 #include <tuple> 31 #include "G4DNAEventSet.hh" 32 #include "G4UnitsTable.hh" 33 #include "G4DNAScavengerMaterial.hh" 34 #include "G4Scheduler.hh" 35 #include "G4DNAMolecularReactionTable.hh" 36 #include "G4ChemEquilibrium.hh" 37 38 G4DNAGillespieDirectMethod::G4DNAGillespieDire 39 : fMolecularReactions(G4DNAMolecularReaction 40 {} 41 42 G4DNAGillespieDirectMethod::~G4DNAGillespieDir 43 44 void G4DNAGillespieDirectMethod::SetEventSet(G 45 { 46 fpEventSet = pEventSet; 47 } 48 49 //#define DEBUG 1 50 51 G4double G4DNAGillespieDirectMethod::VolumeOfN 52 { 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; 58 if(V <= 0) 59 { 60 G4ExceptionDescription exceptionDescriptio 61 exceptionDescription << "V > 0 !! "; 62 G4Exception("G4DNAGillespieDirectMethod::V 63 "G4DNAGillespieDirectMethod03" 64 exceptionDescription); 65 } 66 return V; 67 } 68 G4double G4DNAGillespieDirectMethod::Propensit 69 70 { 71 if(moleType->GetDiffusionCoefficient() == 0) 72 { 73 return 0.; 74 } 75 const auto& node = std::get<2>(voxel); 76 const auto& box = std::get<1>(voxel); 77 78 G4double alpha = 0; 79 auto it = node.find(moleType); 80 if(it != node.end()) 81 { 82 auto LengthY = box.Getyhi() - box.Getylo() 83 G4double d = it->first->GetDiffusionCoef 84 alpha = d * it->second; 85 86 #ifdef DEBUG 87 G4cout << it->first->GetName() << " " << i 88 << " D : " << it->first->GetDiffusi 89 << " LengthY : " << LengthY << " Pr 90 << G4endl; 91 #endif 92 } 93 return alpha; 94 } 95 96 G4double G4DNAGillespieDirectMethod::Propensit 97 98 { 99 G4double value; 100 auto ConfA = data->GetReactant 101 auto ConfB = data->GetReactant 102 G4double scavengerNumber = 0; 103 auto typeANumber = FindScavenging(vo 104 ? scavengerNumb 105 : ComputeNumber 106 107 auto typeBNumber = FindScavenging(voxel, Con 108 ? scavengerNumber 109 : ComputeNumberInNode(v 110 111 if(typeANumber == 0 || typeBNumber == 0) 112 { 113 return 0; 114 } 115 116 auto k = 117 data->GetObservedReactionRateConstant() / 118 if(ConfA == ConfB) 119 { 120 value = typeANumber * (typeBNumber - 1) * 121 } 122 else 123 { 124 value = typeANumber * typeBNumber * k; 125 } 126 127 if(value < 0) 128 { 129 G4ExceptionDescription exceptionDescriptio 130 exceptionDescription 131 << "G4DNAGillespieDirectMethod::Propensi 132 << ConfA->GetName() << "(" << typeANumbe 133 << "(" << typeBNumber << ") : propensity 134 << " GetObservedReactionRateConstant : " 135 << data->GetObservedReactionRateConstant 136 << " GetEffectiveReactionRadius : " 137 << G4BestUnit(data->GetEffectiveReaction 138 << " k : " << k << " volume : " << Volum 139 G4Exception("G4DNAGillespieDirectMethod::P 140 "G4DNAGillespieDirectMethod013 141 exceptionDescription); 142 } 143 144 #ifdef DEBUG 145 if(value > 0) 146 G4cout << "G4DNAGillespieDirectMethod::Pro 147 << ConfA->GetName() << "(" << typeA 148 << ConfB->GetName() << "(" << typeB 149 << ") : propensity : " << value 150 << " Time to Reaction : " << G4Bes 151 << " k : " << k << " Index : " << i 152 #endif 153 154 return value; 155 } 156 157 void G4DNAGillespieDirectMethod::Initialize() 158 { 159 // for Scavenger 160 fpScavengerMaterial = dynamic_cast<G4DNAScav 161 G4Scheduler::Instance()->GetScavengerMater 162 fEquilibriumProcesses.emplace( 163 std::make_pair(6, std::make_unique<G4ChemE 164 fEquilibriumProcesses.emplace( 165 std::make_pair(7, std::make_unique<G4ChemE 166 fEquilibriumProcesses.emplace( 167 std::make_pair(8, std::make_unique<G4ChemE 168 for(auto& it : fEquilibriumProcesses) 169 { 170 it.second->Initialize(); 171 it.second->SetVerbose(fVerbose); 172 } 173 } 174 175 void G4DNAGillespieDirectMethod::CreateEvents( 176 { 177 auto begin = fpMesh->begin(); 178 auto end = fpMesh->end(); 179 for(; begin != end; begin++) 180 { 181 auto index = std::get<0>(*begin); 182 #ifdef DEBUG 183 fpMesh->PrintVoxel(index); 184 #endif 185 CreateEvent(index); 186 } 187 } 188 189 void G4DNAGillespieDirectMethod::SetTimeStep(c 190 { 191 fTimeStep = stepTime; 192 } 193 void G4DNAGillespieDirectMethod::CreateEvent(c 194 { 195 const auto& voxel = fpMesh->GetVoxel(index); 196 if(std::get<2>(voxel).empty()) 197 { 198 G4ExceptionDescription exceptionDescriptio 199 exceptionDescription << "This voxel : " << 200 << " is not ready to 201 G4Exception("G4DNAGillespieDirectMethod::C 202 "G4DNAGillespieDirectMethod05" 203 exceptionDescription); 204 } 205 G4double r1 = G4UniformRand(); 206 G4double r2 = G4UniformRand(); 207 G4double dAlpha0 = DiffusiveJumping(voxel 208 G4double rAlpha0 = Reaction(voxel); 209 G4double alphaTotal = dAlpha0 + rAlpha0; 210 211 if(alphaTotal == 0) 212 { 213 return; 214 } 215 auto timeStep = ((1.0 / (alphaTotal)) * std: 216 217 #ifdef DEBUG 218 G4cout << "r2 : " << r2 << " rAlpha0 : " << 219 << " dAlpha0 : " << dAlpha0 << " r 220 << rAlpha0 / (dAlpha0 + rAlpha0) << G 221 #endif 222 if(r2 < rAlpha0 / alphaTotal) 223 { 224 if(fVerbose > 1) 225 { 226 G4cout << "=>>>>reaction at : " << timeS 227 << G4BestUnit(((1.0 / alphaTotal) 228 << G4endl; 229 } 230 auto rSelectedIter = fReactionDataMap.uppe 231 fpEventSet->CreateEvent(timeStep, index, r 232 } 233 else if(dAlpha0 > 0) 234 { 235 if(fVerbose > 1) 236 { 237 G4cout << "=>>>>jumping at : " << timeSt 238 << G4BestUnit(((1.0 / alphaTotal) 239 << G4endl; 240 } 241 242 auto dSelectedIter = fJumpingDataMap.upper 243 auto pDSelected = 244 std::make_unique<std::pair<MolType, Inde 245 fpEventSet->CreateEvent(timeStep, index, s 246 } 247 #ifdef DEBUG 248 G4cout << G4endl; 249 #endif 250 } 251 252 G4double G4DNAGillespieDirectMethod::Reaction( 253 { 254 fReactionDataMap.clear(); 255 G4double alpha0 = 0; 256 const auto& dataList = 257 fMolecularReactions->GetVectorOfReactionDa 258 if(dataList.empty()) 259 { 260 G4ExceptionDescription exceptionDescriptio 261 exceptionDescription << "MolecularReaction 262 G4Exception("G4DNAGillespieDirectMethod::R 263 "G4DNAGillespieDirectMethod01" 264 exceptionDescription); 265 } 266 267 for(const auto& it : dataList) 268 { 269 if(!IsEquilibrium(it->GetReactionType())) 270 { 271 continue; 272 } 273 auto propensity = PropensityFunction(voxel 274 if(propensity == 0) 275 { 276 continue; 277 } 278 alpha0 += propensity; 279 fReactionDataMap[alpha0] = it; 280 } 281 #ifdef DEBUG 282 G4cout << "Reaction :alpha0 : " << alpha0 < 283 #endif 284 return alpha0; 285 } 286 287 G4double G4DNAGillespieDirectMethod::Diffusive 288 { 289 fJumpingDataMap.clear(); 290 G4double alpha0 = 0; 291 auto index = std::get<0>(voxel); 292 auto NeighboringVoxels = fpMesh->FindNeighbo 293 if(NeighboringVoxels.empty()) 294 { 295 return 0; 296 } 297 auto iter = G4MoleculeTable::Instance()->Get 298 while(iter()) 299 { 300 const auto* conf = iter.value(); 301 auto propensity = PropensityFunction(voxe 302 if(propensity == 0) 303 { 304 continue; 305 } 306 for(const auto& it_Neighbor : NeighboringV 307 { 308 alpha0 += propensity; 309 fJumpingDataMap[alpha0] = std::make_pair 310 #ifdef DEBUG 311 G4cout << "mole : " << conf->GetName() 312 << " number : " << ComputeNumberI 313 << " propensity : " << propensity 314 << G4endl; 315 #endif 316 } 317 } 318 #ifdef DEBUG 319 G4cout << "DiffusiveJumping :alpha0 : " << 320 #endif 321 return alpha0; 322 } 323 324 G4double G4DNAGillespieDirectMethod::ComputeNu 325 const Voxel& voxel, MolType type) // depend 326 { 327 if(type->GetDiffusionCoefficient() != 0) 328 { 329 const auto& node = std::get<2>(voxel); 330 const auto& it = node.find(type); 331 return (it != node.end()) ? (it->second) : 332 } 333 return 0; 334 } 335 336 G4bool G4DNAGillespieDirectMethod::FindScaveng 337 338 339 { 340 numberOfScavenger = 0; 341 if(fpScavengerMaterial == nullptr) 342 { 343 return false; 344 } 345 auto volumeOfNode = VolumeOfNode(voxel); 346 if(G4MoleculeTable::Instance()->GetConfigura 347 { 348 auto factor = Avogadro * volumeOfNod 349 numberOfScavenger = factor; 350 return true; 351 } 352 353 G4double totalNumber = 354 fpScavengerMaterial->GetNumberMoleculePerV 355 moletype); 356 if(totalNumber == 0) 357 { 358 return false; 359 } 360 361 G4double numberInDouble = volumeOfNode * std 362 fpMesh->GetBoundin 363 auto numberInInterg = (int64_t) (std::floor( 364 G4double change = numberInDouble - numbe 365 G4UniformRand() > change ? numberOfScavenger 366 : numberOfScave 367 return true; 368 } 369 370 G4bool G4DNAGillespieDirectMethod::IsEquilibri 371 { 372 auto reaction = fEquilibriumProcesses.find(r 373 if(reaction == fEquilibriumProcesses.end()) 374 { 375 return true; 376 }else 377 { 378 return (reaction->second->GetEquilibriumSt 379 } 380 381 } 382 383 G4bool G4DNAGillespieDirectMethod::SetEquilibr 384 { 385 for(auto& it : fEquilibriumProcesses) 386 { 387 it.second->SetGlobalTime(fTimeStep); 388 it.second->SetEquilibrium(pReaction); 389 if(it.second->IsStatusChanged()) return tr 390 } 391 return false; 392 } 393 394 void G4DNAGillespieDirectMethod::ResetEquilibr 395 { 396 for(auto& it : fEquilibriumProcesses) 397 { 398 it.second->Reset(); 399 } 400 } 401 402 403 404