static char help[] = "Example of using MatPreallocator\n\n"; #include PetscErrorCode ex1_nonsquare_bs1(void) { Mat A,preallocator; PetscInt M,N,m,n,bs; /* Create the Jacobian matrix */ PetscFunctionBegin; M = 10; N = 8; PetscCall(MatCreate(PETSC_COMM_WORLD,&A)); PetscCall(MatSetType(A,MATAIJ)); PetscCall(MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,M,N)); PetscCall(MatSetBlockSize(A,1)); PetscCall(MatSetFromOptions(A)); /* Get the sizes of the jacobian. */ PetscCall(MatGetLocalSize(A,&m,&n)); PetscCall(MatGetBlockSize(A,&bs)); /* Create a preallocator matrix with sizes (local and global) matching the jacobian A. */ PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&preallocator)); PetscCall(MatSetType(preallocator,MATPREALLOCATOR)); PetscCall(MatSetSizes(preallocator,m,n,M,N)); PetscCall(MatSetBlockSize(preallocator,bs)); PetscCall(MatSetUp(preallocator)); /* Insert non-zero pattern (e.g. perform a sweep over the grid). You can use MatSetValues(), MatSetValuesBlocked() or MatSetValue(). */ { PetscInt ii,jj; PetscScalar vv = 0.0; ii = 3; jj = 3; PetscCall(MatSetValues(preallocator,1,&ii,1,&jj,&vv,INSERT_VALUES)); ii = 7; jj = 4; PetscCall(MatSetValues(preallocator,1,&ii,1,&jj,&vv,INSERT_VALUES)); ii = 9; jj = 7; PetscCall(MatSetValue(preallocator,ii,jj,vv,INSERT_VALUES)); } PetscCall(MatAssemblyBegin(preallocator,MAT_FINAL_ASSEMBLY)); PetscCall(MatAssemblyEnd(preallocator,MAT_FINAL_ASSEMBLY)); /* Push the non-zero pattern defined within preallocator into A. Internally this will call MatSetOption(A,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE). The arg fill = PETSC_TRUE will insert zeros in the matrix A automatically. */ PetscCall(MatPreallocatorPreallocate(preallocator,PETSC_TRUE,A)); /* We no longer require the preallocator object so destroy it. */ PetscCall(MatDestroy(&preallocator)); PetscCall(MatView(A,PETSC_VIEWER_STDOUT_WORLD)); /* Insert non-zero values into A. */ { PetscInt ii,jj; PetscScalar vv; ii = 3; jj = 3; vv = 0.3; PetscCall(MatSetValue(A,ii,jj,vv,INSERT_VALUES)); ii = 7; jj = 4; vv = 3.3; PetscCall(MatSetValues(A,1,&ii,1,&jj,&vv,INSERT_VALUES)); ii = 9; jj = 7; vv = 4.3; PetscCall(MatSetValues(A,1,&ii,1,&jj,&vv,INSERT_VALUES)); } PetscCall(MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY)); PetscCall(MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY)); PetscCall(MatView(A,PETSC_VIEWER_STDOUT_WORLD)); PetscCall(MatDestroy(&A)); PetscFunctionReturn(0); } PetscErrorCode ex2_square_bsvariable(void) { Mat A,preallocator; PetscInt M,N,m,n,bs = 1; PetscFunctionBegin; PetscCall(PetscOptionsGetInt(NULL,NULL,"-block_size",&bs,NULL)); /* Create the Jacobian matrix. */ M = 10 * bs; N = 10 * bs; PetscCall(MatCreate(PETSC_COMM_WORLD,&A)); PetscCall(MatSetType(A,MATAIJ)); PetscCall(MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,M,N)); PetscCall(MatSetBlockSize(A,bs)); PetscCall(MatSetFromOptions(A)); /* Get the sizes of the jacobian. */ PetscCall(MatGetLocalSize(A,&m,&n)); PetscCall(MatGetBlockSize(A,&bs)); /* Create a preallocator matrix with dimensions matching the jacobian A. */ PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&preallocator)); PetscCall(MatSetType(preallocator,MATPREALLOCATOR)); PetscCall(MatSetSizes(preallocator,m,n,M,N)); PetscCall(MatSetBlockSize(preallocator,bs)); PetscCall(MatSetUp(preallocator)); /* Insert non-zero pattern (e.g. perform a sweep over the grid). You can use MatSetValues(), MatSetValuesBlocked() or MatSetValue(). */ { PetscInt ii,jj; PetscScalar *vv; PetscCall(PetscCalloc1(bs*bs,&vv)); ii = 0; jj = 9; PetscCall(MatSetValue(preallocator,ii,jj,vv[0],INSERT_VALUES)); ii = 0; jj = 0; PetscCall(MatSetValuesBlocked(preallocator,1,&ii,1,&jj,vv,INSERT_VALUES)); ii = 2; jj = 4; PetscCall(MatSetValuesBlocked(preallocator,1,&ii,1,&jj,vv,INSERT_VALUES)); ii = 4; jj = 2; PetscCall(MatSetValuesBlocked(preallocator,1,&ii,1,&jj,vv,INSERT_VALUES)); ii = 4; jj = 4; PetscCall(MatSetValuesBlocked(preallocator,1,&ii,1,&jj,vv,INSERT_VALUES)); ii = 9; jj = 9; PetscCall(MatSetValuesBlocked(preallocator,1,&ii,1,&jj,vv,INSERT_VALUES)); PetscCall(PetscFree(vv)); } PetscCall(MatAssemblyBegin(preallocator,MAT_FINAL_ASSEMBLY)); PetscCall(MatAssemblyEnd(preallocator,MAT_FINAL_ASSEMBLY)); /* Push non-zero pattern defined from preallocator into A. Internally this will call MatSetOption(A,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE). The arg fill = PETSC_TRUE will insert zeros in the matrix A automatically. */ PetscCall(MatPreallocatorPreallocate(preallocator,PETSC_TRUE,A)); /* We no longer require the preallocator object so destroy it. */ PetscCall(MatDestroy(&preallocator)); PetscCall(MatView(A,PETSC_VIEWER_STDOUT_WORLD)); { PetscInt ii,jj; PetscScalar *vv; PetscCall(PetscCalloc1(bs*bs,&vv)); for (ii=0; ii