HyPar  1.0
Finite-Difference Hyperbolic-Parabolic PDE Solver on Cartesian Grids
NavierStokes3DIBForces.c
Go to the documentation of this file.
1 
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <math.h>
10 #include <basic.h>
11 #include <common.h>
12 #include <arrayfunctions.h>
13 #include <mathfunctions.h>
14 #include <immersedboundaries.h>
16 #include <mpivars.h>
17 #include <hypar.h>
18 
19 int NavierStokes3DComputePressure(double*, const double* const, void*);
20 int NavierStokes3DComputeTemperature(double*, const double* const, void*);
21 
37 static int ComputeShear(void *s,
38  void *m,
39  const double* const u,
40  double** const sf
41  )
42 {
43  HyPar *solver = (HyPar*) s;
44  MPIVariables *mpi = (MPIVariables*) m;
45  NavierStokes3D *physics = (NavierStokes3D*) solver->physics;
46  ImmersedBoundary *IB = (ImmersedBoundary*) solver->ib;
47 
48  if ((*sf) != NULL) {
49  fprintf(stderr, "Error in ComputeShear()\n");
50  fprintf(stderr, " shear force array is not NULL!\n");
51  return 1;
52  }
53 
54  if (!solver->flag_ib) return(0);
55 
56  int nfacets_local = IB->nfacets_local;
57  FacetMap *fmap = IB->fmap;
58  static double v[_MODEL_NVARS_];
59 
60  int nv = 4;
61 
62  if (nfacets_local > 0) {
63 
64  (*sf) = (double*) calloc (nv*nfacets_local, sizeof(double));
65 
66  if (physics->Re > 0) {
67 
68  for (int n = 0; n < nfacets_local; n++) {
69 
70  double *alpha;
71  int *nodes, j, k;
72 
73  alpha = &(fmap[n].interp_coeffs[0]);
74  nodes = &(fmap[n].interp_nodes[0]);
76  for (j=0; j<_IB_NNODES_; j++) {
77  for (k=0; k<_MODEL_NVARS_; k++) {
78  v[k] += ( alpha[j] * u[_MODEL_NVARS_*nodes[j]+k] );
79  }
80  }
81  double rho_c, uvel_c, vvel_c, wvel_c, energy_c, pressure_c;
82  _NavierStokes3DGetFlowVar_(v,_NavierStokes3D_stride_,rho_c,uvel_c,vvel_c,wvel_c,energy_c,pressure_c,physics->gamma);
83 
84  alpha = &(fmap[n].interp_coeffs_ns[0]);
85  nodes = &(fmap[n].interp_nodes_ns[0]);
87  for (j=0; j<_IB_NNODES_; j++) {
88  for (k=0; k<_MODEL_NVARS_; k++) {
89  v[k] += ( alpha[j] * u[_MODEL_NVARS_*nodes[j]+k] );
90  }
91  }
92  double rho_ns, uvel_ns, vvel_ns, wvel_ns, energy_ns, pressure_ns;
93  _NavierStokes3DGetFlowVar_(v,_NavierStokes3D_stride_,rho_ns,uvel_ns,vvel_ns,wvel_ns,energy_ns,pressure_ns,physics->gamma);
94 
95  double u_x = (uvel_ns - uvel_c) / fmap[n].dx;
96  double v_x = (vvel_ns - vvel_c) / fmap[n].dx;
97  double w_x = (wvel_ns - wvel_c) / fmap[n].dx;
98 
99  double u_y = (uvel_ns - uvel_c) / fmap[n].dy;
100  double v_y = (vvel_ns - vvel_c) / fmap[n].dy;
101  double w_y = (wvel_ns - wvel_c) / fmap[n].dy;
102 
103  double u_z = (uvel_ns - uvel_c) / fmap[n].dz;
104  double v_z = (vvel_ns - vvel_c) / fmap[n].dz;
105  double w_z = (wvel_ns - wvel_c) / fmap[n].dz;
106 
107  double nx = fmap[n].facet->nx;
108  double ny = fmap[n].facet->ny;
109  double nz = fmap[n].facet->nz;
110 
111  double T = physics->gamma*pressure_c/rho_c;
112  double mu = raiseto(T, 0.76);
113  double inv_Re = 1.0/physics->Re;
114 
115  double tau_x = (mu*inv_Re) * (2*u_x*nx + (u_y+v_x)*ny + (u_z+w_x)*nz);
116  double tau_y = (mu*inv_Re) * ((v_x+u_y)*nx + 2*v_y*ny + (v_z+w_y)*nz);
117  double tau_z = (mu*inv_Re) * ((w_x+u_z)*nx + (w_y+v_z)*ny + 2*w_z*nz);
118 
119  (*sf)[n*nv+_XDIR_] = tau_x;
120  (*sf)[n*nv+_YDIR_] = tau_y;
121  (*sf)[n*nv+_ZDIR_] = tau_z;
122 
123  (*sf)[n*nv+_ZDIR_+1] = sqrt(tau_x*tau_x + tau_y*tau_y + tau_z*tau_z);
124  }
125 
126  } else {
127 
128  _ArraySetValue_((*sf), nv*nfacets_local, 0.0);
129 
130  }
131 
132  }
133 
134  return 0;
135 }
136 
138 static int WriteSurfaceData( void* m,
139  void* ib,
140  const double* const p_surface,
141  const double* const T_surface,
142  const double* const ngrad_p_surface,
143  const double* const ngrad_T_surface,
144  const double* const shear,
145  char* filename
146  )
147 {
148  MPIVariables *mpi = (MPIVariables*) m;
150  int ierr;
151 
152 #ifndef serial
153  MPI_Status status;
154 #endif
155 
156  /* collect the surface data into global arrays */
157  double* p_surface_g = NULL;
158  ierr = IBAssembleGlobalFacetData(mpi, IB, p_surface, &p_surface_g, 1);
159  if (ierr) {
160  fprintf(stderr,"IBAssembleGlobalFacetData() returned with an error.\n");
161  return 1;
162  }
163  double* T_surface_g = NULL;
164  ierr = IBAssembleGlobalFacetData(mpi, IB, T_surface, &T_surface_g, 1);
165  if (ierr) {
166  fprintf(stderr,"IBAssembleGlobalFacetData() returned with an error.\n");
167  return 1;
168  }
169  double* ngrad_p_surface_g = NULL;
170  ierr = IBAssembleGlobalFacetData(mpi, IB, ngrad_p_surface, &ngrad_p_surface_g, 1);
171  if (ierr) {
172  fprintf(stderr,"IBAssembleGlobalFacetData() returned with an error.\n");
173  return 1;
174  }
175  double* ngrad_T_surface_g = NULL;
176  ierr = IBAssembleGlobalFacetData(mpi, IB, ngrad_T_surface, &ngrad_T_surface_g, 1);
177  if (ierr) {
178  fprintf(stderr,"IBAssembleGlobalFacetData() returned with an error.\n");
179  return 1;
180  }
181  double* shear_g = NULL;
182  ierr = IBAssembleGlobalFacetData(mpi, IB, shear, &shear_g, 4);
183  if (ierr) {
184  fprintf(stderr,"IBAssembleGlobalFacetData() returned with an error.\n");
185  return 1;
186  }
187 
188  /* Rank 0 writes the file */
189  if (!mpi->rank) {
190 
191  int nfacets_global = IB->body->nfacets;
192  const Facet3D* const facets = IB->body->surface;
193 
194  FILE *out;
195  out = fopen(filename,"w");
196  fprintf(out,"TITLE = \"Surface data created by HyPar.\"\n");
197  fprintf(out,"VARIABLES = \"X\", \"Y\", \"Z\", ");
198  fprintf(out,"\"Surface_Pressure\", ");
199  fprintf(out,"\"Surface_Temperature\", ");
200  fprintf(out,"\"Normal_Grad_Surface_Pressure\", ");
201  fprintf(out,"\"Normal_Grad_Surface_Temperature\", ");
202  fprintf(out,"\"Shear_x\", ");
203  fprintf(out,"\"Shear_y\", ");
204  fprintf(out,"\"Shear_z\", ");
205  fprintf(out,"\"Shear_magn\"");
206  fprintf(out,"\n");
207  fprintf(out,"ZONE N = %d, E = %d, DATAPACKING = POINT, ZONETYPE = FETRIANGLE\n",3*nfacets_global,nfacets_global);
208 
209  for (int n = 0; n < nfacets_global; n++) {
210  fprintf( out, "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf\n",
211  facets[n].x1,
212  facets[n].y1,
213  facets[n].z1,
214  p_surface_g[n],
215  T_surface_g[n],
216  ngrad_p_surface_g[n],
217  ngrad_T_surface_g[n],
218  shear_g[4*n+_XDIR_],
219  shear_g[4*n+_YDIR_],
220  shear_g[4*n+_ZDIR_],
221  shear_g[4*n+_ZDIR_+1] );
222  fprintf( out, "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf\n",
223  facets[n].x2,
224  facets[n].y2,
225  facets[n].z2,
226  p_surface_g[n],
227  T_surface_g[n],
228  ngrad_p_surface_g[n],
229  ngrad_T_surface_g[n],
230  shear_g[4*n+_XDIR_],
231  shear_g[4*n+_YDIR_],
232  shear_g[4*n+_ZDIR_],
233  shear_g[4*n+_ZDIR_+1] );
234  fprintf( out, "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf\n",
235  facets[n].x3,
236  facets[n].y3,
237  facets[n].z3,
238  p_surface_g[n],
239  T_surface_g[n],
240  ngrad_p_surface_g[n],
241  ngrad_T_surface_g[n],
242  shear_g[4*n+_XDIR_],
243  shear_g[4*n+_YDIR_],
244  shear_g[4*n+_ZDIR_],
245  shear_g[4*n+_ZDIR_+1] );
246  }
247  for (int n = 0; n < nfacets_global; n++) fprintf(out,"%d %d %d\n",3*n+1,3*n+2,3*n+3);
248  fclose(out);
249  }
250 
251  if (p_surface_g) free(p_surface_g);
252  if (T_surface_g) free(T_surface_g);
253  if (ngrad_p_surface_g) free(ngrad_p_surface_g);
254  if (ngrad_T_surface_g) free(ngrad_T_surface_g);
255  if (shear_g) free(shear_g);
256 
257  return 0;
258 }
259 
260 
265  void* m,
266  double a_t )
267 {
268  HyPar *solver = (HyPar*) s;
269  MPIVariables *mpi = (MPIVariables*) m;
270  NavierStokes3D *physics = (NavierStokes3D*) solver->physics;
271  ImmersedBoundary *IB = (ImmersedBoundary*) solver->ib;
272  int ierr;
273 
274  if (!solver->flag_ib) return(0);
275 
276  int npts = solver->npoints_local_wghosts;
277 
278  double* pressure = (double*) calloc (npts, sizeof(double));
279  ierr = NavierStokes3DComputePressure(pressure, solver->u, solver);
280  if (ierr) {
281  fprintf(stderr,"Error in NavierStokes3DIBForces()\n");
282  fprintf(stderr," NavierStokes3DComputePressure() returned with error.\n");
283  return 1;
284  }
285  double* temperature = (double*) calloc(npts, sizeof(double));
286  ierr = NavierStokes3DComputeTemperature(temperature, solver->u, solver);
287  if (ierr) {
288  fprintf(stderr,"Error in NavierStokes3DIBForces()\n");
289  fprintf(stderr," NavierStokes3DComputeTemperature() returned with error.\n");
290  return 1;
291  }
292 
293  /* Compute surface pressure */
294  double* p_surface = NULL;
295  ierr = IBComputeFacetVar(solver, mpi, pressure, 1, &p_surface);
296  if (ierr) {
297  fprintf(stderr,"Error in NavierStokes3DIBForces()\n");
298  fprintf(stderr," IBComputeFacetVar() returned with error.\n");
299  return 1;
300  }
301  /* Compute surface temperature */
302  double* T_surface = NULL;
303  ierr = IBComputeFacetVar(solver, mpi, temperature, 1, &T_surface);
304  if (ierr) {
305  fprintf(stderr,"Error in NavierStokes3DIBForces()\n");
306  fprintf(stderr," IBComputeFacetVar() returned with error.\n");
307  return 1;
308  }
309  /* Compute normal surface pressure gradient */
310  double *ngrad_p_surface = NULL;
311  ierr = IBComputeNormalGradient(solver, mpi, pressure, 1, &ngrad_p_surface);
312  if (ierr) {
313  fprintf(stderr,"Error in NavierStokes3DIBForces()\n");
314  fprintf(stderr," IBComputeNormalGradient() returned with error.\n");
315  return 1;
316  }
317  /* Compute normal temperature gradient */
318  double *ngrad_T_surface = NULL;
319  ierr = IBComputeNormalGradient(solver, mpi, temperature, 1, &ngrad_T_surface);
320  if (ierr) {
321  fprintf(stderr,"Error in NavierStokes3DIBForces()\n");
322  fprintf(stderr," IBComputeNormalGradient() returned with error.\n");
323  return 1;
324  }
325  /* Compute shear forces */
326  double *shear = NULL;
327  ierr = ComputeShear(solver, mpi, solver->u, &shear);
328  if (ierr) {
329  fprintf(stderr,"Error in NavierStokes3DIBForces()\n");
330  fprintf(stderr," ComputeShear() returned with error.\n");
331  return 1;
332  }
333 
334  char surface_filename[_MAX_STRING_SIZE_] = "surface";
335  if (solver->nsims == 1) {
336  if (!strcmp(solver->op_overwrite,"no")) {
337  strcat(surface_filename,solver->filename_index);
338  }
339  } else {
340  char index[_MAX_STRING_SIZE_];
341  GetStringFromInteger(solver->my_idx, index, (int)log10(solver->nsims)+1);
342  strcat(surface_filename, "_");
343  strcat(surface_filename, index);
344  strcat(surface_filename, "_");
345  }
346  strcat(surface_filename,".dat");
347  if (!mpi->rank) {
348  printf("Writing immersed body surface data file %s.\n",surface_filename);
349  }
350  ierr = WriteSurfaceData( mpi,
351  IB,
352  p_surface,
353  T_surface,
354  ngrad_p_surface,
355  ngrad_T_surface,
356  shear,
357  surface_filename );
358  if (ierr) {
359  fprintf(stderr,"Error in NavierStokes3DIBForces()\n");
360  fprintf(stderr," WriteSurfaceData() returned with error\n");
361  return 1;
362  }
363 
364  free(pressure);
365  free(temperature);
366  if (p_surface) free(p_surface);
367  if (T_surface) free(T_surface);
368  if (ngrad_p_surface) free(ngrad_p_surface);
369  if (ngrad_T_surface) free(ngrad_T_surface);
370  if (shear) free(shear);
371 
372  return 0;
373 }
double interp_coeffs[_IB_NNODES_]
Some common functions used here and there.
Structure defining a facet.
Structure defining a facet map.
#define _IB_NNODES_
Structure containing variables for immersed boundary implementation.
MPI related function definitions.
char * filename_index
Definition: hypar.h:197
Contains function definitions for common mathematical functions.
#define _ZDIR_
Structure containing variables and parameters specific to the 3D Navier Stokes equations. This structure contains the physical parameters, variables, and function pointers specific to the 3D Navier-Stokes equations.
double interp_coeffs_ns[_IB_NNODES_]
Facet3D * surface
int nsims
Definition: hypar.h:64
double * u
Definition: hypar.h:116
void * ib
Definition: hypar.h:443
int NavierStokes3DComputeTemperature(double *, const double *const, void *)
Some basic definitions and macros.
int interp_nodes[_IB_NNODES_]
int flag_ib
Definition: hypar.h:441
3D Navier Stokes equations (compressible flows)
int NavierStokes3DComputePressure(double *, const double *const, void *)
Structure containing all solver-specific variables and functions.
Definition: hypar.h:23
#define _MAX_STRING_SIZE_
Definition: basic.h:14
#define _YDIR_
Definition: euler2d.h:41
static int WriteSurfaceData(void *m, void *ib, const double *const p_surface, const double *const T_surface, const double *const ngrad_p_surface, const double *const ngrad_T_surface, const double *const shear, char *filename)
Contains structure definition for hypar.
char op_overwrite[_MAX_STRING_SIZE_]
Definition: hypar.h:191
static int ComputeShear(void *s, void *m, const double *const u, double **const sf)
void GetStringFromInteger(int, char *, int)
Facet3D * facet
static const int _NavierStokes3D_stride_
int my_idx
Definition: hypar.h:61
#define _ArraySetValue_(x, size, value)
int IBComputeNormalGradient(void *, void *, const double *const, int, double **const)
void * physics
Definition: hypar.h:266
Structures and function definitions for immersed boundaries.
#define _XDIR_
Definition: euler1d.h:75
int interp_nodes_ns[_IB_NNODES_]
Structure of MPI-related variables.
#define raiseto(x, a)
Definition: math_ops.h:37
#define _MODEL_NVARS_
Definition: euler1d.h:58
int npoints_local_wghosts
Definition: hypar.h:42
int IBComputeFacetVar(void *, void *, const double *const, int, double **const)
Contains macros and function definitions for common array operations.
int NavierStokes3DIBForces(void *s, void *m, double a_t)
int IBAssembleGlobalFacetData(void *, void *, const double *const, double **const, int)
#define _NavierStokes3DGetFlowVar_(u, stride, rho, vx, vy, vz, e, P, gamma)