xref: /petsc/src/vec/is/ao/impls/basic/aobasic.c (revision bcda9346efad4e5ba2d553af84eb238771ba1e25)
11447629fSBarry Smith /*
21447629fSBarry Smith     The most basic AO application ordering routines. These store the
3d38ec673SBarry Smith   entire orderings on each processor to be efficient but can require excessive memory
41447629fSBarry Smith */
51447629fSBarry Smith 
61447629fSBarry Smith #include <../src/vec/is/ao/aoimpl.h> /*I  "petscao.h"   I*/
71447629fSBarry Smith 
81447629fSBarry Smith typedef struct {
91447629fSBarry Smith   PetscInt *app;   /* app[i] is the partner for the ith PETSc slot */
101447629fSBarry Smith   PetscInt *petsc; /* petsc[j] is the partner for the jth app slot */
111447629fSBarry Smith } AO_Basic;
121447629fSBarry Smith 
131447629fSBarry Smith /*
141447629fSBarry Smith        All processors have the same data so processor 1 prints it
151447629fSBarry Smith */
AOView_Basic(AO ao,PetscViewer viewer)16da8c939bSJacob Faibussowitsch static PetscErrorCode AOView_Basic(AO ao, PetscViewer viewer)
17d71ae5a4SJacob Faibussowitsch {
181447629fSBarry Smith   PetscMPIInt rank;
191447629fSBarry Smith   PetscInt    i;
201447629fSBarry Smith   AO_Basic   *aobasic = (AO_Basic *)ao->data;
21*9f196a02SMartin Diehl   PetscBool   isascii;
221447629fSBarry Smith 
231447629fSBarry Smith   PetscFunctionBegin;
249566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)ao), &rank));
25dd400576SPatrick Sanan   if (rank == 0) {
26*9f196a02SMartin Diehl     PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
27*9f196a02SMartin Diehl     if (isascii) {
289566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "Number of elements in ordering %" PetscInt_FMT "\n", ao->N));
299566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "PETSc->App  App->PETSc\n"));
3048a46eb9SPierre Jolivet       for (i = 0; i < ao->N; i++) PetscCall(PetscViewerASCIIPrintf(viewer, "%3" PetscInt_FMT "  %3" PetscInt_FMT "    %3" PetscInt_FMT "  %3" PetscInt_FMT "\n", i, aobasic->app[i], i, aobasic->petsc[i]));
311447629fSBarry Smith     }
321447629fSBarry Smith   }
339566063dSJacob Faibussowitsch   PetscCall(PetscViewerFlush(viewer));
343ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
351447629fSBarry Smith }
361447629fSBarry Smith 
AODestroy_Basic(AO ao)37da8c939bSJacob Faibussowitsch static PetscErrorCode AODestroy_Basic(AO ao)
38d71ae5a4SJacob Faibussowitsch {
391447629fSBarry Smith   AO_Basic *aobasic = (AO_Basic *)ao->data;
401447629fSBarry Smith 
411447629fSBarry Smith   PetscFunctionBegin;
429566063dSJacob Faibussowitsch   PetscCall(PetscFree2(aobasic->app, aobasic->petsc));
439566063dSJacob Faibussowitsch   PetscCall(PetscFree(aobasic));
443ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
451447629fSBarry Smith }
461447629fSBarry Smith 
AOPetscToApplication_Basic(AO ao,PetscInt n,PetscInt * ia)47da8c939bSJacob Faibussowitsch static PetscErrorCode AOPetscToApplication_Basic(AO ao, PetscInt n, PetscInt *ia)
48d71ae5a4SJacob Faibussowitsch {
491447629fSBarry Smith   PetscInt  i, N = ao->N;
501447629fSBarry Smith   AO_Basic *aobasic = (AO_Basic *)ao->data;
511447629fSBarry Smith 
521447629fSBarry Smith   PetscFunctionBegin;
531447629fSBarry Smith   for (i = 0; i < n; i++) {
541447629fSBarry Smith     if (ia[i] >= 0 && ia[i] < N) {
551447629fSBarry Smith       ia[i] = aobasic->app[ia[i]];
561447629fSBarry Smith     } else {
571447629fSBarry Smith       ia[i] = -1;
581447629fSBarry Smith     }
591447629fSBarry Smith   }
603ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
611447629fSBarry Smith }
621447629fSBarry Smith 
AOApplicationToPetsc_Basic(AO ao,PetscInt n,PetscInt * ia)63da8c939bSJacob Faibussowitsch static PetscErrorCode AOApplicationToPetsc_Basic(AO ao, PetscInt n, PetscInt *ia)
64d71ae5a4SJacob Faibussowitsch {
651447629fSBarry Smith   PetscInt  i, N = ao->N;
661447629fSBarry Smith   AO_Basic *aobasic = (AO_Basic *)ao->data;
671447629fSBarry Smith 
681447629fSBarry Smith   PetscFunctionBegin;
691447629fSBarry Smith   for (i = 0; i < n; i++) {
701447629fSBarry Smith     if (ia[i] >= 0 && ia[i] < N) {
711447629fSBarry Smith       ia[i] = aobasic->petsc[ia[i]];
721447629fSBarry Smith     } else {
731447629fSBarry Smith       ia[i] = -1;
741447629fSBarry Smith     }
751447629fSBarry Smith   }
763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
771447629fSBarry Smith }
781447629fSBarry Smith 
AOPetscToApplicationPermuteInt_Basic(AO ao,PetscInt block,PetscInt * array)79da8c939bSJacob Faibussowitsch static PetscErrorCode AOPetscToApplicationPermuteInt_Basic(AO ao, PetscInt block, PetscInt *array)
80d71ae5a4SJacob Faibussowitsch {
811447629fSBarry Smith   AO_Basic *aobasic = (AO_Basic *)ao->data;
821447629fSBarry Smith   PetscInt *temp;
831447629fSBarry Smith   PetscInt  i, j;
841447629fSBarry Smith 
851447629fSBarry Smith   PetscFunctionBegin;
869566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(ao->N * block, &temp));
871447629fSBarry Smith   for (i = 0; i < ao->N; i++) {
881447629fSBarry Smith     for (j = 0; j < block; j++) temp[i * block + j] = array[aobasic->petsc[i] * block + j];
891447629fSBarry Smith   }
909566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(array, temp, ao->N * block));
919566063dSJacob Faibussowitsch   PetscCall(PetscFree(temp));
923ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
931447629fSBarry Smith }
941447629fSBarry Smith 
AOApplicationToPetscPermuteInt_Basic(AO ao,PetscInt block,PetscInt * array)95da8c939bSJacob Faibussowitsch static PetscErrorCode AOApplicationToPetscPermuteInt_Basic(AO ao, PetscInt block, PetscInt *array)
96d71ae5a4SJacob Faibussowitsch {
971447629fSBarry Smith   AO_Basic *aobasic = (AO_Basic *)ao->data;
981447629fSBarry Smith   PetscInt *temp;
991447629fSBarry Smith   PetscInt  i, j;
1001447629fSBarry Smith 
1011447629fSBarry Smith   PetscFunctionBegin;
1029566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(ao->N * block, &temp));
1031447629fSBarry Smith   for (i = 0; i < ao->N; i++) {
1041447629fSBarry Smith     for (j = 0; j < block; j++) temp[i * block + j] = array[aobasic->app[i] * block + j];
1051447629fSBarry Smith   }
1069566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(array, temp, ao->N * block));
1079566063dSJacob Faibussowitsch   PetscCall(PetscFree(temp));
1083ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1091447629fSBarry Smith }
1101447629fSBarry Smith 
AOPetscToApplicationPermuteReal_Basic(AO ao,PetscInt block,PetscReal * array)111da8c939bSJacob Faibussowitsch static PetscErrorCode AOPetscToApplicationPermuteReal_Basic(AO ao, PetscInt block, PetscReal *array)
112d71ae5a4SJacob Faibussowitsch {
1131447629fSBarry Smith   AO_Basic  *aobasic = (AO_Basic *)ao->data;
1141447629fSBarry Smith   PetscReal *temp;
1151447629fSBarry Smith   PetscInt   i, j;
1161447629fSBarry Smith 
1171447629fSBarry Smith   PetscFunctionBegin;
1189566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(ao->N * block, &temp));
1191447629fSBarry Smith   for (i = 0; i < ao->N; i++) {
1201447629fSBarry Smith     for (j = 0; j < block; j++) temp[i * block + j] = array[aobasic->petsc[i] * block + j];
1211447629fSBarry Smith   }
1229566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(array, temp, ao->N * block));
1239566063dSJacob Faibussowitsch   PetscCall(PetscFree(temp));
1243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1251447629fSBarry Smith }
1261447629fSBarry Smith 
AOApplicationToPetscPermuteReal_Basic(AO ao,PetscInt block,PetscReal * array)127da8c939bSJacob Faibussowitsch static PetscErrorCode AOApplicationToPetscPermuteReal_Basic(AO ao, PetscInt block, PetscReal *array)
128d71ae5a4SJacob Faibussowitsch {
1291447629fSBarry Smith   AO_Basic  *aobasic = (AO_Basic *)ao->data;
1301447629fSBarry Smith   PetscReal *temp;
1311447629fSBarry Smith   PetscInt   i, j;
1321447629fSBarry Smith 
1331447629fSBarry Smith   PetscFunctionBegin;
1349566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(ao->N * block, &temp));
1351447629fSBarry Smith   for (i = 0; i < ao->N; i++) {
1361447629fSBarry Smith     for (j = 0; j < block; j++) temp[i * block + j] = array[aobasic->app[i] * block + j];
1371447629fSBarry Smith   }
1389566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(array, temp, ao->N * block));
1399566063dSJacob Faibussowitsch   PetscCall(PetscFree(temp));
1403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1411447629fSBarry Smith }
1421447629fSBarry Smith 
143da8c939bSJacob Faibussowitsch static const struct _AOOps AOOps_Basic = {
144267267bdSJacob Faibussowitsch   PetscDesignatedInitializer(view, AOView_Basic),
145267267bdSJacob Faibussowitsch   PetscDesignatedInitializer(destroy, AODestroy_Basic),
146267267bdSJacob Faibussowitsch   PetscDesignatedInitializer(petsctoapplication, AOPetscToApplication_Basic),
147267267bdSJacob Faibussowitsch   PetscDesignatedInitializer(applicationtopetsc, AOApplicationToPetsc_Basic),
148267267bdSJacob Faibussowitsch   PetscDesignatedInitializer(petsctoapplicationpermuteint, AOPetscToApplicationPermuteInt_Basic),
149267267bdSJacob Faibussowitsch   PetscDesignatedInitializer(applicationtopetscpermuteint, AOApplicationToPetscPermuteInt_Basic),
150267267bdSJacob Faibussowitsch   PetscDesignatedInitializer(petsctoapplicationpermutereal, AOPetscToApplicationPermuteReal_Basic),
151267267bdSJacob Faibussowitsch   PetscDesignatedInitializer(applicationtopetscpermutereal, AOApplicationToPetscPermuteReal_Basic),
1521447629fSBarry Smith };
1531447629fSBarry Smith 
AOCreate_Basic(AO ao)154da8c939bSJacob Faibussowitsch PETSC_INTERN PetscErrorCode AOCreate_Basic(AO ao)
155d71ae5a4SJacob Faibussowitsch {
1561447629fSBarry Smith   AO_Basic       *aobasic;
1571447629fSBarry Smith   PetscMPIInt     size, rank, count, *lens, *disp;
1581447629fSBarry Smith   PetscInt        napp, *allpetsc, *allapp, ip, ia, N, i, *petsc = NULL, start;
1591447629fSBarry Smith   IS              isapp = ao->isapp, ispetsc = ao->ispetsc;
1601447629fSBarry Smith   MPI_Comm        comm;
1611447629fSBarry Smith   const PetscInt *myapp, *mypetsc = NULL;
1621447629fSBarry Smith 
1631447629fSBarry Smith   PetscFunctionBegin;
1641447629fSBarry Smith   /* create special struct aobasic */
1654dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&aobasic));
1661447629fSBarry Smith   ao->data   = (void *)aobasic;
167aea10558SJacob Faibussowitsch   ao->ops[0] = AOOps_Basic;
1689566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)ao, AOBASIC));
1691447629fSBarry Smith 
1709566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(isapp, &napp));
1719566063dSJacob Faibussowitsch   PetscCall(ISGetIndices(isapp, &myapp));
1721447629fSBarry Smith 
1739566063dSJacob Faibussowitsch   PetscCall(PetscMPIIntCast(napp, &count));
1741447629fSBarry Smith 
1751447629fSBarry Smith   /* transmit all lengths to all processors */
1769566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)isapp, &comm));
1779566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(comm, &size));
1789566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
1799566063dSJacob Faibussowitsch   PetscCall(PetscMalloc2(size, &lens, size, &disp));
1809566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Allgather(&count, 1, MPI_INT, lens, 1, MPI_INT, comm));
1811447629fSBarry Smith   N = 0;
1821447629fSBarry Smith   for (i = 0; i < size; i++) {
1839566063dSJacob Faibussowitsch     PetscCall(PetscMPIIntCast(N, disp + i)); /* = sum(lens[j]), j< i */
1841447629fSBarry Smith     N += lens[i];
1851447629fSBarry Smith   }
1861447629fSBarry Smith   ao->N = N;
1871447629fSBarry Smith   ao->n = N;
1881447629fSBarry Smith 
1891447629fSBarry Smith   /* If mypetsc is 0 then use "natural" numbering */
1901447629fSBarry Smith   if (napp) {
1911447629fSBarry Smith     if (!ispetsc) {
1921447629fSBarry Smith       start = disp[rank];
1939566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(napp + 1, &petsc));
1941447629fSBarry Smith       for (i = 0; i < napp; i++) petsc[i] = start + i;
1951447629fSBarry Smith     } else {
1969566063dSJacob Faibussowitsch       PetscCall(ISGetIndices(ispetsc, &mypetsc));
1971447629fSBarry Smith       petsc = (PetscInt *)mypetsc;
1981447629fSBarry Smith     }
1991447629fSBarry Smith   }
2001447629fSBarry Smith 
2011447629fSBarry Smith   /* get all indices on all processors */
2029566063dSJacob Faibussowitsch   PetscCall(PetscMalloc2(N, &allpetsc, N, &allapp));
2039566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Allgatherv(petsc, count, MPIU_INT, allpetsc, lens, disp, MPIU_INT, comm));
2049566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Allgatherv((void *)myapp, count, MPIU_INT, allapp, lens, disp, MPIU_INT, comm));
2059566063dSJacob Faibussowitsch   PetscCall(PetscFree2(lens, disp));
2061447629fSBarry Smith 
2074e1ad211SJed Brown   if (PetscDefined(USE_DEBUG)) {
2081447629fSBarry Smith     PetscInt *sorted;
2099566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(N, &sorted));
2101447629fSBarry Smith 
2119566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(sorted, allpetsc, N));
2129566063dSJacob Faibussowitsch     PetscCall(PetscSortInt(N, sorted));
21300045ab3SPierre Jolivet     for (i = 0; i < N; i++) PetscCheck(sorted[i] == i, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "PETSc ordering requires a permutation of numbers 0 to N-1, it is missing %" PetscInt_FMT " has %" PetscInt_FMT, i, sorted[i]);
2141447629fSBarry Smith 
2159566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(sorted, allapp, N));
2169566063dSJacob Faibussowitsch     PetscCall(PetscSortInt(N, sorted));
21700045ab3SPierre Jolivet     for (i = 0; i < N; i++) PetscCheck(sorted[i] == i, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Application ordering requires a permutation of numbers 0 to N-1, it is missing %" PetscInt_FMT " has %" PetscInt_FMT, i, sorted[i]);
2181447629fSBarry Smith 
2199566063dSJacob Faibussowitsch     PetscCall(PetscFree(sorted));
2201447629fSBarry Smith   }
2211447629fSBarry Smith 
2221447629fSBarry Smith   /* generate a list of application and PETSc node numbers */
2239566063dSJacob Faibussowitsch   PetscCall(PetscCalloc2(N, &aobasic->app, N, &aobasic->petsc));
2241447629fSBarry Smith   for (i = 0; i < N; i++) {
2251447629fSBarry Smith     ip = allpetsc[i];
2261447629fSBarry Smith     ia = allapp[i];
2271447629fSBarry Smith     /* check there are no duplicates */
228c9cc58a2SBarry Smith     PetscCheck(!aobasic->app[ip], PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Duplicate in PETSc ordering at position %" PetscInt_FMT ". Already mapped to %" PetscInt_FMT ", not %" PetscInt_FMT ".", i, aobasic->app[ip] - 1, ia);
2291447629fSBarry Smith     aobasic->app[ip] = ia + 1;
230c9cc58a2SBarry Smith     PetscCheck(!aobasic->petsc[ia], PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Duplicate in Application ordering at position %" PetscInt_FMT ". Already mapped to %" PetscInt_FMT ", not %" PetscInt_FMT ".", i, aobasic->petsc[ia] - 1, ip);
2311447629fSBarry Smith     aobasic->petsc[ia] = ip + 1;
2321447629fSBarry Smith   }
23348a46eb9SPierre Jolivet   if (napp && !mypetsc) PetscCall(PetscFree(petsc));
2349566063dSJacob Faibussowitsch   PetscCall(PetscFree2(allpetsc, allapp));
2351447629fSBarry Smith   /* shift indices down by one */
2361447629fSBarry Smith   for (i = 0; i < N; i++) {
2371447629fSBarry Smith     aobasic->app[i]--;
2381447629fSBarry Smith     aobasic->petsc[i]--;
2391447629fSBarry Smith   }
2401447629fSBarry Smith 
2419566063dSJacob Faibussowitsch   PetscCall(ISRestoreIndices(isapp, &myapp));
2421447629fSBarry Smith   if (napp) {
2431447629fSBarry Smith     if (ispetsc) {
2449566063dSJacob Faibussowitsch       PetscCall(ISRestoreIndices(ispetsc, &mypetsc));
2451447629fSBarry Smith     } else {
2469566063dSJacob Faibussowitsch       PetscCall(PetscFree(petsc));
2471447629fSBarry Smith     }
2481447629fSBarry Smith   }
2493ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2501447629fSBarry Smith }
2511447629fSBarry Smith 
252cc4c1da9SBarry Smith /*@
2531447629fSBarry Smith   AOCreateBasic - Creates a basic application ordering using two integer arrays.
2541447629fSBarry Smith 
255d083f849SBarry Smith   Collective
2561447629fSBarry Smith 
2571447629fSBarry Smith   Input Parameters:
258cab54364SBarry Smith + comm    - MPI communicator that is to share `AO`
259d38ec673SBarry Smith . napp    - size of `myapp` and `mypetsc`
2601447629fSBarry Smith . myapp   - integer array that defines an ordering
261dc9a610eSPierre Jolivet - mypetsc - integer array that defines another ordering (may be `NULL` to
2621447629fSBarry Smith             indicate the natural ordering, that is 0,1,2,3,...)
2631447629fSBarry Smith 
2641447629fSBarry Smith   Output Parameter:
2651447629fSBarry Smith . aoout - the new application ordering
2661447629fSBarry Smith 
2671447629fSBarry Smith   Level: beginner
2681447629fSBarry Smith 
269cab54364SBarry Smith   Note:
270b6971eaeSBarry Smith   The arrays `myapp` and `mypetsc` must contain the all the integers 0 to `napp`-1 with no duplicates; that is there cannot be any "holes"
271cab54364SBarry Smith   in the indices. Use `AOCreateMapping()` or `AOCreateMappingIS()` if you wish to have "holes" in the indices.
2721447629fSBarry Smith 
273cab54364SBarry Smith .seealso: [](sec_ao), [](sec_scatter), `AO`, `AOCreateBasicIS()`, `AODestroy()`, `AOPetscToApplication()`, `AOApplicationToPetsc()`
2741447629fSBarry Smith @*/
AOCreateBasic(MPI_Comm comm,PetscInt napp,const PetscInt myapp[],const PetscInt mypetsc[],AO * aoout)275d71ae5a4SJacob Faibussowitsch PetscErrorCode AOCreateBasic(MPI_Comm comm, PetscInt napp, const PetscInt myapp[], const PetscInt mypetsc[], AO *aoout)
276d71ae5a4SJacob Faibussowitsch {
2771447629fSBarry Smith   IS              isapp, ispetsc;
2781447629fSBarry Smith   const PetscInt *app = myapp, *petsc = mypetsc;
2791447629fSBarry Smith 
2801447629fSBarry Smith   PetscFunctionBegin;
2819566063dSJacob Faibussowitsch   PetscCall(ISCreateGeneral(comm, napp, app, PETSC_USE_POINTER, &isapp));
2821447629fSBarry Smith   if (mypetsc) {
2839566063dSJacob Faibussowitsch     PetscCall(ISCreateGeneral(comm, napp, petsc, PETSC_USE_POINTER, &ispetsc));
2841447629fSBarry Smith   } else {
2851447629fSBarry Smith     ispetsc = NULL;
2861447629fSBarry Smith   }
2879566063dSJacob Faibussowitsch   PetscCall(AOCreateBasicIS(isapp, ispetsc, aoout));
2889566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&isapp));
28948a46eb9SPierre Jolivet   if (mypetsc) PetscCall(ISDestroy(&ispetsc));
2903ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2911447629fSBarry Smith }
2921447629fSBarry Smith 
2935d83a8b1SBarry Smith /*@
294cab54364SBarry Smith   AOCreateBasicIS - Creates a basic application ordering using two `IS` index sets.
2951447629fSBarry Smith 
296c3339decSBarry Smith   Collective
2971447629fSBarry Smith 
2981447629fSBarry Smith   Input Parameters:
2991447629fSBarry Smith + isapp   - index set that defines an ordering
300b6971eaeSBarry Smith - ispetsc - index set that defines another ordering (may be `NULL` to use the natural ordering)
3011447629fSBarry Smith 
3021447629fSBarry Smith   Output Parameter:
3031447629fSBarry Smith . aoout - the new application ordering
3041447629fSBarry Smith 
3051447629fSBarry Smith   Level: beginner
3061447629fSBarry Smith 
307cab54364SBarry Smith   Note:
308b6971eaeSBarry Smith   The index sets `isapp` and `ispetsc` must contain the all the integers 0 to napp-1 (where napp is the length of the index sets) with no duplicates;
3091447629fSBarry Smith   that is there cannot be any "holes"
3101447629fSBarry Smith 
311cab54364SBarry Smith .seealso: [](sec_ao), [](sec_scatter), `IS`, `AO`, `AOCreateBasic()`, `AODestroy()`
3121447629fSBarry Smith @*/
AOCreateBasicIS(IS isapp,IS ispetsc,AO * aoout)313d71ae5a4SJacob Faibussowitsch PetscErrorCode AOCreateBasicIS(IS isapp, IS ispetsc, AO *aoout)
314d71ae5a4SJacob Faibussowitsch {
3151447629fSBarry Smith   MPI_Comm comm;
3161447629fSBarry Smith   AO       ao;
3171447629fSBarry Smith 
3181447629fSBarry Smith   PetscFunctionBegin;
3199566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)isapp, &comm));
3209566063dSJacob Faibussowitsch   PetscCall(AOCreate(comm, &ao));
3219566063dSJacob Faibussowitsch   PetscCall(AOSetIS(ao, isapp, ispetsc));
3229566063dSJacob Faibussowitsch   PetscCall(AOSetType(ao, AOBASIC));
3239566063dSJacob Faibussowitsch   PetscCall(AOViewFromOptions(ao, NULL, "-ao_view"));
3241447629fSBarry Smith   *aoout = ao;
3253ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3261447629fSBarry Smith }
327