PetscErrorCode PCMGKCycle_Private(PC pc,PC_MG_Levels **mglevels) { PetscErrorCode ierr; PetscInt i,l = mglevels[0]->levels; PetscFunctionBegin; /* restrict the RHS through all levels to coarsest. */ for (i=l-1; i>0; i--){ if (mglevels[i]->eventinterprestrict) {ierr = PetscLogEventBegin(mglevels[i]->eventinterprestrict,0,0,0,0);CHKERRQ(ierr);} ierr = MatRestrict(mglevels[i]->restrct,mglevels[i]->b,mglevels[i-1]->b);CHKERRQ(ierr); if (mglevels[i]->eventinterprestrict) {ierr = PetscLogEventEnd(mglevels[i]->eventinterprestrict,0,0,0,0);CHKERRQ(ierr);} } /* work our way up through the levels */ ierr = VecSet(mglevels[0]->x,0.0);CHKERRQ(ierr); for (i=0; i<l-1; i++) { if (mglevels[i]->eventsmoothsolve) {ierr = PetscLogEventBegin(mglevels[i]->eventsmoothsolve,0,0,0,0);CHKERRQ(ierr);} ierr = KSPSolve(mglevels[i]->smoothd,mglevels[i]->b,mglevels[i]->x);CHKERRQ(ierr); if (mglevels[i]->eventsmoothsolve) {ierr = PetscLogEventEnd(mglevels[i]->eventsmoothsolve,0,0,0,0);CHKERRQ(ierr);} if (mglevels[i+1]->eventinterprestrict) {ierr = PetscLogEventBegin(mglevels[i+1]->eventinterprestrict,0,0,0,0);CHKERRQ(ierr);} ierr = MatInterpolate(mglevels[i+1]->interpolate,mglevels[i]->x,mglevels[i+1]->x);CHKERRQ(ierr); if (mglevels[i+1]->eventinterprestrict) {ierr = PetscLogEventEnd(mglevels[i+1]->eventinterprestrict,0,0,0,0);CHKERRQ(ierr);} } if (mglevels[l-1]->eventsmoothsolve) {ierr = PetscLogEventBegin(mglevels[l-1]->eventsmoothsolve,0,0,0,0);CHKERRQ(ierr);} ierr = KSPSolve(mglevels[l-1]->smoothd,mglevels[l-1]->b,mglevels[l-1]->x);CHKERRQ(ierr); if (mglevels[l-1]->eventsmoothsolve) {ierr = PetscLogEventEnd(mglevels[l-1]->eventsmoothsolve,0,0,0,0);CHKERRQ(ierr);} PetscFunctionReturn(0); }
/*@C DMMGSolve - Actually solves the (non)linear system defined with the DMMG Collective on DMMG Input Parameter: . dmmg - the context Level: advanced Options Database: + -dmmg_grid_sequence - use grid sequencing to get the initial solution for each level from the previous - -dmmg_monitor_solution - display the solution at each iteration Notes: For linear (KSP) problems may be called more than once, uses the same matrices but recomputes the right hand side for each new solve. Call DMMGSetKSP() to generate new matrices. .seealso DMMGCreate(), DMMGDestroy(), DMMG, DMMGSetSNES(), DMMGSetKSP(), DMMGSetUp(), DMMGSetMatType() @*/ PetscErrorCode PETSCSNES_DLLEXPORT DMMGSolve(DMMG *dmmg) { PetscErrorCode ierr; PetscInt i,nlevels = dmmg[0]->nlevels; PetscTruth gridseq = PETSC_FALSE,vecmonitor = PETSC_FALSE,flg; PetscFunctionBegin; ierr = PetscOptionsGetTruth(0,"-dmmg_grid_sequence",&gridseq,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetTruth(0,"-dmmg_monitor_solution",&vecmonitor,PETSC_NULL);CHKERRQ(ierr); if (gridseq) { if (dmmg[0]->initialguess) { ierr = (*dmmg[0]->initialguess)(dmmg[0],dmmg[0]->x);CHKERRQ(ierr); if (dmmg[0]->ksp && !dmmg[0]->snes) { ierr = KSPSetInitialGuessNonzero(dmmg[0]->ksp,PETSC_TRUE);CHKERRQ(ierr); } } for (i=0; i<nlevels-1; i++) { ierr = (*dmmg[i]->solve)(dmmg,i);CHKERRQ(ierr); if (vecmonitor) { ierr = VecView(dmmg[i]->x,PETSC_VIEWER_DRAW_(dmmg[i]->comm));CHKERRQ(ierr); } ierr = MatInterpolate(dmmg[i+1]->R,dmmg[i]->x,dmmg[i+1]->x);CHKERRQ(ierr); if (dmmg[i+1]->ksp && !dmmg[i+1]->snes) { ierr = KSPSetInitialGuessNonzero(dmmg[i+1]->ksp,PETSC_TRUE);CHKERRQ(ierr); } } } else { if (dmmg[nlevels-1]->initialguess) { ierr = (*dmmg[nlevels-1]->initialguess)(dmmg[nlevels-1],dmmg[nlevels-1]->x);CHKERRQ(ierr); } } /*ierr = VecView(dmmg[nlevels-1]->x,PETSC_VIEWER_DRAW_WORLD);CHKERRQ(ierr);*/ ierr = (*DMMGGetFine(dmmg)->solve)(dmmg,nlevels-1);CHKERRQ(ierr); if (vecmonitor) { ierr = VecView(dmmg[nlevels-1]->x,PETSC_VIEWER_DRAW_(dmmg[nlevels-1]->comm));CHKERRQ(ierr); } flg = PETSC_FALSE; ierr = PetscOptionsGetTruth(PETSC_NULL,"-dmmg_view",&flg,PETSC_NULL);CHKERRQ(ierr); if (flg && !PetscPreLoadingOn) { PetscViewer viewer; ierr = PetscViewerASCIIGetStdout(dmmg[0]->comm,&viewer);CHKERRQ(ierr); ierr = DMMGView(dmmg,viewer);CHKERRQ(ierr); } flg = PETSC_FALSE; ierr = PetscOptionsGetTruth(PETSC_NULL,"-dmmg_view_binary",&flg,PETSC_NULL);CHKERRQ(ierr); if (flg && !PetscPreLoadingOn) { ierr = DMMGView(dmmg,PETSC_VIEWER_BINARY_(dmmg[0]->comm));CHKERRQ(ierr); } PetscFunctionReturn(0); }
int main(int argc,char **argv) { PetscInt M = 14,dof = 1,s = 1,ratio = 2,dim = 2; PetscErrorCode ierr; DM da_c,da_f; Vec v_c,v_f; Mat I; PetscScalar one = 1.0; MPI_Comm comm_f, comm_c; ierr = PetscInitialize(&argc,&argv,(char*)0,help);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-dim",&dim,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-M",&M,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-sw",&s,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-ratio",&ratio,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-dof",&dof,PETSC_NULL);CHKERRQ(ierr); comm_f = PETSC_COMM_WORLD; ierr = DMDASplitComm2d(comm_f,M,M,s,&comm_c);CHKERRQ(ierr); /* Set up the array */ if (dim == 2) { ierr = DMDACreate2d(comm_c,DMDA_BOUNDARY_NONE,DMDA_BOUNDARY_NONE,DMDA_STENCIL_BOX,M,M,PETSC_DECIDE,PETSC_DECIDE,dof,s,PETSC_NULL,PETSC_NULL,&da_c);CHKERRQ(ierr); M = ratio*(M-1) + 1; ierr = DMDACreate2d(comm_f,DMDA_BOUNDARY_NONE,DMDA_BOUNDARY_NONE,DMDA_STENCIL_BOX,M,M,PETSC_DECIDE,PETSC_DECIDE,dof,s,PETSC_NULL,PETSC_NULL,&da_f);CHKERRQ(ierr); } else if (dim == 3) { ; } ierr = DMCreateGlobalVector(da_c,&v_c);CHKERRQ(ierr); ierr = DMCreateGlobalVector(da_f,&v_f);CHKERRQ(ierr); ierr = VecSet(v_c,one);CHKERRQ(ierr); ierr = DMCreateInterpolation(da_c,da_f,&I,PETSC_NULL);CHKERRQ(ierr); ierr = MatInterpolate(I,v_c,v_f);CHKERRQ(ierr); ierr = VecView(v_f,PETSC_VIEWER_STDOUT_(comm_f));CHKERRQ(ierr); ierr = MatRestrict(I,v_f,v_c);CHKERRQ(ierr); ierr = VecView(v_c,PETSC_VIEWER_STDOUT_(comm_c));CHKERRQ(ierr); ierr = MatDestroy(&I);CHKERRQ(ierr); ierr = VecDestroy(&v_c);CHKERRQ(ierr); ierr = DMDestroy(&da_c);CHKERRQ(ierr); ierr = VecDestroy(&v_f);CHKERRQ(ierr); ierr = DMDestroy(&da_f);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
/* The additive cycle looks like: xhat = x xhat = dS(x, b) x = coarsecorrection(xhat, b_d) x = x + nu*(xhat - x); (optional) x = uS(x, b) With the coarse RHS (defect correction) as below. */ PetscErrorCode SNESFASCycle_Additive(SNES snes, Vec X) { Vec F, B, Xhat; Vec X_c, Xo_c, F_c, B_c; PetscErrorCode ierr; SNESConvergedReason reason; PetscReal xnorm, fnorm, ynorm; PetscBool lssuccess; SNES next; Mat restrct, interpolate; SNES_FAS *fas = (SNES_FAS*)snes->data,*fasc; PetscFunctionBegin; ierr = SNESFASCycleGetCorrection(snes, &next);CHKERRQ(ierr); F = snes->vec_func; B = snes->vec_rhs; Xhat = snes->work[1]; ierr = VecCopy(X, Xhat);CHKERRQ(ierr); /* recurse first */ if (next) { fasc = (SNES_FAS*)next->data; ierr = SNESFASCycleGetRestriction(snes, &restrct);CHKERRQ(ierr); ierr = SNESFASCycleGetInterpolation(snes, &interpolate);CHKERRQ(ierr); if (fas->eventresidual) {ierr = PetscLogEventBegin(fas->eventresidual,0,0,0,0);CHKERRQ(ierr);} ierr = SNESComputeFunction(snes, Xhat, F);CHKERRQ(ierr); if (fas->eventresidual) {ierr = PetscLogEventEnd(fas->eventresidual,0,0,0,0);CHKERRQ(ierr);} ierr = VecNorm(F, NORM_2, &fnorm);CHKERRQ(ierr); X_c = next->vec_sol; Xo_c = next->work[0]; F_c = next->vec_func; B_c = next->vec_rhs; ierr = SNESFASRestrict(snes,Xhat,Xo_c);CHKERRQ(ierr); /* restrict the defect */ ierr = MatRestrict(restrct, F, B_c);CHKERRQ(ierr); /* solve the coarse problem corresponding to F^c(x^c) = b^c = Rb + F^c(Rx) - RF(x) */ if (fasc->eventresidual) {ierr = PetscLogEventBegin(fasc->eventresidual,0,0,0,0);CHKERRQ(ierr);} ierr = SNESComputeFunction(next, Xo_c, F_c);CHKERRQ(ierr); if (fasc->eventresidual) {ierr = PetscLogEventEnd(fasc->eventresidual,0,0,0,0);CHKERRQ(ierr);} ierr = VecCopy(B_c, X_c);CHKERRQ(ierr); ierr = VecCopy(F_c, B_c);CHKERRQ(ierr); ierr = VecCopy(X_c, F_c);CHKERRQ(ierr); /* set initial guess of the coarse problem to the projected fine solution */ ierr = VecCopy(Xo_c, X_c);CHKERRQ(ierr); /* recurse */ ierr = SNESSetInitialFunction(next, F_c);CHKERRQ(ierr); ierr = SNESSolve(next, B_c, X_c);CHKERRQ(ierr); /* smooth on this level */ ierr = SNESFASDownSmooth_Private(snes, B, X, F, &fnorm);CHKERRQ(ierr); ierr = SNESGetConvergedReason(next,&reason);CHKERRQ(ierr); if (reason < 0 && reason != SNES_DIVERGED_MAX_IT) { snes->reason = SNES_DIVERGED_INNER; PetscFunctionReturn(0); } /* correct as x <- x + I(x^c - Rx)*/ ierr = VecAYPX(X_c, -1.0, Xo_c);CHKERRQ(ierr); ierr = MatInterpolate(interpolate, X_c, Xhat);CHKERRQ(ierr); /* additive correction of the coarse direction*/ ierr = SNESLineSearchApply(snes->linesearch, X, F, &fnorm, Xhat);CHKERRQ(ierr); ierr = SNESLineSearchGetSuccess(snes->linesearch, &lssuccess);CHKERRQ(ierr); if (!lssuccess) { if (++snes->numFailures >= snes->maxFailures) { snes->reason = SNES_DIVERGED_LINE_SEARCH; PetscFunctionReturn(0); } } ierr = SNESLineSearchGetNorms(snes->linesearch, &xnorm, &snes->norm, &ynorm);CHKERRQ(ierr); } else { ierr = SNESFASDownSmooth_Private(snes, B, X, F, &snes->norm);CHKERRQ(ierr); } PetscFunctionReturn(0); }
PetscErrorCode test1_DAInjection3d(PetscInt mx, PetscInt my, PetscInt mz) { PetscErrorCode ierr; DM dac,daf; PetscViewer vv; Vec ac,af; PetscInt periodicity; DMBoundaryType bx,by,bz; PetscFunctionBeginUser; bx = DM_BOUNDARY_NONE; by = DM_BOUNDARY_NONE; bz = DM_BOUNDARY_NONE; periodicity = 0; ierr = PetscOptionsGetInt(NULL,NULL,"-periodic", &periodicity, NULL);CHKERRQ(ierr); if (periodicity==1) { bx = DM_BOUNDARY_PERIODIC; } else if (periodicity==2) { by = DM_BOUNDARY_PERIODIC; } else if (periodicity==3) { bz = DM_BOUNDARY_PERIODIC; } ierr = DMDACreate3d(PETSC_COMM_WORLD, bx,by,bz, DMDA_STENCIL_BOX,mx+1, my+1,mz+1,PETSC_DECIDE, PETSC_DECIDE,PETSC_DECIDE,1, /* 1 dof */ 1, /* stencil = 1 */NULL,NULL,NULL,&daf);CHKERRQ(ierr); ierr = DMSetFromOptions(daf);CHKERRQ(ierr); ierr = DMSetUp(daf);CHKERRQ(ierr); ierr = DMCoarsen(daf,MPI_COMM_NULL,&dac);CHKERRQ(ierr); ierr = DMDASetUniformCoordinates(dac, -1.0,1.0, -1.0,1.0, -1.0,1.0);CHKERRQ(ierr); ierr = DMDASetUniformCoordinates(daf, -1.0,1.0, -1.0,1.0, -1.0,1.0);CHKERRQ(ierr); { DM cdaf,cdac; Vec coordsc,coordsf,coordsf2; Mat inject; VecScatter vscat; Mat interp; PetscReal norm; ierr = DMGetCoordinateDM(dac,&cdac);CHKERRQ(ierr); ierr = DMGetCoordinateDM(daf,&cdaf);CHKERRQ(ierr); ierr = DMGetCoordinates(dac,&coordsc);CHKERRQ(ierr); ierr = DMGetCoordinates(daf,&coordsf);CHKERRQ(ierr); ierr = DMCreateInjection(cdac,cdaf,&inject);CHKERRQ(ierr); ierr = MatScatterGetVecScatter(inject,&vscat);CHKERRQ(ierr); ierr = VecScatterBegin(vscat,coordsf,coordsc,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(vscat ,coordsf,coordsc,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = MatDestroy(&inject);CHKERRQ(ierr); ierr = DMCreateInterpolation(cdac,cdaf,&interp,NULL);CHKERRQ(ierr); ierr = VecDuplicate(coordsf,&coordsf2);CHKERRQ(ierr); ierr = MatInterpolate(interp,coordsc,coordsf2);CHKERRQ(ierr); ierr = VecAXPY(coordsf2,-1.0,coordsf);CHKERRQ(ierr); ierr = VecNorm(coordsf2,NORM_MAX,&norm);CHKERRQ(ierr); /* The fine coordinates are only reproduced in certain cases */ if (!bx && !by && !bz && norm > PETSC_SQRT_MACHINE_EPSILON) {ierr = PetscPrintf(PETSC_COMM_WORLD,"Norm %g\n",(double)norm);CHKERRQ(ierr);} ierr = VecDestroy(&coordsf2);CHKERRQ(ierr); ierr = MatDestroy(&interp);CHKERRQ(ierr); } if (0) { ierr = DMCreateGlobalVector(dac,&ac);CHKERRQ(ierr); ierr = VecZeroEntries(ac);CHKERRQ(ierr); ierr = DMCreateGlobalVector(daf,&af);CHKERRQ(ierr); ierr = VecZeroEntries(af);CHKERRQ(ierr); ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD, "dac_7.vtk", &vv);CHKERRQ(ierr); ierr = PetscViewerPushFormat(vv, PETSC_VIEWER_ASCII_VTK);CHKERRQ(ierr); ierr = DMView(dac, vv);CHKERRQ(ierr); ierr = VecView(ac, vv);CHKERRQ(ierr); ierr = PetscViewerPopFormat(vv);CHKERRQ(ierr); ierr = PetscViewerDestroy(&vv);CHKERRQ(ierr); ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD, "daf_7.vtk", &vv);CHKERRQ(ierr); ierr = PetscViewerPushFormat(vv, PETSC_VIEWER_ASCII_VTK);CHKERRQ(ierr); ierr = DMView(daf, vv);CHKERRQ(ierr); ierr = VecView(af, vv);CHKERRQ(ierr); ierr = PetscViewerPopFormat(vv);CHKERRQ(ierr); ierr = PetscViewerDestroy(&vv);CHKERRQ(ierr); ierr = VecDestroy(&ac);CHKERRQ(ierr); ierr = VecDestroy(&af);CHKERRQ(ierr); } ierr = DMDestroy(&dac);CHKERRQ(ierr); ierr = DMDestroy(&daf);CHKERRQ(ierr); PetscFunctionReturn(0); }
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(((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 = 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,PetscInt,&lx,dd->n,PetscInt,&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,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 = 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,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 */ 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 = 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->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 = 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; da2->levelup = da->levelup + 1; ierr = DMSetFromOptions(da2);CHKERRQ(ierr); ierr = DMSetUp(da2);CHKERRQ(ierr); ierr = DMViewFromOptions(da2,"-dm_view");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,PETSC_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); }
PetscErrorCode da_test_RefineCoords3D(PetscInt mx,PetscInt my,PetscInt mz) { PetscErrorCode ierr; DM dac,daf; PetscViewer vv; Vec ac,af; PetscInt map_id,Mx,My,Mz; Mat II,INTERP; Vec scale; PetscBool output = PETSC_FALSE; PetscFunctionBeginUser; ierr = DMDACreate3d(PETSC_COMM_WORLD,DMDA_BOUNDARY_NONE,DMDA_BOUNDARY_NONE,DMDA_BOUNDARY_NONE,DMDA_STENCIL_BOX, mx+1, my+1,mz+1, PETSC_DECIDE, PETSC_DECIDE,PETSC_DECIDE, 1, /* 1 dof */ 1, /* stencil = 1 */ PETSC_NULL,PETSC_NULL,PETSC_NULL, &dac );CHKERRQ(ierr); ierr = DMSetFromOptions(dac);CHKERRQ(ierr); ierr = DMRefine(dac,MPI_COMM_NULL,&daf);CHKERRQ(ierr); ierr = DMDAGetInfo(daf,0,&Mx,&My,&Mz,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr); Mx--; My--; Mz--; ierr = DMDASetUniformCoordinates(dac, -1.0,1.0, -1.0,1.0, -1.0,1.0 );CHKERRQ(ierr); ierr = DMDASetUniformCoordinates(daf, -1.0,1.0, -1.0,1.0, -1.0,1.0 );CHKERRQ(ierr); /* apply trilinear mappings */ /*ierr = DAApplyTrilinearMapping(dac);CHKERRQ(ierr);*/ /* apply conformal mappings */ map_id = 0; ierr = PetscOptionsGetInt( PETSC_NULL,"-cmap", &map_id,PETSC_NULL );CHKERRQ(ierr); if (map_id >= 1) { ierr = DAApplyConformalMapping(dac,map_id);CHKERRQ(ierr); } { DM cdaf,cdac; Vec coordsc,coordsf; ierr = DMGetCoordinateDM(dac,&cdac);CHKERRQ(ierr); ierr = DMGetCoordinateDM(daf,&cdaf);CHKERRQ(ierr); ierr = DMGetCoordinates(dac,&coordsc);CHKERRQ(ierr); ierr = DMGetCoordinates(daf,&coordsf);CHKERRQ(ierr); ierr = DMCreateInterpolation(cdac,cdaf,&II,&scale);CHKERRQ(ierr); ierr = MatInterpolate(II,coordsc,coordsf);CHKERRQ(ierr); ierr = MatDestroy(&II);CHKERRQ(ierr); ierr = VecDestroy(&scale);CHKERRQ(ierr); } ierr = DMCreateInterpolation(dac,daf,&INTERP,PETSC_NULL);CHKERRQ(ierr); ierr = DMCreateGlobalVector(dac,&ac);CHKERRQ(ierr); ierr = VecZeroEntries(ac);CHKERRQ(ierr); ierr = DADefineXLinearField3D(dac,ac);CHKERRQ(ierr); ierr = DMCreateGlobalVector(daf,&af);CHKERRQ(ierr); ierr = VecZeroEntries(af);CHKERRQ(ierr); ierr = MatMult(INTERP,ac, af);CHKERRQ(ierr); { Vec afexact; PetscReal nrm; PetscInt N; ierr = DMCreateGlobalVector(daf,&afexact);CHKERRQ(ierr); ierr = VecZeroEntries(afexact);CHKERRQ(ierr); ierr = DADefineXLinearField3D(daf,afexact);CHKERRQ(ierr); ierr = VecAXPY(afexact,-1.0,af);CHKERRQ(ierr); /* af <= af - afinterp */ ierr = VecNorm(afexact,NORM_2,&nrm);CHKERRQ(ierr); ierr = VecGetSize(afexact,&N);CHKERRQ(ierr); PetscPrintf(PETSC_COMM_WORLD,"[%D x %D x %D]=>[%D x %D x %D], interp err = %1.4e\n",mx,my,mz,Mx,My,Mz,nrm/sqrt((PetscReal)N) ); ierr = VecDestroy(&afexact);CHKERRQ(ierr); } PetscOptionsGetBool(PETSC_NULL,"-output",&output,PETSC_NULL);CHKERRQ(ierr); if (output) { ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD, "dac_3D.vtk", &vv);CHKERRQ(ierr); ierr = PetscViewerSetFormat(vv, PETSC_VIEWER_ASCII_VTK);CHKERRQ(ierr); ierr = DMView(dac, vv);CHKERRQ(ierr); ierr = VecView(ac, vv);CHKERRQ(ierr); ierr = PetscViewerDestroy(&vv);CHKERRQ(ierr); ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD, "daf_3D.vtk", &vv);CHKERRQ(ierr); ierr = PetscViewerSetFormat(vv, PETSC_VIEWER_ASCII_VTK);CHKERRQ(ierr); ierr = DMView(daf, vv);CHKERRQ(ierr); ierr = VecView(af, vv);CHKERRQ(ierr); ierr = PetscViewerDestroy(&vv);CHKERRQ(ierr); } ierr = MatDestroy(&INTERP);CHKERRQ(ierr); ierr = DMDestroy(&dac);CHKERRQ(ierr); ierr = DMDestroy(&daf);CHKERRQ(ierr); ierr = VecDestroy(&ac);CHKERRQ(ierr); ierr = VecDestroy(&af);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode da_test_RefineCoords1D(PetscInt mx) { PetscErrorCode ierr; DM dac,daf; PetscViewer vv; Vec ac,af; PetscInt Mx; Mat II,INTERP; Vec scale; PetscBool output = PETSC_FALSE; PetscFunctionBeginUser; ierr = DMDACreate1d( PETSC_COMM_WORLD, DMDA_BOUNDARY_NONE, mx+1, 1, /* 1 dof */ 1, /* stencil = 1 */ PETSC_NULL, &dac );CHKERRQ(ierr); ierr = DMSetFromOptions(dac);CHKERRQ(ierr); ierr = DMRefine(dac,MPI_COMM_NULL,&daf);CHKERRQ(ierr); ierr = DMDAGetInfo(daf,0,&Mx,0,0,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr); Mx--; ierr = DMDASetUniformCoordinates(dac, -1.0,1.0, PETSC_DECIDE,PETSC_DECIDE, PETSC_DECIDE,PETSC_DECIDE );CHKERRQ(ierr); ierr = DMDASetUniformCoordinates(daf, -1.0,1.0, PETSC_DECIDE,PETSC_DECIDE, PETSC_DECIDE,PETSC_DECIDE );CHKERRQ(ierr); { DM cdaf,cdac; Vec coordsc,coordsf; ierr = DMGetCoordinateDM(dac,&cdac);CHKERRQ(ierr); ierr = DMGetCoordinateDM(daf,&cdaf);CHKERRQ(ierr); ierr = DMGetCoordinates(dac,&coordsc);CHKERRQ(ierr); ierr = DMGetCoordinates(daf,&coordsf);CHKERRQ(ierr); ierr = DMCreateInterpolation(cdac,cdaf,&II,&scale);CHKERRQ(ierr); ierr = MatInterpolate(II,coordsc,coordsf);CHKERRQ(ierr); ierr = MatDestroy(&II);CHKERRQ(ierr); ierr = VecDestroy(&scale);CHKERRQ(ierr); } ierr = DMCreateInterpolation(dac,daf,&INTERP,PETSC_NULL);CHKERRQ(ierr); ierr = DMCreateGlobalVector(dac,&ac);CHKERRQ(ierr); ierr = VecSet(ac,66.99);CHKERRQ(ierr); ierr = DMCreateGlobalVector(daf,&af);CHKERRQ(ierr); ierr = MatMult(INTERP,ac, af);CHKERRQ(ierr); { Vec afexact; PetscReal nrm; PetscInt N; ierr = DMCreateGlobalVector(daf,&afexact);CHKERRQ(ierr); ierr = VecSet(afexact,66.99);CHKERRQ(ierr); ierr = VecAXPY(afexact,-1.0,af);CHKERRQ(ierr); /* af <= af - afinterp */ ierr = VecNorm(afexact,NORM_2,&nrm);CHKERRQ(ierr); ierr = VecGetSize(afexact,&N);CHKERRQ(ierr); PetscPrintf(PETSC_COMM_WORLD,"%D=>%D, interp err = %1.4e\n",mx,Mx,nrm/sqrt((PetscReal)N) ); ierr = VecDestroy(&afexact);CHKERRQ(ierr); } PetscOptionsGetBool(PETSC_NULL,"-output",&output,PETSC_NULL);CHKERRQ(ierr); if (output) { ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD, "dac_1D.vtk", &vv);CHKERRQ(ierr); ierr = PetscViewerSetFormat(vv, PETSC_VIEWER_ASCII_VTK);CHKERRQ(ierr); ierr = DMView(dac, vv);CHKERRQ(ierr); ierr = VecView(ac, vv);CHKERRQ(ierr); ierr = PetscViewerDestroy(&vv);CHKERRQ(ierr); ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD, "daf_1D.vtk", &vv);CHKERRQ(ierr); ierr = PetscViewerSetFormat(vv, PETSC_VIEWER_ASCII_VTK);CHKERRQ(ierr); ierr = DMView(daf, vv);CHKERRQ(ierr); ierr = VecView(af, vv);CHKERRQ(ierr); ierr = PetscViewerDestroy(&vv);CHKERRQ(ierr); } ierr = MatDestroy(&INTERP);CHKERRQ(ierr); ierr = DMDestroy(&dac);CHKERRQ(ierr); ierr = DMDestroy(&daf);CHKERRQ(ierr); ierr = VecDestroy(&ac);CHKERRQ(ierr); ierr = VecDestroy(&af);CHKERRQ(ierr); PetscFunctionReturn(0); }