forked from bartvdbraak/blender
305 lines
8.6 KiB
C++
305 lines
8.6 KiB
C++
/** \file elbeem/intern/controlparticles.h
|
|
* \ingroup elbeem
|
|
*/
|
|
// --------------------------------------------------------------------------
|
|
//
|
|
// El'Beem - the visual lattice boltzmann freesurface simulator
|
|
// All code distributed as part of El'Beem is covered by the version 2 of the
|
|
// GNU General Public License. See the file COPYING for details.
|
|
//
|
|
// Copyright 2008 Nils Thuerey , Richard Keiser, Mark Pauly, Ulrich Ruede
|
|
//
|
|
// control particle classes
|
|
//
|
|
// --------------------------------------------------------------------------
|
|
|
|
#ifndef CONTROLPARTICLES_H
|
|
#define CONTROLPARTICLES_H
|
|
|
|
#include "ntl_geometrymodel.h"
|
|
|
|
// indicator for LBM inclusion
|
|
//#ifndef LBMDIM
|
|
|
|
//#include <NxFoundation.h>
|
|
//#include <vector>
|
|
//class MultisphGUI;
|
|
//#define NORMALIZE(a) a.normalize()
|
|
//#define MAGNITUDE(a) a.magnitude()
|
|
//#define CROSS(a,b,c) a.cross(b,c)
|
|
//#define ABS(a) (a>0. ? (a) : -(a))
|
|
//#include "cpdefines.h"
|
|
|
|
//#else // LBMDIM
|
|
|
|
// use compatibility defines
|
|
//#define NORMALIZE(a) normalize(a)
|
|
//#define MAGNITUDE(a) norm(a)
|
|
//#define CROSS(a,b,c) a=cross(b,c)
|
|
|
|
//#endif // LBMDIM
|
|
|
|
#define MAGNITUDE(a) norm(a)
|
|
|
|
// math.h compatibility
|
|
#define CP_PI ((LbmFloat)3.14159265358979323846)
|
|
|
|
// project 2d test cases onto plane?
|
|
// if not, 3d distance is used for 2d sim as well
|
|
#define CP_PROJECT2D 1
|
|
|
|
|
|
// default init for mincpdist, ControlForces::maxDistance
|
|
#define CPF_MAXDINIT 10000.
|
|
|
|
// storage of influence for a fluid cell/particle in lbm/sph
|
|
class ControlForces
|
|
{
|
|
public:
|
|
ControlForces() { };
|
|
~ControlForces() {};
|
|
|
|
// attraction force
|
|
LbmFloat weightAtt;
|
|
LbmVec forceAtt;
|
|
// velocity influence
|
|
LbmFloat weightVel;
|
|
LbmVec forceVel;
|
|
// maximal distance influence,
|
|
// first is max. distance to first control particle
|
|
// second attraction strength
|
|
LbmFloat maxDistance;
|
|
LbmVec forceMaxd;
|
|
|
|
LbmFloat compAvWeight;
|
|
LbmVec compAv;
|
|
|
|
void resetForces() {
|
|
weightAtt = weightVel = 0.;
|
|
maxDistance = CPF_MAXDINIT;
|
|
forceAtt = forceVel = forceMaxd = LbmVec(0.,0.,0.);
|
|
compAvWeight=0.; compAv=LbmVec(0.);
|
|
};
|
|
};
|
|
|
|
|
|
// single control particle
|
|
class ControlParticle
|
|
{
|
|
public:
|
|
ControlParticle() { reset(); };
|
|
~ControlParticle() {};
|
|
|
|
// control parameters
|
|
|
|
// position
|
|
LbmVec pos;
|
|
// size (influences influence radius)
|
|
LbmFloat size;
|
|
// overall strength of influence
|
|
LbmFloat influence;
|
|
// rotation axis
|
|
LbmVec rotaxis;
|
|
|
|
// computed values
|
|
|
|
// velocity
|
|
LbmVec vel;
|
|
// computed density
|
|
LbmFloat density;
|
|
LbmFloat densityWeight;
|
|
|
|
LbmVec avgVel;
|
|
LbmVec avgVelAcc;
|
|
LbmFloat avgVelWeight;
|
|
|
|
// init all zero / defaults
|
|
void reset();
|
|
};
|
|
|
|
|
|
// container for a particle configuration at time t
|
|
class ControlParticleSet
|
|
{
|
|
public:
|
|
|
|
// time of particle set
|
|
LbmFloat time;
|
|
// particle positions
|
|
std::vector<ControlParticle> particles;
|
|
|
|
};
|
|
|
|
|
|
// container & management of control particles
|
|
class ControlParticles
|
|
{
|
|
public:
|
|
ControlParticles();
|
|
~ControlParticles();
|
|
|
|
// reset datastructures for next influence step
|
|
// if motion object is given, particle 1 of second system is used for overall
|
|
// position and speed offset
|
|
void prepareControl(LbmFloat simtime, LbmFloat dt, ControlParticles *motion);
|
|
// post control operations
|
|
void finishControl(std::vector<ControlForces> &forces, LbmFloat iatt, LbmFloat ivel, LbmFloat imaxd);
|
|
// recalculate
|
|
void calculateKernelWeight();
|
|
|
|
// calculate forces at given position, and modify velocity
|
|
// according to timestep (from initControl)
|
|
void calculateCpInfluenceOpt (ControlParticle *cp, LbmVec fluidpos, LbmVec fluidvel, ControlForces *force, LbmFloat fillFactor);
|
|
void calculateMaxdForce (ControlParticle *cp, LbmVec fluidpos, ControlForces *force);
|
|
|
|
// no. of particles
|
|
inline int getSize() { return (int)_particles.size(); }
|
|
int getTotalSize();
|
|
// get particle [i]
|
|
inline ControlParticle* getParticle(int i){ return &_particles[i]; }
|
|
|
|
// set influence parameters
|
|
void setInfluenceTangential(LbmFloat set) { _influenceTangential=set; }
|
|
void setInfluenceAttraction(LbmFloat set) { _influenceAttraction=set; }
|
|
void setInfluenceMaxdist(LbmFloat set) { _influenceMaxdist=set; }
|
|
// calculate for delta t
|
|
void setInfluenceVelocity(LbmFloat set, LbmFloat dt);
|
|
// get influence parameters
|
|
inline LbmFloat getInfluenceAttraction() { return _influenceAttraction; }
|
|
inline LbmFloat getInfluenceTangential() { return _influenceTangential; }
|
|
inline LbmFloat getInfluenceVelocity() { return _influenceVelocity; }
|
|
inline LbmFloat getInfluenceMaxdist() { return _influenceMaxdist; }
|
|
inline LbmFloat getCurrTimestep() { return _currTimestep; }
|
|
|
|
void setRadiusAtt(LbmFloat set) { _radiusAtt=set; }
|
|
inline LbmFloat getRadiusAtt() { return _radiusAtt; }
|
|
void setRadiusVel(LbmFloat set) { _radiusVel=set; }
|
|
inline LbmFloat getRadiusVel() { return _radiusVel; }
|
|
void setRadiusMaxd(LbmFloat set) { _radiusMaxd=set; }
|
|
inline LbmFloat getRadiusMaxd() { return _radiusMaxd; }
|
|
void setRadiusMinMaxd(LbmFloat set) { _radiusMinMaxd=set; }
|
|
inline LbmFloat getRadiusMinMaxd() { return _radiusMinMaxd; }
|
|
|
|
LbmFloat getControlTimStart();
|
|
LbmFloat getControlTimEnd();
|
|
|
|
// set/get characteristic length (and inverse)
|
|
void setCharLength(LbmFloat set) { _charLength=set; _charLengthInv=1./_charLength; }
|
|
inline LbmFloat getCharLength() { return _charLength;}
|
|
inline LbmFloat getCharLengthInv() { return _charLengthInv;}
|
|
|
|
// set init parameters
|
|
void setInitTimeScale(LbmFloat set) { _initTimeScale = set; };
|
|
void setInitMirror(string set) { _initMirror = set; };
|
|
string getInitMirror() { return _initMirror; };
|
|
|
|
void setLastOffset(LbmVec set) { _initLastPartOffset = set; };
|
|
void setLastScale(LbmVec set) { _initLastPartScale = set; };
|
|
void setOffset(LbmVec set) { _initPartOffset = set; };
|
|
void setScale(LbmVec set) { _initPartScale = set; };
|
|
|
|
// set/get cps params
|
|
void setCPSWith(LbmFloat set) { mCPSWidth = set; };
|
|
void setCPSTimestep(LbmFloat set) { mCPSTimestep = set; };
|
|
void setCPSTimeStart(LbmFloat set) { mCPSTimeStart = set; };
|
|
void setCPSTimeEnd(LbmFloat set) { mCPSTimeEnd = set; };
|
|
void setCPSMvmWeightFac(LbmFloat set) { mCPSWeightFac = set; };
|
|
|
|
LbmFloat getCPSWith() { return mCPSWidth; };
|
|
LbmFloat getCPSTimestep() { return mCPSTimestep; };
|
|
LbmFloat getCPSTimeStart() { return mCPSTimeStart; };
|
|
LbmFloat getCPSTimeEnd() { return mCPSTimeEnd; };
|
|
LbmFloat getCPSMvmWeightFac() { return mCPSWeightFac; };
|
|
|
|
void setDebugInit(int set) { mDebugInit = set; };
|
|
|
|
// set init parameters
|
|
void setFluidSpacing(LbmFloat set) { _fluidSpacing = set; };
|
|
|
|
// load positions & timing from text file
|
|
int initFromTextFile(string filename);
|
|
int initFromTextFileOld(string filename);
|
|
// load positions & timing from gzipped binary file
|
|
int initFromBinaryFile(string filename);
|
|
int initFromMVCMesh(string filename);
|
|
// init an example test case
|
|
int initExampleSet();
|
|
|
|
// init for a given time
|
|
void initTime(LbmFloat t, LbmFloat dt);
|
|
|
|
// blender test init
|
|
void initBlenderTest();
|
|
|
|
int initFromObject(ntlGeometryObjModel *model);
|
|
|
|
protected:
|
|
// sets influence params
|
|
friend class MultisphGUI;
|
|
|
|
// tangential and attraction influence
|
|
LbmFloat _influenceTangential, _influenceAttraction;
|
|
// direct velocity influence
|
|
LbmFloat _influenceVelocity;
|
|
// maximal distance influence
|
|
LbmFloat _influenceMaxdist;
|
|
|
|
// influence radii
|
|
LbmFloat _radiusAtt, _radiusVel, _radiusMinMaxd, _radiusMaxd;
|
|
|
|
// currently valid time & timestep
|
|
LbmFloat _currTime, _currTimestep;
|
|
// all particles
|
|
std::vector<ControlParticle> _particles;
|
|
|
|
// particle sets
|
|
std::vector<ControlParticleSet> mPartSets;
|
|
|
|
// additional parameters for initing particles
|
|
LbmFloat _initTimeScale;
|
|
LbmVec _initPartOffset;
|
|
LbmVec _initPartScale;
|
|
LbmVec _initLastPartOffset;
|
|
LbmVec _initLastPartScale;
|
|
// mirror particles for loading?
|
|
string _initMirror;
|
|
|
|
// row spacing paramter, e.g. use for approximation of kernel area/volume
|
|
LbmFloat _fluidSpacing;
|
|
// save current kernel weight
|
|
LbmFloat _kernelWeight;
|
|
// charateristic length in world coordinates for normalizatioon of forces
|
|
LbmFloat _charLength, _charLengthInv;
|
|
|
|
|
|
/*! do ani mesh CPS */
|
|
void calculateCPS(string filename);
|
|
//! ani mesh cps params
|
|
ntlVec3Gfx mvCPSStart, mvCPSEnd;
|
|
gfxReal mCPSWidth, mCPSTimestep;
|
|
gfxReal mCPSTimeStart, mCPSTimeEnd;
|
|
gfxReal mCPSWeightFac;
|
|
|
|
int mDebugInit;
|
|
|
|
|
|
protected:
|
|
// apply init transformations
|
|
void applyTrafos();
|
|
|
|
// helper function for init -> swap components everywhere
|
|
void swapCoords(int a,int b);
|
|
// helper function for init -> mirror time
|
|
void mirrorTime();
|
|
|
|
// helper, init given array
|
|
void initTimeArray(LbmFloat t, std::vector<ControlParticle> &parts);
|
|
|
|
bool checkPointInside(ntlTree *tree, ntlVec3Gfx org, gfxReal &distance);
|
|
};
|
|
|
|
|
|
|
|
#endif
|
|
|