xref: /petsc/src/dm/impls/da/daindex.c (revision d71ae5a4db6382e7f06317b8d368875286fe9008)
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 */
13*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGetNatural_Private(DM da, PetscInt *outNlocal, IS *isnatural)
14*d71ae5a4SJacob Faibussowitsch {
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 
239566063dSJacob 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++) {
40ad540459SPierre Jolivet         for (i = dd->xs; i < dd->xe; i++) lidx[lict++] = i + j * dd->M * dd->w + k * dd->M * dd->N * dd->w;
4147c6ae99SBarry Smith       }
4247c6ae99SBarry Smith     }
4347c6ae99SBarry Smith   }
4447c6ae99SBarry Smith   *outNlocal = Nlocal;
459566063dSJacob Faibussowitsch   PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)da), Nlocal, lidx, PETSC_OWN_POINTER, isnatural));
4647c6ae99SBarry Smith   PetscFunctionReturn(0);
4747c6ae99SBarry Smith }
4847c6ae99SBarry Smith 
4992e66395SSatish Balay /*@C
509db3d8bcSStefano Zampini    DMDASetAOType - Sets the type of application ordering for a distributed array.
519db3d8bcSStefano Zampini 
52d083f849SBarry Smith    Collective on da
539db3d8bcSStefano Zampini 
54d8d19677SJose E. Roman    Input Parameters:
55a2b725a8SWilliam Gropp +  da - the distributed array
56a2b725a8SWilliam Gropp -  aotype - type of AO
579db3d8bcSStefano Zampini 
589db3d8bcSStefano Zampini    Output Parameters:
599db3d8bcSStefano Zampini 
609db3d8bcSStefano Zampini    Level: intermediate
619db3d8bcSStefano Zampini 
629db3d8bcSStefano Zampini    Notes:
639db3d8bcSStefano 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
649db3d8bcSStefano Zampini 
65db781477SPatrick Sanan .seealso: `DMDACreate2d()`, `DMDAGetAO()`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `DMLocalToGlobal()`
66db781477SPatrick Sanan           `DMGlobalToLocalBegin()`, `DMGlobalToLocalEnd()`, `DMLocalToLocalBegin()`, `DMLocalToLocalEnd()`, `DMDAGetGlobalIndices()`, `DMDAGetOwnershipRanges()`,
67db781477SPatrick Sanan           `AO`, `AOPetscToApplication()`, `AOApplicationToPetsc()`
689db3d8bcSStefano Zampini @*/
69*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDASetAOType(DM da, AOType aotype)
70*d71ae5a4SJacob Faibussowitsch {
719db3d8bcSStefano Zampini   DM_DA    *dd;
729db3d8bcSStefano Zampini   PetscBool isdmda;
739db3d8bcSStefano Zampini 
749db3d8bcSStefano Zampini   PetscFunctionBegin;
75a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
769566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)da, DMDA, &isdmda));
777a8be351SBarry Smith   PetscCheck(isdmda, PetscObjectComm((PetscObject)da), PETSC_ERR_SUP, "Requires a DMDA as input");
789db3d8bcSStefano Zampini   /* now we can safely dereference */
799db3d8bcSStefano Zampini   dd = (DM_DA *)da->data;
809db3d8bcSStefano Zampini   if (dd->ao) { /* check if the already computed AO has the same type as requested */
819db3d8bcSStefano Zampini     PetscBool match;
829566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)dd->ao, aotype, &match));
837a8be351SBarry Smith     PetscCheck(match, PetscObjectComm((PetscObject)da), PETSC_ERR_SUP, "Cannot change AO type");
849db3d8bcSStefano Zampini     PetscFunctionReturn(0);
859db3d8bcSStefano Zampini   }
869566063dSJacob Faibussowitsch   PetscCall(PetscFree(dd->aotype));
879566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(aotype, (char **)&dd->aotype));
889db3d8bcSStefano Zampini   PetscFunctionReturn(0);
899db3d8bcSStefano Zampini }
909db3d8bcSStefano Zampini 
9147c6ae99SBarry Smith /*@
92aa219208SBarry Smith    DMDAGetAO - Gets the application ordering context for a distributed array.
9347c6ae99SBarry Smith 
94d083f849SBarry Smith    Collective on da
9547c6ae99SBarry Smith 
9647c6ae99SBarry Smith    Input Parameter:
9747c6ae99SBarry Smith .  da - the distributed array
9847c6ae99SBarry Smith 
9947c6ae99SBarry Smith    Output Parameters:
100aa219208SBarry Smith .  ao - the application ordering context for DMDAs
10147c6ae99SBarry Smith 
10247c6ae99SBarry Smith    Level: intermediate
10347c6ae99SBarry Smith 
10447c6ae99SBarry Smith    Notes:
10547c6ae99SBarry Smith    In this case, the AO maps to the natural grid ordering that would be used
106aa219208SBarry Smith    for the DMDA if only 1 processor were employed (ordering most rapidly in the
10747c6ae99SBarry Smith    x-direction, then y, then z).  Multiple degrees of freedom are numbered
10847c6ae99SBarry Smith    for each node (rather than 1 component for the whole grid, then the next
10947c6ae99SBarry Smith    component, etc.)
11047c6ae99SBarry Smith 
1117a612ce8SBarry Smith    Do NOT call AODestroy() on the ao returned by this function.
1127a612ce8SBarry Smith 
113db781477SPatrick Sanan .seealso: `DMDACreate2d()`, `DMDASetAOType()`, `DMDAGetGhostCorners()`, `DMDAGetCorners()`, `DMLocalToGlobal()`
114db781477SPatrick Sanan           `DMGlobalToLocalBegin()`, `DMGlobalToLocalEnd()`, `DMLocalToLocalBegin()`, `DMLocalToLocalEnd()`, `DMDAGetOwnershipRanges()`,
115db781477SPatrick Sanan           `AO`, `AOPetscToApplication()`, `AOApplicationToPetsc()`
11647c6ae99SBarry Smith @*/
117*d71ae5a4SJacob Faibussowitsch PetscErrorCode DMDAGetAO(DM da, AO *ao)
118*d71ae5a4SJacob Faibussowitsch {
11963868d81SStefano Zampini   DM_DA    *dd;
12063868d81SStefano Zampini   PetscBool isdmda;
12147c6ae99SBarry Smith 
12247c6ae99SBarry Smith   PetscFunctionBegin;
123a9a02de4SBarry Smith   PetscValidHeaderSpecificType(da, DM_CLASSID, 1, DMDA);
12447c6ae99SBarry Smith   PetscValidPointer(ao, 2);
1259566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)da, DMDA, &isdmda));
1267a8be351SBarry Smith   PetscCheck(isdmda, PetscObjectComm((PetscObject)da), PETSC_ERR_SUP, "Requires a DMDA as input");
12763868d81SStefano Zampini   /* now we can safely dereference */
12863868d81SStefano Zampini   dd = (DM_DA *)da->data;
12947c6ae99SBarry Smith 
13047c6ae99SBarry Smith   /*
13147c6ae99SBarry Smith      Build the natural ordering to PETSc ordering mappings.
13247c6ae99SBarry Smith   */
13347c6ae99SBarry Smith   if (!dd->ao) {
13447c6ae99SBarry Smith     IS       ispetsc, isnatural;
13547c6ae99SBarry Smith     PetscInt Nlocal;
13647c6ae99SBarry Smith 
1379566063dSJacob Faibussowitsch     PetscCall(DMDAGetNatural_Private(da, &Nlocal, &isnatural));
1389566063dSJacob Faibussowitsch     PetscCall(ISCreateStride(PetscObjectComm((PetscObject)da), Nlocal, dd->base, 1, &ispetsc));
1399566063dSJacob Faibussowitsch     PetscCall(AOCreate(PetscObjectComm((PetscObject)da), &dd->ao));
1409566063dSJacob Faibussowitsch     PetscCall(AOSetIS(dd->ao, isnatural, ispetsc));
1419566063dSJacob Faibussowitsch     PetscCall(AOSetType(dd->ao, dd->aotype));
1429566063dSJacob Faibussowitsch     PetscCall(ISDestroy(&ispetsc));
1439566063dSJacob Faibussowitsch     PetscCall(ISDestroy(&isnatural));
14447c6ae99SBarry Smith   }
14547c6ae99SBarry Smith   *ao = dd->ao;
14647c6ae99SBarry Smith   PetscFunctionReturn(0);
14747c6ae99SBarry Smith }
148