99 if (
emodel->isParallel() ) {
111 VecDuplicate(globX, & globY);
113 MatMult(this->
mtrx, globX, globY);
126 VecCreate(PETSC_COMM_SELF, & globY);
127 VecSetType(globY, VECSEQ);
128 VecSetSizes(globY, PETSC_DECIDE, this->
nRows);
130 MatMult(this->
mtrx, globX, globY);
132 VecGetArray(globY, & ptr);
134 for (
int i = 0; i < this->
nRows; i++ ) {
135 answer[i] = ptr [ i ];
138 VecRestoreArray(globY, & ptr);
151 if (
emodel->isParallel() ) {
157 VecCreate(PETSC_COMM_SELF, & globY);
158 VecSetType(globY, VECSEQ);
159 VecSetSizes(globY, PETSC_DECIDE, this->
nColumns);
161 MatMultTranspose(this->
mtrx, globX, globY);
163 VecGetArray(globY, & ptr);
165 for (
int i = 0; i < this->
nColumns; i++ ) {
166 answer[i] = ptr [ i ];
169 VecRestoreArray(globY, & ptr);
182 if (
emodel->isParallel() ) {
196 VecCreate(PETSC_COMM_SELF, & globY);
197 VecSetType(globY, VECSEQ);
198 VecSetSizes(globY, PETSC_DECIDE, nr);
202 for (
int k = 0; k < nc; ++k ) {
204 VecCreateSeqWithArray(PETSC_COMM_SELF, 1, nrB, colVals.
givePointer(), & globX);
205 MatMult(this->
mtrx, globX, globY);
206 VecGetArray(globY, & resultsPtr);
207 for (
int i = 0; i < nr; ++i ) {
208 answer(i, k) = resultsPtr [ i ];
210 VecRestoreArray(globY, & resultsPtr);
218 MatMatMult(this->
mtrx, globB, MAT_INITIAL_MATRIX, PETSC_DEFAULT, & globC);
220 for (
int r = 0; r < nr; r++ ) {
221 MatGetRow(globC, r, NULL, NULL, & vals);
222 for (
int i = 0, i2 = r; i < nc; i++, i2 += nr ) {
223 aptr [ i2 ] = vals [ i ];
225 MatRestoreRow(globC, r, NULL, NULL, & vals);
315 if (
emodel->isParallel() ) {
316 OOFEM_ERROR(
"Parallel is not supported in manual matrix creation");
327 std :: vector< IntArray > rows_upper(
nRows), rows_lower(
nRows);
334 rows_upper [ ii - 1 ].insertSortedOnce(jj - 1);
336 rows_lower [ ii - 1 ].insertSortedOnce(jj - 1);
344 for (
int i = 0; i <
leqs; i++ ) {
345 d_nnz[i] = rows_upper [ i ].giveSize() + rows_lower [ i ].giveSize();
350 MatCreate(PETSC_COMM_SELF, &
mtrx);
352 MatSetFromOptions(
mtrx);
355 MatSetType(
mtrx, MATDENSE);
357 MatSetType(
mtrx, MATSEQAIJ);
362 MatSeqAIJSetPreallocation(
mtrx, 0, d_nnz.givePointer() );
364 MatSetOption(
mtrx, MAT_ROW_ORIENTED, PETSC_FALSE);
365 MatSetOption(
mtrx, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE);
391 if (
emodel->isParallel() ) {
406 std :: vector< IntArray > rows_upper(
nRows), rows_lower(
nRows);
409 elem->giveLocationArray(r_loc, r_s);
410 elem->giveLocationArray(c_loc, c_s);
411 for (
int ii : r_loc ) {
413 for (
int jj : c_loc ) {
416 rows_upper [ ii - 1 ].insertSortedOnce(jj - 1, c_loc.giveSize() / 2);
418 rows_lower [ ii - 1 ].insertSortedOnce(jj - 1, c_loc.giveSize() / 2);
426 std :: vector< IntArray >r_locs, c_locs;
427 for (
auto &gbc : domain->
giveBcs() ) {
431 for ( std :: size_t k = 0; k < r_locs.size(); k++ ) {
434 for (
int ii : krloc ) {
436 for (
int jj : kcloc ) {
439 rows_upper [ ii - 1 ].insertSortedOnce(jj - 1, kcloc.giveSize() / 2);
441 rows_lower [ ii - 1 ].insertSortedOnce(jj - 1, kcloc.giveSize() / 2);
452 for (
int i = 0; i <
leqs; i++ ) {
453 d_nnz[i] = rows_upper [ i ].giveSize() + rows_lower [ i ].giveSize();
454 total_nnz += d_nnz[i];
459 MatCreate(PETSC_COMM_SELF, &
mtrx);
461 MatSetFromOptions(
mtrx);
464 MatSetType(
mtrx, MATDENSE);
466 MatSetType(
mtrx, MATSEQAIJ);
471 MatSeqAIJSetPreallocation(
mtrx, 0, d_nnz.givePointer() );
473 MatSetOption(
mtrx, MAT_ROW_ORIENTED, PETSC_FALSE);
474 MatSetOption(
mtrx, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE);
508#ifdef __MPI_PARALLEL_MODE
519 #ifdef __VERBOSE_PARALLEL
528 #ifdef __VERBOSE_PARALLEL
538 std :: vector< IntArray > d_rows_upper(
leqs), d_rows_lower(
leqs);
539 std :: vector< IntArray > o_rows_upper(
leqs), o_rows_lower(
leqs);
548 elem->giveLocationArray(loc, s);
553 for (
int i = 1; i <= lloc.
giveSize(); i++ ) {
554 if ( ( ii = lloc.
at(i) ) ) {
555 for (
int j = 1; j <= lloc.
giveSize(); j++ ) {
556 if ( ( jj = gloc.
at(j) ) >= 0 ) {
558 if ( jj >= ( ii - 1 ) ) {
559 d_rows_upper [ ii - 1 ].insertSortedOnce(jj, loc.
giveSize() / 2);
561 d_rows_lower [ ii - 1 ].insertSortedOnce(jj, loc.
giveSize() / 2);
564 if ( jj >= ( ii - 1 ) ) {
565 o_rows_upper [ ii - 1 ].insertSortedOnce(jj, loc.
giveSize() / 2);
567 o_rows_lower [ ii - 1 ].insertSortedOnce(jj, loc.
giveSize() / 2);
580 for (
int n = 1; n <= n2lmap->
giveSize(); ++n ) {
581 if ( n2lmap->
at(n) ) {
582 d_rows_upper [ n2lmap->
at(n) - 1 ].insertSortedOnce( n2gmap->
at(n) );
586 for (
int i = 0; i <
leqs; i++ ) {
587 d_nnz[i] = d_rows_upper [ i ].giveSize() + d_rows_lower [ i ].giveSize();
588 o_nnz[i] = o_rows_upper [ i ].giveSize() + o_rows_lower [ i ].giveSize();
590 d_nnz_sym[i] = d_rows_upper [ i ].giveSize();
591 o_nnz_sym[i] = o_rows_upper [ i ].
giveSize();
600 MatCreate(this->
emodel->giveParallelComm(), &
mtrx);
602 MatSetType(
mtrx, MATMPIAIJ);
603 MatSetFromOptions(
mtrx);
604 MatMPIAIJSetPreallocation(
mtrx, 0, d_nnz.givePointer(), 0, o_nnz.givePointer() );
613 #ifdef __VERBOSE_PARALLEL
620 IntArray d_nnz, d_nnz_sym, indices, rowstart;
622 MatType type = MATSEQBAIJ;
624 MatCreate(PETSC_COMM_SELF, &
mtrx);
626 MatSetType(
mtrx, type);
627 MatSetFromOptions(
mtrx);
628 MatGetType(
mtrx, &type );
630 if ( strcmp(type, MATDENSE) != 0 ) {
632 std :: vector< IntArray > rows_upper(
leqs), blocks;
635 elem->giveLocationArray(loc, s);
636 for (
int ii : loc ) {
638 for (
int jj : loc ) {
640 rows_upper [ ii - 1 ].insertSortedOnce( jj - 1, loc.giveSize() );
648 std :: vector< IntArray > r_locs, c_locs;
649 for (
auto &gbc : domain->
giveBcs() ) {
653 for ( std :: size_t k = 0; k < r_locs.size(); k++ ) {
654 for (
int ii : r_locs [ k ] ) {
656 for (
int jj : c_locs [ k ] ) {
658 rows_upper [ ii - 1 ].insertSortedOnce( jj - 1, loc.
giveSize() );
669 for (
auto &row_upper : rows_upper ) {
670 nnz += row_upper.giveSize();
673 if ( strcmp(type, MATSEQAIJ) != 0 ) {
676 for (
int bsize = maxblock; bsize > 1; --bsize ) {
677 int nblocks = ceil(rows_upper.size() / (
double)bsize);
679 blocks.resize(nblocks);
680 for (
int i = 0; i <
leqs; i++ ) {
681 int blockrow = i / bsize;
682 for (
int j : rows_upper [ i ] ) {
683 int blockcol = j / bsize;
684 blocks [ blockrow ].insertSortedOnce( blockcol );
689 for (
auto &block : blocks ) {
690 bnnz += block.giveSize() * bsize * bsize;
692 OOFEM_LOG_DEBUG(
"Block size %d resulted in nnz = %d -> %d using %d^2 blocks\n", bsize, nnz, bnnz, nblocks);
693 if ( bnnz <= nnz * 1.2 ) {
704 int nblocks = ceil(rows_upper.size() / (
double)
blocksize);
705 d_nnz_sym.
resize(nblocks);
707 for (
int i = 0; i < nblocks; i++ ) {
708 d_nnz_sym[i] = blocks [ i ].
giveSize();
710 d_nnz[i] += d_nnz_sym[i];
711 for (
int jj : blocks [ i ] ) {
720 if ( strcmp(type, MATSEQAIJ) == 0 ) {
722 }
else if ( strcmp(type, MATSEQBAIJ) == 0 ) {
724 }
else if ( strcmp(type, MATSEQSBAIJ) == 0 ) {
729 MatSetOption(
mtrx, MAT_ROW_ORIENTED, PETSC_FALSE);
730 MatSetOption(
mtrx, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE);
731 MatSetOption(
mtrx, MAT_STRUCTURALLY_SYMMETRIC, PETSC_TRUE);
744#ifdef __MPI_PARALLEL_MODE
745 if (
emodel->isParallel() ) {
747 emodel->giveParallelContext(this->
di)->giveN2Gmap()->map2New(gloc, loc, 0);
754 for (
int i = 1; i <= ndofe; i++ ) {
755 gloc.
at(i) = loc.
at(i) - 1;
766 for (
int b = 0; b < nblocke; ++b ) {
769 if ( gloc[i] != -1 && gloc[i] % this->blocksize != 0 ) {
774 for (
int k = 1; k < this->blocksize; ++k ) {
775 bool ok_seq = gloc[i] + k == gloc[i+k];
776 bool ok_bc = gloc[i] == -1 && gloc[i+k] == -1;
777 if ( !(ok_bc || ok_seq) ) {
783 bloc[b] = gloc[i] == -1 ? -1 : gloc[i] /
blocksize;
797#ifdef __MPI_PARALLEL_MODE
798 if (
emodel->isParallel() ) {
801 emodel->giveParallelContext(this->
di)->giveN2Gmap()->map2New(grloc, rloc, 0);
802 emodel->giveParallelContext(this->
di)->giveN2Gmap()->map2New(gcloc, cloc, 0);
804 MatSetValues(this->
mtrx, grloc.giveSize(), grloc.givePointer(),
809 IntArray grloc(rsize), gcloc(csize);
810 for (
int i = 1; i <= rsize; i++ ) {
811 grloc.at(i) = rloc.
at(i) - 1;
814 for (
int i = 1; i <= csize; i++ ) {
815 gcloc.
at(i) = cloc.
at(i) - 1;
818 MatSetValues(this->
mtrx, rsize, grloc.givePointer(),
821#ifdef __MPI_PARALLEL_MODE
888#ifdef __MPI_PARALLEL_MODE
889 auto comm = this->
emodel->giveParallelComm();
891 auto comm = PETSC_COMM_SELF;
893 IntArray prows = rows, pcols = cols;
897 std::unique_ptr<PetscSparseMtrx> answer = std::make_unique<PetscSparseMtrx>(prows.
giveSize(), pcols.giveSize());
898 answer->emodel = this->
emodel;
902 ISCreateGeneral(comm, prows.
giveSize(), prows.
givePointer(), PETSC_USE_POINTER, & is_rows);
903 ISCreateGeneral(comm, pcols.giveSize(), pcols.givePointer(), PETSC_USE_POINTER, & is_cols);
904 MatGetSubMatrix(this->
mtrx, is_rows, is_cols, MAT_INITIAL_MATRIX, & answer->mtrx);
905 ISDestroy(& is_rows);
906 ISDestroy(& is_cols);
908 return std::move(answer);
981PetscSparseMtrx :: scatterG2L(Vec src,
FloatArray &dest)
const
985#ifdef __MPI_PARALLEL_MODE
986 if (
emodel->isParallel() ) {
990 VecCreateSeq(PETSC_COMM_SELF, neqs, & locVec);
992 VecScatter n2gvecscat;
994 VecScatterBegin(n2gvecscat, src, locVec, INSERT_VALUES, SCATTER_REVERSE);
995 VecScatterEnd(n2gvecscat, src, locVec, INSERT_VALUES, SCATTER_REVERSE);
996 VecScatterDestroy(& n2gvecscat);
999 VecGetArray(locVec, & ptr);
1000 for (
int i = 0; i < neqs; i++ ) {
1001 dest.
at(i + 1) = ptr [ i ];
1004 VecRestoreArray(locVec, & ptr);
1005 VecDestroy(& locVec);
1010 VecGetArray(src, & ptr);
1011 for (
int i = 0; i < neqs; i++ ) {
1012 dest.
at(i + 1) = ptr [ i ];
1014 VecRestoreArray(src, & ptr);
1015#ifdef __MPI_PARALLEL_MODE
int giveNumberOfDofManagers() const
Returns number of dof managers in domain.
std ::vector< std ::unique_ptr< GeneralBoundaryCondition > > & giveBcs()
DofManager * giveDofManager(int n)
std ::vector< std ::unique_ptr< Element > > & giveElements()
Natural2GlobalOrdering * giveN2Gmap()
Natural2LocalOrdering * giveN2Lmap()