xref: /petsc/src/dm/impls/da/daindex.c (revision 9db3d8bc4b77619980d159f620b624bbd12cb695)
147c6ae99SBarry Smith 
247c6ae99SBarry Smith /*
347c6ae99SBarry Smith   Code for manipulating distributed regular arrays in parallel.
447c6ae99SBarry Smith */
547c6ae99SBarry Smith 
64035e84dSBarry Smith #include <petsc-private/dmdaimpl.h>    /*I   "petscdmda.h"   I*/
747c6ae99SBarry Smith 
847c6ae99SBarry Smith #undef __FUNCT__
9aa219208SBarry Smith #define __FUNCT__ "DMDAGetNatural_Private"
1047c6ae99SBarry Smith /*
1147c6ae99SBarry Smith    Gets the natural number for each global number on the process.
1247c6ae99SBarry Smith 
13aa219208SBarry Smith    Used by DMDAGetAO() and DMDAGlobalToNatural_Create()
1447c6ae99SBarry Smith */
15aa219208SBarry Smith PetscErrorCode DMDAGetNatural_Private(DM da,PetscInt *outNlocal,IS *isnatural)
1647c6ae99SBarry Smith {
1747c6ae99SBarry Smith   PetscErrorCode ierr;
18c73cfb54SMatthew G. Knepley   PetscInt       Nlocal,i,j,k,*lidx,lict = 0,dim = da->dim;
1947c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
2047c6ae99SBarry Smith 
2147c6ae99SBarry Smith   PetscFunctionBegin;
2247c6ae99SBarry Smith   Nlocal = (dd->xe-dd->xs);
23c73cfb54SMatthew G. Knepley   if (dim > 1) Nlocal *= (dd->ye-dd->ys);
24c73cfb54SMatthew G. Knepley   if (dim > 2) Nlocal *= (dd->ze-dd->zs);
2547c6ae99SBarry Smith 
26785e854fSJed Brown   ierr = PetscMalloc1(Nlocal,&lidx);CHKERRQ(ierr);
2747c6ae99SBarry Smith 
28c73cfb54SMatthew G. Knepley   if (dim == 1) {
2947c6ae99SBarry Smith     for (i=dd->xs; i<dd->xe; i++) {
3047c6ae99SBarry Smith       /*  global number in natural ordering */
3147c6ae99SBarry Smith       lidx[lict++] = i;
3247c6ae99SBarry Smith     }
33c73cfb54SMatthew G. Knepley   } else if (dim == 2) {
3447c6ae99SBarry Smith     for (j=dd->ys; j<dd->ye; j++) {
3547c6ae99SBarry Smith       for (i=dd->xs; i<dd->xe; i++) {
3647c6ae99SBarry Smith         /*  global number in natural ordering */
3747c6ae99SBarry Smith         lidx[lict++] = i + j*dd->M*dd->w;
3847c6ae99SBarry Smith       }
3947c6ae99SBarry Smith     }
40c73cfb54SMatthew G. Knepley   } else if (dim == 3) {
4147c6ae99SBarry Smith     for (k=dd->zs; k<dd->ze; k++) {
4247c6ae99SBarry Smith       for (j=dd->ys; j<dd->ye; j++) {
4347c6ae99SBarry Smith         for (i=dd->xs; i<dd->xe; i++) {
4447c6ae99SBarry Smith           lidx[lict++] = i + j*dd->M*dd->w + k*dd->M*dd->N*dd->w;
4547c6ae99SBarry Smith         }
4647c6ae99SBarry Smith       }
4747c6ae99SBarry Smith     }
4847c6ae99SBarry Smith   }
4947c6ae99SBarry Smith   *outNlocal = Nlocal;
50ce94432eSBarry Smith   ierr       = ISCreateGeneral(PetscObjectComm((PetscObject)da),Nlocal,lidx,PETSC_OWN_POINTER,isnatural);CHKERRQ(ierr);
5147c6ae99SBarry Smith   PetscFunctionReturn(0);
5247c6ae99SBarry Smith }
5347c6ae99SBarry Smith 
5447c6ae99SBarry Smith #undef __FUNCT__
55*9db3d8bcSStefano Zampini #define __FUNCT__ "DMDASetAOType"
56*9db3d8bcSStefano Zampini /*@
57*9db3d8bcSStefano Zampini    DMDASetAOType - Sets the type of application ordering for a distributed array.
58*9db3d8bcSStefano Zampini 
59*9db3d8bcSStefano Zampini    Collective on DMDA
60*9db3d8bcSStefano Zampini 
61*9db3d8bcSStefano Zampini    Input Parameter:
62*9db3d8bcSStefano Zampini .  da - the distributed array
63*9db3d8bcSStefano Zampini .  aotype - type of AO
64*9db3d8bcSStefano Zampini 
65*9db3d8bcSStefano Zampini    Output Parameters:
66*9db3d8bcSStefano Zampini 
67*9db3d8bcSStefano Zampini    Level: intermediate
68*9db3d8bcSStefano Zampini 
69*9db3d8bcSStefano Zampini    Notes:
70*9db3d8bcSStefano Zampini    It will generate and error if an AO has already been obtained with a call to DMDAGetAO and the user sets a different AOType
71*9db3d8bcSStefano Zampini 
72*9db3d8bcSStefano Zampini .keywords: distributed array, get, global, indices, local-to-global
73*9db3d8bcSStefano Zampini 
74*9db3d8bcSStefano Zampini .seealso: DMDACreate2d(), DMDAGetAO(), DMDAGetGhostCorners(), DMDAGetCorners(), DMDALocalToGlocal()
75*9db3d8bcSStefano Zampini           DMGlobalToLocalBegin(), DMGlobalToLocalEnd(), DMLocalToLocalBegin(), DMLocalToLocalEnd(), DMDAGetGlobalIndices(), DMDAGetOwnershipRanges(),
76*9db3d8bcSStefano Zampini           AO, AOPetscToApplication(), AOApplicationToPetsc()
77*9db3d8bcSStefano Zampini @*/
78*9db3d8bcSStefano Zampini PetscErrorCode  DMDASetAOType(DM da,AOType aotype)
79*9db3d8bcSStefano Zampini {
80*9db3d8bcSStefano Zampini   DM_DA          *dd;
81*9db3d8bcSStefano Zampini   PetscBool      isdmda;
82*9db3d8bcSStefano Zampini   PetscErrorCode ierr;
83*9db3d8bcSStefano Zampini 
84*9db3d8bcSStefano Zampini   PetscFunctionBegin;
85*9db3d8bcSStefano Zampini   PetscValidHeaderSpecific(da,DM_CLASSID,1);
86*9db3d8bcSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)da,DMDA,&isdmda);CHKERRQ(ierr);
87*9db3d8bcSStefano Zampini   if (!isdmda) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Requires a DMDA as input");
88*9db3d8bcSStefano Zampini   /* now we can safely dereference */
89*9db3d8bcSStefano Zampini   dd = (DM_DA*)da->data;
90*9db3d8bcSStefano Zampini   if (dd->ao) { /* check if the already computed AO has the same type as requested */
91*9db3d8bcSStefano Zampini     PetscBool match;
92*9db3d8bcSStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)dd->ao,aotype,&match);CHKERRQ(ierr);
93*9db3d8bcSStefano Zampini     if (!match) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Cannot change AO type");
94*9db3d8bcSStefano Zampini     PetscFunctionReturn(0);
95*9db3d8bcSStefano Zampini   }
96*9db3d8bcSStefano Zampini   ierr = PetscFree(dd->aotype);CHKERRQ(ierr);
97*9db3d8bcSStefano Zampini   ierr = PetscStrallocpy(aotype,(char**)&dd->aotype);CHKERRQ(ierr);
98*9db3d8bcSStefano Zampini   PetscFunctionReturn(0);
99*9db3d8bcSStefano Zampini }
100*9db3d8bcSStefano Zampini 
101*9db3d8bcSStefano Zampini #undef __FUNCT__
102aa219208SBarry Smith #define __FUNCT__ "DMDAGetAO"
10347c6ae99SBarry Smith /*@
104aa219208SBarry Smith    DMDAGetAO - Gets the application ordering context for a distributed array.
10547c6ae99SBarry Smith 
106aa219208SBarry Smith    Collective on DMDA
10747c6ae99SBarry Smith 
10847c6ae99SBarry Smith    Input Parameter:
10947c6ae99SBarry Smith .  da - the distributed array
11047c6ae99SBarry Smith 
11147c6ae99SBarry Smith    Output Parameters:
112aa219208SBarry Smith .  ao - the application ordering context for DMDAs
11347c6ae99SBarry Smith 
11447c6ae99SBarry Smith    Level: intermediate
11547c6ae99SBarry Smith 
11647c6ae99SBarry Smith    Notes:
11747c6ae99SBarry Smith    In this case, the AO maps to the natural grid ordering that would be used
118aa219208SBarry Smith    for the DMDA if only 1 processor were employed (ordering most rapidly in the
11947c6ae99SBarry Smith    x-direction, then y, then z).  Multiple degrees of freedom are numbered
12047c6ae99SBarry Smith    for each node (rather than 1 component for the whole grid, then the next
12147c6ae99SBarry Smith    component, etc.)
12247c6ae99SBarry Smith 
12347c6ae99SBarry Smith .keywords: distributed array, get, global, indices, local-to-global
12447c6ae99SBarry Smith 
125*9db3d8bcSStefano Zampini .seealso: DMDACreate2d(), DMDASetAOType(), DMDAGetGhostCorners(), DMDAGetCorners(), DMDALocalToGlocal()
126565245c5SBarry Smith           DMGlobalToLocalBegin(), DMGlobalToLocalEnd(), DMLocalToLocalBegin(), DMLocalToLocalEnd(),  DMDAGetOwnershipRanges(),
12747c6ae99SBarry Smith           AO, AOPetscToApplication(), AOApplicationToPetsc()
12847c6ae99SBarry Smith @*/
1297087cfbeSBarry Smith PetscErrorCode  DMDAGetAO(DM da,AO *ao)
13047c6ae99SBarry Smith {
13163868d81SStefano Zampini   DM_DA          *dd;
13263868d81SStefano Zampini   PetscBool      isdmda;
13363868d81SStefano Zampini   PetscErrorCode ierr;
13447c6ae99SBarry Smith 
13547c6ae99SBarry Smith   PetscFunctionBegin;
13647c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
13747c6ae99SBarry Smith   PetscValidPointer(ao,2);
13863868d81SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)da,DMDA,&isdmda);CHKERRQ(ierr);
13963868d81SStefano Zampini   if (!isdmda) SETERRQ(PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Requires a DMDA as input");
14063868d81SStefano Zampini   /* now we can safely dereference */
14163868d81SStefano Zampini   dd = (DM_DA*)da->data;
14247c6ae99SBarry Smith 
14347c6ae99SBarry Smith   /*
14447c6ae99SBarry Smith      Build the natural ordering to PETSc ordering mappings.
14547c6ae99SBarry Smith   */
14647c6ae99SBarry Smith   if (!dd->ao) {
14747c6ae99SBarry Smith     IS             ispetsc,isnatural;
14847c6ae99SBarry Smith     PetscErrorCode ierr;
14947c6ae99SBarry Smith     PetscInt       Nlocal;
15047c6ae99SBarry Smith 
151aa219208SBarry Smith     ierr = DMDAGetNatural_Private(da,&Nlocal,&isnatural);CHKERRQ(ierr);
152ce94432eSBarry Smith     ierr = ISCreateStride(PetscObjectComm((PetscObject)da),Nlocal,dd->base,1,&ispetsc);CHKERRQ(ierr);
153ee120560SStefano Zampini     ierr = AOCreate(PetscObjectComm((PetscObject)da),&dd->ao);CHKERRQ(ierr);
154ee120560SStefano Zampini     ierr = AOSetIS(dd->ao,isnatural,ispetsc);CHKERRQ(ierr);
15552a64b67SStefano Zampini     ierr = AOSetType(dd->ao,dd->aotype);CHKERRQ(ierr);
1563bb1ff40SBarry Smith     ierr = PetscLogObjectParent((PetscObject)da,(PetscObject)dd->ao);CHKERRQ(ierr);
157fcfd50ebSBarry Smith     ierr = ISDestroy(&ispetsc);CHKERRQ(ierr);
158fcfd50ebSBarry Smith     ierr = ISDestroy(&isnatural);CHKERRQ(ierr);
15947c6ae99SBarry Smith   }
16047c6ae99SBarry Smith   *ao = dd->ao;
16147c6ae99SBarry Smith   PetscFunctionReturn(0);
16247c6ae99SBarry Smith }
16347c6ae99SBarry Smith 
1648ea3bf28SBarry Smith 
165