HyPar  1.0
Finite-Difference Hyperbolic-Parabolic PDE Solver on Cartesian Grids
NavierStokes2DUpwind_GPU.cu
Go to the documentation of this file.
1 /*! @file NavierStokes2DUpwind_GPU.cu
2  @author Youngdae Kim
3  @brief Contains functions to compute the upwind flux at grid interfaces for the 2D Navier Stokes equations.
4 */
5 #include <time.h>
6 #include <arrayfunctions_gpu.h>
7 #include <math_ops.h>
8 #include <basic_gpu.h>
9 #include <physicalmodels/navierstokes2d.h>
10 #include <hypar.h>
11 
12 #ifdef CUDA_VAR_ORDERDING_AOS
13 
14 /*! Kernel for gpuNavierStokes2DUpwindRusanov() */
15 __global__
16 void NavierStokes2DUpwindRusanov_kernel(
17  int ngrid_points,
18  int dir,
19  int ghosts,
20  double gamma,
21  const int *dim,
22  const double *grav_field_g,
23  const double *fL,
24  const double *fR,
25  const double *uL,
26  const double *uR,
27  const double *u,
28  double *fI
29 )
30 {
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_];
41 
42  /* Modified Rusanov's upwinding scheme */
43 
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]);
48 
49  _NavierStokes2DRoeAverage_(uavg,(u+_MODEL_NVARS_*pL),(u+_MODEL_NVARS_*pR),gamma);
50 
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]);
61 
62  double kappa = max(grav_field_g[pL],grav_field_g[pR]);
63  double alpha = kappa*max3(alphaL,alphaR,alphaavg);
64 
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];
69  }
70  return;
71 }
72 
73 /*! Rusanov's upwinding scheme.
74  \f{equation}{
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]
77  \f}
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
81 
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.
91 
92 */
93 extern "C" int gpuNavierStokes2DUpwindRusanov(
94  double *fI,
95  double *fL,
96  double *fR,
97  double *uL,
98  double *uR,
99  double *u,
100  int dir,
101  void *s,
102  double t
103 )
104 {
105  HyPar *solver = (HyPar *) s;
106  NavierStokes2D *param = (NavierStokes2D*) solver->physics;
107  int *dim = solver->dim_local;
108 
109  int bounds_outer[2];
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);
112 
113  double cpu_time = 0.0;
114  clock_t cpu_start, cpu_end;
115 
116  int ngrid_points = N_outer * (dim[dir]+1);
117  int nblocks = (ngrid_points - 1) / GPU_THREADS_PER_BLOCK + 1;
118 
119  cpu_start = clock();
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();
124  cpu_end = clock();
125  cpu_time += (double)(cpu_end - cpu_start) / CLOCKS_PER_SEC;
126 
127  return (0);
128 }
129 
130 #endif