int DoOutput(DMMG *dmmg, int n_plot) /*---------------------------------------------------------------------*/ { AppCtx *user = (AppCtx*)dmmg[0]->user; Parameter *param; int ierr; char filename[FNAME_LENGTH]; PetscViewer viewer; DA da; ierr = PetscBagGetData(user->bag,(void**)¶m); CHKERRQ(ierr); da = DMMGGetDA(dmmg); if (param->output_to_file) { /* send output to binary file */ /* generate filename for time t */ sprintf(filename,"%s_%3.3d",param->output_filename,n_plot); ierr = PetscPrintf(PETSC_COMM_WORLD,"Generating output: time t = %g, ",param->t); ierr = PetscPrintf(PETSC_COMM_WORLD,"file = \"%s\"\n",filename); /* make output files */ ierr = PetscViewerBinaryMatlabOpen(PETSC_COMM_WORLD,filename,&viewer); CHKERRQ(ierr); ierr = PetscViewerBinaryMatlabOutputBag(viewer,"par",user->bag); CHKERRQ(ierr); ierr = DASetFieldNames("u","v","phi",da); CHKERRQ(ierr); ierr = PetscViewerBinaryMatlabOutputVecDA(viewer,"field",DMMGGetx(dmmg),da); CHKERRQ(ierr); ierr = PetscViewerBinaryMatlabDestroy(viewer); CHKERRQ(ierr); } return 0; }
/* Setup for the custom preconditioner */ PetscErrorCode MyPCSetUp(PC pc) { AppCtx *app; PetscErrorCode ierr; DA da; PetscFunctionBegin; ierr = PCShellGetContext(pc,(void**)&app); CHKERRQ(ierr); /* create the linear solver for the Neutron diffusion */ ierr = DMMGCreate(app->comm,1,0,&app->fdmmg); CHKERRQ(ierr); ierr = DMMGSetOptionsPrefix(app->fdmmg,"phi_"); CHKERRQ(ierr); ierr = DMMGSetUser(app->fdmmg,0,app); CHKERRQ(ierr); ierr = DACreate2d(app->comm,DA_NONPERIODIC,DA_STENCIL_STAR,app->nxv,app->nyvf,PETSC_DETERMINE,1,1,1,0,0,&da); CHKERRQ(ierr); ierr = DMMGSetDM(app->fdmmg,(DM)da); CHKERRQ(ierr); ierr = DMMGSetKSP(app->fdmmg,PETSC_NULL,MyFormMatrix); CHKERRQ(ierr); app->dx = DMMGGetRHS(app->fdmmg); app->dy = DMMGGetx(app->fdmmg); ierr = VecDuplicate(app->dy,&app->c); CHKERRQ(ierr); ierr = DADestroy(da); CHKERRQ(ierr); PetscFunctionReturn(0); }
EXTERN_C_BEGIN void PETSC_STDCALL dmmggetx_(DMMG **dmmg,Vec *x,PetscErrorCode *ierr) { *ierr = 0; *x = DMMGGetx(*dmmg); }
real ImposeLaplaceBoundary(State *BHD, Vec g, Vec b, Vec x, real zpad, int *iter) { real mpi_start, mpi_stop; Vec sol; /* computation time measurement start point */ MPI_Barrier( PETSC_COMM_WORLD); mpi_start = MPI_Wtime(); /* Get boundary of g */ CopyBoundary(BHD, g, BHD->pre, zpad); VecSet(x, 0.0); /* Solve Laplace */ DMMGSolve(BHD->dmmg); sol = DMMGGetx(BHD->dmmg); VecCopy(sol, x); /* subtract solution from g */ VecAXPY(g, -1.0, x); /* computation time measurement stop point */ MPI_Barrier( PETSC_COMM_WORLD); mpi_stop = MPI_Wtime(); return mpi_stop-mpi_start; /* VecView(b,PETSC_VIEWER_STDERR_WORLD); */ /* exit(1); */ }
int CalcSolnNorms(DMMG *dmmg, PetscReal norms[]) /*---------------------------------------------------------------------*/ { Vec x; int ierr; x = DMMGGetx(dmmg); ierr = VecNorm(x, NORM_1, &(norms[0])); ierr = VecNorm(x, NORM_2, &(norms[1])); ierr = VecNorm(x, NORM_INFINITY, &(norms[2])); return 0; }
int Initialize(DMMG *dmmg) /* ------------------------------------------------------------------- */ { AppCtx *user = (AppCtx*)dmmg[0]->user; Parameter *param; DA da; PetscReal PI = 3.14159265358979323846; PetscReal sigma,xc,zc; PetscReal dx=user->grid->dx,dz=user->grid->dz; int i,j,ierr,is,js,im,jm; Field **x; ierr = PetscBagGetData(user->bag,(void**)¶m); CHKERRQ(ierr); sigma=param->sigma; xc=param->xctr; zc=param->zctr; /* Get the DA and grid */ da = (DA)(dmmg[0]->dm); ierr = DAGetCorners(da,&is,&js,PETSC_NULL,&im,&jm,PETSC_NULL); CHKERRQ(ierr); ierr = DAVecGetArray(da,user->Xold,(void**)&x); CHKERRQ(ierr); for (j=js; j<js+jm; j++) { for (i=is; i<is+im; i++) { if (param->flow_type == SHEAR_CELL) { x[j][i].u = -sin(PI*i*dx)*cos(PI*j*dz)/dx; x[j][i].w = sin(PI*j*dz)*cos(PI*i*dx)/dz; } else { x[j][i].u = 0.0; x[j][i].w = -1.0/dz; } x[j][i].phi = 100*exp(-0.5*((i*dx-xc)*(i*dx-xc)+(j*dz-zc)*(j*dz-zc))/sigma/sigma); } } /* restore the grid to it's vector */ ierr = DAVecRestoreArray(da,user->Xold,(void**)&x); CHKERRQ(ierr); ierr = VecCopy(user->Xold, DMMGGetx(dmmg)); CHKERRQ(ierr); return 0; }
int main(int argc,char **argv) { DMMG *dmmg; /* multilevel grid structure */ PetscErrorCode ierr; DA da; AppCtx app; PC pc; KSP ksp; PetscTruth isshell; PetscViewer v1; PetscInitialize(&argc,&argv,(char *)0,help); PreLoadBegin(PETSC_TRUE,"SetUp"); app.comm = PETSC_COMM_WORLD; app.nxv = 6; app.nyvf = 3; app.nyv = app.nyvf + 2; ierr = PetscOptionsBegin(app.comm,PETSC_NULL,"Options for Grid Sizes",PETSC_NULL); ierr = PetscOptionsInt("-nxv","Grid spacing in X direction",PETSC_NULL,app.nxv,&app.nxv,PETSC_NULL); CHKERRQ(ierr); ierr = PetscOptionsInt("-nyvf","Grid spacing in Y direction of Fuel",PETSC_NULL,app.nyvf,&app.nyvf,PETSC_NULL); CHKERRQ(ierr); ierr = PetscOptionsInt("-nyv","Total Grid spacing in Y direction of",PETSC_NULL,app.nyv,&app.nyv,PETSC_NULL); CHKERRQ(ierr); ierr = PetscOptionsEnd(); ierr = PetscViewerDrawOpen(app.comm,PETSC_NULL,"",-1,-1,-1,-1,&v1); CHKERRQ(ierr); /* Create the DMComposite object to manage the three grids/physics. We use a 1d decomposition along the y direction (since one of the grids is 1d). */ ierr = DMCompositeCreate(app.comm,&app.pack); CHKERRQ(ierr); /* 6 fluid unknowns, 3 ghost points on each end for either periodicity or simply boundary conditions */ ierr = DACreate1d(app.comm,DA_XPERIODIC,app.nxv,6,3,0,&da); CHKERRQ(ierr); ierr = DASetFieldName(da,0,"prss"); CHKERRQ(ierr); ierr = DASetFieldName(da,1,"ergg"); CHKERRQ(ierr); ierr = DASetFieldName(da,2,"ergf"); CHKERRQ(ierr); ierr = DASetFieldName(da,3,"alfg"); CHKERRQ(ierr); ierr = DASetFieldName(da,4,"velg"); CHKERRQ(ierr); ierr = DASetFieldName(da,5,"velf"); CHKERRQ(ierr); ierr = DMCompositeAddDM(app.pack,(DM)da); CHKERRQ(ierr); ierr = DADestroy(da); CHKERRQ(ierr); ierr = DACreate2d(app.comm,DA_YPERIODIC,DA_STENCIL_STAR,app.nxv,app.nyv,PETSC_DETERMINE,1,1,1,0,0,&da); CHKERRQ(ierr); ierr = DASetFieldName(da,0,"Tempature"); CHKERRQ(ierr); ierr = DMCompositeAddDM(app.pack,(DM)da); CHKERRQ(ierr); ierr = DADestroy(da); CHKERRQ(ierr); ierr = DACreate2d(app.comm,DA_XYPERIODIC,DA_STENCIL_STAR,app.nxv,app.nyvf,PETSC_DETERMINE,1,2,1,0,0,&da); CHKERRQ(ierr); ierr = DASetFieldName(da,0,"Phi"); CHKERRQ(ierr); ierr = DASetFieldName(da,1,"Pre"); CHKERRQ(ierr); ierr = DMCompositeAddDM(app.pack,(DM)da); CHKERRQ(ierr); ierr = DADestroy(da); CHKERRQ(ierr); app.pri = 1.0135e+5; app.ugi = 2.5065e+6; app.ufi = 4.1894e+5; app.agi = 1.00e-1; app.vgi = 1.0e-1 ; app.vfi = 1.0e-1; app.prin = 1.0135e+5; app.ugin = 2.5065e+6; app.ufin = 4.1894e+5; app.agin = 1.00e-1; app.vgin = 1.0e-1 ; app.vfin = 1.0e-1; app.prout = 1.0135e+5; app.ugout = 2.5065e+6; app.ufout = 4.1894e+5; app.agout = 3.0e-1; app.twi = 373.15e+0; app.phii = 1.0e+0; app.prei = 1.0e-5; /* Create the solver object and attach the grid/physics info */ ierr = DMMGCreate(app.comm,1,0,&dmmg); CHKERRQ(ierr); ierr = DMMGSetDM(dmmg,(DM)app.pack); CHKERRQ(ierr); ierr = DMMGSetUser(dmmg,0,&app); CHKERRQ(ierr); ierr = DMMGSetISColoringType(dmmg,IS_COLORING_GLOBAL); CHKERRQ(ierr); CHKMEMQ; ierr = DMMGSetInitialGuess(dmmg,FormInitialGuess); CHKERRQ(ierr); ierr = DMMGSetSNES(dmmg,FormFunction,0); CHKERRQ(ierr); ierr = DMMGSetFromOptions(dmmg); CHKERRQ(ierr); /* Supply custom shell preconditioner if requested */ ierr = SNESGetKSP(DMMGGetSNES(dmmg),&ksp); CHKERRQ(ierr); ierr = KSPGetPC(ksp,&pc); CHKERRQ(ierr); ierr = PetscTypeCompare((PetscObject)pc,PCSHELL,&isshell); CHKERRQ(ierr); if (isshell) { ierr = PCShellSetContext(pc,&app); CHKERRQ(ierr); ierr = PCShellSetSetUp(pc,MyPCSetUp); CHKERRQ(ierr); ierr = PCShellSetApply(pc,MyPCApply); CHKERRQ(ierr); ierr = PCShellSetDestroy(pc,MyPCDestroy); CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve the nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ PreLoadStage("Solve"); ierr = DMMGSolve(dmmg); CHKERRQ(ierr); ierr = VecView(DMMGGetx(dmmg),v1); CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. All PETSc objects should be destroyed when they are no longer needed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = PetscViewerDestroy(v1); CHKERRQ(ierr); ierr = DMCompositeDestroy(app.pack); CHKERRQ(ierr); ierr = DMMGDestroy(dmmg); CHKERRQ(ierr); PreLoadEnd(); ierr = PetscFinalize(); CHKERRQ(ierr); return 0; }
/* Visualize solutions */ PetscErrorCode MySolutionView(MPI_Comm comm,PetscInt phy_num,void *ctx) { PetscErrorCode ierr; AppCtx *user = (AppCtx*)ctx; DMMG *dmmg = user->dmmg; DA da=DMMGGetDA(dmmg); Field **x = user->x; Field1 **x1 = user->x1; PetscInt i,j,mx,xs,ys,xm,ym; PetscMPIInt size; PetscFunctionBegin; ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); ierr = DAGetCorners(da,&xs,&ys,PETSC_NULL,&xm,&ym,PETSC_NULL);CHKERRQ(ierr); switch (phy_num){ case 0: if (size == 1){ ierr = PetscPrintf(PETSC_COMM_SELF,"Original Physics %d U,V,Omega,Temp: \n",phy_num); ierr = PetscPrintf(PETSC_COMM_SELF,"-----------------------------------\n"); for (j=ys; j<ys+ym; j++) { for (i=xs; i<xs+xm; i++) { ierr = PetscPrintf(PETSC_COMM_SELF,"x[%d,%d] = %g, %g, %g, %g\n",j,i,x[j][i].u,x[j][i].v,x[j][i].omega,x[j][i].temp); } } } break; case 1: if (size == 1){ ierr = PetscPrintf(PETSC_COMM_SELF,"SubPhysics %d: U,V,Omega: \n",phy_num); ierr = PetscPrintf(PETSC_COMM_SELF,"------------------------\n"); DMMG *dmmg1=user->dmmg1; Vec solu_true = DMMGGetx(dmmg1); DA da=DMMGGetDA(dmmg1); Field1 **x1; ierr = DAVecGetArray(da,solu_true,&x1);CHKERRQ(ierr); for (j=ys; j<ys+ym; j++) { for (i=xs; i<xs+xm; i++) { ierr = PetscPrintf(PETSC_COMM_SELF,"x[%d,%d] = %g, %g, %g\n",j,i,x1[j][i].u,x1[j][i].v,x1[j][i].omega); } } ierr = DAVecRestoreArray(da,solu_true,&x1);CHKERRQ(ierr); } break; case 2: if (size == 1){ ierr = PetscPrintf(PETSC_COMM_SELF,"SubPhysics %d: Temperature: \n",phy_num); ierr = PetscPrintf(PETSC_COMM_SELF,"--------------------------\n"); DMMG *dmmg2=user->dmmg2; Vec solu_true = DMMGGetx(dmmg2); DA da=DMMGGetDA(dmmg2); Field2 **x2; ierr = DAVecGetArray(da,solu_true,&x2);CHKERRQ(ierr); for (j=ys; j<ys+ym; j++) { for (i=xs; i<xs+xm; i++) { ierr = PetscPrintf(PETSC_COMM_SELF,"x[%d,%d] = %g\n",j,i,x2[j][i].temp); } } ierr = DAVecRestoreArray(da,solu_true,&x2);CHKERRQ(ierr); } break; default: if (size == 1){ DMMG *dmmg_comp=user->dmmg_comp; DA da1,da2,da=DMMGGetDA(dmmg); Vec X1,X2,solu_true = DMMGGetx(dmmg); Field **x; Field1 **x1; Field2 **x2; DMComposite dm = (DMComposite)(*dmmg_comp)->dm; PetscReal err,err_tmp; if (phy_num == 3){ ierr = PetscPrintf(PETSC_COMM_SELF,"Composite physics %d, U,V,Omega,Temp: \n",phy_num); ierr = PetscPrintf(PETSC_COMM_SELF,"------------------------------------\n"); ierr = PetscPrintf(PETSC_COMM_SELF,"Composite physics, U,V,Omega,Temp: \n");CHKERRQ(ierr); } ierr = DAVecGetArray(da,solu_true,&x);CHKERRQ(ierr); ierr = DMCompositeGetEntries(dm,&da1,&da2);CHKERRQ(ierr); ierr = DMCompositeGetLocalVectors(dm,&X1,&X2);CHKERRQ(ierr); ierr = DAVecGetArray(da1,X1,(void**)&x1);CHKERRQ(ierr); ierr = DAVecGetArray(da2,X2,(void**)&x2);CHKERRQ(ierr); err = 0.0; for (j=ys; j<ys+ym; j++) { for (i=xs; i<xs+xm; i++) { err_tmp = PetscAbs(x[j][i].u-x1[j][i].u) + PetscAbs(x[j][i].v-x1[j][i].v) + PetscAbs(x[j][i].omega-x1[j][i].omega); err_tmp += PetscAbs(x[j][i].temp-x2[j][i].temp); if (err < err_tmp) err = err_tmp; if (phy_num == 3){ ierr = PetscPrintf(PETSC_COMM_SELF,"x[%d,%d] = %g, %g, %g, %g\n",j,i,x1[j][i].u,x1[j][i].v,x1[j][i].omega,x2[j][i].temp); } } } ierr = PetscPrintf(PETSC_COMM_SELF,"|solu - solu_comp| = %g\n",err);CHKERRQ(ierr); ierr = DAVecRestoreArray(da1,X1,(void**)&x1);CHKERRQ(ierr); ierr = DAVecRestoreArray(da2,X2,(void**)&x2);CHKERRQ(ierr); ierr = DMCompositeRestoreLocalVectors(dm,&X1,&X2);CHKERRQ(ierr); ierr = DAVecRestoreArray(da,solu_true,&x);CHKERRQ(ierr); } } PetscFunctionReturn(0); }
int main(int argc,char **argv) { DMMG *dmmg_comp; /* multilevel grid structure */ AppCtx user; /* user-defined work context */ PetscInt mx,my,its,max_its,i; PetscErrorCode ierr; MPI_Comm comm; SNES snes; DA da1,da2; DMComposite pack; DMMG *dmmg1,*dmmg2; PetscTruth SolveSubPhysics=PETSC_FALSE,GaussSeidel=PETSC_TRUE,Jacobi=PETSC_FALSE; Vec X1,X1_local,X2,X2_local; PetscViewer viewer; PetscInitialize(&argc,&argv,(char *)0,help); comm = PETSC_COMM_WORLD; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create user context, set problem data, create vector data structures. Also, compute the initial guess. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Setup Physics 1: - Lap(U) - Grad_y(Omega) = 0 - Lap(V) + Grad_x(Omega) = 0 - Lap(Omega) + Div([U*Omega,V*Omega]) - GR*Grad_x(T) = 0 where T is given by the given x.temp - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DACreate2d(comm,DA_NONPERIODIC,DA_STENCIL_STAR,-4,-4,PETSC_DECIDE,PETSC_DECIDE,3,1,0,0,&da1);CHKERRQ(ierr); ierr = DASetFieldName(da1,0,"x-velocity");CHKERRQ(ierr); ierr = DASetFieldName(da1,1,"y-velocity");CHKERRQ(ierr); ierr = DASetFieldName(da1,2,"Omega");CHKERRQ(ierr); /* Create the solver object and attach the grid/physics info */ ierr = DMMGCreate(comm,1,&user,&dmmg1);CHKERRQ(ierr); ierr = DMMGSetDM(dmmg1,(DM)da1);CHKERRQ(ierr); ierr = DMMGSetISColoringType(dmmg1,IS_COLORING_GLOBAL);CHKERRQ(ierr); ierr = DMMGSetInitialGuess(dmmg1,FormInitialGuess1);CHKERRQ(ierr); ierr = DMMGSetSNES(dmmg1,FormFunction1,0);CHKERRQ(ierr); ierr = DMMGSetFromOptions(dmmg1);CHKERRQ(ierr); /* Set problem parameters (velocity of lid, prandtl, and grashof numbers) */ ierr = DAGetInfo(da1,PETSC_NULL,&mx,&my,0,0,0,0,0,0,0,0);CHKERRQ(ierr); user.lidvelocity = 1.0/(mx*my); user.prandtl = 1.0; user.grashof = 1000.0; ierr = PetscOptionsGetReal(PETSC_NULL,"-lidvelocity",&user.lidvelocity,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetReal(PETSC_NULL,"-prandtl",&user.prandtl,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetReal(PETSC_NULL,"-grashof",&user.grashof,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsHasName(PETSC_NULL,"-solvesubphysics",&SolveSubPhysics);CHKERRQ(ierr); ierr = PetscOptionsHasName(PETSC_NULL,"-Jacobi",&Jacobi);CHKERRQ(ierr); if (Jacobi) GaussSeidel=PETSC_FALSE; ierr = PetscPrintf(comm,"grashof: %g, ",user.grashof);CHKERRQ(ierr); if (GaussSeidel){ ierr = PetscPrintf(comm,"use Block Gauss-Seidel\n");CHKERRQ(ierr); } else { ierr = PetscPrintf(comm,"use Block Jacobi\n");CHKERRQ(ierr); } ierr = PetscPrintf(comm,"===========================================\n");CHKERRQ(ierr); /* Solve the nonlinear system 1 */ if (SolveSubPhysics){ ierr = DMMGSolve(dmmg1);CHKERRQ(ierr); snes = DMMGGetSNES(dmmg1); ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr); ierr = PetscPrintf(comm,"Physics 1: Number of Newton iterations = %D\n\n", its);CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Setup Physics 2: - Lap(T) + PR*Div([U*T,V*T]) = 0 where U and V are given by the given x.u and x.v - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DACreate2d(comm,DA_NONPERIODIC,DA_STENCIL_STAR,-4,-4,PETSC_DECIDE,PETSC_DECIDE,1,1,0,0,&da2);CHKERRQ(ierr); ierr = DASetFieldName(da2,0,"temperature");CHKERRQ(ierr); /* Create the solver object and attach the grid/physics info */ ierr = DMMGCreate(comm,1,&user,&dmmg2);CHKERRQ(ierr); ierr = DMMGSetDM(dmmg2,(DM)da2);CHKERRQ(ierr); ierr = DMMGSetISColoringType(dmmg2,IS_COLORING_GLOBAL);CHKERRQ(ierr); ierr = DMMGSetInitialGuess(dmmg2,FormInitialGuess2);CHKERRQ(ierr); ierr = DMMGSetSNES(dmmg2,FormFunction2,0);CHKERRQ(ierr); ierr = DMMGSetFromOptions(dmmg2);CHKERRQ(ierr); /* Solve the nonlinear system 2 */ if (SolveSubPhysics){ ierr = DMMGSolve(dmmg2);CHKERRQ(ierr); snes = DMMGGetSNES(dmmg2); ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr); ierr = PetscPrintf(comm,"Physics 2: Number of Newton iterations = %D\n\n", its);CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve system 1 and 2 iteratively - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DACreateLocalVector(da1,&X1_local);CHKERRQ(ierr); ierr = DACreateLocalVector(da2,&X2_local);CHKERRQ(ierr); /* Only 1 snes iteration is allowed for each subphysics */ /* snes = DMMGGetSNES(dmmg1); ierr = SNESSetTolerances(snes,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1,PETSC_DEFAULT);CHKERRQ(ierr); snes = DMMGGetSNES(dmmg2); ierr = SNESSetTolerances(snes,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1,PETSC_DEFAULT);CHKERRQ(ierr); */ max_its = 5; ierr = PetscOptionsGetInt(PETSC_NULL,"-mp_max_it",&max_its,PETSC_NULL);CHKERRQ(ierr); user.nsolve = 0; for (i=0; i<max_its; i++){ ierr = PetscPrintf(comm,"\nIterative nsolve %D ...\n", user.nsolve);CHKERRQ(ierr); if (!GaussSeidel){ /* get the ghosted X1_local for Physics 2 */ X1 = DMMGGetx(dmmg1); //Jacobian if (i){ierr = DAVecRestoreArray(da1,X1_local,(Field1 **)&user.x1);CHKERRQ(ierr);} ierr = DAGlobalToLocalBegin(da1,X1,INSERT_VALUES,X1_local);CHKERRQ(ierr); ierr = DAGlobalToLocalEnd(da1,X1,INSERT_VALUES,X1_local);CHKERRQ(ierr); ierr = DAVecGetArray(da1,X1_local,(Field1 **)&user.x1);CHKERRQ(ierr); } ierr = DMMGSolve(dmmg1);CHKERRQ(ierr); snes = DMMGGetSNES(dmmg1); ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr); if (GaussSeidel){ /* get the ghosted X1_local for Physics 2 */ X1 = DMMGGetx(dmmg1); if (i){ierr = DAVecRestoreArray(da1,X1_local,(Field1 **)&user.x1);CHKERRQ(ierr);} ierr = DAGlobalToLocalBegin(da1,X1,INSERT_VALUES,X1_local);CHKERRQ(ierr); ierr = DAGlobalToLocalEnd(da1,X1,INSERT_VALUES,X1_local);CHKERRQ(ierr); ierr = DAVecGetArray(da1,X1_local,(Field1 **)&user.x1);CHKERRQ(ierr); } ierr = PetscPrintf(comm," Iterative physics 1: Number of Newton iterations = %D\n", its);CHKERRQ(ierr); user.nsolve++; ierr = DMMGSolve(dmmg2);CHKERRQ(ierr); snes = DMMGGetSNES(dmmg2); ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr); /* get the ghosted X2_local for Physics 1 */ X2 = DMMGGetx(dmmg2); if (i){ierr = DAVecRestoreArray(da2,X2_local,(Field2 **)&user.x2);CHKERRQ(ierr);} ierr = DAGlobalToLocalBegin(da2,X2,INSERT_VALUES,X2_local);CHKERRQ(ierr); ierr = DAGlobalToLocalEnd(da2,X2,INSERT_VALUES,X2_local);CHKERRQ(ierr); ierr = DAVecGetArray(da2,X2_local,(Field2 **)&user.x2);CHKERRQ(ierr); ierr = PetscPrintf(comm," Iterative physics 2: Number of Newton iterations = %D\n", its);CHKERRQ(ierr); //user.nsolve++; } ierr = DAVecRestoreArray(da1,X1_local,(Field1 **)&user.x1);CHKERRQ(ierr); ierr = DAVecRestoreArray(da2,X2_local,(Field2 **)&user.x2);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create the DMComposite object to manage the two grids/physics. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = PetscPrintf(comm," \n\n DMComposite iteration......\n");CHKERRQ(ierr); ierr = DMCompositeCreate(comm,&pack);CHKERRQ(ierr); ierr = DMCompositeAddDM(pack,(DM)da1);CHKERRQ(ierr); ierr = DMCompositeAddDM(pack,(DM)da2);CHKERRQ(ierr); /* Create the solver object and attach the grid/physics info */ ierr = DMMGCreate(comm,1,&user,&dmmg_comp);CHKERRQ(ierr); ierr = DMMGSetDM(dmmg_comp,(DM)pack);CHKERRQ(ierr); ierr = DMMGSetISColoringType(dmmg_comp,IS_COLORING_GLOBAL);CHKERRQ(ierr); ierr = DMMGSetInitialGuess(dmmg_comp,FormInitialGuessComp);CHKERRQ(ierr); ierr = DMMGSetSNES(dmmg_comp,FormFunctionComp,0);CHKERRQ(ierr); ierr = DMMGSetFromOptions(dmmg_comp);CHKERRQ(ierr); /* Solve the nonlinear system */ /* ierr = DMMGSolve(dmmg_comp);CHKERRQ(ierr); snes = DMMGGetSNES(dmmg_comp); ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr); ierr = PetscPrintf(comm,"Composite Physics: Number of Newton iterations = %D\n\n", its);CHKERRQ(ierr);*/ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free spaces - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMCompositeDestroy(pack);CHKERRQ(ierr); ierr = DADestroy(da1);CHKERRQ(ierr); ierr = DADestroy(da2);CHKERRQ(ierr); ierr = DMMGDestroy(dmmg_comp);CHKERRQ(ierr); ierr = PetscViewerASCIIOpen(comm,"log.py",&viewer);CHKERRQ(ierr); /* -log_summary */ ierr = PetscLogPrintSummaryToPy(comm,viewer);CHKERRQ(ierr); /* -snes_view */ //snes = DMMGGetSNES(dmmg1);CHKERRQ(ierr); ierr = PetscViewerDestroy(viewer);CHKERRQ(ierr); ierr = DMMGDestroy(dmmg1);CHKERRQ(ierr); ierr = DMMGDestroy(dmmg2);CHKERRQ(ierr); ierr = VecDestroy(X1_local);CHKERRQ(ierr); ierr = VecDestroy(X2_local);CHKERRQ(ierr); ierr = PetscFinalize();CHKERRQ(ierr); return 0; }
int DoSolve(DMMG *dmmg) /* ------------------------------------------------------------------- */ { AppCtx *user = (AppCtx*)dmmg[0]->user; Parameter *param; PetscReal t_output = 0.0; int ierr, n_plot = 0, Ncomponents, components[3]; DA da = DMMGGetDA(dmmg); Vec Xstar; Characteristic c; ierr = PetscBagGetData(user->bag,(void**)¶m); CHKERRQ(ierr); ierr = DAGetGlobalVector(da, &Xstar); CHKERRQ(ierr); /*------------ BEGIN CHARACTERISTIC SETUP ---------------*/ ierr = CharacteristicCreate(PETSC_COMM_WORLD, &c); CHKERRQ(ierr); /* set up the velocity interpolation system */ Ncomponents = 2; components[0] = 0; components[1] = 1; ierr = CharacteristicSetVelocityInterpolationLocal(c, da, DMMGGetx(dmmg), user->Xold, Ncomponents, components, InterpVelocity2D, user); CHKERRQ(ierr); /* set up the fields interpolation system */ Ncomponents = 1; components[0] = 2; ierr = CharacteristicSetFieldInterpolationLocal(c, da, user->Xold, Ncomponents, components, InterpFields2D, user); CHKERRQ(ierr); /*------------ END CHARACTERISTIC SETUP ----------------*/ /* output initial data */ PetscPrintf(PETSC_COMM_WORLD," Initialization, Time: %5.4g\n", param->t); if (param->verify) { ierr = DoVerification(dmmg,user); CHKERRQ(ierr); } ierr = DoOutput(dmmg,n_plot); CHKERRQ(ierr); t_output += param->t_output_interval; n_plot++; /* timestep loop */ for (param->t=param->dt; param->t<=param->t_max; param->t+=param->dt) { if (param->n > param->N_steps) { PetscPrintf(PETSC_COMM_WORLD,"EXCEEDED MAX NUMBER OF TIMESTEPS! EXITING SOLVE!\n"); return 0; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve at time t & copy solution into solution vector. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Copy in the velocities to Xstar */ ierr = VecCopy(DMMGGetx(dmmg), Xstar); CHKERRQ(ierr); /* Put \phi_* into Xstar */ ierr = CharacteristicSolve(c, param->dt, Xstar); CHKERRQ(ierr); /* Copy the advected field into the solution \phi_t = \phi_* */ ierr = VecCopy(Xstar, DMMGGetx(dmmg)); CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Copy new solution to old solution in prep for the next timestep. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = VecCopy(DMMGGetx(dmmg), user->Xold); CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Timestep complete, report and update counter. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ PetscPrintf(PETSC_COMM_WORLD," Step: %d, Time: %5.4g\n", param->n, param->t); param->n++; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Verify and make output. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ if (param->verify) { ierr = DoVerification(dmmg,user); CHKERRQ(ierr); } if (param->t >= t_output) { ierr = DoOutput(dmmg,n_plot); CHKERRQ(ierr); t_output += param->t_output_interval; n_plot++; } } ierr = DARestoreGlobalVector(da, &Xstar); CHKERRQ(ierr); ierr = CharacteristicDestroy(c); CHKERRQ(ierr); return 0; }