PetscErrorCode ISCreateGeneral_Private(IS is) { PetscErrorCode ierr; IS_General *sub = (IS_General*)is->data; const PetscInt *idx = sub->idx; PetscBool sorted = PETSC_TRUE; PetscInt n,i,min,max; PetscFunctionBegin; ierr = PetscLayoutGetLocalSize(is->map, &n);CHKERRQ(ierr); ierr = PetscLayoutSetUp(is->map);CHKERRQ(ierr); for (i=1; i<n; i++) { if (idx[i] < idx[i-1]) {sorted = PETSC_FALSE; break;} } if (n) min = max = idx[0]; else min = max = 0; for (i=1; i<n; i++) { if (idx[i] < min) min = idx[i]; if (idx[i] > max) max = idx[i]; } sub->sorted = sorted; is->min = min; is->max = max; is->isperm = PETSC_FALSE; is->isidentity = PETSC_FALSE; ierr = ISViewFromOptions(is,NULL,"-is_view");CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode ISGeneralSetIndices_General(IS is,PetscInt n,const PetscInt idx[],PetscCopyMode mode) { PetscErrorCode ierr; IS_General *sub = (IS_General*)is->data; PetscFunctionBegin; if (n < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"length < 0"); if (n) PetscValidIntPointer(idx,3); ierr = PetscLayoutSetLocalSize(is->map,n);CHKERRQ(ierr); ierr = PetscLayoutSetUp(is->map);CHKERRQ(ierr); if (sub->allocated) {ierr = PetscFree(sub->idx);CHKERRQ(ierr);} if (mode == PETSC_COPY_VALUES) { ierr = PetscMalloc1(n,&sub->idx);CHKERRQ(ierr); ierr = PetscLogObjectMemory((PetscObject)is,n*sizeof(PetscInt));CHKERRQ(ierr); ierr = PetscMemcpy(sub->idx,idx,n*sizeof(PetscInt));CHKERRQ(ierr); sub->allocated = PETSC_TRUE; } else if (mode == PETSC_OWN_POINTER) { sub->idx = (PetscInt*)idx; ierr = PetscLogObjectMemory((PetscObject)is,n*sizeof(PetscInt));CHKERRQ(ierr); sub->allocated = PETSC_TRUE; } else { sub->idx = (PetscInt*)idx; sub->allocated = PETSC_FALSE; } ierr = ISSetUp_General(is);CHKERRQ(ierr); ierr = ISViewFromOptions(is,NULL,"-is_view");CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc, char **argv) { Vec vec, tagged, untagged; VecScatter taggedScatter, untaggedScatter; PetscInt bs; PetscInt n, nloc, nint, i, j, k, localStart, localEnd, ntagged, nuntagged; MPI_Comm comm; VecTagger tagger; PetscScalar *array; PetscRandom rand; VecTaggerBox *defaultBox; VecTaggerBox *boxes; IS is, isBlockGlobal, isComp; PetscErrorCode ierr; ierr = PetscInitialize(&argc,&argv,NULL,help);if (ierr) return ierr; n = 10.; bs = 1; comm = PETSC_COMM_WORLD; ierr = PetscOptionsBegin(comm, "" , "VecTagger Test Options", "Vec");CHKERRQ(ierr); ierr = PetscOptionsInt("-bs","The block size of the vector","ex1.c",bs,&bs,NULL);CHKERRQ(ierr); ierr = PetscOptionsInt("-n","The size of the vector (in blocks)","ex1.c",n,&n,NULL);CHKERRQ(ierr); ierr = PetscOptionsEnd();CHKERRQ(ierr); ierr = PetscRandomCreate(comm,&rand);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rand);CHKERRQ(ierr); ierr = VecCreate(comm,&vec);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)vec,"Vec to Tag");CHKERRQ(ierr); ierr = VecSetBlockSize(vec,bs);CHKERRQ(ierr); ierr = VecSetSizes(vec,PETSC_DECIDE,n);CHKERRQ(ierr); ierr = VecSetUp(vec);CHKERRQ(ierr); ierr = VecGetLocalSize(vec,&nloc);CHKERRQ(ierr); ierr = VecGetArray(vec,&array);CHKERRQ(ierr); for (i = 0; i < nloc; i++) { PetscScalar val; ierr = PetscRandomGetValue(rand,&val);CHKERRQ(ierr); array[i] = val; } ierr = VecRestoreArray(vec,&array);CHKERRQ(ierr); ierr = PetscRandomDestroy(&rand);CHKERRQ(ierr); ierr = VecViewFromOptions(vec,NULL,"-vec_view");CHKERRQ(ierr); ierr = VecTaggerCreate(comm,&tagger);CHKERRQ(ierr); ierr = VecTaggerSetBlockSize(tagger,bs);CHKERRQ(ierr); ierr = VecTaggerSetType(tagger,VECTAGGERABSOLUTE);CHKERRQ(ierr); ierr = PetscMalloc1(bs,&defaultBox);CHKERRQ(ierr); for (i = 0; i < bs; i++) { #if !defined(PETSC_USE_COMPLEX) defaultBox[i].min = 0.1; defaultBox[i].max = 1.5; #else defaultBox[i].min = PetscCMPLX(0.1,0.1); defaultBox[i].max = PetscCMPLX(1.5,1.5); #endif } ierr = VecTaggerAbsoluteSetBox(tagger,defaultBox);CHKERRQ(ierr); ierr = PetscFree(defaultBox);CHKERRQ(ierr); ierr = VecTaggerSetFromOptions(tagger);CHKERRQ(ierr); ierr = VecTaggerSetUp(tagger);CHKERRQ(ierr); ierr = PetscObjectViewFromOptions((PetscObject)tagger,NULL,"-vec_tagger_view");CHKERRQ(ierr); ierr = VecTaggerGetBlockSize(tagger,&bs);CHKERRQ(ierr); ierr = VecTaggerComputeBoxes(tagger,vec,&nint,&boxes); if (ierr && ierr != PETSC_ERR_SUP) CHKERRQ(ierr); else { PetscViewer viewer = NULL; ierr = PetscOptionsGetViewer(comm,NULL,NULL,"-vec_tagger_boxes_view",&viewer,NULL,NULL);CHKERRQ(ierr); if (viewer) { PetscBool iascii; ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); if (iascii) { ierr = PetscViewerASCIIPrintf(viewer,"Num boxes: %D\n",nint);CHKERRQ(ierr); ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); for (i = 0, k = 0; i < nint; i++) { ierr = PetscViewerASCIIPrintf(viewer,"%D: ",i);CHKERRQ(ierr); for (j = 0; j < bs; j++, k++) { if (j) {ierr = PetscViewerASCIIPrintf(viewer," x ");CHKERRQ(ierr);} #if !defined(PETSC_USE_COMPLEX) ierr = PetscViewerASCIIPrintf(viewer,"[%g,%g]",(double)boxes[k].min,(double)boxes[k].max);CHKERRQ(ierr); #else ierr = PetscViewerASCIIPrintf(viewer,"[%g+%gi,%g+%gi]",(double)PetscRealPart(boxes[k].min),(double)PetscImaginaryPart(boxes[k].min),(double)PetscRealPart(boxes[k].max),(double)PetscImaginaryPart(boxes[k].max));CHKERRQ(ierr); #endif } ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); } ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); } } ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); ierr = PetscFree(boxes);CHKERRQ(ierr); } ierr = VecTaggerComputeIS(tagger,vec,&is);CHKERRQ(ierr); ierr = ISGetBlockGlobalIS(is,vec,bs,&isBlockGlobal);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)isBlockGlobal,"Tagged IS (block global)");CHKERRQ(ierr); ierr = ISViewFromOptions(isBlockGlobal,NULL,"-tagged_is_view");CHKERRQ(ierr); ierr = VecGetOwnershipRange(vec,&localStart,&localEnd);CHKERRQ(ierr); ierr = ISComplement(isBlockGlobal,localStart,localEnd,&isComp);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)isComp,"Untagged IS (global)");CHKERRQ(ierr); ierr = ISViewFromOptions(isComp,NULL,"-untagged_is_view");CHKERRQ(ierr); ierr = ISGetLocalSize(isBlockGlobal,&ntagged);CHKERRQ(ierr); ierr = ISGetLocalSize(isComp,&nuntagged);CHKERRQ(ierr); ierr = VecCreate(comm,&tagged);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)tagged,"Tagged selection");CHKERRQ(ierr); ierr = VecSetSizes(tagged,ntagged,PETSC_DETERMINE);CHKERRQ(ierr); ierr = VecSetUp(tagged);CHKERRQ(ierr); ierr = VecCreate(comm,&untagged);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)untagged,"Untagged selection");CHKERRQ(ierr); ierr = VecSetSizes(untagged,nuntagged,PETSC_DETERMINE);CHKERRQ(ierr); ierr = VecSetUp(untagged);CHKERRQ(ierr); ierr = VecScatterCreate(vec,isBlockGlobal,tagged,NULL,&taggedScatter);CHKERRQ(ierr); ierr = VecScatterCreate(vec,isComp,untagged,NULL,&untaggedScatter);CHKERRQ(ierr); ierr = VecScatterBegin(taggedScatter,vec,tagged,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(taggedScatter,vec,tagged,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterBegin(untaggedScatter,vec,untagged,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(untaggedScatter,vec,untagged,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecViewFromOptions(tagged,NULL,"-tagged_vec_view");CHKERRQ(ierr); ierr = VecViewFromOptions(untagged,NULL,"-untagged_vec_view");CHKERRQ(ierr); ierr = VecScatterDestroy(&untaggedScatter);CHKERRQ(ierr); ierr = VecScatterDestroy(&taggedScatter);CHKERRQ(ierr); ierr = VecDestroy(&untagged);CHKERRQ(ierr); ierr = VecDestroy(&tagged);CHKERRQ(ierr); ierr = ISDestroy(&isComp);CHKERRQ(ierr); ierr = ISDestroy(&isBlockGlobal);CHKERRQ(ierr); ierr = ISDestroy(&is);CHKERRQ(ierr); ierr = VecTaggerDestroy(&tagger);CHKERRQ(ierr); ierr = VecDestroy(&vec);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
int main(int argc,char **args) { User user; Mat A,S; PetscScalar *data,diag = 1.3; PetscReal tol = PETSC_SMALL; PetscInt i,j,m = PETSC_DECIDE,n = PETSC_DECIDE,M = 17,N = 15,s1,s2; PetscInt test, ntest = 2; PetscMPIInt rank,size; PetscBool nc = PETSC_FALSE, cong; PetscBool ronl = PETSC_TRUE; PetscBool randomize = PETSC_FALSE; PetscBool keep = PETSC_FALSE; PetscBool testzerorows = PETSC_TRUE, testdiagscale = PETSC_TRUE, testgetdiag = PETSC_TRUE; PetscBool testshift = PETSC_TRUE, testscale = PETSC_TRUE, testdup = PETSC_TRUE, testreset = PETSC_TRUE; PetscErrorCode ierr; ierr = PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr; ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-M",&M,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-N",&N,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-ml",&m,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-nl",&n,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-square_nc",&nc,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-rows_only",&ronl,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-randomize",&randomize,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-test_zerorows",&testzerorows,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-test_diagscale",&testdiagscale,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-test_getdiag",&testgetdiag,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-test_shift",&testshift,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-test_scale",&testscale,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-test_dup",&testdup,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-test_reset",&testreset,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-loop",&ntest,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,NULL,"-tol",&tol,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetScalar(NULL,NULL,"-diag",&diag,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-keep",&keep,NULL);CHKERRQ(ierr); /* This tests square matrices with different row/col layout */ if (nc && size > 1) { M = PetscMax(PetscMax(N,M),1); N = M; m = n = 0; if (rank == 0) { m = M-1; n = 1; } else if (rank == 1) { m = 1; n = N-1; } } ierr = MatCreateDense(PETSC_COMM_WORLD,m,n,M,N,NULL,&A);CHKERRQ(ierr); ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); ierr = MatHasCongruentLayouts(A,&cong);CHKERRQ(ierr); ierr = MatGetOwnershipRange(A,&s1,NULL);CHKERRQ(ierr); s2 = 1; while (s2 < M) s2 *= 10; ierr = MatDenseGetArray(A,&data);CHKERRQ(ierr); for (j = 0; j < N; j++) { for (i = 0; i < m; i++) { data[j*m + i] = s2*j + i + s1 + 1; } } ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatConvert(A,MATAIJ,MAT_INPLACE_MATRIX,&A);CHKERRQ(ierr); ierr = MatSetOption(A,MAT_KEEP_NONZERO_PATTERN,keep);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)A,"initial");CHKERRQ(ierr); ierr = MatViewFromOptions(A,NULL,"-view_mat");CHKERRQ(ierr); ierr = PetscNew(&user);CHKERRQ(ierr); ierr = MatCreateShell(PETSC_COMM_WORLD,m,n,M,N,user,&S);CHKERRQ(ierr); ierr = MatShellSetOperation(S,MATOP_MULT,(void (*)(void))MatMult_User);CHKERRQ(ierr); ierr = MatShellSetOperation(S,MATOP_MULT_TRANSPOSE,(void (*)(void))MatMultTranspose_User);CHKERRQ(ierr); if (cong) { ierr = MatShellSetOperation(S,MATOP_GET_DIAGONAL,(void (*)(void))MatGetDiagonal_User);CHKERRQ(ierr); } ierr = MatDuplicate(A,MAT_COPY_VALUES,&user->B);CHKERRQ(ierr); /* Square and rows only scaling */ ronl = cong ? ronl : PETSC_TRUE; for (test = 0; test < ntest; test++) { PetscReal err; if (testzerorows) { Mat ST,B,C,BT,BTT; IS zr; Vec x = NULL, b1 = NULL, b2 = NULL; PetscInt *idxs = NULL, nr = 0; if (rank == (test%size)) { nr = 1; ierr = PetscMalloc1(nr,&idxs);CHKERRQ(ierr); if (test%2) { idxs[0] = (2*M - 1 - test/2)%M; } else { idxs[0] = (test/2)%M; } idxs[0] = PetscMax(idxs[0],0); } ierr = ISCreateGeneral(PETSC_COMM_WORLD,nr,idxs,PETSC_OWN_POINTER,&zr);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)zr,"ZR");CHKERRQ(ierr); ierr = ISViewFromOptions(zr,NULL,"-view_is");CHKERRQ(ierr); ierr = MatCreateVecs(A,&x,&b1);CHKERRQ(ierr); if (randomize) { ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); ierr = VecSetRandom(b1,NULL);CHKERRQ(ierr); } else { ierr = VecSet(x,11.4);CHKERRQ(ierr); ierr = VecSet(b1,-14.2);CHKERRQ(ierr); } ierr = VecDuplicate(b1,&b2);CHKERRQ(ierr); ierr = VecCopy(b1,b2);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)b1,"A_B1");CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)b2,"A_B2");CHKERRQ(ierr); if (size > 1 && !cong) { /* MATMPIAIJ ZeroRows and ZeroRowsColumns are buggy in this case */ ierr = VecDestroy(&b1);CHKERRQ(ierr); } if (ronl) { ierr = MatZeroRowsIS(A,zr,diag,x,b1);CHKERRQ(ierr); ierr = MatZeroRowsIS(S,zr,diag,x,b2);CHKERRQ(ierr); } else { ierr = MatZeroRowsColumnsIS(A,zr,diag,x,b1);CHKERRQ(ierr); ierr = MatZeroRowsColumnsIS(S,zr,diag,x,b2);CHKERRQ(ierr); ierr = ISDestroy(&zr);CHKERRQ(ierr); /* Mix zerorows and zerorowscols */ nr = 0; idxs = NULL; if (!rank) { nr = 1; ierr = PetscMalloc1(nr,&idxs);CHKERRQ(ierr); if (test%2) { idxs[0] = (3*M - 2 - test/2)%M; } else { idxs[0] = (test/2+1)%M; } idxs[0] = PetscMax(idxs[0],0); } ierr = ISCreateGeneral(PETSC_COMM_WORLD,nr,idxs,PETSC_OWN_POINTER,&zr);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)zr,"ZR2");CHKERRQ(ierr); ierr = ISViewFromOptions(zr,NULL,"-view_is");CHKERRQ(ierr); ierr = MatZeroRowsIS(A,zr,diag*2.0+PETSC_SMALL,NULL,NULL);CHKERRQ(ierr); ierr = MatZeroRowsIS(S,zr,diag*2.0+PETSC_SMALL,NULL,NULL);CHKERRQ(ierr); } ierr = ISDestroy(&zr);CHKERRQ(ierr); if (b1) { Vec b; ierr = VecViewFromOptions(b1,NULL,"-view_b");CHKERRQ(ierr); ierr = VecViewFromOptions(b2,NULL,"-view_b");CHKERRQ(ierr); ierr = VecDuplicate(b1,&b);CHKERRQ(ierr); ierr = VecCopy(b1,b);CHKERRQ(ierr); ierr = VecAXPY(b,-1.0,b2);CHKERRQ(ierr); ierr = VecNorm(b,NORM_INFINITY,&err);CHKERRQ(ierr); if (err >= tol) { ierr = PetscPrintf(PETSC_COMM_WORLD,"[test %D] Error b %g\n",test,(double)err);CHKERRQ(ierr); } ierr = VecDestroy(&b);CHKERRQ(ierr); } ierr = VecDestroy(&b1);CHKERRQ(ierr); ierr = VecDestroy(&b2);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = MatConvert(S,MATDENSE,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); ierr = MatCreateTranspose(S,&ST);CHKERRQ(ierr); ierr = MatComputeOperator(ST,MATDENSE,&BT);CHKERRQ(ierr); ierr = MatTranspose(BT,MAT_INITIAL_MATRIX,&BTT);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)B,"S");CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)BTT,"STT");CHKERRQ(ierr); ierr = MatConvert(A,MATDENSE,MAT_INITIAL_MATRIX,&C);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)C,"A");CHKERRQ(ierr); ierr = MatViewFromOptions(C,NULL,"-view_mat");CHKERRQ(ierr); ierr = MatViewFromOptions(B,NULL,"-view_mat");CHKERRQ(ierr); ierr = MatViewFromOptions(BTT,NULL,"-view_mat");CHKERRQ(ierr); ierr = MatAXPY(C,-1.0,B,SAME_NONZERO_PATTERN);CHKERRQ(ierr); ierr = MatNorm(C,NORM_FROBENIUS,&err);CHKERRQ(ierr); if (err >= tol) { ierr = PetscPrintf(PETSC_COMM_WORLD,"[test %D] Error mat mult %g\n",test,(double)err);CHKERRQ(ierr); } ierr = MatConvert(A,MATDENSE,MAT_REUSE_MATRIX,&C);CHKERRQ(ierr); ierr = MatAXPY(C,-1.0,BTT,SAME_NONZERO_PATTERN);CHKERRQ(ierr); ierr = MatNorm(C,NORM_FROBENIUS,&err);CHKERRQ(ierr); if (err >= tol) { ierr = PetscPrintf(PETSC_COMM_WORLD,"[test %D] Error mat mult transpose %g\n",test,(double)err);CHKERRQ(ierr); } ierr = MatDestroy(&ST);CHKERRQ(ierr); ierr = MatDestroy(&BTT);CHKERRQ(ierr); ierr = MatDestroy(&BT);CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); ierr = MatDestroy(&C);CHKERRQ(ierr); } if (testdiagscale) { /* MatDiagonalScale() */ Vec vr,vl; ierr = MatCreateVecs(A,&vr,&vl);CHKERRQ(ierr); if (randomize) { ierr = VecSetRandom(vr,NULL);CHKERRQ(ierr); ierr = VecSetRandom(vl,NULL);CHKERRQ(ierr); } else { ierr = VecSet(vr,test%2 ? 0.15 : 1.0/0.15);CHKERRQ(ierr); ierr = VecSet(vl,test%2 ? -1.2 : 1.0/-1.2);CHKERRQ(ierr); } ierr = MatDiagonalScale(A,vl,vr);CHKERRQ(ierr); ierr = MatDiagonalScale(S,vl,vr);CHKERRQ(ierr); ierr = VecDestroy(&vr);CHKERRQ(ierr); ierr = VecDestroy(&vl);CHKERRQ(ierr); } if (testscale) { /* MatScale() */ ierr = MatScale(A,test%2 ? 1.4 : 1.0/1.4);CHKERRQ(ierr); ierr = MatScale(S,test%2 ? 1.4 : 1.0/1.4);CHKERRQ(ierr); } if (testshift && cong) { /* MatShift() : MATSHELL shift is broken when row/cols layout are not congruent and left/right scaling have been applied */ ierr = MatShift(A,test%2 ? -77.5 : 77.5);CHKERRQ(ierr); ierr = MatShift(S,test%2 ? -77.5 : 77.5);CHKERRQ(ierr); } if (testgetdiag && cong) { /* MatGetDiagonal() */ Vec dA,dS; ierr = MatCreateVecs(A,&dA,NULL);CHKERRQ(ierr); ierr = MatCreateVecs(S,&dS,NULL);CHKERRQ(ierr); ierr = MatGetDiagonal(A,dA);CHKERRQ(ierr); ierr = MatGetDiagonal(S,dS);CHKERRQ(ierr); ierr = VecAXPY(dA,-1.0,dS);CHKERRQ(ierr); ierr = VecNorm(dA,NORM_INFINITY,&err);CHKERRQ(ierr); if (err >= tol) { ierr = PetscPrintf(PETSC_COMM_WORLD,"[test %D] Error diag %g\n",test,(double)err);CHKERRQ(ierr); } ierr = VecDestroy(&dA);CHKERRQ(ierr); ierr = VecDestroy(&dS);CHKERRQ(ierr); } if (testdup && !test) { Mat A2, S2; ierr = MatDuplicate(A,MAT_COPY_VALUES,&A2);CHKERRQ(ierr); ierr = MatDuplicate(S,MAT_COPY_VALUES,&S2);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = MatDestroy(&S);CHKERRQ(ierr); A = A2; S = S2; } if (testreset && (ntest == 1 || test == ntest-2)) { /* reset MATSHELL */ ierr = MatAssemblyBegin(S,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(S,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* reset A */ ierr = MatCopy(user->B,A,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); } } ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = MatDestroy(&user->B);CHKERRQ(ierr); ierr = MatDestroy(&S);CHKERRQ(ierr); ierr = PetscFree(user);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
int main(int argc, char **argv) { DM dm; /* Problem specification */ SNES snes; /* Nonlinear solver */ Vec u; /* Solutions */ AppCtx user; /* User-defined work context */ PetscErrorCode ierr; ierr = PetscInitialize(&argc, &argv, NULL,help);if (ierr) return ierr; ierr = ProcessOptions(PETSC_COMM_WORLD, &user);CHKERRQ(ierr); /* Primal system */ ierr = SNESCreate(PETSC_COMM_WORLD, &snes);CHKERRQ(ierr); ierr = CreateMesh(PETSC_COMM_WORLD, &user, &dm);CHKERRQ(ierr); ierr = SNESSetDM(snes, dm);CHKERRQ(ierr); ierr = SetupDiscretization(dm, "potential", SetupPrimalProblem, &user);CHKERRQ(ierr); ierr = DMCreateGlobalVector(dm, &u);CHKERRQ(ierr); ierr = VecSet(u, 0.0);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) u, "potential");CHKERRQ(ierr); ierr = DMPlexSetSNESLocalFEM(dm, &user, &user, &user);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); ierr = SNESSolve(snes, NULL, u);CHKERRQ(ierr); ierr = SNESGetSolution(snes, &u);CHKERRQ(ierr); ierr = VecViewFromOptions(u, NULL, "-potential_view");CHKERRQ(ierr); if (user.spectral) { PetscInt planeDir[2] = {0, 1}; PetscReal planeCoord[2] = {0., 1.}; ierr = ComputeSpectral(dm, u, 2, planeDir, planeCoord, &user);CHKERRQ(ierr); } /* Adjoint system */ if (user.adjoint) { DM dmAdj; SNES snesAdj; Vec uAdj; ierr = SNESCreate(PETSC_COMM_WORLD, &snesAdj);CHKERRQ(ierr); ierr = PetscObjectSetOptionsPrefix((PetscObject) snesAdj, "adjoint_");CHKERRQ(ierr); ierr = DMClone(dm, &dmAdj);CHKERRQ(ierr); ierr = SNESSetDM(snesAdj, dmAdj);CHKERRQ(ierr); ierr = SetupDiscretization(dmAdj, "adjoint", SetupAdjointProblem, &user);CHKERRQ(ierr); ierr = DMCreateGlobalVector(dmAdj, &uAdj);CHKERRQ(ierr); ierr = VecSet(uAdj, 0.0);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) uAdj, "adjoint");CHKERRQ(ierr); ierr = DMPlexSetSNESLocalFEM(dmAdj, &user, &user, &user);CHKERRQ(ierr); ierr = SNESSetFromOptions(snesAdj);CHKERRQ(ierr); ierr = SNESSolve(snesAdj, NULL, uAdj);CHKERRQ(ierr); ierr = SNESGetSolution(snesAdj, &uAdj);CHKERRQ(ierr); ierr = VecViewFromOptions(uAdj, NULL, "-adjoint_view");CHKERRQ(ierr); /* Error representation */ { DM dmErr, dmErrAux, dms[2]; Vec errorEst, errorL2, uErr, uErrLoc, uAdjLoc, uAdjProj; IS *subis; PetscReal errorEstTot, errorL2Norm, errorL2Tot; PetscInt N, i; PetscErrorCode (*funcs[1])(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *) = {trig_u}; void (*identity[1])(PetscInt, PetscInt, PetscInt, const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], const PetscInt[], const PetscInt[], const PetscScalar[], const PetscScalar[], const PetscScalar[], PetscReal, const PetscReal[], PetscInt, const PetscScalar[], PetscScalar[]) = {f0_identityaux_u}; void *ctxs[1] = {0}; ctxs[0] = &user; ierr = DMClone(dm, &dmErr);CHKERRQ(ierr); ierr = SetupDiscretization(dmErr, "error", SetupErrorProblem, &user);CHKERRQ(ierr); ierr = DMGetGlobalVector(dmErr, &errorEst);CHKERRQ(ierr); ierr = DMGetGlobalVector(dmErr, &errorL2);CHKERRQ(ierr); /* Compute auxiliary data (solution and projection of adjoint solution) */ ierr = DMGetLocalVector(dmAdj, &uAdjLoc);CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(dmAdj, uAdj, INSERT_VALUES, uAdjLoc);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(dmAdj, uAdj, INSERT_VALUES, uAdjLoc);CHKERRQ(ierr); ierr = DMGetGlobalVector(dm, &uAdjProj);CHKERRQ(ierr); ierr = PetscObjectCompose((PetscObject) dm, "dmAux", (PetscObject) dmAdj);CHKERRQ(ierr); ierr = PetscObjectCompose((PetscObject) dm, "A", (PetscObject) uAdjLoc);CHKERRQ(ierr); ierr = DMProjectField(dm, 0.0, u, identity, INSERT_VALUES, uAdjProj);CHKERRQ(ierr); ierr = PetscObjectCompose((PetscObject) dm, "dmAux", NULL);CHKERRQ(ierr); ierr = PetscObjectCompose((PetscObject) dm, "A", NULL);CHKERRQ(ierr); ierr = DMRestoreLocalVector(dmAdj, &uAdjLoc);CHKERRQ(ierr); /* Attach auxiliary data */ dms[0] = dm; dms[1] = dm; ierr = DMCreateSuperDM(dms, 2, &subis, &dmErrAux);CHKERRQ(ierr); if (0) { PetscSection sec; ierr = DMGetSection(dms[0], &sec);CHKERRQ(ierr); ierr = PetscSectionView(sec, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = DMGetSection(dms[1], &sec);CHKERRQ(ierr); ierr = PetscSectionView(sec, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = DMGetSection(dmErrAux, &sec);CHKERRQ(ierr); ierr = PetscSectionView(sec, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } ierr = DMViewFromOptions(dmErrAux, NULL, "-dm_err_view");CHKERRQ(ierr); ierr = ISViewFromOptions(subis[0], NULL, "-super_is_view");CHKERRQ(ierr); ierr = ISViewFromOptions(subis[1], NULL, "-super_is_view");CHKERRQ(ierr); ierr = DMGetGlobalVector(dmErrAux, &uErr);CHKERRQ(ierr); ierr = VecViewFromOptions(u, NULL, "-map_vec_view");CHKERRQ(ierr); ierr = VecViewFromOptions(uAdjProj, NULL, "-map_vec_view");CHKERRQ(ierr); ierr = VecViewFromOptions(uErr, NULL, "-map_vec_view");CHKERRQ(ierr); ierr = VecISCopy(uErr, subis[0], SCATTER_FORWARD, u);CHKERRQ(ierr); ierr = VecISCopy(uErr, subis[1], SCATTER_FORWARD, uAdjProj);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(dm, &uAdjProj);CHKERRQ(ierr); for (i = 0; i < 2; ++i) {ierr = ISDestroy(&subis[i]);CHKERRQ(ierr);} ierr = PetscFree(subis);CHKERRQ(ierr); ierr = DMGetLocalVector(dmErrAux, &uErrLoc);CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(dm, uErr, INSERT_VALUES, uErrLoc);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(dm, uErr, INSERT_VALUES, uErrLoc);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(dmErrAux, &uErr);CHKERRQ(ierr); ierr = PetscObjectCompose((PetscObject) dmAdj, "dmAux", (PetscObject) dmErrAux);CHKERRQ(ierr); ierr = PetscObjectCompose((PetscObject) dmAdj, "A", (PetscObject) uErrLoc);CHKERRQ(ierr); /* Compute cellwise error estimate */ ierr = VecSet(errorEst, 0.0);CHKERRQ(ierr); ierr = DMPlexComputeCellwiseIntegralFEM(dmAdj, uAdj, errorEst, &user);CHKERRQ(ierr); ierr = PetscObjectCompose((PetscObject) dmAdj, "dmAux", NULL);CHKERRQ(ierr); ierr = PetscObjectCompose((PetscObject) dmAdj, "A", NULL);CHKERRQ(ierr); ierr = DMRestoreLocalVector(dmErrAux, &uErrLoc);CHKERRQ(ierr); ierr = DMDestroy(&dmErrAux);CHKERRQ(ierr); /* Plot cellwise error vector */ ierr = VecViewFromOptions(errorEst, NULL, "-error_view");CHKERRQ(ierr); /* Compute ratio of estimate (sum over cells) with actual L_2 error */ ierr = DMComputeL2Diff(dm, 0.0, funcs, ctxs, u, &errorL2Norm);CHKERRQ(ierr); ierr = DMPlexComputeL2DiffVec(dm, 0.0, funcs, ctxs, u, errorL2);CHKERRQ(ierr); ierr = VecViewFromOptions(errorL2, NULL, "-l2_error_view");CHKERRQ(ierr); ierr = VecNorm(errorL2, NORM_INFINITY, &errorL2Tot);CHKERRQ(ierr); ierr = VecNorm(errorEst, NORM_INFINITY, &errorEstTot);CHKERRQ(ierr); ierr = VecGetSize(errorEst, &N);CHKERRQ(ierr); ierr = VecPointwiseDivide(errorEst, errorEst, errorL2);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) errorEst, "Error ratio");CHKERRQ(ierr); ierr = VecViewFromOptions(errorEst, NULL, "-error_ratio_view");CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "N: %D L2 error: %g Error Ratio: %g/%g = %g\n", N, (double) errorL2Norm, (double) errorEstTot, (double) PetscSqrtReal(errorL2Tot), (double) errorEstTot/PetscSqrtReal(errorL2Tot));CHKERRQ(ierr); ierr = DMRestoreGlobalVector(dmErr, &errorEst);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(dmErr, &errorL2);CHKERRQ(ierr); ierr = DMDestroy(&dmErr);CHKERRQ(ierr); } ierr = DMDestroy(&dmAdj);CHKERRQ(ierr); ierr = VecDestroy(&uAdj);CHKERRQ(ierr); ierr = SNESDestroy(&snesAdj);CHKERRQ(ierr); } /* Cleanup */ ierr = VecDestroy(&u);CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = DMDestroy(&dm);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }