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 6cab5ea25SPierre Jolivet /*@C 7b117cd09SVijay Mahadevan DMMoabGenerateHierarchy - Generate a multi-level uniform refinement hierarchy 8b117cd09SVijay Mahadevan by succesively refining a coarse mesh, already defined in the DM object 9b117cd09SVijay Mahadevan provided by the user. 10b117cd09SVijay Mahadevan 11d083f849SBarry Smith Collective 12b117cd09SVijay Mahadevan 13b117cd09SVijay Mahadevan Input Parameter: 14a2b725a8SWilliam Gropp . dmb - The DMMoab object 15b117cd09SVijay Mahadevan 16d8d19677SJose E. Roman Output Parameters: 17b117cd09SVijay Mahadevan + nlevels - The number of levels of refinement needed to generate the hierarchy 18a2b725a8SWilliam Gropp - ldegrees - The degree of refinement at each level in the hierarchy 19b117cd09SVijay Mahadevan 20b117cd09SVijay Mahadevan Level: beginner 21b117cd09SVijay Mahadevan 22b117cd09SVijay Mahadevan @*/ 23d71ae5a4SJacob Faibussowitsch PetscErrorCode DMMoabGenerateHierarchy(DM dm, PetscInt nlevels, PetscInt *ldegrees) 24d71ae5a4SJacob Faibussowitsch { 25b117cd09SVijay Mahadevan DM_Moab *dmmoab; 26b117cd09SVijay Mahadevan moab::ErrorCode merr; 272417220eSVijay Mahadevan PetscInt *pdegrees, ilevel; 28e882eb38SVijay Mahadevan std::vector<moab::EntityHandle> hsets; 29b117cd09SVijay Mahadevan 30b117cd09SVijay Mahadevan PetscFunctionBegin; 31b117cd09SVijay Mahadevan PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 32b117cd09SVijay Mahadevan dmmoab = (DM_Moab *)(dm)->data; 33b117cd09SVijay Mahadevan 34b117cd09SVijay Mahadevan if (!ldegrees) { 359566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nlevels, &pdegrees)); 362417220eSVijay Mahadevan for (ilevel = 0; ilevel < nlevels; ilevel++) pdegrees[ilevel] = 2; /* default = Degree 2 refinement */ 379371c9d4SSatish Balay } else pdegrees = ldegrees; 38b117cd09SVijay Mahadevan 39b117cd09SVijay Mahadevan /* initialize set level refinement data for hierarchy */ 40b117cd09SVijay Mahadevan dmmoab->nhlevels = nlevels; 41b117cd09SVijay Mahadevan 42b117cd09SVijay Mahadevan /* Instantiate the nested refinement class */ 439daf19fdSVijay Mahadevan #ifdef MOAB_HAVE_MPI 443f1c6e43SVijay Mahadevan dmmoab->hierarchy = new moab::NestedRefine(dynamic_cast<moab::Core *>(dmmoab->mbiface), dmmoab->pcomm, dmmoab->fileset); 459daf19fdSVijay Mahadevan #else 469daf19fdSVijay Mahadevan dmmoab->hierarchy = new moab::NestedRefine(dynamic_cast<moab::Core *>(dmmoab->mbiface), NULL, dmmoab->fileset); 479daf19fdSVijay Mahadevan #endif 48b117cd09SVijay Mahadevan 499566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nlevels + 1, &dmmoab->hsets)); 50e882eb38SVijay Mahadevan 51b117cd09SVijay Mahadevan /* generate the mesh hierarchy */ 529371c9d4SSatish Balay merr = dmmoab->hierarchy->generate_mesh_hierarchy(nlevels, pdegrees, hsets, false); 539371c9d4SSatish Balay MBERRNM(merr); 54e882eb38SVijay Mahadevan 559daf19fdSVijay Mahadevan #ifdef MOAB_HAVE_MPI 56755f3dfbSVijay Mahadevan if (dmmoab->pcomm->size() > 1) { 579371c9d4SSatish Balay merr = dmmoab->hierarchy->exchange_ghosts(hsets, dmmoab->nghostrings); 589371c9d4SSatish Balay MBERRNM(merr); 59755f3dfbSVijay Mahadevan } 609daf19fdSVijay Mahadevan #endif 6149d66b22SVijay Mahadevan 6264e1c140SVijay Mahadevan /* copy the mesh sets for nested refinement hierarchy */ 63e92d1c7cSVijay Mahadevan dmmoab->hsets[0] = hsets[0]; 649371c9d4SSatish Balay for (ilevel = 1; ilevel <= nlevels; ilevel++) { 652417220eSVijay Mahadevan dmmoab->hsets[ilevel] = hsets[ilevel]; 66e92d1c7cSVijay Mahadevan 679c368985SVijay Mahadevan #ifdef MOAB_HAVE_MPI 689371c9d4SSatish Balay merr = dmmoab->pcomm->assign_global_ids(hsets[ilevel], dmmoab->dim, 0, false, true, false); 699371c9d4SSatish Balay MBERRNM(merr); 709c368985SVijay Mahadevan #endif 71e92d1c7cSVijay Mahadevan 72e92d1c7cSVijay Mahadevan /* Update material and other geometric tags from parent to child sets */ 739371c9d4SSatish Balay merr = dmmoab->hierarchy->update_special_tags(ilevel, hsets[ilevel]); 749371c9d4SSatish Balay MBERRNM(merr); 752417220eSVijay Mahadevan } 7664e1c140SVijay Mahadevan 7764e1c140SVijay Mahadevan hsets.clear(); 7848a46eb9SPierre Jolivet if (!ldegrees) PetscCall(PetscFree(pdegrees)); 79b117cd09SVijay Mahadevan PetscFunctionReturn(0); 80b117cd09SVijay Mahadevan } 81b117cd09SVijay Mahadevan 82cab5ea25SPierre Jolivet /*@C 83e882eb38SVijay Mahadevan DMRefineHierarchy_Moab - Generate a multi-level DM hierarchy 84e882eb38SVijay Mahadevan by succesively refining a coarse mesh. 85b117cd09SVijay Mahadevan 86d083f849SBarry Smith Collective 87b117cd09SVijay Mahadevan 88b117cd09SVijay Mahadevan Input Parameter: 89a2b725a8SWilliam Gropp . dm - The DMMoab object 90b117cd09SVijay Mahadevan 91d8d19677SJose E. Roman Output Parameters: 92e882eb38SVijay Mahadevan + nlevels - The number of levels of refinement needed to generate the hierarchy 93a2b725a8SWilliam Gropp - dmf - The DM objects after successive refinement of the hierarchy 94b117cd09SVijay Mahadevan 95b117cd09SVijay Mahadevan Level: beginner 96b117cd09SVijay Mahadevan 97b117cd09SVijay Mahadevan @*/ 98d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode DMRefineHierarchy_Moab(DM dm, PetscInt nlevels, DM dmf[]) 99d71ae5a4SJacob Faibussowitsch { 100b117cd09SVijay Mahadevan PetscInt i; 101b117cd09SVijay Mahadevan 102b117cd09SVijay Mahadevan PetscFunctionBegin; 103b117cd09SVijay Mahadevan 1049566063dSJacob Faibussowitsch PetscCall(DMRefine(dm, PetscObjectComm((PetscObject)dm), &dmf[0])); 10548a46eb9SPierre Jolivet for (i = 1; i < nlevels; i++) PetscCall(DMRefine(dmf[i - 1], PetscObjectComm((PetscObject)dm), &dmf[i])); 106b117cd09SVijay Mahadevan PetscFunctionReturn(0); 107b117cd09SVijay Mahadevan } 108b117cd09SVijay Mahadevan 109cab5ea25SPierre Jolivet /*@C 110e882eb38SVijay Mahadevan DMCoarsenHierarchy_Moab - Generate a multi-level DM hierarchy 111e882eb38SVijay Mahadevan by succesively coarsening a refined mesh. 112b117cd09SVijay Mahadevan 113d083f849SBarry Smith Collective 114b117cd09SVijay Mahadevan 115b117cd09SVijay Mahadevan Input Parameter: 116a2b725a8SWilliam Gropp . dm - The DMMoab object 117b117cd09SVijay Mahadevan 118d8d19677SJose E. Roman Output Parameters: 119e882eb38SVijay Mahadevan + nlevels - The number of levels of refinement needed to generate the hierarchy 120a2b725a8SWilliam Gropp - dmc - The DM objects after successive coarsening of the hierarchy 121b117cd09SVijay Mahadevan 122b117cd09SVijay Mahadevan Level: beginner 123b117cd09SVijay Mahadevan 124b117cd09SVijay Mahadevan @*/ 125d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode DMCoarsenHierarchy_Moab(DM dm, PetscInt nlevels, DM dmc[]) 126d71ae5a4SJacob Faibussowitsch { 127b117cd09SVijay Mahadevan PetscInt i; 128b117cd09SVijay Mahadevan 129b117cd09SVijay Mahadevan PetscFunctionBegin; 130b117cd09SVijay Mahadevan 1319566063dSJacob Faibussowitsch PetscCall(DMCoarsen(dm, PetscObjectComm((PetscObject)dm), &dmc[0])); 13248a46eb9SPierre Jolivet for (i = 1; i < nlevels; i++) PetscCall(DMCoarsen(dmc[i - 1], PetscObjectComm((PetscObject)dm), &dmc[i])); 133b117cd09SVijay Mahadevan PetscFunctionReturn(0); 134b117cd09SVijay Mahadevan } 135b117cd09SVijay Mahadevan 1362417220eSVijay Mahadevan PETSC_EXTERN PetscErrorCode DMMoab_Compute_NNZ_From_Connectivity(DM, PetscInt *, PetscInt *, PetscInt *, PetscInt *, PetscBool); 137b117cd09SVijay Mahadevan 138cab5ea25SPierre Jolivet /*@C 139e882eb38SVijay Mahadevan DMCreateInterpolation_Moab - Generate the interpolation operators to transform 140e882eb38SVijay Mahadevan operators (matrices, vectors) from parent level to child level as defined by 141e882eb38SVijay Mahadevan the DM inputs provided by the user. 142b117cd09SVijay Mahadevan 143d083f849SBarry Smith Collective 144b117cd09SVijay Mahadevan 145d8d19677SJose E. Roman Input Parameters: 146e882eb38SVijay Mahadevan + dm1 - The DMMoab object 147e882eb38SVijay Mahadevan - dm2 - the second, finer DMMoab object 148b117cd09SVijay Mahadevan 149d8d19677SJose E. Roman Output Parameters: 150e882eb38SVijay Mahadevan + interpl - The interpolation operator for transferring data between the levels 151e882eb38SVijay Mahadevan - vec - The scaling vector (optional) 152b117cd09SVijay Mahadevan 153e882eb38SVijay Mahadevan Level: developer 154b117cd09SVijay Mahadevan 155b117cd09SVijay Mahadevan @*/ 156d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode DMCreateInterpolation_Moab(DM dmp, DM dmc, Mat *interpl, Vec *vec) 157d71ae5a4SJacob Faibussowitsch { 158755f3dfbSVijay Mahadevan DM_Moab *dmbp, *dmbc; 159b117cd09SVijay Mahadevan moab::ErrorCode merr; 160e882eb38SVijay Mahadevan PetscInt dim; 1613f1c6e43SVijay Mahadevan PetscReal factor; 162ce27a4eeSVijay Mahadevan PetscInt innz, *nnz, ionz, *onz; 163755f3dfbSVijay Mahadevan PetscInt nlsizp, nlsizc, nlghsizp, ngsizp, ngsizc; 164a86ed394SVijay Mahadevan const PetscBool use_consistent_bases = PETSC_TRUE; 165b117cd09SVijay Mahadevan 166b117cd09SVijay Mahadevan PetscFunctionBegin; 167755f3dfbSVijay Mahadevan PetscValidHeaderSpecific(dmp, DM_CLASSID, 1); 168755f3dfbSVijay Mahadevan PetscValidHeaderSpecific(dmc, DM_CLASSID, 2); 169755f3dfbSVijay Mahadevan dmbp = (DM_Moab *)(dmp)->data; 170755f3dfbSVijay Mahadevan dmbc = (DM_Moab *)(dmc)->data; 171755f3dfbSVijay Mahadevan nlsizp = dmbp->nloc; // *dmb1->numFields; 172755f3dfbSVijay Mahadevan nlsizc = dmbc->nloc; // *dmb2->numFields; 173755f3dfbSVijay Mahadevan ngsizp = dmbp->n; // *dmb1->numFields; 174755f3dfbSVijay Mahadevan ngsizc = dmbc->n; // *dmb2->numFields; 175755f3dfbSVijay Mahadevan nlghsizp = (dmbp->nloc + dmbp->nghost); // *dmb1->numFields; 176b117cd09SVijay Mahadevan 1772417220eSVijay Mahadevan // Columns = Parent DoFs ; Rows = Child DoFs 178755f3dfbSVijay Mahadevan // Interpolation matrix: \sum_{i=1}^P Owned(Child) * (Owned(Parent) + Ghosted(Parent)) 179755f3dfbSVijay Mahadevan // Size: nlsizc * nlghsizp 18063a3b9bcSJacob Faibussowitsch PetscInfo(NULL, "Creating interpolation matrix %" PetscInt_FMT " X %" PetscInt_FMT " to apply transformation between levels %" PetscInt_FMT " -> %" PetscInt_FMT ".\n", ngsizc, nlghsizp, dmbp->hlevel, dmbc->hlevel); 181b117cd09SVijay Mahadevan 1829566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dmp, &dim)); 183a86ed394SVijay Mahadevan 184941e0cffSVijay Mahadevan /* allocate the nnz, onz arrays based on block size and local nodes */ 1859566063dSJacob Faibussowitsch PetscCall(PetscCalloc2(nlsizc, &nnz, nlsizc, &onz)); 186941e0cffSVijay Mahadevan 187941e0cffSVijay Mahadevan /* Loop through the local elements and compute the relation between the current parent and the refined_level. */ 1882417220eSVijay Mahadevan for (moab::Range::iterator iter = dmbc->vowned->begin(); iter != dmbc->vowned->end(); iter++) { 1892417220eSVijay Mahadevan const moab::EntityHandle vhandle = *iter; 1902417220eSVijay Mahadevan /* define local variables */ 1912417220eSVijay Mahadevan moab::EntityHandle parent; 1922417220eSVijay Mahadevan std::vector<moab::EntityHandle> adjs; 1932417220eSVijay Mahadevan moab::Range found; 1942417220eSVijay Mahadevan 1952417220eSVijay Mahadevan /* store the vertex DoF number */ 1962417220eSVijay Mahadevan const int ldof = dmbc->lidmap[vhandle - dmbc->seqstart]; 1972417220eSVijay Mahadevan 1982417220eSVijay Mahadevan /* Get adjacency information for current vertex - i.e., all elements of dimension (dim) that connects 1992417220eSVijay Mahadevan to the current vertex. We can then decipher if a vertex is ghosted or not and compute the 2002417220eSVijay Mahadevan non-zero pattern accordingly. */ 2019371c9d4SSatish Balay merr = dmbc->hierarchy->get_adjacencies(vhandle, dmbc->dim, adjs); 2029371c9d4SSatish Balay MBERRNM(merr); 2032417220eSVijay Mahadevan 2042417220eSVijay Mahadevan /* loop over vertices and update the number of connectivity */ 2052417220eSVijay Mahadevan for (unsigned jter = 0; jter < adjs.size(); jter++) { 2062417220eSVijay Mahadevan const moab::EntityHandle jhandle = adjs[jter]; 207941e0cffSVijay Mahadevan 208941e0cffSVijay Mahadevan /* Get the relation between the current (coarse) parent and its corresponding (finer) children elements */ 2099371c9d4SSatish Balay merr = dmbc->hierarchy->child_to_parent(jhandle, dmbc->hlevel, dmbp->hlevel, &parent); 2109371c9d4SSatish Balay MBERRNM(merr); 211941e0cffSVijay Mahadevan 2122417220eSVijay Mahadevan /* Get connectivity information in canonical ordering for the local element */ 2132417220eSVijay Mahadevan std::vector<moab::EntityHandle> connp; 2149371c9d4SSatish Balay merr = dmbp->hierarchy->get_connectivity(parent, dmbp->hlevel, connp); 2159371c9d4SSatish Balay MBERRNM(merr); 216a86ed394SVijay Mahadevan 2172417220eSVijay Mahadevan for (unsigned ic = 0; ic < connp.size(); ++ic) { 2182417220eSVijay Mahadevan /* loop over each element connected to the adjacent vertex and update as needed */ 2192417220eSVijay Mahadevan /* find the truly user-expected layer of ghosted entities to decipher NNZ pattern */ 2202417220eSVijay Mahadevan if (found.find(connp[ic]) != found.end()) continue; /* make sure we don't double count shared vertices */ 2212417220eSVijay Mahadevan if (dmbp->vghost->find(connp[ic]) != dmbp->vghost->end()) onz[ldof]++; /* update out-of-proc onz */ 2222417220eSVijay Mahadevan else nnz[ldof]++; /* else local vertex */ 2232417220eSVijay Mahadevan found.insert(connp[ic]); 2242417220eSVijay Mahadevan } 2252417220eSVijay Mahadevan } 226941e0cffSVijay Mahadevan } 227941e0cffSVijay Mahadevan 2289371c9d4SSatish Balay for (int i = 0; i < nlsizc; i++) nnz[i] += 1; /* self count the node */ 229941e0cffSVijay Mahadevan 230941e0cffSVijay Mahadevan ionz = onz[0]; 231941e0cffSVijay Mahadevan innz = nnz[0]; 232755f3dfbSVijay Mahadevan for (int tc = 0; tc < nlsizc; tc++) { 233941e0cffSVijay Mahadevan // check for maximum allowed sparsity = fully dense 234755f3dfbSVijay Mahadevan nnz[tc] = std::min(nlsizp, nnz[tc]); 2352417220eSVijay Mahadevan onz[tc] = std::min(ngsizp - nlsizp, onz[tc]); 2362417220eSVijay Mahadevan 2377d3de750SJacob Faibussowitsch PetscInfo(NULL, " %d: NNZ = %d, ONZ = %d\n", tc, nnz[tc], onz[tc]); 238941e0cffSVijay Mahadevan 239941e0cffSVijay Mahadevan innz = (innz < nnz[tc] ? nnz[tc] : innz); 240941e0cffSVijay Mahadevan ionz = (ionz < onz[tc] ? onz[tc] : ionz); 241941e0cffSVijay Mahadevan } 24264e1c140SVijay Mahadevan 24364e1c140SVijay Mahadevan /* create interpolation matrix */ 2449566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)dmc), interpl)); 2459566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*interpl, nlsizc, nlsizp, ngsizc, ngsizp)); 2469566063dSJacob Faibussowitsch PetscCall(MatSetType(*interpl, MATAIJ)); 2479566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(*interpl)); 24864e1c140SVijay Mahadevan 2499566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSetPreallocation(*interpl, innz, nnz)); 2509566063dSJacob Faibussowitsch PetscCall(MatMPIAIJSetPreallocation(*interpl, innz, nnz, ionz, onz)); 251941e0cffSVijay Mahadevan 252941e0cffSVijay Mahadevan /* clean up temporary memory */ 2539566063dSJacob Faibussowitsch PetscCall(PetscFree2(nnz, onz)); 254b117cd09SVijay Mahadevan 255b117cd09SVijay Mahadevan /* set up internal matrix data-structures */ 2569566063dSJacob Faibussowitsch PetscCall(MatSetUp(*interpl)); 257b117cd09SVijay Mahadevan 258a86ed394SVijay Mahadevan /* Define variables for assembly */ 259a86ed394SVijay Mahadevan std::vector<moab::EntityHandle> children; 260a86ed394SVijay Mahadevan std::vector<moab::EntityHandle> connp, connc; 261a86ed394SVijay Mahadevan std::vector<PetscReal> pcoords, ccoords, values_phi; 262a86ed394SVijay Mahadevan 263a86ed394SVijay Mahadevan if (use_consistent_bases) { 2642417220eSVijay Mahadevan const moab::EntityHandle ehandle = dmbp->elocal->front(); 265a86ed394SVijay Mahadevan 2669371c9d4SSatish Balay merr = dmbp->hierarchy->parent_to_child(ehandle, dmbp->hlevel, dmbc->hlevel, children); 2679371c9d4SSatish Balay MBERRNM(merr); 268a86ed394SVijay Mahadevan 269a86ed394SVijay Mahadevan /* Get connectivity and coordinates of the parent vertices */ 2709371c9d4SSatish Balay merr = dmbp->hierarchy->get_connectivity(ehandle, dmbp->hlevel, connp); 2719371c9d4SSatish Balay MBERRNM(merr); 2729371c9d4SSatish Balay merr = dmbc->mbiface->get_connectivity(&children[0], children.size(), connc); 2739371c9d4SSatish Balay MBERRNM(merr); 274a86ed394SVijay Mahadevan 275a86ed394SVijay Mahadevan std::vector<PetscReal> natparam(3 * connc.size(), 0.0); 276a86ed394SVijay Mahadevan pcoords.resize(connp.size() * 3); 277a86ed394SVijay Mahadevan ccoords.resize(connc.size() * 3); 278a86ed394SVijay Mahadevan values_phi.resize(connp.size() * connc.size()); 279a86ed394SVijay Mahadevan /* Get coordinates for connectivity entities in canonical order for both coarse and finer levels */ 2809371c9d4SSatish Balay merr = dmbp->hierarchy->get_coordinates(&connp[0], connp.size(), dmbp->hlevel, &pcoords[0]); 2819371c9d4SSatish Balay MBERRNM(merr); 2829371c9d4SSatish Balay merr = dmbc->hierarchy->get_coordinates(&connc[0], connc.size(), dmbc->hlevel, &ccoords[0]); 2839371c9d4SSatish Balay MBERRNM(merr); 284a86ed394SVijay Mahadevan 285a86ed394SVijay Mahadevan /* Set values: For each DOF in coarse grid cell, set the contribution or PHI evaluated at each fine grid DOF point */ 286a86ed394SVijay Mahadevan for (unsigned tc = 0; tc < connc.size(); tc++) { 287a86ed394SVijay Mahadevan const PetscInt offset = tc * 3; 288a86ed394SVijay Mahadevan 289a86ed394SVijay Mahadevan /* Scale ccoords relative to pcoords */ 2909566063dSJacob Faibussowitsch PetscCall(DMMoabPToRMapping(dim, connp.size(), &pcoords[0], &ccoords[offset], &natparam[offset], &values_phi[connp.size() * tc])); 291a86ed394SVijay Mahadevan } 2921baa6e33SBarry Smith } else { 293a86ed394SVijay Mahadevan factor = std::pow(2.0 /*degree_P_for_refinement*/, (dmbc->hlevel - dmbp->hlevel) * dmbp->dim * 1.0); 294a86ed394SVijay Mahadevan } 295a86ed394SVijay Mahadevan 296755f3dfbSVijay Mahadevan /* TODO: Decipher the correct non-zero pattern. There is still some issue with onz allocation */ 2979566063dSJacob Faibussowitsch PetscCall(MatSetOption(*interpl, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE)); 298b117cd09SVijay Mahadevan 299e882eb38SVijay Mahadevan /* Loop through the remaining vertices. These vertices appear only on the current refined_level. */ 3002417220eSVijay Mahadevan for (moab::Range::iterator iter = dmbp->elocal->begin(); iter != dmbp->elocal->end(); iter++) { 301b117cd09SVijay Mahadevan const moab::EntityHandle ehandle = *iter; 302b117cd09SVijay Mahadevan 303b117cd09SVijay Mahadevan /* Get the relation between the current (coarse) parent and its corresponding (finer) children elements */ 304a86ed394SVijay Mahadevan children.clear(); 305a86ed394SVijay Mahadevan connc.clear(); 3069371c9d4SSatish Balay merr = dmbp->hierarchy->parent_to_child(ehandle, dmbp->hlevel, dmbc->hlevel, children); 3079371c9d4SSatish Balay MBERRNM(merr); 308b117cd09SVijay Mahadevan 309b117cd09SVijay Mahadevan /* Get connectivity and coordinates of the parent vertices */ 3109371c9d4SSatish Balay merr = dmbp->hierarchy->get_connectivity(ehandle, dmbp->hlevel, connp); 3119371c9d4SSatish Balay MBERRNM(merr); 3129371c9d4SSatish Balay merr = dmbc->mbiface->get_connectivity(&children[0], children.size(), connc); 3139371c9d4SSatish Balay MBERRNM(merr); 314b117cd09SVijay Mahadevan 315a86ed394SVijay Mahadevan pcoords.resize(connp.size() * 3); 316a86ed394SVijay Mahadevan ccoords.resize(connc.size() * 3); 317b117cd09SVijay Mahadevan /* Get coordinates for connectivity entities in canonical order for both coarse and finer levels */ 3189371c9d4SSatish Balay merr = dmbp->hierarchy->get_coordinates(&connp[0], connp.size(), dmbp->hlevel, &pcoords[0]); 3199371c9d4SSatish Balay MBERRNM(merr); 3209371c9d4SSatish Balay merr = dmbc->hierarchy->get_coordinates(&connc[0], connc.size(), dmbc->hlevel, &ccoords[0]); 3219371c9d4SSatish Balay MBERRNM(merr); 322b117cd09SVijay Mahadevan 323b117cd09SVijay Mahadevan std::vector<int> dofsp(connp.size()), dofsc(connc.size()); 324b117cd09SVijay Mahadevan /* TODO: specific to scalar system - use GetDofs */ 3259566063dSJacob Faibussowitsch PetscCall(DMMoabGetDofsBlocked(dmp, connp.size(), &connp[0], &dofsp[0])); 3269566063dSJacob Faibussowitsch PetscCall(DMMoabGetDofsBlocked(dmc, connc.size(), &connc[0], &dofsc[0])); 327b117cd09SVijay Mahadevan 328a86ed394SVijay Mahadevan /* Compute the actual interpolation weights when projecting solution/residual between levels */ 329a86ed394SVijay Mahadevan if (use_consistent_bases) { 330a86ed394SVijay Mahadevan /* Use the cached values of natural parameteric coordinates and basis pre-evaluated. 331a86ed394SVijay Mahadevan We are making an assumption here that UMR used in GMG to generate the hierarchy uses 332a86ed394SVijay Mahadevan the same template for all elements; This will fail for mixed element meshes (TRI/QUAD). 333a86ed394SVijay Mahadevan 3342417220eSVijay Mahadevan TODO: Fix the above assumption by caching data for families (especially for Tets and mixed meshes) 335a86ed394SVijay Mahadevan */ 336a86ed394SVijay Mahadevan 337a86ed394SVijay Mahadevan /* Set values: For each DOF in coarse grid cell, set the contribution or PHI evaluated at each fine grid DOF point */ 338a86ed394SVijay Mahadevan for (unsigned tc = 0; tc < connc.size(); tc++) { 339a86ed394SVijay Mahadevan /* TODO: Check if we should be using INSERT_VALUES instead */ 3409566063dSJacob Faibussowitsch PetscCall(MatSetValues(*interpl, 1, &dofsc[tc], connp.size(), &dofsp[0], &values_phi[connp.size() * tc], ADD_VALUES)); 341a86ed394SVijay Mahadevan } 3421baa6e33SBarry Smith } else { 343e882eb38SVijay Mahadevan /* Compute the interpolation weights by determining distance of 1-ring 344755f3dfbSVijay Mahadevan neighbor vertices from current vertex 345755f3dfbSVijay Mahadevan 346a86ed394SVijay Mahadevan This should be used only when FEM basis is not used for the discretization. 347a86ed394SVijay Mahadevan Else, the consistent interface to compute the basis function for interpolation 348a86ed394SVijay Mahadevan between the levels should be evaluated correctly to preserve convergence of GMG. 3492417220eSVijay Mahadevan Shephard's basis will be terrible for any unsmooth problems. 350755f3dfbSVijay Mahadevan */ 351755f3dfbSVijay Mahadevan values_phi.resize(connp.size()); 352755f3dfbSVijay Mahadevan for (unsigned tc = 0; tc < connc.size(); tc++) { 353a86ed394SVijay Mahadevan PetscReal normsum = 0.0; 354755f3dfbSVijay Mahadevan for (unsigned tp = 0; tp < connp.size(); tp++) { 355755f3dfbSVijay Mahadevan values_phi[tp] = 0.0; 3569371c9d4SSatish Balay for (unsigned k = 0; k < 3; k++) values_phi[tp] += std::pow(pcoords[tp * 3 + k] - ccoords[k + tc * 3], dim); 357755f3dfbSVijay Mahadevan if (values_phi[tp] < 1e-12) { 358755f3dfbSVijay Mahadevan values_phi[tp] = 1e12; 3591baa6e33SBarry Smith } else { 360755f3dfbSVijay Mahadevan //values_phi[tp] = std::pow(values_phi[tp], -1.0/dim); 361755f3dfbSVijay Mahadevan values_phi[tp] = std::pow(values_phi[tp], -1.0); 362755f3dfbSVijay Mahadevan normsum += values_phi[tp]; 363b117cd09SVijay Mahadevan } 364b117cd09SVijay Mahadevan } 365755f3dfbSVijay Mahadevan for (unsigned tp = 0; tp < connp.size(); tp++) { 3669371c9d4SSatish Balay if (values_phi[tp] > 1e11) values_phi[tp] = factor * 0.5 / connp.size(); 3679371c9d4SSatish Balay else values_phi[tp] = factor * values_phi[tp] * 0.5 / (connp.size() * normsum); 368b117cd09SVijay Mahadevan } 3699566063dSJacob Faibussowitsch PetscCall(MatSetValues(*interpl, 1, &dofsc[tc], connp.size(), &dofsp[0], &values_phi[0], ADD_VALUES)); 370b117cd09SVijay Mahadevan } 371a86ed394SVijay Mahadevan } 372b117cd09SVijay Mahadevan } 373304006b3SVijay Mahadevan if (vec) *vec = NULL; 3749566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(*interpl, MAT_FINAL_ASSEMBLY)); 3759566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(*interpl, MAT_FINAL_ASSEMBLY)); 376b117cd09SVijay Mahadevan PetscFunctionReturn(0); 377b117cd09SVijay Mahadevan } 378b117cd09SVijay Mahadevan 379cab5ea25SPierre Jolivet /*@C 380b117cd09SVijay Mahadevan DMCreateInjection_Moab - Generate a multi-level uniform refinement hierarchy 381b117cd09SVijay Mahadevan by succesively refining a coarse mesh, already defined in the DM object 382b117cd09SVijay Mahadevan provided by the user. 383b117cd09SVijay Mahadevan 384d083f849SBarry Smith Collective 385b117cd09SVijay Mahadevan 386b117cd09SVijay Mahadevan Input Parameter: 387b117cd09SVijay Mahadevan . dmb - The DMMoab object 388b117cd09SVijay Mahadevan 389d8d19677SJose E. Roman Output Parameters: 390a2b725a8SWilliam Gropp + nlevels - The number of levels of refinement needed to generate the hierarchy 391a2b725a8SWilliam Gropp - ldegrees - The degree of refinement at each level in the hierarchy 392b117cd09SVijay Mahadevan 393b117cd09SVijay Mahadevan Level: beginner 394b117cd09SVijay Mahadevan 395b117cd09SVijay Mahadevan @*/ 396d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode DMCreateInjection_Moab(DM dm1, DM dm2, VecScatter *ctx) 397d71ae5a4SJacob Faibussowitsch { 398e882eb38SVijay Mahadevan //DM_Moab *dmmoab; 399b117cd09SVijay Mahadevan 400b117cd09SVijay Mahadevan PetscFunctionBegin; 401b117cd09SVijay Mahadevan PetscValidHeaderSpecific(dm1, DM_CLASSID, 1); 402b117cd09SVijay Mahadevan PetscValidHeaderSpecific(dm2, DM_CLASSID, 2); 403e882eb38SVijay Mahadevan //dmmoab = (DM_Moab*)(dm1)->data; 404b117cd09SVijay Mahadevan 405b117cd09SVijay Mahadevan PetscPrintf(PETSC_COMM_WORLD, "[DMCreateInjection_Moab] :: Placeholder\n"); 406b117cd09SVijay Mahadevan PetscFunctionReturn(0); 407b117cd09SVijay Mahadevan } 408b117cd09SVijay Mahadevan 409d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMMoab_UMR_Private(DM dm, MPI_Comm comm, PetscBool refine, DM *dmref) 410d71ae5a4SJacob Faibussowitsch { 411e882eb38SVijay Mahadevan PetscInt i, dim; 412b117cd09SVijay Mahadevan DM dm2; 413b117cd09SVijay Mahadevan moab::ErrorCode merr; 414b117cd09SVijay Mahadevan DM_Moab *dmb = (DM_Moab *)dm->data, *dd2; 415b117cd09SVijay Mahadevan 416b117cd09SVijay Mahadevan PetscFunctionBegin; 417b117cd09SVijay Mahadevan PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 418b117cd09SVijay Mahadevan PetscValidPointer(dmref, 4); 419b117cd09SVijay Mahadevan 420b117cd09SVijay Mahadevan if ((dmb->hlevel == dmb->nhlevels && refine) || (dmb->hlevel == 0 && !refine)) { 42163a3b9bcSJacob Faibussowitsch if (dmb->hlevel + 1 > dmb->nhlevels && refine) PetscInfo(NULL, "Invalid multigrid refinement hierarchy level specified (%" PetscInt_FMT "). MOAB UMR max levels = %" PetscInt_FMT ". Creating a NULL object.\n", dmb->hlevel + 1, dmb->nhlevels); 42263a3b9bcSJacob Faibussowitsch if (dmb->hlevel - 1 < 0 && !refine) PetscInfo(NULL, "Invalid multigrid coarsen hierarchy level specified (%" PetscInt_FMT "). Creating a NULL object.\n", dmb->hlevel - 1); 423*f3fa974cSJacob Faibussowitsch *dmref = NULL; 424b117cd09SVijay Mahadevan PetscFunctionReturn(0); 425b117cd09SVijay Mahadevan } 426b117cd09SVijay Mahadevan 4279566063dSJacob Faibussowitsch PetscCall(DMMoabCreate(PetscObjectComm((PetscObject)dm), &dm2)); 428b117cd09SVijay Mahadevan dd2 = (DM_Moab *)dm2->data; 429b117cd09SVijay Mahadevan 430b117cd09SVijay Mahadevan dd2->mbiface = dmb->mbiface; 4319daf19fdSVijay Mahadevan #ifdef MOAB_HAVE_MPI 432b117cd09SVijay Mahadevan dd2->pcomm = dmb->pcomm; 4339daf19fdSVijay Mahadevan #endif 434b117cd09SVijay Mahadevan dd2->icreatedinstance = PETSC_FALSE; 43564e1c140SVijay Mahadevan dd2->nghostrings = dmb->nghostrings; 436b117cd09SVijay Mahadevan 437b117cd09SVijay Mahadevan /* set the new level based on refinement/coarsening */ 438b117cd09SVijay Mahadevan if (refine) { 439b117cd09SVijay Mahadevan dd2->hlevel = dmb->hlevel + 1; 4401baa6e33SBarry Smith } else { 441b117cd09SVijay Mahadevan dd2->hlevel = dmb->hlevel - 1; 442b117cd09SVijay Mahadevan } 443b117cd09SVijay Mahadevan 444b117cd09SVijay Mahadevan /* Copy the multilevel hierarchy pointers in MOAB */ 445b117cd09SVijay Mahadevan dd2->hierarchy = dmb->hierarchy; 446b117cd09SVijay Mahadevan dd2->nhlevels = dmb->nhlevels; 4479566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(dd2->nhlevels + 1, &dd2->hsets)); 448ad540459SPierre Jolivet for (i = 0; i <= dd2->nhlevels; i++) dd2->hsets[i] = dmb->hsets[i]; 449b117cd09SVijay Mahadevan dd2->fileset = dd2->hsets[dd2->hlevel]; 450b117cd09SVijay Mahadevan 451b117cd09SVijay Mahadevan /* do the remaining initializations for DMMoab */ 452b117cd09SVijay Mahadevan dd2->bs = dmb->bs; 453b117cd09SVijay Mahadevan dd2->numFields = dmb->numFields; 454b117cd09SVijay Mahadevan dd2->rw_dbglevel = dmb->rw_dbglevel; 455b117cd09SVijay Mahadevan dd2->partition_by_rank = dmb->partition_by_rank; 4569566063dSJacob Faibussowitsch PetscCall(PetscStrcpy(dd2->extra_read_options, dmb->extra_read_options)); 4579566063dSJacob Faibussowitsch PetscCall(PetscStrcpy(dd2->extra_write_options, dmb->extra_write_options)); 458b117cd09SVijay Mahadevan dd2->read_mode = dmb->read_mode; 459b117cd09SVijay Mahadevan dd2->write_mode = dmb->write_mode; 460b117cd09SVijay Mahadevan 461b117cd09SVijay Mahadevan /* set global ID tag handle */ 4629566063dSJacob Faibussowitsch PetscCall(DMMoabSetLocalToGlobalTag(dm2, dmb->ltog_tag)); 463b117cd09SVijay Mahadevan 4649371c9d4SSatish Balay merr = dd2->mbiface->tag_get_handle(MATERIAL_SET_TAG_NAME, dd2->material_tag); 4659371c9d4SSatish Balay MBERRNM(merr); 466b117cd09SVijay Mahadevan 4679566063dSJacob Faibussowitsch PetscCall(DMSetOptionsPrefix(dm2, ((PetscObject)dm)->prefix)); 4689566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 4699566063dSJacob Faibussowitsch PetscCall(DMSetDimension(dm2, dim)); 470b117cd09SVijay Mahadevan 471b117cd09SVijay Mahadevan /* allow overloaded (user replaced) operations to be inherited by refinement clones */ 472b117cd09SVijay Mahadevan dm2->ops->creatematrix = dm->ops->creatematrix; 473b117cd09SVijay Mahadevan 474b117cd09SVijay Mahadevan /* copy fill information if given */ 4759566063dSJacob Faibussowitsch PetscCall(DMMoabSetBlockFills(dm2, dmb->dfill, dmb->ofill)); 476b117cd09SVijay Mahadevan 477b117cd09SVijay Mahadevan /* copy vector type information */ 4789566063dSJacob Faibussowitsch PetscCall(DMSetMatType(dm2, dm->mattype)); 4799566063dSJacob Faibussowitsch PetscCall(DMSetVecType(dm2, dm->vectype)); 4803f1c6e43SVijay Mahadevan dd2->numFields = dmb->numFields; 48148a46eb9SPierre Jolivet if (dmb->numFields) PetscCall(DMMoabSetFieldNames(dm2, dmb->numFields, dmb->fieldNames)); 482b117cd09SVijay Mahadevan 4839566063dSJacob Faibussowitsch PetscCall(DMSetFromOptions(dm2)); 484b117cd09SVijay Mahadevan 485b117cd09SVijay Mahadevan /* recreate Dof numbering for the refined DM and make sure the distribution is correctly populated */ 4869566063dSJacob Faibussowitsch PetscCall(DMSetUp(dm2)); 487b117cd09SVijay Mahadevan 488b117cd09SVijay Mahadevan *dmref = dm2; 489b117cd09SVijay Mahadevan PetscFunctionReturn(0); 490b117cd09SVijay Mahadevan } 491b117cd09SVijay Mahadevan 492cab5ea25SPierre Jolivet /*@C 493b117cd09SVijay Mahadevan DMRefine_Moab - Generate a multi-level uniform refinement hierarchy 494b117cd09SVijay Mahadevan by succesively refining a coarse mesh, already defined in the DM object 495b117cd09SVijay Mahadevan provided by the user. 496b117cd09SVijay Mahadevan 497d083f849SBarry Smith Collective on dm 498b117cd09SVijay Mahadevan 499d8d19677SJose E. Roman Input Parameters: 500e882eb38SVijay Mahadevan + dm - The DMMoab object 501e882eb38SVijay Mahadevan - comm - the communicator to contain the new DM object (or MPI_COMM_NULL) 502b117cd09SVijay Mahadevan 503b117cd09SVijay Mahadevan Output Parameter: 504e882eb38SVijay Mahadevan . dmf - the refined DM, or NULL 505b117cd09SVijay Mahadevan 506e882eb38SVijay Mahadevan Note: If no refinement was done, the return value is NULL 507e882eb38SVijay Mahadevan 508e882eb38SVijay Mahadevan Level: developer 509b117cd09SVijay Mahadevan 510b117cd09SVijay Mahadevan @*/ 511d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode DMRefine_Moab(DM dm, MPI_Comm comm, DM *dmf) 512d71ae5a4SJacob Faibussowitsch { 513b117cd09SVijay Mahadevan PetscFunctionBegin; 514b117cd09SVijay Mahadevan PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 515b117cd09SVijay Mahadevan 5169566063dSJacob Faibussowitsch PetscCall(DMMoab_UMR_Private(dm, comm, PETSC_TRUE, dmf)); 517b117cd09SVijay Mahadevan PetscFunctionReturn(0); 518b117cd09SVijay Mahadevan } 519b117cd09SVijay Mahadevan 520cab5ea25SPierre Jolivet /*@C 521b117cd09SVijay Mahadevan DMCoarsen_Moab - Generate a multi-level uniform refinement hierarchy 522b117cd09SVijay Mahadevan by succesively refining a coarse mesh, already defined in the DM object 523b117cd09SVijay Mahadevan provided by the user. 524b117cd09SVijay Mahadevan 525d083f849SBarry Smith Collective on dm 526b117cd09SVijay Mahadevan 527d8d19677SJose E. Roman Input Parameters: 528a2b725a8SWilliam Gropp + dm - The DMMoab object 529e882eb38SVijay Mahadevan - comm - the communicator to contain the new DM object (or MPI_COMM_NULL) 530b117cd09SVijay Mahadevan 531b117cd09SVijay Mahadevan Output Parameter: 532e882eb38SVijay Mahadevan . dmf - the coarsened DM, or NULL 533b117cd09SVijay Mahadevan 534e882eb38SVijay Mahadevan Note: If no coarsening was done, the return value is NULL 535b117cd09SVijay Mahadevan 536e882eb38SVijay Mahadevan Level: developer 537e882eb38SVijay Mahadevan 538b117cd09SVijay Mahadevan @*/ 539d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode DMCoarsen_Moab(DM dm, MPI_Comm comm, DM *dmc) 540d71ae5a4SJacob Faibussowitsch { 541b117cd09SVijay Mahadevan PetscFunctionBegin; 542b117cd09SVijay Mahadevan PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5439566063dSJacob Faibussowitsch PetscCall(DMMoab_UMR_Private(dm, comm, PETSC_FALSE, dmc)); 544b117cd09SVijay Mahadevan PetscFunctionReturn(0); 545b117cd09SVijay Mahadevan } 546