PetscErrorCode MatBlockMatSetPreallocation_BlockMat(Mat A,PetscInt bs,PetscInt nz,PetscInt *nnz) { Mat_BlockMat *bmat = (Mat_BlockMat*)A->data; PetscErrorCode ierr; PetscInt i; PetscFunctionBegin; ierr = PetscLayoutSetBlockSize(A->rmap,bs);CHKERRQ(ierr); ierr = PetscLayoutSetBlockSize(A->cmap,bs);CHKERRQ(ierr); ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); ierr = PetscLayoutGetBlockSize(A->rmap,&bs);CHKERRQ(ierr); if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz); if (nnz) { for (i=0; i<A->rmap->n/bs; i++) { if (nnz[i] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]); if (nnz[i] > A->cmap->n/bs) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be greater than row length: local row %d value %d rowlength %d",i,nnz[i],A->cmap->n/bs); } } bmat->mbs = A->rmap->n/bs; ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,bs,NULL,&bmat->right);CHKERRQ(ierr); ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,bs,NULL,&bmat->middle);CHKERRQ(ierr); ierr = VecCreateSeq(PETSC_COMM_SELF,bs,&bmat->left);CHKERRQ(ierr); if (!bmat->imax) { ierr = PetscMalloc2(A->rmap->n,&bmat->imax,A->rmap->n,&bmat->ilen);CHKERRQ(ierr); ierr = PetscLogObjectMemory((PetscObject)A,2*A->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); } if (nnz) { nz = 0; for (i=0; i<A->rmap->n/A->rmap->bs; i++) { bmat->imax[i] = nnz[i]; nz += nnz[i]; } } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Currently requires block row by row preallocation"); /* bmat->ilen will count nonzeros in each row so far. */ for (i=0; i<bmat->mbs; i++) bmat->ilen[i] = 0; /* allocate the matrix space */ ierr = MatSeqXAIJFreeAIJ(A,(PetscScalar**)&bmat->a,&bmat->j,&bmat->i);CHKERRQ(ierr); ierr = PetscMalloc3(nz,&bmat->a,nz,&bmat->j,A->rmap->n+1,&bmat->i);CHKERRQ(ierr); ierr = PetscLogObjectMemory((PetscObject)A,(A->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr); bmat->i[0] = 0; for (i=1; i<bmat->mbs+1; i++) { bmat->i[i] = bmat->i[i-1] + bmat->imax[i-1]; } bmat->singlemalloc = PETSC_TRUE; bmat->free_a = PETSC_TRUE; bmat->free_ij = PETSC_TRUE; bmat->nz = 0; bmat->maxnz = nz; A->info.nz_unneeded = (double)bmat->maxnz; ierr = MatSetOption(A,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); PetscFunctionReturn(0); }
EXTERN_C_BEGIN #undef __FUNCT__ #define __FUNCT__ "MatCreate_Shell" PetscErrorCode MatCreate_Shell(Mat A) { Mat_Shell *b; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscMemcpy(A->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); ierr = PetscNewLog(A,Mat_Shell,&b);CHKERRQ(ierr); A->data = (void*)b; ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); b->ctx = 0; b->vshift = 0.0; b->vscale = 1.0; b->mult = 0; b->multtranspose = 0; b->getdiagonal = 0; A->assembled = PETSC_TRUE; A->preallocated = PETSC_FALSE; ierr = PetscObjectChangeTypeName((PetscObject)A,MATSHELL);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@ MatCreateTranspose - Creates a new matrix object that behaves like A' Collective on Mat Input Parameter: . A - the (possibly rectangular) matrix Output Parameter: . N - the matrix that represents A' Level: intermediate Notes: The transpose A' is NOT actually formed! Rather the new matrix object performs the matrix-vector product by using the MatMultTranspose() on the original matrix .seealso: MatCreateNormal(), MatMult(), MatMultTranspose(), MatCreate() @*/ PetscErrorCode MatCreateTranspose(Mat A,Mat *N) { PetscErrorCode ierr; PetscInt m,n; Mat_Transpose *Na; PetscFunctionBegin; ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); ierr = MatCreate(PetscObjectComm((PetscObject)A),N);CHKERRQ(ierr); ierr = MatSetSizes(*N,n,m,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); ierr = PetscLayoutSetUp((*N)->rmap);CHKERRQ(ierr); ierr = PetscLayoutSetUp((*N)->cmap);CHKERRQ(ierr); ierr = PetscObjectChangeTypeName((PetscObject)*N,MATTRANSPOSEMAT);CHKERRQ(ierr); ierr = PetscNewLog(*N,&Na);CHKERRQ(ierr); (*N)->data = (void*) Na; ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); Na->A = A; (*N)->ops->destroy = MatDestroy_Transpose; (*N)->ops->mult = MatMult_Transpose; (*N)->ops->multadd = MatMultAdd_Transpose; (*N)->ops->multtranspose = MatMultTranspose_Transpose; (*N)->ops->multtransposeadd = MatMultTransposeAdd_Transpose; (*N)->ops->duplicate = MatDuplicate_Transpose; (*N)->ops->getvecs = MatCreateVecs_Transpose; (*N)->ops->axpy = MatAXPY_Transpose; (*N)->assembled = PETSC_TRUE; ierr = PetscObjectComposeFunction((PetscObject)(*N),"MatTransposeGetMat_C",MatTransposeGetMat_Transpose);CHKERRQ(ierr); ierr = MatSetBlockSizes(*N,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); ierr = MatSetUp(*N);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@ MatCreateTranspose - Creates a new matrix object that behaves like A' Collective on Mat Input Parameter: . A - the (possibly rectangular) matrix Output Parameter: . N - the matrix that represents A' Level: intermediate Notes: The transpose A' is NOT actually formed! Rather the new matrix object performs the matrix-vector product by using the MatMultTranspose() on the original matrix .seealso: MatCreateNormal(), MatMult(), MatMultTranspose(), MatCreate() @*/ PetscErrorCode PETSCMAT_DLLEXPORT MatCreateTranspose(Mat A,Mat *N) { PetscErrorCode ierr; PetscInt m,n; Mat_Transpose *Na; PetscFunctionBegin; ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); ierr = MatCreate(((PetscObject)A)->comm,N);CHKERRQ(ierr); ierr = MatSetSizes(*N,n,m,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); ierr = PetscObjectChangeTypeName((PetscObject)*N,MATTRANSPOSEMAT);CHKERRQ(ierr); ierr = PetscNewLog(*N,Mat_Transpose,&Na);CHKERRQ(ierr); (*N)->data = (void*) Na; ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); Na->A = A; (*N)->ops->destroy = MatDestroy_Transpose; (*N)->ops->mult = MatMult_Transpose; (*N)->ops->multadd = MatMultAdd_Transpose; (*N)->ops->multtranspose = MatMultTranspose_Transpose; (*N)->ops->multtransposeadd = MatMultTransposeAdd_Transpose; (*N)->assembled = PETSC_TRUE; ierr = PetscLayoutSetBlockSize((*N)->rmap,A->cmap->bs);CHKERRQ(ierr); ierr = PetscLayoutSetBlockSize((*N)->cmap,A->rmap->bs);CHKERRQ(ierr); ierr = PetscLayoutSetUp((*N)->rmap);CHKERRQ(ierr); ierr = PetscLayoutSetUp((*N)->cmap);CHKERRQ(ierr); PetscFunctionReturn(0); }
EXTERN_C_BEGIN #undef __FUNCT__ #define __FUNCT__ "MatCreate_Scatter" PetscErrorCode PETSCMAT_DLLEXPORT MatCreate_Scatter(Mat A) { Mat_Scatter *b; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscMemcpy(A->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); ierr = PetscNewLog(A,Mat_Scatter,&b);CHKERRQ(ierr); A->data = (void*)b; ierr = PetscLayoutSetBlockSize(A->rmap,1);CHKERRQ(ierr); ierr = PetscLayoutSetBlockSize(A->cmap,1);CHKERRQ(ierr); ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); A->assembled = PETSC_TRUE; A->preallocated = PETSC_FALSE; ierr = PetscObjectChangeTypeName((PetscObject)A,MATSCATTER);CHKERRQ(ierr); PetscFunctionReturn(0); }
PETSC_EXTERN PetscErrorCode MatCreate_Scatter(Mat A) { Mat_Scatter *b; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscMemcpy(A->ops,&MatOps_Values,sizeof(struct _MatOps)); CHKERRQ(ierr); ierr = PetscNewLog(A,Mat_Scatter,&b); CHKERRQ(ierr); A->data = (void*)b; ierr = PetscLayoutSetUp(A->rmap); CHKERRQ(ierr); ierr = PetscLayoutSetUp(A->cmap); CHKERRQ(ierr); A->assembled = PETSC_TRUE; A->preallocated = PETSC_FALSE; ierr = PetscObjectChangeTypeName((PetscObject)A,MATSCATTER); CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@ MatXAIJSetPreallocation - set preallocation for serial and parallel AIJ, BAIJ, and SBAIJ matrices Collective on Mat Input Arguments: + A - matrix being preallocated . bs - block size . dnnz - number of nonzero blocks per block row of diagonal part of parallel matrix . onnz - number of nonzero blocks per block row of off-diagonal part of parallel matrix . dnnzu - number of nonzero blocks per block row of upper-triangular part of diagonal part of parallel matrix - onnzu - number of nonzero blocks per block row of upper-triangular part of off-diagonal part of parallel matrix Level: beginner .seealso: MatSeqAIJSetPreallocation(), MatMPIAIJSetPreallocation(), MatSeqBAIJSetPreallocation(), MatMPIBAIJSetPreallocation(), MatSeqSBAIJSetPreallocation(), MatMPISBAIJSetPreallocation(), PetscSplitOwnership() @*/ PetscErrorCode MatXAIJSetPreallocation(Mat A,PetscInt bs,const PetscInt dnnz[],const PetscInt onnz[],const PetscInt dnnzu[],const PetscInt onnzu[]) { PetscErrorCode ierr; void (*aij)(void); PetscFunctionBegin; ierr = MatSetBlockSize(A,bs); CHKERRQ(ierr); ierr = PetscLayoutSetUp(A->rmap); CHKERRQ(ierr); ierr = PetscLayoutSetUp(A->cmap); CHKERRQ(ierr); ierr = MatSeqBAIJSetPreallocation(A,bs,0,dnnz); CHKERRQ(ierr); ierr = MatMPIBAIJSetPreallocation(A,bs,0,dnnz,0,onnz); CHKERRQ(ierr); ierr = MatSeqSBAIJSetPreallocation(A,bs,0,dnnzu); CHKERRQ(ierr); ierr = MatMPISBAIJSetPreallocation(A,bs,0,dnnzu,0,onnzu); CHKERRQ(ierr); /* In general, we have to do extra work to preallocate for scalar (AIJ) matrices so we check whether it will do any good before going on with it. */ ierr = PetscObjectQueryFunction((PetscObject)A,"MatMPIAIJSetPreallocation_C",&aij); CHKERRQ(ierr); if (!aij) { ierr = PetscObjectQueryFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",&aij); CHKERRQ(ierr); } if (aij) { if (bs == 1) { ierr = MatSeqAIJSetPreallocation(A,0,dnnz); CHKERRQ(ierr); ierr = MatMPIAIJSetPreallocation(A,0,dnnz,0,onnz); CHKERRQ(ierr); } else { /* Convert block-row precallocation to scalar-row */ PetscInt i,m,*sdnnz,*sonnz; ierr = MatGetLocalSize(A,&m,NULL); CHKERRQ(ierr); ierr = PetscMalloc2((!!dnnz)*m,PetscInt,&sdnnz,(!!onnz)*m,PetscInt,&sonnz); CHKERRQ(ierr); for (i=0; i<m; i++) { if (dnnz) sdnnz[i] = dnnz[i/bs] * bs; if (onnz) sonnz[i] = onnz[i/bs] * bs; } ierr = MatSeqAIJSetPreallocation(A,0,dnnz ? sdnnz : NULL); CHKERRQ(ierr); ierr = MatMPIAIJSetPreallocation(A,0,dnnz ? sdnnz : NULL,0,onnz ? sonnz : NULL); CHKERRQ(ierr); ierr = PetscFree2(sdnnz,sonnz); CHKERRQ(ierr); } } PetscFunctionReturn(0); }
/*@ MatSchurComplementSet - Sets the matrices that define the Schur complement Collective on Mat Input Parameter: + N - matrix obtained with MatCreate() and MatSetType(MATSCHURCOMPLEMENT); - A00,A01,A10,A11 - the four parts of the original matrix (A00 is optional) Level: intermediate Notes: The Schur complement is NOT actually formed! Rather this object performs the matrix-vector product by using the the formula for the Schur complement and a KSP solver to approximate the action of inv(A) All four matrices must have the same MPI communicator A00 and A11 must be square matrices .seealso: MatCreateNormal(), MatMult(), MatCreate(), MatSchurComplementGetKSP(), MatSchurComplementUpdate(), MatCreateTranspose(), MatGetSchurComplement() @*/ PetscErrorCode MatSchurComplementSet(Mat N,Mat A00,Mat Ap00,Mat A01,Mat A10,Mat A11) { PetscErrorCode ierr; PetscInt m,n; Mat_SchurComplement *Na = (Mat_SchurComplement*)N->data; PetscFunctionBegin; if (N->assembled) SETERRQ(((PetscObject)N)->comm,PETSC_ERR_ARG_WRONGSTATE,"Use MatSchurComplementUpdate() for already used matrix"); PetscValidHeaderSpecific(A00,MAT_CLASSID,1); PetscValidHeaderSpecific(Ap00,MAT_CLASSID,2); PetscValidHeaderSpecific(A01,MAT_CLASSID,3); PetscValidHeaderSpecific(A10,MAT_CLASSID,4); PetscCheckSameComm(A00,1,Ap00,2); PetscCheckSameComm(A00,1,A01,3); PetscCheckSameComm(A00,1,A10,4); if (A00->rmap->n != A00->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Local rows of A00 %D do not equal local columns %D",A00->rmap->n,A00->cmap->n); if (A00->rmap->n != Ap00->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Local rows of A00 %D do not equal local rows of Ap00 %D",A00->rmap->n,Ap00->rmap->n); if (Ap00->rmap->n != Ap00->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Local rows of Ap00 %D do not equal local columns %D",Ap00->rmap->n,Ap00->cmap->n); if (A00->cmap->n != A01->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Local columns of A00 %D do not equal local rows of A01 %D",A00->cmap->n,A01->rmap->n); if (A10->cmap->n != A00->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Local columns of A10 %D do not equal local rows of A00 %D",A10->cmap->n,A00->rmap->n); if (A11) { PetscValidHeaderSpecific(A11,MAT_CLASSID,5); PetscCheckSameComm(A00,1,A11,5); if (A11->rmap->n != A11->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Local rows of A11 %D do not equal local columns %D",A11->rmap->n,A11->cmap->n); if (A10->rmap->n != A11->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Local rows of A10 %D do not equal local rows A11 %D",A10->rmap->n,A11->rmap->n); } ierr = MatGetLocalSize(A01,PETSC_NULL,&n);CHKERRQ(ierr); ierr = MatGetLocalSize(A10,&m,PETSC_NULL);CHKERRQ(ierr); ierr = MatSetSizes(N,m,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); ierr = PetscObjectReference((PetscObject)A00);CHKERRQ(ierr); ierr = PetscObjectReference((PetscObject)Ap00);CHKERRQ(ierr); ierr = PetscObjectReference((PetscObject)A01);CHKERRQ(ierr); ierr = PetscObjectReference((PetscObject)A10);CHKERRQ(ierr); Na->A = A00; Na->Ap = Ap00; Na->B = A01; Na->C = A10; Na->D = A11; if (A11) { ierr = PetscObjectReference((PetscObject)A11);CHKERRQ(ierr); } N->assembled = PETSC_TRUE; N->preallocated = PETSC_TRUE; ierr = PetscLayoutSetUp((N)->rmap);CHKERRQ(ierr); ierr = PetscLayoutSetUp((N)->cmap);CHKERRQ(ierr); ierr = KSPSetOperators(Na->ksp,A00,Ap00,SAME_NONZERO_PATTERN);CHKERRQ(ierr); PetscFunctionReturn(0); }
PETSC_EXTERN PetscErrorCode MatCreate_IS(Mat A) { PetscErrorCode ierr; Mat_IS *b; PetscFunctionBegin; ierr = PetscNewLog(A,&b);CHKERRQ(ierr); A->data = (void*)b; ierr = PetscMemzero(A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); A->ops->mult = MatMult_IS; A->ops->multadd = MatMultAdd_IS; A->ops->multtranspose = MatMultTranspose_IS; A->ops->multtransposeadd = MatMultTransposeAdd_IS; A->ops->destroy = MatDestroy_IS; A->ops->setlocaltoglobalmapping = MatSetLocalToGlobalMapping_IS; A->ops->setvalues = MatSetValues_IS; A->ops->setvalueslocal = MatSetValuesLocal_IS; A->ops->setvaluesblockedlocal = MatSetValuesBlockedLocal_IS; A->ops->zerorows = MatZeroRows_IS; A->ops->zerorowslocal = MatZeroRowsLocal_IS; A->ops->assemblybegin = MatAssemblyBegin_IS; A->ops->assemblyend = MatAssemblyEnd_IS; A->ops->view = MatView_IS; A->ops->zeroentries = MatZeroEntries_IS; A->ops->scale = MatScale_IS; A->ops->getdiagonal = MatGetDiagonal_IS; A->ops->setoption = MatSetOption_IS; A->ops->ishermitian = MatIsHermitian_IS; A->ops->issymmetric = MatIsSymmetric_IS; A->ops->duplicate = MatDuplicate_IS; ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); /* zeros pointer */ b->A = 0; b->ctx = 0; b->x = 0; b->y = 0; b->mapping = 0; /* special MATIS functions */ ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetLocalMat_C",MatISGetLocalMat_IS);CHKERRQ(ierr); ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetLocalMat_C",MatISSetLocalMat_IS);CHKERRQ(ierr); ierr = PetscObjectComposeFunction((PetscObject)A,"MatISGetMPIXAIJ_C",MatISGetMPIXAIJ_IS);CHKERRQ(ierr); ierr = PetscObjectComposeFunction((PetscObject)A,"MatISSetPreallocation_C",MatISSetPreallocation_IS);CHKERRQ(ierr); ierr = PetscObjectChangeTypeName((PetscObject)A,MATIS);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode ISCreateGeneral_Private(IS is) { PetscErrorCode ierr; IS_General *sub = (IS_General*)is->data; const PetscInt *idx = sub->idx; PetscBool sorted = PETSC_TRUE; PetscInt n,i,min,max; PetscFunctionBegin; ierr = PetscLayoutGetLocalSize(is->map, &n);CHKERRQ(ierr); ierr = PetscLayoutSetUp(is->map);CHKERRQ(ierr); for (i=1; i<n; i++) { if (idx[i] < idx[i-1]) {sorted = PETSC_FALSE; break;} } if (n) min = max = idx[0]; else min = max = 0; for (i=1; i<n; i++) { if (idx[i] < min) min = idx[i]; if (idx[i] > max) max = idx[i]; } sub->sorted = sorted; is->min = min; is->max = max; is->isperm = PETSC_FALSE; is->isidentity = PETSC_FALSE; ierr = ISViewFromOptions(is,NULL,"-is_view");CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode VecCreate_Seq_Private(Vec v,const PetscScalar array[]) { Vec_Seq *s; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscNewLog(v,&s);CHKERRQ(ierr); ierr = PetscMemcpy(v->ops,&DvOps,sizeof(DvOps));CHKERRQ(ierr); v->data = (void*)s; v->petscnative = PETSC_TRUE; s->array = (PetscScalar*)array; s->array_allocated = 0; ierr = PetscLayoutSetUp(v->map);CHKERRQ(ierr); ierr = PetscObjectChangeTypeName((PetscObject)v,VECSEQ);CHKERRQ(ierr); #if defined(PETSC_HAVE_MATLAB_ENGINE) ierr = PetscObjectComposeFunction((PetscObject)v,"PetscMatlabEnginePut_C",VecMatlabEnginePut_Default);CHKERRQ(ierr); ierr = PetscObjectComposeFunction((PetscObject)v,"PetscMatlabEngineGet_C",VecMatlabEngineGet_Default);CHKERRQ(ierr); #endif #if defined(PETSC_USE_MIXED_PRECISION) ((PetscObject)v)->precision = (PetscPrecision)sizeof(PetscReal); #endif PetscFunctionReturn(0); }
PetscErrorCode ISGeneralSetIndices_General(IS is,PetscInt n,const PetscInt idx[],PetscCopyMode mode) { PetscErrorCode ierr; IS_General *sub = (IS_General*)is->data; PetscFunctionBegin; if (n < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"length < 0"); if (n) PetscValidIntPointer(idx,3); ierr = PetscLayoutSetLocalSize(is->map,n);CHKERRQ(ierr); ierr = PetscLayoutSetUp(is->map);CHKERRQ(ierr); if (sub->allocated) {ierr = PetscFree(sub->idx);CHKERRQ(ierr);} if (mode == PETSC_COPY_VALUES) { ierr = PetscMalloc1(n,&sub->idx);CHKERRQ(ierr); ierr = PetscLogObjectMemory((PetscObject)is,n*sizeof(PetscInt));CHKERRQ(ierr); ierr = PetscMemcpy(sub->idx,idx,n*sizeof(PetscInt));CHKERRQ(ierr); sub->allocated = PETSC_TRUE; } else if (mode == PETSC_OWN_POINTER) { sub->idx = (PetscInt*)idx; ierr = PetscLogObjectMemory((PetscObject)is,n*sizeof(PetscInt));CHKERRQ(ierr); sub->allocated = PETSC_TRUE; } else { sub->idx = (PetscInt*)idx; sub->allocated = PETSC_FALSE; } ierr = ISSetUp_General(is);CHKERRQ(ierr); ierr = ISViewFromOptions(is,NULL,"-is_view");CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode DMSetUp_Composite(DM dm) { PetscErrorCode ierr; PetscInt nprev = 0; PetscMPIInt rank,size; DM_Composite *com = (DM_Composite*)dm->data; struct DMCompositeLink *next = com->next; PetscLayout map; PetscFunctionBegin; if (com->setup) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"Packer has already been setup"); ierr = PetscLayoutCreate(((PetscObject)dm)->comm,&map);CHKERRQ(ierr); ierr = PetscLayoutSetLocalSize(map,com->n);CHKERRQ(ierr); ierr = PetscLayoutSetSize(map,PETSC_DETERMINE);CHKERRQ(ierr); ierr = PetscLayoutSetBlockSize(map,1);CHKERRQ(ierr); ierr = PetscLayoutSetUp(map);CHKERRQ(ierr); ierr = PetscLayoutGetSize(map,&com->N);CHKERRQ(ierr); ierr = PetscLayoutGetRange(map,&com->rstart,PETSC_NULL);CHKERRQ(ierr); ierr = PetscLayoutDestroy(&map);CHKERRQ(ierr); /* now set the rstart for each linked vector */ ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr); ierr = MPI_Comm_size(((PetscObject)dm)->comm,&size);CHKERRQ(ierr); while (next) { next->rstart = nprev; nprev += next->n; next->grstart = com->rstart + next->rstart; ierr = PetscMalloc(size*sizeof(PetscInt),&next->grstarts);CHKERRQ(ierr); ierr = MPI_Allgather(&next->grstart,1,MPIU_INT,next->grstarts,1,MPIU_INT,((PetscObject)dm)->comm);CHKERRQ(ierr); next = next->next; } com->setup = PETSC_TRUE; PetscFunctionReturn(0); }
PetscErrorCode MatSetUp_Preallocator(Mat A) { Mat_Preallocator *p = (Mat_Preallocator *) A->data; PetscInt m, bs; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); ierr = MatGetLocalSize(A, &m, NULL);CHKERRQ(ierr); ierr = PetscHSetIJCreate(&p->ht);CHKERRQ(ierr); ierr = MatGetBlockSize(A, &bs);CHKERRQ(ierr); ierr = MatStashCreate_Private(PetscObjectComm((PetscObject) A), bs, &A->stash);CHKERRQ(ierr); ierr = PetscCalloc2(m, &p->dnz, m, &p->onz);CHKERRQ(ierr); PetscFunctionReturn(0); }
EXTERN_C_BEGIN #undef __FUNCT__ #define __FUNCT__ "MatMPIAdjSetPreallocation_MPIAdj" PetscErrorCode PETSCMAT_DLLEXPORT MatMPIAdjSetPreallocation_MPIAdj(Mat B,PetscInt *i,PetscInt *j,PetscInt *values) { Mat_MPIAdj *b = (Mat_MPIAdj *)B->data; PetscErrorCode ierr; #if defined(PETSC_USE_DEBUG) PetscInt ii; #endif PetscFunctionBegin; ierr = PetscLayoutSetBlockSize(B->rmap,1);CHKERRQ(ierr); ierr = PetscLayoutSetBlockSize(B->cmap,1);CHKERRQ(ierr); ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); #if defined(PETSC_USE_DEBUG) if (i[0] != 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"First i[] index must be zero, instead it is %D\n",i[0]); for (ii=1; ii<B->rmap->n; ii++) { if (i[ii] < 0 || i[ii] < i[ii-1]) { SETERRQ4(PETSC_ERR_ARG_OUTOFRANGE,"i[%D]=%D index is out of range: i[%D]=%D",ii,i[ii],ii-1,i[ii-1]); } } for (ii=0; ii<i[B->rmap->n]; ii++) { if (j[ii] < 0 || j[ii] >= B->cmap->N) { SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column index %D out of range %D\n",ii,j[ii]); } } #endif B->preallocated = PETSC_TRUE; b->j = j; b->i = i; b->values = values; b->nz = i[B->rmap->n]; b->diag = 0; b->symmetric = PETSC_FALSE; b->freeaij = PETSC_TRUE; ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); PetscFunctionReturn(0); }
EXTERN_C_END /*MC MATDAAD - MATDAAD = "daad" - A matrix type that can do matrix-vector products using a local function that is differentiated with ADIFOR or ADIC. Level: intermediate .seealso: MatCreateDAAD M*/ EXTERN_C_BEGIN #undef __FUNCT__ #define __FUNCT__ "MatCreate_DAAD" PetscErrorCode MatCreate_DAAD(Mat B) { Mat_DAAD *b; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscNewLog(B,Mat_DAAD,&b); CHKERRQ(ierr); B->data = (void*)b; ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps)); CHKERRQ(ierr); ierr = PetscLayoutSetUp(B->rmap); CHKERRQ(ierr); ierr = PetscLayoutSetUp(B->cmap); CHKERRQ(ierr); ierr = PetscObjectChangeTypeName((PetscObject)B,MATDAAD); CHKERRQ(ierr); ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMFFDSetBase_C","MatMFFDSetBase_AD",MatMFFDSetBase_AD); CHKERRQ(ierr); ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatDAADSetDA_C","MatDAADSetDA_AD",MatDAADSetDA_AD); CHKERRQ(ierr); ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatDAADSetSNES_C","MatDAADSetSNES_AD",MatDAADSetSNES_AD); CHKERRQ(ierr); ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatDAADSetCtx_C","MatDAADSetCtx_AD",MatDAADSetCtx_AD); CHKERRQ(ierr); ierr = PetscObjectChangeTypeName((PetscObject)B,MATDAAD); CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode MatAllocate_LMVM(Mat B, Vec X, Vec F) { Mat_LMVM *lmvm = (Mat_LMVM*)B->data; PetscErrorCode ierr; PetscBool same, allocate = PETSC_FALSE; PetscInt m, n, M, N; VecType type; PetscFunctionBegin; if (lmvm->allocated) { VecCheckMatCompatible(B, X, 2, F, 3); ierr = VecGetType(X, &type);CHKERRQ(ierr); ierr = PetscObjectTypeCompare((PetscObject)lmvm->Xprev, type, &same);CHKERRQ(ierr); if (!same) { /* Given X vector has a different type than allocated X-type data structures. We need to destroy all of this and duplicate again out of the given vector. */ allocate = PETSC_TRUE; ierr = MatLMVMReset(B, PETSC_TRUE);CHKERRQ(ierr); } } else { allocate = PETSC_TRUE; } if (allocate) { ierr = VecGetLocalSize(X, &n);CHKERRQ(ierr); ierr = VecGetSize(X, &N);CHKERRQ(ierr); ierr = VecGetLocalSize(F, &m);CHKERRQ(ierr); ierr = VecGetSize(F, &M);CHKERRQ(ierr); ierr = MatSetSizes(B, m, n, M, N);CHKERRQ(ierr); ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); ierr = VecDuplicate(X, &lmvm->Xprev);CHKERRQ(ierr); ierr = VecDuplicate(F, &lmvm->Fprev);CHKERRQ(ierr); if (lmvm->m > 0) { ierr = VecDuplicateVecs(lmvm->Xprev, lmvm->m, &lmvm->S);CHKERRQ(ierr); ierr = VecDuplicateVecs(lmvm->Fprev, lmvm->m, &lmvm->Y);CHKERRQ(ierr); } lmvm->allocated = PETSC_TRUE; B->preallocated = PETSC_TRUE; B->assembled = PETSC_TRUE; } PetscFunctionReturn(0); }
PETSC_EXTERN PetscErrorCode MatCreate_Composite(Mat A) { Mat_Composite *b; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscNewLog(A,&b);CHKERRQ(ierr); A->data = (void*)b; ierr = PetscMemcpy(A->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); A->assembled = PETSC_TRUE; A->preallocated = PETSC_TRUE; b->type = MAT_COMPOSITE_ADDITIVE; b->scale = 1.0; ierr = PetscObjectChangeTypeName((PetscObject)A,MATCOMPOSITE);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode MatAssemblyBegin_Preallocator(Mat A, MatAssemblyType type) { PetscInt nstash, reallocs; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); ierr = MatStashScatterBegin_Private(A, &A->stash, A->rmap->range);CHKERRQ(ierr); ierr = MatStashGetInfo_Private(&A->stash, &nstash, &reallocs);CHKERRQ(ierr); ierr = PetscInfo2(A, "Stash has %D entries, uses %D mallocs.\n", nstash, reallocs);CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode ISBlockSetIndices_Block(IS is,PetscInt bs,PetscInt n,const PetscInt idx[],PetscCopyMode mode) { PetscErrorCode ierr; PetscInt i,min,max; IS_Block *sub = (IS_Block*)is->data; PetscFunctionBegin; if (bs < 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"block size < 1"); if (n < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"length < 0"); if (n) PetscValidIntPointer(idx,3); ierr = PetscLayoutSetLocalSize(is->map, n*bs);CHKERRQ(ierr); ierr = PetscLayoutSetBlockSize(is->map, bs);CHKERRQ(ierr); ierr = PetscLayoutSetUp(is->map);CHKERRQ(ierr); if (sub->allocated) {ierr = PetscFree(sub->idx);CHKERRQ(ierr);} if (mode == PETSC_COPY_VALUES) { ierr = PetscMalloc1(n,&sub->idx);CHKERRQ(ierr); ierr = PetscLogObjectMemory((PetscObject)is,n*sizeof(PetscInt));CHKERRQ(ierr); ierr = PetscMemcpy(sub->idx,idx,n*sizeof(PetscInt));CHKERRQ(ierr); sub->allocated = PETSC_TRUE; } else if (mode == PETSC_OWN_POINTER) { sub->idx = (PetscInt*) idx; ierr = PetscLogObjectMemory((PetscObject)is,n*sizeof(PetscInt));CHKERRQ(ierr); sub->allocated = PETSC_TRUE; } else if (mode == PETSC_USE_POINTER) { sub->idx = (PetscInt*) idx; sub->allocated = PETSC_FALSE; } sub->sorted = PETSC_TRUE; for (i=1; i<n; i++) { if (idx[i] < idx[i-1]) {sub->sorted = PETSC_FALSE; break;} } if (n) { min = max = idx[0]; for (i=1; i<n; i++) { if (idx[i] < min) min = idx[i]; if (idx[i] > max) max = idx[i]; } is->min = bs*min; is->max = bs*max+bs-1; } else { is->min = PETSC_MAX_INT; is->max = PETSC_MIN_INT; } is->isperm = PETSC_FALSE; is->isidentity = PETSC_FALSE; PetscFunctionReturn(0); }
/*@C VecCreateNest - Creates a new vector containing several nested subvectors, each stored separately Collective on Vec Input Parameter: + comm - Communicator for the new Vec . nb - number of nested blocks . is - array of nb index sets describing each nested block, or NULL to pack subvectors contiguously - x - array of nb sub-vectors Output Parameter: . Y - new vector Level: advanced .seealso: VecCreate(), MatCreateNest(), DMSetVecType(), VECNEST @*/ PetscErrorCode VecCreateNest(MPI_Comm comm,PetscInt nb,IS is[],Vec x[],Vec *Y) { Vec V; Vec_Nest *s; PetscInt n,N; PetscErrorCode ierr; PetscFunctionBegin; ierr = VecCreate(comm,&V);CHKERRQ(ierr); ierr = PetscObjectChangeTypeName((PetscObject)V,VECNEST);CHKERRQ(ierr); /* allocate and set pointer for implememtation data */ ierr = PetscMalloc(sizeof(Vec_Nest),&s);CHKERRQ(ierr); ierr = PetscMemzero(s,sizeof(Vec_Nest));CHKERRQ(ierr); V->data = (void*)s; s->setup_called = PETSC_FALSE; s->nb = -1; s->v = NULL; ierr = VecSetUp_Nest_Private(V,nb,x);CHKERRQ(ierr); n = N = 0; ierr = VecSize_Nest_Recursive(V,PETSC_TRUE,&N);CHKERRQ(ierr); ierr = VecSize_Nest_Recursive(V,PETSC_FALSE,&n);CHKERRQ(ierr); ierr = PetscLayoutSetSize(V->map,N);CHKERRQ(ierr); ierr = PetscLayoutSetLocalSize(V->map,n);CHKERRQ(ierr); ierr = PetscLayoutSetBlockSize(V->map,1);CHKERRQ(ierr); ierr = PetscLayoutSetUp(V->map);CHKERRQ(ierr); ierr = VecSetUp_NestIS_Private(V,nb,is);CHKERRQ(ierr); ierr = VecNestSetOps_Private(V->ops);CHKERRQ(ierr); V->petscnative = PETSC_FALSE; /* expose block api's */ ierr = PetscObjectComposeFunction((PetscObject)V,"VecNestGetSubVec_C",VecNestGetSubVec_Nest);CHKERRQ(ierr); ierr = PetscObjectComposeFunction((PetscObject)V,"VecNestGetSubVecs_C",VecNestGetSubVecs_Nest);CHKERRQ(ierr); ierr = PetscObjectComposeFunction((PetscObject)V,"VecNestSetSubVec_C",VecNestSetSubVec_Nest);CHKERRQ(ierr); ierr = PetscObjectComposeFunction((PetscObject)V,"VecNestSetSubVecs_C",VecNestSetSubVecs_Nest);CHKERRQ(ierr); ierr = PetscObjectComposeFunction((PetscObject)V,"VecNestGetSize_C",VecNestGetSize_Nest);CHKERRQ(ierr); *Y = V; PetscFunctionReturn(0); }
/* VecCreate_MPI_Private - Basic create routine called by VecCreate_MPI() (i.e. VecCreateMPI()), VecCreateMPIWithArray(), VecCreate_Shared() (i.e. VecCreateShared()), VecCreateGhost(), VecDuplicate_MPI(), VecCreateGhostWithArray(), VecDuplicate_MPI(), and VecDuplicate_Shared() If alloc is true and array is NULL then this routine allocates the space, otherwise no space is allocated. */ PetscErrorCode VecCreate_MPI_Private(Vec v,PetscBool alloc,PetscInt nghost,const PetscScalar array[]) { Vec_MPI *s; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscNewLog(v,&s);CHKERRQ(ierr); v->data = (void*)s; ierr = PetscMemcpy(v->ops,&DvOps,sizeof(DvOps));CHKERRQ(ierr); s->nghost = nghost; v->petscnative = PETSC_TRUE; ierr = PetscLayoutSetUp(v->map);CHKERRQ(ierr); s->array = (PetscScalar*)array; s->array_allocated = 0; if (alloc && !array) { PetscInt n = v->map->n+nghost; ierr = PetscMalloc1(n,&s->array);CHKERRQ(ierr); ierr = PetscLogObjectMemory((PetscObject)v,n*sizeof(PetscScalar));CHKERRQ(ierr); ierr = PetscMemzero(s->array,n*sizeof(PetscScalar));CHKERRQ(ierr); s->array_allocated = s->array; } /* By default parallel vectors do not have local representation */ s->localrep = 0; s->localupdate = 0; v->stash.insertmode = NOT_SET_VALUES; v->bstash.insertmode = NOT_SET_VALUES; /* create the stashes. The block-size for bstash is set later when VecSetValuesBlocked is called. */ ierr = VecStashCreate_Private(PetscObjectComm((PetscObject)v),1,&v->stash);CHKERRQ(ierr); ierr = VecStashCreate_Private(PetscObjectComm((PetscObject)v),PetscAbs(v->map->bs),&v->bstash);CHKERRQ(ierr); #if defined(PETSC_HAVE_MATLAB_ENGINE) ierr = PetscObjectComposeFunction((PetscObject)v,"PetscMatlabEnginePut_C",VecMatlabEnginePut_Default);CHKERRQ(ierr); ierr = PetscObjectComposeFunction((PetscObject)v,"PetscMatlabEngineGet_C",VecMatlabEngineGet_Default);CHKERRQ(ierr); #endif ierr = PetscObjectChangeTypeName((PetscObject)v,VECMPI);CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode ISSortRemoveDups_General(IS is) { IS_General *sub = (IS_General*)is->data; PetscInt n; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscLayoutGetLocalSize(is->map, &n);CHKERRQ(ierr); if (sub->sorted) { ierr = PetscSortedRemoveDupsInt(&n,sub->idx);CHKERRQ(ierr); } else { ierr = PetscSortRemoveDupsInt(&n,sub->idx);CHKERRQ(ierr); } ierr = PetscLayoutSetLocalSize(is->map, n);CHKERRQ(ierr); ierr = PetscLayoutSetSize(is->map, PETSC_DECIDE);CHKERRQ(ierr); ierr = PetscLayoutSetUp(is->map);CHKERRQ(ierr); sub->sorted = PETSC_TRUE; PetscFunctionReturn(0); }
static PetscErrorCode ISSortRemoveDups_Block(IS is) { IS_Block *sub = (IS_Block*)is->data; PetscInt bs, n, nb; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscLayoutGetBlockSize(is->map, &bs);CHKERRQ(ierr); ierr = PetscLayoutGetLocalSize(is->map, &n);CHKERRQ(ierr); nb = n/bs; if (sub->sorted) { ierr = PetscSortedRemoveDupsInt(&nb,sub->idx);CHKERRQ(ierr); } else { ierr = PetscSortRemoveDupsInt(&nb,sub->idx);CHKERRQ(ierr); } ierr = PetscLayoutSetLocalSize(is->map, nb*bs);CHKERRQ(ierr); ierr = PetscLayoutSetSize(is->map, PETSC_DECIDE);CHKERRQ(ierr); ierr = PetscLayoutSetUp(is->map);CHKERRQ(ierr); sub->sorted = PETSC_TRUE; PetscFunctionReturn(0); }
PetscErrorCode ISBlockSetIndices_Block(IS is,PetscInt bs,PetscInt n,const PetscInt idx[],PetscCopyMode mode) { PetscErrorCode ierr; PetscInt i,min,max; IS_Block *sub = (IS_Block*)is->data; PetscBool sorted = PETSC_TRUE; PetscFunctionBegin; ierr = PetscFree(sub->idx);CHKERRQ(ierr); ierr = PetscLayoutSetLocalSize(is->map, n*bs);CHKERRQ(ierr); ierr = PetscLayoutSetBlockSize(is->map, bs);CHKERRQ(ierr); ierr = PetscLayoutSetUp(is->map);CHKERRQ(ierr); for (i=1; i<n; i++) { if (idx[i] < idx[i-1]) {sorted = PETSC_FALSE; break;} } if (n) min = max = idx[0]; else min = max = 0; for (i=1; i<n; i++) { if (idx[i] < min) min = idx[i]; if (idx[i] > max) max = idx[i]; } if (mode == PETSC_COPY_VALUES) { ierr = PetscMalloc1(n,&sub->idx);CHKERRQ(ierr); ierr = PetscLogObjectMemory((PetscObject)is,n*sizeof(PetscInt));CHKERRQ(ierr); ierr = PetscMemcpy(sub->idx,idx,n*sizeof(PetscInt));CHKERRQ(ierr); } else if (mode == PETSC_OWN_POINTER) sub->idx = (PetscInt*) idx; else SETERRQ(PetscObjectComm((PetscObject)is),PETSC_ERR_SUP,"Only supports PETSC_COPY_VALUES and PETSC_OWN_POINTER"); sub->sorted = sorted; is->min = bs*min; is->max = bs*max+bs-1; is->data = (void*)sub; ierr = PetscMemcpy(is->ops,&myops,sizeof(myops));CHKERRQ(ierr); is->isperm = PETSC_FALSE; PetscFunctionReturn(0); }
PetscErrorCode MatSetLocalToGlobalMapping_IS(Mat A,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) { PetscErrorCode ierr; PetscInt nr,rbs,nc,cbs; Mat_IS *is = (Mat_IS*)A->data; IS from,to; Vec cglobal,rglobal; PetscFunctionBegin; PetscCheckSameComm(A,1,rmapping,2); PetscCheckSameComm(A,1,cmapping,3); /* Destroy any previous data */ ierr = VecDestroy(&is->x);CHKERRQ(ierr); ierr = VecDestroy(&is->y);CHKERRQ(ierr); ierr = VecScatterDestroy(&is->rctx);CHKERRQ(ierr); ierr = VecScatterDestroy(&is->cctx);CHKERRQ(ierr); ierr = MatDestroy(&is->A);CHKERRQ(ierr); ierr = PetscSFDestroy(&is->sf);CHKERRQ(ierr); ierr = PetscFree2(is->sf_rootdata,is->sf_leafdata);CHKERRQ(ierr); /* Setup Layout and set local to global maps */ ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); ierr = PetscLayoutSetISLocalToGlobalMapping(A->rmap,rmapping);CHKERRQ(ierr); ierr = PetscLayoutSetISLocalToGlobalMapping(A->cmap,cmapping);CHKERRQ(ierr); /* Create the local matrix A */ ierr = ISLocalToGlobalMappingGetSize(rmapping,&nr);CHKERRQ(ierr); ierr = ISLocalToGlobalMappingGetBlockSize(rmapping,&rbs);CHKERRQ(ierr); ierr = ISLocalToGlobalMappingGetSize(cmapping,&nc);CHKERRQ(ierr); ierr = ISLocalToGlobalMappingGetBlockSize(cmapping,&cbs);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_SELF,&is->A);CHKERRQ(ierr); ierr = MatSetType(is->A,MATAIJ);CHKERRQ(ierr); ierr = MatSetSizes(is->A,nr,nc,nr,nc);CHKERRQ(ierr); ierr = MatSetBlockSizes(is->A,rbs,cbs);CHKERRQ(ierr); ierr = MatSetOptionsPrefix(is->A,((PetscObject)A)->prefix);CHKERRQ(ierr); ierr = MatAppendOptionsPrefix(is->A,"is_");CHKERRQ(ierr); ierr = MatSetFromOptions(is->A);CHKERRQ(ierr); /* Create the local work vectors */ ierr = MatCreateVecs(is->A,&is->x,&is->y);CHKERRQ(ierr); /* setup the global to local scatters */ ierr = MatCreateVecs(A,&cglobal,&rglobal);CHKERRQ(ierr); ierr = ISCreateStride(PETSC_COMM_SELF,nr,0,1,&to);CHKERRQ(ierr); ierr = ISLocalToGlobalMappingApplyIS(rmapping,to,&from);CHKERRQ(ierr); ierr = VecScatterCreate(rglobal,from,is->y,to,&is->rctx);CHKERRQ(ierr); if (rmapping != cmapping) { ierr = ISDestroy(&to);CHKERRQ(ierr); ierr = ISDestroy(&from);CHKERRQ(ierr); ierr = ISCreateStride(PETSC_COMM_SELF,nc,0,1,&to);CHKERRQ(ierr); ierr = ISLocalToGlobalMappingApplyIS(cmapping,to,&from);CHKERRQ(ierr); ierr = VecScatterCreate(cglobal,from,is->x,to,&is->cctx);CHKERRQ(ierr); } else { ierr = PetscObjectReference((PetscObject)is->rctx);CHKERRQ(ierr); is->cctx = is->rctx; } ierr = VecDestroy(&rglobal);CHKERRQ(ierr); ierr = VecDestroy(&cglobal);CHKERRQ(ierr); ierr = ISDestroy(&to);CHKERRQ(ierr); ierr = ISDestroy(&from);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode MatGetMultiProcBlock_MPIBAIJ(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat) { PetscErrorCode ierr; Mat_MPIBAIJ *aij = (Mat_MPIBAIJ*)mat->data; Mat_SeqBAIJ *aijB = (Mat_SeqBAIJ*)aij->B->data; PetscMPIInt commRank,subCommSize,subCommRank; PetscMPIInt *commRankMap,subRank,rank,commsize; PetscInt *garrayCMap,col,i,j,*nnz,newRow,newCol,*newbRow,*newbCol,k,k1; PetscInt bs=mat->rmap->bs; PetscScalar *vals,*aijBvals; PetscFunctionBegin; ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr); ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr); /* create subMat object with the relavent layout */ if (scall == MAT_INITIAL_MATRIX) { ierr = MatCreate(subComm,subMat);CHKERRQ(ierr); ierr = MatSetType(*subMat,MATMPIBAIJ);CHKERRQ(ierr); ierr = MatSetSizes(*subMat,mat->rmap->n,mat->cmap->n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); ierr = MatSetBlockSizes(*subMat,mat->rmap->bs,mat->cmap->bs);CHKERRQ(ierr); /* need to setup rmap and cmap before Preallocation */ ierr = PetscLayoutSetBlockSize((*subMat)->rmap,mat->rmap->bs);CHKERRQ(ierr); ierr = PetscLayoutSetBlockSize((*subMat)->cmap,mat->cmap->bs);CHKERRQ(ierr); ierr = PetscLayoutSetUp((*subMat)->rmap);CHKERRQ(ierr); ierr = PetscLayoutSetUp((*subMat)->cmap);CHKERRQ(ierr); } /* create a map of comm_rank from subComm to comm - should commRankMap and garrayCMap be kept for reused? */ ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mat),&commRank);CHKERRQ(ierr); ierr = MPI_Comm_rank(subComm,&subCommRank);CHKERRQ(ierr); ierr = PetscMalloc(subCommSize*sizeof(PetscMPIInt),&commRankMap);CHKERRQ(ierr); ierr = MPI_Allgather(&commRank,1,MPI_INT,commRankMap,1,MPI_INT,subComm);CHKERRQ(ierr); /* Traverse garray and identify blocked column indices [of offdiag mat] that should be discarded. For the ones not discarded, store the newCol+1 value in garrayCMap */ ierr = PetscMalloc(aij->B->cmap->n/bs*sizeof(PetscInt),&garrayCMap);CHKERRQ(ierr); ierr = PetscMemzero(garrayCMap,aij->B->cmap->n/bs*sizeof(PetscInt));CHKERRQ(ierr); for (i=0; i<aij->B->cmap->n/bs; i++) { col = aij->garray[i]; /* blocked column index */ for (subRank=0; subRank<subCommSize; subRank++) { rank = commRankMap[subRank]; if ((col >= mat->cmap->range[rank]/bs) && (col < mat->cmap->range[rank+1]/bs)) { garrayCMap[i] = (((*subMat)->cmap->range[subRank]- mat->cmap->range[rank])/bs + col + 1); break; } } } if (scall == MAT_INITIAL_MATRIX) { /* Now compute preallocation for the offdiag mat */ ierr = PetscMalloc(aij->B->rmap->n/bs*sizeof(PetscInt),&nnz);CHKERRQ(ierr); ierr = PetscMemzero(nnz,aij->B->rmap->n/bs*sizeof(PetscInt));CHKERRQ(ierr); for (i=0; i<aij->B->rmap->n/bs; i++) { for (j=aijB->i[i]; j<aijB->i[i+1]; j++) { if (garrayCMap[aijB->j[j]]) nnz[i]++; } } ierr = MatMPIBAIJSetPreallocation(*(subMat),bs,0,NULL,0,nnz);CHKERRQ(ierr); /* reuse diag block with the new submat */ ierr = MatDestroy(&((Mat_MPIBAIJ*)((*subMat)->data))->A);CHKERRQ(ierr); ((Mat_MPIBAIJ*)((*subMat)->data))->A = aij->A; ierr = PetscObjectReference((PetscObject)aij->A);CHKERRQ(ierr); } else if (((Mat_MPIBAIJ*)(*subMat)->data)->A != aij->A) { PetscObject obj = (PetscObject)((Mat_MPIBAIJ*)((*subMat)->data))->A; ierr = PetscObjectReference((PetscObject)obj);CHKERRQ(ierr); ((Mat_MPIBAIJ*)((*subMat)->data))->A = aij->A; ierr = PetscObjectReference((PetscObject)aij->A);CHKERRQ(ierr); } /* Now traverse aij->B and insert values into subMat */ ierr = PetscMalloc3(bs,PetscInt,&newbRow,bs,PetscInt,&newbCol,bs*bs,PetscScalar,&vals);CHKERRQ(ierr); for (i=0; i<aij->B->rmap->n/bs; i++) { newRow = (*subMat)->rmap->range[subCommRank] + i*bs; for (j=aijB->i[i]; j<aijB->i[i+1]; j++) { newCol = garrayCMap[aijB->j[j]]; if (newCol) { newCol--; /* remove the increment */ newCol *= bs; for (k=0; k<bs; k++) { newbRow[k] = newRow + k; newbCol[k] = newCol + k; } /* copy column-oriented aijB->a into row-oriented vals */ aijBvals = aijB->a + j*bs*bs; for (k1=0; k1<bs; k1++) { for (k=0; k<bs; k++) { vals[k1+k*bs] = *aijBvals++; } } ierr = MatSetValues(*subMat,bs,newbRow,bs,newbCol,vals,INSERT_VALUES);CHKERRQ(ierr); } } } ierr = MatAssemblyBegin(*subMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(*subMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* deallocate temporary data */ ierr = PetscFree3(newbRow,newbCol,vals);CHKERRQ(ierr); ierr = PetscFree(commRankMap);CHKERRQ(ierr); ierr = PetscFree(garrayCMap);CHKERRQ(ierr); if (scall == MAT_INITIAL_MATRIX) { ierr = PetscFree(nnz);CHKERRQ(ierr); } PetscFunctionReturn(0); }
PETSC_EXTERN PetscErrorCode AOCreate_MemoryScalable(AO ao) { PetscErrorCode ierr; IS isapp=ao->isapp,ispetsc=ao->ispetsc; const PetscInt *mypetsc,*myapp; PetscInt napp,n_local,N,i,start,*petsc,*lens,*disp; MPI_Comm comm; AO_MemoryScalable *aomems; PetscLayout map; PetscMPIInt size,rank; PetscFunctionBegin; /* create special struct aomems */ ierr = PetscNewLog(ao, AO_MemoryScalable, &aomems); CHKERRQ(ierr); ao->data = (void*) aomems; ierr = PetscMemcpy(ao->ops,&AOOps_MemoryScalable,sizeof(struct _AOOps)); CHKERRQ(ierr); ierr = PetscObjectChangeTypeName((PetscObject)ao,AOMEMORYSCALABLE); CHKERRQ(ierr); /* transmit all local lengths of isapp to all processors */ ierr = PetscObjectGetComm((PetscObject)isapp,&comm); CHKERRQ(ierr); ierr = MPI_Comm_size(comm, &size); CHKERRQ(ierr); ierr = MPI_Comm_rank(comm, &rank); CHKERRQ(ierr); ierr = PetscMalloc2(size,PetscInt,&lens,size,PetscInt,&disp); CHKERRQ(ierr); ierr = ISGetLocalSize(isapp,&napp); CHKERRQ(ierr); ierr = MPI_Allgather(&napp, 1, MPIU_INT, lens, 1, MPIU_INT, comm); CHKERRQ(ierr); N = 0; for (i = 0; i < size; i++) { disp[i] = N; N += lens[i]; } /* If ispetsc is 0 then use "natural" numbering */ if (napp) { if (!ispetsc) { start = disp[rank]; ierr = PetscMalloc((napp+1) * sizeof(PetscInt), &petsc); CHKERRQ(ierr); for (i=0; i<napp; i++) petsc[i] = start + i; } else { ierr = ISGetIndices(ispetsc,&mypetsc); CHKERRQ(ierr); petsc = (PetscInt*)mypetsc; } } /* create a map with global size N - used to determine the local sizes of ao - shall we use local napp instead of N? */ ierr = PetscLayoutCreate(comm,&map); CHKERRQ(ierr); map->bs = 1; map->N = N; ierr = PetscLayoutSetUp(map); CHKERRQ(ierr); ao->N = N; ao->n = map->n; aomems->map = map; /* create distributed indices app_loc: petsc->app and petsc_loc: app->petsc */ n_local = map->n; ierr = PetscMalloc2(n_local,PetscInt, &aomems->app_loc,n_local,PetscInt,&aomems->petsc_loc); CHKERRQ(ierr); ierr = PetscLogObjectMemory(ao,2*n_local*sizeof(PetscInt)); CHKERRQ(ierr); ierr = PetscMemzero(aomems->app_loc,n_local*sizeof(PetscInt)); CHKERRQ(ierr); ierr = PetscMemzero(aomems->petsc_loc,n_local*sizeof(PetscInt)); CHKERRQ(ierr); ierr = ISGetIndices(isapp,&myapp); CHKERRQ(ierr); ierr = AOCreateMemoryScalable_private(comm,napp,petsc,myapp,ao,aomems->app_loc); CHKERRQ(ierr); ierr = AOCreateMemoryScalable_private(comm,napp,myapp,petsc,ao,aomems->petsc_loc); CHKERRQ(ierr); ierr = ISRestoreIndices(isapp,&myapp); CHKERRQ(ierr); if (napp) { if (ispetsc) { ierr = ISRestoreIndices(ispetsc,&mypetsc); CHKERRQ(ierr); } else { ierr = PetscFree(petsc); CHKERRQ(ierr); } } ierr = PetscFree2(lens,disp); CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode DMPlexVTKWriteAll_ASCII(DM dm, PetscViewer viewer) { MPI_Comm comm; PetscViewer_VTK *vtk = (PetscViewer_VTK*) viewer->data; FILE *fp; PetscViewerVTKObjectLink link; PetscSection coordSection, globalCoordSection; PetscLayout vLayout; Vec coordinates; PetscReal lengthScale; PetscInt vMax, totVertices, totCells; PetscBool hasPoint = PETSC_FALSE, hasCell = PETSC_FALSE, writePartition = PETSC_FALSE; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); ierr = PetscFOpen(comm, vtk->filename, "wb", &fp);CHKERRQ(ierr); ierr = PetscFPrintf(comm, fp, "# vtk DataFile Version 2.0\n");CHKERRQ(ierr); ierr = PetscFPrintf(comm, fp, "Simplicial Mesh Example\n");CHKERRQ(ierr); ierr = PetscFPrintf(comm, fp, "ASCII\n");CHKERRQ(ierr); ierr = PetscFPrintf(comm, fp, "DATASET UNSTRUCTURED_GRID\n");CHKERRQ(ierr); /* Vertices */ ierr = DMPlexGetScale(dm, PETSC_UNIT_LENGTH, &lengthScale);CHKERRQ(ierr); ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); ierr = PetscSectionCreateGlobalSection(coordSection, dm->sf, PETSC_FALSE, PETSC_FALSE, &globalCoordSection);CHKERRQ(ierr); ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); ierr = DMPlexGetHybridBounds(dm, NULL, NULL, NULL, &vMax);CHKERRQ(ierr); if (vMax >= 0) { PetscInt pStart, pEnd, p, localSize = 0; ierr = PetscSectionGetChart(globalCoordSection, &pStart, &pEnd);CHKERRQ(ierr); pEnd = PetscMin(pEnd, vMax); for (p = pStart; p < pEnd; ++p) { PetscInt dof; ierr = PetscSectionGetDof(globalCoordSection, p, &dof);CHKERRQ(ierr); if (dof > 0) ++localSize; } ierr = PetscLayoutCreate(PetscObjectComm((PetscObject)dm), &vLayout);CHKERRQ(ierr); ierr = PetscLayoutSetLocalSize(vLayout, localSize);CHKERRQ(ierr); ierr = PetscLayoutSetBlockSize(vLayout, 1);CHKERRQ(ierr); ierr = PetscLayoutSetUp(vLayout);CHKERRQ(ierr); } else { ierr = PetscSectionGetPointLayout(PetscObjectComm((PetscObject)dm), globalCoordSection, &vLayout);CHKERRQ(ierr); } ierr = PetscLayoutGetSize(vLayout, &totVertices);CHKERRQ(ierr); ierr = PetscFPrintf(comm, fp, "POINTS %d double\n", totVertices);CHKERRQ(ierr); ierr = DMPlexVTKWriteSection_ASCII(dm, coordSection, globalCoordSection, coordinates, fp, 3, PETSC_DETERMINE, lengthScale);CHKERRQ(ierr); /* Cells */ ierr = DMPlexVTKWriteCells_ASCII(dm, fp, &totCells);CHKERRQ(ierr); /* Vertex fields */ for (link = vtk->link; link; link = link->next) { if ((link->ft == PETSC_VTK_POINT_FIELD) || (link->ft == PETSC_VTK_POINT_VECTOR_FIELD)) hasPoint = PETSC_TRUE; if ((link->ft == PETSC_VTK_CELL_FIELD) || (link->ft == PETSC_VTK_CELL_VECTOR_FIELD)) hasCell = PETSC_TRUE; } if (hasPoint) { ierr = PetscFPrintf(comm, fp, "POINT_DATA %d\n", totVertices);CHKERRQ(ierr); for (link = vtk->link; link; link = link->next) { Vec X = (Vec) link->vec; DM dmX; PetscSection section, globalSection, newSection = NULL; const char *name; PetscInt enforceDof = PETSC_DETERMINE; if ((link->ft != PETSC_VTK_POINT_FIELD) && (link->ft != PETSC_VTK_POINT_VECTOR_FIELD)) continue; if (link->ft == PETSC_VTK_POINT_VECTOR_FIELD) enforceDof = 3; ierr = PetscObjectGetName(link->vec, &name);CHKERRQ(ierr); ierr = VecGetDM(X, &dmX);CHKERRQ(ierr); if (dmX) { DMLabel subpointMap, subpointMapX; PetscInt dim, dimX, pStart, pEnd, qStart, qEnd; ierr = DMGetDefaultSection(dmX, §ion);CHKERRQ(ierr); /* Here is where we check whether dmX is a submesh of dm */ ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); ierr = DMGetDimension(dmX, &dimX);CHKERRQ(ierr); ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); ierr = DMPlexGetChart(dmX, &qStart, &qEnd);CHKERRQ(ierr); ierr = DMPlexGetSubpointMap(dm, &subpointMap);CHKERRQ(ierr); ierr = DMPlexGetSubpointMap(dmX, &subpointMapX);CHKERRQ(ierr); if (((dim != dimX) || ((pEnd-pStart) < (qEnd-qStart))) && subpointMap && !subpointMapX) { const PetscInt *ind = NULL; IS subpointIS; PetscInt n = 0, q; ierr = PetscSectionGetChart(section, &qStart, &qEnd);CHKERRQ(ierr); ierr = DMPlexCreateSubpointIS(dm, &subpointIS);CHKERRQ(ierr); if (subpointIS) { ierr = ISGetLocalSize(subpointIS, &n);CHKERRQ(ierr); ierr = ISGetIndices(subpointIS, &ind);CHKERRQ(ierr); } ierr = PetscSectionCreate(comm, &newSection);CHKERRQ(ierr); ierr = PetscSectionSetChart(newSection, pStart, pEnd);CHKERRQ(ierr); for (q = qStart; q < qEnd; ++q) { PetscInt dof, off, p; ierr = PetscSectionGetDof(section, q, &dof);CHKERRQ(ierr); if (dof) { ierr = PetscFindInt(q, n, ind, &p);CHKERRQ(ierr); if (p >= pStart) { ierr = PetscSectionSetDof(newSection, p, dof);CHKERRQ(ierr); ierr = PetscSectionGetOffset(section, q, &off);CHKERRQ(ierr); ierr = PetscSectionSetOffset(newSection, p, off);CHKERRQ(ierr); } } } if (subpointIS) { ierr = ISRestoreIndices(subpointIS, &ind);CHKERRQ(ierr); ierr = ISDestroy(&subpointIS);CHKERRQ(ierr); } /* No need to setup section */ section = newSection; } } else { ierr = PetscObjectQuery(link->vec, "section", (PetscObject*) §ion);CHKERRQ(ierr); if (!section) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Vector %s had no PetscSection composed with it", name); } if (!section) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Vector %s had no PetscSection composed with it", name); ierr = PetscSectionCreateGlobalSection(section, dm->sf, PETSC_FALSE, PETSC_FALSE, &globalSection);CHKERRQ(ierr); ierr = DMPlexVTKWriteField_ASCII(dm, section, globalSection, X, name, fp, enforceDof, PETSC_DETERMINE, 1.0);CHKERRQ(ierr); ierr = PetscSectionDestroy(&globalSection);CHKERRQ(ierr); if (newSection) {ierr = PetscSectionDestroy(&newSection);CHKERRQ(ierr);} } } /* Cell Fields */ ierr = PetscOptionsGetBool(((PetscObject) dm)->prefix, "-dm_view_partition", &writePartition, NULL);CHKERRQ(ierr); if (hasCell || writePartition) { ierr = PetscFPrintf(comm, fp, "CELL_DATA %d\n", totCells);CHKERRQ(ierr); for (link = vtk->link; link; link = link->next) { Vec X = (Vec) link->vec; DM dmX; PetscSection section, globalSection; const char *name; PetscInt enforceDof = PETSC_DETERMINE; if ((link->ft != PETSC_VTK_CELL_FIELD) && (link->ft != PETSC_VTK_CELL_VECTOR_FIELD)) continue; if (link->ft == PETSC_VTK_CELL_VECTOR_FIELD) enforceDof = 3; ierr = PetscObjectGetName(link->vec, &name);CHKERRQ(ierr); ierr = VecGetDM(X, &dmX);CHKERRQ(ierr); if (dmX) { ierr = DMGetDefaultSection(dmX, §ion);CHKERRQ(ierr); } else { PetscContainer c; ierr = PetscObjectQuery(link->vec, "section", (PetscObject*) &c);CHKERRQ(ierr); if (!c) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Vector %s had no PetscSection composed with it", name); ierr = PetscContainerGetPointer(c, (void**) §ion);CHKERRQ(ierr); } if (!section) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Vector %s had no PetscSection composed with it", name); ierr = PetscSectionCreateGlobalSection(section, dm->sf, PETSC_FALSE, PETSC_FALSE, &globalSection);CHKERRQ(ierr); ierr = DMPlexVTKWriteField_ASCII(dm, section, globalSection, X, name, fp, enforceDof, PETSC_DETERMINE, 1.0);CHKERRQ(ierr); ierr = PetscSectionDestroy(&globalSection);CHKERRQ(ierr); } if (writePartition) { ierr = PetscFPrintf(comm, fp, "SCALARS partition int 1\n");CHKERRQ(ierr); ierr = PetscFPrintf(comm, fp, "LOOKUP_TABLE default\n");CHKERRQ(ierr); ierr = DMPlexVTKWritePartition_ASCII(dm, fp);CHKERRQ(ierr); } } /* Cleanup */ ierr = PetscSectionDestroy(&globalCoordSection);CHKERRQ(ierr); ierr = PetscLayoutDestroy(&vLayout);CHKERRQ(ierr); ierr = PetscFClose(comm, fp);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode MatSetUpMultiply_MPIAIJ(Mat mat) { Mat_MPIAIJ *aij = (Mat_MPIAIJ*)mat->data; Mat_SeqAIJ *B = (Mat_SeqAIJ*)(aij->B->data); PetscErrorCode ierr; PetscInt i,j,*aj = B->j,ec = 0,*garray; IS from,to; Vec gvec; #if defined(PETSC_USE_CTABLE) PetscTable gid1_lid1; PetscTablePosition tpos; PetscInt gid,lid; #else PetscInt N = mat->cmap->N,*indices; #endif PetscFunctionBegin; if (!aij->garray) { #if defined(PETSC_USE_CTABLE) /* use a table */ ierr = PetscTableCreate(aij->B->rmap->n,mat->cmap->N+1,&gid1_lid1);CHKERRQ(ierr); for (i=0; i<aij->B->rmap->n; i++) { for (j=0; j<B->ilen[i]; j++) { PetscInt data,gid1 = aj[B->i[i] + j] + 1; ierr = PetscTableFind(gid1_lid1,gid1,&data);CHKERRQ(ierr); if (!data) { /* one based table */ ierr = PetscTableAdd(gid1_lid1,gid1,++ec,INSERT_VALUES);CHKERRQ(ierr); } } } /* form array of columns we need */ ierr = PetscMalloc1(ec+1,&garray);CHKERRQ(ierr); ierr = PetscTableGetHeadPosition(gid1_lid1,&tpos);CHKERRQ(ierr); while (tpos) { ierr = PetscTableGetNext(gid1_lid1,&tpos,&gid,&lid);CHKERRQ(ierr); gid--; lid--; garray[lid] = gid; } ierr = PetscSortInt(ec,garray);CHKERRQ(ierr); /* sort, and rebuild */ ierr = PetscTableRemoveAll(gid1_lid1);CHKERRQ(ierr); for (i=0; i<ec; i++) { ierr = PetscTableAdd(gid1_lid1,garray[i]+1,i+1,INSERT_VALUES);CHKERRQ(ierr); } /* compact out the extra columns in B */ for (i=0; i<aij->B->rmap->n; i++) { for (j=0; j<B->ilen[i]; j++) { PetscInt gid1 = aj[B->i[i] + j] + 1; ierr = PetscTableFind(gid1_lid1,gid1,&lid);CHKERRQ(ierr); lid--; aj[B->i[i] + j] = lid; } } aij->B->cmap->n = aij->B->cmap->N = ec; aij->B->cmap->bs = 1; ierr = PetscLayoutSetUp((aij->B->cmap));CHKERRQ(ierr); ierr = PetscTableDestroy(&gid1_lid1);CHKERRQ(ierr); #else /* Make an array as long as the number of columns */ /* mark those columns that are in aij->B */ ierr = PetscCalloc1(N+1,&indices);CHKERRQ(ierr); for (i=0; i<aij->B->rmap->n; i++) { for (j=0; j<B->ilen[i]; j++) { if (!indices[aj[B->i[i] + j]]) ec++; indices[aj[B->i[i] + j]] = 1; } } /* form array of columns we need */ ierr = PetscMalloc1(ec+1,&garray);CHKERRQ(ierr); ec = 0; for (i=0; i<N; i++) { if (indices[i]) garray[ec++] = i; } /* make indices now point into garray */ for (i=0; i<ec; i++) { indices[garray[i]] = i; } /* compact out the extra columns in B */ for (i=0; i<aij->B->rmap->n; i++) { for (j=0; j<B->ilen[i]; j++) { aj[B->i[i] + j] = indices[aj[B->i[i] + j]]; } } aij->B->cmap->n = aij->B->cmap->N = ec; aij->B->cmap->bs = 1; ierr = PetscLayoutSetUp((aij->B->cmap));CHKERRQ(ierr); ierr = PetscFree(indices);CHKERRQ(ierr); #endif } else { garray = aij->garray; } if (!aij->lvec) { /* create local vector that is used to scatter into */ ierr = VecCreateSeq(PETSC_COMM_SELF,ec,&aij->lvec);CHKERRQ(ierr); } else { ierr = VecGetSize(aij->lvec,&ec);CHKERRQ(ierr); } /* create two temporary Index sets for build scatter gather */ ierr = ISCreateGeneral(((PetscObject)mat)->comm,ec,garray,PETSC_COPY_VALUES,&from);CHKERRQ(ierr); ierr = ISCreateStride(PETSC_COMM_SELF,ec,0,1,&to);CHKERRQ(ierr); /* create temporary global vector to generate scatter context */ /* This does not allocate the array's memory so is efficient */ ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)mat),1,mat->cmap->n,mat->cmap->N,NULL,&gvec);CHKERRQ(ierr); /* generate the scatter context */ if (aij->Mvctx_mpi1_flg) { ierr = VecScatterDestroy(&aij->Mvctx_mpi1);CHKERRQ(ierr); ierr = VecScatterCreate(gvec,from,aij->lvec,to,&aij->Mvctx_mpi1);CHKERRQ(ierr); ierr = VecScatterSetType(aij->Mvctx_mpi1,VECSCATTERMPI1);CHKERRQ(ierr); ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)aij->Mvctx_mpi1);CHKERRQ(ierr); } else { ierr = VecScatterDestroy(&aij->Mvctx);CHKERRQ(ierr); ierr = VecScatterCreate(gvec,from,aij->lvec,to,&aij->Mvctx);CHKERRQ(ierr); ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)aij->Mvctx);CHKERRQ(ierr); ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)aij->lvec);CHKERRQ(ierr); ierr = PetscLogObjectMemory((PetscObject)mat,(ec+1)*sizeof(PetscInt));CHKERRQ(ierr); } aij->garray = garray; ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)from);CHKERRQ(ierr); ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)to);CHKERRQ(ierr); ierr = ISDestroy(&from);CHKERRQ(ierr); ierr = ISDestroy(&to);CHKERRQ(ierr); ierr = VecDestroy(&gvec);CHKERRQ(ierr); PetscFunctionReturn(0); }