85std::unique_ptr<SparseMtrx> DynCompRow :: clone()
const
87 return std::make_unique<DynCompRow>(*
this);
94 OOFEM_ERROR(
"Error in CompRow -- incompatible dimensions");
100 for (
int j = 0; j <
nRows; j++ ) {
102 for (
int t = 1; t <=
rows [ j ].giveSize(); t++ ) {
103 r +=
rows [ j ].at(t) * x[
colind [ j ].at(t) ];
110void DynCompRow :: times(
double x)
136 elem->giveLocationArray(loc, s);
137 for (
int i = 1; i <= loc.
giveSize(); i++ ) {
139 if ( ( ii = loc.
at(i) ) ) {
140 for (
int j = 1; j <= loc.
giveSize(); j++ ) {
142 if ( ( jj = loc.
at(j) ) ) {
151 std :: vector< IntArray >r_locs;
152 std :: vector< IntArray >c_locs;
154 for (
auto &gbc : domain->
giveBcs() ) {
158 for ( std :: size_t k = 0; k < r_locs.size(); k++ ) {
161 for (
int i = 1; i <= krloc.
giveSize(); i++ ) {
163 if ( ( ii = krloc.
at(i) ) ) {
164 for (
int j = 1; j <= kcloc.
giveSize(); j++ ) {
166 if ( ( jj = kcloc.
at(j) ) ) {
180 for (
auto &in: eModel->giveIntegralList()) {
182 for (
auto &elem: in->set->giveElementList()) {
184 in->getElementTermCodeNumbers (locr, locc, domain->
giveElement(elem), *in->term, s) ;
185 for (
int i = 1; i <= locr.
giveSize(); i++ ) {
187 if ( ( ii = locr.
at(i) ) ) {
188 for (
int j = 1; j <= locc.
giveSize(); j++ ) {
190 if ( ( jj = locc.
at(j) ) ) {
202 for (
auto &col : this->
colind ) {
203 nz_ += col.giveSize();
206 OOFEM_LOG_DEBUG(
"DynCompRow info: neq is %d, nelem is %d\n", neq, nz_);
224 OOFEM_ERROR(
"dimension of 'k' and 'loc' mismatch");
228 for (
int j = 1; j <= dim; j++ ) {
231 for (
int i = 1; i <= dim; i++ ) {
234 this->
at(ii, jj) += mat.
at(i, j);
251 for (
int i = 0; i < rsize; i++ ) {
253 if ( ( ii = rloc[i] ) ) {
255 for (
int j = 0; j < csize; j++ ) {
257 if ( ( jj = cloc[j] ) ) {
261 rows [ ii1 ].at(colindx) += mat(i, j);
271void DynCompRow :: zero()
281void DynCompRow :: printStatistics()
const
285 nz +=
row.giveSize();
288 printf(
"\nDynCompRow info: neq is %d, nelem is %d\n",
nRows, nz);
292double &DynCompRow :: at(
int i,
int j)
297 if ( ( colIndx = this->
giveColIndx(i - 1, j - 1) ) ) {
298 return rows [ i - 1 ].at(colIndx);
301 OOFEM_ERROR(
"Array accessing exception -- (%d,%d) out of bounds", i, j);
302 return rows [ 0 ].at(1);
306double DynCompRow :: at(
int i,
int j)
const
309 if ( ( colIndx = this->
giveColIndx(i - 1, j - 1) ) ) {
310 return rows [ i - 1 ].at(colIndx);
316 OOFEM_ERROR(
"Array accessing exception -- (%d,%d) out of bounds", i, j);
317 return rows [ 0 ].at(1);
321double DynCompRow :: operator() (
int i,
int j)
const
325 return rows [ i ].at(colIndx);
331 OOFEM_ERROR(
"Array accessing exception -- (%d,%d) out of bounds", i, j);
332 return rows [ 0 ].at(1);
336double &DynCompRow :: operator() (
int i,
int j)
344 return rows [ i ].at(colIndx);
347 OOFEM_ERROR(
"Array element (%d,%d) not in sparse structure -- cannot assign", i, j);
348 return rows [ 0 ].at(1);
355 OOFEM_ERROR(
"Error in CompRow -- incompatible dimensions");
361 for (
int i = 0; i <
nColumns; i++ ) {
363 for (
int t = 1; t <=
rows [ i ].giveSize(); t++ ) {
364 answer[
colind [ i ].at(t) ] +=
rows [ i ].at(t) * r;
376 for (
int i = 0; i < size; i++ ) {
377 maxid =
max( maxid, loc[i] );
382 for (
int i = 0; i < size; i++ ) {
384 if ( ( ii = loc[i] ) ) {
385 for (
int j = 0; j < size; j++ ) {
387 if ( ( jj = loc[j] ) ) {
403 for (
int i = 0; i < rsize; i++ ) {
404 maxid =
max( maxid, rloc[i] );
407 for (
int i = 0; i < csize; i++ ) {
408 maxid =
max( maxid, cloc[i] );
413 for (
int i = 0; i < rsize; i++ ) {
415 if ( ( ii = rloc[i] ) ) {
416 for (
int j = 0; j < csize; j++ ) {
418 if ( ( jj = cloc[j] ) ) {
427void DynCompRow :: growTo(
int ns)
430 this->
rows.resize(ns);
437int DynCompRow :: giveColIndx(
int row,
int col)
const
440 int left = 1, right = this->
colind [
row ].giveSize();
441 int middle = ( left + right ) / 2;
452 while ( !( ( ( middleVal = this->
colind [
row ].
at(middle) ) == col ) || ( middle == left ) ) ) {
453 if ( col > middleVal ) {
459 middle = ( left + right ) / 2;
462 if ( middleVal == col ) {
471DynCompRow :: insertColInRow(
int row,
int col)
474 int oldsize = this->
colind [
row ].giveSize();
475 int left = 1, right = oldsize;
476 int middle = ( left + right ) / 2;
479 if ( oldsize == 0 ) {
491 while ( !( ( ( middleVal = this->
colind [
row ].
at(middle) ) == col ) || ( middle == left ) ) ) {
492 if ( col > middleVal ) {
498 middle = ( left + right ) / 2;
501 if ( middleVal == col ) {
516 for (
int i = oldsize; i >= right; i-- ) {
529#define ILU_ROW_CHUNK 10
533DynCompRow :: ILUPYourself(
int part_fill,
double drop_tol)
544 for (
int i = 0; i <
nRows; i++ ) {
552 for (
int i = 1; i <
nRows; i++ ) {
554 for (
int ii = 1; ii <=
rows [ i ].giveSize(); ii++ ) {
555 double val =
rows [ i ].at(ii);
563 for (
int kk = 1; kk <=
rows [ i ].giveSize(); kk++ ) {
564 irw[
colind [ i ].at(kk) ] = kk;
565 iw[kk - 1] =
colind [ i ].at(kk);
566 w[kk - 1] =
rows [ i ].at(kk);
571 while ( iw.
at(k + 1) < i ) {
573 int krow = iw.
at(k + 1);
575 double multiplier = ( w.
at(k + 1) /=
rows [ krow ].
at(
diag[krow] ) );
579 if ( fabs(multiplier) >= drop_tol * inorm )
582 for (
int j = 0; j <
colind [ krow ].giveSize(); j++ ) {
583 int jcol =
colind [ krow ].at(j + 1);
587 w.
at( irw[jcol] ) -= multiplier *
rows [ krow ].at(j + 1);
595 iw.
at(newsize) = jcol;
596 w.
at(newsize) = -multiplier *
rows [ krow ].at(j + 1);
617 for (
int kk = 0; kk < iw.
giveSize(); kk++ ) {
618 if ( ( ( iw[kk] - krow ) > 0 ) && ( ( iw[kk] - krow ) < ( ck - krow ) ) ) {
631 while ( curr <= end ) {
632 if ( ( fabs( w.
at(curr) ) < drop_tol * inorm ) && ( iw.
at(curr) != i ) ) {
634 w.
at(curr) = w.
at(end);
635 irw[ iw.
at(curr) ] = 0;
636 iw.
at(curr) = iw.
at(end);
638 irw[ iw.
at(curr) ] = curr;
656 int lsizeLimit =
diag[i] - 1;
657 int usizeLimit =
rows [ i ].giveSize() - lsizeLimit;
659 lsizeLimit += part_fill;
660 usizeLimit += part_fill;
665 for (
int kk = 1; kk <= iw.
giveSize(); kk++ ) {
666 if ( iw.
at(kk) < i ) {
667 if ( ++lnums > lsizeLimit ) {
668 irw[ iw.
at(kk) ] = 0;
672 }
else if ( iw.
at(kk) > i ) {
673 if ( ++unums > usizeLimit ) {
674 irw[ iw.
at(kk) ] = 0;
686 rows [ i ].resize(count);
687 colind [ i ].resize(count);
690 int indx, idist, previndx = -1;
693 for (
int kk = 1; kk <= count; kk++ ) {
697 for (
int kki = 1; kki <= kkend; kki++ ) {
698 if ( ( irw[ iw.
at(kki) ] != 0 ) && ( iw.
at(kki) > previndx ) && ( ( iw.
at(kki) - previndx ) < idist ) ) {
699 idist = iw.
at(kki) - previndx;
708 previndx = iw.
at(indx);
709 rows [ i ].at(icount) = w.
at(indx);
710 colind [ i ].at(icount) = iw.
at(indx);
711 if (
colind [ i ].
at(icount) == i ) {
718 irw[ iw.
at(indx) ] = 0;
719 iw.
at(indx) = iw.
at(kkend);
720 w.
at(indx) = w.
at(kkend);
721 if ( irw[ iw.
at(indx) ] != 0 ) {
722 irw[ iw.
at(indx) ] = indx;
729 std::swap(irw[iw.
at(indx)], irw[iw.
at(kkend)]);
730 std::swap(iw.
at(indx), iw.
at(kkend));
731 std::swap(w.
at(indx), w.
at(kkend));
740 if ( irw.at(kk) > 0 ) {
741 rows[i].at(icount) = w.
at(abs(irw[kk-1]));
742 colind[i].at(icount) = iw.
at(abs(irw[kk-1]));
748 if ( ( icount - count ) != 1 ) {
749 OOFEM_ERROR(
"%d - row errorr (%d,%d)\n", i, icount, count);
753 for (
int kk = 1; kk <= iw.
giveSize(); kk++ ) {
754 irw[ iw.
at(kk) ] = 0;
762 OOFEM_LOG_DEBUG(
"\nILUT(%d,%e): user time consumed by factorization: %.2fs\n", part_fill, drop_tol, timer.
getUtime() );
777 for (
int i = 0; i < M; i++ ) {
779 for (
int t = 0; t < (
diag[i] - 1 ); t++ ) {
780 r -=
rows [ i ].at(t + 1) * work(
colind [ i ].
at(t + 1) );
789 for (
int i = M - 1; i >= 0; i-- ) {
791 for (
int t =
diag[i]; t <
rows [ i ].giveSize(); t++ ) {
792 r -=
rows [ i ].at(t + 1) * y(
colind [ i ].
at(t + 1) );
795 y[i] = r /
rows [ i ].at(
diag[i] );
809 for (
int i = 0; i < M; i++ ) {
810 work[i] = ( x[i] + work[i] ) /
rows [ i ].
at(
diag[i] );
811 for (
int t =
diag[i]; t <
rows [ i ].giveSize(); t++ ) {
812 work(
colind [ i ].
at(t + 1) ) -=
rows [ i ].at(t + 1) * work[i];
817 for (
int i = M - 1; i >= 0; i-- ) {
819 for (
int t = 1; t <
diag[i]; t++ ) {
842 int i = l - 1, j = r;
843 double v = fabs( val[r] );
846 while ( ( fabs( val(++i) ) > v ) ) {
850 while ( ( v > fabs( val(--j) ) ) ) {
860 std::swap(ir[ ind[i] ], ir[ ind[j] ]);
861 std::swap(ind[i], ind[j]);
862 std::swap(val[i], val[j]);
865 std::swap(ir[ ind[i] ], ir[ ind[r] ]);
866 std::swap(ind[i], ind[r]);
867 std::swap(val[i], val[r]);
#define REGISTER_SparseMtrx(class, type)
virtual void giveLocationArrays(std ::vector< IntArray > &rows, std ::vector< IntArray > &cols, CharType type, const UnknownNumberingScheme &r_s, const UnknownNumberingScheme &c_s)
std ::vector< std ::unique_ptr< GeneralBoundaryCondition > > & giveBcs()
Element * giveElement(int n)
std ::vector< std ::unique_ptr< Element > > & giveElements()
int giveColIndx(int row, int col) const
returns the column index of given column at given row, else returns zero.
std::vector< FloatArray > rows
data values per column
std::vector< IntArray > colind
row_ind per column
void qsortRow(IntArray &ind, IntArray &ir, FloatArray &val, int l, int r)
int qsortRowPartition(IntArray &ind, IntArray &ir, FloatArray &val, int l, int r)
IntArray diag
pointers to the diagonal elements; needed only for ILU
int base
index base: offset of first element
double & at(int i, int j) override
Returns coefficient at position (i,j).
int insertColInRow(int row, int col)
insert column entry into row, preserving order of column indexes, returns the index of new row.
const FloatArray & row(int i) const
Returns row values.
virtual int giveNumberOfDomainEquations(int di, const UnknownNumberingScheme &num)
Domain * giveDomain(int n)
Index giveSize() const
Returns the size of receiver.
void resizeWithValues(Index s, std::size_t allocChunk=0)
void zero()
Zeroes all coefficients of receiver.
int giveNumberOfRows() const
Returns number of rows of receiver.
double at(std::size_t i, std::size_t j) const
void resizeWithValues(int n, int allocChunk=0)
int nColumns
Number of columns.
SparseMtrxVersionType version
SparseMtrx(int n=0, int m=0)
double getUtime()
Returns total user time elapsed in seconds.
#define OOFEM_LOG_DEBUG(...)
FloatArrayF< N > max(const FloatArrayF< N > &a, const FloatArrayF< N > &b)
@ SMT_DynCompRow
Dynamically growing compressed row.