26 template<
class T>
class Grid;
27 class ParticleDataBase;
28 template<
class T>
class ParticleDataImpl;
34 enum SystemType { BASE=0, PARTICLE, VORTEX, FILAMENT, FLIP, TURBULENCE, INDEX };
49 virtual SystemType getType()
const {
return BASE; }
50 virtual std::string infoString()
const;
51 virtual ParticleBase* clone() { assertMsg(
false ,
"Dont use, override...");
return NULL; }
54 virtual IndexInt
getSizeSlow()
const { assertMsg(
false ,
"Dont use, override...");
return 0; }
62 PYTHON() PbClass* create(PbType type, PbTypeVec T=PbTypeVec(),
const std::string& name =
"");
90 std::vector< ParticleDataImpl<Vec3> *> mPdataVec3;
91 std::vector< ParticleDataImpl<int> *> mPdataInt;
105 virtual SystemType getType()
const {
return S::getType(); };
108 inline S&
operator[](IndexInt idx) { DEBUG_ONLY(checkPartIndex(idx));
return mData[idx]; }
109 inline const S& operator[](IndexInt idx)
const { DEBUG_ONLY(checkPartIndex(idx));
return mData[idx]; }
112 inline IndexInt
size()
const {
return mData.size(); }
116 PYTHON() int pySize()
const {
return (
int)mData.size(); }
119 inline int getStatus(IndexInt idx)
const { DEBUG_ONLY(checkPartIndex(idx));
return mData[idx].flag; }
120 inline bool isActive(IndexInt idx)
const { DEBUG_ONLY(checkPartIndex(idx));
return (mData[idx].flag & PDELETE) == 0; }
123 PYTHON()
void setPos(
const IndexInt idx,
const Vec3& pos) { DEBUG_ONLY(checkPartIndex(idx)); mData[idx].pos = pos; }
124 PYTHON()
Vec3 getPos(IndexInt idx)
const { DEBUG_ONLY(checkPartIndex(idx));
return mData[idx].pos; }
129 void transformPositions(
Vec3i dimOld,
Vec3i dimNew );
132 void doCompress() {
if ( mDeletes > mDeleteChunk) compress(); }
134 void insertBufferedParticles();
136 void resizeAll(IndexInt newsize);
139 inline void kill(IndexInt idx);
140 IndexInt add(
const S& data);
142 PYTHON()
void clear();
145 PYTHON()
void advectInGrid(
const FlagGrid& flags,
const MACGrid& vel,
const int integrationMode,
146 const bool deleteInObstacle=
true,
const bool stopInObstacle=
true,
150 PYTHON()
void projectOutside(
Grid<Vec3>& gradient);
151 PYTHON()
void projectOutOfBnd(
const FlagGrid &flags,
const Real bnd,
const std::string& plane=
"xXyYzZ",
const ParticleDataImpl<int> *ptype=NULL,
const int exclude=0);
154 virtual std::string infoString()
const;
157 inline void checkPartIndex(IndexInt idx)
const;
166 virtual void compress();
179 static ParticleBase::SystemType getType() {
return ParticleBase::PARTICLE; }
192 PYTHON()
void save(
const std::string name)
const;
193 PYTHON()
void load(
const std::string name);
196 void writeParticlesText(
const std::string name)
const;
198 void writeParticlesRawPositionsGz(
const std::string name)
const;
199 void writeParticlesRawVelocityGz(
const std::string name)
const;
208 std::vector<BasicParticleData>&
getData() {
return mData; }
210 PYTHON()
void printParts(IndexInt start=-1, IndexInt stop=-1,
bool printIndex=
false);
223 static ParticleBase::SystemType getType() {
return ParticleBase::INDEX; }
225 IndexInt sourceIndex;
239 void resize(IndexInt size) { mData.resize(size); }
253 inline bool isSegActive(
int i) {
return (mSegments[i].flag & ParticleBase::PDELETE) == 0; }
254 inline int segSize()
const {
return mSegments.size(); }
255 inline CON& seg(
int i) {
return mSegments[i]; }
256 inline const CON& seg(
int i)
const {
return mSegments[i]; }
261 std::vector<CON> mSegments;
262 virtual void compress();
275 enum PdataType { TypeNone = 0, TypeReal = 1, TypeInt = 2, TypeVec3 = 4 };
278 virtual IndexInt
getSizeSlow()
const { assertMsg(
false ,
"Dont use, override...");
return 0; }
279 virtual void addEntry() { assertMsg(
false ,
"Dont use, override...");
return; }
280 virtual ParticleDataBase* clone() { assertMsg(
false ,
"Dont use, override...");
return NULL; }
281 virtual PdataType getType()
const { assertMsg(
false ,
"Dont use, override...");
return TypeNone; }
282 virtual void resize(IndexInt size) { assertMsg(
false ,
"Dont use, override...");
return; }
283 virtual void copyValueSlow(IndexInt from, IndexInt to) { assertMsg(
false ,
"Dont use, override...");
return; }
289 inline void checkPartIndex(IndexInt idx)
const;
305 inline T&
get(IndexInt idx) { DEBUG_ONLY(checkPartIndex(idx));
return mData[idx]; }
306 inline const T&
get(IndexInt idx)
const { DEBUG_ONLY(checkPartIndex(idx));
return mData[idx]; }
307 inline T& operator[](IndexInt idx) { DEBUG_ONLY(checkPartIndex(idx));
return mData[idx]; }
308 inline const T& operator[](IndexInt idx)
const { DEBUG_ONLY(checkPartIndex(idx));
return mData[idx]; }
311 PYTHON()
void clear();
314 PYTHON()
void setSource(
Grid<T>* grid,
bool isMAC=
false );
318 virtual void addEntry();
321 virtual void resize(IndexInt s);
322 virtual void copyValueSlow(IndexInt from, IndexInt to);
324 IndexInt size()
const {
return mData.size(); }
327 inline void copyValue(IndexInt from, IndexInt to) {
get(to) =
get(from); }
328 void initNewValue(IndexInt idx,
Vec3 pos);
331 PYTHON()
void setConst(T s);
332 PYTHON()
void setConstRange(T s,
const int begin,
const int end);
336 PYTHON()
void addConst(T s);
339 PYTHON()
void multConst(T s);
341 PYTHON()
void clamp(Real min, Real max);
342 PYTHON()
void clampMin(Real vmin);
343 PYTHON()
void clampMax(Real vmax);
345 PYTHON() Real getMaxAbs();
346 PYTHON() Real getMax();
347 PYTHON() Real getMin();
350 PYTHON() Real sumSquare()
const;
351 PYTHON() Real sumMagnitude()
const;
356 PYTHON()
void printPdata(IndexInt start=-1, IndexInt stop=-1,
bool printIndex=
false);
359 PYTHON()
void save(
const std::string name);
360 PYTHON() void load(const
std::
string name);
363 std::vector<T> mData;
380 const
int DELETE_PART = 20;
388 mDeleteChunk = mDeletes = 0;
394 mData.push_back(data);
395 mDeleteChunk = mData.
size() / DELETE_PART;
397 return mData.size()-1;
402 assertMsg(idx>=0 && idx<size(),
"Index out of bounds");
403 mData[idx].flag |= PDELETE;
404 if ( (++mDeletes > mDeleteChunk) && (
mAllowCompress) ) compress();
409 for(IndexInt i=0; i<(IndexInt)this->size(); ++i) {
410 target[i] = this->getPos(i);
415 for(IndexInt i=0; i<(IndexInt)this->size(); ++i) {
416 this->setPos(i, source[i]);
424 for(IndexInt i=0; i<(IndexInt)this->size(); ++i) {
425 this->setPos(i, this->getPos(i) * factor );
431 template<
class S> std::vector<Vec3> GridAdvectKernel (std::vector<S>& p,
const MACGrid& vel,
const FlagGrid& flags, Real dt,
bool deleteInObstacle,
bool stopInObstacle ,
const ParticleDataImpl<int> *ptype,
const int exclude) {}
437 void KnDeleteInObstacle(std::vector<S>& p,
const FlagGrid& flags) {}
441 static inline Vec3 bisectBacktracePos(
const FlagGrid& flags,
const Vec3& oldp,
const Vec3& newp)
444 for(
int i=1; i<5; ++i) {
445 Real ds = 1./(Real)(1<<i);
446 if (!flags.
isObstacle( oldp*(1.-(s+ds)) + newp*(s+ds) )) {
450 return( oldp*(1.-(s)) + newp*(s) );
461 const bool deleteInObstacle,
const bool stopInObstacle,
465 if(!deleteInObstacle) {
467 posOld->resize(mData.size());
468 for(IndexInt i=0; i<(IndexInt)mData.size();++i) (*posOld)[i] = mData[i].pos;
472 GridAdvectKernel<S> kernel(mData, vel, flags, getParent()->getDt(), deleteInObstacle, stopInObstacle, ptype, exclude );
475 if(!deleteInObstacle) {
476 KnClampPositions<S> (mData, flags, posOld , stopInObstacle, ptype, exclude );
479 KnDeleteInObstacle<S> (mData, flags);
489 KnProjectParticles<S>(*
this, gradient);
498 bool axis[6] = {
false };
499 for(std::string::const_iterator it=plane.begin(); it!=plane.end(); ++it) {
500 if(*it==
'x') axis[0] =
true;
501 if(*it==
'X') axis[1] =
true;
502 if(*it==
'y') axis[2] =
true;
503 if(*it==
'Y') axis[3] =
true;
504 if(*it==
'z') axis[4] =
true;
505 if(*it==
'Z') axis[5] =
true;
507 KnProjectOutOfBnd<S>(*
this, flags, bnd, axis, ptype, exclude);
514 for(IndexInt i=0; i<(IndexInt)
mPartData.size(); ++i)
520 IndexInt nextRead = mData.size();
521 for (IndexInt i=0; i<(IndexInt)mData.size(); i++) {
522 while ((mData[i].flag & PDELETE) != 0) {
524 mData[i] = mData[nextRead];
526 for(IndexInt pd=0; pd<(IndexInt)
mPdataReal.size(); ++pd)
mPdataReal[pd]->copyValue(nextRead, i);
527 for(IndexInt pd=0; pd<(IndexInt)mPdataVec3.size(); ++pd) mPdataVec3[pd]->copyValue(nextRead, i);
528 for(IndexInt pd=0; pd<(IndexInt)mPdataInt .size(); ++pd) mPdataInt [pd]->copyValue(nextRead, i);
529 mData[nextRead].flag = PINVALID;
532 if(nextRead<(IndexInt)mData.size()) debMsg(
"Deleted "<<((IndexInt)mData.size() - nextRead)<<
" particles", 1);
536 mDeleteChunk = mData.size() / DELETE_PART;
543 IndexInt newCnt = mData.size();
547 for(IndexInt i=0; i<(IndexInt)mData.size(); ++i) mData[i].flag &= ~PNEW;
549 for(IndexInt i=0; i<(IndexInt)
mNewBuffer.size(); ++i) {
552 mData[newCnt].flag = PNEW;
554 for(IndexInt pd=0; pd<(IndexInt)
mPdataReal.size(); ++pd)
556 for(IndexInt pd=0; pd<(IndexInt)mPdataVec3.size(); ++pd)
557 mPdataVec3[pd]->initNewValue(newCnt,
mNewBuffer[i] );
558 for(IndexInt pd=0; pd<(IndexInt)mPdataInt.size(); ++pd)
559 mPdataInt[pd]->initNewValue(newCnt,
mNewBuffer[i] );
562 if(
mNewBuffer.size()>0) debMsg(
"Added & initialized "<<(IndexInt)
mNewBuffer.size()<<
" particles", 2);
567 template<
class DATA,
class CON>
570 IndexInt *renumber_back =
new IndexInt[sz];
571 IndexInt *renumber =
new IndexInt[sz];
572 for (IndexInt i=0; i<sz; i++)
573 renumber[i] = renumber_back[i] = -1;
577 IndexInt nextRead = sz;
578 for (IndexInt i=0; i<nextRead; i++) {
579 if ((data[i].flag & ParticleBase::PDELETE) != 0) {
581 data[i] = data[nextRead];
582 data[nextRead].flag = 0;
583 renumber_back[i] = nextRead;
585 renumber_back[i] = i;
589 for (IndexInt i=0; i<nextRead; i++)
590 renumber[renumber_back[i]] = i;
593 for (IndexInt i=0; i<(IndexInt)mSegments.size(); i++)
594 mSegments[i].renumber(renumber);
601 delete[] renumber_back;
610 nm->setName(getName());
615 template<
class DATA,
class CON>
620 nm->
mData = this->mData;
621 nm->mSegments = mSegments;
622 nm->setName(this->getName());
630 s <<
"ParticleSys '" << getName() <<
"'\n-> ";
632 s <<
"parts: " << size();
639 IndexInt mySize = this->size();
640 if (idx<0 || idx > mySize ) {
641 errMsg(
"ParticleBase " <<
" size " << mySize <<
" : index " << idx <<
" out of bound " );
647 if (idx<0 || idx > mySize ) {
648 errMsg(
"ParticleData " <<
" size " << mySize <<
" : index " << idx <<
" out of bound " );
650 if ( mpParticleSys && mpParticleSys->getSizeSlow()!=mySize ) {
651 errMsg(
"ParticleData " <<
" size " << mySize <<
" does not match parent! (" << mpParticleSys->getSizeSlow() <<
") " );
658 for(IndexInt i=0; i<(IndexInt)mData.size(); ++i) mData[i] = 0.;
Definition: particle.h:175
Definition: commonkernels.h:22
ParticleDataBase * getPdata(int i)
access one of the fields
Definition: particle.h:77
void kill(IndexInt idx)
adding and deleting
Definition: particle.h:401
PYTHON() void addParticle(Vec3 pos)
add particles in python
Definition: particle.h:205
Definition: particle.h:269
bool mFreePdata
indicate that pdata of this particle system is copied, and needs to be freed
Definition: particle.h:93
S & operator[](IndexInt idx)
accessors
Definition: particle.h:108
virtual void compress()
reduce storage , called by doCompress
Definition: particle.h:519
std::vector< ParticleDataImpl< Real > * > mPdataReal
lists of different types, for fast operations w/o virtual function calls (all calls necessary per par...
Definition: particle.h:89
PYTHON() int pySize() const
note , special call for python, note - doesnt support more than 2b parts!
Definition: particle.h:116
Vec3 pos
data (note, this size is currently hard coded for uni i/o)
Definition: particle.h:182
Definition: particle.h:234
virtual void cloneParticleData(ParticleBase *nm)
copy all the particle data thats registered with the other particle system to this one ...
Definition: particle.cpp:49
Basic inlined vector class.
Definition: vectorbase.h:71
IndexInt size() const
Definition: particle.h:112
IndexInt mDeletes
deletion count , and interval for re-compressing
Definition: particle.h:161
virtual void compress()
reduce storage , called by doCompress
Definition: particle.h:568
void insertBufferedParticles()
insert buffered positions as new particles, update additional particle data
Definition: particle.h:541
bool isObstacle(IndexInt idx) const
check for different flag types
Definition: grid.h:291
void transformPositions(Vec3i dimOld, Vec3i dimNew)
transform coordinate system from one grid size to another (usually upon load)
Definition: particle.h:421
int getStatus(IndexInt idx) const
query status
Definition: particle.h:119
void deregister(ParticleDataBase *pdata)
remove a particle data entry
Definition: particle.cpp:58
Main class for particle systems.
Definition: particle.h:100
Index into other particle system.
Definition: particle.h:220
void doCompress()
explicitly trigger compression from outside
Definition: particle.h:132
void addAllPdata()
add one zero entry to all data fields
Definition: particle.cpp:124
void checkPartIndex(IndexInt idx) const
debugging
Definition: particle.h:645
IndexInt getNumPdata() const
how many are there?
Definition: particle.h:75
static Vec3 pos
Definition: particle.h:228
Definition: particle.h:32
void setParticleSys(ParticleBase *set)
set base pointer
Definition: particle.h:286
std::vector< ParticleDataBase * > mPartData
store particle data , each pointer has its own storage vector of a certain type (int, real, vec3)
Definition: particle.h:87
Vec3 calcGridSizeFactor(Vec3i s1, Vec3i s2)
helper to compute grid conversion factor between local coordinates of two grids
Definition: grid.h:349
void checkPartIndex(IndexInt idx) const
debugging
Definition: particle.h:638
bool mAllowCompress
allow automatic compression / resize? disallowed for, eg, flip particle systems
Definition: particle.h:84
std::vector< BasicParticleData > & getData()
dangerous, get low level access - avoid usage, only used in vortex filament advection for now ...
Definition: particle.h:208
void resize(IndexInt size)
we only need a resize function...
Definition: particle.h:239
void integratePointSet(VelKernel &k, int mode)
Integrate a particle set with a given velocity kernel.
Definition: integrator.h:28
int countParticles(const ParticleDataImpl< int > &t, const int flag)
count by type flag
virtual IndexInt getSizeSlow() const
slow virtual function to query size, do not use in kernels! use size() instead
Definition: particle.h:54
Definition: particle.h:248
void resizeAll(IndexInt newsize)
resize data vector, and all pdata fields
Definition: particle.h:511
virtual IndexInt getSizeSlow() const
interface functions, using assert instead of pure virtual for python compatibility ...
Definition: particle.h:278
virtual IndexInt getSizeSlow() const
slow virtual function of base class, also returns size
Definition: particle.h:114
std::vector< S > mData
the particle data
Definition: particle.h:163
bool isSegActive(int i)
accessors
Definition: particle.h:253
void copyValue(IndexInt from, IndexInt to)
fast inlined functions for per particle operations
Definition: particle.h:327
std::vector< Vec3 > mNewBuffer
new particle candidates
Definition: particle.h:81
void addBuffered(const Vec3 &pos)
add a position as potential candidate for new particle (todo, make usable from parallel threads) ...
Definition: particle.h:382
void registerPdata(ParticleDataBase *pdata)
add a particle data field, set its parent particle-system pointer
Definition: particle.cpp:100
Definition: particle.h:187
Definition: fluidsolver.h:28
PdataType
data type IDs, in line with those for grids
Definition: particle.h:275