Changeset View
Changeset View
Standalone View
Standalone View
extern/mantaflow/preprocessed/plugin/waveletturbulence.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 | |||||
| * | |||||
| * Functions for calculating wavelet turbulence, | |||||
| * plus helpers to compute vorticity, and strain rate magnitude | |||||
| * | |||||
| ******************************************************************************/ | |||||
| #include "vectorbase.h" | |||||
| #include "shapes.h" | |||||
| #include "commonkernels.h" | |||||
| #include "noisefield.h" | |||||
| using namespace std; | |||||
| namespace Manta { | |||||
| //***************************************************************************** | |||||
| // first some fairly generic interpolation functions for grids with multiple sizes | |||||
| //! same as in grid.h , but takes an additional optional "desired" size | |||||
| inline void calcGridSizeFactorMod( | |||||
| Vec3i s1, Vec3i s2, Vec3i optSize, Vec3 scale, Vec3 &sourceFactor, Vec3 &retOff) | |||||
| { | |||||
| for (int c = 0; c < 3; c++) { | |||||
| if (optSize[c] > 0) { | |||||
| s2[c] = optSize[c]; | |||||
| } | |||||
| } | |||||
| sourceFactor = calcGridSizeFactor(s1, s2) / scale; | |||||
| retOff = -retOff * sourceFactor + sourceFactor * 0.5; | |||||
| } | |||||
| void interpolateGrid(Grid<Real> &target, | |||||
| const Grid<Real> &source, | |||||
| Vec3 scale = Vec3(1.), | |||||
| Vec3 offset = Vec3(0.), | |||||
| Vec3i size = Vec3i(-1, -1, -1), | |||||
| int orderSpace = 1) | |||||
| { | |||||
| Vec3 sourceFactor(1.), off2 = offset; | |||||
| calcGridSizeFactorMod(source.getSize(), target.getSize(), size, scale, sourceFactor, off2); | |||||
| // a brief note on a mantaflow specialty: the target grid has to be the first argument here! | |||||
| // the parent fluidsolver object is taken from the first grid, and it determines the size of the | |||||
| // loop for the kernel call. as we're writing into target, it's important to loop exactly over | |||||
| // all cells of the target grid... (note, when calling the plugin in python, it doesnt matter | |||||
| // anymore). | |||||
| // sourceFactor offset necessary to shift eval points by half a small cell width | |||||
| knInterpolateGridTempl<Real>(target, source, sourceFactor, off2, orderSpace); | |||||
| } | |||||
| 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, "interpolateGrid", !noTiming); | |||||
| PyObject *_retval = 0; | |||||
| { | |||||
| ArgLocker _lock; | |||||
| Grid<Real> &target = *_args.getPtr<Grid<Real>>("target", 0, &_lock); | |||||
| const Grid<Real> &source = *_args.getPtr<Grid<Real>>("source", 1, &_lock); | |||||
| Vec3 scale = _args.getOpt<Vec3>("scale", 2, Vec3(1.), &_lock); | |||||
| Vec3 offset = _args.getOpt<Vec3>("offset", 3, Vec3(0.), &_lock); | |||||
| Vec3i size = _args.getOpt<Vec3i>("size", 4, Vec3i(-1, -1, -1), &_lock); | |||||
| int orderSpace = _args.getOpt<int>("orderSpace", 5, 1, &_lock); | |||||
| _retval = getPyNone(); | |||||
| interpolateGrid(target, source, scale, offset, size, orderSpace); | |||||
| _args.check(); | |||||
| } | |||||
| pbFinalizePlugin(parent, "interpolateGrid", !noTiming); | |||||
| return _retval; | |||||
| } | |||||
| catch (std::exception &e) { | |||||
| pbSetError("interpolateGrid", e.what()); | |||||
| return 0; | |||||
| } | |||||
| } | |||||
| static const Pb::Register _RP_interpolateGrid("", "interpolateGrid", _W_0); | |||||
| extern "C" { | |||||
| void PbRegister_interpolateGrid() | |||||
| { | |||||
| KEEP_UNUSED(_RP_interpolateGrid); | |||||
| } | |||||
| } | |||||
| void interpolateGridVec3(Grid<Vec3> &target, | |||||
| const Grid<Vec3> &source, | |||||
| Vec3 scale = Vec3(1.), | |||||
| Vec3 offset = Vec3(0.), | |||||
| Vec3i size = Vec3i(-1, -1, -1), | |||||
| int orderSpace = 1) | |||||
| { | |||||
| Vec3 sourceFactor(1.), off2 = offset; | |||||
| calcGridSizeFactorMod(source.getSize(), target.getSize(), size, scale, sourceFactor, off2); | |||||
| knInterpolateGridTempl<Vec3>(target, source, sourceFactor, off2, orderSpace); | |||||
| } | |||||
| 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, "interpolateGridVec3", !noTiming); | |||||
| PyObject *_retval = 0; | |||||
| { | |||||
| ArgLocker _lock; | |||||
| Grid<Vec3> &target = *_args.getPtr<Grid<Vec3>>("target", 0, &_lock); | |||||
| const Grid<Vec3> &source = *_args.getPtr<Grid<Vec3>>("source", 1, &_lock); | |||||
| Vec3 scale = _args.getOpt<Vec3>("scale", 2, Vec3(1.), &_lock); | |||||
| Vec3 offset = _args.getOpt<Vec3>("offset", 3, Vec3(0.), &_lock); | |||||
| Vec3i size = _args.getOpt<Vec3i>("size", 4, Vec3i(-1, -1, -1), &_lock); | |||||
| int orderSpace = _args.getOpt<int>("orderSpace", 5, 1, &_lock); | |||||
| _retval = getPyNone(); | |||||
| interpolateGridVec3(target, source, scale, offset, size, orderSpace); | |||||
| _args.check(); | |||||
| } | |||||
| pbFinalizePlugin(parent, "interpolateGridVec3", !noTiming); | |||||
| return _retval; | |||||
| } | |||||
| catch (std::exception &e) { | |||||
| pbSetError("interpolateGridVec3", e.what()); | |||||
| return 0; | |||||
| } | |||||
| } | |||||
| static const Pb::Register _RP_interpolateGridVec3("", "interpolateGridVec3", _W_1); | |||||
| extern "C" { | |||||
| void PbRegister_interpolateGridVec3() | |||||
| { | |||||
| KEEP_UNUSED(_RP_interpolateGridVec3); | |||||
| } | |||||
| } | |||||
| //! interpolate a mac velocity grid from one size to another size | |||||
| struct KnInterpolateMACGrid : public KernelBase { | |||||
| KnInterpolateMACGrid(MACGrid &target, | |||||
| const MACGrid &source, | |||||
| const Vec3 &sourceFactor, | |||||
| const Vec3 &off, | |||||
| int orderSpace) | |||||
| : KernelBase(&target, 0), | |||||
| target(target), | |||||
| source(source), | |||||
| sourceFactor(sourceFactor), | |||||
| off(off), | |||||
| orderSpace(orderSpace) | |||||
| { | |||||
| runMessage(); | |||||
| run(); | |||||
| } | |||||
| inline void op(int i, | |||||
| int j, | |||||
| int k, | |||||
| MACGrid &target, | |||||
| const MACGrid &source, | |||||
| const Vec3 &sourceFactor, | |||||
| const Vec3 &off, | |||||
| int orderSpace) const | |||||
| { | |||||
| Vec3 pos = Vec3(i, j, k) * sourceFactor + off; | |||||
| Real vx = source.getInterpolatedHi(pos - Vec3(0.5, 0, 0), orderSpace)[0]; | |||||
| Real vy = source.getInterpolatedHi(pos - Vec3(0, 0.5, 0), orderSpace)[1]; | |||||
| Real vz = 0.f; | |||||
| if (source.is3D()) | |||||
| vz = source.getInterpolatedHi(pos - Vec3(0, 0, 0.5), orderSpace)[2]; | |||||
| target(i, j, k) = Vec3(vx, vy, vz); | |||||
| } | |||||
| inline MACGrid &getArg0() | |||||
| { | |||||
| return target; | |||||
| } | |||||
| typedef MACGrid type0; | |||||
| inline const MACGrid &getArg1() | |||||
| { | |||||
| return source; | |||||
| } | |||||
| typedef MACGrid type1; | |||||
| inline const Vec3 &getArg2() | |||||
| { | |||||
| return sourceFactor; | |||||
| } | |||||
| typedef Vec3 type2; | |||||
| inline const Vec3 &getArg3() | |||||
| { | |||||
| return off; | |||||
| } | |||||
| typedef Vec3 type3; | |||||
| inline int &getArg4() | |||||
| { | |||||
| return orderSpace; | |||||
| } | |||||
| typedef int type4; | |||||
| void runMessage() | |||||
| { | |||||
| debMsg("Executing kernel KnInterpolateMACGrid ", 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, target, source, sourceFactor, off, orderSpace); | |||||
| } | |||||
| 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, target, source, sourceFactor, off, orderSpace); | |||||
| } | |||||
| } | |||||
| 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 ⌖ | |||||
| const MACGrid &source; | |||||
| const Vec3 &sourceFactor; | |||||
| const Vec3 &off; | |||||
| int orderSpace; | |||||
| }; | |||||
| void interpolateMACGrid(MACGrid &target, | |||||
| const MACGrid &source, | |||||
| Vec3 scale = Vec3(1.), | |||||
| Vec3 offset = Vec3(0.), | |||||
| Vec3i size = Vec3i(-1, -1, -1), | |||||
| int orderSpace = 1) | |||||
| { | |||||
| Vec3 sourceFactor(1.), off2 = offset; | |||||
| calcGridSizeFactorMod(source.getSize(), target.getSize(), size, scale, sourceFactor, off2); | |||||
| KnInterpolateMACGrid(target, source, sourceFactor, off2, orderSpace); | |||||
| } | |||||
| 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, "interpolateMACGrid", !noTiming); | |||||
| PyObject *_retval = 0; | |||||
| { | |||||
| ArgLocker _lock; | |||||
| MACGrid &target = *_args.getPtr<MACGrid>("target", 0, &_lock); | |||||
| const MACGrid &source = *_args.getPtr<MACGrid>("source", 1, &_lock); | |||||
| Vec3 scale = _args.getOpt<Vec3>("scale", 2, Vec3(1.), &_lock); | |||||
| Vec3 offset = _args.getOpt<Vec3>("offset", 3, Vec3(0.), &_lock); | |||||
| Vec3i size = _args.getOpt<Vec3i>("size", 4, Vec3i(-1, -1, -1), &_lock); | |||||
| int orderSpace = _args.getOpt<int>("orderSpace", 5, 1, &_lock); | |||||
| _retval = getPyNone(); | |||||
| interpolateMACGrid(target, source, scale, offset, size, orderSpace); | |||||
| _args.check(); | |||||
| } | |||||
| pbFinalizePlugin(parent, "interpolateMACGrid", !noTiming); | |||||
| return _retval; | |||||
| } | |||||
| catch (std::exception &e) { | |||||
| pbSetError("interpolateMACGrid", e.what()); | |||||
| return 0; | |||||
| } | |||||
| } | |||||
| static const Pb::Register _RP_interpolateMACGrid("", "interpolateMACGrid", _W_2); | |||||
| extern "C" { | |||||
| void PbRegister_interpolateMACGrid() | |||||
| { | |||||
| KEEP_UNUSED(_RP_interpolateMACGrid); | |||||
| } | |||||
| } | |||||
| //***************************************************************************** | |||||
| //! Apply vector noise to grid, this is a simplified version - no position scaling or UVs | |||||
| struct knApplySimpleNoiseVec3 : public KernelBase { | |||||
| knApplySimpleNoiseVec3(const FlagGrid &flags, | |||||
| Grid<Vec3> &target, | |||||
| const WaveletNoiseField &noise, | |||||
| Real scale, | |||||
| const Grid<Real> *weight) | |||||
| : KernelBase(&flags, 0), | |||||
| flags(flags), | |||||
| target(target), | |||||
| noise(noise), | |||||
| scale(scale), | |||||
| weight(weight) | |||||
| { | |||||
| runMessage(); | |||||
| run(); | |||||
| } | |||||
| inline void op(int i, | |||||
| int j, | |||||
| int k, | |||||
| const FlagGrid &flags, | |||||
| Grid<Vec3> &target, | |||||
| const WaveletNoiseField &noise, | |||||
| Real scale, | |||||
| const Grid<Real> *weight) const | |||||
| { | |||||
| if (!flags.isFluid(i, j, k)) | |||||
| return; | |||||
| Real factor = 1; | |||||
| if (weight) | |||||
| factor = (*weight)(i, j, k); | |||||
| target(i, j, k) += noise.evaluateCurl(Vec3(i, j, k) + Vec3(0.5)) * scale * factor; | |||||
| } | |||||
| inline const FlagGrid &getArg0() | |||||
| { | |||||
| return flags; | |||||
| } | |||||
| typedef FlagGrid type0; | |||||
| inline Grid<Vec3> &getArg1() | |||||
| { | |||||
| return target; | |||||
| } | |||||
| typedef Grid<Vec3> type1; | |||||
| inline const WaveletNoiseField &getArg2() | |||||
| { | |||||
| return noise; | |||||
| } | |||||
| typedef WaveletNoiseField type2; | |||||
| inline Real &getArg3() | |||||
| { | |||||
| return scale; | |||||
| } | |||||
| typedef Real type3; | |||||
| inline const Grid<Real> *getArg4() | |||||
| { | |||||
| return weight; | |||||
| } | |||||
| typedef Grid<Real> type4; | |||||
| void runMessage() | |||||
| { | |||||
| debMsg("Executing kernel knApplySimpleNoiseVec3 ", 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, noise, scale, weight); | |||||
| } | |||||
| 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, noise, scale, weight); | |||||
| } | |||||
| } | |||||
| 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<Vec3> ⌖ | |||||
| const WaveletNoiseField &noise; | |||||
| Real scale; | |||||
| const Grid<Real> *weight; | |||||
| }; | |||||
| void applySimpleNoiseVec3(const FlagGrid &flags, | |||||
| Grid<Vec3> &target, | |||||
| const WaveletNoiseField &noise, | |||||
| Real scale = 1.0, | |||||
| const Grid<Real> *weight = NULL) | |||||
| { | |||||
| // note - passing a MAC grid here is slightly inaccurate, we should evaluate each component | |||||
| // separately | |||||
| knApplySimpleNoiseVec3(flags, target, noise, scale, weight); | |||||
| } | |||||
| 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, "applySimpleNoiseVec3", !noTiming); | |||||
| PyObject *_retval = 0; | |||||
| { | |||||
| ArgLocker _lock; | |||||
| const FlagGrid &flags = *_args.getPtr<FlagGrid>("flags", 0, &_lock); | |||||
| Grid<Vec3> &target = *_args.getPtr<Grid<Vec3>>("target", 1, &_lock); | |||||
| const WaveletNoiseField &noise = *_args.getPtr<WaveletNoiseField>("noise", 2, &_lock); | |||||
| Real scale = _args.getOpt<Real>("scale", 3, 1.0, &_lock); | |||||
| const Grid<Real> *weight = _args.getPtrOpt<Grid<Real>>("weight", 4, NULL, &_lock); | |||||
| _retval = getPyNone(); | |||||
| applySimpleNoiseVec3(flags, target, noise, scale, weight); | |||||
| _args.check(); | |||||
| } | |||||
| pbFinalizePlugin(parent, "applySimpleNoiseVec3", !noTiming); | |||||
| return _retval; | |||||
| } | |||||
| catch (std::exception &e) { | |||||
| pbSetError("applySimpleNoiseVec3", e.what()); | |||||
| return 0; | |||||
| } | |||||
| } | |||||
| static const Pb::Register _RP_applySimpleNoiseVec3("", "applySimpleNoiseVec3", _W_3); | |||||
| extern "C" { | |||||
| void PbRegister_applySimpleNoiseVec3() | |||||
| { | |||||
| KEEP_UNUSED(_RP_applySimpleNoiseVec3); | |||||
| } | |||||
| } | |||||
| //! Simple noise for a real grid , follows applySimpleNoiseVec3 | |||||
| struct knApplySimpleNoiseReal : public KernelBase { | |||||
| knApplySimpleNoiseReal(const FlagGrid &flags, | |||||
| Grid<Real> &target, | |||||
| const WaveletNoiseField &noise, | |||||
| Real scale, | |||||
| const Grid<Real> *weight) | |||||
| : KernelBase(&flags, 0), | |||||
| flags(flags), | |||||
| target(target), | |||||
| noise(noise), | |||||
| scale(scale), | |||||
| weight(weight) | |||||
| { | |||||
| runMessage(); | |||||
| run(); | |||||
| } | |||||
| inline void op(int i, | |||||
| int j, | |||||
| int k, | |||||
| const FlagGrid &flags, | |||||
| Grid<Real> &target, | |||||
| const WaveletNoiseField &noise, | |||||
| Real scale, | |||||
| const Grid<Real> *weight) const | |||||
| { | |||||
| if (!flags.isFluid(i, j, k)) | |||||
| return; | |||||
| Real factor = 1; | |||||
| if (weight) | |||||
| factor = (*weight)(i, j, k); | |||||
| target(i, j, k) += noise.evaluate(Vec3(i, j, k) + Vec3(0.5)) * scale * factor; | |||||
| } | |||||
| inline const FlagGrid &getArg0() | |||||
| { | |||||
| return flags; | |||||
| } | |||||
| typedef FlagGrid type0; | |||||
| inline Grid<Real> &getArg1() | |||||
| { | |||||
| return target; | |||||
| } | |||||
| typedef Grid<Real> type1; | |||||
| inline const WaveletNoiseField &getArg2() | |||||
| { | |||||
| return noise; | |||||
| } | |||||
| typedef WaveletNoiseField type2; | |||||
| inline Real &getArg3() | |||||
| { | |||||
| return scale; | |||||
| } | |||||
| typedef Real type3; | |||||
| inline const Grid<Real> *getArg4() | |||||
| { | |||||
| return weight; | |||||
| } | |||||
| typedef Grid<Real> type4; | |||||
| void runMessage() | |||||
| { | |||||
| debMsg("Executing kernel knApplySimpleNoiseReal ", 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, noise, scale, weight); | |||||
| } | |||||
| 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, noise, scale, weight); | |||||
| } | |||||
| } | |||||
| 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 WaveletNoiseField &noise; | |||||
| Real scale; | |||||
| const Grid<Real> *weight; | |||||
| }; | |||||
| void applySimpleNoiseReal(const FlagGrid &flags, | |||||
| Grid<Real> &target, | |||||
| const WaveletNoiseField &noise, | |||||
| Real scale = 1.0, | |||||
| const Grid<Real> *weight = NULL) | |||||
| { | |||||
| knApplySimpleNoiseReal(flags, target, noise, scale, weight); | |||||
| } | |||||
| 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, "applySimpleNoiseReal", !noTiming); | |||||
| PyObject *_retval = 0; | |||||
| { | |||||
| ArgLocker _lock; | |||||
| const FlagGrid &flags = *_args.getPtr<FlagGrid>("flags", 0, &_lock); | |||||
| Grid<Real> &target = *_args.getPtr<Grid<Real>>("target", 1, &_lock); | |||||
| const WaveletNoiseField &noise = *_args.getPtr<WaveletNoiseField>("noise", 2, &_lock); | |||||
| Real scale = _args.getOpt<Real>("scale", 3, 1.0, &_lock); | |||||
| const Grid<Real> *weight = _args.getPtrOpt<Grid<Real>>("weight", 4, NULL, &_lock); | |||||
| _retval = getPyNone(); | |||||
| applySimpleNoiseReal(flags, target, noise, scale, weight); | |||||
| _args.check(); | |||||
| } | |||||
| pbFinalizePlugin(parent, "applySimpleNoiseReal", !noTiming); | |||||
| return _retval; | |||||
| } | |||||
| catch (std::exception &e) { | |||||
| pbSetError("applySimpleNoiseReal", e.what()); | |||||
| return 0; | |||||
| } | |||||
| } | |||||
| static const Pb::Register _RP_applySimpleNoiseReal("", "applySimpleNoiseReal", _W_4); | |||||
| extern "C" { | |||||
| void PbRegister_applySimpleNoiseReal() | |||||
| { | |||||
| KEEP_UNUSED(_RP_applySimpleNoiseReal); | |||||
| } | |||||
| } | |||||
| //! Apply vector-based wavelet noise to target grid | |||||
| //! This is the version with more functionality - supports uv grids, and on-the-fly interpolation | |||||
| //! of input grids. | |||||
| struct knApplyNoiseVec3 : public KernelBase { | |||||
| knApplyNoiseVec3(const FlagGrid &flags, | |||||
| Grid<Vec3> &target, | |||||
| const WaveletNoiseField &noise, | |||||
| Real scale, | |||||
| Real scaleSpatial, | |||||
| const Grid<Real> *weight, | |||||
| const Grid<Vec3> *uv, | |||||
| bool uvInterpol, | |||||
| const Vec3 &sourceFactor) | |||||
| : KernelBase(&flags, 0), | |||||
| flags(flags), | |||||
| target(target), | |||||
| noise(noise), | |||||
| scale(scale), | |||||
| scaleSpatial(scaleSpatial), | |||||
| weight(weight), | |||||
| uv(uv), | |||||
| uvInterpol(uvInterpol), | |||||
| sourceFactor(sourceFactor) | |||||
| { | |||||
| runMessage(); | |||||
| run(); | |||||
| } | |||||
| inline void op(int i, | |||||
| int j, | |||||
| int k, | |||||
| const FlagGrid &flags, | |||||
| Grid<Vec3> &target, | |||||
| const WaveletNoiseField &noise, | |||||
| Real scale, | |||||
| Real scaleSpatial, | |||||
| const Grid<Real> *weight, | |||||
| const Grid<Vec3> *uv, | |||||
| bool uvInterpol, | |||||
| const Vec3 &sourceFactor) const | |||||
| { | |||||
| if (!flags.isFluid(i, j, k)) | |||||
| return; | |||||
| // get weighting, interpolate if necessary | |||||
| Real w = 1; | |||||
| if (weight) { | |||||
| if (!uvInterpol) { | |||||
| w = (*weight)(i, j, k); | |||||
| } | |||||
| else { | |||||
| w = weight->getInterpolated(Vec3(i, j, k) * sourceFactor); | |||||
| } | |||||
| } | |||||
| // compute position where to evaluate the noise | |||||
| Vec3 pos = Vec3(i, j, k) + Vec3(0.5); | |||||
| if (uv) { | |||||
| if (!uvInterpol) { | |||||
| pos = (*uv)(i, j, k); | |||||
| } | |||||
| else { | |||||
| pos = uv->getInterpolated(Vec3(i, j, k) * sourceFactor); | |||||
| // uv coordinates are in local space - so we need to adjust the values of the positions | |||||
| pos /= sourceFactor; | |||||
| } | |||||
| } | |||||
| pos *= scaleSpatial; | |||||
| Vec3 noiseVec3 = noise.evaluateCurl(pos) * scale * w; | |||||
| // noiseVec3=pos; // debug , show interpolated positions | |||||
| target(i, j, k) += noiseVec3; | |||||
| } | |||||
| inline const FlagGrid &getArg0() | |||||
| { | |||||
| return flags; | |||||
| } | |||||
| typedef FlagGrid type0; | |||||
| inline Grid<Vec3> &getArg1() | |||||
| { | |||||
| return target; | |||||
| } | |||||
| typedef Grid<Vec3> type1; | |||||
| inline const WaveletNoiseField &getArg2() | |||||
| { | |||||
| return noise; | |||||
| } | |||||
| typedef WaveletNoiseField type2; | |||||
| inline Real &getArg3() | |||||
| { | |||||
| return scale; | |||||
| } | |||||
| typedef Real type3; | |||||
| inline Real &getArg4() | |||||
| { | |||||
| return scaleSpatial; | |||||
| } | |||||
| typedef Real type4; | |||||
| inline const Grid<Real> *getArg5() | |||||
| { | |||||
| return weight; | |||||
| } | |||||
| typedef Grid<Real> type5; | |||||
| inline const Grid<Vec3> *getArg6() | |||||
| { | |||||
| return uv; | |||||
| } | |||||
| typedef Grid<Vec3> type6; | |||||
| inline bool &getArg7() | |||||
| { | |||||
| return uvInterpol; | |||||
| } | |||||
| typedef bool type7; | |||||
| inline const Vec3 &getArg8() | |||||
| { | |||||
| return sourceFactor; | |||||
| } | |||||
| typedef Vec3 type8; | |||||
| void runMessage() | |||||
| { | |||||
| debMsg("Executing kernel knApplyNoiseVec3 ", 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, | |||||
| noise, | |||||
| scale, | |||||
| scaleSpatial, | |||||
| weight, | |||||
| uv, | |||||
| uvInterpol, | |||||
| sourceFactor); | |||||
| } | |||||
| 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, | |||||
| noise, | |||||
| scale, | |||||
| scaleSpatial, | |||||
| weight, | |||||
| uv, | |||||
| uvInterpol, | |||||
| sourceFactor); | |||||
| } | |||||
| } | |||||
| 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<Vec3> ⌖ | |||||
| const WaveletNoiseField &noise; | |||||
| Real scale; | |||||
| Real scaleSpatial; | |||||
| const Grid<Real> *weight; | |||||
| const Grid<Vec3> *uv; | |||||
| bool uvInterpol; | |||||
| const Vec3 &sourceFactor; | |||||
| }; | |||||
| void applyNoiseVec3(const FlagGrid &flags, | |||||
| Grid<Vec3> &target, | |||||
| const WaveletNoiseField &noise, | |||||
| Real scale = 1.0, | |||||
| Real scaleSpatial = 1.0, | |||||
| const Grid<Real> *weight = NULL, | |||||
| const Grid<Vec3> *uv = NULL) | |||||
| { | |||||
| // check whether the uv grid has a different resolution | |||||
| bool uvInterpol = false; | |||||
| // and pre-compute conversion (only used if uvInterpol==true) | |||||
| // used for both uv and weight grid... | |||||
| Vec3 sourceFactor = Vec3(1.); | |||||
| if (uv) { | |||||
| uvInterpol = (target.getSize() != uv->getSize()); | |||||
| sourceFactor = calcGridSizeFactor(uv->getSize(), target.getSize()); | |||||
| } | |||||
| else if (weight) { | |||||
| uvInterpol = (target.getSize() != weight->getSize()); | |||||
| sourceFactor = calcGridSizeFactor(weight->getSize(), target.getSize()); | |||||
| } | |||||
| if (uv && weight) | |||||
| assertMsg(uv->getSize() == weight->getSize(), "UV and weight grid have to match!"); | |||||
| // note - passing a MAC grid here is slightly inaccurate, we should evaluate each component | |||||
| // separately | |||||
| knApplyNoiseVec3( | |||||
| flags, target, noise, scale, scaleSpatial, weight, uv, uvInterpol, sourceFactor); | |||||
| } | |||||
| 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, "applyNoiseVec3", !noTiming); | |||||
| PyObject *_retval = 0; | |||||
| { | |||||
| ArgLocker _lock; | |||||
| const FlagGrid &flags = *_args.getPtr<FlagGrid>("flags", 0, &_lock); | |||||
| Grid<Vec3> &target = *_args.getPtr<Grid<Vec3>>("target", 1, &_lock); | |||||
| const WaveletNoiseField &noise = *_args.getPtr<WaveletNoiseField>("noise", 2, &_lock); | |||||
| Real scale = _args.getOpt<Real>("scale", 3, 1.0, &_lock); | |||||
| Real scaleSpatial = _args.getOpt<Real>("scaleSpatial", 4, 1.0, &_lock); | |||||
| const Grid<Real> *weight = _args.getPtrOpt<Grid<Real>>("weight", 5, NULL, &_lock); | |||||
| const Grid<Vec3> *uv = _args.getPtrOpt<Grid<Vec3>>("uv", 6, NULL, &_lock); | |||||
| _retval = getPyNone(); | |||||
| applyNoiseVec3(flags, target, noise, scale, scaleSpatial, weight, uv); | |||||
| _args.check(); | |||||
| } | |||||
| pbFinalizePlugin(parent, "applyNoiseVec3", !noTiming); | |||||
| return _retval; | |||||
| } | |||||
| catch (std::exception &e) { | |||||
| pbSetError("applyNoiseVec3", e.what()); | |||||
| return 0; | |||||
| } | |||||
| } | |||||
| static const Pb::Register _RP_applyNoiseVec3("", "applyNoiseVec3", _W_5); | |||||
| extern "C" { | |||||
| void PbRegister_applyNoiseVec3() | |||||
| { | |||||
| KEEP_UNUSED(_RP_applyNoiseVec3); | |||||
| } | |||||
| } | |||||
| //! Compute energy of a staggered velocity field (at cell center) | |||||
| struct KnApplyComputeEnergy : public KernelBase { | |||||
| KnApplyComputeEnergy(const FlagGrid &flags, const MACGrid &vel, Grid<Real> &energy) | |||||
| : KernelBase(&flags, 0), flags(flags), vel(vel), energy(energy) | |||||
| { | |||||
| runMessage(); | |||||
| run(); | |||||
| } | |||||
| inline void op( | |||||
| int i, int j, int k, const FlagGrid &flags, const MACGrid &vel, Grid<Real> &energy) const | |||||
| { | |||||
| Real e = 0.f; | |||||
| if (flags.isFluid(i, j, k)) { | |||||
| Vec3 v = vel.getCentered(i, j, k); | |||||
| e = 0.5 * (v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); | |||||
| } | |||||
| energy(i, j, k) = e; | |||||
| } | |||||
| inline const FlagGrid &getArg0() | |||||
| { | |||||
| return flags; | |||||
| } | |||||
| typedef FlagGrid type0; | |||||
| inline const MACGrid &getArg1() | |||||
| { | |||||
| return vel; | |||||
| } | |||||
| typedef MACGrid type1; | |||||
| inline Grid<Real> &getArg2() | |||||
| { | |||||
| return energy; | |||||
| } | |||||
| typedef Grid<Real> type2; | |||||
| void runMessage() | |||||
| { | |||||
| debMsg("Executing kernel KnApplyComputeEnergy ", 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, vel, energy); | |||||
| } | |||||
| 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, vel, energy); | |||||
| } | |||||
| } | |||||
| 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; | |||||
| const MACGrid &vel; | |||||
| Grid<Real> &energy; | |||||
| }; | |||||
| void computeEnergy(const FlagGrid &flags, const MACGrid &vel, Grid<Real> &energy) | |||||
| { | |||||
| KnApplyComputeEnergy(flags, vel, energy); | |||||
| } | |||||
| 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, "computeEnergy", !noTiming); | |||||
| PyObject *_retval = 0; | |||||
| { | |||||
| ArgLocker _lock; | |||||
| const FlagGrid &flags = *_args.getPtr<FlagGrid>("flags", 0, &_lock); | |||||
| const MACGrid &vel = *_args.getPtr<MACGrid>("vel", 1, &_lock); | |||||
| Grid<Real> &energy = *_args.getPtr<Grid<Real>>("energy", 2, &_lock); | |||||
| _retval = getPyNone(); | |||||
| computeEnergy(flags, vel, energy); | |||||
| _args.check(); | |||||
| } | |||||
| pbFinalizePlugin(parent, "computeEnergy", !noTiming); | |||||
| return _retval; | |||||
| } | |||||
| catch (std::exception &e) { | |||||
| pbSetError("computeEnergy", e.what()); | |||||
| return 0; | |||||
| } | |||||
| } | |||||
| static const Pb::Register _RP_computeEnergy("", "computeEnergy", _W_6); | |||||
| extern "C" { | |||||
| void PbRegister_computeEnergy() | |||||
| { | |||||
| KEEP_UNUSED(_RP_computeEnergy); | |||||
| } | |||||
| } | |||||
| void computeWaveletCoeffs(Grid<Real> &input) | |||||
| { | |||||
| Grid<Real> temp1(input.getParent()), temp2(input.getParent()); | |||||
| WaveletNoiseField::computeCoefficients(input, temp1, temp2); | |||||
| } | |||||
| 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, "computeWaveletCoeffs", !noTiming); | |||||
| PyObject *_retval = 0; | |||||
| { | |||||
| ArgLocker _lock; | |||||
| Grid<Real> &input = *_args.getPtr<Grid<Real>>("input", 0, &_lock); | |||||
| _retval = getPyNone(); | |||||
| computeWaveletCoeffs(input); | |||||
| _args.check(); | |||||
| } | |||||
| pbFinalizePlugin(parent, "computeWaveletCoeffs", !noTiming); | |||||
| return _retval; | |||||
| } | |||||
| catch (std::exception &e) { | |||||
| pbSetError("computeWaveletCoeffs", e.what()); | |||||
| return 0; | |||||
| } | |||||
| } | |||||
| static const Pb::Register _RP_computeWaveletCoeffs("", "computeWaveletCoeffs", _W_7); | |||||
| extern "C" { | |||||
| void PbRegister_computeWaveletCoeffs() | |||||
| { | |||||
| KEEP_UNUSED(_RP_computeWaveletCoeffs); | |||||
| } | |||||
| } | |||||
| // note - alomst the same as for vorticity confinement | |||||
| void computeVorticity(const MACGrid &vel, Grid<Vec3> &vorticity, Grid<Real> *norm = NULL) | |||||
| { | |||||
| Grid<Vec3> velCenter(vel.getParent()); | |||||
| GetCentered(velCenter, vel); | |||||
| CurlOp(velCenter, vorticity); | |||||
| if (norm) | |||||
| GridNorm(*norm, vorticity); | |||||
| } | |||||
| 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, "computeVorticity", !noTiming); | |||||
| PyObject *_retval = 0; | |||||
| { | |||||
| ArgLocker _lock; | |||||
| const MACGrid &vel = *_args.getPtr<MACGrid>("vel", 0, &_lock); | |||||
| Grid<Vec3> &vorticity = *_args.getPtr<Grid<Vec3>>("vorticity", 1, &_lock); | |||||
| Grid<Real> *norm = _args.getPtrOpt<Grid<Real>>("norm", 2, NULL, &_lock); | |||||
| _retval = getPyNone(); | |||||
| computeVorticity(vel, vorticity, norm); | |||||
| _args.check(); | |||||
| } | |||||
| pbFinalizePlugin(parent, "computeVorticity", !noTiming); | |||||
| return _retval; | |||||
| } | |||||
| catch (std::exception &e) { | |||||
| pbSetError("computeVorticity", e.what()); | |||||
| return 0; | |||||
| } | |||||
| } | |||||
| static const Pb::Register _RP_computeVorticity("", "computeVorticity", _W_8); | |||||
| extern "C" { | |||||
| void PbRegister_computeVorticity() | |||||
| { | |||||
| KEEP_UNUSED(_RP_computeVorticity); | |||||
| } | |||||
| } | |||||
| // note - very similar to KnComputeProductionStrain, but for use as wavelet turb weighting | |||||
| struct KnComputeStrainRateMag : public KernelBase { | |||||
| KnComputeStrainRateMag(const MACGrid &vel, const Grid<Vec3> &velCenter, Grid<Real> &prod) | |||||
| : KernelBase(&vel, 1), vel(vel), velCenter(velCenter), prod(prod) | |||||
| { | |||||
| runMessage(); | |||||
| run(); | |||||
| } | |||||
| inline void op( | |||||
| int i, int j, int k, const MACGrid &vel, const Grid<Vec3> &velCenter, Grid<Real> &prod) const | |||||
| { | |||||
| // compute Sij = 1/2 * (dU_i/dx_j + dU_j/dx_i) | |||||
| Vec3 diag = Vec3(vel(i + 1, j, k).x, vel(i, j + 1, k).y, 0.) - vel(i, j, k); | |||||
| if (vel.is3D()) | |||||
| diag[2] += vel(i, j, k + 1).z; | |||||
| else | |||||
| diag[2] = 0.; | |||||
| Vec3 ux = 0.5 * (velCenter(i + 1, j, k) - velCenter(i - 1, j, k)); | |||||
| Vec3 uy = 0.5 * (velCenter(i, j + 1, k) - velCenter(i, j - 1, k)); | |||||
| Vec3 uz; | |||||
| if (vel.is3D()) | |||||
| uz = 0.5 * (velCenter(i, j, k + 1) - velCenter(i, j, k - 1)); | |||||
| Real S12 = 0.5 * (ux.y + uy.x); | |||||
| Real S13 = 0.5 * (ux.z + uz.x); | |||||
| Real S23 = 0.5 * (uy.z + uz.y); | |||||
| Real S2 = square(diag.x) + square(diag.y) + square(diag.z) + 2.0 * square(S12) + | |||||
| 2.0 * square(S13) + 2.0 * square(S23); | |||||
| prod(i, j, k) = S2; | |||||
| } | |||||
| inline const MACGrid &getArg0() | |||||
| { | |||||
| return vel; | |||||
| } | |||||
| typedef MACGrid type0; | |||||
| inline const Grid<Vec3> &getArg1() | |||||
| { | |||||
| return velCenter; | |||||
| } | |||||
| typedef Grid<Vec3> type1; | |||||
| inline Grid<Real> &getArg2() | |||||
| { | |||||
| return prod; | |||||
| } | |||||
| typedef Grid<Real> type2; | |||||
| void runMessage() | |||||
| { | |||||
| debMsg("Executing kernel KnComputeStrainRateMag ", 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, vel, velCenter, prod); | |||||
| } | |||||
| 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, vel, velCenter, prod); | |||||
| } | |||||
| } | |||||
| 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 MACGrid &vel; | |||||
| const Grid<Vec3> &velCenter; | |||||
| Grid<Real> ∏ | |||||
| }; | |||||
| void computeStrainRateMag(const MACGrid &vel, Grid<Real> &mag) | |||||
| { | |||||
| Grid<Vec3> velCenter(vel.getParent()); | |||||
| GetCentered(velCenter, vel); | |||||
| KnComputeStrainRateMag(vel, velCenter, mag); | |||||
| } | |||||
| 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, "computeStrainRateMag", !noTiming); | |||||
| PyObject *_retval = 0; | |||||
| { | |||||
| ArgLocker _lock; | |||||
| const MACGrid &vel = *_args.getPtr<MACGrid>("vel", 0, &_lock); | |||||
| Grid<Real> &mag = *_args.getPtr<Grid<Real>>("mag", 1, &_lock); | |||||
| _retval = getPyNone(); | |||||
| computeStrainRateMag(vel, mag); | |||||
| _args.check(); | |||||
| } | |||||
| pbFinalizePlugin(parent, "computeStrainRateMag", !noTiming); | |||||
| return _retval; | |||||
| } | |||||
| catch (std::exception &e) { | |||||
| pbSetError("computeStrainRateMag", e.what()); | |||||
| return 0; | |||||
| } | |||||
| } | |||||
| static const Pb::Register _RP_computeStrainRateMag("", "computeStrainRateMag", _W_9); | |||||
| extern "C" { | |||||
| void PbRegister_computeStrainRateMag() | |||||
| { | |||||
| KEEP_UNUSED(_RP_computeStrainRateMag); | |||||
| } | |||||
| } | |||||
| // extrapolate a real grid into a flagged region (based on initial flags) | |||||
| // by default extrapolates from fluid to obstacle cells | |||||
| template<class T> | |||||
| void extrapolSimpleFlagsHelper(const FlagGrid &flags, | |||||
| Grid<T> &val, | |||||
| int distance = 4, | |||||
| int flagFrom = FlagGrid::TypeFluid, | |||||
| int flagTo = FlagGrid::TypeObstacle) | |||||
| { | |||||
| Grid<int> tmp(flags.getParent()); | |||||
| int dim = (flags.is3D() ? 3 : 2); | |||||
| const Vec3i nb[6] = {Vec3i(1, 0, 0), | |||||
| Vec3i(-1, 0, 0), | |||||
| Vec3i(0, 1, 0), | |||||
| Vec3i(0, -1, 0), | |||||
| Vec3i(0, 0, 1), | |||||
| Vec3i(0, 0, -1)}; | |||||
| // remove all fluid cells (set to 1) | |||||
| tmp.clear(); | |||||
| bool foundTarget = false; | |||||
| FOR_IJK_BND(flags, 0) | |||||
| { | |||||
| if (flags(i, j, k) & flagFrom) | |||||
| tmp(Vec3i(i, j, k)) = 1; | |||||
| if (!foundTarget && (flags(i, j, k) & flagTo)) | |||||
| foundTarget = true; | |||||
| } | |||||
| // optimization, skip extrapolation if we dont have any cells to extrapolate to | |||||
| if (!foundTarget) { | |||||
| debMsg("No target cells found, skipping extrapolation", 1); | |||||
| return; | |||||
| } | |||||
| // extrapolate for given distance | |||||
| for (int d = 1; d < 1 + distance; ++d) { | |||||
| // TODO, parallelize | |||||
| FOR_IJK_BND(flags, 1) | |||||
| { | |||||
| if (tmp(i, j, k) != 0) | |||||
| continue; | |||||
| if (!(flags(i, j, k) & flagTo)) | |||||
| continue; | |||||
| // copy from initialized neighbors | |||||
| Vec3i p(i, j, k); | |||||
| int nbs = 0; | |||||
| T avgVal = 0.; | |||||
| for (int n = 0; n < 2 * dim; ++n) { | |||||
| if (tmp(p + nb[n]) == d) { | |||||
| avgVal += val(p + nb[n]); | |||||
| nbs++; | |||||
| } | |||||
| } | |||||
| if (nbs > 0) { | |||||
| tmp(p) = d + 1; | |||||
| val(p) = avgVal / nbs; | |||||
| } | |||||
| } | |||||
| } // distance | |||||
| } | |||||
| void extrapolateSimpleFlags(const FlagGrid &flags, | |||||
| GridBase *val, | |||||
| int distance = 4, | |||||
| int flagFrom = FlagGrid::TypeFluid, | |||||
| int flagTo = FlagGrid::TypeObstacle) | |||||
| { | |||||
| if (val->getType() & GridBase::TypeReal) { | |||||
| extrapolSimpleFlagsHelper<Real>(flags, *((Grid<Real> *)val), distance, flagFrom, flagTo); | |||||
| } | |||||
| else if (val->getType() & GridBase::TypeInt) { | |||||
| extrapolSimpleFlagsHelper<int>(flags, *((Grid<int> *)val), distance, flagFrom, flagTo); | |||||
| } | |||||
| else if (val->getType() & GridBase::TypeVec3) { | |||||
| extrapolSimpleFlagsHelper<Vec3>(flags, *((Grid<Vec3> *)val), distance, flagFrom, flagTo); | |||||
| } | |||||
| else | |||||
| errMsg("extrapolateSimpleFlags: Grid Type is not supported (only int, Real, Vec3)"); | |||||
| } | |||||
| 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, "extrapolateSimpleFlags", !noTiming); | |||||
| PyObject *_retval = 0; | |||||
| { | |||||
| ArgLocker _lock; | |||||
| const FlagGrid &flags = *_args.getPtr<FlagGrid>("flags", 0, &_lock); | |||||
| GridBase *val = _args.getPtr<GridBase>("val", 1, &_lock); | |||||
| int distance = _args.getOpt<int>("distance", 2, 4, &_lock); | |||||
| int flagFrom = _args.getOpt<int>("flagFrom", 3, FlagGrid::TypeFluid, &_lock); | |||||
| int flagTo = _args.getOpt<int>("flagTo", 4, FlagGrid::TypeObstacle, &_lock); | |||||
| _retval = getPyNone(); | |||||
| extrapolateSimpleFlags(flags, val, distance, flagFrom, flagTo); | |||||
| _args.check(); | |||||
| } | |||||
| pbFinalizePlugin(parent, "extrapolateSimpleFlags", !noTiming); | |||||
| return _retval; | |||||
| } | |||||
| catch (std::exception &e) { | |||||
| pbSetError("extrapolateSimpleFlags", e.what()); | |||||
| return 0; | |||||
| } | |||||
| } | |||||
| static const Pb::Register _RP_extrapolateSimpleFlags("", "extrapolateSimpleFlags", _W_10); | |||||
| extern "C" { | |||||
| void PbRegister_extrapolateSimpleFlags() | |||||
| { | |||||
| KEEP_UNUSED(_RP_extrapolateSimpleFlags); | |||||
| } | |||||
| } | |||||
| //! convert vel to a centered grid, then compute its curl | |||||
| void getCurl(const MACGrid &vel, Grid<Real> &vort, int comp) | |||||
| { | |||||
| Grid<Vec3> velCenter(vel.getParent()), curl(vel.getParent()); | |||||
| GetCentered(velCenter, vel); | |||||
| CurlOp(velCenter, curl); | |||||
| GetComponent(curl, vort, comp); | |||||
| } | |||||
| 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, "getCurl", !noTiming); | |||||
| PyObject *_retval = 0; | |||||
| { | |||||
| ArgLocker _lock; | |||||
| const MACGrid &vel = *_args.getPtr<MACGrid>("vel", 0, &_lock); | |||||
| Grid<Real> &vort = *_args.getPtr<Grid<Real>>("vort", 1, &_lock); | |||||
| int comp = _args.get<int>("comp", 2, &_lock); | |||||
| _retval = getPyNone(); | |||||
| getCurl(vel, vort, comp); | |||||
| _args.check(); | |||||
| } | |||||
| pbFinalizePlugin(parent, "getCurl", !noTiming); | |||||
| return _retval; | |||||
| } | |||||
| catch (std::exception &e) { | |||||
| pbSetError("getCurl", e.what()); | |||||
| return 0; | |||||
| } | |||||
| } | |||||
| static const Pb::Register _RP_getCurl("", "getCurl", _W_11); | |||||
| extern "C" { | |||||
| void PbRegister_getCurl() | |||||
| { | |||||
| KEEP_UNUSED(_RP_getCurl); | |||||
| } | |||||
| } | |||||
| } // namespace Manta | |||||