Program Listing for File DebugTools.cpp

Return to documentation for file (SPlisHSPlasH/Utilities/DebugTools.cpp)

#include "DebugTools.h"

#include "Utilities/Logger.h"
#include <SPlisHSPlasH/Simulation.h>

using namespace SPH;
using namespace GenParam;

int DebugTools::DETERMINE_THREAD_IDS = -1;
int DebugTools::DETERMINE_NUM_NEIGHBORS = -1;
int DebugTools::DETERMINE_VELOCITY_CHANGES = -1;

DebugTools::DebugTools() :
    ParameterObject()
{
    m_determineThreadIds = false;
    m_determineNumNeighbors = false;
    m_determineVelocityChanges = false;

    Simulation* sim = Simulation::getCurrent();
    const unsigned int nModels = sim->numberOfFluidModels();
    for (unsigned int fluidModelIndex = 0; fluidModelIndex < nModels; fluidModelIndex++)
    {
        FluidModel* model = sim->getFluidModel(fluidModelIndex);
        model->addField({ "threadId", FieldType::UInt, [this, fluidModelIndex](const unsigned int i) -> unsigned int* { return &m_threadIds[fluidModelIndex][i]; } });
        model->addField({ "numNeighbors", FieldType::UInt, [this, fluidModelIndex](const unsigned int i) -> unsigned int* { return &m_numNeighbors[fluidModelIndex][i]; } });
        model->addField({ "velocityChanges", FieldType::Vector3, [this, fluidModelIndex](const unsigned int i) -> Real* { return &m_velocityChanges[fluidModelIndex][i][0]; } });
    }
}

DebugTools::~DebugTools()
{
    Simulation* sim = Simulation::getCurrent();
    const unsigned int nModels = sim->numberOfFluidModels();
    for (unsigned int fluidModelIndex = 0; fluidModelIndex < nModels; fluidModelIndex++)
    {
        FluidModel* model = sim->getFluidModel(fluidModelIndex);
        model->removeFieldByName("threadId");
        model->removeFieldByName("numNeighbors");
        model->removeFieldByName("velocityChanges");
    }
}

void DebugTools::init()
{
    initParameters();

    Simulation* sim = Simulation::getCurrent();
    const unsigned int nModels = sim->numberOfFluidModels();

    m_threadIds.resize(nModels);
    m_numNeighbors.resize(nModels);
    m_vOld.resize(nModels);
    m_velocityChanges.resize(nModels);
    for (unsigned int i = 0; i < nModels; i++)
    {
        FluidModel* fm = sim->getFluidModel(i);
        m_threadIds[i].resize(fm->numParticles(), 0);
        m_numNeighbors[i].resize(fm->numParticles(), 0);
        m_vOld[i].resize(fm->numParticles(), Vector3r::Zero());
        m_velocityChanges[i].resize(fm->numParticles(), Vector3r::Zero());
    }
}

void SPH::DebugTools::cleanup()
{
    Simulation* sim = Simulation::getCurrent();
    const unsigned int nModels = sim->numberOfFluidModels();

    for (unsigned int i = 0; i < nModels; i++)
    {
        m_threadIds[i].clear();
        m_numNeighbors[i].clear();
        m_vOld[i].clear();
        m_velocityChanges[i].clear();
    }
    m_threadIds.clear();
    m_numNeighbors.clear();
    m_vOld.clear();
    m_velocityChanges.clear();
}

void DebugTools::initParameters()
{
    ParameterObject::initParameters();

    DETERMINE_THREAD_IDS = createBoolParameter("determineThreadIds", "Determine Thread IDs", &m_determineThreadIds);
    setGroup(DETERMINE_THREAD_IDS, "Debug Tools");
    setDescription(DETERMINE_THREAD_IDS, "Determine Thread IDs and add a corresponding particle field.");

    DETERMINE_NUM_NEIGHBORS = createBoolParameter("determineNumNeighbors", "Determine # neighbors", &m_determineNumNeighbors);
    setGroup(DETERMINE_NUM_NEIGHBORS, "Debug Tools");
    setDescription(DETERMINE_NUM_NEIGHBORS, "Determine number of neighbors and add a corresponding particle field.");

    DETERMINE_VELOCITY_CHANGES = createBoolParameter("determineVelocityChanges", "Determine velocity changes", &m_determineVelocityChanges);
    setGroup(DETERMINE_VELOCITY_CHANGES, "Debug Tools");
    setDescription(DETERMINE_VELOCITY_CHANGES, "Determine velocity change of each particle and add a corresponding particle field.");
}

