コード例 #1
0
ファイル: SPH_Engine.cs プロジェクト: jpneill/SPHSim
        public void CalculateDensity(List <Particle> plst, float smoothing_radius)
        {
            int     pindex, nindex;
            float   density, near_density, distance_squared, distance, smoothing_kernel, smoothing_kernel_squared, smoothing_kernel_cubic;
            Vector2 vector_between_particle_neighbour;

            pindex = 0;
            foreach (Particle p in plst)
            {
                p.Density     = 0.0f;
                p.Neardensity = 0.0f;
                p.Neighbourlist.Clear();
                density      = 0.0f;
                near_density = 0.0f;

                for (nindex = pindex + 1; nindex < plst.Count; nindex++)
                {
                    vector_between_particle_neighbour.X = plst.ElementAt(nindex).Position.X - plst.ElementAt(pindex).Position.X;
                    vector_between_particle_neighbour.Y = plst.ElementAt(nindex).Position.Y - plst.ElementAt(pindex).Position.Y;
                    distance_squared = vector_between_particle_neighbour.LengthSquared();
                    distance         = (float)Math.Sqrt(distance_squared);

                    if (distance_squared < smoothing_radius * smoothing_radius)
                    {
                        N_Particle nparticle = new N_Particle();
                        smoothing_kernel = 1 - distance / smoothing_radius;
                        //smoothing_kernel_squared = (smoothing_kernel * smoothing_kernel);
                        smoothing_kernel_squared = (float)(6 / (smoothing_radius * Math.PI * smoothing_radius)) * (smoothing_kernel * smoothing_kernel);
                        //smoothing_kernel_cubic = smoothing_kernel_squared * smoothing_kernel;
                        smoothing_kernel_cubic = (float)(10 / (Math.PI * smoothing_radius * smoothing_radius)) * (smoothing_kernel * smoothing_kernel * smoothing_kernel);
                        density      += smoothing_kernel_squared;
                        near_density += smoothing_kernel_cubic;
                        plst.ElementAt(nindex).Density     += smoothing_kernel_squared;
                        plst.ElementAt(nindex).Neardensity += smoothing_kernel_cubic;
                        nparticle.Particleindex             = nindex;
                        nparticle.Smoothingkernel           = smoothing_kernel;
                        nparticle.Smoothingkernelsquared    = smoothing_kernel_squared;

                        nparticle.Distance             = distance;
                        nparticle.Ismovingboundary     = plst.ElementAt(nindex).Ismovingboundary;
                        nparticle.Isstationaryboundary = plst.ElementAt(nindex).Isstationaryboundary;
                        plst.ElementAt(pindex).Neighbourlist.Add(nparticle);
                    }
                }
                p.Density     += density;
                p.Neardensity += near_density;

                pindex++;
            }
        }
コード例 #2
0
ファイル: SPH_Engine.cs プロジェクト: jpneill/SPHSim
        public void CalculateViscosity(List <Particle> plst, float smoothing_radius, float dt)
        {
            int   pindex, nindex;
            float length, q, inward_radial_vel;

            N_Particle nparticle = new N_Particle();

            Vector2 vector_between_neighbour_particle;
            Vector2 normalised_vector_between_neighbour_particle;
            Vector2 impulse;

            pindex = 0;
            foreach (Particle p in plst)
            {
                foreach (N_Particle n in p.Neighbourlist)
                {
                    nparticle = n;
                    nindex    = nparticle.Particleindex;
                    vector_between_neighbour_particle = plst.ElementAt(nindex).Position - plst.ElementAt(pindex).Position;
                    length = nparticle.Distance;
                    q      = length / smoothing_radius;
                    normalised_vector_between_neighbour_particle = vector_between_neighbour_particle / length;
                    //calculate inward radial velocity
                    Vector2 temp = new Vector2();
                    temp.X            = plst.ElementAt(pindex).Velocity.X - plst.ElementAt(nindex).Velocity.X;
                    temp.Y            = plst.ElementAt(pindex).Velocity.Y - plst.ElementAt(nindex).Velocity.Y;
                    inward_radial_vel = Vector2.Dot(temp, normalised_vector_between_neighbour_particle);

                    if (inward_radial_vel > 0.0f)
                    {
                        impulse  = normalised_vector_between_neighbour_particle * (plst.ElementAt(nindex).Vsigma *inward_radial_vel + plst.ElementAt(nindex).Vbeta *inward_radial_vel *inward_radial_vel) * (1 - q);
                        impulse *= dt * dt_scalefactor;
                        if (plst.ElementAt(pindex).Ismovingboundary == false && plst.ElementAt(pindex).Isstationaryboundary == false)
                        {
                            plst.ElementAt(pindex).Velocity -= impulse;
                        }
                        if (plst.ElementAt(pindex).Ismovingboundary == false && plst.ElementAt(pindex).Isstationaryboundary == false)
                        {
                            plst.ElementAt(nindex).Velocity += impulse;
                        }
                    }
                }

                pindex++;
            }
        }
