HyPar  1.0
Finite-Difference Hyperbolic-Parabolic PDE Solver on Cartesian Grids
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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 }
Facet3D * facet
#define _YDIR_
Definition: euler2d.h:41
#define _NavierStokes3DGetFlowVar_(u, stride, rho, vx, vy, vz, e, P, gamma)
int npoints_local_wghosts
Definition: hypar.h:42
#define _ArraySetValue_(x, size, value)
static int ComputeShear(void *s, void *m, const double *const u, double **const sf)
double interp_coeffs[_IB_NNODES_]
#define raiseto(x, a)
Definition: math_ops.h:37
int NavierStokes3DComputePressure(double *P, const double *const u, void *s)
3D Navier Stokes equations (compressible flows)
Structure containing variables for immersed boundary implementation.
Structure defining a facet.
Structure defining a facet map.
double * u
Definition: hypar.h:116
Structures and function definitions for immersed boundaries.
void * ib
Definition: hypar.h:443
#define _MODEL_NVARS_
Definition: euler1d.h:58
void GetStringFromInteger(int, char *, int)
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)
int IBAssembleGlobalFacetData(void *, void *, const double *const, double **const, int)
void * physics
Definition: hypar.h:266
int NavierStokes3DComputeTemperature(double *T, const double *const u, void *s)
int flag_ib
Definition: hypar.h:441
MPI related function definitions.
Facet3D * surface
int nsims
Definition: hypar.h:64
#define _ZDIR_
char * filename_index
Definition: hypar.h:197
#define _MAX_STRING_SIZE_
Definition: basic.h:14
int IBComputeFacetVar(void *, void *, const double *const, int, double **const)
char op_overwrite[_MAX_STRING_SIZE_]
Definition: hypar.h:191
Contains function definitions for common mathematical functions.
double interp_coeffs_ns[_IB_NNODES_]
int interp_nodes_ns[_IB_NNODES_]
int interp_nodes[_IB_NNODES_]
Contains structure definition for hypar.
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.
Some basic definitions and macros.
Contains macros and function definitions for common array operations.
int my_idx
Definition: hypar.h:61
Structure of MPI-related variables.
int IBComputeNormalGradient(void *, void *, const double *const, int, double **const)
Structure containing all solver-specific variables and functions.
Definition: hypar.h:23
#define _IB_NNODES_
int NavierStokes3DIBForces(void *s, void *m, double a_t)
#define _XDIR_
Definition: euler1d.h:75
Some common functions used here and there.
static const int _NavierStokes3D_stride_