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 <bramk...@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.zh...@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 <bsm...@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 <bramk...@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 >> > >> > >> >> >