cuIBM
A GPU-based Immersed Boundary Method code
NSWithBody.cu
Go to the documentation of this file.
1 
7 #include "NSWithBody.h"
9 
10 
15 template <typename memoryType>
17 {
18  printf("Initializing bodies ...\n");
19  NavierStokesSolver<memoryType>::logger.startTimer("initialiseBodies");
20 
23 
24  std::string folder = db["inputs"]["caseFolder"].get<std::string>();
25  std::stringstream out;
26  out << folder << "/forces";
27  int timeStep(db["simulation"]["startStep"].get<int>());
28  if (timeStep != 0)
29  {
30  forceFile.open(out.str().c_str(), std::ofstream::app);
31  }
32  else
33  {
34  forceFile.open(out.str().c_str());
35  }
36 
37  NavierStokesSolver<memoryType>::logger.stopTimer("initialiseBodies");
38 } // initialiseBodies
39 
40 
44 template <typename memoryType>
46 {
47  NavierStokesSolver<memoryType>::logger.startTimer("updateBodies");
48 
50  real dt = db["simulation"]["dt"].get<real>();
52  B.update(db, *NavierStokesSolver<memoryType>::domInfo, Time);
53 
54  NavierStokesSolver<memoryType>::logger.stopTimer("updateBodies");
55 } // updateBodies
56 
57 
67 template <>
69 {
70  int nx = domInfo->nx,
71  ny = domInfo->ny;
72 
73  real dt = (*paramDB)["simulation"]["dt"].get<real>(),
74  nu = (*paramDB)["flow"]["nu"].get<real>();
75 
76  real *q_r = thrust::raw_pointer_cast(&q[0]),
77  *qOld_r = thrust::raw_pointer_cast(&qOld[0]),
78  *lambda_r = thrust::raw_pointer_cast(&lambda[0]),
79  *dxD = thrust::raw_pointer_cast(&(domInfo->dxD[0])),
80  *dyD = thrust::raw_pointer_cast(&(domInfo->dyD[0]));
81 
82  // Calculating drag
83  cusp::array1d<real, device_memory>
84  FxX(B.numCellsY[0]),
85  FxY(B.numCellsX[0]+1),
86  FxU((B.numCellsX[0]+1)*B.numCellsY[0]);
87 
88  real *FxX_r = thrust::raw_pointer_cast(&FxX[0]),
89  *FxY_r = thrust::raw_pointer_cast(&FxY[0]),
90  *FxU_r = thrust::raw_pointer_cast(&FxU[0]);
91 
92  const int blockSize = 256;
93  dim3 dimGrid( int((B.numCellsX[0]+B.numCellsY[0]+1-0.5)/blockSize)+1, 1 );
94  dim3 dimBlock(blockSize, 1);
95 
96  kernels::dragLeftRight <<<dimGrid, dimBlock>>> (FxX_r, q_r, lambda_r, nu, dxD, dyD, \
97  nx, ny, B.startI[0], B.startJ[0], B.numCellsX[0], B.numCellsY[0]);
98 
99  kernels::dragBottomTop <<<dimGrid, dimBlock>>> (FxY_r, q_r, nu, dxD, dyD, \
100  nx, ny, B.startI[0], B.startJ[0], B.numCellsX[0], B.numCellsY[0]);
101 
102  dim3 dimGridX( int( ( (B.numCellsX[0]+1)*B.numCellsY[0]-0.5 )/blockSize )+1, 1 );
103  kernels::dragUnsteady <<<dimGridX, dimBlock>>> (FxU_r, q_r, qOld_r, dxD, dyD, dt, \
104  nx, ny, B.startI[0], B.startJ[0], B.numCellsX[0], B.numCellsY[0]);
105 
106  forceX = thrust::reduce(FxX.begin(), FxX.end()) + thrust::reduce(FxY.begin(), FxY.end()) + thrust::reduce(FxU.begin(), FxU.end());
107 
108  // Calculating lift
109  cusp::array1d<real, device_memory>
110  FyX(B.numCellsY[0]+1),
111  FyY(B.numCellsX[0]),
112  FyU((B.numCellsX[0]+1)*B.numCellsY[0]);
113 
114  real *FyX_r = thrust::raw_pointer_cast(&FyX[0]),
115  *FyY_r = thrust::raw_pointer_cast(&FyY[0]),
116  *FyU_r = thrust::raw_pointer_cast(&FyU[0]);
117 
118  kernels::liftLeftRight <<<dimGrid, dimBlock>>> (FyX_r, q_r, nu, dxD, dyD, \
119  nx, ny, B.startI[0], B.startJ[0], B.numCellsX[0], B.numCellsY[0]);
120 
121  kernels::liftBottomTop <<<dimGrid, dimBlock>>> (FyY_r, q_r, lambda_r, nu, dxD, dyD, \
122  nx, ny, B.startI[0], B.startJ[0], B.numCellsX[0], B.numCellsY[0]);
123 
124  dim3 dimGridY( int( ( B.numCellsX[0]*(B.numCellsY[0]+1)-0.5 )/blockSize )+1, 1 );
125  kernels::liftUnsteady <<<dimGridY, dimBlock>>> (FyU_r, q_r, qOld_r, dxD, dyD, dt, \
126  nx, ny, B.startI[0], B.startJ[0], B.numCellsX[0], B.numCellsY[0]);
127 
128  forceY = thrust::reduce(FyX.begin(), FyX.end()) + thrust::reduce(FyY.begin(), FyY.end()) + thrust::reduce(FyU.begin(), FyU.end());
129 } // calculateForce
130 
131 
135 template <typename memoryType>
137 {
138  NavierStokesSolver<memoryType>::logger.startTimer("output");
139 
141  std::string caseFolder = db["inputs"]["caseFolder"].get<std::string>();
142  int nsave = db["simulation"]["nsave"].get<int>();
144 
146 
147  // write the coordinates of the body points
148  if (timeStep % nsave == 0)
149  B.writeToFile(caseFolder, timeStep);
150 
151  NavierStokesSolver<memoryType>::logger.stopTimer("output");
152 } // writeCommon
153 
154 
158 template <typename memoryType>
160 {
162  forceFile.close();
164 } // shutDown
165 
166 
167 // specialization of the class
168 template class NSWithBody<device_memory>;
Declaration of the class NSWithBody.
void initialiseBodies()
Stores the parameters of the simulation and initializes the location and motion of each immersed bodi...
Definition: NSWithBody.cu:16
double real
Is a float or a double depending on the machine precision.
Definition: types.h:116
virtual void writeCommon()
Writes flow variables and position of body points into files.
Definition: NSWithBody.cu:136
Declaration of the kernels to calculate the forces acting on a body The method is described in Lai & ...
std::map< std::string, componentParameter > parameterDB
Map from a string to a componentParameter.
Definition: parameterDB.h:64
__global__ void forceY()
Kernel not usable.
void printTimingInfo(Logger &logger)
Prints the time spent to execute tasks.
Definition: io.cu:469
virtual void writeCommon()
Writes numerical solution at current time-step, as well as the number of iterations performed in each...
void updateBodies()
Updates location and motion of each immersed body at current time.
Definition: NSWithBody.cu:45
__global__ void forceX(real *f, real *q, real *rn, int *tags, int nx, int ny, real *dx, real *dy, real dt, real alpha, real nu)
Kernel not usable.
virtual void calculateForce()
Generic Navier-Stokes solver in the presence of immersed boundaries.
Definition: NSWithBody.h:21
Solves the Navier-Stokes equations in a rectangular domain.
virtual void shutDown()
Closes iteration file and force file.
Definition: NSWithBody.cu:159
virtual void initialise()
Initializes parameters, arrays and matrices required for the simulation.