格子Boltzamnn方法计算平板间方柱绕流流场速度压力分布

/***********************************************
The LBE code is programed for isothermal incompressible flow using the D2Q9 with the bounce back boundary conditon.

for Square column flow around

**********************************************/
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <fstream>
#include<fstream>
#include<sstream>
using namespace std;
const int N = 200;
const int M = 50;
const int DX = 20;
const int DY = 19;
const int H = 10;

const int N1 = (N + 1);
const int M1 = (M + 1);
const int jmax = M;
const int imax = N;
const int L = (M + 1);   // width of the cavity  
const int Q = 9;         // number of discrete velocities  
const double rho0 = 1.0; // initial density 
const double ux0 = 0.0;  // initial velocity component in x direction  
const double uy0 = 0.0;  // initial velocity component in y direction  
const double Re = 200.00;

const double Ma = 0.1;
const double RT = 1.0 / 3.0;
const double CS = sqrt(3 * RT);
const double Umax = CS * Ma;
//const double Umax = 0.1;
double UU;
int i, j, k;
int ex[Q] = { 0, 1, 0, -1, 0, 1, -1, -1, 1 };
int ey[Q] = { 0, 0, 1, 0, -1, 1, 1, -1, -1 };
double w[Q] = { 4.0 / 9, 1.0 / 9, 1.0 / 9 , 1.0 / 9 , 1.0 / 9 , 1.0 / 36, 1.0 / 36 , 1.0 / 36 , 1.0 / 36 };

double f[M1][N1][Q], F[M1][N1][Q];
double ux[M1][N1], uy[M1][N1];
double u0[M1][N1], v0[M1][N1];                                      //error initial condition
double velocity[M1][N1], pressure[M1][N1], rho[M1][N1];             //calculate
double tau, err, err_out;                                           //Relaxtion time for BGK model
double C = 1.0;
void initial(void);
void evolution(void);
void boundary_P(void);
void calculate(void);
void dataoutput(void);
void contour(void);
double feq(double RHO, double U, double V, int k);
double error(void);
//================================================================
int main()
{
    int step, M2, N2;
    double err;
    M2 = M / 2;
    N2 = N / 2;

    step = 0;
    err = 1.0;
    tau = 3 * (double)H * Umax / Re + 0.5;


    clock_t start, finish;
    double time;
    start = clock();
    cout << "start calculate ..." << "\t  Re = " << Re << "\t tau = " << tau;
    cout << " \t  size: " << N << " * " << M << " \t    U = " << Umax << endl << endl;

    initial();

    while (err > 1.0e-6)
    {
        step++;
        evolution();
        calculate();
        boundary_P();
        if (step % 1000 == 0)
        {
            err = error();
            //printf("err = %e  \t ux_center = %e  \t uy_center = %e  \t step = %d\n", err, ux[M2][N2], uy[M2][N2], step);
            cout << scientific << "err = " << err << "\t  step = " << step << endl;
        }
        if (step >= 40000)
        {
            break;
        }
    }
    //dataoutput();
    contour();
    finish = clock();
    time = (float)(finish - start) / CLOCKS_PER_SEC;
    cout << "time = " << time << "s" << endl;
    return 0;
}
//================================================================

//1. 初始化
void initial()
{
    int i, j, k;
    for (j = 0; j <= jmax; j++)
    {
        for (i = 0; i <= imax; i++)
        {
            ux[j][i] = ux0;
            uy[j][i] = uy0;
            rho[j][i] = rho0;
            for (k = 0; k < Q; k++)
                f[j][i][k] = feq(rho[j][i], ux[j][i], uy[j][i], k);
        }
        double D = M;
        UU = (4 * Umax / D / D) * ((double)j * D - (double)j * j);
        ux[j][0] = UU;
    }
}

//2. 局部平衡分布函数
double feq(double RHO, double U, double V, int k)
{
    double euv, uv, re;
    euv = ex[k] * U + ey[k] * V;
    uv = U * U + V * V;
    re = w[k] * RHO * (1.0 + 3.0 * euv + 4.5 * euv * euv - 1.5 * uv);
    return re;
}

