Grid2D.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_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     //char* distance;
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     //void step_particles(Grid2D* prev, Grid2D* temp, real dt, real diff);
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     // internal helper function
00264     //  template<int C> inline real find_velocity(int x, int y, int ind, int ind2, const Grid2D* prev, const Grid2D* temp);
00265     
00266     // Fast Marching Method Levelset Update
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 } // namespace eulerianfluid
00278 
00279 } // namespace behaviormodel
00280 
00281 } // namespace component
00282 
00283 } // namespace sofa
00284 
00285 #endif

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