xref: /petsc/src/vec/is/ao/impls/basic/aobasic.c (revision 1447629fc24590da3991bec7ed146bff2c847561)
1*1447629fSBarry Smith 
2*1447629fSBarry Smith /*
3*1447629fSBarry Smith     The most basic AO application ordering routines. These store the
4*1447629fSBarry Smith   entire orderings on each processor.
5*1447629fSBarry Smith */
6*1447629fSBarry Smith 
7*1447629fSBarry Smith #include <../src/vec/is/ao/aoimpl.h>          /*I  "petscao.h"   I*/
8*1447629fSBarry Smith 
9*1447629fSBarry Smith typedef struct {
10*1447629fSBarry Smith   PetscInt *app;     /* app[i] is the partner for the ith PETSc slot */
11*1447629fSBarry Smith   PetscInt *petsc;   /* petsc[j] is the partner for the jth app slot */
12*1447629fSBarry Smith } AO_Basic;
13*1447629fSBarry Smith 
14*1447629fSBarry Smith /*
15*1447629fSBarry Smith        All processors have the same data so processor 1 prints it
16*1447629fSBarry Smith */
17*1447629fSBarry Smith #undef __FUNCT__
18*1447629fSBarry Smith #define __FUNCT__ "AOView_Basic"
19*1447629fSBarry Smith PetscErrorCode AOView_Basic(AO ao,PetscViewer viewer)
20*1447629fSBarry Smith {
21*1447629fSBarry Smith   PetscErrorCode ierr;
22*1447629fSBarry Smith   PetscMPIInt    rank;
23*1447629fSBarry Smith   PetscInt       i;
24*1447629fSBarry Smith   AO_Basic       *aobasic = (AO_Basic*)ao->data;
25*1447629fSBarry Smith   PetscBool      iascii;
26*1447629fSBarry Smith 
27*1447629fSBarry Smith   PetscFunctionBegin;
28*1447629fSBarry Smith   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)ao),&rank);CHKERRQ(ierr);
29*1447629fSBarry Smith   if (!rank) {
30*1447629fSBarry Smith     ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
31*1447629fSBarry Smith     if (iascii) {
32*1447629fSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"Number of elements in ordering %D\n",ao->N);CHKERRQ(ierr);
33*1447629fSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,  "PETSc->App  App->PETSc\n");CHKERRQ(ierr);
34*1447629fSBarry Smith       for (i=0; i<ao->N; i++) {
35*1447629fSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%3D  %3D    %3D  %3D\n",i,aobasic->app[i],i,aobasic->petsc[i]);CHKERRQ(ierr);
36*1447629fSBarry Smith       }
37*1447629fSBarry Smith     }
38*1447629fSBarry Smith   }
39*1447629fSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
40*1447629fSBarry Smith   PetscFunctionReturn(0);
41*1447629fSBarry Smith }
42*1447629fSBarry Smith 
43*1447629fSBarry Smith #undef __FUNCT__
44*1447629fSBarry Smith #define __FUNCT__ "AODestroy_Basic"
45*1447629fSBarry Smith PetscErrorCode AODestroy_Basic(AO ao)
46*1447629fSBarry Smith {
47*1447629fSBarry Smith   AO_Basic       *aobasic = (AO_Basic*)ao->data;
48*1447629fSBarry Smith   PetscErrorCode ierr;
49*1447629fSBarry Smith 
50*1447629fSBarry Smith   PetscFunctionBegin;
51*1447629fSBarry Smith   ierr = PetscFree2(aobasic->app,aobasic->petsc);CHKERRQ(ierr);
52*1447629fSBarry Smith   ierr = PetscFree(aobasic);CHKERRQ(ierr);
53*1447629fSBarry Smith   PetscFunctionReturn(0);
54*1447629fSBarry Smith }
55*1447629fSBarry Smith 
56*1447629fSBarry Smith #undef __FUNCT__
57*1447629fSBarry Smith #define __FUNCT__ "AOBasicGetIndices_Private"
58*1447629fSBarry Smith PetscErrorCode AOBasicGetIndices_Private(AO ao,PetscInt **app,PetscInt **petsc)
59*1447629fSBarry Smith {
60*1447629fSBarry Smith   AO_Basic *basic = (AO_Basic*)ao->data;
61*1447629fSBarry Smith 
62*1447629fSBarry Smith   PetscFunctionBegin;
63*1447629fSBarry Smith   if (app)   *app   = basic->app;
64*1447629fSBarry Smith   if (petsc) *petsc = basic->petsc;
65*1447629fSBarry Smith   PetscFunctionReturn(0);
66*1447629fSBarry Smith }
67*1447629fSBarry Smith 
68*1447629fSBarry Smith #undef __FUNCT__
69*1447629fSBarry Smith #define __FUNCT__ "AOPetscToApplication_Basic"
70*1447629fSBarry Smith PetscErrorCode AOPetscToApplication_Basic(AO ao,PetscInt n,PetscInt *ia)
71*1447629fSBarry Smith {
72*1447629fSBarry Smith   PetscInt i,N=ao->N;
73*1447629fSBarry Smith   AO_Basic *aobasic = (AO_Basic*)ao->data;
74*1447629fSBarry Smith 
75*1447629fSBarry Smith   PetscFunctionBegin;
76*1447629fSBarry Smith   for (i=0; i<n; i++) {
77*1447629fSBarry Smith     if (ia[i] >= 0 && ia[i] < N) {
78*1447629fSBarry Smith       ia[i] = aobasic->app[ia[i]];
79*1447629fSBarry Smith     } else {
80*1447629fSBarry Smith       ia[i] = -1;
81*1447629fSBarry Smith     }
82*1447629fSBarry Smith   }
83*1447629fSBarry Smith   PetscFunctionReturn(0);
84*1447629fSBarry Smith }
85*1447629fSBarry Smith 
86*1447629fSBarry Smith #undef __FUNCT__
87*1447629fSBarry Smith #define __FUNCT__ "AOApplicationToPetsc_Basic"
88*1447629fSBarry Smith PetscErrorCode AOApplicationToPetsc_Basic(AO ao,PetscInt n,PetscInt *ia)
89*1447629fSBarry Smith {
90*1447629fSBarry Smith   PetscInt i,N=ao->N;
91*1447629fSBarry Smith   AO_Basic *aobasic = (AO_Basic*)ao->data;
92*1447629fSBarry Smith 
93*1447629fSBarry Smith   PetscFunctionBegin;
94*1447629fSBarry Smith   for (i=0; i<n; i++) {
95*1447629fSBarry Smith     if (ia[i] >= 0 && ia[i] < N) {
96*1447629fSBarry Smith       ia[i] = aobasic->petsc[ia[i]];
97*1447629fSBarry Smith     } else {
98*1447629fSBarry Smith       ia[i] = -1;
99*1447629fSBarry Smith     }
100*1447629fSBarry Smith   }
101*1447629fSBarry Smith   PetscFunctionReturn(0);
102*1447629fSBarry Smith }
103*1447629fSBarry Smith 
104*1447629fSBarry Smith #undef __FUNCT__
105*1447629fSBarry Smith #define __FUNCT__ "AOPetscToApplicationPermuteInt_Basic"
106*1447629fSBarry Smith PetscErrorCode AOPetscToApplicationPermuteInt_Basic(AO ao, PetscInt block, PetscInt *array)
107*1447629fSBarry Smith {
108*1447629fSBarry Smith   AO_Basic       *aobasic = (AO_Basic*) ao->data;
109*1447629fSBarry Smith   PetscInt       *temp;
110*1447629fSBarry Smith   PetscInt       i, j;
111*1447629fSBarry Smith   PetscErrorCode ierr;
112*1447629fSBarry Smith 
113*1447629fSBarry Smith   PetscFunctionBegin;
114*1447629fSBarry Smith   ierr = PetscMalloc(ao->N*block * sizeof(PetscInt), &temp);CHKERRQ(ierr);
115*1447629fSBarry Smith   for (i = 0; i < ao->N; i++) {
116*1447629fSBarry Smith     for (j = 0; j < block; j++) temp[i*block+j] = array[aobasic->petsc[i]*block+j];
117*1447629fSBarry Smith   }
118*1447629fSBarry Smith   ierr = PetscMemcpy(array, temp, ao->N*block * sizeof(PetscInt));CHKERRQ(ierr);
119*1447629fSBarry Smith   ierr = PetscFree(temp);CHKERRQ(ierr);
120*1447629fSBarry Smith   PetscFunctionReturn(0);
121*1447629fSBarry Smith }
122*1447629fSBarry Smith 
123*1447629fSBarry Smith #undef __FUNCT__
124*1447629fSBarry Smith #define __FUNCT__ "AOApplicationToPetscPermuteInt_Basic"
125*1447629fSBarry Smith PetscErrorCode AOApplicationToPetscPermuteInt_Basic(AO ao, PetscInt block, PetscInt *array)
126*1447629fSBarry Smith {
127*1447629fSBarry Smith   AO_Basic       *aobasic = (AO_Basic*) ao->data;
128*1447629fSBarry Smith   PetscInt       *temp;
129*1447629fSBarry Smith   PetscInt       i, j;
130*1447629fSBarry Smith   PetscErrorCode ierr;
131*1447629fSBarry Smith 
132*1447629fSBarry Smith   PetscFunctionBegin;
133*1447629fSBarry Smith   ierr = PetscMalloc(ao->N*block * sizeof(PetscInt), &temp);CHKERRQ(ierr);
134*1447629fSBarry Smith   for (i = 0; i < ao->N; i++) {
135*1447629fSBarry Smith     for (j = 0; j < block; j++) temp[i*block+j] = array[aobasic->app[i]*block+j];
136*1447629fSBarry Smith   }
137*1447629fSBarry Smith   ierr = PetscMemcpy(array, temp, ao->N*block * sizeof(PetscInt));CHKERRQ(ierr);
138*1447629fSBarry Smith   ierr = PetscFree(temp);CHKERRQ(ierr);
139*1447629fSBarry Smith   PetscFunctionReturn(0);
140*1447629fSBarry Smith }
141*1447629fSBarry Smith 
142*1447629fSBarry Smith #undef __FUNCT__
143*1447629fSBarry Smith #define __FUNCT__ "AOPetscToApplicationPermuteReal_Basic"
144*1447629fSBarry Smith PetscErrorCode AOPetscToApplicationPermuteReal_Basic(AO ao, PetscInt block, PetscReal *array)
145*1447629fSBarry Smith {
146*1447629fSBarry Smith   AO_Basic       *aobasic = (AO_Basic*) ao->data;
147*1447629fSBarry Smith   PetscReal      *temp;
148*1447629fSBarry Smith   PetscInt       i, j;
149*1447629fSBarry Smith   PetscErrorCode ierr;
150*1447629fSBarry Smith 
151*1447629fSBarry Smith   PetscFunctionBegin;
152*1447629fSBarry Smith   ierr = PetscMalloc(ao->N*block * sizeof(PetscReal), &temp);CHKERRQ(ierr);
153*1447629fSBarry Smith   for (i = 0; i < ao->N; i++) {
154*1447629fSBarry Smith     for (j = 0; j < block; j++) temp[i*block+j] = array[aobasic->petsc[i]*block+j];
155*1447629fSBarry Smith   }
156*1447629fSBarry Smith   ierr = PetscMemcpy(array, temp, ao->N*block * sizeof(PetscReal));CHKERRQ(ierr);
157*1447629fSBarry Smith   ierr = PetscFree(temp);CHKERRQ(ierr);
158*1447629fSBarry Smith   PetscFunctionReturn(0);
159*1447629fSBarry Smith }
160*1447629fSBarry Smith 
161*1447629fSBarry Smith #undef __FUNCT__
162*1447629fSBarry Smith #define __FUNCT__ "AOApplicationToPetscPermuteReal_Basic"
163*1447629fSBarry Smith PetscErrorCode AOApplicationToPetscPermuteReal_Basic(AO ao, PetscInt block, PetscReal *array)
164*1447629fSBarry Smith {
165*1447629fSBarry Smith   AO_Basic       *aobasic = (AO_Basic*) ao->data;
166*1447629fSBarry Smith   PetscReal      *temp;
167*1447629fSBarry Smith   PetscInt       i, j;
168*1447629fSBarry Smith   PetscErrorCode ierr;
169*1447629fSBarry Smith 
170*1447629fSBarry Smith   PetscFunctionBegin;
171*1447629fSBarry Smith   ierr = PetscMalloc(ao->N*block * sizeof(PetscReal), &temp);CHKERRQ(ierr);
172*1447629fSBarry Smith   for (i = 0; i < ao->N; i++) {
173*1447629fSBarry Smith     for (j = 0; j < block; j++) temp[i*block+j] = array[aobasic->app[i]*block+j];
174*1447629fSBarry Smith   }
175*1447629fSBarry Smith   ierr = PetscMemcpy(array, temp, ao->N*block * sizeof(PetscReal));CHKERRQ(ierr);
176*1447629fSBarry Smith   ierr = PetscFree(temp);CHKERRQ(ierr);
177*1447629fSBarry Smith   PetscFunctionReturn(0);
178*1447629fSBarry Smith }
179*1447629fSBarry Smith 
180*1447629fSBarry Smith static struct _AOOps AOOps_Basic = {
181*1447629fSBarry Smith   AOView_Basic,
182*1447629fSBarry Smith   AODestroy_Basic,
183*1447629fSBarry Smith   AOPetscToApplication_Basic,
184*1447629fSBarry Smith   AOApplicationToPetsc_Basic,
185*1447629fSBarry Smith   AOPetscToApplicationPermuteInt_Basic,
186*1447629fSBarry Smith   AOApplicationToPetscPermuteInt_Basic,
187*1447629fSBarry Smith   AOPetscToApplicationPermuteReal_Basic,
188*1447629fSBarry Smith   AOApplicationToPetscPermuteReal_Basic
189*1447629fSBarry Smith };
190*1447629fSBarry Smith 
191*1447629fSBarry Smith EXTERN_C_BEGIN
192*1447629fSBarry Smith #undef __FUNCT__
193*1447629fSBarry Smith #define __FUNCT__ "AOCreate_Basic"
194*1447629fSBarry Smith PetscErrorCode  AOCreate_Basic(AO ao)
195*1447629fSBarry Smith {
196*1447629fSBarry Smith   AO_Basic       *aobasic;
197*1447629fSBarry Smith   PetscMPIInt    size,rank,count,*lens,*disp;
198*1447629fSBarry Smith   PetscInt       napp,*allpetsc,*allapp,ip,ia,N,i,*petsc=NULL,start;
199*1447629fSBarry Smith   PetscErrorCode ierr;
200*1447629fSBarry Smith   IS             isapp=ao->isapp,ispetsc=ao->ispetsc;
201*1447629fSBarry Smith   MPI_Comm       comm;
202*1447629fSBarry Smith   const PetscInt *myapp,*mypetsc=NULL;
203*1447629fSBarry Smith 
204*1447629fSBarry Smith   PetscFunctionBegin;
205*1447629fSBarry Smith   /* create special struct aobasic */
206*1447629fSBarry Smith   ierr     = PetscNewLog(ao, AO_Basic, &aobasic);CHKERRQ(ierr);
207*1447629fSBarry Smith   ao->data = (void*) aobasic;
208*1447629fSBarry Smith   ierr     = PetscMemcpy(ao->ops,&AOOps_Basic,sizeof(struct _AOOps));CHKERRQ(ierr);
209*1447629fSBarry Smith   ierr     = PetscObjectChangeTypeName((PetscObject)ao,AOBASIC);CHKERRQ(ierr);
210*1447629fSBarry Smith 
211*1447629fSBarry Smith   ierr = ISGetLocalSize(isapp,&napp);CHKERRQ(ierr);
212*1447629fSBarry Smith   ierr = ISGetIndices(isapp,&myapp);CHKERRQ(ierr);
213*1447629fSBarry Smith 
214*1447629fSBarry Smith   ierr = PetscMPIIntCast(napp,&count);CHKERRQ(ierr);
215*1447629fSBarry Smith 
216*1447629fSBarry Smith   /* transmit all lengths to all processors */
217*1447629fSBarry Smith   ierr = PetscObjectGetComm((PetscObject)isapp,&comm);CHKERRQ(ierr);
218*1447629fSBarry Smith   ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr);
219*1447629fSBarry Smith   ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr);
220*1447629fSBarry Smith   ierr = PetscMalloc2(size,PetscMPIInt, &lens,size,PetscMPIInt,&disp);CHKERRQ(ierr);
221*1447629fSBarry Smith   ierr = MPI_Allgather(&count, 1, MPI_INT, lens, 1, MPI_INT, comm);CHKERRQ(ierr);
222*1447629fSBarry Smith   N    =  0;
223*1447629fSBarry Smith   for (i = 0; i < size; i++) {
224*1447629fSBarry Smith     ierr = PetscMPIIntCast(N,disp+i);CHKERRQ(ierr); /* = sum(lens[j]), j< i */
225*1447629fSBarry Smith     N   += lens[i];
226*1447629fSBarry Smith   }
227*1447629fSBarry Smith   ao->N = N;
228*1447629fSBarry Smith   ao->n = N;
229*1447629fSBarry Smith 
230*1447629fSBarry Smith   /* If mypetsc is 0 then use "natural" numbering */
231*1447629fSBarry Smith   if (napp) {
232*1447629fSBarry Smith     if (!ispetsc) {
233*1447629fSBarry Smith       start = disp[rank];
234*1447629fSBarry Smith       ierr  = PetscMalloc((napp+1) * sizeof(PetscInt), &petsc);CHKERRQ(ierr);
235*1447629fSBarry Smith       for (i=0; i<napp; i++) petsc[i] = start + i;
236*1447629fSBarry Smith     } else {
237*1447629fSBarry Smith       ierr  = ISGetIndices(ispetsc,&mypetsc);CHKERRQ(ierr);
238*1447629fSBarry Smith       petsc = (PetscInt*)mypetsc;
239*1447629fSBarry Smith     }
240*1447629fSBarry Smith   }
241*1447629fSBarry Smith 
242*1447629fSBarry Smith   /* get all indices on all processors */
243*1447629fSBarry Smith   ierr = PetscMalloc2(N,PetscInt,&allpetsc,N,PetscInt,&allapp);CHKERRQ(ierr);
244*1447629fSBarry Smith   ierr = MPI_Allgatherv(petsc, count, MPIU_INT, allpetsc, lens, disp, MPIU_INT, comm);CHKERRQ(ierr);
245*1447629fSBarry Smith   ierr = MPI_Allgatherv((void*)myapp, count, MPIU_INT, allapp, lens, disp, MPIU_INT, comm);CHKERRQ(ierr);
246*1447629fSBarry Smith   ierr = PetscFree2(lens,disp);CHKERRQ(ierr);
247*1447629fSBarry Smith 
248*1447629fSBarry Smith #if defined(PETSC_USE_DEBUG)
249*1447629fSBarry Smith   {
250*1447629fSBarry Smith     PetscInt *sorted;
251*1447629fSBarry Smith     ierr = PetscMalloc(N*sizeof(PetscInt),&sorted);CHKERRQ(ierr);
252*1447629fSBarry Smith 
253*1447629fSBarry Smith     ierr = PetscMemcpy(sorted,allpetsc,N*sizeof(PetscInt));CHKERRQ(ierr);
254*1447629fSBarry Smith     ierr = PetscSortInt(N,sorted);CHKERRQ(ierr);
255*1447629fSBarry Smith     for (i=0; i<N; i++) {
256*1447629fSBarry 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]);
257*1447629fSBarry Smith     }
258*1447629fSBarry Smith 
259*1447629fSBarry Smith     ierr = PetscMemcpy(sorted,allapp,N*sizeof(PetscInt));CHKERRQ(ierr);
260*1447629fSBarry Smith     ierr = PetscSortInt(N,sorted);CHKERRQ(ierr);
261*1447629fSBarry Smith     for (i=0; i<N; i++) {
262*1447629fSBarry 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]);
263*1447629fSBarry Smith     }
264*1447629fSBarry Smith 
265*1447629fSBarry Smith     ierr = PetscFree(sorted);CHKERRQ(ierr);
266*1447629fSBarry Smith   }
267*1447629fSBarry Smith #endif
268*1447629fSBarry Smith 
269*1447629fSBarry Smith   /* generate a list of application and PETSc node numbers */
270*1447629fSBarry Smith   ierr = PetscMalloc2(N,PetscInt, &aobasic->app,N,PetscInt,&aobasic->petsc);CHKERRQ(ierr);
271*1447629fSBarry Smith   ierr = PetscLogObjectMemory(ao,2*N*sizeof(PetscInt));CHKERRQ(ierr);
272*1447629fSBarry Smith   ierr = PetscMemzero(aobasic->app, N*sizeof(PetscInt));CHKERRQ(ierr);
273*1447629fSBarry Smith   ierr = PetscMemzero(aobasic->petsc, N*sizeof(PetscInt));CHKERRQ(ierr);
274*1447629fSBarry Smith   for (i = 0; i < N; i++) {
275*1447629fSBarry Smith     ip = allpetsc[i];
276*1447629fSBarry Smith     ia = allapp[i];
277*1447629fSBarry Smith     /* check there are no duplicates */
278*1447629fSBarry 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);
279*1447629fSBarry Smith     aobasic->app[ip] = ia + 1;
280*1447629fSBarry 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);
281*1447629fSBarry Smith     aobasic->petsc[ia] = ip + 1;
282*1447629fSBarry Smith   }
283*1447629fSBarry Smith   if (napp && !mypetsc) {
284*1447629fSBarry Smith     ierr = PetscFree(petsc);CHKERRQ(ierr);
285*1447629fSBarry Smith   }
286*1447629fSBarry Smith   ierr = PetscFree2(allpetsc,allapp);CHKERRQ(ierr);
287*1447629fSBarry Smith   /* shift indices down by one */
288*1447629fSBarry Smith   for (i = 0; i < N; i++) {
289*1447629fSBarry Smith     aobasic->app[i]--;
290*1447629fSBarry Smith     aobasic->petsc[i]--;
291*1447629fSBarry Smith   }
292*1447629fSBarry Smith 
293*1447629fSBarry Smith   ierr = ISRestoreIndices(isapp,&myapp);CHKERRQ(ierr);
294*1447629fSBarry Smith   if (napp) {
295*1447629fSBarry Smith     if (ispetsc) {
296*1447629fSBarry Smith       ierr = ISRestoreIndices(ispetsc,&mypetsc);CHKERRQ(ierr);
297*1447629fSBarry Smith     } else {
298*1447629fSBarry Smith       ierr = PetscFree(petsc);CHKERRQ(ierr);
299*1447629fSBarry Smith     }
300*1447629fSBarry Smith   }
301*1447629fSBarry Smith   PetscFunctionReturn(0);
302*1447629fSBarry Smith }
303*1447629fSBarry Smith EXTERN_C_END
304*1447629fSBarry Smith 
305*1447629fSBarry Smith #undef __FUNCT__
306*1447629fSBarry Smith #define __FUNCT__ "AOCreateBasic"
307*1447629fSBarry Smith /*@C
308*1447629fSBarry Smith    AOCreateBasic - Creates a basic application ordering using two integer arrays.
309*1447629fSBarry Smith 
310*1447629fSBarry Smith    Collective on MPI_Comm
311*1447629fSBarry Smith 
312*1447629fSBarry Smith    Input Parameters:
313*1447629fSBarry Smith +  comm - MPI communicator that is to share AO
314*1447629fSBarry Smith .  napp - size of integer arrays
315*1447629fSBarry Smith .  myapp - integer array that defines an ordering
316*1447629fSBarry Smith -  mypetsc - integer array that defines another ordering (may be NULL to
317*1447629fSBarry Smith              indicate the natural ordering, that is 0,1,2,3,...)
318*1447629fSBarry Smith 
319*1447629fSBarry Smith    Output Parameter:
320*1447629fSBarry Smith .  aoout - the new application ordering
321*1447629fSBarry Smith 
322*1447629fSBarry Smith    Level: beginner
323*1447629fSBarry Smith 
324*1447629fSBarry 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"
325*1447629fSBarry Smith            in the indices. Use AOCreateMapping() or AOCreateMappingIS() if you wish to have "holes" in the indices.
326*1447629fSBarry Smith 
327*1447629fSBarry Smith .keywords: AO, create
328*1447629fSBarry Smith 
329*1447629fSBarry Smith .seealso: AOCreateBasicIS(), AODestroy(), AOPetscToApplication(), AOApplicationToPetsc()
330*1447629fSBarry Smith @*/
331*1447629fSBarry Smith PetscErrorCode  AOCreateBasic(MPI_Comm comm,PetscInt napp,const PetscInt myapp[],const PetscInt mypetsc[],AO *aoout)
332*1447629fSBarry Smith {
333*1447629fSBarry Smith   PetscErrorCode ierr;
334*1447629fSBarry Smith   IS             isapp,ispetsc;
335*1447629fSBarry Smith   const PetscInt *app=myapp,*petsc=mypetsc;
336*1447629fSBarry Smith 
337*1447629fSBarry Smith   PetscFunctionBegin;
338*1447629fSBarry Smith   ierr = ISCreateGeneral(comm,napp,app,PETSC_USE_POINTER,&isapp);CHKERRQ(ierr);
339*1447629fSBarry Smith   if (mypetsc) {
340*1447629fSBarry Smith     ierr = ISCreateGeneral(comm,napp,petsc,PETSC_USE_POINTER,&ispetsc);CHKERRQ(ierr);
341*1447629fSBarry Smith   } else {
342*1447629fSBarry Smith     ispetsc = NULL;
343*1447629fSBarry Smith   }
344*1447629fSBarry Smith   ierr = AOCreateBasicIS(isapp,ispetsc,aoout);CHKERRQ(ierr);
345*1447629fSBarry Smith   ierr = ISDestroy(&isapp);CHKERRQ(ierr);
346*1447629fSBarry Smith   if (mypetsc) {
347*1447629fSBarry Smith     ierr = ISDestroy(&ispetsc);CHKERRQ(ierr);
348*1447629fSBarry Smith   }
349*1447629fSBarry Smith   PetscFunctionReturn(0);
350*1447629fSBarry Smith }
351*1447629fSBarry Smith 
352*1447629fSBarry Smith #undef __FUNCT__
353*1447629fSBarry Smith #define __FUNCT__ "AOCreateBasicIS"
354*1447629fSBarry Smith /*@C
355*1447629fSBarry Smith    AOCreateBasicIS - Creates a basic application ordering using two index sets.
356*1447629fSBarry Smith 
357*1447629fSBarry Smith    Collective on IS
358*1447629fSBarry Smith 
359*1447629fSBarry Smith    Input Parameters:
360*1447629fSBarry Smith +  isapp - index set that defines an ordering
361*1447629fSBarry Smith -  ispetsc - index set that defines another ordering (may be NULL to use the
362*1447629fSBarry Smith              natural ordering)
363*1447629fSBarry Smith 
364*1447629fSBarry Smith    Output Parameter:
365*1447629fSBarry Smith .  aoout - the new application ordering
366*1447629fSBarry Smith 
367*1447629fSBarry Smith    Level: beginner
368*1447629fSBarry Smith 
369*1447629fSBarry 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;
370*1447629fSBarry Smith            that is there cannot be any "holes"
371*1447629fSBarry Smith 
372*1447629fSBarry Smith .keywords: AO, create
373*1447629fSBarry Smith 
374*1447629fSBarry Smith .seealso: AOCreateBasic(),  AODestroy()
375*1447629fSBarry Smith @*/
376*1447629fSBarry Smith PetscErrorCode AOCreateBasicIS(IS isapp,IS ispetsc,AO *aoout)
377*1447629fSBarry Smith {
378*1447629fSBarry Smith   PetscErrorCode ierr;
379*1447629fSBarry Smith   MPI_Comm       comm;
380*1447629fSBarry Smith   AO             ao;
381*1447629fSBarry Smith 
382*1447629fSBarry Smith   PetscFunctionBegin;
383*1447629fSBarry Smith   ierr   = PetscObjectGetComm((PetscObject)isapp,&comm);CHKERRQ(ierr);
384*1447629fSBarry Smith   ierr   = AOCreate(comm,&ao);CHKERRQ(ierr);
385*1447629fSBarry Smith   ierr   = AOSetIS(ao,isapp,ispetsc);CHKERRQ(ierr);
386*1447629fSBarry Smith   ierr   = AOSetType(ao,AOBASIC);CHKERRQ(ierr);
387*1447629fSBarry Smith   *aoout = ao;
388*1447629fSBarry Smith   PetscFunctionReturn(0);
389*1447629fSBarry Smith }
390*1447629fSBarry Smith 
391