SPHFluidForceField.h
Go to the documentation of this file.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_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
00068
00069
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
00113
00114
00115
00116
00117
00118
00119
00120
00121
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
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
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
00166
00167
00168
00169
00170
00171
00172
00173
00174
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
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
00200
00201
00202
00203
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
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232 Real constLaplacianWv(Real h)
00233 {
00234 return 6*constWv(h)/(h*h);
00235
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 }
00320
00321 }
00322
00323 }
00324
00325 #endif