On Feb 21, 2014, at 2:41 PM, Chung-Kan Huang <[email protected]> wrote:
> Hello,
>
> In my application I like to use
> PetscErrorCode KSPSetOperators(KSP ksp,Mat Amat,Mat Pmat,MatStructure flag)
> and have Pmat different from Amat
>
> if Amat = L + D + U
> then Pmat = Amat - L* - U* + rowsum(L* + U*)
> where L* and U* is a portion of L and U and rowsum(L* + U*) will add into D
>
> I know I can explicitly construct Pmat step-by-step but wonder what will be
> the most easy way to do this in PETSC?
Kan,
This is something that is trivial in Matlab but not trivial to do
efficiently in PETSc.
How do you determine what “portion” of L and U are used? Does it depend on
numerical values? Is if fixed?
Is Amat an AIJ matrix or a BAIJ matrix?
Do you want to do it in parallel?
I would start by doing it sequentially for a SeqAIJ matrix and #include
"src/mat/impls/aij/seq/aij.h” into the source code then you would write a
routine that looped over the Amat rows accessing values directly in the CSR
storage format
PetscInt *i; /* pointer to beginning of each row */
\
PetscInt *j; /* column values: j + i[k] - 1 is start
of row k */ \
datatype *a; /* nonzero elements */
you would then determine how many non zeros you wanted per row, call
MatCreateSeqAIJ() with the preallocation from the non zeros per row and then
loop over the rows of Amat again calling MatSetValues() to move the values you
want moved into the Pmat matrix and added up for the diagonal.
It is not terribly more difficult for MPIAIJ except that the matrix entries
in Amat are stored in two parts so accessing those values values requires a bit
more complicated code and I would not recommend doing it until you have the
sequential version working perfectly.
Barry
>
> Thanks,
>
>
> Kan
>
>