cuIBM
A GPU-based Immersed Boundary Method code
tagPoints.inl
Go to the documentation of this file.
1 
12 template <>
14 {
15  logger.startTimer("tagPoints");
16 
17  // transferring boundary point coordinates to the host
18  vecH bxH(B.totalPoints), byH(B.totalPoints), uBH(B.totalPoints), vBH(B.totalPoints);
19  bxH = B.x;
20  byH = B.y;
21  uBH = B.uB;
22  vBH = B.vB;
23 
24  // creating raw pointers
25  real *bx = thrust::raw_pointer_cast(&(bxH[0])),
26  *by = thrust::raw_pointer_cast(&(byH[0])),
27  *uB = thrust::raw_pointer_cast(&(uBH[0])),
28  *vB = thrust::raw_pointer_cast(&(vBH[0]));
29 
30  //tagPoints(bx, by);
31  tagPoints(bx, by, uB, vB);
32 
33  // transferring tag and coeffs data to the device
34  tagsD = tags;
35  tags2D = tags2;
36  coeffsD = coeffs;
37  coeffs2D = coeffs2;
38  uvD = uv;
39 
40  logger.stopTimer("tagPoints");
41 } // tagPoints
42 
43 
44 // Bilinear Fadlun1c-type interpolation outside the body, for a moving body.
59 template <typename memoryType>
61 {
64 
65  real *xu = thrust::raw_pointer_cast(&(NavierStokesSolver<memoryType>::domInfo->xu[0])),
66  *yu = thrust::raw_pointer_cast(&(NavierStokesSolver<memoryType>::domInfo->yu[0]));
67 
69  std::string folder = db["inputs"]["caseFolder"].get<std::string>();
70  interpolationType interpType = db["simulation"]["interpolationType"].get<interpolationType>();
71 
72  int I;
73  int bottom, top, left, right;
74  real eps = 1.e-10;
75  bool outsideX, outsideY;
76  int bdryFlagX, bdryFlagY, bdryFlag2X, bdryFlag2Y;
77  real a, b;
78  real cfX, cfY, cf2X, cf2Y;
79  real etaX, etaY;
80  real uvX, uvY;
81  bool flag;
82  real x, y;
83  int k, l;
84  int totalPoints = NSWithBody<memoryType>::B.totalPoints;
85 
86  std::ofstream mask((folder+"/mask.txt").c_str());
87  std::ofstream eta((folder+"/eta_u.txt").c_str());
88 
89  // tag points at which u is evaluated
90  for(int j=0; j<ny; j++)
91  {
92  for(int i=0; i<nx-1; i++)
93  {
94  // index of the current point on the u-grid
95  I = j*(nx-1)+i;
96 
97  // tags and coefficients
98  tags[I] = -1;
99  tags2[I] = -1;
100  coeffs[I] = 0.0;
101  coeffs2[I] = 0.0;
102 
103  // initial indices of the points on the body that define the segment under consideration
104  k = totalPoints-1;
105  l = 0;
106 
107  outsideX = true;
108  outsideY = true;
109  bdryFlagX = -1; // stores if a point is near the boundary
110  bdryFlagY = -1;
111  bdryFlag2X = -1;
112  bdryFlag2Y = -1;
113  uvX = 0.0;
114  uvY = 0.0;
115  cfX = 0.0;
116  cfY = 0.0;
117  cf2X = 0.0;
118  cf2Y = 0.0;
119  flag = false;
120 
121  // cycle through all the segments on the body surface
122  while(l<totalPoints && !flag)
123  {
124  // figure out which of the two end points of the segment are at the bottom and the left
125  if (by[k] > by[l])
126  {
127  bottom = l;
128  top = k;
129  }
130  else
131  {
132  bottom = k;
133  top = l;
134  }
135  if (bx[k] > bx[l])
136  {
137  left = l;
138  right = k;
139  }
140  else
141  {
142  left = k;
143  right = l;
144  }
145 
146  // consider rays along the x-direction
147  // if the ray intersects the boundary segment (top endpoint must be strictly above the ray; bottom can be on or below the ray)
148  if (by[bottom]-eps < yu[j] && by[top]-eps > yu[j])
149  {
150  // if the segment is not parallel to the x-direction
151  if (fabs(by[l]-by[k]) > eps)
152  {
153  // calculate the point of intersection of the double ray with the boundary
154  x = bx[k] + (bx[l]-bx[k]) * (yu[j]-by[k])/(by[l]-by[k]);
155 
156  // calculate the body velocity at the point of intersection
157  uvX = uB[k] + (uB[l]-uB[k]) * (yu[j]-by[k])/(by[l]-by[k]);
158 
159  // if the point of intersection coincides with the grid point
160  if (fabs(x-xu[i]) < eps)
161  {
162  outsideX = true;
163  bdryFlagX = I;
164  bdryFlag2X= I;
165  etaX = 0.0;
166  cfX = 0.0;
167  cf2X = 0.0;
168  flag = true; // flag is true when the point of intersection coincides with the grid point
169  }
170  // if the point of intersection lies to the right of the grid point (right-facing ray intersects the boundary)
171  else if (x > xu[i]+eps)
172  outsideX = !outsideX;
173 
174  // if the point of intersection is in the cell to the immediate left of the grid point
175  if (x>xu[i-1]+eps && x<xu[i]-eps)
176  {
177  bdryFlagX = I+1;
178  bdryFlag2X = I+2;
179  a = xu[i]-x;
180  b = xu[i+1]-xu[i];
181  etaX = a/b;
182  switch(interpType)
183  {
184  case CONSTANT : cfX = 0.0; cf2X = 0.0; break;
185  case LINEAR : cfX = a/(a+b); cf2X = 0.0; break;
186  case QUADRATIC: cfX = 2*a/(a+b); cf2X = -a/(a+2*b); break;
187  default: cfX = a/(a+b); cf2X = 0.0; break;
188  }
189  }
190  // if the point of intersection is in the cell to the immediate right of the grid point
191  else if (x>xu[i]+eps && x<xu[i+1]-eps)
192  {
193  bdryFlagX = I-1;
194  bdryFlag2X = I-2;
195  a = x-xu[i];
196  b = xu[i]-xu[i-1];
197  etaX = a/b;
198  switch(interpType)
199  {
200  case CONSTANT : cfX = 0.0; cf2X = 0.0; break;
201  case LINEAR : cfX = a/(a+b); cf2X = 0.0; break;
202  case QUADRATIC: cfX = 2*a/(a+b); cf2X = -a/(a+2*b); break;
203  default: cfX = a/(a+b); cf2X = 0.0; break;
204  }
205  }
206  }
207  }
208  // consider rays along the y-direction
209  // if the ray intersects the boundary segment (right endpoint must be strictly to the right of ray; left can be on or to the left of the ray)
210  if ( (bx[left]-eps < xu[i]) && (bx[right]-eps > xu[i]) && ( !flag ) ) // no need to do this part if flag is false
211  {
212  // if the segment is not parallel to the y-direction
213  if (fabs(bx[l]-bx[k]) > eps)
214  {
215  // calculate the point of intersection of the double ray with the boundary
216  y = by[k] + (by[l]-by[k]) * (xu[i]-bx[k]) / (bx[l]-bx[k]);
217 
218  // calculate the body velocity at the point of intersection
219  uvY = uB[k] + (uB[l]-uB[k]) * (xu[i]-bx[k])/(bx[l]-bx[k]);
220 
221  // if the point of intersection coincides with the grid point
222  if (fabs(y-yu[j]) < eps)
223  {
224  outsideY = true; // then the point is considered to be outside the grid
225  bdryFlagY = I; // the point is considered to be a forcing point, with index I
226  bdryFlag2Y= I;
227  etaY = 0.0;
228  cfY = 0.0; // the coefficient for the linear interpolation during forcing
229  cf2Y = 0.0;
230  flag = true; // flag is true when the point of intersection coincides with the grid point
231  }
232  // if the point of intersection lies to the top of the grid point
233  else if (y > yu[j]+eps)
234  outsideY = !outsideY; // then flip if inside or outside (start with true, i.e. outside)
235 
236  // if point of intersection is just below the concerned grid point
237  if (y>yu[j-1]+eps && y<yu[j]-eps)
238  {
239  bdryFlagY = I+(nx-1);
240  bdryFlag2Y= I+2*(nx-1);
241  a = yu[j]-y;
242  b = yu[j+1]-yu[j];
243  etaY = a/b;
244  switch(interpType)
245  {
246  case CONSTANT : cfY = 0.0; cf2Y = 0.0; break;
247  case LINEAR : cfY = a/(a+b); cf2Y = 0.0; break;
248  case QUADRATIC: cfY = 2*a/(a+b); cf2Y = -a/(a+2*b); break;
249  default: cfY = a/(a+b); cf2Y = 0.0; break;
250  }
251  }
252  // if point of intersection is just above the concerned grid point
253  else if (y>yu[j]+eps && y<yu[j+1]-eps)
254  {
255  bdryFlagY = I-(nx-1);
256  bdryFlag2Y= I-2*(nx-1);
257  a = y-yu[j];
258  b = yu[j]-yu[j-1];
259  etaY = a/b;
260  switch(interpType)
261  {
262  case CONSTANT : cfY = 0.0; cf2Y = 0.0; break;
263  case LINEAR : cfY = a/(a+b); cf2Y = 0.0; break;
264  case QUADRATIC: cfY = 2*a/(a+b); cf2Y = -a/(a+2*b); break;
265  default: cfY = a/(a+b); cf2Y = 0.0; break;
266  }
267  }
268  }
269  }
270  k = l;
271  l = l+1;
272  }
273  if (outsideX && bdryFlagX>=0)
274  {
275  tags[I] = bdryFlagX;
276  tags2[I] = bdryFlag2X;
277  coeffs[I] = cfX;
278  coeffs2[I] = cf2X;
279  uv[I] = uvX;
280  eta << etaX << std::endl;
281  }
282  else if (outsideY && bdryFlagY>=0)
283  {
284  tags[I] = bdryFlagY;
285  tags2[I] = bdryFlag2Y;
286  coeffs[I] = cfY;
287  coeffs2[I] = cf2Y;
288  uv[I] = uvY;
289  eta << etaY << std::endl;
290  }
291  mask << ((outsideX || outsideY)? 1 : 0) << std::endl;
292  }
293  }
294  eta.close();
295 
296  std::ofstream file((folder+"/tagx.txt").c_str());
297  for(int j=0; j<ny; j++)
298  {
299  for(int i=0; i<nx-1; i++)
300  {
301  I = j*(nx-1)+i;
302  if (tags[I] >= 0)
303  {
304  file << xu[i] << '\t' << yu[j] << std::endl;
305  if (tags[I] == I-1)
306  file << xu[i-1] << '\t' << yu[j] << std::endl;
307  else if (tags[I] == I+1)
308  file << xu[i+1] << '\t' << yu[j] << std::endl;
309  else if (tags[I] == I-(nx-1))
310  file << xu[i] << '\t' << yu[j-1] << std::endl;
311  else if (tags[I] == I+(nx-1))
312  file << xu[i] << '\t' << yu[j+1] << std::endl;
313  file << std::endl;
314  }
315  }
316  }
317  file.close();
318 
319  eta.open((folder+"/eta_v.txt").c_str());
320 
321  real *xv = thrust::raw_pointer_cast(&(NavierStokesSolver<memoryType>::domInfo->xv[0])),
322  *yv = thrust::raw_pointer_cast(&(NavierStokesSolver<memoryType>::domInfo->yv[0]));
323 
324  // tag points at which v is evaluated
325  for(int j=0; j<ny-1; j++)
326  {
327  for(int i=0; i<nx; i++)
328  {
329  // index of the current point on the u-grid
330  I = j*nx+i + (nx-1)*ny;
331 
332  // tags and coefficients
333  tags[I] = -1;
334  coeffs[I] = 0.0;
335 
336  // initial indices of the points on the body that define the segment under consideration
337  k = totalPoints-1;
338  l = 0;
339 
340  outsideX = true;
341  outsideY = true;
342  bdryFlagX = -1;
343  bdryFlagY = -1;
344  uvX = 0.0;
345  uvY = 0.0;
346  cfX = 0.0;
347  cfY = 0.0;
348  flag = false;
349 
350  while(l<totalPoints)
351  {
352  if (by[k] > by[l])
353  {
354  bottom = l;
355  top = k;
356  }
357  else
358  {
359  bottom = k;
360  top = l;
361  }
362  if (bx[k] > bx[l])
363  {
364  left = l;
365  right = k;
366  }
367  else
368  {
369  left = k;
370  right = l;
371  }
372  // consider rays along the x-direction
378  if (by[bottom]-eps < yv[j] && by[top]-eps > yv[j] && !flag)
379  {
380  // if the segment is not parallel to the ray
381  if (fabs(by[l]-by[k]) > eps)
382  {
383  // calculate the point of intersection of the double ray with the boundary
384  x = bx[k] + (bx[l]-bx[k]) * (yv[j]-by[k])/(by[l]-by[k]);
385  // calculate the body velocity at the point of intersection
386  uvX = vB[k] + (vB[l]-vB[k]) * (yv[j]-by[k])/(by[l]-by[k]);
387 
388  // if the point of intersection coincides with the grid point
389  if (fabs(x-xv[i]) < eps)
390  {
391  outsideX = true;
392  bdryFlagX = I;
393  bdryFlag2X= I;
394  etaX = 0.0;
395  cfX = 0.0;
396  cf2X = 0.0;
397  flag = true;
398  }
399  // if the point of intersection lies to the right of the grid point
400  else if (x > xv[i]+eps)
401  outsideX = !outsideX;
402 
403  // if the point of intersection is in the cell to the immediate right of the grid point
404  if (x>xv[i-1]+eps && x<xv[i]-eps)
405  {
406  bdryFlagX = I+1;
407  bdryFlag2X = I+2;
408  a = xv[i]-x;
409  b = xv[i+1]-xv[i];
410  etaX = a/b;
411  switch(interpType)
412  {
413  case CONSTANT : cfX = 0.0; cf2X = 0.0; break;
414  case LINEAR : cfX = a/(a+b); cf2X = 0.0; break;
415  case QUADRATIC: cfX = 2*a/(a+b); cf2X = -a/(a+2*b); break;
416  default: cfX = a/(a+b); cf2X = 0.0; break;
417  }
418  }
419  // if the point of intersection is in the cell to the immediate left of the grid point
420  else if (x>xv[i]+eps && x<xv[i+1]-eps)
421  {
422  bdryFlagX = I-1;
423  bdryFlag2X = I-2;
424  a = x-xv[i];
425  b = xv[i]-xv[i-1];
426  etaX = a/b;
427  switch(interpType)
428  {
429  case CONSTANT : cfX = 0.0; cf2X = 0.0; break;
430  case LINEAR : cfX = a/(a+b); cf2X = 0.0; break;
431  case QUADRATIC: cfX = 2*a/(a+b); cf2X = -a/(a+2*b); break;
432  default: cfX = a/(a+b); cf2X = 0.0; break;
433  }
434  }
435  }
436  }
437  // consider rays along the y-direction
438  if (bx[left]-eps < xv[i] && bx[right]-eps > xv[i] && !flag)
439  {
440  // if the segment is not parallel to the ray
441  if (fabs(bx[l]-bx[k]) > eps)
442  {
443  // calculate the point of intersection of the double ray with the boundary
444  y = by[k] + (by[l]-by[k]) * (xv[i]-bx[k])/(bx[l]-bx[k]);
445  // calculate the body velocity at the point of intersectioin
446  uvY = vB[k] + (vB[l]-vB[k]) * (xv[i]-bx[k])/(bx[l]-bx[k]);
447 
448  // if the point of intersection coincides with the grid point
449  if (fabs(y-yv[j]) < eps)
450  {
451  outsideY = true;
452  bdryFlagY = I;
453  bdryFlag2Y= I;
454  etaY = 0.0;
455  cfY = 0.0;
456  cf2Y = 0.0;
457  flag = true;
458  }
459  // if the point of intersection lies to the top of the grid point
460  else if (y > yv[j]+eps)
461  outsideY = !outsideY;
462 
463  if (y>yv[j-1]+eps && y<yv[j]-eps)
464  {
465  bdryFlagY = I+nx;
466  bdryFlag2Y = I+2*nx;
467  a = yv[j]-y;
468  b = yv[j+1]-yv[j];
469  etaY = a/b;
470  switch(interpType)
471  {
472  case CONSTANT : cfY = 0.0; cf2Y = 0.0; break;
473  case LINEAR : cfY = a/(a+b); cf2Y = 0.0; break;
474  case QUADRATIC: cfY = 2*a/(a+b); cf2Y = -a/(a+2*b); break;
475  default: cfY = a/(a+b); cf2Y = 0.0; break;
476  }
477  }
478  else if (y>yv[j]+eps && y<yv[j+1]-eps)
479  {
480  bdryFlagY = I-nx;
481  bdryFlag2Y = I-2*nx;
482  a = y-yv[j];
483  b = yv[j]-yv[j-1];
484  etaY = a/b;
485  switch(interpType)
486  {
487  case CONSTANT : cfY = 0.0; cf2Y = 0.0; break;
488  case LINEAR : cfY = a/(a+b); cf2Y = 0.0; break;
489  case QUADRATIC: cfY = 2*a/(a+b); cf2Y = -a/(a+2*b); break;
490  default: cfY = a/(a+b); cf2Y = 0.0; break;
491  }
492  }
493  }
494  }
495  k = l;
496  l = l+1;
497  }
498  if (outsideY && bdryFlagY>=0)
499  {
500  tags[I] = bdryFlagY;
501  tags2[I] = bdryFlag2Y;
502  coeffs[I] = cfY;
503  coeffs2[I] = cf2Y;
504  uv[I] = uvY;
505  eta << etaY << std::endl;
506  }
507  else if (outsideX && bdryFlagX>=0)
508  {
509  tags[I] = bdryFlagX;
510  tags2[I] = bdryFlag2X;
511  coeffs[I] = cfX;
512  coeffs2[I] = cf2X;
513  uv[I] = uvX;
514  eta << etaX << std::endl;
515  }
516  mask << ((outsideX || outsideY)? 1 : 0) << std::endl;
517  }
518  }
519  eta.close();
520  mask.close();
521 
522  file.open((folder+"/tagy.txt").c_str());
523  for(int j=0; j<ny-1; j++)
524  {
525  for(int i=0; i<nx; i++)
526  {
527  I = j*nx+i+(nx-1)*ny;
528  if (tags[I] >= 0 || tags[I] >= 0)
529  {
530  file << xv[i] << '\t' << yv[j] << std::endl;
531  if (tags[I] == I-1)
532  file << xv[i-1] << '\t' << yv[j] << std::endl;
533  else if (tags[I] == I+1)
534  file << xv[i+1] << '\t' << yv[j] << std::endl;
535  else if (tags[I] == I-nx)
536  file << xv[i] << '\t' << yv[j-1] << std::endl;
537  else if (tags[I] == I+nx)
538  file << xv[i] << '\t' << yv[j+1] << std::endl;
539  file << std::endl;
540  }
541  }
542  }
543  file.close();
544 } // tagPoints
constant
Definition: types.h:94
double real
Is a float or a double depending on the machine precision.
Definition: types.h:116
std::map< std::string, componentParameter > parameterDB
Map from a string to a componentParameter.
Definition: parameterDB.h:64
cusp::array1d< real, host_memory > vecH
Cusp 1D array stored in the host.
Definition: types.h:154
quadratic
Definition: types.h:96
interpolationType
Specifies the type of interpolation.
Definition: types.h:92
linear
Definition: types.h:95
Generic Navier-Stokes solver in the presence of immersed boundaries.
Definition: NSWithBody.h:21
Solves the Navier-Stokes equations in a rectangular domain.