Program Listing for File EmitterSystem.cpp
↰ Return to documentation for file (SPlisHSPlasH/EmitterSystem.cpp)
#include "EmitterSystem.h"
#include "FluidModel.h"
#include "TimeStep.h"
#include "FluidModel.h"
#include "Utilities/Logger.h"
#include "Simulation.h"
using namespace SPH;
EmitterSystem::EmitterSystem(FluidModel *model)
{
m_model = model;
m_numReusedParticles = 0;
m_numberOfEmittedParticles = 0;
m_reuseParticles = false;
m_boxMin = Vector3r(-1, -1, -1);
m_boxMax = Vector3r(1, 1, 1);
m_reusedParticles.reserve(m_maxParticlesToReusePerStep);
}
EmitterSystem::~EmitterSystem(void)
{
for (size_t i = 0; i < m_emitters.size(); i++)
delete m_emitters[i];
LOG_INFO << "Sum of emitted particles: " << m_numberOfEmittedParticles;
LOG_INFO << "Sum of reused particles: " << m_numReusedParticles;
}
void EmitterSystem::reuseParticles()
{
if (m_reuseParticles)
{
m_reusedParticles.clear();
for (unsigned int i = 0; i < m_model->numActiveParticles(); i++)
{
Vector3r &x = m_model->getPosition(i);
if ((x[0] < m_boxMin[0]) || (x[1] < m_boxMin[1]) || (x[2] < m_boxMin[2]) ||
(x[0] > m_boxMax[0]) || (x[1] > m_boxMax[1]) || (x[2] > m_boxMax[2]))
{
m_reusedParticles.push_back(i);
m_model->getVelocity(i) *= static_cast<Real>(0.95); // make particles slow so that they don't influence
// the CFL condition
//model->getPosition(0, i) = Vector3r(1000 + i, 1000, 1000);
}
}
}
}
void EmitterSystem::step()
{
if (m_emitters.size() == 0)
return;
// reset particle state
Simulation *sim = Simulation::getCurrent();
const unsigned int nModels = sim->numberOfFluidModels();
for (unsigned int m = 0; m < nModels; m++)
{
FluidModel *fm = sim->getFluidModel(m);
const unsigned int numParticles = fm->numActiveParticles();
#pragma omp parallel for schedule(static) default(shared)
for (int i = 0; i < (int)numParticles; i++)
{
if (fm->getParticleState(i) == ParticleState::AnimatedByEmitter)
fm->setParticleState(i, ParticleState::Active);
}
}
reuseParticles();
unsigned int indexReuse = 0;
for (size_t i = 0; i < m_emitters.size(); i++)
{
unsigned int numEmittedParticles = 0;
m_emitters[i]->step(m_reusedParticles, indexReuse, numEmittedParticles);
m_numberOfEmittedParticles += numEmittedParticles;
}
m_numReusedParticles += indexReuse;
}
void EmitterSystem::reset()
{
m_reusedParticles.clear();
m_numReusedParticles = 0;
m_numberOfEmittedParticles = 0;
for (size_t i = 0; i < m_emitters.size(); i++)
{
m_emitters[i]->reset();
}
}
void EmitterSystem::addEmitter(const unsigned int width, const unsigned int height,
const Vector3r &pos, const Matrix3r & rotation,
const Real velocity,
const unsigned int type)
{
m_emitters.push_back(new Emitter(m_model,
width, height,
pos, rotation,
velocity,
type));
}
void EmitterSystem::enableReuseParticles(const Vector3r &boxMin /*= Vector3r(-1, -1, -1)*/, const Vector3r &boxMax /*= Vector3r(1, 1, 1)*/)
{
m_reuseParticles = true;
m_boxMin = boxMin;
m_boxMax = boxMax;
}
void EmitterSystem::disableReuseParticles()
{
m_reuseParticles = false;
}
void SPH::EmitterSystem::saveState(BinaryFileWriter &binWriter)
{
binWriter.write(m_numberOfEmittedParticles);
binWriter.write(m_numReusedParticles);
for (size_t i = 0; i < m_emitters.size(); i++)
m_emitters[i]->saveState(binWriter);
}
void SPH::EmitterSystem::loadState(BinaryFileReader &binReader)
{
binReader.read(m_numberOfEmittedParticles);
binReader.read(m_numReusedParticles);
for (size_t i = 0; i < m_emitters.size(); i++)
m_emitters[i]->loadState(binReader);
}