int main(int argc,char **argv) { PetscErrorCode ierr; SNES snes; Vec u; DMDALocalInfo info; Ctx user; PetscInitialize(&argc,&argv,(char*)0,help); ierr = configureCtx(&user); CHKERRQ(ierr); ierr = DMDACreate2d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DMDA_STENCIL_STAR, -3,-3, PETSC_DECIDE,PETSC_DECIDE, 1,1, NULL,NULL, &user.da); CHKERRQ(ierr); ierr = DMDASetUniformCoordinates(user.da,-1.0,1.0,-1.0,1.0,0.0,1.0); CHKERRQ(ierr); ierr = DMSetApplicationContext(user.da,&user); CHKERRQ(ierr); ierr = DMDAGetLocalInfo(user.da,&info); CHKERRQ(ierr); if ((info.mx < 2) || (info.my < 2)) { SETERRQ(PETSC_COMM_WORLD,1,"grid too coarse ... require (mx,my) > (2,2)"); } ierr = DMCreateGlobalVector(user.da,&u); CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)u,"u_vec");CHKERRQ(ierr); ierr = formInitial(&info,&user,u); CHKERRQ(ierr); ierr = SNESCreate(PETSC_COMM_WORLD,&snes);CHKERRQ(ierr); ierr = SNESSetDM(snes,user.da);CHKERRQ(ierr); ierr = DMDASNESSetFunctionLocal(user.da,INSERT_VALUES, (DMDASNESFunction)FormFunctionLocal,&user);CHKERRQ(ierr); ierr = DMDASNESSetJacobianLocal(user.da, (DMDASNESJacobian)FormJacobianLocal,&user);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); ierr = SNESSolve(snes,NULL,u); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "done on %d x %d x %d grid with eps=%g ...\n", info.mx,info.my,info.mz,user.eps); CHKERRQ(ierr); VecDestroy(&u); SNESDestroy(&snes); DMDestroy(&user.da); ierr = PetscFinalize(); CHKERRQ(ierr); return 0; }
int main(int argc,char **argv) { PetscErrorCode ierr; SNES snes; Vec u, uexact; double err, uexnorm; DMDALocalInfo info; Ctx user; PetscInitialize(&argc,&argv,(char*)0,help); ierr = configureCtx(&user); CHKERRQ(ierr); //STARTDMDA ierr = DMDACreate3d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DM_BOUNDARY_PERIODIC, DMDA_STENCIL_STAR, 3,3,3, PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE, 1, 1, NULL,NULL,NULL, &user.da); CHKERRQ(ierr); //ENDDMDA ierr = DMSetFromOptions(user.da); CHKERRQ(ierr); ierr = DMSetUp(user.da); CHKERRQ(ierr); ierr = DMDASetUniformCoordinates(user.da,-1.0,1.0,-1.0,1.0,-1.0,1.0); CHKERRQ(ierr); ierr = DMSetApplicationContext(user.da,&user); CHKERRQ(ierr); ierr = DMDAGetLocalInfo(user.da,&info); CHKERRQ(ierr); if ((info.mx < 2) || (info.my < 2) || (info.mz < 3)) { SETERRQ(PETSC_COMM_WORLD,1,"grid too coarse: require (mx,my,mz) > (2,2,3)"); } ierr = DMCreateGlobalVector(user.da,&uexact); CHKERRQ(ierr); ierr = VecDuplicate(uexact,&user.f); CHKERRQ(ierr); ierr = VecDuplicate(uexact,&user.g); CHKERRQ(ierr); ierr = formUexFG(&info,&user,uexact); CHKERRQ(ierr); ierr = SNESCreate(PETSC_COMM_WORLD,&snes); CHKERRQ(ierr); ierr = SNESSetDM(snes,user.da); CHKERRQ(ierr); ierr = DMDASNESSetFunctionLocal(user.da,INSERT_VALUES, (DMDASNESFunction)FormFunctionLocal,&user); CHKERRQ(ierr); ierr = DMDASNESSetJacobianLocal(user.da, (DMDASNESJacobian)FormJacobianLocal,&user); CHKERRQ(ierr); ierr = SNESSetFromOptions(snes); CHKERRQ(ierr); ierr = VecDuplicate(uexact,&u); CHKERRQ(ierr); ierr = VecCopy(user.g,u); CHKERRQ(ierr); // g has zeros except at bdry ierr = SNESSolve(snes,NULL,u); CHKERRQ(ierr); ierr = VecAXPY(u,-1.0,uexact); CHKERRQ(ierr); // u <- u + (-1.0) uxact ierr = VecNorm(u,NORM_2,&err); CHKERRQ(ierr); ierr = VecNorm(uexact,NORM_2,&uexnorm); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "done on %d x %d x %d grid with eps=%g: error |u-uexact|_2/|uexact|_2 = %g\n", info.mx,info.my,info.mz,user.eps,err/uexnorm); CHKERRQ(ierr); VecDestroy(&u); VecDestroy(&uexact); VecDestroy(&user.f); VecDestroy(&user.g); SNESDestroy(&snes); DMDestroy(&user.da); ierr = PetscFinalize(); CHKERRQ(ierr); return 0; }