//3. 演化过程(碰撞迁移)
void evolution()
{
    int id, jd;
    for (j = 1; j < jmax; j++)//边界不参与碰撞
        for (i = 1; i < imax; i++)
        {
            if (i >= DX && i <= DX + H && j >= DY && j <= DY + H)
                continue;
            for (k = 0; k < Q; k++)
            {
                id = i - ex[k];
                jd = j - ey[k];
                F[j][i][k] = f[jd][id][k] + (feq(rho[jd][id], ux[jd][id], uy[jd][id], k) - f[jd][id][k]) / tau;
            }
        }
}

//4. 计算宏观量
void calculate()
{
    for (j = 1; j < jmax; j++)
    {
        for (i = 1; i < imax; i++)
        {
            if (i >= DX && i <= DX + H && j >= DY && j <= DY + H)
                continue;       //抛去方柱边界格点
            u0[j][i] = ux[j][i];//不需要收敛判断时可去除
            v0[j][i] = uy[j][i];
            rho[j][i] = 0.0;
            ux[j][i] = 0.0;
            uy[j][i] = 0.0;
            for (k = 0; k < Q; k++)
            {
                f[j][i][k] = F[j][i][k];
                rho[j][i] += f[j][i][k];    //求密度
                ux[j][i] += ex[k] * f[j][i][k];
                uy[j][i] += ey[k] * f[j][i][k];
            }
            ux[j][i] /= rho[j][i];
            uy[j][i] /= rho[j][i];
            velocity[j][i] = sqrt(ux[j][i] * ux[j][i] + uy[j][i] * uy[j][i]);   //计算宏观速度
            pressure[j][i] = rho[j][i] * C * C / 3;                             //计算压力
        }
    }

}

//5. 边界条件
void boundary_P()
{
    for (j = 0; j <= jmax; j++)//入口采用速度边界
    {
        i = 0;
        ux[j][i] = Umax;
        uy[j][i] = 0.0;
        rho[j][i] = (f[j][i][0] + f[j][i][2] + f[j][i][4] + 2.0 * (f[j][i][3] + f[j][i][6] + f[j][i][7])) / (1 - ux[j][i]);
        f[j][i][1] = f[j][i][3] + 2.0 * rho[j][i] * ux[j][i] / 3.0;
        f[j][i][5] = f[j][i][7] + rho[j][i] * ux[j][i] / 6.0 - 0.5 * (f[j][i][2] - f[j][i][4]) + rho[j][i] * uy[j][i] / 2.0;
        f[j][i][8] = f[j][i][6] + rho[j][i] * ux[j][i] / 6.0 + 0.5 * (f[j][i][2] - f[j][i][4]) - rho[j][i] * uy[j][i] / 2.0;
    }

    for (j = 0; j <= jmax; j++)//出口采用压力边界
    {
        i = N;
        ux[j][i] = 0;
        uy[j][i] = 0;
        rho[j][i] = 1.0;
        ux[j][i] = (f[j][i][0] + f[j][i][2] + f[j][i][4] + 2 * (f[j][i][1] + f[j][i][5] + f[j][i][8])) / rho[j][i] - 1.0;
        f[j][i][3] = f[j][i][1] - 2.0 * rho[j][i] * ux[j][i] / 3.0;
        f[j][i][7] = f[j][i][5] - rho[j][i] * ux[j][i] / 6.0 + 0.5 * (f[j][i][2] - f[j][i][4]);
        f[j][i][6] = f[j][i][8] - rho[j][i] * ux[j][i] / 6.0 - 0.5 * (f[j][i][2] - f[j][i][4]);
    }

    for (i = 1; i < N; i++)//上下边界采用标准反弹
    {
        j = 0;
        f[j][i][2] = f[j][i][4];
        f[j][i][5] = f[j][i][7];
        f[j][i][6] = f[j][i][8];
        j = M;
        f[j][i][4] = f[j][i][2];
        f[j][i][7] = f[j][i][5];
        f[j][i][8] = f[j][i][6];
    }

    for (i = DX + 1; i < DX + H; i++) //方柱上下边界采用标准反弹
    {
        j = DY + H;
        f[j][i][2] = f[j][i][4];
        f[j][i][5] = f[j][i][7];
        f[j][i][6] = f[j][i][8];
        j = DY;
        f[j][i][4] = f[j][i][2];
        f[j][i][7] = f[j][i][5];
        f[j][i][8] = f[j][i][6];
    }

    for (j = DY; j <= DY + H; j++) //方柱左右边界采用标准反弹
    {
        i = DX;
        f[j][i][3] = f[j][i][1];
        f[j][i][6] = f[j][i][8];
        f[j][i][7] = f[j][i][5];
        i = DX + H;
        f[j][i][1] = f[j][i][3];
        f[j][i][8] = f[j][i][6];
        f[j][i][5] = f[j][i][7];
    }
}

