• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
SandCu的灌水区
博客园    首页    新随笔    联系   管理    订阅  订阅
流体力学 我也来插一脚吧~毫无技术含量的Silverlight移植版

本版本只是把js+HTML那个版本的算法移植到Silverlight上 连变量名称都没改......

不但没优化 反而退步了  单击start就可以了 ~

原帖:http://news.cnblogs.com/n/85268/ 

园子里的同志用原生js写的http://www.cnblogs.com/hongru/archive/2010/12/21/1912820.html 

代码链接:https://files.cnblogs.com/sandcu/fluent.rar

 

 

代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Threading;
using System.Windows.Threading;
namespace fluent
{
    
public partial class MainPage : UserControl
    {
        LiquidTest lt;
        DispatcherTimer dispatcher 
= new DispatcherTimer();
        
public MainPage()
        {
            InitializeComponent();
            lt 
= new LiquidTest(100, 100, 50, 50);
            lt.init();
            
//  CompositionTarget.Rendering+=RenderFrame;
            dispatcher.Tick += new EventHandler(changePage_Tick);
            dispatcher.Interval 
= new TimeSpan(0, 0, 0, 0, 10);
            canvas 
= LayoutRoot;
        }
        
private void changePage_Tick(object sender, EventArgs e)
        {
            Path path 
= canvas.Children[1] as Path;
            path.ClearValue(Path.DataProperty);
            
foreach (Particle p in lt.particles)
            {
                
//   var p = this.particles[pi];
                line(4.0 * p.x, 4.0 * p.y,
                     
4.0 * (p.x - p.u), 4.0 * (p.y - p.v));
            }
            lt.simulate();
        }
        
private void Button_Click(object sender, RoutedEventArgs e)
        {

            dispatcher.Start();
            running 
= true;
            step 
= 1;

        }
       
        Canvas canvas;
        
//var context;
        bool running = false;
        
int width = 0;
        
int height = 0;
        
//var liquidTest;
        int step = 1;

        
class Material
        {
            
public double m;
            
public double rd;
            
public double k;
            
public double v;
            
public double d;
            
public double g;
            
public Material(double m, double rd, double k, double v, double d, double g)
            {
                
this.m = m;
                
this.rd = rd;
                
this.k = k;
                
this.v = v;
                
this.d = d;
                
this.g = g;

            }
        }

        
class Node
        {
            
public double m = 0;
            
public double d = 0;
            
public double gx = 0;
            
public double gy = 0;
            
public double u = 0;
            
public double v = 0;
            
public double ax = 0;
            
public double ay = 0;
            
public bool active = false;

            
public void clear()
            {
                
this.m = this.d = this.gx = this.gy = this.u = this.v = this.ax = this.ay = 0.0;
                active 
= false;
            }
        }


        
class Particle
        {
            
public Material mat;
            
public double x = 0, y = 0;
            
public double u = 0, v = 0;
            
public Particle(Material mat, double x, double y, double u, double v)
            {
                
this.mat = mat;
                
this.x = x;
                
this.y = y;
                
this.u = u;
                
this.v = v;
            }
            
public double dudx = 0;
            
public double dudy = 0;
            
public double dvdx = 0;
            
public double dvdy = 0;
            
public int cx = 0;
            
public int cy = 0;

            
public double[] px = new double[] { 0, 0, 0 };
            
public double[] py = new double[] { 0, 0, 0 };
            
public double[] gx = new double[] { 0, 0, 0 };
            
public double[] gy = new double[] { 0, 0, 0 };
        }
        
class LiquidTest
        {
            
int gsizeX;
            
int gsizeY;
            
int particlesX; int particlesY;
            
public LiquidTest(int gsizeX, int gsizeY, int particlesX, int particlesY)
            {
                
this.gsizeX = gsizeX;
                
this.gsizeY = gsizeY;
                
this.particlesX = particlesX;
                
this.particlesY = particlesY;
            }
            
public List<Particle> particles = new List<Particle>();



