AcouSTO  version 2.0

◆ matyfd()

void matyfd ( COMPLEX  cfreq,
int  icounter 
)

Evaluates Matrix Y and RHS of the linear System. Valid for Neumann-type & Dirichlet-type Boundary Conditions. Coefficients are read from file.

Parameters
cfreqCOMPLEX frequency
icounterindex of frequency
37  {
38 
39  int icntr;
40  int ielmb,ielmu;
41  int nphiu;
42  int nphib;
43 
44  int mpi_ncntr,mpi_nelmu;
45  COMPLEX cexpc;
46  DOUBLE bb,cc,dd,thetac,estar;
47  COMPLEX matval;
48  COMPLEX yy = 0.0 + I*0.0;;
49  int cstride,bstride;
50  struct panel4* mpi_elements;
51 
52  //DOUBLE *C;
53 
54  Vec psiuvec;
55  Vec psincvec;
56  Vec phincvec;
57  int gCRows;
58  int nn;
59  int mm;
60  int descpsiu[9];
61  int descgpsiu[9];
62  int ione = 1;
63  int info;
64 
65 
66  int gRows,gCols; // global dim of coefficient matrix
67  int locRows,locCols; // local dim of coefficient matrix
68  int izero = 0;
69  int i,j;
70  COMPLEX* ctmp;
71 
72 #ifdef _ACOUSTO_DEBUG
73  FILE* f;
74  FILE* cmatfile;
75  char fname[15];
76  int ipsiu;
77 #endif
78 
79  FILE* fccoef = NULL;
80  FILE* fbcoef = NULL;
81  int nrow,nrowi,iloop,nloop,irow,nio,nrlast;
82  char fcname[MAX_PATH];
83  char fbname[MAX_PATH];
84 
85  int ic,is,ib;
86  int csymmoffset,bsymmoffset;
87  COMPLEX lambda;
88  COMPLEX gamma;
89  COMPLEX func;
90  COMPLEX gamma_over_lambda;
91  COMPLEX lambda_over_gamma;
92  DOUBLE gdotn;
93  struct vector g;
94  struct vector un;
95 
96  MPI_Group* mpi_row_groups;
97  MPI_Group mpi_group_world;
98  MPI_Comm* mpi_comm;
99  int* row_ranks;
100  int ierr;
101 
102  // number of control points,phib and phiu points
103  mpi_elements = geometry->elements;
104  mpi_ncntr = modgeominfo->ncntr + modgeominfo->nchief;
105  nphiu = modgeominfo->ncntr;
106  nphib = modgeominfo->nelmb;
107  mpi_nelmu = nphiu;
108 
109  gRows = mpi_ncntr;
110  gCols = nphiu;
111 
112 
113 #ifdef _ACOUSTO_DEBUG
114  cmatfile = fopen("CD.matrix.out","w");
115  fprintf(cmatfile,"CD=[");
116 #endif
117 
118  logger(LOG_INFO,"bc %d\n",modsolinfo->dirneu);
119 
120 
121  locRows = numroc_(&gRows ,&runinfo->row_block_size,&runinfo->myrow,&izero,&runinfo->nprows);
122  locCols = numroc_(&gCols ,&runinfo->col_block_size,&runinfo->mycol,&izero,&runinfo->npcols);
123  cstride = locRows * locCols; // C stride
124 
125  // nrow partition on node to limit memory usage (see manual)
126  nrow = runinfo->krow;
127  if(runinfo->krow <= 0 || runinfo->krow >= locRows) nrow = locRows;
128 
129  // nrow partition on node to limit memory usage (see manual)
130  if (solution->matY == NULL) {
131  solution->matY = calloc(locRows*locCols,sizeof(COMPLEX)); // allocation
132  } else {
133  for(i = 0; i < locRows*locCols; i++)
134  solution->matY[i] = COMPLEX_ZERO;
135  }
136 
137  gCRows = nphiu;
138  psiuvec = calloc(nphiu,sizeof(COMPLEX)); // allocating vector
139  psincvec = calloc(nphiu,sizeof(COMPLEX)); // allocating vector
140  phincvec = calloc(nphiu,sizeof(COMPLEX)); // allocating vector
141  mm = gCRows;// * runinfo->nprows;
142  nn = runinfo->npcols;
143  descinit_(descpsiu , &gCRows ,&ione, &runinfo->row_block_size ,&ione,&izero,&izero,&runinfo->ctxt,&gCRows ,&info);
144  descinit_(descgpsiu , &mm ,&ione, &gCRows ,&ione,&izero,&izero,&runinfo->ctxt,&gCRows ,&info);
145  pzgemr2d_(&gCRows,&ione,solution->vecPsiu ,&ione, &ione,descpsiu, psiuvec ,&ione,&ione,descgpsiu,&runinfo->ctxt);
146  pzgemr2d_(&gCRows,&ione,solution->vecPsinc,&ione, &ione,descpsiu, psincvec,&ione,&ione,descgpsiu,&runinfo->ctxt);
147  pzgemr2d_(&gCRows,&ione,solution->vecPhinc,&ione, &ione,descpsiu, phincvec,&ione,&ione,descgpsiu,&runinfo->ctxt);
148 
149  MPI_Bcast(psiuvec ,gCRows,MPI_ACOUSTO_COMPLEX,0,MPI_COMM_WORLD);
150  MPI_Bcast(psincvec,gCRows,MPI_ACOUSTO_COMPLEX,0,MPI_COMM_WORLD);
151  MPI_Bcast(phincvec,gCRows,MPI_ACOUSTO_COMPLEX,0,MPI_COMM_WORLD);
152 
153  CREATE_VEC(solution->rhs,locRows); // allocation
154  VecZeroEntries(solution->rhs,locRows); // reset
155 
156  CREATE_VEC(ctmp,locRows); // allocation
157 
158 
159  if(runinfo->krow > 0){
160  // C coefficients (calculated in ac_body_coefs.c)
161  bodycoefs->C = calloc(4*nrow*locCols*runinfo->nsymm,sizeof(DOUBLE));
162  bodycoefs->B = calloc(2*nrow*locCols*runinfo->nsymm,sizeof(DOUBLE));
163  }
164 
165  j12(locRows,nrow,&nrlast,&nloop); // calculating last number of rows and number of loops
166 
167  if(runinfo->krow > 0){
168  get_filename(fbname,"bbcoefs.bin.%d",rank); // B coefficients file name
169  fbcoef = fopen(fbname,"rb");
170  }
171  if(runinfo->krow > 0){
172  get_filename(fcname,"bccoefs.bin.%d",rank); // name of file with C Coefficients
173  fccoef = fopen(fcname,"rb");
174  }
175 
176  for(iloop=0;iloop<nloop;iloop++){ // LOOP ON NLOOP
177  nrowi = nrow;
178  if(iloop == nloop-1) nrowi = nrlast;
179  cstride = nrowi*locCols;
180  bstride = nrowi*locCols; // B stride
181 
182  if(runinfo->krow > 0){
183  nio = fread(bodycoefs->C,sizeof(DOUBLE),4*nrowi*locCols*runinfo->nsymm,fccoef); // reading from file
184  nio = fread(bodycoefs->B,sizeof(DOUBLE),2*nrowi*locCols*runinfo->nsymm,fbcoef); // Reading from file nrowi rows for this partition
185  }
186  for(irow=0;irow<nrowi;irow++){ // LOOP ON NROW
187  i= j21(irow,iloop,nrow);
189 
190  if(modsolinfo->knw == 1){
191  if(runinfo->mycol == 0){
192  if (modsolinfo->dirneu == 1) solution->rhs[i] = -phincvec[icntr]; // DIRICHLET-TYPE
193  if (modsolinfo->dirneu == 2) solution->rhs[i] = phincvec[icntr]; // NEUMANN-TYPE
194  }else{
195  solution->rhs[i] = COMPLEX_ZERO;
196  }
197  }else{
198  solution->rhs[i] = COMPLEX_ZERO;
199  }
200 
201  for(j=0;j<locCols;j++){ // LOOP ON NELMB
203  ic = irow*locCols +j;
204  ib = irow*locCols +j;
205 
206  estar = (icntr == ielmu ) ? 0.5 : 0.0;
207  solution->matY[locRows*j + i ] += estar;
208  for(is=0;is<runinfo->nsymm;is++){
209 
210  ielmb = ielmu + is*mpi_nelmu;
211 
212  csymmoffset = is * 4*nrowi*locCols;
213  bsymmoffset = is * 2*nrowi*locCols;
214 
215  bb = bodycoefs->B[ib + bsymmoffset];
216  cc = bodycoefs->C[ic + csymmoffset];
217  dd = bodycoefs->C[ic + cstride + csymmoffset];
218  thetac = bodycoefs->C[ic + cstride*2 + csymmoffset];
219  cexpc = CEXP(-cfreq*thetac);
220 
221  vec_copy(&un,mpi_elements[ielmb].n);
222  lambda = bc.lambda[ielmu];
223  gamma = bc.gamma[ielmu];
224  func = bc.func[ielmu];
225  gamma_over_lambda = gamma/lambda;
226  lambda_over_gamma = lambda/gamma;
227  g.x = bc.g.x;
228  g.y = bc.g.y;
229  g.z = bc.g.z;
230  gdotn = vec_dot(g,un);
231  matval = (cc+cfreq*dd) * cexpc ;
232  //
233  // THIS IS CLASSICAL YMAT=E*I-(C+s*D). NEEDED TO BUILD NEUMANN & DIRICHLET RHSs.
234  // NOTE: matval includes delay
235  //
236  solution->matY[locRows*j + i ] -= matval;
237  yy = solution->matY[locRows*j + i ];
238 
239  if(modsolinfo->knw == 1){
240  if (modsolinfo->dirneu == 1) solution->rhs[i] += yy * (func+gdotn)/gamma; // DIRICHLET
241  if (modsolinfo->dirneu == 2) solution->rhs[i] += bb * cexpc * (func+gdotn)/lambda; // NEUMANN
242  }else if(modsolinfo->knw == 2){
243  if (modsolinfo->dirneu == 1) solution->rhs[i] += yy * ((func+gdotn)/gamma - psincvec[ielmu]*lambda_over_gamma - phincvec[ielmu]); // DIRICHLET
244  if (modsolinfo->dirneu == 2) solution->rhs[i] += bb * cexpc*((func+gdotn)/lambda - phincvec[ielmu]*gamma_over_lambda - psincvec[ielmu]); // NEUMANN
245  }
246  //
247  // HERE SYSTEM MATRIX IS BUILT ON YMAT.
248  //
249  if (modsolinfo->dirneu == 1) solution->matY[locRows*j + i ] = bb*cexpc + yy * lambda_over_gamma; //DIRICHLET (matrix entry is rewritten)
250  if (modsolinfo->dirneu == 2) solution->matY[locRows*j + i ] += bb * gamma_over_lambda *cexpc; //NEUMANN (matrix entry is updated)
251 
252 #ifdef _ACOUSTO_DEBUG
253  fprintf(cmatfile,"%f + %%i*%f ,",CREAL(solution->matY[locRows*j + i ]),CIMAG(solution->matY[locRows*j + i ]));;
254 #endif
255 
256  }
257  } // END OF LOOP ON NELMB
258 #ifdef _ACOUSTO_DEBUG
259  fprintf(cmatfile,";\n");
260 #endif
261  } // END OF LOOP ON NROW
262  } // END OF LOOP ON NLOOP
263 
264 #ifdef _ACOUSTO_DEBUG
265  fprintf(cmatfile,"];\n");
266 #endif
267 
268 
269  if(runinfo->krow > 0){
270  free(bodycoefs->B);
271  free(bodycoefs->C);
272  }
273 
274  // Reducing RHS if cols in proc grid are > 1
275  if(runinfo->npcols > 1){
276  logger(LOG_INFO," Reducing RHS on columns\n");
277  mpi_row_groups = calloc(sizeof(MPI_Group) , runinfo->nprows);
278  mpi_comm = calloc(sizeof(MPI_Comm) , runinfo->nprows);
279  row_ranks = calloc(sizeof(int) , runinfo->npcols);
280  MPI_Comm_group(MPI_COMM_WORLD, &mpi_group_world);
281  for(i=0;i<runinfo->nprows;i++){
282  for(j=0;j<runinfo->npcols;j++){
283  row_ranks[j] = j + i*runinfo->npcols;
284  }
285  ierr = MPI_Group_incl(mpi_group_world,runinfo->npcols,row_ranks,&mpi_row_groups[i]);
286  ierr = MPI_Comm_create(MPI_COMM_WORLD, mpi_row_groups[i], &mpi_comm[i]);
287  }
288 
289  for(i=0;i<runinfo->nprows;i++){
290 
291  if(MPI_COMM_NULL != mpi_comm[i]){
292  MPI_Allreduce((void*)solution->rhs,
293  (void*)&ctmp[0],
294  locRows,
295  mpi_complex,
297  mpi_comm[i]);
298  }
299 // MPI_COMM_WORLD);
300  }
301 
302  for(i=0;i<locRows;i++){
303  solution->rhs[i] = ctmp[i];
304 // printf("%d %f %f %f %f\n",i, CREAL(solution->rhs[i]),CIMAG(solution->rhs[i]),CREAL(phincvec[i]),CIMAG(phincvec[i]));
305  }
306  }
307 #ifdef _ACOUSTO_DEBUG
308  sprintf(fname,"maty.%d%d",runinfo->myrow,runinfo->mycol);
309  f = fopen(fname,"w");
310  for(i=0;i<locRows;i++){ // LOOP ON ROWS
312  for(j=0;j<locCols;j++){ // LOOP on COLS
314  fprintf(f,"%d %d %f %f\n",icntr,ipsiu,CREAL(solution->matY[i+locRows*j]), CIMAG(solution->matY[i+locRows*j]));
315  }
316  }
317  fclose(f);
318 
319  fclose(cmatfile);
320 #endif
321  if(psiuvec ) free(psiuvec);
322  if(psincvec ) free(psincvec);
323  if(phincvec ) free(phincvec);
324  if(ctmp ) free(ctmp);
325 
326 }
struct bodycoefs_struct * bodycoefs
Definition: globals.h:48
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
COMPLEX * matY
Definition: structs.h:603
MPI_Datatype mpi_complex
Definition: globals.h:93
#define CREAL(x)
Definition: functions.h:49
#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
void get_filename(char *filename, const char *format,...)
Definition: utils.c:59
vector struct to hold triplets.
Definition: structs.h:29
#define CIMAG(x)
Definition: functions.h:50
DOUBLE * B
Definition: structs.h:385
COMPLEX * lambda
Definition: structs.h:623
int nchief
Definition: structs.h:301
MPI_Op mpi_op_complex_sum
Definition: globals.h:124
DOUBLE * C
Definition: structs.h:387
#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
Vec vecPsiu
Definition: structs.h:584
struct modsol_info * modsolinfo
Definition: globals.h:44
DOUBLE z
Definition: structs.h:35
void j12(int i12, int n1, int *i1, int *i2)
Definition: math.c:206
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 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
#define CREATE_VEC(v, lsize)
Definition: allocation.h:90
int col_block_size
Definition: structs.h:121
COMPLEX * func
Definition: structs.h:625
int krow
Definition: structs.h:105
Geometry info structure.
Definition: structs.h:161
#define MAX_PATH
Definition: constants.h:29
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