- merged latest version of fluid solver
authorNils Thuerey <nils@thuerey.de>
Fri, 23 Sep 2005 14:42:14 +0000 (14:42 +0000)
committerNils Thuerey <nils@thuerey.de>
Fri, 23 Sep 2005 14:42:14 +0000 (14:42 +0000)
  (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?

37 files changed:
intern/elbeem/SConscript
intern/elbeem/intern/attributes.cpp
intern/elbeem/intern/attributes.h
intern/elbeem/intern/blendercall.cpp
intern/elbeem/intern/cfglexer.cpp
intern/elbeem/intern/cfgparser.cpp
intern/elbeem/intern/cfgparser.h [moved from intern/elbeem/intern/cfgparser.hpp with 99% similarity]
intern/elbeem/intern/isosurface.cpp
intern/elbeem/intern/isosurface.h
intern/elbeem/intern/lbmdimensions.h
intern/elbeem/intern/lbmfsgrsolver.h
intern/elbeem/intern/lbmfunctions.h
intern/elbeem/intern/lbminterface.cpp
intern/elbeem/intern/lbminterface.h
intern/elbeem/intern/ntl_blenderdumper.cpp
intern/elbeem/intern/ntl_bsptree.cpp
intern/elbeem/intern/ntl_bsptree.h
intern/elbeem/intern/ntl_geometrymodel.cpp
intern/elbeem/intern/ntl_geometryobject.cpp
intern/elbeem/intern/ntl_geometryshader.h
intern/elbeem/intern/ntl_image.h
intern/elbeem/intern/ntl_lightobject.cpp
intern/elbeem/intern/ntl_ray.cpp
intern/elbeem/intern/ntl_ray.h
intern/elbeem/intern/ntl_raytracer.cpp
intern/elbeem/intern/ntl_renderglobals.h
intern/elbeem/intern/ntl_scene.cpp
intern/elbeem/intern/ntl_scene.h
intern/elbeem/intern/ntl_vector3dim.h
intern/elbeem/intern/parametrizer.cpp
intern/elbeem/intern/parametrizer.h
intern/elbeem/intern/particletracer.cpp
intern/elbeem/intern/simulation_object.cpp
intern/elbeem/intern/utilities.cpp
intern/elbeem/intern/utilities.h
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/src/fluidsim.c

index d603390..c155bb7 100644 (file)
@@ -11,6 +11,7 @@ elbeem_env.Append (CPPPATH = user_options_dict['PNG_INCLUDE'])
 elbeem_env.Append (CPPPATH = user_options_dict['Z_INCLUDE'])
 elbeem_env.Append (CPPPATH = user_options_dict['SDL_INCLUDE'])
 
+
 # main build----------------------------------------
 
 Sources = [ 
index aa013a5..97e33e3 100644 (file)
@@ -138,11 +138,9 @@ ntlMat4Gfx Attribute::getAsMat4Gfx()
        bool success = true;
        ntlMat4Gfx ret(0.0);
        char *endptr;
-       const char *str = NULL;
 
        if(mValue.size()==1) {
                const char *str = mValue[0].c_str();
-               char *endptr;
                double rval = strtod(str, &endptr);
                if( (str==endptr) ||
                                ((str!=endptr) && (*endptr != '\0')) )success = false;
@@ -157,7 +155,7 @@ ntlMat4Gfx Attribute::getAsMat4Gfx()
                // 3x3
                for(int i=0; i<3;i++) {
                        for(int j=0; j<3;j++) {
-                               str = mValue[i*3+j].c_str();
+                               const char *str = mValue[i*3+j].c_str();
                                ret.value[i][j] = strtod(str, &endptr);
                                if( (str==endptr) ||
                                                ((str!=endptr) && (*endptr != '\0')) ) success = false;
@@ -167,7 +165,7 @@ ntlMat4Gfx Attribute::getAsMat4Gfx()
                // 4x4
                for(int i=0; i<4;i++) {
                        for(int j=0; j<4;j++) {
-                               str = mValue[i*4+j].c_str();
+                               const char *str = mValue[i*4+j].c_str();
                                ret.value[i][j] = strtod(str, &endptr);
                                if( (str==endptr) ||
                                                ((str!=endptr) && (*endptr != '\0')) ) success = false;
@@ -210,7 +208,7 @@ bool AttributeList::checkUnusedParams()
                        i != mAttrs.end(); i++) {
                if((*i).second) {
                        if(!(*i).second->getUsed()) {
-                               errorOut("Attribute "<<mName<<" has unknown parameter '"<<(*i).first<<"' = '"<< mAttrs[(*i).first]->getAsString() <<"' ");
+                               errMsg("AttributeList::checkUnusedParams", "List "<<mName<<" has unknown parameter '"<<(*i).first<<"' = '"<< mAttrs[(*i).first]->getAsString() <<"' ");
                                found = true;
                        }
                }
@@ -232,7 +230,7 @@ void AttributeList::setAllUsed() {
  *****************************************************************************/
 int AttributeList::readInt(string name, int defaultValue, string source,string target, bool needed) {
        if(!exists(name)) {
-               if(needed) { errorOut("AttributeList::readInt error: Required attribute '"<<name<<"' for "<< source <<"  not set! "); exit(1); }
+               if(needed) { errFatal("AttributeList::readInt","Required attribute '"<<name<<"' for "<< source <<"  not set! ", SIMWORLD_INITERROR); }
                return defaultValue;
        } 
        if(DEBUG_ATTRIBUTES==1) { debugOut( source << " Var '"<< target <<"' set to '"<< find(name)->getCompleteString() <<"' as type int " , 3); }
@@ -241,7 +239,7 @@ int AttributeList::readInt(string name, int defaultValue, string source,string t
 }
 bool AttributeList::readBool(string name, bool defaultValue, string source,string target, bool needed) {
        if(!exists(name)) {
-               if(needed) { errorOut("AttributeList::readBool error: Required attribute '"<<name<<"' for "<< source <<"  not set! "); exit(1); }
+               if(needed) { errFatal("AttributeList::readBool","Required attribute '"<<name<<"' for "<< source <<"  not set! ", SIMWORLD_INITERROR); }
                return defaultValue;
        } 
        if(DEBUG_ATTRIBUTES==1) { debugOut( source << " Var '"<< target <<"' set to '"<< find(name)->getCompleteString() <<"' as type int " , 3); }
@@ -250,7 +248,7 @@ bool AttributeList::readBool(string name, bool defaultValue, string source,strin
 }
 double AttributeList::readFloat(string name, double defaultValue, string source,string target, bool needed) {
        if(!exists(name)) {
-               if(needed) { errorOut("AttributeList::readFloat error: Required attribute '"<<name<<"' for "<< source <<"  not set! "); exit(1); }
+               if(needed) { errFatal("AttributeList::readFloat","Required attribute '"<<name<<"' for "<< source <<"  not set! ", SIMWORLD_INITERROR); }
                return defaultValue;
        } 
        if(DEBUG_ATTRIBUTES==1) { debugOut( source << " Var '"<< target <<"' set to '"<< find(name)->getCompleteString() <<"' as type int " , 3); }
@@ -259,7 +257,7 @@ double AttributeList::readFloat(string name, double defaultValue, string source,
 }
 string AttributeList::readString(string name, string defaultValue, string source,string target, bool needed) {
        if(!exists(name)) {
-               if(needed) { errorOut("AttributeList::readInt error: Required attribute '"<<name<<"' for "<< source <<"  not set! "); exit(1); }
+               if(needed) { errFatal("AttributeList::readInt","Required attribute '"<<name<<"' for "<< source <<"  not set! ", SIMWORLD_INITERROR); }
                return defaultValue;
        } 
        if(DEBUG_ATTRIBUTES==1) { debugOut( source << " Var '"<< target <<"' set to '"<< find(name)->getCompleteString() <<"' as type int " , 3); }
@@ -268,7 +266,7 @@ string AttributeList::readString(string name, string defaultValue, string source
 }
 ntlVec3d AttributeList::readVec3d(string name, ntlVec3d defaultValue, string source,string target, bool needed) {
        if(!exists(name)) {
-               if(needed) { errorOut("AttributeList::readInt error: Required attribute '"<<name<<"' for "<< source <<"  not set! "); exit(1); }
+               if(needed) { errFatal("AttributeList::readInt","Required attribute '"<<name<<"' for "<< source <<"  not set! ", SIMWORLD_INITERROR); }
                return defaultValue;
        } 
        if(DEBUG_ATTRIBUTES==1) { debugOut( source << " Var '"<< target <<"' set to '"<< find(name)->getCompleteString() <<"' as type int " , 3); }
@@ -278,7 +276,7 @@ ntlVec3d AttributeList::readVec3d(string name, ntlVec3d defaultValue, string sou
 
 ntlMat4Gfx AttributeList::readMat4Gfx(string name, ntlMat4Gfx defaultValue, string source,string target, bool needed) {
        if(!exists(name)) {
-               if(needed) { errorOut("AttributeList::readInt error: Required attribute '"<<name<<"' for "<< source <<"  not set! "); exit(1); }
+               if(needed) { errFatal("AttributeList::readInt","Required attribute '"<<name<<"' for "<< source <<"  not set! ", SIMWORLD_INITERROR); }
                return defaultValue;
        } 
        if(DEBUG_ATTRIBUTES==1) { debugOut( source << " Var '"<< target <<"' set to '"<< find(name)->getCompleteString() <<"' as type int " , 3); }
index 9379370..bc92999 100644 (file)
@@ -99,8 +99,10 @@ class AttributeList
                /*! get an attribute */
                Attribute *find(string name) {
                        if(mAttrs.find(name) == mAttrs.end()) { 
-                               errorOut("AttributeList::find error: Invalid attribute '"<<name<<"' , not found..." );
-                               exit(1); 
+                               errFatal("AttributeList::find","Invalid attribute '"<<name<<"' , not found...",SIMWORLD_INITERROR );
+                               // just create a new empty one (warning: small memory leak!), and exit as soon as possible
+                               vector<string> empty;
+                               return new Attribute(name,empty, -1);
                        }
                        return mAttrs[name];
                }
index 41ddf7d..13ab3ae 100644 (file)
 #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;
 };
 
index ddd8367..f4574a6 100644 (file)
@@ -799,16 +799,19 @@ char *yy_text;
 
 /* this header file is automatically generated by bison 
  * and includes all token definitions, as well as yy_lval */
+#if ELBEEM_BLENDER==1
+#include "cfgparser.h"
+#else // ELBEEM_BLENDER==1
 #include "cfgparser.hpp"
+#endif // ELBEEM_BLENDER==1
 #include "utilities.h"
 
 #include <string.h>
 #define CHAR_BUFFER_SIZE 8000
-  char charBuffer[ CHAR_BUFFER_SIZE ];
+char charBuffer[ CHAR_BUFFER_SIZE ];
 
-  int lineCount = 1;
+int lineCount = 1;
 
-// for windos compiler...
 extern "C" int yy_wrap (void ) { return 1; }
 #define YY_NO_UNISTD_H
        
@@ -822,7 +825,7 @@ extern "C" int yy_wrap (void ) { return 1; }
  * rules start 
  */
 /*----------------------------------------------------------------------------*/
-#line 826 "<stdout>"
+#line 829 "<stdout>"
 
 #define INITIAL 0
 #define ATTR 1
@@ -975,11 +978,11 @@ YY_DECL
        register char *yy_cp, *yy_bp;
        register int yy_act;
     
-#line 51 "src/cfglexer.ll"
+#line 54 "src/cfglexer.ll"
 
 
 
-#line 983 "<stdout>"
+#line 986 "<stdout>"
 
        if ( (yy_init) )
                {
@@ -1060,25 +1063,25 @@ do_action:      /* This label is used only to access EOF actions. */
 
 case 1:
 YY_RULE_SETUP
-#line 54 "src/cfglexer.ll"
+#line 57 "src/cfglexer.ll"
 { return KW_PAROPEN; }
        YY_BREAK
 case 2:
 YY_RULE_SETUP
-#line 55 "src/cfglexer.ll"
+#line 58 "src/cfglexer.ll"
 { BEGIN(INITIAL); // '}' always closes scopes
                        return KW_PARCLOSE; }
        YY_BREAK
 case 3:
 YY_RULE_SETUP
-#line 58 "src/cfglexer.ll"
+#line 61 "src/cfglexer.ll"
 { 
                        BEGIN(ATTRVALUE);
                        return KW_EQUALS; }
        YY_BREAK
 case 4:
 YY_RULE_SETUP
-#line 61 "src/cfglexer.ll"
+#line 64 "src/cfglexer.ll"
 { /* attribute name = normal string */
                strncpy( charBuffer, yy_text, CHAR_BUFFER_SIZE-2 );
                yy_lval.charValue = charBuffer;
@@ -1086,7 +1089,7 @@ YY_RULE_SETUP
        YY_BREAK
 case 5:
 YY_RULE_SETUP
-#line 65 "src/cfglexer.ll"
+#line 68 "src/cfglexer.ll"
 { /* quoted string! attribute name = normal string */
                strncpy( charBuffer, yy_text, CHAR_BUFFER_SIZE-2 );
                        /* get rid of " " */
@@ -1097,7 +1100,7 @@ YY_RULE_SETUP
        YY_BREAK
 case 6:
 YY_RULE_SETUP
-#line 72 "src/cfglexer.ll"
+#line 75 "src/cfglexer.ll"
 { /* ends at newline or ';' */
                strncpy( charBuffer, yy_text, CHAR_BUFFER_SIZE-2 );
                yy_lval.charValue = charBuffer;
@@ -1106,428 +1109,428 @@ YY_RULE_SETUP
 case 7:
 /* rule 7 can match eol */
 YY_RULE_SETUP
-#line 76 "src/cfglexer.ll"
+#line 79 "src/cfglexer.ll"
 { /* return end token... */
                        BEGIN(ATTR); 
                        return KW_ATTREND; }
        YY_BREAK
 case 8:
 YY_RULE_SETUP
-#line 81 "src/cfglexer.ll"
+#line 84 "src/cfglexer.ll"
 { return KW_LBMSIM; }
        YY_BREAK
 case 9:
 YY_RULE_SETUP
-#line 82 "src/cfglexer.ll"
+#line 85 "src/cfglexer.ll"
 { return KW_COMPARELBM; }
        YY_BREAK
 case 10:
 YY_RULE_SETUP
-#line 83 "src/cfglexer.ll"
+#line 86 "src/cfglexer.ll"
 { return KW_DEBUGMODE; }
        YY_BREAK
 case 11:
 YY_RULE_SETUP
-#line 84 "src/cfglexer.ll"
+#line 87 "src/cfglexer.ll"
 { return KW_RAYTRACING; }
        YY_BREAK
 case 12:
 YY_RULE_SETUP
-#line 87 "src/cfglexer.ll"
+#line 90 "src/cfglexer.ll"
 { return KW_RESOLUTION; }
        YY_BREAK
 case 13:
 YY_RULE_SETUP
-#line 88 "src/cfglexer.ll"
+#line 91 "src/cfglexer.ll"
 { return KW_ANTIALIAS; }
        YY_BREAK
 case 14:
 YY_RULE_SETUP
-#line 89 "src/cfglexer.ll"
+#line 92 "src/cfglexer.ll"
 { return KW_EYEPOINT; }
        YY_BREAK
 case 15:
 YY_RULE_SETUP
-#line 90 "src/cfglexer.ll"
+#line 93 "src/cfglexer.ll"
 { return KW_LOOKAT ; }
        YY_BREAK
 case 16:
 YY_RULE_SETUP
-#line 91 "src/cfglexer.ll"
+#line 94 "src/cfglexer.ll"
 { return KW_UPVEC ; }
        YY_BREAK
 case 17:
 YY_RULE_SETUP
-#line 92 "src/cfglexer.ll"
+#line 95 "src/cfglexer.ll"
 { return KW_FOVY; }
        YY_BREAK
 case 18:
 YY_RULE_SETUP
-#line 93 "src/cfglexer.ll"
+#line 96 "src/cfglexer.ll"
 { return KW_ASPECT ; }
        YY_BREAK
 case 19:
 YY_RULE_SETUP
-#line 94 "src/cfglexer.ll"
+#line 97 "src/cfglexer.ll"
 { return KW_AMBIENCE; }
        YY_BREAK
 case 20:
 YY_RULE_SETUP
-#line 95 "src/cfglexer.ll"
+#line 98 "src/cfglexer.ll"
 { return KW_BACKGROUND; }
        YY_BREAK
 case 21:
 YY_RULE_SETUP
-#line 96 "src/cfglexer.ll"
+#line 99 "src/cfglexer.ll"
 { return KW_ANISTART; }
        YY_BREAK
 case 22:
 YY_RULE_SETUP
-#line 97 "src/cfglexer.ll"
+#line 100 "src/cfglexer.ll"
 { return KW_ANIFRAMES; }
        YY_BREAK
 case 23:
 YY_RULE_SETUP
-#line 98 "src/cfglexer.ll"
+#line 101 "src/cfglexer.ll"
 { return KW_ANIFRAMETIME; }
        YY_BREAK
 case 24:
 YY_RULE_SETUP
-#line 99 "src/cfglexer.ll"
+#line 102 "src/cfglexer.ll"
 { return KW_FRAMESKIP; }
        YY_BREAK
 case 25:
 YY_RULE_SETUP
-#line 100 "src/cfglexer.ll"
+#line 103 "src/cfglexer.ll"
 { return KW_FILENAME; }
        YY_BREAK
 case 26:
 YY_RULE_SETUP
-#line 101 "src/cfglexer.ll"
+#line 104 "src/cfglexer.ll"
 { return KW_PMCAUSTICS; }
        YY_BREAK
 case 27:
 YY_RULE_SETUP
-#line 102 "src/cfglexer.ll"
+#line 105 "src/cfglexer.ll"
 { return KW_CAUSTICDIST; }
        YY_BREAK
 case 28:
 YY_RULE_SETUP
-#line 103 "src/cfglexer.ll"
+#line 106 "src/cfglexer.ll"
 { return KW_CAUSTICPHOT; }
        YY_BREAK
 case 29:
 YY_RULE_SETUP
-#line 104 "src/cfglexer.ll"
+#line 107 "src/cfglexer.ll"
 { return KW_SHADOWMAPBIAS; }
        YY_BREAK
 case 30:
 YY_RULE_SETUP
-#line 105 "src/cfglexer.ll"
+#line 108 "src/cfglexer.ll"
 { return KW_MAXRAYDEPTH; }
        YY_BREAK
 case 31:
 YY_RULE_SETUP
-#line 106 "src/cfglexer.ll"
+#line 109 "src/cfglexer.ll"
 { return KW_TREEMAXDEPTH; }
        YY_BREAK
 case 32:
 YY_RULE_SETUP
-#line 107 "src/cfglexer.ll"
+#line 110 "src/cfglexer.ll"
 { return KW_TREEMAXTRIANGLES; }
        YY_BREAK
 case 33:
 YY_RULE_SETUP
-#line 108 "src/cfglexer.ll"
+#line 111 "src/cfglexer.ll"
 { return KW_DEBUGPIXEL; }
        YY_BREAK
 case 34:
 YY_RULE_SETUP
-#line 109 "src/cfglexer.ll"
+#line 112 "src/cfglexer.ll"
 { return KW_TESTMODE; }
        YY_BREAK
 case 35:
 YY_RULE_SETUP
-#line 110 "src/cfglexer.ll"
+#line 113 "src/cfglexer.ll"
 { return KW_OPENGLATTR; }
        YY_BREAK
 case 36:
 YY_RULE_SETUP
-#line 111 "src/cfglexer.ll"
+#line 114 "src/cfglexer.ll"
 { return KW_BLENDERATTR; }
        YY_BREAK
 case 37:
 YY_RULE_SETUP
-#line 113 "src/cfglexer.ll"
+#line 116 "src/cfglexer.ll"
 { return KW_OBJATTR; /* assign attr to obj */ }
        YY_BREAK
 case 38:
 YY_RULE_SETUP
-#line 114 "src/cfglexer.ll"
+#line 117 "src/cfglexer.ll"
 { BEGIN(ATTR); return KW_ATTRIBUTE;  /* global attr list */ }
        YY_BREAK
 case 39:
 YY_RULE_SETUP
-#line 115 "src/cfglexer.ll"
+#line 118 "src/cfglexer.ll"
 { BEGIN(ATTR); return KW_DEFINEATTR; /* obj defines new attrs */ }
        YY_BREAK
 case 40:
 YY_RULE_SETUP
-#line 116 "src/cfglexer.ll"
+#line 119 "src/cfglexer.ll"
 { BEGIN(ATTR); return KW_DEFINEATTR; }
        YY_BREAK
 case 41:
 YY_RULE_SETUP
-#line 117 "src/cfglexer.ll"
+#line 120 "src/cfglexer.ll"
 { BEGIN(ATTR); return KW_DEFINEATTR; }
        YY_BREAK
 case 42:
 YY_RULE_SETUP
-#line 119 "src/cfglexer.ll"
+#line 122 "src/cfglexer.ll"
 { return KW_GEOMETRY; }
        YY_BREAK
 case 43:
 YY_RULE_SETUP
-#line 120 "src/cfglexer.ll"
+#line 123 "src/cfglexer.ll"
 { return KW_TYPE; }
        YY_BREAK
 case 44:
 YY_RULE_SETUP
-#line 121 "src/cfglexer.ll"
+#line 124 "src/cfglexer.ll"
 { return KW_GEOTYPE_BOX; }
        YY_BREAK
 case 45:
 YY_RULE_SETUP
-#line 122 "src/cfglexer.ll"
+#line 125 "src/cfglexer.ll"
 { return KW_GEOTYPE_SPHERE; }
        YY_BREAK
 case 46:
 YY_RULE_SETUP
-#line 123 "src/cfglexer.ll"
+#line 126 "src/cfglexer.ll"
 { return KW_GEOTYPE_OBJMODEL; }
        YY_BREAK
 case 47:
 YY_RULE_SETUP
-#line 124 "src/cfglexer.ll"
+#line 127 "src/cfglexer.ll"
 { return KW_CASTSHADOWS; }  
        YY_BREAK
 case 48:
 YY_RULE_SETUP
-#line 125 "src/cfglexer.ll"
+#line 128 "src/cfglexer.ll"
 { return KW_RECEIVESHADOWS ; }
        YY_BREAK
 case 49:
 YY_RULE_SETUP
-#line 126 "src/cfglexer.ll"
+#line 129 "src/cfglexer.ll"
 { return KW_VISIBLE; }  
        YY_BREAK
 case 50:
 YY_RULE_SETUP
-#line 127 "src/cfglexer.ll"
+#line 130 "src/cfglexer.ll"
 { return KW_BOX_START; }
        YY_BREAK
 case 51:
 YY_RULE_SETUP
-#line 128 "src/cfglexer.ll"
+#line 131 "src/cfglexer.ll"
 { return KW_BOX_END; }
        YY_BREAK
 case 52:
 YY_RULE_SETUP
-#line 129 "src/cfglexer.ll"
+#line 132 "src/cfglexer.ll"
 { return KW_POLY ; }
        YY_BREAK
 case 53:
 YY_RULE_SETUP
-#line 130 "src/cfglexer.ll"
+#line 133 "src/cfglexer.ll"
 { return KW_POLY ; }
        YY_BREAK
 case 54:
 YY_RULE_SETUP
-#line 131 "src/cfglexer.ll"
+#line 134 "src/cfglexer.ll"
 { return KW_NUMVERTICES; }
        YY_BREAK
 case 55:
 YY_RULE_SETUP
-#line 132 "src/cfglexer.ll"
+#line 135 "src/cfglexer.ll"
 { return KW_VERTEX; }
        YY_BREAK
 case 56:
 YY_RULE_SETUP
-#line 133 "src/cfglexer.ll"
+#line 136 "src/cfglexer.ll"
 { return KW_NUMPOLYGONS; }
        YY_BREAK
 case 57:
 YY_RULE_SETUP
-#line 134 "src/cfglexer.ll"
+#line 137 "src/cfglexer.ll"
 { return KW_ISOSURF; }  
        YY_BREAK
 case 58:
 YY_RULE_SETUP
-#line 135 "src/cfglexer.ll"
+#line 138 "src/cfglexer.ll"
 { return KW_FILEMODE; }  
        YY_BREAK
 case 59:
 YY_RULE_SETUP
-#line 136 "src/cfglexer.ll"
+#line 139 "src/cfglexer.ll"
 { return KW_INVERT; }  
        YY_BREAK
 case 60:
 YY_RULE_SETUP
-#line 138 "src/cfglexer.ll"
+#line 141 "src/cfglexer.ll"
 { return KW_MATERIAL; }
        YY_BREAK
 case 61:
 YY_RULE_SETUP
-#line 139 "src/cfglexer.ll"
+#line 142 "src/cfglexer.ll"
 { return KW_MATTYPE_PHONG; }
        YY_BREAK
 case 62:
 YY_RULE_SETUP
-#line 140 "src/cfglexer.ll"
+#line 143 "src/cfglexer.ll"
 { return KW_MATTYPE_BLINN; }
        YY_BREAK
 case 63:
 YY_RULE_SETUP
-#line 141 "src/cfglexer.ll"
+#line 144 "src/cfglexer.ll"
 { return KW_NAME; }
        YY_BREAK
 case 64:
 YY_RULE_SETUP
-#line 142 "src/cfglexer.ll"
+#line 145 "src/cfglexer.ll"
 { return KW_AMBIENT; }
        YY_BREAK
 case 65:
 YY_RULE_SETUP
-#line 143 "src/cfglexer.ll"
+#line 146 "src/cfglexer.ll"
 { return KW_DIFFUSE; }
        YY_BREAK
 case 66:
 YY_RULE_SETUP
-#line 144 "src/cfglexer.ll"
+#line 147 "src/cfglexer.ll"
 { return KW_SPECULAR; }
        YY_BREAK
 case 67:
 YY_RULE_SETUP
-#line 145 "src/cfglexer.ll"
+#line 148 "src/cfglexer.ll"
 { return KW_MIRROR; }
        YY_BREAK
 case 68:
 YY_RULE_SETUP
-#line 146 "src/cfglexer.ll"
+#line 149 "src/cfglexer.ll"
 { return KW_TRANSPARENCE; }
        YY_BREAK
 case 69:
 YY_RULE_SETUP
-#line 147 "src/cfglexer.ll"
+#line 150 "src/cfglexer.ll"
 { return KW_REFRACINDEX; }
        YY_BREAK
 case 70:
 YY_RULE_SETUP
-#line 148 "src/cfglexer.ll"
+#line 151 "src/cfglexer.ll"
 { return KW_TRANSADDITIVE; }
        YY_BREAK
 case 71:
 YY_RULE_SETUP
-#line 149 "src/cfglexer.ll"
+#line 152 "src/cfglexer.ll"
 { return KW_TRANSATTCOL; }
        YY_BREAK
 case 72:
 YY_RULE_SETUP
-#line 150 "src/cfglexer.ll"
+#line 153 "src/cfglexer.ll"
 { return KW_FRESNEL; }
        YY_BREAK
 case 73:
 YY_RULE_SETUP
-#line 151 "src/cfglexer.ll"
+#line 154 "src/cfglexer.ll"
 { return KW_FRESNEL; }
        YY_BREAK
 case 74:
 YY_RULE_SETUP
-#line 153 "src/cfglexer.ll"
+#line 156 "src/cfglexer.ll"
 { return KW_LIGHT; }
        YY_BREAK
 case 75:
 YY_RULE_SETUP
-#line 154 "src/cfglexer.ll"
+#line 157 "src/cfglexer.ll"
 { return KW_LIGHT_OMNI; }
        YY_BREAK
 case 76:
 YY_RULE_SETUP
-#line 155 "src/cfglexer.ll"
+#line 158 "src/cfglexer.ll"
 { return KW_ACTIVE; }
        YY_BREAK
 case 77:
 YY_RULE_SETUP
-#line 156 "src/cfglexer.ll"
+#line 159 "src/cfglexer.ll"
 { return KW_COLOUR; }
        YY_BREAK
 case 78:
 YY_RULE_SETUP
-#line 157 "src/cfglexer.ll"
+#line 160 "src/cfglexer.ll"
 { return KW_COLOUR; }
        YY_BREAK
 case 79:
 YY_RULE_SETUP
-#line 158 "src/cfglexer.ll"
+#line 161 "src/cfglexer.ll"
 { return KW_POSITION; }
        YY_BREAK
 case 80:
 YY_RULE_SETUP
-#line 159 "src/cfglexer.ll"
+#line 162 "src/cfglexer.ll"
 { return KW_CAUSTICPHOTONS; }
        YY_BREAK
 case 81:
 YY_RULE_SETUP
-#line 160 "src/cfglexer.ll"
+#line 163 "src/cfglexer.ll"
 { return KW_CAUSTICSTRENGTH; }
        YY_BREAK
 case 82:
 YY_RULE_SETUP
-#line 161 "src/cfglexer.ll"
+#line 164 "src/cfglexer.ll"
 { return KW_SHADOWMAP; }
        YY_BREAK
 case 83:
 YY_RULE_SETUP
-#line 162 "src/cfglexer.ll"
+#line 165 "src/cfglexer.ll"
 { return KW_CAUSTICSMAP; }
        YY_BREAK
 case 84:
 YY_RULE_SETUP
-#line 164 "src/cfglexer.ll"
+#line 167 "src/cfglexer.ll"
 { yy_lval.intValue = 1; return DT_INTEGER; }
        YY_BREAK
 case 85:
 YY_RULE_SETUP
-#line 165 "src/cfglexer.ll"
+#line 168 "src/cfglexer.ll"
 { yy_lval.intValue = 0; return DT_INTEGER; }
        YY_BREAK
 case 86:
 YY_RULE_SETUP
-#line 166 "src/cfglexer.ll"
+#line 169 "src/cfglexer.ll"
 { yy_lval.intValue = 1; return DT_INTEGER; }
        YY_BREAK
 case 87:
 YY_RULE_SETUP
-#line 167 "src/cfglexer.ll"
+#line 170 "src/cfglexer.ll"
 { yy_lval.intValue = 0; return DT_INTEGER; }
        YY_BREAK
 case 88:
 YY_RULE_SETUP
-#line 170 "src/cfglexer.ll"
+#line 173 "src/cfglexer.ll"
 { // integer number
   yy_lval.intValue = atoi( yy_text );
   return DT_INTEGER; }
        YY_BREAK
 case 89:
 YY_RULE_SETUP
-#line 174 "src/cfglexer.ll"
+#line 177 "src/cfglexer.ll"
 { // floating point number
   yy_lval.floatValue = atof( yy_text );
   return DT_FLOAT; }
        YY_BREAK
 case 90:
 YY_RULE_SETUP
-#line 178 "src/cfglexer.ll"
+#line 181 "src/cfglexer.ll"
 { /* normal character strings, now also for paths/filenames */
   strncpy( charBuffer, yy_text, CHAR_BUFFER_SIZE-2 );
        /* get rid of " " */
@@ -1538,17 +1541,17 @@ YY_RULE_SETUP
        YY_BREAK
 case 91:
 YY_RULE_SETUP
-#line 186 "src/cfglexer.ll"
+#line 189 "src/cfglexer.ll"
 { /* one line comment */  }
        YY_BREAK
 case 92:
 YY_RULE_SETUP
-#line 187 "src/cfglexer.ll"
+#line 190 "src/cfglexer.ll"
 { /* one line comment */  }
        YY_BREAK
 case 93:
 YY_RULE_SETUP
-#line 188 "src/cfglexer.ll"
+#line 191 "src/cfglexer.ll"
 { /* multiline comment */
        register int c; 
        for ( ; ; )     {
@@ -1574,26 +1577,26 @@ YY_RULE_SETUP
 case 94:
 /* rule 94 can match eol */
 YY_RULE_SETUP
-#line 212 "src/cfglexer.ll"
+#line 215 "src/cfglexer.ll"
 { // count line numbers
   lineCount++; }
        YY_BREAK
 case 95:
 YY_RULE_SETUP
-#line 215 "src/cfglexer.ll"
+#line 218 "src/cfglexer.ll"
 { /* do nothing by default... */ }
        YY_BREAK
 case 96:
 YY_RULE_SETUP
-#line 217 "src/cfglexer.ll"
-{ /*errorOut( "cfgLexer, Line "<<lineCount<<" : Unknown character '"<<(char)yyinput()<<"' " ); exit(1); */ }
+#line 220 "src/cfglexer.ll"
+{ /*errorOut( "cfgLexer, Line "<<lineCount<<" : Unknown character '"<<(char)yyinput()<<"' " ); xit(1); */ }
        YY_BREAK
 case 97:
 YY_RULE_SETUP
-#line 220 "src/cfglexer.ll"
+#line 223 "src/cfglexer.ll"
 ECHO;
        YY_BREAK
-#line 1597 "<stdout>"
+#line 1600 "<stdout>"
 case YY_STATE_EOF(INITIAL):
 case YY_STATE_EOF(ATTR):
 case YY_STATE_EOF(ATTRVALUE):
@@ -2558,4 +2561,4 @@ void yy_free (void * ptr )
 #undef YY_DECL_IS_OURS
 #undef YY_DECL
 #endif
-#line 220 "src/cfglexer.ll"
+#line 223 "src/cfglexer.ll"
index d70fc50..d5f0be4 100644 (file)
@@ -360,7 +360,7 @@ typedef union YYSTYPE {
   char  *charValue;
 } YYSTYPE;
 /* Line 191 of yacc.c.  */
-#line 364 "bld-std-gcc/src/cfgparser.cpp"
+#line 364 "bld-std-gcc40/src/cfgparser.cpp"
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
 # define YYSTYPE_IS_TRIVIAL 1
@@ -372,7 +372,7 @@ typedef union YYSTYPE {
 
 
 /* Line 214 of yacc.c.  */
-#line 376 "bld-std-gcc/src/cfgparser.cpp"
+#line 376 "bld-std-gcc40/src/cfgparser.cpp"
 
 #if ! defined (yyoverflow) || YYERROR_VERBOSE
 
@@ -1549,7 +1549,7 @@ yyreduce:
 
   case 37:
 #line 204 "src/cfgparser.yy"
-    { reglob->setAniFrameTime( yyvsp[0].intValue ); }
+    { /*reglob->setAniFrameTime( $2 );*/ debMsgStd("cfgparser",DM_NOTIFY,"Deprecated setting aniframetime!",1); }
     break;
 
   case 38:
@@ -2047,7 +2047,7 @@ yyreduce:
     }
 
 /* Line 1010 of yacc.c.  */
-#line 2051 "bld-std-gcc/src/cfgparser.cpp"
+#line 2051 "bld-std-gcc40/src/cfgparser.cpp"
 \f
   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 */
similarity index 99%
rename from intern/elbeem/intern/cfgparser.hpp
rename to intern/elbeem/intern/cfgparser.h
index 3262ddb..659159e 100644 (file)
@@ -247,7 +247,7 @@ typedef union YYSTYPE {
   char  *charValue;
 } YYSTYPE;
 /* Line 1285 of yacc.c.  */
-#line 251 "bld-std-gcc/src/cfgparser.hpp"
+#line 251 "bld-std-gcc40/src/cfgparser.hpp"
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
 # define YYSTYPE_IS_TRIVIAL 1
index a69e2cc..92ed8c6 100644 (file)
@@ -117,8 +117,8 @@ void IsoSurface::triangulate( void )
        myTime_t tritimestart = getTime(); 
 
        if(!mpData) {
-               errorOut("IsoSurface::triangulate fatal error: no LBM object, and no scalar field...!");
-               exit( -1 );
+               errFatal("IsoSurface::triangulate","no LBM object, and no scalar field...!",SIMWORLD_INITERROR);
+               return;
        }
 
   // get grid spacing
@@ -332,9 +332,7 @@ void IsoSurface::triangulate( void )
                smoothNormals(mSmoothNormals);
        }
        myTime_t tritimeend = getTime(); 
-#if ELBEEM_BLENDER!=1
        debMsgStd("IsoSurface::triangulate",DM_MSG,"Took "<< ((tritimeend-tritimestart)/(double)1000.0)<<"s) " , 10 );
-#endif // ELBEEM_BLENDER!=1
 }
 
 
@@ -361,8 +359,9 @@ void IsoSurface::getTriangles( vector<ntlTriangle> *triangles,
        int iniVertIndex = (*vertices).size();
        int iniNormIndex = (*normals).size();
        if(iniVertIndex != iniNormIndex) {
-               errorOut("getTriangles Error for '"<<mName<<"': Vertices and normal array sizes to not match!!!");
-               exit(1); }
+               errFatal("getTriangles Error","For '"<<mName<<"': Vertices and normal array sizes to not match!!!",SIMWORLD_GENERICERROR);
+               return; 
+       }
        //errMsg("NM"," ivi"<<iniVertIndex<<" ini"<<iniNormIndex<<" vs"<<vertices->size()<<" ns"<<normals->size()<<" ts"<<triangles->size() );
        //errMsg("NM"," ovs"<<mVertices.size()<<" ons"<<mVertNormals.size()<<" ots"<<mIndices.size() );
 
@@ -447,8 +446,6 @@ inline ntlVec3Gfx IsoSurface::getNormal(int i, int j,int k) {
 // Subdivide a mesh allways loop
 void IsoSurface::subdivide()
 {
-       int i;
-
        mAdjacentFaces.clear(); 
        mAcrossEdge.clear();
 
@@ -456,18 +453,17 @@ void IsoSurface::subdivide()
        {
                vector<int> numadjacentfaces(mPoints.size());
                //errMsg("SUBDIV ADJFA1", " "<<mPoints.size()<<" - "<<numadjacentfaces.size() );
-               int i;
-               for (i = 0; i < (int)mIndices.size()/3; i++) {
+               for (int i = 0; i < (int)mIndices.size()/3; i++) {
                        numadjacentfaces[mIndices[i*3 + 0]]++;
                        numadjacentfaces[mIndices[i*3 + 1]]++;
                        numadjacentfaces[mIndices[i*3 + 2]]++;
                }
 
                mAdjacentFaces.resize(mPoints.size());
-               for (i = 0; i < (int)mPoints.size(); i++)
+               for (int i = 0; i < (int)mPoints.size(); i++)
                        mAdjacentFaces[i].reserve(numadjacentfaces[i]);
 
-               for (i = 0; i < (int)mIndices.size()/3; i++) {
+               for (int i = 0; i < (int)mIndices.size()/3; i++) {
                        for (int j = 0; j < 3; j++)
                                mAdjacentFaces[mIndices[i*3 + j]].push_back(i);
                }
@@ -529,7 +525,7 @@ void IsoSurface::subdivide()
        vector<int> newvert_count(old_nv + 3*nf); // wichtig...?
        //errMsg("NC", newvert_count.size() );
 
-       for (i = 0; i < nf; i++) {
+       for (int i = 0; i < nf; i++) {
                for (int j = 0; j < 3; j++) {
                        int ae = mAcrossEdge[i*3 + j];
                        if (newverts[i*3 + j] == -1 && ae != -1) {
@@ -580,7 +576,7 @@ void IsoSurface::subdivide()
                        newvert_count[newverts[i*3 + j]]++;
                }
        }
-       for (i = old_nv; i < (int)mPoints.size(); i++) {
+       for (int i = old_nv; i < (int)mPoints.size(); i++) {
                if (!newvert_count[i])
                        continue;
                float scale = 1.0f / newvert_count[i];
@@ -593,7 +589,7 @@ void IsoSurface::subdivide()
        }
 
        // Update old vertices
-       for (i = 0; i < old_nv; i++) {
+       for (int i = 0; i < old_nv; i++) {
                        ntlVec3Gfx bdyavg(0.0), nbdyavg(0.0);
                        ntlVec3Gfx norm_bdyavg(0.0), norm_nbdyavg(0.0); // N
                        int nbdy = 0, nnbdy = 0;
@@ -667,7 +663,7 @@ void IsoSurface::subdivide()
 
        // Insert new faces
        mIndices.reserve(4*nf);
-       for (i = 0; i < nf; i++) {
+       for (int i = 0; i < nf; i++) {
                mIndices.push_back( mIndices[i*3 + 0]);
                mIndices.push_back( newverts[i*3 + 2]);
                mIndices.push_back( newverts[i*3 + 1]);
@@ -688,11 +684,11 @@ void IsoSurface::subdivide()
        // recalc normals
 #if RECALCNORMALS==1
        {
-               int nf = (int)mIndices.size()/3, nv = (int)mPoints.size(), i;
-               for (i = 0; i < nv; i++) {
+               int nf = (int)mIndices.size()/3, nv = (int)mPoints.size();
+               for (int i = 0; i < nv; i++) {
                        mPoints[i].n = ntlVec3Gfx(0.0);
                }
-               for (i = 0; i < nf; i++) {
+               for (int i = 0; i < nf; i++) {
                        const ntlVec3Gfx &p0 = mPoints[mIndices[i*3+0]].v;
                        const ntlVec3Gfx &p1 = mPoints[mIndices[i*3+1]].v;
                        const ntlVec3Gfx &p2 = mPoints[mIndices[i*3+2]].v;
@@ -706,12 +702,12 @@ void IsoSurface::subdivide()
                        mPoints[mIndices[i*3+2]].n += facenormal * (1.0f / (l2c * l2b));
                }
 
-               for (i = 0; i < nv; i++) {
+               for (int i = 0; i < nv; i++) {
                        normalize(mPoints[i].n);
                }
        }
 #else // RECALCNORMALS==1
-               for (i = 0; i < (int)mPoints.size(); i++) {
+               for (int i = 0; i < (int)mPoints.size(); i++) {
                        normalize(mPoints[i].n);
                }
 #endif // RECALCNORMALS==1
index a574ccc..53ea324 100644 (file)
@@ -186,6 +186,8 @@ public:
        };
 
        struct BBox {
+               public: 
+               BBox() {};
                ntlVec3Gfx min, max;
                ntlVec3Gfx center() const { return (min+max)*0.5f; }
                ntlVec3Gfx size() const { return max - min; }
index 5b084cb..cf5077a 100644 (file)
@@ -88,10 +88,10 @@ class LbmD3Q19 {
                STCON char* dfString[ 19 ];
 
                /*! index of normal dist func, not used so far?... */
-               STCON dfDir dfNorm[ 19 ];
+               STCON int dfNorm[ 19 ];
 
                /*! index of inverse dist func, not fast, but useful... */
-               STCON dfDir dfInv[ 19 ];
+               STCON int dfInv[ 19 ];
 
                /*! index of x reflected dist func for free slip, not valid for all DFs... */
                STCON int dfRefX[ 19 ];
@@ -185,10 +185,10 @@ class LbmD2Q9 {
                STCON char* dfString[ 9 ];
 
                /* index of normal dist func, not used so far?... */
-               STCON dfDir dfNorm[ 9 ];
+               STCON int dfNorm[ 9 ];
 
                /* index of inverse dist func, not fast, but useful... */
-               STCON dfDir dfInv[ 9 ];
+               STCON int dfInv[ 9 ];
 
                /* index of x reflected dist func for free slip, not valid for all DFs... */
                STCON int dfRefX[ 9 ];
index 703d4d6..c94a2e0 100644 (file)
@@ -25,6 +25,7 @@
 #define PARALLEL 0
 #endif // PARALLEL
 
+// blender interface
 #if ELBEEM_BLENDER==1
 #include "SDL.h"
 #include "SDL_thread.h"
@@ -43,6 +44,8 @@ ERROR - define model first!
 #endif // LBMMODEL_DEFINED
 
 
+// general solver setting defines
+
 //! debug coordinate accesses and the like? (much slower)
 #define FSGR_STRICT_DEBUG 0
 
@@ -61,9 +64,6 @@ ERROR - define model first!
 //! refinement border method (1 = small border / 2 = larger)
 #define REFINEMENTBORDER 1
 
-// interpolateCellFromCoarse test
-#define INTCFCOARSETEST 1
-
 // use optimized 3D code?
 #if LBMDIM==2
 #define OPT3D false
@@ -86,16 +86,6 @@ ERROR - define model first!
 #define COMPRESSGRIDS 0
 #endif 
 
-// cell mark debugging
-#if FSGR_STRICT_DEBUG==10
-#define debugMarkCell(lev,x,y,z) \
-       errMsg("debugMarkCell",D::mName<<" step: "<<D::mStepCnt<<" lev:"<<(lev)<<" marking "<<PRINT_VEC((x),(y),(z))<<" line "<< __LINE__ ); \
-       debugMarkCellCall((lev),(x),(y),(z));
-#else // FSGR_STRICT_DEBUG==1
-#define debugMarkCell(lev,x,y,z) \
-       debugMarkCellCall((lev),(x),(y),(z));
-#endif // FSGR_STRICT_DEBUG==1
-
 
 //! threshold for level set fluid generation/isosurface
 #define LS_FLUIDTHRESHOLD 0.5
@@ -110,1155 +100,1137 @@ ERROR - define model first!
 #define FSGR_MAGICNR            0.025
 //0.04
 
-// flag array defines -----------------------------------------------------------------------------------------------
 
-// lbm testsolver get index define
-#define _LBMGI(level, ii,ij,ik, is) ( (mLevel[level].lOffsy*(ik)) + (mLevel[level].lOffsx*(ij)) + (ii) )
+// 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) )
 
-//! flag array acces macro
-#define _RFLAG(level,xx,yy,zz,set) mLevel[level].mprsFlags[set][ LBMGI((level),(xx),(yy),(zz),(set)) ]
-#define _RFLAG_NB(level,xx,yy,zz,set, dir) mLevel[level].mprsFlags[set][ LBMGI((level),(xx)+D::dfVecX[dir],(yy)+D::dfVecY[dir],(zz)+D::dfVecZ[dir],set) ]
-#define _RFLAG_NBINV(level,xx,yy,zz,set, dir) mLevel[level].mprsFlags[set][ LBMGI((level),(xx)+D::dfVecX[D::dfInv[dir]],(yy)+D::dfVecY[D::dfInv[dir]],(zz)+D::dfVecZ[D::dfInv[dir]],set) ]
 
-// array data layouts
-// standard array layout  -----------------------------------------------------------------------------------------------
-#define ALSTRING "Standard Array Layout"
-//#define _LBMQI(level, ii,ij,ik, is, lunused) ( ((is)*mLevel[level].lOffsz) + (mLevel[level].lOffsy*(ik)) + (mLevel[level].lOffsx*(ij)) + (ii) )
-#define _LBMQI(level, ii,ij,ik, is, lunused) ( (mLevel[level].lOffsy*(ik)) + (mLevel[level].lOffsx*(ij)) + (ii) )
-#define _QCELL(level,xx,yy,zz,set,l) (mLevel[level].mprsCells[(set)][ LBMQI((level),(xx),(yy),(zz),(set), l)*dTotalNum +(l)])
-#define _QCELL_NB(level,xx,yy,zz,set, dir,l) (mLevel[level].mprsCells[(set)][ LBMQI((level),(xx)+D::dfVecX[dir],(yy)+D::dfVecY[dir],(zz)+D::dfVecZ[dir],set, l)*dTotalNum +(l)])
-#define _QCELL_NBINV(level,xx,yy,zz,set, dir,l) (mLevel[level].mprsCells[(set)][ LBMQI((level),(xx)+D::dfVecX[D::dfInv[dir]],(yy)+D::dfVecY[D::dfInv[dir]],(zz)+D::dfVecZ[D::dfInv[dir]],set, l)*dTotalNum +(l)])
+// 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)
 
-#define QCELLSTEP dTotalNum
-#define _RACPNT(level, ii,ij,ik, is )  &QCELL(level,ii,ij,ik,is,0)
-#define _RAC(s,l) (s)[(l)]
+// 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
 
-// standard arrays
-#define CSRC_C    RAC(ccel                                , dC )
-#define CSRC_E    RAC(ccel + (-1)             *(dTotalNum), dE )
-#define CSRC_W    RAC(ccel + (+1)             *(dTotalNum), dW )
-#define CSRC_N    RAC(ccel + (-mLevel[lev].lOffsx)        *(dTotalNum), dN )
-#define CSRC_S    RAC(ccel + (+mLevel[lev].lOffsx)        *(dTotalNum), dS )
-#define CSRC_NE   RAC(ccel + (-mLevel[lev].lOffsx-1)      *(dTotalNum), dNE)
-#define CSRC_NW   RAC(ccel + (-mLevel[lev].lOffsx+1)      *(dTotalNum), dNW)
-#define CSRC_SE   RAC(ccel + (+mLevel[lev].lOffsx-1)      *(dTotalNum), dSE)
-#define CSRC_SW   RAC(ccel + (+mLevel[lev].lOffsx+1)      *(dTotalNum), dSW)
-#define CSRC_T    RAC(ccel + (-mLevel[lev].lOffsy)        *(dTotalNum), dT )
-#define CSRC_B    RAC(ccel + (+mLevel[lev].lOffsy)        *(dTotalNum), dB )
-#define CSRC_ET   RAC(ccel + (-mLevel[lev].lOffsy-1)      *(dTotalNum), dET)
-#define CSRC_EB   RAC(ccel + (+mLevel[lev].lOffsy-1)      *(dTotalNum), dEB)
-#define CSRC_WT   RAC(ccel + (-mLevel[lev].lOffsy+1)      *(dTotalNum), dWT)
-#define CSRC_WB   RAC(ccel + (+mLevel[lev].lOffsy+1)      *(dTotalNum), dWB)
-#define CSRC_NT   RAC(ccel + (-mLevel[lev].lOffsy-mLevel[lev].lOffsx) *(dTotalNum), dNT)
-#define CSRC_NB   RAC(ccel + (+mLevel[lev].lOffsy-mLevel[lev].lOffsx) *(dTotalNum), dNB)
-#define CSRC_ST   RAC(ccel + (-mLevel[lev].lOffsy+mLevel[lev].lOffsx) *(dTotalNum), dST)
-#define CSRC_SB   RAC(ccel + (+mLevel[lev].lOffsy+mLevel[lev].lOffsx) *(dTotalNum), dSB)
+// iso value defines
+// border for marching cubes
+#define ISOCORR 3
 
-#define XSRC_C(x)    RAC(ccel + (x)                 *dTotalNum, dC )
-#define XSRC_E(x)    RAC(ccel + ((x)-1)             *dTotalNum, dE )
-#define XSRC_W(x)    RAC(ccel + ((x)+1)             *dTotalNum, dW )
-#define XSRC_N(x)    RAC(ccel + ((x)-mLevel[lev].lOffsx)        *dTotalNum, dN )
-#define XSRC_S(x)    RAC(ccel + ((x)+mLevel[lev].lOffsx)        *dTotalNum, dS )
-#define XSRC_NE(x)   RAC(ccel + ((x)-mLevel[lev].lOffsx-1)      *dTotalNum, dNE)
-#define XSRC_NW(x)   RAC(ccel + ((x)-mLevel[lev].lOffsx+1)      *dTotalNum, dNW)
-#define XSRC_SE(x)   RAC(ccel + ((x)+mLevel[lev].lOffsx-1)      *dTotalNum, dSE)
-#define XSRC_SW(x)   RAC(ccel + ((x)+mLevel[lev].lOffsx+1)      *dTotalNum, dSW)
-#define XSRC_T(x)    RAC(ccel + ((x)-mLevel[lev].lOffsy)        *dTotalNum, dT )
-#define XSRC_B(x)    RAC(ccel + ((x)+mLevel[lev].lOffsy)        *dTotalNum, dB )
-#define XSRC_ET(x)   RAC(ccel + ((x)-mLevel[lev].lOffsy-1)      *dTotalNum, dET)
-#define XSRC_EB(x)   RAC(ccel + ((x)+mLevel[lev].lOffsy-1)      *dTotalNum, dEB)
-#define XSRC_WT(x)   RAC(ccel + ((x)-mLevel[lev].lOffsy+1)      *dTotalNum, dWT)
-#define XSRC_WB(x)   RAC(ccel + ((x)+mLevel[lev].lOffsy+1)      *dTotalNum, dWB)
-#define XSRC_NT(x)   RAC(ccel + ((x)-mLevel[lev].lOffsy-mLevel[lev].lOffsx) *dTotalNum, dNT)
-#define XSRC_NB(x)   RAC(ccel + ((x)+mLevel[lev].lOffsy-mLevel[lev].lOffsx) *dTotalNum, dNB)
-#define XSRC_ST(x)   RAC(ccel + ((x)-mLevel[lev].lOffsy+mLevel[lev].lOffsx) *dTotalNum, dST)
-#define XSRC_SB(x)   RAC(ccel + ((x)+mLevel[lev].lOffsy+mLevel[lev].lOffsx) *dTotalNum, dSB)
 
+/*****************************************************************************/
+/*! 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) { };
 
-#if FSGR_STRICT_DEBUG==1
+               // implement CellIdentifierInterface
+               virtual string getAsString() {
+                       std::ostringstream ret;
+                       ret <<"{ i"<<x<<",j"<<y;
+                       if(D::cDimension>2) ret<<",k"<<z;
+                       ret <<" }";
+                       return ret.str();
+               }
 
-#define LBMGI(level,ii,ij,ik, is)                 debLBMGI(level,ii,ij,ik, is)         
-#define RFLAG(level,xx,yy,zz,set)                 debRFLAG(level,xx,yy,zz,set)            
-#define RFLAG_NB(level,xx,yy,zz,set, dir)         debRFLAG_NB(level,xx,yy,zz,set, dir)    
-#define RFLAG_NBINV(level,xx,yy,zz,set, dir)      debRFLAG_NBINV(level,xx,yy,zz,set, dir) 
+               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;
+               }
+};
 
-#define LBMQI(level,ii,ij,ik, is, l)              debLBMQI(level,ii,ij,ik, is, l)         
-#define QCELL(level,xx,yy,zz,set,l)               debQCELL(level,xx,yy,zz,set,l)         
-#define QCELL_NB(level,xx,yy,zz,set, dir,l)       debQCELL_NB(level,xx,yy,zz,set, dir,l)
-#define QCELL_NBINV(level,xx,yy,zz,set, dir,l)    debQCELL_NBINV(level,xx,yy,zz,set, dir,l)
-#define RACPNT(level, ii,ij,ik, is )              debRACPNT(level, ii,ij,ik, is )          
-#define RAC(s,l)                                               debRAC(s,l)                  
+//! information needed for each level in the simulation
+class FsgrLevelData {
+public:
+       int id; // level number
 
-#else // FSGR_STRICT_DEBUG==1
+       //! 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];
 
-#define LBMGI(level,ii,ij,ik, is)                 _LBMGI(level,ii,ij,ik, is)         
-#define RFLAG(level,xx,yy,zz,set)                 _RFLAG(level,xx,yy,zz,set)            
-#define RFLAG_NB(level,xx,yy,zz,set, dir)         _RFLAG_NB(level,xx,yy,zz,set, dir)    
-#define RFLAG_NBINV(level,xx,yy,zz,set, dir)      _RFLAG_NBINV(level,xx,yy,zz,set, dir) 
+       //! smago params and precalculated values
+       LbmFloat lcsmago;
+       LbmFloat lcsmago_sqr;
+       LbmFloat lcnu;
 
-#define LBMQI(level,ii,ij,ik, is, l)              _LBMQI(level,ii,ij,ik, is, l)         
-#define QCELL(level,xx,yy,zz,set,l)               _QCELL(level,xx,yy,zz,set,l)         
-#define QCELL_NB(level,xx,yy,zz,set, dir,l)       _QCELL_NB(level,xx,yy,zz,set, dir, l)
-#define QCELL_NBINV(level,xx,yy,zz,set, dir,l)    _QCELL_NBINV(level,xx,yy,zz,set, dir,l)
-#define RACPNT(level, ii,ij,ik, is )              _RACPNT(level, ii,ij,ik, is )          
-#define RAC(s,l)                                  _RAC(s,l)                  
+       // LES statistics per level
+       double avgOmega;
+       double avgOmegaCnt;
 
-#endif // FSGR_STRICT_DEBUG==1
+       //! current set of dist funcs 
+       int setCurr;
+       //! target/other set of dist funcs 
+       int setOther;
 
-// general defines -----------------------------------------------------------------------------------------------
+       //! mass&volume for this level
+       LbmFloat lmass;
+       LbmFloat lvolume;
+       LbmFloat lcellfactor;
 
-#define TESTFLAG(flag, compflag) ((flag & compflag)==compflag)
+       //! local storage of mSizes
+       int lSizex, lSizey, lSizez;
+       int lOffsx, lOffsy, lOffsz;
 
-#if LBMDIM==2
-#define dC 0
-#define dN 1
-#define dS 2
-#define dE 3
-#define dW 4
-#define dNE 5
-#define dNW 6
-#define dSE 7
-#define dSW 8
-#define LBM_DFNUM 9
-#else
-// direction indices
-#define dC 0
-#define dN 1
-#define dS 2
-#define dE 3
-#define dW 4
-#define dT 5
-#define dB 6
-#define dNE 7
-#define dNW 8
-#define dSE 9
-#define dSW 10
-#define dNT 11
-#define dNB 12
-#define dST 13
-#define dSB 14
-#define dET 15
-#define dEB 16
-#define dWT 17
-#define dWB 18
-#define LBM_DFNUM 19
-#endif
-#define dFfrac 19
-#define dMass 20
-#define dFlux 21
-#define dTotalNum 22
-#define dWB 18
+};
 
-// default init for dFlux values
-#define FLUX_INIT 0.5f * (float)(D::cDfNum)
 
-// only for non DF dir handling!
-#define dNET 19
-#define dNWT 20
-#define dSET 21
-#define dSWT 22
-#define dNEB 23
-#define dNWB 24
-#define dSEB 25
-#define dSWB 26
 
-//! fill value for boundary cells
-#define BND_FILL 0.0
+/*****************************************************************************/
+/*! 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
+{
 
-#define DFL1 (1.0/ 3.0)
-#define DFL2 (1.0/18.0)
-#define DFL3 (1.0/36.0)
+       public:
+               //! Constructor 
+               LbmFsgrSolver();
+               //! Destructor 
+               virtual ~LbmFsgrSolver();
+               //! id string of solver
+               virtual string getIdString() { return string("FsgrSolver[") + D::getIdString(); }
 
-#define OMEGA(l) mLevel[(l)].omega
+               //! 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*/ );
 
-#define EQC (  DFL1*(rho - usqr))
-#define EQN (  DFL2*(rho + uy*(4.5*uy + 3.0) - usqr))
-#define EQS (  DFL2*(rho + uy*(4.5*uy - 3.0) - usqr))
-#define EQE (  DFL2*(rho + ux*(4.5*ux + 3.0) - usqr))
-#define EQW (  DFL2*(rho + ux*(4.5*ux - 3.0) - usqr))
-#define EQT (  DFL2*(rho + uz*(4.5*uz + 3.0) - usqr))
-#define EQB (  DFL2*(rho + uz*(4.5*uz - 3.0) - usqr))
-                    
-#define EQNE ( DFL3*(rho + (+ux+uy)*(4.5*(+ux+uy) + 3.0) - usqr))
-#define EQNW ( DFL3*(rho + (-ux+uy)*(4.5*(-ux+uy) + 3.0) - usqr))
-#define EQSE ( DFL3*(rho + (+ux-uy)*(4.5*(+ux-uy) + 3.0) - usqr))
-#define EQSW ( DFL3*(rho + (-ux-uy)*(4.5*(-ux-uy) + 3.0) - usqr))
-#define EQNT ( DFL3*(rho + (+uy+uz)*(4.5*(+uy+uz) + 3.0) - usqr))
-#define EQNB ( DFL3*(rho + (+uy-uz)*(4.5*(+uy-uz) + 3.0) - usqr))
-#define EQST ( DFL3*(rho + (-uy+uz)*(4.5*(-uy+uz) + 3.0) - usqr))
-#define EQSB ( DFL3*(rho + (-uy-uz)*(4.5*(-uy-uz) + 3.0) - usqr))
-#define EQET ( DFL3*(rho + (+ux+uz)*(4.5*(+ux+uz) + 3.0) - usqr))
-#define EQEB ( DFL3*(rho + (+ux-uz)*(4.5*(+ux-uz) + 3.0) - usqr))
-#define EQWT ( DFL3*(rho + (-ux+uz)*(4.5*(-ux+uz) + 3.0) - usqr))
-#define EQWB ( DFL3*(rho + (-ux-uz)*(4.5*(-ux-uz) + 3.0) - usqr))
+#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();
 
-// this is a bit ugly, but necessary for the CSRC_ access...
-#define MSRC_C    m[dC ]
-#define MSRC_N    m[dN ]
-#define MSRC_S    m[dS ]
-#define MSRC_E    m[dE ]
-#define MSRC_W    m[dW ]
-#define MSRC_T    m[dT ]
-#define MSRC_B    m[dB ]
-#define MSRC_NE   m[dNE]
-#define MSRC_NW   m[dNW]
-#define MSRC_SE   m[dSE]
-#define MSRC_SW   m[dSW]
-#define MSRC_NT   m[dNT]
-#define MSRC_NB   m[dNB]
-#define MSRC_ST   m[dST]
-#define MSRC_SB   m[dSB]
-#define MSRC_ET   m[dET]
-#define MSRC_EB   m[dEB]
-#define MSRC_WT   m[dWT]
-#define MSRC_WB   m[dWB]
+               /*! 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);
 
-// this is a bit ugly, but necessary for the ccel local access...
-#define CCEL_C    RAC(ccel, dC )
-#define CCEL_N    RAC(ccel, dN )
-#define CCEL_S    RAC(ccel, dS )
-#define CCEL_E    RAC(ccel, dE )
-#define CCEL_W    RAC(ccel, dW )
-#define CCEL_T    RAC(ccel, dT )
-#define CCEL_B    RAC(ccel, dB )
-#define CCEL_NE   RAC(ccel, dNE)
-#define CCEL_NW   RAC(ccel, dNW)
-#define CCEL_SE   RAC(ccel, dSE)
-#define CCEL_SW   RAC(ccel, dSW)
-#define CCEL_NT   RAC(ccel, dNT)
-#define CCEL_NB   RAC(ccel, dNB)
-#define CCEL_ST   RAC(ccel, dST)
-#define CCEL_SB   RAC(ccel, dSB)
-#define CCEL_ET   RAC(ccel, dET)
-#define CCEL_EB   RAC(ccel, dEB)
-#define CCEL_WT   RAC(ccel, dWT)
-#define CCEL_WB   RAC(ccel, dWB)
+               /*! 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 );
 
-#if PARALLEL==1
-#define CSMOMEGA_STATS(dlev, domega) 
-#else // PARALLEL==1
-#if FSGR_OMEGA_DEBUG==1
-#define CSMOMEGA_STATS(dlev, domega) \
-       mLevel[dlev].avgOmega += domega; mLevel[dlev].avgOmegaCnt+=1.0; 
-#else // FSGR_OMEGA_DEBUG==1
-#define CSMOMEGA_STATS(dlev, domega) 
-#endif // FSGR_OMEGA_DEBUG==1
-#endif // PARALLEL==1
 
+               /*! debug object display (used e.g. for preview surface) */
+               virtual vector<ntlGeometryObject*> getDebugObjects();
 
-// used for main loops and grav init
-// source set
-#define SRCS(l) mLevel[(l)].setCurr
-// target set
-#define TSET(l) mLevel[(l)].setOther
+               //! 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 );
 
-// complete default stream&collide, 2d/3d
-/* read distribution funtions of adjacent cells = sweep step */ 
-#if OPT3D==false 
+               // 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; }
 
-#if FSGR_STRICT_DEBUG==1
-#define MARKCELLCHECK \
-       debugMarkCell(lev,i,j,k); D::mPanic=1;
-#define STREAMCHECK(ni,nj,nk,nl) \
-       if((m[l] < -1.0) || (m[l]>1.0)) {\
-               errMsg("STREAMCHECK","Invalid streamed DF l"<<l<<" value:"<<m[l]<<" at "<<PRINT_IJK<<" from "<<PRINT_VEC(ni,nj,nk)<<" nl"<<(nl)<<\
-                               " nfc"<< RFLAG(lev, ni,nj,nk, mLevel[lev].setCurr)<<" nfo"<< RFLAG(lev, ni,nj,nk, mLevel[lev].setOther)  ); \
-               MARKCELLCHECK; \
-       }
-#define COLLCHECK \
-       if( (rho>2.0) || (rho<-1.0) || (ABS(ux)>1.0) || (ABS(uy)>1.0) |(ABS(uz)>1.0) ) {\
-               errMsg("COLLCHECK","Invalid collision values r:"<<rho<<" u:"PRINT_VEC(ux,uy,uz)<<" at? "<<PRINT_IJK ); \
-               MARKCELLCHECK; \
-       }
-#else
-#define STREAMCHECK(ni,nj,nk,nl) 
-#define COLLCHECK
-#endif
+               /*! type for cells */
+               typedef typename D::LbmCell LbmCell;
+               
+       protected:
 
-// careful ux,uy,uz need to be inited before!
+               //! 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);
 
-#define DEFAULT_STREAM \
-               m[dC] = RAC(ccel,dC); \
-               FORDF1 { \
-                       if(NBFLAG( D::dfInv[l] )&CFBnd) { \
-                               m[l] = RAC(ccel, D::dfInv[l] ); \
-                               STREAMCHECK(i,j,k, D::dfInv[l]); \
-                       } else { \
-                               m[l] = QCELL_NBINV(lev, i, j, k, SRCS(lev), l,l); \
-                               STREAMCHECK(i+D::dfVecX[D::dfInv[l]], j+D::dfVecY[D::dfInv[l]],k+D::dfVecZ[D::dfInv[l]], l); \
-                       } \
-               }   
+               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);
 
-// careful ux,uy,uz need to be inited before!
-#define DEFAULT_COLLIDE \
-                       D::collideArrays( m, rho,ux,uy,uz, OMEGA(lev), mLevel[lev].lcsmago, &mDebugOmegaRet ); \
-                       CSMOMEGA_STATS(lev,mDebugOmegaRet); \
-                       FORDF0 { RAC(tcel,l) = m[l]; }   \
-                       usqr = 1.5 * (ux*ux + uy*uy + uz*uz);  \
-                       COLLCHECK;
-#define OPTIMIZED_STREAMCOLLIDE \
-                       m[0] = RAC(ccel,0); \
-                       FORDF1 { /* df0 is set later on... */ \
-                               /* FIXME CHECK INV ? */\
-                               if(RFLAG_NBINV(lev, i,j,k,SRCS(lev),l)&CFBnd) { errMsg("???", "bnd-err-nobndfl"); D::mPanic=1;  \
-                               } else { m[l] = QCELL_NBINV(lev, i, j, k, SRCS(lev), l, l); } \
-                               STREAMCHECK(i+D::dfVecX[D::dfInv[l]], j+D::dfVecY[D::dfInv[l]],k+D::dfVecZ[D::dfInv[l]], l); \
-                       }   \
-                       rho=m[0]; ux = mLevel[lev].gravity[0]; uy = mLevel[lev].gravity[1]; uz = mLevel[lev].gravity[2]; \
-                       ux = mLevel[lev].gravity[0]; uy = mLevel[lev].gravity[1]; uz = mLevel[lev].gravity[2]; \
-                       D::collideArrays( m, rho,ux,uy,uz, OMEGA(lev), mLevel[lev].lcsmago , &mDebugOmegaRet  ); \
-                       CSMOMEGA_STATS(lev,mDebugOmegaRet); \
-                       FORDF0 { RAC(tcel,l) = m[l]; } \
-                       usqr = 1.5 * (ux*ux + uy*uy + uz*uz);  \
-                       COLLCHECK;
+               //! minimal and maximal z-coords (for 2D/3D loops)
+               int getForZMinBnd() { return 0; }
+               int getForZMin1()   { 
+                       if(D::cDimension==2) return 0;
+                       return 1; 
+               }
 
-#else  // 3D, opt OPT3D==true
+               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;
+               }
 
-#define DEFAULT_STREAM \
-               m[dC] = RAC(ccel,dC); \
-               /* explicit streaming */ \
-               if((!nbored & CFBnd)) { \
-                       /* no boundary near?, no real speed diff.? */ \
-                       m[dN ] = CSRC_N ; m[dS ] = CSRC_S ; \
-                       m[dE ] = CSRC_E ; m[dW ] = CSRC_W ; \
-                       m[dT ] = CSRC_T ; m[dB ] = CSRC_B ; \
-                       m[dNE] = CSRC_NE; m[dNW] = CSRC_NW; m[dSE] = CSRC_SE; m[dSW] = CSRC_SW; \
-                       m[dNT] = CSRC_NT; m[dNB] = CSRC_NB; m[dST] = CSRC_ST; m[dSB] = CSRC_SB; \
-                       m[dET] = CSRC_ET; m[dEB] = CSRC_EB; m[dWT] = CSRC_WT; m[dWB] = CSRC_WB; \
-               } else { \
-                       /* explicit streaming */ \
-                       if(NBFLAG(dS )&CFBnd) { m[dN ] = RAC(ccel,dS ); } else { m[dN ] = CSRC_N ; } \
-                       if(NBFLAG(dN )&CFBnd) { m[dS ] = RAC(ccel,dN ); } else { m[dS ] = CSRC_S ; } \
-                       if(NBFLAG(dW )&CFBnd) { m[dE ] = RAC(ccel,dW ); } else { m[dE ] = CSRC_E ; } \
-                       if(NBFLAG(dE )&CFBnd) { m[dW ] = RAC(ccel,dE ); } else { m[dW ] = CSRC_W ; } \
-                       if(NBFLAG(dB )&CFBnd) { m[dT ] = RAC(ccel,dB ); } else { m[dT ] = CSRC_T ; } \
-                       if(NBFLAG(dT )&CFBnd) { m[dB ] = RAC(ccel,dT ); } else { m[dB ] = CSRC_B ; } \
-                       \
-                       if(NBFLAG(dSW)&CFBnd) { m[dNE] = RAC(ccel,dSW); } else { m[dNE] = CSRC_NE; } \
-                       if(NBFLAG(dSE)&CFBnd) { m[dNW] = RAC(ccel,dSE); } else { m[dNW] = CSRC_NW; } \
-                       if(NBFLAG(dNW)&CFBnd) { m[dSE] = RAC(ccel,dNW); } else { m[dSE] = CSRC_SE; } \
-                       if(NBFLAG(dNE)&CFBnd) { m[dSW] = RAC(ccel,dNE); } else { m[dSW] = CSRC_SW; } \
-                       if(NBFLAG(dSB)&CFBnd) { m[dNT] = RAC(ccel,dSB); } else { m[dNT] = CSRC_NT; } \
-                       if(NBFLAG(dST)&CFBnd) { m[dNB] = RAC(ccel,dST); } else { m[dNB] = CSRC_NB; } \
-                       if(NBFLAG(dNB)&CFBnd) { m[dST] = RAC(ccel,dNB); } else { m[dST] = CSRC_ST; } \
-                       if(NBFLAG(dNT)&CFBnd) { m[dSB] = RAC(ccel,dNT); } else { m[dSB] = CSRC_SB; } \
-                       if(NBFLAG(dWB)&CFBnd) { m[dET] = RAC(ccel,dWB); } else { m[dET] = CSRC_ET; } \
-                       if(NBFLAG(dWT)&CFBnd) { m[dEB] = RAC(ccel,dWT); } else { m[dEB] = CSRC_EB; } \
-                       if(NBFLAG(dEB)&CFBnd) { m[dWT] = RAC(ccel,dEB); } else { m[dWT] = CSRC_WT; } \
-                       if(NBFLAG(dET)&CFBnd) { m[dWB] = RAC(ccel,dET); } else { m[dWB] = CSRC_WB; } \
-               } 
 
+               // member vars
 
+               //! mass calculated during streaming step
+               LbmFloat mCurrentMass;
+               LbmFloat mCurrentVolume;
+               LbmFloat mInitialMass;
 
-#define COLL_CALCULATE_DFEQ(dstarray) \
-                       dstarray[dN ] = EQN ; dstarray[dS ] = EQS ; \
-                       dstarray[dE ] = EQE ; dstarray[dW ] = EQW ; \
-                       dstarray[dT ] = EQT ; dstarray[dB ] = EQB ; \
-                       dstarray[dNE] = EQNE; dstarray[dNW] = EQNW; dstarray[dSE] = EQSE; dstarray[dSW] = EQSW; \
-                       dstarray[dNT] = EQNT; dstarray[dNB] = EQNB; dstarray[dST] = EQST; dstarray[dSB] = EQSB; \
-                       dstarray[dET] = EQET; dstarray[dEB] = EQEB; dstarray[dWT] = EQWT; dstarray[dWB] = EQWB; 
-#define COLL_CALCULATE_NONEQTENSOR(csolev, srcArray ) \
-                       lcsmqadd  = (srcArray##NE - lcsmeq[ dNE ]); \
-                       lcsmqadd -= (srcArray##NW - lcsmeq[ dNW ]); \
-                       lcsmqadd -= (srcArray##SE - lcsmeq[ dSE ]); \
-                       lcsmqadd += (srcArray##SW - lcsmeq[ dSW ]); \
-                       lcsmqo = (lcsmqadd*    lcsmqadd); \
-                       lcsmqadd  = (srcArray##ET - lcsmeq[  dET ]); \
-                       lcsmqadd -= (srcArray##EB - lcsmeq[  dEB ]); \
-                       lcsmqadd -= (srcArray##WT - lcsmeq[  dWT ]); \
-                       lcsmqadd += (srcArray##WB - lcsmeq[  dWB ]); \
-                       lcsmqo += (lcsmqadd*    lcsmqadd); \
-                       lcsmqadd  = (srcArray##NT - lcsmeq[  dNT ]); \
-                       lcsmqadd -= (srcArray##NB - lcsmeq[  dNB ]); \
-                       lcsmqadd -= (srcArray##ST - lcsmeq[  dST ]); \
-                       lcsmqadd += (srcArray##SB - lcsmeq[  dSB ]); \
-                       lcsmqo += (lcsmqadd*    lcsmqadd); \
-                       lcsmqo *= 2.0; \
-                       lcsmqadd  = (srcArray##E  -  lcsmeq[ dE  ]); \
-                       lcsmqadd += (srcArray##W  -  lcsmeq[ dW  ]); \
-                       lcsmqadd += (srcArray##NE -  lcsmeq[ dNE ]); \
-                       lcsmqadd += (srcArray##NW -  lcsmeq[ dNW ]); \
-                       lcsmqadd += (srcArray##SE -  lcsmeq[ dSE ]); \
-                       lcsmqadd += (srcArray##SW -  lcsmeq[ dSW ]); \
-                       lcsmqadd += (srcArray##ET  - lcsmeq[ dET ]); \
-                       lcsmqadd += (srcArray##EB  - lcsmeq[ dEB ]); \
-                       lcsmqadd += (srcArray##WT  - lcsmeq[ dWT ]); \
-                       lcsmqadd += (srcArray##WB  - lcsmeq[ dWB ]); \
-                       lcsmqo += (lcsmqadd*    lcsmqadd); \
-                       lcsmqadd  = (srcArray##N  -  lcsmeq[ dN  ]); \
-                       lcsmqadd += (srcArray##S  -  lcsmeq[ dS  ]); \
-                       lcsmqadd += (srcArray##NE -  lcsmeq[ dNE ]); \
-                       lcsmqadd += (srcArray##NW -  lcsmeq[ dNW ]); \
-                       lcsmqadd += (srcArray##SE -  lcsmeq[ dSE ]); \
-                       lcsmqadd += (srcArray##SW -  lcsmeq[ dSW ]); \
-                       lcsmqadd += (srcArray##NT  - lcsmeq[ dNT ]); \
-                       lcsmqadd += (srcArray##NB  - lcsmeq[ dNB ]); \
-                       lcsmqadd += (srcArray##ST  - lcsmeq[ dST ]); \
-                       lcsmqadd += (srcArray##SB  - lcsmeq[ dSB ]); \
-                       lcsmqo += (lcsmqadd*    lcsmqadd); \
-                       lcsmqadd  = (srcArray##T  -  lcsmeq[ dT  ]); \
-                       lcsmqadd += (srcArray##B  -  lcsmeq[ dB  ]); \
-                       lcsmqadd += (srcArray##NT -  lcsmeq[ dNT ]); \
-                       lcsmqadd += (srcArray##NB -  lcsmeq[ dNB ]); \
-                       lcsmqadd += (srcArray##ST -  lcsmeq[ dST ]); \
-                       lcsmqadd += (srcArray##SB -  lcsmeq[ dSB ]); \
-                       lcsmqadd += (srcArray##ET  - lcsmeq[ dET ]); \
-                       lcsmqadd += (srcArray##EB  - lcsmeq[ dEB ]); \
-                       lcsmqadd += (srcArray##WT  - lcsmeq[ dWT ]); \
-                       lcsmqadd += (srcArray##WB  - lcsmeq[ dWB ]); \
-                       lcsmqo += (lcsmqadd*    lcsmqadd); \
-                       lcsmqo = sqrt(lcsmqo); /* FIXME check effect of sqrt*/ \
+               //! count problematic cases, that occured so far...
+               int mNumProblems;
 
-//                     COLL_CALCULATE_CSMOMEGAVAL(csolev, lcsmomega); 
+               // average mlsups, count how many so far...
+               double mAvgMLSUPS;
+               double mAvgMLSUPSCnt;
 
-// careful - need lcsmqo 
-#define COLL_CALCULATE_CSMOMEGAVAL(csolev, dstomega ) \
-                       dstomega =  1.0/\
-                                       ( 3.0*( mLevel[(csolev)].lcnu+mLevel[(csolev)].lcsmago_sqr*(\
-                                                       -mLevel[(csolev)].lcnu + sqrt( mLevel[(csolev)].lcnu*mLevel[(csolev)].lcnu + 18.0*mLevel[(csolev)].lcsmago_sqr* lcsmqo ) \
-                                                       / (6.0*mLevel[(csolev)].lcsmago_sqr)) \
-                                               ) +0.5 ); 
+               //! Mcubes object for surface reconstruction 
+               IsoSurface *mpPreviewSurface;
+               int mLoopSubdivs;
+               float mSmoothSurface;
+               float mSmoothNormals;
+               
+               //! use time adaptivity? 
+               bool mTimeAdap;
 
-#define DEFAULT_COLLIDE_LES \
-                       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); \
-                       COLL_CALCULATE_DFEQ(lcsmeq); \
-                       COLL_CALCULATE_NONEQTENSOR(lev, MSRC_)\
-                       COLL_CALCULATE_CSMOMEGAVAL(lev, lcsmomega); \
-                       CSMOMEGA_STATS(lev,lcsmomega); \
-                       \
-                       RAC(tcel,dC ) = (1.0-lcsmomega)*MSRC_C  + lcsmomega*EQC ; \
-                       \
-                       RAC(tcel,dN ) = (1.0-lcsmomega)*MSRC_N  + lcsmomega*lcsmeq[ dN ]; \
-                       RAC(tcel,dS ) = (1.0-lcsmomega)*MSRC_S  + lcsmomega*lcsmeq[ dS ]; \
-                       RAC(tcel,dE ) = (1.0-lcsmomega)*MSRC_E  + lcsmomega*lcsmeq[ dE ]; \
-                       RAC(tcel,dW ) = (1.0-lcsmomega)*MSRC_W  + lcsmomega*lcsmeq[ dW ]; \
-                       RAC(tcel,dT ) = (1.0-lcsmomega)*MSRC_T  + lcsmomega*lcsmeq[ dT ]; \
-                       RAC(tcel,dB ) = (1.0-lcsmomega)*MSRC_B  + lcsmomega*lcsmeq[ dB ]; \
-                       \
-                       RAC(tcel,dNE) = (1.0-lcsmomega)*MSRC_NE + lcsmomega*lcsmeq[ dNE]; \
-                       RAC(tcel,dNW) = (1.0-lcsmomega)*MSRC_NW + lcsmomega*lcsmeq[ dNW]; \
-                       RAC(tcel,dSE) = (1.0-lcsmomega)*MSRC_SE + lcsmomega*lcsmeq[ dSE]; \
-                       RAC(tcel,dSW) = (1.0-lcsmomega)*MSRC_SW + lcsmomega*lcsmeq[ dSW]; \
-                       RAC(tcel,dNT) = (1.0-lcsmomega)*MSRC_NT + lcsmomega*lcsmeq[ dNT]; \
-                       RAC(tcel,dNB) = (1.0-lcsmomega)*MSRC_NB + lcsmomega*lcsmeq[ dNB]; \
-                       RAC(tcel,dST) = (1.0-lcsmomega)*MSRC_ST + lcsmomega*lcsmeq[ dST]; \
-                       RAC(tcel,dSB) = (1.0-lcsmomega)*MSRC_SB + lcsmomega*lcsmeq[ dSB]; \
-                       RAC(tcel,dET) = (1.0-lcsmomega)*MSRC_ET + lcsmomega*lcsmeq[ dET]; \
-                       RAC(tcel,dEB) = (1.0-lcsmomega)*MSRC_EB + lcsmomega*lcsmeq[ dEB]; \
-                       RAC(tcel,dWT) = (1.0-lcsmomega)*MSRC_WT + lcsmomega*lcsmeq[ dWT]; \
-                       RAC(tcel,dWB) = (1.0-lcsmomega)*MSRC_WB + lcsmomega*lcsmeq[ dWB]; 
+               //! output surface preview? if >0 yes, and use as reduzed size 
+               int mOutputSurfacePreview;
+               LbmFloat mPreviewFactor;
+               //! fluid vol height
+               LbmFloat mFVHeight;
+               LbmFloat mFVArea;
+               bool mUpdateFVHeight;
 
-#define DEFAULT_COLLIDE_NOLES \
-                       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); \
-                       \
-                       RAC(tcel,dC ) = (1.0-OMEGA(lev))*MSRC_C  + OMEGA(lev)*EQC ; \
-                       \
-                       RAC(tcel,dN ) = (1.0-OMEGA(lev))*MSRC_N  + OMEGA(lev)*EQN ; \
-                       RAC(tcel,dS ) = (1.0-OMEGA(lev))*MSRC_S  + OMEGA(lev)*EQS ; \
-                       RAC(tcel,dE ) = (1.0-OMEGA(lev))*MSRC_E  + OMEGA(lev)*EQE ; \
-                       RAC(tcel,dW ) = (1.0-OMEGA(lev))*MSRC_W  + OMEGA(lev)*EQW ; \
-                       RAC(tcel,dT ) = (1.0-OMEGA(lev))*MSRC_T  + OMEGA(lev)*EQT ; \
-                       RAC(tcel,dB ) = (1.0-OMEGA(lev))*MSRC_B  + OMEGA(lev)*EQB ; \
-                       \
-                       RAC(tcel,dNE) = (1.0-OMEGA(lev))*MSRC_NE + OMEGA(lev)*EQNE; \
-                       RAC(tcel,dNW) = (1.0-OMEGA(lev))*MSRC_NW + OMEGA(lev)*EQNW; \
-                       RAC(tcel,dSE) = (1.0-OMEGA(lev))*MSRC_SE + OMEGA(lev)*EQSE; \
-                       RAC(tcel,dSW) = (1.0-OMEGA(lev))*MSRC_SW + OMEGA(lev)*EQSW; \
-                       RAC(tcel,dNT) = (1.0-OMEGA(lev))*MSRC_NT + OMEGA(lev)*EQNT; \
-                       RAC(tcel,dNB) = (1.0-OMEGA(lev))*MSRC_NB + OMEGA(lev)*EQNB; \
-                       RAC(tcel,dST) = (1.0-OMEGA(lev))*MSRC_ST + OMEGA(lev)*EQST; \
-                       RAC(tcel,dSB) = (1.0-OMEGA(lev))*MSRC_SB + OMEGA(lev)*EQSB; \
-                       RAC(tcel,dET) = (1.0-OMEGA(lev))*MSRC_ET + OMEGA(lev)*EQET; \
-                       RAC(tcel,dEB) = (1.0-OMEGA(lev))*MSRC_EB + OMEGA(lev)*EQEB; \
-                       RAC(tcel,dWT) = (1.0-OMEGA(lev))*MSRC_WT + OMEGA(lev)*EQWT; \
-                       RAC(tcel,dWB) = (1.0-OMEGA(lev))*MSRC_WB + OMEGA(lev)*EQWB; 
+               //! 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;
 
-#define OPTIMIZED_STREAMCOLLIDE_LES \
-                       /* only surrounded by fluid cells...!, so safe streaming here... */ \
-                       m[dC ] = CSRC_C ; \
-                       m[dN ] = CSRC_N ; m[dS ] = CSRC_S ; \
-                       m[dE ] = CSRC_E ; m[dW ] = CSRC_W ; \
-                       m[dT ] = CSRC_T ; m[dB ] = CSRC_B ; \
-                       m[dNE] = CSRC_NE; m[dNW] = CSRC_NW; m[dSE] = CSRC_SE; m[dSW] = CSRC_SW; \
-                       m[dNT] = CSRC_NT; m[dNB] = CSRC_NB; m[dST] = CSRC_ST; m[dSB] = CSRC_SB; \
-                       m[dET] = CSRC_ET; m[dEB] = CSRC_EB; m[dWT] = CSRC_WT; m[dWB] = CSRC_WB; \
-                       \
-                       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 + mLevel[lev].gravity[0];  \
-                       uy = MSRC_N - MSRC_S + MSRC_NE + MSRC_NW - MSRC_SE - MSRC_SW \
-                               + MSRC_NT + MSRC_NB - MSRC_ST - MSRC_SB + mLevel[lev].gravity[1];  \
-                       uz = MSRC_T - MSRC_B + MSRC_NT - MSRC_NB + MSRC_ST - MSRC_SB \
-                               + MSRC_ET - MSRC_EB + MSRC_WT - MSRC_WB + mLevel[lev].gravity[2];  \
-                       usqr = 1.5 * (ux*ux + uy*uy + uz*uz); \
-                       COLL_CALCULATE_DFEQ(lcsmeq); \
-                       COLL_CALCULATE_NONEQTENSOR(lev, MSRC_) \
-                       COLL_CALCULATE_CSMOMEGAVAL(lev, lcsmomega); \
-                       CSMOMEGA_STATS(lev,lcsmomega); \
-                       \
-                       RAC(tcel,dC ) = (1.0-lcsmomega)*MSRC_C  + lcsmomega*EQC ; \
-                       RAC(tcel,dN ) = (1.0-lcsmomega)*MSRC_N  + lcsmomega*lcsmeq[ dN ];  \
-                       RAC(tcel,dS ) = (1.0-lcsmomega)*MSRC_S  + lcsmomega*lcsmeq[ dS ];  \
-                       RAC(tcel,dE ) = (1.0-lcsmomega)*MSRC_E  + lcsmomega*lcsmeq[ dE ]; \
-                       RAC(tcel,dW ) = (1.0-lcsmomega)*MSRC_W  + lcsmomega*lcsmeq[ dW ];  \
-                       RAC(tcel,dT ) = (1.0-lcsmomega)*MSRC_T  + lcsmomega*lcsmeq[ dT ];  \
-                       RAC(tcel,dB ) = (1.0-lcsmomega)*MSRC_B  + lcsmomega*lcsmeq[ dB ]; \
-                       \
-                       RAC(tcel,dNE) = (1.0-lcsmomega)*MSRC_NE + lcsmomega*lcsmeq[ dNE];  \
-                       RAC(tcel,dNW) = (1.0-lcsmomega)*MSRC_NW + lcsmomega*lcsmeq[ dNW];  \
-                       RAC(tcel,dSE) = (1.0-lcsmomega)*MSRC_SE + lcsmomega*lcsmeq[ dSE];  \
-                       RAC(tcel,dSW) = (1.0-lcsmomega)*MSRC_SW + lcsmomega*lcsmeq[ dSW]; \
-                       \
-                       RAC(tcel,dNT) = (1.0-lcsmomega)*MSRC_NT + lcsmomega*lcsmeq[ dNT];  \
-                       RAC(tcel,dNB) = (1.0-lcsmomega)*MSRC_NB + lcsmomega*lcsmeq[ dNB];  \
-                       RAC(tcel,dST) = (1.0-lcsmomega)*MSRC_ST + lcsmomega*lcsmeq[ dST];  \
-                       RAC(tcel,dSB) = (1.0-lcsmomega)*MSRC_SB + lcsmomega*lcsmeq[ dSB]; \
-                       \
-                       RAC(tcel,dET) = (1.0-lcsmomega)*MSRC_ET + lcsmomega*lcsmeq[ dET];  \
-                       RAC(tcel,dEB) = (1.0-lcsmomega)*MSRC_EB + lcsmomega*lcsmeq[ dEB]; \
-                       RAC(tcel,dWT) = (1.0-lcsmomega)*MSRC_WT + lcsmomega*lcsmeq[ dWT];  \
-                       RAC(tcel,dWB) = (1.0-lcsmomega)*MSRC_WB + lcsmomega*lcsmeq[ dWB];  \
-
-#define OPTIMIZED_STREAMCOLLIDE_UNUSED \
-                       /* only surrounded by fluid cells...!, so safe streaming here... */ \
-                       rho = CSRC_C  + CSRC_N + CSRC_S  + CSRC_E + CSRC_W  + CSRC_T  \
-                               + CSRC_B  + CSRC_NE + CSRC_NW + CSRC_SE + CSRC_SW + CSRC_NT \
-                               + CSRC_NB + CSRC_ST + CSRC_SB + CSRC_ET + CSRC_EB + CSRC_WT + CSRC_WB; \
-                       ux = CSRC_E - CSRC_W + CSRC_NE - CSRC_NW + CSRC_SE - CSRC_SW \
-                               + CSRC_ET + CSRC_EB - CSRC_WT - CSRC_WB + mLevel[lev].gravity[0];  \
-                       uy = CSRC_N - CSRC_S + CSRC_NE + CSRC_NW - CSRC_SE - CSRC_SW \
-                               + CSRC_NT + CSRC_NB - CSRC_ST - CSRC_SB + mLevel[lev].gravity[1];  \
-                       uz = CSRC_T - CSRC_B + CSRC_NT - CSRC_NB + CSRC_ST - CSRC_SB \
-                               + CSRC_ET - CSRC_EB + CSRC_WT - CSRC_WB + mLevel[lev].gravity[2];  \
-                       usqr = 1.5 * (ux*ux + uy*uy + uz*uz); \
-                       COLL_CALCULATE_DFEQ(lcsmeq); \
-                       COLL_CALCULATE_NONEQTENSOR(lev, CSRC_) \
-                       COLL_CALCULATE_CSMOMEGAVAL(lev, lcsmomega); \
-                       \
-                       RAC(tcel,dC ) = (1.0-lcsmomega)*CSRC_C  + lcsmomega*EQC ; \
-                       RAC(tcel,dN ) = (1.0-lcsmomega)*CSRC_N  + lcsmomega*lcsmeq[ dN ];  \
-                       RAC(tcel,dS ) = (1.0-lcsmomega)*CSRC_S  + lcsmomega*lcsmeq[ dS ];  \
-                       RAC(tcel,dE ) = (1.0-lcsmomega)*CSRC_E  + lcsmomega*lcsmeq[ dE ]; \
-                       RAC(tcel,dW ) = (1.0-lcsmomega)*CSRC_W  + lcsmomega*lcsmeq[ dW ];  \
-                       RAC(tcel,dT ) = (1.0-lcsmomega)*CSRC_T  + lcsmomega*lcsmeq[ dT ];  \
-                       RAC(tcel,dB ) = (1.0-lcsmomega)*CSRC_B  + lcsmomega*lcsmeq[ dB ]; \
-                       \
-                       RAC(tcel,dNE) = (1.0-lcsmomega)*CSRC_NE + lcsmomega*lcsmeq[ dNE];  \
-                       RAC(tcel,dNW) = (1.0-lcsmomega)*CSRC_NW + lcsmomega*lcsmeq[ dNW];  \
-                       RAC(tcel,dSE) = (1.0-lcsmomega)*CSRC_SE + lcsmomega*lcsmeq[ dSE];  \
-                       RAC(tcel,dSW) = (1.0-lcsmomega)*CSRC_SW + lcsmomega*lcsmeq[ dSW]; \
-                       \
-                       RAC(tcel,dNT) = (1.0-lcsmomega)*CSRC_NT + lcsmomega*lcsmeq[ dNT];  \
-                       RAC(tcel,dNB) = (1.0-lcsmomega)*CSRC_NB + lcsmomega*lcsmeq[ dNB];  \
-                       RAC(tcel,dST) = (1.0-lcsmomega)*CSRC_ST + lcsmomega*lcsmeq[ dST];  \
-                       RAC(tcel,dSB) = (1.0-lcsmomega)*CSRC_SB + lcsmomega*lcsmeq[ dSB]; \
-                       \
-                       RAC(tcel,dET) = (1.0-lcsmomega)*CSRC_ET + lcsmomega*lcsmeq[ dET];  \
-                       RAC(tcel,dEB) = (1.0-lcsmomega)*CSRC_EB + lcsmomega*lcsmeq[ dEB]; \
-                       RAC(tcel,dWT) = (1.0-lcsmomega)*CSRC_WT + lcsmomega*lcsmeq[ dWT];  \
-                       RAC(tcel,dWB) = (1.0-lcsmomega)*CSRC_WB + lcsmomega*lcsmeq[ dWB];  \
-
-#define OPTIMIZED_STREAMCOLLIDE_NOLES \
-                       /* only surrounded by fluid cells...!, so safe streaming here... */ \
-                       rho = CSRC_C  + CSRC_N + CSRC_S  + CSRC_E + CSRC_W  + CSRC_T  \
-                               + CSRC_B  + CSRC_NE + CSRC_NW + CSRC_SE + CSRC_SW + CSRC_NT \
-                               + CSRC_NB + CSRC_ST + CSRC_SB + CSRC_ET + CSRC_EB + CSRC_WT + CSRC_WB; \
-                       ux = CSRC_E - CSRC_W + CSRC_NE - CSRC_NW + CSRC_SE - CSRC_SW \
-                               + CSRC_ET + CSRC_EB - CSRC_WT - CSRC_WB + mLevel[lev].gravity[0];  \
-                       uy = CSRC_N - CSRC_S + CSRC_NE + CSRC_NW - CSRC_SE - CSRC_SW \
-                               + CSRC_NT + CSRC_NB - CSRC_ST - CSRC_SB + mLevel[lev].gravity[1];  \
-                       uz = CSRC_T - CSRC_B + CSRC_NT - CSRC_NB + CSRC_ST - CSRC_SB \
-                               + CSRC_ET - CSRC_EB + CSRC_WT - CSRC_WB + mLevel[lev].gravity[2];  \
-                       usqr = 1.5 * (ux*ux + uy*uy + uz*uz); \
-                       RAC(tcel,dC ) = (1.0-OMEGA(lev))*CSRC_C  + OMEGA(lev)*EQC ; \
-                       RAC(tcel,dN ) = (1.0-OMEGA(lev))*CSRC_N  + OMEGA(lev)*EQN ;  \
-                       RAC(tcel,dS ) = (1.0-OMEGA(lev))*CSRC_S  + OMEGA(lev)*EQS ;  \
-                       RAC(tcel,dE ) = (1.0-OMEGA(lev))*CSRC_E  + OMEGA(lev)*EQE ; \
-                       RAC(tcel,dW ) = (1.0-OMEGA(lev))*CSRC_W  + OMEGA(lev)*EQW ;  \
-                       RAC(tcel,dT ) = (1.0-OMEGA(lev))*CSRC_T  + OMEGA(lev)*EQT ;  \
-                       RAC(tcel,dB ) = (1.0-OMEGA(lev))*CSRC_B  + OMEGA(lev)*EQB ; \
-                        \
-                       RAC(tcel,dNE) = (1.0-OMEGA(lev))*CSRC_NE + OMEGA(lev)*EQNE;  \
-                       RAC(tcel,dNW) = (1.0-OMEGA(lev))*CSRC_NW + OMEGA(lev)*EQNW;  \
-                       RAC(tcel,dSE) = (1.0-OMEGA(lev))*CSRC_SE + OMEGA(lev)*EQSE;  \
-                       RAC(tcel,dSW) = (1.0-OMEGA(lev))*CSRC_SW + OMEGA(lev)*EQSW; \
-                        \
-                       RAC(tcel,dNT) = (1.0-OMEGA(lev))*CSRC_NT + OMEGA(lev)*EQNT;  \
-                       RAC(tcel,dNB) = (1.0-OMEGA(lev))*CSRC_NB + OMEGA(lev)*EQNB;  \
-                       RAC(tcel,dST) = (1.0-OMEGA(lev))*CSRC_ST + OMEGA(lev)*EQST;  \
-                       RAC(tcel,dSB) = (1.0-OMEGA(lev))*CSRC_SB + OMEGA(lev)*EQSB; \
-                        \
-                       RAC(tcel,dET) = (1.0-OMEGA(lev))*CSRC_ET + OMEGA(lev)*EQET;  \
-                       RAC(tcel,dEB) = (1.0-OMEGA(lev))*CSRC_EB + OMEGA(lev)*EQEB; \
-                       RAC(tcel,dWT) = (1.0-OMEGA(lev))*CSRC_WT + OMEGA(lev)*EQWT;  \
-                       RAC(tcel,dWB) = (1.0-OMEGA(lev))*CSRC_WB + OMEGA(lev)*EQWB;  \
-
+               //! 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;
 
-// debug version1
-#define STREAMCHECK(ni,nj,nk,nl) 
-#define COLLCHECK
-#define OPTIMIZED_STREAMCOLLIDE_DEBUG \
-                       m[0] = RAC(ccel,0); \
-                       FORDF1 { /* df0 is set later on... */ \
-                               if(RFLAG_NB(lev, i,j,k,SRCS(lev),l)&CFBnd) { errMsg("???", "bnd-err-nobndfl"); D::mPanic=1;  \
-                               } else { m[l] = QCELL_NBINV(lev, i, j, k, SRCS(lev), l, l); } \
-                               STREAMCHECK(i+D::dfVecX[D::dfInv[l]], j+D::dfVecY[D::dfInv[l]],k+D::dfVecZ[D::dfInv[l]], l); \
-                       }   \
-                       rho=m[0]; ux = mLevel[lev].gravity[0]; uy = mLevel[lev].gravity[1]; uz = mLevel[lev].gravity[2]; \
-                       ux = mLevel[lev].gravity[0]; uy = mLevel[lev].gravity[1]; uz = mLevel[lev].gravity[2]; \
-                       D::collideArrays( m, rho,ux,uy,uz, OMEGA(lev), mLevel[lev].lcsmago , &mDebugOmegaRet  ); \
-                       CSMOMEGA_STATS(lev,mDebugOmegaRet); \
-                       FORDF0 { RAC(tcel,l) = m[l]; } \
-                       usqr = 1.5 * (ux*ux + uy*uy + uz*uz);  \
-                       COLLCHECK;
+               //! 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;
 
-// more debugging
-/*DEBUG \
-                       m[0] = RAC(ccel,0); \
-                       FORDF1 { \
-                               if(RFLAG_NB(lev, i,j,k,SRCS(lev),l)&CFBnd) { errMsg("???", "bnd-err-nobndfl"); D::mPanic=1;  \
-                               } else { m[l] = QCELL_NBINV(lev, i, j, k, SRCS(lev), l, l); } \
-                       }   \
-f__printf(stderr,"QSDM at %d,%d,%d  lcsmqo=%25.15f, lcsmomega=%f \n", i,j,k, lcsmqo,lcsmomega ); \
-                       rho=m[0]; ux = mLevel[lev].gravity[0]; uy = mLevel[lev].gravity[1]; uz = mLevel[lev].gravity[2]; \
-                       ux = mLevel[lev].gravity[0]; uy = mLevel[lev].gravity[1]; uz = mLevel[lev].gravity[2]; \
-                       D::collideArrays( m, rho,ux,uy,uz, OMEGA(lev), mLevel[lev].lcsmago  , &mDebugOmegaRet ); \
-                       CSMOMEGA_STATS(lev,mDebugOmegaRet); \
-                       */
-#if USE_LES==1
-#define DEFAULT_COLLIDE DEFAULT_COLLIDE_LES
-#define OPTIMIZED_STREAMCOLLIDE OPTIMIZED_STREAMCOLLIDE_LES
-#else 
-#define DEFAULT_COLLIDE DEFAULT_COLLIDE_NOLES
-#define OPTIMIZED_STREAMCOLLIDE OPTIMIZED_STREAMCOLLIDE_NOLES
-#endif
+               /*! df scale factors for level up/down */
+               LbmFloat mDfScaleUp, mDfScaleDown;
 
-#endif
+               /*! precomputed cell area values */
+               LbmFloat mFsgrCellArea[27];
 
-#define USQRMAXCHECK(Cusqr,Cux,Cuy,Cuz,  CmMaxVlen,CmMxvx,CmMxvy,CmMxvz) \
-                       if(Cusqr>CmMaxVlen) { \
-                               CmMxvx = Cux; CmMxvy = Cuy; CmMxvz = Cuz; CmMaxVlen = Cusqr; \
-                       } /* stats */ 
+               /*! 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;
 
-// iso value defines
-// border for marching cubes
-#define ISOCORR 3
+               //! debug function to disable standing f init
+               int mDisableStandingFluidInit;
+               //! debug function to force tadap syncing
+               int mForceTadapRefine;
 
 
-// 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) )
+               // 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
+};
 
 
-// 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;
+// relaxation_macros
 
-               //! 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;
-               }
-};
+// 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
 
-//! 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];
+// flag array defines -----------------------------------------------------------------------------------------------
 
-       //! smago params and precalculated values
-       LbmFloat lcsmago;
-       LbmFloat lcsmago_sqr;
-       LbmFloat lcnu;
+// lbm testsolver get index define
+#define _LBMGI(level, ii,ij,ik, is) ( (mLevel[level].lOffsy*(ik)) + (mLevel[level].lOffsx*(ij)) + (ii) )
 
-       // LES statistics per level
-       double avgOmega;
-       double avgOmegaCnt;
-
-       //! current set of dist funcs 
-       int setCurr;
-       //! target/other set of dist funcs 
-       int setOther;
+//! flag array acces macro
+#define _RFLAG(level,xx,yy,zz,set) mLevel[level].mprsFlags[set][ LBMGI((level),(xx),(yy),(zz),(set)) ]
+#define _RFLAG_NB(level,xx,yy,zz,set, dir) mLevel[level].mprsFlags[set][ LBMGI((level),(xx)+D::dfVecX[dir],(yy)+D::dfVecY[dir],(zz)+D::dfVecZ[dir],set) ]
+#define _RFLAG_NBINV(level,xx,yy,zz,set, dir) mLevel[level].mprsFlags[set][ LBMGI((level),(xx)+D::dfVecX[D::dfInv[dir]],(yy)+D::dfVecY[D::dfInv[dir]],(zz)+D::dfVecZ[D::dfInv[dir]],set) ]
 
-       //! mass&volume for this level
-       LbmFloat lmass;
-       LbmFloat lvolume;
-       LbmFloat lcellfactor;
+// array data layouts
+// standard array layout  -----------------------------------------------------------------------------------------------
+#define ALSTRING "Standard Array Layout"
+//#define _LBMQI(level, ii,ij,ik, is, lunused) ( ((is)*mLevel[level].lOffsz) + (mLevel[level].lOffsy*(ik)) + (mLevel[level].lOffsx*(ij)) + (ii) )
+#define _LBMQI(level, ii,ij,ik, is, lunused) ( (mLevel[level].lOffsy*(ik)) + (mLevel[level].lOffsx*(ij)) + (ii) )
+#define _QCELL(level,xx,yy,zz,set,l) (mLevel[level].mprsCells[(set)][ LBMQI((level),(xx),(yy),(zz),(set), l)*dTotalNum +(l)])
+#define _QCELL_NB(level,xx,yy,zz,set, dir,l) (mLevel[level].mprsCells[(set)][ LBMQI((level),(xx)+D::dfVecX[dir],(yy)+D::dfVecY[dir],(zz)+D::dfVecZ[dir],set, l)*dTotalNum +(l)])
+#define _QCELL_NBINV(level,xx,yy,zz,set, dir,l) (mLevel[level].mprsCells[(set)][ LBMQI((level),(xx)+D::dfVecX[D::dfInv[dir]],(yy)+D::dfVecY[D::dfInv[dir]],(zz)+D::dfVecZ[D::dfInv[dir]],set, l)*dTotalNum +(l)])
 
-       //! local storage of mSizes
-       int lSizex, lSizey, lSizez;
-       int lOffsx, lOffsy, lOffsz;
+#define QCELLSTEP dTotalNum
+#define _RACPNT(level, ii,ij,ik, is )  &QCELL(level,ii,ij,ik,is,0)
+#define _RAC(s,l) (s)[(l)]
 
-};
+// standard arrays
+#define CSRC_C    RAC(ccel                                , dC )
+#define CSRC_E    RAC(ccel + (-1)             *(dTotalNum), dE )
+#define CSRC_W    RAC(ccel + (+1)             *(dTotalNum), dW )
+#define CSRC_N    RAC(ccel + (-mLevel[lev].lOffsx)        *(dTotalNum), dN )
+#define CSRC_S    RAC(ccel + (+mLevel[lev].lOffsx)        *(dTotalNum), dS )
+#define CSRC_NE   RAC(ccel + (-mLevel[lev].lOffsx-1)      *(dTotalNum), dNE)
+#define CSRC_NW   RAC(ccel + (-mLevel[lev].lOffsx+1)      *(dTotalNum), dNW)
+#define CSRC_SE   RAC(ccel + (+mLevel[lev].lOffsx-1)      *(dTotalNum), dSE)
+#define CSRC_SW   RAC(ccel + (+mLevel[lev].lOffsx+1)      *(dTotalNum), dSW)
+#define CSRC_T    RAC(ccel + (-mLevel[lev].lOffsy)        *(dTotalNum), dT )
+#define CSRC_B    RAC(ccel + (+mLevel[lev].lOffsy)        *(dTotalNum), dB )
+#define CSRC_ET   RAC(ccel + (-mLevel[lev].lOffsy-1)      *(dTotalNum), dET)
+#define CSRC_EB   RAC(ccel + (+mLevel[lev].lOffsy-1)      *(dTotalNum), dEB)
+#define CSRC_WT   RAC(ccel + (-mLevel[lev].lOffsy+1)      *(dTotalNum), dWT)
+#define CSRC_WB   RAC(ccel + (+mLevel[lev].lOffsy+1)      *(dTotalNum), dWB)
+#define CSRC_NT   RAC(ccel + (-mLevel[lev].lOffsy-mLevel[lev].lOffsx) *(dTotalNum), dNT)
+#define CSRC_NB   RAC(ccel + (+mLevel[lev].lOffsy-mLevel[lev].lOffsx) *(dTotalNum), dNB)
+#define CSRC_ST   RAC(ccel + (-mLevel[lev].lOffsy+mLevel[lev].lOffsx) *(dTotalNum), dST)
+#define CSRC_SB   RAC(ccel + (+mLevel[lev].lOffsy+mLevel[lev].lOffsx) *(dTotalNum), dSB)
 
+#define XSRC_C(x)    RAC(ccel + (x)                 *dTotalNum, dC )
+#define XSRC_E(x)    RAC(ccel + ((x)-1)             *dTotalNum, dE )
+#define XSRC_W(x)    RAC(ccel + ((x)+1)             *dTotalNum, dW )
+#define XSRC_N(x)    RAC(ccel + ((x)-mLevel[lev].lOffsx)        *dTotalNum, dN )
+#define XSRC_S(x)    RAC(ccel + ((x)+mLevel[lev].lOffsx)        *dTotalNum, dS )
+#define XSRC_NE(x)   RAC(ccel + ((x)-mLevel[lev].lOffsx-1)      *dTotalNum, dNE)
+#define XSRC_NW(x)   RAC(ccel + ((x)-mLevel[lev].lOffsx+1)      *dTotalNum, dNW)
+#define XSRC_SE(x)   RAC(ccel + ((x)+mLevel[lev].lOffsx-1)      *dTotalNum, dSE)
+#define XSRC_SW(x)   RAC(ccel + ((x)+mLevel[lev].lOffsx+1)      *dTotalNum, dSW)
+#define XSRC_T(x)    RAC(ccel + ((x)-mLevel[lev].lOffsy)        *dTotalNum, dT )
+#define XSRC_B(x)    RAC(ccel + ((x)+mLevel[lev].lOffsy)        *dTotalNum, dB )
+#define XSRC_ET(x)   RAC(ccel + ((x)-mLevel[lev].lOffsy-1)      *dTotalNum, dET)
+#define XSRC_EB(x)   RAC(ccel + ((x)+mLevel[lev].lOffsy-1)      *dTotalNum, dEB)
+#define XSRC_WT(x)   RAC(ccel + ((x)-mLevel[lev].lOffsy+1)      *dTotalNum, dWT)
+#define XSRC_WB(x)   RAC(ccel + ((x)+mLevel[lev].lOffsy+1)      *dTotalNum, dWB)
+#define XSRC_NT(x)   RAC(ccel + ((x)-mLevel[lev].lOffsy-mLevel[lev].lOffsx) *dTotalNum, dNT)
+#define XSRC_NB(x)   RAC(ccel + ((x)+mLevel[lev].lOffsy-mLevel[lev].lOffsx) *dTotalNum, dNB)
+#define XSRC_ST(x)   RAC(ccel + ((x)-mLevel[lev].lOffsy+mLevel[lev].lOffsx) *dTotalNum, dST)
+#define XSRC_SB(x)   RAC(ccel + ((x)+mLevel[lev].lOffsy+mLevel[lev].lOffsx) *dTotalNum, dSB)
 
 
-/*****************************************************************************/
-/*! 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(); }
+#if FSGR_STRICT_DEBUG==1
 
-               //! 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*/ );
+#define LBMGI(level,ii,ij,ik, is)                 debLBMGI(level,ii,ij,ik, is)         
+#define RFLAG(level,xx,yy,zz,set)                 debRFLAG(level,xx,yy,zz,set)            
+#define RFLAG_NB(level,xx,yy,zz,set, dir)         debRFLAG_NB(level,xx,yy,zz,set, dir)    
+#define RFLAG_NBINV(level,xx,yy,zz,set, dir)      debRFLAG_NBINV(level,xx,yy,zz,set, dir) 
 
-#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);
+#define LBMQI(level,ii,ij,ik, is, l)              debLBMQI(level,ii,ij,ik, is, l)         
+#define QCELL(level,xx,yy,zz,set,l)               debQCELL(level,xx,yy,zz,set,l)         
+#define QCELL_NB(level,xx,yy,zz,set, dir,l)       debQCELL_NB(level,xx,yy,zz,set, dir,l)
+#define QCELL_NBINV(level,xx,yy,zz,set, dir,l)    debQCELL_NBINV(level,xx,yy,zz,set, dir,l)
+#define RACPNT(level, ii,ij,ik, is )              debRACPNT(level, ii,ij,ik, is )          
+#define RAC(s,l)                                               debRAC(s,l)                  
 
-               //! perform geometry init (if switched on) 
-               bool initGeometryFlags();
-               //! init part for all freesurface testcases 
-               void initFreeSurfaces();
-               //! init density gradient if enabled
-               void initStandingFluidGradient();
+#else // FSGR_STRICT_DEBUG==1
 
-               /*! 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);
+#define LBMGI(level,ii,ij,ik, is)                 _LBMGI(level,ii,ij,ik, is)         
+#define RFLAG(level,xx,yy,zz,set)                 _RFLAG(level,xx,yy,zz,set)            
+#define RFLAG_NB(level,xx,yy,zz,set, dir)         _RFLAG_NB(level,xx,yy,zz,set, dir)    
+#define RFLAG_NBINV(level,xx,yy,zz,set, dir)      _RFLAG_NBINV(level,xx,yy,zz,set, dir) 
 
-               /*! 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);
+#define LBMQI(level,ii,ij,ik, is, l)              _LBMQI(level,ii,ij,ik, is, l)         
+#define QCELL(level,xx,yy,zz,set,l)               _QCELL(level,xx,yy,zz,set,l)         
+#define QCELL_NB(level,xx,yy,zz,set, dir,l)       _QCELL_NB(level,xx,yy,zz,set, dir, l)
+#define QCELL_NBINV(level,xx,yy,zz,set, dir,l)    _QCELL_NBINV(level,xx,yy,zz,set, dir,l)
+#define RACPNT(level, ii,ij,ik, is )              _RACPNT(level, ii,ij,ik, is )          
+#define RAC(s,l)                                  _RAC(s,l)                  
 
-               /*! init particle positions */
-               virtual int initParticles(ParticleTracer *partt);
-               /*! move all particles */
-               virtual void advanceParticles(ParticleTracer *partt );
+#endif // FSGR_STRICT_DEBUG==1
 
+// general defines -----------------------------------------------------------------------------------------------
 
-               /*! debug object display (used e.g. for preview surface) */
-               virtual vector<ntlGeometryObject*> getDebugObjects();
+#define TESTFLAG(flag, compflag) ((flag & compflag)==compflag)
 
-               //! access the fillfrac field (for viz)
-               float getFillFrac(int i, int j, int k) {
-                       return QCELL(mMaxRefine, i,j,k,mLevel[mMaxRefine].setOther, dFfrac);
-               }
+#if LBMDIM==2
+#define dC 0
+#define dN 1
+#define dS 2
+#define dE 3
+#define dW 4
+#define dNE 5
+#define dNW 6
+#define dSE 7
+#define dSW 8
+#define LBM_DFNUM 9
+#else
+// direction indices
+#define dC 0
+#define dN 1
+#define dS 2
+#define dE 3
+#define dW 4
+#define dT 5
+#define dB 6
+#define dNE 7
+#define dNW 8
+#define dSE 9
+#define dSW 10
+#define dNT 11
+#define dNB 12
+#define dST 13
+#define dSB 14
+#define dET 15
+#define dEB 16
+#define dWT 17
+#define dWB 18
+#define LBM_DFNUM 19
+#endif
+//? #define dWB 18
 
-               //! retrieve the fillfrac field ready to display
-               void getIsofieldWeighted(float *iso);
-               void getIsofield(float *iso){ return getIsofieldWeighted(iso); }
-               //! for raytracing, preprocess
-               void prepareVisualization( void );
+// default init for dFlux values
+#define FLUX_INIT 0.5f * (float)(D::cDfNum)
 
-               // 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; }
+// only for non DF dir handling!
+#define dNET 19
+#define dNWT 20
+#define dSET 21
+#define dSWT 22
+#define dNEB 23
+#define dNWB 24
+#define dSEB 25
+#define dSWB 26
 
-               /*! type for cells */
-               typedef typename D::LbmCell LbmCell;
-               
-       protected:
+//! fill value for boundary cells
+#define BND_FILL 0.0
 
-               //! 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);
+#define DFL1 (1.0/ 3.0)
+#define DFL2 (1.0/18.0)
+#define DFL3 (1.0/36.0)
 
-               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);
+#define OMEGA(l) mLevel[(l)].omega
 
-               //! 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;
-               }
+#define EQC (  DFL1*(rho - usqr))
+#define EQN (  DFL2*(rho + uy*(4.5*uy + 3.0) - usqr))
+#define EQS (  DFL2*(rho + uy*(4.5*uy - 3.0) - usqr))
+#define EQE (  DFL2*(rho + ux*(4.5*ux + 3.0) - usqr))
+#define EQW (  DFL2*(rho + ux*(4.5*ux - 3.0) - usqr))
+#define EQT (  DFL2*(rho + uz*(4.5*uz + 3.0) - usqr))
+#define EQB (  DFL2*(rho + uz*(4.5*uz - 3.0) - usqr))
+                    
+#define EQNE ( DFL3*(rho + (+ux+uy)*(4.5*(+ux+uy) + 3.0) - usqr))
+#define EQNW ( DFL3*(rho + (-ux+uy)*(4.5*(-ux+uy) + 3.0) - usqr))
+#define EQSE ( DFL3*(rho + (+ux-uy)*(4.5*(+ux-uy) + 3.0) - usqr))
+#define EQSW ( DFL3*(rho + (-ux-uy)*(4.5*(-ux-uy) + 3.0) - usqr))
+#define EQNT ( DFL3*(rho + (+uy+uz)*(4.5*(+uy+uz) + 3.0) - usqr))
+#define EQNB ( DFL3*(rho + (+uy-uz)*(4.5*(+uy-uz) + 3.0) - usqr))
+#define EQST ( DFL3*(rho + (-uy+uz)*(4.5*(-uy+uz) + 3.0) - usqr))
+#define EQSB ( DFL3*(rho + (-uy-uz)*(4.5*(-uy-uz) + 3.0) - usqr))
+#define EQET ( DFL3*(rho + (+ux+uz)*(4.5*(+ux+uz) + 3.0) - usqr))
+#define EQEB ( DFL3*(rho + (+ux-uz)*(4.5*(+ux-uz) + 3.0) - usqr))
+#define EQWT ( DFL3*(rho + (-ux+uz)*(4.5*(-ux+uz) + 3.0) - usqr))
+#define EQWB ( DFL3*(rho + (-ux-uz)*(4.5*(-ux-uz) + 3.0) - usqr))
 
 
-               // member vars
+// this is a bit ugly, but necessary for the CSRC_ access...
+#define MSRC_C    m[dC ]
+#define MSRC_N    m[dN ]
+#define MSRC_S    m[dS ]
+#define MSRC_E    m[dE ]
+#define MSRC_W    m[dW ]
+#define MSRC_T    m[dT ]
+#define MSRC_B    m[dB ]
+#define MSRC_NE   m[dNE]
+#define MSRC_NW   m[dNW]
+#define MSRC_SE   m[dSE]
+#define MSRC_SW   m[dSW]
+#define MSRC_NT   m[dNT]
+#define MSRC_NB   m[dNB]
+#define MSRC_ST   m[dST]
+#define MSRC_SB   m[dSB]
+#define MSRC_ET   m[dET]
+#define MSRC_EB   m[dEB]
+#define MSRC_WT   m[dWT]
+#define MSRC_WB   m[dWB]
 
-               //! mass calculated during streaming step
-               LbmFloat mCurrentMass;
-               LbmFloat mCurrentVolume;
-               LbmFloat mInitialMass;
+// this is a bit ugly, but necessary for the ccel local access...
+#define CCEL_C    RAC(ccel, dC )
+#define CCEL_N    RAC(ccel, dN )
+#define CCEL_S    RAC(ccel, dS )
+#define CCEL_E    RAC(ccel, dE )
+#define CCEL_W    RAC(ccel, dW )
+#define CCEL_T    RAC(ccel, dT )
+#define CCEL_B    RAC(ccel, dB )
+#define CCEL_NE   RAC(ccel, dNE)
+#define CCEL_NW   RAC(ccel, dNW)
+#define CCEL_SE   RAC(ccel, dSE)
+#define CCEL_SW   RAC(ccel, dSW)
+#define CCEL_NT   RAC(ccel, dNT)
+#define CCEL_NB   RAC(ccel, dNB)
+#define CCEL_ST   RAC(ccel, dST)
+#define CCEL_SB   RAC(ccel, dSB)
+#define CCEL_ET   RAC(ccel, dET)
+#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)])
 
-               //! count problematic cases, that occured so far...
-               int mNumProblems;
 
-               // average mlsups, count how many so far...
-               double mAvgMLSUPS;
-               double mAvgMLSUPSCnt;
+#if PARALLEL==1
+#define CSMOMEGA_STATS(dlev, domega) 
+#else // PARALLEL==1
+#if FSGR_OMEGA_DEBUG==1
+#define CSMOMEGA_STATS(dlev, domega) \
+       mLevel[dlev].avgOmega += domega; mLevel[dlev].avgOmegaCnt+=1.0; 
+#else // FSGR_OMEGA_DEBUG==1
+#define CSMOMEGA_STATS(dlev, domega) 
+#endif // FSGR_OMEGA_DEBUG==1
+#endif // PARALLEL==1
 
-               //! 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;
+// used for main loops and grav init
+// source set
+#define SRCS(l) mLevel[(l)].setCurr
+// target set
+#define TSET(l) mLevel[(l)].setOther
 
-               //! 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;
+// complete default stream&collide, 2d/3d
+/* read distribution funtions of adjacent cells = sweep step */ 
+#if OPT3D==false 
 
-               //! 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;
+#if FSGR_STRICT_DEBUG==1
+#define MARKCELLCHECK \
+       debugMarkCell(lev,i,j,k); D::mPanic=1;
+#define STREAMCHECK(ni,nj,nk,nl) \
+       if((m[l] < -1.0) || (m[l]>1.0)) {\
+               errMsg("STREAMCHECK","Invalid streamed DF l"<<l<<" value:"<<m[l]<<" at "<<PRINT_IJK<<" from "<<PRINT_VEC(ni,nj,nk)<<" nl"<<(nl)<<\
+                               " nfc"<< RFLAG(lev, ni,nj,nk, mLevel[lev].setCurr)<<" nfo"<< RFLAG(lev, ni,nj,nk, mLevel[lev].setOther)  ); \
+               MARKCELLCHECK; \
+       }
+#define COLLCHECK \
+       if( (rho>2.0) || (rho<-1.0) || (ABS(ux)>1.0) || (ABS(uy)>1.0) |(ABS(uz)>1.0) ) {\
+               errMsg("COLLCHECK","Invalid collision values r:"<<rho<<" u:"PRINT_VEC(ux,uy,uz)<<" at? "<<PRINT_IJK ); \
+               MARKCELLCHECK; \
+       }
+#else
+#define STREAMCHECK(ni,nj,nk,nl) 
+#define COLLCHECK
+#endif
 
-               //! for interactive - how to drop drops?
-               int mDropMode;
-               LbmFloat mDropSize;
-               LbmVec mDropSpeed;
-               //! dropping variables
-               bool mDropping;
-               LbmFloat mDropX, mDropY;
-               LbmFloat mDropHeight;
+// careful ux,uy,uz need to be inited before!
 
-               //! get isofield weights
-               int mIsoWeightMethod;
-               float mIsoWeight[27];
+#define DEFAULT_STREAM \
+               m[dC] = RAC(ccel,dC); \
+               FORDF1 { \
+                       if(NBFLAG( D::dfInv[l] )&CFBnd) { \
+                               m[l] = RAC(ccel, D::dfInv[l] ); \
+                               STREAMCHECK(i,j,k, D::dfInv[l]); \
+                       } else { \
+                               m[l] = QCELL_NBINV(lev, i, j, k, SRCS(lev), l,l); \
+                               STREAMCHECK(i+D::dfVecX[D::dfInv[l]], j+D::dfVecY[D::dfInv[l]],k+D::dfVecZ[D::dfInv[l]], l); \
+                       } \
+               }   
 
-               // grid coarsening vars
-               
-               /*! vector for the data for each level */
-#              define MAX_LEV 5
-               FsgrLevelData mLevel[MAX_LEV];
+// careful ux,uy,uz need to be inited before!
+#define DEFAULT_COLLIDE \
+                       D::collideArrays( m, rho,ux,uy,uz, OMEGA(lev), mLevel[lev].lcsmago, &mDebugOmegaRet ); \
+                       CSMOMEGA_STATS(lev,mDebugOmegaRet); \
+                       FORDF0 { RAC(tcel,l) = m[l]; }   \
+                       usqr = 1.5 * (ux*ux + uy*uy + uz*uz);  \
+                       COLLCHECK;
+#define OPTIMIZED_STREAMCOLLIDE \
+                       m[0] = RAC(ccel,0); \
+                       FORDF1 { /* df0 is set later on... */ \
+                               /* FIXME CHECK INV ? */\
+                               if(RFLAG_NBINV(lev, i,j,k,SRCS(lev),l)&CFBnd) { errMsg("???", "bnd-err-nobndfl"); D::mPanic=1;  \
+                               } else { m[l] = QCELL_NBINV(lev, i, j, k, SRCS(lev), l, l); } \
+                               STREAMCHECK(i+D::dfVecX[D::dfInv[l]], j+D::dfVecY[D::dfInv[l]],k+D::dfVecZ[D::dfInv[l]], l); \
+                       }   \
+                       rho=m[0]; ux = mLevel[lev].gravity[0]; uy = mLevel[lev].gravity[1]; uz = mLevel[lev].gravity[2]; \
+                       ux = mLevel[lev].gravity[0]; uy = mLevel[lev].gravity[1]; uz = mLevel[lev].gravity[2]; \
+                       D::collideArrays( m, rho,ux,uy,uz, OMEGA(lev), mLevel[lev].lcsmago , &mDebugOmegaRet  ); \
+                       CSMOMEGA_STATS(lev,mDebugOmegaRet); \
+                       FORDF0 { RAC(tcel,l) = m[l]; } \
+                       usqr = 1.5 * (ux*ux + uy*uy + uz*uz);  \
+                       COLLCHECK;
 
-               /*! minimal and maximal refinement levels */
-               int mMaxRefine;
+#else  // 3D, opt OPT3D==true
 
-               /*! df scale factors for level up/down */
-               LbmFloat mDfScaleUp, mDfScaleDown;
+#define DEFAULT_STREAM \
+               m[dC] = RAC(ccel,dC); \
+               /* explicit streaming */ \
+               if((!nbored & CFBnd)) { \
+                       /* no boundary near?, no real speed diff.? */ \
+                       m[dN ] = CSRC_N ; m[dS ] = CSRC_S ; \
+                       m[dE ] = CSRC_E ; m[dW ] = CSRC_W ; \
+                       m[dT ] = CSRC_T ; m[dB ] = CSRC_B ; \
+                       m[dNE] = CSRC_NE; m[dNW] = CSRC_NW; m[dSE] = CSRC_SE; m[dSW] = CSRC_SW; \
+                       m[dNT] = CSRC_NT; m[dNB] = CSRC_NB; m[dST] = CSRC_ST; m[dSB] = CSRC_SB; \
+                       m[dET] = CSRC_ET; m[dEB] = CSRC_EB; m[dWT] = CSRC_WT; m[dWB] = CSRC_WB; \
+               } else { \
+                       /* explicit streaming */ \
+                       if(NBFLAG(dS )&CFBnd) { m[dN ] = RAC(ccel,dS ); } else { m[dN ] = CSRC_N ; } \
+                       if(NBFLAG(dN )&CFBnd) { m[dS ] = RAC(ccel,dN ); } else { m[dS ] = CSRC_S ; } \
+                       if(NBFLAG(dW )&CFBnd) { m[dE ] = RAC(ccel,dW ); } else { m[dE ] = CSRC_E ; } \
+                       if(NBFLAG(dE )&CFBnd) { m[dW ] = RAC(ccel,dE ); } else { m[dW ] = CSRC_W ; } \
+                       if(NBFLAG(dB )&CFBnd) { m[dT ] = RAC(ccel,dB ); } else { m[dT ] = CSRC_T ; } \
+                       if(NBFLAG(dT )&CFBnd) { m[dB ] = RAC(ccel,dT ); } else { m[dB ] = CSRC_B ; } \
+                       \
+                       if(NBFLAG(dSW)&CFBnd) { m[dNE] = RAC(ccel,dSW); } else { m[dNE] = CSRC_NE; } \
+                       if(NBFLAG(dSE)&CFBnd) { m[dNW] = RAC(ccel,dSE); } else { m[dNW] = CSRC_NW; } \
+                       if(NBFLAG(dNW)&CFBnd) { m[dSE] = RAC(ccel,dNW); } else { m[dSE] = CSRC_SE; } \
+                       if(NBFLAG(dNE)&CFBnd) { m[dSW] = RAC(ccel,dNE); } else { m[dSW] = CSRC_SW; } \
+                       if(NBFLAG(dSB)&CFBnd) { m[dNT] = RAC(ccel,dSB); } else { m[dNT] = CSRC_NT; } \
+                       if(NBFLAG(dST)&CFBnd) { m[dNB] = RAC(ccel,dST); } else { m[dNB] = CSRC_NB; } \
+                       if(NBFLAG(dNB)&CFBnd) { m[dST] = RAC(ccel,dNB); } else { m[dST] = CSRC_ST; } \
+                       if(NBFLAG(dNT)&CFBnd) { m[dSB] = RAC(ccel,dNT); } else { m[dSB] = CSRC_SB; } \
+                       if(NBFLAG(dWB)&CFBnd) { m[dET] = RAC(ccel,dWB); } else { m[dET] = CSRC_ET; } \
+                       if(NBFLAG(dWT)&CFBnd) { m[dEB] = RAC(ccel,dWT); } else { m[dEB] = CSRC_EB; } \
+                       if(NBFLAG(dEB)&CFBnd) { m[dWT] = RAC(ccel,dEB); } else { m[dWT] = CSRC_WT; } \
+                       if(NBFLAG(dET)&CFBnd) { m[dWB] = RAC(ccel,dET); } else { m[dWB] = CSRC_WB; } \
+               } 
+
+
+
+#define COLL_CALCULATE_DFEQ(dstarray) \
+                       dstarray[dN ] = EQN ; dstarray[dS ] = EQS ; \
+                       dstarray[dE ] = EQE ; dstarray[dW ] = EQW ; \
+                       dstarray[dT ] = EQT ; dstarray[dB ] = EQB ; \
+                       dstarray[dNE] = EQNE; dstarray[dNW] = EQNW; dstarray[dSE] = EQSE; dstarray[dSW] = EQSW; \
+                       dstarray[dNT] = EQNT; dstarray[dNB] = EQNB; dstarray[dST] = EQST; dstarray[dSB] = EQSB; \
+                       dstarray[dET] = EQET; dstarray[dEB] = EQEB; dstarray[dWT] = EQWT; dstarray[dWB] = EQWB; 
+#define COLL_CALCULATE_NONEQTENSOR(csolev, srcArray ) \
+                       lcsmqadd  = (srcArray##NE - lcsmeq[ dNE ]); \
+                       lcsmqadd -= (srcArray##NW - lcsmeq[ dNW ]); \
+                       lcsmqadd -= (srcArray##SE - lcsmeq[ dSE ]); \
+                       lcsmqadd += (srcArray##SW - lcsmeq[ dSW ]); \
+                       lcsmqo = (lcsmqadd*    lcsmqadd); \
+                       lcsmqadd  = (srcArray##ET - lcsmeq[  dET ]); \
+                       lcsmqadd -= (srcArray##EB - lcsmeq[  dEB ]); \
+                       lcsmqadd -= (srcArray##WT - lcsmeq[  dWT ]); \
+                       lcsmqadd += (srcArray##WB - lcsmeq[  dWB ]); \
+                       lcsmqo += (lcsmqadd*    lcsmqadd); \
+                       lcsmqadd  = (srcArray##NT - lcsmeq[  dNT ]); \
+                       lcsmqadd -= (srcArray##NB - lcsmeq[  dNB ]); \
+                       lcsmqadd -= (srcArray##ST - lcsmeq[  dST ]); \
+                       lcsmqadd += (srcArray##SB - lcsmeq[  dSB ]); \
+                       lcsmqo += (lcsmqadd*    lcsmqadd); \
+                       lcsmqo *= 2.0; \
+                       lcsmqadd  = (srcArray##E  -  lcsmeq[ dE  ]); \
+                       lcsmqadd += (srcArray##W  -  lcsmeq[ dW  ]); \
+                       lcsmqadd += (srcArray##NE -  lcsmeq[ dNE ]); \
+                       lcsmqadd += (srcArray##NW -  lcsmeq[ dNW ]); \
+                       lcsmqadd += (srcArray##SE -  lcsmeq[ dSE ]); \
+                       lcsmqadd += (srcArray##SW -  lcsmeq[ dSW ]); \
+                       lcsmqadd += (srcArray##ET  - lcsmeq[ dET ]); \
+                       lcsmqadd += (srcArray##EB  - lcsmeq[ dEB ]); \
+                       lcsmqadd += (srcArray##WT  - lcsmeq[ dWT ]); \
+                       lcsmqadd += (srcArray##WB  - lcsmeq[ dWB ]); \
+                       lcsmqo += (lcsmqadd*    lcsmqadd); \
+                       lcsmqadd  = (srcArray##N  -  lcsmeq[ dN  ]); \
+                       lcsmqadd += (srcArray##S  -  lcsmeq[ dS  ]); \
+                       lcsmqadd += (srcArray##NE -  lcsmeq[ dNE ]); \
+                       lcsmqadd += (srcArray##NW -  lcsmeq[ dNW ]); \
+                       lcsmqadd += (srcArray##SE -  lcsmeq[ dSE ]); \
+                       lcsmqadd += (srcArray##SW -  lcsmeq[ dSW ]); \
+                       lcsmqadd += (srcArray##NT  - lcsmeq[ dNT ]); \
+                       lcsmqadd += (srcArray##NB  - lcsmeq[ dNB ]); \
+                       lcsmqadd += (srcArray##ST  - lcsmeq[ dST ]); \
+                       lcsmqadd += (srcArray##SB  - lcsmeq[ dSB ]); \
+                       lcsmqo += (lcsmqadd*    lcsmqadd); \
+                       lcsmqadd  = (srcArray##T  -  lcsmeq[ dT  ]); \
+                       lcsmqadd += (srcArray##B  -  lcsmeq[ dB  ]); \
+                       lcsmqadd += (srcArray##NT -  lcsmeq[ dNT ]); \
+                       lcsmqadd += (srcArray##NB -  lcsmeq[ dNB ]); \
+                       lcsmqadd += (srcArray##ST -  lcsmeq[ dST ]); \
+                       lcsmqadd += (srcArray##SB -  lcsmeq[ dSB ]); \
+                       lcsmqadd += (srcArray##ET  - lcsmeq[ dET ]); \
+                       lcsmqadd += (srcArray##EB  - lcsmeq[ dEB ]); \
+                       lcsmqadd += (srcArray##WT  - lcsmeq[ dWT ]); \
+                       lcsmqadd += (srcArray##WB  - lcsmeq[ dWB ]); \
+                       lcsmqo += (lcsmqadd*    lcsmqadd); \
+                       lcsmqo = sqrt(lcsmqo); /* FIXME check effect of sqrt*/ \
+
+//                     COLL_CALCULATE_CSMOMEGAVAL(csolev, lcsmomega); 
+
+// careful - need lcsmqo 
+#define COLL_CALCULATE_CSMOMEGAVAL(csolev, dstomega ) \
+                       dstomega =  1.0/\
+                                       ( 3.0*( mLevel[(csolev)].lcnu+mLevel[(csolev)].lcsmago_sqr*(\
+                                                       -mLevel[(csolev)].lcnu + sqrt( mLevel[(csolev)].lcnu*mLevel[(csolev)].lcnu + 18.0*mLevel[(csolev)].lcsmago_sqr* lcsmqo ) \
+                                                       / (6.0*mLevel[(csolev)].lcsmago_sqr)) \
+                                               ) +0.5 ); 
+
+#define DEFAULT_COLLIDE_LES \
+                       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); \
+                       COLL_CALCULATE_DFEQ(lcsmeq); \
+                       COLL_CALCULATE_NONEQTENSOR(lev, MSRC_)\
+                       COLL_CALCULATE_CSMOMEGAVAL(lev, lcsmomega); \
+                       CSMOMEGA_STATS(lev,lcsmomega); \
+                       \
+                       RAC(tcel,dC ) = (1.0-lcsmomega)*MSRC_C  + lcsmomega*EQC ; \
+                       \
+                       RAC(tcel,dN ) = (1.0-lcsmomega)*MSRC_N  + lcsmomega*lcsmeq[ dN ]; \
+                       RAC(tcel,dS ) = (1.0-lcsmomega)*MSRC_S  + lcsmomega*lcsmeq[ dS ]; \
+                       RAC(tcel,dE ) = (1.0-lcsmomega)*MSRC_E  + lcsmomega*lcsmeq[ dE ]; \
+                       RAC(tcel,dW ) = (1.0-lcsmomega)*MSRC_W  + lcsmomega*lcsmeq[ dW ]; \
+                       RAC(tcel,dT ) = (1.0-lcsmomega)*MSRC_T  + lcsmomega*lcsmeq[ dT ]; \
+                       RAC(tcel,dB ) = (1.0-lcsmomega)*MSRC_B  + lcsmomega*lcsmeq[ dB ]; \
+                       \
+                       RAC(tcel,dNE) = (1.0-lcsmomega)*MSRC_NE + lcsmomega*lcsmeq[ dNE]; \
+                       RAC(tcel,dNW) = (1.0-lcsmomega)*MSRC_NW + lcsmomega*lcsmeq[ dNW]; \
+                       RAC(tcel,dSE) = (1.0-lcsmomega)*MSRC_SE + lcsmomega*lcsmeq[ dSE]; \
+                       RAC(tcel,dSW) = (1.0-lcsmomega)*MSRC_SW + lcsmomega*lcsmeq[ dSW]; \
+                       RAC(tcel,dNT) = (1.0-lcsmomega)*MSRC_NT + lcsmomega*lcsmeq[ dNT]; \
+                       RAC(tcel,dNB) = (1.0-lcsmomega)*MSRC_NB + lcsmomega*lcsmeq[ dNB]; \
+                       RAC(tcel,dST) = (1.0-lcsmomega)*MSRC_ST + lcsmomega*lcsmeq[ dST]; \
+                       RAC(tcel,dSB) = (1.0-lcsmomega)*MSRC_SB + lcsmomega*lcsmeq[ dSB]; \
+                       RAC(tcel,dET) = (1.0-lcsmomega)*MSRC_ET + lcsmomega*lcsmeq[ dET]; \
+                       RAC(tcel,dEB) = (1.0-lcsmomega)*MSRC_EB + lcsmomega*lcsmeq[ dEB]; \
+                       RAC(tcel,dWT) = (1.0-lcsmomega)*MSRC_WT + lcsmomega*lcsmeq[ dWT]; \
+                       RAC(tcel,dWB) = (1.0-lcsmomega)*MSRC_WB + lcsmomega*lcsmeq[ dWB]; 
+
+#define DEFAULT_COLLIDE_NOLES \
+                       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); \
+                       \
+                       RAC(tcel,dC ) = (1.0-OMEGA(lev))*MSRC_C  + OMEGA(lev)*EQC ; \
+                       \
+                       RAC(tcel,dN ) = (1.0-OMEGA(lev))*MSRC_N  + OMEGA(lev)*EQN ; \
+                       RAC(tcel,dS ) = (1.0-OMEGA(lev))*MSRC_S  + OMEGA(lev)*EQS ; \
+                       RAC(tcel,dE ) = (1.0-OMEGA(lev))*MSRC_E  + OMEGA(lev)*EQE ; \
+                       RAC(tcel,dW ) = (1.0-OMEGA(lev))*MSRC_W  + OMEGA(lev)*EQW ; \
+                       RAC(tcel,dT ) = (1.0-OMEGA(lev))*MSRC_T  + OMEGA(lev)*EQT ; \
+                       RAC(tcel,dB ) = (1.0-OMEGA(lev))*MSRC_B  + OMEGA(lev)*EQB ; \
+                       \
+                       RAC(tcel,dNE) = (1.0-OMEGA(lev))*MSRC_NE + OMEGA(lev)*EQNE; \
+                       RAC(tcel,dNW) = (1.0-OMEGA(lev))*MSRC_NW + OMEGA(lev)*EQNW; \
+                       RAC(tcel,dSE) = (1.0-OMEGA(lev))*MSRC_SE + OMEGA(lev)*EQSE; \
+                       RAC(tcel,dSW) = (1.0-OMEGA(lev))*MSRC_SW + OMEGA(lev)*EQSW; \
+                       RAC(tcel,dNT) = (1.0-OMEGA(lev))*MSRC_NT + OMEGA(lev)*EQNT; \
+                       RAC(tcel,dNB) = (1.0-OMEGA(lev))*MSRC_NB + OMEGA(lev)*EQNB; \
+                       RAC(tcel,dST) = (1.0-OMEGA(lev))*MSRC_ST + OMEGA(lev)*EQST; \
+                       RAC(tcel,dSB) = (1.0-OMEGA(lev))*MSRC_SB + OMEGA(lev)*EQSB; \
+                       RAC(tcel,dET) = (1.0-OMEGA(lev))*MSRC_ET + OMEGA(lev)*EQET; \
+                       RAC(tcel,dEB) = (1.0-OMEGA(lev))*MSRC_EB + OMEGA(lev)*EQEB; \
+                       RAC(tcel,dWT) = (1.0-OMEGA(lev))*MSRC_WT + OMEGA(lev)*EQWT; \
+                       RAC(tcel,dWB) = (1.0-OMEGA(lev))*MSRC_WB + OMEGA(lev)*EQWB; 
+
+
+
+#define OPTIMIZED_STREAMCOLLIDE_LES \
+                       /* only surrounded by fluid cells...!, so safe streaming here... */ \
+                       m[dC ] = CSRC_C ; \
+                       m[dN ] = CSRC_N ; m[dS ] = CSRC_S ; \
+                       m[dE ] = CSRC_E ; m[dW ] = CSRC_W ; \
+                       m[dT ] = CSRC_T ; m[dB ] = CSRC_B ; \
+                       m[dNE] = CSRC_NE; m[dNW] = CSRC_NW; m[dSE] = CSRC_SE; m[dSW] = CSRC_SW; \
+                       m[dNT] = CSRC_NT; m[dNB] = CSRC_NB; m[dST] = CSRC_ST; m[dSB] = CSRC_SB; \
+                       m[dET] = CSRC_ET; m[dEB] = CSRC_EB; m[dWT] = CSRC_WT; m[dWB] = CSRC_WB; \
+                       \
+                       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 + mLevel[lev].gravity[0];  \
+                       uy = MSRC_N - MSRC_S + MSRC_NE + MSRC_NW - MSRC_SE - MSRC_SW \
+                               + MSRC_NT + MSRC_NB - MSRC_ST - MSRC_SB + mLevel[lev].gravity[1];  \
+                       uz = MSRC_T - MSRC_B + MSRC_NT - MSRC_NB + MSRC_ST - MSRC_SB \
+                               + MSRC_ET - MSRC_EB + MSRC_WT - MSRC_WB + mLevel[lev].gravity[2];  \
+                       usqr = 1.5 * (ux*ux + uy*uy + uz*uz); \
+                       COLL_CALCULATE_DFEQ(lcsmeq); \
+                       COLL_CALCULATE_NONEQTENSOR(lev, MSRC_) \
+                       COLL_CALCULATE_CSMOMEGAVAL(lev, lcsmomega); \
+                       CSMOMEGA_STATS(lev,lcsmomega); \
+                       \
+                       RAC(tcel,dC ) = (1.0-lcsmomega)*MSRC_C  + lcsmomega*EQC ; \
+                       RAC(tcel,dN ) = (1.0-lcsmomega)*MSRC_N  + lcsmomega*lcsmeq[ dN ];  \
+                       RAC(tcel,dS ) = (1.0-lcsmomega)*MSRC_S  + lcsmomega*lcsmeq[ dS ];  \
+                       RAC(tcel,dE ) = (1.0-lcsmomega)*MSRC_E  + lcsmomega*lcsmeq[ dE ]; \
+                       RAC(tcel,dW ) = (1.0-lcsmomega)*MSRC_W  + lcsmomega*lcsmeq[ dW ];  \
+                       RAC(tcel,dT ) = (1.0-lcsmomega)*MSRC_T  + lcsmomega*lcsmeq[ dT ];  \
+                       RAC(tcel,dB ) = (1.0-lcsmomega)*MSRC_B  + lcsmomega*lcsmeq[ dB ]; \
+                       \
+                       RAC(tcel,dNE) = (1.0-lcsmomega)*MSRC_NE + lcsmomega*lcsmeq[ dNE];  \
+                       RAC(tcel,dNW) = (1.0-lcsmomega)*MSRC_NW + lcsmomega*lcsmeq[ dNW];  \
+                       RAC(tcel,dSE) = (1.0-lcsmomega)*MSRC_SE + lcsmomega*lcsmeq[ dSE];  \
+                       RAC(tcel,dSW) = (1.0-lcsmomega)*MSRC_SW + lcsmomega*lcsmeq[ dSW]; \
+                       \
+                       RAC(tcel,dNT) = (1.0-lcsmomega)*MSRC_NT + lcsmomega*lcsmeq[ dNT];  \
+                       RAC(tcel,dNB) = (1.0-lcsmomega)*MSRC_NB + lcsmomega*lcsmeq[ dNB];  \
+                       RAC(tcel,dST) = (1.0-lcsmomega)*MSRC_ST + lcsmomega*lcsmeq[ dST];  \
+                       RAC(tcel,dSB) = (1.0-lcsmomega)*MSRC_SB + lcsmomega*lcsmeq[ dSB]; \
+                       \
+                       RAC(tcel,dET) = (1.0-lcsmomega)*MSRC_ET + lcsmomega*lcsmeq[ dET];  \
+                       RAC(tcel,dEB) = (1.0-lcsmomega)*MSRC_EB + lcsmomega*lcsmeq[ dEB]; \
+                       RAC(tcel,dWT) = (1.0-lcsmomega)*MSRC_WT + lcsmomega*lcsmeq[ dWT];  \
+                       RAC(tcel,dWB) = (1.0-lcsmomega)*MSRC_WB + lcsmomega*lcsmeq[ dWB];  \
+
+#define OPTIMIZED_STREAMCOLLIDE_UNUSED \
+                       /* only surrounded by fluid cells...!, so safe streaming here... */ \
+                       rho = CSRC_C  + CSRC_N + CSRC_S  + CSRC_E + CSRC_W  + CSRC_T  \
+                               + CSRC_B  + CSRC_NE + CSRC_NW + CSRC_SE + CSRC_SW + CSRC_NT \
+                               + CSRC_NB + CSRC_ST + CSRC_SB + CSRC_ET + CSRC_EB + CSRC_WT + CSRC_WB; \
+                       ux = CSRC_E - CSRC_W + CSRC_NE - CSRC_NW + CSRC_SE - CSRC_SW \
+                               + CSRC_ET + CSRC_EB - CSRC_WT - CSRC_WB + mLevel[lev].gravity[0];  \
+                       uy = CSRC_N - CSRC_S + CSRC_NE + CSRC_NW - CSRC_SE - CSRC_SW \
+                               + CSRC_NT + CSRC_NB - CSRC_ST - CSRC_SB + mLevel[lev].gravity[1];  \
+                       uz = CSRC_T - CSRC_B + CSRC_NT - CSRC_NB + CSRC_ST - CSRC_SB \
+                               + CSRC_ET - CSRC_EB + CSRC_WT - CSRC_WB + mLevel[lev].gravity[2];  \
+                       usqr = 1.5 * (ux*ux + uy*uy + uz*uz); \
+                       COLL_CALCULATE_DFEQ(lcsmeq); \
+                       COLL_CALCULATE_NONEQTENSOR(lev, CSRC_) \
+                       COLL_CALCULATE_CSMOMEGAVAL(lev, lcsmomega); \
+                       \
+                       RAC(tcel,dC ) = (1.0-lcsmomega)*CSRC_C  + lcsmomega*EQC ; \
+                       RAC(tcel,dN ) = (1.0-lcsmomega)*CSRC_N  + lcsmomega*lcsmeq[ dN ];  \
+                       RAC(tcel,dS ) = (1.0-lcsmomega)*CSRC_S  + lcsmomega*lcsmeq[ dS ];  \
+                       RAC(tcel,dE ) = (1.0-lcsmomega)*CSRC_E  + lcsmomega*lcsmeq[ dE ]; \
+                       RAC(tcel,dW ) = (1.0-lcsmomega)*CSRC_W  + lcsmomega*lcsmeq[ dW ];  \
+                       RAC(tcel,dT ) = (1.0-lcsmomega)*CSRC_T  + lcsmomega*lcsmeq[ dT ];  \
+                       RAC(tcel,dB ) = (1.0-lcsmomega)*CSRC_B  + lcsmomega*lcsmeq[ dB ]; \
+                       \
+                       RAC(tcel,dNE) = (1.0-lcsmomega)*CSRC_NE + lcsmomega*lcsmeq[ dNE];  \
+                       RAC(tcel,dNW) = (1.0-lcsmomega)*CSRC_NW + lcsmomega*lcsmeq[ dNW];  \
+                       RAC(tcel,dSE) = (1.0-lcsmomega)*CSRC_SE + lcsmomega*lcsmeq[ dSE];  \
+                       RAC(tcel,dSW) = (1.0-lcsmomega)*CSRC_SW + lcsmomega*lcsmeq[ dSW]; \
+                       \
+                       RAC(tcel,dNT) = (1.0-lcsmomega)*CSRC_NT + lcsmomega*lcsmeq[ dNT];  \
+                       RAC(tcel,dNB) = (1.0-lcsmomega)*CSRC_NB + lcsmomega*lcsmeq[ dNB];  \
+                       RAC(tcel,dST) = (1.0-lcsmomega)*CSRC_ST + lcsmomega*lcsmeq[ dST];  \
+                       RAC(tcel,dSB) = (1.0-lcsmomega)*CSRC_SB + lcsmomega*lcsmeq[ dSB]; \
+                       \
+                       RAC(tcel,dET) = (1.0-lcsmomega)*CSRC_ET + lcsmomega*lcsmeq[ dET];  \
+                       RAC(tcel,dEB) = (1.0-lcsmomega)*CSRC_EB + lcsmomega*lcsmeq[ dEB]; \
+                       RAC(tcel,dWT) = (1.0-lcsmomega)*CSRC_WT + lcsmomega*lcsmeq[ dWT];  \
+                       RAC(tcel,dWB) = (1.0-lcsmomega)*CSRC_WB + lcsmomega*lcsmeq[ dWB];  \
 
-               /*! precomputed cell area values */
-               LbmFloat mFsgrCellArea[27];
+#define OPTIMIZED_STREAMCOLLIDE_NOLES \
+                       /* only surrounded by fluid cells...!, so safe streaming here... */ \
+                       rho = CSRC_C  + CSRC_N + CSRC_S  + CSRC_E + CSRC_W  + CSRC_T  \
+                               + CSRC_B  + CSRC_NE + CSRC_NW + CSRC_SE + CSRC_SW + CSRC_NT \
+                               + CSRC_NB + CSRC_ST + CSRC_SB + CSRC_ET + CSRC_EB + CSRC_WT + CSRC_WB; \
+                       ux = CSRC_E - CSRC_W + CSRC_NE - CSRC_NW + CSRC_SE - CSRC_SW \
+                               + CSRC_ET + CSRC_EB - CSRC_WT - CSRC_WB + mLevel[lev].gravity[0];  \
+                       uy = CSRC_N - CSRC_S + CSRC_NE + CSRC_NW - CSRC_SE - CSRC_SW \
+                               + CSRC_NT + CSRC_NB - CSRC_ST - CSRC_SB + mLevel[lev].gravity[1];  \
+                       uz = CSRC_T - CSRC_B + CSRC_NT - CSRC_NB + CSRC_ST - CSRC_SB \
+                               + CSRC_ET - CSRC_EB + CSRC_WT - CSRC_WB + mLevel[lev].gravity[2];  \
+                       usqr = 1.5 * (ux*ux + uy*uy + uz*uz); \
+                       RAC(tcel,dC ) = (1.0-OMEGA(lev))*CSRC_C  + OMEGA(lev)*EQC ; \
+                       RAC(tcel,dN ) = (1.0-OMEGA(lev))*CSRC_N  + OMEGA(lev)*EQN ;  \
+                       RAC(tcel,dS ) = (1.0-OMEGA(lev))*CSRC_S  + OMEGA(lev)*EQS ;  \
+                       RAC(tcel,dE ) = (1.0-OMEGA(lev))*CSRC_E  + OMEGA(lev)*EQE ; \
+                       RAC(tcel,dW ) = (1.0-OMEGA(lev))*CSRC_W  + OMEGA(lev)*EQW ;  \
+                       RAC(tcel,dT ) = (1.0-OMEGA(lev))*CSRC_T  + OMEGA(lev)*EQT ;  \
+                       RAC(tcel,dB ) = (1.0-OMEGA(lev))*CSRC_B  + OMEGA(lev)*EQB ; \
+                        \
+                       RAC(tcel,dNE) = (1.0-OMEGA(lev))*CSRC_NE + OMEGA(lev)*EQNE;  \
+                       RAC(tcel,dNW) = (1.0-OMEGA(lev))*CSRC_NW + OMEGA(lev)*EQNW;  \
+                       RAC(tcel,dSE) = (1.0-OMEGA(lev))*CSRC_SE + OMEGA(lev)*EQSE;  \
+                       RAC(tcel,dSW) = (1.0-OMEGA(lev))*CSRC_SW + OMEGA(lev)*EQSW; \
+                        \
+                       RAC(tcel,dNT) = (1.0-OMEGA(lev))*CSRC_NT + OMEGA(lev)*EQNT;  \
+                       RAC(tcel,dNB) = (1.0-OMEGA(lev))*CSRC_NB + OMEGA(lev)*EQNB;  \
+                       RAC(tcel,dST) = (1.0-OMEGA(lev))*CSRC_ST + OMEGA(lev)*EQST;  \
+                       RAC(tcel,dSB) = (1.0-OMEGA(lev))*CSRC_SB + OMEGA(lev)*EQSB; \
+                        \
+                       RAC(tcel,dET) = (1.0-OMEGA(lev))*CSRC_ET + OMEGA(lev)*EQET;  \
+                       RAC(tcel,dEB) = (1.0-OMEGA(lev))*CSRC_EB + OMEGA(lev)*EQEB; \
+                       RAC(tcel,dWT) = (1.0-OMEGA(lev))*CSRC_WT + OMEGA(lev)*EQWT;  \
+                       RAC(tcel,dWB) = (1.0-OMEGA(lev))*CSRC_WB + OMEGA(lev)*EQWB;  \
 
-               /*! 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 version1
+#define STREAMCHECK(ni,nj,nk,nl) 
+#define COLLCHECK
+#define OPTIMIZED_STREAMCOLLIDE_DEBUG \
+                       m[0] = RAC(ccel,0); \
+                       FORDF1 { /* df0 is set later on... */ \
+                               if(RFLAG_NB(lev, i,j,k,SRCS(lev),l)&CFBnd) { errMsg("???", "bnd-err-nobndfl"); D::mPanic=1;  \
+                               } else { m[l] = QCELL_NBINV(lev, i, j, k, SRCS(lev), l, l); } \
+                               STREAMCHECK(i+D::dfVecX[D::dfInv[l]], j+D::dfVecY[D::dfInv[l]],k+D::dfVecZ[D::dfInv[l]], l); \
+                       }   \
+                       rho=m[0]; ux = mLevel[lev].gravity[0]; uy = mLevel[lev].gravity[1]; uz = mLevel[lev].gravity[2]; \
+                       ux = mLevel[lev].gravity[0]; uy = mLevel[lev].gravity[1]; uz = mLevel[lev].gravity[2]; \
+                       D::collideArrays( m, rho,ux,uy,uz, OMEGA(lev), mLevel[lev].lcsmago , &mDebugOmegaRet  ); \
+                       CSMOMEGA_STATS(lev,mDebugOmegaRet); \
+                       FORDF0 { RAC(tcel,l) = m[l]; } \
+                       usqr = 1.5 * (ux*ux + uy*uy + uz*uz);  \
+                       COLLCHECK;
 
-               //! 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
-};
+// more debugging
+/*DEBUG \
+                       m[0] = RAC(ccel,0); \
+                       FORDF1 { \
+                               if(RFLAG_NB(lev, i,j,k,SRCS(lev),l)&CFBnd) { errMsg("???", "bnd-err-nobndfl"); D::mPanic=1;  \
+                               } else { m[l] = QCELL_NBINV(lev, i, j, k, SRCS(lev), l, l); } \
+                       }   \
+f__printf(stderr,"QSDM at %d,%d,%d  lcsmqo=%25.15f, lcsmomega=%f \n", i,j,k, lcsmqo,lcsmomega ); \
+                       rho=m[0]; ux = mLevel[lev].gravity[0]; uy = mLevel[lev].gravity[1]; uz = mLevel[lev].gravity[2]; \
+                       ux = mLevel[lev].gravity[0]; uy = mLevel[lev].gravity[1]; uz = mLevel[lev].gravity[2]; \
+                       D::collideArrays( m, rho,ux,uy,uz, OMEGA(lev), mLevel[lev].lcsmago  , &mDebugOmegaRet ); \
+                       CSMOMEGA_STATS(lev,mDebugOmegaRet); \
+                       */
+#if USE_LES==1
+#define DEFAULT_COLLIDE DEFAULT_COLLIDE_LES
+#define OPTIMIZED_STREAMCOLLIDE OPTIMIZED_STREAMCOLLIDE_LES
+#else 
+#define DEFAULT_COLLIDE DEFAULT_COLLIDE_NOLES
+#define OPTIMIZED_STREAMCOLLIDE OPTIMIZED_STREAMCOLLIDE_NOLES
+#endif
 
+#endif
 
+#define USQRMAXCHECK(Cusqr,Cux,Cuy,Cuz,  CmMaxVlen,CmMxvx,CmMxvy,CmMxvz) \
+                       if(Cusqr>CmMaxVlen) { \
+                               CmMxvx = Cux; CmMxvy = Cuy; CmMxvz = Cuz; CmMaxVlen = Cusqr; \
+                       } /* stats */ 
 
-/*****************************************************************************/
-// 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,172 +3866,464 @@ LbmFsgrSolver<D>::coarseRestrictFromFine(int lev)
                                        omegaDst = mLevel[lev+0].omega; /* NEWSMAGOT*/ 
                                        omegaSrc = mLevel[lev+1].omega;
                                }
-                               //LbmFloat dfScaleFac = (newSteptime/1.0)/(levOldStepsize[lev]/levOldOmega[lev]);
                                dfScale   = (mLevel[lev  ].stepsize/mLevel[lev+1].stepsize)* (1.0/omegaDst-1.0)/ (1.0/omegaSrc-1.0); // yu
-                               //dfScale = 1.0; 
                                FORDF0{
-                                       //QCELL(lev, i,j,k,dstSet, l) = feq[l]+ (df[l]-feq[l])*dfScale; // OLD
                                        RAC(tcel, l) = feq[l]+ (df[l]-feq[l])*dfScale;
                                } 
-#else // OPT3D
-                               /*test this*/
+#                              else // OPT3D
                                // similar to OPTIMIZED_STREAMCOLLIDE_UNUSED
-                               rho = CCEL_C  + CCEL_N + CCEL_S  + CCEL_E + CCEL_W  + CCEL_T  \
-                                       + CCEL_B  + CCEL_NE + CCEL_NW + CCEL_SE + CCEL_SW + CCEL_NT \
-                                       + CCEL_NB + CCEL_ST + CCEL_SB + CCEL_ET + CCEL_EB + CCEL_WT + CCEL_WB; \
-                               ux = CCEL_E - CCEL_W + CCEL_NE - CCEL_NW + CCEL_SE - CCEL_SW \
-                                       + CCEL_ET + CCEL_EB - CCEL_WT - CCEL_WB;  \
-                               uy = CCEL_N - CCEL_S + CCEL_NE + CCEL_NW - CCEL_SE - CCEL_SW \
-                                       + CCEL_NT + CCEL_NB - CCEL_ST - CCEL_SB;  \
-                               uz = CCEL_T - CCEL_B + CCEL_NT - CCEL_NB + CCEL_ST - CCEL_SB \
-                                       + CCEL_ET - CCEL_EB + CCEL_WT - CCEL_WB;  \
+                      
+                               //rho = ux = uy = uz = 0.0;
+                               MSRC_C  = CCELG_C(0) ;
+                               MSRC_N  = CCELG_N(0) ;
+                               MSRC_S  = CCELG_S(0) ;
+                               MSRC_E  = CCELG_E(0) ;
+                               MSRC_W  = CCELG_W(0) ;
+                               MSRC_T  = CCELG_T(0) ;
+                               MSRC_B  = CCELG_B(0) ;
+                               MSRC_NE = CCELG_NE(0);
+                               MSRC_NW = CCELG_NW(0);
+                               MSRC_SE = CCELG_SE(0);
+                               MSRC_SW = CCELG_SW(0);
+                               MSRC_NT = CCELG_NT(0);
+                               MSRC_NB = CCELG_NB(0);
+                               MSRC_ST = CCELG_ST(0);
+                               MSRC_SB = CCELG_SB(0);
+                               MSRC_ET = CCELG_ET(0);
+                               MSRC_EB = CCELG_EB(0);
+                               MSRC_WT = CCELG_WT(0);
+                               MSRC_WB = CCELG_WB(0);
+                               for(int n=1;(n<D::cDirNum); n++) { 
+                                       ccel = RACPNT(lev+1,  2*i+1*D::dfVecX[n], 2*j+1*D::dfVecY[n], 2*k+1*D::dfVecZ[n]  ,srcSet);
+                                       MSRC_C  += CCELG_C(n) ;
+                                       MSRC_N  += CCELG_N(n) ;
+                                       MSRC_S  += CCELG_S(n) ;
+                                       MSRC_E  += CCELG_E(n) ;
+                                       MSRC_W  += CCELG_W(n) ;
+                                       MSRC_T  += CCELG_T(n) ;
+                                       MSRC_B  += CCELG_B(n) ;
+                                       MSRC_NE += CCELG_NE(n);
+                                       MSRC_NW += CCELG_NW(n);
+                                       MSRC_SE += CCELG_SE(n);
+                                       MSRC_SW += CCELG_SW(n);
+                                       MSRC_NT += CCELG_NT(n);
+                                       MSRC_NB += CCELG_NB(n);
+                                       MSRC_ST += CCELG_ST(n);
+                                       MSRC_SB += CCELG_SB(n);
+                                       MSRC_ET += CCELG_ET(n);
+                                       MSRC_EB += CCELG_EB(n);
+                                       MSRC_WT += CCELG_WT(n);
+                                       MSRC_WB += CCELG_WB(n);
+                               }
+                               rho = MSRC_C  + MSRC_N + MSRC_S  + MSRC_E + MSRC_W  + MSRC_T  
+                                       + MSRC_B  + MSRC_NE + MSRC_NW + MSRC_SE + MSRC_SW + MSRC_NT 
+                                       + MSRC_NB + MSRC_ST + MSRC_SB + MSRC_ET + MSRC_EB + MSRC_WT + MSRC_WB; 
+                               ux = MSRC_E - MSRC_W + MSRC_NE - MSRC_NW + MSRC_SE - MSRC_SW 
+                                       + MSRC_ET + MSRC_EB - MSRC_WT - MSRC_WB;  
+                               uy = MSRC_N - MSRC_S + MSRC_NE + MSRC_NW - MSRC_SE - MSRC_SW 
+                                       + MSRC_NT + MSRC_NB - MSRC_ST - MSRC_SB;  
+                               uz = MSRC_T - MSRC_B + MSRC_NT - MSRC_NB + MSRC_ST - MSRC_SB 
+                                       + MSRC_ET - MSRC_EB + MSRC_WT - MSRC_WB;  
                                usqr = 1.5 * (ux*ux + uy*uy + uz*uz);  \
                                \
                                lcsmeq[dC] = EQC ; \
                                COLL_CALCULATE_DFEQ(lcsmeq); \
-                               COLL_CALCULATE_NONEQTENSOR(lev+0, CCEL_ )\
+                               COLL_CALCULATE_NONEQTENSOR(lev+0, MSRC_ )\
                                COLL_CALCULATE_CSMOMEGAVAL(lev+0, lcsmDstOmega); \
                                COLL_CALCULATE_CSMOMEGAVAL(lev+1, lcsmSrcOmega); \
                                \
                                lcsmdfscale   = (mLevel[lev+0].stepsize/mLevel[lev+1].stepsize)* (1.0/lcsmDstOmega-1.0)/ (1.0/lcsmSrcOmega-1.0);  \
-                               RAC(tcel, dC ) = (lcsmeq[dC ] + (CCEL_C -lcsmeq[dC ] )*lcsmdfscale);\
-                               RAC(tcel, dN ) = (lcsmeq[dN ] + (CCEL_N -lcsmeq[dN ] )*lcsmdfscale);\
-                               RAC(tcel, dS ) = (lcsmeq[dS ] + (CCEL_S -lcsmeq[dS ] )*lcsmdfscale);\
-                               RAC(tcel, dE ) = (lcsmeq[dE ] + (CCEL_E -lcsmeq[dE ] )*lcsmdfscale);\
-                               RAC(tcel, dW ) = (lcsmeq[dW ] + (CCEL_W -lcsmeq[dW ] )*lcsmdfscale);\
-                               RAC(tcel, dT ) = (lcsmeq[dT ] + (CCEL_T -lcsmeq[dT ] )*lcsmdfscale);\
-                               RAC(tcel, dB ) = (lcsmeq[dB ] + (CCEL_B -lcsmeq[dB ] )*lcsmdfscale);\
-                               RAC(tcel, dNE) = (lcsmeq[dNE] + (CCEL_NE-lcsmeq[dNE] )*lcsmdfscale);\
-                               RAC(tcel, dNW) = (lcsmeq[dNW] + (CCEL_NW-lcsmeq[dNW] )*lcsmdfscale);\
-                               RAC(tcel, dSE) = (lcsmeq[dSE] + (CCEL_SE-lcsmeq[dSE] )*lcsmdfscale);\
-                               RAC(tcel, dSW) = (lcsmeq[dSW] + (CCEL_SW-lcsmeq[dSW] )*lcsmdfscale);\
-                               RAC(tcel, dNT) = (lcsmeq[dNT] + (CCEL_NT-lcsmeq[dNT] )*lcsmdfscale);\
-                               RAC(tcel, dNB) = (lcsmeq[dNB] + (CCEL_NB-lcsmeq[dNB] )*lcsmdfscale);\
-                               RAC(tcel, dST) = (lcsmeq[dST] + (CCEL_ST-lcsmeq[dST] )*lcsmdfscale);\
-                               RAC(tcel, dSB) = (lcsmeq[dSB] + (CCEL_SB-lcsmeq[dSB] )*lcsmdfscale);\
-                               RAC(tcel, dET) = (lcsmeq[dET] + (CCEL_ET-lcsmeq[dET] )*lcsmdfscale);\
-                               RAC(tcel, dEB) = (lcsmeq[dEB] + (CCEL_EB-lcsmeq[dEB] )*lcsmdfscale);\
-                               RAC(tcel, dWT) = (lcsmeq[dWT] + (CCEL_WT-lcsmeq[dWT] )*lcsmdfscale);\
-                               RAC(tcel, dWB) = (lcsmeq[dWB] + (CCEL_WB-lcsmeq[dWB] )*lcsmdfscale);\
-                               // */
-                               /* IDF_WRITEBACK optimized */
-                               //errMsg("coarseRestrictFromFine", "CRFF_DFDEBUG cell  "<<PRINT_IJK<<" rho:"<<rho<<" u:"<<PRINT_VEC(ux,uy,uz)<<" "<<lcsmdfscale<<","<<lcsmDstOmega<<","<<lcsmSrcOmega ); 
-#endif // OPT3D==false
+                               RAC(tcel, dC ) = (lcsmeq[dC ] + (MSRC_C -lcsmeq[dC ] )*lcsmdfscale);
+                               RAC(tcel, dN ) = (lcsmeq[dN ] + (MSRC_N -lcsmeq[dN ] )*lcsmdfscale);
+                               RAC(tcel, dS ) = (lcsmeq[dS ] + (MSRC_S -lcsmeq[dS ] )*lcsmdfscale);
+                               RAC(tcel, dE ) = (lcsmeq[dE ] + (MSRC_E -lcsmeq[dE ] )*lcsmdfscale);
+                               RAC(tcel, dW ) = (lcsmeq[dW ] + (MSRC_W -lcsmeq[dW ] )*lcsmdfscale);
+                               RAC(tcel, dT ) = (lcsmeq[dT ] + (MSRC_T -lcsmeq[dT ] )*lcsmdfscale);
+                               RAC(tcel, dB ) = (lcsmeq[dB ] + (MSRC_B -lcsmeq[dB ] )*lcsmdfscale);
+                               RAC(tcel, dNE) = (lcsmeq[dNE] + (MSRC_NE-lcsmeq[dNE] )*lcsmdfscale);
+                               RAC(tcel, dNW) = (lcsmeq[dNW] + (MSRC_NW-lcsmeq[dNW] )*lcsmdfscale);
+                               RAC(tcel, dSE) = (lcsmeq[dSE] + (MSRC_SE-lcsmeq[dSE] )*lcsmdfscale);
+                               RAC(tcel, dSW) = (lcsmeq[dSW] + (MSRC_SW-lcsmeq[dSW] )*lcsmdfscale);
+                               RAC(tcel, dNT) = (lcsmeq[dNT] + (MSRC_NT-lcsmeq[dNT] )*lcsmdfscale);
+                               RAC(tcel, dNB) = (lcsmeq[dNB] + (MSRC_NB-lcsmeq[dNB] )*lcsmdfscale);
+                               RAC(tcel, dST) = (lcsmeq[dST] + (MSRC_ST-lcsmeq[dST] )*lcsmdfscale);
+                               RAC(tcel, dSB) = (lcsmeq[dSB] + (MSRC_SB-lcsmeq[dSB] )*lcsmdfscale);
+                               RAC(tcel, dET) = (lcsmeq[dET] + (MSRC_ET-lcsmeq[dET] )*lcsmdfscale);
+                               RAC(tcel, dEB) = (lcsmeq[dEB] + (MSRC_EB-lcsmeq[dEB] )*lcsmdfscale);
+                               RAC(tcel, dWT) = (lcsmeq[dWT] + (MSRC_WT-lcsmeq[dWT] )*lcsmdfscale);
+                               RAC(tcel, dWB) = (lcsmeq[dWB] + (MSRC_WB-lcsmeq[dWB] )*lcsmdfscale);
+#                              endif // OPT3D==false
+
+                               //? if((lev<mMaxRefine)&&(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)<<" " ); 
+#                      endif // FSGR_STRICT_DEBUG==1
+                               D::mNumUsedCells++;
+                       } // from fine & fluid
+                       else {
+                               if(RFLAG(lev+1, 2*i,2*j,2*k,srcSet) & CFGrFromCoarse) {
+                                       RFLAG(lev, i,j,k,dstSet) |= CFGrToFine;
+                               } else {
+                                       RFLAG(lev, i,j,k,dstSet) &= (~CFGrToFine);
+                               }
+                       }
+               } // & fluid
+       }}}
+       if(!D::mSilent){ errMsg("coarseRestrictFromFine"," from l"<<(lev+1)<<",s"<<mLevel[lev+1].setCurr<<" to l"<<lev<<",s"<<mLevel[lev].setCurr); }
+}
+
+template<class D>
+bool 
+LbmFsgrSolver<D>::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)&notSrcAllowed) { // NEWREFT
+                                       removeFromFine=true;
+                               }
+                       }
+                       /*for(int l=0;((l<D::cDirNum) && (!removeFromFine)); l++) {  // FARBORD
+                               int ni=2*i+2*D::dfVecX[l], nj=2*j+2*D::dfVecY[l], nk=2*k+2*D::dfVecZ[l];
+                               if(RFLAG(lev+1, ni,nj,nk, srcFineSet)&notSrcAllowed) { // NEWREFT
+                                       removeFromFine=true;
+                               }
+                       } // FARBORD */
+#elif REFINEMENTBORDER==3 // REFINEMENTBORDER==1
+                       FIX
+                       if(lev+1==mMaxRefine) { // mixborder
+                               if(RFLAG(lev+1, 2*i,2*j,2*k, srcFineSet)&notSrcAllowed) { 
+                                       removeFromFine=true;
+                               }
+                       } else { // mixborder
+                               for(int l=0; l<D::cDirNum; l++) { 
+                                       int ni=2*i+D::dfVecX[l], nj=2*j+D::dfVecY[l], nk=2*k+D::dfVecZ[l];
+                                       if(RFLAG(lev+1, ni,nj,nk, srcFineSet)&notSrcAllowed) { // 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
 
-                               if( ((lev)<mMaxRefine) || (SHOWALL_INT_CELLS))
-                                       if((MARK_INT_CELLS)&&(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)<<" " ); 
-#                      endif // FSGR_STRICT_DEBUG==1
-                               D::mNumUsedCells++;
-                       } // from fine & fluid
-                       else {
-                               if(RFLAG(lev+1, 2*i,2*j,2*k,srcSet) & CFGrFromCoarse) {
-                                       RFLAG(lev, i,j,k,dstSet) |= CFGrToFine;
-                               } else {
-                                       RFLAG(lev, i,j,k,dstSet) &= (~CFGrToFine);
+               } // 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...
+                                       }
                                }
                        }
-               } // & fluid
-       }}}
-       if(!D::mSilent){ errMsg("coarseRestrictFromFine"," from l"<<(lev+1)<<",s"<<mLevel[lev+1].setCurr<<" to l"<<lev<<",s"<<mLevel[lev].setCurr); }
+                       
+               } // 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;
+             &n