コード例 #3
0
ファイル: SPH_Engine.cs プロジェクト: jpneill/SPHSim
        public void CalculatePressure(List <Particle> plst, float stiffness, float near_stiffness, float rest_density, float dt, float smoothing_radius)
        {
            int   pindex, nindex;
            float pressure, near_pressure, smoothing_kernel, smoothing_kernel_squared, scalar_pressure;

            Vector2    particle_pressure;
            Vector2    vector_between_particle_neighbour;
            Vector2    neighbour_pressure;
            N_Particle nparticle = new N_Particle();

            pindex = 0;

            foreach (Particle p in plst)
            {
                pressure            = stiffness * (p.Density - rest_density);
                near_pressure       = near_stiffness * p.Neardensity;
                particle_pressure.X = particle_pressure.Y = 0; //reset particle pressure vector to 0

                foreach (N_Particle n in p.Neighbourlist)
                {
                    nindex = n.Particleindex;
                    //smoothing_kernel = n.Smoothingkernel;
                    smoothing_kernel                    = (float)(n.Smoothingkernel * (3 / (Math.PI * smoothing_radius * smoothing_radius)));
                    smoothing_kernel_squared            = n.Smoothingkernelsquared;
                    vector_between_particle_neighbour.X = plst.ElementAt(nindex).Position.X - plst.ElementAt(pindex).Position.X;
                    vector_between_particle_neighbour.Y = plst.ElementAt(nindex).Position.Y - plst.ElementAt(pindex).Position.Y;
                    scalar_pressure  = pressure * smoothing_kernel + near_pressure * smoothing_kernel_squared;
                    scalar_pressure *= dt * dt * dt_scalefactor * dt_scalefactor;

                    if (n.Distance != 0)
                    {
                        neighbour_pressure = vector_between_particle_neighbour / n.Distance * scalar_pressure;
                    }
                    else
                    {
                        neighbour_pressure.X = neighbour_pressure.Y = 0;
                    }

                    plst.ElementAt(nindex).AccumulateForce(neighbour_pressure);
                    particle_pressure -= neighbour_pressure;
                }
                p.Pressure = (float)(Math.Sqrt(particle_pressure.X * particle_pressure.X + particle_pressure.Y * particle_pressure.Y));
                p.AccumulateForce(particle_pressure);
                pindex++;
            }
        }
コード例 #4
0
ファイル: SPH_Engine.cs プロジェクト: jpneill/SPHSim
        public void CalculateViscoElasticity(List <Particle> plst, float smoothing_radius, float k, float yield_ratio, float pconst, float dt)
        {
            int   pindex, sindex, sp1index, sp2index;
            float restlength, tolerable_def, distance_between_neighbour_particle, tempfloat;

            Vector2 sdisplacement;
            Vector2 temp;

            //create springs
            pindex = 0;
            foreach (Particle p in plst)
            {
                foreach (N_Particle n in p.Neighbourlist)
                {
                    N_Particle nparticle = new N_Particle();
                    Spring     spring    = new Spring();
                    nparticle = n;


                    if (!SpringArray.Springarray[pindex, nparticle.Particleindex])
                    {
                        SpringArray.Springarray[pindex, nparticle.Particleindex] = true;
                        spring.Point1      = pindex;
                        spring.Point2      = nparticle.Particleindex;
                        spring.Restlength  = smoothing_radius;
                        tempfloat          = rand.Next((int)(k * 10), (int)(k * 10 + 3));
                        spring.Coefficient = tempfloat / 10;
                        //spring.Coefficient = k;
                        SpringArray.Springlst.Add(spring);
                    }
                }


                pindex++;
            }

            //Alter the rest length of springs
            sindex = 0;
            foreach (Spring s in SpringArray.Springlst.ToList())
            {
                sp1index      = s.Point1;
                sp2index      = s.Point2;
                restlength    = s.Restlength;
                tolerable_def = yield_ratio * restlength;
                temp.X        = plst.ElementAt(sp2index).Position.X - plst.ElementAt(sp1index).Position.X;
                temp.Y        = plst.ElementAt(sp2index).Position.Y - plst.ElementAt(sp1index).Position.Y;
                distance_between_neighbour_particle = temp.Length();

                if (distance_between_neighbour_particle > (restlength + tolerable_def))
                {
                    s.Restlength += dt * dt_scalefactor * pconst * (distance_between_neighbour_particle - restlength - tolerable_def);
                }
                else if (distance_between_neighbour_particle < (restlength - tolerable_def))
                {
                    s.Restlength -= dt * dt_scalefactor * pconst * (restlength - tolerable_def - distance_between_neighbour_particle);
                }

                if (s.Restlength > smoothing_radius && sindex < plst.Count)
                {
                    SpringArray.Springarray[sindex, sindex] = false;
                    SpringArray.Springlst.RemoveAt(sindex);
                    sindex--;
                }
                sindex++;
            }

            //update position of particle due to spring forces
            sindex = 0;
            foreach (Spring s in SpringArray.Springlst)
            {
                Vector2 sforce = new Vector2(0, 0);
                sp1index   = s.Point1;
                sp2index   = s.Point2;
                restlength = s.Restlength;
                sforce     = s.CalculateForce(sforce, s, plst.ElementAt(sp1index), plst.ElementAt(sp2index));

                sdisplacement = sforce * (1.0f - restlength / smoothing_radius) * dt * dt_scalefactor * dt * dt_scalefactor;
                if (plst.ElementAt(sp1index).Ismovingboundary == false && plst.ElementAt(sp1index).Isstationaryboundary == false)
                {
                    plst.ElementAt(sp1index).Position -= sdisplacement;
                }
                if (plst.ElementAt(sp2index).Ismovingboundary == false && plst.ElementAt(sp2index).Isstationaryboundary == false)
                {
                    plst.ElementAt(sp2index).Position += sdisplacement;
                }

                sindex++;
            }
        }