No, Setting a bigger matrix size won't have a negative impact.  Only the actual number of nonzeros matters.  

--Junchao Zhang


On Thu, Sep 26, 2024 at 1:33 PM Frank Bramkamp <bramkamp@nsc.liu.se> wrote:
Thanks for the reply,

when setting the size larger than needed, would that have any negative impact somewhere else ?!
We typically pre-determine how many non-zero elements are present, when using MatCreate.

Then, the smaller size needs the same memory as the larger matrix ?!

Thanks, Frank




On 26 Sep 2024, at 20:27, Junchao Zhang <junchao.zhang@gmail.com> wrote:

Is it possible to set the size of the COMPACT matrix as large as the WIDE matrix, then do MatAYPX(WIDE, 0, COMPACT, SUBSET_NONZERO_PATTERN), i.e,  WIDE = 0*WIDE + COMPACT?  You need to build WIDE upfront once, but if you repeat, the other MatAYPX will be fast.

--Junchao Zhang


On Thu, Sep 26, 2024 at 1:13 PM Barry Smith <bsmith@petsc.dev> wrote:

  Frank,

   Sorry for the confusion. MatCopy() and MatAXPY() only work for identically sized matrices.

   Even if the two matrices are the same size but one, say A, has a subset of nonzeros than the other, say B, what you want to do is non-trivial. This is because to do a copy you must MatAssembly the matrix first and this squeezes out the zero locations that you would like to fill in B.

   A simple solution is in the code that computes the subset of entries, call MatSetValues() twice, once for A and once for B. Not entirely satisfying but it will work and be reasonably efficient.


  Barry


