xref: /petsc/src/dm/impls/da/daindex.c (revision 9566063d113dddea24716c546802770db7481bc0)
147c6ae99SBarry Smith 
247c6ae99SBarry Smith /*
347c6ae99SBarry Smith   Code for manipulating distributed regular arrays in parallel.
447c6ae99SBarry Smith */
547c6ae99SBarry Smith 
6af0996ceSBarry Smith #include <petsc/private/dmdaimpl.h>    /*I   "petscdmda.h"   I*/
747c6ae99SBarry Smith 
847c6ae99SBarry Smith /*
947c6ae99SBarry Smith    Gets the natural number for each global number on the process.
1047c6ae99SBarry Smith 
11aa219208SBarry Smith    Used by DMDAGetAO() and DMDAGlobalToNatural_Create()
1247c6ae99SBarry Smith */
13aa219208SBarry Smith PetscErrorCode DMDAGetNatural_Private(DM da,PetscInt *outNlocal,IS *isnatural)
1447c6ae99SBarry Smith {
15c73cfb54SMatthew G. Knepley   PetscInt       Nlocal,i,j,k,*lidx,lict = 0,dim = da->dim;
1647c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
1747c6ae99SBarry Smith 
1847c6ae99SBarry Smith   PetscFunctionBegin;
1947c6ae99SBarry Smith   Nlocal = (dd->xe-dd->xs);
20c73cfb54SMatthew G. Knepley   if (dim > 1) Nlocal *= (dd->ye-dd->ys);
21c73cfb54SMatthew G. Knepley   if (dim > 2) Nlocal *= (dd->ze-dd->zs);
2247c6ae99SBarry Smith 
23*9566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nlocal,&lidx));
2447c6ae99SBarry Smith 
25c73cfb54SMatthew G. Knepley   if (dim == 1) {
2647c6ae99SBarry Smith     for (i=dd->xs; i<dd->xe; i++) {
2747c6ae99SBarry Smith       /*  global number in natural ordering */
2847c6ae99SBarry Smith       lidx[lict++] = i;
2947c6ae99SBarry Smith     }
30c73cfb54SMatthew G. Knepley   } else if (dim == 2) {
3147c6ae99SBarry Smith     for (j=dd->ys; j<dd->ye; j++) {
3247c6ae99SBarry Smith       for (i=dd->xs; i<dd->xe; i++) {
3347c6ae99SBarry Smith         /*  global number in natural ordering */
3447c6ae99SBarry Smith         lidx[lict++] = i + j*dd->M*dd->w;
3547c6ae99SBarry Smith       }
3647c6ae99SBarry Smith     }
37c73cfb54SMatthew G. Knepley   } else if (dim == 3) {
3847c6ae99SBarry Smith     for (k=dd->zs; k<dd->ze; k++) {
3947c6ae99SBarry Smith       for (j=dd->ys; j<dd->ye; j++) {
4047c6ae99SBarry Smith         for (i=dd->xs; i<dd->xe; i++) {
4147c6ae99SBarry Smith           lidx[lict++] = i + j*dd->M*dd->w + k*dd->M*dd->N*dd->w;
4247c6ae99SBarry Smith         }
4347c6ae99SBarry Smith       }
4447c6ae99SBarry Smith     }
4547c6ae99SBarry Smith   }
4647c6ae99SBarry Smith   *outNlocal = Nlocal;
47*9566063dSJacob Faibussowitsch   PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)da),Nlocal,lidx,PETSC_OWN_POINTER,isnatural));
4847c6ae99SBarry Smith   PetscFunctionReturn(0);
4947c6ae99SBarry Smith }
5047c6ae99SBarry Smith 
5192e66395SSatish Balay /*@C
529db3d8bcSStefano Zampini    DMDASetAOType - Sets the type of application ordering for a distributed array.
539db3d8bcSStefano Zampini 
54d083f849SBarry Smith    Collective on da
559db3d8bcSStefano Zampini 
56d8d19677SJose E. Roman    Input Parameters:
57a2b725a8SWilliam Gropp +  da - the distributed array
58a2b725a8SWilliam Gropp -  aotype - type of AO
599db3d8bcSStefano Zampini 
609db3d8bcSStefano Zampini    Output Parameters:
619db3d8bcSStefano Zampini 
629db3d8bcSStefano Zampini    Level: intermediate
639db3d8bcSStefano Zampini 
649db3d8bcSStefano Zampini    Notes:
659db3d8bcSStefano 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
669db3d8bcSStefano Zampini 
679df75925SJed Brown .seealso: DMDACreate2d(), DMDAGetAO(), DMDAGetGhostCorners(), DMDAGetCorners(), DMLocalToGlobal()
689db3d8bcSStefano Zampini           DMGlobalToLocalBegin(), DMGlobalToLocalEnd(), DMLocalToLocalBegin(), DMLocalToLocalEnd(), DMDAGetGlobalIndices(), DMDAGetOwnershipRanges(),
699db3d8bcSStefano Zampini           AO, AOPetscToApplication(), AOApplicationToPetsc()
709db3d8bcSStefano Zampini @*/
719db3d8bcSStefano Zampini PetscErrorCode  DMDASetAOType(DM da,AOType aotype)
729db3d8bcSStefano Zampini {
739db3d8bcSStefano Zampini   DM_DA          *dd;
749db3d8bcSStefano Zampini   PetscBool      isdmda;
759db3d8bcSStefano Zampini 
769db3d8bcSStefano Zampini   PetscFunctionBegin;
77a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA);
78*9566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)da,DMDA,&isdmda));
797a8be351SBarry Smith   PetscCheck(isdmda,PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Requires a DMDA as input");
809db3d8bcSStefano Zampini   /* now we can safely dereference */
819db3d8bcSStefano Zampini   dd = (DM_DA*)da->data;
829db3d8bcSStefano Zampini   if (dd->ao) { /* check if the already computed AO has the same type as requested */
839db3d8bcSStefano Zampini     PetscBool match;
84*9566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)dd->ao,aotype,&match));
857a8be351SBarry Smith     PetscCheck(match,PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Cannot change AO type");
869db3d8bcSStefano Zampini     PetscFunctionReturn(0);
879db3d8bcSStefano Zampini   }
88*9566063dSJacob Faibussowitsch   PetscCall(PetscFree(dd->aotype));
89*9566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(aotype,(char**)&dd->aotype));
909db3d8bcSStefano Zampini   PetscFunctionReturn(0);
919db3d8bcSStefano Zampini }
929db3d8bcSStefano Zampini 
9347c6ae99SBarry Smith /*@
94aa219208SBarry Smith    DMDAGetAO - Gets the application ordering context for a distributed array.
9547c6ae99SBarry Smith 
96d083f849SBarry Smith    Collective on da
9747c6ae99SBarry Smith 
9847c6ae99SBarry Smith    Input Parameter:
9947c6ae99SBarry Smith .  da - the distributed array
10047c6ae99SBarry Smith 
10147c6ae99SBarry Smith    Output Parameters:
102aa219208SBarry Smith .  ao - the application ordering context for DMDAs
10347c6ae99SBarry Smith 
10447c6ae99SBarry Smith    Level: intermediate
10547c6ae99SBarry Smith 
10647c6ae99SBarry Smith    Notes:
10747c6ae99SBarry Smith    In this case, the AO maps to the natural grid ordering that would be used
108aa219208SBarry Smith    for the DMDA if only 1 processor were employed (ordering most rapidly in the
10947c6ae99SBarry Smith    x-direction, then y, then z).  Multiple degrees of freedom are numbered
11047c6ae99SBarry Smith    for each node (rather than 1 component for the whole grid, then the next
11147c6ae99SBarry Smith    component, etc.)
11247c6ae99SBarry Smith 
1137a612ce8SBarry Smith    Do NOT call AODestroy() on the ao returned by this function.
1147a612ce8SBarry Smith 
1159df75925SJed Brown .seealso: DMDACreate2d(), DMDASetAOType(), DMDAGetGhostCorners(), DMDAGetCorners(), DMLocalToGlobal()
116565245c5SBarry Smith           DMGlobalToLocalBegin(), DMGlobalToLocalEnd(), DMLocalToLocalBegin(), DMLocalToLocalEnd(),  DMDAGetOwnershipRanges(),
11747c6ae99SBarry Smith           AO, AOPetscToApplication(), AOApplicationToPetsc()
11847c6ae99SBarry Smith @*/
1197087cfbeSBarry Smith PetscErrorCode  DMDAGetAO(DM da,AO *ao)
12047c6ae99SBarry Smith {
12163868d81SStefano Zampini   DM_DA          *dd;
12263868d81SStefano Zampini   PetscBool      isdmda;
12347c6ae99SBarry Smith 
12447c6ae99SBarry Smith   PetscFunctionBegin;
125a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da,DM_CLASSID,1,DMDA);
12647c6ae99SBarry Smith   PetscValidPointer(ao,2);
127*9566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)da,DMDA,&isdmda));
1287a8be351SBarry Smith   PetscCheck(isdmda,PetscObjectComm((PetscObject)da),PETSC_ERR_SUP,"Requires a DMDA as input");
12963868d81SStefano Zampini   /* now we can safely dereference */
13063868d81SStefano Zampini   dd = (DM_DA*)da->data;
13147c6ae99SBarry Smith 
13247c6ae99SBarry Smith   /*
13347c6ae99SBarry Smith      Build the natural ordering to PETSc ordering mappings.
13447c6ae99SBarry Smith   */
13547c6ae99SBarry Smith   if (!dd->ao) {
13647c6ae99SBarry Smith     IS             ispetsc,isnatural;
13747c6ae99SBarry Smith     PetscInt       Nlocal;
13847c6ae99SBarry Smith 
139*9566063dSJacob Faibussowitsch     PetscCall(DMDAGetNatural_Private(da,&Nlocal,&isnatural));
140*9566063dSJacob Faibussowitsch     PetscCall(ISCreateStride(PetscObjectComm((PetscObject)da),Nlocal,dd->base,1,&ispetsc));
141*9566063dSJacob Faibussowitsch     PetscCall(AOCreate(PetscObjectComm((PetscObject)da),&dd->ao));
142*9566063dSJacob Faibussowitsch     PetscCall(AOSetIS(dd->ao,isnatural,ispetsc));
143*9566063dSJacob Faibussowitsch     PetscCall(AOSetType(dd->ao,dd->aotype));
144*9566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectParent((PetscObject)da,(PetscObject)dd->ao));
145*9566063dSJacob Faibussowitsch     PetscCall(ISDestroy(&ispetsc));
146*9566063dSJacob Faibussowitsch     PetscCall(ISDestroy(&isnatural));
14747c6ae99SBarry Smith   }
14847c6ae99SBarry Smith   *ao = dd->ao;
14947c6ae99SBarry Smith   PetscFunctionReturn(0);
15047c6ae99SBarry Smith }
151