1af0996ceSBarry Smith #include <petsc/private/dmdaimpl.h> /*I "petscdmda.h" I*/ 247c6ae99SBarry Smith 347c6ae99SBarry Smith /*@ 4e43dc8daSBarry Smith DMDASetSizes - Sets the number of grid points in the three dimensional directions 547c6ae99SBarry Smith 6aa219208SBarry Smith Logically Collective on DMDA 747c6ae99SBarry Smith 847c6ae99SBarry Smith Input Parameters: 9aa219208SBarry Smith + da - the DMDA 10e43dc8daSBarry Smith . M - the global X size 11e43dc8daSBarry Smith . N - the global Y size 12e43dc8daSBarry Smith - P - the global Z size 1347c6ae99SBarry Smith 1447c6ae99SBarry Smith Level: intermediate 1547c6ae99SBarry Smith 16*628e512eSPatrick Sanan Developer Notes: 17*628e512eSPatrick Sanan Since the dimension may not yet have been set the code cannot error check for non-positive Y and Z number of grid points 18e43dc8daSBarry Smith 19*628e512eSPatrick Sanan .seealso: PetscSplitOwnership() 2047c6ae99SBarry Smith @*/ 217087cfbeSBarry Smith PetscErrorCode DMDASetSizes(DM da, PetscInt M, PetscInt N, PetscInt P) 2247c6ae99SBarry Smith { 2347c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 2447c6ae99SBarry Smith 2547c6ae99SBarry Smith PetscFunctionBegin; 26a9a02de4SBarry Smith PetscValidHeaderSpecificType(da, DM_CLASSID, 1,DMDA); 2747c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da,M,2); 2847c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da,N,3); 2947c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da,P,4); 30ce94432eSBarry Smith if (da->setupcalled) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONGSTATE,"This function must be called before DMSetUp()"); 31e43dc8daSBarry Smith if (M < 1) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_SIZ,"Number of grid points in X direction must be positive"); 32e43dc8daSBarry Smith if (N < 0) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_SIZ,"Number of grid points in Y direction must be positive"); 33e43dc8daSBarry Smith if (P < 0) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_SIZ,"Number of grid points in Z direction must be positive"); 3447c6ae99SBarry Smith 3547c6ae99SBarry Smith dd->M = M; 3647c6ae99SBarry Smith dd->N = N; 3747c6ae99SBarry Smith dd->P = P; 3847c6ae99SBarry Smith PetscFunctionReturn(0); 3947c6ae99SBarry Smith } 4047c6ae99SBarry Smith 4147c6ae99SBarry Smith /*@ 42aa219208SBarry Smith DMDASetNumProcs - Sets the number of processes in each dimension 4347c6ae99SBarry Smith 44aa219208SBarry Smith Logically Collective on DMDA 4547c6ae99SBarry Smith 4647c6ae99SBarry Smith Input Parameters: 47aa219208SBarry Smith + da - the DMDA 4847c6ae99SBarry Smith . m - the number of X procs (or PETSC_DECIDE) 4947c6ae99SBarry Smith . n - the number of Y procs (or PETSC_DECIDE) 5047c6ae99SBarry Smith - p - the number of Z procs (or PETSC_DECIDE) 5147c6ae99SBarry Smith 5247c6ae99SBarry Smith Level: intermediate 5347c6ae99SBarry Smith 54*628e512eSPatrick Sanan .seealso: DMDASetSizes(), PetscSplitOwnership() 5547c6ae99SBarry Smith @*/ 567087cfbeSBarry Smith PetscErrorCode DMDASetNumProcs(DM da, PetscInt m, PetscInt n, PetscInt p) 5747c6ae99SBarry Smith { 5847c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 59e3f3e4b6SBarry Smith PetscErrorCode ierr; 6047c6ae99SBarry Smith 6147c6ae99SBarry Smith PetscFunctionBegin; 62a9a02de4SBarry Smith PetscValidHeaderSpecificType(da, DM_CLASSID, 1,DMDA); 6347c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da,m,2); 6447c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da,n,3); 6547c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da,p,4); 66ce94432eSBarry Smith if (da->setupcalled) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONGSTATE,"This function must be called before DMSetUp()"); 6747c6ae99SBarry Smith dd->m = m; 6847c6ae99SBarry Smith dd->n = n; 6947c6ae99SBarry Smith dd->p = p; 70c73cfb54SMatthew G. Knepley if (da->dim == 2) { 71d3be247eSBarry Smith PetscMPIInt size; 72d3be247eSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)da),&size);CHKERRQ(ierr); 73e3f3e4b6SBarry Smith if ((dd->m > 0) && (dd->n < 0)) { 74e3f3e4b6SBarry Smith dd->n = size/dd->m; 75ce94432eSBarry Smith if (dd->n*dd->m != size) SETERRQ2(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_OUTOFRANGE,"%D processes in X direction not divisible into comm size %d",m,size); 76e3f3e4b6SBarry Smith } 77e3f3e4b6SBarry Smith if ((dd->n > 0) && (dd->m < 0)) { 78e3f3e4b6SBarry Smith dd->m = size/dd->n; 79ce94432eSBarry Smith if (dd->n*dd->m != size) SETERRQ2(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_OUTOFRANGE,"%D processes in Y direction not divisible into comm size %d",n,size); 80e3f3e4b6SBarry Smith } 81e3f3e4b6SBarry Smith } 8247c6ae99SBarry Smith PetscFunctionReturn(0); 8347c6ae99SBarry Smith } 8447c6ae99SBarry Smith 8547c6ae99SBarry Smith /*@ 861321219cSEthan Coon DMDASetBoundaryType - Sets the type of ghost nodes on domain boundaries. 8747c6ae99SBarry Smith 8847c6ae99SBarry Smith Not collective 8947c6ae99SBarry Smith 9047c6ae99SBarry Smith Input Parameter: 91aa219208SBarry Smith + da - The DMDA 92bff4a2f0SMatthew G. Knepley - bx,by,bz - One of DM_BOUNDARY_NONE, DM_BOUNDARY_GHOSTED, DM_BOUNDARY_PERIODIC 9347c6ae99SBarry Smith 9447c6ae99SBarry Smith Level: intermediate 9547c6ae99SBarry Smith 9647c6ae99SBarry Smith .keywords: distributed array, periodicity 97bff4a2f0SMatthew G. Knepley .seealso: DMDACreate(), DMDestroy(), DMDA, DMBoundaryType 9847c6ae99SBarry Smith @*/ 99bff4a2f0SMatthew G. Knepley PetscErrorCode DMDASetBoundaryType(DM da,DMBoundaryType bx,DMBoundaryType by,DMBoundaryType bz) 10047c6ae99SBarry Smith { 10147c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 10247c6ae99SBarry Smith 10347c6ae99SBarry Smith PetscFunctionBegin; 104a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 1055a43f728SLisandro Dalcin PetscValidLogicalCollectiveEnum(da,bx,2); 1065a43f728SLisandro Dalcin PetscValidLogicalCollectiveEnum(da,by,3); 1075a43f728SLisandro Dalcin PetscValidLogicalCollectiveEnum(da,bz,4); 108ce94432eSBarry Smith if (da->setupcalled) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONGSTATE,"This function must be called before DMSetUp()"); 1091321219cSEthan Coon dd->bx = bx; 1101321219cSEthan Coon dd->by = by; 1111321219cSEthan Coon dd->bz = bz; 11247c6ae99SBarry Smith PetscFunctionReturn(0); 11347c6ae99SBarry Smith } 11447c6ae99SBarry Smith 11547c6ae99SBarry Smith /*@ 116aa219208SBarry Smith DMDASetDof - Sets the number of degrees of freedom per vertex 11747c6ae99SBarry Smith 11847c6ae99SBarry Smith Not collective 11947c6ae99SBarry Smith 12059f3ab6dSMatthew G. Knepley Input Parameters: 121aa219208SBarry Smith + da - The DMDA 12247c6ae99SBarry Smith - dof - Number of degrees of freedom 12347c6ae99SBarry Smith 12447c6ae99SBarry Smith Level: intermediate 12547c6ae99SBarry Smith 12647c6ae99SBarry Smith .keywords: distributed array, degrees of freedom 127fb6725baSMatthew G. Knepley .seealso: DMDAGetDof(), DMDACreate(), DMDestroy(), DMDA 12847c6ae99SBarry Smith @*/ 12954cfb0beSLisandro Dalcin PetscErrorCode DMDASetDof(DM da, PetscInt dof) 13047c6ae99SBarry Smith { 13147c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 13247c6ae99SBarry Smith 13347c6ae99SBarry Smith PetscFunctionBegin; 134a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 13554cfb0beSLisandro Dalcin PetscValidLogicalCollectiveInt(da,dof,2); 136ce94432eSBarry Smith if (da->setupcalled) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONGSTATE,"This function must be called before DMSetUp()"); 13747c6ae99SBarry Smith dd->w = dof; 1381411c6eeSJed Brown da->bs = dof; 13947c6ae99SBarry Smith PetscFunctionReturn(0); 14047c6ae99SBarry Smith } 14147c6ae99SBarry Smith 142fb6725baSMatthew G. Knepley /*@ 143fb6725baSMatthew G. Knepley DMDAGetDof - Gets the number of degrees of freedom per vertex 144fb6725baSMatthew G. Knepley 145fb6725baSMatthew G. Knepley Not collective 146fb6725baSMatthew G. Knepley 147fb6725baSMatthew G. Knepley Input Parameter: 148fb6725baSMatthew G. Knepley . da - The DMDA 149fb6725baSMatthew G. Knepley 150fb6725baSMatthew G. Knepley Output Parameter: 151fb6725baSMatthew G. Knepley . dof - Number of degrees of freedom 152fb6725baSMatthew G. Knepley 153fb6725baSMatthew G. Knepley Level: intermediate 154fb6725baSMatthew G. Knepley 155fb6725baSMatthew G. Knepley .keywords: distributed array, degrees of freedom 156fb6725baSMatthew G. Knepley .seealso: DMDASetDof(), DMDACreate(), DMDestroy(), DMDA 157fb6725baSMatthew G. Knepley @*/ 158fb6725baSMatthew G. Knepley PetscErrorCode DMDAGetDof(DM da, PetscInt *dof) 159fb6725baSMatthew G. Knepley { 160fb6725baSMatthew G. Knepley DM_DA *dd = (DM_DA *) da->data; 161fb6725baSMatthew G. Knepley 162fb6725baSMatthew G. Knepley PetscFunctionBegin; 163a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 164fb6725baSMatthew G. Knepley PetscValidPointer(dof,2); 165fb6725baSMatthew G. Knepley *dof = dd->w; 166fb6725baSMatthew G. Knepley PetscFunctionReturn(0); 167fb6725baSMatthew G. Knepley } 168fb6725baSMatthew G. Knepley 1697ddda789SPeter Brune /*@ 1707ddda789SPeter Brune DMDAGetOverlap - Gets the size of the per-processor overlap. 1717ddda789SPeter Brune 1727ddda789SPeter Brune Not collective 1737ddda789SPeter Brune 1747ddda789SPeter Brune Input Parameters: 1757ddda789SPeter Brune . da - The DMDA 1767ddda789SPeter Brune 1777ddda789SPeter Brune Output Parameters: 1787ddda789SPeter Brune + x - Overlap in the x direction 1797ddda789SPeter Brune . y - Overlap in the y direction 1807ddda789SPeter Brune - z - Overlap in the z direction 1817ddda789SPeter Brune 1827ddda789SPeter Brune Level: intermediate 1837ddda789SPeter Brune 1847ddda789SPeter Brune .keywords: distributed array, overlap, domain decomposition 1857ddda789SPeter Brune .seealso: DMDACreateDomainDecomposition(), DMDASetOverlap(), DMDA 1867ddda789SPeter Brune @*/ 1877ddda789SPeter Brune PetscErrorCode DMDAGetOverlap(DM da,PetscInt *x,PetscInt *y,PetscInt *z) 1887ddda789SPeter Brune { 1897ddda789SPeter Brune DM_DA *dd = (DM_DA*)da->data; 1907ddda789SPeter Brune 1917ddda789SPeter Brune PetscFunctionBegin; 192a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 1937ddda789SPeter Brune if (x) *x = dd->xol; 1947ddda789SPeter Brune if (y) *y = dd->yol; 1957ddda789SPeter Brune if (z) *z = dd->zol; 1967ddda789SPeter Brune PetscFunctionReturn(0); 1977ddda789SPeter Brune } 1987ddda789SPeter Brune 19988661749SPeter Brune /*@ 20088661749SPeter Brune DMDASetOverlap - Sets the size of the per-processor overlap. 20188661749SPeter Brune 20288661749SPeter Brune Not collective 20388661749SPeter Brune 2047ddda789SPeter Brune Input Parameters: 20588661749SPeter Brune + da - The DMDA 2067ddda789SPeter Brune . x - Overlap in the x direction 2077ddda789SPeter Brune . y - Overlap in the y direction 2087ddda789SPeter Brune - z - Overlap in the z direction 20988661749SPeter Brune 21088661749SPeter Brune Level: intermediate 21188661749SPeter Brune 2127ddda789SPeter Brune .keywords: distributed array, overlap, domain decomposition 2137ddda789SPeter Brune .seealso: DMDACreateDomainDecomposition(), DMDAGetOverlap(), DMDA 21488661749SPeter Brune @*/ 2157ddda789SPeter Brune PetscErrorCode DMDASetOverlap(DM da,PetscInt x,PetscInt y,PetscInt z) 21688661749SPeter Brune { 21788661749SPeter Brune DM_DA *dd = (DM_DA*)da->data; 21888661749SPeter Brune 21988661749SPeter Brune PetscFunctionBegin; 220a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 2217ddda789SPeter Brune PetscValidLogicalCollectiveInt(da,x,2); 2227ddda789SPeter Brune PetscValidLogicalCollectiveInt(da,y,3); 2237ddda789SPeter Brune PetscValidLogicalCollectiveInt(da,z,4); 2247ddda789SPeter Brune dd->xol = x; 2257ddda789SPeter Brune dd->yol = y; 2267ddda789SPeter Brune dd->zol = z; 22788661749SPeter Brune PetscFunctionReturn(0); 22888661749SPeter Brune } 22988661749SPeter Brune 2303e7870d2SPeter Brune 2313e7870d2SPeter Brune /*@ 2323e7870d2SPeter Brune DMDAGetNumLocalSubDomains - Gets the number of local subdomains created upon decomposition. 2333e7870d2SPeter Brune 2343e7870d2SPeter Brune Not collective 2353e7870d2SPeter Brune 2363e7870d2SPeter Brune Input Parameters: 2373e7870d2SPeter Brune . da - The DMDA 2383e7870d2SPeter Brune 2393e7870d2SPeter Brune Output Parameters: 2403e7870d2SPeter Brune + Nsub - Number of local subdomains created upon decomposition 2413e7870d2SPeter Brune 2423e7870d2SPeter Brune Level: intermediate 2433e7870d2SPeter Brune 2443e7870d2SPeter Brune .keywords: distributed array, domain decomposition 2453e7870d2SPeter Brune .seealso: DMDACreateDomainDecomposition(), DMDASetNumLocalSubDomains(), DMDA 2463e7870d2SPeter Brune @*/ 2473e7870d2SPeter Brune PetscErrorCode DMDAGetNumLocalSubDomains(DM da,PetscInt *Nsub) 2483e7870d2SPeter Brune { 2493e7870d2SPeter Brune DM_DA *dd = (DM_DA*)da->data; 2503e7870d2SPeter Brune 2513e7870d2SPeter Brune PetscFunctionBegin; 252a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 2533e7870d2SPeter Brune if (Nsub) *Nsub = dd->Nsub; 2543e7870d2SPeter Brune PetscFunctionReturn(0); 2553e7870d2SPeter Brune } 2563e7870d2SPeter Brune 2573e7870d2SPeter Brune /*@ 2583e7870d2SPeter Brune DMDASetNumLocalSubDomains - Sets the number of local subdomains created upon decomposition. 2593e7870d2SPeter Brune 2603e7870d2SPeter Brune Not collective 2613e7870d2SPeter Brune 2623e7870d2SPeter Brune Input Parameters: 2633e7870d2SPeter Brune + da - The DMDA 2643e7870d2SPeter Brune - Nsub - The number of local subdomains requested 2653e7870d2SPeter Brune 2663e7870d2SPeter Brune Level: intermediate 2673e7870d2SPeter Brune 2683e7870d2SPeter Brune .keywords: distributed array, domain decomposition 2693e7870d2SPeter Brune .seealso: DMDACreateDomainDecomposition(), DMDAGetNumLocalSubDomains(), DMDA 2703e7870d2SPeter Brune @*/ 2713e7870d2SPeter Brune PetscErrorCode DMDASetNumLocalSubDomains(DM da,PetscInt Nsub) 2723e7870d2SPeter Brune { 2733e7870d2SPeter Brune DM_DA *dd = (DM_DA*)da->data; 2743e7870d2SPeter Brune 2753e7870d2SPeter Brune PetscFunctionBegin; 276a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 2773e7870d2SPeter Brune PetscValidLogicalCollectiveInt(da,Nsub,2); 2783e7870d2SPeter Brune dd->Nsub = Nsub; 2793e7870d2SPeter Brune PetscFunctionReturn(0); 2803e7870d2SPeter Brune } 2813e7870d2SPeter Brune 282d886c4f4SPeter Brune /*@ 283d886c4f4SPeter Brune DMDASetOffset - Sets the index offset of the DA. 284d886c4f4SPeter Brune 285d886c4f4SPeter Brune Collective on DA 286d886c4f4SPeter Brune 287d886c4f4SPeter Brune Input Parameter: 288d886c4f4SPeter Brune + da - The DMDA 289d886c4f4SPeter Brune . xo - The offset in the x direction 290d886c4f4SPeter Brune . yo - The offset in the y direction 291d886c4f4SPeter Brune - zo - The offset in the z direction 292d886c4f4SPeter Brune 293d886c4f4SPeter Brune Level: intermediate 294d886c4f4SPeter Brune 29595452b02SPatrick Sanan Notes: 29695452b02SPatrick Sanan This is used primarily to overlap a computation on a local DA with that on a global DA without 297d886c4f4SPeter Brune changing boundary conditions or subdomain features that depend upon the global offsets. 298d886c4f4SPeter Brune 299d886c4f4SPeter Brune .keywords: distributed array, degrees of freedom 300d886c4f4SPeter Brune .seealso: DMDAGetOffset(), DMDAVecGetArray() 301d886c4f4SPeter Brune @*/ 30295c13181SPeter Brune PetscErrorCode DMDASetOffset(DM da, PetscInt xo, PetscInt yo, PetscInt zo, PetscInt Mo, PetscInt No, PetscInt Po) 303d886c4f4SPeter Brune { 30495c13181SPeter Brune PetscErrorCode ierr; 305d886c4f4SPeter Brune DM_DA *dd = (DM_DA*)da->data; 306d886c4f4SPeter Brune 307d886c4f4SPeter Brune PetscFunctionBegin; 308a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 309d886c4f4SPeter Brune PetscValidLogicalCollectiveInt(da,xo,2); 31095c13181SPeter Brune PetscValidLogicalCollectiveInt(da,yo,3); 31195c13181SPeter Brune PetscValidLogicalCollectiveInt(da,zo,4); 31295c13181SPeter Brune PetscValidLogicalCollectiveInt(da,Mo,5); 31395c13181SPeter Brune PetscValidLogicalCollectiveInt(da,No,6); 31495c13181SPeter Brune PetscValidLogicalCollectiveInt(da,Po,7); 315d886c4f4SPeter Brune dd->xo = xo; 316d886c4f4SPeter Brune dd->yo = yo; 317d886c4f4SPeter Brune dd->zo = zo; 31895c13181SPeter Brune dd->Mo = Mo; 31995c13181SPeter Brune dd->No = No; 32095c13181SPeter Brune dd->Po = Po; 32195c13181SPeter Brune 32295c13181SPeter Brune if (da->coordinateDM) { 32395c13181SPeter Brune ierr = DMDASetOffset(da->coordinateDM,xo,yo,zo,Mo,No,Po);CHKERRQ(ierr); 32495c13181SPeter Brune } 325d886c4f4SPeter Brune PetscFunctionReturn(0); 326d886c4f4SPeter Brune } 327d886c4f4SPeter Brune 328d886c4f4SPeter Brune /*@ 329d886c4f4SPeter Brune DMDAGetOffset - Gets the index offset of the DA. 330d886c4f4SPeter Brune 331d886c4f4SPeter Brune Not collective 332d886c4f4SPeter Brune 333d886c4f4SPeter Brune Input Parameter: 334d886c4f4SPeter Brune . da - The DMDA 335d886c4f4SPeter Brune 336d886c4f4SPeter Brune Output Parameters: 337d886c4f4SPeter Brune + xo - The offset in the x direction 338d886c4f4SPeter Brune . yo - The offset in the y direction 33995c13181SPeter Brune . zo - The offset in the z direction 34095c13181SPeter Brune . Mo - The global size in the x direction 34195c13181SPeter Brune . No - The global size in the y direction 34295c13181SPeter Brune - Po - The global size in the z direction 343d886c4f4SPeter Brune 344d886c4f4SPeter Brune Level: intermediate 345d886c4f4SPeter Brune 346d886c4f4SPeter Brune .keywords: distributed array, degrees of freedom 347d886c4f4SPeter Brune .seealso: DMDASetOffset(), DMDAVecGetArray() 348d886c4f4SPeter Brune @*/ 34995c13181SPeter Brune PetscErrorCode DMDAGetOffset(DM da,PetscInt *xo,PetscInt *yo,PetscInt *zo,PetscInt *Mo,PetscInt *No,PetscInt *Po) 350d886c4f4SPeter Brune { 351d886c4f4SPeter Brune DM_DA *dd = (DM_DA*)da->data; 352d886c4f4SPeter Brune 353d886c4f4SPeter Brune PetscFunctionBegin; 354a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 355d886c4f4SPeter Brune if (xo) *xo = dd->xo; 356d886c4f4SPeter Brune if (yo) *yo = dd->yo; 357d886c4f4SPeter Brune if (zo) *zo = dd->zo; 35895c13181SPeter Brune if (Mo) *Mo = dd->Mo; 35995c13181SPeter Brune if (No) *No = dd->No; 36095c13181SPeter Brune if (Po) *Po = dd->Po; 361d886c4f4SPeter Brune PetscFunctionReturn(0); 362d886c4f4SPeter Brune } 363d886c4f4SPeter Brune 36440234c92SPeter Brune /*@ 36540234c92SPeter Brune DMDAGetNonOverlappingRegion - Gets the indices of the nonoverlapping region of a subdomain DM. 36640234c92SPeter Brune 36740234c92SPeter Brune Not collective 36840234c92SPeter Brune 36940234c92SPeter Brune Input Parameter: 37040234c92SPeter Brune . da - The DMDA 37140234c92SPeter Brune 37240234c92SPeter Brune Output Parameters: 37340234c92SPeter Brune + xs - The start of the region in x 37440234c92SPeter Brune . ys - The start of the region in y 37540234c92SPeter Brune . zs - The start of the region in z 37640234c92SPeter Brune . xs - The size of the region in x 37740234c92SPeter Brune . ys - The size of the region in y 37840234c92SPeter Brune . zs - The size of the region in z 37940234c92SPeter Brune 38040234c92SPeter Brune Level: intermediate 38140234c92SPeter Brune 38240234c92SPeter Brune .keywords: distributed array, degrees of freedom 38340234c92SPeter Brune .seealso: DMDAGetOffset(), DMDAVecGetArray() 38440234c92SPeter Brune @*/ 38540234c92SPeter Brune PetscErrorCode DMDAGetNonOverlappingRegion(DM da, PetscInt *xs, PetscInt *ys, PetscInt *zs, PetscInt *xm, PetscInt *ym, PetscInt *zm) 38640234c92SPeter Brune { 38740234c92SPeter Brune DM_DA *dd = (DM_DA*)da->data; 38840234c92SPeter Brune 38940234c92SPeter Brune PetscFunctionBegin; 390a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 39140234c92SPeter Brune if (xs) *xs = dd->nonxs; 39240234c92SPeter Brune if (ys) *ys = dd->nonys; 39340234c92SPeter Brune if (zs) *zs = dd->nonzs; 39440234c92SPeter Brune if (xm) *xm = dd->nonxm; 39540234c92SPeter Brune if (ym) *ym = dd->nonym; 39640234c92SPeter Brune if (zm) *zm = dd->nonzm; 39740234c92SPeter Brune PetscFunctionReturn(0); 39840234c92SPeter Brune } 39940234c92SPeter Brune 40040234c92SPeter Brune 40140234c92SPeter Brune /*@ 40240234c92SPeter Brune DMDASetNonOverlappingRegion - Sets the indices of the nonoverlapping region of a subdomain DM. 40340234c92SPeter Brune 40440234c92SPeter Brune Collective on DA 40540234c92SPeter Brune 40640234c92SPeter Brune Input Parameter: 40740234c92SPeter Brune + da - The DMDA 40840234c92SPeter Brune . xs - The start of the region in x 40940234c92SPeter Brune . ys - The start of the region in y 41040234c92SPeter Brune . zs - The start of the region in z 41140234c92SPeter Brune . xs - The size of the region in x 41240234c92SPeter Brune . ys - The size of the region in y 41340234c92SPeter Brune . zs - The size of the region in z 41440234c92SPeter Brune 41540234c92SPeter Brune Level: intermediate 41640234c92SPeter Brune 41740234c92SPeter Brune .keywords: distributed array, degrees of freedom 41840234c92SPeter Brune .seealso: DMDAGetOffset(), DMDAVecGetArray() 41940234c92SPeter Brune @*/ 42040234c92SPeter Brune PetscErrorCode DMDASetNonOverlappingRegion(DM da, PetscInt xs, PetscInt ys, PetscInt zs, PetscInt xm, PetscInt ym, PetscInt zm) 42140234c92SPeter Brune { 42240234c92SPeter Brune DM_DA *dd = (DM_DA*)da->data; 42340234c92SPeter Brune 42440234c92SPeter Brune PetscFunctionBegin; 425a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 42640234c92SPeter Brune PetscValidLogicalCollectiveInt(da,xs,2); 42740234c92SPeter Brune PetscValidLogicalCollectiveInt(da,ys,3); 42840234c92SPeter Brune PetscValidLogicalCollectiveInt(da,zs,4); 42940234c92SPeter Brune PetscValidLogicalCollectiveInt(da,xm,5); 43040234c92SPeter Brune PetscValidLogicalCollectiveInt(da,ym,6); 43140234c92SPeter Brune PetscValidLogicalCollectiveInt(da,zm,7); 43240234c92SPeter Brune dd->nonxs = xs; 43340234c92SPeter Brune dd->nonys = ys; 43440234c92SPeter Brune dd->nonzs = zs; 43540234c92SPeter Brune dd->nonxm = xm; 43640234c92SPeter Brune dd->nonym = ym; 43740234c92SPeter Brune dd->nonzm = zm; 43840234c92SPeter Brune 43940234c92SPeter Brune PetscFunctionReturn(0); 44040234c92SPeter Brune } 44188661749SPeter Brune 44247c6ae99SBarry Smith /*@ 443aa219208SBarry Smith DMDASetStencilType - Sets the type of the communication stencil 44447c6ae99SBarry Smith 445aa219208SBarry Smith Logically Collective on DMDA 44647c6ae99SBarry Smith 44747c6ae99SBarry Smith Input Parameter: 448aa219208SBarry Smith + da - The DMDA 449aa219208SBarry Smith - stype - The stencil type, use either DMDA_STENCIL_BOX or DMDA_STENCIL_STAR. 45047c6ae99SBarry Smith 45147c6ae99SBarry Smith Level: intermediate 45247c6ae99SBarry Smith 45347c6ae99SBarry Smith .keywords: distributed array, stencil 45496e147daSBarry Smith .seealso: DMDACreate(), DMDestroy(), DMDA 45547c6ae99SBarry Smith @*/ 4567087cfbeSBarry Smith PetscErrorCode DMDASetStencilType(DM da, DMDAStencilType stype) 45747c6ae99SBarry Smith { 45847c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 45947c6ae99SBarry Smith 46047c6ae99SBarry Smith PetscFunctionBegin; 461a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 46247c6ae99SBarry Smith PetscValidLogicalCollectiveEnum(da,stype,2); 463ce94432eSBarry Smith if (da->setupcalled) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONGSTATE,"This function must be called before DMSetUp()"); 46447c6ae99SBarry Smith dd->stencil_type = stype; 46547c6ae99SBarry Smith PetscFunctionReturn(0); 46647c6ae99SBarry Smith } 46747c6ae99SBarry Smith 468fb6725baSMatthew G. Knepley /*@ 469fb6725baSMatthew G. Knepley DMDAGetStencilType - Gets the type of the communication stencil 470fb6725baSMatthew G. Knepley 471fb6725baSMatthew G. Knepley Not collective 472fb6725baSMatthew G. Knepley 473fb6725baSMatthew G. Knepley Input Parameter: 474fb6725baSMatthew G. Knepley . da - The DMDA 475fb6725baSMatthew G. Knepley 476fb6725baSMatthew G. Knepley Output Parameter: 477fb6725baSMatthew G. Knepley . stype - The stencil type, use either DMDA_STENCIL_BOX or DMDA_STENCIL_STAR. 478fb6725baSMatthew G. Knepley 479fb6725baSMatthew G. Knepley Level: intermediate 480fb6725baSMatthew G. Knepley 481fb6725baSMatthew G. Knepley .keywords: distributed array, stencil 482fb6725baSMatthew G. Knepley .seealso: DMDACreate(), DMDestroy(), DMDA 483fb6725baSMatthew G. Knepley @*/ 484fb6725baSMatthew G. Knepley PetscErrorCode DMDAGetStencilType(DM da, DMDAStencilType *stype) 485fb6725baSMatthew G. Knepley { 486fb6725baSMatthew G. Knepley DM_DA *dd = (DM_DA*)da->data; 487fb6725baSMatthew G. Knepley 488fb6725baSMatthew G. Knepley PetscFunctionBegin; 489a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 490fb6725baSMatthew G. Knepley PetscValidPointer(stype,2); 491fb6725baSMatthew G. Knepley *stype = dd->stencil_type; 492fb6725baSMatthew G. Knepley PetscFunctionReturn(0); 493fb6725baSMatthew G. Knepley } 494fb6725baSMatthew G. Knepley 49547c6ae99SBarry Smith /*@ 496aa219208SBarry Smith DMDASetStencilWidth - Sets the width of the communication stencil 49747c6ae99SBarry Smith 498aa219208SBarry Smith Logically Collective on DMDA 49947c6ae99SBarry Smith 50047c6ae99SBarry Smith Input Parameter: 501aa219208SBarry Smith + da - The DMDA 50247c6ae99SBarry Smith - width - The stencil width 50347c6ae99SBarry Smith 50447c6ae99SBarry Smith Level: intermediate 50547c6ae99SBarry Smith 50647c6ae99SBarry Smith .keywords: distributed array, stencil 50796e147daSBarry Smith .seealso: DMDACreate(), DMDestroy(), DMDA 50847c6ae99SBarry Smith @*/ 5097087cfbeSBarry Smith PetscErrorCode DMDASetStencilWidth(DM da, PetscInt width) 51047c6ae99SBarry Smith { 51147c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 51247c6ae99SBarry Smith 51347c6ae99SBarry Smith PetscFunctionBegin; 514a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 51547c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da,width,2); 516ce94432eSBarry Smith if (da->setupcalled) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONGSTATE,"This function must be called before DMSetUp()"); 51747c6ae99SBarry Smith dd->s = width; 51847c6ae99SBarry Smith PetscFunctionReturn(0); 51947c6ae99SBarry Smith } 52047c6ae99SBarry Smith 521fb6725baSMatthew G. Knepley /*@ 522fb6725baSMatthew G. Knepley DMDAGetStencilWidth - Gets the width of the communication stencil 523fb6725baSMatthew G. Knepley 524fb6725baSMatthew G. Knepley Not collective 525fb6725baSMatthew G. Knepley 526fb6725baSMatthew G. Knepley Input Parameter: 527fb6725baSMatthew G. Knepley . da - The DMDA 528fb6725baSMatthew G. Knepley 529fb6725baSMatthew G. Knepley Output Parameter: 530fb6725baSMatthew G. Knepley . width - The stencil width 531fb6725baSMatthew G. Knepley 532fb6725baSMatthew G. Knepley Level: intermediate 533fb6725baSMatthew G. Knepley 534fb6725baSMatthew G. Knepley .keywords: distributed array, stencil 535fb6725baSMatthew G. Knepley .seealso: DMDACreate(), DMDestroy(), DMDA 536fb6725baSMatthew G. Knepley @*/ 537fb6725baSMatthew G. Knepley PetscErrorCode DMDAGetStencilWidth(DM da, PetscInt *width) 538fb6725baSMatthew G. Knepley { 539fb6725baSMatthew G. Knepley DM_DA *dd = (DM_DA *) da->data; 540fb6725baSMatthew G. Knepley 541fb6725baSMatthew G. Knepley PetscFunctionBegin; 542a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 543fb6725baSMatthew G. Knepley PetscValidPointer(width,2); 544fb6725baSMatthew G. Knepley *width = dd->s; 545fb6725baSMatthew G. Knepley PetscFunctionReturn(0); 546fb6725baSMatthew G. Knepley } 547fb6725baSMatthew G. Knepley 548aa219208SBarry Smith static PetscErrorCode DMDACheckOwnershipRanges_Private(DM da,PetscInt M,PetscInt m,const PetscInt lx[]) 54947c6ae99SBarry Smith { 55047c6ae99SBarry Smith PetscInt i,sum; 55147c6ae99SBarry Smith 55247c6ae99SBarry Smith PetscFunctionBegin; 553ce94432eSBarry Smith if (M < 0) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONGSTATE,"Global dimension not set"); 55447c6ae99SBarry Smith for (i=sum=0; i<m; i++) sum += lx[i]; 555ce94432eSBarry Smith if (sum != M) SETERRQ2(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_INCOMP,"Ownership ranges sum to %D but global dimension is %D",sum,M); 55647c6ae99SBarry Smith PetscFunctionReturn(0); 55747c6ae99SBarry Smith } 55847c6ae99SBarry Smith 55947c6ae99SBarry Smith /*@ 560aa219208SBarry Smith DMDASetOwnershipRanges - Sets the number of nodes in each direction on each process 56147c6ae99SBarry Smith 562aa219208SBarry Smith Logically Collective on DMDA 56347c6ae99SBarry Smith 56447c6ae99SBarry Smith Input Parameter: 565aa219208SBarry Smith + da - The DMDA 5660298fd71SBarry Smith . lx - array containing number of nodes in the X direction on each process, or NULL. If non-null, must be of length da->m 5670298fd71SBarry Smith . ly - array containing number of nodes in the Y direction on each process, or NULL. If non-null, must be of length da->n 5680298fd71SBarry Smith - lz - array containing number of nodes in the Z direction on each process, or NULL. If non-null, must be of length da->p. 56947c6ae99SBarry Smith 57047c6ae99SBarry Smith Level: intermediate 57147c6ae99SBarry Smith 572e3f3e4b6SBarry Smith Note: these numbers are NOT multiplied by the number of dof per node. 573e3f3e4b6SBarry Smith 57447c6ae99SBarry Smith .keywords: distributed array 57596e147daSBarry Smith .seealso: DMDACreate(), DMDestroy(), DMDA 57647c6ae99SBarry Smith @*/ 5777087cfbeSBarry Smith PetscErrorCode DMDASetOwnershipRanges(DM da, const PetscInt lx[], const PetscInt ly[], const PetscInt lz[]) 57847c6ae99SBarry Smith { 57947c6ae99SBarry Smith PetscErrorCode ierr; 58047c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 58147c6ae99SBarry Smith 58247c6ae99SBarry Smith PetscFunctionBegin; 583a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 584ce94432eSBarry Smith if (da->setupcalled) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONGSTATE,"This function must be called before DMSetUp()"); 58547c6ae99SBarry Smith if (lx) { 586ce94432eSBarry Smith if (dd->m < 0) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONGSTATE,"Cannot set ownership ranges before setting number of procs"); 587aa219208SBarry Smith ierr = DMDACheckOwnershipRanges_Private(da,dd->M,dd->m,lx);CHKERRQ(ierr); 58847c6ae99SBarry Smith if (!dd->lx) { 589785e854fSJed Brown ierr = PetscMalloc1(dd->m, &dd->lx);CHKERRQ(ierr); 59047c6ae99SBarry Smith } 59147c6ae99SBarry Smith ierr = PetscMemcpy(dd->lx, lx, dd->m*sizeof(PetscInt));CHKERRQ(ierr); 59247c6ae99SBarry Smith } 59347c6ae99SBarry Smith if (ly) { 594ce94432eSBarry Smith if (dd->n < 0) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONGSTATE,"Cannot set ownership ranges before setting number of procs"); 595aa219208SBarry Smith ierr = DMDACheckOwnershipRanges_Private(da,dd->N,dd->n,ly);CHKERRQ(ierr); 59647c6ae99SBarry Smith if (!dd->ly) { 597785e854fSJed Brown ierr = PetscMalloc1(dd->n, &dd->ly);CHKERRQ(ierr); 59847c6ae99SBarry Smith } 59947c6ae99SBarry Smith ierr = PetscMemcpy(dd->ly, ly, dd->n*sizeof(PetscInt));CHKERRQ(ierr); 60047c6ae99SBarry Smith } 60147c6ae99SBarry Smith if (lz) { 602ce94432eSBarry Smith if (dd->p < 0) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONGSTATE,"Cannot set ownership ranges before setting number of procs"); 603aa219208SBarry Smith ierr = DMDACheckOwnershipRanges_Private(da,dd->P,dd->p,lz);CHKERRQ(ierr); 60447c6ae99SBarry Smith if (!dd->lz) { 605785e854fSJed Brown ierr = PetscMalloc1(dd->p, &dd->lz);CHKERRQ(ierr); 60647c6ae99SBarry Smith } 60747c6ae99SBarry Smith ierr = PetscMemcpy(dd->lz, lz, dd->p*sizeof(PetscInt));CHKERRQ(ierr); 60847c6ae99SBarry Smith } 60947c6ae99SBarry Smith PetscFunctionReturn(0); 61047c6ae99SBarry Smith } 61147c6ae99SBarry Smith 61247c6ae99SBarry Smith /*@ 613aa219208SBarry Smith DMDASetInterpolationType - Sets the type of interpolation that will be 614e727c939SJed Brown returned by DMCreateInterpolation() 61547c6ae99SBarry Smith 616aa219208SBarry Smith Logically Collective on DMDA 61747c6ae99SBarry Smith 61847c6ae99SBarry Smith Input Parameter: 61947c6ae99SBarry Smith + da - initial distributed array 620aa219208SBarry Smith . ctype - DMDA_Q1 and DMDA_Q0 are currently the only supported forms 62147c6ae99SBarry Smith 62247c6ae99SBarry Smith Level: intermediate 62347c6ae99SBarry Smith 62495452b02SPatrick Sanan Notes: 62595452b02SPatrick Sanan you should call this on the coarser of the two DMDAs you pass to DMCreateInterpolation() 62647c6ae99SBarry Smith 62747c6ae99SBarry Smith .keywords: distributed array, interpolation 62847c6ae99SBarry Smith 62996e147daSBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMDestroy(), DMDA, DMDAInterpolationType 63047c6ae99SBarry Smith @*/ 6317087cfbeSBarry Smith PetscErrorCode DMDASetInterpolationType(DM da,DMDAInterpolationType ctype) 63247c6ae99SBarry Smith { 63347c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 63447c6ae99SBarry Smith 63547c6ae99SBarry Smith PetscFunctionBegin; 636a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 63747c6ae99SBarry Smith PetscValidLogicalCollectiveEnum(da,ctype,2); 63847c6ae99SBarry Smith dd->interptype = ctype; 63947c6ae99SBarry Smith PetscFunctionReturn(0); 64047c6ae99SBarry Smith } 64147c6ae99SBarry Smith 6422dde6fd4SLisandro Dalcin /*@ 6432dde6fd4SLisandro Dalcin DMDAGetInterpolationType - Gets the type of interpolation that will be 644e727c939SJed Brown used by DMCreateInterpolation() 6452dde6fd4SLisandro Dalcin 6462dde6fd4SLisandro Dalcin Not Collective 6472dde6fd4SLisandro Dalcin 6482dde6fd4SLisandro Dalcin Input Parameter: 6492dde6fd4SLisandro Dalcin . da - distributed array 6502dde6fd4SLisandro Dalcin 6512dde6fd4SLisandro Dalcin Output Parameter: 6522dde6fd4SLisandro Dalcin . ctype - interpolation type (DMDA_Q1 and DMDA_Q0 are currently the only supported forms) 6532dde6fd4SLisandro Dalcin 6542dde6fd4SLisandro Dalcin Level: intermediate 6552dde6fd4SLisandro Dalcin 6562dde6fd4SLisandro Dalcin .keywords: distributed array, interpolation 6572dde6fd4SLisandro Dalcin 658e727c939SJed Brown .seealso: DMDA, DMDAInterpolationType, DMDASetInterpolationType(), DMCreateInterpolation() 6592dde6fd4SLisandro Dalcin @*/ 6602dde6fd4SLisandro Dalcin PetscErrorCode DMDAGetInterpolationType(DM da,DMDAInterpolationType *ctype) 6612dde6fd4SLisandro Dalcin { 6622dde6fd4SLisandro Dalcin DM_DA *dd = (DM_DA*)da->data; 6632dde6fd4SLisandro Dalcin 6642dde6fd4SLisandro Dalcin PetscFunctionBegin; 665a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 6662dde6fd4SLisandro Dalcin PetscValidPointer(ctype,2); 6672dde6fd4SLisandro Dalcin *ctype = dd->interptype; 6682dde6fd4SLisandro Dalcin PetscFunctionReturn(0); 6692dde6fd4SLisandro Dalcin } 67047c6ae99SBarry Smith 6716a119db4SBarry Smith /*@C 672aa219208SBarry Smith DMDAGetNeighbors - Gets an array containing the MPI rank of all the current 67347c6ae99SBarry Smith processes neighbors. 67447c6ae99SBarry Smith 67547c6ae99SBarry Smith Not Collective 67647c6ae99SBarry Smith 67747c6ae99SBarry Smith Input Parameter: 678aa219208SBarry Smith . da - the DMDA object 67947c6ae99SBarry Smith 68047c6ae99SBarry Smith Output Parameters: 68147c6ae99SBarry Smith . ranks - the neighbors ranks, stored with the x index increasing most rapidly. 68247c6ae99SBarry Smith this process itself is in the list 68347c6ae99SBarry Smith 68495452b02SPatrick Sanan Notes: 68595452b02SPatrick Sanan In 2d the array is of length 9, in 3d of length 27 68647c6ae99SBarry Smith Not supported in 1d 687aa219208SBarry Smith Do not free the array, it is freed when the DMDA is destroyed. 68847c6ae99SBarry Smith 68995452b02SPatrick Sanan Fortran Notes: 69095452b02SPatrick Sanan In fortran you must pass in an array of the appropriate length. 69147c6ae99SBarry Smith 69247c6ae99SBarry Smith Level: intermediate 69347c6ae99SBarry Smith 69447c6ae99SBarry Smith @*/ 6957087cfbeSBarry Smith PetscErrorCode DMDAGetNeighbors(DM da,const PetscMPIInt *ranks[]) 69647c6ae99SBarry Smith { 69747c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 6985fd66863SKarl Rupp 69947c6ae99SBarry Smith PetscFunctionBegin; 700a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 70147c6ae99SBarry Smith *ranks = dd->neighbors; 70247c6ae99SBarry Smith PetscFunctionReturn(0); 70347c6ae99SBarry Smith } 70447c6ae99SBarry Smith 70547c6ae99SBarry Smith /*@C 706aa219208SBarry Smith DMDAGetOwnershipRanges - Gets the ranges of indices in the x, y and z direction that are owned by each process 70747c6ae99SBarry Smith 70847c6ae99SBarry Smith Not Collective 70947c6ae99SBarry Smith 71047c6ae99SBarry Smith Input Parameter: 711aa219208SBarry Smith . da - the DMDA object 71247c6ae99SBarry Smith 71347c6ae99SBarry Smith Output Parameter: 71447c6ae99SBarry Smith + lx - ownership along x direction (optional) 71547c6ae99SBarry Smith . ly - ownership along y direction (optional) 71647c6ae99SBarry Smith - lz - ownership along z direction (optional) 71747c6ae99SBarry Smith 71847c6ae99SBarry Smith Level: intermediate 71947c6ae99SBarry Smith 720aa219208SBarry Smith Note: these correspond to the optional final arguments passed to DMDACreate(), DMDACreate2d(), DMDACreate3d() 72147c6ae99SBarry Smith 72247c6ae99SBarry Smith In Fortran one must pass in arrays lx, ly, and lz that are long enough to hold the values; the sixth, seventh and 723aa219208SBarry Smith eighth arguments from DMDAGetInfo() 72447c6ae99SBarry Smith 72547c6ae99SBarry Smith In C you should not free these arrays, nor change the values in them. They will only have valid values while the 726aa219208SBarry Smith DMDA they came from still exists (has not been destroyed). 72747c6ae99SBarry Smith 728e3f3e4b6SBarry Smith These numbers are NOT multiplied by the number of dof per node. 729e3f3e4b6SBarry Smith 7301fd49c25SBarry Smith Not available from Fortran 7311fd49c25SBarry Smith 732aa219208SBarry Smith .seealso: DMDAGetCorners(), DMDAGetGhostCorners(), DMDACreate(), DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), VecGetOwnershipRanges() 73347c6ae99SBarry Smith @*/ 7347087cfbeSBarry Smith PetscErrorCode DMDAGetOwnershipRanges(DM da,const PetscInt *lx[],const PetscInt *ly[],const PetscInt *lz[]) 73547c6ae99SBarry Smith { 73647c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 73747c6ae99SBarry Smith 73847c6ae99SBarry Smith PetscFunctionBegin; 739a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 74047c6ae99SBarry Smith if (lx) *lx = dd->lx; 74147c6ae99SBarry Smith if (ly) *ly = dd->ly; 74247c6ae99SBarry Smith if (lz) *lz = dd->lz; 74347c6ae99SBarry Smith PetscFunctionReturn(0); 74447c6ae99SBarry Smith } 74547c6ae99SBarry Smith 74647c6ae99SBarry Smith /*@ 747aa219208SBarry Smith DMDASetRefinementFactor - Set the ratios that the DMDA grid is refined 74847c6ae99SBarry Smith 749aa219208SBarry Smith Logically Collective on DMDA 75047c6ae99SBarry Smith 75147c6ae99SBarry Smith Input Parameters: 752aa219208SBarry Smith + da - the DMDA object 75347c6ae99SBarry Smith . refine_x - ratio of fine grid to coarse in x direction (2 by default) 75447c6ae99SBarry Smith . refine_y - ratio of fine grid to coarse in y direction (2 by default) 75547c6ae99SBarry Smith - refine_z - ratio of fine grid to coarse in z direction (2 by default) 75647c6ae99SBarry Smith 75747c6ae99SBarry Smith Options Database: 75847c6ae99SBarry Smith + -da_refine_x - refinement ratio in x direction 75947c6ae99SBarry Smith . -da_refine_y - refinement ratio in y direction 76047c6ae99SBarry Smith - -da_refine_z - refinement ratio in z direction 76147c6ae99SBarry Smith 76247c6ae99SBarry Smith Level: intermediate 76347c6ae99SBarry Smith 76495452b02SPatrick Sanan Notes: 76595452b02SPatrick Sanan Pass PETSC_IGNORE to leave a value unchanged 76647c6ae99SBarry Smith 767aa219208SBarry Smith .seealso: DMRefine(), DMDAGetRefinementFactor() 76847c6ae99SBarry Smith @*/ 7697087cfbeSBarry Smith PetscErrorCode DMDASetRefinementFactor(DM da, PetscInt refine_x, PetscInt refine_y,PetscInt refine_z) 77047c6ae99SBarry Smith { 77147c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 77247c6ae99SBarry Smith 77347c6ae99SBarry Smith PetscFunctionBegin; 774a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 77547c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da,refine_x,2); 77647c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da,refine_y,3); 77747c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da,refine_z,4); 77847c6ae99SBarry Smith 77947c6ae99SBarry Smith if (refine_x > 0) dd->refine_x = refine_x; 78047c6ae99SBarry Smith if (refine_y > 0) dd->refine_y = refine_y; 78147c6ae99SBarry Smith if (refine_z > 0) dd->refine_z = refine_z; 78247c6ae99SBarry Smith PetscFunctionReturn(0); 78347c6ae99SBarry Smith } 78447c6ae99SBarry Smith 78547c6ae99SBarry Smith /*@C 786aa219208SBarry Smith DMDAGetRefinementFactor - Gets the ratios that the DMDA grid is refined 78747c6ae99SBarry Smith 78847c6ae99SBarry Smith Not Collective 78947c6ae99SBarry Smith 79047c6ae99SBarry Smith Input Parameter: 791aa219208SBarry Smith . da - the DMDA object 79247c6ae99SBarry Smith 79347c6ae99SBarry Smith Output Parameters: 79447c6ae99SBarry Smith + refine_x - ratio of fine grid to coarse in x direction (2 by default) 79547c6ae99SBarry Smith . refine_y - ratio of fine grid to coarse in y direction (2 by default) 79647c6ae99SBarry Smith - refine_z - ratio of fine grid to coarse in z direction (2 by default) 79747c6ae99SBarry Smith 79847c6ae99SBarry Smith Level: intermediate 79947c6ae99SBarry Smith 80095452b02SPatrick Sanan Notes: 80195452b02SPatrick Sanan Pass NULL for values you do not need 80247c6ae99SBarry Smith 803aa219208SBarry Smith .seealso: DMRefine(), DMDASetRefinementFactor() 80447c6ae99SBarry Smith @*/ 8057087cfbeSBarry Smith PetscErrorCode DMDAGetRefinementFactor(DM da, PetscInt *refine_x, PetscInt *refine_y,PetscInt *refine_z) 80647c6ae99SBarry Smith { 80747c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 80847c6ae99SBarry Smith 80947c6ae99SBarry Smith PetscFunctionBegin; 810a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 81147c6ae99SBarry Smith if (refine_x) *refine_x = dd->refine_x; 81247c6ae99SBarry Smith if (refine_y) *refine_y = dd->refine_y; 81347c6ae99SBarry Smith if (refine_z) *refine_z = dd->refine_z; 81447c6ae99SBarry Smith PetscFunctionReturn(0); 81547c6ae99SBarry Smith } 81647c6ae99SBarry Smith 81747c6ae99SBarry Smith /*@C 818aa219208SBarry Smith DMDASetGetMatrix - Sets the routine used by the DMDA to allocate a matrix. 81947c6ae99SBarry Smith 820aa219208SBarry Smith Logically Collective on DMDA 82147c6ae99SBarry Smith 82247c6ae99SBarry Smith Input Parameters: 823aa219208SBarry Smith + da - the DMDA object 824aa219208SBarry Smith - f - the function that allocates the matrix for that specific DMDA 82547c6ae99SBarry Smith 82647c6ae99SBarry Smith Level: developer 82747c6ae99SBarry Smith 82895452b02SPatrick Sanan Notes: 82995452b02SPatrick Sanan See DMDASetBlockFills() that provides a simple way to provide the nonzero structure for 83047c6ae99SBarry Smith the diagonal and off-diagonal blocks of the matrix 83147c6ae99SBarry Smith 8321fd49c25SBarry Smith Not supported from Fortran 8331fd49c25SBarry Smith 834950540a4SJed Brown .seealso: DMCreateMatrix(), DMDASetBlockFills() 83547c6ae99SBarry Smith @*/ 836b412c318SBarry Smith PetscErrorCode DMDASetGetMatrix(DM da,PetscErrorCode (*f)(DM, Mat*)) 83747c6ae99SBarry Smith { 83847c6ae99SBarry Smith PetscFunctionBegin; 839a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 84025296bd5SBarry Smith da->ops->creatematrix = f; 84147c6ae99SBarry Smith PetscFunctionReturn(0); 84247c6ae99SBarry Smith } 84347c6ae99SBarry Smith 84447c6ae99SBarry Smith /* 84547c6ae99SBarry Smith Creates "balanced" ownership ranges after refinement, constrained by the need for the 84647c6ae99SBarry Smith fine grid boundaries to fall within one stencil width of the coarse partition. 84747c6ae99SBarry Smith 84847c6ae99SBarry Smith Uses a greedy algorithm to handle non-ideal layouts, could probably do something better. 84947c6ae99SBarry Smith */ 85094013140SBarry Smith static PetscErrorCode DMDARefineOwnershipRanges(DM da,PetscBool periodic,PetscInt stencil_width,PetscInt ratio,PetscInt m,const PetscInt lc[],PetscInt lf[]) 85147c6ae99SBarry Smith { 85247c6ae99SBarry Smith PetscInt i,totalc = 0,remaining,startc = 0,startf = 0; 85347c6ae99SBarry Smith PetscErrorCode ierr; 85447c6ae99SBarry Smith 85547c6ae99SBarry Smith PetscFunctionBegin; 856ce94432eSBarry Smith if (ratio < 1) SETERRQ1(PetscObjectComm((PetscObject)da),PETSC_ERR_USER,"Requested refinement ratio %D must be at least 1",ratio); 85747c6ae99SBarry Smith if (ratio == 1) { 85847c6ae99SBarry Smith ierr = PetscMemcpy(lf,lc,m*sizeof(lc[0]));CHKERRQ(ierr); 85947c6ae99SBarry Smith PetscFunctionReturn(0); 86047c6ae99SBarry Smith } 86147c6ae99SBarry Smith for (i=0; i<m; i++) totalc += lc[i]; 86247c6ae99SBarry Smith remaining = (!periodic) + ratio * (totalc - (!periodic)); 86347c6ae99SBarry Smith for (i=0; i<m; i++) { 86447c6ae99SBarry Smith PetscInt want = remaining/(m-i) + !!(remaining%(m-i)); 86547c6ae99SBarry Smith if (i == m-1) lf[i] = want; 86647c6ae99SBarry Smith else { 8677aca7175SJed Brown const PetscInt nextc = startc + lc[i]; 8687aca7175SJed Brown /* Move the first fine node of the next subdomain to the right until the coarse node on its left is within one 8697aca7175SJed Brown * coarse stencil width of the first coarse node in the next subdomain. */ 8707aca7175SJed Brown while ((startf+want)/ratio < nextc - stencil_width) want++; 8717aca7175SJed Brown /* Move the last fine node in the current subdomain to the left until the coarse node on its right is within one 8727aca7175SJed Brown * coarse stencil width of the last coarse node in the current subdomain. */ 8737aca7175SJed Brown while ((startf+want-1+ratio-1)/ratio > nextc-1+stencil_width) want--; 8747aca7175SJed Brown /* Make sure all constraints are satisfied */ 87530729d88SBarry Smith if (want < 0 || want > remaining || ((startf+want)/ratio < nextc - stencil_width) 876ce94432eSBarry Smith || ((startf+want-1+ratio-1)/ratio > nextc-1+stencil_width)) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_SIZ,"Could not find a compatible refined ownership range"); 87747c6ae99SBarry Smith } 87847c6ae99SBarry Smith lf[i] = want; 87947c6ae99SBarry Smith startc += lc[i]; 88047c6ae99SBarry Smith startf += lf[i]; 88147c6ae99SBarry Smith remaining -= lf[i]; 88247c6ae99SBarry Smith } 88347c6ae99SBarry Smith PetscFunctionReturn(0); 88447c6ae99SBarry Smith } 88547c6ae99SBarry Smith 8862be375d4SJed Brown /* 8872be375d4SJed Brown Creates "balanced" ownership ranges after coarsening, constrained by the need for the 8882be375d4SJed Brown fine grid boundaries to fall within one stencil width of the coarse partition. 8892be375d4SJed Brown 8902be375d4SJed Brown Uses a greedy algorithm to handle non-ideal layouts, could probably do something better. 8912be375d4SJed Brown */ 8922be375d4SJed Brown static PetscErrorCode DMDACoarsenOwnershipRanges(DM da,PetscBool periodic,PetscInt stencil_width,PetscInt ratio,PetscInt m,const PetscInt lf[],PetscInt lc[]) 8932be375d4SJed Brown { 8942be375d4SJed Brown PetscInt i,totalf,remaining,startc,startf; 8952be375d4SJed Brown PetscErrorCode ierr; 8962be375d4SJed Brown 8972be375d4SJed Brown PetscFunctionBegin; 898ce94432eSBarry Smith if (ratio < 1) SETERRQ1(PetscObjectComm((PetscObject)da),PETSC_ERR_USER,"Requested refinement ratio %D must be at least 1",ratio); 8992be375d4SJed Brown if (ratio == 1) { 9002be375d4SJed Brown ierr = PetscMemcpy(lc,lf,m*sizeof(lf[0]));CHKERRQ(ierr); 9012be375d4SJed Brown PetscFunctionReturn(0); 9022be375d4SJed Brown } 9032be375d4SJed Brown for (i=0,totalf=0; i<m; i++) totalf += lf[i]; 9042be375d4SJed Brown remaining = (!periodic) + (totalf - (!periodic)) / ratio; 9052be375d4SJed Brown for (i=0,startc=0,startf=0; i<m; i++) { 9062be375d4SJed Brown PetscInt want = remaining/(m-i) + !!(remaining%(m-i)); 9072be375d4SJed Brown if (i == m-1) lc[i] = want; 9082be375d4SJed Brown else { 9092be375d4SJed Brown const PetscInt nextf = startf+lf[i]; 9102be375d4SJed Brown /* Slide first coarse node of next subdomain to the left until the coarse node to the left of the first fine 9112be375d4SJed Brown * node is within one stencil width. */ 9122be375d4SJed Brown while (nextf/ratio < startc+want-stencil_width) want--; 9132be375d4SJed Brown /* Slide the last coarse node of the current subdomain to the right until the coarse node to the right of the last 9142be375d4SJed Brown * fine node is within one stencil width. */ 9152be375d4SJed Brown while ((nextf-1+ratio-1)/ratio > startc+want-1+stencil_width) want++; 9162be375d4SJed Brown if (want < 0 || want > remaining 917ce94432eSBarry Smith || (nextf/ratio < startc+want-stencil_width) || ((nextf-1+ratio-1)/ratio > startc+want-1+stencil_width)) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_SIZ,"Could not find a compatible coarsened ownership range"); 9182be375d4SJed Brown } 9192be375d4SJed Brown lc[i] = want; 9202be375d4SJed Brown startc += lc[i]; 9212be375d4SJed Brown startf += lf[i]; 9222be375d4SJed Brown remaining -= lc[i]; 9232be375d4SJed Brown } 9242be375d4SJed Brown PetscFunctionReturn(0); 9252be375d4SJed Brown } 9262be375d4SJed Brown 9277087cfbeSBarry Smith PetscErrorCode DMRefine_DA(DM da,MPI_Comm comm,DM *daref) 92847c6ae99SBarry Smith { 92947c6ae99SBarry Smith PetscErrorCode ierr; 930c73cfb54SMatthew G. Knepley PetscInt M,N,P,i,dim; 9319a42bb27SBarry Smith DM da2; 93247c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data,*dd2; 93347c6ae99SBarry Smith 93447c6ae99SBarry Smith PetscFunctionBegin; 935a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 93647c6ae99SBarry Smith PetscValidPointer(daref,3); 93747c6ae99SBarry Smith 938c73cfb54SMatthew G. Knepley ierr = DMGetDimension(da, &dim);CHKERRQ(ierr); 939bff4a2f0SMatthew G. Knepley if (dd->bx == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) { 94047c6ae99SBarry Smith M = dd->refine_x*dd->M; 94147c6ae99SBarry Smith } else { 94247c6ae99SBarry Smith M = 1 + dd->refine_x*(dd->M - 1); 94347c6ae99SBarry Smith } 944bff4a2f0SMatthew G. Knepley if (dd->by == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) { 945c73cfb54SMatthew G. Knepley if (dim > 1) { 94647c6ae99SBarry Smith N = dd->refine_y*dd->N; 94747c6ae99SBarry Smith } else { 9481860e6e9SBarry Smith N = 1; 9491860e6e9SBarry Smith } 9501860e6e9SBarry Smith } else { 95147c6ae99SBarry Smith N = 1 + dd->refine_y*(dd->N - 1); 95247c6ae99SBarry Smith } 953bff4a2f0SMatthew G. Knepley if (dd->bz == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) { 954c73cfb54SMatthew G. Knepley if (dim > 2) { 95547c6ae99SBarry Smith P = dd->refine_z*dd->P; 95647c6ae99SBarry Smith } else { 9571860e6e9SBarry Smith P = 1; 9581860e6e9SBarry Smith } 9591860e6e9SBarry Smith } else { 96047c6ae99SBarry Smith P = 1 + dd->refine_z*(dd->P - 1); 96147c6ae99SBarry Smith } 962ce94432eSBarry Smith ierr = DMDACreate(PetscObjectComm((PetscObject)da),&da2);CHKERRQ(ierr); 963397b6216SJed Brown ierr = DMSetOptionsPrefix(da2,((PetscObject)da)->prefix);CHKERRQ(ierr); 964c73cfb54SMatthew G. Knepley ierr = DMSetDimension(da2,dim);CHKERRQ(ierr); 965397b6216SJed Brown ierr = DMDASetSizes(da2,M,N,P);CHKERRQ(ierr); 966397b6216SJed Brown ierr = DMDASetNumProcs(da2,dd->m,dd->n,dd->p);CHKERRQ(ierr); 967397b6216SJed Brown ierr = DMDASetBoundaryType(da2,dd->bx,dd->by,dd->bz);CHKERRQ(ierr); 968397b6216SJed Brown ierr = DMDASetDof(da2,dd->w);CHKERRQ(ierr); 969397b6216SJed Brown ierr = DMDASetStencilType(da2,dd->stencil_type);CHKERRQ(ierr); 970397b6216SJed Brown ierr = DMDASetStencilWidth(da2,dd->s);CHKERRQ(ierr); 971c73cfb54SMatthew G. Knepley if (dim == 3) { 97247c6ae99SBarry Smith PetscInt *lx,*ly,*lz; 973dcca6d9dSJed Brown ierr = PetscMalloc3(dd->m,&lx,dd->n,&ly,dd->p,&lz);CHKERRQ(ierr); 974bff4a2f0SMatthew G. Knepley ierr = DMDARefineOwnershipRanges(da,(PetscBool)(dd->bx == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0),dd->s,dd->refine_x,dd->m,dd->lx,lx);CHKERRQ(ierr); 975bff4a2f0SMatthew G. Knepley ierr = DMDARefineOwnershipRanges(da,(PetscBool)(dd->by == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0),dd->s,dd->refine_y,dd->n,dd->ly,ly);CHKERRQ(ierr); 976bff4a2f0SMatthew G. Knepley ierr = DMDARefineOwnershipRanges(da,(PetscBool)(dd->bz == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0),dd->s,dd->refine_z,dd->p,dd->lz,lz);CHKERRQ(ierr); 977397b6216SJed Brown ierr = DMDASetOwnershipRanges(da2,lx,ly,lz);CHKERRQ(ierr); 97847c6ae99SBarry Smith ierr = PetscFree3(lx,ly,lz);CHKERRQ(ierr); 979c73cfb54SMatthew G. Knepley } else if (dim == 2) { 98047c6ae99SBarry Smith PetscInt *lx,*ly; 981dcca6d9dSJed Brown ierr = PetscMalloc2(dd->m,&lx,dd->n,&ly);CHKERRQ(ierr); 982bff4a2f0SMatthew G. Knepley ierr = DMDARefineOwnershipRanges(da,(PetscBool)(dd->bx == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0),dd->s,dd->refine_x,dd->m,dd->lx,lx);CHKERRQ(ierr); 983bff4a2f0SMatthew G. Knepley ierr = DMDARefineOwnershipRanges(da,(PetscBool)(dd->by == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0),dd->s,dd->refine_y,dd->n,dd->ly,ly);CHKERRQ(ierr); 9840298fd71SBarry Smith ierr = DMDASetOwnershipRanges(da2,lx,ly,NULL);CHKERRQ(ierr); 98547c6ae99SBarry Smith ierr = PetscFree2(lx,ly);CHKERRQ(ierr); 986c73cfb54SMatthew G. Knepley } else if (dim == 1) { 98747c6ae99SBarry Smith PetscInt *lx; 988785e854fSJed Brown ierr = PetscMalloc1(dd->m,&lx);CHKERRQ(ierr); 989bff4a2f0SMatthew G. Knepley ierr = DMDARefineOwnershipRanges(da,(PetscBool)(dd->bx == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0),dd->s,dd->refine_x,dd->m,dd->lx,lx);CHKERRQ(ierr); 9900298fd71SBarry Smith ierr = DMDASetOwnershipRanges(da2,lx,NULL,NULL);CHKERRQ(ierr); 99147c6ae99SBarry Smith ierr = PetscFree(lx);CHKERRQ(ierr); 99247c6ae99SBarry Smith } 99347c6ae99SBarry Smith dd2 = (DM_DA*)da2->data; 99447c6ae99SBarry Smith 99547c6ae99SBarry Smith /* allow overloaded (user replaced) operations to be inherited by refinement clones */ 99625296bd5SBarry Smith da2->ops->creatematrix = da->ops->creatematrix; 99725296bd5SBarry Smith /* da2->ops->createinterpolation = da->ops->createinterpolation; this causes problem with SNESVI */ 99847c6ae99SBarry Smith da2->ops->getcoloring = da->ops->getcoloring; 99947c6ae99SBarry Smith dd2->interptype = dd->interptype; 100047c6ae99SBarry Smith 100147c6ae99SBarry Smith /* copy fill information if given */ 100247c6ae99SBarry Smith if (dd->dfill) { 1003854ce69bSBarry Smith ierr = PetscMalloc1(dd->dfill[dd->w]+dd->w+1,&dd2->dfill);CHKERRQ(ierr); 100447c6ae99SBarry Smith ierr = PetscMemcpy(dd2->dfill,dd->dfill,(dd->dfill[dd->w]+dd->w+1)*sizeof(PetscInt));CHKERRQ(ierr); 100547c6ae99SBarry Smith } 100647c6ae99SBarry Smith if (dd->ofill) { 1007854ce69bSBarry Smith ierr = PetscMalloc1(dd->ofill[dd->w]+dd->w+1,&dd2->ofill);CHKERRQ(ierr); 100847c6ae99SBarry Smith ierr = PetscMemcpy(dd2->ofill,dd->ofill,(dd->ofill[dd->w]+dd->w+1)*sizeof(PetscInt));CHKERRQ(ierr); 100947c6ae99SBarry Smith } 101047c6ae99SBarry Smith /* copy the refine information */ 1011397b6216SJed Brown dd2->coarsen_x = dd2->refine_x = dd->refine_x; 1012397b6216SJed Brown dd2->coarsen_y = dd2->refine_y = dd->refine_y; 1013397b6216SJed Brown dd2->coarsen_z = dd2->refine_z = dd->refine_z; 101447c6ae99SBarry Smith 1015897f7067SBarry Smith if (dd->refine_z_hier) { 1016897f7067SBarry Smith if (da->levelup - da->leveldown + 1 > -1 && da->levelup - da->leveldown + 1 < dd->refine_z_hier_n) { 1017897f7067SBarry Smith dd2->refine_z = dd->refine_z_hier[da->levelup - da->leveldown + 1]; 1018897f7067SBarry Smith } 1019897f7067SBarry Smith if (da->levelup - da->leveldown > -1 && da->levelup - da->leveldown < dd->refine_z_hier_n) { 1020897f7067SBarry Smith dd2->coarsen_z = dd->refine_z_hier[da->levelup - da->leveldown]; 1021897f7067SBarry Smith } 1022897f7067SBarry Smith dd2->refine_z_hier_n = dd->refine_z_hier_n; 1023897f7067SBarry Smith ierr = PetscMalloc1(dd2->refine_z_hier_n,&dd2->refine_z_hier);CHKERRQ(ierr); 1024897f7067SBarry Smith ierr = PetscMemcpy(dd2->refine_z_hier,dd->refine_z_hier,dd2->refine_z_hier_n*sizeof(PetscInt));CHKERRQ(ierr); 1025897f7067SBarry Smith } 1026897f7067SBarry Smith if (dd->refine_y_hier) { 1027897f7067SBarry Smith if (da->levelup - da->leveldown + 1 > -1 && da->levelup - da->leveldown + 1 < dd->refine_y_hier_n) { 1028897f7067SBarry Smith dd2->refine_y = dd->refine_y_hier[da->levelup - da->leveldown + 1]; 1029897f7067SBarry Smith } 1030897f7067SBarry Smith if (da->levelup - da->leveldown > -1 && da->levelup - da->leveldown < dd->refine_y_hier_n) { 1031897f7067SBarry Smith dd2->coarsen_y = dd->refine_y_hier[da->levelup - da->leveldown]; 1032897f7067SBarry Smith } 1033897f7067SBarry Smith dd2->refine_y_hier_n = dd->refine_y_hier_n; 1034897f7067SBarry Smith ierr = PetscMalloc1(dd2->refine_y_hier_n,&dd2->refine_y_hier);CHKERRQ(ierr); 1035897f7067SBarry Smith ierr = PetscMemcpy(dd2->refine_y_hier,dd->refine_y_hier,dd2->refine_y_hier_n*sizeof(PetscInt));CHKERRQ(ierr); 1036897f7067SBarry Smith } 1037897f7067SBarry Smith if (dd->refine_x_hier) { 1038897f7067SBarry Smith if (da->levelup - da->leveldown + 1 > -1 && da->levelup - da->leveldown + 1 < dd->refine_x_hier_n) { 1039897f7067SBarry Smith dd2->refine_x = dd->refine_x_hier[da->levelup - da->leveldown + 1]; 1040897f7067SBarry Smith } 1041897f7067SBarry Smith if (da->levelup - da->leveldown > -1 && da->levelup - da->leveldown < dd->refine_x_hier_n) { 1042897f7067SBarry Smith dd2->coarsen_x = dd->refine_x_hier[da->levelup - da->leveldown]; 1043897f7067SBarry Smith } 1044897f7067SBarry Smith dd2->refine_x_hier_n = dd->refine_x_hier_n; 1045897f7067SBarry Smith ierr = PetscMalloc1(dd2->refine_x_hier_n,&dd2->refine_x_hier);CHKERRQ(ierr); 1046897f7067SBarry Smith ierr = PetscMemcpy(dd2->refine_x_hier,dd->refine_x_hier,dd2->refine_x_hier_n*sizeof(PetscInt));CHKERRQ(ierr); 1047897f7067SBarry Smith } 1048897f7067SBarry Smith 1049897f7067SBarry Smith 105047c6ae99SBarry Smith /* copy vector type information */ 1051c0dedaeaSBarry Smith ierr = DMSetVecType(da2,da->vectype);CHKERRQ(ierr); 1052ddcf8b74SDave May 1053efd51863SBarry Smith dd2->lf = dd->lf; 1054efd51863SBarry Smith dd2->lj = dd->lj; 1055efd51863SBarry Smith 10566e87535bSJed Brown da2->leveldown = da->leveldown; 10576e87535bSJed Brown da2->levelup = da->levelup + 1; 10588865f1eaSKarl Rupp 10596e87535bSJed Brown ierr = DMSetUp(da2);CHKERRQ(ierr); 10606e87535bSJed Brown 1061ddcf8b74SDave May /* interpolate coordinates if they are set on the coarse grid */ 10626636e97aSMatthew G Knepley if (da->coordinates) { 1063ddcf8b74SDave May DM cdaf,cdac; 1064ddcf8b74SDave May Vec coordsc,coordsf; 1065ddcf8b74SDave May Mat II; 1066ddcf8b74SDave May 10676636e97aSMatthew G Knepley ierr = DMGetCoordinateDM(da,&cdac);CHKERRQ(ierr); 10686636e97aSMatthew G Knepley ierr = DMGetCoordinates(da,&coordsc);CHKERRQ(ierr); 10696636e97aSMatthew G Knepley ierr = DMGetCoordinateDM(da2,&cdaf);CHKERRQ(ierr); 1070b61d3410SDave May /* force creation of the coordinate vector */ 1071b61d3410SDave May ierr = DMDASetUniformCoordinates(da2,0.0,1.0,0.0,1.0,0.0,1.0);CHKERRQ(ierr); 10726636e97aSMatthew G Knepley ierr = DMGetCoordinates(da2,&coordsf);CHKERRQ(ierr); 10730298fd71SBarry Smith ierr = DMCreateInterpolation(cdac,cdaf,&II,NULL);CHKERRQ(ierr); 1074ddcf8b74SDave May ierr = MatInterpolate(II,coordsc,coordsf);CHKERRQ(ierr); 1075fcfd50ebSBarry Smith ierr = MatDestroy(&II);CHKERRQ(ierr); 1076ddcf8b74SDave May } 1077397b6216SJed Brown 1078f3141302SJed Brown for (i=0; i<da->bs; i++) { 1079f3141302SJed Brown const char *fieldname; 1080f3141302SJed Brown ierr = DMDAGetFieldName(da,i,&fieldname);CHKERRQ(ierr); 1081f3141302SJed Brown ierr = DMDASetFieldName(da2,i,fieldname);CHKERRQ(ierr); 1082f3141302SJed Brown } 1083397b6216SJed Brown 108447c6ae99SBarry Smith *daref = da2; 108547c6ae99SBarry Smith PetscFunctionReturn(0); 108647c6ae99SBarry Smith } 108747c6ae99SBarry Smith 1088397b6216SJed Brown 10897087cfbeSBarry Smith PetscErrorCode DMCoarsen_DA(DM da, MPI_Comm comm,DM *daref) 109047c6ae99SBarry Smith { 109147c6ae99SBarry Smith PetscErrorCode ierr; 1092c73cfb54SMatthew G. Knepley PetscInt M,N,P,i,dim; 10939a42bb27SBarry Smith DM da2; 109447c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data,*dd2; 109547c6ae99SBarry Smith 109647c6ae99SBarry Smith PetscFunctionBegin; 1097a9a02de4SBarry Smith PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA); 109847c6ae99SBarry Smith PetscValidPointer(daref,3); 109947c6ae99SBarry Smith 1100c73cfb54SMatthew G. Knepley ierr = DMGetDimension(da, &dim);CHKERRQ(ierr); 1101bff4a2f0SMatthew G. Knepley if (dd->bx == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) { 1102397b6216SJed Brown M = dd->M / dd->coarsen_x; 110347c6ae99SBarry Smith } else { 1104397b6216SJed Brown M = 1 + (dd->M - 1) / dd->coarsen_x; 110547c6ae99SBarry Smith } 1106bff4a2f0SMatthew G. Knepley if (dd->by == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) { 1107c73cfb54SMatthew G. Knepley if (dim > 1) { 1108397b6216SJed Brown N = dd->N / dd->coarsen_y; 110947c6ae99SBarry Smith } else { 11101860e6e9SBarry Smith N = 1; 11111860e6e9SBarry Smith } 11121860e6e9SBarry Smith } else { 1113397b6216SJed Brown N = 1 + (dd->N - 1) / dd->coarsen_y; 111447c6ae99SBarry Smith } 1115bff4a2f0SMatthew G. Knepley if (dd->bz == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) { 1116c73cfb54SMatthew G. Knepley if (dim > 2) { 1117397b6216SJed Brown P = dd->P / dd->coarsen_z; 111847c6ae99SBarry Smith } else { 11191860e6e9SBarry Smith P = 1; 11201860e6e9SBarry Smith } 11211860e6e9SBarry Smith } else { 1122397b6216SJed Brown P = 1 + (dd->P - 1) / dd->coarsen_z; 112347c6ae99SBarry Smith } 1124ce94432eSBarry Smith ierr = DMDACreate(PetscObjectComm((PetscObject)da),&da2);CHKERRQ(ierr); 1125397b6216SJed Brown ierr = DMSetOptionsPrefix(da2,((PetscObject)da)->prefix);CHKERRQ(ierr); 1126c73cfb54SMatthew G. Knepley ierr = DMSetDimension(da2,dim);CHKERRQ(ierr); 1127397b6216SJed Brown ierr = DMDASetSizes(da2,M,N,P);CHKERRQ(ierr); 1128397b6216SJed Brown ierr = DMDASetNumProcs(da2,dd->m,dd->n,dd->p);CHKERRQ(ierr); 1129397b6216SJed Brown ierr = DMDASetBoundaryType(da2,dd->bx,dd->by,dd->bz);CHKERRQ(ierr); 1130397b6216SJed Brown ierr = DMDASetDof(da2,dd->w);CHKERRQ(ierr); 1131397b6216SJed Brown ierr = DMDASetStencilType(da2,dd->stencil_type);CHKERRQ(ierr); 1132397b6216SJed Brown ierr = DMDASetStencilWidth(da2,dd->s);CHKERRQ(ierr); 1133c73cfb54SMatthew G. Knepley if (dim == 3) { 11342be375d4SJed Brown PetscInt *lx,*ly,*lz; 1135dcca6d9dSJed Brown ierr = PetscMalloc3(dd->m,&lx,dd->n,&ly,dd->p,&lz);CHKERRQ(ierr); 1136bff4a2f0SMatthew G. Knepley ierr = DMDACoarsenOwnershipRanges(da,(PetscBool)(dd->bx == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0),dd->s,dd->coarsen_x,dd->m,dd->lx,lx);CHKERRQ(ierr); 1137bff4a2f0SMatthew G. Knepley ierr = DMDACoarsenOwnershipRanges(da,(PetscBool)(dd->by == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0),dd->s,dd->coarsen_y,dd->n,dd->ly,ly);CHKERRQ(ierr); 1138bff4a2f0SMatthew G. Knepley ierr = DMDACoarsenOwnershipRanges(da,(PetscBool)(dd->bz == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0),dd->s,dd->coarsen_z,dd->p,dd->lz,lz);CHKERRQ(ierr); 1139397b6216SJed Brown ierr = DMDASetOwnershipRanges(da2,lx,ly,lz);CHKERRQ(ierr); 11402be375d4SJed Brown ierr = PetscFree3(lx,ly,lz);CHKERRQ(ierr); 1141c73cfb54SMatthew G. Knepley } else if (dim == 2) { 11422be375d4SJed Brown PetscInt *lx,*ly; 1143dcca6d9dSJed Brown ierr = PetscMalloc2(dd->m,&lx,dd->n,&ly);CHKERRQ(ierr); 1144bff4a2f0SMatthew G. Knepley ierr = DMDACoarsenOwnershipRanges(da,(PetscBool)(dd->bx == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0),dd->s,dd->coarsen_x,dd->m,dd->lx,lx);CHKERRQ(ierr); 1145bff4a2f0SMatthew G. Knepley ierr = DMDACoarsenOwnershipRanges(da,(PetscBool)(dd->by == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0),dd->s,dd->coarsen_y,dd->n,dd->ly,ly);CHKERRQ(ierr); 11460298fd71SBarry Smith ierr = DMDASetOwnershipRanges(da2,lx,ly,NULL);CHKERRQ(ierr); 11472be375d4SJed Brown ierr = PetscFree2(lx,ly);CHKERRQ(ierr); 1148c73cfb54SMatthew G. Knepley } else if (dim == 1) { 11492be375d4SJed Brown PetscInt *lx; 1150785e854fSJed Brown ierr = PetscMalloc1(dd->m,&lx);CHKERRQ(ierr); 1151bff4a2f0SMatthew G. Knepley ierr = DMDACoarsenOwnershipRanges(da,(PetscBool)(dd->bx == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0),dd->s,dd->coarsen_x,dd->m,dd->lx,lx);CHKERRQ(ierr); 11520298fd71SBarry Smith ierr = DMDASetOwnershipRanges(da2,lx,NULL,NULL);CHKERRQ(ierr); 11532be375d4SJed Brown ierr = PetscFree(lx);CHKERRQ(ierr); 115447c6ae99SBarry Smith } 115547c6ae99SBarry Smith dd2 = (DM_DA*)da2->data; 115647c6ae99SBarry Smith 11574dcab191SBarry Smith /* allow overloaded (user replaced) operations to be inherited by refinement clones; why are only some inherited and not all? */ 115825296bd5SBarry Smith /* da2->ops->createinterpolation = da->ops->createinterpolation; copying this one causes trouble for DMSetVI */ 115925296bd5SBarry Smith da2->ops->creatematrix = da->ops->creatematrix; 116047c6ae99SBarry Smith da2->ops->getcoloring = da->ops->getcoloring; 116147c6ae99SBarry Smith dd2->interptype = dd->interptype; 116247c6ae99SBarry Smith 116347c6ae99SBarry Smith /* copy fill information if given */ 116447c6ae99SBarry Smith if (dd->dfill) { 1165854ce69bSBarry Smith ierr = PetscMalloc1(dd->dfill[dd->w]+dd->w+1,&dd2->dfill);CHKERRQ(ierr); 116647c6ae99SBarry Smith ierr = PetscMemcpy(dd2->dfill,dd->dfill,(dd->dfill[dd->w]+dd->w+1)*sizeof(PetscInt));CHKERRQ(ierr); 116747c6ae99SBarry Smith } 116847c6ae99SBarry Smith if (dd->ofill) { 1169854ce69bSBarry Smith ierr = PetscMalloc1(dd->ofill[dd->w]+dd->w+1,&dd2->ofill);CHKERRQ(ierr); 117047c6ae99SBarry Smith ierr = PetscMemcpy(dd2->ofill,dd->ofill,(dd->ofill[dd->w]+dd->w+1)*sizeof(PetscInt));CHKERRQ(ierr); 117147c6ae99SBarry Smith } 117247c6ae99SBarry Smith /* copy the refine information */ 1173397b6216SJed Brown dd2->coarsen_x = dd2->refine_x = dd->coarsen_x; 1174397b6216SJed Brown dd2->coarsen_y = dd2->refine_y = dd->coarsen_y; 1175397b6216SJed Brown dd2->coarsen_z = dd2->refine_z = dd->coarsen_z; 117647c6ae99SBarry Smith 1177897f7067SBarry Smith if (dd->refine_z_hier) { 1178897f7067SBarry Smith if (da->levelup - da->leveldown -1 > -1 && da->levelup - da->leveldown - 1< dd->refine_z_hier_n) { 1179897f7067SBarry Smith dd2->refine_z = dd->refine_z_hier[da->levelup - da->leveldown - 1]; 1180897f7067SBarry Smith } 1181897f7067SBarry Smith if (da->levelup - da->leveldown - 2 > -1 && da->levelup - da->leveldown - 2 < dd->refine_z_hier_n) { 1182897f7067SBarry Smith dd2->coarsen_z = dd->refine_z_hier[da->levelup - da->leveldown - 2]; 1183897f7067SBarry Smith } 1184897f7067SBarry Smith dd2->refine_z_hier_n = dd->refine_z_hier_n; 1185897f7067SBarry Smith ierr = PetscMalloc1(dd2->refine_z_hier_n,&dd2->refine_z_hier);CHKERRQ(ierr); 1186897f7067SBarry Smith ierr = PetscMemcpy(dd2->refine_z_hier,dd->refine_z_hier,dd2->refine_z_hier_n*sizeof(PetscInt));CHKERRQ(ierr); 1187897f7067SBarry Smith } 1188897f7067SBarry Smith if (dd->refine_y_hier) { 1189897f7067SBarry Smith if (da->levelup - da->leveldown - 1 > -1 && da->levelup - da->leveldown - 1< dd->refine_y_hier_n) { 1190897f7067SBarry Smith dd2->refine_y = dd->refine_y_hier[da->levelup - da->leveldown - 1]; 1191897f7067SBarry Smith } 1192897f7067SBarry Smith if (da->levelup - da->leveldown - 2 > -1 && da->levelup - da->leveldown - 2 < dd->refine_y_hier_n) { 1193897f7067SBarry Smith dd2->coarsen_y = dd->refine_y_hier[da->levelup - da->leveldown - 2]; 1194897f7067SBarry Smith } 1195897f7067SBarry Smith dd2->refine_y_hier_n = dd->refine_y_hier_n; 1196897f7067SBarry Smith ierr = PetscMalloc1(dd2->refine_y_hier_n,&dd2->refine_y_hier);CHKERRQ(ierr); 1197897f7067SBarry Smith ierr = PetscMemcpy(dd2->refine_y_hier,dd->refine_y_hier,dd2->refine_y_hier_n*sizeof(PetscInt));CHKERRQ(ierr); 1198897f7067SBarry Smith } 1199897f7067SBarry Smith if (dd->refine_x_hier) { 1200897f7067SBarry Smith if (da->levelup - da->leveldown - 1 > -1 && da->levelup - da->leveldown - 1 < dd->refine_x_hier_n) { 1201897f7067SBarry Smith dd2->refine_x = dd->refine_x_hier[da->levelup - da->leveldown - 1]; 1202897f7067SBarry Smith } 1203897f7067SBarry Smith if (da->levelup - da->leveldown - 2 > -1 && da->levelup - da->leveldown - 2 < dd->refine_x_hier_n) { 1204897f7067SBarry Smith dd2->coarsen_x = dd->refine_x_hier[da->levelup - da->leveldown - 2]; 1205897f7067SBarry Smith } 1206897f7067SBarry Smith dd2->refine_x_hier_n = dd->refine_x_hier_n; 1207897f7067SBarry Smith ierr = PetscMalloc1(dd2->refine_x_hier_n,&dd2->refine_x_hier);CHKERRQ(ierr); 1208897f7067SBarry Smith ierr = PetscMemcpy(dd2->refine_x_hier,dd->refine_x_hier,dd2->refine_x_hier_n*sizeof(PetscInt));CHKERRQ(ierr); 1209897f7067SBarry Smith } 1210897f7067SBarry Smith 121147c6ae99SBarry Smith /* copy vector type information */ 1212c0dedaeaSBarry Smith ierr = DMSetVecType(da2,da->vectype);CHKERRQ(ierr); 121347c6ae99SBarry Smith 1214644e2e5bSBarry Smith dd2->lf = dd->lf; 1215644e2e5bSBarry Smith dd2->lj = dd->lj; 1216644e2e5bSBarry Smith 12176e87535bSJed Brown da2->leveldown = da->leveldown + 1; 12186e87535bSJed Brown da2->levelup = da->levelup; 12198865f1eaSKarl Rupp 12206e87535bSJed Brown ierr = DMSetUp(da2);CHKERRQ(ierr); 12216e87535bSJed Brown 1222ddcf8b74SDave May /* inject coordinates if they are set on the fine grid */ 12236636e97aSMatthew G Knepley if (da->coordinates) { 1224ddcf8b74SDave May DM cdaf,cdac; 1225ddcf8b74SDave May Vec coordsc,coordsf; 12266dbf9973SLawrence Mitchell Mat inject; 12276dbf9973SLawrence Mitchell VecScatter vscat; 1228ddcf8b74SDave May 12296636e97aSMatthew G Knepley ierr = DMGetCoordinateDM(da,&cdaf);CHKERRQ(ierr); 12306636e97aSMatthew G Knepley ierr = DMGetCoordinates(da,&coordsf);CHKERRQ(ierr); 12316636e97aSMatthew G Knepley ierr = DMGetCoordinateDM(da2,&cdac);CHKERRQ(ierr); 1232b61d3410SDave May /* force creation of the coordinate vector */ 1233b61d3410SDave May ierr = DMDASetUniformCoordinates(da2,0.0,1.0,0.0,1.0,0.0,1.0);CHKERRQ(ierr); 12346636e97aSMatthew G Knepley ierr = DMGetCoordinates(da2,&coordsc);CHKERRQ(ierr); 1235ddcf8b74SDave May 1236e727c939SJed Brown ierr = DMCreateInjection(cdac,cdaf,&inject);CHKERRQ(ierr); 12376dbf9973SLawrence Mitchell ierr = MatScatterGetVecScatter(inject,&vscat);CHKERRQ(ierr); 12386dbf9973SLawrence Mitchell ierr = VecScatterBegin(vscat,coordsf,coordsc,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12396dbf9973SLawrence Mitchell ierr = VecScatterEnd(vscat,coordsf,coordsc,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12406dbf9973SLawrence Mitchell ierr = MatDestroy(&inject);CHKERRQ(ierr); 1241ddcf8b74SDave May } 1242f98405f7SJed Brown 1243f98405f7SJed Brown for (i=0; i<da->bs; i++) { 1244f98405f7SJed Brown const char *fieldname; 1245f98405f7SJed Brown ierr = DMDAGetFieldName(da,i,&fieldname);CHKERRQ(ierr); 1246f98405f7SJed Brown ierr = DMDASetFieldName(da2,i,fieldname);CHKERRQ(ierr); 1247f98405f7SJed Brown } 1248f98405f7SJed Brown 124947c6ae99SBarry Smith *daref = da2; 125047c6ae99SBarry Smith PetscFunctionReturn(0); 125147c6ae99SBarry Smith } 125247c6ae99SBarry Smith 12537087cfbeSBarry Smith PetscErrorCode DMRefineHierarchy_DA(DM da,PetscInt nlevels,DM daf[]) 125447c6ae99SBarry Smith { 125547c6ae99SBarry Smith PetscErrorCode ierr; 125647c6ae99SBarry Smith PetscInt i,n,*refx,*refy,*refz; 125747c6ae99SBarry Smith 125847c6ae99SBarry Smith PetscFunctionBegin; 125947c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 1260ce94432eSBarry Smith if (nlevels < 0) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative"); 126147c6ae99SBarry Smith if (nlevels == 0) PetscFunctionReturn(0); 126247c6ae99SBarry Smith PetscValidPointer(daf,3); 126347c6ae99SBarry Smith 1264aa219208SBarry Smith /* Get refinement factors, defaults taken from the coarse DMDA */ 1265dcca6d9dSJed Brown ierr = PetscMalloc3(nlevels,&refx,nlevels,&refy,nlevels,&refz);CHKERRQ(ierr); 126647c6ae99SBarry Smith for (i=0; i<nlevels; i++) { 1267aa219208SBarry Smith ierr = DMDAGetRefinementFactor(da,&refx[i],&refy[i],&refz[i]);CHKERRQ(ierr); 126847c6ae99SBarry Smith } 126947c6ae99SBarry Smith n = nlevels; 1270c5929fdfSBarry Smith ierr = PetscOptionsGetIntArray(((PetscObject)da)->options,((PetscObject)da)->prefix,"-da_refine_hierarchy_x",refx,&n,NULL);CHKERRQ(ierr); 127147c6ae99SBarry Smith n = nlevels; 1272c5929fdfSBarry Smith ierr = PetscOptionsGetIntArray(((PetscObject)da)->options,((PetscObject)da)->prefix,"-da_refine_hierarchy_y",refy,&n,NULL);CHKERRQ(ierr); 127347c6ae99SBarry Smith n = nlevels; 1274c5929fdfSBarry Smith ierr = PetscOptionsGetIntArray(((PetscObject)da)->options,((PetscObject)da)->prefix,"-da_refine_hierarchy_z",refz,&n,NULL);CHKERRQ(ierr); 127547c6ae99SBarry Smith 1276aa219208SBarry Smith ierr = DMDASetRefinementFactor(da,refx[0],refy[0],refz[0]);CHKERRQ(ierr); 1277ce94432eSBarry Smith ierr = DMRefine(da,PetscObjectComm((PetscObject)da),&daf[0]);CHKERRQ(ierr); 127847c6ae99SBarry Smith for (i=1; i<nlevels; i++) { 1279aa219208SBarry Smith ierr = DMDASetRefinementFactor(daf[i-1],refx[i],refy[i],refz[i]);CHKERRQ(ierr); 1280ce94432eSBarry Smith ierr = DMRefine(daf[i-1],PetscObjectComm((PetscObject)da),&daf[i]);CHKERRQ(ierr); 128147c6ae99SBarry Smith } 128247c6ae99SBarry Smith ierr = PetscFree3(refx,refy,refz);CHKERRQ(ierr); 128347c6ae99SBarry Smith PetscFunctionReturn(0); 128447c6ae99SBarry Smith } 128547c6ae99SBarry Smith 12867087cfbeSBarry Smith PetscErrorCode DMCoarsenHierarchy_DA(DM da,PetscInt nlevels,DM dac[]) 128747c6ae99SBarry Smith { 128847c6ae99SBarry Smith PetscErrorCode ierr; 128947c6ae99SBarry Smith PetscInt i; 129047c6ae99SBarry Smith 129147c6ae99SBarry Smith PetscFunctionBegin; 129247c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 1293ce94432eSBarry Smith if (nlevels < 0) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative"); 129447c6ae99SBarry Smith if (nlevels == 0) PetscFunctionReturn(0); 129547c6ae99SBarry Smith PetscValidPointer(dac,3); 1296ce94432eSBarry Smith ierr = DMCoarsen(da,PetscObjectComm((PetscObject)da),&dac[0]);CHKERRQ(ierr); 129747c6ae99SBarry Smith for (i=1; i<nlevels; i++) { 1298ce94432eSBarry Smith ierr = DMCoarsen(dac[i-1],PetscObjectComm((PetscObject)da),&dac[i]);CHKERRQ(ierr); 129947c6ae99SBarry Smith } 130047c6ae99SBarry Smith PetscFunctionReturn(0); 130147c6ae99SBarry Smith } 130262197512SBarry Smith 130362197512SBarry Smith #include <petscgll.h> 130462197512SBarry Smith 130562197512SBarry Smith PetscErrorCode DMDASetGLLCoordinates_1d(DM dm,PetscGLL *gll) 130662197512SBarry Smith { 130762197512SBarry Smith PetscErrorCode ierr; 130862197512SBarry Smith PetscInt i,j,n = gll->n,xs,xn,q; 130962197512SBarry Smith PetscScalar *xx; 131062197512SBarry Smith PetscReal h; 131162197512SBarry Smith Vec x; 131262197512SBarry Smith DM_DA *da = (DM_DA*)dm->data; 131362197512SBarry Smith 131462197512SBarry Smith PetscFunctionBegin; 131562197512SBarry Smith if (da->bx != DM_BOUNDARY_PERIODIC) { 131662197512SBarry Smith ierr = DMDAGetInfo(dm,NULL,&q,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);CHKERRQ(ierr); 131762197512SBarry Smith q = (q-1)/(n-1); /* number of spectral elements */ 131862197512SBarry Smith h = 2.0/q; 131962197512SBarry Smith ierr = DMDAGetCorners(dm,&xs,NULL,NULL,&xn,NULL,NULL);CHKERRQ(ierr); 132062197512SBarry Smith xs = xs/(n-1); 132162197512SBarry Smith xn = xn/(n-1); 132262197512SBarry Smith ierr = DMDASetUniformCoordinates(dm,-1.,1.,0.,0.,0.,0.);CHKERRQ(ierr); 132362197512SBarry Smith ierr = DMGetCoordinates(dm,&x);CHKERRQ(ierr); 132462197512SBarry Smith ierr = DMDAVecGetArray(dm,x,&xx);CHKERRQ(ierr); 132562197512SBarry Smith 132662197512SBarry Smith /* loop over local spectral elements */ 132762197512SBarry Smith for (j=xs; j<xs+xn; j++) { 132862197512SBarry Smith /* 132962197512SBarry Smith Except for the first process, each process starts on the second GLL point of the first element on that process 133062197512SBarry Smith */ 133162197512SBarry Smith for (i= (j == xs && xs > 0)? 1 : 0; i<n; i++) { 133262197512SBarry Smith xx[j*(n-1) + i] = -1.0 + h*j + h*(gll->nodes[i]+1.0)/2.; 133362197512SBarry Smith } 133462197512SBarry Smith } 133562197512SBarry Smith ierr = DMDAVecRestoreArray(dm,x,&xx);CHKERRQ(ierr); 133662197512SBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Not yet implemented for periodic"); 133762197512SBarry Smith PetscFunctionReturn(0); 133862197512SBarry Smith } 133962197512SBarry Smith 13401fd49c25SBarry Smith /*@ 134162197512SBarry Smith 134262197512SBarry Smith DMDASetGLLCoordinates - Sets the global coordinates from -1 to 1 to the GLL points of as many GLL elements that fit the number of grid points 134362197512SBarry Smith 134462197512SBarry Smith Collective on DM 134562197512SBarry Smith 134662197512SBarry Smith Input Parameters: 134762197512SBarry Smith + da - the DMDA object 134862197512SBarry Smith - gll - the GLL object 134962197512SBarry Smith 135095452b02SPatrick Sanan Notes: 135195452b02SPatrick Sanan the parallel decomposition of grid points must correspond to the degree of the GLL. That is, the number of grid points 135262197512SBarry Smith on each process much be divisible by the number of GLL elements needed per process. This depends on whether the DM is 135362197512SBarry Smith periodic or not. 135462197512SBarry Smith 1355edc382c3SSatish Balay Level: advanced 1356edc382c3SSatish Balay 135762197512SBarry Smith .seealso: DMDACreate(), PetscGLLCreate(), DMGetCoordinates() 135862197512SBarry Smith @*/ 135962197512SBarry Smith PetscErrorCode DMDASetGLLCoordinates(DM da,PetscGLL *gll) 136062197512SBarry Smith { 136162197512SBarry Smith PetscErrorCode ierr; 136262197512SBarry Smith 136362197512SBarry Smith PetscFunctionBegin; 136462197512SBarry Smith if (da->dim == 1) { 136562197512SBarry Smith ierr = DMDASetGLLCoordinates_1d(da,gll);CHKERRQ(ierr); 136662197512SBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Not yet implemented for 2 or 3d"); 136762197512SBarry Smith PetscFunctionReturn(0); 136862197512SBarry Smith } 13697c3cd84eSPatrick Sanan 13707c3cd84eSPatrick Sanan PETSC_INTERN PetscErrorCode DMGetCompatibility_DA(DM da1,DM dm2,PetscBool *compatible,PetscBool *set) 13717c3cd84eSPatrick Sanan { 13727c3cd84eSPatrick Sanan PetscErrorCode ierr; 13737c3cd84eSPatrick Sanan DM_DA *dd1 = (DM_DA*)da1->data,*dd2; 13747c3cd84eSPatrick Sanan DM da2; 13757c3cd84eSPatrick Sanan DMType dmtype2; 13767c3cd84eSPatrick Sanan PetscBool isda,compatibleLocal; 13777c3cd84eSPatrick Sanan PetscInt i; 13787c3cd84eSPatrick Sanan 13797c3cd84eSPatrick Sanan PetscFunctionBegin; 13807c3cd84eSPatrick Sanan if (!da1->setupcalled) SETERRQ(PetscObjectComm((PetscObject)da1),PETSC_ERR_ARG_WRONGSTATE,"DMSetUp() must be called on first DM before DMGetCompatibility()"); 13817c3cd84eSPatrick Sanan ierr = DMGetType(dm2,&dmtype2);CHKERRQ(ierr); 13827c3cd84eSPatrick Sanan ierr = PetscStrcmp(dmtype2,DMDA,&isda);CHKERRQ(ierr); 13837c3cd84eSPatrick Sanan if (isda) { 13847c3cd84eSPatrick Sanan da2 = dm2; 13857c3cd84eSPatrick Sanan dd2 = (DM_DA*)da2->data; 13867c3cd84eSPatrick Sanan if (!da2->setupcalled) SETERRQ(PetscObjectComm((PetscObject)da2),PETSC_ERR_ARG_WRONGSTATE,"DMSetUp() must be called on second DM before DMGetCompatibility()"); 1387110623a0SKarl Rupp compatibleLocal = (PetscBool)(da1->dim == da2->dim); 1388c790a739SKarl Rupp if (compatibleLocal) compatibleLocal = (PetscBool)(compatibleLocal && (dd1->s == dd2->s)); /* Stencil width */ 1389110623a0SKarl Rupp /* Global size ranks Boundary type */ 1390c790a739SKarl Rupp if (compatibleLocal) compatibleLocal = (PetscBool)(compatibleLocal && (dd1->M == dd2->M) && (dd1->m == dd2->m) && (dd1->bx == dd2->bx)); 1391c790a739SKarl Rupp if (compatibleLocal && da1->dim > 1) compatibleLocal = (PetscBool)(compatibleLocal && (dd1->N == dd2->N) && (dd1->n == dd2->n) && (dd1->by == dd2->by)); 1392c790a739SKarl Rupp if (compatibleLocal && da1->dim > 2) compatibleLocal = (PetscBool)(compatibleLocal && (dd1->P == dd2->P) && (dd1->p == dd2->p) && (dd1->bz == dd2->bz)); 13937c3cd84eSPatrick Sanan if (compatibleLocal) { 13947c3cd84eSPatrick Sanan for (i=0; i<dd1->m; ++i) { 1395c790a739SKarl Rupp compatibleLocal = (PetscBool)(compatibleLocal && (dd1->lx[i] == dd2->lx[i])); /* Local size */ 13967c3cd84eSPatrick Sanan } 13977c3cd84eSPatrick Sanan } 13987c3cd84eSPatrick Sanan if (compatibleLocal && da1->dim > 1) { 13997c3cd84eSPatrick Sanan for (i=0; i<dd1->n; ++i) { 1400c790a739SKarl Rupp compatibleLocal = (PetscBool)(compatibleLocal && (dd1->ly[i] == dd2->ly[i])); 14017c3cd84eSPatrick Sanan } 14027c3cd84eSPatrick Sanan } 14037c3cd84eSPatrick Sanan if (compatibleLocal && da1->dim > 2) { 14047c3cd84eSPatrick Sanan for (i=0; i<dd1->p; ++i) { 1405c790a739SKarl Rupp compatibleLocal = (PetscBool)(compatibleLocal && (dd1->lz[i] == dd2->lz[i])); 14067c3cd84eSPatrick Sanan } 14077c3cd84eSPatrick Sanan } 14087c3cd84eSPatrick Sanan *compatible = compatibleLocal; 14097c3cd84eSPatrick Sanan *set = PETSC_TRUE; 14107c3cd84eSPatrick Sanan } else { 14117c3cd84eSPatrick Sanan /* Decline to determine compatibility with other DM types */ 14127c3cd84eSPatrick Sanan *set = PETSC_FALSE; 14137c3cd84eSPatrick Sanan } 14147c3cd84eSPatrick Sanan PetscFunctionReturn(0); 14157c3cd84eSPatrick Sanan } 1416