00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef SOFA_COMPONENT_BEHAVIORMODEL_EULERIANFLUID_GRID2D_H
00026 #define SOFA_COMPONENT_BEHAVIORMODEL_EULERIANFLUID_GRID2D_H
00027
00028 #include <sofa/defaulttype/Vec.h>
00029 #include <sofa/defaulttype/Mat.h>
00030 #include <sofa/helper/rmath.h>
00031 #include <iostream>
00032
00033
00034 namespace sofa
00035 {
00036
00037 namespace component
00038 {
00039
00040 namespace behaviormodel
00041 {
00042
00043 namespace eulerianfluid
00044 {
00045
00046 using namespace sofa::defaulttype;
00047 using namespace sofa::helper;
00048
00049 #ifndef NDEBUG
00050 #define DEBUGGRID
00051 #endif
00052
00053 class Grid2D
00054 {
00055 public:
00056
00057 typedef float real;
00058 typedef Vec<2,real> vec2;
00059
00060 struct Cell
00061 {
00062 vec2 u;
00063 int type;
00064 int dummy;
00065 void clear()
00066 {
00067 u.clear();
00068 type = 0;
00069 }
00070 };
00071
00072 int nx,ny,ncell;
00073
00074 enum { PART_EMPTY=0, PART_WALL=-1, PART_FULL=1 };
00075
00076 Cell* fdata;
00077 real* pressure;
00078 real* levelset;
00079
00080
00081 real t;
00082 real tend;
00083
00084 real max_pressure;
00085 Cell bcell;
00086
00087 static const unsigned long* obstacles;
00088
00089 Grid2D();
00090 ~Grid2D();
00091
00092 void clear(int _nx,int _ny);
00093
00094 template<class T>
00095 static inline T lerp(T a, T b, real f) { return a+(b-a)*f; }
00096
00097 int clamp_x(int x)
00098 {
00099 return (x<0)?0:(x>=nx)?nx-1:x;
00100 }
00101
00102 int clamp_y(int y)
00103 {
00104 return (y<0)?0:(y>=ny)?ny-1:y;
00105 }
00106
00107 int clamp_in_x(int x)
00108 {
00109 return (x<1)?1:(x>=nx-1)?nx-2:x;
00110 }
00111
00112 int clamp_in_y(int y)
00113 {
00114 return (y<1)?1:(y>=ny-1)?ny-2:y;
00115 }
00116
00117 int index(int x, int y) const
00118 {
00119 return x + y*nx;
00120 }
00121
00122 int index(const vec2& p) const
00123 {
00124 return index(rnear(p[0]), rnear(p[1]));
00125 }
00126
00127 Cell* get(int x, int y, Cell* base) const
00128 {
00129 return base+index(x,y);
00130 }
00131
00132 const Cell* get(int x, int y, const Cell* base) const
00133 {
00134 return base+index(x,y);
00135 }
00136
00137 Cell* get(int x, int y)
00138 {
00139 #ifdef DEBUGGRID
00140 if (((unsigned)x>=(unsigned)nx) || ((unsigned)y>=(unsigned)ny))
00141 {
00142 std::cerr<<"INVALID CELL "<<x<<','<<y<<std::endl;
00143 return &bcell;
00144 }
00145 #endif
00146 return get(x,y,fdata);
00147 }
00148
00149 const Cell* get(int x, int y) const
00150 {
00151 #ifdef DEBUGGRID
00152 if (((unsigned)x>=(unsigned)nx) || ((unsigned)y>=(unsigned)ny))
00153 {
00154 std::cerr<<"INVALID CELL "<<x<<','<<y<<std::endl;
00155 return &bcell;
00156 }
00157 #endif
00158 return get(x,y,fdata);
00159 }
00160
00161 Cell* get(const vec2& p)
00162 {
00163 return get(rnear(p[0]),rnear(p[1]));
00164 }
00165
00166 const Cell* get(const vec2& p) const
00167 {
00168 return get(rnear(p[0]),rnear(p[1]));
00169 }
00170
00171 template<int C> real interp(const Cell* base, real fx, real fy) const
00172 {
00173 return lerp( lerp(get(0,0,base)->u[C],get(1,0,base)->u[C],fx),
00174 lerp(get(0,1,base)->u[C],get(1,1,base)->u[C],fx), fy );
00175 }
00176
00177 template<int C> real interp(vec2 p) const
00178 {
00179 p[C] += 0.5;
00180 int ix = rfloor(p[0]);
00181 int iy = rfloor(p[1]);
00182 const Cell* base = get(ix,iy);
00183 return interp<C>(base, p[0]-ix, p[1]-iy);
00184 }
00185
00186 vec2 interp(vec2 p) const
00187 {
00188 return vec2( interp<0>(p), interp<1>(p) );
00189 }
00190
00191 template<int C> void impulse(Cell* base, real fx, real fy, real i)
00192 {
00193 get(0,0,base)->u[C] += i*(1-fx)*(1-fy);
00194 get(1,0,base)->u[C] += i*( fx)*(1-fy);
00195 get(0,1,base)->u[C] += i*(1-fx)*( fy);
00196 get(1,1,base)->u[C] += i*( fx)*( fy);
00197 }
00198
00199 template<int C> void impulse(vec2 p, real i)
00200 {
00201 p[C] += 0.5;
00202 int ix = rfloor(p[0]);
00203 int iy = rfloor(p[1]);
00204 Cell* base = get(ix,iy);
00205 impulse<C>(base, p[0]-ix, p[1]-iy, i);
00206 }
00207
00208 void impulse(const vec2& p, const vec2& i)
00209 {
00210 impulse<0>(p,i[0]);
00211 impulse<1>(p,i[1]);
00212 }
00213
00214 real* getpressure(int x, int y)
00215 {
00216 return pressure + index(x,y);
00217 }
00218
00219 real getpressure(vec2 p)
00220 {
00221 int ix = rfloor(p[0]);
00222 int iy = rfloor(p[1]);
00223 real fx = p[0]-ix;
00224 real fy = p[1]-iy;
00225 real* base = getpressure(ix,iy);
00226 return lerp( lerp(base[index(0,0)],base[index(1,0)],fx),
00227 lerp(base[index(0,1)],base[index(1,1)],fx), fy );
00228 }
00229
00230 real* getlevelset(int x, int y)
00231 {
00232 return levelset + index(x,y);
00233 }
00234
00235 real getlevelset(vec2 p)
00236 {
00237 int ix = rfloor(p[0]);
00238 int iy = rfloor(p[1]);
00239 real fx = p[0]-ix;
00240 real fy = p[1]-iy;
00241 real* base = getlevelset(ix,iy);
00242 return lerp( lerp(base[index(0,0)],base[index(1,0)],fx),
00243 lerp(base[index(0,1)],base[index(1,1)],fx), fy );
00244 }
00245
00246 void seed(real height);
00247
00248 void seed(real height, vec2 normal);
00249
00250 void seed(vec2 p0, vec2 p1, vec2 velocity=vec2(0,0));
00251
00252 void step(Grid2D* prev, Grid2D* temp, real dt=0.04, real diff=0.00001);
00253 void step_init(const Grid2D* prev, Grid2D* temp, real dt, real diff);
00254
00255 void step_levelset(Grid2D* prev, Grid2D* temp, real dt, real diff);
00256 void step_forces(const Grid2D* prev, Grid2D* temp, real dt, real diff, real scale=1.0);
00257 void step_surface(const Grid2D* prev, Grid2D* temp, real dt, real diff);
00258 void step_advect(const Grid2D* prev, Grid2D* temp, real dt, real diff);
00259 void step_diffuse(const Grid2D* prev, Grid2D* temp, real dt, real diff);
00260 void step_project(const Grid2D* prev, Grid2D* temp, real dt, real diff);
00261 void step_color(const Grid2D* prev, Grid2D* temp, real dt, real diff);
00262
00263
00264
00265
00266
00267 enum Status { FMM_FRONT0 = 0, FMM_FAR = -1, FMM_KNOWN = -2, FMM_BORDER = -3 };
00268 int* fmm_status;
00269 int* fmm_heap;
00270 int fmm_heap_size;
00271
00272 int fmm_pop();
00273 void fmm_push(int index);
00274 void fmm_swap(int entry1, int entry2);
00275 };
00276
00277 }
00278
00279 }
00280
00281 }
00282
00283 }
00284
00285 #endif