void Events::execute() { rates._setSums(eventLists._diffEvents); properties.time -= log(_random.get01()) / rates._total; startOver: double chooseEvent = (rates._total) * _random.get01(); if (chooseEvent < rates._totalAds) { int pom = static_cast<int> ((chooseEvent / rates._totalAds) * c::A); Position pomPos(pom % c::w, pom / c::w); if (molDescent(pomPos)) { lattice.addMolecule(pomPos); alterEvents(pomPos); properties.nAds++, properties.nEvents++; } else { goto startOver; } } else { chooseEvent -= rates._totalAds; double cumulateRates = 0; int ei = 0, ej = 0; while (cumulateRates + rates._sumsofDiff[ei] < chooseEvent) cumulateRates += rates._sumsofDiff[ei++]; ej = static_cast<int> (floor((chooseEvent - cumulateRates) / rates._diff[ei])); DiffusionEvent diffEvent = eventLists._diffEvents[ei][ej]; lattice.moveMolecule(diffEvent); for (int64_t direction = 0; direction < c::nDiffusions; ++direction) { if (lattice[diffEvent.moleculePos].diffEvent(Diffusion(direction)) != c::empty) { eventLists.properDiffEventReplace(lattice[diffEvent.moleculePos], Diffusion(direction), lattice[diffEvent.moleculePos].bounds); } } alterEvents(diffEvent.moleculePos); properties.nDiff++, properties.nEvents++; } }
void Events::alterEvents(Position pos) { std::vector<Position> toAlter = lattice.getSetToAlter(pos); for (auto it = toAlter.begin(); it != toAlter.end(); it++) { GridCell& molecule = lattice[*it]; int64_t oldBounds = molecule.bounds; int64_t newBounds = lattice.recalculateBounds(*it); for (int64_t direction = 0; direction < c::nDiffusions; ++direction) { if (molecule.diffEvent(Diffusion(direction)) != c::empty) { eventLists.properDiffEventReplace(molecule, Diffusion(direction), oldBounds); } } for (int64_t direction = 0; direction < c::nDiffusions; ++direction) { assert(molecule.diffEvent(Diffusion(direction)) == c::empty); if (lattice[*it + c::ptcdaLength * diffusionResolver[direction]].atomType == AtomType::empty && lattice[*it + c::ptcdaLength * diffusionResolver[direction] + diffusionResolver[direction]].atomType == AtomType::empty) { eventLists.properDiffEventAddition(*it, Diffusion(direction), newBounds); } } } }
Diffusion create_diffusion() { return Diffusion(); }