Actual source code: general.c
2: /*
3: Provides the functions for index sets (IS) defined by a list of integers.
4: */
5: #include <../src/vec/is/is/impls/general/general.h>
6: #include <petsc/private/viewerhdf5impl.h>
8: static PetscErrorCode ISDuplicate_General(IS is,IS *newIS)
9: {
11: IS_General *sub = (IS_General*)is->data;
12: PetscInt n;
15: PetscLayoutGetLocalSize(is->map, &n);
16: ISCreateGeneral(PetscObjectComm((PetscObject) is), n, sub->idx, PETSC_COPY_VALUES, newIS);
17: return(0);
18: }
20: static PetscErrorCode ISDestroy_General(IS is)
21: {
22: IS_General *is_general = (IS_General*)is->data;
26: if (is_general->allocated) {PetscFree(is_general->idx);}
27: PetscObjectComposeFunction((PetscObject)is,"ISGeneralSetIndices_C",NULL);
28: PetscObjectComposeFunction((PetscObject)is,"ISGeneralFilter_C",NULL);
29: PetscFree(is->data);
30: return(0);
31: }
33: static PetscErrorCode ISCopy_General(IS is,IS isy)
34: {
35: IS_General *is_general = (IS_General*)is->data,*isy_general = (IS_General*)isy->data;
36: PetscInt n, N, ny, Ny;
40: PetscLayoutGetLocalSize(is->map, &n);
41: PetscLayoutGetSize(is->map, &N);
42: PetscLayoutGetLocalSize(isy->map, &ny);
43: PetscLayoutGetSize(isy->map, &Ny);
44: if (n != ny || N != Ny) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Index sets incompatible");
45: PetscArraycpy(isy_general->idx,is_general->idx,n);
46: return(0);
47: }
49: static PetscErrorCode ISOnComm_General(IS is,MPI_Comm comm,PetscCopyMode mode,IS *newis)
50: {
52: IS_General *sub = (IS_General*)is->data;
53: PetscInt n;
56: if (mode == PETSC_OWN_POINTER) SETERRQ(comm,PETSC_ERR_ARG_WRONG,"Cannot use PETSC_OWN_POINTER");
57: PetscLayoutGetLocalSize(is->map, &n);
58: ISCreateGeneral(comm,n,sub->idx,mode,newis);
59: return(0);
60: }
62: static PetscErrorCode ISSetBlockSize_General(IS is,PetscInt bs)
63: {
67: PetscLayoutSetBlockSize(is->map, bs);
68: return(0);
69: }
71: static PetscErrorCode ISContiguousLocal_General(IS is,PetscInt gstart,PetscInt gend,PetscInt *start,PetscBool *contig)
72: {
73: IS_General *sub = (IS_General*)is->data;
74: PetscInt n,i,p;
78: *start = 0;
79: *contig = PETSC_TRUE;
80: PetscLayoutGetLocalSize(is->map, &n);
81: if (!n) return(0);
82: p = sub->idx[0];
83: if (p < gstart) goto nomatch;
84: *start = p - gstart;
85: if (n > gend-p) goto nomatch;
86: for (i=1; i<n; i++,p++) {
87: if (sub->idx[i] != p+1) goto nomatch;
88: }
89: return(0);
90: nomatch:
91: *start = -1;
92: *contig = PETSC_FALSE;
93: return(0);
94: }
96: static PetscErrorCode ISLocate_General(IS is,PetscInt key,PetscInt *location)
97: {
98: IS_General *sub = (IS_General*)is->data;
99: PetscInt numIdx, i;
100: PetscBool sorted;
104: PetscLayoutGetLocalSize(is->map,&numIdx);
105: ISGetInfo(is,IS_SORTED,IS_LOCAL,PETSC_TRUE,&sorted);
106: if (sorted) {PetscFindInt(key,numIdx,sub->idx,location);}
107: else {
108: const PetscInt *idx = sub->idx;
110: *location = -1;
111: for (i = 0; i < numIdx; i++) {
112: if (idx[i] == key) {
113: *location = i;
114: return(0);
115: }
116: }
117: }
118: return(0);
119: }
121: static PetscErrorCode ISGetIndices_General(IS in,const PetscInt *idx[])
122: {
123: IS_General *sub = (IS_General*)in->data;
126: *idx = sub->idx;
127: return(0);
128: }
130: static PetscErrorCode ISRestoreIndices_General(IS in,const PetscInt *idx[])
131: {
132: IS_General *sub = (IS_General*)in->data;
135: /* F90Array1dCreate() inside ISRestoreArrayF90() does not keep array when zero length array */
136: if (in->map->n > 0 && *idx != sub->idx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must restore with value from ISGetIndices()");
137: return(0);
138: }
140: static PetscErrorCode ISInvertPermutation_General(IS is,PetscInt nlocal,IS *isout)
141: {
142: IS_General *sub = (IS_General*)is->data;
143: PetscInt i,*ii,n,nstart;
144: const PetscInt *idx = sub->idx;
145: PetscMPIInt size;
146: IS istmp,nistmp;
150: PetscLayoutGetLocalSize(is->map, &n);
151: MPI_Comm_size(PetscObjectComm((PetscObject)is),&size);
152: if (size == 1) {
153: PetscMalloc1(n,&ii);
154: for (i=0; i<n; i++) ii[idx[i]] = i;
155: ISCreateGeneral(PETSC_COMM_SELF,n,ii,PETSC_OWN_POINTER,isout);
156: ISSetPermutation(*isout);
157: } else {
158: /* crude, nonscalable get entire IS on each processor */
159: ISAllGather(is,&istmp);
160: ISSetPermutation(istmp);
161: ISInvertPermutation(istmp,PETSC_DECIDE,&nistmp);
162: ISDestroy(&istmp);
163: /* get the part we need */
164: if (nlocal == PETSC_DECIDE) nlocal = n;
165: MPI_Scan(&nlocal,&nstart,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)is));
166: if (PetscDefined(USE_DEBUG)) {
167: PetscInt N;
168: PetscMPIInt rank;
169: MPI_Comm_rank(PetscObjectComm((PetscObject)is),&rank);
170: PetscLayoutGetSize(is->map, &N);
171: if (rank == size-1) {
172: if (nstart != N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Sum of nlocal lengths %d != total IS length %d",nstart,N);
173: }
174: }
175: nstart -= nlocal;
176: ISGetIndices(nistmp,&idx);
177: ISCreateGeneral(PetscObjectComm((PetscObject)is),nlocal,idx+nstart,PETSC_COPY_VALUES,isout);
178: ISRestoreIndices(nistmp,&idx);
179: ISDestroy(&nistmp);
180: }
181: return(0);
182: }
184: #if defined(PETSC_HAVE_HDF5)
185: static PetscErrorCode ISView_General_HDF5(IS is, PetscViewer viewer)
186: {
187: PetscViewer_HDF5 *hdf5 = (PetscViewer_HDF5*) viewer->data;
188: hid_t filespace; /* file dataspace identifier */
189: hid_t chunkspace; /* chunk dataset property identifier */
190: hid_t dset_id; /* dataset identifier */
191: hid_t memspace; /* memory dataspace identifier */
192: hid_t inttype; /* int type (H5T_NATIVE_INT or H5T_NATIVE_LLONG) */
193: hid_t file_id, group;
194: hsize_t dim, maxDims[3], dims[3], chunkDims[3], count[3],offset[3];
195: PetscBool timestepping;
196: PetscInt bs, N, n, timestep=PETSC_MIN_INT, low;
197: hsize_t chunksize;
198: const PetscInt *ind;
199: const char *isname;
200: PetscErrorCode ierr;
203: ISGetBlockSize(is,&bs);
204: bs = PetscMax(bs, 1); /* If N = 0, bs = 0 as well */
205: PetscViewerHDF5OpenGroup(viewer, &file_id, &group);
206: PetscViewerHDF5IsTimestepping(viewer, ×tepping);
207: if (timestepping) {
208: PetscViewerHDF5GetTimestep(viewer, ×tep);
209: }
211: /* Create the dataspace for the dataset.
212: *
213: * dims - holds the current dimensions of the dataset
214: *
215: * maxDims - holds the maximum dimensions of the dataset (unlimited
216: * for the number of time steps with the current dimensions for the
217: * other dimensions; so only additional time steps can be added).
218: *
219: * chunkDims - holds the size of a single time step (required to
220: * permit extending dataset).
221: */
222: dim = 0;
223: chunksize = 1;
224: if (timestep >= 0) {
225: dims[dim] = timestep+1;
226: maxDims[dim] = H5S_UNLIMITED;
227: chunkDims[dim] = 1;
228: ++dim;
229: }
230: ISGetSize(is, &N);
231: ISGetLocalSize(is, &n);
232: PetscHDF5IntCast(N/bs,dims + dim);
234: maxDims[dim] = dims[dim];
235: chunkDims[dim] = PetscMax(1,dims[dim]);
236: chunksize *= chunkDims[dim];
237: ++dim;
238: if (bs >= 1) {
239: dims[dim] = bs;
240: maxDims[dim] = dims[dim];
241: chunkDims[dim] = dims[dim];
242: chunksize *= chunkDims[dim];
243: ++dim;
244: }
245: /* hdf5 chunks must be less than 4GB */
246: if (chunksize > PETSC_HDF5_MAX_CHUNKSIZE/64) {
247: if (bs >= 1) {
248: if (chunkDims[dim-2] > (PetscInt)PetscSqrtReal((PetscReal)(PETSC_HDF5_MAX_CHUNKSIZE/64))) {
249: chunkDims[dim-2] = (PetscInt)PetscSqrtReal((PetscReal)(PETSC_HDF5_MAX_CHUNKSIZE/64));
250: } if (chunkDims[dim-1] > (PetscInt)PetscSqrtReal((PetscReal)(PETSC_HDF5_MAX_CHUNKSIZE/64))) {
251: chunkDims[dim-1] = (PetscInt)PetscSqrtReal((PetscReal)(PETSC_HDF5_MAX_CHUNKSIZE/64));
252: }
253: } else {
254: chunkDims[dim-1] = PETSC_HDF5_MAX_CHUNKSIZE/64;
255: }
256: }
257: PetscStackCallHDF5Return(filespace,H5Screate_simple,(dim, dims, maxDims));
259: #if defined(PETSC_USE_64BIT_INDICES)
260: inttype = H5T_NATIVE_LLONG;
261: #else
262: inttype = H5T_NATIVE_INT;
263: #endif
265: /* Create the dataset with default properties and close filespace */
266: PetscObjectGetName((PetscObject) is, &isname);
267: if (!H5Lexists(group, isname, H5P_DEFAULT)) {
268: /* Create chunk */
269: PetscStackCallHDF5Return(chunkspace,H5Pcreate,(H5P_DATASET_CREATE));
270: PetscStackCallHDF5(H5Pset_chunk,(chunkspace, dim, chunkDims));
272: PetscStackCallHDF5Return(dset_id,H5Dcreate2,(group, isname, inttype, filespace, H5P_DEFAULT, chunkspace, H5P_DEFAULT));
273: PetscStackCallHDF5(H5Pclose,(chunkspace));
274: } else {
275: PetscStackCallHDF5Return(dset_id,H5Dopen2,(group, isname, H5P_DEFAULT));
276: PetscStackCallHDF5(H5Dset_extent,(dset_id, dims));
277: }
278: PetscStackCallHDF5(H5Sclose,(filespace));
280: /* Each process defines a dataset and writes it to the hyperslab in the file */
281: dim = 0;
282: if (timestep >= 0) {
283: count[dim] = 1;
284: ++dim;
285: }
286: PetscHDF5IntCast(n/bs,count + dim);
287: ++dim;
288: if (bs >= 1) {
289: count[dim] = bs;
290: ++dim;
291: }
292: if (n > 0 || H5_VERSION_GE(1,10,0)) {
293: PetscStackCallHDF5Return(memspace,H5Screate_simple,(dim, count, NULL));
294: } else {
295: /* Can't create dataspace with zero for any dimension, so create null dataspace. */
296: PetscStackCallHDF5Return(memspace,H5Screate,(H5S_NULL));
297: }
299: /* Select hyperslab in the file */
300: PetscLayoutGetRange(is->map, &low, NULL);
301: dim = 0;
302: if (timestep >= 0) {
303: offset[dim] = timestep;
304: ++dim;
305: }
306: PetscHDF5IntCast(low/bs,offset + dim);
307: ++dim;
308: if (bs >= 1) {
309: offset[dim] = 0;
310: ++dim;
311: }
312: if (n > 0 || H5_VERSION_GE(1,10,0)) {
313: PetscStackCallHDF5Return(filespace,H5Dget_space,(dset_id));
314: PetscStackCallHDF5(H5Sselect_hyperslab,(filespace, H5S_SELECT_SET, offset, NULL, count, NULL));
315: } else {
316: /* Create null filespace to match null memspace. */
317: PetscStackCallHDF5Return(filespace,H5Screate,(H5S_NULL));
318: }
320: ISGetIndices(is, &ind);
321: PetscStackCallHDF5(H5Dwrite,(dset_id, inttype, memspace, filespace, hdf5->dxpl_id, ind));
322: PetscStackCallHDF5(H5Fflush,(file_id, H5F_SCOPE_GLOBAL));
323: ISRestoreIndices(is, &ind);
325: /* Close/release resources */
326: PetscStackCallHDF5(H5Gclose,(group));
327: PetscStackCallHDF5(H5Sclose,(filespace));
328: PetscStackCallHDF5(H5Sclose,(memspace));
329: PetscStackCallHDF5(H5Dclose,(dset_id));
331: PetscViewerHDF5WriteObjectAttribute(viewer,(PetscObject)is,"timestepping",PETSC_BOOL,×tepping);
332: PetscInfo1(is, "Wrote IS object with name %s\n", isname);
333: return(0);
334: }
335: #endif
337: static PetscErrorCode ISView_General(IS is,PetscViewer viewer)
338: {
339: IS_General *sub = (IS_General*)is->data;
341: PetscInt i,n,*idx = sub->idx;
342: PetscBool iascii,isbinary,ishdf5;
345: PetscLayoutGetLocalSize(is->map, &n);
346: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
347: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);
348: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5);
349: if (iascii) {
350: MPI_Comm comm;
351: PetscMPIInt rank,size;
352: PetscViewerFormat fmt;
353: PetscBool isperm;
355: PetscObjectGetComm((PetscObject)viewer,&comm);
356: MPI_Comm_rank(comm,&rank);
357: MPI_Comm_size(comm,&size);
359: PetscViewerGetFormat(viewer,&fmt);
360: ISGetInfo(is,IS_PERMUTATION,IS_LOCAL,PETSC_FALSE,&isperm);
361: if (isperm && fmt != PETSC_VIEWER_ASCII_MATLAB) {PetscViewerASCIIPrintf(viewer,"Index set is permutation\n");}
362: PetscViewerASCIIPushSynchronized(viewer);
363: if (size > 1) {
364: if (fmt == PETSC_VIEWER_ASCII_MATLAB) {
365: const char* name;
367: PetscObjectGetName((PetscObject)is,&name);
368: PetscViewerASCIISynchronizedPrintf(viewer,"%s_%d = [...\n",name,rank);
369: for (i=0; i<n; i++) {
370: PetscViewerASCIISynchronizedPrintf(viewer,"%D\n",idx[i]+1);
371: }
372: PetscViewerASCIISynchronizedPrintf(viewer,"];\n");
373: } else {
374: PetscInt st = 0;
376: if (fmt == PETSC_VIEWER_ASCII_INDEX) st = is->map->rstart;
377: PetscViewerASCIISynchronizedPrintf(viewer,"[%d] Number of indices in set %D\n",rank,n);
378: for (i=0; i<n; i++) {
379: PetscViewerASCIISynchronizedPrintf(viewer,"[%d] %D %D\n",rank,i + st,idx[i]);
380: }
381: }
382: } else {
383: if (fmt == PETSC_VIEWER_ASCII_MATLAB) {
384: const char* name;
386: PetscObjectGetName((PetscObject)is,&name);
387: PetscViewerASCIISynchronizedPrintf(viewer,"%s = [...\n",name);
388: for (i=0; i<n; i++) {
389: PetscViewerASCIISynchronizedPrintf(viewer,"%D\n",idx[i]+1);
390: }
391: PetscViewerASCIISynchronizedPrintf(viewer,"];\n");
392: } else {
393: PetscInt st = 0;
395: if (fmt == PETSC_VIEWER_ASCII_INDEX) st = is->map->rstart;
396: PetscViewerASCIISynchronizedPrintf(viewer,"Number of indices in set %D\n",n);
397: for (i=0; i<n; i++) {
398: PetscViewerASCIISynchronizedPrintf(viewer,"%D %D\n",i + st,idx[i]);
399: }
400: }
401: }
402: PetscViewerFlush(viewer);
403: PetscViewerASCIIPopSynchronized(viewer);
404: } else if (isbinary) {
405: ISView_Binary(is,viewer);
406: } else if (ishdf5) {
407: #if defined(PETSC_HAVE_HDF5)
408: ISView_General_HDF5(is,viewer);
409: #endif
410: }
411: return(0);
412: }
414: static PetscErrorCode ISSort_General(IS is)
415: {
416: IS_General *sub = (IS_General*)is->data;
417: PetscInt n;
421: PetscLayoutGetLocalSize(is->map, &n);
422: PetscIntSortSemiOrdered(n,sub->idx);
423: return(0);
424: }
426: static PetscErrorCode ISSortRemoveDups_General(IS is)
427: {
428: IS_General *sub = (IS_General*)is->data;
429: PetscLayout map;
430: PetscInt n;
431: PetscBool sorted;
435: PetscLayoutGetLocalSize(is->map, &n);
436: ISGetInfo(is,IS_SORTED,IS_LOCAL,PETSC_TRUE,&sorted);
437: if (sorted) {
438: PetscSortedRemoveDupsInt(&n,sub->idx);
439: } else {
440: PetscSortRemoveDupsInt(&n,sub->idx);
441: }
442: PetscLayoutCreateFromSizes(PetscObjectComm((PetscObject)is), n, PETSC_DECIDE, is->map->bs, &map);
443: PetscLayoutDestroy(&is->map);
444: is->map = map;
445: return(0);
446: }
448: static PetscErrorCode ISSorted_General(IS is,PetscBool *flg)
449: {
453: ISGetInfo(is,IS_SORTED,IS_LOCAL,PETSC_TRUE,flg);
454: return(0);
455: }
457: PetscErrorCode ISToGeneral_General(IS is)
458: {
460: return(0);
461: }
463: static struct _ISOps myops = { ISGetIndices_General,
464: ISRestoreIndices_General,
465: ISInvertPermutation_General,
466: ISSort_General,
467: ISSortRemoveDups_General,
468: ISSorted_General,
469: ISDuplicate_General,
470: ISDestroy_General,
471: ISView_General,
472: ISLoad_Default,
473: ISCopy_General,
474: ISToGeneral_General,
475: ISOnComm_General,
476: ISSetBlockSize_General,
477: ISContiguousLocal_General,
478: ISLocate_General,
479: /* no specializations of {sorted,unique,perm,interval}{local,global}
480: * because the default checks in ISGetInfo_XXX in index.c are exactly
481: * what we would do for ISGeneral */
482: NULL,
483: NULL,
484: NULL,
485: NULL,
486: NULL,
487: NULL,
488: NULL,
489: NULL};
491: PETSC_INTERN PetscErrorCode ISSetUp_General(IS);
493: PetscErrorCode ISSetUp_General(IS is)
494: {
496: IS_General *sub = (IS_General*)is->data;
497: const PetscInt *idx = sub->idx;
498: PetscInt n,i,min,max;
501: PetscLayoutGetLocalSize(is->map, &n);
503: if (n) {
504: min = max = idx[0];
505: for (i=1; i<n; i++) {
506: if (idx[i] < min) min = idx[i];
507: if (idx[i] > max) max = idx[i];
508: }
509: is->min = min;
510: is->max = max;
511: } else {
512: is->min = PETSC_MAX_INT;
513: is->max = PETSC_MIN_INT;
514: }
515: return(0);
516: }
518: /*@
519: ISCreateGeneral - Creates a data structure for an index set
520: containing a list of integers.
522: Collective
524: Input Parameters:
525: + comm - the MPI communicator
526: . n - the length of the index set
527: . idx - the list of integers
528: - mode - PETSC_COPY_VALUES, PETSC_OWN_POINTER, or PETSC_USE_POINTER; see PetscCopyMode for meaning of this flag.
530: Output Parameter:
531: . is - the new index set
533: Notes:
534: When the communicator is not MPI_COMM_SELF, the operations on IS are NOT
535: conceptually the same as MPI_Group operations. The IS are then
536: distributed sets of indices and thus certain operations on them are
537: collective.
539: Level: beginner
541: .seealso: ISCreateStride(), ISCreateBlock(), ISAllGather(), PETSC_COPY_VALUES, PETSC_OWN_POINTER, PETSC_USE_POINTER, PetscCopyMode
542: @*/
543: PetscErrorCode ISCreateGeneral(MPI_Comm comm,PetscInt n,const PetscInt idx[],PetscCopyMode mode,IS *is)
544: {
548: ISCreate(comm,is);
549: ISSetType(*is,ISGENERAL);
550: ISGeneralSetIndices(*is,n,idx,mode);
551: return(0);
552: }
554: /*@
555: ISGeneralSetIndices - Sets the indices for an ISGENERAL index set
557: Collective on IS
559: Input Parameters:
560: + is - the index set
561: . n - the length of the index set
562: . idx - the list of integers
563: - mode - see PetscCopyMode for meaning of this flag.
565: Level: beginner
567: .seealso: ISCreateGeneral(), ISCreateStride(), ISCreateBlock(), ISAllGather(), ISBlockSetIndices(), ISGENERAL, PetscCopyMode
568: @*/
569: PetscErrorCode ISGeneralSetIndices(IS is,PetscInt n,const PetscInt idx[],PetscCopyMode mode)
570: {
574: ISClearInfoCache(is,PETSC_FALSE);
575: PetscUseMethod(is,"ISGeneralSetIndices_C",(IS,PetscInt,const PetscInt[],PetscCopyMode),(is,n,idx,mode));
576: return(0);
577: }
579: PetscErrorCode ISGeneralSetIndices_General(IS is,PetscInt n,const PetscInt idx[],PetscCopyMode mode)
580: {
581: PetscLayout map;
583: IS_General *sub = (IS_General*)is->data;
586: if (n < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"length < 0");
589: PetscLayoutCreateFromSizes(PetscObjectComm((PetscObject)is),n,PETSC_DECIDE,is->map->bs,&map);
590: PetscLayoutDestroy(&is->map);
591: is->map = map;
593: if (sub->allocated) {PetscFree(sub->idx);}
594: if (mode == PETSC_COPY_VALUES) {
595: PetscMalloc1(n,&sub->idx);
596: PetscLogObjectMemory((PetscObject)is,n*sizeof(PetscInt));
597: PetscArraycpy(sub->idx,idx,n);
598: sub->allocated = PETSC_TRUE;
599: } else if (mode == PETSC_OWN_POINTER) {
600: sub->idx = (PetscInt*)idx;
601: PetscLogObjectMemory((PetscObject)is,n*sizeof(PetscInt));
602: sub->allocated = PETSC_TRUE;
603: } else {
604: sub->idx = (PetscInt*)idx;
605: sub->allocated = PETSC_FALSE;
606: }
608: ISSetUp_General(is);
609: ISViewFromOptions(is,NULL,"-is_view");
610: return(0);
611: }
613: static PetscErrorCode ISGeneralFilter_General(IS is, PetscInt start, PetscInt end)
614: {
615: IS_General *sub = (IS_General*)is->data;
616: PetscInt *idx = sub->idx,*idxnew;
617: PetscInt i,n = is->map->n,nnew = 0,o;
621: for (i=0; i<n; ++i)
622: if (idx[i] >= start && idx[i] < end)
623: nnew++;
624: PetscMalloc1(nnew, &idxnew);
625: for (o=0, i=0; i<n; i++) {
626: if (idx[i] >= start && idx[i] < end)
627: idxnew[o++] = idx[i];
628: }
629: ISGeneralSetIndices_General(is,nnew,idxnew,PETSC_OWN_POINTER);
630: return(0);
631: }
633: /*@
634: ISGeneralFilter - Remove all indices outside of [start, end)
636: Collective on IS
638: Input Parameters:
639: + is - the index set
640: . start - the lowest index kept
641: - end - one more than the highest index kept
643: Level: beginner
645: .seealso: ISCreateGeneral(), ISGeneralSetIndices()
646: @*/
647: PetscErrorCode ISGeneralFilter(IS is, PetscInt start, PetscInt end)
648: {
653: ISClearInfoCache(is,PETSC_FALSE);
654: PetscUseMethod(is,"ISGeneralFilter_C",(IS,PetscInt,PetscInt),(is,start,end));
655: return(0);
656: }
658: PETSC_EXTERN PetscErrorCode ISCreate_General(IS is)
659: {
661: IS_General *sub;
664: PetscNewLog(is,&sub);
665: is->data = (void *) sub;
666: PetscMemcpy(is->ops,&myops,sizeof(myops));
667: PetscObjectComposeFunction((PetscObject)is,"ISGeneralSetIndices_C",ISGeneralSetIndices_General);
668: PetscObjectComposeFunction((PetscObject)is,"ISGeneralFilter_C",ISGeneralFilter_General);
669: return(0);
670: }