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