> On Sep 26, 2024, at 1:50 PM, Frank Bramkamp <bramkamp@nsc.liu.se> wrote:
>
> Dear PETSc team,
>
>
> I would like to create two matrices. The first matrix is based on a compact stencil (COMPACT), and the second one has an extended stencil (WIDE)
> So the non-zero elements of the  COMPACT matrix is contained in the WIDE matrix as well. But the WIDE matrix shall contain some additional elements.
> I try to create the COMPACT matrix first, then copy it to the WIDE matrix and then add some more terms to the WIDE matrix.
> We want to create a matrix that is based on a lower order approximation of our scheme which serves as basis matrix for preconditioning,
> where we want to have a more accurate jacobian which has a larger stencil, that is based on the lower approximation plus some additional non-zero elements.
> We want to avoid that we have to call the same routines twice to setup the more accurate matrix, but copy the elements from the lower order (compact) matrix.
>
>
> I try to use MatCopy to copy the COMPACT matrix into the WIDE matrix. Somehow I cannot figure out to do this,
> since there is always a problem wirh non conforming sizes
>
> [0]PETSC ERROR: Nonconforming object sizes
> [0]PETSC ERROR: Mat A,Mat B: global dim (4,8) (4,8)
>
>
> Here is a basic example that I try.
> Adding additional elements to the WIDE matrix is disabled right now, since MatCopy already gives a problem.
> I thought that in MatCopy(COMPACT, WIDE, DIFFERENT_NONZERO_PATTERN, ierr)
> the option DIFFERENT_NONZERO_PATTERN should enable to copy different matrix sizes into each other.
> Or is that not possible to do ?!
>
> Here the COMPACT matrix is a 4x4 matrix and the WIDE matrix 8x8, for a basic test.
>
> Thanks, Frank Bramkamp
>
>
>
>
> program petsc_matrix_example
> #include <petsc/finclude/petsc.h>
>  use petsc
>  implicit none
>
>  PetscErrorCode :: ierr
>  Mat :: COMPACT, WIDE
>  PetscInt :: m, n, MM, NN, d_nz
>  PetscInt :: i, j
>  PetscScalar :: additional_value
>
> ! Initialize PETSc
>  call PetscInitialize(PETSC_NULL_CHARACTER, ierr)
>
> ! Set dimensions for COMPACT matrix
>  m = 4  ! Local rows
>  n = 4  ! Local columns
>  MM = 4  ! Global rows
>  NN = 4  ! Global columns
>  d_nz = 4 ! Estimated non-zeros per row (diagonal) o_nz = 0 ! Estimated non-zeros per row (off-diagonal)
>
> ! Create COMPACT matrix
>  call MatCreateSeqAIJ(PETSC_COMM_SELF, MM, NN, PETSC_DECIDE, PETSC_NULL_INTEGER, COMPACT, ierr)
>
> ! Set some values in COMPACT matrix (example) do i = 0, M-1
>  do i = 0, NN-1
>     !do j = max(0, i-1), min(NN-1, i+1)
>     do j = 0,NN-1
>      call MatSetValue(COMPACT, i, j, 1.0_PETSC_REAL_KIND, INSERT_VALUES, ierr)
>    end do
>  end do
>
> ! Assemble COMPACT matrix
>  call MatAssemblyBegin(COMPACT, MAT_FINAL_ASSEMBLY, ierr)
>  call MatAssemblyEnd(COMPACT, MAT_FINAL_ASSEMBLY, ierr)
>
> ! Set dimensions for WIDE matrix
>  n = 8  ! Increase local columns
>  NN = 8  ! Increase global columns
>  m  = 8
>  MM = 8
>  d_nz = 8
>
> ! Create WIDE matrix
>  call MatCreateSeqAIJ(PETSC_COMM_SELF, MM, NN, PETSC_DECIDE, PETSC_NULL_INTEGER, WIDE, ierr)
>
>  ! Assemble WIDE matrix: MUST WE ASSMBLE THE MATRIX BEFORE MatCOPY ?!
>  call MatAssemblyBegin(WIDE, MAT_FINAL_ASSEMBLY, ierr)
>  call MatAssemblyEnd(WIDE, MAT_FINAL_ASSEMBLY, ierr)
>
> ! Copy elements from COMPACT to WIDE
>  call MatCopy(COMPACT, WIDE, DIFFERENT_NONZERO_PATTERN, ierr)
>
>
>
>  !call MatAssemblyBegin(WIDE, MAT_FINAL_ASSEMBLY, ierr)
>
>  ! Add additional elements to WIDE matrix
> !!$  additional_value = 10.0
> !!$
> !!$  ! original
> !!$  !do i = 0, MM-1
> !!$  !  do j = NN/2, NN-1
> !!$  !    call MatSetValue(WIDE, i, j, additional_value, INSERT_VALUES, ierr)
> !!$  !  end do
> !!$ !end do
> !!$
> !!$  do i = 0, NN-1
> !!$    do j = max(0, i-1), min(NN-1, i+1)
> !!$      call MatSetValue(WIDE, i, j, 10.0_PETSC_REAL_KIND, ADD_VALUES, ierr)
> !!$    end do
> !!$  end do
>
>
> ! Assemble WIDE matrix again
>  call MatAssemblyBegin(WIDE, MAT_FINAL_ASSEMBLY, ierr)
>  call MatAssemblyEnd(WIDE, MAT_FINAL_ASSEMBLY, ierr)
>
> ! View matrices (optional)
>  call PetscPrintf(PETSC_COMM_WORLD, "COMPACT matrix:\n", ierr)
>  call MatView(COMPACT, PETSC_VIEWER_STDOUT_WORLD, ierr)
>  call PetscPrintf(PETSC_COMM_WORLD, "WIDE matrix:\n", ierr)
>  call MatView(WIDE, PETSC_VIEWER_STDOUT_WORLD, ierr)
>
> ! Clean up
>  call MatDestroy(COMPACT, ierr)
>  call MatDestroy(WIDE, ierr)
>
> ! Finalize PETSc
>  call PetscFinalize(ierr)
>
> end program petsc_matrix_example
>
>