xref: /petsc/src/dm/impls/moab/dmmbmg.cxx (revision ce27a4eedb575ea8fca2ab34774e5199472b2ffd)
1 #include <petsc-private/dmmbimpl.h> /*I  "petscdmmoab.h"   I*/
2 
3 #include <petscdmmoab.h>
4 #include <MBTagConventions.hpp>
5 #include <moab/NestedRefine.hpp>
6 
7 #undef __FUNCT__
8 #define __FUNCT__ "DMMoabGenerateHierarchy"
9 /*@
10   DMMoabGenerateHierarchy - Generate a multi-level uniform refinement hierarchy
11   by succesively refining a coarse mesh, already defined in the DM object
12   provided by the user.
13 
14   Collective on MPI_Comm
15 
16   Input Parameter:
17 + dmb  - The DMMoab object
18 
19   Output Parameter:
20 + nlevels   - The number of levels of refinement needed to generate the hierarchy
21 . ldegrees  - The degree of refinement at each level in the hierarchy
22 
23   Level: beginner
24 
25 .keywords: DMMoab, create, refinement
26 @*/
27 PetscErrorCode DMMoabGenerateHierarchy(DM dm,PetscInt nlevels,PetscInt *ldegrees)
28 {
29   DM_Moab        *dmmoab;
30   PetscErrorCode  ierr;
31   moab::ErrorCode merr;
32   PetscInt *pdegrees,i;
33   std::vector<moab::EntityHandle> hsets;
34 
35   PetscFunctionBegin;
36   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
37   dmmoab = (DM_Moab*)(dm)->data;
38 
39   if (!ldegrees) {
40     ierr = PetscMalloc1(nlevels,&pdegrees);CHKERRQ(ierr);
41     for (i=0; i<nlevels; i++) pdegrees[i]=2; /* default = Degree 2 refinement */
42   }
43   else pdegrees=ldegrees;
44 
45   /* initialize set level refinement data for hierarchy */
46   dmmoab->nhlevels=nlevels;
47 
48   /* Instantiate the nested refinement class */
49   dmmoab->hierarchy = new moab::NestedRefine(dynamic_cast<moab::Core*>(dmmoab->mbiface), dmmoab->pcomm, dmmoab->fileset);
50 
51   ierr = PetscMalloc1(nlevels+1,&dmmoab->hsets);CHKERRQ(ierr);
52 
53   /* generate the mesh hierarchy */
54   merr = dmmoab->hierarchy->generate_mesh_hierarchy(pdegrees, nlevels, hsets);MBERRNM(merr);
55 
56   for (i=0; i<=nlevels; i++) dmmoab->hsets[i]=hsets[i];
57 
58   if (!ldegrees) {
59     ierr = PetscFree(pdegrees);CHKERRQ(ierr);
60   }
61   PetscFunctionReturn(0);
62 }
63 
64 #undef __FUNCT__
65 #define __FUNCT__ "DMRefineHierarchy_Moab"
66 /*@
67   DMRefineHierarchy_Moab - Generate a multi-level DM hierarchy
68   by succesively refining a coarse mesh.
69 
70   Collective on MPI_Comm
71 
72   Input Parameter:
73 + dm  - The DMMoab object
74 
75   Output Parameter:
76 + nlevels   - The number of levels of refinement needed to generate the hierarchy
77 . dmf  - The DM objects after successive refinement of the hierarchy
78 
79   Level: beginner
80 
81 .keywords: DMMoab, generate, refinement
82 @*/
83 PetscErrorCode  DMRefineHierarchy_Moab(DM dm,PetscInt nlevels,DM dmf[])
84 {
85   PetscErrorCode  ierr;
86   PetscInt        i;
87 
88   PetscFunctionBegin;
89 
90   ierr = DMRefine(dm,PetscObjectComm((PetscObject)dm),&dmf[0]);CHKERRQ(ierr);
91   for (i=1; i<nlevels; i++) {
92     ierr = DMRefine(dmf[i-1],PetscObjectComm((PetscObject)dm),&dmf[i]);CHKERRQ(ierr);
93   }
94   PetscFunctionReturn(0);
95 }
96 
97 #undef __FUNCT__
98 #define __FUNCT__ "DMCoarsenHierarchy_Moab"
99 /*@
100   DMCoarsenHierarchy_Moab - Generate a multi-level DM hierarchy
101   by succesively coarsening a refined mesh.
102 
103   Collective on MPI_Comm
104 
105   Input Parameter:
106 + dm  - The DMMoab object
107 
108   Output Parameter:
109 + nlevels   - The number of levels of refinement needed to generate the hierarchy
110 . dmc  - The DM objects after successive coarsening of the hierarchy
111 
112   Level: beginner
113 
114 .keywords: DMMoab, generate, coarsening
115 @*/
116 PetscErrorCode DMCoarsenHierarchy_Moab(DM dm,PetscInt nlevels,DM dmc[])
117 {
118   PetscErrorCode  ierr;
119   PetscInt        i;
120 
121   PetscFunctionBegin;
122 
123   ierr = DMCoarsen(dm,PetscObjectComm((PetscObject)dm),&dmc[0]);CHKERRQ(ierr);
124   for (i=1; i<nlevels; i++) {
125     ierr = DMCoarsen(dmc[i-1],PetscObjectComm((PetscObject)dm),&dmc[i]);CHKERRQ(ierr);
126   }
127   PetscFunctionReturn(0);
128 }
129 
130 
131 #undef __FUNCT__
132 #define __FUNCT__ "DMCreateInterpolation_Moab"
133 /*@
134   DMCreateInterpolation_Moab - Generate the interpolation operators to transform
135   operators (matrices, vectors) from parent level to child level as defined by
136   the DM inputs provided by the user.
137 
138   Collective on MPI_Comm
139 
140   Input Parameter:
141 + dm1  - The DMMoab object
142 - dm2  - the second, finer DMMoab object
143 
144   Output Parameter:
145 + interpl  - The interpolation operator for transferring data between the levels
146 - vec      - The scaling vector (optional)
147 
148   Level: developer
149 
150 .keywords: DMMoab, create, refinement
151 @*/
152 PetscErrorCode DMCreateInterpolation_Moab(DM dm1,DM dm2,Mat* interpl,Vec* vec)
153 {
154   DM_Moab         *dmb1, *dmb2;
155   PetscErrorCode   ierr;
156   moab::ErrorCode  merr;
157   PetscInt         dim;
158   PetscReal        factor;
159   PetscBool        eonbnd;
160   PetscInt         innz, *nnz, ionz, *onz;
161   PetscInt         nlsiz1, nlsiz2, ngsiz1, ngsiz2;
162   std::vector<int> bndrows;
163   std::vector<PetscBool> dbdry;
164 
165   PetscFunctionBegin;
166   PetscValidHeaderSpecific(dm1,DM_CLASSID,1);
167   PetscValidHeaderSpecific(dm2,DM_CLASSID,2);
168   dmb1 = (DM_Moab*)(dm1)->data;
169   dmb2 = (DM_Moab*)(dm2)->data;
170   nlsiz1 = dmb1->nloc*dmb2->numFields;
171   nlsiz2 = dmb2->nloc*dmb2->numFields;
172   ngsiz1 = dmb1->n*dmb2->numFields;
173   ngsiz2 = dmb2->n*dmb2->numFields;
174 
175   PetscInfo4(dm1,"Creating interpolation matrix %D X %D to apply transformation between levels %D -> %D.\n",dmb1->nloc,dmb2->nloc,dmb1->hlevel,dmb2->hlevel);
176 
177   ierr = MatCreate(PetscObjectComm((PetscObject)dm1), interpl);CHKERRQ(ierr);
178   ierr = MatSetType(*interpl, dm1->mattype);CHKERRQ(ierr);
179   ierr = MatSetSizes(*interpl, nlsiz2, nlsiz1, ngsiz2, ngsiz1);CHKERRQ(ierr);
180 
181   /* TODO: This is a hack for the rectangular system - decipher NNZ pattern better */
182   ierr = MatSetFromOptions(*interpl);CHKERRQ(ierr);
183 
184   /* allocate the nnz, onz arrays based on block size and local nodes */
185   ierr = PetscCalloc2(nlsiz2,&nnz,nlsiz2,&onz);CHKERRQ(ierr);
186 
187   /* Loop through the local elements and compute the relation between the current parent and the refined_level. */
188   for(moab::Range::iterator iter = dmb1->elocal->begin(); iter!= dmb1->elocal->end(); iter++) {
189 
190     const moab::EntityHandle ehandle = *iter;
191     std::vector<moab::EntityHandle> children;
192     std::vector<moab::EntityHandle> connp, connc;
193 
194     /* Get the relation between the current (coarse) parent and its corresponding (finer) children elements */
195     merr = dmb1->hierarchy->parent_to_child(ehandle, dmb1->hlevel, dmb2->hlevel, children);MBERRNM(merr);
196 
197     /* Get connectivity and coordinates of the parent vertices */
198     merr = dmb1->hierarchy->get_connectivity(ehandle, dmb1->hlevel, connp);MBERRNM(merr);
199     for (unsigned ic=0; ic < children.size(); ic++) {
200       std::vector<moab::EntityHandle> tconnc;
201       /* Get coordinates of the parent vertices in canonical order */
202       merr = dmb2->hierarchy->get_connectivity(children[ic], dmb2->hlevel, tconnc);MBERRNM(merr);
203       for (unsigned tc=0; tc<tconnc.size(); tc++) {
204         if (std::find(connc.begin(), connc.end(), tconnc[tc]) == connc.end())
205           connc.push_back(tconnc[tc]);
206       }
207     }
208 
209     std::vector<int> dofsp(connp.size()), dofsc(connc.size());
210     /* TODO: specific to scalar system - use GetDofs */
211     //ierr = DMMoabGetFieldDofs(dm1, connp.size(), &connp[0], 0, &dofsp[0]);CHKERRQ(ierr);
212     ierr = DMMoabGetFieldDofs(dm2, connc.size(), &connc[0], 0, &dofsc[0]);CHKERRQ(ierr);
213 
214     for (unsigned tp=0;tp<connp.size(); tp++) {
215       // ierr = MatSetValues(*interpl, connc.size(), &dofsc[0], 1, &dofsp[i], &values_phi[0], ADD_VALUES);CHKERRQ(ierr);
216       if (dmb1->vowned->find(connp[tp]) != dmb1->vowned->end()) {
217         for (unsigned tc=0;tc<connc.size(); tc++) nnz[dofsc[tc]]++;
218       }
219       else if (dmb1->vghost->find(connp[tp]) != dmb1->vghost->end()) {
220         for (unsigned tc=0;tc<connc.size(); tc++) onz[dofsc[tc]]++;
221       }
222       else SETERRQ1(PETSC_COMM_WORLD,PETSC_ERR_ARG_OUTOFRANGE,"Invalid entity in parent level %D\n", connc[tp]);
223     }
224     /*
225     for(int tc = 0; tc < connc.size(); tc++) {
226       if (dmb2->vowned->find(connc[tc]) != dmb2->vowned->end()) nnz[dofsc[tc]]++;
227       else if (dmb2->vghost->find(connc[tc]) != dmb2->vghost->end()) onz[dofsc[tc]]++;
228       else SETERRQ1(PETSC_COMM_WORLD,PETSC_ERR_ARG_OUTOFRANGE,"Invalid entity in child level %D\n", connc[tc]);
229     }*/
230   }
231 
232   int i=0;
233   std::vector<moab::EntityHandle> adjs;
234   for(moab::Range::iterator iter = dmb1->vowned->begin(); iter!= dmb1->vowned->end(); iter++, i++) {
235     merr = dmb1->hierarchy->get_adjacencies(*iter, 0, adjs);MBERRNM(merr);
236     nnz[i] -= adjs.size();
237     adjs.clear();
238   }
239   for(moab::Range::iterator iter = dmb1->vowned->begin(); iter!= dmb1->vowned->end(); iter++, i++) {
240     //merr = dmb1->hierarchy->get_adjacencies(&(*iter), 1, 0, false, adjs, moab::Interface::UNION);MBERRNM(merr);
241     merr = dmb1->hierarchy->get_adjacencies(*iter, 0, adjs);MBERRNM(merr);
242     onz[i] -= adjs.size();
243     adjs.clear();
244   }
245 
246   ionz=onz[0];
247   innz=nnz[0];
248   for (int tc=0; tc < nlsiz2; tc++) {
249     // check for maximum allowed sparsity = fully dense
250     nnz[tc] = std::min(nlsiz1,nnz[tc]);
251     onz[tc] = std::min(nlsiz1,onz[tc]);
252 
253     innz = (innz < nnz[tc] ? nnz[tc] : innz);
254     ionz = (ionz < onz[tc] ? onz[tc] : ionz);
255     //PetscPrintf(PETSC_COMM_SELF, "[%D] NNZ = %D, ONZ = %D\n", tc, nnz[tc], onz[tc]);
256   }
257   //PetscPrintf(PETSC_COMM_SELF, "Final: INNZ = %D, IONZ = %D\n", innz, ionz);
258 
259   ierr = MatSeqAIJSetPreallocation(*interpl,innz,nnz);CHKERRQ(ierr);
260   ierr = MatMPIAIJSetPreallocation(*interpl,innz,nnz,ionz,onz);CHKERRQ(ierr);
261 
262   /* clean up temporary memory */
263   ierr = PetscFree2(nnz,onz);CHKERRQ(ierr);
264 
265   /* set up internal matrix data-structures */
266   ierr = MatSetUp(*interpl);CHKERRQ(ierr);
267   ierr = MatZeroEntries(*interpl);CHKERRQ(ierr);
268 
269   ierr = DMGetDimension(dm1, &dim);CHKERRQ(ierr);
270 
271   factor = std::pow(2.0 /*degree_P_for_refinement*/,(dmb2->hlevel-dmb1->hlevel)*dmb1->dim*1.0);
272 
273   /* Loop through the remaining vertices. These vertices appear only on the current refined_level. */
274   for(moab::Range::iterator iter = dmb1->elocal->begin(); iter!= dmb1->elocal->end(); iter++) {
275 
276     const moab::EntityHandle ehandle = *iter;
277     std::vector<moab::EntityHandle> children;
278     std::vector<moab::EntityHandle> connp, connc;
279 
280     /* Get the relation between the current (coarse) parent and its corresponding (finer) children elements */
281     merr = dmb1->hierarchy->parent_to_child(ehandle, dmb1->hlevel, dmb2->hlevel, children);MBERRNM(merr);
282 
283     /* Get connectivity and coordinates of the parent vertices */
284     merr = dmb1->hierarchy->get_connectivity(ehandle, dmb1->hlevel, connp);MBERRNM(merr);
285     for (unsigned ic=0; ic < children.size(); ic++) {
286       std::vector<moab::EntityHandle> tconnc;
287       /* Get coordinates of the parent vertices in canonical order */
288       merr = dmb1->hierarchy->get_connectivity(children[ic], dmb2->hlevel, tconnc);MBERRNM(merr);
289       for (unsigned tc=0; tc<tconnc.size(); tc++) {
290         connc.push_back(tconnc[tc]);
291       }
292     }
293 
294     std::vector<double> pcoords(connp.size()*3), ccoords(connc.size()*3), values_phi(connc.size());
295     /* Get coordinates for connectivity entities in canonical order for both coarse and finer levels */
296     merr = dmb1->hierarchy->get_coordinates(&connp[0], connp.size(), dmb1->hlevel, &pcoords[0]);MBERRNM(merr);
297     merr = dmb2->hierarchy->get_coordinates(&connc[0], connc.size(), dmb2->hlevel, &ccoords[0]);MBERRNM(merr);
298 
299     std::vector<int> dofsp(connp.size()), dofsc(connc.size());
300     /* TODO: specific to scalar system - use GetDofs */
301     ierr = DMMoabGetFieldDofs(dm1, connp.size(), &connp[0], 0, &dofsp[0]);CHKERRQ(ierr);
302     ierr = DMMoabGetFieldDofs(dm2, connc.size(), &connc[0], 0, &dofsc[0]);CHKERRQ(ierr);
303 
304     /* Compute the interpolation weights by determining distance of 1-ring
305        neighbor vertices from current vertex */
306     for (unsigned i=0;i<connp.size(); i++) {
307       double normsum=0.0;
308       for (unsigned j=0;j<connc.size(); j++) {
309         values_phi[j] = 0.0;
310         for (unsigned k=0;k<3; k++)
311           values_phi[j] += std::pow(pcoords[i*3+k]-ccoords[k+j*3], dim);
312         if (values_phi[j] < 1e-12) {
313           values_phi[j] = 1e12;
314         }
315         else {
316           //values_phi[j] = std::pow(values_phi[j], -1.0/dim);
317           values_phi[j] = std::pow(values_phi[j], -1.0);
318           normsum += values_phi[j];
319         }
320       }
321       for (unsigned j=0;j<connc.size(); j++) {
322         if (values_phi[j] > 1e11)
323           values_phi[j] = factor*0.5/connc.size();
324         else
325           values_phi[j] = factor*values_phi[j]*0.5/(connc.size()*normsum);
326       }
327       ierr = MatSetValues(*interpl, connc.size(), &dofsc[0], 1, &dofsp[i], &values_phi[0], ADD_VALUES);CHKERRQ(ierr);
328     }
329 
330     /* check if element is on the boundary */
331     //ierr = DMMoabIsEntityOnBoundary(dm1,ehandle,&eonbnd);CHKERRQ(ierr);
332     dbdry.resize(connc.size());
333     ierr = DMMoabCheckBoundaryVertices(dm2,connc.size(),&connc[0],dbdry.data());CHKERRQ(ierr);
334     eonbnd=PETSC_FALSE;
335     for (unsigned i=0; i< connc.size(); ++i)
336       if (dbdry[i]) eonbnd=PETSC_TRUE;
337 
338     values_phi.clear();
339     values_phi.resize(connp.size());
340     /* apply dirichlet boundary conditions */
341     if (eonbnd) {
342 
343       ierr = MatAssemblyBegin(*interpl,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr);
344       ierr = MatAssemblyEnd(*interpl,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr);
345       /* get the list of nodes on boundary so that we can enforce dirichlet conditions strongly */
346       //ierr = DMMoabCheckBoundaryVertices(dm2,connc.size(),&connc[0],dbdry);CHKERRQ(ierr);
347       for (unsigned i=0; i < connc.size(); i++) {
348         if (dbdry[i]) {  /* dirichlet node */
349           /* think about strongly imposing dirichlet */
350           //bndrows.push_back(dofsc[i]);
351 
352           ierr = MatSetValues(*interpl, 1, &dofsc[i], connp.size(), &dofsp[0], &values_phi[0], INSERT_VALUES);CHKERRQ(ierr);
353           //values_phi[0]=1.0;
354           //ierr = MatSetValues(*interpl, 1, &dofsc[i], 1, &dofsc[i], &values_phi[0], INSERT_VALUES);CHKERRQ(ierr);
355         }
356       }
357 
358       ierr = MatAssemblyBegin(*interpl,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr);
359       ierr = MatAssemblyEnd(*interpl,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr);
360     }
361 
362     //get interpolation weights
363     //ierr = Compute_Quad4_Basis(pcoords, 1, coord, values_phi);CHKERRQ(ierr);
364     // for (int j=0;j<dofs_per_element; j++)
365     //  std::cout<<"values "<<values_phi[j]<<std::endl;
366 
367     //get row and column indices, zero weights are ignored
368     /*
369     int nz_ind = 0;
370     idx = dmb2->vowned->index(vhandle);
371     for (int j=0;j<dofs_per_element; j++){
372       idy[nz_ind] = dmb1->vowned->index(connectivity[j]);
373       PetscPrintf(PETSC_COMM_WORLD, "Finding coarse connectivity vertex %D associated with [%D, %D] - set to %D\n", connectivity[j], parent.size(), vhandle, idy[nz_ind]);
374       //values_phi[nz_ind] = values_phi[j];
375       nz_ind = nz_ind+1;
376     }
377     */
378 
379     //ierr = MatSetValues(*interpl, nz_ind, idy, 1, &idx, values_phi, INSERT_VALUES);CHKERRQ(ierr);
380     //ierr = MatSetValues(*interpl, connp.size(), dofsp, connc.size(), dofsc, &values_phi[0], INSERT_VALUES);CHKERRQ(ierr);
381   }
382 
383   //PetscPrintf(PETSC_COMM_WORLD, "[Boundary vertices = %D] :: A few: %D %D %D %D \n", bndrows.size(), bndrows[0], bndrows[1], bndrows[2], bndrows[3]);
384   //ierr = MatZeroRows(*interpl, bndrows.size(), &bndrows[0], 1.0, 0, 0);CHKERRQ(ierr);
385 
386   ierr = MatAssemblyBegin(*interpl,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
387   ierr = MatAssemblyEnd(*interpl,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
388   PetscFunctionReturn(0);
389 }
390 
391 #undef __FUNCT__
392 #define __FUNCT__ "DMCreateInjection_Moab"
393 /*@
394   DMCreateInjection_Moab - Generate a multi-level uniform refinement hierarchy
395   by succesively refining a coarse mesh, already defined in the DM object
396   provided by the user.
397 
398   Collective on MPI_Comm
399 
400   Input Parameter:
401 . dmb  - The DMMoab object
402 
403   Output Parameter:
404 . nlevels   - The number of levels of refinement needed to generate the hierarchy
405 + ldegrees  - The degree of refinement at each level in the hierarchy
406 
407   Level: beginner
408 
409 .keywords: DMMoab, create, refinement
410 @*/
411 PetscErrorCode DMCreateInjection_Moab(DM dm1,DM dm2,VecScatter* ctx)
412 {
413   //DM_Moab        *dmmoab;
414 
415   PetscFunctionBegin;
416   PetscValidHeaderSpecific(dm1,DM_CLASSID,1);
417   PetscValidHeaderSpecific(dm2,DM_CLASSID,2);
418   //dmmoab = (DM_Moab*)(dm1)->data;
419 
420   PetscPrintf(PETSC_COMM_WORLD, "[DMCreateInjection_Moab] :: Placeholder\n");
421   PetscFunctionReturn(0);
422 }
423 
424 
425 #undef __FUNCT__
426 #define __FUNCT__ "DM_UMR_Moab_Private"
427 PetscErrorCode  DM_UMR_Moab_Private(DM dm,MPI_Comm comm,PetscBool refine,DM *dmref)
428 {
429   PetscErrorCode  ierr;
430   PetscInt        i,dim;
431   DM              dm2;
432   moab::ErrorCode merr;
433   DM_Moab        *dmb = (DM_Moab*)dm->data,*dd2;
434 
435   PetscFunctionBegin;
436   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
437   PetscValidPointer(dmref,4);
438 
439   if ( (dmb->hlevel == dmb->nhlevels && refine) || (dmb->hlevel == 0 && !refine) ) {
440     if (dmb->hlevel+1 > dmb->nhlevels && refine) PetscInfo2(NULL,"Invalid multigrid refinement hierarchy level specified (%D). MOAB UMR max levels = %D. Creating a NULL object.\n",dmb->hlevel+1,dmb->nhlevels);
441     if (dmb->hlevel-1 < 0 && !refine) PetscInfo1(NULL,"Invalid multigrid coarsen hierarchy level specified (%D). Creating a NULL object.\n",dmb->hlevel-1);
442     *dmref = PETSC_NULL;
443     PetscFunctionReturn(0);
444   }
445 
446   ierr = DMMoabCreate(PetscObjectComm((PetscObject)dm), &dm2);CHKERRQ(ierr);
447   dd2 = (DM_Moab*)dm2->data;
448 
449   dd2->mbiface = dmb->mbiface;
450   dd2->pcomm = dmb->pcomm;
451   dd2->icreatedinstance = PETSC_FALSE;
452 
453   /* set the new level based on refinement/coarsening */
454   if (refine) {
455     dd2->hlevel=dmb->hlevel+1;
456   }
457   else {
458     dd2->hlevel=dmb->hlevel-1;
459   }
460 
461   /* Copy the multilevel hierarchy pointers in MOAB */
462   dd2->hierarchy = dmb->hierarchy;
463   dd2->nhlevels = dmb->nhlevels;
464   ierr = PetscMalloc1(dd2->nhlevels+1,&dd2->hsets);CHKERRQ(ierr);
465   for (i=0; i<=dd2->nhlevels; i++) {
466     dd2->hsets[i]=dmb->hsets[i];
467   }
468   dd2->fileset = dd2->hsets[dd2->hlevel];
469 
470   /* do the remaining initializations for DMMoab */
471   dd2->bs = dmb->bs;
472   dd2->numFields = dmb->numFields;
473   dd2->rw_dbglevel = dmb->rw_dbglevel;
474   dd2->partition_by_rank = dmb->partition_by_rank;
475   ierr = PetscStrcpy(dd2->extra_read_options, dmb->extra_read_options);CHKERRQ(ierr);
476   ierr = PetscStrcpy(dd2->extra_write_options, dmb->extra_write_options);CHKERRQ(ierr);
477   dd2->read_mode = dmb->read_mode;
478   dd2->write_mode = dmb->write_mode;
479 
480   /* set global ID tag handle */
481   ierr = DMMoabSetLocalToGlobalTag(dm2, dmb->ltog_tag);CHKERRQ(ierr);
482 
483   merr = dd2->mbiface->tag_get_handle(MATERIAL_SET_TAG_NAME, dd2->material_tag);MBERRNM(merr);
484 
485   ierr = DMSetOptionsPrefix(dm2,((PetscObject)dm)->prefix);CHKERRQ(ierr);
486   ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
487   ierr = DMSetDimension(dm2,dim);CHKERRQ(ierr);
488 
489   /* allow overloaded (user replaced) operations to be inherited by refinement clones */
490   dm2->ops->creatematrix = dm->ops->creatematrix;
491 
492   /* copy fill information if given */
493   ierr = DMMoabSetBlockFills(dm2, dmb->dfill, dmb->ofill);CHKERRQ(ierr);
494 
495   /* copy vector type information */
496   ierr = DMSetMatType(dm2,dm->mattype);CHKERRQ(ierr);
497   ierr = DMSetVecType(dm2,dm->vectype);CHKERRQ(ierr);
498   dd2->numFields = dmb->numFields;
499   if (dmb->numFields) {
500     ierr = DMMoabSetFieldNames(dm2,dmb->numFields,dmb->fieldNames);CHKERRQ(ierr);
501   }
502 
503   ierr = DMSetFromOptions(dm2);CHKERRQ(ierr);
504 
505   /* recreate Dof numbering for the refined DM and make sure the distribution is correctly populated */
506   ierr = DMSetUp(dm2);CHKERRQ(ierr);
507 
508   *dmref = dm2;
509   PetscFunctionReturn(0);
510 }
511 
512 
513 #undef __FUNCT__
514 #define __FUNCT__ "DMRefine_Moab"
515 /*@
516   DMRefine_Moab - Generate a multi-level uniform refinement hierarchy
517   by succesively refining a coarse mesh, already defined in the DM object
518   provided by the user.
519 
520   Collective on DM
521 
522   Input Parameter:
523 + dm  - The DMMoab object
524 - comm - the communicator to contain the new DM object (or MPI_COMM_NULL)
525 
526   Output Parameter:
527 . dmf - the refined DM, or NULL
528 
529   Note: If no refinement was done, the return value is NULL
530 
531   Level: developer
532 
533 .keywords: DMMoab, create, refinement
534 @*/
535 PetscErrorCode DMRefine_Moab(DM dm,MPI_Comm comm,DM* dmf)
536 {
537   PetscErrorCode  ierr;
538 
539   PetscFunctionBegin;
540   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
541 
542   ierr = DM_UMR_Moab_Private(dm,comm,PETSC_TRUE,dmf);CHKERRQ(ierr);
543   PetscFunctionReturn(0);
544 }
545 
546 #undef __FUNCT__
547 #define __FUNCT__ "DMCoarsen_Moab"
548 /*@
549   DMCoarsen_Moab - Generate a multi-level uniform refinement hierarchy
550   by succesively refining a coarse mesh, already defined in the DM object
551   provided by the user.
552 
553   Collective on DM
554 
555   Input Parameter:
556 . dm  - The DMMoab object
557 - comm - the communicator to contain the new DM object (or MPI_COMM_NULL)
558 
559   Output Parameter:
560 . dmf - the coarsened DM, or NULL
561 
562   Note: If no coarsening was done, the return value is NULL
563 
564   Level: developer
565 
566 .keywords: DMMoab, create, coarsening
567 @*/
568 PetscErrorCode DMCoarsen_Moab(DM dm,MPI_Comm comm,DM* dmc)
569 {
570   PetscErrorCode  ierr;
571 
572   PetscFunctionBegin;
573   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
574 
575   ierr = DM_UMR_Moab_Private(dm,comm,PETSC_FALSE,dmc);CHKERRQ(ierr);
576   PetscFunctionReturn(0);
577 }
578