How to efficiently change just the diagonal vector in a matrix at every time step

Sean Dettrick sdettrick at gmail.com
Mon May 12 05:42:47 CDT 2008


On May 10, 2008, at 10:38 AM, Ben Tay wrote:

> Hi Sean,
>
> Maybe for me, I can just insert vector diagonal D into the matrix A  
> and call Assembly and KSP at every time step. Should that be better  
> since there is no need to copy A into B?
>
> Thanks!


Yes, that sounds like it would be faster.  I suppose you would use  
INSERT_VALUES rather than ADD_VALUES.

In my case I copy the whole matrix because constructing the time- 
constant part of the diagonal is very complicated.   But now that you  
mention it, I could store both the time-constant and time-varying  
diagonal components in two separate Vecs, and only have one Mat, and  
then do MatDiagonalSet() twice at each timestep - the first time with  
INSERT_VALUES, the second with ADD_VALUES.  That sounds like it would  
be faster.

Thanks to you too,

Sean


>
>
> On Fri, May 9, 2008 at 8:50 PM, Sean Dettrick <sdettrick at gmail.com>  
> wrote:
>
> One way to do it is to have two Mats, A and B, and a Vec, D, to  
> store the diagonal.  A is constructed only on the first step.  On  
> subsequent steps, A is copied into B, and then D is added to the  
> diagonal:
>
>  ierr = MatCopy( A, B, SAME_NON_ZERO_PATTERN );
>  ierr = MatDiagonalSet( B, D, ADD_VALUES );
>
> The KSP uses B as the matrix, not A.
>
> I don't know if this approach is efficient or not.  Can anybody  
> comment?
>
> Thanks,
> Sean
>
>
>
>
> On May 9, 2008, at 2:33 PM, Ben Tay wrote:
>
> Hi,
> I have a matrix and I inserted all the relevant values during the  
> 1st step. I'll then solve it. For the subsequent steps, I only need  
> to change the diagonal vector of the matrix before solving. I wonder  
> how I can do it efficiently. Of course, the RHS vector also change  
> but I've not included them here.
>
> I set these at the 1st step:
>
> call  
> KSPSetOperators 
> (ksp_semi_x,A_semi_x,A_semi_x,SAME_NONZERO_PATTERN,ierr)
>
> call KSPGetPC(ksp_semi_x,pc_semi_x,ierr)
>
>  ksptype=KSPRICHARDSON
>
>  call KSPSetType(ksp_semi_x,ksptype,ierr)
>
>  ptype = PCILU
>
>  call PCSetType(pc_semi_x,ptype,ierr)
>
>  call KSPSetFromOptions(ksp_semi_x,ierr)
>
>  call KSPSetInitialGuessNonzero(ksp_semi_x,PETSC_TRUE,ierr)
>
>  tol=1.e-5
>
>  call  
> KSPSetTolerances 
> (ksp_semi_x 
> ,tol 
> ,PETSC_DEFAULT_DOUBLE_PRECISION 
> ,PETSC_DEFAULT_DOUBLE_PRECISION,PETSC_DEFAULT_INTEGER,ierr)
>
> and what I did at the subsequent steps is:
>
> do II=1,total
>  call MatSetValues(A_semi_x,1,II,1,II,new_value,INSERT_VALUES,ierr)
>
> end do
>
> call MatAssemblyBegin(A_semi_x,MAT_FINAL_ASSEMBLY,ierr)
>
> call MatAssemblyEnd(A_semi_x,MAT_FINAL_ASSEMBLY,ierr)
>
> call KSPSolve(ksp_semi_x,b_rhs_semi_x,xx_semi_x,ierr)
>
> I realise that the answers are slightly different as compared to  
> calling all the options such as KSPSetType, KSPSetFromOptions,  
> KSPSetTolerances at every time step. Should that be so? Is this the  
> best way?
>
> Also, I can let the matrix be equal at every time step by fixing the  
> delta_time. However, it may give stability problems. I wonder how  
> expensive is these type of value changing and assembly for a matrix?
>
> Thank you very much.
>
> Regards.
>
>
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mcs.anl.gov/pipermail/petsc-users/attachments/20080512/13c5d22e/attachment.htm>


More information about the petsc-users mailing list