46 #include "Parser_dh.h" 
   56 #define CENTER(a) a[0] 
   62 static void setBoundary_private (
int node, 
int *cval, 
double *aval, 
int len,
 
   63                  double *rhs, 
double bc, 
double coeff,
 
   64                  double ctr, 
int nabor);
 
   65 static void generateStriped (
MatGenFD mg, 
int *rp, 
int *cval, 
double *aval,
 
   67 static void generateBlocked (
MatGenFD mg, 
int *rp, 
int *cval, 
double *aval,
 
   69 static void getstencil (
MatGenFD g, 
int ix, 
int iy, 
int iz);
 
   72 static void fdaddbc (
int nx, 
int ny, 
int nz, 
int *rp, 
int *cval,
 
   73              int *diag, 
double *aval, 
double *rhs, 
double h,
 
   78 #define __FUNC__ "MatGenFDCreate" 
   88   tmp->debug = Parser_dhHasSwitch (parser_dh, 
"-debug_matgen");
 
   91   tmp->px = tmp->py = 1;
 
   93   Parser_dhReadInt (parser_dh, 
"-m", &tmp->m);
 
   94   Parser_dhReadInt (parser_dh, 
"-px", &tmp->px);
 
   95   Parser_dhReadInt (parser_dh, 
"-py", &tmp->py);
 
   96   Parser_dhReadInt (parser_dh, 
"-pz", &tmp->pz);
 
  113   if (Parser_dhHasSwitch (parser_dh, 
"-threeD"))
 
  116   tmp->a = tmp->b = tmp->c = 1.0;
 
  117   tmp->d = tmp->e = tmp->f = 0.0;
 
  118   tmp->g = tmp->h = 0.0;
 
  120   Parser_dhReadDouble (parser_dh, 
"-dx", &tmp->a);
 
  121   Parser_dhReadDouble (parser_dh, 
"-dy", &tmp->b);
 
  122   Parser_dhReadDouble (parser_dh, 
"-dz", &tmp->c);
 
  123   Parser_dhReadDouble (parser_dh, 
"-cx", &tmp->d);
 
  124   Parser_dhReadDouble (parser_dh, 
"-cy", &tmp->e);
 
  125   Parser_dhReadDouble (parser_dh, 
"-cz", &tmp->f);
 
  127   tmp->a = -1 * fabs (tmp->a);
 
  128   tmp->b = -1 * fabs (tmp->b);
 
  129   tmp->c = -1 * fabs (tmp->c);
 
  131   tmp->allocateMem = 
true;
 
  133   tmp->A = tmp->B = tmp->C = tmp->D = tmp->E
 
  134     = tmp->F = tmp->G = tmp->H = konstant;
 
  136   tmp->bcX1 = tmp->bcX2 = tmp->bcY1 = tmp->bcY2 = tmp->bcZ1 = tmp->bcZ2 = 0.0;
 
  137   Parser_dhReadDouble (parser_dh, 
"-bcx1", &tmp->bcX1);
 
  138   Parser_dhReadDouble (parser_dh, 
"-bcx2", &tmp->bcX2);
 
  139   Parser_dhReadDouble (parser_dh, 
"-bcy1", &tmp->bcY1);
 
  140   Parser_dhReadDouble (parser_dh, 
"-bcy2", &tmp->bcY2);
 
  141   Parser_dhReadDouble (parser_dh, 
"-bcz1", &tmp->bcZ1);
 
  142   Parser_dhReadDouble (parser_dh, 
"-bcz2", &tmp->bcZ2);
 
  147 #define __FUNC__ "MatGenFD_Destroy" 
  151   START_FUNC_DH FREE_DH (mg);
 
  157 #define __FUNC__ "MatGenFD_Run" 
  171   bool threeD = mg->threeD;
 
  174   bool debug = 
false, striped;
 
  176   if (mg->debug && logFile != NULL)
 
  178   striped = Parser_dhHasSwitch (parser_dh, 
"-striped");
 
  183   Vec_dhCreate (rhsOut);
 
  191   if (!Parser_dhHasSwitch (parser_dh, 
"-noChecks"))
 
  195       int npTest = mg->px * mg->py;
 
  201                "numbers don't match: np_dh = %i, px*py*pz = %i", np,
 
  203           SET_V_ERROR (msgBuf_dh);
 
  213       m = mg->m = m * m * m;
 
  221   mg->hh = 1.0 / (mg->px * mg->cc - 1);
 
  225       sprintf (msgBuf_dh, 
"cc (local grid dimension) = %i", mg->cc);
 
  226       SET_INFO (msgBuf_dh);
 
  229       sprintf (msgBuf_dh, 
"threeD = true");
 
  233       sprintf (msgBuf_dh, 
"threeD = false");
 
  235       SET_INFO (msgBuf_dh);
 
  236       sprintf (msgBuf_dh, 
"np= %i  id= %i", np, 
id);
 
  237       SET_INFO (msgBuf_dh);
 
  242   nnz = threeD ? m * 7 : m * 5;
 
  247       A->rp = (
int *) MALLOC_DH ((m + 1) * 
sizeof (int));
 
  250       A->cval = (
int *) MALLOC_DH (nnz * 
sizeof (
int));
 
  251       CHECK_V_ERROR A->aval = (
double *) MALLOC_DH (nnz * 
sizeof (
double));
 
  260   A->beg_row = mg->first;
 
  264   if (Parser_dhHasSwitch (parser_dh, 
"-striped"))
 
  266       generateStriped (mg, A->rp, A->cval, A->aval, A, rhs);
 
  271       generateBlocked (mg, A->rp, A->cval, A->aval, A, rhs);
 
  286 #define __FUNC__ "generateStriped" 
  288 generateStriped (
MatGenFD mg, 
int *rp, 
int *cval, 
double *aval, 
Mat_dh A,
 
  291   START_FUNC_DH 
int mGlobal;
 
  293   int beg_row, end_row;
 
  295   bool threeD = mg->threeD;
 
  297   double *stencil = mg->stencil;
 
  299   int plane, nodeRemainder;
 
  300   int naborx1, naborx2, nabory1, nabory2;
 
  303   bool applyBdry = 
true;
 
  305   double bcx1 = mg->bcX1;
 
  306   double bcx2 = mg->bcX2;
 
  307   double bcy1 = mg->bcY1;
 
  308   double bcy2 = mg->bcY2;
 
  313   printf_dh (
"@@@ using striped partitioning\n");
 
  315   if (mg->debug && logFile != NULL)
 
  320   Parser_dhReadInt (parser_dh, 
"-m", &m);   
 
  324   i = mGlobal / mg->np;     
 
  325   beg_row = i * mg->id;     
 
  326   end_row = beg_row + i;
 
  327   if (mg->id == mg->np - 1)
 
  331   mg->hh = 1.0 / (m - 1);
 
  332   hhalf = 0.5 * mg->hh;
 
  335   A->m = end_row - beg_row;
 
  336   A->beg_row = beg_row;
 
  338   Vec_dhInit (b, A->m);
 
  346       fprintf (logFile, 
"generateStriped: beg_row= %i; end_row= %i; m= %i\n",
 
  347            beg_row + 1, end_row + 1, m);
 
  350   for (row = beg_row; row < end_row; ++row)
 
  352       int localRow = row - beg_row;
 
  356       nodeRemainder = row - (k * plane);    
 
  357       j = nodeRemainder / m;
 
  358       i = nodeRemainder % m;
 
  362       fprintf (logFile, 
"row= %i  x= %i  y= %i  z= %i\n", row + 1, i, j,
 
  367       getstencil (mg, i, j, k);
 
  376           cval[idx] = row - plane;
 
  377           aval[idx++] = BACK (stencil);
 
  384       nabory1 = cval[idx] = row - m;
 
  385       aval[idx++] = SOUTH (stencil);
 
  391       naborx1 = cval[idx] = row - 1;
 
  392       aval[idx++] = WEST (stencil);
 
  397       aval[idx++] = CENTER (stencil);
 
  402       naborx2 = cval[idx] = row + 1;
 
  403       aval[idx++] = EAST (stencil);
 
  409       nabory2 = cval[idx] = row + m;
 
  410       aval[idx++] = NORTH (stencil);
 
  418           cval[idx] = row + plane;
 
  419           aval[idx++] = FRONT (stencil);
 
  427       if (!threeD && applyBdry)
 
  429       int offset = rp[localRow - 1];
 
  430       int len = rp[localRow] - rp[localRow - 1];
 
  437           coeff = mg->A (mg->a, i + hhalf, j, k);
 
  438           ctr = mg->A (mg->a, i - hhalf, j, k);
 
  439           setBoundary_private (row, cval + offset, aval + offset, len,
 
  440                    &(rhs[localRow - 1]), bcx1, coeff, ctr,
 
  443       else if (i == nx - 1)
 
  445           coeff = mg->A (mg->a, i - hhalf, j, k);
 
  446           ctr = mg->A (mg->a, i + hhalf, j, k);
 
  447           setBoundary_private (row, cval + offset, aval + offset, len,
 
  448                    &(rhs[localRow - 1]), bcx2, coeff, ctr,
 
  453           coeff = mg->B (mg->b, i, j + hhalf, k);
 
  454           ctr = mg->B (mg->b, i, j - hhalf, k);
 
  455           setBoundary_private (row, cval + offset, aval + offset, len,
 
  456                    &(rhs[localRow - 1]), bcy1, coeff, ctr,
 
  459       else if (j == ny - 1)
 
  461           coeff = mg->B (mg->b, i, j - hhalf, k);
 
  462           ctr = mg->B (mg->b, i, j + hhalf, k);
 
  463           setBoundary_private (row, cval + offset, aval + offset, len,
 
  464                    &(rhs[localRow - 1]), bcy2, coeff, ctr,
 
  481 rownum (
const bool threeD, 
const int x, 
const int y, 
const int z,
 
  482     const int nx, 
const int ny, 
const int nz, 
int P, 
int Q)
 
  485   int lowerx, lowery, lowerz;
 
  507       id = r * P * Q + q * P + p;
 
  518   startrow = 
id * (nx * ny * nz);
 
  527       return startrow + nx * ny * (z - lowerz) + nx * (y - lowery) + (x -
 
  532       return startrow + nx * (y - lowery) + (x - lowerx);
 
  539 getstencil (
MatGenFD g, 
int ix, 
int iy, 
int iz)
 
  543   double hhalf = h * 0.5;
 
  548   double *stencil = g->stencil;
 
  550   bool threeD = g->threeD;
 
  552   for (k = 0; k < 8; ++k)
 
  556   coeff = g->A (g->a, x + hhalf, y, z);
 
  557   EAST (stencil) += coeff;
 
  560   coeff = g->A (g->a, x - hhalf, y, z);
 
  561   WEST (stencil) += coeff;
 
  564   coeff = g->D (g->d, x, y, z) * hhalf;
 
  565   EAST (stencil) += coeff;
 
  566   WEST (stencil) -= coeff;
 
  569   coeff = g->B (g->b, x, y + hhalf, z);
 
  570   NORTH (stencil) += coeff;
 
  573   coeff = g->B (g->b, x, y - hhalf, z);
 
  574   SOUTH (stencil) += coeff;
 
  577   coeff = g->E (g->e, x, y, z) * hhalf;
 
  578   NORTH (stencil) += coeff;
 
  579   SOUTH (stencil) -= coeff;
 
  584       coeff = g->C (g->c, x, y, z + hhalf);
 
  585       BACK (stencil) += coeff;
 
  588       coeff = g->C (g->c, x, y, z - hhalf);
 
  589       FRONT (stencil) += coeff;
 
  592       coeff = g->F (g->f, x, y, z) * hhalf;
 
  593       BACK (stencil) += coeff;
 
  594       FRONT (stencil) -= coeff;
 
  598   coeff = g->G (g->g, x, y, z);
 
  599   CENTER (stencil) = h * h * coeff - cntr;
 
  601   RHS (stencil) = h * h * g->H (g->h, x, y, z);
 
  606 konstant (
double coeff, 
double x, 
double y, 
double z)
 
  612 e2_xy (
double coeff, 
double x, 
double y, 
double z)
 
  614   return exp (coeff * x * y);
 
  617 double boxThreeD (
double coeff, 
double x, 
double y, 
double z);
 
  625 box_1 (
double coeff, 
double x, 
double y, 
double z)
 
  627   static bool setup = 
false;
 
  628   double retval = coeff;
 
  631   static double dd1 = BOX1_DD;
 
  632   static double dd2 = BOX2_DD;
 
  633   static double dd3 = BOX3_DD;
 
  636   static double ax1 = BOX1_X1, ay1 = BOX1_Y1;
 
  637   static double ax2 = BOX1_X2, ay2 = BOX1_Y2;
 
  638   static double bx1 = BOX2_X1, by1 = BOX2_Y1;
 
  639   static double bx2 = BOX2_X2, by2 = BOX2_Y2;
 
  640   static double cx1 = BOX3_X1, cy1 = BOX3_Y1;
 
  641   static double cx2 = BOX3_X2, cy2 = BOX3_Y2;
 
  645       return (boxThreeD (coeff, x, y, z));
 
  655       Parser_dhReadDouble (parser_dh, 
"-dd1", &dd1);
 
  656       Parser_dhReadDouble (parser_dh, 
"-dd2", &dd2);
 
  657       Parser_dhReadDouble (parser_dh, 
"-dd3", &dd3);
 
  658       Parser_dhReadDouble (parser_dh, 
"-box1x1", &cx1);
 
  659       Parser_dhReadDouble (parser_dh, 
"-box1x2", &cx2);
 
  664   if (x > ax1 && x < ax2 && y > ay1 && y < ay2)
 
  666       retval = dd1 * coeff;
 
  670   if (x > bx1 && x < bx2 && y > by1 && y < by2)
 
  672       retval = dd2 * coeff;
 
  676   if (x > cx1 && x < cx2 && y > cy1 && y < cy2)
 
  678       retval = dd3 * coeff;
 
  685 boxThreeD (
double coeff, 
double x, 
double y, 
double z)
 
  687   static bool setup = 
false;
 
  688   double retval = coeff;
 
  691   static double dd1 = 100;
 
  694   static double x1 = .2, x2 = .8;
 
  695   static double y1 = .3, y2 = .7;
 
  696   static double z1 = .4, z2 = .6;
 
  701       Parser_dhReadDouble (parser_dh, 
"-dd1", &dd1);
 
  706   if (x > x1 && x < x2 && y > y1 && y < y2 && z > z1 && z < z2)
 
  708       retval = dd1 * coeff;
 
  716 box_1 (
double coeff, 
double x, 
double y, 
double z)
 
  718   static double x1, x2, y1, y2;
 
  719   static double d1, d2;
 
  734       Parser_dhReadDouble (parser_dh, 
"-bx1", &x1);
 
  735       Parser_dhReadDouble (parser_dh, 
"-bx2", &x2);
 
  736       Parser_dhReadDouble (parser_dh, 
"-by1", &y1);
 
  737       Parser_dhReadDouble (parser_dh, 
"-by2", &y2);
 
  738       Parser_dhReadDouble (parser_dh, 
"-bd1", &d1);
 
  739       Parser_dhReadDouble (parser_dh, 
"-bd2", &d2);
 
  746   if (x > x1 && x < x2 && y > y1 && y < y2)
 
  759 box_2 (
double coeff, 
double x, 
double y, 
double z)
 
  762   static double d1, d2;
 
  769       Parser_dhReadDouble (parser_dh, 
"-bd1", &d1);
 
  770       Parser_dhReadDouble (parser_dh, 
"-bd2", &d2);
 
  775   if (x < .5 && y < .5)
 
  777   if (x > .5 && y > .5)
 
  785 #define __FUNC__ "generateBlocked" 
  787 generateBlocked (
MatGenFD mg, 
int *rp, 
int *cval, 
double *aval, 
Mat_dh A,
 
  790   START_FUNC_DH 
bool applyBdry = 
true;
 
  791   double *stencil = mg->stencil;
 
  793   bool threeD = mg->threeD;
 
  794   int px = mg->px, py = mg->py, pz = mg->pz;    
 
  797   int nx = cc, ny = cc, nz = cc;
 
  798   int lowerx, upperx, lowery, uppery, lowerz, upperz;
 
  802   int idx = 0, localRow = 0;    
 
  803   int naborx1, naborx2, nabory1, nabory2, naborz1, naborz2;
 
  806   double hhalf = 0.5 * mg->hh;
 
  807   double bcx1 = mg->bcX1;
 
  808   double bcx2 = mg->bcX2;
 
  809   double bcy1 = mg->bcY1;
 
  810   double bcy2 = mg->bcY2;
 
  814   Vec_dhInit (b, A->m);
 
  818   if (mg->debug && logFile != NULL)
 
  825   q = ((
id - p) / px) % py;
 
  826   r = (
id - p - px * q) / (px * py);
 
  831            "this proc's position in subdomain grid: p= %i  q= %i  r= %i",
 
  833       SET_INFO (msgBuf_dh);
 
  840   upperx = lowerx + nx;
 
  842   uppery = lowery + ny;
 
  844   upperz = lowerz + nz;
 
  848       sprintf (msgBuf_dh, 
"local grid parameters: lowerx= %i  upperx= %i",
 
  850       SET_INFO (msgBuf_dh);
 
  851       sprintf (msgBuf_dh, 
"local grid parameters: lowery= %i  uppery= %i",
 
  853       SET_INFO (msgBuf_dh);
 
  854       sprintf (msgBuf_dh, 
"local grid parameters: lowerz= %i  upperz= %i",
 
  856       SET_INFO (msgBuf_dh);
 
  859   startRow = mg->first;
 
  862   for (z = lowerz; z < upperz; z++)
 
  864       for (y = lowery; y < uppery; y++)
 
  866       for (x = lowerx; x < upperx; x++)
 
  871           fprintf (logFile, 
"row= %i  x= %i  y= %i  z= %i\n",
 
  872                localRow + startRow + 1, x, y, z);
 
  876           getstencil (mg, x, y, z);
 
  884             rownum (threeD, x, y, z - 1, nx, ny, nz, px, py);
 
  886               aval[idx++] = FRONT (stencil);
 
  893           nabory1 = rownum (threeD, x, y - 1, z, nx, ny, nz, px, py);
 
  895           aval[idx++] = SOUTH (stencil);
 
  901           naborx1 = rownum (threeD, x - 1, y, z, nx, ny, nz, px, py);
 
  903           aval[idx++] = WEST (stencil);
 
  914           cval[idx] = localRow + startRow;
 
  915           aval[idx++] = CENTER (stencil);
 
  921           naborx2 = rownum (threeD, x + 1, y, z, nx, ny, nz, px, py);
 
  923           aval[idx++] = EAST (stencil);
 
  934           nabory2 = rownum (threeD, x, y + 1, z, nx, ny, nz, px, py);
 
  936           aval[idx++] = NORTH (stencil);
 
  945             rownum (threeD, x, y, z + 1, nx, ny, nz, px, py);
 
  947               aval[idx++] = BACK (stencil);
 
  958           if (!threeD && applyBdry)
 
  960           int globalRow = localRow + startRow - 1;
 
  961           int offset = rp[localRow - 1];
 
  962           int len = rp[localRow] - rp[localRow - 1];
 
  969               coeff = mg->A (mg->a, x + hhalf, y, z);
 
  970               ctr = mg->A (mg->a, x - hhalf, y, z);
 
  971               setBoundary_private (globalRow, cval + offset,
 
  973                        &(rhs[localRow - 1]), bcx1, coeff,
 
  976           else if (x == nx * px - 1)
 
  978               coeff = mg->A (mg->a, x - hhalf, y, z);
 
  979               ctr = mg->A (mg->a, x + hhalf, y, z);
 
  980               setBoundary_private (globalRow, cval + offset,
 
  982                        &(rhs[localRow - 1]), bcx2, coeff,
 
  987               coeff = mg->B (mg->b, x, y + hhalf, z);
 
  988               ctr = mg->B (mg->b, x, y - hhalf, z);
 
  989               setBoundary_private (globalRow, cval + offset,
 
  991                        &(rhs[localRow - 1]), bcy1, coeff,
 
  994           else if (y == ny * py - 1)
 
  996               coeff = mg->B (mg->b, x, y - hhalf, z);
 
  997               ctr = mg->B (mg->b, x, y + hhalf, z);
 
  998               setBoundary_private (globalRow, cval + offset,
 
 1000                        &(rhs[localRow - 1]), bcy2, coeff,
 
 1007               coeff = mg->B (mg->b, x, y, z + hhalf);
 
 1008               ctr = mg->B (mg->b, x, y, z - hhalf);
 
 1009               setBoundary_private (globalRow, cval + offset,
 
 1011                            &(rhs[localRow - 1]), bcy1,
 
 1012                            coeff, ctr, naborz2);
 
 1014               else if (z == nz * nx - 1)
 
 1016               coeff = mg->B (mg->b, x, y, z - hhalf);
 
 1017               ctr = mg->B (mg->b, x, y, z + hhalf);
 
 1018               setBoundary_private (globalRow, cval + offset,
 
 1020                            &(rhs[localRow - 1]), bcy1,
 
 1021                            coeff, ctr, naborz1);
 
 1032 #define __FUNC__ "setBoundary_private" 
 1034 setBoundary_private (
int node, 
int *cval, 
double *aval, 
int len,
 
 1035              double *rhs, 
double bc, 
double coeff, 
double ctr,
 
 1038   START_FUNC_DH 
int i;
 
 1045       for (i = 0; i < len; ++i)
 
 1047       if (cval[i] == node)
 
 1063       for (i = 0; i < len; ++i)
 
 1066       if (cval[i] == node)
 
 1068           aval[i] += (ctr - coeff);
 
 1071       else if (cval[i] == nabor)
 
 1073           aval[i] = 2.0 * coeff;