1755f3dfbSVijay Mahadevan #include <petsc/private/dmmbimpl.h> 2b117cd09SVijay Mahadevan #include <petscdmmoab.h> 3b117cd09SVijay Mahadevan #include <MBTagConventions.hpp> 4b117cd09SVijay Mahadevan #include <moab/NestedRefine.hpp> 5b117cd09SVijay Mahadevan 6b117cd09SVijay Mahadevan #undef __FUNCT__ 7b117cd09SVijay Mahadevan #define __FUNCT__ "DMMoabGenerateHierarchy" 8b117cd09SVijay Mahadevan /*@ 9b117cd09SVijay Mahadevan DMMoabGenerateHierarchy - Generate a multi-level uniform refinement hierarchy 10b117cd09SVijay Mahadevan by succesively refining a coarse mesh, already defined in the DM object 11b117cd09SVijay Mahadevan provided by the user. 12b117cd09SVijay Mahadevan 13b117cd09SVijay Mahadevan Collective on MPI_Comm 14b117cd09SVijay Mahadevan 15b117cd09SVijay Mahadevan Input Parameter: 16b117cd09SVijay Mahadevan + dmb - The DMMoab object 17b117cd09SVijay Mahadevan 18b117cd09SVijay Mahadevan Output Parameter: 19b117cd09SVijay Mahadevan + nlevels - The number of levels of refinement needed to generate the hierarchy 20b117cd09SVijay Mahadevan . ldegrees - The degree of refinement at each level in the hierarchy 21b117cd09SVijay Mahadevan 22b117cd09SVijay Mahadevan Level: beginner 23b117cd09SVijay Mahadevan 24b117cd09SVijay Mahadevan .keywords: DMMoab, create, refinement 25b117cd09SVijay Mahadevan @*/ 26b117cd09SVijay Mahadevan PetscErrorCode DMMoabGenerateHierarchy(DM dm, PetscInt nlevels, PetscInt *ldegrees) 27b117cd09SVijay Mahadevan { 28b117cd09SVijay Mahadevan DM_Moab *dmmoab; 29b117cd09SVijay Mahadevan PetscErrorCode ierr; 30b117cd09SVijay Mahadevan moab::ErrorCode merr; 31*2417220eSVijay Mahadevan PetscInt *pdegrees, ilevel; 32e882eb38SVijay Mahadevan std::vector<moab::EntityHandle> hsets; 33b117cd09SVijay Mahadevan 34b117cd09SVijay Mahadevan PetscFunctionBegin; 35b117cd09SVijay Mahadevan PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 36b117cd09SVijay Mahadevan dmmoab = (DM_Moab*)(dm)->data; 37b117cd09SVijay Mahadevan 38b117cd09SVijay Mahadevan if (!ldegrees) { 39b117cd09SVijay Mahadevan ierr = PetscMalloc1(nlevels, &pdegrees);CHKERRQ(ierr); 40*2417220eSVijay Mahadevan for (ilevel = 0; ilevel < nlevels; ilevel++) pdegrees[ilevel] = 2; /* default = Degree 2 refinement */ 41b117cd09SVijay Mahadevan } 42b117cd09SVijay Mahadevan else pdegrees = ldegrees; 43b117cd09SVijay Mahadevan 44b117cd09SVijay Mahadevan /* initialize set level refinement data for hierarchy */ 45b117cd09SVijay Mahadevan dmmoab->nhlevels = nlevels; 46b117cd09SVijay Mahadevan 47b117cd09SVijay Mahadevan /* Instantiate the nested refinement class */ 489daf19fdSVijay Mahadevan #ifdef MOAB_HAVE_MPI 493f1c6e43SVijay Mahadevan dmmoab->hierarchy = new moab::NestedRefine(dynamic_cast<moab::Core*>(dmmoab->mbiface), dmmoab->pcomm, dmmoab->fileset); 509daf19fdSVijay Mahadevan #else 519daf19fdSVijay Mahadevan dmmoab->hierarchy = new moab::NestedRefine(dynamic_cast<moab::Core*>(dmmoab->mbiface), NULL, dmmoab->fileset); 529daf19fdSVijay Mahadevan #endif 53b117cd09SVijay Mahadevan 54e882eb38SVijay Mahadevan ierr = PetscMalloc1(nlevels + 1, &dmmoab->hsets);CHKERRQ(ierr); 55e882eb38SVijay Mahadevan 56b117cd09SVijay Mahadevan /* generate the mesh hierarchy */ 5764e1c140SVijay Mahadevan merr = dmmoab->hierarchy->generate_mesh_hierarchy(nlevels, pdegrees, hsets);MBERRNM(merr); 58e882eb38SVijay Mahadevan 599daf19fdSVijay Mahadevan #ifdef MOAB_HAVE_MPI 60755f3dfbSVijay Mahadevan if (dmmoab->pcomm->size() > 1) { 6164e1c140SVijay Mahadevan merr = dmmoab->hierarchy->exchange_ghosts(hsets, dmmoab->nghostrings);MBERRNM(merr); 62755f3dfbSVijay Mahadevan } 639daf19fdSVijay Mahadevan #endif 6449d66b22SVijay Mahadevan 6564e1c140SVijay Mahadevan /* copy the mesh sets for nested refinement hierarchy */ 66*2417220eSVijay Mahadevan for (ilevel = 0; ilevel <= nlevels; ilevel++) 67*2417220eSVijay Mahadevan { 68*2417220eSVijay Mahadevan if (ilevel) { /* Update material and other geometric tags from parent to child sets */ 69*2417220eSVijay Mahadevan merr = dmmoab->hierarchy->update_special_tags(ilevel, hsets[ilevel]);MBERRNM(merr); 70*2417220eSVijay Mahadevan } 71*2417220eSVijay Mahadevan 72*2417220eSVijay Mahadevan dmmoab->hsets[ilevel] = hsets[ilevel]; 73*2417220eSVijay Mahadevan } 7464e1c140SVijay Mahadevan 7564e1c140SVijay Mahadevan hsets.clear(); 76b117cd09SVijay Mahadevan if (!ldegrees) { 77b117cd09SVijay Mahadevan ierr = PetscFree(pdegrees);CHKERRQ(ierr); 78b117cd09SVijay Mahadevan } 79b117cd09SVijay Mahadevan PetscFunctionReturn(0); 80b117cd09SVijay Mahadevan } 81b117cd09SVijay Mahadevan 82b117cd09SVijay Mahadevan #undef __FUNCT__ 83b117cd09SVijay Mahadevan #define __FUNCT__ "DMRefineHierarchy_Moab" 84b117cd09SVijay Mahadevan /*@ 85e882eb38SVijay Mahadevan DMRefineHierarchy_Moab - Generate a multi-level DM hierarchy 86e882eb38SVijay Mahadevan by succesively refining a coarse mesh. 87b117cd09SVijay Mahadevan 88b117cd09SVijay Mahadevan Collective on MPI_Comm 89b117cd09SVijay Mahadevan 90b117cd09SVijay Mahadevan Input Parameter: 91e882eb38SVijay Mahadevan + dm - The DMMoab object 92b117cd09SVijay Mahadevan 93b117cd09SVijay Mahadevan Output Parameter: 94e882eb38SVijay Mahadevan + nlevels - The number of levels of refinement needed to generate the hierarchy 95e882eb38SVijay Mahadevan . dmf - The DM objects after successive refinement of the hierarchy 96b117cd09SVijay Mahadevan 97b117cd09SVijay Mahadevan Level: beginner 98b117cd09SVijay Mahadevan 99e882eb38SVijay Mahadevan .keywords: DMMoab, generate, refinement 100b117cd09SVijay Mahadevan @*/ 101304006b3SVijay Mahadevan PETSC_EXTERN PetscErrorCode DMRefineHierarchy_Moab(DM dm, PetscInt nlevels, DM dmf[]) 102b117cd09SVijay Mahadevan { 103b117cd09SVijay Mahadevan PetscErrorCode ierr; 104b117cd09SVijay Mahadevan PetscInt i; 105b117cd09SVijay Mahadevan 106b117cd09SVijay Mahadevan PetscFunctionBegin; 107b117cd09SVijay Mahadevan 108e882eb38SVijay Mahadevan ierr = DMRefine(dm, PetscObjectComm((PetscObject)dm), &dmf[0]);CHKERRQ(ierr); 109e882eb38SVijay Mahadevan for (i = 1; i < nlevels; i++) { 110e882eb38SVijay Mahadevan ierr = DMRefine(dmf[i - 1], PetscObjectComm((PetscObject)dm), &dmf[i]);CHKERRQ(ierr); 111b117cd09SVijay Mahadevan } 112b117cd09SVijay Mahadevan PetscFunctionReturn(0); 113b117cd09SVijay Mahadevan } 114b117cd09SVijay Mahadevan 115b117cd09SVijay Mahadevan #undef __FUNCT__ 116b117cd09SVijay Mahadevan #define __FUNCT__ "DMCoarsenHierarchy_Moab" 117b117cd09SVijay Mahadevan /*@ 118e882eb38SVijay Mahadevan DMCoarsenHierarchy_Moab - Generate a multi-level DM hierarchy 119e882eb38SVijay Mahadevan by succesively coarsening a refined mesh. 120b117cd09SVijay Mahadevan 121b117cd09SVijay Mahadevan Collective on MPI_Comm 122b117cd09SVijay Mahadevan 123b117cd09SVijay Mahadevan Input Parameter: 124e882eb38SVijay Mahadevan + dm - The DMMoab object 125b117cd09SVijay Mahadevan 126b117cd09SVijay Mahadevan Output Parameter: 127e882eb38SVijay Mahadevan + nlevels - The number of levels of refinement needed to generate the hierarchy 128e882eb38SVijay Mahadevan . dmc - The DM objects after successive coarsening of the hierarchy 129b117cd09SVijay Mahadevan 130b117cd09SVijay Mahadevan Level: beginner 131b117cd09SVijay Mahadevan 132e882eb38SVijay Mahadevan .keywords: DMMoab, generate, coarsening 133b117cd09SVijay Mahadevan @*/ 134304006b3SVijay Mahadevan PETSC_EXTERN PetscErrorCode DMCoarsenHierarchy_Moab(DM dm, PetscInt nlevels, DM dmc[]) 135b117cd09SVijay Mahadevan { 136b117cd09SVijay Mahadevan PetscErrorCode ierr; 137b117cd09SVijay Mahadevan PetscInt i; 138b117cd09SVijay Mahadevan 139b117cd09SVijay Mahadevan PetscFunctionBegin; 140b117cd09SVijay Mahadevan 141e882eb38SVijay Mahadevan ierr = DMCoarsen(dm, PetscObjectComm((PetscObject)dm), &dmc[0]);CHKERRQ(ierr); 142e882eb38SVijay Mahadevan for (i = 1; i < nlevels; i++) { 143e882eb38SVijay Mahadevan ierr = DMCoarsen(dmc[i - 1], PetscObjectComm((PetscObject)dm), &dmc[i]);CHKERRQ(ierr); 144b117cd09SVijay Mahadevan } 145b117cd09SVijay Mahadevan PetscFunctionReturn(0); 146b117cd09SVijay Mahadevan } 147b117cd09SVijay Mahadevan 148*2417220eSVijay Mahadevan PETSC_EXTERN PetscErrorCode DMMoab_Compute_NNZ_From_Connectivity(DM, PetscInt*, PetscInt*, PetscInt*, PetscInt*, PetscBool); 149b117cd09SVijay Mahadevan 150b117cd09SVijay Mahadevan #undef __FUNCT__ 151b117cd09SVijay Mahadevan #define __FUNCT__ "DMCreateInterpolation_Moab" 152b117cd09SVijay Mahadevan /*@ 153e882eb38SVijay Mahadevan DMCreateInterpolation_Moab - Generate the interpolation operators to transform 154e882eb38SVijay Mahadevan operators (matrices, vectors) from parent level to child level as defined by 155e882eb38SVijay Mahadevan the DM inputs provided by the user. 156b117cd09SVijay Mahadevan 157b117cd09SVijay Mahadevan Collective on MPI_Comm 158b117cd09SVijay Mahadevan 159b117cd09SVijay Mahadevan Input Parameter: 160e882eb38SVijay Mahadevan + dm1 - The DMMoab object 161e882eb38SVijay Mahadevan - dm2 - the second, finer DMMoab object 162b117cd09SVijay Mahadevan 163b117cd09SVijay Mahadevan Output Parameter: 164e882eb38SVijay Mahadevan + interpl - The interpolation operator for transferring data between the levels 165e882eb38SVijay Mahadevan - vec - The scaling vector (optional) 166b117cd09SVijay Mahadevan 167e882eb38SVijay Mahadevan Level: developer 168b117cd09SVijay Mahadevan 169b117cd09SVijay Mahadevan .keywords: DMMoab, create, refinement 170b117cd09SVijay Mahadevan @*/ 171304006b3SVijay Mahadevan PETSC_EXTERN PetscErrorCode DMCreateInterpolation_Moab(DM dmp, DM dmc, Mat* interpl, Vec* vec) 172b117cd09SVijay Mahadevan { 173755f3dfbSVijay Mahadevan DM_Moab *dmbp, *dmbc; 174b117cd09SVijay Mahadevan PetscErrorCode ierr; 175b117cd09SVijay Mahadevan moab::ErrorCode merr; 176e882eb38SVijay Mahadevan PetscInt dim; 1773f1c6e43SVijay Mahadevan PetscReal factor; 178ce27a4eeSVijay Mahadevan PetscInt innz, *nnz, ionz, *onz; 179755f3dfbSVijay Mahadevan PetscInt nlsizp, nlsizc, nlghsizp, ngsizp, ngsizc; 180a86ed394SVijay Mahadevan const PetscBool use_consistent_bases=PETSC_TRUE; 181b117cd09SVijay Mahadevan 182b117cd09SVijay Mahadevan PetscFunctionBegin; 183755f3dfbSVijay Mahadevan PetscValidHeaderSpecific(dmp, DM_CLASSID, 1); 184755f3dfbSVijay Mahadevan PetscValidHeaderSpecific(dmc, DM_CLASSID, 2); 185755f3dfbSVijay Mahadevan dmbp = (DM_Moab*)(dmp)->data; 186755f3dfbSVijay Mahadevan dmbc = (DM_Moab*)(dmc)->data; 187755f3dfbSVijay Mahadevan nlsizp = dmbp->nloc;// *dmb1->numFields; 188755f3dfbSVijay Mahadevan nlsizc = dmbc->nloc;// *dmb2->numFields; 189755f3dfbSVijay Mahadevan ngsizp = dmbp->n; // *dmb1->numFields; 190755f3dfbSVijay Mahadevan ngsizc = dmbc->n; // *dmb2->numFields; 191755f3dfbSVijay Mahadevan nlghsizp = (dmbp->nloc + dmbp->nghost); // *dmb1->numFields; 192b117cd09SVijay Mahadevan 193*2417220eSVijay Mahadevan // Columns = Parent DoFs ; Rows = Child DoFs 194755f3dfbSVijay Mahadevan // Interpolation matrix: \sum_{i=1}^P Owned(Child) * (Owned(Parent) + Ghosted(Parent)) 195755f3dfbSVijay Mahadevan // Size: nlsizc * nlghsizp 196755f3dfbSVijay Mahadevan PetscInfo4(NULL, "Creating interpolation matrix %D X %D to apply transformation between levels %D -> %D.\n", ngsizc, nlghsizp, dmbp->hlevel, dmbc->hlevel); 197b117cd09SVijay Mahadevan 198a86ed394SVijay Mahadevan ierr = DMGetDimension(dmp, &dim);CHKERRQ(ierr); 199a86ed394SVijay Mahadevan 200941e0cffSVijay Mahadevan /* allocate the nnz, onz arrays based on block size and local nodes */ 201755f3dfbSVijay Mahadevan ierr = PetscCalloc2(nlsizc, &nnz, nlsizc, &onz);CHKERRQ(ierr); 202941e0cffSVijay Mahadevan 203941e0cffSVijay Mahadevan /* Loop through the local elements and compute the relation between the current parent and the refined_level. */ 204*2417220eSVijay Mahadevan for (moab::Range::iterator iter = dmbc->vowned->begin(); iter != dmbc->vowned->end(); iter++) { 205941e0cffSVijay Mahadevan 206*2417220eSVijay Mahadevan const moab::EntityHandle vhandle = *iter; 207*2417220eSVijay Mahadevan /* define local variables */ 208*2417220eSVijay Mahadevan moab::EntityHandle parent; 209*2417220eSVijay Mahadevan std::vector<moab::EntityHandle> adjs; 210*2417220eSVijay Mahadevan moab::Range found; 211*2417220eSVijay Mahadevan 212*2417220eSVijay Mahadevan /* store the vertex DoF number */ 213*2417220eSVijay Mahadevan const int ldof = dmbc->lidmap[vhandle - dmbc->seqstart]; 214*2417220eSVijay Mahadevan 215*2417220eSVijay Mahadevan /* Get adjacency information for current vertex - i.e., all elements of dimension (dim) that connects 216*2417220eSVijay Mahadevan to the current vertex. We can then decipher if a vertex is ghosted or not and compute the 217*2417220eSVijay Mahadevan non-zero pattern accordingly. */ 218*2417220eSVijay Mahadevan merr = dmbc->hierarchy->get_adjacencies(vhandle, dmbc->dim, adjs);MBERRNM(merr); 219*2417220eSVijay Mahadevan 220*2417220eSVijay Mahadevan /* loop over vertices and update the number of connectivity */ 221*2417220eSVijay Mahadevan for (unsigned jter = 0; jter < adjs.size(); jter++) { 222*2417220eSVijay Mahadevan 223*2417220eSVijay Mahadevan const moab::EntityHandle jhandle = adjs[jter]; 224941e0cffSVijay Mahadevan 225941e0cffSVijay Mahadevan /* Get the relation between the current (coarse) parent and its corresponding (finer) children elements */ 226*2417220eSVijay Mahadevan merr = dmbc->hierarchy->child_to_parent(jhandle, dmbc->hlevel, dmbp->hlevel, &parent);MBERRNM(merr); 227941e0cffSVijay Mahadevan 228*2417220eSVijay Mahadevan /* Get connectivity information in canonical ordering for the local element */ 229*2417220eSVijay Mahadevan std::vector<moab::EntityHandle> connp; 230*2417220eSVijay Mahadevan merr = dmbp->hierarchy->get_connectivity(parent, dmbp->hlevel, connp);MBERRNM(merr); 231a86ed394SVijay Mahadevan 232*2417220eSVijay Mahadevan for (unsigned ic=0; ic < connp.size(); ++ic) { 233*2417220eSVijay Mahadevan 234*2417220eSVijay Mahadevan /* loop over each element connected to the adjacent vertex and update as needed */ 235*2417220eSVijay Mahadevan /* find the truly user-expected layer of ghosted entities to decipher NNZ pattern */ 236*2417220eSVijay Mahadevan if (found.find(connp[ic]) != found.end()) continue; /* make sure we don't double count shared vertices */ 237*2417220eSVijay Mahadevan if (dmbp->vghost->find(connp[ic]) != dmbp->vghost->end()) onz[ldof]++; /* update out-of-proc onz */ 238*2417220eSVijay Mahadevan else nnz[ldof]++; /* else local vertex */ 239*2417220eSVijay Mahadevan found.insert(connp[ic]); 240*2417220eSVijay Mahadevan } 241*2417220eSVijay Mahadevan } 242941e0cffSVijay Mahadevan } 243941e0cffSVijay Mahadevan 244*2417220eSVijay Mahadevan for (int i = 0; i < nlsizc; i++) 245*2417220eSVijay Mahadevan nnz[i] += 1; /* self count the node */ 246941e0cffSVijay Mahadevan 247941e0cffSVijay Mahadevan ionz = onz[0]; 248941e0cffSVijay Mahadevan innz = nnz[0]; 249755f3dfbSVijay Mahadevan for (int tc = 0; tc < nlsizc; tc++) { 250941e0cffSVijay Mahadevan // check for maximum allowed sparsity = fully dense 251755f3dfbSVijay Mahadevan nnz[tc] = std::min(nlsizp, nnz[tc]); 252*2417220eSVijay Mahadevan onz[tc] = std::min(ngsizp - nlsizp, onz[tc]); 253*2417220eSVijay Mahadevan 254*2417220eSVijay Mahadevan PetscInfo3(NULL, " %d: NNZ = %d, ONZ = %d\n", tc, nnz[tc], onz[tc]); 255941e0cffSVijay Mahadevan 256941e0cffSVijay Mahadevan innz = (innz < nnz[tc] ? nnz[tc] : innz); 257941e0cffSVijay Mahadevan ionz = (ionz < onz[tc] ? onz[tc] : ionz); 258941e0cffSVijay Mahadevan } 25964e1c140SVijay Mahadevan 26064e1c140SVijay Mahadevan /* create interpolation matrix */ 261755f3dfbSVijay Mahadevan ierr = MatCreate(PetscObjectComm((PetscObject)dmc), interpl);CHKERRQ(ierr); 262755f3dfbSVijay Mahadevan ierr = MatSetSizes(*interpl, nlsizc, nlsizp, ngsizc, ngsizp);CHKERRQ(ierr); 26364e1c140SVijay Mahadevan ierr = MatSetType(*interpl, MATAIJ);CHKERRQ(ierr); 26464e1c140SVijay Mahadevan ierr = MatSetFromOptions(*interpl);CHKERRQ(ierr); 26564e1c140SVijay Mahadevan 266941e0cffSVijay Mahadevan ierr = MatSeqAIJSetPreallocation(*interpl, innz, nnz);CHKERRQ(ierr); 267941e0cffSVijay Mahadevan ierr = MatMPIAIJSetPreallocation(*interpl, innz, nnz, ionz, onz);CHKERRQ(ierr); 268941e0cffSVijay Mahadevan 269941e0cffSVijay Mahadevan /* clean up temporary memory */ 270941e0cffSVijay Mahadevan ierr = PetscFree2(nnz, onz);CHKERRQ(ierr); 271b117cd09SVijay Mahadevan 272b117cd09SVijay Mahadevan /* set up internal matrix data-structures */ 273b117cd09SVijay Mahadevan ierr = MatSetUp(*interpl);CHKERRQ(ierr); 274b117cd09SVijay Mahadevan 275a86ed394SVijay Mahadevan /* Define variables for assembly */ 276a86ed394SVijay Mahadevan std::vector<moab::EntityHandle> children; 277a86ed394SVijay Mahadevan std::vector<moab::EntityHandle> connp, connc; 278a86ed394SVijay Mahadevan std::vector<PetscReal> pcoords, ccoords, values_phi; 279a86ed394SVijay Mahadevan 280a86ed394SVijay Mahadevan if (use_consistent_bases) { 281*2417220eSVijay Mahadevan const moab::EntityHandle ehandle = dmbp->elocal->front(); 282a86ed394SVijay Mahadevan 283a86ed394SVijay Mahadevan merr = dmbp->hierarchy->parent_to_child(ehandle, dmbp->hlevel, dmbc->hlevel, children);MBERRNM(merr); 284a86ed394SVijay Mahadevan 285a86ed394SVijay Mahadevan /* Get connectivity and coordinates of the parent vertices */ 286a86ed394SVijay Mahadevan merr = dmbp->hierarchy->get_connectivity(ehandle, dmbp->hlevel, connp);MBERRNM(merr); 287*2417220eSVijay Mahadevan merr = dmbc->mbiface->get_connectivity(&children[0], children.size(), connc);MBERRNM(merr); 288a86ed394SVijay Mahadevan 289a86ed394SVijay Mahadevan std::vector<PetscReal> natparam(3*connc.size(), 0.0); 290a86ed394SVijay Mahadevan pcoords.resize(connp.size() * 3); 291a86ed394SVijay Mahadevan ccoords.resize(connc.size() * 3); 292a86ed394SVijay Mahadevan values_phi.resize(connp.size()*connc.size()); 293a86ed394SVijay Mahadevan /* Get coordinates for connectivity entities in canonical order for both coarse and finer levels */ 294a86ed394SVijay Mahadevan merr = dmbp->hierarchy->get_coordinates(&connp[0], connp.size(), dmbp->hlevel, &pcoords[0]);MBERRNM(merr); 295a86ed394SVijay Mahadevan merr = dmbc->hierarchy->get_coordinates(&connc[0], connc.size(), dmbc->hlevel, &ccoords[0]);MBERRNM(merr); 296a86ed394SVijay Mahadevan 297a86ed394SVijay Mahadevan /* Set values: For each DOF in coarse grid cell, set the contribution or PHI evaluated at each fine grid DOF point */ 298a86ed394SVijay Mahadevan for (unsigned tc = 0; tc < connc.size(); tc++) { 299a86ed394SVijay Mahadevan const PetscInt offset = tc * 3; 300a86ed394SVijay Mahadevan 301a86ed394SVijay Mahadevan /* Scale ccoords relative to pcoords */ 302a86ed394SVijay Mahadevan ierr = DMMoabPToRMapping(dim, connp.size(), &pcoords[0], &ccoords[offset], &natparam[offset], &values_phi[connp.size()*tc]);CHKERRQ(ierr); 303a86ed394SVijay Mahadevan } 304a86ed394SVijay Mahadevan } 305a86ed394SVijay Mahadevan else { 306a86ed394SVijay Mahadevan factor = std::pow(2.0 /*degree_P_for_refinement*/, (dmbc->hlevel - dmbp->hlevel) * dmbp->dim * 1.0); 307a86ed394SVijay Mahadevan } 308a86ed394SVijay Mahadevan 309755f3dfbSVijay Mahadevan /* TODO: Decipher the correct non-zero pattern. There is still some issue with onz allocation */ 310*2417220eSVijay Mahadevan ierr = MatSetOption(*interpl, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE);CHKERRQ(ierr); 311b117cd09SVijay Mahadevan 312e882eb38SVijay Mahadevan /* Loop through the remaining vertices. These vertices appear only on the current refined_level. */ 313*2417220eSVijay Mahadevan for (moab::Range::iterator iter = dmbp->elocal->begin(); iter != dmbp->elocal->end(); iter++) { 314b117cd09SVijay Mahadevan 315b117cd09SVijay Mahadevan const moab::EntityHandle ehandle = *iter; 316b117cd09SVijay Mahadevan 317b117cd09SVijay Mahadevan /* Get the relation between the current (coarse) parent and its corresponding (finer) children elements */ 318a86ed394SVijay Mahadevan children.clear(); 319a86ed394SVijay Mahadevan connc.clear(); 320755f3dfbSVijay Mahadevan merr = dmbp->hierarchy->parent_to_child(ehandle, dmbp->hlevel, dmbc->hlevel, children);MBERRNM(merr); 321b117cd09SVijay Mahadevan 322b117cd09SVijay Mahadevan /* Get connectivity and coordinates of the parent vertices */ 323755f3dfbSVijay Mahadevan merr = dmbp->hierarchy->get_connectivity(ehandle, dmbp->hlevel, connp);MBERRNM(merr); 324*2417220eSVijay Mahadevan merr = dmbc->mbiface->get_connectivity(&children[0], children.size(), connc);MBERRNM(merr); 325b117cd09SVijay Mahadevan 326a86ed394SVijay Mahadevan pcoords.resize(connp.size() * 3); 327a86ed394SVijay Mahadevan ccoords.resize(connc.size() * 3); 328b117cd09SVijay Mahadevan /* Get coordinates for connectivity entities in canonical order for both coarse and finer levels */ 329755f3dfbSVijay Mahadevan merr = dmbp->hierarchy->get_coordinates(&connp[0], connp.size(), dmbp->hlevel, &pcoords[0]);MBERRNM(merr); 330755f3dfbSVijay Mahadevan merr = dmbc->hierarchy->get_coordinates(&connc[0], connc.size(), dmbc->hlevel, &ccoords[0]);MBERRNM(merr); 331b117cd09SVijay Mahadevan 332b117cd09SVijay Mahadevan std::vector<int> dofsp(connp.size()), dofsc(connc.size()); 333b117cd09SVijay Mahadevan /* TODO: specific to scalar system - use GetDofs */ 334755f3dfbSVijay Mahadevan ierr = DMMoabGetDofsBlocked(dmp, connp.size(), &connp[0], &dofsp[0]);CHKERRQ(ierr); 335755f3dfbSVijay Mahadevan ierr = DMMoabGetDofsBlocked(dmc, connc.size(), &connc[0], &dofsc[0]);CHKERRQ(ierr); 336b117cd09SVijay Mahadevan 337a86ed394SVijay Mahadevan /* Compute the actual interpolation weights when projecting solution/residual between levels */ 338a86ed394SVijay Mahadevan if (use_consistent_bases) { 339a86ed394SVijay Mahadevan 340a86ed394SVijay Mahadevan /* Use the cached values of natural parameteric coordinates and basis pre-evaluated. 341a86ed394SVijay Mahadevan We are making an assumption here that UMR used in GMG to generate the hierarchy uses 342a86ed394SVijay Mahadevan the same template for all elements; This will fail for mixed element meshes (TRI/QUAD). 343a86ed394SVijay Mahadevan 344*2417220eSVijay Mahadevan TODO: Fix the above assumption by caching data for families (especially for Tets and mixed meshes) 345a86ed394SVijay Mahadevan */ 346a86ed394SVijay Mahadevan 347a86ed394SVijay Mahadevan /* Set values: For each DOF in coarse grid cell, set the contribution or PHI evaluated at each fine grid DOF point */ 348a86ed394SVijay Mahadevan for (unsigned tc = 0; tc < connc.size(); tc++) { 349a86ed394SVijay Mahadevan /* TODO: Check if we should be using INSERT_VALUES instead */ 350a86ed394SVijay Mahadevan ierr = MatSetValues(*interpl, 1, &dofsc[tc], connp.size(), &dofsp[0], &values_phi[connp.size()*tc], ADD_VALUES);CHKERRQ(ierr); 351a86ed394SVijay Mahadevan } 352a86ed394SVijay Mahadevan } 353a86ed394SVijay Mahadevan else { 354e882eb38SVijay Mahadevan /* Compute the interpolation weights by determining distance of 1-ring 355755f3dfbSVijay Mahadevan neighbor vertices from current vertex 356755f3dfbSVijay Mahadevan 357a86ed394SVijay Mahadevan This should be used only when FEM basis is not used for the discretization. 358a86ed394SVijay Mahadevan Else, the consistent interface to compute the basis function for interpolation 359a86ed394SVijay Mahadevan between the levels should be evaluated correctly to preserve convergence of GMG. 360*2417220eSVijay Mahadevan Shephard's basis will be terrible for any unsmooth problems. 361755f3dfbSVijay Mahadevan */ 362755f3dfbSVijay Mahadevan values_phi.resize(connp.size()); 363755f3dfbSVijay Mahadevan for (unsigned tc = 0; tc < connc.size(); tc++) { 364755f3dfbSVijay Mahadevan 365a86ed394SVijay Mahadevan PetscReal normsum = 0.0; 366755f3dfbSVijay Mahadevan for (unsigned tp = 0; tp < connp.size(); tp++) { 367755f3dfbSVijay Mahadevan values_phi[tp] = 0.0; 368e882eb38SVijay Mahadevan for (unsigned k = 0; k < 3; k++) 369755f3dfbSVijay Mahadevan values_phi[tp] += std::pow(pcoords[tp * 3 + k] - ccoords[k + tc * 3], dim); 370755f3dfbSVijay Mahadevan if (values_phi[tp] < 1e-12) { 371755f3dfbSVijay Mahadevan values_phi[tp] = 1e12; 372b117cd09SVijay Mahadevan } 373b117cd09SVijay Mahadevan else { 374755f3dfbSVijay Mahadevan //values_phi[tp] = std::pow(values_phi[tp], -1.0/dim); 375755f3dfbSVijay Mahadevan values_phi[tp] = std::pow(values_phi[tp], -1.0); 376755f3dfbSVijay Mahadevan normsum += values_phi[tp]; 377b117cd09SVijay Mahadevan } 378b117cd09SVijay Mahadevan } 379755f3dfbSVijay Mahadevan for (unsigned tp = 0; tp < connp.size(); tp++) { 380755f3dfbSVijay Mahadevan if (values_phi[tp] > 1e11) 381755f3dfbSVijay Mahadevan values_phi[tp] = factor * 0.5 / connp.size(); 382b117cd09SVijay Mahadevan else 383755f3dfbSVijay Mahadevan values_phi[tp] = factor * values_phi[tp] * 0.5 / (connp.size() * normsum); 384b117cd09SVijay Mahadevan } 385755f3dfbSVijay Mahadevan ierr = MatSetValues(*interpl, 1, &dofsc[tc], connp.size(), &dofsp[0], &values_phi[0], ADD_VALUES);CHKERRQ(ierr); 386b117cd09SVijay Mahadevan } 387a86ed394SVijay Mahadevan } 388b117cd09SVijay Mahadevan } 389304006b3SVijay Mahadevan if (vec) *vec = NULL; 390b117cd09SVijay Mahadevan ierr = MatAssemblyBegin(*interpl, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 391b117cd09SVijay Mahadevan ierr = MatAssemblyEnd(*interpl, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 392b117cd09SVijay Mahadevan PetscFunctionReturn(0); 393b117cd09SVijay Mahadevan } 394b117cd09SVijay Mahadevan 395b117cd09SVijay Mahadevan #undef __FUNCT__ 396b117cd09SVijay Mahadevan #define __FUNCT__ "DMCreateInjection_Moab" 397b117cd09SVijay Mahadevan /*@ 398b117cd09SVijay Mahadevan DMCreateInjection_Moab - Generate a multi-level uniform refinement hierarchy 399b117cd09SVijay Mahadevan by succesively refining a coarse mesh, already defined in the DM object 400b117cd09SVijay Mahadevan provided by the user. 401b117cd09SVijay Mahadevan 402b117cd09SVijay Mahadevan Collective on MPI_Comm 403b117cd09SVijay Mahadevan 404b117cd09SVijay Mahadevan Input Parameter: 405b117cd09SVijay Mahadevan . dmb - The DMMoab object 406b117cd09SVijay Mahadevan 407b117cd09SVijay Mahadevan Output Parameter: 408b117cd09SVijay Mahadevan . nlevels - The number of levels of refinement needed to generate the hierarchy 409b117cd09SVijay Mahadevan + ldegrees - The degree of refinement at each level in the hierarchy 410b117cd09SVijay Mahadevan 411b117cd09SVijay Mahadevan Level: beginner 412b117cd09SVijay Mahadevan 413b117cd09SVijay Mahadevan .keywords: DMMoab, create, refinement 414b117cd09SVijay Mahadevan @*/ 415304006b3SVijay Mahadevan PETSC_EXTERN PetscErrorCode DMCreateInjection_Moab(DM dm1, DM dm2, VecScatter* ctx) 416b117cd09SVijay Mahadevan { 417e882eb38SVijay Mahadevan //DM_Moab *dmmoab; 418b117cd09SVijay Mahadevan 419b117cd09SVijay Mahadevan PetscFunctionBegin; 420b117cd09SVijay Mahadevan PetscValidHeaderSpecific(dm1, DM_CLASSID, 1); 421b117cd09SVijay Mahadevan PetscValidHeaderSpecific(dm2, DM_CLASSID, 2); 422e882eb38SVijay Mahadevan //dmmoab = (DM_Moab*)(dm1)->data; 423b117cd09SVijay Mahadevan 424b117cd09SVijay Mahadevan PetscPrintf(PETSC_COMM_WORLD, "[DMCreateInjection_Moab] :: Placeholder\n"); 425b117cd09SVijay Mahadevan PetscFunctionReturn(0); 426b117cd09SVijay Mahadevan } 427b117cd09SVijay Mahadevan 428b117cd09SVijay Mahadevan 429b117cd09SVijay Mahadevan #undef __FUNCT__ 430b117cd09SVijay Mahadevan #define __FUNCT__ "DM_UMR_Moab_Private" 431b117cd09SVijay Mahadevan PetscErrorCode DM_UMR_Moab_Private(DM dm, MPI_Comm comm, PetscBool refine, DM *dmref) 432b117cd09SVijay Mahadevan { 433b117cd09SVijay Mahadevan PetscErrorCode ierr; 434e882eb38SVijay Mahadevan PetscInt i, dim; 435b117cd09SVijay Mahadevan DM dm2; 436b117cd09SVijay Mahadevan moab::ErrorCode merr; 437b117cd09SVijay Mahadevan DM_Moab *dmb = (DM_Moab*)dm->data, *dd2; 438b117cd09SVijay Mahadevan 439b117cd09SVijay Mahadevan PetscFunctionBegin; 440b117cd09SVijay Mahadevan PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 441b117cd09SVijay Mahadevan PetscValidPointer(dmref, 4); 442b117cd09SVijay Mahadevan 443b117cd09SVijay Mahadevan if ( (dmb->hlevel == dmb->nhlevels && refine) || (dmb->hlevel == 0 && !refine) ) { 444e882eb38SVijay Mahadevan 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); 445e882eb38SVijay Mahadevan if (dmb->hlevel - 1 < 0 && !refine) PetscInfo1(NULL, "Invalid multigrid coarsen hierarchy level specified (%D). Creating a NULL object.\n", dmb->hlevel - 1); 446e882eb38SVijay Mahadevan *dmref = PETSC_NULL; 447b117cd09SVijay Mahadevan PetscFunctionReturn(0); 448b117cd09SVijay Mahadevan } 449b117cd09SVijay Mahadevan 450b117cd09SVijay Mahadevan ierr = DMMoabCreate(PetscObjectComm((PetscObject)dm), &dm2);CHKERRQ(ierr); 451b117cd09SVijay Mahadevan dd2 = (DM_Moab*)dm2->data; 452b117cd09SVijay Mahadevan 453b117cd09SVijay Mahadevan dd2->mbiface = dmb->mbiface; 4549daf19fdSVijay Mahadevan #ifdef MOAB_HAVE_MPI 455b117cd09SVijay Mahadevan dd2->pcomm = dmb->pcomm; 4569daf19fdSVijay Mahadevan #endif 457b117cd09SVijay Mahadevan dd2->icreatedinstance = PETSC_FALSE; 45864e1c140SVijay Mahadevan dd2->nghostrings = dmb->nghostrings; 459b117cd09SVijay Mahadevan 460b117cd09SVijay Mahadevan /* set the new level based on refinement/coarsening */ 461b117cd09SVijay Mahadevan if (refine) { 462b117cd09SVijay Mahadevan dd2->hlevel = dmb->hlevel + 1; 463b117cd09SVijay Mahadevan } 464b117cd09SVijay Mahadevan else { 465b117cd09SVijay Mahadevan dd2->hlevel = dmb->hlevel - 1; 466b117cd09SVijay Mahadevan } 467b117cd09SVijay Mahadevan 468b117cd09SVijay Mahadevan /* Copy the multilevel hierarchy pointers in MOAB */ 469b117cd09SVijay Mahadevan dd2->hierarchy = dmb->hierarchy; 470b117cd09SVijay Mahadevan dd2->nhlevels = dmb->nhlevels; 471b117cd09SVijay Mahadevan ierr = PetscMalloc1(dd2->nhlevels + 1, &dd2->hsets);CHKERRQ(ierr); 472b117cd09SVijay Mahadevan for (i = 0; i <= dd2->nhlevels; i++) { 473b117cd09SVijay Mahadevan dd2->hsets[i] = dmb->hsets[i]; 474b117cd09SVijay Mahadevan } 475b117cd09SVijay Mahadevan dd2->fileset = dd2->hsets[dd2->hlevel]; 476b117cd09SVijay Mahadevan 477b117cd09SVijay Mahadevan /* do the remaining initializations for DMMoab */ 478b117cd09SVijay Mahadevan dd2->bs = dmb->bs; 479b117cd09SVijay Mahadevan dd2->numFields = dmb->numFields; 480b117cd09SVijay Mahadevan dd2->rw_dbglevel = dmb->rw_dbglevel; 481b117cd09SVijay Mahadevan dd2->partition_by_rank = dmb->partition_by_rank; 482b117cd09SVijay Mahadevan ierr = PetscStrcpy(dd2->extra_read_options, dmb->extra_read_options);CHKERRQ(ierr); 483b117cd09SVijay Mahadevan ierr = PetscStrcpy(dd2->extra_write_options, dmb->extra_write_options);CHKERRQ(ierr); 484b117cd09SVijay Mahadevan dd2->read_mode = dmb->read_mode; 485b117cd09SVijay Mahadevan dd2->write_mode = dmb->write_mode; 486b117cd09SVijay Mahadevan 487b117cd09SVijay Mahadevan /* set global ID tag handle */ 488b117cd09SVijay Mahadevan ierr = DMMoabSetLocalToGlobalTag(dm2, dmb->ltog_tag);CHKERRQ(ierr); 489b117cd09SVijay Mahadevan 490b117cd09SVijay Mahadevan merr = dd2->mbiface->tag_get_handle(MATERIAL_SET_TAG_NAME, dd2->material_tag);MBERRNM(merr); 491b117cd09SVijay Mahadevan 492b117cd09SVijay Mahadevan ierr = DMSetOptionsPrefix(dm2, ((PetscObject)dm)->prefix);CHKERRQ(ierr); 493b117cd09SVijay Mahadevan ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 494b117cd09SVijay Mahadevan ierr = DMSetDimension(dm2, dim);CHKERRQ(ierr); 495b117cd09SVijay Mahadevan 496b117cd09SVijay Mahadevan /* allow overloaded (user replaced) operations to be inherited by refinement clones */ 497b117cd09SVijay Mahadevan dm2->ops->creatematrix = dm->ops->creatematrix; 498b117cd09SVijay Mahadevan 499b117cd09SVijay Mahadevan /* copy fill information if given */ 500b117cd09SVijay Mahadevan ierr = DMMoabSetBlockFills(dm2, dmb->dfill, dmb->ofill);CHKERRQ(ierr); 501b117cd09SVijay Mahadevan 502b117cd09SVijay Mahadevan /* copy vector type information */ 503b117cd09SVijay Mahadevan ierr = DMSetMatType(dm2, dm->mattype);CHKERRQ(ierr); 504b117cd09SVijay Mahadevan ierr = DMSetVecType(dm2, dm->vectype);CHKERRQ(ierr); 5053f1c6e43SVijay Mahadevan dd2->numFields = dmb->numFields; 5063f1c6e43SVijay Mahadevan if (dmb->numFields) { 507b117cd09SVijay Mahadevan ierr = DMMoabSetFieldNames(dm2, dmb->numFields, dmb->fieldNames);CHKERRQ(ierr); 5083f1c6e43SVijay Mahadevan } 509b117cd09SVijay Mahadevan 510b117cd09SVijay Mahadevan ierr = DMSetFromOptions(dm2);CHKERRQ(ierr); 511b117cd09SVijay Mahadevan 512b117cd09SVijay Mahadevan /* recreate Dof numbering for the refined DM and make sure the distribution is correctly populated */ 513b117cd09SVijay Mahadevan ierr = DMSetUp(dm2);CHKERRQ(ierr); 514b117cd09SVijay Mahadevan 515b117cd09SVijay Mahadevan *dmref = dm2; 516b117cd09SVijay Mahadevan PetscFunctionReturn(0); 517b117cd09SVijay Mahadevan } 518b117cd09SVijay Mahadevan 519b117cd09SVijay Mahadevan 520b117cd09SVijay Mahadevan #undef __FUNCT__ 521b117cd09SVijay Mahadevan #define __FUNCT__ "DMRefine_Moab" 522b117cd09SVijay Mahadevan /*@ 523b117cd09SVijay Mahadevan DMRefine_Moab - Generate a multi-level uniform refinement hierarchy 524b117cd09SVijay Mahadevan by succesively refining a coarse mesh, already defined in the DM object 525b117cd09SVijay Mahadevan provided by the user. 526b117cd09SVijay Mahadevan 527e882eb38SVijay Mahadevan Collective on DM 528b117cd09SVijay Mahadevan 529b117cd09SVijay Mahadevan Input Parameter: 530e882eb38SVijay Mahadevan + dm - The DMMoab object 531e882eb38SVijay Mahadevan - comm - the communicator to contain the new DM object (or MPI_COMM_NULL) 532b117cd09SVijay Mahadevan 533b117cd09SVijay Mahadevan Output Parameter: 534e882eb38SVijay Mahadevan . dmf - the refined DM, or NULL 535b117cd09SVijay Mahadevan 536e882eb38SVijay Mahadevan Note: If no refinement was done, the return value is NULL 537e882eb38SVijay Mahadevan 538e882eb38SVijay Mahadevan Level: developer 539b117cd09SVijay Mahadevan 540b117cd09SVijay Mahadevan .keywords: DMMoab, create, refinement 541b117cd09SVijay Mahadevan @*/ 542304006b3SVijay Mahadevan PETSC_EXTERN PetscErrorCode DMRefine_Moab(DM dm, MPI_Comm comm, DM* dmf) 543b117cd09SVijay Mahadevan { 544b117cd09SVijay Mahadevan PetscErrorCode ierr; 545b117cd09SVijay Mahadevan 546b117cd09SVijay Mahadevan PetscFunctionBegin; 547b117cd09SVijay Mahadevan PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 548b117cd09SVijay Mahadevan 549b117cd09SVijay Mahadevan ierr = DM_UMR_Moab_Private(dm, comm, PETSC_TRUE, dmf);CHKERRQ(ierr); 550b117cd09SVijay Mahadevan PetscFunctionReturn(0); 551b117cd09SVijay Mahadevan } 552b117cd09SVijay Mahadevan 553b117cd09SVijay Mahadevan #undef __FUNCT__ 554b117cd09SVijay Mahadevan #define __FUNCT__ "DMCoarsen_Moab" 555b117cd09SVijay Mahadevan /*@ 556b117cd09SVijay Mahadevan DMCoarsen_Moab - Generate a multi-level uniform refinement hierarchy 557b117cd09SVijay Mahadevan by succesively refining a coarse mesh, already defined in the DM object 558b117cd09SVijay Mahadevan provided by the user. 559b117cd09SVijay Mahadevan 560e882eb38SVijay Mahadevan Collective on DM 561b117cd09SVijay Mahadevan 562b117cd09SVijay Mahadevan Input Parameter: 563e882eb38SVijay Mahadevan . dm - The DMMoab object 564e882eb38SVijay Mahadevan - comm - the communicator to contain the new DM object (or MPI_COMM_NULL) 565b117cd09SVijay Mahadevan 566b117cd09SVijay Mahadevan Output Parameter: 567e882eb38SVijay Mahadevan . dmf - the coarsened DM, or NULL 568b117cd09SVijay Mahadevan 569e882eb38SVijay Mahadevan Note: If no coarsening was done, the return value is NULL 570b117cd09SVijay Mahadevan 571e882eb38SVijay Mahadevan Level: developer 572e882eb38SVijay Mahadevan 573e882eb38SVijay Mahadevan .keywords: DMMoab, create, coarsening 574b117cd09SVijay Mahadevan @*/ 575304006b3SVijay Mahadevan PETSC_EXTERN PetscErrorCode DMCoarsen_Moab(DM dm, MPI_Comm comm, DM* dmc) 576b117cd09SVijay Mahadevan { 577b117cd09SVijay Mahadevan PetscErrorCode ierr; 578b117cd09SVijay Mahadevan 579b117cd09SVijay Mahadevan PetscFunctionBegin; 580b117cd09SVijay Mahadevan PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 581b117cd09SVijay Mahadevan 582b117cd09SVijay Mahadevan ierr = DM_UMR_Moab_Private(dm, comm, PETSC_FALSE, dmc);CHKERRQ(ierr); 583b117cd09SVijay Mahadevan PetscFunctionReturn(0); 584b117cd09SVijay Mahadevan } 585