            List
<List<Node>> grid = new List<List<Node>>();
            List
<Node> active = new List<Node>(); //Nodes
            Material water = new Material(1.0, 1.0, 1.0, 1.0, 1.0, 1.0);
            
//this.pressed = false;
            
//  this.pressedprev = false;

            
double mx = 0;
            
double my = 0;
            
double mxprev = 0;
            
double myprev = 0;

            
public void init()
            {
                
int i = 0, j = 0;

                
for (i = 0; i < this.gsizeX; i++)
                {
                    List
<Node> nodes = new List<Node>();
                    
for (j = 0; j < this.gsizeY; j++)
                    {
                        nodes.Add(
new Node());
                    }
                    grid.Add(nodes);
                }

                Particle p;
                
for (i = 0; i < particlesX; i++)
                    
for (j = 0; j < particlesY; j++)
                    {
                        p 
= new Particle(water, i + 4, j + 4, 0.0, 0.0);
                        
this.particles.Add(p);
                    }
            }


            
public void simulate()
            {
                
bool drag = false;
                
double mdx = 0.0, mdy = 0.0;

                
// if (this.pressed && this.pressedprev)
                
//  {
                
//     drag = true;
                
//     mdx = 0.25 * (this.mx - this.mxprev);
                
//     mdy = 0.25 * (this.my - this.myprev);
                
// }

                
//   this.pressedprev = this.pressed;
                this.mxprev = this.mx;
                
this.myprev = this.my;

                
foreach (Node n in this.active)
                {
                    n.clear();
                } 
this.active.Clear();


                
double x, y, phi;
                
double fx = 0.0, fy = 0.0;
                
foreach (Particle p in this.particles)
                {
                    
//  var p = this.particles[pi];
                    p.cx = (int)(p.x - 0.5);
                    p.cy 
= (int)(p.y - 0.5);

                    x 
= p.cx - p.x;
                    p.px[
0] = (0.5 * x * x + 1.5 * x + 1.125);
                    p.gx[
0] = (x + 1.5);
                    x 
+= 1.0;
                    p.px[
1] = (-x * x + 0.75);
                    p.gx[
1] = (-2.0 * x);
                    x 
+= 1.0;
                    p.px[
2] = (0.5 * x * x - 1.5 * x + 1.125);
                    p.gx[
2] = (x - 1.5);

                    y 
= p.cy - p.y;
                    p.py[
0] = (0.5 * y * y + 1.5 * y + 1.125);
                    p.gy[
0] = (y + 1.5);
                    y 
+= 1.0;
                    p.py[
1] = (-y * y + 0.75);
                    p.gy[
1] = (-2.0 * y);
                    y 
+= 1.0;
                    p.py[
2] = (0.5 * y * y - 1.5 * y + 1.125);
                    p.gy[
2] = (y - 1.5);

                    
for (int i = 0; i < 3; i++)
                    {
                        
for (int j = 0; j < 3; j++)
                        {
                            Node n 
= this.grid[p.cx + i][p.cy + j];
                            
if (!n.active)
                            {
                                
this.active.Add(n);
                                n.active 
= true;
                            }
                            phi 
= p.px[i] * p.py[j];
                            n.m 
+= phi * p.mat.m;
                            n.d 
+= phi;
                            n.gx 
+= p.gx[i] * p.py[j];
                            n.gy 
+= p.px[i] * p.gy[j];
                        }
                    }
                }

                
double density, pressure, weight;
                Node n01, n02;
                Node n11, n12;
                
int cx, cy;
                
int cxi, cyi;

                
double pdx, pdy;
                
double C20, C02, C30, C03;
                
double csum1, csum2;
                
double C21, C31, C12, C13, C11;

                
double u, u2, u3;
                
double v, v2, v3;

                
foreach (Particle p in this.particles)
                {


                    cx 
= (int)(p.x);
                    cy 
= (int)(p.y);
                    cxi 
= cx + 1;
                    cyi 
= cy + 1;

                    n01 
= this.grid[cx][cy];
                    n02 
= this.grid[cx][cyi];
                    n11 
= this.grid[cxi][cy];
                    n12 
= this.grid[cxi][cyi];

                    pdx 
= n11.d - n01.d;
                    pdy 
= n02.d - n01.d;
                    C20 
= 3.0 * pdx - n11.gx - 2.0 * n01.gx;
                    C02 
= 3.0 * pdy - n02.gy - 2.0 * n01.gy;
                    C30 
= -2.0 * pdx + n11.gx + n01.gx;
                    C03 
= -2.0 * pdy + n02.gy + n01.gy;
                    csum1 
= n01.d + n01.gy + C02 + C03;
                    csum2 
= n01.d + n01.gx + C20 + C30;
                    C21 
= 3.0 * n12.d - 2.0 * n02.gx - n12.gx - 3.0 * csum1 - C20;
                    C31 
= -2.0 * n12.d + n02.gx + n12.gx + 2.0 * csum1 - C30;
                    C12 
= 3.0 * n12.d - 2.0 * n11.gy - n12.gy - 3.0 * csum2 - C02;
                    C13 
= -2.0 * n12.d + n11.gy + n12.gy + 2.0 * csum2 - C03;
                    C11 
= n02.gx - C13 - C12 - n01.gx;

                    u 
= p.x - cx;
                    u2 
= u * u;
                    u3 
= u * u2;
                    v 
= p.y - cy;
                    v2 
= v * v;
                    v3 
= v * v2;
                    density 
= n01.d + n01.gx * u + n01.gy * v + C20 * u2 + C02 * v2 + C30 * u3 + C03 * v3 + C21 * u2 * v + C31 * u3 * v + C12 * u * v2 + C13 * u * v3 + C11 * u * v;

                    pressure 
= density - 1.0;
                    
if (pressure > 2.0)
                        pressure 
= 2.0;

                    fx 
= 0.0;
                    fy 
= 0.0;

                    
if (p.x < 4.0)
                        fx 
+= p.mat.m * (4.0 - p.x);
                    
else if (p.x > this.gsizeX - 5)
                        fx 
+= p.mat.m * (this.gsizeX - 5 - p.x);

                    
if (p.y < 4.0)
                        fy 
+= p.mat.m * (4.0 - p.y);
                    
else if (p.y > this.gsizeY - 5)
                        fy 
+= p.mat.m * (this.gsizeY - 5 - p.y);

                    
if (drag)
                    {
                        var vx 
= Math.Abs(p.x - 0.25 * this.mx);
                        var vy 
= Math.Abs(p.y - 0.25 * this.my);
                        
if ((vx < 10.0) && (vy < 10.0))
                        {
                            weight 
= p.mat.m * (1.0 - vx * 0.10) * (1.0 - vy * 0.10);
                            fx 
+= weight * (mdx - p.u);
                            fy 
+= weight * (mdy - p.v);
                        }
                    }

                    
for (int i = 0; i < 3; i++)
                    {
                        
for (int j = 0; j < 3; j++)
                        {
                            Node n 
= this.grid[(p.cx + i)][(p.cy + j)];
                            phi 
= p.px[i] * p.py[j];
                            n.ax 
+= -((p.gx[i] * p.py[j]) * pressure) + fx * phi;
                            n.ay 
+= -((p.px[i] * p.gy[j]) * pressure) + fy * phi;
                        }
                    }
                }

                
foreach (Node n in this.active)
                {
                    
// var n = this.active[ni];
                    if (n.m > 0.0)
                    {
                        n.ax 
/= n.m;
                        n.ay 
/= n.m;
                        n.ay 
+= 0.03;
                    }
                }

                
double mu, mv;
                
foreach (Particle p in this.particles)
                {
                    
//  var p = this.particles[pi];
                    for (int i = 0; i < 3; i++)
                    {
                        
for (int j = 0; j < 3; j++)
                        {
                            Node n 
= this.grid[(p.cx + i)][(p.cy + j)];
                            phi 
= p.px[i] * p.py[j];
                            p.u 
+= phi * n.ax;
                            p.v 
+= phi * n.ay;
                        }
                    }
                    mu 
= p.mat.m * p.u;
                    mv 
= p.mat.m * p.v;
                    
for (int i = 0; i < 3; i++)
                    {
                        
for (int j = 0; j < 3; j++)
                        {
                            Node n 
= this.grid[(p.cx + i)][(p.cy + j)];
                            phi 
= p.px[i] * p.py[j];
                            n.u 
+= phi * mu;
                            n.v 
+= phi * mv;
                        }
                    }
                }

                
foreach (Node n in this.active)
                {
                    
// var n = this.active[ni];
                    if (n.m > 0.0)
                    {
                        n.u 
/= n.m;
                        n.v 
/= n.m;
                    }
                }

                
double gu, gv;
                Random rm 
= new Random();

                
foreach (Particle p in this.particles)
                {
                    
//var p = this.particles[pi];
                    gu = 0.0;
                    gv 
= 0.0;
                    
for (var i = 0; i < 3; i++)
                    {
                        
for (var j = 0; j < 3; j++)
                        {
                            var n 
= this.grid[(p.cx + i)][(p.cy + j)];
                            phi 
= p.px[i] * p.py[j];
                            gu 
+= phi * n.u;
                            gv 
+= phi * n.v;
                        }
                    }
                    p.x 
+= gu;
                    p.y 
+= gv;
                    p.u 
+= 1.0 * (gu - p.u);
                    p.v 
+= 1.0 * (gv - p.v);
                    
if (p.x < 1.0)
                    {
                        p.x 
= (1.0 + rm.Next(0, 1) * 0.01);
                        p.u 
= 0.0;
                    }
                    
else if (p.x > this.gsizeX - 2)
                    {
                        p.x 
= (this.gsizeX - 2 - rm.Next(0, 1) * 0.01);
                        p.u 
= 0.0;
                    }
                    
if (p.y < 1.0)
                    {
                        p.y 
= (1.0 + rm.Next(0, 1) * 0.01);
                        p.v 
= 0.0;
                    }
                    
else if (p.y > this.gsizeY - 2)
                    {
                        p.y 
= (this.gsizeY - 2 - rm.Next(0, 1) * 0.01);
                        p.v 
= 0.0;
                    }
                }
            }


        }



        
private void line(double x1, double y1, double x2, double y2)
        {
            Path path 
= canvas.Children[1] as Path;
            GeometryGroup aPathGeometry;
// = new PathGeometry();
            if (path.Data == null)
            {
                aPathGeometry 
= new GeometryGroup();
                path.Data 
= aPathGeometry;
                path.Stroke 
= new SolidColorBrush(Colors.Black);
                path.StrokeThickness 
= 2;

            }
            
else
            {
                aPathGeometry 
= path.Data as GeometryGroup;
            }
            LineGeometry Line 
= new LineGeometry();

            Line.StartPoint 
= new Point(x1, y1);
            Line.EndPoint 
= new Point(x2, y2);
            aPathGeometry.Children.Add(Line);
        }

       
    }
}

 

 

posted on 2010-12-21 19:06  abandoned  阅读(1046)  评论(10)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3