00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #include "MatGenFD.h"
00044 #include "Mat_dh.h"
00045 #include "Vec_dh.h"
00046 #include "Parser_dh.h"
00047 #include "Mem_dh.h"
00048
00049
00050 static bool isThreeD;
00051
00052
00053 #define FRONT(a) a[5]
00054 #define SOUTH(a) a[3]
00055 #define WEST(a) a[1]
00056 #define CENTER(a) a[0]
00057 #define EAST(a) a[2]
00058 #define NORTH(a) a[4]
00059 #define BACK(a) a[6]
00060 #define RHS(a) a[7]
00061
00062 static void setBoundary_private (int node, int *cval, double *aval, int len,
00063 double *rhs, double bc, double coeff,
00064 double ctr, int nabor);
00065 static void generateStriped (MatGenFD mg, int *rp, int *cval, double *aval,
00066 Mat_dh A, Vec_dh b);
00067 static void generateBlocked (MatGenFD mg, int *rp, int *cval, double *aval,
00068 Mat_dh A, Vec_dh b);
00069 static void getstencil (MatGenFD g, int ix, int iy, int iz);
00070
00071 #if 0
00072 static void fdaddbc (int nx, int ny, int nz, int *rp, int *cval,
00073 int *diag, double *aval, double *rhs, double h,
00074 MatGenFD mg);
00075 #endif
00076
00077 #undef __FUNC__
00078 #define __FUNC__ "MatGenFDCreate"
00079 void
00080 MatGenFD_Create (MatGenFD * mg)
00081 {
00082 START_FUNC_DH
00083 struct _matgenfd *tmp =
00084 (struct _matgenfd *) MALLOC_DH (sizeof (struct _matgenfd));
00085 CHECK_V_ERROR;
00086 *mg = tmp;
00087
00088 tmp->debug = Parser_dhHasSwitch (parser_dh, "-debug_matgen");
00089
00090 tmp->m = 9;
00091 tmp->px = tmp->py = 1;
00092 tmp->pz = 0;
00093 Parser_dhReadInt (parser_dh, "-m", &tmp->m);
00094 Parser_dhReadInt (parser_dh, "-px", &tmp->px);
00095 Parser_dhReadInt (parser_dh, "-py", &tmp->py);
00096 Parser_dhReadInt (parser_dh, "-pz", &tmp->pz);
00097
00098 if (tmp->px < 1)
00099 tmp->px = 1;
00100 if (tmp->py < 1)
00101 tmp->py = 1;
00102 if (tmp->pz < 0)
00103 tmp->pz = 0;
00104 tmp->threeD = false;
00105 if (tmp->pz)
00106 {
00107 tmp->threeD = true;
00108 }
00109 else
00110 {
00111 tmp->pz = 1;
00112 }
00113 if (Parser_dhHasSwitch (parser_dh, "-threeD"))
00114 tmp->threeD = true;
00115
00116 tmp->a = tmp->b = tmp->c = 1.0;
00117 tmp->d = tmp->e = tmp->f = 0.0;
00118 tmp->g = tmp->h = 0.0;
00119
00120 Parser_dhReadDouble (parser_dh, "-dx", &tmp->a);
00121 Parser_dhReadDouble (parser_dh, "-dy", &tmp->b);
00122 Parser_dhReadDouble (parser_dh, "-dz", &tmp->c);
00123 Parser_dhReadDouble (parser_dh, "-cx", &tmp->d);
00124 Parser_dhReadDouble (parser_dh, "-cy", &tmp->e);
00125 Parser_dhReadDouble (parser_dh, "-cz", &tmp->f);
00126
00127 tmp->a = -1 * fabs (tmp->a);
00128 tmp->b = -1 * fabs (tmp->b);
00129 tmp->c = -1 * fabs (tmp->c);
00130
00131 tmp->allocateMem = true;
00132
00133 tmp->A = tmp->B = tmp->C = tmp->D = tmp->E
00134 = tmp->F = tmp->G = tmp->H = konstant;
00135
00136 tmp->bcX1 = tmp->bcX2 = tmp->bcY1 = tmp->bcY2 = tmp->bcZ1 = tmp->bcZ2 = 0.0;
00137 Parser_dhReadDouble (parser_dh, "-bcx1", &tmp->bcX1);
00138 Parser_dhReadDouble (parser_dh, "-bcx2", &tmp->bcX2);
00139 Parser_dhReadDouble (parser_dh, "-bcy1", &tmp->bcY1);
00140 Parser_dhReadDouble (parser_dh, "-bcy2", &tmp->bcY2);
00141 Parser_dhReadDouble (parser_dh, "-bcz1", &tmp->bcZ1);
00142 Parser_dhReadDouble (parser_dh, "-bcz2", &tmp->bcZ2);
00143 END_FUNC_DH}
00144
00145
00146 #undef __FUNC__
00147 #define __FUNC__ "MatGenFD_Destroy"
00148 void
00149 MatGenFD_Destroy (MatGenFD mg)
00150 {
00151 START_FUNC_DH FREE_DH (mg);
00152 CHECK_V_ERROR;
00153 END_FUNC_DH}
00154
00155
00156 #undef __FUNC__
00157 #define __FUNC__ "MatGenFD_Run"
00158 void
00159 MatGenFD_Run (MatGenFD mg, int id, int np, Mat_dh * AOut, Vec_dh * rhsOut)
00160 {
00161
00162
00163
00164
00165
00166
00167
00168
00169 START_FUNC_DH Mat_dh A;
00170 Vec_dh rhs;
00171 bool threeD = mg->threeD;
00172 int nnz;
00173 int m = mg->m;
00174 bool debug = false, striped;
00175
00176 if (mg->debug && logFile != NULL)
00177 debug = true;
00178 striped = Parser_dhHasSwitch (parser_dh, "-striped");
00179
00180
00181 Mat_dhCreate (AOut);
00182 CHECK_V_ERROR;
00183 Vec_dhCreate (rhsOut);
00184 CHECK_V_ERROR;
00185 A = *AOut;
00186 rhs = *rhsOut;
00187
00188
00189
00190
00191 if (!Parser_dhHasSwitch (parser_dh, "-noChecks"))
00192 {
00193 if (!striped)
00194 {
00195 int npTest = mg->px * mg->py;
00196 if (threeD)
00197 npTest *= mg->pz;
00198 if (npTest != np)
00199 {
00200 sprintf (msgBuf_dh,
00201 "numbers don't match: np_dh = %i, px*py*pz = %i", np,
00202 npTest);
00203 SET_V_ERROR (msgBuf_dh);
00204 }
00205 }
00206 }
00207
00208
00209
00210 mg->cc = m;
00211 if (threeD)
00212 {
00213 m = mg->m = m * m * m;
00214 }
00215 else
00216 {
00217 m = mg->m = m * m;
00218 }
00219
00220 mg->first = id * m;
00221 mg->hh = 1.0 / (mg->px * mg->cc - 1);
00222
00223 if (debug)
00224 {
00225 sprintf (msgBuf_dh, "cc (local grid dimension) = %i", mg->cc);
00226 SET_INFO (msgBuf_dh);
00227 if (threeD)
00228 {
00229 sprintf (msgBuf_dh, "threeD = true");
00230 }
00231 else
00232 {
00233 sprintf (msgBuf_dh, "threeD = false");
00234 }
00235 SET_INFO (msgBuf_dh);
00236 sprintf (msgBuf_dh, "np= %i id= %i", np, id);
00237 SET_INFO (msgBuf_dh);
00238 }
00239
00240 mg->id = id;
00241 mg->np = np;
00242 nnz = threeD ? m * 7 : m * 5;
00243
00244
00245 if (mg->allocateMem)
00246 {
00247 A->rp = (int *) MALLOC_DH ((m + 1) * sizeof (int));
00248 CHECK_V_ERROR;
00249 A->rp[0] = 0;
00250 A->cval = (int *) MALLOC_DH (nnz * sizeof (int));
00251 CHECK_V_ERROR A->aval = (double *) MALLOC_DH (nnz * sizeof (double));
00252 CHECK_V_ERROR;
00253
00254 }
00255
00256
00257 rhs->n = m;
00258 A->m = m;
00259 A->n = m * mg->np;
00260 A->beg_row = mg->first;
00261
00262
00263 isThreeD = threeD;
00264 if (Parser_dhHasSwitch (parser_dh, "-striped"))
00265 {
00266 generateStriped (mg, A->rp, A->cval, A->aval, A, rhs);
00267 CHECK_V_ERROR;
00268 }
00269 else
00270 {
00271 generateBlocked (mg, A->rp, A->cval, A->aval, A, rhs);
00272 CHECK_V_ERROR;
00273 }
00274
00275
00276
00277 if (!threeD)
00278 {
00279
00280 }
00281
00282 END_FUNC_DH}
00283
00284
00285 #undef __FUNC__
00286 #define __FUNC__ "generateStriped"
00287 void
00288 generateStriped (MatGenFD mg, int *rp, int *cval, double *aval, Mat_dh A,
00289 Vec_dh b)
00290 {
00291 START_FUNC_DH int mGlobal;
00292 int m = mg->m;
00293 int beg_row, end_row;
00294 int i, j, k, row;
00295 bool threeD = mg->threeD;
00296 int idx = 0;
00297 double *stencil = mg->stencil;
00298 bool debug = false;
00299 int plane, nodeRemainder;
00300 int naborx1, naborx2, nabory1, nabory2;
00301 double *rhs;
00302
00303 bool applyBdry = true;
00304 double hhalf;
00305 double bcx1 = mg->bcX1;
00306 double bcx2 = mg->bcX2;
00307 double bcy1 = mg->bcY1;
00308 double bcy2 = mg->bcY2;
00309
00310
00311 int nx, ny;
00312
00313 printf_dh ("@@@ using striped partitioning\n");
00314
00315 if (mg->debug && logFile != NULL)
00316 debug = true;
00317
00318
00319 m = 9;
00320 Parser_dhReadInt (parser_dh, "-m", &m);
00321 mGlobal = m * m;
00322 if (threeD)
00323 mGlobal *= m;
00324 i = mGlobal / mg->np;
00325 beg_row = i * mg->id;
00326 end_row = beg_row + i;
00327 if (mg->id == mg->np - 1)
00328 end_row = mGlobal;
00329 nx = ny = m;
00330
00331 mg->hh = 1.0 / (m - 1);
00332 hhalf = 0.5 * mg->hh;
00333
00334 A->n = m * m;
00335 A->m = end_row - beg_row;
00336 A->beg_row = beg_row;
00337
00338 Vec_dhInit (b, A->m);
00339 CHECK_V_ERROR;
00340 rhs = b->vals;
00341
00342 plane = m * m;
00343
00344 if (debug)
00345 {
00346 fprintf (logFile, "generateStriped: beg_row= %i; end_row= %i; m= %i\n",
00347 beg_row + 1, end_row + 1, m);
00348 }
00349
00350 for (row = beg_row; row < end_row; ++row)
00351 {
00352 int localRow = row - beg_row;
00353
00354
00355 k = (row / plane);
00356 nodeRemainder = row - (k * plane);
00357 j = nodeRemainder / m;
00358 i = nodeRemainder % m;
00359
00360 if (debug)
00361 {
00362 fprintf (logFile, "row= %i x= %i y= %i z= %i\n", row + 1, i, j,
00363 k);
00364 }
00365
00366
00367 getstencil (mg, i, j, k);
00368
00369
00370
00371
00372 if (threeD)
00373 {
00374 if (k > 0)
00375 {
00376 cval[idx] = row - plane;
00377 aval[idx++] = BACK (stencil);
00378 }
00379 }
00380
00381
00382 if (j > 0)
00383 {
00384 nabory1 = cval[idx] = row - m;
00385 aval[idx++] = SOUTH (stencil);
00386 }
00387
00388
00389 if (i > 0)
00390 {
00391 naborx1 = cval[idx] = row - 1;
00392 aval[idx++] = WEST (stencil);
00393 }
00394
00395
00396 cval[idx] = row;
00397 aval[idx++] = CENTER (stencil);
00398
00399
00400 if (i < m - 1)
00401 {
00402 naborx2 = cval[idx] = row + 1;
00403 aval[idx++] = EAST (stencil);
00404 }
00405
00406
00407 if (j < m - 1)
00408 {
00409 nabory2 = cval[idx] = row + m;
00410 aval[idx++] = NORTH (stencil);
00411 }
00412
00413
00414 if (threeD)
00415 {
00416 if (k < m - 1)
00417 {
00418 cval[idx] = row + plane;
00419 aval[idx++] = FRONT (stencil);
00420 }
00421 }
00422 rhs[localRow] = 0.0;
00423 ++localRow;
00424 rp[localRow] = idx;
00425
00426
00427 if (!threeD && applyBdry)
00428 {
00429 int offset = rp[localRow - 1];
00430 int len = rp[localRow] - rp[localRow - 1];
00431 double ctr, coeff;
00432
00433
00434
00435 if (i == 0)
00436 {
00437 coeff = mg->A (mg->a, i + hhalf, j, k);
00438 ctr = mg->A (mg->a, i - hhalf, j, k);
00439 setBoundary_private (row, cval + offset, aval + offset, len,
00440 &(rhs[localRow - 1]), bcx1, coeff, ctr,
00441 naborx2);
00442 }
00443 else if (i == nx - 1)
00444 {
00445 coeff = mg->A (mg->a, i - hhalf, j, k);
00446 ctr = mg->A (mg->a, i + hhalf, j, k);
00447 setBoundary_private (row, cval + offset, aval + offset, len,
00448 &(rhs[localRow - 1]), bcx2, coeff, ctr,
00449 naborx1);
00450 }
00451 else if (j == 0)
00452 {
00453 coeff = mg->B (mg->b, i, j + hhalf, k);
00454 ctr = mg->B (mg->b, i, j - hhalf, k);
00455 setBoundary_private (row, cval + offset, aval + offset, len,
00456 &(rhs[localRow - 1]), bcy1, coeff, ctr,
00457 nabory2);
00458 }
00459 else if (j == ny - 1)
00460 {
00461 coeff = mg->B (mg->b, i, j - hhalf, k);
00462 ctr = mg->B (mg->b, i, j + hhalf, k);
00463 setBoundary_private (row, cval + offset, aval + offset, len,
00464 &(rhs[localRow - 1]), bcy2, coeff, ctr,
00465 nabory1);
00466 }
00467 }
00468 }
00469 END_FUNC_DH}
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480 int
00481 rownum (const bool threeD, const int x, const int y, const int z,
00482 const int nx, const int ny, const int nz, int P, int Q)
00483 {
00484 int p, q, r;
00485 int lowerx, lowery, lowerz;
00486 int id, startrow;
00487
00488
00489
00490
00491
00492 p = x / nx;
00493 q = y / ny;
00494 r = z / nz;
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505 if (threeD)
00506 {
00507 id = r * P * Q + q * P + p;
00508 }
00509 else
00510 {
00511 id = q * P + p;
00512 }
00513
00514
00515
00516
00517
00518 startrow = id * (nx * ny * nz);
00519
00520
00521 lowerx = nx * p;
00522 lowery = ny * q;
00523 lowerz = nz * r;
00524
00525 if (threeD)
00526 {
00527 return startrow + nx * ny * (z - lowerz) + nx * (y - lowery) + (x -
00528 lowerx);
00529 }
00530 else
00531 {
00532 return startrow + nx * (y - lowery) + (x - lowerx);
00533 }
00534 }
00535
00536
00537
00538 void
00539 getstencil (MatGenFD g, int ix, int iy, int iz)
00540 {
00541 int k;
00542 double h = g->hh;
00543 double hhalf = h * 0.5;
00544 double x = h * ix;
00545 double y = h * iy;
00546 double z = h * iz;
00547 double cntr = 0.0;
00548 double *stencil = g->stencil;
00549 double coeff;
00550 bool threeD = g->threeD;
00551
00552 for (k = 0; k < 8; ++k)
00553 stencil[k] = 0.0;
00554
00555
00556 coeff = g->A (g->a, x + hhalf, y, z);
00557 EAST (stencil) += coeff;
00558 cntr += coeff;
00559
00560 coeff = g->A (g->a, x - hhalf, y, z);
00561 WEST (stencil) += coeff;
00562 cntr += coeff;
00563
00564 coeff = g->D (g->d, x, y, z) * hhalf;
00565 EAST (stencil) += coeff;
00566 WEST (stencil) -= coeff;
00567
00568
00569 coeff = g->B (g->b, x, y + hhalf, z);
00570 NORTH (stencil) += coeff;
00571 cntr += coeff;
00572
00573 coeff = g->B (g->b, x, y - hhalf, z);
00574 SOUTH (stencil) += coeff;
00575 cntr += coeff;
00576
00577 coeff = g->E (g->e, x, y, z) * hhalf;
00578 NORTH (stencil) += coeff;
00579 SOUTH (stencil) -= coeff;
00580
00581
00582 if (threeD)
00583 {
00584 coeff = g->C (g->c, x, y, z + hhalf);
00585 BACK (stencil) += coeff;
00586 cntr += coeff;
00587
00588 coeff = g->C (g->c, x, y, z - hhalf);
00589 FRONT (stencil) += coeff;
00590 cntr += coeff;
00591
00592 coeff = g->F (g->f, x, y, z) * hhalf;
00593 BACK (stencil) += coeff;
00594 FRONT (stencil) -= coeff;
00595 }
00596
00597
00598 coeff = g->G (g->g, x, y, z);
00599 CENTER (stencil) = h * h * coeff - cntr;
00600
00601 RHS (stencil) = h * h * g->H (g->h, x, y, z);
00602 }
00603
00604
00605 double
00606 konstant (double coeff, double x, double y, double z)
00607 {
00608 return coeff;
00609 }
00610
00611 double
00612 e2_xy (double coeff, double x, double y, double z)
00613 {
00614 return exp (coeff * x * y);
00615 }
00616
00617 double boxThreeD (double coeff, double x, double y, double z);
00618
00619
00620
00621
00622
00623
00624 double
00625 box_1 (double coeff, double x, double y, double z)
00626 {
00627 static bool setup = false;
00628 double retval = coeff;
00629
00630
00631 static double dd1 = BOX1_DD;
00632 static double dd2 = BOX2_DD;
00633 static double dd3 = BOX3_DD;
00634
00635
00636 static double ax1 = BOX1_X1, ay1 = BOX1_Y1;
00637 static double ax2 = BOX1_X2, ay2 = BOX1_Y2;
00638 static double bx1 = BOX2_X1, by1 = BOX2_Y1;
00639 static double bx2 = BOX2_X2, by2 = BOX2_Y2;
00640 static double cx1 = BOX3_X1, cy1 = BOX3_Y1;
00641 static double cx2 = BOX3_X2, cy2 = BOX3_Y2;
00642
00643 if (isThreeD)
00644 {
00645 return (boxThreeD (coeff, x, y, z));
00646 }
00647
00648
00649
00650 if (!setup)
00651 {
00652 dd1 = 0.1;
00653 dd2 = 0.1;
00654 dd3 = 10;
00655 Parser_dhReadDouble (parser_dh, "-dd1", &dd1);
00656 Parser_dhReadDouble (parser_dh, "-dd2", &dd2);
00657 Parser_dhReadDouble (parser_dh, "-dd3", &dd3);
00658 Parser_dhReadDouble (parser_dh, "-box1x1", &cx1);
00659 Parser_dhReadDouble (parser_dh, "-box1x2", &cx2);
00660 setup = true;
00661 }
00662
00663
00664 if (x > ax1 && x < ax2 && y > ay1 && y < ay2)
00665 {
00666 retval = dd1 * coeff;
00667 }
00668
00669
00670 if (x > bx1 && x < bx2 && y > by1 && y < by2)
00671 {
00672 retval = dd2 * coeff;
00673 }
00674
00675
00676 if (x > cx1 && x < cx2 && y > cy1 && y < cy2)
00677 {
00678 retval = dd3 * coeff;
00679 }
00680
00681 return retval;
00682 }
00683
00684 double
00685 boxThreeD (double coeff, double x, double y, double z)
00686 {
00687 static bool setup = false;
00688 double retval = coeff;
00689
00690
00691 static double dd1 = 100;
00692
00693
00694 static double x1 = .2, x2 = .8;
00695 static double y1 = .3, y2 = .7;
00696 static double z1 = .4, z2 = .6;
00697
00698
00699 if (!setup)
00700 {
00701 Parser_dhReadDouble (parser_dh, "-dd1", &dd1);
00702 setup = true;
00703 }
00704
00705
00706 if (x > x1 && x < x2 && y > y1 && y < y2 && z > z1 && z < z2)
00707 {
00708 retval = dd1 * coeff;
00709 }
00710
00711 return retval;
00712 }
00713
00714 #if 0
00715 double
00716 box_1 (double coeff, double x, double y, double z)
00717 {
00718 static double x1, x2, y1, y2;
00719 static double d1, d2;
00720 bool setup = false;
00721 double retval;
00722
00723
00724
00725
00726 if (!setup)
00727 {
00728 x1 = .25;
00729 x2 = .75;
00730 y1 = .25;
00731 y2 = .75;
00732 d1 = 1;
00733 d2 = 2;
00734 Parser_dhReadDouble (parser_dh, "-bx1", &x1);
00735 Parser_dhReadDouble (parser_dh, "-bx2", &x2);
00736 Parser_dhReadDouble (parser_dh, "-by1", &y1);
00737 Parser_dhReadDouble (parser_dh, "-by2", &y2);
00738 Parser_dhReadDouble (parser_dh, "-bd1", &d1);
00739 Parser_dhReadDouble (parser_dh, "-bd2", &d2);
00740 setup = true;
00741 }
00742
00743 retval = d2;
00744
00745
00746 if (x > x1 && x < x2 && y > y1 && y < y2)
00747 {
00748 retval = d1;
00749 }
00750
00751 return -1 * retval;
00752 }
00753 #endif
00754
00755
00756
00757
00758 double
00759 box_2 (double coeff, double x, double y, double z)
00760 {
00761 bool setup = false;
00762 static double d1, d2;
00763 double retval;
00764
00765 if (!setup)
00766 {
00767 d1 = 1;
00768 d2 = 2;
00769 Parser_dhReadDouble (parser_dh, "-bd1", &d1);
00770 Parser_dhReadDouble (parser_dh, "-bd2", &d2);
00771 }
00772
00773 retval = d2;
00774
00775 if (x < .5 && y < .5)
00776 retval = d1;
00777 if (x > .5 && y > .5)
00778 retval = d1;
00779
00780 return -1 * retval;
00781 }
00782
00783
00784 #undef __FUNC__
00785 #define __FUNC__ "generateBlocked"
00786 void
00787 generateBlocked (MatGenFD mg, int *rp, int *cval, double *aval, Mat_dh A,
00788 Vec_dh b)
00789 {
00790 START_FUNC_DH bool applyBdry = true;
00791 double *stencil = mg->stencil;
00792 int id = mg->id;
00793 bool threeD = mg->threeD;
00794 int px = mg->px, py = mg->py, pz = mg->pz;
00795 int p, q, r;
00796 int cc = mg->cc;
00797 int nx = cc, ny = cc, nz = cc;
00798 int lowerx, upperx, lowery, uppery, lowerz, upperz;
00799 int startRow;
00800 int x, y, z;
00801 bool debug = false;
00802 int idx = 0, localRow = 0;
00803 int naborx1, naborx2, nabory1, nabory2, naborz1, naborz2;
00804 double *rhs;
00805
00806 double hhalf = 0.5 * mg->hh;
00807 double bcx1 = mg->bcX1;
00808 double bcx2 = mg->bcX2;
00809 double bcy1 = mg->bcY1;
00810 double bcy2 = mg->bcY2;
00811
00812
00813
00814 Vec_dhInit (b, A->m);
00815 CHECK_V_ERROR;
00816 rhs = b->vals;
00817
00818 if (mg->debug && logFile != NULL)
00819 debug = true;
00820 if (!threeD)
00821 nz = 1;
00822
00823
00824 p = id % px;
00825 q = ((id - p) / px) % py;
00826 r = (id - p - px * q) / (px * py);
00827
00828 if (debug)
00829 {
00830 sprintf (msgBuf_dh,
00831 "this proc's position in subdomain grid: p= %i q= %i r= %i",
00832 p, q, r);
00833 SET_INFO (msgBuf_dh);
00834 }
00835
00836
00837
00838
00839 lowerx = nx * p;
00840 upperx = lowerx + nx;
00841 lowery = ny * q;
00842 uppery = lowery + ny;
00843 lowerz = nz * r;
00844 upperz = lowerz + nz;
00845
00846 if (debug)
00847 {
00848 sprintf (msgBuf_dh, "local grid parameters: lowerx= %i upperx= %i",
00849 lowerx, upperx);
00850 SET_INFO (msgBuf_dh);
00851 sprintf (msgBuf_dh, "local grid parameters: lowery= %i uppery= %i",
00852 lowery, uppery);
00853 SET_INFO (msgBuf_dh);
00854 sprintf (msgBuf_dh, "local grid parameters: lowerz= %i upperz= %i",
00855 lowerz, upperz);
00856 SET_INFO (msgBuf_dh);
00857 }
00858
00859 startRow = mg->first;
00860 rp[0] = 0;
00861
00862 for (z = lowerz; z < upperz; z++)
00863 {
00864 for (y = lowery; y < uppery; y++)
00865 {
00866 for (x = lowerx; x < upperx; x++)
00867 {
00868
00869 if (debug)
00870 {
00871 fprintf (logFile, "row= %i x= %i y= %i z= %i\n",
00872 localRow + startRow + 1, x, y, z);
00873 }
00874
00875
00876 getstencil (mg, x, y, z);
00877
00878
00879 if (threeD)
00880 {
00881 if (z > 0)
00882 {
00883 naborz1 =
00884 rownum (threeD, x, y, z - 1, nx, ny, nz, px, py);
00885 cval[idx] = naborz1;
00886 aval[idx++] = FRONT (stencil);
00887 }
00888 }
00889
00890
00891 if (y > 0)
00892 {
00893 nabory1 = rownum (threeD, x, y - 1, z, nx, ny, nz, px, py);
00894 cval[idx] = nabory1;
00895 aval[idx++] = SOUTH (stencil);
00896 }
00897
00898
00899 if (x > 0)
00900 {
00901 naborx1 = rownum (threeD, x - 1, y, z, nx, ny, nz, px, py);
00902 cval[idx] = naborx1;
00903 aval[idx++] = WEST (stencil);
00904
00905
00906 }
00907
00908
00909
00910
00911
00912
00913
00914 cval[idx] = localRow + startRow;
00915 aval[idx++] = CENTER (stencil);
00916
00917
00918
00919 if (x < nx * px - 1)
00920 {
00921 naborx2 = rownum (threeD, x + 1, y, z, nx, ny, nz, px, py);
00922 cval[idx] = naborx2;
00923 aval[idx++] = EAST (stencil);
00924 }
00925
00926
00927
00928
00929
00930
00931
00932 if (y < ny * py - 1)
00933 {
00934 nabory2 = rownum (threeD, x, y + 1, z, nx, ny, nz, px, py);
00935 cval[idx] = nabory2;
00936 aval[idx++] = NORTH (stencil);
00937 }
00938
00939
00940 if (threeD)
00941 {
00942 if (z < nz * pz - 1)
00943 {
00944 naborz2 =
00945 rownum (threeD, x, y, z + 1, nx, ny, nz, px, py);
00946 cval[idx] = naborz2;
00947 aval[idx++] = BACK (stencil);
00948 }
00949 }
00950
00951
00952 rhs[localRow] = 0.0;
00953
00954 ++localRow;
00955 rp[localRow] = idx;
00956
00957
00958 if (!threeD && applyBdry)
00959 {
00960 int globalRow = localRow + startRow - 1;
00961 int offset = rp[localRow - 1];
00962 int len = rp[localRow] - rp[localRow - 1];
00963 double ctr, coeff;
00964
00965
00966
00967 if (x == 0)
00968 {
00969 coeff = mg->A (mg->a, x + hhalf, y, z);
00970 ctr = mg->A (mg->a, x - hhalf, y, z);
00971 setBoundary_private (globalRow, cval + offset,
00972 aval + offset, len,
00973 &(rhs[localRow - 1]), bcx1, coeff,
00974 ctr, naborx2);
00975 }
00976 else if (x == nx * px - 1)
00977 {
00978 coeff = mg->A (mg->a, x - hhalf, y, z);
00979 ctr = mg->A (mg->a, x + hhalf, y, z);
00980 setBoundary_private (globalRow, cval + offset,
00981 aval + offset, len,
00982 &(rhs[localRow - 1]), bcx2, coeff,
00983 ctr, naborx1);
00984 }
00985 else if (y == 0)
00986 {
00987 coeff = mg->B (mg->b, x, y + hhalf, z);
00988 ctr = mg->B (mg->b, x, y - hhalf, z);
00989 setBoundary_private (globalRow, cval + offset,
00990 aval + offset, len,
00991 &(rhs[localRow - 1]), bcy1, coeff,
00992 ctr, nabory2);
00993 }
00994 else if (y == ny * py - 1)
00995 {
00996 coeff = mg->B (mg->b, x, y - hhalf, z);
00997 ctr = mg->B (mg->b, x, y + hhalf, z);
00998 setBoundary_private (globalRow, cval + offset,
00999 aval + offset, len,
01000 &(rhs[localRow - 1]), bcy2, coeff,
01001 ctr, nabory1);
01002 }
01003 else if (threeD)
01004 {
01005 if (z == 0)
01006 {
01007 coeff = mg->B (mg->b, x, y, z + hhalf);
01008 ctr = mg->B (mg->b, x, y, z - hhalf);
01009 setBoundary_private (globalRow, cval + offset,
01010 aval + offset, len,
01011 &(rhs[localRow - 1]), bcy1,
01012 coeff, ctr, naborz2);
01013 }
01014 else if (z == nz * nx - 1)
01015 {
01016 coeff = mg->B (mg->b, x, y, z - hhalf);
01017 ctr = mg->B (mg->b, x, y, z + hhalf);
01018 setBoundary_private (globalRow, cval + offset,
01019 aval + offset, len,
01020 &(rhs[localRow - 1]), bcy1,
01021 coeff, ctr, naborz1);
01022 }
01023 }
01024 }
01025 }
01026 }
01027 }
01028 END_FUNC_DH}
01029
01030
01031 #undef __FUNC__
01032 #define __FUNC__ "setBoundary_private"
01033 void
01034 setBoundary_private (int node, int *cval, double *aval, int len,
01035 double *rhs, double bc, double coeff, double ctr,
01036 int nabor)
01037 {
01038 START_FUNC_DH int i;
01039
01040
01041 if (bc >= 0)
01042 {
01043
01044 *rhs = bc;
01045 for (i = 0; i < len; ++i)
01046 {
01047 if (cval[i] == node)
01048 {
01049 aval[i] = 1.0;
01050 }
01051 else
01052 {
01053 aval[i] = 0;
01054 }
01055 }
01056 }
01057
01058
01059 else
01060 {
01061
01062
01063 for (i = 0; i < len; ++i)
01064 {
01065
01066 if (cval[i] == node)
01067 {
01068 aval[i] += (ctr - coeff);
01069
01070 }
01071 else if (cval[i] == nabor)
01072 {
01073 aval[i] = 2.0 * coeff;
01074 }
01075 }
01076 }
01077 END_FUNC_DH}