initial commit of the fluid simulator.
[blender.git] / intern / elbeem / intern / lbmfunctions.h
1 /******************************************************************************
2  *
3  * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method
4  * All code distributed as part of El'Beem is covered by the version 2 of the 
5  * GNU General Public License. See the file COPYING for details.
6  * Copyright 2003-2005 Nils Thuerey
7  *
8  * Combined 2D/3D Lattice Boltzmann Solver templated helper functions
9  * 
10  *****************************************************************************/
11 #ifndef LBMFUNCTIONS_H
12
13
14 #if LBM_USE_GUI==1
15 #endif
16
17
18 #if LBM_USE_GUI==1
19
20 //! display a single node
21 template<typename D> 
22 void 
23 debugDisplayNode(fluidDispSettings *dispset, D *lbm, typename D::CellIdentifier cell ) {
24         //debugOut(" DD: "<<cell->getAsString() , 10);
25         ntlVec3Gfx org      = lbm->getCellOrigin( cell );
26         ntlVec3Gfx halfsize = lbm->getCellSize( cell );
27         int    set      = lbm->getCellSet( cell );
28         //debugOut(" DD: "<<cell->getAsString()<<" "<< (dispset->type) , 10);
29
30         bool     showcell = true;
31         int      linewidth = 1;
32         ntlColor col(0.5);
33         LbmFloat cscale = dispset->scale;
34
35         switch(dispset->type) {
36                 case FLUIDDISPNothing: {
37                                 showcell = false;
38                         } break;
39                 case FLUIDDISPCelltypes: {
40                                 CellFlagType flag = lbm->getCellFlag(cell, set );
41                                 cscale = 0.5;
42
43                                 if(flag& CFInvalid  ) { if(!guiShowInvalid  ) return; }
44                                 if(flag& CFUnused   ) { if(!guiShowInvalid  ) return; }
45                                 if(flag& CFEmpty    ) { if(!guiShowEmpty    ) return; }
46                                 if(flag& CFInter    ) { if(!guiShowInterface) return; }
47                                 if(flag& CFNoDelete ) { if(!guiShowNoDelete ) return; }
48                                 if(flag& CFBnd      ) { if(!guiShowBnd      ) return; }
49
50                                 // only dismiss one of these types 
51                                 if(flag& CFGrFromCoarse)  { if(!guiShowCoarseInner  ) return; } // inner not really interesting
52                                 else
53                                 if(flag& CFGrFromFine) { if(!guiShowCoarseBorder ) return; }
54                                 else
55                                 if(flag& CFFluid    )    { if(!guiShowFluid    ) return; }
56
57
58                                 if(flag& CFNoDelete) { // TEST SOLVER debug, mark nodel cells
59                                         glLineWidth( linewidth );
60                                         ntlColor col(0.7,0.0,0.0);
61                                         glColor3f( col[0], col[1], col[2]);
62                                         ntlVec3Gfx s = org-(halfsize * 0.1);
63                                         ntlVec3Gfx e = org+(halfsize * 0.1);
64                                         drawCubeWire( s,e );
65                                 }
66
67                                 /*if(flag& CFAccelerator) {
68                                         cscale = 0.55;
69                                         col = ntlColor(0,1,0);
70                                         //showcell=false; // DEBUG
71                                 } */
72                                 if(flag& CFInvalid) {
73                                         cscale = 0.50;
74                                         col = ntlColor(0.0,0,0.0);
75                                         //showcell=false; // DEBUG
76                                 }
77                                 /*else if(flag& CFSpeedSet) {
78                                         cscale = 0.55;
79                                         col = ntlColor(0.2,1,0.2);
80                                         //showcell=false; // DEBUG
81                                 }*/
82                                 else if(flag& CFBnd) {
83                                         cscale = 0.59;
84                                         col = ntlColor(0.0);
85                                         col = ntlColor(0.4); // DEBUG
86                                         //if(lbm->getSizeZ()>2) { showcell=false; } // DEBUG, 3D no obstacles
87                                 }
88
89                                 /*else if(flag& CFIfFluid) { // TEST SOLVER if inner fluid if
90                                         cscale = 0.55;
91                                         col = ntlColor(0,1,0);
92                                 }
93                                 else if(flag& CFIfEmpty) { // TEST SOLVER if outer empty if
94                                         cscale = 0.55;
95                                         col = ntlColor(0,0.5,0.5);
96                                 }*/
97                                 else if(flag& CFInter) {
98                                         cscale = 0.55;
99                                         col = ntlColor(0,1,1);
100
101                                 } else if(flag& CFGrFromCoarse) {
102                                         // draw as - with marker
103                                         ntlColor col2(0.0,1.0,0.3);
104                                         glColor3f( col2[0], col2[1], col2[2]);
105                                         ntlVec3Gfx s = org-(halfsize * 0.4);
106                                         ntlVec3Gfx e = org+(halfsize * 0.4);
107                                         drawCubeWire( s,e );
108                                         cscale = 0.5;
109                                         //col = ntlColor(0,0,1);
110                                         showcell=false; // DEBUG
111                                 }
112                                 else if(flag& CFFluid) {
113                                         cscale = 0.5;
114                                         /*if(flag& CFCoarseInner) {
115                                                 col = ntlColor(0.3, 0.3, 1.0);
116                                         } else */
117                                         if(flag& CFGrToFine) {
118                                                 glLineWidth( linewidth );
119                                                 ntlColor col2(0.5,0.0,0.5);
120                                                 glColor3f( col2[0], col2[1], col2[2]);
121                                                 ntlVec3Gfx s = org-(halfsize * 0.31);
122                                                 ntlVec3Gfx e = org+(halfsize * 0.31);
123                                                 drawCubeWire( s,e );
124                                                 col = ntlColor(0,0,1);
125                                         }
126                                         if(flag& CFGrFromFine) {
127                                                 glLineWidth( linewidth );
128                                                 ntlColor col2(1.0,1.0,0.0);
129                                                 glColor3f( col2[0], col2[1], col2[2]);
130                                                 ntlVec3Gfx s = org-(halfsize * 0.56);
131                                                 ntlVec3Gfx e = org+(halfsize * 0.56);
132                                                 drawCubeWire( s,e );
133                                                 col = ntlColor(0,0,1);
134                                         } else if(flag& CFGrFromCoarse) {
135                                                 // draw as fluid with marker
136                                                 ntlColor col2(0.0,1.0,0.3);
137                                                 glColor3f( col2[0], col2[1], col2[2]);
138                                                 ntlVec3Gfx s = org-(halfsize * 0.41);
139                                                 ntlVec3Gfx e = org+(halfsize * 0.41);
140                                                 drawCubeWire( s,e );
141                                                 col = ntlColor(0,0,1);
142                                         } else {
143                                                 col = ntlColor(0,0,1);
144                                                 //showcell=false; // DEBUG
145                                         }
146                                 }
147                                 else if(flag& CFEmpty) {
148                                         showcell=false;
149                                 }
150
151                                 // smaller for new lbmqt
152                                 //cscale *= 0.5;
153
154                         } break;
155                 case FLUIDDISPVelocities: {
156                                 // dont use cube display
157                                 LbmVec vel = lbm->getCellVelocity( cell, set );
158                                 glBegin(GL_LINES);
159                                 glColor3f( 0.0,0.0,0.0 );
160                                 glVertex3f( org[0], org[1], org[2] );
161                                 org += vec2G(vel * 10.0 * cscale);
162                                 glColor3f( 1.0,1.0,1.0 );
163                                 glVertex3f( org[0], org[1], org[2] );
164                                 glEnd();
165                                 showcell = false;
166                         } break;
167                 case FLUIDDISPCellfills: {
168                                 CellFlagType flag = lbm->getCellFlag( cell,set );
169                                 cscale = 0.5;
170
171                                 if(flag& CFFluid) {
172                                         cscale = 0.75;
173                                         col = ntlColor(0,0,0.5);
174                                 }
175                                 else if(flag& CFInter) {
176                                         cscale = 0.75 * lbm->getCellMass(cell,set);
177                                         col = ntlColor(0,1,1);
178                                 }
179                                 else {
180                                         showcell=false;
181                                 }
182
183                                         if( ABS(lbm->getCellMass(cell,set)) < 10.0 ) {
184                                                 cscale = 0.75 * lbm->getCellMass(cell,set);
185                                         } else {
186                                                 showcell = false;
187                                         }
188                                         if(cscale>0.0) {
189                                                 col = ntlColor(0,1,1);
190                                         } else {
191                                                 col = ntlColor(1,1,0);
192                                         }
193                         // TODO
194                         } break;
195                 case FLUIDDISPDensity: {
196                                 LbmFloat rho = lbm->getCellDensity(cell,set);
197                                 cscale = rho*rho * 0.25;
198                                 col = ntlColor( MIN(0.5+cscale,1.0) , MIN(0.0+cscale,1.0), MIN(0.0+cscale,1.0) );
199                                 cscale *= 2.0;
200                         } break;
201                 case FLUIDDISPGrid: {
202                                 cscale = 0.59;
203                                 col = ntlColor(1.0);
204                         } break;
205                 default: {
206                                 cscale = 0.5;
207                                 col = ntlColor(1.0,0.0,0.0);
208                         } break;
209         }
210
211         if(!showcell) return;
212         glLineWidth( linewidth );
213         glColor4f( col[0], col[1], col[2], 0.0);
214
215         ntlVec3Gfx s = org-(halfsize * cscale);
216         ntlVec3Gfx e = org+(halfsize * cscale);
217         //if(D::cDimension==2) {
218                 //s[2] = e[2] = (s[2]+e[2])*0.5;
219         //}
220         drawCubeWire( s,e );
221 }
222
223 //! debug display function
224 //  D has to implement the CellIterator interface
225 template<typename D>
226 void 
227 lbmDebugDisplay(fluidDispSettings *dispset, D *lbm) {
228         //je nach solver...?
229         if(!dispset->on) return;
230         glDisable( GL_LIGHTING ); // dont light lines
231
232         typename D::CellIdentifier cid = lbm->getFirstCell();
233         for(; lbm->noEndCell( cid );
234               lbm->advanceCell( cid ) ) {
235                 // display...
236 #if (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
237                 ::debugDisplayNode<>(dispset, lbm, cid );
238 #else
239                 debugDisplayNode<D>(dispset, lbm, cid );
240 #endif
241         }
242         delete cid;
243
244         glEnable( GL_LIGHTING ); // dont light lines
245 }
246
247 //! debug display function
248 //  D has to implement the CellIterator interface
249 template<typename D>
250 void 
251 lbmMarkedCellDisplay(D *lbm) {
252         fluidDispSettings dispset;
253         // trick - display marked cells as grid displa -> white, big
254         dispset.type = FLUIDDISPGrid;
255         dispset.on = true;
256         glDisable( GL_LIGHTING ); // dont light lines
257         
258         typename D::CellIdentifier cid = lbm->markedGetFirstCell();
259         for(; lbm->markedNoEndCell( cid );
260               lbm->markedAdvanceCell( cid ) ) {
261                 // display... FIXME? this is a bit inconvenient...
262                 //MarkedCellIdentifier *mid = dynamic_cast<MarkedCellIdentifier *>( cid );
263 #if (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
264                 //::debugDisplayNode<>(&dispset, lbm, mid->mpCell );
265                 ::debugDisplayNode<>(&dispset, lbm, cid );
266 #else
267                 //debugDisplayNode<D>(&dispset, lbm, mid->mpCell );
268                 debugDisplayNode<D>(&dispset, lbm, cid );
269 #endif
270         }
271         delete cid;
272
273         glEnable( GL_LIGHTING ); // dont light lines
274 }
275
276 #endif
277
278 //! display a single node
279 template<typename D> 
280 void 
281 debugPrintNodeInfo(D *lbm, typename D::CellIdentifier cell, string printInfo,
282                 // force printing of one set? default = -1 = off
283                 int forceSet=-1) {
284   bool printDF     = false;
285   bool printRho    = false;
286   bool printVel    = false;
287   bool printFlag   = false;
288   bool printGeom   = false;
289   bool printMass=false;
290         bool printBothSets = false;
291
292         for(size_t i=0; i<printInfo.length()-0; i++) {
293                 char what = printInfo[i];
294                 switch(what) {
295                         case '+': // all on
296                                                                 printDF = true; printRho = true; printVel = true; printFlag = true; printGeom = true; printMass = true; 
297                                                                 printBothSets = true; break;
298                         case '-': // all off
299                                                                 printDF = false; printRho = false; printVel = false; printFlag = false; printGeom = false; printMass = false; 
300                                                                 printBothSets = false; break;
301                         case 'd': printDF = true; break;
302                         case 'r': printRho = true; break;
303                         case 'v': printVel = true; break;
304                         case 'f': printFlag = true; break;
305                         case 'g': printGeom = true; break;
306                         case 'm': printMass = true; break;
307                         case 's': printBothSets = true; break;
308                         default: errMsg("debugPrintNodeInfo","Invalid node info id "<<what); exit(1);
309                 }
310         }
311
312         ntlVec3Gfx org      = lbm->getCellOrigin( cell );
313         ntlVec3Gfx halfsize = lbm->getCellSize( cell );
314         int    set      = lbm->getCellSet( cell );
315         debMsgStd("debugPrintNodeInfo",DM_NOTIFY, "Printing cell info '"<<printInfo<<"' for node: "<<cell->getAsString()<<" from "<<lbm->getName()<<" currSet:"<<set , 1);
316         if(printGeom) debMsgStd("                  ",DM_MSG, "Org:"<<org<<" Halfsize:"<<halfsize<<" ", 1);
317
318         int setmax = 2;
319         if(!printBothSets) setmax = 1;
320         if(forceSet>=0) setmax = 1;
321
322         for(int s=0; s<setmax; s++) {
323                 int workset = set;
324                 if(s==1){ workset = (set^1); }          
325                 if(forceSet>=0) workset = forceSet;
326                 debMsgStd("                  ",DM_MSG, "Printing set:"<<workset<<" orgSet:"<<set, 1);
327                 
328                 if(printDF) {
329                         for(int l=0; l<lbm->getDfNum(); l++) { // FIXME ??
330                                 debMsgStd("                  ",DM_MSG, "  Df"<<l<<": "<<lbm->getCellDf(cell,workset,l), 1);
331                         }
332                 }
333                 if(printRho) {
334                         debMsgStd("                  ",DM_MSG, "  Rho: "<<lbm->getCellDensity(cell,workset), 1);
335                 }
336                 if(printVel) {
337                         debMsgStd("                  ",DM_MSG, "  Vel: "<<lbm->getCellVelocity(cell,workset), 1);
338                 }
339                 if(printFlag) {
340                         CellFlagType flag = lbm->getCellFlag(cell,workset);
341                         debMsgStd("                  ",DM_MSG, "  Flg: "<< flag<<" "<<convertFlags2String( flag ) <<" "<<convertCellFlagType2String( flag ), 1);
342                 }
343                 if(printMass) {
344                         debMsgStd("                  ",DM_MSG, "  Mss: "<<lbm->getCellMass(cell,workset), 1);
345                 }
346         }
347 }
348
349 #define LBMFUNCTIONS_H
350 #endif
351