AcouSTO  version 2.0

◆ matyfdc()

void matyfdc ( COMPLEX  cfreq,
int  icounter 
)

Evaluates System Matrix and RHS of the linear System. Valid for Neumann-type & Dirichlet-type Boundary Conditions. Coefficients are evaluated here and discarded after use.

Parameters
cfreqCOMPLEX frequency
icounterindex of frequency
37  {
38 
39  int icntr;
40  int ielmb,ielmu;
41  int nphiu, mpi_nelmu;
42  int nphib;
43 
44  int mpi_ncntr;
45  COMPLEX cexpc;
46  DOUBLE bb,cc,dd,thetac,estar;
47  COMPLEX matval = 0.0 + I*0.0;;
48  COMPLEX yy = 0.0 + I*0.0;;
49  int cstride;
50  int kode;
51 
52  //DOUBLE *C;
53 
54  int gRows,gCols; // global dim of coefficient matrix
55  int locRows,locCols; // local dim of coefficient matrix
56  int izero = 0;
57  int i,j;
58  COMPLEX lambda;
59  COMPLEX gamma;
60  COMPLEX func;
61  struct vector g;
62  struct vector un;
63  COMPLEX gamma_over_lambda;
64  COMPLEX lambda_over_gamma;
65  DOUBLE gdotn;
66 
67 #ifdef _ACOUSTO_DEBUG
68  FILE* f;
69  FILE* cmatfile;
70  char fname[15];
71  int ipsiu;
72 #endif
73 
74 // char fname2[25];
75 // FILE* f2;
76 // COMPLEX bbtmp,ytmp;
77 // sprintf(fname2,"bodymatrdump_dipaolo.%d%d",runinfo->myrow,runinfo->mycol);
78 // f2 = fopen(fname2,"w");
79 
80 
81  // int nrow,nrowi,iloop,nloop,irow,nio,nrlast;
82 
83  int is;
84  DOUBLE theta;
85  DOUBLE source,doublet,ratelet;
86  struct panel4* mpi_elements;
87  struct vector* mpi_cntr;
88 
89  MPI_Group* mpi_row_groups;
90  MPI_Group mpi_group_world;
91  MPI_Comm* mpi_comm;
92  int* row_ranks;
93  COMPLEX* ctmp;
94  Vec psiuvec;
95  Vec psincvec;
96  Vec phincvec;
97  int gCRows;
98  int nn;
99  int mm;
100  int descpsiu[9];
101  int descgpsiu[9];
102  int ione = 1;
103  int info;
104 
105 
106  // number of control points,phib and phiu points
107  mpi_elements = geometry->elements;
108  mpi_cntr = geometry->cntrc;
109  mpi_ncntr = modgeominfo->ncntr + modgeominfo->nchief;
110  nphiu = modgeominfo->ncntr;
111  nphib = modgeominfo->nelmb;
112  mpi_nelmu = nphiu;
113 
114  gRows = mpi_ncntr;
115  gCols = nphiu;
116 
117 
118 #ifdef _ACOUSTO_DEBUG
119  cmatfile = fopen("CD.matrix.out","w");
120  fprintf(cmatfile,"CD=[");
121 #endif
122 
123  locRows = numroc_(&gRows ,&runinfo->row_block_size,&runinfo->myrow,&izero,&runinfo->nprows);
124  locCols = numroc_(&gCols ,&runinfo->col_block_size,&runinfo->mycol,&izero,&runinfo->npcols);
125  cstride = locRows * locCols; // C stride
126 
127  // nrow partition on node to limit memory usage (see manual)
128  if (solution->matY == NULL) {
129  solution->matY = calloc(locRows*locCols,sizeof(COMPLEX)); // allocation
130  } else {
131  for(i = 0; i < locRows*locCols; i++)
132  solution->matY[i] = COMPLEX_ZERO;
133  }
134 
135  gCRows = nphiu;
136  psiuvec = calloc(nphiu,sizeof(COMPLEX)); // allocating vector
137  psincvec = calloc(nphiu,sizeof(COMPLEX)); // allocating vector
138  phincvec = calloc(nphiu,sizeof(COMPLEX)); // allocating vector
139  mm = gCRows;// * runinfo->nprows;
140  nn = runinfo->npcols;
141  descinit_(descpsiu , &gCRows ,&ione, &runinfo->row_block_size ,&ione,&izero,&izero,&runinfo->ctxt,&gCRows ,&info);
142  descinit_(descgpsiu , &mm ,&ione, &gCRows ,&ione,&izero,&izero,&runinfo->ctxt,&gCRows ,&info);
143  pzgemr2d_(&gCRows,&ione,solution->vecPsiu ,&ione, &ione,descpsiu, psiuvec ,&ione,&ione,descgpsiu,&runinfo->ctxt);
144  pzgemr2d_(&gCRows,&ione,solution->vecPsinc,&ione, &ione,descpsiu, psincvec,&ione,&ione,descgpsiu,&runinfo->ctxt);
145  pzgemr2d_(&gCRows,&ione,solution->vecPhinc,&ione, &ione,descpsiu, phincvec,&ione,&ione,descgpsiu,&runinfo->ctxt);
146 
147  MPI_Bcast(psiuvec ,gCRows,MPI_ACOUSTO_COMPLEX,0,MPI_COMM_WORLD);
148  MPI_Bcast(psincvec,gCRows,MPI_ACOUSTO_COMPLEX,0,MPI_COMM_WORLD);
149  MPI_Bcast(phincvec,gCRows,MPI_ACOUSTO_COMPLEX,0,MPI_COMM_WORLD);
150 
151  CREATE_VEC(solution->rhs,locRows); // allocation
152  VecZeroEntries(solution->rhs,locRows); // reset
153 
154  CREATE_VEC(ctmp,locRows); // allocation
155 
156  for(i=0;i<locRows;i++){ // LOOP ON ICNTR
158 
159  if(modsolinfo->knw == 1){
160  if(runinfo->mycol == 0){
161  if (modsolinfo->dirneu == 1) solution->rhs[i] = -phincvec[icntr]; // DIRICHLET-TYPE
162  if (modsolinfo->dirneu == 2) solution->rhs[i] = phincvec[icntr]; // NEUMANN-TYPE
163  }else{
164  solution->rhs[i] = COMPLEX_ZERO;
165  }
166  }else{
167  solution->rhs[i] = COMPLEX_ZERO;
168  }
169 
170  for(j=0;j<locCols;j++){ // LOOP ON NELMB
172  //ic = irow*locCols +j;
173 
174  estar = (icntr == ielmu ) ? 0.5 : 0.0;
175  solution->matY[locRows*j + i ] += estar;
176 
177  for(is=0;is<runinfo->nsymm;is++){
178 
179  ielmb = ielmu + is*mpi_nelmu;
180 
181  kode = (ielmb == icntr) ? 1 : 0; // singular panels flag
182 
183  delaya(&theta,ielmb,&mpi_elements[ielmb],mpi_cntr[icntr]); // evaluating acoustic delay
184  intgba(1, 0, kode, &mpi_cntr[icntr], &mpi_elements[ielmb], &source, &doublet, &ratelet); // integrating
185 
186  bb = source;
187  cc = doublet;
188  dd = ((1 == kode) ? (DOUBLE)0.0 : (DOUBLE)ratelet/runinfo->vsound );
189  thetac = theta/runinfo->vsound;
190  cexpc = CEXP(-cfreq*thetac);
191 
192  vec_copy(&un,mpi_elements[ielmb].n);
193  lambda = bc.lambda[ielmu];
194  gamma = bc.gamma[ielmu];
195  func = bc.func[ielmu];
196  gamma_over_lambda = gamma/lambda;
197  lambda_over_gamma = lambda/gamma;
198  g.x = bc.g.x;
199  g.y = bc.g.y;
200  g.z = bc.g.z;
201  gdotn = vec_dot(g,un);
202  matval = (cc+cfreq*dd) * cexpc ;
203  //
204  // THIS IS CLASSICAL YMAT=E*I-(C+s*D). NEEDED TO BUILD NEUMANN & DIRICHLET RHSs.
205  // NOTE: matval includes delay
206  //
207  solution->matY[locRows*j + i ] -= matval;
208  yy = solution->matY[locRows*j + i ];
209 
210  if(modsolinfo->knw == 1){
211  if (modsolinfo->dirneu == 1) solution->rhs[i] += yy * (func+gdotn)/gamma; // DIRICHLET
212  if (modsolinfo->dirneu == 2) solution->rhs[i] += bb * cexpc * (func+gdotn)/lambda; // NEUMANN
213  }else if(modsolinfo->knw == 2){
214  if (modsolinfo->dirneu == 1) solution->rhs[i] += yy * ((func+gdotn)/gamma - psincvec[ielmu]*lambda_over_gamma - phincvec[ielmu]); // DIRICHLET
215  if (modsolinfo->dirneu == 2) solution->rhs[i] += bb * cexpc*((func+gdotn)/lambda - phincvec[ielmu]*gamma_over_lambda - psincvec[ielmu]); // NEUMANN
216  }
217  //
218  // HERE SYSTEM MATRIX IS BUILT ON YMAT.
219  //
220  if (modsolinfo->dirneu == 1) solution->matY[locRows*j + i ] = bb*cexpc + yy * lambda_over_gamma; //DIRICHLET (matrix entry is rewritten)
221  if (modsolinfo->dirneu == 2) solution->matY[locRows*j + i ] += bb * gamma_over_lambda *cexpc; //NEUMANN (matrix entry is updated)
222 
223 #ifdef _ACOUSTO_DEBUG
224  fprintf(cmatfile,"%f + %%i*%f ,",CREAL(solution->matY[locRows*j + i ]),CIMAG(solution->matY[locRows*j + i ]));;
225 #endif
226 
227  } // END OF LOOP ON NSYMM
228 // fprintf(f2,"%d %d %f %f %f %f\n",icntr,ielmu,CREAL(bbtmp),CIMAG(bbtmp),CREAL(ytmp),CIMAG(ytmp));
229  }
230 
231 
232 
233 
234 #ifdef _ACOUSTO_DEBUG
235  fprintf(cmatfile,";\n");
236 #endif
237  } // END OF LOOP ON NROW
238  /*} // END OF LOOP ON NLOOP */
239 
240 // fclose(f2);
241 
242 #ifdef _ACOUSTO_DEBUG
243  fprintf(cmatfile,"];\n");
244 #endif
245 
246 
247  // Reducing RHS if cols in proc grid are > 1
248  if(runinfo->npcols > 1){
249  logger(LOG_INFO," Reducing RHS on columns\n");
250  mpi_row_groups = calloc(sizeof(MPI_Group) , runinfo->nprows);
251  mpi_comm = calloc(sizeof(MPI_Comm) , runinfo->nprows);
252  row_ranks = calloc(sizeof(int) , runinfo->npcols);
253  MPI_Comm_group(MPI_COMM_WORLD, &mpi_group_world);
254  for(i=0;i<runinfo->nprows;i++){
255  for(j=0;j<runinfo->npcols;j++){
256  row_ranks[j] = j + i*runinfo->npcols;
257  }
258  MPI_Group_incl(mpi_group_world,runinfo->npcols,row_ranks,&mpi_row_groups[i]);
259  MPI_Comm_create(MPI_COMM_WORLD, mpi_row_groups[i], &mpi_comm[i]);
260  }
261 
262  for(i=0;i<runinfo->nprows;i++){
263 
264  if(MPI_COMM_NULL != mpi_comm[i]){
265  MPI_Allreduce((void*)solution->rhs,
266  (void*)&ctmp[0],
267  locRows,
268  mpi_complex,
270  mpi_comm[i]);
271  }
272  }
273 
274 
275  for(i=0;i<locRows;i++){
276  /*
277  printf("(%d) %d %f %f - %f %f\n",rank,i,
278  CREAL(solution->rhs[i]),CIMAG(solution->rhs[i]),
279  CREAL(ctmp[i]),CIMAG(ctmp[i]));
280  */
281 
282  solution->rhs[i] = ctmp[i];
283  }
284  }
285 
286 
287  if(psiuvec) free(psiuvec);
288  if(psincvec) free(psincvec);
289  if(phincvec) free(phincvec);
290  if(ctmp) free(ctmp);
291 #ifdef _ACOUSTO_DEBUG
292 FILE* f;
293 char fname[64];
294 int ipsiu;
295  sprintf(fname,"maty.%d%d",runinfo->myrow,runinfo->mycol);
296  f = fopen(fname,"w");
297  for(i=0;i<locRows;i++){ // LOOP ON ROWS
299  for(j=0;j<locCols;j++){ // LOOP on COLS
301  fprintf(f,"%d %d %f %f\n",icntr,ipsiu,CREAL(solution->matY[i+locRows*j]), CIMAG(solution->matY[i+locRows*j]));
302  }
303  }
304  fclose(f);
305 
306 
307 
308 
309  sprintf(fname,"rhs.%d.out",modgeominfo->nelmb);
310  f = fopen(fname,"w");
311  for(i=0;i<locRows;i++){ // LOOP ON ROWS
313  fprintf(f,"%f %f %f %f %f %f\n",
314  geometry->cntr[icntr].x,
315  geometry->cntr[icntr].y,
316  geometry->cntr[icntr].z,
317  CREAL(solution->rhs[i]),
318  CIMAG(solution->rhs[i]),
319  CABS(solution->rhs[i]));
320  }
321  fclose(f);
322 
323 #endif
324 #undef _ACOUSTO_DEBUG
325 
326 #ifdef _ACOUSTO_DEBUG
327 FILE* f;
328 char fname[64];
329  sprintf(fname,"rhs.%d.out",modgeominfo->nelmb);
330  f = fopen(fname,"w");
331  for(i=0;i<locRows;i++){ // LOOP ON ROWS
333  fprintf(f,"%f %f %f %f %f %f\n",
334  geometry->cntr[icntr].x,
335  geometry->cntr[icntr].y,
336  geometry->cntr[icntr].z,
337  CREAL(solution->rhs[i]),
338  CIMAG(solution->rhs[i]),
339  CABS(solution->rhs[i]));
340  }
341  fclose(f);
342 
343 #endif
344 #undef _ACOUSTO_DEBUG
345 }
struct run_info * runinfo
Definition: globals.h:34
#define Vec
Definition: types.h:63
int npcols
Definition: structs.h:113
int ncntr
Definition: structs.h:299
DOUBLE vsound
Definition: structs.h:102
COMPLEX * matY
Definition: structs.h:603
MPI_Datatype mpi_complex
Definition: globals.h:93
#define CREAL(x)
Definition: functions.h:49
void delaya(DOUBLE *theta, int ielmb, struct panel4 *element, struct vector xc)
Definition: integrals.c:268
#define MPI_ACOUSTO_COMPLEX
Definition: types.h:56
Vec vecPsinc
Definition: structs.h:580
int myrow
Definition: structs.h:115
void vec_copy(struct vector *vdest, const struct vector vsrc)
Definition: math.c:158
int nprows
Definition: structs.h:111
vector struct to hold triplets.
Definition: structs.h:29
#define CIMAG(x)
Definition: functions.h:50
COMPLEX * lambda
Definition: structs.h:623
int nchief
Definition: structs.h:301
MPI_Op mpi_op_complex_sum
Definition: globals.h:124
#define LOG_INFO
Definition: logger.h:26
void pzgemr2d_(int *m, int *n, COMPLEX *A, int *ia, int *ja, int *desca, COMPLEX *B, int *ib, int *jb, int *descb, int *ictxt)
Copies a (m x n) submatrix of A from element (ia,ja) on a submatrix of B from element (ib...
struct bc_struct bc
Definition: globals.h:54
int nelmb
Definition: structs.h:295
#define CEXP(x)
Definition: functions.h:48
Vec vecPhinc
Definition: structs.h:578
#define COMPLEX_ZERO
Definition: constants.h:44
int ctxt
Definition: structs.h:109
int knw
Definition: structs.h:446
Definition of a quadrilateral panel.
Definition: structs.h:44
void descinit_(int *desc, int *m, int *n, int *mb, int *nb, int *ia, int *ja, int *ictxt, int *llda, int *info)
struct solution_struct * solution
Definition: globals.h:52
#define COMPLEX
Definition: types.h:48
#define CABS(x)
Definition: functions.h:51
Vec vecPsiu
Definition: structs.h:584
struct modsol_info * modsolinfo
Definition: globals.h:44
DOUBLE z
Definition: structs.h:35
struct vector g
Definition: structs.h:626
DOUBLE vec_dot(struct vector v1, struct vector v2)
Definition: math.c:34
COMPLEX * gamma
Definition: structs.h:624
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)
DOUBLE x
Definition: structs.h:31
#define CREATE_VEC(v, lsize)
Definition: allocation.h:90
int col_block_size
Definition: structs.h:121
COMPLEX * func
Definition: structs.h:625
void intgba(int kcrce, int kelem, int kode, struct vector *xcntr, struct panel4 *element, DOUBLE *source, DOUBLE *doublet, DOUBLE *ratelet)
Definition: integrals.c:40
Geometry info structure.
Definition: structs.h:161
COMPLEX * rhs
Definition: structs.h:605
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
#define VecZeroEntries(V, n)
Definition: allocation.h:99
DOUBLE y
Definition: structs.h:33
int dirneu
Definition: structs.h:444