1 static char help[] = "Example of using MatPreallocator\n\n"; 2 3 /*T 4 Concepts: Mat^matrix preallocation 5 Processors: n 6 T*/ 7 8 #include <petscmat.h> 9 10 PetscErrorCode ex1_nonsquare_bs1(void) 11 { 12 Mat A,preallocator; 13 PetscInt M,N,m,n,bs; 14 15 /* 16 Create the Jacobian matrix 17 */ 18 PetscFunctionBegin; 19 M = 10; 20 N = 8; 21 PetscCall(MatCreate(PETSC_COMM_WORLD,&A)); 22 PetscCall(MatSetType(A,MATAIJ)); 23 PetscCall(MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,M,N)); 24 PetscCall(MatSetBlockSize(A,1)); 25 PetscCall(MatSetFromOptions(A)); 26 27 /* 28 Get the sizes of the jacobian. 29 */ 30 PetscCall(MatGetLocalSize(A,&m,&n)); 31 PetscCall(MatGetBlockSize(A,&bs)); 32 33 /* 34 Create a preallocator matrix with sizes (local and global) matching the jacobian A. 35 */ 36 PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&preallocator)); 37 PetscCall(MatSetType(preallocator,MATPREALLOCATOR)); 38 PetscCall(MatSetSizes(preallocator,m,n,M,N)); 39 PetscCall(MatSetBlockSize(preallocator,bs)); 40 PetscCall(MatSetUp(preallocator)); 41 42 /* 43 Insert non-zero pattern (e.g. perform a sweep over the grid). 44 You can use MatSetValues(), MatSetValuesBlocked() or MatSetValue(). 45 */ 46 { 47 PetscInt ii,jj; 48 PetscScalar vv = 0.0; 49 50 ii = 3; jj = 3; 51 PetscCall(MatSetValues(preallocator,1,&ii,1,&jj,&vv,INSERT_VALUES)); 52 53 ii = 7; jj = 4; 54 PetscCall(MatSetValues(preallocator,1,&ii,1,&jj,&vv,INSERT_VALUES)); 55 56 ii = 9; jj = 7; 57 PetscCall(MatSetValue(preallocator,ii,jj,vv,INSERT_VALUES)); 58 } 59 PetscCall(MatAssemblyBegin(preallocator,MAT_FINAL_ASSEMBLY)); 60 PetscCall(MatAssemblyEnd(preallocator,MAT_FINAL_ASSEMBLY)); 61 62 /* 63 Push the non-zero pattern defined within preallocator into A. 64 Internally this will call MatSetOption(A,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE). 65 The arg fill = PETSC_TRUE will insert zeros in the matrix A automatically. 66 */ 67 PetscCall(MatPreallocatorPreallocate(preallocator,PETSC_TRUE,A)); 68 69 /* 70 We no longer require the preallocator object so destroy it. 71 */ 72 PetscCall(MatDestroy(&preallocator)); 73 74 PetscCall(MatView(A,PETSC_VIEWER_STDOUT_WORLD)); 75 76 /* 77 Insert non-zero values into A. 78 */ 79 { 80 PetscInt ii,jj; 81 PetscScalar vv; 82 83 ii = 3; jj = 3; vv = 0.3; 84 PetscCall(MatSetValue(A,ii,jj,vv,INSERT_VALUES)); 85 86 ii = 7; jj = 4; vv = 3.3; 87 PetscCall(MatSetValues(A,1,&ii,1,&jj,&vv,INSERT_VALUES)); 88 89 ii = 9; jj = 7; vv = 4.3; 90 PetscCall(MatSetValues(A,1,&ii,1,&jj,&vv,INSERT_VALUES)); 91 } 92 PetscCall(MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY)); 93 PetscCall(MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY)); 94 95 PetscCall(MatView(A,PETSC_VIEWER_STDOUT_WORLD)); 96 97 PetscCall(MatDestroy(&A)); 98 PetscFunctionReturn(0); 99 } 100 101 PetscErrorCode ex2_square_bsvariable(void) 102 { 103 Mat A,preallocator; 104 PetscInt M,N,m,n,bs = 1; 105 106 PetscFunctionBegin; 107 PetscCall(PetscOptionsGetInt(NULL,NULL,"-block_size",&bs,NULL)); 108 109 /* 110 Create the Jacobian matrix. 111 */ 112 M = 10 * bs; 113 N = 10 * bs; 114 PetscCall(MatCreate(PETSC_COMM_WORLD,&A)); 115 PetscCall(MatSetType(A,MATAIJ)); 116 PetscCall(MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,M,N)); 117 PetscCall(MatSetBlockSize(A,bs)); 118 PetscCall(MatSetFromOptions(A)); 119 120 /* 121 Get the sizes of the jacobian. 122 */ 123 PetscCall(MatGetLocalSize(A,&m,&n)); 124 PetscCall(MatGetBlockSize(A,&bs)); 125 126 /* 127 Create a preallocator matrix with dimensions matching the jacobian A. 128 */ 129 PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&preallocator)); 130 PetscCall(MatSetType(preallocator,MATPREALLOCATOR)); 131 PetscCall(MatSetSizes(preallocator,m,n,M,N)); 132 PetscCall(MatSetBlockSize(preallocator,bs)); 133 PetscCall(MatSetUp(preallocator)); 134 135 /* 136 Insert non-zero pattern (e.g. perform a sweep over the grid). 137 You can use MatSetValues(), MatSetValuesBlocked() or MatSetValue(). 138 */ 139 { 140 PetscInt ii,jj; 141 PetscScalar *vv; 142 143 PetscCall(PetscCalloc1(bs*bs,&vv)); 144 145 ii = 0; jj = 9; 146 PetscCall(MatSetValue(preallocator,ii,jj,vv[0],INSERT_VALUES)); 147 148 ii = 0; jj = 0; 149 PetscCall(MatSetValuesBlocked(preallocator,1,&ii,1,&jj,vv,INSERT_VALUES)); 150 151 ii = 2; jj = 4; 152 PetscCall(MatSetValuesBlocked(preallocator,1,&ii,1,&jj,vv,INSERT_VALUES)); 153 154 ii = 4; jj = 2; 155 PetscCall(MatSetValuesBlocked(preallocator,1,&ii,1,&jj,vv,INSERT_VALUES)); 156 157 ii = 4; jj = 4; 158 PetscCall(MatSetValuesBlocked(preallocator,1,&ii,1,&jj,vv,INSERT_VALUES)); 159 160 ii = 9; jj = 9; 161 PetscCall(MatSetValuesBlocked(preallocator,1,&ii,1,&jj,vv,INSERT_VALUES)); 162 163 PetscCall(PetscFree(vv)); 164 } 165 PetscCall(MatAssemblyBegin(preallocator,MAT_FINAL_ASSEMBLY)); 166 PetscCall(MatAssemblyEnd(preallocator,MAT_FINAL_ASSEMBLY)); 167 168 /* 169 Push non-zero pattern defined from preallocator into A. 170 Internally this will call MatSetOption(A,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE). 171 The arg fill = PETSC_TRUE will insert zeros in the matrix A automatically. 172 */ 173 PetscCall(MatPreallocatorPreallocate(preallocator,PETSC_TRUE,A)); 174 175 /* 176 We no longer require the preallocator object so destroy it. 177 */ 178 PetscCall(MatDestroy(&preallocator)); 179 180 PetscCall(MatView(A,PETSC_VIEWER_STDOUT_WORLD)); 181 182 { 183 PetscInt ii,jj; 184 PetscScalar *vv; 185 186 PetscCall(PetscCalloc1(bs*bs,&vv)); 187 for (ii=0; ii<bs*bs; ii++) { 188 vv[ii] = (PetscReal)(ii+1); 189 } 190 191 ii = 0; jj = 9; 192 PetscCall(MatSetValue(A,ii,jj,33.3,INSERT_VALUES)); 193 194 ii = 0; jj = 0; 195 PetscCall(MatSetValuesBlocked(A,1,&ii,1,&jj,vv,INSERT_VALUES)); 196 197 ii = 2; jj = 4; 198 PetscCall(MatSetValuesBlocked(A,1,&ii,1,&jj,vv,INSERT_VALUES)); 199 200 ii = 4; jj = 2; 201 PetscCall(MatSetValuesBlocked(A,1,&ii,1,&jj,vv,INSERT_VALUES)); 202 203 ii = 4; jj = 4; 204 PetscCall(MatSetValuesBlocked(A,1,&ii,1,&jj,vv,INSERT_VALUES)); 205 206 ii = 9; jj = 9; 207 PetscCall(MatSetValuesBlocked(A,1,&ii,1,&jj,vv,INSERT_VALUES)); 208 209 PetscCall(PetscFree(vv)); 210 } 211 PetscCall(MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY)); 212 PetscCall(MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY)); 213 214 PetscCall(MatView(A,PETSC_VIEWER_STDOUT_WORLD)); 215 216 PetscCall(MatDestroy(&A)); 217 PetscFunctionReturn(0); 218 } 219 220 int main(int argc, char **args) 221 { 222 PetscInt testid = 0; 223 PetscCall(PetscInitialize(&argc,&args,(char*)0,help)); 224 PetscCall(PetscOptionsGetInt(NULL,NULL,"-test_id",&testid,NULL)); 225 switch (testid) { 226 case 0: 227 PetscCall(ex1_nonsquare_bs1()); 228 break; 229 case 1: 230 PetscCall(ex2_square_bsvariable()); 231 break; 232 default: 233 SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"Invalid value for -test_id. Must be {0,1}"); 234 } 235 PetscCall(PetscFinalize()); 236 return 0; 237 } 238 239 /*TEST 240 241 test: 242 suffix: t0_a_aij 243 nsize: 1 244 args: -test_id 0 -mat_type aij 245 246 test: 247 suffix: t0_b_aij 248 nsize: 6 249 args: -test_id 0 -mat_type aij 250 251 test: 252 suffix: t1_a_aij 253 nsize: 1 254 args: -test_id 1 -mat_type aij 255 256 test: 257 suffix: t2_a_baij 258 nsize: 1 259 args: -test_id 1 -mat_type baij 260 261 test: 262 suffix: t3_a_sbaij 263 nsize: 1 264 args: -test_id 1 -mat_type sbaij 265 266 test: 267 suffix: t4_a_aij_bs3 268 nsize: 1 269 args: -test_id 1 -mat_type aij -block_size 3 270 271 test: 272 suffix: t5_a_baij_bs3 273 nsize: 1 274 args: -test_id 1 -mat_type baij -block_size 3 275 276 test: 277 suffix: t6_a_sbaij_bs3 278 nsize: 1 279 args: -test_id 1 -mat_type sbaij -block_size 3 280 281 test: 282 suffix: t4_b_aij_bs3 283 nsize: 6 284 args: -test_id 1 -mat_type aij -block_size 3 285 286 test: 287 suffix: t5_b_baij_bs3 288 nsize: 6 289 args: -test_id 1 -mat_type baij -block_size 3 290 filter: grep -v Mat_ 291 292 test: 293 suffix: t6_b_sbaij_bs3 294 nsize: 6 295 args: -test_id 1 -mat_type sbaij -block_size 3 296 filter: grep -v Mat_ 297 298 TEST*/ 299