Example #1
0
void
CompCol_ICPreconditioner :: initialize(const CompCol &A)
{
    dim_ [ 0 ] = A.dim(0);
    dim_ [ 1 ] = A.dim(1);

    pntr_.resize(A.dim(1) + 1);


    int i, j, k;

    nz_ = 0;
    for ( k = 0; k < dim_ [ 1 ]; k++ ) {
        for ( j = A.col_ptr(k); j < A.col_ptr(k + 1); j++ ) {
            if ( A.row_ind(j) >= k ) {
                nz_++;
            }
        }
    }

    val_.resize(nz_);
    indx_.resize(nz_);

    // Copy just triangular part
    pntr_(0) = 0;
    for ( k = 0; k < dim_ [ 1 ]; k++ ) {
        pntr_(k + 1) = pntr_(k);
        for ( j = A.col_ptr(k); j < A.col_ptr(k + 1); j++ ) {
            if ( A.row_ind(j) >= k ) {
                i = pntr_(k + 1)++;
                val_(i) = A.val(j);
                indx_(i) = A.row_ind(j);
            }
        }
    }

    //  for (i = 0; i < dim_[1]; i++)
    //    qsortRow(indx_, val_, pntr_(i), pntr_(i+1) -1);

    for ( i = 0; i < dim_ [ 1 ]; i++ ) {
        if ( indx_( pntr_(i) ) != i ) {
            OOFEM_ERROR("diagonal not found!");
        }
    }

    this->ICFactor();
}
Example #2
0
void
CompCol_ICPreconditioner :: ICFactor()
{
    int d, g, h, i, j, k, n = pntr_.giveSize() - 1;
    double z;

    for ( k = 0; k < n - 1; k++ ) {
        d = pntr_(k);
        z = val_(d) = sqrt( val_(d) );

        for ( i = d + 1; i < pntr_(k + 1); i++ ) {
            val_(i) /= z;
        }

        for ( i = d + 1; i < pntr_(k + 1); i++ ) {
            z = val_(i);
            h = indx_(i);
            g = i;

            for ( j = pntr_(h); j < pntr_(h + 1); j++ ) {
                for ( ; g < pntr_(k + 1) && indx_(g + 1) <= indx_(j); g++ ) {
                    if ( indx_(g) == indx_(j) ) {
                        val_(j) -= z * val_(g);
                    }
                }
            }
        }
    }

    d = pntr_(n - 1);
    val_(d) = sqrt( val_(d) );
}
Example #3
0
ICPreconditioner_double::ICPreconditioner_double(const CompRow_Mat_double &A)
  : val_(0), pntr_(A.dim(0)+1), indx_(0), nz_(0)
{
  dim_[0] = A.dim(0);
  dim_[1] = A.dim(1);

  int i, j, k;

  for (k = 0; k < dim_[0]; k++)
    for (j = A.row_ptr(k); j < A.row_ptr(k+1); j++)
      if (A.col_ind(j) >= k)
    nz_++;

  val_.newsize(nz_);
  indx_.newsize(nz_);

  // Copy just triangular part (including diagonal)
  pntr_(0) = 0;
  for (k = 0; k < dim_[0]; k++) {
    pntr_(k+1) = pntr_(k);
    for (j = A.row_ptr(k); j < A.row_ptr(k+1); j++) {
      if (A.col_ind(j) >= k) {
    i = pntr_(k+1)++;
    val_(i) = A.val(j);
    indx_(i) = A.col_ind(j);
      }
    }
  }

  for (i = 0; i < dim_[0]; i++)
    QSort(indx_, val_, pntr_[i], pntr_[i+1] - pntr_[i]);

  for (i = 0; i < dim_[0]; i++)
    if (indx_[pntr_(i)] != i) {
      std::cerr << "IC Preconditioner: diagonal not found!" << i << "\n";
      exit(1);
    }
  
  ICFactor(pntr_, indx_, val_);
}
Example #4
0
void
CompCol_ICPreconditioner :: ICSolve(FloatArray &dest) const
{
    int i, t, M = dest.giveSize();
    FloatArray work(M);
    double val;
    // lower diag

    work.zero();
    // solve Uw=x
    for ( i = 0; i < M; i++ ) {
        work(i) = val = ( dest(i) + work(i) ) / val_( pntr_(i) );
        for ( t = pntr_(i) + 1; t < pntr_(i + 1); t++ ) {
            work( indx_(t) ) -= val_(t) * val;
        }
    }

    dest.zero();
    // solve U^Ty=w
    for ( i = M - 1; i >= 0; i-- ) {
        for ( t = pntr_(i) + 1; t < pntr_(i + 1); t++ ) {
            dest(i) -= val_(t) * dest( indx_(t) );
        }

        dest(i) = ( work(i) + dest(i) ) / val_( pntr_(i) );
    }
}