Program Listing for File BoundaryModel_Akinci2012.cpp

Return to documentation for file (SPlisHSPlasH/BoundaryModel_Akinci2012.cpp)

#include "BoundaryModel_Akinci2012.h"
#include "SPHKernels.h"
#include <iostream>
#include "TimeManager.h"
#include "TimeStep.h"
#include "Utilities/Logger.h"
#include "NeighborhoodSearch.h"
#include "Simulation.h"

using namespace SPH;


BoundaryModel_Akinci2012::BoundaryModel_Akinci2012() :
    m_x0(),
    m_x(),
    m_v(),
    m_V()
{
    m_sorted = false;
    m_pointSetIndex = 0;
}

BoundaryModel_Akinci2012::~BoundaryModel_Akinci2012(void)
{
    m_x0.clear();
    m_x.clear();
    m_v.clear();
    m_V.clear();
}

void BoundaryModel_Akinci2012::reset()
{
    BoundaryModel::reset();

    // Note:
    // positions and velocities are already updated by updateBoundaryParticles
    if (!m_rigidBody->isDynamic() && !m_rigidBody->isAnimated())
    {
        // reset velocities and accelerations
        for (int j = 0; j < (int)numberOfParticles(); j++)
        {
            m_x[j] = m_x0[j];
            m_v[j].setZero();
        }
    }
}

void BoundaryModel_Akinci2012::computeBoundaryVolume()
{
    Simulation *sim = Simulation::getCurrent();
    const unsigned int nFluids = sim->numberOfFluidModels();
    NeighborhoodSearch *neighborhoodSearch = Simulation::getCurrent()->getNeighborhoodSearch();

    const unsigned int numBoundaryParticles = numberOfParticles();

    #pragma omp parallel default(shared)
    {
        #pragma omp for schedule(static)
        for (int i = 0; i < (int)numBoundaryParticles; i++)
        {
            Real delta = sim->W_zero();
            for (unsigned int pid = nFluids; pid < sim->numberOfPointSets(); pid++)
            {
                BoundaryModel_Akinci2012 *bm_neighbor = static_cast<BoundaryModel_Akinci2012*>(sim->getBoundaryModelFromPointSet(pid));
                for (unsigned int j = 0; j < neighborhoodSearch->point_set(m_pointSetIndex).n_neighbors(pid, i); j++)
                {
                    const unsigned int neighborIndex = neighborhoodSearch->point_set(m_pointSetIndex).neighbor(pid, i, j);
                    delta += sim->W(getPosition(i) - bm_neighbor->getPosition(neighborIndex));
                }
            }
            const Real volume = static_cast<Real>(1.0) / delta;
            m_V[i] = volume;
        }
    }
}

void BoundaryModel_Akinci2012::initModel(RigidBodyObject *rbo, const unsigned int numBoundaryParticles, Vector3r *boundaryParticles)
{
    m_x0.resize(numBoundaryParticles);
    m_x.resize(numBoundaryParticles);
    m_v.resize(numBoundaryParticles);
    m_V.resize(numBoundaryParticles);

    if (rbo->isDynamic())
    {
#ifdef _OPENMP
        const int maxThreads = omp_get_max_threads();
#else
        const int maxThreads = 1;
#endif
        m_forcePerThread.resize(maxThreads, Vector3r::Zero());
        m_torquePerThread.resize(maxThreads, Vector3r::Zero());
    }

    #pragma omp parallel default(shared)
    {
        #pragma omp for schedule(static)
        for (int i = 0; i < (int) numBoundaryParticles; i++)
        {
            m_x0[i] = boundaryParticles[i];
            m_x[i] = boundaryParticles[i];
            m_v[i].setZero();
            m_V[i] = 0.0;
        }
    }
    m_rigidBody = rbo;

    NeighborhoodSearch *neighborhoodSearch = Simulation::getCurrent()->getNeighborhoodSearch();
    m_pointSetIndex = neighborhoodSearch->add_point_set(&m_x[0][0], m_x.size(), m_rigidBody->isDynamic() || m_rigidBody->isAnimated(), false, true, this);
}

void BoundaryModel_Akinci2012::performNeighborhoodSearchSort()
{
    const unsigned int numPart = numberOfParticles();

    // sort static boundaries only once
    if ((numPart == 0) || (!m_rigidBody->isDynamic() && !m_rigidBody->isAnimated() && m_sorted))
        return;

    NeighborhoodSearch *neighborhoodSearch = Simulation::getCurrent()->getNeighborhoodSearch();

    auto const& d = neighborhoodSearch->point_set(m_pointSetIndex);
    d.sort_field(&m_x0[0]);
    d.sort_field(&m_x[0]);
    d.sort_field(&m_v[0]);
    d.sort_field(&m_V[0]);
    m_sorted = true;
}

void SPH::BoundaryModel_Akinci2012::saveState(BinaryFileWriter &binWriter)
{
    binWriter.write(m_sorted);
    binWriter.write(m_pointSetIndex);
}

void SPH::BoundaryModel_Akinci2012::loadState(BinaryFileReader &binReader)
{
    binReader.read(m_sorted);
    binReader.read(m_pointSetIndex);
}

void SPH::BoundaryModel_Akinci2012::resize(const unsigned int numBoundaryParticles)
{
    m_x0.resize(numBoundaryParticles);
    m_x.resize(numBoundaryParticles);
    m_v.resize(numBoundaryParticles);
    m_V.resize(numBoundaryParticles);
}