static char help[] = "Example of using MatPreallocator\n\n"; /*T Concepts: Mat^matrix preallocation Processors: n T*/ #include PetscErrorCode ex1_nonsquare_bs1(void) { Mat A,preallocator; PetscInt M,N,m,n,bs; PetscErrorCode ierr; /* Create the Jacobian matrix */ PetscFunctionBegin; M = 10; N = 8; ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatSetType(A,MATAIJ);CHKERRQ(ierr); ierr = MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); ierr = MatSetBlockSize(A,1);CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr); /* Get the sizes of the jacobian. */ ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); /* Create a preallocator matrix with sizes (local and global) matching the jacobian A. */ ierr = MatCreate(PetscObjectComm((PetscObject)A),&preallocator);CHKERRQ(ierr); ierr = MatSetType(preallocator,MATPREALLOCATOR);CHKERRQ(ierr); ierr = MatSetSizes(preallocator,m,n,M,N);CHKERRQ(ierr); ierr = MatSetBlockSize(preallocator,bs);CHKERRQ(ierr); ierr = MatSetUp(preallocator);CHKERRQ(ierr); /* 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; ierr = MatSetValues(preallocator,1,&ii,1,&jj,&vv,INSERT_VALUES);CHKERRQ(ierr); ii = 7; jj = 4; ierr = MatSetValues(preallocator,1,&ii,1,&jj,&vv,INSERT_VALUES);CHKERRQ(ierr); ii = 9; jj = 7; ierr = MatSetValue(preallocator,ii,jj,vv,INSERT_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(preallocator,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(preallocator,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* 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. */ ierr = MatPreallocatorPreallocate(preallocator,PETSC_TRUE,A);CHKERRQ(ierr); /* We no longer require the preallocator object so destroy it. */ ierr = MatDestroy(&preallocator);CHKERRQ(ierr); ierr = MatView(A,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); /* Insert non-zero values into A. */ { PetscInt ii,jj; PetscScalar vv; ii = 3; jj = 3; vv = 0.3; ierr = MatSetValue(A,ii,jj,vv,INSERT_VALUES);CHKERRQ(ierr); ii = 7; jj = 4; vv = 3.3; ierr = MatSetValues(A,1,&ii,1,&jj,&vv,INSERT_VALUES);CHKERRQ(ierr); ii = 9; jj = 7; vv = 4.3; ierr = MatSetValues(A,1,&ii,1,&jj,&vv,INSERT_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatView(A,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); PetscFunctionReturn(0); } PetscErrorCode ex2_square_bsvariable(void) { Mat A,preallocator; PetscInt M,N,m,n,bs = 1; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscOptionsGetInt(NULL,NULL,"-block_size",&bs,NULL);CHKERRQ(ierr); /* Create the Jacobian matrix. */ M = 10 * bs; N = 10 * bs; ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatSetType(A,MATAIJ);CHKERRQ(ierr); ierr = MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); ierr = MatSetBlockSize(A,bs);CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr); /* Get the sizes of the jacobian. */ ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); /* Create a preallocator matrix with dimensions matching the jacobian A. */ ierr = MatCreate(PetscObjectComm((PetscObject)A),&preallocator);CHKERRQ(ierr); ierr = MatSetType(preallocator,MATPREALLOCATOR);CHKERRQ(ierr); ierr = MatSetSizes(preallocator,m,n,M,N);CHKERRQ(ierr); ierr = MatSetBlockSize(preallocator,bs);CHKERRQ(ierr); ierr = MatSetUp(preallocator);CHKERRQ(ierr); /* Insert non-zero pattern (e.g. perform a sweep over the grid). You can use MatSetValues(), MatSetValuesBlocked() or MatSetValue(). */ { PetscInt ii,jj; PetscScalar *vv; ierr = PetscCalloc1(bs*bs,&vv);CHKERRQ(ierr); ii = 0; jj = 9; ierr = MatSetValue(preallocator,ii,jj,vv[0],INSERT_VALUES);CHKERRQ(ierr); ii = 0; jj = 0; ierr = MatSetValuesBlocked(preallocator,1,&ii,1,&jj,vv,INSERT_VALUES);CHKERRQ(ierr); ii = 2; jj = 4; ierr = MatSetValuesBlocked(preallocator,1,&ii,1,&jj,vv,INSERT_VALUES);CHKERRQ(ierr); ii = 4; jj = 2; ierr = MatSetValuesBlocked(preallocator,1,&ii,1,&jj,vv,INSERT_VALUES);CHKERRQ(ierr); ii = 4; jj = 4; ierr = MatSetValuesBlocked(preallocator,1,&ii,1,&jj,vv,INSERT_VALUES);CHKERRQ(ierr); ii = 9; jj = 9; ierr = MatSetValuesBlocked(preallocator,1,&ii,1,&jj,vv,INSERT_VALUES);CHKERRQ(ierr); ierr = PetscFree(vv);CHKERRQ(ierr); } ierr = MatAssemblyBegin(preallocator,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(preallocator,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* 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. */ ierr = MatPreallocatorPreallocate(preallocator,PETSC_TRUE,A);CHKERRQ(ierr); /* We no longer require the preallocator object so destroy it. */ ierr = MatDestroy(&preallocator);CHKERRQ(ierr); ierr = MatView(A,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); { PetscInt ii,jj; PetscScalar *vv; ierr = PetscCalloc1(bs*bs,&vv);CHKERRQ(ierr); for (ii=0; ii