xref: /petsc/src/dm/impls/da/daindex.c (revision dce8aeba1c9b69b19f651c53d8a6b674bd7e9cbd)
147c6ae99SBarry Smith /*
247c6ae99SBarry Smith   Code for manipulating distributed regular arrays in parallel.
347c6ae99SBarry Smith */
447c6ae99SBarry Smith 
5af0996ceSBarry Smith #include <petsc/private/dmdaimpl.h> /*I   "petscdmda.h"   I*/
647c6ae99SBarry Smith 
747c6ae99SBarry Smith /*
847c6ae99SBarry Smith    Gets the natural number for each global number on the process.
947c6ae99SBarry Smith 
10aa219208SBarry Smith    Used by DMDAGetAO() and DMDAGlobalToNatural_Create()
1147c6ae99SBarry Smith */
12d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGetNatural_Private(DM da, PetscInt *outNlocal, IS *isnatural)
13d71ae5a4SJacob Faibussowitsch {
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++) {
39ad540459SPierre 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
55*dce8aebaSBarry Smith -  aotype - type of `AO`
569db3d8bcSStefano Zampini 
579db3d8bcSStefano Zampini    Output Parameters:
589db3d8bcSStefano Zampini 
599db3d8bcSStefano Zampini    Level: intermediate
609db3d8bcSStefano Zampini 
61*dce8aebaSBarry Smith    Note:
62*dce8aebaSBarry Smith    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 
64*dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDACreate2d()`, `DMDAGetAO()`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `DMLocalToGlobal()`
65db781477SPatrick Sanan           `DMGlobalToLocalBegin()`, `DMGlobalToLocalEnd()`, `DMLocalToLocalBegin()`, `DMLocalToLocalEnd()`, `DMDAGetGlobalIndices()`, `DMDAGetOwnershipRanges()`,
66db781477SPatrick Sanan           `AO`, `AOPetscToApplication()`, `AOApplicationToPetsc()`
679db3d8bcSStefano Zampini @*/
68d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDASetAOType(DM da, AOType aotype)
69d71ae5a4SJacob Faibussowitsch {
709db3d8bcSStefano Zampini   DM_DA    *dd;
719db3d8bcSStefano Zampini   PetscBool isdmda;
729db3d8bcSStefano Zampini 
739db3d8bcSStefano Zampini   PetscFunctionBegin;
74a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
759566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)da, DMDA, &isdmda));
767a8be351SBarry Smith   PetscCheck(isdmda, PetscObjectComm((PetscObject)da), PETSC_ERR_SUP, "Requires a DMDA as input");
779db3d8bcSStefano Zampini   /* now we can safely dereference */
789db3d8bcSStefano Zampini   dd = (DM_DA *)da->data;
799db3d8bcSStefano Zampini   if (dd->ao) { /* check if the already computed AO has the same type as requested */
809db3d8bcSStefano Zampini     PetscBool match;
819566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)dd->ao, aotype, &match));
827a8be351SBarry Smith     PetscCheck(match, PetscObjectComm((PetscObject)da), PETSC_ERR_SUP, "Cannot change AO type");
839db3d8bcSStefano Zampini     PetscFunctionReturn(0);
849db3d8bcSStefano Zampini   }
859566063dSJacob Faibussowitsch   PetscCall(PetscFree(dd->aotype));
869566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(aotype, (char **)&dd->aotype));
879db3d8bcSStefano Zampini   PetscFunctionReturn(0);
889db3d8bcSStefano Zampini }
899db3d8bcSStefano Zampini 
9047c6ae99SBarry Smith /*@
91aa219208SBarry Smith    DMDAGetAO - Gets the application ordering context for a distributed array.
9247c6ae99SBarry Smith 
93d083f849SBarry Smith    Collective on da
9447c6ae99SBarry Smith 
9547c6ae99SBarry Smith    Input Parameter:
9647c6ae99SBarry Smith .  da - the distributed array
9747c6ae99SBarry Smith 
9847c6ae99SBarry Smith    Output Parameters:
99*dce8aebaSBarry Smith .  ao - the application ordering context for `DMDA`
10047c6ae99SBarry Smith 
10147c6ae99SBarry Smith    Level: intermediate
10247c6ae99SBarry Smith 
10347c6ae99SBarry Smith    Notes:
104*dce8aebaSBarry Smith    In this case, the `AO` maps to the natural grid ordering that would be used
105*dce8aebaSBarry Smith    for the `DMDA` if only 1 processor were employed (ordering most rapidly in the
10647c6ae99SBarry Smith    x-direction, then y, then z).  Multiple degrees of freedom are numbered
10747c6ae99SBarry Smith    for each node (rather than 1 component for the whole grid, then the next
10847c6ae99SBarry Smith    component, etc.)
10947c6ae99SBarry Smith 
110*dce8aebaSBarry Smith    Do NOT call `AODestroy()` on the ao returned by this function.
1117a612ce8SBarry Smith 
112*dce8aebaSBarry Smith .seealso: `DM`, `DMDA`, `DMDACreate2d()`, `DMDASetAOType()`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `DMLocalToGlobal()`
113db781477SPatrick Sanan           `DMGlobalToLocalBegin()`, `DMGlobalToLocalEnd()`, `DMLocalToLocalBegin()`, `DMLocalToLocalEnd()`, `DMDAGetOwnershipRanges()`,
114db781477SPatrick Sanan           `AO`, `AOPetscToApplication()`, `AOApplicationToPetsc()`
11547c6ae99SBarry Smith @*/
116d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGetAO(DM da, AO *ao)
117d71ae5a4SJacob Faibussowitsch {
11863868d81SStefano Zampini   DM_DA    *dd;
11963868d81SStefano Zampini   PetscBool isdmda;
12047c6ae99SBarry Smith 
12147c6ae99SBarry Smith   PetscFunctionBegin;
122a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
12347c6ae99SBarry Smith   PetscValidPointer(ao, 2);
1249566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)da, DMDA, &isdmda));
1257a8be351SBarry Smith   PetscCheck(isdmda, PetscObjectComm((PetscObject)da), PETSC_ERR_SUP, "Requires a DMDA as input");
12663868d81SStefano Zampini   /* now we can safely dereference */
12763868d81SStefano Zampini   dd = (DM_DA *)da->data;
12847c6ae99SBarry Smith 
12947c6ae99SBarry Smith   /*
13047c6ae99SBarry Smith      Build the natural ordering to PETSc ordering mappings.
13147c6ae99SBarry Smith   */
13247c6ae99SBarry Smith   if (!dd->ao) {
13347c6ae99SBarry Smith     IS       ispetsc, isnatural;
13447c6ae99SBarry Smith     PetscInt Nlocal;
13547c6ae99SBarry Smith 
1369566063dSJacob Faibussowitsch     PetscCall(DMDAGetNatural_Private(da, &Nlocal, &isnatural));
1379566063dSJacob Faibussowitsch     PetscCall(ISCreateStride(PetscObjectComm((PetscObject)da), Nlocal, dd->base, 1, &ispetsc));
1389566063dSJacob Faibussowitsch     PetscCall(AOCreate(PetscObjectComm((PetscObject)da), &dd->ao));
1399566063dSJacob Faibussowitsch     PetscCall(AOSetIS(dd->ao, isnatural, ispetsc));
1409566063dSJacob Faibussowitsch     PetscCall(AOSetType(dd->ao, dd->aotype));
1419566063dSJacob Faibussowitsch     PetscCall(ISDestroy(&ispetsc));
1429566063dSJacob Faibussowitsch     PetscCall(ISDestroy(&isnatural));
14347c6ae99SBarry Smith   }
14447c6ae99SBarry Smith   *ao = dd->ao;
14547c6ae99SBarry Smith   PetscFunctionReturn(0);
14647c6ae99SBarry Smith }
147