void SPH::DebugTools::determineThreadIds()
{
    Simulation* sim = Simulation::getCurrent();
    const unsigned int nFluids = sim->numberOfFluidModels();

    for (unsigned int fluidModelIndex = 0; fluidModelIndex < nFluids; fluidModelIndex++)
    {
        FluidModel* model = sim->getFluidModel(fluidModelIndex);
        const int numParticles = (int)model->numActiveParticles();

        #pragma omp parallel default(shared)
        {
            #pragma omp for schedule(static)
            for (int i = 0; i < numParticles; i++)
            {
#ifdef _OPENMP
                m_threadIds[fluidModelIndex][i] = omp_get_thread_num();
#else
                m_threadIds[fluidModelIndex][i] = 0;
#endif
            }
        }
    }
}

void SPH::DebugTools::determineNumNeighbors()
{
    Simulation* sim = Simulation::getCurrent();
    sim->performNeighborhoodSearch();
    const unsigned int nFluids = sim->numberOfFluidModels();

    for (unsigned int fluidModelIndex = 0; fluidModelIndex < nFluids; fluidModelIndex++)
    {
        FluidModel* model = sim->getFluidModel(fluidModelIndex);
        const int numParticles = (int)model->numActiveParticles();

        #pragma omp parallel default(shared)
        {
            #pragma omp for schedule(static)
            for (int i = 0; i < numParticles; i++)
            {
                m_numNeighbors[fluidModelIndex][i] = 0;
                for (unsigned int pid = 0; pid < sim->numberOfPointSets(); pid++)
                    m_numNeighbors[fluidModelIndex][i] += sim->numberOfNeighbors(fluidModelIndex, pid, i);
            }
        }
    }
}

void SPH::DebugTools::determineVelocityChanges()
{
    Simulation* sim = Simulation::getCurrent();
    const unsigned int nFluids = sim->numberOfFluidModels();

    for (unsigned int fluidModelIndex = 0; fluidModelIndex < nFluids; fluidModelIndex++)
    {
        FluidModel* model = sim->getFluidModel(fluidModelIndex);
        const int numParticles = (int)model->numActiveParticles();

        #pragma omp parallel default(shared)
        {
            #pragma omp for schedule(static)
            for (int i = 0; i < numParticles; i++)
            {
                m_velocityChanges[fluidModelIndex][i] = model->getVelocity(i) - m_vOld[fluidModelIndex][i];
                m_vOld[fluidModelIndex][i] = model->getVelocity(i);
            }
        }
    }
}

void DebugTools::step()
{
    if (m_determineThreadIds)
        determineThreadIds();

    if (m_determineNumNeighbors)
        determineNumNeighbors();

    if (m_determineVelocityChanges)
        determineVelocityChanges();
}

void DebugTools::reset()
{
    Simulation* sim = Simulation::getCurrent();
    const unsigned int nModels = sim->numberOfFluidModels();

    for (unsigned int i = 0; i < nModels; i++)
    {
        FluidModel* fm = sim->getFluidModel(i);
        for (unsigned int j = 0; j < fm->numParticles(); j++)
        {
            m_threadIds[i][j] = 0;
            m_numNeighbors[i][j] = 0;
            m_vOld[i][j].setZero();
            m_velocityChanges[i][j].setZero();
        }
    }
}

void DebugTools::performNeighborhoodSearchSort()
{
    Simulation* sim = Simulation::getCurrent();
    const unsigned int nModels = sim->numberOfFluidModels();

    for (unsigned int i = 0; i < nModels; i++)
    {
        FluidModel* fm = sim->getFluidModel(i);
        const unsigned int numPart = fm->numActiveParticles();
        if (numPart != 0)
        {
            auto const& d = sim->getNeighborhoodSearch()->point_set(fm->getPointSetIndex());
            d.sort_field(&m_vOld[i][0]);
        }
    }
}

void DebugTools::emittedParticles(FluidModel* model, const unsigned int startIndex)
{
}