Hi Wolfgang,
Fortunately, I managed to solve that problem. I found that every single
operation on the iterator needs to call row_length(), which
requires the assembled status of the matrix, and apparently set() operation
will break this status. My solution is to iterate and cache
the rows, columns, values information in a big vector and use another loop
to set them all in a time without the use of iterator.
Now I have another issue, which is I think is not so much reasonable in the
way of implementation: (but I cannot think of a better way,
:(
The problem is that I still encounter the "out of range" problem even when
I do iterator over the local rows. I debugged my code and
checked the source code, and found where the problem is:
The end iterator of each row is pointing to the first entry of the next row
(or true end if the row is the end row).
However when we have multiple ranks, when one wants to get the end iterator
of the last LOCAL row, the end
iterator will point to the next row, which is not belong to local.
Let me take an example to be clear:
I have 1223 rows, where rank 0 has the information of row 0 to 633 and rank
1 has 634 to 1222.
When I iterate over the entries on rank 1, everything works as it is.
When I iterate over the entries on rank 0, especially when it reaches row
633, I will call matrix.end(633)
However this end is essentially matrix.begin(634)! So PETSc tells me I am
out of range, because rank 0
does not have information of row 634.
I have attached the source code here for your reference:
in petsc__matrix__base.h file
1449 inline
1450 MatrixBase::const_iterator
1451 MatrixBase::end(const size_type r) const
1452 {
1453 Assert
<http://www.dealii.org/8.5.0/doxygen/deal.II/group__Exceptions.html#ga70a0bb353656e704acf927945277bbc6>
(r < m(), ExcIndexRange
<http://www.dealii.org/8.5.0/doxygen/deal.II/group__Exceptions.html#ga0d685aad996180f9851183ae3e29019a>(r,
0, m()));
1454
1455 // place the iterator on the first entry
1456 // past this line, or at the end of the
1457 // matrix
1458 for (size_type i=r+1; i<m(); ++i)
1459 if (row_length(i) > 0)
1460 return const_iterator(this, i, 0);
1461
1462 // if there is no such line, then take the
1463 // end iterator of the matrix
1464 return end();
1465 }
Thanks,
Feimi
On Wednesday, March 7, 2018 at 7:38:15 AM UTC-5, Wolfgang Bangerth wrote:
>
>
> > This time I used VectorOperation::insert and it didn't happen the memory
> error
> > that I posted before.
>
> OK, so that then clearly helps :-)
>
>
> > However, if I put the compress function after the loop, it only sets one
> entry
> > on each rank then throws the exception
> > "Object is in wrong state, not for unassembled matrix."
> > Putting the compress() in the loop does not throw exceptions, instead,
> it
> > iterates forever.
> > So just as you said it is very inefficient and not an option.
>
> I see. Yes, this is an effect of the PETSc memory model then. I'm not sure
> how
> to solve this other than to not iterate over the entries of the matrix
> after
> assembly :-(
>
> Best
> W.
>
> --
> ------------------------------------------------------------------------
> Wolfgang Bangerth email: [email protected]
> <javascript:>
> www: http://www.math.colostate.edu/~bangerth/
>
>
--
The deal.II project is located at http://www.dealii.org/
For mailing list/forum options, see
https://groups.google.com/d/forum/dealii?hl=en
---
You received this message because you are subscribed to the Google Groups
"deal.II User Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.