xref: /petsc/src/vec/is/ao/impls/basic/aobasic.c (revision 08401ef684002a709c6d3db98a0c9f54a8bcf1ec)
11447629fSBarry Smith 
21447629fSBarry Smith /*
31447629fSBarry Smith     The most basic AO application ordering routines. These store the
41447629fSBarry Smith   entire orderings on each processor.
51447629fSBarry Smith */
61447629fSBarry Smith 
71447629fSBarry Smith #include <../src/vec/is/ao/aoimpl.h>          /*I  "petscao.h"   I*/
81447629fSBarry Smith 
91447629fSBarry Smith typedef struct {
101447629fSBarry Smith   PetscInt *app;     /* app[i] is the partner for the ith PETSc slot */
111447629fSBarry Smith   PetscInt *petsc;   /* petsc[j] is the partner for the jth app slot */
121447629fSBarry Smith } AO_Basic;
131447629fSBarry Smith 
141447629fSBarry Smith /*
151447629fSBarry Smith        All processors have the same data so processor 1 prints it
161447629fSBarry Smith */
171447629fSBarry Smith PetscErrorCode AOView_Basic(AO ao,PetscViewer viewer)
181447629fSBarry Smith {
191447629fSBarry Smith   PetscMPIInt    rank;
201447629fSBarry Smith   PetscInt       i;
211447629fSBarry Smith   AO_Basic       *aobasic = (AO_Basic*)ao->data;
221447629fSBarry Smith   PetscBool      iascii;
231447629fSBarry Smith 
241447629fSBarry Smith   PetscFunctionBegin;
259566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)ao),&rank));
26dd400576SPatrick Sanan   if (rank == 0) {
279566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
281447629fSBarry Smith     if (iascii) {
299566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"Number of elements in ordering %" PetscInt_FMT "\n",ao->N));
309566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,  "PETSc->App  App->PETSc\n"));
311447629fSBarry Smith       for (i=0; i<ao->N; i++) {
329566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer,"%3" PetscInt_FMT "  %3" PetscInt_FMT "    %3" PetscInt_FMT "  %3" PetscInt_FMT "\n",i,aobasic->app[i],i,aobasic->petsc[i]));
331447629fSBarry Smith       }
341447629fSBarry Smith     }
351447629fSBarry Smith   }
369566063dSJacob Faibussowitsch   PetscCall(PetscViewerFlush(viewer));
371447629fSBarry Smith   PetscFunctionReturn(0);
381447629fSBarry Smith }
391447629fSBarry Smith 
401447629fSBarry Smith PetscErrorCode AODestroy_Basic(AO ao)
411447629fSBarry Smith {
421447629fSBarry Smith   AO_Basic       *aobasic = (AO_Basic*)ao->data;
431447629fSBarry Smith 
441447629fSBarry Smith   PetscFunctionBegin;
459566063dSJacob Faibussowitsch   PetscCall(PetscFree2(aobasic->app,aobasic->petsc));
469566063dSJacob Faibussowitsch   PetscCall(PetscFree(aobasic));
471447629fSBarry Smith   PetscFunctionReturn(0);
481447629fSBarry Smith }
491447629fSBarry Smith 
501447629fSBarry Smith PetscErrorCode AOBasicGetIndices_Private(AO ao,PetscInt **app,PetscInt **petsc)
511447629fSBarry Smith {
521447629fSBarry Smith   AO_Basic *basic = (AO_Basic*)ao->data;
531447629fSBarry Smith 
541447629fSBarry Smith   PetscFunctionBegin;
551447629fSBarry Smith   if (app)   *app   = basic->app;
561447629fSBarry Smith   if (petsc) *petsc = basic->petsc;
571447629fSBarry Smith   PetscFunctionReturn(0);
581447629fSBarry Smith }
591447629fSBarry Smith 
601447629fSBarry Smith PetscErrorCode AOPetscToApplication_Basic(AO ao,PetscInt n,PetscInt *ia)
611447629fSBarry Smith {
621447629fSBarry Smith   PetscInt i,N=ao->N;
631447629fSBarry Smith   AO_Basic *aobasic = (AO_Basic*)ao->data;
641447629fSBarry Smith 
651447629fSBarry Smith   PetscFunctionBegin;
661447629fSBarry Smith   for (i=0; i<n; i++) {
671447629fSBarry Smith     if (ia[i] >= 0 && ia[i] < N) {
681447629fSBarry Smith       ia[i] = aobasic->app[ia[i]];
691447629fSBarry Smith     } else {
701447629fSBarry Smith       ia[i] = -1;
711447629fSBarry Smith     }
721447629fSBarry Smith   }
731447629fSBarry Smith   PetscFunctionReturn(0);
741447629fSBarry Smith }
751447629fSBarry Smith 
761447629fSBarry Smith PetscErrorCode AOApplicationToPetsc_Basic(AO ao,PetscInt n,PetscInt *ia)
771447629fSBarry Smith {
781447629fSBarry Smith   PetscInt i,N=ao->N;
791447629fSBarry Smith   AO_Basic *aobasic = (AO_Basic*)ao->data;
801447629fSBarry Smith 
811447629fSBarry Smith   PetscFunctionBegin;
821447629fSBarry Smith   for (i=0; i<n; i++) {
831447629fSBarry Smith     if (ia[i] >= 0 && ia[i] < N) {
841447629fSBarry Smith       ia[i] = aobasic->petsc[ia[i]];
851447629fSBarry Smith     } else {
861447629fSBarry Smith       ia[i] = -1;
871447629fSBarry Smith     }
881447629fSBarry Smith   }
891447629fSBarry Smith   PetscFunctionReturn(0);
901447629fSBarry Smith }
911447629fSBarry Smith 
921447629fSBarry Smith PetscErrorCode AOPetscToApplicationPermuteInt_Basic(AO ao, PetscInt block, PetscInt *array)
931447629fSBarry Smith {
941447629fSBarry Smith   AO_Basic       *aobasic = (AO_Basic*) ao->data;
951447629fSBarry Smith   PetscInt       *temp;
961447629fSBarry Smith   PetscInt       i, j;
971447629fSBarry Smith 
981447629fSBarry Smith   PetscFunctionBegin;
999566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(ao->N*block, &temp));
1001447629fSBarry Smith   for (i = 0; i < ao->N; i++) {
1011447629fSBarry Smith     for (j = 0; j < block; j++) temp[i*block+j] = array[aobasic->petsc[i]*block+j];
1021447629fSBarry Smith   }
1039566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(array, temp, ao->N*block));
1049566063dSJacob Faibussowitsch   PetscCall(PetscFree(temp));
1051447629fSBarry Smith   PetscFunctionReturn(0);
1061447629fSBarry Smith }
1071447629fSBarry Smith 
1081447629fSBarry Smith PetscErrorCode AOApplicationToPetscPermuteInt_Basic(AO ao, PetscInt block, PetscInt *array)
1091447629fSBarry Smith {
1101447629fSBarry Smith   AO_Basic       *aobasic = (AO_Basic*) ao->data;
1111447629fSBarry Smith   PetscInt       *temp;
1121447629fSBarry Smith   PetscInt       i, j;
1131447629fSBarry Smith 
1141447629fSBarry Smith   PetscFunctionBegin;
1159566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(ao->N*block, &temp));
1161447629fSBarry Smith   for (i = 0; i < ao->N; i++) {
1171447629fSBarry Smith     for (j = 0; j < block; j++) temp[i*block+j] = array[aobasic->app[i]*block+j];
1181447629fSBarry Smith   }
1199566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(array, temp, ao->N*block));
1209566063dSJacob Faibussowitsch   PetscCall(PetscFree(temp));
1211447629fSBarry Smith   PetscFunctionReturn(0);
1221447629fSBarry Smith }
1231447629fSBarry Smith 
1241447629fSBarry Smith PetscErrorCode AOPetscToApplicationPermuteReal_Basic(AO ao, PetscInt block, PetscReal *array)
1251447629fSBarry Smith {
1261447629fSBarry Smith   AO_Basic       *aobasic = (AO_Basic*) ao->data;
1271447629fSBarry Smith   PetscReal      *temp;
1281447629fSBarry Smith   PetscInt       i, j;
1291447629fSBarry Smith 
1301447629fSBarry Smith   PetscFunctionBegin;
1319566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(ao->N*block, &temp));
1321447629fSBarry Smith   for (i = 0; i < ao->N; i++) {
1331447629fSBarry Smith     for (j = 0; j < block; j++) temp[i*block+j] = array[aobasic->petsc[i]*block+j];
1341447629fSBarry Smith   }
1359566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(array, temp, ao->N*block));
1369566063dSJacob Faibussowitsch   PetscCall(PetscFree(temp));
1371447629fSBarry Smith   PetscFunctionReturn(0);
1381447629fSBarry Smith }
1391447629fSBarry Smith 
1401447629fSBarry Smith PetscErrorCode AOApplicationToPetscPermuteReal_Basic(AO ao, PetscInt block, PetscReal *array)
1411447629fSBarry Smith {
1421447629fSBarry Smith   AO_Basic       *aobasic = (AO_Basic*) ao->data;
1431447629fSBarry Smith   PetscReal      *temp;
1441447629fSBarry Smith   PetscInt       i, j;
1451447629fSBarry Smith 
1461447629fSBarry Smith   PetscFunctionBegin;
1479566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(ao->N*block, &temp));
1481447629fSBarry Smith   for (i = 0; i < ao->N; i++) {
1491447629fSBarry Smith     for (j = 0; j < block; j++) temp[i*block+j] = array[aobasic->app[i]*block+j];
1501447629fSBarry Smith   }
1519566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(array, temp, ao->N*block));
1529566063dSJacob Faibussowitsch   PetscCall(PetscFree(temp));
1531447629fSBarry Smith   PetscFunctionReturn(0);
1541447629fSBarry Smith }
1551447629fSBarry Smith 
1561447629fSBarry Smith static struct _AOOps AOOps_Basic = {
157267267bdSJacob Faibussowitsch   PetscDesignatedInitializer(view,AOView_Basic),
158267267bdSJacob Faibussowitsch   PetscDesignatedInitializer(destroy,AODestroy_Basic),
159267267bdSJacob Faibussowitsch   PetscDesignatedInitializer(petsctoapplication,AOPetscToApplication_Basic),
160267267bdSJacob Faibussowitsch   PetscDesignatedInitializer(applicationtopetsc,AOApplicationToPetsc_Basic),
161267267bdSJacob Faibussowitsch   PetscDesignatedInitializer(petsctoapplicationpermuteint,AOPetscToApplicationPermuteInt_Basic),
162267267bdSJacob Faibussowitsch   PetscDesignatedInitializer(applicationtopetscpermuteint,AOApplicationToPetscPermuteInt_Basic),
163267267bdSJacob Faibussowitsch   PetscDesignatedInitializer(petsctoapplicationpermutereal,AOPetscToApplicationPermuteReal_Basic),
164267267bdSJacob Faibussowitsch   PetscDesignatedInitializer(applicationtopetscpermutereal,AOApplicationToPetscPermuteReal_Basic),
1651447629fSBarry Smith };
1661447629fSBarry Smith 
1678cc058d9SJed Brown PETSC_EXTERN PetscErrorCode AOCreate_Basic(AO ao)
1681447629fSBarry Smith {
1691447629fSBarry Smith   AO_Basic       *aobasic;
1701447629fSBarry Smith   PetscMPIInt    size,rank,count,*lens,*disp;
1711447629fSBarry Smith   PetscInt       napp,*allpetsc,*allapp,ip,ia,N,i,*petsc=NULL,start;
1721447629fSBarry Smith   IS             isapp=ao->isapp,ispetsc=ao->ispetsc;
1731447629fSBarry Smith   MPI_Comm       comm;
1741447629fSBarry Smith   const PetscInt *myapp,*mypetsc=NULL;
1751447629fSBarry Smith 
1761447629fSBarry Smith   PetscFunctionBegin;
1771447629fSBarry Smith   /* create special struct aobasic */
1789566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(ao,&aobasic));
1791447629fSBarry Smith   ao->data = (void*) aobasic;
1809566063dSJacob Faibussowitsch   PetscCall(PetscMemcpy(ao->ops,&AOOps_Basic,sizeof(struct _AOOps)));
1819566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)ao,AOBASIC));
1821447629fSBarry Smith 
1839566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(isapp,&napp));
1849566063dSJacob Faibussowitsch   PetscCall(ISGetIndices(isapp,&myapp));
1851447629fSBarry Smith 
1869566063dSJacob Faibussowitsch   PetscCall(PetscMPIIntCast(napp,&count));
1871447629fSBarry Smith 
1881447629fSBarry Smith   /* transmit all lengths to all processors */
1899566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)isapp,&comm));
1909566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(comm, &size));
1919566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
1929566063dSJacob Faibussowitsch   PetscCall(PetscMalloc2(size, &lens,size,&disp));
1939566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Allgather(&count, 1, MPI_INT, lens, 1, MPI_INT, comm));
1941447629fSBarry Smith   N    =  0;
1951447629fSBarry Smith   for (i = 0; i < size; i++) {
1969566063dSJacob Faibussowitsch     PetscCall(PetscMPIIntCast(N,disp+i)); /* = sum(lens[j]), j< i */
1971447629fSBarry Smith     N   += lens[i];
1981447629fSBarry Smith   }
1991447629fSBarry Smith   ao->N = N;
2001447629fSBarry Smith   ao->n = N;
2011447629fSBarry Smith 
2021447629fSBarry Smith   /* If mypetsc is 0 then use "natural" numbering */
2031447629fSBarry Smith   if (napp) {
2041447629fSBarry Smith     if (!ispetsc) {
2051447629fSBarry Smith       start = disp[rank];
2069566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(napp+1, &petsc));
2071447629fSBarry Smith       for (i=0; i<napp; i++) petsc[i] = start + i;
2081447629fSBarry Smith     } else {
2099566063dSJacob Faibussowitsch       PetscCall(ISGetIndices(ispetsc,&mypetsc));
2101447629fSBarry Smith       petsc = (PetscInt*)mypetsc;
2111447629fSBarry Smith     }
2121447629fSBarry Smith   }
2131447629fSBarry Smith 
2141447629fSBarry Smith   /* get all indices on all processors */
2159566063dSJacob Faibussowitsch   PetscCall(PetscMalloc2(N,&allpetsc,N,&allapp));
2169566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Allgatherv(petsc, count, MPIU_INT, allpetsc, lens, disp, MPIU_INT, comm));
2179566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Allgatherv((void*)myapp, count, MPIU_INT, allapp, lens, disp, MPIU_INT, comm));
2189566063dSJacob Faibussowitsch   PetscCall(PetscFree2(lens,disp));
2191447629fSBarry Smith 
2204e1ad211SJed Brown   if (PetscDefined(USE_DEBUG)) {
2211447629fSBarry Smith     PetscInt *sorted;
2229566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(N,&sorted));
2231447629fSBarry Smith 
2249566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(sorted,allpetsc,N));
2259566063dSJacob Faibussowitsch     PetscCall(PetscSortInt(N,sorted));
2261447629fSBarry Smith     for (i=0; i<N; i++) {
227*08401ef6SPierre Jolivet       PetscCheck(sorted[i] == i,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"PETSc ordering requires a permutation of numbers 0 to N-1\n it is missing %" PetscInt_FMT " has %" PetscInt_FMT,i,sorted[i]);
2281447629fSBarry Smith     }
2291447629fSBarry Smith 
2309566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(sorted,allapp,N));
2319566063dSJacob Faibussowitsch     PetscCall(PetscSortInt(N,sorted));
2321447629fSBarry Smith     for (i=0; i<N; i++) {
233*08401ef6SPierre Jolivet       PetscCheck(sorted[i] == i,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Application ordering requires a permutation of numbers 0 to N-1\n it is missing %" PetscInt_FMT " has %" PetscInt_FMT,i,sorted[i]);
2341447629fSBarry Smith     }
2351447629fSBarry Smith 
2369566063dSJacob Faibussowitsch     PetscCall(PetscFree(sorted));
2371447629fSBarry Smith   }
2381447629fSBarry Smith 
2391447629fSBarry Smith   /* generate a list of application and PETSc node numbers */
2409566063dSJacob Faibussowitsch   PetscCall(PetscCalloc2(N, &aobasic->app,N,&aobasic->petsc));
2419566063dSJacob Faibussowitsch   PetscCall(PetscLogObjectMemory((PetscObject)ao,2*N*sizeof(PetscInt)));
2421447629fSBarry Smith   for (i = 0; i < N; i++) {
2431447629fSBarry Smith     ip = allpetsc[i];
2441447629fSBarry Smith     ia = allapp[i];
2451447629fSBarry Smith     /* check there are no duplicates */
2462c71b3e2SJacob Faibussowitsch     PetscCheckFalse(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);
2471447629fSBarry Smith     aobasic->app[ip] = ia + 1;
2482c71b3e2SJacob Faibussowitsch     PetscCheckFalse(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);
2491447629fSBarry Smith     aobasic->petsc[ia] = ip + 1;
2501447629fSBarry Smith   }
2511447629fSBarry Smith   if (napp && !mypetsc) {
2529566063dSJacob Faibussowitsch     PetscCall(PetscFree(petsc));
2531447629fSBarry Smith   }
2549566063dSJacob Faibussowitsch   PetscCall(PetscFree2(allpetsc,allapp));
2551447629fSBarry Smith   /* shift indices down by one */
2561447629fSBarry Smith   for (i = 0; i < N; i++) {
2571447629fSBarry Smith     aobasic->app[i]--;
2581447629fSBarry Smith     aobasic->petsc[i]--;
2591447629fSBarry Smith   }
2601447629fSBarry Smith 
2619566063dSJacob Faibussowitsch   PetscCall(ISRestoreIndices(isapp,&myapp));
2621447629fSBarry Smith   if (napp) {
2631447629fSBarry Smith     if (ispetsc) {
2649566063dSJacob Faibussowitsch       PetscCall(ISRestoreIndices(ispetsc,&mypetsc));
2651447629fSBarry Smith     } else {
2669566063dSJacob Faibussowitsch       PetscCall(PetscFree(petsc));
2671447629fSBarry Smith     }
2681447629fSBarry Smith   }
2691447629fSBarry Smith   PetscFunctionReturn(0);
2701447629fSBarry Smith }
2711447629fSBarry Smith 
2721447629fSBarry Smith /*@C
2731447629fSBarry Smith    AOCreateBasic - Creates a basic application ordering using two integer arrays.
2741447629fSBarry Smith 
275d083f849SBarry Smith    Collective
2761447629fSBarry Smith 
2771447629fSBarry Smith    Input Parameters:
2781447629fSBarry Smith +  comm - MPI communicator that is to share AO
2791447629fSBarry Smith .  napp - size of integer arrays
2801447629fSBarry Smith .  myapp - integer array that defines an ordering
2811447629fSBarry Smith -  mypetsc - integer array that defines another ordering (may be NULL to
2821447629fSBarry Smith              indicate the natural ordering, that is 0,1,2,3,...)
2831447629fSBarry Smith 
2841447629fSBarry Smith    Output Parameter:
2851447629fSBarry Smith .  aoout - the new application ordering
2861447629fSBarry Smith 
2871447629fSBarry Smith    Level: beginner
2881447629fSBarry Smith 
28995452b02SPatrick Sanan     Notes:
29095452b02SPatrick Sanan     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"
2911447629fSBarry Smith            in the indices. Use AOCreateMapping() or AOCreateMappingIS() if you wish to have "holes" in the indices.
2921447629fSBarry Smith 
2931447629fSBarry Smith .seealso: AOCreateBasicIS(), AODestroy(), AOPetscToApplication(), AOApplicationToPetsc()
2941447629fSBarry Smith @*/
2951447629fSBarry Smith PetscErrorCode  AOCreateBasic(MPI_Comm comm,PetscInt napp,const PetscInt myapp[],const PetscInt mypetsc[],AO *aoout)
2961447629fSBarry Smith {
2971447629fSBarry Smith   IS             isapp,ispetsc;
2981447629fSBarry Smith   const PetscInt *app=myapp,*petsc=mypetsc;
2991447629fSBarry Smith 
3001447629fSBarry Smith   PetscFunctionBegin;
3019566063dSJacob Faibussowitsch   PetscCall(ISCreateGeneral(comm,napp,app,PETSC_USE_POINTER,&isapp));
3021447629fSBarry Smith   if (mypetsc) {
3039566063dSJacob Faibussowitsch     PetscCall(ISCreateGeneral(comm,napp,petsc,PETSC_USE_POINTER,&ispetsc));
3041447629fSBarry Smith   } else {
3051447629fSBarry Smith     ispetsc = NULL;
3061447629fSBarry Smith   }
3079566063dSJacob Faibussowitsch   PetscCall(AOCreateBasicIS(isapp,ispetsc,aoout));
3089566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&isapp));
3091447629fSBarry Smith   if (mypetsc) {
3109566063dSJacob Faibussowitsch     PetscCall(ISDestroy(&ispetsc));
3111447629fSBarry Smith   }
3121447629fSBarry Smith   PetscFunctionReturn(0);
3131447629fSBarry Smith }
3141447629fSBarry Smith 
3151447629fSBarry Smith /*@C
3161447629fSBarry Smith    AOCreateBasicIS - Creates a basic application ordering using two index sets.
3171447629fSBarry Smith 
3181447629fSBarry Smith    Collective on IS
3191447629fSBarry Smith 
3201447629fSBarry Smith    Input Parameters:
3211447629fSBarry Smith +  isapp - index set that defines an ordering
3221447629fSBarry Smith -  ispetsc - index set that defines another ordering (may be NULL to use the
3231447629fSBarry Smith              natural ordering)
3241447629fSBarry Smith 
3251447629fSBarry Smith    Output Parameter:
3261447629fSBarry Smith .  aoout - the new application ordering
3271447629fSBarry Smith 
3281447629fSBarry Smith    Level: beginner
3291447629fSBarry Smith 
33095452b02SPatrick Sanan     Notes:
33195452b02SPatrick Sanan     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;
3321447629fSBarry Smith            that is there cannot be any "holes"
3331447629fSBarry Smith 
3341447629fSBarry Smith .seealso: AOCreateBasic(),  AODestroy()
3351447629fSBarry Smith @*/
3361447629fSBarry Smith PetscErrorCode AOCreateBasicIS(IS isapp,IS ispetsc,AO *aoout)
3371447629fSBarry Smith {
3381447629fSBarry Smith   MPI_Comm       comm;
3391447629fSBarry Smith   AO             ao;
3401447629fSBarry Smith 
3411447629fSBarry Smith   PetscFunctionBegin;
3429566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)isapp,&comm));
3439566063dSJacob Faibussowitsch   PetscCall(AOCreate(comm,&ao));
3449566063dSJacob Faibussowitsch   PetscCall(AOSetIS(ao,isapp,ispetsc));
3459566063dSJacob Faibussowitsch   PetscCall(AOSetType(ao,AOBASIC));
3469566063dSJacob Faibussowitsch   PetscCall(AOViewFromOptions(ao,NULL,"-ao_view"));
3471447629fSBarry Smith   *aoout = ao;
3481447629fSBarry Smith   PetscFunctionReturn(0);
3491447629fSBarry Smith }
350