SPHFluidForceField.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_FORCEFIELD_SPHFLUIDFORCEFIELD_H
00026 #define SOFA_COMPONENT_FORCEFIELD_SPHFLUIDFORCEFIELD_H
00027 
00028 #include <sofa/helper/system/config.h>
00029 #include <sofa/core/componentmodel/behavior/ForceField.h>
00030 #include <sofa/core/componentmodel/behavior/MechanicalState.h>
00031 #include <sofa/component/container/SpatialGridContainer.h>
00032 #include <sofa/helper/rmath.h>
00033 #include <vector>
00034 #include <math.h>
00035 
00036 
00037 
00038 namespace sofa
00039 {
00040 
00041 namespace component
00042 {
00043 
00044 namespace forcefield
00045 {
00046 
00047 using namespace sofa::component::container;
00048 
00049 template<class DataTypes>
00050 class SPHFluidForceField : public sofa::core::componentmodel::behavior::ForceField<DataTypes>, public virtual core::objectmodel::BaseObject
00051 {
00052 public:
00053     typedef sofa::core::componentmodel::behavior::ForceField<DataTypes> Inherit;
00054     typedef typename DataTypes::VecCoord VecCoord; 
00055     typedef typename DataTypes::VecDeriv VecDeriv;
00056     typedef typename DataTypes::Coord Coord;
00057     typedef typename DataTypes::Deriv Deriv;
00058     typedef typename Coord::value_type Real;
00059     
00060 protected:
00061     Data< Real > particleRadius;
00062     Data< Real > particleMass;
00063     Data< Real > pressureStiffness; 
00064     Data< Real > density0; 
00065     Data< Real > viscosity;
00066     Data< Real > surfaceTension;
00067     //Real a,b,alpha,beta,dmax,fmax;
00068     //Real d0,p0;
00069     //Real damping;
00070 
00071     struct Particle
00072     {
00073         Real density;
00074         Real pressure;
00075         Deriv normal;
00076         Real curvature;
00077         sofa::helper::vector< std::pair<int,Real> > neighbors; 
00078 #ifdef SOFA_DEBUG_SPATIALGRIDCONTAINER
00079         sofa::helper::vector< std::pair<int,Real> > neighbors2; 
00080 #endif
00081     };
00082 
00083     sofa::helper::vector<Particle> particles;
00084     
00085     typedef SpatialGridContainer<DataTypes> Grid;
00086     
00087     Grid* grid;
00088 
00089 public:
00091     void addNeighbor(int i1, int i2, Real r2, Real h2)
00092     {
00093         Real r_h = (Real)sqrt(r2/h2);
00094         if (i1<i2)
00095             particles[i1].neighbors.push_back(std::make_pair(i2,r_h));
00096         else
00097             particles[i2].neighbors.push_back(std::make_pair(i1,r_h));
00098     }
00099 
00100 protected:
00102     Real  constWd(Real h) const
00103     {
00104         return (Real)(315 / (64*R_PI*h*h*h));
00105     }
00106     Real  Wd(Real r_h, Real C)
00107     {
00108         Real a = (1-r_h*r_h);
00109         return  C*a*a*a;
00110     }
00111 
00112     // grad W = d(W)/dr Ur            in spherical coordinates, with Ur = D/|D| = D/r
00113     //        = d( C(1-r2/h2)3 )/dr D/r
00114     //        = d( C/h6 (h2-r2)3 )/dr D/r
00115     //        = d( C/h6 (h2-r2)(h4+r4-2h2r2) )/dr D/r
00116     //        = ( C/h6 (h2-r2)(4r3-4h2r) + (-2r)(h4+r4-2h2r2) ) D/r
00117     //        = C/h6 ( 4h2r3-4h4r-4r5+4h2r3 -2h4r -2r5 +4h2r3 ) D/r
00118     //        = C/h6 ( -6r5 +12h2r3 -6h4r ) D/r
00119     //        = -6C/h6 ( r4 -2h2r2 +h4 ) D
00120     //        = -6C/h6 ( h2 - r2 )2 D
00121     //        = -6C/h2 ( 1 - r2/h2 )2 D
00122     Real  constGradWd(Real h) const
00123     {
00124         return -6*constWd(h)/(h*h);
00125     }
00126     Deriv gradWd(const Deriv& d, Real r_h, Real C)
00127     {
00128         Real a = (1-r_h*r_h);
00129         return d*(C*a*a);
00130     }
00131 
00132     // laplacian(W) = d(W)/dx2 + d(W)/dy2 + d(W)/dz2
00133     //              = 1/r d2(rW)/dr2                 in spherical coordinate, as f only depends on r
00134     //              = C/r d2(r(1-r2/h2)3)/dr2
00135     //              = C/rh6 d2(r(h2-r2)3)/dr2
00136     //              = C/rh6 d2(r(h2-r2)(h4-2h2r2+r4))/dr2
00137     //              = C/rh6 d2(r(h6-3h4r2+3h2r4-r6))/dr2
00138     //              = C/rh6 d2(h6r-3h4r3+3h2r5-r7)/dr2
00139     //              = C/rh6 d(h6-9h4r2+15h2r4-7r6)/dr
00140     //              = C/rh6 (-18h4r+60h2r3-42r5)
00141     //              = C/h6 (-18h4+60h2r2-42r4)
00142     //              = 6C/h2 (-3+10r2/h2-7r4/h4)
00143     //              = CL (-3+10r2/h2-7r4/h4)
00144     Real  constLaplacianWd(Real h) const
00145     {
00146         return 6*constWd(h)/(h*h);
00147     }
00148     Real  laplacianWd(Real r_h, Real C)
00149     {
00150         Real r2_h2 = r_h*r_h;
00151         return C*(-3+10*r2_h2-7*r2_h2*r2_h2);
00152     }
00153 
00155     Real  constWp(Real h) const
00156     {
00157         return (Real)(15 / (R_PI*h*h*h));
00158     }
00159     Real  Wp(Real r_h, Real C)
00160     {
00161         Real a = (1-r_h);
00162         return  C*a*a*a;
00163     }
00164 
00165     // grad W = d(W)/dr Ur            in spherical coordinates, with Ur = D/|D| = D/r
00166     //        = d( C(1-r/h)3 )/dr D/r
00167     //        = d( C/h3 (h-r)3 )/dr D/r
00168     //        = d( C/h6 (h-r)(h2+r2-2hr) )/dr D/r
00169     //        = C/h6 ( (h-r)(2r-2h) -(h2+r2-2hr) ) D/r
00170     //        = C/h6 ( -2r2+4hr-2h2 -r2+2hr-h2 ) D/r
00171     //        = C/h6 ( -2r2+4hr-2h2 -r2+2hr-h2 ) D/r
00172     //        = C/h6 ( -3r2+6hr-3h2 ) D/r
00173     //        = 3C/h4 ( -r2/h2+2r/h-1 ) D/r
00174     //        = -3C/h4 ( 1-r/h )2 D/r
00175     Real  constGradWp(Real h) const
00176     {
00177         return (-3*constWp(h)) / (h*h*h*h);
00178     }
00179     Deriv gradWp(const Deriv& d, Real r_h, Real C)
00180     {
00181         Real a = (1-r_h);
00182         return d * (C*a*a);
00183     }
00184 
00185     //Real  laplacianWp(Real r_h, Real C);
00186 
00188     Real  constWv(Real h)
00189     {
00190         return (Real)(15/(2*R_PI*h*h*h));
00191     }
00192     Real  Wv(Real r_h, Real C)
00193     {
00194         Real r2_h2 = r_h*r_h;
00195         Real r3_h3 = r2_h2*r_h;
00196         return C*(-0.5f*r3_h3 + r2_h2 + 0.5f/r_h - 1);
00197     }
00198 
00199     // grad W = d(W)/dr Ur            in spherical coordinates, with Ur = D/|D| = D/r
00200     //        = d( C(-r3/2h3 + r2/h2 + h/2r - 1) )/dr D/r
00201     //        = C(-3r2/2h3 + 2r/h2 - h/2r2) D/r
00202     //        = C(-3r/2h3 + 2/h2 - h/2r3) D
00203     //        = C/2h2 (-3r/h + 4 - h3/r3) D
00204 
00205     Real  constGradWv(Real h)
00206     {
00207         return constWv(h)/(2*h*h);
00208     }
00209     Deriv gradWv(const Deriv& d, Real r_h, Real C)
00210     {
00211         Real r3_h3 = r_h*r_h*r_h;
00212         return d * (C*(-3*r_h  + 4 - 1/r3_h3));
00213     }
00214 
00215     // laplacian(W) = d(W)/dx2 + d(W)/dy2 + d(W)/dz2
00216     //              = 1/r d2(rW)/dr2                 in spherical coordinate, as f only depends on r
00217     //              = C/r d2(r(-r3/2h3 + r2/h2 + h/2r - 1))/dr2
00218     //              = C/r d2(-r4/2h3 + r3/h2 + h/2 - r)/dr2
00219     //              = C/r d(-4r3/2h3 + 3r2/h2 - 1)/dr
00220     //              = C/r (-6r2/h3 + 6r/h2)
00221     //              = C (-6r/h3 + 6/h2)
00222     //              = 6C/h2 (1 - r/h)
00223 
00224     // laplacian(W) = d(W)/dx2 + d(W)/dy2 + d(W)/dz2
00225     //              = 1/r2 d(r2 d(W)/dr)/dr                 in spherical coordinate, as f only depends on r
00226     //              = C/r2 d(r2 d(-r3/2h3 + r2/h2 + h/2r - 1)/dr)/dr
00227     //              = C/r2 d(r2 (-3r2/2h3 + 2r/h2 - h/2r2))/dr
00228     //              = C/r2 d(-3r4/2h3 + 2r3/h2 - h/2))/dr
00229     //              = C/r2 (-6r3/h3 + 6r2/h2)
00230     //              = 6C/h2 (1 -r/h)
00231 
00232     Real  constLaplacianWv(Real h)
00233     {
00234         return 6*constWv(h)/(h*h);
00235         //return 75/(R_PI*h*h*h*h*h);
00236     }
00237 
00238     Real  laplacianWv(Real r_h, Real C)
00239     {
00240         return C*(1-r_h);
00241     }
00242 
00244     Real  constWc(Real h) const
00245     {
00246         return (Real)(315 / (64*R_PI*h*h*h));
00247     }
00248     Real  Wc(Real r_h, Real C)
00249     {
00250         Real a = (1-r_h*r_h);
00251         return  C*a*a*a;
00252     }
00253     Real  constGradWc(Real h) const
00254     {
00255         return -6*constWc(h)/(h*h);
00256     }
00257     Deriv gradWc(const Deriv& d, Real r_h, Real C)
00258     {
00259         Real a = (1-r_h*r_h);
00260         return d*(C*a*a);
00261     }
00262     Real  constLaplacianWc(Real h) const
00263     {
00264         return 6*constWc(h)/(h*h);
00265     }
00266     Real  laplacianWc(Real r_h, Real C)
00267     {
00268         Real r2_h2 = r_h*r_h;
00269         return C*(-3+10*r2_h2-7*r2_h2*r2_h2);
00270     }
00271 
00272 
00273     struct DForce
00274     {
00275         unsigned int a,b;
00276         Real df;
00277     };
00278     
00279     sofa::helper::vector<DForce> dforces;
00280     
00281 public:
00282     SPHFluidForceField();
00283 
00284     Real getParticleRadius() const { return particleRadius.getValue(); }
00285     void setParticleRadius(Real v) { particleRadius.setValue(v);    }
00286     Real getParticleMass() const { return particleMass.getValue(); }
00287     void setParticleMass(Real v) { particleMass.setValue(v);    }
00288     Real getPressureStiffness() const { return pressureStiffness.getValue(); }
00289     void setPressureStiffness(Real v) { pressureStiffness.setValue(v);    }
00290     Real getDensity0() const { return density0.getValue(); }
00291     void setDensity0(Real v) { density0.setValue(v);    }
00292     Real getViscosity() const { return viscosity.getValue(); }
00293     void setViscosity(Real v) { viscosity.setValue(v);    }
00294     Real getSurfaceTension() const { return surfaceTension.getValue(); }
00295     void setSurfaceTension(Real v) { surfaceTension.setValue(v);    }
00296     
00297     Real getParticleField(int i, Real r2_h2)
00298     {
00299         Real a = 1-r2_h2;
00300         return (a*a*a)/particles[i].density;
00301     }
00302     
00303     Real getParticleFieldConstant(Real h)
00304     {
00305       return constWc(h)*particleMass.getValue();
00306     }
00307 
00308     virtual void init();
00309     
00310     virtual void addForce (VecDeriv& f, const VecCoord& x, const VecDeriv& v);
00311     
00312     virtual void addDForce (VecDeriv& df, const VecDeriv& dx);
00313         
00314     virtual double getPotentialEnergy(const VecCoord& x);
00315     
00316     void draw();
00317 };
00318 
00319 } // namespace forcefield
00320 
00321 } // namespace component
00322 
00323 } // namespace sofa
00324 
00325 #endif

Generated on Sun Nov 23 03:07:01 2008 for Sofa by  doxygen 1.5.7.1