xref: /petsc/src/dm/impls/moab/dmmbmat.cxx (revision 5905e1ea7a311b87a8e67e52661a33e29129abab)
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,&ltogb);
50da6192ceSVijay Mahadevan   ierr = MatSetLocalToGlobalMappingBlock(*J,ltogb,ltogb);CHKERRQ(ierr);
51da6192ceSVijay Mahadevan   ierr = ISLocalToGlobalMappingDestroy(&ltogb);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