int main(int argc,char **argv) { PetscErrorCode ierr; SNES snes; Vec u, r; /* solution, residual vector */ PetscInt Mx,My,its; SNESConvergedReason reason; DM da; ObsCtx user; PetscReal dx,dy,error1,errorinf; PetscBool feasible = PETSC_FALSE,fdflg = PETSC_FALSE; PetscInitialize(&argc,&argv,(char *)0,help); ierr = DMDACreate2d(PETSC_COMM_WORLD, DMDA_BOUNDARY_NONE, DMDA_BOUNDARY_NONE, DMDA_STENCIL_STAR, /* nonlinear diffusion but diffusivity depends on soln W not grad W */ -11,-11, /* default to 10x10 grid but override with -da_grid_x, -da_grid_y (or -da_refine) */ PETSC_DECIDE,PETSC_DECIDE, /* num of procs in each dim */ 1, /* dof = 1 */ 1, /* s = 1 (stencil extends out one cell) */ PETSC_NULL,PETSC_NULL, /* no specify proc decomposition */ &da);CHKERRQ(ierr); ierr = DMCreateGlobalVector(da,&u);CHKERRQ(ierr); ierr = VecDuplicate(u,&r);CHKERRQ(ierr); ierr = VecDuplicate(u,&(user.uexact));CHKERRQ(ierr); ierr = VecDuplicate(u,&(user.psi));CHKERRQ(ierr); ierr = PetscOptionsBegin(PETSC_COMM_WORLD,"","options to obstacle problem","");CHKERRQ(ierr); ierr = PetscOptionsBool("-fd","use coloring to compute Jacobian by finite differences",PETSC_NULL,fdflg,&fdflg,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-feasible","use feasible initial guess",PETSC_NULL,feasible,&feasible,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsEnd();CHKERRQ(ierr); ierr = DMDASetUniformCoordinates(da,-2.0,2.0,-2.0,2.0,0.0,1.0);CHKERRQ(ierr); ierr = DMSetApplicationContext(da,&user);CHKERRQ(ierr); ierr = FormPsiAndInitialGuess(da,u,feasible);CHKERRQ(ierr); ierr = SNESCreate(PETSC_COMM_WORLD,&snes);CHKERRQ(ierr); ierr = SNESSetDM(snes,da);CHKERRQ(ierr); ierr = SNESSetApplicationContext(snes,&user);CHKERRQ(ierr); ierr = SNESSetType(snes,SNESVINEWTONRSLS);CHKERRQ(ierr); ierr = SNESVISetComputeVariableBounds(snes,&FormBounds);CHKERRQ(ierr); ierr = DMDASNESSetFunctionLocal(da,INSERT_VALUES,(PetscErrorCode (*)(DMDALocalInfo*,void*,void*,void*))FormFunctionLocal,&user);CHKERRQ(ierr); if (!fdflg) { ierr = DMDASNESSetJacobianLocal(da,(PetscErrorCode (*)(DMDALocalInfo*,void*,Mat,Mat,MatStructure*,void*))FormJacobianLocal,&user);CHKERRQ(ierr); } ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); /* report on setup */ ierr = DMDAGetInfo(da,PETSC_IGNORE,&Mx,&My, PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE, PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE, PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);CHKERRQ(ierr); dx = 4.0 / (PetscReal)(Mx-1); dy = 4.0 / (PetscReal)(My-1); ierr = PetscPrintf(PETSC_COMM_WORLD, "setup done: square side length = %.3f\n" " grid Mx,My = %D,%D\n" " spacing dx,dy = %.3f,%.3f\n", 4.0, Mx, My, (double)dx, (double)dy);CHKERRQ(ierr); /* solve nonlinear system */ ierr = SNESSolve(snes,PETSC_NULL,u);CHKERRQ(ierr); ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr); ierr = SNESGetConvergedReason(snes,&reason);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"number of Newton iterations = %D; result = %s\n", its,SNESConvergedReasons[reason]);CHKERRQ(ierr); /* compare to exact */ ierr = VecWAXPY(r,-1.0,user.uexact,u);CHKERRQ(ierr); /* r = W - Wexact */ ierr = VecNorm(r,NORM_1,&error1);CHKERRQ(ierr); error1 /= (PetscReal)Mx * (PetscReal)My; ierr = VecNorm(r,NORM_INFINITY,&errorinf);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"errors: av |u-uexact| = %.3e\n |u-uexact|_inf = %.3e\n",error1,errorinf);CHKERRQ(ierr); /* Free work space. */ ierr = VecDestroy(&u);CHKERRQ(ierr); ierr = VecDestroy(&r);CHKERRQ(ierr); ierr = VecDestroy(&(user.psi));CHKERRQ(ierr); ierr = VecDestroy(&(user.uexact));CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize();CHKERRQ(ierr); return 0; }
PetscInt main(PetscInt argc,char **args) { typedef enum {RANDOM, CONSTANT, TANH, NUM_FUNCS} FuncType; const char *funcNames[NUM_FUNCS] = {"random", "constant", "tanh"}; PetscMPIInt size; PetscInt n = 10,N,Ny,ndim=4,dim[4],DIM,i; Vec x,y,z; PetscScalar s; PetscRandom rdm; PetscReal enorm; PetscInt func=RANDOM; FuncType function = RANDOM; PetscBool view = PETSC_FALSE; PetscErrorCode ierr; PetscScalar *x_array,*y_array,*z_array; fftw_plan fplan,bplan; const ptrdiff_t N0 = 20, N1 = 20; ptrdiff_t alloc_local, local_n0, local_0_start; ierr = PetscInitialize(&argc,&args,(char *)0,help);CHKERRQ(ierr); #if defined(PETSC_USE_COMPLEX) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP, "This example requires real numbers"); #endif ierr = MPI_Comm_size(PETSC_COMM_WORLD, &size);CHKERRQ(ierr); alloc_local=fftw_mpi_local_size_2d(N0, N1, PETSC_COMM_WORLD, &local_n0, &local_0_start); if (size != 1) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP, "This is a uniprocessor example only!"); ierr = PetscOptionsBegin(PETSC_COMM_WORLD, PETSC_NULL, "FFTW Options", "ex142");CHKERRQ(ierr); ierr = PetscOptionsEList("-function", "Function type", "ex142", funcNames, NUM_FUNCS, funcNames[function], &func, PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-vec_view draw", "View the functions", "ex112", view, &view, PETSC_NULL);CHKERRQ(ierr); function = (FuncType) func; ierr = PetscOptionsEnd();CHKERRQ(ierr); for (DIM = 0; DIM < ndim; DIM++){ dim[DIM] = n; /* size of real space vector in DIM-dimension */ } ierr = PetscRandomCreate(PETSC_COMM_SELF, &rdm);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rdm);CHKERRQ(ierr); for (DIM = 1; DIM < 5; DIM++){ /* create vectors of length N=dim[0]*dim[1]* ...*dim[DIM-1] */ /*----------------------------------------------------------*/ N = Ny = 1; for (i = 0; i < DIM-1; i++) { N *= dim[i]; } Ny = N; Ny *= 2*(dim[DIM-1]/2 + 1); /* add padding elements to output vector y */ N *= dim[DIM-1]; ierr = PetscPrintf(PETSC_COMM_SELF, "\n %d-D: FFTW on vector of size %d \n",DIM,N);CHKERRQ(ierr); ierr = VecCreateSeq(PETSC_COMM_SELF,N,&x);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) x, "Real space vector");CHKERRQ(ierr); ierr = VecCreateSeq(PETSC_COMM_SELF,Ny,&y);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) y, "Frequency space vector");CHKERRQ(ierr); ierr = VecDuplicate(x,&z);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) z, "Reconstructed vector");CHKERRQ(ierr); /* Set fftw plan */ /*----------------------------------*/ ierr = VecGetArray(x,&x_array);CHKERRQ(ierr); ierr = VecGetArray(y,&y_array);CHKERRQ(ierr); ierr = VecGetArray(z,&z_array);CHKERRQ(ierr); unsigned int flags = FFTW_ESTIMATE; //or FFTW_MEASURE /* The data in the in/out arrays is overwritten during FFTW_MEASURE planning, so such planning should be done before the input is initialized by the user. */ printf("DIM: %d, N %d, Ny %d\n",DIM,N,Ny); switch (DIM){ case 1: fplan = fftw_plan_dft_r2c_1d(dim[0], (double *)x_array, (fftw_complex*)y_array, flags); bplan = fftw_plan_dft_c2r_1d(dim[0], (fftw_complex*)y_array, (double *)z_array, flags); break; case 2: fplan = fftw_plan_dft_r2c_2d(dim[0],dim[1],(double *)x_array, (fftw_complex*)y_array,flags); bplan = fftw_plan_dft_c2r_2d(dim[0],dim[1],(fftw_complex*)y_array,(double *)z_array,flags); break; case 3: fplan = fftw_plan_dft_r2c_3d(dim[0],dim[1],dim[2],(double *)x_array, (fftw_complex*)y_array,flags); bplan = fftw_plan_dft_c2r_3d(dim[0],dim[1],dim[2],(fftw_complex*)y_array,(double *)z_array,flags); break; default: fplan = fftw_plan_dft_r2c(DIM,dim,(double *)x_array, (fftw_complex*)y_array,flags); bplan = fftw_plan_dft_c2r(DIM,dim,(fftw_complex*)y_array,(double *)z_array,flags); break; } ierr = VecRestoreArray(x,&x_array);CHKERRQ(ierr); ierr = VecRestoreArray(y,&y_array);CHKERRQ(ierr); ierr = VecRestoreArray(z,&z_array);CHKERRQ(ierr); /* Initialize Real space vector x: The data in the in/out arrays is overwritten during FFTW_MEASURE planning, so planning should be done before the input is initialized by the user. --------------------------------------------------------*/ if (function == RANDOM) { ierr = VecSetRandom(x, rdm);CHKERRQ(ierr); } else if (function == CONSTANT) { ierr = VecSet(x, 1.0);CHKERRQ(ierr); } else if (function == TANH) { ierr = VecGetArray(x, &x_array);CHKERRQ(ierr); for (i = 0; i < N; ++i) { x_array[i] = tanh((i - N/2.0)*(10.0/N)); } ierr = VecRestoreArray(x, &x_array);CHKERRQ(ierr); } if (view) { ierr = VecView(x, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } /* FFT - also test repeated transformation */ /*-------------------------------------------*/ ierr = VecGetArray(x,&x_array);CHKERRQ(ierr); ierr = VecGetArray(y,&y_array);CHKERRQ(ierr); ierr = VecGetArray(z,&z_array);CHKERRQ(ierr); for (i=0; i<3; i++){ /* FFTW_FORWARD */ fftw_execute(fplan); //printf("\n fout:\n"); //fftw_complex* fout = (fftw_complex*)y_array; //for (i=0; i<N/2+1; i++) printf("%d (%g %g)\n",i,fout[i][0],fout[i][1]); /* FFTW_BACKWARD: destroys its input array 'y_array' even for out-of-place transforms! */ fftw_execute(bplan); } ierr = VecRestoreArray(x,&x_array);CHKERRQ(ierr); ierr = VecRestoreArray(y,&y_array);CHKERRQ(ierr); ierr = VecRestoreArray(z,&z_array);CHKERRQ(ierr); /* Compare x and z. FFTW computes an unnormalized DFT, thus z = N*x */ /*------------------------------------------------------------------*/ s = 1.0/(PetscReal)N; ierr = VecScale(z,s);CHKERRQ(ierr); if (view) {ierr = VecView(x, PETSC_VIEWER_DRAW_WORLD);CHKERRQ(ierr);} if (view) {ierr = VecView(z, PETSC_VIEWER_DRAW_WORLD);CHKERRQ(ierr);} ierr = VecAXPY(z,-1.0,x);CHKERRQ(ierr); ierr = VecNorm(z,NORM_1,&enorm);CHKERRQ(ierr); if (enorm > 1.e-11){ ierr = PetscPrintf(PETSC_COMM_SELF," Error norm of |x - z| %G\n",enorm);CHKERRQ(ierr); } /* free spaces */ fftw_destroy_plan(fplan); fftw_destroy_plan(bplan); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&y);CHKERRQ(ierr); ierr = VecDestroy(&z);CHKERRQ(ierr); } ierr = PetscRandomDestroy(&rdm);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
PetscErrorCode PCSetFromOptions_MG(PetscOptionItems *PetscOptionsObject,PC pc) { PetscErrorCode ierr; PetscInt m,levels = 1,cycles; PetscBool flg,set; PC_MG *mg = (PC_MG*)pc->data; PC_MG_Levels **mglevels; PCMGType mgtype; PCMGCycleType mgctype; PetscFunctionBegin; ierr = PetscOptionsHead(PetscOptionsObject,"Multigrid options");CHKERRQ(ierr); if (!mg->levels) { ierr = PetscOptionsInt("-pc_mg_levels","Number of Levels","PCMGSetLevels",levels,&levels,&flg);CHKERRQ(ierr); if (!flg && pc->dm) { ierr = DMGetRefineLevel(pc->dm,&levels);CHKERRQ(ierr); levels++; mg->usedmfornumberoflevels = PETSC_TRUE; } ierr = PCMGSetLevels(pc,levels,NULL);CHKERRQ(ierr); } mglevels = mg->levels; mgctype = (PCMGCycleType) mglevels[0]->cycles; ierr = PetscOptionsEnum("-pc_mg_cycle_type","V cycle or for W-cycle","PCMGSetCycleType",PCMGCycleTypes,(PetscEnum)mgctype,(PetscEnum*)&mgctype,&flg);CHKERRQ(ierr); if (flg) { ierr = PCMGSetCycleType(pc,mgctype);CHKERRQ(ierr); } flg = PETSC_FALSE; ierr = PetscOptionsBool("-pc_mg_galerkin","Use Galerkin process to compute coarser operators","PCMGSetGalerkin",flg,&flg,&set);CHKERRQ(ierr); if (set) { ierr = PCMGSetGalerkin(pc,flg);CHKERRQ(ierr); } ierr = PetscOptionsInt("-pc_mg_smoothup","Number of post-smoothing steps","PCMGSetNumberSmoothUp",mg->default_smoothu,&m,&flg);CHKERRQ(ierr); if (flg) { ierr = PCMGSetNumberSmoothUp(pc,m);CHKERRQ(ierr); } ierr = PetscOptionsInt("-pc_mg_smoothdown","Number of pre-smoothing steps","PCMGSetNumberSmoothDown",mg->default_smoothd,&m,&flg);CHKERRQ(ierr); if (flg) { ierr = PCMGSetNumberSmoothDown(pc,m);CHKERRQ(ierr); } mgtype = mg->am; ierr = PetscOptionsEnum("-pc_mg_type","Multigrid type","PCMGSetType",PCMGTypes,(PetscEnum)mgtype,(PetscEnum*)&mgtype,&flg);CHKERRQ(ierr); if (flg) { ierr = PCMGSetType(pc,mgtype);CHKERRQ(ierr); } if (mg->am == PC_MG_MULTIPLICATIVE) { ierr = PetscOptionsInt("-pc_mg_multiplicative_cycles","Number of cycles for each preconditioner step","PCMGMultiplicativeSetCycles",mg->cyclesperpcapply,&cycles,&flg);CHKERRQ(ierr); if (flg) { ierr = PCMGMultiplicativeSetCycles(pc,cycles);CHKERRQ(ierr); } } flg = PETSC_FALSE; ierr = PetscOptionsBool("-pc_mg_log","Log times for each multigrid level","None",flg,&flg,NULL);CHKERRQ(ierr); if (flg) { PetscInt i; char eventname[128]; if (!mglevels) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set MG levels before calling"); levels = mglevels[0]->levels; for (i=0; i<levels; i++) { sprintf(eventname,"MGSetup Level %d",(int)i); ierr = PetscLogEventRegister(eventname,((PetscObject)pc)->classid,&mglevels[i]->eventsmoothsetup);CHKERRQ(ierr); sprintf(eventname,"MGSmooth Level %d",(int)i); ierr = PetscLogEventRegister(eventname,((PetscObject)pc)->classid,&mglevels[i]->eventsmoothsolve);CHKERRQ(ierr); if (i) { sprintf(eventname,"MGResid Level %d",(int)i); ierr = PetscLogEventRegister(eventname,((PetscObject)pc)->classid,&mglevels[i]->eventresidual);CHKERRQ(ierr); sprintf(eventname,"MGInterp Level %d",(int)i); ierr = PetscLogEventRegister(eventname,((PetscObject)pc)->classid,&mglevels[i]->eventinterprestrict);CHKERRQ(ierr); } } #if defined(PETSC_USE_LOG) { const char *sname = "MG Apply"; PetscStageLog stageLog; PetscInt st; PetscFunctionBegin; ierr = PetscLogGetStageLog(&stageLog);CHKERRQ(ierr); for (st = 0; st < stageLog->numStages; ++st) { PetscBool same; ierr = PetscStrcmp(stageLog->stageInfo[st].name, sname, &same);CHKERRQ(ierr); if (same) mg->stageApply = st; } if (!mg->stageApply) { ierr = PetscLogStageRegister(sname, &mg->stageApply);CHKERRQ(ierr); } } #endif } ierr = PetscOptionsTail();CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode MatPtAPSymbolic_SeqAIJ_SeqAIJ(Mat A,Mat P,PetscReal fill,Mat *C) { PetscErrorCode ierr; Mat_SeqAIJ *ap,*c; PetscInt *api,*apj,*ci,pn=P->cmap->N; MatScalar *ca; Mat_PtAP *ptap; Mat Pt,AP; PetscBool sparse_axpy=PETSC_TRUE; PetscFunctionBegin; ierr = PetscObjectOptionsBegin((PetscObject)A);CHKERRQ(ierr); /* flag 'sparse_axpy' determines which implementations to be used: 0: do dense axpy in MatPtAPNumeric() - fastest, but requires storage of struct A*P; 1: do two sparse axpy in MatPtAPNumeric() - slowest, does not store structure of A*P. */ ierr = PetscOptionsBool("-matptap_scalable","Use sparse axpy but slower MatPtAPNumeric()","",sparse_axpy,&sparse_axpy,NULL);CHKERRQ(ierr); ierr = PetscOptionsEnd();CHKERRQ(ierr); if (sparse_axpy) { ierr = MatPtAPSymbolic_SeqAIJ_SeqAIJ_SparseAxpy(A,P,fill,C);CHKERRQ(ierr); PetscFunctionReturn(0); } /* Get symbolic Pt = P^T */ ierr = MatTransposeSymbolic_SeqAIJ(P,&Pt);CHKERRQ(ierr); /* Get symbolic AP = A*P */ ierr = MatMatMultSymbolic_SeqAIJ_SeqAIJ(A,P,fill,&AP);CHKERRQ(ierr); ap = (Mat_SeqAIJ*)AP->data; api = ap->i; apj = ap->j; ap->free_ij = PETSC_FALSE; /* api and apj are kept in struct ptap, cannot be destroyed with AP */ /* Get C = Pt*AP */ ierr = MatMatMultSymbolic_SeqAIJ_SeqAIJ(Pt,AP,fill,C);CHKERRQ(ierr); c = (Mat_SeqAIJ*)(*C)->data; ci = c->i; ierr = PetscMalloc((ci[pn]+1)*sizeof(MatScalar),&ca);CHKERRQ(ierr); ierr = PetscMemzero(ca,(ci[pn]+1)*sizeof(MatScalar));CHKERRQ(ierr); c->a = ca; c->free_a = PETSC_TRUE; /* Create a supporting struct for reuse by MatPtAPNumeric() */ ierr = PetscNew(Mat_PtAP,&ptap);CHKERRQ(ierr); c->ptap = ptap; ptap->destroy = (*C)->ops->destroy; (*C)->ops->destroy = MatDestroy_SeqAIJ_PtAP; /* Allocate temporary array for storage of one row of A*P */ ierr = PetscMalloc((pn+1)*sizeof(PetscScalar),&ptap->apa);CHKERRQ(ierr); ierr = PetscMemzero(ptap->apa,(pn+1)*sizeof(PetscScalar));CHKERRQ(ierr); (*C)->ops->ptapnumeric = MatPtAPNumeric_SeqAIJ_SeqAIJ; ptap->api = api; ptap->apj = apj; /* Clean up. */ ierr = MatDestroy(&Pt);CHKERRQ(ierr); ierr = MatDestroy(&AP);CHKERRQ(ierr); #if defined(PETSC_USE_INFO) ierr = PetscInfo2((*C),"given fill %G, use scalable %d\n",fill,sparse_axpy);CHKERRQ(ierr); #endif PetscFunctionReturn(0); }
PetscInt main(PetscInt argc,char **args) { typedef enum {RANDOM, CONSTANT, TANH, NUM_FUNCS} FuncType; const char *funcNames[NUM_FUNCS] = {"random", "constant", "tanh"}; Mat A; PetscMPIInt size; PetscInt n = 10,N,ndim=4,dim[4],DIM,i; Vec x,y,z; PetscScalar s; PetscRandom rdm; PetscReal enorm; PetscInt func; FuncType function = RANDOM; PetscBool view = PETSC_FALSE; PetscErrorCode ierr; ierr = PetscInitialize(&argc,&args,(char *)0,help);CHKERRQ(ierr); #if !defined(PETSC_USE_COMPLEX) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP, "This example requires complex numbers"); #endif ierr = MPI_Comm_size(PETSC_COMM_WORLD, &size);CHKERRQ(ierr); if (size != 1) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP, "This is a uniprocessor example only!"); ierr = PetscOptionsBegin(PETSC_COMM_WORLD, PETSC_NULL, "FFTW Options", "ex112");CHKERRQ(ierr); ierr = PetscOptionsEList("-function", "Function type", "ex112", funcNames, NUM_FUNCS, funcNames[function], &func, PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-vec_view draw", "View the functions", "ex112", view, &view, PETSC_NULL);CHKERRQ(ierr); function = (FuncType) func; ierr = PetscOptionsEnd();CHKERRQ(ierr); for (DIM = 0; DIM < ndim; DIM++){ dim[DIM] = n; /* size of transformation in DIM-dimension */ } ierr = PetscRandomCreate(PETSC_COMM_SELF, &rdm);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rdm);CHKERRQ(ierr); for (DIM = 1; DIM < 5; DIM++){ for (i = 0, N = 1; i < DIM; i++) N *= dim[i]; ierr = PetscPrintf(PETSC_COMM_SELF, "\n %d-D: FFTW on vector of size %d \n",DIM,N);CHKERRQ(ierr); /* create FFTW object */ ierr = MatCreateFFT(PETSC_COMM_SELF,DIM,dim,MATFFTW,&A);CHKERRQ(ierr); /* create vectors of length N=n^DIM */ ierr = MatGetVecs(A,&x,&y);CHKERRQ(ierr); ierr = MatGetVecs(A,&z,PETSC_NULL);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) x, "Real space vector");CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) y, "Frequency space vector");CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) z, "Reconstructed vector");CHKERRQ(ierr); /* set values of space vector x */ if (function == RANDOM) { ierr = VecSetRandom(x, rdm);CHKERRQ(ierr); } else if (function == CONSTANT) { ierr = VecSet(x, 1.0);CHKERRQ(ierr); } else if (function == TANH) { PetscScalar *a; ierr = VecGetArray(x, &a);CHKERRQ(ierr); for (i = 0; i < N; ++i) { a[i] = tanh((i - N/2.0)*(10.0/N)); } ierr = VecRestoreArray(x, &a);CHKERRQ(ierr); } if (view) {ierr = VecView(x, PETSC_VIEWER_DRAW_WORLD);CHKERRQ(ierr);} /* apply FFTW_FORWARD and FFTW_BACKWARD several times on same x, y, and z */ for (i=0; i<3; i++){ ierr = MatMult(A,x,y);CHKERRQ(ierr); if (view && i == 0) {ierr = VecView(y, PETSC_VIEWER_DRAW_WORLD);CHKERRQ(ierr);} ierr = MatMultTranspose(A,y,z);CHKERRQ(ierr); /* compare x and z. FFTW computes an unnormalized DFT, thus z = N*x */ s = 1.0/(PetscReal)N; ierr = VecScale(z,s);CHKERRQ(ierr); if (view && i == 0) {ierr = VecView(z, PETSC_VIEWER_DRAW_WORLD);CHKERRQ(ierr);} ierr = VecAXPY(z,-1.0,x);CHKERRQ(ierr); ierr = VecNorm(z,NORM_1,&enorm);CHKERRQ(ierr); if (enorm > 1.e-11){ ierr = PetscPrintf(PETSC_COMM_SELF," Error norm of |x - z| %G\n",enorm);CHKERRQ(ierr); } } /* apply FFTW_FORWARD and FFTW_BACKWARD several times on different x */ for (i=0; i<3; i++){ ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecCreateSeq(PETSC_COMM_SELF,N,&x);CHKERRQ(ierr); ierr = VecSetRandom(x, rdm);CHKERRQ(ierr); ierr = MatMult(A,x,y);CHKERRQ(ierr); ierr = MatMultTranspose(A,y,z);CHKERRQ(ierr); /* compare x and z. FFTW computes an unnormalized DFT, thus z = N*x */ s = 1.0/(PetscReal)N; ierr = VecScale(z,s);CHKERRQ(ierr); if (view && i == 0) {ierr = VecView(z, PETSC_VIEWER_DRAW_WORLD);CHKERRQ(ierr);} ierr = VecAXPY(z,-1.0,x);CHKERRQ(ierr); ierr = VecNorm(z,NORM_1,&enorm);CHKERRQ(ierr); if (enorm > 1.e-11){ ierr = PetscPrintf(PETSC_COMM_SELF," Error norm of new |x - z| %G\n",enorm);CHKERRQ(ierr); } } /* free spaces */ ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&y);CHKERRQ(ierr); ierr = VecDestroy(&z);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); } ierr = PetscRandomDestroy(&rdm);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int main(int argc,char **argv) { PetscErrorCode ierr; DM da; /* structured grid topology object */ TS ts; /* time-stepping object (contains snes) */ SNES snes; /* Newton solver object */ Vec X,residual; /* solution, residual */ Mat J; /* Jacobian matrix */ PetscInt Mx,My,fsteps,steps; ISColoring iscoloring; PetscReal tstart,tend,ftime,secperday=3600.0*24.0,Y0; PetscBool fdflg = PETSC_FALSE, mfileflg = PETSC_FALSE, optflg = PETSC_FALSE; char mfile[PETSC_MAX_PATH_LEN] = "out.m"; MatFDColoring matfdcoloring; PorousCtx user; /* user-defined work context */ PetscInitialize(&argc,&argv,(char *)0,help); ierr = DMDACreate2d(PETSC_COMM_WORLD, DMDA_BOUNDARY_NONE, DMDA_BOUNDARY_NONE, // correct for zero Dirichlet DMDA_STENCIL_STAR, // nonlinear diffusion but diffusivity // depends on soln W not grad W -21,-21, // default to 20x20 grid but override with // -da_grid_x, -da_grid_y (or -da_refine) PETSC_DECIDE,PETSC_DECIDE, // num of procs in each dim 2, // dof = 2: node = (W,Y) // or node = (P,dPsqr) // or node = (ddxE,ddyN) 1, // s = 1 (stencil extends out one cell) PETSC_NULL,PETSC_NULL, // no specify proc decomposition &da);CHKERRQ(ierr); ierr = DMSetApplicationContext(da,&user);CHKERRQ(ierr); /* get Vecs and Mats for this grid */ ierr = DMCreateGlobalVector(da,&X);CHKERRQ(ierr); ierr = VecDuplicate(X,&residual);CHKERRQ(ierr); ierr = VecDuplicate(X,&user.geom);CHKERRQ(ierr); ierr = DMGetMatrix(da,MATAIJ,&J);CHKERRQ(ierr); /* set up contexts */ tstart = 10.0 * secperday; /* 10 days in seconds */ tend = 30.0 * secperday; steps = 20; Y0 = 1.0; /* initial value of Y, for computing initial value of P; note Ymin = 0.1 is different */ user.da = da; ierr = DefaultContext(&user);CHKERRQ(ierr); ierr = PetscOptionsBegin(PETSC_COMM_WORLD, "","options to (W,P)-space better hydrology model alt","");CHKERRQ(ierr); { ierr = PetscOptionsReal("-alt_sigma","nonlinear power","", user.sigma,&user.sigma,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-alt_Ymin", "min capacity thickness (esp. in pressure computation)","", user.Ymin,&user.Ymin,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-alt_Wmin", "min water amount (esp. in pressure computation)","", user.Wmin,&user.Wmin,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-alt_Y0", "constant initial capacity thickness","", Y0,&Y0,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-alt_Cmelt", "additional coefficient for amount of melt","", user.Cmelt,&user.Cmelt,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-alt_Creep", "creep closure coefficient","", user.Creep,&user.Creep,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-alt_L","half-width of square region in meters","", user.L,&user.L,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-alt_tstart_days","start time in days","", tstart/secperday,&tstart,&optflg);CHKERRQ(ierr); if (optflg) { tstart *= secperday; } ierr = PetscOptionsReal("-alt_tend_days","end time in days","", tend/secperday,&tend,&optflg);CHKERRQ(ierr); if (optflg) { tend *= secperday; } ierr = PetscOptionsInt("-alt_steps","number of timesteps to take","", steps,&steps,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-alt_converge_check", "run silent and check for convergence", "",user.run_silent,&user.run_silent,PETSC_NULL); CHKERRQ(ierr); ierr = PetscOptionsString("-mfile", "name of Matlab file to write results","", mfile,mfile,PETSC_MAX_PATH_LEN,&mfileflg); CHKERRQ(ierr); } ierr = PetscOptionsEnd();CHKERRQ(ierr); /* fix remaining parameters */ ierr = DerivedConstants(&user);CHKERRQ(ierr); ierr = VecStrideSet(user.geom,0,user.H0);CHKERRQ(ierr); /* H(x,y) = H0 */ ierr = VecStrideSet(user.geom,1,0.0);CHKERRQ(ierr); /* b(x,y) = 0 */ ierr = DMDASetUniformCoordinates(da, // square domain -user.L, user.L, -user.L, user.L, 0.0, 1.0);CHKERRQ(ierr); ierr = DMDAGetInfo(da,PETSC_IGNORE,&Mx,&My, PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE, PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE, PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);CHKERRQ(ierr); user.dx = 2.0 * user.L / (Mx-1); user.dy = 2.0 * user.L / (My-1); /* setup TS = timestepping object */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetType(ts,TSCN);CHKERRQ(ierr); ierr = TSSetRHSFunction(ts,residual,RHSFunction,&user);CHKERRQ(ierr); /* use coloring to compute rhs Jacobian efficiently */ ierr = PetscOptionsGetBool(PETSC_NULL,"-fd",&fdflg,PETSC_NULL);CHKERRQ(ierr); if (fdflg){ ierr = DMGetColoring(da,IS_COLORING_GLOBAL,MATAIJ,&iscoloring);CHKERRQ(ierr); ierr = MatFDColoringCreate(J,iscoloring,&matfdcoloring);CHKERRQ(ierr); ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); ierr = MatFDColoringSetFunction(matfdcoloring, (PetscErrorCode (*)(void))RHSFunction,&user);CHKERRQ(ierr); ierr = TSSetRHSJacobian(ts,J,J,TSDefaultComputeJacobianColor, matfdcoloring);CHKERRQ(ierr); } else { /* default case */ ierr = TSSetRHSJacobian(ts,J,J,RHSJacobian,&user);CHKERRQ(ierr); } /* set initial state: W = barenblatt, P = pi (W/Y0)^sigma */ ierr = InitialState(da,&user,tstart,Y0,X);CHKERRQ(ierr); /* set up times for time-stepping */ ierr = TSSetInitialTimeStep(ts,tstart, (tend - tstart) / (PetscReal)steps);CHKERRQ(ierr); ierr = TSSetDuration(ts,steps,tend);CHKERRQ(ierr); ierr = TSSetExactFinalTime(ts,PETSC_TRUE);CHKERRQ(ierr); ierr = TSMonitorSet(ts,MyTSMonitor,&user,PETSC_NULL);CHKERRQ(ierr); /* Set SNESVI type and supply upper and lower bounds. */ ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); ierr = SNESVISetComputeVariableBounds(snes,FormPositivityBounds); CHKERRQ(ierr); /* ask user to finalize settings */ ierr = TSSetFromOptions(ts);CHKERRQ(ierr); /* report on setup */ if (!user.run_silent) { ierr = PetscPrintf(PETSC_COMM_WORLD, "setup done: square side length = %.3f km\n" " grid Mx,My = %d,%d\n" " spacing dx,dy = %.3f,%.3f m\n" " times tstart:dt:tend = %.3f:%.3f:%.3f days\n", 2.0 * user.L / 1000.0, Mx, My, user.dx, user.dy, tstart / secperday, (tend-tstart)/(steps*secperday), tend / secperday); CHKERRQ(ierr); } if (mfileflg) { if (!user.run_silent) { ierr = PetscPrintf(PETSC_COMM_WORLD, "writing initial W,P and geometry H,b to Matlab file %s ...\n", mfile);CHKERRQ(ierr); } ierr = print2vecmatlab(da,X,"W_init","P_init",mfile,PETSC_FALSE);CHKERRQ(ierr); ierr = print2vecmatlab(da,user.geom,"H","b",mfile,PETSC_TRUE);CHKERRQ(ierr); } /* run time-stepping with implicit steps */ ierr = TSSolve(ts,X,&ftime);CHKERRQ(ierr); /* make a report on run and final state */ ierr = TSGetTimeStepNumber(ts,&fsteps);CHKERRQ(ierr); if ((!user.run_silent) && (ftime != tend)) { ierr = PetscPrintf(PETSC_COMM_WORLD, "***WARNING3***: reported final time wrong: ftime(=%.12e) != tend(=%.12e) (days)\n", ftime / secperday, tend / secperday);CHKERRQ(ierr); } if ((!user.run_silent) && (fsteps != steps)) { ierr = PetscPrintf(PETSC_COMM_WORLD, "***WARNING4***: reported number of steps wrong: fsteps(=%D) != steps(=%D)\n", fsteps, steps);CHKERRQ(ierr); } if (mfileflg) { if (!user.run_silent) { ierr = PetscPrintf(PETSC_COMM_WORLD, "writing final fields to %s ...\n",mfile);CHKERRQ(ierr); } ierr = print2vecmatlab(da,X,"W_final","P_final",mfile,PETSC_TRUE);CHKERRQ(ierr); ierr = printfigurematlab(da,2,"W_init","W_final",mfile,PETSC_TRUE);CHKERRQ(ierr); ierr = printfigurematlab(da,3,"P_init","P_final",mfile,PETSC_TRUE);CHKERRQ(ierr); } if (user.run_silent) { ierr = PetscPrintf(PETSC_COMM_WORLD, "%6d %6d %9.3f %.12e\n", Mx, My, (tend-tstart)/secperday, user.maxrnorm);CHKERRQ(ierr); } /* Free work space. */ ierr = MatDestroy(&J);CHKERRQ(ierr); if (fdflg) { ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr); } ierr = VecDestroy(&X);CHKERRQ(ierr); ierr = VecDestroy(&user.geom);CHKERRQ(ierr); ierr = VecDestroy(&residual);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize();CHKERRQ(ierr); PetscFunctionReturn((PetscInt)(user.not_converged_warning)); }
/*@ MatSetFromOptions - Creates a matrix where the type is determined from the options database. Generates a parallel MPI matrix if the communicator has more than one processor. The default matrix type is AIJ, using the routines MatCreateSeqAIJ() and MatCreateAIJ() if you do not select a type in the options database. Collective on Mat Input Parameter: . A - the matrix Options Database Keys: + -mat_type seqaij - AIJ type, uses MatCreateSeqAIJ() . -mat_type mpiaij - AIJ type, uses MatCreateAIJ() . -mat_type seqdense - dense type, uses MatCreateSeqDense() . -mat_type mpidense - dense type, uses MatCreateDense() . -mat_type seqbaij - block AIJ type, uses MatCreateSeqBAIJ() - -mat_type mpibaij - block AIJ type, uses MatCreateBAIJ() Even More Options Database Keys: See the manpages for particular formats (e.g., MatCreateSeqAIJ()) for additional format-specific options. Level: beginner .keywords: matrix, create .seealso: MatCreateSeqAIJ((), MatCreateAIJ(), MatCreateSeqDense(), MatCreateDense(), MatCreateSeqBAIJ(), MatCreateBAIJ(), MatCreateSeqSBAIJ(), MatCreateSBAIJ(), MatConvert() @*/ PetscErrorCode MatSetFromOptions(Mat B) { PetscErrorCode ierr; const char *deft = MATAIJ; char type[256]; PetscBool flg,set; PetscFunctionBegin; PetscValidHeaderSpecific(B,MAT_CLASSID,1); ierr = PetscObjectOptionsBegin((PetscObject)B); CHKERRQ(ierr); if (B->rmap->bs < 0) { PetscInt newbs = -1; ierr = PetscOptionsInt("-mat_block_size","Set the blocksize used to store the matrix","MatSetBlockSize",newbs,&newbs,&flg); CHKERRQ(ierr); if (flg) { ierr = PetscLayoutSetBlockSize(B->rmap,newbs); CHKERRQ(ierr); ierr = PetscLayoutSetBlockSize(B->cmap,newbs); CHKERRQ(ierr); } } ierr = PetscOptionsList("-mat_type","Matrix type","MatSetType",MatList,deft,type,256,&flg); CHKERRQ(ierr); if (flg) { ierr = MatSetType(B,type); CHKERRQ(ierr); } else if (!((PetscObject)B)->type_name) { ierr = MatSetType(B,deft); CHKERRQ(ierr); } ierr = PetscViewerDestroy(&B->viewonassembly); CHKERRQ(ierr); ierr = PetscOptionsViewer("-mat_view","Display mat with the viewer on MatAssemblyEnd()","MatView",&B->viewonassembly,&B->viewformatonassembly,NULL); CHKERRQ(ierr); ierr = PetscOptionsName("-mat_is_symmetric","Checks if mat is symmetric on MatAssemblyEnd()","MatIsSymmetric",&B->checksymmetryonassembly); CHKERRQ(ierr); ierr = PetscOptionsReal("-mat_is_symmetric","Checks if mat is symmetric on MatAssemblyEnd()","MatIsSymmetric",0.0,&B->checksymmetrytol,NULL); CHKERRQ(ierr); ierr = PetscOptionsBool("-mat_null_space_test","Checks if provided null space is correct in MatAssemblyEnd()","MatSetNullSpaceTest",PETSC_FALSE,&B->checknullspaceonassembly,NULL); CHKERRQ(ierr); if (B->ops->setfromoptions) { ierr = (*B->ops->setfromoptions)(B); CHKERRQ(ierr); } flg = PETSC_FALSE; ierr = PetscOptionsBool("-mat_new_nonzero_location_err","Generate an error if new nonzeros are created in the matrix structure (useful to test preallocation)","MatSetOption",flg,&flg,&set); CHKERRQ(ierr); if (set) { ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,flg); CHKERRQ(ierr); } flg = PETSC_FALSE; ierr = PetscOptionsBool("-mat_new_nonzero_allocation_err","Generate an error if new nonzeros are allocated in the matrix structure (useful to test preallocation)","MatSetOption",flg,&flg,&set); CHKERRQ(ierr); if (set) { ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,flg); CHKERRQ(ierr); } /* process any options handlers added with PetscObjectAddOptionsHandler() */ ierr = PetscObjectProcessOptionsHandlers((PetscObject)B); CHKERRQ(ierr); ierr = PetscOptionsEnd(); CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options) { const char *bcTypes[2] = {"neumann", "dirichlet"}; const char *runTypes[2] = {"full", "test"}; PetscInt bc, run, n; PetscErrorCode ierr; PetscFunctionBeginUser; options->debug = 0; options->runType = RUN_FULL; options->dim = 2; options->interpolate = PETSC_FALSE; options->refinementLimit = 0.0; options->bcType = DIRICHLET; options->numBatches = 1; options->numBlocks = 1; options->jacobianMF = PETSC_FALSE; options->showInitial = PETSC_FALSE; options->showSolution = PETSC_TRUE; options->order[0] = 1; options->order[1] = 1; options->fem.quad = (PetscQuadrature*) &options->q; options->fem.f0Funcs = (void (**)(const PetscScalar[], const PetscScalar[], const PetscReal[], PetscScalar[])) &options->f0Funcs; options->fem.f1Funcs = (void (**)(const PetscScalar[], const PetscScalar[], const PetscReal[], PetscScalar[])) &options->f1Funcs; options->fem.g0Funcs = (void (**)(const PetscScalar[], const PetscScalar[], const PetscReal[], PetscScalar[])) &options->g0Funcs; options->fem.g1Funcs = (void (**)(const PetscScalar[], const PetscScalar[], const PetscReal[], PetscScalar[])) &options->g1Funcs; options->fem.g2Funcs = (void (**)(const PetscScalar[], const PetscScalar[], const PetscReal[], PetscScalar[])) &options->g2Funcs; options->fem.g3Funcs = (void (**)(const PetscScalar[], const PetscScalar[], const PetscReal[], PetscScalar[])) &options->g3Funcs; options->fem.bcFuncs = (void (**)(const PetscReal[], PetscScalar *)) &options->exactFuncs; ierr = MPI_Comm_size(comm, &options->numProcs);CHKERRQ(ierr); ierr = MPI_Comm_rank(comm, &options->rank);CHKERRQ(ierr); ierr = PetscOptionsBegin(comm, "", "Stokes Problem Options", "DMPLEX");CHKERRQ(ierr); ierr = PetscOptionsInt("-debug", "The debugging level", "ex62.c", options->debug, &options->debug, NULL);CHKERRQ(ierr); run = options->runType; ierr = PetscOptionsEList("-run_type", "The run type", "ex62.c", runTypes, 2, runTypes[options->runType], &run, NULL);CHKERRQ(ierr); options->runType = (RunType) run; ierr = PetscOptionsInt("-dim", "The topological mesh dimension", "ex62.c", options->dim, &options->dim, NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-interpolate", "Generate intermediate mesh elements", "ex62.c", options->interpolate, &options->interpolate, NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-refinement_limit", "The largest allowable cell volume", "ex62.c", options->refinementLimit, &options->refinementLimit, NULL);CHKERRQ(ierr); ierr = PetscStrcpy(options->partitioner, "chaco");CHKERRQ(ierr); ierr = PetscOptionsString("-partitioner", "The graph partitioner", "pflotran.cxx", options->partitioner, options->partitioner, 2048, NULL);CHKERRQ(ierr); bc = options->bcType; ierr = PetscOptionsEList("-bc_type","Type of boundary condition","ex62.c",bcTypes,2,bcTypes[options->bcType],&bc,NULL);CHKERRQ(ierr); options->bcType = (BCType) bc; ierr = PetscOptionsInt("-gpu_batches", "The number of cell batches per kernel", "ex62.c", options->numBatches, &options->numBatches, NULL);CHKERRQ(ierr); ierr = PetscOptionsInt("-gpu_blocks", "The number of concurrent blocks per kernel", "ex62.c", options->numBlocks, &options->numBlocks, NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-jacobian_mf", "Calculate the action of the Jacobian on the fly", "ex62.c", options->jacobianMF, &options->jacobianMF, NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-show_initial", "Output the initial guess for verification", "ex62.c", options->showInitial, &options->showInitial, NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-show_solution", "Output the solution for verification", "ex62.c", options->showSolution, &options->showSolution, NULL);CHKERRQ(ierr); n = NUM_FIELDS; ierr = PetscOptionsIntArray("-order", "The FEM order", "ex62.c", options->order, &n, NULL);CHKERRQ(ierr); ierr = PetscOptionsEnd(); ierr = PetscLogEventRegister("CreateMesh", DM_CLASSID, &options->createMeshEvent);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode MatLoad_BlockMat(Mat newmat, PetscViewer viewer) { PetscErrorCode ierr; Mat tmpA; PetscInt i,j,m,n,bs = 1,ncols,*lens,currentcol,mbs,**ii,*ilens,nextcol,*llens,cnt = 0; const PetscInt *cols; const PetscScalar *values; PetscBool flg = PETSC_FALSE,notdone; Mat_SeqAIJ *a; Mat_BlockMat *amat; PetscFunctionBegin; ierr = MatCreate(PETSC_COMM_SELF,&tmpA);CHKERRQ(ierr); ierr = MatSetType(tmpA,MATSEQAIJ);CHKERRQ(ierr); ierr = MatLoad_SeqAIJ(tmpA,viewer);CHKERRQ(ierr); ierr = MatGetLocalSize(tmpA,&m,&n);CHKERRQ(ierr); ierr = PetscOptionsBegin(PETSC_COMM_SELF,NULL,"Options for loading BlockMat matrix 1","Mat");CHKERRQ(ierr); ierr = PetscOptionsInt("-matload_block_size","Set the blocksize used to store the matrix","MatLoad",bs,&bs,NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-matload_symmetric","Store the matrix as symmetric","MatLoad",flg,&flg,NULL);CHKERRQ(ierr); ierr = PetscOptionsEnd();CHKERRQ(ierr); /* Determine number of nonzero blocks for each block row */ a = (Mat_SeqAIJ*) tmpA->data; mbs = m/bs; ierr = PetscMalloc3(mbs,&lens,bs,&ii,bs,&ilens);CHKERRQ(ierr); ierr = PetscMemzero(lens,mbs*sizeof(PetscInt));CHKERRQ(ierr); for (i=0; i<mbs; i++) { for (j=0; j<bs; j++) { ii[j] = a->j + a->i[i*bs + j]; ilens[j] = a->i[i*bs + j + 1] - a->i[i*bs + j]; } currentcol = -1; notdone = PETSC_TRUE; while (PETSC_TRUE) { notdone = PETSC_FALSE; nextcol = 1000000000; for (j=0; j<bs; j++) { while ((ilens[j] > 0 && ii[j][0]/bs <= currentcol)) { ii[j]++; ilens[j]--; } if (ilens[j] > 0) { notdone = PETSC_TRUE; nextcol = PetscMin(nextcol,ii[j][0]/bs); } } if (!notdone) break; if (!flg || (nextcol >= i)) lens[i]++; currentcol = nextcol; } } if (newmat->rmap->n < 0 && newmat->rmap->N < 0 && newmat->cmap->n < 0 && newmat->cmap->N < 0) { ierr = MatSetSizes(newmat,m,n,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); } ierr = MatBlockMatSetPreallocation(newmat,bs,0,lens);CHKERRQ(ierr); if (flg) { ierr = MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); } amat = (Mat_BlockMat*)(newmat)->data; /* preallocate the submatrices */ ierr = PetscMalloc1(bs,&llens);CHKERRQ(ierr); for (i=0; i<mbs; i++) { /* loops for block rows */ for (j=0; j<bs; j++) { ii[j] = a->j + a->i[i*bs + j]; ilens[j] = a->i[i*bs + j + 1] - a->i[i*bs + j]; } currentcol = 1000000000; for (j=0; j<bs; j++) { /* loop over rows in block finding first nonzero block */ if (ilens[j] > 0) { currentcol = PetscMin(currentcol,ii[j][0]/bs); } } notdone = PETSC_TRUE; while (PETSC_TRUE) { /* loops over blocks in block row */ notdone = PETSC_FALSE; nextcol = 1000000000; ierr = PetscMemzero(llens,bs*sizeof(PetscInt));CHKERRQ(ierr); for (j=0; j<bs; j++) { /* loop over rows in block */ while ((ilens[j] > 0 && ii[j][0]/bs <= currentcol)) { /* loop over columns in row */ ii[j]++; ilens[j]--; llens[j]++; } if (ilens[j] > 0) { notdone = PETSC_TRUE; nextcol = PetscMin(nextcol,ii[j][0]/bs); } } if (cnt >= amat->maxnz) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Number of blocks found greater than expected %D",cnt); if (!flg || currentcol >= i) { amat->j[cnt] = currentcol; ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,bs,bs,0,llens,amat->a+cnt++);CHKERRQ(ierr); } if (!notdone) break; currentcol = nextcol; } amat->ilen[i] = lens[i]; } ierr = PetscFree3(lens,ii,ilens);CHKERRQ(ierr); ierr = PetscFree(llens);CHKERRQ(ierr); /* copy over the matrix, one row at a time */ for (i=0; i<m; i++) { ierr = MatGetRow(tmpA,i,&ncols,&cols,&values);CHKERRQ(ierr); ierr = MatSetValues(newmat,1,&i,ncols,cols,values,INSERT_VALUES);CHKERRQ(ierr); ierr = MatRestoreRow(tmpA,i,&ncols,&cols,&values);CHKERRQ(ierr); } ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode EPSSetFromOptions_JD(EPS eps) { PetscErrorCode ierr; PetscBool flg,op; PetscInt opi,opi0; PetscReal opf; KSP ksp; PetscBool orth; const char *orth_list[2] = {"I","B"}; PetscFunctionBegin; ierr = PetscOptionsHead("EPS Jacobi-Davidson (JD) Options");CHKERRQ(ierr); ierr = EPSJDGetKrylovStart(eps,&op);CHKERRQ(ierr); ierr = PetscOptionsBool("-eps_jd_krylov_start","Start the searching subspace with a krylov basis","EPSJDSetKrylovStart",op,&op,&flg);CHKERRQ(ierr); if (flg) { ierr = EPSJDSetKrylovStart(eps,op);CHKERRQ(ierr); } ierr = EPSJDGetBlockSize(eps,&opi);CHKERRQ(ierr); ierr = PetscOptionsInt("-eps_jd_blocksize","Number vectors add to the searching subspace","EPSJDSetBlockSize",opi,&opi,&flg);CHKERRQ(ierr); if (flg) { ierr = EPSJDSetBlockSize(eps,opi);CHKERRQ(ierr); } ierr = EPSJDGetRestart(eps,&opi,&opi0);CHKERRQ(ierr); ierr = PetscOptionsInt("-eps_jd_minv","Set the size of the searching subspace after restarting","EPSJDSetRestart",opi,&opi,&flg);CHKERRQ(ierr); if (flg) { ierr = EPSJDSetRestart(eps,opi,opi0);CHKERRQ(ierr); } ierr = PetscOptionsInt("-eps_jd_plusk","Set the number of saved eigenvectors from the previous iteration when restarting","EPSJDSetRestart",opi0,&opi0,&flg);CHKERRQ(ierr); if (flg) { ierr = EPSJDSetRestart(eps,opi,opi0);CHKERRQ(ierr); } ierr = EPSJDGetInitialSize(eps,&opi);CHKERRQ(ierr); ierr = PetscOptionsInt("-eps_jd_initial_size","Set the initial size of the searching subspace","EPSJDSetInitialSize",opi,&opi,&flg);CHKERRQ(ierr); if (flg) { ierr = EPSJDSetInitialSize(eps,opi);CHKERRQ(ierr); } ierr = EPSJDGetFix(eps,&opf);CHKERRQ(ierr); ierr = PetscOptionsReal("-eps_jd_fix","Set the tolerance for changing the target in the correction equation","EPSJDSetFix",opf,&opf,&flg);CHKERRQ(ierr); if (flg) { ierr = EPSJDSetFix(eps,opf);CHKERRQ(ierr); } ierr = EPSJDGetBOrth(eps,&orth);CHKERRQ(ierr); ierr = PetscOptionsEList("-eps_jd_borth","orthogonalization used in the search subspace","EPSJDSetBOrth",orth_list,2,orth_list[orth?1:0],&opi,&flg);CHKERRQ(ierr); if (flg) { ierr = EPSJDSetBOrth(eps,opi==1?PETSC_TRUE:PETSC_FALSE);CHKERRQ(ierr); } ierr = EPSJDGetConstCorrectionTol(eps,&op);CHKERRQ(ierr); ierr = PetscOptionsBool("-eps_jd_const_correction_tol","Disable the dynamic stopping criterion when solving the correction equation","EPSJDSetConstCorrectionTol",op,&op,&flg);CHKERRQ(ierr); if (flg) { ierr = EPSJDSetConstCorrectionTol(eps,op);CHKERRQ(ierr); } ierr = EPSJDGetWindowSizes(eps,&opi,&opi0);CHKERRQ(ierr); ierr = PetscOptionsInt("-eps_jd_pwindow","(Experimental!) Set the number of converged vectors in the projector","EPSJDSetWindowSizes",opi,&opi,&flg);CHKERRQ(ierr); if (flg) { ierr = EPSJDSetWindowSizes(eps,opi,opi0);CHKERRQ(ierr); } ierr = PetscOptionsInt("-eps_jd_qwindow","(Experimental!) Set the number of converged vectors in the projected problem","EPSJDSetWindowSizes",opi0,&opi0,&flg);CHKERRQ(ierr); if (flg) { ierr = EPSJDSetWindowSizes(eps,opi,opi0);CHKERRQ(ierr); } /* Set STPrecond as the default ST */ if (!((PetscObject)eps->st)->type_name) { ierr = STSetType(eps->st,STPRECOND);CHKERRQ(ierr); } ierr = STPrecondSetKSPHasMat(eps->st,PETSC_FALSE);CHKERRQ(ierr); /* Set the default options of the KSP */ ierr = STGetKSP(eps->st,&ksp);CHKERRQ(ierr); if (!((PetscObject)ksp)->type_name) { ierr = KSPSetType(ksp,KSPBCGSL);CHKERRQ(ierr); ierr = KSPSetTolerances(ksp,1e-4,PETSC_DEFAULT,PETSC_DEFAULT,90);CHKERRQ(ierr); } ierr = PetscOptionsTail();CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc, char **argv) { PetscInt ierr; PetscSF sf; Vec A,Aout; PetscScalar *bufA; PetscScalar *bufAout; PetscMPIInt rank, size; PetscInt nroots, nleaves; PetscInt i; PetscInt *ilocal; PetscSFNode *iremote; PetscBool test_dupped_type; MPI_Datatype contig; ierr = PetscInitialize(&argc,&argv,NULL,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); if (size != 1) SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_USER, "Only coded for one MPI process"); ierr = PetscOptionsBegin(PETSC_COMM_WORLD,"","PetscSF type freeing options","none");CHKERRQ(ierr); test_dupped_type = PETSC_FALSE; ierr = PetscOptionsBool("-test_dupped_type", "Test dupped input type","",test_dupped_type,&test_dupped_type,NULL);CHKERRQ(ierr); ierr = PetscOptionsEnd();CHKERRQ(ierr); ierr = PetscSFCreate(PETSC_COMM_WORLD,&sf);CHKERRQ(ierr); ierr = PetscSFSetFromOptions(sf);CHKERRQ(ierr); nleaves = 1; nroots = 1; ierr = PetscMalloc1(nleaves,&ilocal);CHKERRQ(ierr); for (i = 0; i<nleaves; i++) { ilocal[i] = i; } ierr = PetscMalloc1(nleaves,&iremote);CHKERRQ(ierr); iremote[0].rank = 0; iremote[0].index = 0; ierr = PetscSFSetGraph(sf,nroots,nleaves,ilocal,PETSC_OWN_POINTER,iremote,PETSC_OWN_POINTER);CHKERRQ(ierr); ierr = PetscSFSetUp(sf);CHKERRQ(ierr); ierr = PetscSFView(sf,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = VecCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = VecSetSizes(A,4,PETSC_DETERMINE);CHKERRQ(ierr); ierr = VecSetFromOptions(A);CHKERRQ(ierr); ierr = VecSetUp(A);CHKERRQ(ierr); ierr = VecDuplicate(A,&Aout);CHKERRQ(ierr); ierr = VecGetArray(A,&bufA);CHKERRQ(ierr); for (i=0; i<4; i++) { bufA[i] = (PetscScalar)i; } ierr = VecRestoreArray(A,&bufA);CHKERRQ(ierr); ierr = VecGetArrayRead(A,(const PetscScalar**)&bufA);CHKERRQ(ierr); ierr = VecGetArray(Aout,&bufAout);CHKERRQ(ierr); ierr = MPI_Type_contiguous(4, MPIU_SCALAR, &contig);CHKERRQ(ierr); ierr = MPI_Type_commit(&contig);CHKERRQ(ierr); if (test_dupped_type) { MPI_Datatype tmp; ierr = MPI_Type_dup(contig, &tmp);CHKERRQ(ierr); ierr = MPI_Type_free(&contig);CHKERRQ(ierr); contig = tmp; } for (i=0;i<10000;i++) { ierr = PetscSFBcastBegin(sf,contig,bufA,bufAout);CHKERRQ(ierr); ierr = PetscSFBcastEnd(sf,contig,bufA,bufAout);CHKERRQ(ierr); } ierr = VecRestoreArrayRead(A,(const PetscScalar**)&bufA);CHKERRQ(ierr); ierr = VecRestoreArray(Aout,&bufAout);CHKERRQ(ierr); ierr = VecView(Aout,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = VecDestroy(&A);CHKERRQ(ierr); ierr = VecDestroy(&Aout);CHKERRQ(ierr); ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); ierr = MPI_Type_free(&contig);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
int main(int argc,char *argv[]) { char mat_type[256] = "aij"; /* default matrix type */ PetscErrorCode ierr; MPI_Comm comm; PetscMPIInt rank,size; DM slice; PetscInt i,bs=1,N=5,n,m,rstart,ghosts[2],*d_nnz,*o_nnz,dfill[4]={1,0,0,1},ofill[4]={1,1,1,1}; PetscReal alpha =1,K=1,rho0=1,u0=0,sigma=0.2; PetscBool useblock=PETSC_TRUE; PetscScalar *xx; Mat A; Vec x,b,lf; ierr = PetscInitialize(&argc,&argv,0,help);CHKERRQ(ierr); comm = PETSC_COMM_WORLD; ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); ierr = PetscOptionsBegin(comm,0,"Options for DMSliced test",0);CHKERRQ(ierr); { ierr = PetscOptionsInt("-n","Global number of nodes","",N,&N,NULL);CHKERRQ(ierr); ierr = PetscOptionsInt("-bs","Block size (1 or 2)","",bs,&bs,NULL);CHKERRQ(ierr); if (bs != 1) { if (bs != 2) SETERRQ(PETSC_COMM_WORLD,1,"Block size must be 1 or 2"); ierr = PetscOptionsReal("-alpha","Inverse time step for wave operator","",alpha,&alpha,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-K","Bulk modulus of compressibility","",K,&K,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-rho0","Reference density","",rho0,&rho0,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-u0","Reference velocity","",u0,&u0,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-sigma","Width of Gaussian density perturbation","",sigma,&sigma,NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-block","Use block matrix assembly","",useblock,&useblock,NULL);CHKERRQ(ierr); } ierr = PetscOptionsString("-sliced_mat_type","Matrix type to use (aij or baij)","",mat_type,mat_type,sizeof(mat_type),NULL);CHKERRQ(ierr); } ierr = PetscOptionsEnd();CHKERRQ(ierr); /* Split ownership, set up periodic grid in 1D */ n = PETSC_DECIDE; ierr = PetscSplitOwnership(comm,&n,&N);CHKERRQ(ierr); rstart = 0; ierr = MPI_Scan(&n,&rstart,1,MPIU_INT,MPI_SUM,comm);CHKERRQ(ierr); rstart -= n; ghosts[0] = (N+rstart-1)%N; ghosts[1] = (rstart+n)%N; ierr = PetscMalloc2(n,PetscInt,&d_nnz,n,PetscInt,&o_nnz);CHKERRQ(ierr); for (i=0; i<n; i++) { if (size > 1 && (i==0 || i==n-1)) { d_nnz[i] = 2; o_nnz[i] = 1; } else { d_nnz[i] = 3; o_nnz[i] = 0; } } ierr = DMSlicedCreate(comm,bs,n,2,ghosts,d_nnz,o_nnz,&slice);CHKERRQ(ierr); /* Currently does not copy X_nnz so we can't free them until after DMSlicedGetMatrix */ if (!useblock) {ierr = DMSlicedSetBlockFills(slice,dfill,ofill);CHKERRQ(ierr);} /* Irrelevant for baij formats */ ierr = DMSetMatType(slice,mat_type);CHKERRQ(ierr); ierr = DMCreateMatrix(slice,&A);CHKERRQ(ierr); ierr = PetscFree2(d_nnz,o_nnz);CHKERRQ(ierr); ierr = MatSetOption(A,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); ierr = DMCreateGlobalVector(slice,&x);CHKERRQ(ierr); ierr = VecDuplicate(x,&b);CHKERRQ(ierr); ierr = VecGhostGetLocalForm(x,&lf);CHKERRQ(ierr); ierr = VecGetSize(lf,&m);CHKERRQ(ierr); if (m != (n+2)*bs) SETERRQ2(PETSC_COMM_SELF,1,"size of local form %D, expected %D",m,(n+2)*bs); ierr = VecGetArray(lf,&xx);CHKERRQ(ierr); for (i=0; i<n; i++) { PetscInt row[2],col[9],im,ip; PetscScalar v[12]; const PetscReal xref = 2.0*(rstart+i)/N - 1; /* [-1,1] */ const PetscReal h = 1.0/N; /* grid spacing */ im = (i==0) ? n : i-1; ip = (i==n-1) ? n+1 : i+1; switch (bs) { case 1: /* Laplacian with periodic boundaries */ col[0] = im; col[1] = i; col[2] = ip; v[0] = -h; v[1] = 2*h; v[2] = -h; ierr = MatSetValuesLocal(A,1,&i,3,col,v,INSERT_VALUES);CHKERRQ(ierr); xx[i] = sin(xref*PETSC_PI); break; case 2: /* Linear acoustic wave operator in variables [rho, u], central differences, periodic, timestep 1/alpha */ v[0] = -0.5*u0; v[1] = -0.5*K; v[2] = alpha; v[3] = 0; v[4] = 0.5*u0; v[5] = 0.5*K; v[6] = -0.5/rho0; v[7] = -0.5*u0; v[8] = 0; v[9] = alpha; v[10] = 0.5/rho0; v[11] = 0.5*u0; if (useblock) { row[0] = i; col[0] = im; col[1] = i; col[2] = ip; ierr = MatSetValuesBlockedLocal(A,1,row,3,col,v,INSERT_VALUES);CHKERRQ(ierr); } else { row[0] = 2*i; row[1] = 2*i+1; col[0] = 2*im; col[1] = 2*im+1; col[2] = 2*i; col[3] = 2*ip; col[4] = 2*ip+1; v[3] = v[4]; v[4] = v[5]; /* pack values in first row */ ierr = MatSetValuesLocal(A,1,row,5,col,v,INSERT_VALUES);CHKERRQ(ierr); col[2] = 2*i+1; v[8] = v[9]; v[9] = v[10]; v[10] = v[11]; /* pack values in second row */ ierr = MatSetValuesLocal(A,1,row+1,5,col,v+6,INSERT_VALUES);CHKERRQ(ierr); } /* Set current state (gaussian density perturbation) */ xx[2*i] = 0.2*exp(-PetscSqr(xref)/(2*PetscSqr(sigma))); xx[2*i+1] = 0; break; default: SETERRQ1(PETSC_COMM_SELF,1,"not implemented for block size %D",bs); } } ierr = VecRestoreArray(lf,&xx);CHKERRQ(ierr); ierr = VecGhostRestoreLocalForm(x,&lf);CHKERRQ(ierr); ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatMult(A,x,b);CHKERRQ(ierr); ierr = MatView(A,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = VecView(x,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = VecView(b,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); /* Update the ghosted values, view the result on rank 0. */ ierr = VecGhostUpdateBegin(b,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecGhostUpdateEnd(b,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); if (!rank) { ierr = VecGhostGetLocalForm(b,&lf);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_SELF,"Local form of b on rank 0, last two nodes are ghost nodes\n");CHKERRQ(ierr); ierr = VecView(lf,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); ierr = VecGhostRestoreLocalForm(b,&lf);CHKERRQ(ierr); } ierr = DMDestroy(&slice);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
PETSC_EXTERN PetscErrorCode PetscThreadCommCreate_PThread(PetscThreadComm tcomm) { PetscThreadComm_PThread ptcomm; PetscErrorCode ierr; PetscInt i; PetscFunctionBegin; ptcommcrtct++; ierr = PetscStrcpy(tcomm->type,PTHREAD);CHKERRQ(ierr); ierr = PetscNew(&ptcomm);CHKERRQ(ierr); tcomm->data = (void*)ptcomm; ptcomm->nthreads = 0; ptcomm->sync = PTHREADSYNC_LOCKFREE; ptcomm->aff = PTHREADAFFPOLICY_ONECORE; ptcomm->spark = PTHREADPOOLSPARK_SELF; ptcomm->ismainworker = PETSC_TRUE; ptcomm->synchronizeafter = PETSC_TRUE; tcomm->ops->destroy = PetscThreadCommDestroy_PThread; tcomm->ops->runkernel = PetscThreadCommRunKernel_PThread_LockFree; tcomm->ops->barrier = PetscThreadCommBarrier_PThread_LockFree; tcomm->ops->getrank = PetscThreadCommGetRank_PThread; ierr = PetscMalloc1(tcomm->nworkThreads,&ptcomm->granks);CHKERRQ(ierr); if (!PetscPThreadCommInitializeCalled) { /* Only done for PETSC_THREAD_COMM_WORLD */ PetscBool flg1,flg2,flg3,flg4; PetscPThreadCommInitializeCalled = PETSC_TRUE; ierr = PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"PThread communicator options",NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-threadcomm_pthread_main_is_worker","Main thread is also a worker thread",NULL,PETSC_TRUE,&ptcomm->ismainworker,&flg1);CHKERRQ(ierr); ierr = PetscOptionsEnum("-threadcomm_pthread_affpolicy","Thread affinity policy"," ",PetscPThreadCommAffinityPolicyTypes,(PetscEnum)ptcomm->aff,(PetscEnum*)&ptcomm->aff,&flg2);CHKERRQ(ierr); ierr = PetscOptionsEnum("-threadcomm_pthread_type","Thread pool type"," ",PetscPThreadCommSynchronizationTypes,(PetscEnum)ptcomm->sync,(PetscEnum*)&ptcomm->sync,&flg3);CHKERRQ(ierr); ierr = PetscOptionsEnum("-threadcomm_pthread_spark","Thread pool spark type"," ",PetscPThreadCommPoolSparkTypes,(PetscEnum)ptcomm->spark,(PetscEnum*)&ptcomm->spark,&flg4);CHKERRQ(ierr); ierr = PetscOptionsBool("-threadcomm_pthread_synchronizeafter","Puts a barrier after every kernel call",NULL,PETSC_TRUE,&ptcomm->synchronizeafter,&flg1);CHKERRQ(ierr); ierr = PetscOptionsEnd();CHKERRQ(ierr); if (ptcomm->ismainworker) { ptcomm->nthreads = tcomm->nworkThreads-1; ptcomm->thread_num_start = 1; } else { ptcomm->nthreads = tcomm->nworkThreads; ptcomm->thread_num_start = 0; } switch (ptcomm->sync) { case PTHREADSYNC_LOCKFREE: ptcomm->initialize = PetscPThreadCommInitialize_LockFree; ptcomm->finalize = PetscPThreadCommFinalize_LockFree; tcomm->ops->runkernel = PetscThreadCommRunKernel_PThread_LockFree; tcomm->ops->barrier = PetscThreadCommBarrier_PThread_LockFree; break; default: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only Lock-free synchronization scheme supported currently"); } /* Set up thread ranks */ for (i=0; i< tcomm->nworkThreads; i++) ptcomm->granks[i] = i; if (ptcomm->ismainworker) { #if defined(PETSC_PTHREAD_LOCAL) PetscPThreadRank=0; /* Main thread rank */ #else ierr = pthread_key_create(&PetscPThreadRankkey,NULL);CHKERRQ(ierr); ierr = pthread_setspecific(PetscPThreadRankkey,&ptcomm->granks[0]);CHKERRQ(ierr); #endif } /* Set the leader thread rank */ if (ptcomm->nthreads) { if (ptcomm->ismainworker) tcomm->leader = ptcomm->granks[1]; else tcomm->leader = ptcomm->granks[0]; } /* Create array holding pthread ids */ ierr = PetscMalloc1(tcomm->nworkThreads,&ptcomm->tid);CHKERRQ(ierr); /* Create thread attributes */ ierr = PetscMalloc1(tcomm->nworkThreads,&ptcomm->attr);CHKERRQ(ierr); ierr = PetscThreadCommSetPThreadAttributes(tcomm);CHKERRQ(ierr); if (ptcomm->ismainworker) { /* Pin main thread */ #if defined(PETSC_HAVE_SCHED_CPU_SET_T) cpu_set_t mset; PetscInt ncores,icorr; ierr = PetscGetNCores(&ncores);CHKERRQ(ierr); CPU_ZERO(&mset); icorr = tcomm->affinities[0]%ncores; CPU_SET(icorr,&mset); sched_setaffinity(0,sizeof(cpu_set_t),&mset); #endif } /* Initialize thread pool */ ierr = (*ptcomm->initialize)(tcomm);CHKERRQ(ierr); } else { PetscThreadComm gtcomm; PetscThreadComm_PThread gptcomm; PetscInt *granks,j,*gaffinities; ierr = PetscCommGetThreadComm(PETSC_COMM_WORLD,>comm);CHKERRQ(ierr); gaffinities = gtcomm->affinities; gptcomm = (PetscThreadComm_PThread)tcomm->data; granks = gptcomm->granks; /* Copy over the data from the global thread communicator structure */ ptcomm->ismainworker = gptcomm->ismainworker; ptcomm->thread_num_start = gptcomm->thread_num_start; ptcomm->sync = gptcomm->sync; ptcomm->aff = gptcomm->aff; tcomm->ops->runkernel = gtcomm->ops->runkernel; tcomm->ops->barrier = gtcomm->ops->barrier; for (i=0; i < tcomm->nworkThreads; i++) { for (j=0; j < gtcomm->nworkThreads; j++) { if (tcomm->affinities[i] == gaffinities[j]) ptcomm->granks[i] = granks[j]; } } } PetscFunctionReturn(0); }
/*@ NEPSetFromOptions - Sets NEP options from the options database. This routine must be called before NEPSetUp() if the user is to be allowed to set the solver type. Collective on NEP Input Parameters: . nep - the nonlinear eigensolver context Notes: To see all options, run your program with the -help option. Level: beginner @*/ PetscErrorCode NEPSetFromOptions(NEP nep) { PetscErrorCode ierr; char type[256],monfilename[PETSC_MAX_PATH_LEN]; PetscBool flg,flg1,flg2,flg3,flg4,flg5; PetscReal r1,r2,r3; PetscScalar s; PetscInt i,j,k; PetscViewer monviewer; SlepcConvMonitor ctx; PetscFunctionBegin; PetscValidHeaderSpecific(nep,NEP_CLASSID,1); if (!NEPRegisterAllCalled) { ierr = NEPRegisterAll();CHKERRQ(ierr); } ierr = PetscObjectOptionsBegin((PetscObject)nep);CHKERRQ(ierr); ierr = PetscOptionsFList("-nep_type","Nonlinear Eigenvalue Problem method","NEPSetType",NEPList,(char*)(((PetscObject)nep)->type_name?((PetscObject)nep)->type_name:NEPRII),type,256,&flg);CHKERRQ(ierr); if (flg) { ierr = NEPSetType(nep,type);CHKERRQ(ierr); } else if (!((PetscObject)nep)->type_name) { ierr = NEPSetType(nep,NEPRII);CHKERRQ(ierr); } ierr = PetscOptionsEnum("-nep_refine","Iterative refinement method","NEPSetRefine",NEPRefineTypes,(PetscEnum)nep->refine,(PetscEnum*)&nep->refine,NULL);CHKERRQ(ierr); r1 = nep->reftol; ierr = PetscOptionsReal("-nep_refine_tol","Tolerance for iterative refinement","NEPSetRefine",nep->reftol,&r1,&flg1);CHKERRQ(ierr); j = nep->rits; ierr = PetscOptionsInt("-nep_refine_its","Maximum number of iterations for iterative refinement","NEPSetRefine",nep->rits,&j,&flg2);CHKERRQ(ierr); if (flg1 || flg2) { ierr = NEPSetRefine(nep,nep->refine,r1,j);CHKERRQ(ierr); } i = nep->max_it? nep->max_it: PETSC_DEFAULT; ierr = PetscOptionsInt("-nep_max_it","Maximum number of iterations","NEPSetTolerances",nep->max_it,&i,&flg1);CHKERRQ(ierr); j = nep->max_funcs? nep->max_funcs: PETSC_DEFAULT; ierr = PetscOptionsInt("-nep_max_funcs","Maximum number of function evaluations","NEPSetTolerances",nep->max_funcs,&j,&flg2);CHKERRQ(ierr); r1 = nep->abstol; ierr = PetscOptionsReal("-nep_atol","Absolute tolerance for residual norm","NEPSetTolerances",nep->abstol==PETSC_DEFAULT?SLEPC_DEFAULT_TOL:nep->abstol,&r1,&flg3);CHKERRQ(ierr); r2 = nep->rtol; ierr = PetscOptionsReal("-nep_rtol","Relative tolerance for residual norm","NEPSetTolerances",nep->rtol==PETSC_DEFAULT?SLEPC_DEFAULT_TOL:nep->rtol,&r2,&flg4);CHKERRQ(ierr); r3 = nep->stol; ierr = PetscOptionsReal("-nep_stol","Relative tolerance for step length","NEPSetTolerances",nep->stol==PETSC_DEFAULT?SLEPC_DEFAULT_TOL:nep->stol,&r3,&flg5);CHKERRQ(ierr); if (flg1 || flg2 || flg3 || flg4 || flg5) { ierr = NEPSetTolerances(nep,r1,r2,r3,i,j);CHKERRQ(ierr); } flg = PETSC_FALSE; ierr = PetscOptionsBool("-nep_convergence_default","Default (relative error) convergence test","NEPSetConvergenceTest",flg,&flg,NULL);CHKERRQ(ierr); if (flg) { ierr = NEPSetConvergenceTest(nep,NEPConvergedDefault,NULL,NULL);CHKERRQ(ierr); } i = nep->nev; ierr = PetscOptionsInt("-nep_nev","Number of eigenvalues to compute","NEPSetDimensions",nep->nev,&i,&flg1);CHKERRQ(ierr); j = nep->ncv? nep->ncv: PETSC_DEFAULT; ierr = PetscOptionsInt("-nep_ncv","Number of basis vectors","NEPSetDimensions",nep->ncv,&j,&flg2);CHKERRQ(ierr); k = nep->mpd? nep->mpd: PETSC_DEFAULT; ierr = PetscOptionsInt("-nep_mpd","Maximum dimension of projected problem","NEPSetDimensions",nep->mpd,&k,&flg3);CHKERRQ(ierr); if (flg1 || flg2 || flg3) { ierr = NEPSetDimensions(nep,i,j,k);CHKERRQ(ierr); } i = 0; ierr = PetscOptionsInt("-nep_lag_preconditioner","Interval to rebuild preconditioner","NEPSetLagPreconditioner",nep->lag,&i,&flg);CHKERRQ(ierr); if (flg) { ierr = NEPSetLagPreconditioner(nep,i);CHKERRQ(ierr); } ierr = PetscOptionsBool("-nep_const_correction_tol","Constant correction tolerance for the linear solver","NEPSetConstCorrectionTol",nep->cctol,&nep->cctol,NULL);CHKERRQ(ierr); ierr = PetscOptionsScalar("-nep_target","Value of the target","NEPSetTarget",nep->target,&s,&flg);CHKERRQ(ierr); if (flg) { ierr = NEPSetWhichEigenpairs(nep,NEP_TARGET_MAGNITUDE);CHKERRQ(ierr); ierr = NEPSetTarget(nep,s);CHKERRQ(ierr); } /* -----------------------------------------------------------------------*/ /* Cancels all monitors hardwired into code before call to NEPSetFromOptions() */ flg = PETSC_FALSE; ierr = PetscOptionsBool("-nep_monitor_cancel","Remove any hardwired monitor routines","NEPMonitorCancel",flg,&flg,NULL);CHKERRQ(ierr); if (flg) { ierr = NEPMonitorCancel(nep);CHKERRQ(ierr); } /* Prints approximate eigenvalues and error estimates at each iteration */ ierr = PetscOptionsString("-nep_monitor","Monitor first unconverged approximate eigenvalue and error estimate","NEPMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); if (flg) { ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)nep),monfilename,&monviewer);CHKERRQ(ierr); ierr = NEPMonitorSet(nep,NEPMonitorFirst,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); } ierr = PetscOptionsString("-nep_monitor_conv","Monitor approximate eigenvalues and error estimates as they converge","NEPMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); if (flg) { ierr = PetscNew(&ctx);CHKERRQ(ierr); ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)nep),monfilename,&ctx->viewer);CHKERRQ(ierr); ierr = NEPMonitorSet(nep,NEPMonitorConverged,ctx,(PetscErrorCode (*)(void**))SlepcConvMonitorDestroy);CHKERRQ(ierr); } ierr = PetscOptionsString("-nep_monitor_all","Monitor approximate eigenvalues and error estimates","NEPMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); if (flg) { ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)nep),monfilename,&monviewer);CHKERRQ(ierr); ierr = NEPMonitorSet(nep,NEPMonitorAll,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); ierr = NEPSetTrackAll(nep,PETSC_TRUE);CHKERRQ(ierr); } flg = PETSC_FALSE; ierr = PetscOptionsBool("-nep_monitor_lg","Monitor first unconverged approximate error estimate graphically","NEPMonitorSet",flg,&flg,NULL);CHKERRQ(ierr); if (flg) { ierr = NEPMonitorSet(nep,NEPMonitorLG,NULL,NULL);CHKERRQ(ierr); } flg = PETSC_FALSE; ierr = PetscOptionsBool("-nep_monitor_lg_all","Monitor error estimates graphically","NEPMonitorSet",flg,&flg,NULL);CHKERRQ(ierr); if (flg) { ierr = NEPMonitorSet(nep,NEPMonitorLGAll,NULL,NULL);CHKERRQ(ierr); ierr = NEPSetTrackAll(nep,PETSC_TRUE);CHKERRQ(ierr); } /* -----------------------------------------------------------------------*/ ierr = PetscOptionsBoolGroupBegin("-nep_largest_magnitude","compute largest eigenvalues in magnitude","NEPSetWhichEigenpairs",&flg);CHKERRQ(ierr); if (flg) { ierr = NEPSetWhichEigenpairs(nep,NEP_LARGEST_MAGNITUDE);CHKERRQ(ierr); } ierr = PetscOptionsBoolGroup("-nep_smallest_magnitude","compute smallest eigenvalues in magnitude","NEPSetWhichEigenpairs",&flg);CHKERRQ(ierr); if (flg) { ierr = NEPSetWhichEigenpairs(nep,NEP_SMALLEST_MAGNITUDE);CHKERRQ(ierr); } ierr = PetscOptionsBoolGroup("-nep_largest_real","compute largest real parts","NEPSetWhichEigenpairs",&flg);CHKERRQ(ierr); if (flg) { ierr = NEPSetWhichEigenpairs(nep,NEP_LARGEST_REAL);CHKERRQ(ierr); } ierr = PetscOptionsBoolGroup("-nep_smallest_real","compute smallest real parts","NEPSetWhichEigenpairs",&flg);CHKERRQ(ierr); if (flg) { ierr = NEPSetWhichEigenpairs(nep,NEP_SMALLEST_REAL);CHKERRQ(ierr); } ierr = PetscOptionsBoolGroup("-nep_largest_imaginary","compute largest imaginary parts","NEPSetWhichEigenpairs",&flg);CHKERRQ(ierr); if (flg) { ierr = NEPSetWhichEigenpairs(nep,NEP_LARGEST_IMAGINARY);CHKERRQ(ierr); } ierr = PetscOptionsBoolGroup("-nep_smallest_imaginary","compute smallest imaginary parts","NEPSetWhichEigenpairs",&flg);CHKERRQ(ierr); if (flg) { ierr = NEPSetWhichEigenpairs(nep,NEP_SMALLEST_IMAGINARY);CHKERRQ(ierr); } ierr = PetscOptionsBoolGroup("-nep_target_magnitude","compute nearest eigenvalues to target","NEPSetWhichEigenpairs",&flg);CHKERRQ(ierr); if (flg) { ierr = NEPSetWhichEigenpairs(nep,NEP_TARGET_MAGNITUDE);CHKERRQ(ierr); } ierr = PetscOptionsBoolGroup("-nep_target_real","compute eigenvalues with real parts close to target","NEPSetWhichEigenpairs",&flg);CHKERRQ(ierr); if (flg) { ierr = NEPSetWhichEigenpairs(nep,NEP_TARGET_REAL);CHKERRQ(ierr); } ierr = PetscOptionsBoolGroupEnd("-nep_target_imaginary","compute eigenvalues with imaginary parts close to target","NEPSetWhichEigenpairs",&flg);CHKERRQ(ierr); if (flg) { ierr = NEPSetWhichEigenpairs(nep,NEP_TARGET_IMAGINARY);CHKERRQ(ierr); } ierr = PetscOptionsName("-nep_view","Print detailed information on solver used","NEPView",0);CHKERRQ(ierr); ierr = PetscOptionsName("-nep_plot_eigs","Make a plot of the computed eigenvalues","NEPSolve",0);CHKERRQ(ierr); if (nep->ops->setfromoptions) { ierr = (*nep->ops->setfromoptions)(nep);CHKERRQ(ierr); } ierr = PetscObjectProcessOptionsHandlers((PetscObject)nep);CHKERRQ(ierr); ierr = PetscOptionsEnd();CHKERRQ(ierr); if (!nep->V) { ierr = NEPGetBV(nep,&nep->V);CHKERRQ(ierr); } ierr = BVSetFromOptions(nep->V);CHKERRQ(ierr); if (!nep->rg) { ierr = NEPGetRG(nep,&nep->rg);CHKERRQ(ierr); } ierr = RGSetFromOptions(nep->rg);CHKERRQ(ierr); if (!nep->ds) { ierr = NEPGetDS(nep,&nep->ds);CHKERRQ(ierr); } ierr = DSSetFromOptions(nep->ds);CHKERRQ(ierr); if (!nep->ksp) { ierr = NEPGetKSP(nep,&nep->ksp);CHKERRQ(ierr); } ierr = KSPSetOperators(nep->ksp,nep->function,nep->function_pre);CHKERRQ(ierr); ierr = KSPSetFromOptions(nep->ksp);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(nep->rand);CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc,char **argv) { TS ts; /* ODE integrator */ Vec U; /* solution will be stored here */ Mat A; /* Jacobian matrix */ PetscErrorCode ierr; PetscMPIInt size; PetscInt n = 2; AppCtx ctx; PetscScalar *u; PetscReal du[2] = {0.0,0.0}; PetscBool ensemble = PETSC_FALSE,flg1,flg2; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Initialize program - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = PetscInitialize(&argc,&argv,(char*)0,help);CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); if (size > 1) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"Only for sequential runs"); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create necessary matrix and vectors - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatSetSizes(A,n,n,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); ierr = MatSetType(A,MATDENSE);CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr); ierr = MatSetUp(A);CHKERRQ(ierr); ierr = MatCreateVecs(A,&U,NULL);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"Swing equation options","");CHKERRQ(ierr); { ctx.omega_s = 2.0*PETSC_PI*60.0; ctx.H = 5.0; ierr = PetscOptionsScalar("-Inertia","","",ctx.H,&ctx.H,NULL);CHKERRQ(ierr); ctx.D = 5.0; ierr = PetscOptionsScalar("-D","","",ctx.D,&ctx.D,NULL);CHKERRQ(ierr); ctx.E = 1.1378; ctx.V = 1.0; ctx.X = 0.545; ctx.Pmax = ctx.E*ctx.V/ctx.X;; ierr = PetscOptionsScalar("-Pmax","","",ctx.Pmax,&ctx.Pmax,NULL);CHKERRQ(ierr); ctx.Pm = 0.9; ierr = PetscOptionsScalar("-Pm","","",ctx.Pm,&ctx.Pm,NULL);CHKERRQ(ierr); ctx.tf = 1.0; ctx.tcl = 1.05; ierr = PetscOptionsReal("-tf","Time to start fault","",ctx.tf,&ctx.tf,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-tcl","Time to end fault","",ctx.tcl,&ctx.tcl,NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-ensemble","Run ensemble of different initial conditions","",ensemble,&ensemble,NULL);CHKERRQ(ierr); if (ensemble) { ctx.tf = -1; ctx.tcl = -1; } ierr = VecGetArray(U,&u);CHKERRQ(ierr); u[0] = PetscAsinScalar(ctx.Pm/ctx.Pmax); u[1] = 1.0; ierr = PetscOptionsRealArray("-u","Initial solution","",u,&n,&flg1);CHKERRQ(ierr); n = 2; ierr = PetscOptionsRealArray("-du","Perturbation in initial solution","",du,&n,&flg2);CHKERRQ(ierr); u[0] += du[0]; u[1] += du[1]; ierr = VecRestoreArray(U,&u);CHKERRQ(ierr); if (flg1 || flg2) { ctx.tf = -1; ctx.tcl = -1; } } ierr = PetscOptionsEnd();CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create timestepping solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetProblemType(ts,TS_NONLINEAR);CHKERRQ(ierr); ierr = TSSetType(ts,TSROSW);CHKERRQ(ierr); ierr = TSSetIFunction(ts,NULL,(TSIFunction) IFunction,&ctx);CHKERRQ(ierr); ierr = TSSetIJacobian(ts,A,A,(TSIJacobian)IJacobian,&ctx);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set initial conditions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetSolution(ts,U);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set solver options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetDuration(ts,100000,35.0);CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts,0.0,.01);CHKERRQ(ierr); ierr = TSSetFromOptions(ts);CHKERRQ(ierr); /* ierr = TSSetPostStep(ts,PostStep);CHKERRQ(ierr); */ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ if (ensemble) { for (du[1] = -2.5; du[1] <= .01; du[1] += .1) { ierr = VecGetArray(U,&u);CHKERRQ(ierr); u[0] = PetscAsinScalar(ctx.Pm/ctx.Pmax); u[1] = ctx.omega_s; u[0] += du[0]; u[1] += du[1]; ierr = VecRestoreArray(U,&u);CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts,0.0,.01);CHKERRQ(ierr); ierr = TSSolve(ts,U);CHKERRQ(ierr); } } else { ierr = TSSolve(ts,U);CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. All PETSc objects should be destroyed when they are no longer needed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = VecDestroy(&U);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = PetscFinalize(); return(0); }
PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options) { const char *dShapes[2] = {"box", "cylinder"}; PetscInt shape, bd, n; static PetscInt domainBoxSizes[3] = {1,1,1}; static PetscReal domainBoxL[3] = {0.,0.,0.}; static PetscReal domainBoxU[3] = {1.,1.,1.}; PetscBool flg; PetscErrorCode ierr; PetscFunctionBegin; options->debug = 0; options->dim = 2; options->interpolate = PETSC_FALSE; options->refinementLimit = 0.0; options->cellSimplex = PETSC_TRUE; options->cellWedge = PETSC_FALSE; options->domainShape = BOX; options->domainBoxSizes = NULL; options->domainBoxL = NULL; options->domainBoxU = NULL; options->periodicity[0] = DM_BOUNDARY_NONE; options->periodicity[1] = DM_BOUNDARY_NONE; options->periodicity[2] = DM_BOUNDARY_NONE; options->filename[0] = '\0'; options->bdfilename[0] = '\0'; options->extfilename[0] = '\0'; options->testPartition = PETSC_FALSE; options->overlap = PETSC_FALSE; options->testShape = PETSC_FALSE; options->simplex2tensor = PETSC_FALSE; options->extrude_layers = 2; options->extrude_thickness = 0.1; options->testp4est[0] = PETSC_FALSE; options->testp4est[1] = PETSC_FALSE; ierr = PetscOptionsBegin(comm, "", "Meshing Problem Options", "DMPLEX");CHKERRQ(ierr); ierr = PetscOptionsInt("-debug", "The debugging level", "ex1.c", options->debug, &options->debug, NULL);CHKERRQ(ierr); ierr = PetscOptionsInt("-dim", "The topological mesh dimension", "ex1.c", options->dim, &options->dim, NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-interpolate", "Generate intermediate mesh elements", "ex1.c", options->interpolate, &options->interpolate, NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-refinement_limit", "The largest allowable cell volume", "ex1.c", options->refinementLimit, &options->refinementLimit, NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-cell_simplex", "Use simplices if true, otherwise hexes", "ex1.c", options->cellSimplex, &options->cellSimplex, NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-cell_wedge", "Use wedges if true", "ex1.c", options->cellWedge, &options->cellWedge, NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-simplex2tensor", "Refine simplicial cells in tensor product cells", "ex1.c", options->simplex2tensor, &options->simplex2tensor, NULL);CHKERRQ(ierr); if (options->simplex2tensor) options->interpolate = PETSC_TRUE; shape = options->domainShape; ierr = PetscOptionsEList("-domain_shape","The shape of the domain","ex1.c", dShapes, 2, dShapes[options->domainShape], &shape, NULL);CHKERRQ(ierr); options->domainShape = (DomainShape) shape; ierr = PetscOptionsIntArray("-domain_box_sizes","The sizes of the box domain","ex1.c", domainBoxSizes, (n=3,&n), &flg);CHKERRQ(ierr); if (flg) { options->domainShape = BOX; options->domainBoxSizes = domainBoxSizes;} ierr = PetscOptionsRealArray("-domain_box_ll","Coordinates of the lower left corner of the box domain","ex1.c", domainBoxL, (n=3,&n), &flg);CHKERRQ(ierr); if (flg) { options->domainBoxL = domainBoxL;} ierr = PetscOptionsRealArray("-domain_box_ur","Coordinates of the upper right corner of the box domain","ex1.c", domainBoxU, (n=3,&n), &flg);CHKERRQ(ierr); if (flg) { options->domainBoxU = domainBoxU;} bd = options->periodicity[0]; ierr = PetscOptionsEList("-x_periodicity", "The x-boundary periodicity", "ex1.c", DMBoundaryTypes, 5, DMBoundaryTypes[options->periodicity[0]], &bd, NULL);CHKERRQ(ierr); options->periodicity[0] = (DMBoundaryType) bd; bd = options->periodicity[1]; ierr = PetscOptionsEList("-y_periodicity", "The y-boundary periodicity", "ex1.c", DMBoundaryTypes, 5, DMBoundaryTypes[options->periodicity[1]], &bd, NULL);CHKERRQ(ierr); options->periodicity[1] = (DMBoundaryType) bd; bd = options->periodicity[2]; ierr = PetscOptionsEList("-z_periodicity", "The z-boundary periodicity", "ex1.c", DMBoundaryTypes, 5, DMBoundaryTypes[options->periodicity[2]], &bd, NULL);CHKERRQ(ierr); options->periodicity[2] = (DMBoundaryType) bd; ierr = PetscOptionsString("-filename", "The mesh file", "ex1.c", options->filename, options->filename, PETSC_MAX_PATH_LEN, NULL);CHKERRQ(ierr); ierr = PetscOptionsString("-bd_filename", "The mesh boundary file", "ex1.c", options->bdfilename, options->bdfilename, PETSC_MAX_PATH_LEN, NULL);CHKERRQ(ierr); ierr = PetscOptionsString("-ext_filename", "The 2D mesh file to be extruded", "ex1.c", options->extfilename, options->extfilename, PETSC_MAX_PATH_LEN, NULL);CHKERRQ(ierr); ierr = PetscOptionsInt("-ext_layers", "The number of layers to extrude", "ex1.c", options->extrude_layers, &options->extrude_layers, NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-ext_thickness", "The thickness of the layer to be extruded", "ex1.c", options->extrude_thickness, &options->extrude_thickness, NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-test_partition", "Use a fixed partition for testing", "ex1.c", options->testPartition, &options->testPartition, NULL);CHKERRQ(ierr); ierr = PetscOptionsInt("-overlap", "The cell overlap for partitioning", "ex1.c", options->overlap, &options->overlap, NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-test_shape", "Report cell shape qualities (Jacobian condition numbers)", "ex1.c", options->testShape, &options->testShape, NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-test_p4est_seq", "Test p4est with sequential base DM", "ex1.c", options->testp4est[0], &options->testp4est[0], NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-test_p4est_par", "Test p4est with parallel base DM", "ex1.c", options->testp4est[1], &options->testp4est[1], NULL);CHKERRQ(ierr); ierr = PetscOptionsEnd(); ierr = PetscLogEventRegister("CreateMesh", DM_CLASSID, &options->createMeshEvent);CHKERRQ(ierr); ierr = PetscLogStageRegister("MeshLoad", &options->stages[STAGE_LOAD]);CHKERRQ(ierr); ierr = PetscLogStageRegister("MeshDistribute", &options->stages[STAGE_DISTRIBUTE]);CHKERRQ(ierr); ierr = PetscLogStageRegister("MeshRefine", &options->stages[STAGE_REFINE]);CHKERRQ(ierr); ierr = PetscLogStageRegister("MeshOverlap", &options->stages[STAGE_OVERLAP]);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@ MFNSetFromOptions - Sets MFN options from the options database. This routine must be called before MFNSetUp() if the user is to be allowed to set the solver type. Collective on MFN Input Parameters: . mfn - the matrix function context Notes: To see all options, run your program with the -help option. Level: beginner @*/ PetscErrorCode MFNSetFromOptions(MFN mfn) { PetscErrorCode ierr; char type[256],monfilename[PETSC_MAX_PATH_LEN]; PetscBool flg,flg1,flg2; PetscReal r; PetscInt i; PetscViewer monviewer; PetscFunctionBegin; PetscValidHeaderSpecific(mfn,MFN_CLASSID,1); if (!MFNRegisterAllCalled) { ierr = MFNRegisterAll();CHKERRQ(ierr); } ierr = PetscObjectOptionsBegin((PetscObject)mfn);CHKERRQ(ierr); ierr = PetscOptionsFList("-mfn_type","Matrix Function method","MFNSetType",MFNList,(char*)(((PetscObject)mfn)->type_name?((PetscObject)mfn)->type_name:MFNKRYLOV),type,256,&flg);CHKERRQ(ierr); if (flg) { ierr = MFNSetType(mfn,type);CHKERRQ(ierr); } /* Set the type if it was never set. */ if (!((PetscObject)mfn)->type_name) { ierr = MFNSetType(mfn,MFNKRYLOV);CHKERRQ(ierr); } ierr = PetscOptionsBoolGroupBegin("-mfn_exp","matrix exponential","MFNSetFunction",&flg);CHKERRQ(ierr); if (flg) { ierr = MFNSetFunction(mfn,SLEPC_FUNCTION_EXP);CHKERRQ(ierr); } ierr = PetscOptionsScalar("-mfn_scale","Scale factor","MFNSetScaleFactor",mfn->sfactor,&mfn->sfactor,NULL);CHKERRQ(ierr); i = mfn->max_it; ierr = PetscOptionsInt("-mfn_max_it","Maximum number of iterations","MFNSetTolerances",mfn->max_it,&i,&flg1);CHKERRQ(ierr); r = mfn->tol; ierr = PetscOptionsReal("-mfn_tol","Tolerance","MFNSetTolerances",mfn->tol==PETSC_DEFAULT?SLEPC_DEFAULT_TOL:mfn->tol,&r,&flg2);CHKERRQ(ierr); if (flg1 || flg2) { ierr = MFNSetTolerances(mfn,r,i);CHKERRQ(ierr); } ierr = PetscOptionsInt("-mfn_ncv","Number of basis vectors","MFNSetDimensions",mfn->ncv,&i,&flg);CHKERRQ(ierr); if (flg) { ierr = MFNSetDimensions(mfn,i);CHKERRQ(ierr); } ierr = PetscOptionsBool("-mfn_error_if_not_converged","Generate error if solver does not converge","MFNSetErrorIfNotConverged",mfn->errorifnotconverged,&mfn->errorifnotconverged,NULL);CHKERRQ(ierr); /* -----------------------------------------------------------------------*/ /* Cancels all monitors hardwired into code before call to MFNSetFromOptions() */ flg = PETSC_FALSE; ierr = PetscOptionsBool("-mfn_monitor_cancel","Remove any hardwired monitor routines","MFNMonitorCancel",flg,&flg,NULL);CHKERRQ(ierr); if (flg) { ierr = MFNMonitorCancel(mfn);CHKERRQ(ierr); } /* Prints error estimate at each iteration */ ierr = PetscOptionsString("-mfn_monitor","Monitor error estimate","MFNMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); if (flg) { ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)mfn),monfilename,&monviewer);CHKERRQ(ierr); ierr = MFNMonitorSet(mfn,MFNMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); } flg = PETSC_FALSE; ierr = PetscOptionsBool("-mfn_monitor_lg","Monitor error estimate graphically","MFNMonitorSet",flg,&flg,NULL);CHKERRQ(ierr); if (flg) { ierr = MFNMonitorSet(mfn,MFNMonitorLG,NULL,NULL);CHKERRQ(ierr); } /* -----------------------------------------------------------------------*/ ierr = PetscOptionsName("-mfn_view","Print detailed information on solver used","MFNView",0);CHKERRQ(ierr); if (mfn->ops->setfromoptions) { ierr = (*mfn->ops->setfromoptions)(mfn);CHKERRQ(ierr); } ierr = PetscObjectProcessOptionsHandlers((PetscObject)mfn);CHKERRQ(ierr); ierr = PetscOptionsEnd();CHKERRQ(ierr); if (!mfn->V) { ierr = MFNGetBV(mfn,&mfn->V);CHKERRQ(ierr); } ierr = BVSetFromOptions(mfn->V);CHKERRQ(ierr); if (!mfn->ds) { ierr = MFNGetDS(mfn,&mfn->ds);CHKERRQ(ierr); } ierr = DSSetFromOptions(mfn->ds);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(mfn->rand);CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc,char **argv) { PetscFunctionList plist = NULL; char pname[256]; TS ts; /* nonlinear solver */ Vec x,r; /* solution, residual vectors */ Mat A; /* Jacobian matrix */ Problem problem; PetscBool use_monitor; PetscInt steps,maxsteps = 1000,nonlinits,linits,snesfails,rejects; PetscReal ftime; MonitorCtx mon; PetscErrorCode ierr; PetscMPIInt size; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Initialize program - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ PetscInitialize(&argc,&argv,(char*)0,help); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); if (size > 1) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"Only for sequential runs"); /* Register the available problems */ ierr = PetscFunctionListAdd(&plist,"rober",&RoberCreate);CHKERRQ(ierr); ierr = PetscFunctionListAdd(&plist,"ce",&CECreate);CHKERRQ(ierr); ierr = PetscFunctionListAdd(&plist,"orego",&OregoCreate);CHKERRQ(ierr); ierr = PetscStrcpy(pname,"ce");CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"Timestepping benchmark options","");CHKERRQ(ierr); { ierr = PetscOptionsFList("-problem_type","Name of problem to run","",plist,pname,pname,sizeof(pname),NULL);CHKERRQ(ierr); use_monitor = PETSC_FALSE; ierr = PetscOptionsBool("-monitor_error","Display errors relative to exact solutions","",use_monitor,&use_monitor,NULL);CHKERRQ(ierr); } ierr = PetscOptionsEnd();CHKERRQ(ierr); /* Create the new problem */ ierr = PetscNew(&problem);CHKERRQ(ierr); problem->comm = MPI_COMM_WORLD; { PetscErrorCode (*pcreate)(Problem); ierr = PetscFunctionListFind(plist,pname,&pcreate);CHKERRQ(ierr); if (!pcreate) SETERRQ1(PETSC_COMM_SELF,1,"No problem '%s'",pname); ierr = (*pcreate)(problem);CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create necessary matrix and vectors - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatSetSizes(A,problem->n,problem->n,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr); ierr = MatSetUp(A);CHKERRQ(ierr); ierr = MatGetVecs(A,&x,NULL);CHKERRQ(ierr); ierr = VecDuplicate(x,&r);CHKERRQ(ierr); mon.comm = PETSC_COMM_WORLD; mon.problem = problem; ierr = VecDuplicate(x,&mon.x);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create timestepping solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetProblemType(ts,TS_NONLINEAR);CHKERRQ(ierr); ierr = TSSetType(ts,TSROSW);CHKERRQ(ierr); /* Rosenbrock-W */ ierr = TSSetIFunction(ts,NULL,problem->function,problem->data);CHKERRQ(ierr); ierr = TSSetIJacobian(ts,A,A,problem->jacobian,problem->data);CHKERRQ(ierr); ierr = TSSetDuration(ts,maxsteps,problem->final_time);CHKERRQ(ierr); ierr = TSSetMaxStepRejections(ts,10);CHKERRQ(ierr); ierr = TSSetMaxSNESFailures(ts,-1);CHKERRQ(ierr); /* unlimited */ if (use_monitor) { ierr = TSMonitorSet(ts,&MonitorError,&mon,NULL);CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set initial conditions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = (*problem->solution)(0,x,problem->data);CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts,0.0,.001);CHKERRQ(ierr); ierr = TSSetSolution(ts,x);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetFromOptions(ts);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSolve(ts,x);CHKERRQ(ierr); ierr = TSGetSolveTime(ts,&ftime);CHKERRQ(ierr); ierr = TSGetTimeStepNumber(ts,&steps);CHKERRQ(ierr); ierr = TSGetSNESFailures(ts,&snesfails);CHKERRQ(ierr); ierr = TSGetStepRejections(ts,&rejects);CHKERRQ(ierr); ierr = TSGetSNESIterations(ts,&nonlinits);CHKERRQ(ierr); ierr = TSGetKSPIterations(ts,&linits);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"steps %D (%D rejected, %D SNES fails), ftime %G, nonlinits %D, linits %D\n",steps,rejects,snesfails,ftime,nonlinits,linits);CHKERRQ(ierr); if (problem->hasexact) { ierr = MonitorError(ts,steps,ftime,x,&mon);CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. All PETSc objects should be destroyed when they are no longer needed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&r);CHKERRQ(ierr); ierr = VecDestroy(&mon.x);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); if (problem->destroy) { ierr = (*problem->destroy)(problem);CHKERRQ(ierr); } ierr = PetscFree(problem);CHKERRQ(ierr); ierr = PetscFunctionListDestroy(&plist);CHKERRQ(ierr); ierr = PetscFinalize(); PetscFunctionReturn(0); }
/*@ PetscDrawSetFromOptions - Sets the graphics type from the options database. Defaults to a PETSc X windows graphics. Collective on PetscDraw Input Parameter: . draw - the graphics context Options Database Keys: + -nox - do not use X graphics (ignore graphics calls, but run program correctly) . -nox_warning - when X windows support is not installed this prevents the warning message from being printed . -draw_pause <pause amount> -- -1 indicates wait for mouse input, -2 indicates pause when window is to be destroyed . -draw_save [optional filename] - (X windows only) saves each image before it is cleared to a file . -draw_save_movie - converts image files to a movie at the end of the run. See PetscDrawSetSave() - -draw_save_on_flush - saves an image on each flush in addition to each clear Level: intermediate Notes: Must be called after PetscDrawCreate() before the PetscDrawtor is used. Concepts: drawing^setting options Concepts: graphics^setting options .seealso: PetscDrawCreate(), PetscDrawSetType(), PetscDrawSetSave() @*/ PetscErrorCode PetscDrawSetFromOptions(PetscDraw draw) { PetscErrorCode ierr; PetscBool flg,nox; char vtype[256]; const char *def; PetscReal dpause; #if !defined(PETSC_USE_WINDOWS_GRAPHICS) && !defined(PETSC_HAVE_X) PetscBool warn; #endif PetscFunctionBegin; PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1); if (!PetscDrawList) { ierr = PetscDrawRegisterAll();CHKERRQ(ierr); } if (((PetscObject)draw)->type_name) def = ((PetscObject)draw)->type_name; else { ierr = PetscOptionsHasName(NULL,"-nox",&nox);CHKERRQ(ierr); def = PETSC_DRAW_NULL; #if defined(PETSC_USE_WINDOWS_GRAPHICS) if (!nox) def = PETSC_DRAW_WIN32; #elif defined(PETSC_HAVE_X) if (!nox) def = PETSC_DRAW_X; #elif defined(PETSC_HAVE_GLUT) if (!nox) def = PETSC_DRAW_GLUT; #elif defined(PETSC_HAVE_OPENGLES) if (!nox) def = PETSC_DRAW_OPENGLES; #else ierr = PetscOptionsHasName(NULL,"-nox_warning",&warn);CHKERRQ(ierr); if (!nox && !warn) (*PetscErrorPrintf)("PETSc installed without X windows, Microsoft Graphics, OpenGL ES, or GLUT/OpenGL on this machine\nproceeding without graphics\n"); #endif } ierr = PetscObjectOptionsBegin((PetscObject)draw);CHKERRQ(ierr); ierr = PetscOptionsList("-draw_type","Type of graphical output","PetscDrawSetType",PetscDrawList,def,vtype,256,&flg);CHKERRQ(ierr); if (flg) { ierr = PetscDrawSetType(draw,vtype);CHKERRQ(ierr); } else if (!((PetscObject)draw)->type_name) { ierr = PetscDrawSetType(draw,def);CHKERRQ(ierr); } ierr = PetscOptionsName("-nox","Run without graphics","None",&nox);CHKERRQ(ierr); #if defined(PETSC_HAVE_X) { char filename[PETSC_MAX_PATH_LEN]; PetscBool save,movie = PETSC_FALSE; ierr = PetscOptionsBool("-draw_save_movie","Make a movie from the images saved (X Windows only)","PetscDrawSetSave",movie,&movie,NULL);CHKERRQ(ierr); ierr = PetscOptionsString("-draw_save","Save graphics to file (X Windows only)","PetscDrawSetSave",filename,filename,PETSC_MAX_PATH_LEN,&save);CHKERRQ(ierr); if (save) { ierr = PetscDrawSetSave(draw,filename,movie);CHKERRQ(ierr); } ierr = PetscOptionsBool("-draw_save_on_flush","Save graphics to file (X Windows only) on each flush","PetscDrawSetSave",draw->saveonflush,&draw->saveonflush,NULL);CHKERRQ(ierr); } #endif ierr = PetscOptionsGetReal(NULL,"-draw_pause",&dpause,&flg);CHKERRQ(ierr); if (flg) draw->pause = dpause; /* process any options handlers added with PetscObjectAddOptionsHandler() */ ierr = PetscObjectProcessOptionsHandlers((PetscObject)draw);CHKERRQ(ierr); ierr = PetscOptionsEnd();CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode PCSetFromOptions_ML(PC pc) { PetscErrorCode ierr; PetscInt indx,PrintLevel; const char *scheme[] = {"Uncoupled","Coupled","MIS","METIS"}; PC_MG *mg = (PC_MG*)pc->data; PC_ML *pc_ml = (PC_ML*)mg->innerctx; PetscMPIInt size; MPI_Comm comm = ((PetscObject)pc)->comm; PetscFunctionBegin; ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); ierr = PetscOptionsHead("ML options");CHKERRQ(ierr); PrintLevel = 0; indx = 0; ierr = PetscOptionsInt("-pc_ml_PrintLevel","Print level","ML_Set_PrintLevel",PrintLevel,&PrintLevel,PETSC_NULL);CHKERRQ(ierr); ML_Set_PrintLevel(PrintLevel); ierr = PetscOptionsInt("-pc_ml_maxNlevels","Maximum number of levels","None",pc_ml->MaxNlevels,&pc_ml->MaxNlevels,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsInt("-pc_ml_maxCoarseSize","Maximum coarsest mesh size","ML_Aggregate_Set_MaxCoarseSize",pc_ml->MaxCoarseSize,&pc_ml->MaxCoarseSize,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsEList("-pc_ml_CoarsenScheme","Aggregate Coarsen Scheme","ML_Aggregate_Set_CoarsenScheme_*",scheme,4,scheme[0],&indx,PETSC_NULL);CHKERRQ(ierr); pc_ml->CoarsenScheme = indx; ierr = PetscOptionsReal("-pc_ml_DampingFactor","P damping factor","ML_Aggregate_Set_DampingFactor",pc_ml->DampingFactor,&pc_ml->DampingFactor,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-pc_ml_Threshold","Smoother drop tol","ML_Aggregate_Set_Threshold",pc_ml->Threshold,&pc_ml->Threshold,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-pc_ml_SpectralNormScheme_Anorm","Method used for estimating spectral radius","ML_Set_SpectralNormScheme_Anorm",pc_ml->SpectralNormScheme_Anorm,&pc_ml->SpectralNormScheme_Anorm,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-pc_ml_Symmetrize","Symmetrize aggregation","ML_Set_Symmetrize",pc_ml->Symmetrize,&pc_ml->Symmetrize,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-pc_ml_BlockScaling","Scale all dofs at each node together","None",pc_ml->BlockScaling,&pc_ml->BlockScaling,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsEnum("-pc_ml_nullspace","Which type of null space information to use","None",PCMLNullSpaceTypes,(PetscEnum)pc_ml->nulltype,(PetscEnum*)&pc_ml->nulltype,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsInt("-pc_ml_EnergyMinimization","Energy minimization norm type (0=no minimization; see ML manual for 1,2,3; -1 and 4 undocumented)","None",pc_ml->EnergyMinimization,&pc_ml->EnergyMinimization,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-pc_ml_reuse_interpolation","Reuse the interpolation operators when possible (cheaper, weaker when matrix entries change a lot)","None",pc_ml->reuse_interpolation,&pc_ml->reuse_interpolation,PETSC_NULL);CHKERRQ(ierr); /* The following checks a number of conditions. If we let this stuff slip by, then ML's error handling will take over. This is suboptimal because it amounts to calling exit(1) so we check for the most common conditions. We also try to set some sane defaults when energy minimization is activated, otherwise it's hard to find a working combination of options and ML's exit(1) explanations don't help matters. */ if (pc_ml->EnergyMinimization < -1 || pc_ml->EnergyMinimization > 4) SETERRQ(comm,PETSC_ERR_ARG_OUTOFRANGE,"EnergyMinimization must be in range -1..4"); if (pc_ml->EnergyMinimization == 4 && size > 1) SETERRQ(comm,PETSC_ERR_SUP,"Energy minimization type 4 does not work in parallel"); if (pc_ml->EnergyMinimization == 4) {ierr = PetscInfo(pc,"Mandel's energy minimization scheme is experimental and broken in ML-6.2");CHKERRQ(ierr);} if (pc_ml->EnergyMinimization) { ierr = PetscOptionsReal("-pc_ml_EnergyMinimizationDropTol","Energy minimization drop tolerance","None",pc_ml->EnergyMinimizationDropTol,&pc_ml->EnergyMinimizationDropTol,PETSC_NULL);CHKERRQ(ierr); } if (pc_ml->EnergyMinimization == 2) { /* According to ml_MultiLevelPreconditioner.cpp, this option is only meaningful for norm type (2) */ ierr = PetscOptionsBool("-pc_ml_EnergyMinimizationCheap","Use cheaper variant of norm type 2","None",pc_ml->EnergyMinimizationCheap,&pc_ml->EnergyMinimizationCheap,PETSC_NULL);CHKERRQ(ierr); } /* energy minimization sometimes breaks if this is turned off, the more classical stuff should be okay without it */ if (pc_ml->EnergyMinimization) pc_ml->KeepAggInfo = PETSC_TRUE; ierr = PetscOptionsBool("-pc_ml_KeepAggInfo","Allows the preconditioner to be reused, or auxilliary matrices to be generated","None",pc_ml->KeepAggInfo,&pc_ml->KeepAggInfo,PETSC_NULL);CHKERRQ(ierr); /* Option (-1) doesn't work at all (calls exit(1)) if the tentative restriction operator isn't stored. */ if (pc_ml->EnergyMinimization == -1) pc_ml->Reusable = PETSC_TRUE; ierr = PetscOptionsBool("-pc_ml_Reusable","Store intermedaiate data structures so that the multilevel hierarchy is reusable","None",pc_ml->Reusable,&pc_ml->Reusable,PETSC_NULL);CHKERRQ(ierr); /* ML's C API is severely underdocumented and lacks significant functionality. The C++ API calls ML_Gen_MultiLevelHierarchy_UsingAggregation() which is a modified copy (!?) of the documented function ML_Gen_MGHierarchy_UsingAggregation(). This modification, however, does not provide a strict superset of the functionality in the old function, so some users may still want to use it. Note that many options are ignored in this context, but ML doesn't provide a way to find out which ones. */ ierr = PetscOptionsBool("-pc_ml_OldHierarchy","Use old routine to generate hierarchy","None",pc_ml->OldHierarchy,&pc_ml->OldHierarchy,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsTail();CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc,char **argv) { TS ts; /* ODE integrator */ Vec U; /* solution will be stored here */ Mat A; /* Jacobian matrix */ Mat Jacp; /* Jacobian matrix */ PetscErrorCode ierr; PetscMPIInt size; PetscInt n = 2; AppCtx ctx; PetscScalar *u; PetscReal du[2] = {0.0,0.0}; PetscBool ensemble = PETSC_FALSE,flg1,flg2; PetscReal ftime; PetscInt steps; PetscScalar *x_ptr,*y_ptr; Vec lambda[1],q,mu[1]; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Initialize program - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = PetscInitialize(&argc,&argv,(char*)0,help);CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); if (size > 1) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"Only for sequential runs"); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create necessary matrix and vectors - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatSetSizes(A,n,n,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); ierr = MatSetType(A,MATDENSE);CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr); ierr = MatSetUp(A);CHKERRQ(ierr); ierr = MatCreateVecs(A,&U,NULL);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&Jacp);CHKERRQ(ierr); ierr = MatSetSizes(Jacp,PETSC_DECIDE,PETSC_DECIDE,2,1);CHKERRQ(ierr); ierr = MatSetFromOptions(Jacp);CHKERRQ(ierr); ierr = MatSetUp(Jacp);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"Swing equation options","");CHKERRQ(ierr); { ctx.beta = 2; ctx.c = 10000.0; ctx.u_s = 1.0; ctx.omega_s = 1.0; ctx.omega_b = 120.0*PETSC_PI; ctx.H = 5.0; ierr = PetscOptionsScalar("-Inertia","","",ctx.H,&ctx.H,NULL);CHKERRQ(ierr); ctx.D = 5.0; ierr = PetscOptionsScalar("-D","","",ctx.D,&ctx.D,NULL);CHKERRQ(ierr); ctx.E = 1.1378; ctx.V = 1.0; ctx.X = 0.545; ctx.Pmax = ctx.E*ctx.V/ctx.X;; ierr = PetscOptionsScalar("-Pmax","","",ctx.Pmax,&ctx.Pmax,NULL);CHKERRQ(ierr); ctx.Pm = 1.1; ierr = PetscOptionsScalar("-Pm","","",ctx.Pm,&ctx.Pm,NULL);CHKERRQ(ierr); ctx.tf = 0.1; ctx.tcl = 0.2; ierr = PetscOptionsReal("-tf","Time to start fault","",ctx.tf,&ctx.tf,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-tcl","Time to end fault","",ctx.tcl,&ctx.tcl,NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-ensemble","Run ensemble of different initial conditions","",ensemble,&ensemble,NULL);CHKERRQ(ierr); if (ensemble) { ctx.tf = -1; ctx.tcl = -1; } ierr = VecGetArray(U,&u);CHKERRQ(ierr); u[0] = PetscAsinScalar(ctx.Pm/ctx.Pmax); u[1] = 1.0; ierr = PetscOptionsRealArray("-u","Initial solution","",u,&n,&flg1);CHKERRQ(ierr); n = 2; ierr = PetscOptionsRealArray("-du","Perturbation in initial solution","",du,&n,&flg2);CHKERRQ(ierr); u[0] += du[0]; u[1] += du[1]; ierr = VecRestoreArray(U,&u);CHKERRQ(ierr); if (flg1 || flg2) { ctx.tf = -1; ctx.tcl = -1; } } ierr = PetscOptionsEnd();CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create timestepping solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetProblemType(ts,TS_NONLINEAR);CHKERRQ(ierr); ierr = TSSetType(ts,TSRK);CHKERRQ(ierr); ierr = TSSetRHSFunction(ts,NULL,(TSRHSFunction)RHSFunction,&ctx);CHKERRQ(ierr); ierr = TSSetRHSJacobian(ts,A,A,(TSRHSJacobian)RHSJacobian,&ctx);CHKERRQ(ierr); ierr = TSSetExactFinalTime(ts,TS_EXACTFINALTIME_MATCHSTEP);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set initial conditions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetSolution(ts,U);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Save trajectory of solution so that TSAdjointSolve() may be used - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetSaveTrajectory(ts);CHKERRQ(ierr); ierr = MatCreateVecs(A,&lambda[0],NULL);CHKERRQ(ierr); /* Set initial conditions for the adjoint integration */ ierr = VecGetArray(lambda[0],&y_ptr);CHKERRQ(ierr); y_ptr[0] = 0.0; y_ptr[1] = 0.0; ierr = VecRestoreArray(lambda[0],&y_ptr);CHKERRQ(ierr); ierr = MatCreateVecs(Jacp,&mu[0],NULL);CHKERRQ(ierr); ierr = VecGetArray(mu[0],&x_ptr);CHKERRQ(ierr); x_ptr[0] = -1.0; ierr = VecRestoreArray(mu[0],&x_ptr);CHKERRQ(ierr); ierr = TSSetCostGradients(ts,1,lambda,mu);CHKERRQ(ierr); ierr = TSSetCostIntegrand(ts,1,(PetscErrorCode (*)(TS,PetscReal,Vec,Vec,void*))CostIntegrand, (PetscErrorCode (*)(TS,PetscReal,Vec,Vec*,void*))DRDYFunction, (PetscErrorCode (*)(TS,PetscReal,Vec,Vec*,void*))DRDPFunction,PETSC_TRUE,&ctx);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set solver options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetDuration(ts,PETSC_DEFAULT,10.0);CHKERRQ(ierr); ierr = TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER);CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts,0.0,.01);CHKERRQ(ierr); ierr = TSSetFromOptions(ts);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ if (ensemble) { for (du[1] = -2.5; du[1] <= .01; du[1] += .1) { ierr = VecGetArray(U,&u);CHKERRQ(ierr); u[0] = PetscAsinScalar(ctx.Pm/ctx.Pmax); u[1] = ctx.omega_s; u[0] += du[0]; u[1] += du[1]; ierr = VecRestoreArray(U,&u);CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts,0.0,.01);CHKERRQ(ierr); ierr = TSSolve(ts,U);CHKERRQ(ierr); } } else { ierr = TSSolve(ts,U);CHKERRQ(ierr); } ierr = VecView(U,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = TSGetSolveTime(ts,&ftime);CHKERRQ(ierr); ierr = TSGetTimeStepNumber(ts,&steps);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Adjoint model starts here - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Set initial conditions for the adjoint integration */ ierr = VecGetArray(lambda[0],&y_ptr);CHKERRQ(ierr); y_ptr[0] = 0.0; y_ptr[1] = 0.0; ierr = VecRestoreArray(lambda[0],&y_ptr);CHKERRQ(ierr); ierr = VecGetArray(mu[0],&x_ptr);CHKERRQ(ierr); x_ptr[0] = -1.0; ierr = VecRestoreArray(mu[0],&x_ptr);CHKERRQ(ierr); /* Set RHS JacobianP */ ierr = TSAdjointSetRHSJacobian(ts,Jacp,RHSJacobianP,&ctx);CHKERRQ(ierr); ierr = TSAdjointSolve(ts);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"\n sensitivity wrt initial conditions: d[Psi(tf)]/d[phi0] d[Psi(tf)]/d[omega0]\n");CHKERRQ(ierr); ierr = VecView(lambda[0],PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = VecView(mu[0],PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = TSGetCostIntegral(ts,&q);CHKERRQ(ierr); ierr = VecView(q,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = VecGetArray(q,&x_ptr);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"\n cost function=%g\n",(double)(x_ptr[0]-ctx.Pm));CHKERRQ(ierr); ierr = VecRestoreArray(q,&x_ptr);CHKERRQ(ierr); ierr = ComputeSensiP(lambda[0],mu[0],&ctx);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. All PETSc objects should be destroyed when they are no longer needed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = MatDestroy(&Jacp);CHKERRQ(ierr); ierr = VecDestroy(&U);CHKERRQ(ierr); ierr = VecDestroy(&lambda[0]);CHKERRQ(ierr); ierr = VecDestroy(&mu[0]);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = PetscFinalize(); return(0); }
int main(int argc, char **argv) { MPI_Comm comm; DM dm; Vec v, nv, rv, coord; PetscBool test_read = PETSC_FALSE, verbose = PETSC_FALSE, flg; PetscViewer hdf5Viewer; PetscInt dim = 2; PetscInt numFields = 1; PetscInt numBC = 0; PetscInt numComp[1] = {2}; PetscInt numDof[3] = {2, 0, 0}; PetscInt bcFields[1] = {0}; IS bcPoints[1] = {NULL}; PetscSection section; PetscReal norm; PetscErrorCode ierr; ierr = PetscInitialize(&argc, &argv, (char *) 0, help);CHKERRQ(ierr); comm = PETSC_COMM_WORLD; ierr = PetscOptionsBegin(PETSC_COMM_WORLD,"","Test Options","none");CHKERRQ(ierr); ierr = PetscOptionsBool("-test_read","Test reading from the HDF5 file","",PETSC_FALSE,&test_read,NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-verbose","print the Vecs","",PETSC_FALSE,&verbose,NULL);CHKERRQ(ierr); ierr = PetscOptionsInt("-dim","the dimension of the problem","",2,&dim,NULL);CHKERRQ(ierr); ierr = PetscOptionsEnd(); ierr = DMPlexCreateBoxMesh(comm, dim, PETSC_TRUE, &dm);CHKERRQ(ierr); ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); numDof[0] = dim; ierr = DMPlexCreateSection(dm, dim, numFields, numComp, numDof, numBC, bcFields, bcPoints, NULL, NULL, §ion);CHKERRQ(ierr); ierr = DMSetDefaultSection(dm, section);CHKERRQ(ierr); ierr = PetscSectionDestroy(§ion);CHKERRQ(ierr); ierr = DMSetUseNatural(dm, PETSC_TRUE);CHKERRQ(ierr); { DM dmDist; ierr = DMPlexDistribute(dm, 0, NULL, &dmDist);CHKERRQ(ierr); if (dmDist) { ierr = DMDestroy(&dm);CHKERRQ(ierr); dm = dmDist; } } ierr = DMCreateGlobalVector(dm, &v);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) v, "V");CHKERRQ(ierr); ierr = DMGetCoordinates(dm, &coord);CHKERRQ(ierr); ierr = VecCopy(coord, v);CHKERRQ(ierr); if (verbose) { PetscInt size, bs; ierr = VecGetSize(v, &size);CHKERRQ(ierr); ierr = VecGetBlockSize(v, &bs);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "==== original V in global ordering. size==%d\tblock size=%d\n", size, bs);CHKERRQ(ierr); ierr = VecView(v, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } ierr = DMCreateGlobalVector(dm, &nv);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) nv, "NV");CHKERRQ(ierr); ierr = DMPlexGlobalToNaturalBegin(dm, v, nv);CHKERRQ(ierr); ierr = DMPlexGlobalToNaturalEnd(dm, v, nv);CHKERRQ(ierr); if (verbose) { PetscInt size, bs; ierr = VecGetSize(nv, &size);CHKERRQ(ierr); ierr = VecGetBlockSize(nv, &bs);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "==== V in natural ordering. size==%d\tblock size=%d\n", size, bs);CHKERRQ(ierr); ierr = VecView(nv, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } ierr = VecViewFromOptions(v, NULL, "-global_vec_view");CHKERRQ(ierr); if (test_read) { ierr = DMCreateGlobalVector(dm, &rv);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) rv, "V");CHKERRQ(ierr); /* Test native read */ ierr = PetscViewerHDF5Open(comm, "V.h5", FILE_MODE_READ, &hdf5Viewer);CHKERRQ(ierr); ierr = PetscViewerPushFormat(hdf5Viewer, PETSC_VIEWER_NATIVE);CHKERRQ(ierr); ierr = VecLoad(rv, hdf5Viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&hdf5Viewer);CHKERRQ(ierr); if (verbose) { PetscInt size, bs; ierr = VecGetSize(rv, &size);CHKERRQ(ierr); ierr = VecGetBlockSize(rv, &bs);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "==== Vector from file. size==%d\tblock size=%d\n", size, bs);CHKERRQ(ierr); ierr = VecView(rv, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } ierr = VecEqual(rv, v, &flg);CHKERRQ(ierr); if (flg) { ierr = PetscPrintf(PETSC_COMM_WORLD, "V and RV are equal\n");CHKERRQ(ierr); } else { ierr = PetscPrintf(PETSC_COMM_WORLD, "V and RV are not equal\n\n");CHKERRQ(ierr); ierr = VecAXPY(rv, -1.0, v);CHKERRQ(ierr); ierr = VecNorm(rv, NORM_INFINITY, &norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "diff norm is = %g\n", (double) norm);CHKERRQ(ierr); ierr = VecView(rv, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } /* Test raw read */ ierr = PetscViewerHDF5Open(comm, "V.h5", FILE_MODE_READ, &hdf5Viewer);CHKERRQ(ierr); ierr = VecLoad(rv, hdf5Viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&hdf5Viewer);CHKERRQ(ierr); if (verbose) { PetscInt size, bs; ierr = VecGetSize(rv, &size);CHKERRQ(ierr); ierr = VecGetBlockSize(rv, &bs);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "==== Vector from file. size==%d\tblock size=%d\n", size, bs);CHKERRQ(ierr); ierr = VecView(rv, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } ierr = VecEqual(rv, nv, &flg);CHKERRQ(ierr); if (flg) { ierr = PetscPrintf(PETSC_COMM_WORLD, "NV and RV are equal\n");CHKERRQ(ierr); } else { ierr = PetscPrintf(PETSC_COMM_WORLD, "NV and RV are not equal\n\n");CHKERRQ(ierr); ierr = VecAXPY(rv, -1.0, v);CHKERRQ(ierr); ierr = VecNorm(rv, NORM_INFINITY, &norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "diff norm is = %g\n", (double) norm);CHKERRQ(ierr); ierr = VecView(rv, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } ierr = VecDestroy(&rv);CHKERRQ(ierr); } ierr = VecDestroy(&nv);CHKERRQ(ierr); ierr = VecDestroy(&v);CHKERRQ(ierr); ierr = DMDestroy(&dm);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
PetscErrorCode LoadOptions(MPI_Comm comm, User user) { PetscErrorCode ierr; PetscFunctionBeginUser; Model model = user->model; //Algebra algebra = user->algebra; Physics phy = model->physics; ierr = PetscOptionsBegin(comm,NULL,"Physics Model Options","");CHKERRQ(ierr); { user->includeenergy = PETSC_FALSE; ierr = PetscOptionsBool("-includeenergy","Including the Energy fields","",user->includeenergy,&user->includeenergy,NULL);CHKERRQ(ierr); if (user->includeenergy){ phy->field_desc = PhysicsFields_Full; }else{ phy->field_desc = PhysicsFields_Partial; } user->KDof = 3.0; user->adiabatic = 1.67; //user->R = 8.3144621; user->R = 287.0; user->viscosity = 0.1; user->k = 0.026; user->inflow_u = 0.0; user->inflow_v = 0.0; user->inflow_w = 0.0; ierr = PetscOptionsReal("-kinematic_dof","Kinematic Degrees of freedom, for the monoatomic gas, kinematic_dof = 3 and for a diatomic gas, kinematic_dof = 5","",user->KDof,&user->KDof,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-adiabatic","Heat capacity ratio or called adiabatic","", user->adiabatic, &user->adiabatic, NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-R","The gas constant which is 8.3144621 J K^{-1} mol^{-1} for the state equation","", user->R, &user->R, NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-viscosity","The viscosity of the flow","", user->viscosity, &user->viscosity, NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-k","the thermal conductivity coefficient","", user->k, &user->k, NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-inflow_u","the inflow velocity in x direction","", user->inflow_u, &user->inflow_u, NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-inflow_v","the inflow velocity in y direction","", user->inflow_v, &user->inflow_v, NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-inflow_w","the inflow velocity in z direction","", user->inflow_w, &user->inflow_w, NULL);CHKERRQ(ierr); } ierr = PetscOptionsEnd();CHKERRQ(ierr); ierr = PetscOptionsBegin(comm,NULL,"Unstructured Finite Volume Mesh Options","");CHKERRQ(ierr); { //user->filename = "sevenside.exo"; ierr = PetscOptionsString("-f","Exodus.II filename to read","",user->filename,user->filename,sizeof(user->filename),NULL);CHKERRQ(ierr); user->show_partition = PETSC_FALSE; ierr = PetscOptionsBool("-show_partition","Write cell geometry (for debugging)","",user->show_partition,&user->show_partition,NULL);CHKERRQ(ierr); user->overlap = 1; ierr = PetscOptionsInt("-overlap","Number of cells to overlap partitions","",user->overlap,&user->overlap,NULL);CHKERRQ(ierr); } ierr = PetscOptionsEnd();CHKERRQ(ierr); ierr = PetscOptionsBegin(comm,NULL,"Unstructured Finite Volume Method Options","");CHKERRQ(ierr); { user->reconstruct = PETSC_FALSE; ierr = PetscOptionsBool("-reconstruct","Reconstruct gradients for a second order method (grows stencil)","",user->reconstruct,&user->reconstruct,NULL);CHKERRQ(ierr); user->TimeIntegralMethod = 0; ierr = PetscOptionsInt("-time_integral_method","Method for the time integral, 0 for the explicit method and 1 for the implicit method","",user->TimeIntegralMethod,&user->TimeIntegralMethod,NULL);CHKERRQ(ierr); user->timestep = 0; ierr = PetscOptionsInt("-timestep","Scheme for the implicit time integral: backward Euler, BDF2, ...","",user->timestep,&user->timestep,NULL);CHKERRQ(ierr); user->myownexplicitmethod = PETSC_FALSE; ierr = PetscOptionsBool("-myownexplicitmethod","Using my own explicit metod","",user->myownexplicitmethod,&user->myownexplicitmethod,NULL);CHKERRQ(ierr); user->PressureFlux = PETSC_FALSE; ierr = PetscOptionsBool("-PressureFlux","Transfer the pressure term to the flux style","",user->PressureFlux,&user->PressureFlux,NULL);CHKERRQ(ierr); user->output_solution = PETSC_FALSE; ierr = PetscOptionsBool("-output_solution","output the solution to a file","",user->output_solution,&user->output_solution,NULL);CHKERRQ(ierr); user->JdiffP = PETSC_FALSE; ierr = PetscOptionsBool("-JdiffP","The preconditioner matrix is different from the Jacobian matrix","",user->JdiffP,&user->JdiffP,NULL);CHKERRQ(ierr); user->dt = 0.001; ierr = PetscOptionsReal("-dt","The time step size","",user->dt,&user->dt,NULL);CHKERRQ(ierr); user->initial_time = 0.0; ierr = PetscOptionsReal("-initial_time","The initial time","", user->initial_time, &user->initial_time, NULL);CHKERRQ(ierr); user->final_time = 1.0; ierr = PetscOptionsReal("-final_time","The final time","",user->final_time,&user->final_time,NULL);CHKERRQ(ierr); user->second_order = PETSC_FALSE; ierr = PetscOptionsBool("-second_order","Use the second order scheme by using the reconstruction","",user->second_order,&user->second_order,NULL);CHKERRQ(ierr); user->fd_jacobian = PETSC_FALSE; ierr = PetscOptionsBool("-fd_jacobian","Use the PETSc default finite difference method to construct the Jacobian matrix","",user->fd_jacobian,&user->fd_jacobian,NULL);CHKERRQ(ierr); user->fd_jacobian_color = PETSC_FALSE; ierr = PetscOptionsBool("-fd_jacobian_color","Use the PETSc default finite difference method to construct the Jacobian matrix","",user->fd_jacobian_color,&user->fd_jacobian_color,NULL);CHKERRQ(ierr); } ierr = PetscOptionsEnd();CHKERRQ(ierr); ierr = PetscOptionsBegin(comm,NULL,"Other Options","");CHKERRQ(ierr); { user->benchmark_couette = PETSC_FALSE; ierr = PetscOptionsBool("-benchmark_couette","For the Couette benchmark problem test","",user->benchmark_couette,&user->benchmark_couette,NULL);CHKERRQ(ierr); user->max_time_its = 0; ierr = PetscOptionsInt("-max_time_its","The maximum time steps","",user->max_time_its,&user->max_time_its,NULL);CHKERRQ(ierr); user->Explicit_RK2 = PETSC_FALSE; ierr = PetscOptionsBool("-Explicit_RK2","Use the second order Runge Kutta method","",user->Explicit_RK2,&user->Explicit_RK2,NULL);CHKERRQ(ierr); user->T0 = 0.0; ierr = PetscOptionsReal("-T0","For the couette test case","", user->T0, &user->T0, NULL);CHKERRQ(ierr); user->T1 = 0.0; ierr = PetscOptionsReal("-T1","For the couette test case","", user->T1, &user->T1, NULL);CHKERRQ(ierr); user->Euler = PETSC_FALSE; ierr = PetscOptionsBool("-Euler","Use the Euler equation","",user->Euler,&user->Euler, NULL);CHKERRQ(ierr); } ierr = PetscOptionsEnd();CHKERRQ(ierr); PetscFunctionReturn(0); }
// Generates a mesh of a brick using run-time parameters. // The new mesh populates the given root set. // This should be converted to have a useful programmatic API. dErr dMeshGenerateBlock(dMesh dmesh,dMeshESH root,PetscBool do_geom) { const char pTagName[]="OWNING_PART", pSetName[]="PARALLEL_PARTITION"; PetscBool assoc_with_brick=0,do_color_bdy=0,do_material = 1,do_uniform = 1,do_global_number = 0,do_global_id = 1; PetscBool do_partition = 1,do_pressure = 0,do_faces = 1,do_edges = 1; dReal rotate_y = 0; dInt verbose = 0; iMesh_Instance mesh; iBase_EntityHandle *entbuf; iBase_EntitySetHandle facesets[6]; iBase_TagHandle pTag; MeshListEH v=MLZ,e=MLZ,f=MLZ,r=MLZ,c=MLZ; MeshListReal x=MLZ; MeshListInt s=MLZ,part=MLZ; dInt *face[6],facecount[6]={0}; int err,i,j,k,m,n,p,M,N,P,I,J,K,order=iBase_INTERLEAVED; Box box; PetscViewer viewer; dFunctionBegin; dValidHeader(dmesh,dMESH_CLASSID,1); err = PetscViewerASCIIGetStdout(((PetscObject)dmesh)->comm,&viewer);dCHK(err); err = PetscOptionsBegin(((PetscObject)dmesh)->comm,((PetscObject)dmesh)->prefix,"dMeshGenerate Block: generate cartesian meshes",NULL);dCHK(err); { char boxstr[256] = "-1:1,-1:1,-1:1",mnp[256] = "5,5,5",MNP[256] = "2,2,2"; err = PetscOptionsInt("-dmeshgen_block_verbose","verbosity of output","none",verbose,&verbose,NULL);dCHK(err); if (do_geom) { err = PetscOptionsBool("-dmeshgen_block_assoc_with_brick","associate boundaries with brick","none",assoc_with_brick,&assoc_with_brick,NULL);dCHK(err); } err = PetscOptionsBool("-dmeshgen_block_color_bdy","color boundary sets","none",do_color_bdy,&do_color_bdy,NULL);dCHK(err); err = PetscOptionsBool("-dmeshgen_block_material","create material sets","none",do_material,&do_material,NULL);dCHK(err); err = PetscOptionsBool("-dmeshgen_block_uniform","create uniform sets","none",do_uniform,&do_uniform,NULL);dCHK(err); err = PetscOptionsBool("-dmeshgen_block_global_number","create global_number tags","none",do_global_number,&do_global_number,NULL);dCHK(err); err = PetscOptionsBool("-dmeshgen_block_global_id","create GLOBAL_ID tags","none",do_global_id,&do_global_id,NULL);dCHK(err); err = PetscOptionsBool("-dmeshgen_block_partition","create partition sets","none",do_partition,&do_partition,NULL);dCHK(err); err = PetscOptionsBool("-dmeshgen_block_pressure","create pressure sets","none",do_pressure,&do_pressure,NULL);dCHK(err); err = PetscOptionsBool("-dmeshgen_block_faces","create face entities","none",do_faces,&do_faces,NULL);dCHK(err); err = PetscOptionsBool("-dmeshgen_block_edges","create face entities","none",do_edges,&do_edges,NULL);dCHK(err); err = PetscOptionsReal("-dmeshgen_block_rotate_y","rotate domain by given angle (degrees) around y axis)","none",rotate_y,&rotate_y,NULL);dCHK(err); rotate_y *= PETSC_PI/180.; err = PetscOptionsString("-dmeshgen_block_box","box x0:x1,y0:y1,z0:z1","none",boxstr,boxstr,sizeof(boxstr),NULL);dCHK(err); err = PetscOptionsString("-dmeshgen_block_mnp","number of points m,n,p","none",mnp,mnp,sizeof(mnp),NULL);dCHK(err); err = PetscOptionsString("-dmeshgen_block_procs_mnp","number of procs M,N,P","none",MNP,MNP,sizeof(MNP),NULL);dCHK(err); i = sscanf(boxstr,"%lf:%lf,%lf:%lf,%lf:%lf",&box.x0,&box.x1,&box.y0,&box.y1,&box.z0,&box.z1); if (i != 6) dERROR(PETSC_COMM_SELF,1,"Failed to parse bounding box."); i = sscanf(mnp,"%d,%d,%d",&m,&n,&p); if (i != 3) dERROR(PETSC_COMM_SELF,1,"Failed to parse size."); i = sscanf(MNP,"%d,%d,%d",&M,&N,&P); if (i != 3) dERROR(PETSC_COMM_SELF,1,"Failed to parse partition size."); } err = PetscOptionsEnd(); err = dMeshGetInstance(dmesh,&mesh);dCHK(err); /* Allocate buffers */ err = dMallocA(m*n*p*3,&entbuf);dCHK(err); /* More than enough to hold all entities of any given type */ for (i=0; i<6; i++) { int n2max = dSqrInt(dMaxInt(m,dMaxInt(n,p))); err = dMallocA(2*n2max,&face[i]);dCHK(err); iMesh_createEntSet(mesh,0,&facesets[i],&err);dICHK(mesh,err); } /* Create vertices */ x.a = x.s = m*n*p*3; x.v = malloc(x.a*sizeof(double)); for (i=0; i<m; i++) { for (j=0; j<n; j++) { for (k=0; k<p; k++) { dReal X,Y,Z; I = (i*n+j)*p+k; if (i==0) AddToFace(face,facecount,3,I); else if (i==m-1) AddToFace(face,facecount,1,I); else if (j==0) AddToFace(face,facecount,0,I); else if (j==n-1) AddToFace(face,facecount,2,I); else if (k==0) AddToFace(face,facecount,4,I); else if (k==p-1) AddToFace(face,facecount,5,I); X = box.x0 + (box.x1-box.x0)*(1.*i/(m-1)); Y = box.y0 + (box.y1-box.y0)*(1.*j/(n-1)); Z = box.z0 + (box.z1-box.z0)*(1.*k/(p-1)); x.v[3*I+0] = cos(rotate_y) * X - sin(rotate_y) * Z; x.v[3*I+1] = Y; x.v[3*I+2] = sin(rotate_y) * X + cos(rotate_y) * Z; } } } iMesh_createVtxArr(mesh,m*n*p,order,x.v,x.s,&v.v,&v.a,&v.s,&err);dICHK(mesh,err); err = CommitToFaceSets(mesh,v.v,face,facecount,facesets,entbuf); MeshListFree(x); /* Create regions */ c.a = c.s = (m-1)*(n-1)*(p-1)*8; c.v = malloc(c.a*sizeof(iBase_EntityHandle)); /* connectivity */ I=0; for (i=0; i<m-1; i++) { for (j=0; j<n-1; j++) { for (k=0; k<p-1; k++) { c.v[I++] = v.v[((i+0)*n+(j+0))*p+(k+0)]; c.v[I++] = v.v[((i+1)*n+(j+0))*p+(k+0)]; c.v[I++] = v.v[((i+1)*n+(j+1))*p+(k+0)]; c.v[I++] = v.v[((i+0)*n+(j+1))*p+(k+0)]; c.v[I++] = v.v[((i+0)*n+(j+0))*p+(k+1)]; c.v[I++] = v.v[((i+1)*n+(j+0))*p+(k+1)]; c.v[I++] = v.v[((i+1)*n+(j+1))*p+(k+1)]; c.v[I++] = v.v[((i+0)*n+(j+1))*p+(k+1)]; } } } if (I != c.s) dERROR(PETSC_COMM_SELF,1,"Wrong number of regions."); iMesh_createEntArr(mesh,iMesh_HEXAHEDRON,c.v,c.s,&r.v,&r.a,&r.s,&s.v,&s.a,&s.s,&err);dICHK(mesh,err); if (r.s != (m-1)*(n-1)*(p-1)) dERROR(PETSC_COMM_SELF,1,"Wrong number of regions created."); if (verbose > 0) {err = PetscViewerASCIIPrintf(viewer,"region size %d, status size %d\n",r.s,s.s);dCHK(err);} if (do_global_number) {err = doGlobalNumber(mesh,root);dCHK(err);} if (do_global_id) {err = doGlobalID(mesh,root);dCHK(err);} if (do_partition) { /* Partition tags */ /* Create partition. */ part.a = part.s = r.s; part.v = malloc(part.a*sizeof(int)); for (i=0; i<m-1; i++) { for (j=0; j<n-1; j++) { for (k=0; k<p-1; k++) { I = i*M/(m-1); J = j*N/(n-1); K = k*P/(p-1); part.v[(i*(n-1)+j)*(p-1)+k] = (I*N+J)*P+K; } } } /* MATERIAL_SET is a special name associated with all iMesh instances * If we are using a different name, we can assume it is not special. */ if (strcmp(pTagName,"MATERIAL_SET")) { iMesh_createTag(mesh,pTagName,1,iBase_INTEGER,&pTag,&err,sizeof(pTagName));dICHK(mesh,err); } else { iMesh_getTagHandle(mesh,"MATERIAL_SET",&pTag,&err,sizeof("MATERIAL_SET"));dICHK(mesh,err); } iMesh_setIntArrData(mesh,r.v,r.s,pTag,part.v,part.s,&err);dICHK(mesh,err); MeshListFree(part); } if (do_partition) /* Partition sets */ { int ii,jj,kk; iBase_EntitySetHandle partset; iBase_EntityHandle *entp; /* reuse some stuff, set up the a partition set */ iMesh_createTag(mesh,pSetName,1,iBase_INTEGER,&pTag,&err,sizeof(pSetName));dICHK(mesh,err); for (i=0; i<M; i++) { for (j=0; j<N; j++) { for (k=0; k<P; k++) { iMesh_createEntSet(mesh,0,&partset,&err);dICHK(mesh,err); entp = entbuf; for (ii=i*(m-1)/M; ii<(i+1)*(m-1)/M; ii++) { for (jj=j*(n-1)/N; jj<(j+1)*(n-1)/N; jj++) { for (kk=k*(p-1)/P; kk<(k+1)*(p-1)/P; kk++) { *entp++ = r.v[(ii*(n-1)+jj)*(p-1)+kk]; } } } if (verbose > 0) {err = PetscViewerASCIIPrintf(viewer,"part[%d (%d,%d,%d)] has %d regions\n",(i*N+j)*P+k,i,j,k,(int)(entp-entbuf));dCHK(err);} iMesh_addEntArrToSet(mesh,entbuf,(int)(entp-entbuf),partset,&err);dICHK(mesh,err); iMesh_setEntSetIntData(mesh,partset,pTag,(i*N+j)*P+k,&err);dICHK(mesh,err); } } } } MeshListFree(r); MeshListFree(s); MeshListFree(c); if (do_faces) { /* Create faces */ c.a = c.s = 4*((m-1)*(n-1)*p + (m-1)*n*(p-1) + m*(n-1)*(p-1)); c.v = malloc(c.a*sizeof(iBase_EntityHandle)); I = 0; for (i=0; i<m-1; i++) { /* Faces with normal pointing in positive z direction */ for (j=0; j<n-1; j++) { for (k=0; k<p; k++) { if (k==0) AddToFace(face,facecount,4,I/4); if (k==p-1) AddToFace(face,facecount,5,I/4); c.v[I++] = v.v[((i+0)*n+(j+0))*p+k]; c.v[I++] = v.v[((i+1)*n+(j+0))*p+k]; c.v[I++] = v.v[((i+1)*n+(j+1))*p+k]; c.v[I++] = v.v[((i+0)*n+(j+1))*p+k]; } } } for (i=0; i<m-1; i++) { /* Faces with normal pointing in negative y direction */ for (j=0; j<n; j++) { for (k=0; k<p-1; k++) { if (j==0) AddToFace(face,facecount,0,I/4); if (j==n-1) AddToFace(face,facecount,2,I/4); c.v[I++] = v.v[((i+0)*n+j)*p+(k+0)]; c.v[I++] = v.v[((i+1)*n+j)*p+(k+0)]; c.v[I++] = v.v[((i+1)*n+j)*p+(k+1)]; c.v[I++] = v.v[((i+0)*n+j)*p+(k+1)]; } } } for (i=0; i<m; i++) { /* Faces with normal pointing in positive x direction */ for (j=0; j<n-1; j++) { for (k=0; k<p-1; k++) { if (i==0) AddToFace(face,facecount,3,I/4); if (i==m-1) AddToFace(face,facecount,1,I/4); c.v[I++] = v.v[(i*n+(j+0))*p+(k+0)]; c.v[I++] = v.v[(i*n+(j+1))*p+(k+0)]; c.v[I++] = v.v[(i*n+(j+1))*p+(k+1)]; c.v[I++] = v.v[(i*n+(j+0))*p+(k+1)]; } } } if (I != c.s) dERROR(PETSC_COMM_SELF,1, "Wrong number of faces."); iMesh_createEntArr(mesh,iMesh_QUADRILATERAL,c.v,c.s,&f.v,&f.a,&f.s,&s.v,&s.a,&s.s,&err);dICHK(mesh,err); err = CommitToFaceSets(mesh,f.v,face,facecount,facesets,entbuf);dCHK(err); if (verbose > 0) {err = PetscViewerASCIIPrintf(viewer,"face size %d, status size %d\n",f.s,s.s);dCHK(err);} MeshListFree(f); MeshListFree(s); MeshListFree(c); } if (do_edges) { /* Create edges */ c.a = c.s = 2*(m*n*(p-1) + m*(n-1)*p + (m-1)*n*p); c.v = malloc(c.a*sizeof(iBase_EntityHandle)); I = 0; for (i=0; i<m; i++) { for (j=0; j<n; j++) { for (k=0; k<p-1; k++) { if (i==0) AddToFace(face,facecount,0,I/2); else if (i==m-1) AddToFace(face,facecount,2,I/2); else if (j==0) AddToFace(face,facecount,3,I/2); else if (j==n-1) AddToFace(face,facecount,1,I/2); c.v[I++] = v.v[(i*n+j)*p+(k+0)]; c.v[I++] = v.v[(i*n+j)*p+(k+1)]; } } } for (i=0; i<m; i++) { for (j=0; j<n-1; j++) { for (k=0; k<p; k++) { if (i==0) AddToFace(face,facecount,0,I/2); else if (i==m-1) AddToFace(face,facecount,2,I/2); else if (k==0) AddToFace(face,facecount,4,I/2); else if (k==p-1) AddToFace(face,facecount,5,I/2); c.v[I++] = v.v[(i*n+(j+0))*p+k]; c.v[I++] = v.v[(i*n+(j+1))*p+k]; } } } for (i=0; i<m-1; i++) { for (j=0; j<n; j++) { for (k=0; k<p; k++) { if (j==0) AddToFace(face,facecount,3,I/2); else if (j==n-1) AddToFace(face,facecount,1,I/2); else if (k==0) AddToFace(face,facecount,4,I/2); else if (k==p-1) AddToFace(face,facecount,5,I/2); c.v[I++] = v.v[((i+0)*n+j)*p+k]; c.v[I++] = v.v[((i+1)*n+j)*p+k]; } } } if (I != c.s) dERROR(PETSC_COMM_SELF,1, "Wrong number of edges."); iMesh_createEntArr(mesh,iMesh_LINE_SEGMENT,c.v,c.s, &e.v,&e.a,&e.s, &s.v,&s.a,&s.s,&err);dICHK(mesh,err); err = CommitToFaceSets(mesh,e.v,face,facecount,facesets,entbuf);dCHK(err); if (verbose > 0) {err = PetscViewerASCIIPrintf(viewer,"edge size %d, status size %d\n",e.s,s.s);dCHK(err);} MeshListFree(e); MeshListFree(s); MeshListFree(c); } /* We are done with the master vertex record. */ MeshListFree(v); /* Create boundary sets, these are not related to geometry here */ { dMeshESH wallset,topset,bottomset,senseSet; iBase_TagHandle bdyTag,senseTag; iMesh_getTagHandle(mesh,"NEUMANN_SET",&bdyTag,&err,sizeof("NEUMANN_SET"));dICHK(mesh,err); iMesh_createTag(mesh,"SENSE",1,iBase_INTEGER,&senseTag,&err,sizeof "SENSE");dICHK(mesh,err); iMesh_createEntSet(mesh,0,&wallset,&err);dICHK(mesh,err); iMesh_createEntSet(mesh,0,&topset,&err);dICHK(mesh,err); iMesh_createEntSet(mesh,0,&bottomset,&err);dICHK(mesh,err); iMesh_setEntSetIntData(mesh,wallset,bdyTag,100,&err);dICHK(mesh,err); iMesh_setEntSetIntData(mesh,topset,bdyTag,200,&err);dICHK(mesh,err); iMesh_setEntSetIntData(mesh,bottomset,bdyTag,300,&err);dICHK(mesh,err); for (i=0; i<4; i++) {iMesh_addEntSet(mesh,facesets[i],wallset,&err);dICHK(mesh,err);} iMesh_addEntSet(mesh,facesets[5],topset,&err);dICHK(mesh,err); iMesh_addEntSet(mesh,facesets[4],bottomset,&err);dICHK(mesh,err); /* Deal with SENSE on the walls */ iMesh_createEntSet(mesh,0,&senseSet,&err);dICHK(mesh,err); iMesh_addEntSet(mesh,facesets[2],senseSet,&err);dICHK(mesh,err); iMesh_addEntSet(mesh,facesets[3],senseSet,&err);dICHK(mesh,err); iMesh_setEntSetIntData(mesh,senseSet,senseTag,-1,&err);dICHK(mesh,err); iMesh_addEntSet(mesh,senseSet,wallset,&err);dICHK(mesh,err); /* Deal with SENSE on the bottom */ iMesh_createEntSet(mesh,0,&senseSet,&err);dICHK(mesh,err); iMesh_addEntSet(mesh,facesets[4],senseSet,&err);dICHK(mesh,err); iMesh_setEntSetIntData(mesh,senseSet,senseTag,-1,&err);dICHK(mesh,err); iMesh_addEntSet(mesh,senseSet,bottomset,&err);dICHK(mesh,err); for (i=0; i<6; i++) {err = dFree(face[i]);} err = dFree(entbuf);dCHK(err); } if (do_material) {err = doMaterial(mesh,root);dCHK(err);} /* Add a real valued tag over the vertices. */ if (do_pressure) { static const char *myTagName = "pressure"; iBase_TagHandle myTag; double *myData; iMesh_getEntities(mesh,root,iBase_VERTEX,iMesh_POINT,&v.v,&v.a,&v.s,&err);dICHK(mesh,err); iMesh_createTag(mesh,myTagName,1,iBase_DOUBLE,&myTag,&err,(int)strlen(myTagName));dICHK(mesh,err); err = PetscMalloc(v.s*sizeof(double),&myData);dCHK(err); for (i=0; i<v.s; i++) { myData[i] = 1.0 * i; } iMesh_setDblArrData(mesh,v.v,v.s,myTag,myData,v.s,&err);dICHK(mesh,err); err = PetscFree(myData);dCHK(err); MeshListFree(v); } if (do_uniform) {err = createUniformTags(mesh,root);dCHK(err);} if (do_geom) #ifndef dHAVE_ITAPS_REL dERROR(((dObject)dmesh)->comm,PETSC_ERR_ARG_UNKNOWN_TYPE,"Dohp has not been configured with support for geometry"); #else { const char geom_options[] = ";ENGINE=OCC;"; const char rel_options[] = ""; iGeom_Instance geom; iRel_Instance assoc; iRel_PairHandle pair; iBase_EntityHandle brick; iGeom_newGeom(geom_options,&geom,&err,sizeof geom_options);dIGCHK(geom,err); iRel_create(rel_options,&assoc,&err,sizeof rel_options);dIRCHK(assoc,err); iRel_createPair(assoc,geom,0,iRel_IGEOM_IFACE,iRel_ACTIVE,mesh,1,iRel_IMESH_IFACE,iRel_ACTIVE,&pair,&err);dIGCHK(assoc,err); iGeom_createBrick(geom,box.x1-box.x0,box.y1-box.y0,box.z1-box.z0,&brick,&err);dIGCHK(geom,err); iGeom_moveEnt(geom,brick,0.5*(box.x0+box.x1),0.5*(box.y0+box.y1),0.5*(box.z0+box.z1),&err);dIGCHK(geom,err); if (verbose > 0) {err = BoundingBoxView(geom,brick,"brick",viewer);dCHK(err);} { iBase_EntityHandle gface[6],*gface_p=gface; int gface_a=6,gface_s; iGeom_getEntAdj(geom,brick,2,&gface_p,&gface_a,&gface_s,&err);dIGCHK(geom,err); for (i=0; i<6; i++) { char name[20]; sprintf(name,"face_%d",i); err = BoundingBoxView(geom,gface[i],name,viewer);dCHK(err); } if (assoc_with_brick) { for (i=0; i<6; i++) { iRel_setEntSetRelation(assoc,pair,brick,facesets[i],&err);dIRCHK(assoc,err); } } else { /* Set associations. With the current Lasso implementation, these will not be saved */ iRel_setEntSetRelation(assoc,pair,gface[0],facesets[3],&err);dIRCHK(assoc,err); iRel_setEntSetRelation(assoc,pair,gface[1],facesets[1],&err);dIRCHK(assoc,err); iRel_setEntSetRelation(assoc,pair,gface[2],facesets[0],&err);dIRCHK(assoc,err); iRel_setEntSetRelation(assoc,pair,gface[3],facesets[2],&err);dIRCHK(assoc,err); iRel_setEntSetRelation(assoc,pair,gface[4],facesets[4],&err);dIRCHK(assoc,err); iRel_setEntSetRelation(assoc,pair,gface[5],facesets[5],&err);dIRCHK(assoc,err); } } { dMeshTag meshGlobalIDTag,meshGeomDimTag,geomGlobalIDTag; /* Manually set association tags, these are set so that the associations above can be inferred. */ iMesh_getTagHandle(mesh,"GLOBAL_ID",&meshGlobalIDTag,&err,sizeof "GLOBAL_ID");dICHK(mesh,err); iMesh_getTagHandle(mesh,"GEOM_DIMENSION",&meshGeomDimTag,&err,sizeof "GEOM_DIMENSION");dICHK(mesh,err); iGeom_getTagHandle(geom,"GLOBAL_ID",&geomGlobalIDTag,&err,sizeof "GLOBAL_ID");dIGCHK(geom,err); for (i=0; i<6; i++) { iBase_EntityHandle gface; int gid,gdim; iRel_getSetEntRelation(assoc,pair,facesets[i],1,&gface,&err);dIRCHK(assoc,err); iGeom_getEntType(geom,gface,&gdim,&err);dIGCHK(geom,err); if (gdim != 2) dERROR(PETSC_COMM_SELF,1,"Geometric dimension is %d, expected 2",gdim); iGeom_getIntData(geom,gface,geomGlobalIDTag,&gid,&err);dIGCHK(geom,err); iMesh_setEntSetIntData(mesh,facesets[i],meshGeomDimTag,2,&err);dICHK(mesh,err); /* If the following line is disabled, Lasso will pick up the wrong relations, but at least they will still be with * surfaces. Wouldn't it be better to not find relations? */ iMesh_setEntSetIntData(mesh,facesets[i],meshGlobalIDTag,gid,&err);dICHK(mesh,err); } } err = dMeshSetGeometryRelation(dmesh,geom,assoc);dCHK(err); } #endif dFunctionReturn(0); }
int main(int argc,char **args) { PetscErrorCode ierr; PetscMPIInt rank,size; PetscInt N0=50,N1=20,N=N0*N1,DIM; PetscRandom rdm; PetscScalar a; PetscReal enorm; Vec x,y,z; PetscBool view=PETSC_FALSE,use_interface=PETSC_TRUE; ierr = PetscInitialize(&argc,&args,(char*)0,help);CHKERRQ(ierr); #if !defined(PETSC_USE_COMPLEX) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP, "This example requires complex numbers"); #endif ierr = PetscOptionsBegin(PETSC_COMM_WORLD, NULL, "FFTW Options", "ex143");CHKERRQ(ierr); ierr = PetscOptionsBool("-vec_view draw", "View the vectors", "ex143", view, &view, NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-use_FFTW_interface", "Use PETSc-FFTW interface", "ex143",use_interface, &use_interface, NULL);CHKERRQ(ierr); ierr = PetscOptionsEnd();CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,"-use_FFTW_interface",&use_interface,NULL);CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD, &size);CHKERRQ(ierr); ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank);CHKERRQ(ierr); ierr = PetscRandomCreate(PETSC_COMM_WORLD, &rdm);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rdm);CHKERRQ(ierr); if (!use_interface) { /* Use mpi FFTW without PETSc-FFTW interface, 2D case only */ /*---------------------------------------------------------*/ fftw_plan fplan,bplan; fftw_complex *data_in,*data_out,*data_out2; ptrdiff_t alloc_local,local_n0,local_0_start; DIM = 2; if (!rank) { ierr = PetscPrintf(PETSC_COMM_SELF,"Use FFTW without PETSc-FFTW interface, DIM %D\n",DIM);CHKERRQ(ierr); } fftw_mpi_init(); N = N0*N1; alloc_local = fftw_mpi_local_size_2d(N0,N1,PETSC_COMM_WORLD,&local_n0,&local_0_start); data_in = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*alloc_local); data_out = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*alloc_local); data_out2 = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*alloc_local); ierr = VecCreateMPIWithArray(PETSC_COMM_WORLD,1,(PetscInt)local_n0*N1,(PetscInt)N,(const PetscScalar*)data_in,&x);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) x, "Real Space vector");CHKERRQ(ierr); ierr = VecCreateMPIWithArray(PETSC_COMM_WORLD,1,(PetscInt)local_n0*N1,(PetscInt)N,(const PetscScalar*)data_out,&y);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) y, "Frequency space vector");CHKERRQ(ierr); ierr = VecCreateMPIWithArray(PETSC_COMM_WORLD,1,(PetscInt)local_n0*N1,(PetscInt)N,(const PetscScalar*)data_out2,&z);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) z, "Reconstructed vector");CHKERRQ(ierr); fplan = fftw_mpi_plan_dft_2d(N0,N1,data_in,data_out,PETSC_COMM_WORLD,FFTW_FORWARD,FFTW_ESTIMATE); bplan = fftw_mpi_plan_dft_2d(N0,N1,data_out,data_out2,PETSC_COMM_WORLD,FFTW_BACKWARD,FFTW_ESTIMATE); ierr = VecSetRandom(x, rdm);CHKERRQ(ierr); if (view) {ierr = VecView(x,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);} fftw_execute(fplan); if (view) {ierr = VecView(y,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);} fftw_execute(bplan); /* Compare x and z. FFTW computes an unnormalized DFT, thus z = N*x */ a = 1.0/(PetscReal)N; ierr = VecScale(z,a);CHKERRQ(ierr); if (view) {ierr = VecView(z, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);} ierr = VecAXPY(z,-1.0,x);CHKERRQ(ierr); ierr = VecNorm(z,NORM_1,&enorm);CHKERRQ(ierr); if (enorm > 1.e-11 && !rank) { ierr = PetscPrintf(PETSC_COMM_SELF," Error norm of |x - z| %g\n",(double)enorm);CHKERRQ(ierr); } /* Free spaces */ fftw_destroy_plan(fplan); fftw_destroy_plan(bplan); fftw_free(data_in); ierr = VecDestroy(&x);CHKERRQ(ierr); fftw_free(data_out); ierr = VecDestroy(&y);CHKERRQ(ierr); fftw_free(data_out2);ierr = VecDestroy(&z);CHKERRQ(ierr); } else { /* Use PETSc-FFTW interface */ /*-------------------------------------------*/ PetscInt i,*dim,k; Mat A; N=1; for (i=1; i<5; i++) { DIM = i; ierr = PetscMalloc1(i,&dim);CHKERRQ(ierr); for (k=0; k<i; k++) { dim[k]=30; } N *= dim[i-1]; /* Create FFTW object */ if (!rank) printf("Use PETSc-FFTW interface...%d-DIM: %d\n",(int)DIM,(int)N); ierr = MatCreateFFT(PETSC_COMM_WORLD,DIM,dim,MATFFTW,&A);CHKERRQ(ierr); /* Create vectors that are compatible with parallel layout of A - must call MatCreateVecs()! */ ierr = MatCreateVecsFFTW(A,&x,&y,&z);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) x, "Real space vector");CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) y, "Frequency space vector");CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) z, "Reconstructed vector");CHKERRQ(ierr); /* Set values of space vector x */ ierr = VecSetRandom(x,rdm);CHKERRQ(ierr); if (view) {ierr = VecView(x,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);} /* Apply FFTW_FORWARD and FFTW_BACKWARD */ ierr = MatMult(A,x,y);CHKERRQ(ierr); if (view) {ierr = VecView(y,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);} ierr = MatMultTranspose(A,y,z);CHKERRQ(ierr); /* Compare x and z. FFTW computes an unnormalized DFT, thus z = N*x */ a = 1.0/(PetscReal)N; ierr = VecScale(z,a);CHKERRQ(ierr); if (view) {ierr = VecView(z,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);} ierr = VecAXPY(z,-1.0,x);CHKERRQ(ierr); ierr = VecNorm(z,NORM_1,&enorm);CHKERRQ(ierr); if (enorm > 1.e-9 && !rank) { ierr = PetscPrintf(PETSC_COMM_SELF," Error norm of |x - z| %e\n",enorm);CHKERRQ(ierr); } ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&y);CHKERRQ(ierr); ierr = VecDestroy(&z);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = PetscFree(dim);CHKERRQ(ierr); } } ierr = PetscRandomDestroy(&rdm);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int main(int argc,char **argv) { TS ts; /* time integrator */ TSAdapt adapt; Vec X; /* solution vector */ Mat J; /* Jacobian matrix */ PetscInt steps,maxsteps,ncells,xs,xm,i; PetscErrorCode ierr; PetscReal ftime,dt; char chemfile[PETSC_MAX_PATH_LEN] = "chem.inp",thermofile[PETSC_MAX_PATH_LEN] = "therm.dat"; struct _User user; TSConvergedReason reason; PetscBool showsolutions = PETSC_FALSE; char **snames,*names; Vec lambda; /* used with TSAdjoint for sensitivities */ ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; ierr = PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"Chemistry solver options","");CHKERRQ(ierr); ierr = PetscOptionsString("-chem","CHEMKIN input file","",chemfile,chemfile,sizeof(chemfile),NULL);CHKERRQ(ierr); ierr = PetscOptionsString("-thermo","NASA thermo input file","",thermofile,thermofile,sizeof(thermofile),NULL);CHKERRQ(ierr); user.pressure = 1.01325e5; /* Pascal */ ierr = PetscOptionsReal("-pressure","Pressure of reaction [Pa]","",user.pressure,&user.pressure,NULL);CHKERRQ(ierr); user.Tini = 1550; ierr = PetscOptionsReal("-Tini","Initial temperature [K]","",user.Tini,&user.Tini,NULL);CHKERRQ(ierr); user.diffus = 100; ierr = PetscOptionsReal("-diffus","Diffusion constant","",user.diffus,&user.diffus,NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-draw_solution","Plot the solution for each cell","",showsolutions,&showsolutions,NULL);CHKERRQ(ierr); user.diffusion = PETSC_TRUE; ierr = PetscOptionsBool("-diffusion","Have diffusion","",user.diffusion,&user.diffusion,NULL);CHKERRQ(ierr); user.reactions = PETSC_TRUE; ierr = PetscOptionsBool("-reactions","Have reactions","",user.reactions,&user.reactions,NULL);CHKERRQ(ierr); ierr = PetscOptionsEnd();CHKERRQ(ierr); ierr = TC_initChem(chemfile, thermofile, 0, 1.0);TCCHKERRQ(ierr); user.Nspec = TC_getNspec(); user.Nreac = TC_getNreac(); ierr = DMDACreate1d(PETSC_COMM_WORLD,DM_BOUNDARY_PERIODIC,-1,user.Nspec+1,1,NULL,&user.dm);CHKERRQ(ierr); ierr = DMDAGetInfo(user.dm,NULL,&ncells,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);CHKERRQ(ierr); user.dx = 1.0/ncells; /* Set the coordinates of the cell centers; note final ghost cell is at x coordinate 1.0 */ ierr = DMDASetUniformCoordinates(user.dm,0.0,1.0,0.0,1.0,0.0,1.0);CHKERRQ(ierr); /* set the names of each field in the DMDA based on the species name */ ierr = PetscMalloc1((user.Nspec+1)*LENGTHOFSPECNAME,&names);CHKERRQ(ierr); ierr = PetscStrcpy(names,"Temp");CHKERRQ(ierr); TC_getSnames(user.Nspec,names+LENGTHOFSPECNAME);CHKERRQ(ierr); ierr = PetscMalloc1((user.Nspec+2),&snames);CHKERRQ(ierr); for (i=0; i<user.Nspec+1; i++) snames[i] = names+i*LENGTHOFSPECNAME; snames[user.Nspec+1] = NULL; ierr = DMDASetFieldNames(user.dm,(const char * const *)snames);CHKERRQ(ierr); ierr = PetscFree(snames);CHKERRQ(ierr); ierr = PetscFree(names);CHKERRQ(ierr); ierr = DMCreateMatrix(user.dm,&J);CHKERRQ(ierr); ierr = DMCreateGlobalVector(user.dm,&X);CHKERRQ(ierr); ierr = PetscMalloc3(user.Nspec+1,&user.tchemwork,PetscSqr(user.Nspec+1),&user.Jdense,user.Nspec+1,&user.rows);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create timestepping solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetDM(ts,user.dm);CHKERRQ(ierr); ierr = TSSetType(ts,TSARKIMEX);CHKERRQ(ierr); ierr = TSARKIMEXSetFullyImplicit(ts,PETSC_TRUE);CHKERRQ(ierr); ierr = TSARKIMEXSetType(ts,TSARKIMEX4);CHKERRQ(ierr); ierr = TSSetRHSFunction(ts,NULL,FormRHSFunction,&user);CHKERRQ(ierr); ierr = TSSetRHSJacobian(ts,J,J,FormRHSJacobian,&user);CHKERRQ(ierr); ftime = 1.0; maxsteps = 10000; ierr = TSSetDuration(ts,maxsteps,ftime);CHKERRQ(ierr); ierr = TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set initial conditions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = FormInitialSolution(ts,X,&user);CHKERRQ(ierr); ierr = TSSetSolution(ts,X);CHKERRQ(ierr); dt = 1e-10; /* Initial time step */ ierr = TSSetInitialTimeStep(ts,0.0,dt);CHKERRQ(ierr); ierr = TSGetAdapt(ts,&adapt);CHKERRQ(ierr); ierr = TSAdaptSetStepLimits(adapt,1e-12,1e-4);CHKERRQ(ierr); /* Also available with -ts_adapt_dt_min/-ts_adapt_dt_max */ ierr = TSSetMaxSNESFailures(ts,-1);CHKERRQ(ierr); /* Retry step an unlimited number of times */ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Pass information to graphical monitoring routine - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ if (showsolutions) { ierr = DMDAGetCorners(user.dm,&xs,NULL,NULL,&xm,NULL,NULL);CHKERRQ(ierr); for (i=xs;i<xs+xm;i++) { ierr = MonitorCell(ts,&user,i);CHKERRQ(ierr); } } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetFromOptions(ts);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set final conditions for sensitivities - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMCreateGlobalVector(user.dm,&lambda);CHKERRQ(ierr); ierr = TSSetCostGradients(ts,1,&lambda,NULL);CHKERRQ(ierr); ierr = VecSetValue(lambda,0,1.0,INSERT_VALUES);CHKERRQ(ierr); ierr = VecAssemblyBegin(lambda);CHKERRQ(ierr); ierr = VecAssemblyEnd(lambda);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve ODE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSolve(ts,X);CHKERRQ(ierr); ierr = TSGetSolveTime(ts,&ftime);CHKERRQ(ierr); ierr = TSGetTimeStepNumber(ts,&steps);CHKERRQ(ierr); ierr = TSGetConvergedReason(ts,&reason);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"%s at time %g after %D steps\n",TSConvergedReasons[reason],(double)ftime,steps);CHKERRQ(ierr); { Vec max; const char * const *names; PetscInt i; const PetscReal *bmax; ierr = TSMonitorEnvelopeGetBounds(ts,&max,NULL);CHKERRQ(ierr); if (max) { ierr = TSMonitorLGGetVariableNames(ts,&names);CHKERRQ(ierr); if (names) { ierr = VecGetArrayRead(max,&bmax);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF,"Species - maximum mass fraction\n");CHKERRQ(ierr); for (i=1; i<user.Nspec; i++) { if (bmax[i] > .01) {ierr = PetscPrintf(PETSC_COMM_SELF,"%s %g\n",names[i],bmax[i]);CHKERRQ(ierr);} } ierr = VecRestoreArrayRead(max,&bmax);CHKERRQ(ierr); } } } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ TC_reset(); ierr = DMDestroy(&user.dm);CHKERRQ(ierr); ierr = MatDestroy(&J);CHKERRQ(ierr); ierr = VecDestroy(&X);CHKERRQ(ierr); ierr = VecDestroy(&lambda);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = PetscFree3(user.tchemwork,user.Jdense,user.rows);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
PetscErrorCode SNESSetFromOptions_FAS(PetscOptions *PetscOptionsObject,SNES snes) { SNES_FAS *fas = (SNES_FAS*) snes->data; PetscInt levels = 1; PetscBool flg = PETSC_FALSE, upflg = PETSC_FALSE, downflg = PETSC_FALSE, monflg = PETSC_FALSE, galerkinflg = PETSC_FALSE,continuationflg = PETSC_FALSE; PetscErrorCode ierr; char monfilename[PETSC_MAX_PATH_LEN]; SNESFASType fastype; const char *optionsprefix; SNESLineSearch linesearch; PetscInt m, n_up, n_down; SNES next; PetscBool isFine; PetscFunctionBegin; ierr = SNESFASCycleIsFine(snes, &isFine);CHKERRQ(ierr); ierr = PetscOptionsHead(PetscOptionsObject,"SNESFAS Options-----------------------------------");CHKERRQ(ierr); /* number of levels -- only process most options on the finest level */ if (isFine) { ierr = PetscOptionsInt("-snes_fas_levels", "Number of Levels", "SNESFASSetLevels", levels, &levels, &flg);CHKERRQ(ierr); if (!flg && snes->dm) { ierr = DMGetRefineLevel(snes->dm,&levels);CHKERRQ(ierr); levels++; fas->usedmfornumberoflevels = PETSC_TRUE; } ierr = SNESFASSetLevels(snes, levels, NULL);CHKERRQ(ierr); fastype = fas->fastype; ierr = PetscOptionsEnum("-snes_fas_type","FAS correction type","SNESFASSetType",SNESFASTypes,(PetscEnum)fastype,(PetscEnum*)&fastype,&flg);CHKERRQ(ierr); if (flg) { ierr = SNESFASSetType(snes, fastype);CHKERRQ(ierr); } ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); ierr = PetscOptionsInt("-snes_fas_cycles","Number of cycles","SNESFASSetCycles",fas->n_cycles,&m,&flg);CHKERRQ(ierr); if (flg) { ierr = SNESFASSetCycles(snes, m);CHKERRQ(ierr); } ierr = PetscOptionsBool("-snes_fas_continuation","Corrected grid-sequence continuation","SNESFASSetContinuation",fas->continuation,&continuationflg,&flg);CHKERRQ(ierr); if (flg) { ierr = SNESFASSetContinuation(snes,continuationflg);CHKERRQ(ierr); } ierr = PetscOptionsBool("-snes_fas_galerkin", "Form coarse problems with Galerkin","SNESFASSetGalerkin",fas->galerkin,&galerkinflg,&flg);CHKERRQ(ierr); if (flg) { ierr = SNESFASSetGalerkin(snes, galerkinflg);CHKERRQ(ierr); } if (fas->fastype == SNES_FAS_FULL) { ierr = PetscOptionsBool("-snes_fas_full_downsweep","Smooth on the initial upsweep for full FAS cycles","SNESFASFullSetDownSweep",fas->full_downsweep,&fas->full_downsweep,&flg);CHKERRQ(ierr); if (flg) {SNESFASFullSetDownSweep(snes,fas->full_downsweep);CHKERRQ(ierr);} } ierr = PetscOptionsInt("-snes_fas_smoothup","Number of post-smoothing steps","SNESFASSetNumberSmoothUp",fas->max_up_it,&n_up,&upflg);CHKERRQ(ierr); ierr = PetscOptionsInt("-snes_fas_smoothdown","Number of pre-smoothing steps","SNESFASSetNumberSmoothDown",fas->max_down_it,&n_down,&downflg);CHKERRQ(ierr); ierr = PetscOptionsString("-snes_fas_monitor","Monitor FAS progress","SNESFASSetMonitor","stdout",monfilename,PETSC_MAX_PATH_LEN,&monflg);CHKERRQ(ierr); if (monflg) ierr = SNESFASSetMonitor(snes, PETSC_TRUE);CHKERRQ(ierr); flg = PETSC_FALSE; monflg = PETSC_TRUE; ierr = PetscOptionsBool("-snes_fas_log","Log times for each FAS level","SNESFASSetLog",monflg,&monflg,&flg);CHKERRQ(ierr); if (flg) {ierr = SNESFASSetLog(snes,monflg);CHKERRQ(ierr);} } ierr = PetscOptionsTail();CHKERRQ(ierr); /* setup from the determined types if there is no pointwise procedure or smoother defined */ if (upflg) { ierr = SNESFASSetNumberSmoothUp(snes,n_up);CHKERRQ(ierr); } if (downflg) { ierr = SNESFASSetNumberSmoothDown(snes,n_down);CHKERRQ(ierr); } /* set up the default line search for coarse grid corrections */ if (fas->fastype == SNES_FAS_ADDITIVE) { if (!snes->linesearch) { ierr = SNESGetLineSearch(snes, &linesearch);CHKERRQ(ierr); ierr = SNESLineSearchSetType(linesearch, SNESLINESEARCHL2);CHKERRQ(ierr); } } ierr = SNESFASCycleGetCorrection(snes, &next);CHKERRQ(ierr); /* recursive option setting for the smoothers */ if (next) {ierr = SNESSetFromOptions(next);CHKERRQ(ierr);} PetscFunctionReturn(0); }
int main(int argc,char **args) { Mat Amat; PetscErrorCode ierr; SNES snes; KSP ksp; MPI_Comm comm; PetscMPIInt npe,rank; PetscLogStage stage[7]; PetscBool test_nonzero_cols=PETSC_FALSE,use_nearnullspace=PETSC_TRUE; Vec xx,bb; PetscInt iter,i,N,dim=3,cells[3]={1,1,1},max_conv_its,local_sizes[7],run_type=1; DM dm,distdm,basedm; PetscBool flg; char convType[256]; PetscReal Lx,mdisp[10],err[10]; const char * const options[10] = {"-ex56_dm_refine 0", "-ex56_dm_refine 1", "-ex56_dm_refine 2", "-ex56_dm_refine 3", "-ex56_dm_refine 4", "-ex56_dm_refine 5", "-ex56_dm_refine 6", "-ex56_dm_refine 7", "-ex56_dm_refine 8", "-ex56_dm_refine 9"}; PetscFunctionBeginUser; ierr = PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr; comm = PETSC_COMM_WORLD; ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); ierr = MPI_Comm_size(comm, &npe);CHKERRQ(ierr); /* options */ ierr = PetscOptionsBegin(comm,NULL,"3D bilinear Q1 elasticity options","");CHKERRQ(ierr); { i = 3; ierr = PetscOptionsIntArray("-cells", "Number of (flux tube) processor in each dimension", "ex56.c", cells, &i, NULL);CHKERRQ(ierr); Lx = 1.; /* or ne for rod */ max_conv_its = 3; ierr = PetscOptionsInt("-max_conv_its","Number of iterations in convergence study","",max_conv_its,&max_conv_its,NULL);CHKERRQ(ierr); if (max_conv_its<=0 || max_conv_its>7) SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_USER, "Bad number of iterations for convergence test (%D)",max_conv_its); ierr = PetscOptionsReal("-lx","Length of domain","",Lx,&Lx,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-alpha","material coefficient inside circle","",s_soft_alpha,&s_soft_alpha,NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-test_nonzero_cols","nonzero test","",test_nonzero_cols,&test_nonzero_cols,NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-use_mat_nearnullspace","MatNearNullSpace API test","",use_nearnullspace,&use_nearnullspace,NULL);CHKERRQ(ierr); ierr = PetscOptionsInt("-run_type","0: twisting load on cantalever, 1: 3rd order accurate convergence test","",run_type,&run_type,NULL);CHKERRQ(ierr); i = 3; ierr = PetscOptionsInt("-mat_block_size","","",i,&i,&flg);CHKERRQ(ierr); if (!flg || i!=3) SETERRQ2(PETSC_COMM_WORLD, PETSC_ERR_USER, "'-mat_block_size 3' must be set (%D) and = 3 (%D)",flg,flg? i : 3); } ierr = PetscOptionsEnd();CHKERRQ(ierr); ierr = PetscLogStageRegister("Mesh Setup", &stage[6]);CHKERRQ(ierr); ierr = PetscLogStageRegister("1st Setup", &stage[0]);CHKERRQ(ierr); ierr = PetscLogStageRegister("1st Solve", &stage[1]);CHKERRQ(ierr); /* create DM, Plex calls DMSetup */ ierr = PetscLogStagePush(stage[6]);CHKERRQ(ierr); ierr = DMPlexCreateHexBoxMesh(comm, dim, cells, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, &dm);CHKERRQ(ierr); { DMLabel label; IS is; ierr = DMCreateLabel(dm, "boundary");CHKERRQ(ierr); ierr = DMGetLabel(dm, "boundary", &label);CHKERRQ(ierr); ierr = DMPlexMarkBoundaryFaces(dm, label);CHKERRQ(ierr); if (run_type==0) { ierr = DMGetStratumIS(dm, "boundary", 1, &is);CHKERRQ(ierr); ierr = DMCreateLabel(dm,"Faces");CHKERRQ(ierr); if (is) { PetscInt d, f, Nf; const PetscInt *faces; PetscInt csize; PetscSection cs; Vec coordinates ; DM cdm; ierr = ISGetLocalSize(is, &Nf);CHKERRQ(ierr); ierr = ISGetIndices(is, &faces);CHKERRQ(ierr); ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); ierr = DMGetDefaultSection(cdm, &cs);CHKERRQ(ierr); /* Check for each boundary face if any component of its centroid is either 0.0 or 1.0 */ for (f = 0; f < Nf; ++f) { PetscReal faceCoord; PetscInt b,v; PetscScalar *coords = NULL; PetscInt Nv; ierr = DMPlexVecGetClosure(cdm, cs, coordinates, faces[f], &csize, &coords);CHKERRQ(ierr); Nv = csize/dim; /* Calculate mean coordinate vector */ for (d = 0; d < dim; ++d) { faceCoord = 0.0; for (v = 0; v < Nv; ++v) faceCoord += PetscRealPart(coords[v*dim+d]); faceCoord /= Nv; for (b = 0; b < 2; ++b) { if (PetscAbs(faceCoord - b) < PETSC_SMALL) { /* domain have not been set yet, still [0,1]^3 */ ierr = DMSetLabelValue(dm, "Faces", faces[f], d*2+b+1);CHKERRQ(ierr); } } } ierr = DMPlexVecRestoreClosure(cdm, cs, coordinates, faces[f], &csize, &coords);CHKERRQ(ierr); } ierr = ISRestoreIndices(is, &faces);CHKERRQ(ierr); } ierr = ISDestroy(&is);CHKERRQ(ierr); ierr = DMGetLabel(dm, "Faces", &label);CHKERRQ(ierr); ierr = DMPlexLabelComplete(dm, label);CHKERRQ(ierr); } } { PetscInt dimEmbed, i; PetscInt nCoords; PetscScalar *coords,bounds[] = {0,Lx,-.5,.5,-.5,.5,}; /* x_min,x_max,y_min,y_max */ Vec coordinates; if (run_type==1) { for (i = 0; i < 2*dim; i++) bounds[i] = (i%2) ? 1 : 0; } ierr = DMGetCoordinatesLocal(dm,&coordinates);CHKERRQ(ierr); ierr = DMGetCoordinateDim(dm,&dimEmbed);CHKERRQ(ierr); if (dimEmbed != dim) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"dimEmbed != dim %D",dimEmbed);CHKERRQ(ierr); ierr = VecGetLocalSize(coordinates,&nCoords);CHKERRQ(ierr); if (nCoords % dimEmbed) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Coordinate vector the wrong size");CHKERRQ(ierr); ierr = VecGetArray(coordinates,&coords);CHKERRQ(ierr); for (i = 0; i < nCoords; i += dimEmbed) { PetscInt j; PetscScalar *coord = &coords[i]; for (j = 0; j < dimEmbed; j++) { coord[j] = bounds[2 * j] + coord[j] * (bounds[2 * j + 1] - bounds[2 * j]); } } ierr = VecRestoreArray(coordinates,&coords);CHKERRQ(ierr); ierr = DMSetCoordinatesLocal(dm,coordinates);CHKERRQ(ierr); } /* convert to p4est, and distribute */ ierr = PetscOptionsBegin(comm, "", "Mesh conversion options", "DMPLEX");CHKERRQ(ierr); ierr = PetscOptionsFList("-dm_type","Convert DMPlex to another format (should not be Plex!)","ex56.c",DMList,DMPLEX,convType,256,&flg);CHKERRQ(ierr); ierr = PetscOptionsEnd(); if (flg) { DM newdm; ierr = DMConvert(dm,convType,&newdm);CHKERRQ(ierr); if (newdm) { const char *prefix; PetscBool isForest; ierr = PetscObjectGetOptionsPrefix((PetscObject)dm,&prefix);CHKERRQ(ierr); ierr = PetscObjectSetOptionsPrefix((PetscObject)newdm,prefix);CHKERRQ(ierr); ierr = DMIsForest(newdm,&isForest);CHKERRQ(ierr); if (isForest) { } else SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_USER, "Converted to non Forest?"); ierr = DMDestroy(&dm);CHKERRQ(ierr); dm = newdm; } else SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_USER, "Convert failed?"); } else { /* Plex Distribute mesh over processes */ ierr = DMPlexDistribute(dm, 0, NULL, &distdm);CHKERRQ(ierr); if (distdm) { const char *prefix; ierr = PetscObjectGetOptionsPrefix((PetscObject)dm,&prefix);CHKERRQ(ierr); ierr = PetscObjectSetOptionsPrefix((PetscObject)distdm,prefix);CHKERRQ(ierr); ierr = DMDestroy(&dm);CHKERRQ(ierr); dm = distdm; } } ierr = PetscLogStagePop();CHKERRQ(ierr); basedm = dm; dm = NULL; for (iter=0 ; iter<max_conv_its ; iter++) { ierr = PetscLogStagePush(stage[6]);CHKERRQ(ierr); /* make new DM */ ierr = DMClone(basedm, &dm);CHKERRQ(ierr); ierr = PetscObjectSetOptionsPrefix((PetscObject) dm, "ex56_");CHKERRQ(ierr); ierr = PetscObjectSetName( (PetscObject)dm,"Mesh");CHKERRQ(ierr); ierr = PetscOptionsClearValue(NULL,"-ex56_dm_refine");CHKERRQ(ierr); ierr = PetscOptionsInsertString(NULL,options[iter]);CHKERRQ(ierr); ierr = DMSetFromOptions(dm);CHKERRQ(ierr); /* refinement done here in Plex, p4est */ /* snes */ ierr = SNESCreate(comm, &snes);CHKERRQ(ierr); ierr = SNESSetDM(snes, dm);CHKERRQ(ierr); /* fem */ { const PetscInt Ncomp = dim; const PetscInt components[] = {0,1,2}; const PetscInt Nfid = 1, Npid = 1; const PetscInt fid[] = {1}; /* The fixed faces (x=0) */ const PetscInt pid[] = {2}; /* The faces with loading (x=L_x) */ PetscFE fe; PetscDS prob; DM cdm = dm; ierr = PetscFECreateDefault(dm, dim, dim, PETSC_FALSE, NULL, PETSC_DECIDE, &fe);CHKERRQ(ierr); /* elasticity */ ierr = PetscObjectSetName((PetscObject) fe, "deformation");CHKERRQ(ierr); /* FEM prob */ ierr = DMGetDS(dm, &prob);CHKERRQ(ierr); ierr = PetscDSSetDiscretization(prob, 0, (PetscObject) fe);CHKERRQ(ierr); /* setup problem */ if (run_type==1) { ierr = PetscDSSetJacobian(prob, 0, 0, NULL, NULL, NULL, g3_uu_3d);CHKERRQ(ierr); ierr = PetscDSSetResidual(prob, 0, f0_u_x4, f1_u_3d);CHKERRQ(ierr); } else { ierr = PetscDSSetJacobian(prob, 0, 0, NULL, NULL, NULL, g3_uu_3d_alpha);CHKERRQ(ierr); ierr = PetscDSSetResidual(prob, 0, f0_u, f1_u_3d_alpha);CHKERRQ(ierr); ierr = PetscDSSetBdResidual(prob, 0, f0_bd_u_3d, f1_bd_u);CHKERRQ(ierr); } /* bcs */ if (run_type==1) { PetscInt id = 1; ierr = DMAddBoundary(dm, DM_BC_ESSENTIAL, "wall", "boundary", 0, 0, NULL, (void (*)()) zero, 1, &id, NULL);CHKERRQ(ierr); } else { ierr = PetscDSAddBoundary(prob, DM_BC_ESSENTIAL, "fixed", "Faces", 0, Ncomp, components, (void (*)()) zero, Nfid, fid, NULL);CHKERRQ(ierr); ierr = PetscDSAddBoundary(prob, DM_BC_NATURAL, "traction", "Faces", 0, Ncomp, components, NULL, Npid, pid, NULL);CHKERRQ(ierr); } while (cdm) { ierr = DMSetDS(cdm,prob);CHKERRQ(ierr); ierr = DMGetCoarseDM(cdm, &cdm);CHKERRQ(ierr); } ierr = PetscFEDestroy(&fe);CHKERRQ(ierr); } /* vecs & mat */ ierr = DMCreateGlobalVector(dm,&xx);CHKERRQ(ierr); ierr = VecDuplicate(xx, &bb);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) bb, "b");CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) xx, "u");CHKERRQ(ierr); ierr = DMCreateMatrix(dm, &Amat);CHKERRQ(ierr); ierr = VecGetSize(bb,&N);CHKERRQ(ierr); local_sizes[iter] = N; ierr = PetscPrintf(PETSC_COMM_WORLD,"[%d]%s %d global equations, %d vertices\n",rank,PETSC_FUNCTION_NAME,N,N/dim);CHKERRQ(ierr); if (use_nearnullspace && N/dim > 1) { /* Set up the near null space (a.k.a. rigid body modes) that will be used by the multigrid preconditioner */ DM subdm; MatNullSpace nearNullSpace; PetscInt fields = 0; PetscObject deformation; ierr = DMCreateSubDM(dm, 1, &fields, NULL, &subdm);CHKERRQ(ierr); ierr = DMPlexCreateRigidBody(subdm, &nearNullSpace);CHKERRQ(ierr); ierr = DMGetField(dm, 0, &deformation);CHKERRQ(ierr); ierr = PetscObjectCompose(deformation, "nearnullspace", (PetscObject) nearNullSpace);CHKERRQ(ierr); ierr = DMDestroy(&subdm);CHKERRQ(ierr); ierr = MatNullSpaceDestroy(&nearNullSpace);CHKERRQ(ierr); /* created by DM and destroyed by Mat */ } ierr = DMPlexSetSNESLocalFEM(dm,NULL,NULL,NULL);CHKERRQ(ierr); ierr = SNESSetJacobian(snes, Amat, Amat, NULL, NULL);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); ierr = DMSetUp(dm);CHKERRQ(ierr); ierr = PetscLogStagePop();CHKERRQ(ierr); ierr = PetscLogStagePush(stage[0]);CHKERRQ(ierr); /* ksp */ ierr = SNESGetKSP(snes, &ksp);CHKERRQ(ierr); ierr = KSPSetComputeSingularValues(ksp,PETSC_TRUE);CHKERRQ(ierr); /* test BCs */ ierr = VecZeroEntries(xx);CHKERRQ(ierr); if (test_nonzero_cols) { if (rank==0) ierr = VecSetValue(xx,0,1.0,INSERT_VALUES);CHKERRQ(ierr); ierr = VecAssemblyBegin(xx);CHKERRQ(ierr); ierr = VecAssemblyEnd(xx);CHKERRQ(ierr); } ierr = VecZeroEntries(bb);CHKERRQ(ierr); ierr = VecGetSize(bb,&i);CHKERRQ(ierr); local_sizes[iter] = i; ierr = PetscPrintf(PETSC_COMM_WORLD,"[%d]%s %d equations in vector, %d vertices\n",rank,PETSC_FUNCTION_NAME,i,i/dim);CHKERRQ(ierr); /* setup solver, dummy solve to really setup */ if (0) { ierr = KSPSetTolerances(ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); ierr = SNESSolve(snes, bb, xx);CHKERRQ(ierr); ierr = KSPSetTolerances(ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,50);CHKERRQ(ierr); ierr = VecZeroEntries(xx);CHKERRQ(ierr); } ierr = PetscLogStagePop();CHKERRQ(ierr); /* solve */ ierr = PetscLogStagePush(stage[1]);CHKERRQ(ierr); ierr = SNESSolve(snes, bb, xx);CHKERRQ(ierr); ierr = PetscLogStagePop();CHKERRQ(ierr); ierr = VecNorm(xx,NORM_INFINITY,&mdisp[iter]);CHKERRQ(ierr); ierr = DMViewFromOptions(dm, NULL, "-dm_view");CHKERRQ(ierr); { PetscViewer viewer = NULL; PetscViewerFormat fmt; ierr = PetscOptionsGetViewer(comm,"ex56_","-vec_view",&viewer,&fmt,&flg);CHKERRQ(ierr); if (flg) { ierr = PetscViewerPushFormat(viewer,fmt);CHKERRQ(ierr); ierr = VecView(xx,viewer);CHKERRQ(ierr); ierr = VecView(bb,viewer);CHKERRQ(ierr); ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); } ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); } /* Free work space */ ierr = DMDestroy(&dm);CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = VecDestroy(&xx);CHKERRQ(ierr); ierr = VecDestroy(&bb);CHKERRQ(ierr); ierr = MatDestroy(&Amat);CHKERRQ(ierr); } ierr = DMDestroy(&basedm);CHKERRQ(ierr); if (run_type==1) { err[0] = 59.975208 - mdisp[0]; /* error with what I think is the exact solution */ } else { err[0] = 171.038 - mdisp[0]; } for (iter=1 ; iter<max_conv_its ; iter++) { if (run_type==1) { err[iter] = 59.975208 - mdisp[iter]; } else { err[iter] = 171.038 - mdisp[iter]; } PetscPrintf(PETSC_COMM_WORLD,"[%d]%s %D) N=%12D, max displ=%9.7e, disp diff=%9.2e, error=%4.3e, rate=%3.2g\n", rank,PETSC_FUNCTION_NAME,iter,local_sizes[iter],mdisp[iter], mdisp[iter]-mdisp[iter-1],err[iter],log(err[iter-1]/err[iter])/log(2.)); } ierr = PetscFinalize(); return ierr; }
PetscErrorCode CholmodStart(Mat F) { PetscErrorCode ierr; Mat_CHOLMOD *chol=(Mat_CHOLMOD*)F->spptr; cholmod_common *c; PetscBool flg; PetscFunctionBegin; if (chol->common) PetscFunctionReturn(0); ierr = PetscMalloc(sizeof(*chol->common),&chol->common);CHKERRQ(ierr); ierr = !cholmod_X_start(chol->common);CHKERRQ(ierr); c = chol->common; c->error_handler = CholmodErrorHandler; #define CHOLMOD_OPTION_DOUBLE(name,help) do { \ PetscReal tmp = (PetscReal)c->name; \ ierr = PetscOptionsReal("-mat_cholmod_" #name,help,"None",tmp,&tmp,0);CHKERRQ(ierr); \ c->name = (double)tmp; \ } while (0) #define CHOLMOD_OPTION_INT(name,help) do { \ PetscInt tmp = (PetscInt)c->name; \ ierr = PetscOptionsInt("-mat_cholmod_" #name,help,"None",tmp,&tmp,0);CHKERRQ(ierr); \ c->name = (int)tmp; \ } while (0) #define CHOLMOD_OPTION_SIZE_T(name,help) do { \ PetscInt tmp = (PetscInt)c->name; \ ierr = PetscOptionsInt("-mat_cholmod_" #name,help,"None",tmp,&tmp,0);CHKERRQ(ierr); \ if (tmp < 0) SETERRQ(((PetscObject)F)->comm,PETSC_ERR_ARG_OUTOFRANGE,"value must be positive"); \ c->name = (size_t)tmp; \ } while (0) #define CHOLMOD_OPTION_TRUTH(name,help) do { \ PetscBool tmp = (PetscBool)!!c->name; \ ierr = PetscOptionsBool("-mat_cholmod_" #name,help,"None",tmp,&tmp,0);CHKERRQ(ierr); \ c->name = (int)tmp; \ } while (0) ierr = PetscOptionsBegin(((PetscObject)F)->comm,((PetscObject)F)->prefix,"CHOLMOD Options","Mat");CHKERRQ(ierr); /* CHOLMOD handles first-time packing and refactor-packing separately, but we usually want them to be the same. */ chol->pack = (PetscBool)c->final_pack; ierr = PetscOptionsBool("-mat_cholmod_pack","Pack factors after factorization [disable for frequent repeat factorization]","None",chol->pack,&chol->pack,0);CHKERRQ(ierr); c->final_pack = (int)chol->pack; CHOLMOD_OPTION_DOUBLE(dbound,"Minimum absolute value of diagonal entries of D"); CHOLMOD_OPTION_DOUBLE(grow0,"Global growth ratio when factors are modified"); CHOLMOD_OPTION_DOUBLE(grow1,"Column growth ratio when factors are modified"); CHOLMOD_OPTION_SIZE_T(grow2,"Affine column growth constant when factors are modified"); CHOLMOD_OPTION_SIZE_T(maxrank,"Max rank of update, larger values are faster but use more memory [2,4,8]"); { static const char *const list[] = {"SIMPLICIAL","AUTO","SUPERNODAL","MatCholmodFactorType","MAT_CHOLMOD_FACTOR_",0}; PetscEnum choice = (PetscEnum)c->supernodal; ierr = PetscOptionsEnum("-mat_cholmod_factor","Factorization method","None",list,(PetscEnum)c->supernodal,&choice,0);CHKERRQ(ierr); c->supernodal = (int)choice; } if (c->supernodal) CHOLMOD_OPTION_DOUBLE(supernodal_switch,"flop/nnz_L threshold for switching to supernodal factorization"); CHOLMOD_OPTION_TRUTH(final_asis,"Leave factors \"as is\""); CHOLMOD_OPTION_TRUTH(final_pack,"Pack the columns when finished (use FALSE if the factors will be updated later)"); if (!c->final_asis) { CHOLMOD_OPTION_TRUTH(final_super,"Leave supernodal factors instead of converting to simplicial"); CHOLMOD_OPTION_TRUTH(final_ll,"Turn LDL' factorization into LL'"); CHOLMOD_OPTION_TRUTH(final_monotonic,"Ensure columns are monotonic when done"); CHOLMOD_OPTION_TRUTH(final_resymbol,"Remove numerically zero values resulting from relaxed supernodal amalgamation"); } { PetscReal tmp[] = {(PetscReal)c->zrelax[0],(PetscReal)c->zrelax[1],(PetscReal)c->zrelax[2]}; PetscInt n = 3; ierr = PetscOptionsRealArray("-mat_cholmod_zrelax","3 real supernodal relaxed amalgamation parameters","None",tmp,&n,&flg);CHKERRQ(ierr); if (flg && n != 3) SETERRQ(((PetscObject)F)->comm,PETSC_ERR_ARG_OUTOFRANGE,"must provide exactly 3 parameters to -mat_cholmod_zrelax"); if (flg) while (n--) c->zrelax[n] = (double)tmp[n]; } { PetscInt n,tmp[] = {(PetscInt)c->nrelax[0],(PetscInt)c->nrelax[1],(PetscInt)c->nrelax[2]}; ierr = PetscOptionsIntArray("-mat_cholmod_nrelax","3 size_t supernodal relaxed amalgamation parameters","None",tmp,&n,&flg);CHKERRQ(ierr); if (flg && n != 3) SETERRQ(((PetscObject)F)->comm,PETSC_ERR_ARG_OUTOFRANGE,"must provide exactly 3 parameters to -mat_cholmod_nrelax"); if (flg) while (n--) c->nrelax[n] = (size_t)tmp[n]; } CHOLMOD_OPTION_TRUTH(prefer_upper,"Work with upper triangular form [faster when using fill-reducing ordering, slower in natural ordering]"); CHOLMOD_OPTION_TRUTH(default_nesdis,"Use NESDIS instead of METIS for nested dissection"); CHOLMOD_OPTION_INT(print,"Verbosity level"); ierr = PetscOptionsEnd();CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@ KSPSetFromOptions - Sets KSP options from the options database. This routine must be called before KSPSetUp() if the user is to be allowed to set the Krylov type. Collective on KSP Input Parameters: . ksp - the Krylov space context Options Database Keys: + -ksp_max_it - maximum number of linear iterations . -ksp_rtol rtol - relative tolerance used in default determination of convergence, i.e. if residual norm decreases by this factor than convergence is declared . -ksp_atol abstol - absolute tolerance used in default convergence test, i.e. if residual norm is less than this then convergence is declared . -ksp_divtol tol - if residual norm increases by this factor than divergence is declared . -ksp_converged_use_initial_residual_norm - see KSPConvergedDefaultSetUIRNorm() . -ksp_converged_use_min_initial_residual_norm - see KSPConvergedDefaultSetUMIRNorm() . -ksp_norm_type - none - skip norms used in convergence tests (useful only when not using convergence test (say you always want to run with 5 iterations) to save on communication overhead preconditioned - default for left preconditioning unpreconditioned - see KSPSetNormType() natural - see KSPSetNormType() . -ksp_check_norm_iteration it - do not compute residual norm until iteration number it (does compute at 0th iteration) works only for PCBCGS, PCIBCGS and and PCCG . -ksp_lag_norm - compute the norm of the residual for the ith iteration on the i+1 iteration; this means that one can use the norm of the residual for convergence test WITHOUT an extra MPI_Allreduce() limiting global synchronizations. This will require 1 more iteration of the solver than usual. . -ksp_fischer_guess <model,size> - uses the Fischer initial guess generator for repeated linear solves . -ksp_constant_null_space - assume the operator (matrix) has the constant vector in its null space . -ksp_test_null_space - tests the null space set with KSPSetNullSpace() to see if it truly is a null space . -ksp_knoll - compute initial guess by applying the preconditioner to the right hand side . -ksp_monitor_cancel - cancel all previous convergene monitor routines set . -ksp_monitor <optional filename> - print residual norm at each iteration . -ksp_monitor_lg_residualnorm - plot residual norm at each iteration . -ksp_monitor_solution - plot solution at each iteration - -ksp_monitor_singular_value - monitor extremem singular values at each iteration Notes: To see all options, run your program with the -help option or consult Users-Manual: ch_ksp Level: beginner .keywords: KSP, set, from, options, database .seealso: KSPSetUseFischerGuess() @*/ PetscErrorCode KSPSetFromOptions(KSP ksp) { PetscErrorCode ierr; PetscInt indx; const char *convtests[] = {"default","skip"}; char type[256], monfilename[PETSC_MAX_PATH_LEN]; PetscViewer monviewer; PetscBool flg,flag,reuse; PetscInt model[2]={0,0},nmax; KSPNormType normtype; PCSide pcside; void *ctx; PetscFunctionBegin; PetscValidHeaderSpecific(ksp,KSP_CLASSID,1); if (!ksp->pc) {ierr = KSPGetPC(ksp,&ksp->pc);CHKERRQ(ierr);} ierr = PCSetFromOptions(ksp->pc);CHKERRQ(ierr); if (!KSPRegisterAllCalled) {ierr = KSPRegisterAll();CHKERRQ(ierr);} ierr = PetscObjectOptionsBegin((PetscObject)ksp);CHKERRQ(ierr); ierr = PetscOptionsFList("-ksp_type","Krylov method","KSPSetType",KSPList,(char*)(((PetscObject)ksp)->type_name ? ((PetscObject)ksp)->type_name : KSPGMRES),type,256,&flg);CHKERRQ(ierr); if (flg) { ierr = KSPSetType(ksp,type);CHKERRQ(ierr); } /* Set the type if it was never set. */ if (!((PetscObject)ksp)->type_name) { ierr = KSPSetType(ksp,KSPGMRES);CHKERRQ(ierr); } ierr = PetscOptionsInt("-ksp_max_it","Maximum number of iterations","KSPSetTolerances",ksp->max_it,&ksp->max_it,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-ksp_rtol","Relative decrease in residual norm","KSPSetTolerances",ksp->rtol,&ksp->rtol,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-ksp_atol","Absolute value of residual norm","KSPSetTolerances",ksp->abstol,&ksp->abstol,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-ksp_divtol","Residual norm increase cause divergence","KSPSetTolerances",ksp->divtol,&ksp->divtol,NULL);CHKERRQ(ierr); flag = PETSC_FALSE; ierr = PetscOptionsBool("-ksp_converged_use_initial_residual_norm","Use initial residual residual norm for computing relative convergence","KSPConvergedDefaultSetUIRNorm",flag,&flag,NULL);CHKERRQ(ierr); if (flag) {ierr = KSPConvergedDefaultSetUIRNorm(ksp);CHKERRQ(ierr);} flag = PETSC_FALSE; ierr = PetscOptionsBool("-ksp_converged_use_min_initial_residual_norm","Use minimum of initial residual norm and b for computing relative convergence","KSPConvergedDefaultSetUMIRNorm",flag,&flag,NULL);CHKERRQ(ierr); if (flag) {ierr = KSPConvergedDefaultSetUMIRNorm(ksp);CHKERRQ(ierr);} ierr = KSPGetInitialGuessNonzero(ksp,&flag);CHKERRQ(ierr); ierr = PetscOptionsBool("-ksp_initial_guess_nonzero","Use the contents of the solution vector for initial guess","KSPSetInitialNonzero",flag,&flag,&flg);CHKERRQ(ierr); if (flg) { ierr = KSPSetInitialGuessNonzero(ksp,flag);CHKERRQ(ierr); } ierr = PCGetReusePreconditioner(ksp->pc,&reuse);CHKERRQ(ierr); ierr = PetscOptionsBool("-ksp_reuse_preconditioner","Use initial preconditioner and don't ever compute a new one ","KSPReusePreconditioner",reuse,&reuse,NULL);CHKERRQ(ierr); ierr = KSPSetReusePreconditioner(ksp,reuse);CHKERRQ(ierr); ierr = PetscOptionsBool("-ksp_knoll","Use preconditioner applied to b for initial guess","KSPSetInitialGuessKnoll",ksp->guess_knoll,&ksp->guess_knoll,NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-ksp_error_if_not_converged","Generate error if solver does not converge","KSPSetErrorIfNotConverged",ksp->errorifnotconverged,&ksp->errorifnotconverged,NULL);CHKERRQ(ierr); nmax = 2; ierr = PetscOptionsIntArray("-ksp_fischer_guess","Use Paul Fischer's algorithm for initial guess","KSPSetUseFischerGuess",model,&nmax,&flag);CHKERRQ(ierr); if (flag) { if (nmax != 2) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_ARG_OUTOFRANGE,"Must pass in model,size as arguments"); ierr = KSPSetUseFischerGuess(ksp,model[0],model[1]);CHKERRQ(ierr); } ierr = PetscOptionsEList("-ksp_convergence_test","Convergence test","KSPSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr); if (flg) { switch (indx) { case 0: ierr = KSPConvergedDefaultCreate(&ctx);CHKERRQ(ierr); ierr = KSPSetConvergenceTest(ksp,KSPConvergedDefault,ctx,KSPConvergedDefaultDestroy);CHKERRQ(ierr); break; case 1: ierr = KSPSetConvergenceTest(ksp,KSPConvergedSkip,NULL,NULL);CHKERRQ(ierr); break; } } ierr = KSPSetUpNorms_Private(ksp,&normtype,&pcside);CHKERRQ(ierr); ierr = PetscOptionsEnum("-ksp_norm_type","KSP Norm type","KSPSetNormType",KSPNormTypes,(PetscEnum)normtype,(PetscEnum*)&normtype,&flg);CHKERRQ(ierr); if (flg) { ierr = KSPSetNormType(ksp,normtype);CHKERRQ(ierr); } ierr = PetscOptionsInt("-ksp_check_norm_iteration","First iteration to compute residual norm","KSPSetCheckNormIteration",ksp->chknorm,&ksp->chknorm,NULL);CHKERRQ(ierr); flag = ksp->lagnorm; ierr = PetscOptionsBool("-ksp_lag_norm","Lag the calculation of the residual norm","KSPSetLagNorm",flag,&flag,&flg);CHKERRQ(ierr); if (flg) { ierr = KSPSetLagNorm(ksp,flag);CHKERRQ(ierr); } ierr = KSPGetDiagonalScale(ksp,&flag);CHKERRQ(ierr); ierr = PetscOptionsBool("-ksp_diagonal_scale","Diagonal scale matrix before building preconditioner","KSPSetDiagonalScale",flag,&flag,&flg);CHKERRQ(ierr); if (flg) { ierr = KSPSetDiagonalScale(ksp,flag);CHKERRQ(ierr); } ierr = KSPGetDiagonalScaleFix(ksp,&flag);CHKERRQ(ierr); ierr = PetscOptionsBool("-ksp_diagonal_scale_fix","Fix diagonally scaled matrix after solve","KSPSetDiagonalScaleFix",flag,&flag,&flg);CHKERRQ(ierr); if (flg) { ierr = KSPSetDiagonalScaleFix(ksp,flag);CHKERRQ(ierr); } flg = PETSC_FALSE; ierr = PetscOptionsBool("-ksp_constant_null_space","Add constant null space to Krylov solver","KSPSetNullSpace",flg,&flg,NULL);CHKERRQ(ierr); if (flg) { MatNullSpace nsp; ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)ksp),PETSC_TRUE,0,0,&nsp);CHKERRQ(ierr); ierr = KSPSetNullSpace(ksp,nsp);CHKERRQ(ierr); ierr = MatNullSpaceDestroy(&nsp);CHKERRQ(ierr); } /* option is actually checked in KSPSetUp(), just here so goes into help message */ if (ksp->nullsp) { ierr = PetscOptionsName("-ksp_test_null_space","Is provided null space correct","None",&flg);CHKERRQ(ierr); } /* Prints reason for convergence or divergence of each linear solve */ flg = PETSC_FALSE; ierr = PetscOptionsBool("-ksp_converged_reason","Print reason for converged or diverged","KSPSolve",flg,&flg,NULL);CHKERRQ(ierr); if (flg) ksp->printreason = PETSC_TRUE; flg = PETSC_FALSE; ierr = PetscOptionsBool("-ksp_monitor_cancel","Remove any hardwired monitor routines","KSPMonitorCancel",flg,&flg,NULL);CHKERRQ(ierr); /* -----------------------------------------------------------------------*/ /* Cancels all monitors hardwired into code before call to KSPSetFromOptions() */ if (flg) { ierr = KSPMonitorCancel(ksp);CHKERRQ(ierr); } /* Prints preconditioned residual norm at each iteration */ ierr = PetscOptionsString("-ksp_monitor","Monitor preconditioned residual norm","KSPMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); if (flg) { ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)ksp),monfilename,&monviewer);CHKERRQ(ierr); ierr = KSPMonitorSet(ksp,KSPMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); } /* Prints preconditioned residual norm at each iteration */ ierr = PetscOptionsString("-ksp_monitor_range","Monitor percent of residual entries more than 10 percent of max","KSPMonitorRange","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); if (flg) { ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)ksp),monfilename,&monviewer);CHKERRQ(ierr); ierr = KSPMonitorSet(ksp,KSPMonitorRange,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); } ierr = PetscObjectTypeCompare((PetscObject)ksp->pc,PCKSP,&flg);CHKERRQ(ierr); ierr = PetscObjectTypeCompare((PetscObject)ksp->pc,PCBJACOBI,&flag);CHKERRQ(ierr); if (flg || flag) { /* A hack for using dynamic tolerance in preconditioner */ ierr = PetscOptionsString("-sub_ksp_dynamic_tolerance","Use dynamic tolerance for PC if PC is a KSP","KSPMonitorDynamicTolerance","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); if (flg) { KSPDynTolCtx *scale = NULL; PetscReal defaultv = 1.0; ierr = PetscMalloc1(1,&scale);CHKERRQ(ierr); scale->bnrm = -1.0; scale->coef = defaultv; ierr = PetscOptionsReal("-sub_ksp_dynamic_tolerance_param","Parameter of dynamic tolerance for inner PCKSP","KSPMonitorDynamicToleranceParam",defaultv,&(scale->coef),&flg);CHKERRQ(ierr); ierr = KSPMonitorSet(ksp,KSPMonitorDynamicTolerance,scale,KSPMonitorDynamicToleranceDestroy);CHKERRQ(ierr); } } /* Plots the vector solution */ flg = PETSC_FALSE; ierr = PetscOptionsBool("-ksp_monitor_solution","Monitor solution graphically","KSPMonitorSet",flg,&flg,NULL);CHKERRQ(ierr); if (flg) { ierr = KSPMonitorSet(ksp,KSPMonitorSolution,NULL,NULL);CHKERRQ(ierr); } /* Prints preconditioned and true residual norm at each iteration */ ierr = PetscOptionsString("-ksp_monitor_true_residual","Monitor true residual norm","KSPMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); if (flg) { ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)ksp),monfilename,&monviewer);CHKERRQ(ierr); ierr = KSPMonitorSet(ksp,KSPMonitorTrueResidualNorm,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); } /* Prints with max norm at each iteration */ ierr = PetscOptionsString("-ksp_monitor_max","Monitor true residual max norm","KSPMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); if (flg) { ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)ksp),monfilename,&monviewer);CHKERRQ(ierr); ierr = KSPMonitorSet(ksp,KSPMonitorTrueResidualMaxNorm,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); } /* Prints extreme eigenvalue estimates at each iteration */ ierr = PetscOptionsString("-ksp_monitor_singular_value","Monitor singular values","KSPMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); if (flg) { ierr = KSPSetComputeSingularValues(ksp,PETSC_TRUE);CHKERRQ(ierr); ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)ksp),monfilename,&monviewer);CHKERRQ(ierr); ierr = KSPMonitorSet(ksp,KSPMonitorSingularValue,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); } /* Prints preconditioned residual norm with fewer digits */ ierr = PetscOptionsString("-ksp_monitor_short","Monitor preconditioned residual norm with fewer digits","KSPMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); if (flg) { ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)ksp),monfilename,&monviewer);CHKERRQ(ierr); ierr = KSPMonitorSet(ksp,KSPMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); } /* Calls Python function */ ierr = PetscOptionsString("-ksp_monitor_python","Use Python function","KSPMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); if (flg) {ierr = PetscPythonMonitorSet((PetscObject)ksp,monfilename);CHKERRQ(ierr);} /* Graphically plots preconditioned residual norm */ flg = PETSC_FALSE; ierr = PetscOptionsBool("-ksp_monitor_lg_residualnorm","Monitor graphically preconditioned residual norm","KSPMonitorSet",flg,&flg,NULL);CHKERRQ(ierr); if (flg) { PetscDrawLG ctx; ierr = KSPMonitorLGResidualNormCreate(0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&ctx);CHKERRQ(ierr); ierr = KSPMonitorSet(ksp,KSPMonitorLGResidualNorm,ctx,(PetscErrorCode (*)(void**))KSPMonitorLGResidualNormDestroy);CHKERRQ(ierr); } /* Graphically plots preconditioned and true residual norm */ flg = PETSC_FALSE; ierr = PetscOptionsBool("-ksp_monitor_lg_true_residualnorm","Monitor graphically true residual norm","KSPMonitorSet",flg,&flg,NULL);CHKERRQ(ierr); if (flg) { PetscDrawLG ctx; ierr = KSPMonitorLGTrueResidualNormCreate(PetscObjectComm((PetscObject)ksp),0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&ctx);CHKERRQ(ierr); ierr = KSPMonitorSet(ksp,KSPMonitorLGTrueResidualNorm,ctx,(PetscErrorCode (*)(void**))KSPMonitorLGTrueResidualNormDestroy);CHKERRQ(ierr); } /* Graphically plots preconditioned residual norm and range of residual element values */ flg = PETSC_FALSE; ierr = PetscOptionsBool("-ksp_monitor_lg_range","Monitor graphically range of preconditioned residual norm","KSPMonitorSet",flg,&flg,NULL);CHKERRQ(ierr); if (flg) { PetscViewer ctx; ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)ksp),0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&ctx);CHKERRQ(ierr); ierr = KSPMonitorSet(ksp,KSPMonitorLGRange,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); } #if defined(PETSC_HAVE_SAWS) /* Publish convergence information using AMS */ flg = PETSC_FALSE; ierr = PetscOptionsBool("-ksp_monitor_saws","Publish KSP progress using SAWs","KSPMonitorSet",flg,&flg,NULL);CHKERRQ(ierr); if (flg) { void *ctx; ierr = KSPMonitorSAWsCreate(ksp,&ctx);CHKERRQ(ierr); ierr = KSPMonitorSet(ksp,KSPMonitorSAWs,ctx,KSPMonitorSAWsDestroy);CHKERRQ(ierr); ierr = KSPSetComputeSingularValues(ksp,PETSC_TRUE);CHKERRQ(ierr); } #endif /* -----------------------------------------------------------------------*/ ierr = KSPSetUpNorms_Private(ksp,&normtype,&pcside);CHKERRQ(ierr); ierr = PetscOptionsEnum("-ksp_pc_side","KSP preconditioner side","KSPSetPCSide",PCSides,(PetscEnum)pcside,(PetscEnum*)&pcside,&flg);CHKERRQ(ierr); if (flg) {ierr = KSPSetPCSide(ksp,pcside);CHKERRQ(ierr);} flg = PETSC_FALSE; ierr = PetscOptionsBool("-ksp_compute_singularvalues","Compute singular values of preconditioned operator","KSPSetComputeSingularValues",flg,&flg,NULL);CHKERRQ(ierr); if (flg) { ierr = KSPSetComputeSingularValues(ksp,PETSC_TRUE);CHKERRQ(ierr); } flg = PETSC_FALSE; ierr = PetscOptionsBool("-ksp_compute_eigenvalues","Compute eigenvalues of preconditioned operator","KSPSetComputeSingularValues",flg,&flg,NULL);CHKERRQ(ierr); if (flg) { ierr = KSPSetComputeSingularValues(ksp,PETSC_TRUE);CHKERRQ(ierr); } flg = PETSC_FALSE; ierr = PetscOptionsBool("-ksp_plot_eigenvalues","Scatter plot extreme eigenvalues","KSPSetComputeSingularValues",flg,&flg,NULL);CHKERRQ(ierr); if (flg) { ierr = KSPSetComputeSingularValues(ksp,PETSC_TRUE);CHKERRQ(ierr); } #if defined(PETSC_HAVE_SAWS) { PetscBool set; flg = PETSC_FALSE; ierr = PetscOptionsBool("-ksp_saws_block","Block for SAWs at end of KSPSolve","PetscObjectSAWsBlock",((PetscObject)ksp)->amspublishblock,&flg,&set);CHKERRQ(ierr); if (set) { ierr = PetscObjectSAWsSetBlock((PetscObject)ksp,flg);CHKERRQ(ierr); } } #endif if (ksp->ops->setfromoptions) { ierr = (*ksp->ops->setfromoptions)(ksp);CHKERRQ(ierr); } /* process any options handlers added with PetscObjectAddOptionsHandler() */ ierr = PetscObjectProcessOptionsHandlers((PetscObject)ksp);CHKERRQ(ierr); ierr = PetscOptionsEnd();CHKERRQ(ierr); PetscFunctionReturn(0); }