Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--intern/elbeem/SConscript14
-rw-r--r--intern/elbeem/extern/LBM_fluidsim.h4
-rw-r--r--intern/elbeem/intern/attributes.cpp190
-rw-r--r--intern/elbeem/intern/attributes.h51
-rw-r--r--intern/elbeem/intern/blendercall.cpp44
-rw-r--r--intern/elbeem/intern/blenderdummy.cpp19
-rw-r--r--intern/elbeem/intern/cfglexer.cpp697
-rw-r--r--intern/elbeem/intern/cfgparser.cpp234
-rw-r--r--intern/elbeem/intern/cfgparser.h2
-rw-r--r--intern/elbeem/intern/elbeem.cpp221
-rw-r--r--intern/elbeem/intern/elbeem.h107
-rw-r--r--intern/elbeem/intern/globals.h26
-rw-r--r--intern/elbeem/intern/isosurface.cpp477
-rw-r--r--intern/elbeem/intern/isosurface.h36
-rw-r--r--intern/elbeem/intern/ntl_blenderdumper.cpp125
-rw-r--r--intern/elbeem/intern/ntl_bsptree.cpp22
-rw-r--r--intern/elbeem/intern/ntl_bsptree.h12
-rw-r--r--intern/elbeem/intern/ntl_geometryclass.h8
-rw-r--r--intern/elbeem/intern/ntl_geometrymodel.cpp146
-rw-r--r--intern/elbeem/intern/ntl_geometryobject.cpp464
-rw-r--r--intern/elbeem/intern/ntl_geometryobject.h100
-rw-r--r--intern/elbeem/intern/ntl_geometryshader.h3
-rw-r--r--intern/elbeem/intern/ntl_lighting.cpp (renamed from intern/elbeem/intern/ntl_lightobject.cpp)46
-rw-r--r--intern/elbeem/intern/ntl_lighting.h (renamed from intern/elbeem/intern/ntl_material.h)129
-rw-r--r--intern/elbeem/intern/ntl_lightobject.h91
-rw-r--r--intern/elbeem/intern/ntl_matrices.h55
-rw-r--r--intern/elbeem/intern/ntl_ray.cpp264
-rw-r--r--intern/elbeem/intern/ntl_ray.h285
-rw-r--r--intern/elbeem/intern/ntl_renderglobals.h365
-rw-r--r--intern/elbeem/intern/ntl_rndstream.h127
-rw-r--r--intern/elbeem/intern/ntl_scene.cpp235
-rw-r--r--intern/elbeem/intern/ntl_scene.h167
-rw-r--r--intern/elbeem/intern/ntl_triangle.h183
-rw-r--r--intern/elbeem/intern/ntl_vector3dim.h1
-rw-r--r--intern/elbeem/intern/ntl_world.cpp285
-rw-r--r--intern/elbeem/intern/ntl_world.h283
-rw-r--r--intern/elbeem/intern/parametrizer.cpp334
-rw-r--r--intern/elbeem/intern/parametrizer.h111
-rw-r--r--intern/elbeem/intern/particletracer.cpp254
-rw-r--r--intern/elbeem/intern/particletracer.h147
-rw-r--r--intern/elbeem/intern/simulation_object.cpp142
-rw-r--r--intern/elbeem/intern/simulation_object.h40
-rw-r--r--intern/elbeem/intern/solver_class.h370
-rw-r--r--intern/elbeem/intern/solver_dimenions.h21
-rw-r--r--intern/elbeem/intern/solver_init.cpp1460
-rw-r--r--intern/elbeem/intern/solver_interface.cpp357
-rw-r--r--intern/elbeem/intern/solver_interface.h544
-rw-r--r--intern/elbeem/intern/solver_main.cpp940
-rw-r--r--intern/elbeem/intern/solver_relax.h457
-rw-r--r--intern/elbeem/intern/solver_util.cpp1017
-rw-r--r--intern/elbeem/intern/utilities.cpp18
-rw-r--r--intern/elbeem/intern/utilities.h6
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c219
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c4
-rw-r--r--source/blender/blenkernel/intern/effect.c104
-rw-r--r--source/blender/blenkernel/intern/ipo.c7
-rw-r--r--source/blender/blenloader/intern/readfile.c4
-rw-r--r--source/blender/include/BSE_editipo.h1
-rw-r--r--source/blender/include/butspace.h3
-rw-r--r--source/blender/makesdna/DNA_ID.h1
-rw-r--r--source/blender/makesdna/DNA_ipo_types.h20
-rw-r--r--source/blender/makesdna/DNA_object_fluidsim.h39
-rw-r--r--source/blender/render/intern/source/convertblender.c243
-rw-r--r--source/blender/src/buttons_object.c115
-rw-r--r--source/blender/src/drawobject.c12
-rw-r--r--source/blender/src/editipo.c52
-rw-r--r--source/blender/src/editipo_lib.c7
-rw-r--r--source/blender/src/editipo_mods.c1
-rw-r--r--source/blender/src/fluidsim.c1036
-rw-r--r--source/blender/src/header_ipo.c14
70 files changed, 8149 insertions, 5469 deletions
diff --git a/intern/elbeem/SConscript b/intern/elbeem/SConscript
index 8c1aa59170c..3044ecff0b7 100644
--- a/intern/elbeem/SConscript
+++ b/intern/elbeem/SConscript
@@ -1,21 +1,9 @@
#!/usr/bin/python
import sys
import os
-Import('env')
-
-#if use_fluidsim=='false':
-# # print "El'Beem Fluid Simulation Disabled..." # debug
-# elbeem_env.Append (CPPPATH = user_options_dict['PNG_INCLUDE'])
-# elbeem_env.Append (CPPPATH = user_options_dict['SDL_INCLUDE'])
-# elbeem_env.Append(CPPDEFINES= 'ELBEEM_DUMMIES');
-# # dummy interface build
-# Sources = [
-# "intern/utilities.cpp",
-# "intern/blenderdummy.cpp"
-# ]; # sources
+import('env')
sources = env.Glob('intern/*.cpp')
-sources.remove('intern'+os.sep+'blenderdummy.cpp')
defs = 'NOGUI ELBEEM_BLENDER=1'
if env['OURPLATFORM']=='win32-vc':
diff --git a/intern/elbeem/extern/LBM_fluidsim.h b/intern/elbeem/extern/LBM_fluidsim.h
index ff0b0a465dd..b879dd41396 100644
--- a/intern/elbeem/extern/LBM_fluidsim.h
+++ b/intern/elbeem/extern/LBM_fluidsim.h
@@ -53,7 +53,7 @@ void fluidsimBake(struct Object* ob);
/* read & write bobj / bobj.gz files (e.g. for fluid sim surface meshes) */
void writeBobjgz(char *filename, struct Object *ob);
-struct Mesh* readBobjgz(char *filename, struct Mesh *orgmesh);
+struct Mesh* readBobjgz(char *filename, struct Mesh *orgmesh, float* bbstart, float *bbsize);
/* create derived mesh for fluid sim objects */
// WARNING - currently implemented in DerivedMesh.c!
@@ -66,7 +66,7 @@ int performElbeemSimulation(char *cfgfilename);
/* init axis aligned BB for mesh object */
// implemented in source/blender/blenkernel/intern/DerivedMesh.c
void fluidsimGetAxisAlignedBB(struct Mesh *mesh, float obmat[][4],
- /*RET*/ float start[3], /*RET*/ float size[3] );
+ /*RET*/ float start[3], /*RET*/ float size[3], /*RET*/ struct Mesh **bbmesh );
// implemented in intern/elbeem/utilities.cpp
/* set elbeem debug output level (0=off to 10=full on) */
diff --git a/intern/elbeem/intern/attributes.cpp b/intern/elbeem/intern/attributes.cpp
index 8689a3fe98e..abdd931a4bf 100644
--- a/intern/elbeem/intern/attributes.cpp
+++ b/intern/elbeem/intern/attributes.cpp
@@ -8,12 +8,17 @@
*****************************************************************************/
#include "attributes.h"
+#include "ntl_matrices.h"
+#include "elbeem.h"
#include <sstream>
//! output attribute values? on=1/off=0
#define DEBUG_ATTRIBUTES 0
+//! output channel values? on=1/off=0
+#define DEBUG_CHANNELS 0
+
/******************************************************************************
* attribute conversion functions
@@ -70,20 +75,19 @@ bool Attribute::initChannel(int elemSize) {
mValue = newvalue;
mChannelInited = elemSize;
- print();
+ if(DEBUG_CHANNELS) print();
return true;
}
// get value as string
-string Attribute::getAsString()
+string Attribute::getAsString(bool debug)
{
- if(mIsChannel) {
+ if(mIsChannel && (!debug)) {
errMsg("Attribute::getAsString", "Attribute \"" << mName << "\" used as string is a channel! Not allowed...");
print();
return string("");
}
if(mValue.size()!=1) {
- //errMsg("Attribute::getAsString", "Attribute \"" << mName << "\" used as string has invalid value '"<< getCompleteString() <<"' ");
// for directories etc. , this might be valid! cutoff "..." first
string comp = getCompleteString();
if(comp.size()<2) return string("");
@@ -215,7 +219,7 @@ ntlVec3d Attribute::getAsVec3d()
}
// get value as 4x4 matrix
-ntlMat4Gfx Attribute::getAsMat4Gfx()
+void Attribute::getAsMat4Gfx(ntlMat4Gfx *mat)
{
bool success = true;
ntlMat4Gfx ret(0.0);
@@ -265,9 +269,10 @@ ntlMat4Gfx Attribute::getAsMat4Gfx()
#if ELBEEM_PLUGIN!=1
gElbeemState = -4; // parse error
#endif
- return ntlMat4Gfx(0.0);
+ *mat = ntlMat4Gfx(0.0);
+ return;
}
- return ret;
+ *mat = ret;
}
@@ -355,7 +360,7 @@ bool AttributeList::checkUnusedParams()
i != mAttrs.end(); i++) {
if((*i).second) {
if(!(*i).second->getUsed()) {
- errMsg("AttributeList::checkUnusedParams", "List "<<mName<<" has unknown parameter '"<<(*i).first<<"' = '"<< mAttrs[(*i).first]->getAsString() <<"' ");
+ errMsg("AttributeList::checkUnusedParams", "List "<<mName<<" has unknown parameter '"<<(*i).first<<"' = '"<< mAttrs[(*i).first]->getAsString(true) <<"' ");
found = true;
}
}
@@ -409,7 +414,7 @@ string AttributeList::readString(string name, string defaultValue, string source
}
if(DEBUG_ATTRIBUTES==1) { debugOut( source << " Var '"<< target <<"' set to '"<< find(name)->getCompleteString() <<"' as type int " , 3); }
find(name)->setUsed(true);
- return find(name)->getAsString();
+ return find(name)->getAsString(false);
}
ntlVec3d AttributeList::readVec3d(string name, ntlVec3d defaultValue, string source,string target, bool needed) {
if(!exists(name)) {
@@ -421,14 +426,16 @@ ntlVec3d AttributeList::readVec3d(string name, ntlVec3d defaultValue, string sou
return find(name)->getAsVec3d();
}
-ntlMat4Gfx AttributeList::readMat4Gfx(string name, ntlMat4Gfx defaultValue, string source,string target, bool needed) {
+void AttributeList::readMat4Gfx(string name, ntlMat4Gfx defaultValue, string source,string target, bool needed, ntlMat4Gfx *mat) {
if(!exists(name)) {
if(needed) { errFatal("AttributeList::readInt","Required attribute '"<<name<<"' for "<< source <<" not set! ", SIMWORLD_INITERROR); }
- return defaultValue;
+ *mat = defaultValue;
+ return;
}
if(DEBUG_ATTRIBUTES==1) { debugOut( source << " Var '"<< target <<"' set to '"<< find(name)->getCompleteString() <<"' as type int " , 3); }
find(name)->setUsed(true);
- return find(name)->getAsMat4Gfx();
+ find(name)->getAsMat4Gfx( mat );
+ return;
}
// set that a parameter can be given, and will be ignored...
@@ -442,15 +449,39 @@ bool AttributeList::ignoreParameter(string name, string source) {
// read channels
AnimChannel<double> AttributeList::readChannelFloat(string name) {
if(!exists(name)) { return AnimChannel<double>(0.0); }
- return find(name)->getChannelFloat();
+ AnimChannel<double> ret = find(name)->getChannelFloat();
+ find(name)->setUsed(true);
+ channelSimplifyd(ret);
+ return ret;
}
AnimChannel<int> AttributeList::readChannelInt(string name) {
if(!exists(name)) { return AnimChannel<int>(0); }
- return find(name)->getChannelInt();
+ AnimChannel<int> ret = find(name)->getChannelInt();
+ find(name)->setUsed(true);
+ channelSimplifyi(ret);
+ return ret;
}
AnimChannel<ntlVec3d> AttributeList::readChannelVec3d(string name) {
if(!exists(name)) { return AnimChannel<ntlVec3d>(0.0); }
- return find(name)->getChannelVec3d();
+ AnimChannel<ntlVec3d> ret = find(name)->getChannelVec3d();
+ find(name)->setUsed(true);
+ channelSimplifyVd(ret);
+ return ret;
+}
+AnimChannel<ntlVec3f> AttributeList::readChannelVec3f(string name) {
+ if(!exists(name)) { return AnimChannel<ntlVec3f>(0.0); }
+
+ AnimChannel<ntlVec3d> convert = find(name)->getChannelVec3d();
+ // convert to float
+ vector<ntlVec3f> vals;
+ for(size_t i=0; i<convert.accessValues().size(); i++) {
+ vals.push_back( vec2F(convert.accessValues()[i]) );
+ }
+ vector<double> times = convert.accessTimes();
+ AnimChannel<ntlVec3f> ret(vals, times);
+ find(name)->setUsed(true);
+ channelSimplifyVf(ret);
+ return ret;
}
/******************************************************************************
@@ -509,7 +540,6 @@ void AttributeList::print()
}
-
/******************************************************************************
* import attributes from other attribute list
*****************************************************************************/
@@ -526,5 +556,133 @@ void AttributeList::import(AttributeList *oal)
}
+/******************************************************************************
+ * channel max finding
+ *****************************************************************************/
+ntlVec3f channelFindMaxVf (AnimChannel<ntlVec3f> channel) {
+ ntlVec3f ret(0.0);
+ float maxLen = 0.0;
+ for(size_t i=0; i<channel.accessValues().size(); i++) {
+ float nlen = normNoSqrt(channel.accessValues()[i]);
+ if(nlen>maxLen) { ret=channel.accessValues()[i]; maxLen=nlen; }
+ }
+ return ret;
+}
+ntlVec3d channelFindMaxVd (AnimChannel<ntlVec3d> channel) {
+ ntlVec3d ret(0.0);
+ float maxLen = 0.0;
+ for(size_t i=0; i<channel.accessValues().size(); i++) {
+ float nlen = normNoSqrt(channel.accessValues()[i]);
+ if(nlen>maxLen) { ret=channel.accessValues()[i]; maxLen=nlen; }
+ }
+ return ret;
+}
+int channelFindMaxi (AnimChannel<float > channel) {
+ int ret = 0;
+ float maxLen = 0.0;
+ for(size_t i=0; i<channel.accessValues().size(); i++) {
+ float nlen = ABS(channel.accessValues()[i]);
+ if(nlen>maxLen) { ret= (int)channel.accessValues()[i]; maxLen=nlen; }
+ }
+ return ret;
+}
+float channelFindMaxf (AnimChannel<float > channel) {
+ float ret = 0.0;
+ float maxLen = 0.0;
+ for(size_t i=0; i<channel.accessValues().size(); i++) {
+ float nlen = ABS(channel.accessValues()[i]);
+ if(nlen>maxLen) { ret=channel.accessValues()[i]; maxLen=nlen; }
+ }
+ return ret;
+}
+double channelFindMaxd (AnimChannel<double > channel) {
+ double ret = 0.0;
+ float maxLen = 0.0;
+ for(size_t i=0; i<channel.accessValues().size(); i++) {
+ float nlen = ABS(channel.accessValues()[i]);
+ if(nlen>maxLen) { ret=channel.accessValues()[i]; maxLen=nlen; }
+ }
+ return ret;
+}
+
+/******************************************************************************
+ // unoptimized channel simplification functions, use elbeem.cpp functions
+ // warning - currently only with single precision
+ *****************************************************************************/
+
+template<class SCALAR>
+static bool channelSimplifyScalarT(AnimChannel<SCALAR> &channel) {
+ int size = channel.getSize();
+ if(size<=1) return false;
+ float *nchannel = new float[2*size];
+ if(DEBUG_CHANNELS) errMsg("channelSimplifyf","S" << channel.printChannel() );
+ // convert to array
+ for(size_t i=0; i<channel.accessValues().size(); i++) {
+ nchannel[i*2 + 0] = (float)channel.accessValues()[i];
+ nchannel[i*2 + 1] = (float)channel.accessTimes()[i];
+ }
+ bool ret = elbeemSimplifyChannelFloat(nchannel, &size);
+ if(ret) {
+ vector<SCALAR> vals;
+ vector<double> times;
+ for(int i=0; i<size; i++) {
+ vals.push_back( (SCALAR)(nchannel[i*2 + 0]) );
+ times.push_back( (double)(nchannel[i*2 + 1]) );
+ }
+ channel = AnimChannel<SCALAR>(vals, times);
+ if(DEBUG_CHANNELS) errMsg("channelSimplifyf","C" << channel.printChannel() );
+ }
+ delete [] nchannel;
+ return ret;
+}
+bool channelSimplifyi (AnimChannel<int > &channel) { return channelSimplifyScalarT<int>(channel); }
+bool channelSimplifyf (AnimChannel<float> &channel) { return channelSimplifyScalarT<float>(channel); }
+bool channelSimplifyd (AnimChannel<double > &channel) { return channelSimplifyScalarT<double>(channel); }
+template<class VEC>
+static bool channelSimplifyVecT(AnimChannel<VEC> &channel) {
+ int size = channel.getSize();
+ if(size<=1) return false;
+ float *nchannel = new float[4*size];
+ if(DEBUG_CHANNELS) errMsg("channelSimplifyf","S" << channel.printChannel() );
+ // convert to array
+ for(size_t i=0; i<channel.accessValues().size(); i++) {
+ nchannel[i*4 + 0] = (float)channel.accessValues()[i][0];
+ nchannel[i*4 + 1] = (float)channel.accessValues()[i][1];
+ nchannel[i*4 + 2] = (float)channel.accessValues()[i][2];
+ nchannel[i*4 + 3] = (float)channel.accessTimes()[i];
+ }
+ bool ret = elbeemSimplifyChannelVec3(nchannel, &size);
+ if(ret) {
+ vector<VEC> vals;
+ vector<double> times;
+ for(int i=0; i<size; i++) {
+ vals.push_back( VEC(nchannel[i*4 + 0], nchannel[i*4 + 1], nchannel[i*4 + 2] ) );
+ times.push_back( (double)(nchannel[i*4 + 3]) );
+ }
+ channel = AnimChannel<VEC>(vals, times);
+ if(DEBUG_CHANNELS) errMsg("channelSimplifyf","C" << channel.printChannel() );
+ }
+ delete [] nchannel;
+ return ret;
+}
+bool channelSimplifyVf (AnimChannel<ntlVec3f> &channel) {
+ return channelSimplifyVecT<ntlVec3f>(channel);
+}
+bool channelSimplifyVd (AnimChannel<ntlVec3d> &channel) {
+ return channelSimplifyVecT<ntlVec3d>(channel);
+}
+
+template<class Scalar>
+string AnimChannel<Scalar>::printChannel() {
+ std::ostringstream ostr;
+ ostr << " CHANNEL #"<< mValue.size() <<" = { ";
+ for(size_t i=0;i<mValue.size();i++) {
+ ostr <<"'"<< mValue[i]<<"' ";
+ ostr << "@"<<mTimes[i]<<"; ";
+ }
+ ostr << " } ";
+ return ostr.str();
+} // */
+
diff --git a/intern/elbeem/intern/attributes.h b/intern/elbeem/intern/attributes.h
index f9f44e2eb52..730e136f962 100644
--- a/intern/elbeem/intern/attributes.h
+++ b/intern/elbeem/intern/attributes.h
@@ -11,7 +11,7 @@
#ifndef NTL_ATTRIBUTES_H
#include "utilities.h"
-#include "ntl_matrices.h"
+template<class T> class ntlMatrix4x4;
//! An animated attribute channel
@@ -19,19 +19,24 @@ template<class Scalar>
class AnimChannel
{
public:
+ // default constructor
+ AnimChannel() :
+ mValue(), mTimes() { mInited = false; }
+
// null init constructor
AnimChannel(Scalar null) :
- mValue(1), mTimes(1) { mValue[0]=null; mTimes[0]=0.0; };
+ mValue(1), mTimes(1) { mValue[0]=null; mTimes[0]=0.0; mInited = true; }
// proper init
AnimChannel(vector<Scalar> v, vector<double> t) :
- mValue(v), mTimes(t) { };
+ mValue(v), mTimes(t) { mInited = true; }
// desctructor, nothing to do
~AnimChannel() { };
// get interpolated value at time t
Scalar get(double t) {
+ if(!mInited) { Scalar null; null=(Scalar)(0.0); return null; }
if(t<=mTimes[0]) { return mValue[0]; }
if(t>=mTimes[mTimes.size()-1]) { return mValue[mTimes.size()-1]; }
for(size_t i=0; i<mTimes.size()-1; i++) {
@@ -40,7 +45,7 @@ class AnimChannel
// interpolate
double d = mTimes[i+1]-mTimes[i];
double f = (t-mTimes[i])/d;
- return mValue[i] * (1.0-f) + mValue[i+1] * f;
+ return (Scalar)(mValue[i] * (1.0-f) + mValue[i+1] * f);
}
}
// whats this...?
@@ -50,6 +55,7 @@ class AnimChannel
// get uninterpolated value at time t
Scalar getConstant(double t) {
//errMsg("DEBB","getc"<<t<<" ");
+ if(!mInited) { Scalar null; null=(Scalar)0.0; return null; }
if(t<=mTimes[0]) { return mValue[0]; }
if(t>=mTimes[mTimes.size()-1]) { return mValue[mTimes.size()-1]; }
for(size_t i=0; i<mTimes.size()-1; i++) {
@@ -69,14 +75,29 @@ class AnimChannel
mTimes.push_back(0.0);
}
+ //! debug function, prints channel as string
+ string printChannel();
+ //! valid init?
+ bool isInited() { return mInited; }
+
+ //! get number of entries (value and time sizes have to be equal)
+ int getSize() { return mValue.size(); };
+ //! raw access of value vector
+ vector<Scalar> &accessValues() { return mValue; }
+ //! raw access of time vector
+ vector<double> &accessTimes() { return mTimes; }
+
protected:
+ /*! inited at least once? */
+ bool mInited;
/*! anim channel attribute values */
vector<Scalar> mValue;
/*! anim channel attr times */
vector<double> mTimes;
};
+
//! A single attribute
class Attribute
{
@@ -106,7 +127,7 @@ class Attribute
bool getIsChannel() { return mIsChannel; }
//! get value as string
- string getAsString();
+ string getAsString(bool debug=false);
//! get value as integer value
int getAsInt();
//! get value as boolean
@@ -116,13 +137,13 @@ class Attribute
//! get value as 3d vector
ntlVec3d getAsVec3d();
//! get value as 4x4 matrix
- ntlMat4Gfx getAsMat4Gfx();
+ void getAsMat4Gfx(ntlMatrix4x4<gfxReal> *mat);
//! get channel as integer value
AnimChannel<int> getChannelInt();
//! get channel as double value
AnimChannel<double> getChannelFloat();
- //! get channel as double value
+ //! get channel as double vector
AnimChannel<ntlVec3d> getChannelVec3d();
//! get the concatenated string of all value string
@@ -207,11 +228,12 @@ class AttributeList
double readFloat(string name, double defaultValue, string source,string target, bool needed);
string readString(string name, string defaultValue, string source,string target, bool needed);
ntlVec3d readVec3d(string name, ntlVec3d defaultValue, string source,string target, bool needed);
- ntlMat4Gfx readMat4Gfx(string name, ntlMat4Gfx defaultValue, string source,string target, bool needed);
+ void readMat4Gfx(string name, ntlMatrix4x4<gfxReal> defaultValue, string source,string target, bool needed, ntlMatrix4x4<gfxReal> *mat);
//! read attributes channels (attribute should be inited before)
AnimChannel<int> readChannelInt(string name);
AnimChannel<double> readChannelFloat(string name);
AnimChannel<ntlVec3d> readChannelVec3d(string name);
+ AnimChannel<ntlVec3f> readChannelVec3f(string name);
//! set that a parameter can be given, and will be ignored...
bool ignoreParameter(string name, string source);
@@ -229,6 +251,19 @@ class AttributeList
};
+ntlVec3f channelFindMaxVf (AnimChannel<ntlVec3f> channel);
+ntlVec3d channelFindMaxVd (AnimChannel<ntlVec3d> channel);
+int channelFindMaxi (AnimChannel<int > channel);
+float channelFindMaxf (AnimChannel<float > channel);
+double channelFindMaxd (AnimChannel<double > channel);
+
+// unoptimized channel simplification functions, use elbeem.cpp functions
+bool channelSimplifyVf (AnimChannel<ntlVec3f> &channel);
+bool channelSimplifyVd (AnimChannel<ntlVec3d> &channel);
+bool channelSimplifyi (AnimChannel<int > &channel);
+bool channelSimplifyf (AnimChannel<float > &channel);
+bool channelSimplifyd (AnimChannel<double > &channel);
+
#define NTL_ATTRIBUTES_H
#endif
diff --git a/intern/elbeem/intern/blendercall.cpp b/intern/elbeem/intern/blendercall.cpp
deleted file mode 100644
index f1617da8296..00000000000
--- a/intern/elbeem/intern/blendercall.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-/******************************************************************************
- *
- * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method
- * 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 2003-2005 Nils Thuerey
- *
- * Blender call interface
- *
- *****************************************************************************/
-
-#include "globals.h"
-#include "utilities.h"
-#include "ntl_blenderdumper.h"
-#include <stdlib.h>
-
-// ELBEEM_BLENDER always =1 here
-extern "C" void elbeemCheckDebugEnv(void);
-
-extern "C"
-int performElbeemSimulation(char *cfgfilename) {
- gElbeemState = SIMWORLD_INVALID;
- strcpy(gElbeemErrorString,"[none]");
-
- //if(gDebugLevel>0) {
- elbeemCheckDebugEnv();
- debMsgStd("performElbeemSimulation",DM_NOTIFY,"Running El'Beem from Blender with file '"<< cfgfilename <<"', debugLevel:"<<gDebugLevel<<" ...\n", 2);
- //}
- // load given file in command line mode
- ntlBlenderDumper elbeem(cfgfilename, true);
- if(SIMWORLD_OK()) {
- gElbeemState = SIMWORLD_INITED;
- myTime_t timestart = getTime();
- elbeem.renderAnimation();
- myTime_t timeend = getTime();
- debMsgStd("performElbeemSimulation",DM_NOTIFY, "El'Beem simulation done, time: "<<((timeend-timestart)/(double)1000.0) <<" seconds.\n", 2 );
- } else {
- // signal there was an initialization problem
- setGlobalBakeState( -2 );
- }
- return 1;
-};
-
-
diff --git a/intern/elbeem/intern/blenderdummy.cpp b/intern/elbeem/intern/blenderdummy.cpp
deleted file mode 100644
index 4d672dee528..00000000000
--- a/intern/elbeem/intern/blenderdummy.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-/******************************************************************************
- *
- * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method
- * 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 2003-2005 Nils Thuerey
- *
- * Blender call for disabled fluidsim
- *
- *****************************************************************************/
-
-#include <stdlib.h>
-
-extern "C"
-int performElbeemSimulation(char *cfgfilename) {
- return 1;
-};
-
-
diff --git a/intern/elbeem/intern/cfglexer.cpp b/intern/elbeem/intern/cfglexer.cpp
index 472c6929451..0bc9d96b5b2 100644
--- a/intern/elbeem/intern/cfglexer.cpp
+++ b/intern/elbeem/intern/cfglexer.cpp
@@ -430,16 +430,16 @@ static yyconst flex_int32_t yy_ec[256] =
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 4, 1, 5, 6, 1, 1, 1, 1, 1,
- 1, 7, 1, 1, 8, 9, 10, 11, 11, 11,
- 11, 11, 11, 11, 11, 11, 11, 12, 13, 1,
- 14, 1, 1, 1, 17, 18, 19, 20, 21, 22,
- 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
- 33, 34, 35, 36, 37, 38, 39, 40, 41, 33,
- 1, 15, 1, 1, 16, 1, 17, 18, 19, 20,
-
- 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
- 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
- 41, 33, 42, 1, 43, 1, 1, 1, 1, 1,
+ 1, 7, 8, 1, 9, 10, 11, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 13, 14, 1,
+ 15, 1, 1, 1, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
+ 34, 35, 36, 37, 38, 39, 40, 41, 42, 34,
+ 1, 16, 1, 1, 17, 1, 18, 19, 20, 21,
+
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
+ 42, 34, 43, 1, 44, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -456,103 +456,103 @@ static yyconst flex_int32_t yy_ec[256] =
1, 1, 1, 1, 1
} ;
-static yyconst flex_int32_t yy_meta[44] =
+static yyconst flex_int32_t yy_meta[45] =
{ 0,
- 1, 2, 3, 4, 1, 1, 1, 5, 6, 5,
- 6, 5, 2, 1, 5, 6, 6, 6, 6, 6,
+ 1, 2, 3, 4, 1, 1, 1, 5, 5, 6,
+ 5, 6, 5, 2, 1, 5, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 1, 1
+ 6, 6, 1, 1
} ;
-static yyconst flex_int16_t yy_base[576] =
+static yyconst flex_int16_t yy_base[575] =
{ 0,
- 0, 0, 43, 86, 128, 170, 704, 705, 60, 705,
- 63, 0, 0, 43, 692, 53, 50, 47, 53, 78,
- 47, 39, 87, 681, 43, 82, 54, 80, 117, 92,
- 93, 112, 116, 669, 99, 123, 138, 149, 152, 0,
- 141, 0, 695, 156, 101, 705, 157, 160, 163, 175,
- 180, 694, 0, 687, 176, 686, 705, 0, 177, 660,
- 677, 153, 662, 657, 673, 101, 651, 161, 46, 175,
- 178, 670, 668, 660, 659, 649, 647, 186, 653, 645,
- 651, 658, 649, 168, 645, 649, 648, 650, 653, 644,
- 705, 652, 641, 174, 630, 192, 653, 131, 652, 633,
-
- 198, 635, 628, 631, 629, 214, 219, 222, 226, 0,
- 227, 0, 658, 657, 230, 0, 235, 705, 0, 636,
- 635, 146, 634, 637, 623, 629, 625, 624, 705, 617,
- 617, 620, 618, 612, 623, 619, 624, 705, 613, 609,
- 622, 617, 600, 611, 604, 609, 616, 601, 611, 607,
- 612, 598, 597, 609, 206, 600, 705, 603, 597, 596,
- 584, 599, 587, 601, 587, 600, 588, 598, 598, 595,
- 581, 578, 583, 591, 590, 589, 588, 572, 582, 238,
- 568, 584, 570, 567, 585, 582, 575, 576, 578, 567,
- 561, 559, 183, 577, 570, 562, 570, 553, 558, 567,
-
- 216, 567, 705, 565, 555, 563, 549, 545, 545, 563,
- 545, 561, 546, 705, 545, 554, 543, 705, 550, 549,
- 548, 534, 535, 543, 550, 545, 537, 533, 526, 528,
- 525, 531, 524, 529, 705, 705, 538, 535, 537, 533,
- 523, 535, 534, 522, 513, 530, 513, 525, 705, 521,
- 519, 705, 509, 508, 221, 520, 521, 504, 513, 705,
- 506, 519, 507, 499, 512, 496, 495, 496, 705, 493,
- 503, 486, 492, 497, 490, 503, 494, 705, 490, 495,
- 502, 480, 498, 482, 478, 475, 485, 491, 705, 480,
- 193, 493, 705, 469, 480, 705, 471, 477, 471, 479,
-
- 705, 466, 471, 467, 483, 480, 705, 477, 476, 465,
- 470, 478, 457, 471, 461, 470, 460, 470, 460, 458,
- 451, 705, 462, 705, 466, 462, 705, 440, 444, 458,
- 461, 447, 445, 456, 453, 448, 453, 435, 441, 452,
- 705, 448, 221, 450, 426, 705, 444, 436, 442, 426,
- 444, 424, 422, 441, 437, 227, 428, 417, 434, 413,
- 435, 417, 705, 414, 428, 427, 418, 421, 705, 404,
- 427, 415, 421, 418, 415, 411, 402, 705, 407, 411,
- 400, 404, 416, 407, 414, 396, 408, 408, 391, 392,
- 227, 705, 400, 219, 705, 389, 402, 392, 385, 389,
-
- 385, 394, 231, 399, 395, 394, 393, 377, 387, 705,
- 705, 705, 705, 379, 705, 391, 705, 377, 377, 388,
- 705, 370, 705, 375, 380, 383, 365, 370, 368, 705,
- 705, 374, 379, 376, 375, 361, 371, 705, 368, 705,
- 357, 371, 354, 350, 354, 356, 369, 351, 355, 355,
- 705, 354, 345, 361, 705, 358, 342, 347, 355, 341,
- 351, 356, 351, 336, 340, 351, 332, 336, 336, 333,
- 339, 339, 333, 705, 705, 327, 325, 342, 322, 325,
- 335, 705, 705, 705, 321, 705, 705, 330, 318, 317,
- 705, 705, 331, 310, 313, 705, 323, 322, 318, 326,
-
- 308, 326, 306, 320, 705, 705, 320, 308, 705, 308,
- 312, 705, 705, 705, 305, 705, 310, 317, 295, 705,
- 311, 307, 300, 705, 705, 236, 299, 305, 309, 287,
- 306, 289, 302, 705, 705, 299, 296, 296, 281, 274,
- 267, 264, 263, 705, 705, 269, 258, 261, 705, 267,
- 250, 705, 705, 245, 225, 222, 705, 212, 166, 705,
- 705, 155, 705, 705, 705, 268, 274, 277, 283, 113,
- 289, 295, 301, 307, 313
+ 0, 0, 44, 0, 87, 130, 713, 714, 95, 714,
+ 102, 0, 0, 84, 700, 96, 90, 85, 91, 92,
+ 86, 83, 122, 689, 82, 85, 101, 111, 133, 118,
+ 137, 128, 125, 677, 136, 124, 166, 167, 173, 0,
+ 174, 0, 704, 177, 173, 714, 181, 185, 188, 191,
+ 192, 703, 0, 695, 187, 694, 714, 0, 188, 668,
+ 685, 175, 670, 665, 681, 180, 659, 167, 178, 190,
+ 192, 678, 676, 668, 667, 657, 655, 200, 661, 653,
+ 659, 666, 657, 182, 653, 657, 656, 658, 661, 652,
+ 714, 660, 649, 191, 638, 205, 661, 199, 660, 641,
+
+ 208, 643, 636, 639, 637, 231, 235, 236, 240, 0,
+ 241, 0, 667, 666, 245, 0, 246, 714, 0, 644,
+ 643, 229, 642, 645, 631, 637, 633, 632, 714, 625,
+ 625, 628, 626, 620, 631, 627, 632, 714, 621, 617,
+ 630, 625, 608, 619, 612, 617, 624, 609, 619, 615,
+ 620, 606, 605, 617, 222, 608, 714, 611, 605, 604,
+ 592, 607, 595, 609, 595, 608, 596, 606, 606, 603,
+ 589, 586, 591, 599, 598, 597, 596, 580, 590, 252,
+ 576, 592, 578, 575, 593, 590, 583, 584, 586, 575,
+ 569, 567, 229, 585, 578, 570, 578, 561, 566, 575,
+
+ 227, 575, 714, 573, 563, 571, 557, 553, 553, 571,
+ 553, 569, 554, 714, 553, 562, 551, 714, 558, 557,
+ 556, 542, 543, 551, 558, 553, 545, 541, 534, 536,
+ 533, 539, 532, 537, 714, 714, 546, 543, 545, 541,
+ 531, 543, 542, 530, 521, 538, 521, 533, 714, 529,
+ 527, 714, 517, 516, 239, 528, 529, 512, 521, 714,
+ 514, 527, 515, 507, 520, 504, 503, 504, 714, 501,
+ 511, 494, 500, 505, 498, 511, 502, 714, 498, 503,
+ 510, 488, 506, 490, 486, 483, 493, 499, 714, 488,
+ 244, 501, 714, 477, 488, 714, 479, 485, 479, 487,
+
+ 714, 474, 479, 475, 491, 488, 714, 485, 484, 473,
+ 478, 486, 465, 479, 469, 478, 468, 478, 468, 466,
+ 459, 714, 470, 714, 474, 470, 714, 448, 452, 466,
+ 469, 455, 453, 464, 461, 456, 461, 443, 449, 460,
+ 714, 456, 249, 458, 434, 714, 452, 444, 450, 434,
+ 452, 432, 430, 449, 445, 245, 436, 425, 442, 421,
+ 443, 425, 714, 422, 436, 435, 426, 429, 714, 412,
+ 435, 423, 429, 426, 423, 419, 410, 714, 415, 419,
+ 408, 412, 424, 415, 422, 404, 416, 416, 399, 400,
+ 252, 714, 408, 238, 714, 397, 410, 400, 393, 397,
+
+ 393, 402, 246, 407, 403, 402, 401, 385, 395, 714,
+ 714, 714, 714, 387, 714, 399, 714, 385, 385, 396,
+ 714, 378, 714, 383, 388, 391, 373, 378, 376, 714,
+ 714, 382, 387, 384, 383, 369, 379, 714, 376, 714,
+ 365, 379, 362, 358, 362, 364, 377, 359, 363, 363,
+ 714, 362, 353, 369, 714, 366, 350, 355, 363, 349,
+ 359, 364, 359, 344, 348, 359, 340, 344, 344, 341,
+ 347, 347, 341, 714, 714, 335, 333, 350, 330, 333,
+ 343, 714, 714, 714, 329, 714, 714, 338, 326, 325,
+ 714, 714, 339, 318, 321, 714, 331, 330, 326, 334,
+
+ 316, 334, 314, 328, 714, 714, 328, 316, 714, 316,
+ 320, 714, 714, 714, 313, 714, 318, 325, 303, 714,
+ 319, 315, 305, 714, 714, 261, 299, 300, 300, 278,
+ 297, 277, 290, 714, 714, 287, 280, 268, 256, 254,
+ 252, 252, 251, 714, 714, 256, 248, 231, 714, 228,
+ 197, 714, 714, 207, 167, 149, 714, 150, 106, 714,
+ 714, 101, 714, 714, 714, 294, 297, 303, 89, 309,
+ 315, 321, 327, 333
} ;
-static yyconst flex_int16_t yy_def[576] =
+static yyconst flex_int16_t yy_def[575] =
{ 0,
- 565, 1, 566, 566, 567, 567, 565, 565, 565, 565,
- 565, 568, 569, 565, 565, 565, 565, 565, 565, 565,
+ 565, 1, 565, 3, 566, 566, 565, 565, 565, 565,
+ 565, 567, 568, 565, 565, 565, 565, 565, 565, 565,
565, 565, 565, 565, 565, 565, 565, 565, 565, 565,
- 565, 565, 565, 565, 565, 565, 565, 565, 565, 570,
- 565, 571, 572, 573, 571, 565, 571, 571, 565, 565,
- 565, 568, 569, 565, 565, 565, 565, 574, 565, 565,
+ 565, 565, 565, 565, 565, 565, 565, 565, 565, 569,
+ 565, 570, 571, 572, 570, 565, 570, 570, 565, 565,
+ 565, 567, 568, 565, 565, 565, 565, 573, 565, 565,
565, 565, 565, 565, 565, 565, 565, 565, 565, 565,
565, 565, 565, 565, 565, 565, 565, 565, 565, 565,
565, 565, 565, 565, 565, 565, 565, 565, 565, 565,
565, 565, 565, 565, 565, 565, 565, 565, 565, 565,
- 565, 565, 565, 565, 565, 565, 565, 565, 565, 570,
- 565, 571, 572, 572, 573, 571, 575, 565, 574, 565,
+ 565, 565, 565, 565, 565, 565, 565, 565, 565, 569,
+ 565, 570, 571, 571, 572, 570, 574, 565, 573, 565,
565, 565, 565, 565, 565, 565, 565, 565, 565, 565,
565, 565, 565, 565, 565, 565, 565, 565, 565, 565,
565, 565, 565, 565, 565, 565, 565, 565, 565, 565,
565, 565, 565, 565, 565, 565, 565, 565, 565, 565,
565, 565, 565, 565, 565, 565, 565, 565, 565, 565,
- 565, 565, 565, 565, 565, 565, 565, 565, 565, 575,
+ 565, 565, 565, 565, 565, 565, 565, 565, 565, 574,
565, 565, 565, 565, 565, 565, 565, 565, 565, 565,
565, 565, 565, 565, 565, 565, 565, 565, 565, 565,
@@ -596,175 +596,177 @@ static yyconst flex_int16_t yy_def[576] =
565, 565, 565, 565, 565, 565, 565, 565, 565, 565,
565, 565, 565, 565, 565, 565, 565, 565, 565, 565,
565, 565, 565, 565, 0, 565, 565, 565, 565, 565,
- 565, 565, 565, 565, 565
+ 565, 565, 565, 565
} ;
-static yyconst flex_int16_t yy_nxt[749] =
+static yyconst flex_int16_t yy_nxt[759] =
{ 0,
- 8, 9, 10, 11, 12, 13, 8, 14, 15, 16,
- 17, 8, 8, 8, 8, 8, 18, 19, 20, 21,
- 22, 23, 24, 8, 25, 8, 8, 26, 27, 28,
- 29, 30, 8, 31, 32, 33, 34, 35, 8, 8,
- 8, 36, 37, 8, 38, 10, 39, 8, 13, 8,
- 8, 54, 16, 55, 8, 8, 41, 8, 54, 57,
- 59, 49, 58, 49, 49, 60, 49, 70, 72, 65,
- 84, 71, 80, 132, 133, 61, 62, 81, 85, 73,
- 66, 63, 64, 67, 36, 37, 8, 38, 10, 39,
- 8, 13, 8, 8, 68, 16, 86, 8, 8, 41,
-
- 8, 50, 51, 74, 50, 51, 82, 116, 69, 95,
- 117, 75, 83, 96, 76, 93, 87, 77, 110, 104,
- 78, 127, 94, 105, 106, 128, 106, 36, 37, 9,
- 10, 11, 43, 44, 88, 97, 100, 45, 89, 107,
- 46, 107, 111, 98, 111, 90, 91, 99, 92, 101,
- 108, 169, 108, 108, 170, 108, 102, 53, 106, 53,
- 106, 107, 109, 107, 49, 109, 49, 183, 53, 47,
- 48, 9, 10, 11, 43, 44, 106, 122, 106, 45,
- 184, 107, 46, 107, 54, 54, 55, 59, 123, 564,
- 50, 51, 134, 50, 51, 130, 135, 131, 136, 137,
-
- 563, 161, 144, 151, 50, 51, 145, 152, 162, 343,
- 164, 47, 48, 165, 173, 106, 252, 106, 174, 253,
- 107, 166, 107, 108, 344, 108, 167, 111, 111, 111,
- 111, 53, 562, 53, 175, 109, 119, 215, 119, 119,
- 388, 119, 53, 216, 261, 262, 435, 119, 309, 310,
- 119, 401, 311, 438, 439, 537, 389, 561, 402, 447,
- 560, 403, 436, 50, 51, 559, 448, 538, 40, 40,
- 40, 40, 40, 40, 42, 42, 42, 42, 42, 42,
- 52, 52, 52, 53, 53, 558, 53, 53, 53, 112,
- 557, 556, 555, 112, 112, 113, 554, 553, 552, 113,
-
- 113, 115, 115, 551, 115, 115, 115, 119, 119, 550,
- 119, 119, 119, 180, 180, 549, 180, 180, 180, 548,
- 547, 546, 545, 544, 543, 542, 541, 540, 539, 536,
- 535, 534, 533, 532, 531, 530, 529, 528, 527, 526,
- 525, 524, 523, 522, 521, 520, 519, 518, 517, 516,
- 515, 514, 513, 512, 511, 510, 509, 508, 507, 506,
- 505, 504, 503, 502, 501, 500, 499, 498, 497, 496,
- 495, 494, 493, 492, 491, 490, 489, 488, 487, 486,
- 485, 484, 483, 482, 481, 480, 479, 478, 477, 476,
- 475, 474, 473, 472, 471, 470, 469, 468, 467, 466,
-
- 465, 464, 463, 462, 461, 460, 459, 458, 457, 456,
- 455, 454, 453, 452, 451, 450, 449, 446, 445, 444,
- 443, 442, 441, 440, 437, 434, 433, 432, 431, 430,
- 429, 428, 427, 426, 425, 424, 423, 422, 421, 420,
- 419, 418, 417, 416, 415, 414, 413, 412, 411, 410,
- 409, 408, 407, 406, 405, 404, 400, 399, 398, 397,
- 396, 395, 394, 393, 392, 391, 390, 387, 386, 385,
- 384, 383, 382, 381, 380, 379, 378, 377, 376, 375,
- 374, 373, 372, 371, 370, 369, 368, 367, 366, 365,
- 364, 363, 362, 361, 360, 359, 358, 357, 356, 355,
-
- 354, 353, 352, 351, 350, 349, 348, 347, 346, 345,
- 342, 341, 340, 339, 338, 337, 336, 335, 334, 333,
- 332, 331, 330, 329, 328, 327, 326, 325, 324, 323,
- 322, 321, 320, 319, 318, 317, 316, 315, 314, 313,
- 312, 308, 307, 306, 305, 304, 303, 302, 301, 300,
- 299, 298, 297, 296, 295, 294, 293, 292, 291, 290,
- 289, 288, 287, 286, 285, 284, 283, 282, 281, 280,
- 279, 278, 277, 276, 275, 274, 273, 272, 271, 270,
- 269, 268, 267, 266, 265, 264, 263, 260, 259, 258,
- 257, 256, 255, 254, 251, 250, 249, 248, 247, 246,
-
- 245, 244, 243, 242, 241, 240, 239, 238, 237, 236,
- 235, 234, 233, 232, 231, 230, 229, 228, 227, 226,
- 225, 224, 223, 222, 221, 220, 219, 218, 217, 214,
- 213, 212, 211, 210, 209, 208, 207, 206, 205, 204,
- 203, 202, 201, 200, 199, 198, 197, 196, 195, 194,
- 193, 192, 191, 190, 189, 188, 187, 186, 185, 182,
- 181, 114, 114, 179, 178, 177, 176, 172, 171, 168,
- 163, 160, 159, 158, 157, 156, 155, 154, 153, 150,
- 149, 148, 147, 146, 143, 142, 141, 140, 139, 138,
- 129, 126, 125, 124, 121, 120, 56, 56, 118, 114,
-
- 103, 79, 56, 565, 7, 565, 565, 565, 565, 565,
+ 8, 9, 10, 11, 12, 13, 8, 8, 14, 15,
+ 16, 17, 8, 8, 8, 8, 8, 18, 19, 20,
+ 21, 22, 23, 24, 8, 25, 8, 8, 26, 27,
+ 28, 29, 30, 8, 31, 32, 33, 34, 35, 8,
+ 8, 8, 36, 37, 8, 38, 10, 39, 8, 13,
+ 8, 8, 8, 40, 16, 40, 8, 8, 41, 8,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 36, 37, 9, 10,
+ 11, 43, 44, 54, 110, 55, 49, 45, 49, 54,
+
+ 46, 59, 57, 49, 60, 49, 58, 70, 65, 68,
+ 82, 71, 80, 72, 61, 62, 83, 81, 84, 66,
+ 63, 64, 67, 69, 73, 106, 85, 106, 86, 47,
+ 48, 9, 10, 11, 43, 44, 564, 50, 51, 74,
+ 45, 563, 93, 46, 50, 51, 100, 75, 87, 94,
+ 76, 88, 97, 77, 95, 89, 78, 104, 96, 101,
+ 98, 105, 90, 91, 99, 92, 102, 107, 108, 107,
+ 108, 562, 47, 48, 108, 111, 108, 111, 53, 116,
+ 53, 109, 106, 117, 106, 561, 107, 109, 107, 49,
+ 53, 49, 106, 107, 106, 107, 54, 54, 55, 59,
+
+ 122, 127, 130, 560, 131, 128, 132, 133, 134, 50,
+ 51, 123, 135, 136, 137, 50, 51, 144, 151, 161,
+ 169, 145, 152, 170, 164, 173, 162, 165, 559, 174,
+ 50, 51, 106, 558, 106, 166, 107, 108, 107, 108,
+ 167, 111, 111, 111, 111, 175, 53, 119, 53, 119,
+ 109, 183, 557, 119, 215, 119, 261, 262, 53, 119,
+ 216, 343, 556, 252, 184, 119, 253, 309, 310, 388,
+ 401, 311, 435, 438, 439, 447, 344, 402, 50, 51,
+ 403, 537, 448, 555, 554, 389, 553, 552, 436, 551,
+ 550, 549, 548, 538, 42, 42, 42, 42, 42, 42,
+
+ 52, 52, 52, 53, 53, 547, 53, 53, 53, 112,
+ 546, 545, 544, 112, 112, 113, 543, 542, 541, 113,
+ 113, 115, 115, 540, 115, 115, 115, 119, 119, 539,
+ 119, 119, 119, 180, 180, 536, 180, 180, 180, 535,
+ 534, 533, 532, 531, 530, 529, 528, 527, 526, 525,
+ 524, 523, 522, 521, 520, 519, 518, 517, 516, 515,
+ 514, 513, 512, 511, 510, 509, 508, 507, 506, 505,
+ 504, 503, 502, 501, 500, 499, 498, 497, 496, 495,
+ 494, 493, 492, 491, 490, 489, 488, 487, 486, 485,
+ 484, 483, 482, 481, 480, 479, 478, 477, 476, 475,
+
+ 474, 473, 472, 471, 470, 469, 468, 467, 466, 465,
+ 464, 463, 462, 461, 460, 459, 458, 457, 456, 455,
+ 454, 453, 452, 451, 450, 449, 446, 445, 444, 443,
+ 442, 441, 440, 437, 434, 433, 432, 431, 430, 429,
+ 428, 427, 426, 425, 424, 423, 422, 421, 420, 419,
+ 418, 417, 416, 415, 414, 413, 412, 411, 410, 409,
+ 408, 407, 406, 405, 404, 400, 399, 398, 397, 396,
+ 395, 394, 393, 392, 391, 390, 387, 386, 385, 384,
+ 383, 382, 381, 380, 379, 378, 377, 376, 375, 374,
+ 373, 372, 371, 370, 369, 368, 367, 366, 365, 364,
+
+ 363, 362, 361, 360, 359, 358, 357, 356, 355, 354,
+ 353, 352, 351, 350, 349, 348, 347, 346, 345, 342,
+ 341, 340, 339, 338, 337, 336, 335, 334, 333, 332,
+ 331, 330, 329, 328, 327, 326, 325, 324, 323, 322,
+ 321, 320, 319, 318, 317, 316, 315, 314, 313, 312,
+ 308, 307, 306, 305, 304, 303, 302, 301, 300, 299,
+ 298, 297, 296, 295, 294, 293, 292, 291, 290, 289,
+ 288, 287, 286, 285, 284, 283, 282, 281, 280, 279,
+ 278, 277, 276, 275, 274, 273, 272, 271, 270, 269,
+ 268, 267, 266, 265, 264, 263, 260, 259, 258, 257,
+
+ 256, 255, 254, 251, 250, 249, 248, 247, 246, 245,
+ 244, 243, 242, 241, 240, 239, 238, 237, 236, 235,
+ 234, 233, 232, 231, 230, 229, 228, 227, 226, 225,
+ 224, 223, 222, 221, 220, 219, 218, 217, 214, 213,
+ 212, 211, 210, 209, 208, 207, 206, 205, 204, 203,
+ 202, 201, 200, 199, 198, 197, 196, 195, 194, 193,
+ 192, 191, 190, 189, 188, 187, 186, 185, 182, 181,
+ 114, 114, 179, 178, 177, 176, 172, 171, 168, 163,
+ 160, 159, 158, 157, 156, 155, 154, 153, 150, 149,
+ 148, 147, 146, 143, 142, 141, 140, 139, 138, 129,
+
+ 126, 125, 124, 121, 120, 56, 56, 118, 114, 103,
+ 79, 56, 565, 7, 565, 565, 565, 565, 565, 565,
565, 565, 565, 565, 565, 565, 565, 565, 565, 565,
565, 565, 565, 565, 565, 565, 565, 565, 565, 565,
565, 565, 565, 565, 565, 565, 565, 565, 565, 565,
565, 565, 565, 565, 565, 565, 565, 565
} ;
-static yyconst flex_int16_t yy_chk[749] =
+static yyconst flex_int16_t yy_chk[759] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 3, 3, 3, 3, 3, 3, 3,
- 3, 14, 3, 14, 3, 3, 3, 3, 17, 16,
- 17, 9, 16, 9, 11, 18, 11, 21, 22, 19,
- 27, 21, 25, 69, 69, 18, 18, 25, 27, 22,
- 19, 18, 18, 19, 3, 3, 4, 4, 4, 4,
- 4, 4, 4, 4, 20, 4, 28, 4, 4, 4,
-
- 4, 9, 9, 23, 11, 11, 26, 45, 20, 31,
- 45, 23, 26, 31, 23, 30, 28, 23, 570, 35,
- 23, 66, 30, 35, 36, 66, 36, 4, 4, 5,
- 5, 5, 5, 5, 29, 32, 33, 5, 29, 37,
- 5, 37, 41, 32, 41, 29, 29, 32, 29, 33,
- 38, 98, 38, 39, 98, 39, 33, 44, 47, 44,
- 47, 48, 38, 48, 49, 39, 49, 122, 44, 5,
- 5, 6, 6, 6, 6, 6, 50, 62, 50, 6,
- 122, 51, 6, 51, 55, 59, 55, 59, 62, 562,
- 38, 38, 70, 39, 39, 68, 70, 68, 71, 71,
-
- 559, 94, 78, 84, 49, 49, 78, 84, 94, 291,
- 96, 6, 6, 96, 101, 106, 193, 106, 101, 193,
- 107, 96, 107, 108, 291, 108, 96, 109, 111, 109,
- 111, 115, 558, 115, 101, 108, 117, 155, 117, 180,
- 343, 180, 115, 155, 201, 201, 391, 117, 255, 255,
- 180, 356, 255, 394, 394, 526, 343, 556, 356, 403,
- 555, 356, 391, 108, 108, 554, 403, 526, 566, 566,
- 566, 566, 566, 566, 567, 567, 567, 567, 567, 567,
- 568, 568, 568, 569, 569, 551, 569, 569, 569, 571,
- 550, 548, 547, 571, 571, 572, 546, 543, 542, 572,
-
- 572, 573, 573, 541, 573, 573, 573, 574, 574, 540,
- 574, 574, 574, 575, 575, 539, 575, 575, 575, 538,
- 537, 536, 533, 532, 531, 530, 529, 528, 527, 523,
- 522, 521, 519, 518, 517, 515, 511, 510, 508, 507,
- 504, 503, 502, 501, 500, 499, 498, 497, 495, 494,
- 493, 490, 489, 488, 485, 481, 480, 479, 478, 477,
- 476, 473, 472, 471, 470, 469, 468, 467, 466, 465,
- 464, 463, 462, 461, 460, 459, 458, 457, 456, 454,
- 453, 452, 450, 449, 448, 447, 446, 445, 444, 443,
- 442, 441, 439, 437, 436, 435, 434, 433, 432, 429,
-
- 428, 427, 426, 425, 424, 422, 420, 419, 418, 416,
- 414, 409, 408, 407, 406, 405, 404, 402, 401, 400,
- 399, 398, 397, 396, 393, 390, 389, 388, 387, 386,
- 385, 384, 383, 382, 381, 380, 379, 377, 376, 375,
- 374, 373, 372, 371, 370, 368, 367, 366, 365, 364,
- 362, 361, 360, 359, 358, 357, 355, 354, 353, 352,
- 351, 350, 349, 348, 347, 345, 344, 342, 340, 339,
- 338, 337, 336, 335, 334, 333, 332, 331, 330, 329,
- 328, 326, 325, 323, 321, 320, 319, 318, 317, 316,
- 315, 314, 313, 312, 311, 310, 309, 308, 306, 305,
-
- 304, 303, 302, 300, 299, 298, 297, 295, 294, 292,
- 290, 288, 287, 286, 285, 284, 283, 282, 281, 280,
- 279, 277, 276, 275, 274, 273, 272, 271, 270, 268,
- 267, 266, 265, 264, 263, 262, 261, 259, 258, 257,
- 256, 254, 253, 251, 250, 248, 247, 246, 245, 244,
- 243, 242, 241, 240, 239, 238, 237, 234, 233, 232,
- 231, 230, 229, 228, 227, 226, 225, 224, 223, 222,
- 221, 220, 219, 217, 216, 215, 213, 212, 211, 210,
- 209, 208, 207, 206, 205, 204, 202, 200, 199, 198,
- 197, 196, 195, 194, 192, 191, 190, 189, 188, 187,
-
- 186, 185, 184, 183, 182, 181, 179, 178, 177, 176,
- 175, 174, 173, 172, 171, 170, 169, 168, 167, 166,
- 165, 164, 163, 162, 161, 160, 159, 158, 156, 154,
- 153, 152, 151, 150, 149, 148, 147, 146, 145, 144,
- 143, 142, 141, 140, 139, 137, 136, 135, 134, 133,
- 132, 131, 130, 128, 127, 126, 125, 124, 123, 121,
- 120, 114, 113, 105, 104, 103, 102, 100, 99, 97,
- 95, 93, 92, 90, 89, 88, 87, 86, 85, 83,
- 82, 81, 80, 79, 77, 76, 75, 74, 73, 72,
- 67, 65, 64, 63, 61, 60, 56, 54, 52, 43,
-
- 34, 24, 15, 7, 565, 565, 565, 565, 565, 565,
+ 1, 1, 1, 1, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 5, 5,
+ 5, 5, 5, 14, 569, 14, 9, 5, 9, 17,
+
+ 5, 17, 16, 11, 18, 11, 16, 21, 19, 20,
+ 26, 21, 25, 22, 18, 18, 26, 25, 27, 19,
+ 18, 18, 19, 20, 22, 36, 27, 36, 28, 5,
+ 5, 6, 6, 6, 6, 6, 562, 9, 9, 23,
+ 6, 559, 30, 6, 11, 11, 33, 23, 28, 30,
+ 23, 29, 32, 23, 31, 29, 23, 35, 31, 33,
+ 32, 35, 29, 29, 32, 29, 33, 37, 38, 37,
+ 38, 558, 6, 6, 39, 41, 39, 41, 44, 45,
+ 44, 38, 47, 45, 47, 556, 48, 39, 48, 49,
+ 44, 49, 50, 51, 50, 51, 55, 59, 55, 59,
+
+ 62, 66, 68, 555, 68, 66, 69, 69, 70, 38,
+ 38, 62, 70, 71, 71, 39, 39, 78, 84, 94,
+ 98, 78, 84, 98, 96, 101, 94, 96, 554, 101,
+ 49, 49, 106, 551, 106, 96, 107, 108, 107, 108,
+ 96, 109, 111, 109, 111, 101, 115, 117, 115, 117,
+ 108, 122, 550, 180, 155, 180, 201, 201, 115, 117,
+ 155, 291, 548, 193, 122, 180, 193, 255, 255, 343,
+ 356, 255, 391, 394, 394, 403, 291, 356, 108, 108,
+ 356, 526, 403, 547, 546, 343, 543, 542, 391, 541,
+ 540, 539, 538, 526, 566, 566, 566, 566, 566, 566,
+
+ 567, 567, 567, 568, 568, 537, 568, 568, 568, 570,
+ 536, 533, 532, 570, 570, 571, 531, 530, 529, 571,
+ 571, 572, 572, 528, 572, 572, 572, 573, 573, 527,
+ 573, 573, 573, 574, 574, 523, 574, 574, 574, 522,
+ 521, 519, 518, 517, 515, 511, 510, 508, 507, 504,
+ 503, 502, 501, 500, 499, 498, 497, 495, 494, 493,
+ 490, 489, 488, 485, 481, 480, 479, 478, 477, 476,
+ 473, 472, 471, 470, 469, 468, 467, 466, 465, 464,
+ 463, 462, 461, 460, 459, 458, 457, 456, 454, 453,
+ 452, 450, 449, 448, 447, 446, 445, 444, 443, 442,
+
+ 441, 439, 437, 436, 435, 434, 433, 432, 429, 428,
+ 427, 426, 425, 424, 422, 420, 419, 418, 416, 414,
+ 409, 408, 407, 406, 405, 404, 402, 401, 400, 399,
+ 398, 397, 396, 393, 390, 389, 388, 387, 386, 385,
+ 384, 383, 382, 381, 380, 379, 377, 376, 375, 374,
+ 373, 372, 371, 370, 368, 367, 366, 365, 364, 362,
+ 361, 360, 359, 358, 357, 355, 354, 353, 352, 351,
+ 350, 349, 348, 347, 345, 344, 342, 340, 339, 338,
+ 337, 336, 335, 334, 333, 332, 331, 330, 329, 328,
+ 326, 325, 323, 321, 320, 319, 318, 317, 316, 315,
+
+ 314, 313, 312, 311, 310, 309, 308, 306, 305, 304,
+ 303, 302, 300, 299, 298, 297, 295, 294, 292, 290,
+ 288, 287, 286, 285, 284, 283, 282, 281, 280, 279,
+ 277, 276, 275, 274, 273, 272, 271, 270, 268, 267,
+ 266, 265, 264, 263, 262, 261, 259, 258, 257, 256,
+ 254, 253, 251, 250, 248, 247, 246, 245, 244, 243,
+ 242, 241, 240, 239, 238, 237, 234, 233, 232, 231,
+ 230, 229, 228, 227, 226, 225, 224, 223, 222, 221,
+ 220, 219, 217, 216, 215, 213, 212, 211, 210, 209,
+ 208, 207, 206, 205, 204, 202, 200, 199, 198, 197,
+
+ 196, 195, 194, 192, 191, 190, 189, 188, 187, 186,
+ 185, 184, 183, 182, 181, 179, 178, 177, 176, 175,
+ 174, 173, 172, 171, 170, 169, 168, 167, 166, 165,
+ 164, 163, 162, 161, 160, 159, 158, 156, 154, 153,
+ 152, 151, 150, 149, 148, 147, 146, 145, 144, 143,
+ 142, 141, 140, 139, 137, 136, 135, 134, 133, 132,
+ 131, 130, 128, 127, 126, 125, 124, 123, 121, 120,
+ 114, 113, 105, 104, 103, 102, 100, 99, 97, 95,
+ 93, 92, 90, 89, 88, 87, 86, 85, 83, 82,
+ 81, 80, 79, 77, 76, 75, 74, 73, 72, 67,
+
+ 65, 64, 63, 61, 60, 56, 54, 52, 43, 34,
+ 24, 15, 7, 565, 565, 565, 565, 565, 565, 565,
565, 565, 565, 565, 565, 565, 565, 565, 565, 565,
565, 565, 565, 565, 565, 565, 565, 565, 565, 565,
565, 565, 565, 565, 565, 565, 565, 565, 565, 565,
@@ -800,10 +802,11 @@ char *yy_text;
/* this header file is automatically generated by bison
* and includes all token definitions, as well as yy_lval */
#if ELBEEM_BLENDER==1
+// for blender the headers have to be .h
#include "cfgparser.h"
-#else // ELBEEM_BLENDER==1
+#else
#include "cfgparser.hpp"
-#endif // ELBEEM_BLENDER==1
+#endif
#include "utilities.h"
#include <string.h>
@@ -825,7 +828,7 @@ extern "C" int yy_wrap (void ) { return 1; }
* rules start
*/
/*----------------------------------------------------------------------------*/
-#line 829 "<stdout>"
+#line 832 "<stdout>"
#define INITIAL 0
#define ATTR 1
@@ -978,11 +981,11 @@ YY_DECL
register char *yy_cp, *yy_bp;
register int yy_act;
-#line 54 "src/cfglexer.ll"
+#line 55 "src/cfglexer.ll"
-#line 986 "<stdout>"
+#line 989 "<stdout>"
if ( (yy_init) )
{
@@ -1063,25 +1066,25 @@ do_action: /* This label is used only to access EOF actions. */
case 1:
YY_RULE_SETUP
-#line 57 "src/cfglexer.ll"
+#line 58 "src/cfglexer.ll"
{ return KW_PAROPEN; }
YY_BREAK
case 2:
YY_RULE_SETUP
-#line 58 "src/cfglexer.ll"
+#line 59 "src/cfglexer.ll"
{ BEGIN(INITIAL); // '}' always closes scopes
return KW_PARCLOSE; }
YY_BREAK
case 3:
YY_RULE_SETUP
-#line 61 "src/cfglexer.ll"
+#line 62 "src/cfglexer.ll"
{
BEGIN(ATTRVALUE);
return KW_EQUALS; }
YY_BREAK
case 4:
YY_RULE_SETUP
-#line 64 "src/cfglexer.ll"
+#line 65 "src/cfglexer.ll"
{ /* attribute name = normal string */
strncpy( charBuffer, yy_text, CHAR_BUFFER_SIZE-2 );
yy_lval.charValue = charBuffer;
@@ -1091,7 +1094,7 @@ YY_RULE_SETUP
YY_BREAK
case 5:
YY_RULE_SETUP
-#line 70 "src/cfglexer.ll"
+#line 71 "src/cfglexer.ll"
{ /* quoted string! attribute name = normal string */
strncpy( charBuffer, yy_text, CHAR_BUFFER_SIZE-2 );
/* get rid of " " */
@@ -1102,7 +1105,7 @@ YY_RULE_SETUP
YY_BREAK
case 6:
YY_RULE_SETUP
-#line 77 "src/cfglexer.ll"
+#line 78 "src/cfglexer.ll"
{ /* ends at newline or ';' */
strncpy( charBuffer, yy_text, CHAR_BUFFER_SIZE-2 );
yy_lval.charValue = charBuffer;
@@ -1110,433 +1113,433 @@ YY_RULE_SETUP
YY_BREAK
case 7:
YY_RULE_SETUP
-#line 81 "src/cfglexer.ll"
+#line 82 "src/cfglexer.ll"
{ /* return end token... */
BEGIN(ATTR);
return KW_ATTREND; }
YY_BREAK
case 8:
YY_RULE_SETUP
-#line 86 "src/cfglexer.ll"
+#line 87 "src/cfglexer.ll"
{ return KW_LBMSIM; }
YY_BREAK
case 9:
YY_RULE_SETUP
-#line 87 "src/cfglexer.ll"
+#line 88 "src/cfglexer.ll"
{ return KW_COMPARELBM; }
YY_BREAK
case 10:
YY_RULE_SETUP
-#line 88 "src/cfglexer.ll"
+#line 89 "src/cfglexer.ll"
{ return KW_DEBUGMODE; }
YY_BREAK
case 11:
YY_RULE_SETUP
-#line 89 "src/cfglexer.ll"
+#line 90 "src/cfglexer.ll"
{ return KW_DEBUGLEVEL; }
YY_BREAK
case 12:
YY_RULE_SETUP
-#line 90 "src/cfglexer.ll"
+#line 91 "src/cfglexer.ll"
{ return KW_RAYTRACING; }
YY_BREAK
case 13:
YY_RULE_SETUP
-#line 93 "src/cfglexer.ll"
+#line 94 "src/cfglexer.ll"
{ return KW_RESOLUTION; }
YY_BREAK
case 14:
YY_RULE_SETUP
-#line 94 "src/cfglexer.ll"
+#line 95 "src/cfglexer.ll"
{ return KW_ANTIALIAS; }
YY_BREAK
case 15:
YY_RULE_SETUP
-#line 95 "src/cfglexer.ll"
+#line 96 "src/cfglexer.ll"
{ return KW_EYEPOINT; }
YY_BREAK
case 16:
YY_RULE_SETUP
-#line 96 "src/cfglexer.ll"
+#line 97 "src/cfglexer.ll"
{ return KW_LOOKAT ; }
YY_BREAK
case 17:
YY_RULE_SETUP
-#line 97 "src/cfglexer.ll"
+#line 98 "src/cfglexer.ll"
{ return KW_UPVEC ; }
YY_BREAK
case 18:
YY_RULE_SETUP
-#line 98 "src/cfglexer.ll"
+#line 99 "src/cfglexer.ll"
{ return KW_FOVY; }
YY_BREAK
case 19:
YY_RULE_SETUP
-#line 99 "src/cfglexer.ll"
+#line 100 "src/cfglexer.ll"
{ return KW_ASPECT ; }
YY_BREAK
case 20:
YY_RULE_SETUP
-#line 100 "src/cfglexer.ll"
+#line 101 "src/cfglexer.ll"
{ return KW_AMBIENCE; }
YY_BREAK
case 21:
YY_RULE_SETUP
-#line 101 "src/cfglexer.ll"
+#line 102 "src/cfglexer.ll"
{ return KW_BACKGROUND; }
YY_BREAK
case 22:
YY_RULE_SETUP
-#line 102 "src/cfglexer.ll"
+#line 103 "src/cfglexer.ll"
{ return KW_ANISTART; }
YY_BREAK
case 23:
YY_RULE_SETUP
-#line 103 "src/cfglexer.ll"
+#line 104 "src/cfglexer.ll"
{ return KW_ANIFRAMES; }
YY_BREAK
case 24:
YY_RULE_SETUP
-#line 104 "src/cfglexer.ll"
+#line 105 "src/cfglexer.ll"
{ return KW_ANIFRAMETIME; }
YY_BREAK
case 25:
YY_RULE_SETUP
-#line 105 "src/cfglexer.ll"
+#line 106 "src/cfglexer.ll"
{ return KW_FRAMESKIP; }
YY_BREAK
case 26:
YY_RULE_SETUP
-#line 106 "src/cfglexer.ll"
+#line 107 "src/cfglexer.ll"
{ return KW_FILENAME; }
YY_BREAK
case 27:
YY_RULE_SETUP
-#line 107 "src/cfglexer.ll"
+#line 108 "src/cfglexer.ll"
{ return KW_PMCAUSTICS; }
YY_BREAK
case 28:
YY_RULE_SETUP
-#line 108 "src/cfglexer.ll"
+#line 109 "src/cfglexer.ll"
{ return KW_CAUSTICDIST; }
YY_BREAK
case 29:
YY_RULE_SETUP
-#line 109 "src/cfglexer.ll"
+#line 110 "src/cfglexer.ll"
{ return KW_CAUSTICPHOT; }
YY_BREAK
case 30:
YY_RULE_SETUP
-#line 110 "src/cfglexer.ll"
+#line 111 "src/cfglexer.ll"
{ return KW_SHADOWMAPBIAS; }
YY_BREAK
case 31:
YY_RULE_SETUP
-#line 111 "src/cfglexer.ll"
+#line 112 "src/cfglexer.ll"
{ return KW_MAXRAYDEPTH; }
YY_BREAK
case 32:
YY_RULE_SETUP
-#line 112 "src/cfglexer.ll"
+#line 113 "src/cfglexer.ll"
{ return KW_TREEMAXDEPTH; }
YY_BREAK
case 33:
YY_RULE_SETUP
-#line 113 "src/cfglexer.ll"
+#line 114 "src/cfglexer.ll"
{ return KW_TREEMAXTRIANGLES; }
YY_BREAK
case 34:
YY_RULE_SETUP
-#line 114 "src/cfglexer.ll"
+#line 115 "src/cfglexer.ll"
{ return KW_DEBUGPIXEL; }
YY_BREAK
case 35:
YY_RULE_SETUP
-#line 115 "src/cfglexer.ll"
+#line 116 "src/cfglexer.ll"
{ return KW_TESTMODE; }
YY_BREAK
case 36:
YY_RULE_SETUP
-#line 116 "src/cfglexer.ll"
+#line 117 "src/cfglexer.ll"
{ return KW_OPENGLATTR; }
YY_BREAK
case 37:
YY_RULE_SETUP
-#line 117 "src/cfglexer.ll"
+#line 118 "src/cfglexer.ll"
{ return KW_BLENDERATTR; }
YY_BREAK
case 38:
YY_RULE_SETUP
-#line 119 "src/cfglexer.ll"
+#line 120 "src/cfglexer.ll"
{ return KW_OBJATTR; /* assign attr to obj */ }
YY_BREAK
case 39:
YY_RULE_SETUP
-#line 120 "src/cfglexer.ll"
+#line 121 "src/cfglexer.ll"
{ BEGIN(ATTR); return KW_ATTRIBUTE; /* global attr list */ }
YY_BREAK
case 40:
YY_RULE_SETUP
-#line 121 "src/cfglexer.ll"
+#line 122 "src/cfglexer.ll"
{ BEGIN(ATTR); return KW_DEFINEATTR; /* obj defines new attrs */ }
YY_BREAK
case 41:
YY_RULE_SETUP
-#line 122 "src/cfglexer.ll"
+#line 123 "src/cfglexer.ll"
{ BEGIN(ATTR); return KW_DEFINEATTR; }
YY_BREAK
case 42:
YY_RULE_SETUP
-#line 123 "src/cfglexer.ll"
+#line 124 "src/cfglexer.ll"
{ BEGIN(ATTR); return KW_DEFINEATTR; }
YY_BREAK
case 43:
YY_RULE_SETUP
-#line 125 "src/cfglexer.ll"
+#line 126 "src/cfglexer.ll"
{ return KW_GEOMETRY; }
YY_BREAK
case 44:
YY_RULE_SETUP
-#line 126 "src/cfglexer.ll"
+#line 127 "src/cfglexer.ll"
{ return KW_TYPE; }
YY_BREAK
case 45:
YY_RULE_SETUP
-#line 127 "src/cfglexer.ll"
+#line 128 "src/cfglexer.ll"
{ return KW_GEOTYPE_BOX; }
YY_BREAK
case 46:
YY_RULE_SETUP
-#line 128 "src/cfglexer.ll"
+#line 129 "src/cfglexer.ll"
{ return KW_GEOTYPE_SPHERE; }
YY_BREAK
case 47:
YY_RULE_SETUP
-#line 129 "src/cfglexer.ll"
+#line 130 "src/cfglexer.ll"
{ return KW_GEOTYPE_OBJMODEL; }
YY_BREAK
case 48:
YY_RULE_SETUP
-#line 130 "src/cfglexer.ll"
+#line 131 "src/cfglexer.ll"
{ return KW_CASTSHADOWS; }
YY_BREAK
case 49:
YY_RULE_SETUP
-#line 131 "src/cfglexer.ll"
+#line 132 "src/cfglexer.ll"
{ return KW_RECEIVESHADOWS ; }
YY_BREAK
case 50:
YY_RULE_SETUP
-#line 132 "src/cfglexer.ll"
+#line 133 "src/cfglexer.ll"
{ return KW_VISIBLE; }
YY_BREAK
case 51:
YY_RULE_SETUP
-#line 133 "src/cfglexer.ll"
+#line 134 "src/cfglexer.ll"
{ return KW_BOX_START; }
YY_BREAK
case 52:
YY_RULE_SETUP
-#line 134 "src/cfglexer.ll"
+#line 135 "src/cfglexer.ll"
{ return KW_BOX_END; }
YY_BREAK
case 53:
YY_RULE_SETUP
-#line 135 "src/cfglexer.ll"
+#line 136 "src/cfglexer.ll"
{ return KW_POLY ; }
YY_BREAK
case 54:
YY_RULE_SETUP
-#line 136 "src/cfglexer.ll"
+#line 137 "src/cfglexer.ll"
{ return KW_POLY ; }
YY_BREAK
case 55:
YY_RULE_SETUP
-#line 137 "src/cfglexer.ll"
+#line 138 "src/cfglexer.ll"
{ return KW_NUMVERTICES; }
YY_BREAK
case 56:
YY_RULE_SETUP
-#line 138 "src/cfglexer.ll"
+#line 139 "src/cfglexer.ll"
{ return KW_VERTEX; }
YY_BREAK
case 57:
YY_RULE_SETUP
-#line 139 "src/cfglexer.ll"
+#line 140 "src/cfglexer.ll"
{ return KW_NUMPOLYGONS; }
YY_BREAK
case 58:
YY_RULE_SETUP
-#line 140 "src/cfglexer.ll"
+#line 141 "src/cfglexer.ll"
{ return KW_ISOSURF; }
YY_BREAK
case 59:
YY_RULE_SETUP
-#line 141 "src/cfglexer.ll"
+#line 142 "src/cfglexer.ll"
{ return KW_FILEMODE; }
YY_BREAK
case 60:
YY_RULE_SETUP
-#line 142 "src/cfglexer.ll"
+#line 143 "src/cfglexer.ll"
{ return KW_INVERT; }
YY_BREAK
case 61:
YY_RULE_SETUP
-#line 144 "src/cfglexer.ll"
+#line 145 "src/cfglexer.ll"
{ return KW_MATERIAL; }
YY_BREAK
case 62:
YY_RULE_SETUP
-#line 145 "src/cfglexer.ll"
+#line 146 "src/cfglexer.ll"
{ return KW_MATTYPE_PHONG; }
YY_BREAK
case 63:
YY_RULE_SETUP
-#line 146 "src/cfglexer.ll"
+#line 147 "src/cfglexer.ll"
{ return KW_MATTYPE_BLINN; }
YY_BREAK
case 64:
YY_RULE_SETUP
-#line 147 "src/cfglexer.ll"
+#line 148 "src/cfglexer.ll"
{ return KW_NAME; }
YY_BREAK
case 65:
YY_RULE_SETUP
-#line 148 "src/cfglexer.ll"
+#line 149 "src/cfglexer.ll"
{ return KW_AMBIENT; }
YY_BREAK
case 66:
YY_RULE_SETUP
-#line 149 "src/cfglexer.ll"
+#line 150 "src/cfglexer.ll"
{ return KW_DIFFUSE; }
YY_BREAK
case 67:
YY_RULE_SETUP
-#line 150 "src/cfglexer.ll"
+#line 151 "src/cfglexer.ll"
{ return KW_SPECULAR; }
YY_BREAK
case 68:
YY_RULE_SETUP
-#line 151 "src/cfglexer.ll"
+#line 152 "src/cfglexer.ll"
{ return KW_MIRROR; }
YY_BREAK
case 69:
YY_RULE_SETUP
-#line 152 "src/cfglexer.ll"
+#line 153 "src/cfglexer.ll"
{ return KW_TRANSPARENCE; }
YY_BREAK
case 70:
YY_RULE_SETUP
-#line 153 "src/cfglexer.ll"
+#line 154 "src/cfglexer.ll"
{ return KW_REFRACINDEX; }
YY_BREAK
case 71:
YY_RULE_SETUP
-#line 154 "src/cfglexer.ll"
+#line 155 "src/cfglexer.ll"
{ return KW_TRANSADDITIVE; }
YY_BREAK
case 72:
YY_RULE_SETUP
-#line 155 "src/cfglexer.ll"
+#line 156 "src/cfglexer.ll"
{ return KW_TRANSATTCOL; }
YY_BREAK
case 73:
YY_RULE_SETUP
-#line 156 "src/cfglexer.ll"
+#line 157 "src/cfglexer.ll"
{ return KW_FRESNEL; }
YY_BREAK
case 74:
YY_RULE_SETUP
-#line 157 "src/cfglexer.ll"
+#line 158 "src/cfglexer.ll"
{ return KW_FRESNEL; }
YY_BREAK
case 75:
YY_RULE_SETUP
-#line 159 "src/cfglexer.ll"
+#line 160 "src/cfglexer.ll"
{ return KW_LIGHT; }
YY_BREAK
case 76:
YY_RULE_SETUP
-#line 160 "src/cfglexer.ll"
+#line 161 "src/cfglexer.ll"
{ return KW_LIGHT_OMNI; }
YY_BREAK
case 77:
YY_RULE_SETUP
-#line 161 "src/cfglexer.ll"
+#line 162 "src/cfglexer.ll"
{ return KW_ACTIVE; }
YY_BREAK
case 78:
YY_RULE_SETUP
-#line 162 "src/cfglexer.ll"
+#line 163 "src/cfglexer.ll"
{ return KW_COLOUR; }
YY_BREAK
case 79:
YY_RULE_SETUP
-#line 163 "src/cfglexer.ll"
+#line 164 "src/cfglexer.ll"
{ return KW_COLOUR; }
YY_BREAK
case 80:
YY_RULE_SETUP
-#line 164 "src/cfglexer.ll"
+#line 165 "src/cfglexer.ll"
{ return KW_POSITION; }
YY_BREAK
case 81:
YY_RULE_SETUP
-#line 165 "src/cfglexer.ll"
+#line 166 "src/cfglexer.ll"
{ return KW_CAUSTICPHOTONS; }
YY_BREAK
case 82:
YY_RULE_SETUP
-#line 166 "src/cfglexer.ll"
+#line 167 "src/cfglexer.ll"
{ return KW_CAUSTICSTRENGTH; }
YY_BREAK
case 83:
YY_RULE_SETUP
-#line 167 "src/cfglexer.ll"
+#line 168 "src/cfglexer.ll"
{ return KW_SHADOWMAP; }
YY_BREAK
case 84:
YY_RULE_SETUP
-#line 168 "src/cfglexer.ll"
+#line 169 "src/cfglexer.ll"
{ return KW_CAUSTICSMAP; }
YY_BREAK
case 85:
YY_RULE_SETUP
-#line 170 "src/cfglexer.ll"
+#line 171 "src/cfglexer.ll"
{ yy_lval.intValue = 1; return DT_INTEGER; }
YY_BREAK
case 86:
YY_RULE_SETUP
-#line 171 "src/cfglexer.ll"
+#line 172 "src/cfglexer.ll"
{ yy_lval.intValue = 0; return DT_INTEGER; }
YY_BREAK
case 87:
YY_RULE_SETUP
-#line 172 "src/cfglexer.ll"
+#line 173 "src/cfglexer.ll"
{ yy_lval.intValue = 1; return DT_INTEGER; }
YY_BREAK
case 88:
YY_RULE_SETUP
-#line 173 "src/cfglexer.ll"
+#line 174 "src/cfglexer.ll"
{ yy_lval.intValue = 0; return DT_INTEGER; }
YY_BREAK
case 89:
YY_RULE_SETUP
-#line 176 "src/cfglexer.ll"
+#line 177 "src/cfglexer.ll"
{ // integer number
yy_lval.intValue = atoi( yy_text );
return DT_INTEGER; }
YY_BREAK
case 90:
YY_RULE_SETUP
-#line 180 "src/cfglexer.ll"
+#line 181 "src/cfglexer.ll"
{ // floating point number
yy_lval.floatValue = atof( yy_text );
return DT_FLOAT; }
YY_BREAK
case 91:
YY_RULE_SETUP
-#line 184 "src/cfglexer.ll"
+#line 185 "src/cfglexer.ll"
{ /* normal character strings, now also for paths/filenames */
strncpy( charBuffer, yy_text, CHAR_BUFFER_SIZE-2 );
/* get rid of " " */
@@ -1547,17 +1550,17 @@ YY_RULE_SETUP
YY_BREAK
case 92:
YY_RULE_SETUP
-#line 192 "src/cfglexer.ll"
+#line 193 "src/cfglexer.ll"
{ /* one line comment */ }
YY_BREAK
case 93:
YY_RULE_SETUP
-#line 193 "src/cfglexer.ll"
+#line 194 "src/cfglexer.ll"
{ /* one line comment */ }
YY_BREAK
case 94:
YY_RULE_SETUP
-#line 194 "src/cfglexer.ll"
+#line 195 "src/cfglexer.ll"
{ /* multiline comment */
register int c;
for ( ; ; ) {
@@ -1583,26 +1586,26 @@ YY_RULE_SETUP
case 95:
/* rule 95 can match eol */
YY_RULE_SETUP
-#line 218 "src/cfglexer.ll"
+#line 219 "src/cfglexer.ll"
{ // count line numbers
lineCount++; }
YY_BREAK
case 96:
YY_RULE_SETUP
-#line 221 "src/cfglexer.ll"
+#line 222 "src/cfglexer.ll"
{ /* do nothing by default... */ }
YY_BREAK
case 97:
YY_RULE_SETUP
-#line 223 "src/cfglexer.ll"
+#line 224 "src/cfglexer.ll"
{ /*errorOut( "cfgLexer, Line "<<lineCount<<" : Unknown character '"<<(char)yyinput()<<"' " ); xit(1); */ }
YY_BREAK
case 98:
YY_RULE_SETUP
-#line 226 "src/cfglexer.ll"
+#line 227 "src/cfglexer.ll"
ECHO;
YY_BREAK
-#line 1606 "<stdout>"
+#line 1609 "<stdout>"
case YY_STATE_EOF(INITIAL):
case YY_STATE_EOF(ATTR):
case YY_STATE_EOF(ATTRVALUE):
@@ -2567,4 +2570,4 @@ void yy_free (void * ptr )
#undef YY_DECL_IS_OURS
#undef YY_DECL
#endif
-#line 226 "src/cfglexer.ll"
+#line 227 "src/cfglexer.ll"
diff --git a/intern/elbeem/intern/cfgparser.cpp b/intern/elbeem/intern/cfgparser.cpp
index 16a8772ff72..6ca309f77a5 100644
--- a/intern/elbeem/intern/cfgparser.cpp
+++ b/intern/elbeem/intern/cfgparser.cpp
@@ -299,19 +299,17 @@
int yy_parse( void );
// local variables to access objects
+#include "solver_interface.h"
#include "simulation_object.h"
#ifdef LBM_INCLUDE_TESTSOLVERS
#include "simulation_complbm.h"
#endif // LBM_INCLUDE_TESTSOLVERS
#include "parametrizer.h"
-#include "ntl_renderglobals.h"
-#include "ntl_scene.h"
-
-#include "ntl_lightobject.h"
-#include "ntl_material.h"
+#include "ntl_world.h"
+#include "ntl_ray.h"
+#include "ntl_lighting.h"
#include "ntl_geometrymodel.h"
-#include "globals.h"
/* global variables */
static map<string,AttributeList*> attrs; /* global attribute storage */
@@ -333,11 +331,11 @@
AttributeList *currentAttrib;
string currentAttrName, currentAttribAddName;
-#ifndef ELBEEM_BLENDER
+#ifndef ELBEEM_PLUGIN
#include "ntl_geometrybox.h"
#include "ntl_geometrysphere.h"
ntlGeometryBox *currentGeometryBox;
-#endif //ELBEEM_BLENDER
+#endif //ELBEEM_PLUGIN
/* material init checks */
ntlMaterial *currentMaterial;
@@ -358,14 +356,14 @@
#endif
#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
-#line 87 "src/cfgparser.yy"
+#line 85 "src/cfgparser.yy"
typedef union YYSTYPE {
int intValue;
float floatValue;
char *charValue;
} YYSTYPE;
/* Line 190 of yacc.c. */
-#line 369 "bld-std-gcc/src/cfgparser.cpp"
+#line 367 "bld-std-gcc/src/cfgparser.cpp"
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
@@ -377,7 +375,7 @@ typedef union YYSTYPE {
/* Line 213 of yacc.c. */
-#line 381 "bld-std-gcc/src/cfgparser.cpp"
+#line 379 "bld-std-gcc/src/cfgparser.cpp"
#if ! defined (yyoverflow) || YYERROR_VERBOSE
@@ -609,21 +607,21 @@ static const short int yyrhs[] =
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
static const unsigned short int yyrline[] =
{
- 0, 146, 146, 147, 150, 151, 152, 153, 157, 160,
- 175, 176, 176, 179, 180, 181, 182, 184, 185, 186,
- 187, 188, 189, 190, 191, 192, 193, 194, 195, 196,
- 197, 198, 199, 200, 202, 203, 204, 205, 210, 214,
- 219, 223, 229, 233, 237, 241, 245, 249, 253, 257,
- 261, 265, 269, 273, 277, 281, 285, 289, 294, 303,
- 314, 315, 318, 326, 327, 328, 329, 333, 338, 343,
- 348, 366, 365, 386, 387, 390, 399, 407, 412, 418,
- 430, 431, 432, 433, 434, 435, 436, 437, 438, 443,
- 448, 454, 460, 466, 471, 486, 502, 508, 518, 529,
- 530, 533, 538, 542, 543, 544, 545, 546, 547, 548,
- 549, 550, 551, 556, 561, 566, 571, 577, 582, 587,
- 592, 597, 602, 613, 613, 623, 623, 626, 626, 629,
- 630, 629, 637, 638, 637, 645, 648, 658, 661, 673,
- 675, 681, 692, 704
+ 0, 144, 144, 145, 148, 149, 150, 151, 155, 158,
+ 173, 174, 174, 177, 178, 179, 180, 182, 183, 184,
+ 185, 186, 187, 188, 189, 190, 191, 192, 193, 194,
+ 195, 196, 197, 198, 200, 201, 202, 203, 208, 212,
+ 217, 221, 227, 231, 235, 239, 243, 247, 251, 255,
+ 259, 263, 267, 271, 275, 279, 283, 287, 292, 301,
+ 312, 313, 316, 324, 325, 326, 327, 331, 336, 341,
+ 346, 364, 363, 385, 386, 389, 398, 406, 411, 417,
+ 429, 430, 431, 432, 433, 434, 435, 436, 437, 442,
+ 447, 453, 459, 465, 470, 485, 501, 510, 520, 531,
+ 532, 535, 540, 544, 545, 546, 547, 548, 549, 550,
+ 551, 552, 553, 558, 563, 568, 573, 579, 584, 589,
+ 594, 599, 604, 615, 615, 625, 625, 628, 628, 631,
+ 632, 631, 639, 640, 639, 647, 650, 660, 663, 675,
+ 677, 683, 694, 706
};
#endif
@@ -1583,12 +1581,12 @@ yyreduce:
switch (yyn)
{
case 8:
-#line 157 "src/cfgparser.yy"
+#line 155 "src/cfgparser.yy"
{ yy_debug = (yyvsp[0].intValue); }
break;
case 9:
-#line 160 "src/cfgparser.yy"
+#line 158 "src/cfgparser.yy"
{
int sdebug = (yyvsp[0].intValue);
if(sdebug<0) sdebug=0;
@@ -1598,114 +1596,114 @@ yyreduce:
break;
case 38:
-#line 211 "src/cfgparser.yy"
+#line 209 "src/cfgparser.yy"
{ reglob->setAniStart( (yyvsp[0].intValue) ); }
break;
case 39:
-#line 215 "src/cfgparser.yy"
+#line 213 "src/cfgparser.yy"
{ /*reglob->setAniFrameTime( $2 );*/ debMsgStd("cfgparser",DM_NOTIFY,"Deprecated setting aniframetime!",1); }
break;
case 40:
-#line 220 "src/cfgparser.yy"
+#line 218 "src/cfgparser.yy"
{ reglob->setAniFrames( ((yyvsp[0].intValue))-1 ); }
break;
case 41:
-#line 224 "src/cfgparser.yy"
+#line 222 "src/cfgparser.yy"
{ reglob->setFrameSkip( ((yyvsp[0].intValue)) ); }
break;
case 42:
-#line 230 "src/cfgparser.yy"
+#line 228 "src/cfgparser.yy"
{ reglob->setResX( (yyvsp[-1].intValue) ); reglob->setResY( (yyvsp[0].intValue)); }
break;
case 43:
-#line 234 "src/cfgparser.yy"
+#line 232 "src/cfgparser.yy"
{ reglob->setAADepth( (yyvsp[0].intValue) ); }
break;
case 44:
-#line 238 "src/cfgparser.yy"
+#line 236 "src/cfgparser.yy"
{ reglob->setEye( ntlVec3Gfx((yyvsp[-2].floatValue),(yyvsp[-1].floatValue),(yyvsp[0].floatValue)) ); }
break;
case 45:
-#line 242 "src/cfgparser.yy"
+#line 240 "src/cfgparser.yy"
{ reglob->setLookat( ntlVec3Gfx((yyvsp[-2].floatValue),(yyvsp[-1].floatValue),(yyvsp[0].floatValue)) ); }
break;
case 46:
-#line 246 "src/cfgparser.yy"
+#line 244 "src/cfgparser.yy"
{ reglob->setUpVec( ntlVec3Gfx((yyvsp[-2].floatValue),(yyvsp[-1].floatValue),(yyvsp[0].floatValue)) ); }
break;
case 47:
-#line 250 "src/cfgparser.yy"
+#line 248 "src/cfgparser.yy"
{ reglob->setFovy( (yyvsp[0].floatValue) ); }
break;
case 48:
-#line 254 "src/cfgparser.yy"
+#line 252 "src/cfgparser.yy"
{ reglob->setAspect( (yyvsp[0].floatValue) ); }
break;
case 49:
-#line 258 "src/cfgparser.yy"
+#line 256 "src/cfgparser.yy"
{ reglob->setAmbientLight( ntlColor((yyvsp[-2].floatValue),(yyvsp[-1].floatValue),(yyvsp[0].floatValue)) ); }
break;
case 50:
-#line 262 "src/cfgparser.yy"
+#line 260 "src/cfgparser.yy"
{ reglob->setBackgroundCol( ntlColor((yyvsp[-2].floatValue),(yyvsp[-1].floatValue),(yyvsp[0].floatValue)) ); }
break;
case 51:
-#line 266 "src/cfgparser.yy"
+#line 264 "src/cfgparser.yy"
{ reglob->setOutFilename( (yyvsp[0].charValue) ); }
break;
case 52:
-#line 270 "src/cfgparser.yy"
+#line 268 "src/cfgparser.yy"
{ reglob->setTreeMaxDepth( (yyvsp[0].intValue) ); }
break;
case 53:
-#line 274 "src/cfgparser.yy"
+#line 272 "src/cfgparser.yy"
{ reglob->setTreeMaxTriangles( (yyvsp[0].intValue) ); }
break;
case 54:
-#line 278 "src/cfgparser.yy"
+#line 276 "src/cfgparser.yy"
{ reglob->setRayMaxDepth( (yyvsp[0].intValue) ); }
break;
case 55:
-#line 282 "src/cfgparser.yy"
+#line 280 "src/cfgparser.yy"
{ reglob->setDebugPixel( (yyvsp[-1].intValue), (yyvsp[0].intValue) ); }
break;
case 56:
-#line 286 "src/cfgparser.yy"
+#line 284 "src/cfgparser.yy"
{ reglob->setTestMode( (yyvsp[0].intValue) ); }
break;
case 57:
-#line 290 "src/cfgparser.yy"
+#line 288 "src/cfgparser.yy"
{ if(attrs[(yyvsp[0].charValue)] == NULL){ yyerror("OPENGL ATTRIBUTES: The attribute was not found!"); }
reglob->getOpenGlAttributes()->import( attrs[(yyvsp[0].charValue)] ); }
break;
case 58:
-#line 295 "src/cfgparser.yy"
+#line 293 "src/cfgparser.yy"
{ if(attrs[(yyvsp[0].charValue)] == NULL){ yyerror("BLENDER ATTRIBUTES: The attribute was not found!"); }
reglob->getBlenderAttributes()->import( attrs[(yyvsp[0].charValue)] ); }
break;
case 59:
-#line 307 "src/cfgparser.yy"
+#line 305 "src/cfgparser.yy"
{
/* reset light pointers */
currentLightOmni = NULL;
@@ -1713,7 +1711,7 @@ yyreduce:
break;
case 62:
-#line 319 "src/cfgparser.yy"
+#line 317 "src/cfgparser.yy"
{ currentLightOmni = new ntlLightObject( reglob );
currentLight = currentLightOmni;
reglob->getLightList()->push_back(currentLight);
@@ -1721,28 +1719,28 @@ yyreduce:
break;
case 67:
-#line 333 "src/cfgparser.yy"
+#line 331 "src/cfgparser.yy"
{
currentLight->setActive( (yyvsp[0].intValue) );
}
break;
case 68:
-#line 338 "src/cfgparser.yy"
+#line 336 "src/cfgparser.yy"
{
currentLight->setCastShadows( (yyvsp[0].intValue) );
}
break;
case 69:
-#line 343 "src/cfgparser.yy"
+#line 341 "src/cfgparser.yy"
{
currentLight->setColor( ntlColor((yyvsp[-2].floatValue),(yyvsp[-1].floatValue),(yyvsp[0].floatValue)) );
}
break;
case 70:
-#line 348 "src/cfgparser.yy"
+#line 346 "src/cfgparser.yy"
{
int init = 0;
if(currentLightOmni != NULL) {
@@ -1752,16 +1750,17 @@ yyreduce:
break;
case 71:
-#line 366 "src/cfgparser.yy"
+#line 364 "src/cfgparser.yy"
{
// geo classes have attributes...
- reglob->getScene()->addGeoClass(currentGeoClass);
+ reglob->getRenderScene()->addGeoClass(currentGeoClass);
+ reglob->getSimScene()->addGeoClass(currentGeoClass);
currentAttrib = currentGeoClass->getAttributeList();
}
break;
case 72:
-#line 372 "src/cfgparser.yy"
+#line 371 "src/cfgparser.yy"
{
/* reset geometry object pointers */
currentGeoObj = NULL;
@@ -1769,39 +1768,39 @@ yyreduce:
currentGeometrySim = NULL;
currentGeometryModel = NULL;
currentAttrib = NULL;
-#ifndef ELBEEM_BLENDER
+#ifndef ELBEEM_PLUGIN
currentGeometryBox = NULL;
-#endif // ELBEEM_BLENDER
+#endif // ELBEEM_PLUGIN
}
break;
case 75:
-#line 390 "src/cfgparser.yy"
+#line 389 "src/cfgparser.yy"
{
-#ifndef ELBEEM_BLENDER
+#ifndef ELBEEM_PLUGIN
currentGeometryBox = new ntlGeometryBox( );
currentGeoClass = currentGeometryBox;
currentGeoObj = (ntlGeometryObject*)( currentGeometryBox );
-#else // ELBEEM_BLENDER
+#else // ELBEEM_PLUGIN
yyerror("GEOTYPE_BOX : This object type is not supported in this version!");
-#endif // ELBEEM_BLENDER
+#endif // ELBEEM_PLUGIN
}
break;
case 76:
-#line 399 "src/cfgparser.yy"
+#line 398 "src/cfgparser.yy"
{
-#ifndef ELBEEM_BLENDER
+#ifndef ELBEEM_PLUGIN
currentGeoClass = new ntlGeometrySphere( );
currentGeoObj = (ntlGeometryObject*)( currentGeoClass );
-#else // ELBEEM_BLENDER
+#else // ELBEEM_PLUGIN
yyerror("GEOTYPE_SPHERE : This object type is not supported in this version!");
-#endif // ELBEEM_BLENDER
+#endif // ELBEEM_PLUGIN
}
break;
case 77:
-#line 407 "src/cfgparser.yy"
+#line 406 "src/cfgparser.yy"
{
currentGeometryModel = new ntlGeometryObjModel( );
currentGeoClass = currentGeometryModel;
@@ -1810,7 +1809,7 @@ yyreduce:
break;
case 78:
-#line 412 "src/cfgparser.yy"
+#line 411 "src/cfgparser.yy"
{
currentGeometrySim = new SimulationObject();
currentGeoClass = currentGeometrySim;
@@ -1820,7 +1819,7 @@ yyreduce:
break;
case 79:
-#line 418 "src/cfgparser.yy"
+#line 417 "src/cfgparser.yy"
{
#ifdef LBM_INCLUDE_TESTSOLVERS
currentGeometrySim = new SimulationCompareLbm();
@@ -1833,14 +1832,14 @@ yyreduce:
break;
case 89:
-#line 443 "src/cfgparser.yy"
+#line 442 "src/cfgparser.yy"
{
currentGeoClass->setName( (yyvsp[0].charValue) );
}
break;
case 90:
-#line 448 "src/cfgparser.yy"
+#line 447 "src/cfgparser.yy"
{
if(currentGeoObj == NULL){ yyerror(" MATERIAL : This property can only be set for geometry objects!"); }
currentGeoObj->setMaterialName( (yyvsp[0].charValue) );
@@ -1848,7 +1847,7 @@ yyreduce:
break;
case 91:
-#line 454 "src/cfgparser.yy"
+#line 453 "src/cfgparser.yy"
{
if(currentGeoObj == NULL){ yyerror(" CAST_SHADOW : This property can only be set for geometry objects!"); }
currentGeoObj->setCastShadows( (yyvsp[0].intValue) );
@@ -1856,7 +1855,7 @@ yyreduce:
break;
case 92:
-#line 460 "src/cfgparser.yy"
+#line 459 "src/cfgparser.yy"
{
if(currentGeoObj == NULL){ yyerror(" RECEIVE_SHADOW : This property can only be set for geometry objects!"); }
currentGeoObj->setReceiveShadows( (yyvsp[0].intValue) );
@@ -1864,21 +1863,21 @@ yyreduce:
break;
case 93:
-#line 466 "src/cfgparser.yy"
+#line 465 "src/cfgparser.yy"
{
currentGeoClass->setVisible( (yyvsp[0].intValue) );
}
break;
case 94:
-#line 471 "src/cfgparser.yy"
+#line 470 "src/cfgparser.yy"
{
int init = 0;
-#ifndef ELBEEM_BLENDER
+#ifndef ELBEEM_PLUGIN
if(currentGeometryBox != NULL){
currentGeometryBox->setStart( ntlVec3Gfx((yyvsp[-2].floatValue),(yyvsp[-1].floatValue),(yyvsp[0].floatValue)) ); init=1; }
-#else // ELBEEM_BLENDER
-#endif // ELBEEM_BLENDER
+#else // ELBEEM_PLUGIN
+#endif // ELBEEM_PLUGIN
if(currentGeometrySim != NULL){
currentGeometrySim->setGeoStart( ntlVec3Gfx((yyvsp[-2].floatValue),(yyvsp[-1].floatValue),(yyvsp[0].floatValue)) ); init=1; }
if(currentGeometryModel != NULL){
@@ -1888,14 +1887,14 @@ yyreduce:
break;
case 95:
-#line 486 "src/cfgparser.yy"
+#line 485 "src/cfgparser.yy"
{
int init = 0;
-#ifndef ELBEEM_BLENDER
+#ifndef ELBEEM_PLUGIN
if(currentGeometryBox != NULL){
currentGeometryBox->setEnd( ntlVec3Gfx((yyvsp[-2].floatValue),(yyvsp[-1].floatValue),(yyvsp[0].floatValue)) ); init=1; }
-#else // ELBEEM_BLENDER
-#endif // ELBEEM_BLENDER
+#else // ELBEEM_PLUGIN
+#endif // ELBEEM_PLUGIN
if(currentGeometrySim != NULL){
currentGeometrySim->setGeoEnd( ntlVec3Gfx((yyvsp[-2].floatValue),(yyvsp[-1].floatValue),(yyvsp[0].floatValue)) ); init=1; }
if(currentGeometryModel != NULL){
@@ -1905,20 +1904,23 @@ yyreduce:
break;
case 96:
-#line 502 "src/cfgparser.yy"
+#line 501 "src/cfgparser.yy"
{
if(attrs[(yyvsp[0].charValue)] == NULL){ yyerror("GEO ATTRIBUTES: The attribute was not found!"); }
- currentGeoClass->getAttributeList()->import( attrs[(yyvsp[0].charValue)] );
+ else {
+ if(currentGeoClass->getAttributeList())
+ currentGeoClass->getAttributeList()->import( attrs[(yyvsp[0].charValue)] );
+ }
}
break;
case 97:
-#line 510 "src/cfgparser.yy"
+#line 512 "src/cfgparser.yy"
{ }
break;
case 98:
-#line 522 "src/cfgparser.yy"
+#line 524 "src/cfgparser.yy"
{
/* reset geometry object pointers */
currentMaterial = NULL;
@@ -1926,7 +1928,7 @@ yyreduce:
break;
case 101:
-#line 534 "src/cfgparser.yy"
+#line 536 "src/cfgparser.yy"
{ currentMaterial = new ntlMaterial( );
currentMaterial = currentMaterial;
reglob->getMaterials()->push_back(currentMaterial);
@@ -1934,34 +1936,34 @@ yyreduce:
break;
case 102:
-#line 538 "src/cfgparser.yy"
+#line 540 "src/cfgparser.yy"
{
yyerror("MATTYPE: Blinn NYI!"); }
break;
case 113:
-#line 556 "src/cfgparser.yy"
+#line 558 "src/cfgparser.yy"
{
currentMaterial->setName( (yyvsp[0].charValue) );
}
break;
case 114:
-#line 561 "src/cfgparser.yy"
+#line 563 "src/cfgparser.yy"
{
currentMaterial->setAmbientRefl( ntlColor((yyvsp[-2].floatValue),(yyvsp[-1].floatValue),(yyvsp[0].floatValue)) );
}
break;
case 115:
-#line 566 "src/cfgparser.yy"
+#line 568 "src/cfgparser.yy"
{
currentMaterial->setDiffuseRefl( ntlColor((yyvsp[-2].floatValue),(yyvsp[-1].floatValue),(yyvsp[0].floatValue)) );
}
break;
case 116:
-#line 571 "src/cfgparser.yy"
+#line 573 "src/cfgparser.yy"
{
currentMaterial->setSpecular( (yyvsp[-1].floatValue) );
currentMaterial->setSpecExponent( (yyvsp[0].floatValue) );
@@ -1969,56 +1971,56 @@ yyreduce:
break;
case 117:
-#line 577 "src/cfgparser.yy"
+#line 579 "src/cfgparser.yy"
{
currentMaterial->setMirror( (yyvsp[0].floatValue) );
}
break;
case 118:
-#line 582 "src/cfgparser.yy"
+#line 584 "src/cfgparser.yy"
{
currentMaterial->setTransparence( (yyvsp[0].floatValue) );
}
break;
case 119:
-#line 587 "src/cfgparser.yy"
+#line 589 "src/cfgparser.yy"
{
currentMaterial->setRefracIndex( (yyvsp[0].floatValue) );
}
break;
case 120:
-#line 592 "src/cfgparser.yy"
+#line 594 "src/cfgparser.yy"
{
currentMaterial->setTransAdditive( (yyvsp[0].floatValue) );
}
break;
case 121:
-#line 597 "src/cfgparser.yy"
+#line 599 "src/cfgparser.yy"
{
currentMaterial->setTransAttCol( ntlColor((yyvsp[-2].floatValue),(yyvsp[-1].floatValue),(yyvsp[0].floatValue)) );
}
break;
case 122:
-#line 602 "src/cfgparser.yy"
+#line 604 "src/cfgparser.yy"
{
currentMaterial->setFresnel( (yyvsp[0].intValue) );
}
break;
case 123:
-#line 613 "src/cfgparser.yy"
+#line 615 "src/cfgparser.yy"
{
currentAttrib = new AttributeList((yyvsp[-1].charValue));
currentAttrName = (yyvsp[-1].charValue); }
break;
case 124:
-#line 616 "src/cfgparser.yy"
+#line 618 "src/cfgparser.yy"
{ // store attribute
//std::cerr << " NEW ATTR " << currentAttrName << std::endl;
//currentAttrib->print();
@@ -2027,12 +2029,12 @@ yyreduce:
break;
case 129:
-#line 629 "src/cfgparser.yy"
+#line 631 "src/cfgparser.yy"
{ currentAttrValue.clear(); currentAttribAddName = (yyvsp[-1].charValue); }
break;
case 130:
-#line 630 "src/cfgparser.yy"
+#line 632 "src/cfgparser.yy"
{
currentAttrib->addAttr( currentAttribAddName, currentAttrValue, lineCount, true);
//std::cerr << " ADD ATTRCHANNEL " << currentAttribAddName << std::endl;
@@ -2041,12 +2043,12 @@ yyreduce:
break;
case 132:
-#line 637 "src/cfgparser.yy"
+#line 639 "src/cfgparser.yy"
{ currentAttrValue.clear(); currentAttribAddName = (yyvsp[-1].charValue); }
break;
case 133:
-#line 638 "src/cfgparser.yy"
+#line 640 "src/cfgparser.yy"
{
currentAttrib->addAttr( currentAttribAddName, currentAttrValue, lineCount, false);
//std::cerr << " ADD ATTRNORM " << currentAttribAddName << std::endl;
@@ -2055,21 +2057,21 @@ yyreduce:
break;
case 135:
-#line 645 "src/cfgparser.yy"
+#line 647 "src/cfgparser.yy"
{
//std::cerr << "LLL "<<$2<<std::endl; // ignore newline entries
if(strcmp((yyvsp[0].charValue),"\n")) currentAttrValue.push_back((yyvsp[0].charValue)); }
break;
case 136:
-#line 648 "src/cfgparser.yy"
+#line 650 "src/cfgparser.yy"
{
//std::cerr << "LRR "<<$1<<std::endl;
if(strcmp((yyvsp[0].charValue),"\n")) currentAttrValue.push_back((yyvsp[0].charValue)); }
break;
case 138:
-#line 662 "src/cfgparser.yy"
+#line 664 "src/cfgparser.yy"
{
if ( ((yyvsp[0].floatValue) < 0.0) || ((yyvsp[0].floatValue) > 1.0) ) {
yyerror("Value out of range (only 0 to 1 allowed)");
@@ -2081,17 +2083,17 @@ yyreduce:
break;
case 139:
-#line 674 "src/cfgparser.yy"
+#line 676 "src/cfgparser.yy"
{ (yyval.floatValue) = (yyvsp[0].floatValue); }
break;
case 140:
-#line 676 "src/cfgparser.yy"
+#line 678 "src/cfgparser.yy"
{ (yyval.floatValue) = (float) (yyvsp[0].intValue); /* conversion from integers */ }
break;
case 141:
-#line 682 "src/cfgparser.yy"
+#line 684 "src/cfgparser.yy"
{
if ( (yyvsp[0].intValue) <= 0 ) {
yy_error("Value out of range (has to be above zero)");
@@ -2103,7 +2105,7 @@ yyreduce:
break;
case 142:
-#line 693 "src/cfgparser.yy"
+#line 695 "src/cfgparser.yy"
{
//cout << " " << $1 << " ";
if ( (yyvsp[0].intValue) < 0 ) {
@@ -2116,7 +2118,7 @@ yyreduce:
break;
case 143:
-#line 705 "src/cfgparser.yy"
+#line 707 "src/cfgparser.yy"
{
if( ( (yyvsp[0].intValue) != 0 ) && ( (yyvsp[0].intValue) != 1 ) ) {
yy_error("Boolean value has to be 1|0, 'true'|'false' or 'on'|'off'!");
@@ -2130,7 +2132,7 @@ yyreduce:
}
/* Line 1037 of yacc.c. */
-#line 2134 "bld-std-gcc/src/cfgparser.cpp"
+#line 2136 "bld-std-gcc/src/cfgparser.cpp"
yyvsp -= yylen;
yyssp -= yylen;
@@ -2358,7 +2360,7 @@ yyreturn:
}
-#line 713 "src/cfgparser.yy"
+#line 715 "src/cfgparser.yy"
/*---------------------------------------------------------------------------*/
diff --git a/intern/elbeem/intern/cfgparser.h b/intern/elbeem/intern/cfgparser.h
index 20b46f4e346..2b7791a78cb 100644
--- a/intern/elbeem/intern/cfgparser.h
+++ b/intern/elbeem/intern/cfgparser.h
@@ -244,7 +244,7 @@
#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
-#line 87 "src/cfgparser.yy"
+#line 85 "src/cfgparser.yy"
typedef union YYSTYPE {
int intValue;
float floatValue;
diff --git a/intern/elbeem/intern/elbeem.cpp b/intern/elbeem/intern/elbeem.cpp
index a1072d84297..8e96879737f 100644
--- a/intern/elbeem/intern/elbeem.cpp
+++ b/intern/elbeem/intern/elbeem.cpp
@@ -12,7 +12,7 @@
#include "ntl_blenderdumper.h"
extern "C" void elbeemCheckDebugEnv(void);
-#include "ntl_scene.h"
+#include "ntl_world.h"
#include "ntl_geometrymodel.h"
/*****************************************************************************/
@@ -29,15 +29,51 @@ int guiRoiMaxLev=6, guiRoiMinLev=0;
//! global raytracer pointer (=world)
ntlWorld *gpWorld = NULL;
-//! debug output switch
-bool myDebugOut = false;
-//! global leave program / abort variable
-bool gQuit = false;
+// API
+// reset elbeemSimulationSettings struct with defaults
+extern "C"
+void elbeemResetSettings(elbeemSimulationSettings *set) {
+ if(!set) return;
+ set->version = 2;
+ for(int i=0 ; i<3; i++) set->geoStart[i] = 0.0;
+ for(int i=0 ; i<3; i++) set->geoSize[i] = 1.0;
+ set->resolutionxyz = 64;
+ set->previewresxyz = 24;
+ set->realsize = 1.0;
+ set->viscosity = 0.000001;
-// API
+ for(int i=0 ; i<2; i++) set->gravity[i] = 0.0;
+ set->gravity[2] = -9.81;
+
+ set->animStart = 0;
+ set->aniFrameTime = 0.01;
+ set->noOfFrames = 10;
+ set->gstar = 0.005;
+ set->maxRefine = -1;
+ set->generateParticles = 1.0;
+ strcpy(set->outputPath,"./elbeemdata_");
+
+ set->channelSizeFrameTime=0;
+ set->channelFrameTime=NULL;
+ set->channelSizeViscosity=0;
+ set->channelViscosity=NULL;
+ set->channelSizeGravity=0;
+ set->channelGravity=NULL;
+ set->obstacleType= FLUIDSIM_OBSTACLE_NOSLIP;
+ set->obstaclePartslip= 0.;
+ set->generateVertexVectors = 0;
+ set->surfaceSmoothing = 1.;
+
+ // init identity
+ for(int i=0; i<16; i++) set->surfaceTrafo[i] = 0.0;
+ for(int i=0; i<4; i++) set->surfaceTrafo[i*4+i] = 1.0;
+}
+
+// start fluidsim init
+extern "C"
int elbeemInit(elbeemSimulationSettings *settings) {
gElbeemState = SIMWORLD_INVALID;
strcpy(gElbeemErrorString,"[none]");
@@ -51,10 +87,41 @@ int elbeemInit(elbeemSimulationSettings *settings) {
return 0;
}
+// reset elbeemMesh struct with zeroes
+extern "C"
+void elbeemResetMesh(elbeemMesh *mesh) {
+ if(!mesh) return;
+ mesh->type = 0;
+ mesh->numVertices = 0;
+ mesh->vertices = NULL;
+ mesh->numTriangles = 0;
+ mesh->triangles = NULL;
+ mesh->channelSizeTranslation = 0;
+ mesh->channelTranslation = NULL;
+ mesh->channelSizeRotation = 0;
+ mesh->channelRotation = NULL;
+ mesh->channelSizeScale = 0;
+ mesh->channelScale = NULL;
+ mesh->channelSizeActive = 0;
+ mesh->channelActive = NULL;
+ mesh->channelSizeInitialVel = 0;
+ mesh->channelInitialVel = NULL;
+ mesh->localInivelCoords = 0;
+ mesh->obstacleType= FLUIDSIM_OBSTACLE_NOSLIP;
+ mesh->obstaclePartslip= 0.;
+ mesh->name = "[unnamed]";
+}
+
+// add mesh as fluidsim object
+extern "C"
int elbeemAddMesh(elbeemMesh *mesh) {
int initType = -1;
switch(mesh->type) {
- case OB_FLUIDSIM_OBSTACLE: initType = FGI_BNDNO; break;
+ case OB_FLUIDSIM_OBSTACLE:
+ if (mesh->obstacleType==FLUIDSIM_OBSTACLE_PARTSLIP) initType = FGI_BNDPART;
+ else if(mesh->obstacleType==FLUIDSIM_OBSTACLE_FREESLIP) initType = FGI_BNDFREE;
+ else /*if(mesh->obstacleType==FLUIDSIM_OBSTACLE_NOSLIP)*/ initType = FGI_BNDNO;
+ break;
case OB_FLUIDSIM_FLUID: initType = FGI_FLUID; break;
case OB_FLUIDSIM_INFLOW: initType = FGI_MBNDINFLOW; break;
case OB_FLUIDSIM_OUTFLOW: initType = FGI_MBNDOUTFLOW; break;
@@ -63,15 +130,30 @@ int elbeemAddMesh(elbeemMesh *mesh) {
if(initType<0) return 1;
ntlGeometryObjModel *obj = new ntlGeometryObjModel( );
- gpWorld->getRenderGlobals()->getScene()->addGeoClass( obj );
+ gpWorld->getRenderGlobals()->getSimScene()->addGeoClass( obj );
obj->initModel(mesh->numVertices, mesh->vertices, mesh->numTriangles, mesh->triangles);
- obj->setGeoInitId(true);
+ if(mesh->name) obj->setName(std::string(mesh->name));
+ else obj->setName(std::string("[unnamed]"));
+ obj->setGeoInitId(1);
obj->setGeoInitIntersect(true);
obj->setGeoInitType(initType);
- obj->setInitialVelocity( ntlVec3Gfx(mesh->iniVelx, mesh->iniVely, mesh->iniVelz) );
+ obj->setGeoPartSlipValue(mesh->obstaclePartslip);
+ // use channel instead, obj->setInitialVelocity( ntlVec3Gfx(mesh->iniVelocity[0], mesh->iniVelocity[1], mesh->iniVelocity[2]) );
+ obj->initChannels(
+ mesh->channelSizeTranslation, mesh->channelTranslation,
+ mesh->channelSizeRotation, mesh->channelRotation,
+ mesh->channelSizeScale, mesh->channelScale,
+ mesh->channelSizeActive, mesh->channelActive,
+ mesh->channelSizeInitialVel, mesh->channelInitialVel
+ );
+ obj->setLocalCoordInivel( mesh->localInivelCoords );
+
+ debMsgStd("elbeemAddMesh",DM_MSG,"Added elbeem mesh: "<<obj->getName()<<" type="<<initType<<" "<<obj->getIsAnimated(), 9 );
return 0;
}
+// do the actual simulation
+extern "C"
int elbeemSimulate(void) {
if(!gpWorld) return 1;
@@ -82,7 +164,7 @@ int elbeemSimulate(void) {
myTime_t timestart = getTime();
gpWorld->renderAnimation();
myTime_t timeend = getTime();
- debMsgStd("performElbeemSimulation",DM_NOTIFY, "El'Beem simulation done, time: "<<((timeend-timestart)/(double)1000.0) <<" seconds.\n", 2 );
+ debMsgStd("elbeemSimulate",DM_NOTIFY, "El'Beem simulation done, time: "<<getTimeString(timeend-timestart)<<".\n", 2 );
// ok, we're done...
delete gpWorld;
@@ -95,4 +177,121 @@ int elbeemSimulate(void) {
}
+// global vector to flag values to remove
+vector<int> gKeepVal;
+
+#define SIMPLIFY_FLOAT_EPSILON (1e-6f)
+#define SIMPLIFY_DOUBLE_EPSILON (1e-12f)
+#define SFLOATEQ(x,y) (ABS((x)-(y)) < SIMPLIFY_FLOAT_EPSILON)
+#define SDOUBLEEQ(x,y) (ABS((x)-(y)) < SIMPLIFY_DOUBLE_EPSILON)
+#define SVECFLOATEQ(x,y) ( \
+ (ABS((x)[0]-(y)[0]) < SIMPLIFY_FLOAT_EPSILON) && \
+ (ABS((x)[1]-(y)[1]) < SIMPLIFY_FLOAT_EPSILON) && \
+ (ABS((x)[2]-(y)[2]) < SIMPLIFY_FLOAT_EPSILON) )
+
+// helper function - simplify animation channels
+extern "C"
+int elbeemSimplifyChannelFloat(float *channel, int* size) {
+ bool changed = false;
+ int nsize = *size;
+ int orgsize = *size;
+ if(orgsize<1) return false;
+ gKeepVal.resize( orgsize );
+ for(int i=0; i<orgsize; i++) { gKeepVal[i] = true; }
+ const bool debugSF = false;
+
+ float last = channel[0 + 0];
+ for(int i=1; i<orgsize; i++) {
+ float curr = channel[2*i + 0];
+ bool remove = false;
+ if(SFLOATEQ(curr,last)) remove = true;
+ // dont remove if next value is different
+ if((remove)&&(i<orgsize-1)) {
+ float next = channel[2*(i+1)+0];
+ if(!SFLOATEQ(next,curr)) remove = false;
+ }
+ if(remove) {
+ changed = true;
+ gKeepVal[i] = false;
+ nsize--;
+ }
+ if(debugSF) errMsg("elbeemSimplifyChannelFloat","i"<<i<<"/"<<orgsize<<" v"<<channel[ (i*2) + 0 ]<<" t"<<channel[ (i*2) + 1 ]<<" nsize="<<nsize<<" r"<<remove );
+ last = curr;
+ }
+
+ if(changed) {
+ nsize = 1;
+ for(int i=1; i<orgsize; i++) {
+ if(gKeepVal[i]) {
+ channel[ (nsize*2) + 0 ] = channel[ (i*2) + 0 ];
+ channel[ (nsize*2) + 1 ] = channel[ (i*2) + 1 ];
+ nsize++;
+ }
+ }
+ *size = nsize;
+ }
+
+ if(debugSF) for(int i=1; i<nsize; i++) {
+ errMsg("elbeemSimplifyChannelFloat","n i"<<i<<"/"<<nsize<<" v"<<channel[ (i*2) + 0 ]<<" t"<<channel[ (i*2) + 1 ] );
+ }
+
+ return changed;
+}
+
+extern "C"
+int elbeemSimplifyChannelVec3(float *channel, int* size) {
+ bool changed = false;
+ int nsize = *size;
+ int orgsize = *size;
+ if(orgsize<1) return false;
+ gKeepVal.resize( orgsize );
+ for(int i=0; i<orgsize; i++) { gKeepVal[i] = true; }
+ const bool debugVF = false;
+
+ ntlVec3f last( channel[0 + 0], channel[0 + 1], channel[0 + 2] );
+ for(int i=1; i<orgsize; i++) {
+ ntlVec3f curr( channel[4*i + 0], channel[4*i + 1], channel[4*i + 2]);
+ bool remove = false;
+ if(SVECFLOATEQ(curr,last)) remove = true;
+ // dont remove if next value is different
+ if((remove)&&(i<orgsize-1)) {
+ ntlVec3f next( channel[4*(i+1)+0], channel[4*(i+1)+1], channel[4*(i+1)+2]);
+ if(!SVECFLOATEQ(next,curr)) remove = false;
+ }
+ if(remove) {
+ changed = true;
+ gKeepVal[i] = false;
+ nsize--;
+ }
+ if(debugVF) errMsg("elbeemSimplifyChannelVec3","i"<<i<<"/"<<orgsize<<" v"<<
+ channel[ (i*4) + 0 ]<<","<< channel[ (i*4) + 1 ]<<","<< channel[ (i*4) + 2 ]<<
+ " t"<<channel[ (i*4) + 3 ]<<" nsize="<<nsize<<" r"<<remove );
+ last = curr;
+ }
+
+ if(changed) {
+ nsize = 1;
+ for(int i=1; i<orgsize; i++) {
+ if(gKeepVal[i]) {
+ for(int j=0; j<4; j++){ channel[ (nsize*4) + j ] = channel[ (i*4) + j ]; }
+ nsize++;
+ }
+ }
+ *size = nsize;
+ }
+
+ if(debugVF) for(int i=1; i<nsize; i++) {
+ errMsg("elbeemSimplifyChannelVec3","n i"<<i<<"/"<<nsize<<" v"<<
+ channel[ (i*4) + 0 ]<<","<< channel[ (i*4) + 1 ]<<","<< channel[ (i*4) + 2 ]<<
+ " t"<<channel[ (i*4) + 3 ] );
+ }
+
+ return changed;
+}
+
+
+#undef SIMPLIFY_FLOAT_EPSILON
+#undef SIMPLIFY_DOUBLE_EPSILON
+#undef SFLOATEQ
+#undef SDOUBLEEQ
diff --git a/intern/elbeem/intern/elbeem.h b/intern/elbeem/intern/elbeem.h
index efbda58a096..83a9cb99afc 100644
--- a/intern/elbeem/intern/elbeem.h
+++ b/intern/elbeem/intern/elbeem.h
@@ -11,21 +11,6 @@
#define ELBEEM_API_H
-
-/*! fluid geometry init types */
-#define FGI_FLAGSTART 16
-#define FGI_FLUID (1<<(FGI_FLAGSTART+ 0))
-#define FGI_NO_FLUID (1<<(FGI_FLAGSTART+ 1))
-#define FGI_BNDNO (1<<(FGI_FLAGSTART+ 2))
-#define FGI_BNDFREE (1<<(FGI_FLAGSTART+ 3))
-#define FGI_BNDPART (1<<(FGI_FLAGSTART+ 4))
-#define FGI_NO_BND (1<<(FGI_FLAGSTART+ 5))
-#define FGI_MBNDINFLOW (1<<(FGI_FLAGSTART+ 6))
-#define FGI_MBNDOUTFLOW (1<<(FGI_FLAGSTART+ 7))
-
-#define FGI_ALLBOUNDS ( FGI_BNDNO | FGI_BNDFREE | FGI_BNDPART | FGI_MBNDINFLOW | FGI_MBNDOUTFLOW )
-
-
/*! blender types for mesh->type */
//#define OB_FLUIDSIM_DOMAIN 2
#define OB_FLUIDSIM_FLUID 4
@@ -33,6 +18,10 @@
#define OB_FLUIDSIM_INFLOW 16
#define OB_FLUIDSIM_OUTFLOW 32
+#define FLUIDSIM_OBSTACLE_NOSLIP 1
+#define FLUIDSIM_OBSTACLE_PARTSLIP 2
+#define FLUIDSIM_OBSTACLE_FREESLIP 3
+
// global settings for the simulation
typedef struct elbeemSimulationSettings {
@@ -51,16 +40,39 @@ typedef struct elbeemSimulationSettings {
/* fluid properties */
double viscosity;
/* gravity strength */
- float gravx,gravy,gravz;
+ float gravity[3];
/* anim start end time */
float animStart, aniFrameTime;
+ /* no. of frames to simulate & output */
+ short noOfFrames;
/* g star param (LBM compressibility) */
float gstar;
/* activate refinement? */
short maxRefine;
+ /* amount of particles to generate (0=off) */
+ float generateParticles;
/* store output path, and file prefix for baked fluid surface */
- char surfdataPath[160+80];
+ char outputPath[160+80];
+
+ /* channel for frame time, visc & gravity animations */
+ int channelSizeFrameTime;
+ float *channelFrameTime;
+ int channelSizeViscosity;
+ float *channelViscosity;
+ int channelSizeGravity;
+ float *channelGravity; // vector
+
+ /* boundary types and settings for domain walls */
+ short obstacleType;
+ float obstaclePartslip;
+ /* generate speed vectors for vertices (e.g. for image based motion blur)*/
+ short generateVertexVectors;
+ /* strength of surface smoothing */
+ float surfaceSmoothing;
+
+ /* global transformation to apply to fluidsim mesh */
+ float surfaceTrafo[4*4];
} elbeemSimulationSettings;
@@ -69,9 +81,6 @@ typedef struct elbeemMesh {
/* obstacle,fluid or inflow... */
short type;
- /* initial velocity (for fluid/inflow) */
- float iniVelx,iniVely,iniVelz;
-
/* vertices */
int numVertices;
float *vertices; // = float[][3];
@@ -79,13 +88,46 @@ typedef struct elbeemMesh {
/* triangles */
int numTriangles;
int *triangles; // = int[][3];
+
+ /* animation channels */
+ int channelSizeTranslation;
+ float *channelTranslation;
+ int channelSizeRotation;
+ float *channelRotation;
+ int channelSizeScale;
+ float *channelScale;
+
+ /* active channel */
+ int channelSizeActive;
+ float *channelActive;
+ /* initial velocity channel (e.g. for inflow) */
+ int channelSizeInitialVel;
+ float *channelInitialVel; // vector
+ /* use initial velocity in object coordinates? (e.g. for rotation) */
+ short localInivelCoords;
+ /* boundary types and settings */
+ short obstacleType;
+ float obstaclePartslip;
+
+ /* name of the mesh, mostly for debugging */
+ char *name;
} elbeemMesh;
// API functions
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+// reset elbeemSimulationSettings struct with defaults
+void elbeemResetSettings(struct elbeemSimulationSettings*);
+
// start fluidsim init
int elbeemInit(struct elbeemSimulationSettings*);
+// reset elbeemMesh struct with zeroes
+void elbeemResetMesh(struct elbeemMesh*);
+
// add mesh as fluidsim object
int elbeemAddMesh(struct elbeemMesh*);
@@ -93,5 +135,30 @@ int elbeemAddMesh(struct elbeemMesh*);
int elbeemSimulate(void);
+// helper function - simplify animation channels
+// returns if the channel and its size changed
+int elbeemSimplifyChannelFloat(float *channel, int *size);
+int elbeemSimplifyChannelVec3(float *channel, int *size);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+/******************************************************************************/
+// internal defines, do not use for setting up simulation
+
+/*! fluid geometry init types */
+#define FGI_FLAGSTART 16
+#define FGI_FLUID (1<<(FGI_FLAGSTART+ 0))
+#define FGI_NO_FLUID (1<<(FGI_FLAGSTART+ 1))
+#define FGI_BNDNO (1<<(FGI_FLAGSTART+ 2))
+#define FGI_BNDFREE (1<<(FGI_FLAGSTART+ 3))
+#define FGI_BNDPART (1<<(FGI_FLAGSTART+ 4))
+#define FGI_NO_BND (1<<(FGI_FLAGSTART+ 5))
+#define FGI_MBNDINFLOW (1<<(FGI_FLAGSTART+ 6))
+#define FGI_MBNDOUTFLOW (1<<(FGI_FLAGSTART+ 7))
+
+#define FGI_ALLBOUNDS ( FGI_BNDNO | FGI_BNDFREE | FGI_BNDPART | FGI_MBNDINFLOW | FGI_MBNDOUTFLOW )
+
#endif // ELBEEM_API_H
diff --git a/intern/elbeem/intern/globals.h b/intern/elbeem/intern/globals.h
deleted file mode 100644
index c2a092ab1c9..00000000000
--- a/intern/elbeem/intern/globals.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/******************************************************************************
- *
- * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method
- * 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 2003-2005 Nils Thuerey
- *
- * Global variables (unavoidable at times...)
- * all defines in main.cpp
- *
- *****************************************************************************/
-
-
-/*****************************************************************************/
-//! user interface variables
-
-// global raytracer pointer (=world)
-class ntlWorld;
-extern ntlWorld *gpWorld;
-
-// debug output switch
-extern bool myDebugOut;
-
-// global leave program / abort variable
-extern bool gQuit;
-
diff --git a/intern/elbeem/intern/isosurface.cpp b/intern/elbeem/intern/isosurface.cpp
index 545cdc89eff..ed0fab289d8 100644
--- a/intern/elbeem/intern/isosurface.cpp
+++ b/intern/elbeem/intern/isosurface.cpp
@@ -9,7 +9,7 @@
#include "isosurface.h"
#include "mcubes_tables.h"
-#include "ntl_scene.h"
+#include "ntl_ray.h"
#include <algorithm>
#include <stdio.h>
@@ -20,23 +20,15 @@
#include <ieeefp.h>
#endif
-/*
-template class vector<IsoLevelVertex>;
-template class vector<int>;
-template class vector<unsigned int>;
-template class vector<float>;
-template class vector<ntlVec3Gfx>;
-template class vector< vector<int> >;
-*/
/******************************************************************************
* Constructor
*****************************************************************************/
-IsoSurface::IsoSurface(double iso, double blend) :
+IsoSurface::IsoSurface(double iso) :
ntlGeometryObject(),
mSizex(-1), mSizey(-1), mSizez(-1),
+ mpData(NULL),
mIsoValue( iso ),
- mBlendVal( blend ),
mPoints(),
mpEdgeVerticesX(NULL), mpEdgeVerticesY(NULL), mpEdgeVerticesZ(NULL),
mIndices(),
@@ -44,7 +36,10 @@ IsoSurface::IsoSurface(double iso, double blend) :
mStart(0.0), mEnd(0.0), mDomainExtent(0.0),
mInitDone(false),
mSmoothSurface(0.0), mSmoothNormals(0.0),
- mAcrossEdge(), mAdjacentFaces()
+ mAcrossEdge(), mAdjacentFaces(),
+ mCutoff(-1), // off by default
+ mFlagCnt(1),
+ mSCrad1(0.), mSCrad2(0.), mSCcenter(0.)
{
}
@@ -87,16 +82,6 @@ void IsoSurface::initializeIsosurface(int setx, int sety, int setz, ntlVec3Gfx e
// marching cubes are ready
mInitDone = true;
- /*unsigned long int memCnt = (3*sizeof(int)*nodes + sizeof(float)*nodes);
- double memd = memCnt;
- char *sizeStr = "";
- const double sfac = 1000.0;
- if(memd>sfac){ memd /= sfac; sizeStr="KB"; }
- if(memd>sfac){ memd /= sfac; sizeStr="MB"; }
- if(memd>sfac){ memd /= sfac; sizeStr="GB"; }
- if(memd>sfac){ memd /= sfac; sizeStr="TB"; }
-
- debMsgStd("IsoSurface::initializeIsosurface",DM_MSG,"Inited "<<PRINT_VEC(setx,sety,setz)<<" alloced:"<< memd<<" "<<sizeStr<<"." ,10);*/
}
@@ -107,11 +92,10 @@ void IsoSurface::initializeIsosurface(int setx, int sety, int setz, ntlVec3Gfx e
*****************************************************************************/
IsoSurface::~IsoSurface( void )
{
-
+ if(mpData) delete [] mpData;
if(mpEdgeVerticesX) delete [] mpEdgeVerticesX;
if(mpEdgeVerticesY) delete [] mpEdgeVerticesY;
if(mpEdgeVerticesZ) delete [] mpEdgeVerticesZ;
-
}
@@ -132,10 +116,10 @@ void IsoSurface::triangulate( void )
return;
}
- // get grid spacing
- gsx = (mEnd[0]-mStart[0])/(double)(mSizex-1.0);
- gsy = (mEnd[1]-mStart[1])/(double)(mSizey-1.0);
- gsz = (mEnd[2]-mStart[2])/(double)(mSizez-1.0);
+ // get grid spacing (-2 to have same spacing as sim)
+ gsx = (mEnd[0]-mStart[0])/(double)(mSizex-2.0);
+ gsy = (mEnd[1]-mStart[1])/(double)(mSizey-2.0);
+ gsz = (mEnd[2]-mStart[2])/(double)(mSizez-2.0);
// clean up previous frame
mIndices.clear();
@@ -169,13 +153,13 @@ void IsoSurface::triangulate( void )
0,0,0,0, 1,1,1,1 };
// let the cubes march
- pz = mStart[2]-gsz;
+ pz = mStart[2]-gsz*0.5;
for(int k=1;k<(mSizez-2);k++) {
pz += gsz;
- py = mStart[1]-gsy;
+ py = mStart[1]-gsy*0.5;
for(int j=1;j<(mSizey-2);j++) {
py += gsy;
- px = mStart[0]-gsx;
+ px = mStart[0]-gsx*0.5;
for(int i=1;i<(mSizex-2);i++) {
px += gsx;
int baseIn = ISOLEVEL_INDEX( i+0, j+0, k+0);
@@ -275,6 +259,12 @@ void IsoSurface::triangulate( void )
}
+ const int coAdd=2;
+ if(i<coAdd+mCutoff) continue;
+ if(j<coAdd+mCutoff) continue;
+ if((mCutoff>0) && (k<coAdd)) continue;
+ if(i>mSizex-2-coAdd-mCutoff) continue;
+ if(j>mSizey-2-coAdd-mCutoff) continue;
// Create the triangles...
for(int e=0; mcTriTable[cubeIndex][e]!=-1; e+=3) {
@@ -283,13 +273,10 @@ void IsoSurface::triangulate( void )
mIndices.push_back( triIndices[ mcTriTable[cubeIndex][e+1] ] );
mIndices.push_back( triIndices[ mcTriTable[cubeIndex][e+2] ] );
}
-
- }
- }
-
+ }//i
+ }// j
} // k
-
// precalculate normals using an approximation of the scalar field gradient
for(int ni=0;ni<(int)mPoints.size();ni++) {
@@ -297,11 +284,10 @@ void IsoSurface::triangulate( void )
normalize( mPoints[ni].n );
}
- //for(int i=0; i<mLoopSubdivs; i++) { subdivide(); }// DEBUG test
- if(mSmoothSurface>0.0) { smoothSurface(mSmoothSurface); }
+ if(mSmoothSurface>0.0) { smoothSurface(mSmoothSurface, (mSmoothNormals<=0.0) ); }
if(mSmoothNormals>0.0) { smoothNormals(mSmoothNormals); }
myTime_t tritimeend = getTime();
- debMsgStd("IsoSurface::triangulate",DM_MSG,"took "<< ((tritimeend-tritimestart)/(double)1000.0)<<"s, ss="<<mSmoothSurface<<" sm="<<mSmoothNormals , 10 );
+ debMsgStd("IsoSurface::triangulate",DM_MSG,"took "<< getTimeString(tritimeend-tritimestart)<<", S("<<mSmoothSurface<<","<<mSmoothNormals<<")" , 10 );
}
@@ -406,7 +392,6 @@ inline ntlVec3Gfx IsoSurface::getNormal(int i, int j,int k) {
-
/******************************************************************************
*
* Surface improvement
@@ -418,334 +403,109 @@ inline ntlVec3Gfx IsoSurface::getNormal(int i, int j,int k) {
*
*****************************************************************************/
-
-// Subdivide a mesh allways loop
-/*void IsoSurface::subdivide()
-{
- int i;
-
- mAdjacentFaces.clear();
- mAcrossEdge.clear();
-
- //void TriMesh::need_adjacentfaces()
- {
- vector<int> numadjacentfaces(mPoints.size());
- //errMsg("SUBDIV ADJFA1", " "<<mPoints.size()<<" - "<<numadjacentfaces.size() );
- int i;
- for (i = 0; i < (int)mIndices.size()/3; i++) {
- numadjacentfaces[mIndices[i*3 + 0]]++;
- numadjacentfaces[mIndices[i*3 + 1]]++;
- numadjacentfaces[mIndices[i*3 + 2]]++;
- }
-
- mAdjacentFaces.resize(mPoints.size());
- for (i = 0; i < (int)mPoints.size(); i++)
- mAdjacentFaces[i].reserve(numadjacentfaces[i]);
-
- for (i = 0; i < (int)mIndices.size()/3; i++) {
- for (int j = 0; j < 3; j++)
- mAdjacentFaces[mIndices[i*3 + j]].push_back(i);
- }
-
- }
-
- // Find the face across each edge from each other face (-1 on boundary)
- // If topology is bad, not necessarily what one would expect...
- //void TriMesh::need_across_edge()
- {
- mAcrossEdge.resize(mIndices.size(), -1);
-
- for (int i = 0; i < (int)mIndices.size()/3; i++) {
- for (int j = 0; j < 3; j++) {
- if (mAcrossEdge[i*3 + j] != -1)
- continue;
- int v1 = mIndices[i*3 + ((j+1)%3)];
- int v2 = mIndices[i*3 + ((j+2)%3)];
- const vector<int> &a1 = mAdjacentFaces[v1];
- const vector<int> &a2 = mAdjacentFaces[v2];
- for (int k1 = 0; k1 < (int)a1.size(); k1++) {
- int other = a1[k1];
- if (other == i)
- continue;
- vector<int>::const_iterator it =
- std::find(a2.begin(), a2.end(), other);
- if (it == a2.end())
- continue;
-
- //int ind = (faces[other].indexof(v1)+1)%3;
- int ind = -1;
- if( mIndices[other*3+0] == (unsigned int)v1 ) ind = 0;
- else if( mIndices[other*3+1] == (unsigned int)v1 ) ind = 1;
- else if( mIndices[other*3+2] == (unsigned int)v1 ) ind = 2;
- ind = (ind+1)%3;
-
- if ( (int)mIndices[other*3 + ((ind+1)%3)] != v2)
- continue;
- mAcrossEdge[i*3 + j] = other;
- mAcrossEdge[other*3 + ind] = i;
- break;
- }
- }
- }
-
- //errMsg("SUBDIV ACREDG", "Done.\n");
- }
-
- //errMsg("SUBDIV","start");
- // Introduce new vertices
- int nf = (int)mIndices.size() / 3;
-
- //vector<TriMesh::Face> newverts(nf, TriMesh::Face(-1,-1,-1));
- vector<int> newverts(nf*3); //, TriMesh::Face(-1,-1,-1));
- for(int j=0; j<(int)newverts.size(); j++) newverts[j] = -1;
-
- int old_nv = (int)mPoints.size();
- mPoints.reserve(4 * old_nv);
- vector<int> newvert_count(old_nv + 3*nf); // wichtig...?
- //errMsg("NC", newvert_count.size() );
-
- for (i = 0; i < nf; i++) {
- for (int j = 0; j < 3; j++) {
- int ae = mAcrossEdge[i*3 + j];
- if (newverts[i*3 + j] == -1 && ae != -1) {
- if (mAcrossEdge[ae*3 + 0] == i)
- newverts[i*3 + j] = newverts[ae*3 + 0];
- else if (mAcrossEdge[ae*3 + 1] == i)
- newverts[i*3 + j] = newverts[ae*3 + 1];
- else if (mAcrossEdge[ae*3 + 2] == i)
- newverts[i*3 + j] = newverts[ae*3 + 2];
- }
- if (newverts[i*3 + j] == -1) {
- IsoLevelVertex ilv;
- ilv.v = ntlVec3Gfx(0.0);
- ilv.n = ntlVec3Gfx(0.0);
- mPoints.push_back(ilv);
- newverts[i*3 + j] = (int)mPoints.size() - 1;
- if (ae != -1) {
- if (mAcrossEdge[ae*3 + 0] == i)
- newverts[ae*3 + 0] = newverts[i*3 + j];
- else if (mAcrossEdge[ae*3 + 1] == i)
- newverts[ae*3 + 1] = newverts[i*3 + j];
- else if (mAcrossEdge[ae*3 + 2] == i)
- newverts[ae*3 + 2] = newverts[i*3 + j];
- }
- }
- if(ae != -1) {
- mPoints[newverts[i*3 + j]].v +=
- mPoints[ mIndices[i*3 + ( j )] ].v * 0.25f + // j = 0,1,2?
- mPoints[ mIndices[i*3 + ((j+1)%3)] ].v * 0.375f +
- mPoints[ mIndices[i*3 + ((j+2)%3)] ].v * 0.375f;
-#if RECALCNORMALS==0
- mPoints[newverts[i*3 + j]].n +=
- mPoints[ mIndices[i*3 + ( j )] ].n * 0.25f + // j = 0,1,2?
- mPoints[ mIndices[i*3 + ((j+1)%3)] ].n * 0.375f +
- mPoints[ mIndices[i*3 + ((j+2)%3)] ].n * 0.375f;
-#endif // RECALCNORMALS==0
- } else {
- mPoints[newverts[i*3 + j]].v +=
- mPoints[ mIndices[i*3 + ((j+1)%3)] ].v * 0.5f +
- mPoints[ mIndices[i*3 + ((j+2)%3)] ].v * 0.5f ;
-#if RECALCNORMALS==0
- mPoints[newverts[i*3 + j]].n +=
- mPoints[ mIndices[i*3 + ((j+1)%3)] ].n * 0.5f +
- mPoints[ mIndices[i*3 + ((j+2)%3)] ].n * 0.5f ;
-#endif // RECALCNORMALS==0
- }
-
- newvert_count[newverts[i*3 + j]]++;
- }
- }
- for (i = old_nv; i < (int)mPoints.size(); i++) {
- if (!newvert_count[i])
- continue;
- float scale = 1.0f / newvert_count[i];
- mPoints[i].v *= scale;
-
-#if RECALCNORMALS==0
- //mPoints[i].n *= scale;
- //normalize( mPoints[i].n );
-#endif // RECALCNORMALS==0
- }
-
- // Update old vertices
- for (i = 0; i < old_nv; i++) {
- ntlVec3Gfx bdyavg(0.0), nbdyavg(0.0);
- ntlVec3Gfx norm_bdyavg(0.0), norm_nbdyavg(0.0); // N
- int nbdy = 0, nnbdy = 0;
- int naf = (int)mAdjacentFaces[i].size();
- if (!naf)
- continue;
- for (int j = 0; j < naf; j++) {
- int af = mAdjacentFaces[i][j];
-
- int afi = -1;
- if( mIndices[af*3+0] == (unsigned int)i ) afi = 0;
- else if( mIndices[af*3+1] == (unsigned int)i ) afi = 1;
- else if( mIndices[af*3+2] == (unsigned int)i ) afi = 2;
-
- int n1 = (afi+1) % 3;
- int n2 = (afi+2) % 3;
- if (mAcrossEdge[af*3 + n1] == -1) {
- bdyavg += mPoints[newverts[af*3 + n1]].v;
-#if RECALCNORMALS==0
- //norm_bdyavg += mPoints[newverts[af*3 + n1]].n;
-#endif // RECALCNORMALS==0
- nbdy++;
- } else {
- nbdyavg += mPoints[newverts[af*3 + n1]].v;
-#if RECALCNORMALS==0
- //norm_nbdyavg += mPoints[newverts[af*3 + n1]].n;
-#endif // RECALCNORMALS==0
- nnbdy++;
- }
- if (mAcrossEdge[af*3 + n2] == -1) {
- bdyavg += mPoints[newverts[af*3 + n2]].v;
-#if RECALCNORMALS==0
- //norm_bdyavg += mPoints[newverts[af*3 + n2]].n;
-#endif // RECALCNORMALS==0
- nbdy++;
- } else {
- nbdyavg += mPoints[newverts[af*3 + n2]].v;
-#if RECALCNORMALS==0
- //norm_nbdyavg += mPoints[newverts[af*3 + n2]].n;
-#endif // RECALCNORMALS==0
- nnbdy++;
- }
- }
-
- float alpha;
- ntlVec3Gfx newpt;
- if (nbdy) {
- newpt = bdyavg / (float) nbdy;
- alpha = 0.5f;
- } else if (nnbdy) {
- newpt = nbdyavg / (float) nnbdy;
- if (nnbdy == 6)
- alpha = 1.05;
- else if (nnbdy == 8)
- alpha = 0.86;
- else if (nnbdy == 10)
- alpha = 0.7;
- else
- alpha = 0.6;
- } else {
- continue;
- }
- mPoints[i].v *= 1.0f - alpha;
- mPoints[i].v += newpt * alpha;
-
-#if RECALCNORMALS==0
- //mPoints[i].n *= 1.0f - alpha;
- //mPoints[i].n += newpt * alpha;
-#endif // RECALCNORMALS==0
- }
-
- // Insert new faces
- mIndices.reserve(4*nf);
- for (i = 0; i < nf; i++) {
- mIndices.push_back( mIndices[i*3 + 0]);
- mIndices.push_back( newverts[i*3 + 2]);
- mIndices.push_back( newverts[i*3 + 1]);
-
- mIndices.push_back( mIndices[i*3 + 1]);
- mIndices.push_back( newverts[i*3 + 0]);
- mIndices.push_back( newverts[i*3 + 2]);
-
- mIndices.push_back( mIndices[i*3 + 2]);
- mIndices.push_back( newverts[i*3 + 1]);
- mIndices.push_back( newverts[i*3 + 0]);
-
- mIndices[i*3+0] = newverts[i*3+0];
- mIndices[i*3+1] = newverts[i*3+1];
- mIndices[i*3+2] = newverts[i*3+2];
- }
-
- // recalc normals
-#if RECALCNORMALS==1
- {
- int nf = (int)mIndices.size()/3, nv = (int)mPoints.size(), i;
- for (i = 0; i < nv; i++) {
- mPoints[i].n = ntlVec3Gfx(0.0);
- }
- for (i = 0; i < nf; i++) {
- const ntlVec3Gfx &p0 = mPoints[mIndices[i*3+0]].v;
- const ntlVec3Gfx &p1 = mPoints[mIndices[i*3+1]].v;
- const ntlVec3Gfx &p2 = mPoints[mIndices[i*3+2]].v;
- ntlVec3Gfx a = p0-p1, b = p1-p2, c = p2-p0;
- float l2a = normNoSqrt(a), l2b = normNoSqrt(b), l2c = normNoSqrt(c);
-
- ntlVec3Gfx facenormal = cross(a, b);
-
- mPoints[mIndices[i*3+0]].n += facenormal * (1.0f / (l2a * l2c));
- mPoints[mIndices[i*3+1]].n += facenormal * (1.0f / (l2b * l2a));
- mPoints[mIndices[i*3+2]].n += facenormal * (1.0f / (l2c * l2b));
- }
-
- for (i = 0; i < nv; i++) {
- normalize(mPoints[i].n);
- }
- }
-#else // RECALCNORMALS==1
- for (i = 0; i < (int)mPoints.size(); i++) {
- normalize(mPoints[i].n);
- }
-#endif // RECALCNORMALS==1
-
- //errMsg("SUBDIV","done nv:"<<mPoints.size()<<" nf:"<<mIndices.size() );
-}*/
-
+void IsoSurface::setSmoothRad(float radi1, float radi2, ntlVec3Gfx mscc) {
+ mSCrad1 = radi1*radi1;
+ mSCrad2 = radi2*radi2;
+ mSCcenter = mscc;
+}
// Diffuse a vector field at 1 vertex, weighted by
// a gaussian of width 1/sqrt(invsigma2)
-void IsoSurface::diffuseVertexField(ntlVec3Gfx *field, const int pointerScale, int v, float invsigma2, ntlVec3Gfx &flt)
+bool IsoSurface::diffuseVertexField(ntlVec3Gfx *field, const int pointerScale, int src, float invsigma2, ntlVec3Gfx &flt)
{
+ if((neighbors[src].size()<1) || (pointareas[src]<=0.0)) return 0;
+ const ntlVec3Gfx srcp = mPoints[src].v;
+ const ntlVec3Gfx srcn = mPoints[src].n;
+ if(mSCrad1>0.0 && mSCrad2>0.0) {
+ ntlVec3Gfx dp = mSCcenter-srcp; dp[2] = 0.0; // only xy-plane
+ float rd = normNoSqrt(dp);
+ if(rd > mSCrad2) {
+ //errMsg("TRi","p"<<srcp<<" c"<<mSCcenter<<" rd:"<<rd<<" r1:"<<mSCrad1<<" r2:"<<mSCrad2<<" ");
+ //invsigma2 *= (rd*rd-mSCrad1);
+ //flt = ntlVec3Gfx(100); return 1;
+ return 0;
+ } else if(rd > mSCrad1) {
+ // optimize?
+ float org = 1.0/sqrt(invsigma2);
+ org *= (1.0- (rd-mSCrad1) / (mSCrad2-mSCrad1));
+ invsigma2 = 1.0/(org*org);
+ //flt = ntlVec3Gfx((rd-mSCrad1) / (mSCrad2-mSCrad1)); return 1;
+ //errMsg("TRi","p"<<srcp<<" rd:"<<rd<<" r1:"<<mSCrad1<<" r2:"<<mSCrad2<<" org:"<<org<<" is:"<<invsigma2);
+ //invsigma2 *= (rd*rd-mSCrad1);
+ //return 0;
+ } else {
+ }
+ }
flt = ntlVec3Gfx(0.0);
- flt += *(field+pointerScale*v) *pointareas[v];
- float sum_w = pointareas[v];
- const ntlVec3Gfx &nv = mPoints[v].n;
-
- unsigned &flag = flag_curr;
- flag++;
- flags[v] = flag;
- vector<int> boundary = neighbors[v];
- while (!boundary.empty()) {
- const int bbn = boundary.back();
- boundary.pop_back();
- if (flags[bbn] == flag) continue;
+ flt += *(field+pointerScale*src) *pointareas[src];
+ float sum_w = pointareas[src];
+ //const ntlVec3Gfx &nv = mPoints[src].n;
+
+ int flag = mFlagCnt;
+ mFlagCnt++;
+ flags[src] = flag;
+ //vector<int> mDboundary = neighbors[src];
+ mDboundary = neighbors[src];
+ while (!mDboundary.empty()) {
+ const int bbn = mDboundary.back();
+ mDboundary.pop_back();
+ if(flags[bbn]==flag) continue;
flags[bbn] = flag;
+ // normal check
+ const float nvdot = dot(srcn, mPoints[bbn].n); // faster than before d2 calc?
+ if(nvdot <= 0.0f) continue; // faster than before d2 calc?
+
// gaussian weight of width 1/sqrt(invsigma2)
- const float d2 = invsigma2 * normNoSqrt(mPoints[bbn].v - mPoints[v].v);
+ const float d2 = invsigma2 * normNoSqrt(mPoints[bbn].v - srcp);
if(d2 >= 9.0f) continue; // 25 also possible , slower
- //float w = (d2 >= 9.0f) ? 0.0f : exp(-0.5f*d2);
- float w = exp(-0.5f*d2);
- if(dot(nv, mPoints[bbn].n) <= 0.0f) continue; // faster than before d2 calc?
+ //if(dot(srcn, mPoints[bbn].n) <= 0.0f) continue; // faster than before d2 calc?
+ //float w = (d2 >= 9.0f) ? 0.0f : exp(-0.5f*d2);
+ //float w = expf(-0.5f*d2);
+#if 0
+ float w=1.0;
// Downweight things pointing in different directions
- w *= dot(nv , mPoints[bbn].n);
+ w *= nvdot; //dot(srcn , mPoints[bbn].n);
// Surface area "belonging" to each point
w *= pointareas[bbn];
// Accumulate weight times field at neighbor
flt += *(field+pointerScale*bbn)*w;
-
sum_w += w;
- for (int i = 0; i < (int)neighbors[bbn].size(); i++) {
- int nn = neighbors[bbn][i];
+ // */
+#else
+ // more aggressive smoothing with: float w=1.0;
+ float w=nvdot * pointareas[bbn];
+ // Accumulate weight times field at neighbor
+ flt += *(field+pointerScale*bbn)*w;
+ sum_w += w;
+#endif
+ // */
+
+ for(int i = 0; i < (int)neighbors[bbn].size(); i++) {
+ const int nn = neighbors[bbn][i];
if (flags[nn] == flag) continue;
- boundary.push_back(nn);
+ mDboundary.push_back(nn);
}
}
flt /= sum_w;
+ return 1;
}
-void IsoSurface::smoothSurface(float sigma)
+// REF
+// TestData::getTriangles message: Time for surface generation:3.75s, S(0.0390625,0.1171875)
+ // ntlWorld::ntlWorld message: Time for start-sims:0s
+ // TestData::getTriangles message: Time for surface generation:3.69s, S(0.0390625,0.1171875)
+
+
+
+void IsoSurface::smoothSurface(float sigma, bool normSmooth)
{
int nv = mPoints.size();
if ((int)flags.size() != nv) flags.resize(nv);
int nf = mIndices.size()/3;
{ // need neighbors
-
vector<int> numneighbors(mPoints.size());
int i;
for (i = 0; i < (int)mIndices.size()/3; i++) {
@@ -845,10 +605,11 @@ void IsoSurface::smoothSurface(float sigma)
vector<ntlVec3Gfx> dflt(nv);
for (int i = 0; i < nv; i++) {
- diffuseVertexField( &mPoints[0].v, 2,
- i, invsigma2, dflt[i]);
- // Just keep the displacement
- dflt[i] -= mPoints[i].v;
+ if(diffuseVertexField( &mPoints[0].v, 2,
+ i, invsigma2, dflt[i])) {
+ // Just keep the displacement
+ dflt[i] -= mPoints[i].v;
+ } else { dflt[i] = 0.0; } //?mPoints[i].v; }
}
// Slightly better small-neighborhood approximation
@@ -869,8 +630,9 @@ void IsoSurface::smoothSurface(float sigma)
// Filter displacement field
vector<ntlVec3Gfx> dflt2(nv);
for (int i = 0; i < nv; i++) {
- diffuseVertexField( &dflt[0], 1,
- i, invsigma2, dflt2[i]);
+ if(diffuseVertexField( &dflt[0], 1,
+ i, invsigma2, dflt2[i])) { }
+ else { /*mPoints[i].v=0.0;*/ dflt2[i] = 0.0; }//dflt2[i]; }
}
// Update vertex positions
@@ -881,10 +643,13 @@ void IsoSurface::smoothSurface(float sigma)
// when normals smoothing off, this cleans up quite well
// costs ca. 50% additional time though
float nsFac = 1.5f;
- { float ninvsigma2 = 1.0f / (nsFac*nsFac*sigma*sigma);
+ if(normSmooth) { float ninvsigma2 = 1.0f / (nsFac*nsFac*sigma*sigma);
for (int i = 0; i < nv; i++) {
- diffuseVertexField( &mPoints[0].n, 2, i, ninvsigma2, dflt[i]);
- normalize(dflt[i]);
+ if( diffuseVertexField( &mPoints[0].n, 2, i, ninvsigma2, dflt[i]) ) {
+ normalize(dflt[i]);
+ } else {
+ dflt[i] = mPoints[i].n;
+ }
}
for (int i = 0; i < nv; i++) {
mPoints[i].n = dflt[i];
@@ -896,7 +661,9 @@ void IsoSurface::smoothSurface(float sigma)
void IsoSurface::smoothNormals(float sigma)
{
- { // need neighbor
+ // reuse from smoothSurface
+ if(neighbors.size() != mPoints.size()) {
+ // need neighbor
vector<int> numneighbors(mPoints.size());
int i;
for (i = 0; i < (int)mIndices.size()/3; i++) {
@@ -998,13 +765,13 @@ void IsoSurface::smoothNormals(float sigma)
vector<ntlVec3Gfx> nflt(nv);
for (int i = 0; i < nv; i++) {
- diffuseVertexField( &mPoints[0].n, 2, i, invsigma2, nflt[i]);
- normalize(nflt[i]);
+ if(diffuseVertexField( &mPoints[0].n, 2, i, invsigma2, nflt[i])) {
+ normalize(nflt[i]);
+ } else { nflt[i]=mPoints[i].n; }
}
- for (int i = 0; i < nv; i++) {
- mPoints[i].n = nflt[i];
- }
+ // copy back
+ for (int i = 0; i < nv; i++) { mPoints[i].n = nflt[i]; }
//errMsg("SMNRMLS","done v:"<<sigma); // DEBUG
}
diff --git a/intern/elbeem/intern/isosurface.h b/intern/elbeem/intern/isosurface.h
index 9682b571b21..90a4e11e95f 100644
--- a/intern/elbeem/intern/isosurface.h
+++ b/intern/elbeem/intern/isosurface.h
@@ -40,9 +40,9 @@ class IsoSurface :
public:
/*! Constructor */
- IsoSurface(double iso, double blend);
+ IsoSurface(double iso);
/*! Destructor */
- ~IsoSurface();
+ virtual ~IsoSurface();
/*! Init ararys etc. */
virtual void initializeIsosurface(int setx, int sety, int setz, ntlVec3Gfx extent);
@@ -63,9 +63,6 @@ class IsoSurface :
//! Level of the iso surface
double mIsoValue;
- //! blending distance for marching cubes
- double mBlendVal;
-
//! Store all the triangles vertices
vector<IsoLevelVertex> mPoints;
@@ -96,8 +93,12 @@ class IsoSurface :
vector<int> mAcrossEdge;
vector< vector<int> > mAdjacentFaces;
- vector<unsigned> flags;
- unsigned flag_curr;
+ //! cutoff border area
+ int mCutoff;
+
+ //! trimesh vars
+ vector<int> flags;
+ int mFlagCnt;
vector<ntlVec3Gfx> cornerareas;
vector<float> pointareas;
vector< vector<int> > neighbors;
@@ -116,6 +117,8 @@ class IsoSurface :
//! set loop subdiv num
inline void setSmoothSurface(float set) { mSmoothSurface = set; };
inline void setSmoothNormals(float set) { mSmoothNormals = set; };
+ inline float getSmoothSurface() { return mSmoothSurface; }
+ inline float getSmoothNormals() { return mSmoothNormals; }
// geometry object functions
virtual void getTriangles( vector<ntlTriangle> *triangles,
@@ -155,6 +158,8 @@ class IsoSurface :
return mpData + ISOLEVEL_INDEX(ii+1,jj+1,kk+1);
#endif
}
+ //! set cut off border
+ inline void setCutoff(int set) { mCutoff = set; };
//! OpenGL viz "interface"
unsigned int getIsoVertexCount() {
@@ -169,16 +174,21 @@ class IsoSurface :
unsigned int *getIsoIndexArray() {
return &(mIndices[0]);
}
+
+ // surface smoothing functions
+ void setSmoothRad(float radi1, float radi2, ntlVec3Gfx mscc);
+ void smoothSurface(float val, bool smoothNorm);
+ void smoothNormals(float val);
protected:
- //! computer normal
+ //! compute normal
inline ntlVec3Gfx getNormal(int i, int j,int k);
-
- void subdivide();
- void smoothSurface(float val);
- void smoothNormals(float val);
- void diffuseVertexField(ntlVec3Gfx *field, const int pointerScale, int v, float invsigma2, ntlVec3Gfx &flt);
+ //! smoothing helper function
+ bool diffuseVertexField(ntlVec3Gfx *field, int pointerScale, int v, float invsigma2, ntlVec3Gfx &flt);
+ vector<int> mDboundary;
+ float mSCrad1, mSCrad2;
+ ntlVec3Gfx mSCcenter;
};
diff --git a/intern/elbeem/intern/ntl_blenderdumper.cpp b/intern/elbeem/intern/ntl_blenderdumper.cpp
index e9e67b1a72d..fce5a085f59 100644
--- a/intern/elbeem/intern/ntl_blenderdumper.cpp
+++ b/intern/elbeem/intern/ntl_blenderdumper.cpp
@@ -14,7 +14,8 @@
#include "utilities.h"
#include "ntl_matrices.h"
#include "ntl_blenderdumper.h"
-#include "ntl_scene.h"
+#include "ntl_world.h"
+#include "solver_interface.h"
#include <zlib.h>
@@ -31,17 +32,15 @@ ntlBlenderDumper::ntlBlenderDumper(string filename, bool commandlineMode) :
AttributeList *pAttrs = glob->getBlenderAttributes();
mpTrafo = new ntlMat4Gfx(0.0);
mpTrafo->initId();
- (*mpTrafo) = pAttrs->readMat4Gfx("transform" , (*mpTrafo), "ntlBlenderDumper","mpTrafo", false );
+ pAttrs->readMat4Gfx("transform" , (*mpTrafo), "ntlBlenderDumper","mpTrafo", false, mpTrafo );
}
ntlBlenderDumper::ntlBlenderDumper(elbeemSimulationSettings *settings) :
ntlWorld(settings), mpTrafo(NULL)
{
// same as normal constructor here
- ntlRenderGlobals *glob = mpGlob;
- AttributeList *pAttrs = glob->getBlenderAttributes();
mpTrafo = new ntlMat4Gfx(0.0);
- mpTrafo->initId();
- (*mpTrafo) = pAttrs->readMat4Gfx("transform" , (*mpTrafo), "ntlBlenderDumper","mpTrafo", false );
+ mpTrafo->initArrayCheck(settings->surfaceTrafo);
+ //errMsg("ntlBlenderDumper","mpTrafo inited: "<<(*mpTrafo) );
}
@@ -52,6 +51,7 @@ ntlBlenderDumper::ntlBlenderDumper(elbeemSimulationSettings *settings) :
ntlBlenderDumper::~ntlBlenderDumper()
{
delete mpTrafo;
+ debMsgStd("ntlBlenderDumper",DM_NOTIFY, "ntlBlenderDumper done", 10);
}
/******************************************************************************
@@ -61,11 +61,11 @@ int ntlBlenderDumper::renderScene( void )
{
char nrStr[5]; /* nr conversion */
ntlRenderGlobals *glob = mpGlob;
- ntlScene *scene = mpGlob->getScene();
+ ntlScene *scene = mpGlob->getSimScene();
bool debugOut = true;
-#if ELBEEM_BLENDER==1
+#if ELBEEM_PLUGIN==1
debugOut = false;
-#endif // ELBEEM_BLENDER==1
+#endif // ELBEEM_PLUGIN==1
// output path
/*std::ostringstream ecrpath("");
@@ -91,6 +91,7 @@ int ntlBlenderDumper::renderScene( void )
vector<ntlTriangle> Triangles;
vector<ntlVec3Gfx> Vertices;
vector<ntlVec3Gfx> VertNormals;
+ errMsg("ntlBlenderDumper","mpTrafo : "<<(*mpTrafo) );
/* init geometry array, first all standard objects */
int idCnt = 0; // give IDs to objects
@@ -106,80 +107,117 @@ int ntlBlenderDumper::renderScene( void )
if(tid & GEOCLASSTID_SHADER) {
ntlGeometryShader *geoshad = (ntlGeometryShader*)(*iter); //dynamic_cast<ntlGeometryShader*>(*iter);
hideObjs.push_back( (*iter)->getName() );
+ geoshad->notifyShaderOfDump(glob->getAniCount(),nrStr,glob->getOutFilename());
for (vector<ntlGeometryObject*>::iterator siter = geoshad->getObjectsBegin();
siter != geoshad->getObjectsEnd();
siter++) {
if(debugOut) debMsgStd("ntlBlenderDumper::BuildScene",DM_MSG,"added shader geometry "<<(*siter)->getName(), 8);
+
+ (*siter)->notifyOfDump(glob->getAniCount(),nrStr,glob->getOutFilename());
+ bool doDump = false;
+ bool isPreview = false;
+ // only dump final&preview surface meshes
+ if( (*siter)->getName().find( "final" ) != string::npos) {
+ doDump = true;
+ } else if( (*siter)->getName().find( "preview" ) != string::npos) {
+ doDump = true;
+ isPreview = true;
+ }
+ if(!doDump) continue;
// only dump geo shader objects
Triangles.clear();
Vertices.clear();
VertNormals.clear();
(*siter)->initialize( mpGlob );
+ //int vstart = mVertNormals.size()-1;
(*siter)->getTriangles(&Triangles, &Vertices, &VertNormals, idCnt);
+
idCnt ++;
// always dump mesh, even empty ones...
- //if(Vertices.size() <= 0) continue;
- //if(Triangles.size() <= 0) continue;
-
- for(size_t i=0; i<Vertices.size(); i++) {
- Vertices[i] = (*mpTrafo) * Vertices[i];
- }
// dump to binary file
std::ostringstream boutfilename("");
//boutfilename << ecrpath.str() << glob->getOutFilename() <<"_"<< (*siter)->getName() <<"_" << nrStr << ".obj";
- boutfilename << glob->getOutFilename() <<"_"<< (*siter)->getName() <<"_" << nrStr << ".bobj";
+ boutfilename << glob->getOutFilename() <<"_"<< (*siter)->getName() <<"_" << nrStr;
if(debugOut) debMsgStd("ntlBlenderDumper::renderScene",DM_MSG,"B-Dumping: "<< (*siter)->getName()
<<", triangles:"<<Triangles.size()<<", vertices:"<<Vertices.size()<<
" to "<<boutfilename.str() , 7);
- bool isPreview = false;
- if( (*siter)->getName().find( "preview" ) != string::npos) {
- isPreview = true;
- }
- boutfilename << ".gz";
-
- // compress all bobj's except for preview ones...
gzFile gzf;
- if(isPreview) {
- gzf = gzopen(boutfilename.str().c_str(), "wb1");
- } else {
- gzf = gzopen(boutfilename.str().c_str(), "wb9");
+
+ // output velocities if desired
+ // WARNING - this is dirty, but simobjs are the only geoshaders right now
+ SimulationObject *sim = (SimulationObject *)geoshad;
+ LbmSolverInterface *lbm = sim->getSolver();
+ if((!isPreview) && (lbm->getDumpVelocities())) {
+ std::ostringstream bvelfilename;
+ bvelfilename << boutfilename.str();
+ bvelfilename << ".bvel.gz";
+ gzf = gzopen(bvelfilename.str().c_str(), "wb9");
+ if(gzf) {
+ int numVerts;
+ if(sizeof(numVerts)!=4) { errMsg("ntlBlenderDumper::renderScene","Invalid int size"); return 1; }
+ numVerts = Vertices.size();
+ gzwrite(gzf, &numVerts, sizeof(numVerts));
+ for(size_t i=0; i<Vertices.size(); i++) {
+ // returns smoothed velocity, scaled by frame time
+ ntlVec3Gfx v = lbm->getVelocityAt( Vertices[i][0], Vertices[i][1], Vertices[i][2] );
+ // translation not necessary, test rotation & scaling?
+ //? v = (*mpTrafo) * v;
+ for(int j=0; j<3; j++) {
+ float vertp = v[j];
+ //if(i<20) errMsg("ntlBlenderDumper","DUMP_VEL final "<<i<<" = "<<v);
+ gzwrite(gzf, &vertp, sizeof(vertp)); }
+ }
+ gzclose( gzf );
+ }
}
+
+ // compress all bobj's
+ boutfilename << ".bobj.gz";
+ //if(isPreview) { } else { }
+ gzf = gzopen(boutfilename.str().c_str(), "wb1"); // wb9 is slow for large meshes!
if (!gzf) {
errMsg("ntlBlenderDumper::renderScene","Unable to open output '"<<boutfilename<<"' ");
return 1; }
- int wri;
- float wrf;
- if(sizeof(wri)!=4) { errMsg("ntlBlenderDumper::renderScene","Invalid int size"); return 1; }
- wri = Vertices.size();
- gzwrite(gzf, &wri, sizeof(wri));
+ // transform into source space
+ for(size_t i=0; i<Vertices.size(); i++) {
+ Vertices[i] = (*mpTrafo) * Vertices[i];
+ }
+ // write to file
+ int numVerts;
+ if(sizeof(numVerts)!=4) { errMsg("ntlBlenderDumper::renderScene","Invalid int size"); return 1; }
+ numVerts = Vertices.size();
+ gzwrite(gzf, &numVerts, sizeof(numVerts));
for(size_t i=0; i<Vertices.size(); i++) {
for(int j=0; j<3; j++) {
- wrf = Vertices[i][j];
- gzwrite(gzf, &wrf, sizeof(wrf)); }
+ float vertp = Vertices[i][j];
+ gzwrite(gzf, &vertp, sizeof(vertp)); }
}
// should be the same as Vertices.size
- wri = VertNormals.size();
- gzwrite(gzf, &wri, sizeof(wri));
+ if(VertNormals.size() != (size_t)numVerts) {
+ errMsg("ntlBlenderDumper::renderScene","Normals have to have same size as vertices!");
+ VertNormals.resize( Vertices.size() );
+ }
+ gzwrite(gzf, &numVerts, sizeof(numVerts));
for(size_t i=0; i<VertNormals.size(); i++) {
for(int j=0; j<3; j++) {
- wrf = VertNormals[i][j];
- gzwrite(gzf, &wrf, sizeof(wrf)); }
+ float normp = VertNormals[i][j];
+ gzwrite(gzf, &normp, sizeof(normp)); }
}
- wri = Triangles.size();
- gzwrite(gzf, &wri, sizeof(wri));
+ int numTris = Triangles.size();
+ gzwrite(gzf, &numTris, sizeof(numTris));
for(size_t i=0; i<Triangles.size(); i++) {
for(int j=0; j<3; j++) {
- wri = Triangles[i].getPoints()[j];
- gzwrite(gzf, &wri, sizeof(wri)); }
+ int triIndex = Triangles[i].getPoints()[j];
+ gzwrite(gzf, &triIndex, sizeof(triIndex)); }
}
gzclose( gzf );
- debMsgDirect(" Wrote: '"<<boutfilename.str()<<"'. ");
+ debMsgStd("ntlBlenderDumper::renderScene",DM_NOTIFY," Wrote: '"<<boutfilename.str()<<"' ", 2);
numGMs++;
}
}
@@ -200,6 +238,7 @@ int ntlBlenderDumper::renderScene( void )
debMsgStd("ntlBlenderDumper::renderScene",DM_MSG,"Scene #"<<nrStr<<" dump time: "<< getTimeString(stopTime-startTime) <<" ", 10);
// still render for preview...
+debugOut = false; // DEBUG!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
if(debugOut) {
debMsgStd("ntlBlenderDumper::renderScene",DM_NOTIFY,"Performing preliminary render", 1);
ntlWorld::renderScene(); }
diff --git a/intern/elbeem/intern/ntl_bsptree.cpp b/intern/elbeem/intern/ntl_bsptree.cpp
index 59b0fd50ea2..afa1fa5804c 100644
--- a/intern/elbeem/intern/ntl_bsptree.cpp
+++ b/intern/elbeem/intern/ntl_bsptree.cpp
@@ -9,7 +9,6 @@
#include "ntl_bsptree.h"
-#include "ntl_scene.h"
#include "utilities.h"
#include <algorithm>
@@ -146,7 +145,7 @@ ntlTree::ntlTree(int depth, int objnum, ntlScene *scene, int triFlagMask) :
mStart(0.0), mEnd(0.0), mMaxDepth( depth ), mMaxListLength( objnum ), mpRoot( NULL) ,
mpNodeStack( NULL), mpTBB( NULL ),
mTriangleMask( 0xFFFF ),
- mCurrentDepth(0), mCurrentNodes(0)
+ mCurrentDepth(0), mCurrentNodes(0), mTriDoubles(0)
{
// init scene data pointers
mpVertices = scene->getVertexPointer();
@@ -175,11 +174,12 @@ ntlTree::ntlTree(int depth, int objnum, ntlScene *scene, int triFlagMask) :
mpTBB = new TriangleBBox[ noOfTriangles ];
int bbCount = 0;
mStart = mEnd = (*mpVertices)[ mpTriangles->front().getPoints()[0] ];
+ //errMsg("TreeDebug","Start");
for (vector<ntlTriangle>::iterator iter = mpTriangles->begin();
iter != mpTriangles->end();
iter++ ) {
+ //errorOut(" d "<< convertFlags2String((int)(*iter).getFlags()) <<" "<< convertFlags2String( (int)mTriangleMask)<<" add? "<<( ((int)(*iter).getFlags() & (int)mTriangleMask) != 0 ) );
// discard triangles that dont match mask
- //errorOut(" d "<<(int)(*iter).getFlags() <<" "<< (int)mTriangleMask );
if( ((int)(*iter).getFlags() & (int)mTriangleMask) == 0 ) {
continue;
}
@@ -194,9 +194,11 @@ ntlTree::ntlTree(int depth, int objnum, ntlScene *scene, int triFlagMask) :
// */
ntlVec3Gfx bbs, bbe;
+ //errMsg("TreeDebug","Triangle");
for(int i=0;i<3;i++) {
int index = (*iter).getPoints()[i];
ntlVec3Gfx tp = (*mpVertices)[ index ];
+ //errMsg("TreeDebug"," Point "<<i<<" = "<<tp<<" ");
if(tp[0] < mStart[0]) mStart[0]= tp[0];
if(tp[0] > mEnd[0]) mEnd[0]= tp[0];
if(tp[1] < mStart[1]) mStart[1]= tp[1];
@@ -241,6 +243,8 @@ ntlTree::ntlTree(int depth, int objnum, ntlScene *scene, int triFlagMask) :
mpRoot->cloneVec = 0;
globalSortingPoints = mpVertices;
mpTriDist = new char[ mppTriangles->size() ];
+ mNumNodes = 1;
+ mAbortSubdiv = 0;
/* create tree */
debugOutInter( "Generating BSP Tree... (Nodes "<< mCurrentNodes <<
@@ -265,9 +269,15 @@ ntlTree::ntlTree(int depth, int objnum, ntlScene *scene, int triFlagMask) :
triPerLeaf /= (gfxReal)noLeafs;
debMsgStd("ntlTree::ntlTree",DM_MSG,"Tree ("<<doSort<<","<<chooseAxis<<") Stats: Leafs:"<<noLeafs<<", avgDepth:"<<avgDepth<<
", triPerLeaf:"<<triPerLeaf<<", triDoubles:"<<mTriDoubles<<", totalTris:"<<totalTris
+ <<" nodes:"<<mNumNodes
//<<" T"<< (totalTris%3) // 0=ich, 1=f, 2=a
, 2 );
+ if(mAbortSubdiv) {
+ errMsg("ntlTree::ntlTree","Aborted... "<<mNumNodes);
+ deleteNode(mpRoot);
+ mpRoot = NULL;
+ }
}
/******************************************************************************
@@ -295,6 +305,7 @@ void ntlTree::subdivide(BSPNode *node, int depth, int axis)
if( ( (int)node->members->size() > mMaxListLength) &&
(depth < mMaxDepth )
&& (node->cloneVec<10)
+ && (!mAbortSubdiv)
) {
gfxReal planeDiv = 0.499999; // position of plane division
@@ -339,6 +350,9 @@ void ntlTree::subdivide(BSPNode *node, int depth, int axis)
node->child[i]->members = NULL;
nextAxis = (axis+1)%3;
node->child[i]->axis = nextAxis;
+ mNumNodes++;
+ // abort when using 256MB only for tree...
+ if(mNumNodes*sizeof(BSPNode)> 1024*1024*512) mAbortSubdiv = 1;
/* current division plane */
if(!i) {
@@ -489,6 +503,7 @@ void ntlTree::intersect(const ntlRay &ray, gfxReal &distance,
ray.intersectCompleteAABB(mStart,mEnd,mindist,maxdist);
if((maxdist < 0.0) ||
+ (!mpRoot) ||
(mindist == GFX_REAL_MAX) ||
(maxdist == GFX_REAL_MAX) ) {
distance = -1.0;
@@ -681,6 +696,7 @@ void ntlTree::intersectX(const ntlRay &ray, gfxReal &distance,
ray.intersectCompleteAABB(mStart,mEnd,mindist,maxdist); // +X
if((maxdist < 0.0) ||
+ (!mpRoot) ||
(mindist == GFX_REAL_MAX) ||
(maxdist == GFX_REAL_MAX) ) {
distance = -1.0;
diff --git a/intern/elbeem/intern/ntl_bsptree.h b/intern/elbeem/intern/ntl_bsptree.h
index d9746532fc0..face7c3aa7f 100644
--- a/intern/elbeem/intern/ntl_bsptree.h
+++ b/intern/elbeem/intern/ntl_bsptree.h
@@ -6,14 +6,11 @@
* Tree container for fast triangle intersects
*
*****************************************************************************/
-
-
-#ifndef NTL_TREE_HH
-#define NTL_TREE_HH
+#ifndef NTL_TREE_H
+#define NTL_TREE_H
#include "ntl_vector3dim.h"
#include "ntl_ray.h"
-#include "ntl_triangle.h"
#define AXIS_X 0
@@ -29,6 +26,8 @@ class BSPNode;
class BSPStackElement;
class BSPStack;
class TriangleBBox;
+class ntlScene;
+class ntlTriangle;
//! Class for a bsp tree for triangles
@@ -85,6 +84,9 @@ class ntlTree
//! root node pointer
BSPNode *mpRoot;
+ //! count no. of node
+ int mNumNodes;
+ int mAbortSubdiv;
//! stack for the node pointers
BSPStack *mpNodeStack;
diff --git a/intern/elbeem/intern/ntl_geometryclass.h b/intern/elbeem/intern/ntl_geometryclass.h
index 145f36bbc5f..bcc5a32fb58 100644
--- a/intern/elbeem/intern/ntl_geometryclass.h
+++ b/intern/elbeem/intern/ntl_geometryclass.h
@@ -28,6 +28,7 @@ class ntlGeometryClass
//! Default constructor
inline ntlGeometryClass() :
mVisible( 1 ), mName( "[ObjNameUndef]" ),
+ mObjectId(-1),
mpAttrs( NULL )
{
mpAttrs = new AttributeList("objAttrs");
@@ -62,6 +63,10 @@ class ntlGeometryClass
virtual inline ntlVec3Gfx *getBBStart() { return NULL; }
virtual inline ntlVec3Gfx *getBBEnd() { return NULL; }
+ /*! Set/get the object id*/
+ inline void setObjectId(int set) { mObjectId=set; }
+ inline int getObjectId() const { return mObjectId; }
+
/*! GUI - this function is called for selected objects to display debugging information with OpenGL */
virtual void drawDebugDisplay() { /* do nothing by default */ }
/*! GUI - this function is called for selected objects to display interactive information with OpenGL */
@@ -79,6 +84,9 @@ class ntlGeometryClass
/*! Name of this object */
string mName;
+ /*! global scene object id */
+ int mObjectId;
+
/*! configuration attributes */
AttributeList *mpAttrs;
diff --git a/intern/elbeem/intern/ntl_geometrymodel.cpp b/intern/elbeem/intern/ntl_geometrymodel.cpp
index 2ab80f5be79..3c2e05a8c36 100644
--- a/intern/elbeem/intern/ntl_geometrymodel.cpp
+++ b/intern/elbeem/intern/ntl_geometrymodel.cpp
@@ -9,7 +9,7 @@
#include "ntl_geometrymodel.h"
#include "ntl_ray.h"
-#include "ntl_scene.h"
+#include "ntl_world.h"
#include "zlib.h"
#ifdef WIN32
@@ -46,6 +46,13 @@ ntlGeometryObjModel::~ntlGeometryObjModel()
/*****************************************************************************/
void ntlGeometryObjModel::initialize(ntlRenderGlobals *glob)
{
+ // perhaps the model is already inited from initModel below?
+ if(mLoaded==1) {
+ // init default material
+ searchMaterial( glob->getMaterials() );
+ return;
+ }
+
ntlGeometryObject::initialize(glob);
mFilename = mpAttrs->readString("filename", mFilename,"ntlGeometryObjModel", "mFilename", true);
@@ -73,36 +80,32 @@ void ntlGeometryObjModel::initialize(ntlRenderGlobals *glob)
}
}
-
-/* defines */
-#define T(x) model->triangles[(x)]
-
/******************************************************************************
- *
+ * init model from given vertex and triangle arrays
*****************************************************************************/
-void
-ntlGeometryObjModel::getTriangles( vector<ntlTriangle> *triangles,
- vector<ntlVec3Gfx> *vertices,
- vector<ntlVec3Gfx> *normals, int objectId )
+
+int ntlGeometryObjModel::initModel(int numVertices, float *vertices, int numTriangles, int *triangles)
{
- if(!mLoaded) { // invalid type...
- return;
+ mVertices.clear();
+ mVertices.resize( numVertices );
+ mNormals.resize( numVertices );
+ for(int i=0; i<numVertices; i++) {
+ mVertices[i] = ntlVec3Gfx(vertices[i*3+0],vertices[i*3+1],vertices[i*3+2]);
+ mNormals[i] = ntlVec3Gfx(1.0); // unused, set to !=0.0
}
- for(int i=0; i<(int)mTriangles.size(); i+=3) {
- int trip[3];
- trip[0] = mTriangles[i+0];
- trip[1] = mTriangles[i+1];
- trip[2] = mTriangles[i+2];
- sceneAddTriangle(
- mVertices[trip[0]], mVertices[trip[1]], mVertices[trip[2]],
- mNormals[trip[0]], mNormals[trip[1]], mNormals[trip[2]],
- ntlVec3Gfx(0.0), 1 ); /* normal unused */
+ mTriangles.clear();
+ mTriangles.resize( 3*numTriangles );
+ for(int i=0; i<numTriangles; i++) {
+ mTriangles[3*i+0] = triangles[i*3+0];
+ mTriangles[3*i+1] = triangles[i*3+1];
+ mTriangles[3*i+2] = triangles[i*3+2];
}
- // bobj
- return;
-}
+ // inited, no need to parse attribs etc.
+ mLoaded = 1;
+ return 0;
+}
/******************************************************************************
@@ -119,67 +122,61 @@ int ntlGeometryObjModel::loadBobjModel(string filename)
return 1;
}
- int wri;
- int gotbytes = -1;
- gotbytes = gzread(gzf, &wri, sizeof(wri) );
- if(gotbytes != sizeof(int)){ errMsg("Reading GZ_BOBJ"," Invalid readNV size "<< wri); goto gzreaderror; }
- if(sizeof(wri)!=4) { // paranoia check
- errMsg("Reading GZ_BOBJ"," Invalid int size "<< wri);
+ int numVerts;
+ if(sizeof(numVerts)!=4) { // paranoia check
+ errMsg("Reading GZ_BOBJ"," Invalid int size, check compiler settings: int has to be 4 byte long");
goto gzreaderror;
}
- if(wri<0 || wri>1e9) {
- errMsg("Reading GZ_BOBJ"," invalid num vertices "<< wri);
+ gzread(gzf, &numVerts, sizeof(numVerts) );
+ if(numVerts<0 || numVerts>1e9) {
+ errMsg("Reading GZ_BOBJ"," invalid num vertices "<< numVerts);
goto gzreaderror;
}
mVertices.clear();
- mVertices.resize( wri );
- for(int i=0; i<wri; i++) {
+ mVertices.resize( numVerts );
+ for(int i=0; i<numVerts; i++) {
float x[3];
for(int j=0; j<3; j++) {
- gotbytes = gzread(gzf, &(x[j]), sizeof( (x[j]) ) );
- if(gotbytes != sizeof(float)){ errMsg("Reading GZ_BOBJ"," Invalid readV size "<< wri); goto gzreaderror; } // CHECK
+ gzread(gzf, &(x[j]), sizeof( (x[j]) ) );
}
mVertices[i] = ntlVec3Gfx(x[0],x[1],x[2]);
}
- if(debugPrint) errMsg("NV"," "<<wri<<" "<< mVertices.size() );
+ if(debugPrint) errMsg("NV"," "<<numVerts<<" "<< mVertices.size() );
// should be the same as Vertices.size
- gotbytes = gzread(gzf, &wri, sizeof(wri) );
- if(gotbytes != sizeof(int)){ errMsg("Reading GZ_BOBJ","Invalid readNN size "<< wri); goto gzreaderror; }
- if(wri<0 || wri>1e9) {
- errMsg("Reading GZ_BOBJ","invalid num normals "<< wri);
+ gzread(gzf, &numVerts, sizeof(numVerts) );
+ if(numVerts<0 || numVerts>1e9) {
+ errMsg("Reading GZ_BOBJ","invalid num normals "<< numVerts);
goto gzreaderror;
}
mNormals.clear();
- mNormals.resize( wri );
- for(int i=0; i<wri; i++) {
+ mNormals.resize( numVerts );
+ for(int i=0; i<numVerts; i++) {
float n[3];
for(int j=0; j<3; j++) {
- gotbytes = gzread(gzf, &(n[j]), sizeof( (n[j]) ) );
- if(gotbytes != sizeof(float)){ errMsg("Reading GZ_BOBJ","Invalid readN size "<< wri); goto gzreaderror; }
+ gzread(gzf, &(n[j]), sizeof( (n[j]) ) );
}
mNormals[i] = ntlVec3Gfx(n[0],n[1],n[2]);
}
- if(debugPrint) errMsg("NN"," "<<wri<<" "<< mNormals.size() );
+ if(debugPrint) errMsg("NN"," "<<numVerts<<" "<< mNormals.size() );
- gotbytes = gzread(gzf, &wri, sizeof(wri) );
- if(gotbytes != sizeof(int)){ errMsg("Reading GZ_BOBJ","Invalid readNT size "<< wri); goto gzreaderror; }
- if(wri<0 || wri>1e9) {
- errMsg("Reading GZ_BOBJ","invalid num normals "<< wri);
+ int numTris;
+ gzread(gzf, &numTris, sizeof(numTris) );
+ if(numTris<0 || numTris>1e9) {
+ errMsg("Reading GZ_BOBJ","invalid num normals "<< numTris);
goto gzreaderror;
}
- mTriangles.resize( 3*wri );
- for(int i=0; i<wri; i++) {
+ mTriangles.resize( 3*numTris );
+ for(int i=0; i<numTris; i++) {
int tri[3];
for(int j=0; j<3; j++) {
- gotbytes = gzread(gzf, &(tri[j]), sizeof( (tri[j]) ) );
- if(gotbytes != sizeof(int)){ errMsg("Reading GZ_BOBJ","Invalid readT size "<< wri); goto gzreaderror; }
+ gzread(gzf, &(tri[j]), sizeof( (tri[j]) ) );
}
mTriangles[3*i+0] = tri[0];
mTriangles[3*i+1] = tri[1];
mTriangles[3*i+2] = tri[2];
}
- if(debugPrint) errMsg("NT"," "<<wri<<" "<< mTriangles.size() );
+ if(debugPrint) errMsg("NT"," "<<numTris<<" "<< mTriangles.size() );
debMsgStd("ntlGeometryObjModel::loadBobjModel",DM_MSG, "File '"<<filename<<"' loaded, #Vertices: "<<mVertices.size()<<", #Normals: "<<mNormals.size()<<", #Triangles: "<<(mTriangles.size()/3)<<" ", 1 );
@@ -196,27 +193,34 @@ gzreaderror:
/******************************************************************************
- * init model from given vertex and triangle arrays
+ *
*****************************************************************************/
-
-int ntlGeometryObjModel::initModel(int numVertices, float *vertices, int numTriangles, int *triangles)
+void
+ntlGeometryObjModel::getTriangles( vector<ntlTriangle> *triangles,
+ vector<ntlVec3Gfx> *vertices,
+ vector<ntlVec3Gfx> *normals, int objectId )
{
- mVertices.clear();
- mVertices.resize( numVertices );
- for(int i=0; i<numVertices; i++) {
- //mVertices[i] = ntlVec3Gfx(vertices[i][0],vertices[i][1],vertices[i][2]);
- mVertices[i] = ntlVec3Gfx(vertices[i*3+0],vertices[i*3+1],vertices[i*3+2]);
+ if(!mLoaded) { // invalid type...
+ return;
}
- mTriangles.clear();
- mTriangles.resize( 3*numTriangles );
- for(int i=0; i<numTriangles; i++) {
- mTriangles[3*i+0] = triangles[i*3+0];
- mTriangles[3*i+1] = triangles[i*3+1];
- mTriangles[3*i+2] = triangles[i*3+2];
- }
+ for(int i=0; i<(int)mTriangles.size(); i+=3) {
+ int trip[3];
+ trip[0] = mTriangles[i+0];
+ trip[1] = mTriangles[i+1];
+ trip[2] = mTriangles[i+2];
- return 0;
+ sceneAddTriangle(
+ mVertices[trip[0]], mVertices[trip[1]], mVertices[trip[2]],
+ mNormals[trip[0]], mNormals[trip[1]], mNormals[trip[2]],
+ ntlVec3Gfx(0.0), 1 , triangles,vertices,normals ); /* normal unused */
+ }
+ objectId = -1; // remove warning
+ // bobj
+ return;
}
+
+
+
diff --git a/intern/elbeem/intern/ntl_geometryobject.cpp b/intern/elbeem/intern/ntl_geometryobject.cpp
index a9340fd2dec..7bbae5d87a1 100644
--- a/intern/elbeem/intern/ntl_geometryobject.cpp
+++ b/intern/elbeem/intern/ntl_geometryobject.cpp
@@ -10,7 +10,8 @@
#include "ntl_geometryobject.h"
-#include "ntl_renderglobals.h"
+#include "ntl_world.h"
+#include "ntl_matrices.h"
// for FGI
#include "elbeem.h"
@@ -21,13 +22,23 @@
/* Default constructor */
/*****************************************************************************/
ntlGeometryObject::ntlGeometryObject() :
- mpMaterial( NULL ),
+ mIsInitialized(false), mpMaterial( NULL ),
mMaterialName( "default" ),
mCastShadows( 1 ),
mReceiveShadows( 1 ),
mGeoInitId( -1 ), mGeoInitType( 0 ),
- mInitialVelocity(0.0),
- mGeoInitIntersect(false)
+ mInitialVelocity(0.0), mcInitialVelocity(0.0), mLocalCoordInivel(false),
+ mGeoInitIntersect(false),
+ mGeoPartSlipValue(0.0),
+ mOnlyThinInit(false),
+ mInitialPos(0.),
+ mcTrans(0.), mcRot(0.), mcScale(1.),
+ mIsAnimated(false),
+ mMovPoints(), mMovNormals(),
+ mHaveCachedMov(false),
+ mCachedMovPoints(), mCachedMovNormals(),
+ mMovPntsInited(-100.0), mMaxMovPnt(-1),
+ mcGeoActive(1.)
{
};
@@ -60,6 +71,11 @@ static int initStringTypes[GEOINIT_STRINGS] = {
void ntlGeometryObject::initialize(ntlRenderGlobals *glob)
{
//debugOut("ntlGeometryObject::initialize: '"<<getName()<<"' ", 10);
+ // initialize only once...
+ if(mIsInitialized) return;
+
+ // init material, always necessary
+ searchMaterial( glob->getMaterials() );
mGeoInitId = mpAttrs->readInt("geoinitid", mGeoInitId,"ntlGeometryObject", "mGeoInitId", false);
mGeoInitIntersect = mpAttrs->readInt("geoinit_intersect", mGeoInitIntersect,"ntlGeometryObject", "mGeoInitIntersect", false);
@@ -74,7 +90,7 @@ void ntlGeometryObject::initialize(ntlRenderGlobals *glob)
}
if(!gotit) {
- errFatal("ntlGeometryObject::initialize","Unkown 'geoinittype' value: '"<< ginitStr <<"' ", SIMWORLD_INITERROR);
+ errFatal("ntlGeometryObject::initialize","Obj '"<<mName<<"', Unkown 'geoinittype' value: '"<< ginitStr <<"' ", SIMWORLD_INITERROR);
return;
}
}
@@ -84,32 +100,77 @@ void ntlGeometryObject::initialize(ntlRenderGlobals *glob)
// disable geo init again...
mGeoInitId = -1;
}
- mInitialVelocity = vec2G( mpAttrs->readVec3d("initial_velocity", vec2D(mInitialVelocity),"ntlGeometryObject", "mInitialVelocity", false));
+ mInitialVelocity = vec2G( mpAttrs->readVec3d("initial_velocity", vec2D(mInitialVelocity),"ntlGeometryObject", "mInitialVelocity", false));
+ if(getAttributeList()->exists("initial_velocity") || (!mcInitialVelocity.isInited()) ) {
+ mcInitialVelocity = mpAttrs->readChannelVec3f("initial_velocity");
+ }
+ // always use channel
+ if(!mcInitialVelocity.isInited()) { mcInitialVelocity = AnimChannel<ntlVec3Gfx>(mInitialVelocity); }
+ mLocalCoordInivel = mpAttrs->readBool("geoinit_localinivel", mLocalCoordInivel,"ntlGeometryObject", "mLocalCoordInivel", false);
+
mGeoPartSlipValue = mpAttrs->readFloat("geoinit_partslip", mGeoPartSlipValue,"ntlGeometryObject", "mGeoPartSlipValue", false);
- debMsgStd("ntlGeometryObject::initialize",DM_MSG,"GeoObj '"<<this->getName()<<"': gid="<<mGeoInitId<<" gtype="<<mGeoInitType<<","<<ginitStr<<
- " gvel="<<mInitialVelocity<<" gisect="<<mGeoInitIntersect, 10); // debug
+ mOnlyThinInit = mpAttrs->readBool("geoinit_onlythin", mOnlyThinInit,"ntlGeometryObject", "mOnlyThinInit", false);
// override cfg types
mVisible = mpAttrs->readBool("visible", mVisible,"ntlGeometryObject", "mVisible", false);
mReceiveShadows = mpAttrs->readBool("recv_shad", mReceiveShadows,"ntlGeometryObject", "mReceiveShadows", false);
mCastShadows = mpAttrs->readBool("cast_shad", mCastShadows,"ntlGeometryObject", "mCastShadows", false);
-
- // init material
- searchMaterial( glob->getMaterials() );
+
+ // read mesh animation channels
+ ntlVec3d translation(0.0);
+ translation = mpAttrs->readVec3d("translation", translation,"ntlGeometryObject", "translation", false);
+ if(getAttributeList()->exists("translation") || (!mcTrans.isInited()) ) {
+ mcTrans = mpAttrs->readChannelVec3f("translation");
+ }
+ ntlVec3d rotation(0.0);
+ rotation = mpAttrs->readVec3d("rotation", rotation,"ntlGeometryObject", "rotation", false);
+ if(getAttributeList()->exists("rotation") || (!mcRot.isInited()) ) {
+ mcRot = mpAttrs->readChannelVec3f("rotation");
+ }
+ ntlVec3d scale(1.0);
+ scale = mpAttrs->readVec3d("scale", scale,"ntlGeometryObject", "scale", false);
+ if(getAttributeList()->exists("scale") || (!mcScale.isInited()) ) {
+ mcScale = mpAttrs->readChannelVec3f("scale");
+ }
+
+ float geoactive=1.;
+ geoactive = mpAttrs->readFloat("geoactive", geoactive,"ntlGeometryObject", "geoactive", false);
+ if(getAttributeList()->exists("geoactive") || (!mcGeoActive.isInited()) ) {
+ mcGeoActive = mpAttrs->readChannelFloat("geoactive");
+ }
+ // always use channel
+ if(!mcGeoActive.isInited()) { mcGeoActive = AnimChannel<double>(geoactive); }
+
+ if( (mcTrans.accessValues().size()>1) // VALIDATE
+ || (mcRot.accessValues().size()>1)
+ || (mcScale.accessValues().size()>1)
+ || (mcGeoActive.accessValues().size()>1)
+ || (mcInitialVelocity.accessValues().size()>1)
+ ) {
+ mIsAnimated = true;
+ }
+
+ mIsInitialized = true;
+ debMsgStd("ntlGeometryObject::initialize",DM_MSG,"GeoObj '"<<this->getName()<<"': visible="<<this->mVisible<<" gid="<<mGeoInitId<<" gtype="<<mGeoInitType<<","<<ginitStr<<
+ " gvel="<<mInitialVelocity<<" gisect="<<mGeoInitIntersect, 10); // debug
}
+/*! notify object that dump is in progress (e.g. for particles) */
+// default action - do nothing...
+void ntlGeometryObject::notifyOfDump(int frameNr,char *frameNrStr,string outfilename) {
+ bool debugOut=false;
+ if(debugOut) debMsgStd("ntlGeometryObject::notifyOfDump",DM_MSG,"obj:"<<this->getName()<<" frame:"<<frameNrStr<<","<<frameNr<<" to "<<outfilename, 10); // DEBUG
+}
/*****************************************************************************/
/* Search the material for this object from the material list */
/*****************************************************************************/
void ntlGeometryObject::searchMaterial(vector<ntlMaterial *> *mat)
{
- //errorOut("my: "<<mMaterialName); // DEBUG
/* search the list... */
int i=0;
for (vector<ntlMaterial*>::iterator iter = mat->begin();
iter != mat->end(); iter++) {
- //if(strcmp(mMaterialName, (*iter)->getName()) == 0) { // DEBUG
if( mMaterialName == (*iter)->getName() ) {
//warnMsg("ntlGeometryObject::searchMaterial","for obj '"<<getName()<<"' found - '"<<(*iter)->getName()<<"' "<<i); // DEBUG
mpMaterial = (*iter);
@@ -118,8 +179,385 @@ void ntlGeometryObject::searchMaterial(vector<ntlMaterial *> *mat)
i++;
}
errFatal("ntlGeometryObject::searchMaterial","Unknown material '"<<mMaterialName<<"' ! ", SIMWORLD_INITERROR);
+ mpMaterial = new ntlMaterial();
return;
}
+/******************************************************************************
+ * static add triangle function
+ *****************************************************************************/
+void ntlGeometryObject::sceneAddTriangle(
+ ntlVec3Gfx p1,ntlVec3Gfx p2,ntlVec3Gfx p3,
+ ntlVec3Gfx pn1,ntlVec3Gfx pn2,ntlVec3Gfx pn3,
+ ntlVec3Gfx trin, bool smooth,
+ vector<ntlTriangle> *triangles,
+ vector<ntlVec3Gfx> *vertices,
+ vector<ntlVec3Gfx> *normals) {
+ ntlTriangle tri;
+ int tempVert;
+
+ if(normals->size() != vertices->size()) {
+ errFatal("ntlGeometryObject::sceneAddTriangle","For '"<<this->mName<<"': Vertices and normals sizes to not match!!!",SIMWORLD_GENERICERROR);
+
+ } else {
+
+ vertices->push_back( p1 );
+ normals->push_back( pn1 );
+ tempVert = normals->size()-1;
+ tri.getPoints()[0] = tempVert;
+
+ vertices->push_back( p2 );
+ normals->push_back( pn2 );
+ tempVert = normals->size()-1;
+ tri.getPoints()[1] = tempVert;
+
+ vertices->push_back( p3 );
+ normals->push_back( pn3 );
+ tempVert = normals->size()-1;
+ tri.getPoints()[2] = tempVert;
+
+
+ /* init flags from ntl_ray.h */
+ int flag = 0;
+ if(getVisible()){ flag |= TRI_GEOMETRY; }
+ if(getCastShadows() ) {
+ flag |= TRI_CASTSHADOWS; }
+ if( (getMaterial()->getMirror()>0.0) ||
+ (getMaterial()->getTransparence()>0.0) ||
+ (getMaterial()->getFresnel()>0.0) ) {
+ flag |= TRI_MAKECAUSTICS; }
+ else {
+ flag |= TRI_NOCAUSTICS; }
+
+ /* init geo init id */
+ int geoiId = getGeoInitId();
+ if((geoiId > 0) && (!mOnlyThinInit) && (!mIsAnimated)) {
+ flag |= (1<< (geoiId+4));
+ flag |= mGeoInitType;
+ }
+ /*errMsg("ntlScene::addTriangle","DEBUG flag="<<convertFlags2String(flag) ); */
+ tri.setFlags( flag );
+
+ /* triangle normal missing */
+ tri.setNormal( trin );
+ tri.setSmoothNormals( smooth );
+ tri.setObjectId( this->mObjectId );
+ triangles->push_back( tri );
+ } /* normals check*/
+}
+
+
+
+/******************************************************************************/
+/* Init channels from float arrays (for elbeem API) */
+/******************************************************************************/
+
+#define ADD_CHANNEL_VEC(dst,nvals,val) \
+ vals.clear(); time.clear(); elbeemSimplifyChannelVec3(val,&nvals); \
+ for(int i=0; i<(nvals); i++) { \
+ vals.push_back(ntlVec3Gfx((val)[i*4+0], (val)[i*4+1],(val)[i*4+2] )); \
+ time.push_back( (val)[i*4+3] ); \
+ } \
+ (dst) = AnimChannel< ntlVec3Gfx >(vals,time);
+
+#define ADD_CHANNEL_FLOAT(dst,nvals,val) \
+ valsd.clear(); time.clear(); elbeemSimplifyChannelFloat(val,&nvals); \
+ for(int i=0; i<(nvals); i++) { \
+ valsd.push_back( (val)[i*2+0] ); \
+ time.push_back( (val)[i*2+1] ); \
+ } \
+ (dst) = AnimChannel< double >(valsd,time);
+
+void ntlGeometryObject::initChannels(
+ int nTrans, float *trans, int nRot, float *rot, int nScale, float *scale,
+ int nAct, float *act, int nIvel, float *ivel
+ ) {
+ const bool debugInitc=true;
+ if(debugInitc) { debMsgStd("ntlGeometryObject::initChannels",DM_MSG,"nt:"<<nTrans<<" nr:"<<nRot<<" ns:"<<nScale, 10);
+ debMsgStd("ntlGeometryObject::initChannels",DM_MSG,"na:"<<nAct<<" niv:"<<nIvel<<" ", 10); }
+ vector<ntlVec3Gfx> vals;
+ vector<double> valsd;
+ vector<double> time;
+ if((trans)&&(nTrans>0)) { ADD_CHANNEL_VEC(mcTrans, nTrans, trans); }
+ if((rot)&&(nRot>0)) { ADD_CHANNEL_VEC(mcRot, nRot, rot); }
+ if((scale)&&(nScale>0)) { ADD_CHANNEL_VEC(mcScale, nScale, scale); }
+ if((act)&&(nAct>0)) { ADD_CHANNEL_FLOAT(mcGeoActive, nAct, act); }
+ if((ivel)&&(nIvel>0)) { ADD_CHANNEL_VEC(mcInitialVelocity, nIvel, ivel); }
+
+ if( (mcTrans.accessValues().size()>1) // VALIDATE
+ || (mcRot.accessValues().size()>1)
+ || (mcScale.accessValues().size()>1)
+ || (mcGeoActive.accessValues().size()>1)
+ || (mcInitialVelocity.accessValues().size()>1)
+ ) {
+ mIsAnimated = true;
+ }
+ if(debugInitc) {
+ debMsgStd("ntlGeometryObject::initChannels",DM_MSG,getName()<<
+ " nt:"<<mcTrans.accessValues().size()<<" nr:"<<mcRot.accessValues().size()<<
+ " ns:"<<mcScale.accessValues().size()<<" isAnim:"<<mIsAnimated, 10); }
+
+ if(debugInitc) {
+ std::ostringstream ostr;
+ ostr << "trans: ";
+ for(size_t i=0; i<mcTrans.accessValues().size(); i++) {
+ ostr<<" "<<mcTrans.accessValues()[i]<<"@"<<mcTrans.accessTimes()[i]<<" ";
+ } ostr<<"; ";
+ ostr<<"rot: ";
+ for(size_t i=0; i<mcRot.accessValues().size(); i++) {
+ ostr<<" "<<mcRot.accessValues()[i]<<"@"<<mcRot.accessTimes()[i]<<" ";
+ } ostr<<"; ";
+ ostr<<"scale: ";
+ for(size_t i=0; i<mcScale.accessValues().size(); i++) {
+ ostr<<" "<<mcScale.accessValues()[i]<<"@"<<mcScale.accessTimes()[i]<<" ";
+ } ostr<<"; ";
+ ostr<<"act: ";
+ for(size_t i=0; i<mcGeoActive.accessValues().size(); i++) {
+ ostr<<" "<<mcGeoActive.accessValues()[i]<<"@"<<mcGeoActive.accessTimes()[i]<<" ";
+ } ostr<<"; ";
+ ostr<<"ivel: ";
+ for(size_t i=0; i<mcInitialVelocity.accessValues().size(); i++) {
+ ostr<<" "<<mcInitialVelocity.accessValues()[i]<<"@"<<mcInitialVelocity.accessTimes()[i]<<" ";
+ } ostr<<"; ";
+ debMsgStd("ntlGeometryObject::initChannels",DM_MSG,"Inited "<<ostr.str(),10);
+ }
+}
+#undef ADD_CHANNEL
+
+
+/*****************************************************************************/
+/* apply object translation at time t*/
+/*****************************************************************************/
+void ntlGeometryObject::applyTransformation(double t, vector<ntlVec3Gfx> *verts, vector<ntlVec3Gfx> *norms, int vstart, int vend, int forceTrafo) {
+ if( (mcTrans.accessValues().size()>1) // VALIDATE
+ || (mcRot.accessValues().size()>1)
+ || (mcScale.accessValues().size()>1)
+ || (forceTrafo)
+ || (!mHaveCachedMov)
+ ) {
+ // transformation is animated, continue
+ ntlVec3Gfx pos = mcTrans.get(t);
+ ntlVec3Gfx scale = mcScale.get(t);
+ ntlVec3Gfx rot = mcRot.get(t);
+ ntlMat4Gfx rotMat;
+ rotMat.initRotationXYZ(rot[0],rot[1],rot[2]);
+ pos += mInitialPos;
+ //errMsg("ntlGeometryObject::applyTransformation","obj="<<getName()<<" t"<<pos<<" r"<<rot<<" s"<<scale);
+ for(int i=vstart; i<vend; i++) {
+ (*verts)[i] *= scale;
+ (*verts)[i] = rotMat * (*verts)[i];
+ (*verts)[i] += pos;
+ }
+ if(norms) {
+ for(int i=vstart; i<vend; i++) {
+ (*norms)[i] = rotMat * (*norms)[i];
+ }
+ }
+ } else {
+ // not animated, cached points were already returned
+ errMsg ("ntlGeometryObject::applyTransformation","Object "<<getName()<<" used cached points ");
+ }
+}
+
+/*! Prepare points for moving objects */
+void ntlGeometryObject::initMovingPoints(gfxReal featureSize) {
+ if(mMovPntsInited==featureSize) return;
+ const bool debugMoinit=false;
+
+ vector<ntlTriangle> triangles;
+ vector<ntlVec3Gfx> vertices;
+ vector<ntlVec3Gfx> normals;
+ int objectId = 1;
+ this->getTriangles(&triangles,&vertices,&normals,objectId);
+
+ mMovPoints.clear(); //= vertices;
+ mMovNormals.clear(); //= normals;
+ if(debugMoinit) errMsg("ntlGeometryObject::initMovingPoints","Object "<<getName()<<" has v:"<<vertices.size()<<" t:"<<triangles.size() );
+ // no points?
+ if(vertices.size()<1) {
+ mMaxMovPnt=-1;
+ return;
+ }
+
+ ntlVec3f maxscale = channelFindMaxVf(mcScale);
+ float maxpart = ABS(maxscale[0]);
+ if(ABS(maxscale[1])>maxpart) maxpart = ABS(maxscale[1]);
+ if(ABS(maxscale[2])>maxpart) maxpart = ABS(maxscale[2]);
+ float scaleFac = 1.0/(maxpart);
+ // TODO - better reinit from time to time?
+ const gfxReal fsTri = featureSize*0.5 *scaleFac;
+ if(debugMoinit) errMsg("ntlGeometryObject::initMovingPoints","maxscale:"<<maxpart<<" featureSize:"<<featureSize<<" fsTri:"<<fsTri );
+
+ // debug: count points to init
+ if(debugMoinit) {
+ errMsg("ntlGeometryObject::initMovingPoints","Object "<<getName()<<" estimating...");
+ int countp=vertices.size()*2;
+ for(size_t i=0; i<triangles.size(); i++) {
+ ntlVec3Gfx p0 = vertices[ triangles[i].getPoints()[0] ];
+ ntlVec3Gfx side1 = vertices[ triangles[i].getPoints()[1] ] - p0;
+ ntlVec3Gfx side2 = vertices[ triangles[i].getPoints()[2] ] - p0;
+ int divs1=0, divs2=0;
+ if(normNoSqrt(side1) > fsTri*fsTri) { divs1 = (int)(norm(side1)/fsTri); }
+ if(normNoSqrt(side2) > fsTri*fsTri) { divs2 = (int)(norm(side2)/fsTri); }
+ errMsg("ntlGeometryObject::initMovingPoints","tri:"<<i<<" p:"<<p0<<" s1:"<<side1<<" s2:"<<side2<<" -> "<<divs1<<","<<divs2 );
+ if(divs1+divs2 > 0) {
+ for(int u=0; u<=divs1; u++) {
+ for(int v=0; v<=divs2; v++) {
+ const gfxReal uf = (gfxReal)(u+0.25) / (gfxReal)(divs1+0.0);
+ const gfxReal vf = (gfxReal)(v+0.25) / (gfxReal)(divs2+0.0);
+ if(uf+vf>1.0) continue;
+ countp+=2;
+ }
+ }
+ }
+ }
+ errMsg("ntlGeometryObject::initMovingPoints","Object "<<getName()<<" requires:"<<countp*2);
+ }
+
+ bool discardInflowBack = false;
+ if( (mGeoInitType==FGI_MBNDINFLOW) && (mcInitialVelocity.accessValues().size()<1) ) discardInflowBack = true;
+ discardInflowBack = false; // DEBUG disable for now
+
+
+ // init std points
+ for(size_t i=0; i<vertices.size(); i++) {
+ ntlVec3Gfx p = vertices[ i ];
+ ntlVec3Gfx n = normals[ i ];
+ // discard inflow backsides
+ //if( (mGeoInitType==FGI_MBNDINFLOW) && (!mIsAnimated)) {
+ if(discardInflowBack) { //if( (mGeoInitType==FGI_MBNDINFLOW) && (!mIsAnimated)) {
+ if(dot(mInitialVelocity,n)<0.0) continue;
+ }
+ mMovPoints.push_back(p);
+ mMovNormals.push_back(n);
+ }
+ // init points & refine...
+ for(size_t i=0; i<triangles.size(); i++) {
+ ntlVec3Gfx p0 = vertices[ triangles[i].getPoints()[0] ];
+ ntlVec3Gfx side1 = vertices[ triangles[i].getPoints()[1] ] - p0;
+ ntlVec3Gfx side2 = vertices[ triangles[i].getPoints()[2] ] - p0;
+ int divs1=0, divs2=0;
+ if(normNoSqrt(side1) > fsTri*fsTri) { divs1 = (int)(norm(side1)/fsTri); }
+ if(normNoSqrt(side2) > fsTri*fsTri) { divs2 = (int)(norm(side2)/fsTri); }
+ /* if( (i!=6) &&
+ (i!=6) ) { divs1=divs2=0; } // DEBUG */
+ if(divs1+divs2 > 0) {
+ for(int u=0; u<=divs1; u++) {
+ for(int v=0; v<=divs2; v++) {
+ const gfxReal uf = (gfxReal)(u+0.25) / (gfxReal)(divs1+0.0);
+ const gfxReal vf = (gfxReal)(v+0.25) / (gfxReal)(divs2+0.0);
+ if(uf+vf>1.0) continue;
+ ntlVec3Gfx p = vertices[ triangles[i].getPoints()[0] ] * (1.0-uf-vf)+
+ vertices[ triangles[i].getPoints()[1] ]*uf +
+ vertices[ triangles[i].getPoints()[2] ]*vf;
+ ntlVec3Gfx n = normals[ triangles[i].getPoints()[0] ] * (1.0-uf-vf)+
+ normals[ triangles[i].getPoints()[1] ]*uf +
+ normals[ triangles[i].getPoints()[2] ]*vf;
+ normalize(n);
+ //if(mGeoInitType==FGI_MBNDINFLOW) {
+ // discard inflow backsides
+ if(discardInflowBack) { //if( (mGeoInitType==FGI_MBNDINFLOW) && (!mIsAnimated)) {
+ if(dot(mInitialVelocity,n)<0.0) continue;
+ }
+
+ mMovPoints.push_back(p);
+ mMovNormals.push_back(n);
+ }
+ }
+ }
+ }
+
+ // duplicate insides
+ size_t mpsize = mMovPoints.size();
+ for(size_t i=0; i<mpsize; i++) {
+ //normalize(normals[i]);
+ //errMsg("TTAT"," moved:"<<(mMovPoints[i] - mMovPoints[i]*featureSize)<<" org"<<mMovPoints[i]<<" norm"<<mMovPoints[i]<<" fs"<<featureSize);
+ mMovPoints.push_back(mMovPoints[i] - mMovNormals[i]*0.5*featureSize);
+ mMovNormals.push_back(mMovNormals[i]);
+ }
+
+ // find max point
+ mMaxMovPnt = 0;
+ gfxReal dist = normNoSqrt(mMovPoints[0]);
+ for(size_t i=0; i<mpsize; i++) {
+ if(normNoSqrt(mMovPoints[i])>dist) {
+ mMaxMovPnt = i;
+ dist = normNoSqrt(mMovPoints[0]);
+ }
+ }
+
+ if( (mcTrans.accessValues().size()>1) // VALIDATE
+ || (mcRot.accessValues().size()>1)
+ || (mcScale.accessValues().size()>1)
+ ) {
+ // also do trafo...
+ } else {
+ mCachedMovPoints = mMovPoints;
+ mCachedMovNormals = mMovNormals;
+ applyTransformation(0., &mCachedMovPoints, &mCachedMovNormals, 0, mCachedMovPoints.size(), true);
+ mHaveCachedMov = true;
+ debMsgStd("ntlGeometryObject::initMovingPoints",DM_MSG,"Object "<<getName()<<" cached points ", 7);
+ }
+
+ mMovPntsInited = featureSize;
+ debMsgStd("ntlGeometryObject::initMovingPoints",DM_MSG,"Object "<<getName()<<" inited v:"<<vertices.size()<<"->"<<mMovPoints.size() , 5);
+}
+
+/*! Prepare points for moving objects */
+void ntlGeometryObject::getMovingPoints(vector<ntlVec3Gfx> &ret, vector<ntlVec3Gfx> *norms) {
+ if(mHaveCachedMov) {
+ ret = mCachedMovPoints;
+ if(norms) { *norms = mCachedMovNormals; }
+ errMsg ("ntlGeometryObject::getMovingPoints","Object "<<getName()<<" used cached points ");
+ return;
+ }
+
+ ret = mMovPoints;
+ if(norms) { *norms = mMovNormals; }
+}
+
+/*! Calculate max. velocity on object from t1 to t2 */
+ntlVec3Gfx ntlGeometryObject::calculateMaxVel(double t1, double t2) {
+ ntlVec3Gfx vel(0.);
+ if(mMaxMovPnt<0) return vel;
+
+ vector<ntlVec3Gfx> verts1,verts2;
+ verts1.push_back(mMovPoints[mMaxMovPnt]);
+ verts2 = verts1;
+ applyTransformation(t1,&verts1,NULL, 0,verts1.size(), true);
+ applyTransformation(t2,&verts2,NULL, 0,verts2.size(), true);
+
+ vel = (verts2[0]-verts1[0]); // /(t2-t1);
+ errMsg("ntlGeometryObject::calculateMaxVel","t1="<<t1<<" t2="<<t2<<" p1="<<verts1[0]<<" p2="<<verts2[0]<<" v="<<vel);
+ return vel;
+}
+
+/*! get translation at time t*/
+ntlVec3Gfx ntlGeometryObject::getTranslation(double t) {
+ ntlVec3Gfx pos = mcTrans.get(t);
+ return pos;
+}
+/*! get active flag time t*/
+float ntlGeometryObject::getGeoActive(double t) {
+ //float act = mcGeoActive.getConstant(t);
+ float act = mcGeoActive.get(t); // if <= 0.0 -> off
+ return act;
+}
+
+void ntlGeometryObject::setInitialVelocity(ntlVec3Gfx set) {
+ mInitialVelocity=set;
+ mcInitialVelocity = AnimChannel<ntlVec3Gfx>(set);
+}
+ntlVec3Gfx ntlGeometryObject::getInitialVelocity(double t) {
+ ntlVec3Gfx v = mcInitialVelocity.get(t); //return mInitialVelocity;
+ if(!mLocalCoordInivel) return v;
+
+ ntlVec3Gfx rot = mcRot.get(t);
+ ntlMat4Gfx rotMat;
+ rotMat.initRotationXYZ(rot[0],rot[1],rot[2]);
+ v = rotMat * v;
+ return v;
+}
+
diff --git a/intern/elbeem/intern/ntl_geometryobject.h b/intern/elbeem/intern/ntl_geometryobject.h
index 71a5566d8eb..157d160c0e4 100644
--- a/intern/elbeem/intern/ntl_geometryobject.h
+++ b/intern/elbeem/intern/ntl_geometryobject.h
@@ -7,13 +7,14 @@
* all other geometry objects are derived from this one
*
*****************************************************************************/
-#ifndef NTL_GEOMETRYOBJECT_HH
+#ifndef NTL_GEOMETRYOBJECT_H
+#define NTL_GEOMETRYOBJECT_H
#include "ntl_geometryclass.h"
-#include "ntl_material.h"
-#include "ntl_triangle.h"
-class ntlRay;
+#include "ntl_lighting.h"
+#include "ntl_ray.h"
class ntlRenderGlobals;
+class ntlTriangle;
class ntlGeometryObject : public ntlGeometryClass
@@ -28,13 +29,16 @@ class ntlGeometryObject : public ntlGeometryClass
//! Return type id
virtual int getTypeId() { return GEOCLASSTID_OBJECT; }
+ /*! Init attributes etc. of this object */
+ virtual void initialize(ntlRenderGlobals *glob);
+
/*! Get the triangles from this object */
virtual void getTriangles( vector<ntlTriangle> *triangles,
vector<ntlVec3Gfx> *vertices,
vector<ntlVec3Gfx> *normals, int objectId ) = 0;
-
- /*! Init attributes etc. of this object */
- virtual void initialize(ntlRenderGlobals *glob);
+
+ /*! notify object that dump is in progress (e.g. for particles) */
+ virtual void notifyOfDump(int frameNr,char *frameNrStr,string outfilename);
/*! Search the material for this object from the material list */
void searchMaterial(vector<ntlMaterial *> *mat);
@@ -68,20 +72,64 @@ class ntlGeometryObject : public ntlGeometryClass
/*! Returns the geo init typ */
inline int getGeoInitType() const { return mGeoInitType; }
- /*! Set/get the cast initial veocity attribute */
- inline void setInitialVelocity(ntlVec3Gfx set) { mInitialVelocity=set; }
- inline ntlVec3Gfx getInitialVelocity() const { return mInitialVelocity; }
-
/*! Set/get the intersect init flag */
inline bool getGeoInitIntersect() const { return mGeoInitIntersect; }
inline void setGeoInitIntersect(bool set) { mGeoInitIntersect=set; }
/*! Set/get the part slip value*/
- inline bool getGeoPartSlipValue() const { return mGeoPartSlipValue; }
+ inline float getGeoPartSlipValue() const { return mGeoPartSlipValue; }
inline void setGeoPartSlipValue(float set) { mGeoPartSlipValue=set; }
+ /*! Set/get the part slip value*/
+ inline bool getOnlyThinInit() const { return mOnlyThinInit; }
+ inline void setOnlyThinInit(float set) { mOnlyThinInit=set; }
+
+ /*! Set/get the cast initial veocity attribute */
+ void setInitialVelocity(ntlVec3Gfx set);
+ ntlVec3Gfx getInitialVelocity(double t);
+
+ /*! Set/get the local inivel coords flag */
+ inline bool getLocalCoordInivel() const { return mLocalCoordInivel; }
+ inline void setLocalCoordInivel(bool set) { mLocalCoordInivel=set; }
+
+ /*! Init channels from float arrays (for elbeem API) */
+ void initChannels(
+ int nTrans, float *trans, int nRot, float *rot, int nScale, float *scale,
+ int nAct, float *act, int nIvel, float *ivel
+ );
+
+ /*! is the object animated? */
+ inline bool getIsAnimated() const { return mIsAnimated; }
+
+ /*! apply object translation at time t*/
+ void applyTransformation(double t, vector<ntlVec3Gfx> *verts, vector<ntlVec3Gfx> *norms, int vstart, int vend, int forceTrafo);
+
+ /*! Prepare points for moving objects */
+ void initMovingPoints(gfxReal featureSize);
+ /*! Prepare points for moving objects (copy into ret) */
+ void getMovingPoints(vector<ntlVec3Gfx> &ret, vector<ntlVec3Gfx> *norms = NULL);
+ /*! Calculate max. velocity on object from t1 to t2 */
+ ntlVec3Gfx calculateMaxVel(double t1, double t2);
+ /*! get translation at time t*/
+ ntlVec3Gfx getTranslation(double t);
+ /*! get active flag time t*/
+ float getGeoActive(double t);
+
+ /*! add triangle to scene and init flags */
+ // helper function for getTriangles
+ void sceneAddTriangle(
+ ntlVec3Gfx p1,ntlVec3Gfx p2,ntlVec3Gfx p3,
+ ntlVec3Gfx pn1,ntlVec3Gfx pn2,ntlVec3Gfx pn3,
+ ntlVec3Gfx trin, bool smooth,
+ vector<ntlTriangle> *triangles,
+ vector<ntlVec3Gfx> *vertices,
+ vector<ntlVec3Gfx> *vertNormals);
+
protected:
+ /* initialized for scene? */
+ bool mIsInitialized;
+
/*! Point to a property object describing the surface of this object */
ntlMaterial *mpMaterial;
@@ -100,15 +148,41 @@ class ntlGeometryObject : public ntlGeometryClass
int mGeoInitType;
/*! initial velocity for fluid objects */
ntlVec3Gfx mInitialVelocity;
+ AnimChannel<ntlVec3Gfx> mcInitialVelocity;
+ /*! use object local inflow? */
+ bool mLocalCoordInivel;
/*! perform more accurate intersecting geo init for this object? */
bool mGeoInitIntersect;
/*! part slip bc value */
float mGeoPartSlipValue;
+ /*! only init as thin object, dont fill? */
+ bool mOnlyThinInit;
+
+ /*! initial offset for rot/scale */
+ ntlVec3Gfx mInitialPos;
+ /*! animated channels for postition, rotation and scale */
+ AnimChannel<ntlVec3Gfx> mcTrans, mcRot, mcScale;
+ /*! easy check for animation */
+ bool mIsAnimated;
+
+ /*! moving point/normal storage */
+ vector<ntlVec3Gfx> mMovPoints;
+ vector<ntlVec3Gfx> mMovNormals;
+ /*! cached points for non moving objects/timeslots */
+ bool mHaveCachedMov;
+ vector<ntlVec3Gfx> mCachedMovPoints;
+ vector<ntlVec3Gfx> mCachedMovNormals;
+ /*! inited? */
+ float mMovPntsInited;
+ /*! point with max. distance from center */
+ int mMaxMovPnt;
+
+ /*! animated channels for in/outflow on/off */
+ AnimChannel<double> mcGeoActive;
public:
};
-#define NTL_GEOMETRYOBJECT_HH
#endif
diff --git a/intern/elbeem/intern/ntl_geometryshader.h b/intern/elbeem/intern/ntl_geometryshader.h
index 06a11838149..7d767b0f8b9 100644
--- a/intern/elbeem/intern/ntl_geometryshader.h
+++ b/intern/elbeem/intern/ntl_geometryshader.h
@@ -38,6 +38,9 @@ class ntlGeometryShader :
virtual vector<ntlGeometryObject *>::iterator getObjectsBegin() { return mObjects.begin(); }
/*! Get end iterator for all objects */
virtual vector<ntlGeometryObject *>::iterator getObjectsEnd() { return mObjects.end(); }
+
+ /*! notify object that dump is in progress (e.g. for field dump) */
+ virtual void notifyShaderOfDump(int frameNr,char *frameNrStr,string outfilename) = 0;
protected:
diff --git a/intern/elbeem/intern/ntl_lightobject.cpp b/intern/elbeem/intern/ntl_lighting.cpp
index c8db66bab74..d4eae7051e0 100644
--- a/intern/elbeem/intern/ntl_lightobject.cpp
+++ b/intern/elbeem/intern/ntl_lighting.cpp
@@ -8,10 +8,9 @@
*****************************************************************************/
-#include "ntl_lightobject.h"
+#include "ntl_lighting.h"
#include "ntl_ray.h"
-#include "ntl_scene.h"
-#include "ntl_renderglobals.h"
+#include "ntl_world.h"
/******************************************************************************
@@ -126,7 +125,7 @@ ntlColor ntlLightObject::illuminatePoint(ntlRay &reflectedRay, ntlGeometryObject
ntlTriangle *tri;
ntlVec3Gfx triNormal;
gfxReal trit;
- mpGlob->getScene()->intersectScene(rayOfLight, trit, triNormal, tri, TRI_CASTSHADOWS);
+ mpGlob->getRenderScene()->intersectScene(rayOfLight, trit, triNormal, tri, TRI_CASTSHADOWS);
if(( trit>0 )&&( trit<lightDirNorm )) visibility = 0.0;
if(mpGlob->getDebugOut() > 5) errorOut("Omni lighting with "<<visibility );
}
@@ -142,3 +141,42 @@ ntlColor ntlLightObject::illuminatePoint(ntlRay &reflectedRay, ntlGeometryObject
}
+
+/******************************************************************************
+ * Default constructor
+ *****************************************************************************/
+ntlMaterial::ntlMaterial( void ) :
+ mName( "default" ),
+ mDiffuseRefl(0.5,0.5,0.5), mAmbientRefl(0.0,0.0,0.0),
+ mSpecular(0.0), mSpecExponent(0.0), mMirror(0.0),
+ mTransparence(0.0), mRefracIndex(0.0), mTransAdditive(0.0), mTransAttCol(0.0),
+ mFresnel( 0 )
+ //mNtfId(0), mNtfFluid(0), mNtfSolid(0)
+{
+ // just do default init...
+}
+
+
+
+/******************************************************************************
+ * Init constructor
+ *****************************************************************************/
+ntlMaterial::ntlMaterial( string name,
+ const ntlColor& Ref, const ntlColor& Amb,
+ gfxReal Spec, gfxReal SpecEx, gfxReal Mirr,
+ gfxReal Trans, gfxReal Refrac, gfxReal TAdd,
+ const ntlColor& Att, int fres)
+{
+ mName = name;
+ mDiffuseRefl = Ref;
+ mAmbientRefl = Amb;
+ mSpecular = Spec;
+ mSpecExponent = SpecEx;
+ mMirror = Mirr;
+ mTransparence = Trans;
+ mRefracIndex = Refrac;
+ mTransAdditive = TAdd;
+ mTransAttCol = Att;
+ mFresnel = fres;
+}
+
diff --git a/intern/elbeem/intern/ntl_material.h b/intern/elbeem/intern/ntl_lighting.h
index 41bfd167bb2..af53a13ebc7 100644
--- a/intern/elbeem/intern/ntl_material.h
+++ b/intern/elbeem/intern/ntl_lighting.h
@@ -3,15 +3,89 @@
* El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method
* Copyright 2003,2004 Nils Thuerey
*
- * a geometry object
- * all other geometry objects are derived from this one
+ * a light object
+ * default omni light implementation
*
*****************************************************************************/
-#ifndef NTL_MATERIAL_HH
-#define NTL_MATERIAL_HH
+#ifndef NTL_LIGHTING_H
+#define NTL_LIGHTING_H
#include "ntl_vector3dim.h"
+class ntlMaterial;
class ntlRay;
+class ntlRenderGlobals;
+class ntlGeometryObject;
+
+
+
+/* shadow map directions */
+#define LSM_RIGHT 0
+#define LSM_LEFT 1
+#define LSM_UP 2
+#define LSM_DOWN 3
+#define LSM_FRONT 4
+#define LSM_BACK 5
+
+/*! Basic object for lights, all other light are derived from this one */
+class ntlLightObject
+{
+public:
+ /* CONSTRUCTORS */
+ /*! Default constructor */
+ ntlLightObject(ntlRenderGlobals *glob);
+ /*! Constructor with parameters */
+ ntlLightObject(ntlRenderGlobals *glob, const ntlColor& col);
+ /*! Destructor */
+ virtual ~ntlLightObject();
+
+ /*! prepare light for rendering (for example shadow maps) */
+ virtual void prepare( bool );
+
+ /*! do the illumination... */
+ virtual ntlColor illuminatePoint(ntlRay &reflectedRay,
+ ntlGeometryObject *closest,
+ ntlColor &highlight);
+ /*! shade the point */
+ const ntlColor
+ getShadedColor(const ntlRay &reflectedray, ntlVec3Gfx lightDir,
+ ntlMaterial *surf, ntlColor &highlight) const;
+
+
+ /* access methods */
+ /*! Access the active flag */
+ inline void setActive(bool set) { mActive = set; }
+ inline bool getActive() const { return mActive; }
+ /*! Access the shadow flag */
+ inline void setCastShadows(bool set) { mCastShadows = set; }
+ inline bool getCastShadows() const { return mCastShadows; }
+ /*! Access the light color */
+ inline void setColor(ntlColor set) { mcColor = set; }
+ inline ntlColor getColor() const { return mcColor; }
+
+ /*! Access the omni light position */
+ void setPosition(ntlVec3Gfx set) { mvPosition = set; }
+ ntlVec3Gfx getPosition() const { return mvPosition; }
+
+
+protected:
+ /*! render globals */
+ ntlRenderGlobals *mpGlob;
+
+ /*! is this light acitve? */
+ bool mActive;
+
+ /*! does it cast shadows? */
+ bool mCastShadows;
+
+ /*! color of this light */
+ ntlColor mcColor;
+
+ /*! light position */
+ ntlVec3Gfx mvPosition;
+
+private:
+
+};
//! Properties of an geo object, describing the reflection properties of the surface
@@ -20,12 +94,12 @@ class ntlMaterial
public:
// CONSTRUCTORS
//! Default constructor
- inline ntlMaterial( void );
+ ntlMaterial( void );
//! Constructor with parameters
/*! Sets reflectance, ambient reflection, specular intensity
* specular exponent, mirror intensity
* transparency, refraction index */
- inline ntlMaterial( string name,
+ ntlMaterial( string name,
const ntlColor& Ref, const ntlColor& Amb,
gfxReal Spec, gfxReal Exp, gfxReal Mirror,
gfxReal Trans, gfxReal Refrac, gfxReal TAdd,
@@ -121,47 +195,6 @@ public:
};
-
-
-/******************************************************************************
- * Default constructor
- *****************************************************************************/
-inline ntlMaterial::ntlMaterial( void ) :
- mName( "default" ),
- mDiffuseRefl(0.5,0.5,0.5), mAmbientRefl(0.0,0.0,0.0),
- mSpecular(0.0), mSpecExponent(0.0), mMirror(0.0),
- mTransparence(0.0), mRefracIndex(0.0), mTransAdditive(0.0), mTransAttCol(0.0),
- mFresnel( 0 )
- //mNtfId(0), mNtfFluid(0), mNtfSolid(0)
-{
- // just do default init...
-}
-
-
-
-/******************************************************************************
- * Init constructor
- *****************************************************************************/
-inline
-ntlMaterial::ntlMaterial( string name,
- const ntlColor& Ref, const ntlColor& Amb,
- gfxReal Spec, gfxReal SpecEx, gfxReal Mirr,
- gfxReal Trans, gfxReal Refrac, gfxReal TAdd,
- const ntlColor& Att, int fres)
-{
- mName = name;
- mDiffuseRefl = Ref;
- mAmbientRefl = Amb;
- mSpecular = Spec;
- mSpecExponent = SpecEx;
- mMirror = Mirr;
- mTransparence = Trans;
- mRefracIndex = Refrac;
- mTransAdditive = TAdd;
- mTransAttCol = Att;
- mFresnel = fres;
-}
-
/******************************************************************************
* Macro to define the default surface properties for a newly created object
*****************************************************************************/
@@ -201,3 +234,5 @@ ntlMaterial::calculateFresnel(const ntlVec3Gfx &dir, const ntlVec3Gfx &normal, g
#endif
+
+
diff --git a/intern/elbeem/intern/ntl_lightobject.h b/intern/elbeem/intern/ntl_lightobject.h
deleted file mode 100644
index 19dde8829a1..00000000000
--- a/intern/elbeem/intern/ntl_lightobject.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/******************************************************************************
- *
- * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method
- * Copyright 2003,2004 Nils Thuerey
- *
- * a light object
- * default omni light implementation
- *
- *****************************************************************************/
-#ifndef NTL_LIGHTOBJECT_HH
-#define NTL_LIGHTOBJECT_HH
-
-#include "ntl_vector3dim.h"
-#include "ntl_material.h"
-class ntlRay;
-class ntlRenderGlobals;
-class ntlGeometryObject;
-
-
-
-/* shadow map directions */
-#define LSM_RIGHT 0
-#define LSM_LEFT 1
-#define LSM_UP 2
-#define LSM_DOWN 3
-#define LSM_FRONT 4
-#define LSM_BACK 5
-
-/*! Basic object for lights, all other light are derived from this one */
-class ntlLightObject
-{
-public:
- /* CONSTRUCTORS */
- /*! Default constructor */
- ntlLightObject(ntlRenderGlobals *glob);
- /*! Constructor with parameters */
- ntlLightObject(ntlRenderGlobals *glob, const ntlColor& col);
- /*! Destructor */
- virtual ~ntlLightObject();
-
- /*! prepare light for rendering (for example shadow maps) */
- virtual void prepare( bool );
-
- /*! do the illumination... */
- virtual ntlColor illuminatePoint(ntlRay &reflectedRay,
- ntlGeometryObject *closest,
- ntlColor &highlight);
- /*! shade the point */
- const ntlColor
- getShadedColor(const ntlRay &reflectedray, ntlVec3Gfx lightDir,
- ntlMaterial *surf, ntlColor &highlight) const;
-
-
- /* access methods */
- /*! Access the active flag */
- inline void setActive(bool set) { mActive = set; }
- inline bool getActive() const { return mActive; }
- /*! Access the shadow flag */
- inline void setCastShadows(bool set) { mCastShadows = set; }
- inline bool getCastShadows() const { return mCastShadows; }
- /*! Access the light color */
- inline void setColor(ntlColor set) { mcColor = set; }
- inline ntlColor getColor() const { return mcColor; }
-
- /*! Access the omni light position */
- void setPosition(ntlVec3Gfx set) { mvPosition = set; }
- ntlVec3Gfx getPosition() const { return mvPosition; }
-
-
-protected:
- /*! render globals */
- ntlRenderGlobals *mpGlob;
-
- /*! is this light acitve? */
- bool mActive;
-
- /*! does it cast shadows? */
- bool mCastShadows;
-
- /*! color of this light */
- ntlColor mcColor;
-
- /*! light position */
- ntlVec3Gfx mvPosition;
-
-private:
-
-};
-
-#endif
-
diff --git a/intern/elbeem/intern/ntl_matrices.h b/intern/elbeem/intern/ntl_matrices.h
index 8a70dceb1c7..7d27a6e7c7a 100644
--- a/intern/elbeem/intern/ntl_matrices.h
+++ b/intern/elbeem/intern/ntl_matrices.h
@@ -77,9 +77,12 @@ public:
inline void initRotationX(Scalar rot);
inline void initRotationY(Scalar rot);
inline void initRotationZ(Scalar rot);
+ inline void initRotationXYZ(Scalar rotx,Scalar roty, Scalar rotz);
//! init scaling matrix
inline void initScaling(Scalar scale);
inline void initScaling(Scalar x, Scalar y, Scalar z);
+ //! from 16 value array (init id if all 0)
+ inline void initArrayCheck(Scalar *array);
//! public to avoid [][] operators
Scalar value[4][4]; //< Storage of vector values
@@ -593,8 +596,8 @@ template<class Scalar>
inline void
ntlMatrix4x4<Scalar>::initRotationX(Scalar rot)
{
- double drot = (double)rot;
- while(drot < 0.0) drot += (M_PI*2.0);
+ double drot = (double)(rot/360.0*2.0*M_PI);
+ //? while(drot < 0.0) drot += (M_PI*2.0);
this->initId();
value[1][1] = (Scalar) cos(drot);
@@ -606,8 +609,8 @@ template<class Scalar>
inline void
ntlMatrix4x4<Scalar>::initRotationY(Scalar rot)
{
- double drot = (double)rot;
- while(drot < 0.0) drot += (M_PI*2.0);
+ double drot = (double)(rot/360.0*2.0*M_PI);
+ //? while(drot < 0.0) drot += (M_PI*2.0);
this->initId();
value[0][0] = (Scalar) cos(drot);
@@ -619,8 +622,8 @@ template<class Scalar>
inline void
ntlMatrix4x4<Scalar>::initRotationZ(Scalar rot)
{
- double drot = (double)rot;
- while(drot < 0.0) drot += (M_PI*2.0);
+ double drot = (double)(rot/360.0*2.0*M_PI);
+ //? while(drot < 0.0) drot += (M_PI*2.0);
this->initId();
value[0][0] = (Scalar) cos(drot);
@@ -628,6 +631,32 @@ ntlMatrix4x4<Scalar>::initRotationZ(Scalar rot)
value[1][0] = (Scalar)(-sin(drot));
value[1][1] = (Scalar) cos(drot);
}
+template<class Scalar>
+inline void
+ntlMatrix4x4<Scalar>::initRotationXYZ( Scalar rotx, Scalar roty, Scalar rotz)
+{
+ ntlMatrix4x4<Scalar> val;
+ ntlMatrix4x4<Scalar> rot;
+ this->initId();
+
+ // org
+ /*rot.initRotationX(rotx);
+ (*this) *= rot;
+ rot.initRotationY(roty);
+ (*this) *= rot;
+ rot.initRotationZ(rotz);
+ (*this) *= rot;
+ // org */
+
+ // blender
+ rot.initRotationZ(rotz);
+ (*this) *= rot;
+ rot.initRotationY(roty);
+ (*this) *= rot;
+ rot.initRotationX(rotx);
+ (*this) *= rot;
+ // blender */
+}
//! init scaling matrix
template<class Scalar>
@@ -651,6 +680,20 @@ ntlMatrix4x4<Scalar>::initScaling(Scalar x, Scalar y, Scalar z)
}
+//! from 16 value array (init id if all 0)
+template<class Scalar>
+inline void
+ntlMatrix4x4<Scalar>::initArrayCheck(Scalar *array)
+{
+ bool allZero = true;
+ for(int i=0; i<4; i++) {
+ for(int j=0; j<4; j++) {
+ value[i][j] = array[i*4+j];
+ if(array[i*4+j]!=0.0) allZero=false;
+ }
+ }
+ if(allZero) this->initId();
+}
#define NTL_MATRICES_H
diff --git a/intern/elbeem/intern/ntl_ray.cpp b/intern/elbeem/intern/ntl_ray.cpp
index ed5f96a4541..5df9c0068f9 100644
--- a/intern/elbeem/intern/ntl_ray.cpp
+++ b/intern/elbeem/intern/ntl_ray.cpp
@@ -8,8 +8,11 @@
*****************************************************************************/
+#include "utilities.h"
#include "ntl_ray.h"
-#include "ntl_scene.h"
+#include "ntl_world.h"
+#include "ntl_geometryobject.h"
+#include "ntl_geometryshader.h"
/* Minimum value for refl/refr to be traced */
@@ -116,7 +119,7 @@ ntlRay::~ntlRay()
#define MIDDLE 2
//! intersect ray with AABB
-#ifndef ELBEEM_BLENDER
+#ifndef ELBEEM_PLUGIN
void ntlRay::intersectFrontAABB(ntlVec3Gfx mStart, ntlVec3Gfx mEnd, gfxReal &t, ntlVec3Gfx &retnormal,ntlVec3Gfx &retcoord) const
{
char inside = true; /* inside box? */
@@ -288,7 +291,7 @@ void ntlRay::intersectBackAABB(ntlVec3Gfx mStart, ntlVec3Gfx mEnd, gfxReal &t, n
retnormal = normal;
retcoord = coord;
}
-#endif // ELBEEM_BLENDER
+#endif // ELBEEM_PLUGIN
//! intersect ray with AABB
void ntlRay::intersectCompleteAABB(ntlVec3Gfx mStart, ntlVec3Gfx mEnd, gfxReal &tmin, gfxReal &tmax) const
@@ -441,7 +444,7 @@ void ntlRay::intersectCompleteAABB(ntlVec3Gfx mStart, ntlVec3Gfx mEnd, gfxReal &
*****************************************************************************/
const ntlColor ntlRay::shade() //const
{
-#ifndef ELBEEM_BLENDER
+#ifndef ELBEEM_PLUGIN
ntlGeometryObject *closest = NULL;
gfxReal minT = GFX_REAL_MAX;
vector<ntlLightObject*> *lightlist = mpGlob->getLightList();
@@ -457,9 +460,9 @@ const ntlColor ntlRay::shade() //const
/* find closes object that intersects */
ntlTriangle *tri = NULL;
ntlVec3Gfx normal;
- mpGlob->getScene()->intersectScene(*this, minT, normal, tri, 0);
+ mpGlob->getRenderScene()->intersectScene(*this, minT, normal, tri, 0);
if(minT>0) {
- closest = mpGlob->getScene()->getObject( tri->getObjectId() );
+ closest = mpGlob->getRenderScene()->getObject( tri->getObjectId() );
}
/* object hit... */
@@ -481,7 +484,7 @@ const ntlColor ntlRay::shade() //const
ntlMaterial *clossurf = closest->getMaterial();
/*if(mpGlob->getDebugOut() > 5) {
errorOut("Ray hit: at "<<intersectionPosition<<" n:"<<normal<<" dn:"<<valDN<<" ins:"<<intersectionInside<<" cl:"<<((unsigned int)closest) );
- errorOut(" t1:"<<mpGlob->getScene()->getVertex(tri->getPoints()[0])<<" t2:"<<mpGlob->getScene()->getVertex(tri->getPoints()[1])<<" t3:"<<mpGlob->getScene()->getVertex(tri->getPoints()[2]) );
+ errorOut(" t1:"<<mpGlob->getRenderScene()->getVertex(tri->getPoints()[0])<<" t2:"<<mpGlob->getRenderScene()->getVertex(tri->getPoints()[1])<<" t3:"<<mpGlob->getScene()->getVertex(tri->getPoints()[2]) );
errorOut(" trin:"<<tri->getNormal() );
} // debug */
@@ -559,9 +562,9 @@ const ntlColor ntlRay::shade() //const
refractionPosition2 -= (triangleNormal*getVecEpsilon() );
ntlRay reflectedRay2 = ntlRay(refractionPosition2, reflectedDir, mDepth+1, mContribution*currRefl, mpGlob);
- mpGlob->getScene()->intersectScene(reflectedRay2, minT2, normal2, tri2, 0);
+ mpGlob->getRenderScene()->intersectScene(reflectedRay2, minT2, normal2, tri2, 0);
if(minT2>0) {
- closest2 = mpGlob->getScene()->getObject( tri2->getObjectId() );
+ closest2 = mpGlob->getRenderScene()->getObject( tri2->getObjectId() );
}
/* object hit... */
@@ -649,13 +652,254 @@ const ntlColor ntlRay::shade() //const
return ntlColor(currentColor);
}
-#endif // ELBEEM_BLENDER
+#endif // ELBEEM_PLUGIN
/* no object hit -> ray goes to infinity */
return mpGlob->getBackgroundCol();
}
+/******************************************************************************
+ ******************************************************************************
+ ******************************************************************************
+ * scene implementation
+ ******************************************************************************
+ ******************************************************************************
+ *****************************************************************************/
+
+
+
+/******************************************************************************
+ * Constructor
+ *****************************************************************************/
+ntlScene::ntlScene( ntlRenderGlobals *glob, bool del ) :
+ mpGlob( glob ), mSceneDel(del),
+ mpTree( NULL ),
+ mDisplayListId( -1 ),
+ mSceneBuilt( false ), mFirstInitDone( false )
+{
+}
+
+
+/******************************************************************************
+ * Destructor
+ *****************************************************************************/
+ntlScene::~ntlScene()
+{
+ if(mpTree != NULL) delete mpTree;
+
+ // cleanup lists, only if this is the rendering cleanup scene
+ if(mSceneDel) {
+ for (vector<ntlGeometryClass*>::iterator iter = mGeos.begin();
+ iter != mGeos.end(); iter++) {
+ //errMsg("ntlScene::~ntlScene","Deleting obj "<<(*iter)->getName() );
+ delete (*iter);
+ }
+ for (vector<ntlLightObject*>::iterator iter = mpGlob->getLightList()->begin();
+ iter != mpGlob->getLightList()->end(); iter++) {
+ delete (*iter);
+ }
+ for (vector<ntlMaterial*>::iterator iter = mpGlob->getMaterials()->begin();
+ iter != mpGlob->getMaterials()->end(); iter++) {
+ delete (*iter);
+ }
+ }
+ errMsg("ntlScene::~ntlScene","Deleted, ObjFree:"<<mSceneDel);
+}
+
+
+/******************************************************************************
+ * Build the scene arrays (obj, tris etc.)
+ *****************************************************************************/
+void ntlScene::buildScene(double time,bool firstInit)
+{
+ const bool buildInfo=true;
+
+ if(firstInit) {
+ mObjects.clear();
+ /* init geometry array, first all standard objects */
+ for (vector<ntlGeometryClass*>::iterator iter = mGeos.begin();
+ iter != mGeos.end(); iter++) {
+ bool geoinit = false;
+ int tid = (*iter)->getTypeId();
+ if(tid & GEOCLASSTID_OBJECT) {
+ ntlGeometryObject *geoobj = (ntlGeometryObject*)(*iter);
+ geoinit = true;
+ mObjects.push_back( geoobj );
+ if(buildInfo) debMsgStd("ntlScene::BuildScene",DM_MSG,"added GeoObj "<<geoobj->getName()<<" Id:"<<geoobj->getObjectId(), 5 );
+ }
+ //if(geoshad) {
+ if(tid & GEOCLASSTID_SHADER) {
+ ntlGeometryShader *geoshad = (ntlGeometryShader*)(*iter);
+ geoinit = true;
+ if(!mFirstInitDone) {
+ // only on first init
+ geoshad->initializeShader();
+ }
+ for (vector<ntlGeometryObject*>::iterator siter = geoshad->getObjectsBegin();
+ siter != geoshad->getObjectsEnd();
+ siter++) {
+ if(buildInfo) debMsgStd("ntlScene::BuildScene",DM_MSG,"added shader geometry "<<(*siter)->getName()<<" Id:"<<(*siter)->getObjectId(), 5 );
+ mObjects.push_back( (*siter) );
+ }
+ }
+
+ if(!geoinit) {
+ errFatal("ntlScene::BuildScene","Invalid geometry class!", SIMWORLD_INITERROR);
+ return;
+ }
+ }
+ }
+
+ // collect triangles
+ mTriangles.clear();
+ mVertices.clear();
+ mVertNormals.clear();
+
+ /* for test mode deactivate transparencies etc. */
+ if( mpGlob->getTestMode() ) {
+ debugOut("ntlScene::buildScene : Test Mode activated!", 2);
+ // assign random colors to dark materials
+ int matCounter = 0;
+ ntlColor stdCols[] = { ntlColor(0,0,1.0), ntlColor(0,1.0,0), ntlColor(1.0,0.7,0) , ntlColor(0.7,0,0.6) };
+ int stdColNum = 4;
+ for (vector<ntlMaterial*>::iterator iter = mpGlob->getMaterials()->begin();
+ iter != mpGlob->getMaterials()->end(); iter++) {
+ (*iter)->setTransparence(0.0);
+ (*iter)->setMirror(0.0);
+ (*iter)->setFresnel(false);
+ // too dark?
+ if( norm((*iter)->getDiffuseRefl()) <0.01) {
+ (*iter)->setDiffuseRefl( stdCols[matCounter] );
+ matCounter ++;
+ matCounter = matCounter%stdColNum;
+ }
+ }
+
+ // restrict output file size to 400
+ float downscale = 1.0;
+ if(mpGlob->getResX() > 400){ downscale = 400.0/(float)mpGlob->getResX(); }
+ if(mpGlob->getResY() > 400){
+ float downscale2 = 400.0/(float)mpGlob->getResY();
+ if(downscale2<downscale) downscale=downscale2;
+ }
+ mpGlob->setResX( (int)(mpGlob->getResX() * downscale) );
+ mpGlob->setResY( (int)(mpGlob->getResY() * downscale) );
+
+ }
+
+ /* collect triangles from objects */
+ int idCnt = 0; // give IDs to objects
+ bool debugTriCollect = false;
+ if(debugTriCollect) debMsgStd("ntlScene::buildScene",DM_MSG,"Start...",5);
+ for (vector<ntlGeometryObject*>::iterator iter = mObjects.begin();
+ iter != mObjects.end();
+ iter++) {
+ /* only add visible objects */
+ if(firstInit) {
+ if(debugTriCollect) debMsgStd("ntlScene::buildScene",DM_MSG,"Collect init of "<<(*iter)->getName()<<" idCnt:"<<idCnt, 4 );
+ (*iter)->initialize( mpGlob ); }
+ if(debugTriCollect) debMsgStd("ntlScene::buildScene",DM_MSG,"Collecting tris from "<<(*iter)->getName(), 4 );
+
+ int vstart = mVertNormals.size();
+ (*iter)->setObjectId(idCnt);
+ (*iter)->getTriangles(&mTriangles, &mVertices, &mVertNormals, idCnt);
+ (*iter)->applyTransformation(time, &mVertices, &mVertNormals, vstart, mVertices.size(), false );
+
+ if(debugTriCollect) debMsgStd("ntlScene::buildScene",DM_MSG,"Done with "<<(*iter)->getName()<<" totTris:"<<mTriangles.size()<<" totVerts:"<<mVertices.size()<<" totNorms:"<<mVertNormals.size(), 4 );
+ idCnt ++;
+ }
+ if(debugTriCollect) debMsgStd("ntlScene::buildScene",DM_MSG,"End",5);
+
+
+ /* calculate triangle normals, and initialize flags */
+ for (vector<ntlTriangle>::iterator iter = mTriangles.begin();
+ iter != mTriangles.end();
+ iter++) {
+
+ // calculate normal from triangle points
+ ntlVec3Gfx normal =
+ cross( (ntlVec3Gfx)( (mVertices[(*iter).getPoints()[2]] - mVertices[(*iter).getPoints()[0]]) *-1.0), // BLITZ minus sign right??
+ (ntlVec3Gfx)(mVertices[(*iter).getPoints()[1]] - mVertices[(*iter).getPoints()[0]]) );
+ normalize(normal);
+ (*iter).setNormal( normal );
+ }
+
+
+
+ // scene geometry built
+ mSceneBuilt = true;
+
+ // init shaders that require complete geometry
+ if(!mFirstInitDone) {
+ // only on first init
+ for (vector<ntlGeometryClass*>::iterator iter = mGeos.begin();
+ iter != mGeos.end(); iter++) {
+ if( (*iter)->getTypeId() & GEOCLASSTID_SHADER ) {
+ ntlGeometryShader *geoshad = (ntlGeometryShader*)(*iter);
+ geoshad->postGeoConstrInit( mpGlob );
+ }
+ }
+ mFirstInitDone = true;
+ }
+
+ // check unused attributes (for classes and objects!)
+ for (vector<ntlGeometryObject*>::iterator iter = mObjects.begin(); iter != mObjects.end(); iter++) {
+ if((*iter)->getAttributeList()->checkUnusedParams()) {
+ (*iter)->getAttributeList()->print(); // DEBUG
+ errFatal("ntlScene::buildScene","Unused params for object '"<< (*iter)->getName() <<"' !", SIMWORLD_INITERROR );
+ return;
+ }
+ }
+ for (vector<ntlGeometryClass*>::iterator iter = mGeos.begin(); iter != mGeos.end(); iter++) {
+ if((*iter)->getAttributeList()->checkUnusedParams()) {
+ (*iter)->getAttributeList()->print(); // DEBUG
+ errFatal("ntlScene::buildScene","Unused params for object '"<< (*iter)->getName() <<"' !", SIMWORLD_INITERROR );
+ return;
+ }
+ }
+
+}
+
+/******************************************************************************
+ * Prepare the scene triangles and maps for raytracing
+ *****************************************************************************/
+void ntlScene::prepareScene(double time)
+{
+ /* init triangles... */
+ buildScene(time, false);
+ // what for currently not used ???
+ if(mpTree != NULL) delete mpTree;
+ mpTree = new ntlTree( mpGlob->getTreeMaxDepth(), mpGlob->getTreeMaxTriangles(),
+ this, TRI_GEOMETRY );
+
+ //debMsgStd("ntlScene::prepareScene",DM_MSG,"Stats - tris:"<< (int)mTriangles.size()<<" verts:"<<mVertices.size()<<" vnorms:"<<mVertNormals.size(), 5 );
+}
+/******************************************************************************
+ * Do some memory cleaning, when frame is finished
+ *****************************************************************************/
+void ntlScene::cleanupScene( void )
+{
+ mTriangles.clear();
+ mVertices.clear();
+ mVertNormals.clear();
+
+ if(mpTree != NULL) delete mpTree;
+ mpTree = NULL;
+}
+
+
+/******************************************************************************
+ * Intersect a ray with the scene triangles
+ *****************************************************************************/
+void ntlScene::intersectScene(const ntlRay &r, gfxReal &distance, ntlVec3Gfx &normal, ntlTriangle *&tri,int flags) const
+{
+ distance = -1.0;
+ mpGlob->setCounterSceneInter( mpGlob->getCounterSceneInter()+1 );
+ mpTree->intersect(r, distance, normal, tri, flags, false);
+}
+
+
diff --git a/intern/elbeem/intern/ntl_ray.h b/intern/elbeem/intern/ntl_ray.h
index 71fac128e26..716a620bfab 100644
--- a/intern/elbeem/intern/ntl_ray.h
+++ b/intern/elbeem/intern/ntl_ray.h
@@ -6,14 +6,20 @@
* ray class
*
*****************************************************************************/
-#ifndef NTL_RAY_HH
-#define NTL_RAY_HH
+#ifndef NTL_RAY_H
+#define NTL_RAY_H
+#include <sstream>
#include "ntl_vector3dim.h"
-#include "ntl_lightobject.h"
+#include "ntl_lighting.h"
#include "ntl_geometryobject.h"
-#include "ntl_renderglobals.h"
+#include "ntl_bsptree.h"
+class ntlTriangle;
+class ntlRay;
+class ntlTree;
+class ntlScene;
+class ntlRenderGlobals;
//! store data for an intersection of a ray and a triangle
// NOT YET USED
@@ -131,12 +137,279 @@ private:
};
-
+/******************************************************************************
+ *
+ * a single triangle
+ *
+ *****************************************************************************/
// triangle intersection code in bsptree.cpp
// intersectTriangle(vector<ntlVec3Gfx> *mpV, ntlTriangle *tri, gfxReal &t, gfxReal &u, gfxReal &v);
-// ...
+/*! Triangle flag defines */
+#define TRI_GEOMETRY (1<<0)
+#define TRI_CASTSHADOWS (1<<1)
+#define TRI_MAKECAUSTICS (1<<2)
+#define TRI_NOCAUSTICS (1<<3)
+
+
+class ntlTriangle
+{
+public:
+ /* CONSTRUCTORS */
+ /*! Default constructor */
+ inline ntlTriangle( void );
+ /*! Constructor with parameters */
+ inline ntlTriangle(int *p, bool smooth, int obj, ntlVec3Gfx norm, int setflags);
+ /*! Copy - Constructor */
+ inline ntlTriangle(const ntlTriangle &tri);
+ /*! Destructor */
+ inline ~ntlTriangle() {}
+
+ /* Access methods */
+
+ /*! Acces to points of triangle */
+ inline int *getPoints( void ) { return mPoints; }
+ /*! Acces normal smoothing */
+ inline bool getSmoothNormals( void ) const { return mSmoothNormals; }
+ inline void setSmoothNormals( bool set){ mSmoothNormals = set; }
+ /*! Access object */
+ inline int getObjectId( void ) const { return mObjectId; }
+ inline void setObjectId( int set) { mObjectId = set; }
+ /*! Acces normal index */
+ inline ntlVec3Gfx getNormal( void ) const { return mNormal; }
+ inline void setNormal( ntlVec3Gfx set ) { mNormal = set; }
+ /*! Acces flags */
+ inline int getFlags( void ) const { return mFlags; }
+ inline void setFlags( int set ) { mFlags = set; }
+ /*! Access last intersection ray ID */
+ inline int getLastRay( void ) const { return mLastRay; }
+ inline void setLastRay( int set ) { mLastRay = set; }
+ /*! Acces bbox id */
+ inline int getBBoxId( void ) const { return mBBoxId; }
+ inline void setBBoxId( int set ) { mBBoxId = set; }
+
+ /*! Get average of the three points for this axis */
+ inline gfxReal getAverage( int axis ) const;
+
+ /*! operator < for sorting, uses global sorting axis */
+ inline friend bool operator<(const ntlTriangle &lhs, const ntlTriangle &rhs);
+ /*! operator > for sorting, uses global sorting axis */
+ inline friend bool operator>(const ntlTriangle &lhs, const ntlTriangle &rhs);
+
+protected:
+
+private:
+
+ /*! indices to the three points of the triangle */
+ int mPoints[3];
+
+ /*! bounding box id (for tree generation), -1 if invalid */
+ int mBBoxId;
+
+ /*! Should the normals of this triangle get smoothed? */
+ bool mSmoothNormals;
+
+ /*! Id of parent object */
+ int mObjectId;
+
+ /*! Index to normal (for not smooth triangles) */
+ //int mNormalIndex; ??
+ ntlVec3Gfx mNormal;
+
+ /*! Flags for object attributes cast shadows, make caustics etc. */
+ int mFlags;
+
+ /*! ID of last ray that an intersection was calculated for */
+ int mLastRay;
+
+};
+
+
+
+
+/******************************************************************************
+ * Default Constructor
+ *****************************************************************************/
+ntlTriangle::ntlTriangle( void ) :
+ mBBoxId(-1),
+ mLastRay( 0 )
+{
+ mPoints[0] = mPoints[1] = mPoints[2] = 0;
+ mSmoothNormals = 0;
+ mObjectId = 0;
+ mNormal = ntlVec3Gfx(0.0);
+ mFlags = 0;
+}
+
+
+/******************************************************************************
+ * Constructor
+ *****************************************************************************/
+ntlTriangle::ntlTriangle(int *p, bool smooth, int obj, ntlVec3Gfx norm, int setflags) :
+ mBBoxId(-1),
+ mLastRay( 0 )
+{
+ mPoints[0] = p[0];
+ mPoints[1] = p[1];
+ mPoints[2] = p[2];
+ mSmoothNormals = smooth;
+ mObjectId = obj;
+ mNormal = norm;
+ mFlags = setflags;
+}
+
+
+/******************************************************************************
+ * Copy Constructor
+ *****************************************************************************/
+ntlTriangle::ntlTriangle(const ntlTriangle &tri) :
+ mBBoxId(-1),
+ mLastRay( 0 )
+{
+ mPoints[0] = tri.mPoints[0];
+ mPoints[1] = tri.mPoints[1];
+ mPoints[2] = tri.mPoints[2];
+ mSmoothNormals = tri.mSmoothNormals;
+ mObjectId = tri.mObjectId;
+ mNormal = tri.mNormal;
+ mFlags = tri.mFlags;
+}
+
+
+
+
+/******************************************************************************
+ * Triangle sorting functions
+ *****************************************************************************/
+
+/* variables imported from ntl_bsptree.cc, necessary for using the stl sort funtion */
+/* Static global variable for sorting direction */
+extern int globalSortingAxis;
+/* Access to points array for sorting */
+extern vector<ntlVec3Gfx> *globalSortingPoints;
+
+
+gfxReal ntlTriangle::getAverage( int axis ) const
+{
+ return ( ( (*globalSortingPoints)[ mPoints[0] ][axis] +
+ (*globalSortingPoints)[ mPoints[1] ][axis] +
+ (*globalSortingPoints)[ mPoints[2] ][axis] )/3.0);
+}
+
+bool operator<(const ntlTriangle &lhs,const ntlTriangle &rhs)
+{
+ return ( lhs.getAverage(globalSortingAxis) <
+ rhs.getAverage(globalSortingAxis) );
+}
+
+bool operator>(const ntlTriangle &lhs,const ntlTriangle &rhs)
+{
+ return ( lhs.getAverage(globalSortingAxis) >
+ rhs.getAverage(globalSortingAxis) );
+}
+
+
+
+/******************************************************************************
+ *
+ * Scene object, that contains and manages all geometry objects
+ *
+ *****************************************************************************/
+
+
+
+class ntlScene
+{
+public:
+ /* CONSTRUCTORS */
+ /*! Default constructor */
+ ntlScene( ntlRenderGlobals *glob, bool del=true );
+ /*! Default destructor */
+ ~ntlScene();
+
+ /*! Add an object to the scene */
+ inline void addGeoClass(ntlGeometryClass *geo) {
+ mGeos.push_back( geo );
+ geo->setObjectId(mGeos.size());
+ }
+
+ /*! Acces a certain object */
+ inline ntlGeometryObject *getObject(int id) {
+ if(!mSceneBuilt) { errMsg("ntlScene::getObject","Scene not inited!"); return NULL; }
+ return mObjects[id]; }
+
+ /*! Acces object array */
+ inline vector<ntlGeometryObject*> *getObjects() {
+ if(!mSceneBuilt) { errMsg("ntlScene::getObjects[]","Scene not inited!"); return NULL; }
+ return &mObjects; }
+
+ /*! Acces geo class array */
+ inline vector<ntlGeometryClass*> *getGeoClasses() {
+ if(!mSceneBuilt) { errMsg("ntlScene::getGeoClasses[]","Scene not inited!"); return NULL; }
+ return &mGeos; }
+
+ /*! draw scene with opengl */
+ //void draw();
+
+ /*! Build/first init the scene arrays */
+ void buildScene(double time, bool firstInit);
+
+ //! Prepare the scene triangles and maps for raytracing
+ void prepareScene(double time);
+ //! Do some memory cleaning, when frame is finished
+ void cleanupScene( void );
+
+ /*! Intersect a ray with the scene triangles */
+ void intersectScene(const ntlRay &r, gfxReal &distance, ntlVec3Gfx &normal, ntlTriangle *&tri, int flags) const;
+
+ /*! return a vertex */
+ ntlVec3Gfx getVertex(int index) { return mVertices[index]; }
+
+ // for tree generation
+ /*! return pointer to vertices vector */
+ vector<ntlVec3Gfx> *getVertexPointer( void ) { return &mVertices; }
+ /*! return pointer to vertices vector */
+ vector<ntlVec3Gfx> *getVertexNormalPointer( void ) { return &mVertNormals; }
+ /*! return pointer to vertices vector */
+ vector<ntlTriangle> *getTrianglePointer( void ) { return &mTriangles; }
+
+private:
+
+ /*! Global settings */
+ ntlRenderGlobals *mpGlob;
+
+ /*! free objects? (only necessary for render scene, which contains all) */
+ bool mSceneDel;
+
+ /*! List of geometry classes */
+ vector<ntlGeometryClass *> mGeos;
+
+ /*! List of geometry objects */
+ vector<ntlGeometryObject *> mObjects;
+
+ /*! List of triangles */
+ vector<ntlTriangle> mTriangles;
+ /*! List of vertices */
+ vector<ntlVec3Gfx> mVertices;
+ /*! List of normals */
+ vector<ntlVec3Gfx> mVertNormals;
+ /*! List of triangle normals */
+ vector<ntlVec3Gfx> mTriangleNormals;
+
+ /*! Tree to store quickly intersect triangles */
+ ntlTree *mpTree;
+
+ /*! id of dislpay list for raytracer stuff */
+ int mDisplayListId;
+
+ /*! was the scene successfully built? only then getObject(i) requests are valid */
+ bool mSceneBuilt;
+
+ /*! shader/obj initializations are only done on first init */
+ bool mFirstInitDone;
+
+};
#endif
diff --git a/intern/elbeem/intern/ntl_renderglobals.h b/intern/elbeem/intern/ntl_renderglobals.h
deleted file mode 100644
index 606d0588554..00000000000
--- a/intern/elbeem/intern/ntl_renderglobals.h
+++ /dev/null
@@ -1,365 +0,0 @@
-/******************************************************************************
- *
- * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method
- * Copyright 2003,2004 Nils Thuerey
- *
- * main renderer class
- *
- *****************************************************************************/
-#ifndef NTL_RENDERGLOBALS_HH
-#define NTL_RENDERGLOBALS_HH
-
-
-#include "ntl_vector3dim.h"
-#include "ntl_rndstream.h"
-#include "ntl_geometryobject.h"
-#include "ntl_material.h"
-#include "ntl_lightobject.h"
-class ntlScene;
-class SimulationObject;
-
-
-
-//! Display mode
-#define DM_VIZ 0
-#define DM_RAY 1
-#define DM_LBM 2
-
-
-
-//! Class that handles global rendering parameters
-class ntlRenderGlobals
-{
- public:
- //! Standard constructor
- inline ntlRenderGlobals();
- //! Destructor
- ~ntlRenderGlobals();
-
- //! Returns the scene manager
- inline ntlScene *getScene(void) { return mpScene; }
- //! Set the scene manager
- inline void setScene(ntlScene *set) { mpScene = set;}
-
- //! Returns the object list
- //inline vector<ntlGeometryObject*> *getObjectList(void) { return mpObjList; }
- //! Set the object list
- //inline void setObjectList(vector<ntlGeometryObject*> *set) { mpObjList = set;}
-
- //! Returns the light object list
- inline vector<ntlLightObject*> *getLightList(void) { return mpLightList; }
- //! Set the light list
- inline void setLightList(vector<ntlLightObject*> *set) { mpLightList = set;}
-
- //! Returns the property object list
- inline vector<ntlMaterial*> *getMaterials(void) { return mpMaterials; }
- //! Set the property list
- inline void setMaterials(vector<ntlMaterial*> *set) { mpMaterials = set;}
-
- //! Returns the list of simulations
- inline vector<SimulationObject*> *getSims(void) { return mpSims; }
- //! Set the pointer to the list of simulations
- inline void setSims(vector<SimulationObject*> *set) { mpSims = set;}
-
- //! Set the x resolution
- inline void setResX(unsigned int set) { mResX = set; }
- //! Set the y resolution
- inline void setResY(unsigned int set) { mResY = set; }
- //! Set the anti-aliasing depth
- inline void setAADepth(int set) { mAADepth = set; }
- //! Set the max color value
- inline void setMaxColVal(unsigned int set) { mMaxColVal = set; }
- //! Set the maximum ray recursion
- inline void setRayMaxDepth(unsigned int set) { mRayMaxDepth = set; }
- //! Set the eye point
- inline void setEye(ntlVec3Gfx set) { mvEye = set; }
- //! Set the look at vector
- inline void setLookat(ntlVec3Gfx set) { mvLookat = set; }
- //! Set the up vector
- inline void setUpVec(ntlVec3Gfx set) { mvUpvec = set; }
- //! Set the image aspect
- inline void setAspect(float set) { mAspect = set; }
- //! Set the field of view
- inline void setFovy(float set) { mFovy = set; }
- //! Set the background color
- inline void setBackgroundCol(ntlColor set) { mcBackgr = set; }
- //! Set the ambient lighting color
- inline void setAmbientLight(ntlColor set) { mcAmbientLight = set; }
- //! Set the debug output var
- inline void setDebugOut(int set) { mDebugOut = set; }
-
- //! Set the animation start time
- inline void setAniStart(int set) { mAniStart = set; }
- //! Set the animation number of frames
- inline void setAniFrames(int set) { mAniFrames = set; }
- //! Set the animation
- inline void setAniCount(int set) { mAniCount = set; }
- //! Set the ray counter
- inline void setCounterRays(int set) { mCounterRays = set; }
- //! Set the ray shades counter
- inline void setCounterShades(int set) { mCounterShades = set; }
- //! Set the scenen intersection counter
- inline void setCounterSceneInter(int set) { mCounterSceneInter = set; }
- //! Set if existing frames should be skipped
- inline void setFrameSkip(int set) { mFrameSkip = set; }
-
- //! Set the outfilename
- inline void setOutFilename(string set) { mOutFilename = set; }
-
- //! get Maximum depth for BSP tree
- inline void setTreeMaxDepth( int set ) { mTreeMaxDepth = set; }
- //! get Maxmimum nr of triangles per BSP tree node
- inline void setTreeMaxTriangles( int set ) { mTreeMaxTriangles = set; }
-
- //! set the enable flag of the test sphere
- inline void setTestSphereEnabled( bool set ) { mTestSphereEnabled = set; }
- //! set the center of the test sphere
- inline void setTestSphereCenter( ntlVec3Gfx set ) { mTestSphereCenter = set; }
- //! set the radius of the test sphere
- inline void setTestSphereRadius( gfxReal set ) { mTestSphereRadius = set; }
- //! set the material name of the test sphere
- inline void setTestSphereMaterialName( char* set ) { mTestSphereMaterialName = set; }
- //! set debugging pixel coordinates
- inline void setDebugPixel( int setx, int sety ) { mDebugPixelX = setx; mDebugPixelY = sety; }
- //! set test mode flag
- inline void setTestMode( bool set ) { mTestMode = set; }
- //! set single frame mode flag
- inline void setSingleFrameMode(bool set) {mSingleFrameMode = set; };
- //! set single frame mode filename
- inline void setSingleFrameFilename(string set) {mSingleFrameFilename = set; };
-
-
- //! Return the x resolution
- inline unsigned int getResX(void) { return mResX; }
- //! Return the y resolution
- inline unsigned int getResY(void) { return mResY; }
- //! Return the anti-aliasing depth
- inline int getAADepth(void) { return mAADepth; }
- //! Return the max color value for ppm
- inline unsigned int getMaxColVal(void) { return mMaxColVal; }
- //! Return the maximum ray recursion
- inline unsigned int getRayMaxDepth(void) { return mRayMaxDepth; }
- //! Return the eye point
- inline ntlVec3Gfx getEye(void) { return mvEye; }
- //! Return the look at vector
- inline ntlVec3Gfx getLookat(void) { return mvLookat; }
- //! Return the up vector
- inline ntlVec3Gfx getUpVec(void) { return mvUpvec; }
- //! Return the image aspect
- inline float getAspect(void) { return mAspect; }
- //! Return the field of view
- inline float getFovy(void) { return mFovy; }
- //! Return the background color
- inline ntlColor getBackgroundCol(void) { return mcBackgr; }
- //! Return the ambient color
- inline ntlColor getAmbientLight(void) { return mcAmbientLight; }
- //! Return the debug mode setting
- inline int getDebugOut(void) { return mDebugOut; }
-
- //! Return the animation start time
- inline int getAniStart(void) { return mAniStart; }
- //! Return the animation frame number
- inline int getAniFrames(void) { return mAniFrames; }
- //! Return the animation counter
- inline int getAniCount(void) { return mAniCount; }
- //! Return the ray counter
- inline int getCounterRays(void) { return mCounterRays; }
- //! Return the ray shades counter
- inline int getCounterShades(void) { return mCounterShades; }
- //! Return the scene intersection counter
- inline int getCounterSceneInter(void) { return mCounterSceneInter; }
- //! Check if existing frames should be skipped
- inline int getFrameSkip( void ) { return mFrameSkip; }
-
-
- //! Return the outfilename
- inline string getOutFilename(void) { return mOutFilename; }
-
- //! get Maximum depth for BSP tree
- inline int getTreeMaxDepth( void ) { return mTreeMaxDepth; }
- //! get Maxmimum nr of triangles per BSP tree node
- inline int getTreeMaxTriangles( void ) { return mTreeMaxTriangles; }
-
- //! get open gl attribute list
- inline AttributeList* getOpenGlAttributes( void ) { return mpOpenGlAttr; }
- //! get blender output attribute list
- inline AttributeList* getBlenderAttributes( void ) { return mpBlenderAttr; }
-
- //! is the test sphere enabled?
- inline bool getTestSphereEnabled( void ) { return mTestSphereEnabled; }
- //! get the center of the test sphere
- inline ntlVec3Gfx getTestSphereCenter( void ) { return mTestSphereCenter; }
- //! get the radius of the test sphere
- inline gfxReal getTestSphereRadius( void) { return mTestSphereRadius; }
- //! get the materialname of the test sphere
- inline char *getTestSphereMaterialName( void) { return mTestSphereMaterialName; }
- //! get the debug pixel coordinate
- inline int getDebugPixelX( void ) { return mDebugPixelX; }
- //! get the debug pixel coordinate
- inline int getDebugPixelY( void ) { return mDebugPixelY; }
- //! get test mode flag
- inline bool getTestMode( void ) { return mTestMode; }
- //! set single frame mode flag
- inline bool getSingleFrameMode() { return mSingleFrameMode; };
- //! set single frame mode filename
- inline string getSingleFrameFilename() { return mSingleFrameFilename; };
-
-
- // random number functions
- //! init random numbers for photon directions
- inline void initRandomDirections( int seed ) { if(mpRndDirections) delete mpRndDirections; mpRndDirections = new ntlRandomStream( seed ); }
- //! get the next random photon direction
- inline ntlVec3Gfx getRandomDirection( void );
- //! init random numbers for russian roulette
- inline void initRandomRoulette( int seed ) { if(mpRndRoulette) delete mpRndRoulette; mpRndRoulette = new ntlRandomStream( seed ); }
- //! get the next random number for russion roulette
- inline gfxReal getRandomRoulette( void ) { return mpRndRoulette->getGfxReal(); }
-
-
-protected:
-
-private:
-
- /*! Scene storage */
- ntlScene *mpScene;
-
- //! List of geometry objects
- //vector<ntlGeometryObject*> *mpObjList;
- //! List of light objects
- vector<ntlLightObject*> *mpLightList;
- //! List of surface properties
- vector<ntlMaterial*> *mpMaterials;
- /*! storage for simulations */
- vector<SimulationObject*> *mpSims;
-
- //! resolution of the picture
- unsigned int mResX, mResY;
- //! Anti-Aliasing depth
- int mAADepth;
- //! max color value for ppm
- unsigned int mMaxColVal;
- /* Maximal ray recursion depth */
- int mRayMaxDepth;
- //! The eye point
- ntlVec3Gfx mvEye;
- //! The look at point
- ntlVec3Gfx mvLookat;
- //! The up vector
- ntlVec3Gfx mvUpvec;
- //! The image aspect = Xres/Yres
- float mAspect;
- //! The horizontal field of view
- float mFovy;
- //! The background color
- ntlColor mcBackgr;
- //! The ambient color
- ntlColor mcAmbientLight;
- //! how much debug output is needed? off by default
- char mDebugOut;
-
-
- //! animation properties, start time
- int mAniStart;
- //! animation properties, number of frames to render
- int mAniFrames;
- //! animation status, current frame number
- int mAniCount;
- /*! Should existing picture frames be skipped? */
- int mFrameSkip;
-
-
- //! count the total number of rays created (also used for ray ID's)
- int mCounterRays;
- //! count the total number of rays shaded
- int mCounterShades;
- //! count the total number of scene intersections
- int mCounterSceneInter;
-
- /*! filename of output pictures (without suffix or numbers) */
- string mOutFilename;
-
- //! get Maximum depth for BSP tree
- int mTreeMaxDepth;
- //! get Maxmimum nr of triangles per BSP tree node
- int mTreeMaxTriangles;
-
- //! attribute list for opengl renderer
- AttributeList *mpOpenGlAttr;
- //! attribute list for blender output
- AttributeList *mpBlenderAttr;
-
-
- //! Enable test sphere?
- bool mTestSphereEnabled;
- //! Center of the test sphere
- ntlVec3Gfx mTestSphereCenter;
- //! Radius of the test sphere
- gfxReal mTestSphereRadius;
- //! Materialname of the test sphere
- char *mTestSphereMaterialName;
- //! coordinates of the debugging pixel
- int mDebugPixelX, mDebugPixelY;
-
- //! test mode for quick rendering activated?, inited in ntl_scene::buildScene
- bool mTestMode;
-
- //! single frame flag
- bool mSingleFrameMode;
- //! filename for single frame mode
- string mSingleFrameFilename;
-
- /*! Two random number streams for photon generation (one for the directions, the other for russion roulette) */
- ntlRandomStream *mpRndDirections, *mpRndRoulette;
-
-};
-
-
-
-
-/*****************************************************************************/
-/* Constructor with standard value init */
-inline ntlRenderGlobals::ntlRenderGlobals() :
- mpLightList( NULL ), mpMaterials( NULL ), mpSims( NULL ),
- mResX(320), mResY(200), mAADepth(-1), mMaxColVal(255),
- mRayMaxDepth( 5 ),
- mvEye(0.0,0.0,5.0), mvLookat(0.0,0.0,0.0), mvUpvec(0.0,1.0,0.0),
- mAspect(320.0/200.0),
- mFovy(45), mcBackgr(0.0,0.0,0.0), mcAmbientLight(0.0,0.0,0.0),
- mDebugOut( 0 ),
- mAniStart(0), mAniFrames( -1 ), mAniCount( 0 ),
- mFrameSkip( 0 ),
- mCounterRays( 0 ), mCounterShades( 0 ), mCounterSceneInter( 0 ),
- mOutFilename( "pic" ),
- mTreeMaxDepth( 30 ), mTreeMaxTriangles( 30 ),
- mpOpenGlAttr(NULL),
- mpBlenderAttr(NULL),
- mTestSphereEnabled( false ),
- mDebugPixelX( -1 ), mDebugPixelY( -1 ), mTestMode(false),
- mSingleFrameMode(false), mSingleFrameFilename(""),
- mpRndDirections( NULL ), mpRndRoulette( NULL )
-{
- // create internal attribute list for opengl renderer
- mpOpenGlAttr = new AttributeList("__ntlOpenGLRenderer");
- mpBlenderAttr = new AttributeList("__ntlBlenderAttr");
-};
-
-
-/*****************************************************************************/
-/* Destructor */
-inline ntlRenderGlobals::~ntlRenderGlobals() {
- if(mpOpenGlAttr) delete mpOpenGlAttr;
- if(mpBlenderAttr) delete mpBlenderAttr;
-}
-
-
-/*****************************************************************************/
-//! get the next random photon direction
-inline ntlVec3Gfx ntlRenderGlobals::getRandomDirection( void ) {
- return ntlVec3Gfx(
- (mpRndDirections->getGfxReal()-0.5),
- (mpRndDirections->getGfxReal()-0.5),
- (mpRndDirections->getGfxReal()-0.5) );
-}
-
-#endif
-
diff --git a/intern/elbeem/intern/ntl_rndstream.h b/intern/elbeem/intern/ntl_rndstream.h
deleted file mode 100644
index 9eaa9093a0b..00000000000
--- a/intern/elbeem/intern/ntl_rndstream.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/******************************************************************************
- *
- * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method
- * Copyright 2003,2004 Nils Thuerey
- *
- * A seperate random number stream (e.g. for photon tracing)
- * (cf. Numerical recipes in C, sec. ed., p 283, Knuth method)
- *
- *****************************************************************************/
-#ifndef NTL_RANDOMSTREAM_H
-
-
-//! some big number
-#define MBIG 1000000000
-
-//! modify initial seed
-#define MSEED 161803398
-
-//! minimum value - no idea why this is a define?
-#define MZ 0
-
-//! for normalization to 0..1
-#define FAC (1.0/MBIG)
-
-
-/*! a stream of random numbers using Knuth's portable method */
-class ntlRandomStream
-{
-public:
- /*! Default constructor */
- inline ntlRandomStream(long seed);
- /*! Destructor */
- ~ntlRandomStream() {}
-
- /*! get a random number from the stream */
- inline double getDouble( void );
-
-#ifdef HAVE_GFXTYPES
- //! gfx random functions
-
- /*! get a random number from the stream */
- inline gfxReal getGfxReal( void );
-#endif
-
-private:
-
- /*! random number state */
- long idnum;
-
- /*! pointers into number table */
- int inext, inextp;
- /*! store seed and number for subtraction */
- long ma[56];
-
-};
-
-
-/* init random stream tables */
-inline ntlRandomStream::ntlRandomStream(long seed)
-{
- idnum = seed;
-
- long mj = MSEED - (idnum < 0 ? -idnum : idnum);
- mj %= MBIG;
- ma[55] = mj;
- long mk = 1;
-
- // init table once, otherwise strange results...
- for(int i=0;i<=55;i++) ma[i] = (i*i+seed);
-
- // init table in random order
- for(int i=1;i<=54;i++) {
- int ii = (21*i) % 56;
- ma[ii] = mk;
- mk = mj - mk;
- if(mk < MZ) mk += MBIG;
- mj = ma[ii];
- }
-
- // "warm up" generator
- for(int k=1;k<=4;k++)
- for(int i=1;i<=55;i++) {
- ma[i] -= ma[1+ (i+30) % 55];
- if(ma[i] < MZ) ma[i] += MBIG;
- }
-
- inext = 0;
- inextp = 31; // the special "31"
- idnum = 1;
-}
-
-
-/* return one random value */
-inline double ntlRandomStream::getDouble( void )
-{
- if( ++inext == 56) inext = 1;
- if( ++inextp == 56) inextp = 1;
-
- // generate by subtaction
- long mj = ma[inext] - ma[inextp];
-
- // check range
- if(mj < MZ) mj += MBIG;
- ma[ inext ] = mj;
- return (double)(mj * FAC);
-}
-
-#ifdef HAVE_GFXTYPES
-/* return one random value */
-inline gfxReal ntlRandomStream::getGfxReal( void )
-{
- if( ++inext == 56) inext = 1;
- if( ++inextp == 56) inextp = 1;
-
- // generate by subtaction
- long mj = ma[inext] - ma[inextp];
-
- // check range
- if(mj < MZ) mj += MBIG;
- ma[ inext ] = mj;
- return (gfxReal)(mj * FAC);
-}
-#endif
-
-#define NTL_RANDOMSTREAM_H
-#endif
-
diff --git a/intern/elbeem/intern/ntl_scene.cpp b/intern/elbeem/intern/ntl_scene.cpp
deleted file mode 100644
index 4e980944f22..00000000000
--- a/intern/elbeem/intern/ntl_scene.cpp
+++ /dev/null
@@ -1,235 +0,0 @@
-/******************************************************************************
- *
- * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method
- * Copyright 2003,2004 Nils Thuerey
- *
- * Scene object, that contains and manages all geometry objects
- *
- *****************************************************************************/
-
-#include "utilities.h"
-#include "ntl_scene.h"
-#include "ntl_geometryobject.h"
-#include "ntl_geometryshader.h"
-
-
-/******************************************************************************
- * Constructor
- *****************************************************************************/
-ntlScene::ntlScene( ntlRenderGlobals *glob ) :
- mpGlob( glob ),
- mpTree( NULL ),
- mDisplayListId( -1 ),
- mSceneBuilt( false ), mFirstInitDone( false )
-{
-}
-
-
-/******************************************************************************
- * Destructor
- *****************************************************************************/
-ntlScene::~ntlScene()
-{
- cleanupScene();
-
- // cleanup lists
- for (vector<ntlGeometryClass*>::iterator iter = mGeos.begin();
- iter != mGeos.end(); iter++) {
- delete (*iter);
- }
- for (vector<ntlLightObject*>::iterator iter = mpGlob->getLightList()->begin();
- iter != mpGlob->getLightList()->end(); iter++) {
- delete (*iter);
- }
- for (vector<ntlMaterial*>::iterator iter = mpGlob->getMaterials()->begin();
- iter != mpGlob->getMaterials()->end(); iter++) {
- delete (*iter);
- }
-}
-
-
-/******************************************************************************
- * Build the scene arrays (obj, tris etc.)
- *****************************************************************************/
-void ntlScene::buildScene( void )
-{
- const bool buildInfo=false;
- mObjects.clear();
- /* init geometry array, first all standard objects */
- for (vector<ntlGeometryClass*>::iterator iter = mGeos.begin();
- iter != mGeos.end(); iter++) {
- bool geoinit = false;
- int tid = (*iter)->getTypeId();
- if(tid & GEOCLASSTID_OBJECT) {
- ntlGeometryObject *geoobj = (ntlGeometryObject*)(*iter);
- geoinit = true;
- mObjects.push_back( geoobj );
- if(buildInfo) debMsgStd("ntlScene::BuildScene",DM_MSG,"added GeoObj "<<geoobj->getName(), 5 );
- }
- //if(geoshad) {
- if(tid & GEOCLASSTID_SHADER) {
- ntlGeometryShader *geoshad = (ntlGeometryShader*)(*iter);
- geoinit = true;
- if(!mFirstInitDone) {
- // only on first init
- geoshad->initializeShader();
- }
- for (vector<ntlGeometryObject*>::iterator siter = geoshad->getObjectsBegin();
- siter != geoshad->getObjectsEnd();
- siter++) {
- if(buildInfo) debMsgStd("ntlScene::BuildScene",DM_MSG,"added shader geometry "<<(*siter)->getName(), 5 );
- mObjects.push_back( (*siter) );
- }
- }
-
- if(!geoinit) {
- errFatal("ntlScene::BuildScene","Invalid geometry class!", SIMWORLD_INITERROR);
- return;
- }
- }
-
- // collect triangles
- mTriangles.clear();
- mVertices.clear();
- mVertNormals.clear();
-
- /* for test mode deactivate transparencies etc. */
- if( mpGlob->getTestMode() ) {
- debugOut("ntlScene::buildScene : Test Mode activated!", 2);
- // assign random colors to dark materials
- int matCounter = 0;
- ntlColor stdCols[] = { ntlColor(0,0,1.0), ntlColor(0,1.0,0), ntlColor(1.0,0.7,0) , ntlColor(0.7,0,0.6) };
- int stdColNum = 4;
- for (vector<ntlMaterial*>::iterator iter = mpGlob->getMaterials()->begin();
- iter != mpGlob->getMaterials()->end(); iter++) {
- (*iter)->setTransparence(0.0);
- (*iter)->setMirror(0.0);
- (*iter)->setFresnel(false);
- // too dark?
- if( norm((*iter)->getDiffuseRefl()) <0.01) {
- (*iter)->setDiffuseRefl( stdCols[matCounter] );
- matCounter ++;
- matCounter = matCounter%stdColNum;
- }
- }
-
- // restrict output file size to 400
- float downscale = 1.0;
- if(mpGlob->getResX() > 400){ downscale = 400.0/(float)mpGlob->getResX(); }
- if(mpGlob->getResY() > 400){
- float downscale2 = 400.0/(float)mpGlob->getResY();
- if(downscale2<downscale) downscale=downscale2;
- }
- mpGlob->setResX( (int)(mpGlob->getResX() * downscale) );
- mpGlob->setResY( (int)(mpGlob->getResY() * downscale) );
-
- }
-
- /* collect triangles from objects */
- int idCnt = 0; // give IDs to objects
- for (vector<ntlGeometryObject*>::iterator iter = mObjects.begin();
- iter != mObjects.end();
- iter++) {
- /* only add visible objects */
- (*iter)->initialize( mpGlob );
- (*iter)->getTriangles(&mTriangles, &mVertices, &mVertNormals, idCnt);
- idCnt ++;
- }
-
-
- /* calculate triangle normals, and initialize flags */
- for (vector<ntlTriangle>::iterator iter = mTriangles.begin();
- iter != mTriangles.end();
- iter++) {
-
- // calculate normal from triangle points
- ntlVec3Gfx normal =
- cross( (ntlVec3Gfx)( (mVertices[(*iter).getPoints()[2]] - mVertices[(*iter).getPoints()[0]]) *-1.0), // BLITZ minus sign right??
- (ntlVec3Gfx)(mVertices[(*iter).getPoints()[1]] - mVertices[(*iter).getPoints()[0]]) );
- normalize(normal);
- (*iter).setNormal( normal );
- }
-
-
-
- // scene geometry built
- mSceneBuilt = true;
-
- // init shaders that require complete geometry
- if(!mFirstInitDone) {
- // only on first init
- for (vector<ntlGeometryClass*>::iterator iter = mGeos.begin();
- iter != mGeos.end(); iter++) {
- if( (*iter)->getTypeId() & GEOCLASSTID_SHADER ) {
- ntlGeometryShader *geoshad = (ntlGeometryShader*)(*iter);
- geoshad->postGeoConstrInit( mpGlob );
- }
- }
- mFirstInitDone = true;
- }
-
- // check unused attributes (for classes and objects!)
- for (vector<ntlGeometryObject*>::iterator iter = mObjects.begin(); iter != mObjects.end(); iter++) {
- if((*iter)->getAttributeList()->checkUnusedParams()) {
- (*iter)->getAttributeList()->print(); // DEBUG
- errFatal("ntlScene::buildScene","Unused params for object '"<< (*iter)->getName() <<"' !", SIMWORLD_INITERROR );
- return;
- }
- }
- for (vector<ntlGeometryClass*>::iterator iter = mGeos.begin(); iter != mGeos.end(); iter++) {
- if((*iter)->getAttributeList()->checkUnusedParams()) {
- (*iter)->getAttributeList()->print(); // DEBUG
- errFatal("ntlScene::buildScene","Unused params for object '"<< (*iter)->getName() <<"' !", SIMWORLD_INITERROR );
- return;
- }
- }
-
-}
-
-/******************************************************************************
- * Prepare the scene triangles and maps for raytracing
- *****************************************************************************/
-void ntlScene::prepareScene( void )
-{
- /* init triangles... */
- buildScene();
- // what for currently not used ???
- if(mpTree != NULL) delete mpTree;
- mpTree = new ntlTree( mpGlob->getTreeMaxDepth(), mpGlob->getTreeMaxTriangles(),
- this, TRI_GEOMETRY );
-
- //debMsgStd("ntlScene::prepareScene",DM_MSG,"Stats - tris:"<< (int)mTriangles.size()<<" verts:"<<mVertices.size()<<" vnorms:"<<mVertNormals.size(), 5 );
-}
-/******************************************************************************
- * Do some memory cleaning, when frame is finished
- *****************************************************************************/
-void ntlScene::cleanupScene( void )
-{
- mObjects.clear();
- mTriangles.clear();
- mVertices.clear();
- mVertNormals.clear();
-
- if(mpTree != NULL) delete mpTree;
- mpTree = NULL;
-}
-
-
-/******************************************************************************
- * Intersect a ray with the scene triangles
- *****************************************************************************/
-void ntlScene::intersectScene(const ntlRay &r, gfxReal &distance, ntlVec3Gfx &normal, ntlTriangle *&tri,int flags) const
-{
- distance = -1.0;
- mpGlob->setCounterSceneInter( mpGlob->getCounterSceneInter()+1 );
- mpTree->intersect(r, distance, normal, tri, flags, false);
-}
-
-
-
-
-
-
-
-
-
diff --git a/intern/elbeem/intern/ntl_scene.h b/intern/elbeem/intern/ntl_scene.h
deleted file mode 100644
index f01aedc84af..00000000000
--- a/intern/elbeem/intern/ntl_scene.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/******************************************************************************
- *
- * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method
- * Copyright 2003,2004 Nils Thuerey
- *
- * Scene object, that contains and manages all geometry objects
- *
- *****************************************************************************/
-#ifndef NTL_SCENE_HH
-#define NTL_SCENE_HH
-
-#include <sstream>
-#include "ntl_vector3dim.h"
-#include "ntl_material.h"
-#include "ntl_geometryclass.h"
-#include "ntl_triangle.h"
-#include "ntl_bsptree.h"
-class ntlRay;
-class ntlGeometryObject;
-
-
-//! convenience macro for adding triangles
-#define sceneAddTriangle(p1,p2,p3, pn1,pn2,pn3, trin, smooth) {\
- \
- ntlTriangle tri;\
- int tempVert;\
- \
- if(normals->size() != vertices->size()) {\
- errFatal("getTriangles","For '"<<mName<<"': Vertices and normals sizes to not match!!!",SIMWORLD_GENERICERROR);\
- } else {\
- \
- vertices->push_back( p1 ); \
- normals->push_back( pn1 ); \
- tempVert = normals->size()-1;\
- tri.getPoints()[0] = tempVert;\
- \
- vertices->push_back( p2 ); \
- normals->push_back( pn2 ); \
- tempVert = normals->size()-1;\
- tri.getPoints()[1] = tempVert;\
- \
- vertices->push_back( p3 ); \
- normals->push_back( pn3 ); \
- tempVert = normals->size()-1;\
- tri.getPoints()[2] = tempVert;\
- \
- \
- /* init flags */\
- int flag = 0; \
- if(getVisible()){ flag |= TRI_GEOMETRY; }\
- if(getCastShadows() ) { \
- flag |= TRI_CASTSHADOWS; } \
- if( (getMaterial()->getMirror()>0.0) || \
- (getMaterial()->getTransparence()>0.0) || \
- (getMaterial()->getFresnel()>0.0) ) { \
- flag |= TRI_MAKECAUSTICS; } \
- else { \
- flag |= TRI_NOCAUSTICS; } \
- \
- /* init geo init id */\
- int geoiId = getGeoInitId(); \
- if(geoiId > 0) { \
- flag |= (1<< (geoiId+4)); \
- flag |= mGeoInitType; \
- } \
- \
- tri.setFlags( flag );\
- \
- /* triangle normal missing */\
- tri.setNormal( trin );\
- tri.setSmoothNormals( smooth );\
- tri.setObjectId( objectId );\
- triangles->push_back( tri ); \
- } /* normals check*/ \
- }\
-
-
-
-class ntlScene
-{
-public:
- /* CONSTRUCTORS */
- /*! Default constructor */
- ntlScene( ntlRenderGlobals *glob );
- /*! Default destructor */
- ~ntlScene();
-
- /*! Add an object to the scene */
- inline void addGeoClass(ntlGeometryClass *geo) { mGeos.push_back( geo ); }
-
- /*! Acces a certain object */
- inline ntlGeometryObject *getObject(int id) {
- if(!mSceneBuilt) { errMsg("ntlScene::getObject","Scene not inited!"); return NULL; }
- return mObjects[id]; }
-
- /*! Acces object array */
- inline vector<ntlGeometryObject*> *getObjects() {
- if(!mSceneBuilt) { errMsg("ntlScene::getObjects[]","Scene not inited!"); return NULL; }
- return &mObjects; }
-
- /*! Acces geo class array */
- inline vector<ntlGeometryClass*> *getGeoClasses() {
- if(!mSceneBuilt) { errMsg("ntlScene::getGeoClasses[]","Scene not inited!"); return NULL; }
- return &mGeos; }
-
- /*! draw scene with opengl */
- //void draw();
-
- /*! Build the scene arrays */
- void buildScene( void );
-
- //! Prepare the scene triangles and maps for raytracing
- void prepareScene( void );
- //! Do some memory cleaning, when frame is finished
- void cleanupScene( void );
-
- /*! Intersect a ray with the scene triangles */
- void intersectScene(const ntlRay &r, gfxReal &distance, ntlVec3Gfx &normal, ntlTriangle *&tri, int flags) const;
-
- /*! return a vertex */
- ntlVec3Gfx getVertex(int index) { return mVertices[index]; }
-
- // for tree generation
- /*! return pointer to vertices vector */
- vector<ntlVec3Gfx> *getVertexPointer( void ) { return &mVertices; }
- /*! return pointer to vertices vector */
- vector<ntlVec3Gfx> *getVertexNormalPointer( void ) { return &mVertNormals; }
- /*! return pointer to vertices vector */
- vector<ntlTriangle> *getTrianglePointer( void ) { return &mTriangles; }
-
-private:
-
- /*! Global settings */
- ntlRenderGlobals *mpGlob;
-
- /*! List of geometry classes */
- vector<ntlGeometryClass *> mGeos;
-
- /*! List of geometry objects */
- vector<ntlGeometryObject *> mObjects;
-
- /*! List of triangles */
- vector<ntlTriangle> mTriangles;
- /*! List of vertices */
- vector<ntlVec3Gfx> mVertices;
- /*! List of normals */
- vector<ntlVec3Gfx> mVertNormals;
- /*! List of triangle normals */
- vector<ntlVec3Gfx> mTriangleNormals;
-
- /*! Tree to store quickly intersect triangles */
- ntlTree *mpTree;
-
- /*! id of dislpay list for raytracer stuff */
- int mDisplayListId;
-
- /*! was the scene successfully built? only then getObject(i) requests are valid */
- bool mSceneBuilt;
-
- /*! shader/obj initializations are only done on first init */
- bool mFirstInitDone;
-
-};
-
-
-#endif
-
diff --git a/intern/elbeem/intern/ntl_triangle.h b/intern/elbeem/intern/ntl_triangle.h
deleted file mode 100644
index 7f1c7f1595e..00000000000
--- a/intern/elbeem/intern/ntl_triangle.h
+++ /dev/null
@@ -1,183 +0,0 @@
-/******************************************************************************
- *
- * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method
- * Copyright 2003,2004 Nils Thuerey
- *
- * a single triangle
- *
- *****************************************************************************/
-#ifndef NTL_TRIANGLE_HH
-#define NTL_TRIANGLE_HH
-
-
-#include "ntl_vector3dim.h"
-#include "ntl_material.h"
-class ntlRay;
-
-
-/*! Triangle flag defines */
-#define TRI_GEOMETRY (1<<0)
-#define TRI_CASTSHADOWS (1<<1)
-#define TRI_MAKECAUSTICS (1<<2)
-#define TRI_NOCAUSTICS (1<<3)
-
-
-class ntlTriangle
-{
-public:
- /* CONSTRUCTORS */
- /*! Default constructor */
- inline ntlTriangle( void );
- /*! Constructor with parameters */
- inline ntlTriangle(int *p, bool smooth, int obj, ntlVec3Gfx norm, int setflags);
- /*! Copy - Constructor */
- inline ntlTriangle(const ntlTriangle &tri);
- /*! Destructor */
- inline ~ntlTriangle() {}
-
- /* Access methods */
-
- /*! Acces to points of triangle */
- inline int *getPoints( void ) { return mPoints; }
- /*! Acces normal smoothing */
- inline bool getSmoothNormals( void ) const { return mSmoothNormals; }
- inline void setSmoothNormals( bool set){ mSmoothNormals = set; }
- /*! Access object */
- inline int getObjectId( void ) const { return mObjectId; }
- inline void setObjectId( int set) { mObjectId = set; }
- /*! Acces normal index */
- inline ntlVec3Gfx getNormal( void ) const { return mNormal; }
- inline void setNormal( ntlVec3Gfx set ) { mNormal = set; }
- /*! Acces flags */
- inline int getFlags( void ) const { return mFlags; }
- inline void setFlags( int set ) { mFlags = set; }
- /*! Access last intersection ray ID */
- inline int getLastRay( void ) const { return mLastRay; }
- inline void setLastRay( int set ) { mLastRay = set; }
- /*! Acces bbox id */
- inline int getBBoxId( void ) const { return mBBoxId; }
- inline void setBBoxId( int set ) { mBBoxId = set; }
-
- /*! Get average of the three points for this axis */
- inline gfxReal getAverage( int axis ) const;
-
- /*! operator < for sorting, uses global sorting axis */
- inline friend bool operator<(const ntlTriangle &lhs, const ntlTriangle &rhs);
- /*! operator > for sorting, uses global sorting axis */
- inline friend bool operator>(const ntlTriangle &lhs, const ntlTriangle &rhs);
-
-protected:
-
-private:
-
- /*! indices to the three points of the triangle */
- int mPoints[3];
-
- /*! bounding box id (for tree generation), -1 if invalid */
- int mBBoxId;
-
- /*! Should the normals of this triangle get smoothed? */
- bool mSmoothNormals;
-
- /*! Id of parent object */
- int mObjectId;
-
- /*! Index to normal (for not smooth triangles) */
- //int mNormalIndex; ??
- ntlVec3Gfx mNormal;
-
- /*! Flags for object attributes cast shadows, make caustics etc. */
- int mFlags;
-
- /*! ID of last ray that an intersection was calculated for */
- int mLastRay;
-
-};
-
-
-
-
-/******************************************************************************
- * Default Constructor
- *****************************************************************************/
-ntlTriangle::ntlTriangle( void ) :
- mBBoxId(-1),
- mLastRay( 0 )
-{
- mPoints[0] = mPoints[1] = mPoints[2] = 0;
- mSmoothNormals = 0;
- mObjectId = 0;
- mNormal = ntlVec3Gfx(0.0);
- mFlags = 0;
-}
-
-
-/******************************************************************************
- * Constructor
- *****************************************************************************/
-ntlTriangle::ntlTriangle(int *p, bool smooth, int obj, ntlVec3Gfx norm, int setflags) :
- mBBoxId(-1),
- mLastRay( 0 )
-{
- mPoints[0] = p[0];
- mPoints[1] = p[1];
- mPoints[2] = p[2];
- mSmoothNormals = smooth;
- mObjectId = obj;
- mNormal = norm;
- mFlags = setflags;
-}
-
-
-/******************************************************************************
- * Copy Constructor
- *****************************************************************************/
-ntlTriangle::ntlTriangle(const ntlTriangle &tri) :
- mBBoxId(-1),
- mLastRay( 0 )
-{
- mPoints[0] = tri.mPoints[0];
- mPoints[1] = tri.mPoints[1];
- mPoints[2] = tri.mPoints[2];
- mSmoothNormals = tri.mSmoothNormals;
- mObjectId = tri.mObjectId;
- mNormal = tri.mNormal;
- mFlags = tri.mFlags;
-}
-
-
-
-
-/******************************************************************************
- * Triangle sorting functions
- *****************************************************************************/
-
-/* variables imported from ntl_bsptree.cc, necessary for using the stl sort funtion */
-/* Static global variable for sorting direction */
-extern int globalSortingAxis;
-/* Access to points array for sorting */
-extern vector<ntlVec3Gfx> *globalSortingPoints;
-
-
-gfxReal ntlTriangle::getAverage( int axis ) const
-{
- return ( ( (*globalSortingPoints)[ mPoints[0] ][axis] +
- (*globalSortingPoints)[ mPoints[1] ][axis] +
- (*globalSortingPoints)[ mPoints[2] ][axis] )/3.0);
-}
-
-bool operator<(const ntlTriangle &lhs,const ntlTriangle &rhs)
-{
- return ( lhs.getAverage(globalSortingAxis) <
- rhs.getAverage(globalSortingAxis) );
-}
-
-bool operator>(const ntlTriangle &lhs,const ntlTriangle &rhs)
-{
- return ( lhs.getAverage(globalSortingAxis) >
- rhs.getAverage(globalSortingAxis) );
-}
-
-
-#endif
-
diff --git a/intern/elbeem/intern/ntl_vector3dim.h b/intern/elbeem/intern/ntl_vector3dim.h
index de4d5f8722a..ffcaa4149e0 100644
--- a/intern/elbeem/intern/ntl_vector3dim.h
+++ b/intern/elbeem/intern/ntl_vector3dim.h
@@ -92,6 +92,7 @@ using std::string;
#ifndef M_PI
#define M_PI 3.1415926536
+#define M_E 2.7182818284
#endif
// make sure elbeem plugin def is valid
diff --git a/intern/elbeem/intern/ntl_world.cpp b/intern/elbeem/intern/ntl_world.cpp
index c207fd94b90..8d1d5d4b45c 100644
--- a/intern/elbeem/intern/ntl_world.cpp
+++ b/intern/elbeem/intern/ntl_world.cpp
@@ -12,9 +12,7 @@
#include <sstream>
#include "utilities.h"
#include "ntl_world.h"
-#include "ntl_scene.h"
#include "parametrizer.h"
-#include "globals.h"
// for non-threaded renderViz
#ifndef NOGUI
@@ -25,114 +23,41 @@
/* external parser functions from cfgparser.cxx */
+#ifndef ELBEEM_PLUGIN
/* parse given file as config file */
void parseFile(string filename);
/* set pointers for parsing */
void setPointers( ntlRenderGlobals *setglob);
+#endif // ELBEEM_PLUGIN
/******************************************************************************
* Constructor
*****************************************************************************/
ntlWorld::ntlWorld(string filename, bool commandlineMode)
- /*:
- mpGlob(NULL),
- mpLightList(NULL), mpPropList(NULL), mpSims(NULL),
- mpOpenGLRenderer(NULL),
- mStopRenderVisualization( false ),
- mThreadRunning( false ),
- mSimulationTime(0.0), mFirstSim(-1),
- mSingleStepDebug( false ),
- mFrameCnt(0)*/
{
-#if 0
- /* create scene storage */
- mpGlob = new ntlRenderGlobals();
- mpLightList = new vector<ntlLightObject*>;
- mpPropList = new vector<ntlMaterial*>;
- mpSims = new vector<SimulationObject*>;
-
- mpGlob->setLightList(mpLightList);
- mpGlob->setMaterials(mpPropList);
- mpGlob->setSims(mpSims);
-
- /* init default material */
- ntlMaterial *def = GET_GLOBAL_DEFAULT_MATERIAL;
- mpPropList->push_back( def );
-
- /* init the scene object */
- ntlScene *scene;
- scene = new ntlScene( mpGlob );
- mpGlob->setScene( scene );
-
- // moved TODO test...
-#endif // 0
-
- initDefaults();
-#ifndef NOGUI
- // setup opengl display, save first animation step for start time
- if(!commandlineMode) {
- mpOpenGLRenderer = new ntlOpenGLRenderer( mpGlob );
- }
-#else // NOGUI
- commandlineMode = true; // remove warning...
-#endif // NOGUI
- // load config
- setPointers( getRenderGlobals() );
- parseFile( filename.c_str() );
- finishWorldInit();
- /*if(!SIMWORLD_OK()) return;
-
- // init the scene for the first time
- long sstartTime = getTime();
- scene->buildScene();
- long sstopTime = getTime();
- debMsgStd("ntlWorld::ntlWorld",DM_MSG,"Scene build time: "<< getTimeString(sstopTime-sstartTime) <<" ", 10);
-
- // TODO check simulations, run first steps
- mFirstSim = -1;
- if(mpSims->size() > 0) {
-
- // use values from first simulation as master time scale
- long startTime = getTime();
-
- // remember first active sim
- for(size_t i=0;i<mpSims->size();i++) {
- if(!(*mpSims)[i]->getVisible()) continue;
- if((*mpSims)[i]->getPanic()) continue;
-
- // check largest timestep
- if(mFirstSim>=0) {
- if( (*mpSims)[i]->getStepTime() > (*mpSims)[mFirstSim]->getStepTime() ) {
- mFirstSim = i;
- debMsgStd("ntlWorld::ntlWorld",DM_MSG,"First Sim changed: "<<i ,10);
- }
- }
- // check any valid sim
- if(mFirstSim<0) {
- mFirstSim = i;
- debMsgStd("ntlWorld::ntlWorld",DM_MSG,"First Sim: "<<i ,10);
- }
+#ifndef ELBEEM_PLUGIN
+
+ initDefaults();
+# ifdef NOGUI
+ commandlineMode = true; // remove warning...
+# endif // NOGUI
+
+ // load config
+ setPointers( getRenderGlobals() );
+ parseFile( filename.c_str() );
+# ifndef NOGUI
+ // setup opengl display, save first animation step for start time
+ // init after parsing file...
+ if(!commandlineMode) {
+ mpOpenGLRenderer = new ntlOpenGLRenderer( mpGlob );
}
+# endif // NOGUI
+ finishWorldInit();
- if(mFirstSim>=0) {
- debMsgStd("ntlWorld::ntlWorld",DM_MSG,"Anistart Time: "<<(*mpSims)[mFirstSim]->getStartTime() ,10);
- while(mSimulationTime < (*mpSims)[mFirstSim]->getStartTime() ) {
- debMsgStd("ntlWorld::ntlWorld",DM_MSG,"Anistart Time: "<<(*mpSims)[mFirstSim]->getStartTime()<<" simtime:"<<mSimulationTime ,10);
- advanceSims(-1);
- }
- long stopTime = getTime();
-
- mSimulationTime += (*mpSims)[mFirstSim]->getStartTime();
- debMsgStd("ntlWorld::ntlWorld",DM_MSG,"Time for start simulations times "<<": "<< getTimeString(stopTime-startTime) <<"s ", 1);
-#ifndef NOGUI
- guiResetSimulationTimeRange( mSimulationTime );
-#endif
- } else {
- if(!mpGlob->getSingleFrameMode()) debMsgStd("ntlWorld::ntlWorld",DM_WARNING,"No active simulations!", 1);
- }
- }
-*/
+#else // ELBEEM_PLUGIN
+ errFatal("ntlWorld::init","Cfg file parsing not supported for API version!", SIMWORLD_INITERROR);
+#endif // ELBEEM_PLUGIN
}
ntlWorld::ntlWorld(elbeemSimulationSettings *settings)
@@ -141,34 +66,53 @@ ntlWorld::ntlWorld(elbeemSimulationSettings *settings)
// todo init settings
SimulationObject *sim = new SimulationObject();
mpGlob->getSims()->push_back( sim );
- mpGlob->getScene()->addGeoClass( sim );
+ // important - add to both, only render scene objects are free'd
+ mpGlob->getRenderScene()->addGeoClass( sim );
+ mpGlob->getSimScene()->addGeoClass( sim );
sim->setGeoStart(ntlVec3Gfx(settings->geoStart[0],settings->geoStart[1],settings->geoStart[2]));
sim->setGeoEnd(ntlVec3Gfx(
settings->geoStart[0]+settings->geoSize[0],
settings->geoStart[1]+settings->geoSize[1],
settings->geoStart[2]+settings->geoSize[2] ));
- sim->getSolver()->setSmoothing(1.0, 0.0);
- sim->getSolver()->setPreviewSize(settings->previewresxyz);
- sim->getSolver()->setRefinementDesired(settings->maxRefine);
+ // further init in postGeoConstrInit/initializeLbmSimulation of SimulationObject
+ sim->copyElbeemSettings(settings);
Parametrizer *param = sim->getParametrizer();
param->setSize( settings->resolutionxyz );
param->setDomainSize( settings->realsize );
param->setViscosity( settings->viscosity );
- param->setGravity( ParamVec(settings->gravx, settings->gravy, settings->gravx) );
+ param->setGravity( ParamVec(settings->gravity[0], settings->gravity[1], settings->gravity[2]) );
param->setAniStart( settings->animStart );
- param->setAniFrameTime( settings->aniFrameTime );
+ param->setAniFrameTimeChannel( settings->aniFrameTime );
param->setNormalizedGStar( settings->gstar );
- // dont setup lights, camera, materials...?
- /*
- ntlMaterial *fluidmat = new ntlMaterial( );
- currentMaterial->setAmbientRefl( ntlColor(0.3, 0.5, 0.9) );
- currentMaterial->setDiffuseRefl( ntlColor(0.3, 0.5, 0.9) );
- currentMaterial->setSpecular( 0.2 );
- currentMaterial->setSpecExponent( 10.0 );
- mpGlob->getMaterials()->push_back( fluidmat );
- // */
+ // init domain channels
+ vector<ParamFloat> valf;
+ vector<ParamVec> valv;
+ vector<double> time;
+
+#define INIT_CHANNEL_FLOAT(channel,size) \
+ valf.clear(); time.clear(); elbeemSimplifyChannelFloat(channel,&size); \
+ for(int i=0; i<size; i++) { valf.push_back( channel[2*i+0] ); time.push_back( channel[2*i+1] ); }
+#define INIT_CHANNEL_VEC(channel,size) \
+ valv.clear(); time.clear(); elbeemSimplifyChannelVec3(channel,&size); \
+ for(int i=0; i<size; i++) { valv.push_back( ParamVec(channel[4*i+0],channel[4*i+1],channel[4*i+2]) ); time.push_back( channel[4*i+3] ); }
+
+ INIT_CHANNEL_FLOAT(settings->channelViscosity, settings->channelSizeViscosity);
+ param->initViscosityChannel(valf,time);
+
+ INIT_CHANNEL_VEC(settings->channelGravity, settings->channelSizeGravity);
+ param->initGravityChannel(valv,time);
+
+ INIT_CHANNEL_FLOAT(settings->channelFrameTime, settings->channelSizeFrameTime);
+ param->initAniFrameTimeChannel(valf,time);
+
+#undef INIT_CHANNEL_FLOAT
+#undef INIT_CHANNEL_VEC
+
+ mpGlob->setAniFrames( settings->noOfFrames );
+ mpGlob->setOutFilename( settings->outputPath );
+ // further init in postGeoConstrInit/initializeLbmSimulation of SimulationObject
}
void ntlWorld::initDefaults()
@@ -196,8 +140,11 @@ void ntlWorld::initDefaults()
mpPropList->push_back( def );
/* init the scene object */
- ntlScene *newscene = new ntlScene( mpGlob );
- mpGlob->setScene( newscene );
+ ntlScene *renderscene = new ntlScene( mpGlob, true );
+ mpGlob->setRenderScene( renderscene );
+ // sim scene shouldnt delete objs, may only contain subset
+ ntlScene *simscene = new ntlScene( mpGlob, false );
+ mpGlob->setSimScene( simscene );
}
void ntlWorld::finishWorldInit()
@@ -206,7 +153,10 @@ void ntlWorld::finishWorldInit()
// init the scene for the first time
long sstartTime = getTime();
- mpGlob->getScene()->buildScene();
+
+ // first init sim scene for geo setup
+ mpGlob->getSimScene()->buildScene(0.0, true);
+ mpGlob->getRenderScene()->buildScene(0.0, true);
long sstopTime = getTime();
debMsgStd("ntlWorld::ntlWorld",DM_MSG,"Scene build time: "<< getTimeString(sstopTime-sstartTime) <<" ", 10);
@@ -225,7 +175,7 @@ void ntlWorld::finishWorldInit()
// check largest timestep
if(mFirstSim>=0) {
- if( (*mpSims)[i]->getStepTime() > (*mpSims)[mFirstSim]->getStepTime() ) {
+ if( (*mpSims)[i]->getTimestep() > (*mpSims)[mFirstSim]->getTimestep() ) {
mFirstSim = i;
debMsgStd("ntlWorld::ntlWorld",DM_MSG,"First Sim changed: "<<i ,10);
}
@@ -246,7 +196,7 @@ void ntlWorld::finishWorldInit()
long stopTime = getTime();
mSimulationTime += (*mpSims)[mFirstSim]->getStartTime();
- debMsgStd("ntlWorld::ntlWorld",DM_MSG,"Time for start simulations times "<<": "<< getTimeString(stopTime-startTime) <<"s ", 1);
+ debMsgStd("ntlWorld::ntlWorld",DM_MSG,"Time for start-sims:"<< getTimeString(stopTime-startTime) , 1);
#ifndef NOGUI
guiResetSimulationTimeRange( mSimulationTime );
#endif
@@ -263,7 +213,8 @@ void ntlWorld::finishWorldInit()
*****************************************************************************/
ntlWorld::~ntlWorld()
{
- delete mpGlob->getScene();
+ delete mpGlob->getRenderScene();
+ delete mpGlob->getSimScene();
delete mpGlob;
delete mpLightList;
delete mpPropList;
@@ -271,6 +222,7 @@ ntlWorld::~ntlWorld()
#ifndef NOGUI
if(mpOpenGLRenderer) delete mpOpenGLRenderer;
#endif // NOGUI
+ debMsgStd("ntlWorld",DM_NOTIFY, "ntlWorld done", 10);
}
/******************************************************************************/
@@ -349,9 +301,9 @@ int ntlWorld::renderVisualization( bool multiThreaded )
advanceSims(mFrameCnt);
mFrameCnt++;
long stopTime = getTime();
- debMsgStd("ntlWorld::renderVisualization",DM_MSG,"Time for "<<mSimulationTime<<": "<< getTimeString(stopTime-startTime) <<"s ", 10);
+ debMsgStd("ntlWorld::renderVisualization",DM_MSG,"Time for t="<<mSimulationTime<<": "<< getTimeString(stopTime-startTime) <<" ", 10);
} else {
- double targetTime = mSimulationTime + (*mpSims)[mFirstSim]->getStepTime();
+ double targetTime = mSimulationTime + (*mpSims)[mFirstSim]->getTimestep();
singleStepSims(targetTime);
// check paniced sims (normally done by advanceSims
@@ -390,7 +342,7 @@ int ntlWorld::renderVisualization( bool multiThreaded )
int ntlWorld::singleStepVisualization( void )
{
mThreadRunning = true;
- double targetTime = mSimulationTime + (*mpSims)[mFirstSim]->getStepTime();
+ double targetTime = mSimulationTime + (*mpSims)[mFirstSim]->getTimestep();
singleStepSims(targetTime);
mSimulationTime = (*mpSims)[0]->getCurrentTime();
@@ -419,12 +371,10 @@ int ntlWorld::advanceSims(int framenum)
//debMsgStd("ntlWorld::advanceSims",DM_MSG,"Advancing sims to "<<targetTime, 10 ); // timedebug
for(size_t i=0;i<mpSims->size();i++) { (*mpSims)[i]->setFrameNum(framenum); }
- double targetTime = mSimulationTime + (*mpSims)[mFirstSim]->getFrameTime();
-//FIXME check blender abort here...
-//FIXME check no ipo export
+ double targetTime = mSimulationTime + (*mpSims)[mFirstSim]->getFrameTime(framenum);
// time stopped? nothing else to do...
- if( (*mpSims)[mFirstSim]->getFrameTime() <= 0.0 ){
+ if( (*mpSims)[mFirstSim]->getFrameTime(framenum) <= 0.0 ){
done=true; allPanic=false;
}
@@ -437,17 +387,25 @@ int ntlWorld::advanceSims(int framenum)
#endif // ELBEEM_BLENDER==1
// step all the sims, and check for panic
+ debMsgStd("ntlWorld::advanceSims",DM_MSG, " sims "<<mpSims->size()<<" t"<<targetTime<<" done:"<<done<<" panic:"<<allPanic, 10); // debug // timedebug
while(!done) {
- double nextTargetTime = (*mpSims)[mFirstSim]->getCurrentTime() + (*mpSims)[mFirstSim]->getStepTime();
+ double nextTargetTime = (*mpSims)[mFirstSim]->getCurrentTime() + (*mpSims)[mFirstSim]->getTimestep();
singleStepSims(nextTargetTime);
// check target times
done = true;
allPanic = false;
- for(size_t i=0;i<mpSims->size();i++) {
- if(!(*mpSims)[i]->getVisible()) continue;
- if((*mpSims)[i]->getPanic()) allPanic = true; // do any panic now!?
- //debMsgStd("ntlWorld::advanceSims",DM_MSG, " sim "<<i<<" c"<<(*mpSims)[i]->getCurrentTime()<<" p"<<(*mpSims)[i]->getPanic()<<" t"<<targetTime, 10); // debug // timedebug
+ //if((framenum>0) && (nextTargetTime<=(*mpSims)[mFirstSim]->getCurrentTime()) ) {
+ if((*mpSims)[mFirstSim]->getTimestep() <1e-9 ) {
+ // safety check, avoid timesteps that are too small
+ errMsg("ntlWorld::advanceSims","Invalid time step, causing panic! curr:"<<(*mpSims)[mFirstSim]->getCurrentTime()<<" next:"<<nextTargetTime<<", stept:"<< (*mpSims)[mFirstSim]->getTimestep() );
+ allPanic = true;
+ } else {
+ for(size_t i=0;i<mpSims->size();i++) {
+ if(!(*mpSims)[i]->getVisible()) continue;
+ if((*mpSims)[i]->getPanic()) allPanic = true; // do any panic now!?
+ debMsgStd("ntlWorld::advanceSims",DM_MSG, "Sim "<<i<<", currt:"<<(*mpSims)[i]->getCurrentTime()<<", nt:"<<nextTargetTime<<", panic:"<<(*mpSims)[i]->getPanic()<<", targett:"<<targetTime, 10); // debug // timedebug
+ }
}
if( (targetTime - (*mpSims)[mFirstSim]->getCurrentTime()) > LBM_TIME_EPSILON) done=false;
if(allPanic) done = true;
@@ -474,7 +432,7 @@ int ntlWorld::advanceSims(int framenum)
/* dont check target time, if *targetTime==NULL */
void ntlWorld::singleStepSims(double targetTime) {
const bool debugTime = false;
- //double targetTime = mSimulationTime + (*mpSims)[mFirstSim]->getStepTime();
+ //double targetTime = mSimulationTime + (*mpSims)[mFirstSim]->getTimestep();
if(debugTime) errMsg("ntlWorld::singleStepSims","Target time: "<<targetTime);
for(size_t i=0;i<mpSims->size();i++) {
@@ -484,7 +442,7 @@ void ntlWorld::singleStepSims(double targetTime) {
bool done = false;
while(!done) {
// try to prevent round off errs
- if(debugTime) errMsg("ntlWorld::singleStepSims","Test sim "<<i<<" curt:"<< sim->getCurrentTime()<<" target:"<<targetTime<<" delta:"<<(targetTime - sim->getCurrentTime())<<" stept:"<<sim->getStepTime()<<" leps:"<<LBM_TIME_EPSILON ); // timedebug
+ if(debugTime) errMsg("ntlWorld::singleStepSims","Test sim "<<i<<" curt:"<< sim->getCurrentTime()<<" target:"<<targetTime<<" delta:"<<(targetTime - sim->getCurrentTime())<<" stept:"<<sim->getTimestep()<<" leps:"<<LBM_TIME_EPSILON ); // timedebug
if( (targetTime - sim->getCurrentTime()) > LBM_TIME_EPSILON) {
if(debugTime) errMsg("ntlWorld::singleStepSims","Stepping sim "<<i<<" t:"<< sim->getCurrentTime()); // timedebug
sim->step();
@@ -509,7 +467,7 @@ void ntlWorld::singleStepSims(double targetTime) {
*****************************************************************************/
int ntlWorld::renderScene( void )
{
-#ifndef ELBEEM_BLENDER
+#ifndef ELBEEM_PLUGIN
char nrStr[5]; /* nr conversion */
//std::ostringstream outfilename(""); /* ppm file */
std::ostringstream outfn_conv(""); /* converted ppm with other suffix */
@@ -541,8 +499,8 @@ int ntlWorld::renderScene( void )
/* start program */
timeStart = getTime();
- /* build scene geometry */
- glob->getScene()->prepareScene();
+ /* build scene geometry, calls buildScene(t,false) */
+ glob->getRenderScene()->prepareScene(mSimulationTime);
/* start program */
totalStart = getTime();
@@ -566,7 +524,7 @@ int ntlWorld::renderScene( void )
/* check if vectors are valid */
if( (equal(upVec,ntlVec3Gfx(0.0))) || (equal(rightVec,ntlVec3Gfx(0.0))) ) {
- errorOut("NTL ERROR: Invalid viewpoint vectors!\n");
+ errMsg("ntlWorld::renderScene","Invalid viewpoint vectors! up="<<upVec<<" right="<<rightVec);
return(1);
}
@@ -856,15 +814,66 @@ int ntlWorld::renderScene( void )
delete [] aaCol;
delete [] aaUse;
delete [] finalPic;
- glob->getScene()->cleanupScene();
+ glob->getRenderScene()->cleanupScene();
if(mpGlob->getSingleFrameMode() ) {
debMsgStd("ntlWorld::renderScene",DM_NOTIFY, "Single frame mode done...", 1 );
return 1;
}
-#endif // ELBEEM_BLENDER
+#endif // ELBEEM_PLUGIN
return 0;
}
+/******************************************************************************
+ * renderglobals
+ *****************************************************************************/
+
+
+/*****************************************************************************/
+/* Constructor with standard value init */
+ntlRenderGlobals::ntlRenderGlobals() :
+ mpRenderScene(NULL), mpSimScene(NULL),
+ mpLightList( NULL ), mpMaterials( NULL ), mpSims( NULL ),
+ mResX(320), mResY(200), mAADepth(-1), mMaxColVal(255),
+ mRayMaxDepth( 5 ),
+ mvEye(0.0,0.0,5.0), mvLookat(0.0,0.0,0.0), mvUpvec(0.0,1.0,0.0),
+ mAspect(320.0/200.0),
+ mFovy(45), mcBackgr(0.0,0.0,0.0), mcAmbientLight(0.0,0.0,0.0),
+ mDebugOut( 0 ),
+ mAniStart(0), mAniFrames( -1 ), mAniCount( 0 ),
+ mFrameSkip( 0 ),
+ mCounterRays( 0 ), mCounterShades( 0 ), mCounterSceneInter( 0 ),
+ mOutFilename( "pic" ),
+ mTreeMaxDepth( 30 ), mTreeMaxTriangles( 30 ),
+ mpOpenGlAttr(NULL),
+ mpBlenderAttr(NULL),
+ mTestSphereEnabled( false ),
+ mDebugPixelX( -1 ), mDebugPixelY( -1 ), mTestMode(false),
+ mSingleFrameMode(false), mSingleFrameFilename("")
+ //,mpRndDirections( NULL ), mpRndRoulette( NULL )
+{
+ // create internal attribute list for opengl renderer
+ mpOpenGlAttr = new AttributeList("__ntlOpenGLRenderer");
+ mpBlenderAttr = new AttributeList("__ntlBlenderAttr");
+};
+
+
+/*****************************************************************************/
+/* Destructor */
+ntlRenderGlobals::~ntlRenderGlobals() {
+ if(mpOpenGlAttr) delete mpOpenGlAttr;
+ if(mpBlenderAttr) delete mpBlenderAttr;
+}
+
+
+/*****************************************************************************/
+//! get the next random photon direction
+//ntlVec3Gfx ntlRenderGlobals::getRandomDirection( void ) {
+ //return ntlVec3Gfx(
+ //(mpRndDirections->getGfxReal()-0.5),
+ //(mpRndDirections->getGfxReal()-0.5),
+ //(mpRndDirections->getGfxReal()-0.5) );
+//}
+
diff --git a/intern/elbeem/intern/ntl_world.h b/intern/elbeem/intern/ntl_world.h
index 97c27b06456..2256e85ec96 100644
--- a/intern/elbeem/intern/ntl_world.h
+++ b/intern/elbeem/intern/ntl_world.h
@@ -11,13 +11,14 @@
#include "ntl_vector3dim.h"
#include "ntl_ray.h"
+#include "ntl_lighting.h"
#include "ntl_geometryobject.h"
-#include "ntl_lightobject.h"
-#include "ntl_renderglobals.h"
-#include "ntl_material.h"
#include "simulation_object.h"
#include "elbeem.h"
class ntlOpenGLRenderer;
+class ntlScene;
+class SimulationObject;
+class ntlRandomStream;
class ntlWorld
{
@@ -100,6 +101,7 @@ class ntlWorld
/*! remember the current simulation time */
double mSimulationTime;
+
/*! first simulation that is valid */
int mFirstSim;
@@ -110,4 +112,279 @@ class ntlWorld
int mFrameCnt;
};
+
+//! Class that handles global rendering parameters
+class ntlRenderGlobals
+{
+ public:
+ //! Standard constructor
+ ntlRenderGlobals();
+ //! Destructor
+ ~ntlRenderGlobals();
+
+ //! Returns the renderscene manager (scene changes for each frame)
+ inline ntlScene *getRenderScene(void) { return mpRenderScene; }
+ //! Set the renderscene manager
+ inline void setRenderScene(ntlScene *set) { mpRenderScene = set;}
+
+ //! Returns the simulation scene manager (static scene with sim objects)
+ inline ntlScene *getSimScene(void) { return mpSimScene; }
+ //! Set the simulation scene manager
+ inline void setSimScene(ntlScene *set) { mpSimScene = set;}
+
+ //! Returns the light object list
+ inline vector<ntlLightObject*> *getLightList(void) { return mpLightList; }
+ //! Set the light list
+ inline void setLightList(vector<ntlLightObject*> *set) { mpLightList = set;}
+
+ //! Returns the property object list
+ inline vector<ntlMaterial*> *getMaterials(void) { return mpMaterials; }
+ //! Set the property list
+ inline void setMaterials(vector<ntlMaterial*> *set) { mpMaterials = set;}
+
+ //! Returns the list of simulations
+ inline vector<SimulationObject*> *getSims(void) { return mpSims; }
+ //! Set the pointer to the list of simulations
+ inline void setSims(vector<SimulationObject*> *set) { mpSims = set;}
+
+ //! Set the x resolution
+ inline void setResX(unsigned int set) { mResX = set; }
+ //! Set the y resolution
+ inline void setResY(unsigned int set) { mResY = set; }
+ //! Set the anti-aliasing depth
+ inline void setAADepth(int set) { mAADepth = set; }
+ //! Set the max color value
+ inline void setMaxColVal(unsigned int set) { mMaxColVal = set; }
+ //! Set the maximum ray recursion
+ inline void setRayMaxDepth(unsigned int set) { mRayMaxDepth = set; }
+ //! Set the eye point
+ inline void setEye(ntlVec3Gfx set) { mvEye = set; }
+ //! Set the look at vector
+ inline void setLookat(ntlVec3Gfx set) { mvLookat = set; }
+ //! Set the up vector
+ inline void setUpVec(ntlVec3Gfx set) { mvUpvec = set; }
+ //! Set the image aspect
+ inline void setAspect(float set) { mAspect = set; }
+ //! Set the field of view
+ inline void setFovy(float set) { mFovy = set; }
+ //! Set the background color
+ inline void setBackgroundCol(ntlColor set) { mcBackgr = set; }
+ //! Set the ambient lighting color
+ inline void setAmbientLight(ntlColor set) { mcAmbientLight = set; }
+ //! Set the debug output var
+ inline void setDebugOut(int set) { mDebugOut = set; }
+
+ //! Set the animation start time
+ inline void setAniStart(int set) { mAniStart = set; }
+ //! Set the animation number of frames
+ inline void setAniFrames(int set) { mAniFrames = set; }
+ //! Set the animation
+ inline void setAniCount(int set) { mAniCount = set; }
+ //! Set the ray counter
+ inline void setCounterRays(int set) { mCounterRays = set; }
+ //! Set the ray shades counter
+ inline void setCounterShades(int set) { mCounterShades = set; }
+ //! Set the scenen intersection counter
+ inline void setCounterSceneInter(int set) { mCounterSceneInter = set; }
+ //! Set if existing frames should be skipped
+ inline void setFrameSkip(int set) { mFrameSkip = set; }
+
+ //! Set the outfilename
+ inline void setOutFilename(string set) { mOutFilename = set; }
+
+ //! get Maximum depth for BSP tree
+ inline void setTreeMaxDepth( int set ) { mTreeMaxDepth = set; }
+ //! get Maxmimum nr of triangles per BSP tree node
+ inline void setTreeMaxTriangles( int set ) { mTreeMaxTriangles = set; }
+
+ //! set the enable flag of the test sphere
+ inline void setTestSphereEnabled( bool set ) { mTestSphereEnabled = set; }
+ //! set the center of the test sphere
+ inline void setTestSphereCenter( ntlVec3Gfx set ) { mTestSphereCenter = set; }
+ //! set the radius of the test sphere
+ inline void setTestSphereRadius( gfxReal set ) { mTestSphereRadius = set; }
+ //! set the material name of the test sphere
+ inline void setTestSphereMaterialName( char* set ) { mTestSphereMaterialName = set; }
+ //! set debugging pixel coordinates
+ inline void setDebugPixel( int setx, int sety ) { mDebugPixelX = setx; mDebugPixelY = sety; }
+ //! set test mode flag
+ inline void setTestMode( bool set ) { mTestMode = set; }
+ //! set single frame mode flag
+ inline void setSingleFrameMode(bool set) {mSingleFrameMode = set; };
+ //! set single frame mode filename
+ inline void setSingleFrameFilename(string set) {mSingleFrameFilename = set; };
+
+
+ //! Return the x resolution
+ inline unsigned int getResX(void) { return mResX; }
+ //! Return the y resolution
+ inline unsigned int getResY(void) { return mResY; }
+ //! Return the anti-aliasing depth
+ inline int getAADepth(void) { return mAADepth; }
+ //! Return the max color value for ppm
+ inline unsigned int getMaxColVal(void) { return mMaxColVal; }
+ //! Return the maximum ray recursion
+ inline unsigned int getRayMaxDepth(void) { return mRayMaxDepth; }
+ //! Return the eye point
+ inline ntlVec3Gfx getEye(void) { return mvEye; }
+ //! Return the look at vector
+ inline ntlVec3Gfx getLookat(void) { return mvLookat; }
+ //! Return the up vector
+ inline ntlVec3Gfx getUpVec(void) { return mvUpvec; }
+ //! Return the image aspect
+ inline float getAspect(void) { return mAspect; }
+ //! Return the field of view
+ inline float getFovy(void) { return mFovy; }
+ //! Return the background color
+ inline ntlColor getBackgroundCol(void) { return mcBackgr; }
+ //! Return the ambient color
+ inline ntlColor getAmbientLight(void) { return mcAmbientLight; }
+ //! Return the debug mode setting
+ inline int getDebugOut(void) { return mDebugOut; }
+
+ //! Return the animation start time
+ inline int getAniStart(void) { return mAniStart; }
+ //! Return the animation frame number
+ inline int getAniFrames(void) { return mAniFrames; }
+ //! Return the animation counter
+ inline int getAniCount(void) { return mAniCount; }
+ //! Return the ray counter
+ inline int getCounterRays(void) { return mCounterRays; }
+ //! Return the ray shades counter
+ inline int getCounterShades(void) { return mCounterShades; }
+ //! Return the scene intersection counter
+ inline int getCounterSceneInter(void) { return mCounterSceneInter; }
+ //! Check if existing frames should be skipped
+ inline int getFrameSkip( void ) { return mFrameSkip; }
+
+
+ //! Return the outfilename
+ inline string getOutFilename(void) { return mOutFilename; }
+
+ //! get Maximum depth for BSP tree
+ inline int getTreeMaxDepth( void ) { return mTreeMaxDepth; }
+ //! get Maxmimum nr of triangles per BSP tree node
+ inline int getTreeMaxTriangles( void ) { return mTreeMaxTriangles; }
+
+ //! get open gl attribute list
+ inline AttributeList* getOpenGlAttributes( void ) { return mpOpenGlAttr; }
+ //! get blender output attribute list
+ inline AttributeList* getBlenderAttributes( void ) { return mpBlenderAttr; }
+
+ //! is the test sphere enabled?
+ inline bool getTestSphereEnabled( void ) { return mTestSphereEnabled; }
+ //! get the center of the test sphere
+ inline ntlVec3Gfx getTestSphereCenter( void ) { return mTestSphereCenter; }
+ //! get the radius of the test sphere
+ inline gfxReal getTestSphereRadius( void) { return mTestSphereRadius; }
+ //! get the materialname of the test sphere
+ inline char *getTestSphereMaterialName( void) { return mTestSphereMaterialName; }
+ //! get the debug pixel coordinate
+ inline int getDebugPixelX( void ) { return mDebugPixelX; }
+ //! get the debug pixel coordinate
+ inline int getDebugPixelY( void ) { return mDebugPixelY; }
+ //! get test mode flag
+ inline bool getTestMode( void ) { return mTestMode; }
+ //! set single frame mode flag
+ inline bool getSingleFrameMode() { return mSingleFrameMode; };
+ //! set single frame mode filename
+ inline string getSingleFrameFilename() { return mSingleFrameFilename; };
+
+
+private:
+
+ /*! Scene storage (dynamic rendering scene) */
+ ntlScene *mpRenderScene;
+ /*! Scene storage (static sim scene, inited only once) */
+ ntlScene *mpSimScene;
+
+ //! List of light objects
+ vector<ntlLightObject*> *mpLightList;
+ //! List of surface properties
+ vector<ntlMaterial*> *mpMaterials;
+ /*! storage for simulations */
+ vector<SimulationObject*> *mpSims;
+
+ //! resolution of the picture
+ unsigned int mResX, mResY;
+ //! Anti-Aliasing depth
+ int mAADepth;
+ //! max color value for ppm
+ unsigned int mMaxColVal;
+ /* Maximal ray recursion depth */
+ int mRayMaxDepth;
+ //! The eye point
+ ntlVec3Gfx mvEye;
+ //! The look at point
+ ntlVec3Gfx mvLookat;
+ //! The up vector
+ ntlVec3Gfx mvUpvec;
+ //! The image aspect = Xres/Yres
+ float mAspect;
+ //! The horizontal field of view
+ float mFovy;
+ //! The background color
+ ntlColor mcBackgr;
+ //! The ambient color
+ ntlColor mcAmbientLight;
+ //! how much debug output is needed? off by default
+ char mDebugOut;
+
+
+ //! animation properties, start time
+ int mAniStart;
+ //! animation properties, number of frames to render
+ int mAniFrames;
+ //! animation status, current frame number
+ int mAniCount;
+ /*! Should existing picture frames be skipped? */
+ int mFrameSkip;
+
+
+ //! count the total number of rays created (also used for ray ID's)
+ int mCounterRays;
+ //! count the total number of rays shaded
+ int mCounterShades;
+ //! count the total number of scene intersections
+ int mCounterSceneInter;
+
+ /*! filename of output pictures (without suffix or numbers) */
+ string mOutFilename;
+
+ //! get Maximum depth for BSP tree
+ int mTreeMaxDepth;
+ //! get Maxmimum nr of triangles per BSP tree node
+ int mTreeMaxTriangles;
+
+ //! attribute list for opengl renderer
+ AttributeList *mpOpenGlAttr;
+ //! attribute list for blender output
+ AttributeList *mpBlenderAttr;
+
+
+ //! Enable test sphere?
+ bool mTestSphereEnabled;
+ //! Center of the test sphere
+ ntlVec3Gfx mTestSphereCenter;
+ //! Radius of the test sphere
+ gfxReal mTestSphereRadius;
+ //! Materialname of the test sphere
+ char *mTestSphereMaterialName;
+ //! coordinates of the debugging pixel
+ int mDebugPixelX, mDebugPixelY;
+
+ //! test mode for quick rendering activated?, inited in ntl_scene::buildScene
+ bool mTestMode;
+
+ //! single frame flag
+ bool mSingleFrameMode;
+ //! filename for single frame mode
+ string mSingleFrameFilename;
+
+ /*! Two random number streams for photon generation (one for the directions, the other for russion roulette) */
+ //ntlRandomStream *mpRndDirections, *mpRndRoulette;
+};
+
+
+
#endif
diff --git a/intern/elbeem/intern/parametrizer.cpp b/intern/elbeem/intern/parametrizer.cpp
index 581b04216bb..50d544d2bcf 100644
--- a/intern/elbeem/intern/parametrizer.cpp
+++ b/intern/elbeem/intern/parametrizer.cpp
@@ -10,6 +10,9 @@
#include <sstream>
#include "parametrizer.h"
+// debug output flag
+#define DEBUG_PARAMCHANNELS 0
+
/*! param seen debug string array */
char *ParamStrings[] = {
"RelaxTime",
@@ -19,7 +22,7 @@ char *ParamStrings[] = {
"DomainSize",
"GravityForce",
"TimeLength",
- "StepTime",
+ "Timestep",
"Size",
"TimeFactor",
"AniFrames",
@@ -42,26 +45,25 @@ char *ParamStrings[] = {
* Default constructor
*****************************************************************************/
Parametrizer::Parametrizer( void ) :
- mRelaxTime( 1.0 ), mReynolds( 0.0 ),
- mViscosity( 8.94e-7 ), mcViscosity( 8.94e-7 ),
+ mcViscosity( 8.94e-7 ),
mSoundSpeed( 1500 ),
mDomainSize( 0.1 ), mCellSize( 0.01 ),
- mGravity(0.0, 0.0, 0.0), mcGravity( ParamVec(0.0) ),
- mLatticeGravity(0.0, 0.0, 0.0),
- mStepTime(0.0001), mDesiredStepTime(-1.0),
- mMaxStepTime(-1.0),
- mMinStepTime(-1.0),
+ mcGravity( ParamVec(0.0) ),
+ mTimestep(0.0001), mDesiredTimestep(-1.0),
+ mMaxTimestep(-1.0),
+ mMinTimestep(-1.0),
mSizex(50), mSizey(50), mSizez(50),
mTimeFactor( 1.0 ),
- //mAniFrames(0),
- mAniFrameTime(0.0001), mcAniFrameTime(0.0001),
+ mcAniFrameTime(0.0001),
+ mAniFrameTime(0.0001),
+ mTimeStepScale(1.0),
mAniStart(0.0),
- mExtent(1.0, 1.0, 1.0), mSurfaceTension( 0.0 ),
+ mExtent(1.0, 1.0, 1.0), //mSurfaceTension( 0.0 ),
mDensity(1000.0), mGStar(0.0001), mFluidVolumeHeight(0.0),
mSimulationMaxSpeed(0.0),
- mTadapMaxOmega(2.0), mTadapMaxSpeed(0.1)/*FIXME test 0.16666 */, mTadapLevels(1),
+ mTadapMaxOmega(2.0), mTadapMaxSpeed(0.1), mTadapLevels(1),
+ mFrameNum(0),
mSeenValues( 0 ), mCalculatedValues( 0 )
- //mActive( false )
{
}
@@ -89,15 +91,8 @@ void Parametrizer::parseAttrList()
mSetupType = mpAttrs->readString("p_setup",mSetupType, "Parametrizer","mSetupType", false);
// real params
- mRelaxTime = mpAttrs->readFloat("p_relaxtime",mRelaxTime, "Parametrizer","mRelaxTime", false);
- if(getAttributeList()->exists("p_relaxtime")) seenThis( PARAM_RELAXTIME );
-
- mReynolds = mpAttrs->readFloat("p_reynolds",mReynolds, "Parametrizer","mReynolds", false);
- if(getAttributeList()->exists("p_reynolds")) seenThis( PARAM_REYNOLDS );
-
- mViscosity = mpAttrs->readFloat("p_viscosity",mViscosity, "Parametrizer","mViscosity", false);
- mcViscosity = mpAttrs->readChannelFloat("p_viscosity");
- if(getAttributeList()->exists("p_viscosity")) seenThis( PARAM_VISCOSITY );
+ if(getAttributeList()->exists("p_viscosity")) {
+ mcViscosity = mpAttrs->readChannelFloat("p_viscosity"); seenThis( PARAM_VISCOSITY ); }
mSoundSpeed = mpAttrs->readFloat("p_soundspeed",mSoundSpeed, "Parametrizer","mSoundSpeed", false);
if(getAttributeList()->exists("p_soundspeed")) seenThis( PARAM_SOUNDSPEED );
@@ -105,27 +100,24 @@ void Parametrizer::parseAttrList()
mDomainSize = mpAttrs->readFloat("p_domainsize",mDomainSize, "Parametrizer","mDomainSize", false);
if(getAttributeList()->exists("p_domainsize")) seenThis( PARAM_DOMAINSIZE );
if(mDomainSize<=0.0) {
- errMsg("Parametrizer::parseAttrList","Invalid real world domain size:"<<mAniFrameTime<<", resetting to 0.1");
+ errMsg("Parametrizer::parseAttrList","Invalid real world domain size:"<<mDomainSize<<", resetting to 0.1");
mDomainSize = 0.1;
}
- mGravity = mpAttrs->readVec3d("p_gravity",mGravity, "Parametrizer","mGravity", false);
- mcGravity = mpAttrs->readChannelVec3d("p_gravity");
- if(getAttributeList()->exists("p_gravity")) seenThis( PARAM_GRAVITY );
+ if(getAttributeList()->exists("p_gravity")) { // || (!mcGravity.isInited()) ) {
+ mcGravity = mpAttrs->readChannelVec3d("p_gravity"); seenThis( PARAM_GRAVITY );
+ }
- mStepTime = mpAttrs->readFloat("p_steptime",mStepTime, "Parametrizer","mStepTime", false);
+ mTimestep = mpAttrs->readFloat("p_steptime",mTimestep, "Parametrizer","mTimestep", false);
if(getAttributeList()->exists("p_steptime")) seenThis( PARAM_STEPTIME );
mTimeFactor = mpAttrs->readFloat("p_timefactor",mTimeFactor, "Parametrizer","mTimeFactor", false);
if(getAttributeList()->exists("p_timefactor")) seenThis( PARAM_TIMEFACTOR );
- mAniFrameTime = mpAttrs->readFloat("p_aniframetime",mAniFrameTime, "Parametrizer","mAniFrameTime", false);
- mcAniFrameTime = mpAttrs->readChannelFloat("p_aniframetime");
- if(getAttributeList()->exists("p_aniframetime")) { seenThis( PARAM_ANIFRAMETIME ); }
- if(mAniFrameTime<0.0) {
- errMsg("Parametrizer::parseAttrList","Invalid frame time:"<<mAniFrameTime<<", resetting to 0.0001");
- mAniFrameTime = 0.0001;
+ if(getAttributeList()->exists("p_aniframetime")) { //|| (!mcAniFrameTime.isInited()) ) {
+ mcAniFrameTime = mpAttrs->readChannelFloat("p_aniframetime");seenThis( PARAM_ANIFRAMETIME );
}
+ mTimeStepScale = mpAttrs->readFloat("p_timestepscale",mTimeStepScale, "Parametrizer","mTimeStepScale", false);
mAniStart = mpAttrs->readFloat("p_anistart",mAniStart, "Parametrizer","mAniStart", false);
if(getAttributeList()->exists("p_anistart")) seenThis( PARAM_ANISTART );
@@ -134,14 +126,14 @@ void Parametrizer::parseAttrList()
mAniStart = 0.0;
}
- mSurfaceTension = mpAttrs->readFloat("p_surfacetension",mSurfaceTension, "Parametrizer","mSurfaceTension", false);
- if(getAttributeList()->exists("p_surfacetension")) seenThis( PARAM_SURFACETENSION );
+ //mSurfaceTension = mpAttrs->readFloat("p_surfacetension",mSurfaceTension, "Parametrizer","mSurfaceTension", false);
+ //if(getAttributeList()->exists("p_surfacetension")) seenThis( PARAM_SURFACETENSION );
mDensity = mpAttrs->readFloat("p_density",mDensity, "Parametrizer","mDensity", false);
if(getAttributeList()->exists("p_density")) seenThis( PARAM_DENSITY );
- mCellSize = mpAttrs->readFloat("p_cellsize",mCellSize, "Parametrizer","mCellSize", false);
- if(getAttributeList()->exists("p_cellsize")) seenThis( PARAM_CELLSIZE );
+ ParamFloat cellSize = 0.0; // unused, deprecated
+ cellSize = mpAttrs->readFloat("p_cellsize",cellSize, "Parametrizer","cellSize", false);
mGStar = mpAttrs->readFloat("p_gstar",mGStar, "Parametrizer","mGStar", false);
if(getAttributeList()->exists("p_gstar")) seenThis( PARAM_GSTAR );
@@ -156,16 +148,28 @@ void Parametrizer::parseAttrList()
/******************************************************************************
*! advance to next render/output frame
*****************************************************************************/
-void Parametrizer::setFrameNum(int num) {
- double frametime = (double)num;
- double oldval = mAniFrameTime;
- mAniFrameTime = mcAniFrameTime.get(frametime);
- if(mAniFrameTime<0.0) {
- errMsg("Parametrizer::setFrameNum","Invalid frame time:"<<mAniFrameTime<<" at frame "<<num<<", resetting to "<<oldval);
- mAniFrameTime = oldval;
+void Parametrizer::setFrameNum(int frame) {
+ //double oldval = mAniFrameTime;
+ //mAniFrameTime = mcAniFrameTime.get(frametime);
+ //if(mAniFrameTime<0.0) {
+ //errMsg("Parametrizer::setFrameNum","Invalid frame time:"<<mAniFrameTime<<" at frame "<<frame<<", resetting to "<<oldval);
+ //mAniFrameTime = oldval; }
+ //errMsg("ChannelAnimDebug","anim: anif"<<mAniFrameTime<<" at "<<frame<<" ");
+ // debug getAttributeList()->find("p_aniframetime")->print();
+ mFrameNum = frame;
+ if(DEBUG_PARAMCHANNELS) errMsg("DEBUG_PARAMCHANNELS","setFrameNum frame-num="<<mFrameNum);
+}
+/*! get time of an animation frame (renderer) */
+ParamFloat Parametrizer::getAniFrameTime( int frame ) {
+ double frametime = (double)frame;
+ ParamFloat anift = mcAniFrameTime.get(frametime);
+ if(anift<0.0) {
+ ParamFloat resetv = 0.;
+ errMsg("Parametrizer::setFrameNum","Invalid frame time:"<<anift<<" at frame "<<frame<<", resetting to "<<resetv);
+ anift = resetv;
}
- //errMsg("ChannelAnimDebug","anim: anif"<<mAniFrameTime<<" at "<<num<<" ");
- getAttributeList()->find("p_aniframetime")->print();
+ if(DEBUG_PARAMCHANNELS) errMsg("DEBUG_PARAMCHANNELS","getAniFrameTime frame="<<frame<<", frametime="<<anift<<" ");
+ return anift;
}
/******************************************************************************
@@ -173,8 +177,8 @@ void Parametrizer::setFrameNum(int num) {
*****************************************************************************/
ParamVec Parametrizer::calculateAddForce(ParamVec vec, string usage)
{
- ParamVec ret = vec * (mStepTime*mStepTime) /mCellSize;
- debMsgStd("Parametrizer::calculateVector", DM_MSG, "scaled vector = "<<ret<<" for '"<<usage<<"', org = "<<vec<<" dt="<<mStepTime ,10);
+ ParamVec ret = vec * (mTimestep*mTimestep) /mCellSize;
+ debMsgStd("Parametrizer::calculateVector", DM_MSG, "scaled vector = "<<ret<<" for '"<<usage<<"', org = "<<vec<<" dt="<<mTimestep ,10);
return ret;
}
@@ -196,109 +200,98 @@ ParamFloat Parametrizer::calculateCellSize(void)
/* simple calulation functions */
/*****************************************************************************/
-/*! get omega for LBM */
-//ParamFloat Parametrizer::calculateOmega( void ) { return (1.0/mRelaxTime); }
/*! get omega for LBM from channel */
-ParamFloat Parametrizer::calculateOmega( ParamFloat t ) {
- mViscosity = mcViscosity.get(t);
- ParamFloat viscStar = calculateLatticeViscosity();
- mRelaxTime = (6.0 * viscStar + 1) * 0.5;
- //errMsg("ChannelAnimDebug","anim: omega"<<(1.0/mRelaxTime)<<" v"<<mViscosity<<" at "<<t<<" ");
- return (1.0/mRelaxTime);
+ParamFloat Parametrizer::calculateOmega( double time ) {
+ ParamFloat viscStar = calculateLatticeViscosity(time);
+ ParamFloat relaxTime = (6.0 * viscStar + 1) * 0.5;
+ if(DEBUG_PARAMCHANNELS) errMsg("DEBUG_PARAMCHANNELS","calculateOmega viscStar="<<viscStar<<" relaxtime="<<relaxTime);
+ return (1.0/relaxTime);
}
-/*! get no. of timesteps for LBM */
-//int calculateNoOfSteps( void ) {
-int Parametrizer::calculateNoOfSteps( ParamFloat timelen ) {
- return (int)(timelen/mStepTime);
+/*! get external force x component */
+ParamVec Parametrizer::calculateGravity( double time ) {
+ ParamVec grav = mcGravity.get(time);
+ ParamFloat forceFactor = (mTimestep *mTimestep)/mCellSize;
+ ParamVec latticeGravity = grav * forceFactor;
+ if(DEBUG_PARAMCHANNELS) errMsg("DEBUG_PARAMCHANNELS","calculateGravity grav="<<grav<<" ff"<<forceFactor<<" lattGrav="<<latticeGravity);
+ return latticeGravity;
}
-/*! get external force x component */
-//ParamVec Parametrizer::calculateGravity( void ) { return mLatticeGravity; }
-ParamVec Parametrizer::calculateGravity( ParamFloat t ) {
- mGravity = mcGravity.get(t);
- ParamFloat forceFactor = (mStepTime *mStepTime)/mCellSize;
- mLatticeGravity = mGravity * forceFactor;
- //errMsg("ChannelAnimDebug","anim: grav"<<mLatticeGravity<<" g"<<mGravity<<" at "<<t<<" ");
- return mLatticeGravity;
+/*! calculate the lattice viscosity */
+ParamFloat Parametrizer::calculateLatticeViscosity( double time ) {
+ // check seen values
+ int reqValues = PARAM_VISCOSITY | PARAM_STEPTIME;
+ if(!checkSeenValues( reqValues ) ){
+ errMsg("Parametrizer::calculateLatticeViscosity"," Missing arguments!");
+ }
+ ParamFloat viscStar = mcViscosity.get(time) * mTimestep / (mCellSize*mCellSize);
+ if(DEBUG_PARAMCHANNELS) errMsg("DEBUG_PARAMCHANNELS","calculateLatticeViscosity viscStar="<<viscStar);
+ return viscStar;
}
/*! get no of steps for the given length in seconds */
int Parametrizer::calculateStepsForSecs( ParamFloat s ) {
- return (int)(s/mStepTime);
+ return (int)(s/mTimestep);
}
/*! get start time of animation */
int Parametrizer::calculateAniStart( void ) {
- return (int)(mAniStart/mStepTime);
+ return (int)(mAniStart/mTimestep);
}
/*! get no of steps for a single animation frame */
-int Parametrizer::calculateAniStepsPerFrame( void ) {
+int Parametrizer::calculateAniStepsPerFrame(int frame) {
if(!checkSeenValues(PARAM_ANIFRAMETIME)) {
errFatal("Parametrizer::calculateAniStepsPerFrame", "Missing ani frame time argument!", SIMWORLD_INITERROR);
return 1;
}
- int value = (int)(mAniFrameTime/mStepTime);
+ int value = (int)(getAniFrameTime(frame)/mTimestep);
if((value<0) || (value>1000000)) {
- errFatal("Parametrizer::calculateAniStepsPerFrame", "Invalid step-time (="<<mAniFrameTime<<") <> ani-frame-time ("<<mStepTime<<") settings, aborting...", SIMWORLD_INITERROR);
+ errFatal("Parametrizer::calculateAniStepsPerFrame", "Invalid step-time (="<<mAniFrameTime<<") <> ani-frame-time ("<<mTimestep<<") settings, aborting...", SIMWORLD_INITERROR);
return 1;
}
return value;
}
+/*! get no. of timesteps for LBM */
+int Parametrizer::calculateNoOfSteps( ParamFloat timelen ) {
+ return (int)(timelen/mTimestep);
+}
+
/*! get extent of the domain = (1,1,1) if parametrizer not used, (x,y,z) [m] otherwise */
ParamVec Parametrizer::calculateExtent( void ) {
return mExtent;
}
/*! get (scaled) surface tension */
-ParamFloat Parametrizer::calculateSurfaceTension( void ) {
- return mSurfaceTension;
+//ParamFloat Parametrizer::calculateSurfaceTension( void ) { return mSurfaceTension; }
+
+/*! get the length of a single time step */
+// explicity scaled by time factor for refinement
+ParamFloat Parametrizer::getTimestep( void ) {
+ return mTimestep;
}
/*! calculate lattice velocity from real world value [m/s] */
ParamVec Parametrizer::calculateLattVelocityFromRw( ParamVec ivel ) {
ParamVec velvec = ivel;
velvec /= mCellSize;
- velvec *= mStepTime;
+ velvec *= mTimestep;
return velvec;
}
/*! calculate real world [m/s] velocity from lattice value */
ParamVec Parametrizer::calculateRwVelocityFromLatt( ParamVec ivel ) {
ParamVec velvec = ivel;
velvec *= mCellSize;
- velvec /= mStepTime;
+ velvec /= mTimestep;
return velvec;
}
-/*! get the length of a single time step */
-// explicity scaled by time factor for refinement
-// testing purposes (e.g. fsgr solver)
-// not working... done manually in solver
-ParamFloat Parametrizer::getStepTime( void ) {
- //return mTimeFactor * mStepTime;
- return mStepTime;
-}
-
-/*! calculate the lattice viscosity */
-ParamFloat Parametrizer::calculateLatticeViscosity( void ) {
- // check seen values
- int reqValues = PARAM_VISCOSITY | PARAM_STEPTIME; // |PARAM_CELLSIZE | PARAM_GRAVITY;
- if(!checkSeenValues( reqValues ) ){
- errMsg("Parametrizer::calculateLatticeViscosity"," Missing arguments!");
- }
- ParamFloat viscStar = mViscosity * mStepTime / (mCellSize*mCellSize);
- return viscStar;
-}
-
/*! get g star value with fhvol calculations */
ParamFloat Parametrizer::getCurrentGStar( void ) {
ParamFloat gStar = mGStar; // check? TODO get from mNormalizedGStar?
- if(mFluidVolumeHeight>0.0) {
- gStar = mGStar/mFluidVolumeHeight;
- }
+ if(mFluidVolumeHeight>0.0) { gStar = mGStar/mFluidVolumeHeight; }
return gStar;
}
@@ -306,18 +299,12 @@ ParamFloat Parametrizer::getCurrentGStar( void ) {
* function that tries to calculate all the missing values from the given ones
* prints errors and returns false if thats not possible
*****************************************************************************/
-bool Parametrizer::calculateAllMissingValues( bool silent )
+bool Parametrizer::calculateAllMissingValues( double time, bool silent )
{
bool init = false; // did we init correctly?
int valuesChecked = 0;
int reqValues;
- // are we active anyway?
- //if(!mActive) {
- // not active - so there's nothing to calculate
- //return true;
- //}
-
// we always need the sizes
reqValues = PARAM_SIZE;
valuesChecked |= reqValues;
@@ -326,10 +313,6 @@ bool Parametrizer::calculateAllMissingValues( bool silent )
return false;
}
- if(checkSeenValues(PARAM_CELLSIZE)) {
- errMsg("Parametrizer::calculateAllMissingValues"," Dont explicitly set cell size (use domain size instead)");
- return false;
- }
if(!checkSeenValues(PARAM_DOMAINSIZE)) {
errMsg("Parametrizer::calculateAllMissingValues"," Missing domain size argument!");
return false;
@@ -343,7 +326,6 @@ bool Parametrizer::calculateAllMissingValues( bool silent )
/* Carolin init , see DA for details */
ParamFloat maxDeltaT = 0.0;
- ParamFloat maxSpeed = 1.0/6.0; // for rough reynolds approx
/* normalized gstar init */
reqValues = PARAM_NORMALIZEDGSTAR;
@@ -355,7 +337,13 @@ bool Parametrizer::calculateAllMissingValues( bool silent )
errMsg("Parametrizer::calculateAllMissingValues","Invalid NormGstar: "<<mNormalizedGStar<<"... resetting to "<<normgstarReset);
mNormalizedGStar = normgstarReset;
}
+
mGStar = mNormalizedGStar/maxsize;
+
+// TODO FIXME add use testdata check!
+mGStar = mNormalizedGStar/mSizez;
+errMsg("Warning","Used z-dir for gstar!");
+
if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," g star set to "<<mGStar<<" from normalizedGStar="<<mNormalizedGStar ,1);
seenThis(PARAM_GSTAR);
}
@@ -370,20 +358,19 @@ bool Parametrizer::calculateAllMissingValues( bool silent )
mGStar = gstarReset;
}
- ParamFloat gStar = getCurrentGStar();
+ ParamFloat gStar = getCurrentGStar(); // mGStar
if(mFluidVolumeHeight>0.0) {
debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," height"<<mFluidVolumeHeight<<" resGStar = "<<gStar, 10);
}
if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," g star = "<<gStar, 10);
- //if(!checkSeenValues(PARAM_GRAVITY)) { errMsg("Parametrizer::calculateAllMissingValues","Setup requires gravity force!"); goto failure; }
ParamFloat forceStrength = 0.0;
- if(checkSeenValues(PARAM_GRAVITY)) { forceStrength = norm(mGravity); }
- //if(forceStrength<=0) { errMsg("Parametrizer::calculateAllMissingValues"," Init failed - forceStrength = "<<forceStrength); goto failure; }
+ //if(checkSeenValues(PARAM_GRAVITY)) { forceStrength = norm( calculateGravity(time) ); }
+ if(checkSeenValues(PARAM_GRAVITY)) { forceStrength = norm( mcGravity.get(time) ); }
// determine max. delta density per timestep trough gravity force
if(forceStrength>0.0) {
- maxDeltaT = sqrt( gStar*mCellSize/forceStrength );
+ maxDeltaT = sqrt( gStar*mCellSize *mTimeStepScale /forceStrength );
} else {
// use 1 lbm setp = 1 anim step as max
maxDeltaT = mAniFrameTime;
@@ -391,22 +378,22 @@ bool Parametrizer::calculateAllMissingValues( bool silent )
if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," targeted step time = "<<maxDeltaT, 10);
- ParamFloat viscStarFac = mViscosity/(mCellSize*mCellSize);
- if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," viscStarFac = "<<viscStarFac, 10);
+ //ParamFloat viscStarFac = mViscosity/(mCellSize*mCellSize);
+ //if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," viscStarFac = "<<viscStarFac<<" viscosity:"<<mViscosity, 10);
// time step adaptivty, only for caro with max sim speed
ParamFloat setDeltaT = maxDeltaT;
- if(mDesiredStepTime>0.0) {
+ if(mDesiredTimestep>0.0) {
// explicitly set step time according to max velocity in sim
- setDeltaT = mDesiredStepTime;
- mDesiredStepTime = -1.0;
+ setDeltaT = mDesiredTimestep;
if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," desired step time = "<<setDeltaT, 10);
+ mDesiredTimestep = -1.0;
} else {
// just use max delta t as current
}
// and once for init determine minimal delta t by omega max.
- if((mMinStepTime<0.0) || (mMaxStepTime<0.0)) {
+ if((mMinTimestep<0.0) || (mMaxTimestep<0.0)) {
ParamFloat minDeltaT;
ParamFloat maxOmega = mTadapMaxOmega;
ParamFloat minRelaxTime = 1.0/maxOmega;
@@ -417,8 +404,8 @@ bool Parametrizer::calculateAllMissingValues( bool silent )
maxOmega = 1.0/minRelaxTime;
if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," maxOmega="<<maxOmega<<" minRelaxTime="<<minRelaxTime<<" levels="<<mTadapLevels, 1);
// visc-star for min relax time to calculate min delta ta
- if(mViscosity>0.0) {
- minDeltaT = ((2.0*minRelaxTime-1.0)/6.0) * mCellSize * mCellSize / mViscosity;
+ if(mcViscosity.get(time)>0.0) {
+ minDeltaT = ((2.0*minRelaxTime-1.0)/6.0) * mCellSize * mCellSize / mcViscosity.get(time);
} else {
// visc=0, this is not physical, but might happen
minDeltaT = 0.0;
@@ -426,62 +413,37 @@ bool Parametrizer::calculateAllMissingValues( bool silent )
if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," min delta t = "<<minDeltaT<<" , range = " << (maxDeltaT/minDeltaT) ,1);
// sim speed + accel shouldnt exceed 0.1?
- mMaxStepTime = maxDeltaT;
- mMinStepTime = minDeltaT;
+ mMaxTimestep = maxDeltaT;
+ mMinTimestep = minDeltaT;
// only use once...
}
- setStepTime( setDeltaT ); // set mStepTime to new value
-
- //ParamFloat viscStar = mViscosity * mStepTime / (mCellSize*mCellSize);
- ParamFloat viscStar = calculateLatticeViscosity();
- mRelaxTime = (6.0 * viscStar + 1) * 0.5;
+ setTimestep( setDeltaT ); // set mTimestep to new value
init = true;
}
// finish init
if(init) {
- if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," omega = "<<calculateOmega(0.0)<<", relax time = "<<mRelaxTime<<", delt="<<mStepTime,1);
- //debMsgStd("Parametrizer::calculateAllMissingValues: lbm steps = "<<calculateNoOfSteps()<<" ",1);
+ if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," omega = "<<calculateOmega(0.0)<<", delt="<<mTimestep,1);
if(checkSeenValues(PARAM_GRAVITY)) {
- ParamFloat forceFactor = (mStepTime *mStepTime)/mCellSize;
- //if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," given force = "<<PRINT_NTLVEC(mGravity),1);
- mLatticeGravity = mGravity * forceFactor;
- if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," gravity force = "<<PRINT_NTLVEC(mGravity)<<", scaled with "<<forceFactor<<" to "<<mLatticeGravity,1);
- }
-
- if((checkSeenValues(PARAM_SURFACETENSION))&&(mSurfaceTension>0.0)) {
- ParamFloat massDelta = 1.0;
- ParamFloat densityStar = 1.0;
- massDelta = mDensity / densityStar *mCellSize*mCellSize*mCellSize;
- if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," massDelta = "<<massDelta, 10);
-
- mSurfaceTension = mSurfaceTension*mStepTime*mStepTime/massDelta;
- if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," surface tension = "<<mSurfaceTension<<" ",1);
+ ParamFloat forceFactor = (mTimestep *mTimestep)/mCellSize; // only used for printing...
+ if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," gravity force = "<<PRINT_NTLVEC(mcGravity.get(time))<<", scaled with "<<forceFactor<<" to "<<calculateGravity(time),1);
}
mExtent = ParamVec( mCellSize*mSizex, mCellSize*mSizey, mCellSize*mSizez );
- if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," domain extent = "<<PRINT_NTLVEC(mExtent)<<"m ",1);
+ if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," domain extent = "<<PRINT_NTLVEC(mExtent)<<"m , gs:"<<PRINT_VEC(mSizex,mSizey,mSizez)<<" cs:"<<mCellSize,1);
if(!checkSeenValues(PARAM_ANIFRAMETIME)) {
errFatal("Parametrizer::calculateAllMissingValues"," Warning no ani frame time given!", SIMWORLD_INITERROR);
- mAniFrameTime = mStepTime;
+ mAniFrameTime = mTimestep;
}
- //mAniFrameTime = mAniFrames * mStepTime;
- if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," ani frame steps = "<<calculateAniStepsPerFrame()<<" ", 1);
+ //mAniFrameTime = mAniFrames * mTimestep;
+ if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," ani frame steps = "<<calculateAniStepsPerFrame(mFrameNum)<<" for frame "<<mFrameNum, 1);
if((checkSeenValues(PARAM_ANISTART))&&(calculateAniStart()>0)) {
if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," ani start steps = "<<calculateAniStart()<<" ",1);
}
-
- // calculate reynolds number
- if(mViscosity>0.0) {
- ParamFloat reynoldsApprox = -1.0;
- ParamFloat gridSpeed = (maxSpeed*mCellSize/mStepTime);
- reynoldsApprox = (mDomainSize*gridSpeed) / mViscosity;
- if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," reynolds number (D="<<mDomainSize<<", assuming V="<<gridSpeed<<")= "<<reynoldsApprox<<" ", 1);
- }
if(!SIMWORLD_OK()) return false;
// everything ok
@@ -510,7 +472,59 @@ bool Parametrizer::calculateAllMissingValues( bool silent )
+// OLD interface stuff
+// reactivate at some point?
+
+ /*! surface tension, [kg/s^2] */
+ //ParamFloat mSurfaceTension;
+ /*! set starting time of the animation (renderer) */
+ //void setSurfaceTension(ParamFloat set) { mSurfaceTension = set; seenThis( PARAM_SURFACETENSION ); }
+ /*! get starting time of the animation (renderer) */
+ //ParamFloat getSurfaceTension( void ) { return mSurfaceTension; }
+ /*if((checkSeenValues(PARAM_SURFACETENSION))&&(mSurfaceTension>0.0)) {
+ ParamFloat massDelta = 1.0;
+ ParamFloat densityStar = 1.0;
+ massDelta = mDensity / densityStar *mCellSize*mCellSize*mCellSize;
+ if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," massDelta = "<<massDelta, 10);
+
+ mSurfaceTension = mSurfaceTension*mTimestep*mTimestep/massDelta;
+ if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," surface tension = "<<mSurfaceTension<<" ",1);
+ } // */
+
+// probably just delete:
+
+ /*! reynolds number (calculated from domain length and max. speed [dimensionless] */
+ //ParamFloat mReynolds;
+
+ /*! set relaxation time */
+ //void setRelaxTime(ParamFloat set) { mRelaxTime = set; seenThis( PARAM_RELAXTIME ); }
+ /*! get relaxation time */
+ //ParamFloat getRelaxTime( void ) { return mRelaxTime; }
+ /*! set reynolds number */
+ //void setReynolds(ParamFloat set) { mReynolds = set; seenThis( PARAM_REYNOLDS ); }
+ /*! get reynolds number */
+ //ParamFloat getReynolds( void ) { return mReynolds; }
+
+ // calculate reynolds number
+ /*if(mViscosity>0.0) {
+ ParamFloat maxSpeed = 1.0/6.0; // for rough reynolds approx
+ ParamFloat reynoldsApprox = -1.0;
+ ParamFloat gridSpeed = (maxSpeed*mCellSize/mTimestep);
+ reynoldsApprox = (mDomainSize*gridSpeed) / mViscosity;
+ if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," reynolds number (D="<<mDomainSize<<", assuming V="<<gridSpeed<<")= "<<reynoldsApprox<<" ", 1);
+ } // */
+
+ //? mRelaxTime = mpAttrs->readFloat("p_relaxtime",mRelaxTime, "Parametrizer","mRelaxTime", false);
+ //if(getAttributeList()->exists("p_relaxtime")) seenThis( PARAM_RELAXTIME );
+ //? mReynolds = mpAttrs->readFloat("p_reynolds",mReynolds, "Parametrizer","mReynolds", false);
+ //if(getAttributeList()->exists("p_reynolds")) seenThis( PARAM_REYNOLDS );
+
+ //mViscosity = mpAttrs->readFloat("p_viscosity",mViscosity, "Parametrizer","mViscosity", false);
+ //if(getAttributeList()->exists("p_viscosity") || (!mcViscosity.isInited()) ) { }
+ //if(getAttributeList()->exists("p_viscosity"))
+ //ParamFloat viscStar = calculateLatticeViscosity(time);
+ //RelaxTime = (6.0 * viscStar + 1) * 0.5;
diff --git a/intern/elbeem/intern/parametrizer.h b/intern/elbeem/intern/parametrizer.h
index 9140deefc0b..471fb571e35 100644
--- a/intern/elbeem/intern/parametrizer.h
+++ b/intern/elbeem/intern/parametrizer.h
@@ -32,7 +32,6 @@ typedef ntlVec3d ParamVec;
#define PARAM_ANISTART (1<<12)
#define PARAM_SURFACETENSION (1<<13)
#define PARAM_DENSITY (1<<14)
-#define PARAM_CELLSIZE (1<<15)
#define PARAM_GSTAR (1<<16)
#define PARAM_SIMMAXSPEED (1<<18)
#define PARAM_FLUIDVOLHEIGHT (1<<19)
@@ -58,9 +57,9 @@ class Parametrizer {
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 */
- bool calculateAllMissingValues( bool silent = false );
- bool oldCalculateAllMissingValues( void );
+ * 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; }
@@ -83,7 +82,9 @@ class Parametrizer {
/*! 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 num);
+ 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 */
@@ -91,17 +92,17 @@ class Parametrizer {
/* simple calulation functions */
/*! get omega for LBM */
- ParamFloat calculateOmega( ParamFloat t );
+ ParamFloat calculateOmega( double time );
/*! get no. of timesteps for LBM */
int calculateNoOfSteps( ParamFloat timelen );
/*! get external force x component */
- ParamVec calculateGravity( ParamFloat t );
+ 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 no of steps for a singel animation frame */
- int calculateAniStepsPerFrame( 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 */
@@ -111,7 +112,7 @@ class Parametrizer {
/*! calculate size of a single cell */
ParamFloat calculateCellSize(void);
/*! calculate the lattice viscosity */
- ParamFloat calculateLatticeViscosity(void);
+ ParamFloat calculateLatticeViscosity( double time );
/*! calculate lattice velocity from real world value [m/s] */
ParamVec calculateLattVelocityFromRw( ParamVec ivel );
@@ -119,23 +120,9 @@ class Parametrizer {
ParamVec calculateRwVelocityFromLatt( ParamVec ivel );
- /*! set relaxation time */
- void setRelaxTime(ParamFloat set) { mRelaxTime = set; seenThis( PARAM_RELAXTIME ); }
- /*! get relaxation time */
- ParamFloat getRelaxTime( void ) { return mRelaxTime; }
-
- /*! set reynolds number */
- void setReynolds(ParamFloat set) { mReynolds = set; seenThis( PARAM_REYNOLDS ); }
- /*! get reynolds number */
- ParamFloat getReynolds( void ) { return mReynolds; }
-
/*! set kinematic viscosity */
- void setViscosity(ParamFloat set) {
- mViscosity = set; seenThis( PARAM_VISCOSITY );
- mcViscosity = AnimChannel<ParamFloat>(mViscosity);
- }
- /*! get current kinematic viscosity (warning - this might change over time) */
- ParamFloat getViscosity( void ) { return mViscosity; }
+ void setViscosity(ParamFloat set) { mcViscosity = AnimChannel<ParamFloat>(set); seenThis( PARAM_VISCOSITY ); }
+ void initViscosityChannel(vector<ParamFloat> val, vector<double> time) { mcViscosity = AnimChannel<ParamFloat>(val,time); }
/*! set speed of sound */
void setSoundSpeed(ParamFloat set) { mSoundSpeed = set; seenThis( PARAM_SOUNDSPEED ); }
@@ -143,25 +130,21 @@ class Parametrizer {
ParamFloat getSoundSpeed( void ) { return mSoundSpeed; }
/*! set the external force */
- void setGravity(ParamFloat setx, ParamFloat sety, ParamFloat setz) {
- mGravity = ParamVec(setx,sety,setz); seenThis( PARAM_GRAVITY );
- mcGravity = AnimChannel<ParamVec>(mGravity);
- }
- void setGravity(ParamVec set) {
- mGravity = set; seenThis( PARAM_GRAVITY );
- mcGravity = AnimChannel<ParamVec>(mGravity);
- }
+ void setGravity(ParamFloat setx, ParamFloat sety, ParamFloat setz) { mcGravity = AnimChannel<ParamVec>(ParamVec(setx,sety,setz)); seenThis( PARAM_GRAVITY ); }
+ void setGravity(ParamVec set) { mcGravity = AnimChannel<ParamVec>(set); seenThis( PARAM_GRAVITY ); }
+ void initGravityChannel(vector<ParamVec> val, vector<double> time) { mcGravity = AnimChannel<ParamVec>(val,time); }
+ ParamVec getGravity(double time) { return mcGravity.get( time ); }
/*! set the length of a single time step */
- void setStepTime(ParamFloat set) { mStepTime = set; seenThis( PARAM_STEPTIME ); }
+ void setTimestep(ParamFloat set) { mTimestep = set; seenThis( PARAM_STEPTIME ); }
/*! get the length of a single time step */
- ParamFloat getStepTime( void);
+ ParamFloat getTimestep( void);
/*! set a desired step time for rescaling/adaptive timestepping */
- void setDesiredStepTime(ParamFloat set) { mDesiredStepTime = set; }
+ void setDesiredTimestep(ParamFloat set) { mDesiredTimestep = set; }
/*! get the length of a single time step */
- ParamFloat getMaxStepTime( void ) { return mMaxStepTime; }
+ ParamFloat getMaxTimestep( void ) { return mMaxTimestep; }
/*! get the length of a single time step */
- ParamFloat getMinStepTime( void ) { return mMinStepTime; }
+ ParamFloat getMinTimestep( void ) { return mMinTimestep; }
/*! set the time scaling factor */
void setTimeFactor(ParamFloat set) { mTimeFactor = set; seenThis( PARAM_TIMEFACTOR ); }
@@ -173,20 +156,15 @@ class Parametrizer {
void setSize(int i,int j, int k) { mSizex = i; mSizey = j; mSizez = k; seenThis( PARAM_SIZE ); }
/*! set time of an animation frame (renderer) */
- void setAniFrameTime(ParamFloat set) { mAniFrameTime = set; seenThis( PARAM_ANIFRAMETIME ); }
- /*! get time of an animation frame (renderer) */
- ParamFloat getAniFrameTime( void ) { return mAniFrameTime; }
+ //void setAniFrameTime(ParamFloat set) { mAniFrameTime = set; seenThis( PARAM_ANIFRAMETIME ); }
+ void setAniFrameTimeChannel(ParamFloat set) { mcAniFrameTime = AnimChannel<ParamFloat>(set); seenThis( PARAM_ANIFRAMETIME ); }
+ void initAniFrameTimeChannel(vector<ParamFloat> val, vector<double> time) { mcAniFrameTime = AnimChannel<ParamFloat>(val,time); seenThis( PARAM_ANIFRAMETIME ); }
/*! 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 starting time of the animation (renderer) */
- void setSurfaceTension(ParamFloat set) { mSurfaceTension = set; seenThis( PARAM_SURFACETENSION ); }
- /*! get starting time of the animation (renderer) */
- ParamFloat getSurfaceTension( void ) { return mSurfaceTension; }
-
/*! set fluid density */
void setDensity(ParamFloat set) { mDensity = set; seenThis( PARAM_DENSITY ); }
/*! get fluid density */
@@ -213,8 +191,8 @@ class Parametrizer {
/*! get the size of a single lbm cell */
ParamFloat getDomainSize( void ) { return mDomainSize; }
- /*! set the size of a single lbm cell */
- void setCellSize(ParamFloat set) { mCellSize = set; seenThis( PARAM_CELLSIZE ); }
+ /*! 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; }
@@ -246,9 +224,6 @@ class Parametrizer {
/*! get maximum allowed omega for time adaptivity */
int getTadapLevels( void ) { return mTadapLevels; }
- /*! get current gravity value (warning this might change over time!) */
- ParamVec getGravity( void ) { return mGravity; }
-
/*! set */
// void set(ParamFloat set) { m = set; seenThis( PARAM_ ); }
/*! get */
@@ -258,15 +233,7 @@ class Parametrizer {
private:
- /*! relaxation time [s] */
- ParamFloat mRelaxTime;
-
- /*! reynolds number (calculated from domain length and max. speed [dimensionless] */
- ParamFloat mReynolds;
-
/*! kinematic viscosity of the fluid [m^2/s] */
- ParamFloat mViscosity;
- /*! animated channel */
AnimChannel<ParamFloat> mcViscosity;
/*! speed of sound of the fluid [m/s] */
@@ -282,18 +249,14 @@ class Parametrizer {
ParamFloat mTimeStep;
/*! external force as acceleration [m/s^2] */
- ParamVec mGravity;
AnimChannel<ParamVec> mcGravity;
- /*! force converted to lattice units (returned by calc gravity) */
- ParamVec mLatticeGravity;
-
/*! length of one time step in the simulation */
- ParamFloat mStepTime;
+ ParamFloat mTimestep;
/*! desired step time for rescaling/adaptive timestepping, only regarded if >0.0, reset after usage */
- ParamFloat mDesiredStepTime;
+ ParamFloat mDesiredTimestep;
/*! minimal and maximal step times for current setup */
- ParamFloat mMaxStepTime, mMinStepTime;
+ ParamFloat mMaxTimestep, mMinTimestep;
/*! domain resoultion, the same values as in lbmsolver */
int mSizex, mSizey, mSizez;
@@ -302,9 +265,11 @@ class Parametrizer {
ParamFloat mTimeFactor;
/*! for renderer - length of an animation step [s] */
- ParamFloat mAniFrameTime;
- /*! animated channel */
AnimChannel<ParamFloat> mcAniFrameTime;
+ /*! current value for next frame */
+ ParamFloat mAniFrameTime;
+ /*! time step scaling factor for testing/debugging */
+ ParamFloat mTimeStepScale;
/*! for renderer - start time of the animation [s] */
ParamFloat mAniStart;
@@ -312,9 +277,6 @@ class Parametrizer {
/*! extent of the domain in meters */
ParamVec mExtent;
- /*! surface tension, [kg/s^2] */
- ParamFloat mSurfaceTension;
-
/*! fluid density [kg/m^3], default 1.0 g/cm^3 */
ParamFloat mDensity;
@@ -334,6 +296,8 @@ class Parametrizer {
/*! 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;
@@ -341,9 +305,6 @@ class Parametrizer {
/*! values that are calculated from the seen ones for this simulation */
int mCalculatedValues;
- /*! is the parametrizer active? */
- //bool mActive;
-
/*! pointer to the attribute list */
AttributeList *mpAttrs;
};
diff --git a/intern/elbeem/intern/particletracer.cpp b/intern/elbeem/intern/particletracer.cpp
index 1321edb19cc..0a5af90564a 100644
--- a/intern/elbeem/intern/particletracer.cpp
+++ b/intern/elbeem/intern/particletracer.cpp
@@ -15,7 +15,9 @@
#include "particletracer.h"
#include "ntl_matrices.h"
#include "ntl_ray.h"
-#include "ntl_scene.h"
+#include "ntl_matrices.h"
+
+#include <zlib.h>
@@ -24,24 +26,43 @@
*****************************************************************************/
ParticleTracer::ParticleTracer() :
ntlGeometryObject(),
- mParts(1),
- mNumParticles(0), mTrailLength(1), mTrailInterval(1),mTrailIntervalCounter(0),
- mPartSize(0.01), mTrailScale(1.0),
+ mParts(),
+ //mTrailLength(1), mTrailInterval(1),mTrailIntervalCounter(0),
+ mPartSize(0.01),
mStart(-1.0), mEnd(1.0),
mSimStart(-1.0), mSimEnd(1.0),
mPartScale(1.0) , mPartHeadDist( 0.5 ), mPartTailDist( -4.5 ), mPartSegments( 4 ),
mValueScale(0),
- mValueCutoffTop(0.0), mValueCutoffBottom(0.0)
+ mValueCutoffTop(0.0), mValueCutoffBottom(0.0),
+ mDumpParts(0), mShowOnly(0), mpTrafo(NULL)
{
+ // check env var
+#ifdef ELBEEM_PLUGIN
+ mDumpParts=1; // default on
+#endif // ELBEEM_PLUGIN
+ if(getenv("ELBEEM_DUMPPARTICLE")) { // DEBUG!
+ int set = atoi( getenv("ELBEEM_DUMPPARTICLE") );
+ if((set>=0)&&(set!=mDumpParts)) {
+ mDumpParts=set;
+ debMsgStd("ParticleTracer::notifyOfDump",DM_NOTIFY,"Using envvar ELBEEM_DUMPPARTICLE to set mDumpParts to "<<set<<","<<mDumpParts,8);
+ }
+ }
};
+ParticleTracer::~ParticleTracer() {
+ debMsgStd("ParticleTracer::~ParticleTracer",DM_MSG,"destroyed",10);
+}
+
/*****************************************************************************/
//! parse settings from attributes (dont use own list!)
/*****************************************************************************/
void ParticleTracer::parseAttrList(AttributeList *att)
{
- AttributeList *tempAtt = mpAttrs;
+ AttributeList *tempAtt = mpAttrs;
mpAttrs = att;
+ int mNumParticles =0; // UNUSED
+ int mTrailLength = 0; // UNUSED
+ int mTrailInterval= 0; // UNUSED
mNumParticles = mpAttrs->readInt("particles",mNumParticles, "ParticleTracer","mNumParticles", false);
mTrailLength = mpAttrs->readInt("traillength",mTrailLength, "ParticleTracer","mTrailLength", false);
mTrailInterval= mpAttrs->readInt("trailinterval",mTrailInterval, "ParticleTracer","mTrailInterval", false);
@@ -54,17 +75,18 @@ void ParticleTracer::parseAttrList(AttributeList *att)
mValueCutoffTop = mpAttrs->readFloat("part_valcutofftop",mValueCutoffTop, "ParticleTracer","mValueCutoffTop", false);
mValueCutoffBottom = mpAttrs->readFloat("part_valcutoffbottom",mValueCutoffBottom, "ParticleTracer","mValueCutoffBottom", false);
- mTrailScale = mpAttrs->readFloat("trail_scale",mTrailScale, "ParticleTracer","mTrailScale", false);
+ mDumpParts = mpAttrs->readInt ("part_dump",mDumpParts, "ParticleTracer","mDumpParts", false);
+ mShowOnly = mpAttrs->readInt ("part_showonly",mShowOnly, "ParticleTracer","mShowOnly", false);
string matPart;
matPart = mpAttrs->readString("material_part", "default", "ParticleTracer","material", false);
setMaterialName( matPart );
// trail length has to be at least one, if anything should be displayed
- if((mNumParticles>0)&&(mTrailLength<2)) mTrailLength = 2;
+ //if((mNumParticles>0)&&(mTrailLength<2)) mTrailLength = 2;
// restore old list
mpAttrs = tempAtt;
- mParts.resize(mTrailLength*mTrailInterval);
+ //mParts.resize(mTrailLength*mTrailInterval);
}
/******************************************************************************
@@ -74,38 +96,67 @@ void ParticleTracer::draw()
{
}
+/******************************************************************************
+ * init trafo matrix
+ *****************************************************************************/
+void ParticleTracer::initTrafoMatrix() {
+ ntlVec3Gfx scale = ntlVec3Gfx(
+ (mEnd[0]-mStart[0])/(mSimEnd[0]-mSimStart[0]),
+ (mEnd[1]-mStart[1])/(mSimEnd[1]-mSimStart[1]),
+ (mEnd[2]-mStart[2])/(mSimEnd[2]-mSimStart[2])
+ );
+ ntlVec3Gfx trans = mStart;
+ if(!mpTrafo) mpTrafo = new ntlMat4Gfx(0.0);
+ mpTrafo->initId();
+ for(int i=0; i<3; i++) { mpTrafo->value[i][i] = scale[i]; }
+ for(int i=0; i<3; i++) { mpTrafo->value[i][3] = trans[i]; }
+}
/******************************************************************************
- * set the number of timesteps to trace
+ * adapt time step by rescaling velocities
*****************************************************************************/
-void ParticleTracer::setTimesteps(int steps)
-{
- steps=0; // remove warning...
+void ParticleTracer::adaptPartTimestep(float factor) {
+ for(size_t i=0; i<mParts.size(); i++) {
+ mParts[i].setVel( mParts[i].getVel() * factor );
+ }
}
/******************************************************************************
* add a particle at this position
*****************************************************************************/
-void ParticleTracer::addParticle(double x, double y, double z)
+void ParticleTracer::addParticle(float x, float y, float z)
{
ntlVec3Gfx p(x,y,z);
ParticleObject part( p );
- //mParts[0].push_back( part );
+ //mParts.push_back( part );
// TODO handle other arrays?
//part.setActive( false );
- for(size_t l=0; l<mParts.size(); l++) {
+ mParts.push_back( part );
+ //for(size_t l=0; l<mParts.size(); l++) {
// add deactivated particles to other arrays
- mParts[l].push_back( part );
// deactivate further particles
- if(l>1) {
+ //if(l>1) {
//mParts[l][ mParts.size()-1 ].setActive( false );
- }
- }
+ //}
+ //}
}
+void ParticleTracer::cleanup() {
+ // cleanup
+ int last = (int)mParts.size()-1;
+ //for(vector<ParticleObject>::iterator pit= getParticlesBegin();pit!= getParticlesEnd(); pit++) {
+ for(int i=0; i<=last; i++) {
+ if( mParts[i].getActive()==false ) {
+ ParticleObject *p = &mParts[i];
+ ParticleObject *p2 = &mParts[last];
+ *p = *p2; last--; mParts.pop_back();
+ }
+ }
+}
+
/******************************************************************************
* save particle positions before adding a new timestep
* copy "one index up", newest has to remain unmodified, it will be
@@ -114,6 +165,7 @@ void ParticleTracer::addParticle(double x, double y, double z)
void ParticleTracer::savePreviousPositions()
{
//debugOut(" PARTS SIZE "<<mParts.size() ,10);
+ /*
if(mTrailIntervalCounter==0) {
//errMsg("spp"," PARTS SIZE "<<mParts.size() );
for(size_t l=mParts.size()-1; l>0; l--) {
@@ -131,9 +183,65 @@ void ParticleTracer::savePreviousPositions()
}
mTrailIntervalCounter++;
if(mTrailIntervalCounter>=mTrailInterval) mTrailIntervalCounter = 0;
+ UNUSED!? */
}
+/*! dump particles if desired */
+void ParticleTracer::notifyOfDump(int frameNr,char *frameNrStr,string outfilename) {
+ debMsgStd("ParticleTracer::notifyOfDump",DM_MSG,"obj:"<<this->getName()<<" frame:"<<frameNrStr, 10); // DEBUG
+
+ if(mDumpParts>0) {
+ // dump to binary file
+ std::ostringstream boutfilename("");
+ //boutfilename << ecrpath.str() << glob->getOutFilename() <<"_"<< this->getName() <<"_" << frameNrStr << ".obj";
+ //boutfilename << outfilename <<"_particles_"<< this->getName() <<"_" << frameNrStr<< ".gz";
+ boutfilename << outfilename <<"_particles_" << frameNrStr<< ".gz";
+ debMsgStd("ParticleTracer::notifyOfDump",DM_MSG,"B-Dumping: "<< this->getName()
+ <<", particles:"<<mParts.size()<<" "<< " to "<<boutfilename.str()<<" #"<<frameNr , 7);
+
+ // output to zipped file
+ gzFile gzf;
+ gzf = gzopen(boutfilename.str().c_str(), "wb1");
+ if(gzf) {
+ int numParts;
+ if(sizeof(numParts)!=4) { errMsg("ParticleTracer::notifyOfDump","Invalid int size"); return; }
+ // only dump active particles
+ numParts = 0;
+ for(size_t i=0; i<mParts.size(); i++) {
+ if(!mParts[i].getActive()) continue;
+ numParts++;
+ }
+ gzwrite(gzf, &numParts, sizeof(numParts));
+ for(size_t i=0; i<mParts.size(); i++) {
+ if(!mParts[i].getActive()) { continue; }
+ if(mParts[i].getLifeTime()<30) { continue; } //? CHECK
+ ParticleObject *p = &mParts[i];
+ int type = p->getType();
+ ntlVec3Gfx pos = p->getPos();
+ float size = p->getSize();
+
+ if(type&PART_FLOAT) { // WARNING same handling for dump!
+ // add one gridcell offset
+ //pos[2] += 1.0;
+ }
+ pos = (*mpTrafo) * pos;
+
+ ntlVec3Gfx v = p->getVel();
+ v[0] *= mpTrafo->value[0][0];
+ v[1] *= mpTrafo->value[1][1];
+ v[2] *= mpTrafo->value[2][2];
+ // FIXME check: pos = (*mpTrafo) * pos;
+ gzwrite(gzf, &type, sizeof(type));
+ gzwrite(gzf, &size, sizeof(size));
+ for(int j=0; j<3; j++) { gzwrite(gzf, &pos[j], sizeof(float)); }
+ for(int j=0; j<3; j++) { gzwrite(gzf, &v[j], sizeof(float)); }
+ }
+ gzclose( gzf );
+ }
+ } // dump?
+}
+
/******************************************************************************
@@ -143,45 +251,71 @@ void ParticleTracer::getTriangles( vector<ntlTriangle> *triangles,
vector<ntlVec3Gfx> *vertices,
vector<ntlVec3Gfx> *normals, int objectId )
{
-#ifdef ELBEEM_BLENDER
+#ifdef ELBEEM_PLUGIN
// suppress warnings...
vertices = NULL; triangles = NULL;
normals = NULL; objectId = 0;
-#else // ELBEEM_BLENDER
+#else // ELBEEM_PLUGIN
// currently not used in blender
+ objectId = 0; // remove, deprecated
+ if(mDumpParts>1) {
+ return; // only dump, no tri-gen
+ }
const bool debugParts = false;
int tris = 0;
gfxReal partNormSize = 0.01 * mPartScale;
- ntlVec3Gfx pScale = ntlVec3Gfx(
- (mEnd[0]-mStart[0])/(mSimEnd[0]-mSimStart[0]),
- (mEnd[1]-mStart[1])/(mSimEnd[1]-mSimStart[1]),
- (mEnd[2]-mStart[2])/(mSimEnd[2]-mSimStart[2])
- );
- if(debugParts) errMsg("DebugParts"," geo:"<< mSimStart<<","<<mEnd<<"; sim:"<<mSimStart<<","<<mSimEnd<<"; S "<<pScale );
- ntlVec3Gfx org = mStart;
int segments = mPartSegments;
- int lnewst = mTrailLength-1;
- int loldst = mTrailLength-2;
+ //int lnewst = mTrailLength-1;
+ // TODO get rid of mPart[X] array
+ //? int loldst = mTrailLength-2;
// trails gehen nicht so richtig mit der
// richtung der partikel...
- for(size_t i=0; i<mParts[lnewst].size(); i++) {
+ ntlVec3Gfx scale = ntlVec3Gfx( (mEnd[0]-mStart[0])/(mSimEnd[0]-mSimStart[0]), (mEnd[1]-mStart[1])/(mSimEnd[1]-mSimStart[1]), (mEnd[2]-mStart[2])/(mSimEnd[2]-mSimStart[2]));
+ ntlVec3Gfx trans = mStart;
+ for(size_t i=0; i<mParts.size(); i++) {
//mParts[0][i].setActive(true);
+ ParticleObject *p = &mParts[i];
- if( mParts[lnewst][i].getActive()==false ) continue;
- if( mParts[loldst][i].getActive()==false ) continue;
+ if(mShowOnly!=10) {
+ // 10=show only deleted
+ if( p->getActive()==false ) continue;
+ } else {
+ if( p->getActive()==true ) continue;
+ }
+ int type = p->getType();
+ if(mShowOnly>0) {
+ switch(mShowOnly) {
+ case 1: if(!(type&PART_BUBBLE)) continue; break;
+ case 2: if(!(type&PART_DROP)) continue; break;
+ case 3: if(!(type&PART_INTER)) continue; break;
+ case 4: if(!(type&PART_FLOAT)) continue; break;
+ }
+ } else {
+ // by default dont display inter
+ if(type&PART_INTER) continue;
+ }
+
+ ntlVec3Gfx pnew = p->getPos();
+ if(type&PART_FLOAT) { // WARNING same handling for dump!
+ // add one gridcell offset
+ //pnew[2] += 1.0;
+ }
- ntlVec3Gfx pnew = mParts[lnewst][i].getPos();
- ntlVec3Gfx pold = mParts[loldst][i].getPos();
- ntlVec3Gfx pdir = pnew - pold;
+ ntlVec3Gfx pdir = p->getVel();
gfxReal plen = normalize( pdir );
if( plen < 1e-05) pdir = ntlVec3Gfx(-1.0 ,0.0 ,0.0);
- ntlVec3Gfx p = org + pnew*pScale;
+ ntlVec3Gfx pos = (*mpTrafo) * pnew;
+ //ntlVec3Gfx pos = pnew; // T
+ //pos[0] = pos[0]*scale[0]+trans[0]; // T
+ //pos[1] = pos[1]*scale[1]+trans[1]; // T
+ //pos[2] = pos[2]*scale[2]+trans[2]; // T
gfxReal partsize = 0.0;
- if(debugParts) errMsg("DebugParts"," i"<<i<<" new"<<pnew<<" old"<<pold );
+ if(debugParts) errMsg("DebugParts"," i"<<i<<" new"<<pnew<<" vel"<<pdir<<" pos="<<pos );
+ //if(i==0 &&(debugParts)) errMsg("DebugParts"," i"<<i<<" new"<<pnew[0]<<" pos="<<pos[0]<<" scale="<<scale[0]<<" t="<<trans[0] );
// value length scaling?
if(mValueScale==1) {
@@ -194,6 +328,8 @@ void ParticleTracer::getTriangles( vector<ntlTriangle> *triangles,
} else {
partsize = mPartScale; // no length scaling
}
+ //if(type&(PART_DROP|PART_BUBBLE))
+ partsize *= p->getSize()/5.0;
ntlVec3Gfx pstart( mPartHeadDist *partsize, 0.0, 0.0 );
ntlVec3Gfx pend ( mPartTailDist *partsize, 0.0, 0.0 );
@@ -207,9 +343,9 @@ void ParticleTracer::getTriangles( vector<ntlTriangle> *triangles,
ntlVec3Gfx cv2 = ntlVec3Gfx(pdir[1], -pdir[0], 0.0);
ntlVec3Gfx cv3 = cross( cv1, cv2);
for(int l=0; l<3; l++) {
- cvmat.value[l][0] = cv1[l];
- cvmat.value[l][1] = cv2[l];
- cvmat.value[l][2] = cv3[l];
+ //? cvmat.value[l][0] = cv1[l];
+ //? cvmat.value[l][1] = cv2[l];
+ //? cvmat.value[l][2] = cv3[l];
}
pstart = (cvmat * pstart);
pend = (cvmat * pend);
@@ -231,10 +367,10 @@ void ParticleTracer::getTriangles( vector<ntlTriangle> *triangles,
p1 = (cvmat * p1);
p2 = (cvmat * p2);
- sceneAddTriangle( p+pstart, p+p1, p+p2,
- ns,n1,n2, ntlVec3Gfx(0.0), 1 );
- sceneAddTriangle( p+pend , p+p2, p+p1,
- ns,n2,n1, ntlVec3Gfx(0.0), 1 );
+ sceneAddTriangle( pos+pstart, pos+p1, pos+p2,
+ ns,n1,n2, ntlVec3Gfx(0.0), 1, triangles,vertices,normals );
+ sceneAddTriangle( pos+pend , pos+p2, pos+p1,
+ ns,n2,n1, ntlVec3Gfx(0.0), 1, triangles,vertices,normals );
phi += phiD;
tris += 2;
@@ -244,31 +380,7 @@ void ParticleTracer::getTriangles( vector<ntlTriangle> *triangles,
//} // trail
return; // DEBUG
-
- // add trails
- //double tScale = 0.01 * mPartScale * mTrailScale;
- double trails = 0.01 * mPartScale * mTrailScale;
- //for(int l=0; l<mParts.size()-1; l++) {
- for(int l=0; l<mTrailLength-2; l++) {
- for(size_t i=0; i<mParts[0].size(); i++) {
- int tl1 = l*mTrailInterval;
- int tl2 = (l+1)*mTrailInterval;
- if( mParts[tl1][i].getActive()==false ) continue;
- if( mParts[tl2][i].getActive()==false ) continue;
- ntlVec3Gfx p1 = org+mParts[tl1][i].getPos()*pScale;
- ntlVec3Gfx p2 = org+mParts[tl2][i].getPos()*pScale;
- ntlVec3Gfx n = ntlVec3Gfx(0,0,-1);
- sceneAddTriangle( p1+ntlVec3Gfx(0,trails,0), p1+ntlVec3Gfx(0,-trails,0), p2,
- n,n,n, ntlVec3Gfx(0.0), 1 );
- sceneAddTriangle( p2, p1+ntlVec3Gfx(0,-trails,0), p1+ntlVec3Gfx(0,trails,0),
- n,n,n, ntlVec3Gfx(0.0), 1 );
- tris += 2;
- }
- }
- debugOut("ParticleTracer::getTriangles "<<mName<<" : Triangulated "<< (mParts[0].size()) <<" particles (triangles: "<<tris<<") ", 10);
- //debugOut(" s"<<mStart<<" e"<<mEnd<<" ss"<<mSimStart<<" se"<<mSimEnd , 10);
-
-#endif // ELBEEM_BLENDER
+#endif // ELBEEM_PLUGIN
}
diff --git a/intern/elbeem/intern/particletracer.h b/intern/elbeem/intern/particletracer.h
index b5f5838d87f..b9179b68dc0 100644
--- a/intern/elbeem/intern/particletracer.h
+++ b/intern/elbeem/intern/particletracer.h
@@ -9,7 +9,18 @@
#ifndef NTL_PARTICLETRACER_H
#include "ntl_geometryobject.h"
+template<class Scalar> class ntlMatrix4x4;
+// particle types
+#define PART_BUBBLE (1<< 1)
+#define PART_DROP (1<< 2)
+#define PART_INTER (1<< 3)
+#define PART_FLOAT (1<< 4)
+
+// particle state
+#define PART_IN (1<< 8)
+#define PART_OUT (1<< 9)
+#define PART_INACTIVE (1<<10)
//! A single particle
class ParticleObject
@@ -17,24 +28,26 @@ class ParticleObject
public:
//! Standard constructor
inline ParticleObject(ntlVec3Gfx mp) :
- mPos(mp),mVel(0.0), mStatus(0), mActive( true ) { };
+ mPos(mp),mVel(0.0), mSize(1.0), mStatus(0),mLifeTime(0) { };
//! Copy constructor
inline ParticleObject(const ParticleObject &a) :
- mPos(a.mPos), mVel(a.mVel),
- mStatus(a.mStatus), mActive(a.mActive) { };
+ mPos(a.mPos), mVel(a.mVel), mSize(a.mSize),
+ mStatus(a.mStatus),
+ mLifeTime(a.mLifeTime) { };
//! Destructor
inline ~ParticleObject() { /* empty */ };
//! add vector to position
- inline void advance(double vx, double vy, double vz) {
+ inline void advance(float vx, float vy, float vz) {
mPos[0] += vx; mPos[1] += vy; mPos[2] += vz; }
//! advance with own velocity
inline void advanceVel() { mPos += mVel; }
//! add acceleration to velocity
inline void addToVel(ntlVec3Gfx acc) { mVel += acc; }
- //! get vector to position
+ //! get/set vector to position
inline ntlVec3Gfx getPos() { return mPos; }
+ inline void setPos(ntlVec3Gfx set) { mPos=set; }
//! set velocity
inline void setVel(ntlVec3Gfx set) { mVel = set; }
//! set velocity
@@ -42,14 +55,31 @@ class ParticleObject
//! get velocity
inline ntlVec3Gfx getVel() { return mVel; }
+ //! get/set size value
+ inline gfxReal getSize() { return mSize; }
+ inline void setSize(gfxReal set) { mSize=set; }
+
+ //! get whole flags
+ inline int getFlags() const { return mStatus; }
+ //! get status (higher byte)
+ inline int getStatus() const { return (mStatus&0xFF00); }
+ //! set status (higher byte)
+ inline void setStatus(int set) { mStatus = set|(mStatus&0x00FF); }
+ //! get type (lower byte)
+ inline int getType() const { return (mStatus&0x00FF); }
+ //! set type (lower byte)
+ inline void setType(int set) { mStatus = set|(mStatus&0xFF00); }
//! get active flag
- inline bool getActive() { return mActive; }
+ inline bool getActive() const { return ((mStatus&PART_INACTIVE)==0); }
//! set active flag
- inline void setActive(bool set) { mActive = set; }
- //! get status int
- inline int getStatus() { return mStatus; }
- //! setstatus int
- inline void setStatus(int set) { mStatus = set; }
+ inline void setActive(bool set) {
+ if(set) mStatus &= (~PART_INACTIVE);
+ else mStatus |= PART_INACTIVE;
+ }
+ //! get/set lifetime
+ inline int getLifeTime() const { return mLifeTime; }
+ //! set type (lower byte)
+ inline void setLifeTime(int set) { mLifeTime = set; }
protected:
@@ -57,11 +87,12 @@ class ParticleObject
ntlVec3Gfx mPos;
/*! the particle velocity */
ntlVec3Gfx mVel;
-
+ /*! size / mass of particle */
+ gfxReal mSize;
/*! particle status */
int mStatus;
- /*! particle active? */
- bool mActive;
+ /*! count survived time steps */
+ int mLifeTime;
};
@@ -73,10 +104,10 @@ class ParticleTracer :
//! Standard constructor
ParticleTracer();
//! Destructor
- ~ParticleTracer() { /* empty */ };
+ ~ParticleTracer();
//! add a particle at this position
- void addParticle(double x, double y, double z);
+ void addParticle(float x, float y, float z);
//! save particle positions before adding a new timestep
void savePreviousPositions();
@@ -87,78 +118,60 @@ class ParticleTracer :
//! parse settings from attributes (dont use own list!)
void parseAttrList( AttributeList *att );
+ //! adapt time step by rescaling velocities
+ void adaptPartTimestep(float factor);
// access funcs
- //! set the number of timesteps to trace
- void setTimesteps(int steps);
-
- //! set the number of particles
- inline void setNumParticles(int set) { mNumParticles = set; }
//! get the number of particles
- inline int getNumParticles() { return mNumParticles; }
-
- //! set the number of timesteps to trace
- inline void setTrailLength(int set) { mTrailLength = set; mParts.resize(mTrailLength*mTrailInterval); }
- //! get the number of timesteps to trace
- inline int getTrailLength() { return mTrailLength; }
- //! set the number of timesteps between each anim step saving
- inline void setTrailInterval(int set) { mTrailInterval = set; mParts.resize(mTrailLength*mTrailInterval); }
-
- //! get the no. of particles in the current array
- inline int getPartArraySize() { return mParts[0].size(); }
+ inline int getNumParticles() { return mParts.size(); }
//! iterate over all newest particles (for advancing positions)
- inline vector<ParticleObject>::iterator getParticlesBegin() { return mParts[0].begin(); }
+ inline vector<ParticleObject>::iterator getParticlesBegin() { return mParts.begin(); }
//! end iterator for newest particles
- inline vector<ParticleObject>::iterator getParticlesEnd() { return mParts[0].end(); }
+ inline vector<ParticleObject>::iterator getParticlesEnd() { return mParts.end(); }
//! end iterator for newest particles
- inline ParticleObject* getLast() { return &(mParts[0][ mParts[0].size()-1 ]); }
+ inline ParticleObject* getLast() { return &(mParts[ mParts.size()-1 ]); }
/*! set geometry start (for renderer) */
- inline void setStart(ntlVec3Gfx set) { mStart = set; }
+ inline void setStart(ntlVec3Gfx set) { mStart = set; initTrafoMatrix(); }
+ /*! set geometry end (for renderer) */
+ inline void setEnd(ntlVec3Gfx set) { mEnd = set; initTrafoMatrix(); }
+ /*! get values */
+ inline ntlVec3Gfx getStart() { return mStart; }
/*! set geometry end (for renderer) */
- inline void setEnd(ntlVec3Gfx set) { mEnd = set; }
+ inline ntlVec3Gfx getEnd() { return mEnd; }
/*! set simulation domain start */
- inline void setSimStart(ntlVec3Gfx set) { mSimStart = set; }
+ inline void setSimStart(ntlVec3Gfx set) { mSimStart = set; initTrafoMatrix(); }
/*! set simulation domain end */
- inline void setSimEnd(ntlVec3Gfx set) { mSimEnd = set; }
+ inline void setSimEnd(ntlVec3Gfx set) { mSimEnd = set; initTrafoMatrix(); }
+
+ /*! set/get dump flag */
+ inline void setDumpParts(bool set) { mDumpParts = set; }
+ inline bool getDumpParts() { return mDumpParts; }
//! set the particle scaling factor
- inline void setPartScale(double set) { mPartScale = set; }
- //! set the trail scaling factor
- inline void setTrailScale(double set) { mTrailScale = set; }
+ inline void setPartScale(float set) { mPartScale = set; }
// NTL geometry implementation
-
/*! Get the triangles from this object */
virtual void getTriangles( vector<ntlTriangle> *triangles,
vector<ntlVec3Gfx> *vertices,
vector<ntlVec3Gfx> *normals, int objectId );
+ virtual void notifyOfDump(int frameNr,char *frameNrStr,string outfilename);
+ // free deleted particles
+ void cleanup();
protected:
/*! the particle array (for multiple timesteps) */
- vector< vector<ParticleObject> > mParts;
-
- /*! desired number of particles */
- int mNumParticles;
-
- /*! number of particle positions to trace */
- int mTrailLength;
-
- /*! number of timesteps to between saving particle positions */
- int mTrailInterval;
- int mTrailIntervalCounter;
+ vector<ParticleObject> mParts;
/*! size of the particles to display */
- double mPartSize;
-
- /*! size of the particle trail */
- double mTrailScale;
+ float mPartSize;
/*! start and end vectors for the triangulation region to create particles in */
ntlVec3Gfx mStart, mEnd;
@@ -167,18 +180,28 @@ class ParticleTracer :
ntlVec3Gfx mSimStart, mSimEnd;
/*! scaling param for particles */
- double mPartScale;
+ float mPartScale;
/*! head and tail distance for particle shapes */
- double mPartHeadDist, mPartTailDist;
+ float mPartHeadDist, mPartTailDist;
/*! no of segments for particle cone */
int mPartSegments;
/*! use length/absval of values to scale particles? */
int mValueScale;
/*! value length maximal cutoff value, for mValueScale==2 */
- double mValueCutoffTop;
+ float mValueCutoffTop;
/*! value length minimal cutoff value, for mValueScale==2 */
- double mValueCutoffBottom;
+ float mValueCutoffBottom;
+
+ /*! dump particles (or certain types of) to disk? */
+ int mDumpParts;
+ /*! show only a certain type (debugging) */
+ int mShowOnly;
+
+ //! transform matrix
+ ntlMatrix4x4<gfxReal> *mpTrafo;
+ /*! init sim/pos transformation */
+ void initTrafoMatrix();
};
#define NTL_PARTICLETRACER_H
diff --git a/intern/elbeem/intern/simulation_object.cpp b/intern/elbeem/intern/simulation_object.cpp
index bec1e82ca21..481eb836ad6 100644
--- a/intern/elbeem/intern/simulation_object.cpp
+++ b/intern/elbeem/intern/simulation_object.cpp
@@ -8,9 +8,13 @@
*****************************************************************************/
#include "simulation_object.h"
+#include "solver_interface.h"
#include "ntl_bsptree.h"
-#include "ntl_scene.h"
+#include "ntl_ray.h"
+#include "ntl_world.h"
+#include "solver_interface.h"
#include "particletracer.h"
+#include "elbeem.h"
#ifdef _WIN32
#else
@@ -32,22 +36,15 @@ SimulationObject::SimulationObject() :
mpGlob(NULL),
mPanic( false ),
mDebugType( 1 /* =FLUIDDISPNothing*/ ),
- mSolverType("-"), mStepsPerFrame( 10 ),
- mpLbm(NULL),
- mpParam( NULL ),
+ mStepsPerFrame( 10 ),
+ mpLbm(NULL), mpParam( NULL ),
mShowSurface(true), mShowParticles(false),
mSelectedCid( NULL ),
+ mpElbeemSettings( NULL )
- stnOld("opt"),
- stnFsgr("fsgr")
{
mpParam = new Parametrizer();
-
- for(int i=0; i<MAX_DEBDISPSET; i++) {
- mDebDispSet[i].type = (i);
- mDebDispSet[i].on = false;
- mDebDispSet[i].scale = 1.0;
- }
+ //for(int i=0; i<MAX_DEBDISPSET; i++) { mDebDispSet[i].type = (i); mDebDispSet[i].on = false; mDebDispSet[i].scale = 1.0; }
// reset time
mTime = 0.0;
@@ -60,9 +57,10 @@ SimulationObject::SimulationObject() :
*****************************************************************************/
SimulationObject::~SimulationObject()
{
- if(mpGiTree != NULL) delete mpGiTree;
- delete mpLbm;
- delete mpParam;
+ if(mpGiTree) delete mpGiTree;
+ if(mpElbeemSettings) delete mpElbeemSettings;
+ if(mpLbm) delete mpLbm;
+ if(mpParam) delete mpParam;
debMsgStd("SimulationObject",DM_MSG,"El'Beem Done!\n",10);
}
@@ -77,7 +75,7 @@ void SimulationObject::initGeoTree(int id) {
return;
}
mGeoInitId = id;
- ntlScene *scene = mpGlob->getScene();
+ ntlScene *scene = mpGlob->getSimScene();
mpGiObjects = scene->getObjects();
if(mpGiTree != NULL) delete mpGiTree;
@@ -95,6 +93,11 @@ void SimulationObject::freeGeoTree() {
+// copy & remember settings for later use
+void SimulationObject::copyElbeemSettings(elbeemSimulationSettings *settings) {
+ mpElbeemSettings = new elbeemSimulationSettings;
+ *mpElbeemSettings = *settings;
+}
/******************************************************************************
* simluation interface: initialize simulation using the given configuration file
@@ -102,33 +105,34 @@ void SimulationObject::freeGeoTree() {
int SimulationObject::initializeLbmSimulation(ntlRenderGlobals *glob)
{
if(!SIMWORLD_OK()) return 1;
+
+ // already inited?
+ if(mpLbm) return 0;
+
mpGlob = glob;
if(!getVisible()) {
mpAttrs->setAllUsed();
return 0;
}
- //mDimension is deprecated
- mSolverType = mpAttrs->readString("solver", mSolverType, "SimulationObject","mSolverType", false );
- if(mSolverType == stnFsgr) {
- mpLbm = createSolver();
- } else if(mSolverType == stnOld) {
- errFatal("SimulationObject::initializeLbmSimulation","Invalid solver type - note that mDimension is deprecated, use the 'solver' keyword instead", SIMWORLD_INITERROR);
- return 1;
- }
+ //mDimension, mSolverType are deprecated
+ string mSolverType("");
+ mSolverType = mpAttrs->readString("solver", mSolverType, "SimulationObject","mSolverType", false );
+ //errFatal("SimulationObject::initializeLbmSimulation","Invalid solver type - note that mDimension is deprecated, use the 'solver' keyword instead", SIMWORLD_INITERROR); return 1;
+ mpLbm = createSolver();
/* check lbm pointer */
if(mpLbm == NULL) {
- errFatal("SimulationObject::initializeLbmSimulation","Unable to init dim"<<mSolverType<<" LBM solver! ", SIMWORLD_INITERROR);
+ errFatal("SimulationObject::initializeLbmSimulation","Unable to init LBM solver! ", SIMWORLD_INITERROR);
return 1;
}
- debugOut("SimulationObject::initialized "<< mpLbm->getIdString() <<" LBM solver! ", 2);
+ debMsgStd("SimulationObject::initialized",DM_MSG,"IdStr:"<<mpLbm->getIdString() <<" LBM solver! ", 2);
// for non-param simulations
mpLbm->setParametrizer( mpParam );
mpParam->setAttrList( getAttributeList() );
- // not needed.. done in solver_init: mpParam->setSize ...
+ // not needed.. done in solver_init: mpParam->setSize ... in solver_interface
mpParam->parseAttrList();
mpLbm->setAttrList( getAttributeList() );
@@ -152,6 +156,27 @@ int SimulationObject::initializeLbmSimulation(ntlRenderGlobals *glob)
mpLbm->setGeoEnd( mGeoEnd );
mpLbm->setRenderGlobals( mpGlob );
mpLbm->setName( getName() + "_lbm" );
+ if(mpElbeemSettings) {
+ // set further settings from API struct init
+ mpLbm->setSmoothing(1.0 * mpElbeemSettings->surfaceSmoothing, 1.0 * mpElbeemSettings->surfaceSmoothing);
+ mpLbm->setSizeX(mpElbeemSettings->resolutionxyz);
+ mpLbm->setSizeY(mpElbeemSettings->resolutionxyz);
+ mpLbm->setSizeZ(mpElbeemSettings->resolutionxyz);
+ mpLbm->setPreviewSize(mpElbeemSettings->previewresxyz);
+ mpLbm->setRefinementDesired(mpElbeemSettings->maxRefine);
+ mpLbm->setGenerateParticles(mpElbeemSettings->generateParticles);
+
+ string dinitType = std::string("no");
+ if (mpElbeemSettings->obstacleType==FLUIDSIM_OBSTACLE_PARTSLIP) dinitType = std::string("part");
+ else if(mpElbeemSettings->obstacleType==FLUIDSIM_OBSTACLE_FREESLIP) dinitType = std::string("free");
+ else /*if(mpElbeemSettings->obstacleType==FLUIDSIM_OBSTACLE_NOSLIP)*/ dinitType = std::string("no");
+ mpLbm->setDomainBound(dinitType);
+ mpLbm->setDomainPartSlip(mpElbeemSettings->obstaclePartslip);
+ mpLbm->setDumpVelocities(mpElbeemSettings->generateVertexVectors);
+ debMsgStd("SimulationObject::initialize",DM_MSG,"Added domain bound: "<<dinitType<<" ps="<<mpElbeemSettings->obstaclePartslip<<" vv"<<mpElbeemSettings->generateVertexVectors<<","<<mpLbm->getDumpVelocities(), 9 );
+
+ debMsgStd("SimulationObject::initialize",DM_MSG,"Set ElbeemSettings values "<<mpLbm->getGenerateParticles(),10);
+ }
mpLbm->initializeSolver();
// print cell type stats
@@ -175,7 +200,7 @@ int SimulationObject::initializeLbmSimulation(ntlRenderGlobals *glob)
}
mpLbm->deleteCellIterator( &cid );
-#if ELBEEM_BLENDER!=1
+#if ELBEEM_PLUGIN!=1
char charNl = '\n';
debugOutNnl("SimulationObject::initializeLbmSimulation celltype stats: " <<charNl, 5);
debugOutNnl("no. of cells = "<<totalCells<<", "<<charNl ,5);
@@ -199,12 +224,18 @@ int SimulationObject::initializeLbmSimulation(ntlRenderGlobals *glob)
out<<"\tFractions: [empty/bnd - fluid - interface - ext. if] = [" << ebFrac<<" - " << flFrac<<" - " << ifFrac<<"] "<< charNl;
if(diffInits > 0) {
- debugOut("SimulationObject::initializeLbmSimulation celltype Warning: Diffinits="<<diffInits<<" !!!!!!!!!" , 5);
+ debMsgStd("SimulationObject::initializeLbmSimulation",DM_MSG,"celltype Warning: Diffinits="<<diffInits<<" !!!!!!!!!" , 5);
}
debugOutNnl(out.str(), 5);
}
-#endif // ELBEEM_BLENDER==1
+#endif // ELBEEM_PLUGIN==1
+ // might be modified by mpLbm
+ mpParts->setStart( mGeoStart );
+ mpParts->setEnd( mGeoEnd );
+ mpParts->setCastShadows( false );
+ mpParts->setReceiveShadows( false );
+ mpParts->searchMaterial( glob->getMaterials() );
mpLbm->initParticles(mpParts);
// this has to be inited here - before, the values might be unknown
@@ -218,12 +249,19 @@ int SimulationObject::initializeLbmSimulation(ntlRenderGlobals *glob)
if(mShowSurface) mObjects.push_back( surf );
}
- mpParts->setStart( mGeoStart );
- mpParts->setEnd( mGeoEnd );
- mpParts->setCastShadows( false );
- mpParts->setReceiveShadows( false );
- mpParts->searchMaterial( glob->getMaterials() );
- if(mShowParticles) mObjects.push_back(mpParts);
+#ifdef ELBEEM_PLUGIN
+ mShowParticles=1;
+#endif // ELBEEM_PLUGIN
+ //if(getenv("ELBEEM_DUMPPARTICLE")) { // DEBUG ENABLE!!!!!!!!!!
+ if(mpLbm->getGenerateParticles()>0.0) {
+ mShowParticles=1;
+ mpParts->setDumpParts(true);
+ }
+ //debMsgStd("SimulationObject::init",DM_NOTIFY,"Using envvar ELBEEM_DUMPPARTICLE to set mShowParticles, DEBUG!",1);
+ //} // DEBUG ENABLE!!!!!!!!!!
+ if(mShowParticles) {
+ mObjects.push_back(mpParts);
+ }
// add objects to display for debugging (e.g. levelset particles)
vector<ntlGeometryObject *> debugObjs = mpLbm->getDebugObjects();
@@ -247,17 +285,17 @@ void SimulationObject::setFrameNum(int num) {
*****************************************************************************/
void SimulationObject::step( void )
{
- if(mpParam->getAniFrameTime()>0.0) {
+ if(mpParam->getCurrentAniFrameTime()>0.0) {
// dont advance for stopped time
mpLbm->step();
mpParts->savePreviousPositions();
mpLbm->advanceParticles(mpParts);
- mTime += mpParam->getStepTime();
+ mTime += mpParam->getTimestep();
}
if(mpLbm->getPanic()) mPanic = true;
- //debMsgStd("SimulationObject::step",DM_MSG," Sim '"<<mName<<"' stepped to "<<mTime<<" (stept="<<(mpParam->getStepTime())<<", framet="<<getFrameTime()<<") ", 10);
+ //debMsgStd("SimulationObject::step",DM_MSG," Sim '"<<mName<<"' stepped to "<<mTime<<" (stept="<<(mpParam->getTimestep())<<", framet="<<getFrameTime()<<") ", 10);
}
/*! prepare visualization of simulation for e.g. raytracing */
void SimulationObject::prepareVisualization( void ) {
@@ -273,12 +311,12 @@ double SimulationObject::getStartTime( void ) {
return mpParam->getAniStart();
}
/* get time for a single animation frame */
-double SimulationObject::getFrameTime( void ) {
- return mpParam->getAniFrameTime();
+double SimulationObject::getFrameTime( int frame ) {
+ return mpParam->getAniFrameTime(frame);
}
/* get time for a single time step */
-double SimulationObject::getStepTime( void ) {
- return mpParam->getStepTime();
+double SimulationObject::getTimestep( void ) {
+ return mpParam->getTimestep();
}
@@ -307,17 +345,12 @@ SimulationObject::getObjectsEnd()
void SimulationObject::drawDebugDisplay() {
#ifndef NOGUI
- //debugOut(" SD: "<<mDebugType<<" v"<<getVisible()<<" don"<< (mDebDispSet[mDebugType].on) , 10);
if(!getVisible()) return;
- if( mDebugType > (MAX_DEBDISPSET-1) ){
- errFatal("SimulationObject::drawDebugDisplay","Invalid debug type!", SIMWORLD_GENERICERROR);
- return;
- }
-
- mDebDispSet[ mDebugType ].on = true;
+ //if( mDebugType > (MAX_DEBDISPSET-1) ){ errFatal("SimulationObject::drawDebugDisplay","Invalid debug type!", SIMWORLD_GENERICERROR); return; }
+ //mDebDispSet[ mDebugType ].on = true;
//errorOut( mDebugType <<"//"<< mDebDispSet[mDebugType].type );
- mpLbm->debugDisplay( &mDebDispSet[ mDebugType ] );
+ mpLbm->debugDisplay( mDebugType );
//::lbmMarkedCellDisplay<>( mpLbm );
mpLbm->lbmMarkedCellDisplay();
@@ -331,7 +364,7 @@ void SimulationObject::drawInteractiveDisplay()
if(!getVisible()) return;
if(mSelectedCid) {
// in debugDisplayNode if dispset is on is ignored...
- mpLbm->debugDisplayNode( &mDebDispSet[ FLUIDDISPGrid ], mSelectedCid );
+ mpLbm->debugDisplayNode( FLUIDDISPGrid, mSelectedCid );
}
#endif
}
@@ -365,4 +398,9 @@ void SimulationObject::setMouseClick()
}
}
+/*! notify object that dump is in progress (e.g. for field dump) */
+void SimulationObject::notifyShaderOfDump(int frameNr,char *frameNrStr,string outfilename) {
+ if(!mpLbm) return;
+ mpLbm->notifySolverOfDump(frameNr,frameNrStr,outfilename);
+}
diff --git a/intern/elbeem/intern/simulation_object.h b/intern/elbeem/intern/simulation_object.h
index 3105a494661..4e7bc19294d 100644
--- a/intern/elbeem/intern/simulation_object.h
+++ b/intern/elbeem/intern/simulation_object.h
@@ -13,13 +13,15 @@
#define USE_GLUTILITIES
#include "ntl_geometryshader.h"
-#include "solver_interface.h"
#include "parametrizer.h"
+class LbmSolverInterface;
+class CellIdentifierInterface;
class ntlTree;
class ntlRenderGlobals;
class ntlRenderGlobals;
class ParticleTracer;
+struct elbeemSimulationSettings;
//! type fluid geometry init
@@ -48,6 +50,8 @@ class SimulationObject :
SimulationObject();
/*! Destructor */
virtual ~SimulationObject();
+ /*! for init from API */
+ void copyElbeemSettings(elbeemSimulationSettings *settings);
/*! init tree for certain geometry init */
@@ -86,6 +90,8 @@ class SimulationObject :
/*! Do geo etc. init */
virtual int postGeoConstrInit(ntlRenderGlobals *glob) { return initializeLbmSimulation(glob); };
virtual int initializeShader() { /* ... */ return true; };
+ /*! notify object that dump is in progress (e.g. for field dump) */
+ virtual void notifyShaderOfDump(int frameNr,char *frameNrStr,string outfilename);
/*! simluation interface: draw the simulation with OpenGL */
virtual void draw( void ) {};
virtual vector<ntlGeometryObject *>::iterator getObjectsBegin();
@@ -97,13 +103,6 @@ class SimulationObject :
/*! prepare visualization of simulation for e.g. raytracing */
virtual void prepareVisualization( void );
- /*! get current start simulation time */
- virtual double getStartTime( void );
- /*! get time for a single animation frame */
- virtual double getFrameTime( void );
- /*! get time for a single time step in the simulation */
- virtual double getStepTime( void );
-
/*! GUI - display debug info */
virtual void drawDebugDisplay();
/*! GUI - display interactive info */
@@ -112,6 +111,13 @@ class SimulationObject :
virtual void setMousePos(int x,int y, ntlVec3Gfx org, ntlVec3Gfx dir);
virtual void setMouseClick();
+ /*! get current start simulation time */
+ double getStartTime( void );
+ /*! get time for a single animation frame */
+ double getFrameTime( int frame );
+ /*! get time for a single time step in the simulation */
+ double getTimestep( void );
+
//! access solver
LbmSolverInterface *getSolver(){ return mpLbm; }
@@ -143,7 +149,6 @@ class SimulationObject :
//! dimension of the simulation - now given by LBM-DIM define globally
//! solver type
- string mSolverType;
/*! when no parametrizer, use this as no. of steps per frame */
int mStepsPerFrame;
@@ -165,24 +170,21 @@ class SimulationObject :
bool mShowParticles;
/*! debug display settings */
-#ifndef USE_MSVC6FIXES
- static const int MAX_DEBDISPSET = 10;
-#else
- // so this is a known and documented MSVC6 bug
- // work around
- enum {MAX_DEBDISPSET = 10};
-#endif
- fluidDispSettings mDebDispSet[ MAX_DEBDISPSET ];
+ int mDebDispSetting;
/*! pointer to identifier of selected node */
CellIdentifierInterface *mSelectedCid;
+ /*! storage of API settings */
+ elbeemSimulationSettings *mpElbeemSettings;
+
public:
// debug display setting funtions
/*! set type of info to display */
inline void setDebugDisplay(int disp) { mDebugType = disp; }
+ inline int getDebugDisplay() { return mDebugType; }
/* miscelleanous access functions */
@@ -198,10 +200,6 @@ class SimulationObject :
virtual inline ntlVec3Gfx *getBBStart() { return &mGeoStart; }
virtual inline ntlVec3Gfx *getBBEnd() { return &mGeoEnd; }
- /*! solver dimension constants */
- const string stnOld;
- const string stnFsgr;
-
};
diff --git a/intern/elbeem/intern/solver_class.h b/intern/elbeem/intern/solver_class.h
index 98c1882d79c..7217964e7ba 100644
--- a/intern/elbeem/intern/solver_class.h
+++ b/intern/elbeem/intern/solver_class.h
@@ -15,7 +15,7 @@
#include "utilities.h"
#include "solver_interface.h"
-#include "ntl_scene.h"
+#include "ntl_ray.h"
#include <stdio.h>
#if PARALLEL==1
@@ -25,22 +25,14 @@
#define PARALLEL 0
#endif // PARALLEL
-#ifndef LBMMODEL_DEFINED
-// force compiler error!
-ERROR - define model first!
-#endif // LBMMODEL_DEFINED
-
// general solver setting defines
-// default to 3dim
-#ifndef LBMDIM
-#define LBMDIM 3
-#endif // LBMDIM
-
-
//! debug coordinate accesses and the like? (much slower)
+// might be enabled by compilation
+#ifndef FSGR_STRICT_DEBUG
#define FSGR_STRICT_DEBUG 0
+#endif // FSGR_STRICT_DEBUG
//! debug coordinate accesses and the like? (much slower)
#define FSGR_OMEGA_DEBUG 0
@@ -81,6 +73,7 @@ ERROR - define model first!
#define FSGR_MAXNOOFLEVELS 5
// enable/disable fine grid compression for finest level
+// make sure this is same as useGridComp in calculateMemreqEstimate
#if LBMDIM==3
#define COMPRESSGRIDS 1
#else
@@ -113,15 +106,14 @@ ERROR - define model first!
#endif
#endif
-#if ELBEEM_BLENDER!=1
+#if LBM_INCLUDE_TESTSOLVERS==1
#include "solver_test.h"
-#endif // ELBEEM_BLENDER==1
+#endif // LBM_INCLUDE_TESTSOLVERS==1
/*****************************************************************************/
/*! cell access classes */
-template<typename D>
class UniformFsgrCellIdentifier :
- public CellIdentifierInterface
+ public CellIdentifierInterface , public LbmCellContents
{
public:
//! which grid level?
@@ -137,14 +129,13 @@ class UniformFsgrCellIdentifier :
virtual string getAsString() {
std::ostringstream ret;
ret <<"{ i"<<x<<",j"<<y;
- if(D::cDimension>2) ret<<",k"<<z;
+ if(LBMDIM>2) ret<<",k"<<z;
ret <<" }";
return ret.str();
}
virtual bool equal(CellIdentifierInterface* other) {
- //UniformFsgrCellIdentifier<D> *cid = dynamic_cast<UniformFsgrCellIdentifier<D> *>( other );
- UniformFsgrCellIdentifier<D> *cid = (UniformFsgrCellIdentifier<D> *)( other );
+ UniformFsgrCellIdentifier *cid = (UniformFsgrCellIdentifier *)( other );
if(!cid) return false;
if( x==cid->x && y==cid->y && z==cid->z && level==cid->level ) return true;
return false;
@@ -165,7 +156,7 @@ public:
//! size this level was advanced to
LbmFloat time;
//! size of a single lbm step in time units on this level
- LbmFloat stepsize;
+ LbmFloat timestep;
//! step count
int lsteps;
//! gravity force for this level
@@ -203,9 +194,8 @@ public:
/*****************************************************************************/
/*! class for solving a LBM problem */
-template<class D>
class LbmFsgrSolver :
- public D // this means, the solver is a lbmData object and implements the lbmInterface
+ public LbmSolverInterface // this means, the solver is a lbmData object and implements the lbmInterface
{
public:
@@ -213,26 +203,23 @@ class LbmFsgrSolver :
LbmFsgrSolver();
//! Destructor
virtual ~LbmFsgrSolver();
- //! id string of solver
- virtual string getIdString();
- //! dimension of solver
- virtual int getDimension();
//! initilize variables fom attribute list
virtual void parseAttrList();
//! Initialize omegas and forces on all levels (for init/timestep change)
void initLevelOmegas();
//! finish the init with config file values (allocate arrays...)
- virtual bool initializeSolver(); //( ntlTree* /*tree*/, vector<ntlGeometryObject*>* /*objects*/ );
+ virtual bool initializeSolver();
+ //! notify object that dump is in progress (e.g. for field dump)
+ virtual void notifySolverOfDump(int frameNr,char *frameNrStr,string outfilename);
#if LBM_USE_GUI==1
//! show simulation info (implement LbmSolverInterface pure virtual func)
- virtual void debugDisplay(fluidDispSettings *set);
+ virtual void debugDisplay(int set);
#endif
-
// implement CellIterator<UniformFsgrCellIdentifier> interface
- typedef UniformFsgrCellIdentifier<typename D::LbmCellContents> stdCellId;
+ typedef UniformFsgrCellIdentifier stdCellId;
virtual CellIdentifierInterface* getFirstCell( );
virtual void advanceCell( CellIdentifierInterface* );
virtual bool noEndCell( CellIdentifierInterface* );
@@ -249,7 +236,7 @@ class LbmFsgrSolver :
virtual LbmFloat getCellFill ( CellIdentifierInterface* ,int set);
virtual CellFlagType getCellFlag ( CellIdentifierInterface* ,int set);
virtual LbmFloat getEquilDf ( int );
- virtual int getDfNum ( );
+ virtual ntlVec3Gfx getVelocityAt (float x, float y, float z);
// convert pointers
stdCellId* convertBaseCidToStdCid( CellIdentifierInterface* basecid);
@@ -264,6 +251,8 @@ class LbmFsgrSolver :
LBM_INLINED void initEmptyCell(int level, int i,int j,int k, CellFlagType flag, LbmFloat rho, LbmFloat mass);
LBM_INLINED void initVelocityCell(int level, int i,int j,int k, CellFlagType flag, LbmFloat rho, LbmFloat mass, LbmVec vel);
LBM_INLINED void changeFlag(int level, int xx,int yy,int zz,int set,CellFlagType newflag);
+ //! interpolate velocity and density at a given position
+ void interpolateCellValues(int level,int ei,int ej,int ek,int workSet, LbmFloat &retrho, LbmFloat &retux, LbmFloat &retuy, LbmFloat &retuz);
/*! perform a single LBM step */
void stepMain();
@@ -288,8 +277,8 @@ class LbmFsgrSolver :
// gui/output debugging functions
#if LBM_USE_GUI==1
- virtual void debugDisplayNode(fluidDispSettings *dispset, CellIdentifierInterface* cell );
- virtual void lbmDebugDisplay(fluidDispSettings *dispset);
+ virtual void debugDisplayNode(int dispset, CellIdentifierInterface* cell );
+ virtual void lbmDebugDisplay(int dispset);
virtual void lbmMarkedCellDisplay();
#endif // LBM_USE_GUI==1
virtual void debugPrintNodeInfo(CellIdentifierInterface* cell, int forceSet=-1);
@@ -298,7 +287,7 @@ class LbmFsgrSolver :
void prepareVisualization( void );
/*! type for cells */
- typedef typename D::LbmCell LbmCell;
+ //typedef typename this->LbmCell LbmCell;
protected:
@@ -311,6 +300,8 @@ class LbmFsgrSolver :
void adaptTimestep();
//! init mObjectSpeeds for current parametrization
void recalculateObjectSpeeds();
+ //! init moving obstacles for next sim step sim
+ void initMovingObstacles(bool staticInit);
//! flag reinit step - always works on finest grid!
void reinitFlags( int workSet );
//! mass dist weights
@@ -347,10 +338,6 @@ class LbmFsgrSolver :
//! use time adaptivity?
bool mTimeAdap;
- //! domain boundary free/no slip type
- string mDomainBound;
- //! part slip value for domain
- LbmFloat mDomainPartSlipValue;
//! fluid vol height
LbmFloat mFVHeight;
@@ -364,12 +351,17 @@ class LbmFsgrSolver :
//! smoother surface initialization?
int mInitSurfaceSmoothing;
+ //! lock time step down switching
int mTimestepReduceLock;
+ //! count no. of switches
int mTimeSwitchCounts;
+ // only switch of maxvel is higher for several steps...
+ int mTimeMaxvelStepCnt;
+
//! total simulation time so far
- LbmFloat mSimulationTime;
+ LbmFloat mSimulationTime, mLastSimTime;
//! smallest and largest step size so far
- LbmFloat mMinStepTime, mMaxStepTime;
+ LbmFloat mMinTimestep, mMaxTimestep;
//! track max. velocity
LbmFloat mMxvx, mMxvy, mMxvz, mMaxVlen;
@@ -442,17 +434,10 @@ class LbmFsgrSolver :
int mDisableStandingFluidInit;
//! debug function to force tadap syncing
int mForceTadapRefine;
-
-#ifndef ELBEEM_BLENDER
- // test functions
- bool mUseTestdata;
- LbmTestdata *mpTest;
- void initTestdata();
- void destroyTestdata();
- void handleTestdata();
- void exportTestdata();
+ //! border cutoff value
+ int mCutoff;
+ //! store particle tracer
ParticleTracer *mpParticles;
-#endif // ELBEEM_BLENDER==1
// strict debug interface
# if FSGR_STRICT_DEBUG==1
@@ -467,8 +452,226 @@ class LbmFsgrSolver :
LbmFloat* debRACPNT(int level, int ii,int ij,int ik, int is );
LbmFloat& debRAC(LbmFloat* s,int l);
# endif // FSGR_STRICT_DEBUG==1
+
+ bool mUseTestdata;
+#if LBM_INCLUDE_TESTSOLVERS==1
+ // test functions
+ LbmTestdata *mpTest;
+ void initTestdata();
+ void destroyTestdata();
+ void handleTestdata();
+ void exportTestdata();
+ void set3dHeight(int ,int );
+ public:
+ // needed from testdata
+ void find3dHeight(int i,int j, LbmFloat prev, LbmFloat &ret, LbmFloat &retux, LbmFloat &retuy);
+#endif // LBM_INCLUDE_TESTSOLVERS==1
+
+ public: // former LbmModelLBGK functions
+ // relaxation funtions - implemented together with relax macros
+ static inline LbmFloat getVelVecLen(int l, LbmFloat ux,LbmFloat uy,LbmFloat uz);
+ static inline LbmFloat getCollideEq(int l, LbmFloat rho, LbmFloat ux, LbmFloat uy, LbmFloat uz);
+ inline LbmFloat getLesNoneqTensorCoeff( LbmFloat df[], LbmFloat feq[] );
+ inline LbmFloat getLesOmega(LbmFloat omega, LbmFloat csmago, LbmFloat Qo);
+ inline void collideArrays( int i, int j, int k, // position - more for debugging
+ LbmFloat df[], LbmFloat &outrho, // out only!
+ // velocity modifiers (returns actual velocity!)
+ LbmFloat &mux, LbmFloat &muy, LbmFloat &muz, LbmFloat omega, LbmFloat csmago, LbmFloat *newOmegaRet, LbmFloat *newQoRet);
+
+
+ // former LBM models
+ public:
+
+//! shorten static const definitions
+#define STCON static const
+
+#if LBMDIM==3
+
+ //! id string of solver
+ virtual string getIdString() { return string("FreeSurfaceFsgrSolver[BGK_D3Q19]"); }
+
+ //! how many dimensions? UNUSED? replace by LBMDIM?
+ STCON int cDimension;
+
+ // Wi factors for collide step
+ STCON LbmFloat cCollenZero;
+ STCON LbmFloat cCollenOne;
+ STCON LbmFloat cCollenSqrtTwo;
+
+ //! threshold value for filled/emptied cells
+ STCON LbmFloat cMagicNr2;
+ STCON LbmFloat cMagicNr2Neg;
+ STCON LbmFloat cMagicNr;
+ STCON LbmFloat cMagicNrNeg;
+
+ //! size of a single set of distribution functions
+ STCON int cDfNum;
+ //! direction vector contain vecs for all spatial dirs, even if not used for LBM model
+ STCON int cDirNum;
+
+ //! distribution functions directions
+ typedef enum {
+ cDirInv= -1,
+ cDirC = 0,
+ cDirN = 1,
+ cDirS = 2,
+ cDirE = 3,
+ cDirW = 4,
+ cDirT = 5,
+ cDirB = 6,
+ cDirNE = 7,
+ cDirNW = 8,
+ cDirSE = 9,
+ cDirSW = 10,
+ cDirNT = 11,
+ cDirNB = 12,
+ cDirST = 13,
+ cDirSB = 14,
+ cDirET = 15,
+ cDirEB = 16,
+ cDirWT = 17,
+ cDirWB = 18
+ } dfDir;
+
+ /* Vector Order 3D:
+ * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
+ * 0, 0, 0, 1,-1, 0, 0, 1,-1, 1,-1, 0, 0, 0, 0, 1, 1,-1,-1, 1,-1, 1,-1, 1,-1, 1,-1
+ * 0, 1,-1, 0, 0, 0, 0, 1, 1,-1,-1, 1, 1,-1,-1, 0, 0, 0, 0, 1, 1,-1,-1, 1, 1,-1,-1
+ * 0, 0, 0, 0, 0, 1,-1, 0, 0, 0, 0, 1,-1, 1,-1, 1,-1, 1,-1, 1, 1, 1, 1, -1,-1,-1,-1
+ */
+
+ /*! name of the dist. function
+ only for nicer output */
+ STCON char* dfString[ 19 ];
+
+ /*! index of normal dist func, not used so far?... */
+ STCON int dfNorm[ 19 ];
+
+ /*! index of inverse dist func, not fast, but useful... */
+ STCON int dfInv[ 19 ];
+
+ /*! index of x reflected dist func for free slip, not valid for all DFs... */
+ STCON int dfRefX[ 19 ];
+ /*! index of x reflected dist func for free slip, not valid for all DFs... */
+ STCON int dfRefY[ 19 ];
+ /*! index of x reflected dist func for free slip, not valid for all DFs... */
+ STCON int dfRefZ[ 19 ];
+
+ /*! dist func vectors */
+ STCON int dfVecX[ 27 ];
+ STCON int dfVecY[ 27 ];
+ STCON int dfVecZ[ 27 ];
+
+ /*! arrays as before with doubles */
+ STCON LbmFloat dfDvecX[ 27 ];
+ STCON LbmFloat dfDvecY[ 27 ];
+ STCON LbmFloat dfDvecZ[ 27 ];
+
+ /*! principal directions */
+ STCON int princDirX[ 2*3 ];
+ STCON int princDirY[ 2*3 ];
+ STCON int princDirZ[ 2*3 ];
+
+ /*! vector lengths */
+ STCON LbmFloat dfLength[ 19 ];
+
+ /*! equilibrium distribution functions, precalculated = getCollideEq(i, 0,0,0,0) */
+ static LbmFloat dfEquil[ 19 ];
+
+ /*! arrays for les model coefficients */
+ static LbmFloat lesCoeffDiag[ (3-1)*(3-1) ][ 27 ];
+ static LbmFloat lesCoeffOffdiag[ 3 ][ 27 ];
+
+#else // end LBMDIM==3 , LBMDIM==2
+
+ //! id string of solver
+ virtual string getIdString() { return string("FreeSurfaceFsgrSolver[BGK_D2Q9]"); }
+
+ //! how many dimensions?
+ STCON int cDimension;
+
+ //! Wi factors for collide step
+ STCON LbmFloat cCollenZero;
+ STCON LbmFloat cCollenOne;
+ STCON LbmFloat cCollenSqrtTwo;
+
+ //! threshold value for filled/emptied cells
+ STCON LbmFloat cMagicNr2;
+ STCON LbmFloat cMagicNr2Neg;
+ STCON LbmFloat cMagicNr;
+ STCON LbmFloat cMagicNrNeg;
+
+ //! size of a single set of distribution functions
+ STCON int cDfNum;
+ STCON int cDirNum;
+
+ //! distribution functions directions
+ typedef enum {
+ cDirInv= -1,
+ cDirC = 0,
+ cDirN = 1,
+ cDirS = 2,
+ cDirE = 3,
+ cDirW = 4,
+ cDirNE = 5,
+ cDirNW = 6,
+ cDirSE = 7,
+ cDirSW = 8
+ } dfDir;
+
+ /* Vector Order 2D:
+ * 0 1 2 3 4 5 6 7 8
+ * 0, 0,0, 1,-1, 1,-1,1,-1
+ * 0, 1,-1, 0,0, 1,1,-1,-1 */
+
+ /* name of the dist. function
+ only for nicer output */
+ STCON char* dfString[ 9 ];
+
+ /* index of normal dist func, not used so far?... */
+ STCON int dfNorm[ 9 ];
+
+ /* index of inverse dist func, not fast, but useful... */
+ STCON int dfInv[ 9 ];
+
+ /* index of x reflected dist func for free slip, not valid for all DFs... */
+ STCON int dfRefX[ 9 ];
+ /* index of x reflected dist func for free slip, not valid for all DFs... */
+ STCON int dfRefY[ 9 ];
+ /* index of x reflected dist func for free slip, not valid for all DFs... */
+ STCON int dfRefZ[ 9 ];
+
+ /* dist func vectors */
+ STCON int dfVecX[ 9 ];
+ STCON int dfVecY[ 9 ];
+ /* Z, 2D values are all 0! */
+ STCON int dfVecZ[ 9 ];
+
+ /* arrays as before with doubles */
+ STCON LbmFloat dfDvecX[ 9 ];
+ STCON LbmFloat dfDvecY[ 9 ];
+ /* Z, 2D values are all 0! */
+ STCON LbmFloat dfDvecZ[ 9 ];
+
+ /*! principal directions */
+ STCON int princDirX[ 2*2 ];
+ STCON int princDirY[ 2*2 ];
+ STCON int princDirZ[ 2*2 ];
+
+ /* vector lengths */
+ STCON LbmFloat dfLength[ 9 ];
+
+ /* equilibrium distribution functions, precalculated = getCollideEq(i, 0,0,0,0) */
+ static LbmFloat dfEquil[ 9 ];
+
+ /*! arrays for les model coefficients */
+ static LbmFloat lesCoeffDiag[ (2-1)*(2-1) ][ 9 ];
+ static LbmFloat lesCoeffOffdiag[ 2 ][ 9 ];
+
+#endif // LBMDIM==2
};
+#undef STCON
/*****************************************************************************/
@@ -479,7 +682,7 @@ class LbmFsgrSolver :
// cell mark debugging
#if FSGR_STRICT_DEBUG==10
#define debugMarkCell(lev,x,y,z) \
- errMsg("debugMarkCell",D::mName<<" step: "<<D::mStepCnt<<" lev:"<<(lev)<<" marking "<<PRINT_VEC((x),(y),(z))<<" line "<< __LINE__ ); \
+ errMsg("debugMarkCell",this->mName<<" step: "<<this->mStepCnt<<" lev:"<<(lev)<<" marking "<<PRINT_VEC((x),(y),(z))<<" line "<< __LINE__ ); \
debugMarkCellCall((lev),(x),(y),(z));
#else // FSGR_STRICT_DEBUG==1
#define debugMarkCell(lev,x,y,z) \
@@ -494,8 +697,8 @@ class LbmFsgrSolver :
//! flag array acces macro
#define _RFLAG(level,xx,yy,zz,set) mLevel[level].mprsFlags[set][ LBMGI((level),(xx),(yy),(zz),(set)) ]
-#define _RFLAG_NB(level,xx,yy,zz,set, dir) mLevel[level].mprsFlags[set][ LBMGI((level),(xx)+D::dfVecX[dir],(yy)+D::dfVecY[dir],(zz)+D::dfVecZ[dir],set) ]
-#define _RFLAG_NBINV(level,xx,yy,zz,set, dir) mLevel[level].mprsFlags[set][ LBMGI((level),(xx)+D::dfVecX[D::dfInv[dir]],(yy)+D::dfVecY[D::dfInv[dir]],(zz)+D::dfVecZ[D::dfInv[dir]],set) ]
+#define _RFLAG_NB(level,xx,yy,zz,set, dir) mLevel[level].mprsFlags[set][ LBMGI((level),(xx)+this->dfVecX[dir],(yy)+this->dfVecY[dir],(zz)+this->dfVecZ[dir],set) ]
+#define _RFLAG_NBINV(level,xx,yy,zz,set, dir) mLevel[level].mprsFlags[set][ LBMGI((level),(xx)+this->dfVecX[this->dfInv[dir]],(yy)+this->dfVecY[this->dfInv[dir]],(zz)+this->dfVecZ[this->dfInv[dir]],set) ]
// array data layouts
// standard array layout -----------------------------------------------------------------------------------------------
@@ -503,8 +706,8 @@ class LbmFsgrSolver :
//#define _LBMQI(level, ii,ij,ik, is, lunused) ( ((is)*mLevel[level].lOffsz) + (mLevel[level].lOffsy*(ik)) + (mLevel[level].lOffsx*(ij)) + (ii) )
#define _LBMQI(level, ii,ij,ik, is, lunused) ( (mLevel[level].lOffsy*(ik)) + (mLevel[level].lOffsx*(ij)) + (ii) )
#define _QCELL(level,xx,yy,zz,set,l) (mLevel[level].mprsCells[(set)][ LBMQI((level),(xx),(yy),(zz),(set), l)*dTotalNum +(l)])
-#define _QCELL_NB(level,xx,yy,zz,set, dir,l) (mLevel[level].mprsCells[(set)][ LBMQI((level),(xx)+D::dfVecX[dir],(yy)+D::dfVecY[dir],(zz)+D::dfVecZ[dir],set, l)*dTotalNum +(l)])
-#define _QCELL_NBINV(level,xx,yy,zz,set, dir,l) (mLevel[level].mprsCells[(set)][ LBMQI((level),(xx)+D::dfVecX[D::dfInv[dir]],(yy)+D::dfVecY[D::dfInv[dir]],(zz)+D::dfVecZ[D::dfInv[dir]],set, l)*dTotalNum +(l)])
+#define _QCELL_NB(level,xx,yy,zz,set, dir,l) (mLevel[level].mprsCells[(set)][ LBMQI((level),(xx)+this->dfVecX[dir],(yy)+this->dfVecY[dir],(zz)+this->dfVecZ[dir],set, l)*dTotalNum +(l)])
+#define _QCELL_NBINV(level,xx,yy,zz,set, dir,l) (mLevel[level].mprsCells[(set)][ LBMQI((level),(xx)+this->dfVecX[this->dfInv[dir]],(yy)+this->dfVecY[this->dfInv[dir]],(zz)+this->dfVecZ[this->dfInv[dir]],set, l)*dTotalNum +(l)])
#define QCELLSTEP dTotalNum
#define _RACPNT(level, ii,ij,ik, is ) &QCELL(level,ii,ij,ik,is,0)
@@ -555,7 +758,6 @@ class LbmFsgrSolver :
#define dNW 6
#define dSE 7
#define dSW 8
-#define LBM_DFNUM 9
#else
// direction indices
#define dC 0
@@ -577,12 +779,11 @@ class LbmFsgrSolver :
#define dEB 16
#define dWT 17
#define dWB 18
-#define LBM_DFNUM 19
#endif
//? #define dWB 18
// default init for dFlux values
-#define FLUX_INIT 0.5f * (float)(D::cDfNum)
+#define FLUX_INIT 0.5f * (float)(this->cDfNum)
// only for non DF dir handling!
#define dNET 19
@@ -617,24 +818,44 @@ class LbmFsgrSolver :
+/******************************************************************************/
+/*! equilibrium functions */
+/******************************************************************************/
+
+/*! calculate length of velocity vector */
+inline LbmFloat LbmFsgrSolver::getVelVecLen(int l, LbmFloat ux,LbmFloat uy,LbmFloat uz) {
+ return ((ux)*dfDvecX[l]+(uy)*dfDvecY[l]+(uz)*dfDvecZ[l]);
+};
+
+/*! calculate equilibrium DF for given values */
+inline LbmFloat LbmFsgrSolver::getCollideEq(int l, LbmFloat rho, LbmFloat ux, LbmFloat uy, LbmFloat uz) {
+#if FSGR_STRICT_DEBUG==1
+ if((l<0)||(l>LBM_DFNUM)) { errFatal("LbmFsgrSolver::getCollideEq","Invalid DFEQ call "<<l, SIMWORLD_PANIC ); /* no access to mPanic here */ }
+#endif // FSGR_STRICT_DEBUG==1
+ LbmFloat tmp = getVelVecLen(l,ux,uy,uz);
+ return( dfLength[l] *(
+ + rho - (3.0/2.0*(ux*ux + uy*uy + uz*uz))
+ + 3.0 *tmp
+ + 9.0/2.0 *(tmp*tmp) )
+ );
+};
+
/*****************************************************************************/
/* init a given cell with flag, density, mass and equilibrium dist. funcs */
-template<class D>
-void LbmFsgrSolver<D>::changeFlag(int level, int xx,int yy,int zz,int set,CellFlagType newflag) {
+void LbmFsgrSolver::changeFlag(int level, int xx,int yy,int zz,int set,CellFlagType newflag) {
CellFlagType pers = RFLAG(level,xx,yy,zz,set) & CFPersistMask;
RFLAG(level,xx,yy,zz,set) = newflag | pers;
}
-template<class D>
void
-LbmFsgrSolver<D>::initEmptyCell(int level, int i,int j,int k, CellFlagType flag, LbmFloat rho, LbmFloat mass) {
+LbmFsgrSolver::initEmptyCell(int level, int i,int j,int k, CellFlagType flag, LbmFloat rho, LbmFloat mass) {
/* init eq. dist funcs */
LbmFloat *ecel;
int workSet = mLevel[level].setCurr;
ecel = RACPNT(level, i,j,k, workSet);
- FORDF0 { RAC(ecel, l) = D::dfEquil[l] * rho; }
+ FORDF0 { RAC(ecel, l) = this->dfEquil[l] * rho; }
RAC(ecel, dMass) = mass;
RAC(ecel, dFfrac) = mass/rho;
RAC(ecel, dFlux) = FLUX_INIT;
@@ -646,14 +867,13 @@ LbmFsgrSolver<D>::initEmptyCell(int level, int i,int j,int k, CellFlagType flag,
return;
}
-template<class D>
void
-LbmFsgrSolver<D>::initVelocityCell(int level, int i,int j,int k, CellFlagType flag, LbmFloat rho, LbmFloat mass, LbmVec vel) {
+LbmFsgrSolver::initVelocityCell(int level, int i,int j,int k, CellFlagType flag, LbmFloat rho, LbmFloat mass, LbmVec vel) {
LbmFloat *ecel;
int workSet = mLevel[level].setCurr;
ecel = RACPNT(level, i,j,k, workSet);
- FORDF0 { RAC(ecel, l) = D::getCollideEq(l, rho,vel[0],vel[1],vel[2]); }
+ FORDF0 { RAC(ecel, l) = getCollideEq(l, rho,vel[0],vel[1],vel[2]); }
RAC(ecel, dMass) = mass;
RAC(ecel, dFfrac) = mass/rho;
RAC(ecel, dFlux) = FLUX_INIT;
@@ -665,24 +885,20 @@ LbmFsgrSolver<D>::initVelocityCell(int level, int i,int j,int k, CellFlagType fl
return;
}
-template<class D>
-int LbmFsgrSolver<D>::getForZMinBnd() {
+int LbmFsgrSolver::getForZMinBnd() {
return 0;
}
-template<class D>
-int LbmFsgrSolver<D>::getForZMin1() {
- if(D::cDimension==2) return 0;
+int LbmFsgrSolver::getForZMin1() {
+ if(LBMDIM==2) return 0;
return 1;
}
-template<class D>
-int LbmFsgrSolver<D>::getForZMaxBnd(int lev) {
- if(D::cDimension==2) return 1;
+int LbmFsgrSolver::getForZMaxBnd(int lev) {
+ if(LBMDIM==2) return 1;
return mLevel[lev].lSizez -0;
}
-template<class D>
-int LbmFsgrSolver<D>::getForZMax1(int lev) {
- if(D::cDimension==2) return 1;
+int LbmFsgrSolver::getForZMax1(int lev) {
+ if(LBMDIM==2) return 1;
return mLevel[lev].lSizez -1;
}
diff --git a/intern/elbeem/intern/solver_dimenions.h b/intern/elbeem/intern/solver_dimenions.h
deleted file mode 100644
index 04f9eb5c125..00000000000
--- a/intern/elbeem/intern/solver_dimenions.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/******************************************************************************
- *
- * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method
- * 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 2003-2005 Nils Thuerey
- *
- * Combined 2D/3D Lattice Boltzmann Solver auxiliary classes
- *
- *****************************************************************************/
-#ifndef LBMHEADER_H
-
-/* LBM Files */
-#include "solver_interface.h"
-
-
-#define LBMHEADER_H
-#endif
-
-
-
diff --git a/intern/elbeem/intern/solver_init.cpp b/intern/elbeem/intern/solver_init.cpp
index a138ad19ca8..44b24264caf 100644
--- a/intern/elbeem/intern/solver_init.cpp
+++ b/intern/elbeem/intern/solver_init.cpp
@@ -7,30 +7,302 @@
*
*****************************************************************************/
-#if ((!defined(__APPLE_CC__)) && (!defined(__INTEL_COMPILER))) || defined(LBM_FORCEINCLUDE)
+
#include "solver_class.h"
#include "solver_relax.h"
-
// for geo init FGI_ defines
#include "elbeem.h"
+/*****************************************************************************/
+//! common variables
+
+/*****************************************************************************/
+/*! 3D implementation D3Q19 */
+#if LBMDIM==3
+
+ //! how many dimensions?
+ const int LbmFsgrSolver::cDimension = 3;
+
+ // Wi factors for collide step
+ const LbmFloat LbmFsgrSolver::cCollenZero = (1.0/3.0);
+ const LbmFloat LbmFsgrSolver::cCollenOne = (1.0/18.0);
+ const LbmFloat LbmFsgrSolver::cCollenSqrtTwo = (1.0/36.0);
+
+ //! threshold value for filled/emptied cells
+ const LbmFloat LbmFsgrSolver::cMagicNr2 = 1.0005;
+ const LbmFloat LbmFsgrSolver::cMagicNr2Neg = -0.0005;
+ const LbmFloat LbmFsgrSolver::cMagicNr = 1.010001;
+ const LbmFloat LbmFsgrSolver::cMagicNrNeg = -0.010001;
+
+ //! size of a single set of distribution functions
+ const int LbmFsgrSolver::cDfNum = 19;
+ //! direction vector contain vecs for all spatial dirs, even if not used for LBM model
+ const int LbmFsgrSolver::cDirNum = 27;
+
+ //const string LbmFsgrSolver::dfString[ cDfNum ] = {
+ const char* LbmFsgrSolver::dfString[ cDfNum ] = {
+ " C", " N"," S"," E"," W"," T"," B",
+ "NE","NW","SE","SW",
+ "NT","NB","ST","SB",
+ "ET","EB","WT","WB"
+ };
+
+ const int LbmFsgrSolver::dfNorm[ cDfNum ] = {
+ cDirC, cDirN, cDirS, cDirE, cDirW, cDirT, cDirB,
+ cDirNE, cDirNW, cDirSE, cDirSW,
+ cDirNT, cDirNB, cDirST, cDirSB,
+ cDirET, cDirEB, cDirWT, cDirWB
+ };
+
+ const int LbmFsgrSolver::dfInv[ cDfNum ] = {
+ cDirC, cDirS, cDirN, cDirW, cDirE, cDirB, cDirT,
+ cDirSW, cDirSE, cDirNW, cDirNE,
+ cDirSB, cDirST, cDirNB, cDirNT,
+ cDirWB, cDirWT, cDirEB, cDirET
+ };
+
+ const int LbmFsgrSolver::dfRefX[ cDfNum ] = {
+ 0, 0, 0, 0, 0, 0, 0,
+ cDirSE, cDirSW, cDirNE, cDirNW,
+ 0, 0, 0, 0,
+ cDirEB, cDirET, cDirWB, cDirWT
+ };
+
+ const int LbmFsgrSolver::dfRefY[ cDfNum ] = {
+ 0, 0, 0, 0, 0, 0, 0,
+ cDirNW, cDirNE, cDirSW, cDirSE,
+ cDirNB, cDirNT, cDirSB, cDirST,
+ 0, 0, 0, 0
+ };
+
+ const int LbmFsgrSolver::dfRefZ[ cDfNum ] = {
+ 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ cDirST, cDirSB, cDirNT, cDirNB,
+ cDirWT, cDirWB, cDirET, cDirEB
+ };
+
+ // Vector Order 3D:
+ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
+ // 0, 0, 0, 1,-1, 0, 0, 1,-1, 1,-1, 0, 0, 0, 0, 1, 1,-1,-1, 1,-1, 1,-1, 1,-1, 1,-1
+ // 0, 1,-1, 0, 0, 0, 0, 1, 1,-1,-1, 1, 1,-1,-1, 0, 0, 0, 0, 1, 1,-1,-1, 1, 1,-1,-1
+ // 0, 0, 0, 0, 0, 1,-1, 0, 0, 0, 0, 1,-1, 1,-1, 1,-1, 1,-1, 1, 1, 1, 1, -1,-1,-1,-1
+
+ const int LbmFsgrSolver::dfVecX[ cDirNum ] = {
+ 0, 0,0, 1,-1, 0,0,
+ 1,-1,1,-1,
+ 0,0,0,0,
+ 1,1,-1,-1,
+ 1,-1, 1,-1,
+ 1,-1, 1,-1,
+ };
+ const int LbmFsgrSolver::dfVecY[ cDirNum ] = {
+ 0, 1,-1, 0,0,0,0,
+ 1,1,-1,-1,
+ 1,1,-1,-1,
+ 0,0,0,0,
+ 1, 1,-1,-1,
+ 1, 1,-1,-1
+ };
+ const int LbmFsgrSolver::dfVecZ[ cDirNum ] = {
+ 0, 0,0,0,0,1,-1,
+ 0,0,0,0,
+ 1,-1,1,-1,
+ 1,-1,1,-1,
+ 1, 1, 1, 1,
+ -1,-1,-1,-1
+ };
+
+ const LbmFloat LbmFsgrSolver::dfDvecX[ cDirNum ] = {
+ 0, 0,0, 1,-1, 0,0,
+ 1,-1,1,-1,
+ 0,0,0,0,
+ 1,1,-1,-1,
+ 1,-1, 1,-1,
+ 1,-1, 1,-1
+ };
+ const LbmFloat LbmFsgrSolver::dfDvecY[ cDirNum ] = {
+ 0, 1,-1, 0,0,0,0,
+ 1,1,-1,-1,
+ 1,1,-1,-1,
+ 0,0,0,0,
+ 1, 1,-1,-1,
+ 1, 1,-1,-1
+ };
+ const LbmFloat LbmFsgrSolver::dfDvecZ[ cDirNum ] = {
+ 0, 0,0,0,0,1,-1,
+ 0,0,0,0,
+ 1,-1,1,-1,
+ 1,-1,1,-1,
+ 1, 1, 1, 1,
+ -1,-1,-1,-1
+ };
+
+ /* principal directions */
+ const int LbmFsgrSolver::princDirX[ 2*LbmFsgrSolver::cDimension ] = {
+ 1,-1, 0,0, 0,0
+ };
+ const int LbmFsgrSolver::princDirY[ 2*LbmFsgrSolver::cDimension ] = {
+ 0,0, 1,-1, 0,0
+ };
+ const int LbmFsgrSolver::princDirZ[ 2*LbmFsgrSolver::cDimension ] = {
+ 0,0, 0,0, 1,-1
+ };
+
+ /*! arrays for les model coefficients, inited in lbmsolver constructor */
+ LbmFloat LbmFsgrSolver::lesCoeffDiag[ (cDimension-1)*(cDimension-1) ][ cDirNum ];
+ LbmFloat LbmFsgrSolver::lesCoeffOffdiag[ cDimension ][ cDirNum ];
+
+
+ const LbmFloat LbmFsgrSolver::dfLength[ cDfNum ]= {
+ cCollenZero,
+ cCollenOne, cCollenOne, cCollenOne,
+ cCollenOne, cCollenOne, cCollenOne,
+ cCollenSqrtTwo, cCollenSqrtTwo, cCollenSqrtTwo, cCollenSqrtTwo,
+ cCollenSqrtTwo, cCollenSqrtTwo, cCollenSqrtTwo, cCollenSqrtTwo,
+ cCollenSqrtTwo, cCollenSqrtTwo, cCollenSqrtTwo, cCollenSqrtTwo
+ };
+
+ /* precalculated equilibrium dfs, inited in lbmsolver constructor */
+ LbmFloat LbmFsgrSolver::dfEquil[ cDfNum ];
+
+#else // end LBMDIM==3 , LBMDIM==2
+
+/*****************************************************************************/
+/*! 2D implementation D2Q9 */
+
+ //! how many dimensions?
+ const int LbmFsgrSolver::cDimension = 2;
+
+ //! Wi factors for collide step
+ const LbmFloat LbmFsgrSolver::cCollenZero = (4.0/9.0);
+ const LbmFloat LbmFsgrSolver::cCollenOne = (1.0/9.0);
+ const LbmFloat LbmFsgrSolver::cCollenSqrtTwo = (1.0/36.0);
+
+ //! threshold value for filled/emptied cells
+ const LbmFloat LbmFsgrSolver::cMagicNr2 = 1.0005;
+ const LbmFloat LbmFsgrSolver::cMagicNr2Neg = -0.0005;
+ const LbmFloat LbmFsgrSolver::cMagicNr = 1.010001;
+ const LbmFloat LbmFsgrSolver::cMagicNrNeg = -0.010001;
+
+ //! size of a single set of distribution functions
+ const int LbmFsgrSolver::cDfNum = 9;
+ const int LbmFsgrSolver::cDirNum = 9;
+
+ //const string LbmFsgrSolver::dfString[ cDfNum ] = {
+ const char* LbmFsgrSolver::dfString[ cDfNum ] = {
+ " C",
+ " N", " S", " E", " W",
+ "NE", "NW", "SE","SW"
+ };
+
+ const int LbmFsgrSolver::dfNorm[ cDfNum ] = {
+ cDirC,
+ cDirN, cDirS, cDirE, cDirW,
+ cDirNE, cDirNW, cDirSE, cDirSW
+ };
+
+ const int LbmFsgrSolver::dfInv[ cDfNum ] = {
+ cDirC,
+ cDirS, cDirN, cDirW, cDirE,
+ cDirSW, cDirSE, cDirNW, cDirNE
+ };
+
+ const int LbmFsgrSolver::dfRefX[ cDfNum ] = {
+ 0,
+ 0, 0, 0, 0,
+ cDirSE, cDirSW, cDirNE, cDirNW
+ };
+
+ const int LbmFsgrSolver::dfRefY[ cDfNum ] = {
+ 0,
+ 0, 0, 0, 0,
+ cDirNW, cDirNE, cDirSW, cDirSE
+ };
+
+ const int LbmFsgrSolver::dfRefZ[ cDfNum ] = {
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0
+ };
+
+ // Vector Order 2D:
+ // 0 1 2 3 4 5 6 7 8
+ // 0, 0,0, 1,-1, 1,-1,1,-1
+ // 0, 1,-1, 0,0, 1,1,-1,-1
+
+ const int LbmFsgrSolver::dfVecX[ cDirNum ] = {
+ 0,
+ 0,0, 1,-1,
+ 1,-1,1,-1
+ };
+ const int LbmFsgrSolver::dfVecY[ cDirNum ] = {
+ 0,
+ 1,-1, 0,0,
+ 1,1,-1,-1
+ };
+ const int LbmFsgrSolver::dfVecZ[ cDirNum ] = {
+ 0, 0,0,0,0, 0,0,0,0
+ };
+
+ const LbmFloat LbmFsgrSolver::dfDvecX[ cDirNum ] = {
+ 0,
+ 0,0, 1,-1,
+ 1,-1,1,-1
+ };
+ const LbmFloat LbmFsgrSolver::dfDvecY[ cDirNum ] = {
+ 0,
+ 1,-1, 0,0,
+ 1,1,-1,-1
+ };
+ const LbmFloat LbmFsgrSolver::dfDvecZ[ cDirNum ] = {
+ 0, 0,0,0,0, 0,0,0,0
+ };
+
+ const int LbmFsgrSolver::princDirX[ 2*LbmFsgrSolver::cDimension ] = {
+ 1,-1, 0,0
+ };
+ const int LbmFsgrSolver::princDirY[ 2*LbmFsgrSolver::cDimension ] = {
+ 0,0, 1,-1
+ };
+ const int LbmFsgrSolver::princDirZ[ 2*LbmFsgrSolver::cDimension ] = {
+ 0,0, 0,0
+ };
+
+
+ /*! arrays for les model coefficients, inited in lbmsolver constructor */
+ LbmFloat LbmFsgrSolver::lesCoeffDiag[ (cDimension-1)*(cDimension-1) ][ cDirNum ];
+ LbmFloat LbmFsgrSolver::lesCoeffOffdiag[ cDimension ][ cDirNum ];
+
+
+ const LbmFloat LbmFsgrSolver::dfLength[ cDfNum ]= {
+ cCollenZero,
+ cCollenOne, cCollenOne, cCollenOne, cCollenOne,
+ cCollenSqrtTwo, cCollenSqrtTwo, cCollenSqrtTwo, cCollenSqrtTwo
+ };
+
+ /* precalculated equilibrium dfs, inited in lbmsolver constructor */
+ LbmFloat LbmFsgrSolver::dfEquil[ cDfNum ];
+
+// D2Q9 end
+#endif // LBMDIM==2
+
+
/******************************************************************************
* Lbm Constructor
*****************************************************************************/
-template<class D>
-LbmFsgrSolver<D>::LbmFsgrSolver() :
- D(),
+LbmFsgrSolver::LbmFsgrSolver() :
+ //D(),
mCurrentMass(0.0), mCurrentVolume(0.0),
mNumProblems(0),
mAvgMLSUPS(0.0), mAvgMLSUPSCnt(0.0),
mpPreviewSurface(NULL),
- mTimeAdap(true), mDomainBound("noslip"), mDomainPartSlipValue(0.1),
+ mTimeAdap(true),
mFVHeight(0.0), mFVArea(1.0), mUpdateFVHeight(false),
mInitSurfaceSmoothing(0),
mTimestepReduceLock(0),
- mTimeSwitchCounts(0),
- mSimulationTime(0.0),
- mMinStepTime(0.0), mMaxStepTime(0.0),
+ mTimeSwitchCounts(0), mTimeMaxvelStepCnt(0),
+ mSimulationTime(0.0), mLastSimTime(0.0),
+ mMinTimestep(0.0), mMaxTimestep(0.0),
mMaxNoCells(0), mMinNoCells(0), mAvgNumUsedCells(0),
mDropMode(1), mDropSize(0.15), mDropSpeed(0.0),
mObjectSpeeds(), mObjectPartslips(),
@@ -41,52 +313,51 @@ LbmFsgrSolver<D>::LbmFsgrSolver() :
mLastOmega(1e10), mLastGravity(1e10),
mNumInvIfTotal(0), mNumFsgrChanges(0),
mDisableStandingFluidInit(0),
- mForceTadapRefine(-1)
+ mForceTadapRefine(-1), mCutoff(-1)
{
// not much to do here...
- D::mpIso = new IsoSurface( D::mIsoValue, false );
-#if ELBEEM_PLUGIN!=1
+#if LBM_INCLUDE_TESTSOLVERS==1
mpTest = new LbmTestdata();
- mpParticles = NULL;
#endif // ELBEEM_PLUGIN!=1
+ this->mpIso = new IsoSurface( this->mIsoValue );
// init equilibrium dist. func
LbmFloat rho=1.0;
FORDF0 {
- D::dfEquil[l] = D::getCollideEq( l,rho, 0.0, 0.0, 0.0);
+ this->dfEquil[l] = this->getCollideEq( l,rho, 0.0, 0.0, 0.0);
}
// init LES
int odm = 0;
- for(int m=0; m<D::cDimension; m++) {
- for(int l=0; l<D::cDfNum; l++) {
- D::lesCoeffDiag[m][l] =
- D::lesCoeffOffdiag[m][l] = 0.0;
+ for(int m=0; m<LBMDIM; m++) {
+ for(int l=0; l<this->cDfNum; l++) {
+ this->lesCoeffDiag[m][l] =
+ this->lesCoeffOffdiag[m][l] = 0.0;
}
}
- for(int m=0; m<D::cDimension; m++) {
- for(int n=0; n<D::cDimension; n++) {
- for(int l=1; l<D::cDfNum; l++) {
+ for(int m=0; m<LBMDIM; m++) {
+ for(int n=0; n<LBMDIM; n++) {
+ for(int l=1; l<this->cDfNum; l++) {
LbmFloat em;
switch(m) {
- case 0: em = D::dfDvecX[l]; break;
- case 1: em = D::dfDvecY[l]; break;
- case 2: em = D::dfDvecZ[l]; break;
+ case 0: em = this->dfDvecX[l]; break;
+ case 1: em = this->dfDvecY[l]; break;
+ case 2: em = this->dfDvecZ[l]; break;
default: em = -1.0; errFatal("SMAGO1","err m="<<m, SIMWORLD_GENERICERROR);
}
LbmFloat en;
switch(n) {
- case 0: en = D::dfDvecX[l]; break;
- case 1: en = D::dfDvecY[l]; break;
- case 2: en = D::dfDvecZ[l]; break;
+ case 0: en = this->dfDvecX[l]; break;
+ case 1: en = this->dfDvecY[l]; break;
+ case 2: en = this->dfDvecZ[l]; break;
default: en = -1.0; errFatal("SMAGO2","err n="<<n, SIMWORLD_GENERICERROR);
}
const LbmFloat coeff = em*en;
if(m==n) {
- D::lesCoeffDiag[m][l] = coeff;
+ this->lesCoeffDiag[m][l] = coeff;
} else {
if(m>n) {
- D::lesCoeffOffdiag[odm][l] = coeff;
+ this->lesCoeffOffdiag[odm][l] = coeff;
}
}
}
@@ -101,7 +372,7 @@ LbmFsgrSolver<D>::LbmFsgrSolver() :
mDvecNrm[0] = LbmVec(0.0);
FORDF1 {
mDvecNrm[l] = getNormalized(
- LbmVec(D::dfDvecX[D::dfInv[l]], D::dfDvecY[D::dfInv[l]], D::dfDvecZ[D::dfInv[l]] )
+ LbmVec(this->dfDvecX[this->dfInv[l]], this->dfDvecY[this->dfInv[l]], this->dfDvecZ[this->dfInv[l]] )
) * -1.0;
}
@@ -109,32 +380,32 @@ LbmFsgrSolver<D>::LbmFsgrSolver() :
//LbmFloat mGaussw[27];
LbmFloat totGaussw = 0.0;
const LbmFloat alpha = 1.0;
- const LbmFloat gw = sqrt(2.0*D::cDimension);
+ const LbmFloat gw = sqrt(2.0*LBMDIM);
#if ELBEEM_PLUGIN!=1
errMsg("coarseRestrictFromFine", "TCRFF_DFDEBUG2 test df/dir num!");
#endif
- for(int n=0;(n<D::cDirNum); n++) { mGaussw[n] = 0.0; }
- //for(int n=0;(n<D::cDirNum); n++) {
- for(int n=0;(n<D::cDfNum); n++) {
- const LbmFloat d = norm(LbmVec(D::dfVecX[n], D::dfVecY[n], D::dfVecZ[n]));
+ for(int n=0;(n<this->cDirNum); n++) { mGaussw[n] = 0.0; }
+ //for(int n=0;(n<this->cDirNum); n++) {
+ for(int n=0;(n<this->cDfNum); n++) {
+ const LbmFloat d = norm(LbmVec(this->dfVecX[n], this->dfVecY[n], this->dfVecZ[n]));
LbmFloat w = expf( -alpha*d*d ) - expf( -alpha*gw*gw );
mGaussw[n] = w;
totGaussw += w;
}
- for(int n=0;(n<D::cDirNum); n++) {
+ for(int n=0;(n<this->cDirNum); n++) {
mGaussw[n] = mGaussw[n]/totGaussw;
}
+ mpParticles = NULL;
//addDrop(false,0,0);
}
/*****************************************************************************/
/* Destructor */
/*****************************************************************************/
-template<class D>
-LbmFsgrSolver<D>::~LbmFsgrSolver()
+LbmFsgrSolver::~LbmFsgrSolver()
{
- if(!D::mInitDone){ debugOut("LbmFsgrSolver::LbmFsgrSolver : not inited...",0); return; }
+ if(!this->mInitDone){ debugOut("LbmFsgrSolver::LbmFsgrSolver : not inited...",0); return; }
#if COMPRESSGRIDS==1
delete mLevel[mMaxRefine].mprsCells[1];
mLevel[mMaxRefine].mprsCells[0] = mLevel[mMaxRefine].mprsCells[1] = NULL;
@@ -146,17 +417,16 @@ LbmFsgrSolver<D>::~LbmFsgrSolver()
if(mLevel[i].mprsFlags[s]) delete [] mLevel[i].mprsFlags[s];
}
}
- delete D::mpIso;
+ delete this->mpIso;
if(mpPreviewSurface) delete mpPreviewSurface;
-#if ELBEEM_PLUGIN!=1
- destroyTestdata();
- delete mpTest;
+#if LBM_INCLUDE_TESTSOLVERS==1
+ // cleanup done during scene deletion...
#endif // ELBEEM_PLUGIN!=1
// always output performance estimate
debMsgStd("LbmFsgrSolver::~LbmFsgrSolver",DM_MSG," Avg. MLSUPS:"<<(mAvgMLSUPS/mAvgMLSUPSCnt), 5);
- if(!D::mSilent) debMsgStd("LbmFsgrSolver::~LbmFsgrSolver",DM_MSG,"Deleted...",10);
+ if(!this->mSilent) debMsgStd("LbmFsgrSolver::~LbmFsgrSolver",DM_MSG,"Deleted...",10);
}
@@ -165,29 +435,27 @@ LbmFsgrSolver<D>::~LbmFsgrSolver()
/******************************************************************************
* initilize variables fom attribute list
*****************************************************************************/
-template<class D>
-void
-LbmFsgrSolver<D>::parseAttrList()
+void LbmFsgrSolver::parseAttrList()
{
LbmSolverInterface::parseStdAttrList();
string matIso("default");
- matIso = D::mpAttrs->readString("material_surf", matIso, "SimulationLbm","mpIso->material", false );
- D::mpIso->setMaterialName( matIso );
- D::mOutputSurfacePreview = D::mpAttrs->readInt("surfacepreview", D::mOutputSurfacePreview, "SimulationLbm","D::mOutputSurfacePreview", false );
- mTimeAdap = D::mpAttrs->readBool("timeadap", mTimeAdap, "SimulationLbm","mTimeAdap", false );
- mDomainBound = D::mpAttrs->readString("domainbound", mDomainBound, "SimulationLbm","mDomainBound", false );
- mDomainPartSlipValue = D::mpAttrs->readFloat("domainpartslip", mDomainPartSlipValue, "SimulationLbm","mDomainPartSlipValue", false );
-
- mIsoWeightMethod= D::mpAttrs->readInt("isoweightmethod", mIsoWeightMethod, "SimulationLbm","mIsoWeightMethod", false );
- mInitSurfaceSmoothing = D::mpAttrs->readInt("initsurfsmooth", mInitSurfaceSmoothing, "SimulationLbm","mInitSurfaceSmoothing", false );
- D::mSmoothSurface = D::mpAttrs->readFloat("smoothsurface", D::mSmoothSurface, "SimulationLbm","mSmoothSurface", false );
- D::mSmoothNormals = D::mpAttrs->readFloat("smoothnormals", D::mSmoothNormals, "SimulationLbm","mSmoothNormals", false );
-
- mInitialCsmago = D::mpAttrs->readFloat("csmago", mInitialCsmago, "SimulationLbm","mInitialCsmago", false );
+ matIso = this->mpAttrs->readString("material_surf", matIso, "SimulationLbm","mpIso->material", false );
+ this->mpIso->setMaterialName( matIso );
+ this->mOutputSurfacePreview = this->mpAttrs->readInt("surfacepreview", this->mOutputSurfacePreview, "SimulationLbm","this->mOutputSurfacePreview", false );
+ mTimeAdap = this->mpAttrs->readBool("timeadap", mTimeAdap, "SimulationLbm","mTimeAdap", false );
+ this->mDomainBound = this->mpAttrs->readString("domainbound", this->mDomainBound, "SimulationLbm","mDomainBound", false );
+ this->mDomainPartSlipValue = this->mpAttrs->readFloat("domainpartslip", this->mDomainPartSlipValue, "SimulationLbm","mDomainPartSlipValue", false );
+
+ mIsoWeightMethod= this->mpAttrs->readInt("isoweightmethod", mIsoWeightMethod, "SimulationLbm","mIsoWeightMethod", false );
+ mInitSurfaceSmoothing = this->mpAttrs->readInt("initsurfsmooth", mInitSurfaceSmoothing, "SimulationLbm","mInitSurfaceSmoothing", false );
+ this->mSmoothSurface = this->mpAttrs->readFloat("smoothsurface", this->mSmoothSurface, "SimulationLbm","mSmoothSurface", false );
+ this->mSmoothNormals = this->mpAttrs->readFloat("smoothnormals", this->mSmoothNormals, "SimulationLbm","mSmoothNormals", false );
+
+ mInitialCsmago = this->mpAttrs->readFloat("csmago", mInitialCsmago, "SimulationLbm","mInitialCsmago", false );
// deprecated!
float mInitialCsmagoCoarse = 0.0;
- mInitialCsmagoCoarse = D::mpAttrs->readFloat("csmago_coarse", mInitialCsmagoCoarse, "SimulationLbm","mInitialCsmagoCoarse", false );
+ mInitialCsmagoCoarse = this->mpAttrs->readFloat("csmago_coarse", mInitialCsmagoCoarse, "SimulationLbm","mInitialCsmagoCoarse", false );
#if USE_LES==1
#else // USE_LES==1
debMsgStd("LbmFsgrSolver", DM_WARNING, "LES model switched off!",2);
@@ -195,42 +463,47 @@ LbmFsgrSolver<D>::parseAttrList()
#endif // USE_LES==1
// refinement
- mMaxRefine = D::mRefinementDesired;
- mMaxRefine = D::mpAttrs->readInt("maxrefine", mMaxRefine ,"LbmFsgrSolver", "mMaxRefine", false);
+ mMaxRefine = this->mRefinementDesired;
+ mMaxRefine = this->mpAttrs->readInt("maxrefine", mMaxRefine ,"LbmFsgrSolver", "mMaxRefine", false);
if(mMaxRefine<0) mMaxRefine=0;
if(mMaxRefine>FSGR_MAXNOOFLEVELS) mMaxRefine=FSGR_MAXNOOFLEVELS-1;
- mDisableStandingFluidInit = D::mpAttrs->readInt("disable_stfluidinit", mDisableStandingFluidInit,"LbmFsgrSolver", "mDisableStandingFluidInit", false);
- mForceTadapRefine = D::mpAttrs->readInt("forcetadaprefine", mForceTadapRefine,"LbmFsgrSolver", "mForceTadapRefine", false);
+ mDisableStandingFluidInit = this->mpAttrs->readInt("disable_stfluidinit", mDisableStandingFluidInit,"LbmFsgrSolver", "mDisableStandingFluidInit", false);
+ mForceTadapRefine = this->mpAttrs->readInt("forcetadaprefine", mForceTadapRefine,"LbmFsgrSolver", "mForceTadapRefine", false);
// demo mode settings
- mFVHeight = D::mpAttrs->readFloat("fvolheight", mFVHeight, "LbmFsgrSolver","mFVHeight", false );
+ mFVHeight = this->mpAttrs->readFloat("fvolheight", mFVHeight, "LbmFsgrSolver","mFVHeight", false );
// FIXME check needed?
- mFVArea = D::mpAttrs->readFloat("fvolarea", mFVArea, "LbmFsgrSolver","mFArea", false );
+ mFVArea = this->mpAttrs->readFloat("fvolarea", mFVArea, "LbmFsgrSolver","mFArea", false );
-#if ELBEEM_PLUGIN!=1
+#if LBM_INCLUDE_TESTSOLVERS==1
mUseTestdata = 0;
- mUseTestdata = D::mpAttrs->readBool("use_testdata", mUseTestdata,"LbmFsgrSolver", "mUseTestdata", false);
- mpTest->parseTestdataAttrList(D::mpAttrs);
-#endif // ELBEEM_PLUGIN!=1
+ mUseTestdata = this->mpAttrs->readBool("use_testdata", mUseTestdata,"LbmFsgrSolver", "mUseTestdata", false);
+ mpTest->parseTestdataAttrList(this->mpAttrs);
+#ifdef ELBEEM_PLUGIN
+ mUseTestdata=1; // DEBUG
+#endif // ELBEEM_PLUGIN
+ errMsg("LbmFsgrSolver::LBM_INCLUDE_TESTSOLVERS","Active, mUseTestdata:"<<mUseTestdata<<" ");
+#else // LBM_INCLUDE_TESTSOLVERS!=1
+ // off by default
+ mUseTestdata = 0;
+#endif // LBM_INCLUDE_TESTSOLVERS!=1
}
/******************************************************************************
* Initialize omegas and forces on all levels (for init/timestep change)
*****************************************************************************/
-template<class D>
-void
-LbmFsgrSolver<D>::initLevelOmegas()
+void LbmFsgrSolver::initLevelOmegas()
{
// no explicit settings
- D::mOmega = D::mpParam->calculateOmega(mSimulationTime);
- D::mGravity = vec2L( D::mpParam->calculateGravity(mSimulationTime) );
- D::mSurfaceTension = D::mpParam->calculateSurfaceTension(); // unused
+ this->mOmega = this->mpParam->calculateOmega(mSimulationTime);
+ this->mGravity = vec2L( this->mpParam->calculateGravity(mSimulationTime) );
+ this->mSurfaceTension = 0.; //this->mpParam->calculateSurfaceTension(); // unused
// check if last init was ok
- LbmFloat gravDelta = norm(D::mGravity-mLastGravity);
- //errMsg("ChannelAnimDebug","t:"<<mSimulationTime<<" om:"<<D::mOmega<<" - lom:"<<mLastOmega<<" gv:"<<D::mGravity<<" - "<<mLastGravity<<" , "<<gravDelta );
- if((D::mOmega == mLastOmega) && (gravDelta<=0.0)) return;
+ LbmFloat gravDelta = norm(this->mGravity-mLastGravity);
+ //errMsg("ChannelAnimDebug","t:"<<mSimulationTime<<" om:"<<this->mOmega<<" - lom:"<<mLastOmega<<" gv:"<<this->mGravity<<" - "<<mLastGravity<<" , "<<gravDelta );
+ if((this->mOmega == mLastOmega) && (gravDelta<=0.0)) return;
if(mInitialCsmago<=0.0) {
if(OPT3D==1) {
@@ -242,8 +515,8 @@ LbmFsgrSolver<D>::initLevelOmegas()
// use Tau instead of Omega for calculations
{ // init base level
int i = mMaxRefine;
- mLevel[i].omega = D::mOmega;
- mLevel[i].stepsize = D::mpParam->getStepTime();
+ mLevel[i].omega = this->mOmega;
+ mLevel[i].timestep = this->mpParam->getTimestep();
mLevel[i].lcsmago = mInitialCsmago; //CSMAGO_INITIAL;
mLevel[i].lcsmago_sqr = mLevel[i].lcsmago*mLevel[i].lcsmago;
mLevel[i].lcnu = (2.0* (1.0/mLevel[i].omega)-1.0) * (1.0/6.0);
@@ -255,42 +528,42 @@ LbmFsgrSolver<D>::initLevelOmegas()
double nomega = 0.5 * ( (1.0/(double)mLevel[i+1].omega) -0.5) + 0.5;
nomega = 1.0/nomega;
mLevel[i].omega = (LbmFloat)nomega;
- mLevel[i].stepsize = 2.0 * mLevel[i+1].stepsize;
+ mLevel[i].timestep = 2.0 * mLevel[i+1].timestep;
mLevel[i].lcsmago = mInitialCsmago;
mLevel[i].lcsmago_sqr = mLevel[i].lcsmago*mLevel[i].lcsmago;
mLevel[i].lcnu = (2.0* (1.0/mLevel[i].omega)-1.0) * (1.0/6.0);
}
// for lbgk
- mLevel[ mMaxRefine ].gravity = D::mGravity / mLevel[ mMaxRefine ].omega;
+ mLevel[ mMaxRefine ].gravity = this->mGravity / mLevel[ mMaxRefine ].omega;
for(int i=mMaxRefine-1; i>=0; i--) {
// should be the same on all levels...
// for lbgk
mLevel[i].gravity = (mLevel[i+1].gravity * mLevel[i+1].omega) * 2.0 / mLevel[i].omega;
}
- mLastOmega = D::mOmega;
- mLastGravity = D::mGravity;
+ mLastOmega = this->mOmega;
+ mLastGravity = this->mGravity;
// debug? invalidate old values...
- D::mGravity = -100.0;
- D::mOmega = -100.0;
+ this->mGravity = -100.0;
+ this->mOmega = -100.0;
for(int i=0; i<=mMaxRefine; i++) {
- if(!D::mSilent) {
+ if(!this->mSilent) {
errMsg("LbmFsgrSolver", "Level init "<<i<<" - sizes:"<<mLevel[i].lSizex<<","<<mLevel[i].lSizey<<","<<mLevel[i].lSizez<<" offs:"<<mLevel[i].lOffsx<<","<<mLevel[i].lOffsy<<","<<mLevel[i].lOffsz
<<" omega:"<<mLevel[i].omega<<" grav:"<<mLevel[i].gravity<< ", "
<<" cmsagp:"<<mLevel[i].lcsmago<<", "
- << " ss"<<mLevel[i].stepsize<<" ns"<<mLevel[i].nodeSize<<" cs"<<mLevel[i].simCellSize );
+ << " ss"<<mLevel[i].timestep<<" ns"<<mLevel[i].nodeSize<<" cs"<<mLevel[i].simCellSize );
} else {
- if(!D::mInitDone) {
+ if(!this->mInitDone) {
debMsgStd("LbmFsgrSolver", DM_MSG, "Level init "<<i<<" - sizes:"<<mLevel[i].lSizex<<","<<mLevel[i].lSizey<<","<<mLevel[i].lSizez<<" "
<<"omega:"<<mLevel[i].omega<<" grav:"<<mLevel[i].gravity , 5);
}
}
}
if(mMaxRefine>0) {
- mDfScaleUp = (mLevel[0 ].stepsize/mLevel[0+1].stepsize)* (1.0/mLevel[0 ].omega-1.0)/ (1.0/mLevel[0+1].omega-1.0); // yu
- mDfScaleDown = (mLevel[0+1].stepsize/mLevel[0 ].stepsize)* (1.0/mLevel[0+1].omega-1.0)/ (1.0/mLevel[0 ].omega-1.0); // yu
+ mDfScaleUp = (mLevel[0 ].timestep/mLevel[0+1].timestep)* (1.0/mLevel[0 ].omega-1.0)/ (1.0/mLevel[0+1].omega-1.0); // yu
+ mDfScaleDown = (mLevel[0+1].timestep/mLevel[0 ].timestep)* (1.0/mLevel[0+1].omega-1.0)/ (1.0/mLevel[0 ].omega-1.0); // yu
}
}
@@ -298,26 +571,26 @@ LbmFsgrSolver<D>::initLevelOmegas()
/******************************************************************************
* Init Solver (values should be read from config file)
*****************************************************************************/
-template<class D>
-bool
-//LbmFsgrSolver<D>::initialize( ntlTree* /*tree*/, vector<ntlGeometryObject*>* /*objects*/ )
-LbmFsgrSolver<D>::initializeSolver()
+bool LbmFsgrSolver::initializeSolver()
{
- debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Init start... (Layout:"<<ALSTRING<<") ",1);
+ debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Init start... (Layout:"<<ALSTRING<<") "<<this->mInitDone<<" "<<(int)this,1);
// size inits to force cubic cells and mult4 level dimensions
// and make sure we dont allocate too much...
bool memOk = false;
- int orgSx = D::mSizex;
- int orgSy = D::mSizey;
- int orgSz = D::mSizez;
+ int orgSx = this->mSizex;
+ int orgSy = this->mSizey;
+ int orgSz = this->mSizez;
double sizeReduction = 1.0;
- double memCnt = -1.0;
+ double memEstFromFunc = -1.0;
string memreqStr("");
+#if LBM_INCLUDE_TESTSOLVERS==1
+ if(mUseTestdata) { mMaxRefine=0; } // force fsgr off
+#endif
while(!memOk) {
- initGridSizes( D::mSizex, D::mSizey, D::mSizez,
- D::mvGeoStart, D::mvGeoEnd, mMaxRefine, PARALLEL);
- calculateMemreqEstimate( D::mSizex, D::mSizey, D::mSizez, mMaxRefine, &memCnt, &memreqStr );
+ initGridSizes( this->mSizex, this->mSizey, this->mSizez,
+ this->mvGeoStart, this->mvGeoEnd, mMaxRefine, PARALLEL);
+ calculateMemreqEstimate( this->mSizex, this->mSizey, this->mSizez, mMaxRefine, &memEstFromFunc, &memreqStr );
double memLimit;
if(sizeof(int)==4) {
@@ -327,55 +600,52 @@ LbmFsgrSolver<D>::initializeSolver()
// 64bit, just take 16GB as limit for now...
memLimit = 16.0* 1024.0*1024.0*1024.0;
}
- if(memCnt>memLimit) {
+ if(memEstFromFunc>memLimit) {
sizeReduction *= 0.9;
- D::mSizex = (int)(orgSx * sizeReduction);
- D::mSizey = (int)(orgSy * sizeReduction);
- D::mSizez = (int)(orgSz * sizeReduction);
- debMsgStd("LbmFsgrSolver::initialize",DM_WARNING,"initGridSizes: memory limit exceeded "<<memCnt<<"/"<<memLimit<<", retrying: "
- <<D::mSizex<<" Y:"<<D::mSizey<<" Z:"<<D::mSizez, 3 );
+ this->mSizex = (int)(orgSx * sizeReduction);
+ this->mSizey = (int)(orgSy * sizeReduction);
+ this->mSizez = (int)(orgSz * sizeReduction);
+ debMsgStd("LbmFsgrSolver::initialize",DM_WARNING,"initGridSizes: memory limit exceeded "<<memEstFromFunc<<"/"<<memLimit<<", retrying: "
+ <<this->mSizex<<" Y:"<<this->mSizey<<" Z:"<<this->mSizez, 3 );
} else {
memOk = true;
}
}
- D::mPreviewFactor = (LbmFloat)D::mOutputSurfacePreview / (LbmFloat)D::mSizex;
- debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"initGridSizes: Final domain size X:"<<D::mSizex<<" Y:"<<D::mSizey<<" Z:"<<D::mSizez<<
- ", Domain: "<<D::mvGeoStart<<":"<<D::mvGeoEnd<<", "<<(D::mvGeoEnd-D::mvGeoStart)<<
+ this->mPreviewFactor = (LbmFloat)this->mOutputSurfacePreview / (LbmFloat)this->mSizex;
+ debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"initGridSizes: Final domain size X:"<<this->mSizex<<" Y:"<<this->mSizey<<" Z:"<<this->mSizez<<
+ ", Domain: "<<this->mvGeoStart<<":"<<this->mvGeoEnd<<", "<<(this->mvGeoEnd-this->mvGeoStart)<<
", est. Mem.Req.: "<<memreqStr ,2);
- //debMsgStd("LbmFsgrSolver::initialize",DM_MSG, ,2);
- D::mpParam->setSize(D::mSizex, D::mSizey, D::mSizez);
-
- //debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Size X:"<<D::mSizex<<" Y:"<<D::mSizey<<" Z:"<<D::mSizez ,2);
+ this->mpParam->setSize(this->mSizex, this->mSizey, this->mSizez);
-#if ELBEEM_PLUGIN!=1
debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Definitions: "
- <<"LBM_EPSILON="<<LBM_EPSILON <<" "
- <<"FSGR_STRICT_DEBUG="<<FSGR_STRICT_DEBUG <<" "
- <<"OPT3D="<<OPT3D <<" "
+ <<"LBM_EPSILON="<<LBM_EPSILON <<" "
+ <<"FSGR_STRICT_DEBUG="<<FSGR_STRICT_DEBUG <<" "
+ <<"OPT3D="<<OPT3D <<" "
<<"COMPRESSGRIDS="<<COMPRESSGRIDS<<" "
- <<"MASS_INVALID="<<MASS_INVALID <<" "
- <<"FSGR_LISTTRICK="<<FSGR_LISTTRICK <<" "
- <<"FSGR_LISTTTHRESHEMPTY="<<FSGR_LISTTTHRESHEMPTY <<" "
- <<"FSGR_LISTTTHRESHFULL="<<FSGR_LISTTTHRESHFULL <<" "
- <<"FSGR_MAGICNR="<<FSGR_MAGICNR <<" "
- <<"USE_LES="<<USE_LES <<" "
+ <<"MASS_INVALID="<<MASS_INVALID <<" "
+ <<"FSGR_LISTTRICK="<<FSGR_LISTTRICK <<" "
+ <<"FSGR_LISTTTHRESHEMPTY="<<FSGR_LISTTTHRESHEMPTY <<" "
+ <<"FSGR_LISTTTHRESHFULL="<<FSGR_LISTTTHRESHFULL <<" "
+ <<"FSGR_MAGICNR="<<FSGR_MAGICNR <<" "
+ <<"USE_LES="<<USE_LES <<" "
,10);
+#if ELBEEM_PLUGIN!=1
#endif // ELBEEM_PLUGIN!=1
// perform 2D corrections...
- if(D::cDimension == 2) D::mSizez = 1;
+ if(LBMDIM == 2) this->mSizez = 1;
- D::mpParam->setSimulationMaxSpeed(0.0);
- if(mFVHeight>0.0) D::mpParam->setFluidVolumeHeight(mFVHeight);
- D::mpParam->setTadapLevels( mMaxRefine+1 );
+ this->mpParam->setSimulationMaxSpeed(0.0);
+ if(mFVHeight>0.0) this->mpParam->setFluidVolumeHeight(mFVHeight);
+ this->mpParam->setTadapLevels( mMaxRefine+1 );
if(mForceTadapRefine>mMaxRefine) {
- D::mpParam->setTadapLevels( mForceTadapRefine+1 );
+ this->mpParam->setTadapLevels( mForceTadapRefine+1 );
debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Forcing a t-adap refine level of "<<mForceTadapRefine, 6);
}
- if(!D::mpParam->calculateAllMissingValues()) {
+ if(!this->mpParam->calculateAllMissingValues(mSimulationTime, false)) {
errFatal("LbmFsgrSolver::initialize","Fatal: failed to init parameters! Aborting...",SIMWORLD_INITERROR);
return false;
}
@@ -388,7 +658,7 @@ LbmFsgrSolver<D>::initializeSolver()
mLevel[i].simCellSize = 0.0;
mLevel[i].omega = 0.0;
mLevel[i].time = 0.0;
- mLevel[i].stepsize = 1.0;
+ mLevel[i].timestep = 1.0;
mLevel[i].gravity = LbmVec(0.0);
mLevel[i].mprsCells[0] = NULL;
mLevel[i].mprsCells[1] = NULL;
@@ -400,9 +670,9 @@ LbmFsgrSolver<D>::initializeSolver()
}
// init sizes
- mLevel[mMaxRefine].lSizex = D::mSizex;
- mLevel[mMaxRefine].lSizey = D::mSizey;
- mLevel[mMaxRefine].lSizez = D::mSizez;
+ mLevel[mMaxRefine].lSizex = this->mSizex;
+ mLevel[mMaxRefine].lSizey = this->mSizey;
+ mLevel[mMaxRefine].lSizez = this->mSizez;
for(int i=mMaxRefine-1; i>=0; i--) {
mLevel[i].lSizex = mLevel[i+1].lSizex/2;
mLevel[i].lSizey = mLevel[i+1].lSizey/2;
@@ -415,50 +685,50 @@ LbmFsgrSolver<D>::initializeSolver()
return false;
}
- double memCheck = 0.0;
- mLevel[ mMaxRefine ].nodeSize = ((D::mvGeoEnd[0]-D::mvGeoStart[0]) / (LbmFloat)(D::mSizex));
- mLevel[ mMaxRefine ].simCellSize = D::mpParam->getCellSize();
+ double ownMemCheck = 0.0;
+ mLevel[ mMaxRefine ].nodeSize = ((this->mvGeoEnd[0]-this->mvGeoStart[0]) / (LbmFloat)(this->mSizex));
+ mLevel[ mMaxRefine ].simCellSize = this->mpParam->getCellSize();
mLevel[ mMaxRefine ].lcellfactor = 1.0;
LONGINT rcellSize = ((mLevel[mMaxRefine].lSizex*mLevel[mMaxRefine].lSizey*mLevel[mMaxRefine].lSizez) *dTotalNum);
// +4 for safety ?
mLevel[ mMaxRefine ].mprsFlags[0] = new CellFlagType[ rcellSize/dTotalNum +4 ];
mLevel[ mMaxRefine ].mprsFlags[1] = new CellFlagType[ rcellSize/dTotalNum +4 ];
- memCheck += 2 * sizeof(CellFlagType) * (rcellSize/dTotalNum +4);
+ ownMemCheck += 2 * sizeof(CellFlagType) * (rcellSize/dTotalNum +4);
#if COMPRESSGRIDS==0
mLevel[ mMaxRefine ].mprsCells[0] = new LbmFloat[ rcellSize +4 ];
mLevel[ mMaxRefine ].mprsCells[1] = new LbmFloat[ rcellSize +4 ];
- memCheck += 2 * sizeof(LbmFloat) * (rcellSize+4);
+ ownMemCheck += 2 * sizeof(LbmFloat) * (rcellSize+4);
#else // COMPRESSGRIDS==0
LONGINT compressOffset = (mLevel[mMaxRefine].lSizex*mLevel[mMaxRefine].lSizey*dTotalNum*2);
mLevel[ mMaxRefine ].mprsCells[1] = new LbmFloat[ rcellSize +compressOffset +4 ];
mLevel[ mMaxRefine ].mprsCells[0] = mLevel[ mMaxRefine ].mprsCells[1]+compressOffset;
- memCheck += sizeof(LbmFloat) * (rcellSize +compressOffset +4);
+ ownMemCheck += sizeof(LbmFloat) * (rcellSize +compressOffset +4);
#endif // COMPRESSGRIDS==0
LbmFloat lcfdimFac = 8.0;
- if(D::cDimension==2) lcfdimFac = 4.0;
+ if(LBMDIM==2) lcfdimFac = 4.0;
for(int i=mMaxRefine-1; i>=0; i--) {
mLevel[i].nodeSize = 2.0 * mLevel[i+1].nodeSize;
mLevel[i].simCellSize = 2.0 * mLevel[i+1].simCellSize;
mLevel[i].lcellfactor = mLevel[i+1].lcellfactor * lcfdimFac;
- if(D::cDimension==2){ mLevel[i].lSizez = 1; } // 2D
+ if(LBMDIM==2){ mLevel[i].lSizez = 1; } // 2D
rcellSize = ((mLevel[i].lSizex*mLevel[i].lSizey*mLevel[i].lSizez) *dTotalNum);
mLevel[i].mprsFlags[0] = new CellFlagType[ rcellSize/dTotalNum +4 ];
mLevel[i].mprsFlags[1] = new CellFlagType[ rcellSize/dTotalNum +4 ];
- memCheck += 2 * sizeof(CellFlagType) * (rcellSize/dTotalNum +4);
+ ownMemCheck += 2 * sizeof(CellFlagType) * (rcellSize/dTotalNum +4);
mLevel[i].mprsCells[0] = new LbmFloat[ rcellSize +4 ];
mLevel[i].mprsCells[1] = new LbmFloat[ rcellSize +4 ];
- memCheck += 2 * sizeof(LbmFloat) * (rcellSize+4);
+ ownMemCheck += 2 * sizeof(LbmFloat) * (rcellSize+4);
}
// isosurface memory
- memCheck += (3*sizeof(int)+sizeof(float)) * ((D::mSizex+2)*(D::mSizey+2)*(D::mSizez+2));
+ ownMemCheck += (3*sizeof(int)+sizeof(float)) * ((this->mSizex+2)*(this->mSizey+2)*(this->mSizez+2));
// sanity check
#if ELBEEM_PLUGIN!=1
- if(ABS(1.0-memCheck/memCnt)>0.01) {
- errMsg("LbmFsgrSolver::initialize","Sanity Error - memory estimate is off: "<<memCheck<<" vs. "<<memCnt );
+ if(ABS(1.0-ownMemCheck/memEstFromFunc)>0.01) {
+ errMsg("LbmFsgrSolver::initialize","Sanity Error - memory estimate is off! real:"<<ownMemCheck<<" vs. estimate:"<<memEstFromFunc );
}
#endif // ELBEEM_PLUGIN!=1
@@ -476,15 +746,22 @@ LbmFsgrSolver<D>::initializeSolver()
// calc omega, force for all levels
initLevelOmegas();
- mMinStepTime = D::mpParam->getStepTime();
- mMaxStepTime = D::mpParam->getStepTime();
+ mMinTimestep = this->mpParam->getTimestep();
+ mMaxTimestep = this->mpParam->getTimestep();
// init isosurf
- D::mpIso->setIsolevel( D::mIsoValue );
+#if LBM_INCLUDE_TESTSOLVERS==1
+ if(mUseTestdata) {
+ mpTest->setMaterialName( this->mpIso->getMaterialName() );
+ delete this->mpIso;
+ this->mpIso = mpTest;
+ }
+#endif // ELBEEM_PLUGIN!=1
+ this->mpIso->setIsolevel( this->mIsoValue );
// approximate feature size with mesh resolution
float featureSize = mLevel[ mMaxRefine ].nodeSize*0.5;
- D::mpIso->setSmoothSurface( D::mSmoothSurface * featureSize );
- D::mpIso->setSmoothNormals( D::mSmoothNormals * featureSize );
+ this->mpIso->setSmoothSurface( this->mSmoothSurface * featureSize );
+ this->mpIso->setSmoothNormals( this->mSmoothNormals * featureSize );
// init iso weight values mIsoWeightMethod
int wcnt = 0;
@@ -513,31 +790,31 @@ LbmFsgrSolver<D>::initializeSolver()
}
for(int i=0; i<27; i++) mIsoWeight[i] /= totw;
- LbmVec isostart = vec2L(D::mvGeoStart);
- LbmVec isoend = vec2L(D::mvGeoEnd);
+ LbmVec isostart = vec2L(this->mvGeoStart);
+ LbmVec isoend = vec2L(this->mvGeoEnd);
int twodOff = 0; // 2d slices
- if(D::cDimension==2) {
+ if(LBMDIM==2) {
LbmFloat sn,se;
- sn = isostart[2]+(isoend[2]-isostart[2])*0.5 - ((isoend[0]-isostart[0]) / (LbmFloat)(D::mSizex+1.0))*0.5;
- se = isostart[2]+(isoend[2]-isostart[2])*0.5 + ((isoend[0]-isostart[0]) / (LbmFloat)(D::mSizex+1.0))*0.5;
+ sn = isostart[2]+(isoend[2]-isostart[2])*0.5 - ((isoend[0]-isostart[0]) / (LbmFloat)(this->mSizex+1.0))*0.5;
+ se = isostart[2]+(isoend[2]-isostart[2])*0.5 + ((isoend[0]-isostart[0]) / (LbmFloat)(this->mSizex+1.0))*0.5;
isostart[2] = sn;
isoend[2] = se;
twodOff = 2;
}
- //errMsg(" SETISO ", " "<<isostart<<" - "<<isoend<<" "<<(((isoend[0]-isostart[0]) / (LbmFloat)(D::mSizex+1.0))*0.5)<<" "<<(LbmFloat)(D::mSizex+1.0)<<" " );
- D::mpIso->setStart( vec2G(isostart) );
- D::mpIso->setEnd( vec2G(isoend) );
+ //errMsg(" SETISO ", " "<<isostart<<" - "<<isoend<<" "<<(((isoend[0]-isostart[0]) / (LbmFloat)(this->mSizex+1.0))*0.5)<<" "<<(LbmFloat)(this->mSizex+1.0)<<" " );
+ this->mpIso->setStart( vec2G(isostart) );
+ this->mpIso->setEnd( vec2G(isoend) );
LbmVec isodist = isoend-isostart;
- D::mpIso->initializeIsosurface( D::mSizex+2, D::mSizey+2, D::mSizez+2+twodOff, vec2G(isodist) );
- for(int ak=0;ak<D::mSizez+2+twodOff;ak++)
- for(int aj=0;aj<D::mSizey+2;aj++)
- for(int ai=0;ai<D::mSizex+2;ai++) { *D::mpIso->getData(ai,aj,ak) = 0.0; }
+ this->mpIso->initializeIsosurface( this->mSizex+2, this->mSizey+2, this->mSizez+2+twodOff, vec2G(isodist) );
+ for(int ak=0;ak<this->mSizez+2+twodOff;ak++)
+ for(int aj=0;aj<this->mSizey+2;aj++)
+ for(int ai=0;ai<this->mSizex+2;ai++) { *this->mpIso->getData(ai,aj,ak) = 0.0; }
/* init array (set all invalid first) */
for(int lev=0; lev<=mMaxRefine; lev++) {
FSGR_FORIJK_BOUNDS(lev) {
RFLAG(lev,i,j,k,0) = RFLAG(lev,i,j,k,0) = 0; // reset for changeFlag usage
- if(!D::mAllfluid) {
+ if(!this->mAllfluid) {
initEmptyCell(lev, i,j,k, CFEmpty, -1.0, -1.0);
} else {
initEmptyCell(lev, i,j,k, CFFluid, 1.0, 1.0);
@@ -547,35 +824,37 @@ LbmFsgrSolver<D>::initializeSolver()
// init defaults
mAvgNumUsedCells = 0;
- D::mFixMass= 0.0;
+ this->mFixMass= 0.0;
/* init boundaries */
debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Boundary init...",10);
+ // init obstacles, and reinit time step size
initGeometryFlags();
+ mLastSimTime = -1.0;
// TODO check for invalid cells? nitGenericTestCases();
// new - init noslip 1 everywhere...
// half fill boundary cells?
CellFlagType domainBoundType = CFInvalid;
- if(mDomainBound.find(string("free")) != string::npos) {
+ // TODO use normal object types instad...
+ if(this->mDomainBound.find(string("free")) != string::npos) {
domainBoundType = CFBnd | CFBndFreeslip;
- debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Domain Boundary Type: FreeSlip, value:"<<mDomainBound,10);
- } else if(mDomainBound.find(string("part")) != string::npos) {
+ debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Domain Boundary Type: FreeSlip, value:"<<this->mDomainBound,10);
+ } else if(this->mDomainBound.find(string("part")) != string::npos) {
domainBoundType = CFBnd | CFBndPartslip; // part slip type
- debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Domain Boundary Type: PartSlip ("<<mDomainPartSlipValue<<"), value:"<<mDomainBound,10);
+ debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Domain Boundary Type: PartSlip ("<<this->mDomainPartSlipValue<<"), value:"<<this->mDomainBound,10);
} else {
domainBoundType = CFBnd | CFBndNoslip;
- debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Domain Boundary Type: NoSlip, value:"<<mDomainBound,10);
+ debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Domain Boundary Type: NoSlip, value:"<<this->mDomainBound,10);
}
// use ar[numobjs] as entry for domain (used e.g. for mDomainPartSlipValue in mObjectPartslips)
- int domainobj = (int)(D::mpGiObjects->size());
+ int domainobj = (int)(this->mpGiObjects->size());
domainBoundType |= (domainobj<<24);
//for(int i=0; i<(int)(domainobj+0); i++) {
- //errMsg("GEOIN","i"<<i<<" "<<(*D::mpGiObjects)[i]->getName());
- //if((*D::mpGiObjects)[i] == D::mpIso) {
- //check...
+ //errMsg("GEOIN","i"<<i<<" "<<(*this->mpGiObjects)[i]->getName());
+ //if((*this->mpGiObjects)[i] == this->mpIso) { //check...
//}
//}
//errMsg("GEOIN"," dm "<<(domainBoundType>>24));
@@ -594,7 +873,7 @@ LbmFsgrSolver<D>::initializeSolver()
//initEmptyCell(mMaxRefine, mLevel[mMaxRefine].lSizex-2,j,k, domainBoundType, 0.0, BND_FILL);
}
- if(D::cDimension == 3) {
+ if(LBMDIM == 3) {
// only for 3D
for(int j=0;j<mLevel[mMaxRefine].lSizey;j++)
for(int i=0;i<mLevel[mMaxRefine].lSizex;i++) {
@@ -647,8 +926,8 @@ LbmFsgrSolver<D>::initializeSolver()
}
mCurrentVolume = mCurrentMass = mInitialMass;
- ParamVec cspv = D::mpParam->calculateCellSize();
- if(D::cDimension==2) cspv[2] = 1.0;
+ ParamVec cspv = this->mpParam->calculateCellSize();
+ if(LBMDIM==2) cspv[2] = 1.0;
inmCellCnt = 1;
double nrmMass = (double)mInitialMass / (double)(inmCellCnt) *cspv[0]*cspv[1]*cspv[2] * 1000.0;
debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Initial Mass:"<<mInitialMass<<" normalized:"<<nrmMass, 3);
@@ -656,7 +935,7 @@ LbmFsgrSolver<D>::initializeSolver()
//mStartSymm = false;
#if ELBEEM_PLUGIN!=1
- if((D::cDimension==2)&&(D::mSizex<200)) {
+ if((LBMDIM==2)&&(this->mSizex<200)) {
if(!checkSymmetry("init")) {
errMsg("LbmFsgrSolver::initialize","Unsymmetric init...");
} else {
@@ -676,18 +955,18 @@ LbmFsgrSolver<D>::initializeSolver()
adaptGrid(lev);
coarseRestrictFromFine(lev);
}
- D::markedClearList();
+ this->markedClearList();
myTime_t fsgrtend = getTime();
- if(!D::mSilent){ debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"FSGR init done ("<< ((fsgrtend-fsgrtstart)/(double)1000.0)<<"s), changes:"<<mNumFsgrChanges , 10 ); }
+ if(!this->mSilent){ debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"FSGR init done ("<< getTimeString(fsgrtend-fsgrtstart)<<"), changes:"<<mNumFsgrChanges , 10 ); }
mNumFsgrChanges = 0;
- for(int l=0; l<D::cDirNum; l++) {
+ for(int l=0; l<this->cDirNum; l++) {
LbmFloat area = 0.5 * 0.5 *0.5;
- if(D::cDimension==2) area = 0.5 * 0.5;
+ if(LBMDIM==2) area = 0.5 * 0.5;
- if(D::dfVecX[l]!=0) area *= 0.5;
- if(D::dfVecY[l]!=0) area *= 0.5;
- if(D::dfVecZ[l]!=0) area *= 0.5;
+ if(this->dfVecX[l]!=0) area *= 0.5;
+ if(this->dfVecY[l]!=0) area *= 0.5;
+ if(this->dfVecZ[l]!=0) area *= 0.5;
mFsgrCellArea[l] = area;
} // l
@@ -700,35 +979,31 @@ LbmFsgrSolver<D>::initializeSolver()
- if(D::cDimension==2) {
- if(D::mOutputSurfacePreview) {
+ if(LBMDIM==2) {
+ if(this->mOutputSurfacePreview) {
errMsg("LbmFsgrSolver::init","No preview in 2D allowed!");
- D::mOutputSurfacePreview = 0; }
+ this->mOutputSurfacePreview = 0; }
}
- if(D::mOutputSurfacePreview) {
+ if(this->mOutputSurfacePreview) {
// same as normal one, but use reduced size
- mpPreviewSurface = new IsoSurface( D::mIsoValue, false );
+ mpPreviewSurface = new IsoSurface( this->mIsoValue );
mpPreviewSurface->setMaterialName( mpPreviewSurface->getMaterialName() );
- mpPreviewSurface->setIsolevel( D::mIsoValue );
+ mpPreviewSurface->setIsolevel( this->mIsoValue );
// usually dont display for rendering
mpPreviewSurface->setVisible( false );
mpPreviewSurface->setStart( vec2G(isostart) );
mpPreviewSurface->setEnd( vec2G(isoend) );
LbmVec pisodist = isoend-isostart;
- LbmFloat pfac = D::mPreviewFactor;
- mpPreviewSurface->initializeIsosurface( (int)(pfac*D::mSizex)+2, (int)(pfac*D::mSizey)+2, (int)(pfac*D::mSizez)+2, vec2G(pisodist) );
- //mpPreviewSurface->setName( D::getName() + "preview" );
+ LbmFloat pfac = this->mPreviewFactor;
+ mpPreviewSurface->initializeIsosurface( (int)(pfac*this->mSizex)+2, (int)(pfac*this->mSizey)+2, (int)(pfac*this->mSizez)+2, vec2G(pisodist) );
+ //mpPreviewSurface->setName( this->getName() + "preview" );
mpPreviewSurface->setName( "preview" );
- debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Preview with sizes "<<(pfac*D::mSizex)<<","<<(pfac*D::mSizey)<<","<<(pfac*D::mSizez)<<" enabled",10);
+ debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Preview with sizes "<<(pfac*this->mSizex)<<","<<(pfac*this->mSizey)<<","<<(pfac*this->mSizez)<<" enabled",10);
}
-#if ELBEEM_PLUGIN!=1
- initTestdata();
-#endif // ELBEEM_PLUGIN!=1
-
// make sure fill fracs are right for first surface generation
stepMain();
@@ -743,73 +1018,454 @@ LbmFsgrSolver<D>::initializeSolver()
// now really done...
debugOut("LbmFsgrSolver::initialize : Init done ...",10);
- D::mInitDone = 1;
+ this->mInitDone = 1;
+
+#if LBM_INCLUDE_TESTSOLVERS==1
+ initTestdata();
+#endif // ELBEEM_PLUGIN!=1
+
return true;
}
+
+/*****************************************************************************/
+//! init moving obstacles for next sim step sim
+/*****************************************************************************/
+void LbmFsgrSolver::initMovingObstacles(bool staticInit) {
+
+ myTime_t monstart = getTime();
+ // new test
+ const int level = mMaxRefine;
+ const int workSet = mLevel[level].setCurr;
+ LbmFloat sourceTime = mSimulationTime; // should be equal to mLastSimTime!
+ // for debugging - check targetTime check during DEFAULT STREAM
+ LbmFloat targetTime = mSimulationTime + this->mpParam->getTimestep();
+ if(mLastSimTime == targetTime) {
+ debMsgStd("LbmFsgrSolver::initMovingObstacles",DM_WARNING,"Called for same time! (t="<<mSimulationTime<<" , targett="<<targetTime<<")", 1);
+ return;
+ }
+ //debMsgStd("LbmFsgrSolver::initMovingObstacles",DM_WARNING,"time: "<<mSimulationTime<<" lasttt:"<<mLastSimTime,10);
+ //if(mSimulationTime!=mLastSimTime) errMsg("LbmFsgrSolver::initMovingObstacles","time: "<<mSimulationTime<<" lasttt:"<<mLastSimTime);
+
+ LbmFloat rhomass = 0.0;
+ CellFlagType otype = CFInvalid; // verify type of last step, might be non moving obs!
+ CellFlagType ntype = CFInvalid;
+ // WARNING - copied from geo init!
+ int numobjs = (int)(this->mpGiObjects->size());
+ ntlVec3Gfx dvec = ntlVec3Gfx(mLevel[level].nodeSize); //dvec*1.0;
+ // 2d display as rectangles
+ ntlVec3Gfx iniPos(0.0);
+ if(LBMDIM==2) {
+ dvec[2] = 1.0;
+ iniPos = (this->mvGeoStart + ntlVec3Gfx( 0.0, 0.0, (this->mvGeoEnd[2]-this->mvGeoStart[2])*0.5 ))-(dvec*0.0);
+ } else {
+ iniPos = (this->mvGeoStart + ntlVec3Gfx( 0.0 ))-(dvec*0.0);
+ //iniPos[2] = this->mvGeoStart[2] + dvec[2]*getForZMin1();
+ }
+
+ // stats
+ int monPoints=0, monObsts=0, monFluids=0, monTotal=0, monTrafo=0;
+ CellFlagType nbflag[LBM_DFNUM];
+ int nbored;
+ vector<ntlVec3Gfx> vertices;
+ vector<ntlVec3Gfx> verticesOld;
+ int i,j,k; // grid pos init
+ LbmFloat ux,uy,uz, rho;
+ for(int OId=0; OId<numobjs; OId++) {
+ ntlGeometryObject *obj = (*this->mpGiObjects)[OId];
+ if( (!staticInit) && (!obj->getIsAnimated()) ) continue;
+ if( ( staticInit) && ( obj->getIsAnimated()) ) continue;
+
+ if(obj->getGeoInitType()&FGI_ALLBOUNDS) {
+
+ otype = ntype = CFInvalid;
+ switch(obj->getGeoInitType()) {
+ case FGI_BNDPART:
+ case FGI_BNDFREE:
+ errMsg("LbmFsgrSolver::initMovingObstacles","Warning - moving free/part slip objects NYI "<<obj->getName() );
+ case FGI_BNDNO:
+ rhomass = BND_FILL;
+ otype = ntype = CFBnd|CFBndNoslip;
+ break;
+ case FGI_MBNDINFLOW:
+ otype = ntype = CFMbndInflow;
+ break;
+ case FGI_MBNDOUTFLOW:
+ otype = ntype = CFMbndOutflow;
+ break;
+ }
+ int wasActive = ((obj->getGeoActive(sourceTime)>0.)? 1:0);
+ int active = ((obj->getGeoActive(targetTime)>0.)? 1:0);
+ //errMsg("GEOACTT"," obj "<<obj->getName()<<" a:"<<active<<","<<wasActive<<" s"<<sourceTime<<" t"<<targetTime <<" v"<<mObjectSpeeds[OId] );
+ // skip inactive in/out flows
+ if((!active) && (otype&(CFMbndOutflow|CFMbndInflow)) ) continue;
+
+ // copied from recalculateObjectSpeeds
+ mObjectSpeeds[OId] = vec2L(this->mpParam->calculateLattVelocityFromRw( vec2P( (*this->mpGiObjects)[OId]->getInitialVelocity(mSimulationTime) )));
+ debMsgStd("LbmFsgrSolver::initMovingObstacles",DM_MSG,"id"<<OId<<" "<<obj->getName()<<" inivel set to "<< mObjectSpeeds[OId]<<", unscaled:"<< (*this->mpGiObjects)[OId]->getInitialVelocity(mSimulationTime) ,10 );
+
+ vertices.clear();
+ obj->getMovingPoints(vertices);
+ verticesOld = vertices;
+ // WARNING - assumes mSimulationTime is global!?
+ obj->applyTransformation(targetTime, &vertices,NULL, 0, vertices.size(), false );
+ monTrafo += vertices.size();
+
+ // correct flags from last position, but extrapolate
+ // velocity to next timestep
+ obj->applyTransformation(sourceTime, &verticesOld,NULL, 0, verticesOld.size(), false );
+ monTrafo += verticesOld.size();
+
+ // object types
+ if(ntype&CFBnd){
+
+ // check if object is moving at all
+ if(obj->getIsAnimated()) {
+ ntlVec3Gfx objMaxVel = obj->calculateMaxVel(sourceTime,targetTime);
+ // FIXME?
+ if(normNoSqrt(objMaxVel)>0.0) { ntype |= CFBndMoving; }
+ // get old type - CHECK FIXME , timestep could have changed - cause trouble?
+ ntlVec3Gfx oldobjMaxVel = obj->calculateMaxVel(sourceTime - this->mpParam->getTimestep(),sourceTime);
+ if(normNoSqrt(oldobjMaxVel)>0.0) { otype |= CFBndMoving; }
+ }
+
+#if LBMDIM==2
+#define CHECKIJK \
+ if(i<=0) continue; \
+ if(j<=0) continue; \
+ if(i>=mLevel[level].lSizex-2) continue; \
+ if(j>=mLevel[level].lSizey-2) continue;
+#define POS2GRID(vec,n) \
+ monTotal++;\
+ i=(int)( ((vec)[n][0]-iniPos[0])/dvec[0] +0.0); \
+ j=(int)( ((vec)[n][1]-iniPos[1])/dvec[1] +0.0); \
+ k=0;
+#else // LBMDIM -> 3
+#define CHECKIJK \
+ if(i<=0) continue; \
+ if(j<=0) continue; \
+ if(k<=0) continue; \
+ if(i>=mLevel[level].lSizex-2) continue; \
+ if(j>=mLevel[level].lSizey-2) continue; \
+ if(k>=mLevel[level].lSizez-2) continue;
+#define POS2GRID(vec,n) \
+ monTotal++;\
+ i=(int)( ((vec)[n][0]-iniPos[0])/dvec[0] +0.0); \
+ j=(int)( ((vec)[n][1]-iniPos[1])/dvec[1] +0.0); \
+ k=(int)( ((vec)[n][2]-iniPos[2])/dvec[2] +0.0);
+#endif // LBMDIM
+
+ // first pass - set new obs. cells
+ if(active) {
+ for(size_t n=0; n<vertices.size(); n++) {
+ //errMsg("AAABB","OId"<<OId<<" n"<<n<<" -> "<<PRINT_IJK);
+ POS2GRID(vertices,n);
+ CHECKIJK;
+ //if(i==30 && j==14) { errMsg("AAABB","OId"<<OId<<" n"<<n<<" -> "<<PRINT_IJK<<" "); }
+ if(QCELL(level, i,j,k, workSet, dFlux)==targetTime) continue;
+ monPoints++;
+ LbmVec u= vec2L((vertices[n]-verticesOld[n]) /dvec); // * timeFac;
+ RFLAG(level, i,j,k, workSet) = ntype;
+ FORDF1 {
+ CellFlagType flag = RFLAG_NB(level, i,j,k,workSet,l);
+ if(flag&(CFFluid|CFInter)) {
+ flag &= (~CFNoBndFluid); // remove CFNoBndFluid flag
+ RFLAG_NB(level, i,j,k,workSet,l) &= flag;
+ }
+ }
+ LbmFloat *dstCell = RACPNT(level, i,j,k,workSet);
+ RAC(dstCell,0) = 0.0;
+ if(ntype&CFBndMoving) {
+ //if(i==30 && j==14) { errMsg("AAABB","OId"<<OId<<" move "<<u); }
+ // movement?
+ FORDF1 {
+ // TODO optimize, test rho calc necessary?
+ // calculate destination density
+ LbmFloat *dfs = &QCELL_NB(level, i,j,k,workSet,l,dC);
+ rho = RAC(dfs,dC);
+ for(int nl=0; nl<this->cDfNum; nl++) rho += RAC(dfs,nl);
+ //rho = 1.0;
+ const LbmFloat factor = 2.0*this->dfLength[l]*rho* 3.0;
+ ux = this->dfDvecX[l]*u[0];
+ uy = this->dfDvecY[l]*u[1];
+ uz = this->dfDvecZ[l]*u[2];
+ const LbmFloat usqr = (ux*ux+uy*uy+uz*uz)*1.5;
+ USQRMAXCHECK(usqr,ux,uy,uz, mMaxVlen, mMxvx,mMxvy,mMxvz);
+ //ux=uy=uz=0.0; // DEBUG
+ RAC(dstCell,l) = factor*(ux+uy+uz);
+ }
+ } else {
+ FORDF1 { RAC(dstCell,l) = 0.0; }
+ }
+ //errMsg("AAABB","OId"<<OId<<" n"<<n<<" -> "<<PRINT_IJK" u"<<u<<" ul"<<PRINT_VEC(ux,uy,uz) );
+ RAC(dstCell, dFlux) = targetTime;
+ monObsts++;
+ } } // bnd, is active?
+
+ // second pass, remove old ones
+ if(wasActive) {
+ for(size_t n=0; n<verticesOld.size(); n++) {
+ POS2GRID(verticesOld,n);
+ CHECKIJK;
+ monPoints++;
+ if((RFLAG(level, i,j,k, workSet) == otype) &&
+ (QCELL(level, i,j,k, workSet, dFlux) != targetTime)) {
+ //? unused ntlVec3Gfx u= (vertices[n]-verticesOld[n]);
+ // from mainloop
+ nbored = 0;
+#if OPT3D==0
+ FORDF1 {
+ nbflag[l] = RFLAG_NB(level, i,j,k,workSet,l);
+ nbored |= nbflag[l];
+ }
+#else
+ const CellFlagType *pFlagCheck = &RFLAG(level, i,j,k,workSet); // omp
+ nbflag[dSB] = *(pFlagCheck + (-mLevel[level].lOffsy+-mLevel[level].lOffsx)); nbored |= nbflag[dSB];
+ nbflag[dWB] = *(pFlagCheck + (-mLevel[level].lOffsy+-1)); nbored |= nbflag[dWB];
+ nbflag[ dB] = *(pFlagCheck + (-mLevel[level].lOffsy)); nbored |= nbflag[dB];
+ nbflag[dEB] = *(pFlagCheck + (-mLevel[level].lOffsy+ 1)); nbored |= nbflag[dEB];
+ nbflag[dNB] = *(pFlagCheck + (-mLevel[level].lOffsy+ mLevel[level].lOffsx)); nbored |= nbflag[dNB];
+
+ nbflag[dSW] = *(pFlagCheck + (-mLevel[level].lOffsx+-1)); nbored |= nbflag[dSW];
+ nbflag[ dS] = *(pFlagCheck + (-mLevel[level].lOffsx)); nbored |= nbflag[dS];
+ nbflag[dSE] = *(pFlagCheck + (-mLevel[level].lOffsx+ 1)); nbored |= nbflag[dSE];
+
+ nbflag[ dW] = *(pFlagCheck + (-1)); nbored |= nbflag[dW];
+ nbflag[ dE] = *(pFlagCheck + ( 1)); nbored |= nbflag[dE];
+
+ nbflag[dNW] = *(pFlagCheck + ( mLevel[level].lOffsx+-1)); nbored |= nbflag[dNW];
+ nbflag[ dN] = *(pFlagCheck + ( mLevel[level].lOffsx)); nbored |= nbflag[dN];
+ nbflag[dNE] = *(pFlagCheck + ( mLevel[level].lOffsx+ 1)); nbored |= nbflag[dNE];
+
+ nbflag[dST] = *(pFlagCheck + ( mLevel[level].lOffsy+-mLevel[level].lOffsx)); nbored |= nbflag[dST];
+ nbflag[dWT] = *(pFlagCheck + ( mLevel[level].lOffsy+-1)); nbored |= nbflag[dWT];
+ nbflag[ dT] = *(pFlagCheck + ( mLevel[level].lOffsy)); nbored |= nbflag[dT];
+ nbflag[dET] = *(pFlagCheck + ( mLevel[level].lOffsy+ 1)); nbored |= nbflag[dET];
+ nbflag[dNT] = *(pFlagCheck + ( mLevel[level].lOffsy+ mLevel[level].lOffsx)); nbored |= nbflag[dNT];
+ // */
+#endif
+ CellFlagType settype = CFInvalid;
+ LbmFloat avgrho=0.0, avgux=0.0, avguy=0.0, avguz=0.0;
+ if(nbored&CFFluid) {
+ if(nbored&CFInter) {
+ settype = CFInter|CFNoInterpolSrc; rhomass = 0.001;
+ interpolateCellValues(level,i,j,k, workSet, avgrho,avgux,avguy,avguz);
+ } else {
+ // ? dangerous...? settype = CFFluid|CFNoInterpolSrc; rhomass = 1.0;
+ settype = CFInter|CFNoInterpolSrc; rhomass = 1.0;
+ interpolateCellValues(level,i,j,k, workSet, avgrho,avgux,avguy,avguz);
+ }
+ } else {
+ settype = CFEmpty; rhomass = 0.0;
+ }
+ //settype = CFBnd|CFBndNoslip; rhomass = 0.0;
+ //avgux=avguy=avguz=0.0; avgrho=1.0;
+ LbmVec speed(avgux,avguy,avguz);
+ initVelocityCell(level, i,j,k, settype, avgrho, rhomass, speed );
+ monFluids++;
+ } // flag & simtime
+ }
+ } } // bnd, active
+
+ else if(ntype&CFMbndInflow){
+ // inflow pass - add new fluid cells
+ // this is slightly different for standing inflows,
+ // as the fluid is forced to the desired velocity inside as
+ // well...
+ const LbmFloat iniRho = 1.0;
+ const LbmVec vel(mObjectSpeeds[OId]);
+ const LbmFloat usqr = (vel[0]*vel[0]+vel[1]*vel[1]+vel[2]*vel[2])*1.5;
+ USQRMAXCHECK(usqr,vel[0],vel[1],vel[2], mMaxVlen, mMxvx,mMxvy,mMxvz);
+ errMsg("LbmFsgrSolver::initMovingObstacles","id"<<OId<<" "<<obj->getName()<<" inflow "<<staticInit<<" "<<vertices.size() );
+
+ for(size_t n=0; n<vertices.size(); n++) {
+ POS2GRID(vertices,n);
+ CHECKIJK;
+ // TODO - also reinit interface cells !?
+ if(RFLAG(level, i,j,k, workSet)!=CFEmpty) {
+ // test prevent particle gen for inflow inter cells
+ if(RFLAG(level, i,j,k, workSet)&(CFInter)) { RFLAG(level, i,j,k, workSet) &= (~CFNoBndFluid); } // remove CFNoBndFluid flag
+ continue; }
+ monFluids++;
+
+ // TODO add OPT3D treatment
+ LbmFloat *tcel = RACPNT(level, i,j,k,workSet);
+ FORDF0 { RAC(tcel, l) = this->getCollideEq(l, iniRho,vel[0],vel[1],vel[2]); }
+ RAC(tcel, dMass) = RAC(tcel, dFfrac) = iniRho;
+ RAC(tcel, dFlux) = FLUX_INIT;
+ CellFlagType setFlag = CFInter;
+ changeFlag(level, i,j,k, workSet, setFlag);
+ mInitialMass += iniRho;
+ }
+ // second static init pass
+ if(staticInit) {
+ CellFlagType set2Flag = CFMbndInflow|(OId<<24);
+ for(size_t n=0; n<vertices.size(); n++) {
+ POS2GRID(vertices,n);
+ CHECKIJK;
+ if(RFLAG(level, i,j,k, workSet)&(CFMbndInflow|CFMbndOutflow)){ continue; }
+ if(RFLAG(level, i,j,k, workSet)&(CFEmpty)) {
+ changeFlag(level, i,j,k, workSet, set2Flag);
+ } else if(RFLAG(level, i,j,k, workSet)&(CFFluid|CFInter)) {
+ changeFlag(level, i,j,k, workSet, RFLAG(level, i,j,k, workSet)|set2Flag);
+ }
+ }
+ } // second static inflow pass
+
+ } // inflow
+
+ //else if(ntype&CFMbndOutflow){
+ else if(ntype&CFMbndOutflow){
+ const LbmFloat iniRho = 0.0;
+ for(size_t n=0; n<vertices.size(); n++) {
+ POS2GRID(vertices,n);
+ CHECKIJK;
+ // FIXME check fluid/inter cells for non-static!?
+ if(!(RFLAG(level, i,j,k, workSet)&(CFFluid|CFInter))) {
+ if((staticInit)&&(RFLAG(level, i,j,k, workSet)==CFEmpty)) {
+ changeFlag(level, i,j,k, workSet, CFMbndOutflow); }
+ continue;
+ }
+ monFluids++;
+ // interface cell - might be double empty? FIXME check?
+
+ // remove fluid cells, shouldnt be here anyway
+ LbmFloat *tcel = RACPNT(level, i,j,k,workSet);
+ LbmFloat fluidRho = RAC(tcel,0); FORDF1 { fluidRho += RAC(tcel,l); }
+ mInitialMass -= fluidRho;
+ RAC(tcel, dMass) = RAC(tcel, dFfrac) = iniRho;
+ RAC(tcel, dFlux) = FLUX_INIT;
+ CellFlagType setFlag = CFInter;
+ changeFlag(level, i,j,k, workSet, setFlag);
+
+ // same as ifemptied for if below
+ LbmPoint emptyp;
+ emptyp.x = i; emptyp.y = j; emptyp.z = k;
+ mListEmpty.push_back( emptyp );
+ //calcCellsEmptied++;
+ } // points
+ // second static init pass
+ if(staticInit) {
+ CellFlagType set2Flag = CFMbndOutflow|(OId<<24);
+ for(size_t n=0; n<vertices.size(); n++) {
+ POS2GRID(vertices,n);
+ CHECKIJK;
+ if(RFLAG(level, i,j,k, workSet)&(CFMbndInflow|CFMbndOutflow)){ continue; }
+ if(RFLAG(level, i,j,k, workSet)&(CFEmpty)) {
+ changeFlag(level, i,j,k, workSet, set2Flag);
+ } else if(RFLAG(level, i,j,k, workSet)&(CFFluid|CFInter)) {
+ changeFlag(level, i,j,k, workSet, RFLAG(level, i,j,k, workSet)|set2Flag);
+ }
+ }
+ } // second static outflow pass
+ } // outflow
+ }
+ //vector<ntlGeometryObject*> *mpGiObjects;
+ //Obj->getGeoInitType() ){
+ }
+
+
+ /* { // DEBUG check
+ int workSet = mLevel[level].setCurr;
+ FSGR_FORIJK1(level) {
+ if( (RFLAG(level,i,j,k, workSet) & CFBndMoving) ) {
+ if(QCELL(level, i,j,k, workSet, dFlux)!=targetTime) {
+ errMsg("lastt"," old val!? at "<<PRINT_IJK<<" t="<<QCELL(level, i,j,k, workSet, dFlux)<<" target="<<targetTime);
+ }
+ }
+ }
+ } // DEBUG */
+
+#undef CHECKIJK
+#undef POS2GRID
+ myTime_t monend = getTime();
+ errMsg("LbmFsgrSolver::initMovingObstacles","Total: "<<monTotal<<" Points :"<<monPoints<<" ObstInits:"<<monObsts<<" FlInits:"<<monFluids<<" Trafos:"<<monTotal<<", took "<<getTimeString(monend-monstart));
+ mLastSimTime = targetTime;
+}
+
+
/*****************************************************************************/
/*! perform geometry init (if switched on) */
/*****************************************************************************/
extern int globGeoInitDebug; //solver_interface
-template<class D>
-bool
-LbmFsgrSolver<D>::initGeometryFlags() {
+bool LbmFsgrSolver::initGeometryFlags() {
int level = mMaxRefine;
myTime_t geotimestart = getTime();
ntlGeometryObject *pObj;
// getCellSize (due to forced cubes, use x values)
- ntlVec3Gfx dvec( (D::mvGeoEnd[0]-D::mvGeoStart[0])/ ((LbmFloat)D::mSizex*2.0));
- bool thinHit = false;
+ //ntlVec3Gfx dvec; //( (this->mvGeoEnd[0]-this->mvGeoStart[0])/ ((LbmFloat)this->mSizex*2.0));
+ //bool thinHit = false;
// real cell size from now on...
- dvec *= 2.0;
- ntlVec3Gfx nodesize = ntlVec3Gfx(mLevel[level].nodeSize); //dvec*1.0;
- dvec = nodesize;
- debMsgStd("LbmFsgrSolver::initGeometryFlags",DM_MSG,"Performing geometry init ("<< D::mGeoInitId <<") v"<<dvec,3);
+ //dvec *= 2.0;
+ //ntlVec3Gfx nodesize = ntlVec3Gfx(mLevel[level].nodeSize); //dvec*1.0;
+ //dvec = nodesize;
+ ntlVec3Gfx dvec = ntlVec3Gfx(mLevel[level].nodeSize); //dvec*1.0;
+ debMsgStd("LbmFsgrSolver::initGeometryFlags",DM_MSG,"Performing geometry init ("<< this->mGeoInitId <<") v"<<dvec,3);
+ // WARNING - copied to movobj init!
/* init object velocities, this has always to be called for init */
- D::initGeoTree(D::mGeoInitId);
- if(D::mAllfluid) {
- D::freeGeoTree();
+ this->initGeoTree(this->mGeoInitId);
+ if(this->mAllfluid) {
+ this->freeGeoTree();
return true; }
- ntlVec3Gfx maxIniVel = vec2G( D::mpParam->calculateLattVelocityFromRw( vec2P(D::getGeoMaxInitialVelocity()) ));
- D::mpParam->setSimulationMaxSpeed( norm(maxIniVel) + norm(mLevel[level].gravity) );
- LbmFloat allowMax = D::mpParam->getTadapMaxSpeed(); // maximum allowed velocity
- debMsgStd("LbmFsgrSolver::initGeometryFlags",DM_MSG,"Maximum Velocity from geo init="<< maxIniVel <<", allowed Max="<<allowMax ,5);
- if(D::mpParam->getSimulationMaxSpeed() > allowMax) {
+ // make sure moving obstacles are inited correctly
+ // preinit moving obj points
+ int numobjs = (int)(this->mpGiObjects->size());
+ for(int o=0; o<numobjs; o++) {
+ ntlGeometryObject *obj = (*this->mpGiObjects)[o];
+ if(
+ ((obj->getGeoInitType()&FGI_ALLBOUNDS) && (obj->getIsAnimated())) ||
+ (obj->getOnlyThinInit()) ) {
+ obj->initMovingPoints(mLevel[mMaxRefine].nodeSize);
+ }
+ }
+
+ // max speed init
+ ntlVec3Gfx maxMovobjVelRw = this->getGeoMaxMovementVelocity( mSimulationTime, this->mpParam->getTimestep() );
+ ntlVec3Gfx maxMovobjVel = vec2G( this->mpParam->calculateLattVelocityFromRw( vec2P( maxMovobjVelRw )) );
+ this->mpParam->setSimulationMaxSpeed( norm(maxMovobjVel) + norm(mLevel[level].gravity) );
+ LbmFloat allowMax = this->mpParam->getTadapMaxSpeed(); // maximum allowed velocity
+ debMsgStd("LbmFsgrSolver::initGeometryFlags",DM_MSG,"Maximum Velocity from geo init="<< maxMovobjVel <<" from mov. obj.="<<maxMovobjVelRw<<" , allowed Max="<<allowMax ,5);
+ if(this->mpParam->getSimulationMaxSpeed() > allowMax) {
// similar to adaptTimestep();
- LbmFloat nextmax = D::mpParam->getSimulationMaxSpeed();
- LbmFloat newdt = D::mpParam->getStepTime() * (allowMax / nextmax); // newtr
- debMsgStd("LbmFsgrSolver::initGeometryFlags",DM_MSG,"Performing reparametrization, newdt="<< newdt<<" prevdt="<< D::mpParam->getStepTime() <<" ",5);
- D::mpParam->setDesiredStepTime( newdt );
- D::mpParam->calculateAllMissingValues( D::mSilent );
- maxIniVel = vec2G( D::mpParam->calculateLattVelocityFromRw( vec2P(D::getGeoMaxInitialVelocity()) ));
- debMsgStd("LbmFsgrSolver::initGeometryFlags",DM_MSG,"New maximum Velocity from geo init="<< maxIniVel,5);
+ LbmFloat nextmax = this->mpParam->getSimulationMaxSpeed();
+ LbmFloat newdt = this->mpParam->getTimestep() * (allowMax / nextmax); // newtr
+ debMsgStd("LbmFsgrSolver::initGeometryFlags",DM_MSG,"Performing reparametrization, newdt="<< newdt<<" prevdt="<< this->mpParam->getTimestep() <<" ",5);
+ this->mpParam->setDesiredTimestep( newdt );
+ this->mpParam->calculateAllMissingValues( mSimulationTime, this->mSilent );
+ //maxIniVel = vec2G( this->mpParam->calculateLattVelocityFromRw( vec2P(this->getGeoMaxInitialVelocity()) ));
+ maxMovobjVel = vec2G( this->mpParam->calculateLattVelocityFromRw( vec2P(this->getGeoMaxMovementVelocity(
+ mSimulationTime, this->mpParam->getTimestep() )) ));
+ debMsgStd("LbmFsgrSolver::initGeometryFlags",DM_MSG,"New maximum Velocity from geo init="<< maxMovobjVel,5);
}
recalculateObjectSpeeds();
// */
+ // init obstacles for first time step (requires obj speeds)
+ initMovingObstacles(true);
+
/* set interface cells */
ntlVec3Gfx pos,iniPos; // position of current cell
LbmFloat rhomass = 0.0;
+ CellFlagType ntype = CFInvalid;
int savedNodes = 0;
int OId = -1;
gfxReal distance;
// 2d display as rectangles
- if(D::cDimension==2) {
+ if(LBMDIM==2) {
dvec[2] = 0.0;
- iniPos =(D::mvGeoStart + ntlVec3Gfx( 0.0, 0.0, (D::mvGeoEnd[2]-D::mvGeoStart[2])*0.5 ))-(dvec*0.0);
- //iniPos =(D::mvGeoStart + ntlVec3Gfx( 0.0 ))+dvec;
+ iniPos =(this->mvGeoStart + ntlVec3Gfx( 0.0, 0.0, (this->mvGeoEnd[2]-this->mvGeoStart[2])*0.5 ))+(dvec*0.5);
} else {
- iniPos =(D::mvGeoStart + ntlVec3Gfx( 0.0 ))-(dvec*0.0);
- iniPos[2] = D::mvGeoStart[2] + dvec[2]*getForZMin1();
+ iniPos =(this->mvGeoStart + ntlVec3Gfx( 0.0 ))+(dvec*0.5);
}
// first init boundary conditions
+ // invalid cells are set to empty afterwards
#define GETPOS(i,j,k) \
ntlVec3Gfx( iniPos[0]+ dvec[0]*(gfxReal)(i), \
iniPos[1]+ dvec[1]*(gfxReal)(j), \
@@ -817,23 +1473,34 @@ LbmFsgrSolver<D>::initGeometryFlags() {
for(int k= getForZMin1(); k< getForZMax1(level); ++k) {
for(int j=1;j<mLevel[level].lSizey-1;j++) {
for(int i=1;i<mLevel[level].lSizex-1;i++) {
- CellFlagType ntype = CFInvalid;
+ ntype = CFInvalid;
- if(D::geoInitCheckPointInside( GETPOS(i,j,k) , FGI_ALLBOUNDS, OId, distance)) {
- //if(D::geoInitCheckPointInside( GETPOS(i,j,k) , ntlVec3Gfx(1.0,0.0,0.0), FGI_ALLBOUNDS, OId, distance, dvec[0]*0.5, thinHit, true)) {
- pObj = (*D::mpGiObjects)[OId];
+ const bool inside = this->geoInitCheckPointInside( GETPOS(i,j,k) , FGI_ALLBOUNDS, OId, distance);
+ // = this->geoInitCheckPointInside( GETPOS(i,j,k) , ntlVec3Gfx(1.0,0.0,0.0), FGI_ALLBOUNDS, OId, distance, dvec[0]*0.5, thinHit, true);
+ //if(this->geoInitCheckPointInside( GETPOS(i,j,k) , FGI_ALLBOUNDS, OId, distance)) {
+ if(inside) {
+ pObj = (*this->mpGiObjects)[OId];
switch( pObj->getGeoInitType() ){
case FGI_MBNDINFLOW:
- rhomass = 1.0;
- ntype = CFFluid|CFMbndInflow;
+ if(! pObj->getIsAnimated() ) {
+ rhomass = 1.0;
+ ntype = CFFluid | CFMbndInflow;
+ } else {
+ ntype = CFInvalid;
+ }
break;
case FGI_MBNDOUTFLOW:
- rhomass = 0.0;
- ntype = CFEmpty|CFMbndOutflow;
+ if(! pObj->getIsAnimated() ) {
+ rhomass = 0.0;
+ ntype = CFEmpty|CFMbndOutflow;
+ } else {
+ ntype = CFInvalid;
+ }
break;
case FGI_BNDNO:
rhomass = BND_FILL;
- ntype = CFBnd|CFBndNoslip; break;
+ ntype = CFBnd|CFBndNoslip;
+ break;
case FGI_BNDFREE:
rhomass = BND_FILL;
ntype = CFBnd|CFBndFreeslip; break;
@@ -869,140 +1536,17 @@ LbmFsgrSolver<D>::initGeometryFlags() {
} // zmax
// */
- /*
- for(int k= getForZMin1(); k< getForZMax1(level); ++k) {
- for(int i=1;i<mLevel[level].lSizex-1;i++) {
- for(int j=1;j<mLevel[level].lSizey-1;j++) {
- //errMsg("INIT0","at "<<PRINT_IJK<<" p="<<GETPOS(i,j,k)<<" j"<<j<<" "<<mLevel[level].lSizey);
- //if(!(RFLAG(level, i,j,k, mLevel[level].setCurr)==CFEmpty)) continue;
- CellFlagType ntype = CFInvalid;
- //errMsg("INIT1","at "<<PRINT_IJK<<" p="<<GETPOS(i,j,k));
- //if(D::geoInitCheckPointInside( GETPOS(i,j,k) , ntlVec3Gfx(0.0,1.0,0.0), FGI_ALLBOUNDS, OId, distance, dvec[1]*0.5)) {
- if(D::geoInitCheckPointInside( GETPOS(i,j,k) , ntlVec3Gfx(0.0,1.0,0.0), FGI_ALLBOUNDS, OId, distance, dvec[1]*0.5, thinHit, true)) {
- pObj = (*D::mpGiObjects)[OId];
- switch( pObj->getGeoInitType() ){
- case FGI_MBNDINFLOW:
- rhomass = 1.0;
- ntype = CFFluid|CFMbndInflow;
- break;
- case FGI_MBNDOUTFLOW:
- rhomass = 0.0;
- ntype = CFEmpty|CFMbndOutflow;
- break;
- default:
- rhomass = BND_FILL;
- ntype = CFBnd; break;
- }
- }
- if(ntype != CFInvalid) {
- // initDefaultCell
- if((ntype & CFMbndInflow) || (ntype & CFMbndOutflow) ) {
- ntype |= (OId<<24);
- }
- initVelocityCell(level, i,j,k, ntype, rhomass, rhomass, mObjectSpeeds[OId] );
- }
- //errMsg("INITT","at "<<PRINT_IJK<<" t="<<ntype<<" d="<<distance);
-
- // walk along x until hit for following inits
- if(distance<=-1.0) { distance = 100.0; }
- if(distance>=0.0) {
- gfxReal dcnt=dvec[1];
- while(( dcnt< distance-dvec[1] )&&(j+1<mLevel[level].lSizey-1)) {
- dcnt += dvec[1]; j++;
- //if(!(RFLAG(level, i,j,k, mLevel[level].setCurr)==CFEmpty)) continue;
- savedNodes++;
- if(ntype != CFInvalid) {
- // rho,mass,OId are still inited from above
- initVelocityCell(level, i,j,k, ntype, rhomass, rhomass, mObjectSpeeds[OId] );
- }
- }
- }
-
- }
- }
- } // zmax, j
- // */
-
-
- /*
- for(int j=1;j<mLevel[level].lSizey-1;j++) {
- for(int i=1;i<mLevel[level].lSizex-1;i++) {
- for(int k= getForZMin1(); k< getForZMax1(level); ++k) {
- //if(!(RFLAG(level, i,j,k, mLevel[level].setCurr)==CFEmpty)) continue;
- CellFlagType ntype = CFInvalid;
- if(D::geoInitCheckPointInside( GETPOS(i,j,k) , ntlVec3Gfx(0.0,0.0,1.0), FGI_ALLBOUNDS, OId, distance, dvec[2]*0.5, thinHit, true)) {
- pObj = (*D::mpGiObjects)[OId];
- switch( pObj->getGeoInitType() ){
- case FGI_MBNDINFLOW:
- rhomass = 1.0;
- ntype = CFFluid|CFMbndInflow;
- break;
- case FGI_MBNDOUTFLOW:
- rhomass = 0.0;
- ntype = CFEmpty|CFMbndOutflow;
- break;
- default:
- rhomass = BND_FILL;
- ntype = CFBnd; break;
- }
- }
- if(ntype != CFInvalid) {
- // initDefaultCell
- if((ntype & CFMbndInflow) || (ntype & CFMbndOutflow) ) {
- ntype |= (OId<<24);
- }
- initVelocityCell(level, i,j,k, ntype, rhomass, rhomass, mObjectSpeeds[OId] );
- }
- errMsg("INITZ","at "<<PRINT_IJK<<" t="<<ntype<<" d="<<distance);
-
- // walk along x until hit for following inits
- if(distance<=-1.0) { distance = 100.0; }
- if(distance>=0.0) {
- gfxReal dcnt=dvec[2];
- while(( dcnt< distance-dvec[2] )&&(k+1<mLevel[level].lSizez-1)) {
- dcnt += dvec[2]; k++;
- //if(!(RFLAG(level, i,j,k, mLevel[level].setCurr)==CFEmpty)) continue;
- savedNodes++;
- if(ntype != CFInvalid) {
- // rho,mass,OId are still inited from above
- initVelocityCell(level, i,j,k, ntype, rhomass, rhomass, mObjectSpeeds[OId] );
- }
- }
- } // *
-
- }
- }
- } // zmax, k
- // */
- thinHit = false;
-
-
// now init fluid layer
for(int k= getForZMin1(); k< getForZMax1(level); ++k) {
for(int j=1;j<mLevel[level].lSizey-1;j++) {
for(int i=1;i<mLevel[level].lSizex-1;i++) {
if(!(RFLAG(level, i,j,k, mLevel[level].setCurr)==CFEmpty)) continue;
-
- CellFlagType ntype = CFInvalid;
+ ntype = CFInvalid;
int inits = 0;
- // DEBUG
- if((j==mLevel[level].lSizey/2)&&(k==getForZMax1(level)*7/10)) globGeoInitDebug=1;
- else globGeoInitDebug=0;
- //errMsg("AAA","j"<<j<<"|"<<(mLevel[level].lSizey/2)<<" k"<<k<<"|"<<(getForZMax1(level)*7/10)<<" gd"<<globGeoInitDebug);
-
- if((i==1) && (j==31) && (k==48)) globGeoInitDebug=1;
- else globGeoInitDebug=0;
- bool inside = D::geoInitCheckPointInside( GETPOS(i,j,k) , FGI_FLUID, OId, distance);
- /*if((i==1) && (j==31) && (inside)) {
- globGeoInitDebug=1;
- D::geoInitCheckPointInside( GETPOS(i,j,k) , FGI_FLUID, OId, distance);
- globGeoInitDebug=0;
- errMsg("III"," i1 at "<<PRINT_IJK);
- } // DEBUG */
+ //if((i==1) && (j==31) && (k==48)) globGeoInitDebug=1;
+ //else globGeoInitDebug=0;
+ const bool inside = this->geoInitCheckPointInside( GETPOS(i,j,k) , FGI_FLUID, OId, distance);
if(inside) {
- // DEBUG
-
- //if(D::geoInitCheckPointInside( GETPOS(i,j,k) , FGI_FLUID, OId, distance)) {
ntype = CFFluid;
}
if(ntype != CFInvalid) {
@@ -1032,19 +1576,30 @@ LbmFsgrSolver<D>::initGeometryFlags() {
}
} // zmax
- D::freeGeoTree();
+ // reset invalid to empty again
+ for(int k= getForZMin1(); k< getForZMax1(level); ++k) {
+ for(int j=1;j<mLevel[level].lSizey-1;j++) {
+ for(int i=1;i<mLevel[level].lSizex-1;i++) {
+ if(RFLAG(level, i,j,k, mLevel[level].setCurr)==CFInvalid) {
+ RFLAG(level, i,j,k, mLevel[level].setOther) =
+ RFLAG(level, i,j,k, mLevel[level].setCurr) = CFEmpty;
+ }
+ }
+ }
+ }
+
+ this->freeGeoTree();
myTime_t geotimeend = getTime();
- debMsgStd("LbmFsgrSolver::initGeometryFlags",DM_MSG,"Geometry init done ("<< ((geotimeend-geotimestart)/(double)1000.0)<<"s,"<<savedNodes<<") " , 10 );
+ debMsgStd("LbmFsgrSolver::initGeometryFlags",DM_MSG,"Geometry init done ("<< getTimeString(geotimeend-geotimestart)<<","<<savedNodes<<") " , 10 );
//errMsg(" SAVED "," "<<savedNodes<<" of "<<(mLevel[mMaxRefine].lSizex*mLevel[mMaxRefine].lSizey*mLevel[mMaxRefine].lSizez));
return true;
}
/*****************************************************************************/
/* init part for all freesurface testcases */
-template<class D>
-void
-LbmFsgrSolver<D>::initFreeSurfaces() {
+void LbmFsgrSolver::initFreeSurfaces() {
double interfaceFill = 0.45; // filling level of interface cells
+ //interfaceFill = 1.0; // DEUG!! GEOMTEST!!!!!!!!!!!!
// set interface cells
FSGR_FORIJK1(mMaxRefine) {
@@ -1093,7 +1648,7 @@ LbmFsgrSolver<D>::initFreeSurfaces() {
initEmptyCell(mMaxRefine, i,j,k, CFFluid, 1.0, 1.0);
}
} // interface
- }
+ } // */
// another brute force init, make sure the fill values are right...
// and make sure both sets are equal
@@ -1112,35 +1667,53 @@ LbmFsgrSolver<D>::initFreeSurfaces() {
// ----------------------------------------------------------------------
// smoother surface...
if(mInitSurfaceSmoothing>0) {
- debMsgStd("Surface Smoothing init", DM_MSG, "Performing "<<(mInitSurfaceSmoothing)<<" smoothing steps ",10);
+ debMsgStd("Surface Smoothing init", DM_MSG, "Performing "<<(mInitSurfaceSmoothing)<<" smoothing timestep ",10);
#if COMPRESSGRIDS==1
- errFatal("NYI","COMPRESSGRIDS mInitSurfaceSmoothing",SIMWORLD_INITERROR); return;
+ //errFatal("NYI","COMPRESSGRIDS mInitSurfaceSmoothing",SIMWORLD_INITERROR); return;
#endif // COMPRESSGRIDS==0
}
for(int s=0; s<mInitSurfaceSmoothing; s++) {
- FSGR_FORIJK1(mMaxRefine) {
- if( TESTFLAG( RFLAG(mMaxRefine, i,j,k, mLevel[mMaxRefine].setCurr), CFInter) ) {
+ //SGR_FORIJK1(mMaxRefine) {
+
+ int kstart=getForZMin1(), kend=getForZMax1(mMaxRefine);
+ int lev = mMaxRefine;
+#if COMPRESSGRIDS==0
+ for(int k=kstart;k<kend;++k) {
+#else // COMPRESSGRIDS==0
+ int kdir = 1; // COMPRT ON
+ if(mLevel[lev].setCurr==1) {
+ kdir = -1;
+ int temp = kend;
+ kend = kstart-1;
+ kstart = temp-1;
+ } // COMPRT
+ for(int k=kstart;k!=kend;k+=kdir) {
+#endif // COMPRESSGRIDS==0
+ for(int j=1;j<mLevel[lev].lSizey-1;++j) {
+ for(int i=1;i<mLevel[lev].lSizex-1;++i) {
+ if( TESTFLAG( RFLAG(lev, i,j,k, mLevel[lev].setCurr), CFInter) ) {
LbmFloat mass = 0.0;
//LbmFloat nbdiv;
- FORDF0 {
- int ni=i+D::dfVecX[l], nj=j+D::dfVecY[l], nk=k+D::dfVecZ[l];
- if( RFLAG(mMaxRefine, ni,nj,nk, mLevel[mMaxRefine].setCurr) & CFFluid ){
+ //FORDF0 {
+ for(int l=0;(l<this->cDirNum); l++) {
+ int ni=i+this->dfVecX[l], nj=j+this->dfVecY[l], nk=k+this->dfVecZ[l];
+ if( RFLAG(lev, ni,nj,nk, mLevel[lev].setCurr) & CFFluid ){
mass += 1.0;
}
- if( RFLAG(mMaxRefine, ni,nj,nk, mLevel[mMaxRefine].setCurr) & CFInter ){
- mass += QCELL(mMaxRefine, ni,nj,nk, mLevel[mMaxRefine].setCurr, dMass);
+ if( RFLAG(lev, ni,nj,nk, mLevel[lev].setCurr) & CFInter ){
+ mass += QCELL(lev, ni,nj,nk, mLevel[lev].setCurr, dMass);
}
//nbdiv+=1.0;
}
//errMsg(" I ", PRINT_IJK<<" m"<<mass );
- QCELL(mMaxRefine, i,j,k, mLevel[mMaxRefine].setOther, dMass) = (mass/19.0);
- QCELL(mMaxRefine, i,j,k, mLevel[mMaxRefine].setOther, dFfrac) = QCELL(mMaxRefine, i,j,k, mLevel[mMaxRefine].setOther, dMass);
+ QCELL(lev, i,j,k, mLevel[lev].setOther, dMass) = (mass/ ((LbmFloat)this->cDirNum) );
+ QCELL(lev, i,j,k, mLevel[lev].setOther, dFfrac) = QCELL(lev, i,j,k, mLevel[lev].setOther, dMass);
}
- }
+ }}}
- mLevel[mMaxRefine].setOther = mLevel[mMaxRefine].setCurr;
- mLevel[mMaxRefine].setCurr ^= 1;
+ mLevel[lev].setOther = mLevel[lev].setCurr;
+ mLevel[lev].setCurr ^= 1;
}
// copy back...?
@@ -1148,9 +1721,7 @@ LbmFsgrSolver<D>::initFreeSurfaces() {
/*****************************************************************************/
/* init part for all freesurface testcases */
-template<class D>
-void
-LbmFsgrSolver<D>::initStandingFluidGradient() {
+void LbmFsgrSolver::initStandingFluidGradient() {
// ----------------------------------------------------------------------
// standing fluid preinit
const int debugStandingPreinit = 0;
@@ -1203,7 +1774,8 @@ LbmFsgrSolver<D>::initStandingFluidGradient() {
GRAVLOOP {
int i = gravIndex[0], j = gravIndex[1], k = gravIndex[2];
if( ( (RFLAG(mMaxRefine,i,j,k,mLevel[mMaxRefine].setCurr) & (CFInter)) ) ||
- ( (RFLAG(mMaxRefine,i,j,k,mLevel[mMaxRefine].setCurr) & (CFEmpty)) ) ){
+ ( (RFLAG(mMaxRefine,i,j,k,mLevel[mMaxRefine].setCurr) & (CFBndMoving)) ) ||
+ ( (RFLAG(mMaxRefine,i,j,k,mLevel[mMaxRefine].setCurr) & (CFEmpty)) ) ) {
int fluidHeight = (ABS(gravIndex[maxGravComp] - gravIMin[maxGravComp]));
if(debugStandingPreinit) errMsg("Standing fp","fh="<<fluidHeight<<" gmax="<<gravIMax[maxGravComp]<<" gi="<<gravIndex[maxGravComp] );
if(fluidHeight>1) {
@@ -1217,8 +1789,8 @@ LbmFsgrSolver<D>::initStandingFluidGradient() {
LbmFloat fluidHeight;
fluidHeight = (LbmFloat)(ABS(gravIMax[maxGravComp]-gravIMin[maxGravComp]));
-#if ELBEEM_PLUGIN!=1
- mpTest->mFluidHeight = (int)fluidHeight;
+#if LBM_INCLUDE_TESTSOLVERS==1
+ if(mUseTestdata) mpTest->mFluidHeight = (int)fluidHeight;
#endif // ELBEEM_PLUGIN!=1
if(debugStandingPreinit) debMsgStd("Standing fluid preinit", DM_MSG, "fheight="<<fluidHeight<<" min="<<PRINT_VEC(gravIMin[0],gravIMin[1], gravIMin[2])<<" max="<<PRINT_VEC(gravIMax[0], gravIMax[1],gravIMax[2])<<
" mgc="<<maxGravComp<<" mc1="<<gravComp1<<" mc2="<<gravComp2<<" dir="<<gravDir[maxGravComp]<<" have="<<haveStandingFluid ,10);
@@ -1286,10 +1858,22 @@ LbmFsgrSolver<D>::initStandingFluidGradient() {
debMsgStd("Standing fluid preinit", DM_MSG, "Density gradient inited (max-rho:"<<
(1.0+ (fluidHeight) * (mLevel[lev].gravity[maxGravComp])* (-3.0/1.0)*(mLevel[lev].omega)) <<", h:"<< fluidHeight<<") ", 8);
+#if ELBEEM_PLUGIN!=1 && LBMDIM==3
+ /*int lowj = 0;
+ for(int k=1;k<mLevel[lev].lSizez-1;++k) {
+ for(int i=1;i<mLevel[lev].lSizex-1;++i) {
+ LbmFloat rho = 1.0+ (fluidHeight) * (mLevel[lev].gravity[maxGravComp])* (-3.0/1.0)*(mLevel[lev].omega);
+ RFLAG(lev, i,lowj,k, rhoworkSet^1) =
+ RFLAG(lev, i,lowj,k, rhoworkSet) = CFFluid;
+ FORDF0 { QCELL(lev, i,lowj,k, rhoworkSet, l) = this->dfEquil[l]*rho; }
+ QCELL(lev, i,lowj,k, rhoworkSet, dMass) = rho;
+ } } // */
+#endif
+
int preinitSteps = (haveStandingFluid* ((mLevel[lev].lSizey+mLevel[lev].lSizez+mLevel[lev].lSizex)/3) );
preinitSteps = (haveStandingFluid>>2); // not much use...?
//preinitSteps = 4; // DEBUG!!!!
- //D::mInitDone = 1; // GRAVTEST
+ //this->mInitDone = 1; // GRAVTEST
//preinitSteps = 0;
debMsgNnl("Standing fluid preinit", DM_MSG, "Performing "<<preinitSteps<<" prerelaxations ",10);
for(int s=0; s<preinitSteps; s++) {
@@ -1316,8 +1900,6 @@ LbmFsgrSolver<D>::initStandingFluidGradient() {
kstart = temp-1;
} // COMPRT
for(int k=kstart;k!=kend;k+=kdir) {
-
- //errMsg("LbmFsgrSolver::mainLoop","k="<<k<<" ks="<<kstart<<" ke="<<kend<<" kdir="<<kdir ); // debug
#endif // COMPRESSGRIDS==0
for(int j=0;j<mLevel[lev].lSizey-0;++j) {
@@ -1349,20 +1931,18 @@ LbmFsgrSolver<D>::initStandingFluidGradient() {
mLevel[lev].setOther = mLevel[lev].setCurr;
mLevel[lev].setCurr ^= 1;
}
- //D::mInitDone = 0; // GRAVTEST
+ //this->mInitDone = 0; // GRAVTEST
// */
myTime_t timeend = getTime();
- debMsgDirect(" done, "<<((timeend-timestart)/(double)1000.0)<<"s \n");
+ debMsgDirect(" done, "<<getTimeString(timeend-timestart)<<" \n");
#undef NBFLAG
}
}
-template<class D>
-bool
-LbmFsgrSolver<D>::checkSymmetry(string idstring)
+bool LbmFsgrSolver::checkSymmetry(string idstring)
{
bool erro = false;
bool symm = true;
@@ -1388,7 +1968,7 @@ LbmFsgrSolver<D>::checkSymmetry(string idstring)
if(lev==mMaxRefine) inb -= 1; // FSGR_SYMM_T
if( RFLAG(lev, i,j,k,s) != RFLAG(lev, inb,j,k,s) ) { erro = true;
- if(D::cDimension==2) {
+ if(LBMDIM==2) {
if(msgs<maxMsgs) { msgs++;
errMsg("EFLAG", PRINT_IJK<<"s"<<s<<" flag "<<RFLAG(lev, i,j,k,s)<<" , at "<<PRINT_VEC(inb,j,k)<<"s"<<s<<" flag "<<RFLAG(lev, inb,j,k,s) );
}
@@ -1397,7 +1977,7 @@ LbmFsgrSolver<D>::checkSymmetry(string idstring)
symm = false;
}
if( LBM_FLOATNEQ(QCELL(lev, i,j,k,s, dMass), QCELL(lev, inb,j,k,s, dMass)) ) { erro = true;
- if(D::cDimension==2) {
+ if(LBMDIM==2) {
if(msgs<maxMsgs) { msgs++;
//debMsgDirect(" mass1 "<<QCELL(lev, i,j,k,s, dMass)<<" mass2 "<<QCELL(lev, inb,j,k,s, dMass) <<std::endl);
errMsg("EMASS", PRINT_IJK<<"s"<<s<<" mass "<<QCELL(lev, i,j,k,s, dMass)<<" , at "<<PRINT_VEC(inb,j,k)<<"s"<<s<<" mass "<<QCELL(lev, inb,j,k,s, dMass) );
@@ -1412,7 +1992,7 @@ LbmFsgrSolver<D>::checkSymmetry(string idstring)
LbmFloat otrho = QCELL(lev, inb,j,k, s, dC);
FORDF1 { otrho += QCELL(lev, inb,j,k, s, l); }
if( LBM_FLOATNEQ(nbrho, otrho) ) { erro = true;
- if(D::cDimension==2) {
+ if(LBMDIM==2) {
if(msgs<maxMsgs) { msgs++;
//debMsgDirect(" rho 1 "<<nbrho <<" rho 2 "<<otrho <<std::endl);
errMsg("ERHO ", PRINT_IJK<<"s"<<s<<" rho "<<nbrho <<" , at "<<PRINT_VEC(inb,j,k)<<"s"<<s<<" rho "<<otrho );
@@ -1427,7 +2007,7 @@ LbmFsgrSolver<D>::checkSymmetry(string idstring)
LbmFloat maxdiv =0.0;
if(erro) {
errMsg("SymCheck Failed!", idstring<<" rho maxdiv:"<< maxdiv );
- //if(D::cDimension==2) D::mPanic = true;
+ //if(LBMDIM==2) this->mPanic = true;
//return false;
} else {
errMsg("SymCheck OK!", idstring<<" rho maxdiv:"<< maxdiv );
@@ -1436,24 +2016,56 @@ LbmFsgrSolver<D>::checkSymmetry(string idstring)
return symm;
}// */
-#endif // !defined(__APPLE_CC__) || defined(LBM_FORCEINCLUDE)
-
-
-/******************************************************************************
- * instantiation
- *****************************************************************************/
-
-#if ((!defined(__APPLE_CC__)) && (!defined(__INTEL_COMPILER))) && (!defined(LBM_FORCEINCLUDE))
-#if LBMDIM==2
-#define LBM_INSTANTIATE LbmBGK2D
-#endif // LBMDIM==2
-#if LBMDIM==3
-#define LBM_INSTANTIATE LbmBGK3D
-#endif // LBMDIM==3
+void
+LbmFsgrSolver::interpolateCellValues(
+ int level,int ei,int ej,int ek,int workSet,
+ LbmFloat &retrho, LbmFloat &retux, LbmFloat &retuy, LbmFloat &retuz)
+{
+ LbmFloat avgrho = 0.0;
+ LbmFloat avgux = 0.0, avguy = 0.0, avguz = 0.0;
+ LbmFloat cellcnt = 0.0;
+ LbmFloat avgnbdf[LBM_DFNUM];
+ FORDF0M { avgnbdf[m]= 0.0; }
+
+ for(int nbl=1; nbl< this->cDfNum ; ++nbl) {
+ if( (RFLAG_NB(level,ei,ej,ek,workSet,nbl) & CFFluid) ||
+ ((!(RFLAG_NB(level,ei,ej,ek,workSet,nbl) & CFNoInterpolSrc) ) &&
+ (RFLAG_NB(level,ei,ej,ek,workSet,nbl) & CFInter) )) {
+ cellcnt += 1.0;
+ for(int rl=0; rl< this->cDfNum ; ++rl) {
+ LbmFloat nbdf = QCELL_NB(level,ei,ej,ek, workSet,nbl, rl);
+ avgnbdf[rl] += nbdf;
+ avgux += (this->dfDvecX[rl]*nbdf);
+ avguy += (this->dfDvecY[rl]*nbdf);
+ avguz += (this->dfDvecZ[rl]*nbdf);
+ avgrho += nbdf;
+ }
+ }
+ }
-template class LbmFsgrSolver< LBM_INSTANTIATE >;
+ if(cellcnt<=0.0) {
+ // no nbs? just use eq.
+ //FORDF0 { QCELL(level,ei,ej,ek, workSet, l) = this->dfEquil[l]; }
+ avgrho = 1.0;
+ avgux = avguy = avguz = 0.0;
+ //TTT mNumProblems++;
+#if ELBEEM_PLUGIN!=1
+ //this->mPanic=1;
+ // this can happen for worst case moving obj scenarios...
+ errMsg("LbmFsgrSolver::interpolateCellValues","Cellcnt<=0.0 at "<<PRINT_VEC(ei,ej,ek)); //,SIMWORLD_GENERICERROR);
+#endif // ELBEEM_PLUGIN
+ } else {
+ // init speed
+ avgux /= cellcnt; avguy /= cellcnt; avguz /= cellcnt;
+ avgrho /= cellcnt;
+ FORDF0M { avgnbdf[m] /= cellcnt; } // CHECK FIXME test?
+ }
-#endif // __APPLE_CC__ __INTEL_COMPILER
+ retrho = avgrho;
+ retux = avgux;
+ retuy = avguy;
+ retuz = avguz;
+} // interpolateCellValues
diff --git a/intern/elbeem/intern/solver_interface.cpp b/intern/elbeem/intern/solver_interface.cpp
index 1de27d4beec..04e0456286b 100644
--- a/intern/elbeem/intern/solver_interface.cpp
+++ b/intern/elbeem/intern/solver_interface.cpp
@@ -12,284 +12,11 @@
/* LBM Files */
#include "solver_interface.h"
-#include "ntl_scene.h"
#include "ntl_ray.h"
+#include "ntl_world.h"
#include "elbeem.h"
-/*****************************************************************************/
-//! common variables
-
-/*****************************************************************************/
-/*! class for solver templating - 3D implementation D3Q19 */
-
- //! how many dimensions?
- const int LbmD3Q19::cDimension = 3;
-
- // Wi factors for collide step
- const LbmFloat LbmD3Q19::cCollenZero = (1.0/3.0);
- const LbmFloat LbmD3Q19::cCollenOne = (1.0/18.0);
- const LbmFloat LbmD3Q19::cCollenSqrtTwo = (1.0/36.0);
-
- //! threshold value for filled/emptied cells
- const LbmFloat LbmD3Q19::cMagicNr2 = 1.0005;
- const LbmFloat LbmD3Q19::cMagicNr2Neg = -0.0005;
- const LbmFloat LbmD3Q19::cMagicNr = 1.010001;
- const LbmFloat LbmD3Q19::cMagicNrNeg = -0.010001;
-
- //! size of a single set of distribution functions
- const int LbmD3Q19::cDfNum = 19;
- //! direction vector contain vecs for all spatial dirs, even if not used for LBM model
- const int LbmD3Q19::cDirNum = 27;
-
- //const string LbmD3Q19::dfString[ cDfNum ] = {
- const char* LbmD3Q19::dfString[ cDfNum ] = {
- " C", " N"," S"," E"," W"," T"," B",
- "NE","NW","SE","SW",
- "NT","NB","ST","SB",
- "ET","EB","WT","WB"
- };
-
- const int LbmD3Q19::dfNorm[ cDfNum ] = {
- cDirC, cDirN, cDirS, cDirE, cDirW, cDirT, cDirB,
- cDirNE, cDirNW, cDirSE, cDirSW,
- cDirNT, cDirNB, cDirST, cDirSB,
- cDirET, cDirEB, cDirWT, cDirWB
- };
-
- const int LbmD3Q19::dfInv[ cDfNum ] = {
- cDirC, cDirS, cDirN, cDirW, cDirE, cDirB, cDirT,
- cDirSW, cDirSE, cDirNW, cDirNE,
- cDirSB, cDirST, cDirNB, cDirNT,
- cDirWB, cDirWT, cDirEB, cDirET
- };
-
- const int LbmD3Q19::dfRefX[ cDfNum ] = {
- 0, 0, 0, 0, 0, 0, 0,
- cDirSE, cDirSW, cDirNE, cDirNW,
- 0, 0, 0, 0,
- cDirEB, cDirET, cDirWB, cDirWT
- };
-
- const int LbmD3Q19::dfRefY[ cDfNum ] = {
- 0, 0, 0, 0, 0, 0, 0,
- cDirNW, cDirNE, cDirSW, cDirSE,
- cDirNB, cDirNT, cDirSB, cDirST,
- 0, 0, 0, 0
- };
-
- const int LbmD3Q19::dfRefZ[ cDfNum ] = {
- 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0,
- cDirST, cDirSB, cDirNT, cDirNB,
- cDirWT, cDirWB, cDirET, cDirEB
- };
-
- // Vector Order 3D:
- // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
- // 0, 0, 0, 1,-1, 0, 0, 1,-1, 1,-1, 0, 0, 0, 0, 1, 1,-1,-1, 1,-1, 1,-1, 1,-1, 1,-1
- // 0, 1,-1, 0, 0, 0, 0, 1, 1,-1,-1, 1, 1,-1,-1, 0, 0, 0, 0, 1, 1,-1,-1, 1, 1,-1,-1
- // 0, 0, 0, 0, 0, 1,-1, 0, 0, 0, 0, 1,-1, 1,-1, 1,-1, 1,-1, 1, 1, 1, 1, -1,-1,-1,-1
-
- const int LbmD3Q19::dfVecX[ cDirNum ] = {
- 0, 0,0, 1,-1, 0,0,
- 1,-1,1,-1,
- 0,0,0,0,
- 1,1,-1,-1,
- 1,-1, 1,-1,
- 1,-1, 1,-1,
- };
- const int LbmD3Q19::dfVecY[ cDirNum ] = {
- 0, 1,-1, 0,0,0,0,
- 1,1,-1,-1,
- 1,1,-1,-1,
- 0,0,0,0,
- 1, 1,-1,-1,
- 1, 1,-1,-1
- };
- const int LbmD3Q19::dfVecZ[ cDirNum ] = {
- 0, 0,0,0,0,1,-1,
- 0,0,0,0,
- 1,-1,1,-1,
- 1,-1,1,-1,
- 1, 1, 1, 1,
- -1,-1,-1,-1
- };
-
- const LbmFloat LbmD3Q19::dfDvecX[ cDirNum ] = {
- 0, 0,0, 1,-1, 0,0,
- 1,-1,1,-1,
- 0,0,0,0,
- 1,1,-1,-1,
- 1,-1, 1,-1,
- 1,-1, 1,-1
- };
- const LbmFloat LbmD3Q19::dfDvecY[ cDirNum ] = {
- 0, 1,-1, 0,0,0,0,
- 1,1,-1,-1,
- 1,1,-1,-1,
- 0,0,0,0,
- 1, 1,-1,-1,
- 1, 1,-1,-1
- };
- const LbmFloat LbmD3Q19::dfDvecZ[ cDirNum ] = {
- 0, 0,0,0,0,1,-1,
- 0,0,0,0,
- 1,-1,1,-1,
- 1,-1,1,-1,
- 1, 1, 1, 1,
- -1,-1,-1,-1
- };
-
- /* principal directions */
- const int LbmD3Q19::princDirX[ 2*LbmD3Q19::cDimension ] = {
- 1,-1, 0,0, 0,0
- };
- const int LbmD3Q19::princDirY[ 2*LbmD3Q19::cDimension ] = {
- 0,0, 1,-1, 0,0
- };
- const int LbmD3Q19::princDirZ[ 2*LbmD3Q19::cDimension ] = {
- 0,0, 0,0, 1,-1
- };
-
- /*! arrays for les model coefficients, inited in lbmsolver constructor */
- LbmFloat LbmD3Q19::lesCoeffDiag[ (cDimension-1)*(cDimension-1) ][ cDirNum ];
- LbmFloat LbmD3Q19::lesCoeffOffdiag[ cDimension ][ cDirNum ];
-
-
- const LbmFloat LbmD3Q19::dfLength[ cDfNum ]= {
- cCollenZero,
- cCollenOne, cCollenOne, cCollenOne,
- cCollenOne, cCollenOne, cCollenOne,
- cCollenSqrtTwo, cCollenSqrtTwo, cCollenSqrtTwo, cCollenSqrtTwo,
- cCollenSqrtTwo, cCollenSqrtTwo, cCollenSqrtTwo, cCollenSqrtTwo,
- cCollenSqrtTwo, cCollenSqrtTwo, cCollenSqrtTwo, cCollenSqrtTwo
- };
-
- /* precalculated equilibrium dfs, inited in lbmsolver constructor */
- LbmFloat LbmD3Q19::dfEquil[ cDfNum ];
-
-// D3Q19 end
-
-
-
-/*****************************************************************************/
-/*! class for solver templating - 2D implementation D2Q9 */
-
- //! how many dimensions?
- const int LbmD2Q9::cDimension = 2;
-
- //! Wi factors for collide step
- const LbmFloat LbmD2Q9::cCollenZero = (4.0/9.0);
- const LbmFloat LbmD2Q9::cCollenOne = (1.0/9.0);
- const LbmFloat LbmD2Q9::cCollenSqrtTwo = (1.0/36.0);
-
- //! threshold value for filled/emptied cells
- const LbmFloat LbmD2Q9::cMagicNr2 = 1.0005;
- const LbmFloat LbmD2Q9::cMagicNr2Neg = -0.0005;
- const LbmFloat LbmD2Q9::cMagicNr = 1.010001;
- const LbmFloat LbmD2Q9::cMagicNrNeg = -0.010001;
-
- //! size of a single set of distribution functions
- const int LbmD2Q9::cDfNum = 9;
- const int LbmD2Q9::cDirNum = 9;
-
- //const string LbmD2Q9::dfString[ cDfNum ] = {
- const char* LbmD2Q9::dfString[ cDfNum ] = {
- " C",
- " N", " S", " E", " W",
- "NE", "NW", "SE","SW"
- };
-
- const int LbmD2Q9::dfNorm[ cDfNum ] = {
- cDirC,
- cDirN, cDirS, cDirE, cDirW,
- cDirNE, cDirNW, cDirSE, cDirSW
- };
-
- const int LbmD2Q9::dfInv[ cDfNum ] = {
- cDirC,
- cDirS, cDirN, cDirW, cDirE,
- cDirSW, cDirSE, cDirNW, cDirNE
- };
-
- const int LbmD2Q9::dfRefX[ cDfNum ] = {
- 0,
- 0, 0, 0, 0,
- cDirSE, cDirSW, cDirNE, cDirNW
- };
-
- const int LbmD2Q9::dfRefY[ cDfNum ] = {
- 0,
- 0, 0, 0, 0,
- cDirNW, cDirNE, cDirSW, cDirSE
- };
-
- const int LbmD2Q9::dfRefZ[ cDfNum ] = {
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0
- };
-
- // Vector Order 2D:
- // 0 1 2 3 4 5 6 7 8
- // 0, 0,0, 1,-1, 1,-1,1,-1
- // 0, 1,-1, 0,0, 1,1,-1,-1
-
- const int LbmD2Q9::dfVecX[ cDirNum ] = {
- 0,
- 0,0, 1,-1,
- 1,-1,1,-1
- };
- const int LbmD2Q9::dfVecY[ cDirNum ] = {
- 0,
- 1,-1, 0,0,
- 1,1,-1,-1
- };
- const int LbmD2Q9::dfVecZ[ cDirNum ] = {
- 0, 0,0,0,0, 0,0,0,0
- };
-
- const LbmFloat LbmD2Q9::dfDvecX[ cDirNum ] = {
- 0,
- 0,0, 1,-1,
- 1,-1,1,-1
- };
- const LbmFloat LbmD2Q9::dfDvecY[ cDirNum ] = {
- 0,
- 1,-1, 0,0,
- 1,1,-1,-1
- };
- const LbmFloat LbmD2Q9::dfDvecZ[ cDirNum ] = {
- 0, 0,0,0,0, 0,0,0,0
- };
-
- const int LbmD2Q9::princDirX[ 2*LbmD2Q9::cDimension ] = {
- 1,-1, 0,0
- };
- const int LbmD2Q9::princDirY[ 2*LbmD2Q9::cDimension ] = {
- 0,0, 1,-1
- };
- const int LbmD2Q9::princDirZ[ 2*LbmD2Q9::cDimension ] = {
- 0,0, 0,0
- };
-
-
- /*! arrays for les model coefficients, inited in lbmsolver constructor */
- LbmFloat LbmD2Q9::lesCoeffDiag[ (cDimension-1)*(cDimension-1) ][ cDirNum ];
- LbmFloat LbmD2Q9::lesCoeffOffdiag[ cDimension ][ cDirNum ];
-
-
- const LbmFloat LbmD2Q9::dfLength[ cDfNum ]= {
- cCollenZero,
- cCollenOne, cCollenOne, cCollenOne, cCollenOne,
- cCollenSqrtTwo, cCollenSqrtTwo, cCollenSqrtTwo, cCollenSqrtTwo
- };
-
- /* precalculated equilibrium dfs, inited in lbmsolver constructor */
- LbmFloat LbmD2Q9::dfEquil[ cDfNum ];
-
-// D2Q9 end
-
/******************************************************************************
@@ -308,9 +35,9 @@ LbmSolverInterface::LbmSolverInterface() :
mInitDone( false ),
mInitDensityGradient( false ),
mpAttrs( NULL ), mpParam( NULL ),
- mNumParticlesLost(0), mNumInvalidDfs(0), mNumFilledCells(0), mNumEmptiedCells(0), mNumUsedCells(0), mMLSUPS(0),
+ mNumParticlesLost(0),
+ mNumInvalidDfs(0), mNumFilledCells(0), mNumEmptiedCells(0), mNumUsedCells(0), mMLSUPS(0),
mDebugVelScale( 0.01 ), mNodeInfoString("+"),
- mRandom( 5123 ),
mvGeoStart(-1.0), mvGeoEnd(1.0),
mAccurateGeoinit(0),
mName("lbm_default") ,
@@ -321,10 +48,14 @@ LbmSolverInterface::LbmSolverInterface() :
mpGiObjects( NULL ), mGiObjInside(), mpGlob( NULL ),
mRefinementDesired(0),
mOutputSurfacePreview(0), mPreviewFactor(0.25),
- mSmoothSurface(0.0), mSmoothNormals(0.0),
- mMarkedCells(), mMarkedCellIndex(0)
+ mSmoothSurface(1.0), mSmoothNormals(1.0),
+ mPartGenProb(0.),
+ mDumpVelocities(false),
+ mMarkedCells(), mMarkedCellIndex(0),
+ mDomainBound("noslip"), mDomainPartSlipValue(0.1),
+ mTForceStrength(0.0)
{
-#if ELBEEM_BLENDER==1
+#if ELBEEM_PLUGIN==1
if(gDebugLevel<=1) mSilent = true;
#endif
}
@@ -341,7 +72,7 @@ void initGridSizes(int &sizex, int &sizey, int &sizez,
int mMaxRefine, bool parallel)
{
// fix size inits to force cubic cells and mult4 level dimensions
- const int debugGridsizeInit = 1;
+ const int debugGridsizeInit = 0;
if(debugGridsizeInit) debMsgStd("initGridSizes",DM_MSG,"Called - size X:"<<sizex<<" Y:"<<sizey<<" Z:"<<sizez<<" " ,10);
int maxGridSize = sizex; // get max size
@@ -383,6 +114,10 @@ void initGridSizes(int &sizex, int &sizey, int &sizez,
void calculateMemreqEstimate( int resx,int resy,int resz, int refine,
double *reqret, string *reqstr) {
+ // debug estimation?
+ const bool debugMemEst = false;
+ // COMPRESSGRIDS define is not available here, make sure it matches
+ const bool useGridComp = true;
// make sure we can handle bid numbers here... all double
double memCnt = 0.0;
double ddTotalNum = (double)dTotalNum;
@@ -392,12 +127,15 @@ void calculateMemreqEstimate( int resx,int resy,int resz, int refine,
double currResz = (double)resz;
double rcellSize = ((currResx*currResy*currResz) *ddTotalNum);
memCnt += (double)(sizeof(CellFlagType) * (rcellSize/ddTotalNum +4.0) *2.0);
-#if COMPRESSGRIDS==0
- memCnt += (double)(sizeof(LbmFloat) * (rcellSize +4.0) *2.0);
-#else // COMPRESSGRIDS==0
- double compressOffset = (double)(currResx*currResy*ddTotalNum*2.0);
- memCnt += (double)(sizeof(LbmFloat) * (rcellSize+compressOffset +4.0));
-#endif // COMPRESSGRIDS==0
+ if(debugMemEst) debMsgStd("calculateMemreqEstimate",DM_MSG,"res:"<<PRINT_VEC(currResx,currResy,currResz)<<" rcellSize:"<<rcellSize<<" mc:"<<memCnt, 10);
+ if(!useGridComp) {
+ memCnt += (double)(sizeof(LbmFloat) * (rcellSize +4.0) *2.0);
+ if(debugMemEst) debMsgStd("calculateMemreqEstimate",DM_MSG," no-comp, mc:"<<memCnt, 10);
+ } else {
+ double compressOffset = (double)(currResx*currResy*ddTotalNum*2.0);
+ memCnt += (double)(sizeof(LbmFloat) * (rcellSize+compressOffset +4.0));
+ if(debugMemEst) debMsgStd("calculateMemreqEstimate",DM_MSG," w-comp, mc:"<<memCnt, 10);
+ }
for(int i=refine-1; i>=0; i--) {
currResx /= 2.0;
currResy /= 2.0;
@@ -405,10 +143,12 @@ void calculateMemreqEstimate( int resx,int resy,int resz, int refine,
rcellSize = ((currResz*currResy*currResx) *ddTotalNum);
memCnt += (double)(sizeof(CellFlagType) * (rcellSize/ddTotalNum +4.0) *2.0);
memCnt += (double)(sizeof(LbmFloat) * (rcellSize +4.0) *2.0);
+ if(debugMemEst) debMsgStd("calculateMemreqEstimate",DM_MSG,"refine "<<i<<", mc:"<<memCnt, 10);
}
// isosurface memory
memCnt += (double)( (3*sizeof(int)+sizeof(float)) * ((resx+2)*(resy+2)*(resz+2)) );
+ if(debugMemEst) debMsgStd("calculateMemreqEstimate",DM_MSG,"iso, mc:"<<memCnt, 10);
double memd = memCnt;
char *sizeStr = "";
@@ -453,7 +193,7 @@ CellFlagType LbmSolverInterface::readBoundaryFlagInt(string name, int defaultVal
return (CellFlagType)( CFFluid );
}
errMsg("LbmSolverInterface::readBoundaryFlagInt","Invalid value '"<<val<<"' " );
-# if LBM_STRICT_DEBUG==1
+# if FSGR_STRICT_DEBUG==1
errFatal("readBoundaryFlagInt","Strict abort..."<<val, SIMWORLD_INITERROR);
# endif
return defaultValue;
@@ -480,7 +220,9 @@ void LbmSolverInterface::parseStdAttrList() {
mSizex = (int)sizeVec[0];
mSizey = (int)sizeVec[1];
mSizez = (int)sizeVec[2];
- mpParam->setSize(mSizex, mSizey, mSizez ); // param needs size in any case
+ // param needs size in any case
+ // test solvers might not have mpPara, though
+ if(mpParam) mpParam->setSize(mSizex, mSizey, mSizez );
mInitDensityGradient = mpAttrs->readBool("initdensitygradient", mInitDensityGradient,"LbmSolverInterface", "mInitDensityGradient", false);
mGeoInitId = mpAttrs->readInt("geoinitid", mGeoInitId,"LbmSolverInterface", "mGeoInitId", false);
@@ -488,6 +230,20 @@ void LbmSolverInterface::parseStdAttrList() {
mDebugVelScale = mpAttrs->readFloat("debugvelscale", mDebugVelScale,"LbmSolverInterface", "mDebugVelScale", false);
mNodeInfoString = mpAttrs->readString("nodeinfo", mNodeInfoString, "SimulationLbm","mNodeInfoString", false );
+
+ mDumpVelocities = mpAttrs->readBool("dump_velocities", mDumpVelocities, "SimulationLbm","mDumpVelocities", false );
+ if(getenv("ELBEEM_DUMPVELOCITIES")) {
+ int get = atoi(getenv("ELBEEM_DUMPVELOCITIES"));
+ if((get==0)||(get==1)) {
+ mDumpVelocities = get;
+ debMsgStd("LbmSolverInterface::parseAttrList",DM_NOTIFY,"Using envvar ELBEEM_DUMPVELOCITIES to set mDumpVelocities to "<<get<<","<<mDumpVelocities,8);
+ }
+ }
+
+ // new test vars
+ mTForceStrength = mpAttrs->readFloat("tforcestrength", mTForceStrength,"LbmSolverInterface", "mTForceStrength", false);
+
+ mPartGenProb = mpAttrs->readFloat("partgenprob", mPartGenProb,"LbmFsgrSolver", "mPartGenProb", false);
}
@@ -500,7 +256,7 @@ void LbmSolverInterface::parseStdAttrList() {
void LbmSolverInterface::initGeoTree(int id) {
if(mpGlob == NULL) { errFatal("LbmSolverInterface::initGeoTree","Requires globals!",SIMWORLD_INITERROR); return; }
mGeoInitId = id;
- ntlScene *scene = mpGlob->getScene();
+ ntlScene *scene = mpGlob->getSimScene();
mpGiObjects = scene->getObjects();
mGiObjInside.resize( mpGiObjects->size() );
mGiObjDistance.resize( mpGiObjects->size() );
@@ -779,25 +535,26 @@ bool LbmSolverInterface::geoInitCheckPointInside(ntlVec3Gfx org, ntlVec3Gfx dir,
}
}
+
/*****************************************************************************/
-/*! get max. velocity of all objects to initialize as fluid regions or inflow */
-ntlVec3Gfx LbmSolverInterface::getGeoMaxInitialVelocity() {
+ntlVec3Gfx LbmSolverInterface::getGeoMaxMovementVelocity(LbmFloat simtime, LbmFloat stepsize) {
ntlVec3Gfx max(0.0);
if(mpGlob == NULL) return max;
-
- ntlScene *scene = mpGlob->getScene();
- mpGiObjects = scene->getObjects();
+ // mpGiObjects has to be inited here...
for(int i=0; i< (int)mpGiObjects->size(); i++) {
+ errMsg("MVT","i"<<i<<" "<< (*mpGiObjects)[i]->getName() ); // DEBUG
if( (*mpGiObjects)[i]->getGeoInitType() & (FGI_FLUID|FGI_MBNDINFLOW) ){
- ntlVec3Gfx ovel = (*mpGiObjects)[i]->getInitialVelocity();
- if( normNoSqrt(ovel) > normNoSqrt(max) ) { max = ovel; }
- //errMsg("IVT","i"<<i<<" "<< (*mpGiObjects)[i]->getInitialVelocity() ); // DEBUG
+ //ntlVec3Gfx objMaxVel = obj->calculateMaxVel(sourceTime,targetTime);
+ ntlVec3Gfx orgvel = (*mpGiObjects)[i]->calculateMaxVel( simtime, simtime+stepsize );
+ if( normNoSqrt(orgvel) > normNoSqrt(max) ) { max = orgvel; }
+ //errMsg("MVT","i"<<i<<" a"<< (*mpGiObjects)[i]->getInitialVelocity(simtime)<<" o"<<orgvel ); // DEBUG
+ // TODO check if inflow and simtime
+ ntlVec3Gfx inivel = (*mpGiObjects)[i]->getInitialVelocity(simtime);
+ if( normNoSqrt(inivel) > normNoSqrt(max) ) { max = inivel; }
}
}
- //errMsg("IVT","max "<<" "<< max ); // DEBUG
- // unused !? mGiInsideCnt.resize( mpGiObjects->size() );
-
+ errMsg("MVT","max "<<" "<< max ); // DEBUG
return max;
}
diff --git a/intern/elbeem/intern/solver_interface.h b/intern/elbeem/intern/solver_interface.h
index ead866108bd..c86bbce2a89 100644
--- a/intern/elbeem/intern/solver_interface.h
+++ b/intern/elbeem/intern/solver_interface.h
@@ -29,11 +29,10 @@
#include "utilities.h"
#include "ntl_bsptree.h"
#include "ntl_geometryobject.h"
-#include "ntl_rndstream.h"
#include "parametrizer.h"
#include "attributes.h"
-#include "particletracer.h"
#include "isosurface.h"
+class ParticleTracer;
// use which fp-precision for LBM? 1=float, 2=double
#ifdef PRECISION_LBM_SINGLE
@@ -67,6 +66,17 @@ typedef ntlVec3d LbmVec;
#endif
+// default to 3dim
+#ifndef LBMDIM
+#define LBMDIM 3
+#endif // LBMDIM
+
+#if LBMDIM==2
+#define LBM_DFNUM 9
+#else
+#define LBM_DFNUM 19
+#endif
+
// conversions (lbm and parametrizer)
template<class T> inline LbmVec vec2L(T v) { return LbmVec(v[0],v[1],v[2]); }
template<class T> inline ParamVec vec2P(T v) { return ParamVec(v[0],v[1],v[2]); }
@@ -75,40 +85,73 @@ template<class T> inline ParamVec vec2P(T v) { return ParamVec(v[0],v[1],v[2])
// bubble id type
typedef int BubbleId;
-// for both short int/char
+// basic cell type distinctions
#define CFUnused (1<< 0)
#define CFEmpty (1<< 1)
#define CFBnd (1<< 2)
-#define CFBndNoslip (1<< 3)
-#define CFBndFreeslip (1<< 4)
-#define CFBndPartslip (1<< 5)
-// force symmetry for flag reinit
-#define CFNoInterpolSrc (1<< 6)
-#define CFFluid (1<< 7)
-#define CFInter (1<< 8)
-#define CFNoNbFluid (1<< 9)
-#define CFNoNbEmpty (1<<10)
-#define CFNoDelete (1<<11)
-#define CFNoBndFluid (1<<12)
+#define CFMbndInflow (1<< 3)
+#define CFMbndOutflow (1<< 4)
+#define CFFluid (1<< 5)
+#define CFInter (1<< 6)
+// additional for fluid (needed separately for adaptive grids)
+#define CFNoBndFluid (1<< 7)
+#define CFNoDelete (1<< 8)
+
+// additional bnd add flags
+#define CFBndNoslip (1<< 9)
+#define CFBndFreeslip (1<<10)
+#define CFBndPartslip (1<<11)
+#define CFBndMoving (1<<12)
+
+// additional for fluid/interface
+// force symmetry for flag reinit
+#define CFNoInterpolSrc (1<< 9)
+#define CFNoNbFluid (1<<10)
+#define CFNoNbEmpty (1<<11)
-//! refinement tags
// cell treated normally on coarser grids
-#define CFGrNorm (1<<13)
+#define CFGrNorm (1<< 9)
+#define CFGrCoarseInited (1<<10)
+
+// (the following values shouldnt overlap to ensure
+// proper coarsening)
// border cells to be interpolated from finer grid
-#define CFGrFromFine (1<<14)
-#define CFGrFromCoarse (1<<15)
-#define CFGrCoarseInited (1<<16)
+#define CFGrFromFine (1<<13)
// 32k aux border marker
-#define CFGrToFine (1<<17)
-#define CFMbndInflow (1<<18)
-#define CFMbndOutflow (1<<19)
-
-// debug/helper type
-#define CFIgnore (1<<20)
+#define CFGrToFine (1<<14)
+// also needed on finest level
+#define CFGrFromCoarse (1<<15)
+// additional refinement tags (coarse grids only?)
+// */
// above 24 is used to encode in/outflow object type
#define CFPersistMask (0xFF000000 | CFMbndInflow | CFMbndOutflow)
+/*
+// TEST
+// additional bnd add flags
+#define CFBndNoslip (1<< 9)
+#define CFBndFreeslip (1<<10)
+#define CFBndPartslip (1<<11)
+#define CFBndMoving (1<<12)
+
+// additional for fluid/interface
+// force symmetry for flag reinit
+#define CFNoInterpolSrc (1<<13)
+#define CFNoNbFluid (1<<14)
+#define CFNoNbEmpty (1<<15)
+
+// additional refinement tags (coarse grids only?)
+// cell treated normally on coarser grids
+#define CFGrNorm (1<<16)
+// border cells to be interpolated from finer grid
+#define CFGrFromFine (1<<17)
+#define CFGrFromCoarse (1<<18)
+#define CFGrCoarseInited (1<<19)
+// 32k aux border marker
+#define CFGrToFine (1<<20)
+// TEST */
+
// nk
#define CFInvalid (CellFlagType)(1<<31)
@@ -129,14 +172,12 @@ typedef int BubbleId;
// max. no. of cell values for 3d
#define dTotalNum 22
-
/*****************************************************************************/
/*! a single lbm cell */
/* the template is only needed for
* dimension dependend constants e.g.
* number of df's in model */
-template<typename D>
-class LbmCellTemplate {
+class LbmCellContents {
public:
LbmFloat df[ 27 ]; // be on the safe side here...
LbmFloat rho;
@@ -145,52 +186,8 @@ class LbmCellTemplate {
CellFlagType flag;
BubbleId bubble;
LbmFloat ffrac;
-
- //! test if a flag is set
- inline bool test(CellFlagType t) {
- return ((flag & t)==t);
- }
- //! test if any of the given flags is set
- inline bool testAny(CellFlagType t) {
- return ((flag & t)!=0);
- }
- //! test if the cell is empty
- inline bool isEmpty() {
- return (flag == CFEmpty);
- }
-
- //! init default values for a certain flag type
- inline void initDefaults(CellFlagType type) {
- flag = type;
- vel = LbmVec(0.0);
- for(int l=0; l<D::cDfNum;l++) df[l] = D::dfEquil[l];
-
- if(type & CFFluid) {
- rho = mass = ffrac = 1.0;
- bubble = -1;
- }
- else if(type & CFInter) {
- rho = mass = ffrac = 0.0;
- bubble = 0;
- }
- else if(type & CFBnd) {
- rho = mass = ffrac = 0.0;
- bubble = -1;
- }
- else if(type & CFEmpty) {
- rho = mass = ffrac = 0.0;
- bubble = 0;
- } else {
- // ?
- rho = mass = ffrac = 0.0;
- bubble = -1;
- }
- }
-
- //TODO add init method?
};
-
/* struct for the coordinates of a cell in the grid */
typedef struct {
int x,y,z;
@@ -218,13 +215,6 @@ typedef struct {
#define FLUIDDISPGrid 6
#define FLUIDDISPSurface 7
-//! settings for a debug display
-typedef struct fluidDispSettings_T {
- int type; // what to display
- bool on; // display enabled?
- float scale; // additional scale param
-} fluidDispSettings;
-
/*****************************************************************************/
@@ -265,11 +255,12 @@ class LbmSolverInterface
virtual ~LbmSolverInterface() { };
//! id string of solver
virtual string getIdString() = 0;
- //! dimension of solver
- virtual int getDimension() = 0;
/*! finish the init with config file values (allocate arrays...) */
- virtual bool initializeSolver() =0; //( ntlTree *tree, vector<ntlGeometryObject*> *objects ) = 0;
+ virtual bool initializeSolver() =0;
+
+ /*! notify object that dump is in progress (e.g. for field dump) */
+ virtual void notifySolverOfDump(int frameNr,char *frameNrStr,string outfilename) = 0;
/*! parse a boundary flag string */
CellFlagType readBoundaryFlagInt(string name, int defaultValue, string source,string target, bool needed);
@@ -292,7 +283,7 @@ class LbmSolverInterface
#if LBM_USE_GUI==1
/*! show simulation info */
- virtual void debugDisplay(fluidDispSettings *) = 0;
+ virtual void debugDisplay(int) = 0;
#endif
/*! init tree for certain geometry init */
@@ -305,8 +296,8 @@ class LbmSolverInterface
const gfxReal halfCellsize, bool &thinHit, bool recurse);
/*! set render globals, for scene/tree access */
void setRenderGlobals(ntlRenderGlobals *glob) { mpGlob = glob; };
- /*! get max. velocity of all objects to initialize as fluid regions */
- ntlVec3Gfx getGeoMaxInitialVelocity();
+ /*! get max. velocity of all objects to initialize as fluid regions, and of all moving objects */
+ ntlVec3Gfx getGeoMaxMovementVelocity(LbmFloat simtime, LbmFloat stepsize);
/* rt interface functions */
unsigned int getIsoVertexCount() { return mpIso->getIsoVertexCount(); }
@@ -374,6 +365,20 @@ class LbmSolverInterface
//! set desired refinement
inline void setRefinementDesired(int set){ mRefinementDesired = set; }
+ //! set/get dump velocities flag
+ inline void setDumpVelocities(bool set) { mDumpVelocities = set; }
+ inline bool getDumpVelocities() const { return mDumpVelocities; }
+
+ //! set/get particle generation prob.
+ inline void setGenerateParticles(LbmFloat set) { mPartGenProb = set; }
+ inline LbmFloat getGenerateParticles() const { return mPartGenProb; }
+
+ //! set/get dump velocities flag
+ inline void setDomainBound(std::string set) { mDomainBound = set; }
+ inline std::string getDomainBound() const { return mDomainBound; }
+ //! set/get dump velocities flag
+ inline void setDomainPartSlip(LbmFloat set) { mDomainPartSlipValue = set; }
+ inline LbmFloat getDomainPartSlip() const { return mDomainPartSlipValue; }
// cell iterator interface
@@ -399,18 +404,19 @@ class LbmSolverInterface
virtual LbmVec getCellVelocity ( CellIdentifierInterface*,int ) = 0;
/*! get equilibrium distribution functions */
virtual LbmFloat getEquilDf ( int ) = 0;
- /*! get number of distribution functions */
- virtual int getDfNum ( ) = 0;
/*! redundant cell functions */
virtual LbmFloat getCellDf ( CellIdentifierInterface* ,int set, int dir) = 0;
virtual LbmFloat getCellMass ( CellIdentifierInterface* ,int set) = 0;
virtual LbmFloat getCellFill ( CellIdentifierInterface* ,int set) = 0;
virtual CellFlagType getCellFlag ( CellIdentifierInterface* ,int set) = 0;
+ /*! get velocity directly from position */
+ virtual ntlVec3Gfx getVelocityAt(float x, float y, float z) = 0;
+
// gui/output debugging functions
#if LBM_USE_GUI==1
- virtual void debugDisplayNode(fluidDispSettings *dispset, CellIdentifier cell ) = 0;
- virtual void lbmDebugDisplay(fluidDispSettings *dispset) = 0;
+ virtual void debugDisplayNode(int dispset, CellIdentifier cell ) = 0;
+ virtual void lbmDebugDisplay(int dispset) = 0;
virtual void lbmMarkedCellDisplay() = 0;
#endif // LBM_USE_GUI==1
virtual void debugPrintNodeInfo(CellIdentifier cell, int forceSet=-1) = 0;
@@ -484,11 +490,6 @@ class LbmSolverInterface
/*! string for node info debugging output */
string mNodeInfoString;
-
- /*! an own random stream */
- ntlRandomStream mRandom;
-
-
// geo init vars
// TODO deprecate SimulationObject vars
@@ -534,353 +535,26 @@ class LbmSolverInterface
float mSmoothSurface;
float mSmoothNormals;
+ //! particle generation probability
+ LbmFloat mPartGenProb;
+
+ //! dump velocities?
+ bool mDumpVelocities;
+
// list for marked cells
vector<CellIdentifierInterface *> mMarkedCells;
int mMarkedCellIndex;
-};
-
-
-//! shorten static const definitions
-#define STCON static const
-
-
-/*****************************************************************************/
-/*! class for solver templating - 3D implementation */
-class LbmD3Q19 {
-
- public:
-
- // constructor, init interface
- LbmD3Q19() {};
- // virtual destructor
- virtual ~LbmD3Q19() {};
- //! id string of solver
- string getIdString() { return string("3D"); }
-
- //! how many dimensions?
- STCON int cDimension;
-
- // Wi factors for collide step
- STCON LbmFloat cCollenZero;
- STCON LbmFloat cCollenOne;
- STCON LbmFloat cCollenSqrtTwo;
-
- //! threshold value for filled/emptied cells
- STCON LbmFloat cMagicNr2;
- STCON LbmFloat cMagicNr2Neg;
- STCON LbmFloat cMagicNr;
- STCON LbmFloat cMagicNrNeg;
-
- //! size of a single set of distribution functions
- STCON int cDfNum;
- //! direction vector contain vecs for all spatial dirs, even if not used for LBM model
- STCON int cDirNum;
-
- //! distribution functions directions
- typedef enum {
- cDirInv= -1,
- cDirC = 0,
- cDirN = 1,
- cDirS = 2,
- cDirE = 3,
- cDirW = 4,
- cDirT = 5,
- cDirB = 6,
- cDirNE = 7,
- cDirNW = 8,
- cDirSE = 9,
- cDirSW = 10,
- cDirNT = 11,
- cDirNB = 12,
- cDirST = 13,
- cDirSB = 14,
- cDirET = 15,
- cDirEB = 16,
- cDirWT = 17,
- cDirWB = 18
- } dfDir;
-
- /* Vector Order 3D:
- * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
- * 0, 0, 0, 1,-1, 0, 0, 1,-1, 1,-1, 0, 0, 0, 0, 1, 1,-1,-1, 1,-1, 1,-1, 1,-1, 1,-1
- * 0, 1,-1, 0, 0, 0, 0, 1, 1,-1,-1, 1, 1,-1,-1, 0, 0, 0, 0, 1, 1,-1,-1, 1, 1,-1,-1
- * 0, 0, 0, 0, 0, 1,-1, 0, 0, 0, 0, 1,-1, 1,-1, 1,-1, 1,-1, 1, 1, 1, 1, -1,-1,-1,-1
- */
-
- /*! name of the dist. function
- only for nicer output */
- STCON char* dfString[ 19 ];
-
- /*! index of normal dist func, not used so far?... */
- STCON int dfNorm[ 19 ];
-
- /*! index of inverse dist func, not fast, but useful... */
- STCON int dfInv[ 19 ];
-
- /*! index of x reflected dist func for free slip, not valid for all DFs... */
- STCON int dfRefX[ 19 ];
- /*! index of x reflected dist func for free slip, not valid for all DFs... */
- STCON int dfRefY[ 19 ];
- /*! index of x reflected dist func for free slip, not valid for all DFs... */
- STCON int dfRefZ[ 19 ];
-
- /*! dist func vectors */
- STCON int dfVecX[ 27 ];
- STCON int dfVecY[ 27 ];
- STCON int dfVecZ[ 27 ];
-
- /*! arrays as before with doubles */
- STCON LbmFloat dfDvecX[ 27 ];
- STCON LbmFloat dfDvecY[ 27 ];
- STCON LbmFloat dfDvecZ[ 27 ];
-
- /*! principal directions */
- STCON int princDirX[ 2*3 ];
- STCON int princDirY[ 2*3 ];
- STCON int princDirZ[ 2*3 ];
-
- /*! vector lengths */
- STCON LbmFloat dfLength[ 19 ];
-
- /*! equilibrium distribution functions, precalculated = getCollideEq(i, 0,0,0,0) */
- static LbmFloat dfEquil[ 19 ];
-
- /*! arrays for les model coefficients */
- static LbmFloat lesCoeffDiag[ (3-1)*(3-1) ][ 27 ];
- static LbmFloat lesCoeffOffdiag[ 3 ][ 27 ];
-
-}; // LbmData3D
-
-
-/*****************************************************************************/
-//! class for solver templating - 2D implementation
-class LbmD2Q9 {
-
- public:
-
- // constructor, init interface
- LbmD2Q9() {};
- // virtual destructor
- virtual ~LbmD2Q9() {};
- //! id string of solver
- string getIdString() { return string("2D"); }
-
- //! how many dimensions?
- STCON int cDimension;
-
- //! Wi factors for collide step
- STCON LbmFloat cCollenZero;
- STCON LbmFloat cCollenOne;
- STCON LbmFloat cCollenSqrtTwo;
-
- //! threshold value for filled/emptied cells
- STCON LbmFloat cMagicNr2;
- STCON LbmFloat cMagicNr2Neg;
- STCON LbmFloat cMagicNr;
- STCON LbmFloat cMagicNrNeg;
-
- //! size of a single set of distribution functions
- STCON int cDfNum;
- STCON int cDirNum;
-
- //! distribution functions directions
- typedef enum {
- cDirInv= -1,
- cDirC = 0,
- cDirN = 1,
- cDirS = 2,
- cDirE = 3,
- cDirW = 4,
- cDirNE = 5,
- cDirNW = 6,
- cDirSE = 7,
- cDirSW = 8
- } dfDir;
-
- /* Vector Order 2D:
- * 0 1 2 3 4 5 6 7 8
- * 0, 0,0, 1,-1, 1,-1,1,-1
- * 0, 1,-1, 0,0, 1,1,-1,-1 */
-
- /* name of the dist. function
- only for nicer output */
- STCON char* dfString[ 9 ];
-
- /* index of normal dist func, not used so far?... */
- STCON int dfNorm[ 9 ];
-
- /* index of inverse dist func, not fast, but useful... */
- STCON int dfInv[ 9 ];
-
- /* index of x reflected dist func for free slip, not valid for all DFs... */
- STCON int dfRefX[ 9 ];
- /* index of x reflected dist func for free slip, not valid for all DFs... */
- STCON int dfRefY[ 9 ];
- /* index of x reflected dist func for free slip, not valid for all DFs... */
- STCON int dfRefZ[ 9 ];
-
- /* dist func vectors */
- STCON int dfVecX[ 9 ];
- STCON int dfVecY[ 9 ];
- /* Z, 2D values are all 0! */
- STCON int dfVecZ[ 9 ];
-
- /* arrays as before with doubles */
- STCON LbmFloat dfDvecX[ 9 ];
- STCON LbmFloat dfDvecY[ 9 ];
- /* Z, 2D values are all 0! */
- STCON LbmFloat dfDvecZ[ 9 ];
-
- /*! principal directions */
- STCON int princDirX[ 2*2 ];
- STCON int princDirY[ 2*2 ];
- STCON int princDirZ[ 2*2 ];
-
- /* vector lengths */
- STCON LbmFloat dfLength[ 9 ];
+ //! domain boundary free/no slip type
+ std::string mDomainBound;
+ //! part slip value for domain
+ LbmFloat mDomainPartSlipValue;
- /* equilibrium distribution functions, precalculated = getCollideEq(i, 0,0,0,0) */
- static LbmFloat dfEquil[ 9 ];
+ //! test vars
+ // strength of applied force
+ LbmFloat mTForceStrength;
- /*! arrays for les model coefficients */
- static LbmFloat lesCoeffDiag[ (2-1)*(2-1) ][ 9 ];
- static LbmFloat lesCoeffOffdiag[ 2 ][ 9 ];
-
-}; // LbmData3D
-
-
-
-// lbmdimensions
-
-// not needed hereafter
-#undef STCON
-
-
-
-/*****************************************************************************/
-//! class for solver templating - lbgk (srt) model implementation
-template<class DQ>
-class LbmModelLBGK : public DQ , public LbmSolverInterface {
- public:
-
- /*! type for cells contents, needed for cell id interface */
- typedef DQ LbmCellContents;
- /*! type for cells */
- typedef LbmCellTemplate< LbmCellContents > LbmCell;
-
- // constructor
- LbmModelLBGK() : DQ(), LbmSolverInterface() {};
- // virtual destructor
- virtual ~LbmModelLBGK() {};
- //! id string of solver
- string getIdString() { return DQ::getIdString() + string("lbgk]"); }
-
- /*! calculate length of velocity vector */
- static inline LbmFloat getVelVecLen(int l, LbmFloat ux,LbmFloat uy,LbmFloat uz) {
- return ((ux)*DQ::dfDvecX[l]+(uy)*DQ::dfDvecY[l]+(uz)*DQ::dfDvecZ[l]);
- };
-
- /*! calculate equilibrium DF for given values */
- static inline LbmFloat getCollideEq(int l, LbmFloat rho, LbmFloat ux, LbmFloat uy, LbmFloat uz) {
- LbmFloat tmp = getVelVecLen(l,ux,uy,uz);
- return( DQ::dfLength[l] *(
- + rho - (3.0/2.0*(ux*ux + uy*uy + uz*uz))
- + 3.0 *tmp
- + 9.0/2.0 *(tmp*tmp) )
- );
- };
-
-
- /*! relaxation LES functions */
- inline LbmFloat getLesNoneqTensorCoeff(
- LbmFloat df[],
- LbmFloat feq[] ) {
- LbmFloat Qo = 0.0;
- for(int m=0; m< ((DQ::cDimension*DQ::cDimension)-DQ::cDimension)/2 ; m++) {
- LbmFloat qadd = 0.0;
- for(int l=1; l<DQ::cDfNum; l++) {
- if(DQ::lesCoeffOffdiag[m][l]==0.0) continue;
- qadd += DQ::lesCoeffOffdiag[m][l]*(df[l]-feq[l]);
- }
- Qo += (qadd*qadd);
- }
- Qo *= 2.0; // off diag twice
- for(int m=0; m<DQ::cDimension; m++) {
- LbmFloat qadd = 0.0;
- for(int l=1; l<DQ::cDfNum; l++) {
- if(DQ::lesCoeffDiag[m][l]==0.0) continue;
- qadd += DQ::lesCoeffDiag[m][l]*(df[l]-feq[l]);
- }
- Qo += (qadd*qadd);
- }
- Qo = sqrt(Qo);
- return Qo;
- }
- inline LbmFloat getLesOmega(LbmFloat omega, LbmFloat csmago, LbmFloat Qo) {
- const LbmFloat tau = 1.0/omega;
- const LbmFloat nu = (2.0*tau-1.0) * (1.0/6.0);
- const LbmFloat C = csmago;
- const LbmFloat Csqr = C*C;
- LbmFloat S = -nu + sqrt( nu*nu + 18.0*Csqr*Qo ) / (6.0*Csqr);
- return( 1.0/( 3.0*( nu+Csqr*S ) +0.5 ) );
- }
-
- // "normal" collision
- inline void collideArrays(LbmFloat df[],
- LbmFloat &outrho, // out only!
- // velocity modifiers (returns actual velocity!)
- LbmFloat &mux, LbmFloat &muy, LbmFloat &muz,
- LbmFloat omega, LbmFloat csmago,
- LbmFloat *newOmegaRet, LbmFloat *newQoRet
- ) {
- LbmFloat rho=df[0];
- LbmFloat ux = mux;
- LbmFloat uy = muy;
- LbmFloat uz = muz;
- for(int l=1; l<DQ::cDfNum; l++) {
- rho += df[l];
- ux += (DQ::dfDvecX[l]*df[l]);
- uy += (DQ::dfDvecY[l]*df[l]);
- uz += (DQ::dfDvecZ[l]*df[l]);
- }
- LbmFloat feq[19];
- for(int l=0; l<DQ::cDfNum; l++) {
- feq[l] = getCollideEq(l,rho,ux,uy,uz);
- }
-
- LbmFloat omegaNew;
- LbmFloat Qo = 0.0;
- if(csmago>0.0) {
- Qo = getLesNoneqTensorCoeff(df,feq);
- omegaNew = getLesOmega(omega,csmago,Qo);
- } else {
- omegaNew = omega; // smago off...
- }
- if(newOmegaRet) *newOmegaRet = omegaNew; // return value for stats
- if(newQoRet) *newQoRet = Qo; // return value of non-eq. stress tensor
-
- for(int l=0; l<DQ::cDfNum; l++) {
- df[l] = (1.0-omegaNew ) * df[l] + omegaNew * feq[l];
- }
-
- mux = ux;
- muy = uy;
- muz = uz;
- outrho = rho;
- };
-
-}; // LBGK
-
-#ifdef LBMMODEL_DEFINED
-// force compiler error!
-ERROR - Dont include several LBM models at once...
-#endif
-#define LBMMODEL_DEFINED 1
-
-
-typedef LbmModelLBGK< LbmD2Q9 > LbmBGK2D;
-typedef LbmModelLBGK< LbmD3Q19 > LbmBGK3D;
+};
// helper function to create consistent grid resolutions
diff --git a/intern/elbeem/intern/solver_main.cpp b/intern/elbeem/intern/solver_main.cpp
index c4f5c9ba14e..c8f0678a6f0 100644
--- a/intern/elbeem/intern/solver_main.cpp
+++ b/intern/elbeem/intern/solver_main.cpp
@@ -9,66 +9,60 @@
#include "solver_class.h"
#include "solver_relax.h"
+#include "particletracer.h"
/*****************************************************************************/
/*! perform a single LBM step */
/*****************************************************************************/
-template<class D>
-string LbmFsgrSolver<D>::getIdString() {
- return string("FsgrSolver[") + D::getIdString();
-}
-
-template<class D>
-int LbmFsgrSolver<D>::getDimension() { return D::cDimension; }
-template<class D>
-void LbmFsgrSolver<D>::step() {
+void LbmFsgrSolver::step() {
initLevelOmegas();
stepMain();
}
-template<class D>
-void
-LbmFsgrSolver<D>::stepMain()
+void LbmFsgrSolver::stepMain()
{
-#if ELBEEM_PLUGIN==1
+#if ELBEEM_BLENDER==1
// update gui display
//SDL_mutexP(lobalBakeLock);
if(getGlobalBakeState()<0) {
// this means abort... cause panic
- D::mPanic = 1;
+ CAUSE_PANIC;
errMsg("LbmFsgrSolver::step","Got abort signal from GUI, causing panic, aborting...");
}
//SDL_mutexV(lobalBakeLock);
#endif // ELBEEM_PLUGIN==1
- D::markedClearList(); // DMC clearMarkedCellsList
+ this->markedClearList(); // DMC clearMarkedCellsList
// safety check, counter reset
- D::mNumUsedCells = 0;
+ this->mNumUsedCells = 0;
mNumInterdCells = 0;
mNumInvIfCells = 0;
- //debugOutNnl("LbmFsgrSolver::step : "<<D::mStepCnt, 10);
- if(!D::mSilent){ debMsgNnl("LbmFsgrSolver::step", DM_MSG, D::mName<<" cnt:"<<D::mStepCnt<<" ", 10); }
- //debMsgDirect( "LbmFsgrSolver::step : "<<D::mStepCnt<<" ");
+ //debugOutNnl("LbmFsgrSolver::step : "<<this->mStepCnt, 10);
+ if(!this->mSilent){ debMsgStd("LbmFsgrSolver::step", DM_MSG, this->mName<<" cnt:"<<this->mStepCnt<<" t:"<<mSimulationTime, 10); }
+ //debMsgDirect( "LbmFsgrSolver::step : "<<this->mStepCnt<<" ");
myTime_t timestart = getTime();
//myTime_t timestart = 0;
//if(mStartSymm) { checkSymmetry("step1"); } // DEBUG
+ // time adapt
+ mMaxVlen = mMxvz = mMxvy = mMxvx = 0.0;
+
+ // init moving bc's, can change mMaxVlen
+ initMovingObstacles(false);
+
// important - keep for tadap
- mCurrentMass = D::mFixMass; // reset here for next step
+ mCurrentMass = this->mFixMass; // reset here for next step
mCurrentVolume = 0.0;
- //stats
- mMaxVlen = mMxvz = mMxvy = mMxvx = 0.0;
-
//change to single step advance!
int levsteps = 0;
- int dsbits = D::mStepCnt ^ (D::mStepCnt-1);
- //errMsg("S"," step:"<<D::mStepCnt<<" s-1:"<<(D::mStepCnt-1)<<" xf:"<<convertCellFlagType2String(dsbits));
+ int dsbits = this->mStepCnt ^ (this->mStepCnt-1);
+ //errMsg("S"," step:"<<this->mStepCnt<<" s-1:"<<(this->mStepCnt-1)<<" xf:"<<convertCellFlagType2String(dsbits));
for(int lev=0; lev<=mMaxRefine; lev++) {
- //if(! (D::mStepCnt&(1<<lev)) ) {
+ //if(! (this->mStepCnt&(1<<lev)) ) {
if( dsbits & (1<<(mMaxRefine-lev)) ) {
//errMsg("S"," l"<<lev);
@@ -91,44 +85,46 @@ LbmFsgrSolver<D>::stepMain()
}
// prepare next step
- D::mStepCnt++;
+ this->mStepCnt++;
// some dbugging output follows
// calculate MLSUPS
myTime_t timeend = getTime();
- D::mNumUsedCells += mNumInterdCells; // count both types for MLSUPS
- mAvgNumUsedCells += D::mNumUsedCells;
- D::mMLSUPS = (D::mNumUsedCells / ((timeend-timestart)/(double)1000.0) ) / (1000000);
- if(D::mMLSUPS>10000){ D::mMLSUPS = -1; }
- else { mAvgMLSUPS += D::mMLSUPS; mAvgMLSUPSCnt += 1.0; } // track average mlsups
+ this->mNumUsedCells += mNumInterdCells; // count both types for MLSUPS
+ mAvgNumUsedCells += this->mNumUsedCells;
+ this->mMLSUPS = (this->mNumUsedCells / ((timeend-timestart)/(double)1000.0) ) / (1000000);
+ if(this->mMLSUPS>10000){ this->mMLSUPS = -1; }
+ else { mAvgMLSUPS += this->mMLSUPS; mAvgMLSUPSCnt += 1.0; } // track average mlsups
LbmFloat totMLSUPS = ( ((mLevel[mMaxRefine].lSizex-2)*(mLevel[mMaxRefine].lSizey-2)*(getForZMax1(mMaxRefine)-getForZMin1())) / ((timeend-timestart)/(double)1000.0) ) / (1000000);
if(totMLSUPS>10000) totMLSUPS = -1;
mNumInvIfTotal += mNumInvIfCells; // debug
// do some formatting
- if(!D::mSilent){
+ if(!this->mSilent){
string sepStr(""); // DEBUG
- int avgcls = (int)(mAvgNumUsedCells/(LONGINT)D::mStepCnt);
- debMsgDirect(
- "mlsups(curr:"<<D::mMLSUPS<<
+ int avgcls = (int)(mAvgNumUsedCells/(LONGINT)this->mStepCnt);
+ debMsgStd("LbmFsgrSolver::step", DM_MSG, this->mName<<" cnt:"<<this->mStepCnt<<" t:"<<mSimulationTime<<
+ //debMsgDirect(
+ "mlsups(curr:"<<this->mMLSUPS<<
" avg:"<<(mAvgMLSUPS/mAvgMLSUPSCnt)<<"), "<< sepStr<<
- " totcls:"<<(D::mNumUsedCells)<< sepStr<<
+ " totcls:"<<(this->mNumUsedCells)<< sepStr<<
" avgcls:"<< avgcls<< sepStr<<
" intd:"<<mNumInterdCells<< sepStr<<
" invif:"<<mNumInvIfCells<< sepStr<<
" invift:"<<mNumInvIfTotal<< sepStr<<
" fsgrcs:"<<mNumFsgrChanges<< sepStr<<
- " filled:"<<D::mNumFilledCells<<", emptied:"<<D::mNumEmptiedCells<< sepStr<<
+ " filled:"<<this->mNumFilledCells<<", emptied:"<<this->mNumEmptiedCells<< sepStr<<
" mMxv:"<<mMxvx<<","<<mMxvy<<","<<mMxvz<<", tscnts:"<<mTimeSwitchCounts<< sepStr<<
+ " RWmxv:"<<ntlVec3Gfx(mMxvx,mMxvy,mMxvz)*(mLevel[mMaxRefine].simCellSize / mLevel[mMaxRefine].timestep)<<" "<< /* realworld vel output */
" probs:"<<mNumProblems<< sepStr<<
" simt:"<<mSimulationTime<< sepStr<<
- " for '"<<D::mName<<"' " );
+ " for '"<<this->mName<<"' " , 10);
debMsgDirect(std::endl);
- debMsgDirect(D::mStepCnt<<": dccd="<< mCurrentMass<<"/"<<mCurrentVolume<<"(fix="<<D::mFixMass<<",ini="<<mInitialMass<<") ");
+ debMsgDirect(this->mStepCnt<<": dccd="<< mCurrentMass<<"/"<<mCurrentVolume<<"(fix="<<this->mFixMass<<",ini="<<mInitialMass<<") ");
debMsgDirect(std::endl);
// nicer output
@@ -139,11 +135,11 @@ LbmFsgrSolver<D>::stepMain()
//if((mStepCnt%10)==9) debMsgDirect("\n");
}
- if(D::mStepCnt==1) {
- mMinNoCells = mMaxNoCells = D::mNumUsedCells;
+ if(this->mStepCnt==1) {
+ mMinNoCells = mMaxNoCells = this->mNumUsedCells;
} else {
- if(D::mNumUsedCells>mMaxNoCells) mMaxNoCells = D::mNumUsedCells;
- if(D::mNumUsedCells<mMinNoCells) mMinNoCells = D::mNumUsedCells;
+ if(this->mNumUsedCells>mMaxNoCells) mMaxNoCells = this->mNumUsedCells;
+ if(this->mNumUsedCells<mMinNoCells) mMinNoCells = this->mNumUsedCells;
}
// mass scale test
@@ -167,7 +163,7 @@ LbmFsgrSolver<D>::stepMain()
errMsg("MDTDD","\n\n");
errMsg("MDTDD","FORCE RESCALE MASS! "
<<"ini:"<<mInitialMass<<", cur:"<<mCurrentMass<<", f="<<ABS(mInitialMass/mCurrentMass)
- <<" step:"<<D::mStepCnt<<" levstep:"<<mLevel[0].lsteps<<" msc:"<<mscount<<" "
+ <<" step:"<<this->mStepCnt<<" levstep:"<<mLevel[0].lsteps<<" msc:"<<mscount<<" "
);
errMsg("MDTDD","\n\n");
@@ -208,58 +204,53 @@ LbmFsgrSolver<D>::stepMain()
}
}
+#if LBM_INCLUDE_TESTSOLVERS==1
+ if((mUseTestdata)&&(this->mInitDone)) { handleTestdata(); }
+#endif
+
// one of the last things to do - adapt timestep
// was in fineAdvance before...
if(mTimeAdap) {
adaptTimestep();
} // time adaptivity
- // debug - raw dump of ffrac values
- /*if((D::mStepCnt%100)==1){
- std::ostringstream name;
- name <<"fill_" << D::mStepCnt <<".dump";
- FILE *file = fopen(name.str().c_str(),"w");
- for(int k= getForZMinBnd(); k< getForZMaxBnd(mMaxRefine); ++k) {
- for(int j=0;j<mLevel[mMaxRefine].lSizey-0;j++) {
- for(int i=0;i<mLevel[mMaxRefine].lSizex-0;i++) {
- float val = QCELL(mMaxRefine,i,j,k, mLevel[mMaxRefine].setCurr,dFfrac);
- //fwrite( &val, sizeof(val), 1, file); // binary
- fprintf(file, "%f ",val); // text
- //errMsg("W", PRINT_IJK<<" val:"<<val);
- }
- fprintf(file, "\n"); // text
- }
- fprintf(file, "\n"); // text
- }
- fclose(file);
- } // */
-#if ELBEEM_PLUGIN!=1
- if(mUseTestdata) {
- if(mpTest->mDebugvalue3>0.0) handleTestdata();
- }
-#endif // ELBEEM_PLUGIN!=1
+#ifndef WIN32
+ // good indicator for instabilities
+ if( (!finite(mMxvx)) || (!finite(mMxvy)) || (!finite(mMxvz)) ) { CAUSE_PANIC; }
+ if( (!finite(mCurrentMass)) || (!finite(mCurrentVolume)) ) { CAUSE_PANIC; }
+#endif // WIN32
+ //#endif // ELBEEM_PLUGIN!=1
}
-template<class D>
-void
-LbmFsgrSolver<D>::fineAdvance()
+#define NEWDEBCHECK(str) \
+ if(!this->mPanic){ FSGR_FORIJK_BOUNDS(mMaxRefine) { \
+ if(RFLAG(mMaxRefine,i,j,k,mLevel[mMaxRefine].setCurr)&(CFFluid|CFInter)) { \
+ for(int l=0;l<dTotalNum;l++) { \
+ if(!finite(QCELL(mMaxRefine,i,j,k,mLevel[mMaxRefine].setCurr,l))) { errMsg("NNOFIN"," "<<str<<" at "<<PRINT_IJK<<" l"<<l<<" "); }\
+ }/*for*/ \
+ }/*if*/ \
+ } }
+
+void LbmFsgrSolver::fineAdvance()
{
// do the real thing...
+ //NEWDEBCHECK("t1");
mainLoop( mMaxRefine );
if(mUpdateFVHeight) {
// warning assume -Y gravity...
mFVHeight = mCurrentMass*mFVArea/((LbmFloat)(mLevel[mMaxRefine].lSizex*mLevel[mMaxRefine].lSizez));
if(mFVHeight<1.0) mFVHeight = 1.0;
- D::mpParam->setFluidVolumeHeight(mFVHeight);
+ this->mpParam->setFluidVolumeHeight(mFVHeight);
}
+ //NEWDEBCHECK("t2");
// advance time before timestep change
- mSimulationTime += D::mpParam->getStepTime();
+ mSimulationTime += this->mpParam->getTimestep();
// time adaptivity
- D::mpParam->setSimulationMaxSpeed( sqrt(mMaxVlen / 1.5) );
+ this->mpParam->setSimulationMaxSpeed( sqrt(mMaxVlen / 1.5) );
//if(mStartSymm) { checkSymmetry("step2"); } // DEBUG
- if(!D::mSilent){ errMsg("fineAdvance"," stepped from "<<mLevel[mMaxRefine].setCurr<<" to "<<mLevel[mMaxRefine].setOther<<" step"<< (mLevel[mMaxRefine].lsteps) ); }
+ if(!this->mSilent){ errMsg("fineAdvance"," stepped from "<<mLevel[mMaxRefine].setCurr<<" to "<<mLevel[mMaxRefine].setOther<<" step"<< (mLevel[mMaxRefine].lsteps) ); }
// update other set
mLevel[mMaxRefine].setOther = mLevel[mMaxRefine].setCurr;
@@ -268,7 +259,8 @@ LbmFsgrSolver<D>::fineAdvance()
// flag init... (work on current set, to simplify flag checks)
reinitFlags( mLevel[mMaxRefine].setCurr );
- if(!D::mSilent){ errMsg("fineAdvance"," flags reinit on set "<< mLevel[mMaxRefine].setCurr ); }
+ if(!this->mSilent){ errMsg("fineAdvance"," flags reinit on set "<< mLevel[mMaxRefine].setCurr ); }
+ //NEWDEBCHECK("t3");
}
@@ -276,26 +268,35 @@ LbmFsgrSolver<D>::fineAdvance()
//! coarse/fine step functions
/*****************************************************************************/
+
+// ZDEB
+
// access to own dfs during step (may be changed to local array)
#define MYDF(l) RAC(ccel, l)
-template<class D>
void
-LbmFsgrSolver<D>::mainLoop(int lev)
+LbmFsgrSolver::mainLoop(int lev)
{
// loops over _only inner_ cells -----------------------------------------------------------------------------------
LbmFloat calcCurrentMass = 0.0;
LbmFloat calcCurrentVolume = 0.0;
- int calcCellsFilled = D::mNumFilledCells;
- int calcCellsEmptied = D::mNumEmptiedCells;
- int calcNumUsedCells = D::mNumUsedCells;
-
+ int calcCellsFilled = this->mNumFilledCells;
+ int calcCellsEmptied = this->mNumEmptiedCells;
+ int calcNumUsedCells = this->mNumUsedCells;
+
+# if LBM_INCLUDE_TESTSOLVERS==1
+ if((mUseTestdata)&&(mpTest->mDebugvalue1>0.0)) {
+ // 3d region off... quit
+ this->mpIso->setIsolevel(-100.0); return; }
+#endif // ELBEEM_PLUGIN!=1
+ //printLbmCell(lev, 6,6,16, mLevel[lev].setCurr ); // DEBUG
+
#if PARALLEL==1
#include "paraloop.h"
#else // PARALLEL==1
{ // main loop region
int kstart=getForZMin1(), kend=getForZMax1(mMaxRefine);
-//{ errMsg("LbmFsgrSolver::mainLoop","Err MAINADVANCE0 ks:"<< kstart<<" ke:"<<kend<<" dim:"<<D::cDimension<<" mlsz:"<< mLevel[mMaxRefine].lSizez<<" zmax1:"<<getForZMax1(mMaxRefine) ); } // DEBUG
+ //{ errMsg("LbmFsgrSolver::mainLoop","Err MAINADVANCE0 ks:"<< kstart<<" ke:"<<kend<<" dim:"<<LBMDIMcDimension<<" mlsz:"<< mLevel[mMaxRefine].lSizez<<" zmax1:"<<getForZMax1(mMaxRefine) ); } // DEBUG
#define PERFORM_USQRMAXCHECK USQRMAXCHECK(usqr,ux,uy,uz, mMaxVlen, mMxvx,mMxvy,mMxvz);
#endif // PARALLEL==1
@@ -308,7 +309,7 @@ LbmFsgrSolver<D>::mainLoop(int lev)
int nbored;
LbmFloat m[LBM_DFNUM];
LbmFloat rho, ux, uy, uz, tmp, usqr;
- LbmFloat mass, change, lcsmqo;
+ LbmFloat mass, change, lcsmqo=0.0;
usqr = tmp = 0.0;
#if OPT3D==1
LbmFloat lcsmqadd, lcsmeq[LBM_DFNUM], lcsmomega;
@@ -343,13 +344,12 @@ LbmFsgrSolver<D>::mainLoop(int lev)
pFlagDst+= (p); \
i+= (p);
-
// ---
// now stream etc.
-//{ errMsg("LbmFsgrSolver::mainLoop","Err MAINADVANCE0 ks:"<< kstart<<" ke:"<<kend<<" dim:"<<D::cDimension<<" mlsz:"<<mLevel[mMaxRefine].lSizez ); } // DEBUG
+ //{ errMsg("LbmFsgrSolver::mainLoop","Err MAINADVANCE0 ks:"<< kstart<<" ke:"<<kend<<" dim:"<<LBMDIM<<" mlsz:"<<mLevel[mMaxRefine].lSizez ); } // DEBUG
- // use template functions for 2D/3D
+ // use //template functions for 2D/3D
#if COMPRESSGRIDS==0
for(int k=kstart;k<kend;++k) {
for(int j=1;j<mLevel[lev].lSizey-1;++j) {
@@ -378,7 +378,7 @@ LbmFsgrSolver<D>::mainLoop(int lev)
#if PARALLEL==1
PARA_INITIALIZE();
- errMsg("LbmFsgrSolver::mainLoop","id="<<id<<" js="<<jstart<<" je="<<jend<<" jdir="<<(1) ); // debug
+ //errMsg("LbmFsgrSolver::mainLoop","id="<<id<<" js="<<jstart<<" je="<<jend<<" jdir="<<(1) ); // debug
#endif // PARALLEL==1
for(int k=kstart;k!=kend;k+=kdir) {
@@ -404,7 +404,7 @@ LbmFsgrSolver<D>::mainLoop(int lev)
(int)(&RFLAG(lev, i,j,k,mLevel[lev].setCurr))<<","<<(int)(&RFLAG(lev, i,j,k,mLevel[lev].setOther))<<" but is "<<
(int)(pFlagSrc)<<","<<(int)(pFlagDst)<<" "
);
- D::mPanic=1;
+ CAUSE_PANIC;
}
if( (&QCELL(lev, i,j,k,mLevel[lev].setCurr,0) != ccel) ||
(&QCELL(lev, i,j,k,mLevel[lev].setOther,0) != tcel) ) {
@@ -412,7 +412,7 @@ LbmFsgrSolver<D>::mainLoop(int lev)
(int)(&QCELL(lev, i,j,k,mLevel[lev].setCurr,0))<<","<<(int)(&QCELL(lev, i,j,k,mLevel[lev].setOther,0))<<" but is "<<
(int)(ccel)<<","<<(int)(tcel)<<" "
);
- D::mPanic=1;
+ CAUSE_PANIC;
}
#endif
oldFlag = *pFlagSrc;
@@ -421,7 +421,7 @@ LbmFsgrSolver<D>::mainLoop(int lev)
// old INTCFCOARSETEST==1
if( (oldFlag & (CFGrFromCoarse)) ) { // interpolateFineFromCoarse test!
- if(( D::mStepCnt & (1<<(mMaxRefine-lev)) ) ==1) {
+ if(( this->mStepCnt & (1<<(mMaxRefine-lev)) ) ==1) {
FORDF0 { RAC(tcel,l) = RAC(ccel,l); }
} else {
interpolateCellFromCoarse( lev, i,j,k, TSET(lev), 0.0, CFFluid|CFGrFromCoarse, false);
@@ -439,12 +439,13 @@ LbmFsgrSolver<D>::mainLoop(int lev)
// make new if cell
const LbmVec vel(mObjectSpeeds[OId]);
// TODO add OPT3D treatment
- FORDF0 { RAC(tcel, l) = D::getCollideEq(l, iniRho,vel[0],vel[1],vel[2]); }
+ FORDF0 { RAC(tcel, l) = this->getCollideEq(l, iniRho,vel[0],vel[1],vel[2]); }
RAC(tcel, dMass) = RAC(tcel, dFfrac) = iniRho;
RAC(tcel, dFlux) = FLUX_INIT;
changeFlag(lev, i,j,k, TSET(lev), CFInter);
calcCurrentMass += iniRho; calcCurrentVolume += 1.0; calcNumUsedCells++;
mInitialMass += iniRho;
+ //errMsg("INFLOW_DEBUG","ini at "<<PRINT_IJK<<" v="<<vel<<" inirho="<<iniRho);
// dont treat cell until next step
continue;
}
@@ -529,17 +530,19 @@ LbmFsgrSolver<D>::mainLoop(int lev)
// only standard fluid cells (with nothing except fluid as nbs
if(oldFlag&CFMbndInflow) {
- // force velocity for inflow
+ // force velocity for inflow, necessary to have constant direction of flow
+ // FIXME , test also set interface cells?
const int OId = oldFlag>>24;
- DEFAULT_STREAM;
+ //? DEFAULT_STREAM;
//const LbmFloat fluidRho = 1.0;
// for submerged inflows, streaming would have to be performed...
LbmFloat fluidRho = m[0]; FORDF1 { fluidRho += m[l]; }
const LbmVec vel(mObjectSpeeds[OId]);
ux=vel[0], uy=vel[1], uz=vel[2];
usqr = 1.5 * (ux*ux + uy*uy + uz*uz);
- FORDF0 { RAC(tcel, l) = D::getCollideEq(l, fluidRho,ux,uy,uz); }
+ FORDF0 { RAC(tcel, l) = this->getCollideEq(l, fluidRho,ux,uy,uz); }
rho = fluidRho;
+ //errMsg("INFLOW_DEBUG","std at "<<PRINT_IJK<<" v="<<vel<<" rho="<<rho);
} else {
if(nbored&CFBnd) {
DEFAULT_STREAM;
@@ -549,7 +552,6 @@ LbmFsgrSolver<D>::mainLoop(int lev)
} else {
// do standard stream/collide
OPTIMIZED_STREAMCOLLIDE;
- // FIXME check for which cells this is executed!
oldFlag |= CFNoBndFluid;
}
}
@@ -586,7 +588,7 @@ LbmFsgrSolver<D>::mainLoop(int lev)
// calculate mass exchange for interface cells
LbmFloat myfrac = RAC(ccel,dFfrac);
-# define nbdf(l) m[ D::dfInv[(l)] ]
+# define nbdf(l) m[ this->dfInv[(l)] ]
// update mass
// only do boundaries for fluid cells, and interface cells without
@@ -693,7 +695,7 @@ LbmFsgrSolver<D>::mainLoop(int lev)
if( (ABS(nx)+ABS(ny)+ABS(nz)) > LBM_EPSILON) {
// normal ok and usable...
FORDF1 {
- if( (D::dfDvecX[l]*nx + D::dfDvecY[l]*ny + D::dfDvecZ[l]*nz) // dot Dvec,norml
+ if( (this->dfDvecX[l]*nx + this->dfDvecY[l]*ny + this->dfDvecZ[l]*nz) // dot Dvec,norml
> LBM_EPSILON) {
recons[l] = 2;
numRecons++;
@@ -707,11 +709,11 @@ LbmFsgrSolver<D>::mainLoop(int lev)
#if OPT3D==0
oldRho=RAC(ccel,0);
oldUx = oldUy = oldUz = 0.0;
- for(int l=1; l<D::cDfNum; l++) {
+ for(int l=1; l<this->cDfNum; l++) {
oldRho += RAC(ccel,l);
- oldUx += (D::dfDvecX[l]*RAC(ccel,l));
- oldUy += (D::dfDvecY[l]*RAC(ccel,l));
- oldUz += (D::dfDvecZ[l]*RAC(ccel,l));
+ oldUx += (this->dfDvecX[l]*RAC(ccel,l));
+ oldUy += (this->dfDvecY[l]*RAC(ccel,l));
+ oldUz += (this->dfDvecZ[l]*RAC(ccel,l));
}
#else // OPT3D==0
oldRho = + RAC(ccel,dC) + RAC(ccel,dN )
@@ -750,9 +752,9 @@ LbmFsgrSolver<D>::mainLoop(int lev)
// NOW - construct dist funcs from empty cells
FORDF1 {
if(recons[ l ]) {
- m[ D::dfInv[l] ] =
- D::getCollideEq(l, REFERENCE_PRESSURE, oldUx,oldUy,oldUz) +
- D::getCollideEq(D::dfInv[l], REFERENCE_PRESSURE, oldUx,oldUy,oldUz)
+ m[ this->dfInv[l] ] =
+ this->getCollideEq(l, REFERENCE_PRESSURE, oldUx,oldUy,oldUz) +
+ this->getCollideEq(this->dfInv[l], REFERENCE_PRESSURE, oldUx,oldUy,oldUz)
- MYDF( l );
}
}
@@ -780,12 +782,6 @@ LbmFsgrSolver<D>::mainLoop(int lev)
if(recons[dWB]) { m[dET] = EQWB + EQET - MYDF(dWB); }
#endif
- // mass streaming done... do normal collide
- ux = mLevel[lev].gravity[0]; uy = mLevel[lev].gravity[1]; uz = mLevel[lev].gravity[2];
- ux *= mass; uy *= mass; uz *= mass; // acc. according to mass in cell
- DEFAULT_COLLIDE;
- PERFORM_USQRMAXCHECK;
- // rho init from default collide necessary for fill/empty check below
// inflow bc handling
if(oldFlag & (CFMbndInflow)) {
@@ -794,12 +790,161 @@ LbmFsgrSolver<D>::mainLoop(int lev)
mass += 0.25;
mInitialMass += 0.25;
}
- }
+ const int OId = oldFlag>>24;
+ const LbmVec vel(mObjectSpeeds[OId]);
+ ux=vel[0], uy=vel[1], uz=vel[2];
+ //? usqr = 1.5 * (ux*ux + uy*uy + uz*uz);
+ //FORDF0 { RAC(tcel, l) = this->getCollideEq(l, fluidRho,ux,uy,uz); } rho = fluidRho;
+ rho = REFERENCE_PRESSURE;
+ FORDF0 { RAC(tcel, l) = this->getCollideEq(l, rho,ux,uy,uz); }
+ //errMsg("INFLOW_DEBUG","if at "<<PRINT_IJK<<" v="<<vel<<" rho="<<rho);
+ } else {
+ // normal collide
+ // mass streaming done... do normal collide
+ ux = mLevel[lev].gravity[0]; uy = mLevel[lev].gravity[1]; uz = mLevel[lev].gravity[2];
+ ux *= mass; uy *= mass; uz *= mass; // acc. according to mass in cell
+ DEFAULT_COLLIDE;
+ PERFORM_USQRMAXCHECK;
+ // rho init from default collide necessary for fill/empty check below
+ }
+
+ // testing..., particle generation
+//# include "est_if.h" test_if
+ // also check oldFlag for CFNoNbFluid, test
+ // for inflow no pargen test
+ // NOBUBBB!
+ if((this->mInitDone) //&&(mUseTestdata)
+ && (!((oldFlag|newFlag)&CFNoNbEmpty))
+ && (!((oldFlag|newFlag)&CFNoDelete))
+ && (this->mPartGenProb>0.0)) {
+ bool bndOk=true;
+ if( (i<1+mCutoff)||(i>this->mSizex-1-mCutoff)||
+ (j<1+mCutoff)||(j>this->mSizey-1-mCutoff)||
+ (k<1+mCutoff)||(k>this->mSizez-1-mCutoff) ) { bndOk=false; }
+
+ LbmFloat realWorldFac = (mLevel[lev].simCellSize / mLevel[lev].timestep);
+ LbmFloat rux = (ux * realWorldFac);
+ LbmFloat ruy = (uy * realWorldFac);
+ LbmFloat ruz = (uz * realWorldFac);
+ LbmFloat rl = norm(ntlVec3Gfx(rux,ruy,ruz));
+ // WHMOD
+ const LbmFloat val2fac = 1.0; //? TODO N test? /(this->mPartGenProb); // FIXME remove factor!
+ bool doAdd = true;
+
+ LbmFloat prob = (rand()/(RAND_MAX+1.0));
+ LbmFloat basethresh = this->mPartGenProb*lcsmqo*rl;
+ if( (prob< (basethresh*rl)) && (lcsmqo>0.0095) && (rl>2.5) ) {
+ // add
+ } else {
+ doAdd = false; // dont...
+ }
+
+//#define SLOWDOWNREGION (2*mCutoff)
+#if LBMDIM==3
+ // normal
+#define SLOWDOWNREGION (this->mSizez/5)
+#else // LBMDIM==2
+ // off
+#define SLOWDOWNREGION 10
+#endif // LBMDIM==2
+#define P_LCSMQO 0.01
+
+ // "wind" disturbance
+ // use realworld relative velocity here instead?
+ if(
+ ((rl>1.0) && (lcsmqo<P_LCSMQO)) // normal checks
+ ||(k>this->mSizez-SLOWDOWNREGION) ) {
+ LbmFloat nuz = uz;
+ LbmFloat jdf; // = 0.05 * (rand()/(RAND_MAX+1.0));
+ if(rl>1.0) jdf *= (rl-1.0);
+ if(k>this->mSizez-SLOWDOWNREGION) {
+ // special case
+ LbmFloat zfac = (LbmFloat)( k-(this->mSizez-SLOWDOWNREGION) );
+ zfac /= (LbmFloat)(SLOWDOWNREGION);
+ nuz += zfac; // check max speed? OFF?
+ } else {
+ // normal probability
+ LbmFloat fac = P_LCSMQO-lcsmqo;
+ jdf *= fac;
+ }
+ FORDF1 {
+ jdf = 0.05 * (rand()/(RAND_MAX+1.0));
+ // TODO use wind velocity?
+ if(jdf>0.025) {
+ const LbmFloat add = this->dfLength[l]*(-ux*this->dfDvecX[l]-uy*this->dfDvecY[l]-nuz*this->dfDvecZ[l])*jdf;
+ RAC(tcel,l) += add*jdf; }
+ }
+ //errMsg("TOPDOWNCORR"," jdf:"<<jdf<<" rl"<<rl<<" vel "<<PRINT_VEC(ux,uy,nuz)<<" rwv"<<PRINT_VEC(rux,ruy,ruz) );
+ //errMsg("TOPDOWNCORR"," jdf:"<<jdf<<" rl"<<rl<<" vel "<<norm(LbmVec(ux,uy,nuz))<<" rwv"<<norm(LbmVec(rux,ruy,ruz)) );
+ } // wind disturbance
+
+ if(usqr<0.0001) doAdd=false; // TODO check!?
+ // if outside, and 20% above sea level, delete, TODO really check level?
+ //if((!bndOk)&&((LbmFloat)k>pTest->mFluidHeight*1.5)) { doAdd=true; } // FORCEDISSOLVE
+ //? if(!bndOk) doAdd=false;
+ //if(this->mStepCnt>700) errMsg("DFJITT"," at "<<PRINT_IJK<<"rwl:"<<rl<<" usqr:"<<usqr <<" qo:"<<lcsmqo<<" add="<<doAdd );
+
+ if( (doAdd) ) { // ADD DROP
+ LbmFloat len = norm(LbmVec(ux,uy,uz));
+ // WHMOD
+ //for(int s=0; s<10; s++) { // multiple parts
+ for(int s=0; s<1; s++) { // one part!
+ //LbmFloat prob = this->mPartGenProb * 0.02* (rand()/(RAND_MAX+1.0));
+ const LbmFloat posjitter = 1.0;
+ const LbmFloat posjitteroffs = posjitter*-0.5;
+ LbmFloat jpx = posjitteroffs+ posjitter* (rand()/(RAND_MAX+1.0));
+ LbmFloat jpy = posjitteroffs+ posjitter* (rand()/(RAND_MAX+1.0));
+ LbmFloat jpz = posjitteroffs+ posjitter* (rand()/(RAND_MAX+1.0));
+
+ const LbmFloat jitterstr = 0.1;
+ const LbmFloat jitteroffs = jitterstr*-0.5;
+ LbmFloat jx = jitteroffs+ jitterstr* (rand()/(RAND_MAX+1.0));
+ LbmFloat jy = jitteroffs+ jitterstr* (rand()/(RAND_MAX+1.0));
+ LbmFloat jz = jitteroffs+ jitterstr* (rand()/(RAND_MAX+1.0));
+
+ // average normal & velocity
+ // -> mostly along velocity dir, many into surface
+ LbmVec pv = (LbmVec(nx+jx,ny+jy,nz+jz)*0.75 + getNormalized(LbmVec(ux,uy,uz)) )*0.35;
+ normalize(pv);
+
+ LbmFloat srci = i+0.5+jpx; // TEST? + (pv[0]*1.41);
+ LbmFloat srcj = j+0.5+jpy; // TEST? + (pv[1]*1.41);
+ LbmFloat srck = k+0.5+jpz; // TEST? + (pv[2]*1.41);
+ int type=0;
+ //if((s%3)!=2) {
+
+ type=PART_DROP;
+ // drop
+ srci += (pv[0]*1.41);
+ srcj += (pv[1]*1.41);
+ srck += (pv[2]*1.41);
+ if(!(RFLAG(lev, (int)(srci),(int)(srcj),(int)(srck),SRCS(lev)) &CFEmpty)) continue; // only add in good direction
+ //} else { type=PART_FLOAT; }
+
+ pv *= len;
+ LbmFloat size = 1.0+ 9.0* (rand()/(RAND_MAX+1.0));
+
+ mpParticles->addParticle(srci, srcj, srck); //i+0.5+jpx,j+0.5+jpy,k+0.5+jpz);
+ mpParticles->getLast()->setVel(pv[0],pv[1],pv[2]);
+ //? mpParticles->getLast()->advanceVel(); // advance a bit outwards
+ mpParticles->getLast()->setStatus(PART_IN);
+ mpParticles->getLast()->setType(type);
+ //mpParticles->getLast()->setType(PART_INTER);
+ //if((s%3)==2) mpParticles->getLast()->setType(PART_FLOAT);
+ mpParticles->getLast()->setSize(size);
+ //errMsg("NEWPART"," at "<<PRINT_IJK<<" u="<<PRINT_VEC(ux,uy,uz) <<" RWu="<<PRINT_VEC(rux,ruy,ruz)<<" add"<<doAdd<<" pvel="<<pv );
+ //errMsg("NEWPART"," at "<<PRINT_IJK<<" u="<<norm(LbmVec(ux,uy,uz)) <<" RWu="<<norm(LbmVec(rux,ruy,ruz))<<" add"<<doAdd<<" pvel="<<norm(pv) );
+ //if(!bndOk){ mass -= val2fac*size*0.02; } // FORCEDISSOLVE
+ mass -= val2fac*size*0.0015; // NTEST!
+ //mass -= val2fac*size*0.001; // NTEST!
+#if LBMDIM==2
+ mpParticles->getLast()->setVel(pv[0],pv[1],0.0);
+ mpParticles->getLast()->setPos(ntlVec3Gfx(srci,srcj,0.5));
+#endif // LBMDIM==2
+ } // multiple parts
+ } // doAdd
+ } // */
-# if ELBEEM_PLUGIN!=1
- // testing...
-# include "test_if.h"
-# endif // ELBEEM_PLUGIN
// interface cell filled or emptied?
iffilled = ifemptied = 0;
@@ -851,7 +996,7 @@ LbmFsgrSolver<D>::mainLoop(int lev)
#else // PARALLEL==1
mListFull.push_back( filledp );
#endif // PARALLEL==1
- //D::mNumFilledCells++; // DEBUG
+ //this->mNumFilledCells++; // DEBUG
calcCellsFilled++;
}
else if(ifemptied) {
@@ -862,7 +1007,7 @@ LbmFsgrSolver<D>::mainLoop(int lev)
#else // PARALLEL==1
mListEmpty.push_back( emptyp );
#endif // PARALLEL==1
- //D::mNumEmptiedCells++; // DEBUG
+ //this->mNumEmptiedCells++; // DEBUG
calcCellsEmptied++;
} else {
// ...
@@ -875,13 +1020,13 @@ LbmFsgrSolver<D>::mainLoop(int lev)
float flux = FLUX_INIT; // dxqn on
if(newFlag&CFNoBndFluid) {
//flux = 50.0; // extreme on
- for(int nn=1; nn<D::cDfNum; nn++) {
- if(nbflag[nn] & (CFFluid|CFInter|CFBnd)) { flux += D::dfLength[nn]; }
+ for(int nn=1; nn<this->cDfNum; nn++) {
+ if(nbflag[nn] & (CFFluid|CFInter|CFBnd)) { flux += this->dfLength[nn]; }
}
// optical hack - smooth slow moving
// surface regions
if(usqr< sssUsqrLimit) {
- for(int nn=1; nn<D::cDfNum; nn++) {
+ for(int nn=1; nn<this->cDfNum; nn++) {
if(nbfracs[nn]!=0.0) {
LbmFloat curSmooth = (sssUsqrLimit-usqr)*sssUsqrLimitInv;
if(curSmooth>1.0) curSmooth=1.0;
@@ -923,9 +1068,9 @@ LbmFsgrSolver<D>::mainLoop(int lev)
//errMsg("DFINI"," maxr l"<<mMaxRefine<<" cm="<<calcCurrentMass<<" cv="<<calcCurrentVolume );
mLevel[lev].lmass = calcCurrentMass;
mLevel[lev].lvolume = calcCurrentVolume;
- D::mNumFilledCells = calcCellsFilled;
- D::mNumEmptiedCells = calcCellsEmptied;
- D::mNumUsedCells = calcNumUsedCells;
+ this->mNumFilledCells = calcCellsFilled;
+ this->mNumEmptiedCells = calcCellsEmptied;
+ this->mNumUsedCells = calcNumUsedCells;
#if PARALLEL==1
PARA_FINISH();
#endif // PARALLEL==1
@@ -933,9 +1078,10 @@ LbmFsgrSolver<D>::mainLoop(int lev)
// check other vars...?
}
-template<class D>
-void
-LbmFsgrSolver<D>::coarseCalculateFluxareas(int lev)
+// ZDEB
+
+
+void LbmFsgrSolver::coarseCalculateFluxareas(int lev)
{
#if LBM_NOADCOARSENING==1
if(mMaxRefine>0) errMsg("LbmFsgrSolver","Adaptive Coarsening not compiled, but refinement switched on ("<<mMaxRefine<<")!");
@@ -945,8 +1091,8 @@ LbmFsgrSolver<D>::coarseCalculateFluxareas(int lev)
if( RFLAG(lev, i,j,k,mLevel[lev].setCurr) & CFFluid) {
if( RFLAG(lev+1, i*2,j*2,k*2,mLevel[lev+1].setCurr) & CFGrFromCoarse) {
LbmFloat totArea = mFsgrCellArea[0]; // for l=0
- for(int l=1; l<D::cDirNum; l++) {
- int ni=(2*i)+D::dfVecX[l], nj=(2*j)+D::dfVecY[l], nk=(2*k)+D::dfVecZ[l];
+ for(int l=1; l<this->cDirNum; l++) {
+ int ni=(2*i)+this->dfVecX[l], nj=(2*j)+this->dfVecY[l], nk=(2*k)+this->dfVecZ[l];
if(RFLAG(lev+1, ni,nj,nk, mLevel[lev+1].setCurr)&
(CFGrFromCoarse|CFUnused|CFEmpty) //? (CFBnd|CFEmpty|CFGrFromCoarse|CFUnused)
) {
@@ -965,13 +1111,11 @@ LbmFsgrSolver<D>::coarseCalculateFluxareas(int lev)
//errMsg("DFINI"," at l"<<lev<<" "<<PRINT_IJK<<" v:"<<QCELL(lev, i,j,k,mLevel[lev].setCurr, dFlux) );
}
} // } TEST DEBUG
- if(!D::mSilent){ debMsgStd("coarseCalculateFluxareas",DM_MSG,"level "<<lev<<" calculated", 7); }
+ if(!this->mSilent){ debMsgStd("coarseCalculateFluxareas",DM_MSG,"level "<<lev<<" calculated", 7); }
#endif //! LBM_NOADCOARSENING==1
}
-template<class D>
-void
-LbmFsgrSolver<D>::coarseAdvance(int lev)
+void LbmFsgrSolver::coarseAdvance(int lev)
{
#if LBM_NOADCOARSENING==1
if(mMaxRefine>0) errMsg("LbmFsgrSolver","Adaptive Coarsening not compiled, but refinement switched on ("<<mMaxRefine<<")!");
@@ -999,7 +1143,7 @@ LbmFsgrSolver<D>::coarseAdvance(int lev)
ccel -= QCELLSTEP;
tcel = RACPNT(lev, 1,1,getForZMin1() ,TSET(lev)); // QTEST
tcel -= QCELLSTEP;
- //if(strstr(D::getName().c_str(),"Debug")){ errMsg("DEBUG","DEBUG!!!!!!!!!!!!!!!!!!!!!!!"); }
+ //if(strstr(this->getName().c_str(),"Debug")){ errMsg("DEBUG","DEBUG!!!!!!!!!!!!!!!!!!!!!!!"); }
for(int k= getForZMin1(); k< getForZMax1(lev); ++k) {
for(int j=1;j<mLevel[lev].lSizey-1;++j) {
@@ -1034,11 +1178,11 @@ LbmFsgrSolver<D>::coarseAdvance(int lev)
// old INTCFCOARSETEST==1
if((*pFlagSrc) & CFGrFromCoarse) { // interpolateFineFromCoarse test!
- if(( D::mStepCnt & (1<<(mMaxRefine-lev)) ) ==1) {
+ if(( this->mStepCnt & (1<<(mMaxRefine-lev)) ) ==1) {
FORDF0 { RAC(tcel,l) = RAC(ccel,l); }
} else {
interpolateCellFromCoarse( lev, i,j,k, TSET(lev), 0.0, CFFluid|CFGrFromCoarse, false);
- D::mNumUsedCells++;
+ this->mNumUsedCells++;
}
continue; // interpolateFineFromCoarse test!
} // interpolateFineFromCoarse test! old INTCFCOARSETEST==1
@@ -1065,10 +1209,10 @@ LbmFsgrSolver<D>::coarseAdvance(int lev)
#if FSGR_STRICT_DEBUG==1
if(rho<-1.0){ debugMarkCell(lev, i,j,k );
errMsg("INVRHOCELL_CHECK"," l"<<lev<<" "<< PRINT_IJK<<" rho:"<<rho );
- D::mPanic = 1;
+ CAUSE_PANIC;
}
#endif // FSGR_STRICT_DEBUG==1
- D::mNumUsedCells++;
+ this->mNumUsedCells++;
}
}
@@ -1085,7 +1229,7 @@ LbmFsgrSolver<D>::coarseAdvance(int lev)
//errMsg("coarseAdvance","level "<<lev<<" stepped from "<<mLevel[lev].setCurr<<" to "<<mLevel[lev].setOther);
- if(!D::mSilent){ errMsg("coarseAdvance","level "<<lev<<" stepped from "<<SRCS(lev)<<" to "<<TSET(lev)); }
+ if(!this->mSilent){ errMsg("coarseAdvance","level "<<lev<<" stepped from "<<SRCS(lev)<<" to "<<TSET(lev)); }
// */
// update other set
@@ -1107,9 +1251,7 @@ LbmFsgrSolver<D>::coarseAdvance(int lev)
// get dfs from level (lev+1) to (lev) coarse border nodes
-template<class D>
-void
-LbmFsgrSolver<D>::coarseRestrictFromFine(int lev)
+void LbmFsgrSolver::coarseRestrictFromFine(int lev)
{
#if LBM_NOADCOARSENING==1
if(mMaxRefine>0) errMsg("LbmFsgrSolver","Adaptive Coarsening not compiled, but refinement switched on ("<<mMaxRefine<<")!");
@@ -1153,7 +1295,7 @@ LbmFsgrSolver<D>::coarseRestrictFromFine(int lev)
mNumInterdCells++;
coarseRestrictCell(lev, i,j,k,srcSet,dstSet);
- D::mNumUsedCells++;
+ this->mNumUsedCells++;
} // from fine & fluid
else {
if(RFLAG(lev+1, 2*i,2*j,2*k,srcSet) & CFGrFromCoarse) {
@@ -1164,13 +1306,11 @@ LbmFsgrSolver<D>::coarseRestrictFromFine(int lev)
}
} // & fluid
}}}
- if(!D::mSilent){ errMsg("coarseRestrictFromFine"," from l"<<(lev+1)<<",s"<<mLevel[lev+1].setCurr<<" to l"<<lev<<",s"<<mLevel[lev].setCurr); }
+ if(!this->mSilent){ errMsg("coarseRestrictFromFine"," from l"<<(lev+1)<<",s"<<mLevel[lev+1].setCurr<<" to l"<<lev<<",s"<<mLevel[lev].setCurr); }
#endif //! LBM_NOADCOARSENING==1
}
-template<class D>
-bool
-LbmFsgrSolver<D>::adaptGrid(int lev) {
+bool LbmFsgrSolver::adaptGrid(int lev) {
#if LBM_NOADCOARSENING==1
if(mMaxRefine>0) errMsg("LbmFsgrSolver","Adaptive Coarsening not compiled, but refinement switched on ("<<mMaxRefine<<")!");
lev =0; // get rid of warnings...
@@ -1190,11 +1330,11 @@ LbmFsgrSolver<D>::adaptGrid(int lev) {
const int srcFineSet = mLevel[lev+1].setCurr;
const bool debugRefinement = false;
- // use template functions for 2D/3D
- /*if(strstr(D::getName().c_str(),"Debug"))
+ // use //template functions for 2D/3D
+ /*if(strstr(this->getName().c_str(),"Debug"))
if(lev+1==mMaxRefine) { // mixborder
- for(int l=0;((l<D::cDirNum) && (!removeFromFine)); l++) { // FARBORD
- int ni=2*i+2*D::dfVecX[l], nj=2*j+2*D::dfVecY[l], nk=2*k+2*D::dfVecZ[l];
+ for(int l=0;((l<this->cDirNum) && (!removeFromFine)); l++) { // FARBORD
+ int ni=2*i+2*this->dfVecX[l], nj=2*j+2*this->dfVecY[l], nk=2*k+2*this->dfVecZ[l];
if(RFLAG(lev+1, ni,nj,nk, srcFineSet)&CFBnd) { // NEWREFT
removeFromFine=true;
}
@@ -1226,18 +1366,18 @@ LbmFsgrSolver<D>::adaptGrid(int lev) {
RFLAG(lev, i,j,k, dstSet) |= CFGrCoarseInited; // remove later on? FIXME?
#endif // FSGR_STRICT_DEBUG==1
//RFLAG(lev, i,j,k, mLevel[lev].setOther) = CFEmpty; // FLAGTEST
- if((D::cDimension==2)&&(debugRefinement)) debugMarkCell(lev,i,j,k);
+ if((LBMDIM==2)&&(debugRefinement)) debugMarkCell(lev,i,j,k);
change=true;
mNumFsgrChanges++;
- for(int l=1; l<D::cDirNum; l++) {
- int ni=i+D::dfVecX[l], nj=j+D::dfVecY[l], nk=k+D::dfVecZ[l];
+ for(int l=1; l<this->cDirNum; l++) {
+ int ni=i+this->dfVecX[l], nj=j+this->dfVecY[l], nk=k+this->dfVecZ[l];
//errMsg("performRefinement","On lev:"<<lev<<" check: "<<PRINT_VEC(ni,nj,nk)<<" set:"<<dstSet<<" = "<<convertCellFlagType2String(RFLAG(lev, ni,nj,nk, srcSet)) );
if( ( RFLAG(lev, ni,nj,nk, srcSet)&CFFluid ) &&
(!(RFLAG(lev, ni,nj,nk, srcSet)&CFGrFromFine)) ) { // dont change status of nb. from fine cells
// tag as inited for debugging, cell contains fluid DFs anyway
RFLAG(lev, ni,nj,nk, dstSet) = CFFluid|CFGrFromFine|CFGrCoarseInited;
//errMsg("performRefinement","On lev:"<<lev<<" set to from fine: "<<PRINT_VEC(ni,nj,nk)<<" set:"<<dstSet);
- //if((D::cDimension==2)&&(debugRefinement)) debugMarkCell(lev,ni,nj,nk);
+ //if((LBMDIM==2)&&(debugRefinement)) debugMarkCell(lev,ni,nj,nk);
}
} // l
@@ -1272,14 +1412,14 @@ LbmFsgrSolver<D>::adaptGrid(int lev) {
// from coarse cells without unused nbs are not necessary...! -> remove
bool invNb = false;
bool fluidNb = false;
- for(int l=1; l<D::cDirNum; l++) {
+ for(int l=1; l<this->cDirNum; l++) {
if(RFLAG_NB(lev, i, j, k, srcSet, l) & CFUnused) { invNb = true; }
if(RFLAG_NB(lev, i, j, k, srcSet, l) & (CFGrNorm)) { fluidNb = true; }
}
if(!invNb) {
// no unused cells around -> calculate normally from now on
RFLAG(lev, i,j,k, dstSet) = CFFluid|CFGrNorm;
- if((D::cDimension==2)&&(debugRefinement)) debugMarkCell(lev, i, j, k);
+ if((LBMDIM==2)&&(debugRefinement)) debugMarkCell(lev, i, j, k);
change=true;
mNumFsgrChanges++;
} // from advance
@@ -1287,7 +1427,7 @@ LbmFsgrSolver<D>::adaptGrid(int lev) {
// no fluid cells near -> no transfer necessary
RFLAG(lev, i,j,k, dstSet) = CFUnused;
//RFLAG(lev, i,j,k, mLevel[lev].setOther) = CFUnused; // FLAGTEST
- if((D::cDimension==2)&&(debugRefinement)) debugMarkCell(lev, i, j, k);
+ if((LBMDIM==2)&&(debugRefinement)) debugMarkCell(lev, i, j, k);
change=true;
mNumFsgrChanges++;
} // from advance
@@ -1300,18 +1440,18 @@ LbmFsgrSolver<D>::adaptGrid(int lev) {
//errMsg("performRefinement","Removing CFGrFromCoarse on lev"<<lev<<" " <<PRINT_IJK<<" due to finer from coarse cell " );
RFLAG(lev, i,j,k, dstSet) = CFFluid|CFGrNorm;
if(lev>0) RFLAG(lev-1, i/2,j/2,k/2, mLevel[lev-1].setCurr) &= (~CFGrToFine); // TODO add more of these?
- if((D::cDimension==2)&&(debugRefinement)) debugMarkCell(lev, i, j, k);
+ if((LBMDIM==2)&&(debugRefinement)) debugMarkCell(lev, i, j, k);
change=true;
mNumFsgrChanges++;
- for(int l=1; l<D::cDirNum; l++) {
- int ni=i+D::dfVecX[l], nj=j+D::dfVecY[l], nk=k+D::dfVecZ[l];
+ for(int l=1; l<this->cDirNum; l++) {
+ int ni=i+this->dfVecX[l], nj=j+this->dfVecY[l], nk=k+this->dfVecZ[l];
if(RFLAG(lev, ni,nj,nk, srcSet)&(CFGrNorm)) { //ok
- for(int m=1; m<D::cDirNum; m++) {
- int mi= ni +D::dfVecX[m], mj= nj +D::dfVecY[m], mk= nk +D::dfVecZ[m];
+ for(int m=1; m<this->cDirNum; m++) {
+ int mi= ni +this->dfVecX[m], mj= nj +this->dfVecY[m], mk= nk +this->dfVecZ[m];
if(RFLAG(lev, mi, mj, mk, srcSet)&CFUnused) {
// norm cells in neighborhood with unused nbs have to be new border...
RFLAG(lev, ni,nj,nk, dstSet) = CFFluid|CFGrFromCoarse;
- if((D::cDimension==2)&&(debugRefinement)) debugMarkCell(lev,ni,nj,nk);
+ if((LBMDIM==2)&&(debugRefinement)) debugMarkCell(lev,ni,nj,nk);
}
}
// these alreay have valid values...
@@ -1319,7 +1459,7 @@ LbmFsgrSolver<D>::adaptGrid(int lev) {
else if(RFLAG(lev, ni,nj,nk, srcSet)&(CFUnused)) { //ok
// this should work because we have a valid neighborhood here for now
interpolateCellFromCoarse(lev, ni, nj, nk, dstSet, interTime, CFFluid|CFGrFromCoarse, false);
- if((D::cDimension==2)&&(debugRefinement)) debugMarkCell(lev,ni,nj,nk);
+ if((LBMDIM==2)&&(debugRefinement)) debugMarkCell(lev,ni,nj,nk);
mNumFsgrChanges++;
}
} // l
@@ -1347,31 +1487,31 @@ LbmFsgrSolver<D>::adaptGrid(int lev) {
RFLAG(lev+1, 2*i,2*j,2*k, srcFineSet)=setf;
change=true;
mNumFsgrChanges++;
- for(int l=1; l<D::cDirNum; l++) {
- int bi=(2*i)+D::dfVecX[l], bj=(2*j)+D::dfVecY[l], bk=(2*k)+D::dfVecZ[l];
+ for(int l=1; l<this->cDirNum; l++) {
+ int bi=(2*i)+this->dfVecX[l], bj=(2*j)+this->dfVecY[l], bk=(2*k)+this->dfVecZ[l];
if(RFLAG(lev+1, bi, bj, bk, srcFineSet)&(CFGrFromCoarse)) {
//errMsg("performRefinement","Removing CFGrFromCoarse on lev"<<(lev+1)<<" "<<PRINT_VEC(bi,bj,bk) );
RFLAG(lev+1, bi, bj, bk, srcFineSet) = setf;
- if((D::cDimension==2)&&(debugRefinement)) debugMarkCell(lev+1,bi,bj,bk);
+ if((LBMDIM==2)&&(debugRefinement)) debugMarkCell(lev+1,bi,bj,bk);
}
else if(RFLAG(lev+1, bi, bj, bk, srcFineSet)&(CFUnused )) {
//errMsg("performRefinement","Removing CFUnused on lev"<<(lev+1)<<" "<<PRINT_VEC(bi,bj,bk) );
interpolateCellFromCoarse(lev+1, bi, bj, bk, srcFineSet, interTime, setf, false);
- if((D::cDimension==2)&&(debugRefinement)) debugMarkCell(lev+1,bi,bj,bk);
+ if((LBMDIM==2)&&(debugRefinement)) debugMarkCell(lev+1,bi,bj,bk);
mNumFsgrChanges++;
}
}
- for(int l=1; l<D::cDirNum; l++) {
- int bi=(2*i)+D::dfVecX[l], bj=(2*j)+D::dfVecY[l], bk=(2*k)+D::dfVecZ[l];
+ for(int l=1; l<this->cDirNum; l++) {
+ int bi=(2*i)+this->dfVecX[l], bj=(2*j)+this->dfVecY[l], bk=(2*k)+this->dfVecZ[l];
if( (RFLAG(lev+1, bi, bj, bk, srcFineSet)&CFFluid ) &&
(!(RFLAG(lev+1, bi, bj, bk, srcFineSet)&CFGrFromCoarse)) ) {
// all unused nbs now of coarse have to be from coarse
- for(int m=1; m<D::cDirNum; m++) {
- int mi= bi +D::dfVecX[m], mj= bj +D::dfVecY[m], mk= bk +D::dfVecZ[m];
+ for(int m=1; m<this->cDirNum; m++) {
+ int mi= bi +this->dfVecX[m], mj= bj +this->dfVecY[m], mk= bk +this->dfVecZ[m];
if(RFLAG(lev+1, mi, mj, mk, srcFineSet)&CFUnused) {
//errMsg("performRefinement","Changing CFUnused on lev"<<(lev+1)<<" "<<PRINT_VEC(mi,mj,mk) );
interpolateCellFromCoarse(lev+1, mi, mj, mk, srcFineSet, interTime, CFFluid|CFGrFromCoarse, false);
- if((D::cDimension==2)&&(debugRefinement)) debugMarkCell(lev+1,mi,mj,mk);
+ if((LBMDIM==2)&&(debugRefinement)) debugMarkCell(lev+1,mi,mj,mk);
mNumFsgrChanges++;
}
}
@@ -1384,11 +1524,11 @@ LbmFsgrSolver<D>::adaptGrid(int lev) {
}}} // TEST
// PASS 3 */
- if(!D::mSilent){ errMsg("performRefinement"," for l"<<lev<<" done ("<<change<<") " ); }
+ if(!this->mSilent){ errMsg("performRefinement"," for l"<<lev<<" done ("<<change<<") " ); }
} // PASS 1-3
// refinement done
- //LbmFsgrSolver<D>::performCoarsening(int lev) {
+ //LbmFsgrSolver::performCoarsening(int lev) {
{ // PASS 4,5
bool nbsok;
// WARNING
@@ -1399,7 +1539,7 @@ LbmFsgrSolver<D>::adaptGrid(int lev) {
const bool debugCoarsening = false;
// PASS 5 test DEBUG
- /*if(D::mInitDone) {
+ /*if(this->mInitDone) {
for(int k= getForZMin1(); k< getForZMax1(lev); ++k) {
for(int j=1;j<mLevel[lev].lSizey-1;++j) {
for(int i=1;i<mLevel[lev].lSizex-1;++i) {
@@ -1416,7 +1556,7 @@ LbmFsgrSolver<D>::adaptGrid(int lev) {
change = true;
mNumFsgrChanges++;
RFLAG(lev, i,j,k, srcSet) = CFFluid|CFGrFromFine;
- if((D::cDimension==2)&&(debugCoarsening)) debugMarkCell(lev,i,j,k);
+ if((LBMDIM==2)&&(debugCoarsening)) debugMarkCell(lev,i,j,k);
// same as restr from fine func! not necessary ?!
// coarseRestrictFromFine part
coarseRestrictCell(lev, i,j,k,srcSet, dstFineSet);
@@ -1425,11 +1565,11 @@ LbmFsgrSolver<D>::adaptGrid(int lev) {
}}} // TEST!
} // PASS 5 */
- // use template functions for 2D/3D
- /*if(strstr(D::getName().c_str(),"Debug"))
+ // use //template functions for 2D/3D
+ /*if(strstr(this->getName().c_str(),"Debug"))
if((nbsok)&&(lev+1==mMaxRefine)) { // mixborder
- for(int l=0;((l<D::cDirNum) && (nbsok)); l++) { // FARBORD
- int ni=2*i+2*D::dfVecX[l], nj=2*j+2*D::dfVecY[l], nk=2*k+2*D::dfVecZ[l];
+ for(int l=0;((l<this->cDirNum) && (nbsok)); l++) { // FARBORD
+ int ni=2*i+2*this->dfVecX[l], nj=2*j+2*this->dfVecY[l], nk=2*k+2*this->dfVecZ[l];
if(RFLAG(lev+1, ni,nj,nk, dstFineSet)&CFBnd) { // NEWREFT
nbsok=false;
}
@@ -1451,8 +1591,8 @@ LbmFsgrSolver<D>::adaptGrid(int lev) {
if(lev+1==mMaxRefine) reqType = CFNoBndFluid;
nbsok = true;
- for(int l=0; l<D::cDirNum && nbsok; l++) {
- int ni=(2*i)+D::dfVecX[l], nj=(2*j)+D::dfVecY[l], nk=(2*k)+D::dfVecZ[l];
+ for(int l=0; l<this->cDirNum && nbsok; l++) {
+ int ni=(2*i)+this->dfVecX[l], nj=(2*j)+this->dfVecY[l], nk=(2*k)+this->dfVecZ[l];
if( (RFLAG(lev+1, ni,nj,nk, dstFineSet) & reqType) &&
(!(RFLAG(lev+1, ni,nj,nk, dstFineSet) & (notAllowed)) ) ){
// ok
@@ -1463,8 +1603,8 @@ LbmFsgrSolver<D>::adaptGrid(int lev) {
}
// dont turn CFGrFromFine above interface cells into CFGrNorm
// now check nbs on same level
- for(int l=1; l<D::cDirNum && nbsok; l++) {
- int ni=i+D::dfVecX[l], nj=j+D::dfVecY[l], nk=k+D::dfVecZ[l];
+ for(int l=1; l<this->cDirNum && nbsok; l++) {
+ int ni=i+this->dfVecX[l], nj=j+this->dfVecY[l], nk=k+this->dfVecZ[l];
if(RFLAG(lev, ni,nj,nk, srcSet)&(CFFluid)) { //ok
} else {
nbsok = false;
@@ -1477,8 +1617,8 @@ LbmFsgrSolver<D>::adaptGrid(int lev) {
mNumFsgrChanges++;
RFLAG(lev, i,j,k, srcSet) = CFFluid|CFGrNorm;
// dfs are already ok...
- //if(D::mInitDone) errMsg("performCoarsening","CFGrFromFine changed to CFGrNorm at lev"<<lev<<" " <<PRINT_IJK );
- if((D::cDimension==2)&&(debugCoarsening)) debugMarkCell(lev,i,j,k);
+ //if(this->mInitDone) errMsg("performCoarsening","CFGrFromFine changed to CFGrNorm at lev"<<lev<<" " <<PRINT_IJK );
+ if((LBMDIM==2)&&(debugCoarsening)) debugMarkCell(lev,i,j,k);
// only check complete cubes
for(int dx=-1;dx<=1;dx+=2) {
@@ -1504,31 +1644,31 @@ LbmFsgrSolver<D>::adaptGrid(int lev) {
mNumFsgrChanges++;
RFLAG(dstlev, dstx,dsty,dstz, dstFineSet) = CFUnused;
RFLAG(dstlev, dstx,dsty,dstz, mLevel[dstlev].setOther) = CFUnused; // FLAGTEST
- //if(D::mInitDone) errMsg("performCoarsening","CFGrFromFine subcube init center unused set l"<<dstlev<<" at "<<PRINT_VEC(dstx,dsty,dstz) );
+ //if(this->mInitDone) errMsg("performCoarsening","CFGrFromFine subcube init center unused set l"<<dstlev<<" at "<<PRINT_VEC(dstx,dsty,dstz) );
- for(int l=1; l<D::cDirNum; l++) {
- int dstni=dstx+D::dfVecX[l], dstnj=dsty+D::dfVecY[l], dstnk=dstz+D::dfVecZ[l];
+ for(int l=1; l<this->cDirNum; l++) {
+ int dstni=dstx+this->dfVecX[l], dstnj=dsty+this->dfVecY[l], dstnk=dstz+this->dfVecZ[l];
if(RFLAG(dstlev, dstni,dstnj,dstnk, dstFineSet)&(CFFluid)) {
RFLAG(dstlev, dstni,dstnj,dstnk, dstFineSet) = CFFluid|CFGrFromCoarse;
}
if(RFLAG(dstlev, dstni,dstnj,dstnk, dstFineSet)&(CFInter)) {
- //if(D::mInitDone) errMsg("performCoarsening","CFGrFromFine subcube init CHECK Warning - deleting interface cell...");
- D::mFixMass += QCELL( dstlev, dstni,dstnj,dstnk, dstFineSet, dMass);
+ //if(this->mInitDone) errMsg("performCoarsening","CFGrFromFine subcube init CHECK Warning - deleting interface cell...");
+ this->mFixMass += QCELL( dstlev, dstni,dstnj,dstnk, dstFineSet, dMass);
RFLAG(dstlev, dstni,dstnj,dstnk, dstFineSet) = CFFluid|CFGrFromCoarse;
}
} // l
// again check nb flags of all surrounding cells to see if any from coarse
// can be convted to unused
- for(int l=1; l<D::cDirNum; l++) {
- int dstni=dstx+D::dfVecX[l], dstnj=dsty+D::dfVecY[l], dstnk=dstz+D::dfVecZ[l];
+ for(int l=1; l<this->cDirNum; l++) {
+ int dstni=dstx+this->dfVecX[l], dstnj=dsty+this->dfVecY[l], dstnk=dstz+this->dfVecZ[l];
// have to be at least from coarse here...
//errMsg("performCoarsening","CFGrFromFine subcube init unused check l"<<dstlev<<" at "<<PRINT_VEC(dstni,dstnj,dstnk)<<" "<< convertCellFlagType2String(RFLAG(dstlev, dstni,dstnj,dstnk, dstFineSet)) );
if(!(RFLAG(dstlev, dstni,dstnj,dstnk, dstFineSet)&(CFUnused) )) {
bool delok = true;
// careful long range here... check domain bounds?
- for(int m=1; m<D::cDirNum; m++) {
- int chkni=dstni+D::dfVecX[m], chknj=dstnj+D::dfVecY[m], chknk=dstnk+D::dfVecZ[m];
+ for(int m=1; m<this->cDirNum; m++) {
+ int chkni=dstni+this->dfVecX[m], chknj=dstnj+this->dfVecY[m], chknk=dstnk+this->dfVecZ[m];
if(RFLAG(dstlev, chkni,chknj,chknk, dstFineSet)&(CFUnused|CFGrFromCoarse)) {
// this nb cell is ok for deletion
} else {
@@ -1541,13 +1681,13 @@ LbmFsgrSolver<D>::adaptGrid(int lev) {
mNumFsgrChanges++;
RFLAG(dstlev, dstni,dstnj,dstnk, dstFineSet) = CFUnused;
RFLAG(dstlev, dstni,dstnj,dstnk, mLevel[dstlev].setOther) = CFUnused; // FLAGTEST
- if((D::cDimension==2)&&(debugCoarsening)) debugMarkCell(dstlev,dstni,dstnj,dstnk);
+ if((LBMDIM==2)&&(debugCoarsening)) debugMarkCell(dstlev,dstni,dstnj,dstnk);
}
}
} // l
// treat subcube
//ebugMarkCell(lev,i+dx,j+dy,k+dz);
- //if(D::mInitDone) errMsg("performCoarsening","CFGrFromFine subcube init, dir:"<<PRINT_VEC(dx,dy,dz) );
+ //if(this->mInitDone) errMsg("performCoarsening","CFGrFromFine subcube init, dir:"<<PRINT_VEC(dx,dy,dz) );
}
} } }
@@ -1560,13 +1700,13 @@ LbmFsgrSolver<D>::adaptGrid(int lev) {
/*if( RFLAG(lev, i,j,k,srcSet) & CFFluid) {
if( RFLAG(lev+1, i*2,j*2,k*2,dstFineSet) & CFGrFromCoarse) {
LbmFloat totArea = mFsgrCellArea[0]; // for l=0
- for(int l=1; l<D::cDirNum; l++) {
- int ni=(2*i)+D::dfVecX[l], nj=(2*j)+D::dfVecY[l], nk=(2*k)+D::dfVecZ[l];
+ for(int l=1; l<this->cDirNum; l++) {
+ int ni=(2*i)+this->dfVecX[l], nj=(2*j)+this->dfVecY[l], nk=(2*k)+this->dfVecZ[l];
if(RFLAG(lev+1, ni,nj,nk, dstFineSet)&
(CFGrFromCoarse|CFUnused|CFEmpty) //? (CFBnd|CFEmpty|CFGrFromCoarse|CFUnused)
//(CFUnused|CFEmpty) //? (CFBnd|CFEmpty|CFGrFromCoarse|CFUnused)
) {
- //LbmFloat area = 0.25; if(D::dfVecX[l]!=0) area *= 0.5; if(D::dfVecY[l]!=0) area *= 0.5; if(D::dfVecZ[l]!=0) area *= 0.5;
+ //LbmFloat area = 0.25; if(this->dfVecX[l]!=0) area *= 0.5; if(this->dfVecY[l]!=0) area *= 0.5; if(this->dfVecZ[l]!=0) area *= 0.5;
totArea += mFsgrCellArea[l];
}
} // l
@@ -1582,15 +1722,15 @@ LbmFsgrSolver<D>::adaptGrid(int lev) {
// PASS 5 org
- /*if(strstr(D::getName().c_str(),"Debug"))
+ /*if(strstr(this->getName().c_str(),"Debug"))
if((changeToFromFine)&&(lev+1==mMaxRefine)) { // mixborder
- for(int l=0;((l<D::cDirNum) && (changeToFromFine)); l++) { // FARBORD
- int ni=2*i+2*D::dfVecX[l], nj=2*j+2*D::dfVecY[l], nk=2*k+2*D::dfVecZ[l];
+ for(int l=0;((l<this->cDirNum) && (changeToFromFine)); l++) { // FARBORD
+ int ni=2*i+2*this->dfVecX[l], nj=2*j+2*this->dfVecY[l], nk=2*k+2*this->dfVecZ[l];
if(RFLAG(lev+1, ni,nj,nk, dstFineSet)&CFBnd) { // NEWREFT
changeToFromFine=false; }
}
}// FARBORD */
- //if(!D::mInitDone) {
+ //if(!this->mInitDone) {
for(int k= getForZMin1(); k< getForZMax1(lev); ++k) {
for(int j=1;j<mLevel[lev].lSizey-1;++j) {
for(int i=1;i<mLevel[lev].lSizex-1;++i) {
@@ -1615,7 +1755,7 @@ LbmFsgrSolver<D>::adaptGrid(int lev) {
change = true;
mNumFsgrChanges++;
RFLAG(lev, i,j,k, srcSet) = CFFluid|CFGrFromFine;
- if((D::cDimension==2)&&(debugCoarsening)) debugMarkCell(lev,i,j,k);
+ if((LBMDIM==2)&&(debugCoarsening)) debugMarkCell(lev,i,j,k);
// same as restr from fine func! not necessary ?!
// coarseRestrictFromFine part
}
@@ -1626,7 +1766,7 @@ LbmFsgrSolver<D>::adaptGrid(int lev) {
// PASS 5 */
} // coarsening, PASS 4,5
- if(!D::mSilent){ errMsg("adaptGrid"," for l"<<lev<<" done " ); }
+ if(!this->mSilent){ errMsg("adaptGrid"," for l"<<lev<<" done " ); }
return change;
#endif //! LBM_NOADCOARSENING==1
}
@@ -1635,9 +1775,7 @@ LbmFsgrSolver<D>::adaptGrid(int lev) {
//! cell restriction and prolongation
/*****************************************************************************/
-template<class D>
-void
-LbmFsgrSolver<D>::coarseRestrictCell(int lev, int i,int j,int k, int srcSet, int dstSet)
+void LbmFsgrSolver::coarseRestrictCell(int lev, int i,int j,int k, int srcSet, int dstSet)
{
#if LBM_NOADCOARSENING==1
if(mMaxRefine>0) errMsg("LbmFsgrSolver","Adaptive Coarsening not compiled, but refinement switched on ("<<mMaxRefine<<")!");
@@ -1666,8 +1804,8 @@ LbmFsgrSolver<D>::coarseRestrictCell(int lev, int i,int j,int k, int srcSet, int
# if OPT3D==0
// add up weighted dfs
FORDF0{ df[l] = 0.0;}
- for(int n=0;(n<D::cDirNum); n++) {
- int ni=2*i+1*D::dfVecX[n], nj=2*j+1*D::dfVecY[n], nk=2*k+1*D::dfVecZ[n];
+ for(int n=0;(n<this->cDirNum); n++) {
+ int ni=2*i+1*this->dfVecX[n], nj=2*j+1*this->dfVecY[n], nk=2*k+1*this->dfVecZ[n];
ccel = RACPNT(lev+1, ni,nj,nk,srcSet);// CFINTTEST
const LbmFloat weight = mGaussw[n];
FORDF0{
@@ -1685,21 +1823,21 @@ LbmFsgrSolver<D>::coarseRestrictCell(int lev, int i,int j,int k, int srcSet, int
FORDF0{
LbmFloat cdf = df[l];
rho += cdf;
- ux += (D::dfDvecX[l]*cdf);
- uy += (D::dfDvecY[l]*cdf);
- uz += (D::dfDvecZ[l]*cdf);
+ ux += (this->dfDvecX[l]*cdf);
+ uy += (this->dfDvecY[l]*cdf);
+ uz += (this->dfDvecZ[l]*cdf);
}
- FORDF0{ feq[l] = D::getCollideEq(l, rho,ux,uy,uz); }
+ FORDF0{ feq[l] = this->getCollideEq(l, rho,ux,uy,uz); }
if(mLevel[lev ].lcsmago>0.0) {
- const LbmFloat Qo = D::getLesNoneqTensorCoeff(df,feq);
- omegaDst = D::getLesOmega(mLevel[lev ].omega,mLevel[lev ].lcsmago,Qo);
- omegaSrc = D::getLesOmega(mLevel[lev+1].omega,mLevel[lev+1].lcsmago,Qo);
+ const LbmFloat Qo = this->getLesNoneqTensorCoeff(df,feq);
+ omegaDst = this->getLesOmega(mLevel[lev ].omega,mLevel[lev ].lcsmago,Qo);
+ omegaSrc = this->getLesOmega(mLevel[lev+1].omega,mLevel[lev+1].lcsmago,Qo);
} else {
omegaDst = mLevel[lev+0].omega; /* NEWSMAGOT*/
omegaSrc = mLevel[lev+1].omega;
}
- dfScale = (mLevel[lev ].stepsize/mLevel[lev+1].stepsize)* (1.0/omegaDst-1.0)/ (1.0/omegaSrc-1.0); // yu
+ dfScale = (mLevel[lev ].timestep/mLevel[lev+1].timestep)* (1.0/omegaDst-1.0)/ (1.0/omegaSrc-1.0); // yu
FORDF0{
RAC(tcel, l) = feq[l]+ (df[l]-feq[l])*dfScale;
}
@@ -1726,8 +1864,8 @@ LbmFsgrSolver<D>::coarseRestrictCell(int lev, int i,int j,int k, int srcSet, int
MSRC_EB = CCELG_EB(0);
MSRC_WT = CCELG_WT(0);
MSRC_WB = CCELG_WB(0);
- for(int n=1;(n<D::cDirNum); n++) {
- ccel = RACPNT(lev+1, 2*i+1*D::dfVecX[n], 2*j+1*D::dfVecY[n], 2*k+1*D::dfVecZ[n] ,srcSet);
+ for(int n=1;(n<this->cDirNum); n++) {
+ ccel = RACPNT(lev+1, 2*i+1*this->dfVecX[n], 2*j+1*this->dfVecY[n], 2*k+1*this->dfVecZ[n] ,srcSet);
MSRC_C += CCELG_C(n) ;
MSRC_N += CCELG_N(n) ;
MSRC_S += CCELG_S(n) ;
@@ -1765,7 +1903,7 @@ LbmFsgrSolver<D>::coarseRestrictCell(int lev, int i,int j,int k, int srcSet, int
COLL_CALCULATE_CSMOMEGAVAL(lev+0, lcsmDstOmega); \
COLL_CALCULATE_CSMOMEGAVAL(lev+1, lcsmSrcOmega); \
\
- lcsmdfscale = (mLevel[lev+0].stepsize/mLevel[lev+1].stepsize)* (1.0/lcsmDstOmega-1.0)/ (1.0/lcsmSrcOmega-1.0); \
+ lcsmdfscale = (mLevel[lev+0].timestep/mLevel[lev+1].timestep)* (1.0/lcsmDstOmega-1.0)/ (1.0/lcsmSrcOmega-1.0); \
RAC(tcel, dC ) = (lcsmeq[dC ] + (MSRC_C -lcsmeq[dC ] )*lcsmdfscale);
RAC(tcel, dN ) = (lcsmeq[dN ] + (MSRC_N -lcsmeq[dN ] )*lcsmdfscale);
RAC(tcel, dS ) = (lcsmeq[dS ] + (MSRC_S -lcsmeq[dS ] )*lcsmdfscale);
@@ -1789,8 +1927,7 @@ LbmFsgrSolver<D>::coarseRestrictCell(int lev, int i,int j,int k, int srcSet, int
#endif //! LBM_NOADCOARSENING==1
}
-template<class D>
-void LbmFsgrSolver<D>::interpolateCellFromCoarse(int lev, int i, int j,int k, int dstSet, LbmFloat t, CellFlagType flagSet, bool markNbs) {
+void LbmFsgrSolver::interpolateCellFromCoarse(int lev, int i, int j,int k, int dstSet, LbmFloat t, CellFlagType flagSet, bool markNbs) {
#if LBM_NOADCOARSENING==1
if(mMaxRefine>0) errMsg("LbmFsgrSolver","Adaptive Coarsening not compiled, but refinement switched on ("<<mMaxRefine<<")!");
i=j=k=dstSet=lev =0; // get rid of warnings...
@@ -1811,7 +1948,7 @@ void LbmFsgrSolver<D>::interpolateCellFromCoarse(int lev, int i, int j,int k, in
// this is not necessary for interpolateFineFromCoarse
if(markNbs) {
FORDF1{
- int ni=i+D::dfVecX[l], nj=j+D::dfVecY[l], nk=k+D::dfVecZ[l];
+ int ni=i+this->dfVecX[l], nj=j+this->dfVecY[l], nk=k+this->dfVecZ[l];
if(RFLAG(lev,ni,nj,nk,dstSet)&CFUnused) {
// parents have to be inited!
interpolateCellFromCoarse(lev, ni, nj, nk, dstSet, t, CFFluid|CFGrFromCoarse, false);
@@ -1871,7 +2008,7 @@ void LbmFsgrSolver<D>::interpolateCellFromCoarse(int lev, int i, int j,int k, in
ADD_INT_DFS(lev-1, (i/2)+1,(j/2)+1,(k/2)+1, t, WO1D3);
}
else {
- D::mPanic=1;
+ CAUSE_PANIC;
errFatal("interpolateCellFromCoarse","Invalid!?", SIMWORLD_GENERICERROR);
}
@@ -1883,70 +2020,74 @@ void LbmFsgrSolver<D>::interpolateCellFromCoarse(int lev, int i, int j,int k, in
/*****************************************************************************/
-/*! perform a single LBM step */
+/*! change the size of the LBM time step */
/*****************************************************************************/
-template<class D>
-void
-LbmFsgrSolver<D>::adaptTimestep()
-{
+void LbmFsgrSolver::adaptTimestep() {
LbmFloat massTOld=0.0, massTNew=0.0;
LbmFloat volTOld=0.0, volTNew=0.0;
bool rescale = false; // do any rescale at all?
LbmFloat scaleFac = -1.0; // timestep scaling
+ if(this->mPanic) return;
LbmFloat levOldOmega[FSGR_MAXNOOFLEVELS];
LbmFloat levOldStepsize[FSGR_MAXNOOFLEVELS];
for(int lev=mMaxRefine; lev>=0 ; lev--) {
levOldOmega[lev] = mLevel[lev].omega;
- levOldStepsize[lev] = mLevel[lev].stepsize;
+ levOldStepsize[lev] = mLevel[lev].timestep;
}
//if(mTimeSwitchCounts>0){ errMsg("DEB CSKIP",""); return; } // DEBUG
LbmFloat fac = 0.8; // modify time step by 20%, TODO? do multiple times for large changes?
LbmFloat diffPercent = 0.05; // dont scale if less than 5%
- LbmFloat allowMax = D::mpParam->getTadapMaxSpeed(); // maximum allowed velocity
- LbmFloat nextmax = D::mpParam->getSimulationMaxSpeed() + norm(mLevel[mMaxRefine].gravity);
-
- //newdt = D::mpParam->getStepTime() * (allowMax/nextmax);
- LbmFloat newdt = D::mpParam->getStepTime(); // newtr
- if(nextmax>allowMax/fac) {
- newdt = D::mpParam->getStepTime() * fac;
+ LbmFloat allowMax = this->mpParam->getTadapMaxSpeed(); // maximum allowed velocity
+ LbmFloat nextmax = this->mpParam->getSimulationMaxSpeed() + norm(mLevel[mMaxRefine].gravity);
+
+ //newdt = this->mpParam->getTimestep() * (allowMax/nextmax);
+ LbmFloat newdt = this->mpParam->getTimestep(); // newtr
+ if(nextmax > allowMax/fac) {
+ mTimeMaxvelStepCnt++; }
+ else { mTimeMaxvelStepCnt=0; }
+
+ // emergency, or 10 steps with high vel
+ if((mTimeMaxvelStepCnt>5) || (nextmax> (1.0/3.0) ) ) {
+ //if(nextmax > allowMax/fac) {
+ newdt = this->mpParam->getTimestep() * fac;
} else {
if(nextmax<allowMax*fac) {
- newdt = D::mpParam->getStepTime() / fac;
+ newdt = this->mpParam->getTimestep() / fac;
}
} // newtr
- //errMsg("LbmFsgrSolver::adaptTimestep","nextmax="<<nextmax<<" allowMax="<<allowMax<<" fac="<<fac<<" simmaxv="<< D::mpParam->getSimulationMaxSpeed() );
+ //errMsg("LbmFsgrSolver::adaptTimestep","nextmax="<<nextmax<<" allowMax="<<allowMax<<" fac="<<fac<<" simmaxv="<< this->mpParam->getSimulationMaxSpeed() );
bool minCutoff = false;
LbmFloat desireddt = newdt;
- if(newdt>D::mpParam->getMaxStepTime()){ newdt = D::mpParam->getMaxStepTime(); }
- if(newdt<D::mpParam->getMinStepTime()){
- newdt = D::mpParam->getMinStepTime();
+ if(newdt>this->mpParam->getMaxTimestep()){ newdt = this->mpParam->getMaxTimestep(); }
+ if(newdt<this->mpParam->getMinTimestep()){
+ newdt = this->mpParam->getMinTimestep();
if(nextmax>allowMax/fac){ minCutoff=true; } // only if really large vels...
}
- LbmFloat dtdiff = fabs(newdt - D::mpParam->getStepTime());
- if(!D::mSilent) {
- debMsgStd("LbmFsgrSolver::TAdp",DM_MSG, "new"<<newdt<<" max"<<D::mpParam->getMaxStepTime()<<" min"<<D::mpParam->getMinStepTime()<<" diff"<<dtdiff<<
- " simt:"<<mSimulationTime<<" minsteps:"<<(mSimulationTime/mMaxStepTime)<<" maxsteps:"<<(mSimulationTime/mMinStepTime) , 10); }
+ LbmFloat dtdiff = fabs(newdt - this->mpParam->getTimestep());
+ if(!this->mSilent) {
+ debMsgStd("LbmFsgrSolver::TAdp",DM_MSG, "new"<<newdt<<" max"<<this->mpParam->getMaxTimestep()<<" min"<<this->mpParam->getMinTimestep()<<" diff"<<dtdiff<<
+ " simt:"<<mSimulationTime<<" minsteps:"<<(mSimulationTime/mMaxTimestep)<<" maxsteps:"<<(mSimulationTime/mMinTimestep) , 10); }
// in range, and more than X% change?
- //if( newdt < D::mpParam->getStepTime() ) // DEBUG
+ //if( newdt < this->mpParam->getTimestep() ) // DEBUG
LbmFloat rhoAvg = mCurrentMass/mCurrentVolume;
- if( (newdt<=D::mpParam->getMaxStepTime()) && (newdt>=D::mpParam->getMinStepTime())
- && (dtdiff>(D::mpParam->getStepTime()*diffPercent)) ) {
+ if( (newdt<=this->mpParam->getMaxTimestep()) && (newdt>=this->mpParam->getMinTimestep())
+ && (dtdiff>(this->mpParam->getTimestep()*diffPercent)) ) {
if((newdt>levOldStepsize[mMaxRefine])&&(mTimestepReduceLock)) {
// wait some more...
//debMsgNnl("LbmFsgrSolver::TAdp",DM_NOTIFY," Delayed... "<<mTimestepReduceLock<<" ",10);
debMsgDirect("D");
} else {
- D::mpParam->setDesiredStepTime( newdt );
+ this->mpParam->setDesiredTimestep( newdt );
rescale = true;
- if(!D::mSilent) {
+ if(!this->mSilent) {
debMsgStd("LbmFsgrSolver::TAdp",DM_NOTIFY,"\n\n\n\n",10);
- debMsgStd("LbmFsgrSolver::TAdp",DM_NOTIFY,"Timestep change: new="<<newdt<<" old="<<D::mpParam->getStepTime()<<" maxSpeed:"<<D::mpParam->getSimulationMaxSpeed()<<" next:"<<nextmax<<" step:"<<D::mStepCnt, 10 );
+ debMsgStd("LbmFsgrSolver::TAdp",DM_NOTIFY,"Timestep change: new="<<newdt<<" old="<<this->mpParam->getTimestep()<<" maxSpeed:"<<this->mpParam->getSimulationMaxSpeed()<<" next:"<<nextmax<<" step:"<<this->mStepCnt, 10 );
debMsgStd("LbmFsgrSolver::TAdp",DM_NOTIFY,"Timestep change: "<<
"rhoAvg="<<rhoAvg<<" cMass="<<mCurrentMass<<" cVol="<<mCurrentVolume,10);
}
@@ -1956,22 +2097,21 @@ LbmFsgrSolver<D>::adaptTimestep()
if(mTimestepReduceLock>0) mTimestepReduceLock--;
- /*
// forced back and forth switchting (for testing)
- const int tadtogInter = 300;
+ /*const int tadtogInter = 100;
const double tadtogSwitch = 0.66;
errMsg("TIMESWITCHTOGGLETEST","warning enabled "<< tadtogSwitch<<","<<tadtogSwitch<<" !!!!!!!!!!!!!!!!!!!");
- if( ((D::mStepCnt% tadtogInter)== (tadtogInter/4*1)-1) ||
- ((D::mStepCnt% tadtogInter)== (tadtogInter/4*2)-1) ){
+ if( ((this->mStepCnt% tadtogInter)== (tadtogInter/4*1)-1) ||
+ ((this->mStepCnt% tadtogInter)== (tadtogInter/4*2)-1) ){
rescale = true; minCutoff = false;
- newdt = tadtogSwitch * D::mpParam->getStepTime();
- D::mpParam->setDesiredStepTime( newdt );
+ newdt = tadtogSwitch * this->mpParam->getTimestep();
+ this->mpParam->setDesiredTimestep( newdt );
} else
- if( ((D::mStepCnt% tadtogInter)== (tadtogInter/4*3)-1) ||
- ((D::mStepCnt% tadtogInter)== (tadtogInter/4*4)-1) ){
+ if( ((this->mStepCnt% tadtogInter)== (tadtogInter/4*3)-1) ||
+ ((this->mStepCnt% tadtogInter)== (tadtogInter/4*4)-1) ){
rescale = true; minCutoff = false;
- newdt = D::mpParam->getStepTime()/tadtogSwitch ;
- D::mpParam->setDesiredStepTime( newdt );
+ newdt = this->mpParam->getTimestep()/tadtogSwitch ;
+ this->mpParam->setDesiredTimestep( newdt );
} else {
rescale = false; minCutoff = false;
}
@@ -1979,36 +2119,62 @@ LbmFsgrSolver<D>::adaptTimestep()
// test mass rescale
- scaleFac = newdt/D::mpParam->getStepTime();
+ scaleFac = newdt/this->mpParam->getTimestep();
if(rescale) {
- // fixme - warum y, wird jetzt gemittelt...
+ // perform acutal rescaling...
+ mTimeMaxvelStepCnt=0;
+
+ // FIXME - approximate by averaging, take gravity direction here?
mTimestepReduceLock = 4*(mLevel[mMaxRefine].lSizey+mLevel[mMaxRefine].lSizez+mLevel[mMaxRefine].lSizex)/3;
mTimeSwitchCounts++;
- D::mpParam->calculateAllMissingValues( D::mSilent );
+ this->mpParam->calculateAllMissingValues( mSimulationTime, this->mSilent );
recalculateObjectSpeeds();
// calc omega, force for all levels
mLastOmega=1e10; mLastGravity=1e10;
initLevelOmegas();
- if(D::mpParam->getStepTime()<mMinStepTime) mMinStepTime = D::mpParam->getStepTime();
- if(D::mpParam->getStepTime()>mMaxStepTime) mMaxStepTime = D::mpParam->getStepTime();
-
+ if(this->mpParam->getTimestep()<mMinTimestep) mMinTimestep = this->mpParam->getTimestep();
+ if(this->mpParam->getTimestep()>mMaxTimestep) mMaxTimestep = this->mpParam->getTimestep();
+
+ // this might be called during init, before we have any particles
+ if(mpParticles) { mpParticles->adaptPartTimestep(scaleFac); }
+#if LBM_INCLUDE_TESTSOLVERS==1
+ if((mUseTestdata)&&(mpTest)) {
+ mpTest->adaptTimestep(scaleFac, mLevel[mMaxRefine].omega, mLevel[mMaxRefine].timestep, vec2L( mpParam->calculateGravity(mSimulationTime)) );
+ }
+#endif // LBM_INCLUDE_TESTSOLVERS!=1
+
for(int lev=mMaxRefine; lev>=0 ; lev--) {
- LbmFloat newSteptime = mLevel[lev].stepsize;
+ LbmFloat newSteptime = mLevel[lev].timestep;
LbmFloat dfScaleFac = (newSteptime/1.0)/(levOldStepsize[lev]/levOldOmega[lev]);
- if(!D::mSilent) {
+ if(!this->mSilent) {
debMsgStd("LbmFsgrSolver::TAdp",DM_NOTIFY,"Level: "<<lev<<" Timestep change: "<<
" scaleFac="<<dfScaleFac<<" newDt="<<newSteptime<<" newOmega="<<mLevel[lev].omega,10);
}
if(lev!=mMaxRefine) coarseCalculateFluxareas(lev);
int wss = 0, wse = 1;
- // FIXME always currset!?
+ // only change currset (necessary for compressed grids, better for non-compr.gr.)
wss = wse = mLevel[lev].setCurr;
for(int workSet = wss; workSet<=wse; workSet++) { // COMPRT
// warning - check sets for higher levels...?
FSGR_FORIJK1(lev) {
+ if( (RFLAG(lev,i,j,k, workSet) & CFBndMoving) ) {
+ /*
+ // paranoid check - shouldnt be necessary!
+ if(QCELL(lev, i, j, k, workSet, dFlux)!=mSimulationTime) {
+ errMsg("TTTT","found invalid bnd cell.... removing at "<<PRINT_IJK);
+ RFLAG(lev,i,j,k, workSet) = CFInter;
+ // init empty zero vel interface cell...
+ initVelocityCell(lev, i,j,k, CFInter, 1.0, 0.01, LbmVec(0.) );
+ } else {// */
+ for(int l=0; l<this->cDfNum; l++) {
+ QCELL(lev, i, j, k, workSet, l) = QCELL(lev, i, j, k, workSet, l)* scaleFac;
+ }
+ //} // ok
+ continue;
+ }
if(
(RFLAG(lev,i,j,k, workSet) & CFFluid) ||
(RFLAG(lev,i,j,k, workSet) & CFInter) ||
@@ -2026,12 +2192,12 @@ LbmFsgrSolver<D>::adaptTimestep()
LbmVec velOld;
LbmFloat rho, ux,uy,uz;
rho=0.0; ux = uy = uz = 0.0;
- for(int l=0; l<D::cDfNum; l++) {
+ for(int l=0; l<this->cDfNum; l++) {
LbmFloat m = QCELL(lev, i, j, k, workSet, l);
rho += m;
- ux += (D::dfDvecX[l]*m);
- uy += (D::dfDvecY[l]*m);
- uz += (D::dfDvecZ[l]*m);
+ ux += (this->dfDvecX[l]*m);
+ uy += (this->dfDvecY[l]*m);
+ uz += (this->dfDvecZ[l]*m);
}
rhoOld = rho;
velOld = LbmVec(ux,uy,uz);
@@ -2042,21 +2208,21 @@ LbmFsgrSolver<D>::adaptTimestep()
LbmFloat df[LBM_DFNUM];
LbmFloat feqOld[LBM_DFNUM];
LbmFloat feqNew[LBM_DFNUM];
- for(int l=0; l<D::cDfNum; l++) {
- feqOld[l] = D::getCollideEq(l,rhoOld, velOld[0],velOld[1],velOld[2] );
- feqNew[l] = D::getCollideEq(l,rhoNew, velNew[0],velNew[1],velNew[2] );
+ for(int l=0; l<this->cDfNum; l++) {
+ feqOld[l] = this->getCollideEq(l,rhoOld, velOld[0],velOld[1],velOld[2] );
+ feqNew[l] = this->getCollideEq(l,rhoNew, velNew[0],velNew[1],velNew[2] );
df[l] = QCELL(lev, i,j,k,workSet, l);
}
- const LbmFloat Qo = D::getLesNoneqTensorCoeff(df,feqOld);
- const LbmFloat oldOmega = D::getLesOmega(levOldOmega[lev], mLevel[lev].lcsmago,Qo);
- const LbmFloat newOmega = D::getLesOmega(mLevel[lev].omega,mLevel[lev].lcsmago,Qo);
+ const LbmFloat Qo = this->getLesNoneqTensorCoeff(df,feqOld);
+ const LbmFloat oldOmega = this->getLesOmega(levOldOmega[lev], mLevel[lev].lcsmago,Qo);
+ const LbmFloat newOmega = this->getLesOmega(mLevel[lev].omega,mLevel[lev].lcsmago,Qo);
//newOmega = mLevel[lev].omega; // FIXME debug test
//LbmFloat dfScaleFac = (newSteptime/1.0)/(levOldStepsize[lev]/levOldOmega[lev]);
const LbmFloat dfScale = (newSteptime/newOmega)/(levOldStepsize[lev]/oldOmega);
//dfScale = dfScaleFac/newOmega;
- for(int l=0; l<D::cDfNum; l++) {
+ for(int l=0; l<this->cDfNum; l++) {
// org scaling
//df = eqOld + (df-eqOld)*dfScale; df *= (eqNew/eqOld); // non-eq. scaling, important
// new scaling
@@ -2100,21 +2266,22 @@ LbmFsgrSolver<D>::adaptTimestep()
} // lev
- if(!D::mSilent) {
- debMsgStd("LbmFsgrSolver::step",DM_MSG,"REINIT DONE "<<D::mStepCnt<<
- " no"<<mTimeSwitchCounts<<" maxdt"<<mMaxStepTime<<
- " mindt"<<mMinStepTime<<" currdt"<<mLevel[mMaxRefine].stepsize, 10);
+ if(!this->mSilent) {
+ debMsgStd("LbmFsgrSolver::step",DM_MSG,"REINIT DONE "<<this->mStepCnt<<
+ " no"<<mTimeSwitchCounts<<" maxdt"<<mMaxTimestep<<
+ " mindt"<<mMinTimestep<<" currdt"<<mLevel[mMaxRefine].timestep, 10);
debMsgStd("LbmFsgrSolver::step",DM_MSG,"REINIT DONE masst:"<<massTNew<<","<<massTOld<<" org:"<<mCurrentMass<<"; "<<
" volt:"<<volTNew<<","<<volTOld<<" org:"<<mCurrentVolume, 10);
} else {
debMsgStd("\nLbmOptSolver::step",DM_MSG,"Timestep change by "<< (newdt/levOldStepsize[mMaxRefine]) <<" newDt:"<<newdt
- <<", oldDt:"<<levOldStepsize[mMaxRefine]<<" newOmega:"<<D::mOmega<<" gStar:"<<D::mpParam->getCurrentGStar() , 10);
+ <<", oldDt:"<<levOldStepsize[mMaxRefine]<<" newOmega:"<<this->mOmega<<" gStar:"<<this->mpParam->getCurrentGStar() , 10);
}
} // rescale?
+ //NEWDEBCHECK("tt2");
//errMsg("adaptTimestep","Warning - brute force rescale off!"); minCutoff = false; // DEBUG
if(minCutoff) {
- errMsg("adaptTimestep","Warning - performing Brute-Force rescale... (sim:"<<D::mName<<" step:"<<D::mStepCnt<<" newdt="<<desireddt<<" mindt="<<D::mpParam->getMinStepTime()<<") " );
+ errMsg("adaptTimestep","Warning - performing Brute-Force rescale... (sim:"<<this->mName<<" step:"<<this->mStepCnt<<" newdt="<<desireddt<<" mindt="<<this->mpParam->getMinTimestep()<<") " );
//brute force resacle all the time?
for(int lev=mMaxRefine; lev>=0 ; lev--) {
@@ -2143,12 +2310,12 @@ LbmFsgrSolver<D>::adaptTimestep()
// collide on current set
LbmFloat rho, ux,uy,uz;
rho=0.0; ux = uy = uz = 0.0;
- for(int l=0; l<D::cDfNum; l++) {
+ for(int l=0; l<this->cDfNum; l++) {
LbmFloat m = QCELL(lev, i, j, k, workSet, l);
rho += m;
- ux += (D::dfDvecX[l]*m);
- uy += (D::dfDvecY[l]*m);
- uz += (D::dfDvecZ[l]*m);
+ ux += (this->dfDvecX[l]*m);
+ uy += (this->dfDvecY[l]*m);
+ uz += (this->dfDvecZ[l]*m);
}
#ifndef WIN32
if (!finite(rho)) {
@@ -2165,8 +2332,8 @@ LbmFsgrSolver<D>::adaptTimestep()
ux *= cfac;
uy *= cfac;
uz *= cfac;
- for(int l=0; l<D::cDfNum; l++) {
- QCELL(lev, i, j, k, workSet, l) = D::getCollideEq(l, rho, ux,uy,uz); }
+ for(int l=0; l<this->cDfNum; l++) {
+ QCELL(lev, i, j, k, workSet, l) = this->getCollideEq(l, rho, ux,uy,uz); }
rescs++;
debMsgDirect("B");
}
@@ -2189,9 +2356,7 @@ LbmFsgrSolver<D>::adaptTimestep()
* work on lists from updateCellMass to reinit cell flags
*****************************************************************************/
-template<class D>
-LbmFloat
-LbmFsgrSolver<D>::getMassdWeight(bool dirForw, int i,int j,int k,int workSet, int l) {
+LbmFloat LbmFsgrSolver::getMassdWeight(bool dirForw, int i,int j,int k,int workSet, int l) {
//return 0.0; // test
int level = mMaxRefine;
LbmFloat *ccel = RACPNT(level, i,j,k, workSet);
@@ -2226,8 +2391,7 @@ LbmFsgrSolver<D>::getMassdWeight(bool dirForw, int i,int j,int k,int workSet, in
return ret;
}
-template<class D>
-void LbmFsgrSolver<D>::addToNewInterList( int ni, int nj, int nk ) {
+void LbmFsgrSolver::addToNewInterList( int ni, int nj, int nk ) {
#if FSGR_STRICT_DEBUG==10
// dangerous, this can change the simulation...
/*for( vector<LbmPoint>::iterator iter=mListNewInter.begin();
@@ -2245,20 +2409,14 @@ void LbmFsgrSolver<D>::addToNewInterList( int ni, int nj, int nk ) {
mListNewInter.push_back(newinter);
}
-template<class D>
-void LbmFsgrSolver<D>::reinitFlags( int workSet )
-{
+void LbmFsgrSolver::reinitFlags( int workSet ) {
// OLD mods:
// add all to intel list?
// check ffrac for new cells
// new if cell inits (last loop)
// vweights handling
-#if ELBEEM_PLUGIN==1
- const int debugFlagreinit = 0;
-#else // ELBEEM_PLUGIN==1
const int debugFlagreinit = 0;
-#endif // ELBEEM_PLUGIN==1
// some things need to be read/modified on the other set
int otherSet = (workSet^1);
@@ -2278,66 +2436,39 @@ void LbmFsgrSolver<D>::reinitFlags( int workSet )
int i=iter->x, j=iter->y, k=iter->z;
if(debugFlagreinit) errMsg("FULL", PRINT_IJK<<" mss"<<QCELL(workLev, i,j,k, workSet, dMass) <<" rho"<< QCELL(workLev, i,j,k, workSet, 0) ); // DEBUG SYMM
FORDF1 {
- int ni=i+D::dfVecX[l], nj=j+D::dfVecY[l], nk=k+D::dfVecZ[l];
+ int ni=i+this->dfVecX[l], nj=j+this->dfVecY[l], nk=k+this->dfVecZ[l];
+ //if((LBMDIM>2)&&( (ni<=0) || (nj<=0) || (nk<=0) || (ni>=mLevel[workLev].lSizex-1) || (nj>=mLevel[workLev].lSizey-1) || (nk>=mLevel[workLev].lSizez-1) )) {
+ if( (ni<=0) || (nj<=0) ||
+ (ni>=mLevel[workLev].lSizex-1) ||
+ (nj>=mLevel[workLev].lSizey-1)
+# if LBMDIM==3
+ || (nk<=0) || (nk>=mLevel[workLev].lSizez-1)
+# endif // LBMDIM==1
+ ) {
+ continue; } // new bc, dont treat cells on boundary NEWBC
if( RFLAG(workLev, ni,nj,nk, workSet) & CFEmpty ){
- // new and empty interface cell, dont change old flag here!
- addToNewInterList(ni,nj,nk);
// preinit speed, get from average surrounding cells
// interpolate from non-workset to workset, sets are handled in function
- {
- // WARNING - other i,j,k than filling cell!
- int ei=ni; int ej=nj; int ek=nk;
- LbmFloat avgrho = 0.0;
- LbmFloat avgux = 0.0, avguy = 0.0, avguz = 0.0;
- LbmFloat cellcnt = 0.0;
- LbmFloat avgnbdf[LBM_DFNUM];
- FORDF0M { avgnbdf[m]= 0.0; }
-
- for(int nbl=1; nbl< D::cDfNum ; ++nbl) {
- if( (RFLAG_NB(workLev,ei,ej,ek,workSet,nbl) & CFFluid) ||
- ((!(RFLAG_NB(workLev,ei,ej,ek,workSet,nbl) & CFNoInterpolSrc) ) &&
- (RFLAG_NB(workLev,ei,ej,ek,workSet,nbl) & CFInter) )) {
- cellcnt += 1.0;
- for(int rl=0; rl< D::cDfNum ; ++rl) {
- LbmFloat nbdf = QCELL_NB(workLev,ei,ej,ek, workSet,nbl, rl);
- avgnbdf[rl] += nbdf;
- avgux += (D::dfDvecX[rl]*nbdf);
- avguy += (D::dfDvecY[rl]*nbdf);
- avguz += (D::dfDvecZ[rl]*nbdf);
- avgrho += nbdf;
- }
- }
- }
- if(cellcnt<=0.0) {
- // no nbs? just use eq.
- //FORDF0 { QCELL(workLev,ei,ej,ek, workSet, l) = D::dfEquil[l]; }
- avgrho = 1.0;
- avgux = avguy = avguz = 0.0;
- //TTT mNumProblems++;
-#if ELBEEM_PLUGIN!=1
- D::mPanic=1; errFatal("NYI2","cellcnt<=0.0",SIMWORLD_GENERICERROR);
-#endif // ELBEEM_PLUGIN
- } else {
- // init speed
- avgux /= cellcnt; avguy /= cellcnt; avguz /= cellcnt;
- avgrho /= cellcnt;
- FORDF0M { avgnbdf[m] /= cellcnt; } // CHECK FIXME test?
- }
+ // new and empty interface cell, dont change old flag here!
+ addToNewInterList(ni,nj,nk);
- // careful with l's...
- FORDF0M {
- QCELL(workLev,ei,ej,ek, workSet, m) = D::getCollideEq( m,avgrho, avgux, avguy, avguz );
- //QCELL(workLev,ei,ej,ek, workSet, l) = avgnbdf[l]; // CHECK FIXME test?
- }
- //errMsg("FNEW", PRINT_VEC(ei,ej,ek)<<" mss"<<QCELL(workLev, i,j,k, workSet, dMass) <<" rho"<<avgrho<<" vel"<<PRINT_VEC(avgux,avguy,avguz) ); // DEBUG SYMM
- QCELL(workLev,ei,ej,ek, workSet, dMass) = 0.0; //?? new
- QCELL(workLev,ei,ej,ek, workSet, dFfrac) = 0.0; //?? new
- //RFLAG(workLev,ei,ej,ek,workSet) = (CellFlagType)(CFInter|CFNoInterpolSrc);
- changeFlag(workLev,ei,ej,ek,workSet, (CFInter|CFNoInterpolSrc));
- if(debugFlagreinit) errMsg("NEWE", PRINT_IJK<<" newif "<<PRINT_VEC(ei,ej,ek)<<" rho"<<avgrho<<" vel("<<avgux<<","<<avguy<<","<<avguz<<") " );
- }
+ LbmFloat avgrho = 0.0;
+ LbmFloat avgux = 0.0, avguy = 0.0, avguz = 0.0;
+ interpolateCellValues(workLev,ni,nj,nk,workSet, avgrho,avgux,avguy,avguz);
+
+ // careful with l's...
+ FORDF0M {
+ QCELL(workLev,ni,nj,nk, workSet, m) = this->getCollideEq( m,avgrho, avgux, avguy, avguz );
+ //QCELL(workLev,ni,nj,nk, workSet, l) = avgnbdf[l]; // CHECK FIXME test?
+ }
+ //errMsg("FNEW", PRINT_VEC(ni,nj,nk)<<" mss"<<QCELL(workLev, i,j,k, workSet, dMass) <<" rho"<<avgrho<<" vel"<<PRINT_VEC(avgux,avguy,avguz) ); // DEBUG SYMM
+ QCELL(workLev,ni,nj,nk, workSet, dMass) = 0.0; //?? new
+ QCELL(workLev,ni,nj,nk, workSet, dFfrac) = 0.0; //?? new
+ //RFLAG(workLev,ni,nj,nk,workSet) = (CellFlagType)(CFInter|CFNoInterpolSrc);
+ changeFlag(workLev,ni,nj,nk,workSet, (CFInter|CFNoInterpolSrc));
+ if(debugFlagreinit) errMsg("NEWE", PRINT_IJK<<" newif "<<PRINT_VEC(ni,nj,nk)<<" rho"<<avgrho<<" vel("<<avgux<<","<<avguy<<","<<avguz<<") " );
}
/* prevent surrounding interface cells from getting removed as empty cells
* (also cells that are not newly inited) */
@@ -2381,14 +2512,14 @@ void LbmFsgrSolver<D>::reinitFlags( int workSet )
/* set surrounding fluid cells to interface cells */
FORDF1 {
- int ni=i+D::dfVecX[l], nj=j+D::dfVecY[l], nk=k+D::dfVecZ[l];
+ int ni=i+this->dfVecX[l], nj=j+this->dfVecY[l], nk=k+this->dfVecZ[l];
if( RFLAG(workLev,ni,nj,nk, workSet) & CFFluid){
// init fluid->interface
//RFLAG(workLev,ni,nj,nk, workSet) = (CellFlagType)(CFInter);
changeFlag(workLev,ni,nj,nk, workSet, CFInter);
/* new mass = current density */
LbmFloat nbrho = QCELL(workLev,ni,nj,nk, workSet, dC);
- for(int rl=1; rl< D::cDfNum ; ++rl) { nbrho += QCELL(workLev,ni,nj,nk, workSet, rl); }
+ for(int rl=1; rl< this->cDfNum ; ++rl) { nbrho += QCELL(workLev,ni,nj,nk, workSet, rl); }
QCELL(workLev,ni,nj,nk, workSet, dMass) = nbrho;
QCELL(workLev,ni,nj,nk, workSet, dFfrac) = 1.0;
@@ -2421,7 +2552,7 @@ void LbmFsgrSolver<D>::reinitFlags( int workSet )
int i=iter->x, j=iter->y, k=iter->z;
nbCount = 0; nbTotWeights = 0.0;
FORDF1 {
- int ni=i+D::dfVecX[l], nj=j+D::dfVecY[l], nk=k+D::dfVecZ[l];
+ int ni=i+this->dfVecX[l], nj=j+this->dfVecY[l], nk=k+this->dfVecZ[l];
if( RFLAG(workLev,ni,nj,nk, workSet) & CFInter) {
nbCount++;
nbWeights[l] = getMassdWeight(1,i,j,k,workSet,l);
@@ -2445,7 +2576,7 @@ void LbmFsgrSolver<D>::reinitFlags( int workSet )
int i=iter->x, j=iter->y, k=iter->z;
nbCount = 0; nbTotWeights = 0.0;
FORDF1 {
- int ni=i+D::dfVecX[l], nj=j+D::dfVecY[l], nk=k+D::dfVecZ[l];
+ int ni=i+this->dfVecX[l], nj=j+this->dfVecY[l], nk=k+this->dfVecZ[l];
if( RFLAG(workLev,ni,nj,nk, workSet) & CFInter) {
nbCount++;
nbWeights[l] = getMassdWeight(0,i,j,k,workSet,l);
@@ -2479,12 +2610,11 @@ void LbmFsgrSolver<D>::reinitFlags( int workSet )
/*int nbCount = 0;
LbmFloat nbWeights[LBM_DFNUM];
FORDF1 {
- int ni=i+D::dfVecX[l], nj=j+D::dfVecY[l], nk=k+D::dfVecZ[l];
+ int ni=i+this->dfVecX[l], nj=j+this->dfVecY[l], nk=k+this->dfVecZ[l];
if( RFLAG(workLev,ni,nj,nk, workSet) & CFInter) {
nbCount++;
nbWeights[l] = vWeights[weightIndex].val[l];
- } else {
- }
+ } else { }
}*/
//errMsg("FDIST", PRINT_IJK<<" mss"<<massChange <<" nb"<< nbCount ); // DEBUG SYMM
@@ -2492,7 +2622,7 @@ void LbmFsgrSolver<D>::reinitFlags( int workSet )
const LbmFloat nbTotWeightsp = vWeights[weightIndex].val[0];
//errMsg("FF I", PRINT_IJK<<" "<<weightIndex<<" "<<nbTotWeightsp);
FORDF1 {
- int ni=i+D::dfVecX[l], nj=j+D::dfVecY[l], nk=k+D::dfVecZ[l];
+ int ni=i+this->dfVecX[l], nj=j+this->dfVecY[l], nk=k+this->dfVecZ[l];
if( RFLAG(workLev,ni,nj,nk, workSet) & CFInter) {
LbmFloat change = -1.0;
if(nbTotWeightsp>0.0) {
@@ -2507,9 +2637,9 @@ void LbmFsgrSolver<D>::reinitFlags( int workSet )
massChange = 0.0;
} else {
// Problem! no interface neighbors
- D::mFixMass += massChange;
+ this->mFixMass += massChange;
//TTT mNumProblems++;
- //errMsg(" FULL PROBLEM ", PRINT_IJK<<" "<<D::mFixMass);
+ //errMsg(" FULL PROBLEM ", PRINT_IJK<<" "<<this->mFixMass);
}
weightIndex++;
@@ -2531,7 +2661,7 @@ void LbmFsgrSolver<D>::reinitFlags( int workSet )
/*int nbCount = 0;
LbmFloat nbWeights[LBM_DFNUM];
FORDF1 {
- int ni=i+D::dfVecX[l], nj=j+D::dfVecY[l], nk=k+D::dfVecZ[l];
+ int ni=i+this->dfVecX[l], nj=j+this->dfVecY[l], nk=k+this->dfVecZ[l];
if( RFLAG(workLev,ni,nj,nk, workSet) & CFInter) {
nbCount++;
nbWeights[l] = vWeights[weightIndex].val[l];
@@ -2546,7 +2676,7 @@ void LbmFsgrSolver<D>::reinitFlags( int workSet )
const LbmFloat nbTotWeightsp = vWeights[weightIndex].val[0];
//errMsg("EE I", PRINT_IJK<<" "<<weightIndex<<" "<<nbTotWeightsp);
FORDF1 {
- int ni=i+D::dfVecX[l], nj=j+D::dfVecY[l], nk=k+D::dfVecZ[l];
+ int ni=i+this->dfVecX[l], nj=j+this->dfVecY[l], nk=k+this->dfVecZ[l];
if( RFLAG(workLev,ni,nj,nk, workSet) & CFInter) {
LbmFloat change = -1.0;
if(nbTotWeightsp>0.0) {
@@ -2560,9 +2690,9 @@ void LbmFsgrSolver<D>::reinitFlags( int workSet )
massChange = 0.0;
} else {
// Problem! no interface neighbors
- D::mFixMass += massChange;
+ this->mFixMass += massChange;
//TTT mNumProblems++;
- //errMsg(" EMPT PROBLEM ", PRINT_IJK<<" "<<D::mFixMass);
+ //errMsg(" EMPT PROBLEM ", PRINT_IJK<<" "<<this->mFixMass);
}
weightIndex++;
@@ -2602,12 +2732,18 @@ void LbmFsgrSolver<D>::reinitFlags( int workSet )
for( vector<LbmPoint>::iterator iter=mListNewInter.begin();
iter != mListNewInter.end(); iter++ ) {
int i=iter->x, j=iter->y, k=iter->z;
+ if((i<=0) || (j<=0) ||
+ (i>=mLevel[workLev].lSizex-1) ||
+ (j>=mLevel[workLev].lSizey-1) ||
+ ((LBMDIM==3) && ((k<=0) || (k>=mLevel[workLev].lSizez-1) ) )
+ ) {
+ continue; } // new bc, dont treat cells on boundary NEWBC
if(!(RFLAG(workLev,i,j,k, workSet)&CFInter)) {
//errMsg("???"," "<<PRINT_IJK);
continue;
- }
+ } // */
- QCELL(workLev,i,j,k, workSet, dMass) += (D::mFixMass * newIfFac);
+ QCELL(workLev,i,j,k, workSet, dMass) += (this->mFixMass * newIfFac);
int nbored = 0;
FORDF1 { nbored |= RFLAG_NB(workLev, i,j,k, workSet,l); }
@@ -2634,8 +2770,8 @@ void LbmFsgrSolver<D>::reinitFlags( int workSet )
}
if(mListNewInter.size()>0){
- //errMsg("FixMassDisted"," fm:"<<D::mFixMass<<" nif:"<<mListNewInter.size() );
- D::mFixMass = 0.0;
+ //errMsg("FixMassDisted"," fm:"<<this->mFixMass<<" nif:"<<mListNewInter.size() );
+ this->mFixMass = 0.0;
}
// empty lists for next step
@@ -2649,42 +2785,6 @@ void LbmFsgrSolver<D>::reinitFlags( int workSet )
* instantiation
*****************************************************************************/
-// ugly workaround for multiple definitions
-// of template instatiations for macs... compile
-// everything in one file again
-#if defined(__APPLE_CC__) || (defined __INTEL_COMPILER)
-#define LBM_FORCEINCLUDE
-#include "solver_init.cpp"
-#include "solver_util.cpp"
-#undef LBM_FORCEINCLUDE
-#endif // defined(__APPLE_CC__)
-
//! lbm factory functions
-LbmSolverInterface* createSolver() {
-#if LBMDIM==2
- return new LbmFsgrSolver< LbmBGK2D >();
-#endif // LBMDIM==2
-#if LBMDIM==3
- return new LbmFsgrSolver< LbmBGK3D >();
-#endif // LBMDIM==3
- return NULL;
-}
-
-
-#ifndef LBM_INSTANTIATE
-#if LBMDIM==2
-#define LBM_INSTANTIATE LbmBGK2D
-#endif // LBMDIM==2
-#if LBMDIM==3
-#define LBM_INSTANTIATE LbmBGK3D
-#endif // LBMDIM==3
-#endif // LBM_INSTANTIATE
-
-template class LbmFsgrSolver< LBM_INSTANTIATE >;
-// the intel compiler is too smart - so the virtual functions called from other cpp
-// files have to be instantiated explcitly (otherwise this will cause undefined
-// references to "non virtual thunks") ... still not working, though
-//template<class LBM_INSTANTIATE> string LbmFsgrSolver<LBM_INSTANTIATE>::getIdString();
-//template<class LBM_INSTANTIATE> void LbmFsgrSolver<LBM_INSTANTIATE>::step();
-
+LbmSolverInterface* createSolver() { return new LbmFsgrSolver(); }
diff --git a/intern/elbeem/intern/solver_relax.h b/intern/elbeem/intern/solver_relax.h
index b2c2fcbe7cc..bc027655be0 100644
--- a/intern/elbeem/intern/solver_relax.h
+++ b/intern/elbeem/intern/solver_relax.h
@@ -9,7 +9,111 @@
*
*****************************************************************************/
+#if FSGR_STRICT_DEBUG==1
+#define CAUSE_PANIC { this->mPanic=1; /* *((int*)(0x0)) = 1; crash*/ }
+#else // FSGR_STRICT_DEBUG==1
+#define CAUSE_PANIC { this->mPanic=1; } /*set flag*/
+#endif // FSGR_STRICT_DEBUG==1
+
+
+
+#if LBM_INCLUDE_TESTSOLVERS!=1
+
+// off for non testing
+#define PRECOLLIDE_MODS(rho,ux,uy,uz)
+
+#else // LBM_INCLUDE_TESTSOLVERS!=1
+#define PRECOLLIDE_GETPOS \
+ LbmVec( \
+ ((this->mvGeoEnd[0]-this->mvGeoStart[0])/(LbmFloat)this->mSizex) * (LbmFloat)i + this->mvGeoStart[0], \
+ ((this->mvGeoEnd[1]-this->mvGeoStart[1])/(LbmFloat)this->mSizey) * (LbmFloat)j + this->mvGeoStart[1], \
+ ((this->mvGeoEnd[2]-this->mvGeoStart[2])/(LbmFloat)this->mSizez) * (LbmFloat)k + this->mvGeoStart[2] \
+ )
+
+// debug modifications of collide vars (testing)
+#define PRECOLLIDE_MODS(rho,ux,uy,uz) \
+ if( (this->mTForceStrength>0.) && (RFLAG(0,i,j,k, mLevel[0].setCurr)&CFNoBndFluid) ) { \
+ LbmVec pos = PRECOLLIDE_GETPOS; \
+ LbmVec vel(ux,uy,uz); \
+ mpTest->mControlParts.modifyVelocity(pos,vel); /* */\
+ if((i==16)&&(j==10)){ /*debugMarkCell(0,16,10,0);*/ errMsg("FTDEB"," at "<<PRINT_IJK<<" targ:"<<vel<<",len:"<<norm(vel)<<", org:"<<ntlVec3Gfx(ux,uy,uz) ); }\
+ ux = vel[0]; uy=vel[1]; uz=vel[2]; \
+ /* test acutal values...? */ \
+ }
+ /* end PRECOLLIDE_MODS */
+
+// debug modifications of collide vars (testing)
+#define _PRECOLLIDE_MODS(rho,ux,uy,uz) \
+ if(this->mTForceStrength>0.) { \
+ LbmVec u(ux,uy,uz); \
+ LbmVec pos = PRECOLLIDE_GETPOS; \
+ LbmVec targv = u; const int lev=0; \
+ mpTest->mControlParts.modifyVelocity(pos,targv); /* */\
+ LbmVec devia = (targv-u); \
+ LbmVec set; \
+ set = u + (devia/this->mOmega) * this->mTForceStrength; /* */\
+ set = u + targv*this->mTForceStrength; /* */\
+ ux = set[0]; uy=set[1]; uz=set[2]; \
+ if(j==10){ errMsg("FTDEB"," at "<<PRINT_IJK<<" targ"<<targv<<","<<norm(targv)<<" set:"<<set<<","<<norm(set) ); }\
+ }
+ /* end PRECOLLIDE_MODS */
+
+#endif // LBM_INCLUDE_TESTSOLVERS!=1
+
+/*
+
+ \
+ if((0) && (j>=0.01*this->mSizey) && (j<0.9*this->mSizey)) { \
+ if((1) && (i>=0.5*this->mSizex) && (i<0.6*this->mSizex)) { \
+ LbmFloat len = sqrtf(ux*ux + uy*uy + uz*uz); \
+ LbmVec u(ux,uy,uz); LbmVec t(1., 0., 0.); \
+ ux = len*t[0]; uy=len*t[1]; uz=len*t[2]; \
+ } \
+ if((1) && (i>=0.65*this->mSizex) && (i<0.75*this->mSizex)) { \
+ LbmFloat len = sqrtf(ux*ux + uy*uy + uz*uz); \
+ LbmVec u(ux,uy,uz); LbmVec t(0., 1., 0.); \
+ ux = len*t[0]; uy=len*t[1]; uz=len*t[2]; \
+ } \
+ } \
+ \
+ if((0) && (j>=0.0*this->mSizey) && (j<1.0 *this->mSizey)) { \
+ if((1) && (i>=0.6 *this->mSizex) && (i<0.7 *this->mSizex)) { \
+ LbmFloat len = sqrtf(ux*ux + uy*uy + uz*uz); \
+ LbmVec u(ux,uy,uz); \
+ LbmVec t(0., 1., 0.); \
+ LbmFloat devia = norm(u-t); \
+ // 0.0001-strong, 0.000001-small,
+ t = u - (devia/this->mOmega) * this->mTForceStrength; \
+ // ux = len*t[0]; uy=len*t[1]; uz=len*t[2];
+ ux = t[0]; uy=t[1]; uz=t[2]; \
+ //ux= uy= uz= 0.0;
+ //errMsg("DDDD"," at "<<PRINT_IJK);
+ } \
+ } \
+ if(0) { \
+ LbmFloat len = sqrtf(ux*ux + uy*uy + uz*uz); \
+ LbmVec u(ux,uy,uz); \
+ LbmVec p(i/(LbmFloat)this->mSizex, j/(LbmFloat)this->mSizey, k/(LbmFloat)this->mSizez); \
+ LbmVec cp(0.5, 0.5, 0.5); \
+ LbmVec delt = cp - p; \
+ LbmFloat dist = norm(delt); \
+ normalize(delt); \
+ LbmVec tang = cross(delt, LbmVec(0.,0.,1.)); \
+ normalize(tang); \
+ const LbmFloat falloff = 5.0; \
+ LbmVec targv = tang*1.0 * 1.0/(1.0+falloff*dist); \
+ LbmVec devia = (targv-u); \
+ LbmFloat devial = norm(devia); \
+ LbmVec set; \
+ set = u +targv * this->mTForceStrength; \
+ set = u + (devia/this->mOmega) * this->mTForceStrength; \
+ ux = set[0]; uy=set[1]; uz=set[2]; \
+ if(j==10){ errMsg("FTDEB"," at "<<PRINT_IJK<<" dist:"<<delt<<","<<dist<<" targ"<<targv<<","<<norm(targv)<<" set:"<<set<<","<<norm(set) ); }\
+ } \
+
+*/
+
/******************************************************************************
* normal relaxation
*****************************************************************************/
@@ -165,20 +269,20 @@
// treatment of freeslip reflection
// used both for OPT and nonOPT
#define DEFAULT_STREAM_FREESLIP(l,invl,mnbf) \
- /*const int inv_l = D::dfInv[l];*/ \
+ /*const int inv_l = this->dfInv[l];*/ \
int nb1 = 0, nb2 = 0; /* is neighbor in this direction an obstacle? */\
LbmFloat newval = 0.0; /* new value for m[l], differs for free/part slip */\
- const int dx = D::dfVecX[invl], dy = D::dfVecY[invl], dz = D::dfVecZ[invl]; \
+ const int dx = this->dfVecX[invl], dy = this->dfVecY[invl], dz = this->dfVecZ[invl]; \
if(dz==0) { \
nb1 = !(RFLAG(lev, i, j+dy,k, SRCS(lev))&(CFFluid|CFInter)); \
nb2 = !(RFLAG(lev, i+dx,j, k, SRCS(lev))&(CFFluid|CFInter)); \
if((nb1)&&(!nb2)) { \
/* x reflection */\
- newval = QCELL(lev, i+dx,j,k,SRCS(lev), D::dfRefX[l]); \
+ newval = QCELL(lev, i+dx,j,k,SRCS(lev), this->dfRefX[l]); \
} else \
if((!nb1)&&(nb2)) { \
/* y reflection */\
- newval = QCELL(lev, i,j+dy,k,SRCS(lev), D::dfRefY[l]); \
+ newval = QCELL(lev, i,j+dy,k,SRCS(lev), this->dfRefY[l]); \
} else { \
/* normal no slip in all other cases */\
newval = QCELL(lev, i,j,k,SRCS(lev), invl); \
@@ -189,11 +293,11 @@
nb2 = !(RFLAG(lev, i+dx,j,k, SRCS(lev))&(CFFluid|CFInter)); \
if((nb1)&&(!nb2)) { \
/* x reflection */\
- newval = QCELL(lev, i+dx,j,k,SRCS(lev), D::dfRefX[l]); \
+ newval = QCELL(lev, i+dx,j,k,SRCS(lev), this->dfRefX[l]); \
} else \
if((!nb1)&&(nb2)) { \
/* z reflection */\
- newval = QCELL(lev, i,j,k+dz,SRCS(lev), D::dfRefZ[l]); \
+ newval = QCELL(lev, i,j,k+dz,SRCS(lev), this->dfRefZ[l]); \
} else { \
/* normal no slip in all other cases */\
newval = ( QCELL(lev, i,j,k,SRCS(lev), invl) ); \
@@ -205,11 +309,11 @@
nb2 = !(RFLAG(lev, i,j+dy,k, SRCS(lev))&(CFFluid|CFInter)); \
if((nb1)&&(!nb2)) { \
/* y reflection */\
- newval = QCELL(lev, i,j+dy,k,SRCS(lev), D::dfRefY[l]); \
+ newval = QCELL(lev, i,j+dy,k,SRCS(lev), this->dfRefY[l]); \
} else \
if((!nb1)&&(nb2)) { \
/* z reflection */\
- newval = QCELL(lev, i,j,k+dz,SRCS(lev), D::dfRefZ[l]); \
+ newval = QCELL(lev, i,j,k+dz,SRCS(lev), this->dfRefZ[l]); \
} else { \
/* normal no slip in all other cases */\
newval = ( QCELL(lev, i,j,k,SRCS(lev), invl) ); \
@@ -217,7 +321,7 @@
} \
if(mnbf & CFBndPartslip) { /* part slip interpolation */ \
const LbmFloat partv = mObjectPartslips[(int)(mnbf>>24)]; \
- m[l] = RAC(ccel, D::dfInv[l] ) * partv + newval * (1.0-partv); /* part slip */ \
+ m[l] = RAC(ccel, this->dfInv[l] ) * partv + newval * (1.0-partv); /* part slip */ \
} else {\
m[l] = newval; /* normal free slip*/\
}\
@@ -228,20 +332,22 @@
#if FSGR_STRICT_DEBUG==1
#define MARKCELLCHECK \
- debugMarkCell(lev,i,j,k); D::mPanic=1;
-#define STREAMCHECK(ni,nj,nk,nl) \
- if((m[l] < -1.0) || (m[l]>1.0)) {\
- errMsg("STREAMCHECK","Invalid streamed DF l"<<l<<" value:"<<m[l]<<" at "<<PRINT_IJK<<" from "<<PRINT_VEC(ni,nj,nk)<<" nl"<<(nl)<<\
+ debugMarkCell(lev,i,j,k); CAUSE_PANIC;
+#define STREAMCHECK(id,ni,nj,nk,nl) \
+ if((m[nl] < -1.0) || (m[nl]>1.0)) {\
+ errMsg("STREAMCHECK","ID"<<id<<" Invalid streamed DF nl"<<nl<<" value:"<<m[nl]<<" at "<<PRINT_IJK<<" from "<<PRINT_VEC(ni,nj,nk)<<" nl"<<(nl)<<\
" nfc"<< RFLAG(lev, ni,nj,nk, mLevel[lev].setCurr)<<" nfo"<< RFLAG(lev, ni,nj,nk, mLevel[lev].setOther) ); \
+ /*FORDF0{ errMsg("STREAMCHECK"," at "<<PRINT_IJK<<" df "<<l<<"="<<m[l] ); } */ \
MARKCELLCHECK; \
}
#define COLLCHECK \
if( (rho>2.0) || (rho<-1.0) || (ABS(ux)>1.0) || (ABS(uy)>1.0) |(ABS(uz)>1.0) ) {\
errMsg("COLLCHECK","Invalid collision values r:"<<rho<<" u:"PRINT_VEC(ux,uy,uz)<<" at? "<<PRINT_IJK ); \
+ /*FORDF0{ errMsg("COLLCHECK"," at? "<<PRINT_IJK<<" df "<<l<<"="<<m[l] ); }*/ \
MARKCELLCHECK; \
}
#else
-#define STREAMCHECK(ni,nj,nk,nl)
+#define STREAMCHECK(id, ni,nj,nk,nl)
#define COLLCHECK
#endif
@@ -249,121 +355,38 @@
#define DEFAULT_STREAM \
m[dC] = RAC(ccel,dC); \
+ STREAMCHECK(1, i,j,k, dC); \
FORDF1 { \
- CellFlagType nbf = nbflag[ D::dfInv[l] ];\
+ CellFlagType nbf = nbflag[ this->dfInv[l] ];\
if(nbf & CFBnd) { \
if(nbf & CFBndNoslip) { \
/* no slip, default */ \
- m[l] = RAC(ccel, D::dfInv[l] ); STREAMCHECK(i,j,k, D::dfInv[l]); /* noslip */ \
+ m[l] = RAC(ccel, this->dfInv[l] ); /* noslip */ \
+ if(nbf&CFBndMoving) m[l]+=QCELL_NBINV(lev, i, j, k, SRCS(lev), l,l); /* obs. speed*/ \
+ STREAMCHECK(2, i,j,k, l); \
} else if(nbf & (CFBndFreeslip|CFBndPartslip)) { \
/* free slip */ \
if(l<=LBMDIM*2) { \
- m[l] = RAC(ccel, D::dfInv[l] ); STREAMCHECK(i,j,k, D::dfInv[l]); /* noslip for <dim*2 */ \
+ m[l] = RAC(ccel, this->dfInv[l] ); STREAMCHECK(3, i,j,k, l); /* noslip for <dim*2 */ \
} else { \
- const int inv_l = D::dfInv[l]; \
- DEFAULT_STREAM_FREESLIP(l,inv_l,nbf); \
- } /* l>2*dim free slip */ \
- \
- } /* type reflect */\
- else {\
- errMsg("LbmFsgrSolver","Invalid Bnd type at "<<PRINT_IJK<<" f"<<convertCellFlagType2String(nbf)<<",nbdir"<<D::dfInv[l] ); \
- } \
- } else { \
- m[l] = QCELL_NBINV(lev, i, j, k, SRCS(lev), l,l); \
- STREAMCHECK(i+D::dfVecX[D::dfInv[l]], j+D::dfVecY[D::dfInv[l]],k+D::dfVecZ[D::dfInv[l]], l); \
- } \
- }
-
-#define _________________DEFAULT_STREAM \
- m[dC] = RAC(ccel,dC); \
- FORDF1 { \
- CellFlagType nbf = nbflag[ D::dfInv[l] ];\
- if(nbf & CFBnd) { \
- if(nbf & CFBndNoslip) { \
- /* no slip, default */ \
- m[l] = RAC(ccel, D::dfInv[l] ); STREAMCHECK(i,j,k, D::dfInv[l]); /* noslip */ \
- } else if(nbf & (CFBndFreeslip|CFBndPartslip)) { \
- /* free slip */ \
- if(l<=LBMDIM*2) { \
- m[l] = RAC(ccel, D::dfInv[l] ); STREAMCHECK(i,j,k, D::dfInv[l]); /* noslip for <dim*2 */ \
- } else { \
- const int inv_l = D::dfInv[l]; \
- int debug_srcl = -1; \
- int nb1 = 0, nb2 = 0; /* is neighbor in this direction an obstacle? */\
- LbmFloat newval = 0.0; /* new value for m[l], differs for free/part slip */\
- const int dx = D::dfVecX[inv_l], dy = D::dfVecY[inv_l], dz = D::dfVecZ[inv_l]; \
+ const int inv_l = this->dfInv[l]; \
+ DEFAULT_STREAM_FREESLIP(l,inv_l,nbf); \
+ } /* l>2*dim free slip */ \
\
- if(dz==0) { \
- nb1 = !(RFLAG(lev, i, j+dy,k, SRCS(lev))&(CFFluid|CFInter)); /* FIXME add noslip|free|part here */ \
- nb2 = !(RFLAG(lev, i+dx,j, k, SRCS(lev))&(CFFluid|CFInter)); \
- if((nb1)&&(!nb2)) { \
- /* x reflection */\
- newval = QCELL(lev, i+dx,j,k,SRCS(lev), D::dfRefX[l]); \
- debug_srcl = D::dfRefX[l]; \
- } else \
- if((!nb1)&&(nb2)) { \
- /* y reflection */\
- newval = QCELL(lev, i,j+dy,k,SRCS(lev), D::dfRefY[l]); \
- debug_srcl = D::dfRefY[l]; \
- } else { \
- /* normal no slip in all other cases */\
- newval = QCELL(lev, i,j,k,SRCS(lev), inv_l); \
- debug_srcl = inv_l; \
- } \
- } else /* z=0 */\
- if(dy==0) { \
- nb1 = !(RFLAG(lev, i,j,k+dz, SRCS(lev))&(CFFluid|CFInter)); \
- nb2 = !(RFLAG(lev, i+dx,j,k, SRCS(lev))&(CFFluid|CFInter)); \
- if((nb1)&&(!nb2)) { \
- /* x reflection */\
- newval = QCELL(lev, i+dx,j,k,SRCS(lev), D::dfRefX[l]); \
- } else \
- if((!nb1)&&(nb2)) { \
- /* z reflection */\
- newval = QCELL(lev, i,j,k+dz,SRCS(lev), D::dfRefZ[l]); \
- } else { \
- /* normal no slip in all other cases */\
- newval = ( QCELL(lev, i,j,k,SRCS(lev), inv_l) ); \
- } \
- /* end y=0 */ \
- } else { \
- /* x=0 */\
- nb1 = !(RFLAG(lev, i,j,k+dz, SRCS(lev))&(CFFluid|CFInter)); \
- nb2 = !(RFLAG(lev, i,j+dy,k, SRCS(lev))&(CFFluid|CFInter)); \
- if((nb1)&&(!nb2)) { \
- /* y reflection */\
- newval = QCELL(lev, i,j+dy,k,SRCS(lev), D::dfRefY[l]); \
- } else \
- if((!nb1)&&(nb2)) { \
- /* z reflection */\
- newval = QCELL(lev, i,j,k+dz,SRCS(lev), D::dfRefZ[l]); \
- } else { \
- /* normal no slip in all other cases */\
- newval = ( QCELL(lev, i,j,k,SRCS(lev), inv_l) ); \
- } \
- } \
- if(nbf & CFBndPartslip) { /* part slip interpolation */ \
- const LbmFloat partv = mObjectPartslips[(int)(nbf>>24)]; \
- m[l] = RAC(ccel, D::dfInv[l] ) * partv + newval * (1.0-partv); /* part slip */ \
- } else {\
- m[l] = newval; /* normal free slip*/\
- }\
- /*if(RFLAG(lev, i,j,k, SRCS(lev))&CFInter) errMsg("FS","at "<<PRINT_IJK<<",l"<<l<<" nb1"<<nb1<<" nb2"<<nb2<<" dx"<<PRINT_VEC(dx,dy,dz)<<",srcl"<<debug_srcl<<" -> "<<newval );*/ \
- } /* l>2*dim free slip */ \
- \
} /* type reflect */\
else {\
- errMsg("LbmFsgrSolver","Invalid Bnd type at "<<PRINT_IJK<<" f"<<convertCellFlagType2String(nbf)<<",nbdir"<<D::dfInv[l] ); \
+ errMsg("LbmFsgrSolver","Invalid Bnd type at "<<PRINT_IJK<<" f"<<convertCellFlagType2String(nbf)<<",nbdir"<<this->dfInv[l] ); \
} \
} else { \
m[l] = QCELL_NBINV(lev, i, j, k, SRCS(lev), l,l); \
- STREAMCHECK(i+D::dfVecX[D::dfInv[l]], j+D::dfVecY[D::dfInv[l]],k+D::dfVecZ[D::dfInv[l]], l); \
+ STREAMCHECK(4, i+this->dfVecX[this->dfInv[l]], j+this->dfVecY[this->dfInv[l]],k+this->dfVecZ[this->dfInv[l]], l); \
} \
}
+
// careful ux,uy,uz need to be inited before!
#define DEFAULT_COLLIDE \
- D::collideArrays( m, rho,ux,uy,uz, OMEGA(lev), mLevel[lev].lcsmago, &mDebugOmegaRet, &lcsmqo ); \
+ this->collideArrays(i,j,k, m, rho,ux,uy,uz, OMEGA(lev), mLevel[lev].lcsmago, &mDebugOmegaRet, &lcsmqo ); \
CSMOMEGA_STATS(lev,mDebugOmegaRet); \
FORDF0 { RAC(tcel,l) = m[l]; } \
usqr = 1.5 * (ux*ux + uy*uy + uz*uz); \
@@ -372,13 +395,13 @@
m[0] = RAC(ccel,0); \
FORDF1 { /* df0 is set later on... */ \
/* FIXME CHECK INV ? */\
- if(RFLAG_NBINV(lev, i,j,k,SRCS(lev),l)&CFBnd) { errMsg("???", "bnd-err-nobndfl"); D::mPanic=1; \
+ if(RFLAG_NBINV(lev, i,j,k,SRCS(lev),l)&CFBnd) { errMsg("???", "bnd-err-nobndfl"); CAUSE_PANIC; \
} else { m[l] = QCELL_NBINV(lev, i, j, k, SRCS(lev), l, l); } \
- STREAMCHECK(i+D::dfVecX[D::dfInv[l]], j+D::dfVecY[D::dfInv[l]],k+D::dfVecZ[D::dfInv[l]], l); \
+ STREAMCHECK(8, i+this->dfVecX[this->dfInv[l]], j+this->dfVecY[this->dfInv[l]],k+this->dfVecZ[this->dfInv[l]], l); \
} \
- rho=m[0]; ux = mLevel[lev].gravity[0]; uy = mLevel[lev].gravity[1]; uz = mLevel[lev].gravity[2]; \
+ rho=m[0]; \
ux = mLevel[lev].gravity[0]; uy = mLevel[lev].gravity[1]; uz = mLevel[lev].gravity[2]; \
- D::collideArrays( m, rho,ux,uy,uz, OMEGA(lev), mLevel[lev].lcsmago , &mDebugOmegaRet, &lcsmqo ); \
+ this->collideArrays(i,j,k, m, rho,ux,uy,uz, OMEGA(lev), mLevel[lev].lcsmago , &mDebugOmegaRet, &lcsmqo ); \
CSMOMEGA_STATS(lev,mDebugOmegaRet); \
FORDF0 { RAC(tcel,l) = m[l]; } \
usqr = 1.5 * (ux*ux + uy*uy + uz*uz); \
@@ -387,6 +410,20 @@
#else // 3D, opt OPT3D==true
+// handle mov. obj
+#if FSGR_STRICT_DEBUG==1
+#define LBMDS_ADDMOV(linv,l) if(nbflag[linv]&CFBndMoving){ \
+ if(QCELL_NBINV(lev, i, j, k, SRCS(lev), l,dFlux)== (mSimulationTime+this->mpParam->getTimestep()) ) { \
+ m[l]+=QCELL_NBINV(lev, i, j, k, SRCS(lev), l,l); /* obs. speed*/ \
+ } else { \
+ CAUSE_PANIC; errMsg("INVALID_MOV_OBJ_TIME"," at "<<PRINT_IJK<<" from l"<<l<<" t="<<mSimulationTime<<" ct="<<QCELL_NBINV(lev, i, j, k, SRCS(lev), l,dFlux)); \
+ } \
+ }
+#else // FSGR_STRICT_DEBUG==1
+#define LBMDS_ADDMOV(linv,l) if(nbflag[linv]&CFBndMoving){ m[l]+=QCELL_NBINV(lev, i, j, k, SRCS(lev), l,l); } /* obs. speed*/
+#endif // FSGR_STRICT_DEBUG==1
+
+// default stream opt3d add moving bc val
#define DEFAULT_STREAM \
m[dC] = RAC(ccel,dC); \
/* explicit streaming */ \
@@ -400,26 +437,26 @@
m[dET] = CSRC_ET; m[dEB] = CSRC_EB; m[dWT] = CSRC_WT; m[dWB] = CSRC_WB; \
} else { \
/* explicit streaming, normal velocity always zero for obstacles */ \
- if(nbflag[dS ]&CFBnd) { m[dN ] = RAC(ccel,dS ); } else { m[dN ] = CSRC_N ; } \
- if(nbflag[dN ]&CFBnd) { m[dS ] = RAC(ccel,dN ); } else { m[dS ] = CSRC_S ; } \
- if(nbflag[dW ]&CFBnd) { m[dE ] = RAC(ccel,dW ); } else { m[dE ] = CSRC_E ; } \
- if(nbflag[dE ]&CFBnd) { m[dW ] = RAC(ccel,dE ); } else { m[dW ] = CSRC_W ; } \
- if(nbflag[dB ]&CFBnd) { m[dT ] = RAC(ccel,dB ); } else { m[dT ] = CSRC_T ; } \
- if(nbflag[dT ]&CFBnd) { m[dB ] = RAC(ccel,dT ); } else { m[dB ] = CSRC_B ; } \
+ if(nbflag[dS ]&CFBnd) { m[dN ] = RAC(ccel,dS ); LBMDS_ADDMOV(dS ,dN ); } else { m[dN ] = CSRC_N ; } \
+ if(nbflag[dN ]&CFBnd) { m[dS ] = RAC(ccel,dN ); LBMDS_ADDMOV(dN ,dS ); } else { m[dS ] = CSRC_S ; } \
+ if(nbflag[dW ]&CFBnd) { m[dE ] = RAC(ccel,dW ); LBMDS_ADDMOV(dW ,dE ); } else { m[dE ] = CSRC_E ; } \
+ if(nbflag[dE ]&CFBnd) { m[dW ] = RAC(ccel,dE ); LBMDS_ADDMOV(dE ,dW ); } else { m[dW ] = CSRC_W ; } \
+ if(nbflag[dB ]&CFBnd) { m[dT ] = RAC(ccel,dB ); LBMDS_ADDMOV(dB ,dT ); } else { m[dT ] = CSRC_T ; } \
+ if(nbflag[dT ]&CFBnd) { m[dB ] = RAC(ccel,dT ); LBMDS_ADDMOV(dT ,dB ); } else { m[dB ] = CSRC_B ; } \
\
/* also treat free slip here */ \
- if(nbflag[dSW]&CFBnd) { if(nbflag[dSW]&CFBndNoslip){ m[dNE] = RAC(ccel,dSW); }else{ DEFAULT_STREAM_FREESLIP(dNE,dSW,nbflag[dSW]);} } else { m[dNE] = CSRC_NE; } \
- if(nbflag[dSE]&CFBnd) { if(nbflag[dSE]&CFBndNoslip){ m[dNW] = RAC(ccel,dSE); }else{ DEFAULT_STREAM_FREESLIP(dNW,dSE,nbflag[dSE]);} } else { m[dNW] = CSRC_NW; } \
- if(nbflag[dNW]&CFBnd) { if(nbflag[dNW]&CFBndNoslip){ m[dSE] = RAC(ccel,dNW); }else{ DEFAULT_STREAM_FREESLIP(dSE,dNW,nbflag[dNW]);} } else { m[dSE] = CSRC_SE; } \
- if(nbflag[dNE]&CFBnd) { if(nbflag[dNE]&CFBndNoslip){ m[dSW] = RAC(ccel,dNE); }else{ DEFAULT_STREAM_FREESLIP(dSW,dNE,nbflag[dNE]);} } else { m[dSW] = CSRC_SW; } \
- if(nbflag[dSB]&CFBnd) { if(nbflag[dSB]&CFBndNoslip){ m[dNT] = RAC(ccel,dSB); }else{ DEFAULT_STREAM_FREESLIP(dNT,dSB,nbflag[dSB]);} } else { m[dNT] = CSRC_NT; } \
- if(nbflag[dST]&CFBnd) { if(nbflag[dST]&CFBndNoslip){ m[dNB] = RAC(ccel,dST); }else{ DEFAULT_STREAM_FREESLIP(dNB,dST,nbflag[dST]);} } else { m[dNB] = CSRC_NB; } \
- if(nbflag[dNB]&CFBnd) { if(nbflag[dNB]&CFBndNoslip){ m[dST] = RAC(ccel,dNB); }else{ DEFAULT_STREAM_FREESLIP(dST,dNB,nbflag[dNB]);} } else { m[dST] = CSRC_ST; } \
- if(nbflag[dNT]&CFBnd) { if(nbflag[dNT]&CFBndNoslip){ m[dSB] = RAC(ccel,dNT); }else{ DEFAULT_STREAM_FREESLIP(dSB,dNT,nbflag[dNT]);} } else { m[dSB] = CSRC_SB; } \
- if(nbflag[dWB]&CFBnd) { if(nbflag[dWB]&CFBndNoslip){ m[dET] = RAC(ccel,dWB); }else{ DEFAULT_STREAM_FREESLIP(dET,dWB,nbflag[dWB]);} } else { m[dET] = CSRC_ET; } \
- if(nbflag[dWT]&CFBnd) { if(nbflag[dWT]&CFBndNoslip){ m[dEB] = RAC(ccel,dWT); }else{ DEFAULT_STREAM_FREESLIP(dEB,dWT,nbflag[dWT]);} } else { m[dEB] = CSRC_EB; } \
- if(nbflag[dEB]&CFBnd) { if(nbflag[dEB]&CFBndNoslip){ m[dWT] = RAC(ccel,dEB); }else{ DEFAULT_STREAM_FREESLIP(dWT,dEB,nbflag[dEB]);} } else { m[dWT] = CSRC_WT; } \
- if(nbflag[dET]&CFBnd) { if(nbflag[dET]&CFBndNoslip){ m[dWB] = RAC(ccel,dET); }else{ DEFAULT_STREAM_FREESLIP(dWB,dET,nbflag[dET]);} } else { m[dWB] = CSRC_WB; } \
+ if(nbflag[dSW]&CFBnd) { if(nbflag[dSW]&CFBndNoslip){ m[dNE] = RAC(ccel,dSW); LBMDS_ADDMOV(dSW,dNE); }else{ DEFAULT_STREAM_FREESLIP(dNE,dSW,nbflag[dSW]);} } else { m[dNE] = CSRC_NE; } \
+ if(nbflag[dSE]&CFBnd) { if(nbflag[dSE]&CFBndNoslip){ m[dNW] = RAC(ccel,dSE); LBMDS_ADDMOV(dSE,dNW); }else{ DEFAULT_STREAM_FREESLIP(dNW,dSE,nbflag[dSE]);} } else { m[dNW] = CSRC_NW; } \
+ if(nbflag[dNW]&CFBnd) { if(nbflag[dNW]&CFBndNoslip){ m[dSE] = RAC(ccel,dNW); LBMDS_ADDMOV(dNW,dSE); }else{ DEFAULT_STREAM_FREESLIP(dSE,dNW,nbflag[dNW]);} } else { m[dSE] = CSRC_SE; } \
+ if(nbflag[dNE]&CFBnd) { if(nbflag[dNE]&CFBndNoslip){ m[dSW] = RAC(ccel,dNE); LBMDS_ADDMOV(dNE,dSW); }else{ DEFAULT_STREAM_FREESLIP(dSW,dNE,nbflag[dNE]);} } else { m[dSW] = CSRC_SW; } \
+ if(nbflag[dSB]&CFBnd) { if(nbflag[dSB]&CFBndNoslip){ m[dNT] = RAC(ccel,dSB); LBMDS_ADDMOV(dSB,dNT); }else{ DEFAULT_STREAM_FREESLIP(dNT,dSB,nbflag[dSB]);} } else { m[dNT] = CSRC_NT; } \
+ if(nbflag[dST]&CFBnd) { if(nbflag[dST]&CFBndNoslip){ m[dNB] = RAC(ccel,dST); LBMDS_ADDMOV(dST,dNB); }else{ DEFAULT_STREAM_FREESLIP(dNB,dST,nbflag[dST]);} } else { m[dNB] = CSRC_NB; } \
+ if(nbflag[dNB]&CFBnd) { if(nbflag[dNB]&CFBndNoslip){ m[dST] = RAC(ccel,dNB); LBMDS_ADDMOV(dNB,dST); }else{ DEFAULT_STREAM_FREESLIP(dST,dNB,nbflag[dNB]);} } else { m[dST] = CSRC_ST; } \
+ if(nbflag[dNT]&CFBnd) { if(nbflag[dNT]&CFBndNoslip){ m[dSB] = RAC(ccel,dNT); LBMDS_ADDMOV(dNT,dSB); }else{ DEFAULT_STREAM_FREESLIP(dSB,dNT,nbflag[dNT]);} } else { m[dSB] = CSRC_SB; } \
+ if(nbflag[dWB]&CFBnd) { if(nbflag[dWB]&CFBndNoslip){ m[dET] = RAC(ccel,dWB); LBMDS_ADDMOV(dWB,dET); }else{ DEFAULT_STREAM_FREESLIP(dET,dWB,nbflag[dWB]);} } else { m[dET] = CSRC_ET; } \
+ if(nbflag[dWT]&CFBnd) { if(nbflag[dWT]&CFBndNoslip){ m[dEB] = RAC(ccel,dWT); LBMDS_ADDMOV(dWT,dEB); }else{ DEFAULT_STREAM_FREESLIP(dEB,dWT,nbflag[dWT]);} } else { m[dEB] = CSRC_EB; } \
+ if(nbflag[dEB]&CFBnd) { if(nbflag[dEB]&CFBndNoslip){ m[dWT] = RAC(ccel,dEB); LBMDS_ADDMOV(dEB,dWT); }else{ DEFAULT_STREAM_FREESLIP(dWT,dEB,nbflag[dEB]);} } else { m[dWT] = CSRC_WT; } \
+ if(nbflag[dET]&CFBnd) { if(nbflag[dET]&CFBndNoslip){ m[dWB] = RAC(ccel,dET); LBMDS_ADDMOV(dET,dWB); }else{ DEFAULT_STREAM_FREESLIP(dWB,dET,nbflag[dET]);} } else { m[dWB] = CSRC_WB; } \
}
@@ -522,9 +559,10 @@
+ MSRC_ST - MSRC_SB \
+ MSRC_ET - MSRC_EB \
+ MSRC_WT - MSRC_WB ; \
+ PRECOLLIDE_MODS(rho,ux,uy,uz); \
usqr = 1.5 * (ux*ux + uy*uy + uz*uz); \
COLL_CALCULATE_DFEQ(lcsmeq); \
- COLL_CALCULATE_NONEQTENSOR(lev, MSRC_)\
+ COLL_CALCULATE_NONEQTENSOR(lev, MSRC_); \
COLL_CALCULATE_CSMOMEGAVAL(lev, lcsmomega); \
CSMOMEGA_STATS(lev,lcsmomega); \
\
@@ -579,6 +617,7 @@
+ MSRC_ST - MSRC_SB \
+ MSRC_ET - MSRC_EB \
+ MSRC_WT - MSRC_WB ; \
+ PRECOLLIDE_MODS(rho,ux,uy,uz); \
usqr = 1.5 * (ux*ux + uy*uy + uz*uz); \
\
RAC(tcel,dC ) = (1.0-OMEGA(lev))*MSRC_C + OMEGA(lev)*EQC ; \
@@ -624,6 +663,7 @@
+ MSRC_NT + MSRC_NB - MSRC_ST - MSRC_SB + mLevel[lev].gravity[1]; \
uz = MSRC_T - MSRC_B + MSRC_NT - MSRC_NB + MSRC_ST - MSRC_SB \
+ MSRC_ET - MSRC_EB + MSRC_WT - MSRC_WB + mLevel[lev].gravity[2]; \
+ PRECOLLIDE_MODS(rho,ux,uy,uz); \
usqr = 1.5 * (ux*ux + uy*uy + uz*uz); \
COLL_CALCULATE_DFEQ(lcsmeq); \
COLL_CALCULATE_NONEQTENSOR(lev, MSRC_) \
@@ -664,6 +704,7 @@
+ CSRC_NT + CSRC_NB - CSRC_ST - CSRC_SB + mLevel[lev].gravity[1]; \
uz = CSRC_T - CSRC_B + CSRC_NT - CSRC_NB + CSRC_ST - CSRC_SB \
+ CSRC_ET - CSRC_EB + CSRC_WT - CSRC_WB + mLevel[lev].gravity[2]; \
+ PRECOLLIDE_MODS(rho,ux,uy,uz); \
usqr = 1.5 * (ux*ux + uy*uy + uz*uz); \
COLL_CALCULATE_DFEQ(lcsmeq); \
COLL_CALCULATE_NONEQTENSOR(lev, CSRC_) \
@@ -703,6 +744,7 @@
+ CSRC_NT + CSRC_NB - CSRC_ST - CSRC_SB + mLevel[lev].gravity[1]; \
uz = CSRC_T - CSRC_B + CSRC_NT - CSRC_NB + CSRC_ST - CSRC_SB \
+ CSRC_ET - CSRC_EB + CSRC_WT - CSRC_WB + mLevel[lev].gravity[2]; \
+ PRECOLLIDE_MODS(rho,ux,uy,uz); \
usqr = 1.5 * (ux*ux + uy*uy + uz*uz); \
RAC(tcel,dC ) = (1.0-OMEGA(lev))*CSRC_C + OMEGA(lev)*EQC ; \
RAC(tcel,dN ) = (1.0-OMEGA(lev))*CSRC_N + OMEGA(lev)*EQN ; \
@@ -734,13 +776,12 @@
#define OPTIMIZED_STREAMCOLLIDE_DEBUG \
m[0] = RAC(ccel,0); \
FORDF1 { /* df0 is set later on... */ \
- if(RFLAG_NB(lev, i,j,k,SRCS(lev),l)&CFBnd) { errMsg("???", "bnd-err-nobndfl"); D::mPanic=1; \
+ if(RFLAG_NB(lev, i,j,k,SRCS(lev),l)&CFBnd) { errMsg("???", "bnd-err-nobndfl"); CAUSE_PANIC;\
} else { m[l] = QCELL_NBINV(lev, i, j, k, SRCS(lev), l, l); } \
- STREAMCHECK(i+D::dfVecX[D::dfInv[l]], j+D::dfVecY[D::dfInv[l]],k+D::dfVecZ[D::dfInv[l]], l); \
+ STREAMCHECK(9, i+this->dfVecX[this->dfInv[l]], j+this->dfVecY[this->dfInv[l]],k+this->dfVecZ[this->dfInv[l]], l); \
} \
rho=m[0]; ux = mLevel[lev].gravity[0]; uy = mLevel[lev].gravity[1]; uz = mLevel[lev].gravity[2]; \
- ux = mLevel[lev].gravity[0]; uy = mLevel[lev].gravity[1]; uz = mLevel[lev].gravity[2]; \
- D::collideArrays( m, rho,ux,uy,uz, OMEGA(lev), mLevel[lev].lcsmago , &mDebugOmegaRet, &lcsmqo ); \
+ this->collideArrays(i,j,k, m, rho,ux,uy,uz, OMEGA(lev), mLevel[lev].lcsmago , &mDebugOmegaRet, &lcsmqo ); \
CSMOMEGA_STATS(lev,mDebugOmegaRet); \
FORDF0 { RAC(tcel,l) = m[l]; } \
usqr = 1.5 * (ux*ux + uy*uy + uz*uz); \
@@ -752,13 +793,12 @@
/*DEBUG \
m[0] = RAC(ccel,0); \
FORDF1 { \
- if(RFLAG_NB(lev, i,j,k,SRCS(lev),l)&CFBnd) { errMsg("???", "bnd-err-nobndfl"); D::mPanic=1; \
+ if(RFLAG_NB(lev, i,j,k,SRCS(lev),l)&CFBnd) { errMsg("???", "bnd-err-nobndfl");CAUSE_PANIC; \
} else { m[l] = QCELL_NBINV(lev, i, j, k, SRCS(lev), l, l); } \
} \
errMsg("T","QSDM at %d,%d,%d lcsmqo=%25.15f, lcsmomega=%f \n", i,j,k, lcsmqo,lcsmomega ); \
rho=m[0]; ux = mLevel[lev].gravity[0]; uy = mLevel[lev].gravity[1]; uz = mLevel[lev].gravity[2]; \
- ux = mLevel[lev].gravity[0]; uy = mLevel[lev].gravity[1]; uz = mLevel[lev].gravity[2]; \
- D::collideArrays( m, rho,ux,uy,uz, OMEGA(lev), mLevel[lev].lcsmago , &mDebugOmegaRet, &lcsmqo ); \
+ this->collideArrays(i,j,k, m, rho,ux,uy,uz, OMEGA(lev), mLevel[lev].lcsmago , &mDebugOmegaRet, &lcsmqo ); \
CSMOMEGA_STATS(lev,mDebugOmegaRet); \
*/
#if USE_LES==1
@@ -811,7 +851,7 @@ errMsg("T","QSDM at %d,%d,%d lcsmqo=%25.15f, lcsmomega=%f \n", i,j,k, lcsmqo,lc
((( (at))>0.0) && (!(QCELL((alev), (ai),(aj),(ak),mLevel[(alev)].setOther, l) > -1.0 ))) ){ \
errMsg("INVDFSCHECK", " l"<<(alev)<<" "<<PRINT_VEC((ai),(aj),(ak))<<" fc:"<<RFLAG((alev), (ai),(aj),(ak),mLevel[(alev)].setCurr )<<" fo:"<<RFLAG((alev), (ai),(aj),(ak),mLevel[(alev)].setOther )<<" dfl"<<l ); \
debugMarkCell((alev), (ai),(aj),(ak));\
- D::mPanic = 1; \
+ CAUSE_PANIC; \
}
// end ADD_INT_DFSCHECK
#define ADD_INT_FLAGCHECK(alev, ai,aj,ak, at, afac) \
@@ -821,7 +861,7 @@ errMsg("T","QSDM at %d,%d,%d lcsmqo=%25.15f, lcsmomega=%f \n", i,j,k, lcsmqo,lc
" fc:"<< convertCellFlagType2String(RFLAG((alev), (ai),(aj),(ak),mLevel[(alev)].setCurr )) <<\
" fold:"<< convertCellFlagType2String(RFLAG((alev), (ai),(aj),(ak),mLevel[(alev)].setOther )) ); \
debugMarkCell((alev), (ai),(aj),(ak));\
- D::mPanic = 1; \
+ CAUSE_PANIC; \
}
// end ADD_INT_DFSCHECK
@@ -833,7 +873,7 @@ errMsg("T","QSDM at %d,%d,%d lcsmqo=%25.15f, lcsmomega=%f \n", i,j,k, lcsmqo,lc
if( (RFLAG(lev+1, (ix),(iy),(iz), mLevel[lev+1].setCurr) != (CFFluid|CFGrFromCoarse)) ){\
errMsg("INTFLAGUNU_CHECK", PRINT_VEC(i,j,k)<<" child not unused at l"<<(lev+1)<<" "<<PRINT_VEC((ix),(iy),(iz))<<" flag: "<< RFLAG(lev+1, (ix),(iy),(iz), mLevel[lev+1].setCurr) ); \
debugMarkCell((lev+1), (ix),(iy),(iz));\
- D::mPanic = 1; \
+ CAUSE_PANIC; \
}\
RFLAG(lev+1, (ix),(iy),(iz), mLevel[lev+1].setCurr) |= CFGrCoarseInited; \
// INTUNUTCHECK
@@ -841,7 +881,7 @@ errMsg("T","QSDM at %d,%d,%d lcsmqo=%25.15f, lcsmomega=%f \n", i,j,k, lcsmqo,lc
if( QCELL(lev+1, (ix),(iy),(iz), mLevel[lev+1].setCurr, l) <= 0.0 ){\
errMsg("INVDFCCELLCHECK", "caseId:"<<caseId<<" "<<PRINT_VEC(i,j,k)<<" child inter at "<<PRINT_VEC((ix),(iy),(iz))<<" invalid df "<<l<<" = "<< QCELL(lev+1, (ix),(iy),(iz), mLevel[lev+1].setCurr, l) ); \
debugMarkCell((lev+1), (ix),(iy),(iz));\
- D::mPanic = 1; \
+ CAUSE_PANIC; \
}\
// INTSTRICTCHECK
@@ -858,11 +898,11 @@ errMsg("T","QSDM at %d,%d,%d lcsmqo=%25.15f, lcsmomega=%f \n", i,j,k, lcsmqo,lc
{ /*LbmFloat rho,ux,uy,uz;*/ \
rho = ux=uy=uz=0.0; \
FORDF0{ LbmFloat m = QCELL(lev,i,j,k, dstSet, l); \
- rho += m; ux += (D::dfDvecX[l]*m); uy += (D::dfDvecY[l]*m); uz += (D::dfDvecZ[l]*m); \
- if(ABS(m)>1.0) { errMsg("interpolateCellFromCoarse", "ICFC_DFCHECK cell "<<PRINT_IJK<<" m"<<l<<":"<< m ); D::mPanic=1; }\
+ rho += m; ux += (this->dfDvecX[l]*m); uy += (this->dfDvecY[l]*m); uz += (this->dfDvecZ[l]*m); \
+ if(ABS(m)>1.0) { errMsg("interpolateCellFromCoarse", "ICFC_DFCHECK cell "<<PRINT_IJK<<" m"<<l<<":"<< m );CAUSE_PANIC;}\
/*errMsg("interpolateCellFromCoarse", " cell "<<PRINT_IJK<<" df"<<l<<":"<<m );*/ \
} \
- /*if(D::mPanic) { errMsg("interpolateCellFromCoarse", "ICFC_DFOUT cell "<<PRINT_IJK<<" rho:"<<rho<<" u:"<<PRINT_VEC(ux,uy,uz)<<" b"<<PRINT_VEC(betx,bety,betz) ); }*/ \
+ /*if(this->mPanic) { errMsg("interpolateCellFromCoarse", "ICFC_DFOUT cell "<<PRINT_IJK<<" rho:"<<rho<<" u:"<<PRINT_VEC(ux,uy,uz)<<" b"<<PRINT_VEC(betx,bety,betz) ); }*/ \
if(markNbs) errMsg("interpolateCellFromCoarse", " cell "<<PRINT_IJK<<" rho:"<<rho<<" u:"<<PRINT_VEC(ux,uy,uz)<<" b"<<PRINT_VEC(betx,bety,betz) ); \
/*errMsg("interpolateCellFromCoarse", "ICFC_DFDEBUG cell "<<PRINT_IJK<<" rho:"<<rho<<" u:"<<PRINT_VEC(ux,uy,uz)<<" b"<<PRINT_VEC(betx,bety,betz) ); */\
} \
@@ -872,7 +912,7 @@ errMsg("T","QSDM at %d,%d,%d lcsmqo=%25.15f, lcsmomega=%f \n", i,j,k, lcsmqo,lc
/* might also have CFGrCoarseInited (shouldnt be a problem here)*/ \
errMsg("interpolateCellFromCoarse", "CHECK cell not CFGrFromCoarse? "<<PRINT_IJK<<" flag:"<< RFLAG(lev,i,j,k, dstSet)<<" fstr:"<<convertCellFlagType2String( RFLAG(lev,i,j,k, dstSet) )); \
/* FIXME check this warning...? return; this can happen !? */ \
- /*D::mPanic = 1;*/ \
+ /*CAUSE_PANIC;*/ \
} \
// end INTDEBOUT
#else // FSGR_STRICT_DEBUG==1
@@ -894,15 +934,15 @@ errMsg("T","QSDM at %d,%d,%d lcsmqo=%25.15f, lcsmomega=%f \n", i,j,k, lcsmqo,lc
ADD_INT_DFSCHECK(alev, ai,aj,ak, at, afac, l); \
df *= (afac); \
rho += df; \
- ux += (D::dfDvecX[l]*df); \
- uy += (D::dfDvecY[l]*df); \
- uz += (D::dfDvecZ[l]*df); \
+ ux += (this->dfDvecX[l]*df); \
+ uy += (this->dfDvecY[l]*df); \
+ uz += (this->dfDvecZ[l]*df); \
intDf[l] += df; \
}
// write interpolated dfs back to cell (correct non-eq. parts)
#define IDF_WRITEBACK_ \
FORDF0{ \
- LbmFloat eq = D::getCollideEq(l, rho,ux,uy,uz);\
+ LbmFloat eq = getCollideEq(l, rho,ux,uy,uz);\
QCELL(lev,i,j,k, dstSet, l) = (eq+ (intDf[l]-eq)*mDfScaleDown);\
} \
/* check that all values are ok */ \
@@ -913,18 +953,18 @@ errMsg("T","QSDM at %d,%d,%d lcsmqo=%25.15f, lcsmomega=%f \n", i,j,k, lcsmqo,lc
LbmFloat feq[LBM_DFNUM]; \
LbmFloat dfScale = mDfScaleDown; \
FORDF0{ \
- feq[l] = D::getCollideEq(l, rho,ux,uy,uz); \
+ feq[l] = getCollideEq(l, rho,ux,uy,uz); \
} \
if(mLevel[lev ].lcsmago>0.0) {\
- LbmFloat Qo = D::getLesNoneqTensorCoeff(intDf,feq); \
- omegaDst = D::getLesOmega(mLevel[lev+0].omega,mLevel[lev+0].lcsmago,Qo); \
- omegaSrc = D::getLesOmega(mLevel[lev-1].omega,mLevel[lev-1].lcsmago,Qo); \
+ LbmFloat Qo = this->getLesNoneqTensorCoeff(intDf,feq); \
+ omegaDst = this->getLesOmega(mLevel[lev+0].omega,mLevel[lev+0].lcsmago,Qo); \
+ omegaSrc = this->getLesOmega(mLevel[lev-1].omega,mLevel[lev-1].lcsmago,Qo); \
} else {\
omegaDst = mLevel[lev+0].omega; \
omegaSrc = mLevel[lev-1].omega;\
} \
\
- dfScale = (mLevel[lev+0].stepsize/mLevel[lev-1].stepsize)* (1.0/omegaDst-1.0)/ (1.0/omegaSrc-1.0); \
+ dfScale = (mLevel[lev+0].timestep/mLevel[lev-1].timestep)* (1.0/omegaDst-1.0)/ (1.0/omegaSrc-1.0); \
FORDF0{ \
/*errMsg("SMAGO"," org"<<mDfScaleDown<<" n"<<dfScale<<" qc"<< QCELL(lev,i,j,k, dstSet, l)<<" idf"<<intDf[l]<<" eq"<<feq[l] ); */ \
QCELL(lev,i,j,k, dstSet, l) = (feq[l]+ (intDf[l]-feq[l])*dfScale);\
@@ -1015,7 +1055,7 @@ errMsg("T","QSDM at %d,%d,%d lcsmqo=%25.15f, lcsmomega=%f \n", i,j,k, lcsmqo,lc
COLL_CALCULATE_CSMOMEGAVAL(lev+0, lcsmDstOmega); \
COLL_CALCULATE_CSMOMEGAVAL(lev-1, lcsmSrcOmega); \
\
- lcsmdfscale = (mLevel[lev+0].stepsize/mLevel[lev-1].stepsize)* (1.0/lcsmDstOmega-1.0)/ (1.0/lcsmSrcOmega-1.0); \
+ lcsmdfscale = (mLevel[lev+0].timestep/mLevel[lev-1].timestep)* (1.0/lcsmDstOmega-1.0)/ (1.0/lcsmSrcOmega-1.0); \
RAC(dstcell, dC ) = (lcsmeq[dC ] + (intDf[dC ]-lcsmeq[dC ] )*lcsmdfscale);\
RAC(dstcell, dN ) = (lcsmeq[dN ] + (intDf[dN ]-lcsmeq[dN ] )*lcsmdfscale);\
RAC(dstcell, dS ) = (lcsmeq[dS ] + (intDf[dS ]-lcsmeq[dS ] )*lcsmdfscale);\
@@ -1070,3 +1110,104 @@ errMsg("T","QSDM at %d,%d,%d lcsmqo=%25.15f, lcsmomega=%f \n", i,j,k, lcsmqo,lc
#endif// OPT3D==0
+
+
+/******************************************************************************/
+/*! relaxation LES functions */
+/******************************************************************************/
+
+
+inline LbmFloat LbmFsgrSolver::getLesNoneqTensorCoeff(
+ LbmFloat df[],
+ LbmFloat feq[] ) {
+ LbmFloat Qo = 0.0;
+ for(int m=0; m< ((LBMDIM*LBMDIM)-LBMDIM)/2 ; m++) {
+ LbmFloat qadd = 0.0;
+ for(int l=1; l<this->cDfNum; l++) {
+ if(this->lesCoeffOffdiag[m][l]==0.0) continue;
+ qadd += this->lesCoeffOffdiag[m][l]*(df[l]-feq[l]);
+ }
+ Qo += (qadd*qadd);
+ }
+ Qo *= 2.0; // off diag twice
+ for(int m=0; m<LBMDIM; m++) {
+ LbmFloat qadd = 0.0;
+ for(int l=1; l<this->cDfNum; l++) {
+ if(this->lesCoeffDiag[m][l]==0.0) continue;
+ qadd += this->lesCoeffDiag[m][l]*(df[l]-feq[l]);
+ }
+ Qo += (qadd*qadd);
+ }
+ Qo = sqrt(Qo);
+ return Qo;
+};
+
+inline LbmFloat LbmFsgrSolver::getLesOmega(LbmFloat omega, LbmFloat csmago, LbmFloat Qo) {
+ const LbmFloat tau = 1.0/omega;
+ const LbmFloat nu = (2.0*tau-1.0) * (1.0/6.0);
+ const LbmFloat C = csmago;
+ const LbmFloat Csqr = C*C;
+ LbmFloat S = -nu + sqrt( nu*nu + 18.0*Csqr*Qo ) / (6.0*Csqr);
+ return( 1.0/( 3.0*( nu+Csqr*S ) +0.5 ) );
+}
+
+#define DEBUG_CALCPRINTCELL(str,df) {\
+ LbmFloat rho=df[0], ux=0., uy=0., uz=0.; \
+ for(int l=1; l<this->cDfNum; l++) { \
+ rho += df[l]; \
+ ux += (this->dfDvecX[l]*df[l]); \
+ uy += (this->dfDvecY[l]*df[l]); \
+ uz += (this->dfDvecZ[l]*df[l]); \
+ } \
+ errMsg("DEBUG_CALCPRINTCELL",">"<<str<<" rho="<<rho<<" vel="<<ntlVec3Gfx(ux,uy,uz) ); \
+ } /* END DEBUG_CALCPRINTCELL */
+
+// "normal" collision
+inline void LbmFsgrSolver::collideArrays(
+ int i, int j, int k, // position - more for debugging
+ LbmFloat df[],
+ LbmFloat &outrho, // out only!
+ // velocity modifiers (returns actual velocity!)
+ LbmFloat &mux, LbmFloat &muy, LbmFloat &muz,
+ LbmFloat omega, LbmFloat csmago,
+ LbmFloat *newOmegaRet, LbmFloat *newQoRet
+ ) {
+ LbmFloat rho=df[0];
+ LbmFloat ux = mux;
+ LbmFloat uy = muy;
+ LbmFloat uz = muz;
+ for(int l=1; l<this->cDfNum; l++) {
+ rho += df[l];
+ ux += (this->dfDvecX[l]*df[l]);
+ uy += (this->dfDvecY[l]*df[l]);
+ uz += (this->dfDvecZ[l]*df[l]);
+ }
+
+ PRECOLLIDE_MODS(rho,ux,uy,uz);
+ LbmFloat feq[19];
+ for(int l=0; l<this->cDfNum; l++) {
+ feq[l] = getCollideEq(l,rho,ux,uy,uz);
+ }
+
+ LbmFloat omegaNew;
+ LbmFloat Qo = 0.0;
+ if(csmago>0.0) {
+ Qo = getLesNoneqTensorCoeff(df,feq);
+ omegaNew = getLesOmega(omega,csmago,Qo);
+ } else {
+ omegaNew = omega; // smago off...
+ }
+ if(newOmegaRet) *newOmegaRet = omegaNew; // return value for stats
+ if(newQoRet) *newQoRet = Qo; // return value of non-eq. stress tensor
+
+ for(int l=0; l<this->cDfNum; l++) {
+ df[l] = (1.0-omegaNew ) * df[l] + omegaNew * feq[l];
+ }
+ if((i==16)&&(j==10)) DEBUG_CALCPRINTCELL( "2dcoll "<<PRINT_IJK, df);
+
+ mux = ux;
+ muy = uy;
+ muz = uz;
+ outrho = rho;
+};
+
diff --git a/intern/elbeem/intern/solver_util.cpp b/intern/elbeem/intern/solver_util.cpp
index 9c2a0035024..7406c55acbc 100644
--- a/intern/elbeem/intern/solver_util.cpp
+++ b/intern/elbeem/intern/solver_util.cpp
@@ -7,8 +7,9 @@
*
*****************************************************************************/
-#if ((!defined(__APPLE_CC__)) && (!defined(__INTEL_COMPILER))) || defined(LBM_FORCEINCLUDE)
#include "solver_class.h"
+#include "solver_relax.h"
+#include "particletracer.h"
/******************************************************************************
@@ -16,8 +17,7 @@
*****************************************************************************/
//! for raytracing
-template<class D>
-void LbmFsgrSolver<D>::prepareVisualization( void ) {
+void LbmFsgrSolver::prepareVisualization( void ) {
int lev = mMaxRefine;
int workSet = mLevel[lev].setCurr;
@@ -31,7 +31,7 @@ void LbmFsgrSolver<D>::prepareVisualization( void ) {
for(int k= 0; k< 5; ++k)
for(int j=0;j<mLevel[lev].lSizey-0;j++)
for(int i=0;i<mLevel[lev].lSizex-0;i++) {
- *D::mpIso->lbmGetData(i,j,ZKOFF)=0.0;
+ *this->mpIso->lbmGetData(i,j,ZKOFF)=0.0;
}
#else // LBMDIM==2
// 3d, use normal bounds
@@ -41,7 +41,7 @@ void LbmFsgrSolver<D>::prepareVisualization( void ) {
for(int k= getForZMinBnd(); k< getForZMaxBnd(lev); ++k)
for(int j=0;j<mLevel[lev].lSizey-0;j++)
for(int i=0;i<mLevel[lev].lSizex-0;i++) {
- *D::mpIso->lbmGetData(i,j,ZKOFF)=0.0;
+ *this->mpIso->lbmGetData(i,j,ZKOFF)=0.0;
}
#endif // LBMDIM==2
@@ -63,153 +63,183 @@ void LbmFsgrSolver<D>::prepareVisualization( void ) {
/* // flicker-test-fix: no real difference
if( (!(RFLAG(lev, i,j,k,workSet)&CFNoBndFluid)) &&
(RFLAG(lev, i,j,k,workSet)&CFNoNbFluid) &&
- (val<D::mIsoValue) ){
- val = D::mIsoValue*1.1; }
+ (val<this->mIsoValue) ){
+ val = this->mIsoValue*1.1; }
// */
} else {
// fluid?
val = 1.0; ///27.0;
} // */
- *D::mpIso->lbmGetData( i-1 , j-1 ,ZKOFF-ZKD1) += ( val * mIsoWeight[0] );
- *D::mpIso->lbmGetData( i , j-1 ,ZKOFF-ZKD1) += ( val * mIsoWeight[1] );
- *D::mpIso->lbmGetData( i+1 , j-1 ,ZKOFF-ZKD1) += ( val * mIsoWeight[2] );
+ *this->mpIso->lbmGetData( i-1 , j-1 ,ZKOFF-ZKD1) += ( val * mIsoWeight[0] );
+ *this->mpIso->lbmGetData( i , j-1 ,ZKOFF-ZKD1) += ( val * mIsoWeight[1] );
+ *this->mpIso->lbmGetData( i+1 , j-1 ,ZKOFF-ZKD1) += ( val * mIsoWeight[2] );
- *D::mpIso->lbmGetData( i-1 , j ,ZKOFF-ZKD1) += ( val * mIsoWeight[3] );
- *D::mpIso->lbmGetData( i , j ,ZKOFF-ZKD1) += ( val * mIsoWeight[4] );
- *D::mpIso->lbmGetData( i+1 , j ,ZKOFF-ZKD1) += ( val * mIsoWeight[5] );
+ *this->mpIso->lbmGetData( i-1 , j ,ZKOFF-ZKD1) += ( val * mIsoWeight[3] );
+ *this->mpIso->lbmGetData( i , j ,ZKOFF-ZKD1) += ( val * mIsoWeight[4] );
+ *this->mpIso->lbmGetData( i+1 , j ,ZKOFF-ZKD1) += ( val * mIsoWeight[5] );
- *D::mpIso->lbmGetData( i-1 , j+1 ,ZKOFF-ZKD1) += ( val * mIsoWeight[6] );
- *D::mpIso->lbmGetData( i , j+1 ,ZKOFF-ZKD1) += ( val * mIsoWeight[7] );
- *D::mpIso->lbmGetData( i+1 , j+1 ,ZKOFF-ZKD1) += ( val * mIsoWeight[8] );
+ *this->mpIso->lbmGetData( i-1 , j+1 ,ZKOFF-ZKD1) += ( val * mIsoWeight[6] );
+ *this->mpIso->lbmGetData( i , j+1 ,ZKOFF-ZKD1) += ( val * mIsoWeight[7] );
+ *this->mpIso->lbmGetData( i+1 , j+1 ,ZKOFF-ZKD1) += ( val * mIsoWeight[8] );
- *D::mpIso->lbmGetData( i-1 , j-1 ,ZKOFF ) += ( val * mIsoWeight[9] );
- *D::mpIso->lbmGetData( i , j-1 ,ZKOFF ) += ( val * mIsoWeight[10] );
- *D::mpIso->lbmGetData( i+1 , j-1 ,ZKOFF ) += ( val * mIsoWeight[11] );
+ *this->mpIso->lbmGetData( i-1 , j-1 ,ZKOFF ) += ( val * mIsoWeight[9] );
+ *this->mpIso->lbmGetData( i , j-1 ,ZKOFF ) += ( val * mIsoWeight[10] );
+ *this->mpIso->lbmGetData( i+1 , j-1 ,ZKOFF ) += ( val * mIsoWeight[11] );
- *D::mpIso->lbmGetData( i-1 , j ,ZKOFF ) += ( val * mIsoWeight[12] );
- *D::mpIso->lbmGetData( i , j ,ZKOFF ) += ( val * mIsoWeight[13] );
- *D::mpIso->lbmGetData( i+1 , j ,ZKOFF ) += ( val * mIsoWeight[14] );
+ *this->mpIso->lbmGetData( i-1 , j ,ZKOFF ) += ( val * mIsoWeight[12] );
+ *this->mpIso->lbmGetData( i , j ,ZKOFF ) += ( val * mIsoWeight[13] );
+ *this->mpIso->lbmGetData( i+1 , j ,ZKOFF ) += ( val * mIsoWeight[14] );
- *D::mpIso->lbmGetData( i-1 , j+1 ,ZKOFF ) += ( val * mIsoWeight[15] );
- *D::mpIso->lbmGetData( i , j+1 ,ZKOFF ) += ( val * mIsoWeight[16] );
- *D::mpIso->lbmGetData( i+1 , j+1 ,ZKOFF ) += ( val * mIsoWeight[17] );
+ *this->mpIso->lbmGetData( i-1 , j+1 ,ZKOFF ) += ( val * mIsoWeight[15] );
+ *this->mpIso->lbmGetData( i , j+1 ,ZKOFF ) += ( val * mIsoWeight[16] );
+ *this->mpIso->lbmGetData( i+1 , j+1 ,ZKOFF ) += ( val * mIsoWeight[17] );
- *D::mpIso->lbmGetData( i-1 , j-1 ,ZKOFF+ZKD1) += ( val * mIsoWeight[18] );
- *D::mpIso->lbmGetData( i , j-1 ,ZKOFF+ZKD1) += ( val * mIsoWeight[19] );
- *D::mpIso->lbmGetData( i+1 , j-1 ,ZKOFF+ZKD1) += ( val * mIsoWeight[20] );
+ *this->mpIso->lbmGetData( i-1 , j-1 ,ZKOFF+ZKD1) += ( val * mIsoWeight[18] );
+ *this->mpIso->lbmGetData( i , j-1 ,ZKOFF+ZKD1) += ( val * mIsoWeight[19] );
+ *this->mpIso->lbmGetData( i+1 , j-1 ,ZKOFF+ZKD1) += ( val * mIsoWeight[20] );
- *D::mpIso->lbmGetData( i-1 , j ,ZKOFF+ZKD1) += ( val * mIsoWeight[21] );
- *D::mpIso->lbmGetData( i , j ,ZKOFF+ZKD1)+= ( val * mIsoWeight[22] );
- *D::mpIso->lbmGetData( i+1 , j ,ZKOFF+ZKD1) += ( val * mIsoWeight[23] );
+ *this->mpIso->lbmGetData( i-1 , j ,ZKOFF+ZKD1) += ( val * mIsoWeight[21] );
+ *this->mpIso->lbmGetData( i , j ,ZKOFF+ZKD1)+= ( val * mIsoWeight[22] );
+ *this->mpIso->lbmGetData( i+1 , j ,ZKOFF+ZKD1) += ( val * mIsoWeight[23] );
- *D::mpIso->lbmGetData( i-1 , j+1 ,ZKOFF+ZKD1) += ( val * mIsoWeight[24] );
- *D::mpIso->lbmGetData( i , j+1 ,ZKOFF+ZKD1) += ( val * mIsoWeight[25] );
- *D::mpIso->lbmGetData( i+1 , j+1 ,ZKOFF+ZKD1) += ( val * mIsoWeight[26] );
+ *this->mpIso->lbmGetData( i-1 , j+1 ,ZKOFF+ZKD1) += ( val * mIsoWeight[24] );
+ *this->mpIso->lbmGetData( i , j+1 ,ZKOFF+ZKD1) += ( val * mIsoWeight[25] );
+ *this->mpIso->lbmGetData( i+1 , j+1 ,ZKOFF+ZKD1) += ( val * mIsoWeight[26] );
}
-#if ELBEEM_PLUGIN!=1
- if(mUseTestdata) {
+#if LBM_INCLUDE_TESTSOLVERS==1
+ /*if(mUseTestdata) {
int border = 1;
for(int k=0;k<mLevel[mMaxRefine].lSizez-1;k++)
for(int j=0;j<mLevel[mMaxRefine].lSizey-1;j++) {
for(int l=0; l<=border; l++) {
- *D::mpIso->lbmGetData( l-1, j,ZKOFF) = *D::mpIso->lbmGetData( border+1, j,ZKOFF);
- *D::mpIso->lbmGetData( mLevel[mMaxRefine].lSizex-l, j,ZKOFF) = *D::mpIso->lbmGetData( mLevel[mMaxRefine].lSizex-border-1, j,ZKOFF);
+ *this->mpIso->lbmGetData( l-1, j,ZKOFF) = *this->mpIso->lbmGetData( border+1, j,ZKOFF);
+ *this->mpIso->lbmGetData( mLevel[mMaxRefine].lSizex-l, j,ZKOFF) = *this->mpIso->lbmGetData( mLevel[mMaxRefine].lSizex-border-1, j,ZKOFF);
}
}
for(int k=0;k<mLevel[mMaxRefine].lSizez-1;k++)
for(int i=-1;i<mLevel[mMaxRefine].lSizex+1;i++) {
for(int l=0; l<=border; l++) {
- *D::mpIso->lbmGetData( i, l-1, ZKOFF) = *D::mpIso->lbmGetData( i, border+1, ZKOFF);
- *D::mpIso->lbmGetData( i, mLevel[mMaxRefine].lSizey-l, ZKOFF) = *D::mpIso->lbmGetData( i, mLevel[mMaxRefine].lSizey-border-1, ZKOFF);
+ *this->mpIso->lbmGetData( i, l-1, ZKOFF) = *this->mpIso->lbmGetData( i, border+1, ZKOFF);
+ *this->mpIso->lbmGetData( i, mLevel[mMaxRefine].lSizey-l, ZKOFF) = *this->mpIso->lbmGetData( i, mLevel[mMaxRefine].lSizey-border-1, ZKOFF);
}
}
- if(D::cDimension == 3) {
+ if(LBMDIM == 3) {
// only for 3D
for(int j=-1;j<mLevel[mMaxRefine].lSizey+1;j++)
for(int i=-1;i<mLevel[mMaxRefine].lSizex+1;i++) {
for(int l=0; l<=border; l++) {
- *D::mpIso->lbmGetData( i,j,l-1 ) = *D::mpIso->lbmGetData( i,j, border+1 );
- *D::mpIso->lbmGetData( i,j,mLevel[mMaxRefine].lSizez-l) = *D::mpIso->lbmGetData( i,j,mLevel[mMaxRefine].lSizez-1-border);
+ *this->mpIso->lbmGetData( i,j,l-1 ) = *this->mpIso->lbmGetData( i,j, border+1 );
+ *this->mpIso->lbmGetData( i,j,mLevel[mMaxRefine].lSizez-l) = *this->mpIso->lbmGetData( i,j,mLevel[mMaxRefine].lSizez-1-border);
}
}
}
- } // testdata
-#endif // ELBEEM_PLUGIN
+ } // testdata */
+#endif // LBM_INCLUDE_TESTSOLVERS==1
// */
// update preview, remove 2d?
- if(D::mOutputSurfacePreview) {
- int pvsx = (int)(D::mPreviewFactor*D::mSizex);
- int pvsy = (int)(D::mPreviewFactor*D::mSizey);
- int pvsz = (int)(D::mPreviewFactor*D::mSizez);
- //float scale = (float)D::mSizex / previewSize;
- LbmFloat scalex = (LbmFloat)D::mSizex/(LbmFloat)pvsx;
- LbmFloat scaley = (LbmFloat)D::mSizey/(LbmFloat)pvsy;
- LbmFloat scalez = (LbmFloat)D::mSizez/(LbmFloat)pvsz;
- for(int k= 0; k< ((D::cDimension==3) ? (pvsz-1):1) ; ++k)
+ if((this->mOutputSurfacePreview)&&(LBMDIM==3)) {
+ int pvsx = (int)(this->mPreviewFactor*this->mSizex);
+ int pvsy = (int)(this->mPreviewFactor*this->mSizey);
+ int pvsz = (int)(this->mPreviewFactor*this->mSizez);
+ //float scale = (float)this->mSizex / previewSize;
+ LbmFloat scalex = (LbmFloat)this->mSizex/(LbmFloat)pvsx;
+ LbmFloat scaley = (LbmFloat)this->mSizey/(LbmFloat)pvsy;
+ LbmFloat scalez = (LbmFloat)this->mSizez/(LbmFloat)pvsz;
+ for(int k= 0; k< (pvsz-1); ++k)
for(int j=0;j< pvsy;j++)
for(int i=0;i< pvsx;i++) {
- *mpPreviewSurface->lbmGetData(i,j,k) = *D::mpIso->lbmGetData( (int)(i*scalex), (int)(j*scaley), (int)(k*scalez) );
+ *mpPreviewSurface->lbmGetData(i,j,k) = *this->mpIso->lbmGetData( (int)(i*scalex), (int)(j*scaley), (int)(k*scalez) );
}
// set borders again...
- for(int k= 0; k< ((D::cDimension == 3) ? (pvsz-1):1) ; ++k) {
+ for(int k= 0; k< (pvsz-1); ++k) {
for(int j=0;j< pvsy;j++) {
- *mpPreviewSurface->lbmGetData(0,j,k) = *D::mpIso->lbmGetData( 0, (int)(j*scaley), (int)(k*scalez) );
- *mpPreviewSurface->lbmGetData(pvsx-1,j,k) = *D::mpIso->lbmGetData( D::mSizex-1, (int)(j*scaley), (int)(k*scalez) );
+ *mpPreviewSurface->lbmGetData(0,j,k) = *this->mpIso->lbmGetData( 0, (int)(j*scaley), (int)(k*scalez) );
+ *mpPreviewSurface->lbmGetData(pvsx-1,j,k) = *this->mpIso->lbmGetData( this->mSizex-1, (int)(j*scaley), (int)(k*scalez) );
}
for(int i=0;i< pvsx;i++) {
- *mpPreviewSurface->lbmGetData(i,0,k) = *D::mpIso->lbmGetData( (int)(i*scalex), 0, (int)(k*scalez) );
- *mpPreviewSurface->lbmGetData(i,pvsy-1,k) = *D::mpIso->lbmGetData( (int)(i*scalex), D::mSizey-1, (int)(k*scalez) );
+ *mpPreviewSurface->lbmGetData(i,0,k) = *this->mpIso->lbmGetData( (int)(i*scalex), 0, (int)(k*scalez) );
+ *mpPreviewSurface->lbmGetData(i,pvsy-1,k) = *this->mpIso->lbmGetData( (int)(i*scalex), this->mSizey-1, (int)(k*scalez) );
}
}
- if(D::cDimension == 3) {
- // only for 3D
+ for(int j=0;j<pvsy;j++)
+ for(int i=0;i<pvsx;i++) {
+ *mpPreviewSurface->lbmGetData(i,j,0) = *this->mpIso->lbmGetData( (int)(i*scalex), (int)(j*scaley) , 0);
+ *mpPreviewSurface->lbmGetData(i,j,pvsz-1) = *this->mpIso->lbmGetData( (int)(i*scalex), (int)(j*scaley) , this->mSizez-1);
+ }
+
+ if(mUseTestdata) {
+ // also remove preview border
+ for(int k= 0; k< (pvsz-1); ++k) {
+ for(int j=0;j< pvsy;j++) {
+ *mpPreviewSurface->lbmGetData(0,j,k) =
+ *mpPreviewSurface->lbmGetData(1,j,k) =
+ *mpPreviewSurface->lbmGetData(2,j,k);
+ *mpPreviewSurface->lbmGetData(pvsx-1,j,k) =
+ *mpPreviewSurface->lbmGetData(pvsx-2,j,k) =
+ *mpPreviewSurface->lbmGetData(pvsx-3,j,k);
+ //0.0;
+ }
+ for(int i=0;i< pvsx;i++) {
+ *mpPreviewSurface->lbmGetData(i,0,k) =
+ *mpPreviewSurface->lbmGetData(i,1,k) =
+ *mpPreviewSurface->lbmGetData(i,2,k);
+ *mpPreviewSurface->lbmGetData(i,pvsy-1,k) =
+ *mpPreviewSurface->lbmGetData(i,pvsy-2,k) =
+ *mpPreviewSurface->lbmGetData(i,pvsy-3,k);
+ //0.0;
+ }
+ }
for(int j=0;j<pvsy;j++)
for(int i=0;i<pvsx;i++) {
- *mpPreviewSurface->lbmGetData(i,j,0) = *D::mpIso->lbmGetData( (int)(i*scalex), (int)(j*scaley) , 0);
- *mpPreviewSurface->lbmGetData(i,j,pvsz-1) = *D::mpIso->lbmGetData( (int)(i*scalex), (int)(j*scaley) , D::mSizez-1);
- }
- } // borders done...
+ *mpPreviewSurface->lbmGetData(i,j,0) =
+ *mpPreviewSurface->lbmGetData(i,j,1) =
+ *mpPreviewSurface->lbmGetData(i,j,2);
+ *mpPreviewSurface->lbmGetData(i,j,pvsz-1) =
+ *mpPreviewSurface->lbmGetData(i,j,pvsz-2) =
+ *mpPreviewSurface->lbmGetData(i,j,pvsz-3);
+ //0.0;
+ }
+ }
}
-#if ELBEEM_PLUGIN!=1
- if(D::mInitDone) {
- if(mpTest->mDebugvalue3<=0.0) handleTestdata();
- }
-#endif // ELBEEM_PLUGIN!=1
// correction
return;
}
/*! calculate speeds of fluid objects (or inflow) */
-template<class D>
-void LbmFsgrSolver<D>::recalculateObjectSpeeds() {
- int numobjs = (int)(D::mpGiObjects->size());
+void LbmFsgrSolver::recalculateObjectSpeeds() {
+ const bool debugRecalc = false;
+ int numobjs = (int)(this->mpGiObjects->size());
// note - (numobjs + 1) is entry for domain settings
+
+ if(debugRecalc) errMsg("recalculateObjectSpeeds","start, #obj:"<<numobjs);
if(numobjs>255-1) {
errFatal("LbmFsgrSolver::recalculateObjectSpeeds","More than 256 objects currently not supported...",SIMWORLD_INITERROR);
return;
}
mObjectSpeeds.resize(numobjs+1);
for(int i=0; i<(int)(numobjs+0); i++) {
- mObjectSpeeds[i] = vec2L(D::mpParam->calculateLattVelocityFromRw( vec2P( (*D::mpGiObjects)[i]->getInitialVelocity() )));
- //errMsg("recalculateObjectSpeeds","id"<<i<<" set to "<< mObjectSpeeds[i]<<", unscaled:"<< (*D::mpGiObjects)[i]->getInitialVelocity() );
+ mObjectSpeeds[i] = vec2L(this->mpParam->calculateLattVelocityFromRw( vec2P( (*this->mpGiObjects)[i]->getInitialVelocity(mSimulationTime) )));
+ if(debugRecalc) errMsg("recalculateObjectSpeeds","id"<<i<<" set to "<< mObjectSpeeds[i]<<", unscaled:"<< (*this->mpGiObjects)[i]->getInitialVelocity(mSimulationTime) );
}
// also reinit part slip values here
mObjectPartslips.resize(numobjs+1);
for(int i=0; i<(int)(numobjs+0); i++) {
- mObjectPartslips[i] = (LbmFloat)(*D::mpGiObjects)[i]->getGeoPartSlipValue();
+ mObjectPartslips[i] = (LbmFloat)(*this->mpGiObjects)[i]->getGeoPartSlipValue();
+ if(debugRecalc) errMsg("recalculateObjectSpeeds","id"<<i<<" parts "<< mObjectPartslips[i] );
}
- //errMsg("GEOIN"," dm set "<<mDomainPartSlipValue);
- mObjectPartslips[numobjs] = mDomainPartSlipValue;
+
+ mObjectPartslips[numobjs] = this->mDomainPartSlipValue;
+ if(debugRecalc) errMsg("recalculateObjectSpeeds","done, domain:"<<mObjectPartslips[numobjs]<<" n"<<numobjs);
}
@@ -217,13 +247,12 @@ void LbmFsgrSolver<D>::recalculateObjectSpeeds() {
/*****************************************************************************/
/*! debug object display */
/*****************************************************************************/
-template<class D>
-vector<ntlGeometryObject*> LbmFsgrSolver<D>::getDebugObjects() {
+vector<ntlGeometryObject*> LbmFsgrSolver::getDebugObjects() {
vector<ntlGeometryObject*> debo;
- if(D::mOutputSurfacePreview) {
+ if(this->mOutputSurfacePreview) {
debo.push_back( mpPreviewSurface );
}
-#if ELBEEM_PLUGIN!=1
+#if LBM_INCLUDE_TESTSOLVERS==1
if(mUseTestdata) {
vector<ntlGeometryObject*> tdebo;
tdebo = mpTest->getDebugObjects();
@@ -238,143 +267,511 @@ vector<ntlGeometryObject*> LbmFsgrSolver<D>::getDebugObjects() {
*****************************************************************************/
/*! init particle positions */
-template<class D>
-int LbmFsgrSolver<D>::initParticles(ParticleTracer *partt) {
-#if ELBEEM_PLUGIN==1
- partt = NULL; // remove warning
-#else // ELBEEM_PLUGIN
+int LbmFsgrSolver::initParticles(ParticleTracer *partt) {
int workSet = mLevel[mMaxRefine].setCurr;
int tries = 0;
int num = 0;
mpParticles=partt;
- //partt->setSimEnd ( ntlVec3Gfx(D::mSizex-1, D::mSizey-1, getForZMax1()) );
- partt->setSimEnd ( ntlVec3Gfx(D::mSizex, D::mSizey, getForZMaxBnd(mMaxRefine)) );
+ partt->setStart( this->mvGeoStart + ntlVec3Gfx(mLevel[mMaxRefine].nodeSize*0.5) );
+ partt->setEnd ( this->mvGeoEnd + ntlVec3Gfx(mLevel[mMaxRefine].nodeSize*0.5) );
+
partt->setSimStart( ntlVec3Gfx(0.0) );
+ partt->setSimEnd ( ntlVec3Gfx(this->mSizex, this->mSizey, getForZMaxBnd(mMaxRefine)) );
while( (num<partt->getNumParticles()) && (tries<100*partt->getNumParticles()) ) {
- double x,y,z;
- x = 0.0+(( (float)(D::mSizex-1) ) * (rand()/(RAND_MAX+1.0)) );
- y = 0.0+(( (float)(D::mSizey-1) ) * (rand()/(RAND_MAX+1.0)) );
- z = 0.0+(( (float) getForZMax1(mMaxRefine) )* (rand()/(RAND_MAX+1.0)) );
- int i = (int)(x-0.5);
- int j = (int)(y-0.5);
- int k = (int)(z-0.5);
- if(D::cDimension==2) {
+ LbmFloat x,y,z;
+ x = 0.0+(( (LbmFloat)(this->mSizex-1) ) * (rand()/(RAND_MAX+1.0)) );
+ y = 0.0+(( (LbmFloat)(this->mSizey-1) ) * (rand()/(RAND_MAX+1.0)) );
+ z = 0.0+(( (LbmFloat) getForZMax1(mMaxRefine) )* (rand()/(RAND_MAX+1.0)) );
+ int i = (int)(x+0.5);
+ int j = (int)(y+0.5);
+ int k = (int)(z+0.5);
+ if(LBMDIM==2) {
k = 0;
z = 0.5; // place in the middle of domain
}
if( TESTFLAG( RFLAG(mMaxRefine, i,j,k, workSet), CFFluid ) ||
- TESTFLAG( RFLAG(mMaxRefine, i,j,k, workSet), CFFluid ) ) { // only fluid cells?
+ TESTFLAG( RFLAG(mMaxRefine, i,j,k, workSet), CFInter ) ) { // only fluid cells?
// in fluid...
partt->addParticle(x,y,z);
+ partt->getLast()->setStatus(PART_IN);
+ partt->getLast()->setType(PART_BUBBLE);
num++;
}
tries++;
}
- debMsgStd("LbmFsgrSolver::initParticles",DM_MSG,"Added "<<num<<" particles ", 10);
+
+
+ // DEBUG TEST
+#if LBM_INCLUDE_TESTSOLVERS==1
+ if(mUseTestdata) {
+ const bool partDebug=false;
+ if(mpTest->mDebugvalue2!=0.0){ errMsg("LbmTestdata"," part init "<<mpTest->mDebugvalue2); }
+ if(mpTest->mDebugvalue2==-12.0){
+ const int lev = mMaxRefine;
+ for(int i=5;i<15;i++) {
+ LbmFloat x,y,z;
+ y = 0.5+(LbmFloat)(i);
+ x = mLevel[lev].lSizex/20.0*10.0;
+ z = mLevel[lev].lSizez/20.0*2.0;
+ partt->addParticle(x,y,z);
+ partt->getLast()->setStatus(PART_IN);
+ partt->getLast()->setType(PART_BUBBLE);
+ partt->getLast()->setSize( (-4.0+(LbmFloat)i)/1.0 );
+ if(partDebug) errMsg("PARTTT","SET "<<PRINT_VEC(x,y,z)<<" p"<<partt->getLast()->getPos() <<" s"<<partt->getLast()->getSize() );
+ }
+ }
+ if(mpTest->mDebugvalue2==-11.0){
+ const int lev = mMaxRefine;
+ for(int i=5;i<15;i++) {
+ LbmFloat x,y,z;
+ y = 10.5+(LbmFloat)(i);
+ x = mLevel[lev].lSizex/20.0*10.0;
+ z = mLevel[lev].lSizez/20.0*40.0;
+ partt->addParticle(x,y,z);
+ partt->getLast()->setStatus(PART_IN);
+ partt->getLast()->setType(PART_DROP);
+ partt->getLast()->setSize( (-4.0+(LbmFloat)i)/1.0 );
+ if(partDebug) errMsg("PARTTT","SET "<<PRINT_VEC(x,y,z)<<" p"<<partt->getLast()->getPos() <<" s"<<partt->getLast()->getSize() );
+ }
+ }
+ if(mpTest->mDebugvalue2==-10.0){
+ const int lev = mMaxRefine;
+ const int sx = mLevel[lev].lSizex;
+ const int sy = mLevel[lev].lSizey;
+ //for(int j=-(int)(sy*0.25);j<-(int)(sy*0.25)+2;++j) { for(int i=-(int)(sx*0.25);i<-(int)(sy*0.25)+2;++i) {
+ //for(int j=-(int)(sy*1.25);j<(int)(2.25*sy);++j) { for(int i=-(int)(sx*1.25);i<(int)(2.25*sx);++i) {
+ for(int j=-(int)(sy*0.5);j<(int)(1.5*sy);++j) { for(int i=-(int)(sx*0.5);i<(int)(1.5*sx);++i) {
+ //for(int j=-(int)(sy*0.2);j<(int)(0.2*sy);++j) { for(int i= (int)(sx*0.5);i<= (int)(0.51*sx);++i) {
+ LbmFloat x,y,z;
+ x = 0.0+(LbmFloat)(i);
+ y = 0.0+(LbmFloat)(j);
+ //z = 0.5+(LbmFloat)(k);
+ z = mLevel[lev].lSizez/20.0*8.0 - 1.0;
+ partt->addParticle(x,y,z);
+ //if( (i>0)&&(i<sx) && (j>0)&&(j<sy) ) { partt->getLast()->setStatus(PART_IN); } else { partt->getLast()->setStatus(PART_OUT); }
+ partt->getLast()->setStatus(PART_IN);
+ partt->getLast()->setType(PART_FLOAT);
+ partt->getLast()->setSize( 15.0 );
+ if(partDebug) errMsg("PARTTT","SET "<<PRINT_VEC(x,y,z)<<" p"<<partt->getLast()->getPos() <<" s"<<partt->getLast()->getSize() );
+ }
+ } }
+ }
+ // DEBUG TEST
+#endif // LBM_INCLUDE_TESTSOLVERS
+
+
+ debMsgStd("LbmFsgrSolver::initParticles",DM_MSG,"Added "<<num<<" particles, genProb:"<<this->mPartGenProb, 10);
if(num != partt->getNumParticles()) return 1;
-#endif // ELBEEM_PLUGIN
return 0;
}
-template<class D>
-void LbmFsgrSolver<D>::advanceParticles(ParticleTracer *partt) {
-#if ELBEEM_PLUGIN==1
- partt = NULL; // remove warning
-#else // ELBEEM_PLUGIN
+void LbmFsgrSolver::advanceParticles(ParticleTracer *partt) {
int workSet = mLevel[mMaxRefine].setCurr;
LbmFloat vx=0.0,vy=0.0,vz=0.0;
LbmFloat rho, df[27]; //feq[27];
- if(mpParticles!=partt) { errMsg("LbmFsgrSolver<D>::advanceParticles","Invalid ParticleTracer..."); }
+ if(mpParticles!=partt) { errMsg("LbmFsgrSolver::advanceParticles","Invalid ParticleTracer..."); }
+#define DEL_PART { \
+ /*errMsg("PIT","DEL AT "<< __LINE__<<" type:"<<p->getType()<<" "); */ \
+ p->setActive( false ); \
+ continue; }
+
+ myTime_t parttstart = getTime();
+ const LbmFloat cellsize = this->mpParam->getCellSize();
+ const LbmFloat timestep = this->mpParam->getTimestep();
+ //const LbmFloat viscAir = 1.79 * 1e-5; // RW2L kin. viscosity, mu
+ const LbmFloat viscWater = 1.0 * 1e-6; // RW2L kin. viscosity, mu
+ const LbmFloat rhoAir = 1.2; // [kg m^-3] RW2L
+ const LbmFloat rhoWater = 1000.0; // RW2L
+ const LbmFloat minDropSize = 0.0005; // [m], = 2mm RW2L
+ const LbmVec velAir(0.); // [m / s]
+
+ const LbmFloat r1 = 0.005; // r max
+ const LbmFloat r2 = 0.0005; // r min
+ const LbmFloat v1 = 9.0; // v max
+ const LbmFloat v2 = 2.0; // v min
+ const LbmVec rwgrav = vec2L( this->mpParam->getGravity(mSimulationTime) );
// TODO use timestep size
+ //bool isIn,isOut,isInZ;
+ //const int cutval = 1+mCutoff/2; // TODO FIXME add half border!
+ //const int cutval = mCutoff/2; // TODO FIXME add half border!
+ //const int cutval = 0; // TODO FIXME add half border!
+ const int cutval = mCutoff; // use full border!?
+ int actCnt=0;
+ if(this->mStepCnt%50==49) { partt->cleanup(); }
for(vector<ParticleObject>::iterator pit= partt->getParticlesBegin();
pit!= partt->getParticlesEnd(); pit++) {
- //errorOut(" pit "<< (*pit).getPos() );
+ //errMsg("PIT"," pit "<< (*pit).getPos()<<" status:"<<convertFlags2String((*pit).getFlags())<<" vel:"<< (*pit).getVel() );
+ //errMsg("PIT"," pit pos:"<< (*pit).getPos()<<" vel:"<< (*pit).getVel()<<" status:"<<convertFlags2String((*pit).getFlags()) <<" " <<partt->getStart()<<" "<<partt->getEnd() );
+ //int flag = (*pit).getFlags();
if( (*pit).getActive()==false ) continue;
int i,j,k;
ParticleObject *p = &(*pit);
+ p->setLifeTime(p->getLifeTime()+1);
// nearest neighbor, particle positions don't include empty bounds
ntlVec3Gfx pos = p->getPos();
i= (int)(pos[0]+0.5);
j= (int)(pos[1]+0.5);
k= (int)(pos[2]+0.5);
- if(D::cDimension==2) {
+ if(LBMDIM==2) {
k = 0;
}
- if( (i<0)||(i>D::mSizex-1)||
- (j<0)||(j>D::mSizey-1)||
- (k<0)||(k>D::mSizez-1) ) {
- p->setActive( false );
- continue;
+ // only testdata handling, all for sws
+#if LBM_INCLUDE_TESTSOLVERS==1
+ if(mUseTestdata) {
+ if(mpTest->mDebugvalue1>0.0){
+ p->setStatus(PART_OUT);
+ mpTest->handleParticle(p, i,j,k); continue;
+ } }
+#endif // LBM_INCLUDE_TESTSOLVERS==1
+
+ if(p->getStatus()&PART_IN) { // IN
+ if( (i<cutval)||(i>this->mSizex-1-cutval)||
+ (j<cutval)||(j>this->mSizey-1-cutval)
+ //||(k<cutval)||(k>this->mSizez-1-cutval)
+ ) {
+ if(!mUseTestdata) { DEL_PART;
+ } else {
+ p->setStatus(PART_OUT);
+ /* del? */ //if((rand()/(RAND_MAX+1.0))<0.5) DEL_PART;
+ }
+ }
+ } else { // OUT rough check
+ // check in again?
+ if( (i>=cutval)&&(i<=this->mSizex-1-cutval)&&
+ (j>=cutval)&&(j<=this->mSizey-1-cutval)
+ //&&(k>=cutval)&&(k<=this->mSizez-1-cutval)
+ ) {
+ p->setStatus(PART_IN);
+ /* del? */ //if((rand()/(RAND_MAX+1.0))<0.5) DEL_PART;
+ }
}
+ //p->setStatus(PART_OUT);// DEBUG always out!
+
+ if(p->getType()==PART_BUBBLE) {
- if(p->getStatus()==0) {
// no interpol
rho = vx = vy = vz = 0.0;
- FORDF0{
- LbmFloat cdf = QCELL(mMaxRefine, i,j,k, workSet, l);
- df[l] = cdf;
- rho += cdf;
- vx += (D::dfDvecX[l]*cdf);
- vy += (D::dfDvecY[l]*cdf);
- vz += (D::dfDvecZ[l]*cdf);
- }
+ if(p->getStatus()&PART_IN) { // IN
+ if(k>=cutval) {
+ if(k>this->mSizez-1-cutval) DEL_PART;
+ FORDF0{
+ LbmFloat cdf = QCELL(mMaxRefine, i,j,k, workSet, l);
+ df[l] = cdf;
+ rho += cdf;
+ vx += (this->dfDvecX[l]*cdf);
+ vy += (this->dfDvecY[l]*cdf);
+ vz += (this->dfDvecZ[l]*cdf);
+ }
- // remove gravity influence
- //FORDF0{ feq[l] = D::getCollideEq(l, rho,vx,vy,vz); }
- //const LbmFloat Qo = D::getLesNoneqTensorCoeff(df,feq);
- //const LbmFloat lesomega = D::getLesOmega(mLevel[mMaxRefine].omega,mLevel[mMaxRefine].lcsmago,Qo);
- const LbmFloat lesomega = mLevel[mMaxRefine].omega; // no les
- vx -= mLevel[mMaxRefine].gravity[0] * lesomega*0.5;
- vy -= mLevel[mMaxRefine].gravity[1] * lesomega*0.5;
- vz -= mLevel[mMaxRefine].gravity[2] * lesomega*0.5;
-
- if( TESTFLAG( RFLAG(mMaxRefine, i,j,k, workSet), CFFluid ) ||
- TESTFLAG( RFLAG(mMaxRefine, i,j,k, workSet), CFInter ) ) {
- // still ok
- } else {
- // out of bounds, deactivate...
- // FIXME make fsgr treatment
- p->setActive( false );
- continue;
- D::mNumParticlesLost++;
+ // remove gravity influence
+ const LbmFloat lesomega = mLevel[mMaxRefine].omega; // no les
+ vx -= mLevel[mMaxRefine].gravity[0] * lesomega*0.5;
+ vy -= mLevel[mMaxRefine].gravity[1] * lesomega*0.5;
+ vz -= mLevel[mMaxRefine].gravity[2] * lesomega*0.5;
+
+ if( RFLAG(mMaxRefine, i,j,k, workSet)&(CFFluid) ) {
+ // still ok
+ } else { // OUT
+ // out of bounds, deactivate...
+ // FIXME make fsgr treatment
+ p->setType( PART_FLOAT ); continue;
+ }
+ } else {
+ // below 3d region, just rise
+ }
+ } else { // OUT
+#if LBM_INCLUDE_TESTSOLVERS==1
+ if(mUseTestdata) { mpTest->handleParticle(p, i,j,k); }
+ else DEL_PART;
+#else // LBM_INCLUDE_TESTSOLVERS==1
+ DEL_PART;
+#endif // LBM_INCLUDE_TESTSOLVERS==1
+ // TODO use x,y vel...?
}
- p->advance( vx,vy,vz );
- // fluid particle
- } else {
- p->setVel( p->getVel() * 0.999 ); // dampen...
- p->addToVel( vec2G(mLevel[mMaxRefine].gravity) );
+ ntlVec3Gfx v = p->getVel(); // dampen...
+ if(mUseTestdata) {
+ // test rise
+ //O vz = p->getVel()[2]-0.5*mLevel[mMaxRefine].gravity[2];
+
+ LbmFloat radius = p->getSize() * minDropSize;
+ LbmVec velPart = vec2L(p->getVel()) *cellsize/timestep; // L2RW, lattice velocity
+ LbmVec velWater = LbmVec(vx,vy,vz) *cellsize/timestep;// L2RW, fluid velocity
+ LbmVec velRel = velWater - velPart;
+ LbmFloat velRelNorm = norm(velRel);
+ // TODO calculate values in lattice units, compute CD?!??!
+ LbmFloat pvolume = rhoAir * 4.0/3.0 * M_PI* radius*radius*radius; // volume: 4/3 pi r^3
+ //const LbmFloat cd =
+
+ LbmVec fb = -rwgrav* pvolume *rhoWater;
+ LbmVec fd = velRel*6.0*M_PI*radius* (1e-3); //viscWater;
+ LbmVec change = (fb+fd) *10.0*timestep *(timestep/cellsize);
+ //LbmVec change = (fb+fd) *timestep / (pvolume*rhoAir) *(timestep/cellsize);
+ //actCnt++; // should be after active test
+ if(actCnt<0) {
+ errMsg("\nPIT","BTEST1 vol="<<pvolume<<" radius="<<radius<<" vn="<<velRelNorm<<" velPart="<<velPart<<" velRel"<<velRel);
+ errMsg("PIT","BTEST2 cellsize="<<cellsize<<" timestep="<<timestep<<" viscW="<<viscWater<<" ss/mb="<<(timestep/(pvolume*rhoAir)));
+ errMsg("PIT","BTEST2 grav="<<rwgrav<<" " );
+ errMsg("PIT","BTEST2 change="<<(change)<<" fb="<<(fb)<<" fd="<<(fd)<<" ");
+ errMsg("PIT","BTEST2 change="<<norm(change)<<" fb="<<norm(fb)<<" fd="<<norm(fd)<<" ");
+#if LOOPTEST==1
+ errMsg("PIT","BTEST2 n="<<n<<" "); // LOOPTEST! DEBUG
+#endif // LOOPTEST==1
+ errMsg("PIT","\n");
+ }
+
+ //v += change;
+ //v += ntlVec3Gfx(vx,vy,vz);
+ LbmVec fd2 = (LbmVec(vx,vy,vz)-vec2L(p->getVel())) * 6.0*M_PI*radius* (1e-3); //viscWater;
+ LbmFloat w = 0.99;
+ vz = (1.0-w)*vz + w*(p->getVel()[2]-0.5*(p->getSize()/5.0)*mLevel[mMaxRefine].gravity[2]);
+ v = ntlVec3Gfx(vx,vy,vz)+vec2G(fd2);
+ }
+ p->setVel( v );
+ //p->setVel( ntlVec3Gfx(vx,vy,vz) );
p->advanceVel();
- //errMsg("NNNPART"," at "<<p->getPos()<<" u="<<p->getVel() );
- if( TESTFLAG( RFLAG(mMaxRefine, i,j,k, workSet), CFEmpty ) ||
- TESTFLAG( RFLAG(mMaxRefine, i,j,k, workSet), CFInter ) ) {
- // still ok
+ // fluid particle
+ }
+
+ // drop handling
+ else if(p->getType()==PART_DROP) {
+ ntlVec3Gfx v = p->getVel(); // dampen...
+
+ if(1) {
+ LbmFloat radius = p->getSize() * minDropSize;
+ LbmVec velPart = vec2L(p->getVel()) *cellsize /timestep; // * cellsize / timestep; // L2RW, lattice velocity
+ LbmVec velRel = velAir - velPart;
+ //LbmVec velRelLat = velRel /cellsize*timestep; // L2RW
+ LbmFloat velRelNorm = norm(velRel);
+ // TODO calculate values in lattice units, compute CD?!??!
+ LbmFloat mb = rhoWater * 4.0/3.0 * M_PI* radius*radius*radius; // mass: 4/3 pi r^3 rho
+ const LbmFloat rw = (r1-radius)/(r1-r2);
+ const LbmFloat rmax = (0.5 + 0.5*rw);
+ const LbmFloat vmax = (v2 + (v1-v2)* (1.0-rw) );
+ const LbmFloat cd = (rmax) * (velRelNorm)/(vmax);
+
+ LbmVec fg = rwgrav * mb;// * (1.0-rhoAir/rhoWater);
+ LbmVec fd = velRel* velRelNorm* cd*M_PI *rhoAir *0.5 *radius*radius;
+ LbmVec change = (fg+ fd ) *timestep / mb *(timestep/cellsize);
+
+ //actCnt++; // should be after active test
+ if(actCnt<0) {
+ errMsg("\nPIT","NTEST1 mb="<<mb<<" radius="<<radius<<" vn="<<velRelNorm<<" velPart="<<velPart<<" velRel"<<velRel<<" pgetVel="<<p->getVel() );
+ //errMsg("PIT","NTEST2 cellsize="<<cellsize<<" timestep="<<timestep<<" viscAir="<<viscAir<<" ss/mb="<<(timestep/mb));
+ //errMsg("PIT","NTEST2 grav="<<rwgrav<<" mb="<<mb<<" "<<" cd="<<cd );
+ //errMsg("PIT","NTEST2 change="<<norm(change)<<" fg="<<norm(fg)<<" fd="<<norm(fd)<<" ");
+ }
+
+ v += vec2G(change);
+ p->setVel(v);
+ // NEW
} else {
- // out of bounds, deactivate...
- // FIXME make fsgr treatment
- p->setActive( false );
- continue;
- D::mNumParticlesLost++;
+ p->setVel( v * 0.999 ); // dampen...
+ p->setVel( v ); // DEBUG!
+ p->addToVel( vec2G(mLevel[mMaxRefine].gravity) );\
+ } // OLD
+ p->advanceVel();
+
+ if(p->getStatus()&PART_IN) { // IN
+ if(k<cutval) { DEL_PART; continue; }
+ if(k<=this->mSizez-1-cutval){
+ //if( RFLAG(mMaxRefine, i,j,k, workSet)& (CFEmpty|CFInter)) {
+ if( RFLAG(mMaxRefine, i,j,k, workSet)& (CFEmpty)) {
+ // still ok
+ } else if( RFLAG(mMaxRefine, i,j,k, workSet) & (CFFluid|CFInter) ){
+ // FIXME make fsgr treatment
+ if(p->getLifeTime()>50) {
+ p->setType( PART_FLOAT ); continue;
+ } else DEL_PART;
+ } else {
+ DEL_PART;
+ this->mNumParticlesLost++;
+ }
+ }
+ } else { // OUT
+#if LBM_INCLUDE_TESTSOLVERS==1
+ if(mUseTestdata) { mpTest->handleParticle(p, i,j,k); }
+ else{ DEL_PART; }
+#else // LBM_INCLUDE_TESTSOLVERS==1
+ { DEL_PART; }
+#endif // LBM_INCLUDE_TESTSOLVERS==1
}
+
} // air particle
+
+ // inter particle
+ else if(p->getType()==PART_INTER) {
+ if(p->getStatus()&PART_IN) { // IN
+ if((k<cutval)||(k>this->mSizez-1-cutval)) {
+ // undecided particle above or below... remove?
+ DEL_PART;
+ }
+
+ if( TESTFLAG( RFLAG(mMaxRefine, i,j,k, workSet), CFInter ) ) {
+ // still ok
+ } else if( TESTFLAG( RFLAG(mMaxRefine, i,j,k, workSet), CFFluid ) ) {
+ //errMsg("PIT","NEWBUB pit "<< (*pit).getPos()<<" status:"<<convertFlags2String((*pit).getFlags()) );
+
+ //p->setType( PART_BUBBLE ); continue;
+ // currently bubbles off! DEBUG!
+ DEL_PART; // DEBUG bubbles off for siggraph
+ } else if( TESTFLAG( RFLAG(mMaxRefine, i,j,k, workSet), CFEmpty ) ) {
+ //errMsg("PIT","NEWDROP pit "<< (*pit).getPos()<<" status:"<<convertFlags2String((*pit).getFlags()) );
+ //? if(p->getLifeTime()>50) {
+ // only use drops that really flew for a while...?
+ //? } else DEL_PART;
+ //if( (i<=cutval)||(i>=this->mSizex-1-cutval)||
+ //(j<=cutval)||(j>=this->mSizey-1-cutval)) {
+ //} else
+ //if(p->getLifeTime()>10) {
+ p->setType( PART_DROP ); continue;
+ //} else DEL_PART;
+
+ }
+ } else { // OUT
+ // undecided particle outside... remove?
+ DEL_PART;
+ }
+ }
+
+ // float particle
+ else if(p->getType()==PART_FLOAT) {
+ // test - delte on boundary!?
+ //if( (i<=cutval)||(i>=this->mSizex-1-cutval)|| (j<=cutval)||(j>=this->mSizey-1-cutval)) { DEL_PART; } // DEBUG TEST
+
+ LbmFloat prob = 1.0;
+#if LBM_INCLUDE_TESTSOLVERS==1
+ // vanishing
+ prob = (rand()/(RAND_MAX+1.0));
+ if((mUseTestdata)&&(k>mpTest->mFluidHeight)) {
+ LbmFloat fac = (LbmFloat)(k-mpTest->mFluidHeight)/(LbmFloat)(10*(mLevel[mMaxRefine].lSizez-mpTest->mFluidHeight));
+ prob /= fac; // TODO test? errMsg("T","T "<<prob<<" "<<fac);
+ }
+ if(prob<mLevel[mMaxRefine].timestep*0.1) DEL_PART;
+#else // LBM_INCLUDE_TESTSOLVERS==1
+#endif // LBM_INCLUDE_TESTSOLVERS==1
+
+ if(p->getStatus()&PART_IN) { // IN
+ if((k<cutval)||(k>this->mSizez-1-cutval)) DEL_PART;
+ //ntlVec3Gfx v = getVelocityAt(i,j,k);
+ rho = vx = vy = vz = 0.0;
+
+ //const int DEPTH_AVG=11; // TODO how much!?
+ const int DEPTH_AVG=7; // TODO how much!?
+ int ccnt=0;
+ for(int kk=1;kk<DEPTH_AVG;kk+=2) {
+ //for(int kk=1;kk<DEPTH_AVG;kk+=1) {
+ if((k-kk)<1) continue;
+ if(RFLAG(mMaxRefine, i,j,k, workSet)&(CFFluid|CFInter)) {} else continue;
+ ccnt++;
+ FORDF0{
+ LbmFloat cdf = QCELL(mMaxRefine, i,j,k-kk, workSet, l);
+ df[l] = cdf;
+ //rho += cdf;
+ vx += (this->dfDvecX[l]*cdf);
+ vy += (this->dfDvecY[l]*cdf);
+ vz += (this->dfDvecZ[l]*cdf);
+ }
+ }
+ if(ccnt) {
+ vx /=(LbmFloat)(ccnt * 1.0); // half xy speed! value2
+ vy /=(LbmFloat)(ccnt * 1.0);
+ vz /=(LbmFloat)(ccnt); }
+ // forced vanishing
+ if(k>this->mSizez*3/4) { if(prob<3.0*mLevel[mMaxRefine].timestep*0.1) DEL_PART;}
+
+ if( TESTFLAG( RFLAG(mMaxRefine, i,j,k, workSet), CFFluid ) ) {
+ if((1) && (k<this->mSizez-3) &&
+ (
+ TESTFLAG( RFLAG(mMaxRefine, i,j,k+1, workSet), CFInter ) ||
+ TESTFLAG( RFLAG(mMaxRefine, i,j,k+2, workSet), CFInter ) )
+ ) {
+ vz = p->getVel()[2]-0.5*mLevel[mMaxRefine].gravity[2];
+ if(vz<0.0) vz=0.0;
+ } else DEL_PART;
+ } else if( TESTFLAG( RFLAG(mMaxRefine, i,j,k, workSet), CFInter ) ) {
+ // keep in interface , one grid cell offset is added in part. gen
+ }
+ // check if above inter, remove otherwise
+ else if((1) && (k>2) && (
+ TESTFLAG( RFLAG(mMaxRefine, i,j,k-1, workSet), CFInter ) ||
+ TESTFLAG( RFLAG(mMaxRefine, i,j,k-2, workSet), CFInter ) )
+ ) {
+ vz = p->getVel()[2]+0.5*mLevel[mMaxRefine].gravity[2];
+ if(vz>0.0) vz=0.0;
+ } else DEL_PART; // */
+ /*
+ // move down from empty
+ else if( TESTFLAG( RFLAG(mMaxRefine, i,j,k, workSet), CFEmpty ) ) {
+ vz = p->getVel()[2]+0.5*mLevel[mMaxRefine].gravity[2];
+ if(vz>0.0) vz=0.0;
+ //DEL_PART; // ????
+ } else { DEL_PART; } // */
+ //vz = 0.0; // DEBUG
+ ntlVec3Gfx v(vx,vy,vz);
+ p->setVel( vec2G(v) ); //?
+ //p->setVel( vec2G(v)*0.75 + p->getVel()*0.25 ); //?
+ p->advanceVel();
+ //errMsg("PIT","IN pit "<< (*pit).getPos()<<" status:"<<convertFlags2String((*pit).getFlags()) );
+ } else {
+#if LBM_INCLUDE_TESTSOLVERS==1
+ if(mUseTestdata) { mpTest->handleParticle(p, i,j,k); }
+ else DEL_PART;
+#else // LBM_INCLUDE_TESTSOLVERS==1
+ DEL_PART;
+#endif // LBM_INCLUDE_TESTSOLVERS==1
+ //errMsg("PIT","OUT pit "<< (*pit).getPos()<<" status:"<<convertFlags2String((*pit).getFlags()) );
+ }
+ }
+
+ // unknown particle type
+ else {
+ errMsg("LbmFsgrSolver::advanceParticles","PIT pit invalid type!? "<<p->getStatus() );
+ }
}
-#endif // ELBEEM_PLUGIN
+ myTime_t parttend = getTime();
+ debMsgStd("LbmFsgrSolver::advanceParticles",DM_MSG,"Time for particle update:"<< getTimeString(parttend-parttstart)<<" "<<partt->getNumParticles() , 10 );
}
+void LbmFsgrSolver::notifySolverOfDump(int frameNr,char *frameNrStr,string outfilename) {
+ // debug - raw dump of ffrac values
+ if(getenv("ELBEEM_RAWDEBUGDUMP")) {
+ std::ostringstream name;
+ //name <<"fill_" << this->mStepCnt <<".dump";
+ name << outfilename<< frameNrStr <<".dump";
+ FILE *file = fopen(name.str().c_str(),"w");
+ if(file) {
+
+ for(int k= getForZMinBnd(); k< getForZMaxBnd(mMaxRefine); ++k) {
+ for(int j=0;j<mLevel[mMaxRefine].lSizey-0;j++) {
+ for(int i=0;i<mLevel[mMaxRefine].lSizex-0;i++) {
+ float val = QCELL(mMaxRefine,i,j,k, mLevel[mMaxRefine].setCurr,dFfrac);
+ //fwrite( &val, sizeof(val), 1, file); // binary
+ fprintf(file, "%f ",val); // text
+ //errMsg("W", PRINT_IJK<<" val:"<<val);
+ }
+ fprintf(file, "\n"); // text
+ }
+ fprintf(file, "\n"); // text
+ }
+ fclose(file);
+
+ } // file
+ } // */
+}
/*****************************************************************************/
/*! internal quick print function (for debugging) */
/*****************************************************************************/
-template<class D>
void
-LbmFsgrSolver<D>::printLbmCell(int level, int i, int j, int k, int set) {
+LbmFsgrSolver::printLbmCell(int level, int i, int j, int k, int set) {
stdCellId *newcid = new stdCellId;
newcid->level = level;
newcid->x = i;
@@ -385,15 +782,14 @@ LbmFsgrSolver<D>::printLbmCell(int level, int i, int j, int k, int set) {
debugPrintNodeInfo( newcid, set );
delete newcid;
}
-template<class D>
void
-LbmFsgrSolver<D>::debugMarkCellCall(int level, int vi,int vj,int vk) {
+LbmFsgrSolver::debugMarkCellCall(int level, int vi,int vj,int vk) {
stdCellId *newcid = new stdCellId;
newcid->level = level;
newcid->x = vi;
newcid->y = vj;
newcid->z = vk;
- addCellToMarkedList( newcid );
+ this->addCellToMarkedList( newcid );
}
@@ -414,9 +810,8 @@ extern int guiRoiMaxLev, guiRoiMinLev;
#define CID_EY (int)( (mLevel[cid->level].lSizey-1) * guiRoiEY )
#define CID_EZ (int)( (mLevel[cid->level].lSizez-1) * guiRoiEZ )
-template<class D>
CellIdentifierInterface*
-LbmFsgrSolver<D>::getFirstCell( ) {
+LbmFsgrSolver::getFirstCell( ) {
int level = mMaxRefine;
#if LBMDIM==3
@@ -434,17 +829,14 @@ LbmFsgrSolver<D>::getFirstCell( ) {
return cid;
}
-template<class D>
-typename LbmFsgrSolver<D>::stdCellId*
-LbmFsgrSolver<D>::convertBaseCidToStdCid( CellIdentifierInterface* basecid) {
+LbmFsgrSolver::stdCellId*
+LbmFsgrSolver::convertBaseCidToStdCid( CellIdentifierInterface* basecid) {
//stdCellId *cid = dynamic_cast<stdCellId*>( basecid );
stdCellId *cid = (stdCellId*)( basecid );
return cid;
}
-template<class D>
-void
-LbmFsgrSolver<D>::advanceCell( CellIdentifierInterface* basecid) {
+void LbmFsgrSolver::advanceCell( CellIdentifierInterface* basecid) {
stdCellId *cid = convertBaseCidToStdCid(basecid);
if(cid->getEnd()) return;
@@ -467,39 +859,32 @@ LbmFsgrSolver<D>::advanceCell( CellIdentifierInterface* basecid) {
//debugOut(" ADa "<<cid->x<<","<<cid->y<<","<<cid->z<<" e"<<cid->getEnd(), 10);
}
-template<class D>
-bool
-LbmFsgrSolver<D>::noEndCell( CellIdentifierInterface* basecid) {
+bool LbmFsgrSolver::noEndCell( CellIdentifierInterface* basecid) {
stdCellId *cid = convertBaseCidToStdCid(basecid);
return (!cid->getEnd());
}
-template<class D>
-void
-LbmFsgrSolver<D>::deleteCellIterator( CellIdentifierInterface** cid ) {
+void LbmFsgrSolver::deleteCellIterator( CellIdentifierInterface** cid ) {
delete *cid;
*cid = NULL;
}
-template<class D>
-CellIdentifierInterface*
-LbmFsgrSolver<D>::getCellAt( ntlVec3Gfx pos ) {
+CellIdentifierInterface* LbmFsgrSolver::getCellAt( ntlVec3Gfx pos ) {
//int cellok = false;
- pos -= (D::mvGeoStart);
+ pos -= (this->mvGeoStart);
LbmFloat mmaxsize = mLevel[mMaxRefine].nodeSize;
for(int level=mMaxRefine; level>=0; level--) { // finest first
//for(int level=0; level<=mMaxRefine; level++) { // coarsest first
LbmFloat nsize = mLevel[level].nodeSize;
int x,y,z;
- //LbmFloat nsize = getCellSize(NULL)[0]*2.0;
- x = (int)((pos[0]-0.5*mmaxsize) / nsize );
- y = (int)((pos[1]-0.5*mmaxsize) / nsize );
- z = (int)((pos[2]-0.5*mmaxsize) / nsize );
- if(D::cDimension==2) z = 0;
+ // CHECK +- maxsize?
+ x = (int)((pos[0]+0.5*mmaxsize) / nsize );
+ y = (int)((pos[1]+0.5*mmaxsize) / nsize );
+ z = (int)((pos[2]+0.5*mmaxsize) / nsize );
+ if(LBMDIM==2) z = 0;
// double check...
- //int level = mMaxRefine;
if(x<0) continue;
if(y<0) continue;
if(z<0) continue;
@@ -518,7 +903,7 @@ LbmFsgrSolver<D>::getCellAt( ntlVec3Gfx pos ) {
newcid->x = x;
newcid->y = y;
newcid->z = z;
- //errMsg("cellAt",D::mName<<" "<<pos<<" l"<<level<<":"<<x<<","<<y<<","<<z<<" "<<convertCellFlagType2String(RFLAG(level, x,y,z, mLevel[level].setCurr)) );
+ //errMsg("cellAt",this->mName<<" "<<pos<<" l"<<level<<":"<<x<<","<<y<<","<<z<<" "<<convertCellFlagType2String(RFLAG(level, x,y,z, mLevel[level].setCurr)) );
return newcid;
}
@@ -528,60 +913,50 @@ LbmFsgrSolver<D>::getCellAt( ntlVec3Gfx pos ) {
// INFO functions
-template<class D>
-int
-LbmFsgrSolver<D>::getCellSet ( CellIdentifierInterface* basecid) {
+int LbmFsgrSolver::getCellSet ( CellIdentifierInterface* basecid) {
stdCellId *cid = convertBaseCidToStdCid(basecid);
return mLevel[cid->level].setCurr;
//return mLevel[cid->level].setOther;
}
-template<class D>
-int
-LbmFsgrSolver<D>::getCellLevel ( CellIdentifierInterface* basecid) {
+int LbmFsgrSolver::getCellLevel ( CellIdentifierInterface* basecid) {
stdCellId *cid = convertBaseCidToStdCid(basecid);
return cid->level;
}
-template<class D>
-ntlVec3Gfx
-LbmFsgrSolver<D>::getCellOrigin ( CellIdentifierInterface* basecid) {
+ntlVec3Gfx LbmFsgrSolver::getCellOrigin ( CellIdentifierInterface* basecid) {
ntlVec3Gfx ret;
stdCellId *cid = convertBaseCidToStdCid(basecid);
ntlVec3Gfx cs( mLevel[cid->level].nodeSize );
- if(D::cDimension==2) { cs[2] = 0.0; }
+ if(LBMDIM==2) { cs[2] = 0.0; }
- if(D::cDimension==2) {
- ret =(D::mvGeoStart -(cs*0.5) + ntlVec3Gfx( cid->x *cs[0], cid->y *cs[1], (D::mvGeoEnd[2]-D::mvGeoStart[2])*0.5 )
+ if(LBMDIM==2) {
+ ret =(this->mvGeoStart + ntlVec3Gfx( cid->x *cs[0], cid->y *cs[1], (this->mvGeoEnd[2]-this->mvGeoStart[2])*0.5 )
+ ntlVec3Gfx(0.0,0.0,cs[1]*-0.25)*cid->level )
+getCellSize(basecid);
} else {
- ret =(D::mvGeoStart -(cs*0.5) + ntlVec3Gfx( cid->x *cs[0], cid->y *cs[1], cid->z *cs[2] ))
+ ret =(this->mvGeoStart + ntlVec3Gfx( cid->x *cs[0], cid->y *cs[1], cid->z *cs[2] ))
+getCellSize(basecid);
}
return (ret);
}
-template<class D>
-ntlVec3Gfx
-LbmFsgrSolver<D>::getCellSize ( CellIdentifierInterface* basecid) {
+ntlVec3Gfx LbmFsgrSolver::getCellSize ( CellIdentifierInterface* basecid) {
// return half size
stdCellId *cid = convertBaseCidToStdCid(basecid);
ntlVec3Gfx retvec( mLevel[cid->level].nodeSize * 0.5 );
// 2d display as rectangles
- if(D::cDimension==2) { retvec[2] = 0.0; }
+ if(LBMDIM==2) { retvec[2] = 0.0; }
return (retvec);
}
-template<class D>
-LbmFloat
-LbmFsgrSolver<D>::getCellDensity ( CellIdentifierInterface* basecid,int set) {
+LbmFloat LbmFsgrSolver::getCellDensity ( CellIdentifierInterface* basecid,int set) {
stdCellId *cid = convertBaseCidToStdCid(basecid);
LbmFloat rho = 0.0;
//FORDF0 { rho += QCELL(cid->level, cid->x,cid->y,cid->z, set, l); } // ORG
- //return ((rho-1.0) * mLevel[cid->level].simCellSize / mLevel[cid->level].stepsize) +1.0; // ORG
+ //return ((rho-1.0) * mLevel[cid->level].simCellSize / mLevel[cid->level].timestep) +1.0; // ORG
if(RFLAG(cid->level, cid->x,cid->y,cid->z, set)&CFInter) { // test
LbmFloat ux,uy,uz;
ux=uy=uz= 0.0;
@@ -589,87 +964,133 @@ LbmFsgrSolver<D>::getCellDensity ( CellIdentifierInterface* basecid,int set) {
LbmFloat df[27], feqOld[27];
FORDF0 {
rho += QCELL(lev, cid->x,cid->y,cid->z, set, l);
- ux += D::dfDvecX[l]* QCELL(lev, cid->x,cid->y,cid->z, set, l);
- uy += D::dfDvecY[l]* QCELL(lev, cid->x,cid->y,cid->z, set, l);
- uz += D::dfDvecZ[l]* QCELL(lev, cid->x,cid->y,cid->z, set, l);
+ ux += this->dfDvecX[l]* QCELL(lev, cid->x,cid->y,cid->z, set, l);
+ uy += this->dfDvecY[l]* QCELL(lev, cid->x,cid->y,cid->z, set, l);
+ uz += this->dfDvecZ[l]* QCELL(lev, cid->x,cid->y,cid->z, set, l);
df[l] = QCELL(lev, cid->x,cid->y,cid->z, set, l);
}
FORDF0 {
- feqOld[l] = D::getCollideEq(l, rho,ux,uy,uz);
+ feqOld[l] = getCollideEq(l, rho,ux,uy,uz);
}
- const LbmFloat Qo = D::getLesNoneqTensorCoeff(df,feqOld);
- //const LbmFloat modOmega = D::getLesOmega(mLevel[lev].omega, mLevel[lev].lcsmago,Qo);
+ // debugging mods
+ //const LbmFloat Qo = this->getLesNoneqTensorCoeff(df,feqOld);
+ //const LbmFloat modOmega = this->getLesOmega(mLevel[lev].omega, mLevel[lev].lcsmago,Qo);
//rho = (2.0-modOmega) *25.0;
- rho = Qo*100.0;
+ //rho = Qo*100.0;
//if(cid->x==24){ errMsg("MODOMT"," at "<<PRINT_VEC(cid->x,cid->y,cid->z)<<" = "<<rho<<" "<<Qo); }
//else{ rho=0.0; }
} // test
return rho; // test
}
-template<class D>
-LbmVec
-LbmFsgrSolver<D>::getCellVelocity ( CellIdentifierInterface* basecid,int set) {
+LbmVec LbmFsgrSolver::getCellVelocity ( CellIdentifierInterface* basecid,int set) {
stdCellId *cid = convertBaseCidToStdCid(basecid);
+ // skip non-fluid cells
+ if(RFLAG(cid->level, cid->x,cid->y,cid->z, set)&(CFFluid|CFInter)) {
+ // ok go on...
+ } else {
+ return LbmVec(0.0);
+ }
+
LbmFloat ux,uy,uz;
ux=uy=uz= 0.0;
FORDF0 {
- ux += D::dfDvecX[l]* QCELL(cid->level, cid->x,cid->y,cid->z, set, l);
- uy += D::dfDvecY[l]* QCELL(cid->level, cid->x,cid->y,cid->z, set, l);
- uz += D::dfDvecZ[l]* QCELL(cid->level, cid->x,cid->y,cid->z, set, l);
+ ux += this->dfDvecX[l]* QCELL(cid->level, cid->x,cid->y,cid->z, set, l);
+ uy += this->dfDvecY[l]* QCELL(cid->level, cid->x,cid->y,cid->z, set, l);
+ uz += this->dfDvecZ[l]* QCELL(cid->level, cid->x,cid->y,cid->z, set, l);
}
LbmVec vel(ux,uy,uz);
// TODO fix...
- return (vel * mLevel[cid->level].simCellSize / mLevel[cid->level].stepsize * D::mDebugVelScale); // normal
+ return (vel * mLevel[cid->level].simCellSize / mLevel[cid->level].timestep * this->mDebugVelScale); // normal
}
-template<class D>
-LbmFloat
-LbmFsgrSolver<D>::getCellDf( CellIdentifierInterface* basecid,int set, int dir) {
+LbmFloat LbmFsgrSolver::getCellDf( CellIdentifierInterface* basecid,int set, int dir) {
stdCellId *cid = convertBaseCidToStdCid(basecid);
return QCELL(cid->level, cid->x,cid->y,cid->z, set, dir);
}
-template<class D>
-LbmFloat
-LbmFsgrSolver<D>::getCellMass( CellIdentifierInterface* basecid,int set) {
+LbmFloat LbmFsgrSolver::getCellMass( CellIdentifierInterface* basecid,int set) {
stdCellId *cid = convertBaseCidToStdCid(basecid);
return QCELL(cid->level, cid->x,cid->y,cid->z, set, dMass);
}
-template<class D>
-LbmFloat
-LbmFsgrSolver<D>::getCellFill( CellIdentifierInterface* basecid,int set) {
+LbmFloat LbmFsgrSolver::getCellFill( CellIdentifierInterface* basecid,int set) {
stdCellId *cid = convertBaseCidToStdCid(basecid);
if(RFLAG(cid->level, cid->x,cid->y,cid->z, set)&CFInter) return QCELL(cid->level, cid->x,cid->y,cid->z, set, dFfrac);
if(RFLAG(cid->level, cid->x,cid->y,cid->z, set)&CFFluid) return 1.0;
return 0.0;
//return QCELL(cid->level, cid->x,cid->y,cid->z, set, dFfrac);
}
-template<class D>
-CellFlagType
-LbmFsgrSolver<D>::getCellFlag( CellIdentifierInterface* basecid,int set) {
+CellFlagType LbmFsgrSolver::getCellFlag( CellIdentifierInterface* basecid,int set) {
stdCellId *cid = convertBaseCidToStdCid(basecid);
return RFLAG(cid->level, cid->x,cid->y,cid->z, set);
}
-template<class D>
-LbmFloat
-LbmFsgrSolver<D>::getEquilDf( int l ) {
- return D::dfEquil[l];
+LbmFloat LbmFsgrSolver::getEquilDf( int l ) {
+ return this->dfEquil[l];
}
-template<class D>
-int
-LbmFsgrSolver<D>::getDfNum( ) {
- return D::cDfNum;
+
+ntlVec3Gfx LbmFsgrSolver::getVelocityAt (float xp, float yp, float zp) {
+ ntlVec3Gfx avgvel(0.0);
+ LbmFloat avgnum = 0.;
+
+ // taken from getCellAt!
+ const int level = mMaxRefine;
+ const int workSet = mLevel[level].setCurr;
+ LbmFloat nsize = mLevel[level].nodeSize;
+ const int x = (int)((-this->mvGeoStart[0]+xp-0.5*nsize) / nsize );
+ const int y = (int)((-this->mvGeoStart[1]+yp-0.5*nsize) / nsize );
+ int z = (int)((-this->mvGeoStart[2]+zp-0.5*nsize) / nsize );
+ if(LBMDIM==2) z=0;
+ //errMsg("DUMPVEL","p"<<PRINT_VEC(xp,yp,zp)<<" at "<<PRINT_VEC(x,y,z)<<" max"<<PRINT_VEC(mLevel[level].lSizex,mLevel[level].lSizey,mLevel[level].lSizez) );
+
+ // return fluid/if/border cells
+ // search neighborhood, do smoothing
+ FORDF0{
+ int i=x+this->dfVecX[l];
+ int j=y+this->dfVecY[l];
+ int k=z+this->dfVecZ[l];
+
+ if( (i<0) || (j<0) || (k<0)
+ || (i>=mLevel[level].lSizex)
+ || (j>=mLevel[level].lSizey)
+ || (k>=mLevel[level].lSizez) ) continue;
+
+ if( (RFLAG(level, i,j,k, mLevel[level].setCurr)&(CFFluid|CFInter)) ) {
+ ntlVec3Gfx vel(0.0);
+ LbmFloat *ccel = RACPNT(level, i,j,k ,workSet); // omp
+ for(int n=1; n<this->cDfNum; n++) {
+ vel[0] += (this->dfDvecX[n]*RAC(ccel,n));
+ vel[1] += (this->dfDvecY[n]*RAC(ccel,n));
+ vel[2] += (this->dfDvecZ[n]*RAC(ccel,n));
+ }
+
+ avgvel += vel;
+ avgnum += 1.0;
+ if(l==0) { // center slightly more weight
+ avgvel += vel; avgnum += 1.0;
+ }
+ } // */
+ }
+
+ if(avgnum>0.) {
+ ntlVec3Gfx retv = avgvel / avgnum;
+ retv *= nsize/mLevel[level].timestep;
+ // scale for current animation settings (frame time)
+ retv *= mpParam->getCurrentAniFrameTime();
+ //errMsg("DUMPVEL","t"<<mSimulationTime<<" at "<<PRINT_VEC(xp,yp,zp)<<" ret:"<<retv<<", avgv:"<<avgvel<<" n"<<avgnum<<" nsize"<<nsize<<" ts"<<mLevel[level].timestep<<" fr"<<mpParam->getCurrentAniFrameTime() );
+ return retv;
+ }
+ // no cells here...?
+ //errMsg("DUMPVEL"," at "<<PRINT_VEC(xp,yp,zp)<<" v"<<avgvel<<" n"<<avgnum<<" no vel !?");
+ return ntlVec3Gfx(0.);
}
#if LBM_USE_GUI==1
//! show simulation info (implement SimulationObject pure virtual func)
-template<class D>
void
-LbmFsgrSolver<D>::debugDisplay(fluidDispSettings *set){
- //lbmDebugDisplay< LbmFsgrSolver<D> >( set, this );
+LbmFsgrSolver::debugDisplay(int set){
+ //lbmDebugDisplay< LbmFsgrSolver >( set, this );
lbmDebugDisplay( set );
}
#endif
@@ -680,8 +1101,7 @@ LbmFsgrSolver<D>::debugDisplay(fluidDispSettings *set){
#if FSGR_STRICT_DEBUG==1
#define STRICT_EXIT *((int *)0)=0;
-template<class D>
-int LbmFsgrSolver<D>::debLBMGI(int level, int ii,int ij,int ik, int is) {
+int LbmFsgrSolver::debLBMGI(int level, int ii,int ij,int ik, int is) {
if(level < 0){ errMsg("LbmStrict::debLBMGI"," invLev- l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; }
if(level > mMaxRefine){ errMsg("LbmStrict::debLBMGI"," invLev+ l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; }
@@ -696,28 +1116,24 @@ int LbmFsgrSolver<D>::debLBMGI(int level, int ii,int ij,int ik, int is) {
return _LBMGI(level, ii,ij,ik, is);
};
-template<class D>
-CellFlagType& LbmFsgrSolver<D>::debRFLAG(int level, int xx,int yy,int zz,int set){
+CellFlagType& LbmFsgrSolver::debRFLAG(int level, int xx,int yy,int zz,int set){
return _RFLAG(level, xx,yy,zz,set);
};
-template<class D>
-CellFlagType& LbmFsgrSolver<D>::debRFLAG_NB(int level, int xx,int yy,int zz,int set, int dir) {
+CellFlagType& LbmFsgrSolver::debRFLAG_NB(int level, int xx,int yy,int zz,int set, int dir) {
if(dir<0) { errMsg("LbmStrict"," invD- l"<<level<<"|"<<xx<<","<<yy<<","<<zz<<" s"<<set<<" d"<<dir); STRICT_EXIT; }
// warning might access all spatial nbs
- if(dir>D::cDirNum){ errMsg("LbmStrict"," invD+ l"<<level<<"|"<<xx<<","<<yy<<","<<zz<<" s"<<set<<" d"<<dir); STRICT_EXIT; }
+ if(dir>this->cDirNum){ errMsg("LbmStrict"," invD+ l"<<level<<"|"<<xx<<","<<yy<<","<<zz<<" s"<<set<<" d"<<dir); STRICT_EXIT; }
return _RFLAG_NB(level, xx,yy,zz,set, dir);
};
-template<class D>
-CellFlagType& LbmFsgrSolver<D>::debRFLAG_NBINV(int level, int xx,int yy,int zz,int set, int dir) {
+CellFlagType& LbmFsgrSolver::debRFLAG_NBINV(int level, int xx,int yy,int zz,int set, int dir) {
if(dir<0) { errMsg("LbmStrict"," invD- l"<<level<<"|"<<xx<<","<<yy<<","<<zz<<" s"<<set<<" d"<<dir); STRICT_EXIT; }
- if(dir>D::cDirNum){ errMsg("LbmStrict"," invD+ l"<<level<<"|"<<xx<<","<<yy<<","<<zz<<" s"<<set<<" d"<<dir); STRICT_EXIT; }
+ if(dir>this->cDirNum){ errMsg("LbmStrict"," invD+ l"<<level<<"|"<<xx<<","<<yy<<","<<zz<<" s"<<set<<" d"<<dir); STRICT_EXIT; }
return _RFLAG_NBINV(level, xx,yy,zz,set, dir);
};
-template<class D>
-int LbmFsgrSolver<D>::debLBMQI(int level, int ii,int ij,int ik, int is, int l) {
+int LbmFsgrSolver::debLBMQI(int level, int ii,int ij,int ik, int is, int l) {
if(level < 0){ errMsg("LbmStrict::debLBMQI"," invLev- l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; }
if(level > mMaxRefine){ errMsg("LbmStrict::debLBMQI"," invLev+ l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; }
@@ -730,44 +1146,39 @@ int LbmFsgrSolver<D>::debLBMQI(int level, int ii,int ij,int ik, int is, int l) {
if(is<0){ errMsg("LbmStrict"," invS- l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; }
if(is>1){ errMsg("LbmStrict"," invS+ l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; }
if(l<0) { errMsg("LbmStrict"," invD- "<<" l"<<l); STRICT_EXIT; }
- if(l>D::cDfNum){ // dFfrac is an exception
+ if(l>this->cDfNum){ // dFfrac is an exception
if((l != dMass) && (l != dFfrac) && (l != dFlux)){ errMsg("LbmStrict"," invD+ "<<" l"<<l); STRICT_EXIT; } }
#if COMPRESSGRIDS==1
- //if((!D::mInitDone) && (is!=mLevel[level].setCurr)){ STRICT_EXIT; } // COMPRT debug
+ //if((!this->mInitDone) && (is!=mLevel[level].setCurr)){ STRICT_EXIT; } // COMPRT debug
#endif // COMPRESSGRIDS==1
return _LBMQI(level, ii,ij,ik, is, l);
};
-template<class D>
-LbmFloat& LbmFsgrSolver<D>::debQCELL(int level, int xx,int yy,int zz,int set,int l) {
+LbmFloat& LbmFsgrSolver::debQCELL(int level, int xx,int yy,int zz,int set,int l) {
//errMsg("LbmStrict","debQCELL debug: l"<<level<<"|"<<xx<<","<<yy<<","<<zz<<" s"<<set<<" l"<<l<<" index"<<LBMGI(level, xx,yy,zz,set));
return _QCELL(level, xx,yy,zz,set,l);
};
-template<class D>
-LbmFloat& LbmFsgrSolver<D>::debQCELL_NB(int level, int xx,int yy,int zz,int set, int dir,int l) {
+LbmFloat& LbmFsgrSolver::debQCELL_NB(int level, int xx,int yy,int zz,int set, int dir,int l) {
if(dir<0) { errMsg("LbmStrict"," invD- l"<<level<<"|"<<xx<<","<<yy<<","<<zz<<" s"<<set<<" d"<<dir); STRICT_EXIT; }
- if(dir>D::cDfNum){ errMsg("LbmStrict"," invD+ l"<<level<<"|"<<xx<<","<<yy<<","<<zz<<" s"<<set<<" d"<<dir); STRICT_EXIT; }
+ if(dir>this->cDfNum){ errMsg("LbmStrict"," invD+ l"<<level<<"|"<<xx<<","<<yy<<","<<zz<<" s"<<set<<" d"<<dir); STRICT_EXIT; }
return _QCELL_NB(level, xx,yy,zz,set, dir,l);
};
-template<class D>
-LbmFloat& LbmFsgrSolver<D>::debQCELL_NBINV(int level, int xx,int yy,int zz,int set, int dir,int l) {
+LbmFloat& LbmFsgrSolver::debQCELL_NBINV(int level, int xx,int yy,int zz,int set, int dir,int l) {
if(dir<0) { errMsg("LbmStrict"," invD- l"<<level<<"|"<<xx<<","<<yy<<","<<zz<<" s"<<set<<" d"<<dir); STRICT_EXIT; }
- if(dir>D::cDfNum){ errMsg("LbmStrict"," invD+ l"<<level<<"|"<<xx<<","<<yy<<","<<zz<<" s"<<set<<" d"<<dir); STRICT_EXIT; }
+ if(dir>this->cDfNum){ errMsg("LbmStrict"," invD+ l"<<level<<"|"<<xx<<","<<yy<<","<<zz<<" s"<<set<<" d"<<dir); STRICT_EXIT; }
return _QCELL_NBINV(level, xx,yy,zz,set, dir,l);
};
-template<class D>
-LbmFloat* LbmFsgrSolver<D>::debRACPNT(int level, int ii,int ij,int ik, int is ) {
+LbmFloat* LbmFsgrSolver::debRACPNT(int level, int ii,int ij,int ik, int is ) {
return _RACPNT(level, ii,ij,ik, is );
};
-template<class D>
-LbmFloat& LbmFsgrSolver<D>::debRAC(LbmFloat* s,int l) {
+LbmFloat& LbmFsgrSolver::debRAC(LbmFloat* s,int l) {
if(l<0) { errMsg("LbmStrict"," invD- "<<" l"<<l); STRICT_EXIT; }
if(l>dTotalNum){ errMsg("LbmStrict"," invD+ "<<" l"<<l); STRICT_EXIT; }
- //if(l>D::cDfNum){ // dFfrac is an exception
+ //if(l>this->cDfNum){ // dFfrac is an exception
//if((l != dMass) && (l != dFfrac) && (l != dFlux)){ errMsg("LbmStrict"," invD+ "<<" l"<<l); STRICT_EXIT; } }
return _RAC(s,l);
};
@@ -785,8 +1196,7 @@ LbmFloat& LbmFsgrSolver<D>::debRAC(LbmFloat* s,int l) {
#include "../gui/gui_utilities.h"
//! display a single node
-template<class D>
-void LbmFsgrSolver<D>::debugDisplayNode(fluidDispSettings *dispset, CellIdentifierInterface* cell ) {
+void LbmFsgrSolver::debugDisplayNode(int dispset, CellIdentifierInterface* cell ) {
//debugOut(" DD: "<<cell->getAsString() , 10);
ntlVec3Gfx org = this->getCellOrigin( cell );
ntlVec3Gfx halfsize = this->getCellSize( cell );
@@ -796,7 +1206,7 @@ void LbmFsgrSolver<D>::debugDisplayNode(fluidDispSettings *dispset, CellIdentifi
bool showcell = true;
int linewidth = 1;
ntlColor col(0.5);
- LbmFloat cscale = dispset->scale;
+ LbmFloat cscale = 1.0; //dispset->scale;
#define DRAWDISPCUBE(col,scale) \
{ glLineWidth( linewidth ); \
@@ -821,7 +1231,7 @@ void LbmFsgrSolver<D>::debugDisplayNode(fluidDispSettings *dispset, CellIdentifi
else
if(flag& CFFluid ) { if(!guiShowFluid ) return; }
- switch(dispset->type) {
+ switch(dispset) {
case FLUIDDISPNothing: {
showcell = false;
} break;
@@ -947,35 +1357,44 @@ void LbmFsgrSolver<D>::debugDisplayNode(fluidDispSettings *dispset, CellIdentifi
//! debug display function
// D has to implement the CellIterator interface
-template<class D>
-void LbmFsgrSolver<D>::lbmDebugDisplay(fluidDispSettings *dispset) {
- //je nach solver...?
- if(!dispset->on) return;
+void LbmFsgrSolver::lbmDebugDisplay(int dispset) {
+ // DEBUG always display testdata
+#if LBM_INCLUDE_TESTSOLVERS==1
+ if(mUseTestdata){ mpTest->testDebugDisplay(dispset); }
+#endif // LBM_INCLUDE_TESTSOLVERS==1
+ if(dispset<=FLUIDDISPNothing) return;
+ //if(!dispset->on) return;
glDisable( GL_LIGHTING ); // dont light lines
- typename D::CellIdentifier cid = this->getFirstCell();
+#if LBM_INCLUDE_TESTSOLVERS==1
+ if((!mUseTestdata)|| (mUseTestdata)&&(mpTest->mDebugvalue1<=0.0)) {
+#endif // LBM_INCLUDE_TESTSOLVERS==1
+
+ LbmFsgrSolver::CellIdentifier cid = this->getFirstCell();
for(; this->noEndCell( cid );
this->advanceCell( cid ) ) {
this->debugDisplayNode(dispset, cid );
}
delete cid;
+#if LBM_INCLUDE_TESTSOLVERS==1
+ } // 3d check
+#endif // LBM_INCLUDE_TESTSOLVERS==1
+
glEnable( GL_LIGHTING ); // dont light lines
}
//! debug display function
// D has to implement the CellIterator interface
-template<class D>
-void LbmFsgrSolver<D>::lbmMarkedCellDisplay() {
- fluidDispSettings dispset;
+void LbmFsgrSolver::lbmMarkedCellDisplay() {
+ //fluidDispSettings dispset;
// trick - display marked cells as grid displa -> white, big
- dispset.type = FLUIDDISPGrid;
- dispset.on = true;
+ int dispset = FLUIDDISPGrid;
glDisable( GL_LIGHTING ); // dont light lines
- typename D::CellIdentifier cid = this->markedGetFirstCell();
+ LbmFsgrSolver::CellIdentifier cid = this->markedGetFirstCell();
while(cid) {
- this->debugDisplayNode(&dispset, cid );
+ this->debugDisplayNode(dispset, cid );
cid = this->markedAdvanceCell();
}
delete cid;
@@ -986,8 +1405,7 @@ void LbmFsgrSolver<D>::lbmMarkedCellDisplay() {
#endif // LBM_USE_GUI==1
//! display a single node
-template<class D>
-void LbmFsgrSolver<D>::debugPrintNodeInfo(CellIdentifierInterface* cell, int forceSet) {
+void LbmFsgrSolver::debugPrintNodeInfo(CellIdentifierInterface* cell, int forceSet) {
//string printInfo,
// force printing of one set? default = -1 = off
bool printDF = false;
@@ -1037,7 +1455,7 @@ void LbmFsgrSolver<D>::debugPrintNodeInfo(CellIdentifierInterface* cell, int for
debMsgStd(" ",DM_MSG, "Printing set:"<<workset<<" orgSet:"<<set, 1);
if(printDF) {
- for(int l=0; l<this->getDfNum(); l++) { // FIXME ??
+ for(int l=0; l<LBM_DFNUM; l++) { // FIXME ??
debMsgStd(" ",DM_MSG, " Df"<<l<<": "<<this->getCellDf(cell,workset,l), 1);
}
}
@@ -1054,24 +1472,9 @@ void LbmFsgrSolver<D>::debugPrintNodeInfo(CellIdentifierInterface* cell, int for
if(printMass) {
debMsgStd(" ",DM_MSG, " Mss: "<<this->getCellMass(cell,workset), 1);
}
+ // dirty... TODO fixme
+ debMsgStd(" ",DM_MSG, " Flx: "<<this->getCellDf(cell,workset,dFlux), 1);
}
}
-#endif // !defined(__APPLE_CC__) || defined(LBM_FORCEINCLUDE)
-
-/******************************************************************************
- * instantiation
- *****************************************************************************/
-#if ((!defined(__APPLE_CC__)) && (!defined(__INTEL_COMPILER))) && (!defined(LBM_FORCEINCLUDE))
-
-#if LBMDIM==2
-#define LBM_INSTANTIATE LbmBGK2D
-#endif // LBMDIM==2
-#if LBMDIM==3
-#define LBM_INSTANTIATE LbmBGK3D
-#endif // LBMDIM==3
-
-template class LbmFsgrSolver< LBM_INSTANTIATE >;
-
-#endif // __APPLE_CC__ __INTEL_COMPILER
diff --git a/intern/elbeem/intern/utilities.cpp b/intern/elbeem/intern/utilities.cpp
index 340a306c7f1..7cb4dd50577 100644
--- a/intern/elbeem/intern/utilities.cpp
+++ b/intern/elbeem/intern/utilities.cpp
@@ -30,8 +30,8 @@ extern "C" void simulateThreadIncreaseFrame(void);
extern "C" SDL_mutex *globalBakeLock;
// global state variables
extern "C" int globalBakeState;
-extern "C" int globalBakeFrame;
-#endif // ELBEEM_BLENDER==1
+//extern "C" int globalBakeFrame; not needed...?
+#endif // ELBEEM_PLUGIN==1
#include "utilities.h"
@@ -184,8 +184,9 @@ myTime_t getTime()
string getTimeString(myTime_t usecs) {
std::ostringstream ret;
//myTime_t us = usecs % 1000;
- myTime_t ms = usecs / (60*1000);
- myTime_t ss = (usecs / 1000) - (ms*60);
+ myTime_t ms = (myTime_t)( (double)usecs / (60.0*1000.0) );
+ myTime_t ss = (myTime_t)( ((double)usecs / 1000.0) - ((double)ms*60.0) );
+ int ps = (int)( ((double)usecs - (double)ss*1000.0)/10.0 );
//ret.setf(ios::showpoint|ios::fixed);
//ret.precision(5); ret.width(7);
@@ -193,7 +194,13 @@ string getTimeString(myTime_t usecs) {
if(ms>0) {
ret << ms<<"m"<< ss<<"s" ;
} else {
- ret << ss<<"s" ;
+ if(ps>0) {
+ ret << ss<<".";
+ if(ps<10) { ret <<"0"; }
+ ret <<ps<<"s" ;
+ } else {
+ ret << ss<<"s" ;
+ }
}
return ret.str();
}
@@ -368,6 +375,7 @@ double elbeemEstimateMemreq(int res,
#if ELBEEM_BLENDER==1
+// Blender state sync
void setGlobalBakeState(int set) {
SDL_mutexP(globalBakeLock);
globalBakeState = set;
diff --git a/intern/elbeem/intern/utilities.h b/intern/elbeem/intern/utilities.h
index 19d93c3a91c..3ba023e4730 100644
--- a/intern/elbeem/intern/utilities.h
+++ b/intern/elbeem/intern/utilities.h
@@ -27,13 +27,13 @@ bool checkBoundingBox(ntlVec3Gfx s, ntlVec3Gfx e, string checker);
/* debugging outputs , debug level 0 (off) to 10 (max) */
-#ifdef ELBEEM_BLENDER
+#ifdef ELBEEM_PLUGIN
#define DEBUG 0
void setGlobalBakeState(int set);
int getGlobalBakeState(void);
-#else // ELBEEM_BLENDER
+#else // ELBEEM_PLUGIN
#define DEBUG 10
-#endif // ELBEEM_BLENDER
+#endif // ELBEEM_PLUGIN
extern "C" int gDebugLevel;
// state of the simulation world
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index c51a50dd313..89ac6040eb6 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -555,26 +555,46 @@ static DerivedMesh *getMeshDerivedMesh(Mesh *me, Object *ob, float (*vertCos)[3]
mdm->freeNors = 0;
mdm->freeVerts = 0;
- if (vertCos) {
+ if((ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) &&
+ (ob->fluidsimSettings->type & OB_FLUIDSIM_DOMAIN)&&
+ (ob->fluidsimSettings->meshSurface) &&
+ (me->totvert == ((Mesh *)(ob->fluidsimSettings->meshSurface))->totvert) ) {
+ // dont recompute for fluidsim mesh, use from readBobjgz
+ // TODO? check for modifiers!?
int i;
-
- /* copy the original verts to preserve flag settings; if this is too
- * costly, must at least use MEM_callocN to clear flags */
- mdm->verts = MEM_dupallocN( me->mvert );
- for (i=0; i<me->totvert; i++) {
- VECCOPY(mdm->verts[i].co, vertCos[i]);
- }
mesh_calc_normals(mdm->verts, me->totvert, me->mface, me->totface, &mdm->nors);
mdm->freeNors = 1;
- mdm->freeVerts = 1;
+ for (i=0; i<me->totvert; i++) {
+ MVert *mv= &mdm->verts[i];
+ MVert *fsv;
+ fsv = &ob->fluidsimSettings->meshSurfNormals[i];
+ VECCOPY(mv->no, fsv->no);
+ //mv->no[0]= 30000; mv->no[1]= mv->no[2]= 0; // DEBUG fixed test normals
+ }
} else {
+ // recompute normally
+
+ if (vertCos) {
+ int i;
+
+ /* copy the original verts to preserve flag settings; if this is too
+ * costly, must at least use MEM_callocN to clear flags */
+ mdm->verts = MEM_dupallocN( me->mvert );
+ for (i=0; i<me->totvert; i++) {
+ VECCOPY(mdm->verts[i].co, vertCos[i]);
+ }
+ mesh_calc_normals(mdm->verts, me->totvert, me->mface, me->totface, &mdm->nors);
+ mdm->freeNors = 1;
+ mdm->freeVerts = 1;
+ } else {
// XXX this is kinda hacky because we shouldn't really be editing
// the mesh here, however, we can't just call mesh_build_faceNormals(ob)
// because in the case when a key is applied to a mesh the vertex normals
// would never be correctly computed.
- mesh_calc_normals(mdm->verts, me->totvert, me->mface, me->totface, &mdm->nors);
- mdm->freeNors = 1;
- }
+ mesh_calc_normals(mdm->verts, me->totvert, me->mface, me->totface, &mdm->nors);
+ mdm->freeNors = 1;
+ }
+ } // fs TEST
return (DerivedMesh*) mdm;
}
@@ -2072,8 +2092,9 @@ void writeBobjgz(char *filename, struct Object *ob)
wri = dlm->totvert;
gzwrite(gzf, &wri, sizeof(wri));
for(i=0; i<wri;i++) {
- VECCOPY(vec, dlm->mvert[i].co); /* get transformed point */
- Mat4MulVecfl(ob->obmat, vec);
+ VECCOPY(vec, dlm->mvert[i].co);
+ //VECCOPY(vec, dlm->mvert[i].co); /* get transformed point */
+ //Mat4MulVecfl(ob->obmat, vec);
for(j=0; j<3; j++) {
wrf = vec[j];
gzwrite(gzf, &wrf, sizeof( wrf ));
@@ -2087,7 +2108,8 @@ void writeBobjgz(char *filename, struct Object *ob)
for(i=0; i<wri;i++) {
VECCOPY(vec, dlm->mvert[i].no);
// FIXME divide? mv->no[0]= (short)(no[0]*32767.0);
- Mat3MulVecfl(rotmat, vec);
+ //VECCOPY(vec, dlm->mvert[i].no);
+ //Mat3MulVecfl(rotmat, vec);
Normalise(vec);
for(j=0; j<3; j++) {
wrf = vec[j];
@@ -2130,8 +2152,63 @@ void writeBobjgz(char *filename, struct Object *ob)
dm->release(dm);
}
+void initElbeemMesh(struct Object *ob,
+ int *numVertices, float **vertices,
+ int *numTriangles, int **triangles)
+{
+ DispListMesh *dlm = NULL;
+ DerivedMesh *dm = NULL;
+ MFace *mface = NULL;
+ int countTris=0, i;
+ float *verts;
+ int *tris;
+
+ dm = mesh_create_derived_render(ob);
+ if(!dm) { *numVertices = *numTriangles = 0; *triangles=NULL; *vertices=NULL; }
+ dlm = dm->convertToDispListMesh(dm, 1);
+ if(!dlm) { dm->release(dm); *numVertices = *numTriangles = 0; *triangles=NULL; *vertices=NULL; }
+ mface = dlm->mface;
+
+ *numVertices = dlm->totvert;
+ verts = MEM_callocN( dlm->totvert*3*sizeof(float), "elbeemmesh_vertices");
+ for(i=0; i<dlm->totvert; i++) {
+ VECCOPY( &verts[i*3], dlm->mvert[i].co);
+ }
+ *vertices = verts;
+
+ for(i=0; i<dlm->totface; i++) {
+ countTris++;
+ if(mface[i].v4) { countTris++; }
+ }
+ *numTriangles = countTris;
+ tris = MEM_callocN( countTris*3*sizeof(int), "elbeemmesh_triangles");
+ countTris = 0;
+ for(i=0; i<dlm->totface; i++) {
+ int face[4];
+ face[0] = mface[i].v1;
+ face[1] = mface[i].v2;
+ face[2] = mface[i].v3;
+ face[3] = mface[i].v4;
+
+ tris[countTris*3+0] = face[0];
+ tris[countTris*3+1] = face[1];
+ tris[countTris*3+2] = face[2];
+ countTris++;
+ if(face[3]) {
+ tris[countTris*3+0] = face[0];
+ tris[countTris*3+1] = face[2];
+ tris[countTris*3+2] = face[3];
+ countTris++;
+ }
+ }
+ *triangles = tris;
+
+ if(dlm) displistmesh_free(dlm);
+ dm->release(dm);
+}
+
/* read .bobj.gz file into a fluidsimDerivedMesh struct */
-Mesh* readBobjgz(char *filename, Mesh *orgmesh) //, fluidsimDerivedMesh *fsdm)
+Mesh* readBobjgz(char *filename, Mesh *orgmesh, float* bbstart, float *bbsize) //, fluidsimDerivedMesh *fsdm)
{
int wri,i,j;
char debugStrBuffer[256];
@@ -2211,9 +2288,13 @@ Mesh* readBobjgz(char *filename, Mesh *orgmesh) //, fluidsimDerivedMesh *fsdm)
for(i=0; i<newmesh->totvert;i++) {
for(j=0; j<3; j++) {
gotBytes = gzread(gzf, &wrf, sizeof( wrf ));
- newmesh->mvert[i].no[j] = wrf*32767.0;
+ newmesh->mvert[i].no[j] = (short)(wrf*32767.0f);
+ //newmesh->mvert[i].no[j] = 0.5; // DEBUG tst
}
+ //fprintf(stderr," DEBDPCN nm%d, %d = %d,%d,%d \n",
+ //(int)(newmesh->mvert), i, newmesh->mvert[i].no[0], newmesh->mvert[i].no[1], newmesh->mvert[i].no[2]);
}
+ //fprintf(stderr," DPCN 0 = %d,%d,%d \n", newmesh->mvert[0].no[0], newmesh->mvert[0].no[1], newmesh->mvert[0].no[2]);
/* compute no. of triangles */
@@ -2258,6 +2339,61 @@ Mesh* readBobjgz(char *filename, Mesh *orgmesh) //, fluidsimDerivedMesh *fsdm)
return newmesh;
}
+/* read zipped fluidsim velocities into the co's of the fluidsimsettings normals struct */
+void readVelgz(char *filename, Object *srcob)
+{
+ char debugStrBuffer[256];
+ int wri, i, j;
+ float wrf;
+ gzFile gzf;
+ MVert *vverts = srcob->fluidsimSettings->meshSurfNormals;
+ int len = strlen(filename);
+ Mesh *mesh = srcob->data;
+ // mesh and vverts have to be valid from loading...
+
+ // clean up in any case
+ for(i=0; i<mesh->totvert;i++) {
+ for(j=0; j<3; j++) {
+ vverts[i].co[j] = 0.;
+ }
+ }
+ if(srcob->fluidsimSettings->typeFlags&OB_FSDOMAIN_NOVECGEN) return;
+
+ if(len<7) {
+ //printf("readVelgz Eror: invalid filename '%s'\n",filename); // DEBUG
+ return;
+ }
+
+ // .bobj.gz , correct filename
+ // 87654321
+ filename[len-6] = 'v';
+ filename[len-5] = 'e';
+ filename[len-4] = 'l';
+
+ snprintf(debugStrBuffer,256,"Reading '%s' GZ_VEL... ",filename); elbeemDebugOut(debugStrBuffer);
+ gzf = gzopen(filename, "rb");
+ if (!gzf) {
+ //printf("readVelgz Eror: unable to open file '%s'\n",filename); // DEBUG
+ return;
+ }
+
+ gzread(gzf, &wri, sizeof( wri ));
+ if(wri != mesh->totvert) {
+ //printf("readVelgz Eror: invalid no. of velocities %d vs. %d aborting.\n" ,wri ,mesh->totvert ); // DEBUG
+ return;
+ }
+
+ for(i=0; i<mesh->totvert;i++) {
+ for(j=0; j<3; j++) {
+ gzread(gzf, &wrf, sizeof( wrf ));
+ vverts[i].co[j] = wrf;
+ }
+ //if(i<20) fprintf(stderr, "GZ_VELload %d = %f,%f,%f \n",i,vverts[i].co[0],vverts[i].co[1],vverts[i].co[2]); // DEBUG
+ }
+
+ gzclose(gzf);
+}
+
/* ***************************** fluidsim derived mesh ***************************** */
@@ -2297,6 +2433,9 @@ void loadFluidsimMesh(Object *srcob, int useRenderParams)
if(srcob->data == srcob->fluidsimSettings->meshSurface)
srcob->data = srcob->fluidsimSettings->orgMesh;
srcob->fluidsimSettings->meshSurface = NULL;
+
+ if(srcob->fluidsimSettings->meshSurfNormals) MEM_freeN(srcob->fluidsimSettings->meshSurfNormals);
+ srcob->fluidsimSettings->meshSurfNormals = NULL;
}
// init bounding box
@@ -2305,7 +2444,7 @@ void loadFluidsimMesh(Object *srcob, int useRenderParams)
lastBB[0] = bbSize[0]; // TEST
lastBB[1] = bbSize[1];
lastBB[2] = bbSize[2];
- fluidsimGetAxisAlignedBB(srcob->fluidsimSettings->orgMesh, srcob->obmat, bbStart, bbSize);
+ fluidsimGetAxisAlignedBB(srcob->fluidsimSettings->orgMesh, srcob->obmat, bbStart, bbSize, &srcob->fluidsimSettings->meshBB);
// check free fsmesh... TODO
if(!useRenderParams) {
@@ -2314,7 +2453,8 @@ void loadFluidsimMesh(Object *srcob, int useRenderParams)
displaymode = srcob->fluidsimSettings->renderDisplayMode;
}
- snprintf(debugStrBuffer,256,"loadFluidsimMesh call (obid '%s', rp %d, dm %d)\n", srcob->id.name, useRenderParams, displaymode); // debug
+ snprintf(debugStrBuffer,256,"loadFluidsimMesh call (obid '%s', rp %d, dm %d), curFra=%d, sFra=%d #=%d \n",
+ srcob->id.name, useRenderParams, displaymode, G.scene->r.cfra, G.scene->r.sfra, curFrame ); // debug
elbeemDebugOut(debugStrBuffer); // debug
strncpy(targetDir, srcob->fluidsimSettings->surfdataPath, FILE_MAXDIR);
@@ -2335,7 +2475,11 @@ void loadFluidsimMesh(Object *srcob, int useRenderParams)
snprintf(debugStrBuffer,256,"loadFluidsimMesh call (obid '%s', rp %d, dm %d) '%s' \n", srcob->id.name, useRenderParams, displaymode, targetFile); // debug
elbeemDebugOut(debugStrBuffer); // debug
- mesh = readBobjgz(targetFile, srcob->fluidsimSettings->orgMesh );
+ if(displaymode!=2) { // dont add bounding box for final
+ mesh = readBobjgz(targetFile, srcob->fluidsimSettings->orgMesh ,NULL,NULL);
+ } else {
+ mesh = readBobjgz(targetFile, srcob->fluidsimSettings->orgMesh, bbSize,bbSize );
+ }
if(!mesh) {
// display org. object upon failure
srcob->data = srcob->fluidsimSettings->orgMesh;
@@ -2347,13 +2491,27 @@ void loadFluidsimMesh(Object *srcob, int useRenderParams)
}
srcob->fluidsimSettings->meshSurface = mesh;
srcob->data = mesh;
+ srcob->fluidsimSettings->meshSurfNormals = MEM_dupallocN(mesh->mvert);
+
+ // load vertex velocities, if they exist...
+ // TODO? use generate flag as loading flag as well?
+ // warning, needs original .bobj.gz mesh loading filename
+ if(displaymode==3) {
+ readVelgz(targetFile, srcob);
+ } else {
+ // no data for preview, only clear...
+ int i,j;
+ for(i=0; i<mesh->totvert;i++) { for(j=0; j<3; j++) { srcob->fluidsimSettings->meshSurfNormals[i].co[j] = 0.; }}
+ }
+
+ //fprintf(stderr,"LOADFLM DEBXHCH fs=%d 3:%d,%d,%d \n", (int)mesh, ((Mesh *)(srcob->fluidsimSettings->meshSurface))->mvert[3].no[0], ((Mesh *)(srcob->fluidsimSettings->meshSurface))->mvert[3].no[1], ((Mesh *)(srcob->fluidsimSettings->meshSurface))->mvert[3].no[2]);
return;
}
/* helper function */
/* init axis aligned BB for mesh object */
void fluidsimGetAxisAlignedBB(struct Mesh *mesh, float obmat[][4],
- /*RET*/ float start[3], /*RET*/ float size[3] )
+ /*RET*/ float start[3], /*RET*/ float size[3], /*RET*/ struct Mesh **bbmesh )
{
float bbsx=0.0, bbsy=0.0, bbsz=0.0;
float bbex=1.0, bbey=1.0, bbez=1.0;
@@ -2388,6 +2546,25 @@ void fluidsimGetAxisAlignedBB(struct Mesh *mesh, float obmat[][4],
size[1] = bbey-bbsy;
size[2] = bbez-bbsz;
}
+
+ // init bounding box mesh?
+ if(bbmesh) {
+ int i,j;
+ Mesh *newmesh = NULL;
+ if(!(*bbmesh)) { newmesh = MEM_callocN(sizeof(Mesh), "fluidsimGetAxisAlignedBB_meshbb"); }
+ else { newmesh = *bbmesh; }
+
+ newmesh->totvert = 8;
+ if(!newmesh->mvert) newmesh->mvert = MEM_callocN(sizeof(MVert)*newmesh->totvert, "fluidsimBBMesh_bobjvertices");
+ for(i=0; i<8; i++) {
+ for(j=0; j<3; j++) newmesh->mvert[i].co[j] = start[j];
+ }
+
+ newmesh->totface = 6;
+ if(!newmesh->mface) newmesh->mface = MEM_callocN(sizeof(MFace)*newmesh->totface, "fluidsimBBMesh_bobjfaces");
+
+ *bbmesh = newmesh;
+ }
}
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 51701c19ca0..9d8857d4119 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -1610,8 +1610,8 @@ static void dag_object_time_update_flags(Object *ob)
}
if((ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) && (ob->fluidsimSettings)) {
// fluidsimSettings might not be initialized during load...
- if(ob->fluidsimSettings->type & OB_FLUIDSIM_DOMAIN) {
- ob->recalc |= OB_RECALC_DATA; // NT
+ if(ob->fluidsimSettings->type & (OB_FLUIDSIM_DOMAIN|OB_FLUIDSIM_PARTICLE)) {
+ ob->recalc |= OB_RECALC_DATA; // NT FSPARTICLE
}
}
break;
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index 663fe02aaf0..2a95bd82872 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -51,6 +51,11 @@
#include "DNA_object_force.h"
#include "DNA_texture_types.h"
#include "DNA_scene_types.h"
+// FSPARTICLE
+#include "DNA_object_fluidsim.h"
+#include "LBM_fluidsim.h"
+#include <zlib.h>
+#include <string.h>
#include "BLI_arithb.h"
#include "BLI_blenlib.h"
@@ -1594,6 +1599,7 @@ void build_particle_system(Object *ob)
float *volengths= NULL, *folengths= NULL;
int deform=0, a, totpart, paf_sta, paf_end;
int waitcursor_set= 0, totvert, totface, curface, curvert;
+ int readMask =0, activeParts;
/* return conditions */
if(ob->type!=OB_MESH) return;
@@ -1604,6 +1610,104 @@ void build_particle_system(Object *ob)
if(paf->keys) MEM_freeN(paf->keys); /* free as early as possible, for returns */
paf->keys= NULL;
+ // FSPARTICLE all own created...
+ if( (1) && (ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) &&
+ (ob->fluidsimSettings) &&
+ (ob->fluidsimSettings->type == OB_FLUIDSIM_PARTICLE)) {
+ char *suffix = "fluidsurface_particles_#";
+ char *suffix2 = ".gz";
+ char filename[256];
+ int curFrame = G.scene->r.cfra -1; // warning - sync with derived mesh fsmesh loading
+ int j, numFileParts;
+ gzFile gzf;
+ float vel[3];
+
+ if(ob==G.obedit) { // off...
+ paf->totpart = 1;
+ return;
+ }
+
+ // ok, start loading
+ strcpy(filename, ob->fluidsimSettings->surfdataPath);
+ strcat(filename, suffix);
+ BLI_convertstringcode(filename, G.sce, curFrame); // fixed #frame-no
+ strcat(filename, suffix2);
+
+ gzf = gzopen(filename, "rb");
+ if (!gzf) {
+ //char debugStrBuffer[256];
+ //define win32... snprintf(debugStrBuffer,256,"readFsPartData::error - Unable to open file for reading '%s'\n", filename);
+ //elbeemDebugOut(debugStrBuffer);
+ paf->totpart = 1;
+ return;
+ }
+
+ gzread(gzf, &totpart, sizeof(totpart));
+ numFileParts = totpart;
+ totpart = (G.rendering)?totpart:(paf->disp*totpart)/100;
+ paf->totpart= totpart;
+ paf->totkey= 1;
+ /* initialize particles */
+ new_particle(paf);// ?
+ ftime = 0.0;
+ dtime= 0.0f;
+
+ // set up reading mask
+ //for(j=1; j<=4; j++ ){ if(ob->fluidsimSettings->guiDisplayMode&j) readMask |= (1<<j); }
+ readMask = ob->fluidsimSettings->guiDisplayMode;
+ activeParts=0;
+ // FIXME only allocate needed ones?
+
+ //fprintf(stderr,"FSPARTICLE debug set %s , tot%d mask=%d \n", filename, totpart, readMask );
+ for(a=0; a<totpart; a++, ftime+=dtime) {
+ int ptype=0;
+ short shsize=0;
+ float convertSize=0.0;
+ gzread(gzf, &ptype, sizeof( ptype ));
+ //if(a<25) fprintf(stderr,"FSPARTICLE debug set %s , a%d t=%d , mask=%d , active%d\n", filename, a, ptype, readMask, activeParts );
+ if(ptype&readMask) {
+ activeParts++;
+ pa= new_particle(paf);
+ pa->time= ftime;
+ pa->lifetime= ftime + G.scene->r.efra +1.0;
+ pa->co[0] = 0.0;
+ pa->co[1] =
+ pa->co[2] = 1.0*(float)a / (float)totpart;
+ pa->no[0] = pa->no[1] = pa->no[2] = 0.0;
+ pa->mat_nr= paf->omat;
+ gzread(gzf, &convertSize, sizeof( float ));
+ // convert range of 1.0-10.0 to shorts 1000-10000)
+ shsize = (short)(convertSize*1000.0);
+ pa->rt = shsize;
+ //if(a<200) fprintf(stderr,"SREAD %f %d %d \n",convertSize,shsize,pa->rt);
+
+ for(j=0; j<3; j++) {
+ float wrf;
+ gzread(gzf, &wrf, sizeof( wrf ));
+ pa->co[j] = wrf;
+ //fprintf(stderr,"Rj%d ",j);
+ }
+ for(j=0; j<3; j++) {
+ float wrf;
+ gzread(gzf, &wrf, sizeof( wrf ));
+ vel[j] = wrf;
+ }
+ } else {
+ // skip...
+ for(j=0; j<2*3+1; j++) {
+ float wrf; gzread(gzf, &wrf, sizeof( wrf ));
+ }
+ }
+ //fprintf(stderr,"FSPARTICLE debug set %s , a%d = %f,%f,%f , life=%f \n", filename, a, pa->co[0],pa->co[1],pa->co[2], pa->lifetime );
+ }
+ gzclose( gzf );
+
+ totpart = paf->totpart = activeParts;
+ //fprintf(stderr,"PARTOBH debug %s %d \n", ob->id.name, totpart); // DEBUG
+ return;
+ }
+
+
if(paf->end < paf->sta) return;
if( (paf->flag & PAF_OFACE) && (paf->flag & PAF_FACE)==0) return;
diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c
index 13821ea3712..c7587bbeb59 100644
--- a/source/blender/blenkernel/intern/ipo.c
+++ b/source/blender/blenkernel/intern/ipo.c
@@ -171,6 +171,13 @@ int snd_ar[SND_TOTIPO]= {
SND_VOLUME, SND_PITCH, SND_PANNING, SND_ATTEN
};
+int fluidsim_ar[FLUIDSIM_TOTIPO]= {
+ FLUIDSIM_VISC, FLUIDSIM_TIME,
+ FLUIDSIM_GRAV_X , FLUIDSIM_GRAV_Y , FLUIDSIM_GRAV_Z ,
+ FLUIDSIM_VEL_X , FLUIDSIM_VEL_Y , FLUIDSIM_VEL_Z ,
+ FLUIDSIM_ACTIVE
+};
+
float frame_to_float(int cfra) /* see also bsystem_time in object.c */
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index ff1948af18d..cbe3195da27 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -2371,6 +2371,10 @@ static void lib_link_object(FileData *fd, Main *main)
act= act->next;
}
+ if(ob->fluidsimSettings) {
+ ob->fluidsimSettings->ipo = newlibadr_us(fd, ob->id.lib, ob->fluidsimSettings->ipo);
+ }
+
lib_link_scriptlink(fd, &ob->id, &ob->scriptlink);
lib_link_modifiers(fd, ob);
}
diff --git a/source/blender/include/BSE_editipo.h b/source/blender/include/BSE_editipo.h
index 06611ec6dda..8ae27f26e7d 100644
--- a/source/blender/include/BSE_editipo.h
+++ b/source/blender/include/BSE_editipo.h
@@ -58,6 +58,7 @@ char *getname_cu_ei(int nr);
char *getname_la_ei(int nr);
char *getname_cam_ei(int nr);
char *getname_snd_ei(int nr);
+char *getname_fluidsim_ei(int nr);
struct EditIpo *get_active_editipo(void);
diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h
index 82c9756f2b3..b5b0e5ac39e 100644
--- a/source/blender/include/butspace.h
+++ b/source/blender/include/butspace.h
@@ -252,8 +252,9 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la
/* Fluidsim button defines */
#define B_FLUIDSIM_BAKE 1450
-#define B_FLUIDSIM_SELDIR 1451
+#define B_FLUIDSIM_SELDIR 1451
#define B_FLUIDSIM_FORCEREDRAW 1452
+#define B_FLUIDSIM_MAKEPART 1453
#define B_GROUP_RELINK 1460
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index 71f4a30bb24..7e71da6df76 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -127,6 +127,7 @@ typedef struct Library {
#define ID_AR MAKE_ID2('A', 'R')
#define ID_AC MAKE_ID2('A', 'C')
#define ID_SCRIPT MAKE_ID2('P', 'Y')
+#define ID_FLUIDSIM MAKE_ID2('F', 'S')
#define ID_NT MAKE_ID2('N', 'T')
/* NOTE! Fake IDs, needed for g.sipo->blocktype or outliner */
diff --git a/source/blender/makesdna/DNA_ipo_types.h b/source/blender/makesdna/DNA_ipo_types.h
index c05c27ede6b..fc30c1ec5e6 100644
--- a/source/blender/makesdna/DNA_ipo_types.h
+++ b/source/blender/makesdna/DNA_ipo_types.h
@@ -326,6 +326,26 @@ typedef short IPO_Channel;
#define CO_ROLL 9
*/
+/* ******************** */
+/* fluidsim ipos NT */
+
+#define FLUIDSIM_TOTIPO 9
+#define FLUIDSIM_TOTNAM 9
+
+#define FLUIDSIM_VISC 1
+#define FLUIDSIM_TIME 2
+
+#define FLUIDSIM_GRAV_X 3
+#define FLUIDSIM_GRAV_Y 4
+#define FLUIDSIM_GRAV_Z 5
+
+#define FLUIDSIM_VEL_X 6
+#define FLUIDSIM_VEL_Y 7
+#define FLUIDSIM_VEL_Z 8
+
+#define FLUIDSIM_ACTIVE 9
+
+
/* these are IpoCurve specific */
/* **************** IPO ********************* */
diff --git a/source/blender/makesdna/DNA_object_fluidsim.h b/source/blender/makesdna/DNA_object_fluidsim.h
index 1b5b77591f7..e2e2ecd5570 100644
--- a/source/blender/makesdna/DNA_object_fluidsim.h
+++ b/source/blender/makesdna/DNA_object_fluidsim.h
@@ -33,12 +33,15 @@
#ifndef DNA_OBJECT_FLUIDSIM_H
#define DNA_OBJECT_FLUIDSIM_H
+#include "DNA_ID.h"
#ifdef __cplusplus
extern "C" {
#endif
struct Mesh;
+struct Ipo;
+struct MVert;
typedef struct FluidsimSettings {
/* domain,fluid or obstacle */
@@ -87,6 +90,24 @@ typedef struct FluidsimSettings {
/* store start coords of axis aligned bounding box together with size */
/* values are inited during derived mesh display */
float bbStart[3], bbSize[3];
+
+ /* animated params */
+ struct Ipo *ipo;
+
+ /* additional flags depending on the type, lower short contains flags
+ * to check validity, higher short additional flags */
+ int typeFlags;
+
+ /* boundary "stickiness" for part slip values */
+ float partSlipValue;
+ /* particle generation - on if >0, then determines amount */
+ float generateParticles, dummy;
+ /* particle display - size scaling, and alpha influence */
+ float particleInfSize, particleInfAlpha;
+
+ /* save fluidsurface normals in mvert.no, and surface vertex velocities (if available) in mvert.co */
+ struct MVert *meshSurfNormals;
+
} FluidsimSettings;
/* ob->fluidsimSettings defines */
@@ -96,6 +117,24 @@ typedef struct FluidsimSettings {
#define OB_FLUIDSIM_OBSTACLE 8
#define OB_FLUIDSIM_INFLOW 16
#define OB_FLUIDSIM_OUTFLOW 32
+#define OB_FLUIDSIM_PARTICLE 64
+
+#define OB_TYPEFLAG_START 16
+#define OB_FSGEO_THIN (1<<(OB_TYPEFLAG_START+1))
+#define OB_FSBND_NOSLIP (1<<(OB_TYPEFLAG_START+2))
+#define OB_FSBND_PARTSLIP (1<<(OB_TYPEFLAG_START+3))
+#define OB_FSBND_FREESLIP (1<<(OB_TYPEFLAG_START+4))
+#define OB_FSINFLOW_LOCALCOORD (1<<(OB_TYPEFLAG_START+5))
+#define OB_FSDOMAIN_NOVECGEN (1<<(OB_TYPEFLAG_START+6))
+
+// guiDisplayMode particle flags
+#define OB_FSDOM_GEOM 1
+#define OB_FSDOM_PREVIEW 2
+#define OB_FSDOM_FINAL 3
+#define OB_FSPART_BUBBLE (1<<1)
+#define OB_FSPART_DROP (1<<2)
+#define OB_FSPART_NEWPART (1<<3)
+#define OB_FSPART_FLOAT (1<<4)
#ifdef __cplusplus
}
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index 937a5834964..6498cf534ba 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -56,6 +56,7 @@
#include "DNA_meta_types.h"
#include "DNA_object_types.h"
#include "DNA_object_force.h"
+#include "DNA_object_fluidsim.h"
#include "DNA_scene_types.h"
#include "DNA_texture_types.h"
#include "DNA_view3d_types.h"
@@ -447,6 +448,104 @@ static void calc_vertexnormals(Render *re, int startvert, int startvlak, int do_
}
}
+// NT same as calc_vertexnormals, but dont modify the existing vertex normals
+// only recalculate other render data. If this is at some point used for other things than fluidsim,
+// this could be made on option for the normal calc_vertexnormals
+static void calc_fluidsimnormals(Render *re, int startvert, int startvlak, int do_tangent)
+{
+ int a;
+
+ /* dont clear vertex normals here */
+ // OFF for(a=startvert; a<re->totvert; a++) { VertRen *ver= RE_findOrAddVert(re, a); ver->n[0]=ver->n[1]=ver->n[2]= 0.0; }
+ /* calculate cos of angles and point-masses, use as weight factor to add face normal to vertex */
+ for(a=startvlak; a<re->totvlak; a++) {
+ VlakRen *vlr= RE_findOrAddVlak(re, a);
+ if(vlr->flag & ME_SMOOTH) {
+ VertRen *adrve1= vlr->v1;
+ VertRen *adrve2= vlr->v2;
+ VertRen *adrve3= vlr->v3;
+ VertRen *adrve4= vlr->v4;
+ float n1[3], n2[3], n3[3], n4[3];
+ float fac1, fac2, fac3, fac4=0.0f;
+
+ VecSubf(n1, adrve2->co, adrve1->co);
+ Normalise(n1);
+ VecSubf(n2, adrve3->co, adrve2->co);
+ Normalise(n2);
+ if(adrve4==NULL) {
+ VecSubf(n3, adrve1->co, adrve3->co);
+ Normalise(n3);
+ fac1= saacos(-n1[0]*n3[0]-n1[1]*n3[1]-n1[2]*n3[2]);
+ fac2= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]);
+ fac3= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]);
+ }
+ else {
+ VecSubf(n3, adrve4->co, adrve3->co);
+ Normalise(n3);
+ VecSubf(n4, adrve1->co, adrve4->co);
+ Normalise(n4);
+
+ fac1= saacos(-n4[0]*n1[0]-n4[1]*n1[1]-n4[2]*n1[2]);
+ fac2= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]);
+ fac3= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]);
+ fac4= saacos(-n3[0]*n4[0]-n3[1]*n4[1]-n3[2]*n4[2]);
+
+ if(!(vlr->flag & R_NOPUNOFLIP)) {
+ if( contrpuntnormr(vlr->n, adrve4->n) ) fac4= -fac4;
+ }
+ }
+
+ if(do_tangent)
+ calc_tangent_vector(re, vlr, fac1, fac2, fac3, fac4);
+ }
+ }
+
+ /* do solid faces */
+ for(a=startvlak; a<re->totvlak; a++) {
+ VlakRen *vlr= RE_findOrAddVlak(re, a);
+ if((vlr->flag & ME_SMOOTH)==0) {
+ float *f1= vlr->v1->n;
+ if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n);
+ f1= vlr->v2->n;
+ if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n);
+ f1= vlr->v3->n;
+ if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n);
+ if(vlr->v4) {
+ f1= vlr->v4->n;
+ if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n);
+ }
+ }
+ }
+
+ /* normalise vertex normals */
+ for(a=startvert; a<re->totvert; a++) {
+ VertRen *ver= RE_findOrAddVert(re, a);
+ Normalise(ver->n);
+ if(do_tangent) {
+ float *tav= RE_vertren_get_tangent(re, ver, 0);
+ if(tav) Normalise(tav);
+ }
+ }
+
+ /* vertex normal (puno) switch flags for during render */
+ for(a=startvlak; a<re->totvlak; a++) {
+ VlakRen *vlr= RE_findOrAddVlak(re, a);
+ if((vlr->flag & R_NOPUNOFLIP)==0) {
+ VertRen *adrve1= vlr->v1;
+ VertRen *adrve2= vlr->v2;
+ VertRen *adrve3= vlr->v3;
+ VertRen *adrve4= vlr->v4;
+ vlr->puno &= ~15;
+ if ((vlr->n[0]*adrve1->n[0]+vlr->n[1]*adrve1->n[1]+vlr->n[2]*adrve1->n[2])<0.0) vlr->puno= 1;
+ if ((vlr->n[0]*adrve2->n[0]+vlr->n[1]*adrve2->n[1]+vlr->n[2]*adrve2->n[2])<0.0) vlr->puno+= 2;
+ if ((vlr->n[0]*adrve3->n[0]+vlr->n[1]*adrve3->n[1]+vlr->n[2]*adrve3->n[2])<0.0) vlr->puno+= 4;
+ if(adrve4) {
+ if((vlr->n[0]*adrve4->n[0]+vlr->n[1]*adrve4->n[1]+vlr->n[2]*adrve4->n[2])<0.0) vlr->puno+= 8;
+ }
+ }
+ }
+}
+
/* ------------------------------------------------------------------------- */
/* Autosmoothing: */
/* ------------------------------------------------------------------------- */
@@ -742,6 +841,12 @@ static void render_particle_system(Render *re, Object *ob, PartEff *paf)
float xn, yn, zn, imat[3][3], tmat[4][4], mat[4][4], hasize, stime, ptime, ctime, vec[3], vec1[3], view[3], nor[3];
int a, mat_nr=1, seed;
+ int useFluidsimParticles = 0; // FSPARTICLE
+ float haloScale = 1.0; //NT scale halos
+ float iniAlpha = 0.0; // restore material alpha
+
+
+
pa= paf->keys;
if(pa==NULL || paf->disp!=100) {
build_particle_system(ob);
@@ -767,6 +872,10 @@ static void render_particle_system(Render *re, Object *ob, PartEff *paf)
else ptime= 0.0;
ctime= bsystem_time(ob, 0, (float)re->scene->r.cfra, ptime);
seed= ma->seed1;
+ if( (ob->fluidsimSettings) && (ob->fluidsimSettings->type == OB_FLUIDSIM_PARTICLE)) {
+ useFluidsimParticles = 1;
+ iniAlpha = ma->alpha;
+ }
for(a=0; a<paf->totpart; a++, pa+=paf->totkey, seed++) {
@@ -810,7 +919,16 @@ static void render_particle_system(Render *re, Object *ob, PartEff *paf)
execute_ipo((ID *)ma, ma->ipo);
}
- hasize= ma->hasize;
+ //NT scale halos FSPARTICLE
+ if(useFluidsimParticles) {
+ // rescale to 1.0-10.0, then div by 5 afterwards, gives values in range 0.2-2.0
+ double fspsize = ((double)pa->rt / 1000.0f) / 5.0 ;
+ haloScale = (float)pow(fspsize, (double)ob->fluidsimSettings->particleInfSize);
+ ma->alpha = iniAlpha / (float)pow( fspsize, (double)ob->fluidsimSettings->particleInfAlpha);
+ if(ma->alpha>1.) ma->alpha = 1.;
+ }
+
+ hasize= ma->hasize * haloScale;
if(ma->mode & MA_HALOPUNO) {
xn= pa->no[0];
@@ -852,6 +970,8 @@ static void render_particle_system(Render *re, Object *ob, PartEff *paf)
MEM_freeN(paf->keys);
paf->keys= NULL;
}
+
+ if(useFluidsimParticles) { ma->alpha = iniAlpha; }// FSPARTICLE restore...
}
@@ -1442,6 +1562,7 @@ static void init_render_mesh(Render *re, Object *ob, int only_verts)
float *orco=0;
int a, a1, ok, need_orco=0, need_stress=0, need_tangent=0, totvlako, totverto, vertofs;
int end, do_autosmooth=0, totvert = 0, dm_needsfree;
+ int useFluidmeshNormals = 0; // NT fluidsim, use smoothed normals?
me= ob->data;
@@ -1493,6 +1614,12 @@ static void init_render_mesh(Render *re, Object *ob, int only_verts)
dm_needsfree= 1;
if(dm==NULL) return; /* in case duplicated object fails? */
+
+ if((ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) &&
+ (ob->fluidsimSettings->type & OB_FLUIDSIM_DOMAIN)&&
+ (ob->fluidsimSettings->meshSurface) ) {
+ useFluidmeshNormals = 1;
+ }
dlm = dm->convertToDispListMesh(dm, 1);
@@ -1514,6 +1641,16 @@ static void init_render_mesh(Render *re, Object *ob, int only_verts)
if(do_autosmooth==0) /* autosmooth on original unrotated data to prevent differences between frames */
MTC_Mat4MulVecfl(mat, ver->co);
+ if(useFluidmeshNormals) {
+ xn = mvert->no[0]/ 32767.0;
+ yn = mvert->no[1]/ 32767.0;
+ zn = mvert->no[2]/ 32767.0;
+ /* transfor to cam space */
+ ver->n[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
+ ver->n[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
+ ver->n[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
+ } // useFluidmeshNormals
+
if(orco) {
ver->orco= orco;
orco+=3;
@@ -1705,7 +1842,12 @@ static void init_render_mesh(Render *re, Object *ob, int only_verts)
autosmooth(re, mat, totverto, totvlako, me->smoothresh);
}
- calc_vertexnormals(re, totverto, totvlako, need_tangent);
+ if(useFluidmeshNormals) {
+ // do not recalculate, only init render data
+ calc_fluidsimnormals(re, totverto, totvlako, need_tangent);
+ } else {
+ calc_vertexnormals(re, totverto, totvlako, need_tangent);
+ }
if(need_stress)
calc_edge_stress(re, me, totverto, totvlako);
@@ -3126,9 +3268,84 @@ static void calculate_speedvectors(Render *re, float *vectors, int startvert, in
speed[0]= zco[0];
speed[1]= zco[1];
}
+
}
}
+static int load_fluidsimspeedvectors(Render *re, float *vectors, int startvert, int endvert, int step, Object *fsob)
+{
+ VertRen *ver= NULL;
+ float *speed, div, zco[2];
+ float zmulx= re->winx/2, zmuly= re->winy/2, len;
+ float winsq= re->winx*re->winy, winroot= sqrt(winsq);
+ int a, j;
+ float hoco[4], fsvec[4], camco[4];
+ float mat[4][4];
+ float imat[4][4];
+ MVert *vverts;
+
+ /* only one step needed */
+ if(step) return 1;
+
+ Mat4CpyMat4(mat, re->viewmat);
+ MTC_Mat4Invert(imat, mat);
+
+ /* set first vertex OK */
+ a= startvert-1;
+ ver= re->vertnodes[a>>8].vert + (a & 255);
+
+ if( (!fsob->fluidsimSettings) || (!fsob->fluidsimSettings->meshSurfNormals) ) return 0;
+ vverts = fsob->fluidsimSettings->meshSurfNormals;
+ //fprintf(stderr, "GZ_VEL obj '%s', calc load_fluidsimspeedvectors\n",fsob->id.name); // NT DEBUG
+
+ if( endvert-startvert != fsob->fluidsimSettings->meshSurface->totvert ) {
+ //fprintf(stderr, "load_fluidsimspeedvectors - modified fluidsim mesh, not using speed vectors (%d,%d)...\n", endvert-startvert , fsob->fluidsimSettings->meshSurface->totvert); // DEBUG
+ return 0;
+ }
+
+ for(a=startvert; a<endvert; a++, vectors+=2) {
+ if((a & 255)==0)
+ ver= re->vertnodes[a>>8].vert;
+ else
+ ver++;
+
+ // get fluid velocity
+ fsvec[3] = 0.;
+ //fsvec[0] = fsvec[1] = fsvec[2] = fsvec[3] = 0.; fsvec[2] = 2.; // NT fixed test
+ for(j=0;j<3;j++) fsvec[j] = vverts[a-startvert].co[j];
+
+ // transform (=rotate) to cam space
+ camco[0]= imat[0][0]*fsvec[0] + imat[0][1]*fsvec[1] + imat[0][2]*fsvec[2];
+ camco[1]= imat[1][0]*fsvec[0] + imat[1][1]*fsvec[1] + imat[1][2]*fsvec[2];
+ camco[2]= imat[2][0]*fsvec[0] + imat[2][1]*fsvec[1] + imat[2][2]*fsvec[2];
+
+ // get homogenous coordinates
+ projectverto(camco, re->winmat, hoco);
+
+ /* now map hocos to screenspace, uses very primitive clip still */
+ // use ho[3] of original vertex, xy component of vel. direction
+ if(ver->ho[3]<0.1f) div= 10.0f;
+ else div= 1.0f/ver->ho[3];
+ zco[0]= zmulx*hoco[0]*div;
+ zco[1]= zmuly*hoco[1]*div;
+
+ // maximize speed as usual
+ len= zco[0]*zco[0] + zco[1]*zco[1];
+ if(len > winsq) {
+ len= winroot/sqrt(len);
+ zco[0]*= len; zco[1]*= len;
+ }
+
+ speed= RE_vertren_get_winspeed(re, ver, 1);
+ // set both to the same value
+ speed[0]= speed[2]= zco[0];
+ speed[1]= speed[3]= zco[1];
+ //if(a<20) fprintf(stderr,"speed %d %f,%f | camco %f,%f,%f | hoco %f,%f,%f,%f \n", a, speed[0], speed[1], camco[0],camco[1], camco[2], hoco[0],hoco[1], hoco[2],hoco[3]); // NT DEBUG
+ }
+
+ return 1;
+}
+
/* makes copy per object of all vectors */
/* result should be that we can free entire database */
static void copy_dbase_object_vectors(Render *re, ListBase *lb)
@@ -3236,13 +3453,21 @@ void RE_Database_FromScene_Vectors(Render *re, Scene *sce)
// printf("speed table: missing object %s\n", obren->ob->id.name+2);
continue;
}
- /* check if both have same amounts of vertices */
- if(obren->endvert-obren->startvert != oldobren->endvert-oldobren->startvert) {
- printf("Warning: object %s has different amount of vertices on other frame\n", obren->ob->id.name+2);
- continue;
- }
-
- calculate_speedvectors(re, oldobren->vectors, obren->startvert, obren->endvert, step);
+
+ // NT check for fluidsim special treatment
+ if((obren->ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) && (obren->ob->fluidsimSettings->type & OB_FLUIDSIM_DOMAIN)) {
+ // use preloaded per vertex simulation data , only does calculation for step=1
+ // NOTE/FIXME - velocities and meshes loaded unnecessarily often during the database_fromscene_vectors calls...
+ load_fluidsimspeedvectors(re, oldobren->vectors, obren->startvert, obren->endvert, step, obren->ob);
+ } else {
+ /* check if both have same amounts of vertices */
+ if(obren->endvert-obren->startvert != oldobren->endvert-oldobren->startvert) {
+ printf("Warning: object %s has different amount of vertices on other frame\n", obren->ob->id.name+2);
+ continue;
+ }
+
+ calculate_speedvectors(re, oldobren->vectors, obren->startvert, obren->endvert, step);
+ } // not fluidsim
}
}
}
diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c
index 9f43e06926c..f584109db81 100644
--- a/source/blender/src/buttons_object.c
+++ b/source/blender/src/buttons_object.c
@@ -1377,6 +1377,27 @@ void do_object_panels(unsigned short event)
/* write config files (currently no simulation) */
fluidsimBake(ob);
break;
+ case B_FLUIDSIM_MAKEPART:
+ ob= OBACT;
+ {
+ PartEff *paf= NULL;
+ /* prepare fluidsim particle display */
+ // simplified delete effect, create new - recalc some particles...
+ if(ob==NULL || ob->type!=OB_MESH) break;
+ ob->fluidsimSettings->type = 0;
+ // reset type, and init particle system once normally
+ eff= ob->effect.first;
+ //if((eff) && (eff->flag & SELECT)) { BLI_remlink(&ob->effect, eff); free_effect(eff); }
+ if(!eff){ copy_act_effect(ob); DAG_scene_sort(G.scene); }
+ paf = give_parteff(ob);
+ paf->totpart = 1000; paf->sta = paf->end = 1.0; // generate some particles...
+ build_particle_system(ob);
+
+ ob->fluidsimSettings->type = OB_FLUIDSIM_PARTICLE;
+ }
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSOBJECT, 0);
+ break;
case B_FLUIDSIM_SELDIR: {
ScrArea *sa = closest_bigger_area();
ob= OBACT;
@@ -2290,6 +2311,7 @@ static void object_panel_fluidsim(Object *ob)
uiDefButS(block, ROW, REDRAWBUTSOBJECT ,"Inflow", 90, yline, 70,objHeight, &fss->type, 15.0, OB_FLUIDSIM_INFLOW, 20.0, 4.0, "Object adds fluid to the simulation.");
uiDefButS(block, ROW, REDRAWBUTSOBJECT ,"Outflow", 160, yline, 70,objHeight, &fss->type, 15.0, OB_FLUIDSIM_OUTFLOW, 20.0, 5.0, "Object removes fluid from the simulation.");
+ uiDefButS(block, ROW, B_FLUIDSIM_MAKEPART ,"Particle", 230, yline, 70,objHeight, &fss->type, 15.0, OB_FLUIDSIM_PARTICLE,20.0, 3.0, "Object is a fixed obstacle.");
uiBlockEndAlign(block);
yline -= lineHeight;
yline -= 2*separateHeight;
@@ -2304,7 +2326,11 @@ static void object_panel_fluidsim(Object *ob)
elbeemEstimateMemreq(fss->resolutionxyz,
ob->fluidsimSettings->bbSize[0],ob->fluidsimSettings->bbSize[1],ob->fluidsimSettings->bbSize[2], fss->maxRefine, memString);
- uiDefButBitS(block, TOG, 1, REDRAWBUTSOBJECT, "Advanced>>", 0,yline, 75,objHeight, &fss->show_advancedoptions, 0, 0, 0, 0, "Show advanced domain options.");
+ //uiDefButBitS(block, TOG, 1, REDRAWBUTSOBJECT, "Advanced>>", 0,yline, 75,objHeight, &fss->show_advancedoptions, 0, 0, 0, 0, "Show advanced domain options.");
+ uiDefButS(block, ROW, REDRAWBUTSOBJECT, "Std", 0,yline, 25,objHeight, &fss->show_advancedoptions, 16.0, 0, 20.0, 0, "Show standard domain options.");
+ uiDefButS(block, ROW, REDRAWBUTSOBJECT, "Adv", 25,yline, 25,objHeight, &fss->show_advancedoptions, 16.0, 1, 20.0, 1, "Show advanced domain options.");
+ uiDefButS(block, ROW, REDRAWBUTSOBJECT, "Bnd", 50,yline, 25,objHeight, &fss->show_advancedoptions, 16.0, 2, 20.0, 2, "Show domain boundary options.");
+
uiDefBut(block, BUT, B_FLUIDSIM_BAKE, "BAKE",90, yline,210,objHeight, NULL, 0.0, 0.0, 10, 0, "Perform simulation and output and surface&preview meshes for each frame.");
yline -= lineHeight;
yline -= 2*separateHeight;
@@ -2324,6 +2350,7 @@ static void object_panel_fluidsim(Object *ob)
yline -= lineHeight;
yline -= 2*separateHeight;
+ if((fss->guiDisplayMode<1) || (fss->guiDisplayMode>3)){ fss->guiDisplayMode=2; } // can be changed by particle setting
uiDefBut(block, LABEL, 0, "Disp.-Qual.:", 0,yline, 90,objHeight, NULL, 0.0, 0, 0, 0, "");
uiDefButS(block, MENU, B_FLUIDSIM_FORCEREDRAW, "GuiDisplayMode%t|Geometry %x1|Preview %x2|Final %x3",
90,yline,105,objHeight, &fss->guiDisplayMode, 0, 0, 0, 0, "How to display the fluid mesh in the blender gui.");
@@ -2335,7 +2362,7 @@ static void object_panel_fluidsim(Object *ob)
uiDefIconBut(block, BUT, B_FLUIDSIM_SELDIR, ICON_FILESEL, 0, yline, 20, objHeight, 0, 0, 0, 0, 0, "Select Directory (and/or filename prefix) to store baked fluid simulation files in");
uiDefBut(block, TEX, B_FLUIDSIM_FORCEREDRAW,"", 20, yline, 280, objHeight, fss->surfdataPath, 0.0,79.0, 0, 0, "Enter Directory (and/or filename prefix) to store baked fluid simulation files in");
// FIXME what is the 79.0 above?
- } else {
+ } else if(fss->show_advancedoptions == 1) {
// advanced options
uiBlockBeginAlign(block);
uiDefBut(block, LABEL, 0, "Gravity:", 0, yline, 90,objHeight, NULL, 0.0, 0, 0, 0, "");
@@ -2362,7 +2389,7 @@ static void object_panel_fluidsim(Object *ob)
yline -= 1*separateHeight;
uiDefBut(block, LABEL, 0, "Realworld-size:", 0,yline,150,objHeight, NULL, 0.0, 0, 0, 0, "");
- uiDefButF(block, NUM, B_DIFF, "", 150, yline,150,objHeight, &fss->realsize, 0.001, 1.0, 10, 0, "Size of the simulation domain in meters.");
+ uiDefButF(block, NUM, B_DIFF, "", 150, yline,150,objHeight, &fss->realsize, 0.001, 10.0, 10, 0, "Size of the simulation domain in meters.");
yline -= lineHeight;
yline -= 2*separateHeight;
@@ -2374,6 +2401,31 @@ static void object_panel_fluidsim(Object *ob)
uiDefButF(block, NUM, B_DIFF, "", 150, yline,150,objHeight, &fss->gstar, 0.001, 0.10, 10,0, "Allowed compressibility due to gravitational force for standing fluid (directly affects simulation step size).");
yline -= lineHeight;
+ } else if(fss->show_advancedoptions == 2) {
+ // copied from obstacle...
+ //yline -= lineHeight + 5;
+ uiDefBut(block, LABEL, 0, "Domain boundary type settings:", 0,yline,300,objHeight, NULL, 0.0, 0, 0, 0, "");
+ yline -= lineHeight;
+ uiBlockBeginAlign(block);
+ uiDefButI(block, ROW, REDRAWBUTSOBJECT ,"Noslip", 00, yline,100,objHeight, &fss->typeFlags, 15.0, OB_FSBND_NOSLIP, 20.0, 1.0, "Obstacle causes zero normal and tangential velocity (=sticky). Default for all. Only option for moving objects.");
+ uiDefButI(block, ROW, REDRAWBUTSOBJECT ,"Part", 100, yline,100,objHeight, &fss->typeFlags, 15.0, OB_FSBND_PARTSLIP, 20.0, 2.0, "Mix between no-slip and free-slip. Non moving objects only!");
+ uiDefButI(block, ROW, REDRAWBUTSOBJECT ,"Free", 200, yline,100,objHeight, &fss->typeFlags, 15.0, OB_FSBND_FREESLIP, 20.0, 3.0, "Obstacle only causes zero normal velocity (=not sticky). Non moving objects only!");
+ uiBlockEndAlign(block);
+ yline -= lineHeight;
+ if(fss->typeFlags&OB_FSBND_PARTSLIP) {
+ uiDefBut(block, LABEL, 0, "PartSlipValue:", 0,yline,150,objHeight, NULL, 0.0, 0, 0, 0, "");
+ uiDefButF(block, NUM, B_DIFF, "", 150, yline,150,objHeight, &fss->partSlipValue, 0.0, 0.1, 10,0, ".");
+ yline -= lineHeight;
+ }
+
+ uiDefBut(block, LABEL, 0, "Generate Particles:", 0,yline,200,objHeight, NULL, 0.0, 0, 0, 0, "");
+ uiDefButF(block, NUM, B_DIFF, "", 200, yline,100,objHeight, &fss->generateParticles, 0.0, 10.0, 10,0, "Amount of particles to generate (0=off, 1=normal, >1=more).");
+ yline -= lineHeight;
+
+ uiDefBut(block, LABEL, 0, "Generate&Use SpeedVecs:", 0,yline,200,objHeight, NULL, 0.0, 0, 0, 0, "");
+ uiDefButBitI(block, TOG, OB_FSDOMAIN_NOVECGEN, REDRAWBUTSOBJECT, "Disable", 200, yline,100,objHeight, &fss->typeFlags, 0, 0, 0, 0, "Default is to generate and use fluidsim vertex speed vectors, this option switches calculation off during bake, and disables loading.");
+ yline -= lineHeight;
+ // copied from obstacle...
}
}
else if(
@@ -2390,15 +2442,64 @@ static void object_panel_fluidsim(Object *ob)
uiDefButF(block, NUM, B_DIFF, "Z:", 200, yline, 100,objHeight, &fss->iniVelz, -1000.1, 1000.1, 10, 0, "Fluid velocity in Z direction");
uiBlockEndAlign(block);
yline -= lineHeight;
+
+ if(fss->type == OB_FLUIDSIM_INFLOW) {
+ uiDefBut(block, LABEL, 0, "Local Inflow Coords", 0,yline,200,objHeight, NULL, 0.0, 0, 0, 0, "");
+ uiDefButBitI(block, TOG, OB_FSINFLOW_LOCALCOORD, REDRAWBUTSOBJECT, "Enable", 200, yline,100,objHeight, &fss->typeFlags, 0, 0, 0, 0, "Use local coordinates for inflow (e.g. for rotating objects).");
+ yline -= lineHeight;
+ }
}
- else if(
- (fss->type == OB_FLUIDSIM_OBSTACLE)
- || (fss->type == OB_FLUIDSIM_OUTFLOW)
- ) {
+ else if( (fss->type == OB_FLUIDSIM_OUTFLOW) ) {
yline -= lineHeight + 5;
uiDefBut(block, LABEL, 0, "No additional settings as of now...", 0,yline,300,objHeight, NULL, 0.0, 0, 0, 0, "");
+ }
+ else if( (fss->type == OB_FLUIDSIM_OBSTACLE) ) {
+ yline -= lineHeight + 5;
+
+ uiBlockBeginAlign(block);
+ uiDefButI(block, ROW, REDRAWBUTSOBJECT ,"Noslip", 00, yline,100,objHeight, &fss->typeFlags, 15.0, OB_FSBND_NOSLIP, 20.0, 1.0, "Obstacle causes zero normal and tangential velocity (=sticky). Default for all. Only option for moving objects.");
+ uiDefButI(block, ROW, REDRAWBUTSOBJECT ,"Part", 100, yline,100,objHeight, &fss->typeFlags, 15.0, OB_FSBND_PARTSLIP, 20.0, 2.0, "Mix between no-slip and free-slip. Non moving objects only!");
+ uiDefButI(block, ROW, REDRAWBUTSOBJECT ,"Free", 200, yline,100,objHeight, &fss->typeFlags, 15.0, OB_FSBND_FREESLIP, 20.0, 3.0, "Obstacle only causes zero normal velocity (=not sticky). Non moving objects only!");
+ uiBlockEndAlign(block);
+ yline -= lineHeight;
+
+ if(fss->typeFlags&OB_FSBND_PARTSLIP) {
+ uiDefBut(block, LABEL, 0, "PartSlipValue:", 0,yline,150,objHeight, NULL, 0.0, 0, 0, 0, "");
+ uiDefButF(block, NUM, B_DIFF, "", 150, yline,150,objHeight, &fss->partSlipValue, 0.0, 0.1, 10,0, ".");
+ yline -= lineHeight;
+ }
+
yline -= lineHeight;
}
+ else if(fss->type == OB_FLUIDSIM_PARTICLE) {
+
+ if(fss->guiDisplayMode==0) fss->guiDisplayMode=2; // default drops
+ uiDefBut(block, LABEL, 0, "Part.-Type:", 0,yline,100,objHeight, NULL, 0.0, 0, 0, 0, "");
+ // TODO make toggle buttons
+ //uiDefButS(block, MENU, B_FLUIDSIM_FORCEREDRAW, "Gui%t|Bubble %x2|Drop %x4|Newparts %x8|Float %x16",
+ //100,yline,200,objHeight, &fss->guiDisplayMode, 0, 0, 0, 0, "Which type of particles to display.");
+ //uiDefButS(block, MENU, B_DIFF, "Render%t|Geometry %x1|Preview %x2|Final %x3",
+ //195,yline,105,objHeight, &fss->renderDisplayMode, 0, 0, 0, 0, "How to display the fluid mesh for rendering.");
+ uiDefBut(block, LABEL, 0, "Drops", 100,yline,200,objHeight, NULL, 0.0, 0, 0, 0, "");
+ fss->guiDisplayMode = 4; // fix to drops for now
+ yline -= lineHeight;
+
+ uiDefBut(block, LABEL, 0, "Size Influence:", 0,yline,150,objHeight, NULL, 0.0, 0, 0, 0, "");
+ uiDefButF(block, NUM, B_DIFF, "", 150, yline,150,objHeight, &fss->particleInfSize, 0.0, 2.0, 10,0, "Amount of particle size scaling: 0=off (all same size), 1=full (range 0.2-2.0), >1=stronger.");
+ yline -= lineHeight;
+ uiDefBut(block, LABEL, 0, "Alpha Influence:", 0,yline,150,objHeight, NULL, 0.0, 0, 0, 0, "");
+ uiDefButF(block, NUM, B_DIFF, "", 150, yline,150,objHeight, &fss->particleInfAlpha, 0.0, 2.0, 10,0, "Amount of particle alpha change, inverse of size influence: 0=off (all same alpha), 1=full (large particles get lower alphas, smaller ones higher values).");
+ yline -= lineHeight;
+
+ yline -= 1*separateHeight;
+
+ // FSPARTICLE also select input files
+ uiDefIconBut(block, BUT, B_FLUIDSIM_SELDIR, ICON_FILESEL, 0, yline, 20, objHeight, 0, 0, 0, 0, 0, "Select Directory (and/or filename prefix) to store baked fluid simulation files in");
+ uiDefBut(block, TEX, B_FLUIDSIM_FORCEREDRAW,"", 20, yline, 280, objHeight, fss->surfdataPath, 0.0,79.0, 0, 0, "Enter Directory (and/or filename prefix) to store baked fluid simulation files in");
+ yline -= lineHeight;
+
+
+ }
else {
yline -= lineHeight + 5;
/* not yet set */
diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c
index 7a09fc9a80d..697dcce20cb 100644
--- a/source/blender/src/drawobject.c
+++ b/source/blender/src/drawobject.c
@@ -67,6 +67,8 @@
#include "DNA_userdef_types.h"
#include "DNA_view3d_types.h"
#include "DNA_world_types.h"
+// FSPARTICLE
+#include "DNA_object_fluidsim.h"
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
@@ -2502,7 +2504,10 @@ static void draw_particle_system(Object *ob, PartEff *paf)
int a, totpart;
pa= paf->keys;
- if(pa==NULL) {
+ // FSPARTICLE always rebuild fluid particle system upon change...
+ if( (pa==NULL)
+ || ( (ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) && (ob->fluidsimSettings) && (ob->fluidsimSettings->type == OB_FLUIDSIM_PARTICLE))
+ ) {
build_particle_system(ob);
pa= paf->keys;
if(pa==NULL) return;
@@ -2558,7 +2563,10 @@ static void draw_static_particle_system(Object *ob, PartEff *paf, int dt)
int a, use_norm=0, totpart;
pa= paf->keys;
- if(pa==NULL) {
+ // FSPARTICLE always rebuild upon change...
+ if( (pa==NULL)
+ || ( (ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) && (ob->fluidsimSettings) && (ob->fluidsimSettings->type == OB_FLUIDSIM_PARTICLE))
+ ) {
build_particle_system(ob);
pa= paf->keys;
if(pa==NULL) return;
diff --git a/source/blender/src/editipo.c b/source/blender/src/editipo.c
index b8953a63fc6..aaf60c62ceb 100644
--- a/source/blender/src/editipo.c
+++ b/source/blender/src/editipo.c
@@ -60,6 +60,7 @@
#include "DNA_lamp_types.h"
#include "DNA_material_types.h"
#include "DNA_object_types.h"
+#include "DNA_object_fluidsim.h"
#include "DNA_screen_types.h"
#include "DNA_scene_types.h"
#include "DNA_space_types.h"
@@ -122,6 +123,7 @@ extern int snd_ar[];
extern int ac_ar[];
extern int co_ar[];
extern int te_ar[];
+extern int fluidsim_ar[]; // NT
/* forwards */
#define BEZSELECTED(bezt) (((bezt)->f1 & 1) || ((bezt)->f2 & 1) || ((bezt)->f3 & 1))
@@ -428,6 +430,32 @@ static void make_ob_editipo(Object *ob, SpaceIpo *si)
ei++;
}
+ //fprintf(stderr,"FSIMAKE_OPBJ call %d \n", si->totipo);
+}
+
+// copied from make_seq_editipo
+static void make_fluidsim_editipo(SpaceIpo *si) // NT
+{
+ EditIpo *ei;
+ int a;
+ char *name;
+ ei= si->editipo= MEM_callocN(FLUIDSIM_TOTIPO*sizeof(EditIpo), "fluidsim_editipo");
+ si->totipo = FLUIDSIM_TOTIPO;
+ for(a=0; a<FLUIDSIM_TOTIPO; a++) {
+ //fprintf(stderr,"FSINAME %d %d \n",a,fluidsim_ar[a], (int)(getname_fluidsim_ei(fluidsim_ar[a])) );
+ name = getname_fluidsim_ei(fluidsim_ar[a]);
+ strcpy(ei->name, name);
+ ei->adrcode= fluidsim_ar[a];
+ ei->col= ipo_rainbow(a, FLUIDSIM_TOTIPO);
+ ei->icu= find_ipocurve(si->ipo, ei->adrcode);
+ if(ei->icu) {
+ ei->flag = ei->icu->flag;
+ }
+ //else { ei->flag |= IPO_VISIBLE; }
+ //fprintf(stderr,"FSIMAKE eif%d,icuf%d icu%d %d|%d\n", ei->flag,ei->icu->flag, (int)ei->icu, IPO_VISIBLE,IPO_SELECT);
+ //fprintf(stderr,"FSIMAKE eif%d icu%d %d|%d\n", ei->flag, (int)ei->icu, IPO_VISIBLE,IPO_SELECT);
+ ei++;
+ }
}
static void make_seq_editipo(SpaceIpo *si)
@@ -886,6 +914,12 @@ static void make_editipo(void)
ob->ipowin= ID_PO;
}
}
+ else if(G.sipo->blocktype==ID_FLUIDSIM) {
+ if (ob) { // NT
+ ob->ipowin= ID_FLUIDSIM;
+ make_fluidsim_editipo(G.sipo);
+ }
+ }
if(G.sipo->editipo==0) return;
@@ -1059,6 +1093,13 @@ static void get_ipo_context(short blocktype, ID **from, Ipo **ipo, char *actname
// if(sound) *ipo= sound->ipo;
// }
}
+ else if(blocktype==ID_FLUIDSIM) {
+ if(ob && ( ob->fluidsimFlag & OB_FLUIDSIM_ENABLE)) {
+ FluidsimSettings *fss= ob->fluidsimSettings;
+ *from= (ID *)ob;
+ if(fss) *ipo= fss->ipo;
+ }
+ }
}
/* called on each redraw, check if editipo data has to be remade */
@@ -1674,6 +1715,17 @@ Ipo *verify_ipo(ID *from, short blocktype, char *actname, char *constname)
}
return NULL;
}
+ else if(blocktype== ID_FLUIDSIM) {
+ Object *ob= (Object *)from;
+ if(ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) {
+ FluidsimSettings *fss= ob->fluidsimSettings;
+ if(fss->ipo==NULL) {
+ fss->ipo= add_ipo("FluidsimIpo", ID_FLUIDSIM);
+ //fprintf(stderr,"FSIPO NEW!\n");
+ }
+ return fss->ipo;
+ }
+ }
}
break;
case ID_MA:
diff --git a/source/blender/src/editipo_lib.c b/source/blender/src/editipo_lib.c
index 22587c2da3c..ed9466a3bf9 100644
--- a/source/blender/src/editipo_lib.c
+++ b/source/blender/src/editipo_lib.c
@@ -93,6 +93,7 @@ char *snd_ic_names[SND_TOTNAM] = { "Vol", "Pitch", "Pan", "Atten" };
char *ac_ic_names[AC_TOTNAM] = {"LocX", "LocY", "LocZ", "SizeX", "SizeY",
"SizeZ", "QuatW", "QuatX", "QuatY", "QuatZ"};
char *ic_name_empty[1] ={ "" };
+char *fluidsim_ic_names[FLUIDSIM_TOTNAM] = { "Fac-Visc", "Fac-Time", "GravX","GravY","GravZ", "VelX","VelY","VelZ", "Active" };
char *getname_ac_ei(int nr)
{
@@ -198,6 +199,12 @@ char *getname_snd_ei(int nr)
return ic_name_empty[0];
}
+char *getname_fluidsim_ei(int nr)
+{
+ if(nr <= FLUIDSIM_TOTIPO) return fluidsim_ic_names[nr-1];
+ return ic_name_empty[0];
+}
+
void boundbox_ipocurve(IpoCurve *icu)
{
diff --git a/source/blender/src/editipo_mods.c b/source/blender/src/editipo_mods.c
index 83aec9ccbee..85119d9a2cc 100644
--- a/source/blender/src/editipo_mods.c
+++ b/source/blender/src/editipo_mods.c
@@ -178,6 +178,7 @@ void swap_visible_editipo(void)
}
}
else ei->flag &= ~IPO_VISIBLE;
+ printf("FSISWAP %d, icu%d %d|%d\n", ei->flag, (int)ei->icu, IPO_VISIBLE,IPO_SELECT);
ei++;
}
diff --git a/source/blender/src/fluidsim.c b/source/blender/src/fluidsim.c
index bab93250d23..a608b079266 100644
--- a/source/blender/src/fluidsim.c
+++ b/source/blender/src/fluidsim.c
@@ -52,6 +52,7 @@
#include "DNA_scene_types.h"
#include "DNA_camera_types.h"
#include "DNA_screen_types.h"
+#include "DNA_ipo_types.h"
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
@@ -69,6 +70,9 @@
#include "BKE_DerivedMesh.h"
#include "BKE_ipo.h"
#include "LBM_fluidsim.h"
+// FIXME move?
+// TODO FIXME DOUBLE elbeem.h! in intern/extern...
+#include "elbeem.h"
#include "BLI_editVert.h"
#include "BIF_editdeform.h"
@@ -80,7 +84,6 @@
#include "BSE_headerbuttons.h"
#include "mydevice.h"
-
#include "SDL.h"
#include "SDL_thread.h"
#include "SDL_mutex.h"
@@ -99,6 +102,9 @@
#undef main
#endif
+// from DerivedMesh.c
+void initElbeemMesh(struct Object *ob, int *numVertices, float **vertices, int *numTriangles, int **triangles);
+
/* from header info.c */
extern int start_progress_bar(void);
extern void end_progress_bar(void);
@@ -179,6 +185,7 @@ FluidsimSettings *fluidsimSettingsNew(struct Object *srcob)
fss->orgMesh = (Mesh *)srcob->data;
fss->meshSurface = NULL;
fss->meshBB = NULL;
+ fss->meshSurfNormals = NULL;
// first init of bounding box
fss->bbStart[0] = 0.0;
@@ -187,7 +194,15 @@ FluidsimSettings *fluidsimSettingsNew(struct Object *srcob)
fss->bbSize[0] = 1.0;
fss->bbSize[1] = 1.0;
fss->bbSize[2] = 1.0;
- fluidsimGetAxisAlignedBB(srcob->data, srcob->obmat, fss->bbStart, fss->bbSize);
+ fluidsimGetAxisAlignedBB(srcob->data, srcob->obmat, fss->bbStart, fss->bbSize, &fss->meshBB);
+
+ fss->typeFlags = 0;
+ fss->partSlipValue = 0.0;
+
+ fss->generateParticles = 0.0;
+ fss->particleInfSize = 0.0;
+ fss->particleInfAlpha = 0.0;
+
return fss;
}
@@ -202,6 +217,16 @@ void fluidsimSettingsFree(FluidsimSettings *fss)
MEM_freeN(freeFsMesh);
}
+ freeFsMesh = fss->meshBB;
+ if(freeFsMesh) { // same as before...
+ if(freeFsMesh->mvert) MEM_freeN(freeFsMesh->mvert);
+ if(freeFsMesh->medge) MEM_freeN(freeFsMesh->medge);
+ if(freeFsMesh->mface) MEM_freeN(freeFsMesh->mface);
+ MEM_freeN(freeFsMesh);
+ }
+
+ if(fss->meshSurfNormals) MEM_freeN(fss->meshSurfNormals);
+
MEM_freeN(fss);
}
@@ -213,17 +238,121 @@ void fluidsimGetGeometryObjFilename(struct Object *ob, char *dst) { //, char *sr
}
+
+
+/* ******************************************************************************** */
+/* ********************** fluid sim channel helper functions ********************** */
+/* ******************************************************************************** */
+
+// no. of entries for the two channel sizes
+#define CHANNEL_FLOAT 1
+#define CHANNEL_VEC 3
+
+#define FS_FREE_ONECHANNEL(c,str) { \
+ if(c){ MEM_freeN(c); c=NULL; } \
+} // end ONE CHANN, debug: fprintf(stderr,"freeing " str " \n");
+
+#define FS_FREE_CHANNELS { \
+ FS_FREE_ONECHANNEL(timeAtIndex,"timeAtIndex");\
+ FS_FREE_ONECHANNEL(timeAtFrame,"timeAtFrame");\
+ FS_FREE_ONECHANNEL(channelDomainTime,"channelDomainTime"); \
+ FS_FREE_ONECHANNEL(channelDomainGravity,"channelDomainGravity");\
+ FS_FREE_ONECHANNEL(channelDomainViscosity,"channelDomainViscosity");\
+ for(i=0;i<256;i++) { \
+ FS_FREE_ONECHANNEL(channelObjMove[i][0],"channelObjMove0"); \
+ FS_FREE_ONECHANNEL(channelObjMove[i][1],"channelObjMove1"); \
+ FS_FREE_ONECHANNEL(channelObjMove[i][2],"channelObjMove2"); \
+ FS_FREE_ONECHANNEL(channelObjInivel[i],"channelObjInivel"); \
+ FS_FREE_ONECHANNEL(channelObjActive[i],"channelObjActive"); \
+ } \
+} // end FS FREE CHANNELS
+
+
+// simplify channels before printing
+// for API this is done anyway upon init
+static void fluidsimPrintChannel(FILE *file, float *channel, int paramsize, char *str, int entries)
+{
+ int i,j;
+ int channelSize = paramsize;
+
+ if(entries==3) {
+ elbeemSimplifyChannelVec3( channel, &channelSize);
+ } else if(entries==1) {
+ elbeemSimplifyChannelFloat( channel, &channelSize);
+ } else {
+ // invalid, cant happen?
+ }
+
+ fprintf(file, " CHANNEL %s = \n", str);
+ for(i=0; i<channelSize;i++) {
+ fprintf(file," ");
+ for(j=0;j<=entries;j++) { // also print time value
+ fprintf(file," %f ", channel[i*(entries+1)+j] );
+ if(j==entries-1){ fprintf(file," "); }
+ }
+ fprintf(file," \n");
+ }
+
+ fprintf(file, " ; \n" );
+}
+
+
+static void fluidsimInitChannel(float **setchannel, int size, float *time,
+ int *icuIds, float *defaults, Ipo* ipo, int entries) {
+ int i,j;
+ IpoCurve* icus[3];
+ char *cstr = NULL;
+ float *channel = NULL;
+ float aniFrlen = G.scene->r.framelen;
+ if((entries<1) || (entries>3)) {
+ printf("fluidsimInitChannel::Error - invalid no. of entries: %d\n",entries);
+ entries = 1;
+ }
+
+ cstr = "fluidsiminit_channelfloat";
+ if(entries>1) cstr = "fluidsiminit_channelvec";
+ channel = MEM_callocN( size* (entries+1)* sizeof(float), cstr );
+
+ if(ipo) {
+ for(i=0; i<entries; i++) icus[i] = find_ipocurve(ipo, icuIds[i] );
+ } else {
+ for(i=0; i<entries; i++) icus[i] = NULL;
+ }
+
+ for(j=0; j<entries; j++) {
+ if(icus[j]) {
+ for(i=1; i<=size; i++) {
+ calc_icu(icus[j], aniFrlen*((float)i) );
+ channel[(i-1)*(entries+1) + j] = icus[j]->curval;
+ }
+ } else {
+ for(i=1; i<=size; i++) { channel[(i-1)*(entries+1) + j] = defaults[j]; }
+ }
+ }
+ // set time values
+ for(i=1; i<=size; i++) {
+ channel[(i-1)*(entries+1) + entries] = time[i];
+ }
+
+ *setchannel = channel;
+}
+
+
+
+/* ******************************************************************************** */
/* ********************** simulation thread ************************* */
+/* ******************************************************************************** */
+
SDL_mutex *globalBakeLock=NULL;
int globalBakeState = 0; // 0 everything ok, -1 abort simulation, 1 sim done
int globalBakeFrame = 0;
// run simulation in seperate thread
-int fluidsimSimulateThread(void *ptr) {
- char* fnameCfgPath = (char*)(ptr);
- int ret;
+int fluidsimSimulateThread(void) { // *ptr) {
+ //char* fnameCfgPath = (char*)(ptr);
+ int ret=0;
- ret = performElbeemSimulation(fnameCfgPath);
+ ret = elbeemSimulate();
SDL_mutexP(globalBakeLock);
if(globalBakeState==0) {
// if no error, set to normal exit
@@ -242,31 +371,27 @@ void simulateThreadIncreaseFrame(void) {
SDL_mutexV(globalBakeLock);
}
-/* remember files created during bake for deletion */
- //createdFiles[numCreatedFiles] = (char *)malloc(strlen(str)+1);
- //strcpy(createdFiles[numCreatedFiles] ,str);
-#define ADD_CREATEDFILE(str) \
- if(numCreatedFiles<255) {\
- createdFiles[numCreatedFiles] = strdup(str); \
- numCreatedFiles++; }
+/* ******************************************************************************** */
/* ********************** write fluidsim config to file ************************* */
+/* ******************************************************************************** */
+
void fluidsimBake(struct Object *ob)
{
FILE *fileCfg;
int i;
struct Object *fsDomain = NULL;
- FluidsimSettings *fssDomain;
+ FluidsimSettings *domainSettings;
struct Object *obit = NULL; /* object iterator */
int origFrame = G.scene->r.cfra;
char debugStrBuffer[256];
int dirExist = 0;
int gridlevels = 0;
- char *createdFiles[256];
- int numCreatedFiles = 0;
- int doDeleteCreatedFiles = 1;
int simAborted = 0; // was the simulation aborted by user?
- char *delEnvStr = "BLENDER_DELETEELBEEMFILES";
+ int doExportOnly = 0;
+ char *exportEnvStr = "BLENDER_ELBEEMEXPORTONLY";
+ const char *strEnvName = "BLENDER_ELBEEMDEBUG"; // from blendercall.cpp
+ //char *channelNames[3] = { "translation","rotation","scale" };
char *suffixConfig = "fluidsim.cfg";
char *suffixSurface = "fluidsurface";
@@ -275,17 +400,46 @@ void fluidsimBake(struct Object *ob)
char targetFile[FILE_MAXDIR+FILE_MAXFILE]; // temp. store filename from targetDir for access
int outStringsChanged = 0; // modified? copy back before baking
int haveSomeFluid = 0; // check if any fluid objects are set
- int noFrames = G.scene->r.efra - 1 /*G.scene->r.sfra*/;
- const char *strEnvName = "BLENDER_ELBEEMDEBUG"; // from blendercall.cpp
+ // config vars, inited before either export or run...
+ double calcViscosity = 0.0;
+ int noFrames;
+ double aniFrameTime;
+ float aniFrlen;
+ int channelObjCount;
+ float *bbStart = NULL;
+ float *bbSize = NULL;
+ float domainMat[4][4];
+ float invDomMat[4][4];
+ // channel data
+ int allchannelSize; // fixed by no. of frames
+ int startFrame = 1; // dont use G.scene->r.sfra here, always start with frame 1
+ // easy frame -> sim time calc
+ float *timeAtFrame=NULL, *timeAtIndex=NULL;
+ // domain
+ float *channelDomainTime = NULL;
+ float *channelDomainViscosity = NULL;
+ float *channelDomainGravity = NULL;
+ // objects (currently max. 256 objs)
+ float *channelObjMove[256][3]; // object movments , 0=trans, 1=rot, 2=scale
+ float *channelObjInivel[256]; // initial velocities
+ float *channelObjActive[256]; // obj active channel
if(getenv(strEnvName)) {
int dlevel = atoi(getenv(strEnvName));
elbeemSetDebugLevel(dlevel);
- snprintf(debugStrBuffer,256,"fluidsimBake::msg: Debug messages activated due to envvar '%s'\n",strEnvName);
+ snprintf(debugStrBuffer,256,"fluidsimBake::msg: Debug messages activated due to envvar '%s'\n",strEnvName);
+ elbeemDebugOut(debugStrBuffer);
+ }
+ if(getenv(exportEnvStr)) {
+ doExportOnly = atoi(getenv(exportEnvStr));
+ snprintf(debugStrBuffer,256,"fluidsimBake::msg: Exporting mode set to '%d' due to envvar '%s'\n",doExportOnly, exportEnvStr);
elbeemDebugOut(debugStrBuffer);
}
+ // make sure it corresponds to startFrame setting
+ // old: noFrames = G.scene->r.efra - G.scene->r.sfra +1;
+ noFrames = G.scene->r.efra - 0;
if(noFrames<=0) {
pupmenu("Fluidsim Bake Error%t|No frames to export - check your animation range settings. Aborted%x0");
return;
@@ -296,36 +450,37 @@ void fluidsimBake(struct Object *ob)
if((obit->fluidsimFlag & OB_FLUIDSIM_ENABLE)&&(obit->type==OB_MESH)) {
if(obit->fluidsimSettings->type == OB_FLUIDSIM_DOMAIN) {
if(obit != ob) {
- snprintf(debugStrBuffer,256,"fluidsimBake::warning - More than one domain!\n");
- elbeemDebugOut(debugStrBuffer);
+ //snprintf(debugStrBuffer,256,"fluidsimBake::warning - More than one domain!\n"); elbeemDebugOut(debugStrBuffer);
+ pupmenu("Fluidsim Bake Error%t|There should be only one domain object! Aborted%x0");
+ return;
}
}
}
}
/* these both have to be valid, otherwise we wouldnt be here...*/
fsDomain = ob;
- fssDomain = ob->fluidsimSettings;
+ domainSettings = ob->fluidsimSettings;
/* rough check of settings... */
- if(fssDomain->previewresxyz > fssDomain->resolutionxyz) {
- snprintf(debugStrBuffer,256,"fluidsimBake::warning - Preview (%d) >= Resolution (%d)... setting equal.\n", fssDomain->previewresxyz , fssDomain->resolutionxyz);
+ if(domainSettings->previewresxyz > domainSettings->resolutionxyz) {
+ snprintf(debugStrBuffer,256,"fluidsimBake::warning - Preview (%d) >= Resolution (%d)... setting equal.\n", domainSettings->previewresxyz , domainSettings->resolutionxyz);
elbeemDebugOut(debugStrBuffer);
- fssDomain->previewresxyz = fssDomain->resolutionxyz;
+ domainSettings->previewresxyz = domainSettings->resolutionxyz;
}
// set adaptive coarsening according to resolutionxyz
// this should do as an approximation, with in/outflow
// doing this more accurate would be overkill
// perhaps add manual setting?
- if(fssDomain->maxRefine <0) {
- if(fssDomain->resolutionxyz>128) {
+ if(domainSettings->maxRefine <0) {
+ if(domainSettings->resolutionxyz>128) {
gridlevels = 2;
} else
- if(fssDomain->resolutionxyz>64) {
+ if(domainSettings->resolutionxyz>64) {
gridlevels = 1;
} else {
gridlevels = 0;
}
} else {
- gridlevels = fssDomain->maxRefine;
+ gridlevels = domainSettings->maxRefine;
}
snprintf(debugStrBuffer,256,"fluidsimBake::msg: Baking %s, refine: %d\n", fsDomain->id.name , gridlevels );
elbeemDebugOut(debugStrBuffer);
@@ -347,12 +502,13 @@ void fluidsimBake(struct Object *ob)
}
// prepare names...
- strncpy(targetDir, fssDomain->surfdataPath, FILE_MAXDIR);
- strncpy(newSurfdataPath, fssDomain->surfdataPath, FILE_MAXDIR);
+ strncpy(targetDir, domainSettings->surfdataPath, FILE_MAXDIR);
+ strncpy(newSurfdataPath, domainSettings->surfdataPath, FILE_MAXDIR);
BLI_convertstringcode(targetDir, G.sce, 0); // fixed #frame-no
strcpy(targetFile, targetDir);
strcat(targetFile, suffixConfig);
+ if(!doExportOnly) { strcat(targetFile,".tmp"); } // dont overwrite/delete original file
// make sure all directories exist
// as the bobjs use the same dir, this only needs to be checked
// for the cfg output
@@ -361,7 +517,11 @@ void fluidsimBake(struct Object *ob)
// check selected directory
// simply try to open cfg file for writing to test validity of settings
fileCfg = fopen(targetFile, "w");
- if(fileCfg) { dirExist = 1; fclose(fileCfg); }
+ if(fileCfg) {
+ dirExist = 1; fclose(fileCfg);
+ // remove cfg dummy from directory test
+ if(!doExportOnly) { BLI_delete(targetFile, 0,0); }
+ }
if((strlen(targetDir)<1) || (!dirExist)) {
char blendDir[FILE_MAXDIR+FILE_MAXFILE], blendFile[FILE_MAXDIR+FILE_MAXFILE];
@@ -395,316 +555,302 @@ void fluidsimBake(struct Object *ob)
selection = pupmenu(dispmsg);
if(selection<1) return; // 0 from menu, or -1 aborted
strcpy(targetDir, newSurfdataPath);
+ strncpy(domainSettings->surfdataPath, newSurfdataPath, FILE_MAXDIR);
BLI_convertstringcode(targetDir, G.sce, 0); // fixed #frame-no
}
+ // --------------------------------------------------------------------------------------------
+ // dump data for start frame
+ // CHECK more reasonable to number frames according to blender?
// dump data for frame 0
- G.scene->r.cfra = 1 /*G.scene->r.sfra*/;
+ G.scene->r.cfra = startFrame;
scene_update_for_newframe(G.scene, G.scene->lay);
-
- // start writing
- strcpy(targetFile, targetDir);
- strcat(targetFile, suffixConfig);
- // make sure these directories exist as well
- if(outStringsChanged) {
- BLI_make_existing_file(targetFile);
- }
- fileCfg = fopen(targetFile, "w");
- if(!fileCfg) {
- snprintf(debugStrBuffer,256,"fluidsimBake::error - Unable to open file for writing '%s'\n", targetFile);
- elbeemDebugOut(debugStrBuffer);
- pupmenu("Fluidsim Bake Error%t|Unable to output files... Aborted%x0");
- return;
+ // init common export vars for both file export and run
+ for(i=0; i<256; i++) {
+ channelObjMove[i][0] = channelObjMove[i][1] = channelObjMove[i][2] = NULL;
+ channelObjInivel[i] = NULL;
+ channelObjActive[i] = NULL;
+ }
+ allchannelSize = G.scene->r.efra; // always use till last frame
+ aniFrameTime = (domainSettings->animEnd - domainSettings->animStart)/(double)noFrames;
+ // blender specific - scale according to map old/new settings in anim panel:
+ aniFrlen = G.scene->r.framelen;
+ if(domainSettings->viscosityMode==1) {
+ /* manual mode */
+ calcViscosity = (1.0/(domainSettings->viscosityExponent*10)) * domainSettings->viscosityValue;
+ } else {
+ calcViscosity = fluidsimViscosityPreset[ domainSettings->viscosityMode ];
}
- ADD_CREATEDFILE(targetFile);
-
- fprintf(fileCfg, "# Blender ElBeem File , Source %s , Frame %d, to %s \n\n\n", G.sce, -1, targetFile );
- // file open -> valid settings -> store
- strncpy(fssDomain->surfdataPath, newSurfdataPath, FILE_MAXDIR);
-
- /* output simulation settings */
- {
- double calcViscosity = 0.0;
- double aniFrameTime = (fssDomain->animEnd - fssDomain->animStart)/(double)noFrames;
- char *simString = "\n"
- "attribute \"simulation1\" { \n"
- " solver = \"fsgr\"; \n" "\n"
- " p_domainsize = " "%f" /* realsize */ "; \n"
- " p_anistart = " "%f" /* aniStart*/ "; \n"
- " p_gravity = " "%f %f %f" /* pGravity*/ "; \n" "\n"
- " p_normgstar = %f; \n" /* use gstar param? */
- " p_viscosity = " "%f" /* pViscosity*/ "; \n" "\n"
-
- " maxrefine = " "%d" /* maxRefine*/ "; \n"
- " size = " "%d" /* gridSize*/ "; \n"
- " surfacepreview = " "%d" /* previewSize*/ "; \n"
- " smoothsurface = 1.0; \n"
-
- " geoinitid = 1; \n" "\n"
- " isovalue = 0.4900; \n"
- " isoweightmethod = 1; \n" "\n"
- "\n" ;
-
- if(fssDomain->viscosityMode==1) {
- /* manual mode */
- calcViscosity = (1.0/(fssDomain->viscosityExponent*10)) * fssDomain->viscosityValue;
- } else {
- calcViscosity = fluidsimViscosityPreset[ fssDomain->viscosityMode ];
+ bbStart = fsDomain->fluidsimSettings->bbStart;
+ bbSize = fsDomain->fluidsimSettings->bbSize;
+ fluidsimGetAxisAlignedBB(fsDomain->data, fsDomain->obmat, bbStart, bbSize, &domainSettings->meshBB);
+
+ // always init
+ { int timeIcu[1] = { FLUIDSIM_TIME };
+ float timeDef[1] = { 1. };
+ int gravIcu[3] = { FLUIDSIM_GRAV_X, FLUIDSIM_GRAV_Y, FLUIDSIM_GRAV_Z };
+ float gravDef[3] = { domainSettings->gravx, domainSettings->gravy, domainSettings->gravz };
+ int viscIcu[1] = { FLUIDSIM_VISC };
+ float viscDef[1] = { 1. };
+
+ // time channel is a bit special, init by hand...
+ timeAtIndex = MEM_callocN( (allchannelSize+1)*1*sizeof(float), "fluidsiminit_timeatindex");
+ for(i=0; i<=G.scene->r.efra; i++) {
+ timeAtIndex[i] = (float)(i-startFrame);
}
- fprintf(fileCfg, simString,
- (double)fssDomain->realsize,
- (double)fssDomain->animStart,
- (double)fssDomain->gravx, (double)fssDomain->gravy, (double)fssDomain->gravz,
- (double)fssDomain->gstar,
- calcViscosity,
- gridlevels, (int)fssDomain->resolutionxyz, (int)fssDomain->previewresxyz
- );
-
- // export animatable params
- if(fsDomain->ipo) {
- int i;
- float tsum=0.0, shouldbe=0.0;
- fprintf(fileCfg, " CHANNEL p_aniframetime = ");
- for(i=1 /*G.scene->r.sfra*/; i<G.scene->r.efra; i++) {
- float anit = (calc_ipo_time(fsDomain->ipo, i+1) -
- calc_ipo_time(fsDomain->ipo, i)) * aniFrameTime;
- if(anit<0.0) anit = 0.0;
- tsum += anit;
+ fluidsimInitChannel( &channelDomainTime, allchannelSize, timeAtIndex, timeIcu,timeDef, domainSettings->ipo, CHANNEL_FLOAT ); // NDEB
+ // time channel is a multiplicator for aniFrameTime
+ if(channelDomainTime) {
+ for(i=0; i<allchannelSize; i++) {
+ channelDomainTime[i*2+0] = aniFrameTime * channelDomainTime[i*2+0];
+ if(channelDomainTime[i*2+0]<0.) channelDomainTime[i*2+0] = 0.;
}
- // make sure inaccurate integration doesnt modify end time
- shouldbe = ((float)(G.scene->r.efra - 1 /*G.scene->r.sfra*/)) *aniFrameTime;
- for(i=1 /*G.scene->r.sfra*/; i<G.scene->r.efra; i++) {
- float anit = (calc_ipo_time(fsDomain->ipo, i+1) -
- calc_ipo_time(fsDomain->ipo, i)) * aniFrameTime;
- if(anit<0.0) anit = 0.0;
- anit *= (shouldbe/tsum);
- fprintf(fileCfg," %f %d \n",anit, (i-1)); // start with 0
+ }
+ timeAtFrame = MEM_callocN( (allchannelSize+1)*1*sizeof(float), "fluidsiminit_timeatframe");
+ timeAtFrame[0] = timeAtFrame[1] = domainSettings->animStart; // start at index 1
+ if(channelDomainTime) {
+ for(i=2; i<=allchannelSize; i++) {
+ timeAtFrame[i] = timeAtFrame[i-1]+channelDomainTime[(i-1)*2+0];
}
- fprintf(fileCfg, "; #cfgset, base=%f \n", aniFrameTime );
- //fprintf(stderr, "DEBUG base=%f tsum=%f, sb=%f, ts2=%f \n", aniFrameTime, tsum,shouldbe,tsum2 );
} else {
- fprintf(fileCfg, " p_aniframetime = " "%f" /* 2 aniFrameTime*/ "; #cfgset \n" ,
- aniFrameTime );
+ for(i=2; i<=allchannelSize; i++) { timeAtFrame[i] = timeAtFrame[i-1]+aniFrameTime; }
}
-
- fprintf(fileCfg, "} \n" );
- }
- // output blender object transformation
- {
- float domainMat[4][4];
- float invDomMat[4][4];
- char* blendattrString = "\n"
- "attribute \"btrafoattr\" { \n"
- " transform = %f %f %f %f "
- " %f %f %f %f "
- " %f %f %f %f "
- " %f %f %f %f ;\n"
- "} \n";
-
- MTC_Mat4CpyMat4(domainMat, fsDomain->obmat);
- if(!Mat4Invert(invDomMat, domainMat)) {
- snprintf(debugStrBuffer,256,"fluidsimBake::error - Invalid obj matrix?\n");
- elbeemDebugOut(debugStrBuffer);
- // FIXME add fatal msg
- return;
+ fluidsimInitChannel( &channelDomainViscosity, allchannelSize, timeAtFrame, viscIcu,viscDef, domainSettings->ipo, CHANNEL_FLOAT ); // NDEB
+ if(channelDomainViscosity) {
+ for(i=0; i<allchannelSize; i++) { channelDomainViscosity[i*2+0] = calcViscosity * channelDomainViscosity[i*2+0]; }
}
+ fluidsimInitChannel( &channelDomainGravity, allchannelSize, timeAtFrame, gravIcu,gravDef, domainSettings->ipo, CHANNEL_VEC );
+ } // domain channel init
+
+ // init obj movement channels
+ channelObjCount=0;
+ for(obit= G.main->object.first; obit; obit= obit->id.next) {
+ //{ snprintf(debugStrBuffer,256,"DEBUG object name=%s, type=%d ...\n", obit->id.name, obit->type); elbeemDebugOut(debugStrBuffer); } // DEBUG
+ if( (obit->fluidsimFlag & OB_FLUIDSIM_ENABLE) &&
+ (obit->type==OB_MESH) &&
+ (obit->fluidsimSettings->type != OB_FLUIDSIM_DOMAIN) && // if has to match 3 places! // CHECKMATCH
+ (obit->fluidsimSettings->type != OB_FLUIDSIM_PARTICLE) ) {
+
+ // cant use fluidsimInitChannel for obj channels right now, due
+ // to the special DXXX channels, and the rotation specialities
+ IpoCurve *icuex[3][3];
+ int icuIds[3][3] = {
+ {OB_LOC_X, OB_LOC_Y, OB_LOC_Z},
+ {OB_ROT_X, OB_ROT_Y, OB_ROT_Z},
+ {OB_SIZE_X, OB_SIZE_Y, OB_SIZE_Z}
+ };
+ // relative ipos
+ IpoCurve *icudex[3][3];
+ int icudIds[3][3] = {
+ {OB_DLOC_X, OB_DLOC_Y, OB_DLOC_Z},
+ {OB_DROT_X, OB_DROT_Y, OB_DROT_Z},
+ {OB_DSIZE_X, OB_DSIZE_Y, OB_DSIZE_Z}
+ };
+ int j,k;
+ float vals[3] = {0.0,0.0,0.0};
+ int o = channelObjCount;
+ int inivelIcu[3] = { FLUIDSIM_VEL_X, FLUIDSIM_VEL_Y, FLUIDSIM_VEL_Z };
+ float inivelDefs[3] = { obit->fluidsimSettings->iniVelx, obit->fluidsimSettings->iniVely, obit->fluidsimSettings->iniVelz };
+ int activeIcu[1] = { FLUIDSIM_ACTIVE };
+ float activeDefs[1] = { 1 }; // default to on
+
+ // check & init loc,rot,size
+ for(j=0; j<3; j++) {
+ for(k=0; k<3; k++) {
+ icuex[j][k] = find_ipocurve(obit->ipo, icuIds[j][k] );
+ icudex[j][k] = find_ipocurve(obit->ipo, icudIds[j][k] );
+ }
+ }
- fprintf(fileCfg, blendattrString,
- invDomMat[0][0],invDomMat[1][0],invDomMat[2][0],invDomMat[3][0],
- invDomMat[0][1],invDomMat[1][1],invDomMat[2][1],invDomMat[3][1],
- invDomMat[0][2],invDomMat[1][2],invDomMat[2][2],invDomMat[3][2],
- invDomMat[0][3],invDomMat[1][3],invDomMat[2][3],invDomMat[3][3] );
- }
-
+ for(j=0; j<3; j++) {
+ channelObjMove[o][j] = MEM_callocN( allchannelSize*4*sizeof(float), "fluidsiminit_objmovchannel");
+ for(i=1; i<=allchannelSize; i++) {
+
+ for(k=0; k<3; k++) {
+ if(icuex[j][k]) {
+ calc_icu(icuex[j][k], aniFrlen*((float)i) );
+ vals[k] = icuex[j][k]->curval;
+ } else {
+ float setval=0.0;
+ if(j==0) { setval = obit->loc[k];
+ } else if(j==1) { setval = ( 180.0*obit->rot[k] )/( 10.0*M_PI );
+ } else { setval = obit->size[k]; }
+ vals[k] = setval;
+ }
+ if(icudex[j][k]) {
+ calc_icu(icudex[j][k], aniFrlen*((float)i) );
+ vals[k] += icudex[j][k]->curval;
+ }
+ } // k
+
+ for(k=0; k<3; k++) {
+ float set = vals[k];
+ if(j==1) { // rot is downscaled by 10 for ipo !?
+ set = 360.0 - (10.0*set);
+ }
+ channelObjMove[o][j][(i-1)*4 + k] = set; // - obit->loc[k];
+ } // k
+ channelObjMove[o][j][(i-1)*4 + 3] = timeAtFrame[i];
+ }
+ }
+ fluidsimInitChannel( &channelObjInivel[o], allchannelSize, timeAtFrame, inivelIcu,inivelDefs, obit->fluidsimSettings->ipo, CHANNEL_VEC );
+ fluidsimInitChannel( &channelObjActive[o], allchannelSize, timeAtFrame, activeIcu,activeDefs, obit->fluidsimSettings->ipo, CHANNEL_FLOAT );
- fprintf(fileCfg, "raytracing {\n");
-
- /* output picture settings for preview renders */
- {
- char *rayString = "\n"
- " anistart= 0; \n"
- " aniframes= " "%d" /*1 frameEnd-frameStart+0*/ "; #cfgset \n"
- " frameSkip= false; \n"
- " filename= \"" "%s" /* rayPicFilename*/ "\"; #cfgset \n"
- " aspect 1.0; \n"
- " resolution " "%d %d" /*2,3 blendResx,blendResy*/ "; #cfgset \n"
- " antialias 1; \n"
- " ambientlight (1, 1, 1); \n"
- " maxRayDepth 6; \n"
- " treeMaxDepth 25; \n"
- " treeMaxTriangles 8; \n"
- " background (0.08, 0.08, 0.20); \n"
- " eyepoint= (" "%f %f %f"/*4,5,6 eyep*/ "); #cfgset \n"
- " lookat= (" "%f %f %f"/*7,8,9 lookatp*/ "); #cfgset \n"
- " upvec= (0 0 1); \n"
- " fovy= " "%f" /*blendFov*/ "; #cfgset \n"
- " blenderattr= \"btrafoattr\"; \n"
- "\n\n";
-
- char *lightString = "\n"
- " light { \n"
- " type= omni; \n"
- " active= 1; \n"
- " color= (1.0, 1.0, 1.0); \n"
- " position= (" "%f %f %f"/*1,2,3 eyep*/ "); #cfgset \n"
- " castShadows= 1; \n"
- " } \n\n" ;
-
- struct Object *cam = G.scene->camera;
- float eyex=2.0, eyey=2.0, eyez=2.0;
- int resx = 200, resy=200;
- float lookatx=0.0, lookaty=0.0, lookatz=0.0;
- float fov = 45.0;
+ channelObjCount++;
- strcpy(targetFile, targetDir);
- strcat(targetFile, suffixSurface);
- resx = G.scene->r.xsch;
- resy = G.scene->r.ysch;
- if((cam) && (cam->type == OB_CAMERA)) {
- Camera *camdata= G.scene->camera->data;
- double lens = camdata->lens;
- double imgRatio = (double)resx/(double)resy;
- fov = 360.0 * atan(16.0*imgRatio/lens) / M_PI;
- //R.near= camdata->clipsta; R.far= camdata->clipend;
-
- eyex = cam->loc[0];
- eyey = cam->loc[1];
- eyez = cam->loc[2];
- // TODO - place lookat in middle of domain?
}
+ }
- fprintf(fileCfg, rayString,
- (noFrames+1), targetFile, resx,resy,
- eyex, eyey, eyez ,
- lookatx, lookaty, lookatz,
- fov
- );
- fprintf(fileCfg, lightString,
- eyex, eyey, eyez );
+ // init trafo matrix
+ MTC_Mat4CpyMat4(domainMat, fsDomain->obmat);
+ if(!Mat4Invert(invDomMat, domainMat)) {
+ snprintf(debugStrBuffer,256,"fluidsimBake::error - Invalid obj matrix?\n");
+ elbeemDebugOut(debugStrBuffer);
+ // FIXME add fatal msg
+ FS_FREE_CHANNELS;
+ return;
}
- /* output fluid domain */
- {
- char * domainString = "\n"
- " geometry { \n"
- " type= fluidlbm; \n"
- " name = \"" "%s" /*name*/ "\"; #cfgset \n"
- " visible= 1; \n"
- " attributes= \"simulation1\"; \n"
- //" define { material_surf = \"fluidblue\"; } \n"
- " start= " "%f %f %f" /*bbstart*/ "; #cfgset \n"
- " end = " "%f %f %f" /*bbend */ "; #cfgset \n"
- " } \n"
- "\n";
- float *bbStart = fsDomain->fluidsimSettings->bbStart;
- float *bbSize = fsDomain->fluidsimSettings->bbSize;
- fluidsimGetAxisAlignedBB(fsDomain->data, fsDomain->obmat, bbStart, bbSize);
-
- fprintf(fileCfg, domainString,
- fsDomain->id.name,
- bbStart[0], bbStart[1], bbStart[2],
- bbStart[0]+bbSize[0], bbStart[1]+bbSize[1], bbStart[2]+bbSize[2]
- );
+ // --------------------------------------------------------------------------------------------
+ // start writing / exporting
+ strcpy(targetFile, targetDir);
+ strcat(targetFile, suffixConfig);
+ if(!doExportOnly) { strcat(targetFile,".tmp"); } // dont overwrite/delete original file
+ // make sure these directories exist as well
+ if(outStringsChanged) {
+ BLI_make_existing_file(targetFile);
}
-
- /* setup geometry */
- {
- char *objectStringStart =
- " geometry { \n"
- " type= objmodel; \n"
- " name = \"" "%s" /* name */ "\"; #cfgset \n"
- // DEBUG , also obs invisible?
- " visible= 0; \n"
- " define { \n" ;
- char *obstacleString =
- " geoinittype= \"" "%s" /* type */ "\"; #cfgset \n"
- " filename= \"" "%s" /* data filename */ "\"; #cfgset \n" ;
- char *fluidString =
- " geoinittype= \"" "%s" /* type */ "\"; \n"
- " filename= \"" "%s" /* data filename */ "\"; #cfgset \n"
- " initial_velocity= " "%f %f %f" /* vel vector */ "; #cfgset \n" ;
- char *objectStringEnd =
- " geoinit_intersect = 1; \n" /* always use accurate init here */
- " geoinitid= 1; \n"
- " } \n"
- " } \n"
- "\n" ;
- char fnameObjdat[FILE_MAXFILE];
-
+ if(!doExportOnly) {
+ SDL_Thread *simthr = NULL;
+
+ // perform simulation with El'Beem api and SDL threads
+ elbeemSimulationSettings fsset;
+ fsset.version = 1;
+
+ // setup global settings
+ for(i=0 ; i<3; i++) fsset.geoStart[i] = bbStart[i];
+ for(i=0 ; i<3; i++) fsset.geoSize[i] = bbSize[i];
+ // simulate with 50^3
+ fsset.resolutionxyz = (int)domainSettings->resolutionxyz;
+ fsset.previewresxyz = (int)domainSettings->previewresxyz;
+ // 10cm water domain
+ fsset.realsize = domainSettings->realsize;
+ fsset.viscosity = calcViscosity;
+ // earth gravity
+ fsset.gravity[0] = domainSettings->gravx;
+ fsset.gravity[1] = domainSettings->gravy;
+ fsset.gravity[2] = domainSettings->gravz;
+ // simulate 5 frames, each 0.03 seconds, output to ./apitest_XXX.bobj.gz
+ fsset.animStart = domainSettings->animStart;
+ fsset.aniFrameTime = aniFrameTime;
+ fsset.noOfFrames = noFrames - 1; // is otherwise subtracted in parser
+ strcpy(targetFile, targetDir);
+ strcat(targetFile, suffixSurface);
+ // defaults for compressibility and adaptive grids
+ fsset.gstar = domainSettings->gstar;
+ fsset.maxRefine = domainSettings->maxRefine; // check <-> gridlevels
+ fsset.generateParticles = domainSettings->generateParticles;
+ strcpy( fsset.outputPath, targetFile);
+
+ // domain channels
+ fsset.channelSizeFrameTime =
+ fsset.channelSizeViscosity =
+ fsset.channelSizeGravity = allchannelSize;
+ fsset.channelFrameTime = channelDomainTime;
+ fsset.channelViscosity = channelDomainViscosity;
+ fsset.channelGravity = channelDomainGravity;
+
+ if( (domainSettings->typeFlags&OB_FSBND_NOSLIP)) fsset.obstacleType = FLUIDSIM_OBSTACLE_NOSLIP;
+ else if((domainSettings->typeFlags&OB_FSBND_PARTSLIP)) fsset.obstacleType = FLUIDSIM_OBSTACLE_PARTSLIP;
+ else if((domainSettings->typeFlags&OB_FSBND_FREESLIP)) fsset.obstacleType = FLUIDSIM_OBSTACLE_FREESLIP;
+ fsset.obstaclePartslip = domainSettings->partSlipValue;
+ fsset.generateVertexVectors = (int)(!(domainSettings->typeFlags&OB_FSDOMAIN_NOVECGEN));
+ // fprintf(stderr," VVV %d %d \n",fsset.generateVertexVectors , (domainSettings->typeFlags&OB_FSDOMAIN_NOVECGEN)); // DEBUG
+
+ // init blender trafo matrix
+ // fprintf(stderr,"elbeemInit - mpTrafo:\n");
+ { int j;
+ for(i=0; i<4; i++) {
+ for(j=0; j<4; j++) {
+ fsset.surfaceTrafo[i*4+j] = invDomMat[j][i];
+ // fprintf(stderr,"elbeemInit - mpTrafo %d %d = %f (%d) \n", i,j, fsset.surfaceTrafo[i*4+j] , (i*4+j) );
+ }
+ } }
+
+ // init solver with settings
+ elbeemInit(&fsset);
+
+ // init objects
+ channelObjCount = 0;
for(obit= G.main->object.first; obit; obit= obit->id.next) {
//{ snprintf(debugStrBuffer,256,"DEBUG object name=%s, type=%d ...\n", obit->id.name, obit->type); elbeemDebugOut(debugStrBuffer); } // DEBUG
- if( (obit->fluidsimFlag & OB_FLUIDSIM_ENABLE) &&
+ if( (obit->fluidsimFlag & OB_FLUIDSIM_ENABLE) && // if has to match 3 places! // CHECKMATCH
(obit->type==OB_MESH) &&
- (obit->fluidsimSettings->type != OB_FLUIDSIM_DOMAIN)
+ (obit->fluidsimSettings->type != OB_FLUIDSIM_DOMAIN) &&
+ (obit->fluidsimSettings->type != OB_FLUIDSIM_PARTICLE)
) {
- fluidsimGetGeometryObjFilename(obit, fnameObjdat); //, outPrefix);
- strcpy(targetFile, targetDir);
- strcat(targetFile, fnameObjdat);
- fprintf(fileCfg, objectStringStart, obit->id.name ); // abs path
- if(obit->fluidsimSettings->type == OB_FLUIDSIM_FLUID) {
- fprintf(fileCfg, fluidString, "fluid", targetFile, // do use absolute paths?
- (double)obit->fluidsimSettings->iniVelx, (double)obit->fluidsimSettings->iniVely, (double)obit->fluidsimSettings->iniVelz );
- }
- if(obit->fluidsimSettings->type == OB_FLUIDSIM_INFLOW) {
- fprintf(fileCfg, fluidString, "inflow", targetFile, // do use absolute paths?
- (double)obit->fluidsimSettings->iniVelx, (double)obit->fluidsimSettings->iniVely, (double)obit->fluidsimSettings->iniVelz );
- }
- if(obit->fluidsimSettings->type == OB_FLUIDSIM_OUTFLOW) {
- fprintf(fileCfg, fluidString, "outflow", targetFile, // do use absolute paths?
- (double)obit->fluidsimSettings->iniVelx, (double)obit->fluidsimSettings->iniVely, (double)obit->fluidsimSettings->iniVelz );
- }
- if(obit->fluidsimSettings->type == OB_FLUIDSIM_OBSTACLE) {
- fprintf(fileCfg, obstacleString, "bnd_no" , targetFile); // abs path
- }
- fprintf(fileCfg, objectStringEnd ); // abs path
- ADD_CREATEDFILE(targetFile);
- writeBobjgz(targetFile, obit);
- }
- }
- }
-
- /* fluid material */
- fprintf(fileCfg,
- " material { \n"
- " type= phong; \n"
- " name= \"fluidblue\"; \n"
- " diffuse= 0.3 0.5 0.9; \n"
- " ambient= 0.1 0.1 0.1; \n"
- " specular= 0.2 10.0; \n"
- " } \n" );
-
-
+ float *verts=NULL;
+ int *tris=NULL;
+ int numVerts=0, numTris=0;
+ int o = channelObjCount;
+ elbeemMesh fsmesh;
+ elbeemResetMesh( &fsmesh );
+ fsmesh.type = obit->fluidsimSettings->type;;
+ // get name of object for debugging solver
+ fsmesh.name = obit->id.name;
+
+ initElbeemMesh(obit, &numVerts, &verts, &numTris, &tris);
+ fsmesh.numVertices = numVerts;
+ fsmesh.numTriangles = numTris;
+ fsmesh.vertices = verts;
+ fsmesh.triangles = tris;
+
+ fsmesh.channelSizeTranslation =
+ fsmesh.channelSizeRotation =
+ fsmesh.channelSizeScale =
+ fsmesh.channelSizeInitialVel =
+ fsmesh.channelSizeActive = allchannelSize;
+
+ fsmesh.channelTranslation = channelObjMove[o][0];
+ fsmesh.channelRotation = channelObjMove[o][1];
+ fsmesh.channelScale = channelObjMove[o][2];
+ fsmesh.channelActive = channelObjActive[o];
+ if( (fsmesh.type == OB_FLUIDSIM_FLUID) ||
+ (fsmesh.type == OB_FLUIDSIM_INFLOW) ) {
+ fsmesh.channelInitialVel = channelObjInivel[o];
+ fsmesh.localInivelCoords = ((obit->fluidsimSettings->typeFlags&OB_FSINFLOW_LOCALCOORD)?1:0);
+ }
- fprintf(fileCfg, "} // end raytracing\n");
- fclose(fileCfg);
+ if( (obit->fluidsimSettings->typeFlags&OB_FSBND_NOSLIP)) fsmesh.obstacleType = FLUIDSIM_OBSTACLE_NOSLIP;
+ else if((obit->fluidsimSettings->typeFlags&OB_FSBND_PARTSLIP)) fsmesh.obstacleType = FLUIDSIM_OBSTACLE_PARTSLIP;
+ else if((obit->fluidsimSettings->typeFlags&OB_FSBND_FREESLIP)) fsmesh.obstacleType = FLUIDSIM_OBSTACLE_FREESLIP;
+ fsmesh.obstaclePartslip = obit->fluidsimSettings->partSlipValue;
- strcpy(targetFile, targetDir);
- strcat(targetFile, suffixConfig);
- snprintf(debugStrBuffer,256,"fluidsimBake::msg: Wrote %s\n", targetFile);
- elbeemDebugOut(debugStrBuffer);
+ elbeemAddMesh(&fsmesh);
- // perform simulation
- {
- SDL_Thread *simthr = NULL;
+ if(verts) MEM_freeN(verts);
+ if(tris) MEM_freeN(tris);
+ channelObjCount++;
+ } // valid mesh
+ } // objects
+
globalBakeLock = SDL_CreateMutex();
// set to neutral, -1 means user abort, -2 means init error
globalBakeState = 0;
- globalBakeFrame = 1;
+ globalBakeFrame = 0;
simthr = SDL_CreateThread(fluidsimSimulateThread, targetFile);
-#ifndef WIN32
- // DEBUG for win32 debugging, dont use threads...
-#endif // WIN32
+
if(!simthr) {
snprintf(debugStrBuffer,256,"fluidsimBake::error: Unable to create thread... running without one.\n");
elbeemDebugOut(debugStrBuffer);
set_timecursor(0);
- performElbeemSimulation(targetFile);
+ elbeemSimulate();
} else {
int done = 0;
unsigned short event=0;
@@ -747,7 +893,8 @@ void fluidsimBake(struct Object *ob)
// redraw the 3D for showing progress once in a while...
if(lastRedraw!=globalBakeFrame) {
ScrArea *sa;
- G.scene->r.cfra = lastRedraw = globalBakeFrame;
+ G.scene->r.cfra = startFrame+globalBakeFrame;
+ lastRedraw = globalBakeFrame;
update_for_newframe_muted();
sa= G.curscreen->areabase.first;
while(sa) {
@@ -762,19 +909,278 @@ void fluidsimBake(struct Object *ob)
}
SDL_DestroyMutex(globalBakeLock);
globalBakeLock = NULL;
- } // thread creation
+ } // El'Beem API init, thread creation
+ // --------------------------------------------------------------------------------------------
+ else
+ { // write config file to be run with command line simulator
+ fileCfg = fopen(targetFile, "w");
+ if(!fileCfg) {
+ snprintf(debugStrBuffer,256,"fluidsimBake::error - Unable to open file for writing '%s'\n", targetFile);
+ elbeemDebugOut(debugStrBuffer);
+
+ pupmenu("Fluidsim Bake Error%t|Unable to output files... Aborted%x0");
+ FS_FREE_CHANNELS;
+ return;
+ }
+ //ADD_CREATEDFILE(targetFile);
+
+ fprintf(fileCfg, "# Blender ElBeem File , Source %s , Frame %d, to %s \n\n\n", G.sce, -1, targetFile );
+ // file open -> valid settings -> store
+ strncpy(domainSettings->surfdataPath, newSurfdataPath, FILE_MAXDIR);
+
+ /* output simulation settings */
+ {
+ char *dtype[3] = { "no", "part", "free" };
+ float pslip = domainSettings->partSlipValue; int bi=0;
+ char *simString = "\n"
+ "attribute \"simulation1\" { \n"
+ " solver = \"fsgr\"; \n" "\n"
+ " p_domainsize = " "%f" /* realsize */ "; \n"
+ " p_anistart = " "%f" /* aniStart*/ "; \n"
+ " p_normgstar = %f; \n" /* use gstar param? */
+ " maxrefine = " "%d" /* maxRefine*/ "; \n"
+ " size = " "%d" /* gridSize*/ "; \n"
+ " surfacepreview = " "%d" /* previewSize*/ "; \n"
+ " dump_velocities = " "%d" /* vector dump */ "; \n"
+ " smoothsurface = 1.0; \n"
+ " smoothnormals = 1.0; \n"
+ " geoinitid = 1; \n" "\n"
+ " isovalue = 0.4900; \n"
+ " isoweightmethod = 1; \n" "\n" ;
- // cleanup sim files
- if(getenv(delEnvStr)) {
- doDeleteCreatedFiles = atoi(getenv(delEnvStr));
- }
- for(i=0; i<numCreatedFiles; i++) {
- if(doDeleteCreatedFiles>0) {
- //fprintf(stderr," CREATED '%s' deleting... \n", createdFiles[i]); // debug
- BLI_delete(createdFiles[i], 0,0);
+ fprintf(fileCfg, simString,
+ (double)domainSettings->realsize, (double)domainSettings->animStart, (double)domainSettings->gstar,
+ gridlevels, (int)domainSettings->resolutionxyz, (int)domainSettings->previewresxyz ,
+ (int)(!(domainSettings->typeFlags&OB_FSDOMAIN_NOVECGEN))
+ );
+
+ if((domainSettings->typeFlags&OB_FSBND_NOSLIP)) bi=0;
+ else if((domainSettings->typeFlags&OB_FSBND_PARTSLIP)) bi=1;
+ else if((domainSettings->typeFlags&OB_FSBND_FREESLIP)) bi=2;
+ fprintf(fileCfg, " domainbound = %s; domainpartslip=%f; \n", dtype[bi], pslip);
+
+ fprintf(fileCfg," # org aniframetime: %f \n", aniFrameTime);
+ fluidsimPrintChannel(fileCfg, channelDomainTime,allchannelSize,"p_aniframetime",CHANNEL_FLOAT);
+ fluidsimPrintChannel(fileCfg, channelDomainViscosity,allchannelSize,"p_viscosity",CHANNEL_FLOAT);
+ fluidsimPrintChannel(fileCfg, channelDomainGravity, allchannelSize,"p_gravity",CHANNEL_VEC);
+
+ fprintf(fileCfg, "\n} \n" );
}
- free(createdFiles[i]);
- }
+
+ // output blender object transformation
+ {
+ char* blendattrString = "\n"
+ "attribute \"btrafoattr\" { \n"
+ " transform = %f %f %f %f "
+ " %f %f %f %f "
+ " %f %f %f %f "
+ " %f %f %f %f ;\n"
+ "} \n";
+
+ fprintf(fileCfg, blendattrString,
+ invDomMat[0][0],invDomMat[1][0],invDomMat[2][0],invDomMat[3][0],
+ invDomMat[0][1],invDomMat[1][1],invDomMat[2][1],invDomMat[3][1],
+ invDomMat[0][2],invDomMat[1][2],invDomMat[2][2],invDomMat[3][2],
+ invDomMat[0][3],invDomMat[1][3],invDomMat[2][3],invDomMat[3][3] );
+ }
+
+
+
+ fprintf(fileCfg, "raytracing {\n");
+
+ /* output picture settings for preview renders */
+ {
+ char *rayString = "\n"
+ " anistart= 0; \n"
+ " aniframes= " "%d" /*1 frameEnd-frameStart+0*/ "; #cfgset \n"
+ " frameSkip= false; \n"
+ " filename= \"" "%s" /* rayPicFilename*/ "\"; #cfgset \n"
+ " aspect 1.0; \n"
+ " resolution " "%d %d" /*2,3 blendResx,blendResy*/ "; #cfgset \n"
+ " antialias 1; \n"
+ " ambientlight (1, 1, 1); \n"
+ " maxRayDepth 6; \n"
+ " treeMaxDepth 25; \n"
+ " treeMaxTriangles 8; \n"
+ " background (0.08, 0.08, 0.20); \n"
+ " eyepoint= (" "%f %f %f"/*4,5,6 eyep*/ "); #cfgset \n"
+ " lookat= (" "%f %f %f"/*7,8,9 lookatp*/ "); #cfgset \n"
+ " upvec= (0 0 1); \n"
+ " fovy= " "%f" /*blendFov*/ "; #cfgset \n"
+ " blenderattr= \"btrafoattr\"; \n"
+ "\n\n";
+
+ char *lightString = "\n"
+ " light { \n"
+ " type= omni; \n"
+ " active= 1; \n"
+ " color= (1.0, 1.0, 1.0); \n"
+ " position= (" "%f %f %f"/*1,2,3 eyep*/ "); #cfgset \n"
+ " castShadows= 1; \n"
+ " } \n\n" ;
+
+ struct Object *cam = G.scene->camera;
+ float eyex=2.0, eyey=2.0, eyez=2.0;
+ int resx = 200, resy=200;
+ float lookatx=0.0, lookaty=0.0, lookatz=0.0;
+ float fov = 45.0;
+
+ strcpy(targetFile, targetDir);
+ strcat(targetFile, suffixSurface);
+ resx = G.scene->r.xsch;
+ resy = G.scene->r.ysch;
+ if((cam) && (cam->type == OB_CAMERA)) {
+ Camera *camdata= G.scene->camera->data;
+ double lens = camdata->lens;
+ double imgRatio = (double)resx/(double)resy;
+ fov = 360.0 * atan(16.0*imgRatio/lens) / M_PI;
+ //R.near= camdata->clipsta; R.far= camdata->clipend;
+
+ eyex = cam->loc[0];
+ eyey = cam->loc[1];
+ eyez = cam->loc[2];
+ // TODO - place lookat in middle of domain?
+ }
+
+ fprintf(fileCfg, rayString,
+ (noFrames+0), targetFile, resx,resy,
+ eyex, eyey, eyez ,
+ lookatx, lookaty, lookatz,
+ fov
+ );
+ fprintf(fileCfg, lightString,
+ eyex, eyey, eyez );
+ }
+
+
+ /* output fluid domain */
+ {
+ char * domainString = "\n"
+ " geometry { \n"
+ " type= fluidlbm; \n"
+ " name = \"" "%s" /*name*/ "\"; #cfgset \n"
+ " visible= 1; \n"
+ " attributes= \"simulation1\"; \n"
+ //" define { material_surf = \"fluidblue\"; } \n"
+ " start= " "%f %f %f" /*bbstart*/ "; #cfgset \n"
+ " end = " "%f %f %f" /*bbend */ "; #cfgset \n"
+ " } \n"
+ "\n";
+ fprintf(fileCfg, domainString,
+ fsDomain->id.name,
+ bbStart[0], bbStart[1], bbStart[2],
+ bbStart[0]+bbSize[0], bbStart[1]+bbSize[1], bbStart[2]+bbSize[2]
+ );
+ }
+
+
+ /* setup geometry */
+ {
+ char *objectStringStart =
+ " geometry { \n"
+ " type= objmodel; \n"
+ " name = \"" "%s" /* name */ "\"; #cfgset \n"
+ // DEBUG , also obs invisible?
+ " visible= 0; \n"
+ " define { \n" ;
+ char *outflowString =
+ " geoinittype= \"" "%s" /* type */ "\"; #cfgset \n"
+ " filename= \"" "%s" /* data filename */ "\"; #cfgset \n" ;
+ char *obstacleString =
+ " geoinittype= \"" "%s" /* type */ "\"; #cfgset \n"
+ " geoinit_partslip = \"" "%f" /* partslip */ "\"; #cfgset \n"
+ " filename= \"" "%s" /* data filename */ "\"; #cfgset \n" ;
+ char *fluidString =
+ " geoinittype= \"" "%s" /* type */ "\"; \n"
+ " filename= \"" "%s" /* data filename */ "\"; #cfgset \n" ;
+ //" initial_velocity= " "%f %f %f" /* vel vector */ "; #cfgset \n" ;
+ char *inflowString =
+ " geoinittype= \"" "%s" /* type */ "\"; \n"
+ " filename= \"" "%s" /* data filename */ "\"; #cfgset \n"
+ //" initial_velocity= " "%f %f %f" /* vel vector */ "; #cfgset \n"
+ " geoinit_localinivel = " "%d" /* local coords */ "; #cfgset \n" ;
+ char *objectStringEnd =
+ " geoinit_intersect = 1; \n" /* always use accurate init here */
+ " geoinitid= 1; \n"
+ " } \n"
+ " } \n"
+ "\n" ;
+ char fnameObjdat[FILE_MAXFILE];
+
+ channelObjCount = 0;
+ for(obit= G.main->object.first; obit; obit= obit->id.next) {
+ if( (obit->fluidsimFlag & OB_FLUIDSIM_ENABLE) &&
+ (obit->type==OB_MESH) && // if has to match 3 places! // CHECKMATCH
+ (obit->fluidsimSettings->type != OB_FLUIDSIM_DOMAIN) &&
+ (obit->fluidsimSettings->type != OB_FLUIDSIM_PARTICLE)
+ ) {
+
+ fluidsimGetGeometryObjFilename(obit, fnameObjdat);
+ strcpy(targetFile, targetDir);
+ strcat(targetFile, fnameObjdat);
+ fprintf(fileCfg, objectStringStart, obit->id.name ); // abs path
+ if(obit->fluidsimSettings->type == OB_FLUIDSIM_FLUID) {
+ fprintf(fileCfg, fluidString, "fluid", targetFile // do use absolute paths?
+ //,(double)obit->fluidsimSettings->iniVelx, (double)obit->fluidsimSettings->iniVely, (double)obit->fluidsimSettings->iniVelz
+ );
+ }
+ if(obit->fluidsimSettings->type == OB_FLUIDSIM_INFLOW) {
+ int locc = ((obit->fluidsimSettings->typeFlags&OB_FSINFLOW_LOCALCOORD)?1:0);
+ fprintf(fileCfg, inflowString, "inflow", targetFile // do use absolute paths?
+ //,(double)obit->fluidsimSettings->iniVelx, (double)obit->fluidsimSettings->iniVely, (double)obit->fluidsimSettings->iniVelz
+ ,locc );
+ }
+ if(obit->fluidsimSettings->type == OB_FLUIDSIM_OBSTACLE) {
+ char *btype[3] = { "bnd_no", "bnd_part", "bnd_free" };
+ float pslip = obit->fluidsimSettings->partSlipValue; int bi=0;
+ if((obit->fluidsimSettings->typeFlags&OB_FSBND_NOSLIP)) bi=0;
+ else if((obit->fluidsimSettings->typeFlags&OB_FSBND_PARTSLIP)) bi=1;
+ else if((obit->fluidsimSettings->typeFlags&OB_FSBND_FREESLIP)) bi=2;
+ fprintf(fileCfg, obstacleString, btype[bi], pslip, targetFile); // abs path
+ }
+ if(obit->fluidsimSettings->type == OB_FLUIDSIM_OUTFLOW) {
+ fprintf(fileCfg, outflowString, "outflow" , targetFile); // abs path
+ }
+
+ fluidsimPrintChannel(fileCfg, channelObjMove[channelObjCount][0],allchannelSize, "translation", CHANNEL_VEC);
+ fluidsimPrintChannel(fileCfg, channelObjMove[channelObjCount][1],allchannelSize, "rotation" , CHANNEL_VEC);
+ fluidsimPrintChannel(fileCfg, channelObjMove[channelObjCount][2],allchannelSize, "scale" , CHANNEL_VEC);
+ fluidsimPrintChannel(fileCfg, channelObjActive[channelObjCount] ,allchannelSize, "geoactive" , CHANNEL_FLOAT);
+ if( (obit->fluidsimSettings->type == OB_FLUIDSIM_FLUID) ||
+ (obit->fluidsimSettings->type == OB_FLUIDSIM_INFLOW) ) {
+ fluidsimPrintChannel(fileCfg, channelObjInivel[channelObjCount],allchannelSize,"initial_velocity" ,CHANNEL_VEC);
+ }
+ channelObjCount++;
+
+ fprintf(fileCfg, objectStringEnd ); // abs path
+ writeBobjgz(targetFile, obit);
+ }
+ }
+ }
+
+ /* fluid material */
+ fprintf(fileCfg,
+ " material { \n"
+ " type= phong; \n"
+ " name= \"fluidblue\"; \n"
+ " diffuse= 0.3 0.5 0.9; \n"
+ " ambient= 0.1 0.1 0.1; \n"
+ " specular= 0.2 10.0; \n"
+ " } \n" );
+
+ fprintf(fileCfg, "} // end raytracing\n");
+ fclose(fileCfg);
+
+ strcpy(targetFile, targetDir);
+ strcat(targetFile, suffixConfig);
+ snprintf(debugStrBuffer,256,"fluidsimBake::msg: Wrote %s\n", targetFile);
+ elbeemDebugOut(debugStrBuffer);
+
+ pupmenu("Fluidsim Bake Message%t|Config files exported successfully!%x0");
+ } // config file export done!
+
+ // --------------------------------------------------------------------------------------------
+ FS_FREE_CHANNELS;
// go back to "current" blender time
waitcursor(0);
diff --git a/source/blender/src/header_ipo.c b/source/blender/src/header_ipo.c
index 9271fe834d4..48b98e9a65d 100644
--- a/source/blender/src/header_ipo.c
+++ b/source/blender/src/header_ipo.c
@@ -53,6 +53,7 @@
#include "DNA_lamp_types.h"
#include "DNA_material_types.h"
#include "DNA_object_types.h"
+#include "DNA_object_fluidsim.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_texture_types.h"
@@ -141,6 +142,14 @@ void spaceipo_assign_ipo(SpaceIpo *si, Ipo *ipo)
conchan->ipo= ipo;
}
}
+ else if(si->blocktype==ID_FLUIDSIM) { // NT
+ if( (ob->fluidsimSettings) &&
+ (ob->fluidsimSettings->ipo) ) {
+ // decrement users counter
+ ob->fluidsimSettings->ipo->id.us--;
+ }
+ ob->fluidsimSettings->ipo = ipo;
+ }
else if(si->blocktype==ID_OB) {
if(ob->ipo)
ob->ipo->id.us--;
@@ -798,6 +807,9 @@ static char *ipo_modeselect_pup(void)
#ifdef __CON_IPO
str += sprintf(str,formatstring, "Constraint",ID_CO, ICON_CONSTRAINT);
#endif
+ if(ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) {
+ str += sprintf(str,formatstring,"Fluidsim",ID_FLUIDSIM, ICON_WORLD);
+ }
}
str += sprintf(str,formatstring, "Sequence",ID_SEQ, ICON_SEQUENCE);
@@ -1135,6 +1147,8 @@ void ipo_buttons(void)
icon = ICON_SEQUENCE;
else if(G.sipo->blocktype == ID_TE)
icon = ICON_TEXTURE;
+ else if(G.sipo->blocktype == ID_FLUIDSIM)
+ icon = ICON_WORLD;
uiDefIconTextButS(block, MENU, B_IPOMAIN, icon, ipo_modeselect_pup(), xco,0,100,20, &(G.sipo->blocktype), 0, 0, 0, 0, "Show IPO type");