예제 #1
0
DSS_NAMESPASE_BEGIN

SparseConectivityMtxII :: SparseConectivityMtxII(const SparseMatrixF &sm, char block_size)
{
    n = ( long ) sm.neq / block_size + ( ( ( sm.neq % block_size ) == 0 ) ? 0 : 1 );
    nonzeros = 0;
    ColumnsIndexes = new IntArrayList * [ n ];
    for ( long bj = 0; bj < n; bj++ ) {
        ColumnsIndexes [ bj ] = new IntArrayList();
    }

    long *pmask = new long [ n ];
    memset( pmask, 0, n * sizeof( long ) );
    IntArrayList *this_columnJ = NULL;

    // Fill the upper half of the matrix
    for ( unsigned long j = 0; j < sm.neq; j++ ) {
        long bj = j / block_size;

        if ( j % block_size == 0 ) {
            this_columnJ = ColumnsIndexes [ bj ];
        }

        long lastbi = -1;
        for ( unsigned long ad = sm.Adr(j); ad < sm.Adr(j + 1); ad++ ) {
            long i = sm.Ci(ad);
            long bi = i / block_size;
            if ( bi == bj || bi == lastbi ) {
                continue;
            }

            lastbi = bi;

            if ( pmask [ bi ] == 0 ) {
                nonzeros++;
                this_columnJ->SortInsert(bi);
                pmask [ bi ] = 1;
            }
        }

        if ( ( long ) ( j % block_size ) == ( long ) ( block_size - 1 ) ) {
            this_columnJ->SetIndexesTo(pmask, 0);
        }
    }

    // Fill lower half of the matrix
    for ( unsigned long i = 0; i < sm.neq; i++ ) {
        long bi = i / block_size;

        long lastbj = -1;
        for ( unsigned long ad = sm.Adr(i); ad < sm.Adr(i + 1); ad++ ) {
            long j = sm.Ci(ad);
            long bj = j / block_size;
            if ( bi == bj || bj == lastbj ) {
                continue;
            }

            lastbj = bj;

            if ( ColumnsIndexes [ bj ]->AddIfNotLast(bi) >= 0 ) {
                nonzeros++;
            }
        }
    }

    if ( pmask ) {
        delete [] pmask;
    }

    pmask = NULL;
}
예제 #2
0
void SparseGridMtxLU :: LoadMatrixNumbers(SparseMatrixF &sm)
{
    LoadZeros();
    long *blockP = this->block_order->perm->Items;
    long *nodeP = this->node_order ? node_order->perm->Items : NULL;

    long aux_bi_idx = 0;        // index of the last found block in the column
    long aux_bj_idx = 0;

    for ( unsigned long j = 0; j < sm.neq; j++ ) {
        long nj = ( nodeP == NULL ) ? j : nodeP [ j ];

        long sj = nj % block_size;
        long bj = nj / block_size;
        long nbj = ( blockP == NULL ) ? bj : blockP [ bj ];

        SparseGridColumn *Column_nbj = Columns [ nbj ];
        SparseGridColumn *Column_nbi = NULL;

        double *column_nbj_bi_data = NULL;
        double *row_nbi_bj_data = NULL;

        long old_nbi = -1;

        for ( unsigned long ad = sm.Adr(j); ad < sm.Adr(j + 1); ad++ ) {
            long i = ( long ) sm.Ci(ad);
            long ni = ( nodeP == NULL ) ? i : nodeP [ i ];
            double val = sm.a [ ad ];

            long si = ni % block_size;
            long bi = ni / block_size;
            long nbi = ( blockP == NULL ) ? bi : blockP [ bi ];

            if ( old_nbi != nbi ) {
                Column_nbi = Columns [ nbi ];
                aux_bj_idx = aux_bi_idx = -1;
                if ( nbi < nbj ) {
                    aux_bi_idx = Column_nbj->FindExistingBlockIndex(nbi);
                    column_nbj_bi_data = Columns_data + Column_nbj->column_start_idx + aux_bi_idx * block_storage;
                } else if ( nbi > nbj )       {
                    aux_bj_idx = Column_nbi->FindExistingBlockIndex(nbj);
                    row_nbi_bj_data = Rows_data + Column_nbi->column_start_idx + aux_bj_idx * block_storage;
                }

                old_nbi = nbi;
            }

            if ( aux_bi_idx < 0 && aux_bj_idx < 0 ) {           //diagonal index
                Diagonal_data [ nbi * block_storage + si + sj * block_size ] = val;
            } else if ( aux_bi_idx >= 0 ) {     // write into column bj
                column_nbj_bi_data [ block_size * sj + si ] = val;
            } else {                                            // write into row bi
                row_nbi_bj_data [ block_size * si + sj ] = val;
            }

            nonzeros++;
        }
    }

    //long bl = n_blocks-1;
    //long nbl = (blockP==NULL)?bl:blockP[bl];

    // Dummy DOFs
    //for (long i=block_size-1; i>=block_size-noDummyDOFs; i--)
    //Columns_data[nbl*block_storage + block_size*i + i] = 1.0;
    //this->SetValue(nbl,nbl,i,i,1.0,aux_bi_idx,aux_bj_idx);

    /*long dzeros = 0;
     *      //Check diagonal for zeros
     *      for (long bj=0; bj<n_blocks; bj++)
     *              for (long j=0; j<block_size; j++)
     *                      if (Columns_data[bj*block_storage + block_size*j + j] == 0.0)
     *                      {
     *                              Columns_data[bj*block_storage + block_size*j + j] = 1.0;
     *                              dzeros++;
     *                      }*/
    //if (dzeros>0)
    //{
    //char str[128];
    //sprintf(str,"Matrix had %ld zeros on diagonal!",dzeros);
    //eMT->Writeln(str);
    //}
}
예제 #3
0
SparseConectivityMtxII :: SparseConectivityMtxII(const SparseMatrixF &sm, Ordering *node_order, char block_size)
{
    long *nprm = NULL;
    if ( node_order ) {
        nprm = node_order->perm->Items;
        n = node_order->order->Count / block_size;
    } else {
        n = ( long ) sm.neq / block_size + ( ( ( sm.neq % block_size ) == 0 ) ? 0 : 1 );
    }

    nonzeros = 0;
    ColumnsIndexes = new IntArrayList * [ n ];
    for ( long bj = 0; bj < n; bj++ ) {
        ColumnsIndexes [ bj ] = new IntArrayList();
    }

    long *pmask = new long [ n ];
    memset( pmask, 0, n * sizeof( long ) );
    IntArrayList *this_columnJ = NULL;


    long old_bj = -1;

    // Fill the upper half of the matrix
    for ( unsigned long j = 0; j < sm.neq; j++ ) {
        long nj = node_order ? node_order->perm->Items [ j ] : j;
        long bj = nj / block_size;

        if ( bj != old_bj ) {
            if ( this_columnJ ) {
                this_columnJ->SetIndexesTo(pmask, 0);
            }

            this_columnJ = ColumnsIndexes [ bj ];
            old_bj = bj;
        }

        long lastbi = -1;
        for ( unsigned long ad = sm.Adr(j); ad < sm.Adr(j + 1); ad++ ) {
            long i = sm.Ci(ad);

            long ni = nprm ? nprm [ i ] : i;

            long bi = ni / block_size;
            if ( bi == bj || bi == lastbi ) {
                continue;
            }

            lastbi = bi;

            if ( pmask [ bi ] == 0 ) {
                nonzeros++;
                this_columnJ->SortInsert(bi);
                pmask [ bi ] = 1;
            }
        }
    }

    // Fill lower half of the matrix
    for ( unsigned long i = 0; i < sm.neq; i++ ) {
        long ni = nprm ? nprm [ i ] : i;

        long bi = ni / block_size;

        long lastbj = -1;
        for ( unsigned long ad = sm.Adr(i); ad < sm.Adr(i + 1); ad++ ) {
            long j = sm.Ci(ad);
            long nj = nprm ? nprm [ j ] : j;

            long bj = nj / block_size;
            if ( bi == bj || bj == lastbj ) {
                continue;
            }

            lastbj = bj;

            // I have to think about this better
            //if (ColumnsIndexes[bj]->AddIfNotLast(bi)>=0)
            //nonzeros++;
            if ( ColumnsIndexes [ bj ]->SortInsertIfNot(bi) >= 0 ) {
                nonzeros++;
            }
        }
    }

    if ( pmask ) {
        delete [] pmask;
    }

    pmask = NULL;
}