bool dynamo::OverlapFunctions::CubePlane(const Vector& CubeOrigin, const Vector& CubeDimensions, const Vector& PlaneOrigin, const Vector& PlaneNormal, const double tol) { Vector relpos(CubeOrigin - PlaneOrigin); size_t counter[3] = {0, 0, 0}; while (counter[NDIM-1] < 2) { Vector pointpos(relpos); for (size_t iDim(0); iDim < NDIM; ++iDim) pointpos[iDim] += counter[iDim] * CubeDimensions[iDim]; if ((pointpos | PlaneNormal) < tol) return true; ++counter[0]; for (size_t iDim(0); iDim < NDIM-1; ++iDim) if (counter[iDim] > 1) { counter[iDim] = 0; ++counter[iDim+1]; } } return false; }
void OPVTK::initialise() { size_t vecSize = 1; for (size_t iDim(0); iDim < NDIM; ++iDim) { binWidth[iDim] *= Sim->dynamics.units().unitLength(); if (binWidth[iDim] > 0.5 * Sim->primaryCellSize[iDim]) M_throw() << "Your bin width is too large for the " << iDim << " dimension"; nBins[iDim] = static_cast<size_t> (Sim->primaryCellSize[iDim] / binWidth[iDim]); //This is just to ensure the bin width fits an integer number of //times into the simulation binWidth[iDim] = Sim->primaryCellSize[iDim] / nBins[iDim]; invBinWidth[iDim] = 1.0 / binWidth[iDim]; vecSize *= nBins[iDim]; } binVol = binWidth[0] * binWidth[1] * binWidth[2]; if (CollisionStats) { collCounter.clear(); collCounter.resize(vecSize, 0); } if (fields) { mVsquared.resize(vecSize, 0.0); SampleCounter.resize(vecSize, 0); Momentum.resize(vecSize, Vector (0,0,0)); std::string tmp("< "); for (size_t iDim(0); iDim < NDIM; ++iDim) tmp += boost::lexical_cast<std::string>(nBins[iDim]) + " "; dout << "Number of bins " << tmp << ">" << std::endl; tmp = std::string("< "); for (size_t iDim(0); iDim < NDIM; ++iDim) tmp +=boost::lexical_cast<std::string> (binWidth[iDim]/Sim->dynamics.units().unitLength()) + " "; dout << "Bin width " << tmp << ">" << std::endl; } ticker(); }
GlobalEvent GSOCells::getEvent(const Particle& part) const { #ifdef ISSS_DEBUG if (!Sim->dynamics->isUpToDate(part)) M_throw() << "Particle is not up to date"; #endif //This //Sim->dynamics->updateParticle(part); //is not required as we compensate for the delay using //Sim->dynamics->getParticleDelay(part) Vector CellOrigin; size_t ID(part.getID()); for (size_t iDim(0); iDim < NDIM; ++iDim) { CellOrigin[iDim] = (ID % cuberootN) * cellDimension[iDim] - 0.5*Sim->primaryCellSize[iDim]; ID /= cuberootN; } return GlobalEvent(part, Sim->dynamics-> getSquareCellCollision2 (part, CellOrigin, cellDimension) -Sim->dynamics->getParticleDelay(part), CELL, *this); }
void OPRijVij::process2PED(mapdata& ref, const PairEventData& PDat) { Vector rijnorm(PDat.rij / PDat.rij.nrm()); Vector vijnorm(PDat.vijold / PDat.vijold.nrm()); double rvdot(rijnorm | vijnorm); for (size_t iDim(0); iDim < NDIM; ++iDim) { ref.rij[iDim].addVal(rijnorm[iDim]); ref.vij[iDim].addVal(vijnorm[iDim]); size_t id1(static_cast<size_t>((rijnorm[iDim] + 1.0) * 1000)); size_t id2(static_cast<size_t>(-rvdot * 1000.0)); ++ref.rijcostheta[iDim].at(id1).first; ref.rijcostheta[iDim].at(id1).second += rvdot; ++ref.costhetarij[iDim].at(id2).first; ref.costhetarij[iDim].at(id2).second += std::fabs(rijnorm[iDim]); id1 = static_cast<size_t>((rijnorm[iDim] + 1.0) * 100); id2 = static_cast<size_t>(-rvdot * 100.0); ++ref.anglemapcount; ++ref.anglemap[iDim][id1][id2]; } }
void DynGravity::enforceParabola(Particle& part) const { updateParticle(part); Vector pos(part.getPosition()), vel(part.getVelocity()); Sim->BCs->applyBC(pos, vel); //Find the dimension that is closest to size_t dim = NDIM; double time = HUGE_VAL; for (size_t iDim(0); iDim < NDIM; ++iDim) if (g[iDim] != 0) { double tmpTime = std::abs(- vel[iDim] / g[iDim]); if ((std::abs(tmpTime) < time)) { time = tmpTime; dim = iDim; } } #ifdef DYNAMO_DEBUG if (dim >= NDIM) M_throw() << "Could not find a dimension to enforce the parabola in!"; #endif part.getVelocity()[dim] = 0; }
NEventData DynGravity::enforceParabola(Particle& part) const { updateParticle(part); const Species& species = *Sim->species(part); NEventData retval(ParticleEventData(part, species, VIRTUAL)); Vector pos(part.getPosition()), vel(part.getVelocity()); Sim->BCs->applyBC(pos, vel); //Find the dimension that is closest to size_t dim = NDIM; double time = std::numeric_limits<float>::infinity(); for (size_t iDim(0); iDim < NDIM; ++iDim) if (g[iDim] != 0) { double tmpTime = std::abs(- vel[iDim] / g[iDim]); if ((std::abs(tmpTime) < time)) { time = tmpTime; dim = iDim; } } #ifdef DYNAMO_DEBUG if (dim >= NDIM) M_throw() << "Could not find a dimension to enforce the parabola in!"; #endif part.getVelocity()[dim] = 0; return retval; }
void GSOCells::runEvent(Particle& part, const double) const { Sim->dynamics->updateParticle(part); Vector CellOrigin; size_t ID(part.getID()); for (size_t iDim(0); iDim < NDIM; ++iDim) { CellOrigin[iDim] = (ID % cuberootN) * cellDimension[iDim] - 0.5*Sim->primaryCellSize[iDim]; ID /= cuberootN; } //Determine the cell transition direction, its saved int cellDirectionInt(Sim->dynamics-> getSquareCellCollision3 (part, CellOrigin, cellDimension)); size_t cellDirection = abs(cellDirectionInt) - 1; GlobalEvent iEvent(getEvent(part)); #ifdef DYNAMO_DEBUG if (std::isnan(iEvent.getdt())) M_throw() << "A NAN Interaction collision time has been found" << iEvent.stringData(Sim); if (iEvent.getdt() == HUGE_VAL) M_throw() << "An infinite Interaction (not marked as NONE) collision time has been found\n" << iEvent.stringData(Sim); #endif Sim->systemTime += iEvent.getdt(); Sim->ptrScheduler->stream(iEvent.getdt()); Sim->stream(iEvent.getdt()); Vector vNorm(0,0,0); Vector pos(part.getPosition()), vel(part.getVelocity()); Sim->BCs->applyBC(pos, vel); vNorm[cellDirection] = (cellDirectionInt > 0) ? -1 : +1; //Run the collision and catch the data NEventData EDat(Sim->dynamics->runPlaneEvent(part, vNorm, 1.0, 0.0)); Sim->_sigParticleUpdate(EDat); //Now we're past the event update the scheduler and plugins Sim->ptrScheduler->fullUpdate(part); for (shared_ptr<OutputPlugin> & Ptr : Sim->outputPlugins) Ptr->eventUpdate(iEvent, EDat); }
void OPViscosityE::impulseDelG(const NEventData& ndat) { BOOST_FOREACH(const PairEventData& dat, ndat.L2partChanges) for (size_t iDim(0); iDim < NDIM; ++iDim) for (size_t jDim(0); jDim < NDIM; ++jDim) delG[iDim][jDim] += dat.particle1_.getDeltaP()[iDim] * dat.rij[jDim]; }
/*! \brief Discovers if a cube and a point intersect. \param CubeOrigin The location of the cube relative to the point. \param CubeDimensions The size of the cube sides. \return If the point is inside/on the cube. */ inline bool point_cube(const magnet::math::Vector& CubeOrigin, const magnet::math::Vector& CubeDimensions, const double tol = 0) { for (size_t iDim(0); iDim < NDIM; ++iDim) if (fabs(CubeOrigin[iDim]) > (CubeDimensions[iDim] / 2)) return false; return true; }
void OPVACF::accPass() { ++count; BOOST_FOREACH(const std::tr1::shared_ptr<Species>& spec, Sim->dynamics.getSpecies()) BOOST_FOREACH(const size_t& ID, *spec->getRange()) for (size_t j = 0; j < CorrelatorLength; ++j) for (size_t iDim(0); iDim < NDIM; ++iDim) accG2[spec->getID()][j][iDim] += G[ID].front()[iDim] * G[ID][j][iDim]; }
PairEventData DynNewtonian::parallelCubeColl(const IntEvent& event, const double& e, const double&, const EEventType& eType) const { Particle& particle1 = Sim->particles[event.getParticle1ID()]; Particle& particle2 = Sim->particles[event.getParticle2ID()]; updateParticlePair(particle1, particle2); PairEventData retVal(particle1, particle2, *Sim->species[particle1], *Sim->species[particle2], eType); Sim->BCs->applyBC(retVal.rij, retVal.vijold); size_t dim(0); for (size_t iDim(1); iDim < NDIM; ++iDim) if (fabs(retVal.rij[dim]) < fabs(retVal.rij[iDim])) dim = iDim; double p1Mass = Sim->species[retVal.particle1_.getSpeciesID()]->getMass(particle1.getID()); double p2Mass = Sim->species[retVal.particle2_.getSpeciesID()]->getMass(particle2.getID()); double mu = p1Mass * p2Mass/ (p1Mass + p2Mass); Vector collvec(0,0,0); if (retVal.rij[dim] < 0) collvec[dim] = -1; else collvec[dim] = 1; retVal.rvdot = (retVal.rij | retVal.vijold); retVal.dP = collvec * (1.0 + e) * mu * (collvec | retVal.vijold); //This function must edit particles so it overrides the const! particle1.getVelocity() -= retVal.dP / p1Mass; particle2.getVelocity() += retVal.dP / p2Mass; retVal.particle1_.setDeltaKE(0.5 * p1Mass * (particle1.getVelocity().nrm2() - retVal.particle1_.getOldVel().nrm2())); retVal.particle2_.setDeltaKE(0.5 * p2Mass * (particle2.getVelocity().nrm2() - retVal.particle2_.getOldVel().nrm2())); return retVal; }
size_t OPVTK::getCellID(Vector pos) { size_t retval(0); size_t factor(1); Sim->dynamics.BCs().applyBC(pos); for (size_t iDim(0); iDim < NDIM; ++iDim) { retval += factor * static_cast<size_t>((pos[iDim] + 0.5 * Sim->primaryCellSize[iDim]) * invBinWidth[iDim]); factor *= nBins[iDim]; } return retval; }
void GSOCells::initialise(size_t nID) { Global::initialise(nID); cuberootN = (unsigned long)(std::pow(Sim->N(), 1.0/3.0) + 0.5); if (boost::math::pow<3>(cuberootN) != Sim->N()) M_throw() << "Cannot use single occupancy cells without a integer cube root of N" << "\nN = " << Sim->N() << "\nN^(1/3) = " << cuberootN; for (size_t iDim(0); iDim < NDIM; ++iDim) cellDimension[iDim] = Sim->primaryCellSize[iDim] / cuberootN; if (std::dynamic_pointer_cast<const DynGravity>(Sim->dynamics)) dout << "Warning, in order for SingleOccupancyCells to work in gravity\n" << "You must add the ParabolaSentinel Global event." << std::endl; }
void OPSCParameter::initialise() { for (size_t iDim(0); iDim < NDIM; ++iDim) if (Sim->primaryCellSize[iDim] != 1.0) M_throw() << "Cannot use this parameter in a non-cubic box"; maxWaveNumber = lrint(std::pow(Sim->N, 1.0/3.0)); if (boost::math::pow<3>(maxWaveNumber) != Sim->N) M_throw() << "Failed, N does not have an integer cube root!"; dout << "Max wavelength is " << 1.0 / (maxWaveNumber * Sim->units.unitLength()) << std::endl; maxWaveNumber *= 2; runningsum.resize(maxWaveNumber + 1, 0); ticker(); }
IDRangeList GCells::getParticleNeighbours(const magnet::math::MortonNumber<3>& particle_cell_coords) const { if (verbose) { derr << "Getting neighbours of cell " << particle_cell_coords.toString() << std::endl; } magnet::math::MortonNumber<3> zero_coords; for (size_t iDim(0); iDim < NDIM; ++iDim) zero_coords[iDim] = (particle_cell_coords[iDim].getRealValue() + cellCount[iDim] - overlink) % cellCount[iDim]; IDRangeList retval; //This initial reserve greatly speeds up the later inserts retval.getContainer().reserve(32); magnet::math::MortonNumber<3> coords(zero_coords); for (size_t x(0); x < 2 * overlink + 1; ++x) { coords[0] = (zero_coords[0].getRealValue() + x) % cellCount[0]; for (size_t y(0); y < 2 * overlink + 1; ++y) { coords[1] = (zero_coords[1].getRealValue() + y) % cellCount[1]; for (size_t z(0); z < 2 * overlink + 1; ++z) { coords[2] = (zero_coords[2].getRealValue() + z) % cellCount[2]; const std::vector<size_t>& nlist = list[coords.getMortonNum()]; retval.getContainer().insert(retval.getContainer().end(), nlist.begin(), nlist.end()); } } } return retval; }
void OPSCParameter::ticker() { ++count; for (size_t k(0); k <= maxWaveNumber; ++k) { std::complex<double> sum(0, 0); for (const Particle& part : Sim->particles) { double psum(0); for (size_t iDim(0); iDim < NDIM; ++iDim) psum += part.getPosition()[iDim]; psum *= 2.0 * M_PI * k; sum += std::complex<double>(std::cos(psum), std::sin(psum)); } runningsum[k] += std::abs(sum); } }
double DynGravity::getParabolaSentinelTime(const Particle& part) const { #ifdef DYNAMO_DEBUG if (!isUpToDate(part)) M_throw() << "Particle is not up to date"; #endif if (!part.testState(Particle::DYNAMIC)) return std::numeric_limits<float>::infinity(); //Particle is not dynamic (does not feel gravity) Vector pos(part.getPosition()), vel(part.getVelocity()); Sim->BCs->applyBC(pos, vel); //We return the time of the next turning point, per dimension double time = std::numeric_limits<float>::infinity(); for (size_t iDim(0); iDim < NDIM; ++iDim) if (g[iDim] != 0) { double tmpTime = - vel[iDim] / g[iDim]; if ((tmpTime > 0) && (tmpTime < time)) time = tmpTime; } return time; }
void OPRijVij::output(magnet::xml::XmlStream &XML) { XML << magnet::xml::tag("RijVijComponents"); typedef std::pair<const mapKey, mapdata> mappair; BOOST_FOREACH(const mappair& pair1, rvdotacc) { XML << magnet::xml::tag("Element") << magnet::xml::attr("Type") << pair1.first.first << magnet::xml::attr("EventName") << getName(pair1.first.second, Sim); for (size_t iDim(0); iDim < NDIM; ++iDim) { XML << magnet::xml::tag("Rij") << magnet::xml::attr("dimension") << iDim << magnet::xml::chardata(); pair1.second.rij[iDim].outputHistogram(XML, 1.0); XML << magnet::xml::endtag("Rij"); } for (size_t iDim(0); iDim < NDIM; ++iDim) { XML << magnet::xml::tag("Vij") << magnet::xml::attr("dimension") << iDim << magnet::xml::chardata(); pair1.second.vij[iDim].outputHistogram(XML, 1.0); XML << magnet::xml::endtag("Vij"); } for (size_t iDim(0); iDim < NDIM; ++iDim) { XML << magnet::xml::tag("RijVijvsRij") << magnet::xml::attr("dimension") << iDim << magnet::xml::chardata(); for (size_t i(0); i < 2000; ++i) XML << ((i - 1000.0) / 1000.0) << " " << pair1.second.rijcostheta[iDim][i].second / pair1.second.rijcostheta[iDim][i].first << "\n"; XML << magnet::xml::endtag("RijVijvsRij"); } for (size_t iDim(0); iDim < NDIM; ++iDim) { XML << magnet::xml::tag("RijvsRijVij") << magnet::xml::attr("dimension") << iDim << magnet::xml::chardata(); for (size_t i(0); i < 1000; ++i) XML << ( static_cast<double>(i) / -1000.0) << " " << pair1.second.costhetarij[iDim][i].second / pair1.second.costhetarij[iDim][i].first << "\n"; XML << magnet::xml::endtag("RijvsRijVij"); } for (size_t iDim(0); iDim < NDIM; ++iDim) { XML << magnet::xml::tag("XijRvdot") << magnet::xml::attr("dimension") << iDim << magnet::xml::chardata(); for (size_t i1(0); i1 < 200; ++i1) { for (size_t i2(0); i2 < 100; ++i2) XML << ( (static_cast<double>(i1) - 100.0) / 100.0) << " " << ( static_cast<double>(i2) / -100.0) << " " << static_cast<double>(pair1.second.anglemap[iDim][i1][i2]) / static_cast<double>(pair1.second.anglemapcount) << "\n"; XML << "\n"; } XML << magnet::xml::endtag("XijRvdot"); } XML << magnet::xml::endtag("Element"); }
void OPVTK::eventUpdate(const IntEvent& IEvent, const PairEventData& PDat) { if (CollisionStats) { ++collCounter[getCellID(PDat.particle1_.getParticle().getPosition())]; ++collCounter[getCellID(PDat.particle2_.getParticle().getPosition())]; if (!(++eventCounter % 50000)) { char *fileName; if ( asprintf(&fileName, "%05ld", ++collstatsfilecounter) < 0) M_throw() << "asprintf error in VTK"; std::ofstream of((std::string("CollStats") + fileName + std::string(".vtu")).c_str()); free(fileName); magnet::xml::XmlStream XML(of); XML << magnet::xml::tag("VTKFile") << magnet::xml::attr("type") << "ImageData" << magnet::xml::attr("version") << "0.1" << magnet::xml::attr("byte_order") << "LittleEndian" << magnet::xml::attr("compressor") << "vtkZLibDataCompressor" << magnet::xml::tag("ImageData") << magnet::xml::attr("WholeExtent"); for (size_t iDim(0); iDim < NDIM; ++iDim) XML << " " << "0 " << nBins[iDim] - 1; XML << magnet::xml::attr("Origin"); for (size_t iDim(0); iDim < NDIM; ++iDim) XML << (Sim->primaryCellSize[iDim] * (-0.5)) / Sim->dynamics.units().unitLength() << " "; XML << magnet::xml::attr("Spacing"); for (size_t iDim(0); iDim < NDIM; ++iDim) XML << binWidth[iDim] / Sim->dynamics.units().unitLength() << " "; XML << magnet::xml::tag("Piece") << magnet::xml::attr("Extent"); for (size_t iDim(0); iDim < NDIM; ++iDim) XML << " " << "0 " << nBins[iDim] - 1; XML << magnet::xml::tag("PointData"); //////////////////////////HERE BEGINS THE OUTPUT OF THE FIELDS ////////////SAMPLE COUNTS XML << magnet::xml::tag("DataArray") << magnet::xml::attr("type") << "Int32" << magnet::xml::attr("Name") << "Collisions Per Snapshot" << magnet::xml::attr("format") << "ascii" << magnet::xml::chardata(); BOOST_FOREACH(const unsigned long& val, collCounter) XML << val; XML << "\n" << magnet::xml::endtag("DataArray"); BOOST_FOREACH(unsigned long& val, collCounter) val = 0; std::vector<size_t> density(nBins[0] * nBins[1] * nBins[2], 0); BOOST_FOREACH(const Particle& part, Sim->particleList) ++density[getCellID(part.getPosition())]; XML << magnet::xml::tag("DataArray") << magnet::xml::attr("type") << "Float32" << magnet::xml::attr("Name") << "Density" << magnet::xml::attr("format") << "ascii" << magnet::xml::chardata(); BOOST_FOREACH(const size_t& val, density) XML << (val / binVol); XML << "\n" << magnet::xml::endtag("DataArray"); ////////////Postamble XML << magnet::xml::endtag("PointData") << magnet::xml::tag("CellData") << magnet::xml::endtag("CellData") << magnet::xml::endtag("Piece") << magnet::xml::endtag("ImageData") << magnet::xml::endtag("VTKFile"); } }
void OPVTK::output(magnet::xml::XmlStream& XML) { XML << magnet::xml::tag("VTK") << magnet::xml::attr("ImagesTaken") << imageCounter << magnet::xml::tag("VTKFile") << magnet::xml::attr("type") << "ImageData" << magnet::xml::attr("version") << "0.1" << magnet::xml::attr("byte_order") << "LittleEndian" << magnet::xml::attr("compressor") << "vtkZLibDataCompressor" << magnet::xml::tag("ImageData") << magnet::xml::attr("WholeExtent"); for (size_t iDim(0); iDim < NDIM; ++iDim) XML << " " << "0 " << nBins[iDim] - 1; XML << magnet::xml::attr("Origin"); for (size_t iDim(0); iDim < NDIM; ++iDim) XML << (Sim->primaryCellSize[iDim] * (-0.5)) / Sim->dynamics.units().unitLength() << " "; XML << magnet::xml::attr("Spacing"); for (size_t iDim(0); iDim < NDIM; ++iDim) XML << binWidth[iDim] / Sim->dynamics.units().unitLength() << " "; XML << magnet::xml::tag("Piece") << magnet::xml::attr("Extent"); for (size_t iDim(0); iDim < NDIM; ++iDim) XML << " " << "0 " << nBins[iDim] - 1; XML << magnet::xml::tag("PointData"); ////////////SAMPLE COUNTS XML << magnet::xml::tag("DataArray") << magnet::xml::attr("type") << "Int32" << magnet::xml::attr("Name") << "Samples per cell" << magnet::xml::attr("format") << "ascii" << magnet::xml::chardata(); for (size_t id(0); id < SampleCounter.size(); ++id) XML << SampleCounter[id]; XML << "\n" << magnet::xml::endtag("DataArray"); ////////////Momentum field XML << magnet::xml::tag("DataArray") << magnet::xml::attr("type") << "Float32" << magnet::xml::attr("Name") << "Avg Particle Momentum" << magnet::xml::attr("NumberOfComponents") << NDIM << magnet::xml::attr("format") << "ascii" << magnet::xml::chardata(); for (size_t id(0); id < Momentum.size(); ++id) { for (size_t iDim(0); iDim < NDIM; ++iDim) //Nans are not tolerated by paraview if (SampleCounter[id]) XML << Momentum[id][iDim] / (SampleCounter[id] * Sim->dynamics.units().unitMomentum()); else XML << 0.0; } XML << "\n" << magnet::xml::endtag("DataArray"); ////////////Energy XML << magnet::xml::tag("DataArray") << magnet::xml::attr("type") << "Float32" << magnet::xml::attr("Name") << "Avg Particle Energy" << magnet::xml::attr("format") << "ascii" << magnet::xml::chardata(); for (size_t id(0); id < SampleCounter.size(); ++id) //Nans are not tolerated by paraview if (SampleCounter[id]) XML << mVsquared[id] * 0.5 / (SampleCounter[id] * Sim->dynamics.units().unitEnergy()); else XML << 0.0; XML << "\n" << magnet::xml::endtag("DataArray"); ////////////Postamble XML << magnet::xml::endtag("PointData") << magnet::xml::tag("CellData") << magnet::xml::endtag("CellData") << magnet::xml::endtag("Piece") << magnet::xml::endtag("ImageData") << magnet::xml::endtag("VTKFile") << magnet::xml::endtag("VTK"); }
void CSRingDSMC::initialise(size_t nID) { ID = nID; dt = tstep; n12 = 0; n13 = 0; factor12 = range1->size() * diameter * M_PI * chi12 * tstep / Sim->dynamics.getSimVolume(); factor13 = range1->size() * diameter * M_PI * chi13 * tstep / Sim->dynamics.getSimVolume(); if (maxprob12 == 0.0) { boost::variate_generator <dynamo::baseRNG&, boost::uniform_int<size_t> > id1sampler(Sim->ranGenerator, boost::uniform_int<size_t>(0, (range1->size()/2) - 1)); //Just do some quick testing to get an estimate for (size_t n = 0; n < 1000; ++n) { size_t pairID(id1sampler()); const Particle& p1(Sim->particleList[*(range1->begin() + 2 * pairID)]); const Particle& p2(Sim->particleList[*(range1->begin() + 2 * pairID + 1)]); Sim->dynamics.getLiouvillean().updateParticlePair(p1, p2); CPDData PDat; for (size_t iDim(0); iDim < NDIM; ++iDim) PDat.rij[iDim] = Sim->normal_sampler(); PDat.rij *= diameter / PDat.rij.nrm(); Sim->dynamics.getLiouvillean().DSMCSpheresTest(p1, p2, maxprob12, factor12, PDat); } } if (maxprob13 == 0.0) { boost::variate_generator <dynamo::baseRNG&, boost::uniform_int<size_t> > id1sampler(Sim->ranGenerator, boost::uniform_int<size_t>(0, range1->size() - 1)); //Just do some quick testing to get an estimate for (size_t n = 0; n < 1000; ++n) { const Particle& p1(Sim->particleList[*(range1->begin() + id1sampler())]); size_t secondID(id1sampler()); while ((secondID == p1.getID()) || ((secondID % 2) ? ((secondID-1) == p1.getID()) : ((secondID+1) == p1.getID()))) secondID = id1sampler(); const Particle& p2(Sim->particleList[*(range1->begin() + secondID)]); Sim->dynamics.getLiouvillean().updateParticlePair(p1, p2); CPDData PDat; for (size_t iDim(0); iDim < NDIM; ++iDim) PDat.rij[iDim] = Sim->normal_sampler(); PDat.rij *= diameter / PDat.rij.nrm(); Sim->dynamics.getLiouvillean().DSMCSpheresTest(p1, p2, maxprob13, factor13, PDat); } } if (maxprob12 > 0.5) derr << "MaxProbability12 is " << maxprob12 << "\nNpairs12 per step is " << range1->size() * maxprob12 << std::endl; else dout << "MaxProbability12 is " << maxprob12 << "\nNpairs12 per step is " << range1->size() * maxprob12 << std::endl; if (maxprob13 > 0.5) derr << "MaxProbability13 is " << maxprob13 << "\nNpairs13 per step is " << range1->size() * maxprob13 << std::endl; else dout << "MaxProbability13 is " << maxprob13 << "\nNpairs13 per step is " << range1->size() * maxprob13 << std::endl; if (range1->size() * maxprob12 < 2.0) derr << "The 12 probability is low" << std::endl; if (range1->size() * maxprob13 < 2.0) derr << "The 13 probability is low" << std::endl; }
void CSRingDSMC::runEvent() const { double locdt = dt; #ifdef DYNAMO_DEBUG if (boost::math::isnan(locdt)) M_throw() << "A NAN system event time has been found"; #endif Sim->dSysTime += locdt; Sim->ptrScheduler->stream(locdt); //dynamics must be updated first Sim->dynamics.stream(locdt); dt = tstep; locdt += Sim->freestreamAcc; Sim->freestreamAcc = 0; BOOST_FOREACH(std::tr1::shared_ptr<OutputPlugin>& Ptr, Sim->outputPlugins) Ptr->eventUpdate(*this, NEventData(), locdt); //////////////////// T(1,2) operator double intPart; double fracpart = std::modf(maxprob12 * range1->size(), &intPart); size_t nmax = static_cast<size_t>(intPart) + (Sim->uniform_sampler() < fracpart); { boost::variate_generator <dynamo::baseRNG&, boost::uniform_int<size_t> > id1sampler(Sim->ranGenerator, boost::uniform_int<size_t>(0, (range1->size()/2) - 1)); for (size_t n = 0; n < nmax; ++n) { size_t pairID(id1sampler()); const Particle& p1(Sim->particleList[*(range1->begin() + 2 * pairID)]); const Particle& p2(Sim->particleList[*(range1->begin() + 2 * pairID + 1)]); Sim->dynamics.getLiouvillean().updateParticlePair(p1, p2); CPDData PDat; for (size_t iDim(0); iDim < NDIM; ++iDim) PDat.rij[iDim] = Sim->normal_sampler(); PDat.rij *= diameter / PDat.rij.nrm(); if (Sim->dynamics.getLiouvillean().DSMCSpheresTest (p1, p2, maxprob12, factor12, PDat)) { ++Sim->eventCount; ++n12; const PairEventData SDat(Sim->dynamics.getLiouvillean().DSMCSpheresRun(p1, p2, e, PDat)); Sim->signalParticleUpdate(SDat); Sim->ptrScheduler->fullUpdate(p1, p2); BOOST_FOREACH(std::tr1::shared_ptr<OutputPlugin>& Ptr, Sim->outputPlugins) Ptr->eventUpdate(*this, SDat, 0.0); } } } //////////////////// T(1,3) operator { fracpart = std::modf(maxprob13 * range1->size(), &intPart); nmax = static_cast<size_t>(intPart) + (Sim->uniform_sampler() < fracpart); boost::variate_generator <dynamo::baseRNG&, boost::uniform_int<size_t> > id1sampler(Sim->ranGenerator, boost::uniform_int<size_t>(0, range1->size() - 1)); for (size_t n = 0; n < nmax; ++n) { const Particle& p1(Sim->particleList[*(range1->begin() + id1sampler())]); size_t secondID(id1sampler()); while ((secondID == p1.getID()) || ((secondID % 2) ? ((secondID-1) == p1.getID()) : ((secondID+1) == p1.getID()))) secondID = id1sampler(); const Particle& p2(Sim->particleList[*(range1->begin() + secondID)]); Sim->dynamics.getLiouvillean().updateParticlePair(p1, p2); CPDData PDat; for (size_t iDim(0); iDim < NDIM; ++iDim) PDat.rij[iDim] = Sim->normal_sampler(); PDat.rij *= diameter / PDat.rij.nrm(); if (Sim->dynamics.getLiouvillean().DSMCSpheresTest (p1, p2, maxprob13, factor13, PDat)) { ++Sim->eventCount; ++n13; const PairEventData SDat(Sim->dynamics.getLiouvillean().DSMCSpheresRun(p1, p2, e, PDat)); Sim->signalParticleUpdate(SDat); Sim->ptrScheduler->fullUpdate(p1, p2); BOOST_FOREACH(std::tr1::shared_ptr<OutputPlugin>& Ptr, Sim->outputPlugins) Ptr->eventUpdate(*this, SDat, 0.0); } } } }