Grid3D.h

Go to the documentation of this file.
00001 /******************************************************************************
00002 *       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 3      *
00003 *                (c) 2006-2008 MGH, INRIA, USTL, UJF, CNRS                    *
00004 *                                                                             *
00005 * This library is free software; you can redistribute it and/or modify it     *
00006 * under the terms of the GNU Lesser General Public License as published by    *
00007 * the Free Software Foundation; either version 2.1 of the License, or (at     *
00008 * your option) any later version.                                             *
00009 *                                                                             *
00010 * This library is distributed in the hope that it will be useful, but WITHOUT *
00011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
00012 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
00013 * for more details.                                                           *
00014 *                                                                             *
00015 * You should have received a copy of the GNU Lesser General Public License    *
00016 * along with this library; if not, write to the Free Software Foundation,     *
00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
00018 *******************************************************************************
00019 *                               SOFA :: Modules                               *
00020 *                                                                             *
00021 * Authors: The SOFA Team and external contributors (see Authors.txt)          *
00022 *                                                                             *
00023 * Contact information: contact@sofa-framework.org                             *
00024 ******************************************************************************/
00025 #ifndef SOFA_COMPONENT_BEHAVIORMODEL_EULERIANFLUID_GRID3D_H
00026 #define SOFA_COMPONENT_BEHAVIORMODEL_EULERIANFLUID_GRID3D_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 Grid3D
00054 {
00055 public:
00056 
00057     typedef float real;
00058     typedef Vec<3,real> vec3;
00059     
00060     struct Cell
00061     {
00062         vec3 u; 
00063         int type; 
00064         void clear()
00065         {
00066             u.clear();
00067             type = 0;
00068         }
00069     };
00070     
00071     int nx,ny,nz,nxny,ncell;
00072     
00073     enum { PART_EMPTY=0, PART_WALL=-1, PART_FULL=1 };
00074     
00075     Cell* fdata;
00076     real* pressure;
00077     real* levelset;
00078     //char* distance;
00079     
00080     real t;
00081     real tend;
00082     
00083     real max_pressure;
00084     Cell bcell;
00085     
00086     vec3 gravity;
00087     
00088     static const unsigned long* obstacles;
00089     
00090     Grid3D();
00091     ~Grid3D();
00092     
00093     void clear(int _nx,int _ny,int _nz);
00094     
00095     template<class T>
00096     static inline T lerp(T a, T b, real f) { return a+(b-a)*f; }
00097     
00098     int clamp_x(int x)
00099     {
00100         return (x<0)?0:(x>=nx)?nx-1:x;
00101     }
00102     
00103     int clamp_y(int y)
00104     {
00105         return (y<0)?0:(y>=ny)?ny-1:y;
00106     }
00107     
00108     int clamp_z(int z)
00109     {
00110         return (z<0)?0:(z>=nz)?nz-1:z;
00111     }
00112     
00113     int clamp_in_x(int x)
00114     {
00115         return (x<1)?1:(x>=nx-1)?nx-2:x;
00116     }
00117     
00118     int clamp_in_y(int y)
00119     {
00120         return (y<1)?1:(y>=ny-1)?ny-2:y;
00121     }
00122     
00123     int clamp_in_z(int z)
00124     {
00125         return (z<1)?1:(z>=nz-1)?nz-2:z;
00126     }
00127     
00128     int index(int x, int y, int z) const
00129     {
00130         return x + y*nx + z*nxny;
00131     }
00132     
00133     int index(const vec3& p) const
00134     {
00135         return index(rnear(p[0]), rnear(p[1]), rnear(p[2]));
00136     }
00137     
00138     Cell* get(int x, int y, int z, Cell* base) const
00139     {
00140         return base+index(x,y,z);
00141     }
00142     
00143     const Cell* get(int x, int y, int z, const Cell* base) const
00144     {
00145         return base+index(x,y,z);
00146     }
00147     
00148     Cell* get(int x, int y, int z)
00149     {
00150 #ifdef DEBUGGRID
00151         if (((unsigned)x>=(unsigned)nx) || ((unsigned)y>=(unsigned)ny) || ((unsigned)z>=(unsigned)nz))
00152         {
00153             std::cerr<<"INVALID CELL "<<x<<','<<y<<','<<z<<std::endl;
00154             return &bcell;
00155         }
00156 #endif
00157         return get(x,y,z,fdata);
00158     }
00159 
00160     const Cell* get(int x, int y, int z) const
00161     {
00162 #ifdef DEBUGGRID
00163         if (((unsigned)x>=(unsigned)nx) || ((unsigned)y>=(unsigned)ny) || ((unsigned)z>=(unsigned)nz))
00164         {
00165             std::cerr<<"INVALID CELL "<<x<<','<<y<<','<<z<<std::endl;
00166             return &bcell;
00167         }
00168 #endif
00169         return get(x,y,z,fdata);
00170     }
00171     
00172     Cell* get(const vec3& p)
00173     {
00174         return get(rnear(p[0]),rnear(p[1]),rnear(p[2]));
00175     }
00176     
00177     const Cell* get(const vec3& p) const
00178     {
00179         return get(rnear(p[0]),rnear(p[1]),rnear(p[2]));
00180     }
00181     
00182     template<int C> real interp(const Cell* base, real fx, real fy, real fz) const
00183     {
00184         return lerp( lerp( lerp(get(0,0,0,base)->u[C],get(1,0,0,base)->u[C],fx),
00185                            lerp(get(0,1,0,base)->u[C],get(1,1,0,base)->u[C],fx), fy ),
00186                      lerp( lerp(get(0,0,1,base)->u[C],get(1,0,1,base)->u[C],fx),
00187                            lerp(get(0,1,1,base)->u[C],get(1,1,1,base)->u[C],fx), fy ),
00188                      fz );
00189     }
00190     
00191     template<int C> real interp(vec3 p) const
00192     {
00193         p[C] += 0.5;
00194         int ix = rfloor(p[0]);
00195         int iy = rfloor(p[1]);
00196         int iz = rfloor(p[2]);
00197         const Cell* base = get(ix,iy,iz);
00198         return interp<C>(base, p[0]-ix, p[1]-iy,p[2]-iz);
00199     }
00200     
00201     vec3 interp(vec3 p) const
00202     {
00203         return vec3( interp<0>(p), interp<1>(p), interp<2>(p) );
00204     }
00205     
00206     template<int C> void impulse(Cell* base, real fx, real fy, real fz, real i)
00207     {
00208         get(0,0,0,base)->u[C] += i*(1-fx)*(1-fy)*(1-fz);
00209         get(1,0,0,base)->u[C] += i*(  fx)*(1-fy)*(1-fz);
00210         get(0,1,0,base)->u[C] += i*(1-fx)*(  fy)*(1-fz);
00211         get(1,1,0,base)->u[C] += i*(  fx)*(  fy)*(1-fz);
00212         get(0,0,1,base)->u[C] += i*(1-fx)*(1-fy)*(  fz);
00213         get(1,0,1,base)->u[C] += i*(  fx)*(1-fy)*(  fz);
00214         get(0,1,1,base)->u[C] += i*(1-fx)*(  fy)*(  fz);
00215         get(1,1,1,base)->u[C] += i*(  fx)*(  fy)*(  fz);
00216     }
00217     
00218     template<int C> void impulse(vec3 p, real i)
00219     {
00220         p[C] += 0.5;
00221         int ix = rfloor(p[0]);
00222         int iy = rfloor(p[1]);
00223         int iz = rfloor(p[2]);
00224         Cell* base = get(ix,iy,iz);
00225         impulse<C>(base, p[0]-ix, p[1]-iy,p[2]-iz, i);
00226     }
00227     
00228     void impulse(const vec3& p, const vec3& i)
00229     {
00230         impulse<0>(p,i[0]);
00231         impulse<1>(p,i[1]);
00232         impulse<2>(p,i[2]);
00233     }
00234     
00235     real* getpressure(int x, int y, int z)
00236     {
00237         return pressure + index(x,y,z);
00238     }
00239     
00240     real getpressure(vec3 p)
00241     {
00242         int ix = rfloor(p[0]);
00243         int iy = rfloor(p[1]);
00244         int iz = rfloor(p[2]);
00245         real fx = p[0]-ix;
00246         real fy = p[1]-iy;
00247         real fz = p[2]-iz;
00248         real* base = getpressure(ix,iy,iz);
00249         return lerp( lerp( lerp(base[index(0,0,0)],base[index(1,0,0)],fx),
00250                            lerp(base[index(0,1,0)],base[index(1,1,0)],fx), fy ),
00251                      lerp( lerp(base[index(0,0,1)],base[index(1,0,1)],fx),
00252                            lerp(base[index(0,1,1)],base[index(1,1,1)],fx), fy ),
00253                      fz );
00254     }
00255     
00256     real* getlevelset(int x, int y, int z)
00257     {
00258         return levelset + index(x,y,z);
00259     }
00260     
00261     real getlevelset(vec3 p)
00262     {
00263         int ix = rfloor(p[0]);
00264         int iy = rfloor(p[1]);
00265         int iz = rfloor(p[2]);
00266         real fx = p[0]-ix;
00267         real fy = p[1]-iy;
00268         real fz = p[2]-iz;
00269         real* base = getlevelset(ix,iy,iz);
00270         return lerp( lerp( lerp(base[index(0,0,0)],base[index(1,0,0)],fx),
00271                            lerp(base[index(0,1,0)],base[index(1,1,0)],fx), fy ),
00272                      lerp( lerp(base[index(0,0,1)],base[index(1,0,1)],fx),
00273                            lerp(base[index(0,1,1)],base[index(1,1,1)],fx), fy ),
00274                      fz );
00275     }
00276     
00277     void seed(real height);
00278     
00279     void seed(real height, vec3 normal);
00280     
00281     void seed(vec3 p0, vec3 p1, vec3 velocity=vec3(0,0,0));
00282     
00283     void step(Grid3D* prev, Grid3D* temp, real dt=0.04, real diff=0.00001);
00284     void step_init(const Grid3D* prev, Grid3D* temp, real dt, real diff);
00285     //void step_particles(Grid3D* prev, Grid3D* temp, real dt, real diff);
00286     void step_levelset(Grid3D* prev, Grid3D* temp, real dt, real diff);
00287     void step_forces(const Grid3D* prev, Grid3D* temp, real dt, real diff, real scale=1.0);
00288     void step_surface(const Grid3D* prev, Grid3D* temp, real dt, real diff);
00289     void step_advect(const Grid3D* prev, Grid3D* temp, real dt, real diff);
00290     void step_diffuse(const Grid3D* prev, Grid3D* temp, real dt, real diff);
00291     void step_project(const Grid3D* prev, Grid3D* temp, real dt, real diff);
00292     void step_color(const Grid3D* prev, Grid3D* temp, real dt, real diff);
00293     
00294     // internal helper function
00295     //  template<int C> inline real find_velocity(int x, int y, int z, int ind, int ind2, const Grid3D* prev, const Grid3D* temp);
00296     
00297     // Fast Marching Method Levelset Update
00298     enum Status { FMM_FRONT0 = 0, FMM_FAR = -1, FMM_KNOWN = -2, FMM_BORDER = -3 };
00299     int* fmm_status;
00300     int* fmm_heap;
00301     int fmm_heap_size;
00302     
00303     int fmm_pop();
00304     void fmm_push(int index);
00305     void fmm_swap(int entry1, int entry2);
00306 };
00307 
00308 } // namespace eulerianfluid
00309 
00310 } // namespace behaviormodel
00311 
00312 } // namespace component
00313 
00314 } // namespace sofa
00315 
00316 #endif

Generated on Sun Nov 23 02:29:31 2008 for Sofa by  doxygen 1.5.7.1