/*@ ISLocalToGlobalMappingApplyIS - Creates from an IS in the local numbering a new index set using the global numbering defined in an ISLocalToGlobalMapping context. Not collective Input Parameters: + mapping - mapping between local and global numbering - is - index set in local numbering Output Parameters: . newis - index set in global numbering Level: advanced Concepts: mapping^local to global .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(), ISLocalToGlobalMappingDestroy(), ISGlobalToLocalMappingApply() @*/ PetscErrorCode PETSCVEC_DLLEXPORT ISLocalToGlobalMappingApplyIS(ISLocalToGlobalMapping mapping,IS is,IS *newis) { PetscErrorCode ierr; PetscInt n,i,*idxmap,*idxout,Nmax = mapping->n; const PetscInt *idxin; PetscFunctionBegin; PetscValidHeaderSpecific(mapping,IS_LTOGM_COOKIE,1); PetscValidHeaderSpecific(is,IS_COOKIE,2); PetscValidPointer(newis,3); ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); ierr = ISGetIndices(is,&idxin);CHKERRQ(ierr); idxmap = mapping->indices; ierr = PetscMalloc(n*sizeof(PetscInt),&idxout);CHKERRQ(ierr); for (i=0; i<n; i++) { if (idxin[i] >= Nmax) SETERRQ3(PETSC_ERR_ARG_OUTOFRANGE,"Local index %d too large %d (max) at %d",idxin[i],Nmax-1,i); idxout[i] = idxmap[idxin[i]]; } ierr = ISRestoreIndices(is,&idxin);CHKERRQ(ierr); ierr = ISCreateGeneralNC(PETSC_COMM_SELF,n,idxout,newis);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@ ISDifference - Computes the difference between two index sets. Collective on IS Input Parameter: + is1 - first index, to have items removed from it - is2 - index values to be removed Output Parameters: . isout - is1 - is2 Notes: Negative values are removed from the lists. is2 may have values that are not in is1. This requires O(imax-imin) memory and O(imax-imin) work, where imin and imax are the bounds on the indices in is1. Level: intermediate Concepts: index sets^difference Concepts: IS^difference .seealso: ISDestroy(), ISView(), ISSum(), ISExpand() @*/ PetscErrorCode PETSCVEC_DLLEXPORT ISDifference(IS is1,IS is2,IS *isout) { PetscErrorCode ierr; PetscInt i,n1,n2,imin,imax,nout,*iout; const PetscInt *i1,*i2; PetscBT mask; MPI_Comm comm; PetscFunctionBegin; PetscValidHeaderSpecific(is1,IS_COOKIE,1); PetscValidHeaderSpecific(is2,IS_COOKIE,2); PetscValidPointer(isout,3); ierr = ISGetIndices(is1,&i1);CHKERRQ(ierr); ierr = ISGetLocalSize(is1,&n1);CHKERRQ(ierr); /* Create a bit mask array to contain required values */ if (n1) { imin = PETSC_MAX_INT; imax = 0; for (i=0; i<n1; i++) { if (i1[i] < 0) continue; imin = PetscMin(imin,i1[i]); imax = PetscMax(imax,i1[i]); } } else { imin = imax = 0; } ierr = PetscBTCreate(imax-imin,mask);CHKERRQ(ierr); /* Put the values from is1 */ for (i=0; i<n1; i++) { if (i1[i] < 0) continue; ierr = PetscBTSet(mask,i1[i] - imin);CHKERRQ(ierr); } ierr = ISRestoreIndices(is1,&i1);CHKERRQ(ierr); /* Remove the values from is2 */ ierr = ISGetIndices(is2,&i2);CHKERRQ(ierr); ierr = ISGetLocalSize(is2,&n2);CHKERRQ(ierr); for (i=0; i<n2; i++) { if (i2[i] < imin || i2[i] > imax) continue; ierr = PetscBTClear(mask,i2[i] - imin);CHKERRQ(ierr); } ierr = ISRestoreIndices(is2,&i2);CHKERRQ(ierr); /* Count the number in the difference */ nout = 0; for (i=0; i<imax-imin+1; i++) { if (PetscBTLookup(mask,i)) nout++; } /* create the new IS containing the difference */ ierr = PetscMalloc(nout*sizeof(PetscInt),&iout);CHKERRQ(ierr); nout = 0; for (i=0; i<imax-imin+1; i++) { if (PetscBTLookup(mask,i)) iout[nout++] = i + imin; } ierr = PetscObjectGetComm((PetscObject)is1,&comm);CHKERRQ(ierr); ierr = ISCreateGeneralNC(comm,nout,iout,isout);CHKERRQ(ierr); ierr = PetscBTDestroy(mask);CHKERRQ(ierr); PetscFunctionReturn(0); }