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
1455 // place the iterator on the first entry
1456 // past this line, or at the end of the
1458 for (size_type i=r+1; i<m(); ++i)
1459 if (row_length(i) > 0)
1460 return const_iterator(
this, i, 0);
1462 // if there is no such line, then take the
1463 // end iterator of the matrix
Thanks,
Feimi