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;