diff options
author | Nils Thuerey <nils@thuerey.de> | 2005-09-23 18:42:14 +0400 |
---|---|---|
committer | Nils Thuerey <nils@thuerey.de> | 2005-09-23 18:42:14 +0400 |
commit | 4fb0cccc68efabe264e9139f980cd67fd29980f3 (patch) | |
tree | d718606f1bc4a904ca2a0a4ab585044bf702e96b /intern | |
parent | 5f767d16273684cd02cf40c6fed6cea758134474 (diff) |
- 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?
Diffstat (limited to 'intern')
35 files changed, 2279 insertions, 2064 deletions
diff --git a/intern/elbeem/SConscript b/intern/elbeem/SConscript index d60339058ce..c155bb79fab 100644 --- a/intern/elbeem/SConscript +++ b/intern/elbeem/SConscript @@ -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 = [ diff --git a/intern/elbeem/intern/attributes.cpp b/intern/elbeem/intern/attributes.cpp index aa013a5b3aa..97e33e3d65e 100644 --- a/intern/elbeem/intern/attributes.cpp +++ b/intern/elbeem/intern/attributes.cpp @@ -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); } diff --git a/intern/elbeem/intern/attributes.h b/intern/elbeem/intern/attributes.h index 93793708533..bc92999a05f 100644 --- a/intern/elbeem/intern/attributes.h +++ b/intern/elbeem/intern/attributes.h @@ -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]; } diff --git a/intern/elbeem/intern/blendercall.cpp b/intern/elbeem/intern/blendercall.cpp index 41ddf7d63e1..13ab3aeae5e 100644 --- a/intern/elbeem/intern/blendercall.cpp +++ b/intern/elbeem/intern/blendercall.cpp @@ -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; }; diff --git a/intern/elbeem/intern/cfglexer.cpp b/intern/elbeem/intern/cfglexer.cpp index ddd8367eae0..f4574a6c05a 100644 --- a/intern/elbeem/intern/cfglexer.cpp +++ b/intern/elbeem/intern/cfglexer.cpp @@ -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" diff --git a/intern/elbeem/intern/cfgparser.cpp b/intern/elbeem/intern/cfgparser.cpp index d70fc50ec4c..d5f0be48c12 100644 --- a/intern/elbeem/intern/cfgparser.cpp +++ b/intern/elbeem/intern/cfgparser.cpp @@ -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 */ diff --git a/intern/elbeem/intern/cfgparser.hpp b/intern/elbeem/intern/cfgparser.h index 3262ddba03d..659159ef74d 100644 --- a/intern/elbeem/intern/cfgparser.hpp +++ b/intern/elbeem/intern/cfgparser.h @@ -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 diff --git a/intern/elbeem/intern/isosurface.cpp b/intern/elbeem/intern/isosurface.cpp index a69e2ccb998..92ed8c63eab 100644 --- a/intern/elbeem/intern/isosurface.cpp +++ b/intern/elbeem/intern/isosurface.cpp @@ -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 diff --git a/intern/elbeem/intern/isosurface.h b/intern/elbeem/intern/isosurface.h index a574cccdba6..53ea324a2c2 100644 --- a/intern/elbeem/intern/isosurface.h +++ b/intern/elbeem/intern/isosurface.h @@ -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; } diff --git a/intern/elbeem/intern/lbmdimensions.h b/intern/elbeem/intern/lbmdimensions.h index 5b084cbd3e8..cf5077a07a0 100644 --- a/intern/elbeem/intern/lbmdimensions.h +++ b/intern/elbeem/intern/lbmdimensions.h @@ -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 ]; diff --git a/intern/elbeem/intern/lbmfsgrsolver.h b/intern/elbeem/intern/lbmfsgrsolver.h index 703d4d61989..c94a2e06efe 100644 --- a/intern/elbeem/intern/lbmfsgrsolver.h +++ b/intern/elbeem/intern/lbmfsgrsolver.h @@ -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,11 +1777,21 @@ 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 ); @@ -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 - - if( ((lev)<mMaxRefine) || (SHOWALL_INT_CELLS)) - if((MARK_INT_CELLS)&&(D::cDimension==2)) { debugMarkCell(lev,i,j,k); } + 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)&&(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 @@ -4078,99 +3974,356 @@ LbmFsgrSolver<D>::coarseRestrictFromFine(int lev) template<class D> bool +LbmFsgrSolver<D>::performRefinement(int lev) { + if((lev<0) || ((lev+1)>mMaxRefine)) return false; + bool change = false; + //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(); 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) & CFGrFromFine) { + bool removeFromFine = 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), 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, srcFineSet)¬SrcAllowed) { // 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, srcFineSet)¬SrcAllowed) { // 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, srcFineSet)¬SrcAllowed) { + 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, srcFineSet)¬SrcAllowed) { // NEWREFT + removeFromFine=true; + } + } + } // mixborder + // also remove from fine cells that are above from fine +#else // REFINEMENTBORDER==1 + ERROR +#endif // REFINEMENTBORDER==1 + + if(removeFromFine) { + // dont turn CFGrFromFine above interface cells into CFGrNorm + //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]; + //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 + + + 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, 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, srcFineSet)&(CFGrFromCoarse)) { + //errMsg("performRefinement","Removing CFGrFromCoarse on lev"<<(lev+1)<<" "<<PRINT_VEC(bi,bj,bk) ); + RFLAG(lev+1, bi, bj, bk, srcFineSet) = setf; + if((D::cDimension==2)&&(debugRefinement)) debugMarkCell(lev+1,bi,bj,bk); + } + else if(RFLAG(lev+1, bi, bj, bk, srcFineSet)&(CFUnused )) { + //errMsg("performRefinement","Removing CFUnused on lev"<<(lev+1)<<" "<<PRINT_VEC(bi,bj,bk) ); + interpolateCellFromCoarse(lev+1, bi, bj, bk, srcFineSet, interTime, setf, false); + if((D::cDimension==2)&&(debugRefinement)) debugMarkCell(lev+1,bi,bj,bk); + 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, 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, srcFineSet)&CFUnused) { + //errMsg("performRefinement","Changing CFUnused on lev"<<(lev+1)<<" "<<PRINT_VEC(mi,mj,mk) ); + interpolateCellFromCoarse(lev+1, mi, mj, mk, srcFineSet, interTime, CFFluid|CFGrFromCoarse, false); + if((D::cDimension==2)&&(debugRefinement)) debugMarkCell(lev+1,mi,mj,mk); + mNumFsgrChanges++; + } + } + // nbs prepared... + } + } + } + + } // convert regions of from fine + }}} // 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(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) { // 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) { + 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; - 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; + 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; + } } - } // l + } // FARBORD */ } - // dont turn CFGrFromFine above interface cells into CFGrNorm + // 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 + if(RFLAG(lev, ni,nj,nk, srcSet)&(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; + 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) debugMarkCell(lev,i,j,k); + 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"<<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(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 , 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)) + // 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 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; + 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, mLevel[dstlev].setCurr)&(CFFluid)) { - RFLAG(dstlev, dstni,dstnj,dstnk, mLevel[dstlev].setCurr) = CFFluid|CFGrFromCoarse; + if(RFLAG(dstlev, dstni,dstnj,dstnk, dstFineSet)&(CFFluid)) { + RFLAG(dstlev, dstni,dstnj,dstnk, dstFineSet) = CFFluid|CFGrFromCoarse; } - if(RFLAG(dstlev, dstni,dstnj,dstnk, mLevel[dstlev].setCurr)&(CFInter)) { + 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, mLevel[dstlev].setCurr, dMass); - RFLAG(dstlev, dstni,dstnj,dstnk, mLevel[dstlev].setCurr) = CFFluid|CFGrFromCoarse; + D::mFixMass += QCELL( dstlev, dstni,dstnj,dstnk, dstFineSet, dMass); + RFLAG(dstlev, dstni,dstnj,dstnk, dstFineSet) = CFFluid|CFGrFromCoarse; } } // l @@ -4179,24 +4332,25 @@ LbmFsgrSolver<D>::performCoarsening(int lev) { 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) )) { + //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, mLevel[dstlev].setCurr)&(CFUnused|CFGrFromCoarse)) { + 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:"<< convertFlags2String( RFLAG(dstlev, chkni,chknj,chknk, mLevel[dstlev].setCurr))<<" nbsok"<<delok ); + //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) { - RFLAG(dstlev, dstni,dstnj,dstnk, mLevel[dstlev].setCurr) = CFUnused; + mNumFsgrChanges++; + RFLAG(dstlev, dstni,dstnj,dstnk, dstFineSet) = CFUnused; RFLAG(dstlev, dstni,dstnj,dstnk, mLevel[dstlev].setOther) = CFUnused; // FLAGTEST - if(D::cDimension==2) debugMarkCell(dstlev,dstni,dstnj,dstnk); + if((D::cDimension==2)&&(debugCoarsening)) debugMarkCell(dstlev,dstni,dstnj,dstnk); } } } // l @@ -4208,14 +4362,15 @@ LbmFsgrSolver<D>::performCoarsening(int lev) { } // ? } // convert regions of from fine + }}} // TEST! // 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) { + /*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, mLevel[lev+1].setCurr)& + if(RFLAG(lev+1, ni,nj,nk, dstFineSet)& (CFGrFromCoarse|CFUnused|CFEmpty) //? (CFBnd|CFEmpty|CFGrFromCoarse|CFUnused) //(CFUnused|CFEmpty) //? (CFBnd|CFEmpty|CFGrFromCoarse|CFUnused) ) { @@ -4224,54 +4379,72 @@ LbmFsgrSolver<D>::performCoarsening(int lev) { } } // l QCELL(lev, i,j,k,mLevel[lev].setOther, dFlux) = - QCELL(lev, i,j,k,mLevel[lev].setCurr, dFlux) = totArea; + QCELL(lev, i,j,k,srcSet, dFlux) = totArea; } else { QCELL(lev, i,j,k,mLevel[lev].setOther, dFlux) = - QCELL(lev, i,j,k,mLevel[lev].setCurr, dFlux) = 1.0; + QCELL(lev, i,j,k,srcSet, dFlux) = 1.0; } - //errMsg("DFINI"," at l"<<lev<<" "<<PRINT_IJK<<" v:"<<QCELL(lev, i,j,k,mLevel[lev].setCurr, dFlux) ); + //errMsg("DFINI"," at l"<<lev<<" "<<PRINT_IJK<<" v:"<<QCELL(lev, i,j,k,srcSet, dFlux) ); } // */ - if(RFLAG(lev, i,j,k, mLevel[lev].setCurr) & CFEmpty) { + 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|CFGrFromCoarse|CFGrFromFine|CFGrToFine); - const CellFlagType notNbAllowed = (CFEmpty|CFGrFromFine|CFInter|CFBnd); + 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) & (CFFluid)) && - (!(RFLAG(lev+1, (2*i),(2*j),(2*k), mLevel[lev+1].setCurr) & (notAllowed)) ) ){ + 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), mLevel[lev+1].setCurr) & (CFFluid)) && - (!(RFLAG(lev+1, (2*i),(2*j),(2*k), mLevel[lev+1].setCurr) & (notAllowed)) ) ){ + 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, mLevel[lev+1].setCurr)&(notNbAllowed)) { // NEWREFT + 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, mLevel[lev+1].setCurr)&(notNbAllowed)) { // NEWREFT + 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), mLevel[lev+1].setCurr) & (CFFluid|CFInter)) && - (!(RFLAG(lev+1, (2*i),(2*j),(2*k), mLevel[lev+1].setCurr) & (notAllowed)) ) ){ + 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), mLevel[lev+1].setCurr) & (CFFluid)) && - (!(RFLAG(lev+1, (2*i),(2*j),(2*k), mLevel[lev+1].setCurr) & (notAllowed)) ) ){ + 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, mLevel[lev+1].setCurr)&(notNbAllowed)) { // NEWREFT + if(RFLAG(lev+1, ni,nj,nk, dstFineSet)&(notNbAllowed)) { // NEWREFT changeToFromFine=false; } } @@ -4281,222 +4454,20 @@ LbmFsgrSolver<D>::performCoarsening(int lev) { #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); + 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; } -template<class D> -bool -LbmFsgrSolver<D>::performRefinement(int lev) { - if((lev<0) || ((lev+1)>mMaxRefine)) return false; - bool change = false; - //bool nbsok; - // TIMEINTORDER ? - LbmFloat interTime = 0.0; - - // 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) { - - // ???? - /*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++) { - //} - bool removeFromFine = false; - const CellFlagType notSrcAllowed = (CFEmpty|CFGrFromFine|CFInter|CFBnd|CFGrToFine); - -#if REFINEMENTBORDER==1 - if(RFLAG(lev+1, 2*i,2*j,2*k, mLevel[lev+1].setCurr)¬SrcAllowed) { - removeFromFine=true; - } -#elif REFINEMENTBORDER==2 // REFINEMENTBORDER==1 - 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)¬SrcAllowed) { // 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)¬SrcAllowed) { // NEWREFT - removeFromFine=true; - } - } // FARBORD */ -#elif REFINEMENTBORDER==3 // REFINEMENTBORDER==1 - if(lev+1==mMaxRefine) { // mixborder - if(RFLAG(lev+1, 2*i,2*j,2*k, mLevel[lev+1].setCurr)¬SrcAllowed) { - 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)¬SrcAllowed) { // NEWREFT - removeFromFine=true; - } - } - } // mixborder - // also remove from fine cells that are above from fine -#else // REFINEMENTBORDER==1 - ERROR -#endif // REFINEMENTBORDER==1 - - 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); - 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)&(CFFluid)) { //ok - RFLAG(lev, ni,nj,nk, mLevel[lev].setCurr) = CFFluid|CFGrFromFine; - if(D::cDimension==2) debugMarkCell(lev,ni,nj,nk); - } - } // l - } - - // recheck from fine flag - } - - 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))) { - //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; - change=true; - 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)) { - //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); - } - else if(RFLAG(lev+1, bi, bj, bk, mLevel[lev+1].setCurr)&(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); - } - } - 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)) ) { - // 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) { - //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); - } - } - // nbs prepared... - } - } - } - - } // 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 - - } } } - - if(!D::mSilent){ errMsg("performRefinement"," for l"<<lev<<" done ("<<change<<") " ); } - 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++) { @@ -5963,6 +5938,11 @@ void LbmFsgrSolver<D>::prepareVisualization( void ) { *****************************************************************************/ 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) ); float val; @@ -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 diff --git a/intern/elbeem/intern/lbmfunctions.h b/intern/elbeem/intern/lbmfunctions.h index e799d108205..4038c995f68 100644 --- a/intern/elbeem/intern/lbmfunctions.h +++ b/intern/elbeem/intern/lbmfunctions.h @@ -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; } } diff --git a/intern/elbeem/intern/lbminterface.cpp b/intern/elbeem/intern/lbminterface.cpp index 975fcebeb2d..f64132d755b 100644 --- a/intern/elbeem/intern/lbminterface.cpp +++ b/intern/elbeem/intern/lbminterface.cpp @@ -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; } }; diff --git a/intern/elbeem/intern/lbminterface.h b/intern/elbeem/intern/lbminterface.h index e89dcacf153..9b7c07ebc02 100644 --- a/intern/elbeem/intern/lbminterface.h +++ b/intern/elbeem/intern/lbminterface.h @@ -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; }; diff --git a/intern/elbeem/intern/ntl_blenderdumper.cpp b/intern/elbeem/intern/ntl_blenderdumper.cpp index 535a13c214a..9c7fbc70b16 100644 --- a/intern/elbeem/intern/ntl_blenderdumper.cpp +++ b/intern/elbeem/intern/ntl_blenderdumper.cpp @@ -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) { diff --git a/intern/elbeem/intern/ntl_bsptree.cpp b/intern/elbeem/intern/ntl_bsptree.cpp index d9c1539f7b8..43d45130ca6 100644 --- a/intern/elbeem/intern/ntl_bsptree.cpp +++ b/intern/elbeem/intern/ntl_bsptree.cpp @@ -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); +} + + + diff --git a/intern/elbeem/intern/ntl_bsptree.h b/intern/elbeem/intern/ntl_bsptree.h index 396499838c4..b2d24fd318a 100644 --- a/intern/elbeem/intern/ntl_bsptree.h +++ b/intern/elbeem/intern/ntl_bsptree.h @@ -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; } diff --git a/intern/elbeem/intern/ntl_geometrymodel.cpp b/intern/elbeem/intern/ntl_geometrymodel.cpp index 5dfe86b8027..51b2b5e7f9a 100644 --- a/intern/elbeem/intern/ntl_geometrymodel.cpp +++ b/intern/elbeem/intern/ntl_geometrymodel.cpp @@ -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 } diff --git a/intern/elbeem/intern/ntl_geometryobject.cpp b/intern/elbeem/intern/ntl_geometryobject.cpp index ed71a57856c..80122c41146 100644 --- a/intern/elbeem/intern/ntl_geometryobject.cpp +++ b/intern/elbeem/intern/ntl_geometryobject.cpp @@ -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; } diff --git a/intern/elbeem/intern/ntl_geometryshader.h b/intern/elbeem/intern/ntl_geometryshader.h index ef7608f68e0..12cd5e7c0bc 100644 --- a/intern/elbeem/intern/ntl_geometryshader.h +++ b/intern/elbeem/intern/ntl_geometryshader.h @@ -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(); } diff --git a/intern/elbeem/intern/ntl_image.h b/intern/elbeem/intern/ntl_image.h index 497c68a7139..f6d9093e95c 100644 --- a/intern/elbeem/intern/ntl_image.h +++ b/intern/elbeem/intern/ntl_image.h @@ -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: diff --git a/intern/elbeem/intern/ntl_lightobject.cpp b/intern/elbeem/intern/ntl_lightobject.cpp index 88fc3b4502e..c8db66bab74 100644 --- a/intern/elbeem/intern/ntl_lightobject.cpp +++ b/intern/elbeem/intern/ntl_lightobject.cpp @@ -97,6 +97,7 @@ ntlLightObject::getShadedColor(const ntlRay &reflectedRay, const ntlVec3Gfx ligh *****************************************************************************/ void ntlLightObject::prepare( bool doCaustics ) { + doCaustics = false; // unused if(!mActive) { return; } } diff --git a/intern/elbeem/intern/ntl_ray.cpp b/intern/elbeem/intern/ntl_ray.cpp index 7b31ba38237..ef7278248ba 100644 --- a/intern/elbeem/intern/ntl_ray.cpp +++ b/intern/elbeem/intern/ntl_ray.cpp @@ -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 ? } diff --git a/intern/elbeem/intern/ntl_ray.h b/intern/elbeem/intern/ntl_ray.h index c433c45b33d..71fac128e26 100644 --- a/intern/elbeem/intern/ntl_ray.h +++ b/intern/elbeem/intern/ntl_ray.h @@ -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); +// ... diff --git a/intern/elbeem/intern/ntl_raytracer.cpp b/intern/elbeem/intern/ntl_raytracer.cpp index ccd51a1a69e..45a15a714fb 100644 --- a/intern/elbeem/intern/ntl_raytracer.cpp +++ b/intern/elbeem/intern/ntl_raytracer.cpp @@ -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; } diff --git a/intern/elbeem/intern/ntl_renderglobals.h b/intern/elbeem/intern/ntl_renderglobals.h index dc999f2c92f..606d0588554 100644 --- a/intern/elbeem/intern/ntl_renderglobals.h +++ b/intern/elbeem/intern/ntl_renderglobals.h @@ -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 ), diff --git a/intern/elbeem/intern/ntl_scene.cpp b/intern/elbeem/intern/ntl_scene.cpp index 87148776697..7a7e47f5d06 100644 --- a/intern/elbeem/intern/ntl_scene.cpp +++ b/intern/elbeem/intern/ntl_scene.cpp @@ -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; } } diff --git a/intern/elbeem/intern/ntl_scene.h b/intern/elbeem/intern/ntl_scene.h index 9e7a8dfbdea..94f40058196 100644 --- a/intern/elbeem/intern/ntl_scene.h +++ b/intern/elbeem/intern/ntl_scene.h @@ -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 */ diff --git a/intern/elbeem/intern/ntl_vector3dim.h b/intern/elbeem/intern/ntl_vector3dim.h index 7fb3e71b2d3..3679b689b1b 100644 --- a/intern/elbeem/intern/ntl_vector3dim.h +++ b/intern/elbeem/intern/ntl_vector3dim.h @@ -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 diff --git a/intern/elbeem/intern/parametrizer.cpp b/intern/elbeem/intern/parametrizer.cpp index fb63126623e..8b5a9772923 100644 --- a/intern/elbeem/intern/parametrizer.cpp +++ b/intern/elbeem/intern/parametrizer.cpp @@ -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)) { diff --git a/intern/elbeem/intern/parametrizer.h b/intern/elbeem/intern/parametrizer.h index d6a8d9575b9..71b7514cda5 100644 --- a/intern/elbeem/intern/parametrizer.h +++ b/intern/elbeem/intern/parametrizer.h @@ -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; diff --git a/intern/elbeem/intern/particletracer.cpp b/intern/elbeem/intern/particletracer.cpp index 7b9fb9fd1f4..388e68b0261 100644 --- a/intern/elbeem/intern/particletracer.cpp +++ b/intern/elbeem/intern/particletracer.cpp @@ -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++) { diff --git a/intern/elbeem/intern/simulation_object.cpp b/intern/elbeem/intern/simulation_object.cpp index eabbeac5662..15fb79fa5f2 100644 --- a/intern/elbeem/intern/simulation_object.cpp +++ b/intern/elbeem/intern/simulation_object.cpp @@ -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; diff --git a/intern/elbeem/intern/utilities.cpp b/intern/elbeem/intern/utilities.cpp index c647281fe68..4cfcef9cf0f 100644 --- a/intern/elbeem/intern/utilities.cpp +++ b/intern/elbeem/intern/utilities.cpp @@ -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 + diff --git a/intern/elbeem/intern/utilities.h b/intern/elbeem/intern/utilities.h index fa74f3d091c..bb6825fab82 100644 --- a/intern/elbeem/intern/utilities.h +++ b/intern/elbeem/intern/utilities.h @@ -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); - -#endif // USE_GLUTILITIES - -/* debugging outputs */ -//#define DEBUG 10 +/* 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; + +// 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); -#else +# 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 |