- merged latest version of fluid solver

(fixed shadowed variables warnings, removed cfgparser.hpp,
	added cfgparser.h, removed debugging output)
- added support for env. var BLENDER_ELBEEMDEBUG to enable
  debugging output again
- fixed missing triangle display (marching cubes produced v3=0 triangles)
- fixed geometry init bug (nearest intersection check
  for intersecting objects was messed up)
- changed position of derived mesh creation in DerivedMesh.c
  (for some reason the useDeform code is necessary, without it or
	 with useDeform=0 nothing is displayed)
- 3dviews now update every 2 seconds to show simulation progress
- note: mesh_strip_loose_faces(me); in ./source/blender/blenkernel/intern/mesh.c:937
  not necessary anymore?
This commit is contained in:
Nils Thuerey
2005-09-23 14:42:14 +00:00
parent 5f767d1627
commit 4fb0cccc68
37 changed files with 2426 additions and 2202 deletions

View File

@@ -11,6 +11,7 @@ elbeem_env.Append (CPPPATH = user_options_dict['PNG_INCLUDE'])
elbeem_env.Append (CPPPATH = user_options_dict['Z_INCLUDE'])
elbeem_env.Append (CPPPATH = user_options_dict['SDL_INCLUDE'])
# main build----------------------------------------
Sources = [

View File

@@ -138,11 +138,9 @@ ntlMat4Gfx Attribute::getAsMat4Gfx()
bool success = true;
ntlMat4Gfx ret(0.0);
char *endptr;
const char *str = NULL;
if(mValue.size()==1) {
const char *str = mValue[0].c_str();
char *endptr;
double rval = strtod(str, &endptr);
if( (str==endptr) ||
((str!=endptr) && (*endptr != '\0')) )success = false;
@@ -157,7 +155,7 @@ ntlMat4Gfx Attribute::getAsMat4Gfx()
// 3x3
for(int i=0; i<3;i++) {
for(int j=0; j<3;j++) {
str = mValue[i*3+j].c_str();
const char *str = mValue[i*3+j].c_str();
ret.value[i][j] = strtod(str, &endptr);
if( (str==endptr) ||
((str!=endptr) && (*endptr != '\0')) ) success = false;
@@ -167,7 +165,7 @@ ntlMat4Gfx Attribute::getAsMat4Gfx()
// 4x4
for(int i=0; i<4;i++) {
for(int j=0; j<4;j++) {
str = mValue[i*4+j].c_str();
const char *str = mValue[i*4+j].c_str();
ret.value[i][j] = strtod(str, &endptr);
if( (str==endptr) ||
((str!=endptr) && (*endptr != '\0')) ) success = false;
@@ -210,7 +208,7 @@ bool AttributeList::checkUnusedParams()
i != mAttrs.end(); i++) {
if((*i).second) {
if(!(*i).second->getUsed()) {
errorOut("Attribute "<<mName<<" has unknown parameter '"<<(*i).first<<"' = '"<< mAttrs[(*i).first]->getAsString() <<"' ");
errMsg("AttributeList::checkUnusedParams", "List "<<mName<<" has unknown parameter '"<<(*i).first<<"' = '"<< mAttrs[(*i).first]->getAsString() <<"' ");
found = true;
}
}
@@ -232,7 +230,7 @@ void AttributeList::setAllUsed() {
*****************************************************************************/
int AttributeList::readInt(string name, int defaultValue, string source,string target, bool needed) {
if(!exists(name)) {
if(needed) { errorOut("AttributeList::readInt error: Required attribute '"<<name<<"' for "<< source <<" not set! "); exit(1); }
if(needed) { errFatal("AttributeList::readInt","Required attribute '"<<name<<"' for "<< source <<" not set! ", SIMWORLD_INITERROR); }
return defaultValue;
}
if(DEBUG_ATTRIBUTES==1) { debugOut( source << " Var '"<< target <<"' set to '"<< find(name)->getCompleteString() <<"' as type int " , 3); }
@@ -241,7 +239,7 @@ int AttributeList::readInt(string name, int defaultValue, string source,string t
}
bool AttributeList::readBool(string name, bool defaultValue, string source,string target, bool needed) {
if(!exists(name)) {
if(needed) { errorOut("AttributeList::readBool error: Required attribute '"<<name<<"' for "<< source <<" not set! "); exit(1); }
if(needed) { errFatal("AttributeList::readBool","Required attribute '"<<name<<"' for "<< source <<" not set! ", SIMWORLD_INITERROR); }
return defaultValue;
}
if(DEBUG_ATTRIBUTES==1) { debugOut( source << " Var '"<< target <<"' set to '"<< find(name)->getCompleteString() <<"' as type int " , 3); }
@@ -250,7 +248,7 @@ bool AttributeList::readBool(string name, bool defaultValue, string source,strin
}
double AttributeList::readFloat(string name, double defaultValue, string source,string target, bool needed) {
if(!exists(name)) {
if(needed) { errorOut("AttributeList::readFloat error: Required attribute '"<<name<<"' for "<< source <<" not set! "); exit(1); }
if(needed) { errFatal("AttributeList::readFloat","Required attribute '"<<name<<"' for "<< source <<" not set! ", SIMWORLD_INITERROR); }
return defaultValue;
}
if(DEBUG_ATTRIBUTES==1) { debugOut( source << " Var '"<< target <<"' set to '"<< find(name)->getCompleteString() <<"' as type int " , 3); }
@@ -259,7 +257,7 @@ double AttributeList::readFloat(string name, double defaultValue, string source,
}
string AttributeList::readString(string name, string defaultValue, string source,string target, bool needed) {
if(!exists(name)) {
if(needed) { errorOut("AttributeList::readInt error: Required attribute '"<<name<<"' for "<< source <<" not set! "); exit(1); }
if(needed) { errFatal("AttributeList::readInt","Required attribute '"<<name<<"' for "<< source <<" not set! ", SIMWORLD_INITERROR); }
return defaultValue;
}
if(DEBUG_ATTRIBUTES==1) { debugOut( source << " Var '"<< target <<"' set to '"<< find(name)->getCompleteString() <<"' as type int " , 3); }
@@ -268,7 +266,7 @@ string AttributeList::readString(string name, string defaultValue, string source
}
ntlVec3d AttributeList::readVec3d(string name, ntlVec3d defaultValue, string source,string target, bool needed) {
if(!exists(name)) {
if(needed) { errorOut("AttributeList::readInt error: Required attribute '"<<name<<"' for "<< source <<" not set! "); exit(1); }
if(needed) { errFatal("AttributeList::readInt","Required attribute '"<<name<<"' for "<< source <<" not set! ", SIMWORLD_INITERROR); }
return defaultValue;
}
if(DEBUG_ATTRIBUTES==1) { debugOut( source << " Var '"<< target <<"' set to '"<< find(name)->getCompleteString() <<"' as type int " , 3); }
@@ -278,7 +276,7 @@ ntlVec3d AttributeList::readVec3d(string name, ntlVec3d defaultValue, string sou
ntlMat4Gfx AttributeList::readMat4Gfx(string name, ntlMat4Gfx defaultValue, string source,string target, bool needed) {
if(!exists(name)) {
if(needed) { errorOut("AttributeList::readInt error: Required attribute '"<<name<<"' for "<< source <<" not set! "); exit(1); }
if(needed) { errFatal("AttributeList::readInt","Required attribute '"<<name<<"' for "<< source <<" not set! ", SIMWORLD_INITERROR); }
return defaultValue;
}
if(DEBUG_ATTRIBUTES==1) { debugOut( source << " Var '"<< target <<"' set to '"<< find(name)->getCompleteString() <<"' as type int " , 3); }

View File

@@ -99,8 +99,10 @@ class AttributeList
/*! get an attribute */
Attribute *find(string name) {
if(mAttrs.find(name) == mAttrs.end()) {
errorOut("AttributeList::find error: Invalid attribute '"<<name<<"' , not found..." );
exit(1);
errFatal("AttributeList::find","Invalid attribute '"<<name<<"' , not found...",SIMWORLD_INITERROR );
// just create a new empty one (warning: small memory leak!), and exit as soon as possible
vector<string> empty;
return new Attribute(name,empty, -1);
}
return mAttrs[name];
}

View File

@@ -12,16 +12,30 @@
#include "globals.h"
#include "ntl_raytracer.h"
#include "ntl_blenderdumper.h"
#include <stdlib.h>
extern "C"
int performElbeemSimulation(char *cfgfilename) {
fprintf(GEN_userstream, "Running El'Beem from Blender with file '%s' ...\n",cfgfilename);
const char *strEnvName = "BLENDER_ELBEEMDEBUG";
gWorldState = SIMWORLD_INVALID;
strcpy(gWorldStringState,"[none]");
if(getenv(strEnvName)) {
gDebugLevel = atoi(getenv(strEnvName));
if(gDebugLevel< 0) gDebugLevel = 0;
if(gDebugLevel>10) gDebugLevel = 0; // only use valid values
if(gDebugLevel>0) fprintf(stderr, "Using envvar '%s'='%s', debugLevel set to: %d\n",strEnvName, getenv(strEnvName), gDebugLevel);
}
if(gDebugLevel>0) fprintf(GEN_userstream, "Running El'Beem from Blender with file '%s', debugLevel:%d ...\n",cfgfilename,gDebugLevel);
// load given file in command line mode
ntlBlenderDumper elbeem(cfgfilename, true);
myTime_t timestart = getTime();
elbeem.renderAnimation();
myTime_t timeend = getTime();
fprintf(GEN_userstream, "El'Beem simulation done, time: %f seconds.\n", ((timeend-timestart)/(double)1000.0) );
if(SIMWORLD_OK()) {
gWorldState = SIMWORLD_INITED;
myTime_t timestart = getTime();
elbeem.renderAnimation();
myTime_t timeend = getTime();
if(gDebugLevel>0) fprintf(GEN_userstream, "El'Beem simulation done, time: %f seconds.\n", ((timeend-timestart)/(double)1000.0) );
} else {
}
return 1;
};

View File

@@ -799,16 +799,19 @@ 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
#include "cfgparser.h"
#else // ELBEEM_BLENDER==1
#include "cfgparser.hpp"
#endif // ELBEEM_BLENDER==1
#include "utilities.h"
#include <string.h>
#define CHAR_BUFFER_SIZE 8000
char charBuffer[ CHAR_BUFFER_SIZE ];
char charBuffer[ CHAR_BUFFER_SIZE ];
int lineCount = 1;
int lineCount = 1;
// for windos compiler...
extern "C" int yy_wrap (void ) { return 1; }
#define YY_NO_UNISTD_H
@@ -822,7 +825,7 @@ extern "C" int yy_wrap (void ) { return 1; }
* rules start
*/
/*----------------------------------------------------------------------------*/
#line 826 "<stdout>"
#line 829 "<stdout>"
#define INITIAL 0
#define ATTR 1
@@ -975,11 +978,11 @@ YY_DECL
register char *yy_cp, *yy_bp;
register int yy_act;
#line 51 "src/cfglexer.ll"
#line 54 "src/cfglexer.ll"
#line 983 "<stdout>"
#line 986 "<stdout>"
if ( (yy_init) )
{
@@ -1060,25 +1063,25 @@ do_action: /* This label is used only to access EOF actions. */
case 1:
YY_RULE_SETUP
#line 54 "src/cfglexer.ll"
#line 57 "src/cfglexer.ll"
{ return KW_PAROPEN; }
YY_BREAK
case 2:
YY_RULE_SETUP
#line 55 "src/cfglexer.ll"
#line 58 "src/cfglexer.ll"
{ BEGIN(INITIAL); // '}' always closes scopes
return KW_PARCLOSE; }
YY_BREAK
case 3:
YY_RULE_SETUP
#line 58 "src/cfglexer.ll"
#line 61 "src/cfglexer.ll"
{
BEGIN(ATTRVALUE);
return KW_EQUALS; }
YY_BREAK
case 4:
YY_RULE_SETUP
#line 61 "src/cfglexer.ll"
#line 64 "src/cfglexer.ll"
{ /* attribute name = normal string */
strncpy( charBuffer, yy_text, CHAR_BUFFER_SIZE-2 );
yy_lval.charValue = charBuffer;
@@ -1086,7 +1089,7 @@ YY_RULE_SETUP
YY_BREAK
case 5:
YY_RULE_SETUP
#line 65 "src/cfglexer.ll"
#line 68 "src/cfglexer.ll"
{ /* quoted string! attribute name = normal string */
strncpy( charBuffer, yy_text, CHAR_BUFFER_SIZE-2 );
/* get rid of " " */
@@ -1097,7 +1100,7 @@ YY_RULE_SETUP
YY_BREAK
case 6:
YY_RULE_SETUP
#line 72 "src/cfglexer.ll"
#line 75 "src/cfglexer.ll"
{ /* ends at newline or ';' */
strncpy( charBuffer, yy_text, CHAR_BUFFER_SIZE-2 );
yy_lval.charValue = charBuffer;
@@ -1106,428 +1109,428 @@ YY_RULE_SETUP
case 7:
/* rule 7 can match eol */
YY_RULE_SETUP
#line 76 "src/cfglexer.ll"
#line 79 "src/cfglexer.ll"
{ /* return end token... */
BEGIN(ATTR);
return KW_ATTREND; }
YY_BREAK
case 8:
YY_RULE_SETUP
#line 81 "src/cfglexer.ll"
#line 84 "src/cfglexer.ll"
{ return KW_LBMSIM; }
YY_BREAK
case 9:
YY_RULE_SETUP
#line 82 "src/cfglexer.ll"
#line 85 "src/cfglexer.ll"
{ return KW_COMPARELBM; }
YY_BREAK
case 10:
YY_RULE_SETUP
#line 83 "src/cfglexer.ll"
#line 86 "src/cfglexer.ll"
{ return KW_DEBUGMODE; }
YY_BREAK
case 11:
YY_RULE_SETUP
#line 84 "src/cfglexer.ll"
#line 87 "src/cfglexer.ll"
{ return KW_RAYTRACING; }
YY_BREAK
case 12:
YY_RULE_SETUP
#line 87 "src/cfglexer.ll"
#line 90 "src/cfglexer.ll"
{ return KW_RESOLUTION; }
YY_BREAK
case 13:
YY_RULE_SETUP
#line 88 "src/cfglexer.ll"
#line 91 "src/cfglexer.ll"
{ return KW_ANTIALIAS; }
YY_BREAK
case 14:
YY_RULE_SETUP
#line 89 "src/cfglexer.ll"
#line 92 "src/cfglexer.ll"
{ return KW_EYEPOINT; }
YY_BREAK
case 15:
YY_RULE_SETUP
#line 90 "src/cfglexer.ll"
#line 93 "src/cfglexer.ll"
{ return KW_LOOKAT ; }
YY_BREAK
case 16:
YY_RULE_SETUP
#line 91 "src/cfglexer.ll"
#line 94 "src/cfglexer.ll"
{ return KW_UPVEC ; }
YY_BREAK
case 17:
YY_RULE_SETUP
#line 92 "src/cfglexer.ll"
#line 95 "src/cfglexer.ll"
{ return KW_FOVY; }
YY_BREAK
case 18:
YY_RULE_SETUP
#line 93 "src/cfglexer.ll"
#line 96 "src/cfglexer.ll"
{ return KW_ASPECT ; }
YY_BREAK
case 19:
YY_RULE_SETUP
#line 94 "src/cfglexer.ll"
#line 97 "src/cfglexer.ll"
{ return KW_AMBIENCE; }
YY_BREAK
case 20:
YY_RULE_SETUP
#line 95 "src/cfglexer.ll"
#line 98 "src/cfglexer.ll"
{ return KW_BACKGROUND; }
YY_BREAK
case 21:
YY_RULE_SETUP
#line 96 "src/cfglexer.ll"
#line 99 "src/cfglexer.ll"
{ return KW_ANISTART; }
YY_BREAK
case 22:
YY_RULE_SETUP
#line 97 "src/cfglexer.ll"
#line 100 "src/cfglexer.ll"
{ return KW_ANIFRAMES; }
YY_BREAK
case 23:
YY_RULE_SETUP
#line 98 "src/cfglexer.ll"
#line 101 "src/cfglexer.ll"
{ return KW_ANIFRAMETIME; }
YY_BREAK
case 24:
YY_RULE_SETUP
#line 99 "src/cfglexer.ll"
#line 102 "src/cfglexer.ll"
{ return KW_FRAMESKIP; }
YY_BREAK
case 25:
YY_RULE_SETUP
#line 100 "src/cfglexer.ll"
#line 103 "src/cfglexer.ll"
{ return KW_FILENAME; }
YY_BREAK
case 26:
YY_RULE_SETUP
#line 101 "src/cfglexer.ll"
#line 104 "src/cfglexer.ll"
{ return KW_PMCAUSTICS; }
YY_BREAK
case 27:
YY_RULE_SETUP
#line 102 "src/cfglexer.ll"
#line 105 "src/cfglexer.ll"
{ return KW_CAUSTICDIST; }
YY_BREAK
case 28:
YY_RULE_SETUP
#line 103 "src/cfglexer.ll"
#line 106 "src/cfglexer.ll"
{ return KW_CAUSTICPHOT; }
YY_BREAK
case 29:
YY_RULE_SETUP
#line 104 "src/cfglexer.ll"
#line 107 "src/cfglexer.ll"
{ return KW_SHADOWMAPBIAS; }
YY_BREAK
case 30:
YY_RULE_SETUP
#line 105 "src/cfglexer.ll"
#line 108 "src/cfglexer.ll"
{ return KW_MAXRAYDEPTH; }
YY_BREAK
case 31:
YY_RULE_SETUP
#line 106 "src/cfglexer.ll"
#line 109 "src/cfglexer.ll"
{ return KW_TREEMAXDEPTH; }
YY_BREAK
case 32:
YY_RULE_SETUP
#line 107 "src/cfglexer.ll"
#line 110 "src/cfglexer.ll"
{ return KW_TREEMAXTRIANGLES; }
YY_BREAK
case 33:
YY_RULE_SETUP
#line 108 "src/cfglexer.ll"
#line 111 "src/cfglexer.ll"
{ return KW_DEBUGPIXEL; }
YY_BREAK
case 34:
YY_RULE_SETUP
#line 109 "src/cfglexer.ll"
#line 112 "src/cfglexer.ll"
{ return KW_TESTMODE; }
YY_BREAK
case 35:
YY_RULE_SETUP
#line 110 "src/cfglexer.ll"
#line 113 "src/cfglexer.ll"
{ return KW_OPENGLATTR; }
YY_BREAK
case 36:
YY_RULE_SETUP
#line 111 "src/cfglexer.ll"
#line 114 "src/cfglexer.ll"
{ return KW_BLENDERATTR; }
YY_BREAK
case 37:
YY_RULE_SETUP
#line 113 "src/cfglexer.ll"
#line 116 "src/cfglexer.ll"
{ return KW_OBJATTR; /* assign attr to obj */ }
YY_BREAK
case 38:
YY_RULE_SETUP
#line 114 "src/cfglexer.ll"
#line 117 "src/cfglexer.ll"
{ BEGIN(ATTR); return KW_ATTRIBUTE; /* global attr list */ }
YY_BREAK
case 39:
YY_RULE_SETUP
#line 115 "src/cfglexer.ll"
#line 118 "src/cfglexer.ll"
{ BEGIN(ATTR); return KW_DEFINEATTR; /* obj defines new attrs */ }
YY_BREAK
case 40:
YY_RULE_SETUP
#line 116 "src/cfglexer.ll"
#line 119 "src/cfglexer.ll"
{ BEGIN(ATTR); return KW_DEFINEATTR; }
YY_BREAK
case 41:
YY_RULE_SETUP
#line 117 "src/cfglexer.ll"
#line 120 "src/cfglexer.ll"
{ BEGIN(ATTR); return KW_DEFINEATTR; }
YY_BREAK
case 42:
YY_RULE_SETUP
#line 119 "src/cfglexer.ll"
#line 122 "src/cfglexer.ll"
{ return KW_GEOMETRY; }
YY_BREAK
case 43:
YY_RULE_SETUP
#line 120 "src/cfglexer.ll"
#line 123 "src/cfglexer.ll"
{ return KW_TYPE; }
YY_BREAK
case 44:
YY_RULE_SETUP
#line 121 "src/cfglexer.ll"
#line 124 "src/cfglexer.ll"
{ return KW_GEOTYPE_BOX; }
YY_BREAK
case 45:
YY_RULE_SETUP
#line 122 "src/cfglexer.ll"
#line 125 "src/cfglexer.ll"
{ return KW_GEOTYPE_SPHERE; }
YY_BREAK
case 46:
YY_RULE_SETUP
#line 123 "src/cfglexer.ll"
#line 126 "src/cfglexer.ll"
{ return KW_GEOTYPE_OBJMODEL; }
YY_BREAK
case 47:
YY_RULE_SETUP
#line 124 "src/cfglexer.ll"
#line 127 "src/cfglexer.ll"
{ return KW_CASTSHADOWS; }
YY_BREAK
case 48:
YY_RULE_SETUP
#line 125 "src/cfglexer.ll"
#line 128 "src/cfglexer.ll"
{ return KW_RECEIVESHADOWS ; }
YY_BREAK
case 49:
YY_RULE_SETUP
#line 126 "src/cfglexer.ll"
#line 129 "src/cfglexer.ll"
{ return KW_VISIBLE; }
YY_BREAK
case 50:
YY_RULE_SETUP
#line 127 "src/cfglexer.ll"
#line 130 "src/cfglexer.ll"
{ return KW_BOX_START; }
YY_BREAK
case 51:
YY_RULE_SETUP
#line 128 "src/cfglexer.ll"
#line 131 "src/cfglexer.ll"
{ return KW_BOX_END; }
YY_BREAK
case 52:
YY_RULE_SETUP
#line 129 "src/cfglexer.ll"
#line 132 "src/cfglexer.ll"
{ return KW_POLY ; }
YY_BREAK
case 53:
YY_RULE_SETUP
#line 130 "src/cfglexer.ll"
#line 133 "src/cfglexer.ll"
{ return KW_POLY ; }
YY_BREAK
case 54:
YY_RULE_SETUP
#line 131 "src/cfglexer.ll"
#line 134 "src/cfglexer.ll"
{ return KW_NUMVERTICES; }
YY_BREAK
case 55:
YY_RULE_SETUP
#line 132 "src/cfglexer.ll"
#line 135 "src/cfglexer.ll"
{ return KW_VERTEX; }
YY_BREAK
case 56:
YY_RULE_SETUP
#line 133 "src/cfglexer.ll"
#line 136 "src/cfglexer.ll"
{ return KW_NUMPOLYGONS; }
YY_BREAK
case 57:
YY_RULE_SETUP
#line 134 "src/cfglexer.ll"
#line 137 "src/cfglexer.ll"
{ return KW_ISOSURF; }
YY_BREAK
case 58:
YY_RULE_SETUP
#line 135 "src/cfglexer.ll"
#line 138 "src/cfglexer.ll"
{ return KW_FILEMODE; }
YY_BREAK
case 59:
YY_RULE_SETUP
#line 136 "src/cfglexer.ll"
#line 139 "src/cfglexer.ll"
{ return KW_INVERT; }
YY_BREAK
case 60:
YY_RULE_SETUP
#line 138 "src/cfglexer.ll"
#line 141 "src/cfglexer.ll"
{ return KW_MATERIAL; }
YY_BREAK
case 61:
YY_RULE_SETUP
#line 139 "src/cfglexer.ll"
#line 142 "src/cfglexer.ll"
{ return KW_MATTYPE_PHONG; }
YY_BREAK
case 62:
YY_RULE_SETUP
#line 140 "src/cfglexer.ll"
#line 143 "src/cfglexer.ll"
{ return KW_MATTYPE_BLINN; }
YY_BREAK
case 63:
YY_RULE_SETUP
#line 141 "src/cfglexer.ll"
#line 144 "src/cfglexer.ll"
{ return KW_NAME; }
YY_BREAK
case 64:
YY_RULE_SETUP
#line 142 "src/cfglexer.ll"
#line 145 "src/cfglexer.ll"
{ return KW_AMBIENT; }
YY_BREAK
case 65:
YY_RULE_SETUP
#line 143 "src/cfglexer.ll"
#line 146 "src/cfglexer.ll"
{ return KW_DIFFUSE; }
YY_BREAK
case 66:
YY_RULE_SETUP
#line 144 "src/cfglexer.ll"
#line 147 "src/cfglexer.ll"
{ return KW_SPECULAR; }
YY_BREAK
case 67:
YY_RULE_SETUP
#line 145 "src/cfglexer.ll"
#line 148 "src/cfglexer.ll"
{ return KW_MIRROR; }
YY_BREAK
case 68:
YY_RULE_SETUP
#line 146 "src/cfglexer.ll"
#line 149 "src/cfglexer.ll"
{ return KW_TRANSPARENCE; }
YY_BREAK
case 69:
YY_RULE_SETUP
#line 147 "src/cfglexer.ll"
#line 150 "src/cfglexer.ll"
{ return KW_REFRACINDEX; }
YY_BREAK
case 70:
YY_RULE_SETUP
#line 148 "src/cfglexer.ll"
#line 151 "src/cfglexer.ll"
{ return KW_TRANSADDITIVE; }
YY_BREAK
case 71:
YY_RULE_SETUP
#line 149 "src/cfglexer.ll"
#line 152 "src/cfglexer.ll"
{ return KW_TRANSATTCOL; }
YY_BREAK
case 72:
YY_RULE_SETUP
#line 150 "src/cfglexer.ll"
#line 153 "src/cfglexer.ll"
{ return KW_FRESNEL; }
YY_BREAK
case 73:
YY_RULE_SETUP
#line 151 "src/cfglexer.ll"
#line 154 "src/cfglexer.ll"
{ return KW_FRESNEL; }
YY_BREAK
case 74:
YY_RULE_SETUP
#line 153 "src/cfglexer.ll"
#line 156 "src/cfglexer.ll"
{ return KW_LIGHT; }
YY_BREAK
case 75:
YY_RULE_SETUP
#line 154 "src/cfglexer.ll"
#line 157 "src/cfglexer.ll"
{ return KW_LIGHT_OMNI; }
YY_BREAK
case 76:
YY_RULE_SETUP
#line 155 "src/cfglexer.ll"
#line 158 "src/cfglexer.ll"
{ return KW_ACTIVE; }
YY_BREAK
case 77:
YY_RULE_SETUP
#line 156 "src/cfglexer.ll"
#line 159 "src/cfglexer.ll"
{ return KW_COLOUR; }
YY_BREAK
case 78:
YY_RULE_SETUP
#line 157 "src/cfglexer.ll"
#line 160 "src/cfglexer.ll"
{ return KW_COLOUR; }
YY_BREAK
case 79:
YY_RULE_SETUP
#line 158 "src/cfglexer.ll"
#line 161 "src/cfglexer.ll"
{ return KW_POSITION; }
YY_BREAK
case 80:
YY_RULE_SETUP
#line 159 "src/cfglexer.ll"
#line 162 "src/cfglexer.ll"
{ return KW_CAUSTICPHOTONS; }
YY_BREAK
case 81:
YY_RULE_SETUP
#line 160 "src/cfglexer.ll"
#line 163 "src/cfglexer.ll"
{ return KW_CAUSTICSTRENGTH; }
YY_BREAK
case 82:
YY_RULE_SETUP
#line 161 "src/cfglexer.ll"
#line 164 "src/cfglexer.ll"
{ return KW_SHADOWMAP; }
YY_BREAK
case 83:
YY_RULE_SETUP
#line 162 "src/cfglexer.ll"
#line 165 "src/cfglexer.ll"
{ return KW_CAUSTICSMAP; }
YY_BREAK
case 84:
YY_RULE_SETUP
#line 164 "src/cfglexer.ll"
#line 167 "src/cfglexer.ll"
{ yy_lval.intValue = 1; return DT_INTEGER; }
YY_BREAK
case 85:
YY_RULE_SETUP
#line 165 "src/cfglexer.ll"
#line 168 "src/cfglexer.ll"
{ yy_lval.intValue = 0; return DT_INTEGER; }
YY_BREAK
case 86:
YY_RULE_SETUP
#line 166 "src/cfglexer.ll"
#line 169 "src/cfglexer.ll"
{ yy_lval.intValue = 1; return DT_INTEGER; }
YY_BREAK
case 87:
YY_RULE_SETUP
#line 167 "src/cfglexer.ll"
#line 170 "src/cfglexer.ll"
{ yy_lval.intValue = 0; return DT_INTEGER; }
YY_BREAK
case 88:
YY_RULE_SETUP
#line 170 "src/cfglexer.ll"
#line 173 "src/cfglexer.ll"
{ // integer number
yy_lval.intValue = atoi( yy_text );
return DT_INTEGER; }
YY_BREAK
case 89:
YY_RULE_SETUP
#line 174 "src/cfglexer.ll"
#line 177 "src/cfglexer.ll"
{ // floating point number
yy_lval.floatValue = atof( yy_text );
return DT_FLOAT; }
YY_BREAK
case 90:
YY_RULE_SETUP
#line 178 "src/cfglexer.ll"
#line 181 "src/cfglexer.ll"
{ /* normal character strings, now also for paths/filenames */
strncpy( charBuffer, yy_text, CHAR_BUFFER_SIZE-2 );
/* get rid of " " */
@@ -1538,17 +1541,17 @@ YY_RULE_SETUP
YY_BREAK
case 91:
YY_RULE_SETUP
#line 186 "src/cfglexer.ll"
#line 189 "src/cfglexer.ll"
{ /* one line comment */ }
YY_BREAK
case 92:
YY_RULE_SETUP
#line 187 "src/cfglexer.ll"
#line 190 "src/cfglexer.ll"
{ /* one line comment */ }
YY_BREAK
case 93:
YY_RULE_SETUP
#line 188 "src/cfglexer.ll"
#line 191 "src/cfglexer.ll"
{ /* multiline comment */
register int c;
for ( ; ; ) {
@@ -1574,26 +1577,26 @@ YY_RULE_SETUP
case 94:
/* rule 94 can match eol */
YY_RULE_SETUP
#line 212 "src/cfglexer.ll"
#line 215 "src/cfglexer.ll"
{ // count line numbers
lineCount++; }
YY_BREAK
case 95:
YY_RULE_SETUP
#line 215 "src/cfglexer.ll"
#line 218 "src/cfglexer.ll"
{ /* do nothing by default... */ }
YY_BREAK
case 96:
YY_RULE_SETUP
#line 217 "src/cfglexer.ll"
{ /*errorOut( "cfgLexer, Line "<<lineCount<<" : Unknown character '"<<(char)yyinput()<<"' " ); exit(1); */ }
#line 220 "src/cfglexer.ll"
{ /*errorOut( "cfgLexer, Line "<<lineCount<<" : Unknown character '"<<(char)yyinput()<<"' " ); xit(1); */ }
YY_BREAK
case 97:
YY_RULE_SETUP
#line 220 "src/cfglexer.ll"
#line 223 "src/cfglexer.ll"
ECHO;
YY_BREAK
#line 1597 "<stdout>"
#line 1600 "<stdout>"
case YY_STATE_EOF(INITIAL):
case YY_STATE_EOF(ATTR):
case YY_STATE_EOF(ATTRVALUE):
@@ -2558,4 +2561,4 @@ void yy_free (void * ptr )
#undef YY_DECL_IS_OURS
#undef YY_DECL
#endif
#line 220 "src/cfglexer.ll"
#line 223 "src/cfglexer.ll"

View File

@@ -360,7 +360,7 @@ typedef union YYSTYPE {
char *charValue;
} YYSTYPE;
/* Line 191 of yacc.c. */
#line 364 "bld-std-gcc/src/cfgparser.cpp"
#line 364 "bld-std-gcc40/src/cfgparser.cpp"
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
@@ -372,7 +372,7 @@ typedef union YYSTYPE {
/* Line 214 of yacc.c. */
#line 376 "bld-std-gcc/src/cfgparser.cpp"
#line 376 "bld-std-gcc40/src/cfgparser.cpp"
#if ! defined (yyoverflow) || YYERROR_VERBOSE
@@ -1549,7 +1549,7 @@ yyreduce:
case 37:
#line 204 "src/cfgparser.yy"
{ reglob->setAniFrameTime( yyvsp[0].intValue ); }
{ /*reglob->setAniFrameTime( $2 );*/ debMsgStd("cfgparser",DM_NOTIFY,"Deprecated setting aniframetime!",1); }
break;
case 38:
@@ -2047,7 +2047,7 @@ yyreduce:
}
/* Line 1010 of yacc.c. */
#line 2051 "bld-std-gcc/src/cfgparser.cpp"
#line 2051 "bld-std-gcc40/src/cfgparser.cpp"
yyvsp -= yylen;
yyssp -= yylen;
@@ -2290,8 +2290,8 @@ void yy_warn(char *s)
void yy_error(const char *s)
{
//errorOut("Current token: "<<yytname[ (int)yytranslate[yychar] ]);
errorOut("Config Parse Error at Line "<<lineCount<<": "<<s );
exit(1);
errFatal("yy_error","Config Parse Error at Line "<<lineCount<<": "<<s,SIMWORLD_INITERROR);
return;
}
@@ -2303,8 +2303,8 @@ void setPointers(ntlRenderGlobals *setglob)
(!setglob) ||
(!setglob)
) {
errMsg("setPointers","Config Parse Error: Invalid Pointers!\n");
exit(1);
errFatal("setPointers","Config Parse Error: Invalid Pointers!\n",SIMWORLD_INITERROR);
return;
}
reglob = setglob;
@@ -2316,15 +2316,15 @@ void setPointers(ntlRenderGlobals *setglob)
void parseFile(string filename)
{
if(!pointersInited) {
errMsg("parseFile","Config Parse Error: Pointers not set!\n");
exit(1);
errFatal("parseFile","Config Parse Error: Pointers not set!\n", SIMWORLD_INITERROR);
return;
}
/* open file */
yy_in = fopen( filename.c_str(), "r");
if(!yy_in) {
errMsg("parseFile","Config Parse Error: Unable to open '"<<filename.c_str() <<"'!\n" );
exit(1);
errFatal("parseFile","Config Parse Error: Unable to open '"<<filename.c_str() <<"'!\n", SIMWORLD_INITERROR );
return;
}
/* parse */

View File

@@ -247,7 +247,7 @@ typedef union YYSTYPE {
char *charValue;
} YYSTYPE;
/* Line 1285 of yacc.c. */
#line 251 "bld-std-gcc/src/cfgparser.hpp"
#line 251 "bld-std-gcc40/src/cfgparser.hpp"
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1

View File

@@ -117,8 +117,8 @@ void IsoSurface::triangulate( void )
myTime_t tritimestart = getTime();
if(!mpData) {
errorOut("IsoSurface::triangulate fatal error: no LBM object, and no scalar field...!");
exit( -1 );
errFatal("IsoSurface::triangulate","no LBM object, and no scalar field...!",SIMWORLD_INITERROR);
return;
}
// get grid spacing
@@ -332,9 +332,7 @@ void IsoSurface::triangulate( void )
smoothNormals(mSmoothNormals);
}
myTime_t tritimeend = getTime();
#if ELBEEM_BLENDER!=1
debMsgStd("IsoSurface::triangulate",DM_MSG,"Took "<< ((tritimeend-tritimestart)/(double)1000.0)<<"s) " , 10 );
#endif // ELBEEM_BLENDER!=1
}
@@ -361,8 +359,9 @@ void IsoSurface::getTriangles( vector<ntlTriangle> *triangles,
int iniVertIndex = (*vertices).size();
int iniNormIndex = (*normals).size();
if(iniVertIndex != iniNormIndex) {
errorOut("getTriangles Error for '"<<mName<<"': Vertices and normal array sizes to not match!!!");
exit(1); }
errFatal("getTriangles Error","For '"<<mName<<"': Vertices and normal array sizes to not match!!!",SIMWORLD_GENERICERROR);
return;
}
//errMsg("NM"," ivi"<<iniVertIndex<<" ini"<<iniNormIndex<<" vs"<<vertices->size()<<" ns"<<normals->size()<<" ts"<<triangles->size() );
//errMsg("NM"," ovs"<<mVertices.size()<<" ons"<<mVertNormals.size()<<" ots"<<mIndices.size() );
@@ -447,8 +446,6 @@ inline ntlVec3Gfx IsoSurface::getNormal(int i, int j,int k) {
// Subdivide a mesh allways loop
void IsoSurface::subdivide()
{
int i;
mAdjacentFaces.clear();
mAcrossEdge.clear();
@@ -456,18 +453,17 @@ void IsoSurface::subdivide()
{
vector<int> numadjacentfaces(mPoints.size());
//errMsg("SUBDIV ADJFA1", " "<<mPoints.size()<<" - "<<numadjacentfaces.size() );
int i;
for (i = 0; i < (int)mIndices.size()/3; i++) {
for (int 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++)
for (int i = 0; i < (int)mPoints.size(); i++)
mAdjacentFaces[i].reserve(numadjacentfaces[i]);
for (i = 0; i < (int)mIndices.size()/3; i++) {
for (int i = 0; i < (int)mIndices.size()/3; i++) {
for (int j = 0; j < 3; j++)
mAdjacentFaces[mIndices[i*3 + j]].push_back(i);
}
@@ -529,7 +525,7 @@ void IsoSurface::subdivide()
vector<int> newvert_count(old_nv + 3*nf); // wichtig...?
//errMsg("NC", newvert_count.size() );
for (i = 0; i < nf; i++) {
for (int 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) {
@@ -580,7 +576,7 @@ void IsoSurface::subdivide()
newvert_count[newverts[i*3 + j]]++;
}
}
for (i = old_nv; i < (int)mPoints.size(); i++) {
for (int i = old_nv; i < (int)mPoints.size(); i++) {
if (!newvert_count[i])
continue;
float scale = 1.0f / newvert_count[i];
@@ -593,7 +589,7 @@ void IsoSurface::subdivide()
}
// Update old vertices
for (i = 0; i < old_nv; i++) {
for (int 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;
@@ -667,7 +663,7 @@ void IsoSurface::subdivide()
// Insert new faces
mIndices.reserve(4*nf);
for (i = 0; i < nf; i++) {
for (int 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]);
@@ -688,11 +684,11 @@ void IsoSurface::subdivide()
// recalc normals
#if RECALCNORMALS==1
{
int nf = (int)mIndices.size()/3, nv = (int)mPoints.size(), i;
for (i = 0; i < nv; i++) {
int nf = (int)mIndices.size()/3, nv = (int)mPoints.size();
for (int i = 0; i < nv; i++) {
mPoints[i].n = ntlVec3Gfx(0.0);
}
for (i = 0; i < nf; i++) {
for (int 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;
@@ -706,12 +702,12 @@ void IsoSurface::subdivide()
mPoints[mIndices[i*3+2]].n += facenormal * (1.0f / (l2c * l2b));
}
for (i = 0; i < nv; i++) {
for (int i = 0; i < nv; i++) {
normalize(mPoints[i].n);
}
}
#else // RECALCNORMALS==1
for (i = 0; i < (int)mPoints.size(); i++) {
for (int i = 0; i < (int)mPoints.size(); i++) {
normalize(mPoints[i].n);
}
#endif // RECALCNORMALS==1

View File

@@ -186,6 +186,8 @@ public:
};
struct BBox {
public:
BBox() {};
ntlVec3Gfx min, max;
ntlVec3Gfx center() const { return (min+max)*0.5f; }
ntlVec3Gfx size() const { return max - min; }

View File

@@ -88,10 +88,10 @@ class LbmD3Q19 {
STCON char* dfString[ 19 ];
/*! index of normal dist func, not used so far?... */
STCON dfDir dfNorm[ 19 ];
STCON int dfNorm[ 19 ];
/*! index of inverse dist func, not fast, but useful... */
STCON dfDir dfInv[ 19 ];
STCON int dfInv[ 19 ];
/*! index of x reflected dist func for free slip, not valid for all DFs... */
STCON int dfRefX[ 19 ];
@@ -185,10 +185,10 @@ class LbmD2Q9 {
STCON char* dfString[ 9 ];
/* index of normal dist func, not used so far?... */
STCON dfDir dfNorm[ 9 ];
STCON int dfNorm[ 9 ];
/* index of inverse dist func, not fast, but useful... */
STCON dfDir dfInv[ 9 ];
STCON int dfInv[ 9 ];
/* index of x reflected dist func for free slip, not valid for all DFs... */
STCON int dfRefX[ 9 ];

View File

@@ -25,6 +25,7 @@
#define PARALLEL 0
#endif // PARALLEL
// blender interface
#if ELBEEM_BLENDER==1
#include "SDL.h"
#include "SDL_thread.h"
@@ -43,6 +44,8 @@ ERROR - define model first!
#endif // LBMMODEL_DEFINED
// general solver setting defines
//! debug coordinate accesses and the like? (much slower)
#define FSGR_STRICT_DEBUG 0
@@ -61,9 +64,6 @@ ERROR - define model first!
//! refinement border method (1 = small border / 2 = larger)
#define REFINEMENTBORDER 1
// interpolateCellFromCoarse test
#define INTCFCOARSETEST 1
// use optimized 3D code?
#if LBMDIM==2
#define OPT3D false
@@ -86,16 +86,6 @@ ERROR - define model first!
#define COMPRESSGRIDS 0
#endif
// 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__ ); \
debugMarkCellCall((lev),(x),(y),(z));
#else // FSGR_STRICT_DEBUG==1
#define debugMarkCell(lev,x,y,z) \
debugMarkCellCall((lev),(x),(y),(z));
#endif // FSGR_STRICT_DEBUG==1
//! threshold for level set fluid generation/isosurface
#define LS_FLUIDTHRESHOLD 0.5
@@ -110,6 +100,409 @@ ERROR - define model first!
#define FSGR_MAGICNR 0.025
//0.04
// helper for comparing floats with epsilon
#define GFX_FLOATNEQ(x,y) ( ABS((x)-(y)) > (VECTOR_EPSILON) )
#define LBM_FLOATNEQ(x,y) ( ABS((x)-(y)) > (10.0*LBM_EPSILON) )
// macros for loops over all DFs
#define FORDF0 for(int l= 0; l< LBM_DFNUM; ++l)
#define FORDF1 for(int l= 1; l< LBM_DFNUM; ++l)
// and with different loop var to prevent shadowing
#define FORDF0M for(int m= 0; m< LBM_DFNUM; ++m)
#define FORDF1M for(int m= 1; m< LBM_DFNUM; ++m)
// aux. field indices (same for 2d)
#define dFfrac 19
#define dMass 20
#define dFlux 21
// max. no. of cell values for 3d
#define dTotalNum 22
// iso value defines
// border for marching cubes
#define ISOCORR 3
/*****************************************************************************/
/*! cell access classes */
template<typename D>
class UniformFsgrCellIdentifier :
public CellIdentifierInterface
{
public:
//! which grid level?
int level;
//! location in grid
int x,y,z;
//! reset constructor
UniformFsgrCellIdentifier() :
x(0), y(0), z(0) { };
// implement CellIdentifierInterface
virtual string getAsString() {
std::ostringstream ret;
ret <<"{ i"<<x<<",j"<<y;
if(D::cDimension>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 );
if(!cid) return false;
if( x==cid->x && y==cid->y && z==cid->z && level==cid->level ) return true;
return false;
}
};
//! information needed for each level in the simulation
class FsgrLevelData {
public:
int id; // level number
//! node size on this level (geometric, in world coordinates, not simulation units!)
LbmFloat nodeSize;
//! node size on this level in simulation units
LbmFloat simCellSize;
//! quadtree node relaxation parameter
LbmFloat omega;
//! size this level was advanced to
LbmFloat time;
//! size of a single lbm step in time units on this level
LbmFloat stepsize;
//! step count
int lsteps;
//! gravity force for this level
LbmVec gravity;
//! level array
LbmFloat *mprsCells[2];
CellFlagType *mprsFlags[2];
//! smago params and precalculated values
LbmFloat lcsmago;
LbmFloat lcsmago_sqr;
LbmFloat lcnu;
// LES statistics per level
double avgOmega;
double avgOmegaCnt;
//! current set of dist funcs
int setCurr;
//! target/other set of dist funcs
int setOther;
//! mass&volume for this level
LbmFloat lmass;
LbmFloat lvolume;
LbmFloat lcellfactor;
//! local storage of mSizes
int lSizex, lSizey, lSizez;
int lOffsx, lOffsy, lOffsz;
};
/*****************************************************************************/
/*! class for solving a LBM problem */
template<class D>
class LbmFsgrSolver :
public /*? virtual */ D // this means, the solver is a lbmData object and implements the lbmInterface
{
public:
//! Constructor
LbmFsgrSolver();
//! Destructor
virtual ~LbmFsgrSolver();
//! id string of solver
virtual string getIdString() { return string("FsgrSolver[") + D::getIdString(); }
//! 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 initialize( ntlTree* /*tree*/, vector<ntlGeometryObject*>* /*objects*/ );
#if LBM_USE_GUI==1
//! show simulation info (implement SimulationObject pure virtual func)
virtual void debugDisplay(fluidDispSettings *set);
#endif
// implement CellIterator<UniformFsgrCellIdentifier> interface
typedef UniformFsgrCellIdentifier<typename D::LbmCellContents> stdCellId;
virtual CellIdentifierInterface* getFirstCell( );
virtual void advanceCell( CellIdentifierInterface* );
virtual bool noEndCell( CellIdentifierInterface* );
virtual void deleteCellIterator( CellIdentifierInterface** );
virtual CellIdentifierInterface* getCellAt( ntlVec3Gfx pos );
virtual int getCellSet ( CellIdentifierInterface* );
virtual ntlVec3Gfx getCellOrigin ( CellIdentifierInterface* );
virtual ntlVec3Gfx getCellSize ( CellIdentifierInterface* );
virtual int getCellLevel ( CellIdentifierInterface* );
virtual LbmFloat getCellDensity ( CellIdentifierInterface* ,int set);
virtual LbmVec getCellVelocity ( CellIdentifierInterface* ,int set);
virtual LbmFloat getCellDf ( CellIdentifierInterface* ,int set, int dir);
virtual LbmFloat getCellMass ( CellIdentifierInterface* ,int set);
virtual LbmFloat getCellFill ( CellIdentifierInterface* ,int set);
virtual CellFlagType getCellFlag ( CellIdentifierInterface* ,int set);
virtual LbmFloat getEquilDf ( int );
virtual int getDfNum ( );
// convert pointers
stdCellId* convertBaseCidToStdCid( CellIdentifierInterface* basecid);
//! perform geometry init (if switched on)
bool initGeometryFlags();
//! init part for all freesurface testcases
void initFreeSurfaces();
//! init density gradient if enabled
void initStandingFluidGradient();
/*! init a given cell with flag, density, mass and equilibrium dist. funcs */
inline void initEmptyCell(int level, int i,int j,int k, CellFlagType flag, LbmFloat rho, LbmFloat mass);
inline void initVelocityCell(int level, int i,int j,int k, CellFlagType flag, LbmFloat rho, LbmFloat mass, LbmVec vel);
inline void changeFlag(int level, int xx,int yy,int zz,int set,CellFlagType newflag);
/*! perform a single LBM step */
virtual void step() { stepMain(); }
void stepMain();
void fineAdvance();
void coarseAdvance(int lev);
void coarseCalculateFluxareas(int lev);
// coarsen a given level (returns true if sth. was changed)
bool performRefinement(int lev);
bool performCoarsening(int lev);
//void oarseInterpolateToFineSpaceTime(int lev,LbmFloat t);
void interpolateFineFromCoarse(int lev,LbmFloat t);
void coarseRestrictFromFine(int lev);
/*! init particle positions */
virtual int initParticles(ParticleTracer *partt);
/*! move all particles */
virtual void advanceParticles(ParticleTracer *partt );
/*! debug object display (used e.g. for preview surface) */
virtual vector<ntlGeometryObject*> getDebugObjects();
//! access the fillfrac field (for viz)
inline float getFillFrac(int i, int j, int k);
//! retrieve the fillfrac field ready to display
void getIsofieldWeighted(float *iso);
void getIsofield(float *iso){ return getIsofieldWeighted(iso); }
//! for raytracing, preprocess
void prepareVisualization( void );
// rt interface
void addDrop(bool active, float mx, float my);
void initDrop(float mx, float my);
void printCellStats();
int checkGfxEndTime(); // {return 9;};
//! get gfx geo setup id
int getGfxGeoSetup() { return mGfxGeoSetup; }
/*! type for cells */
typedef typename D::LbmCell LbmCell;
protected:
//! internal quick print function (for debugging)
void printLbmCell(int level, int i, int j, int k,int set);
// debugging use CellIterator interface to mark cell
void debugMarkCellCall(int level, int vi,int vj,int vk);
void mainLoop(int lev);
void adaptTimestep();
//! init mObjectSpeeds for current parametrization
void recalculateObjectSpeeds();
//! flag reinit step - always works on finest grid!
void reinitFlags( int workSet );
//! mass dist weights
LbmFloat getMassdWeight(bool dirForw, int i,int j,int k,int workSet, int l);
//! add point to mListNewInter list
inline void addToNewInterList( int ni, int nj, int nk );
//! cell is interpolated from coarse level (inited into set, source sets are determined by t)
inline void interpolateCellFromCoarse(int lev, int i, int j,int k, int dstSet, LbmFloat t, CellFlagType flagSet,bool markNbs);
//! minimal and maximal z-coords (for 2D/3D loops)
int getForZMinBnd() { return 0; }
int getForZMin1() {
if(D::cDimension==2) return 0;
return 1;
}
int getForZMaxBnd(int lev) {
if(D::cDimension==2) return 1;
return mLevel[lev].lSizez -0;
}
int getForZMax1(int lev) {
if(D::cDimension==2) return 1;
return mLevel[lev].lSizez -1;
}
// member vars
//! mass calculated during streaming step
LbmFloat mCurrentMass;
LbmFloat mCurrentVolume;
LbmFloat mInitialMass;
//! count problematic cases, that occured so far...
int mNumProblems;
// average mlsups, count how many so far...
double mAvgMLSUPS;
double mAvgMLSUPSCnt;
//! Mcubes object for surface reconstruction
IsoSurface *mpPreviewSurface;
int mLoopSubdivs;
float mSmoothSurface;
float mSmoothNormals;
//! use time adaptivity?
bool mTimeAdap;
//! output surface preview? if >0 yes, and use as reduzed size
int mOutputSurfacePreview;
LbmFloat mPreviewFactor;
//! fluid vol height
LbmFloat mFVHeight;
LbmFloat mFVArea;
bool mUpdateFVHeight;
//! require some geo setup from the viz?
int mGfxGeoSetup;
//! force quit for gfx
LbmFloat mGfxEndTime;
//! smoother surface initialization?
int mInitSurfaceSmoothing;
int mTimestepReduceLock;
int mTimeSwitchCounts;
//! total simulation time so far
LbmFloat mSimulationTime;
//! smallest and largest step size so far
LbmFloat mMinStepTime, mMaxStepTime;
//! track max. velocity
LbmFloat mMxvx, mMxvy, mMxvz, mMaxVlen;
//! list of the cells to empty at the end of the step
vector<LbmPoint> mListEmpty;
//! list of the cells to make fluid at the end of the step
vector<LbmPoint> mListFull;
//! list of new interface cells to init
vector<LbmPoint> mListNewInter;
//! class for handling redist weights in reinit flag function
class lbmFloatSet {
public:
LbmFloat val[dTotalNum];
LbmFloat numNbs;
};
//! normalized vectors for all neighboring cell directions (for e.g. massdweight calc)
LbmVec mDvecNrm[27];
//! debugging
bool checkSymmetry(string idstring);
//! symmetric init?
//bool mStartSymm;
//! kepp track of max/min no. of filled cells
int mMaxNoCells, mMinNoCells;
long long int mAvgNumUsedCells;
//! for interactive - how to drop drops?
int mDropMode;
LbmFloat mDropSize;
LbmVec mDropSpeed;
//! dropping variables
bool mDropping;
LbmFloat mDropX, mDropY;
LbmFloat mDropHeight;
//! precalculated objects speeds for current parametrization
vector<LbmVec> mObjectSpeeds;
//! get isofield weights
int mIsoWeightMethod;
float mIsoWeight[27];
// grid coarsening vars
/*! vector for the data for each level */
# define MAX_LEV 5
FsgrLevelData mLevel[MAX_LEV];
/*! minimal and maximal refinement levels */
int mMaxRefine;
/*! df scale factors for level up/down */
LbmFloat mDfScaleUp, mDfScaleDown;
/*! precomputed cell area values */
LbmFloat mFsgrCellArea[27];
/*! LES C_smago paramter for finest grid */
float mInitialCsmago;
/*! LES C_smago paramter for coarser grids */
float mInitialCsmagoCoarse;
/*! LES stats for non OPT3D */
LbmFloat mDebugOmegaRet;
//! fluid stats
int mNumInterdCells;
int mNumInvIfCells;
int mNumInvIfTotal;
int mNumFsgrChanges;
//! debug function to disable standing f init
int mDisableStandingFluidInit;
//! debug function to force tadap syncing
int mForceTadapRefine;
// strict debug interface
# if FSGR_STRICT_DEBUG==1
int debLBMGI(int level, int ii,int ij,int ik, int is);
CellFlagType& debRFLAG(int level, int xx,int yy,int zz,int set);
CellFlagType& debRFLAG_NB(int level, int xx,int yy,int zz,int set, int dir);
CellFlagType& debRFLAG_NBINV(int level, int xx,int yy,int zz,int set, int dir);
int debLBMQI(int level, int ii,int ij,int ik, int is, int l);
LbmFloat& debQCELL(int level, int xx,int yy,int zz,int set,int l);
LbmFloat& debQCELL_NB(int level, int xx,int yy,int zz,int set, int dir,int l);
LbmFloat& debQCELL_NBINV(int level, int xx,int yy,int zz,int set, int dir,int l);
LbmFloat* debRACPNT(int level, int ii,int ij,int ik, int is );
LbmFloat& debRAC(LbmFloat* s,int l);
# endif // FSGR_STRICT_DEBUG==1
};
/*****************************************************************************/
// relaxation_macros
// 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__ ); \
debugMarkCellCall((lev),(x),(y),(z));
#else // FSGR_STRICT_DEBUG==1
#define debugMarkCell(lev,x,y,z) \
debugMarkCellCall((lev),(x),(y),(z));
#endif // FSGR_STRICT_DEBUG==1
// flag array defines -----------------------------------------------------------------------------------------------
// lbm testsolver get index define
@@ -244,11 +637,7 @@ ERROR - define model first!
#define dWB 18
#define LBM_DFNUM 19
#endif
#define dFfrac 19
#define dMass 20
#define dFlux 21
#define dTotalNum 22
#define dWB 18
//? #define dWB 18
// default init for dFlux values
#define FLUX_INIT 0.5f * (float)(D::cDfNum)
@@ -335,6 +724,26 @@ ERROR - define model first!
#define CCEL_EB RAC(ccel, dEB)
#define CCEL_WT RAC(ccel, dWT)
#define CCEL_WB RAC(ccel, dWB)
// for coarse to fine interpol access
#define CCELG_C(f) (RAC(ccel, dC )*mGaussw[(f)])
#define CCELG_N(f) (RAC(ccel, dN )*mGaussw[(f)])
#define CCELG_S(f) (RAC(ccel, dS )*mGaussw[(f)])
#define CCELG_E(f) (RAC(ccel, dE )*mGaussw[(f)])
#define CCELG_W(f) (RAC(ccel, dW )*mGaussw[(f)])
#define CCELG_T(f) (RAC(ccel, dT )*mGaussw[(f)])
#define CCELG_B(f) (RAC(ccel, dB )*mGaussw[(f)])
#define CCELG_NE(f) (RAC(ccel, dNE)*mGaussw[(f)])
#define CCELG_NW(f) (RAC(ccel, dNW)*mGaussw[(f)])
#define CCELG_SE(f) (RAC(ccel, dSE)*mGaussw[(f)])
#define CCELG_SW(f) (RAC(ccel, dSW)*mGaussw[(f)])
#define CCELG_NT(f) (RAC(ccel, dNT)*mGaussw[(f)])
#define CCELG_NB(f) (RAC(ccel, dNB)*mGaussw[(f)])
#define CCELG_ST(f) (RAC(ccel, dST)*mGaussw[(f)])
#define CCELG_SB(f) (RAC(ccel, dSB)*mGaussw[(f)])
#define CCELG_ET(f) (RAC(ccel, dET)*mGaussw[(f)])
#define CCELG_EB(f) (RAC(ccel, dEB)*mGaussw[(f)])
#define CCELG_WT(f) (RAC(ccel, dWT)*mGaussw[(f)])
#define CCELG_WB(f) (RAC(ccel, dWB)*mGaussw[(f)])
#if PARALLEL==1
@@ -807,458 +1216,21 @@ f__printf(stderr,"QSDM at %d,%d,%d lcsmqo=%25.15f, lcsmomega=%f \n", i,j,k, lcs
} /* stats */
// iso value defines
// border for marching cubes
#define ISOCORR 3
// helper for comparing floats with epsilon
#define GFX_FLOATNEQ(x,y) ( ABS((x)-(y)) > (VECTOR_EPSILON) )
#define LBM_FLOATNEQ(x,y) ( ABS((x)-(y)) > (10.0*LBM_EPSILON) )
// macros for loops over all DFs
#define FORDF0 for(int l= 0; l< LBM_DFNUM; ++l)
#define FORDF1 for(int l= 1; l< LBM_DFNUM; ++l)
/*****************************************************************************/
/*! cell access classes */
// WARNING - can be shadowed by class from lbmstdsolver.h 's
template<typename D>
class UniformFsgrCellIdentifier :
public CellIdentifierInterface
{
public:
//! which grid level?
int level;
//! location in grid
int x,y,z;
//! reset constructor
UniformFsgrCellIdentifier() :
x(0), y(0), z(0) { };
// implement CellIdentifierInterface
virtual string getAsString() {
std::ostringstream ret;
ret <<"{ i"<<x<<",j"<<y;
if(D::cDimension>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 );
if(!cid) return false;
if( x==cid->x && y==cid->y && z==cid->z && level==cid->level ) return true;
return false;
}
};
//! information needed for each level in the simulation
class FsgrLevelData {
public:
int id; // level number
//! node size on this level (geometric, in world coordinates, not simulation units!)
LbmFloat nodeSize;
//! node size on this level in simulation units
LbmFloat simCellSize;
//! quadtree node relaxation parameter
LbmFloat omega;
//! size this level was advanced to
LbmFloat time;
//! size of a single lbm step in time units on this level
LbmFloat stepsize;
//! step count
int lsteps;
//! gravity force for this level
LbmVec gravity;
//! level array
LbmFloat *mprsCells[2];
CellFlagType *mprsFlags[2];
//! smago params and precalculated values
LbmFloat lcsmago;
LbmFloat lcsmago_sqr;
LbmFloat lcnu;
// LES statistics per level
double avgOmega;
double avgOmegaCnt;
//! current set of dist funcs
int setCurr;
//! target/other set of dist funcs
int setOther;
//! mass&volume for this level
LbmFloat lmass;
LbmFloat lvolume;
LbmFloat lcellfactor;
//! local storage of mSizes
int lSizex, lSizey, lSizez;
int lOffsx, lOffsy, lOffsz;
};
/*****************************************************************************/
/*! class for solving a LBM problem */
template<class D>
class LbmFsgrSolver :
public /*? virtual */ D // this means, the solver is a lbmData object and implements the lbmInterface
{
public:
//! Constructor
LbmFsgrSolver();
//! Destructor
virtual ~LbmFsgrSolver();
//! id string of solver
virtual string getIdString() { return string("FsgrSolver[") + D::getIdString(); }
//! 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 initialize( ntlTree* /*tree*/, vector<ntlGeometryObject*>* /*objects*/ );
#if LBM_USE_GUI==1
//! show simulation info (implement SimulationObject pure virtual func)
virtual void debugDisplay(fluidDispSettings *set);
#endif
// implement CellIterator<UniformFsgrCellIdentifier> interface
typedef UniformFsgrCellIdentifier<typename D::LbmCellContents> stdCellId;
virtual CellIdentifierInterface* getFirstCell( );
virtual void advanceCell( CellIdentifierInterface* );
virtual bool noEndCell( CellIdentifierInterface* );
virtual void deleteCellIterator( CellIdentifierInterface** );
virtual CellIdentifierInterface* getCellAt( ntlVec3Gfx pos );
virtual int getCellSet ( CellIdentifierInterface* );
virtual ntlVec3Gfx getCellOrigin ( CellIdentifierInterface* );
virtual ntlVec3Gfx getCellSize ( CellIdentifierInterface* );
virtual int getCellLevel ( CellIdentifierInterface* );
virtual LbmFloat getCellDensity ( CellIdentifierInterface* ,int set);
virtual LbmVec getCellVelocity ( CellIdentifierInterface* ,int set);
virtual LbmFloat getCellDf ( CellIdentifierInterface* ,int set, int dir);
virtual LbmFloat getCellMass ( CellIdentifierInterface* ,int set);
virtual LbmFloat getCellFill ( CellIdentifierInterface* ,int set);
virtual CellFlagType getCellFlag ( CellIdentifierInterface* ,int set);
virtual LbmFloat getEquilDf ( int );
virtual int getDfNum ( );
// convert pointers
stdCellId* convertBaseCidToStdCid( CellIdentifierInterface* basecid);
//! perform geometry init (if switched on)
bool initGeometryFlags();
//! init part for all freesurface testcases
void initFreeSurfaces();
//! init density gradient if enabled
void initStandingFluidGradient();
/*! init a given cell with flag, density, mass and equilibrium dist. funcs */
inline void initEmptyCell(int level, int i,int j,int k, CellFlagType flag, LbmFloat rho, LbmFloat mass);
void initVelocityCell(int level, int i,int j,int k, CellFlagType flag, LbmFloat rho, LbmFloat mass, LbmVec vel);
/*! perform a single LBM step */
virtual void step() { stepMain(); }
void stepMain();
void fineAdvance();
void coarseAdvance(int lev);
void coarseCalculateFluxareas(int lev);
// coarsen a given level (returns true if sth. was changed)
bool performCoarsening(int lev);
bool performRefinement(int lev);
//void oarseInterpolateToFineSpaceTime(int lev,LbmFloat t);
void interpolateFineFromCoarse(int lev,LbmFloat t);
void coarseRestrictFromFine(int lev);
/*! init particle positions */
virtual int initParticles(ParticleTracer *partt);
/*! move all particles */
virtual void advanceParticles(ParticleTracer *partt );
/*! debug object display (used e.g. for preview surface) */
virtual vector<ntlGeometryObject*> getDebugObjects();
//! access the fillfrac field (for viz)
float getFillFrac(int i, int j, int k) {
return QCELL(mMaxRefine, i,j,k,mLevel[mMaxRefine].setOther, dFfrac);
}
//! retrieve the fillfrac field ready to display
void getIsofieldWeighted(float *iso);
void getIsofield(float *iso){ return getIsofieldWeighted(iso); }
//! for raytracing, preprocess
void prepareVisualization( void );
// rt interface
void addDrop(bool active, float mx, float my);
void initDrop(float mx, float my);
void printCellStats();
int checkGfxEndTime(); // {return 9;};
//! get gfx geo setup id
int getGfxGeoSetup() { return mGfxGeoSetup; }
/*! type for cells */
typedef typename D::LbmCell LbmCell;
protected:
//! internal quick print function (for debugging)
void printLbmCell(int level, int i, int j, int k,int set);
// debugging use CellIterator interface to mark cell
void debugMarkCellCall(int level, int vi,int vj,int vk);
void mainLoop(int lev);
void adaptTimestep();
//! flag reinit step - always works on finest grid!
void reinitFlags( int workSet );
//! mass dist weights
LbmFloat getMassdWeight(bool dirForw, int i,int j,int k,int workSet, int l);
//! add point to mListNewInter list
inline void addToNewInterList( int ni, int nj, int nk );
//! cell is interpolated from coarse level (inited into set, source sets are determined by t)
inline void interpolateCellFromCoarse(int lev, int i, int j,int k, int dstSet, LbmFloat t, CellFlagType flagSet,bool markNbs);
//! minimal and maximal z-coords (for 2D/3D loops)
int getForZMinBnd(int lev) {
return 0;
}
int getForZMaxBnd(int lev) {
if(D::cDimension==2) return 1;
//return D::getSizeZ()-0;
return mLevel[lev].lSizez -0;
}
int getForZMin1(int lev) {
if(D::cDimension==2) return 0;
return 1;
}
int getForZMax1(int lev) {
if(D::cDimension==2) return 1;
//return D::getSizeZ()-1;
return mLevel[lev].lSizez -1;
}
// member vars
//! mass calculated during streaming step
LbmFloat mCurrentMass;
LbmFloat mCurrentVolume;
LbmFloat mInitialMass;
//! count problematic cases, that occured so far...
int mNumProblems;
// average mlsups, count how many so far...
double mAvgMLSUPS;
double mAvgMLSUPSCnt;
//! Mcubes object for surface reconstruction
IsoSurface *mpPreviewSurface;
int mLoopSubdivs;
float mSmoothSurface;
float mSmoothNormals;
//! use time adaptivity?
bool mTimeAdap;
//! output surface preview? if >0 yes, and use as reduzed size
int mOutputSurfacePreview;
LbmFloat mPreviewFactor;
//! fluid vol height
LbmFloat mFVHeight;
LbmFloat mFVArea;
bool mUpdateFVHeight;
//! require some geo setup from the viz?
int mGfxGeoSetup;
//! force quit for gfx
LbmFloat mGfxEndTime;
//! smoother surface initialization?
int mInitSurfaceSmoothing;
int mTimestepReduceLock;
int mTimeSwitchCounts;
//! total simulation time so far
LbmFloat mSimulationTime;
//! smallest and largest step size so far
LbmFloat mMinStepTime, mMaxStepTime;
//! track max. velocity
LbmFloat mMxvx, mMxvy, mMxvz, mMaxVlen;
//! list of the cells to empty at the end of the step
vector<LbmPoint> mListEmpty;
//! list of the cells to make fluid at the end of the step
vector<LbmPoint> mListFull;
//! list of new interface cells to init
vector<LbmPoint> mListNewInter;
//! class for handling redist weights in reinit flag function
class lbmFloatSet {
public:
LbmFloat val[dTotalNum];
};
//! normalized vectors for all neighboring cell directions (for e.g. massdweight calc)
LbmVec mDvecNrm[27];
//! debugging
bool checkSymmetry(string idstring);
//! symmetric init?
//bool mStartSymm;
//! kepp track of max/min no. of filled cells
int mMaxNoCells, mMinNoCells;
long long int mAvgNumUsedCells;
//! for interactive - how to drop drops?
int mDropMode;
LbmFloat mDropSize;
LbmVec mDropSpeed;
//! dropping variables
bool mDropping;
LbmFloat mDropX, mDropY;
LbmFloat mDropHeight;
//! get isofield weights
int mIsoWeightMethod;
float mIsoWeight[27];
// grid coarsening vars
/*! vector for the data for each level */
# define MAX_LEV 5
FsgrLevelData mLevel[MAX_LEV];
/*! minimal and maximal refinement levels */
int mMaxRefine;
/*! df scale factors for level up/down */
LbmFloat mDfScaleUp, mDfScaleDown;
/*! precomputed cell area values */
LbmFloat mFsgrCellArea[27];
/*! LES C_smago paramter for finest grid */
float mInitialCsmago;
float mCsmagoRefineMultiplier;
/*! LES stats for non OPT3D */
LbmFloat mDebugOmegaRet;
//! fluid stats
int mNumInterdCells;
int mNumInvIfCells;
int mNumInvIfTotal;
//! debug function to disable standing f init
int mDisableStandingFluidInit;
//! debug function to force tadap syncing
int mForceTadapRefine;
# if FSGR_STRICT_DEBUG==1
# define STRICT_EXIT *((int *)0)=0;
int 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; }
if(ii<0){ errMsg("LbmStrict"," invX- l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; }
if(ij<0){ errMsg("LbmStrict"," invY- l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; }
if(ik<0){ errMsg("LbmStrict"," invZ- l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; }
if(ii>mLevel[level].lSizex-1){ errMsg("LbmStrict"," invX+ l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; }
if(ij>mLevel[level].lSizey-1){ errMsg("LbmStrict"," invY+ l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; }
if(ik>mLevel[level].lSizez-1){ errMsg("LbmStrict"," invZ+ l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; }
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; }
return _LBMGI(level, ii,ij,ik, is);
};
CellFlagType& debRFLAG(int level, int xx,int yy,int zz,int set){
return _RFLAG(level, xx,yy,zz,set);
};
CellFlagType& 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; }
return _RFLAG_NB(level, xx,yy,zz,set, dir);
};
CellFlagType& 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; }
return _RFLAG_NBINV(level, xx,yy,zz,set, dir);
};
int 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; }
if(ii<0){ errMsg("LbmStrict"," invX- l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; }
if(ij<0){ errMsg("LbmStrict"," invY- l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; }
if(ik<0){ errMsg("LbmStrict"," invZ- l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; }
if(ii>mLevel[level].lSizex-1){ errMsg("LbmStrict"," invX+ l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; }
if(ij>mLevel[level].lSizey-1){ errMsg("LbmStrict"," invY+ l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; }
if(ik>mLevel[level].lSizez-1){ errMsg("LbmStrict"," invZ+ l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; }
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 != 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
#endif // COMPRESSGRIDS==1
return _LBMQI(level, ii,ij,ik, is, l);
};
LbmFloat& 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);
};
LbmFloat& 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; }
return _QCELL_NB(level, xx,yy,zz,set, dir,l);
};
LbmFloat& 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; }
return _QCELL_NBINV(level, xx,yy,zz,set, dir,l);
};
LbmFloat* debRACPNT(int level, int ii,int ij,int ik, int is ) {
return _RACPNT(level, ii,ij,ik, is );
};
LbmFloat& 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 != dMass) && (l != dFfrac) && (l != dFlux)){ errMsg("LbmStrict"," invD+ "<<" l"<<l); STRICT_EXIT; } }
return _RAC(s,l);
};
# endif // FSGR_STRICT_DEBUG==1
};
/*****************************************************************************/
// compilation settings
// loops over _all_ cells (including boundary layer)
#define FSGR_FORIJK_BOUNDS(leveli) \
for(int k= getForZMinBnd(leveli); k< getForZMaxBnd(leveli); ++k) \
for(int k= getForZMinBnd(); k< getForZMaxBnd(leveli); ++k) \
for(int j=0;j<mLevel[leveli].lSizey-0;++j) \
for(int i=0;i<mLevel[leveli].lSizex-0;++i) \
// loops over _only inner_ cells
#define FSGR_FORIJK1(leveli) \
for(int k= getForZMin1(leveli); k< getForZMax1(leveli); ++k) \
for(int k= getForZMin1(); k< getForZMax1(leveli); ++k) \
for(int j=1;j<mLevel[leveli].lSizey-1;++j) \
for(int i=1;i<mLevel[leveli].lSizex-1;++i) \
// relaxation_macros end
/******************************************************************************
* Lbm Constructor
@@ -1286,20 +1258,21 @@ LbmFsgrSolver<D>::LbmFsgrSolver() :
mIsoWeightMethod(2),
mMaxRefine(1),
mDfScaleUp(-1.0), mDfScaleDown(-1.0),
mInitialCsmago(0.04), mCsmagoRefineMultiplier(8.0), mDebugOmegaRet(0.0),
mNumInvIfTotal(0),
mInitialCsmago(0.04), mInitialCsmagoCoarse(1.0), mDebugOmegaRet(0.0),
mNumInvIfTotal(0), mNumFsgrChanges(0),
mDisableStandingFluidInit(0),
mForceTadapRefine(-1)
{
/* not much to do here... */
// not much to do here...
D::mpIso = new IsoSurface( D::mIsoValue, false );
/* init equilibrium dist. func */
// init equilibrium dist. func
LbmFloat rho=1.0;
FORDF0 {
D::dfEquil[l] = D::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++) {
@@ -1309,35 +1282,31 @@ LbmFsgrSolver<D>::LbmFsgrSolver() :
}
for(int m=0; m<D::cDimension; m++) {
for(int n=0; n<D::cDimension; n++) {
//LbmFloat qadd = 0.0;
for(int l=1; l<D::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;
default: em = -1.0; errMsg("SMAGO","err m="<<m); exit(1);
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;
default: en = -1.0; errMsg("SMAGO","err n="<<n); exit(1);
default: en = -1.0; errFatal("SMAGO2","err n="<<n, SIMWORLD_GENERICERROR);
}
const LbmFloat coeff = em*en;
if(m==n) {
D::lesCoeffDiag[m][l] = coeff;
// f__printf(stderr,"QSMDEB: CF DIAG m:%d l:%d = %f \n", m,l, coeff);
} else {
if(m>n) {
D::lesCoeffOffdiag[odm][l] = coeff;
// f__printf(stderr,"QSMDEB: CF OFFDIAG odm:%d l:%d = %f \n", odm,l, coeff);
}
}
}
if(m==n) {
} else {
if(m>n) odm++;
@@ -1407,7 +1376,7 @@ LbmFsgrSolver<D>::parseAttrList()
mSmoothNormals = D::mpAttrs->readFloat("smoothnormals", mSmoothNormals, "SimulationLbm","mSmoothNormals", false );
mInitialCsmago = D::mpAttrs->readFloat("csmago", mInitialCsmago, "SimulationLbm","mInitialCsmago", false );
mCsmagoRefineMultiplier = D::mpAttrs->readFloat("csmago_refinemultiplier", mCsmagoRefineMultiplier, "SimulationLbm","mCsmagoRefineMultiplier", false );
mInitialCsmagoCoarse = D::mpAttrs->readFloat("csmago_coarse", mInitialCsmagoCoarse, "SimulationLbm","mInitialCsmagoCoarse", false );
// refinement
mMaxRefine = D::mpAttrs->readInt("maxrefine", mMaxRefine ,"LbmFsgrSolver", "mMaxRefine", true);
@@ -1442,18 +1411,20 @@ LbmFsgrSolver<D>::initLevelOmegas()
if(mInitialCsmago<=0.0) {
if(OPT3D==1) {
errMsg("LbmFsgrSolver::initLevelOmegas","Csmago-LES = 0 not supported for optimized 3D version...");
exit(1);
errFatal("LbmFsgrSolver::initLevelOmegas","Csmago-LES = 0 not supported for optimized 3D version...",SIMWORLD_INITERROR);
return;
}
}
// use Tau instead of Omega for calculations
int i = mMaxRefine;
mLevel[i].omega = D::mOmega;
mLevel[i].stepsize = D::mpParam->getStepTime();
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);
{ // init base level
int i = mMaxRefine;
mLevel[i].omega = D::mOmega;
mLevel[i].stepsize = D::mpParam->getStepTime();
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);
}
// init all sub levels
for(int i=mMaxRefine-1; i>=0; i--) {
@@ -1462,7 +1433,14 @@ LbmFsgrSolver<D>::initLevelOmegas()
nomega = 1.0/nomega;
mLevel[i].omega = (LbmFloat)nomega;
mLevel[i].stepsize = 2.0 * mLevel[i+1].stepsize;
mLevel[i].lcsmago = mLevel[i+1].lcsmago*mCsmagoRefineMultiplier;
//mLevel[i].lcsmago = mLevel[i+1].lcsmago*mCsmagoRefineMultiplier;
//if(mLevel[i].lcsmago>1.0) mLevel[i].lcsmago = 1.0;
//if(strstr(D::getName().c_str(),"Debug")){
//mLevel[i].lcsmago = mLevel[mMaxRefine].lcsmago; // DEBUG
// if(strstr(D::getName().c_str(),"Debug")) mLevel[i].lcsmago = mLevel[mMaxRefine].lcsmago * (LbmFloat)(mMaxRefine-i)*0.5+1.0;
//if(strstr(D::getName().c_str(),"Debug")) mLevel[i].lcsmago = mLevel[mMaxRefine].lcsmago * ((LbmFloat)(mMaxRefine-i)*1.0 + 1.0 );
//if(strstr(D::getName().c_str(),"Debug")) mLevel[i].lcsmago = 0.99;
mLevel[i].lcsmago = mInitialCsmagoCoarse;
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);
}
@@ -1530,16 +1508,10 @@ LbmFsgrSolver<D>::initialize( ntlTree* /*tree*/, vector<ntlGeometryObject*>* /*o
if(PARALLEL==1) maskBits+=2;
for(int i=0; i<maskBits; i++) { sizeMask |= (1<<i); }
sizeMask = ~sizeMask;
if(debugGridsizeInit) debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Size X:"<<D::mSizex<<" Y:"<<D::mSizey<<" Z:"<<D::mSizez<<" m"<<convertFlags2String(sizeMask) ,10);
if(debugGridsizeInit) debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Size X:"<<D::mSizex<<" Y:"<<D::mSizey<<" Z:"<<D::mSizez<<" m"<<convertCellFlagType2String(sizeMask) ,10);
D::mSizex &= sizeMask;
D::mSizey &= sizeMask;
D::mSizez &= sizeMask;
if(PARALLEL==1) {
// make (size+2)%4 == 0 , assumes MAX_THREADS=4
D::mSizex += 2;
D::mSizey += 2;
D::mSizez += 2;
}
// force geom size to match rounded grid sizes
D::mvGeoEnd[0] = D::mvGeoStart[0] + cellSize*(LbmFloat)D::mSizex;
D::mvGeoEnd[1] = D::mvGeoStart[1] + cellSize*(LbmFloat)D::mSizey;
@@ -1559,7 +1531,6 @@ LbmFsgrSolver<D>::initialize( ntlTree* /*tree*/, vector<ntlGeometryObject*>* /*o
<<"INTORDER="<<INTORDER <<" "
<<"TIMEINTORDER="<<TIMEINTORDER <<" "
<<"REFINEMENTBORDER="<<REFINEMENTBORDER <<" "
<<"INTCFCOARSETEST="<<INTCFCOARSETEST<<" "
<<"OPT3D="<<OPT3D <<" "
<<"COMPRESSGRIDS="<<COMPRESSGRIDS<<" "
<<"LS_FLUIDTHRESHOLD="<<LS_FLUIDTHRESHOLD <<" "
@@ -1585,16 +1556,17 @@ LbmFsgrSolver<D>::initialize( ntlTree* /*tree*/, vector<ntlGeometryObject*>* /*o
}
if(!D::mpParam->calculateAllMissingValues()) {
errMsg("LbmFsgrSolver::initialize","Fatal: failed to init parameters! Aborting...");
exit(1);
errFatal("LbmFsgrSolver::initialize","Fatal: failed to init parameters! Aborting...",SIMWORLD_INITERROR);
return false;
}
// recalc objects speeds in geo init
// init vectors
if(mMaxRefine >= MAX_LEV) {
errMsg("LbmFsgrSolver::initializeLbmGridref"," error: Too many levels!");
exit(1);
errFatal("LbmFsgrSolver::initializeLbmGridref"," error: Too many levels!", SIMWORLD_INITERROR);
return false;
}
for(int i=0; i<=mMaxRefine; i++) {
mLevel[i].id = i;
@@ -1621,13 +1593,10 @@ LbmFsgrSolver<D>::initialize( ntlTree* /*tree*/, vector<ntlGeometryObject*>* /*o
mLevel[i].lSizex = mLevel[i+1].lSizex/2;
mLevel[i].lSizey = mLevel[i+1].lSizey/2;
mLevel[i].lSizez = mLevel[i+1].lSizez/2;
if(
((mLevel[i].lSizex % 4) != 0) ||
((mLevel[i].lSizey % 4) != 0) ||
((mLevel[i].lSizez % 4) != 0) ) {
/*if( ((mLevel[i].lSizex % 4) != 0) || ((mLevel[i].lSizey % 4) != 0) || ((mLevel[i].lSizez % 4) != 0) ) {
errMsg("LbmFsgrSolver","Init: error invalid sizes on level "<<i<<" "<<PRINT_VEC(mLevel[i].lSizex,mLevel[i].lSizey,mLevel[i].lSizez) );
exit(1);
}
xit(1);
}// old QUAD handling */
}
// estimate memory usage
@@ -1656,6 +1625,12 @@ LbmFsgrSolver<D>::initialize( ntlTree* /*tree*/, vector<ntlGeometryObject*>* /*o
debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Required Grid memory: "<< memd <<" "<< sizeStr<<" ",4);
}
// safety check
if(sizeof(CellFlagType) != CellFlagTypeSize) {
errFatal("LbmFsgrSolver::initialize","Fatal Error: CellFlagType has wrong size! Is:"<<sizeof(CellFlagType)<<", should be:"<<CellFlagTypeSize, SIMWORLD_GENERICERROR);
return false;
}
mLevel[ mMaxRefine ].nodeSize = ((D::mvGeoEnd[0]-D::mvGeoStart[0]) / (LbmFloat)(D::mSizex));
mLevel[ mMaxRefine ].simCellSize = D::mpParam->getCellSize();
mLevel[ mMaxRefine ].lcellfactor = 1.0;
@@ -1671,14 +1646,15 @@ LbmFsgrSolver<D>::initialize( ntlTree* /*tree*/, vector<ntlGeometryObject*>* /*o
unsigned long int 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;
//errMsg("CGD","rcs:"<<rcellSize<<" cpff:"<<compressOffset<< " c0:"<<mLevel[ mMaxRefine ].mprsCells[0]<<" c1:"<<mLevel[ mMaxRefine ].mprsCells[1]<< " c0e:"<<(mLevel[ mMaxRefine ].mprsCells[0]+rcellSize)<<" c1:"<<(mLevel[ mMaxRefine ].mprsCells[1]+rcellSize)); // DEBUG
#endif // COMPRESSGRIDS==0
LbmFloat lcfdimFac = 8.0;
if(D::cDimension==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;
LbmFloat dimFac = 8.0;
if(D::cDimension==2) dimFac = 4.0;
mLevel[i].lcellfactor = mLevel[i+1].lcellfactor * dimFac;
mLevel[i].lcellfactor = mLevel[i+1].lcellfactor * lcfdimFac;
if(D::cDimension==2){ mLevel[i].lSizez = 1; } // 2D
rcellSize = ((mLevel[i].lSizex*mLevel[i].lSizey*mLevel[i].lSizez) *dTotalNum);
@@ -1763,6 +1739,7 @@ LbmFsgrSolver<D>::initialize( ntlTree* /*tree*/, vector<ntlGeometryObject*>* /*o
/* 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
initEmptyCell(lev, i,j,k, CFEmpty, -1.0, -1.0);
}
}
@@ -1800,12 +1777,22 @@ LbmFsgrSolver<D>::initialize( ntlTree* /*tree*/, vector<ntlGeometryObject*>* /*o
for(int k=0;k<mLevel[mMaxRefine].lSizez;k++)
for(int j=0;j<mLevel[mMaxRefine].lSizey;j++) {
initEmptyCell(mMaxRefine, 0,j,k, CFBnd, 0.0, BND_FILL);
// for quads! tag +x border... CF4_EMPTY, CF4_BND, CF4_UNUSED
// do this last to prevent any overwriting...
//initEmptyCell(mMaxRefine, mLevel[mMaxRefine].lSizex-1,j,k, CFBnd|CFBndMARK, 0.0, BND_FILL);
initEmptyCell(mMaxRefine, mLevel[mMaxRefine].lSizex-1,j,k, CFBnd, 0.0, BND_FILL);
// DEBUG BORDER!
//initEmptyCell(mMaxRefine, mLevel[mMaxRefine].lSizex-2,j,k, CFBnd, 0.0, BND_FILL);
}
// TEST!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!11
/*for(int k=0;k<mLevel[mMaxRefine].lSizez;k++)
for(int j=0;j<mLevel[mMaxRefine].lSizey;j++) {
initEmptyCell(mMaxRefine, mLevel[mMaxRefine].lSizex-2,j,k, CFBnd, 0.0, BND_FILL);
}
for(int k=0;k<mLevel[mMaxRefine].lSizez;k++)
for(int i=0;i<mLevel[mMaxRefine].lSizex;i++) {
initEmptyCell(mMaxRefine, i,1,k, CFBnd, 0.0, BND_FILL);
}
// */
/*for(int ii=0; ii<(int)pow(2.0,mMaxRefine)-1; ii++) {
errMsg("BNDTESTSYMM","set "<<mLevel[mMaxRefine].lSizex-2-ii );
for(int k=0;k<mLevel[mMaxRefine].lSizez;k++)
@@ -1821,15 +1808,16 @@ LbmFsgrSolver<D>::initialize( ntlTree* /*tree*/, vector<ntlGeometryObject*>* /*o
// prepare interface cells
initFreeSurfaces();
D::mInitialMass = 0.0;
initStandingFluidGradient();
// perform first step to init initial mass
mInitialMass = 0.0;
int inmCellCnt = 0;
FSGR_FORIJK1(mMaxRefine) {
if( TESTFLAG( RFLAG(mMaxRefine, i,j,k, mLevel[mMaxRefine].setCurr), CFFluid) ) {
mInitialMass += 1.0;
if( TESTFLAG( RFLAG(mMaxRefine, i,j,k, mLevel[mMaxRefine].setCurr), CFFluid) ) {
LbmFloat fluidRho = QCELL(mMaxRefine, i,j,k, mLevel[mMaxRefine].setCurr, 0);
FORDF1 { fluidRho += QCELL(mMaxRefine, i,j,k, mLevel[mMaxRefine].setCurr, l); }
mInitialMass += fluidRho;
inmCellCnt ++;
} else if( TESTFLAG( RFLAG(mMaxRefine, i,j,k, mLevel[mMaxRefine].setCurr), CFInter) ) {
mInitialMass += QCELL(mMaxRefine, i,j,k, mLevel[mMaxRefine].setCurr, dMass);
@@ -1843,6 +1831,7 @@ LbmFsgrSolver<D>::initialize( ntlTree* /*tree*/, vector<ntlGeometryObject*>* /*o
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);
mInitialMass = 0.0; // reset, and use actual value after first step
//mStartSymm = false;
#if ELBEEM_BLENDER!=1
@@ -1860,14 +1849,23 @@ LbmFsgrSolver<D>::initialize( ntlTree* /*tree*/, vector<ntlGeometryObject*>* /*o
// coarsen region
myTime_t fsgrtstart = getTime();
for(int lev=mMaxRefine-1; lev>=0; lev--) {
while(performCoarsening(lev)){
coarseRestrictFromFine(lev);
debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Coarsening level "<<lev<<".",8);
}
debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Coarsening level "<<lev<<".",8);
performRefinement(lev);
performCoarsening(lev);
coarseRestrictFromFine(lev);
performRefinement(lev);
performCoarsening(lev);
coarseRestrictFromFine(lev);
//while( performRefinement(lev) | performCoarsening(lev)){
//coarseRestrictFromFine(lev);
//debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Coarsening level "<<lev<<".",8);
//}
}
D::markedClearList();
myTime_t fsgrtend = getTime();
if(!D::mSilent){ debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"FSGR init done ("<< ((fsgrtend-fsgrtstart)/(double)1000.0)<<"s) " , 10 ); }
if(!D::mSilent){ debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"FSGR init done ("<< ((fsgrtend-fsgrtstart)/(double)1000.0)<<"s), changes:"<<mNumFsgrChanges , 10 ); }
mNumFsgrChanges = 0;
for(int l=0; l<D::cDirNum; l++) {
LbmFloat area = 0.5 * 0.5 *0.5;
@@ -1913,25 +1911,12 @@ LbmFsgrSolver<D>::initialize( ntlTree* /*tree*/, vector<ntlGeometryObject*>* /*o
FSGR_FORIJK_BOUNDS(lev) {
RFLAG(lev, i,j,k,mLevel[lev].setOther) = RFLAG(lev, i,j,k,mLevel[lev].setCurr);
} } // first copy flags */
#if COMPRESSGRIDS==0
/*for(int lev=0; lev<=mMaxRefine; lev++) {
FSGR_FORIJK_BOUNDS(lev) {
// copy from other to curr
for(int l=0; l<D::cDfNum; l++) {
QCELL(lev, i,j,k,mLevel[lev].setOther, l) = QCELL(lev, i,j,k,mLevel[lev].setCurr, l);
}
QCELL(lev, i,j,k,mLevel[lev].setOther, dMass) = QCELL(lev, i,j,k,mLevel[lev].setCurr, dMass);
QCELL(lev, i,j,k,mLevel[lev].setOther, dFfrac) = QCELL(lev, i,j,k,mLevel[lev].setCurr, dFfrac);
QCELL(lev, i,j,k,mLevel[lev].setOther, dFlux) = QCELL(lev, i,j,k,mLevel[lev].setCurr, dFlux);
} } // COMPRT OFF */
#endif // COMPRESSGRIDS==0
if(mOutputSurfacePreview) {
if(D::cDimension==2) {
errMsg("LbmFsgrSolver::init","No preview in 2D allowed!"); exit (1);
errFatal("LbmFsgrSolver::init","No preview in 2D allowed!",SIMWORLD_INITERROR); return false;
}
//int previewSize = mOutputSurfacePreview;
@@ -1944,8 +1929,8 @@ LbmFsgrSolver<D>::initialize( ntlTree* /*tree*/, vector<ntlGeometryObject*>* /*o
mpPreviewSurface->setStart( vec2G(isostart) );
mpPreviewSurface->setEnd( vec2G(isoend) );
LbmVec isodist = isoend-isostart;
mpPreviewSurface->initializeIsosurface( (int)(mPreviewFactor*D::mSizex)+2, (int)(mPreviewFactor*D::mSizey)+2, (int)(mPreviewFactor*D::mSizez)+2, vec2G(isodist) );
LbmVec pisodist = isoend-isostart;
mpPreviewSurface->initializeIsosurface( (int)(mPreviewFactor*D::mSizex)+2, (int)(mPreviewFactor*D::mSizey)+2, (int)(mPreviewFactor*D::mSizez)+2, vec2G(pisodist) );
//mpPreviewSurface->setName( D::getName() + "preview" );
mpPreviewSurface->setName( "preview" );
@@ -1986,7 +1971,6 @@ LbmFsgrSolver<D>::initialize( ntlTree* /*tree*/, vector<ntlGeometryObject*>* /*o
template<class D>
bool
LbmFsgrSolver<D>::initGeometryFlags() {
if(!D::mPerformGeoInit) return false;
int level = mMaxRefine;
myTime_t geotimestart = getTime();
ntlGeometryObject *pObj;
@@ -2014,14 +1998,13 @@ LbmFsgrSolver<D>::initGeometryFlags() {
maxIniVel = vec2G( D::mpParam->calculateLattVelocityFromRw( vec2P(D::getGeoMaxInitialVelocity()) ));
debMsgStd("LbmFsgrSolver::initGeometryFlags",DM_MSG,"New maximum Velocity from geo init="<< maxIniVel,5);
}
recalculateObjectSpeeds();
ntlVec3Gfx pos,iniPos; // position of current cell
LbmFloat rhomass = 0.0;
int savedNodes = 0;
int OId = -1;
gfxReal distance;
LbmVec nodevel(0.0);
// 2d display as rectangles
if(D::cDimension==2) {
@@ -2030,7 +2013,7 @@ LbmFsgrSolver<D>::initGeometryFlags() {
//iniPos =(D::mvGeoStart + ntlVec3Gfx( 0.0 ))+dvec;
} else {
iniPos =(D::mvGeoStart + ntlVec3Gfx( 0.0 ))-(dvec*0.0);
iniPos[2] = D::mvGeoStart[2] + dvec[2]*getForZMin1(level);
iniPos[2] = D::mvGeoStart[2] + dvec[2]*getForZMin1();
}
@@ -2039,163 +2022,96 @@ LbmFsgrSolver<D>::initGeometryFlags() {
ntlVec3Gfx( iniPos[0]+ dvec[0]*(gfxReal)(i), \
iniPos[1]+ dvec[1]*(gfxReal)(j), \
iniPos[2]+ dvec[2]*(gfxReal)(k) )
//pos = iniPos;
for(int k= getForZMin1(level); k< getForZMax1(level); ++k) {
//pos[1] = D::mvGeoStart[1] + dvec[1]*1.0;
for(int k= getForZMin1(); k< getForZMax1(level); ++k) {
for(int j=1;j<mLevel[level].lSizey-1;j++) {
//pos[0] = D::mvGeoStart[0] + dvec[0]*1.0;
for(int i=1;i<mLevel[level].lSizex-1;i++) {
//CellFlagType ntype = D::geoInitGetPointType( pos, nodesize, &pObj, distance );
CellFlagType ntype = CFInvalid;
if(D::geoInitCheckPointInside( GETPOS(i,j,k) , FGI_ALLBOUNDS, OId, distance)) {
ntype = CFBnd;
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;
}
}
//CellFlagType convntype = ntype;
if(ntype != CFInvalid) {
// initDefaultCell
nodevel = LbmVec(0.0);
rhomass = BND_FILL;
initVelocityCell(level, i,j,k, ntype, rhomass, rhomass, nodevel );
if((ntype == CFMbndInflow) || (ntype == CFMbndOutflow) ) {
ntype |= (OId<<24);
}
initVelocityCell(level, i,j,k, ntype, rhomass, rhomass, mObjectSpeeds[OId] );
}
// walk along x until hit for following inits
if(distance<=-1.0) { distance = 100.0; }
if(distance>0.0) {
//distance += pos[0];
//while(((pos[0]+dvec[0])<distance)&&(i+1<mLevel[level].lSizex-1)) {
gfxReal dcnt=dvec[0];
while((dcnt<distance)&&(i+1<mLevel[level].lSizex-1)) {
while(( dcnt< distance )&&(i+1<mLevel[level].lSizex-1)) {
dcnt += dvec[0]; i++;
savedNodes++;
if(ntype != CFInvalid) {
// nodevel&rhomass are still inited from above
initVelocityCell(level, i,j,k, ntype, rhomass, rhomass, nodevel );
// rhomass are still inited from above
initVelocityCell(level, i,j,k, ntype, rhomass, rhomass, mObjectSpeeds[OId] );
}
}
} //pos[0] += dvec[0];
} //pos[1] += dvec[1];
} //pos[2] += dvec[2];
}
// */
}
}
} // zmax
// now init fluid layer
//pos = iniPos;
for(int k= getForZMin1(level); k< getForZMax1(level); ++k) {
//pos[1] = D::mvGeoStart[1] + dvec[1]*1.0;
for(int k= getForZMin1(); k< getForZMax1(level); ++k) {
for(int j=1;j<mLevel[level].lSizey-1;j++) {
//pos[0] = D::mvGeoStart[0] + dvec[0]*1.0;
for(int i=1;i<mLevel[level].lSizex-1;i++) {
if(!(RFLAG(level, i,j,k, mLevel[level].setCurr)&CFEmpty)) continue;
if(!(RFLAG(level, i,j,k, mLevel[level].setCurr)==CFEmpty)) continue;
//CellFlagType ntype = D::geoInitGetPointType( pos, nodesize, &pObj, distance );
CellFlagType ntype = CFInvalid;
int inits = 0;
if(D::geoInitCheckPointInside( GETPOS(i,j,k) , FGI_FLUID, OId, distance)) {
ntype = CFFluid;
pObj = (*D::mpGiObjects)[OId];
}
//CellFlagType convntype = ntype;
if(ntype != CFInvalid) {
// initDefaultCell
nodevel = vec2L(D::mpParam->calculateLattVelocityFromRw( vec2P(pObj->getInitialVelocity() )));
rhomass = 1.0;
initVelocityCell(level, i,j,k, ntype, rhomass, rhomass, nodevel );
initVelocityCell(level, i,j,k, ntype, rhomass, rhomass, mObjectSpeeds[OId] );
inits++;
}
// walk along x until hit for following inits
if(distance<=-1.0) { distance = 100.0; }
if(distance>0.0) {
//distance += pos[0];
//while(((pos[0]+dvec[0])<distance)&&(i+1<mLevel[level].lSizex-1)) {
//pos[0] += dvec[0]; i++;
gfxReal dcnt=dvec[0];
while((dcnt<distance)&&(i+1<mLevel[level].lSizex-1)) {
while((dcnt< distance )&&(i+1<mLevel[level].lSizex-1)) {
dcnt += dvec[0]; i++;
savedNodes++;
if(!(RFLAG(level, i,j,k, mLevel[level].setCurr)&CFEmpty)) continue;
if(!(RFLAG(level, i,j,k, mLevel[level].setCurr)==CFEmpty)) continue;
if(ntype != CFInvalid) {
// nodevel&rhomass are still inited from above
initVelocityCell(level, i,j,k, ntype, rhomass, rhomass, nodevel );
// rhomass are still inited from above
initVelocityCell(level, i,j,k, ntype, rhomass, rhomass, mObjectSpeeds[OId] );
inits++;
}
}
} //pos[0] += dvec[0];
} //pos[1] += dvec[1];
} //pos[2] += dvec[2];
} // distance>0
}
}
} // zmax
/*
// now init fluid layer
if(D::cDimension==2) {
dvec[2] = 0.0;
pos =(D::mvGeoStart + ntlVec3Gfx( 0.0, 0.0, (D::mvGeoEnd[2]-D::mvGeoStart[2])*0.5 ))+dvec;
pos[2] = D::mvGeoStart[2] + dvec[2]*getForZMin1(mMaxRefine);
} else {
pos =(D::mvGeoStart + ntlVec3Gfx( 0.0, 0.0, 0.0 ))+dvec;
}
for(int k= getForZMin1(mMaxRefine); k< getForZMax1(mMaxRefine); ++k) {
pos[1] = D::mvGeoStart[1] + dvec[1]*1.0;
for(int j=1;j<mLevel[mMaxRefine].lSizey-1;j++) {
pos[0] = D::mvGeoStart[0] + dvec[0]*1.0;
for(int i=1;i<mLevel[mMaxRefine].lSizex-1;i++) {
//debMsgInter("LbmFsgrSolver::initGeometryFlags",DM_MSG,"Checking"<<PRINT_IJK,2,2000 );
if(RFLAG(mMaxRefine, i,j,k, mLevel[mMaxRefine].setCurr)&CFEmpty) {
// overwrite these...
} else {
continue;
}
CellFlagType ntype = D::geoInitGetPointType( pos, nodesize, &pObj, distance );
CellFlagType convntype = ntype;
if(ntype != CFInvalid) {
// initDefaultCell
if(convntype & CFFluid) { nodevel = vec2L(D::mpParam->calculateLattVelocityFromRw( vec2P(pObj->getInitialVelocity() ))); }
else { nodevel = LbmVec(0.0); }
if(convntype & CFFluid) { rhomass = 1.0; }
else if(convntype & CFBnd) { rhomass = BND_FILL; }
else { rhomass = 0.0; } // empty, inter
//initEmptyCell(mMaxRefine, i,j,k, convntype, rhomass, rhomass );
initVelocityCell(mMaxRefine, i,j,k, convntype, rhomass, rhomass, nodevel );
//errMsg(" DT ",PRINT_IJK<<" "<<distance<<" "<<pos<<" i"<<i<<" "<<ntype );
}
// walk along x until hit for following inits
//if(distance==-1.0) { distance = 100.0; }
if(distance<=-1.0) { distance = 100.0; }
if(distance>0.0) {
distance += pos[0];
//errMsg(" DS "," "<<distance<<" "<<pos<<" i"<<i<<" type:"<<ntype<<" "<<convertFlags2String(ntype) );
while(((pos[0]+dvec[0])<distance)&&(i+1<mLevel[mMaxRefine].lSizex-1)) {
if(RFLAG(mMaxRefine, i,j,k, mLevel[mMaxRefine].setCurr)&CFEmpty) {
// overwrite these...
} else {
continue;
}
pos[0] += dvec[0]; i++;
savedNodes++;
//errMsg(" DT "," "<<distance<<" "<<pos<<" i"<<i<<" "<<ntype );
if(ntype != CFInvalid) {
// initDefaultCell
// nodevel is still inited from above
if(convntype & CFFluid) { rhomass = 1.0; }
else if(convntype & CFBnd) { rhomass = BND_FILL; }
else { rhomass = 0.0; } // empty, inter
//initEmptyCell(mMaxRefine, i,j,k, convntype, rhomass, rhomass );
initVelocityCell(mMaxRefine, i,j,k, convntype, rhomass, rhomass, nodevel );
}
}
}
pos[0] += dvec[0];
}
pos[1] += dvec[1];
}
pos[2] += dvec[2];
} // */
D::freeGeoTree();
myTime_t geotimeend = getTime();
debMsgStd("LbmFsgrSolver::initGeometryFlags",DM_MSG,"Geometry init done ("<< ((geotimeend-geotimestart)/(double)1000.0)<<"s) " , 10 );
debMsgStd("LbmFsgrSolver::initGeometryFlags",DM_MSG,"Geometry init done ("<< ((geotimeend-geotimestart)/(double)1000.0)<<"s,"<<savedNodes<<") " , 10 );
//errMsg(" SAVED "," "<<savedNodes<<" of "<<(mLevel[mMaxRefine].lSizex*mLevel[mMaxRefine].lSizey*mLevel[mMaxRefine].lSizez));
return true;
}
@@ -2278,25 +2194,13 @@ LbmFsgrSolver<D>::initFreeSurfaces() {
for(int lev=0; lev<=mMaxRefine; lev++) {
FSGR_FORIJK_BOUNDS(lev) {
if( (RFLAG(lev, i,j,k,0) & (CFBnd)) ) {
QCELL(lev, i,j,k,mLevel[mMaxRefine].setCurr, dFfrac) =
//QCELL(lev, i,j,k,mLevel[mMaxRefine].setOther, dFfrac) = // COMPRT OFF
BND_FILL;
QCELL(lev, i,j,k,mLevel[mMaxRefine].setCurr, dFfrac) = BND_FILL;
continue;
}
if( (RFLAG(lev, i,j,k,0) & (CFEmpty)) ) {
QCELL(lev, i,j,k,mLevel[mMaxRefine].setCurr, dFfrac) =
//QCELL(lev, i,j,k,mLevel[mMaxRefine].setOther, dFfrac) = // COMPRT OFF
0.0;
QCELL(lev, i,j,k,mLevel[mMaxRefine].setCurr, dFfrac) = 0.0;
continue;
}
// copy from other to curr
//?? RFLAG(lev, i,j,k,mLevel[lev].setOther) = RFLAG(lev, i,j,k,mLevel[lev].setCurr);
//?? for(int l=0; l<D::cDfNum; l++) {
//?? QCELL(lev, i,j,k,mLevel[lev].setOther, l) = QCELL(lev, i,j,k,mLevel[lev].setCurr, l);
//?? }
//?? QCELL(lev, i,j,k,mLevel[lev].setOther, dMass) = QCELL(lev, i,j,k,mLevel[lev].setCurr, dMass);
//?? QCELL(lev, i,j,k,mLevel[lev].setOther, dFfrac) = QCELL(lev, i,j,k,mLevel[lev].setCurr, dFfrac);
} }
// ----------------------------------------------------------------------
@@ -2304,7 +2208,7 @@ LbmFsgrSolver<D>::initFreeSurfaces() {
if(mInitSurfaceSmoothing>0) {
debMsgStd("Surface Smoothing init", DM_MSG, "Performing "<<(mInitSurfaceSmoothing)<<" smoothing steps ",10);
#if COMPRESSGRIDS==1
errMsg("NYI","COMPRESSGRIDS mInitSurfaceSmoothing"); exit(1);
errFatal("NYI","COMPRESSGRIDS mInitSurfaceSmoothing",SIMWORLD_INITERROR); return;
#endif // COMPRESSGRIDS==0
}
for(int s=0; s<mInitSurfaceSmoothing; s++) {
@@ -2332,17 +2236,7 @@ LbmFsgrSolver<D>::initFreeSurfaces() {
mLevel[mMaxRefine].setOther = mLevel[mMaxRefine].setCurr;
mLevel[mMaxRefine].setCurr ^= 1;
}
// copy back...
/*for(int lev=0; lev<=mMaxRefine; lev++) {
FSGR_FORIJK1(lev) {
if( TESTFLAG( RFLAG(lev, i,j,k, mLevel[lev].setCurr), CFInter) ) {
QCELL(lev, i,j,k, mLevel[lev].setOther, dMass ) = QCELL(lev, i,j,k, mLevel[lev].setCurr, dMass);
QCELL(lev, i,j,k, mLevel[lev].setOther, dFfrac) = QCELL(lev, i,j,k, mLevel[lev].setCurr, dFfrac);
QCELL(lev, i,j,k, mLevel[lev].setOther, dFlux) = QCELL(lev, i,j,k, mLevel[lev].setCurr, dFlux);
}
}
} // COMPRT OFF */
// copy back...?
}
@@ -2431,8 +2325,29 @@ LbmFsgrSolver<D>::initStandingFluidGradient() {
haveStandingFluid=0;
}
// copy flags and init , as no flags will be changed during grav init
// also important for corasening later on
const int lev = mMaxRefine;
CellFlagType nbflag[LBM_DFNUM], nbored;
for(int k=D::getForZMinBnd();k<D::getForZMaxBnd();++k) {
for(int j=0;j<mLevel[lev].lSizey-0;++j) {
for(int i=0;i<mLevel[lev].lSizex-0;++i) {
if( (RFLAG(lev, i,j,k,SRCS(lev)) & (CFFluid)) ) {
nbored = 0;
FORDF1 {
nbflag[l] = RFLAG_NB(lev, i,j,k, SRCS(lev),l);
nbored |= nbflag[l];
}
if(nbored&CFBnd) {
RFLAG(lev, i,j,k,SRCS(lev)) &= (~CFNoBndFluid);
} else {
RFLAG(lev, i,j,k,SRCS(lev)) |= CFNoBndFluid;
}
}
RFLAG(lev, i,j,k,TSET(lev)) = RFLAG(lev, i,j,k,SRCS(lev));
} } }
if(haveStandingFluid) {
int lev = mMaxRefine;
int rhoworkSet = mLevel[lev].setCurr;
myTime_t timestart = getTime(); // FIXME use user time here?
#if OPT3D==true
@@ -2466,26 +2381,6 @@ LbmFsgrSolver<D>::initStandingFluidGradient() {
} // GRAVLOOP
debMsgStd("Standing fluid preinit", DM_MSG, "Density gradient inited", 8);
// copy flags and init , as no flags will be changed during grav init
CellFlagType nbflag[LBM_DFNUM], nbored;
for(int k=D::getForZMinBnd();k<D::getForZMaxBnd();++k) {
for(int j=0;j<mLevel[lev].lSizey-0;++j) {
for(int i=0;i<mLevel[lev].lSizex-0;++i) {
if( (RFLAG(lev, i,j,k,SRCS(lev)) & (CFFluid)) ) {
nbored = 0;
FORDF1 {
nbflag[l] = RFLAG_NB(lev, i,j,k, SRCS(lev),l);
nbored |= nbflag[l];
}
if(nbored&CFBnd) {
RFLAG(lev, i,j,k,SRCS(lev)) &= (~CFNoBndFluid);
} else {
RFLAG(lev, i,j,k,SRCS(lev)) |= CFNoBndFluid;
}
}
RFLAG(lev, i,j,k,TSET(lev)) = RFLAG(lev, i,j,k,SRCS(lev));
} } }
int preinitSteps = (haveStandingFluid* ((mLevel[lev].lSizey+mLevel[lev].lSizez+mLevel[lev].lSizex)/3) );
preinitSteps = (haveStandingFluid>>2); // not much use...?
//preinitSteps = 4; // DEBUG!!!!
@@ -2495,7 +2390,7 @@ LbmFsgrSolver<D>::initStandingFluidGradient() {
for(int s=0; s<preinitSteps; s++) {
int workSet = SRCS(lev); //mLevel[lev].setCurr;
int otherSet = TSET(lev); //mLevel[lev].setOther;
//debMsgDirect(".");
debMsgDirect(".");
if(debugStandingPreinit) debMsgStd("Standing fluid preinit", DM_MSG, "s="<<s<<" curset="<<workSet<<" srcs"<<SRCS(lev), 10);
LbmFloat *ccel;
LbmFloat *tcel;
@@ -2553,7 +2448,7 @@ LbmFsgrSolver<D>::initStandingFluidGradient() {
// */
myTime_t timeend = getTime();
//debMsgDirect(" done, "<<((timeend-timestart)/(double)1000.0)<<"s \n");
debMsgDirect(" done, "<<((timeend-timestart)/(double)1000.0)<<"s \n");
#undef NBFLAG
}
}
@@ -2562,6 +2457,13 @@ LbmFsgrSolver<D>::initStandingFluidGradient() {
/*****************************************************************************/
/* 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) {
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) {
@@ -2574,17 +2476,11 @@ LbmFsgrSolver<D>::initEmptyCell(int level, int i,int j,int k, CellFlagType flag,
RAC(ecel, dMass) = mass;
RAC(ecel, dFfrac) = mass/rho;
RAC(ecel, dFlux) = FLUX_INIT;
RFLAG(level, i,j,k, workSet)= flag;
//RFLAG(level, i,j,k, workSet)= flag;
changeFlag(level, i,j,k, workSet, flag);
workSet ^= 1;
#if COMPRESSGRIDS==0
/*ecel = RACPNT(level, i,j,k, workSet); FIXME why doesnt this work with COMPRESSGRIDS off?
FORDF0 { RAC(ecel, l) = D::dfEquil[l] * rho; }
RAC(ecel, dMass) = mass;
RAC(ecel, dFfrac) = mass/rho;
RAC(ecel, dFlux) = FLUX_INIT; // COMPRT OFF */
#endif // COMPRESSGRIDS==0
RFLAG(level, i,j,k, workSet)= flag;
changeFlag(level, i,j,k, workSet, flag);
return;
}
@@ -2599,17 +2495,11 @@ LbmFsgrSolver<D>::initVelocityCell(int level, int i,int j,int k, CellFlagType fl
RAC(ecel, dMass) = mass;
RAC(ecel, dFfrac) = mass/rho;
RAC(ecel, dFlux) = FLUX_INIT;
RFLAG(level, i,j,k, workSet) = flag;
//RFLAG(level, i,j,k, workSet) = flag;
changeFlag(level, i,j,k, workSet, flag);
workSet ^= 1;
#if COMPRESSGRIDS==0
/*ecel = RACPNT(level, i,j,k, workSet); FIXME why doesnt this work with COMPRESSGRIDS off?
FORDF0 { RAC(ecel, l) = D::getCollideEq(l, rho,vel[0],vel[1],vel[2]); }
RAC(ecel, dMass) = mass;
RAC(ecel, dFfrac) = mass/rho;
RAC(ecel, dFlux) = FLUX_INIT; // COMPRT OFF */
#endif // COMPRESSGRIDS==0
RFLAG(level, i,j,k, workSet) = flag;
changeFlag(level, i,j,k, workSet, flag);
return;
}
@@ -2652,10 +2542,8 @@ LbmFsgrSolver<D>::checkSymmetry(string idstring)
if( LBM_FLOATNEQ(QCELL(lev, i,j,k,s, dMass), QCELL(lev, inb,j,k,s, dMass)) ) { erro = true;
if(D::cDimension==2) {
if(msgs<maxMsgs) { msgs++;
/*
debMsgDirect(" mass1 "<<QCELL(lev, i,j,k,s, dMass)<<" mass2 "<<QCELL(lev, inb,j,k,s, dMass) <<std::endl);
//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) );
*/
}
}
if(markCells){ debugMarkCell(lev, i,j,k); debugMarkCell(lev, inb,j,k); }
@@ -2760,8 +2648,9 @@ LbmFsgrSolver<D>::stepMain()
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:"<<convertFlags2String(dsbits));
//errMsg("S"," step:"<<D::mStepCnt<<" s-1:"<<(D::mStepCnt-1)<<" xf:"<<convertCellFlagType2String(dsbits));
for(int lev=0; lev<=mMaxRefine; lev++) {
//if(! (D::mStepCnt&(1<<lev)) ) {
if( dsbits & (1<<(mMaxRefine-lev)) ) {
@@ -2793,16 +2682,7 @@ LbmFsgrSolver<D>::stepMain()
#else // TIMEINTORDER==0
interTime = 0.0;
#endif // TIMEINTORDER==1
// test mix! , double 0.5 stablest?
#if INTCFCOARSETEST==1
//if(lev!=mMaxRefine) { interpolateFineFromCoarse(lev,interTime); } // test!
#else // INTCFCOARSETEST==1
interpolateFineFromCoarse(lev,interTime);
ooo
#endif // INTCFCOARSETEST==1
// */
levsteps++;
}
mCurrentMass += mLevel[lev].lmass;
mCurrentVolume += mLevel[lev].lvolume;
@@ -2822,7 +2702,7 @@ LbmFsgrSolver<D>::stepMain()
if(D::mMLSUPS>10000){ D::mMLSUPS = -1; }
else { mAvgMLSUPS += D::mMLSUPS; mAvgMLSUPSCnt += 1.0; } // track average mlsups
LbmFloat totMLSUPS = ( ((mLevel[mMaxRefine].lSizex-2)*(mLevel[mMaxRefine].lSizey-2)*(getForZMax1(mMaxRefine)-getForZMin1(mMaxRefine))) / ((timeend-timestart)/(double)1000.0) ) / (1000000);
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
@@ -2837,6 +2717,7 @@ LbmFsgrSolver<D>::stepMain()
" intd:"<<mNumInterdCells<< sepStr<<
" invif:"<<mNumInvIfCells<< sepStr<<
" invift:"<<mNumInvIfTotal<< sepStr<<
" fsgrcs:"<<mNumFsgrChanges<< sepStr<<
" filled:"<<D::mNumFilledCells<<", emptied:"<<D::mNumEmptiedCells<< sepStr<<
" mMxv:"<<mMxvx<<","<<mMxvy<<","<<mMxvz<<", tscnts:"<<mTimeSwitchCounts<< sepStr<<
/*" rhoMax:"<<mRhoMax<<", rhoMin:"<<mRhoMin<<", vlenMax:"<<mMaxVlen<<", "*/
@@ -2845,17 +2726,18 @@ LbmFsgrSolver<D>::stepMain()
" for '"<<D::mName<<"' " );
//wrong?
debMsgDirect(", dccd:"<< mCurrentMass<<"/"<<mCurrentVolume<<"("<<D::mFixMass<<")" );
//debMsgDirect(", dccd:"<< mCurrentMass<<"/"<<mCurrentVolume<<"(fix:"<<D::mFixMass<<",ini:"<<mInitialMass<<") ");
debMsgDirect(std::endl);
debMsgDirect(D::mStepCnt<<": dccd="<< mCurrentMass<<"/"<<mCurrentVolume<<"(fix="<<D::mFixMass<<",ini="<<mInitialMass<<") ");
debMsgDirect(std::endl);
// nicer output
debMsgDirect(std::endl); //
//debMsgStd(" ",DM_MSG," ",10);
}
// else {
//debMsgDirect(".");
} else {
debMsgDirect(".");
//if((mStepCnt%10)==9) debMsgDirect("\n");
//}
}
if(D::mStepCnt==1) {
mMinNoCells = mMaxNoCells = D::mNumUsedCells;
@@ -2865,7 +2747,7 @@ LbmFsgrSolver<D>::stepMain()
}
// mass scale test
if(mMaxRefine>0) {
if((mMaxRefine>0)&&(mInitialMass>0.0)) {
LbmFloat mscale = mInitialMass/mCurrentMass;
mscale = 1.0;
@@ -2873,10 +2755,15 @@ LbmFsgrSolver<D>::stepMain()
if(mCurrentMass<mInitialMass) mscale = 1.0+dchh;
if(mCurrentMass>mInitialMass) mscale = 1.0-dchh;
// use mass rescaling?
// with float precision this seems to be nonsense...
const bool MREnable = false;
const int MSInter = 2;
static int mscount = 0;
if( (1) && ((mLevel[0].lsteps%MSInter)== (MSInter-1)) && ( ABS( (mInitialMass/mCurrentMass)-1.0 ) > 0.01) && ( dsbits & (1<<(mMaxRefine-0)) ) ){
if( (MREnable) && ((mLevel[0].lsteps%MSInter)== (MSInter-1)) && ( ABS( (mInitialMass/mCurrentMass)-1.0 ) > 0.01) && ( dsbits & (1<<(mMaxRefine-0)) ) ){
// example: FORCE RESCALE MASS! ini:1843.5, cur:1817.6, f=1.01425 step:22153 levstep:5539 msc:37
// mass rescale MASS RESCALE check
errMsg("MDTDD","\n\n");
errMsg("MDTDD","FORCE RESCALE MASS! "
<<"ini:"<<mInitialMass<<", cur:"<<mCurrentMass<<", f="<<ABS(mInitialMass/mCurrentMass)
@@ -2913,6 +2800,13 @@ LbmFsgrSolver<D>::stepMain()
mCurrentMass *= mscale;
}// if mass scale test */
else {
// use current mass after full step for initial setting
if((mMaxRefine>0)&&(mInitialMass<=0.0) && (levsteps == (mMaxRefine+1))) {
mInitialMass = mCurrentMass;
debMsgStd("MDTDD",DM_NOTIFY,"Second Initial Mass Init: "<<mInitialMass, 2);
}
}
// one of the last things to do - adapt timestep
// was in fineAdvance before...
@@ -2984,15 +2878,9 @@ LbmFsgrSolver<D>::fineAdvance()
// advance time before timestep change
mSimulationTime += D::mpParam->getStepTime();
// time adaptivity
D::mpParam->setSimulationMaxSpeed( sqrt(mMaxVlen / 1.5) );
if(mTimeAdap) {
// ORG adaptTimestep();
} // time adaptivity
//if(mStartSymm) { checkSymmetry("step2"); } // DEBUG
if(!D::mSilent){ errMsg("fineAdvance"," stepped from "<<mLevel[mMaxRefine].setCurr<<" to "<<mLevel[mMaxRefine].setOther<<" step"<< (mLevel[mMaxRefine].lsteps) ); }
// update other set
@@ -3029,7 +2917,6 @@ LbmFsgrSolver<D>::mainLoop(int lev)
#include "paraloop.h"
#else // PARALLEL==1
{ // main loop region
const int id = 0, Nthrds = 1;
int kstart=D::getForZMin1(), kend=D::getForZMax1();
#define PERFORM_USQRMAXCHECK USQRMAXCHECK(usqr,ux,uy,uz, mMaxVlen, mMxvx,mMxvy,mMxvz);
#endif // PARALLEL==1
@@ -3079,7 +2966,7 @@ LbmFsgrSolver<D>::mainLoop(int lev)
// nutshell outflow HACK
if(mGfxGeoSetup==2) {
for(int k= getForZMin1(lev); k< getForZMax1(lev); ++k) {
for(int k= getForZMin1(); k< getForZMax1(lev); ++k) {
{const int j=1;
for(int i=1;i<mLevel[mMaxRefine].lSizex-1;++i) {
if(RFLAG(lev, i,j,k,SRCS(lev)) & CFFluid) {
@@ -3099,8 +2986,6 @@ LbmFsgrSolver<D>::mainLoop(int lev)
// now stream etc.
// use template functions for 2D/3D
//#pragma omp for schedule(static,1) nowait
//for(int k= getForZMin1(lev); k< getForZMax1(lev); ++k) {
#if COMPRESSGRIDS==0
for(int k=kstart;k<kend;++k) {
for(int j=1;j<mLevel[lev].lSizey-1;++j) {
@@ -3114,12 +2999,18 @@ LbmFsgrSolver<D>::mainLoop(int lev)
kstart = temp-1;
} // COMPRT
const int Nj = D::mSizey-2;
const int jstart = 1+( id * (Nj / Nthrds) );
const int jend = 1+( (id+1) * (Nj / Nthrds) );
#if PARALLEL==0
const int id = 0, Nthrds = 1;
#endif // PARALLEL==1
const int Nj = mLevel[mMaxRefine].lSizey;
int jstart = 0+( id * (Nj / Nthrds) );
int jend = 0+( (id+1) * (Nj / Nthrds) );
if( ((Nj/Nthrds) *Nthrds) != Nj) {
errMsg("LbmFsgrSolver","Invalid domain size Nj="<<Nj<<" Nthrds="<<Nthrds);
}
// cutoff obstacle boundary
if(jstart<1) jstart = 1;
if(jend>mLevel[mMaxRefine].lSizey-1) jend = mLevel[mMaxRefine].lSizey-1;
#if PARALLEL==1
errMsg("LbmFsgrSolver::mainLoop","id="<<id<<" js="<<jstart<<" je="<<jend<<" jdir="<<(1) ); // debug
@@ -3159,11 +3050,11 @@ LbmFsgrSolver<D>::mainLoop(int lev)
D::mPanic=1;
}
#endif
oldFlag = *pFlagSrc;
// stream from current set to other, then collide and store
#if INTCFCOARSETEST==1
//if(RFLAG(lev, i,j,k,mLevel[lev].setCurr)&CFGrFromCoarse) {
if( ((*pFlagSrc) & (CFGrFromCoarse)) ) { // interpolateFineFromCoarse test!
// old INTCFCOARSETEST==1
if( (oldFlag & (CFGrFromCoarse)) ) { // interpolateFineFromCoarse test!
if(( D::mStepCnt & (1<<(mMaxRefine-lev)) ) ==1) {
FORDF0 { RAC(tcel,l) = RAC(ccel,l); }
} else {
@@ -3171,20 +3062,70 @@ LbmFsgrSolver<D>::mainLoop(int lev)
calcNumUsedCells++;
}
continue; // interpolateFineFromCoarse test!
} // interpolateFineFromCoarse test!
#else // INTCFCOARSETEST==1
done in main loop afterwards..
#endif // INTCFCOARSETEST==1
} // interpolateFineFromCoarse test! old INTCFCOARSETEST==1
if( ((*pFlagSrc) & (CFBnd|CFEmpty|CFGrFromCoarse|CFUnused)) ) {
*pFlagDst = *pFlagSrc;
if(oldFlag & (CFMbndInflow)) {
// fluid & if are ok, fill if later on
int isValid = oldFlag & (CFFluid|CFInter);
const LbmFloat iniRho = 1.0;
const int OId = oldFlag>>24;
if(!isValid) {
// 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]); }
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;
// dont treat cell until next step
continue;
}
}
else // these are exclusive
if(oldFlag & (CFMbndOutflow)) {
//errMsg("OUTFLOW"," ar "<<PRINT_IJK );
int isnotValid = oldFlag & (CFFluid);
if(isnotValid) {
// remove fluid cells, shouldnt be here anyway
//const int OId = oldFlag>>24;
LbmFloat fluidRho = m[0]; FORDF1 { fluidRho += m[l]; }
mInitialMass -= fluidRho;
const LbmFloat iniRho = 0.0;
RAC(tcel, dMass) = RAC(tcel, dFfrac) = iniRho;
RAC(tcel, dFlux) = FLUX_INIT;
changeFlag(lev, i,j,k, TSET(lev), CFInter);
// same as ifemptied for if below
LbmPoint emptyp;
emptyp.x = i; emptyp.y = j; emptyp.z = k;
#if PARALLEL==1
calcListEmpty[id].push_back( emptyp );
#else // PARALLEL==1
mListEmpty.push_back( emptyp );
#endif // PARALLEL==1
calcCellsEmptied++;
continue;
}
}
if(oldFlag & (CFBnd|CFEmpty|CFGrFromCoarse|CFUnused)) {
*pFlagDst = oldFlag;
//RAC(tcel,dFfrac) = 0.0;
//RAC(tcel,dFlux) = FLUX_INIT; // necessary?
continue;
}
/*if( oldFlag & CFNoBndFluid ) { // TEST ME FASTER?
OPTIMIZED_STREAMCOLLIDE; PERFORM_USQRMAXCHECK;
RAC(tcel,dFfrac) = 1.0;
*pFlagDst = (CellFlagType)oldFlag; // newFlag;
calcCurrentMass += rho; calcCurrentVolume += 1.0;
calcNumUsedCells++;
continue;
}// TEST ME FASTER? */
// only neighbor flags! not own flag
oldFlag = * pFlagSrc;
nbored = 0;
#if OPT3D==false
@@ -3223,28 +3164,40 @@ LbmFsgrSolver<D>::mainLoop(int lev)
// FLUID cells
if( oldFlag & CFFluid ) {
// only standard fluid cells (with nothing except fluid as nbs
if(!( (nbored) & (~(CFFluid)) )) {
// do standard stream/collide
OPTIMIZED_STREAMCOLLIDE;
// FIXME check for which cells this is executed!
} else {
if(oldFlag&CFMbndInflow) {
// force velocity for inflow
const int OId = oldFlag>>24;
DEFAULT_STREAM;
ux = mLevel[lev].gravity[0]; uy = mLevel[lev].gravity[1]; uz = mLevel[lev].gravity[2];
DEFAULT_COLLIDE;
}
if(nbored&CFBnd) {
oldFlag &= (~CFNoBndFluid);
//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); }
} else {
oldFlag |= CFNoBndFluid;
if(nbored&CFBnd) {
DEFAULT_STREAM;
ux = mLevel[lev].gravity[0]; uy = mLevel[lev].gravity[1]; uz = mLevel[lev].gravity[2];
DEFAULT_COLLIDE;
oldFlag &= (~CFNoBndFluid);
} else {
// do standard stream/collide
OPTIMIZED_STREAMCOLLIDE;
// FIXME check for which cells this is executed!
oldFlag |= CFNoBndFluid;
}
}
PERFORM_USQRMAXCHECK;
// "normal" fluid cells
RAC(tcel,dFfrac) = 1.0;
*pFlagDst = (CellFlagType)oldFlag; // newFlag;
calcCurrentMass += rho;
LbmFloat ofrho=RAC(ccel,0);
for(int l=1; l<D::cDfNum; l++) { ofrho += RAC(ccel,l); }
calcCurrentMass += ofrho;
calcCurrentVolume += 1.0;
continue;
}
@@ -3253,12 +3206,11 @@ LbmFsgrSolver<D>::mainLoop(int lev)
// make sure: check which flags to really unset...!
newFlag = newFlag & (~(
CFNoNbFluid|CFNoNbEmpty| CFNoDelete
|CFNoInterpolSrc
|CFNoBndFluid
| CFNoInterpolSrc
| CFNoBndFluid
));
// unnecessary for interface cells... !?
if(nbored&CFBnd) { } else { newFlag |= CFNoBndFluid; }
//if(nbored&CFBnd) { } else { newFlag |= CFNoBndFluid; }
// store own dfs and mass
mass = RAC(ccel,dMass);
@@ -3471,6 +3423,14 @@ LbmFsgrSolver<D>::mainLoop(int lev)
// only with interface neighbors...?
PERFORM_USQRMAXCHECK;
if(oldFlag & (CFMbndInflow)) {
// fill if cells in inflow region
if(myfrac<0.5) {
mass += 0.25;
mInitialMass += 0.25;
}
}
// interface cell filled or emptied?
iffilled = ifemptied = 0;
// interface cells empty/full?, WARNING: to mark these cells, better do it at the end of reinitCellFlags
@@ -3479,6 +3439,12 @@ LbmFsgrSolver<D>::mainLoop(int lev)
// interface cell if empty?
if( (mass) <= (rho * ( -FSGR_MAGICNR)) ) { ifemptied = 1; }
if(oldFlag & (CFMbndOutflow)) {
mInitialMass -= mass;
mass = myfrac = 0.0;
iffilled = 0; ifemptied = 1;
}
// looks much nicer... LISTTRICK
#if FSGR_LISTTRICK==true
if(!iffilled) {
@@ -3580,7 +3546,7 @@ LbmFsgrSolver<D>::mainLoop(int lev)
D::mNumEmptiedCells = calcCellsEmptied;
D::mNumUsedCells = calcNumUsedCells;
#if PARALLEL==1
errMsg("PARALLELusqrcheck"," curr: "<<mMaxVlen<<"|"<<mMxvx<<","<<mMxvy<<","<<mMxvz);
//errMsg("PARALLELusqrcheck"," curr: "<<mMaxVlen<<"|"<<mMxvx<<","<<mMxvy<<","<<mMxvz);
for(int i=0; i<MAX_THREADS; i++) {
for(int j=0; j<calcListFull[i].size() ; j++) mListFull.push_back( calcListFull[i][j] );
for(int j=0; j<calcListEmpty[i].size(); j++) mListEmpty.push_back( calcListEmpty[i][j] );
@@ -3591,7 +3557,7 @@ LbmFsgrSolver<D>::mainLoop(int lev)
mMaxVlen = calcMaxVlen[i];
}
errMsg("PARALLELusqrcheck"," curr: "<<mMaxVlen<<"|"<<mMxvx<<","<<mMxvy<<","<<mMxvz<<
" calc["<<i<<": "<<calcMaxVlen[i]<<"|"<<calcMxvx[i]<<","<<calcMxvy[i]<<","<<calcMxvz[i] );
" calc["<<i<<": "<<calcMaxVlen[i]<<"|"<<calcMxvx[i]<<","<<calcMxvy[i]<<","<<calcMxvz[i]<<"] " );
}
#endif // PARALLEL==1
@@ -3658,49 +3624,18 @@ LbmFsgrSolver<D>::coarseAdvance(int lev)
m[0] = tmp = usqr = 0.0;
coarseCalculateFluxareas(lev);
/*
//for(int lev=0; lev<mMaxRefine; lev++) { TEST DEBUG
FSGR_FORIJK_BOUNDS(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];
if(RFLAG(lev+1, ni,nj,nk, mLevel[lev+1].setCurr)&
(CFGrFromCoarse|CFUnused|CFEmpty) //? (CFBnd|CFEmpty|CFGrFromCoarse|CFUnused)
) {
totArea += mFsgrCellArea[l];
}
} // l
QCELL(lev, i,j,k,mLevel[lev].setCurr, dFlux) = totArea;
//continue;
} else
if( RFLAG(lev+1, i*2,j*2,k*2,mLevel[lev+1].setCurr) & (CFEmpty|CFUnused)) {
QCELL(lev, i,j,k,mLevel[lev].setCurr, dFlux) = 1.0;
//continue;
} else {
QCELL(lev, i,j,k,mLevel[lev].setCurr, dFlux) = 0.0;
}
//errMsg("DFINI"," at l"<<lev<<" "<<PRINT_IJK<<" v:"<<QCELL(lev, i,j,k,mLevel[lev].setCurr, dFlux) );
}
} // } TEST DEBUG */
// copied from fineAdv.
CellFlagType *pFlagSrc = &RFLAG(lev, 1,1,getForZMin1(lev),SRCS(lev));
CellFlagType *pFlagDst = &RFLAG(lev, 1,1,getForZMin1(lev),TSET(lev));
CellFlagType *pFlagSrc = &RFLAG(lev, 1,1,getForZMin1(),SRCS(lev));
CellFlagType *pFlagDst = &RFLAG(lev, 1,1,getForZMin1(),TSET(lev));
pFlagSrc -= 1;
pFlagDst -= 1;
ccel = RACPNT(lev, 1,1,getForZMin1(lev) ,SRCS(lev)); // QTEST
ccel = RACPNT(lev, 1,1,getForZMin1() ,SRCS(lev)); // QTEST
ccel -= QCELLSTEP;
tcel = RACPNT(lev, 1,1,getForZMin1(lev) ,TSET(lev)); // QTEST
tcel = RACPNT(lev, 1,1,getForZMin1() ,TSET(lev)); // QTEST
tcel -= QCELLSTEP;
//if(strstr(D::getName().c_str(),"Debug")){ errMsg("DEBUG","DEBUG!!!!!!!!!!!!!!!!!!!!!!!"); }
// use template functions for 2D/3D
//for(int k= getForZMin1(lev); k< getForZMax1(lev); ++k) {
//for(int j=1;j<mLevel[lev].lSizey-1;++j) {
//for(int i=1;i<mLevel[lev].lSizex-1;++i) {
//CellFlagType *pFlagSrc = &RFLAG(lev, i,j,k,SRCS(lev));
for(int k= getForZMin1(lev); k< getForZMax1(lev); ++k) {
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) {
#if FSGR_STRICT_DEBUG==1
@@ -3710,13 +3645,6 @@ LbmFsgrSolver<D>::coarseAdvance(int lev)
pFlagDst++;
ccel += QCELLSTEP;
tcel += QCELLSTEP;
/*if(
//((*((ULLI*) pFlagSrc))==CF4_EMPTY ) ||
((*((ULLI*) pFlagSrc))==CF4_UNUSED )
) {
//ebugMarkCell(mMaxRefine, i,j,k);
ADVANCE_POINTERS(3); continue;
} //else */
// from coarse cells without unused nbs are not necessary...! -> remove
if( ((*pFlagSrc) & (CFGrFromCoarse)) ) {
@@ -3729,13 +3657,18 @@ LbmFsgrSolver<D>::coarseAdvance(int lev)
#if ELBEEM_BLENDER!=1
errMsg("coarseAdvance","FC2NRM_CHECK Converted CFGrFromCoarse to Norm at "<<lev<<" "<<PRINT_IJK);
#endif // ELBEEM_BLENDER!=1
// FIXME add debug check for these types of cells?
// FIXME add debug check for these types of cells?, move to perform coarsening?
}
} // */
//*(pFlagSrc+pFlagTarOff) = *pFlagSrc; // always set other set...
#if FSGR_STRICT_DEBUG==1
*pFlagDst = *pFlagSrc; // always set other set...
#if INTCFCOARSETEST==1
#else
*pFlagDst = (*pFlagSrc & (~CFGrCoarseInited)); // always set other set... , remove coarse inited flag
#endif
// old INTCFCOARSETEST==1
if((*pFlagSrc) & CFGrFromCoarse) { // interpolateFineFromCoarse test!
if(( D::mStepCnt & (1<<(mMaxRefine-lev)) ) ==1) {
FORDF0 { RAC(tcel,l) = RAC(ccel,l); }
@@ -3744,49 +3677,7 @@ LbmFsgrSolver<D>::coarseAdvance(int lev)
D::mNumUsedCells++;
}
continue; // interpolateFineFromCoarse test!
} // interpolateFineFromCoarse test!
#else // INTCFCOARSETEST==1
//done in main loop afterwards..
#endif // INTCFCOARSETEST==1
/*if( ( (*((ULLI*) pFlagSrc))==CF4_NOBND_NORMFLUID ) ) {
//ebugMarkCell(lev,i,j,k);
// WARNING removed iis stuff
// -------------------------------------------------------------------------------------------------------------
//tcel = (ccel+(pFlagTarOff*dTotalNum));
OPTIMIZED_STREAMCOLLIDE;
//USQRMAXCHECK(usqr,ux,uy,uz, mMaxVlen, mMxvx,mMxvy,mMxvz);
calcCurrentVolume += RAC(ccel,dFlux); calcCurrentMass += RAC(ccel,dFlux)*rho;
RAC(tcel,dFfrac) = 1.0;
*pFlagDst = *pFlagSrc;
ADVANCE_POINTERS(1); //tcel += (QCELLSTEP);
// -------------------------------------------------------------------------------------------------------------
OPTIMIZED_STREAMCOLLIDE;
//USQRMAXCHECK(usqr,ux,uy,uz, mMaxVlen, mMxvx,mMxvy,mMxvz);
//calcCurrentVolume += 1.0; calcCurrentMass += rho;
calcCurrentVolume += RAC(ccel,dFlux); calcCurrentMass += RAC(ccel,dFlux)*rho;
tcel[dFfrac] = 1.0;
*pFlagDst = *pFlagSrc;
ADVANCE_POINTERS(1); //tcel += (QCELLSTEP);
// -------------------------------------------------------------------------------------------------------------
OPTIMIZED_STREAMCOLLIDE;
//USQRMAXCHECK(usqr,ux,uy,uz, mMaxVlen, mMxvx,mMxvy,mMxvz);
//calcCurrentVolume += 1.0; calcCurrentMass += rho;
calcCurrentVolume += RAC(ccel,dFlux); calcCurrentMass += RAC(ccel,dFlux)*rho;
tcel[dFfrac] = 1.0;
*pFlagDst = *pFlagSrc;
ADVANCE_POINTERS(1); //tcel += (QCELLSTEP);
// -------------------------------------------------------------------------------------------------------------
OPTIMIZED_STREAMCOLLIDE;
//USQRMAXCHECK(usqr,ux,uy,uz, mMaxVlen, mMxvx,mMxvy,mMxvz);
//calcCurrentVolume += 1.0; calcCurrentMass += rho;
calcCurrentVolume += RAC(ccel,dFlux); calcCurrentMass += RAC(ccel,dFlux)*rho;
tcel[dFfrac] = 1.0;
*pFlagDst = *pFlagSrc;
D::mNumUsedCells+=4;
continue; // nobnd fluid case
} // */
} // interpolateFineFromCoarse test! old INTCFCOARSETEST==1
if( ((*pFlagSrc) & (CFFluid)) ) {
ccel = RACPNT(lev, i,j,k ,SRCS(lev));
@@ -3803,13 +3694,9 @@ LbmFsgrSolver<D>::coarseAdvance(int lev)
}
OPTIMIZED_STREAMCOLLIDE;
//USQRMAXCHECK(usqr,ux,uy,uz, mMaxVlen, mMxvx,mMxvy,mMxvz);
//if(nbored&CFBnd) { oldFlag &= (~CFNoBndFluid); } else { }
*pFlagDst |= CFNoBndFluid; // test?
//calcCurrentVolume += 1.0; calcCurrentMass += rho;
calcCurrentVolume += RAC(ccel,dFlux); calcCurrentMass += RAC(ccel,dFlux)*rho;
calcCurrentVolume += RAC(ccel,dFlux);
calcCurrentMass += RAC(ccel,dFlux)*rho;
//ebugMarkCell(lev+1, 2*i+1,2*j+1,2*k );
#if FSGR_STRICT_DEBUG==1
if(rho<-1.0){ debugMarkCell(lev, i,j,k );
@@ -3843,80 +3730,16 @@ LbmFsgrSolver<D>::coarseAdvance(int lev)
mLevel[lev].lsteps++;
mLevel[lev].lmass = calcCurrentMass * mLevel[lev].lcellfactor;
mLevel[lev].lvolume = calcCurrentVolume * mLevel[lev].lcellfactor;
//errMsg("DFINI", " m l"<<lev<<" m="<<mLevel[lev].lmass<<" c="<<calcCurrentMass<<" lcf="<< mLevel[lev].lcellfactor );
//errMsg("DFINI", " v l"<<lev<<" v="<<mLevel[lev].lvolume<<" c="<<calcCurrentVolume<<" lcf="<< mLevel[lev].lcellfactor );
#ifndef ELBEEM_BLENDER
errMsg("DFINI", " m l"<<lev<<" m="<<mLevel[lev].lmass<<" c="<<calcCurrentMass<<" lcf="<< mLevel[lev].lcellfactor );
errMsg("DFINI", " v l"<<lev<<" v="<<mLevel[lev].lvolume<<" c="<<calcCurrentVolume<<" lcf="<< mLevel[lev].lcellfactor );
#endif // ELBEEM_BLENDER
}
/*****************************************************************************/
//! multi level functions
/*****************************************************************************/
#define MARK_INT_CELLS false
#define SHOWALL_INT_CELLS true
// interpolate from level lev-1 to lev at borders CFGrFromCoarse
template<class D>
void
LbmFsgrSolver<D>::interpolateFineFromCoarse(int lev, LbmFloat t)
{
if((lev-1<0) || ((lev)>mMaxRefine)) return;
# if FSGR_STRICT_DEBUG==1
// reset all unused cell values to invalid
{ int dlev = lev; //mMaxRefine;
int unuCnt = 0;
for(int k= getForZMin1(dlev); k< getForZMax1(dlev); ++k) {
for(int j=1;j<mLevel[dlev].lSizey-1;++j) {
for(int i=1;i<mLevel[dlev].lSizex-1;++i) {
if( (RFLAG(dlev, i,j,k,mLevel[dlev].setCurr) & CFGrFromCoarse ) ||
(RFLAG(dlev, i,j,k,mLevel[dlev].setCurr) & CFUnused ) ||
(RFLAG(dlev, i,j,k,mLevel[dlev].setCurr) & CFEmpty ) ) {
if(RFLAG(dlev, i,j,k,mLevel[dlev].setCurr) & CFGrFromCoarse ) { RFLAG(dlev, i,j,k,mLevel[dlev].setCurr) = CFFluid|CFGrFromCoarse; }
FORDF0 { QCELL(dlev,i,j,k,mLevel[dlev].setCurr,l) = -100.0; }
unuCnt++;
}
} } }
errMsg("interpolateFineFromCoarse"," reset l"<<dlev<<" "<<unuCnt<<" cells unused ");
} // dlev
# endif // FSGR_STRICT_DEBUG==1
// INTCFCOARSETEST
// now set fine bc
for(int k= getForZMin1(lev); k< getForZMax1(lev); ++k) {
for(int j=1;j<mLevel[lev].lSizey-1;++j) {
for(int i=1;i<mLevel[lev].lSizex-1;++i) {
if(RFLAG(lev, i,j,k,mLevel[lev].setCurr)&CFGrFromCoarse) {
/*if((i&1) && (j&1) && ( (D::cDimension==2) || (k&1) ) ){
errMsg("IFFC_CHECK", " betXYZ cell? on lev "<<lev<<" "<<PRINT_IJK);
debugMarkCell(lev,i,j,k);
D::mPanic=1;
} // */
interpolateCellFromCoarse( lev,i,j,k, mLevel[lev].setCurr, t, CFFluid|CFGrFromCoarse, false);
D::mNumUsedCells++;
//int lev, int i, int j,int k, int set, LbmFloat t, CellFlagType flagSet) {
}
} } }
# if FSGR_STRICT_DEBUG==1
// check that all values are now correctly inited
{ int dlev = lev; //mMaxRefine;
for(int k= getForZMin1(dlev); k< getForZMax1(dlev); ++k) {
for(int j=1;j<mLevel[dlev].lSizey-1;++j) {
for(int i=1;i<mLevel[dlev].lSizex-1;++i) {
if(RFLAG(dlev, i,j,k,mLevel[dlev].setCurr) & CFGrFromCoarse ) {
FORDF0 { if(QCELL(dlev,i,j,k,mLevel[dlev].setCurr,l)<-1.0){
errMsg("CHECKFCINITS"," l"<<(dlev)<<" "<< PRINT_IJK <<" was not inited! ");
debugMarkCell(dlev,i,j,k);
D::mPanic = 1;
} }
}
} } }
} // dlev
# endif // FSGR_STRICT_DEBUG==1
if(!D::mSilent){ errMsg("interpolateFineFromCoarse"," to l"<<lev<<" s"<<mLevel[lev].setCurr<<", from "<<(lev-1)<<" (s"<< mLevel[lev-1].setCurr<<"*"<<(1.0-(t))<<"+ s"<<mLevel[lev-1].setOther<<"*"<<((t))<<")" <<" "); }
}
// get dfs from level (lev+1) to (lev) coarse border nodes
template<class D>
@@ -3927,7 +3750,7 @@ LbmFsgrSolver<D>::coarseRestrictFromFine(int lev)
#if FSGR_STRICT_DEBUG==1
// reset all unused cell values to invalid
int unuCnt = 0;
for(int k= getForZMin1(lev); k< getForZMax1(lev); ++k) {
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) {
CellFlagType *pFlagSrc = &RFLAG(lev, i,j,k,mLevel[lev].setCurr);
@@ -3951,23 +3774,51 @@ LbmFsgrSolver<D>::coarseRestrictFromFine(int lev)
const int dstSet = mLevel[lev].setCurr;
LbmFloat rho=0.0, ux=0.0, uy=0.0, uz=0.0;
LbmFloat omegaDst, omegaSrc;
LbmFloat df[LBM_DFNUM];
LbmFloat feq[LBM_DFNUM];
LbmFloat dfScale = mDfScaleUp;
LbmFloat *ccel = NULL;
LbmFloat *tcel = NULL;
#if OPT3D==true
LbmFloat m[LBM_DFNUM];
// for macro add
LbmFloat usqr;
//LbmFloat *addfcel, *dstcell;
LbmFloat lcsmqadd, lcsmqo, lcsmeq[LBM_DFNUM];
LbmFloat lcsmDstOmega, lcsmSrcOmega, lcsmdfscale;
#else // OPT3D==true
LbmFloat df[LBM_DFNUM];
LbmFloat omegaDst, omegaSrc;
LbmFloat feq[LBM_DFNUM];
LbmFloat dfScale = mDfScaleUp;
#endif // OPT3D==true
LbmFloat mGaussw[27];
LbmFloat totGaussw = 0.0;
const LbmFloat alpha = 1.0;
const LbmFloat gw = sqrt(2.0*D::cDimension);
#ifndef ELBEEM_BLENDER
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]));
LbmFloat w = expf( -alpha*d*d ) - expf( -alpha*gw*gw );
//errMsg("coarseRestrictFromFine", "TCRFF_DFDEBUG2 cell n"<<n<<" d"<<d<<" w"<<w);
mGaussw[n] = w;
totGaussw += w;
}
for(int n=0;(n<D::cDirNum); n++) {
mGaussw[n] = mGaussw[n]/totGaussw;
}
//totGaussw = 1.0/totGaussw;
//if(!D::mInitDone) {
//errMsg("coarseRestrictFromFine", "TCRFF_DFDEBUG2 test pre init");
//mGaussw[0] = 1.0;
//for(int n=1;(n<D::cDirNum); n++) { mGaussw[n] = 0.0; }
//}
//restrict
for(int k= getForZMin1(lev); k< getForZMax1(lev); ++k) {
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) {
CellFlagType *pFlagSrc = &RFLAG(lev, i,j,k,dstSet);
@@ -3979,24 +3830,34 @@ LbmFsgrSolver<D>::coarseRestrictFromFine(int lev)
ccel = RACPNT(lev+1, 2*i,2*j,2*k,srcSet);
tcel = RACPNT(lev , i,j,k ,dstSet);
#if OPT3D==false
rho= ux= uy= uz=0.0;
FORDF0{
df[l] = RAC(ccel,l); //QCELL(lev+1, 2*i,2*j,2*k,srcSet, l);
//df[l] = QCELL(lev+1, 2*i,2*j,2*k,srcSet, l); // OLD
#if FSGR_STRICT_DEBUG==1
if( df[l]<-1.0 ){ errMsg("INVDFCREST_DFCHECK", PRINT_IJK<<" s"<<dstSet<<" from "<<PRINT_VEC(2*i,2*j,2*k)<<" s"<<srcSet<<" df"<<l<<":"<< df[l]); }
#endif
rho += df[l];
ux += (D::dfDvecX[l]*df[l]);
uy += (D::dfDvecY[l]*df[l]);
uz += (D::dfDvecZ[l]*df[l]);
# if OPT3D==false
// 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];
ccel = RACPNT(lev+1, ni,nj,nk,srcSet);// CFINTTEST
const LbmFloat weight = mGaussw[n];
FORDF0{
LbmFloat cdf = weight * RAC(ccel,l);
# if FSGR_STRICT_DEBUG==1
if( cdf<-1.0 ){ errMsg("INVDFCREST_DFCHECK", PRINT_IJK<<" s"<<dstSet<<" from "<<PRINT_VEC(2*i,2*j,2*k)<<" s"<<srcSet<<" df"<<l<<":"<< df[l]); }
# endif
//errMsg("INVDFCREST_DFCHECK", PRINT_IJK<<" s"<<dstSet<<" from "<<PRINT_VEC(2*i,2*j,2*k)<<" s"<<srcSet<<" df"<<l<<":"<< df[l]<<" = "<<cdf<<" , w"<<weight);
df[l] += cdf;
}
}
// calc rho etc. from weighted dfs
rho = ux = uy = uz = 0.0;
FORDF0{
feq[l] = D::getCollideEq(l, rho,ux,uy,uz);
//df[l] = QCELL(lev+1, 2*i,2*j,2*k,srcSet, l); // OLD
LbmFloat cdf = df[l];
rho += cdf;
ux += (D::dfDvecX[l]*cdf);
uy += (D::dfDvecY[l]*cdf);
uz += (D::dfDvecZ[l]*cdf);
}
FORDF0{ feq[l] = D::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);
@@ -4005,62 +3866,97 @@ LbmFsgrSolver<D>::coarseRestrictFromFine(int lev)
omegaDst = mLevel[lev+0].omega; /* NEWSMAGOT*/
omegaSrc = mLevel[lev+1].omega;
}
//LbmFloat dfScaleFac = (newSteptime/1.0)/(levOldStepsize[lev]/levOldOmega[lev]);
dfScale = (mLevel[lev ].stepsize/mLevel[lev+1].stepsize)* (1.0/omegaDst-1.0)/ (1.0/omegaSrc-1.0); // yu
//dfScale = 1.0;
FORDF0{
//QCELL(lev, i,j,k,dstSet, l) = feq[l]+ (df[l]-feq[l])*dfScale; // OLD
RAC(tcel, l) = feq[l]+ (df[l]-feq[l])*dfScale;
}
#else // OPT3D
/*test this*/
# else // OPT3D
// similar to OPTIMIZED_STREAMCOLLIDE_UNUSED
rho = CCEL_C + CCEL_N + CCEL_S + CCEL_E + CCEL_W + CCEL_T \
+ CCEL_B + CCEL_NE + CCEL_NW + CCEL_SE + CCEL_SW + CCEL_NT \
+ CCEL_NB + CCEL_ST + CCEL_SB + CCEL_ET + CCEL_EB + CCEL_WT + CCEL_WB; \
ux = CCEL_E - CCEL_W + CCEL_NE - CCEL_NW + CCEL_SE - CCEL_SW \
+ CCEL_ET + CCEL_EB - CCEL_WT - CCEL_WB; \
uy = CCEL_N - CCEL_S + CCEL_NE + CCEL_NW - CCEL_SE - CCEL_SW \
+ CCEL_NT + CCEL_NB - CCEL_ST - CCEL_SB; \
uz = CCEL_T - CCEL_B + CCEL_NT - CCEL_NB + CCEL_ST - CCEL_SB \
+ CCEL_ET - CCEL_EB + CCEL_WT - CCEL_WB; \
//rho = ux = uy = uz = 0.0;
MSRC_C = CCELG_C(0) ;
MSRC_N = CCELG_N(0) ;
MSRC_S = CCELG_S(0) ;
MSRC_E = CCELG_E(0) ;
MSRC_W = CCELG_W(0) ;
MSRC_T = CCELG_T(0) ;
MSRC_B = CCELG_B(0) ;
MSRC_NE = CCELG_NE(0);
MSRC_NW = CCELG_NW(0);
MSRC_SE = CCELG_SE(0);
MSRC_SW = CCELG_SW(0);
MSRC_NT = CCELG_NT(0);
MSRC_NB = CCELG_NB(0);
MSRC_ST = CCELG_ST(0);
MSRC_SB = CCELG_SB(0);
MSRC_ET = CCELG_ET(0);
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);
MSRC_C += CCELG_C(n) ;
MSRC_N += CCELG_N(n) ;
MSRC_S += CCELG_S(n) ;
MSRC_E += CCELG_E(n) ;
MSRC_W += CCELG_W(n) ;
MSRC_T += CCELG_T(n) ;
MSRC_B += CCELG_B(n) ;
MSRC_NE += CCELG_NE(n);
MSRC_NW += CCELG_NW(n);
MSRC_SE += CCELG_SE(n);
MSRC_SW += CCELG_SW(n);
MSRC_NT += CCELG_NT(n);
MSRC_NB += CCELG_NB(n);
MSRC_ST += CCELG_ST(n);
MSRC_SB += CCELG_SB(n);
MSRC_ET += CCELG_ET(n);
MSRC_EB += CCELG_EB(n);
MSRC_WT += CCELG_WT(n);
MSRC_WB += CCELG_WB(n);
}
rho = MSRC_C + MSRC_N + MSRC_S + MSRC_E + MSRC_W + MSRC_T
+ MSRC_B + MSRC_NE + MSRC_NW + MSRC_SE + MSRC_SW + MSRC_NT
+ MSRC_NB + MSRC_ST + MSRC_SB + MSRC_ET + MSRC_EB + MSRC_WT + MSRC_WB;
ux = MSRC_E - MSRC_W + MSRC_NE - MSRC_NW + MSRC_SE - MSRC_SW
+ MSRC_ET + MSRC_EB - MSRC_WT - MSRC_WB;
uy = MSRC_N - MSRC_S + MSRC_NE + MSRC_NW - MSRC_SE - MSRC_SW
+ MSRC_NT + MSRC_NB - MSRC_ST - MSRC_SB;
uz = MSRC_T - MSRC_B + MSRC_NT - MSRC_NB + MSRC_ST - MSRC_SB
+ MSRC_ET - MSRC_EB + MSRC_WT - MSRC_WB;
usqr = 1.5 * (ux*ux + uy*uy + uz*uz); \
\
lcsmeq[dC] = EQC ; \
COLL_CALCULATE_DFEQ(lcsmeq); \
COLL_CALCULATE_NONEQTENSOR(lev+0, CCEL_ )\
COLL_CALCULATE_NONEQTENSOR(lev+0, MSRC_ )\
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); \
RAC(tcel, dC ) = (lcsmeq[dC ] + (CCEL_C -lcsmeq[dC ] )*lcsmdfscale);\
RAC(tcel, dN ) = (lcsmeq[dN ] + (CCEL_N -lcsmeq[dN ] )*lcsmdfscale);\
RAC(tcel, dS ) = (lcsmeq[dS ] + (CCEL_S -lcsmeq[dS ] )*lcsmdfscale);\
RAC(tcel, dE ) = (lcsmeq[dE ] + (CCEL_E -lcsmeq[dE ] )*lcsmdfscale);\
RAC(tcel, dW ) = (lcsmeq[dW ] + (CCEL_W -lcsmeq[dW ] )*lcsmdfscale);\
RAC(tcel, dT ) = (lcsmeq[dT ] + (CCEL_T -lcsmeq[dT ] )*lcsmdfscale);\
RAC(tcel, dB ) = (lcsmeq[dB ] + (CCEL_B -lcsmeq[dB ] )*lcsmdfscale);\
RAC(tcel, dNE) = (lcsmeq[dNE] + (CCEL_NE-lcsmeq[dNE] )*lcsmdfscale);\
RAC(tcel, dNW) = (lcsmeq[dNW] + (CCEL_NW-lcsmeq[dNW] )*lcsmdfscale);\
RAC(tcel, dSE) = (lcsmeq[dSE] + (CCEL_SE-lcsmeq[dSE] )*lcsmdfscale);\
RAC(tcel, dSW) = (lcsmeq[dSW] + (CCEL_SW-lcsmeq[dSW] )*lcsmdfscale);\
RAC(tcel, dNT) = (lcsmeq[dNT] + (CCEL_NT-lcsmeq[dNT] )*lcsmdfscale);\
RAC(tcel, dNB) = (lcsmeq[dNB] + (CCEL_NB-lcsmeq[dNB] )*lcsmdfscale);\
RAC(tcel, dST) = (lcsmeq[dST] + (CCEL_ST-lcsmeq[dST] )*lcsmdfscale);\
RAC(tcel, dSB) = (lcsmeq[dSB] + (CCEL_SB-lcsmeq[dSB] )*lcsmdfscale);\
RAC(tcel, dET) = (lcsmeq[dET] + (CCEL_ET-lcsmeq[dET] )*lcsmdfscale);\
RAC(tcel, dEB) = (lcsmeq[dEB] + (CCEL_EB-lcsmeq[dEB] )*lcsmdfscale);\
RAC(tcel, dWT) = (lcsmeq[dWT] + (CCEL_WT-lcsmeq[dWT] )*lcsmdfscale);\
RAC(tcel, dWB) = (lcsmeq[dWB] + (CCEL_WB-lcsmeq[dWB] )*lcsmdfscale);\
// */
/* IDF_WRITEBACK optimized */
//errMsg("coarseRestrictFromFine", "CRFF_DFDEBUG cell "<<PRINT_IJK<<" rho:"<<rho<<" u:"<<PRINT_VEC(ux,uy,uz)<<" "<<lcsmdfscale<<","<<lcsmDstOmega<<","<<lcsmSrcOmega );
#endif // OPT3D==false
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);
RAC(tcel, dE ) = (lcsmeq[dE ] + (MSRC_E -lcsmeq[dE ] )*lcsmdfscale);
RAC(tcel, dW ) = (lcsmeq[dW ] + (MSRC_W -lcsmeq[dW ] )*lcsmdfscale);
RAC(tcel, dT ) = (lcsmeq[dT ] + (MSRC_T -lcsmeq[dT ] )*lcsmdfscale);
RAC(tcel, dB ) = (lcsmeq[dB ] + (MSRC_B -lcsmeq[dB ] )*lcsmdfscale);
RAC(tcel, dNE) = (lcsmeq[dNE] + (MSRC_NE-lcsmeq[dNE] )*lcsmdfscale);
RAC(tcel, dNW) = (lcsmeq[dNW] + (MSRC_NW-lcsmeq[dNW] )*lcsmdfscale);
RAC(tcel, dSE) = (lcsmeq[dSE] + (MSRC_SE-lcsmeq[dSE] )*lcsmdfscale);
RAC(tcel, dSW) = (lcsmeq[dSW] + (MSRC_SW-lcsmeq[dSW] )*lcsmdfscale);
RAC(tcel, dNT) = (lcsmeq[dNT] + (MSRC_NT-lcsmeq[dNT] )*lcsmdfscale);
RAC(tcel, dNB) = (lcsmeq[dNB] + (MSRC_NB-lcsmeq[dNB] )*lcsmdfscale);
RAC(tcel, dST) = (lcsmeq[dST] + (MSRC_ST-lcsmeq[dST] )*lcsmdfscale);
RAC(tcel, dSB) = (lcsmeq[dSB] + (MSRC_SB-lcsmeq[dSB] )*lcsmdfscale);
RAC(tcel, dET) = (lcsmeq[dET] + (MSRC_ET-lcsmeq[dET] )*lcsmdfscale);
RAC(tcel, dEB) = (lcsmeq[dEB] + (MSRC_EB-lcsmeq[dEB] )*lcsmdfscale);
RAC(tcel, dWT) = (lcsmeq[dWT] + (MSRC_WT-lcsmeq[dWT] )*lcsmdfscale);
RAC(tcel, dWB) = (lcsmeq[dWB] + (MSRC_WB-lcsmeq[dWB] )*lcsmdfscale);
# endif // OPT3D==false
if( ((lev)<mMaxRefine) || (SHOWALL_INT_CELLS))
if((MARK_INT_CELLS)&&(D::cDimension==2)) { debugMarkCell(lev,i,j,k); }
//? if((lev<mMaxRefine)&&(D::cDimension==2)) { debugMarkCell(lev,i,j,k); }
# if FSGR_STRICT_DEBUG==1
errMsg("coarseRestrictFromFine", "CRFF_DFDEBUG cell "<<PRINT_IJK<<" rho:"<<rho<<" u:"<<PRINT_VEC(ux,uy,uz)<<" " );
//errMsg("coarseRestrictFromFine", "CRFF_DFDEBUG cell "<<PRINT_IJK<<" rho:"<<rho<<" u:"<<PRINT_VEC(ux,uy,uz)<<" " );
# endif // FSGR_STRICT_DEBUG==1
D::mNumUsedCells++;
} // from fine & fluid
@@ -4076,224 +3972,6 @@ LbmFsgrSolver<D>::coarseRestrictFromFine(int lev)
if(!D::mSilent){ errMsg("coarseRestrictFromFine"," from l"<<(lev+1)<<",s"<<mLevel[lev+1].setCurr<<" to l"<<lev<<",s"<<mLevel[lev].setCurr); }
}
template<class D>
bool
LbmFsgrSolver<D>::performCoarsening(int lev) {
if((lev<0) || ((lev+1)>mMaxRefine)) return false;
bool change = false;
bool nbsok;
// use template functions for 2D/3D
for(int k= getForZMin1(lev); k< getForZMax1(lev); ++k) {
for(int j=1;j<mLevel[lev].lSizey-1;++j) {
for(int i=1;i<mLevel[lev].lSizex-1;++i) {
// from coarse cells without unused nbs are not necessary...! -> remove
// perform check from coarseAdvance here?
if(RFLAG(lev, i,j,k, mLevel[lev].setCurr) & CFGrFromFine) {
nbsok = true;
if((lev+1 == mMaxRefine) && (RFLAG(lev+1, 2*i,2*j,2*k, mLevel[lev+1].setCurr)&(CFInter))) {
// dont turn CFGrFromFine above interface cells into CFGrNorm
nbsok=false;
}
if(lev+1 == mMaxRefine) {
for(int l=1; l<D::cDirNum && nbsok; l++) {
int ni=(2*i)+D::dfVecX[l], nj=(2*j)+D::dfVecY[l], nk=(2*k)+D::dfVecZ[l];
if(RFLAG(lev+1, ni,nj,nk, mLevel[lev+1].setCurr)&(CFInter)) { // dont coarsen when near interface
nbsok = false;
}
} // l
} else {
for(int l=1; l<D::cDirNum && nbsok; l++) {
int ni=(2*i)+D::dfVecX[l], nj=(2*j)+D::dfVecY[l], nk=(2*k)+D::dfVecZ[l];
if(RFLAG(lev+1, ni,nj,nk, mLevel[lev+1].setCurr)&(CFGrFromFine)) { // dont coarsen when near interface
nbsok = false;
}
} // l
}
// 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];
if(RFLAG(lev, ni,nj,nk, mLevel[lev].setCurr)&(CFFluid)) { //ok
} else {
nbsok = false;
}
} // l
if(nbsok) {
// conversion to coarse fluid cell
change = true;
RFLAG(lev, i,j,k, mLevel[lev].setCurr) = CFFluid|CFGrNorm;
// dfs are already ok...
//if(D::mInitDone) errMsg("performCoarsening","CFGrFromFine changed to CFGrNorm at lev"<<lev<<" " <<PRINT_IJK );
if(D::cDimension==2) debugMarkCell(lev,i,j,k);
// only check complete cubes
for(int dx=-1;dx<=1;dx+=2) {
for(int dy=-1;dy<=1;dy+=2) {
for(int dz=-1*(LBMDIM&1);dz<=1*(LBMDIM&1);dz+=2) { // 2d/3d
// check for norm and from coarse, as the coarse level might just have been refined...
/*if(D::mInitDone) errMsg("performCoarsening","CFGrFromFine subc check "<<
"x"<<convertFlags2String( RFLAG(lev, i+dx, j , k , mLevel[lev].setCurr))<<" "
"y"<<convertFlags2String( RFLAG(lev, i , j+dy, k , mLevel[lev].setCurr))<<" "
"z"<<convertFlags2String( RFLAG(lev, i , j , k+dz, mLevel[lev].setCurr))<<" "
"xy"<<convertFlags2String( RFLAG(lev, i+dx, j+dy, k , mLevel[lev].setCurr))<<" "
"xz"<<convertFlags2String( RFLAG(lev, i+dx, j , k+dz, mLevel[lev].setCurr))<<" "
"yz"<<convertFlags2String( RFLAG(lev, i , j+dy, k+dz, mLevel[lev].setCurr))<<" "
"xyz"<<convertFlags2String( RFLAG(lev, i+dx, j+dy, k+dz, mLevel[lev].setCurr))<<" " ); // */
if(
// we now the flag of the current cell! ( RFLAG(lev, i , j , k , mLevel[lev].setCurr)&(CFGrNorm)) &&
( RFLAG(lev, i+dx, j , k , mLevel[lev].setCurr)&(CFGrNorm|CFGrFromCoarse)) &&
( RFLAG(lev, i , j+dy, k , mLevel[lev].setCurr)&(CFGrNorm|CFGrFromCoarse)) &&
( RFLAG(lev, i , j , k+dz, mLevel[lev].setCurr)&(CFGrNorm|CFGrFromCoarse)) &&
( RFLAG(lev, i+dx, j+dy, k , mLevel[lev].setCurr)&(CFGrNorm|CFGrFromCoarse)) &&
( RFLAG(lev, i+dx, j , k+dz, mLevel[lev].setCurr)&(CFGrNorm|CFGrFromCoarse)) &&
( RFLAG(lev, i , j+dy, k+dz, mLevel[lev].setCurr)&(CFGrNorm|CFGrFromCoarse)) &&
( RFLAG(lev, i+dx, j+dy, k+dz, mLevel[lev].setCurr)&(CFGrNorm|CFGrFromCoarse))
) {
// middle source node on higher level
int dstlev = lev+1;
int dstx = (2*i)+dx;
int dsty = (2*j)+dy;
int dstz = (2*k)+dz;
RFLAG(dstlev, dstx,dsty,dstz, mLevel[dstlev].setCurr) = 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) );
for(int l=1; l<D::cDirNum; l++) {
int dstni=dstx+D::dfVecX[l], dstnj=dsty+D::dfVecY[l], dstnk=dstz+D::dfVecZ[l];
if(RFLAG(dstlev, dstni,dstnj,dstnk, mLevel[dstlev].setCurr)&(CFFluid)) {
RFLAG(dstlev, dstni,dstnj,dstnk, mLevel[dstlev].setCurr) = CFFluid|CFGrFromCoarse;
}
if(RFLAG(dstlev, dstni,dstnj,dstnk, mLevel[dstlev].setCurr)&(CFInter)) {
//if(D::mInitDone) errMsg("performCoarsening","CFGrFromFine subcube init CHECK Warning - deleting interface cell...");
D::mFixMass += QCELL( dstlev, dstni,dstnj,dstnk, mLevel[dstlev].setCurr, dMass);
RFLAG(dstlev, dstni,dstnj,dstnk, mLevel[dstlev].setCurr) = 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];
// have to be at least from coarse here...
//errMsg("performCoarsening","CFGrFromFine subcube init unused check l"<<dstlev<<" at "<<PRINT_VEC(dstni,dstnj,dstnk)<<" "<< convertFlags2String(RFLAG(dstlev, dstni,dstnj,dstnk, mLevel[dstlev].setCurr)) );
if(!(RFLAG(dstlev, dstni,dstnj,dstnk, mLevel[dstlev].setCurr)&(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];
if(RFLAG(dstlev, chkni,chknj,chknk, mLevel[dstlev].setCurr)&(CFUnused|CFGrFromCoarse)) {
// this nb cell is ok for deletion
} else {
delok=false; // keep it!
}
//errMsg("performCoarsening"," CHECK "<<PRINT_VEC(dstni,dstnj,dstnk)<<" to "<<PRINT_VEC( chkni,chknj,chknk )<<" f:"<< convertFlags2String( RFLAG(dstlev, chkni,chknj,chknk, mLevel[dstlev].setCurr))<<" nbsok"<<delok );
}
//errMsg("performCoarsening","CFGrFromFine subcube init unused check l"<<dstlev<<" at "<<PRINT_VEC(dstni,dstnj,dstnk)<<" ok"<<delok );
if(delok) {
RFLAG(dstlev, dstni,dstnj,dstnk, mLevel[dstlev].setCurr) = CFUnused;
RFLAG(dstlev, dstni,dstnj,dstnk, mLevel[dstlev].setOther) = CFUnused; // FLAGTEST
if(D::cDimension==2) 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) );
}
} } }
} // ?
} // convert regions of from fine
// reinit cell area value
/*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];
if(RFLAG(lev+1, ni,nj,nk, mLevel[lev+1].setCurr)&
(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;
totArea += mFsgrCellArea[l];
}
} // l
QCELL(lev, i,j,k,mLevel[lev].setOther, dFlux) =
QCELL(lev, i,j,k,mLevel[lev].setCurr, dFlux) = totArea;
} else {
QCELL(lev, i,j,k,mLevel[lev].setOther, dFlux) =
QCELL(lev, i,j,k,mLevel[lev].setCurr, dFlux) = 1.0;
}
//errMsg("DFINI"," at l"<<lev<<" "<<PRINT_IJK<<" v:"<<QCELL(lev, i,j,k,mLevel[lev].setCurr, dFlux) );
}
// */
if(RFLAG(lev, i,j,k, mLevel[lev].setCurr) & CFEmpty) {
bool changeToFromFine = false;
const CellFlagType notAllowed = (CFInter|CFGrFromCoarse|CFGrFromFine|CFGrToFine);
const CellFlagType notNbAllowed = (CFEmpty|CFGrFromFine|CFInter|CFBnd);
#if REFINEMENTBORDER==1
if( (RFLAG(lev+1, (2*i),(2*j),(2*k), mLevel[lev+1].setCurr) & (CFFluid)) &&
(!(RFLAG(lev+1, (2*i),(2*j),(2*k), mLevel[lev+1].setCurr) & (notAllowed)) ) ){
changeToFromFine=true;
}
#elif REFINEMENTBORDER==2 // REFINEMENTBORDER==1
if( (RFLAG(lev+1, (2*i),(2*j),(2*k), mLevel[lev+1].setCurr) & (CFFluid)) &&
(!(RFLAG(lev+1, (2*i),(2*j),(2*k), mLevel[lev+1].setCurr) & (notAllowed)) ) ){
changeToFromFine=true;
for(int l=0; ((l<D::cDirNum)&&(changeToFromFine)); l++) {
int ni=2*i+D::dfVecX[l], nj=2*j+D::dfVecY[l], nk=2*k+D::dfVecZ[l];
if(RFLAG(lev+1, ni,nj,nk, mLevel[lev+1].setCurr)&(notNbAllowed)) { // NEWREFT
changeToFromFine=false;
}
}
/*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];
if(RFLAG(lev+1, ni,nj,nk, mLevel[lev+1].setCurr)&(notNbAllowed)) { // NEWREFT
changeToFromFine=false;
}
} // FARBORD*/
}
#elif REFINEMENTBORDER==3 // REFINEMENTBORDER==3
if(lev+1==mMaxRefine) { // mixborder
if( (RFLAG(lev+1, (2*i),(2*j),(2*k), mLevel[lev+1].setCurr) & (CFFluid|CFInter)) &&
(!(RFLAG(lev+1, (2*i),(2*j),(2*k), mLevel[lev+1].setCurr) & (notAllowed)) ) ){
changeToFromFine=true;
}
} else {
if( (RFLAG(lev+1, (2*i),(2*j),(2*k), mLevel[lev+1].setCurr) & (CFFluid)) &&
(!(RFLAG(lev+1, (2*i),(2*j),(2*k), mLevel[lev+1].setCurr) & (notAllowed)) ) ){
changeToFromFine=true;
for(int l=0; l<D::cDirNum; l++) {
int ni=2*i+D::dfVecX[l], nj=2*j+D::dfVecY[l], nk=2*k+D::dfVecZ[l];
if(RFLAG(lev+1, ni,nj,nk, mLevel[lev+1].setCurr)&(notNbAllowed)) { // NEWREFT
changeToFromFine=false;
}
}
} } // mixborder
#else // REFINEMENTBORDER==3
ERROR
#endif // REFINEMENTBORDER==1
if(changeToFromFine) {
change = true;
RFLAG(lev, i,j,k, mLevel[lev].setCurr) = CFFluid|CFGrFromFine;
if(D::cDimension==2) debugMarkCell(lev,i,j,k);
// same as restr from fine func! not necessary ?!
// coarseRestrictFromFine part */
}
} // only check empty cells
} } }
if(!D::mSilent){ errMsg("performCoarsening"," for l"<<lev<<" done " ); }
return change;
}
template<class D>
bool
LbmFsgrSolver<D>::performRefinement(int lev) {
@@ -4302,74 +3980,63 @@ LbmFsgrSolver<D>::performRefinement(int lev) {
//bool nbsok;
// TIMEINTORDER ?
LbmFloat interTime = 0.0;
// update curr from other, as streaming afterwards works on curr
// thus read only from srcSet, modify other
const int srcSet = mLevel[lev].setOther;
const int dstSet = mLevel[lev].setCurr;
const int srcFineSet = mLevel[lev+1].setCurr;
const bool debugRefinement = false;
// use template functions for 2D/3D
for(int k= getForZMin1(lev); k< getForZMax1(lev); ++k) {
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) {
// ????
/*if(RFLAG(lev, i,j,k, mLevel[lev].setCurr) & CFGrFromFine) {
// from fine cells without fluid nbs are not necessary...! -> remove
bool fluidNb = false;
for(int l=1; l<D::cDirNum; l++) {
if(RFLAG_NB(lev, i, j, k, mLevel[lev].setCurr, l) & CFFluid) { fluidNb = true; }
}
if(!fluidNb) {
RFLAG(lev, i,j,k, mLevel[lev].setCurr) = CFFluid|CFGrNorm;
}
} // */
// check for "inactive" norm cells (without finer border near)?
if(RFLAG(lev, i,j,k, mLevel[lev].setCurr) & CFGrNorm) {
if(lev+1 == mMaxRefine) {
for(int l=0; l<D::cDirNum; l++) {
int ni=(2*i)+D::dfVecX[l], nj=(2*j)+D::dfVecY[l], nk=(2*k)+D::dfVecZ[l];
if(RFLAG(lev+1, ni,nj,nk, mLevel[lev+1].setCurr)&(CFInter)) { // dont compute
//nbsok = false;
RFLAG(lev, i,j,k, mLevel[lev].setCurr) = CFFluid|CFGrFromFine;
if(D::cDimension==2) debugMarkCell(lev,i,j,k);
l = D::cDirNum;
}
} // l
}
}
if(RFLAG(lev, i,j,k, mLevel[lev].setCurr) & CFGrFromFine) {
// remove from coarse cells in neighborhood !?
//for(int l=0; l<D::cDirNum; l++) {
//}
if(RFLAG(lev, i,j,k, srcSet) & CFGrFromFine) {
bool removeFromFine = false;
const CellFlagType notSrcAllowed = (CFEmpty|CFGrFromFine|CFInter|CFBnd|CFGrToFine);
const CellFlagType notAllowed = (CFInter|CFGrFromFine|CFGrToFine);
CellFlagType reqType = CFGrNorm;
if(lev+1==mMaxRefine) reqType = CFNoBndFluid;
#if REFINEMENTBORDER==1
if(RFLAG(lev+1, 2*i,2*j,2*k, mLevel[lev+1].setCurr)&notSrcAllowed) {
if( (RFLAG(lev+1, (2*i),(2*j),(2*k), srcFineSet) & reqType) &&
(!(RFLAG(lev+1, (2*i),(2*j),(2*k), srcFineSet) & (notAllowed)) ) ){ // ok
} else {
removeFromFine=true;
}
/*if(strstr(D::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];
if(RFLAG(lev+1, ni,nj,nk, srcFineSet)&CFBnd) { // NEWREFT
removeFromFine=true;
}
}
} // FARBORD */
#elif REFINEMENTBORDER==2 // REFINEMENTBORDER==1
FIX
for(int l=0;((l<D::cDirNum) && (!removeFromFine)); l++) {
int ni=2*i+D::dfVecX[l], nj=2*j+D::dfVecY[l], nk=2*k+D::dfVecZ[l];
if(RFLAG(lev+1, ni,nj,nk, mLevel[lev+1].setCurr)&notSrcAllowed) { // NEWREFT
if(RFLAG(lev+1, ni,nj,nk, srcFineSet)&notSrcAllowed) { // NEWREFT
removeFromFine=true;
}
}
/*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];
if(RFLAG(lev+1, ni,nj,nk, mLevel[lev+1].setCurr)&notSrcAllowed) { // NEWREFT
if(RFLAG(lev+1, ni,nj,nk, srcFineSet)&notSrcAllowed) { // NEWREFT
removeFromFine=true;
}
} // FARBORD */
#elif REFINEMENTBORDER==3 // REFINEMENTBORDER==1
FIX
if(lev+1==mMaxRefine) { // mixborder
if(RFLAG(lev+1, 2*i,2*j,2*k, mLevel[lev+1].setCurr)&notSrcAllowed) {
if(RFLAG(lev+1, 2*i,2*j,2*k, srcFineSet)&notSrcAllowed) {
removeFromFine=true;
}
} else { // mixborder
for(int l=0; l<D::cDirNum; l++) {
int ni=2*i+D::dfVecX[l], nj=2*j+D::dfVecY[l], nk=2*k+D::dfVecZ[l];
if(RFLAG(lev+1, ni,nj,nk, mLevel[lev+1].setCurr)&notSrcAllowed) { // NEWREFT
if(RFLAG(lev+1, ni,nj,nk, srcFineSet)&notSrcAllowed) { // NEWREFT
removeFromFine=true;
}
}
@@ -4381,54 +4048,159 @@ LbmFsgrSolver<D>::performRefinement(int lev) {
if(removeFromFine) {
// dont turn CFGrFromFine above interface cells into CFGrNorm
//errMsg("performRefinement","Removing CFGrFromFine on lev"<<lev<<" " <<PRINT_IJK );
RFLAG(lev, i,j,k, mLevel[lev].setCurr) = CFEmpty;
RFLAG(lev, i,j,k, mLevel[lev].setOther) = CFEmpty; // FLAGTEST
if(D::cDimension==2) debugMarkCell(lev,i,j,k);
//errMsg("performRefinement","Removing CFGrFromFine on lev"<<lev<<" " <<PRINT_IJK<<" srcflag:"<<convertCellFlagType2String(RFLAG(lev+1, (2*i),(2*j),(2*k), srcFineSet)) <<" set:"<<dstSet );
RFLAG(lev, i,j,k, dstSet) = CFEmpty;
#if FSGR_STRICT_DEBUG==1
// for interpolation later on during fine grid fixing
// these cells are still correctly inited
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);
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];
if(RFLAG(lev, ni,nj,nk, mLevel[lev].setCurr)&(CFFluid)) { //ok
RFLAG(lev, ni,nj,nk, mLevel[lev].setCurr) = CFFluid|CFGrFromFine;
if(D::cDimension==2) debugMarkCell(lev,ni,nj,nk);
//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);
}
} // l
// FIXME fix fine level?
}
// recheck from fine flag
}
}}} // TEST
if(RFLAG(lev, i,j,k, mLevel[lev].setCurr) & CFGrFromFine) {
if((RFLAG(lev+1, 2*i,2*j,2*k, mLevel[lev+1].setCurr)&(CFGrFromCoarse))) {
for(int k= getForZMin1(); k< getForZMax1(lev); ++k) { // TEST
for(int j=1;j<mLevel[lev].lSizey-1;++j) { // TEST
for(int i=1;i<mLevel[lev].lSizex-1;++i) { // TEST
// test from coarseAdvance
// from coarse cells without unused nbs are not necessary...! -> remove
/*if( ((*pFlagSrc) & (CFGrFromCoarse)) ) {
bool invNb = false;
FORDF1 {
if(RFLAG_NB(lev, i, j, k, SRCS(lev), l) & CFUnused) { invNb = true; }
}
if(!invNb) {
*pFlagSrc = CFFluid|CFGrNorm;
errMsg("coarseAdvance","FC2NRM_CHECK Converted CFGrFromCoarse to Norm at "<<lev<<" "<<PRINT_IJK);
}
} // */
if(RFLAG(lev, i,j,k, srcSet) & CFGrFromCoarse) {
// from coarse cells without unused nbs are not necessary...! -> remove
bool invNb = false;
bool fluidNb = false;
for(int l=1; l<D::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);
change=true;
mNumFsgrChanges++;
} // from advance */
if(!fluidNb) {
// 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);
change=true;
mNumFsgrChanges++;
} // from advance */
// dont allow double transfer
// this might require fixing the neighborhood
if(RFLAG(lev+1, 2*i,2*j,2*k, srcFineSet)&(CFGrFromCoarse)) {
// dont turn CFGrFromFine above interface cells into CFGrNorm
//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);
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];
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];
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);
}
}
// these alreay have valid values...
}
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 /*mLevel[lev].setCurr*/, interTime, CFFluid|CFGrFromCoarse, false);
if((D::cDimension==2)&&(debugRefinement)) debugMarkCell(lev,ni,nj,nk);
mNumFsgrChanges++;
}
} // l
} // double transer
} // from coarse
} } }
// fix dstSet from fine cells here
// warning - checks CFGrFromFine on dstset changed before!
for(int k= getForZMin1(); k< getForZMax1(lev); ++k) { // TEST
for(int j=1;j<mLevel[lev].lSizey-1;++j) { // TEST
for(int i=1;i<mLevel[lev].lSizex-1;++i) { // TEST
//if(RFLAG(lev, i,j,k, srcSet) & CFGrFromFine) {
if(RFLAG(lev, i,j,k, dstSet) & CFGrFromFine) {
// modify finer level border
if((RFLAG(lev+1, 2*i,2*j,2*k, srcFineSet)&(CFGrFromCoarse))) {
//errMsg("performRefinement","Removing CFGrFromCoarse on lev"<<(lev+1)<<" from l"<<lev<<" " <<PRINT_IJK );
CellFlagType setf = CFFluid;
if(lev+1 < mMaxRefine) setf = CFFluid|CFGrNorm;
RFLAG(lev+1, 2*i,2*j,2*k, mLevel[lev+1].setCurr)=setf;
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];
if(RFLAG(lev+1, bi, bj, bk, mLevel[lev+1].setCurr)&(CFGrFromCoarse)) {
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, mLevel[lev+1].setCurr) = setf;
if(D::cDimension==2) debugMarkCell(lev+1,bi,bj,bk);
RFLAG(lev+1, bi, bj, bk, srcFineSet) = setf;
if((D::cDimension==2)&&(debugRefinement)) debugMarkCell(lev+1,bi,bj,bk);
}
else if(RFLAG(lev+1, bi, bj, bk, mLevel[lev+1].setCurr)&(CFUnused )) {
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, mLevel[lev+1].setCurr, interTime, setf, false);
if(D::cDimension==2) debugMarkCell(lev+1,bi,bj,bk);
interpolateCellFromCoarse(lev+1, bi, bj, bk, srcFineSet, interTime, setf, false);
if((D::cDimension==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];
if( (RFLAG(lev+1, bi, bj, bk, mLevel[lev+1].setCurr)&CFFluid ) &&
(!(RFLAG(lev+1, bi, bj, bk, mLevel[lev+1].setCurr)&CFGrFromCoarse)) ) {
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];
if(RFLAG(lev+1, mi, mj, mk, mLevel[lev+1].setCurr)&CFUnused) {
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, mLevel[lev+1].setCurr, interTime, CFFluid|CFGrFromCoarse, false);
if(D::cDimension==2) debugMarkCell(lev+1,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);
mNumFsgrChanges++;
}
}
// nbs prepared...
@@ -4437,66 +4209,265 @@ LbmFsgrSolver<D>::performRefinement(int lev) {
}
} // convert regions of from fine
if(RFLAG(lev, i,j,k, mLevel[lev].setCurr) & CFGrFromCoarse) {
// from coarse cells without unused nbs are not necessary...! -> remove
bool invNb = false;
bool fluidNb = false;
for(int l=1; l<D::cDirNum; l++) {
if(RFLAG_NB(lev, i, j, k, mLevel[lev].setCurr, l) & CFUnused) { invNb = true; }
if(RFLAG_NB(lev, i, j, k, mLevel[lev].setCurr, l) & (CFGrNorm)) { fluidNb = true; }
}
if(!invNb) {
RFLAG(lev, i,j,k, mLevel[lev].setCurr) = CFFluid|CFGrNorm;
if(D::cDimension==2) debugMarkCell(lev, i, j, k);
change=true;
} // from advance */
if(!fluidNb) {
RFLAG(lev, i,j,k, mLevel[lev].setCurr) = CFUnused;
RFLAG(lev, i,j,k, mLevel[lev].setOther) = CFUnused; // FLAGTEST
if(D::cDimension==2) debugMarkCell(lev, i, j, k);
change=true;
} // from advance */
// dont allow double transfer
if(RFLAG(lev+1, 2*i,2*j,2*k, mLevel[lev+1].setCurr)&(CFGrFromCoarse)) {
// dont turn CFGrFromFine above interface cells into CFGrNorm
//errMsg("performRefinement","Removing CFGrFromCoarse on lev"<<lev<<" " <<PRINT_IJK<<" due to finer from coarse cell " );
RFLAG(lev, i,j,k, mLevel[lev].setCurr) = CFFluid|CFGrNorm;
if(D::cDimension==2) debugMarkCell(lev, i, j, k);
change=true;
for(int l=1; l<D::cDirNum; l++) {
int ni=i+D::dfVecX[l], nj=j+D::dfVecY[l], nk=k+D::dfVecZ[l];
if(RFLAG(lev, ni,nj,nk, mLevel[lev].setCurr)&(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];
if(RFLAG(lev, mi, mj, mk, mLevel[lev].setCurr)&CFUnused) {
// norm cells in neighborhood with unused nbs have to be new border...
RFLAG(lev, ni,nj,nk, mLevel[lev].setCurr) = CFFluid|CFGrFromCoarse;
if(D::cDimension==2) debugMarkCell(lev,ni,nj,nk);
}
}
// these alreay have valid values...
}
else if(RFLAG(lev, ni,nj,nk, mLevel[lev].setCurr)&(CFUnused)) { //ok
//RFLAG(lev, ni,nj,nk, mLevel[lev].setCurr) = CFFluid|CFGrFromFine;
// is this guaranteed to always work?
interpolateCellFromCoarse(lev, ni, nj, nk, mLevel[lev].setCurr, interTime, CFFluid|CFGrFromCoarse, false);
if(D::cDimension==2) debugMarkCell(lev,ni,nj,nk);
}
} // l
}
} // from coarse
} } }
}}} // TEST
if(!D::mSilent){ errMsg("performRefinement"," for l"<<lev<<" done ("<<change<<") " ); }
return change;
}
// done after refinement
template<class D>
bool
LbmFsgrSolver<D>::performCoarsening(int lev) {
//if(D::mInitDone){ errMsg("performCoarsening","skip"); return 0;} // DEBUG
if((lev<0) || ((lev+1)>mMaxRefine)) return false;
bool change = false;
bool nbsok;
// hence work on modified curr set
const int srcSet = mLevel[lev].setCurr;
const int dstlev = lev+1;
const int dstFineSet = mLevel[dstlev].setCurr;
const bool debugCoarsening = false;
// use template functions for 2D/3D
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) {
// from coarse cells without unused nbs are not necessary...! -> remove
// perform check from coarseAdvance here?
if(RFLAG(lev, i,j,k, srcSet) & CFGrFromFine) {
// remove from fine cells now that are completely in fluid
// FIXME? check that new from fine in performRefinement never get deleted here afterwards?
// or more general, one cell never changed more than once?
const CellFlagType notAllowed = (CFInter|CFGrFromFine|CFGrToFine);
//const CellFlagType notNbAllowed = (CFInter|CFBnd|CFGrFromFine); unused
CellFlagType reqType = CFGrNorm;
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];
if( (RFLAG(lev+1, ni,nj,nk, dstFineSet) & reqType) &&
(!(RFLAG(lev+1, ni,nj,nk, dstFineSet) & (notAllowed)) ) ){
// ok
} else {
nbsok=false;
}
/*if(strstr(D::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];
if(RFLAG(lev+1, ni,nj,nk, dstFineSet)&CFBnd) { // NEWREFT
nbsok=false;
}
}
} // FARBORD */
}
// 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];
if(RFLAG(lev, ni,nj,nk, srcSet)&(CFFluid)) { //ok
} else {
nbsok = false;
}
} // l
if(nbsok) {
// conversion to coarse fluid cell
change = true;
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);
// only check complete cubes
for(int dx=-1;dx<=1;dx+=2) {
for(int dy=-1;dy<=1;dy+=2) {
for(int dz=-1*(LBMDIM&1);dz<=1*(LBMDIM&1);dz+=2) { // 2d/3d
// check for norm and from coarse, as the coarse level might just have been refined...
/*if(D::mInitDone) errMsg("performCoarsening","CFGrFromFine subc check "<< "x"<<convertCellFlagType2String( RFLAG(lev, i+dx, j , k , srcSet))<<" "
"y"<<convertCellFlagType2String( RFLAG(lev, i , j+dy, k , srcSet))<<" " "z"<<convertCellFlagType2String( RFLAG(lev, i , j , k+dz, srcSet))<<" "
"xy"<<convertCellFlagType2String( RFLAG(lev, i+dx, j+dy, k , srcSet))<<" " "xz"<<convertCellFlagType2String( RFLAG(lev, i+dx, j , k+dz, srcSet))<<" "
"yz"<<convertCellFlagType2String( RFLAG(lev, i , j+dy, k+dz, srcSet))<<" " "xyz"<<convertCellFlagType2String( RFLAG(lev, i+dx, j+dy, k+dz, srcSet))<<" " ); // */
if(
// we now the flag of the current cell! ( RFLAG(lev, i , j , k , srcSet)&(CFGrNorm)) &&
( RFLAG(lev, i+dx, j , k , srcSet)&(CFGrNorm|CFGrFromCoarse)) &&
( RFLAG(lev, i , j+dy, k , srcSet)&(CFGrNorm|CFGrFromCoarse)) &&
( RFLAG(lev, i , j , k+dz, srcSet)&(CFGrNorm|CFGrFromCoarse)) &&
( RFLAG(lev, i+dx, j+dy, k , srcSet)&(CFGrNorm|CFGrFromCoarse)) &&
( RFLAG(lev, i+dx, j , k+dz, srcSet)&(CFGrNorm|CFGrFromCoarse)) &&
( RFLAG(lev, i , j+dy, k+dz, srcSet)&(CFGrNorm|CFGrFromCoarse)) &&
( RFLAG(lev, i+dx, j+dy, k+dz, srcSet)&(CFGrNorm|CFGrFromCoarse))
) {
// middle source node on higher level
int dstx = (2*i)+dx;
int dsty = (2*j)+dy;
int dstz = (2*k)+dz;
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) );
for(int l=1; l<D::cDirNum; l++) {
int dstni=dstx+D::dfVecX[l], dstnj=dsty+D::dfVecY[l], dstnk=dstz+D::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);
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];
// 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];
if(RFLAG(dstlev, chkni,chknj,chknk, dstFineSet)&(CFUnused|CFGrFromCoarse)) {
// this nb cell is ok for deletion
} else {
delok=false; // keep it!
}
//errMsg("performCoarsening"," CHECK "<<PRINT_VEC(dstni,dstnj,dstnk)<<" to "<<PRINT_VEC( chkni,chknj,chknk )<<" f:"<< convertCellFlagType2String( RFLAG(dstlev, chkni,chknj,chknk, dstFineSet))<<" nbsok"<<delok );
}
//errMsg("performCoarsening","CFGrFromFine subcube init unused check l"<<dstlev<<" at "<<PRINT_VEC(dstni,dstnj,dstnk)<<" ok"<<delok );
if(delok) {
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);
}
}
} // 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) );
}
} } }
} // ?
} // convert regions of from fine
}}} // TEST!
// reinit cell area value
/*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];
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;
totArea += mFsgrCellArea[l];
}
} // l
QCELL(lev, i,j,k,mLevel[lev].setOther, dFlux) =
QCELL(lev, i,j,k,srcSet, dFlux) = totArea;
} else {
QCELL(lev, i,j,k,mLevel[lev].setOther, dFlux) =
QCELL(lev, i,j,k,srcSet, dFlux) = 1.0;
}
//errMsg("DFINI"," at l"<<lev<<" "<<PRINT_IJK<<" v:"<<QCELL(lev, i,j,k,srcSet, dFlux) );
}
// */
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) {
if(RFLAG(lev, i,j,k, srcSet) & CFEmpty) {
// check empty -> from fine conversion
bool changeToFromFine = false;
const CellFlagType notAllowed = (CFInter|CFGrFromFine|CFGrToFine);
CellFlagType reqType = CFGrNorm;
if(lev+1==mMaxRefine) reqType = CFNoBndFluid;
#if REFINEMENTBORDER==1
if( (RFLAG(lev+1, (2*i),(2*j),(2*k), dstFineSet) & reqType) &&
(!(RFLAG(lev+1, (2*i),(2*j),(2*k), dstFineSet) & (notAllowed)) ) ){
changeToFromFine=true;
}
/*if(strstr(D::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];
if(RFLAG(lev+1, ni,nj,nk, dstFineSet)&CFBnd) { // NEWREFT
changeToFromFine=false;
}
}
}// FARBORD */
#elif REFINEMENTBORDER==2 // REFINEMENTBORDER==1
if( (RFLAG(lev+1, (2*i),(2*j),(2*k), dstFineSet) & reqType) &&
(!(RFLAG(lev+1, (2*i),(2*j),(2*k), dstFineSet) & (notAllowed)) ) ){
changeToFromFine=true;
for(int l=0; ((l<D::cDirNum)&&(changeToFromFine)); l++) {
int ni=2*i+D::dfVecX[l], nj=2*j+D::dfVecY[l], nk=2*k+D::dfVecZ[l];
if(RFLAG(lev+1, ni,nj,nk, dstFineSet)&(notNbAllowed)) { // NEWREFT
changeToFromFine=false;
}
}
/*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];
if(RFLAG(lev+1, ni,nj,nk, dstFineSet)&(notNbAllowed)) { // NEWREFT
changeToFromFine=false;
}
} // FARBORD*/
}
#elif REFINEMENTBORDER==3 // REFINEMENTBORDER==3
FIX!!!
if(lev+1==mMaxRefine) { // mixborder
if( (RFLAG(lev+1, (2*i),(2*j),(2*k), dstFineSet) & (CFFluid|CFInter)) &&
(!(RFLAG(lev+1, (2*i),(2*j),(2*k), dstFineSet) & (notAllowed)) ) ){
changeToFromFine=true;
}
} else {
if( (RFLAG(lev+1, (2*i),(2*j),(2*k), dstFineSet) & (CFFluid)) &&
(!(RFLAG(lev+1, (2*i),(2*j),(2*k), dstFineSet) & (notAllowed)) ) ){
changeToFromFine=true;
for(int l=0; l<D::cDirNum; l++) {
int ni=2*i+D::dfVecX[l], nj=2*j+D::dfVecY[l], nk=2*k+D::dfVecZ[l];
if(RFLAG(lev+1, ni,nj,nk, dstFineSet)&(notNbAllowed)) { // NEWREFT
changeToFromFine=false;
}
}
} } // mixborder
#else // REFINEMENTBORDER==3
ERROR
#endif // REFINEMENTBORDER==1
if(changeToFromFine) {
change = true;
mNumFsgrChanges++;
RFLAG(lev, i,j,k, srcSet) = CFFluid|CFGrFromFine;
if((D::cDimension==2)&&(debugCoarsening)) debugMarkCell(lev,i,j,k);
// same as restr from fine func! not necessary ?!
// coarseRestrictFromFine part */
}
} // only check empty cells
}}} // TEST!
if(!D::mSilent){ errMsg("performCoarsening"," for l"<<lev<<" done " ); }
return change;
}
/*****************************************************************************/
/*! perform a single LBM step */
@@ -4556,7 +4527,7 @@ LbmFsgrSolver<D>::adaptTimestep()
if((newdt>levOldStepsize[mMaxRefine])&&(mTimestepReduceLock)) {
// wait some more...
//debMsgNnl("LbmFsgrSolver::TAdp",DM_NOTIFY," Delayed... "<<mTimestepReduceLock<<" ",10);
//debMsgDirect("D");
debMsgDirect("D");
} else {
D::mpParam->setDesiredStepTime( newdt );
rescale = true;
@@ -4571,17 +4542,20 @@ LbmFsgrSolver<D>::adaptTimestep()
if(mTimestepReduceLock>0) mTimestepReduceLock--;
/*
// forced back and forth switchting (for testing)
const int tadtogInter = 40;
const int tadtogInter = 300;
const double tadtogSwitch = 0.66;
errMsg("TIMESWITCHTOGGLETEST","warning enabled "<< tadtogSwitch<<","<<tadtogSwitch<<" !!!!!!!!!!!!!!!!!!!");
if((D::mStepCnt% tadtogInter)== tadtogInter/2-1) {
if( ((D::mStepCnt% tadtogInter)== (tadtogInter/4*1)-1) ||
((D::mStepCnt% tadtogInter)== (tadtogInter/4*2)-1) ){
rescale = true; minCutoff = false;
newdt = tadtogSwitch * D::mpParam->getStepTime();
D::mpParam->setDesiredStepTime( newdt );
} else
if((D::mStepCnt% tadtogInter)== tadtogInter-1) {
if( ((D::mStepCnt% tadtogInter)== (tadtogInter/4*3)-1) ||
((D::mStepCnt% tadtogInter)== (tadtogInter/4*4)-1) ){
rescale = true; minCutoff = false;
newdt = D::mpParam->getStepTime()/tadtogSwitch ;
D::mpParam->setDesiredStepTime( newdt );
@@ -4599,6 +4573,7 @@ LbmFsgrSolver<D>::adaptTimestep()
mTimeSwitchCounts++;
D::mpParam->calculateAllMissingValues( D::mSilent );
recalculateObjectSpeeds();
// calc omega, force for all levels
initLevelOmegas();
if(D::mpParam->getStepTime()<mMinStepTime) mMinStepTime = D::mpParam->getStepTime();
@@ -4606,12 +4581,11 @@ LbmFsgrSolver<D>::adaptTimestep()
for(int lev=mMaxRefine; lev>=0 ; lev--) {
LbmFloat newSteptime = mLevel[lev].stepsize;
LbmFloat newOmega = mLevel[lev].omega;
LbmFloat dfScaleFac = (newSteptime/1.0)/(levOldStepsize[lev]/levOldOmega[lev]);
if(!D::mSilent) {
debMsgStd("LbmFsgrSolver::TAdp",DM_NOTIFY,"Level: "<<lev<<" Timestep change: "<<
" scaleFac="<<dfScaleFac<<" newDt="<<newSteptime<<" newOmega="<<newOmega,10);
" scaleFac="<<dfScaleFac<<" newDt="<<newSteptime<<" newOmega="<<mLevel[lev].omega,10);
}
if(lev!=mMaxRefine) coarseCalculateFluxareas(lev);
@@ -4764,7 +4738,7 @@ LbmFsgrSolver<D>::adaptTimestep()
}
#ifndef WIN32
if (!finite(rho)) {
//errMsg("adaptTimestep","Brute force non-finite rho at"<<PRINT_IJK); // DEBUG!
errMsg("adaptTimestep","Brute force non-finite rho at"<<PRINT_IJK); // DEBUG!
rho = 1.0;
ux = uy = uz = 0.0;
QCELL(lev, i, j, k, workSet, dMass) = 1.0;
@@ -4780,7 +4754,7 @@ LbmFsgrSolver<D>::adaptTimestep()
for(int l=0; l<D::cDfNum; l++) {
QCELL(lev, i, j, k, workSet, l) = D::getCollideEq(l, rho, ux,uy,uz); }
rescs++;
//debMsgDirect("B");
debMsgDirect("B");
}
} }
@@ -4834,7 +4808,7 @@ LbmFsgrSolver<D>::getMassdWeight(bool dirForw, int i,int j,int k,int workSet, in
if(scal>-LBM_EPSILON) ret = 0.0;
else ret = scal * -1.0;
}
//errMsg("massd", PRINT_IJK<<" nv"<<nvel<<" : ret="<<ret ); //exit(1); //VECDEB
//errMsg("massd", PRINT_IJK<<" nv"<<nvel<<" : ret="<<ret ); //xit(1); //VECDEB
return ret;
}
@@ -4892,7 +4866,9 @@ void LbmFsgrSolver<D>::addToNewInterList( int ni, int nj, int nk ) {
#define ADD_INT_FLAGCHECK(alev, ai,aj,ak, at, afac) \
if( (((1.0-(at))>0.0) && (!(RFLAG((alev), (ai),(aj),(ak),mLevel[(alev)].setCurr )&(CFInter|CFFluid|CFGrCoarseInited) ))) || \
((( (at))>0.0) && (!(RFLAG((alev), (ai),(aj),(ak),mLevel[(alev)].setOther)&(CFInter|CFFluid|CFGrCoarseInited) ))) ){ \
errMsg("INVFLAGCINTCHECK", " l"<<(alev)<<" "<<PRINT_VEC((ai),(aj),(ak))<<" fc:"<<RFLAG((alev), (ai),(aj),(ak),mLevel[(alev)].setCurr ) <<"="<<convertFlags2String(RFLAG((alev), (ai),(aj),(ak),mLevel[(alev)].setCurr ))<<" fold:"<<RFLAG((alev), (ai),(aj),(ak),mLevel[(alev)].setOther ) ); \
errMsg("INVFLAGCINTCHECK", " l"<<(alev)<<" at:"<<(at)<<" "<<PRINT_VEC((ai),(aj),(ak))<<\
" 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; \
}
@@ -4928,7 +4904,7 @@ void LbmFsgrSolver<D>::addToNewInterList( int ni, int nj, int nk ) {
#if FSGR_STRICT_DEBUG==1
#define INTDEBOUT \
{ LbmFloat rho,ux,uy,uz; \
{ /*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); \
@@ -4937,13 +4913,13 @@ void LbmFsgrSolver<D>::addToNewInterList( int ni, int nj, int nk ) {
} \
/*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(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) ); \
/*errMsg("interpolateCellFromCoarse", "ICFC_DFDEBUG cell "<<PRINT_IJK<<" rho:"<<rho<<" u:"<<PRINT_VEC(ux,uy,uz)<<" b"<<PRINT_VEC(betx,bety,betz) ); */\
} \
/* both cases are ok to interpolate */ \
if( (!(RFLAG(lev,i,j,k, dstSet) & CFGrFromCoarse)) && \
(!(RFLAG(lev,i,j,k, dstSet) & CFUnused)) ) { \
/* 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:"<<convertFlags2String( RFLAG(lev,i,j,k, dstSet) )); \
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;*/ \
} \
@@ -5145,8 +5121,8 @@ void LbmFsgrSolver<D>::addToNewInterList( int ni, int nj, int nk ) {
template<class D>
void LbmFsgrSolver<D>::interpolateCellFromCoarse(int lev, int i, int j,int k, int dstSet, LbmFloat t, CellFlagType flagSet, bool markNbs) {
//errMsg("INV DEBUG REINIT! off!",""); exit(1); // DEBUG exit
//if(markNbs) errMsg("interpolateCellFromCoarse"," l"<<lev<<" "<<PRINT_VEC(i,j,k)<<" s"<<dstSet<<" t"<<t); //exit(1); // DEBUG exit
//errMsg("INV DEBUG REINIT! off!",""); xit(1); // DEBUG quit
//if(markNbs) errMsg("interpolateCellFromCoarse"," l"<<lev<<" "<<PRINT_VEC(i,j,k)<<" s"<<dstSet<<" t"<<t); //xit(1); // DEBUG quit
LbmFloat rho=0.0, ux=0.0, uy=0.0, uz=0.0;
//LbmFloat intDf[LBM_DFNUM];
@@ -5423,8 +5399,8 @@ void LbmFsgrSolver<D>::interpolateCellFromCoarse(int lev, int i, int j,int k, in
return;
}
errMsg("interpolateCellFromCoarse","Invalid!?");
exit(1);
D::mPanic=1;
errFatal("interpolateCellFromCoarse","Invalid!?", SIMWORLD_GENERICERROR);
}
template<class D>
@@ -5474,7 +5450,7 @@ void LbmFsgrSolver<D>::reinitFlags( int workSet )
LbmFloat avgux = 0.0, avguy = 0.0, avguz = 0.0;
LbmFloat cellcnt = 0.0;
LbmFloat avgnbdf[LBM_DFNUM];
FORDF0 { avgnbdf[l]= 0.0; }
FORDF0M { avgnbdf[m]= 0.0; }
for(int nbl=1; nbl< D::cDfNum ; ++nbl) {
if( (RFLAG_NB(workLev,ei,ej,ek,workSet,nbl) & CFFluid) ||
@@ -5499,38 +5475,41 @@ void LbmFsgrSolver<D>::reinitFlags( int workSet )
avgux = avguy = avguz = 0.0;
//TTT mNumProblems++;
#if ELBEEM_BLENDER!=1
errMsg("NYI2",""); exit(1);
D::mPanic=1; errFatal("NYI2","cellcnt<=0.0",SIMWORLD_GENERICERROR);
#endif // ELBEEM_BLENDER
} else {
// init speed
avgux /= cellcnt; avguy /= cellcnt; avguz /= cellcnt;
avgrho /= cellcnt;
FORDF0 { avgnbdf[l] /= cellcnt; } // CHECK FIXME test?
FORDF0M { avgnbdf[m] /= cellcnt; } // CHECK FIXME test?
}
// careful with l's...
FORDF0 {
QCELL(workLev,ei,ej,ek, workSet, l) = D::getCollideEq( l,avgrho, avgux, avguy, avguz );
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);
//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<<") " );
}
}
/* prevent surrounding interface cells from getting removed as empty cells
* (also cells that are not newly inited) */
if( RFLAG(workLev,ni,nj,nk, workSet) & CFInter) {
RFLAG(workLev,ni,nj,nk, workSet) = (CellFlagType)(RFLAG(workLev,ni,nj,nk, workSet) | CFNoDelete);
//RFLAG(workLev,ni,nj,nk, workSet) = (CellFlagType)(RFLAG(workLev,ni,nj,nk, workSet) | CFNoDelete);
changeFlag(workLev,ni,nj,nk, workSet, (RFLAG(workLev,ni,nj,nk, workSet) | CFNoDelete));
// also add to list...
addToNewInterList(ni,nj,nk);
} // NEW?
}
// NEW? no extra loop...
RFLAG(workLev,i,j,k, workSet) = CFFluid;
//RFLAG(workLev,i,j,k, workSet) = CFFluid;
changeFlag(workLev,i,j,k, workSet,CFFluid);
}
/* remove empty interface cells that are not allowed to be removed anyway
@@ -5563,7 +5542,8 @@ void LbmFsgrSolver<D>::reinitFlags( int workSet )
int ni=i+D::dfVecX[l], nj=j+D::dfVecY[l], nk=k+D::dfVecZ[l];
if( RFLAG(workLev,ni,nj,nk, workSet) & CFFluid){
// init fluid->interface
RFLAG(workLev,ni,nj,nk, workSet) = (CellFlagType)(CFInter);
//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); }
@@ -5580,14 +5560,14 @@ void LbmFsgrSolver<D>::reinitFlags( int workSet )
}
/* for symmetry, set our flag right now */
RFLAG(workLev,i,j,k, workSet) = CFEmpty;
//RFLAG(workLev,i,j,k, workSet) = CFEmpty;
changeFlag(workLev,i,j,k, workSet, CFEmpty);
// mark cell not be changed mass... - not necessary, not in list anymore anyway!
} // emptylist
/* precompute weights! */
//vector<LbmFloat[dTotalNum]> vWeights;
// precompute weights to get rid of order dependancies
vector<lbmFloatSet> vWeights;
vWeights.reserve( mListFull.size() + mListEmpty.size() );
int weightIndex = 0;
@@ -5597,9 +5577,6 @@ void LbmFsgrSolver<D>::reinitFlags( int workSet )
for( vector<LbmPoint>::iterator iter=mListFull.begin();
iter != mListFull.end(); iter++ ) {
int i=iter->x, j=iter->y, k=iter->z;
//int nbCount = 0;
//LbmFloat nbWeights[LBM_DFNUM];
//LbmFloat nbTotWeights = 0.0;
nbCount = 0; nbTotWeights = 0.0;
FORDF1 {
int ni=i+D::dfVecX[l], nj=j+D::dfVecY[l], nk=k+D::dfVecZ[l];
@@ -5615,8 +5592,11 @@ void LbmFsgrSolver<D>::reinitFlags( int workSet )
//errMsg("FF I", PRINT_IJK<<" "<<weightIndex<<" "<<nbTotWeights);
vWeights[weightIndex].val[0] = nbTotWeights;
FORDF1 { vWeights[weightIndex].val[l] = nbWeights[l]; }
weightIndex++;
} else { }
vWeights[weightIndex].numNbs = (LbmFloat)nbCount;
} else {
vWeights[weightIndex].numNbs = 0.0;
}
weightIndex++;
}
for( vector<LbmPoint>::iterator iter=mListEmpty.begin();
iter != mListEmpty.end(); iter++ ) {
@@ -5636,8 +5616,11 @@ void LbmFsgrSolver<D>::reinitFlags( int workSet )
//errMsg("EE I", PRINT_IJK<<" "<<weightIndex<<" "<<nbTotWeights);
vWeights[weightIndex].val[0] = nbTotWeights;
FORDF1 { vWeights[weightIndex].val[l] = nbWeights[l]; }
weightIndex++;
} else { }
vWeights[weightIndex].numNbs = (LbmFloat)nbCount;
} else {
vWeights[weightIndex].numNbs = 0.0;
}
weightIndex++;
}
weightIndex = 0;
@@ -5651,47 +5634,42 @@ void LbmFsgrSolver<D>::reinitFlags( int workSet )
FORDF1 { myrho += QCELL(workLev,i,j,k, workSet, l); } // QCELL.rho
LbmFloat massChange = QCELL(workLev,i,j,k, workSet, dMass) - myrho;
int nbCount = 0;
/*int nbCount = 0;
LbmFloat nbWeights[LBM_DFNUM];
LbmFloat nbTotWeights = 0.0;
FORDF1 {
int ni=i+D::dfVecX[l], nj=j+D::dfVecY[l], nk=k+D::dfVecZ[l];
if( RFLAG(workLev,ni,nj,nk, workSet) & CFInter) {
nbCount++;
nbWeights[l] = vWeights[weightIndex].val[l];
//nbWeights[l] = getMassdWeight(1,i,j,k,workSet,l);
//nbTotWeights += nbWeights[l];
} else {
//nbWeights[l] = -100.0; // DEBUG;
}
}
}*/
//errMsg("FDIST", PRINT_IJK<<" mss"<<massChange <<" nb"<< nbCount ); // DEBUG SYMM
if(nbCount>0) {
nbTotWeights = vWeights[weightIndex].val[0];
//errMsg("FF I", PRINT_IJK<<" "<<weightIndex<<" "<<nbTotWeights);
//if(vWeights[weightIndex].val[0] != nbTotWeights) { errMsg("WD","WD"<<vWeights[weightIndex].val[0]<<" "<<nbTotWeights); }
if(vWeights[weightIndex].numNbs>0.0) {
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];
if( RFLAG(workLev,ni,nj,nk, workSet) & CFInter) {
LbmFloat change = -1.0;
if(nbTotWeights>0.0) {
//if(nbWeights[l] != vWeights[weightIndex].val[l]) { errMsg("WD","WD"<<nbWeights[l]<<" "<<vWeights[weightIndex].val[l]); } // DEBUG
change = massChange * ( nbWeights[l]/nbTotWeights );
if(nbTotWeightsp>0.0) {
//change = massChange * ( nbWeights[l]/nbTotWeightsp );
change = massChange * ( vWeights[weightIndex].val[l]/nbTotWeightsp );
} else {
change = (LbmFloat)(massChange/(LbmFloat)nbCount);
change = (LbmFloat)(massChange/vWeights[weightIndex].numNbs);
}
QCELL(workLev,ni,nj,nk, workSet, dMass) += change;
}
}
massChange = 0.0;
weightIndex++;
} else {
// Problem! no interface neighbors
D::mFixMass += massChange;
//TTT mNumProblems++;
//errMsg(" FULL PROBLEM ", PRINT_IJK<<" "<<D::mFixMass);
}
weightIndex++;
// already done? RFLAG(workLev,i,j,k, workSet) = CFFluid;
QCELL(workLev,i,j,k, workSet, dMass) = myrho; // should be rho... but unused?
@@ -5708,47 +5686,43 @@ void LbmFsgrSolver<D>::reinitFlags( int workSet )
int i=iter->x, j=iter->y, k=iter->z;
LbmFloat massChange = QCELL(workLev, i,j,k, workSet, dMass);
int nbCount = 0;
/*int nbCount = 0;
LbmFloat nbWeights[LBM_DFNUM];
LbmFloat nbTotWeights = 0.0;
FORDF1 {
int ni=i+D::dfVecX[l], nj=j+D::dfVecY[l], nk=k+D::dfVecZ[l];
if( RFLAG(workLev,ni,nj,nk, workSet) & CFInter) {
nbCount++;
nbWeights[l] = vWeights[weightIndex].val[l];
//nbWeights[l] = getMassdWeight(0,i,j,k,workSet,l);
//nbTotWeights += nbWeights[l];
} else {
nbWeights[l] = -100.0; // DEBUG;
}
}
}*/
//errMsg("EDIST", PRINT_IJK<<" mss"<<massChange <<" nb"<< nbCount ); // DEBUG SYMM
if(nbCount>0) {
nbTotWeights = vWeights[weightIndex].val[0];
//errMsg("EE I", PRINT_IJK<<" "<<weightIndex<<" "<<nbTotWeights);
//if(vWeights[weightIndex].val[0] != nbTotWeights) { errMsg("WD","WD"<<vWeights[weightIndex].val[0]<<" "<<nbTotWeights); }
//if(nbCount>0) {
if(vWeights[weightIndex].numNbs>0.0) {
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];
if( RFLAG(workLev,ni,nj,nk, workSet) & CFInter) {
LbmFloat change = -1.0;
if(nbTotWeights>0.0) {
//if(nbWeights[l] != vWeights[weightIndex].val[l]) { errMsg("WD","WD"<<nbWeights[l]<<" "<<vWeights[weightIndex].val[l]); } // DEBUG
change = massChange * ( nbWeights[l]/nbTotWeights );
if(nbTotWeightsp>0.0) {
change = massChange * ( vWeights[weightIndex].val[l]/nbTotWeightsp );
} else {
change = (LbmFloat)(massChange/(LbmFloat)nbCount);
change = (LbmFloat)(massChange/vWeights[weightIndex].numNbs);
}
QCELL(workLev, ni,nj,nk, workSet, dMass) += change;
}
}
massChange = 0.0;
weightIndex++;
} else {
// Problem! no interface neighbors
D::mFixMass += massChange;
//TTT mNumProblems++;
//errMsg(" EMPT PROBLEM ", PRINT_IJK<<" "<<D::mFixMass);
}
weightIndex++;
// finally... make it empty
// already done? RFLAG(workLev,i,j,k, workSet) = CFEmpty;
@@ -5758,7 +5732,8 @@ void LbmFsgrSolver<D>::reinitFlags( int workSet )
for( vector<LbmPoint>::iterator iter=mListEmpty.begin();
iter != mListEmpty.end(); iter++ ) {
int i=iter->x, j=iter->y, k=iter->z;
RFLAG(workLev,i,j,k, otherSet) = CFEmpty;
//RFLAG(workLev,i,j,k, otherSet) = CFEmpty;
changeFlag(workLev,i,j,k, otherSet, CFEmpty);
/*QCELL(workLev,i,j,k, otherSet, dMass) = 0.0;
QCELL(workLev,i,j,k, otherSet, dFfrac) = 0.0; // COMPRT OFF */
}
@@ -5851,7 +5826,7 @@ void LbmFsgrSolver<D>::prepareVisualization( void ) {
# define ZKD1 1
# define ZKOFF k
// reset all values...
for(int k= getForZMinBnd(lev); k< getForZMaxBnd(lev); ++k)
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;
@@ -5862,7 +5837,7 @@ void LbmFsgrSolver<D>::prepareVisualization( void ) {
// add up...
float val = 0.0;
for(int k= getForZMin1(lev); k< getForZMax1(lev); ++k)
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++) {
@@ -5962,6 +5937,11 @@ void LbmFsgrSolver<D>::prepareVisualization( void ) {
* demo functions
*****************************************************************************/
template<class D>
float LbmFsgrSolver<D>::getFillFrac(int i, int j, int k) {
return QCELL(mMaxRefine, i,j,k,mLevel[mMaxRefine].setOther, dFfrac);
}
template<class D>
void LbmFsgrSolver<D>::getIsofieldWeighted(float *iso) {
//errMsg("XxxX", " "<<( szx+ISOCORR) );
@@ -6183,8 +6163,6 @@ int LbmFsgrSolver<D>::checkGfxEndTime() {
if((mGfxEndTime>0.0) && (mSimulationTime>mGfxEndTime)) {
errMsg("LbmFsgrSolver","GfxEndTime "<<mSimulationTime<<" steps:"<<D::mStepCnt);
return true;
//printCellStats();
//exit(1);
}
return false;
}
@@ -6213,6 +6191,21 @@ int LbmFsgrSolver<D>::initParticles(ParticleTracer *partt) {
}
/*! init particle positions */
template<class D>
void LbmFsgrSolver<D>::recalculateObjectSpeeds() {
int numobjs = (int)(D::mpGiObjects->size());
if(numobjs>255) {
errFatal("LbmFsgrSolver::recalculateObjectSpeeds","More than 256 objects currently not supported...",SIMWORLD_INITERROR);
return;
}
mObjectSpeeds.resize(numobjs+0);
for(int i=0; i<(int)(numobjs+0); i++) {
//errMsg("recalculateObjectSpeeds","id"<<i<<" "<<vec2L(D::mpParam->calculateLattVelocityFromRw( vec2P( (*D::mpGiObjects)[i]->getInitialVelocity() )) ));
mObjectSpeeds[i] = vec2L(D::mpParam->calculateLattVelocityFromRw( vec2P( (*D::mpGiObjects)[i]->getInitialVelocity() )));
}
}
/*****************************************************************************/
/*! internal quick print function (for debugging) */
/*****************************************************************************/
@@ -6376,7 +6369,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<<" "<<convertFlags2String(RFLAG(level, x,y,z, mLevel[level].setCurr)) );
//errMsg("cellAt",D::mName<<" "<<pos<<" l"<<level<<":"<<x<<","<<y<<","<<z<<" "<<convertCellFlagType2String(RFLAG(level, x,y,z, mLevel[level].setCurr)) );
return newcid;
}
@@ -6512,6 +6505,105 @@ LbmFsgrSolver<D>::debugDisplay(fluidDispSettings *set){
}
#endif
/*****************************************************************************/
// strict debugging functions
/*****************************************************************************/
#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) {
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; }
if(ii<0){ errMsg("LbmStrict"," invX- l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; }
if(ij<0){ errMsg("LbmStrict"," invY- l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; }
if(ik<0){ errMsg("LbmStrict"," invZ- l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; }
if(ii>mLevel[level].lSizex-1){ errMsg("LbmStrict"," invX+ l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; }
if(ij>mLevel[level].lSizey-1){ errMsg("LbmStrict"," invY+ l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; }
if(ik>mLevel[level].lSizez-1){ errMsg("LbmStrict"," invZ+ l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; }
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; }
return _LBMGI(level, ii,ij,ik, is);
};
template<class D>
CellFlagType& LbmFsgrSolver<D>::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) {
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; }
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) {
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; }
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) {
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; }
if(ii<0){ errMsg("LbmStrict"," invX- l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; }
if(ij<0){ errMsg("LbmStrict"," invY- l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; }
if(ik<0){ errMsg("LbmStrict"," invZ- l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; }
if(ii>mLevel[level].lSizex-1){ errMsg("LbmStrict"," invX+ l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; }
if(ij>mLevel[level].lSizey-1){ errMsg("LbmStrict"," invY+ l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; }
if(ik>mLevel[level].lSizez-1){ errMsg("LbmStrict"," invZ+ l"<<level<<"|"<<ii<<","<<ij<<","<<ik<<" s"<<is); STRICT_EXIT; }
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 != 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
#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) {
//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) {
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; }
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) {
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; }
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 ) {
return _RACPNT(level, ii,ij,ik, is );
};
template<class D>
LbmFloat& LbmFsgrSolver<D>::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 != dMass) && (l != dFfrac) && (l != dFlux)){ errMsg("LbmStrict"," invD+ "<<" l"<<l); STRICT_EXIT; } }
return _RAC(s,l);
};
#endif // FSGR_STRICT_DEBUG==1
#define LBMFSGRSOLVER_H
#endif

View File

@@ -11,11 +11,10 @@
#ifndef LBMFUNCTIONS_H
#if LBM_USE_GUI==1
#endif
#if LBM_USE_GUI==1
#define USE_GLUTILITIES
#include "../gui/gui_utilities.h"
//! display a single node
template<typename D>
@@ -32,6 +31,13 @@ debugDisplayNode(fluidDispSettings *dispset, D *lbm, typename D::CellIdentifier
ntlColor col(0.5);
LbmFloat cscale = dispset->scale;
#define DRAWDISPCUBE(col,scale) \
{ glLineWidth( linewidth ); \
glColor3f( (col)[0], (col)[1], (col)[2]); \
ntlVec3Gfx s = org-(halfsize * (scale)); \
ntlVec3Gfx e = org+(halfsize * (scale)); \
drawCubeWire( s,e ); }
switch(dispset->type) {
case FLUIDDISPNothing: {
showcell = false;
@@ -54,46 +60,36 @@ debugDisplayNode(fluidDispSettings *dispset, D *lbm, typename D::CellIdentifier
else
if(flag& CFFluid ) { if(!guiShowFluid ) return; }
if(flag& CFNoDelete) { // TEST SOLVER debug, mark nodel cells
glLineWidth( linewidth );
ntlColor col(0.7,0.0,0.0);
glColor3f( col[0], col[1], col[2]);
ntlVec3Gfx s = org-(halfsize * 0.1);
ntlVec3Gfx e = org+(halfsize * 0.1);
drawCubeWire( s,e );
if(flag& CFNoDelete) { // debug, mark nodel cells
ntlColor ccol(0.7,0.0,0.0);
DRAWDISPCUBE(ccol, 0.1);
}
if(flag& CFPersistMask) { // mark persistent flags
ntlColor ccol(0.5);
DRAWDISPCUBE(ccol, 0.125);
}
if(flag& CFNoBndFluid) { // mark persistent flags
ntlColor ccol(0,0,1);
DRAWDISPCUBE(ccol, 0.075);
}
/*if(flag& CFAccelerator) {
cscale = 0.55;
col = ntlColor(0,1,0);
//showcell=false; // DEBUG
} */
if(flag& CFInvalid) {
cscale = 0.50;
col = ntlColor(0.0,0,0.0);
//showcell=false; // DEBUG
}
/*else if(flag& CFSpeedSet) {
cscale = 0.55;
col = ntlColor(0.2,1,0.2);
//showcell=false; // DEBUG
}*/
else if(flag& CFBnd) {
cscale = 0.59;
col = ntlColor(0.0);
col = ntlColor(0.4); // DEBUG
//if(lbm->getSizeZ()>2) { showcell=false; } // DEBUG, 3D no obstacles
col = ntlColor(0.4);
}
/*else if(flag& CFIfFluid) { // TEST SOLVER if inner fluid if
cscale = 0.55;
col = ntlColor(0,1,0);
}
else if(flag& CFIfEmpty) { // TEST SOLVER if outer empty if
cscale = 0.55;
col = ntlColor(0,0.5,0.5);
}*/
else if(flag& CFInter) {
cscale = 0.55;
col = ntlColor(0,1,1);
@@ -101,56 +97,34 @@ debugDisplayNode(fluidDispSettings *dispset, D *lbm, typename D::CellIdentifier
} else if(flag& CFGrFromCoarse) {
// draw as - with marker
ntlColor col2(0.0,1.0,0.3);
glColor3f( col2[0], col2[1], col2[2]);
ntlVec3Gfx s = org-(halfsize * 0.4);
ntlVec3Gfx e = org+(halfsize * 0.4);
drawCubeWire( s,e );
DRAWDISPCUBE(col2, 0.1);
cscale = 0.5;
//col = ntlColor(0,0,1);
showcell=false; // DEBUG
}
else if(flag& CFFluid) {
cscale = 0.5;
/*if(flag& CFCoarseInner) {
col = ntlColor(0.3, 0.3, 1.0);
} else */
if(flag& CFGrToFine) {
glLineWidth( linewidth );
ntlColor col2(0.5,0.0,0.5);
glColor3f( col2[0], col2[1], col2[2]);
ntlVec3Gfx s = org-(halfsize * 0.31);
ntlVec3Gfx e = org+(halfsize * 0.31);
drawCubeWire( s,e );
DRAWDISPCUBE(col2, 0.1);
col = ntlColor(0,0,1);
}
if(flag& CFGrFromFine) {
glLineWidth( linewidth );
ntlColor col2(1.0,1.0,0.0);
glColor3f( col2[0], col2[1], col2[2]);
ntlVec3Gfx s = org-(halfsize * 0.56);
ntlVec3Gfx e = org+(halfsize * 0.56);
drawCubeWire( s,e );
DRAWDISPCUBE(col2, 0.1);
col = ntlColor(0,0,1);
} else if(flag& CFGrFromCoarse) {
// draw as fluid with marker
ntlColor col2(0.0,1.0,0.3);
glColor3f( col2[0], col2[1], col2[2]);
ntlVec3Gfx s = org-(halfsize * 0.41);
ntlVec3Gfx e = org+(halfsize * 0.41);
drawCubeWire( s,e );
DRAWDISPCUBE(col2, 0.1);
col = ntlColor(0,0,1);
} else {
col = ntlColor(0,0,1);
//showcell=false; // DEBUG
}
}
else if(flag& CFEmpty) {
showcell=false;
}
// smaller for new lbmqt
//cscale *= 0.5;
} break;
case FLUIDDISPVelocities: {
// dont use cube display
@@ -209,15 +183,7 @@ debugDisplayNode(fluidDispSettings *dispset, D *lbm, typename D::CellIdentifier
}
if(!showcell) return;
glLineWidth( linewidth );
glColor4f( col[0], col[1], col[2], 0.0);
ntlVec3Gfx s = org-(halfsize * cscale);
ntlVec3Gfx e = org+(halfsize * cscale);
//if(D::cDimension==2) {
//s[2] = e[2] = (s[2]+e[2])*0.5;
//}
drawCubeWire( s,e );
DRAWDISPCUBE(col, cscale);
}
//! debug display function
@@ -256,8 +222,9 @@ lbmMarkedCellDisplay(D *lbm) {
glDisable( GL_LIGHTING ); // dont light lines
typename D::CellIdentifier cid = lbm->markedGetFirstCell();
for(; lbm->markedNoEndCell( cid );
lbm->markedAdvanceCell( cid ) ) {
while(cid) {
//for(; lbm->markedNoEndCell( cid );
//cid = lbm->markedAdvanceCell( cid ) ) {
// display... FIXME? this is a bit inconvenient...
//MarkedCellIdentifier *mid = dynamic_cast<MarkedCellIdentifier *>( cid );
#if (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
@@ -267,13 +234,14 @@ lbmMarkedCellDisplay(D *lbm) {
//debugDisplayNode<D>(&dispset, lbm, mid->mpCell );
debugDisplayNode<D>(&dispset, lbm, cid );
#endif
cid = lbm->markedAdvanceCell();
}
delete cid;
glEnable( GL_LIGHTING ); // dont light lines
}
#endif
#endif // LBM_USE_GUI
//! display a single node
template<typename D>
@@ -305,7 +273,8 @@ debugPrintNodeInfo(D *lbm, typename D::CellIdentifier cell, string printInfo,
case 'g': printGeom = true; break;
case 'm': printMass = true; break;
case 's': printBothSets = true; break;
default: errMsg("debugPrintNodeInfo","Invalid node info id "<<what); exit(1);
default:
errFatal("debugPrintNodeInfo","Invalid node info id "<<what,SIMWORLD_GENERICERROR); return;
}
}

View File

@@ -52,14 +52,14 @@
"ET","EB","WT","WB"
};
const LbmD3Q19::dfDir LbmD3Q19::dfNorm[ cDfNum ] = {
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 LbmD3Q19::dfDir LbmD3Q19::dfInv[ cDfNum ] = {
const int LbmD3Q19::dfInv[ cDfNum ] = {
cDirC, cDirS, cDirN, cDirW, cDirE, cDirB, cDirT,
cDirSW, cDirSE, cDirNW, cDirNE,
cDirSB, cDirST, cDirNB, cDirNT,
@@ -203,13 +203,13 @@
"NE", "NW", "SE","SW"
};
const LbmD2Q9::dfDir LbmD2Q9::dfNorm[ cDfNum ] = {
const int LbmD2Q9::dfNorm[ cDfNum ] = {
cDirC,
cDirN, cDirS, cDirE, cDirW,
cDirNE, cDirNW, cDirSE, cDirSW
};
const LbmD2Q9::dfDir LbmD2Q9::dfInv[ cDfNum ] = {
const int LbmD2Q9::dfInv[ cDfNum ] = {
cDirC,
cDirS, cDirN, cDirW, cDirE,
cDirSW, cDirSE, cDirNW, cDirNE
@@ -305,7 +305,6 @@ LbmSolverInterface::LbmSolverInterface() :
mOmega( 1.0 ),
mGravity(0.0),
mSurfaceTension( 0.0 ),
mInitialMass (0.0),
mBoundaryEast( (CellFlagType)(CFBnd) ),mBoundaryWest( (CellFlagType)(CFBnd) ),mBoundaryNorth( (CellFlagType)(CFBnd) ),
mBoundarySouth( (CellFlagType)(CFBnd) ),mBoundaryTop( (CellFlagType)(CFBnd) ),mBoundaryBottom( (CellFlagType)(CFBnd) ),
mInitDone( false ),
@@ -316,16 +315,17 @@ LbmSolverInterface::LbmSolverInterface() :
mRandom( 5123 ),
mvGeoStart(-1.0), mvGeoEnd(1.0),
mPerformGeoInit( false ),
mAccurateGeoinit(0),
mName("lbm_default") ,
mpIso( NULL ), mIsoValue(0.49999),
mSilent(false) ,
mGeoInitId( 0 ),
mpGiTree( NULL ),
mAccurateGeoinit(0),
mpGiObjects( NULL ), mGiObjInside(), mpGlob( NULL )
mpGiObjects( NULL ), mGiObjInside(), mpGlob( NULL ),
mMarkedCells(), mMarkedCellIndex(0)
{
#if ELBEEM_BLENDER==1
mSilent = true;
if(gDebugLevel<=1) mSilent = true;
#endif
}
@@ -348,9 +348,9 @@ CellFlagType LbmSolverInterface::readBoundaryFlagInt(string name, int defaultVal
/* might be used for some in/out flow cases */
return (CellFlagType)( CFFluid );
}
errorOut("LbmStdSolver::readBoundaryFlagInt error: Invalid value '"<<val<<"' " );
errMsg("LbmStdSolver::readBoundaryFlagInt","Invalid value '"<<val<<"' " );
# if LBM_STRICT_DEBUG==1
exit(1);
errFatal("readBoundaryFlagInt","Strict abort..."<<val, SIMWORLD_INITERROR);
# endif
return defaultValue;
}
@@ -359,8 +359,8 @@ CellFlagType LbmSolverInterface::readBoundaryFlagInt(string name, int defaultVal
/*! parse standard attributes */
void LbmSolverInterface::parseStdAttrList() {
if(!mpAttrs) {
errorOut("LbmStdSolver::parseAttrList error: mpAttrs pointer not initialized!");
exit(1); }
errFatal("LbmStdSolver::parseAttrList","mpAttrs pointer not initialized!",SIMWORLD_INITERROR);
return; }
// st currently unused
//mSurfaceTension = mpAttrs->readFloat("d_surfacetension", mSurfaceTension, "LbmStdSolver", "mSurfaceTension", false);
@@ -395,7 +395,7 @@ void LbmSolverInterface::parseStdAttrList() {
/*****************************************************************************/
/*! init tree for certain geometry init */
void LbmSolverInterface::initGeoTree(int id) {
if(mpGlob == NULL) { errorOut("LbmSolverInterface::initGeoTree error: Requires globals!"); exit(1); }
if(mpGlob == NULL) { errFatal("LbmSolverInterface::initGeoTree","Requires globals!",SIMWORLD_INITERROR); return; }
mGeoInitId = id;
ntlScene *scene = mpGlob->getScene();
mpGiObjects = scene->getObjects();
@@ -427,17 +427,19 @@ void LbmSolverInterface::freeGeoTree() {
bool LbmSolverInterface::geoInitCheckPointInside(ntlVec3Gfx org, int flags, int &OId, gfxReal &distance) {
// shift ve ctors to avoid rounding errors
org += ntlVec3Gfx(0.0001);
ntlVec3Gfx dir = ntlVec3Gfx(0.999999,0.0,0.0);
ntlVec3Gfx dir = ntlVec3Gfx(1.0, 0.0, 0.0);
OId = -1;
ntlRay ray(org, dir, 0, 1.0, mpGlob);
//int insCnt = 0;
bool done = false;
bool inside = false;
//errMsg("III"," start org"<<org<<" dir"<<dir);
//int insID = ray.getID();
for(size_t i=0; i<mGiObjInside.size(); i++) { mGiObjInside[i] = 0; }
for(size_t i=0; i<mGiObjInside.size(); i++) {
mGiObjInside[i] = 0;
mGiObjDistance[i] = -1.0;
}
// if not inside, return distance to first hit
gfxReal firstHit=-1.0;
int firstOId = -1;
if(mAccurateGeoinit) {
while(!done) {
@@ -445,7 +447,7 @@ bool LbmSolverInterface::geoInitCheckPointInside(ntlVec3Gfx org, int flags, int
ntlTriangle *triIns = NULL;
distance = -1.0;
ntlVec3Gfx normal(0.0);
mpGiTree->intersect(ray,distance,normal, triIns, flags, true);
mpGiTree->intersectX(ray,distance,normal, triIns, flags, true);
if(triIns) {
ntlVec3Gfx norg = ray.getOrigin() + ray.getDirection()*distance;
LbmFloat orientation = dot(normal, dir);
@@ -454,44 +456,22 @@ bool LbmSolverInterface::geoInitCheckPointInside(ntlVec3Gfx org, int flags, int
// outside hit
normal *= -1.0;
mGiObjInside[OId]++;
mGiObjDistance[OId] = -1.0;
//mGiObjDistance[OId] = -1.0;
//errMsg("IIO"," oid:"<<OId<<" org"<<org<<" norg"<<norg);
} else {
// inside hit
mGiObjInside[OId]++;
mGiObjDistance[OId] = distance;
if(mGiObjDistance[OId]<0.0) mGiObjDistance[OId] = distance;
//errMsg("III"," oid:"<<OId<<" org"<<org<<" norg"<<norg);
}
norg += normal * getVecEpsilon();
ray = ntlRay(norg, dir, 0, 1.0, mpGlob);
if(firstHit<0.0) firstHit = distance;
//if((OId<0) && ())
//insCnt++;
/*
// check outside intersect
LbmFloat orientation = dot(normal, dir);
if(orientation<=0.0) {
// do more thorough checks... advance ray
ntlVec3Gfx norg = ray.getOrigin() + ray.getDirection()*distance;
norg += normal * (-1.0 * getVecEpsilon());
ray = ntlRay(norg, dir, 0, 1.0, mpGlob);
insCnt++;
errMsg("III"," oid:"<<OId<<" org"<<org<<" norg"<<norg<<" insCnt"<<insCnt);
} else {
if(insCnt>0) {
// we have entered this obj before?
ntlVec3Gfx norg = ray.getOrigin() + ray.getDirection()*distance;
norg += normal * (-1.0 * getVecEpsilon());
ray = ntlRay(norg, dir, 0, 1.0, mpGlob);
insCnt--;
errMsg("IIIS"," oid:"<<OId<<" org"<<org<<" norg"<<norg<<" insCnt"<<insCnt);
} else {
// first inside intersection -> ok
OId = triIns->getObjectId();
done = inside = true;
// remember first hit distance, in case we're not
// inside anything
if(firstHit<0.0) {
firstHit = distance;
firstOId = OId;
}
}
*/
} else {
// no more intersections... return false
done = true;
@@ -503,24 +483,20 @@ bool LbmSolverInterface::geoInitCheckPointInside(ntlVec3Gfx org, int flags, int
for(size_t i=0; i<mGiObjInside.size(); i++) {
//errMsg("CHIII","i"<<i<<" ins="<<mGiObjInside[i]<<" t"<<mGiObjDistance[i]<<" d"<<distance);
if(((mGiObjInside[i]%2)==1)&&(mGiObjDistance[i]>0.0)) {
if(distance<0.0) {
// first intersection -> good
if( (distance<0.0) || // first intersection -> good
((distance>0.0)&&(distance>mGiObjDistance[i])) // more than one intersection -> use closest one
) {
distance = mGiObjDistance[i];
OId = i;
inside = true;
} else {
if(distance>mGiObjDistance[i]) {
// more than one intersection -> use closest one
distance = mGiObjDistance[i];
OId = i;
inside = true;
}
}
}
}
}
if(!inside) {
distance = firstHit;
OId = firstOId;
}
//errMsg("CHIII","i"<<inside<<" fh"<<firstHit<<" fo"<<firstOId<<" - h"<<distance<<" o"<<OId);
return inside;
} else {
@@ -529,7 +505,7 @@ bool LbmSolverInterface::geoInitCheckPointInside(ntlVec3Gfx org, int flags, int
ntlTriangle *triIns = NULL;
distance = -1.0;
ntlVec3Gfx normal(0.0);
mpGiTree->intersect(ray,distance,normal, triIns, flags, true);
mpGiTree->intersectX(ray,distance,normal, triIns, flags, true);
if(triIns) {
// check outside intersect
LbmFloat orientation = dot(normal, dir);
@@ -605,44 +581,25 @@ LbmSolverInterface::addCellToMarkedList( CellIdentifierInterface *cid ) {
for(size_t i=0; i<mMarkedCells.size(); i++) {
// check if cids alreay in
if( mMarkedCells[i]->equal(cid) ) return;
mMarkedCells[i]->setEnd(false);
//mMarkedCells[i]->setEnd(false);
}
mMarkedCells.push_back( cid );
cid->setEnd(true);
//cid->setEnd(true);
}
/*****************************************************************************/
//! marked cell iteration methods
CellIdentifierInterface*
LbmSolverInterface::markedGetFirstCell( ) {
/*MarkedCellIdentifier *newcid = new MarkedCellIdentifier();
if(mMarkedCells.size() < 1){
newcid->setEnd( true );
} else {
newcid->mpCell = mMarkedCells[0];
}
return newcid;*/
if(mMarkedCells.size() > 0){ return mMarkedCells[0]; }
return NULL;
}
void
LbmSolverInterface::markedAdvanceCell( CellIdentifierInterface* basecid ) {
if(!basecid) return;
basecid->setEnd( true );
/*MarkedCellIdentifier *cid = dynamic_cast<MarkedCellIdentifier*>( basecid );
CellIdentifierInterface *cid = basecid;
cid->mIndex++;
if(cid->mIndex >= (int)mMarkedCells.size()) {
cid->setEnd( true );
}
cid->mpCell = mMarkedCells[ cid->mIndex ];
*/
}
bool
LbmSolverInterface::markedNoEndCell( CellIdentifierInterface* cid ) {
if(!cid) return false;
return(! cid->getEnd() );
CellIdentifierInterface*
LbmSolverInterface::markedAdvanceCell() {
mMarkedCellIndex++;
if(mMarkedCellIndex>=(int)mMarkedCells.size()) return NULL;
return mMarkedCells[mMarkedCellIndex];
}
void LbmSolverInterface::markedClearList() {
@@ -669,11 +626,12 @@ std::string convertSingleFlag2String(CellFlagType cflag) {
if(flag == CFNoNbEmpty ) return string("cCFNoNbEmpty");
if(flag == CFNoDelete ) return string("cCFNoDelete");
if(flag == CFNoBndFluid ) return string("cCFNoBndFluid");
if(flag == CFBndMARK ) return string("cCFBndMARK");
if(flag == CFGrNorm ) return string("cCFGrNorm");
if(flag == CFGrFromFine ) return string("cCFGrFromFine");
if(flag == CFGrFromCoarse ) return string("cCFGrFromCoarse");
if(flag == CFGrCoarseInited ) return string("cCFGrCoarseInited");
if(flag == CFMbndInflow ) return string("cCFMbndInflow");
if(flag == CFMbndOutflow ) return string("cCFMbndOutflow");
if(flag == CFInvalid ) return string("cfINVALID");
std::ostringstream mult;
@@ -701,7 +659,7 @@ std::string convertCellFlagType2String( CellFlagType cflag ) {
for(int j=0; j<jmax ; j++) {
if(flag& (1<<j)) {
if(somefound) mult << "|";
mult << convertSingleFlag2String( (CellFlagType)(1<<j) ); // this call should always be _non_-recursive
mult << j<<"<"<< convertSingleFlag2String( (CellFlagType)(1<<j) ); // this call should always be _non_-recursive
somefound = true;
}
};

View File

@@ -21,9 +21,6 @@
#if LBM_USE_GUI==1
#define USE_GLUTILITIES
// for debug display
#ifdef _WIN32
#include <windows.h>
#endif
#include <GL/gl.h>
#include "../gui/guifuncs.h"
#endif
@@ -76,51 +73,48 @@ template<class T> inline ParamVec vec2P(T v) { return ParamVec(v[0],v[1],v[2])
typedef int BubbleId;
// for both short int/char
// 1
#define CFUnused (1<< 0)
// 2
#define CFEmpty (1<< 1)
// 4
#define CFBnd (1<< 2)
// 8, force symmetry for flag reinit
#define CFNoInterpolSrc (1<< 3)
// 16
#define CFFluid (1<< 4)
// 32
#define CFInter (1<< 5)
// 64
#define CFNoNbFluid (1<< 6)
// 128
#define CFNoNbEmpty (1<< 7)
// 256
#define CFNoDelete (1<< 8)
// 512
#define CFNoBndFluid (1<< 9)
// 1024
#define CFBndMARK (1<<10)
#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)
//! refinement tags
// cell treated normally on coarser grids
// 2048
#define CFGrNorm (1<<11)
#define CFGrNorm (1<<13)
// border cells to be interpolated from finer grid
// 4096
#define CFGrFromFine (1<<12)
// 8192
#define CFGrFromCoarse (1<<13)
// 16384
#define CFGrCoarseInited (1<<14)
// 32k (aux marker, no real action)
#define CFGrToFine (1<<15)
#define CFGrFromFine (1<<14)
#define CFGrFromCoarse (1<<15)
#define CFGrCoarseInited (1<<16)
// 32k aux border marker
#define CFGrToFine (1<<17)
#define CFMbndInflow (1<<18)
#define CFMbndOutflow (1<<19)
// above 24 is used to encode in/outflow object type
#define CFPersistMask (0xFF000000 | CFMbndInflow | CFMbndOutflow)
// nk
#define CFInvalid (CellFlagType)(1<<31)
// use 16bit flag types
//#define CellFlagType unsigned short int
// use 32bit flag types
#define CellFlagType unsigned long int
#ifdef __x86_64__
typedef int cfINT32;
#else
typedef long cfINT32;
#endif // defined (_IA64)
#define CellFlagType cfINT32
#define CellFlagTypeSize 4
/*****************************************************************************/
@@ -225,7 +219,7 @@ typedef struct fluidDispSettings_T {
class CellIdentifierInterface {
public:
//! reset constructor
CellIdentifierInterface() : mEnd (false) { };
CellIdentifierInterface():mEnd(false) { };
//! virtual destructor
virtual ~CellIdentifierInterface() {};
@@ -235,50 +229,16 @@ class CellIdentifierInterface {
//! compare cids
virtual bool equal(CellIdentifierInterface* other) = 0;
//! set/get end flag
//! set/get end flag for grid traversal (not needed for marked cells)
inline void setEnd(bool set){ mEnd = set; }
inline bool getEnd( ) { return mEnd; }
protected:
//! has the grid been traversed?
bool mEnd;
};
/*****************************************************************************/
/*! marked cell access class *
class MarkedCellIdentifier :
public CellIdentifierInterface
{
public:
//! cell pointer
CellIdentifierInterface *mpCell;
//! location in mMarkedCells vector
int mIndex;
//! reset constructor
MarkedCellIdentifier() :
mpCell( NULL ), mIndex(0)
{ };
// implement CellIdentifierInterface
virtual std::string getAsString() {
std::ostringstream ret;
ret <<"{MC i"<<mIndex<<" }";
return ret.str();
}
virtual bool equal(CellIdentifierInterface* other) {
MarkedCellIdentifier *cid = dynamic_cast<MarkedCellIdentifier *>( other );
if(!cid) return false;
if( mpCell==cid->mpCell ) return true;
return false;
}
}; */
/*****************************************************************************/
/*! class defining abstract function interface */
@@ -326,8 +286,6 @@ class LbmSolverInterface
void initGeoTree(int id);
/*! destroy tree etc. when geometry init done */
void freeGeoTree();
/*! get fluid init type at certain position */
// DEPRECATED CellFlagType geoInitGetPointType(ntlVec3Gfx org, ntlVec3Gfx nodesize, ntlGeometryObject **mpObj, gfxReal &distance);
/*! check for a certain flag type at position org (needed for e.g. quadtree refinement) */
bool geoInitCheckPointInside(ntlVec3Gfx org, int flags, int &OId, gfxReal &distance);
/*! set render globals, for scene/tree access */
@@ -341,13 +299,6 @@ class LbmSolverInterface
char* getIsoVertexArray() { return mpIso->getIsoVertexArray(); }
unsigned int *getIsoIndexArray() { return mpIso->getIsoIndexArray(); }
void triangulateSurface() { return mpIso->triangulate(); }
// drop stuff
//virtual void addDrop(bool active, float mx, float my) = 0;
//! avg. used cell count stats
//virtual void printCellStats() = 0;
//! check end time for gfx ani
//virtual int checkGfxEndTime() = 0;
//virtual int getGfxGeoSetup() = 0;
/* access functions */
@@ -434,8 +385,7 @@ class LbmSolverInterface
void addCellToMarkedList( CellIdentifierInterface *cid );
//! marked cell iteration methods
CellIdentifierInterface* markedGetFirstCell( );
void markedAdvanceCell( CellIdentifierInterface* pcid );
bool markedNoEndCell( CellIdentifierInterface* cid );
CellIdentifierInterface* markedAdvanceCell();
void markedClearList();
#ifndef LBMDIM
@@ -481,8 +431,6 @@ class LbmSolverInterface
LbmFloat mSurfaceTension;
/*! initial mass to display changes */
LbmFloat mInitialMass;
/* boundary inits */
CellFlagType mBoundaryEast, mBoundaryWest,
mBoundaryNorth, mBoundarySouth,
@@ -557,6 +505,7 @@ class LbmSolverInterface
// list for marked cells
std::vector<CellIdentifierInterface *> mMarkedCells;
int mMarkedCellIndex;
};

View File

@@ -55,10 +55,8 @@ int ntlBlenderDumper::renderScene( void )
ntlRenderGlobals *glob = mpGlob;
ntlScene *scene = mpGlob->getScene();
bool debugOut = true;
bool otherOut = true;
#if ELBEEM_BLENDER==1
debugOut = false;
otherOut = false;
#endif // ELBEEM_BLENDER==1
// output path
@@ -173,8 +171,7 @@ int ntlBlenderDumper::renderScene( void )
gzwrite(gzf, &wri, sizeof(wri)); }
}
gzclose( gzf );
if(otherOut)
debMsgDirect(" Wrote: '"<<boutfilename.str()<<"'. ");
debMsgDirect(" Wrote: '"<<boutfilename.str()<<"'. ");
numGMs++;
}
}
@@ -185,20 +182,14 @@ int ntlBlenderDumper::renderScene( void )
if(numGMs>0) {
if(debugOut) debMsgStd("ntlBlenderDumper::renderScene",DM_MSG,"Objects dumped: "<<numGMs, 10);
} else {
errMsg("ntlBlenderDumper::renderScene","No objects to dump! Aborting...");
#if ELBEEM_BLENDER==1
// TODO ... D::mPanic=1;
errFatal("ntlBlenderDumper::renderScene","No objects to dump! Aborting...",SIMWORLD_INITERROR);
return 1;
#else // ELBEEM_BLENDER==1
exit(1);
#endif // ELBEEM_BLENDER==1
}
/* next frame */
//glob->setAniCount( glob->getAniCount() +1 );
long stopTime = getTime();
if(debugOut)
debMsgStd("ntlBlenderDumper::renderScene",DM_MSG,"Scene #"<<nrStr<<" dump time: "<< getTimeString(stopTime-startTime) <<" ", 10);
debMsgStd("ntlBlenderDumper::renderScene",DM_MSG,"Scene #"<<nrStr<<" dump time: "<< getTimeString(stopTime-startTime) <<" ", 10);
// still render for preview...
if(debugOut) {

View File

@@ -30,6 +30,8 @@ int doSort = 0;
//! struct for a single node in the bsp tree
class BSPNode {
public:
BSPNode() {};
ntlVec3Gfx min,max; /* AABB for node */
vector<ntlTriangle *> *members; /* stored triangles */
BSPNode *child[2]; /* pointer to children nodes */
@@ -131,8 +133,8 @@ ntlTree::ntlTree() :
mpNodeStack( NULL), mpVertices( NULL ), mpVertNormals( NULL ), mpTriangles( NULL ),
mCurrentDepth(0), mCurrentNodes(0), mTriDoubles(0)
{
errorOut( "ntlTree Cons: Uninitialized BSP Tree!\n" );
exit(1);
errFatal( "ntlTree","Uninitialized BSP Tree!\n",SIMWORLD_INITERROR );
return;
}
@@ -153,8 +155,8 @@ ntlTree::ntlTree(int depth, int objnum, ntlScene *scene, int triFlagMask) :
mTriangleMask = triFlagMask;
if(mpTriangles == NULL) {
errorOut( "ntlTree Cons: no triangle list!\n");
exit(1);
errFatal( "ntlTree Cons","no triangle list!\n",SIMWORLD_INITERROR);
return;
}
if(mpTriangles->size() == 0) {
warnMsg( "ntlTree::ntlTree","No triangles ("<< mpTriangles->size() <<")!\n");
@@ -162,8 +164,8 @@ ntlTree::ntlTree(int depth, int objnum, ntlScene *scene, int triFlagMask) :
return;
}
if(depth>=BSP_STACK_SIZE) {
errMsg( "ntlTree::ntlTree","Depth to high ("<< mMaxDepth <<")!\n" );
exit(1);
errFatal( "ntlTree::ntlTree","Depth to high ("<< mMaxDepth <<")!\n", SIMWORLD_INITERROR );
return;
}
/* check triangles (a bit inefficient, but we dont know which vertices belong
@@ -363,10 +365,10 @@ void ntlTree::subdivide(BSPNode *node, int depth, int axis)
/* add triangle, check bounding box axis */
TriangleBBox *bbox = &mpTBB[ (*iter)->getBBoxId() ];
bool intersect = true;
if( bbox->end[axis] < node->child[i]->min[axis] ) intersect = false;
else if( bbox->start[axis] > node->child[i]->max[axis] ) intersect = false;
if(intersect) {
bool isintersect = true;
if( bbox->end[axis] < node->child[i]->min[axis] ) isintersect = false;
else if( bbox->start[axis] > node->child[i]->max[axis] ) isintersect = false;
if(isintersect) {
// add flag to vector
mpTriDist[t] |= (1<<i);
// count no. of triangles for vector init
@@ -439,9 +441,48 @@ void ntlTree::subdivide(BSPNode *node, int depth, int axis)
} /* subdivision necessary */
}
/******************************************************************
* triangle intersection with triangle pointer,
* returns t,u,v by references
*/
#if GFX_PRECISION==1
// float values
//! the minimal triangle determinant length
#define RAY_TRIANGLE_EPSILON (1e-07)
#else
// double values
//! the minimal triangle determinant length
#define RAY_TRIANGLE_EPSILON (1e-15)
#endif
/******************************************************************************
* intersect ray with BSPtree
*****************************************************************************/
inline void ntlRay::intersectTriangle(vector<ntlVec3Gfx> *mpV, ntlTriangle *tri, gfxReal &t, gfxReal &u, gfxReal &v) const
{
/* (cf. moeller&haines, page 305) */
t = GFX_REAL_MAX;
ntlVec3Gfx e0 = (*mpV)[ tri->getPoints()[0] ];
ntlVec3Gfx e1 = (*mpV)[ tri->getPoints()[1] ] - e0;
ntlVec3Gfx e2 = (*mpV)[ tri->getPoints()[2] ] - e0;
ntlVec3Gfx p = cross( mDirection, e2 );
gfxReal divisor = dot(e1, p);
if((divisor > -RAY_TRIANGLE_EPSILON)&&(divisor < RAY_TRIANGLE_EPSILON)) return;
gfxReal invDivisor = 1/divisor;
ntlVec3Gfx s = mOrigin - e0;
u = invDivisor * dot(s, p);
if( (u<0.0-RAY_TRIANGLE_EPSILON) || (u>1.0+RAY_TRIANGLE_EPSILON) ) return;
ntlVec3Gfx q = cross( s,e1 );
v = invDivisor * dot(mDirection, q);
if( (v<0.0-RAY_TRIANGLE_EPSILON) || ((u+v)>1.0+RAY_TRIANGLE_EPSILON) ) return;
t = invDivisor * dot(e2, q);
}
void ntlTree::intersect(const ntlRay &ray, gfxReal &distance,
ntlVec3Gfx &normal,
ntlTriangle *&tri,
@@ -623,6 +664,215 @@ void ntlTree::intersect(const ntlRay &ray, gfxReal &distance,
return;
}
inline void ntlRay::intersectTriangleX(vector<ntlVec3Gfx> *mpV, ntlTriangle *tri, gfxReal &t, gfxReal &u, gfxReal &v) const
{
/* (cf. moeller&haines, page 305) */
t = GFX_REAL_MAX;
ntlVec3Gfx e0 = (*mpV)[ tri->getPoints()[0] ];
ntlVec3Gfx e1 = (*mpV)[ tri->getPoints()[1] ] - e0;
ntlVec3Gfx e2 = (*mpV)[ tri->getPoints()[2] ] - e0;
//ntlVec3Gfx p = cross( mDirection, e2 );
//ntlVector3Dim<Scalar> cp( (-), (- (1.0 *v[2])), ((1.0 *v[1]) -) );
ntlVec3Gfx p(0.0, -e2[2], e2[1]);
gfxReal divisor = dot(e1, p);
if((divisor > -RAY_TRIANGLE_EPSILON)&&(divisor < RAY_TRIANGLE_EPSILON)) return;
gfxReal invDivisor = 1/divisor;
ntlVec3Gfx s = mOrigin - e0;
u = invDivisor * dot(s, p);
if( (u<0.0-RAY_TRIANGLE_EPSILON) || (u>1.0+RAY_TRIANGLE_EPSILON) ) return;
ntlVec3Gfx q = cross( s,e1 );
//v = invDivisor * dot(mDirection, q);
v = invDivisor * q[0];
if( (v<0.0-RAY_TRIANGLE_EPSILON) || ((u+v)>1.0+RAY_TRIANGLE_EPSILON) ) return;
t = invDivisor * dot(e2, q);
}
void ntlTree::intersectX(const ntlRay &ray, gfxReal &distance,
ntlVec3Gfx &normal,
ntlTriangle *&tri,
int flags, bool forceNonsmooth) const
{
gfxReal mint = GFX_REAL_MAX; /* current minimal t */
ntlVec3Gfx retnormal; /* intersection (interpolated) normal */
gfxReal mintu=0.0, mintv=0.0; /* u,v for min t intersection */
BSPNode *curr, *nearChild, *farChild; /* current node and children */
gfxReal planedist, mindist, maxdist;
ntlVec3Gfx pos;
ntlTriangle *hit = NULL;
tri = NULL;
ray.intersectCompleteAABB(mStart,mEnd,mindist,maxdist); // +X
if((maxdist < 0.0) ||
(mindist == GFX_REAL_MAX) ||
(maxdist == GFX_REAL_MAX) ) {
distance = -1.0;
return;
}
mindist -= getVecEpsilon();
maxdist += getVecEpsilon();
/* stack init */
mpNodeStack->elem[0].node = NULL;
mpNodeStack->stackPtr = 1;
curr = mpRoot;
mint = GFX_REAL_MAX;
while(curr != NULL) { // +X
while( !curr->isLeaf() ) {
planedist = distanceToPlane(curr, curr->child[0]->max, ray );
getChildren(curr, ray.getOrigin(), nearChild, farChild );
// check ray direction for small plane distances
if( (planedist>-getVecEpsilon() )&&(planedist< getVecEpsilon() ) ) {
// ray origin on intersection plane
planedist = 0.0;
if(ray.getDirection()[curr->axis]>getVecEpsilon() ) {
// larger coords
curr = curr->child[1];
} else if(ray.getDirection()[curr->axis]<-getVecEpsilon() ) {
// smaller coords
curr = curr->child[0];
} else {
// paralell, order doesnt really matter are min/max/plane ok?
mpNodeStack->elem[ mpNodeStack->stackPtr ].node = curr->child[0];
mpNodeStack->elem[ mpNodeStack->stackPtr ].mindist = planedist;
mpNodeStack->elem[ mpNodeStack->stackPtr ].maxdist = maxdist;
(mpNodeStack->stackPtr)++;
curr = curr->child[1];
maxdist = planedist;
}
} else {
// normal ray
if( (planedist>maxdist) || (planedist<0.0-getVecEpsilon() ) ) {
curr = nearChild;
} else if(planedist < mindist) {
curr = farChild;
} else {
mpNodeStack->elem[ mpNodeStack->stackPtr ].node = farChild;
mpNodeStack->elem[ mpNodeStack->stackPtr ].mindist = planedist;
mpNodeStack->elem[ mpNodeStack->stackPtr ].maxdist = maxdist;
(mpNodeStack->stackPtr)++;
curr = nearChild;
maxdist = planedist;
}
}
} // +X
/* intersect with current node */
for (vector<ntlTriangle *>::iterator iter = curr->members->begin();
iter != curr->members->end(); iter++ ) {
/* check for triangle flags before intersecting */
if((!flags) || ( ((*iter)->getFlags() & flags) > 0 )) {
if( ((*iter)->getLastRay() == ray.getID() )&&((*iter)->getLastRay()>0) ) {
// was already intersected...
} else {
// we still need to intersect this triangle
gfxReal u=0.0,v=0.0, t=-1.0;
ray.intersectTriangleX( mpVertices, (*iter), t,u,v);
(*iter)->setLastRay( ray.getID() );
if( (t > 0.0) && (t<mint) ) {
mint = t;
hit = (*iter);
mintu = u; mintv = v;
if((ray.getRenderglobals())&&(ray.getRenderglobals()->getDebugOut() > 5)) { // DEBUG!!!
errorOut("Tree tri hit at "<<t<<","<<mint<<" triangle: "<<PRINT_TRIANGLE( (*hit), (*mpVertices) ) );
gfxReal u1=0.0,v1=0.0, t1=-1.0;
ray.intersectTriangleX( mpVertices, hit, t1,u1,v1);
errorOut("Tree second test1 :"<<t1<<" u1:"<<u1<<" v1:"<<v1 );
if(t==GFX_REAL_MAX) errorOut( "Tree MAX t " );
//errorOut( mpVertices[ (*iter).getPoints()[0] ][0] );
}
//retnormal = -(e2-e0).crossProd(e1-e0); // DEBUG
}
}
} // flags check
} // +X
/* check if intersection is valid */
if( (mint>0.0) && (mint < GFX_REAL_MAX) ) {
pos = ray.getOrigin() + ray.getDirection()*mint;
if( (pos[0] >= curr->min[0]) && (pos[0] <= curr->max[0]) &&
(pos[1] >= curr->min[1]) && (pos[1] <= curr->max[1]) &&
(pos[2] >= curr->min[2]) && (pos[2] <= curr->max[2]) )
{
if(forceNonsmooth) {
// calculate triangle normal
ntlVec3Gfx e0,e1,e2;
e0 = (*mpVertices)[ hit->getPoints()[0] ];
e1 = (*mpVertices)[ hit->getPoints()[1] ];
e2 = (*mpVertices)[ hit->getPoints()[2] ];
retnormal = cross( -(e2-e0), (e1-e0) );
} else {
// calculate interpolated normal
retnormal = (*mpVertNormals)[ hit->getPoints()[0] ] * (1.0-mintu-mintv)+
(*mpVertNormals)[ hit->getPoints()[1] ]*mintu +
(*mpVertNormals)[ hit->getPoints()[2] ]*mintv;
}
normalize(retnormal);
normal = retnormal;
distance = mint;
tri = hit;
return;
}
} // +X
(mpNodeStack->stackPtr)--;
curr = mpNodeStack->elem[ mpNodeStack->stackPtr ].node;
mindist = mpNodeStack->elem[ mpNodeStack->stackPtr ].mindist;
maxdist = mpNodeStack->elem[ mpNodeStack->stackPtr ].maxdist;
} /* traverse tree */
if(mint == GFX_REAL_MAX) {
distance = -1.0;
} else {
if((ray.getRenderglobals())&&(ray.getRenderglobals()->getDebugOut() > 5)) { // DEBUG!!!
errorOut("Intersection outside BV ");
}
// intersection outside the BSP bounding volumes might occur due to roundoff...
//retnormal = (*mpVertNormals)[ hit->getPoints()[0] ] * (1.0-mintu-mintv)+ (*mpVertNormals)[ hit->getPoints()[1] ]*mintu + (*mpVertNormals)[ hit->getPoints()[2] ]*mintv;
if(forceNonsmooth) {
// calculate triangle normal
ntlVec3Gfx e0,e1,e2;
e0 = (*mpVertices)[ hit->getPoints()[0] ];
e1 = (*mpVertices)[ hit->getPoints()[1] ];
e2 = (*mpVertices)[ hit->getPoints()[2] ];
retnormal = cross( -(e2-e0), (e1-e0) );
} else {
// calculate interpolated normal
retnormal = (*mpVertNormals)[ hit->getPoints()[0] ] * (1.0-mintu-mintv)+
(*mpVertNormals)[ hit->getPoints()[1] ]*mintu +
(*mpVertNormals)[ hit->getPoints()[2] ]*mintv;
}
normalize(retnormal);
normal = retnormal;
distance = mint;
tri = hit;
} // +X
return;
}
/******************************************************************************
* distance to plane function for nodes
@@ -666,3 +916,55 @@ void ntlTree::deleteNode(BSPNode *curr)
}
/******************************************************************
* intersect only front or backsides
* currently unused
*/
inline void ntlRay::intersectTriangleFront(vector<ntlVec3Gfx> *mpV, ntlTriangle *tri, gfxReal &t, gfxReal &u, gfxReal &v) const
{
t = GFX_REAL_MAX;
ntlVec3Gfx e0 = (*mpV)[ tri->getPoints()[0] ];
ntlVec3Gfx e1 = (*mpV)[ tri->getPoints()[1] ] - e0;
ntlVec3Gfx e2 = (*mpV)[ tri->getPoints()[2] ] - e0;
ntlVec3Gfx p = cross( mDirection, e2 );
gfxReal a = dot(e1, p);
//if((a > -RAY_TRIANGLE_EPSILON)&&(a < RAY_TRIANGLE_EPSILON)) return;
if(a < RAY_TRIANGLE_EPSILON) return; // cull backsides
gfxReal f = 1/a;
ntlVec3Gfx s = mOrigin - e0;
u = f * dot(s, p);
if( (u<0.0-RAY_TRIANGLE_EPSILON) || (u>1.0+RAY_TRIANGLE_EPSILON) ) return;
ntlVec3Gfx q = cross( s,e1 );
v = f * dot(mDirection, q);
if( (v<0.0-RAY_TRIANGLE_EPSILON) || ((u+v)>1.0+RAY_TRIANGLE_EPSILON) ) return;
t = f * dot(e2, q);
}
inline void ntlRay::intersectTriangleBack(vector<ntlVec3Gfx> *mpV, ntlTriangle *tri, gfxReal &t, gfxReal &u, gfxReal &v) const
{
t = GFX_REAL_MAX;
ntlVec3Gfx e0 = (*mpV)[ tri->getPoints()[0] ];
ntlVec3Gfx e1 = (*mpV)[ tri->getPoints()[1] ] - e0;
ntlVec3Gfx e2 = (*mpV)[ tri->getPoints()[2] ] - e0;
ntlVec3Gfx p = cross( mDirection, e2 );
gfxReal a = dot(e1, p);
//if((a > -RAY_TRIANGLE_EPSILON)&&(a < RAY_TRIANGLE_EPSILON)) return;
if(a > -RAY_TRIANGLE_EPSILON) return; // cull frontsides
gfxReal f = 1/a;
ntlVec3Gfx s = mOrigin - e0;
u = f * dot(s, p);
if( (u<0.0-RAY_TRIANGLE_EPSILON) || (u>1.0+RAY_TRIANGLE_EPSILON) ) return;
ntlVec3Gfx q = cross( s,e1 );
v = f * dot(mDirection, q);
if( (v<0.0-RAY_TRIANGLE_EPSILON) || ((u+v)>1.0+RAY_TRIANGLE_EPSILON) ) return;
t = f * dot(e2, q);
}

View File

@@ -48,6 +48,8 @@ class ntlTree
//! intersect ray with BSPtree
void intersect(const ntlRay &ray, gfxReal &distance, ntlVec3Gfx &normal, ntlTriangle *&tri, int flags, bool forceNonsmooth) const;
//! intersect along +X ray
void intersectX(const ntlRay &ray, gfxReal &distance, ntlVec3Gfx &normal, ntlTriangle *&tri, int flags, bool forceNonsmooth) const;
//! Returns number of nodes
int getCurrentNodes( void ) { return mCurrentNodes; }

View File

@@ -115,12 +115,8 @@ int ntlGeometryObjModel::loadBobjModel(string filename)
gzFile gzf;
gzf = gzopen(filename.c_str(), "rb");
if (!gzf) {
errMsg("ntlGeometryObjModel::loadBobjModel","Reading GZ_BOBJ, Unable to open '"<< filename <<"'...\n" );
#if ELBEEM_BLENDER==1
exit(1);
#else // ELBEEM_BLENDER==1
errFatal("ntlGeometryObjModel::loadBobjModel","Reading GZ_BOBJ, Unable to open '"<< filename <<"'...\n", SIMWORLD_INITERROR );
return 1;
#endif // ELBEEM_BLENDER==1
}
int wri;
@@ -191,12 +187,8 @@ int ntlGeometryObjModel::loadBobjModel(string filename)
return 0;
gzreaderror:
gzclose( gzf );
#if ELBEEM_BLENDER==1
errMsg("ntlGeometryObjModel::loadBobjModel","Reading GZ_BOBJ, Unable to load '"<< filename <<"', exiting...\n" );
exit(1);
#else // ELBEEM_BLENDER==1
errFatal("ntlGeometryObjModel::loadBobjModel","Reading GZ_BOBJ, Unable to load '"<< filename <<"', exiting...\n", SIMWORLD_INITERROR );
return 1;
#endif // ELBEEM_BLENDER==1
}

View File

@@ -42,46 +42,40 @@ ntlGeometryObject::~ntlGeometryObject()
/*****************************************************************************/
/* Init attributes etc. of this object */
/*****************************************************************************/
#define GEOINIT_STRINGS 9
static char *initStringStrs[GEOINIT_STRINGS] = {
"fluid",
"bnd_no","bnd_noslip",
"bnd_free","bnd_freeslip",
"bnd_part","bnd_partslip",
"inflow", "outflow"
};
static int initStringTypes[GEOINIT_STRINGS] = {
FGI_FLUID,
FGI_BNDNO, FGI_BNDNO,
FGI_BNDFREE, FGI_BNDFREE,
FGI_BNDPART, FGI_BNDPART,
FGI_MBNDINFLOW, FGI_MBNDOUTFLOW
};
void ntlGeometryObject::initialize(ntlRenderGlobals *glob)
{
//debugOut("ntlGeometryObject::initialize: '"<<getName()<<"' ", 10);
mGeoInitId = mpAttrs->readInt("geoinitid", mGeoInitId,"ntlGeometryObject", "mGeoInitId", false);
mGeoInitIntersect = mpAttrs->readInt("geoinit_intersect", mGeoInitIntersect,"ntlGeometryObject", "mGeoInitIntersect", false);
string ginitStr = mpAttrs->readString("geoinittype", "", "ntlGeometryObject", "mGeoInitType", false);
if(mGeoInitId>=0) {
string initStr = mpAttrs->readString("geoinittype", "", "ntlGeometryObject", "mGeoInitType", false);
if(initStr== "fluid") {
mGeoInitType = FGI_FLUID;
} else
if((initStr== "bnd_no") || (initStr=="bnd_noslip")) {
mGeoInitType = FGI_BNDNO;
} else
if((initStr== "bnd_free") || (initStr=="bnd_freeslip")) {
mGeoInitType = FGI_BNDFREE;
} else
if((initStr== "acc") || (initStr=="accelerator")) {
mGeoInitType = FGI_ACC;
ntlVec3d force = mpAttrs->readVec3d("geoinitforce", ntlVec3d(0.0), "ntlGeometryObject", "mGeoInitForce", true);
errMsg("ntlGeometryObject::initialize","Deprectated acc object used!"); exit(1);
} else
if((initStr== "set") || (initStr=="speedset")) {
mGeoInitType = FGI_SPEEDSET;
ntlVec3d force = mpAttrs->readVec3d("geoinitforce", ntlVec3d(0.0), "ntlGeometryObject", "mGeoInitForce", true);
errMsg("ntlGeometryObject::initialize","Deprectated speedset object used!"); exit(1);
} else
// not so nice - define refinement types...
if(initStr== "p1") {
mGeoInitType = FGI_REFP1;
} else
if(initStr== "p2") {
mGeoInitType = FGI_REFP2;
} else
if(initStr== "p3") {
mGeoInitType = FGI_REFP3;
// nothing found
} else {
errorOut("ntlGeometryObject::initialize error: Unkown 'geoinittype' value: '"<< initStr <<"' ");
exit(1);
bool gotit = false;
for(int i=0; i<GEOINIT_STRINGS; i++) {
if(ginitStr== initStringStrs[i]) {
gotit = true;
mGeoInitType = initStringTypes[i];
}
}
if(!gotit) {
errFatal("ntlGeometryObject::initialize","Unkown 'geoinittype' value: '"<< ginitStr <<"' ", SIMWORLD_INITERROR);
return;
}
}
@@ -91,6 +85,8 @@ void ntlGeometryObject::initialize(ntlRenderGlobals *glob)
mGeoInitId = -1;
}
mInitialVelocity = vec2G( mpAttrs->readVec3d("initial_velocity", vec2D(mInitialVelocity),"ntlGeometryObject", "mInitialVelocity", false));
debMsgStd("ntlGeometryObject::initialize",DM_MSG,"GeoObj '"<<this->getName()<<"': gid="<<mGeoInitId<<" gtype="<<mGeoInitType<<","<<ginitStr<<
" gvel="<<mInitialVelocity<<" gisect="<<mGeoInitIntersect, 10); // debug
// override cfg types
mVisible = mpAttrs->readBool("visible", mVisible,"ntlGeometryObject", "mVisible", false);
@@ -120,8 +116,8 @@ void ntlGeometryObject::searchMaterial(vector<ntlMaterial *> *mat)
}
i++;
}
errMsg("ntlGeometryObject::searchMaterial","Unknown material '"<<mMaterialName<<"' ! ");
exit(1);
errFatal("ntlGeometryObject::searchMaterial","Unknown material '"<<mMaterialName<<"' ! ", SIMWORLD_INITERROR);
return;
}

View File

@@ -32,7 +32,7 @@ class ntlGeometryShader :
virtual int initializeShader() = 0;
/*! Do further object initialization after all geometry has been constructed, should return !=0 upon error */
virtual int postGeoConstrInit(ntlRenderGlobals *glob) { return 0; };
virtual int postGeoConstrInit(ntlRenderGlobals *glob) { glob=NULL; /*unused*/ return 0; };
/*! Get start iterator for all objects */
virtual std::vector<ntlGeometryObject *>::iterator getObjectsBegin() { return mObjects.begin(); }

View File

@@ -35,7 +35,7 @@ public:
inline Value get(int x, int y) { return mpC[y*mSizex+x]; }
/*! Set a pixel in the image */
inline void set(int x, int y, Value set) { mpC[y*mSizex+x] = set; }
inline void set(int x, int y, Value setv) { mpC[y*mSizex+x] = setv; }
protected:
private:

View File

@@ -97,6 +97,7 @@ ntlLightObject::getShadedColor(const ntlRay &reflectedRay, const ntlVec3Gfx ligh
*****************************************************************************/
void ntlLightObject::prepare( bool doCaustics )
{
doCaustics = false; // unused
if(!mActive) { return; }
}

View File

@@ -12,6 +12,23 @@
#include "ntl_scene.h"
/* Minimum value for refl/refr to be traced */
#define RAY_THRESHOLD 0.001
#if GFX_PRECISION==1
// float values
//! Minimal contribution for rays to be traced on
#define RAY_MINCONTRIB (1e-04)
#else
// double values
//! Minimal contribution for rays to be traced on
#define RAY_MINCONTRIB (1e-05)
#endif
/******************************************************************************
@@ -25,8 +42,8 @@ ntlRay::ntlRay( void )
, mpGlob(NULL)
, mIsRefracted(0)
{
errorOut("ntlRay::ntlRay() Error: don't use uninitialized rays !");
exit(-1);
errFatal("ntlRay::ntlRay()","Don't use uninitialized rays !", SIMWORLD_GENERICERROR);
return;
}
@@ -565,7 +582,6 @@ const ntlColor ntlRay::shade() //const
intersectionPosition2 += ( triangleNormal2*getVecEpsilon() );
reflectedRay = ntlRay(intersectionPosition2, reflectedDir, mDepth+1, mContribution*currRefl, mpGlob);
} else {
/*exit(-1);*/
// ray seems to work, continue normally ?
}

View File

@@ -15,27 +15,6 @@
#include "ntl_renderglobals.h"
/* Minimum value for refl/refr to be traced */
#define RAY_THRESHOLD 0.001
#if GFX_PRECISION==1
// float values
//! the minimal triangle determinant length
#define RAY_TRIANGLE_EPSILON (1e-08)
//! Minimal contribution for rays to be traced on
#define RAY_MINCONTRIB (1e-04)
#else
// double values
//! the minimal triangle determinant length
#define RAY_TRIANGLE_EPSILON (1e-15)
//! Minimal contribution for rays to be traced on
#define RAY_MINCONTRIB (1e-05)
#endif
//! store data for an intersection of a ray and a triangle
// NOT YET USED
class ntlIntersection {
@@ -84,8 +63,11 @@ public:
void intersectFrontAABB(ntlVec3Gfx mStart, ntlVec3Gfx mEnd, gfxReal &t, ntlVec3Gfx &normal, ntlVec3Gfx &retcoord) const;
void intersectBackAABB(ntlVec3Gfx mStart, ntlVec3Gfx mEnd, gfxReal &t, ntlVec3Gfx &normal, ntlVec3Gfx &retcoord) const;
void intersectCompleteAABB(ntlVec3Gfx mStart, ntlVec3Gfx mEnd, gfxReal &tmin, gfxReal &tmax) const;
// intersection routines in bsptree.cpp
//! optimized intersect ray with triangle
inline void intersectTriangle(vector<ntlVec3Gfx> *mpV, ntlTriangle *tri, gfxReal &t, gfxReal &u, gfxReal &v) const;
//! optimized intersect ray with triangle along +X axis dir
inline void intersectTriangleX(vector<ntlVec3Gfx> *mpV, ntlTriangle *tri, gfxReal &t, gfxReal &u, gfxReal &v) const;
//! intersect only with front side
inline void intersectTriangleFront(vector<ntlVec3Gfx> *mpV, ntlTriangle *tri, gfxReal &t, gfxReal &u, gfxReal &v) const;
//! intersect ray only with backsides
@@ -151,82 +133,9 @@ private:
/******************************************************************
* triangle intersection with triangle pointer,
* returns t,u,v by references
*/
inline void ntlRay::intersectTriangle(vector<ntlVec3Gfx> *mpV, ntlTriangle *tri, gfxReal &t, gfxReal &u, gfxReal &v) const
{
/* (cf. moeller&haines, page 305) */
t = GFX_REAL_MAX;
ntlVec3Gfx e0 = (*mpV)[ tri->getPoints()[0] ];
ntlVec3Gfx e1 = (*mpV)[ tri->getPoints()[1] ] - e0;
ntlVec3Gfx e2 = (*mpV)[ tri->getPoints()[2] ] - e0;
ntlVec3Gfx p = cross( mDirection, e2 );
gfxReal a = dot(e1, p);
if((a > -RAY_TRIANGLE_EPSILON)&&(a < RAY_TRIANGLE_EPSILON)) return;
gfxReal f = 1/a;
ntlVec3Gfx s = mOrigin - e0;
u = f * dot(s, p);
if( (u<0.0-RAY_TRIANGLE_EPSILON) || (u>1.0+RAY_TRIANGLE_EPSILON) ) return;
ntlVec3Gfx q = cross( s,e1 );
v = f * dot(mDirection, q);
if( (v<0.0-RAY_TRIANGLE_EPSILON) || ((u+v)>1.0+RAY_TRIANGLE_EPSILON) ) return;
t = f * dot(e2, q);
}
/******************************************************************
* intersect only front or backsides
*/
inline void ntlRay::intersectTriangleFront(vector<ntlVec3Gfx> *mpV, ntlTriangle *tri, gfxReal &t, gfxReal &u, gfxReal &v) const
{
t = GFX_REAL_MAX;
ntlVec3Gfx e0 = (*mpV)[ tri->getPoints()[0] ];
ntlVec3Gfx e1 = (*mpV)[ tri->getPoints()[1] ] - e0;
ntlVec3Gfx e2 = (*mpV)[ tri->getPoints()[2] ] - e0;
ntlVec3Gfx p = cross( mDirection, e2 );
gfxReal a = dot(e1, p);
//if((a > -RAY_TRIANGLE_EPSILON)&&(a < RAY_TRIANGLE_EPSILON)) return;
if(a < RAY_TRIANGLE_EPSILON) return; // cull backsides
gfxReal f = 1/a;
ntlVec3Gfx s = mOrigin - e0;
u = f * dot(s, p);
if( (u<0.0-RAY_TRIANGLE_EPSILON) || (u>1.0+RAY_TRIANGLE_EPSILON) ) return;
ntlVec3Gfx q = cross( s,e1 );
v = f * dot(mDirection, q);
if( (v<0.0-RAY_TRIANGLE_EPSILON) || ((u+v)>1.0+RAY_TRIANGLE_EPSILON) ) return;
t = f * dot(e2, q);
}
inline void ntlRay::intersectTriangleBack(vector<ntlVec3Gfx> *mpV, ntlTriangle *tri, gfxReal &t, gfxReal &u, gfxReal &v) const
{
t = GFX_REAL_MAX;
ntlVec3Gfx e0 = (*mpV)[ tri->getPoints()[0] ];
ntlVec3Gfx e1 = (*mpV)[ tri->getPoints()[1] ] - e0;
ntlVec3Gfx e2 = (*mpV)[ tri->getPoints()[2] ] - e0;
ntlVec3Gfx p = cross( mDirection, e2 );
gfxReal a = dot(e1, p);
//if((a > -RAY_TRIANGLE_EPSILON)&&(a < RAY_TRIANGLE_EPSILON)) return;
if(a > -RAY_TRIANGLE_EPSILON) return; // cull frontsides
gfxReal f = 1/a;
ntlVec3Gfx s = mOrigin - e0;
u = f * dot(s, p);
if( (u<0.0-RAY_TRIANGLE_EPSILON) || (u>1.0+RAY_TRIANGLE_EPSILON) ) return;
ntlVec3Gfx q = cross( s,e1 );
v = f * dot(mDirection, q);
if( (v<0.0-RAY_TRIANGLE_EPSILON) || ((u+v)>1.0+RAY_TRIANGLE_EPSILON) ) return;
t = f * dot(e2, q);
}
// triangle intersection code in bsptree.cpp
// intersectTriangle(vector<ntlVec3Gfx> *mpV, ntlTriangle *tri, gfxReal &t, gfxReal &u, gfxReal &v);
// ...

View File

@@ -68,13 +68,13 @@ ntlRaytracer::ntlRaytracer(string filename, bool commandlineMode) :
// load config
setPointers( getRenderGlobals() );
parseFile( filename.c_str() );
if(!SIMWORLD_OK()) return;
// init the scene for the first time
long startTime = getTime();
long sstartTime = getTime();
scene->buildScene();
long stopTime = getTime();
debMsgStd("ntlRaytracer::ntlRaytracer",DM_MSG,"Scene build time: "<< getTimeString(stopTime-startTime) <<" ", 10);
long sstopTime = getTime();
debMsgStd("ntlRaytracer::ntlRaytracer",DM_MSG,"Scene build time: "<< getTimeString(sstopTime-sstartTime) <<" ", 10);
// TODO check simulations, run first steps
mFirstSim = -1;
@@ -233,6 +233,10 @@ int ntlRaytracer::renderVisualization( bool multiThreaded )
warnMsg("ntlRaytracer::advanceSims","All sims panicked... stopping thread" );
setStopRenderVisualization( true );
}
if(!SIMWORLD_OK()) {
warnMsg("ntlRaytracer::advanceSims","World state error... stopping" );
setStopRenderVisualization( true );
}
//? mSimulationTime = (*mpSims)[mFirstSim]->getCurrentTime();
//debMsgStd("ntlRaytracer::renderVisualization : single step mode ", 10);
//debMsgStd("", 10 );
@@ -717,7 +721,7 @@ int ntlRaytracer::renderScene( void )
if(mpGlob->getSingleFrameMode() ) {
debMsgStd("ntlRaytracer::renderScene",DM_NOTIFY, "Single frame mode done...", 1 );
exit(1);
return 1;
}
return 0;
}

View File

@@ -94,8 +94,6 @@ class ntlRenderGlobals
inline void setAniFrames(int set) { mAniFrames = set; }
//! Set the animation
inline void setAniCount(int set) { mAniCount = set; }
//! Set the lbmsolver animation step size
inline void setAniFrameTime(int set) { mAniFrameTime=set; }
//! Set the ray counter
inline void setCounterRays(int set) { mCounterRays = set; }
//! Set the ray shades counter
@@ -170,8 +168,6 @@ class ntlRenderGlobals
inline int getCounterShades(void) { return mCounterShades; }
//! Return the scene intersection counter
inline int getCounterSceneInter(void) { return mCounterSceneInter; }
/*! Get auto run time variable */
inline int getAniFrameTime( void ) { return mAniFrameTime; }
//! Check if existing frames should be skipped
inline int getFrameSkip( void ) { return mFrameSkip; }
@@ -268,8 +264,6 @@ private:
int mAniFrames;
//! animation status, current frame number
int mAniCount;
/*! no. of steps for auto run (lbmsolver steps) */
int mAniFrameTime;
/*! Should existing picture frames be skipped? */
int mFrameSkip;
@@ -333,7 +327,7 @@ inline ntlRenderGlobals::ntlRenderGlobals() :
mFovy(45), mcBackgr(0.0,0.0,0.0), mcAmbientLight(0.0,0.0,0.0),
mDebugOut( 0 ),
mAniStart(0), mAniFrames( -1 ), mAniCount( 0 ),
mAniFrameTime(10), mFrameSkip( 0 ),
mFrameSkip( 0 ),
mCounterRays( 0 ), mCounterShades( 0 ), mCounterSceneInter( 0 ),
mOutFilename( "pic" ),
mTreeMaxDepth( 30 ), mTreeMaxTriangles( 30 ),

View File

@@ -87,8 +87,8 @@ void ntlScene::buildScene( void )
}
if(!geoinit) {
errMsg("ntlScene::BuildScene","Invalid geometry class!");
exit(1);
errFatal("ntlScene::BuildScene","Invalid geometry class!", SIMWORLD_INITERROR);
return;
}
}
@@ -175,16 +175,16 @@ void ntlScene::buildScene( void )
// check unused attributes (for classes and objects!)
for (vector<ntlGeometryObject*>::iterator iter = mObjects.begin(); iter != mObjects.end(); iter++) {
if((*iter)->getAttributeList()->checkUnusedParams()) {
debMsgStd("ntlScene::buildScene",DM_WARNING,"Unused params for object '"<< (*iter)->getName() <<"' !", 1 );
(*iter)->getAttributeList()->print(); // DEBUG
exit(1);
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()) {
debMsgStd("ntlScene::buildScene",DM_WARNING,"Unused params for object '"<< (*iter)->getName() <<"' !", 1 );
(*iter)->getAttributeList()->print(); // DEBUG
exit(1);
errFatal("ntlScene::buildScene","Unused params for object '"<< (*iter)->getName() <<"' !", SIMWORLD_INITERROR );
return;
}
}

View File

@@ -19,24 +19,17 @@ class ntlRay;
class ntlGeometryObject;
/*! 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_NO_BND (1<<(FGI_FLAGSTART+4))
#define FGI_ACC (1<<(FGI_FLAGSTART+5))
#define FGI_NO_ACC (1<<(FGI_FLAGSTART+6))
#define FGI_SPEEDSET (1<<(FGI_FLAGSTART+7))
#define FGI_NO_SPEEDSET (1<<(FGI_FLAGSTART+8))
#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)
#define FGI_REFP1 (1<<(FGI_FLAGSTART+0))
#define FGI_REFP2 (1<<(FGI_FLAGSTART+1))
#define FGI_REFP3 (1<<(FGI_FLAGSTART+2))
#define FGI_ALLREFS (FGI_REFP1 | FGI_REFP2 | FGI_REFP3)
#define FGI_ALLBOUNDS ( FGI_BNDNO | FGI_BNDFREE | FGI_BNDPART | FGI_MBNDINFLOW | FGI_MBNDOUTFLOW )
//! convenience macro for adding triangles
@@ -46,8 +39,8 @@ class ntlGeometryObject;
int tempVert;\
\
if(normals->size() != vertices->size()) {\
errorOut("getTriangles Error for '"<<mName<<"': Vertices and normals sizes to not match!!!");\
exit(1); }\
errFatal("getTriangles","For '"<<mName<<"': Vertices and normals sizes to not match!!!",SIMWORLD_GENERICERROR);\
} else {\
\
vertices->push_back( p1 ); \
normals->push_back( pn1 ); \
@@ -91,6 +84,7 @@ class ntlGeometryObject;
tri.setSmoothNormals( smooth );\
tri.setObjectId( objectId );\
triangles->push_back( tri ); \
} /* normals check*/ \
}\
@@ -109,17 +103,17 @@ public:
/*! Acces a certain object */
inline ntlGeometryObject *getObject(int id) {
if(!mSceneBuilt) { errMsg("ntlScene::getObject","Scene not inited!"); exit(1); }
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!"); exit(1); }
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!"); exit(1); }
if(!mSceneBuilt) { errMsg("ntlScene::getGeoClasses[]","Scene not inited!"); return NULL; }
return &mGeos; }
/*! draw scene with opengl */

View File

@@ -24,21 +24,17 @@ using std::vector;
using std::string;
#include <math.h>
#include <string.h>
#include <stdio.h>
#ifdef __APPLE_CC__
// apple
#else
#ifdef WIN32
// windos, hardcoded limits for now...
// windos fixes...
// for windos MSVC compiler...
#ifndef __FLT_MAX__
#define __FLT_MAX__ 3.402823466e+38f
#endif // __FLT_MAX__
#ifndef __DBL_MAX__
#define __DBL_MAX__ 1.7976931348623158e+308
#endif // __DBL_MAX__
// windows values missing, see below
#ifndef snprintf
#define snprintf _snprintf
#endif
#ifndef bool
#define bool int
#endif
@@ -48,12 +44,6 @@ using std::string;
#ifndef true
#define true 1
#endif
#ifndef snprintf
#define snprintf _snprintf
#endif
#ifndef M_PI
#define M_PI 3.1415926536
#endif
#else // WIN32
@@ -63,7 +53,28 @@ using std::string;
#endif // WIN32
#endif // __APPLE_CC__
// windos, hardcoded limits for now...
// for e.g. MSVC compiler...
// some of these defines can be needed
// for linux systems as well (e.g. FLT_MAX)
#ifndef __FLT_MAX__
# ifdef FLT_MAX // try to use it instead
# define __FLT_MAX__ FLT_MAX
# else // FLT_MAX
# define __FLT_MAX__ 3.402823466e+38f
# endif // FLT_MAX
#endif // __FLT_MAX__
#ifndef __DBL_MAX__
# ifdef DBL_MAX // try to use it instead
# define __DBL_MAX__ DBL_MAX
# else // DBL_MAX
# define __DBL_MAX__ 1.7976931348623158e+308
# endif // DBL_MAX
#endif // __DBL_MAX__
#ifndef M_PI
#define M_PI 3.1415926536
#endif
// basic inlined vector class
@@ -214,18 +225,18 @@ inline ntlVector3Dim<Scalar>::ntlVector3Dim( const ntlVector3Dim<Scalar> &v )
value[2] = v.value[2];
}
template<class Scalar>
inline ntlVector3Dim<Scalar>::ntlVector3Dim( const float *value)
inline ntlVector3Dim<Scalar>::ntlVector3Dim( const float *fvalue)
{
value[0] = (Scalar)value[0];
value[1] = (Scalar)value[1];
value[2] = (Scalar)value[2];
value[0] = (Scalar)fvalue[0];
value[1] = (Scalar)fvalue[1];
value[2] = (Scalar)fvalue[2];
}
template<class Scalar>
inline ntlVector3Dim<Scalar>::ntlVector3Dim( const double *value)
inline ntlVector3Dim<Scalar>::ntlVector3Dim( const double *fvalue)
{
value[0] = (Scalar)value[0];
value[1] = (Scalar)value[1];
value[2] = (Scalar)value[2];
value[0] = (Scalar)fvalue[0];
value[1] = (Scalar)fvalue[1];
value[2] = (Scalar)fvalue[2];
}
@@ -755,7 +766,6 @@ template<class T> inline ntlColor vec2Col(T v) { return ntlColor(v[0],v[1],v[2])
// use which fp-precision for raytracing? 1=float, 2=double
#define GFX_PRECISION 1
/* VECTOR_EPSILON is the minimal vector length
In order to be able to discriminate floating point values near zero, and

View File

@@ -50,7 +50,8 @@ Parametrizer::Parametrizer( void ) :
mStepTime(0.01), mDesiredStepTime(-1.0),
mSizex(50), mSizey(50), mSizez(50),
mTimeFactor( 1.0 ),
mAniFrames(0), mAniFrameTime(0.0), mAniStart(0.0),
//mAniFrames(0),
mAniFrameTime(0.0), mAniStart(0.0),
mExtent(1.0, 1.0, 1.0), mSurfaceTension( 0.0 ),
mDensity(1000.0), mGStar(0.0001), mFluidVolumeHeight(0.0),
mMaxSpeed(0.0), mSimulationMaxSpeed(0.0),
@@ -75,8 +76,8 @@ Parametrizer::~Parametrizer()
void Parametrizer::parseAttrList()
{
if(!mpAttrs) {
errMsg("Parametrizer::parseAttrList", "mpAttrs pointer not initialized!");
exit(1);
errFatal("Parametrizer::parseAttrList", "mpAttrs pointer not initialized!", SIMWORLD_INITERROR);
return;
}
//mActive = mpAttrs->readBool("p_active",mActive, "Parametrizer","mActive", false);
@@ -99,18 +100,12 @@ void Parametrizer::parseAttrList()
mGravity = mpAttrs->readVec3d("p_gravity",mGravity, "Parametrizer","mGravity", false);
if(getAttributeList()->exists("p_gravity")) seenThis( PARAM_GRAVITY );
//mTimeLength = mpAttrs->readFloat("p_timelength",mTimeLength, "Parametrizer","mTimeLength", false);
//if(getAttributeList()->exists("p_timelength")) seenThis( PARAM_TIMELENGTH );
mStepTime = mpAttrs->readFloat("p_steptime",mStepTime, "Parametrizer","mStepTime", 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 );
mAniFrames = mpAttrs->readInt("p_aniframes",mAniFrames, "Parametrizer","mAniFrames", false);
if(getAttributeList()->exists("p_aniframes")) seenThis( PARAM_ANIFRAMES );
mAniFrameTime = mpAttrs->readFloat("p_aniframetime",mAniFrameTime, "Parametrizer","mAniFrameTime", false);
if(getAttributeList()->exists("p_aniframetime")) seenThis( PARAM_ANIFRAMETIME );
if(mAniFrameTime<=0.0) {
@@ -202,11 +197,11 @@ int Parametrizer::calculateAniStart( void ) {
return (int)(mAniStart/mStepTime);
}
/*! get no of steps for a singel animation frame */
/*! get no of steps for a single animation frame */
int Parametrizer::calculateAniStepsPerFrame( void ) {
if(!checkSeenValues(PARAM_ANIFRAMETIME)) {
errMsg("Parametrizer::calculateAniStepsPerFrame", " Missing ani frame time argument!");
exit(1);
errFatal("Parametrizer::calculateAniStepsPerFrame", " Missing ani frame time argument!", SIMWORLD_INITERROR);
return 1;
}
return (int)(mAniFrameTime/mStepTime);
}
@@ -449,14 +444,11 @@ bool Parametrizer::calculateAllMissingValues( bool silent )
mExtent = ParamVec( mCellSize*mSizex, mCellSize*mSizey, mCellSize*mSizez );
if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," domain extent = "<<PRINT_NTLVEC(mExtent)<<"m ",1);
if(checkSeenValues(PARAM_ANIFRAMETIME)) {
if(checkSeenValues(PARAM_ANIFRAMES)) {
if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," Warning - ani frame time and ani frames given!", 1);
exit(1);
}
} else {
mAniFrameTime = mAniFrames * mStepTime;
}
if(!checkSeenValues(PARAM_ANIFRAMETIME)) {
errFatal("Parametrizer::calculateAllMissingValues"," Warning no ani frame time given!", SIMWORLD_INITERROR);
mAniFrameTime = mStepTime;
}
//mAniFrameTime = mAniFrames * mStepTime;
if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," ani frame steps = "<<calculateAniStepsPerFrame()<<" ", 1);
if((checkSeenValues(PARAM_ANISTART))&&(calculateAniStart()>0)) {

View File

@@ -25,11 +25,9 @@ typedef ntlVec3d ParamVec;
#define PARAM_SOUNDSPEED (1<< 3)
#define PARAM_DOMAINSIZE (1<< 4)
#define PARAM_GRAVITY (1<< 5)
#define PARAM_TIMELENGTH (1<< 6)
#define PARAM_STEPTIME (1<< 7)
#define PARAM_SIZE (1<< 8)
#define PARAM_TIMEFACTOR (1<< 9)
#define PARAM_ANIFRAMES (1<<10)
#define PARAM_ANIFRAMETIME (1<<11)
#define PARAM_ANISTART (1<<12)
#define PARAM_SURFACETENSION (1<<13)
@@ -42,9 +40,6 @@ typedef ntlVec3d ParamVec;
#define PARAM_NORMALIZEDGSTAR (1<<20)
#define PARAM_NUMIDS 21
//! parameters to ignore for parametrizer activation
#define PARAM_IGNORE (~(PARAM_ANIFRAMES|PARAM_SIZE))
//! output parameter debug message?
//#define PARAM_DEBUG 1
@@ -68,7 +63,6 @@ class Parametrizer {
bool calculateAllMissingValues( bool silent = false );
bool oldCalculateAllMissingValues( void );
/*! is the parametrizer used at all? */
//bool isUsed() { if(!mActive){ return false; } return(mSeenValues!=(~PARAM_IGNORE)); }
bool isUsed() { return true; }
/*! add this flag to the seen values */
@@ -98,7 +92,6 @@ class Parametrizer {
/*! get omega for LBM */
ParamFloat calculateOmega( void );
/*! get no. of timesteps for LBM */
//int calculateNoOfSteps( void ) { return (int)(mTimeLength/mStepTime); }
int calculateNoOfSteps( ParamFloat timelen );
/*! get external force x component */
ParamVec calculateGravity( void );
@@ -149,11 +142,6 @@ class Parametrizer {
void setGravity(ParamFloat setx, ParamFloat sety, ParamFloat setz) { mGravity = ParamVec(setx,sety,setz); seenThis( PARAM_GRAVITY ); }
void setGravity(ParamVec set) { mGravity = set; seenThis( PARAM_GRAVITY ); }
/*! set the length of the simulation */
//void setTimeLength(ParamFloat set) { mTimeLength = set; seenThis( PARAM_TIMELENGTH ); }
/*! get the length of the simulation */
//ParamFloat getTimeLength( void ) { return mTimeLength; }
/*! set the length of a single time step */
void setStepTime(ParamFloat set) { mStepTime = set; seenThis( PARAM_STEPTIME ); }
/*! get the length of a single time step */
@@ -174,11 +162,6 @@ class Parametrizer {
void setSize(int ijk) { mSizex = ijk; mSizey = ijk; mSizez = ijk; seenThis( PARAM_SIZE ); }
void setSize(int i,int j, int k) { mSizex = i; mSizey = j; mSizez = k; seenThis( PARAM_SIZE ); }
/*! set no of animation steps (renderer) */
void setAniFrames(int set) { mAniFrames = set; seenThis( PARAM_ANIFRAMES ); }
/*! get no of animation steps (renderer) */
int getAniFrames( void ) { return mAniFrames; }
/*! set time of an animation frame (renderer) */
void setAniFrameTime(ParamFloat set) { mAniFrameTime = set; seenThis( PARAM_ANIFRAMETIME ); }
/*! get time of an animation frame (renderer) */
@@ -297,8 +280,6 @@ class Parametrizer {
/*! force converted to lattice units (returned by calc gravity) */
ParamVec mLatticeGravity;
/*! lenth of the simulation [s] */
//ParamFloat mTimeLength;
/*! length of one time step in the simulation */
ParamFloat mStepTime;
@@ -313,9 +294,6 @@ class Parametrizer {
/*! time scaling factor (auto calc from accel, or set), equals the delta t in LBM */
ParamFloat mTimeFactor;
/*! from renderer - no of animation frames for the animation (same as mpglob mAniFrames) */
int mAniFrames;
/*! for renderer - length of an animation step [s] */
ParamFloat mAniFrameTime;

View File

@@ -118,9 +118,9 @@ void ParticleTracer::savePreviousPositions()
//errMsg("spp"," PARTS SIZE "<<mParts.size() );
for(size_t l=mParts.size()-1; l>0; l--) {
if( mParts[l].size() != mParts[l-1].size() ) {
errorOut("ParticleTracer::savePreviousPositions error: Invalid array sizes ["<<l<<"]="<<mParts[l].size()<<
" ["<<(l+1)<<"]="<<mParts[l+1].size() <<" , total "<< mParts.size() );
exit(1);
errFatal("ParticleTracer::savePreviousPositions","Invalid array sizes ["<<l<<"]="<<mParts[l].size()<<
" ["<<(l+1)<<"]="<<mParts[l+1].size() <<" , total "<< mParts.size() , SIMWORLD_GENERICERROR);
return;
}
for(size_t i=0; i<mParts[l].size(); i++) {

View File

@@ -71,7 +71,10 @@ SimulationObject::~SimulationObject()
/*! init tree for certain geometry init */
/*****************************************************************************/
void SimulationObject::initGeoTree(int id) {
if(mpGlob == NULL) { errorOut("SimulationObject::initGeoTree error: Requires globals!"); exit(1); }
if(mpGlob == NULL) {
errFatal("SimulationObject::initGeoTree error","Requires globals!", SIMWORLD_INITERROR);
return;
}
mGeoInitId = id;
ntlScene *scene = mpGlob->getScene();
mpGiObjects = scene->getObjects();
@@ -113,15 +116,15 @@ int SimulationObject::initializeLbmSimulation(ntlRenderGlobals *glob)
mpLbm = createSolverOld();
#endif // LBM_TESTSOLVER
} else {
errorOut("SimulationObject::initializeLbmSimulation : Invalid solver type - note that mDimension is deprecated, use the 'solver' keyword instead");
exit(1);
errFatal("SimulationObject::initializeLbmSimulation","Invalid solver type - note that mDimension is deprecated, use the 'solver' keyword instead", SIMWORLD_INITERROR);
return 1;
}
/* check lbm pointer */
if(mpLbm == NULL) {
errorOut("SimulationObject::initializeLbmSimulation : Unable to init dim"<<mSolverType<<" LBM solver! ");
exit(1);
errFatal("SimulationObject::initializeLbmSimulation","Unable to init dim"<<mSolverType<<" LBM solver! ", SIMWORLD_INITERROR);
return 1;
}
debugOut("SimulationObject::initialized "<< mpLbm->getIdString() <<" LBM solver! ", 2);
@@ -300,8 +303,8 @@ void SimulationObject::drawDebugDisplay() {
if(!getVisible()) return;
if( mDebugType > (MAX_DEBDISPSET-1) ){
errorOut("SimulationObject::drawDebugDisplay : Invalid debug type!");
exit(1);
errFatal("SimulationObject::drawDebugDisplay","Invalid debug type!", SIMWORLD_GENERICERROR);
return;
}
mDebDispSet[ mDebugType ].on = true;

View File

@@ -29,6 +29,18 @@
#endif
#endif // NOPNG
// global debug level
#ifdef DEBUG
int gDebugLevel = DEBUG;
#else // DEBUG
int gDebugLevel = 0;
#endif // DEBUG
// global world state
int gWorldState = SIMWORLD_INVALID;
// last error as string
char gWorldStringState[256] = {'-','\0' };
//! for interval debugging output
myTime_t globalIntervalTime = 0;
//! color output setting for messages (0==off, else on)
@@ -190,8 +202,8 @@ bool checkBoundingBox(ntlVec3Gfx s, ntlVec3Gfx e, std::string checker) {
if( (s[0]>e[0]) ||
(s[1]>e[1]) ||
(s[2]>e[2]) ) {
errMsg("checkBoundingBox","Check by '"<<checker<<"' for BB "<<s<<":"<<e<<" failed! Aborting...");
exit(1);
errFatal("checkBoundingBox","Check by '"<<checker<<"' for BB "<<s<<":"<<e<<" failed! Aborting...",SIMWORLD_INITERROR);
return 1;
}
return 0;
}
@@ -227,7 +239,7 @@ void messageOutputFunc(std::string from, int id, std::string msg, myTime_t inter
}
// colors off?
if(globalColorSetting==0) {
if((globalColorSetting==0) || (id==DM_FATAL) ){
// only reset once
col_std = col_black = col_dark_gray = col_bright_gray =
col_red = col_bright_red = col_green =
@@ -258,14 +270,25 @@ void messageOutputFunc(std::string from, int id, std::string msg, myTime_t inter
case DM_ERROR:
sout << col_red << " error:" << col_red;
break;
case DM_FATAL:
sout << col_red << " fatal("<<gWorldState<<"):" << col_red;
break;
default:
// this shouldnt happen...
sout << col_red << " --- messageOutputFunc error: invalid id ("<<id<<") --- aborting... \n\n" << col_std;
exit(1);
//xit(1); // unecessary?
break;
}
sout <<" "<< msg << col_std;
}
if(id==DM_FATAL) {
strncpy(gWorldStringState,sout.str().c_str(), 256);
// dont print?
if(gDebugLevel==0) return;
sout << "\n"; // add newline for output
}
#ifdef ELBEEM_BLENDER
fprintf(GEN_userstream, "%s",sout.str().c_str() );
if(id!=DM_DIRECT) fflush(GEN_userstream);
@@ -288,5 +311,8 @@ bool debugOutInterTest(myTime_t interval) {
#endif
//-----------------------------------------------------------------------------
// save exit function

View File

@@ -17,14 +17,6 @@ int convertString2Int(const char *string, int alt);
//! helper function that converts a flag field to a readable integer
std::string convertFlags2String(int flags);
//! write png image
#ifndef NOPNG
//int writePng(const char *fileName, unsigned char **rows, int w, int h, int colortype, int bitdepth);
int writePng(const char *fileName, unsigned char **rows, int w, int h);
//! write opengl buffer to png
void writeOpenglToPng(const char *fileName);
#endif// NOPNG
// output streams
#ifdef ELBEEM_BLENDER
extern "C" FILE* GEN_errorstream;
@@ -39,17 +31,32 @@ std::string getTimeString(myTime_t usecs);
//! helper to check if a bounding box was specified in the right way
bool checkBoundingBox(ntlVec3Gfx s, ntlVec3Gfx e, std::string checker);
// optionally include OpenGL utility functions
#ifdef USE_GLUTILITIES
void drawCubeWire(ntlVec3Gfx s, ntlVec3Gfx e);
void drawCubeSolid(ntlVec3Gfx s, ntlVec3Gfx e);
/* debugging outputs , debug level 0 (off) to 10 (max) */
#ifdef ELBEEM_BLENDER
#define DEBUG 0
#else // ELBEEM_BLENDER
#define DEBUG 10
#endif // ELBEEM_BLENDER
extern "C" int gDebugLevel;
#endif // USE_GLUTILITIES
/* debugging outputs */
//#define DEBUG 10
// state of the simulation world
// default
#define SIMWORLD_INVALID 0
// after init, before starting simulation
#define SIMWORLD_INITED 1
// error during init
#define SIMWORLD_INITERROR -1
// error during simulation
#define SIMWORLD_PANIC -2
// general error
#define SIMWORLD_GENERICERROR -3
// global world state
extern "C" int gWorldState;
// last error as string
extern "C" char gWorldStringState[256];
// check world status macro
#define SIMWORLD_OK() (gWorldState>=0)
/* debug output function */
#define DM_MSG 1
@@ -58,25 +65,30 @@ void drawCubeSolid(ntlVec3Gfx s, ntlVec3Gfx e);
#define DM_WARNING 4
#define DM_ERROR 5
#define DM_DIRECT 6
#define DM_FATAL 7
void messageOutputFunc(std::string from, int id, std::string msg, myTime_t interval);
/* debugging messages defines */
#ifdef DEBUG
#if LBM_PRECISION==2
#define MSGSTREAM std::ostringstream msg; msg.precision(15); msg.width(17);
#else
#define MSGSTREAM std::ostringstream msg; msg.precision(7); msg.width(9);
#endif
#ifdef DEBUG
# define debMsgDirect(mStr) { std::ostringstream msg; msg << mStr; messageOutputFunc(string(""), DM_DIRECT, msg.str(), 0); }
# define debMsgStd(from,id,mStr,level) if(DEBUG>=level){ MSGSTREAM; msg << mStr <<"\n"; messageOutputFunc(from, id, msg.str(), 0); }
# define debMsgNnl(from,id,mStr,level) if(DEBUG>=level){ MSGSTREAM; msg << mStr ; messageOutputFunc(from, id, msg.str(), 0); }
# define debMsgInter(from,id,mStr,level, interval) if(DEBUG>=level){ MSGSTREAM; msg << mStr <<"\n"; messageOutputFunc(from, id, msg.str(), interval); }
# define debugOut(mStr,level) if(DEBUG>=level){ debMsgStd("D",DM_MSG,mStr,level); }
# define debugOutNnl(mStr,level) if(DEBUG>=level){ debMsgNnl("D",DM_MSG,mStr,level); }
# define debugOutInter(mStr,level, interval) debMsgInter("D",DM_MSG,mStr,level, interval);
# define debMsgDirect(mStr) if(gDebugLevel>0) { std::ostringstream msg; msg << mStr; messageOutputFunc(string(""), DM_DIRECT, msg.str(), 0); }
# define debMsgStd(from,id,mStr,level) if(gDebugLevel>=level) { MSGSTREAM; msg << mStr <<"\n"; messageOutputFunc(from, id, msg.str(), 0); }
# define debMsgNnl(from,id,mStr,level) if(gDebugLevel>=level) { MSGSTREAM; msg << mStr ; messageOutputFunc(from, id, msg.str(), 0); }
# define debMsgInter(from,id,mStr,level, interval) if(gDebugLevel>=level) { MSGSTREAM; msg << mStr <<"\n"; messageOutputFunc(from, id, msg.str(), interval); }
# define debugOut(mStr,level) if(gDebugLevel>=level) { debMsgStd("D",DM_MSG,mStr,level); }
# define debugOutNnl(mStr,level) if(gDebugLevel>=level) { debMsgNnl("D",DM_MSG,mStr,level); }
# define debugOutInter(mStr,level, interval) debMsgInter("D",DM_MSG ,mStr,level, interval);
/* Error output function */
#define errMsg(from,mStr) if(gDebugLevel>0){ MSGSTREAM; msg << mStr <<"\n"; messageOutputFunc(from, DM_ERROR, msg.str(), 0); }
#define warnMsg(from,mStr) if(gDebugLevel>0){ MSGSTREAM; msg << mStr <<"\n"; messageOutputFunc(from, DM_WARNING, msg.str(), 0); }
#else
// no messages at all...
# define debMsgDirect(mStr)
# define debMsgStd(from,id,mStr,level)
# define debMsgNnl(from,id,mStr,level)
@@ -84,13 +96,18 @@ void messageOutputFunc(std::string from, int id, std::string msg, myTime_t inter
# define debugOut(mStr,level)
# define debugOutNnl(mStr,level)
# define debugOutInter(mStr,level, interval)
# define errMsg(from,mStr)
# define warnMsg(from,mStr)
#endif
/* Error output function */
#define errMsg(from,mStr) { MSGSTREAM; msg << mStr <<"\n"; messageOutputFunc(from, DM_ERROR, msg.str(), 0); }
#define warnMsg(from,mStr){ MSGSTREAM; msg << mStr <<"\n"; messageOutputFunc(from, DM_WARNING, msg.str(), 0); }
#define errorOut(mStr) { errMsg("D",mStr); }
// old... #define ...(mStr) { std::cout << mStr << "\n"; fflush(stdout); }
// fatal errors - have to be handled
#define errFatal(from,mStr,errCode) { \
gWorldState = errCode; \
MSGSTREAM; msg << mStr; \
messageOutputFunc(from, DM_FATAL, msg.str(), 0); \
}
/*! print some vector from 3 values e.g. for ux,uy,uz */
#define PRINT_VEC(x,y,z) " ["<<(x)<<","<<(y)<<","<<(z)<<"] "
@@ -119,6 +136,10 @@ void messageOutputFunc(std::string from, int id, std::string msg, myTime_t inter
PRINT_VEC( (mpV[(t).getPoints()[2]][0]),(mpV[(t).getPoints()[2]][1]),(mpV[(t).getPoints()[2]][2]) )<<" } "
#ifndef NOPNG
// write png image
int writePng(const char *fileName, unsigned char **rowsp, int w, int h);
#endif // NOPNG
/* some useful templated functions
* may require some operators for the classes

View File

@@ -1473,14 +1473,6 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], DerivedM
if (deform_r) *deform_r = NULL;
*final_r = NULL;
// N_T
if((G.obedit!=ob) && (ob->fluidsimFlag & OB_FLUIDSIM_ENABLE)) {
if(ob->fluidsimSettings->type & OB_FLUIDSIM_DOMAIN) {
*final_r = getFluidsimDerivedMesh(ob,useRenderParams, NULL,NULL);
if(*final_r) return;
}
}
if (useDeform) {
do_mesh_key(me);
@@ -1508,6 +1500,17 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], DerivedM
deformedVerts = inputVertexCos;
}
/* N_T
* i dont know why, but somehow the if(useDeform) part
* is necessary to get anything displayed
*/
if((G.obedit!=ob) && (ob->fluidsimFlag & OB_FLUIDSIM_ENABLE)) {
if(ob->fluidsimSettings->type & OB_FLUIDSIM_DOMAIN) {
*final_r = getFluidsimDerivedMesh(ob,useRenderParams, NULL,NULL);
if(*final_r) return;
}
}
/* Now apply all remaining modifiers. If useDeform is off then skip
* OnlyDeform ones.
*/
@@ -1950,7 +1953,9 @@ DerivedMesh *editmesh_get_derived_base(void)
return getEditMeshDerivedMesh(G.editMesh, NULL);
}
// N_T fluidsim declarations
/* ***************************** fluidsim derived mesh ***************************** */
typedef struct {
MeshDerivedMesh mdm;
@@ -1958,9 +1963,6 @@ typedef struct {
char freeMesh;
} FluidsimDerivedMesh;
/***/
// N_T fluidsim interface
#ifdef WIN32
#ifndef snprintf
#define snprintf _snprintf
@@ -2026,8 +2028,14 @@ DerivedMesh *getFluidsimDerivedMesh(Object *srcob, int useRenderParams, float *e
mesh = srcob->data;
return getMeshDerivedMesh(mesh , srcob, NULL);
}
if((mesh)&&(mesh->totvert>0)) {
make_edges(mesh, 0); // 0 = make all edges draw
// force all edge draw
for(i=0;i<mesh->totedge;i++) {
//mesh->medge[i].flag = ME_EDGEDRAW;
//fprintf(stderr,"me %d = %d\n",i,mesh->medge[i].flag);
}
}
// WARNING copied from getMeshDerivedMesh
@@ -2064,29 +2072,10 @@ DerivedMesh *getFluidsimDerivedMesh(Object *srcob, int useRenderParams, float *e
mdm->freeNors = 0;
mdm->freeVerts = 0;
//fprintf(stderr,"fsdm loc %f,%f,%f; size %f,%f,%f; rot %f,%f,%f \n",
//mesh->loc[0], mesh->loc[1], mesh->loc[2],
//mesh->size[0], mesh->size[1], mesh->size[2],
//mesh->rot[0], mesh->rot[1], mesh->rot[2]);
if (vertCos) {
int i;
mdm->verts = MEM_mallocN(sizeof(*mdm->verts)*mdm->me->totvert, "deformedVerts");
for (i=0; i<mdm->me->totvert; i++) {
mdm->verts[i].co[0] = vertCos[i][0];
mdm->verts[i].co[1] = vertCos[i][1];
mdm->verts[i].co[2] = vertCos[i][2];
}
mesh_calc_normals(mdm->verts, mdm->me->totvert, mdm->me->mface, mdm->me->totface, &mdm->nors);
mdm->freeNors = 1;
mdm->freeVerts = 1;
} else {
// XXX this is kinda ... see getMeshDerivedMesh
mesh_calc_normals(mdm->verts, mdm->me->totvert, mdm->me->mface, mdm->me->totface, &mdm->nors);
mdm->freeNors = 1;
}
/* if (vertCos) { not needed for fluid meshes... */
// XXX this is kinda ... see getMeshDerivedMesh
mesh_calc_normals(mdm->verts, mdm->me->totvert, mdm->me->mface, mdm->me->totface, &mdm->nors);
mdm->freeNors = 1;
return (DerivedMesh*) mdm;
}
@@ -2097,6 +2086,7 @@ DerivedMesh *getFluidsimDerivedMesh(Object *srcob, int useRenderParams, float *e
void writeBobjgz(char *filename, struct Object *ob)
{
const int debugBobjWrite = 0;
int wri,i,j;
float wrf;
gzFile gzf;
@@ -2114,7 +2104,7 @@ void writeBobjgz(char *filename, struct Object *ob)
fprintf(stderr,"\nfluidSim::writeBobjgz:: Warning object %s has negative scaling - check triangle ordering...?\n\n", ob->id.name);
}
fprintf(stderr,"Writing GZ_BOBJ '%s' ... ",filename);
if(debugBobjWrite) fprintf(stderr,"Writing GZ_BOBJ '%s' ... ",filename);
gzf = gzopen(filename, "wb9");
if (!gzf) {
fprintf(stderr,"writeBobjgz::error - Unable to open file for writing '%s'\n", filename);
@@ -2131,7 +2121,6 @@ void writeBobjgz(char *filename, struct Object *ob)
for(i=0; i<wri;i++) {
VECCOPY(vec, dlm->mvert[i].co); /* get transformed point */
Mat4MulVecfl(ob->obmat, vec);
//fprintf(stderr,"VTEST %d = %f,%f,%f\n",i,vec[0],vec[1],vec[2]); // DEBUG
for(j=0; j<3; j++) {
wrf = vec[j];
gzwrite(gzf, &wrf, sizeof( wrf ));
@@ -2147,9 +2136,8 @@ void writeBobjgz(char *filename, struct Object *ob)
// FIXME divide? mv->no[0]= (short)(no[0]*32767.0);
Mat3MulVecfl(rotmat, vec);
Normalise(vec);
//fprintf(stderr, "N %s normrot %d %f %f %f\n",ob->id.name, i,vec[0],vec[1],vec[2]); // DEBUG
for(j=0; j<3; j++) {
wrf = vec[j]; //dlm->normals[i][j];
wrf = vec[j];
gzwrite(gzf, &wrf, sizeof( wrf ));
}
}
@@ -2185,37 +2173,29 @@ void writeBobjgz(char *filename, struct Object *ob)
if(dlm) displistmesh_free(dlm);
dm->release(dm);
//fprintf(stderr,"done. #Vertices: %d, #Normals: %d, #Triangles: %d\n", dlm->vertices.size(), dlm->normals.size(), dlm->faces.size() );
if(debugBobjWrite) fprintf(stderr,"done. #Vertices: %d, #Triangles: %d\n", dlm->totvert, dlm->totface );
}
/* security macro for readgin bobjs */
#define CHECK_GOTBYTES(b,s) \
if((b)!=4) { \
if(newmesh->mvert) MEM_freeN(newmesh->mvert); \
if(newmesh->mface) MEM_freeN(newmesh->mface); \
if(newmesh) MEM_freeN(newmesh); \
return NULL; \
}
/* read .bobj.gz file into a fluidsimDerivedMesh struct */
Mesh* readBobjgz(char *filename, Mesh *orgmesh) //, fluidsimDerivedMesh *fsdm)
{
int wri,i,j;
float wrf;
gzFile gzf;
Mesh *newmesh;
const int debugOutput = 0;
const int debugBobjRead = 0;
// init data from old mesh (materials,flags)
MFace *origMFace = &((MFace*) orgmesh->mface)[0];
int mat_nr = origMFace->mat_nr;
int flag = origMFace->flag;
MFace *fsface = NULL;
int gotBytes;
gzFile gzf;
if(!orgmesh) return NULL;
// similar to copy_mesh
newmesh = MEM_dupallocN(orgmesh);
newmesh->mat= orgmesh->mat; //MEM_dupallocN(orgmesh->mat); // use original?
newmesh->mat= orgmesh->mat;
newmesh->mvert= NULL;
newmesh->medge= NULL;
@@ -2223,21 +2203,23 @@ Mesh* readBobjgz(char *filename, Mesh *orgmesh) //, fluidsimDerivedMesh *fsdm)
newmesh->tface= NULL;
newmesh->dface= NULL;
newmesh->dvert = NULL; //MEM_mallocN (sizeof (MDeformVert)*orgmesh->totvert, "MDeformVert");
newmesh->dvert = NULL;
newmesh->mcol= NULL; //MEM_dupallocN(orgmesh->mcol);
newmesh->msticky= NULL; //MEM_dupallocN(orgmesh->msticky);
newmesh->mcol= NULL;
newmesh->msticky= NULL;
newmesh->texcomesh= NULL;
newmesh->key= NULL; //copy_key(orgmesh->key);
newmesh->key= NULL;
newmesh->totface = 0;
newmesh->totvert = 0;
newmesh->totedge = 0;
newmesh->medge = NULL; //? MEM_mallocN(sizeof(MEdge)*fsdm->fstotedge, "fluidsimDerivedMesh_edges");
newmesh->medge = NULL;
if(debugOutput) fprintf(stderr,"Reading '%s' GZ_BOBJ... ",filename);
if(debugBobjRead) fprintf(stderr,"Reading '%s' GZ_BOBJ... ",filename);
gzf = gzopen(filename, "rb");
// gzf = fopen(filename, "rb");
// debug: fread(b,c,1,a) = gzread(a,b,c)
if (!gzf) {
//fprintf(stderr,"readBobjgz::error - Unable to open file for reading '%s'\n", filename); // DEBUG
MEM_freeN(newmesh);
@@ -2245,24 +2227,22 @@ Mesh* readBobjgz(char *filename, Mesh *orgmesh) //, fluidsimDerivedMesh *fsdm)
}
//if(sizeof(wri)!=4) { fprintf(stderr,"Reading GZ_BOBJ, Invalid int size %d...\n", wri); return NULL; } // paranoia check
gotBytes = gzread(gzf, &wri, sizeof(wri));
CHECK_GOTBYTES(gotBytes, "numverts");
newmesh->totvert = wri;
newmesh->mvert = MEM_mallocN(sizeof(MVert)*newmesh->totvert, "fluidsimDerivedMesh_bobjvertices");
if(debugOutput) fprintf(stderr,"#vertices %d ", newmesh->totvert); //DEBUG
newmesh->mvert = MEM_callocN(sizeof(MVert)*newmesh->totvert, "fluidsimDerivedMesh_bobjvertices");
if(debugBobjRead) fprintf(stderr,"#vertices %d ", newmesh->totvert); //DEBUG
for(i=0; i<newmesh->totvert;i++) {
//if(debugBobjRead) fprintf(stderr,"V %d = ",i);
for(j=0; j<3; j++) {
gotBytes = gzread(gzf, &wrf, sizeof( wrf ));
CHECK_GOTBYTES(gotBytes, "vert");
newmesh->mvert[i].co[j] = wrf;
//if(debugBobjRead) fprintf(stderr,"%25.20f ", wrf);
}
//fprintf(stderr,"VTEST %d = %f,%f,%f\n",i,newmesh->mvert[i].co[0],newmesh->mvert[i].co[1],newmesh->mvert[i].co[2]); // DEBUG
//if(debugBobjRead) fprintf(stderr,"\n");
}
// should be the same as Vertices.size
gotBytes = gzread(gzf, &wri, sizeof(wri));
CHECK_GOTBYTES(gotBytes, "numnorms");
if(wri != newmesh->totvert) {
// complain #vertices has to be equal to #normals, reset&abort
MEM_freeN(newmesh->mvert);
@@ -2273,7 +2253,6 @@ 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 ));
CHECK_GOTBYTES(gotBytes, "norm");
newmesh->mvert[i].no[j] = wrf*32767.0;
}
}
@@ -2281,37 +2260,47 @@ Mesh* readBobjgz(char *filename, Mesh *orgmesh) //, fluidsimDerivedMesh *fsdm)
/* compute no. of triangles */
gotBytes = gzread(gzf, &wri, sizeof(wri));
CHECK_GOTBYTES(gotBytes, "numfaces");
newmesh->totface = wri;
newmesh->mface = MEM_mallocN(sizeof(MFace)*newmesh->totface, "fluidsimDerivedMesh_bobjfaces");
if(debugOutput) fprintf(stderr,"#faces %d ", newmesh->totface); // DEBUG
newmesh->mface = MEM_callocN(sizeof(MFace)*newmesh->totface, "fluidsimDerivedMesh_bobjfaces");
if(debugBobjRead) fprintf(stderr,"#faces %d ", newmesh->totface); // DEBUG
fsface = newmesh->mface;
for(i=0; i<newmesh->totface; i++) {
int face[4];
gotBytes = gzread(gzf, &(face[0]), sizeof( face[0] ));
CHECK_GOTBYTES(gotBytes, "f1");
gotBytes = gzread(gzf, &(face[1]), sizeof( face[1] ));
CHECK_GOTBYTES(gotBytes, "f2");
gotBytes = gzread(gzf, &(face[2]), sizeof( face[2] ));
CHECK_GOTBYTES(gotBytes, "f3");
face[3] = 0;
fsface[i].v1 = face[0];
fsface[i].v2 = face[1];
fsface[i].v3 = face[2];
fsface[i].v4 = face[3];
//fprintf(stderr,"F %s %d = %d,%d,%d,%d \n",newmesh->ob->id.name, i, face[0],face[1],face[2],face[3] );
}
/*if(debugBobjRead) {
for(i=0; i<newmesh->totvert; i++) { fprintf(stderr,"V %d = %f,%f,%f \n",i, newmesh->mvert[i].co[0],newmesh->mvert[i].co[1],newmesh->mvert[i].co[2] ); }
for(i=0; i<newmesh->totface; i++) { fprintf(stderr,"F %d = %d,%d,%d,%d \n",i, fsface[i].v1,fsface[i].v2,fsface[i].v3,fsface[i].v4); }
} // debug */
// correct triangles with v3==0 for blender, cycle verts
for(i=0; i<newmesh->totface; i++) {
if(!fsface[i].v3) {
int temp = fsface[i].v1;
fsface[i].v1 = fsface[i].v2;
fsface[i].v2 = fsface[i].v3;
fsface[i].v3 = temp;
}
}
gzclose( gzf );
for(i=0;i<newmesh->totface;i++) {
fsface[i].mat_nr = mat_nr;
fsface[i].flag = flag;
fsface[i].edcode = ME_V1V2 | ME_V2V3 | ME_V3V1;
//fprintf(stderr,"%d : %d,%d,%d\n", i,fsface[i].mat_nr, fsface[i].flag, fsface[i].edcode );
}
// if(debugOutput) fprintf(stderr," done\n");
if(debugBobjRead) fprintf(stderr," done\n");
return newmesh;
}

View File

@@ -51,6 +51,7 @@
#include "DNA_lattice_types.h"
#include "DNA_scene_types.h"
#include "DNA_camera_types.h"
#include "DNA_screen_types.h"
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
@@ -226,7 +227,15 @@ void fluidsimBake(struct Object *ob)
char curWd[FILE_MAXDIR];
int dirExist = 0;
const int maxRes = 200;
int debugBake = 0;
const char *strEnvName = "BLENDER_ELBEEMDEBUG"; // from blendercall.cpp
if(getenv(strEnvName)) {
int dlevel = atoi(getenv(strEnvName));
if((dlevel>0) && (dlevel<=10)) debugBake = 1;
if(debugBake) fprintf(stderr,"fluidsimBake::msg: Debug messages activated due to envvar '%s'\n",strEnvName);
}
/* check if there's another domain... */
for(obit= G.main->object.first; obit; obit= obit->id.next) {
if((obit->fluidsimFlag & OB_FLUIDSIM_ENABLE)&&(obit->type==OB_MESH)) {
@@ -250,17 +259,18 @@ void fluidsimBake(struct Object *ob)
fssDomain->previewresxyz = fssDomain->resolutionxyz;
}
// set adaptive coarsening according to resolutionxyz
// this should do as an approximation,
// it would be more accurate to take into account geometry and no.
// fluid cells... max 1 for now...
// this should do as an approximation, with in/outflow
// doing this more accurate would be overkill
// perhaps add manual setting?
if(fssDomain->resolutionxyz>128) {
fssDomain->maxRefine = 0; // disable for now
fssDomain->maxRefine = 2;
} else
if(fssDomain->resolutionxyz>64) {
fssDomain->maxRefine = 0;
fssDomain->maxRefine = 1;
} else {
fssDomain->maxRefine = 0;
}
if(debugBake) fprintf(stderr,"fluidsimBake::msg: Baking %s, refine: %d\n", fsDomain->id.name , fssDomain->maxRefine );
// prepare names...
strcpy(curWd, G.sce);
@@ -398,7 +408,6 @@ void fluidsimBake(struct Object *ob)
{
char *rayString = "\n"
" anistart= 0; \n"
" aniframetime= 10; \n"
" aniframes= " "%d" /*1 frameEnd-frameStart+0*/ "; #cfgset \n"
" frameSkip= false; \n"
" filename= \"" "%s" /* rayPicFilename*/ "\"; #cfgset \n"
@@ -484,8 +493,6 @@ void fluidsimBake(struct Object *ob)
//bb = NULL; // TODO test existing bounding box...
//if(!bb && (mesh->totvert>0) )
{
int i;
float vec[3];
@@ -573,7 +580,7 @@ void fluidsimBake(struct Object *ob)
fprintf(fileCfg, "} // end raytracing\n");
fclose(fileCfg);
fprintf(stderr,"fluidsimBake::msg: Wrote %s\n", fnameCfg);
if(debugBake) fprintf(stderr,"fluidsimBake::msg: Wrote %s\n", fnameCfg);
// perform simulation
{
@@ -595,6 +602,7 @@ void fluidsimBake(struct Object *ob)
short val;
float noFramesf = G.scene->r.efra - G.scene->r.sfra;
float percentdone = 0.0;
int lastRedraw = -1;
start_progress_bar();
@@ -608,7 +616,7 @@ void fluidsimBake(struct Object *ob)
sprintf(busy_mess, "baking fluids %d / %d |||", globalBakeFrame, (int) noFramesf);
progress_bar(percentdone, busy_mess );
SDL_Delay(1000);
SDL_Delay(2000); // longer delay to prevent frequent redrawing
SDL_mutexP(globalBakeLock);
if(globalBakeState == 1) done = 1;
SDL_mutexV(globalBakeLock);
@@ -619,13 +627,25 @@ void fluidsimBake(struct Object *ob)
// abort...
SDL_mutexP(globalBakeLock);
done = -1;
//SDL_KillThread(simthr);
globalBakeFrame = 0;
globalBakeState = -1;
SDL_mutexV(globalBakeLock);
break;
}
}
// redraw the 3D for showing progress once in a while...
if(lastRedraw!=globalBakeFrame) {
ScrArea *sa;
G.scene->r.cfra = lastRedraw = globalBakeFrame;
update_for_newframe_muted();
sa= G.curscreen->areabase.first;
while(sa) {
if(sa->spacetype == SPACE_VIEW3D) { scrarea_do_windraw(sa); }
sa= sa->next;
}
screen_swapbuffers();
} // redraw
}
SDL_WaitThread(simthr,NULL);
end_progress_bar();