Changeset View
Changeset View
Standalone View
Standalone View
extern/mantaflow/preprocessed/plugin/initplugins.cpp
- This file was added.
| // 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.apache.org/licenses/LICENSE-2.0 | |||||
| * | |||||
| * Tools to setup fields and inflows | |||||
| * | |||||
| ******************************************************************************/ | |||||
| #include "vectorbase.h" | |||||
| #include "shapes.h" | |||||
| #include "commonkernels.h" | |||||
| #include "particle.h" | |||||
| #include "noisefield.h" | |||||
| #include "simpleimage.h" | |||||
| #include "mesh.h" | |||||
| using namespace std; | |||||
| namespace Manta { | |||||
| //! Apply noise to grid | |||||
| struct KnApplyNoiseInfl : public KernelBase { | |||||
| KnApplyNoiseInfl(const FlagGrid &flags, | |||||
| Grid<Real> &density, | |||||
| const WaveletNoiseField &noise, | |||||
| const Grid<Real> &sdf, | |||||
| Real scale, | |||||
| Real sigma) | |||||
| : KernelBase(&flags, 0), | |||||
| flags(flags), | |||||
| density(density), | |||||
| noise(noise), | |||||
| sdf(sdf), | |||||
| scale(scale), | |||||
| sigma(sigma) | |||||
| { | |||||
| runMessage(); | |||||
| run(); | |||||
| } | |||||
| inline void op(int i, | |||||
| int j, | |||||
| int k, | |||||
| const FlagGrid &flags, | |||||
| Grid<Real> &density, | |||||
| const WaveletNoiseField &noise, | |||||
| const Grid<Real> &sdf, | |||||
| Real scale, | |||||
| Real sigma) const | |||||
| { | |||||
| if (!flags.isFluid(i, j, k) || sdf(i, j, k) > sigma) | |||||
| return; | |||||
| Real factor = clamp(1.0 - 0.5 / sigma * (sdf(i, j, k) + sigma), 0.0, 1.0); | |||||
| Real target = noise.evaluate(Vec3(i, j, k)) * scale * factor; | |||||
| if (density(i, j, k) < target) | |||||
| density(i, j, k) = target; | |||||
| } | |||||
| inline const FlagGrid &getArg0() | |||||
| { | |||||
| return flags; | |||||
| } | |||||
| typedef FlagGrid type0; | |||||
| inline Grid<Real> &getArg1() | |||||
| { | |||||
| return density; | |||||
| } | |||||
| typedef Grid<Real> type1; | |||||
| inline const WaveletNoiseField &getArg2() | |||||
| { | |||||
| return noise; | |||||
| } | |||||
| typedef WaveletNoiseField type2; | |||||
| inline const Grid<Real> &getArg3() | |||||
| { | |||||
| return sdf; | |||||
| } | |||||
| typedef Grid<Real> type3; | |||||
| inline Real &getArg4() | |||||
| { | |||||
| return scale; | |||||
| } | |||||
| typedef Real type4; | |||||
| inline Real &getArg5() | |||||
| { | |||||
| return sigma; | |||||
| } | |||||
| typedef Real type5; | |||||
| void runMessage() | |||||
| { | |||||
| debMsg("Executing kernel KnApplyNoiseInfl ", 3); | |||||
| debMsg("Kernel range" | |||||
| << " x " << maxX << " y " << maxY << " z " << minZ << " - " << maxZ << " ", | |||||
| 4); | |||||
| }; | |||||
| void operator()(const tbb::blocked_range<IndexInt> &__r) const | |||||
| { | |||||
| const int _maxX = maxX; | |||||
| const int _maxY = maxY; | |||||
| if (maxZ > 1) { | |||||
| for (int k = __r.begin(); k != (int)__r.end(); k++) | |||||
| for (int j = 0; j < _maxY; j++) | |||||
| for (int i = 0; i < _maxX; i++) | |||||
| op(i, j, k, flags, density, noise, sdf, scale, sigma); | |||||
| } | |||||
| else { | |||||
| const int k = 0; | |||||
| for (int j = __r.begin(); j != (int)__r.end(); j++) | |||||
| for (int i = 0; i < _maxX; i++) | |||||
| op(i, j, k, flags, density, noise, sdf, scale, sigma); | |||||
| } | |||||
| } | |||||
| void run() | |||||
| { | |||||
| if (maxZ > 1) | |||||
| tbb::parallel_for(tbb::blocked_range<IndexInt>(minZ, maxZ), *this); | |||||
| else | |||||
| tbb::parallel_for(tbb::blocked_range<IndexInt>(0, maxY), *this); | |||||
| } | |||||
| const FlagGrid &flags; | |||||
| Grid<Real> &density; | |||||
| const WaveletNoiseField &noise; | |||||
| const Grid<Real> &sdf; | |||||
| Real scale; | |||||
| Real sigma; | |||||
| }; | |||||
| //! Init noise-modulated density inside shape | |||||
| void densityInflow(const FlagGrid &flags, | |||||
| Grid<Real> &density, | |||||
| const WaveletNoiseField &noise, | |||||
| Shape *shape, | |||||
| Real scale = 1.0, | |||||
| Real sigma = 0) | |||||
| { | |||||
| Grid<Real> sdf = shape->computeLevelset(); | |||||
| KnApplyNoiseInfl(flags, density, noise, sdf, scale, sigma); | |||||
| } | |||||
| static PyObject *_W_0(PyObject *_self, PyObject *_linargs, PyObject *_kwds) | |||||
| { | |||||
| try { | |||||
| PbArgs _args(_linargs, _kwds); | |||||
| FluidSolver *parent = _args.obtainParent(); | |||||
| bool noTiming = _args.getOpt<bool>("notiming", -1, 0); | |||||
| pbPreparePlugin(parent, "densityInflow", !noTiming); | |||||
| PyObject *_retval = 0; | |||||
| { | |||||
| ArgLocker _lock; | |||||
| const FlagGrid &flags = *_args.getPtr<FlagGrid>("flags", 0, &_lock); | |||||
| Grid<Real> &density = *_args.getPtr<Grid<Real>>("density", 1, &_lock); | |||||
| const WaveletNoiseField &noise = *_args.getPtr<WaveletNoiseField>("noise", 2, &_lock); | |||||
| Shape *shape = _args.getPtr<Shape>("shape", 3, &_lock); | |||||
| Real scale = _args.getOpt<Real>("scale", 4, 1.0, &_lock); | |||||
| Real sigma = _args.getOpt<Real>("sigma", 5, 0, &_lock); | |||||
| _retval = getPyNone(); | |||||
| densityInflow(flags, density, noise, shape, scale, sigma); | |||||
| _args.check(); | |||||
| } | |||||
| pbFinalizePlugin(parent, "densityInflow", !noTiming); | |||||
| return _retval; | |||||
| } | |||||
| catch (std::exception &e) { | |||||
| pbSetError("densityInflow", e.what()); | |||||
| return 0; | |||||
| } | |||||
| } | |||||
| static const Pb::Register _RP_densityInflow("", "densityInflow", _W_0); | |||||
| extern "C" { | |||||
| void PbRegister_densityInflow() | |||||
| { | |||||
| KEEP_UNUSED(_RP_densityInflow); | |||||
| } | |||||
| } | |||||
| //! Apply noise to real grid based on an SDF | |||||
| struct KnAddNoise : public KernelBase { | |||||
| KnAddNoise(const FlagGrid &flags, | |||||
| Grid<Real> &density, | |||||
| const WaveletNoiseField &noise, | |||||
| const Grid<Real> *sdf, | |||||
| Real scale) | |||||
| : KernelBase(&flags, 0), flags(flags), density(density), noise(noise), sdf(sdf), scale(scale) | |||||
| { | |||||
| runMessage(); | |||||
| run(); | |||||
| } | |||||
| inline void op(int i, | |||||
| int j, | |||||
| int k, | |||||
| const FlagGrid &flags, | |||||
| Grid<Real> &density, | |||||
| const WaveletNoiseField &noise, | |||||
| const Grid<Real> *sdf, | |||||
| Real scale) const | |||||
| { | |||||
| if (!flags.isFluid(i, j, k) || (sdf && (*sdf)(i, j, k) > 0.)) | |||||
| return; | |||||
| density(i, j, k) += noise.evaluate(Vec3(i, j, k)) * scale; | |||||
| } | |||||
| inline const FlagGrid &getArg0() | |||||
| { | |||||
| return flags; | |||||
| } | |||||
| typedef FlagGrid type0; | |||||
| inline Grid<Real> &getArg1() | |||||
| { | |||||
| return density; | |||||
| } | |||||
| typedef Grid<Real> type1; | |||||
| inline const WaveletNoiseField &getArg2() | |||||
| { | |||||
| return noise; | |||||
| } | |||||
| typedef WaveletNoiseField type2; | |||||
| inline const Grid<Real> *getArg3() | |||||
| { | |||||
| return sdf; | |||||
| } | |||||
| typedef Grid<Real> type3; | |||||
| inline Real &getArg4() | |||||
| { | |||||
| return scale; | |||||
| } | |||||
| typedef Real type4; | |||||
| void runMessage() | |||||
| { | |||||
| debMsg("Executing kernel KnAddNoise ", 3); | |||||
| debMsg("Kernel range" | |||||
| << " x " << maxX << " y " << maxY << " z " << minZ << " - " << maxZ << " ", | |||||
| 4); | |||||
| }; | |||||
| void operator()(const tbb::blocked_range<IndexInt> &__r) const | |||||
| { | |||||
| const int _maxX = maxX; | |||||
| const int _maxY = maxY; | |||||
| if (maxZ > 1) { | |||||
| for (int k = __r.begin(); k != (int)__r.end(); k++) | |||||
| for (int j = 0; j < _maxY; j++) | |||||
| for (int i = 0; i < _maxX; i++) | |||||
| op(i, j, k, flags, density, noise, sdf, scale); | |||||
| } | |||||
| else { | |||||
| const int k = 0; | |||||
| for (int j = __r.begin(); j != (int)__r.end(); j++) | |||||
| for (int i = 0; i < _maxX; i++) | |||||
| op(i, j, k, flags, density, noise, sdf, scale); | |||||
| } | |||||
| } | |||||
| void run() | |||||
| { | |||||
| if (maxZ > 1) | |||||
| tbb::parallel_for(tbb::blocked_range<IndexInt>(minZ, maxZ), *this); | |||||
| else | |||||
| tbb::parallel_for(tbb::blocked_range<IndexInt>(0, maxY), *this); | |||||
| } | |||||
| const FlagGrid &flags; | |||||
| Grid<Real> &density; | |||||
| const WaveletNoiseField &noise; | |||||
| const Grid<Real> *sdf; | |||||
| Real scale; | |||||
| }; | |||||
| void addNoise(const FlagGrid &flags, | |||||
| Grid<Real> &density, | |||||
| const WaveletNoiseField &noise, | |||||
| const Grid<Real> *sdf = NULL, | |||||
| Real scale = 1.0) | |||||
| { | |||||
| KnAddNoise(flags, density, noise, sdf, scale); | |||||
| } | |||||
| static PyObject *_W_1(PyObject *_self, PyObject *_linargs, PyObject *_kwds) | |||||
| { | |||||
| try { | |||||
| PbArgs _args(_linargs, _kwds); | |||||
| FluidSolver *parent = _args.obtainParent(); | |||||
| bool noTiming = _args.getOpt<bool>("notiming", -1, 0); | |||||
| pbPreparePlugin(parent, "addNoise", !noTiming); | |||||
| PyObject *_retval = 0; | |||||
| { | |||||
| ArgLocker _lock; | |||||
| const FlagGrid &flags = *_args.getPtr<FlagGrid>("flags", 0, &_lock); | |||||
| Grid<Real> &density = *_args.getPtr<Grid<Real>>("density", 1, &_lock); | |||||
| const WaveletNoiseField &noise = *_args.getPtr<WaveletNoiseField>("noise", 2, &_lock); | |||||
| const Grid<Real> *sdf = _args.getPtrOpt<Grid<Real>>("sdf", 3, NULL, &_lock); | |||||
| Real scale = _args.getOpt<Real>("scale", 4, 1.0, &_lock); | |||||
| _retval = getPyNone(); | |||||
| addNoise(flags, density, noise, sdf, scale); | |||||
| _args.check(); | |||||
| } | |||||
| pbFinalizePlugin(parent, "addNoise", !noTiming); | |||||
| return _retval; | |||||
| } | |||||
| catch (std::exception &e) { | |||||
| pbSetError("addNoise", e.what()); | |||||
| return 0; | |||||
| } | |||||
| } | |||||
| static const Pb::Register _RP_addNoise("", "addNoise", _W_1); | |||||
| extern "C" { | |||||
| void PbRegister_addNoise() | |||||
| { | |||||
| KEEP_UNUSED(_RP_addNoise); | |||||
| } | |||||
| } | |||||
| //! sample noise field and set pdata with its values (for convenience, scale the noise values) | |||||
| template<class T> struct knSetPdataNoise : public KernelBase { | |||||
| knSetPdataNoise(const BasicParticleSystem &parts, | |||||
| ParticleDataImpl<T> &pdata, | |||||
| const WaveletNoiseField &noise, | |||||
| Real scale) | |||||
| : KernelBase(parts.size()), parts(parts), pdata(pdata), noise(noise), scale(scale) | |||||
| { | |||||
| runMessage(); | |||||
| run(); | |||||
| } | |||||
| inline void op(IndexInt idx, | |||||
| const BasicParticleSystem &parts, | |||||
| ParticleDataImpl<T> &pdata, | |||||
| const WaveletNoiseField &noise, | |||||
| Real scale) const | |||||
| { | |||||
| pdata[idx] = noise.evaluate(parts.getPos(idx)) * scale; | |||||
| } | |||||
| inline const BasicParticleSystem &getArg0() | |||||
| { | |||||
| return parts; | |||||
| } | |||||
| typedef BasicParticleSystem type0; | |||||
| inline ParticleDataImpl<T> &getArg1() | |||||
| { | |||||
| return pdata; | |||||
| } | |||||
| typedef ParticleDataImpl<T> type1; | |||||
| inline const WaveletNoiseField &getArg2() | |||||
| { | |||||
| return noise; | |||||
| } | |||||
| typedef WaveletNoiseField type2; | |||||
| inline Real &getArg3() | |||||
| { | |||||
| return scale; | |||||
| } | |||||
| typedef Real type3; | |||||
| void runMessage() | |||||
| { | |||||
| debMsg("Executing kernel knSetPdataNoise ", 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, parts, pdata, noise, scale); | |||||
| } | |||||
| void run() | |||||
| { | |||||
| tbb::parallel_for(tbb::blocked_range<IndexInt>(0, size), *this); | |||||
| } | |||||
| const BasicParticleSystem &parts; | |||||
| ParticleDataImpl<T> &pdata; | |||||
| const WaveletNoiseField &noise; | |||||
| Real scale; | |||||
| }; | |||||
| template<class T> struct knSetPdataNoiseVec : public KernelBase { | |||||
| knSetPdataNoiseVec(const BasicParticleSystem &parts, | |||||
| ParticleDataImpl<T> &pdata, | |||||
| const WaveletNoiseField &noise, | |||||
| Real scale) | |||||
| : KernelBase(parts.size()), parts(parts), pdata(pdata), noise(noise), scale(scale) | |||||
| { | |||||
| runMessage(); | |||||
| run(); | |||||
| } | |||||
| inline void op(IndexInt idx, | |||||
| const BasicParticleSystem &parts, | |||||
| ParticleDataImpl<T> &pdata, | |||||
| const WaveletNoiseField &noise, | |||||
| Real scale) const | |||||
| { | |||||
| pdata[idx] = noise.evaluateVec(parts.getPos(idx)) * scale; | |||||
| } | |||||
| inline const BasicParticleSystem &getArg0() | |||||
| { | |||||
| return parts; | |||||
| } | |||||
| typedef BasicParticleSystem type0; | |||||
| inline ParticleDataImpl<T> &getArg1() | |||||
| { | |||||
| return pdata; | |||||
| } | |||||
| typedef ParticleDataImpl<T> type1; | |||||
| inline const WaveletNoiseField &getArg2() | |||||
| { | |||||
| return noise; | |||||
| } | |||||
| typedef WaveletNoiseField type2; | |||||
| inline Real &getArg3() | |||||
| { | |||||
| return scale; | |||||
| } | |||||
| typedef Real type3; | |||||
| void runMessage() | |||||
| { | |||||
| debMsg("Executing kernel knSetPdataNoiseVec ", 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, parts, pdata, noise, scale); | |||||
| } | |||||
| void run() | |||||
| { | |||||
| tbb::parallel_for(tbb::blocked_range<IndexInt>(0, size), *this); | |||||
| } | |||||
| const BasicParticleSystem &parts; | |||||
| ParticleDataImpl<T> &pdata; | |||||
| const WaveletNoiseField &noise; | |||||
| Real scale; | |||||
| }; | |||||
| void setNoisePdata(const BasicParticleSystem &parts, | |||||
| ParticleDataImpl<Real> &pd, | |||||
| const WaveletNoiseField &noise, | |||||
| Real scale = 1.) | |||||
| { | |||||
| knSetPdataNoise<Real>(parts, pd, noise, scale); | |||||
| } | |||||
| static PyObject *_W_2(PyObject *_self, PyObject *_linargs, PyObject *_kwds) | |||||
| { | |||||
| try { | |||||
| PbArgs _args(_linargs, _kwds); | |||||
| FluidSolver *parent = _args.obtainParent(); | |||||
| bool noTiming = _args.getOpt<bool>("notiming", -1, 0); | |||||
| pbPreparePlugin(parent, "setNoisePdata", !noTiming); | |||||
| PyObject *_retval = 0; | |||||
| { | |||||
| ArgLocker _lock; | |||||
| const BasicParticleSystem &parts = *_args.getPtr<BasicParticleSystem>("parts", 0, &_lock); | |||||
| ParticleDataImpl<Real> &pd = *_args.getPtr<ParticleDataImpl<Real>>("pd", 1, &_lock); | |||||
| const WaveletNoiseField &noise = *_args.getPtr<WaveletNoiseField>("noise", 2, &_lock); | |||||
| Real scale = _args.getOpt<Real>("scale", 3, 1., &_lock); | |||||
| _retval = getPyNone(); | |||||
| setNoisePdata(parts, pd, noise, scale); | |||||
| _args.check(); | |||||
| } | |||||
| pbFinalizePlugin(parent, "setNoisePdata", !noTiming); | |||||
| return _retval; | |||||
| } | |||||
| catch (std::exception &e) { | |||||
| pbSetError("setNoisePdata", e.what()); | |||||
| return 0; | |||||
| } | |||||
| } | |||||
| static const Pb::Register _RP_setNoisePdata("", "setNoisePdata", _W_2); | |||||
| extern "C" { | |||||
| void PbRegister_setNoisePdata() | |||||
| { | |||||
| KEEP_UNUSED(_RP_setNoisePdata); | |||||
| } | |||||
| } | |||||
| void setNoisePdataVec3(const BasicParticleSystem &parts, | |||||
| ParticleDataImpl<Vec3> &pd, | |||||
| const WaveletNoiseField &noise, | |||||
| Real scale = 1.) | |||||
| { | |||||
| knSetPdataNoiseVec<Vec3>(parts, pd, noise, scale); | |||||
| } | |||||
| static PyObject *_W_3(PyObject *_self, PyObject *_linargs, PyObject *_kwds) | |||||
| { | |||||
| try { | |||||
| PbArgs _args(_linargs, _kwds); | |||||
| FluidSolver *parent = _args.obtainParent(); | |||||
| bool noTiming = _args.getOpt<bool>("notiming", -1, 0); | |||||
| pbPreparePlugin(parent, "setNoisePdataVec3", !noTiming); | |||||
| PyObject *_retval = 0; | |||||
| { | |||||
| ArgLocker _lock; | |||||
| const BasicParticleSystem &parts = *_args.getPtr<BasicParticleSystem>("parts", 0, &_lock); | |||||
| ParticleDataImpl<Vec3> &pd = *_args.getPtr<ParticleDataImpl<Vec3>>("pd", 1, &_lock); | |||||
| const WaveletNoiseField &noise = *_args.getPtr<WaveletNoiseField>("noise", 2, &_lock); | |||||
| Real scale = _args.getOpt<Real>("scale", 3, 1., &_lock); | |||||
| _retval = getPyNone(); | |||||
| setNoisePdataVec3(parts, pd, noise, scale); | |||||
| _args.check(); | |||||
| } | |||||
| pbFinalizePlugin(parent, "setNoisePdataVec3", !noTiming); | |||||
| return _retval; | |||||
| } | |||||
| catch (std::exception &e) { | |||||
| pbSetError("setNoisePdataVec3", e.what()); | |||||
| return 0; | |||||
| } | |||||
| } | |||||
| static const Pb::Register _RP_setNoisePdataVec3("", "setNoisePdataVec3", _W_3); | |||||
| extern "C" { | |||||
| void PbRegister_setNoisePdataVec3() | |||||
| { | |||||
| KEEP_UNUSED(_RP_setNoisePdataVec3); | |||||
| } | |||||
| } | |||||
| void setNoisePdataInt(const BasicParticleSystem &parts, | |||||
| ParticleDataImpl<int> &pd, | |||||
| const WaveletNoiseField &noise, | |||||
| Real scale = 1.) | |||||
| { | |||||
| knSetPdataNoise<int>(parts, pd, noise, scale); | |||||
| } | |||||
| static PyObject *_W_4(PyObject *_self, PyObject *_linargs, PyObject *_kwds) | |||||
| { | |||||
| try { | |||||
| PbArgs _args(_linargs, _kwds); | |||||
| FluidSolver *parent = _args.obtainParent(); | |||||
| bool noTiming = _args.getOpt<bool>("notiming", -1, 0); | |||||
| pbPreparePlugin(parent, "setNoisePdataInt", !noTiming); | |||||
| PyObject *_retval = 0; | |||||
| { | |||||
| ArgLocker _lock; | |||||
| const BasicParticleSystem &parts = *_args.getPtr<BasicParticleSystem>("parts", 0, &_lock); | |||||
| ParticleDataImpl<int> &pd = *_args.getPtr<ParticleDataImpl<int>>("pd", 1, &_lock); | |||||
| const WaveletNoiseField &noise = *_args.getPtr<WaveletNoiseField>("noise", 2, &_lock); | |||||
| Real scale = _args.getOpt<Real>("scale", 3, 1., &_lock); | |||||
| _retval = getPyNone(); | |||||
| setNoisePdataInt(parts, pd, noise, scale); | |||||
| _args.check(); | |||||
| } | |||||
| pbFinalizePlugin(parent, "setNoisePdataInt", !noTiming); | |||||
| return _retval; | |||||
| } | |||||
| catch (std::exception &e) { | |||||
| pbSetError("setNoisePdataInt", e.what()); | |||||
| return 0; | |||||
| } | |||||
| } | |||||
| static const Pb::Register _RP_setNoisePdataInt("", "setNoisePdataInt", _W_4); | |||||
| extern "C" { | |||||
| void PbRegister_setNoisePdataInt() | |||||
| { | |||||
| KEEP_UNUSED(_RP_setNoisePdataInt); | |||||
| } | |||||
| } | |||||
| //! SDF gradient from obstacle flags, for turbulence.py | |||||
| // FIXME, slow, without kernel... | |||||
| Grid<Vec3> obstacleGradient(const FlagGrid &flags) | |||||
| { | |||||
| LevelsetGrid levelset(flags.getParent(), false); | |||||
| Grid<Vec3> gradient(flags.getParent()); | |||||
| // rebuild obstacle levelset | |||||
| FOR_IDX(levelset) | |||||
| { | |||||
| levelset[idx] = flags.isObstacle(idx) ? -0.5 : 0.5; | |||||
| } | |||||
| levelset.reinitMarching(flags, 6.0, 0, true, false, FlagGrid::TypeReserved); | |||||
| // build levelset gradient | |||||
| GradientOp(gradient, levelset); | |||||
| FOR_IDX(levelset) | |||||
| { | |||||
| Vec3 grad = gradient[idx]; | |||||
| Real s = normalize(grad); | |||||
| if (s <= 0.1 || levelset[idx] >= 0) | |||||
| grad = Vec3(0.); | |||||
| gradient[idx] = grad * levelset[idx]; | |||||
| } | |||||
| return gradient; | |||||
| } | |||||
| static PyObject *_W_5(PyObject *_self, PyObject *_linargs, PyObject *_kwds) | |||||
| { | |||||
| try { | |||||
| PbArgs _args(_linargs, _kwds); | |||||
| FluidSolver *parent = _args.obtainParent(); | |||||
| bool noTiming = _args.getOpt<bool>("notiming", -1, 0); | |||||
| pbPreparePlugin(parent, "obstacleGradient", !noTiming); | |||||
| PyObject *_retval = 0; | |||||
| { | |||||
| ArgLocker _lock; | |||||
| const FlagGrid &flags = *_args.getPtr<FlagGrid>("flags", 0, &_lock); | |||||
| _retval = toPy(obstacleGradient(flags)); | |||||
| _args.check(); | |||||
| } | |||||
| pbFinalizePlugin(parent, "obstacleGradient", !noTiming); | |||||
| return _retval; | |||||
| } | |||||
| catch (std::exception &e) { | |||||
| pbSetError("obstacleGradient", e.what()); | |||||
| return 0; | |||||
| } | |||||
| } | |||||
| static const Pb::Register _RP_obstacleGradient("", "obstacleGradient", _W_5); | |||||
| extern "C" { | |||||
| void PbRegister_obstacleGradient() | |||||
| { | |||||
| KEEP_UNUSED(_RP_obstacleGradient); | |||||
| } | |||||
| } | |||||
| //! SDF from obstacle flags, for turbulence.py | |||||
| LevelsetGrid obstacleLevelset(const FlagGrid &flags) | |||||
| { | |||||
| LevelsetGrid levelset(flags.getParent(), false); | |||||
| // rebuild obstacle levelset | |||||
| FOR_IDX(levelset) | |||||
| { | |||||
| levelset[idx] = flags.isObstacle(idx) ? -0.5 : 0.5; | |||||
| } | |||||
| levelset.reinitMarching(flags, 6.0, 0, true, false, FlagGrid::TypeReserved); | |||||
| return levelset; | |||||
| } | |||||
| static PyObject *_W_6(PyObject *_self, PyObject *_linargs, PyObject *_kwds) | |||||
| { | |||||
| try { | |||||
| PbArgs _args(_linargs, _kwds); | |||||
| FluidSolver *parent = _args.obtainParent(); | |||||
| bool noTiming = _args.getOpt<bool>("notiming", -1, 0); | |||||
| pbPreparePlugin(parent, "obstacleLevelset", !noTiming); | |||||
| PyObject *_retval = 0; | |||||
| { | |||||
| ArgLocker _lock; | |||||
| const FlagGrid &flags = *_args.getPtr<FlagGrid>("flags", 0, &_lock); | |||||
| _retval = toPy(obstacleLevelset(flags)); | |||||
| _args.check(); | |||||
| } | |||||
| pbFinalizePlugin(parent, "obstacleLevelset", !noTiming); | |||||
| return _retval; | |||||
| } | |||||
| catch (std::exception &e) { | |||||
| pbSetError("obstacleLevelset", e.what()); | |||||
| return 0; | |||||
| } | |||||
| } | |||||
| static const Pb::Register _RP_obstacleLevelset("", "obstacleLevelset", _W_6); | |||||
| extern "C" { | |||||
| void PbRegister_obstacleLevelset() | |||||
| { | |||||
| KEEP_UNUSED(_RP_obstacleLevelset); | |||||
| } | |||||
| } | |||||
| //***************************************************************************** | |||||
| // blender init functions | |||||
| struct KnApplyEmission : public KernelBase { | |||||
| KnApplyEmission(const FlagGrid &flags, | |||||
| Grid<Real> &target, | |||||
| const Grid<Real> &source, | |||||
| const Grid<Real> *emissionTexture, | |||||
| bool isAbsolute, | |||||
| int type) | |||||
| : KernelBase(&flags, 0), | |||||
| flags(flags), | |||||
| target(target), | |||||
| source(source), | |||||
| emissionTexture(emissionTexture), | |||||
| isAbsolute(isAbsolute), | |||||
| type(type) | |||||
| { | |||||
| runMessage(); | |||||
| run(); | |||||
| } | |||||
| inline void op(int i, | |||||
| int j, | |||||
| int k, | |||||
| const FlagGrid &flags, | |||||
| Grid<Real> &target, | |||||
| const Grid<Real> &source, | |||||
| const Grid<Real> *emissionTexture, | |||||
| bool isAbsolute, | |||||
| int type) const | |||||
| { | |||||
| // if type is given, only apply emission when celltype matches type from flaggrid | |||||
| // and if emission texture is given, only apply emission when some emission is present at cell | |||||
| // (important for emit from particles) | |||||
| bool isInflow = (type & FlagGrid::TypeInflow && flags.isInflow(i, j, k)); | |||||
| bool isOutflow = (type & FlagGrid::TypeOutflow && flags.isOutflow(i, j, k)); | |||||
| if ((type && !isInflow && !isOutflow) && (emissionTexture && !(*emissionTexture)(i, j, k))) | |||||
| return; | |||||
| if (isAbsolute) | |||||
| target(i, j, k) = source(i, j, k); | |||||
| else | |||||
| target(i, j, k) += source(i, j, k); | |||||
| } | |||||
| inline const FlagGrid &getArg0() | |||||
| { | |||||
| return flags; | |||||
| } | |||||
| typedef FlagGrid type0; | |||||
| inline Grid<Real> &getArg1() | |||||
| { | |||||
| return target; | |||||
| } | |||||
| typedef Grid<Real> type1; | |||||
| inline const Grid<Real> &getArg2() | |||||
| { | |||||
| return source; | |||||
| } | |||||
| typedef Grid<Real> type2; | |||||
| inline const Grid<Real> *getArg3() | |||||
| { | |||||
| return emissionTexture; | |||||
| } | |||||
| typedef Grid<Real> type3; | |||||
| inline bool &getArg4() | |||||
| { | |||||
| return isAbsolute; | |||||
| } | |||||
| typedef bool type4; | |||||
| inline int &getArg5() | |||||
| { | |||||
| return type; | |||||
| } | |||||
| typedef int type5; | |||||
| void runMessage() | |||||
| { | |||||
| debMsg("Executing kernel KnApplyEmission ", 3); | |||||
| debMsg("Kernel range" | |||||
| << " x " << maxX << " y " << maxY << " z " << minZ << " - " << maxZ << " ", | |||||
| 4); | |||||
| }; | |||||
| void operator()(const tbb::blocked_range<IndexInt> &__r) const | |||||
| { | |||||
| const int _maxX = maxX; | |||||
| const int _maxY = maxY; | |||||
| if (maxZ > 1) { | |||||
| for (int k = __r.begin(); k != (int)__r.end(); k++) | |||||
| for (int j = 0; j < _maxY; j++) | |||||
| for (int i = 0; i < _maxX; i++) | |||||
| op(i, j, k, flags, target, source, emissionTexture, isAbsolute, type); | |||||
| } | |||||
| else { | |||||
| const int k = 0; | |||||
| for (int j = __r.begin(); j != (int)__r.end(); j++) | |||||
| for (int i = 0; i < _maxX; i++) | |||||
| op(i, j, k, flags, target, source, emissionTexture, isAbsolute, type); | |||||
| } | |||||
| } | |||||
| void run() | |||||
| { | |||||
| if (maxZ > 1) | |||||
| tbb::parallel_for(tbb::blocked_range<IndexInt>(minZ, maxZ), *this); | |||||
| else | |||||
| tbb::parallel_for(tbb::blocked_range<IndexInt>(0, maxY), *this); | |||||
| } | |||||
| const FlagGrid &flags; | |||||
| Grid<Real> ⌖ | |||||
| const Grid<Real> &source; | |||||
| const Grid<Real> *emissionTexture; | |||||
| bool isAbsolute; | |||||
| int type; | |||||
| }; | |||||
| //! Add emission values | |||||
| // isAbsolute: whether to add emission values to existing, or replace | |||||
| void applyEmission(FlagGrid &flags, | |||||
| Grid<Real> &target, | |||||
| Grid<Real> &source, | |||||
| Grid<Real> *emissionTexture = NULL, | |||||
| bool isAbsolute = true, | |||||
| int type = 0) | |||||
| { | |||||
| KnApplyEmission(flags, target, source, emissionTexture, isAbsolute, type); | |||||
| } | |||||
| static PyObject *_W_7(PyObject *_self, PyObject *_linargs, PyObject *_kwds) | |||||
| { | |||||
| try { | |||||
| PbArgs _args(_linargs, _kwds); | |||||
| FluidSolver *parent = _args.obtainParent(); | |||||
| bool noTiming = _args.getOpt<bool>("notiming", -1, 0); | |||||
| pbPreparePlugin(parent, "applyEmission", !noTiming); | |||||
| PyObject *_retval = 0; | |||||
| { | |||||
| ArgLocker _lock; | |||||
| FlagGrid &flags = *_args.getPtr<FlagGrid>("flags", 0, &_lock); | |||||
| Grid<Real> &target = *_args.getPtr<Grid<Real>>("target", 1, &_lock); | |||||
| Grid<Real> &source = *_args.getPtr<Grid<Real>>("source", 2, &_lock); | |||||
| Grid<Real> *emissionTexture = _args.getPtrOpt<Grid<Real>>( | |||||
| "emissionTexture", 3, NULL, &_lock); | |||||
| bool isAbsolute = _args.getOpt<bool>("isAbsolute", 4, true, &_lock); | |||||
| int type = _args.getOpt<int>("type", 5, 0, &_lock); | |||||
| _retval = getPyNone(); | |||||
| applyEmission(flags, target, source, emissionTexture, isAbsolute, type); | |||||
| _args.check(); | |||||
| } | |||||
| pbFinalizePlugin(parent, "applyEmission", !noTiming); | |||||
| return _retval; | |||||
| } | |||||
| catch (std::exception &e) { | |||||
| pbSetError("applyEmission", e.what()); | |||||
| return 0; | |||||
| } | |||||
| } | |||||
| static const Pb::Register _RP_applyEmission("", "applyEmission", _W_7); | |||||
| extern "C" { | |||||
| void PbRegister_applyEmission() | |||||
| { | |||||
| KEEP_UNUSED(_RP_applyEmission); | |||||
| } | |||||
| } | |||||
| // blender init functions for meshes | |||||
| struct KnApplyDensity : public KernelBase { | |||||
| KnApplyDensity( | |||||
| const FlagGrid &flags, Grid<Real> &density, const Grid<Real> &sdf, Real value, Real sigma) | |||||
| : KernelBase(&flags, 0), flags(flags), density(density), sdf(sdf), value(value), sigma(sigma) | |||||
| { | |||||
| runMessage(); | |||||
| run(); | |||||
| } | |||||
| inline void op(int i, | |||||
| int j, | |||||
| int k, | |||||
| const FlagGrid &flags, | |||||
| Grid<Real> &density, | |||||
| const Grid<Real> &sdf, | |||||
| Real value, | |||||
| Real sigma) const | |||||
| { | |||||
| if (!flags.isFluid(i, j, k) || sdf(i, j, k) > sigma) | |||||
| return; | |||||
| density(i, j, k) = value; | |||||
| } | |||||
| inline const FlagGrid &getArg0() | |||||
| { | |||||
| return flags; | |||||
| } | |||||
| typedef FlagGrid type0; | |||||
| inline Grid<Real> &getArg1() | |||||
| { | |||||
| return density; | |||||
| } | |||||
| typedef Grid<Real> type1; | |||||
| inline const Grid<Real> &getArg2() | |||||
| { | |||||
| return sdf; | |||||
| } | |||||
| typedef Grid<Real> type2; | |||||
| inline Real &getArg3() | |||||
| { | |||||
| return value; | |||||
| } | |||||
| typedef Real type3; | |||||
| inline Real &getArg4() | |||||
| { | |||||
| return sigma; | |||||
| } | |||||
| typedef Real type4; | |||||
| void runMessage() | |||||
| { | |||||
| debMsg("Executing kernel KnApplyDensity ", 3); | |||||
| debMsg("Kernel range" | |||||
| << " x " << maxX << " y " << maxY << " z " << minZ << " - " << maxZ << " ", | |||||
| 4); | |||||
| }; | |||||
| void operator()(const tbb::blocked_range<IndexInt> &__r) const | |||||
| { | |||||
| const int _maxX = maxX; | |||||
| const int _maxY = maxY; | |||||
| if (maxZ > 1) { | |||||
| for (int k = __r.begin(); k != (int)__r.end(); k++) | |||||
| for (int j = 0; j < _maxY; j++) | |||||
| for (int i = 0; i < _maxX; i++) | |||||
| op(i, j, k, flags, density, sdf, value, sigma); | |||||
| } | |||||
| else { | |||||
| const int k = 0; | |||||
| for (int j = __r.begin(); j != (int)__r.end(); j++) | |||||
| for (int i = 0; i < _maxX; i++) | |||||
| op(i, j, k, flags, density, sdf, value, sigma); | |||||
| } | |||||
| } | |||||
| void run() | |||||
| { | |||||
| if (maxZ > 1) | |||||
| tbb::parallel_for(tbb::blocked_range<IndexInt>(minZ, maxZ), *this); | |||||
| else | |||||
| tbb::parallel_for(tbb::blocked_range<IndexInt>(0, maxY), *this); | |||||
| } | |||||
| const FlagGrid &flags; | |||||
| Grid<Real> &density; | |||||
| const Grid<Real> &sdf; | |||||
| Real value; | |||||
| Real sigma; | |||||
| }; | |||||
| //! Init noise-modulated density inside mesh | |||||
| void densityInflowMeshNoise(const FlagGrid &flags, | |||||
| Grid<Real> &density, | |||||
| const WaveletNoiseField &noise, | |||||
| Mesh *mesh, | |||||
| Real scale = 1.0, | |||||
| Real sigma = 0) | |||||
| { | |||||
| LevelsetGrid sdf(density.getParent(), false); | |||||
| mesh->computeLevelset(sdf, 1.); | |||||
| KnApplyNoiseInfl(flags, density, noise, sdf, scale, sigma); | |||||
| } | |||||
| static PyObject *_W_8(PyObject *_self, PyObject *_linargs, PyObject *_kwds) | |||||
| { | |||||
| try { | |||||
| PbArgs _args(_linargs, _kwds); | |||||
| FluidSolver *parent = _args.obtainParent(); | |||||
| bool noTiming = _args.getOpt<bool>("notiming", -1, 0); | |||||
| pbPreparePlugin(parent, "densityInflowMeshNoise", !noTiming); | |||||
| PyObject *_retval = 0; | |||||
| { | |||||
| ArgLocker _lock; | |||||
| const FlagGrid &flags = *_args.getPtr<FlagGrid>("flags", 0, &_lock); | |||||
| Grid<Real> &density = *_args.getPtr<Grid<Real>>("density", 1, &_lock); | |||||
| const WaveletNoiseField &noise = *_args.getPtr<WaveletNoiseField>("noise", 2, &_lock); | |||||
| Mesh *mesh = _args.getPtr<Mesh>("mesh", 3, &_lock); | |||||
| Real scale = _args.getOpt<Real>("scale", 4, 1.0, &_lock); | |||||
| Real sigma = _args.getOpt<Real>("sigma", 5, 0, &_lock); | |||||
| _retval = getPyNone(); | |||||
| densityInflowMeshNoise(flags, density, noise, mesh, scale, sigma); | |||||
| _args.check(); | |||||
| } | |||||
| pbFinalizePlugin(parent, "densityInflowMeshNoise", !noTiming); | |||||
| return _retval; | |||||
| } | |||||
| catch (std::exception &e) { | |||||
| pbSetError("densityInflowMeshNoise", e.what()); | |||||
| return 0; | |||||
| } | |||||
| } | |||||
| static const Pb::Register _RP_densityInflowMeshNoise("", "densityInflowMeshNoise", _W_8); | |||||
| extern "C" { | |||||
| void PbRegister_densityInflowMeshNoise() | |||||
| { | |||||
| KEEP_UNUSED(_RP_densityInflowMeshNoise); | |||||
| } | |||||
| } | |||||
| //! Init constant density inside mesh | |||||
| void densityInflowMesh(const FlagGrid &flags, | |||||
| Grid<Real> &density, | |||||
| Mesh *mesh, | |||||
| Real value = 1., | |||||
| Real cutoff = 7, | |||||
| Real sigma = 0) | |||||
| { | |||||
| LevelsetGrid sdf(density.getParent(), false); | |||||
| mesh->computeLevelset(sdf, 2., cutoff); | |||||
| KnApplyDensity(flags, density, sdf, value, sigma); | |||||
| } | |||||
| static PyObject *_W_9(PyObject *_self, PyObject *_linargs, PyObject *_kwds) | |||||
| { | |||||
| try { | |||||
| PbArgs _args(_linargs, _kwds); | |||||
| FluidSolver *parent = _args.obtainParent(); | |||||
| bool noTiming = _args.getOpt<bool>("notiming", -1, 0); | |||||
| pbPreparePlugin(parent, "densityInflowMesh", !noTiming); | |||||
| PyObject *_retval = 0; | |||||
| { | |||||
| ArgLocker _lock; | |||||
| const FlagGrid &flags = *_args.getPtr<FlagGrid>("flags", 0, &_lock); | |||||
| Grid<Real> &density = *_args.getPtr<Grid<Real>>("density", 1, &_lock); | |||||
| Mesh *mesh = _args.getPtr<Mesh>("mesh", 2, &_lock); | |||||
| Real value = _args.getOpt<Real>("value", 3, 1., &_lock); | |||||
| Real cutoff = _args.getOpt<Real>("cutoff", 4, 7, &_lock); | |||||
| Real sigma = _args.getOpt<Real>("sigma", 5, 0, &_lock); | |||||
| _retval = getPyNone(); | |||||
| densityInflowMesh(flags, density, mesh, value, cutoff, sigma); | |||||
| _args.check(); | |||||
| } | |||||
| pbFinalizePlugin(parent, "densityInflowMesh", !noTiming); | |||||
| return _retval; | |||||
| } | |||||
| catch (std::exception &e) { | |||||
| pbSetError("densityInflowMesh", e.what()); | |||||
| return 0; | |||||
| } | |||||
| } | |||||
| static const Pb::Register _RP_densityInflowMesh("", "densityInflowMesh", _W_9); | |||||
| extern "C" { | |||||
| void PbRegister_densityInflowMesh() | |||||
| { | |||||
| KEEP_UNUSED(_RP_densityInflowMesh); | |||||
| } | |||||
| } | |||||
| //***************************************************************************** | |||||
| //! check for symmetry , optionally enfore by copying | |||||
| void checkSymmetry( | |||||
| Grid<Real> &a, Grid<Real> *err = NULL, bool symmetrize = false, int axis = 0, int bound = 0) | |||||
| { | |||||
| const int c = axis; | |||||
| const int s = a.getSize()[c]; | |||||
| FOR_IJK(a) | |||||
| { | |||||
| Vec3i idx(i, j, k), mdx(i, j, k); | |||||
| mdx[c] = s - 1 - idx[c]; | |||||
| if (bound > 0 && ((!a.isInBounds(idx, bound)) || (!a.isInBounds(mdx, bound)))) | |||||
| continue; | |||||
| if (err) | |||||
| (*err)(idx) = fabs((double)(a(idx) - a(mdx))); | |||||
| if (symmetrize && (idx[c] < s / 2)) { | |||||
| a(idx) = a(mdx); | |||||
| } | |||||
| } | |||||
| } | |||||
| static PyObject *_W_10(PyObject *_self, PyObject *_linargs, PyObject *_kwds) | |||||
| { | |||||
| try { | |||||
| PbArgs _args(_linargs, _kwds); | |||||
| FluidSolver *parent = _args.obtainParent(); | |||||
| bool noTiming = _args.getOpt<bool>("notiming", -1, 0); | |||||
| pbPreparePlugin(parent, "checkSymmetry", !noTiming); | |||||
| PyObject *_retval = 0; | |||||
| { | |||||
| ArgLocker _lock; | |||||
| Grid<Real> &a = *_args.getPtr<Grid<Real>>("a", 0, &_lock); | |||||
| Grid<Real> *err = _args.getPtrOpt<Grid<Real>>("err", 1, NULL, &_lock); | |||||
| bool symmetrize = _args.getOpt<bool>("symmetrize", 2, false, &_lock); | |||||
| int axis = _args.getOpt<int>("axis", 3, 0, &_lock); | |||||
| int bound = _args.getOpt<int>("bound", 4, 0, &_lock); | |||||
| _retval = getPyNone(); | |||||
| checkSymmetry(a, err, symmetrize, axis, bound); | |||||
| _args.check(); | |||||
| } | |||||
| pbFinalizePlugin(parent, "checkSymmetry", !noTiming); | |||||
| return _retval; | |||||
| } | |||||
| catch (std::exception &e) { | |||||
| pbSetError("checkSymmetry", e.what()); | |||||
| return 0; | |||||
| } | |||||
| } | |||||
| static const Pb::Register _RP_checkSymmetry("", "checkSymmetry", _W_10); | |||||
| extern "C" { | |||||
| void PbRegister_checkSymmetry() | |||||
| { | |||||
| KEEP_UNUSED(_RP_checkSymmetry); | |||||
| } | |||||
| } | |||||
| //! check for symmetry , mac grid version | |||||
| void checkSymmetryVec3(Grid<Vec3> &a, | |||||
| Grid<Real> *err = NULL, | |||||
| bool symmetrize = false, | |||||
| int axis = 0, | |||||
| int bound = 0, | |||||
| int disable = 0) | |||||
| { | |||||
| if (err) | |||||
| err->setConst(0.); | |||||
| // each dimension is measured separately for flexibility (could be combined) | |||||
| const int c = axis; | |||||
| const int o1 = (c + 1) % 3; | |||||
| const int o2 = (c + 2) % 3; | |||||
| // x | |||||
| if (!(disable & 1)) { | |||||
| const int s = a.getSize()[c] + 1; | |||||
| FOR_IJK(a) | |||||
| { | |||||
| Vec3i idx(i, j, k), mdx(i, j, k); | |||||
| mdx[c] = s - 1 - idx[c]; | |||||
| if (mdx[c] >= a.getSize()[c]) | |||||
| continue; | |||||
| if (bound > 0 && ((!a.isInBounds(idx, bound)) || (!a.isInBounds(mdx, bound)))) | |||||
| continue; | |||||
| // special case: center "line" of values , should be zero! | |||||
| if (mdx[c] == idx[c]) { | |||||
| if (err) | |||||
| (*err)(idx) += fabs((double)(a(idx)[c])); | |||||
| if (symmetrize) | |||||
| a(idx)[c] = 0.; | |||||
| continue; | |||||
| } | |||||
| // note - the a(mdx) component needs to be inverted here! | |||||
| if (err) | |||||
| (*err)(idx) += fabs((double)(a(idx)[c] - (a(mdx)[c] * -1.))); | |||||
| if (symmetrize && (idx[c] < s / 2)) { | |||||
| a(idx)[c] = a(mdx)[c] * -1.; | |||||
| } | |||||
| } | |||||
| } | |||||
| // y | |||||
| if (!(disable & 2)) { | |||||
| const int s = a.getSize()[c]; | |||||
| FOR_IJK(a) | |||||
| { | |||||
| Vec3i idx(i, j, k), mdx(i, j, k); | |||||
| mdx[c] = s - 1 - idx[c]; | |||||
| if (bound > 0 && ((!a.isInBounds(idx, bound)) || (!a.isInBounds(mdx, bound)))) | |||||
| continue; | |||||
| if (err) | |||||
| (*err)(idx) += fabs((double)(a(idx)[o1] - a(mdx)[o1])); | |||||
| if (symmetrize && (idx[c] < s / 2)) { | |||||
| a(idx)[o1] = a(mdx)[o1]; | |||||
| } | |||||
| } | |||||
| } | |||||
| // z | |||||
| if (!(disable & 4)) { | |||||
| const int s = a.getSize()[c]; | |||||
| FOR_IJK(a) | |||||
| { | |||||
| Vec3i idx(i, j, k), mdx(i, j, k); | |||||
| mdx[c] = s - 1 - idx[c]; | |||||
| if (bound > 0 && ((!a.isInBounds(idx, bound)) || (!a.isInBounds(mdx, bound)))) | |||||
| continue; | |||||
| if (err) | |||||
| (*err)(idx) += fabs((double)(a(idx)[o2] - a(mdx)[o2])); | |||||
| if (symmetrize && (idx[c] < s / 2)) { | |||||
| a(idx)[o2] = a(mdx)[o2]; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| static PyObject *_W_11(PyObject *_self, PyObject *_linargs, PyObject *_kwds) | |||||
| { | |||||
| try { | |||||
| PbArgs _args(_linargs, _kwds); | |||||
| FluidSolver *parent = _args.obtainParent(); | |||||
| bool noTiming = _args.getOpt<bool>("notiming", -1, 0); | |||||
| pbPreparePlugin(parent, "checkSymmetryVec3", !noTiming); | |||||
| PyObject *_retval = 0; | |||||
| { | |||||
| ArgLocker _lock; | |||||
| Grid<Vec3> &a = *_args.getPtr<Grid<Vec3>>("a", 0, &_lock); | |||||
| Grid<Real> *err = _args.getPtrOpt<Grid<Real>>("err", 1, NULL, &_lock); | |||||
| bool symmetrize = _args.getOpt<bool>("symmetrize", 2, false, &_lock); | |||||
| int axis = _args.getOpt<int>("axis", 3, 0, &_lock); | |||||
| int bound = _args.getOpt<int>("bound", 4, 0, &_lock); | |||||
| int disable = _args.getOpt<int>("disable", 5, 0, &_lock); | |||||
| _retval = getPyNone(); | |||||
| checkSymmetryVec3(a, err, symmetrize, axis, bound, disable); | |||||
| _args.check(); | |||||
| } | |||||
| pbFinalizePlugin(parent, "checkSymmetryVec3", !noTiming); | |||||
| return _retval; | |||||
| } | |||||
| catch (std::exception &e) { | |||||
| pbSetError("checkSymmetryVec3", e.what()); | |||||
| return 0; | |||||
| } | |||||
| } | |||||
| static const Pb::Register _RP_checkSymmetryVec3("", "checkSymmetryVec3", _W_11); | |||||
| extern "C" { | |||||
| void PbRegister_checkSymmetryVec3() | |||||
| { | |||||
| KEEP_UNUSED(_RP_checkSymmetryVec3); | |||||
| } | |||||
| } | |||||
| // from simpleimage.cpp | |||||
| void projectImg(SimpleImage &img, const Grid<Real> &val, int shadeMode = 0, Real scale = 1.); | |||||
| //! output shaded (all 3 axes at once for 3D) | |||||
| //! shading modes: 0 smoke, 1 surfaces | |||||
| void projectPpmFull(const Grid<Real> &val, string name, int shadeMode = 0, Real scale = 1.) | |||||
| { | |||||
| SimpleImage img; | |||||
| projectImg(img, val, shadeMode, scale); | |||||
| img.writePpm(name); | |||||
| } | |||||
| static PyObject *_W_12(PyObject *_self, PyObject *_linargs, PyObject *_kwds) | |||||
| { | |||||
| try { | |||||
| PbArgs _args(_linargs, _kwds); | |||||
| FluidSolver *parent = _args.obtainParent(); | |||||
| bool noTiming = _args.getOpt<bool>("notiming", -1, 0); | |||||
| pbPreparePlugin(parent, "projectPpmFull", !noTiming); | |||||
| PyObject *_retval = 0; | |||||
| { | |||||
| ArgLocker _lock; | |||||
| const Grid<Real> &val = *_args.getPtr<Grid<Real>>("val", 0, &_lock); | |||||
| string name = _args.get<string>("name", 1, &_lock); | |||||
| int shadeMode = _args.getOpt<int>("shadeMode", 2, 0, &_lock); | |||||
| Real scale = _args.getOpt<Real>("scale", 3, 1., &_lock); | |||||
| _retval = getPyNone(); | |||||
| projectPpmFull(val, name, shadeMode, scale); | |||||
| _args.check(); | |||||
| } | |||||
| pbFinalizePlugin(parent, "projectPpmFull", !noTiming); | |||||
| return _retval; | |||||
| } | |||||
| catch (std::exception &e) { | |||||
| pbSetError("projectPpmFull", e.what()); | |||||
| return 0; | |||||
| } | |||||
| } | |||||
| static const Pb::Register _RP_projectPpmFull("", "projectPpmFull", _W_12); | |||||
| extern "C" { | |||||
| void PbRegister_projectPpmFull() | |||||
| { | |||||
| KEEP_UNUSED(_RP_projectPpmFull); | |||||
| } | |||||
| } | |||||
| // helper functions for pdata operator tests | |||||
| //! init some test particles at the origin | |||||
| void addTestParts(BasicParticleSystem &parts, int num) | |||||
| { | |||||
| for (int i = 0; i < num; ++i) | |||||
| parts.addBuffered(Vec3(0, 0, 0)); | |||||
| parts.doCompress(); | |||||
| parts.insertBufferedParticles(); | |||||
| } | |||||
| static PyObject *_W_13(PyObject *_self, PyObject *_linargs, PyObject *_kwds) | |||||
| { | |||||
| try { | |||||
| PbArgs _args(_linargs, _kwds); | |||||
| FluidSolver *parent = _args.obtainParent(); | |||||
| bool noTiming = _args.getOpt<bool>("notiming", -1, 0); | |||||
| pbPreparePlugin(parent, "addTestParts", !noTiming); | |||||
| PyObject *_retval = 0; | |||||
| { | |||||
| ArgLocker _lock; | |||||
| BasicParticleSystem &parts = *_args.getPtr<BasicParticleSystem>("parts", 0, &_lock); | |||||
| int num = _args.get<int>("num", 1, &_lock); | |||||
| _retval = getPyNone(); | |||||
| addTestParts(parts, num); | |||||
| _args.check(); | |||||
| } | |||||
| pbFinalizePlugin(parent, "addTestParts", !noTiming); | |||||
| return _retval; | |||||
| } | |||||
| catch (std::exception &e) { | |||||
| pbSetError("addTestParts", e.what()); | |||||
| return 0; | |||||
| } | |||||
| } | |||||
| static const Pb::Register _RP_addTestParts("", "addTestParts", _W_13); | |||||
| extern "C" { | |||||
| void PbRegister_addTestParts() | |||||
| { | |||||
| KEEP_UNUSED(_RP_addTestParts); | |||||
| } | |||||
| } | |||||
| //! calculate the difference between two pdata fields (note - slow!, not parallelized) | |||||
| Real pdataMaxDiff(const ParticleDataBase *a, const ParticleDataBase *b) | |||||
| { | |||||
| double maxVal = 0.; | |||||
| // debMsg(" PD "<< a->getType()<<" as"<<a->getSizeSlow()<<" bs"<<b->getSizeSlow() , 1); | |||||
| assertMsg(a->getType() == b->getType(), "pdataMaxDiff problem - different pdata types!"); | |||||
| assertMsg(a->getSizeSlow() == b->getSizeSlow(), "pdataMaxDiff problem - different pdata sizes!"); | |||||
| if (a->getType() & ParticleDataBase::TypeReal) { | |||||
| const ParticleDataImpl<Real> &av = *dynamic_cast<const ParticleDataImpl<Real> *>(a); | |||||
| const ParticleDataImpl<Real> &bv = *dynamic_cast<const ParticleDataImpl<Real> *>(b); | |||||
| FOR_PARTS(av) | |||||
| { | |||||
| maxVal = std::max(maxVal, (double)fabs(av[idx] - bv[idx])); | |||||
| } | |||||
| } | |||||
| else if (a->getType() & ParticleDataBase::TypeInt) { | |||||
| const ParticleDataImpl<int> &av = *dynamic_cast<const ParticleDataImpl<int> *>(a); | |||||
| const ParticleDataImpl<int> &bv = *dynamic_cast<const ParticleDataImpl<int> *>(b); | |||||
| FOR_PARTS(av) | |||||
| { | |||||
| maxVal = std::max(maxVal, (double)fabs((double)av[idx] - bv[idx])); | |||||
| } | |||||
| } | |||||
| else if (a->getType() & ParticleDataBase::TypeVec3) { | |||||
| const ParticleDataImpl<Vec3> &av = *dynamic_cast<const ParticleDataImpl<Vec3> *>(a); | |||||
| const ParticleDataImpl<Vec3> &bv = *dynamic_cast<const ParticleDataImpl<Vec3> *>(b); | |||||
| FOR_PARTS(av) | |||||
| { | |||||
| double d = 0.; | |||||
| for (int c = 0; c < 3; ++c) { | |||||
| d += fabs((double)av[idx][c] - (double)bv[idx][c]); | |||||
| } | |||||
| maxVal = std::max(maxVal, d); | |||||
| } | |||||
| } | |||||
| else { | |||||
| errMsg("pdataMaxDiff: Grid Type is not supported (only Real, Vec3, int)"); | |||||
| } | |||||
| return maxVal; | |||||
| } | |||||
| static PyObject *_W_14(PyObject *_self, PyObject *_linargs, PyObject *_kwds) | |||||
| { | |||||
| try { | |||||
| PbArgs _args(_linargs, _kwds); | |||||
| FluidSolver *parent = _args.obtainParent(); | |||||
| bool noTiming = _args.getOpt<bool>("notiming", -1, 0); | |||||
| pbPreparePlugin(parent, "pdataMaxDiff", !noTiming); | |||||
| PyObject *_retval = 0; | |||||
| { | |||||
| ArgLocker _lock; | |||||
| const ParticleDataBase *a = _args.getPtr<ParticleDataBase>("a", 0, &_lock); | |||||
| const ParticleDataBase *b = _args.getPtr<ParticleDataBase>("b", 1, &_lock); | |||||
| _retval = toPy(pdataMaxDiff(a, b)); | |||||
| _args.check(); | |||||
| } | |||||
| pbFinalizePlugin(parent, "pdataMaxDiff", !noTiming); | |||||
| return _retval; | |||||
| } | |||||
| catch (std::exception &e) { | |||||
| pbSetError("pdataMaxDiff", e.what()); | |||||
| return 0; | |||||
| } | |||||
| } | |||||
| static const Pb::Register _RP_pdataMaxDiff("", "pdataMaxDiff", _W_14); | |||||
| extern "C" { | |||||
| void PbRegister_pdataMaxDiff() | |||||
| { | |||||
| KEEP_UNUSED(_RP_pdataMaxDiff); | |||||
| } | |||||
| } | |||||
| //! calculate center of mass given density grid, for re-centering | |||||
| Vec3 calcCenterOfMass(const Grid<Real> &density) | |||||
| { | |||||
| Vec3 p(0.0f); | |||||
| Real w = 0.0f; | |||||
| FOR_IJK(density) | |||||
| { | |||||
| p += density(i, j, k) * Vec3(i + 0.5f, j + 0.5f, k + 0.5f); | |||||
| w += density(i, j, k); | |||||
| } | |||||
| if (w > 1e-6f) | |||||
| p /= w; | |||||
| return p; | |||||
| } | |||||
| static PyObject *_W_15(PyObject *_self, PyObject *_linargs, PyObject *_kwds) | |||||
| { | |||||
| try { | |||||
| PbArgs _args(_linargs, _kwds); | |||||
| FluidSolver *parent = _args.obtainParent(); | |||||
| bool noTiming = _args.getOpt<bool>("notiming", -1, 0); | |||||
| pbPreparePlugin(parent, "calcCenterOfMass", !noTiming); | |||||
| PyObject *_retval = 0; | |||||
| { | |||||
| ArgLocker _lock; | |||||
| const Grid<Real> &density = *_args.getPtr<Grid<Real>>("density", 0, &_lock); | |||||
| _retval = toPy(calcCenterOfMass(density)); | |||||
| _args.check(); | |||||
| } | |||||
| pbFinalizePlugin(parent, "calcCenterOfMass", !noTiming); | |||||
| return _retval; | |||||
| } | |||||
| catch (std::exception &e) { | |||||
| pbSetError("calcCenterOfMass", e.what()); | |||||
| return 0; | |||||
| } | |||||
| } | |||||
| static const Pb::Register _RP_calcCenterOfMass("", "calcCenterOfMass", _W_15); | |||||
| extern "C" { | |||||
| void PbRegister_calcCenterOfMass() | |||||
| { | |||||
| KEEP_UNUSED(_RP_calcCenterOfMass); | |||||
| } | |||||
| } | |||||
| //***************************************************************************** | |||||
| // helper functions for volume fractions (which are needed for second order obstacle boundaries) | |||||
| inline static Real calcFraction(Real phi1, Real phi2, Real fracThreshold) | |||||
| { | |||||
| if (phi1 > 0. && phi2 > 0.) | |||||
| return 1.; | |||||
| if (phi1 < 0. && phi2 < 0.) | |||||
| return 0.; | |||||
| // make sure phi1 < phi2 | |||||
| if (phi2 < phi1) { | |||||
| Real t = phi1; | |||||
| phi1 = phi2; | |||||
| phi2 = t; | |||||
| } | |||||
| Real denom = phi1 - phi2; | |||||
| if (denom > -1e-04) | |||||
| return 0.5; | |||||
| Real frac = 1. - phi1 / denom; | |||||
| if (frac < fracThreshold) | |||||
| frac = 0.; // stomp small values , dont mark as fluid | |||||
| return std::min(Real(1), frac); | |||||
| } | |||||
| struct KnUpdateFractions : public KernelBase { | |||||
| KnUpdateFractions(const FlagGrid &flags, | |||||
| const Grid<Real> &phiObs, | |||||
| MACGrid &fractions, | |||||
| const int &boundaryWidth, | |||||
| const Real fracThreshold) | |||||
| : KernelBase(&flags, 1), | |||||
| flags(flags), | |||||
| phiObs(phiObs), | |||||
| fractions(fractions), | |||||
| boundaryWidth(boundaryWidth), | |||||
| fracThreshold(fracThreshold) | |||||
| { | |||||
| runMessage(); | |||||
| run(); | |||||
| } | |||||
| inline void op(int i, | |||||
| int j, | |||||
| int k, | |||||
| const FlagGrid &flags, | |||||
| const Grid<Real> &phiObs, | |||||
| MACGrid &fractions, | |||||
| const int &boundaryWidth, | |||||
| const Real fracThreshold) const | |||||
| { | |||||
| // walls at domain bounds and inner objects | |||||
| fractions(i, j, k).x = calcFraction(phiObs(i, j, k), phiObs(i - 1, j, k), fracThreshold); | |||||
| fractions(i, j, k).y = calcFraction(phiObs(i, j, k), phiObs(i, j - 1, k), fracThreshold); | |||||
| if (phiObs.is3D()) { | |||||
| fractions(i, j, k).z = calcFraction(phiObs(i, j, k), phiObs(i, j, k - 1), fracThreshold); | |||||
| } | |||||
| // remaining BCs at the domain boundaries | |||||
| const int w = boundaryWidth; | |||||
| // only set if not in obstacle | |||||
| if (phiObs(i, j, k) < 0.) | |||||
| return; | |||||
| // x-direction boundaries | |||||
| if (i <= w + 1) { // min x | |||||
| if ((flags.isInflow(i - 1, j, k)) || (flags.isOutflow(i - 1, j, k)) || | |||||
| (flags.isOpen(i - 1, j, k))) { | |||||
| fractions(i, j, k).x = fractions(i, j, k).y = 1.; | |||||
| if (flags.is3D()) | |||||
| fractions(i, j, k).z = 1.; | |||||
| } | |||||
| } | |||||
| if (i >= flags.getSizeX() - w - 2) { // max x | |||||
| if ((flags.isInflow(i + 1, j, k)) || (flags.isOutflow(i + 1, j, k)) || | |||||
| (flags.isOpen(i + 1, j, k))) { | |||||
| fractions(i + 1, j, k).x = fractions(i + 1, j, k).y = 1.; | |||||
| if (flags.is3D()) | |||||
| fractions(i + 1, j, k).z = 1.; | |||||
| } | |||||
| } | |||||
| // y-direction boundaries | |||||
| if (j <= w + 1) { // min y | |||||
| if ((flags.isInflow(i, j - 1, k)) || (flags.isOutflow(i, j - 1, k)) || | |||||
| (flags.isOpen(i, j - 1, k))) { | |||||
| fractions(i, j, k).x = fractions(i, j, k).y = 1.; | |||||
| if (flags.is3D()) | |||||
| fractions(i, j, k).z = 1.; | |||||
| } | |||||
| } | |||||
| if (j >= flags.getSizeY() - w - 2) { // max y | |||||
| if ((flags.isInflow(i, j + 1, k)) || (flags.isOutflow(i, j + 1, k)) || | |||||
| (flags.isOpen(i, j + 1, k))) { | |||||
| fractions(i, j + 1, k).x = fractions(i, j + 1, k).y = 1.; | |||||
| if (flags.is3D()) | |||||
| fractions(i, j + 1, k).z = 1.; | |||||
| } | |||||
| } | |||||
| // z-direction boundaries | |||||
| if (flags.is3D()) { | |||||
| if (k <= w + 1) { // min z | |||||
| if ((flags.isInflow(i, j, k - 1)) || (flags.isOutflow(i, j, k - 1)) || | |||||
| (flags.isOpen(i, j, k - 1))) { | |||||
| fractions(i, j, k).x = fractions(i, j, k).y = 1.; | |||||
| if (flags.is3D()) | |||||
| fractions(i, j, k).z = 1.; | |||||
| } | |||||
| } | |||||
| if (j >= flags.getSizeZ() - w - 2) { // max z | |||||
| if ((flags.isInflow(i, j, k + 1)) || (flags.isOutflow(i, j, k + 1)) || | |||||
| (flags.isOpen(i, j, k + 1))) { | |||||
| fractions(i, j, k + 1).x = fractions(i, j, k + 1).y = 1.; | |||||
| if (flags.is3D()) | |||||
| fractions(i, j, k + 1).z = 1.; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| inline const FlagGrid &getArg0() | |||||
| { | |||||
| return flags; | |||||
| } | |||||
| typedef FlagGrid type0; | |||||
| inline const Grid<Real> &getArg1() | |||||
| { | |||||
| return phiObs; | |||||
| } | |||||
| typedef Grid<Real> type1; | |||||
| inline MACGrid &getArg2() | |||||
| { | |||||
| return fractions; | |||||
| } | |||||
| typedef MACGrid type2; | |||||
| inline const int &getArg3() | |||||
| { | |||||
| return boundaryWidth; | |||||
| } | |||||
| typedef int type3; | |||||
| inline const Real &getArg4() | |||||
| { | |||||
| return fracThreshold; | |||||
| } | |||||
| typedef Real type4; | |||||
| void runMessage() | |||||
| { | |||||
| debMsg("Executing kernel KnUpdateFractions ", 3); | |||||
| debMsg("Kernel range" | |||||
| << " x " << maxX << " y " << maxY << " z " << minZ << " - " << maxZ << " ", | |||||
| 4); | |||||
| }; | |||||
| void operator()(const tbb::blocked_range<IndexInt> &__r) const | |||||
| { | |||||
| const int _maxX = maxX; | |||||
| const int _maxY = maxY; | |||||
| if (maxZ > 1) { | |||||
| for (int k = __r.begin(); k != (int)__r.end(); k++) | |||||
| for (int j = 1; j < _maxY; j++) | |||||
| for (int i = 1; i < _maxX; i++) | |||||
| op(i, j, k, flags, phiObs, fractions, boundaryWidth, fracThreshold); | |||||
| } | |||||
| else { | |||||
| const int k = 0; | |||||
| for (int j = __r.begin(); j != (int)__r.end(); j++) | |||||
| for (int i = 1; i < _maxX; i++) | |||||
| op(i, j, k, flags, phiObs, fractions, boundaryWidth, fracThreshold); | |||||
| } | |||||
| } | |||||
| void run() | |||||
| { | |||||
| if (maxZ > 1) | |||||
| tbb::parallel_for(tbb::blocked_range<IndexInt>(minZ, maxZ), *this); | |||||
| else | |||||
| tbb::parallel_for(tbb::blocked_range<IndexInt>(1, maxY), *this); | |||||
| } | |||||
| const FlagGrid &flags; | |||||
| const Grid<Real> &phiObs; | |||||
| MACGrid &fractions; | |||||
| const int &boundaryWidth; | |||||
| const Real fracThreshold; | |||||
| }; | |||||
| //! update fill fraction values | |||||
| void updateFractions(const FlagGrid &flags, | |||||
| const Grid<Real> &phiObs, | |||||
| MACGrid &fractions, | |||||
| const int &boundaryWidth = 0, | |||||
| const Real fracThreshold = 0.01) | |||||
| { | |||||
| fractions.setConst(Vec3(0.)); | |||||
| KnUpdateFractions(flags, phiObs, fractions, boundaryWidth, fracThreshold); | |||||
| } | |||||
| static PyObject *_W_16(PyObject *_self, PyObject *_linargs, PyObject *_kwds) | |||||
| { | |||||
| try { | |||||
| PbArgs _args(_linargs, _kwds); | |||||
| FluidSolver *parent = _args.obtainParent(); | |||||
| bool noTiming = _args.getOpt<bool>("notiming", -1, 0); | |||||
| pbPreparePlugin(parent, "updateFractions", !noTiming); | |||||
| PyObject *_retval = 0; | |||||
| { | |||||
| ArgLocker _lock; | |||||
| const FlagGrid &flags = *_args.getPtr<FlagGrid>("flags", 0, &_lock); | |||||
| const Grid<Real> &phiObs = *_args.getPtr<Grid<Real>>("phiObs", 1, &_lock); | |||||
| MACGrid &fractions = *_args.getPtr<MACGrid>("fractions", 2, &_lock); | |||||
| const int &boundaryWidth = _args.getOpt<int>("boundaryWidth", 3, 0, &_lock); | |||||
| const Real fracThreshold = _args.getOpt<Real>("fracThreshold", 4, 0.01, &_lock); | |||||
| _retval = getPyNone(); | |||||
| updateFractions(flags, phiObs, fractions, boundaryWidth, fracThreshold); | |||||
| _args.check(); | |||||
| } | |||||
| pbFinalizePlugin(parent, "updateFractions", !noTiming); | |||||
| return _retval; | |||||
| } | |||||
| catch (std::exception &e) { | |||||
| pbSetError("updateFractions", e.what()); | |||||
| return 0; | |||||
| } | |||||
| } | |||||
| static const Pb::Register _RP_updateFractions("", "updateFractions", _W_16); | |||||
| extern "C" { | |||||
| void PbRegister_updateFractions() | |||||
| { | |||||
| KEEP_UNUSED(_RP_updateFractions); | |||||
| } | |||||
| } | |||||
| struct KnUpdateFlagsObs : public KernelBase { | |||||
| KnUpdateFlagsObs(FlagGrid &flags, | |||||
| const MACGrid *fractions, | |||||
| const Grid<Real> &phiObs, | |||||
| const Grid<Real> *phiOut, | |||||
| const Grid<Real> *phiIn) | |||||
| : KernelBase(&flags, 1), | |||||
| flags(flags), | |||||
| fractions(fractions), | |||||
| phiObs(phiObs), | |||||
| phiOut(phiOut), | |||||
| phiIn(phiIn) | |||||
| { | |||||
| runMessage(); | |||||
| run(); | |||||
| } | |||||
| inline void op(int i, | |||||
| int j, | |||||
| int k, | |||||
| FlagGrid &flags, | |||||
| const MACGrid *fractions, | |||||
| const Grid<Real> &phiObs, | |||||
| const Grid<Real> *phiOut, | |||||
| const Grid<Real> *phiIn) const | |||||
| { | |||||
| bool isObs = false; | |||||
| if (fractions) { | |||||
| Real f = 0.; | |||||
| f += fractions->get(i, j, k).x; | |||||
| f += fractions->get(i + 1, j, k).x; | |||||
| f += fractions->get(i, j, k).y; | |||||
| f += fractions->get(i, j + 1, k).y; | |||||
| if (flags.is3D()) { | |||||
| f += fractions->get(i, j, k).z; | |||||
| f += fractions->get(i, j, k + 1).z; | |||||
| } | |||||
| if (f == 0.) | |||||
| isObs = true; | |||||
| } | |||||
| else { | |||||
| if (phiObs(i, j, k) < 0.) | |||||
| isObs = true; | |||||
| } | |||||
| bool isOutflow = false; | |||||
| bool isInflow = false; | |||||
| if (phiOut && (*phiOut)(i, j, k) < 0.) | |||||
| isOutflow = true; | |||||
| if (phiIn && (*phiIn)(i, j, k) < 0.) | |||||
| isInflow = true; | |||||
| if (isObs) | |||||
| flags(i, j, k) = FlagGrid::TypeObstacle; | |||||
| else if (isInflow) | |||||
| flags(i, j, k) = (FlagGrid::TypeFluid | FlagGrid::TypeInflow); | |||||
| else if (isOutflow) | |||||
| flags(i, j, k) = (FlagGrid::TypeEmpty | FlagGrid::TypeOutflow); | |||||
| else | |||||
| flags(i, j, k) = FlagGrid::TypeEmpty; | |||||
| } | |||||
| inline FlagGrid &getArg0() | |||||
| { | |||||
| return flags; | |||||
| } | |||||
| typedef FlagGrid type0; | |||||
| inline const MACGrid *getArg1() | |||||
| { | |||||
| return fractions; | |||||
| } | |||||
| typedef MACGrid type1; | |||||
| inline const Grid<Real> &getArg2() | |||||
| { | |||||
| return phiObs; | |||||
| } | |||||
| typedef Grid<Real> type2; | |||||
| inline const Grid<Real> *getArg3() | |||||
| { | |||||
| return phiOut; | |||||
| } | |||||
| typedef Grid<Real> type3; | |||||
| inline const Grid<Real> *getArg4() | |||||
| { | |||||
| return phiIn; | |||||
| } | |||||
| typedef Grid<Real> type4; | |||||
| void runMessage() | |||||
| { | |||||
| debMsg("Executing kernel KnUpdateFlagsObs ", 3); | |||||
| debMsg("Kernel range" | |||||
| << " x " << maxX << " y " << maxY << " z " << minZ << " - " << maxZ << " ", | |||||
| 4); | |||||
| }; | |||||
| void operator()(const tbb::blocked_range<IndexInt> &__r) const | |||||
| { | |||||
| const int _maxX = maxX; | |||||
| const int _maxY = maxY; | |||||
| if (maxZ > 1) { | |||||
| for (int k = __r.begin(); k != (int)__r.end(); k++) | |||||
| for (int j = 1; j < _maxY; j++) | |||||
| for (int i = 1; i < _maxX; i++) | |||||
| op(i, j, k, flags, fractions, phiObs, phiOut, phiIn); | |||||
| } | |||||
| else { | |||||
| const int k = 0; | |||||
| for (int j = __r.begin(); j != (int)__r.end(); j++) | |||||
| for (int i = 1; i < _maxX; i++) | |||||
| op(i, j, k, flags, fractions, phiObs, phiOut, phiIn); | |||||
| } | |||||
| } | |||||
| void run() | |||||
| { | |||||
| if (maxZ > 1) | |||||
| tbb::parallel_for(tbb::blocked_range<IndexInt>(minZ, maxZ), *this); | |||||
| else | |||||
| tbb::parallel_for(tbb::blocked_range<IndexInt>(1, maxY), *this); | |||||
| } | |||||
| FlagGrid &flags; | |||||
| const MACGrid *fractions; | |||||
| const Grid<Real> &phiObs; | |||||
| const Grid<Real> *phiOut; | |||||
| const Grid<Real> *phiIn; | |||||
| }; | |||||
| //! update obstacle and outflow flags from levelsets | |||||
| //! optionally uses fill fractions for obstacle | |||||
| void setObstacleFlags(FlagGrid &flags, | |||||
| const Grid<Real> &phiObs, | |||||
| const MACGrid *fractions = NULL, | |||||
| const Grid<Real> *phiOut = NULL, | |||||
| const Grid<Real> *phiIn = NULL) | |||||
| { | |||||
| KnUpdateFlagsObs(flags, fractions, phiObs, phiOut, phiIn); | |||||
| } | |||||
| static PyObject *_W_17(PyObject *_self, PyObject *_linargs, PyObject *_kwds) | |||||
| { | |||||
| try { | |||||
| PbArgs _args(_linargs, _kwds); | |||||
| FluidSolver *parent = _args.obtainParent(); | |||||
| bool noTiming = _args.getOpt<bool>("notiming", -1, 0); | |||||
| pbPreparePlugin(parent, "setObstacleFlags", !noTiming); | |||||
| PyObject *_retval = 0; | |||||
| { | |||||
| ArgLocker _lock; | |||||
| FlagGrid &flags = *_args.getPtr<FlagGrid>("flags", 0, &_lock); | |||||
| const Grid<Real> &phiObs = *_args.getPtr<Grid<Real>>("phiObs", 1, &_lock); | |||||
| const MACGrid *fractions = _args.getPtrOpt<MACGrid>("fractions", 2, NULL, &_lock); | |||||
| const Grid<Real> *phiOut = _args.getPtrOpt<Grid<Real>>("phiOut", 3, NULL, &_lock); | |||||
| const Grid<Real> *phiIn = _args.getPtrOpt<Grid<Real>>("phiIn", 4, NULL, &_lock); | |||||
| _retval = getPyNone(); | |||||
| setObstacleFlags(flags, phiObs, fractions, phiOut, phiIn); | |||||
| _args.check(); | |||||
| } | |||||
| pbFinalizePlugin(parent, "setObstacleFlags", !noTiming); | |||||
| return _retval; | |||||
| } | |||||
| catch (std::exception &e) { | |||||
| pbSetError("setObstacleFlags", e.what()); | |||||
| return 0; | |||||
| } | |||||
| } | |||||
| static const Pb::Register _RP_setObstacleFlags("", "setObstacleFlags", _W_17); | |||||
| extern "C" { | |||||
| void PbRegister_setObstacleFlags() | |||||
| { | |||||
| KEEP_UNUSED(_RP_setObstacleFlags); | |||||
| } | |||||
| } | |||||
| //! small helper for test case test_1040_secOrderBnd.py | |||||
| struct kninitVortexVelocity : public KernelBase { | |||||
| kninitVortexVelocity(const Grid<Real> &phiObs, | |||||
| MACGrid &vel, | |||||
| const Vec3 ¢er, | |||||
| const Real &radius) | |||||
| : KernelBase(&phiObs, 0), phiObs(phiObs), vel(vel), center(center), radius(radius) | |||||
| { | |||||
| runMessage(); | |||||
| run(); | |||||
| } | |||||
| inline void op(int i, | |||||
| int j, | |||||
| int k, | |||||
| const Grid<Real> &phiObs, | |||||
| MACGrid &vel, | |||||
| const Vec3 ¢er, | |||||
| const Real &radius) const | |||||
| { | |||||
| if (phiObs(i, j, k) >= -1.) { | |||||
| Real dx = i - center.x; | |||||
| if (dx >= 0) | |||||
| dx -= .5; | |||||
| else | |||||
| dx += .5; | |||||
| Real dy = j - center.y; | |||||
| Real r = std::sqrt(dx * dx + dy * dy); | |||||
| Real alpha = atan2(dy, dx); | |||||
| vel(i, j, k).x = -std::sin(alpha) * (r / radius); | |||||
| dx = i - center.x; | |||||
| dy = j - center.y; | |||||
| if (dy >= 0) | |||||
| dy -= .5; | |||||
| else | |||||
| dy += .5; | |||||
| r = std::sqrt(dx * dx + dy * dy); | |||||
| alpha = atan2(dy, dx); | |||||
| vel(i, j, k).y = std::cos(alpha) * (r / radius); | |||||
| } | |||||
| } | |||||
| inline const Grid<Real> &getArg0() | |||||
| { | |||||
| return phiObs; | |||||
| } | |||||
| typedef Grid<Real> type0; | |||||
| inline MACGrid &getArg1() | |||||
| { | |||||
| return vel; | |||||
| } | |||||
| typedef MACGrid type1; | |||||
| inline const Vec3 &getArg2() | |||||
| { | |||||
| return center; | |||||
| } | |||||
| typedef Vec3 type2; | |||||
| inline const Real &getArg3() | |||||
| { | |||||
| return radius; | |||||
| } | |||||
| typedef Real type3; | |||||
| void runMessage() | |||||
| { | |||||
| debMsg("Executing kernel kninitVortexVelocity ", 3); | |||||
| debMsg("Kernel range" | |||||
| << " x " << maxX << " y " << maxY << " z " << minZ << " - " << maxZ << " ", | |||||
| 4); | |||||
| }; | |||||
| void operator()(const tbb::blocked_range<IndexInt> &__r) const | |||||
| { | |||||
| const int _maxX = maxX; | |||||
| const int _maxY = maxY; | |||||
| if (maxZ > 1) { | |||||
| for (int k = __r.begin(); k != (int)__r.end(); k++) | |||||
| for (int j = 0; j < _maxY; j++) | |||||
| for (int i = 0; i < _maxX; i++) | |||||
| op(i, j, k, phiObs, vel, center, radius); | |||||
| } | |||||
| else { | |||||
| const int k = 0; | |||||
| for (int j = __r.begin(); j != (int)__r.end(); j++) | |||||
| for (int i = 0; i < _maxX; i++) | |||||
| op(i, j, k, phiObs, vel, center, radius); | |||||
| } | |||||
| } | |||||
| void run() | |||||
| { | |||||
| if (maxZ > 1) | |||||
| tbb::parallel_for(tbb::blocked_range<IndexInt>(minZ, maxZ), *this); | |||||
| else | |||||
| tbb::parallel_for(tbb::blocked_range<IndexInt>(0, maxY), *this); | |||||
| } | |||||
| const Grid<Real> &phiObs; | |||||
| MACGrid &vel; | |||||
| const Vec3 ¢er; | |||||
| const Real &radius; | |||||
| }; | |||||
| void initVortexVelocity(const Grid<Real> &phiObs, | |||||
| MACGrid &vel, | |||||
| const Vec3 ¢er, | |||||
| const Real &radius) | |||||
| { | |||||
| kninitVortexVelocity(phiObs, vel, center, radius); | |||||
| } | |||||
| static PyObject *_W_18(PyObject *_self, PyObject *_linargs, PyObject *_kwds) | |||||
| { | |||||
| try { | |||||
| PbArgs _args(_linargs, _kwds); | |||||
| FluidSolver *parent = _args.obtainParent(); | |||||
| bool noTiming = _args.getOpt<bool>("notiming", -1, 0); | |||||
| pbPreparePlugin(parent, "initVortexVelocity", !noTiming); | |||||
| PyObject *_retval = 0; | |||||
| { | |||||
| ArgLocker _lock; | |||||
| const Grid<Real> &phiObs = *_args.getPtr<Grid<Real>>("phiObs", 0, &_lock); | |||||
| MACGrid &vel = *_args.getPtr<MACGrid>("vel", 1, &_lock); | |||||
| const Vec3 ¢er = _args.get<Vec3>("center", 2, &_lock); | |||||
| const Real &radius = _args.get<Real>("radius", 3, &_lock); | |||||
| _retval = getPyNone(); | |||||
| initVortexVelocity(phiObs, vel, center, radius); | |||||
| _args.check(); | |||||
| } | |||||
| pbFinalizePlugin(parent, "initVortexVelocity", !noTiming); | |||||
| return _retval; | |||||
| } | |||||
| catch (std::exception &e) { | |||||
| pbSetError("initVortexVelocity", e.what()); | |||||
| return 0; | |||||
| } | |||||
| } | |||||
| static const Pb::Register _RP_initVortexVelocity("", "initVortexVelocity", _W_18); | |||||
| extern "C" { | |||||
| void PbRegister_initVortexVelocity() | |||||
| { | |||||
| KEEP_UNUSED(_RP_initVortexVelocity); | |||||
| } | |||||
| } | |||||
| //***************************************************************************** | |||||
| // helper functions for blurring | |||||
| //! class for Gaussian Blur | |||||
| struct GaussianKernelCreator { | |||||
| public: | |||||
| float mSigma; | |||||
| int mDim; | |||||
| float *mMat1D; | |||||
| GaussianKernelCreator() : mSigma(0.0f), mDim(0), mMat1D(NULL) | |||||
| { | |||||
| } | |||||
| GaussianKernelCreator(float sigma, int dim = 0) : mSigma(0.0f), mDim(0), mMat1D(NULL) | |||||
| { | |||||
| setGaussianSigma(sigma, dim); | |||||
| } | |||||
| Real getWeiAtDis(float disx, float disy) | |||||
| { | |||||
| float m = 1.0 / (sqrt(2.0 * M_PI) * mSigma); | |||||
| float v = m * exp(-(1.0 * disx * disx + 1.0 * disy * disy) / (2.0 * mSigma * mSigma)); | |||||
| return v; | |||||
| } | |||||
| Real getWeiAtDis(float disx, float disy, float disz) | |||||
| { | |||||
| float m = 1.0 / (sqrt(2.0 * M_PI) * mSigma); | |||||
| float v = m * exp(-(1.0 * disx * disx + 1.0 * disy * disy + 1.0 * disz * disz) / | |||||
| (2.0 * mSigma * mSigma)); | |||||
| return v; | |||||
| } | |||||
| void setGaussianSigma(float sigma, int dim = 0) | |||||
| { | |||||
| mSigma = sigma; | |||||
| if (dim < 3) | |||||
| mDim = (int)(2.0 * 3.0 * sigma + 1.0f); | |||||
| else | |||||
| mDim = dim; | |||||
| if (mDim < 3) | |||||
| mDim = 3; | |||||
| if (mDim % 2 == 0) | |||||
| ++mDim; // make dim odd | |||||
| float s2 = mSigma * mSigma; | |||||
| int c = mDim / 2; | |||||
| float m = 1.0 / (sqrt(2.0 * M_PI) * mSigma); | |||||
| // create 1D matrix | |||||
| if (mMat1D) | |||||
| delete[] mMat1D; | |||||
| mMat1D = new float[mDim]; | |||||
| for (int i = 0; i < (mDim + 1) / 2; i++) { | |||||
| float v = m * exp(-(1.0 * i * i) / (2.0 * s2)); | |||||
| mMat1D[c + i] = v; | |||||
| mMat1D[c - i] = v; | |||||
| } | |||||
| } | |||||
| ~GaussianKernelCreator() | |||||
| { | |||||
| if (mMat1D) | |||||
| delete[] mMat1D; | |||||
| } | |||||
| float get1DKernelValue(int off) | |||||
| { | |||||
| assertMsg(off >= 0 && off < mDim, "off exceeded boundary in Gaussian Kernel 1D!"); | |||||
| return mMat1D[off]; | |||||
| } | |||||
| }; | |||||
| template<class T> | |||||
| T convolveGrid(Grid<T> &originGrid, GaussianKernelCreator &gkSigma, Vec3 pos, int cdir) | |||||
| { | |||||
| // pos should be the centre pos, e.g., 1.5, 4.5, 0.5 for grid pos 1,4,0 | |||||
| Vec3 step(1.0, 0.0, 0.0); | |||||
| if (cdir == 1) // todo, z | |||||
| step = Vec3(0.0, 1.0, 0.0); | |||||
| else if (cdir == 2) | |||||
| step = Vec3(0.0, 0.0, 1.0); | |||||
| T pxResult(0); | |||||
| for (int i = 0; i < gkSigma.mDim; ++i) { | |||||
| Vec3i curpos = toVec3i(pos - step * (i - gkSigma.mDim / 2)); | |||||
| if (originGrid.isInBounds(curpos)) | |||||
| pxResult += gkSigma.get1DKernelValue(i) * originGrid.get(curpos); | |||||
| else { // TODO , improve... | |||||
| Vec3i curfitpos = curpos; | |||||
| if (curfitpos.x < 0) | |||||
| curfitpos.x = 0; | |||||
| else if (curfitpos.x >= originGrid.getSizeX()) | |||||
| curfitpos.x = originGrid.getSizeX() - 1; | |||||
| if (curfitpos.y < 0) | |||||
| curfitpos.y = 0; | |||||
| else if (curfitpos.y >= originGrid.getSizeY()) | |||||
| curfitpos.y = originGrid.getSizeY() - 1; | |||||
| if (curfitpos.z < 0) | |||||
| curfitpos.z = 0; | |||||
| else if (curfitpos.z >= originGrid.getSizeZ()) | |||||
| curfitpos.z = originGrid.getSizeZ() - 1; | |||||
| pxResult += gkSigma.get1DKernelValue(i) * originGrid.get(curfitpos); | |||||
| } | |||||
| } | |||||
| return pxResult; | |||||
| } | |||||
| template<class T> struct knBlurGrid : public KernelBase { | |||||
| knBlurGrid(Grid<T> &originGrid, Grid<T> &targetGrid, GaussianKernelCreator &gkSigma, int cdir) | |||||
| : KernelBase(&originGrid, 0), | |||||
| originGrid(originGrid), | |||||
| targetGrid(targetGrid), | |||||
| gkSigma(gkSigma), | |||||
| cdir(cdir) | |||||
| { | |||||
| runMessage(); | |||||
| run(); | |||||
| } | |||||
| inline void op(int i, | |||||
| int j, | |||||
| int k, | |||||
| Grid<T> &originGrid, | |||||
| Grid<T> &targetGrid, | |||||
| GaussianKernelCreator &gkSigma, | |||||
| int cdir) const | |||||
| { | |||||
| targetGrid(i, j, k) = convolveGrid<T>(originGrid, gkSigma, Vec3(i, j, k), cdir); | |||||
| } | |||||
| inline Grid<T> &getArg0() | |||||
| { | |||||
| return originGrid; | |||||
| } | |||||
| typedef Grid<T> type0; | |||||
| inline Grid<T> &getArg1() | |||||
| { | |||||
| return targetGrid; | |||||
| } | |||||
| typedef Grid<T> type1; | |||||
| inline GaussianKernelCreator &getArg2() | |||||
| { | |||||
| return gkSigma; | |||||
| } | |||||
| typedef GaussianKernelCreator type2; | |||||
| inline int &getArg3() | |||||
| { | |||||
| return cdir; | |||||
| } | |||||
| typedef int type3; | |||||
| void runMessage() | |||||
| { | |||||
| debMsg("Executing kernel knBlurGrid ", 3); | |||||
| debMsg("Kernel range" | |||||
| << " x " << maxX << " y " << maxY << " z " << minZ << " - " << maxZ << " ", | |||||
| 4); | |||||
| }; | |||||
| void operator()(const tbb::blocked_range<IndexInt> &__r) const | |||||
| { | |||||
| const int _maxX = maxX; | |||||
| const int _maxY = maxY; | |||||
| if (maxZ > 1) { | |||||
| for (int k = __r.begin(); k != (int)__r.end(); k++) | |||||
| for (int j = 0; j < _maxY; j++) | |||||
| for (int i = 0; i < _maxX; i++) | |||||
| op(i, j, k, originGrid, targetGrid, gkSigma, cdir); | |||||
| } | |||||
| else { | |||||
| const int k = 0; | |||||
| for (int j = __r.begin(); j != (int)__r.end(); j++) | |||||
| for (int i = 0; i < _maxX; i++) | |||||
| op(i, j, k, originGrid, targetGrid, gkSigma, cdir); | |||||
| } | |||||
| } | |||||
| void run() | |||||
| { | |||||
| if (maxZ > 1) | |||||
| tbb::parallel_for(tbb::blocked_range<IndexInt>(minZ, maxZ), *this); | |||||
| else | |||||
| tbb::parallel_for(tbb::blocked_range<IndexInt>(0, maxY), *this); | |||||
| } | |||||
| Grid<T> &originGrid; | |||||
| Grid<T> &targetGrid; | |||||
| GaussianKernelCreator &gkSigma; | |||||
| int cdir; | |||||
| }; | |||||
| template<class T> int blurGrid(Grid<T> &originGrid, Grid<T> &targetGrid, float sigma) | |||||
| { | |||||
| GaussianKernelCreator tmGK(sigma); | |||||
| Grid<T> tmpGrid(originGrid); | |||||
| knBlurGrid<T>(originGrid, tmpGrid, tmGK, 0); // blur x | |||||
| knBlurGrid<T>(tmpGrid, targetGrid, tmGK, 1); // blur y | |||||
| if (targetGrid.is3D()) { | |||||
| tmpGrid.copyFrom(targetGrid); | |||||
| knBlurGrid<T>(tmpGrid, targetGrid, tmGK, 2); | |||||
| } | |||||
| return tmGK.mDim; | |||||
| } | |||||
| struct KnBlurMACGridGauss : public KernelBase { | |||||
| KnBlurMACGridGauss(MACGrid &originGrid, | |||||
| MACGrid &target, | |||||
| GaussianKernelCreator &gkSigma, | |||||
| int cdir) | |||||
| : KernelBase(&originGrid, 0), | |||||
| originGrid(originGrid), | |||||
| target(target), | |||||
| gkSigma(gkSigma), | |||||
| cdir(cdir) | |||||
| { | |||||
| runMessage(); | |||||
| run(); | |||||
| } | |||||
| inline void op(int i, | |||||
| int j, | |||||
| int k, | |||||
| MACGrid &originGrid, | |||||
| MACGrid &target, | |||||
| GaussianKernelCreator &gkSigma, | |||||
| int cdir) const | |||||
| { | |||||
| Vec3 pos(i, j, k); | |||||
| Vec3 step(1.0, 0.0, 0.0); | |||||
| if (cdir == 1) | |||||
| step = Vec3(0.0, 1.0, 0.0); | |||||
| else if (cdir == 2) | |||||
| step = Vec3(0.0, 0.0, 1.0); | |||||
| Vec3 pxResult(0.0f); | |||||
| for (int di = 0; di < gkSigma.mDim; ++di) { | |||||
| Vec3i curpos = toVec3i(pos - step * (di - gkSigma.mDim / 2)); | |||||
| if (!originGrid.isInBounds(curpos)) { | |||||
| if (curpos.x < 0) | |||||
| curpos.x = 0; | |||||
| else if (curpos.x >= originGrid.getSizeX()) | |||||
| curpos.x = originGrid.getSizeX() - 1; | |||||
| if (curpos.y < 0) | |||||
| curpos.y = 0; | |||||
| else if (curpos.y >= originGrid.getSizeY()) | |||||
| curpos.y = originGrid.getSizeY() - 1; | |||||
| if (curpos.z < 0) | |||||
| curpos.z = 0; | |||||
| else if (curpos.z >= originGrid.getSizeZ()) | |||||
| curpos.z = originGrid.getSizeZ() - 1; | |||||
| } | |||||
| pxResult += gkSigma.get1DKernelValue(di) * originGrid.get(curpos); | |||||
| } | |||||
| target(i, j, k) = pxResult; | |||||
| } | |||||
| inline MACGrid &getArg0() | |||||
| { | |||||
| return originGrid; | |||||
| } | |||||
| typedef MACGrid type0; | |||||
| inline MACGrid &getArg1() | |||||
| { | |||||
| return target; | |||||
| } | |||||
| typedef MACGrid type1; | |||||
| inline GaussianKernelCreator &getArg2() | |||||
| { | |||||
| return gkSigma; | |||||
| } | |||||
| typedef GaussianKernelCreator type2; | |||||
| inline int &getArg3() | |||||
| { | |||||
| return cdir; | |||||
| } | |||||
| typedef int type3; | |||||
| void runMessage() | |||||
| { | |||||
| debMsg("Executing kernel KnBlurMACGridGauss ", 3); | |||||
| debMsg("Kernel range" | |||||
| << " x " << maxX << " y " << maxY << " z " << minZ << " - " << maxZ << " ", | |||||
| 4); | |||||
| }; | |||||
| void operator()(const tbb::blocked_range<IndexInt> &__r) const | |||||
| { | |||||
| const int _maxX = maxX; | |||||
| const int _maxY = maxY; | |||||
| if (maxZ > 1) { | |||||
| for (int k = __r.begin(); k != (int)__r.end(); k++) | |||||
| for (int j = 0; j < _maxY; j++) | |||||
| for (int i = 0; i < _maxX; i++) | |||||
| op(i, j, k, originGrid, target, gkSigma, cdir); | |||||
| } | |||||
| else { | |||||
| const int k = 0; | |||||
| for (int j = __r.begin(); j != (int)__r.end(); j++) | |||||
| for (int i = 0; i < _maxX; i++) | |||||
| op(i, j, k, originGrid, target, gkSigma, cdir); | |||||
| } | |||||
| } | |||||
| void run() | |||||
| { | |||||
| if (maxZ > 1) | |||||
| tbb::parallel_for(tbb::blocked_range<IndexInt>(minZ, maxZ), *this); | |||||
| else | |||||
| tbb::parallel_for(tbb::blocked_range<IndexInt>(0, maxY), *this); | |||||
| } | |||||
| MACGrid &originGrid; | |||||
| MACGrid ⌖ | |||||
| GaussianKernelCreator &gkSigma; | |||||
| int cdir; | |||||
| }; | |||||
| int blurMacGrid(MACGrid &oG, MACGrid &tG, float si) | |||||
| { | |||||
| GaussianKernelCreator tmGK(si); | |||||
| MACGrid tmpGrid(oG); | |||||
| KnBlurMACGridGauss(oG, tmpGrid, tmGK, 0); // blur x | |||||
| KnBlurMACGridGauss(tmpGrid, tG, tmGK, 1); // blur y | |||||
| if (tG.is3D()) { | |||||
| tmpGrid.copyFrom(tG); | |||||
| KnBlurMACGridGauss(tmpGrid, tG, tmGK, 2); | |||||
| } | |||||
| return tmGK.mDim; | |||||
| } | |||||
| static PyObject *_W_19(PyObject *_self, PyObject *_linargs, PyObject *_kwds) | |||||
| { | |||||
| try { | |||||
| PbArgs _args(_linargs, _kwds); | |||||
| FluidSolver *parent = _args.obtainParent(); | |||||
| bool noTiming = _args.getOpt<bool>("notiming", -1, 0); | |||||
| pbPreparePlugin(parent, "blurMacGrid", !noTiming); | |||||
| PyObject *_retval = 0; | |||||
| { | |||||
| ArgLocker _lock; | |||||
| MACGrid &oG = *_args.getPtr<MACGrid>("oG", 0, &_lock); | |||||
| MACGrid &tG = *_args.getPtr<MACGrid>("tG", 1, &_lock); | |||||
| float si = _args.get<float>("si", 2, &_lock); | |||||
| _retval = toPy(blurMacGrid(oG, tG, si)); | |||||
| _args.check(); | |||||
| } | |||||
| pbFinalizePlugin(parent, "blurMacGrid", !noTiming); | |||||
| return _retval; | |||||
| } | |||||
| catch (std::exception &e) { | |||||
| pbSetError("blurMacGrid", e.what()); | |||||
| return 0; | |||||
| } | |||||
| } | |||||
| static const Pb::Register _RP_blurMacGrid("", "blurMacGrid", _W_19); | |||||
| extern "C" { | |||||
| void PbRegister_blurMacGrid() | |||||
| { | |||||
| KEEP_UNUSED(_RP_blurMacGrid); | |||||
| } | |||||
| } | |||||
| int blurRealGrid(Grid<Real> &oG, Grid<Real> &tG, float si) | |||||
| { | |||||
| return blurGrid<Real>(oG, tG, si); | |||||
| } | |||||
| static PyObject *_W_20(PyObject *_self, PyObject *_linargs, PyObject *_kwds) | |||||
| { | |||||
| try { | |||||
| PbArgs _args(_linargs, _kwds); | |||||
| FluidSolver *parent = _args.obtainParent(); | |||||
| bool noTiming = _args.getOpt<bool>("notiming", -1, 0); | |||||
| pbPreparePlugin(parent, "blurRealGrid", !noTiming); | |||||
| PyObject *_retval = 0; | |||||
| { | |||||
| ArgLocker _lock; | |||||
| Grid<Real> &oG = *_args.getPtr<Grid<Real>>("oG", 0, &_lock); | |||||
| Grid<Real> &tG = *_args.getPtr<Grid<Real>>("tG", 1, &_lock); | |||||
| float si = _args.get<float>("si", 2, &_lock); | |||||
| _retval = toPy(blurRealGrid(oG, tG, si)); | |||||
| _args.check(); | |||||
| } | |||||
| pbFinalizePlugin(parent, "blurRealGrid", !noTiming); | |||||
| return _retval; | |||||
| } | |||||
| catch (std::exception &e) { | |||||
| pbSetError("blurRealGrid", e.what()); | |||||
| return 0; | |||||
| } | |||||
| } | |||||
| static const Pb::Register _RP_blurRealGrid("", "blurRealGrid", _W_20); | |||||
| extern "C" { | |||||
| void PbRegister_blurRealGrid() | |||||
| { | |||||
| KEEP_UNUSED(_RP_blurRealGrid); | |||||
| } | |||||
| } | |||||
| } // namespace Manta | |||||