1af0996ceSBarry Smith #include <petsc/private/dmdaimpl.h> /*I "petscdmda.h" I*/ 247c6ae99SBarry Smith 347c6ae99SBarry Smith /*@ 4aa219208SBarry Smith DMDASetSizes - Sets the global sizes 547c6ae99SBarry Smith 6aa219208SBarry Smith Logically Collective on DMDA 747c6ae99SBarry Smith 847c6ae99SBarry Smith Input Parameters: 9aa219208SBarry Smith + da - the DMDA 1047c6ae99SBarry Smith . M - the global X size (or PETSC_DECIDE) 1147c6ae99SBarry Smith . N - the global Y size (or PETSC_DECIDE) 1247c6ae99SBarry Smith - P - the global Z size (or PETSC_DECIDE) 1347c6ae99SBarry Smith 1447c6ae99SBarry Smith Level: intermediate 1547c6ae99SBarry Smith 16aa219208SBarry Smith .seealso: DMDAGetSize(), PetscSplitOwnership() 1747c6ae99SBarry Smith @*/ 187087cfbeSBarry Smith PetscErrorCode DMDASetSizes(DM da, PetscInt M, PetscInt N, PetscInt P) 1947c6ae99SBarry Smith { 2047c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 2147c6ae99SBarry Smith 2247c6ae99SBarry Smith PetscFunctionBegin; 2347c6ae99SBarry Smith PetscValidHeaderSpecific(da, DM_CLASSID, 1); 2447c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da,M,2); 2547c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da,N,3); 2647c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da,P,4); 27ce94432eSBarry Smith if (da->setupcalled) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONGSTATE,"This function must be called before DMSetUp()"); 2847c6ae99SBarry Smith 2947c6ae99SBarry Smith dd->M = M; 3047c6ae99SBarry Smith dd->N = N; 3147c6ae99SBarry Smith dd->P = P; 3247c6ae99SBarry Smith PetscFunctionReturn(0); 3347c6ae99SBarry Smith } 3447c6ae99SBarry Smith 3547c6ae99SBarry Smith /*@ 36aa219208SBarry Smith DMDASetNumProcs - Sets the number of processes in each dimension 3747c6ae99SBarry Smith 38aa219208SBarry Smith Logically Collective on DMDA 3947c6ae99SBarry Smith 4047c6ae99SBarry Smith Input Parameters: 41aa219208SBarry Smith + da - the DMDA 4247c6ae99SBarry Smith . m - the number of X procs (or PETSC_DECIDE) 4347c6ae99SBarry Smith . n - the number of Y procs (or PETSC_DECIDE) 4447c6ae99SBarry Smith - p - the number of Z procs (or PETSC_DECIDE) 4547c6ae99SBarry Smith 4647c6ae99SBarry Smith Level: intermediate 4747c6ae99SBarry Smith 48aa219208SBarry Smith .seealso: DMDASetSizes(), DMDAGetSize(), PetscSplitOwnership() 4947c6ae99SBarry Smith @*/ 507087cfbeSBarry Smith PetscErrorCode DMDASetNumProcs(DM da, PetscInt m, PetscInt n, PetscInt p) 5147c6ae99SBarry Smith { 5247c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 53e3f3e4b6SBarry Smith PetscErrorCode ierr; 5447c6ae99SBarry Smith 5547c6ae99SBarry Smith PetscFunctionBegin; 5647c6ae99SBarry Smith PetscValidHeaderSpecific(da, DM_CLASSID, 1); 5747c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da,m,2); 5847c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da,n,3); 5947c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da,p,4); 60ce94432eSBarry Smith if (da->setupcalled) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONGSTATE,"This function must be called before DMSetUp()"); 6147c6ae99SBarry Smith dd->m = m; 6247c6ae99SBarry Smith dd->n = n; 6347c6ae99SBarry Smith dd->p = p; 64c73cfb54SMatthew G. Knepley if (da->dim == 2) { 65d3be247eSBarry Smith PetscMPIInt size; 66d3be247eSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)da),&size);CHKERRQ(ierr); 67e3f3e4b6SBarry Smith if ((dd->m > 0) && (dd->n < 0)) { 68e3f3e4b6SBarry Smith dd->n = size/dd->m; 69ce94432eSBarry 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); 70e3f3e4b6SBarry Smith } 71e3f3e4b6SBarry Smith if ((dd->n > 0) && (dd->m < 0)) { 72e3f3e4b6SBarry Smith dd->m = size/dd->n; 73ce94432eSBarry 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); 74e3f3e4b6SBarry Smith } 75e3f3e4b6SBarry Smith } 7647c6ae99SBarry Smith PetscFunctionReturn(0); 7747c6ae99SBarry Smith } 7847c6ae99SBarry Smith 7947c6ae99SBarry Smith /*@ 801321219cSEthan Coon DMDASetBoundaryType - Sets the type of ghost nodes on domain boundaries. 8147c6ae99SBarry Smith 8247c6ae99SBarry Smith Not collective 8347c6ae99SBarry Smith 8447c6ae99SBarry Smith Input Parameter: 85aa219208SBarry Smith + da - The DMDA 86bff4a2f0SMatthew G. Knepley - bx,by,bz - One of DM_BOUNDARY_NONE, DM_BOUNDARY_GHOSTED, DM_BOUNDARY_PERIODIC 8747c6ae99SBarry Smith 8847c6ae99SBarry Smith Level: intermediate 8947c6ae99SBarry Smith 9047c6ae99SBarry Smith .keywords: distributed array, periodicity 91bff4a2f0SMatthew G. Knepley .seealso: DMDACreate(), DMDestroy(), DMDA, DMBoundaryType 9247c6ae99SBarry Smith @*/ 93bff4a2f0SMatthew G. Knepley PetscErrorCode DMDASetBoundaryType(DM da,DMBoundaryType bx,DMBoundaryType by,DMBoundaryType bz) 9447c6ae99SBarry Smith { 9547c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 9647c6ae99SBarry Smith 9747c6ae99SBarry Smith PetscFunctionBegin; 9847c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 995a43f728SLisandro Dalcin PetscValidLogicalCollectiveEnum(da,bx,2); 1005a43f728SLisandro Dalcin PetscValidLogicalCollectiveEnum(da,by,3); 1015a43f728SLisandro Dalcin PetscValidLogicalCollectiveEnum(da,bz,4); 102ce94432eSBarry Smith if (da->setupcalled) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONGSTATE,"This function must be called before DMSetUp()"); 1031321219cSEthan Coon dd->bx = bx; 1041321219cSEthan Coon dd->by = by; 1051321219cSEthan Coon dd->bz = bz; 10647c6ae99SBarry Smith PetscFunctionReturn(0); 10747c6ae99SBarry Smith } 10847c6ae99SBarry Smith 10947c6ae99SBarry Smith /*@ 110aa219208SBarry Smith DMDASetDof - Sets the number of degrees of freedom per vertex 11147c6ae99SBarry Smith 11247c6ae99SBarry Smith Not collective 11347c6ae99SBarry Smith 11459f3ab6dSMatthew G. Knepley Input Parameters: 115aa219208SBarry Smith + da - The DMDA 11647c6ae99SBarry Smith - dof - Number of degrees of freedom 11747c6ae99SBarry Smith 11847c6ae99SBarry Smith Level: intermediate 11947c6ae99SBarry Smith 12047c6ae99SBarry Smith .keywords: distributed array, degrees of freedom 121fb6725baSMatthew G. Knepley .seealso: DMDAGetDof(), DMDACreate(), DMDestroy(), DMDA 12247c6ae99SBarry Smith @*/ 12354cfb0beSLisandro Dalcin PetscErrorCode DMDASetDof(DM da, PetscInt dof) 12447c6ae99SBarry Smith { 12547c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 12647c6ae99SBarry Smith 12747c6ae99SBarry Smith PetscFunctionBegin; 12847c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 12954cfb0beSLisandro Dalcin PetscValidLogicalCollectiveInt(da,dof,2); 130ce94432eSBarry Smith if (da->setupcalled) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONGSTATE,"This function must be called before DMSetUp()"); 13147c6ae99SBarry Smith dd->w = dof; 1321411c6eeSJed Brown da->bs = dof; 13347c6ae99SBarry Smith PetscFunctionReturn(0); 13447c6ae99SBarry Smith } 13547c6ae99SBarry Smith 136fb6725baSMatthew G. Knepley /*@ 137fb6725baSMatthew G. Knepley DMDAGetDof - Gets the number of degrees of freedom per vertex 138fb6725baSMatthew G. Knepley 139fb6725baSMatthew G. Knepley Not collective 140fb6725baSMatthew G. Knepley 141fb6725baSMatthew G. Knepley Input Parameter: 142fb6725baSMatthew G. Knepley . da - The DMDA 143fb6725baSMatthew G. Knepley 144fb6725baSMatthew G. Knepley Output Parameter: 145fb6725baSMatthew G. Knepley . dof - Number of degrees of freedom 146fb6725baSMatthew G. Knepley 147fb6725baSMatthew G. Knepley Level: intermediate 148fb6725baSMatthew G. Knepley 149fb6725baSMatthew G. Knepley .keywords: distributed array, degrees of freedom 150fb6725baSMatthew G. Knepley .seealso: DMDASetDof(), DMDACreate(), DMDestroy(), DMDA 151fb6725baSMatthew G. Knepley @*/ 152fb6725baSMatthew G. Knepley PetscErrorCode DMDAGetDof(DM da, PetscInt *dof) 153fb6725baSMatthew G. Knepley { 154fb6725baSMatthew G. Knepley DM_DA *dd = (DM_DA *) da->data; 155fb6725baSMatthew G. Knepley 156fb6725baSMatthew G. Knepley PetscFunctionBegin; 157fb6725baSMatthew G. Knepley PetscValidHeaderSpecific(da,DM_CLASSID,1); 158fb6725baSMatthew G. Knepley PetscValidPointer(dof,2); 159fb6725baSMatthew G. Knepley *dof = dd->w; 160fb6725baSMatthew G. Knepley PetscFunctionReturn(0); 161fb6725baSMatthew G. Knepley } 162fb6725baSMatthew G. Knepley 1637ddda789SPeter Brune /*@ 1647ddda789SPeter Brune DMDAGetOverlap - Gets the size of the per-processor overlap. 1657ddda789SPeter Brune 1667ddda789SPeter Brune Not collective 1677ddda789SPeter Brune 1687ddda789SPeter Brune Input Parameters: 1697ddda789SPeter Brune . da - The DMDA 1707ddda789SPeter Brune 1717ddda789SPeter Brune Output Parameters: 1727ddda789SPeter Brune + x - Overlap in the x direction 1737ddda789SPeter Brune . y - Overlap in the y direction 1747ddda789SPeter Brune - z - Overlap in the z direction 1757ddda789SPeter Brune 1767ddda789SPeter Brune Level: intermediate 1777ddda789SPeter Brune 1787ddda789SPeter Brune .keywords: distributed array, overlap, domain decomposition 1797ddda789SPeter Brune .seealso: DMDACreateDomainDecomposition(), DMDASetOverlap(), DMDA 1807ddda789SPeter Brune @*/ 1817ddda789SPeter Brune PetscErrorCode DMDAGetOverlap(DM da,PetscInt *x,PetscInt *y,PetscInt *z) 1827ddda789SPeter Brune { 1837ddda789SPeter Brune DM_DA *dd = (DM_DA*)da->data; 1847ddda789SPeter Brune 1857ddda789SPeter Brune PetscFunctionBegin; 1867ddda789SPeter Brune PetscValidHeaderSpecific(da,DM_CLASSID,1); 1877ddda789SPeter Brune if (x) *x = dd->xol; 1887ddda789SPeter Brune if (y) *y = dd->yol; 1897ddda789SPeter Brune if (z) *z = dd->zol; 1907ddda789SPeter Brune PetscFunctionReturn(0); 1917ddda789SPeter Brune } 1927ddda789SPeter Brune 19388661749SPeter Brune /*@ 19488661749SPeter Brune DMDASetOverlap - Sets the size of the per-processor overlap. 19588661749SPeter Brune 19688661749SPeter Brune Not collective 19788661749SPeter Brune 1987ddda789SPeter Brune Input Parameters: 19988661749SPeter Brune + da - The DMDA 2007ddda789SPeter Brune . x - Overlap in the x direction 2017ddda789SPeter Brune . y - Overlap in the y direction 2027ddda789SPeter Brune - z - Overlap in the z direction 20388661749SPeter Brune 20488661749SPeter Brune Level: intermediate 20588661749SPeter Brune 2067ddda789SPeter Brune .keywords: distributed array, overlap, domain decomposition 2077ddda789SPeter Brune .seealso: DMDACreateDomainDecomposition(), DMDAGetOverlap(), DMDA 20888661749SPeter Brune @*/ 2097ddda789SPeter Brune PetscErrorCode DMDASetOverlap(DM da,PetscInt x,PetscInt y,PetscInt z) 21088661749SPeter Brune { 21188661749SPeter Brune DM_DA *dd = (DM_DA*)da->data; 21288661749SPeter Brune 21388661749SPeter Brune PetscFunctionBegin; 21488661749SPeter Brune PetscValidHeaderSpecific(da,DM_CLASSID,1); 2157ddda789SPeter Brune PetscValidLogicalCollectiveInt(da,x,2); 2167ddda789SPeter Brune PetscValidLogicalCollectiveInt(da,y,3); 2177ddda789SPeter Brune PetscValidLogicalCollectiveInt(da,z,4); 2187ddda789SPeter Brune dd->xol = x; 2197ddda789SPeter Brune dd->yol = y; 2207ddda789SPeter Brune dd->zol = z; 22188661749SPeter Brune PetscFunctionReturn(0); 22288661749SPeter Brune } 22388661749SPeter Brune 2243e7870d2SPeter Brune 2253e7870d2SPeter Brune /*@ 2263e7870d2SPeter Brune DMDAGetNumLocalSubDomains - Gets the number of local subdomains created upon decomposition. 2273e7870d2SPeter Brune 2283e7870d2SPeter Brune Not collective 2293e7870d2SPeter Brune 2303e7870d2SPeter Brune Input Parameters: 2313e7870d2SPeter Brune . da - The DMDA 2323e7870d2SPeter Brune 2333e7870d2SPeter Brune Output Parameters: 2343e7870d2SPeter Brune + Nsub - Number of local subdomains created upon decomposition 2353e7870d2SPeter Brune 2363e7870d2SPeter Brune Level: intermediate 2373e7870d2SPeter Brune 2383e7870d2SPeter Brune .keywords: distributed array, domain decomposition 2393e7870d2SPeter Brune .seealso: DMDACreateDomainDecomposition(), DMDASetNumLocalSubDomains(), DMDA 2403e7870d2SPeter Brune @*/ 2413e7870d2SPeter Brune PetscErrorCode DMDAGetNumLocalSubDomains(DM da,PetscInt *Nsub) 2423e7870d2SPeter Brune { 2433e7870d2SPeter Brune DM_DA *dd = (DM_DA*)da->data; 2443e7870d2SPeter Brune 2453e7870d2SPeter Brune PetscFunctionBegin; 2463e7870d2SPeter Brune PetscValidHeaderSpecific(da,DM_CLASSID,1); 2473e7870d2SPeter Brune if (Nsub) *Nsub = dd->Nsub; 2483e7870d2SPeter Brune PetscFunctionReturn(0); 2493e7870d2SPeter Brune } 2503e7870d2SPeter Brune 2513e7870d2SPeter Brune /*@ 2523e7870d2SPeter Brune DMDASetNumLocalSubDomains - Sets the number of local subdomains created upon decomposition. 2533e7870d2SPeter Brune 2543e7870d2SPeter Brune Not collective 2553e7870d2SPeter Brune 2563e7870d2SPeter Brune Input Parameters: 2573e7870d2SPeter Brune + da - The DMDA 2583e7870d2SPeter Brune - Nsub - The number of local subdomains requested 2593e7870d2SPeter Brune 2603e7870d2SPeter Brune Level: intermediate 2613e7870d2SPeter Brune 2623e7870d2SPeter Brune .keywords: distributed array, domain decomposition 2633e7870d2SPeter Brune .seealso: DMDACreateDomainDecomposition(), DMDAGetNumLocalSubDomains(), DMDA 2643e7870d2SPeter Brune @*/ 2653e7870d2SPeter Brune PetscErrorCode DMDASetNumLocalSubDomains(DM da,PetscInt Nsub) 2663e7870d2SPeter Brune { 2673e7870d2SPeter Brune DM_DA *dd = (DM_DA*)da->data; 2683e7870d2SPeter Brune 2693e7870d2SPeter Brune PetscFunctionBegin; 2703e7870d2SPeter Brune PetscValidHeaderSpecific(da,DM_CLASSID,1); 2713e7870d2SPeter Brune PetscValidLogicalCollectiveInt(da,Nsub,2); 2723e7870d2SPeter Brune dd->Nsub = Nsub; 2733e7870d2SPeter Brune PetscFunctionReturn(0); 2743e7870d2SPeter Brune } 2753e7870d2SPeter Brune 276d886c4f4SPeter Brune /*@ 277d886c4f4SPeter Brune DMDASetOffset - Sets the index offset of the DA. 278d886c4f4SPeter Brune 279d886c4f4SPeter Brune Collective on DA 280d886c4f4SPeter Brune 281d886c4f4SPeter Brune Input Parameter: 282d886c4f4SPeter Brune + da - The DMDA 283d886c4f4SPeter Brune . xo - The offset in the x direction 284d886c4f4SPeter Brune . yo - The offset in the y direction 285d886c4f4SPeter Brune - zo - The offset in the z direction 286d886c4f4SPeter Brune 287d886c4f4SPeter Brune Level: intermediate 288d886c4f4SPeter Brune 289d886c4f4SPeter Brune Notes: This is used primarily to overlap a computation on a local DA with that on a global DA without 290d886c4f4SPeter Brune changing boundary conditions or subdomain features that depend upon the global offsets. 291d886c4f4SPeter Brune 292d886c4f4SPeter Brune .keywords: distributed array, degrees of freedom 293d886c4f4SPeter Brune .seealso: DMDAGetOffset(), DMDAVecGetArray() 294d886c4f4SPeter Brune @*/ 29595c13181SPeter Brune PetscErrorCode DMDASetOffset(DM da, PetscInt xo, PetscInt yo, PetscInt zo, PetscInt Mo, PetscInt No, PetscInt Po) 296d886c4f4SPeter Brune { 29795c13181SPeter Brune PetscErrorCode ierr; 298d886c4f4SPeter Brune DM_DA *dd = (DM_DA*)da->data; 299d886c4f4SPeter Brune 300d886c4f4SPeter Brune PetscFunctionBegin; 301d886c4f4SPeter Brune PetscValidHeaderSpecific(da,DM_CLASSID,1); 302d886c4f4SPeter Brune PetscValidLogicalCollectiveInt(da,xo,2); 30395c13181SPeter Brune PetscValidLogicalCollectiveInt(da,yo,3); 30495c13181SPeter Brune PetscValidLogicalCollectiveInt(da,zo,4); 30595c13181SPeter Brune PetscValidLogicalCollectiveInt(da,Mo,5); 30695c13181SPeter Brune PetscValidLogicalCollectiveInt(da,No,6); 30795c13181SPeter Brune PetscValidLogicalCollectiveInt(da,Po,7); 308d886c4f4SPeter Brune dd->xo = xo; 309d886c4f4SPeter Brune dd->yo = yo; 310d886c4f4SPeter Brune dd->zo = zo; 31195c13181SPeter Brune dd->Mo = Mo; 31295c13181SPeter Brune dd->No = No; 31395c13181SPeter Brune dd->Po = Po; 31495c13181SPeter Brune 31595c13181SPeter Brune if (da->coordinateDM) { 31695c13181SPeter Brune ierr = DMDASetOffset(da->coordinateDM,xo,yo,zo,Mo,No,Po);CHKERRQ(ierr); 31795c13181SPeter Brune } 318d886c4f4SPeter Brune PetscFunctionReturn(0); 319d886c4f4SPeter Brune } 320d886c4f4SPeter Brune 321d886c4f4SPeter Brune /*@ 322d886c4f4SPeter Brune DMDAGetOffset - Gets the index offset of the DA. 323d886c4f4SPeter Brune 324d886c4f4SPeter Brune Not collective 325d886c4f4SPeter Brune 326d886c4f4SPeter Brune Input Parameter: 327d886c4f4SPeter Brune . da - The DMDA 328d886c4f4SPeter Brune 329d886c4f4SPeter Brune Output Parameters: 330d886c4f4SPeter Brune + xo - The offset in the x direction 331d886c4f4SPeter Brune . yo - The offset in the y direction 33295c13181SPeter Brune . zo - The offset in the z direction 33395c13181SPeter Brune . Mo - The global size in the x direction 33495c13181SPeter Brune . No - The global size in the y direction 33595c13181SPeter Brune - Po - The global size in the z direction 336d886c4f4SPeter Brune 337d886c4f4SPeter Brune Level: intermediate 338d886c4f4SPeter Brune 339d886c4f4SPeter Brune .keywords: distributed array, degrees of freedom 340d886c4f4SPeter Brune .seealso: DMDASetOffset(), DMDAVecGetArray() 341d886c4f4SPeter Brune @*/ 34295c13181SPeter Brune PetscErrorCode DMDAGetOffset(DM da,PetscInt *xo,PetscInt *yo,PetscInt *zo,PetscInt *Mo,PetscInt *No,PetscInt *Po) 343d886c4f4SPeter Brune { 344d886c4f4SPeter Brune DM_DA *dd = (DM_DA*)da->data; 345d886c4f4SPeter Brune 346d886c4f4SPeter Brune PetscFunctionBegin; 347d886c4f4SPeter Brune PetscValidHeaderSpecific(da,DM_CLASSID,1); 348d886c4f4SPeter Brune if (xo) *xo = dd->xo; 349d886c4f4SPeter Brune if (yo) *yo = dd->yo; 350d886c4f4SPeter Brune if (zo) *zo = dd->zo; 35195c13181SPeter Brune if (Mo) *Mo = dd->Mo; 35295c13181SPeter Brune if (No) *No = dd->No; 35395c13181SPeter Brune if (Po) *Po = dd->Po; 354d886c4f4SPeter Brune PetscFunctionReturn(0); 355d886c4f4SPeter Brune } 356d886c4f4SPeter Brune 35740234c92SPeter Brune /*@ 35840234c92SPeter Brune DMDAGetNonOverlappingRegion - Gets the indices of the nonoverlapping region of a subdomain DM. 35940234c92SPeter Brune 36040234c92SPeter Brune Not collective 36140234c92SPeter Brune 36240234c92SPeter Brune Input Parameter: 36340234c92SPeter Brune . da - The DMDA 36440234c92SPeter Brune 36540234c92SPeter Brune Output Parameters: 36640234c92SPeter Brune + xs - The start of the region in x 36740234c92SPeter Brune . ys - The start of the region in y 36840234c92SPeter Brune . zs - The start of the region in z 36940234c92SPeter Brune . xs - The size of the region in x 37040234c92SPeter Brune . ys - The size of the region in y 37140234c92SPeter Brune . zs - The size of the region in z 37240234c92SPeter Brune 37340234c92SPeter Brune Level: intermediate 37440234c92SPeter Brune 37540234c92SPeter Brune .keywords: distributed array, degrees of freedom 37640234c92SPeter Brune .seealso: DMDAGetOffset(), DMDAVecGetArray() 37740234c92SPeter Brune @*/ 37840234c92SPeter Brune PetscErrorCode DMDAGetNonOverlappingRegion(DM da, PetscInt *xs, PetscInt *ys, PetscInt *zs, PetscInt *xm, PetscInt *ym, PetscInt *zm) 37940234c92SPeter Brune { 38040234c92SPeter Brune DM_DA *dd = (DM_DA*)da->data; 38140234c92SPeter Brune 38240234c92SPeter Brune PetscFunctionBegin; 38340234c92SPeter Brune PetscValidHeaderSpecific(da,DM_CLASSID,1); 38440234c92SPeter Brune if (xs) *xs = dd->nonxs; 38540234c92SPeter Brune if (ys) *ys = dd->nonys; 38640234c92SPeter Brune if (zs) *zs = dd->nonzs; 38740234c92SPeter Brune if (xm) *xm = dd->nonxm; 38840234c92SPeter Brune if (ym) *ym = dd->nonym; 38940234c92SPeter Brune if (zm) *zm = dd->nonzm; 39040234c92SPeter Brune PetscFunctionReturn(0); 39140234c92SPeter Brune } 39240234c92SPeter Brune 39340234c92SPeter Brune 39440234c92SPeter Brune /*@ 39540234c92SPeter Brune DMDASetNonOverlappingRegion - Sets the indices of the nonoverlapping region of a subdomain DM. 39640234c92SPeter Brune 39740234c92SPeter Brune Collective on DA 39840234c92SPeter Brune 39940234c92SPeter Brune Input Parameter: 40040234c92SPeter Brune + da - The DMDA 40140234c92SPeter Brune . xs - The start of the region in x 40240234c92SPeter Brune . ys - The start of the region in y 40340234c92SPeter Brune . zs - The start of the region in z 40440234c92SPeter Brune . xs - The size of the region in x 40540234c92SPeter Brune . ys - The size of the region in y 40640234c92SPeter Brune . zs - The size of the region in z 40740234c92SPeter Brune 40840234c92SPeter Brune Level: intermediate 40940234c92SPeter Brune 41040234c92SPeter Brune .keywords: distributed array, degrees of freedom 41140234c92SPeter Brune .seealso: DMDAGetOffset(), DMDAVecGetArray() 41240234c92SPeter Brune @*/ 41340234c92SPeter Brune PetscErrorCode DMDASetNonOverlappingRegion(DM da, PetscInt xs, PetscInt ys, PetscInt zs, PetscInt xm, PetscInt ym, PetscInt zm) 41440234c92SPeter Brune { 41540234c92SPeter Brune DM_DA *dd = (DM_DA*)da->data; 41640234c92SPeter Brune 41740234c92SPeter Brune PetscFunctionBegin; 41840234c92SPeter Brune PetscValidHeaderSpecific(da,DM_CLASSID,1); 41940234c92SPeter Brune PetscValidLogicalCollectiveInt(da,xs,2); 42040234c92SPeter Brune PetscValidLogicalCollectiveInt(da,ys,3); 42140234c92SPeter Brune PetscValidLogicalCollectiveInt(da,zs,4); 42240234c92SPeter Brune PetscValidLogicalCollectiveInt(da,xm,5); 42340234c92SPeter Brune PetscValidLogicalCollectiveInt(da,ym,6); 42440234c92SPeter Brune PetscValidLogicalCollectiveInt(da,zm,7); 42540234c92SPeter Brune dd->nonxs = xs; 42640234c92SPeter Brune dd->nonys = ys; 42740234c92SPeter Brune dd->nonzs = zs; 42840234c92SPeter Brune dd->nonxm = xm; 42940234c92SPeter Brune dd->nonym = ym; 43040234c92SPeter Brune dd->nonzm = zm; 43140234c92SPeter Brune 43240234c92SPeter Brune PetscFunctionReturn(0); 43340234c92SPeter Brune } 43488661749SPeter Brune 43547c6ae99SBarry Smith /*@ 436aa219208SBarry Smith DMDASetStencilType - Sets the type of the communication stencil 43747c6ae99SBarry Smith 438aa219208SBarry Smith Logically Collective on DMDA 43947c6ae99SBarry Smith 44047c6ae99SBarry Smith Input Parameter: 441aa219208SBarry Smith + da - The DMDA 442aa219208SBarry Smith - stype - The stencil type, use either DMDA_STENCIL_BOX or DMDA_STENCIL_STAR. 44347c6ae99SBarry Smith 44447c6ae99SBarry Smith Level: intermediate 44547c6ae99SBarry Smith 44647c6ae99SBarry Smith .keywords: distributed array, stencil 44796e147daSBarry Smith .seealso: DMDACreate(), DMDestroy(), DMDA 44847c6ae99SBarry Smith @*/ 4497087cfbeSBarry Smith PetscErrorCode DMDASetStencilType(DM da, DMDAStencilType stype) 45047c6ae99SBarry Smith { 45147c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 45247c6ae99SBarry Smith 45347c6ae99SBarry Smith PetscFunctionBegin; 45447c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 45547c6ae99SBarry Smith PetscValidLogicalCollectiveEnum(da,stype,2); 456ce94432eSBarry Smith if (da->setupcalled) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONGSTATE,"This function must be called before DMSetUp()"); 45747c6ae99SBarry Smith dd->stencil_type = stype; 45847c6ae99SBarry Smith PetscFunctionReturn(0); 45947c6ae99SBarry Smith } 46047c6ae99SBarry Smith 461fb6725baSMatthew G. Knepley /*@ 462fb6725baSMatthew G. Knepley DMDAGetStencilType - Gets the type of the communication stencil 463fb6725baSMatthew G. Knepley 464fb6725baSMatthew G. Knepley Not collective 465fb6725baSMatthew G. Knepley 466fb6725baSMatthew G. Knepley Input Parameter: 467fb6725baSMatthew G. Knepley . da - The DMDA 468fb6725baSMatthew G. Knepley 469fb6725baSMatthew G. Knepley Output Parameter: 470fb6725baSMatthew G. Knepley . stype - The stencil type, use either DMDA_STENCIL_BOX or DMDA_STENCIL_STAR. 471fb6725baSMatthew G. Knepley 472fb6725baSMatthew G. Knepley Level: intermediate 473fb6725baSMatthew G. Knepley 474fb6725baSMatthew G. Knepley .keywords: distributed array, stencil 475fb6725baSMatthew G. Knepley .seealso: DMDACreate(), DMDestroy(), DMDA 476fb6725baSMatthew G. Knepley @*/ 477fb6725baSMatthew G. Knepley PetscErrorCode DMDAGetStencilType(DM da, DMDAStencilType *stype) 478fb6725baSMatthew G. Knepley { 479fb6725baSMatthew G. Knepley DM_DA *dd = (DM_DA*)da->data; 480fb6725baSMatthew G. Knepley 481fb6725baSMatthew G. Knepley PetscFunctionBegin; 482fb6725baSMatthew G. Knepley PetscValidHeaderSpecific(da,DM_CLASSID,1); 483fb6725baSMatthew G. Knepley PetscValidPointer(stype,2); 484fb6725baSMatthew G. Knepley *stype = dd->stencil_type; 485fb6725baSMatthew G. Knepley PetscFunctionReturn(0); 486fb6725baSMatthew G. Knepley } 487fb6725baSMatthew G. Knepley 48847c6ae99SBarry Smith /*@ 489aa219208SBarry Smith DMDASetStencilWidth - Sets the width of the communication stencil 49047c6ae99SBarry Smith 491aa219208SBarry Smith Logically Collective on DMDA 49247c6ae99SBarry Smith 49347c6ae99SBarry Smith Input Parameter: 494aa219208SBarry Smith + da - The DMDA 49547c6ae99SBarry Smith - width - The stencil width 49647c6ae99SBarry Smith 49747c6ae99SBarry Smith Level: intermediate 49847c6ae99SBarry Smith 49947c6ae99SBarry Smith .keywords: distributed array, stencil 50096e147daSBarry Smith .seealso: DMDACreate(), DMDestroy(), DMDA 50147c6ae99SBarry Smith @*/ 5027087cfbeSBarry Smith PetscErrorCode DMDASetStencilWidth(DM da, PetscInt width) 50347c6ae99SBarry Smith { 50447c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 50547c6ae99SBarry Smith 50647c6ae99SBarry Smith PetscFunctionBegin; 50747c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 50847c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da,width,2); 509ce94432eSBarry Smith if (da->setupcalled) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONGSTATE,"This function must be called before DMSetUp()"); 51047c6ae99SBarry Smith dd->s = width; 51147c6ae99SBarry Smith PetscFunctionReturn(0); 51247c6ae99SBarry Smith } 51347c6ae99SBarry Smith 514fb6725baSMatthew G. Knepley /*@ 515fb6725baSMatthew G. Knepley DMDAGetStencilWidth - Gets the width of the communication stencil 516fb6725baSMatthew G. Knepley 517fb6725baSMatthew G. Knepley Not collective 518fb6725baSMatthew G. Knepley 519fb6725baSMatthew G. Knepley Input Parameter: 520fb6725baSMatthew G. Knepley . da - The DMDA 521fb6725baSMatthew G. Knepley 522fb6725baSMatthew G. Knepley Output Parameter: 523fb6725baSMatthew G. Knepley . width - The stencil width 524fb6725baSMatthew G. Knepley 525fb6725baSMatthew G. Knepley Level: intermediate 526fb6725baSMatthew G. Knepley 527fb6725baSMatthew G. Knepley .keywords: distributed array, stencil 528fb6725baSMatthew G. Knepley .seealso: DMDACreate(), DMDestroy(), DMDA 529fb6725baSMatthew G. Knepley @*/ 530fb6725baSMatthew G. Knepley PetscErrorCode DMDAGetStencilWidth(DM da, PetscInt *width) 531fb6725baSMatthew G. Knepley { 532fb6725baSMatthew G. Knepley DM_DA *dd = (DM_DA *) da->data; 533fb6725baSMatthew G. Knepley 534fb6725baSMatthew G. Knepley PetscFunctionBegin; 535fb6725baSMatthew G. Knepley PetscValidHeaderSpecific(da,DM_CLASSID,1); 536fb6725baSMatthew G. Knepley PetscValidPointer(width,2); 537fb6725baSMatthew G. Knepley *width = dd->s; 538fb6725baSMatthew G. Knepley PetscFunctionReturn(0); 539fb6725baSMatthew G. Knepley } 540fb6725baSMatthew G. Knepley 541aa219208SBarry Smith static PetscErrorCode DMDACheckOwnershipRanges_Private(DM da,PetscInt M,PetscInt m,const PetscInt lx[]) 54247c6ae99SBarry Smith { 54347c6ae99SBarry Smith PetscInt i,sum; 54447c6ae99SBarry Smith 54547c6ae99SBarry Smith PetscFunctionBegin; 546ce94432eSBarry Smith if (M < 0) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONGSTATE,"Global dimension not set"); 54747c6ae99SBarry Smith for (i=sum=0; i<m; i++) sum += lx[i]; 548ce94432eSBarry Smith if (sum != M) SETERRQ2(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_INCOMP,"Ownership ranges sum to %D but global dimension is %D",sum,M); 54947c6ae99SBarry Smith PetscFunctionReturn(0); 55047c6ae99SBarry Smith } 55147c6ae99SBarry Smith 55247c6ae99SBarry Smith /*@ 553aa219208SBarry Smith DMDASetOwnershipRanges - Sets the number of nodes in each direction on each process 55447c6ae99SBarry Smith 555aa219208SBarry Smith Logically Collective on DMDA 55647c6ae99SBarry Smith 55747c6ae99SBarry Smith Input Parameter: 558aa219208SBarry Smith + da - The DMDA 5590298fd71SBarry 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 5600298fd71SBarry 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 5610298fd71SBarry 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. 56247c6ae99SBarry Smith 56347c6ae99SBarry Smith Level: intermediate 56447c6ae99SBarry Smith 565e3f3e4b6SBarry Smith Note: these numbers are NOT multiplied by the number of dof per node. 566e3f3e4b6SBarry Smith 56747c6ae99SBarry Smith .keywords: distributed array 56896e147daSBarry Smith .seealso: DMDACreate(), DMDestroy(), DMDA 56947c6ae99SBarry Smith @*/ 5707087cfbeSBarry Smith PetscErrorCode DMDASetOwnershipRanges(DM da, const PetscInt lx[], const PetscInt ly[], const PetscInt lz[]) 57147c6ae99SBarry Smith { 57247c6ae99SBarry Smith PetscErrorCode ierr; 57347c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 57447c6ae99SBarry Smith 57547c6ae99SBarry Smith PetscFunctionBegin; 57647c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 577ce94432eSBarry Smith if (da->setupcalled) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONGSTATE,"This function must be called before DMSetUp()"); 57847c6ae99SBarry Smith if (lx) { 579ce94432eSBarry Smith if (dd->m < 0) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONGSTATE,"Cannot set ownership ranges before setting number of procs"); 580aa219208SBarry Smith ierr = DMDACheckOwnershipRanges_Private(da,dd->M,dd->m,lx);CHKERRQ(ierr); 58147c6ae99SBarry Smith if (!dd->lx) { 582785e854fSJed Brown ierr = PetscMalloc1(dd->m, &dd->lx);CHKERRQ(ierr); 58347c6ae99SBarry Smith } 58447c6ae99SBarry Smith ierr = PetscMemcpy(dd->lx, lx, dd->m*sizeof(PetscInt));CHKERRQ(ierr); 58547c6ae99SBarry Smith } 58647c6ae99SBarry Smith if (ly) { 587ce94432eSBarry Smith if (dd->n < 0) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONGSTATE,"Cannot set ownership ranges before setting number of procs"); 588aa219208SBarry Smith ierr = DMDACheckOwnershipRanges_Private(da,dd->N,dd->n,ly);CHKERRQ(ierr); 58947c6ae99SBarry Smith if (!dd->ly) { 590785e854fSJed Brown ierr = PetscMalloc1(dd->n, &dd->ly);CHKERRQ(ierr); 59147c6ae99SBarry Smith } 59247c6ae99SBarry Smith ierr = PetscMemcpy(dd->ly, ly, dd->n*sizeof(PetscInt));CHKERRQ(ierr); 59347c6ae99SBarry Smith } 59447c6ae99SBarry Smith if (lz) { 595ce94432eSBarry Smith if (dd->p < 0) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_WRONGSTATE,"Cannot set ownership ranges before setting number of procs"); 596aa219208SBarry Smith ierr = DMDACheckOwnershipRanges_Private(da,dd->P,dd->p,lz);CHKERRQ(ierr); 59747c6ae99SBarry Smith if (!dd->lz) { 598785e854fSJed Brown ierr = PetscMalloc1(dd->p, &dd->lz);CHKERRQ(ierr); 59947c6ae99SBarry Smith } 60047c6ae99SBarry Smith ierr = PetscMemcpy(dd->lz, lz, dd->p*sizeof(PetscInt));CHKERRQ(ierr); 60147c6ae99SBarry Smith } 60247c6ae99SBarry Smith PetscFunctionReturn(0); 60347c6ae99SBarry Smith } 60447c6ae99SBarry Smith 60547c6ae99SBarry Smith /*@ 606aa219208SBarry Smith DMDASetInterpolationType - Sets the type of interpolation that will be 607e727c939SJed Brown returned by DMCreateInterpolation() 60847c6ae99SBarry Smith 609aa219208SBarry Smith Logically Collective on DMDA 61047c6ae99SBarry Smith 61147c6ae99SBarry Smith Input Parameter: 61247c6ae99SBarry Smith + da - initial distributed array 613aa219208SBarry Smith . ctype - DMDA_Q1 and DMDA_Q0 are currently the only supported forms 61447c6ae99SBarry Smith 61547c6ae99SBarry Smith Level: intermediate 61647c6ae99SBarry Smith 617e727c939SJed Brown Notes: you should call this on the coarser of the two DMDAs you pass to DMCreateInterpolation() 61847c6ae99SBarry Smith 61947c6ae99SBarry Smith .keywords: distributed array, interpolation 62047c6ae99SBarry Smith 62196e147daSBarry Smith .seealso: DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMDestroy(), DMDA, DMDAInterpolationType 62247c6ae99SBarry Smith @*/ 6237087cfbeSBarry Smith PetscErrorCode DMDASetInterpolationType(DM da,DMDAInterpolationType ctype) 62447c6ae99SBarry Smith { 62547c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 62647c6ae99SBarry Smith 62747c6ae99SBarry Smith PetscFunctionBegin; 62847c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 62947c6ae99SBarry Smith PetscValidLogicalCollectiveEnum(da,ctype,2); 63047c6ae99SBarry Smith dd->interptype = ctype; 63147c6ae99SBarry Smith PetscFunctionReturn(0); 63247c6ae99SBarry Smith } 63347c6ae99SBarry Smith 6342dde6fd4SLisandro Dalcin /*@ 6352dde6fd4SLisandro Dalcin DMDAGetInterpolationType - Gets the type of interpolation that will be 636e727c939SJed Brown used by DMCreateInterpolation() 6372dde6fd4SLisandro Dalcin 6382dde6fd4SLisandro Dalcin Not Collective 6392dde6fd4SLisandro Dalcin 6402dde6fd4SLisandro Dalcin Input Parameter: 6412dde6fd4SLisandro Dalcin . da - distributed array 6422dde6fd4SLisandro Dalcin 6432dde6fd4SLisandro Dalcin Output Parameter: 6442dde6fd4SLisandro Dalcin . ctype - interpolation type (DMDA_Q1 and DMDA_Q0 are currently the only supported forms) 6452dde6fd4SLisandro Dalcin 6462dde6fd4SLisandro Dalcin Level: intermediate 6472dde6fd4SLisandro Dalcin 6482dde6fd4SLisandro Dalcin .keywords: distributed array, interpolation 6492dde6fd4SLisandro Dalcin 650e727c939SJed Brown .seealso: DMDA, DMDAInterpolationType, DMDASetInterpolationType(), DMCreateInterpolation() 6512dde6fd4SLisandro Dalcin @*/ 6522dde6fd4SLisandro Dalcin PetscErrorCode DMDAGetInterpolationType(DM da,DMDAInterpolationType *ctype) 6532dde6fd4SLisandro Dalcin { 6542dde6fd4SLisandro Dalcin DM_DA *dd = (DM_DA*)da->data; 6552dde6fd4SLisandro Dalcin 6562dde6fd4SLisandro Dalcin PetscFunctionBegin; 6572dde6fd4SLisandro Dalcin PetscValidHeaderSpecific(da,DM_CLASSID,1); 6582dde6fd4SLisandro Dalcin PetscValidPointer(ctype,2); 6592dde6fd4SLisandro Dalcin *ctype = dd->interptype; 6602dde6fd4SLisandro Dalcin PetscFunctionReturn(0); 6612dde6fd4SLisandro Dalcin } 66247c6ae99SBarry Smith 663*1fd49c25SBarry Smith /*@ 664aa219208SBarry Smith DMDAGetNeighbors - Gets an array containing the MPI rank of all the current 66547c6ae99SBarry Smith processes neighbors. 66647c6ae99SBarry Smith 66747c6ae99SBarry Smith Not Collective 66847c6ae99SBarry Smith 66947c6ae99SBarry Smith Input Parameter: 670aa219208SBarry Smith . da - the DMDA object 67147c6ae99SBarry Smith 67247c6ae99SBarry Smith Output Parameters: 67347c6ae99SBarry Smith . ranks - the neighbors ranks, stored with the x index increasing most rapidly. 67447c6ae99SBarry Smith this process itself is in the list 67547c6ae99SBarry Smith 67647c6ae99SBarry Smith Notes: In 2d the array is of length 9, in 3d of length 27 67747c6ae99SBarry Smith Not supported in 1d 678aa219208SBarry Smith Do not free the array, it is freed when the DMDA is destroyed. 67947c6ae99SBarry Smith 68047c6ae99SBarry Smith Fortran Notes: In fortran you must pass in an array of the appropriate length. 68147c6ae99SBarry Smith 68247c6ae99SBarry Smith Level: intermediate 68347c6ae99SBarry Smith 68447c6ae99SBarry Smith @*/ 6857087cfbeSBarry Smith PetscErrorCode DMDAGetNeighbors(DM da,const PetscMPIInt *ranks[]) 68647c6ae99SBarry Smith { 68747c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 6885fd66863SKarl Rupp 68947c6ae99SBarry Smith PetscFunctionBegin; 69047c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 69147c6ae99SBarry Smith *ranks = dd->neighbors; 69247c6ae99SBarry Smith PetscFunctionReturn(0); 69347c6ae99SBarry Smith } 69447c6ae99SBarry Smith 69547c6ae99SBarry Smith /*@C 696aa219208SBarry Smith DMDAGetOwnershipRanges - Gets the ranges of indices in the x, y and z direction that are owned by each process 69747c6ae99SBarry Smith 69847c6ae99SBarry Smith Not Collective 69947c6ae99SBarry Smith 70047c6ae99SBarry Smith Input Parameter: 701aa219208SBarry Smith . da - the DMDA object 70247c6ae99SBarry Smith 70347c6ae99SBarry Smith Output Parameter: 70447c6ae99SBarry Smith + lx - ownership along x direction (optional) 70547c6ae99SBarry Smith . ly - ownership along y direction (optional) 70647c6ae99SBarry Smith - lz - ownership along z direction (optional) 70747c6ae99SBarry Smith 70847c6ae99SBarry Smith Level: intermediate 70947c6ae99SBarry Smith 710aa219208SBarry Smith Note: these correspond to the optional final arguments passed to DMDACreate(), DMDACreate2d(), DMDACreate3d() 71147c6ae99SBarry Smith 71247c6ae99SBarry Smith In Fortran one must pass in arrays lx, ly, and lz that are long enough to hold the values; the sixth, seventh and 713aa219208SBarry Smith eighth arguments from DMDAGetInfo() 71447c6ae99SBarry Smith 71547c6ae99SBarry Smith In C you should not free these arrays, nor change the values in them. They will only have valid values while the 716aa219208SBarry Smith DMDA they came from still exists (has not been destroyed). 71747c6ae99SBarry Smith 718e3f3e4b6SBarry Smith These numbers are NOT multiplied by the number of dof per node. 719e3f3e4b6SBarry Smith 720*1fd49c25SBarry Smith Not available from Fortran 721*1fd49c25SBarry Smith 722aa219208SBarry Smith .seealso: DMDAGetCorners(), DMDAGetGhostCorners(), DMDACreate(), DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), VecGetOwnershipRanges() 72347c6ae99SBarry Smith @*/ 7247087cfbeSBarry Smith PetscErrorCode DMDAGetOwnershipRanges(DM da,const PetscInt *lx[],const PetscInt *ly[],const PetscInt *lz[]) 72547c6ae99SBarry Smith { 72647c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 72747c6ae99SBarry Smith 72847c6ae99SBarry Smith PetscFunctionBegin; 72947c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 73047c6ae99SBarry Smith if (lx) *lx = dd->lx; 73147c6ae99SBarry Smith if (ly) *ly = dd->ly; 73247c6ae99SBarry Smith if (lz) *lz = dd->lz; 73347c6ae99SBarry Smith PetscFunctionReturn(0); 73447c6ae99SBarry Smith } 73547c6ae99SBarry Smith 73647c6ae99SBarry Smith /*@ 737aa219208SBarry Smith DMDASetRefinementFactor - Set the ratios that the DMDA grid is refined 73847c6ae99SBarry Smith 739aa219208SBarry Smith Logically Collective on DMDA 74047c6ae99SBarry Smith 74147c6ae99SBarry Smith Input Parameters: 742aa219208SBarry Smith + da - the DMDA object 74347c6ae99SBarry Smith . refine_x - ratio of fine grid to coarse in x direction (2 by default) 74447c6ae99SBarry Smith . refine_y - ratio of fine grid to coarse in y direction (2 by default) 74547c6ae99SBarry Smith - refine_z - ratio of fine grid to coarse in z direction (2 by default) 74647c6ae99SBarry Smith 74747c6ae99SBarry Smith Options Database: 74847c6ae99SBarry Smith + -da_refine_x - refinement ratio in x direction 74947c6ae99SBarry Smith . -da_refine_y - refinement ratio in y direction 75047c6ae99SBarry Smith - -da_refine_z - refinement ratio in z direction 75147c6ae99SBarry Smith 75247c6ae99SBarry Smith Level: intermediate 75347c6ae99SBarry Smith 75447c6ae99SBarry Smith Notes: Pass PETSC_IGNORE to leave a value unchanged 75547c6ae99SBarry Smith 756aa219208SBarry Smith .seealso: DMRefine(), DMDAGetRefinementFactor() 75747c6ae99SBarry Smith @*/ 7587087cfbeSBarry Smith PetscErrorCode DMDASetRefinementFactor(DM da, PetscInt refine_x, PetscInt refine_y,PetscInt refine_z) 75947c6ae99SBarry Smith { 76047c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 76147c6ae99SBarry Smith 76247c6ae99SBarry Smith PetscFunctionBegin; 76347c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 76447c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da,refine_x,2); 76547c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da,refine_y,3); 76647c6ae99SBarry Smith PetscValidLogicalCollectiveInt(da,refine_z,4); 76747c6ae99SBarry Smith 76847c6ae99SBarry Smith if (refine_x > 0) dd->refine_x = refine_x; 76947c6ae99SBarry Smith if (refine_y > 0) dd->refine_y = refine_y; 77047c6ae99SBarry Smith if (refine_z > 0) dd->refine_z = refine_z; 77147c6ae99SBarry Smith PetscFunctionReturn(0); 77247c6ae99SBarry Smith } 77347c6ae99SBarry Smith 77447c6ae99SBarry Smith /*@C 775aa219208SBarry Smith DMDAGetRefinementFactor - Gets the ratios that the DMDA grid is refined 77647c6ae99SBarry Smith 77747c6ae99SBarry Smith Not Collective 77847c6ae99SBarry Smith 77947c6ae99SBarry Smith Input Parameter: 780aa219208SBarry Smith . da - the DMDA object 78147c6ae99SBarry Smith 78247c6ae99SBarry Smith Output Parameters: 78347c6ae99SBarry Smith + refine_x - ratio of fine grid to coarse in x direction (2 by default) 78447c6ae99SBarry Smith . refine_y - ratio of fine grid to coarse in y direction (2 by default) 78547c6ae99SBarry Smith - refine_z - ratio of fine grid to coarse in z direction (2 by default) 78647c6ae99SBarry Smith 78747c6ae99SBarry Smith Level: intermediate 78847c6ae99SBarry Smith 7890298fd71SBarry Smith Notes: Pass NULL for values you do not need 79047c6ae99SBarry Smith 791aa219208SBarry Smith .seealso: DMRefine(), DMDASetRefinementFactor() 79247c6ae99SBarry Smith @*/ 7937087cfbeSBarry Smith PetscErrorCode DMDAGetRefinementFactor(DM da, PetscInt *refine_x, PetscInt *refine_y,PetscInt *refine_z) 79447c6ae99SBarry Smith { 79547c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 79647c6ae99SBarry Smith 79747c6ae99SBarry Smith PetscFunctionBegin; 79847c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 79947c6ae99SBarry Smith if (refine_x) *refine_x = dd->refine_x; 80047c6ae99SBarry Smith if (refine_y) *refine_y = dd->refine_y; 80147c6ae99SBarry Smith if (refine_z) *refine_z = dd->refine_z; 80247c6ae99SBarry Smith PetscFunctionReturn(0); 80347c6ae99SBarry Smith } 80447c6ae99SBarry Smith 80547c6ae99SBarry Smith /*@C 806aa219208SBarry Smith DMDASetGetMatrix - Sets the routine used by the DMDA to allocate a matrix. 80747c6ae99SBarry Smith 808aa219208SBarry Smith Logically Collective on DMDA 80947c6ae99SBarry Smith 81047c6ae99SBarry Smith Input Parameters: 811aa219208SBarry Smith + da - the DMDA object 812aa219208SBarry Smith - f - the function that allocates the matrix for that specific DMDA 81347c6ae99SBarry Smith 81447c6ae99SBarry Smith Level: developer 81547c6ae99SBarry Smith 816aa219208SBarry Smith Notes: See DMDASetBlockFills() that provides a simple way to provide the nonzero structure for 81747c6ae99SBarry Smith the diagonal and off-diagonal blocks of the matrix 81847c6ae99SBarry Smith 819*1fd49c25SBarry Smith Not supported from Fortran 820*1fd49c25SBarry Smith 821950540a4SJed Brown .seealso: DMCreateMatrix(), DMDASetBlockFills() 82247c6ae99SBarry Smith @*/ 823b412c318SBarry Smith PetscErrorCode DMDASetGetMatrix(DM da,PetscErrorCode (*f)(DM, Mat*)) 82447c6ae99SBarry Smith { 82547c6ae99SBarry Smith PetscFunctionBegin; 82647c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 82725296bd5SBarry Smith da->ops->creatematrix = f; 82847c6ae99SBarry Smith PetscFunctionReturn(0); 82947c6ae99SBarry Smith } 83047c6ae99SBarry Smith 83147c6ae99SBarry Smith /* 83247c6ae99SBarry Smith Creates "balanced" ownership ranges after refinement, constrained by the need for the 83347c6ae99SBarry Smith fine grid boundaries to fall within one stencil width of the coarse partition. 83447c6ae99SBarry Smith 83547c6ae99SBarry Smith Uses a greedy algorithm to handle non-ideal layouts, could probably do something better. 83647c6ae99SBarry Smith */ 83794013140SBarry Smith static PetscErrorCode DMDARefineOwnershipRanges(DM da,PetscBool periodic,PetscInt stencil_width,PetscInt ratio,PetscInt m,const PetscInt lc[],PetscInt lf[]) 83847c6ae99SBarry Smith { 83947c6ae99SBarry Smith PetscInt i,totalc = 0,remaining,startc = 0,startf = 0; 84047c6ae99SBarry Smith PetscErrorCode ierr; 84147c6ae99SBarry Smith 84247c6ae99SBarry Smith PetscFunctionBegin; 843ce94432eSBarry Smith if (ratio < 1) SETERRQ1(PetscObjectComm((PetscObject)da),PETSC_ERR_USER,"Requested refinement ratio %D must be at least 1",ratio); 84447c6ae99SBarry Smith if (ratio == 1) { 84547c6ae99SBarry Smith ierr = PetscMemcpy(lf,lc,m*sizeof(lc[0]));CHKERRQ(ierr); 84647c6ae99SBarry Smith PetscFunctionReturn(0); 84747c6ae99SBarry Smith } 84847c6ae99SBarry Smith for (i=0; i<m; i++) totalc += lc[i]; 84947c6ae99SBarry Smith remaining = (!periodic) + ratio * (totalc - (!periodic)); 85047c6ae99SBarry Smith for (i=0; i<m; i++) { 85147c6ae99SBarry Smith PetscInt want = remaining/(m-i) + !!(remaining%(m-i)); 85247c6ae99SBarry Smith if (i == m-1) lf[i] = want; 85347c6ae99SBarry Smith else { 8547aca7175SJed Brown const PetscInt nextc = startc + lc[i]; 8557aca7175SJed Brown /* Move the first fine node of the next subdomain to the right until the coarse node on its left is within one 8567aca7175SJed Brown * coarse stencil width of the first coarse node in the next subdomain. */ 8577aca7175SJed Brown while ((startf+want)/ratio < nextc - stencil_width) want++; 8587aca7175SJed Brown /* Move the last fine node in the current subdomain to the left until the coarse node on its right is within one 8597aca7175SJed Brown * coarse stencil width of the last coarse node in the current subdomain. */ 8607aca7175SJed Brown while ((startf+want-1+ratio-1)/ratio > nextc-1+stencil_width) want--; 8617aca7175SJed Brown /* Make sure all constraints are satisfied */ 86230729d88SBarry Smith if (want < 0 || want > remaining || ((startf+want)/ratio < nextc - stencil_width) 863ce94432eSBarry 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"); 86447c6ae99SBarry Smith } 86547c6ae99SBarry Smith lf[i] = want; 86647c6ae99SBarry Smith startc += lc[i]; 86747c6ae99SBarry Smith startf += lf[i]; 86847c6ae99SBarry Smith remaining -= lf[i]; 86947c6ae99SBarry Smith } 87047c6ae99SBarry Smith PetscFunctionReturn(0); 87147c6ae99SBarry Smith } 87247c6ae99SBarry Smith 8732be375d4SJed Brown /* 8742be375d4SJed Brown Creates "balanced" ownership ranges after coarsening, constrained by the need for the 8752be375d4SJed Brown fine grid boundaries to fall within one stencil width of the coarse partition. 8762be375d4SJed Brown 8772be375d4SJed Brown Uses a greedy algorithm to handle non-ideal layouts, could probably do something better. 8782be375d4SJed Brown */ 8792be375d4SJed Brown static PetscErrorCode DMDACoarsenOwnershipRanges(DM da,PetscBool periodic,PetscInt stencil_width,PetscInt ratio,PetscInt m,const PetscInt lf[],PetscInt lc[]) 8802be375d4SJed Brown { 8812be375d4SJed Brown PetscInt i,totalf,remaining,startc,startf; 8822be375d4SJed Brown PetscErrorCode ierr; 8832be375d4SJed Brown 8842be375d4SJed Brown PetscFunctionBegin; 885ce94432eSBarry Smith if (ratio < 1) SETERRQ1(PetscObjectComm((PetscObject)da),PETSC_ERR_USER,"Requested refinement ratio %D must be at least 1",ratio); 8862be375d4SJed Brown if (ratio == 1) { 8872be375d4SJed Brown ierr = PetscMemcpy(lc,lf,m*sizeof(lf[0]));CHKERRQ(ierr); 8882be375d4SJed Brown PetscFunctionReturn(0); 8892be375d4SJed Brown } 8902be375d4SJed Brown for (i=0,totalf=0; i<m; i++) totalf += lf[i]; 8912be375d4SJed Brown remaining = (!periodic) + (totalf - (!periodic)) / ratio; 8922be375d4SJed Brown for (i=0,startc=0,startf=0; i<m; i++) { 8932be375d4SJed Brown PetscInt want = remaining/(m-i) + !!(remaining%(m-i)); 8942be375d4SJed Brown if (i == m-1) lc[i] = want; 8952be375d4SJed Brown else { 8962be375d4SJed Brown const PetscInt nextf = startf+lf[i]; 8972be375d4SJed Brown /* Slide first coarse node of next subdomain to the left until the coarse node to the left of the first fine 8982be375d4SJed Brown * node is within one stencil width. */ 8992be375d4SJed Brown while (nextf/ratio < startc+want-stencil_width) want--; 9002be375d4SJed Brown /* Slide the last coarse node of the current subdomain to the right until the coarse node to the right of the last 9012be375d4SJed Brown * fine node is within one stencil width. */ 9022be375d4SJed Brown while ((nextf-1+ratio-1)/ratio > startc+want-1+stencil_width) want++; 9032be375d4SJed Brown if (want < 0 || want > remaining 904ce94432eSBarry 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"); 9052be375d4SJed Brown } 9062be375d4SJed Brown lc[i] = want; 9072be375d4SJed Brown startc += lc[i]; 9082be375d4SJed Brown startf += lf[i]; 9092be375d4SJed Brown remaining -= lc[i]; 9102be375d4SJed Brown } 9112be375d4SJed Brown PetscFunctionReturn(0); 9122be375d4SJed Brown } 9132be375d4SJed Brown 9147087cfbeSBarry Smith PetscErrorCode DMRefine_DA(DM da,MPI_Comm comm,DM *daref) 91547c6ae99SBarry Smith { 91647c6ae99SBarry Smith PetscErrorCode ierr; 917c73cfb54SMatthew G. Knepley PetscInt M,N,P,i,dim; 9189a42bb27SBarry Smith DM da2; 91947c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data,*dd2; 92047c6ae99SBarry Smith 92147c6ae99SBarry Smith PetscFunctionBegin; 92247c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 92347c6ae99SBarry Smith PetscValidPointer(daref,3); 92447c6ae99SBarry Smith 925c73cfb54SMatthew G. Knepley ierr = DMGetDimension(da, &dim);CHKERRQ(ierr); 926bff4a2f0SMatthew G. Knepley if (dd->bx == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) { 92747c6ae99SBarry Smith M = dd->refine_x*dd->M; 92847c6ae99SBarry Smith } else { 92947c6ae99SBarry Smith M = 1 + dd->refine_x*(dd->M - 1); 93047c6ae99SBarry Smith } 931bff4a2f0SMatthew G. Knepley if (dd->by == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) { 932c73cfb54SMatthew G. Knepley if (dim > 1) { 93347c6ae99SBarry Smith N = dd->refine_y*dd->N; 93447c6ae99SBarry Smith } else { 9351860e6e9SBarry Smith N = 1; 9361860e6e9SBarry Smith } 9371860e6e9SBarry Smith } else { 93847c6ae99SBarry Smith N = 1 + dd->refine_y*(dd->N - 1); 93947c6ae99SBarry Smith } 940bff4a2f0SMatthew G. Knepley if (dd->bz == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) { 941c73cfb54SMatthew G. Knepley if (dim > 2) { 94247c6ae99SBarry Smith P = dd->refine_z*dd->P; 94347c6ae99SBarry Smith } else { 9441860e6e9SBarry Smith P = 1; 9451860e6e9SBarry Smith } 9461860e6e9SBarry Smith } else { 94747c6ae99SBarry Smith P = 1 + dd->refine_z*(dd->P - 1); 94847c6ae99SBarry Smith } 949ce94432eSBarry Smith ierr = DMDACreate(PetscObjectComm((PetscObject)da),&da2);CHKERRQ(ierr); 950397b6216SJed Brown ierr = DMSetOptionsPrefix(da2,((PetscObject)da)->prefix);CHKERRQ(ierr); 951c73cfb54SMatthew G. Knepley ierr = DMSetDimension(da2,dim);CHKERRQ(ierr); 952397b6216SJed Brown ierr = DMDASetSizes(da2,M,N,P);CHKERRQ(ierr); 953397b6216SJed Brown ierr = DMDASetNumProcs(da2,dd->m,dd->n,dd->p);CHKERRQ(ierr); 954397b6216SJed Brown ierr = DMDASetBoundaryType(da2,dd->bx,dd->by,dd->bz);CHKERRQ(ierr); 955397b6216SJed Brown ierr = DMDASetDof(da2,dd->w);CHKERRQ(ierr); 956397b6216SJed Brown ierr = DMDASetStencilType(da2,dd->stencil_type);CHKERRQ(ierr); 957397b6216SJed Brown ierr = DMDASetStencilWidth(da2,dd->s);CHKERRQ(ierr); 958c73cfb54SMatthew G. Knepley if (dim == 3) { 95947c6ae99SBarry Smith PetscInt *lx,*ly,*lz; 960dcca6d9dSJed Brown ierr = PetscMalloc3(dd->m,&lx,dd->n,&ly,dd->p,&lz);CHKERRQ(ierr); 961bff4a2f0SMatthew 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); 962bff4a2f0SMatthew 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); 963bff4a2f0SMatthew 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); 964397b6216SJed Brown ierr = DMDASetOwnershipRanges(da2,lx,ly,lz);CHKERRQ(ierr); 96547c6ae99SBarry Smith ierr = PetscFree3(lx,ly,lz);CHKERRQ(ierr); 966c73cfb54SMatthew G. Knepley } else if (dim == 2) { 96747c6ae99SBarry Smith PetscInt *lx,*ly; 968dcca6d9dSJed Brown ierr = PetscMalloc2(dd->m,&lx,dd->n,&ly);CHKERRQ(ierr); 969bff4a2f0SMatthew 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); 970bff4a2f0SMatthew 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); 9710298fd71SBarry Smith ierr = DMDASetOwnershipRanges(da2,lx,ly,NULL);CHKERRQ(ierr); 97247c6ae99SBarry Smith ierr = PetscFree2(lx,ly);CHKERRQ(ierr); 973c73cfb54SMatthew G. Knepley } else if (dim == 1) { 97447c6ae99SBarry Smith PetscInt *lx; 975785e854fSJed Brown ierr = PetscMalloc1(dd->m,&lx);CHKERRQ(ierr); 976bff4a2f0SMatthew 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); 9770298fd71SBarry Smith ierr = DMDASetOwnershipRanges(da2,lx,NULL,NULL);CHKERRQ(ierr); 97847c6ae99SBarry Smith ierr = PetscFree(lx);CHKERRQ(ierr); 97947c6ae99SBarry Smith } 98047c6ae99SBarry Smith dd2 = (DM_DA*)da2->data; 98147c6ae99SBarry Smith 98247c6ae99SBarry Smith /* allow overloaded (user replaced) operations to be inherited by refinement clones */ 98325296bd5SBarry Smith da2->ops->creatematrix = da->ops->creatematrix; 98425296bd5SBarry Smith /* da2->ops->createinterpolation = da->ops->createinterpolation; this causes problem with SNESVI */ 98547c6ae99SBarry Smith da2->ops->getcoloring = da->ops->getcoloring; 98647c6ae99SBarry Smith dd2->interptype = dd->interptype; 98747c6ae99SBarry Smith 98847c6ae99SBarry Smith /* copy fill information if given */ 98947c6ae99SBarry Smith if (dd->dfill) { 990854ce69bSBarry Smith ierr = PetscMalloc1(dd->dfill[dd->w]+dd->w+1,&dd2->dfill);CHKERRQ(ierr); 99147c6ae99SBarry Smith ierr = PetscMemcpy(dd2->dfill,dd->dfill,(dd->dfill[dd->w]+dd->w+1)*sizeof(PetscInt));CHKERRQ(ierr); 99247c6ae99SBarry Smith } 99347c6ae99SBarry Smith if (dd->ofill) { 994854ce69bSBarry Smith ierr = PetscMalloc1(dd->ofill[dd->w]+dd->w+1,&dd2->ofill);CHKERRQ(ierr); 99547c6ae99SBarry Smith ierr = PetscMemcpy(dd2->ofill,dd->ofill,(dd->ofill[dd->w]+dd->w+1)*sizeof(PetscInt));CHKERRQ(ierr); 99647c6ae99SBarry Smith } 99747c6ae99SBarry Smith /* copy the refine information */ 998397b6216SJed Brown dd2->coarsen_x = dd2->refine_x = dd->refine_x; 999397b6216SJed Brown dd2->coarsen_y = dd2->refine_y = dd->refine_y; 1000397b6216SJed Brown dd2->coarsen_z = dd2->refine_z = dd->refine_z; 100147c6ae99SBarry Smith 1002897f7067SBarry Smith if (dd->refine_z_hier) { 1003897f7067SBarry Smith if (da->levelup - da->leveldown + 1 > -1 && da->levelup - da->leveldown + 1 < dd->refine_z_hier_n) { 1004897f7067SBarry Smith dd2->refine_z = dd->refine_z_hier[da->levelup - da->leveldown + 1]; 1005897f7067SBarry Smith } 1006897f7067SBarry Smith if (da->levelup - da->leveldown > -1 && da->levelup - da->leveldown < dd->refine_z_hier_n) { 1007897f7067SBarry Smith dd2->coarsen_z = dd->refine_z_hier[da->levelup - da->leveldown]; 1008897f7067SBarry Smith } 1009897f7067SBarry Smith dd2->refine_z_hier_n = dd->refine_z_hier_n; 1010897f7067SBarry Smith ierr = PetscMalloc1(dd2->refine_z_hier_n,&dd2->refine_z_hier);CHKERRQ(ierr); 1011897f7067SBarry Smith ierr = PetscMemcpy(dd2->refine_z_hier,dd->refine_z_hier,dd2->refine_z_hier_n*sizeof(PetscInt));CHKERRQ(ierr); 1012897f7067SBarry Smith } 1013897f7067SBarry Smith if (dd->refine_y_hier) { 1014897f7067SBarry Smith if (da->levelup - da->leveldown + 1 > -1 && da->levelup - da->leveldown + 1 < dd->refine_y_hier_n) { 1015897f7067SBarry Smith dd2->refine_y = dd->refine_y_hier[da->levelup - da->leveldown + 1]; 1016897f7067SBarry Smith } 1017897f7067SBarry Smith if (da->levelup - da->leveldown > -1 && da->levelup - da->leveldown < dd->refine_y_hier_n) { 1018897f7067SBarry Smith dd2->coarsen_y = dd->refine_y_hier[da->levelup - da->leveldown]; 1019897f7067SBarry Smith } 1020897f7067SBarry Smith dd2->refine_y_hier_n = dd->refine_y_hier_n; 1021897f7067SBarry Smith ierr = PetscMalloc1(dd2->refine_y_hier_n,&dd2->refine_y_hier);CHKERRQ(ierr); 1022897f7067SBarry Smith ierr = PetscMemcpy(dd2->refine_y_hier,dd->refine_y_hier,dd2->refine_y_hier_n*sizeof(PetscInt));CHKERRQ(ierr); 1023897f7067SBarry Smith } 1024897f7067SBarry Smith if (dd->refine_x_hier) { 1025897f7067SBarry Smith if (da->levelup - da->leveldown + 1 > -1 && da->levelup - da->leveldown + 1 < dd->refine_x_hier_n) { 1026897f7067SBarry Smith dd2->refine_x = dd->refine_x_hier[da->levelup - da->leveldown + 1]; 1027897f7067SBarry Smith } 1028897f7067SBarry Smith if (da->levelup - da->leveldown > -1 && da->levelup - da->leveldown < dd->refine_x_hier_n) { 1029897f7067SBarry Smith dd2->coarsen_x = dd->refine_x_hier[da->levelup - da->leveldown]; 1030897f7067SBarry Smith } 1031897f7067SBarry Smith dd2->refine_x_hier_n = dd->refine_x_hier_n; 1032897f7067SBarry Smith ierr = PetscMalloc1(dd2->refine_x_hier_n,&dd2->refine_x_hier);CHKERRQ(ierr); 1033897f7067SBarry Smith ierr = PetscMemcpy(dd2->refine_x_hier,dd->refine_x_hier,dd2->refine_x_hier_n*sizeof(PetscInt));CHKERRQ(ierr); 1034897f7067SBarry Smith } 1035897f7067SBarry Smith 1036897f7067SBarry Smith 103747c6ae99SBarry Smith /* copy vector type information */ 1038c0dedaeaSBarry Smith ierr = DMSetVecType(da2,da->vectype);CHKERRQ(ierr); 1039ddcf8b74SDave May 1040efd51863SBarry Smith dd2->lf = dd->lf; 1041efd51863SBarry Smith dd2->lj = dd->lj; 1042efd51863SBarry Smith 10436e87535bSJed Brown da2->leveldown = da->leveldown; 10446e87535bSJed Brown da2->levelup = da->levelup + 1; 10458865f1eaSKarl Rupp 10466e87535bSJed Brown ierr = DMSetUp(da2);CHKERRQ(ierr); 10476e87535bSJed Brown 1048ddcf8b74SDave May /* interpolate coordinates if they are set on the coarse grid */ 10496636e97aSMatthew G Knepley if (da->coordinates) { 1050ddcf8b74SDave May DM cdaf,cdac; 1051ddcf8b74SDave May Vec coordsc,coordsf; 1052ddcf8b74SDave May Mat II; 1053ddcf8b74SDave May 10546636e97aSMatthew G Knepley ierr = DMGetCoordinateDM(da,&cdac);CHKERRQ(ierr); 10556636e97aSMatthew G Knepley ierr = DMGetCoordinates(da,&coordsc);CHKERRQ(ierr); 10566636e97aSMatthew G Knepley ierr = DMGetCoordinateDM(da2,&cdaf);CHKERRQ(ierr); 1057b61d3410SDave May /* force creation of the coordinate vector */ 1058b61d3410SDave May ierr = DMDASetUniformCoordinates(da2,0.0,1.0,0.0,1.0,0.0,1.0);CHKERRQ(ierr); 10596636e97aSMatthew G Knepley ierr = DMGetCoordinates(da2,&coordsf);CHKERRQ(ierr); 10600298fd71SBarry Smith ierr = DMCreateInterpolation(cdac,cdaf,&II,NULL);CHKERRQ(ierr); 1061ddcf8b74SDave May ierr = MatInterpolate(II,coordsc,coordsf);CHKERRQ(ierr); 1062fcfd50ebSBarry Smith ierr = MatDestroy(&II);CHKERRQ(ierr); 1063ddcf8b74SDave May } 1064397b6216SJed Brown 1065f3141302SJed Brown for (i=0; i<da->bs; i++) { 1066f3141302SJed Brown const char *fieldname; 1067f3141302SJed Brown ierr = DMDAGetFieldName(da,i,&fieldname);CHKERRQ(ierr); 1068f3141302SJed Brown ierr = DMDASetFieldName(da2,i,fieldname);CHKERRQ(ierr); 1069f3141302SJed Brown } 1070397b6216SJed Brown 107147c6ae99SBarry Smith *daref = da2; 107247c6ae99SBarry Smith PetscFunctionReturn(0); 107347c6ae99SBarry Smith } 107447c6ae99SBarry Smith 1075397b6216SJed Brown 10767087cfbeSBarry Smith PetscErrorCode DMCoarsen_DA(DM da, MPI_Comm comm,DM *daref) 107747c6ae99SBarry Smith { 107847c6ae99SBarry Smith PetscErrorCode ierr; 1079c73cfb54SMatthew G. Knepley PetscInt M,N,P,i,dim; 10809a42bb27SBarry Smith DM da2; 108147c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data,*dd2; 108247c6ae99SBarry Smith 108347c6ae99SBarry Smith PetscFunctionBegin; 108447c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 108547c6ae99SBarry Smith PetscValidPointer(daref,3); 108647c6ae99SBarry Smith 1087c73cfb54SMatthew G. Knepley ierr = DMGetDimension(da, &dim);CHKERRQ(ierr); 1088bff4a2f0SMatthew G. Knepley if (dd->bx == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) { 1089397b6216SJed Brown M = dd->M / dd->coarsen_x; 109047c6ae99SBarry Smith } else { 1091397b6216SJed Brown M = 1 + (dd->M - 1) / dd->coarsen_x; 109247c6ae99SBarry Smith } 1093bff4a2f0SMatthew G. Knepley if (dd->by == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) { 1094c73cfb54SMatthew G. Knepley if (dim > 1) { 1095397b6216SJed Brown N = dd->N / dd->coarsen_y; 109647c6ae99SBarry Smith } else { 10971860e6e9SBarry Smith N = 1; 10981860e6e9SBarry Smith } 10991860e6e9SBarry Smith } else { 1100397b6216SJed Brown N = 1 + (dd->N - 1) / dd->coarsen_y; 110147c6ae99SBarry Smith } 1102bff4a2f0SMatthew G. Knepley if (dd->bz == DM_BOUNDARY_PERIODIC || dd->interptype == DMDA_Q0) { 1103c73cfb54SMatthew G. Knepley if (dim > 2) { 1104397b6216SJed Brown P = dd->P / dd->coarsen_z; 110547c6ae99SBarry Smith } else { 11061860e6e9SBarry Smith P = 1; 11071860e6e9SBarry Smith } 11081860e6e9SBarry Smith } else { 1109397b6216SJed Brown P = 1 + (dd->P - 1) / dd->coarsen_z; 111047c6ae99SBarry Smith } 1111ce94432eSBarry Smith ierr = DMDACreate(PetscObjectComm((PetscObject)da),&da2);CHKERRQ(ierr); 1112397b6216SJed Brown ierr = DMSetOptionsPrefix(da2,((PetscObject)da)->prefix);CHKERRQ(ierr); 1113c73cfb54SMatthew G. Knepley ierr = DMSetDimension(da2,dim);CHKERRQ(ierr); 1114397b6216SJed Brown ierr = DMDASetSizes(da2,M,N,P);CHKERRQ(ierr); 1115397b6216SJed Brown ierr = DMDASetNumProcs(da2,dd->m,dd->n,dd->p);CHKERRQ(ierr); 1116397b6216SJed Brown ierr = DMDASetBoundaryType(da2,dd->bx,dd->by,dd->bz);CHKERRQ(ierr); 1117397b6216SJed Brown ierr = DMDASetDof(da2,dd->w);CHKERRQ(ierr); 1118397b6216SJed Brown ierr = DMDASetStencilType(da2,dd->stencil_type);CHKERRQ(ierr); 1119397b6216SJed Brown ierr = DMDASetStencilWidth(da2,dd->s);CHKERRQ(ierr); 1120c73cfb54SMatthew G. Knepley if (dim == 3) { 11212be375d4SJed Brown PetscInt *lx,*ly,*lz; 1122dcca6d9dSJed Brown ierr = PetscMalloc3(dd->m,&lx,dd->n,&ly,dd->p,&lz);CHKERRQ(ierr); 1123bff4a2f0SMatthew 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); 1124bff4a2f0SMatthew 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); 1125bff4a2f0SMatthew 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); 1126397b6216SJed Brown ierr = DMDASetOwnershipRanges(da2,lx,ly,lz);CHKERRQ(ierr); 11272be375d4SJed Brown ierr = PetscFree3(lx,ly,lz);CHKERRQ(ierr); 1128c73cfb54SMatthew G. Knepley } else if (dim == 2) { 11292be375d4SJed Brown PetscInt *lx,*ly; 1130dcca6d9dSJed Brown ierr = PetscMalloc2(dd->m,&lx,dd->n,&ly);CHKERRQ(ierr); 1131bff4a2f0SMatthew 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); 1132bff4a2f0SMatthew 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); 11330298fd71SBarry Smith ierr = DMDASetOwnershipRanges(da2,lx,ly,NULL);CHKERRQ(ierr); 11342be375d4SJed Brown ierr = PetscFree2(lx,ly);CHKERRQ(ierr); 1135c73cfb54SMatthew G. Knepley } else if (dim == 1) { 11362be375d4SJed Brown PetscInt *lx; 1137785e854fSJed Brown ierr = PetscMalloc1(dd->m,&lx);CHKERRQ(ierr); 1138bff4a2f0SMatthew 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); 11390298fd71SBarry Smith ierr = DMDASetOwnershipRanges(da2,lx,NULL,NULL);CHKERRQ(ierr); 11402be375d4SJed Brown ierr = PetscFree(lx);CHKERRQ(ierr); 114147c6ae99SBarry Smith } 114247c6ae99SBarry Smith dd2 = (DM_DA*)da2->data; 114347c6ae99SBarry Smith 11444dcab191SBarry Smith /* allow overloaded (user replaced) operations to be inherited by refinement clones; why are only some inherited and not all? */ 114525296bd5SBarry Smith /* da2->ops->createinterpolation = da->ops->createinterpolation; copying this one causes trouble for DMSetVI */ 114625296bd5SBarry Smith da2->ops->creatematrix = da->ops->creatematrix; 114747c6ae99SBarry Smith da2->ops->getcoloring = da->ops->getcoloring; 114847c6ae99SBarry Smith dd2->interptype = dd->interptype; 114947c6ae99SBarry Smith 115047c6ae99SBarry Smith /* copy fill information if given */ 115147c6ae99SBarry Smith if (dd->dfill) { 1152854ce69bSBarry Smith ierr = PetscMalloc1(dd->dfill[dd->w]+dd->w+1,&dd2->dfill);CHKERRQ(ierr); 115347c6ae99SBarry Smith ierr = PetscMemcpy(dd2->dfill,dd->dfill,(dd->dfill[dd->w]+dd->w+1)*sizeof(PetscInt));CHKERRQ(ierr); 115447c6ae99SBarry Smith } 115547c6ae99SBarry Smith if (dd->ofill) { 1156854ce69bSBarry Smith ierr = PetscMalloc1(dd->ofill[dd->w]+dd->w+1,&dd2->ofill);CHKERRQ(ierr); 115747c6ae99SBarry Smith ierr = PetscMemcpy(dd2->ofill,dd->ofill,(dd->ofill[dd->w]+dd->w+1)*sizeof(PetscInt));CHKERRQ(ierr); 115847c6ae99SBarry Smith } 115947c6ae99SBarry Smith /* copy the refine information */ 1160397b6216SJed Brown dd2->coarsen_x = dd2->refine_x = dd->coarsen_x; 1161397b6216SJed Brown dd2->coarsen_y = dd2->refine_y = dd->coarsen_y; 1162397b6216SJed Brown dd2->coarsen_z = dd2->refine_z = dd->coarsen_z; 116347c6ae99SBarry Smith 1164897f7067SBarry Smith if (dd->refine_z_hier) { 1165897f7067SBarry Smith if (da->levelup - da->leveldown -1 > -1 && da->levelup - da->leveldown - 1< dd->refine_z_hier_n) { 1166897f7067SBarry Smith dd2->refine_z = dd->refine_z_hier[da->levelup - da->leveldown - 1]; 1167897f7067SBarry Smith } 1168897f7067SBarry Smith if (da->levelup - da->leveldown - 2 > -1 && da->levelup - da->leveldown - 2 < dd->refine_z_hier_n) { 1169897f7067SBarry Smith dd2->coarsen_z = dd->refine_z_hier[da->levelup - da->leveldown - 2]; 1170897f7067SBarry Smith } 1171897f7067SBarry Smith dd2->refine_z_hier_n = dd->refine_z_hier_n; 1172897f7067SBarry Smith ierr = PetscMalloc1(dd2->refine_z_hier_n,&dd2->refine_z_hier);CHKERRQ(ierr); 1173897f7067SBarry Smith ierr = PetscMemcpy(dd2->refine_z_hier,dd->refine_z_hier,dd2->refine_z_hier_n*sizeof(PetscInt));CHKERRQ(ierr); 1174897f7067SBarry Smith } 1175897f7067SBarry Smith if (dd->refine_y_hier) { 1176897f7067SBarry Smith if (da->levelup - da->leveldown - 1 > -1 && da->levelup - da->leveldown - 1< dd->refine_y_hier_n) { 1177897f7067SBarry Smith dd2->refine_y = dd->refine_y_hier[da->levelup - da->leveldown - 1]; 1178897f7067SBarry Smith } 1179897f7067SBarry Smith if (da->levelup - da->leveldown - 2 > -1 && da->levelup - da->leveldown - 2 < dd->refine_y_hier_n) { 1180897f7067SBarry Smith dd2->coarsen_y = dd->refine_y_hier[da->levelup - da->leveldown - 2]; 1181897f7067SBarry Smith } 1182897f7067SBarry Smith dd2->refine_y_hier_n = dd->refine_y_hier_n; 1183897f7067SBarry Smith ierr = PetscMalloc1(dd2->refine_y_hier_n,&dd2->refine_y_hier);CHKERRQ(ierr); 1184897f7067SBarry Smith ierr = PetscMemcpy(dd2->refine_y_hier,dd->refine_y_hier,dd2->refine_y_hier_n*sizeof(PetscInt));CHKERRQ(ierr); 1185897f7067SBarry Smith } 1186897f7067SBarry Smith if (dd->refine_x_hier) { 1187897f7067SBarry Smith if (da->levelup - da->leveldown - 1 > -1 && da->levelup - da->leveldown - 1 < dd->refine_x_hier_n) { 1188897f7067SBarry Smith dd2->refine_x = dd->refine_x_hier[da->levelup - da->leveldown - 1]; 1189897f7067SBarry Smith } 1190897f7067SBarry Smith if (da->levelup - da->leveldown - 2 > -1 && da->levelup - da->leveldown - 2 < dd->refine_x_hier_n) { 1191897f7067SBarry Smith dd2->coarsen_x = dd->refine_x_hier[da->levelup - da->leveldown - 2]; 1192897f7067SBarry Smith } 1193897f7067SBarry Smith dd2->refine_x_hier_n = dd->refine_x_hier_n; 1194897f7067SBarry Smith ierr = PetscMalloc1(dd2->refine_x_hier_n,&dd2->refine_x_hier);CHKERRQ(ierr); 1195897f7067SBarry Smith ierr = PetscMemcpy(dd2->refine_x_hier,dd->refine_x_hier,dd2->refine_x_hier_n*sizeof(PetscInt));CHKERRQ(ierr); 1196897f7067SBarry Smith } 1197897f7067SBarry Smith 119847c6ae99SBarry Smith /* copy vector type information */ 1199c0dedaeaSBarry Smith ierr = DMSetVecType(da2,da->vectype);CHKERRQ(ierr); 120047c6ae99SBarry Smith 1201644e2e5bSBarry Smith dd2->lf = dd->lf; 1202644e2e5bSBarry Smith dd2->lj = dd->lj; 1203644e2e5bSBarry Smith 12046e87535bSJed Brown da2->leveldown = da->leveldown + 1; 12056e87535bSJed Brown da2->levelup = da->levelup; 12068865f1eaSKarl Rupp 12076e87535bSJed Brown ierr = DMSetUp(da2);CHKERRQ(ierr); 12086e87535bSJed Brown 1209ddcf8b74SDave May /* inject coordinates if they are set on the fine grid */ 12106636e97aSMatthew G Knepley if (da->coordinates) { 1211ddcf8b74SDave May DM cdaf,cdac; 1212ddcf8b74SDave May Vec coordsc,coordsf; 12136dbf9973SLawrence Mitchell Mat inject; 12146dbf9973SLawrence Mitchell VecScatter vscat; 1215ddcf8b74SDave May 12166636e97aSMatthew G Knepley ierr = DMGetCoordinateDM(da,&cdaf);CHKERRQ(ierr); 12176636e97aSMatthew G Knepley ierr = DMGetCoordinates(da,&coordsf);CHKERRQ(ierr); 12186636e97aSMatthew G Knepley ierr = DMGetCoordinateDM(da2,&cdac);CHKERRQ(ierr); 1219b61d3410SDave May /* force creation of the coordinate vector */ 1220b61d3410SDave May ierr = DMDASetUniformCoordinates(da2,0.0,1.0,0.0,1.0,0.0,1.0);CHKERRQ(ierr); 12216636e97aSMatthew G Knepley ierr = DMGetCoordinates(da2,&coordsc);CHKERRQ(ierr); 1222ddcf8b74SDave May 1223e727c939SJed Brown ierr = DMCreateInjection(cdac,cdaf,&inject);CHKERRQ(ierr); 12246dbf9973SLawrence Mitchell ierr = MatScatterGetVecScatter(inject,&vscat);CHKERRQ(ierr); 12256dbf9973SLawrence Mitchell ierr = VecScatterBegin(vscat,coordsf,coordsc,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12266dbf9973SLawrence Mitchell ierr = VecScatterEnd(vscat,coordsf,coordsc,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12276dbf9973SLawrence Mitchell ierr = MatDestroy(&inject);CHKERRQ(ierr); 1228ddcf8b74SDave May } 1229f98405f7SJed Brown 1230f98405f7SJed Brown for (i=0; i<da->bs; i++) { 1231f98405f7SJed Brown const char *fieldname; 1232f98405f7SJed Brown ierr = DMDAGetFieldName(da,i,&fieldname);CHKERRQ(ierr); 1233f98405f7SJed Brown ierr = DMDASetFieldName(da2,i,fieldname);CHKERRQ(ierr); 1234f98405f7SJed Brown } 1235f98405f7SJed Brown 123647c6ae99SBarry Smith *daref = da2; 123747c6ae99SBarry Smith PetscFunctionReturn(0); 123847c6ae99SBarry Smith } 123947c6ae99SBarry Smith 12407087cfbeSBarry Smith PetscErrorCode DMRefineHierarchy_DA(DM da,PetscInt nlevels,DM daf[]) 124147c6ae99SBarry Smith { 124247c6ae99SBarry Smith PetscErrorCode ierr; 124347c6ae99SBarry Smith PetscInt i,n,*refx,*refy,*refz; 124447c6ae99SBarry Smith 124547c6ae99SBarry Smith PetscFunctionBegin; 124647c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 1247ce94432eSBarry Smith if (nlevels < 0) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative"); 124847c6ae99SBarry Smith if (nlevels == 0) PetscFunctionReturn(0); 124947c6ae99SBarry Smith PetscValidPointer(daf,3); 125047c6ae99SBarry Smith 1251aa219208SBarry Smith /* Get refinement factors, defaults taken from the coarse DMDA */ 1252dcca6d9dSJed Brown ierr = PetscMalloc3(nlevels,&refx,nlevels,&refy,nlevels,&refz);CHKERRQ(ierr); 125347c6ae99SBarry Smith for (i=0; i<nlevels; i++) { 1254aa219208SBarry Smith ierr = DMDAGetRefinementFactor(da,&refx[i],&refy[i],&refz[i]);CHKERRQ(ierr); 125547c6ae99SBarry Smith } 125647c6ae99SBarry Smith n = nlevels; 1257c5929fdfSBarry Smith ierr = PetscOptionsGetIntArray(((PetscObject)da)->options,((PetscObject)da)->prefix,"-da_refine_hierarchy_x",refx,&n,NULL);CHKERRQ(ierr); 125847c6ae99SBarry Smith n = nlevels; 1259c5929fdfSBarry Smith ierr = PetscOptionsGetIntArray(((PetscObject)da)->options,((PetscObject)da)->prefix,"-da_refine_hierarchy_y",refy,&n,NULL);CHKERRQ(ierr); 126047c6ae99SBarry Smith n = nlevels; 1261c5929fdfSBarry Smith ierr = PetscOptionsGetIntArray(((PetscObject)da)->options,((PetscObject)da)->prefix,"-da_refine_hierarchy_z",refz,&n,NULL);CHKERRQ(ierr); 126247c6ae99SBarry Smith 1263aa219208SBarry Smith ierr = DMDASetRefinementFactor(da,refx[0],refy[0],refz[0]);CHKERRQ(ierr); 1264ce94432eSBarry Smith ierr = DMRefine(da,PetscObjectComm((PetscObject)da),&daf[0]);CHKERRQ(ierr); 126547c6ae99SBarry Smith for (i=1; i<nlevels; i++) { 1266aa219208SBarry Smith ierr = DMDASetRefinementFactor(daf[i-1],refx[i],refy[i],refz[i]);CHKERRQ(ierr); 1267ce94432eSBarry Smith ierr = DMRefine(daf[i-1],PetscObjectComm((PetscObject)da),&daf[i]);CHKERRQ(ierr); 126847c6ae99SBarry Smith } 126947c6ae99SBarry Smith ierr = PetscFree3(refx,refy,refz);CHKERRQ(ierr); 127047c6ae99SBarry Smith PetscFunctionReturn(0); 127147c6ae99SBarry Smith } 127247c6ae99SBarry Smith 12737087cfbeSBarry Smith PetscErrorCode DMCoarsenHierarchy_DA(DM da,PetscInt nlevels,DM dac[]) 127447c6ae99SBarry Smith { 127547c6ae99SBarry Smith PetscErrorCode ierr; 127647c6ae99SBarry Smith PetscInt i; 127747c6ae99SBarry Smith 127847c6ae99SBarry Smith PetscFunctionBegin; 127947c6ae99SBarry Smith PetscValidHeaderSpecific(da,DM_CLASSID,1); 1280ce94432eSBarry Smith if (nlevels < 0) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_ARG_OUTOFRANGE,"nlevels cannot be negative"); 128147c6ae99SBarry Smith if (nlevels == 0) PetscFunctionReturn(0); 128247c6ae99SBarry Smith PetscValidPointer(dac,3); 1283ce94432eSBarry Smith ierr = DMCoarsen(da,PetscObjectComm((PetscObject)da),&dac[0]);CHKERRQ(ierr); 128447c6ae99SBarry Smith for (i=1; i<nlevels; i++) { 1285ce94432eSBarry Smith ierr = DMCoarsen(dac[i-1],PetscObjectComm((PetscObject)da),&dac[i]);CHKERRQ(ierr); 128647c6ae99SBarry Smith } 128747c6ae99SBarry Smith PetscFunctionReturn(0); 128847c6ae99SBarry Smith } 128962197512SBarry Smith 129062197512SBarry Smith #include <petscgll.h> 129162197512SBarry Smith 129262197512SBarry Smith PetscErrorCode DMDASetGLLCoordinates_1d(DM dm,PetscGLL *gll) 129362197512SBarry Smith { 129462197512SBarry Smith PetscErrorCode ierr; 129562197512SBarry Smith PetscInt i,j,n = gll->n,xs,xn,q; 129662197512SBarry Smith PetscScalar *xx; 129762197512SBarry Smith PetscReal h; 129862197512SBarry Smith Vec x; 129962197512SBarry Smith DM_DA *da = (DM_DA*)dm->data; 130062197512SBarry Smith 130162197512SBarry Smith PetscFunctionBegin; 130262197512SBarry Smith if (da->bx != DM_BOUNDARY_PERIODIC) { 130362197512SBarry Smith ierr = DMDAGetInfo(dm,NULL,&q,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);CHKERRQ(ierr); 130462197512SBarry Smith q = (q-1)/(n-1); /* number of spectral elements */ 130562197512SBarry Smith h = 2.0/q; 130662197512SBarry Smith ierr = DMDAGetCorners(dm,&xs,NULL,NULL,&xn,NULL,NULL);CHKERRQ(ierr); 130762197512SBarry Smith xs = xs/(n-1); 130862197512SBarry Smith xn = xn/(n-1); 130962197512SBarry Smith ierr = DMDASetUniformCoordinates(dm,-1.,1.,0.,0.,0.,0.);CHKERRQ(ierr); 131062197512SBarry Smith ierr = DMGetCoordinates(dm,&x);CHKERRQ(ierr); 131162197512SBarry Smith ierr = DMDAVecGetArray(dm,x,&xx);CHKERRQ(ierr); 131262197512SBarry Smith 131362197512SBarry Smith /* loop over local spectral elements */ 131462197512SBarry Smith for (j=xs; j<xs+xn; j++) { 131562197512SBarry Smith /* 131662197512SBarry Smith Except for the first process, each process starts on the second GLL point of the first element on that process 131762197512SBarry Smith */ 131862197512SBarry Smith for (i= (j == xs && xs > 0)? 1 : 0; i<n; i++) { 131962197512SBarry Smith xx[j*(n-1) + i] = -1.0 + h*j + h*(gll->nodes[i]+1.0)/2.; 132062197512SBarry Smith } 132162197512SBarry Smith } 132262197512SBarry Smith ierr = DMDAVecRestoreArray(dm,x,&xx);CHKERRQ(ierr); 132362197512SBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Not yet implemented for periodic"); 132462197512SBarry Smith PetscFunctionReturn(0); 132562197512SBarry Smith } 132662197512SBarry Smith 1327*1fd49c25SBarry Smith /*@ 132862197512SBarry Smith 132962197512SBarry 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 133062197512SBarry Smith 133162197512SBarry Smith Collective on DM 133262197512SBarry Smith 133362197512SBarry Smith Input Parameters: 133462197512SBarry Smith + da - the DMDA object 133562197512SBarry Smith - gll - the GLL object 133662197512SBarry Smith 133762197512SBarry Smith Notes: the parallel decomposition of grid points must correspond to the degree of the GLL. That is, the number of grid points 133862197512SBarry Smith on each process much be divisible by the number of GLL elements needed per process. This depends on whether the DM is 133962197512SBarry Smith periodic or not. 134062197512SBarry Smith 1341edc382c3SSatish Balay Level: advanced 1342edc382c3SSatish Balay 134362197512SBarry Smith .seealso: DMDACreate(), PetscGLLCreate(), DMGetCoordinates() 134462197512SBarry Smith @*/ 134562197512SBarry Smith PetscErrorCode DMDASetGLLCoordinates(DM da,PetscGLL *gll) 134662197512SBarry Smith { 134762197512SBarry Smith PetscErrorCode ierr; 134862197512SBarry Smith 134962197512SBarry Smith PetscFunctionBegin; 135062197512SBarry Smith if (da->dim == 1) { 135162197512SBarry Smith ierr = DMDASetGLLCoordinates_1d(da,gll);CHKERRQ(ierr); 135262197512SBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Not yet implemented for 2 or 3d"); 135362197512SBarry Smith PetscFunctionReturn(0); 135462197512SBarry Smith } 1355