xref: /petsc/src/dm/impls/da/daindex.c (revision ad540459ab38c4a232710a68077e487eb6627fe2)
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 */
139371c9d4SSatish Balay PetscErrorCode DMDAGetNatural_Private(DM da, PetscInt *outNlocal, IS *isnatural) {
14c73cfb54SMatthew G. Knepley   PetscInt Nlocal, i, j, k, *lidx, lict = 0, dim = da->dim;
1547c6ae99SBarry Smith   DM_DA   *dd = (DM_DA *)da->data;
1647c6ae99SBarry Smith 
1747c6ae99SBarry Smith   PetscFunctionBegin;
1847c6ae99SBarry Smith   Nlocal = (dd->xe - dd->xs);
19c73cfb54SMatthew G. Knepley   if (dim > 1) Nlocal *= (dd->ye - dd->ys);
20c73cfb54SMatthew G. Knepley   if (dim > 2) Nlocal *= (dd->ze - dd->zs);
2147c6ae99SBarry Smith 
229566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(Nlocal, &lidx));
2347c6ae99SBarry Smith 
24c73cfb54SMatthew G. Knepley   if (dim == 1) {
2547c6ae99SBarry Smith     for (i = dd->xs; i < dd->xe; i++) {
2647c6ae99SBarry Smith       /*  global number in natural ordering */
2747c6ae99SBarry Smith       lidx[lict++] = i;
2847c6ae99SBarry Smith     }
29c73cfb54SMatthew G. Knepley   } else if (dim == 2) {
3047c6ae99SBarry Smith     for (j = dd->ys; j < dd->ye; j++) {
3147c6ae99SBarry Smith       for (i = dd->xs; i < dd->xe; i++) {
3247c6ae99SBarry Smith         /*  global number in natural ordering */
3347c6ae99SBarry Smith         lidx[lict++] = i + j * dd->M * dd->w;
3447c6ae99SBarry Smith       }
3547c6ae99SBarry Smith     }
36c73cfb54SMatthew G. Knepley   } else if (dim == 3) {
3747c6ae99SBarry Smith     for (k = dd->zs; k < dd->ze; k++) {
3847c6ae99SBarry Smith       for (j = dd->ys; j < dd->ye; j++) {
39*ad540459SPierre Jolivet         for (i = dd->xs; i < dd->xe; i++) lidx[lict++] = i + j * dd->M * dd->w + k * dd->M * dd->N * dd->w;
4047c6ae99SBarry Smith       }
4147c6ae99SBarry Smith     }
4247c6ae99SBarry Smith   }
4347c6ae99SBarry Smith   *outNlocal = Nlocal;
449566063dSJacob Faibussowitsch   PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)da), Nlocal, lidx, PETSC_OWN_POINTER, isnatural));
4547c6ae99SBarry Smith   PetscFunctionReturn(0);
4647c6ae99SBarry Smith }
4747c6ae99SBarry Smith 
4892e66395SSatish Balay /*@C
499db3d8bcSStefano Zampini    DMDASetAOType - Sets the type of application ordering for a distributed array.
509db3d8bcSStefano Zampini 
51d083f849SBarry Smith    Collective on da
529db3d8bcSStefano Zampini 
53d8d19677SJose E. Roman    Input Parameters:
54a2b725a8SWilliam Gropp +  da - the distributed array
55a2b725a8SWilliam Gropp -  aotype - type of AO
569db3d8bcSStefano Zampini 
579db3d8bcSStefano Zampini    Output Parameters:
589db3d8bcSStefano Zampini 
599db3d8bcSStefano Zampini    Level: intermediate
609db3d8bcSStefano Zampini 
619db3d8bcSStefano Zampini    Notes:
629db3d8bcSStefano 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
639db3d8bcSStefano Zampini 
64db781477SPatrick Sanan .seealso: `DMDACreate2d()`, `DMDAGetAO()`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `DMLocalToGlobal()`
65db781477SPatrick Sanan           `DMGlobalToLocalBegin()`, `DMGlobalToLocalEnd()`, `DMLocalToLocalBegin()`, `DMLocalToLocalEnd()`, `DMDAGetGlobalIndices()`, `DMDAGetOwnershipRanges()`,
66db781477SPatrick Sanan           `AO`, `AOPetscToApplication()`, `AOApplicationToPetsc()`
679db3d8bcSStefano Zampini @*/
689371c9d4SSatish Balay PetscErrorCode DMDASetAOType(DM da, AOType aotype) {
699db3d8bcSStefano Zampini   DM_DA    *dd;
709db3d8bcSStefano Zampini   PetscBool isdmda;
719db3d8bcSStefano Zampini 
729db3d8bcSStefano Zampini   PetscFunctionBegin;
73a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
749566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)da, DMDA, &isdmda));
757a8be351SBarry Smith   PetscCheck(isdmda, PetscObjectComm((PetscObject)da), PETSC_ERR_SUP, "Requires a DMDA as input");
769db3d8bcSStefano Zampini   /* now we can safely dereference */
779db3d8bcSStefano Zampini   dd = (DM_DA *)da->data;
789db3d8bcSStefano Zampini   if (dd->ao) { /* check if the already computed AO has the same type as requested */
799db3d8bcSStefano Zampini     PetscBool match;
809566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)dd->ao, aotype, &match));
817a8be351SBarry Smith     PetscCheck(match, PetscObjectComm((PetscObject)da), PETSC_ERR_SUP, "Cannot change AO type");
829db3d8bcSStefano Zampini     PetscFunctionReturn(0);
839db3d8bcSStefano Zampini   }
849566063dSJacob Faibussowitsch   PetscCall(PetscFree(dd->aotype));
859566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(aotype, (char **)&dd->aotype));
869db3d8bcSStefano Zampini   PetscFunctionReturn(0);
879db3d8bcSStefano Zampini }
889db3d8bcSStefano Zampini 
8947c6ae99SBarry Smith /*@
90aa219208SBarry Smith    DMDAGetAO - Gets the application ordering context for a distributed array.
9147c6ae99SBarry Smith 
92d083f849SBarry Smith    Collective on da
9347c6ae99SBarry Smith 
9447c6ae99SBarry Smith    Input Parameter:
9547c6ae99SBarry Smith .  da - the distributed array
9647c6ae99SBarry Smith 
9747c6ae99SBarry Smith    Output Parameters:
98aa219208SBarry Smith .  ao - the application ordering context for DMDAs
9947c6ae99SBarry Smith 
10047c6ae99SBarry Smith    Level: intermediate
10147c6ae99SBarry Smith 
10247c6ae99SBarry Smith    Notes:
10347c6ae99SBarry Smith    In this case, the AO maps to the natural grid ordering that would be used
104aa219208SBarry Smith    for the DMDA if only 1 processor were employed (ordering most rapidly in the
10547c6ae99SBarry Smith    x-direction, then y, then z).  Multiple degrees of freedom are numbered
10647c6ae99SBarry Smith    for each node (rather than 1 component for the whole grid, then the next
10747c6ae99SBarry Smith    component, etc.)
10847c6ae99SBarry Smith 
1097a612ce8SBarry Smith    Do NOT call AODestroy() on the ao returned by this function.
1107a612ce8SBarry Smith 
111db781477SPatrick Sanan .seealso: `DMDACreate2d()`, `DMDASetAOType()`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `DMLocalToGlobal()`
112db781477SPatrick Sanan           `DMGlobalToLocalBegin()`, `DMGlobalToLocalEnd()`, `DMLocalToLocalBegin()`, `DMLocalToLocalEnd()`, `DMDAGetOwnershipRanges()`,
113db781477SPatrick Sanan           `AO`, `AOPetscToApplication()`, `AOApplicationToPetsc()`
11447c6ae99SBarry Smith @*/
1159371c9d4SSatish Balay PetscErrorCode DMDAGetAO(DM da, AO *ao) {
11663868d81SStefano Zampini   DM_DA    *dd;
11763868d81SStefano Zampini   PetscBool isdmda;
11847c6ae99SBarry Smith 
11947c6ae99SBarry Smith   PetscFunctionBegin;
120a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
12147c6ae99SBarry Smith   PetscValidPointer(ao, 2);
1229566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)da, DMDA, &isdmda));
1237a8be351SBarry Smith   PetscCheck(isdmda, PetscObjectComm((PetscObject)da), PETSC_ERR_SUP, "Requires a DMDA as input");
12463868d81SStefano Zampini   /* now we can safely dereference */
12563868d81SStefano Zampini   dd = (DM_DA *)da->data;
12647c6ae99SBarry Smith 
12747c6ae99SBarry Smith   /*
12847c6ae99SBarry Smith      Build the natural ordering to PETSc ordering mappings.
12947c6ae99SBarry Smith   */
13047c6ae99SBarry Smith   if (!dd->ao) {
13147c6ae99SBarry Smith     IS       ispetsc, isnatural;
13247c6ae99SBarry Smith     PetscInt Nlocal;
13347c6ae99SBarry Smith 
1349566063dSJacob Faibussowitsch     PetscCall(DMDAGetNatural_Private(da, &Nlocal, &isnatural));
1359566063dSJacob Faibussowitsch     PetscCall(ISCreateStride(PetscObjectComm((PetscObject)da), Nlocal, dd->base, 1, &ispetsc));
1369566063dSJacob Faibussowitsch     PetscCall(AOCreate(PetscObjectComm((PetscObject)da), &dd->ao));
1379566063dSJacob Faibussowitsch     PetscCall(AOSetIS(dd->ao, isnatural, ispetsc));
1389566063dSJacob Faibussowitsch     PetscCall(AOSetType(dd->ao, dd->aotype));
1399566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectParent((PetscObject)da, (PetscObject)dd->ao));
1409566063dSJacob Faibussowitsch     PetscCall(ISDestroy(&ispetsc));
1419566063dSJacob Faibussowitsch     PetscCall(ISDestroy(&isnatural));
14247c6ae99SBarry Smith   }
14347c6ae99SBarry Smith   *ao = dd->ao;
14447c6ae99SBarry Smith   PetscFunctionReturn(0);
14547c6ae99SBarry Smith }
146