Program Listing for File AnimationField.cpp

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

#include "AnimationField.h"
#include "SPHKernels.h"
#include <iostream>
#include "TimeManager.h"
#include "TimeStep.h"
#include "FluidModel.h"
#include "Simulation.h"
#include "extern/tinyexpr/tinyexpr.h"
#include "Utilities/Logger.h"

using namespace SPH;

AnimationField::AnimationField(
    const std::string &particleFieldName,
    const Vector3r &pos, const Matrix3r & rotation, const Vector3r &scale,
    const std::string expression[3], const unsigned int type)
    : m_particleFieldName(particleFieldName)
    , m_x(pos)
    , m_rotation(rotation)
    , m_scale(scale)
    , m_type(type)
    , m_startTime(0)
    , m_endTime(REAL_MAX)
{
    for (int i = 0; i < 3; i++)
        m_expression[i] = expression[i];
}

AnimationField::~AnimationField(void)
{
}

void AnimationField::reset()
{
}

double getTime()
{
    return TimeManager::getCurrent()->getTime();
}

void AnimationField::step()
{
    Simulation *sim = Simulation::getCurrent();
    TimeManager *tm = TimeManager::getCurrent();
    const Real t = tm->getTime();
    const Real dt = tm->getTimeStepSize();

    if (t >= m_startTime && t <= m_endTime)
    {
        // animate particles
        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();

            // find animated field
            const FieldDescription *particleField = nullptr;
            for (unsigned int j = 0; j < fm->numberOfFields(); j++)
            {
                const FieldDescription &field = fm->getField(j);
                if (field.name == m_particleFieldName)
                {
                    particleField = &field;
                    break;
                }
            }

            if (particleField == nullptr)
                continue;

            #pragma omp parallel for schedule(static) default(shared)
            for (int i = 0; i < (int)numParticles; i++)
            {
                const Vector3r &xi = fm->getPosition(i);
                const Vector3r &vi = fm->getVelocity(i);

                const Eigen::Vector3d xi_double = xi.cast<double>();
                const Eigen::Vector3d vi_double = vi.cast<double>();

                if (inShape(m_type, xi, m_x, m_rotation, m_scale))
                {
                    Eigen::Map<Vector3r> value((Real*) particleField->getFct(i));
                    const Eigen::Vector3d value_double = Vector3r(value).cast<double>();

                    const double t_double = static_cast<double>(t);
                    const double dt_double = static_cast<double>(dt);

                    te_variable vars[] = { {"t", &t_double}, {"dt", &dt_double},
                                           {"x", &xi_double[0]}, {"y", &xi_double[1]}, {"z", &xi_double[2]},
                                           {"vx", &vi_double[0]}, {"vy", &vi_double[1]}, {"vz", &vi_double[2]},
                                           {"valuex", &value_double[0]}, {"valuey", &value_double[1]}, {"valuez", &value_double[2]},
                                         };
                    const int numVars = 11;
                    int err;

                    // v_x
                    if (m_expression[0] != "")
                    {
                        te_expr *expr_vx = te_compile(m_expression[0].c_str(), vars, numVars, &err);
                        if (expr_vx)
                            value[0] = static_cast<Real>(te_eval(expr_vx));
                        te_free(expr_vx);

                        if (err != 0)
                            LOG_ERR << "Animation field: expression for x is wrong.";
                    }

                    // v_y
                    if (m_expression[1] != "")
                    {
                        te_expr *expr_vy = te_compile(m_expression[1].c_str(), vars, numVars, &err);
                        if (expr_vy)
                            value[1] = static_cast<Real>(te_eval(expr_vy));
                        te_free(expr_vy);

                        if (err != 0)
                            LOG_ERR << "Animation field: expression for y is wrong.";
                    }

                    // v_z
                    if (m_expression[2] != "")
                    {
                        te_expr *expr_vz = te_compile(m_expression[2].c_str(), vars, numVars, &err);
                        if (expr_vz)
                            value[2] = static_cast<Real>(te_eval(expr_vz));
                        te_free(expr_vz);

                        if (err != 0)
                            LOG_ERR << "Animation field: expression for z is wrong.";
                    }
                }
            }
        }
    }
}