AcouSTO  version 2.0

◆ acoustic_body_coefs()

int acoustic_body_coefs ( )

Evaluates B and C coefficients (please refer to the user manual for details on the theory) The actual evaluation is done in parallel on all the nodes of the domain (SPMD). The matrices are partitioned according to scalapack 2D block cyclic distribution (locRows x locCols). In each loop over the nodes, krow lines of the coefficient matrices can be loaded into memory to minimize memory usage and then written on two different files:

bbcoefs.bin.<nodeid> B coefficients
bccoefs.bin.<nodeid> C coefficients

where <nodeid> is the rank of the node (to avoid name-clashing on multiple process running on the same node). The same files are then read in the Matrices assembly procedure (matrices.c), basically we dictate here the overall partitioning method for the run.

See also
ac_coef_mics.c
matrices.c
integrals.c
50  {
51 
52  int npsib,nphib,nelmu;
53  int icntr,ielmb;
54  int ielmu,is;
55  int mpi_nelmb;
56  struct panel4* mpi_elements;
57  int mpi_ncntr;
58  struct vector* mpi_cntr;
59 
60  int kode;
61  int bstride;
62  int cstride;
63 
64  DOUBLE theta;
65  DOUBLE source,doublet,ratelet;
66 
67  int gRows,gCols; // global dim of coefficient matrix
68  int locRows,locCols; // local dim of coefficient matrix
69 
70  int izero=0;
71 
72 //#define _ACOUSTO_DEBUG
73 #ifdef _ACOUSTO_DEBUG
74  FILE* f;
75  char fname[15];
76 #endif
77 
78  FILE* fbcoef = NULL;
79  FILE* fccoef = NULL;
80  int nrow,nrowi,iloop,nloop,irow,nio,nrlast;
81  char fbname[MAX_PATH];
82  char fcname[MAX_PATH];
83 
84  DOUBLE* ctmp;
85  int i,j;
86  int ic;
87  int bsymmoffset,csymmoffset;
88 
89  long long int perc,ioldcurrent,icurrent,ntotal;
90 
91 
93 
94  // assigning number of psi and phi points (coincident with number of elements)
95  npsib = modgeominfo->nelmb;
96  nphib = modgeominfo->nelmb;
97  nelmu = modgeominfo->ncntr;
98 
99 
100  /* copying variables into local storage (just for ease of use) */
101  mpi_nelmb = modgeominfo->nelmb;
102  mpi_elements = geometry->elements;
103  mpi_ncntr = modgeominfo->ncntr + modgeominfo->nchief;
104  mpi_cntr = geometry->cntrc;
105 
106 
107 #ifdef _ACOUSTO_DEBUG
108  if(rank == 0){
109  sprintf(fname,"elements.%d",rank);
110  logger(LOG_DEBUG,"filename [%s]\n",fname);
111  f = fopen(fname,"w");
112  for(i=0;i<modgeominfo->nelmb;i++){
113  fprintf(f,"# ielmb=%d\n",i);
114  fprintf(f,VECTOR_PRINTF,mpi_elements[i].x[0].x, mpi_elements[i].x[0].y, mpi_elements[i].x[0].z);
115  fprintf(f,VECTOR_PRINTF,mpi_elements[i].x[1].x, mpi_elements[i].x[1].y, mpi_elements[i].x[1].z);
116  fprintf(f,VECTOR_PRINTF,mpi_elements[i].x[2].x, mpi_elements[i].x[2].y, mpi_elements[i].x[2].z);
117  fprintf(f,VECTOR_PRINTF,mpi_elements[i].x[3].x, mpi_elements[i].x[3].y, mpi_elements[i].x[3].z);
118  fprintf(f,"\n\n");
119  }
120  fclose(f);
121  sprintf(fname,"cntr.%d",rank);
122  logger(LOG_DEBUG,"filename [%s]\n",fname);
123  f = fopen(fname,"w");
124  for(i=0;i<mpi_ncntr;i++){
125  fprintf(f,VECTOR_PRINTF,mpi_cntr[i].x, mpi_cntr[i].y, mpi_cntr[i].z);
126  }
127  fclose(f);
128  sprintf(fname,"normals.%d",rank);
129  logger(LOG_DEBUG,"filename [%s]\n",fname);
130  f = fopen(fname,"w");
131  for(i=0;i<mpi_ncntr;i++){
132  fprintf(f,VECTOR_PRINTF,mpi_cntr[i].x, mpi_cntr[i].y, mpi_cntr[i].z);
133  fprintf(f,VECTOR_PRINTF,mpi_cntr[i].x+mpi_elements[i].n.x,
134  mpi_cntr[i].y+mpi_elements[i].n.y,
135  mpi_cntr[i].z+mpi_elements[i].n.z);
136  fprintf(f,"\n\n");
137  }
138  fclose(f);
139  }
140 #endif
141  gRows = mpi_ncntr;
142  //gCols = mpi_nelmb;
143  gCols = modgeominfo->ncntr;
144 
145  bodycoefs = calloc(1,sizeof(struct bodycoefs_struct)); // allocating main body coefs struct
146 
147  // Building array descriptor
148  locRows = numroc_(&gRows,&runinfo->row_block_size,&runinfo->myrow,&izero,&runinfo->nprows);
149  locCols = numroc_(&gCols,&runinfo->col_block_size,&runinfo->mycol,&izero,&runinfo->npcols);
150 
151  // nrow lines each loop
152  nrow = runinfo->krow;
153  if(runinfo->krow <= 0 || runinfo->krow >= locRows) nrow = locRows;
154 
155  // ALLOCATING COEFS
156  bodycoefs->B =calloc(2*nrow*locCols*runinfo->nsymm,sizeof(DOUBLE)); // 2 B coefficients, nrow*partition size*symmetry factor
157  bodycoefs->C =calloc(4*nrow*locCols*runinfo->nsymm,sizeof(DOUBLE)); // 4 C coefficients, nrow*partition size*symmetry factor
158  logger(LOG_DEBUG,"Total allocated memory for body coefficients=%d bytes\n",
159  (2*nrow*locCols*runinfo->nsymm*sizeof(DOUBLE) + 4*nrow*locCols*runinfo->nsymm*sizeof(DOUBLE)));
160 
161  ctmp = calloc(locRows,sizeof(DOUBLE));
162 
163 
164  if(runinfo->krow > 0){ // only if krow is used
165  // setting names of files (different for each node in case of multi-process run)
166  get_filename(fbname,"bbcoefs.bin.%d",rank);
167  get_filename(fcname,"bccoefs.bin.%d",rank);
168  logger(LOG_DEBUG,"body coefficients will be in files \"%s\" and \"%s\"\n", fbname,fcname);
169  // opening files in binary-write mode
170  fbcoef = fopen(fbname,"wb");
171  fccoef = fopen(fcname,"wb");
172  }
173 
174  // evaluating local block of coefficient
175  j12(locRows,nrow,&nrlast,&nloop); // calculating start row and number of loops
176 
177  ntotal = (nloop-1) * nrow * locCols * runinfo->nsymm;
178  ioldcurrent = 0;
179  icurrent = 0;
180  ioldcurrent = -1;
181 
182  for(iloop=0;iloop<nloop;iloop++){ // LOOP ON NLOOP
183  ic = 0;
184  nrowi = nrow;
185  if(iloop == nloop-1) nrowi = nrlast; // setting number of rows=number of last rows on final loop
186  //calculating stride for arrays
187  bstride = nrowi*locCols;
188  cstride = nrowi*locCols;
189 
190  for(irow=0;irow<nrowi;irow++){ // LOOP ON NROW
191  i= j21(irow,iloop,nrow); // calculating control point index
193  for(j=0;j<locCols;j++){
194  // getting local indices
195 
197  for(is=0;is<runinfo->nsymm;is++){
198 
199  bsymmoffset = is * 2*nrowi*locCols;
200  csymmoffset = is * 4*nrowi*locCols;
201  ielmb = ielmu + is*nelmu;
202 
203  kode = (ielmb == icntr) ? 1 : 0; // singular panels flag
204 
205  delaya(&theta,ielmb,&mpi_elements[ielmb],mpi_cntr[icntr]); // evaluating acoustic delay
206  intgba(1, 0, kode, &mpi_cntr[icntr], &mpi_elements[ielmb], &source, &doublet, &ratelet); // integrating
207 
208  ic = irow*locCols +j;
209 
210  bodycoefs->B[ic + bsymmoffset] = source;
211  bodycoefs->B[ic + bstride + bsymmoffset] = theta/runinfo->vsound;
212 
213  bodycoefs->C[ic + csymmoffset] = doublet;
214  bodycoefs->C[ic + cstride + csymmoffset] = ((1 == kode) ? (DOUBLE)0.0 : (DOUBLE)ratelet/runinfo->vsound );
215  bodycoefs->C[ic + cstride*2 + csymmoffset] = theta/runinfo->vsound;
216 
217 
218  bodycoefs->C[ic + cstride*3 + csymmoffset] = (icntr == ielmb) ? 0.5 : 0.0;
219 // ic++;
220 
221  icurrent++;
222  if( (icurrent*10/ntotal) != (ioldcurrent*10/ntotal)){
223  perc =icurrent*100/ntotal;
224  logger(LOG_INFO,"Completed %lld \%% \n",perc);
225  }
226  ioldcurrent = icurrent;
227  }
228 
229 
230  } // LOOP ON locCOLS END
231  } // LOOP ON NROW END
232  if(runinfo->krow > 0){
233  // append on files
234  nio = fwrite(bodycoefs->B,sizeof(DOUBLE),2*nrowi*locCols*runinfo->nsymm,fbcoef);
235  nio = fwrite(bodycoefs->C,sizeof(DOUBLE),4*nrowi*locCols*runinfo->nsymm,fccoef);
236  }
237  } // LOOP ON NLOOP END
238 
239  if(runinfo->krow > 0){
240  fclose(fbcoef);
241  fclose(fccoef);
242  }
243  //zgsum2d_(&runinfo->ctxt,"R"," ",&locRows,&runinfo->npcols,ctmp,&locRows,&ione,&ione,&imone,&imone,&imone);
244  /*
245  Cdgsum2d(runinfo->ctxt,"R"," ",locRows,1,ctmp,locRows,-1,-1);
246 
247 
248  for(icntr=0;icntr<gRows;icntr++){
249  sc_g2l(icntr,gRows,runinfo->nprows,runinfo->row_block_size,&myi,&i);
250  sc_g2l(icntr,gCols,runinfo->npcols,runinfo->col_block_size,&myj,&j);
251  if(myi == runinfo->myrow &&
252  myj == runinfo->mycol){
253  bodycoefs->C[(i*locCols+j) + cstride*3] = 1.0 + ctmp[i]; // setting C[3] value
254  }
255  }
256  */
257 
258  // out of main loop for diagonal element (must optimize this)
259  /*
260  for(icntr=0;icntr<gRows;icntr++){
261  dsum = 0.0;
262  for(ielmb=0;ielmb<gCols;ielmb++){ // summing on col
263  kode = (ielmb == icntr) ? 1 : 0; // singular panels flag
264  intgba(1, 0, kode, &mpi_cntr[icntr], &mpi_elements[ielmb], &source, &doublet, &ratelet); // integrating
265  dsum += doublet;
266  }
267  sc_g2l(icntr,gRows,runinfo->nprows,runinfo->row_block_size,&myi,&i);
268  sc_g2l(icntr,gCols,runinfo->npcols,runinfo->col_block_size,&myj,&j);
269  if(myi == runinfo->myrow &&
270  myj == runinfo->mycol){
271  bodycoefs->C[(i*locCols+j) + cstride*3] = 1.0 + dsum; // setting C[3] value
272  }
273  }
274  */
275 
276 #ifdef _ACOUSTO_DEBUG
277  if(runinfo->krow > 0){ // only if krow is used
278  get_filename(fbname,"bbcoefs.bin.%d",rank); get_filename(fcname,"bccoefs.bin.%d",rank);
279  fbcoef = fopen(fbname,"rb"); fccoef = fopen(fcname,"rb");
280  }
281 
282  sprintf(fname,"bcoef.%d%d",runinfo->myrow,runinfo->mycol);
283  f = fopen(fname,"w");
284  j12(locRows,nrow,&nrlast,&nloop);
285  for(iloop=0;iloop<nloop;iloop++){ // LOOP ON NLOOP
286  nrowi = nrow;
287  if(iloop == nloop-1) nrowi = nrlast;
288  bstride = nrowi*locCols;
289  cstride = nrowi*locCols;
290  if(runinfo->krow > 0){ // only if krow is used
291  nio = fread(bodycoefs->B,sizeof(DOUBLE),2*nrowi*locCols*runinfo->nsymm,fbcoef);
292  nio = fread(bodycoefs->C,sizeof(DOUBLE),4*nrowi*locCols*runinfo->nsymm,fccoef);
293  }
294  for(irow=0;irow<nrowi;irow++){ // LOOP ON NROW
295  i= j21(irow,iloop,nrow);
297  for(j=0;j<locCols;j++){
299  for(is=0;is<runinfo->nsymm;is++){
300 
301  ielmb = ielmu + is*nelmu;
302  bsymmoffset = is * 2*nrowi*locCols;
303  csymmoffset = is * 4*nrow*locCols;
304  fprintf(f,"%d %d %f %f %f %f %f %f\n",icntr,ielmb,
305  bodycoefs->B[(irow*locCols+j) + bsymmoffset],
306  bodycoefs->B[(irow*locCols+j) + bstride + bsymmoffset],
307  bodycoefs->C[(irow*locCols+j) + csymmoffset],
308  bodycoefs->C[(irow*locCols+j) + cstride + csymmoffset],
309  bodycoefs->C[(irow*locCols+j) + cstride*2 + csymmoffset],
310  bodycoefs->C[(irow*locCols+j) + cstride*3 + csymmoffset]);
311  }
312 
313  }
314  }
315  }
316  if(runinfo->krow > 0){ // only if krow is used
317  fclose(fbcoef);
318  fclose(fccoef);
319  }
320 
321 
322  fclose(f);
323 #endif
324 #undef _ACOUSTO_DEBUG
325  if(runinfo->krow > 0){
326  free(bodycoefs->B);
327  free(bodycoefs->C);
328  }
329 
330  free(ctmp);
332  return 1;
333 
334 }
struct bodycoefs_struct * bodycoefs
Definition: globals.h:48
struct run_info * runinfo
Definition: globals.h:34
int npcols
Definition: structs.h:113
int ncntr
Definition: structs.h:299
DOUBLE vsound
Definition: structs.h:102
#define VECTOR_PRINTF
Definition: formats.h:66
void delaya(DOUBLE *theta, int ielmb, struct panel4 *element, struct vector xc)
Definition: integrals.c:268
struct to hold Coefficients at the body.
Definition: structs.h:379
int myrow
Definition: structs.h:115
int nprows
Definition: structs.h:111
void get_filename(char *filename, const char *format,...)
Definition: utils.c:59
vector struct to hold triplets.
Definition: structs.h:29
DOUBLE * B
Definition: structs.h:385
#define MSG_BODYCOEF_END
Definition: messages.h:48
int nchief
Definition: structs.h:301
DOUBLE * C
Definition: structs.h:387
#define LOG_INFO
Definition: logger.h:26
int nelmb
Definition: structs.h:295
#define MSG_BODYCOEF_START
Definition: messages.h:46
Definition of a quadrilateral panel.
Definition: structs.h:44
struct vector n
Definition: structs.h:48
DOUBLE z
Definition: structs.h:35
void j12(int i12, int n1, int *i1, int *i2)
Definition: math.c:206
#define LOG_DEBUG
Definition: logger.h:27
int j21(int i1, int i2, int n1)
Definition: math.c:202
int mycol
Definition: structs.h:117
int nsymm
Definition: structs.h:97
double DOUBLE
Definition: types.h:44
int numroc_(int *m, int *mb, int *p, int *ia, int *npr)
int rank
Definition: globals.h:79
DOUBLE x
Definition: structs.h:31
int col_block_size
Definition: structs.h:121
void intgba(int kcrce, int kelem, int kode, struct vector *xcntr, struct panel4 *element, DOUBLE *source, DOUBLE *doublet, DOUBLE *ratelet)
Definition: integrals.c:40
int krow
Definition: structs.h:105
Geometry info structure.
Definition: structs.h:161
struct vector x[4]
Definition: structs.h:46
#define MAX_PATH
Definition: constants.h:29
int row_block_size
Definition: structs.h:119
void logger(int level, char *msg,...)
Definition: logger.c:56
#define calloc(n, size)
Definition: allocation.h:37
struct modgeom_info * modgeominfo
Definition: globals.h:38
void sc_l2g(int il, int p, int n, int np, int nb, int *i)
Definition: matutils.c:116
DOUBLE y
Definition: structs.h:33