//6. 输出宏观量
void dataoutput()
{
    cout << "start output data ... " << endl;
    char n1[200];
    char n2[200];
    char n3[200];
    char n4[200];
    char n5[200];
    sprintf(n1, "x_%.0f.dat", Re);
    sprintf(n2, "y_%.0f.dat", Re);
    sprintf(n3, "ux_%.0f.dat", Re);
    sprintf(n4, "uy_%.0f.dat", Re);
    sprintf(n5, "rho_%.0f.dat", Re);

    int i, j;
    FILE* fp;

    fp = fopen(n1, "w+");
    for (i = 0; i <= N; i++) fprintf(fp, "%e \n", (i + 0.5) / L);
    fclose(fp);
    cout << "finish x.dat" << endl;

    fp = fopen(n2, "w+");
    for (j = 0; j <= M; j++) fprintf(fp, "%e \n", (j + 0.5) / L);
    fclose(fp);
    cout << "finish y.dat" << endl;

    fp = fopen(n3, "w");
    for (j = 0; j <= M; j++)
    {
        for (i = 0; i <= N; i++) fprintf(fp, "%e ", ux[j][i]);
        fprintf(fp, "\n");
    }
    fclose(fp);
    cout << "finish ux.dat" << endl;

    fp = fopen(n4, "w");
    for (j = 0; j <= M; j++)
    {
        for (i = 0; i <= N; i++) fprintf(fp, "%e ", uy[j][i]);
        fprintf(fp, "\n");
    }
    fclose(fp);
    cout << "finish uy.dat" << endl;

    fp = fopen(n5, "w");
    for (j = 0; j <= M; j++)
    {
        for (i = 0; i <= N; i++) fprintf(fp, "%e ", rho[j][i]);
        fprintf(fp, "\n");
    }
    fclose(fp);
    cout << "finish rho.dat" << endl;

}

//7. 输出云图
void contour()
{
    char c1[200];
    char c2[200];
    sprintf(c1, "Vector_%.0f .dat", Re);
    sprintf(c2, "Contour_%.0f.dat", Re);
    int i, j;
    //=======================================================
    ofstream fout;
    fout.open(c1, ios::app);
    fout << "TITLE = Vector   \nVariables = X Y U V  Pressure   Velocity \n" << "Zone " << "I = " << N1 << "  J = " << M1 << "   F = POINT" << endl;

    for (j = 0; j <= jmax; j++)
    {
        for (i = 0; i <= imax; i++)
        {
            fout << i << "\t" << j << "\t" << ux[j][i] << "\t" << uy[j][i] << "\t" << pressure[j][i] << "\t" << velocity[j][i] << endl;
        }
    }
    fout.close();
    cout << "Vector data finish" << endl;
    =======================================================
    //fout.open(c2, ios::app);
    //fout << "TITLE = Contour  \nVariables = X Y Velocity  \n" << "Zone " << "I = " << N1 << "  J = " << M1 << "   F = POINT" << endl;
    //for (j = 0; j <= jmax; j++)
    //{
    //    for (i = 0; i <= imax; i++)
    //    {
    //        fout << i << "\t" << j << "\t" << velocity[j][i] << endl;
    //    }
    //}
    //fout.close();
    //cout << "Contour data finish" << endl;
}

//8. 计算误差
double error()
{
    double err1, err2;
    err1 = err2 = 0.0;
    for (j = 1; j < jmax; j++)
        for (i = 1; i < imax; i++)
        {
            if (i >= DX && i <= DX + H && j >= DY && j <= DY + H)
                continue;
            err1 += sqrt((ux[j][i] - u0[j][i]) * (ux[j][i] - u0[j][i]) + (uy[j][i] - v0[j][i]) * (uy[j][i] - v0[j][i]));
            err2 += sqrt(ux[j][i] * ux[j][i] + uy[j][i] * uy[j][i]);
        }
    return err1 / (err2 + 1e-30);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Yvie_Bae

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值