Actual source code: aobasic.c
1: /*$Id: aobasic.c,v 1.60 2001/03/23 23:24:52 balay Exp $*/
3: /*
4: The most basic AO application ordering routines. These store the
5: entire orderings on each processor.
6: */
8: #include src/dm/ao/aoimpl.h
9: #include petscsys.h
11: typedef struct {
12: int N;
13: int *app,*petsc; /* app[i] is the partner for the ith PETSc slot */
14: /* petsc[j] is the partner for the jth app slot */
15: } AO_Basic;
17: /*
18: All processors have the same data so processor 1 prints it
19: */
22: int AOView_Basic(AO ao,PetscViewer viewer)
23: {
24: int rank,ierr,i;
25: AO_Basic *aodebug = (AO_Basic*)ao->data;
26: PetscTruth isascii;
29: MPI_Comm_rank(ao->comm,&rank);
30: if (!rank){
31: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
32: if (isascii) {
33: PetscViewerASCIIPrintf(viewer,"Number of elements in ordering %d\n",aodebug->N);
34: PetscViewerASCIIPrintf(viewer, "PETSc->App App->PETSc\n");
35: for (i=0; i<aodebug->N; i++) {
36: PetscViewerASCIIPrintf(viewer,"%3d %3d %3d %3d\n",i,aodebug->app[i],i,aodebug->petsc[i]);
37: }
38: } else {
39: SETERRQ1(1,"Viewer type %s not supported for AOData basic",((PetscObject)viewer)->type_name);
40: }
41: }
42: PetscViewerFlush(viewer);
43: return(0);
44: }
48: int AODestroy_Basic(AO ao)
49: {
50: AO_Basic *aodebug = (AO_Basic*)ao->data;
51: int ierr;
54: PetscFree(aodebug->app);
55: PetscFree(ao->data);
56: return(0);
57: }
61: int AOBasicGetIndices_Private(AO ao,int **app,int **petsc)
62: {
63: AO_Basic *basic = (AO_Basic*)ao->data;
66: if (app) *app = basic->app;
67: if (petsc) *petsc = basic->petsc;
68: return(0);
69: }
73: int AOPetscToApplication_Basic(AO ao,int n,int *ia)
74: {
75: int i;
76: AO_Basic *aodebug = (AO_Basic*)ao->data;
79: for (i=0; i<n; i++) {
80: if (ia[i] >= 0) {ia[i] = aodebug->app[ia[i]];}
81: }
82: return(0);
83: }
87: int AOApplicationToPetsc_Basic(AO ao,int n,int *ia)
88: {
89: int i;
90: AO_Basic *aodebug = (AO_Basic*)ao->data;
93: for (i=0; i<n; i++) {
94: if (ia[i] >= 0) {ia[i] = aodebug->petsc[ia[i]];}
95: }
96: return(0);
97: }
101: int AOPetscToApplicationPermuteInt_Basic(AO ao, int block, int *array)
102: {
103: AO_Basic *aodebug = (AO_Basic *) ao->data;
104: int *temp;
105: int i, j;
106: int ierr;
109: PetscMalloc(aodebug->N*block * sizeof(int), &temp);
110: for(i = 0; i < aodebug->N; i++) {
111: for(j = 0; j < block; j++) temp[i*block+j] = array[aodebug->petsc[i]*block+j];
112: }
113: PetscMemcpy(array, temp, aodebug->N*block * sizeof(int));
114: PetscFree(temp);
115: return(0);
116: }
120: int AOApplicationToPetscPermuteInt_Basic(AO ao, int block, int *array)
121: {
122: AO_Basic *aodebug = (AO_Basic *) ao->data;
123: int *temp;
124: int i, j;
125: int ierr;
128: PetscMalloc(aodebug->N*block * sizeof(int), &temp);
129: for(i = 0; i < aodebug->N; i++) {
130: for(j = 0; j < block; j++) temp[i*block+j] = array[aodebug->app[i]*block+j];
131: }
132: PetscMemcpy(array, temp, aodebug->N*block * sizeof(int));
133: PetscFree(temp);
134: return(0);
135: }
139: int AOPetscToApplicationPermuteReal_Basic(AO ao, int block, double *array)
140: {
141: AO_Basic *aodebug = (AO_Basic *) ao->data;
142: double *temp;
143: int i, j;
144: int ierr;
147: PetscMalloc(aodebug->N*block * sizeof(double), &temp);
148: for(i = 0; i < aodebug->N; i++) {
149: for(j = 0; j < block; j++) temp[i*block+j] = array[aodebug->petsc[i]*block+j];
150: }
151: PetscMemcpy(array, temp, aodebug->N*block * sizeof(double));
152: PetscFree(temp);
153: return(0);
154: }
158: int AOApplicationToPetscPermuteReal_Basic(AO ao, int block, double *array)
159: {
160: AO_Basic *aodebug = (AO_Basic *) ao->data;
161: double *temp;
162: int i, j;
163: int ierr;
166: PetscMalloc(aodebug->N*block * sizeof(double), &temp);
167: for(i = 0; i < aodebug->N; i++) {
168: for(j = 0; j < block; j++) temp[i*block+j] = array[aodebug->app[i]*block+j];
169: }
170: PetscMemcpy(array, temp, aodebug->N*block * sizeof(double));
171: PetscFree(temp);
172: return(0);
173: }
175: static struct _AOOps AOops = {AOView_Basic,
176: AODestroy_Basic,
177: AOPetscToApplication_Basic,
178: AOApplicationToPetsc_Basic,
179: AOPetscToApplicationPermuteInt_Basic,
180: AOApplicationToPetscPermuteInt_Basic,
181: AOPetscToApplicationPermuteReal_Basic,
182: AOApplicationToPetscPermuteReal_Basic};
186: /*@C
187: AOCreateBasic - Creates a basic application ordering using two integer arrays.
189: Collective on MPI_Comm
191: Input Parameters:
192: + comm - MPI communicator that is to share AO
193: . napp - size of integer arrays
194: . myapp - integer array that defines an ordering
195: - mypetsc - integer array that defines another ordering (may be PETSC_NULL to
196: indicate the natural ordering)
198: Output Parameter:
199: . aoout - the new application ordering
201: Options Database Key:
202: . -ao_view - call AOView() at the conclusion of AOCreateBasic()
204: Level: beginner
206: .keywords: AO, create
208: .seealso: AOCreateBasicIS(), AODestroy()
209: @*/
210: int AOCreateBasic(MPI_Comm comm,int napp,const int myapp[],const int mypetsc[],AO *aoout)
211: {
212: AO_Basic *aobasic;
213: AO ao;
214: int *lens,size,rank,N,i,*petsc,start;
215: int *allpetsc,*allapp,*disp,ip,ia;
216: PetscTruth opt;
217: int ierr;
221: *aoout = 0;
222: #ifndef PETSC_USE_DYNAMIC_LIBRARIES
223: DMInitializePackage(PETSC_NULL);
224: #endif
226: PetscHeaderCreate(ao, _p_AO, struct _AOOps, AO_COOKIE, AO_BASIC, "AO", comm, AODestroy, AOView);
227: PetscLogObjectCreate(ao);
228: PetscNew(AO_Basic, &aobasic);
229: PetscLogObjectMemory(ao, sizeof(struct _p_AO) + sizeof(AO_Basic));
231: PetscMemcpy(ao->ops, &AOops, sizeof(AOops));
232: ao->data = (void *) aobasic;
234: /* transmit all lengths to all processors */
235: MPI_Comm_size(comm, &size);
236: MPI_Comm_rank(comm, &rank);
237: PetscMalloc(2*size * sizeof(int), &lens);
238: disp = lens + size;
239: MPI_Allgather(&napp, 1, MPI_INT, lens, 1, MPI_INT, comm);
240: N = 0;
241: for(i = 0; i < size; i++) {
242: disp[i] = N;
243: N += lens[i];
244: }
245: aobasic->N = N;
247: /*
248: If mypetsc is 0 then use "natural" numbering
249: */
250: if (!mypetsc) {
251: start = disp[rank];
252: PetscMalloc((napp+1) * sizeof(int), &petsc);
253: for (i=0; i<napp; i++) {
254: petsc[i] = start + i;
255: }
256: } else {
257: petsc = (int *)mypetsc;
258: }
260: /* get all indices on all processors */
261: PetscMalloc(2*N * sizeof(int), &allpetsc);
262: allapp = allpetsc + N;
263: MPI_Allgatherv(petsc, napp, MPI_INT, allpetsc, lens, disp, MPI_INT, comm);
264: MPI_Allgatherv((void*)myapp, napp, MPI_INT, allapp, lens, disp, MPI_INT, comm);
265: PetscFree(lens);
267: /* generate a list of application and PETSc node numbers */
268: PetscMalloc(2*N * sizeof(int), &aobasic->app);
269: PetscLogObjectMemory(ao,2*N*sizeof(int));
270: aobasic->petsc = aobasic->app + N;
271: PetscMemzero(aobasic->app, 2*N*sizeof(int));
272: for(i = 0; i < N; i++) {
273: ip = allpetsc[i];
274: ia = allapp[i];
275: /* check there are no duplicates */
276: if (aobasic->app[ip]) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Duplicate in PETSc ordering");
277: aobasic->app[ip] = ia + 1;
278: if (aobasic->petsc[ia]) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Duplicate in Application ordering");
279: aobasic->petsc[ia] = ip + 1;
280: }
281: if (!mypetsc) {
282: PetscFree(petsc);
283: }
284: PetscFree(allpetsc);
285: /* shift indices down by one */
286: for(i = 0; i < N; i++) {
287: aobasic->app[i]--;
288: aobasic->petsc[i]--;
289: }
291: PetscOptionsHasName(PETSC_NULL, "-ao_view", &opt);
292: if (opt) {
293: AOView(ao, PETSC_VIEWER_STDOUT_SELF);
294: }
296: *aoout = ao;
297: return(0);
298: }
302: /*@C
303: AOCreateBasicIS - Creates a basic application ordering using two index sets.
305: Collective on IS
307: Input Parameters:
308: + isapp - index set that defines an ordering
309: - ispetsc - index set that defines another ordering (may be PETSC_NULL to use the
310: natural ordering)
312: Output Parameter:
313: . aoout - the new application ordering
315: Options Database Key:
316: - -ao_view - call AOView() at the conclusion of AOCreateBasicIS()
318: Level: beginner
320: .keywords: AO, create
322: .seealso: AOCreateBasic(), AODestroy()
323: @*/
324: int AOCreateBasicIS(IS isapp,IS ispetsc,AO *aoout)
325: {
326: int *mypetsc = 0,*myapp,ierr,napp,npetsc;
327: MPI_Comm comm;
330: PetscObjectGetComm((PetscObject)isapp,&comm);
331: ISGetLocalSize(isapp,&napp);
332: if (ispetsc) {
333: ISGetLocalSize(ispetsc,&npetsc);
334: if (napp != npetsc) SETERRQ(PETSC_ERR_ARG_SIZ,"Local IS lengths must match");
335: ISGetIndices(ispetsc,&mypetsc);
336: }
337: ISGetIndices(isapp,&myapp);
339: AOCreateBasic(comm,napp,myapp,mypetsc,aoout);
341: ISRestoreIndices(isapp,&myapp);
342: if (ispetsc) {
343: ISRestoreIndices(ispetsc,&mypetsc);
344: }
345: return(0);
346: }