int main(int argc,char **argv) { KSP ksp; DM da; UserContext user; const char *bcTypes[2] = {"dirichlet","neumann"}; PetscErrorCode ierr; PetscInt bc; Vec b,x; PetscInitialize(&argc,&argv,(char *)0,help); ierr = KSPCreate(PETSC_COMM_WORLD,&ksp); CHKERRQ(ierr); ierr = DMDACreate2d(PETSC_COMM_WORLD, DMDA_BOUNDARY_NONE, DMDA_BOUNDARY_NONE,DMDA_STENCIL_STAR,-3,-3,PETSC_DECIDE,PETSC_DECIDE,1,1,0,0,&da); CHKERRQ(ierr); ierr = DMDASetUniformCoordinates(da,0,1,0,1,0,0); CHKERRQ(ierr); ierr = DMDASetFieldName(da,0,"Pressure"); CHKERRQ(ierr); ierr = PetscOptionsBegin(PETSC_COMM_WORLD, "", "Options for the inhomogeneous Poisson equation", "DMqq"); user.rho = 1.0; ierr = PetscOptionsReal("-rho", "The conductivity", "ex29.c", user.rho, &user.rho, PETSC_NULL); CHKERRQ(ierr); user.nu = 0.1; ierr = PetscOptionsReal("-nu", "The width of the Gaussian source", "ex29.c", user.nu, &user.nu, PETSC_NULL); CHKERRQ(ierr); bc = (PetscInt)DIRICHLET; ierr = PetscOptionsEList("-bc_type","Type of boundary condition","ex29.c",bcTypes,2,bcTypes[0],&bc,PETSC_NULL); CHKERRQ(ierr); user.bcType = (BCType)bc; ierr = PetscOptionsEnd(); ierr = KSPSetComputeRHS(ksp,ComputeRHS,&user); CHKERRQ(ierr); ierr = KSPSetComputeOperators(ksp,ComputeMatrix,&user); CHKERRQ(ierr); ierr = KSPSetDM(ksp,da); CHKERRQ(ierr); ierr = KSPSetFromOptions(ksp); CHKERRQ(ierr); ierr = KSPSetUp(ksp); CHKERRQ(ierr); ierr = KSPSolve(ksp,PETSC_NULL,PETSC_NULL); CHKERRQ(ierr); ierr = KSPGetSolution(ksp,&x); CHKERRQ(ierr); ierr = KSPGetRhs(ksp,&b); CHKERRQ(ierr); ierr = DMDestroy(&da); CHKERRQ(ierr); ierr = KSPDestroy(&ksp); CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int main(int argc,char **argv) { PetscErrorCode ierr; KSP ksp; PetscReal norm; DM da; Vec x,b,r; Mat A; PetscInitialize(&argc,&argv,(char *)0,help); ierr = KSPCreate(PETSC_COMM_WORLD,&ksp); CHKERRQ(ierr); ierr = DMDACreate3d(PETSC_COMM_WORLD,DMDA_BOUNDARY_NONE,DMDA_BOUNDARY_NONE,DMDA_BOUNDARY_NONE,DMDA_STENCIL_STAR,-7,-7,-7,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,1,1,0,0,0,&da); CHKERRQ(ierr); ierr = DMSetInitialGuess(da,ComputeInitialGuess); CHKERRQ(ierr); ierr = KSPSetComputeRHS(ksp,ComputeRHS,PETSC_NULL); CHKERRQ(ierr); ierr = KSPSetComputeOperators(ksp,ComputeMatrix,PETSC_NULL); CHKERRQ(ierr); ierr = KSPSetDM(ksp,da); CHKERRQ(ierr); ierr = DMDestroy(&da); CHKERRQ(ierr); ierr = KSPSetFromOptions(ksp); CHKERRQ(ierr); ierr = KSPSolve(ksp,PETSC_NULL,PETSC_NULL); CHKERRQ(ierr); ierr = KSPGetSolution(ksp,&x); CHKERRQ(ierr); ierr = KSPGetRhs(ksp,&b); CHKERRQ(ierr); ierr = VecDuplicate(b,&r); CHKERRQ(ierr); ierr = KSPGetOperators(ksp,&A,PETSC_NULL,PETSC_NULL); CHKERRQ(ierr); ierr = MatMult(A,x,r); CHKERRQ(ierr); ierr = VecAXPY(r,-1.0,b); CHKERRQ(ierr); ierr = VecNorm(r,NORM_2,&norm); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Residual norm %G\n",norm); CHKERRQ(ierr); ierr = VecDestroy(&r); CHKERRQ(ierr); ierr = KSPDestroy(&ksp); CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
/*@C KSPMonitorDynamicTolerance - Recompute the inner tolerance in every outer iteration in an adaptive way. Collective on KSP Input Parameters: + ksp - iterative context . n - iteration number (not used) . fnorm - the current residual norm . dummy - some context as a C struct. fields: coef: a scaling coefficient. default 1.0. can be passed through -sub_ksp_dynamic_tolerance_param bnrm: norm of the right-hand side. store it to avoid repeated calculation Notes: This may be useful for a flexibly preconditioner Krylov method to control the accuracy of the inner solves needed to gaurantee the convergence of the outer iterations. Level: advanced .keywords: KSP, inner tolerance .seealso: KSPMonitorDynamicToleranceDestroy() @*/ PetscErrorCode KSPMonitorDynamicTolerance(KSP ksp,PetscInt its,PetscReal fnorm,void *dummy) { PetscErrorCode ierr; PC pc; PetscReal outer_rtol, outer_abstol, outer_dtol, inner_rtol; PetscInt outer_maxits,nksp,first,i; KSPDynTolCtx *scale = (KSPDynTolCtx*)dummy; KSP kspinner = NULL, *subksp = NULL; PetscFunctionBegin; ierr = KSPGetPC(ksp, &pc); CHKERRQ(ierr); /* compute inner_rtol */ if (scale->bnrm < 0.0) { Vec b; ierr = KSPGetRhs(ksp, &b); CHKERRQ(ierr); ierr = VecNorm(b, NORM_2, &(scale->bnrm)); CHKERRQ(ierr); } ierr = KSPGetTolerances(ksp, &outer_rtol, &outer_abstol, &outer_dtol, &outer_maxits); CHKERRQ(ierr); inner_rtol = PetscMin(scale->coef * scale->bnrm * outer_rtol / fnorm, 0.999); /*ierr = PetscPrintf(PETSC_COMM_WORLD, " Inner rtol = %g\n", (double)inner_rtol);CHKERRQ(ierr);*/ /* if pc is ksp */ ierr = PCKSPGetKSP(pc, &kspinner); CHKERRQ(ierr); if (kspinner) { ierr = KSPSetTolerances(kspinner, inner_rtol, outer_abstol, outer_dtol, outer_maxits); CHKERRQ(ierr); PetscFunctionReturn(0); } /* if pc is bjacobi */ ierr = PCBJacobiGetSubKSP(pc, &nksp, &first, &subksp); CHKERRQ(ierr); if (subksp) { for (i=0; i<nksp; i++) { ierr = KSPSetTolerances(subksp[i], inner_rtol, outer_abstol, outer_dtol, outer_maxits); CHKERRQ(ierr); } PetscFunctionReturn(0); } /* todo: dynamic tolerance may apply to other types of pc too */ PetscFunctionReturn(0); }
int main(int argc,char **argv) { PetscErrorCode ierr; KSP ksp; DM da; AppCtx user; Mat A; Vec b,b2; Vec x; PetscReal nrm; PetscInitialize(&argc,&argv,(char*)0,help); user.k = 1; user.e = .99; ierr = PetscOptionsGetInt(0,"-k",&user.k,0);CHKERRQ(ierr); ierr = PetscOptionsGetScalar(0,"-e",&user.e,0);CHKERRQ(ierr); ierr = KSPCreate(PETSC_COMM_WORLD,&ksp);CHKERRQ(ierr); ierr = DMDACreate1d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,-3,1,1,0,&da);CHKERRQ(ierr); ierr = KSPSetDM(ksp,da);CHKERRQ(ierr); ierr = KSPSetComputeRHS(ksp,ComputeRHS,&user);CHKERRQ(ierr); ierr = KSPSetComputeOperators(ksp,ComputeMatrix,&user);CHKERRQ(ierr); ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr); ierr = KSPSolve(ksp,NULL,NULL);CHKERRQ(ierr); ierr = KSPGetOperators(ksp,&A,NULL);CHKERRQ(ierr); ierr = KSPGetSolution(ksp,&x);CHKERRQ(ierr); ierr = KSPGetRhs(ksp,&b);CHKERRQ(ierr); ierr = VecDuplicate(b,&b2);CHKERRQ(ierr); ierr = MatMult(A,x,b2);CHKERRQ(ierr); ierr = VecAXPY(b2,-1.0,b);CHKERRQ(ierr); ierr = VecNorm(b2,NORM_MAX,&nrm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Residual norm %g\n",(double)nrm);CHKERRQ(ierr); ierr = VecDestroy(&b2);CHKERRQ(ierr); ierr = KSPDestroy(&ksp);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int main(int argc,char **argv) { KSP ksp; DM da; PetscReal norm; PetscErrorCode ierr; PetscInt i,j,k,mx,my,mz,xm,ym,zm,xs,ys,zs; PetscScalar Hx,Hy,Hz; PetscScalar ***array; Vec x,b,r; Mat J; PetscInitialize(&argc,&argv,(char*)0,help); ierr = KSPCreate(PETSC_COMM_WORLD,&ksp);CHKERRQ(ierr); ierr = DMDACreate3d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE,DMDA_STENCIL_STAR,-12,-12,-12,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,1,1,0,0,0,&da);CHKERRQ(ierr); ierr = DMDASetInterpolationType(da, DMDA_Q0);CHKERRQ(ierr); ierr = KSPSetDM(ksp,da);CHKERRQ(ierr); ierr = KSPSetComputeRHS(ksp,ComputeRHS,NULL);CHKERRQ(ierr); ierr = KSPSetComputeOperators(ksp,ComputeMatrix,NULL);CHKERRQ(ierr); ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr); ierr = KSPSolve(ksp,NULL,NULL);CHKERRQ(ierr); ierr = KSPGetSolution(ksp,&x);CHKERRQ(ierr); ierr = KSPGetRhs(ksp,&b);CHKERRQ(ierr); ierr = KSPGetOperators(ksp,NULL,&J);CHKERRQ(ierr); ierr = VecDuplicate(b,&r);CHKERRQ(ierr); ierr = MatMult(J,x,r);CHKERRQ(ierr); ierr = VecAXPY(r,-1.0,b);CHKERRQ(ierr); ierr = VecNorm(r,NORM_2,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Residual norm %g\n",(double)norm);CHKERRQ(ierr); ierr = DMDAGetInfo(da, 0, &mx, &my, &mz, 0,0,0,0,0,0,0,0,0);CHKERRQ(ierr); Hx = 1.0 / (PetscReal)(mx); Hy = 1.0 / (PetscReal)(my); Hz = 1.0 / (PetscReal)(mz); ierr = DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr); ierr = DMDAVecGetArray(da, x, &array);CHKERRQ(ierr); for (k=zs; k<zs+zm; k++) { for (j=ys; j<ys+ym; j++) { for (i=xs; i<xs+xm; i++) { array[k][j][i] -= PetscCosScalar(2*PETSC_PI*(((PetscReal)i+0.5)*Hx))* PetscCosScalar(2*PETSC_PI*(((PetscReal)j+0.5)*Hy))* PetscCosScalar(2*PETSC_PI*(((PetscReal)k+0.5)*Hz)); } } } ierr = DMDAVecRestoreArray(da, x, &array);CHKERRQ(ierr); ierr = VecAssemblyBegin(x);CHKERRQ(ierr); ierr = VecAssemblyEnd(x);CHKERRQ(ierr); ierr = VecNorm(x,NORM_INFINITY,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Error norm %g\n",(double)norm);CHKERRQ(ierr); ierr = VecNorm(x,NORM_1,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Error norm %g\n",(double)(norm/((PetscReal)(mx)*(PetscReal)(my)*(PetscReal)(mz))));CHKERRQ(ierr); ierr = VecNorm(x,NORM_2,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Error norm %g\n",(double)(norm/((PetscReal)(mx)*(PetscReal)(my)*(PetscReal)(mz))));CHKERRQ(ierr); ierr = VecDestroy(&r);CHKERRQ(ierr); ierr = KSPDestroy(&ksp);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int main(int argc,char **argv) { KSP ksp; DM da; UserContext user; PetscReal norm; const char *bcTypes[2] = {"dirichlet","neumann"}; PetscErrorCode ierr; PetscInt bc; PetscInt i,j,k,mx,my,mz,xm,ym,zm,xs,ys,zs; PetscScalar Hx,Hy,Hz; PetscScalar ***array; Vec x,b,r; Mat J; PetscInitialize(&argc,&argv,(char *)0,help); ierr = KSPCreate(PETSC_COMM_WORLD,&ksp);CHKERRQ(ierr); ierr = DMDACreate3d(PETSC_COMM_WORLD,DMDA_BOUNDARY_NONE,DMDA_BOUNDARY_NONE,DMDA_BOUNDARY_NONE,DMDA_STENCIL_STAR,12,12,12,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,1,1,0,0,0,&da);CHKERRQ(ierr); ierr = DMDASetInterpolationType(da, DMDA_Q0);CHKERRQ(ierr); ierr = KSPSetDM(ksp,da);CHKERRQ(ierr); ierr = PetscOptionsBegin(PETSC_COMM_WORLD, "", "Options for the inhomogeneous Poisson equation", "DM"); bc = (PetscInt)NEUMANN; ierr = PetscOptionsEList("-bc_type","Type of boundary condition","ex34.c",bcTypes,2,bcTypes[0],&bc,PETSC_NULL);CHKERRQ(ierr); user.bcType = (BCType)bc; ierr = PetscOptionsEnd(); ierr = KSPSetComputeRHS(ksp,ComputeRHS,&user);CHKERRQ(ierr); ierr = KSPSetComputeOperators(ksp,ComputeMatrix,&user);CHKERRQ(ierr); ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr); ierr = KSPSolve(ksp,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); ierr = KSPGetSolution(ksp,&x);CHKERRQ(ierr); ierr = KSPGetRhs(ksp,&b);CHKERRQ(ierr); ierr = KSPGetOperators(ksp,PETSC_NULL,&J,PETSC_NULL);CHKERRQ(ierr); ierr = VecDuplicate(b,&r);CHKERRQ(ierr); ierr = MatMult(J,x,r);CHKERRQ(ierr); ierr = VecAXPY(r,-1.0,b);CHKERRQ(ierr); ierr = VecNorm(r,NORM_2,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Residual norm %G\n",norm);CHKERRQ(ierr); ierr = DMDAGetInfo(da, 0, &mx, &my, &mz, 0,0,0,0,0,0,0,0,0);CHKERRQ(ierr); Hx = 1.0 / (PetscReal)(mx); Hy = 1.0 / (PetscReal)(my); Hz = 1.0 / (PetscReal)(mz); ierr = DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr); ierr = DMDAVecGetArray(da, x, &array);CHKERRQ(ierr); for (k=zs; k<zs+zm; k++){ for (j=ys; j<ys+ym; j++){ for(i=xs; i<xs+xm; i++){ array[k][j][i] -= PetscCosScalar(2*PETSC_PI*(((PetscReal)i+0.5)*Hx))* PetscCosScalar(2*PETSC_PI*(((PetscReal)j+0.5)*Hy))* PetscCosScalar(2*PETSC_PI*(((PetscReal)k+0.5)*Hz)); } } } ierr = DMDAVecRestoreArray(da, x, &array);CHKERRQ(ierr); ierr = VecAssemblyBegin(x);CHKERRQ(ierr); ierr = VecAssemblyEnd(x);CHKERRQ(ierr); ierr = VecNorm(x,NORM_INFINITY,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Error norm %g\n",norm);CHKERRQ(ierr); ierr = VecNorm(x,NORM_1,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Error norm %g\n",norm/((PetscReal)(mx)*(PetscReal)(my)*(PetscReal)(mz)));CHKERRQ(ierr); ierr = VecNorm(x,NORM_2,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Error norm %g\n",norm/((PetscReal)(mx)*(PetscReal)(my)*(PetscReal)(mz)));CHKERRQ(ierr); ierr = VecDestroy(&r);CHKERRQ(ierr); ierr = KSPDestroy(&ksp);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }