1032b8ab6SVijay Mahadevan #include <petsc-private/dmmbimpl.h> /*I "petscdm.h" I*/ 2032b8ab6SVijay Mahadevan #include <petsc-private/vecimpl.h> /*I "petscdm.h" I*/ 3032b8ab6SVijay Mahadevan 4032b8ab6SVijay Mahadevan #include <petscdmmoab.h> 5032b8ab6SVijay Mahadevan 6032b8ab6SVijay Mahadevan static PetscErrorCode DMMoab_Compute_NNZ_From_Connectivity(DM,PetscInt*,PetscInt*,PetscInt*,PetscInt*,PetscBool); 7032b8ab6SVijay Mahadevan 8032b8ab6SVijay Mahadevan #undef __FUNCT__ 9032b8ab6SVijay Mahadevan #define __FUNCT__ "DMCreateMatrix_Moab" 10032b8ab6SVijay Mahadevan PetscErrorCode DMCreateMatrix_Moab(DM dm, MatType mtype,Mat *J) 11032b8ab6SVijay Mahadevan { 12032b8ab6SVijay Mahadevan PetscErrorCode ierr; 13032b8ab6SVijay Mahadevan ISLocalToGlobalMapping ltog; 14032b8ab6SVijay Mahadevan MatType mltype; 15032b8ab6SVijay Mahadevan PetscInt i,nloc,count,dof,innz,ionz,nsize; 16032b8ab6SVijay Mahadevan DM_Moab *dmmoab = (DM_Moab*)dm->data; 17032b8ab6SVijay Mahadevan moab::Range *range=dmmoab->vowned; 18*15de014fSVijay Mahadevan PetscInt *nnz,*onz; 19032b8ab6SVijay Mahadevan char *tmp=0; 20032b8ab6SVijay Mahadevan moab::ErrorCode merr; 21032b8ab6SVijay Mahadevan 22032b8ab6SVijay Mahadevan PetscFunctionBegin; 23032b8ab6SVijay Mahadevan PetscValidHeaderSpecific(dm,DM_CLASSID,1); 24032b8ab6SVijay Mahadevan PetscValidPointer(J,3); 25032b8ab6SVijay Mahadevan nloc = dmmoab->vowned->size() * dmmoab->bs; 26032b8ab6SVijay Mahadevan 27db66d124SVijay Mahadevan /* create the Matrix and set its type as specified by user */ 28032b8ab6SVijay Mahadevan ierr = MatCreate(dmmoab->pcomm->comm(), J);CHKERRQ(ierr); 29032b8ab6SVijay Mahadevan ierr = MatSetSizes(*J, nloc, nloc, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 30032b8ab6SVijay Mahadevan ierr = MatSetType(*J, mtype);CHKERRQ(ierr); 31032b8ab6SVijay Mahadevan ierr = MatSetFromOptions(*J);CHKERRQ(ierr); 32032b8ab6SVijay Mahadevan 33db66d124SVijay Mahadevan /* next, need to allocate the non-zero arrays to enable pre-allocation */ 34032b8ab6SVijay Mahadevan ierr = MatGetType(*J, &mltype);CHKERRQ(ierr); /* in case user overrode the default type from command-line, re-check the type */ 35032b8ab6SVijay Mahadevan ierr = PetscStrstr(mltype, "baij", &tmp);CHKERRQ(ierr); 36032b8ab6SVijay Mahadevan nsize = (tmp ? dmmoab->nloc:dmmoab->nloc*dmmoab->bs); 37032b8ab6SVijay Mahadevan 38032b8ab6SVijay Mahadevan /* allocate the nnz, onz arrays based on block size and local nodes */ 39032b8ab6SVijay Mahadevan ierr = PetscMalloc(nsize*sizeof(PetscInt),&nnz);CHKERRQ(ierr); 40032b8ab6SVijay Mahadevan ierr = PetscMemzero(nnz,sizeof(PetscInt)*nsize);CHKERRQ(ierr); 41032b8ab6SVijay Mahadevan ierr = PetscMalloc(nsize*sizeof(PetscInt),&onz);CHKERRQ(ierr); 42032b8ab6SVijay Mahadevan ierr = PetscMemzero(onz,sizeof(PetscInt)*nsize);CHKERRQ(ierr); 43032b8ab6SVijay Mahadevan 44032b8ab6SVijay Mahadevan /* compute the nonzero pattern based on MOAB connectivity data for local elements */ 45032b8ab6SVijay Mahadevan ierr = DMMoab_Compute_NNZ_From_Connectivity(dm,&innz,nnz,&ionz,onz,(tmp?PETSC_TRUE:PETSC_FALSE));CHKERRQ(ierr); 46032b8ab6SVijay Mahadevan 47032b8ab6SVijay Mahadevan if (dmmoab->bs > 1 && tmp) { 48db66d124SVijay Mahadevan /* Block matrix created, now set local to global mapping */ 49*15de014fSVijay Mahadevan ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,range->size(),dmmoab->gsindices,PETSC_COPY_VALUES,<og);CHKERRQ(ierr); 50032b8ab6SVijay Mahadevan ierr = MatSetLocalToGlobalMappingBlock(*J,ltog,ltog);CHKERRQ(ierr); 51032b8ab6SVijay Mahadevan 52db66d124SVijay Mahadevan /* Clean up */ 53032b8ab6SVijay Mahadevan ierr = ISLocalToGlobalMappingDestroy(<og);CHKERRQ(ierr); 54032b8ab6SVijay Mahadevan 55032b8ab6SVijay Mahadevan } else { 56032b8ab6SVijay Mahadevan ierr = MatSetBlockSize(*J, dmmoab->bs);CHKERRQ(ierr); 57032b8ab6SVijay Mahadevan } 58032b8ab6SVijay Mahadevan 59032b8ab6SVijay Mahadevan /* set preallocation based on different supported Mat types */ 60e23c60ebSVijay Mahadevan ierr = MatSeqAIJSetPreallocation(*J, innz, nnz);CHKERRQ(ierr); 61e23c60ebSVijay Mahadevan ierr = MatMPIAIJSetPreallocation(*J, innz, nnz, ionz, onz);CHKERRQ(ierr); 62032b8ab6SVijay Mahadevan ierr = MatSeqBAIJSetPreallocation(*J, dmmoab->bs, innz, nnz);CHKERRQ(ierr); 63032b8ab6SVijay Mahadevan ierr = MatMPIBAIJSetPreallocation(*J, dmmoab->bs, innz, nnz, ionz, onz);CHKERRQ(ierr); 64032b8ab6SVijay Mahadevan 65032b8ab6SVijay Mahadevan ierr = MatSetDM(*J, dm);CHKERRQ(ierr); 66032b8ab6SVijay Mahadevan ierr = PetscFree(nnz);CHKERRQ(ierr); 67032b8ab6SVijay Mahadevan ierr = PetscFree(onz);CHKERRQ(ierr); 68032b8ab6SVijay Mahadevan PetscFunctionReturn(0); 69032b8ab6SVijay Mahadevan } 70032b8ab6SVijay Mahadevan 71032b8ab6SVijay Mahadevan 72032b8ab6SVijay Mahadevan #undef __FUNCT__ 73032b8ab6SVijay Mahadevan #define __FUNCT__ "DMMoab_Compute_NNZ_From_Connectivity" 74032b8ab6SVijay Mahadevan PetscErrorCode DMMoab_Compute_NNZ_From_Connectivity(DM dm,PetscInt* innz,PetscInt* nnz,PetscInt* ionz,PetscInt* onz,PetscBool isbaij) 75032b8ab6SVijay Mahadevan { 76032b8ab6SVijay Mahadevan PetscErrorCode ierr; 770df6e276SVijay Mahadevan PetscInt i,j,f,nloc,vpere,bs,nsize,nghost_found; 78032b8ab6SVijay Mahadevan DM_Moab *dmmoab = (DM_Moab*)dm->data; 79032b8ab6SVijay Mahadevan const moab::EntityHandle *connect; 800df6e276SVijay Mahadevan moab::Range *vowned=dmmoab->vowned,*elocal=dmmoab->elocal,*eghost=dmmoab->eghost,adjs,visited; 81032b8ab6SVijay Mahadevan moab::Range::iterator iter; 820df6e276SVijay Mahadevan PetscInt dof,doff,ndofs; 83032b8ab6SVijay Mahadevan moab::Tag id_tag; 84032b8ab6SVijay Mahadevan moab::ErrorCode merr; 850df6e276SVijay Mahadevan PetscSection section; 86032b8ab6SVijay Mahadevan 87032b8ab6SVijay Mahadevan PetscFunctionBegin; 88032b8ab6SVijay Mahadevan bs = dmmoab->bs; 89032b8ab6SVijay Mahadevan nloc = dmmoab->nloc; 90032b8ab6SVijay Mahadevan nsize = (isbaij ? nloc:nloc*bs); 91032b8ab6SVijay Mahadevan 92032b8ab6SVijay Mahadevan ierr = DMMoabGetLocalToGlobalTag(dm,&id_tag);CHKERRQ(ierr); 93032b8ab6SVijay Mahadevan 940df6e276SVijay Mahadevan ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr); 95032b8ab6SVijay Mahadevan 96032b8ab6SVijay Mahadevan for(iter = elocal->begin(),i=0; iter != elocal->end(); iter++,i++) { 97032b8ab6SVijay Mahadevan /* Get connectivity information in canonical ordering for the local element */ 98032b8ab6SVijay Mahadevan merr = dmmoab->mbiface->get_connectivity((*iter),connect,vpere);MBERRNM(merr); 99032b8ab6SVijay Mahadevan 100032b8ab6SVijay Mahadevan nghost_found=0; 101032b8ab6SVijay Mahadevan /* loop over vertices and update the number of connectivity */ 102032b8ab6SVijay Mahadevan for (j=0;j<vpere;j++) { 103032b8ab6SVijay Mahadevan moab::Range::const_iterator giter = dmmoab->vghost->find(connect[j]); 104032b8ab6SVijay Mahadevan if (giter != dmmoab->vghost->end()) nghost_found++; 105032b8ab6SVijay Mahadevan } 106032b8ab6SVijay Mahadevan 107032b8ab6SVijay Mahadevan /* loop over vertices and update the number of connectivity */ 108032b8ab6SVijay Mahadevan for (j=0;j<vpere;j++) { 109032b8ab6SVijay Mahadevan 1100df6e276SVijay Mahadevan /* 1110df6e276SVijay Mahadevan moab::Range::const_iterator giter = visited.find(connect[j]); 1120df6e276SVijay Mahadevan if (giter != visited.end()) continue; 113032b8ab6SVijay Mahadevan 1140df6e276SVijay Mahadevan visited.insert(connect[j]); 1150df6e276SVijay Mahadevan */ 1160df6e276SVijay Mahadevan 117*15de014fSVijay Mahadevan /* loop over vertices and update the number of connectivity */ 118*15de014fSVijay Mahadevan for(jter = adjs.begin(); jter != adjs.end(); jter++) { 1190df6e276SVijay Mahadevan 120*15de014fSVijay Mahadevan /* Get connectivity information in canonical ordering for the local element */ 121*15de014fSVijay Mahadevan merr = dmmoab->mbiface->get_connectivity(*jter,connect,vpere,false,&storage);MBERRNM(merr); 1220df6e276SVijay Mahadevan 123*15de014fSVijay Mahadevan for (i=0; i<vpere; ++i) { 124*15de014fSVijay Mahadevan if (connect[i] == vtx || found.find(connect[i]) != found.end()) continue; 125*15de014fSVijay Mahadevan if (dmmoab->vghost->find(connect[i]) != dmmoab->vghost->end()) n_onz++; 126*15de014fSVijay Mahadevan else n_nnz++; 127*15de014fSVijay Mahadevan found.insert(connect[i]); 128*15de014fSVijay Mahadevan } 129*15de014fSVijay Mahadevan } 130*15de014fSVijay Mahadevan 131*15de014fSVijay Mahadevan merr = dmmoab->mbiface->tag_get_data(id_tag,&vtx,1,&gid);MBERRNM(merr); 132*15de014fSVijay Mahadevan 133*15de014fSVijay Mahadevan if (isbaij) { 134*15de014fSVijay Mahadevan nnz[ivtx]=n_nnz; /* leave out self to avoid repeats -> node shared by multiple elements */ 135*15de014fSVijay Mahadevan if (onz) onz[ivtx]=n_onz; /* add ghost non-owned nodes */ 136*15de014fSVijay Mahadevan } 137*15de014fSVijay Mahadevan else { 1380df6e276SVijay Mahadevan for (f=0;f<dmmoab->nfields;f++) { 139*15de014fSVijay Mahadevan nnz[dmmoab->nfields*ivtx+f]=n_nnz; /* leave out self to avoid repeats -> node shared by multiple elements */ 140*15de014fSVijay Mahadevan if (onz) onz[dmmoab->nfields*ivtx+f]=n_onz; /* add ghost non-owned nodes */ 1410df6e276SVijay Mahadevan } 1420df6e276SVijay Mahadevan } 1430df6e276SVijay Mahadevan } 1440df6e276SVijay Mahadevan 1450df6e276SVijay Mahadevan visited.clear(); 1460df6e276SVijay Mahadevan 1470df6e276SVijay Mahadevan if (innz) *innz=0; 1480df6e276SVijay Mahadevan if (ionz) *ionz=0; 1490df6e276SVijay Mahadevan for (i=0;i<nsize;i++) { 1500df6e276SVijay Mahadevan nnz[i]+=1; /* self count the node */ 151032b8ab6SVijay Mahadevan if (!isbaij) { 1520df6e276SVijay Mahadevan nnz[i]*=bs; 1530df6e276SVijay Mahadevan onz[i]*=bs; 154032b8ab6SVijay Mahadevan } 1550df6e276SVijay Mahadevan 1560df6e276SVijay Mahadevan if (innz && nnz[i]>*innz) *innz=nnz[i]; 1570df6e276SVijay Mahadevan if (ionz && onz[i]>*ionz) *ionz=onz[i]; 158032b8ab6SVijay Mahadevan } 1590df6e276SVijay Mahadevan PetscFunctionReturn(0); 160032b8ab6SVijay Mahadevan } 161032b8ab6SVijay Mahadevan 162