/***********************************************
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);
}
格子Boltzamnn方法计算平板间方柱绕流流场速度压力分布
最新推荐文章于 2024-11-08 09:08:26 发布