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 #include "ilu_dh.h"
00033 #include "Mem_dh.h"
00034 #include "Parser_dh.h"
00035 #include "Euclid_dh.h"
00036 #include "getRow_dh.h"
00037 #include "Factor_dh.h"
00038 #include "SubdomainGraph_dh.h"
00039
00040 static bool check_constraint_private (Euclid_dh ctx, int b, int j);
00041
00042 static int symbolic_row_private (int localRow,
00043 int *list, int *marker, int *tmpFill,
00044 int len, int *CVAL, double *AVAL,
00045 int *o2n_col, Euclid_dh ctx, bool debug);
00046
00047 static int numeric_row_private (int localRow,
00048 int len, int *CVAL, double *AVAL,
00049 REAL_DH * work, int *o2n_col, Euclid_dh ctx,
00050 bool debug);
00051
00052
00053 #undef __FUNC__
00054 #define __FUNC__ "compute_scaling_private"
00055 void
00056 compute_scaling_private (int row, int len, double *AVAL, Euclid_dh ctx)
00057 {
00058 START_FUNC_DH double tmp = 0.0;
00059 int j;
00060
00061 for (j = 0; j < len; ++j)
00062 tmp = MAX (tmp, fabs (AVAL[j]));
00063 if (tmp)
00064 {
00065 ctx->scale[row] = 1.0 / tmp;
00066 }
00067 END_FUNC_DH}
00068
00069 #if 0
00070
00071
00072 #undef __FUNC__
00073 #define __FUNC__ "fixPivot_private"
00074 double
00075 fixPivot_private (int row, int len, float *vals)
00076 {
00077 START_FUNC_DH int i;
00078 float max = 0.0;
00079 bool debug = false;
00080
00081 for (i = 0; i < len; ++i)
00082 {
00083 float tmp = fabs (vals[i]);
00084 max = MAX (max, tmp);
00085 }
00086 END_FUNC_VAL (max * ctxPrivate->pivotFix)}
00087
00088 #endif
00089
00090
00091
00092
00093 #undef __FUNC__
00094 #define __FUNC__ "iluk_seq"
00095 void
00096 iluk_seq (Euclid_dh ctx)
00097 {
00098 START_FUNC_DH int *rp, *cval, *diag;
00099 int *CVAL;
00100 int i, j, len, count, col, idx = 0;
00101 int *list, *marker, *fill, *tmpFill;
00102 int temp, m, from = ctx->from, to = ctx->to;
00103 int *n2o_row, *o2n_col, beg_row, beg_rowP;
00104 double *AVAL;
00105 REAL_DH *work, *aval;
00106 Factor_dh F = ctx->F;
00107 SubdomainGraph_dh sg = ctx->sg;
00108 bool debug = false;
00109
00110 if (logFile != NULL && Parser_dhHasSwitch (parser_dh, "-debug_ilu"))
00111 debug = true;
00112
00113 m = F->m;
00114 rp = F->rp;
00115 cval = F->cval;
00116 fill = F->fill;
00117 diag = F->diag;
00118 aval = F->aval;
00119 work = ctx->work;
00120 count = rp[from];
00121
00122 if (sg == NULL)
00123 {
00124 SET_V_ERROR ("subdomain graph is NULL");
00125 }
00126
00127 n2o_row = ctx->sg->n2o_row;
00128 o2n_col = ctx->sg->o2n_col;
00129 beg_row = ctx->sg->beg_row[myid_dh];
00130 beg_rowP = ctx->sg->beg_rowP[myid_dh];
00131
00132
00133 list = (int *) MALLOC_DH ((m + 1) * sizeof (int));
00134 CHECK_V_ERROR;
00135 marker = (int *) MALLOC_DH (m * sizeof (int));
00136 CHECK_V_ERROR;
00137 tmpFill = (int *) MALLOC_DH (m * sizeof (int));
00138 CHECK_V_ERROR;
00139 for (i = 0; i < m; ++i)
00140 marker[i] = -1;
00141
00142
00143 for (i = 0; i < m; ++i)
00144 work[i] = 0.0;
00145
00146
00147
00148
00149
00150
00151
00152 for (i = from; i < to; ++i)
00153 {
00154 int row = n2o_row[i];
00155 int globalRow = row + beg_row;
00156
00157
00158
00159
00160 if (debug)
00161 {
00162 fprintf (logFile,
00163 "ILU_seq ================================= starting local row: %i, (global= %i) level= %i\n",
00164 i + 1, i + 1 + sg->beg_rowP[myid_dh], ctx->level);
00165 }
00166
00167 EuclidGetRow (ctx->A, globalRow, &len, &CVAL, &AVAL);
00168 CHECK_V_ERROR;
00169
00170
00171 if (ctx->isScaled)
00172 {
00173 compute_scaling_private (i, len, AVAL, ctx);
00174 CHECK_V_ERROR;
00175 }
00176
00177
00178
00179
00180 count = symbolic_row_private (i, list, marker, tmpFill,
00181 len, CVAL, AVAL, o2n_col, ctx, debug);
00182 CHECK_V_ERROR;
00183
00184
00185 if (idx + count > F->alloc)
00186 {
00187 Factor_dhReallocate (F, idx, count);
00188 CHECK_V_ERROR;
00189 SET_INFO ("REALLOCATED from ilu_seq");
00190 cval = F->cval;
00191 fill = F->fill;
00192 aval = F->aval;
00193 }
00194
00195
00196 col = list[m];
00197 while (count--)
00198 {
00199 cval[idx] = col;
00200 fill[idx] = tmpFill[col];
00201 ++idx;
00202
00203
00204 col = list[col];
00205 }
00206
00207
00208 rp[i + 1] = idx;
00209
00210
00211 temp = rp[i];
00212 while (cval[temp] != i)
00213 ++temp;
00214 diag[i] = temp;
00215
00216
00217
00218
00219
00220 numeric_row_private (i, len, CVAL, AVAL, work, o2n_col, ctx, debug);
00221 CHECK_V_ERROR EuclidRestoreRow (ctx->A, globalRow, &len, &CVAL, &AVAL);
00222 CHECK_V_ERROR;
00223
00224
00225
00226
00227 if (debug)
00228 {
00229 fprintf (logFile, "ILU_seq: ");
00230 for (j = rp[i]; j < rp[i + 1]; ++j)
00231 {
00232 col = cval[j];
00233 aval[j] = work[col];
00234 work[col] = 0.0;
00235 fprintf (logFile, "%i,%i,%g ; ", 1 + cval[j], fill[j], aval[j]);
00236 fflush (logFile);
00237 }
00238 fprintf (logFile, "\n");
00239 }
00240 else
00241 {
00242 for (j = rp[i]; j < rp[i + 1]; ++j)
00243 {
00244 col = cval[j];
00245 aval[j] = work[col];
00246 work[col] = 0.0;
00247 }
00248 }
00249
00250
00251 if (!aval[diag[i]])
00252 {
00253 sprintf (msgBuf_dh, "zero diagonal in local row %i", i + 1);
00254 SET_V_ERROR (msgBuf_dh);
00255 }
00256 }
00257
00258 FREE_DH (list);
00259 CHECK_V_ERROR;
00260 FREE_DH (tmpFill);
00261 CHECK_V_ERROR;
00262 FREE_DH (marker);
00263 CHECK_V_ERROR;
00264
00265
00266 if (beg_rowP)
00267 {
00268 int start = rp[from];
00269 int stop = rp[to];
00270 for (i = start; i < stop; ++i)
00271 cval[i] += beg_rowP;
00272 }
00273
00274
00275
00276
00277 for (i = to + 1; i < m; ++i)
00278 rp[i] = 0;
00279
00280 END_FUNC_DH}
00281
00282
00283 #undef __FUNC__
00284 #define __FUNC__ "iluk_seq_block"
00285 void
00286 iluk_seq_block (Euclid_dh ctx)
00287 {
00288 START_FUNC_DH int *rp, *cval, *diag;
00289 int *CVAL;
00290 int h, i, j, len, count, col, idx = 0;
00291 int *list, *marker, *fill, *tmpFill;
00292 int temp, m;
00293 int *n2o_row, *o2n_col, *beg_rowP, *n2o_sub, blocks;
00294 int *row_count, *dummy = NULL, dummy2[1];
00295 double *AVAL;
00296 REAL_DH *work, *aval;
00297 Factor_dh F = ctx->F;
00298 SubdomainGraph_dh sg = ctx->sg;
00299 bool bj = false, constrained = false;
00300 int discard = 0;
00301 int gr = -1;
00302 bool debug = false;
00303
00304 if (logFile != NULL && Parser_dhHasSwitch (parser_dh, "-debug_ilu"))
00305 debug = true;
00306
00307
00308
00309
00310 if (!strcmp (ctx->algo_par, "bj"))
00311 bj = true;
00312 constrained = !Parser_dhHasSwitch (parser_dh, "-unconstrained");
00313
00314 m = F->m;
00315 rp = F->rp;
00316 cval = F->cval;
00317 fill = F->fill;
00318 diag = F->diag;
00319 aval = F->aval;
00320 work = ctx->work;
00321
00322 if (sg != NULL)
00323 {
00324 n2o_row = sg->n2o_row;
00325 o2n_col = sg->o2n_col;
00326 row_count = sg->row_count;
00327
00328 beg_rowP = sg->beg_rowP;
00329 n2o_sub = sg->n2o_sub;
00330 blocks = sg->blocks;
00331 }
00332
00333 else
00334 {
00335 dummy = (int *) MALLOC_DH (m * sizeof (int));
00336 CHECK_V_ERROR;
00337 for (i = 0; i < m; ++i)
00338 dummy[i] = i;
00339 n2o_row = dummy;
00340 o2n_col = dummy;
00341 dummy2[0] = m;
00342 row_count = dummy2;
00343
00344 beg_rowP = dummy;
00345 n2o_sub = dummy;
00346 blocks = 1;
00347 }
00348
00349
00350 list = (int *) MALLOC_DH ((m + 1) * sizeof (int));
00351 CHECK_V_ERROR;
00352 marker = (int *) MALLOC_DH (m * sizeof (int));
00353 CHECK_V_ERROR;
00354 tmpFill = (int *) MALLOC_DH (m * sizeof (int));
00355 CHECK_V_ERROR;
00356 for (i = 0; i < m; ++i)
00357 marker[i] = -1;
00358
00359
00360 for (i = 0; i < m; ++i)
00361 work[i] = 0.0;
00362
00363
00364
00365 for (h = 0; h < blocks; ++h)
00366 {
00367
00368 int curBlock = n2o_sub[h];
00369 int first_row = beg_rowP[curBlock];
00370 int end_row = first_row + row_count[curBlock];
00371
00372 if (debug)
00373 {
00374 fprintf (logFile, "\n\nILU_seq BLOCK: %i @@@@@@@@@@@@@@@ \n",
00375 curBlock);
00376 }
00377
00378 for (i = first_row; i < end_row; ++i)
00379 {
00380 int row = n2o_row[i];
00381 ++gr;
00382
00383 if (debug)
00384 {
00385 fprintf (logFile,
00386 "ILU_seq global: %i local: %i =================================\n",
00387 1 + gr, 1 + i - first_row);
00388 }
00389
00390
00391
00392
00393 EuclidGetRow (ctx->A, row, &len, &CVAL, &AVAL);
00394 CHECK_V_ERROR;
00395
00396
00397 if (ctx->isScaled)
00398 {
00399 compute_scaling_private (i, len, AVAL, ctx);
00400 CHECK_V_ERROR;
00401 }
00402
00403
00404
00405
00406 count = symbolic_row_private (i, list, marker, tmpFill,
00407 len, CVAL, AVAL, o2n_col, ctx, debug);
00408 CHECK_V_ERROR;
00409
00410
00411 if (idx + count > F->alloc)
00412 {
00413 Factor_dhReallocate (F, idx, count);
00414 CHECK_V_ERROR;
00415 SET_INFO ("REALLOCATED from ilu_seq");
00416 cval = F->cval;
00417 fill = F->fill;
00418 aval = F->aval;
00419 }
00420
00421
00422 col = list[m];
00423 while (count--)
00424 {
00425
00426
00427 if (constrained && !bj)
00428 {
00429 if (col >= first_row && col < end_row)
00430 {
00431 cval[idx] = col;
00432 fill[idx] = tmpFill[col];
00433 ++idx;
00434 }
00435 else
00436 {
00437 if (check_constraint_private (ctx, curBlock, col))
00438 {
00439 cval[idx] = col;
00440 fill[idx] = tmpFill[col];
00441 ++idx;
00442 }
00443 else
00444 {
00445 ++discard;
00446 }
00447 }
00448 col = list[col];
00449 }
00450
00451
00452 else if (bj)
00453 {
00454 if (col >= first_row && col < end_row)
00455 {
00456 cval[idx] = col;
00457 fill[idx] = tmpFill[col];
00458 ++idx;
00459 }
00460 else
00461 {
00462 ++discard;
00463 }
00464 col = list[col];
00465 }
00466
00467
00468 else
00469 {
00470 cval[idx] = col;
00471 fill[idx] = tmpFill[col];
00472 ++idx;
00473 col = list[col];
00474 }
00475 }
00476
00477
00478 rp[i + 1] = idx;
00479
00480
00481 temp = rp[i];
00482 while (cval[temp] != i)
00483 ++temp;
00484 diag[i] = temp;
00485
00486
00487 numeric_row_private (i, len, CVAL, AVAL, work, o2n_col, ctx, debug);
00488 CHECK_V_ERROR EuclidRestoreRow (ctx->A, row, &len, &CVAL, &AVAL);
00489 CHECK_V_ERROR;
00490
00491
00492
00493
00494 if (debug)
00495 {
00496 fprintf (logFile, "ILU_seq: ");
00497 for (j = rp[i]; j < rp[i + 1]; ++j)
00498 {
00499 col = cval[j];
00500 aval[j] = work[col];
00501 work[col] = 0.0;
00502 fprintf (logFile, "%i,%i,%g ; ", 1 + cval[j], fill[j],
00503 aval[j]);
00504 }
00505 fprintf (logFile, "\n");
00506 }
00507
00508
00509 else
00510 {
00511 for (j = rp[i]; j < rp[i + 1]; ++j)
00512 {
00513 col = cval[j];
00514 aval[j] = work[col];
00515 work[col] = 0.0;
00516 }
00517 }
00518
00519
00520 if (!aval[diag[i]])
00521 {
00522 sprintf (msgBuf_dh, "zero diagonal in local row %i", i + 1);
00523 SET_V_ERROR (msgBuf_dh);
00524 }
00525 }
00526 }
00527
00528
00529
00530 if (dummy != NULL)
00531 {
00532 FREE_DH (dummy);
00533 CHECK_V_ERROR;
00534 }
00535 FREE_DH (list);
00536 CHECK_V_ERROR;
00537 FREE_DH (tmpFill);
00538 CHECK_V_ERROR;
00539 FREE_DH (marker);
00540 CHECK_V_ERROR;
00541
00542 END_FUNC_DH}
00543
00544
00545
00546
00547
00548
00549
00550
00551 #undef __FUNC__
00552 #define __FUNC__ "symbolic_row_private"
00553 int
00554 symbolic_row_private (int localRow,
00555 int *list, int *marker, int *tmpFill,
00556 int len, int *CVAL, double *AVAL,
00557 int *o2n_col, Euclid_dh ctx, bool debug)
00558 {
00559 START_FUNC_DH int level = ctx->level, m = ctx->F->m;
00560 int *cval = ctx->F->cval, *diag = ctx->F->diag, *rp = ctx->F->rp;
00561 int *fill = ctx->F->fill;
00562 int count = 0;
00563 int j, node, tmp, col, head;
00564 int fill1, fill2, beg_row;
00565 double val;
00566 double thresh = ctx->sparseTolA;
00567 REAL_DH scale;
00568
00569 scale = ctx->scale[localRow];
00570 ctx->stats[NZA_STATS] += (double) len;
00571 beg_row = ctx->sg->beg_row[myid_dh];
00572
00573
00574
00575
00576
00577 list[m] = m;
00578 for (j = 0; j < len; ++j)
00579 {
00580 tmp = m;
00581 col = *CVAL++;
00582 col -= beg_row;
00583 col = o2n_col[col];
00584 val = *AVAL++;
00585 val *= scale;
00586
00587 if (fabs (val) > thresh || col == localRow)
00588 {
00589 ++count;
00590 while (col > list[tmp])
00591 tmp = list[tmp];
00592 list[col] = list[tmp];
00593 list[tmp] = col;
00594 tmpFill[col] = 0;
00595 marker[col] = localRow;
00596 }
00597 }
00598
00599
00600 if (marker[localRow] != localRow)
00601 {
00602 tmp = m;
00603 while (localRow > list[tmp])
00604 tmp = list[tmp];
00605 list[localRow] = list[tmp];
00606 list[tmp] = localRow;
00607 tmpFill[localRow] = 0;
00608 marker[localRow] = localRow;
00609 ++count;
00610 }
00611 ctx->stats[NZA_USED_STATS] += (double) count;
00612
00613
00614 head = m;
00615 if (level > 0)
00616 {
00617 while (list[head] < localRow)
00618 {
00619 node = list[head];
00620 fill1 = tmpFill[node];
00621
00622 if (debug)
00623 {
00624 fprintf (logFile, "ILU_seq sf updating from row: %i\n",
00625 1 + node);
00626 }
00627
00628 if (fill1 < level)
00629 {
00630 for (j = diag[node] + 1; j < rp[node + 1]; ++j)
00631 {
00632 col = cval[j];
00633 fill2 = fill1 + fill[j] + 1;
00634
00635 if (fill2 <= level)
00636 {
00637
00638
00639
00640 if (marker[col] < localRow)
00641 {
00642 tmp = head;
00643 marker[col] = localRow;
00644 tmpFill[col] = fill2;
00645 while (col > list[tmp])
00646 tmp = list[tmp];
00647 list[col] = list[tmp];
00648 list[tmp] = col;
00649 ++count;
00650 }
00651
00652
00653 else
00654 {
00655 tmpFill[col] =
00656 (fill2 < tmpFill[col]) ? fill2 : tmpFill[col];
00657 }
00658 }
00659 }
00660 }
00661 head = list[head];
00662 }
00663 }
00664 END_FUNC_VAL (count)}
00665
00666
00667 #undef __FUNC__
00668 #define __FUNC__ "numeric_row_private"
00669 int
00670 numeric_row_private (int localRow,
00671 int len, int *CVAL, double *AVAL,
00672 REAL_DH * work, int *o2n_col, Euclid_dh ctx, bool debug)
00673 {
00674 START_FUNC_DH double pc, pv, multiplier;
00675 int j, k, col, row;
00676 int *rp = ctx->F->rp, *cval = ctx->F->cval;
00677 int *diag = ctx->F->diag;
00678 int beg_row;
00679 double val;
00680 REAL_DH *aval = ctx->F->aval, scale;
00681
00682 scale = ctx->scale[localRow];
00683 beg_row = ctx->sg->beg_row[myid_dh];
00684
00685
00686
00687 for (j = rp[localRow]; j < rp[localRow + 1]; ++j)
00688 {
00689 col = cval[j];
00690 work[col] = 0.0;
00691 }
00692
00693
00694
00695 for (j = 0; j < len; ++j)
00696 {
00697 col = *CVAL++;
00698 col -= beg_row;
00699 val = *AVAL++;
00700 col = o2n_col[col];
00701 work[col] = val * scale;
00702 }
00703
00704
00705
00706
00707
00708
00709
00710 for (j = rp[localRow]; j < diag[localRow]; ++j)
00711 {
00712 row = cval[j];
00713 pc = work[row];
00714
00715
00716 pv = aval[diag[row]];
00717
00718
00719
00720
00721
00722
00723
00724 if (pc != 0.0 && pv != 0.0)
00725 {
00726 multiplier = pc / pv;
00727 work[row] = multiplier;
00728
00729 if (debug)
00730 {
00731 fprintf (logFile,
00732 "ILU_seq nf updating from row: %i; multiplier= %g\n",
00733 1 + row, multiplier);
00734 }
00735
00736 for (k = diag[row] + 1; k < rp[row + 1]; ++k)
00737 {
00738 col = cval[k];
00739 work[col] -= (multiplier * aval[k]);
00740 }
00741 }
00742 else
00743 {
00744 if (debug)
00745 {
00746 fprintf (logFile,
00747 "ILU_seq nf NO UPDATE from row %i; pc = %g; pv = %g\n",
00748 1 + row, pc, pv);
00749 }
00750 }
00751 }
00752
00753
00754 #if 0
00755 if (fabs (work[i]) <= pivotTol)
00756 {
00757
00758 aval[diag[i]] = pivotFix;
00759 }
00760 #endif
00761
00762 END_FUNC_VAL (0)}
00763
00764
00765
00766
00767
00768 int ilut_row_private (int localRow, int *list, int *o2n_col, int *marker,
00769 int len, int *CVAL, double *AVAL,
00770 REAL_DH * work, Euclid_dh ctx, bool debug);
00771
00772 #undef __FUNC__
00773 #define __FUNC__ "ilut_seq"
00774 void
00775 ilut_seq (Euclid_dh ctx)
00776 {
00777 START_FUNC_DH int *rp, *cval, *diag, *CVAL;
00778 int i, len, count, col, idx = 0;
00779 int *list, *marker;
00780 int temp, m, from, to;
00781 int *n2o_row, *o2n_col, beg_row, beg_rowP;
00782 double *AVAL, droptol;
00783 REAL_DH *work, *aval, val;
00784 Factor_dh F = ctx->F;
00785 SubdomainGraph_dh sg = ctx->sg;
00786 bool debug = false;
00787
00788 if (logFile != NULL && Parser_dhHasSwitch (parser_dh, "-debug_ilu"))
00789 debug = true;
00790
00791 m = F->m;
00792 rp = F->rp;
00793 cval = F->cval;
00794 diag = F->diag;
00795 aval = F->aval;
00796 work = ctx->work;
00797 from = ctx->from;
00798 to = ctx->to;
00799 count = rp[from];
00800 droptol = ctx->droptol;
00801
00802 if (sg == NULL)
00803 {
00804 SET_V_ERROR ("subdomain graph is NULL");
00805 }
00806
00807 n2o_row = ctx->sg->n2o_row;
00808 o2n_col = ctx->sg->o2n_col;
00809 beg_row = ctx->sg->beg_row[myid_dh];
00810 beg_rowP = ctx->sg->beg_rowP[myid_dh];
00811
00812
00813
00814 list = (int *) MALLOC_DH ((m + 1) * sizeof (int));
00815 CHECK_V_ERROR;
00816 marker = (int *) MALLOC_DH (m * sizeof (int));
00817 CHECK_V_ERROR;
00818 for (i = 0; i < m; ++i)
00819 marker[i] = -1;
00820 rp[0] = 0;
00821
00822
00823 for (i = 0; i < m; ++i)
00824 work[i] = 0.0;
00825
00826
00827 for (i = from; i < to; ++i)
00828 {
00829 int row = n2o_row[i];
00830 int globalRow = row + beg_row;
00831 EuclidGetRow (ctx->A, globalRow, &len, &CVAL, &AVAL);
00832 CHECK_V_ERROR;
00833
00834
00835 compute_scaling_private (i, len, AVAL, ctx);
00836 CHECK_V_ERROR;
00837
00838
00839 count = ilut_row_private (i, list, o2n_col, marker,
00840 len, CVAL, AVAL, work, ctx, debug);
00841 CHECK_V_ERROR;
00842
00843 EuclidRestoreRow (ctx->A, globalRow, &len, &CVAL, &AVAL);
00844 CHECK_V_ERROR;
00845
00846
00847 if (idx + count > F->alloc)
00848 {
00849 Factor_dhReallocate (F, idx, count);
00850 CHECK_V_ERROR;
00851 SET_INFO ("REALLOCATED from ilu_seq");
00852 cval = F->cval;
00853 aval = F->aval;
00854 }
00855
00856
00857
00858
00859
00860 col = list[m];
00861 while (count--)
00862 {
00863 val = work[col];
00864 if (col == i || fabs (val) > droptol)
00865 {
00866 cval[idx] = col;
00867 aval[idx++] = val;
00868 work[col] = 0.0;
00869 }
00870 col = list[col];
00871 }
00872
00873
00874 rp[i + 1] = idx;
00875
00876
00877 temp = rp[i];
00878 while (cval[temp] != i)
00879 ++temp;
00880 diag[i] = temp;
00881
00882
00883 if (!aval[diag[i]])
00884 {
00885 sprintf (msgBuf_dh, "zero diagonal in local row %i", i + 1);
00886 SET_V_ERROR (msgBuf_dh);
00887 }
00888 }
00889
00890
00891 if (beg_rowP)
00892 {
00893 int start = rp[from];
00894 int stop = rp[to];
00895 for (i = start; i < stop; ++i)
00896 cval[i] += beg_rowP;
00897 }
00898
00899 FREE_DH (list);
00900 FREE_DH (marker);
00901 END_FUNC_DH}
00902
00903
00904 #undef __FUNC__
00905 #define __FUNC__ "ilut_row_private"
00906 int
00907 ilut_row_private (int localRow, int *list, int *o2n_col, int *marker,
00908 int len, int *CVAL, double *AVAL,
00909 REAL_DH * work, Euclid_dh ctx, bool debug)
00910 {
00911 START_FUNC_DH Factor_dh F = ctx->F;
00912 int j, col, m = ctx->m, *rp = F->rp, *cval = F->cval;
00913 int tmp, *diag = F->diag;
00914 int head;
00915 int count = 0, beg_row;
00916 double val;
00917 double mult, *aval = F->aval;
00918 double scale, pv, pc;
00919 double droptol = ctx->droptol;
00920 double thresh = ctx->sparseTolA;
00921
00922 scale = ctx->scale[localRow];
00923 ctx->stats[NZA_STATS] += (double) len;
00924 beg_row = ctx->sg->beg_row[myid_dh];
00925
00926
00927
00928
00929
00930
00931 list[m] = m;
00932 for (j = 0; j < len; ++j)
00933 {
00934 tmp = m;
00935 col = *CVAL++;
00936 col -= beg_row;
00937 col = o2n_col[col];
00938 val = *AVAL++;
00939 val *= scale;
00940
00941 if (fabs (val) > thresh || col == localRow)
00942 {
00943 ++count;
00944 while (col > list[tmp])
00945 tmp = list[tmp];
00946 list[col] = list[tmp];
00947 list[tmp] = col;
00948 work[col] = val;
00949 marker[col] = localRow;
00950 }
00951 }
00952
00953
00954 if (marker[localRow] != localRow)
00955 {
00956 tmp = m;
00957 while (localRow > list[tmp])
00958 tmp = list[tmp];
00959 list[localRow] = list[tmp];
00960 list[tmp] = localRow;
00961 marker[localRow] = localRow;
00962 ++count;
00963 }
00964
00965
00966 head = m;
00967 while (list[head] < localRow)
00968 {
00969 int row = list[head];
00970
00971
00972 pc = work[row];
00973 if (pc != 0.0)
00974 {
00975 pv = aval[diag[row]];
00976 mult = pc / pv;
00977
00978
00979 if (fabs (mult) > droptol)
00980 {
00981 work[row] = mult;
00982
00983 for (j = diag[row] + 1; j < rp[row + 1]; ++j)
00984 {
00985 col = cval[j];
00986 work[col] -= (mult * aval[j]);
00987
00988
00989 if (marker[col] < localRow)
00990 {
00991 marker[col] = localRow;
00992 tmp = head;
00993 while (col > list[tmp])
00994 tmp = list[tmp];
00995 list[col] = list[tmp];
00996 list[tmp] = col;
00997 ++count;
00998 }
00999 }
01000 }
01001 }
01002 head = list[head];
01003 }
01004
01005 END_FUNC_VAL (count)}
01006
01007
01008 #undef __FUNC__
01009 #define __FUNC__ "check_constraint_private"
01010 bool
01011 check_constraint_private (Euclid_dh ctx, int p1, int j)
01012 {
01013 START_FUNC_DH bool retval = false;
01014 int i, p2;
01015 int *nabors, count;
01016 SubdomainGraph_dh sg = ctx->sg;
01017
01018 if (sg == NULL)
01019 {
01020 SET_ERROR (-1, "ctx->sg == NULL");
01021 }
01022
01023 p2 = SubdomainGraph_dhFindOwner (ctx->sg, j, true);
01024
01025
01026 nabors = sg->adj + sg->ptrs[p1];
01027 count = sg->ptrs[p1 + 1] - sg->ptrs[p1];
01028
01029
01030
01031
01032
01033
01034
01035 for (i = 0; i < count; ++i)
01036 {
01037
01038
01039 if (nabors[i] == p2)
01040 {
01041 retval = true;
01042 break;
01043 }
01044 }
01045
01046 END_FUNC_VAL (retval)}