1 /*! @file NavierStokes2DUpwind_GPU.cu
3 @brief Contains functions to compute the upwind flux at grid interfaces for the 2D Navier Stokes equations.
6 #include <arrayfunctions_gpu.h>
9 #include <physicalmodels/navierstokes2d.h>
12 #ifdef CUDA_VAR_ORDERDING_AOS
14 /*! Kernel for gpuNavierStokes2DUpwindRusanov() */
16 void NavierStokes2DUpwindRusanov_kernel(
22 const double *grav_field_g,
31 int p = threadIdx.x + (blockDim.x * blockIdx.x);
32 if (p < ngrid_points) {
33 int bounds_inter[2], index_inter[2];
34 bounds_inter[0] = dim[0]; bounds_inter[1] = dim[1]; bounds_inter[dir] += 1;
35 _ArrayIndexnD_(_MODEL_NDIMS_,p,bounds_inter,index_inter,0);
36 int indexL[_MODEL_NDIMS_]; _ArrayCopy1D_(index_inter,indexL,_MODEL_NDIMS_); indexL[dir]--;
37 int indexR[_MODEL_NDIMS_]; _ArrayCopy1D_(index_inter,indexR,_MODEL_NDIMS_);
38 int pL; _ArrayIndex1D_(_MODEL_NDIMS_,dim,indexL,ghosts,pL);
39 int pR; _ArrayIndex1D_(_MODEL_NDIMS_,dim,indexR,ghosts,pR);
40 double udiff[_MODEL_NVARS_],uavg[_MODEL_NVARS_];
42 /* Modified Rusanov's upwinding scheme */
44 udiff[0] = 0.5 * (uR[_MODEL_NVARS_*p+0] - uL[_MODEL_NVARS_*p+0]);
45 udiff[1] = 0.5 * (uR[_MODEL_NVARS_*p+1] - uL[_MODEL_NVARS_*p+1]);
46 udiff[2] = 0.5 * (uR[_MODEL_NVARS_*p+2] - uL[_MODEL_NVARS_*p+2]);
47 udiff[3] = 0.5 * (uR[_MODEL_NVARS_*p+3] - uL[_MODEL_NVARS_*p+3]);
49 _NavierStokes2DRoeAverage_(uavg,(u+_MODEL_NVARS_*pL),(u+_MODEL_NVARS_*pR),gamma);
51 double c, vel[_MODEL_NDIMS_], rho,E,P;
52 _NavierStokes2DGetFlowVar_((u+_MODEL_NVARS_*pL),rho,vel[0],vel[1],E,P,gamma);
53 c = sqrt(gamma*P/rho);
54 double alphaL = c + absolute(vel[dir]);
55 _NavierStokes2DGetFlowVar_((u+_MODEL_NVARS_*pR),rho,vel[0],vel[1],E,P,gamma);
56 c = sqrt(gamma*P/rho);
57 double alphaR = c + absolute(vel[dir]);
58 _NavierStokes2DGetFlowVar_(uavg,rho,vel[0],vel[1],E,P,gamma);
59 c = sqrt(gamma*P/rho);
60 double alphaavg = c + absolute(vel[dir]);
62 double kappa = max(grav_field_g[pL],grav_field_g[pR]);
63 double alpha = kappa*max3(alphaL,alphaR,alphaavg);
65 fI[_MODEL_NVARS_*p+0] = 0.5*(fL[_MODEL_NVARS_*p+0]+fR[_MODEL_NVARS_*p+0])-alpha*udiff[0];
66 fI[_MODEL_NVARS_*p+1] = 0.5*(fL[_MODEL_NVARS_*p+1]+fR[_MODEL_NVARS_*p+1])-alpha*udiff[1];
67 fI[_MODEL_NVARS_*p+2] = 0.5*(fL[_MODEL_NVARS_*p+2]+fR[_MODEL_NVARS_*p+2])-alpha*udiff[2];
68 fI[_MODEL_NVARS_*p+3] = 0.5*(fL[_MODEL_NVARS_*p+3]+fR[_MODEL_NVARS_*p+3])-alpha*udiff[3];
73 /*! Rusanov's upwinding scheme.
75 {\bf f}_{j+1/2} = \frac{1}{2}\left[ {\bf f}_{j+1/2}^L + {\bf f}_{j+1/2}^R
76 - \max_{j,j+1} \nu_j \left( {\bf u}_{j+1/2}^R - {\bf u}_{j+1/2}^L \right)\right]
78 where \f$\nu = c + \left|u\right|\f$.
79 + Rusanov, V. V., "The calculation of the interaction of non-stationary shock waves and obstacles," USSR
80 Computational Mathematics and Mathematical Physics, Vol. 1, No. 2, 1962, pp. 304–320
82 This upwinding scheme is modified for the balanced discretization of the 2D Navier Stokes equations when
83 there is a non-zero gravitational force. See the reference below. For flows without any gravitational forces,
84 it reduces to its original form.
85 + Ghosh, D., Constantinescu, E.M., Well-Balanced Formulation of Gravitational Source
86 Terms for Conservative Finite-Difference Atmospheric Flow Solvers, AIAA Paper 2015-2889,
87 7th AIAA Atmospheric and Space Environments Conference, June 22-26, 2015, Dallas, TX,
88 http://dx.doi.org/10.2514/6.2015-2889
89 + Ghosh, D., Constantinescu, E.M., A Well-Balanced, Conservative Finite-Difference Algorithm
90 for Atmospheric Flows, AIAA Journal, http://dx.doi.org/10.2514/1.J054580.
93 extern "C" int gpuNavierStokes2DUpwindRusanov(
105 HyPar *solver = (HyPar *) s;
106 NavierStokes2D *param = (NavierStokes2D*) solver->physics;
107 int *dim = solver->dim_local;
110 bounds_outer[0] = dim[0]; bounds_outer[1] = dim[1]; bounds_outer[dir] = 1;
111 int N_outer; _ArrayProduct1D_(bounds_outer,_MODEL_NDIMS_,N_outer);
113 double cpu_time = 0.0;
114 clock_t cpu_start, cpu_end;
116 int ngrid_points = N_outer * (dim[dir]+1);
117 int nblocks = (ngrid_points - 1) / GPU_THREADS_PER_BLOCK + 1;
120 NavierStokes2DUpwindRusanov_kernel<<<nblocks, GPU_THREADS_PER_BLOCK>>>(
121 ngrid_points, dir, solver->ghosts, param->gamma, solver->dim_local,
122 param->gpu_grav_field_g, fL, fR, uL, uR, u, fI);
123 cudaDeviceSynchronize();
125 cpu_time += (double)(cpu_end - cpu_start) / CLOCKS_PER_SEC;