// DO NOT EDIT ! // This file is generated using the MantaFlow preprocessor (prep generate). /****************************************************************************** * * MantaFlow fluid solver framework * Copyright 2016 Sebastian Barschkis, 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 * * Fire modeling plugin * ******************************************************************************/ #include "general.h" #include "grid.h" #include "vectorbase.h" using namespace std; namespace Manta { struct KnProcessBurn : public KernelBase { KnProcessBurn(Grid &fuel, Grid &density, Grid &react, Grid *red, Grid *green, Grid *blue, Grid *heat, Real burningRate, Real flameSmoke, Real ignitionTemp, Real maxTemp, Real dt, Vec3 flameSmokeColor) : KernelBase(&fuel, 1), fuel(fuel), density(density), react(react), red(red), green(green), blue(blue), heat(heat), burningRate(burningRate), flameSmoke(flameSmoke), ignitionTemp(ignitionTemp), maxTemp(maxTemp), dt(dt), flameSmokeColor(flameSmokeColor) { runMessage(); run(); } inline void op(int i, int j, int k, Grid &fuel, Grid &density, Grid &react, Grid *red, Grid *green, Grid *blue, Grid *heat, Real burningRate, Real flameSmoke, Real ignitionTemp, Real maxTemp, Real dt, Vec3 flameSmokeColor) { // Save initial values Real origFuel = fuel(i, j, k); Real origSmoke = density(i, j, k); Real smokeEmit = 0.0f; Real flame = 0.0f; // Process fuel fuel(i, j, k) -= burningRate * dt; if (fuel(i, j, k) < 0.0f) fuel(i, j, k) = 0.0f; // Process reaction coordinate if (origFuel > VECTOR_EPSILON) { react(i, j, k) *= fuel(i, j, k) / origFuel; flame = pow(react(i, j, k), 0.5f); } else { react(i, j, k) = 0.0f; } // Set fluid temperature based on fuel burn rate and "flameSmoke" factor smokeEmit = (origFuel < 1.0f) ? (1.0 - origFuel) * 0.5f : 0.0f; smokeEmit = (smokeEmit + 0.5f) * (origFuel - fuel(i, j, k)) * 0.1f * flameSmoke; density(i, j, k) += smokeEmit; clamp(density(i, j, k), (Real)0.0f, (Real)1.0f); // Set fluid temperature from the flame temperature profile if (heat && flame) (*heat)(i, j, k) = (1.0f - flame) * ignitionTemp + flame * maxTemp; // Mix new color if (smokeEmit > VECTOR_EPSILON) { float smokeFactor = density(i, j, k) / (origSmoke + smokeEmit); if (red) (*red)(i, j, k) = ((*red)(i, j, k) + flameSmokeColor.x * smokeEmit) * smokeFactor; if (green) (*green)(i, j, k) = ((*green)(i, j, k) + flameSmokeColor.y * smokeEmit) * smokeFactor; if (blue) (*blue)(i, j, k) = ((*blue)(i, j, k) + flameSmokeColor.z * smokeEmit) * smokeFactor; } } inline Grid &getArg0() { return fuel; } typedef Grid type0; inline Grid &getArg1() { return density; } typedef Grid type1; inline Grid &getArg2() { return react; } typedef Grid type2; inline Grid *getArg3() { return red; } typedef Grid type3; inline Grid *getArg4() { return green; } typedef Grid type4; inline Grid *getArg5() { return blue; } typedef Grid type5; inline Grid *getArg6() { return heat; } typedef Grid type6; inline Real &getArg7() { return burningRate; } typedef Real type7; inline Real &getArg8() { return flameSmoke; } typedef Real type8; inline Real &getArg9() { return ignitionTemp; } typedef Real type9; inline Real &getArg10() { return maxTemp; } typedef Real type10; inline Real &getArg11() { return dt; } typedef Real type11; inline Vec3 &getArg12() { return flameSmokeColor; } typedef Vec3 type12; void runMessage(){}; void run() { const int _maxX = maxX; const int _maxY = maxY; if (maxZ > 1) { #pragma omp parallel { #pragma omp for for (int k = minZ; k < maxZ; k++) for (int j = 1; j < _maxY; j++) for (int i = 1; i < _maxX; i++) op(i, j, k, fuel, density, react, red, green, blue, heat, burningRate, flameSmoke, ignitionTemp, maxTemp, dt, flameSmokeColor); } } else { const int k = 0; #pragma omp parallel { #pragma omp for for (int j = 1; j < _maxY; j++) for (int i = 1; i < _maxX; i++) op(i, j, k, fuel, density, react, red, green, blue, heat, burningRate, flameSmoke, ignitionTemp, maxTemp, dt, flameSmokeColor); } } } Grid &fuel; Grid &density; Grid &react; Grid *red; Grid *green; Grid *blue; Grid *heat; Real burningRate; Real flameSmoke; Real ignitionTemp; Real maxTemp; Real dt; Vec3 flameSmokeColor; }; void processBurn(Grid &fuel, Grid &density, Grid &react, Grid *red = nullptr, Grid *green = nullptr, Grid *blue = nullptr, Grid *heat = nullptr, Real burningRate = 0.75f, Real flameSmoke = 1.0f, Real ignitionTemp = 1.25f, Real maxTemp = 1.75f, Vec3 flameSmokeColor = Vec3(0.7f, 0.7f, 0.7f)) { Real dt = fuel.getParent()->getDt(); KnProcessBurn(fuel, density, react, red, green, blue, heat, burningRate, flameSmoke, ignitionTemp, maxTemp, dt, flameSmokeColor); } static PyObject *_W_0(PyObject *_self, PyObject *_linargs, PyObject *_kwds) { try { PbArgs _args(_linargs, _kwds); FluidSolver *parent = _args.obtainParent(); bool noTiming = _args.getOpt("notiming", -1, 0); pbPreparePlugin(parent, "processBurn", !noTiming); PyObject *_retval = nullptr; { ArgLocker _lock; Grid &fuel = *_args.getPtr>("fuel", 0, &_lock); Grid &density = *_args.getPtr>("density", 1, &_lock); Grid &react = *_args.getPtr>("react", 2, &_lock); Grid *red = _args.getPtrOpt>("red", 3, nullptr, &_lock); Grid *green = _args.getPtrOpt>("green", 4, nullptr, &_lock); Grid *blue = _args.getPtrOpt>("blue", 5, nullptr, &_lock); Grid *heat = _args.getPtrOpt>("heat", 6, nullptr, &_lock); Real burningRate = _args.getOpt("burningRate", 7, 0.75f, &_lock); Real flameSmoke = _args.getOpt("flameSmoke", 8, 1.0f, &_lock); Real ignitionTemp = _args.getOpt("ignitionTemp", 9, 1.25f, &_lock); Real maxTemp = _args.getOpt("maxTemp", 10, 1.75f, &_lock); Vec3 flameSmokeColor = _args.getOpt( "flameSmokeColor", 11, Vec3(0.7f, 0.7f, 0.7f), &_lock); _retval = getPyNone(); processBurn(fuel, density, react, red, green, blue, heat, burningRate, flameSmoke, ignitionTemp, maxTemp, flameSmokeColor); _args.check(); } pbFinalizePlugin(parent, "processBurn", !noTiming); return _retval; } catch (std::exception &e) { pbSetError("processBurn", e.what()); return 0; } } static const Pb::Register _RP_processBurn("", "processBurn", _W_0); extern "C" { void PbRegister_processBurn() { KEEP_UNUSED(_RP_processBurn); } } struct KnUpdateFlame : public KernelBase { KnUpdateFlame(const Grid &react, Grid &flame) : KernelBase(&react, 1), react(react), flame(flame) { runMessage(); run(); } inline void op(int i, int j, int k, const Grid &react, Grid &flame) { if (react(i, j, k) > 0.0f) flame(i, j, k) = pow(react(i, j, k), 0.5f); else flame(i, j, k) = 0.0f; } inline const Grid &getArg0() { return react; } typedef Grid type0; inline Grid &getArg1() { return flame; } typedef Grid type1; void runMessage(){}; void run() { const int _maxX = maxX; const int _maxY = maxY; if (maxZ > 1) { #pragma omp parallel { #pragma omp for for (int k = minZ; k < maxZ; k++) for (int j = 1; j < _maxY; j++) for (int i = 1; i < _maxX; i++) op(i, j, k, react, flame); } } else { const int k = 0; #pragma omp parallel { #pragma omp for for (int j = 1; j < _maxY; j++) for (int i = 1; i < _maxX; i++) op(i, j, k, react, flame); } } } const Grid &react; Grid &flame; }; void updateFlame(const Grid &react, Grid &flame) { KnUpdateFlame(react, flame); } static PyObject *_W_1(PyObject *_self, PyObject *_linargs, PyObject *_kwds) { try { PbArgs _args(_linargs, _kwds); FluidSolver *parent = _args.obtainParent(); bool noTiming = _args.getOpt("notiming", -1, 0); pbPreparePlugin(parent, "updateFlame", !noTiming); PyObject *_retval = nullptr; { ArgLocker _lock; const Grid &react = *_args.getPtr>("react", 0, &_lock); Grid &flame = *_args.getPtr>("flame", 1, &_lock); _retval = getPyNone(); updateFlame(react, flame); _args.check(); } pbFinalizePlugin(parent, "updateFlame", !noTiming); return _retval; } catch (std::exception &e) { pbSetError("updateFlame", e.what()); return 0; } } static const Pb::Register _RP_updateFlame("", "updateFlame", _W_1); extern "C" { void PbRegister_updateFlame() { KEEP_UNUSED(_RP_updateFlame); } } } // namespace Manta