/* Sets up a monitor that will display He as a function of space and cluster size for each time step */ PetscErrorCode MyMonitorSetUp(TS ts) { DM da; PetscErrorCode ierr; PetscInt xi,xs,xm,*idx,M,xj,cnt = 0,dof = 3*N + N*N; const PetscInt *lx; Vec C; MyMonitorCtx *ctx; PetscBool flg; IS is; char ycoor[32]; PetscReal valuebounds[4] = {0, 1.2, 0, 1.2}; PetscFunctionBeginUser; ierr = PetscOptionsHasName(PETSC_NULL,"-mymonitor",&flg);CHKERRQ(ierr); if (!flg) PetscFunctionReturn(0); ierr = TSGetDM(ts,&da);CHKERRQ(ierr); ierr = PetscNew(MyMonitorCtx,&ctx);CHKERRQ(ierr); ierr = PetscViewerDrawOpen(((PetscObject)da)->comm,PETSC_NULL,"",PETSC_DECIDE,PETSC_DECIDE,600,400,&ctx->viewer);CHKERRQ(ierr); ierr = DMDAGetCorners(da,&xs,PETSC_NULL,PETSC_NULL,&xm,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); ierr = DMDAGetInfo(da,PETSC_IGNORE,&M,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);CHKERRQ(ierr); ierr = DMDAGetOwnershipRanges(da,&lx,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); ierr = DMDACreate2d(((PetscObject)da)->comm,DMDA_BOUNDARY_NONE,DMDA_BOUNDARY_NONE,DMDA_STENCIL_STAR,M,N,PETSC_DETERMINE,1,2,1,lx,PETSC_NULL,&ctx->da);CHKERRQ(ierr); ierr = DMDASetFieldName(ctx->da,0,"He");CHKERRQ(ierr); ierr = DMDASetFieldName(ctx->da,1,"V");CHKERRQ(ierr); ierr = DMDASetCoordinateName(ctx->da,0,"X coordinate direction");CHKERRQ(ierr); ierr = PetscSNPrintf(ycoor,32,"%D ... Cluster size ... 1",N);CHKERRQ(ierr); ierr = DMDASetCoordinateName(ctx->da,1,ycoor);CHKERRQ(ierr); ierr = DMCreateGlobalVector(ctx->da,&ctx->He);CHKERRQ(ierr); ierr = PetscMalloc(2*N*xm*sizeof(PetscInt),&idx);CHKERRQ(ierr); cnt = 0; for (xj=0; xj<N; xj++) { for (xi=xs; xi<xs+xm; xi++) { idx[cnt++] = dof*xi + xj; idx[cnt++] = dof*xi + xj + N; } } ierr = ISCreateGeneral(((PetscObject)ts)->comm,2*N*xm,idx,PETSC_OWN_POINTER,&is);CHKERRQ(ierr); ierr = TSGetSolution(ts,&C);CHKERRQ(ierr); ierr = VecScatterCreate(C,is,ctx->He,PETSC_NULL,&ctx->scatter);CHKERRQ(ierr); ierr = ISDestroy(&is);CHKERRQ(ierr); /* sets the bounds on the contour plot values so the colors mean the same thing for different timesteps */ ierr = PetscViewerDrawSetBounds(ctx->viewer,2,valuebounds);CHKERRQ(ierr); ierr = TSMonitorSet(ts,MyMonitorMonitor,ctx,MyMonitorDestroy);CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc,char **argv) { KSP ksp; DM da; UserContext user; const char *bcTypes[2] = {"dirichlet","neumann"}; PetscErrorCode ierr; PetscInt bc; Vec b,x; PetscInitialize(&argc,&argv,(char *)0,help); ierr = KSPCreate(PETSC_COMM_WORLD,&ksp); CHKERRQ(ierr); ierr = DMDACreate2d(PETSC_COMM_WORLD, DMDA_BOUNDARY_NONE, DMDA_BOUNDARY_NONE,DMDA_STENCIL_STAR,-3,-3,PETSC_DECIDE,PETSC_DECIDE,1,1,0,0,&da); CHKERRQ(ierr); ierr = DMDASetUniformCoordinates(da,0,1,0,1,0,0); CHKERRQ(ierr); ierr = DMDASetFieldName(da,0,"Pressure"); CHKERRQ(ierr); ierr = PetscOptionsBegin(PETSC_COMM_WORLD, "", "Options for the inhomogeneous Poisson equation", "DMqq"); user.rho = 1.0; ierr = PetscOptionsReal("-rho", "The conductivity", "ex29.c", user.rho, &user.rho, PETSC_NULL); CHKERRQ(ierr); user.nu = 0.1; ierr = PetscOptionsReal("-nu", "The width of the Gaussian source", "ex29.c", user.nu, &user.nu, PETSC_NULL); CHKERRQ(ierr); bc = (PetscInt)DIRICHLET; ierr = PetscOptionsEList("-bc_type","Type of boundary condition","ex29.c",bcTypes,2,bcTypes[0],&bc,PETSC_NULL); CHKERRQ(ierr); user.bcType = (BCType)bc; ierr = PetscOptionsEnd(); ierr = KSPSetComputeRHS(ksp,ComputeRHS,&user); CHKERRQ(ierr); ierr = KSPSetComputeOperators(ksp,ComputeMatrix,&user); CHKERRQ(ierr); ierr = KSPSetDM(ksp,da); CHKERRQ(ierr); ierr = KSPSetFromOptions(ksp); CHKERRQ(ierr); ierr = KSPSetUp(ksp); CHKERRQ(ierr); ierr = KSPSolve(ksp,PETSC_NULL,PETSC_NULL); CHKERRQ(ierr); ierr = KSPGetSolution(ksp,&x); CHKERRQ(ierr); ierr = KSPGetRhs(ksp,&b); CHKERRQ(ierr); ierr = DMDestroy(&da); CHKERRQ(ierr); ierr = KSPDestroy(&ksp); CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int main(int argc,char **argv) { TS ts; SNES snes; SNESLineSearch linesearch; Vec x; AppCtx ctx; PetscErrorCode ierr; DM da; ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; ierr = SetFromOptions(&ctx);CHKERRQ(ierr); ierr = TSCreate(PETSC_COMM_WORLD, &ts);CHKERRQ(ierr); ierr = TSSetType(ts,TSCN);CHKERRQ(ierr); ierr = TSSetProblemType(ts,TS_NONLINEAR);CHKERRQ(ierr); ierr = TSSetIFunction(ts, NULL, FormIFunction, &ctx);CHKERRQ(ierr); ierr = DMDACreate2d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE,DMDA_STENCIL_STAR,-4,-4,PETSC_DECIDE,PETSC_DECIDE,N_SPECIES,1,NULL,NULL,&da);CHKERRQ(ierr); ierr = DMDASetUniformCoordinates(da, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0);CHKERRQ(ierr); ierr = DMDASetFieldName(da,0,"species A");CHKERRQ(ierr); ierr = DMDASetFieldName(da,1,"species B");CHKERRQ(ierr); ierr = DMDASetFieldName(da,2,"species C");CHKERRQ(ierr); ierr = DMSetApplicationContext(da,&ctx);CHKERRQ(ierr); ierr = DMCreateGlobalVector(da,&x);CHKERRQ(ierr); ierr = FormInitialGuess(da, &ctx, x);CHKERRQ(ierr); ierr = TSSetDM(ts, da);CHKERRQ(ierr); ierr = TSSetDuration(ts,10000,1000.0);CHKERRQ(ierr); ierr = TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER);CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts,0.0,1.0);CHKERRQ(ierr); ierr = TSSetSolution(ts,x);CHKERRQ(ierr); ierr = TSSetFromOptions(ts);CHKERRQ(ierr); ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); ierr = SNESGetLineSearch(snes,&linesearch);CHKERRQ(ierr); ierr = SNESLineSearchSetPostCheck(linesearch, ReactingFlowPostCheck, (void*)&ctx);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); ierr = TSSolve(ts,x);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize(); PetscFunctionReturn(0); }
/* PipeSetUp - Set up pipe based on set parameters. */ PetscErrorCode PipeSetUp(Pipe pipe) { DMDALocalInfo info; PetscErrorCode ierr; MPI_Comm comm = pipe->comm; PetscFunctionBegin; ierr = DMDACreate1d(comm, DM_BOUNDARY_GHOSTED, pipe->nnodes, 2, 1, PETSC_NULL, &(pipe->da));CHKERRQ(ierr); ierr = DMDASetFieldName(pipe->da, 0, "Q");CHKERRQ(ierr); ierr = DMDASetFieldName(pipe->da, 1, "H");CHKERRQ(ierr); ierr = DMDASetUniformCoordinates(pipe->da, 0, pipe->length, 0, 0, 0, 0);CHKERRQ(ierr); ierr = DMCreateGlobalVector(pipe->da, &(pipe->x));CHKERRQ(ierr); ierr = DMDAGetLocalInfo(pipe->da, &info);CHKERRQ(ierr); pipe->rad = pipe->D / 2; pipe->A = PETSC_PI*pipe->rad*pipe->rad; pipe->R = pipe->fric / (2*pipe->D*pipe->A); PetscFunctionReturn(0); }
PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *user, DM *dm) { PetscInt dim = user->dim; PetscErrorCode ierr; PetscFunctionBegin; switch(dim) { case 2: ierr = DMDACreate2d(comm, DMDA_BOUNDARY_NONE, DMDA_BOUNDARY_NONE, DMDA_STENCIL_STAR, -4, -4, PETSC_DECIDE, PETSC_DECIDE, 2, 1, PETSC_NULL, PETSC_NULL, dm);CHKERRQ(ierr); break; case 3: ierr = DMDACreate3d(comm, DMDA_BOUNDARY_NONE, DMDA_BOUNDARY_NONE, DMDA_BOUNDARY_NONE, DMDA_STENCIL_STAR, -4, -4, -4, PETSC_DECIDE, PETSC_DECIDE, PETSC_DECIDE, 2, 1, PETSC_NULL, PETSC_NULL, PETSC_NULL, dm);CHKERRQ(ierr); break; default: SETERRQ1(comm, PETSC_ERR_ARG_OUTOFRANGE, "Could not create mesh for dimension %d", dim); } ierr = DMSetFromOptions(*dm);CHKERRQ(ierr); ierr = DMDASetFieldName(*dm, 0, "velocity");CHKERRQ(ierr); ierr = DMDASetFieldName(*dm, 1, "pressure");CHKERRQ(ierr); user->dm = *dm; PetscFunctionReturn(0); }
int main(int argc,char **argv) { TS ts; Vec x,c; PetscErrorCode ierr; DM da; PetscInitialize(&argc,&argv,(char *)0,help); ierr = TSCreate(PETSC_COMM_WORLD, &ts);CHKERRQ(ierr); ierr = TSSetType(ts,TSCN);CHKERRQ(ierr); ierr = TSSetProblemType(ts,TS_NONLINEAR);CHKERRQ(ierr); ierr = DMDACreate2d(PETSC_COMM_WORLD, DMDA_BOUNDARY_NONE, DMDA_BOUNDARY_NONE,DMDA_STENCIL_STAR,-4,-4,PETSC_DECIDE,PETSC_DECIDE,1,1,PETSC_NULL,PETSC_NULL,&da);CHKERRQ(ierr); ierr = DMDASetUniformCoordinates(da, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0);CHKERRQ(ierr); ierr = DMDASetFieldName(da,0,"Heat");CHKERRQ(ierr); ierr = DMCreateGlobalVector(da,&x);CHKERRQ(ierr); ierr = FormInitialGuess(da,PETSC_NULL,x);CHKERRQ(ierr); ierr = DMDATSSetIFunctionLocal(da,INSERT_VALUES,(PetscErrorCode (*)(DMDALocalInfo*,PetscReal,void*,void*,void*,void*))FormIFunctionLocal,PETSC_NULL);CHKERRQ(ierr); /* set up the coefficient */ ierr = DMGetNamedGlobalVector(da,"coefficient",&c);CHKERRQ(ierr); ierr = FormDiffusionCoefficient(da,PETSC_NULL,c);CHKERRQ(ierr); ierr = DMRestoreNamedGlobalVector(da,"coefficient",&c);CHKERRQ(ierr); ierr = DMCoarsenHookAdd(da,PETSC_NULL,CoefficientRestrictHook,ts);CHKERRQ(ierr); ierr = DMSubDomainHookAdd(da,PETSC_NULL,CoefficientSubDomainRestrictHook,ts);CHKERRQ(ierr); ierr = TSSetDM(ts, da);CHKERRQ(ierr); ierr = TSSetDuration(ts,10000,1000.0);CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts,0.0,0.05);CHKERRQ(ierr); ierr = TSSetSolution(ts,x);CHKERRQ(ierr); ierr = TSSetFromOptions(ts);CHKERRQ(ierr); ierr = TSSolve(ts,x);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize(); PetscFunctionReturn(0); }
int main(int argc,char **argv) { TS ts; /* ODE integrator */ Vec x; /* solution */ PetscErrorCode ierr; DM da; AppCtx appctx; Vec lambda[1]; PetscScalar *x_ptr; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Initialize program - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; PetscFunctionBeginUser; appctx.D1 = 8.0e-5; appctx.D2 = 4.0e-5; appctx.gamma = .024; appctx.kappa = .06; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create distributed array (DMDA) to manage parallel grid and vectors - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMDACreate2d(PETSC_COMM_WORLD,DM_BOUNDARY_PERIODIC,DM_BOUNDARY_PERIODIC,DMDA_STENCIL_STAR,65,65,PETSC_DECIDE,PETSC_DECIDE,2,1,NULL,NULL,&da);CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMSetUp(da);CHKERRQ(ierr); ierr = DMDASetFieldName(da,0,"u");CHKERRQ(ierr); ierr = DMDASetFieldName(da,1,"v");CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Extract global vectors from DMDA; then duplicate for remaining vectors that are the same types - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMCreateGlobalVector(da,&x);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create timestepping solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetType(ts,TSCN);CHKERRQ(ierr); ierr = TSSetDM(ts,da);CHKERRQ(ierr); ierr = TSSetProblemType(ts,TS_NONLINEAR);CHKERRQ(ierr); ierr = TSSetRHSFunction(ts,NULL,RHSFunction,&appctx);CHKERRQ(ierr); ierr = TSSetRHSJacobian(ts,NULL,NULL,RHSJacobian,&appctx);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set initial conditions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = InitialConditions(da,x);CHKERRQ(ierr); ierr = TSSetSolution(ts,x);CHKERRQ(ierr); /* Have the TS save its trajectory so that TSAdjointSolve() may be used */ ierr = TSSetSaveTrajectory(ts);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set solver options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetDuration(ts,PETSC_DEFAULT,2000.0);CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts,0.0,.0001);CHKERRQ(ierr); ierr = TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER);CHKERRQ(ierr); ierr = TSSetFromOptions(ts);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve ODE system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSolve(ts,x);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Start the Adjoint model - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = VecDuplicate(x,&lambda[0]);CHKERRQ(ierr); /* Reset initial conditions for the adjoint integration */ ierr = VecGetArray(lambda[0],&x_ptr);CHKERRQ(ierr); ierr = InitializeLambda(da,lambda[0],0.5,0.5);CHKERRQ(ierr); ierr = TSSetCostGradients(ts,1,lambda,NULL);CHKERRQ(ierr); ierr = TSAdjointSolve(ts);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. All PETSc objects should be destroyed when they are no longer needed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = VecDestroy(&lambda[0]);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
int main(int argc,char **argv) { PetscErrorCode ierr; PatternCtx user; TS ts; Vec x; DMDALocalInfo info; double noiselevel = -1.0; // negative value means no initial noise PetscInitialize(&argc,&argv,(char*)0,help); // parameter values from pages 21-22 in Hundsdorfer & Verwer (2003) user.L = 2.5; user.Du = 8.0e-5; user.Dv = 4.0e-5; user.phi = 0.024; user.kappa = 0.06; ierr = PetscOptionsBegin(PETSC_COMM_WORLD, "ptn_", "options for patterns", ""); CHKERRQ(ierr); ierr = PetscOptionsReal("-noisy_init", "initialize u,v with this much random noise (e.g. 0.2) on top of usual initial values", "pattern.c",noiselevel,&noiselevel,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-L","square domain side length; recommend L >= 0.5", "pattern.c",user.L,&user.L,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-Du","diffusion coefficient of first equation", "pattern.c",user.Du,&user.Du,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-Dv","diffusion coefficient of second equation", "pattern.c",user.Dv,&user.Dv,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-phi","dimensionless feed rate (=F in (Pearson, 1993))", "pattern.c",user.phi,&user.phi,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-kappa","dimensionless rate constant (=k in (Pearson, 1993))", "pattern.c",user.kappa,&user.kappa,NULL);CHKERRQ(ierr); ierr = PetscOptionsEnd(); CHKERRQ(ierr); //DMDACREATE ierr = DMDACreate2d(PETSC_COMM_WORLD, DM_BOUNDARY_PERIODIC, DM_BOUNDARY_PERIODIC, DMDA_STENCIL_BOX, // for 9-point stencil 4,4,PETSC_DECIDE,PETSC_DECIDE, 2, 1, // degrees of freedom, stencil width NULL,NULL,&user.da); CHKERRQ(ierr); //ENDDMDACREATE ierr = DMSetFromOptions(user.da); CHKERRQ(ierr); ierr = DMSetUp(user.da); CHKERRQ(ierr); ierr = DMDASetFieldName(user.da,0,"u"); CHKERRQ(ierr); ierr = DMDASetFieldName(user.da,1,"v"); CHKERRQ(ierr); ierr = DMDAGetLocalInfo(user.da,&info); CHKERRQ(ierr); if (info.mx != info.my) { SETERRQ(PETSC_COMM_WORLD,1,"pattern.c requires mx == my"); } ierr = DMDASetUniformCoordinates(user.da, 0.0, user.L, 0.0, user.L, -1.0, -1.0); CHKERRQ(ierr); ierr = DMSetApplicationContext(user.da,&user); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "running on %d x %d grid with square cells of side h = %.6f ...\n", info.mx,info.my,user.L/(double)(info.mx)); CHKERRQ(ierr); //TSSETUP ierr = TSCreate(PETSC_COMM_WORLD,&ts); CHKERRQ(ierr); ierr = TSSetProblemType(ts,TS_NONLINEAR); CHKERRQ(ierr); ierr = TSSetDM(ts,user.da); CHKERRQ(ierr); ierr = DMDATSSetRHSFunctionLocal(user.da,INSERT_VALUES, (DMDATSRHSFunctionLocal)FormRHSFunctionLocal,&user); CHKERRQ(ierr); ierr = DMDATSSetIFunctionLocal(user.da,INSERT_VALUES, (DMDATSIFunctionLocal)FormIFunctionLocal,&user); CHKERRQ(ierr); ierr = DMDATSSetIJacobianLocal(user.da, (DMDATSIJacobianLocal)FormIJacobianLocal,&user); CHKERRQ(ierr); ierr = TSSetType(ts,TSARKIMEX); CHKERRQ(ierr); ierr = TSSetExactFinalTime(ts,TS_EXACTFINALTIME_MATCHSTEP); CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts,0.0,5.0); CHKERRQ(ierr); // t_0 = 0.0, dt = 5.0 ierr = TSSetDuration(ts,1000000,200.0); CHKERRQ(ierr); // t_f = 200 ierr = TSSetFromOptions(ts);CHKERRQ(ierr); //ENDTSSETUP ierr = DMCreateGlobalVector(user.da,&x); CHKERRQ(ierr); ierr = InitialState(x,noiselevel,&user); CHKERRQ(ierr); ierr = TSSolve(ts,x); CHKERRQ(ierr); VecDestroy(&x); TSDestroy(&ts); DMDestroy(&user.da); PetscFinalize(); return 0; }
int main(int argc,char **argv) { PetscErrorCode ierr; PetscBag bag; Parameter *params; PetscViewer viewer; DM da; Vec global,local; PetscMPIInt rank; /* Every PETSc routine should begin with the PetscInitialize() routine. argc, argv - These command line arguments are taken to extract the options supplied to PETSc and options supplied to MPI. help - When PETSc executable is invoked with the option -help, it prints the various options that can be applied at runtime. The user can use the "help" variable place additional help messages in this printout. */ ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; /* Create a DMDA and an associated vector */ ierr = DMDACreate2d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE,DMDA_STENCIL_BOX,10,10,PETSC_DECIDE,PETSC_DECIDE,2,1,NULL,NULL,&da);CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMSetUp(da);CHKERRQ(ierr); ierr = DMCreateGlobalVector(da,&global);CHKERRQ(ierr); ierr = DMCreateLocalVector(da,&local);CHKERRQ(ierr); ierr = VecSet(global,-1.0);CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(da,global,INSERT_VALUES,local);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(da,global,INSERT_VALUES,local);CHKERRQ(ierr); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = VecScale(local,rank+1);CHKERRQ(ierr); ierr = DMLocalToGlobalBegin(da,local,ADD_VALUES,global);CHKERRQ(ierr); ierr = DMLocalToGlobalEnd(da,local,ADD_VALUES,global);CHKERRQ(ierr); /* Create an empty bag */ ierr = PetscBagCreate(PETSC_COMM_WORLD,sizeof(Parameter),&bag);CHKERRQ(ierr); ierr = PetscBagGetData(bag,(void**)¶ms);CHKERRQ(ierr); /* fill bag: register variables, defaults, names, help strings */ ierr = PetscBagSetName(bag,"ParameterBag","contains problem parameters");CHKERRQ(ierr); ierr = PetscBagRegisterString(bag,¶ms->filename,PETSC_MAX_PATH_LEN,"output_file","filename","Name of secret file");CHKERRQ(ierr); ierr = PetscBagRegisterReal (bag,¶ms->ra,1.0,"param_1","The first parameter");CHKERRQ(ierr); ierr = PetscBagRegisterInt (bag,¶ms->ia,5,"param_2","The second parameter");CHKERRQ(ierr); ierr = PetscBagRegisterBool (bag,¶ms->ta,PETSC_TRUE,"do_output","Write output file (true/false)");CHKERRQ(ierr); /* Write output file with PETSC_VIEWER_BINARY_MATLAB format NOTE: the output generated with this viewer can be loaded into MATLAB using $PETSC_DIR/share/petsc/matlab/PetscReadBinaryMatlab.m */ ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,params->filename,FILE_MODE_WRITE,&viewer);CHKERRQ(ierr); ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_BINARY_MATLAB);CHKERRQ(ierr); ierr = PetscBagView(bag,viewer);CHKERRQ(ierr); ierr = DMDASetFieldName(da,0,"field1");CHKERRQ(ierr); ierr = DMDASetFieldName(da,1,"field2");CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)global,"da1");CHKERRQ(ierr); ierr = VecView(global,viewer);CHKERRQ(ierr); ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); /* clean up and exit */ ierr = PetscBagDestroy(&bag);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = VecDestroy(&local);CHKERRQ(ierr); ierr = VecDestroy(&global);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
int main(int argc,char **argv) { PetscErrorCode ierr; int time; /* amount of loops */ struct in put; PetscScalar rh; /* relative humidity */ PetscScalar x; /* memory varialbe for relative humidity calculation */ PetscScalar deep_grnd_temp; /* temperature of ground under top soil surface layer */ PetscScalar emma; /* absorption-emission constant for air */ PetscScalar pressure1 = 101300; /* surface pressure */ PetscScalar mixratio; /* mixing ratio */ PetscScalar airtemp; /* temperature of air near boundary layer inversion */ PetscScalar dewtemp; /* dew point temperature */ PetscScalar sfctemp; /* temperature at surface */ PetscScalar pwat; /* total column precipitable water */ PetscScalar cloudTemp; /* temperature at base of cloud */ AppCtx user; /* user-defined work context */ MonitorCtx usermonitor; /* user-defined monitor context */ PetscMPIInt rank,size; TS ts; SNES snes; DM da; Vec T,rhs; /* solution vector */ Mat J; /* Jacobian matrix */ PetscReal ftime,dt; PetscInt steps,dof = 5; PetscBool use_coloring = PETSC_TRUE; MatFDColoring matfdcoloring = 0; PetscBool monitor_off = PETSC_FALSE; PetscInitialize(&argc,&argv,(char*)0,help); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); /* Inputs */ readinput(&put); sfctemp = put.Ts; dewtemp = put.Td; cloudTemp = put.Tc; airtemp = put.Ta; pwat = put.pwt; if (!rank) PetscPrintf(PETSC_COMM_SELF,"Initial Temperature = %g\n",sfctemp); /* input surface temperature */ deep_grnd_temp = sfctemp - 10; /* set underlying ground layer temperature */ emma = emission(pwat); /* accounts for radiative effects of water vapor */ /* Converts from Fahrenheit to Celsuis */ sfctemp = fahr_to_cel(sfctemp); airtemp = fahr_to_cel(airtemp); dewtemp = fahr_to_cel(dewtemp); cloudTemp = fahr_to_cel(cloudTemp); deep_grnd_temp = fahr_to_cel(deep_grnd_temp); /* Converts from Celsius to Kelvin */ sfctemp += 273; airtemp += 273; dewtemp += 273; cloudTemp += 273; deep_grnd_temp += 273; /* Calculates initial relative humidity */ x = calcmixingr(dewtemp,pressure1); mixratio = calcmixingr(sfctemp,pressure1); rh = (x/mixratio)*100; if (!rank) printf("Initial RH = %.1f percent\n\n",rh); /* prints initial relative humidity */ time = 3600*put.time; /* sets amount of timesteps to run model */ /* Configure PETSc TS solver */ /*------------------------------------------*/ /* Create grid */ ierr = DMDACreate2d(PETSC_COMM_WORLD,DMDA_BOUNDARY_PERIODIC,DMDA_BOUNDARY_PERIODIC,DMDA_STENCIL_STAR,-20,-20, PETSC_DECIDE,PETSC_DECIDE,dof,1,NULL,NULL,&da);CHKERRQ(ierr); ierr = DMDASetUniformCoordinates(da, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0);CHKERRQ(ierr); /* Define output window for each variable of interest */ ierr = DMDASetFieldName(da,0,"Ts");CHKERRQ(ierr); ierr = DMDASetFieldName(da,1,"Ta");CHKERRQ(ierr); ierr = DMDASetFieldName(da,2,"u");CHKERRQ(ierr); ierr = DMDASetFieldName(da,3,"v");CHKERRQ(ierr); ierr = DMDASetFieldName(da,4,"p");CHKERRQ(ierr); /* set values for appctx */ user.da = da; user.Ts = sfctemp; user.fract = put.fr; /* fraction of sky covered by clouds */ user.dewtemp = dewtemp; /* dew point temperature (mositure in air) */ user.csoil = 2000000; /* heat constant for layer */ user.dzlay = 0.08; /* thickness of top soil layer */ user.emma = emma; /* emission parameter */ user.wind = put.wnd; /* wind spped */ user.pressure1 = pressure1; /* sea level pressure */ user.airtemp = airtemp; /* temperature of air near boundar layer inversion */ user.Tc = cloudTemp; /* temperature at base of lowest cloud layer */ user.init = put.init; /* user chosen initiation scenario */ user.lat = 70*0.0174532; /* converts latitude degrees to latitude in radians */ user.deep_grnd_temp = deep_grnd_temp; /* temp in lowest ground layer */ /* set values for MonitorCtx */ usermonitor.drawcontours = PETSC_FALSE; ierr = PetscOptionsHasName(NULL,"-drawcontours",&usermonitor.drawcontours);CHKERRQ(ierr); if (usermonitor.drawcontours) { PetscReal bounds[] = {1000.0,-1000., -1000.,-1000., 1000.,-1000., 1000.,-1000., 1000,-1000, 100700,100800}; ierr = PetscViewerDrawOpen(PETSC_COMM_WORLD,0,0,0,0,300,300,&usermonitor.drawviewer);CHKERRQ(ierr); ierr = PetscViewerDrawSetBounds(usermonitor.drawviewer,dof,bounds);CHKERRQ(ierr); } usermonitor.interval = 1; ierr = PetscOptionsGetInt(NULL,"-monitor_interval",&usermonitor.interval,NULL);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Extract global vectors from DA; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMCreateGlobalVector(da,&T);CHKERRQ(ierr); ierr = VecDuplicate(T,&rhs);CHKERRQ(ierr); /* r: vector to put the computed right hand side */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetProblemType(ts,TS_NONLINEAR);CHKERRQ(ierr); ierr = TSSetType(ts,TSBEULER);CHKERRQ(ierr); ierr = TSSetRHSFunction(ts,rhs,RhsFunc,&user);CHKERRQ(ierr); /* Set Jacobian evaluation routine - use coloring to compute finite difference Jacobian efficiently */ ierr = DMSetMatType(da,MATAIJ);CHKERRQ(ierr); ierr = DMCreateMatrix(da,&J);CHKERRQ(ierr); ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); if (use_coloring) { ISColoring iscoloring; ierr = DMCreateColoring(da,IS_COLORING_GLOBAL,&iscoloring);CHKERRQ(ierr); ierr = MatFDColoringCreate(J,iscoloring,&matfdcoloring);CHKERRQ(ierr); ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); ierr = MatFDColoringSetUp(J,iscoloring,matfdcoloring);CHKERRQ(ierr); ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode (*)(void))SNESTSFormFunction,ts);CHKERRQ(ierr); ierr = SNESSetJacobian(snes,J,J,SNESComputeJacobianDefaultColor,matfdcoloring);CHKERRQ(ierr); } else { ierr = SNESSetJacobian(snes,J,J,SNESComputeJacobianDefault,NULL);CHKERRQ(ierr); } /* Define what to print for ts_monitor option */ ierr = PetscOptionsHasName(NULL,"-monitor_off",&monitor_off);CHKERRQ(ierr); if (!monitor_off) { ierr = TSMonitorSet(ts,Monitor,&usermonitor,NULL);CHKERRQ(ierr); } ierr = FormInitialSolution(da,T,&user);CHKERRQ(ierr); dt = TIMESTEP; /* initial time step */ ftime = TIMESTEP*time; if (!rank) printf("time %d, ftime %g hour, TIMESTEP %g\n",time,ftime/3600,dt); ierr = TSSetInitialTimeStep(ts,0.0,dt);CHKERRQ(ierr); ierr = TSSetDuration(ts,time,ftime);CHKERRQ(ierr); ierr = TSSetSolution(ts,T);CHKERRQ(ierr); ierr = TSSetDM(ts,da);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetFromOptions(ts);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSolve(ts,T);CHKERRQ(ierr); ierr = TSGetSolveTime(ts,&ftime);CHKERRQ(ierr); ierr = TSGetTimeStepNumber(ts,&steps);CHKERRQ(ierr); if (!rank) PetscPrintf(PETSC_COMM_WORLD,"Solution T after %g hours %d steps\n",ftime/3600,steps); if (matfdcoloring) {ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr);} if (usermonitor.drawcontours) { ierr = PetscViewerDestroy(&usermonitor.drawviewer);CHKERRQ(ierr); } ierr = MatDestroy(&J);CHKERRQ(ierr); ierr = VecDestroy(&T);CHKERRQ(ierr); ierr = VecDestroy(&rhs);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); PetscFinalize(); return 0; }
int main(int argc,char **argv) { TS ts; /* nonlinear solver */ Vec x,r; /* solution, residual vectors */ PetscInt steps,maxsteps = 100; /* iterations for convergence */ PetscErrorCode ierr; DM da; PetscReal ftime; SNES ts_snes; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Initialize program - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ PetscInitialize(&argc,&argv,(char*)0,help); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create distributed array (DMDA) to manage parallel grid and vectors - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMDACreate2d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE,DMDA_STENCIL_STAR,-8,-8,PETSC_DECIDE,PETSC_DECIDE, 2,1,NULL,NULL,&da);CHKERRQ(ierr); ierr = DMDASetFieldName(da,0,"u");CHKERRQ(ierr); ierr = DMDASetFieldName(da,1,"v");CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Extract global vectors from DMDA; then duplicate for remaining vectors that are the same types - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMCreateGlobalVector(da,&x);CHKERRQ(ierr); ierr = VecDuplicate(x,&r);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create timestepping solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetDM(ts,da);CHKERRQ(ierr); ierr = TSSetProblemType(ts,TS_NONLINEAR);CHKERRQ(ierr); ierr = TSSetRHSFunction(ts,NULL,FormFunction,da);CHKERRQ(ierr); ierr = TSSetDuration(ts,maxsteps,1.0);CHKERRQ(ierr); ierr = TSMonitorSet(ts,MyTSMonitor,0,0);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Customize nonlinear solver - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetType(ts,TSBEULER);CHKERRQ(ierr); ierr = TSGetSNES(ts,&ts_snes); ierr = SNESMonitorSet(ts_snes,MySNESMonitor,NULL,NULL); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set initial conditions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = FormInitialSolution(da,x);CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts,0.0,.0001);CHKERRQ(ierr); ierr = TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER);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); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. All PETSc objects should be destroyed when they are no longer needed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&r);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize(); PetscFunctionReturn(0); }
int main(int argc,char **argv) { DM da; SNES snes; /* nonlinear solver */ AppCtx *user; /* user-defined work context */ PetscBag bag; PetscInt its; /* iterations for convergence */ PetscMPIInt size; SNESConvergedReason reason; PetscErrorCode ierr; PetscReal lambda_max = 6.81, lambda_min = 0.0, error; Vec x; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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,"Example only works for one process."); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Initialize problem parameters - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = PetscBagCreate(PETSC_COMM_WORLD, sizeof(AppCtx), &bag);CHKERRQ(ierr); ierr = PetscBagGetData(bag, (void**) &user);CHKERRQ(ierr); ierr = PetscBagSetName(bag, "params", "Parameters for SNES example 4");CHKERRQ(ierr); ierr = PetscBagRegisterReal(bag, &user->alpha, 1.0, "alpha", "Linear coefficient");CHKERRQ(ierr); ierr = PetscBagRegisterReal(bag, &user->lambda, 6.0, "lambda", "Nonlinear coefficient");CHKERRQ(ierr); ierr = PetscBagSetFromOptions(bag);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,"-alpha",&user->alpha,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,"-lambda",&user->lambda,NULL);CHKERRQ(ierr); if (user->lambda > lambda_max || user->lambda < lambda_min) SETERRQ3(PETSC_COMM_SELF,1,"Lambda %g is out of range [%g, %g]", (double)user->lambda, (double)lambda_min, (double)lambda_max); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create multilevel DM data structure (SNES) to manage hierarchical solvers - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = SNESCreate(PETSC_COMM_WORLD,&snes);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create distributed array (DMDA) to manage parallel grid and vectors - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMDACreate2d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE,DMDA_STENCIL_BOX,-3,-3,PETSC_DECIDE,PETSC_DECIDE,3,1,NULL,NULL,&da);CHKERRQ(ierr); ierr = DMDASetFieldName(da, 0, "ooblek");CHKERRQ(ierr); ierr = DMSetApplicationContext(da,user);CHKERRQ(ierr); ierr = SNESSetDM(snes, (DM) da);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set the discretization functions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMDASNESSetFunctionLocal(da,INSERT_VALUES,(PetscErrorCode (*)(DMDALocalInfo*,void*,void*,void*))FormFunctionLocal,user);CHKERRQ(ierr); ierr = DMDASNESSetJacobianLocal(da,(PetscErrorCode (*)(DMDALocalInfo*,void*,Mat,Mat,void*))FormJacobianLocal,user);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); ierr = SNESSetComputeInitialGuess(snes, FormInitialGuess,NULL);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = SNESSolve(snes,NULL,NULL);CHKERRQ(ierr); ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr); ierr = SNESGetConvergedReason(snes, &reason);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = PetscPrintf(PETSC_COMM_WORLD,"Number of SNES iterations = %D, %s\n",its,SNESConvergedReasons[reason]);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = SNESGetDM(snes,&da);CHKERRQ(ierr); ierr = SNESGetSolution(snes,&x);CHKERRQ(ierr); ierr = L_2Error(da, x, &error, user);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"L_2 error in the solution: %g\n", (double)error);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. All PETSc objects should be destroyed when they are no longer needed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = PetscBagDestroy(&bag);CHKERRQ(ierr); ierr = PetscFinalize(); PetscFunctionReturn(0); }
#include <petsc-private/fortranimpl.h> #include <petscdmda.h> #if defined(PETSC_HAVE_FORTRAN_CAPS) #define dmdasetfieldname_ DMDASETFIELDNAME #define dmdagetfieldname_ DMDAGETFIELDNAME #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE) #define dmdasetfieldname_ dmdasetfieldname #define dmdagetfieldname_ dmdagetfieldname #endif PETSC_EXTERN void PETSC_STDCALL dmdasetfieldname_(DM *da,PetscInt *nf,CHAR name PETSC_MIXED_LEN(len),PetscErrorCode *ierr PETSC_END_LEN(len)) { char *t; FIXCHAR(name,len,t); *ierr = DMDASetFieldName(*da,*nf,t); FREECHAR(name,t); } PETSC_EXTERN void PETSC_STDCALL dmdagetfieldname_(DM *da,PetscInt *nf,CHAR name PETSC_MIXED_LEN(len),PetscErrorCode *ierr PETSC_END_LEN(len)) { const char *tname; *ierr = DMDAGetFieldName(*da,*nf,&tname); *ierr = PetscStrncpy(name,tname,len); }
int main(int argc,char **argv) { AppCtx user; /* user-defined work context */ PetscInt mx,my; PetscErrorCode ierr; MPI_Comm comm; DM da; Vec x; Mat J = NULL,Jmf = NULL; MatShellCtx matshellctx; PetscInt mlocal,nlocal; PC pc; KSP ksp; PetscBool errorinmatmult = PETSC_FALSE,errorinpcapply = PETSC_FALSE,errorinpcsetup = PETSC_FALSE; ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return(1); PetscFunctionBeginUser; ierr = PetscOptionsGetBool(NULL,"-error_in_matmult",&errorinmatmult,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,"-error_in_pcapply",&errorinpcapply,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,"-error_in_pcsetup",&errorinpcsetup,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,"-error_in_domain",&user.errorindomain,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,"-error_in_domainmf",&user.errorindomainmf,NULL);CHKERRQ(ierr); comm = PETSC_COMM_WORLD; ierr = SNESCreate(comm,&user.snes);CHKERRQ(ierr); /* Create distributed array object to manage parallel grid and vectors for principal unknowns (x) and governing residuals (f) */ ierr = DMDACreate2d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE,DMDA_STENCIL_STAR,-4,-4,PETSC_DECIDE,PETSC_DECIDE,4,1,0,0,&da);CHKERRQ(ierr); ierr = SNESSetDM(user.snes,da);CHKERRQ(ierr); ierr = DMDAGetInfo(da,0,&mx,&my,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE, PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);CHKERRQ(ierr); /* Problem parameters (velocity of lid, prandtl, and grashof numbers) */ user.lidvelocity = 1.0/(mx*my); user.prandtl = 1.0; user.grashof = 1.0; ierr = PetscOptionsGetReal(NULL,"-lidvelocity",&user.lidvelocity,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,"-prandtl",&user.prandtl,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,"-grashof",&user.grashof,NULL);CHKERRQ(ierr); ierr = PetscOptionsHasName(NULL,"-contours",&user.draw_contours);CHKERRQ(ierr); ierr = DMDASetFieldName(da,0,"x_velocity");CHKERRQ(ierr); ierr = DMDASetFieldName(da,1,"y_velocity");CHKERRQ(ierr); ierr = DMDASetFieldName(da,2,"Omega");CHKERRQ(ierr); ierr = DMDASetFieldName(da,3,"temperature");CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create user context, set problem data, create vector data structures. Also, compute the initial guess. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create nonlinear solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMSetApplicationContext(da,&user);CHKERRQ(ierr); ierr = DMDASNESSetFunctionLocal(da,INSERT_VALUES,(PetscErrorCode (*)(DMDALocalInfo*,void*,void*,void*))FormFunctionLocal,&user);CHKERRQ(ierr); if (errorinmatmult) { ierr = MatCreateSNESMF(user.snes,&Jmf);CHKERRQ(ierr); ierr = MatSetFromOptions(Jmf);CHKERRQ(ierr); ierr = MatGetLocalSize(Jmf,&mlocal,&nlocal);CHKERRQ(ierr); matshellctx.Jmf = Jmf; ierr = MatCreateShell(PetscObjectComm((PetscObject)Jmf),mlocal,nlocal,PETSC_DECIDE,PETSC_DECIDE,&matshellctx,&J);CHKERRQ(ierr); ierr = MatShellSetOperation(J,MATOP_MULT,(void (*)(void))MatMult_MyShell);CHKERRQ(ierr); ierr = MatShellSetOperation(J,MATOP_ASSEMBLY_END,(void (*)(void))MatAssemblyEnd_MyShell);CHKERRQ(ierr); ierr = SNESSetJacobian(user.snes,J,J,MatMFFDComputeJacobian,NULL);CHKERRQ(ierr); } ierr = SNESSetFromOptions(user.snes);CHKERRQ(ierr); ierr = PetscPrintf(comm,"lid velocity = %g, prandtl # = %g, grashof # = %g\n",(double)user.lidvelocity,(double)user.prandtl,(double)user.grashof);CHKERRQ(ierr); if (errorinpcapply) { ierr = SNESGetKSP(user.snes,&ksp);CHKERRQ(ierr); ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); ierr = PCSetType(pc,PCSHELL);CHKERRQ(ierr); ierr = PCShellSetApply(pc,PCApply_MyShell);CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve the nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMCreateGlobalVector(da,&x);CHKERRQ(ierr); ierr = FormInitialGuess(&user,da,x);CHKERRQ(ierr); if (errorinpcsetup) { ierr = SNESSetUp(user.snes);CHKERRQ(ierr); ierr = SNESSetJacobian(user.snes,NULL,NULL,SNESComputeJacobian_MyShell,NULL);CHKERRQ(ierr); } ierr = SNESSolve(user.snes,NULL,x);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. All PETSc objects should be destroyed when they are no longer needed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatDestroy(&J);CHKERRQ(ierr); ierr = MatDestroy(&Jmf);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = SNESDestroy(&user.snes);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int main(int argc,char **argv) { TS ts; /* nonlinear solver */ Vec U; /* solution, residual vectors */ PetscErrorCode ierr; DM da; AppCtx appctx; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Initialize program - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ PetscInitialize(&argc,&argv,(char*)0,help); appctx.epsilon = 1.0e-3; appctx.delta = 1.0; appctx.alpha = 10.0; appctx.beta = 4.0; appctx.gamma = 1.0; appctx.kappa = .75; appctx.lambda = 1.0; appctx.mu = 100.; appctx.cstar = .2; appctx.upwind = PETSC_TRUE; ierr = PetscOptionsGetScalar(NULL,"-delta",&appctx.delta,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,"-upwind",&appctx.upwind,NULL);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create distributed array (DMDA) to manage parallel grid and vectors - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMDACreate1d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE,-8,2,1,NULL,&da);CHKERRQ(ierr); ierr = DMDASetFieldName(da,0,"rho");CHKERRQ(ierr); ierr = DMDASetFieldName(da,1,"c");CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Extract global vectors from DMDA; then duplicate for remaining vectors that are the same types - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMCreateGlobalVector(da,&U);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create timestepping solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetType(ts,TSROSW);CHKERRQ(ierr); ierr = TSSetDM(ts,da);CHKERRQ(ierr); ierr = TSSetProblemType(ts,TS_NONLINEAR);CHKERRQ(ierr); ierr = TSSetIFunction(ts,NULL,IFunction,&appctx);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set initial conditions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = InitialConditions(da,U);CHKERRQ(ierr); ierr = TSSetSolution(ts,U);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set solver options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetInitialTimeStep(ts,0.0,.0001);CHKERRQ(ierr); ierr = TSSetDuration(ts,PETSC_DEFAULT,1.0);CHKERRQ(ierr); ierr = TSSetFromOptions(ts);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSolve(ts,U);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. All PETSc objects should be destroyed when they are no longer needed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = VecDestroy(&U);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize(); PetscFunctionReturn(0); }
PetscErrorCode InitialConditions(DM da,Vec C) { PetscErrorCode ierr; PetscInt i,I,He,V,xs,xm,Mx,cnt = 0; Concentrations *c; PetscReal hx,x; char string[16]; PetscFunctionBeginUser; ierr = DMDAGetInfo(da,PETSC_IGNORE,&Mx,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);CHKERRQ(ierr); hx = 1.0/(PetscReal)(Mx-1); /* Name each of the concentrations */ for (He=1; He<N+1; He++) { ierr = PetscSNPrintf(string,16,"%d-He",He);CHKERRQ(ierr); ierr = DMDASetFieldName(da,cnt++,string);CHKERRQ(ierr); } for (V=1; V<N+1; V++) { ierr = PetscSNPrintf(string,16,"%d-V",V);CHKERRQ(ierr); ierr = DMDASetFieldName(da,cnt++,string);CHKERRQ(ierr); } for (I=1; I<N+1; I++) { ierr = PetscSNPrintf(string,16,"%d-I",I);CHKERRQ(ierr); ierr = DMDASetFieldName(da,cnt++,string);CHKERRQ(ierr); } for (He=1; He<N+1; He++) { for (V=1; V<N+1; V++) { ierr = PetscSNPrintf(string,16,"%d-He-%d-V",He,V);CHKERRQ(ierr); ierr = DMDASetFieldName(da,cnt++,string);CHKERRQ(ierr); } } /* Get pointer to vector data */ ierr = DMDAVecGetArray(da,C,&c);CHKERRQ(ierr); /* Shift the c pointer to allow accessing with index of 1, instead of 0 */ c = (Concentrations*)(((PetscScalar*)c)-1); /* Get local grid boundaries */ ierr = DMDAGetCorners(da,&xs,PETSC_NULL,PETSC_NULL,&xm,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); /* Compute function over the locally owned part of the grid */ for (i=xs; i<xs+xm; i++) { x = i*hx; for (He=1; He<N+1; He++) { c[i].He[He] = 0.0; } for (V=1; V<N+1; V++) { c[i].V[V] = 1.0; } for (I=1; I<N+1; I++) { c[i].I[I] = 1.0; } for (He=1; He<N+1; He++) { for (V=1; V<N+1; V++) { c[i].HeV[He][V] = 0.0; } } } /* Restore vectors */ c = (Concentrations*)(((PetscScalar*)c)+1); ierr = DMDAVecRestoreArray(da,C,&c);CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc, char *argv[]) { PetscErrorCode ierr; DM dau,dak,pack; const PetscInt *lxu; PetscInt *lxk,m,sizes; User user; SNES snes; Vec X,F,Xu,Xk,Fu,Fk; Mat B; IS *isg; PetscBool view_draw,pass_dm; PetscInitialize(&argc,&argv,0,help); ierr = DMDACreate1d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,-10,1,1,NULL,&dau);CHKERRQ(ierr); ierr = DMSetOptionsPrefix(dau,"u_");CHKERRQ(ierr); ierr = DMSetFromOptions(dau);CHKERRQ(ierr); ierr = DMDAGetOwnershipRanges(dau,&lxu,0,0);CHKERRQ(ierr); ierr = DMDAGetInfo(dau,0, &m,0,0, &sizes,0,0, 0,0,0,0,0,0);CHKERRQ(ierr); ierr = PetscMalloc1(sizes,&lxk);CHKERRQ(ierr); ierr = PetscMemcpy(lxk,lxu,sizes*sizeof(*lxk));CHKERRQ(ierr); lxk[0]--; ierr = DMDACreate1d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,m-1,1,1,lxk,&dak);CHKERRQ(ierr); ierr = DMSetOptionsPrefix(dak,"k_");CHKERRQ(ierr); ierr = DMSetFromOptions(dak);CHKERRQ(ierr); ierr = PetscFree(lxk);CHKERRQ(ierr); ierr = DMCompositeCreate(PETSC_COMM_WORLD,&pack);CHKERRQ(ierr); ierr = DMSetOptionsPrefix(pack,"pack_");CHKERRQ(ierr); ierr = DMCompositeAddDM(pack,dau);CHKERRQ(ierr); ierr = DMCompositeAddDM(pack,dak);CHKERRQ(ierr); ierr = DMDASetFieldName(dau,0,"u");CHKERRQ(ierr); ierr = DMDASetFieldName(dak,0,"k");CHKERRQ(ierr); ierr = DMSetFromOptions(pack);CHKERRQ(ierr); ierr = DMCreateGlobalVector(pack,&X);CHKERRQ(ierr); ierr = VecDuplicate(X,&F);CHKERRQ(ierr); ierr = PetscNew(&user);CHKERRQ(ierr); user->pack = pack; ierr = DMCompositeGetGlobalISs(pack,&isg);CHKERRQ(ierr); ierr = DMCompositeGetLocalVectors(pack,&user->Uloc,&user->Kloc);CHKERRQ(ierr); ierr = DMCompositeScatter(pack,X,user->Uloc,user->Kloc);CHKERRQ(ierr); ierr = PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"Coupled problem options","SNES");CHKERRQ(ierr); { user->ptype = 0; view_draw = PETSC_FALSE; pass_dm = PETSC_TRUE; ierr = PetscOptionsInt("-problem_type","0: solve for u only, 1: solve for k only, 2: solve for both",0,user->ptype,&user->ptype,NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-view_draw","Draw the final coupled solution regardless of whether only one physics was solved",0,view_draw,&view_draw,NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-pass_dm","Pass the packed DM to SNES to use when determining splits and forward into splits",0,pass_dm,&pass_dm,NULL);CHKERRQ(ierr); } ierr = PetscOptionsEnd();CHKERRQ(ierr); ierr = FormInitial_Coupled(user,X);CHKERRQ(ierr); ierr = SNESCreate(PETSC_COMM_WORLD,&snes);CHKERRQ(ierr); switch (user->ptype) { case 0: ierr = DMCompositeGetAccess(pack,X,&Xu,0);CHKERRQ(ierr); ierr = DMCompositeGetAccess(pack,F,&Fu,0);CHKERRQ(ierr); ierr = DMCreateMatrix(dau,&B);CHKERRQ(ierr); ierr = SNESSetFunction(snes,Fu,FormFunction_All,user);CHKERRQ(ierr); ierr = SNESSetJacobian(snes,B,B,FormJacobian_All,user);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); ierr = SNESSetDM(snes,dau);CHKERRQ(ierr); ierr = SNESSolve(snes,NULL,Xu);CHKERRQ(ierr); ierr = DMCompositeRestoreAccess(pack,X,&Xu,0);CHKERRQ(ierr); ierr = DMCompositeRestoreAccess(pack,F,&Fu,0);CHKERRQ(ierr); break; case 1: ierr = DMCompositeGetAccess(pack,X,0,&Xk);CHKERRQ(ierr); ierr = DMCompositeGetAccess(pack,F,0,&Fk);CHKERRQ(ierr); ierr = DMCreateMatrix(dak,&B);CHKERRQ(ierr); ierr = SNESSetFunction(snes,Fk,FormFunction_All,user);CHKERRQ(ierr); ierr = SNESSetJacobian(snes,B,B,FormJacobian_All,user);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); ierr = SNESSetDM(snes,dak);CHKERRQ(ierr); ierr = SNESSolve(snes,NULL,Xk);CHKERRQ(ierr); ierr = DMCompositeRestoreAccess(pack,X,0,&Xk);CHKERRQ(ierr); ierr = DMCompositeRestoreAccess(pack,F,0,&Fk);CHKERRQ(ierr); break; case 2: ierr = DMCreateMatrix(pack,&B);CHKERRQ(ierr); /* This example does not correctly allocate off-diagonal blocks. These options allows new nonzeros (slow). */ ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); ierr = SNESSetFunction(snes,F,FormFunction_All,user);CHKERRQ(ierr); ierr = SNESSetJacobian(snes,B,B,FormJacobian_All,user);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); if (!pass_dm) { /* Manually provide index sets and names for the splits */ KSP ksp; PC pc; ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); ierr = PCFieldSplitSetIS(pc,"u",isg[0]);CHKERRQ(ierr); ierr = PCFieldSplitSetIS(pc,"k",isg[1]);CHKERRQ(ierr); } else { /* The same names come from the options prefix for dau and dak. This option can support geometric multigrid inside * of splits, but it requires using a DM (perhaps your own implementation). */ ierr = SNESSetDM(snes,pack);CHKERRQ(ierr); } ierr = SNESSolve(snes,NULL,X);CHKERRQ(ierr); break; } if (view_draw) {ierr = VecView(X,PETSC_VIEWER_DRAW_WORLD);CHKERRQ(ierr);} if (0) { PetscInt col = 0; PetscBool mult_dup = PETSC_FALSE,view_dup = PETSC_FALSE; Mat D; Vec Y; ierr = PetscOptionsGetInt(0,"-col",&col,0);CHKERRQ(ierr); ierr = PetscOptionsGetBool(0,"-mult_dup",&mult_dup,0);CHKERRQ(ierr); ierr = PetscOptionsGetBool(0,"-view_dup",&view_dup,0);CHKERRQ(ierr); ierr = VecDuplicate(X,&Y);CHKERRQ(ierr); /* ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); */ /* ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); */ ierr = MatConvert(B,MATAIJ,MAT_INITIAL_MATRIX,&D);CHKERRQ(ierr); ierr = VecZeroEntries(X);CHKERRQ(ierr); ierr = VecSetValue(X,col,1.0,INSERT_VALUES);CHKERRQ(ierr); ierr = VecAssemblyBegin(X);CHKERRQ(ierr); ierr = VecAssemblyEnd(X);CHKERRQ(ierr); ierr = MatMult(mult_dup ? D : B,X,Y);CHKERRQ(ierr); ierr = MatView(view_dup ? D : B,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); /* ierr = VecView(X,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); */ ierr = VecView(Y,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = MatDestroy(&D);CHKERRQ(ierr); ierr = VecDestroy(&Y);CHKERRQ(ierr); } ierr = DMCompositeRestoreLocalVectors(pack,&user->Uloc,&user->Kloc);CHKERRQ(ierr); ierr = PetscFree(user);CHKERRQ(ierr); ierr = ISDestroy(&isg[0]);CHKERRQ(ierr); ierr = ISDestroy(&isg[1]);CHKERRQ(ierr); ierr = PetscFree(isg);CHKERRQ(ierr); ierr = VecDestroy(&X);CHKERRQ(ierr); ierr = VecDestroy(&F);CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); ierr = DMDestroy(&dau);CHKERRQ(ierr); ierr = DMDestroy(&dak);CHKERRQ(ierr); ierr = DMDestroy(&pack);CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); PetscFinalize(); return 0; }
int main(int argc,char **argv) { PetscInt M = 10,N = 8,dof=1,s=1,bx=0,by=0,i,n,j,k,m,wrap,xs,ys; PetscErrorCode ierr; DM da,dac; PetscViewer viewer; Vec local,global,coors; PetscScalar ***xy,***aglobal; PetscDraw draw; char fname[16]; ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; /* Create viewers */ ierr = PetscViewerDrawOpen(PETSC_COMM_WORLD,0,"",PETSC_DECIDE,PETSC_DECIDE,600,200,&viewer);CHKERRQ(ierr); ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); ierr = PetscDrawSetDoubleBuffer(draw);CHKERRQ(ierr); /* Read options */ ierr = PetscOptionsGetInt(NULL,NULL,"-M",&M,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-N",&N,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-dof",&dof,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-s",&s,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-periodic_x",&wrap,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-periodic_y",&wrap,NULL);CHKERRQ(ierr); /* Create distributed array and get vectors */ ierr = DMDACreate2d(PETSC_COMM_WORLD,(DMBoundaryType)bx,(DMBoundaryType)by,DMDA_STENCIL_BOX,M,N,PETSC_DECIDE,PETSC_DECIDE,dof,s,NULL,NULL,&da);CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMSetUp(da);CHKERRQ(ierr); ierr = DMDASetUniformCoordinates(da,0.0,1.0,0.0,1.0,0.0,0.0);CHKERRQ(ierr); for (i=0; i<dof; i++) { sprintf(fname,"Field %d",(int)i); ierr = DMDASetFieldName(da,i,fname);CHKERRQ(ierr); } ierr = DMView(da,viewer);CHKERRQ(ierr); ierr = DMCreateGlobalVector(da,&global);CHKERRQ(ierr); ierr = DMCreateLocalVector(da,&local);CHKERRQ(ierr); ierr = DMGetCoordinates(da,&coors);CHKERRQ(ierr); ierr = DMGetCoordinateDM(da,&dac);CHKERRQ(ierr); /* Set values into global vectors */ ierr = DMDAVecGetArrayDOFRead(dac,coors,&xy);CHKERRQ(ierr); ierr = DMDAVecGetArrayDOF(da,global,&aglobal);CHKERRQ(ierr); ierr = DMDAGetCorners(da,&xs,&ys,0,&m,&n,0);CHKERRQ(ierr); for (k=0; k<dof; k++) { for (j=ys; j<ys+n; j++) { for (i=xs; i<xs+m; i++) { aglobal[j][i][k] = PetscSinScalar(2.0*PETSC_PI*(k+1)*xy[j][i][0]); } } } ierr = DMDAVecRestoreArrayDOF(da,global,&aglobal);CHKERRQ(ierr); ierr = DMDAVecRestoreArrayDOFRead(dac,coors,&xy);CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(da,global,INSERT_VALUES,local);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(da,global,INSERT_VALUES,local);CHKERRQ(ierr); ierr = VecSet(global,0.0);CHKERRQ(ierr); ierr = DMLocalToGlobalBegin(da,local,INSERT_VALUES,global);CHKERRQ(ierr); ierr = DMLocalToGlobalEnd(da,local,INSERT_VALUES,global);CHKERRQ(ierr); ierr = VecView(global,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = VecView(global,viewer);CHKERRQ(ierr); /* Free memory */ ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); ierr = VecDestroy(&global);CHKERRQ(ierr); ierr = VecDestroy(&local);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
PetscErrorCode DMRefine_DA(DM da,MPI_Comm comm,DM *daref) { PetscErrorCode ierr; PetscInt M,N,P,i; DM da2; DM_DA *dd = (DM_DA*)da->data,*dd2; PetscFunctionBegin; PetscValidHeaderSpecific(da,DM_CLASSID,1); PetscValidPointer(daref,3); if (dd->bx == DMDA_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) { M = dd->refine_x*dd->M; } else { M = 1 + dd->refine_x*(dd->M - 1); } if (dd->by == DMDA_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) { if (dd->dim > 1) { N = dd->refine_y*dd->N; } else { N = 1; } } else { N = 1 + dd->refine_y*(dd->N - 1); } if (dd->bz == DMDA_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) { if (dd->dim > 2) { P = dd->refine_z*dd->P; } else { P = 1; } } else { P = 1 + dd->refine_z*(dd->P - 1); } ierr = DMDACreate(PetscObjectComm((PetscObject)da),&da2);CHKERRQ(ierr); ierr = DMSetOptionsPrefix(da2,((PetscObject)da)->prefix);CHKERRQ(ierr); ierr = DMDASetDim(da2,dd->dim);CHKERRQ(ierr); ierr = DMDASetSizes(da2,M,N,P);CHKERRQ(ierr); ierr = DMDASetNumProcs(da2,dd->m,dd->n,dd->p);CHKERRQ(ierr); ierr = DMDASetBoundaryType(da2,dd->bx,dd->by,dd->bz);CHKERRQ(ierr); ierr = DMDASetDof(da2,dd->w);CHKERRQ(ierr); ierr = DMDASetStencilType(da2,dd->stencil_type);CHKERRQ(ierr); ierr = DMDASetStencilWidth(da2,dd->s);CHKERRQ(ierr); if (dd->dim == 3) { PetscInt *lx,*ly,*lz; ierr = PetscMalloc3(dd->m,&lx,dd->n,&ly,dd->p,&lz);CHKERRQ(ierr); ierr = DMDARefineOwnershipRanges(da,(PetscBool)(dd->bx == DMDA_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0),dd->s,dd->refine_x,dd->m,dd->lx,lx);CHKERRQ(ierr); ierr = DMDARefineOwnershipRanges(da,(PetscBool)(dd->by == DMDA_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0),dd->s,dd->refine_y,dd->n,dd->ly,ly);CHKERRQ(ierr); ierr = DMDARefineOwnershipRanges(da,(PetscBool)(dd->bz == DMDA_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0),dd->s,dd->refine_z,dd->p,dd->lz,lz);CHKERRQ(ierr); ierr = DMDASetOwnershipRanges(da2,lx,ly,lz);CHKERRQ(ierr); ierr = PetscFree3(lx,ly,lz);CHKERRQ(ierr); } else if (dd->dim == 2) { PetscInt *lx,*ly; ierr = PetscMalloc2(dd->m,&lx,dd->n,&ly);CHKERRQ(ierr); ierr = DMDARefineOwnershipRanges(da,(PetscBool)(dd->bx == DMDA_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0),dd->s,dd->refine_x,dd->m,dd->lx,lx);CHKERRQ(ierr); ierr = DMDARefineOwnershipRanges(da,(PetscBool)(dd->by == DMDA_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0),dd->s,dd->refine_y,dd->n,dd->ly,ly);CHKERRQ(ierr); ierr = DMDASetOwnershipRanges(da2,lx,ly,NULL);CHKERRQ(ierr); ierr = PetscFree2(lx,ly);CHKERRQ(ierr); } else if (dd->dim == 1) { PetscInt *lx; ierr = PetscMalloc1(dd->m,&lx);CHKERRQ(ierr); ierr = DMDARefineOwnershipRanges(da,(PetscBool)(dd->bx == DMDA_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0),dd->s,dd->refine_x,dd->m,dd->lx,lx);CHKERRQ(ierr); ierr = DMDASetOwnershipRanges(da2,lx,NULL,NULL);CHKERRQ(ierr); ierr = PetscFree(lx);CHKERRQ(ierr); } dd2 = (DM_DA*)da2->data; /* allow overloaded (user replaced) operations to be inherited by refinement clones */ da2->ops->creatematrix = da->ops->creatematrix; /* da2->ops->createinterpolation = da->ops->createinterpolation; this causes problem with SNESVI */ da2->ops->getcoloring = da->ops->getcoloring; dd2->interptype = dd->interptype; /* copy fill information if given */ if (dd->dfill) { ierr = PetscMalloc1((dd->dfill[dd->w]+dd->w+1),&dd2->dfill);CHKERRQ(ierr); ierr = PetscMemcpy(dd2->dfill,dd->dfill,(dd->dfill[dd->w]+dd->w+1)*sizeof(PetscInt));CHKERRQ(ierr); } if (dd->ofill) { ierr = PetscMalloc1((dd->ofill[dd->w]+dd->w+1),&dd2->ofill);CHKERRQ(ierr); ierr = PetscMemcpy(dd2->ofill,dd->ofill,(dd->ofill[dd->w]+dd->w+1)*sizeof(PetscInt));CHKERRQ(ierr); } /* copy the refine information */ dd2->coarsen_x = dd2->refine_x = dd->refine_x; dd2->coarsen_y = dd2->refine_y = dd->refine_y; dd2->coarsen_z = dd2->refine_z = dd->refine_z; /* copy vector type information */ ierr = DMSetVecType(da2,da->vectype);CHKERRQ(ierr); dd2->lf = dd->lf; dd2->lj = dd->lj; da2->leveldown = da->leveldown; da2->levelup = da->levelup + 1; ierr = DMSetFromOptions(da2);CHKERRQ(ierr); ierr = DMSetUp(da2);CHKERRQ(ierr); /* interpolate coordinates if they are set on the coarse grid */ if (da->coordinates) { DM cdaf,cdac; Vec coordsc,coordsf; Mat II; ierr = DMGetCoordinateDM(da,&cdac);CHKERRQ(ierr); ierr = DMGetCoordinates(da,&coordsc);CHKERRQ(ierr); ierr = DMGetCoordinateDM(da2,&cdaf);CHKERRQ(ierr); /* force creation of the coordinate vector */ ierr = DMDASetUniformCoordinates(da2,0.0,1.0,0.0,1.0,0.0,1.0);CHKERRQ(ierr); ierr = DMGetCoordinates(da2,&coordsf);CHKERRQ(ierr); ierr = DMCreateInterpolation(cdac,cdaf,&II,NULL);CHKERRQ(ierr); ierr = MatInterpolate(II,coordsc,coordsf);CHKERRQ(ierr); ierr = MatDestroy(&II);CHKERRQ(ierr); } for (i=0; i<da->bs; i++) { const char *fieldname; ierr = DMDAGetFieldName(da,i,&fieldname);CHKERRQ(ierr); ierr = DMDASetFieldName(da2,i,fieldname);CHKERRQ(ierr); } *daref = da2; PetscFunctionReturn(0); }
int main(int argc,char **argv) { TS ts; /* nonlinear solver */ Vec U; /* solution, residual vectors */ Mat J; /* Jacobian matrix */ PetscInt maxsteps = 1000; PetscErrorCode ierr; DM da; AppCtx user; PetscInt i; char Name[16]; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Initialize program - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ PetscInitialize(&argc,&argv,(char*)0,help); user.N = 1; ierr = PetscOptionsGetInt(NULL,"-N",&user.N,NULL);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create distributed array (DMDA) to manage parallel grid and vectors - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMDACreate1d(PETSC_COMM_WORLD, DMDA_BOUNDARY_MIRROR,-8,user.N,1,NULL,&da);CHKERRQ(ierr); for (i=0; i<user.N; i++) { ierr = PetscSNPrintf(Name,16,"Void size %d",(int)(i+1)); ierr = DMDASetFieldName(da,i,Name);CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Extract global vectors from DMDA; then duplicate for remaining vectors that are the same types - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMCreateGlobalVector(da,&U);CHKERRQ(ierr); ierr = DMCreateMatrix(da,MATAIJ,&J);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create timestepping solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetType(ts,TSARKIMEX);CHKERRQ(ierr); ierr = TSSetDM(ts,da);CHKERRQ(ierr); ierr = TSSetProblemType(ts,TS_NONLINEAR);CHKERRQ(ierr); ierr = TSSetIFunction(ts,NULL,IFunction,&user);CHKERRQ(ierr); ierr = TSSetIJacobian(ts,J,J,IJacobian,&user);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set initial conditions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = InitialConditions(da,U);CHKERRQ(ierr); ierr = TSSetSolution(ts,U);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set solver options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetInitialTimeStep(ts,0.0,.001);CHKERRQ(ierr); ierr = TSSetDuration(ts,maxsteps,1.0);CHKERRQ(ierr); ierr = TSSetFromOptions(ts);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSolve(ts,U);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. All PETSc objects should be destroyed when they are no longer needed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = VecDestroy(&U);CHKERRQ(ierr); ierr = MatDestroy(&J);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize(); PetscFunctionReturn(0); }
int main(int argc,char **argv) { PetscErrorCode ierr; SNES snes; /* nonlinear solver */ Vec Hu; /* solution vector */ AppCtx user; /* user-defined work context */ ExactCtx exact; PetscInt its; /* snes reports iteration count */ SNESConvergedReason reason; /* snes reports convergence */ PetscReal tmp1, tmp2, tmp3, errnorms[2], scaleNode[2], descaleNode[2]; PetscInt i; char dumpfile[80],dxdocstr[80]; PetscBool eps_set = PETSC_FALSE, dump = PETSC_FALSE, exactinitial = PETSC_FALSE, snes_mf_set, snes_fd_set, dx_set; PetscInitialize(&argc,&argv,(char *)0,help); ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &user.rank); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "MARINE solves for thickness and velocity in 1D, steady marine ice sheet\n" " [run with -help for info and options]\n");CHKERRQ(ierr); user.n = 3.0; /* Glen flow law exponent */ user.secpera = 31556926.0; user.rho = 910.0; /* kg m^-3 */ user.rhow = 1028.0; /* kg m^-3 */ user.omega = 1.0 - user.rho / user.rhow; user.g = 9.81; /* m s^-2 */ /* get parameters of exact solution */ ierr = params_exactBod(&tmp1, &(exact.L0), &(exact.xg), &tmp2, &tmp3, &(user.k)); CHKERRQ(ierr); ierr = exactBod(exact.xg,&(exact.Hg),&tmp2,&(exact.Mg)); CHKERRQ(ierr); ierr = exactBodBueler(exact.xg,&tmp1,&(exact.Bg)); CHKERRQ(ierr); user.zocean = user.rho * exact.Hg / user.rhow; /* see ../marineshoot.py: */ #define xa_default 0.2 #define xc_default 0.98 /* define interval [xa,xc] */ user.xa = xa_default * exact.L0; user.xc = xc_default * exact.L0; /* get Dirichlet boundary conditions, and mass balance on shelf */ ierr = exactBod(user.xa, &(user.Ha), &(user.ua), &tmp1); CHKERRQ(ierr); /* regularize using strain rate of 1/(length) per year */ user.epsilon = (1.0 / user.secpera) / (user.xc - user.xa); /*user.epsilon = 0.0;*/ user.Hscale = 1000.0; user.uscale = 100.0 / user.secpera; user.noscale = PETSC_FALSE; user.dx = 10000.0; /* default to coarse 10 km grid */ ierr = PetscOptionsBegin(PETSC_COMM_WORLD, "","options to marine (steady marine ice sheet solver)","");CHKERRQ(ierr); { ierr = PetscOptionsBool("-snes_mf","","",PETSC_FALSE,&snes_mf_set,NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-snes_fd","","",PETSC_FALSE,&snes_fd_set,NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-noscale","","",PETSC_FALSE,&user.noscale,NULL);CHKERRQ(ierr); snprintf(dxdocstr,80,"target grid spacing (m) on interval of length %.0f m", user.xc-user.xa); ierr = PetscOptionsReal("-dx",dxdocstr,"",user.dx,&user.dx,&dx_set);CHKERRQ(ierr); ierr = PetscOptionsBool("-exactinit", "initialize using exact solution instead of default linear function","", PETSC_FALSE,&exactinitial,NULL);CHKERRQ(ierr); ierr = PetscOptionsString("-dump", "dump approx and exact solution into given file (as ascii matlab format)","", NULL,dumpfile,80,&dump);CHKERRQ(ierr); ierr = PetscOptionsReal("-epsilon","regularizing strain rate for stress computation (a-1)","", user.epsilon * user.secpera,&user.epsilon,&eps_set);CHKERRQ(ierr); if (eps_set) user.epsilon *= 1.0 / user.secpera; } ierr = PetscOptionsEnd();CHKERRQ(ierr); if (snes_fd_set) { ierr = PetscPrintf(PETSC_COMM_WORLD, " using approximate Jacobian; finite-differencing using coloring\n"); CHKERRQ(ierr); } else if (snes_mf_set) { ierr = PetscPrintf(PETSC_COMM_WORLD, " matrix free; no preconditioner\n"); CHKERRQ(ierr); } else { ierr = PetscPrintf(PETSC_COMM_WORLD, " true Jacobian\n"); CHKERRQ(ierr); } if (dx_set && (user.dx <= 0.0)) { PetscPrintf(PETSC_COMM_WORLD, "\n***ERROR: -dx value must be positive ... USAGE FOLLOWS ...\n\n%s",help); PetscEnd(); } user.N = (int)ceil( ((user.xc - user.xa) / user.dx) - 0.5 ); user.Mx = user.N + 2; user.dx = (user.xc - user.xa) / ((PetscReal)(user.N) + 0.5); /* recompute so dx * (N+1/2) = xc - xa */ if (dx_set && (user.dx < 1.0)) { PetscPrintf(PETSC_COMM_WORLD, "\n***WARNING: '-dx %.3f' meters is below one meter and creates grid of %d points\n" " ... probably uncomputable!\n\n", user.dx,user.Mx); } /* residual scaling coeffs; motivation at right */ user.rscHa = 1.0 / user.Hscale, /* Dirichlet cond for H */ user.rscua = 1.0 / user.uscale, /* Dirichlet cond for u */ user.rscuH = user.dx / (user.Hscale * user.uscale), /* flux derivative d(uH)/dx */ user.rscstress = 1.0 / (user.k * user.rho * user.g * user.Hscale * user.uscale), /* beta term in SSA */ user.rsccalv = 1.0 / (0.025 * user.rho * user.g * user.Hscale); /* 0.5 * omega * overburden */ /* Create machinery for parallel grid management (DMDA), nonlinear solver (SNES), and Vecs for fields (solution, RHS). Degrees of freedom = 2 (thickness and velocity at each point). */ ierr = DMDACreate1d(PETSC_COMM_WORLD,DMDA_BOUNDARY_NONE,user.Mx,2,1,PETSC_NULL,&user.da); CHKERRQ(ierr); ierr = DMSetApplicationContext(user.da,&user);CHKERRQ(ierr); ierr = DMDASetFieldName(user.da,0,"ice thickness [non-dimensional]"); CHKERRQ(ierr); ierr = DMDASetFieldName(user.da,1,"ice velocity [non-dimensional]"); CHKERRQ(ierr); ierr = DMSetFromOptions(user.da); CHKERRQ(ierr); ierr = DMDAGetInfo(user.da,PETSC_IGNORE,&user.Mx,PETSC_IGNORE, PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE, PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE, PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);CHKERRQ(ierr); ierr = DMDAGetCorners(user.da,&user.xs,PETSC_NULL,PETSC_NULL,&user.xm,PETSC_NULL,PETSC_NULL); CHKERRQ(ierr); /* another DMDA for scalar staggered parameters; one fewer point */ ierr = DMDACreate1d(PETSC_COMM_WORLD,DMDA_BOUNDARY_NONE,user.Mx-1,1,1,PETSC_NULL,&user.stagda); CHKERRQ(ierr); /* establish geometry on grid; note xa = x_0 and xc = x_{N+1/2} */ ierr = DMDASetUniformCoordinates(user.da, user.xa, user.xc+0.5*user.dx, 0.0,1.0,0.0,1.0);CHKERRQ(ierr); ierr = DMDASetUniformCoordinates(user.stagda,user.xa+0.5*user.dx,user.xc, 0.0,1.0,0.0,1.0);CHKERRQ(ierr); /* report on current grid */ ierr = PetscPrintf(PETSC_COMM_WORLD, " grid: Mx = N+2 = %D regular points, dx = %.3f m, xa = %.2f km, xc = %.2f km\n", user.Mx, user.dx, user.xa/1000.0, user.xc/1000.0);CHKERRQ(ierr); /* Extract/allocate global vectors from DMDAs and duplicate for remaining same types */ ierr = DMCreateGlobalVector(user.da,&Hu);CHKERRQ(ierr); ierr = VecSetBlockSize(Hu,2);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)Hu,"Hu");CHKERRQ(ierr); ierr = VecDuplicate(Hu,&exact.Hu);CHKERRQ(ierr); /* inherits block size */ ierr = PetscObjectSetName((PetscObject)exact.Hu,"exactHu");CHKERRQ(ierr); ierr = DMCreateGlobalVector(user.stagda,&user.Mstag);CHKERRQ(ierr); ierr = VecDuplicate(user.Mstag,&user.Bstag);CHKERRQ(ierr); /* set up snes */ ierr = SNESCreate(PETSC_COMM_WORLD,&snes);CHKERRQ(ierr); ierr = SNESSetDM(snes,user.da);CHKERRQ(ierr); ierr = DMDASNESSetFunctionLocal(user.da,INSERT_VALUES,(DMDASNESFunction)scshell,&user);CHKERRQ(ierr); ierr = DMDASNESSetJacobianLocal(user.da,(DMDASNESJacobian)JacobianMatrixLocal,&user);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); /* the exact thickness and exact ice velocity (user.uHexact) are known */ ierr = FillExactSoln(&exact, &user); CHKERRQ(ierr); /* the exact solution allows setting M(x), B(x) */ ierr = FillDistributedParams(&exact, &user);CHKERRQ(ierr); if (exactinitial) { ierr = PetscPrintf(PETSC_COMM_WORLD," using exact solution as initial guess\n"); CHKERRQ(ierr); /* the initial guess is the exact continuum solution */ ierr = VecCopy(exact.Hu,Hu); CHKERRQ(ierr); } else { /* the initial guess is a linear solution */ ierr = FillInitial(&user, &Hu); CHKERRQ(ierr); } /************ SOLVE NONLINEAR SYSTEM ************/ /* recall that RHS r is used internally by KSP, and is set by the SNES */ if (user.noscale) { user.Hscale = 1.0; user.uscale = 1.0; } scaleNode[0] = user.Hscale; scaleNode[1] = user.uscale; for (i = 0; i < 2; i++) descaleNode[i] = 1.0 / scaleNode[i]; ierr = VecStrideScaleAll(Hu,descaleNode); CHKERRQ(ierr); /* de-dimensionalize initial guess */ ierr = SNESSolve(snes,PETSC_NULL,Hu);CHKERRQ(ierr); ierr = VecStrideScaleAll(Hu,scaleNode); CHKERRQ(ierr); /* put back in "real" scale */ /* minimal report on solve */ ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr); ierr = SNESGetConvergedReason(snes,&reason);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, " %s Number of Newton iterations = %D\n", SNESConvergedReasons[reason],its);CHKERRQ(ierr); if (dump) { ierr = PetscPrintf(PETSC_COMM_WORLD, "dumping results in ascii matlab format to file '%s' ...\n",dumpfile);CHKERRQ(ierr); PetscViewer viewer; ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD,dumpfile,&viewer);CHKERRQ(ierr); ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); DM coord_da; Vec coord_x; ierr = DMGetCoordinateDM(user.da, &coord_da); CHKERRQ(ierr); ierr = DMGetCoordinates(user.da, &coord_x); CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"%% START MATLAB\n"); CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)coord_x,"x");CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"%% viewing coordinate vector x \n");CHKERRQ(ierr); ierr = VecView(coord_x,viewer); CHKERRQ(ierr); ierr = VecView(Hu,viewer); CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"%% viewing combined result Hu\n");CHKERRQ(ierr); ierr = VecView(Hu,viewer); CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"%% viewing combined exact result exactHu\n");CHKERRQ(ierr); ierr = VecView(exact.Hu,viewer); CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer, "%% defining plottable variables and plotting in Matlab\n" "Mx = %d; secpera = 31556926.0;\n" "H = Hu(1:2:2*Mx-1);\n" "u = Hu(2:2:2*Mx);\n" "exactH = exactHu(1:2:2*Mx-1);\n" "exactu = exactHu(2:2:2*Mx);\n" "figure, plot(x,H,x,exactH);\n" "legend('numerical','exact'), xlabel x, ylabel('H (m)')\n" "figure, plot(x,u*secpera,x,exactu*secpera);\n" "legend('numerical','exact'), xlabel x, ylabel('u (m/a)')\n" "figure, subplot(2,1,1), semilogy(x,abs(H-exactH));\n" "ylabel('H error (m)'), grid\n" "subplot(2,1,2), semilogy(x,abs(u-exactu)*secpera);\n" "xlabel x, ylabel('u error (m/a)'), grid\n", user.Mx); CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"%% END MATLAB\n"); CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); } /* evaluate error relative to exact solution */ ierr = VecAXPY(Hu,-1.0,exact.Hu); CHKERRQ(ierr); /* Hu = - Huexact + Hu */ ierr = VecStrideNormAll(Hu,NORM_INFINITY,errnorms); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "(dx,errHinf,erruinf) %.3f %.4e %.4e\n", user.dx,errnorms[0],errnorms[1]*user.secpera);CHKERRQ(ierr); ierr = VecDestroy(&Hu);CHKERRQ(ierr); ierr = VecDestroy(&(exact.Hu));CHKERRQ(ierr); ierr = VecDestroy(&(user.Mstag));CHKERRQ(ierr); ierr = VecDestroy(&(user.Bstag));CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = DMDestroy(&(user.da));CHKERRQ(ierr); ierr = DMDestroy(&(user.stagda));CHKERRQ(ierr); ierr = PetscFinalize();CHKERRQ(ierr); return 0; }
PetscErrorCode DMCoarsen_DA(DM da, MPI_Comm comm,DM *daref) { PetscErrorCode ierr; PetscInt M,N,P,i; DM da2; DM_DA *dd = (DM_DA*)da->data,*dd2; PetscFunctionBegin; PetscValidHeaderSpecific(da,DM_CLASSID,1); PetscValidPointer(daref,3); if (dd->bx == DMDA_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0){ M = dd->M / dd->coarsen_x; } else { M = 1 + (dd->M - 1) / dd->coarsen_x; } if (dd->by == DMDA_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0){ if (dd->dim > 1) { N = dd->N / dd->coarsen_y; } else { N = 1; } } else { N = 1 + (dd->N - 1) / dd->coarsen_y; } if (dd->bz == DMDA_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0){ if (dd->dim > 2) { P = dd->P / dd->coarsen_z; } else { P = 1; } } else { P = 1 + (dd->P - 1) / dd->coarsen_z; } ierr = DMDACreate(((PetscObject)da)->comm,&da2);CHKERRQ(ierr); ierr = DMSetOptionsPrefix(da2,((PetscObject)da)->prefix);CHKERRQ(ierr); ierr = DMDASetDim(da2,dd->dim);CHKERRQ(ierr); ierr = DMDASetSizes(da2,M,N,P);CHKERRQ(ierr); ierr = DMDASetNumProcs(da2,dd->m,dd->n,dd->p);CHKERRQ(ierr); ierr = DMDASetBoundaryType(da2,dd->bx,dd->by,dd->bz);CHKERRQ(ierr); ierr = DMDASetDof(da2,dd->w);CHKERRQ(ierr); ierr = DMDASetStencilType(da2,dd->stencil_type);CHKERRQ(ierr); ierr = DMDASetStencilWidth(da2,dd->s);CHKERRQ(ierr); if (dd->dim == 3) { PetscInt *lx,*ly,*lz; ierr = PetscMalloc3(dd->m,PetscInt,&lx,dd->n,PetscInt,&ly,dd->p,PetscInt,&lz);CHKERRQ(ierr); ierr = DMDACoarsenOwnershipRanges(da,(PetscBool)(dd->bx == DMDA_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0),dd->s,dd->coarsen_x,dd->m,dd->lx,lx);CHKERRQ(ierr); ierr = DMDACoarsenOwnershipRanges(da,(PetscBool)(dd->by == DMDA_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0),dd->s,dd->coarsen_y,dd->n,dd->ly,ly);CHKERRQ(ierr); ierr = DMDACoarsenOwnershipRanges(da,(PetscBool)(dd->bz == DMDA_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0),dd->s,dd->coarsen_z,dd->p,dd->lz,lz);CHKERRQ(ierr); ierr = DMDASetOwnershipRanges(da2,lx,ly,lz);CHKERRQ(ierr); ierr = PetscFree3(lx,ly,lz);CHKERRQ(ierr); } else if (dd->dim == 2) { PetscInt *lx,*ly; ierr = PetscMalloc2(dd->m,PetscInt,&lx,dd->n,PetscInt,&ly);CHKERRQ(ierr); ierr = DMDACoarsenOwnershipRanges(da,(PetscBool)(dd->bx == DMDA_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0),dd->s,dd->coarsen_x,dd->m,dd->lx,lx);CHKERRQ(ierr); ierr = DMDACoarsenOwnershipRanges(da,(PetscBool)(dd->by == DMDA_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0),dd->s,dd->coarsen_y,dd->n,dd->ly,ly);CHKERRQ(ierr); ierr = DMDASetOwnershipRanges(da2,lx,ly,PETSC_NULL);CHKERRQ(ierr); ierr = PetscFree2(lx,ly);CHKERRQ(ierr); } else if (dd->dim == 1) { PetscInt *lx; ierr = PetscMalloc(dd->m*sizeof(PetscInt),&lx);CHKERRQ(ierr); ierr = DMDACoarsenOwnershipRanges(da,(PetscBool)(dd->bx == DMDA_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0),dd->s,dd->coarsen_x,dd->m,dd->lx,lx);CHKERRQ(ierr); ierr = DMDASetOwnershipRanges(da2,lx,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); ierr = PetscFree(lx);CHKERRQ(ierr); } dd2 = (DM_DA*)da2->data; /* allow overloaded (user replaced) operations to be inherited by refinement clones; why are only some inherited and not all? */ /* da2->ops->createinterpolation = da->ops->createinterpolation; copying this one causes trouble for DMSetVI */ da2->ops->creatematrix = da->ops->creatematrix; da2->ops->getcoloring = da->ops->getcoloring; dd2->interptype = dd->interptype; /* copy fill information if given */ if (dd->dfill) { ierr = PetscMalloc((dd->dfill[dd->w]+dd->w+1)*sizeof(PetscInt),&dd2->dfill);CHKERRQ(ierr); ierr = PetscMemcpy(dd2->dfill,dd->dfill,(dd->dfill[dd->w]+dd->w+1)*sizeof(PetscInt));CHKERRQ(ierr); } if (dd->ofill) { ierr = PetscMalloc((dd->ofill[dd->w]+dd->w+1)*sizeof(PetscInt),&dd2->ofill);CHKERRQ(ierr); ierr = PetscMemcpy(dd2->ofill,dd->ofill,(dd->ofill[dd->w]+dd->w+1)*sizeof(PetscInt));CHKERRQ(ierr); } /* copy the refine information */ dd2->coarsen_x = dd2->refine_x = dd->coarsen_x; dd2->coarsen_y = dd2->refine_y = dd->coarsen_y; dd2->coarsen_z = dd2->refine_z = dd->coarsen_z; /* copy vector type information */ ierr = PetscFree(da2->vectype);CHKERRQ(ierr); ierr = PetscStrallocpy(da->vectype,(char**)&da2->vectype);CHKERRQ(ierr); dd2->lf = dd->lf; dd2->lj = dd->lj; da2->leveldown = da->leveldown + 1; da2->levelup = da->levelup; ierr = DMSetFromOptions(da2);CHKERRQ(ierr); ierr = DMSetUp(da2);CHKERRQ(ierr); ierr = DMViewFromOptions(da2,"-dm_view");CHKERRQ(ierr); /* inject coordinates if they are set on the fine grid */ if (da->coordinates) { DM cdaf,cdac; Vec coordsc,coordsf; VecScatter inject; ierr = DMGetCoordinateDM(da,&cdaf);CHKERRQ(ierr); ierr = DMGetCoordinates(da,&coordsf);CHKERRQ(ierr); ierr = DMGetCoordinateDM(da2,&cdac);CHKERRQ(ierr); /* force creation of the coordinate vector */ ierr = DMDASetUniformCoordinates(da2,0.0,1.0,0.0,1.0,0.0,1.0);CHKERRQ(ierr); ierr = DMGetCoordinates(da2,&coordsc);CHKERRQ(ierr); ierr = DMCreateInjection(cdac,cdaf,&inject);CHKERRQ(ierr); ierr = VecScatterBegin(inject,coordsf,coordsc,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(inject ,coordsf,coordsc,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterDestroy(&inject);CHKERRQ(ierr); } for (i=0; i<da->bs; i++) { const char *fieldname; ierr = DMDAGetFieldName(da,i,&fieldname);CHKERRQ(ierr); ierr = DMDASetFieldName(da2,i,fieldname);CHKERRQ(ierr); } *daref = da2; PetscFunctionReturn(0); }
int main(int argc,char **argv) { AppCtx user; /* user-defined work context */ PetscInt mx,my,its; PetscErrorCode ierr; MPI_Comm comm; SNES snes; DM da; Vec x,X,b; PetscBool youngflg,poissonflg,muflg,lambdaflg,view=PETSC_FALSE,viewline=PETSC_FALSE; PetscReal poisson=0.2,young=4e4; char filename[PETSC_MAX_PATH_LEN] = "ex16.vts"; char filename_def[PETSC_MAX_PATH_LEN] = "ex16_def.vts"; ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; ierr = FormElements();CHKERRQ(ierr); comm = PETSC_COMM_WORLD; ierr = SNESCreate(comm,&snes);CHKERRQ(ierr); ierr = DMDACreate3d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE,DMDA_STENCIL_BOX,11,2,2,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,3,1,NULL,NULL,NULL,&da);CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMSetUp(da);CHKERRQ(ierr); ierr = SNESSetDM(snes,(DM)da);CHKERRQ(ierr); ierr = SNESSetNGS(snes,NonlinearGS,&user);CHKERRQ(ierr); ierr = DMDAGetInfo(da,0,&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.loading = 0.0; user.arc = PETSC_PI/3.; user.mu = 4.0; user.lambda = 1.0; user.rad = 100.0; user.height = 3.; user.width = 1.; user.ploading = -5e3; ierr = PetscOptionsGetReal(NULL,NULL,"-arc",&user.arc,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,NULL,"-mu",&user.mu,&muflg);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,NULL,"-lambda",&user.lambda,&lambdaflg);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,NULL,"-rad",&user.rad,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,NULL,"-height",&user.height,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,NULL,"-width",&user.width,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,NULL,"-loading",&user.loading,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,NULL,"-ploading",&user.ploading,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,NULL,"-poisson",&poisson,&poissonflg);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,NULL,"-young",&young,&youngflg);CHKERRQ(ierr); if ((youngflg || poissonflg) || !(muflg || lambdaflg)) { /* set the lame' parameters based upon the poisson ratio and young's modulus */ user.lambda = poisson*young / ((1. + poisson)*(1. - 2.*poisson)); user.mu = young/(2.*(1. + poisson)); } ierr = PetscOptionsGetBool(NULL,NULL,"-view",&view,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-view_line",&viewline,NULL);CHKERRQ(ierr); ierr = DMDASetFieldName(da,0,"x_disp");CHKERRQ(ierr); ierr = DMDASetFieldName(da,1,"y_disp");CHKERRQ(ierr); ierr = DMDASetFieldName(da,2,"z_disp");CHKERRQ(ierr); ierr = DMSetApplicationContext(da,&user);CHKERRQ(ierr); ierr = DMDASNESSetFunctionLocal(da,INSERT_VALUES,(PetscErrorCode (*)(DMDALocalInfo*,void*,void*,void*))FormFunctionLocal,&user);CHKERRQ(ierr); ierr = DMDASNESSetJacobianLocal(da,(DMDASNESJacobian)FormJacobianLocal,&user);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); ierr = FormCoordinates(da,&user);CHKERRQ(ierr); ierr = DMCreateGlobalVector(da,&x);CHKERRQ(ierr); ierr = DMCreateGlobalVector(da,&b);CHKERRQ(ierr); ierr = InitialGuess(da,&user,x);CHKERRQ(ierr); ierr = FormRHS(da,&user,b);CHKERRQ(ierr); ierr = PetscPrintf(comm,"lambda: %f mu: %f\n",(double)user.lambda,(double)user.mu);CHKERRQ(ierr); /* show a cross-section of the initial state */ if (viewline) { ierr = DisplayLine(snes,x);CHKERRQ(ierr); } /* get the loaded configuration */ ierr = SNESSolve(snes,b,x);CHKERRQ(ierr); ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr); ierr = PetscPrintf(comm,"Number of SNES iterations = %D\n", its);CHKERRQ(ierr); ierr = SNESGetSolution(snes,&X);CHKERRQ(ierr); /* show a cross-section of the final state */ if (viewline) { ierr = DisplayLine(snes,X);CHKERRQ(ierr); } if (view) { PetscViewer viewer; Vec coords; ierr = PetscViewerVTKOpen(PETSC_COMM_WORLD,filename,FILE_MODE_WRITE,&viewer);CHKERRQ(ierr); ierr = VecView(x,viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); ierr = DMGetCoordinates(da,&coords);CHKERRQ(ierr); ierr = VecAXPY(coords,1.0,x);CHKERRQ(ierr); ierr = PetscViewerVTKOpen(PETSC_COMM_WORLD,filename_def,FILE_MODE_WRITE,&viewer);CHKERRQ(ierr); ierr = VecView(x,viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); } ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
/*@ DMDASetUniformCoordinates - Sets a DMDA coordinates to be a uniform grid Collective on DMDA Input Parameters: + da - the distributed array object . xmin,xmax - extremes in the x direction . ymin,ymax - extremes in the y direction (use NULL for 1 dimensional problems) - zmin,zmax - extremes in the z direction (use NULL for 1 or 2 dimensional problems) Level: beginner .seealso: DMSetCoordinates(), DMGetCoordinates(), DMDACreate1d(), DMDACreate2d(), DMDACreate3d() @*/ PetscErrorCode DMDASetUniformCoordinates(DM da,PetscReal xmin,PetscReal xmax,PetscReal ymin,PetscReal ymax,PetscReal zmin,PetscReal zmax) { MPI_Comm comm; PetscSection section; DM cda; DMBoundaryType bx,by,bz; Vec xcoor; PetscScalar *coors; PetscReal hx,hy,hz_; PetscInt i,j,k,M,N,P,istart,isize,jstart,jsize,kstart,ksize,dim,cnt; PetscErrorCode ierr; PetscFunctionBegin; PetscValidHeaderSpecific(da,DM_CLASSID,1); ierr = DMDAGetInfo(da,&dim,&M,&N,&P,0,0,0,0,0,&bx,&by,&bz,0);CHKERRQ(ierr); if (xmax <= xmin) SETERRQ2(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_INCOMP,"xmax must be larger than xmin %g %g",(double)xmin,(double)xmax); if ((ymax <= ymin) && (dim > 1)) SETERRQ2(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_INCOMP,"ymax must be larger than ymin %g %g",(double)ymin,(double)ymax); if ((zmax <= zmin) && (dim > 2)) SETERRQ2(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_INCOMP,"zmax must be larger than zmin %g %g",(double)zmin,(double)zmax); ierr = PetscObjectGetComm((PetscObject)da,&comm);CHKERRQ(ierr); ierr = DMGetDefaultSection(da,§ion);CHKERRQ(ierr); ierr = DMDAGetCorners(da,&istart,&jstart,&kstart,&isize,&jsize,&ksize);CHKERRQ(ierr); ierr = DMGetCoordinateDM(da, &cda);CHKERRQ(ierr); if (section) { /* This would be better as a vector, but this is compatible */ PetscInt numComp[3] = {1, 1, 1}; PetscInt numVertexDof[3] = {1, 1, 1}; ierr = DMDASetFieldName(cda, 0, "x");CHKERRQ(ierr); if (dim > 1) {ierr = DMDASetFieldName(cda, 1, "y");CHKERRQ(ierr);} if (dim > 2) {ierr = DMDASetFieldName(cda, 2, "z");CHKERRQ(ierr);} ierr = DMDACreateSection(cda, numComp, numVertexDof, NULL, NULL);CHKERRQ(ierr); } ierr = DMCreateGlobalVector(cda, &xcoor);CHKERRQ(ierr); if (section) { PetscSection csection; PetscInt vStart, vEnd; ierr = DMGetDefaultGlobalSection(cda,&csection);CHKERRQ(ierr); ierr = VecGetArray(xcoor,&coors);CHKERRQ(ierr); ierr = DMDAGetHeightStratum(da, dim, &vStart, &vEnd);CHKERRQ(ierr); if (bx == DM_BOUNDARY_PERIODIC) hx = (xmax-xmin)/(M+1); else hx = (xmax-xmin)/(M ? M : 1); if (by == DM_BOUNDARY_PERIODIC) hy = (ymax-ymin)/(N+1); else hy = (ymax-ymin)/(N ? N : 1); if (bz == DM_BOUNDARY_PERIODIC) hz_ = (zmax-zmin)/(P+1); else hz_ = (zmax-zmin)/(P ? P : 1); switch (dim) { case 1: for (i = 0; i < isize+1; ++i) { PetscInt v = i+vStart, dof, off; ierr = PetscSectionGetDof(csection, v, &dof);CHKERRQ(ierr); ierr = PetscSectionGetOffset(csection, v, &off);CHKERRQ(ierr); if (off >= 0) { coors[off] = xmin + hx*(i+istart); } } break; case 2: for (j = 0; j < jsize+1; ++j) { for (i = 0; i < isize+1; ++i) { PetscInt v = j*(isize+1)+i+vStart, dof, off; ierr = PetscSectionGetDof(csection, v, &dof);CHKERRQ(ierr); ierr = PetscSectionGetOffset(csection, v, &off);CHKERRQ(ierr); if (off >= 0) { coors[off+0] = xmin + hx*(i+istart); coors[off+1] = ymin + hy*(j+jstart); } } } break; case 3: for (k = 0; k < ksize+1; ++k) { for (j = 0; j < jsize+1; ++j) { for (i = 0; i < isize+1; ++i) { PetscInt v = (k*(jsize+1)+j)*(isize+1)+i+vStart, dof, off; ierr = PetscSectionGetDof(csection, v, &dof);CHKERRQ(ierr); ierr = PetscSectionGetOffset(csection, v, &off);CHKERRQ(ierr); if (off >= 0) { coors[off+0] = xmin + hx*(i+istart); coors[off+1] = ymin + hy*(j+jstart); coors[off+2] = zmin + hz_*(k+kstart); } } } } break; default: SETERRQ1(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Cannot create uniform coordinates for this dimension %D\n",dim); } ierr = VecRestoreArray(xcoor,&coors);CHKERRQ(ierr); ierr = DMSetCoordinates(da,xcoor);CHKERRQ(ierr); ierr = PetscLogObjectParent((PetscObject)da,(PetscObject)xcoor);CHKERRQ(ierr); ierr = VecDestroy(&xcoor);CHKERRQ(ierr); PetscFunctionReturn(0); } if (dim == 1) { if (bx == DM_BOUNDARY_PERIODIC) hx = (xmax-xmin)/M; else hx = (xmax-xmin)/(M-1); ierr = VecGetArray(xcoor,&coors);CHKERRQ(ierr); for (i=0; i<isize; i++) { coors[i] = xmin + hx*(i+istart); } ierr = VecRestoreArray(xcoor,&coors);CHKERRQ(ierr); } else if (dim == 2) { if (bx == DM_BOUNDARY_PERIODIC) hx = (xmax-xmin)/(M); else hx = (xmax-xmin)/(M-1); if (by == DM_BOUNDARY_PERIODIC) hy = (ymax-ymin)/(N); else hy = (ymax-ymin)/(N-1); ierr = VecGetArray(xcoor,&coors);CHKERRQ(ierr); cnt = 0; for (j=0; j<jsize; j++) { for (i=0; i<isize; i++) { coors[cnt++] = xmin + hx*(i+istart); coors[cnt++] = ymin + hy*(j+jstart); } } ierr = VecRestoreArray(xcoor,&coors);CHKERRQ(ierr); } else if (dim == 3) { if (bx == DM_BOUNDARY_PERIODIC) hx = (xmax-xmin)/(M); else hx = (xmax-xmin)/(M-1); if (by == DM_BOUNDARY_PERIODIC) hy = (ymax-ymin)/(N); else hy = (ymax-ymin)/(N-1); if (bz == DM_BOUNDARY_PERIODIC) hz_ = (zmax-zmin)/(P); else hz_ = (zmax-zmin)/(P-1); ierr = VecGetArray(xcoor,&coors);CHKERRQ(ierr); cnt = 0; for (k=0; k<ksize; k++) { for (j=0; j<jsize; j++) { for (i=0; i<isize; i++) { coors[cnt++] = xmin + hx*(i+istart); coors[cnt++] = ymin + hy*(j+jstart); coors[cnt++] = zmin + hz_*(k+kstart); } } } ierr = VecRestoreArray(xcoor,&coors);CHKERRQ(ierr); } else SETERRQ1(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Cannot create uniform coordinates for this dimension %D\n",dim); ierr = DMSetCoordinates(da,xcoor);CHKERRQ(ierr); ierr = PetscLogObjectParent((PetscObject)da,(PetscObject)xcoor);CHKERRQ(ierr); ierr = VecDestroy(&xcoor);CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc,char **argv) { TS ts; /* nonlinear solver */ Vec x,r; /* solution, residual vectors */ Mat J; /* Jacobian matrix */ PetscInt steps,Mx,maxsteps = 10000000; PetscErrorCode ierr; DM da; MatFDColoring matfdcoloring; ISColoring iscoloring; PetscReal dt; PetscReal vbounds[] = {-100000,100000,-1.1,1.1}; PetscBool wait; Vec ul,uh; SNES snes; UserCtx ctx; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Initialize program - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; ctx.kappa = 1.0; ierr = PetscOptionsGetReal(NULL,"-kappa",&ctx.kappa,NULL);CHKERRQ(ierr); ctx.cahnhillard = PETSC_FALSE; ierr = PetscOptionsGetBool(NULL,NULL,"-cahn-hillard",&ctx.cahnhillard,NULL);CHKERRQ(ierr); ierr = PetscViewerDrawSetBounds(PETSC_VIEWER_DRAW_(PETSC_COMM_WORLD),2,vbounds);CHKERRQ(ierr); ierr = PetscViewerDrawResize(PETSC_VIEWER_DRAW_(PETSC_COMM_WORLD),600,600);CHKERRQ(ierr); ctx.energy = 1; /* ierr = PetscOptionsGetInt(NULL,NULL,"-energy",&ctx.energy,NULL);CHKERRQ(ierr); */ ierr = PetscOptionsGetInt(NULL,NULL,"-energy",&ctx.energy,NULL);CHKERRQ(ierr); ctx.tol = 1.0e-8; ierr = PetscOptionsGetReal(NULL,"-tol",&ctx.tol,NULL);CHKERRQ(ierr); ctx.theta = .001; ctx.theta_c = 1.0; ierr = PetscOptionsGetReal(NULL,"-theta",&ctx.theta,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,"-theta_c",&ctx.theta_c,NULL);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create distributed array (DMDA) to manage parallel grid and vectors - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMDACreate1d(PETSC_COMM_WORLD, DM_BOUNDARY_PERIODIC, -10,2,2,NULL,&da);CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMSetUp(da);CHKERRQ(ierr); ierr = DMDASetFieldName(da,0,"Biharmonic heat equation: w = -kappa*u_xx");CHKERRQ(ierr); ierr = DMDASetFieldName(da,1,"Biharmonic heat equation: u");CHKERRQ(ierr); ierr = DMDAGetInfo(da,0,&Mx,0,0,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr); dt = 1.0/(10.*ctx.kappa*Mx*Mx*Mx*Mx); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Extract global vectors from DMDA; then duplicate for remaining vectors that are the same types - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMCreateGlobalVector(da,&x);CHKERRQ(ierr); ierr = VecDuplicate(x,&r);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create timestepping solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetDM(ts,da);CHKERRQ(ierr); ierr = TSSetProblemType(ts,TS_NONLINEAR);CHKERRQ(ierr); ierr = TSSetIFunction(ts,NULL,FormFunction,&ctx);CHKERRQ(ierr); ierr = TSSetDuration(ts,maxsteps,.02);CHKERRQ(ierr); ierr = TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create matrix data structure; set Jacobian evaluation routine < Set Jacobian matrix data structure and default Jacobian evaluation routine. User can override with: -snes_mf : matrix-free Newton-Krylov method with no preconditioning (unless user explicitly sets preconditioner) -snes_mf_operator : form preconditioning matrix as set by the user, but use matrix-free approx for Jacobian-vector products within Newton-Krylov method - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); ierr = DMCreateColoring(da,IS_COLORING_GLOBAL,&iscoloring);CHKERRQ(ierr); ierr = DMSetMatType(da,MATAIJ);CHKERRQ(ierr); ierr = DMCreateMatrix(da,&J);CHKERRQ(ierr); ierr = MatFDColoringCreate(J,iscoloring,&matfdcoloring);CHKERRQ(ierr); ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode (*)(void))SNESTSFormFunction,ts);CHKERRQ(ierr); ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); ierr = MatFDColoringSetUp(J,iscoloring,matfdcoloring);CHKERRQ(ierr); ierr = SNESSetJacobian(snes,J,J,SNESComputeJacobianDefaultColor,matfdcoloring);CHKERRQ(ierr); { ierr = VecDuplicate(x,&ul);CHKERRQ(ierr); ierr = VecDuplicate(x,&uh);CHKERRQ(ierr); ierr = VecStrideSet(ul,0,PETSC_NINFINITY);CHKERRQ(ierr); ierr = VecStrideSet(ul,1,-1.0);CHKERRQ(ierr); ierr = VecStrideSet(uh,0,PETSC_INFINITY);CHKERRQ(ierr); ierr = VecStrideSet(uh,1,1.0);CHKERRQ(ierr); ierr = TSVISetVariableBounds(ts,ul,uh);CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Customize nonlinear solver - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetType(ts,TSBEULER);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set initial conditions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = FormInitialSolution(da,x,ctx.kappa);CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts,0.0,dt);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); wait = PETSC_FALSE; ierr = PetscOptionsGetBool(NULL,NULL,"-wait",&wait,NULL);CHKERRQ(ierr); if (wait) { ierr = PetscSleep(-1);CHKERRQ(ierr); } ierr = TSGetTimeStepNumber(ts,&steps);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. All PETSc objects should be destroyed when they are no longer needed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ { ierr = VecDestroy(&ul);CHKERRQ(ierr); ierr = VecDestroy(&uh);CHKERRQ(ierr); } ierr = MatDestroy(&J);CHKERRQ(ierr); ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&r);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize(); PetscFunctionReturn(0); }
PetscErrorCode efs_setup(efs *slv, int offset[], int stride[]) { PetscErrorCode ierr; PetscInt xs, ys, zs, xm, ym, zm; PCType pc_type; if (efs_log(slv, EFS_LOG_STATUS)) { ierr = ef_io_print(slv->comm, "Setting up electric field solver");CHKERRQ(ierr); } slv->ts = 0; if (efs_log(slv, EFS_LOG_RESIDUAL)) { ierr = PetscOptionsSetValue("-ksp_monitor_short", NULL);CHKERRQ(ierr); } ierr = DMDASetFieldName(slv->dm, 0,"potential");CHKERRQ(ierr); if (slv->grid.nd == 2) { ierr = DMDAGetCorners(slv->dm, &xs, &ys, 0, &xm, &ym, 0);CHKERRQ(ierr); slv->dmap = ef_dmap_create_2d(xs - offset[0], ys - offset[1], xm, ym, stride); } else if (slv->grid.nd == 3) { ierr = DMDAGetCorners(slv->dm, &xs, &ys, &zs, &xm, &ym, &zm);CHKERRQ(ierr); slv->dmap = ef_dmap_create_3d(xs - offset[0], ys - offset[1], zs - offset[2], xm, ym, zm, stride); } else { SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_SUP, "Unsupported dimmension: %d", slv->grid.nd); } ierr = ef_callback_create(&slv->callback);CHKERRQ(ierr); ierr = KSPCreate(slv->comm, &slv->ksp);CHKERRQ(ierr); if (efs_log(slv, EFS_LOG_EIGS)) { ierr = KSPSetComputeEigenvalues(slv->ksp, PETSC_TRUE);CHKERRQ(ierr); } ierr = KSPSetDM(slv->ksp, slv->dm);CHKERRQ(ierr); ierr = KSPGetPC(slv->ksp, &slv->pc);CHKERRQ(ierr); ierr = PCSetType(slv->pc, PCMG);CHKERRQ(ierr); if (slv->options.galerkin) { ierr = PCMGSetGalerkin(slv->pc, PETSC_TRUE);CHKERRQ(ierr); } else { ierr = PCMGSetGalerkin(slv->pc, PETSC_FALSE);CHKERRQ(ierr); } ierr = KSPSetComputeOperators(slv->ksp, slv->callback->matrix, slv);CHKERRQ(ierr); ierr = KSPSetComputeRHS(slv->ksp, slv->callback->rhs, slv);CHKERRQ(ierr); ierr = KSPSetComputeInitialGuess(slv->ksp, slv->callback->guess, slv);CHKERRQ(ierr); ierr = KSPSetFromOptions(slv->ksp);CHKERRQ(ierr); ierr = PCGetType(slv->pc, &pc_type);CHKERRQ(ierr); ierr = PCMGGetLevels(slv->pc, &slv->options.levels);CHKERRQ(ierr); if (slv->options.levels < 1) slv->options.levels++; ierr = PCMGGetGalerkin(slv->pc, &slv->options.galerkin);CHKERRQ(ierr); if (strcmp(pc_type, PCGAMG) == 0 || strcmp(pc_type, PCHYPRE) == 0) slv->options.galerkin = 1; if (!slv->options.galerkin) { slv->levels = (ef_level*) malloc(slv->options.levels*sizeof(ef_level)); // setup callback for transforming rhs on coarse levels } else { slv->levels = (ef_level*) malloc(sizeof(ef_level)); } ierr = ef_fd_create(&slv->fd, EF_FD_STANDARD_O2);CHKERRQ(ierr); ierr = ef_operator_create(&slv->op, slv->levels, slv->fd, slv->grid.nd);CHKERRQ(ierr); ierr = ef_boundary_create(&slv->boundary, slv->levels, slv->options.levels, slv->dmap, &slv->state, slv->fd);CHKERRQ(ierr); slv->op->axisymmetric = slv->options.axisymmetric; slv->boundary->axisymmetric = slv->options.axisymmetric; ierr = DMSetMatType(slv->dm, MATAIJ);CHKERRQ(ierr); ierr = DMCreateGlobalVector(slv->dm, &slv->levels[0].eps);CHKERRQ(ierr); ierr = DMCreateGlobalVector(slv->dm, &slv->levels[0].g);CHKERRQ(ierr); ierr = DMCreateGlobalVector(slv->dm, &slv->levels[0].ag);CHKERRQ(ierr); ierr = DMCreateGlobalVector(slv->dm, &slv->levels[0].gcomp);CHKERRQ(ierr); ierr = DMCreateGlobalVector(slv->dm, &slv->levels[0].scale);CHKERRQ(ierr); ierr = DMCreateGlobalVector(slv->dm, &slv->levels[0].nscale);CHKERRQ(ierr); ierr = VecSet(slv->levels[0].g, 0);CHKERRQ(ierr); ierr = VecSet(slv->levels[0].gcomp, 1);CHKERRQ(ierr); ierr = VecSet(slv->levels[0].scale, 1);CHKERRQ(ierr); ierr = VecSet(slv->levels[0].nscale, 1);CHKERRQ(ierr); ierr = DMCoarsenHookAdd(slv->dm, slv->callback->coarsen, slv->callback->restrct, slv);CHKERRQ(ierr); return 0; }
int main(int argc,char **argv) { TS ts; /* time integrator */ Vec x,r; /* solution, residual vectors */ PetscInt steps,Mx; PetscErrorCode ierr; DM da; PetscReal dt; UserCtx ctx; PetscBool mymonitor; PetscViewer viewer; PetscBool flg; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Initialize program - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; ctx.kappa = 1.0; ierr = PetscOptionsGetReal(NULL,NULL,"-kappa",&ctx.kappa,NULL);CHKERRQ(ierr); ctx.allencahn = PETSC_FALSE; ierr = PetscOptionsHasName(NULL,NULL,"-allen-cahn",&ctx.allencahn);CHKERRQ(ierr); ierr = PetscOptionsHasName(NULL,NULL,"-mymonitor",&mymonitor);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create distributed array (DMDA) to manage parallel grid and vectors - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMDACreate1d(PETSC_COMM_WORLD, DM_BOUNDARY_PERIODIC, 10,1,2,NULL,&da);CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMSetUp(da);CHKERRQ(ierr); ierr = DMDASetFieldName(da,0,"Heat equation: u");CHKERRQ(ierr); ierr = DMDAGetInfo(da,0,&Mx,0,0,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr); dt = 1.0/(ctx.kappa*Mx*Mx); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Extract global vectors from DMDA; then duplicate for remaining vectors that are the same types - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMCreateGlobalVector(da,&x);CHKERRQ(ierr); ierr = VecDuplicate(x,&r);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create timestepping solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetDM(ts,da);CHKERRQ(ierr); ierr = TSSetProblemType(ts,TS_NONLINEAR);CHKERRQ(ierr); ierr = TSSetRHSFunction(ts,NULL,FormFunction,&ctx);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Customize nonlinear solver - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetType(ts,TSCN);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set initial conditions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = FormInitialSolution(da,x);CHKERRQ(ierr); ierr = TSSetTimeStep(ts,dt);CHKERRQ(ierr); ierr = TSSetMaxTime(ts,.02);CHKERRQ(ierr); ierr = TSSetExactFinalTime(ts,TS_EXACTFINALTIME_INTERPOLATE);CHKERRQ(ierr); ierr = TSSetSolution(ts,x);CHKERRQ(ierr); if (mymonitor) { ctx.ports = NULL; ierr = TSMonitorSet(ts,MyMonitor,&ctx,MyDestroy);CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetFromOptions(ts);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSolve(ts,x);CHKERRQ(ierr); ierr = TSGetStepNumber(ts,&steps);CHKERRQ(ierr); ierr = PetscOptionsHasName(NULL,NULL,"-square_initial",&flg);CHKERRQ(ierr); if (flg) { ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,"InitialSolution.heat",FILE_MODE_WRITE,&viewer);CHKERRQ(ierr); ierr = VecView(x,viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. All PETSc objects should be destroyed when they are no longer needed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&r);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }