コード例 #1
0
ファイル: icprecond.C プロジェクト: vivianyw/oofem
void
CompCol_ICPreconditioner :: qsortRow(IntArray &src, FloatArray &val, int l, int r)
{
    if ( r <= l ) {
        return;
    }

    int i = qsortRowPartition(src, val, l, r);
    qsortRow(src, val, l, i - 1);
    qsortRow(src, val, i + 1, r);
}
コード例 #2
0
ファイル: iluprecond.C プロジェクト: MartinFagerstrom/oofem
void
CompCol_ILUPreconditioner :: initialize(const DynCompCol &A)
{
    int i, j, k, pn, qn, rn;
    double multiplier;

    // Copy
    dim_ [ 0 ] = A.giveNumberOfRows();
    dim_ [ 1 ] = A.giveNumberOfColumns();

    l_colptr_.resize(A.giveNumberOfColumns() + 1);
    u_colptr_.resize(A.giveNumberOfColumns() + 1);

    l_nz_ = 0;
    u_nz_ = 0;

#ifndef DynCompCol_USE_STL_SETS
    // Get size of l and u
    for ( i = 0; i < dim_ [ 1 ]; i++ ) {
        for ( j = 0; j < A.row_ind(i)->giveSize(); j++ ) {
            if ( A.row_ind(i)->at(j + 1) > i ) {
                l_nz_++;
            } else {
                u_nz_++;
            }
        }
    }

    l_val_.resize(l_nz_);
    u_val_.resize(u_nz_);
    l_rowind_.resize(l_nz_);
    u_rowind_.resize(u_nz_);

    l_colptr_(0) = u_colptr_(0) = 0;

    // Split up A into l and u
    for ( i = 0; i < dim_ [ 1 ]; i++ ) {
        l_colptr_(i + 1) = l_colptr_(i);
        u_colptr_(i + 1) = u_colptr_(i);

        for ( j = 0; j < A.row_ind(i)->giveSize(); j++ ) {
            if ( A.row_ind(i)->at(j + 1) > i ) {
                k = l_colptr_(i + 1)++;
                l_val_(k) = A.column(i)->at(j + 1);
                l_rowind_(k) = A.row_ind(i)->at(j + 1);
            } else if ( A.row_ind(i)->at(j + 1) <= i ) {
                k = u_colptr_(i + 1)++;
                u_val_(k) = A.column(i)->at(j + 1);
                u_rowind_(k) = A.row_ind(i)->at(j + 1);
            }
        }
    }

#else
    std :: map< int, double > :: iterator pos;
    // Get size of l and u
    for ( i = 0; i < dim_ [ 1 ]; i++ ) {
        for ( pos = A.column(i)->begin(); pos != A.column(i)->end(); ++pos ) {
            if ( pos->first > i ) {
                l_nz_++;
            } else {
                u_nz_++;
            }
        }
    }

    l_val_.resize(l_nz_);
    u_val_.resize(u_nz_);
    l_rowind_.resize(l_nz_);
    u_rowind_.resize(u_nz_);

    l_colptr_(0) = u_colptr_(0) = 0;

    // Split up A into l and u
    for ( i = 0; i < dim_ [ 1 ]; i++ ) {
        l_colptr_(i + 1) = l_colptr_(i);
        u_colptr_(i + 1) = u_colptr_(i);

        for ( pos = A.column(i)->begin(); pos != A.column(i)->end(); ++pos ) {
            if ( pos->first > i ) {
                k = l_colptr_(i + 1)++;
                l_val_(k) = pos->second;
                l_rowind_(k) = pos->first;
            } else if ( pos->first <= i ) {
                k = u_colptr_(i + 1)++;
                u_val_(k) = pos->second;
                u_rowind_(k) = pos->first;
            }
        }
    }

#endif
    /* sort entries to assure entries stored with increasing row index */

    for ( i = 0; i < dim_ [ 1 ]; i++ ) {
        qsortRow(l_rowind_, l_val_, l_colptr_(i), l_colptr_(i + 1) - 1);
        qsortRow(u_rowind_, u_val_, u_colptr_(i), u_colptr_(i + 1) - 1);
    }

    // Factor matrix
    for ( i = 0; i < dim_ [ 0 ] - 1; i++ ) {
        multiplier = u_val_(u_colptr_(i + 1) - 1);

        for ( j = l_colptr_(i); j < l_colptr_(i + 1); j++ ) {
            l_val_(j) /= multiplier;
        }

        for ( j = u_colptr_(i + 1); j < u_colptr_(i + 2) - 1; j++ ) {
            multiplier = u_val_(j);
            qn = j + 1;
            rn = l_colptr_(i + 1);
            for ( pn = l_colptr_( u_rowind_(j) );
                    pn < l_colptr_(u_rowind_(j) + 1) && l_rowind_(pn) <= i + 1; pn++ ) {
                while ( qn < u_colptr_(i + 2) && u_rowind_(qn) < l_rowind_(pn) ) {
                    qn++;
                }

                if ( qn < u_colptr_(i + 2) && l_rowind_(pn) == u_rowind_(qn) ) {
                    u_val_(qn) -= multiplier * l_val_(pn);
                }
            }

            for ( ; pn < l_colptr_(u_rowind_(j) + 1); pn++ ) {
                while ( rn < l_colptr_(i + 2) && l_rowind_(rn) < l_rowind_(pn) ) {
                    rn++;
                }

                if ( rn < l_colptr_(i + 2) && l_rowind_(pn) == l_rowind_(rn) ) {
                    l_val_(rn) -= multiplier * l_val_(pn);
                }
            }
        }
    }
}