PetscErrorCode DMCreateInterpolation_Composite(DM coarse,DM fine,Mat *A,Vec *v) { PetscErrorCode ierr; PetscInt m,n,M,N,nDM,i; struct DMCompositeLink *nextc; struct DMCompositeLink *nextf; Vec gcoarse,gfine,*vecs; DM_Composite *comcoarse = (DM_Composite*)coarse->data; DM_Composite *comfine = (DM_Composite*)fine->data; Mat *mats; PetscFunctionBegin; PetscValidHeaderSpecific(coarse,DM_CLASSID,1); PetscValidHeaderSpecific(fine,DM_CLASSID,2); ierr = DMSetUp(coarse);CHKERRQ(ierr); ierr = DMSetUp(fine);CHKERRQ(ierr); /* use global vectors only for determining matrix layout */ ierr = DMGetGlobalVector(coarse,&gcoarse);CHKERRQ(ierr); ierr = DMGetGlobalVector(fine,&gfine);CHKERRQ(ierr); ierr = VecGetLocalSize(gcoarse,&n);CHKERRQ(ierr); ierr = VecGetLocalSize(gfine,&m);CHKERRQ(ierr); ierr = VecGetSize(gcoarse,&N);CHKERRQ(ierr); ierr = VecGetSize(gfine,&M);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(coarse,&gcoarse);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(fine,&gfine);CHKERRQ(ierr); nDM = comfine->nDM; if (nDM != comcoarse->nDM) SETERRQ2(((PetscObject)fine)->comm,PETSC_ERR_ARG_INCOMP,"Fine DMComposite has %D entries, but coarse has %D",nDM,comcoarse->nDM); ierr = PetscMalloc(nDM*nDM*sizeof(Mat),&mats);CHKERRQ(ierr); ierr = PetscMemzero(mats,nDM*nDM*sizeof(Mat));CHKERRQ(ierr); if (v) { ierr = PetscMalloc(nDM*sizeof(Vec),&vecs);CHKERRQ(ierr); ierr = PetscMemzero(vecs,nDM*sizeof(Vec));CHKERRQ(ierr); } /* loop over packed objects, handling one at at time */ for (nextc=comcoarse->next,nextf=comfine->next,i=0; nextc; nextc=nextc->next,nextf=nextf->next,i++) { if (!v) { ierr = DMCreateInterpolation(nextc->dm,nextf->dm,&mats[i*nDM+i],PETSC_NULL);CHKERRQ(ierr); } else { ierr = DMCreateInterpolation(nextc->dm,nextf->dm,&mats[i*nDM+i],&vecs[i]);CHKERRQ(ierr); } } ierr = MatCreateNest(((PetscObject)fine)->comm,nDM,PETSC_NULL,nDM,PETSC_NULL,mats,A);CHKERRQ(ierr); if (v) { ierr = VecCreateNest(((PetscObject)fine)->comm,nDM,PETSC_NULL,vecs,v);CHKERRQ(ierr); } for (i=0; i<nDM*nDM; i++) {ierr = MatDestroy(&mats[i]);CHKERRQ(ierr);} ierr = PetscFree(mats);CHKERRQ(ierr); if (v) { for (i=0; i<nDM; i++) {ierr = VecDestroy(&vecs[i]);CHKERRQ(ierr);} ierr = PetscFree(vecs);CHKERRQ(ierr); } PetscFunctionReturn(0); }
static PetscErrorCode VecDuplicate_Nest(Vec x,Vec *y) { Vec_Nest *bx = (Vec_Nest*)x->data; Vec Y; Vec *sub; PetscInt i; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscMalloc(sizeof(Vec)*bx->nb,&sub);CHKERRQ(ierr); for (i=0; i<bx->nb; i++) { ierr = VecDuplicate(bx->v[i],&sub[i]);CHKERRQ(ierr); } ierr = VecCreateNest(PetscObjectComm((PetscObject)x),bx->nb,bx->is,sub,&Y);CHKERRQ(ierr); for (i=0; i<bx->nb; i++) { ierr = VecDestroy(&sub[i]);CHKERRQ(ierr); } ierr = PetscFree(sub);CHKERRQ(ierr); *y = Y; PetscFunctionReturn(0); }
PetscErrorCode test_view( void ) { Vec X, a,b; Vec c,d,e,f; Vec tmp_buf[2]; IS tmp_is[2]; PetscInt index; PetscReal val; PetscInt list[]={0,1,2}; PetscScalar vals[]={0.720032,0.061794,0.0100223}; PetscErrorCode ierr; PetscBool explcit = PETSC_FALSE; PetscFunctionBegin; PetscPrintf( PETSC_COMM_WORLD, "\n\n============== %s ==============\n", PETSC_FUNCTION_NAME ); ierr = VecCreate( PETSC_COMM_WORLD, &c );CHKERRQ(ierr); ierr = VecSetSizes( c, PETSC_DECIDE, 3 );CHKERRQ(ierr); ierr = VecSetFromOptions( c );CHKERRQ(ierr); ierr = VecDuplicate( c, &d );CHKERRQ(ierr); ierr = VecDuplicate( c, &e );CHKERRQ(ierr); ierr = VecDuplicate( c, &f );CHKERRQ(ierr); ierr = VecSet( c, 1.0 );CHKERRQ(ierr); ierr = VecSet( d, 2.0 );CHKERRQ(ierr); ierr = VecSet( e, 3.0 );CHKERRQ(ierr); ierr = VecSetValues(f,3,list,vals,INSERT_VALUES);CHKERRQ(ierr); ierr = VecAssemblyBegin(f);CHKERRQ(ierr); ierr = VecAssemblyEnd(f);CHKERRQ(ierr); ierr = VecScale( f, 10.0 );CHKERRQ(ierr); tmp_buf[0] = e; tmp_buf[1] = f; ierr = PetscOptionsGetBool(0,"-explicit_is",&explcit,0);CHKERRQ(ierr); ierr = GetISs(tmp_buf,tmp_is);CHKERRQ(ierr); ierr = VecCreateNest(PETSC_COMM_WORLD,2,explcit?tmp_is:PETSC_NULL,tmp_buf,&b);CHKERRQ(ierr); ierr = VecDestroy(&e);CHKERRQ(ierr); ierr = VecDestroy(&f);CHKERRQ(ierr); ierr = ISDestroy(&tmp_is[0]);CHKERRQ(ierr); ierr = ISDestroy(&tmp_is[1]);CHKERRQ(ierr); tmp_buf[0] = c; tmp_buf[1] = d; ierr = VecCreateNest(PETSC_COMM_WORLD,2,PETSC_NULL,tmp_buf,&a);CHKERRQ(ierr); ierr = VecDestroy(&c);CHKERRQ(ierr); ierr = VecDestroy(&d);CHKERRQ(ierr); tmp_buf[0] = a; tmp_buf[1] = b; ierr = VecCreateNest(PETSC_COMM_WORLD,2,PETSC_NULL,tmp_buf,&X);CHKERRQ(ierr); ierr = VecDestroy(&a);CHKERRQ(ierr); ierr = VecAssemblyBegin(X);CHKERRQ(ierr); ierr = VecAssemblyEnd(X);CHKERRQ(ierr); ierr = VecMax( b, &index, &val );CHKERRQ(ierr); PetscPrintf( PETSC_COMM_WORLD, "(max-b) = %f : index = %d \n", val, index ); ierr = VecMin( b, &index, &val );CHKERRQ(ierr); PetscPrintf( PETSC_COMM_WORLD, "(min-b) = %f : index = %d \n", val, index ); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = VecMax( X, &index, &val );CHKERRQ(ierr); PetscPrintf( PETSC_COMM_WORLD, "(max-X) = %f : index = %d \n", val, index ); ierr = VecMin( X, &index, &val );CHKERRQ(ierr); PetscPrintf( PETSC_COMM_WORLD, "(min-X) = %f : index = %d \n", val, index ); ierr = VecView( X, PETSC_VIEWER_STDOUT_WORLD );CHKERRQ(ierr); ierr = VecDestroy(&X);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode test_axpy_dot_max( void ) { Vec x1,y1, x2,y2; Vec tmp_buf[2]; Vec X, Y; PetscReal real,real2; PetscScalar scalar; PetscInt index; PetscErrorCode ierr; PetscFunctionBegin; PetscPrintf( PETSC_COMM_WORLD, "\n\n============== %s ==============\n", PETSC_FUNCTION_NAME ); gen_test_vector( PETSC_COMM_WORLD, 4, 0, 1, &x1 ); gen_test_vector( PETSC_COMM_WORLD, 5, 10, 2, &x2 ); gen_test_vector( PETSC_COMM_WORLD, 4, 4, 3, &y1 ); gen_test_vector( PETSC_COMM_WORLD, 5, 5, 1, &y2 ); tmp_buf[0] = x1; tmp_buf[1] = x2; ierr = VecCreateNest(PETSC_COMM_WORLD,2,PETSC_NULL,tmp_buf,&X);CHKERRQ(ierr); ierr = VecAssemblyBegin(X);CHKERRQ(ierr); ierr = VecAssemblyEnd(X);CHKERRQ(ierr); ierr = VecDestroy(&x1);CHKERRQ(ierr); ierr = VecDestroy(&x2);CHKERRQ(ierr); tmp_buf[0] = y1; tmp_buf[1] = y2; ierr = VecCreateNest(PETSC_COMM_WORLD,2,PETSC_NULL,tmp_buf,&Y);CHKERRQ(ierr); ierr = VecAssemblyBegin(Y);CHKERRQ(ierr); ierr = VecAssemblyEnd(Y);CHKERRQ(ierr); ierr = VecDestroy(&y1);CHKERRQ(ierr); ierr = VecDestroy(&y2);CHKERRQ(ierr); PetscPrintf( PETSC_COMM_WORLD, "VecAXPY \n"); ierr = VecAXPY( Y, 1.0, X ); /* Y <- a X + Y */ ierr = VecNestGetSubVec( Y, 0, &y1 );CHKERRQ(ierr); ierr = VecNestGetSubVec( Y, 1, &y2 );CHKERRQ(ierr); PetscPrintf( PETSC_COMM_WORLD, "(1) y1 = \n" ); ierr = VecView( y1, PETSC_VIEWER_STDOUT_WORLD );CHKERRQ(ierr); PetscPrintf( PETSC_COMM_WORLD, "(1) y2 = \n" ); ierr = VecView( y2, PETSC_VIEWER_STDOUT_WORLD );CHKERRQ(ierr); ierr = VecDot( X,Y, &scalar );CHKERRQ(ierr); PetscPrintf( PETSC_COMM_WORLD, "X.Y = %lf + %lfi \n", PetscRealPart(scalar), PetscImaginaryPart(scalar) ); ierr = VecDotNorm2( X,Y, &scalar, &real2 );CHKERRQ(ierr); PetscPrintf( PETSC_COMM_WORLD, "X.Y = %lf + %lfi norm2(Y) = %lf\n", PetscRealPart(scalar), PetscImaginaryPart(scalar), real2); ierr = VecAXPY( Y, 1.0, X ); /* Y <- a X + Y */ ierr = VecNestGetSubVec( Y, 0, &y1 );CHKERRQ(ierr); ierr = VecNestGetSubVec( Y, 1, &y2 );CHKERRQ(ierr); PetscPrintf( PETSC_COMM_WORLD, "(2) y1 = \n" ); ierr = VecView( y1, PETSC_VIEWER_STDOUT_WORLD );CHKERRQ(ierr); PetscPrintf( PETSC_COMM_WORLD, "(2) y2 = \n" ); ierr = VecView( y2, PETSC_VIEWER_STDOUT_WORLD );CHKERRQ(ierr); ierr = VecDot( X,Y, &scalar );CHKERRQ(ierr); PetscPrintf( PETSC_COMM_WORLD, "X.Y = %lf + %lfi \n", PetscRealPart(scalar), PetscImaginaryPart(scalar) ); ierr = VecDotNorm2( X,Y, &scalar, &real2 );CHKERRQ(ierr); PetscPrintf( PETSC_COMM_WORLD, "X.Y = %lf + %lfi norm2(Y) = %lf\n", PetscRealPart(scalar), PetscImaginaryPart(scalar), real2); ierr = VecMax( X, &index, &real );CHKERRQ(ierr); PetscPrintf( PETSC_COMM_WORLD, "(max-X) = %f : index = %d \n", real, index ); ierr = VecMin( X, &index, &real );CHKERRQ(ierr); PetscPrintf( PETSC_COMM_WORLD, "(min-X) = %f : index = %d \n", real, index ); ierr = VecDestroy(&X);CHKERRQ(ierr); ierr = VecDestroy(&Y);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode test_vec_ops(void) { Vec X,Y,a,b; Vec c,d,e,f,g,h; PetscScalar val; PetscErrorCode ierr; PetscInt tmp_ind[2]; Vec tmp_buf[2]; PetscFunctionBegin; PetscPrintf(PETSC_COMM_WORLD, "============== %s ==============\n",PETSC_FUNCTION_NAME); /* create 4 slave vectors */ ierr = VecCreate(PETSC_COMM_WORLD, &c);CHKERRQ(ierr); ierr = VecSetSizes(c, PETSC_DECIDE, 4);CHKERRQ(ierr); ierr = VecSetType(c, VECMPI);CHKERRQ(ierr); ierr = VecDuplicate(c, &d);CHKERRQ(ierr); ierr = VecDuplicate(c, &e);CHKERRQ(ierr); ierr = VecDuplicate(c, &f);CHKERRQ(ierr); /* create two more slaves of different sizes */ ierr = VecCreate(PETSC_COMM_WORLD, &g);CHKERRQ(ierr); ierr = VecSetSizes(g, PETSC_DECIDE, 6);CHKERRQ(ierr); ierr = VecSetType(g, VECMPI);CHKERRQ(ierr); ierr = VecCreate(PETSC_COMM_WORLD, &h);CHKERRQ(ierr); ierr = VecSetSizes(h, PETSC_DECIDE, 8);CHKERRQ(ierr); ierr = VecSetType(h, VECMPI);CHKERRQ(ierr); /* set the 6 vectors to some numbers */ ierr = VecSet(c, 1.0);CHKERRQ(ierr); ierr = VecSet(d, 2.0);CHKERRQ(ierr); ierr = VecSet(e, 3.0);CHKERRQ(ierr); ierr = VecSet(f, 4.0);CHKERRQ(ierr); ierr = VecSet(g, 5.0);CHKERRQ(ierr); ierr = VecSet(h, 6.0);CHKERRQ(ierr); /* assemble a */ PetscPrintf(PETSC_COMM_WORLD, "a = [c d] \n"); tmp_buf[0] = c; tmp_buf[1] = d; ierr = VecCreateNest(PETSC_COMM_WORLD,2,NULL,tmp_buf,&a);CHKERRQ(ierr); ierr = VecView(a,PETSC_VIEWER_STDOUT_WORLD); PetscPrintf(PETSC_COMM_WORLD, "a = [d c] \n"); ierr = VecNestSetSubVec(a, 1, c);CHKERRQ(ierr); ierr = VecNestSetSubVec(a, 0, d);CHKERRQ(ierr); ierr = VecAssemblyBegin(a);CHKERRQ(ierr); ierr = VecAssemblyEnd(a);CHKERRQ(ierr); ierr = VecView(a,PETSC_VIEWER_STDOUT_WORLD); /* assemble b */ PetscPrintf(PETSC_COMM_WORLD, "b = [e f] \n"); tmp_buf[0] = e; tmp_buf[1] = f; ierr = VecCreateNest(PETSC_COMM_WORLD,2,NULL,tmp_buf,&b);CHKERRQ(ierr); ierr = VecView(b,PETSC_VIEWER_STDOUT_WORLD); PetscPrintf(PETSC_COMM_WORLD, "b = [f e] \n"); ierr = VecNestSetSubVec(b, 1, e);CHKERRQ(ierr); ierr = VecNestSetSubVec(b, 0, f);CHKERRQ(ierr); ierr = VecAssemblyBegin(b);CHKERRQ(ierr); ierr = VecAssemblyEnd(b);CHKERRQ(ierr); ierr = VecView(b,PETSC_VIEWER_STDOUT_WORLD); PetscPrintf(PETSC_COMM_WORLD, "X = [a b] \n"); tmp_buf[0] = a; tmp_buf[1] = b; ierr = VecCreateNest(PETSC_COMM_WORLD,2,NULL,tmp_buf,&X);CHKERRQ(ierr); ierr = VecView(X,PETSC_VIEWER_STDOUT_WORLD); ierr = VecDot(X,X, &val);CHKERRQ(ierr); PetscPrintf(PETSC_COMM_WORLD, "X.X = %f \n", val); /* re-order components of X */ PetscPrintf(PETSC_COMM_WORLD, "X = [b a] \n"); ierr = VecNestSetSubVec(X,1,a);CHKERRQ(ierr); ierr = VecNestSetSubVec(X,0,b);CHKERRQ(ierr); ierr = VecAssemblyBegin(X);CHKERRQ(ierr); ierr = VecAssemblyEnd(X);CHKERRQ(ierr); ierr = VecView(X,PETSC_VIEWER_STDOUT_WORLD); ierr = VecDot(X,X,&val);CHKERRQ(ierr); PetscPrintf(PETSC_COMM_WORLD, "X.X = %f \n", val); /* re-assemble X */ PetscPrintf(PETSC_COMM_WORLD, "X = [g h] \n"); ierr = VecNestSetSubVec(X,1,g);CHKERRQ(ierr); ierr = VecNestSetSubVec(X,0,h);CHKERRQ(ierr); ierr = VecAssemblyBegin(X);CHKERRQ(ierr); ierr = VecAssemblyEnd(X);CHKERRQ(ierr); ierr = VecView(X,PETSC_VIEWER_STDOUT_WORLD); ierr = VecDot(X,X,&val);CHKERRQ(ierr); PetscPrintf(PETSC_COMM_WORLD, "X.X = %f \n", val); PetscPrintf(PETSC_COMM_WORLD, "Y = X \n"); ierr = VecDuplicate(X, &Y);CHKERRQ(ierr); ierr = VecCopy(X,Y);CHKERRQ(ierr); ierr = VecView(Y,PETSC_VIEWER_STDOUT_WORLD); ierr = VecDot(Y,Y,&val);CHKERRQ(ierr); PetscPrintf(PETSC_COMM_WORLD, "Y.Y = %f \n", val); PetscPrintf(PETSC_COMM_WORLD, "Y = [a b] \n"); tmp_buf[0] = a; tmp_buf[1] = b; tmp_ind[0] = 0; tmp_ind[1] = 1; ierr = VecNestSetSubVecs(Y,2,tmp_ind,tmp_buf);CHKERRQ(ierr); ierr = VecView(Y,PETSC_VIEWER_STDOUT_WORLD); ierr = VecDestroy(&c);CHKERRQ(ierr); ierr = VecDestroy(&d);CHKERRQ(ierr); ierr = VecDestroy(&e);CHKERRQ(ierr); ierr = VecDestroy(&f);CHKERRQ(ierr); ierr = VecDestroy(&g);CHKERRQ(ierr); ierr = VecDestroy(&h);CHKERRQ(ierr); ierr = VecDestroy(&a);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = VecDestroy(&X);CHKERRQ(ierr); ierr = VecDestroy(&Y);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode test_solve(void) { Mat A11, A12,A21,A22, A, tmp[2][2]; KSP ksp; PC pc; Vec b,x, f,h, diag, x1,x2; Vec tmp_x[2],*_tmp_x; int n, np, i,j; PetscErrorCode ierr; PetscFunctionBeginUser; PetscPrintf(PETSC_COMM_WORLD, "%s \n", PETSC_FUNCTION_NAME); n = 3; np = 2; /* Create matrices */ /* A11 */ ierr = VecCreate(PETSC_COMM_WORLD, &diag);CHKERRQ(ierr); ierr = VecSetSizes(diag, PETSC_DECIDE, n);CHKERRQ(ierr); ierr = VecSetFromOptions(diag);CHKERRQ(ierr); ierr = VecSet(diag, (1.0/10.0));CHKERRQ(ierr); /* so inverse = diag(10) */ /* As a test, create a diagonal matrix for A11 */ ierr = MatCreate(PETSC_COMM_WORLD, &A11);CHKERRQ(ierr); ierr = MatSetSizes(A11, PETSC_DECIDE, PETSC_DECIDE, n, n);CHKERRQ(ierr); ierr = MatSetType(A11, MATAIJ);CHKERRQ(ierr); ierr = MatSeqAIJSetPreallocation(A11, n, NULL);CHKERRQ(ierr); ierr = MatMPIAIJSetPreallocation(A11, np, NULL,np, NULL);CHKERRQ(ierr); ierr = MatDiagonalSet(A11, diag, INSERT_VALUES);CHKERRQ(ierr); ierr = VecDestroy(&diag);CHKERRQ(ierr); /* A12 */ ierr = MatCreate(PETSC_COMM_WORLD, &A12);CHKERRQ(ierr); ierr = MatSetSizes(A12, PETSC_DECIDE, PETSC_DECIDE, n, np);CHKERRQ(ierr); ierr = MatSetType(A12, MATAIJ);CHKERRQ(ierr); ierr = MatSeqAIJSetPreallocation(A12, np, NULL);CHKERRQ(ierr); ierr = MatMPIAIJSetPreallocation(A12, np, NULL,np, NULL);CHKERRQ(ierr); for (i=0; i<n; i++) { for (j=0; j<np; j++) { ierr = MatSetValue(A12, i,j, (PetscScalar)(i+j*n), INSERT_VALUES);CHKERRQ(ierr); } } ierr = MatSetValue(A12, 2,1, (PetscScalar)(4), INSERT_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin(A12, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A12, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* A21 */ ierr = MatTranspose(A12, MAT_INITIAL_MATRIX, &A21);CHKERRQ(ierr); A22 = NULL; /* Create block matrix */ tmp[0][0] = A11; tmp[0][1] = A12; tmp[1][0] = A21; tmp[1][1] = A22; ierr = MatCreateNest(PETSC_COMM_WORLD,2,NULL,2,NULL,&tmp[0][0],&A);CHKERRQ(ierr); ierr = MatNestSetVecType(A,VECNEST);CHKERRQ(ierr); ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* Create vectors */ ierr = MatCreateVecs(A12, &h, &f);CHKERRQ(ierr); ierr = VecSet(f, 1.0);CHKERRQ(ierr); ierr = VecSet(h, 0.0);CHKERRQ(ierr); /* Create block vector */ tmp_x[0] = f; tmp_x[1] = h; ierr = VecCreateNest(PETSC_COMM_WORLD,2,NULL,tmp_x,&b);CHKERRQ(ierr); ierr = VecAssemblyBegin(b);CHKERRQ(ierr); ierr = VecAssemblyEnd(b);CHKERRQ(ierr); ierr = VecDuplicate(b, &x);CHKERRQ(ierr); ierr = KSPCreate(PETSC_COMM_WORLD, &ksp);CHKERRQ(ierr); ierr = KSPSetOperators(ksp, A, A);CHKERRQ(ierr); ierr = KSPSetType(ksp, "gmres");CHKERRQ(ierr); ierr = KSPGetPC(ksp, &pc);CHKERRQ(ierr); ierr = PCSetType(pc, "none");CHKERRQ(ierr); ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr); ierr = KSPSolve(ksp, b, x);CHKERRQ(ierr); ierr = VecNestGetSubVecs(x,NULL,&_tmp_x);CHKERRQ(ierr); x1 = _tmp_x[0]; x2 = _tmp_x[1]; PetscPrintf(PETSC_COMM_WORLD, "x1 \n"); PetscViewerPushFormat(PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_ASCII_INFO_DETAIL);CHKERRQ(ierr); ierr = VecView(x1, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); PetscPrintf(PETSC_COMM_WORLD, "x2 \n"); ierr = VecView(x2, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); PetscViewerPopFormat(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = KSPDestroy(&ksp);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = MatDestroy(&A11);CHKERRQ(ierr); ierr = MatDestroy(&A12);CHKERRQ(ierr); ierr = MatDestroy(&A21);CHKERRQ(ierr); ierr = VecDestroy(&f);CHKERRQ(ierr); ierr = VecDestroy(&h);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode _BlockSolve( void* solver, void* _stokesSLE ) { Stokes_SLE* stokesSLE = (Stokes_SLE*)_stokesSLE; StokesBlockKSPInterface* Solver = (StokesBlockKSPInterface*)solver; /* Create shortcuts to stuff needed on sle */ Mat K; Mat G; Mat Gt; Mat D; Mat C; Mat approxS; Vec u; Vec p; Vec f; Vec h; Mat stokes_P; Mat stokes_A; Vec stokes_x; Vec stokes_b; Mat a[2][2]; Vec x[2]; Vec b[2]; KSP stokes_ksp; PC stokes_pc; PetscTruth sym,flg; PetscErrorCode ierr; PetscInt N,n; SBKSP_GetStokesOperators( stokesSLE, &K,&G,&D,&C, &approxS, &f,&h, &u,&p ); /* create Gt */ if( !D ) { ierr = MatTranspose( G, MAT_INITIAL_MATRIX, &Gt);CHKERRQ(ierr); sym = PETSC_TRUE; Solver->DIsSym = sym; } else { Gt = D; sym = PETSC_FALSE; Solver->DIsSym = sym; } flg=PETSC_FALSE; PetscOptionsHasName(PETSC_NULL,"-use_petsc_ksp",&flg); if (flg) { if( !C ) { /* Everything in this bracket, dependent on !C, is to build a matrix with diagonals of 0 for C the previous comment ways need a 'zero' matrix to keep fieldsplit happy in petsc? */ MatType mtype; Vec V; //MatGetSize( G, &M, &N ); VecGetSize(p, &N); VecGetLocalSize( p, &n ); MatCreate( PetscObjectComm((PetscObject) K), &C ); MatSetSizes( C, PETSC_DECIDE ,PETSC_DECIDE, N, N ); #if (((PETSC_VERSION_MAJOR==3) && (PETSC_VERSION_MINOR>=3)) || (PETSC_VERSION_MAJOR>3) ) MatSetUp(C); #endif MatGetType( G, &mtype ); MatSetType( C, mtype ); MatGetVecs( G, &V, PETSC_NULL ); VecSet(V, 0.0); //VecSet(h, 1.0); ierr = VecAssemblyBegin( V );CHKERRQ(ierr); ierr = VecAssemblyEnd ( V );CHKERRQ(ierr); ierr = MatDiagonalSet(C,V,INSERT_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin( C, MAT_FINAL_ASSEMBLY );CHKERRQ(ierr); ierr = MatAssemblyEnd ( C, MAT_FINAL_ASSEMBLY );CHKERRQ(ierr); } } a[0][0]=K; a[0][1]=G; a[1][0]=Gt; a[1][1]=C; ierr = MatCreateNest(PetscObjectComm((PetscObject) K), 2, NULL, 2, NULL, (Mat *)a, &stokes_A);CHKERRQ(ierr); ierr = MatAssemblyBegin( stokes_A, MAT_FINAL_ASSEMBLY );CHKERRQ(ierr); ierr = MatAssemblyEnd( stokes_A, MAT_FINAL_ASSEMBLY );CHKERRQ(ierr); x[0]=u; x[1]=p; ierr = VecCreateNest(PetscObjectComm((PetscObject) u), 2, NULL, x, &stokes_x);CHKERRQ(ierr); ierr = VecAssemblyBegin( stokes_x );CHKERRQ(ierr); ierr = VecAssemblyEnd( stokes_x);CHKERRQ(ierr); b[0]=f; b[1]=h; ierr = VecCreateNest(PetscObjectComm((PetscObject) f), 2, NULL, b, &stokes_b);CHKERRQ(ierr); ierr = VecAssemblyBegin( stokes_b );CHKERRQ(ierr); ierr = VecAssemblyEnd( stokes_b);CHKERRQ(ierr); /* if( approxS ) { */ /* a[0][0]=K; a[0][1]=G; */ /* a[1][0]=NULL; a[1][1]=approxS; */ /* ierr = MatCreateNest(PetscObjectComm((PetscObject) K), 2, NULL, 2, NULL, (Mat *)a, &stokes_P);CHKERRQ(ierr); */ /* ierr = MatAssemblyBegin( stokes_P, MAT_FINAL_ASSEMBLY );CHKERRQ(ierr); */ /* ierr = MatAssemblyEnd( stokes_P, MAT_FINAL_ASSEMBLY );CHKERRQ(ierr); */ /* } */ /* else { */ stokes_P = stokes_A; /* } */ /* probably should make a Destroy function for these two */ /* Update options from file and/or string here so we can change things on the fly */ //PetscOptionsInsertFile(PETSC_COMM_WORLD, Solver->optionsFile, PETSC_FALSE); //PetscOptionsInsertString(Solver->optionsString); ierr = KSPCreate( PETSC_COMM_WORLD, &stokes_ksp );CHKERRQ(ierr); Stg_KSPSetOperators( stokes_ksp, stokes_A, stokes_P, SAME_NONZERO_PATTERN ); ierr = KSPSetType( stokes_ksp, "bsscr" );/* i.e. making this the default solver : calls KSPCreate_XXX */CHKERRQ(ierr); ierr = KSPGetPC( stokes_ksp, &stokes_pc );CHKERRQ(ierr); ierr = PCSetType( stokes_pc, PCNONE );CHKERRQ(ierr); ierr = KSPSetInitialGuessNonzero( stokes_ksp, PETSC_TRUE );CHKERRQ(ierr); ierr = KSPSetFromOptions( stokes_ksp );CHKERRQ(ierr); /* Doing this so the KSP Solver has access to the StgFEM Multigrid struct (PETScMGSolver). As well as any custom stuff on the Stokes_SLE struct */ if( stokes_ksp->data ){/* then ksp->data has been created in a KSpSetUp_XXX function */ /* testing for our KSP types that need the data that is on Solver... */ /* for the moment then, this function not completely agnostic about our KSPs */ //if(!strcmp("bsscr",stokes_ksp->type_name)){/* if is bsscr then set up the data on the ksp */ flg=PETSC_FALSE; PetscOptionsHasName(PETSC_NULL,"-use_petsc_ksp",&flg); if (!flg) { ((KSP_COMMON*)(stokes_ksp->data))->st_sle = Solver->st_sle; ((KSP_COMMON*)(stokes_ksp->data))->mg = Solver->mg; ((KSP_COMMON*)(stokes_ksp->data))->DIsSym = Solver->DIsSym; ((KSP_COMMON*)(stokes_ksp->data))->preconditioner = Solver->preconditioner; ((KSP_COMMON*)(stokes_ksp->data))->solver = Solver; } } ierr = KSPSolve( stokes_ksp, stokes_b, stokes_x );CHKERRQ(ierr); Stg_KSPDestroy(&stokes_ksp ); //if( ((StokesBlockKSPInterface*)stokesSLE->solver)->preconditioner ) if(stokes_P != stokes_A) { Stg_MatDestroy(&stokes_P ); } Stg_MatDestroy(&stokes_A ); Stg_VecDestroy(&stokes_x); Stg_VecDestroy(&stokes_b); if(!D){ Stg_MatDestroy(&Gt); } if(C && (stokesSLE->cStiffMat->matrix != C) ){ Stg_MatDestroy(&C); } PetscFunctionReturn(0); }
static int block_system(void) { SNES snes; /* nonlinear solver context */ KSP ksp; /* linear solver context */ PC pc; /* preconditioner context */ Vec x,r; /* solution, residual vectors */ Mat J; /* Jacobian matrix */ PetscErrorCode ierr; PetscInt its; PetscScalar pfive = .5; PetscBool flg; Mat j11, j12, j21, j22; Vec x1, x2, r1, r2; Vec bv; Vec bx[2]; Mat bA[2][2]; PetscFunctionBegin; PetscPrintf( PETSC_COMM_WORLD, "\n\n========================= Block system =========================\n\n" ); ierr = SNESCreate(PETSC_COMM_WORLD,&snes); CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create matrix and vector data structures; set corresponding routines - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Create sub vectors for solution and nonlinear function */ ierr = VecCreateSeq(PETSC_COMM_SELF,1,&x1); CHKERRQ(ierr); ierr = VecDuplicate(x1,&r1); CHKERRQ(ierr); ierr = VecCreateSeq(PETSC_COMM_SELF,1,&x2); CHKERRQ(ierr); ierr = VecDuplicate(x2,&r2); CHKERRQ(ierr); /* Create the block vectors */ bx[0] = x1; bx[1] = x2; ierr = VecCreateNest(PETSC_COMM_WORLD,2,PETSC_NULL,bx,&x); CHKERRQ(ierr); ierr = VecAssemblyBegin(x); CHKERRQ(ierr); ierr = VecAssemblyEnd(x); CHKERRQ(ierr); ierr = VecDestroy(&x1); CHKERRQ(ierr); ierr = VecDestroy(&x2); CHKERRQ(ierr); bx[0] = r1; bx[1] = r2; ierr = VecCreateNest(PETSC_COMM_WORLD,2,PETSC_NULL,bx,&r); CHKERRQ(ierr); ierr = VecDestroy(&r1); CHKERRQ(ierr); ierr = VecDestroy(&r2); CHKERRQ(ierr); ierr = VecAssemblyBegin(r); CHKERRQ(ierr); ierr = VecAssemblyEnd(r); CHKERRQ(ierr); /* Create sub Jacobian matrix data structure */ ierr = MatCreate( PETSC_COMM_WORLD, &j11 ); CHKERRQ(ierr); ierr = MatSetSizes( j11, 1, 1, 1, 1 ); CHKERRQ(ierr); ierr = MatSetType( j11, MATSEQAIJ ); CHKERRQ(ierr); ierr = MatSetUp(j11); CHKERRQ(ierr); ierr = MatCreate( PETSC_COMM_WORLD, &j12 ); CHKERRQ(ierr); ierr = MatSetSizes( j12, 1, 1, 1, 1 ); CHKERRQ(ierr); ierr = MatSetType( j12, MATSEQAIJ ); CHKERRQ(ierr); ierr = MatSetUp(j12); CHKERRQ(ierr); ierr = MatCreate( PETSC_COMM_WORLD, &j21 ); CHKERRQ(ierr); ierr = MatSetSizes( j21, 1, 1, 1, 1 ); CHKERRQ(ierr); ierr = MatSetType( j21, MATSEQAIJ ); CHKERRQ(ierr); ierr = MatSetUp(j21); CHKERRQ(ierr); ierr = MatCreate( PETSC_COMM_WORLD, &j22 ); CHKERRQ(ierr); ierr = MatSetSizes( j22, PETSC_DECIDE, PETSC_DECIDE, 1, 1 ); CHKERRQ(ierr); ierr = MatSetType( j22, MATSEQAIJ ); CHKERRQ(ierr); ierr = MatSetUp(j22); CHKERRQ(ierr); /* Create block Jacobian matrix data structure */ bA[0][0] = j11; bA[0][1] = j12; bA[1][0] = j21; bA[1][1] = j22; ierr = MatCreateNest(PETSC_COMM_WORLD,2,PETSC_NULL,2,PETSC_NULL,&bA[0][0],&J); CHKERRQ(ierr); ierr = MatSetUp(J); CHKERRQ(ierr); ierr = MatNestSetVecType(J,VECNEST); CHKERRQ(ierr); ierr = MatDestroy(&j11); CHKERRQ(ierr); ierr = MatDestroy(&j12); CHKERRQ(ierr); ierr = MatDestroy(&j21); CHKERRQ(ierr); ierr = MatDestroy(&j22); CHKERRQ(ierr); ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); ierr = PetscOptionsHasName(PETSC_NULL,"-hard",&flg); CHKERRQ(ierr); if (!flg) { /* Set function evaluation routine and vector. */ ierr = SNESSetFunction(snes,r,FormFunction1_block,PETSC_NULL); CHKERRQ(ierr); /* Set Jacobian matrix data structure and Jacobian evaluation routine */ ierr = SNESSetJacobian(snes,J,J,FormJacobian1_block,PETSC_NULL); CHKERRQ(ierr); } else { ierr = SNESSetFunction(snes,r,FormFunction2_block,PETSC_NULL); CHKERRQ(ierr); ierr = SNESSetJacobian(snes,J,J,FormJacobian2_block,PETSC_NULL); CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Customize nonlinear solver; set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Set linear solver defaults for this problem. By extracting the KSP, KSP, and PC contexts from the SNES context, we can then directly call any KSP, KSP, and PC routines to set various options. */ ierr = SNESGetKSP(snes,&ksp); CHKERRQ(ierr); ierr = KSPGetPC(ksp,&pc); CHKERRQ(ierr); ierr = PCSetType(pc,PCNONE); CHKERRQ(ierr); ierr = KSPSetTolerances(ksp,1.e-4,PETSC_DEFAULT,PETSC_DEFAULT,20); CHKERRQ(ierr); /* Set SNES/KSP/KSP/PC runtime options, e.g., -snes_view -snes_monitor -ksp_type <ksp> -pc_type <pc> These options will override those specified above as long as SNESSetFromOptions() is called _after_ any other customization routines. */ ierr = SNESSetFromOptions(snes); CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Evaluate initial guess; then solve nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ if (!flg) { ierr = VecSet(x,pfive); CHKERRQ(ierr); } else { Vec *vecs; ierr = VecNestGetSubVecs( x, PETSC_NULL, &vecs ); CHKERRQ(ierr); bv = vecs[0]; // ierr = VecBlockGetSubVec( x, 0, &bv );CHKERRQ(ierr); ierr = VecSetValue( bv, 0, 2.0, INSERT_VALUES ); CHKERRQ(ierr); /* xx[0] = 2.0; */ ierr = VecAssemblyBegin(bv); CHKERRQ(ierr); ierr = VecAssemblyEnd(bv); CHKERRQ(ierr); // ierr = VecBlockGetSubVec( x, 1, &bv );CHKERRQ(ierr); bv = vecs[1]; ierr = VecSetValue( bv, 0, 3.0, INSERT_VALUES ); CHKERRQ(ierr); /* xx[1] = 3.0; */ ierr = VecAssemblyBegin(bv); CHKERRQ(ierr); ierr = VecAssemblyEnd(bv); CHKERRQ(ierr); } /* Note: The user should initialize the vector, x, with the initial guess for the nonlinear solver prior to calling SNESSolve(). In particular, to employ an initial guess of zero, the user should explicitly set this vector to zero by calling VecSet(). */ ierr = SNESSolve(snes,PETSC_NULL,x); CHKERRQ(ierr); ierr = SNESGetIterationNumber(snes,&its); CHKERRQ(ierr); if (flg) { Vec f; ierr = VecView(x,PETSC_VIEWER_STDOUT_WORLD); CHKERRQ(ierr); ierr = SNESGetFunction(snes,&f,0,0); CHKERRQ(ierr); ierr = VecView(r,PETSC_VIEWER_STDOUT_WORLD); CHKERRQ(ierr); } ierr = PetscPrintf(PETSC_COMM_SELF,"number of SNES iterations = %D\n\n",its); CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. All PETSc objects should be destroyed when they are no longer needed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = VecDestroy(&x); CHKERRQ(ierr); ierr = VecDestroy(&r); CHKERRQ(ierr); ierr = MatDestroy(&J); CHKERRQ(ierr); ierr = SNESDestroy(&snes); CHKERRQ(ierr); PetscFunctionReturn(0); }