1b8ecf6d3SVijay Mahadevan #include <petsc-private/dmmbimpl.h> /*I "petscdmmoab.h" I*/ 2b8ecf6d3SVijay Mahadevan #include <petsc-private/vecimpl.h> 3032b8ab6SVijay Mahadevan 4032b8ab6SVijay Mahadevan #include <petscdmmoab.h> 5da6192ceSVijay Mahadevan #include <MBTagConventions.hpp> 6032b8ab6SVijay Mahadevan 7032b8ab6SVijay Mahadevan static PetscErrorCode DMMoab_Compute_NNZ_From_Connectivity(DM,PetscInt*,PetscInt*,PetscInt*,PetscInt*,PetscBool); 8da8c5b52SVijay Mahadevan static PetscErrorCode DMMoab_MatFillMatrixEntries_Private(DM,Mat); 9032b8ab6SVijay Mahadevan 10032b8ab6SVijay Mahadevan #undef __FUNCT__ 11032b8ab6SVijay Mahadevan #define __FUNCT__ "DMCreateMatrix_Moab" 12baf0d1e0SVijay Mahadevan PetscErrorCode DMCreateMatrix_Moab(DM dm,Mat *J) 13032b8ab6SVijay Mahadevan { 14032b8ab6SVijay Mahadevan PetscErrorCode ierr; 15da6192ceSVijay Mahadevan ISLocalToGlobalMapping ltogb; 16da6192ceSVijay Mahadevan PetscInt innz,ionz,nlsiz; 17032b8ab6SVijay Mahadevan DM_Moab *dmmoab=(DM_Moab*)dm->data; 18da6192ceSVijay Mahadevan PetscInt *nnz=0,*onz=0; 19032b8ab6SVijay Mahadevan char *tmp=0; 20baf0d1e0SVijay Mahadevan MatType mtype; 21032b8ab6SVijay Mahadevan 22032b8ab6SVijay Mahadevan PetscFunctionBegin; 23032b8ab6SVijay Mahadevan PetscValidHeaderSpecific(dm,DM_CLASSID,1); 24032b8ab6SVijay Mahadevan PetscValidPointer(J,3); 25032b8ab6SVijay Mahadevan 26db66d124SVijay Mahadevan /* next, need to allocate the non-zero arrays to enable pre-allocation */ 27baf0d1e0SVijay Mahadevan mtype = dm->mattype; 28baf0d1e0SVijay Mahadevan ierr = PetscStrstr(mtype, "baij", &tmp);CHKERRQ(ierr); 29baf0d1e0SVijay Mahadevan nlsiz = (tmp ? dmmoab->nloc:dmmoab->nloc*dmmoab->bs); 30032b8ab6SVijay Mahadevan 31032b8ab6SVijay Mahadevan /* allocate the nnz, onz arrays based on block size and local nodes */ 32da6192ceSVijay Mahadevan ierr = PetscMalloc((nlsiz)*sizeof(PetscInt),&nnz);CHKERRQ(ierr); 33da6192ceSVijay Mahadevan ierr = PetscMemzero(nnz,sizeof(PetscInt)*(nlsiz));CHKERRQ(ierr); 34da6192ceSVijay Mahadevan ierr = PetscMalloc(nlsiz*sizeof(PetscInt),&onz);CHKERRQ(ierr); 35da6192ceSVijay Mahadevan ierr = PetscMemzero(onz,sizeof(PetscInt)*nlsiz);CHKERRQ(ierr); 36032b8ab6SVijay Mahadevan 37032b8ab6SVijay Mahadevan /* compute the nonzero pattern based on MOAB connectivity data for local elements */ 38032b8ab6SVijay Mahadevan ierr = DMMoab_Compute_NNZ_From_Connectivity(dm,&innz,nnz,&ionz,onz,(tmp?PETSC_TRUE:PETSC_FALSE));CHKERRQ(ierr); 39032b8ab6SVijay Mahadevan 40da6192ceSVijay Mahadevan /* create the Matrix and set its type as specified by user */ 41da6192ceSVijay Mahadevan ierr = MatCreate(dmmoab->pcomm->comm(), J);CHKERRQ(ierr); 42addae81cSVijay Mahadevan ierr = MatSetSizes(*J, dmmoab->nloc*dmmoab->numFields, dmmoab->nloc*dmmoab->numFields, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 43032b8ab6SVijay Mahadevan ierr = MatSetBlockSize(*J, dmmoab->bs);CHKERRQ(ierr); 44da6192ceSVijay Mahadevan ierr = MatSetType(*J, mtype);CHKERRQ(ierr); 45da6192ceSVijay Mahadevan ierr = MatSetFromOptions(*J);CHKERRQ(ierr); 46da6192ceSVijay Mahadevan 47da6192ceSVijay Mahadevan if (!dmmoab->ltog_map) SETERRQ(dmmoab->pcomm->comm(), PETSC_ERR_ORDER, "Cannot create a DMMoab Mat without calling DMSetUp first."); 48da6192ceSVijay Mahadevan ierr = MatSetLocalToGlobalMapping(*J,dmmoab->ltog_map,dmmoab->ltog_map);CHKERRQ(ierr); 49da6192ceSVijay Mahadevan ierr = ISLocalToGlobalMappingBlock(dmmoab->ltog_map,dmmoab->bs,<ogb); 50da6192ceSVijay Mahadevan ierr = MatSetLocalToGlobalMappingBlock(*J,ltogb,ltogb);CHKERRQ(ierr); 51da6192ceSVijay Mahadevan ierr = ISLocalToGlobalMappingDestroy(<ogb);CHKERRQ(ierr); 52032b8ab6SVijay Mahadevan 53032b8ab6SVijay Mahadevan /* set preallocation based on different supported Mat types */ 54e23c60ebSVijay Mahadevan ierr = MatSeqAIJSetPreallocation(*J, innz, nnz);CHKERRQ(ierr); 55e23c60ebSVijay Mahadevan ierr = MatMPIAIJSetPreallocation(*J, innz, nnz, ionz, onz);CHKERRQ(ierr); 56032b8ab6SVijay Mahadevan ierr = MatSeqBAIJSetPreallocation(*J, dmmoab->bs, innz, nnz);CHKERRQ(ierr); 57032b8ab6SVijay Mahadevan ierr = MatMPIBAIJSetPreallocation(*J, dmmoab->bs, innz, nnz, ionz, onz);CHKERRQ(ierr); 58032b8ab6SVijay Mahadevan 59da8c5b52SVijay Mahadevan /* clean up temporary memory */ 60032b8ab6SVijay Mahadevan ierr = PetscFree(nnz);CHKERRQ(ierr); 61032b8ab6SVijay Mahadevan ierr = PetscFree(onz);CHKERRQ(ierr); 62da8c5b52SVijay Mahadevan 63da8c5b52SVijay Mahadevan /* set up internal matrix data-structures */ 64da8c5b52SVijay Mahadevan ierr = MatSetUp(*J);CHKERRQ(ierr); 65da8c5b52SVijay Mahadevan 66da8c5b52SVijay Mahadevan /* set DM reference */ 67da8c5b52SVijay Mahadevan ierr = MatSetDM(*J, dm);CHKERRQ(ierr); 68da8c5b52SVijay Mahadevan 69da8c5b52SVijay Mahadevan /* set the correct NNZ pattern by setting matrix entries - make the matrix ready to use */ 70da8c5b52SVijay Mahadevan ierr = DMMoab_MatFillMatrixEntries_Private(dm,*J);CHKERRQ(ierr); 71032b8ab6SVijay Mahadevan PetscFunctionReturn(0); 72032b8ab6SVijay Mahadevan } 73032b8ab6SVijay Mahadevan 74032b8ab6SVijay Mahadevan 75032b8ab6SVijay Mahadevan #undef __FUNCT__ 76032b8ab6SVijay Mahadevan #define __FUNCT__ "DMMoab_Compute_NNZ_From_Connectivity" 77032b8ab6SVijay Mahadevan PetscErrorCode DMMoab_Compute_NNZ_From_Connectivity(DM dm,PetscInt* innz,PetscInt* nnz,PetscInt* ionz,PetscInt* onz,PetscBool isbaij) 78032b8ab6SVijay Mahadevan { 79*5905e1eaSVijay Mahadevan PetscInt i,f,nloc,vpere,bs,ivtx,n_nnz,n_onz; 80*5905e1eaSVijay Mahadevan PetscInt ibs,jbs,inbsize,iobsize,nfields; 81032b8ab6SVijay Mahadevan DM_Moab *dmmoab = (DM_Moab*)dm->data; 82032b8ab6SVijay Mahadevan const moab::EntityHandle *connect; 83da6192ceSVijay Mahadevan moab::Range adjs,found,allvlocal,allvghost; 84da6192ceSVijay Mahadevan moab::Range::iterator iter,jter; 85da6192ceSVijay Mahadevan std::vector<moab::EntityHandle> storage; 86*5905e1eaSVijay Mahadevan PetscBool isinterlaced; 87da6192ceSVijay Mahadevan moab::EntityHandle vtx; 88032b8ab6SVijay Mahadevan moab::ErrorCode merr; 89032b8ab6SVijay Mahadevan 90032b8ab6SVijay Mahadevan PetscFunctionBegin; 91032b8ab6SVijay Mahadevan bs = dmmoab->bs; 92032b8ab6SVijay Mahadevan nloc = dmmoab->nloc; 93*5905e1eaSVijay Mahadevan nfields = dmmoab->numFields; 94*5905e1eaSVijay Mahadevan isinterlaced=(isbaij || bs==nfields ? PETSC_FALSE : PETSC_TRUE); 95032b8ab6SVijay Mahadevan 96da6192ceSVijay Mahadevan /* find the truly user-expected layer of ghosted entities to decipher NNZ pattern */ 97da6192ceSVijay Mahadevan merr = dmmoab->mbiface->get_entities_by_type(dmmoab->fileset,moab::MBVERTEX,allvlocal,true);MBERRNM(merr); 98da6192ceSVijay Mahadevan merr = dmmoab->pcomm->filter_pstatus(allvlocal,PSTATUS_NOT_OWNED,PSTATUS_NOT,-1,&adjs);MBERRNM(merr); 99da6192ceSVijay Mahadevan allvghost = moab::subtract(allvlocal, adjs); 100032b8ab6SVijay Mahadevan 101f6829af0SVijay Mahadevan /* loop over the locally owned vertices and figure out the NNZ pattern using connectivity information */ 102e427d9c9SVijay Mahadevan for(iter = dmmoab->vowned->begin(),ivtx=0; iter != dmmoab->vowned->end(); iter++,ivtx++) { 103032b8ab6SVijay Mahadevan 104da6192ceSVijay Mahadevan vtx = *iter; 105da6192ceSVijay Mahadevan adjs.clear(); 106da6192ceSVijay Mahadevan /* Get adjacency information for current vertex - i.e., all elements of dimension (dim) that connects 107da6192ceSVijay Mahadevan to the current vertex. We can then decipher if a vertex is ghosted or not and compute the 108da6192ceSVijay Mahadevan non-zero pattern accordingly. */ 109da6192ceSVijay Mahadevan merr = dmmoab->mbiface->get_adjacencies(&vtx,1,dmmoab->dim,false,adjs,moab::Interface::INTERSECT); 1100df6e276SVijay Mahadevan 111e427d9c9SVijay Mahadevan /* reset counters */ 112e427d9c9SVijay Mahadevan n_nnz=n_onz=0; 113e427d9c9SVijay Mahadevan found.clear(); 114e427d9c9SVijay Mahadevan 11515de014fSVijay Mahadevan /* loop over vertices and update the number of connectivity */ 11615de014fSVijay Mahadevan for(jter = adjs.begin(); jter != adjs.end(); jter++) { 1170df6e276SVijay Mahadevan 11815de014fSVijay Mahadevan /* Get connectivity information in canonical ordering for the local element */ 11915de014fSVijay Mahadevan merr = dmmoab->mbiface->get_connectivity(*jter,connect,vpere,false,&storage);MBERRNM(merr); 1200df6e276SVijay Mahadevan 121f6829af0SVijay Mahadevan /* loop over each element connected to the adjacent vertex and update as needed */ 12215de014fSVijay Mahadevan for (i=0; i<vpere; ++i) { 123f6829af0SVijay Mahadevan if (connect[i] == vtx || found.find(connect[i]) != found.end()) continue; /* make sure we don't double count shared vertices */ 124f6829af0SVijay Mahadevan if (allvghost.find(connect[i]) != allvghost.end()) n_onz++; /* update out-of-proc onz */ 125f6829af0SVijay Mahadevan else n_nnz++; /* else local vertex */ 12615de014fSVijay Mahadevan found.insert(connect[i]); 12715de014fSVijay Mahadevan } 12815de014fSVijay Mahadevan } 12915de014fSVijay Mahadevan 13015de014fSVijay Mahadevan if (isbaij) { 13115de014fSVijay Mahadevan nnz[ivtx]=n_nnz; /* leave out self to avoid repeats -> node shared by multiple elements */ 132*5905e1eaSVijay Mahadevan if (onz) { 133*5905e1eaSVijay Mahadevan onz[ivtx]=n_onz; /* add ghost non-owned nodes */ 134*5905e1eaSVijay Mahadevan } 13515de014fSVijay Mahadevan } 136f6829af0SVijay Mahadevan else { /* AIJ matrices */ 137*5905e1eaSVijay Mahadevan if (!isinterlaced) { 138*5905e1eaSVijay Mahadevan for (f=0;f<nfields;f++) { 139*5905e1eaSVijay Mahadevan nnz[f*nloc+ivtx]=n_nnz; /* leave out self to avoid repeats -> node shared by multiple elements */ 140*5905e1eaSVijay Mahadevan if (onz) 141*5905e1eaSVijay Mahadevan onz[f*nloc+ivtx]=n_onz; /* add ghost non-owned nodes */ 142*5905e1eaSVijay Mahadevan } 143*5905e1eaSVijay Mahadevan } 144*5905e1eaSVijay Mahadevan else { 145*5905e1eaSVijay Mahadevan for (f=0;f<nfields;f++) { 146*5905e1eaSVijay Mahadevan nnz[nfields*ivtx+f]=n_nnz; /* leave out self to avoid repeats -> node shared by multiple elements */ 147*5905e1eaSVijay Mahadevan if (onz) 148*5905e1eaSVijay Mahadevan onz[nfields*ivtx+f]=n_onz; /* add ghost non-owned nodes */ 149*5905e1eaSVijay Mahadevan } 1500df6e276SVijay Mahadevan } 1510df6e276SVijay Mahadevan } 1520df6e276SVijay Mahadevan } 1530df6e276SVijay Mahadevan 154*5905e1eaSVijay Mahadevan for (i=0;i<nloc*nfields;i++) 155*5905e1eaSVijay Mahadevan nnz[i]+=1; /* self count the node */ 156*5905e1eaSVijay Mahadevan 157*5905e1eaSVijay Mahadevan for (i=0;i<nloc;i++) { 158*5905e1eaSVijay Mahadevan if (!isbaij) { 159*5905e1eaSVijay Mahadevan for (ibs=0; ibs<nfields; ibs++) { 160*5905e1eaSVijay Mahadevan /* first address the diagonal block */ 161*5905e1eaSVijay Mahadevan if (dmmoab->dfill) { 162*5905e1eaSVijay Mahadevan /* just add up the ints -- easier/faster rather than branching based on "1" */ 163*5905e1eaSVijay Mahadevan for (jbs=0,inbsize=0; jbs<nfields; jbs++) 164*5905e1eaSVijay Mahadevan inbsize += dmmoab->dfill[ibs*nfields+jbs]; 165*5905e1eaSVijay Mahadevan } 166*5905e1eaSVijay Mahadevan else inbsize=bs; /* dense coupling since user didn't specify the component fill explicitly */ 167*5905e1eaSVijay Mahadevan if (isinterlaced) nnz[i*nfields+ibs]*=inbsize; 168*5905e1eaSVijay Mahadevan else nnz[ibs*nloc+i]*=inbsize; 169*5905e1eaSVijay Mahadevan 170*5905e1eaSVijay Mahadevan if (onz) { 171*5905e1eaSVijay Mahadevan /* next address the off-diagonal block */ 172*5905e1eaSVijay Mahadevan if (dmmoab->ofill) { 173*5905e1eaSVijay Mahadevan /* just add up the ints -- easier/faster rather than branching based on "1" */ 174*5905e1eaSVijay Mahadevan for (jbs=0,iobsize=0; jbs<nfields; jbs++) 175*5905e1eaSVijay Mahadevan iobsize += dmmoab->dfill[ibs*nfields+jbs]; 176*5905e1eaSVijay Mahadevan } 177*5905e1eaSVijay Mahadevan else iobsize=bs; /* dense coupling since user didn't specify the component fill explicitly */ 178*5905e1eaSVijay Mahadevan if (isinterlaced) onz[i*nfields+ibs]*=iobsize; 179*5905e1eaSVijay Mahadevan else onz[ibs*nloc+i]*=iobsize; 180*5905e1eaSVijay Mahadevan } 181*5905e1eaSVijay Mahadevan } 182*5905e1eaSVijay Mahadevan } 183*5905e1eaSVijay Mahadevan else { 184*5905e1eaSVijay Mahadevan /* check if we got overzealous in our nnz computations */ 185*5905e1eaSVijay Mahadevan nnz[i]=(nnz[i]>dmmoab->nloc ? dmmoab->nloc:nnz[i]); 186*5905e1eaSVijay Mahadevan } 187*5905e1eaSVijay Mahadevan } 188*5905e1eaSVijay Mahadevan /* update innz and ionz based on local maxima */ 189*5905e1eaSVijay Mahadevan if (innz || ionz) { 1900df6e276SVijay Mahadevan if (innz) *innz=0; 1910df6e276SVijay Mahadevan if (ionz) *ionz=0; 192*5905e1eaSVijay Mahadevan for (i=0;i<nloc*nfields;i++) { 193da6192ceSVijay Mahadevan if (innz && (nnz[i]>*innz)) *innz=nnz[i]; 194da6192ceSVijay Mahadevan if ((ionz && onz) && (onz[i]>*ionz)) *ionz=onz[i]; 195032b8ab6SVijay Mahadevan } 196*5905e1eaSVijay Mahadevan } 1970df6e276SVijay Mahadevan PetscFunctionReturn(0); 198032b8ab6SVijay Mahadevan } 199032b8ab6SVijay Mahadevan 200da8c5b52SVijay Mahadevan 201da8c5b52SVijay Mahadevan #undef __FUNCT__ 202da8c5b52SVijay Mahadevan #define __FUNCT__ "DMMoab_MatFillMatrixEntries_Private" 203da8c5b52SVijay Mahadevan PetscErrorCode DMMoab_MatFillMatrixEntries_Private(DM dm, Mat A) 204da8c5b52SVijay Mahadevan { 205da8c5b52SVijay Mahadevan DM_Moab *dmmoab = (DM_Moab*)dm->data; 206da8c5b52SVijay Mahadevan PetscInt nconn = 0,prev_nconn = 0; 207da8c5b52SVijay Mahadevan const moab::EntityHandle *connect; 208da8c5b52SVijay Mahadevan PetscScalar *locala=NULL; 209da8c5b52SVijay Mahadevan PetscInt *dof_indices=NULL; 210da8c5b52SVijay Mahadevan PetscErrorCode ierr; 211da8c5b52SVijay Mahadevan 212da8c5b52SVijay Mahadevan PetscFunctionBegin; 213da8c5b52SVijay Mahadevan /* loop over local elements */ 214da8c5b52SVijay Mahadevan for(moab::Range::iterator iter = dmmoab->elocal->begin(); iter != dmmoab->elocal->end(); iter++) { 215da8c5b52SVijay Mahadevan const moab::EntityHandle ehandle = *iter; 216da8c5b52SVijay Mahadevan 217da8c5b52SVijay Mahadevan /* Get connectivity information: */ 218da8c5b52SVijay Mahadevan ierr = DMMoabGetElementConnectivity(dm, ehandle, &nconn, &connect);CHKERRQ(ierr); 219da8c5b52SVijay Mahadevan 220da8c5b52SVijay Mahadevan /* if we have mixed elements or arrays have not been initialized - Allocate now */ 221da8c5b52SVijay Mahadevan if (prev_nconn != nconn) { 222da8c5b52SVijay Mahadevan if (locala) { 223da8c5b52SVijay Mahadevan ierr = PetscFree(locala);CHKERRQ(ierr); 224da8c5b52SVijay Mahadevan ierr = PetscFree(dof_indices);CHKERRQ(ierr); 225da8c5b52SVijay Mahadevan } 226da8c5b52SVijay Mahadevan ierr = PetscMalloc(sizeof(PetscScalar)*nconn*nconn*dmmoab->numFields*dmmoab->numFields,&locala);CHKERRQ(ierr); 227da8c5b52SVijay Mahadevan ierr = PetscMemzero(locala,sizeof(PetscScalar)*nconn*nconn*dmmoab->numFields*dmmoab->numFields);CHKERRQ(ierr); 228da8c5b52SVijay Mahadevan ierr = PetscMalloc(sizeof(PetscInt)*nconn,&dof_indices);CHKERRQ(ierr); 229da8c5b52SVijay Mahadevan prev_nconn=nconn; 230da8c5b52SVijay Mahadevan } 231da8c5b52SVijay Mahadevan 232da8c5b52SVijay Mahadevan /* get the global DOF number to appropriately set the element contribution in the RHS vector */ 233da8c5b52SVijay Mahadevan ierr = DMMoabGetDofsBlockedLocal(dm, nconn, connect, dof_indices);CHKERRQ(ierr); 234da8c5b52SVijay Mahadevan 235da8c5b52SVijay Mahadevan /* set the values directly into appropriate locations. Can alternately use VecSetValues */ 236da8c5b52SVijay Mahadevan ierr = MatSetValuesBlockedLocal(A, nconn, dof_indices, nconn, dof_indices, locala, INSERT_VALUES);CHKERRQ(ierr); 237da8c5b52SVijay Mahadevan } 238da8c5b52SVijay Mahadevan 239da8c5b52SVijay Mahadevan /* clean up memory */ 240da8c5b52SVijay Mahadevan ierr = PetscFree(locala);CHKERRQ(ierr); 241da8c5b52SVijay Mahadevan ierr = PetscFree(dof_indices);CHKERRQ(ierr); 242da8c5b52SVijay Mahadevan 243da8c5b52SVijay Mahadevan /* finish assembly */ 244da8c5b52SVijay Mahadevan ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 245da8c5b52SVijay Mahadevan ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 246da8c5b52SVijay Mahadevan PetscFunctionReturn(0); 247da8c5b52SVijay Mahadevan } 248da8c5b52SVijay Mahadevan 249*5905e1eaSVijay Mahadevan 250*5905e1eaSVijay Mahadevan #undef __FUNCT__ 251*5905e1eaSVijay Mahadevan #define __FUNCT__ "DMMoabSetBlockFills_Private" 252*5905e1eaSVijay Mahadevan static PetscErrorCode DMMoabSetBlockFills_Private(PetscInt w,const PetscInt *fill,PetscInt **rfill) 253*5905e1eaSVijay Mahadevan { 254*5905e1eaSVijay Mahadevan PetscErrorCode ierr; 255*5905e1eaSVijay Mahadevan PetscInt i,j,*ifill; 256*5905e1eaSVijay Mahadevan 257*5905e1eaSVijay Mahadevan PetscFunctionBegin; 258*5905e1eaSVijay Mahadevan if (!fill) PetscFunctionReturn(0); 259*5905e1eaSVijay Mahadevan ierr = PetscMalloc1(w*w,&ifill);CHKERRQ(ierr); 260*5905e1eaSVijay Mahadevan for (i=0;i<w;i++) { 261*5905e1eaSVijay Mahadevan for (j=0; j<w; j++) 262*5905e1eaSVijay Mahadevan ifill[i*w+j]=fill[i*w+j]; 263*5905e1eaSVijay Mahadevan } 264*5905e1eaSVijay Mahadevan 265*5905e1eaSVijay Mahadevan *rfill = ifill; 266*5905e1eaSVijay Mahadevan PetscFunctionReturn(0); 267*5905e1eaSVijay Mahadevan } 268*5905e1eaSVijay Mahadevan 269*5905e1eaSVijay Mahadevan 270*5905e1eaSVijay Mahadevan #undef __FUNCT__ 271*5905e1eaSVijay Mahadevan #define __FUNCT__ "DMMoabSetBlockFills" 272*5905e1eaSVijay Mahadevan /*@ 273*5905e1eaSVijay Mahadevan DMMoabSetBlockFills - Sets the fill pattern in each block for a multi-component problem 274*5905e1eaSVijay Mahadevan of the matrix returned by DMCreateMatrix(). 275*5905e1eaSVijay Mahadevan 276*5905e1eaSVijay Mahadevan Logically Collective on DMDA 277*5905e1eaSVijay Mahadevan 278*5905e1eaSVijay Mahadevan Input Parameter: 279*5905e1eaSVijay Mahadevan + dm - the DMMoab object 280*5905e1eaSVijay Mahadevan . dfill - the fill pattern in the diagonal block (may be NULL, means use dense block) 281*5905e1eaSVijay Mahadevan - ofill - the fill pattern in the off-diagonal blocks 282*5905e1eaSVijay Mahadevan 283*5905e1eaSVijay Mahadevan Level: developer 284*5905e1eaSVijay Mahadevan 285*5905e1eaSVijay Mahadevan Notes: This only makes sense when you are doing multicomponent problems but using the 286*5905e1eaSVijay Mahadevan MPIAIJ matrix format 287*5905e1eaSVijay Mahadevan 288*5905e1eaSVijay Mahadevan The format for dfill and ofill is a 2 dimensional dof by dof matrix with 1 entries 289*5905e1eaSVijay Mahadevan representing coupling and 0 entries for missing coupling. For example 290*5905e1eaSVijay Mahadevan $ dfill[9] = {1, 0, 0, 291*5905e1eaSVijay Mahadevan $ 1, 1, 0, 292*5905e1eaSVijay Mahadevan $ 0, 1, 1} 293*5905e1eaSVijay Mahadevan means that row 0 is coupled with only itself in the diagonal block, row 1 is coupled with 294*5905e1eaSVijay Mahadevan itself and row 0 (in the diagonal block) and row 2 is coupled with itself and row 1 (in the 295*5905e1eaSVijay Mahadevan diagonal block). 296*5905e1eaSVijay Mahadevan 297*5905e1eaSVijay Mahadevan DMDASetGetMatrix() allows you to provide general code for those more complicated nonzero patterns then 298*5905e1eaSVijay Mahadevan can be represented in the dfill, ofill format 299*5905e1eaSVijay Mahadevan 300*5905e1eaSVijay Mahadevan Contributed by Glenn Hammond 301*5905e1eaSVijay Mahadevan 302*5905e1eaSVijay Mahadevan .seealso DMCreateMatrix(), DMDASetGetMatrix(), DMSetMatrixPreallocateOnly() 303*5905e1eaSVijay Mahadevan 304*5905e1eaSVijay Mahadevan @*/ 305*5905e1eaSVijay Mahadevan PetscErrorCode DMMoabSetBlockFills(DM dm,const PetscInt *dfill,const PetscInt *ofill) 306*5905e1eaSVijay Mahadevan { 307*5905e1eaSVijay Mahadevan DM_Moab *dmmoab=(DM_Moab*)dm->data; 308*5905e1eaSVijay Mahadevan PetscErrorCode ierr; 309*5905e1eaSVijay Mahadevan 310*5905e1eaSVijay Mahadevan PetscFunctionBegin; 311*5905e1eaSVijay Mahadevan PetscValidHeaderSpecific(dm,DM_CLASSID,1); 312*5905e1eaSVijay Mahadevan ierr = DMMoabSetBlockFills_Private(dmmoab->numFields,dfill,&dmmoab->dfill);CHKERRQ(ierr); 313*5905e1eaSVijay Mahadevan ierr = DMMoabSetBlockFills_Private(dmmoab->numFields,ofill,&dmmoab->ofill);CHKERRQ(ierr); 314*5905e1eaSVijay Mahadevan PetscFunctionReturn(0); 315*5905e1eaSVijay Mahadevan } 316