void project ( float * u, float * v, float * p, float * div ) { float h = 1.0/N; for ( int i=1 ; i<=N ; i++ ) { for ( int j=1 ; j<=N ; j++ ) { div[IX(i,j)] = -0.5*h*(u[IX(i+1,j)]-u[IX(i-1,j)]+ v[IX(i,j+1)]-v[IX(i,j-1)]); p[IX(i,j)] = 0; } } set_bnd ( 0, div ); set_bnd ( 0, p ); for ( int k=0 ; k<20 ; k++ ) { for ( int i=1 ; i<=N ; i++ ) { for ( int j=1 ; j<=N ; j++ ) { p[IX(i,j)] = (div[IX(i,j)]+p[IX(i-1,j)]+p[IX(i+1,j)]+ p[IX(i,j-1)]+p[IX(i,j+1)])/4; } } set_bnd ( 0, p ); } for ( int i=1 ; i<=N ; i++ ) { for ( int j=1 ; j<=N ; j++ ) { u[IX(i,j)] -= 0.5*(p[IX(i+1,j)]-p[IX(i-1,j)])/h; v[IX(i,j)] -= 0.5*(p[IX(i,j+1)]-p[IX(i,j-1)])/h; } } set_bnd ( 1, u ); set_bnd ( 2, v ); }
void project (gaszone_type *gz, float * u, float * v, float * p, float * div ) { int i, j, k; float h = 1.0/gz->n; for (i=1 ; i<=gz->n ; i++ ) { for (j=1 ; j<=gz->n ; j++ ) { div[IX(i,j)] = -0.5*h*(u[IX(i+1,j)]-u[IX(i-1,j)]+ v[IX(i,j+1)]-v[IX(i,j-1)]); p[IX(i,j)] = 0; } } set_bnd (gz, 0, div ); set_bnd (gz, 0, p ); for (k=0 ; k<19 ; k++ ) { for (i=1 ; i<=gz->n ; i++ ) { for (j=1 ; j<=gz->n ; j++ ) { p[IX(i,j)] = (div[IX(i,j)] + p[IX(i-1,j)] + p[IX(i+1,j)] + p[IX(i,j-1)] + p[IX(i,j+1)]) / 4; } } set_bnd (gz, 0, p ); } for (i=1 ; i<=gz->n ; i++ ) { for (j=1 ; j<=gz->n ; j++ ) { u[IX(i,j)] -= 0.5*(p[IX(i+1,j)]-p[IX(i-1,j)])/h; v[IX(i,j)] -= 0.5*(p[IX(i,j+1)]-p[IX(i,j-1)])/h; } } set_bnd (gz, 1, u ); set_bnd (gz, 2, v ); }
/* A linear backtrace that uses previous positions of particles to * calculate future positions */ void advect ( int N, int b, float * d, float * d0, float *u, float *v, float dt ) { int i, j, i0, j0, i1, j1; float x, y, s0, t0, s1, t1, dt0; dt0 = dt*N; FOR_EACH_CELL x = i-dt0*u[ IX(i, j) ]; y = j-dt0*v[ IX(i, j) ]; if(x<0.5f) x = 0.5f; if(x>N+0.5f) x = N+0.5f; i0 = (int)x; i1=i0+1; if(y<0.5f) y=0.5f; if (y>N+0.5f) y=N+0.5f; j0=(int)y; j1=j0+1; s1 = x-i0; s0 = 1-s1; t1 = y-j0; t0 = 1-t1; d[IX(i, j)] = s0*(t0*d0[IX(i0, j0)]+t1*d0[IX(i0, j1)])+ s1*(t0*d0[IX(i1, j0)]+t1*d0[IX(i1, j1)]); END_FOR set_bnd(N, b, d); }
inline void Fluid::advect(int b, float* x0, float* x, float* uu, float* vv, float* ww, float dt) { int i, j, k, i0, j0, k0, i1, j1, k1; float sx0, sx1, sy0, sy1, sz0, sz1, v0, v1; float xx, yy, zz, dt0; dt0 = dt*N; for (k=1; k<=N; k++) { for (j=1; j<=N; j++) { for (i=1; i<=N; i++) { xx = i-dt0*uu[_I(i,j,k)]; yy = j-dt0*vv[_I(i,j,k)]; zz = k-dt0*ww[_I(i,j,k)]; if (xx<0.5) xx=0.5f; if (xx>N+0.5) xx=N+0.5f; i0=(int)xx; i1=i0+1; if (yy<0.5) yy=0.5f; if (yy>N+0.5) yy=N+0.5f; j0=(int)yy; j1=j0+1; if (zz<0.5) zz=0.5f; if (zz>N+0.5) zz=N+0.5f; k0=(int)zz; k1=k0+1; sx1 = xx-i0; sx0 = 1-sx1; sy1 = yy-j0; sy0 = 1-sy1; sz1 = zz-k0; sz0 = 1-sz1; v0 = sx0*(sy0*x0[_I(i0,j0,k0)]+sy1*x0[_I(i0,j1,k0)])+sx1*(sy0*x0[_I(i1,j0,k0)]+sy1*x0[_I(i1,j1,k0)]); v1 = sx0*(sy0*x0[_I(i0,j0,k1)]+sy1*x0[_I(i0,j1,k1)])+sx1*(sy0*x0[_I(i1,j0,k1)]+sy1*x0[_I(i1,j1,k1)]); x[_I(i,j,k)] = sz0*v0 + sz1*v1; } } } set_bnd(b,d); }
// update density map according to velocity map // b : boundary width // d : current density map // d0 : previous density map // u,v : current velocity map // dt : elapsed time void advect ( int b, float * d, float * d0, float * u, float * v, float dt ) { int i0, j0, i1, j1; float x, y, s0, t0, s1, t1, dt0; dt0 = dt*N; for ( int i=1 ; i<=N ; i++ ) { for ( int j=1 ; j<=N ; j++ ) { x = i-dt0*u[IX(i,j)]; y = j-dt0*v[IX(i,j)]; if (x<0.5) x=0.5; if (x>N+0.5) x=N+ 0.5; i0=(int)x; i1=i0+1; if (y<0.5) y=0.5; if (y>N+0.5) y=N+ 0.5; j0=(int)y; j1=j0+1; s1 = x-i0; s0 = 1-s1; t1 = y-j0; t0 = 1-t1; d[IX(i,j)] = s0*(t0*d0[IX(i0,j0)]+t1*d0[IX(i0,j1)])+ s1*(t0*d0[IX(i1,j0)]+t1*d0[IX(i1,j1)]); } } set_bnd ( b, d ); }
// update density map according to velocity map // b : boundary width // d : current density map // d0 : previous density map // u,v : current velocity map // dt : elapsed time void advect (gaszone_type *gz, int b, float * d, float * d0, float * u, float * v, float dt ) { int i0, j0, i1, j1; float x, y, s0, t0, s1, t1, dt0; dt0 = dt*gz->n; int i, j; for (i=1 ; i<=gz->n ; i++ ) { for (j=1 ; j<=gz->n ; j++ ) { x = i-dt0*u[IX(i,j)]; y = j-dt0*v[IX(i,j)]; if (x<0.5) x=0.5; if (x>gz->n+0.5) x=gz->n+ 0.5; i0=(int)x; i1=i0+1; if (y<0.5) y=0.5; if (y>gz->n+0.5) y=gz->n+ 0.5; j0=(int)y; j1=j0+1; s1 = x-i0; s0 = 1-s1; t1 = y-j0; t0 = 1-t1; d[IX(i,j)] = s0*(t0*d0[IX(i0,j0)]+t1*d0[IX(i0,j1)])+ s1*(t0*d0[IX(i1,j0)]+t1*d0[IX(i1,j1)]); } } set_bnd (gz, b, d ); }
void advect(int width, int height, int b, float *d, float *d0, float *u, float *v, float dt) { for (int row = 1; row <= height; ++row) { for (int col = 1; col <= width; ++col) { float x = row - dt*width*u[IX(row, col)]; float y = col - dt*height*v[IX(row, col)]; if (x < 0.5) x = 0.5; if (x > (width + 0.5)) x = width + 0.5; float i0 = (int)x, i1 = i0 + 1; if (y < 0.5) y = 0.5; if (y > (height + 0.5)) y = height + 0.5; float j0 = (int)y, j1 = i0 + 1; float s1 = x - i0, s0 = 1 -s1, t1 = y - j0, t0 = 1 - t1; d[IX(row, col)] = (s0*(t0*d0[IX(i0, j0)] + t1*d0[IX(i0, j1)]) + s1*(t0*d0[IX(i1, j0)] + t1*d0[IX(i1, j1)])); } } set_bnd(width, height, b, d); }
/////////////////////////////////////////////////////////////////////////////// /// Entrance of calculating diffusion equation /// ///\param para Pointer to FFD parameters ///\param var Pointer to FFD simulation variables ///\param var_type Type of variable ///\param index Index of trace substance or species ///\param psi Pointer to the variable at current time step ///\param psi0 Pointer to the variable at previous time step ///\param BINDEX Pointer to boundary index /// ///\return 0 if no error occurred /////////////////////////////////////////////////////////////////////////////// int diffusion(PARA_DATA *para, REAL **var, int var_type, int index, REAL *psi, REAL *psi0, int **BINDEX) { int flag = 0; /**************************************************************************** | Define the coeffcients for diffusion euqation ****************************************************************************/ flag = coef_diff(para, var, psi, psi0, var_type, index, BINDEX); if(flag!=0) { ffd_log("diffsuion(): Could not calculate coefficents for " "diffusion equation.", FFD_ERROR); return flag; } // Solve the equations equ_solver(para, var, var_type, psi); // Define B.C. set_bnd(para, var, var_type, index, psi, BINDEX); // Check residual if(para->solv->check_residual==1) { switch(var_type) { case VX: sprintf(msg, "diffusion(): Residual of VX is %f", check_residual(para, var, psi)); ffd_log(msg, FFD_NORMAL); break; case VY: sprintf(msg, "diffusion(): Residual of VY is %f", check_residual(para, var, psi)); ffd_log(msg, FFD_NORMAL); break; case VZ: sprintf(msg, "diffusion(): Residual of VZ is %f", check_residual(para, var, psi)); ffd_log(msg, FFD_NORMAL); break; case TEMP: sprintf(msg, "diffusion(): Residual of T is %f", check_residual(para, var, psi)); ffd_log(msg, FFD_NORMAL); break; case TRACE: sprintf(msg, "diffusion(): Residual of Trace %d is %f", index, check_residual(para, var, psi)); ffd_log(msg, FFD_NORMAL); break; default: sprintf(msg, "diffusion(): No sovler for varibale type %d", var_type); ffd_log(msg, FFD_ERROR); flag = 1; } } return flag; } // End of diffusion( )
void project ( int N, float * u, float * v, float * p, float * div ) { int i, j; FOR_EACH_CELL div[IX(i,j)] = -0.5f*(u[IX(i+1,j)]-u[IX(i-1,j)]+v[IX(i,j+1)]-v[IX(i,j-1)])/N; p[IX(i,j)] = 0; END_FOR set_bnd ( N, 0, div ); set_bnd ( N, 0, p ); lin_solve ( N, 0, p, div, 1, 4 ); FOR_EACH_CELL u[IX(i,j)] -= 0.5f*N*(p[IX(i+1,j)]-p[IX(i-1,j)]); v[IX(i,j)] -= 0.5f*N*(p[IX(i,j+1)]-p[IX(i,j-1)]); END_FOR set_bnd ( N, 1, u ); set_bnd ( N, 2, v ); }
void Fluid::project(void) { float* p = u0; float* div = v0; // temporary buffers, use old velocity buffers int i, j, k, l; float h; h = 1.0f/N; for (k=1; k<=N; k++) { for (j=1; j<=N; j++) { for (i=1; i<=N; i++) { div[_I(i,j,k)] = -h*( u[_I(i+1,j,k)]-u[_I(i-1,j,k)]+ v[_I(i,j+1,k)]-v[_I(i,j-1,k)]+ w[_I(i,j,k+1)]-w[_I(i,j,k-1)])/3; p[_I(i,j,k)] = 0; } } } set_bnd(0,div); set_bnd(0,p); for (l=0; l<20; l++) { for (k=1; k<=N; k++) { for (j=1; j<=N; j++) { for (i=1; i<=N; i++) { p[_I(i,j,k)] = (div[_I(i,j,k)]+ p[_I(i-1,j,k)]+p[_I(i+1,j,k)]+ p[_I(i,j-1,k)]+p[_I(i,j+1,k)]+ p[_I(i,j,k-1)]+p[_I(i,j,k+1)])/6; } } } set_bnd(0,p); } for (k=1; k<=N; k++) { for (j=1; j<=N; j++) { for (i=1; i<=N; i++) { u[_I(i,j,k)] -= (p[_I(i+1,j,k)]-p[_I(i-1,j,k)])/3/h; v[_I(i,j,k)] -= (p[_I(i,j+1,k)]-p[_I(i,j-1,k)])/3/h; w[_I(i,j,k)] -= (p[_I(i,j,k+1)]-p[_I(i,j,k-1)])/3/h; } } } set_bnd(1,u); set_bnd(2,v); }
void project(int width, int height, float *u, float *v, float *p, float *div) { float w = 1.0f/width; float h = 1.0f/height; for (int row = 1; row <= height; ++row) { for (int col = 1; col <= width; ++col) { div[IX(row, col)] = -0.5*(w*(u[IX(row+1, col)] - u[IX(row-1, col)]) + h*(v[IX(row, col+1)] - v[IX(row, col-1)])); p[IX(row, col)] = 0; } } set_bnd(width, height, 0, div); set_bnd(width, height, 0, p); for (int count = 0; count < 20; ++count) { for (int row = 1; row <= height; ++row) { for (int col = 1; col <= width; ++col) { p[IX(row, col)] = (div[IX(row, col)] + p[IX(row-1, col)] + p[IX(row+1, col)] + p[IX(row, col-1)] + p[IX(row, col+1)])/4; } } set_bnd(width, height, 0, p); } for (int row = 1; row <= height; ++row) { for (int col = 1; col <= width; ++col) { v[IX(row, col)] -= 0.5f*(p[IX(row+1, col)] - p[IX(row-1, col)])/w; v[IX(row, col)] -= 0.5f*(p[IX(row, col+1)] - p[IX(row, col-1)])/h; } } set_bnd(width, height, 1, u); set_bnd(width, height, 2, v); }
void lin_solve ( int N, int b, float * x, float * x0, float a, float c ) { int i, j, k; for ( k=0 ; k<20 ; k++ ) { FOR_EACH_CELL x[IX(i,j)] = (x0[IX(i,j)] + a*(x[IX(i-1,j)]+x[IX(i+1,j)]+x[IX(i,j-1)]+x[IX(i,j+1)]))/c; END_FOR set_bnd ( N, b, x ); } }
// update density or velocity map for diffusion // b : boundary width // x : current density map // x0 : previous density map // diff : diffusion coef // dt : elapsed time void diffuse( int b, float *x, float *x0, float diff, float dt) { float a = diff*dt*N*N; for (int k=0; k < 20; k++) { for ( int i=1; i <= N; i++ ) { for (int j=1; j<= N; j++) { x[IX(i,j)] = (x0[IX(i,j)] + a*(x[IX(i-1,j)]+x[IX(i+1,j)] +x[IX(i,j-1)]+x[IX(i,j+1)]))/(1+4*a); } } set_bnd(b,x); } }
// update density or velocity map for diffusion // b : boundary width // x : current density map // x0 : previous density map // diff : diffusion coef // dt : elapsed time void diffuse(gaszone_type *gz, int b, float *x, float *x0, float diff, float dt) { float a = diff*dt*gz->n*gz->n; int i, j, k; for (k=0; k < 20; k++) { for (i=1; i <= gz->n; i++ ) { for (j=1; j<= gz->n; j++) { x[IX(i,j)] = (x0[IX(i,j)] + a*(x[IX(i-1,j)]+x[IX(i+1,j)] +x[IX(i,j-1)]+x[IX(i,j+1)]))/(1+4*a); } } set_bnd(gz, b,x); } }
void diffuse(int width, int height, int b, float *x, float *x0, float diff, float dt) { float a = dt*diff*width*height; for (int count = 0; count < 20; ++count) { for (int row = 1; row <= height; ++row) { for (int col = 1; col <= width; ++col) { x[IX(row, col)] = (x0[IX(row, col)] + a*(x[IX(row-1, col)] + x[IX(row+1, col)] + x[IX(row, col-1)] + x[IX(row, col+1)]))/(1+4*a); } } } set_bnd(width, height, b, x); }
inline void Fluid::diffuse(int b, float* x0, float* x, float diff, float dt) { int i, j, k, l; float a=dt*diff*N*N*N; for (l=0; l<20; l++) { for (k=1; k<=N; k++) { for (j=1; j<=N; j++) { for (i=1; i<=N; i++) { x[_I(i,j,k)] = (x0[_I(i,j,k)] + a*( x[_I(i-1,j,k)]+x[_I(i+1,j,k)]+ x[_I(i,j-1,k)]+x[_I(i,j+1,k)]+ x[_I(i,j,k-1)]+x[_I(i,j,k+1)]))/(1+6*a); } } } set_bnd(b,x); } }
/////////////////////////////////////////////////////////////////////////////// /// Calcuate coefficients for difussion equation solver /// ///\param para Pointer to FFD parameters ///\param var Pointer to FFD simulation variables ///\param psi Pointer to the variable at current time step ///\param psi0 Pointer to the variable at previous time step ///\param var_type Type of variable ///\param index Index of trace substance or species ///\param BINDEX Pointer to boundary index /// ///\return 0 if no error occurred /////////////////////////////////////////////////////////////////////////////// int coef_diff(PARA_DATA *para, REAL **var, REAL *psi, REAL *psi0, int var_type, int index, int **BINDEX) { int i, j, k; int imax = para->geom->imax, jmax = para->geom->jmax; int kmax = para->geom->kmax; int IMAX = imax+2, IJMAX = (imax+2)*(jmax+2); REAL *aw = var[AW], *ae = var[AE], *as = var[AS], *an = var[AN]; REAL *af = var[AF], *ab = var[AB], *ap = var[AP], *ap0 = var[AP0], *b = var[B]; REAL *x = var[X], *y = var[Y], *z = var[Z]; REAL *gx = var[GX], *gy = var[GY], *gz = var[GZ]; REAL *pp = var[PP]; REAL *Temp = var[TEMP]; REAL dxe, dxw, dyn, dys, dzf, dzb, Dx, Dy, Dz; REAL dt = para->mytime->dt, beta = para->prob->beta; REAL Temp_Buoyancy = para->prob->Temp_Buoyancy; REAL gravx = para->prob->gravx, gravy = para->prob->gravy, gravz = para->prob->gravz; REAL kapa; // define kapa switch(var_type) { /*------------------------------------------------------------------------- | X-velocity -------------------------------------------------------------------------*/ case VX: if(para->prob->tur_model==LAM) kapa = para->prob->nu; else if(para->prob->tur_model==CONSTANT) kapa = 101.0f * para->prob->nu; FOR_U_CELL dxe = gx[IX(i+1,j ,k)] - gx[IX(i ,j,k)]; dxw = gx[IX(i ,j ,k)] - gx[IX(i-1,j,k)]; dyn = y[IX(i ,j+1,k)] - y[IX(i ,j,k)]; dys = y[IX(i,j,k)] - y[IX(i,j-1,k)]; dzf = z[IX(i,j,k+1)] - z[IX(i,j,k)]; dzb = z[IX(i,j,k)] - z[IX(i,j,k-1)]; Dx = x[IX(i+1,j,k)] - x[IX(i,j,k)]; Dy = gy[IX(i,j,k)] - gy[IX(i,j-1,k)]; Dz = gz[IX(i,j,k)] - gz[IX(i,j,k-1)]; if(para->prob->tur_model==CHEN) kapa = nu_t_chen_zero_equ(para, var, i, j, k); aw[IX(i,j,k)] = kapa*Dy*Dz/dxw; ae[IX(i,j,k)] = kapa*Dy*Dz/dxe; an[IX(i,j,k)] = kapa*Dx*Dz/dyn; as[IX(i,j,k)] = kapa*Dx*Dz/dys; af[IX(i,j,k)] = kapa*Dx*Dy/dzf; ab[IX(i,j,k)] = kapa*Dx*Dy/dzb; ap0[IX(i,j,k)] = Dx*Dy*Dz/dt; b[IX(i,j,k)] = psi0[IX(i,j,k)]*ap0[IX(i,j,k)] - beta*gravx*(Temp[IX(i,j,k)]-Temp_Buoyancy)*Dx*Dy*Dz + (pp[IX(i,j,k)]-pp[IX(i+1,j,k)])*Dy*Dz; END_FOR //set_bnd(para, var, var_type, psi, BINDEX); FOR_U_CELL ap[IX(i,j,k)] = ap0[IX(i,j,k)] + ae[IX(i,j,k)] + aw[IX(i,j,k)] + an[IX(i,j,k)] + as[IX(i,j,k)] + af[IX(i,j,k)] + ab[IX(i,j,k)]; END_FOR break; /*------------------------------------------------------------------------- | Y-velocity -------------------------------------------------------------------------*/ case VY: if(para->prob->tur_model==LAM) kapa = para->prob->nu; else if(para->prob->tur_model==CONSTANT) kapa = (REAL) 101.0 * para->prob->nu; FOR_V_CELL dxe = x[IX(i+1,j,k)] - x[IX(i,j,k)]; dxw = x[IX(i,j,k)] - x[IX(i-1,j,k)]; dyn = gy[IX(i,j+1,k)] - gy[IX(i,j,k)]; dys = gy[IX(i,j,k)] - gy[IX(i,j-1,k)]; dzf = z[IX(i,j,k+1)] - z[IX(i,j,k)]; dzb = z[IX(i,j,k)] - z[IX(i,j,k-1)]; Dx = gx[IX(i,j,k)] - gx[IX(i-1,j,k)]; Dy = y[IX(i,j+1,k)] - y[IX(i,j,k)]; Dz = gz[IX(i,j,k)] - gz[IX(i,j,k-1)]; if(para->prob->tur_model==CHEN) kapa = nu_t_chen_zero_equ(para, var, i, j, k); aw[IX(i,j,k)] = kapa*Dy*Dz/dxw; ae[IX(i,j,k)] = kapa*Dy*Dz/dxe; an[IX(i,j,k)] = kapa*Dx*Dz/dyn; as[IX(i,j,k)] = kapa*Dx*Dz/dys; af[IX(i,j,k)] = kapa*Dx*Dy/dzf; ab[IX(i,j,k)] = kapa*Dx*Dy/dzb; ap0[IX(i,j,k)] = Dx*Dy*Dz/dt; b[IX(i,j,k)] = psi0[IX(i,j,k)]*ap0[IX(i,j,k)] - beta*gravy*(Temp[IX(i,j,k)]-Temp_Buoyancy)*Dx*Dy*Dz + (pp[IX(i,j,k)]-pp[IX(i ,j+1,k)])*Dx*Dz; END_FOR //set_bnd(para, var, var_type, psi,BINDEX); FOR_V_CELL ap[IX(i,j,k)] = ap0[IX(i,j,k)] + ae[IX(i,j,k)] + aw[IX(i,j,k)] + an[IX(i,j,k)] + as[IX(i,j,k)] + af[IX(i,j,k)] + ab[IX(i,j,k)]; END_FOR break; /*------------------------------------------------------------------------- | Z-velocity -------------------------------------------------------------------------*/ case VZ: if(para->prob->tur_model==LAM) kapa = para->prob->nu; else if(para->prob->tur_model==CONSTANT) kapa = (REAL) 101.0 * para->prob->nu; FOR_W_CELL dxe = x[IX(i+1,j,k)] - x[IX(i,j,k)]; dxw = x[IX(i,j,k)] - x[IX(i-1,j,k)]; dyn = y[IX(i,j+1,k)] - y[IX(i,j,k)]; dys = y[IX(i,j,k)] - y[IX(i,j-1,k)]; dzf = gz[IX(i,j,k+1)] - gz[IX(i,j,k)]; dzb = gz[IX(i,j,k)] - gz[IX(i,j,k-1)]; Dx = gx[IX(i,j,k)] - gx[IX(i-1,j,k)]; Dy = gy[IX(i,j,k)] - gy[IX(i,j-1,k)]; Dz = z[IX(i,j,k+1)] - z[IX(i,j,k)]; if(para->prob->tur_model==CHEN) kapa = nu_t_chen_zero_equ(para, var, i, j, k); aw[IX(i,j,k)] = kapa*Dy*Dz/dxw; ae[IX(i,j,k)] = kapa*Dy*Dz/dxe; an[IX(i,j,k)] = kapa*Dx*Dz/dyn; as[IX(i,j,k)] = kapa*Dx*Dz/dys; af[IX(i,j,k)] = kapa*Dx*Dy/dzf; ab[IX(i,j,k)] = kapa*Dx*Dy/dzb; ap0[IX(i,j,k)] = Dx*Dy*Dz/dt; b[IX(i,j,k)] = psi0[IX(i,j,k)]*ap0[IX(i,j,k)] - beta*gravz*(Temp[IX(i,j,k)]-Temp_Buoyancy)*Dx*Dy*Dz + (pp[IX(i,j,k)]-pp[IX(i ,j,k+1)])*Dy*Dx; END_FOR //set_bnd(para, var, var_type, psi, BINDEX); FOR_W_CELL ap[IX(i,j,k)] = ap0[IX(i,j,k)] + ae[IX(i,j,k)] + aw[IX(i,j,k)] + an[IX(i,j,k)] + as[IX(i,j,k)] + af[IX(i,j,k)] + ab[IX(i,j,k)]; END_FOR break; /*------------------------------------------------------------------------- | Scalar Variable -------------------------------------------------------------------------*/ case TEMP: case TRACE: if(para->prob->tur_model == LAM) kapa = para->prob->alpha; else if(para->prob->tur_model == CONSTANT) kapa = (REAL) 101.0 * para->prob->alpha; FOR_EACH_CELL dxe = x[IX(i+1,j,k)] - x[IX(i,j,k)]; dxw = x[IX(i,j,k)] - x[IX(i-1,j,k)]; dyn = y[IX(i,j+1,k)] - y[IX(i,j,k)]; dys = y[IX(i,j,k)] - y[IX(i,j-1,k)]; dzf = z[IX(i,j,k+1)] - z[IX(i,j,k)]; dzb = z[IX(i,j,k)] - z[IX(i,j,k-1)]; Dx = gx[IX(i,j,k)] - gx[IX(i-1,j,k)]; Dy = gy[IX(i,j,k)] - gy[IX(i,j-1,k)]; Dz = gz[IX(i,j,k)] - gz[IX(i,j,k-1)]; aw[IX(i,j,k)] = kapa*Dy*Dz/dxw; ae[IX(i,j,k)] = kapa*Dy*Dz/dxe; an[IX(i,j,k)] = kapa*Dx*Dz/dyn; as[IX(i,j,k)] = kapa*Dx*Dz/dys; af[IX(i,j,k)] = kapa*Dx*Dy/dzf; ab[IX(i,j,k)] = kapa*Dx*Dy/dzb; ap0[IX(i,j,k)] = Dx*Dy*Dz/dt; b[IX(i,j,k)] = psi0[IX(i,j,k)]*ap0[IX(i,j,k)]; END_FOR set_bnd(para, var, var_type, index, psi, BINDEX); FOR_EACH_CELL ap[IX(i,j,k)] = ap0[IX(i,j,k)] + ae[IX(i,j,k)] + aw[IX(i,j,k)] + an[IX(i,j,k)] + as[IX(i,j,k)] + af[IX(i,j,k)] + ab[IX(i,j,k)]; END_FOR break; default: sprintf(msg, "coe_diff(): No function for variable type %d", var_type); ffd_log(msg, FFD_ERROR); return 1; break; } return 0; }// End of coef_diff( )
/****************************************************************************** | advection ******************************************************************************/ void advection(PARA_DATA *para, REAL **var, int var_type, REAL *d, REAL *d0) { int i, j, k, p, q, r; int imax = para->geom->imax, jmax = para->geom->jmax; int kmax = para->geom->kmax; int IMAX = imax+2, IJMAX = (imax+2)*(jmax+2); int LOCATION; REAL x0, y0, z0, x_1, y_1,z_1; REAL dt = para->mytime->dt; REAL u0, v0, w0, x_min, x_max, y_min, y_max, z_min, z_max; REAL *x = var[X], *y = var[Y], *z = var[Z]; REAL *gx = var[GX], *gy = var[GY], *gz = var[GZ]; REAL *u = var[VX], *v = var[VY], *w = var[VZ]; REAL *flagp = var[FLAGP],*flagu = var[FLAGU],*flagv = var[FLAGV],*flagw = var[FLAGW]; int k1 = para->geom->k1, k2 = para->geom->k2, k3 = para->geom->k3; int i1 = para->geom->i1, i2 = para->geom->i2; int j1 = para->geom->j1, j2 = para->geom->j2; REAL z1 = para->geom->z1, z2 = para->geom->z2 ,z3 = para->geom->z3; REAL x1 = para->geom->x1, x2 = para->geom->x2; REAL y1 = para->geom->y1, y2 = para->geom->y2; REAL Lx = para->geom->Lx, Ly = para->geom->Ly, Lz = para->geom->Lz; switch (var_type) { case VX: { /*--------------------------------------------------------------------------- | Tracing Back and Interplotaing ---------------------------------------------------------------------------*/ FOR_U_CELL if (i>=i1 && i<=i2 && j>j1 && j<=j2 && k<=k2) continue; /*------------------------------------------------------------------------- | Step 1: Tracing Back -------------------------------------------------------------------------*/ u0 = u[IX(i,j,k)]; v0 = 0.5f *((v[IX(i, j,k)]+ v[IX(i, j-1,k)])*( x[IX(i+1,j,k)]-gx[IX(i,j,k)]) +(v[IX(i+1,j,k)]+ v[IX(i+1,j-1,k)])*(gx[IX(i, j,k)]- x[IX(i,j,k)])) /(x[IX(i+1,j,k)]-x[IX(i,j,k)]); w0 = 0.5f *((w[IX(i, j,k)]+ w[IX(i ,j, k-1)])*( x[IX(i+1,j,k)]-gx[IX(i,j,k)]) +(w[IX(i+1,j,k)]+ w[IX(i+1,j, k-1)])*(gx[IX(i, j,k)]- x[IX(i,j,k)]))/(x[IX(i+1,j,k)]-x[IX(i,j,k)]); x0 =gx[IX(i,j,k)] - u0*dt; y0 = y[IX(i,j,k)] - v0*dt; z0 = z[IX(i,j,k)] - w0*dt; p = i; q = j; r = k; if(u0>0) { while(x0<gx[IX(p,q,r)] && flagu[IX(p,q,r)]<0) p -=1; if(flagu[IX(p,q,r)]>0 && x0< gx[IX(p,q,r)]) x0=gx[IX(p,q,r)]; } else { while(x0>gx[IX(p+1,q,r)] && flagu[IX(p+1,q,r)]<0) p +=1; if(flagu[IX(p+1,q,r)]>0 && x0>gx[IX(p+1,q,r)]) x0=gx[IX(p+1,q,r)]; } if(v0>0) { while(y0<y[IX(p,q,r)] && flagu[IX(p,q,r)]<0) q -=1; if(y0<y[IX(p,q,r)] && flagu[IX(p,q,r)]>0) y0=y[IX(p,q+1,r)]; } else { while(y0>y[IX(p,q+1,r)] && flagu[IX(p,q+1,r)]<0) q +=1; if(y0>y[IX(p,q+1,r)] && flagu[IX(p,q+1,r)]>0) y0=y[IX(p,q,r)]; } if(w0>0) { while(z0<z[IX(p,q,r)] && flagu[IX(p,q,r)]<0) r -=1; if(z0<z[IX(p,q,r)] && flagu[IX(p,q,r)]>0) z0=z[IX(p,q,r+1)]; } else { while(z0>z[IX(p,q,r+1)] && flagu[IX(p,q,r+1)]<0) r +=1; if(z0>z[IX(p,q,r+1)] && flagu[IX(p,q,r+1)]>0) z0=z[IX(p,q,r)]; } x_1 = (x0-gx[IX(p,q,r)]) /(gx[IX(p+1, q ,r )]-gx[IX(p,q,r)]); y_1 = (y0- y[IX(p,q,r)]) /(y [IX(p, q+1, r )]- y[IX(p,q,r)]); z_1 = (z0- z[IX(p,q,r)]) /(z [IX(p, q, r+1)]- z[IX(p,q,r)]); /*------------------------------------------------------------------------- | Interpolating for all variables -------------------------------------------------------------------------*/ d[IX(i,j,k)] = interpolation(para, d0, x_1, y_1, z_1, p, q, r); END_FOR /*--------------------------------------------------------------------------- | define the b.c. ---------------------------------------------------------------------------*/ set_bnd(para, var, var_type, d); } break; case VY: { /*--------------------------------------------------------------------------- | Tracing Back and Interplotaing ---------------------------------------------------------------------------*/ FOR_V_CELL if (i>i1 && i<=i2 && j>=j1 && j<=j2 && k<=k2) continue; /*------------------------------------------------------------------------- | Step 1: Tracing Back -------------------------------------------------------------------------*/ u0 = 0.5f* ((u[IX(i,j,k)] + u[IX(i-1,j, k)]) *(y [IX(i,j+1,k)]-gy[IX(i,j,k)]) +(u[IX(i,j+1,k)] + u[IX(i-1,j+1,k)]) *(gy[IX(i,j, k)]-y[IX(i,j,k)]))/(y[IX(i,j+1,k)]-y[IX(i,j,k)]); v0 = v[IX(i,j,k)]; w0 = 0.5f *((w[IX(i,j, k)]+ w[IX(i,j ,k-1)])* (y [IX(i,j+1,k)]- gy[IX(i,j,k)]) +(w[IX(i,j+1,k)]+ w[IX(i,j+1,k-1)])* (gy[IX(i,j, k)]- y [IX(i,j,k)]))/(y[IX(i,j+1,k)]-y[IX(i,j,k)]); x0 = x[IX(i,j,k)] - u0*dt; y0 = gy[IX(i,j,k)] - v0*dt; z0 = z[IX(i,j,k)] - w0*dt; p = i; q = j; r = k; if(u0>0) { while(x0<x[IX(p,q,r)] && flagv[IX(p,q,r)]<0) p -=1; if(flagv[IX(p,q,r)]>0 && x0< x[IX(p,q,r)]) x0=x[IX(p+1,q,r)]; } else { while(x0>x[IX(p+1,q,r)] && flagv[IX(p+1,q,r)]<0) p +=1; if(flagv[IX(p+1,q,r)]>0 && x0>x[IX(p+1,q,r)]) x0=x[IX(p,q,r)]; } if(v0>0) { while(y0<gy[IX(p,q,r)] && flagv[IX(p,q,r)]<0) q -=1; if(y0<gy[IX(p,q,r)] && flagv[IX(p,q,r)]>0) y0=gy[IX(p,q,r)]; } else { while(y0>gy[IX(p,q+1,r)] && flagv[IX(p,q+1,r)]<0) q +=1; if(y0>gy[IX(p,q+1,r)] && flagv[IX(p,q+1,r)]>0) y0=gy[IX(p,q+1,r)]; } if(w0>0) { while(z0<z[IX(p,q,r)] && flagv[IX(p,q,r)]<0) r -=1; if(z0<z[IX(p,q,r)] && flagv[IX(p,q,r)]>0) z0=z[IX(p,q,r+1)]; } else { while(z0>z[IX(p,q,r+1)] && flagv[IX(p,q,r+1)]<0) r +=1; if(z0>z[IX(p,q,r+1)] && flagv[IX(p,q,r+1)]>0) z0=z[IX(p,q,r)]; } x_1 = (x0- x[IX(p,q,r)])/(x [IX(p+1,q, r)]-x [IX(p,q,r)]); y_1 = (y0-gy[IX(p,q,r)])/(gy[IX(p, q+1, r)]-gy[IX(p,q,r)]); z_1 = (z0- z[IX(p,q,r)])/(z [IX(p, q, r+1)]-z [IX(p,q,r)]); /*------------------------------------------------------------------------- | Interpolating for all variables -------------------------------------------------------------------------*/ d[IX(i,j,k)] = interpolation(para, d0, x_1, y_1, z_1, p, q, r); END_FOR /*--------------------------------------------------------------------------- | define the b.c. ---------------------------------------------------------------------------*/ set_bnd(para, var, var_type, d); } break; case VZ: { /*--------------------------------------------------------------------------- | Tracing Back and Interplotaing ---------------------------------------------------------------------------*/ FOR_W_CELL if (i>i1 && i<=i2 && j>j1 && j<=j2 && k<=k2) continue; /*------------------------------------------------------------------------- | Step 1: Tracing Back -------------------------------------------------------------------------*/ u0 = 0.5f*((u[IX(i,j,k )] + u[IX(i-1,j,k )])*(z [IX(i,j,k+1)]-gz[IX(i,j,k)]) +(u[IX(i,j,k+1)] + u[IX(i-1,j,k+1)])*(gz[IX(i,j,k )]- z[IX(i,j,k)]))/(z[IX(i,j,k+1)]-z[IX(i,j,k)]); v0 = 0.5f*((v[IX(i,j,k )] + v[IX(i,j-1,k )])*(z [IX(i,j,k+1)]-gz[IX(i,j,k)]) +(v[IX(i,j,k+1)] + v[IX(i,j-1,k+1)])*(gz[IX(i,j,k )]-z [IX(i,j,k)]))/(z[IX(i,j,k+1)]-z[IX(i,j,k)]); w0 = w[IX(i,j,k)]; x0 = x[IX(i,j,k)] - u0*dt; y0 = y[IX(i,j,k)] - v0*dt; z0 = gz[IX(i,j,k)] - w0*dt; p = i; q = j; r = k; if(u0>0) { while(x0<x[IX(p,q,r)] && flagw[IX(p,q,r)]<0) p -=1; if(flagw[IX(p,q,r)]>0 && x0< x[IX(p,q,r)]) x0=x[IX(p+1,q,r)]; } else { while(x0>x[IX(p+1,q,r)] && flagw[IX(p+1,q,r)]<0) p +=1; if(flagw[IX(p+1,q,r)]>0 && x0>x[IX(p+1,q,r)]) x0=x[IX(p,q,r)]; } if(v0>0) { while(y0<y[IX(p,q,r)] && flagw[IX(p,q,r)]<0) q -=1; if(y0<y[IX(p,q,r)] && flagw[IX(p,q,r)]>0) y0=y[IX(p,q+1,r)]; } else { while(y0>y[IX(p,q+1,r)] && flagw[IX(p,q+1,r)]<0) q +=1; if(y0>y[IX(p,q+1,r)] && flagw[IX(p,q+1,r)]>0) y0=y[IX(p,q,r)]; } if(w0>0) { while(z0<gz[IX(p,q,r)] && flagw[IX(p,q,r)]<0) r -=1; if(z0<gz[IX(p,q,r)] && flagw[IX(p,q,r)]>0) z0=gz[IX(p,q,r)]; } else { while(z0>gz[IX(p,q,r+1)] && flagw[IX(p,q,r+1)]<0) r +=1; if(z0>gz[IX(p,q,r+1)] && flagw[IX(p,q,r+1)]>0) z0=gz[IX(p,q,r+1)]; } x_1 = (x0- x[IX(p,q,r)])/( x[IX(p+1,q, r )]- x[IX(p,q,r)]); y_1 = (y0- y[IX(p,q,r)])/( y[IX(p, q+1, r )]- y[IX(p,q,r)]); z_1 = (z0-gz[IX(p,q,r)])/(gz[IX(p, q, r+1)]-gz[IX(p,q,r)]); /*------------------------------------------------------------------------- | Interpolating for all variables -------------------------------------------------------------------------*/ d[IX(i,j,k)] = interpolation(para, d0, x_1, y_1, z_1, p, q, r); END_FOR /*--------------------------------------------------------------------------- | define the b.c. ---------------------------------------------------------------------------*/ set_bnd(para, var, var_type, d); } break; } } // End of semi_Lagrangian( )
/****************************************************************************** Trace the VX ******************************************************************************/ int trace_vx(PARA_DATA *para, REAL **var, int var_type, REAL *d, REAL *d0, int **BINDEX) { int i, j, k; int it; int itmax = 20000; // Max number of iterations for backward tracing int imax = para->geom->imax, jmax = para->geom->jmax; int kmax = para->geom->kmax; int IMAX = imax+2, IJMAX = (imax+2)*(jmax+2); REAL x_1, y_1, z_1; REAL dt = para->mytime->dt; REAL u0, v0, w0; REAL *x = var[X], *y = var[Y], *z = var[Z]; REAL *gx = var[GX], *gy = var[GY], *gz = var[GZ]; REAL *u = var[VX], *v = var[VY], *w = var[VZ]; REAL *flagu = var[FLAGU]; REAL Lx = para->geom->Lx, Ly = para->geom->Ly, Lz = para->geom->Lz; int COOD[3], LOC[3]; REAL OL[3]; int OC[3]; FOR_U_CELL if(flagu[IX(i,j,k)]>=0) continue; /*----------------------------------------------------------------------- | Step 1: Tracing Back -----------------------------------------------------------------------*/ // Get velocities at the location of VX u0 = u[IX(i,j,k)]; v0 = 0.5 * ((v[IX(i, j,k)]+v[IX(i, j-1,k)])*( x[IX(i+1,j,k)]-gx[IX(i,j,k)]) +(v[IX(i+1,j,k)]+v[IX(i+1,j-1,k)])*(gx[IX(i, j,k)]- x[IX(i,j,k)])) / (x[IX(i+1,j,k)]-x[IX(i,j,k)]); w0 = 0.5 * ((w[IX(i, j,k)]+w[IX(i ,j, k-1)])*( x[IX(i+1,j,k)]-gx[IX(i,j,k)]) +(w[IX(i+1,j,k)]+w[IX(i+1,j, k-1)])*(gx[IX(i, j,k)]- x[IX(i,j,k)])) / (x[IX(i+1,j,k)]-x[IX(i,j,k)]); // Find the location at previous time step OL[X] =gx[IX(i,j,k)] - u0*dt; OL[Y] = y[IX(i,j,k)] - v0*dt; OL[Z] = z[IX(i,j,k)] - w0*dt; // Initialize the coordinates of previous step OC[X] = i; OC[Y] = j; OC[Z] = k; //OC is the trace back coodinates // Initialize the signs for track process // Completed: 0; In process: 1 COOD[X] = 1; COOD[Y] = 1; COOD[Z] = 1; // Initialize the signs for recording if the track back hits the boundary // Hit the boundary: 0; Not hit the boundary: 1 LOC[X] = 1; LOC[Y] = 1; LOC[Z] = 1; //Initialize the number of iterations it=1; // Trace back more if the any of the trace is still in process while(COOD[X]==1 || COOD[Y] ==1 || COOD[Z] ==1) { it++; // If trace in X is in process and donot hit the boundary if(COOD[X]==1 && LOC[X]==1) set_x_location(para, var, flagu, gx, u0, i, j, k, OL, OC, LOC, COOD); // If trace in Y is in process and donot hit the boundary if(COOD[Y]==1 && LOC[Y]==1) set_y_location(para, var, flagu, y, v0, i, j, k, OL, OC, LOC, COOD); // If trace in Z is in process and donot hit the boundary if(COOD[Z]==1 && LOC[Z]==1) set_z_location(para, var, flagu, z, w0, i, j, k, OL, OC, LOC, COOD); if(it>itmax) { printf("Error: advection.c, can not track the location for VX(%d, %d,%d)", i, j, k); printf("after %d iterations.\n", it); return 1; } } // End of while() for backward tracing // Set the coordinates of previous location if it is as boundary if(u0>0 && LOC[X]==0) OC[X] -=1; if(v0>0 && LOC[Y]==0) OC[Y] -=1; if(w0>0 && LOC[Z]==0) OC[Z] -=1; // Fixme: Do not understand here. Should it be // if(u0<0 && LOC[X] = 0) OC[X] += 1; if(u0<0 && LOC[X]==1) OC[X] -=1; if(v0<0 && LOC[Y]==1) OC[Y] -=1; if(w0<0 && LOC[Z]==1) OC[Z] -=1; /*------------------------------------------------------------------------- | Interpolate -------------------------------------------------------------------------*/ x_1 = (OL[X]-gx[IX(OC[X],OC[Y],OC[Z])]) / (gx[IX(OC[X]+1,OC[Y],OC[Z])]-gx[IX(OC[X],OC[Y],OC[Z])]); y_1 = (OL[Y]-y[IX(OC[X],OC[Y],OC[Z])]) / (y[IX(OC[X],OC[Y]+1,OC[Z])]-y[IX(OC[X],OC[Y],OC[Z])]); z_1 = (OL[Z]-z[IX(OC[X],OC[Y],OC[Z])]) / (z[IX(OC[X],OC[Y],OC[Z]+1)]-z[IX(OC[X],OC[Y],OC[Z])]); d[IX(i,j,k)] = interpolation(para, d0, x_1, y_1, z_1, OC[X], OC[Y], OC[Z]); END_FOR // End of loop for all cells /*--------------------------------------------------------------------------- | define the b.c. ---------------------------------------------------------------------------*/ set_bnd(para, var, var_type, d, BINDEX); return 0; } // End of trace_vx()