Files
test2/extern/mantaflow/preprocessed/turbulencepart.cpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

289 lines
6.8 KiB
C++
Raw Normal View History

// DO NOT EDIT !
// This file is generated using the MantaFlow preprocessor (prep generate).
/******************************************************************************
*
* MantaFlow fluid solver framework
* Copyright 2011 Tobias Pfaff, Nils Thuerey
*
* This program is free software, distributed under the terms of the
* Apache License, Version 2.0
* http://www.ynu.org/licenses
*
* Turbulence particles
*
******************************************************************************/
#include "turbulencepart.h"
#include "shapes.h"
#include "randomstream.h"
using namespace std;
namespace Manta {
TurbulenceParticleSystem::TurbulenceParticleSystem(FluidSolver *parent, WaveletNoiseField &noise)
: ParticleSystem<TurbulenceParticleData>(parent), noise(noise)
{
}
ParticleBase *TurbulenceParticleSystem::clone()
{
TurbulenceParticleSystem *nm = new TurbulenceParticleSystem(getParent(), noise);
compress();
nm->mData = mData;
nm->setName(getName());
return nm;
}
inline Vec3 hsv2rgb(Real h, Real s, Real v)
{
Real r = 0, g = 0, b = 0;
int i = (int)(h * 6);
Real f = h * 6 - i;
Real p = v * (1 - s);
Real q = v * (1 - f * s);
Real t = v * (1 - (1 - f) * s);
switch (i % 6) {
case 0:
r = v, g = t, b = p;
break;
case 1:
r = q, g = v, b = p;
break;
case 2:
r = p, g = v, b = t;
break;
case 3:
r = p, g = q, b = v;
break;
case 4:
r = t, g = p, b = v;
break;
case 5:
r = v, g = p, b = q;
break;
default:
break;
}
return Vec3(r, g, b);
}
void TurbulenceParticleSystem::seed(Shape *shape, int num)
{
static RandomStream rand(34894231);
Vec3 sz = shape->getExtent(), p0 = shape->getCenter() - sz * 0.5;
for (int i = 0; i < num; i++) {
Vec3 p;
do {
p = rand.getVec3() * sz + p0;
} while (!shape->isInside(p));
Real z = (p.z - p0.z) / sz.z;
add(TurbulenceParticleData(p, hsv2rgb(z, 0.75, 1.0)));
}
}
void TurbulenceParticleSystem::resetTexCoords(int num, const Vec3 &inflow)
{
if (num == 0) {
for (int i = 0; i < size(); i++)
mData[i].tex0 = mData[i].pos - inflow;
}
else {
for (int i = 0; i < size(); i++)
mData[i].tex1 = mData[i].pos - inflow;
}
}
struct KnSynthesizeTurbulence : public KernelBase {
KnSynthesizeTurbulence(TurbulenceParticleSystem &p,
FlagGrid &flags,
WaveletNoiseField &noise,
Grid<Real> &kGrid,
Real alpha,
Real dt,
int octaves,
Real scale,
Real invL0,
Real kmin)
: KernelBase(p.size()),
p(p),
flags(flags),
noise(noise),
kGrid(kGrid),
alpha(alpha),
dt(dt),
octaves(octaves),
scale(scale),
invL0(invL0),
kmin(kmin)
{
runMessage();
run();
}
inline void op(IndexInt idx,
TurbulenceParticleSystem &p,
FlagGrid &flags,
WaveletNoiseField &noise,
Grid<Real> &kGrid,
Real alpha,
Real dt,
int octaves,
Real scale,
Real invL0,
Real kmin) const
{
const Real PERSISTENCE = 0.56123f;
const Vec3 pos(p[idx].pos);
if (flags.isInBounds(pos)) { // && !flags.isObstacle(pos)) {
Real k2 = kGrid.getInterpolated(pos) - kmin;
Real ks = k2 < 0 ? 0.0 : sqrt(k2);
// Wavelet noise lookup
Real amplitude = scale * ks;
Real multiplier = invL0;
Vec3 vel(0.);
for (int o = 0; o < octaves; o++) {
// Vec3 ns = noise.evaluateCurl(p[i].pos * multiplier) * amplitude;
Vec3 n0 = noise.evaluateCurl(p[idx].tex0 * multiplier) * amplitude;
Vec3 n1 = noise.evaluateCurl(p[idx].tex1 * multiplier) * amplitude;
vel += alpha * n0 + (1.0f - alpha) * n1;
// next scale
amplitude *= PERSISTENCE;
multiplier *= 2.0f;
}
// advection
Vec3 dx = vel * dt;
p[idx].pos += dx;
p[idx].tex0 += dx;
p[idx].tex1 += dx;
}
}
inline TurbulenceParticleSystem &getArg0()
{
return p;
}
typedef TurbulenceParticleSystem type0;
inline FlagGrid &getArg1()
{
return flags;
}
typedef FlagGrid type1;
inline WaveletNoiseField &getArg2()
{
return noise;
}
typedef WaveletNoiseField type2;
inline Grid<Real> &getArg3()
{
return kGrid;
}
typedef Grid<Real> type3;
inline Real &getArg4()
{
return alpha;
}
typedef Real type4;
inline Real &getArg5()
{
return dt;
}
typedef Real type5;
inline int &getArg6()
{
return octaves;
}
typedef int type6;
inline Real &getArg7()
{
return scale;
}
typedef Real type7;
inline Real &getArg8()
{
return invL0;
}
typedef Real type8;
inline Real &getArg9()
{
return kmin;
}
typedef Real type9;
void runMessage()
{
debMsg("Executing kernel KnSynthesizeTurbulence ", 3);
debMsg("Kernel range"
<< " size " << size << " ",
4);
};
void operator()(const tbb::blocked_range<IndexInt> &__r) const
{
for (IndexInt idx = __r.begin(); idx != (IndexInt)__r.end(); idx++)
op(idx, p, flags, noise, kGrid, alpha, dt, octaves, scale, invL0, kmin);
}
void run()
{
tbb::parallel_for(tbb::blocked_range<IndexInt>(0, size), *this);
}
TurbulenceParticleSystem &p;
FlagGrid &flags;
WaveletNoiseField &noise;
Grid<Real> &kGrid;
Real alpha;
Real dt;
int octaves;
Real scale;
Real invL0;
Real kmin;
};
void TurbulenceParticleSystem::synthesize(FlagGrid &flags,
Grid<Real> &k,
int octaves,
Real switchLength,
Real L0,
Real scale,
Vec3 inflowBias)
{
static Real ctime = 0;
static Vec3 inflow(0.);
Real dt = getParent()->getDt();
// collect inflow bias
inflow += inflowBias * dt;
// alpha: hat function over time
Real oldAlpha = 2.0f * nmod(ctime / switchLength, Real(1.0));
ctime += dt;
Real alpha = 2.0f * nmod(ctime / switchLength, Real(1.0));
if (oldAlpha < 1.0f && alpha >= 1.0f)
resetTexCoords(0, inflow);
if (oldAlpha > alpha)
resetTexCoords(1, inflow);
if (alpha > 1.0f)
alpha = 2.0f - alpha;
alpha = 1.0;
KnSynthesizeTurbulence(
*this, flags, noise, k, alpha, dt, octaves, scale, 1.0f / L0, 1.5 * square(0.1));
}
void TurbulenceParticleSystem::deleteInObstacle(FlagGrid &flags)
{
for (int i = 0; i < size(); i++)
if (flags.isObstacle(mData[i].pos))
mData[i].flag |= PDELETE;
compress();
}
} // namespace Manta