xref: /petsc/src/vec/is/ao/impls/basic/aobasic.c (revision 8cc058d9cd56c1ccb3be12a47760ddfc446aaffc)
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 #undef __FUNCT__
181447629fSBarry Smith #define __FUNCT__ "AOView_Basic"
191447629fSBarry Smith PetscErrorCode AOView_Basic(AO ao,PetscViewer viewer)
201447629fSBarry Smith {
211447629fSBarry Smith   PetscErrorCode ierr;
221447629fSBarry Smith   PetscMPIInt    rank;
231447629fSBarry Smith   PetscInt       i;
241447629fSBarry Smith   AO_Basic       *aobasic = (AO_Basic*)ao->data;
251447629fSBarry Smith   PetscBool      iascii;
261447629fSBarry Smith 
271447629fSBarry Smith   PetscFunctionBegin;
281447629fSBarry Smith   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)ao),&rank);CHKERRQ(ierr);
291447629fSBarry Smith   if (!rank) {
301447629fSBarry Smith     ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
311447629fSBarry Smith     if (iascii) {
321447629fSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"Number of elements in ordering %D\n",ao->N);CHKERRQ(ierr);
331447629fSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,  "PETSc->App  App->PETSc\n");CHKERRQ(ierr);
341447629fSBarry Smith       for (i=0; i<ao->N; i++) {
351447629fSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%3D  %3D    %3D  %3D\n",i,aobasic->app[i],i,aobasic->petsc[i]);CHKERRQ(ierr);
361447629fSBarry Smith       }
371447629fSBarry Smith     }
381447629fSBarry Smith   }
391447629fSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
401447629fSBarry Smith   PetscFunctionReturn(0);
411447629fSBarry Smith }
421447629fSBarry Smith 
431447629fSBarry Smith #undef __FUNCT__
441447629fSBarry Smith #define __FUNCT__ "AODestroy_Basic"
451447629fSBarry Smith PetscErrorCode AODestroy_Basic(AO ao)
461447629fSBarry Smith {
471447629fSBarry Smith   AO_Basic       *aobasic = (AO_Basic*)ao->data;
481447629fSBarry Smith   PetscErrorCode ierr;
491447629fSBarry Smith 
501447629fSBarry Smith   PetscFunctionBegin;
511447629fSBarry Smith   ierr = PetscFree2(aobasic->app,aobasic->petsc);CHKERRQ(ierr);
521447629fSBarry Smith   ierr = PetscFree(aobasic);CHKERRQ(ierr);
531447629fSBarry Smith   PetscFunctionReturn(0);
541447629fSBarry Smith }
551447629fSBarry Smith 
561447629fSBarry Smith #undef __FUNCT__
571447629fSBarry Smith #define __FUNCT__ "AOBasicGetIndices_Private"
581447629fSBarry Smith PetscErrorCode AOBasicGetIndices_Private(AO ao,PetscInt **app,PetscInt **petsc)
591447629fSBarry Smith {
601447629fSBarry Smith   AO_Basic *basic = (AO_Basic*)ao->data;
611447629fSBarry Smith 
621447629fSBarry Smith   PetscFunctionBegin;
631447629fSBarry Smith   if (app)   *app   = basic->app;
641447629fSBarry Smith   if (petsc) *petsc = basic->petsc;
651447629fSBarry Smith   PetscFunctionReturn(0);
661447629fSBarry Smith }
671447629fSBarry Smith 
681447629fSBarry Smith #undef __FUNCT__
691447629fSBarry Smith #define __FUNCT__ "AOPetscToApplication_Basic"
701447629fSBarry Smith PetscErrorCode AOPetscToApplication_Basic(AO ao,PetscInt n,PetscInt *ia)
711447629fSBarry Smith {
721447629fSBarry Smith   PetscInt i,N=ao->N;
731447629fSBarry Smith   AO_Basic *aobasic = (AO_Basic*)ao->data;
741447629fSBarry Smith 
751447629fSBarry Smith   PetscFunctionBegin;
761447629fSBarry Smith   for (i=0; i<n; i++) {
771447629fSBarry Smith     if (ia[i] >= 0 && ia[i] < N) {
781447629fSBarry Smith       ia[i] = aobasic->app[ia[i]];
791447629fSBarry Smith     } else {
801447629fSBarry Smith       ia[i] = -1;
811447629fSBarry Smith     }
821447629fSBarry Smith   }
831447629fSBarry Smith   PetscFunctionReturn(0);
841447629fSBarry Smith }
851447629fSBarry Smith 
861447629fSBarry Smith #undef __FUNCT__
871447629fSBarry Smith #define __FUNCT__ "AOApplicationToPetsc_Basic"
881447629fSBarry Smith PetscErrorCode AOApplicationToPetsc_Basic(AO ao,PetscInt n,PetscInt *ia)
891447629fSBarry Smith {
901447629fSBarry Smith   PetscInt i,N=ao->N;
911447629fSBarry Smith   AO_Basic *aobasic = (AO_Basic*)ao->data;
921447629fSBarry Smith 
931447629fSBarry Smith   PetscFunctionBegin;
941447629fSBarry Smith   for (i=0; i<n; i++) {
951447629fSBarry Smith     if (ia[i] >= 0 && ia[i] < N) {
961447629fSBarry Smith       ia[i] = aobasic->petsc[ia[i]];
971447629fSBarry Smith     } else {
981447629fSBarry Smith       ia[i] = -1;
991447629fSBarry Smith     }
1001447629fSBarry Smith   }
1011447629fSBarry Smith   PetscFunctionReturn(0);
1021447629fSBarry Smith }
1031447629fSBarry Smith 
1041447629fSBarry Smith #undef __FUNCT__
1051447629fSBarry Smith #define __FUNCT__ "AOPetscToApplicationPermuteInt_Basic"
1061447629fSBarry Smith PetscErrorCode AOPetscToApplicationPermuteInt_Basic(AO ao, PetscInt block, PetscInt *array)
1071447629fSBarry Smith {
1081447629fSBarry Smith   AO_Basic       *aobasic = (AO_Basic*) ao->data;
1091447629fSBarry Smith   PetscInt       *temp;
1101447629fSBarry Smith   PetscInt       i, j;
1111447629fSBarry Smith   PetscErrorCode ierr;
1121447629fSBarry Smith 
1131447629fSBarry Smith   PetscFunctionBegin;
1141447629fSBarry Smith   ierr = PetscMalloc(ao->N*block * sizeof(PetscInt), &temp);CHKERRQ(ierr);
1151447629fSBarry Smith   for (i = 0; i < ao->N; i++) {
1161447629fSBarry Smith     for (j = 0; j < block; j++) temp[i*block+j] = array[aobasic->petsc[i]*block+j];
1171447629fSBarry Smith   }
1181447629fSBarry Smith   ierr = PetscMemcpy(array, temp, ao->N*block * sizeof(PetscInt));CHKERRQ(ierr);
1191447629fSBarry Smith   ierr = PetscFree(temp);CHKERRQ(ierr);
1201447629fSBarry Smith   PetscFunctionReturn(0);
1211447629fSBarry Smith }
1221447629fSBarry Smith 
1231447629fSBarry Smith #undef __FUNCT__
1241447629fSBarry Smith #define __FUNCT__ "AOApplicationToPetscPermuteInt_Basic"
1251447629fSBarry Smith PetscErrorCode AOApplicationToPetscPermuteInt_Basic(AO ao, PetscInt block, PetscInt *array)
1261447629fSBarry Smith {
1271447629fSBarry Smith   AO_Basic       *aobasic = (AO_Basic*) ao->data;
1281447629fSBarry Smith   PetscInt       *temp;
1291447629fSBarry Smith   PetscInt       i, j;
1301447629fSBarry Smith   PetscErrorCode ierr;
1311447629fSBarry Smith 
1321447629fSBarry Smith   PetscFunctionBegin;
1331447629fSBarry Smith   ierr = PetscMalloc(ao->N*block * sizeof(PetscInt), &temp);CHKERRQ(ierr);
1341447629fSBarry Smith   for (i = 0; i < ao->N; i++) {
1351447629fSBarry Smith     for (j = 0; j < block; j++) temp[i*block+j] = array[aobasic->app[i]*block+j];
1361447629fSBarry Smith   }
1371447629fSBarry Smith   ierr = PetscMemcpy(array, temp, ao->N*block * sizeof(PetscInt));CHKERRQ(ierr);
1381447629fSBarry Smith   ierr = PetscFree(temp);CHKERRQ(ierr);
1391447629fSBarry Smith   PetscFunctionReturn(0);
1401447629fSBarry Smith }
1411447629fSBarry Smith 
1421447629fSBarry Smith #undef __FUNCT__
1431447629fSBarry Smith #define __FUNCT__ "AOPetscToApplicationPermuteReal_Basic"
1441447629fSBarry Smith PetscErrorCode AOPetscToApplicationPermuteReal_Basic(AO ao, PetscInt block, PetscReal *array)
1451447629fSBarry Smith {
1461447629fSBarry Smith   AO_Basic       *aobasic = (AO_Basic*) ao->data;
1471447629fSBarry Smith   PetscReal      *temp;
1481447629fSBarry Smith   PetscInt       i, j;
1491447629fSBarry Smith   PetscErrorCode ierr;
1501447629fSBarry Smith 
1511447629fSBarry Smith   PetscFunctionBegin;
1521447629fSBarry Smith   ierr = PetscMalloc(ao->N*block * sizeof(PetscReal), &temp);CHKERRQ(ierr);
1531447629fSBarry Smith   for (i = 0; i < ao->N; i++) {
1541447629fSBarry Smith     for (j = 0; j < block; j++) temp[i*block+j] = array[aobasic->petsc[i]*block+j];
1551447629fSBarry Smith   }
1561447629fSBarry Smith   ierr = PetscMemcpy(array, temp, ao->N*block * sizeof(PetscReal));CHKERRQ(ierr);
1571447629fSBarry Smith   ierr = PetscFree(temp);CHKERRQ(ierr);
1581447629fSBarry Smith   PetscFunctionReturn(0);
1591447629fSBarry Smith }
1601447629fSBarry Smith 
1611447629fSBarry Smith #undef __FUNCT__
1621447629fSBarry Smith #define __FUNCT__ "AOApplicationToPetscPermuteReal_Basic"
1631447629fSBarry Smith PetscErrorCode AOApplicationToPetscPermuteReal_Basic(AO ao, PetscInt block, PetscReal *array)
1641447629fSBarry Smith {
1651447629fSBarry Smith   AO_Basic       *aobasic = (AO_Basic*) ao->data;
1661447629fSBarry Smith   PetscReal      *temp;
1671447629fSBarry Smith   PetscInt       i, j;
1681447629fSBarry Smith   PetscErrorCode ierr;
1691447629fSBarry Smith 
1701447629fSBarry Smith   PetscFunctionBegin;
1711447629fSBarry Smith   ierr = PetscMalloc(ao->N*block * sizeof(PetscReal), &temp);CHKERRQ(ierr);
1721447629fSBarry Smith   for (i = 0; i < ao->N; i++) {
1731447629fSBarry Smith     for (j = 0; j < block; j++) temp[i*block+j] = array[aobasic->app[i]*block+j];
1741447629fSBarry Smith   }
1751447629fSBarry Smith   ierr = PetscMemcpy(array, temp, ao->N*block * sizeof(PetscReal));CHKERRQ(ierr);
1761447629fSBarry Smith   ierr = PetscFree(temp);CHKERRQ(ierr);
1771447629fSBarry Smith   PetscFunctionReturn(0);
1781447629fSBarry Smith }
1791447629fSBarry Smith 
1801447629fSBarry Smith static struct _AOOps AOOps_Basic = {
1811447629fSBarry Smith   AOView_Basic,
1821447629fSBarry Smith   AODestroy_Basic,
1831447629fSBarry Smith   AOPetscToApplication_Basic,
1841447629fSBarry Smith   AOApplicationToPetsc_Basic,
1851447629fSBarry Smith   AOPetscToApplicationPermuteInt_Basic,
1861447629fSBarry Smith   AOApplicationToPetscPermuteInt_Basic,
1871447629fSBarry Smith   AOPetscToApplicationPermuteReal_Basic,
1881447629fSBarry Smith   AOApplicationToPetscPermuteReal_Basic
1891447629fSBarry Smith };
1901447629fSBarry Smith 
1911447629fSBarry Smith #undef __FUNCT__
1921447629fSBarry Smith #define __FUNCT__ "AOCreate_Basic"
193*8cc058d9SJed Brown PETSC_EXTERN PetscErrorCode AOCreate_Basic(AO ao)
1941447629fSBarry Smith {
1951447629fSBarry Smith   AO_Basic       *aobasic;
1961447629fSBarry Smith   PetscMPIInt    size,rank,count,*lens,*disp;
1971447629fSBarry Smith   PetscInt       napp,*allpetsc,*allapp,ip,ia,N,i,*petsc=NULL,start;
1981447629fSBarry Smith   PetscErrorCode ierr;
1991447629fSBarry Smith   IS             isapp=ao->isapp,ispetsc=ao->ispetsc;
2001447629fSBarry Smith   MPI_Comm       comm;
2011447629fSBarry Smith   const PetscInt *myapp,*mypetsc=NULL;
2021447629fSBarry Smith 
2031447629fSBarry Smith   PetscFunctionBegin;
2041447629fSBarry Smith   /* create special struct aobasic */
2051447629fSBarry Smith   ierr     = PetscNewLog(ao, AO_Basic, &aobasic);CHKERRQ(ierr);
2061447629fSBarry Smith   ao->data = (void*) aobasic;
2071447629fSBarry Smith   ierr     = PetscMemcpy(ao->ops,&AOOps_Basic,sizeof(struct _AOOps));CHKERRQ(ierr);
2081447629fSBarry Smith   ierr     = PetscObjectChangeTypeName((PetscObject)ao,AOBASIC);CHKERRQ(ierr);
2091447629fSBarry Smith 
2101447629fSBarry Smith   ierr = ISGetLocalSize(isapp,&napp);CHKERRQ(ierr);
2111447629fSBarry Smith   ierr = ISGetIndices(isapp,&myapp);CHKERRQ(ierr);
2121447629fSBarry Smith 
2131447629fSBarry Smith   ierr = PetscMPIIntCast(napp,&count);CHKERRQ(ierr);
2141447629fSBarry Smith 
2151447629fSBarry Smith   /* transmit all lengths to all processors */
2161447629fSBarry Smith   ierr = PetscObjectGetComm((PetscObject)isapp,&comm);CHKERRQ(ierr);
2171447629fSBarry Smith   ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr);
2181447629fSBarry Smith   ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr);
2191447629fSBarry Smith   ierr = PetscMalloc2(size,PetscMPIInt, &lens,size,PetscMPIInt,&disp);CHKERRQ(ierr);
2201447629fSBarry Smith   ierr = MPI_Allgather(&count, 1, MPI_INT, lens, 1, MPI_INT, comm);CHKERRQ(ierr);
2211447629fSBarry Smith   N    =  0;
2221447629fSBarry Smith   for (i = 0; i < size; i++) {
2231447629fSBarry Smith     ierr = PetscMPIIntCast(N,disp+i);CHKERRQ(ierr); /* = sum(lens[j]), j< i */
2241447629fSBarry Smith     N   += lens[i];
2251447629fSBarry Smith   }
2261447629fSBarry Smith   ao->N = N;
2271447629fSBarry Smith   ao->n = N;
2281447629fSBarry Smith 
2291447629fSBarry Smith   /* If mypetsc is 0 then use "natural" numbering */
2301447629fSBarry Smith   if (napp) {
2311447629fSBarry Smith     if (!ispetsc) {
2321447629fSBarry Smith       start = disp[rank];
2331447629fSBarry Smith       ierr  = PetscMalloc((napp+1) * sizeof(PetscInt), &petsc);CHKERRQ(ierr);
2341447629fSBarry Smith       for (i=0; i<napp; i++) petsc[i] = start + i;
2351447629fSBarry Smith     } else {
2361447629fSBarry Smith       ierr  = ISGetIndices(ispetsc,&mypetsc);CHKERRQ(ierr);
2371447629fSBarry Smith       petsc = (PetscInt*)mypetsc;
2381447629fSBarry Smith     }
2391447629fSBarry Smith   }
2401447629fSBarry Smith 
2411447629fSBarry Smith   /* get all indices on all processors */
2421447629fSBarry Smith   ierr = PetscMalloc2(N,PetscInt,&allpetsc,N,PetscInt,&allapp);CHKERRQ(ierr);
2431447629fSBarry Smith   ierr = MPI_Allgatherv(petsc, count, MPIU_INT, allpetsc, lens, disp, MPIU_INT, comm);CHKERRQ(ierr);
2441447629fSBarry Smith   ierr = MPI_Allgatherv((void*)myapp, count, MPIU_INT, allapp, lens, disp, MPIU_INT, comm);CHKERRQ(ierr);
2451447629fSBarry Smith   ierr = PetscFree2(lens,disp);CHKERRQ(ierr);
2461447629fSBarry Smith 
2471447629fSBarry Smith #if defined(PETSC_USE_DEBUG)
2481447629fSBarry Smith   {
2491447629fSBarry Smith     PetscInt *sorted;
2501447629fSBarry Smith     ierr = PetscMalloc(N*sizeof(PetscInt),&sorted);CHKERRQ(ierr);
2511447629fSBarry Smith 
2521447629fSBarry Smith     ierr = PetscMemcpy(sorted,allpetsc,N*sizeof(PetscInt));CHKERRQ(ierr);
2531447629fSBarry Smith     ierr = PetscSortInt(N,sorted);CHKERRQ(ierr);
2541447629fSBarry Smith     for (i=0; i<N; i++) {
2551447629fSBarry Smith       if (sorted[i] != i) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"PETSc ordering requires a permutation of numbers 0 to N-1\n it is missing %D has %D",i,sorted[i]);
2561447629fSBarry Smith     }
2571447629fSBarry Smith 
2581447629fSBarry Smith     ierr = PetscMemcpy(sorted,allapp,N*sizeof(PetscInt));CHKERRQ(ierr);
2591447629fSBarry Smith     ierr = PetscSortInt(N,sorted);CHKERRQ(ierr);
2601447629fSBarry Smith     for (i=0; i<N; i++) {
2611447629fSBarry Smith       if (sorted[i] != i) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Application ordering requires a permutation of numbers 0 to N-1\n it is missing %D has %D",i,sorted[i]);
2621447629fSBarry Smith     }
2631447629fSBarry Smith 
2641447629fSBarry Smith     ierr = PetscFree(sorted);CHKERRQ(ierr);
2651447629fSBarry Smith   }
2661447629fSBarry Smith #endif
2671447629fSBarry Smith 
2681447629fSBarry Smith   /* generate a list of application and PETSc node numbers */
2691447629fSBarry Smith   ierr = PetscMalloc2(N,PetscInt, &aobasic->app,N,PetscInt,&aobasic->petsc);CHKERRQ(ierr);
2701447629fSBarry Smith   ierr = PetscLogObjectMemory(ao,2*N*sizeof(PetscInt));CHKERRQ(ierr);
2711447629fSBarry Smith   ierr = PetscMemzero(aobasic->app, N*sizeof(PetscInt));CHKERRQ(ierr);
2721447629fSBarry Smith   ierr = PetscMemzero(aobasic->petsc, N*sizeof(PetscInt));CHKERRQ(ierr);
2731447629fSBarry Smith   for (i = 0; i < N; i++) {
2741447629fSBarry Smith     ip = allpetsc[i];
2751447629fSBarry Smith     ia = allapp[i];
2761447629fSBarry Smith     /* check there are no duplicates */
2771447629fSBarry Smith     if (aobasic->app[ip]) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Duplicate in PETSc ordering at position %d. Already mapped to %d, not %d.", i, aobasic->app[ip]-1, ia);
2781447629fSBarry Smith     aobasic->app[ip] = ia + 1;
2791447629fSBarry Smith     if (aobasic->petsc[ia]) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Duplicate in Application ordering at position %d. Already mapped to %d, not %d.", i, aobasic->petsc[ia]-1, ip);
2801447629fSBarry Smith     aobasic->petsc[ia] = ip + 1;
2811447629fSBarry Smith   }
2821447629fSBarry Smith   if (napp && !mypetsc) {
2831447629fSBarry Smith     ierr = PetscFree(petsc);CHKERRQ(ierr);
2841447629fSBarry Smith   }
2851447629fSBarry Smith   ierr = PetscFree2(allpetsc,allapp);CHKERRQ(ierr);
2861447629fSBarry Smith   /* shift indices down by one */
2871447629fSBarry Smith   for (i = 0; i < N; i++) {
2881447629fSBarry Smith     aobasic->app[i]--;
2891447629fSBarry Smith     aobasic->petsc[i]--;
2901447629fSBarry Smith   }
2911447629fSBarry Smith 
2921447629fSBarry Smith   ierr = ISRestoreIndices(isapp,&myapp);CHKERRQ(ierr);
2931447629fSBarry Smith   if (napp) {
2941447629fSBarry Smith     if (ispetsc) {
2951447629fSBarry Smith       ierr = ISRestoreIndices(ispetsc,&mypetsc);CHKERRQ(ierr);
2961447629fSBarry Smith     } else {
2971447629fSBarry Smith       ierr = PetscFree(petsc);CHKERRQ(ierr);
2981447629fSBarry Smith     }
2991447629fSBarry Smith   }
3001447629fSBarry Smith   PetscFunctionReturn(0);
3011447629fSBarry Smith }
3021447629fSBarry Smith 
3031447629fSBarry Smith #undef __FUNCT__
3041447629fSBarry Smith #define __FUNCT__ "AOCreateBasic"
3051447629fSBarry Smith /*@C
3061447629fSBarry Smith    AOCreateBasic - Creates a basic application ordering using two integer arrays.
3071447629fSBarry Smith 
3081447629fSBarry Smith    Collective on MPI_Comm
3091447629fSBarry Smith 
3101447629fSBarry Smith    Input Parameters:
3111447629fSBarry Smith +  comm - MPI communicator that is to share AO
3121447629fSBarry Smith .  napp - size of integer arrays
3131447629fSBarry Smith .  myapp - integer array that defines an ordering
3141447629fSBarry Smith -  mypetsc - integer array that defines another ordering (may be NULL to
3151447629fSBarry Smith              indicate the natural ordering, that is 0,1,2,3,...)
3161447629fSBarry Smith 
3171447629fSBarry Smith    Output Parameter:
3181447629fSBarry Smith .  aoout - the new application ordering
3191447629fSBarry Smith 
3201447629fSBarry Smith    Level: beginner
3211447629fSBarry Smith 
3221447629fSBarry Smith     Notes: 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"
3231447629fSBarry Smith            in the indices. Use AOCreateMapping() or AOCreateMappingIS() if you wish to have "holes" in the indices.
3241447629fSBarry Smith 
3251447629fSBarry Smith .keywords: AO, create
3261447629fSBarry Smith 
3271447629fSBarry Smith .seealso: AOCreateBasicIS(), AODestroy(), AOPetscToApplication(), AOApplicationToPetsc()
3281447629fSBarry Smith @*/
3291447629fSBarry Smith PetscErrorCode  AOCreateBasic(MPI_Comm comm,PetscInt napp,const PetscInt myapp[],const PetscInt mypetsc[],AO *aoout)
3301447629fSBarry Smith {
3311447629fSBarry Smith   PetscErrorCode ierr;
3321447629fSBarry Smith   IS             isapp,ispetsc;
3331447629fSBarry Smith   const PetscInt *app=myapp,*petsc=mypetsc;
3341447629fSBarry Smith 
3351447629fSBarry Smith   PetscFunctionBegin;
3361447629fSBarry Smith   ierr = ISCreateGeneral(comm,napp,app,PETSC_USE_POINTER,&isapp);CHKERRQ(ierr);
3371447629fSBarry Smith   if (mypetsc) {
3381447629fSBarry Smith     ierr = ISCreateGeneral(comm,napp,petsc,PETSC_USE_POINTER,&ispetsc);CHKERRQ(ierr);
3391447629fSBarry Smith   } else {
3401447629fSBarry Smith     ispetsc = NULL;
3411447629fSBarry Smith   }
3421447629fSBarry Smith   ierr = AOCreateBasicIS(isapp,ispetsc,aoout);CHKERRQ(ierr);
3431447629fSBarry Smith   ierr = ISDestroy(&isapp);CHKERRQ(ierr);
3441447629fSBarry Smith   if (mypetsc) {
3451447629fSBarry Smith     ierr = ISDestroy(&ispetsc);CHKERRQ(ierr);
3461447629fSBarry Smith   }
3471447629fSBarry Smith   PetscFunctionReturn(0);
3481447629fSBarry Smith }
3491447629fSBarry Smith 
3501447629fSBarry Smith #undef __FUNCT__
3511447629fSBarry Smith #define __FUNCT__ "AOCreateBasicIS"
3521447629fSBarry Smith /*@C
3531447629fSBarry Smith    AOCreateBasicIS - Creates a basic application ordering using two index sets.
3541447629fSBarry Smith 
3551447629fSBarry Smith    Collective on IS
3561447629fSBarry Smith 
3571447629fSBarry Smith    Input Parameters:
3581447629fSBarry Smith +  isapp - index set that defines an ordering
3591447629fSBarry Smith -  ispetsc - index set that defines another ordering (may be NULL to use the
3601447629fSBarry Smith              natural ordering)
3611447629fSBarry Smith 
3621447629fSBarry Smith    Output Parameter:
3631447629fSBarry Smith .  aoout - the new application ordering
3641447629fSBarry Smith 
3651447629fSBarry Smith    Level: beginner
3661447629fSBarry Smith 
3671447629fSBarry Smith     Notes: 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;
3681447629fSBarry Smith            that is there cannot be any "holes"
3691447629fSBarry Smith 
3701447629fSBarry Smith .keywords: AO, create
3711447629fSBarry Smith 
3721447629fSBarry Smith .seealso: AOCreateBasic(),  AODestroy()
3731447629fSBarry Smith @*/
3741447629fSBarry Smith PetscErrorCode AOCreateBasicIS(IS isapp,IS ispetsc,AO *aoout)
3751447629fSBarry Smith {
3761447629fSBarry Smith   PetscErrorCode ierr;
3771447629fSBarry Smith   MPI_Comm       comm;
3781447629fSBarry Smith   AO             ao;
3791447629fSBarry Smith 
3801447629fSBarry Smith   PetscFunctionBegin;
3811447629fSBarry Smith   ierr   = PetscObjectGetComm((PetscObject)isapp,&comm);CHKERRQ(ierr);
3821447629fSBarry Smith   ierr   = AOCreate(comm,&ao);CHKERRQ(ierr);
3831447629fSBarry Smith   ierr   = AOSetIS(ao,isapp,ispetsc);CHKERRQ(ierr);
3841447629fSBarry Smith   ierr   = AOSetType(ao,AOBASIC);CHKERRQ(ierr);
3851447629fSBarry Smith   *aoout = ao;
3861447629fSBarry Smith   PetscFunctionReturn(0);
3871447629fSBarry Smith }
3881447629fSBarry Smith 
389