HyPar  1.0
Finite-Difference Hyperbolic-Parabolic PDE Solver on Cartesian Grids
IBAssembleGlobalFacetData.c
Go to the documentation of this file.
1 
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <arrayfunctions.h>
9 #include <immersedboundaries.h>
10 #include <mpivars.h>
11 
23  void* ib,
24  const double* const local_var,
25  double** const global_var,
26  int nvars
27  )
28 {
29  MPIVariables *mpi = (MPIVariables*) m;
31 
32  if ((*global_var) != NULL) {
33  fprintf(stderr,"Error in IBAssembleGlobalFacetData()\n");
34  fprintf(stderr," global_var is not NULL on rank %d\n",
35  mpi->rank );
36  return 1;
37  }
38 
39  int nfacets_local = IB->nfacets_local;
40  FacetMap *fmap = IB->fmap;
41 
42  if ((nfacets_local == 0) && (local_var != NULL)) {
43  fprintf(stderr, "Error in IBAssembleGlobalFacetData()\n");
44  fprintf(stderr, " nfacets_local is 0 but local_var is not NULL!\n");
45  return 1;
46  }
47  if ((nfacets_local > 0) && (local_var == NULL)) {
48  fprintf(stderr, "Error in IBAssembleGlobalFacetData()\n");
49  fprintf(stderr, " nfacets_local > 0 but local_var is NULL!\n");
50  return 1;
51  }
52 
53 #ifndef serial
54  MPI_Status status;
55 #endif
56 
57  if (!mpi->rank) {
58 
59  int nfacets_global = IB->body->nfacets;
60 
61  /* allocate arrays for whole domain */
62  *global_var = (double*) calloc (nfacets_global*nvars, sizeof(double));
63  _ArraySetValue_((*global_var), (nfacets_global*nvars), 0.0);
64 
65  /* check array - to avoid double counting of facets */
66  int *check = (int*) calloc (nfacets_global, sizeof(int));
67  _ArraySetValue_(check, nfacets_global, 0);
68 
69  /* local data */
70  for (int n = 0; n < nfacets_local; n++) {
71  _ArrayAXPY_((local_var+n), 1.0, ((*global_var)+fmap[n].index), nvars);
72  check[fmap[n].index]++;
73  }
74 
75 #ifndef serial
76  for (int proc = 1; proc < mpi->nproc; proc++) {
77 
78  int nf_incoming;
79  MPI_Recv(&nf_incoming, 1, MPI_INT, proc, 98927, MPI_COMM_WORLD, &status);
80 
81  if (nf_incoming > 0) {
82 
83  int *indices_incoming = (int*) calloc(nf_incoming, sizeof(int));
84  double *var_incoming = (double*) calloc(nf_incoming*nvars, sizeof(double));
85 
86  MPI_Recv(indices_incoming, nf_incoming, MPI_INT, proc, 98928, mpi->world, &status);
87  MPI_Recv(var_incoming, nf_incoming*nvars, MPI_DOUBLE, proc, 98929, mpi->world, &status);
88 
89  for (int n = 0; n < nf_incoming; n++) {
90  _ArrayAXPY_((var_incoming+n), 1.0, ((*global_var)+indices_incoming[n]), nvars);
91  check[indices_incoming[n]]++;
92  }
93 
94  free(indices_incoming);
95  free(var_incoming);
96  }
97  }
98 #endif
99 
100  for (int n = 0; n < nfacets_global; n++) {
101  if (check[n] == 0) {
102  fprintf(stderr, "Error in IBAssembleGlobalFacetData()\n");
103  fprintf(stderr, " No data received for facet %d\n", n);
104  return 1;
105  } else {
106  _ArrayScale1D_(((*global_var)+n), (1.0/(double)check[n]), nvars);
107  }
108  }
109 
110  } else {
111 
112 #ifndef serial
113 
114  MPI_Send(&nfacets_local, 1, MPI_INT, 0, 98927, MPI_COMM_WORLD);
115 
116  if (nfacets_local > 0) {
117 
118  int i, *indices = (int*) calloc (nfacets_local, sizeof(int));
119  for (i = 0; i < nfacets_local; i++) indices[i] = fmap[i].index;
120 
121  MPI_Send(indices, nfacets_local, MPI_INT, 0, 98928, mpi->world);
122  MPI_Send(local_var, nfacets_local*nvars, MPI_DOUBLE, 0, 98929, mpi->world);
123 
124  free(indices);
125  }
126 #endif
127 
128  }
129 
130  return 0;
131 }
Structure defining a facet map.
Structure containing variables for immersed boundary implementation.
MPI related function definitions.
#define _ArrayAXPY_(x, a, y, size)
MPI_Comm world
#define _ArraySetValue_(x, size, value)
Structures and function definitions for immersed boundaries.
Structure of MPI-related variables.
#define _ArrayScale1D_(x, a, size)
int IBAssembleGlobalFacetData(void *m, void *ib, const double *const local_var, double **const global_var, int nvars)
Contains macros and function definitions for common array operations.