forked from bartvdbraak/blender
3bea663ffa
#4742 exported normals are now correct #4821 & 4956 for complex movements in/outflows can now also use the animated mesh option - new features * isosurface subdivision: directly creates a finer surface mesh from the simulation data. this increases simulation time and harddisk usage, though, so be careful - usually values of 2-4 should be enough. * fluidsim particles: extended model for particle simulation and generation. When isosurface subdivision is enabled, the particles are now included in the surface generation, giving a better impression of a single connected surface. Note - the particles are only included in the final surface mesh, so the preview surface shows none of the particle effects. * particle loading: different types of particles can now be selected for display: drops, floats and tracers. This is a bit obsolete due to the extensions mentioned above, but might still be useful. Floats are just particles floating on the fluid surface, could be used for e.g. foam. * moving objects impact factor: this is another tweaking option, as the handling of moving objects is still not conserving mass. setting this to zero simply deletes the fluid, 1 is the default, while larger values cause a stronger impact. For tweaking the simulation: if fluid disappears, try increasing this value, and if too much is appearing reduce it. You can even use negative values for some strange results :) - more code cleanup, e.g. removed config file writing in fluidsim.c, added additional safety checks for particles & fluidsim domains (these currently dont work together). I also removed the "build particles" debug message in effects.c (seemed to be unnecessary?). Some more info on the new features: Here are two test animations showing the difference between using the particle generation with isosurface subdivision. This is how it would look with the old solver version: http://www10.informatik.uni-erlangen.de/~sinithue/blender/fluid6_fl6manc4_1noparts.mpg and this with the new one: http://www10.informatik.uni-erlangen.de/~sinithue/blender/fluid6_fl6manc4_2wparts.mpg Both simulations use a resolution of 64, however, the version with particles takes significantly longer (almost twice as long). The .blend file for a similar setup can be found here: http://www10.informatik.uni-erlangen.de/~sinithue/blender/fluid6_testmanc4.blend (Minor Tips for this file: dont enable subdivions of characters until rendering, thus leave off for simulation, as it uses the rendering settings! For making nice pictures switch on subdivion, and OSA.) And here's a picture of old vs. new (for webpage or so): http://www10.informatik.uni-erlangen.de/~sinithue/blender/fluid6_manc4compare.png
311 lines
11 KiB
C++
311 lines
11 KiB
C++
/******************************************************************************
|
|
*
|
|
* El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method
|
|
* Copyright 2003-2006 Nils Thuerey
|
|
*
|
|
* Parameter calculator for the LBM Solver class
|
|
*
|
|
*****************************************************************************/
|
|
#ifndef MFFSLBM_PARAMETRIZER
|
|
#define MFFSLBM_PARAMETRIZER
|
|
|
|
|
|
/* LBM Files */
|
|
#include "utilities.h"
|
|
#include "attributes.h"
|
|
|
|
/* parametrizer accuracy */
|
|
typedef double ParamFloat;
|
|
typedef ntlVec3d ParamVec;
|
|
|
|
/*! flags to check which values are known */
|
|
#define PARAM_RELAXTIME (1<< 0)
|
|
#define PARAM_REYNOLDS (1<< 1)
|
|
#define PARAM_VISCOSITY (1<< 2)
|
|
#define PARAM_SOUNDSPEED (1<< 3)
|
|
#define PARAM_DOMAINSIZE (1<< 4)
|
|
#define PARAM_GRAVITY (1<< 5)
|
|
#define PARAM_STEPTIME (1<< 7)
|
|
#define PARAM_SIZE (1<< 8)
|
|
#define PARAM_TIMEFACTOR (1<< 9)
|
|
#define PARAM_ANIFRAMETIME (1<<11)
|
|
#define PARAM_ANISTART (1<<12)
|
|
#define PARAM_SURFACETENSION (1<<13)
|
|
#define PARAM_DENSITY (1<<14)
|
|
#define PARAM_GSTAR (1<<16)
|
|
#define PARAM_SIMMAXSPEED (1<<18)
|
|
#define PARAM_FLUIDVOLHEIGHT (1<<19)
|
|
#define PARAM_NORMALIZEDGSTAR (1<<20)
|
|
#define PARAM_NUMIDS 21
|
|
|
|
//! output parameter debug message?
|
|
//#define PARAM_DEBUG 1
|
|
|
|
|
|
|
|
/*! Parameter calculator for the LBM Solver class */
|
|
class Parametrizer {
|
|
|
|
public:
|
|
/*! default contructor */
|
|
Parametrizer();
|
|
|
|
/*! destructor */
|
|
~Parametrizer();
|
|
|
|
/*! Initilize variables fom attribute list */
|
|
void parseAttrList( void );
|
|
|
|
/*! function that tries to calculate all the missing values from the given ones
|
|
* prints errors and returns false if thats not possible
|
|
* currently needs time value as well */
|
|
bool calculateAllMissingValues( double time, bool silent );
|
|
/*! is the parametrizer used at all? */
|
|
bool isUsed() { return true; }
|
|
|
|
/*! add this flag to the seen values */
|
|
void seenThis(int seen) { mSeenValues = (mSeenValues | seen);
|
|
#ifdef PARAM_DEBUG
|
|
errorOut(" seen "<<seen<<endl);
|
|
#endif
|
|
}
|
|
|
|
/*! set the flags integer */
|
|
void setSeenValues(int set) { mSeenValues = set; }
|
|
/*! check if the flags are set in the values int */
|
|
bool checkSeenValues(int check) { /*errorOut( " b"<<((mSeenValues&check)==check) );*/ return ((mSeenValues&check)==check); }
|
|
|
|
/*! add this flag to the calculated values */
|
|
void calculatedThis(int cac) { mCalculatedValues = (mCalculatedValues | cac); /*errorOut(" a "<<seen);*/ }
|
|
/*! set the calculated flags integer */
|
|
void setCalculatedValues(int set) { mCalculatedValues = set; }
|
|
/*! check if the calculated flags are set in the values int */
|
|
bool checkCalculatedValues(int check) { /*errorOut( " b"<<((mSeenValues&check)==check) );*/ return ((mCalculatedValues&check)==check); }
|
|
/*! advance to next render/output frame */
|
|
void setFrameNum(int frame);
|
|
ParamFloat getAniFrameTime(int frame);
|
|
ParamFloat getCurrentAniFrameTime(){ return getAniFrameTime(mFrameNum); };
|
|
|
|
/*! scale a given speed vector in m/s to lattice values
|
|
* usage string is only needed for debugging */
|
|
ParamVec calculateAddForce(ParamVec vec, string usage);
|
|
|
|
/* simple calulation functions */
|
|
/*! get omega for LBM */
|
|
ParamFloat calculateOmega( double time );
|
|
/*! get no. of timesteps for LBM */
|
|
int calculateNoOfSteps( ParamFloat timelen );
|
|
/*! get external force x component */
|
|
ParamVec calculateGravity( double time );
|
|
/*! get no of steps for the given length in seconds */
|
|
int calculateStepsForSecs( ParamFloat s );
|
|
/*! get no of steps for a singel animation frame */
|
|
int calculateAniStepsPerFrame(int frame);
|
|
/*! get start time of animation */
|
|
int calculateAniStart( void );
|
|
/*! get extent of the domain = (1,1,1) if parametrizer not used, (x,y,z) [m] otherwise */
|
|
//ParamVec calculateExtent( void );
|
|
/*! get (scaled) surface tension */
|
|
ParamFloat calculateSurfaceTension( void );
|
|
/*! get time step size for lbm (equals mTimeFactor) */
|
|
// unused ParamFloat calculateTimestep( void );
|
|
/*! calculate size of a single cell */
|
|
ParamFloat calculateCellSize(void);
|
|
/*! calculate the lattice viscosity */
|
|
ParamFloat calculateLatticeViscosity( double time );
|
|
|
|
/*! calculate lattice velocity from real world value [m/s] */
|
|
ParamVec calculateLattVelocityFromRw( ParamVec ivel );
|
|
/*! calculate real world [m/s] velocity from lattice value */
|
|
ParamVec calculateRwVelocityFromLatt( ParamVec ivel );
|
|
|
|
/*! set speed of sound */
|
|
void setSoundSpeed(ParamFloat set) { mSoundSpeed = set; seenThis( PARAM_SOUNDSPEED ); }
|
|
/*! get speed of sound */
|
|
ParamFloat getSoundSpeed( void ) { return mSoundSpeed; }
|
|
|
|
/*! set kinematic viscosity */
|
|
void setViscosity(ParamFloat set);
|
|
void initViscosityChannel(vector<ParamFloat> val, vector<double> time);
|
|
|
|
/*! set the external force */
|
|
void setGravity(ParamFloat setx, ParamFloat sety, ParamFloat setz);
|
|
void setGravity(ParamVec set);
|
|
void initGravityChannel(vector<ParamVec> val, vector<double> time);
|
|
ParamVec getGravity(double time) { return mcGravity.get( time ); }
|
|
|
|
/*! set time of an animation frame (renderer) */
|
|
void setAniFrameTimeChannel(ParamFloat set);
|
|
void initAniFrameTimeChannel(vector<ParamFloat> val, vector<double> time);
|
|
|
|
/*! set the length of a single time step */
|
|
void setTimestep(ParamFloat set) { mTimestep = set; seenThis( PARAM_STEPTIME ); }
|
|
/*! get the length of a single time step */
|
|
ParamFloat getTimestep( void);
|
|
/*! set a desired step time for rescaling/adaptive timestepping */
|
|
void setDesiredTimestep(ParamFloat set) { mDesiredTimestep = set; }
|
|
/*! get the length of a single time step */
|
|
ParamFloat getMaxTimestep( void ) { return mMaxTimestep; }
|
|
/*! get the length of a single time step */
|
|
ParamFloat getMinTimestep( void ) { return mMinTimestep; }
|
|
|
|
/*! set the time scaling factor */
|
|
void setTimeFactor(ParamFloat set) { mTimeFactor = set; seenThis( PARAM_TIMEFACTOR ); }
|
|
/*! get the time scaling factor */
|
|
ParamFloat getTimeFactor( void ) { return mTimeFactor; }
|
|
|
|
/*! init domain resoultion */
|
|
void setSize(int ijk) { mSizex = ijk; mSizey = ijk; mSizez = ijk; seenThis( PARAM_SIZE ); }
|
|
void setSize(int i,int j, int k) { mSizex = i; mSizey = j; mSizez = k; seenThis( PARAM_SIZE ); }
|
|
|
|
/*! set starting time of the animation (renderer) */
|
|
void setAniStart(ParamFloat set) { mAniStart = set; seenThis( PARAM_ANISTART ); }
|
|
/*! get starting time of the animation (renderer) */
|
|
ParamFloat getAniStart( void ) { return mAniStart; }
|
|
|
|
/*! set fluid density */
|
|
void setDensity(ParamFloat set) { mDensity = set; seenThis( PARAM_DENSITY ); }
|
|
/*! get fluid density */
|
|
ParamFloat getDensity( void ) { return mDensity; }
|
|
|
|
/*! set g star value */
|
|
void setGStar(ParamFloat set) { mGStar = set; seenThis( PARAM_GSTAR ); }
|
|
/*! get g star value */
|
|
ParamFloat getGStar( void ) { return mGStar; }
|
|
/*! get g star value with fhvol calculations */
|
|
ParamFloat getCurrentGStar( void );
|
|
/*! set normalized g star value */
|
|
void setNormalizedGStar(ParamFloat set) { mNormalizedGStar = set; seenThis( PARAM_NORMALIZEDGSTAR ); }
|
|
/*! get normalized g star value */
|
|
ParamFloat getNormalizedGStar( void ) { return mNormalizedGStar; }
|
|
|
|
/*! set g star value */
|
|
void setFluidVolumeHeight(ParamFloat set) { mFluidVolumeHeight = set; seenThis( PARAM_FLUIDVOLHEIGHT ); }
|
|
/*! get g star value */
|
|
ParamFloat getFluidVolumeHeight( void ) { return mFluidVolumeHeight; }
|
|
|
|
/*! set the size of a single lbm cell */
|
|
void setDomainSize(ParamFloat set) { mDomainSize = set; seenThis( PARAM_DOMAINSIZE ); }
|
|
/*! get the size of a single lbm cell */
|
|
ParamFloat getDomainSize( void ) { return mDomainSize; }
|
|
|
|
/*! set the size of a single lbm cell (dont use, normally set by domainsize and resolution) */
|
|
void setCellSize(ParamFloat set) { mCellSize = set; }
|
|
/*! get the size of a single lbm cell */
|
|
ParamFloat getCellSize( void ) { return mCellSize; }
|
|
|
|
/*! set active flag for parametrizer */
|
|
//void setActive(bool set) { mActive = set; }
|
|
|
|
/*! set attr list pointer */
|
|
void setAttrList(AttributeList *set) { mpAttrs = set; }
|
|
/*! Returns the attribute list pointer */
|
|
inline AttributeList *getAttributeList() { return mpAttrs; }
|
|
|
|
/*! set maximum allowed speed for maxspeed setup */
|
|
void setSimulationMaxSpeed(ParamFloat set) { mSimulationMaxSpeed = set; seenThis( PARAM_SIMMAXSPEED ); }
|
|
/*! get maximum allowed speed for maxspeed setup */
|
|
ParamFloat getSimulationMaxSpeed( void ) { return mSimulationMaxSpeed; }
|
|
|
|
/*! set maximum allowed omega for time adaptivity */
|
|
void setTadapMaxOmega(ParamFloat set) { mTadapMaxOmega = set; }
|
|
/*! get maximum allowed omega for time adaptivity */
|
|
ParamFloat getTadapMaxOmega( void ) { return mTadapMaxOmega; }
|
|
|
|
/*! set maximum allowed speed for time adaptivity */
|
|
void setTadapMaxSpeed(ParamFloat set) { mTadapMaxSpeed = set; }
|
|
/*! get maximum allowed speed for time adaptivity */
|
|
ParamFloat getTadapMaxSpeed( void ) { return mTadapMaxSpeed; }
|
|
|
|
/*! set maximum allowed omega for time adaptivity */
|
|
void setTadapLevels(int set) { mTadapLevels = set; }
|
|
/*! get maximum allowed omega for time adaptivity */
|
|
int getTadapLevels( void ) { return mTadapLevels; }
|
|
|
|
/*! set */
|
|
// void set(ParamFloat set) { m = set; seenThis( PARAM_ ); }
|
|
/*! get */
|
|
// ParamFloat get( void ) { return m; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
/*! kinematic viscosity of the fluid [m^2/s] */
|
|
AnimChannel<ParamFloat> mcViscosity;
|
|
|
|
/*! speed of sound of the fluid [m/s] */
|
|
ParamFloat mSoundSpeed;
|
|
|
|
/*! size of the domain [m] */
|
|
ParamFloat mDomainSize;
|
|
|
|
/*! size of a single cell in the grid [m] */
|
|
ParamFloat mCellSize;
|
|
|
|
/*! time step length [s] */
|
|
ParamFloat mTimeStep;
|
|
|
|
/*! external force as acceleration [m/s^2] */
|
|
AnimChannel<ParamVec> mcGravity;
|
|
|
|
/*! length of one time step in the simulation */
|
|
ParamFloat mTimestep;
|
|
/*! desired step time for rescaling/adaptive timestepping, only regarded if >0.0, reset after usage */
|
|
ParamFloat mDesiredTimestep;
|
|
/*! minimal and maximal step times for current setup */
|
|
ParamFloat mMaxTimestep, mMinTimestep;
|
|
|
|
/*! domain resoultion, the same values as in lbmsolver */
|
|
int mSizex, mSizey, mSizez;
|
|
|
|
/*! time scaling factor (auto calc from accel, or set), equals the delta t in LBM */
|
|
ParamFloat mTimeFactor;
|
|
|
|
/*! for renderer - length of an animation step [s] */
|
|
AnimChannel<ParamFloat> mcAniFrameTime;
|
|
/*! time step scaling factor for testing/debugging */
|
|
ParamFloat mTimeStepScale;
|
|
|
|
/*! for renderer - start time of the animation [s] */
|
|
ParamFloat mAniStart;
|
|
|
|
/*! extent of the domain in meters */
|
|
//ParamVec mExtent;
|
|
|
|
/*! fluid density [kg/m^3], default 1.0 g/cm^3 */
|
|
ParamFloat mDensity;
|
|
|
|
/*! max difference due to gravity (for caro setup) */
|
|
ParamFloat mGStar;
|
|
/*! set gstar normalized! */
|
|
ParamFloat mNormalizedGStar;
|
|
/*! fluid volume/height multiplier for GStar */
|
|
ParamFloat mFluidVolumeHeight;
|
|
|
|
/*! current max speed of the simulation (for adaptive time steps) */
|
|
ParamFloat mSimulationMaxSpeed;
|
|
/*! maximum omega (for adaptive time steps) */
|
|
ParamFloat mTadapMaxOmega;
|
|
/*! maximum allowed speed in lattice units e.g. 0.1 (for adaptive time steps, not directly used in parametrizer) */
|
|
ParamFloat mTadapMaxSpeed;
|
|
/*! no. of levels for max omega (set by fsgr, not in cfg file) */
|
|
int mTadapLevels;
|
|
|
|
/*! remember current frame number */
|
|
int mFrameNum;
|
|
|
|
/*! values that are seen for this simulation */
|
|
int mSeenValues;
|
|
|
|
/*! values that are calculated from the seen ones for this simulation */
|
|
int mCalculatedValues;
|
|
|
|
/*! pointer to the attribute list */
|
|
AttributeList *mpAttrs;
|
|
};
|
|
|
|
|
|
#endif
|
|
|