PetscErrorCode DMRefineHierarchy_DA(DM da,PetscInt nlevels,DM daf[]) { PetscErrorCode ierr; PetscInt i,n,*refx,*refy,*refz; PetscFunctionBegin; PetscValidHeaderSpecific(da,DM_CLASSID,1); if (nlevels < 0) SETERRQ(((PetscObject)da)->comm,PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative"); if (nlevels == 0) PetscFunctionReturn(0); PetscValidPointer(daf,3); /* Get refinement factors, defaults taken from the coarse DMDA */ ierr = PetscMalloc3(nlevels,PetscInt,&refx,nlevels,PetscInt,&refy,nlevels,PetscInt,&refz);CHKERRQ(ierr); for (i=0; i<nlevels; i++) { ierr = DMDAGetRefinementFactor(da,&refx[i],&refy[i],&refz[i]);CHKERRQ(ierr); } n = nlevels; ierr = PetscOptionsGetIntArray(((PetscObject)da)->prefix,"-da_refine_hierarchy_x",refx,&n,PETSC_NULL);CHKERRQ(ierr); n = nlevels; ierr = PetscOptionsGetIntArray(((PetscObject)da)->prefix,"-da_refine_hierarchy_y",refy,&n,PETSC_NULL);CHKERRQ(ierr); n = nlevels; ierr = PetscOptionsGetIntArray(((PetscObject)da)->prefix,"-da_refine_hierarchy_z",refz,&n,PETSC_NULL);CHKERRQ(ierr); ierr = DMDASetRefinementFactor(da,refx[0],refy[0],refz[0]);CHKERRQ(ierr); ierr = DMRefine(da,((PetscObject)da)->comm,&daf[0]);CHKERRQ(ierr); for (i=1; i<nlevels; i++) { ierr = DMDASetRefinementFactor(daf[i-1],refx[i],refy[i],refz[i]);CHKERRQ(ierr); ierr = DMRefine(daf[i-1],((PetscObject)da)->comm,&daf[i]);CHKERRQ(ierr); } ierr = PetscFree3(refx,refy,refz);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode DMSetFromOptions_DA(DM da) { PetscErrorCode ierr; DM_DA *dd = (DM_DA*)da->data; PetscInt refine = 0,maxnlevels = 100,*refx,*refy,*refz,n,i; PetscBool negativeMNP = PETSC_FALSE,bM = PETSC_FALSE,bN = PETSC_FALSE, bP = PETSC_FALSE; PetscFunctionBegin; PetscValidHeaderSpecific(da,DM_CLASSID,1); if (dd->M < 0) { dd->M = -dd->M; bM = PETSC_TRUE; negativeMNP = PETSC_TRUE; } if (dd->dim > 1 && dd->N < 0) { dd->N = -dd->N; bN = PETSC_TRUE; negativeMNP = PETSC_TRUE; } if (dd->dim > 2 && dd->P < 0) { dd->P = -dd->P; bP = PETSC_TRUE; negativeMNP = PETSC_TRUE; } ierr = PetscOptionsHead("DMDA Options");CHKERRQ(ierr); if (bM) {ierr = PetscOptionsInt("-da_grid_x","Number of grid points in x direction","DMDASetSizes",dd->M,&dd->M,PETSC_NULL);CHKERRQ(ierr);} if (bN) {ierr = PetscOptionsInt("-da_grid_y","Number of grid points in y direction","DMDASetSizes",dd->N,&dd->N,PETSC_NULL);CHKERRQ(ierr);} if (bP) {ierr = PetscOptionsInt("-da_grid_z","Number of grid points in z direction","DMDASetSizes",dd->P,&dd->P,PETSC_NULL);CHKERRQ(ierr);} /* Handle DMDA parallel distibution */ ierr = PetscOptionsInt("-da_processors_x","Number of processors in x direction","DMDASetNumProcs",dd->m,&dd->m,PETSC_NULL);CHKERRQ(ierr); if (dd->dim > 1) {ierr = PetscOptionsInt("-da_processors_y","Number of processors in y direction","DMDASetNumProcs",dd->n,&dd->n,PETSC_NULL);CHKERRQ(ierr);} if (dd->dim > 2) {ierr = PetscOptionsInt("-da_processors_z","Number of processors in z direction","DMDASetNumProcs",dd->p,&dd->p,PETSC_NULL);CHKERRQ(ierr);} /* Handle DMDA refinement */ ierr = PetscOptionsInt("-da_refine_x","Refinement ratio in x direction","DMDASetRefinementFactor",dd->refine_x,&dd->refine_x,PETSC_NULL);CHKERRQ(ierr); if (dd->dim > 1) {ierr = PetscOptionsInt("-da_refine_y","Refinement ratio in y direction","DMDASetRefinementFactor",dd->refine_y,&dd->refine_y,PETSC_NULL);CHKERRQ(ierr);} if (dd->dim > 2) {ierr = PetscOptionsInt("-da_refine_z","Refinement ratio in z direction","DMDASetRefinementFactor",dd->refine_z,&dd->refine_z,PETSC_NULL);CHKERRQ(ierr);} dd->coarsen_x = dd->refine_x; dd->coarsen_y = dd->refine_y; dd->coarsen_z = dd->refine_z; /* Get refinement factors, defaults taken from the coarse DMDA */ ierr = PetscMalloc3(maxnlevels,PetscInt,&refx,maxnlevels,PetscInt,&refy,maxnlevels,PetscInt,&refz);CHKERRQ(ierr); ierr = DMDAGetRefinementFactor(da,&refx[0],&refy[0],&refz[0]);CHKERRQ(ierr); for (i=1; i<maxnlevels; i++) { refx[i] = refx[0]; refy[i] = refy[0]; refz[i] = refz[0]; } n = maxnlevels; ierr = PetscOptionsGetIntArray(((PetscObject)da)->prefix,"-da_refine_hierarchy_x",refx,&n,PETSC_NULL);CHKERRQ(ierr); if (da->levelup - da->leveldown >= 0) dd->refine_x = refx[da->levelup - da->leveldown]; if (da->levelup - da->leveldown >= 1) dd->coarsen_x = refx[da->levelup - da->leveldown - 1]; if (dd->dim > 1) { n = maxnlevels; ierr = PetscOptionsGetIntArray(((PetscObject)da)->prefix,"-da_refine_hierarchy_y",refy,&n,PETSC_NULL);CHKERRQ(ierr); if (da->levelup - da->leveldown >= 0) dd->refine_y = refy[da->levelup - da->leveldown]; if (da->levelup - da->leveldown >= 1) dd->coarsen_y = refy[da->levelup - da->leveldown - 1]; } if (dd->dim > 2) { n = maxnlevels; ierr = PetscOptionsGetIntArray(((PetscObject)da)->prefix,"-da_refine_hierarchy_z",refz,&n,PETSC_NULL);CHKERRQ(ierr); if (da->levelup - da->leveldown >= 0) dd->refine_z = refz[da->levelup - da->leveldown]; if (da->levelup - da->leveldown >= 1) dd->coarsen_z = refz[da->levelup - da->leveldown - 1]; } if (negativeMNP) {ierr = PetscOptionsInt("-da_refine","Uniformly refine DA one or more times","None",refine,&refine,PETSC_NULL);CHKERRQ(ierr);} ierr = PetscOptionsTail();CHKERRQ(ierr); while (refine--) { if (dd->bx == DMDA_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0){ dd->M = dd->refine_x*dd->M; } else { dd->M = 1 + dd->refine_x*(dd->M - 1); } if (dd->by == DMDA_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0){ dd->N = dd->refine_y*dd->N; } else { dd->N = 1 + dd->refine_y*(dd->N - 1); } if (dd->bz == DMDA_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0){ dd->P = dd->refine_z*dd->P; } else { dd->P = 1 + dd->refine_z*(dd->P - 1); } da->levelup++; if (da->levelup - da->leveldown >= 0) { dd->refine_x = refx[da->levelup - da->leveldown]; dd->refine_y = refy[da->levelup - da->leveldown]; dd->refine_z = refz[da->levelup - da->leveldown]; } if (da->levelup - da->leveldown >= 1) { dd->coarsen_x = refx[da->levelup - da->leveldown - 1]; dd->coarsen_y = refy[da->levelup - da->leveldown - 1]; dd->coarsen_z = refz[da->levelup - da->leveldown - 1]; } } ierr = PetscFree3(refx,refy,refz);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode DMSetFromOptions_DA(PetscOptionItems *PetscOptionsObject,DM da) { PetscErrorCode ierr; DM_DA *dd = (DM_DA*)da->data; PetscInt refine = 0,dim = da->dim,maxnlevels = 100,refx[100],refy[100],refz[100],n,i; PetscBool flg; PetscFunctionBegin; PetscValidHeaderSpecific(da,DM_CLASSID,1); if (dd->M < 0) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_OUTOFRANGE,"Dimension must be non-negative, call DMSetFromOptions() if you want to change the value at runtime"); if (dd->N < 0) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_OUTOFRANGE,"Dimension must be non-negative, call DMSetFromOptions() if you want to change the value at runtime"); if (dd->P < 0) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_OUTOFRANGE,"Dimension must be non-negative, call DMSetFromOptions() if you want to change the value at runtime"); ierr = PetscOptionsHead(PetscOptionsObject,"DMDA Options");CHKERRQ(ierr); ierr = PetscOptionsInt("-da_grid_x","Number of grid points in x direction","DMDASetSizes",dd->M,&dd->M,NULL);CHKERRQ(ierr); ierr = PetscOptionsInt("-da_grid_y","Number of grid points in y direction","DMDASetSizes",dd->N,&dd->N,NULL);CHKERRQ(ierr); ierr = PetscOptionsInt("-da_grid_z","Number of grid points in z direction","DMDASetSizes",dd->P,&dd->P,NULL);CHKERRQ(ierr); ierr = PetscOptionsInt("-da_overlap","Decomposition overlap in all directions","DMDASetOverlap",dd->xol,&dd->xol,&flg);CHKERRQ(ierr); if (flg) {ierr = DMDASetOverlap(da,dd->xol,dd->xol,dd->xol);CHKERRQ(ierr);} ierr = PetscOptionsInt("-da_overlap_x","Decomposition overlap in x direction","DMDASetOverlap",dd->xol,&dd->xol,NULL);CHKERRQ(ierr); if (dim > 1) {ierr = PetscOptionsInt("-da_overlap_y","Decomposition overlap in y direction","DMDASetOverlap",dd->yol,&dd->yol,NULL);CHKERRQ(ierr);} if (dim > 2) {ierr = PetscOptionsInt("-da_overlap_z","Decomposition overlap in z direction","DMDASetOverlap",dd->zol,&dd->zol,NULL);CHKERRQ(ierr);} ierr = PetscOptionsInt("-da_local_subdomains","","DMDASetNumLocalSubdomains",dd->Nsub,&dd->Nsub,&flg);CHKERRQ(ierr); if (flg) {ierr = DMDASetNumLocalSubDomains(da,dd->Nsub);CHKERRQ(ierr);} /* Handle DMDA parallel distibution */ ierr = PetscOptionsInt("-da_processors_x","Number of processors in x direction","DMDASetNumProcs",dd->m,&dd->m,NULL);CHKERRQ(ierr); if (dim > 1) {ierr = PetscOptionsInt("-da_processors_y","Number of processors in y direction","DMDASetNumProcs",dd->n,&dd->n,NULL);CHKERRQ(ierr);} if (dim > 2) {ierr = PetscOptionsInt("-da_processors_z","Number of processors in z direction","DMDASetNumProcs",dd->p,&dd->p,NULL);CHKERRQ(ierr);} /* Handle DMDA refinement */ ierr = PetscOptionsInt("-da_refine_x","Refinement ratio in x direction","DMDASetRefinementFactor",dd->refine_x,&dd->refine_x,NULL);CHKERRQ(ierr); if (dim > 1) {ierr = PetscOptionsInt("-da_refine_y","Refinement ratio in y direction","DMDASetRefinementFactor",dd->refine_y,&dd->refine_y,NULL);CHKERRQ(ierr);} if (dim > 2) {ierr = PetscOptionsInt("-da_refine_z","Refinement ratio in z direction","DMDASetRefinementFactor",dd->refine_z,&dd->refine_z,NULL);CHKERRQ(ierr);} dd->coarsen_x = dd->refine_x; dd->coarsen_y = dd->refine_y; dd->coarsen_z = dd->refine_z; /* Get refinement factors, defaults taken from the coarse DMDA */ ierr = DMDAGetRefinementFactor(da,&refx[0],&refy[0],&refz[0]);CHKERRQ(ierr); for (i=1; i<maxnlevels; i++) { refx[i] = refx[0]; refy[i] = refy[0]; refz[i] = refz[0]; } n = maxnlevels; ierr = PetscOptionsIntArray("-da_refine_hierarchy_x","Refinement factor for each level","None",refx,&n,&flg);CHKERRQ(ierr); if (flg) { dd->refine_x = refx[0]; dd->refine_x_hier_n = n; ierr = PetscMalloc1(n,&dd->refine_x_hier);CHKERRQ(ierr); ierr = PetscMemcpy(dd->refine_x_hier,refx,n*sizeof(PetscInt));CHKERRQ(ierr); } if (dim > 1) { n = maxnlevels; ierr = PetscOptionsIntArray("-da_refine_hierarchy_y","Refinement factor for each level","None",refy,&n,&flg);CHKERRQ(ierr); if (flg) { dd->refine_y = refy[0]; dd->refine_y_hier_n = n; ierr = PetscMalloc1(n,&dd->refine_y_hier);CHKERRQ(ierr); ierr = PetscMemcpy(dd->refine_y_hier,refy,n*sizeof(PetscInt));CHKERRQ(ierr); } } if (dim > 2) { n = maxnlevels; ierr = PetscOptionsIntArray("-da_refine_hierarchy_z","Refinement factor for each level","None",refz,&n,&flg);CHKERRQ(ierr); if (flg) { dd->refine_z = refz[0]; dd->refine_z_hier_n = n; ierr = PetscMalloc1(n,&dd->refine_z_hier);CHKERRQ(ierr); ierr = PetscMemcpy(dd->refine_z_hier,refz,n*sizeof(PetscInt));CHKERRQ(ierr); } } ierr = PetscOptionsInt("-da_refine","Uniformly refine DA one or more times","None",refine,&refine,NULL);CHKERRQ(ierr); ierr = PetscOptionsTail();CHKERRQ(ierr); while (refine--) { if (dd->bx == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) { dd->M = dd->refine_x*dd->M; } else { dd->M = 1 + dd->refine_x*(dd->M - 1); } if (dd->by == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) { dd->N = dd->refine_y*dd->N; } else { dd->N = 1 + dd->refine_y*(dd->N - 1); } if (dd->bz == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) { dd->P = dd->refine_z*dd->P; } else { dd->P = 1 + dd->refine_z*(dd->P - 1); } da->levelup++; if (da->levelup - da->leveldown >= 0) { dd->refine_x = refx[da->levelup - da->leveldown]; dd->refine_y = refy[da->levelup - da->leveldown]; dd->refine_z = refz[da->levelup - da->leveldown]; } if (da->levelup - da->leveldown >= 1) { dd->coarsen_x = refx[da->levelup - da->leveldown - 1]; dd->coarsen_y = refy[da->levelup - da->leveldown - 1]; dd->coarsen_z = refz[da->levelup - da->leveldown - 1]; } } PetscFunctionReturn(0); }