1af0996ceSBarry Smith #include <petsc/private/dmpleximpl.h> /*I "petscdmplex.h" I*/ 2af0996ceSBarry Smith #include <petsc/private/isimpl.h> 3e5c6e791SKarl Rupp #include <petsc/private/vecimpl.h> 48135c375SStefano Zampini #include <petsc/private/glvisvecimpl.h> 50c312b8eSJed Brown #include <petscsf.h> 6e228b242SToby Isaac #include <petscds.h> 7e412dcbdSMatthew G. Knepley #include <petscdraw.h> 8f19dbd58SToby Isaac #include <petscdmfield.h> 9552f7358SJed Brown 10552f7358SJed Brown /* Logging support */ 1141525646SFlorian Wechsung PetscLogEvent DMPLEX_Interpolate, DMPLEX_Partition, DMPLEX_Distribute, DMPLEX_DistributeCones, DMPLEX_DistributeLabels, DMPLEX_DistributeSF, DMPLEX_DistributeOverlap, DMPLEX_DistributeField, DMPLEX_DistributeData, DMPLEX_Migrate, DMPLEX_InterpolateSF, DMPLEX_GlobalToNaturalBegin, DMPLEX_GlobalToNaturalEnd, DMPLEX_NaturalToGlobalBegin, DMPLEX_NaturalToGlobalEnd, DMPLEX_Stratify, DMPLEX_Preallocate, DMPLEX_ResidualFEM, DMPLEX_JacobianFEM, DMPLEX_InterpolatorFEM, DMPLEX_InjectorFEM, DMPLEX_IntegralFEM, DMPLEX_CreateGmsh, DMPLEX_RebalanceSharedPoints; 12552f7358SJed Brown 135a576424SJed Brown PETSC_EXTERN PetscErrorCode VecView_MPI(Vec, PetscViewer); 14552f7358SJed Brown 15e5337592SStefano Zampini /*@ 16e5337592SStefano Zampini DMPlexRefineSimplexToTensor - Uniformly refines simplicial cells into tensor product cells. 17e5337592SStefano Zampini 3 quadrilaterals per triangle in 2D and 4 hexahedra per tetrahedron in 3D. 18e5337592SStefano Zampini 19e5337592SStefano Zampini Collective 20e5337592SStefano Zampini 21e5337592SStefano Zampini Input Parameters: 22e5337592SStefano Zampini . dm - The DMPlex object 23e5337592SStefano Zampini 24e5337592SStefano Zampini Output Parameters: 25e5337592SStefano Zampini . dmRefined - The refined DMPlex object 26e5337592SStefano Zampini 27e5337592SStefano Zampini Note: Returns NULL if the mesh is already a tensor product mesh. 28e5337592SStefano Zampini 29e5337592SStefano Zampini Level: intermediate 30e5337592SStefano Zampini 31e5337592SStefano Zampini .seealso: DMPlexCreate(), DMPlexSetRefinementUniform() 32e5337592SStefano Zampini @*/ 33e5337592SStefano Zampini PetscErrorCode DMPlexRefineSimplexToTensor(DM dm, DM *dmRefined) 34e5337592SStefano Zampini { 35e5337592SStefano Zampini PetscInt dim, cMax, fMax, cStart, cEnd, coneSize; 36e5337592SStefano Zampini CellRefiner cellRefiner; 37e5337592SStefano Zampini PetscBool lop, allnoop, localized; 38e5337592SStefano Zampini PetscErrorCode ierr; 39e5337592SStefano Zampini 40e5337592SStefano Zampini PetscFunctionBegin; 41e5337592SStefano Zampini PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 424330a3fcSStefano Zampini PetscValidPointer(dmRefined, 1); 43e5337592SStefano Zampini ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 44e5337592SStefano Zampini ierr = DMPlexGetHybridBounds(dm,&cMax,&fMax,NULL,NULL);CHKERRQ(ierr); 45e5337592SStefano Zampini ierr = DMPlexGetHeightStratum(dm,0,&cStart,&cEnd);CHKERRQ(ierr); 46e5337592SStefano Zampini if (!(cEnd - cStart)) cellRefiner = REFINER_NOOP; 47e5337592SStefano Zampini else { 48e5337592SStefano Zampini ierr = DMPlexGetConeSize(dm,cStart,&coneSize);CHKERRQ(ierr); 49e5337592SStefano Zampini switch (dim) { 50e5337592SStefano Zampini case 1: 51e5337592SStefano Zampini cellRefiner = REFINER_NOOP; 52e5337592SStefano Zampini break; 53e5337592SStefano Zampini case 2: 54e5337592SStefano Zampini switch (coneSize) { 55e5337592SStefano Zampini case 3: 564330a3fcSStefano Zampini if (cMax >= 0) cellRefiner = REFINER_HYBRID_SIMPLEX_TO_HEX_2D; 574330a3fcSStefano Zampini else cellRefiner = REFINER_SIMPLEX_TO_HEX_2D; 58e5337592SStefano Zampini break; 59e5337592SStefano Zampini case 4: 604330a3fcSStefano Zampini if (cMax >= 0) cellRefiner = REFINER_HYBRID_SIMPLEX_TO_HEX_2D; 614330a3fcSStefano Zampini else cellRefiner = REFINER_NOOP; 62e5337592SStefano Zampini break; 63e5337592SStefano Zampini default: SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot handle coneSize %D with dimension %D",coneSize,dim); 64e5337592SStefano Zampini } 65e5337592SStefano Zampini break; 66e5337592SStefano Zampini case 3: 67e5337592SStefano Zampini switch (coneSize) { 68e5337592SStefano Zampini case 4: 694330a3fcSStefano Zampini if (cMax >= 0) cellRefiner = REFINER_HYBRID_SIMPLEX_TO_HEX_3D; 704330a3fcSStefano Zampini else cellRefiner = REFINER_SIMPLEX_TO_HEX_3D; 714330a3fcSStefano Zampini break; 724330a3fcSStefano Zampini case 5: 734330a3fcSStefano Zampini if (cMax >= 0) cellRefiner = REFINER_HYBRID_SIMPLEX_TO_HEX_3D; 744330a3fcSStefano Zampini else cellRefiner = REFINER_NOOP; 75e5337592SStefano Zampini break; 76e5337592SStefano Zampini case 6: 774330a3fcSStefano Zampini if (cMax >= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Simplex2Tensor in 3D with Hybrid mesh not yet done"); 78e5337592SStefano Zampini cellRefiner = REFINER_NOOP; 79e5337592SStefano Zampini break; 80e5337592SStefano Zampini default: SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot handle coneSize %D with dimension %D",coneSize,dim); 81e5337592SStefano Zampini } 82e5337592SStefano Zampini break; 83e5337592SStefano Zampini default: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot handle dimension %D",dim); 84e5337592SStefano Zampini } 85e5337592SStefano Zampini } 86e5337592SStefano Zampini /* return if we don't need to refine */ 87e5337592SStefano Zampini lop = (cellRefiner == REFINER_NOOP) ? PETSC_TRUE : PETSC_FALSE; 88e5337592SStefano Zampini ierr = MPIU_Allreduce(&lop,&allnoop,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 89e5337592SStefano Zampini if (allnoop) { 90e5337592SStefano Zampini *dmRefined = NULL; 91e5337592SStefano Zampini PetscFunctionReturn(0); 92e5337592SStefano Zampini } 93e5337592SStefano Zampini ierr = DMPlexRefineUniform_Internal(dm, cellRefiner, dmRefined);CHKERRQ(ierr); 94e5337592SStefano Zampini ierr = DMCopyBoundary(dm, *dmRefined);CHKERRQ(ierr); 95e5337592SStefano Zampini ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 96e5337592SStefano Zampini if (localized) { 97e5337592SStefano Zampini ierr = DMLocalizeCoordinates(*dmRefined);CHKERRQ(ierr); 98e5337592SStefano Zampini } 99e5337592SStefano Zampini PetscFunctionReturn(0); 100e5337592SStefano Zampini } 101e5337592SStefano Zampini 1027afe7537SMatthew G. Knepley PetscErrorCode DMPlexGetFieldType_Internal(DM dm, PetscSection section, PetscInt field, PetscInt *sStart, PetscInt *sEnd, PetscViewerVTKFieldType *ft) 1037e42fee7SMatthew G. Knepley { 104a99a26bcSAdrian Croucher PetscInt dim, pStart, pEnd, vStart, vEnd, cStart, cEnd, cEndInterior; 105a99a26bcSAdrian Croucher PetscInt vcdof[2] = {0,0}, globalvcdof[2]; 1067e42fee7SMatthew G. Knepley PetscErrorCode ierr; 1077e42fee7SMatthew G. Knepley 1087e42fee7SMatthew G. Knepley PetscFunctionBegin; 1097e42fee7SMatthew G. Knepley *ft = PETSC_VTK_POINT_FIELD; 110c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 1117e42fee7SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 1127e42fee7SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 11380d5bdc6SMatthew G. Knepley ierr = DMPlexGetHybridBounds(dm, &cEndInterior, NULL, NULL, NULL);CHKERRQ(ierr); 11480d5bdc6SMatthew G. Knepley cEnd = cEndInterior < 0 ? cEnd : cEndInterior; 1157e42fee7SMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 1167e42fee7SMatthew G. Knepley if (field >= 0) { 117a99a26bcSAdrian Croucher if ((vStart >= pStart) && (vStart < pEnd)) {ierr = PetscSectionGetFieldDof(section, vStart, field, &vcdof[0]);CHKERRQ(ierr);} 118a99a26bcSAdrian Croucher if ((cStart >= pStart) && (cStart < pEnd)) {ierr = PetscSectionGetFieldDof(section, cStart, field, &vcdof[1]);CHKERRQ(ierr);} 1197e42fee7SMatthew G. Knepley } else { 120a99a26bcSAdrian Croucher if ((vStart >= pStart) && (vStart < pEnd)) {ierr = PetscSectionGetDof(section, vStart, &vcdof[0]);CHKERRQ(ierr);} 121a99a26bcSAdrian Croucher if ((cStart >= pStart) && (cStart < pEnd)) {ierr = PetscSectionGetDof(section, cStart, &vcdof[1]);CHKERRQ(ierr);} 1227e42fee7SMatthew G. Knepley } 1235483465cSMatthew G. Knepley ierr = MPI_Allreduce(vcdof, globalvcdof, 2, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 124a99a26bcSAdrian Croucher if (globalvcdof[0]) { 1257e42fee7SMatthew G. Knepley *sStart = vStart; 1267e42fee7SMatthew G. Knepley *sEnd = vEnd; 127a99a26bcSAdrian Croucher if (globalvcdof[0] == dim) *ft = PETSC_VTK_POINT_VECTOR_FIELD; 1287e42fee7SMatthew G. Knepley else *ft = PETSC_VTK_POINT_FIELD; 129a99a26bcSAdrian Croucher } else if (globalvcdof[1]) { 1307e42fee7SMatthew G. Knepley *sStart = cStart; 1317e42fee7SMatthew G. Knepley *sEnd = cEnd; 132a99a26bcSAdrian Croucher if (globalvcdof[1] == dim) *ft = PETSC_VTK_CELL_VECTOR_FIELD; 1337e42fee7SMatthew G. Knepley else *ft = PETSC_VTK_CELL_FIELD; 1347e42fee7SMatthew G. Knepley } else SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Could not classify input Vec for VTK"); 1357e42fee7SMatthew G. Knepley PetscFunctionReturn(0); 1367e42fee7SMatthew G. Knepley } 1377e42fee7SMatthew G. Knepley 1387cd05799SMatthew G. Knepley static PetscErrorCode VecView_Plex_Local_Draw(Vec v, PetscViewer viewer) 139e412dcbdSMatthew G. Knepley { 140e412dcbdSMatthew G. Knepley DM dm; 141d1df6f1dSMatthew G. Knepley PetscSection s; 142e412dcbdSMatthew G. Knepley PetscDraw draw, popup; 143e412dcbdSMatthew G. Knepley DM cdm; 144e412dcbdSMatthew G. Knepley PetscSection coordSection; 145e412dcbdSMatthew G. Knepley Vec coordinates; 146e412dcbdSMatthew G. Knepley const PetscScalar *coords, *array; 147e412dcbdSMatthew G. Knepley PetscReal bound[4] = {PETSC_MAX_REAL, PETSC_MAX_REAL, PETSC_MIN_REAL, PETSC_MIN_REAL}; 148339e3443SMatthew G. Knepley PetscReal vbound[2], time; 149339e3443SMatthew G. Knepley PetscBool isnull, flg; 150d1df6f1dSMatthew G. Knepley PetscInt dim, Nf, f, Nc, comp, vStart, vEnd, cStart, cEnd, c, N, level, step, w = 0; 151e412dcbdSMatthew G. Knepley const char *name; 152339e3443SMatthew G. Knepley char title[PETSC_MAX_PATH_LEN]; 153e412dcbdSMatthew G. Knepley PetscErrorCode ierr; 154e412dcbdSMatthew G. Knepley 155e412dcbdSMatthew G. Knepley PetscFunctionBegin; 156d1df6f1dSMatthew G. Knepley ierr = PetscViewerDrawGetDraw(viewer, 0, &draw);CHKERRQ(ierr); 157d1df6f1dSMatthew G. Knepley ierr = PetscDrawIsNull(draw, &isnull);CHKERRQ(ierr); 158d1df6f1dSMatthew G. Knepley if (isnull) PetscFunctionReturn(0); 159d1df6f1dSMatthew G. Knepley 160e412dcbdSMatthew G. Knepley ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 161e412dcbdSMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dim);CHKERRQ(ierr); 1628135c375SStefano Zampini if (dim != 2) SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Cannot draw meshes of dimension %D. Use PETSCVIEWERGLVIS", dim); 163e87a4003SBarry Smith ierr = DMGetSection(dm, &s);CHKERRQ(ierr); 164d1df6f1dSMatthew G. Knepley ierr = PetscSectionGetNumFields(s, &Nf);CHKERRQ(ierr); 165e412dcbdSMatthew G. Knepley ierr = DMGetCoarsenLevel(dm, &level);CHKERRQ(ierr); 166e412dcbdSMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 167e87a4003SBarry Smith ierr = DMGetSection(cdm, &coordSection);CHKERRQ(ierr); 168e412dcbdSMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 169e412dcbdSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 170e412dcbdSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 171e412dcbdSMatthew G. Knepley 172e412dcbdSMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) v, &name);CHKERRQ(ierr); 173339e3443SMatthew G. Knepley ierr = DMGetOutputSequenceNumber(dm, &step, &time);CHKERRQ(ierr); 174e412dcbdSMatthew G. Knepley 175e412dcbdSMatthew G. Knepley ierr = VecGetLocalSize(coordinates, &N);CHKERRQ(ierr); 176e412dcbdSMatthew G. Knepley ierr = VecGetArrayRead(coordinates, &coords);CHKERRQ(ierr); 177e412dcbdSMatthew G. Knepley for (c = 0; c < N; c += dim) { 1780c81f2a8SMatthew G. Knepley bound[0] = PetscMin(bound[0], PetscRealPart(coords[c])); bound[2] = PetscMax(bound[2], PetscRealPart(coords[c])); 1790c81f2a8SMatthew G. Knepley bound[1] = PetscMin(bound[1], PetscRealPart(coords[c+1])); bound[3] = PetscMax(bound[3], PetscRealPart(coords[c+1])); 180e412dcbdSMatthew G. Knepley } 181e412dcbdSMatthew G. Knepley ierr = VecRestoreArrayRead(coordinates, &coords);CHKERRQ(ierr); 182e412dcbdSMatthew G. Knepley ierr = PetscDrawClear(draw);CHKERRQ(ierr); 183e412dcbdSMatthew G. Knepley 184d1df6f1dSMatthew G. Knepley /* Could implement something like DMDASelectFields() */ 185d1df6f1dSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 186d1df6f1dSMatthew G. Knepley DM fdm = dm; 187d1df6f1dSMatthew G. Knepley Vec fv = v; 188d1df6f1dSMatthew G. Knepley IS fis; 189d1df6f1dSMatthew G. Knepley char prefix[PETSC_MAX_PATH_LEN]; 190d1df6f1dSMatthew G. Knepley const char *fname; 191d1df6f1dSMatthew G. Knepley 192d1df6f1dSMatthew G. Knepley ierr = PetscSectionGetFieldComponents(s, f, &Nc);CHKERRQ(ierr); 193d1df6f1dSMatthew G. Knepley ierr = PetscSectionGetFieldName(s, f, &fname);CHKERRQ(ierr); 194d1df6f1dSMatthew G. Knepley 195a126751eSBarry Smith if (v->hdr.prefix) {ierr = PetscStrncpy(prefix, v->hdr.prefix,sizeof(prefix));CHKERRQ(ierr);} 196d1df6f1dSMatthew G. Knepley else {prefix[0] = '\0';} 197d1df6f1dSMatthew G. Knepley if (Nf > 1) { 198d1df6f1dSMatthew G. Knepley ierr = DMCreateSubDM(dm, 1, &f, &fis, &fdm);CHKERRQ(ierr); 199d1df6f1dSMatthew G. Knepley ierr = VecGetSubVector(v, fis, &fv);CHKERRQ(ierr); 200a126751eSBarry Smith ierr = PetscStrlcat(prefix, fname,sizeof(prefix));CHKERRQ(ierr); 201a126751eSBarry Smith ierr = PetscStrlcat(prefix, "_",sizeof(prefix));CHKERRQ(ierr); 202d1df6f1dSMatthew G. Knepley } 203d1df6f1dSMatthew G. Knepley for (comp = 0; comp < Nc; ++comp, ++w) { 204d1df6f1dSMatthew G. Knepley PetscInt nmax = 2; 205d1df6f1dSMatthew G. Knepley 206d1df6f1dSMatthew G. Knepley ierr = PetscViewerDrawGetDraw(viewer, w, &draw);CHKERRQ(ierr); 207d1df6f1dSMatthew G. Knepley if (Nc > 1) {ierr = PetscSNPrintf(title, sizeof(title), "%s:%s_%D Step: %D Time: %.4g", name, fname, comp, step, time);CHKERRQ(ierr);} 208d1df6f1dSMatthew G. Knepley else {ierr = PetscSNPrintf(title, sizeof(title), "%s:%s Step: %D Time: %.4g", name, fname, step, time);CHKERRQ(ierr);} 209d1df6f1dSMatthew G. Knepley ierr = PetscDrawSetTitle(draw, title);CHKERRQ(ierr); 210d1df6f1dSMatthew G. Knepley 211d1df6f1dSMatthew G. Knepley /* TODO Get max and min only for this component */ 212d1df6f1dSMatthew G. Knepley ierr = PetscOptionsGetRealArray(NULL, prefix, "-vec_view_bounds", vbound, &nmax, &flg);CHKERRQ(ierr); 213339e3443SMatthew G. Knepley if (!flg) { 214d1df6f1dSMatthew G. Knepley ierr = VecMin(fv, NULL, &vbound[0]);CHKERRQ(ierr); 215d1df6f1dSMatthew G. Knepley ierr = VecMax(fv, NULL, &vbound[1]);CHKERRQ(ierr); 216d1df6f1dSMatthew G. Knepley if (vbound[1] <= vbound[0]) vbound[1] = vbound[0] + 1.0; 217339e3443SMatthew G. Knepley } 218e412dcbdSMatthew G. Knepley ierr = PetscDrawGetPopup(draw, &popup);CHKERRQ(ierr); 219339e3443SMatthew G. Knepley ierr = PetscDrawScalePopup(popup, vbound[0], vbound[1]);CHKERRQ(ierr); 220d1df6f1dSMatthew G. Knepley ierr = PetscDrawSetCoordinates(draw, bound[0], bound[1], bound[2], bound[3]);CHKERRQ(ierr); 221e412dcbdSMatthew G. Knepley 222d1df6f1dSMatthew G. Knepley ierr = VecGetArrayRead(fv, &array);CHKERRQ(ierr); 223e412dcbdSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 22499a2f7bcSMatthew G. Knepley PetscScalar *coords = NULL, *a = NULL; 225e56f9228SJed Brown PetscInt numCoords, color[4] = {-1,-1,-1,-1}; 226e412dcbdSMatthew G. Knepley 227d1df6f1dSMatthew G. Knepley ierr = DMPlexPointLocalRead(fdm, c, array, &a);CHKERRQ(ierr); 228339e3443SMatthew G. Knepley if (a) { 229d1df6f1dSMatthew G. Knepley color[0] = PetscDrawRealToColor(PetscRealPart(a[comp]), vbound[0], vbound[1]); 230339e3443SMatthew G. Knepley color[1] = color[2] = color[3] = color[0]; 231339e3443SMatthew G. Knepley } else { 232339e3443SMatthew G. Knepley PetscScalar *vals = NULL; 233339e3443SMatthew G. Knepley PetscInt numVals, va; 234339e3443SMatthew G. Knepley 235d1df6f1dSMatthew G. Knepley ierr = DMPlexVecGetClosure(fdm, NULL, fv, c, &numVals, &vals);CHKERRQ(ierr); 236d1df6f1dSMatthew G. Knepley if (numVals % Nc) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "The number of components %D does not divide the number of values in the closure %D", Nc, numVals); 237d1df6f1dSMatthew G. Knepley switch (numVals/Nc) { 238d1df6f1dSMatthew G. Knepley case 3: /* P1 Triangle */ 239d1df6f1dSMatthew G. Knepley case 4: /* P1 Quadrangle */ 240d1df6f1dSMatthew G. Knepley for (va = 0; va < numVals/Nc; ++va) color[va] = PetscDrawRealToColor(PetscRealPart(vals[va*Nc+comp]), vbound[0], vbound[1]); 241339e3443SMatthew G. Knepley break; 242d1df6f1dSMatthew G. Knepley case 6: /* P2 Triangle */ 243d1df6f1dSMatthew G. Knepley case 8: /* P2 Quadrangle */ 244d1df6f1dSMatthew G. Knepley for (va = 0; va < numVals/(Nc*2); ++va) color[va] = PetscDrawRealToColor(PetscRealPart(vals[va*Nc+comp + numVals/(Nc*2)]), vbound[0], vbound[1]); 245d1df6f1dSMatthew G. Knepley break; 246d1df6f1dSMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Number of values for cell closure %D cannot be handled", numVals/Nc); 247339e3443SMatthew G. Knepley } 248d1df6f1dSMatthew G. Knepley ierr = DMPlexVecRestoreClosure(fdm, NULL, fv, c, &numVals, &vals);CHKERRQ(ierr); 249339e3443SMatthew G. Knepley } 250e412dcbdSMatthew G. Knepley ierr = DMPlexVecGetClosure(dm, coordSection, coordinates, c, &numCoords, &coords);CHKERRQ(ierr); 251e412dcbdSMatthew G. Knepley switch (numCoords) { 252e412dcbdSMatthew G. Knepley case 6: 253339e3443SMatthew G. Knepley ierr = PetscDrawTriangle(draw, PetscRealPart(coords[0]), PetscRealPart(coords[1]), PetscRealPart(coords[2]), PetscRealPart(coords[3]), PetscRealPart(coords[4]), PetscRealPart(coords[5]), color[0], color[1], color[2]);CHKERRQ(ierr); 254e412dcbdSMatthew G. Knepley break; 255e412dcbdSMatthew G. Knepley case 8: 256339e3443SMatthew G. Knepley ierr = PetscDrawTriangle(draw, PetscRealPart(coords[0]), PetscRealPart(coords[1]), PetscRealPart(coords[2]), PetscRealPart(coords[3]), PetscRealPart(coords[4]), PetscRealPart(coords[5]), color[0], color[1], color[2]);CHKERRQ(ierr); 257339e3443SMatthew G. Knepley ierr = PetscDrawTriangle(draw, PetscRealPart(coords[4]), PetscRealPart(coords[5]), PetscRealPart(coords[6]), PetscRealPart(coords[7]), PetscRealPart(coords[0]), PetscRealPart(coords[1]), color[2], color[3], color[0]);CHKERRQ(ierr); 258e412dcbdSMatthew G. Knepley break; 259e412dcbdSMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot draw cells with %D coordinates", numCoords); 260e412dcbdSMatthew G. Knepley } 261e412dcbdSMatthew G. Knepley ierr = DMPlexVecRestoreClosure(dm, coordSection, coordinates, c, &numCoords, &coords);CHKERRQ(ierr); 262e412dcbdSMatthew G. Knepley } 263d1df6f1dSMatthew G. Knepley ierr = VecRestoreArrayRead(fv, &array);CHKERRQ(ierr); 264e412dcbdSMatthew G. Knepley ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 265e412dcbdSMatthew G. Knepley ierr = PetscDrawPause(draw);CHKERRQ(ierr); 266e412dcbdSMatthew G. Knepley ierr = PetscDrawSave(draw);CHKERRQ(ierr); 267d1df6f1dSMatthew G. Knepley } 268d1df6f1dSMatthew G. Knepley if (Nf > 1) { 269d1df6f1dSMatthew G. Knepley ierr = VecRestoreSubVector(v, fis, &fv);CHKERRQ(ierr); 270d1df6f1dSMatthew G. Knepley ierr = ISDestroy(&fis);CHKERRQ(ierr); 271d1df6f1dSMatthew G. Knepley ierr = DMDestroy(&fdm);CHKERRQ(ierr); 272d1df6f1dSMatthew G. Knepley } 273d1df6f1dSMatthew G. Knepley } 274e412dcbdSMatthew G. Knepley PetscFunctionReturn(0); 275e412dcbdSMatthew G. Knepley } 276e412dcbdSMatthew G. Knepley 277684b87d9SLisandro Dalcin static PetscErrorCode VecView_Plex_Local_VTK(Vec v, PetscViewer viewer) 278684b87d9SLisandro Dalcin { 279684b87d9SLisandro Dalcin DM dm; 280684b87d9SLisandro Dalcin Vec locv; 281684b87d9SLisandro Dalcin const char *name; 282684b87d9SLisandro Dalcin PetscSection section; 283684b87d9SLisandro Dalcin PetscInt pStart, pEnd; 284684b87d9SLisandro Dalcin PetscViewerVTKFieldType ft; 285684b87d9SLisandro Dalcin PetscErrorCode ierr; 286684b87d9SLisandro Dalcin 287684b87d9SLisandro Dalcin PetscFunctionBegin; 288684b87d9SLisandro Dalcin ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 289684b87d9SLisandro Dalcin ierr = DMCreateLocalVector(dm, &locv);CHKERRQ(ierr); /* VTK viewer requires exclusive ownership of the vector */ 290684b87d9SLisandro Dalcin ierr = PetscObjectGetName((PetscObject) v, &name);CHKERRQ(ierr); 291684b87d9SLisandro Dalcin ierr = PetscObjectSetName((PetscObject) locv, name);CHKERRQ(ierr); 292684b87d9SLisandro Dalcin ierr = VecCopy(v, locv);CHKERRQ(ierr); 293e87a4003SBarry Smith ierr = DMGetSection(dm, §ion);CHKERRQ(ierr); 294684b87d9SLisandro Dalcin ierr = DMPlexGetFieldType_Internal(dm, section, PETSC_DETERMINE, &pStart, &pEnd, &ft);CHKERRQ(ierr); 295a8f87f1dSPatrick Sanan ierr = PetscViewerVTKAddField(viewer, (PetscObject) dm, DMPlexVTKWriteAll, ft, PETSC_TRUE,(PetscObject) locv);CHKERRQ(ierr); 296684b87d9SLisandro Dalcin PetscFunctionReturn(0); 297684b87d9SLisandro Dalcin } 298684b87d9SLisandro Dalcin 299552f7358SJed Brown PetscErrorCode VecView_Plex_Local(Vec v, PetscViewer viewer) 300552f7358SJed Brown { 301552f7358SJed Brown DM dm; 302684b87d9SLisandro Dalcin PetscBool isvtk, ishdf5, isdraw, isglvis; 303552f7358SJed Brown PetscErrorCode ierr; 304552f7358SJed Brown 305552f7358SJed Brown PetscFunctionBegin; 306552f7358SJed Brown ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 30782f516ccSBarry Smith if (!dm) SETERRQ(PetscObjectComm((PetscObject)v), PETSC_ERR_ARG_WRONG, "Vector not generated from a DM"); 308552f7358SJed Brown ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERVTK, &isvtk);CHKERRQ(ierr); 309b136c2c9SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 310f13a32a3SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERDRAW, &isdraw);CHKERRQ(ierr); 3118135c375SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERGLVIS, &isglvis);CHKERRQ(ierr); 312684b87d9SLisandro Dalcin if (isvtk || ishdf5 || isdraw || isglvis) { 313684b87d9SLisandro Dalcin PetscInt i,numFields; 314684b87d9SLisandro Dalcin PetscObject fe; 315ef31f671SMatthew G. Knepley PetscBool fem = PETSC_FALSE; 316684b87d9SLisandro Dalcin Vec locv = v; 317684b87d9SLisandro Dalcin const char *name; 318684b87d9SLisandro Dalcin PetscInt step; 319684b87d9SLisandro Dalcin PetscReal time; 320ef31f671SMatthew G. Knepley 321ef31f671SMatthew G. Knepley ierr = DMGetNumFields(dm, &numFields);CHKERRQ(ierr); 322684b87d9SLisandro Dalcin for (i=0; i<numFields; i++) { 32344a7f3ddSMatthew G. Knepley ierr = DMGetField(dm, i, NULL, &fe);CHKERRQ(ierr); 324684b87d9SLisandro Dalcin if (fe->classid == PETSCFE_CLASSID) { fem = PETSC_TRUE; break; } 325ef31f671SMatthew G. Knepley } 326684b87d9SLisandro Dalcin if (fem) { 327684b87d9SLisandro Dalcin ierr = DMGetLocalVector(dm, &locv);CHKERRQ(ierr); 328684b87d9SLisandro Dalcin ierr = PetscObjectGetName((PetscObject) v, &name);CHKERRQ(ierr); 329684b87d9SLisandro Dalcin ierr = PetscObjectSetName((PetscObject) locv, name);CHKERRQ(ierr); 330684b87d9SLisandro Dalcin ierr = VecCopy(v, locv);CHKERRQ(ierr); 331684b87d9SLisandro Dalcin ierr = DMGetOutputSequenceNumber(dm, NULL, &time);CHKERRQ(ierr); 332684b87d9SLisandro Dalcin ierr = DMPlexInsertBoundaryValues(dm, PETSC_TRUE, locv, time, NULL, NULL, NULL);CHKERRQ(ierr); 333ef31f671SMatthew G. Knepley } 334552f7358SJed Brown if (isvtk) { 335684b87d9SLisandro Dalcin ierr = VecView_Plex_Local_VTK(locv, viewer);CHKERRQ(ierr); 336b136c2c9SMatthew G. Knepley } else if (ishdf5) { 337b136c2c9SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 338684b87d9SLisandro Dalcin ierr = VecView_Plex_Local_HDF5_Internal(locv, viewer);CHKERRQ(ierr); 339b136c2c9SMatthew G. Knepley #else 340b136c2c9SMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 341b136c2c9SMatthew G. Knepley #endif 342f13a32a3SMatthew G. Knepley } else if (isdraw) { 343684b87d9SLisandro Dalcin ierr = VecView_Plex_Local_Draw(locv, viewer);CHKERRQ(ierr); 344684b87d9SLisandro Dalcin } else if (isglvis) { 345684b87d9SLisandro Dalcin ierr = DMGetOutputSequenceNumber(dm, &step, NULL);CHKERRQ(ierr); 346684b87d9SLisandro Dalcin ierr = PetscViewerGLVisSetSnapId(viewer, step);CHKERRQ(ierr); 347684b87d9SLisandro Dalcin ierr = VecView_GLVis(locv, viewer);CHKERRQ(ierr); 348684b87d9SLisandro Dalcin } 349684b87d9SLisandro Dalcin if (fem) {ierr = DMRestoreLocalVector(dm, &locv);CHKERRQ(ierr);} 350552f7358SJed Brown } else { 351684b87d9SLisandro Dalcin PetscBool isseq; 352684b87d9SLisandro Dalcin 353684b87d9SLisandro Dalcin ierr = PetscObjectTypeCompare((PetscObject) v, VECSEQ, &isseq);CHKERRQ(ierr); 35455f2e967SMatthew G. Knepley if (isseq) {ierr = VecView_Seq(v, viewer);CHKERRQ(ierr);} 35555f2e967SMatthew G. Knepley else {ierr = VecView_MPI(v, viewer);CHKERRQ(ierr);} 356552f7358SJed Brown } 357552f7358SJed Brown PetscFunctionReturn(0); 358552f7358SJed Brown } 359552f7358SJed Brown 360552f7358SJed Brown PetscErrorCode VecView_Plex(Vec v, PetscViewer viewer) 361552f7358SJed Brown { 362552f7358SJed Brown DM dm; 363684b87d9SLisandro Dalcin PetscBool isvtk, ishdf5, isdraw, isglvis; 364552f7358SJed Brown PetscErrorCode ierr; 365552f7358SJed Brown 366552f7358SJed Brown PetscFunctionBegin; 367552f7358SJed Brown ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 36882f516ccSBarry Smith if (!dm) SETERRQ(PetscObjectComm((PetscObject)v), PETSC_ERR_ARG_WRONG, "Vector not generated from a DM"); 369552f7358SJed Brown ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERVTK, &isvtk);CHKERRQ(ierr); 37033c3e6b4SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 371e412dcbdSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERDRAW, &isdraw);CHKERRQ(ierr); 3728135c375SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERGLVIS, &isglvis);CHKERRQ(ierr); 373684b87d9SLisandro Dalcin if (isvtk || isdraw || isglvis) { 374552f7358SJed Brown Vec locv; 375552f7358SJed Brown const char *name; 376552f7358SJed Brown 377c8dd51e9SBarry Smith ierr = DMGetLocalVector(dm, &locv);CHKERRQ(ierr); 378552f7358SJed Brown ierr = PetscObjectGetName((PetscObject) v, &name);CHKERRQ(ierr); 379552f7358SJed Brown ierr = PetscObjectSetName((PetscObject) locv, name);CHKERRQ(ierr); 380552f7358SJed Brown ierr = DMGlobalToLocalBegin(dm, v, INSERT_VALUES, locv);CHKERRQ(ierr); 381552f7358SJed Brown ierr = DMGlobalToLocalEnd(dm, v, INSERT_VALUES, locv);CHKERRQ(ierr); 382552f7358SJed Brown ierr = VecView_Plex_Local(locv, viewer);CHKERRQ(ierr); 383c8dd51e9SBarry Smith ierr = DMRestoreLocalVector(dm, &locv);CHKERRQ(ierr); 384b136c2c9SMatthew G. Knepley } else if (ishdf5) { 385b136c2c9SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 38639d25373SMatthew G. Knepley ierr = VecView_Plex_HDF5_Internal(v, viewer);CHKERRQ(ierr); 387b136c2c9SMatthew G. Knepley #else 388b136c2c9SMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 389b136c2c9SMatthew G. Knepley #endif 390552f7358SJed Brown } else { 391684b87d9SLisandro Dalcin PetscBool isseq; 392684b87d9SLisandro Dalcin 393684b87d9SLisandro Dalcin ierr = PetscObjectTypeCompare((PetscObject) v, VECSEQ, &isseq);CHKERRQ(ierr); 39455f2e967SMatthew G. Knepley if (isseq) {ierr = VecView_Seq(v, viewer);CHKERRQ(ierr);} 39555f2e967SMatthew G. Knepley else {ierr = VecView_MPI(v, viewer);CHKERRQ(ierr);} 396552f7358SJed Brown } 397552f7358SJed Brown PetscFunctionReturn(0); 398552f7358SJed Brown } 399552f7358SJed Brown 400d930f514SMatthew G. Knepley PetscErrorCode VecView_Plex_Native(Vec originalv, PetscViewer viewer) 401d930f514SMatthew G. Knepley { 402d930f514SMatthew G. Knepley DM dm; 403d930f514SMatthew G. Knepley MPI_Comm comm; 404d930f514SMatthew G. Knepley PetscViewerFormat format; 405d930f514SMatthew G. Knepley Vec v; 406d930f514SMatthew G. Knepley PetscBool isvtk, ishdf5; 407d930f514SMatthew G. Knepley PetscErrorCode ierr; 408d930f514SMatthew G. Knepley 409d930f514SMatthew G. Knepley PetscFunctionBegin; 410d930f514SMatthew G. Knepley ierr = VecGetDM(originalv, &dm);CHKERRQ(ierr); 411d930f514SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject) originalv, &comm);CHKERRQ(ierr); 4122c4c0c81SMatthew G. Knepley if (!dm) SETERRQ(comm, PETSC_ERR_ARG_WRONG, "Vector not generated from a DM"); 413d930f514SMatthew G. Knepley ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 414d930f514SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 415d930f514SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERVTK, &isvtk);CHKERRQ(ierr); 416d930f514SMatthew G. Knepley if (format == PETSC_VIEWER_NATIVE) { 417a8ad634aSStefano Zampini /* Natural ordering is the common case for DMDA, NATIVE means plain vector, for PLEX is the opposite */ 418a8ad634aSStefano Zampini /* this need a better fix */ 419a8ad634aSStefano Zampini if (dm->useNatural) { 420a8ad634aSStefano Zampini if (dm->sfNatural) { 421d930f514SMatthew G. Knepley const char *vecname; 422d930f514SMatthew G. Knepley PetscInt n, nroots; 423d930f514SMatthew G. Knepley 424ca43db0aSBarry Smith ierr = VecGetLocalSize(originalv, &n);CHKERRQ(ierr); 425d930f514SMatthew G. Knepley ierr = PetscSFGetGraph(dm->sfNatural, &nroots, NULL, NULL, NULL);CHKERRQ(ierr); 426d930f514SMatthew G. Knepley if (n == nroots) { 427d930f514SMatthew G. Knepley ierr = DMGetGlobalVector(dm, &v);CHKERRQ(ierr); 428d930f514SMatthew G. Knepley ierr = DMPlexGlobalToNaturalBegin(dm, originalv, v);CHKERRQ(ierr); 429d930f514SMatthew G. Knepley ierr = DMPlexGlobalToNaturalEnd(dm, originalv, v);CHKERRQ(ierr); 430d930f514SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) originalv, &vecname);CHKERRQ(ierr); 431d930f514SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) v, vecname);CHKERRQ(ierr); 432d930f514SMatthew G. Knepley } else SETERRQ(comm, PETSC_ERR_ARG_WRONG, "DM global to natural SF only handles global vectors"); 433d930f514SMatthew G. Knepley } else SETERRQ(comm, PETSC_ERR_ARG_WRONGSTATE, "DM global to natural SF was not created"); 434a8ad634aSStefano Zampini } else v = originalv; 435a8ad634aSStefano Zampini } else v = originalv; 436a8ad634aSStefano Zampini 437d930f514SMatthew G. Knepley if (ishdf5) { 438d930f514SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 43939d25373SMatthew G. Knepley ierr = VecView_Plex_HDF5_Native_Internal(v, viewer);CHKERRQ(ierr); 440d930f514SMatthew G. Knepley #else 441d930f514SMatthew G. Knepley SETERRQ(comm, PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 442d930f514SMatthew G. Knepley #endif 443d930f514SMatthew G. Knepley } else if (isvtk) { 444d930f514SMatthew G. Knepley SETERRQ(comm, PETSC_ERR_SUP, "VTK format does not support viewing in natural order. Please switch to HDF5."); 445d930f514SMatthew G. Knepley } else { 446d930f514SMatthew G. Knepley PetscBool isseq; 447d930f514SMatthew G. Knepley 448d930f514SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) v, VECSEQ, &isseq);CHKERRQ(ierr); 449d930f514SMatthew G. Knepley if (isseq) {ierr = VecView_Seq(v, viewer);CHKERRQ(ierr);} 450d930f514SMatthew G. Knepley else {ierr = VecView_MPI(v, viewer);CHKERRQ(ierr);} 451d930f514SMatthew G. Knepley } 452a8ad634aSStefano Zampini if (v != originalv) {ierr = DMRestoreGlobalVector(dm, &v);CHKERRQ(ierr);} 453d930f514SMatthew G. Knepley PetscFunctionReturn(0); 454d930f514SMatthew G. Knepley } 455d930f514SMatthew G. Knepley 4562c40f234SMatthew G. Knepley PetscErrorCode VecLoad_Plex_Local(Vec v, PetscViewer viewer) 4572c40f234SMatthew G. Knepley { 4582c40f234SMatthew G. Knepley DM dm; 4592c40f234SMatthew G. Knepley PetscBool ishdf5; 4602c40f234SMatthew G. Knepley PetscErrorCode ierr; 4612c40f234SMatthew G. Knepley 4622c40f234SMatthew G. Knepley PetscFunctionBegin; 4632c40f234SMatthew G. Knepley ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 4642c40f234SMatthew G. Knepley if (!dm) SETERRQ(PetscObjectComm((PetscObject)v), PETSC_ERR_ARG_WRONG, "Vector not generated from a DM"); 4652c40f234SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 4662c40f234SMatthew G. Knepley if (ishdf5) { 4672c40f234SMatthew G. Knepley DM dmBC; 4682c40f234SMatthew G. Knepley Vec gv; 4692c40f234SMatthew G. Knepley const char *name; 4702c40f234SMatthew G. Knepley 4712c40f234SMatthew G. Knepley ierr = DMGetOutputDM(dm, &dmBC);CHKERRQ(ierr); 4722c40f234SMatthew G. Knepley ierr = DMGetGlobalVector(dmBC, &gv);CHKERRQ(ierr); 4732c40f234SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) v, &name);CHKERRQ(ierr); 4742c40f234SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) gv, name);CHKERRQ(ierr); 4752c40f234SMatthew G. Knepley ierr = VecLoad_Default(gv, viewer);CHKERRQ(ierr); 4762c40f234SMatthew G. Knepley ierr = DMGlobalToLocalBegin(dmBC, gv, INSERT_VALUES, v);CHKERRQ(ierr); 4772c40f234SMatthew G. Knepley ierr = DMGlobalToLocalEnd(dmBC, gv, INSERT_VALUES, v);CHKERRQ(ierr); 4782c40f234SMatthew G. Knepley ierr = DMRestoreGlobalVector(dmBC, &gv);CHKERRQ(ierr); 4792c40f234SMatthew G. Knepley } else { 4802c40f234SMatthew G. Knepley ierr = VecLoad_Default(v, viewer);CHKERRQ(ierr); 4812c40f234SMatthew G. Knepley } 4822c40f234SMatthew G. Knepley PetscFunctionReturn(0); 4832c40f234SMatthew G. Knepley } 4842c40f234SMatthew G. Knepley 4852c40f234SMatthew G. Knepley PetscErrorCode VecLoad_Plex(Vec v, PetscViewer viewer) 4862c40f234SMatthew G. Knepley { 4872c40f234SMatthew G. Knepley DM dm; 4882c40f234SMatthew G. Knepley PetscBool ishdf5; 4892c40f234SMatthew G. Knepley PetscErrorCode ierr; 4902c40f234SMatthew G. Knepley 4912c40f234SMatthew G. Knepley PetscFunctionBegin; 4922c40f234SMatthew G. Knepley ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 4932c40f234SMatthew G. Knepley if (!dm) SETERRQ(PetscObjectComm((PetscObject)v), PETSC_ERR_ARG_WRONG, "Vector not generated from a DM"); 4942c40f234SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 4952c40f234SMatthew G. Knepley if (ishdf5) { 496878b459fSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 49739d25373SMatthew G. Knepley ierr = VecLoad_Plex_HDF5_Internal(v, viewer);CHKERRQ(ierr); 498b136c2c9SMatthew G. Knepley #else 499b136c2c9SMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 500878b459fSMatthew G. Knepley #endif 5012c40f234SMatthew G. Knepley } else { 5022c40f234SMatthew G. Knepley ierr = VecLoad_Default(v, viewer);CHKERRQ(ierr); 503552f7358SJed Brown } 504552f7358SJed Brown PetscFunctionReturn(0); 505552f7358SJed Brown } 506552f7358SJed Brown 507d930f514SMatthew G. Knepley PetscErrorCode VecLoad_Plex_Native(Vec originalv, PetscViewer viewer) 508d930f514SMatthew G. Knepley { 509d930f514SMatthew G. Knepley DM dm; 510d930f514SMatthew G. Knepley PetscViewerFormat format; 511d930f514SMatthew G. Knepley PetscBool ishdf5; 512d930f514SMatthew G. Knepley PetscErrorCode ierr; 513d930f514SMatthew G. Knepley 514d930f514SMatthew G. Knepley PetscFunctionBegin; 515d930f514SMatthew G. Knepley ierr = VecGetDM(originalv, &dm);CHKERRQ(ierr); 516d930f514SMatthew G. Knepley if (!dm) SETERRQ(PetscObjectComm((PetscObject) originalv), PETSC_ERR_ARG_WRONG, "Vector not generated from a DM"); 517d930f514SMatthew G. Knepley ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 518d930f514SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 519d930f514SMatthew G. Knepley if (format == PETSC_VIEWER_NATIVE) { 520a8ad634aSStefano Zampini if (dm->useNatural) { 521d930f514SMatthew G. Knepley if (dm->sfNatural) { 522d930f514SMatthew G. Knepley if (ishdf5) { 523d930f514SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 524d930f514SMatthew G. Knepley Vec v; 525d930f514SMatthew G. Knepley const char *vecname; 526d930f514SMatthew G. Knepley 527d930f514SMatthew G. Knepley ierr = DMGetGlobalVector(dm, &v);CHKERRQ(ierr); 528d930f514SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) originalv, &vecname);CHKERRQ(ierr); 529d930f514SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) v, vecname);CHKERRQ(ierr); 53039d25373SMatthew G. Knepley ierr = VecLoad_Plex_HDF5_Native_Internal(v, viewer);CHKERRQ(ierr); 531d930f514SMatthew G. Knepley ierr = DMPlexNaturalToGlobalBegin(dm, v, originalv);CHKERRQ(ierr); 532d930f514SMatthew G. Knepley ierr = DMPlexNaturalToGlobalEnd(dm, v, originalv);CHKERRQ(ierr); 533d930f514SMatthew G. Knepley ierr = DMRestoreGlobalVector(dm, &v);CHKERRQ(ierr); 534d930f514SMatthew G. Knepley #else 535d930f514SMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 536d930f514SMatthew G. Knepley #endif 537d930f514SMatthew G. Knepley } else SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Reading in natural order is not supported for anything but HDF5."); 538d930f514SMatthew G. Knepley } 539a8ad634aSStefano Zampini } else { 540a8ad634aSStefano Zampini ierr = VecLoad_Default(originalv, viewer);CHKERRQ(ierr); 541a8ad634aSStefano Zampini } 542d930f514SMatthew G. Knepley } 543d930f514SMatthew G. Knepley PetscFunctionReturn(0); 544d930f514SMatthew G. Knepley } 545d930f514SMatthew G. Knepley 5467cd05799SMatthew G. Knepley PETSC_UNUSED static PetscErrorCode DMPlexView_Ascii_Geometry(DM dm, PetscViewer viewer) 547731e8ddeSMatthew G. Knepley { 548731e8ddeSMatthew G. Knepley PetscSection coordSection; 549731e8ddeSMatthew G. Knepley Vec coordinates; 550731e8ddeSMatthew G. Knepley DMLabel depthLabel; 551731e8ddeSMatthew G. Knepley const char *name[4]; 552731e8ddeSMatthew G. Knepley const PetscScalar *a; 553731e8ddeSMatthew G. Knepley PetscInt dim, pStart, pEnd, cStart, cEnd, c; 554731e8ddeSMatthew G. Knepley PetscErrorCode ierr; 555731e8ddeSMatthew G. Knepley 556731e8ddeSMatthew G. Knepley PetscFunctionBegin; 557731e8ddeSMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 558731e8ddeSMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 559731e8ddeSMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 560731e8ddeSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &depthLabel);CHKERRQ(ierr); 561731e8ddeSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 562731e8ddeSMatthew G. Knepley ierr = PetscSectionGetChart(coordSection, &pStart, &pEnd);CHKERRQ(ierr); 563731e8ddeSMatthew G. Knepley ierr = VecGetArrayRead(coordinates, &a);CHKERRQ(ierr); 564731e8ddeSMatthew G. Knepley name[0] = "vertex"; 565731e8ddeSMatthew G. Knepley name[1] = "edge"; 566731e8ddeSMatthew G. Knepley name[dim-1] = "face"; 567731e8ddeSMatthew G. Knepley name[dim] = "cell"; 568731e8ddeSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 569731e8ddeSMatthew G. Knepley PetscInt *closure = NULL; 570731e8ddeSMatthew G. Knepley PetscInt closureSize, cl; 571731e8ddeSMatthew G. Knepley 572f347f43bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer, "Geometry for cell %D:\n", c);CHKERRQ(ierr); 573731e8ddeSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 574731e8ddeSMatthew G. Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 575731e8ddeSMatthew G. Knepley for (cl = 0; cl < closureSize*2; cl += 2) { 576731e8ddeSMatthew G. Knepley PetscInt point = closure[cl], depth, dof, off, d, p; 577731e8ddeSMatthew G. Knepley 578731e8ddeSMatthew G. Knepley if ((point < pStart) || (point >= pEnd)) continue; 579731e8ddeSMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, point, &dof);CHKERRQ(ierr); 580731e8ddeSMatthew G. Knepley if (!dof) continue; 581731e8ddeSMatthew G. Knepley ierr = DMLabelGetValue(depthLabel, point, &depth);CHKERRQ(ierr); 582731e8ddeSMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, point, &off);CHKERRQ(ierr); 583f347f43bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer, "%s %D coords:", name[depth], point);CHKERRQ(ierr); 584731e8ddeSMatthew G. Knepley for (p = 0; p < dof/dim; ++p) { 585731e8ddeSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " (");CHKERRQ(ierr); 586731e8ddeSMatthew G. Knepley for (d = 0; d < dim; ++d) { 587731e8ddeSMatthew G. Knepley if (d > 0) {ierr = PetscViewerASCIIPrintf(viewer, ", ");CHKERRQ(ierr);} 58841477eefSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "%g", PetscRealPart(a[off+p*dim+d]));CHKERRQ(ierr); 589731e8ddeSMatthew G. Knepley } 590731e8ddeSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, ")");CHKERRQ(ierr); 591731e8ddeSMatthew G. Knepley } 592731e8ddeSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "\n");CHKERRQ(ierr); 593731e8ddeSMatthew G. Knepley } 594731e8ddeSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 595731e8ddeSMatthew G. Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 596731e8ddeSMatthew G. Knepley } 597731e8ddeSMatthew G. Knepley ierr = VecRestoreArrayRead(coordinates, &a);CHKERRQ(ierr); 598731e8ddeSMatthew G. Knepley PetscFunctionReturn(0); 599731e8ddeSMatthew G. Knepley } 600731e8ddeSMatthew G. Knepley 6017cd05799SMatthew G. Knepley static PetscErrorCode DMPlexView_Ascii(DM dm, PetscViewer viewer) 602552f7358SJed Brown { 603552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 604552f7358SJed Brown DM cdm; 605552f7358SJed Brown DMLabel markers; 606552f7358SJed Brown PetscSection coordSection; 607552f7358SJed Brown Vec coordinates; 608552f7358SJed Brown PetscViewerFormat format; 609552f7358SJed Brown PetscErrorCode ierr; 610552f7358SJed Brown 611552f7358SJed Brown PetscFunctionBegin; 612552f7358SJed Brown ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 613e87a4003SBarry Smith ierr = DMGetSection(cdm, &coordSection);CHKERRQ(ierr); 614552f7358SJed Brown ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 615552f7358SJed Brown ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 616552f7358SJed Brown if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 617552f7358SJed Brown const char *name; 618f73eea6eSMatthew G. Knepley PetscInt dim, cellHeight, maxConeSize, maxSupportSize; 619552f7358SJed Brown PetscInt pStart, pEnd, p; 620552f7358SJed Brown PetscMPIInt rank, size; 621552f7358SJed Brown 62282f516ccSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank);CHKERRQ(ierr); 62382f516ccSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)dm), &size);CHKERRQ(ierr); 624552f7358SJed Brown ierr = PetscObjectGetName((PetscObject) dm, &name);CHKERRQ(ierr); 625552f7358SJed Brown ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 626552f7358SJed Brown ierr = DMPlexGetMaxSizes(dm, &maxConeSize, &maxSupportSize);CHKERRQ(ierr); 627f73eea6eSMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 628f73eea6eSMatthew G. Knepley ierr = DMPlexGetVTKCellHeight(dm, &cellHeight);CHKERRQ(ierr); 629f73eea6eSMatthew G. Knepley if (name) {ierr = PetscViewerASCIIPrintf(viewer, "%s in %D dimension%s:\n", name, dim, dim == 1 ? "" : "s");CHKERRQ(ierr);} 630f73eea6eSMatthew G. Knepley else {ierr = PetscViewerASCIIPrintf(viewer, "Mesh in %D dimension%s:\n", dim, dim == 1 ? "" : "s");CHKERRQ(ierr);} 631f73eea6eSMatthew G. Knepley if (cellHeight) {ierr = PetscViewerASCIIPrintf(viewer, " Cells are at height %D\n", cellHeight);CHKERRQ(ierr);} 632e9cb465cSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "Supports:\n", name);CHKERRQ(ierr); 6334d4c343aSBarry Smith ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 634e9cb465cSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "[%d] Max support size: %D\n", rank, maxSupportSize);CHKERRQ(ierr); 635552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 636552f7358SJed Brown PetscInt dof, off, s; 637552f7358SJed Brown 638552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, &dof);CHKERRQ(ierr); 639552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, p, &off);CHKERRQ(ierr); 640552f7358SJed Brown for (s = off; s < off+dof; ++s) { 641e4b003c7SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer, "[%d]: %D ----> %D\n", rank, p, mesh->supports[s]);CHKERRQ(ierr); 642552f7358SJed Brown } 643552f7358SJed Brown } 644552f7358SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 645e9cb465cSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "Cones:\n", name);CHKERRQ(ierr); 646e9cb465cSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "[%d] Max cone size: %D\n", rank, maxConeSize);CHKERRQ(ierr); 647552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 648552f7358SJed Brown PetscInt dof, off, c; 649552f7358SJed Brown 650552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 651552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 652552f7358SJed Brown for (c = off; c < off+dof; ++c) { 653e4b003c7SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer, "[%d]: %D <---- %D (%D)\n", rank, p, mesh->cones[c], mesh->coneOrientations[c]);CHKERRQ(ierr); 654552f7358SJed Brown } 655552f7358SJed Brown } 656552f7358SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 6574d4c343aSBarry Smith ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); 6583d2e540fSStefano Zampini if (coordSection && coordinates) { 65980180ce3SStefano Zampini ierr = PetscSectionVecView(coordSection, coordinates, viewer);CHKERRQ(ierr); 6603d2e540fSStefano Zampini } 661c58f1c22SToby Isaac ierr = DMGetLabel(dm, "marker", &markers);CHKERRQ(ierr); 6627422c0d1SMatthew G. Knepley if (markers) {ierr = DMLabelView(markers,viewer);CHKERRQ(ierr);} 663552f7358SJed Brown if (size > 1) { 664552f7358SJed Brown PetscSF sf; 665552f7358SJed Brown 666552f7358SJed Brown ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 667552f7358SJed Brown ierr = PetscSFView(sf, viewer);CHKERRQ(ierr); 668552f7358SJed Brown } 669552f7358SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 670552f7358SJed Brown } else if (format == PETSC_VIEWER_ASCII_LATEX) { 6710588280cSMatthew G. Knepley const char *name, *color; 6720588280cSMatthew G. Knepley const char *defcolors[3] = {"gray", "orange", "green"}; 6730588280cSMatthew G. Knepley const char *deflcolors[4] = {"blue", "cyan", "red", "magenta"}; 674552f7358SJed Brown PetscReal scale = 2.0; 67578081901SStefano Zampini PetscReal tikzscale = 1.0; 6760588280cSMatthew G. Knepley PetscBool useNumbers = PETSC_TRUE, useLabels, useColors; 6770588280cSMatthew G. Knepley double tcoords[3]; 678552f7358SJed Brown PetscScalar *coords; 6790588280cSMatthew G. Knepley PetscInt numLabels, l, numColors, numLColors, dim, depth, cStart, cEnd, c, vStart, vEnd, v, eStart = 0, eEnd = 0, e, p; 680552f7358SJed Brown PetscMPIInt rank, size; 6810588280cSMatthew G. Knepley char **names, **colors, **lcolors; 682202fd40aSStefano Zampini PetscBool plotEdges, flg; 683552f7358SJed Brown 6840588280cSMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 685552f7358SJed Brown ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 686c58f1c22SToby Isaac ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 6870588280cSMatthew G. Knepley numLabels = PetscMax(numLabels, 10); 6880588280cSMatthew G. Knepley numColors = 10; 6890588280cSMatthew G. Knepley numLColors = 10; 6900588280cSMatthew G. Knepley ierr = PetscCalloc3(numLabels, &names, numColors, &colors, numLColors, &lcolors);CHKERRQ(ierr); 691c5929fdfSBarry Smith ierr = PetscOptionsGetReal(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_scale", &scale, NULL);CHKERRQ(ierr); 69278081901SStefano Zampini ierr = PetscOptionsGetReal(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_tikzscale", &tikzscale, NULL);CHKERRQ(ierr); 693c5929fdfSBarry Smith ierr = PetscOptionsGetBool(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_numbers", &useNumbers, NULL);CHKERRQ(ierr); 694c5929fdfSBarry Smith ierr = PetscOptionsGetStringArray(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_labels", names, &numLabels, &useLabels);CHKERRQ(ierr); 6950588280cSMatthew G. Knepley if (!useLabels) numLabels = 0; 696c5929fdfSBarry Smith ierr = PetscOptionsGetStringArray(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_colors", colors, &numColors, &useColors);CHKERRQ(ierr); 6970588280cSMatthew G. Knepley if (!useColors) { 6980588280cSMatthew G. Knepley numColors = 3; 6990588280cSMatthew G. Knepley for (c = 0; c < numColors; ++c) {ierr = PetscStrallocpy(defcolors[c], &colors[c]);CHKERRQ(ierr);} 7000588280cSMatthew G. Knepley } 701c5929fdfSBarry Smith ierr = PetscOptionsGetStringArray(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_lcolors", lcolors, &numLColors, &useColors);CHKERRQ(ierr); 7020588280cSMatthew G. Knepley if (!useColors) { 7030588280cSMatthew G. Knepley numLColors = 4; 7040588280cSMatthew G. Knepley for (c = 0; c < numLColors; ++c) {ierr = PetscStrallocpy(deflcolors[c], &lcolors[c]);CHKERRQ(ierr);} 7050588280cSMatthew G. Knepley } 706202fd40aSStefano Zampini plotEdges = (PetscBool)(depth > 1 && useNumbers && dim < 3); 707202fd40aSStefano Zampini ierr = PetscOptionsGetBool(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_edges", &plotEdges, &flg);CHKERRQ(ierr); 708202fd40aSStefano Zampini if (flg && plotEdges && depth < dim) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Mesh must be interpolated"); 709202fd40aSStefano Zampini if (depth < dim) plotEdges = PETSC_FALSE; 71082f516ccSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank);CHKERRQ(ierr); 71182f516ccSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)dm), &size);CHKERRQ(ierr); 712552f7358SJed Brown ierr = PetscObjectGetName((PetscObject) dm, &name);CHKERRQ(ierr); 713770b213bSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, "\ 7140588280cSMatthew G. Knepley \\documentclass[tikz]{standalone}\n\n\ 715552f7358SJed Brown \\usepackage{pgflibraryshapes}\n\ 716552f7358SJed Brown \\usetikzlibrary{backgrounds}\n\ 717552f7358SJed Brown \\usetikzlibrary{arrows}\n\ 7180588280cSMatthew G. Knepley \\begin{document}\n");CHKERRQ(ierr); 7190588280cSMatthew G. Knepley if (size > 1) { 720f738dd31SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "%s for process ", name);CHKERRQ(ierr); 721770b213bSMatthew G Knepley for (p = 0; p < size; ++p) { 722770b213bSMatthew G Knepley if (p > 0 && p == size-1) { 723770b213bSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, ", and ", colors[p%numColors], p);CHKERRQ(ierr); 724770b213bSMatthew G Knepley } else if (p > 0) { 725770b213bSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, ", ", colors[p%numColors], p);CHKERRQ(ierr); 726770b213bSMatthew G Knepley } 727770b213bSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, "{\\textcolor{%s}%D}", colors[p%numColors], p);CHKERRQ(ierr); 728770b213bSMatthew G Knepley } 7290588280cSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, ".\n\n\n");CHKERRQ(ierr); 7300588280cSMatthew G. Knepley } 73178081901SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer, "\\begin{tikzpicture}[scale = %g,font=\\fontsize{8}{8}\\selectfont]\n", tikzscale);CHKERRQ(ierr); 732552f7358SJed Brown /* Plot vertices */ 733552f7358SJed Brown ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 734552f7358SJed Brown ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 7354d4c343aSBarry Smith ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 736552f7358SJed Brown for (v = vStart; v < vEnd; ++v) { 737552f7358SJed Brown PetscInt off, dof, d; 7380588280cSMatthew G. Knepley PetscBool isLabeled = PETSC_FALSE; 739552f7358SJed Brown 740552f7358SJed Brown ierr = PetscSectionGetDof(coordSection, v, &dof);CHKERRQ(ierr); 741552f7358SJed Brown ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 7420588280cSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "\\path (");CHKERRQ(ierr); 743f6dae198SJed Brown if (PetscUnlikely(dof > 3)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"coordSection vertex %D has dof %D > 3",v,dof); 7440588280cSMatthew G. Knepley for (d = 0; d < dof; ++d) { 7450588280cSMatthew G. Knepley tcoords[d] = (double) (scale*PetscRealPart(coords[off+d])); 746c068d9bbSLisandro Dalcin tcoords[d] = PetscAbs(tcoords[d]) < 1e-10 ? 0.0 : tcoords[d]; 7470588280cSMatthew G. Knepley } 7480588280cSMatthew G. Knepley /* Rotate coordinates since PGF makes z point out of the page instead of up */ 7490588280cSMatthew G. Knepley if (dim == 3) {PetscReal tmp = tcoords[1]; tcoords[1] = tcoords[2]; tcoords[2] = -tmp;} 750552f7358SJed Brown for (d = 0; d < dof; ++d) { 751552f7358SJed Brown if (d > 0) {ierr = PetscViewerASCIISynchronizedPrintf(viewer, ",");CHKERRQ(ierr);} 7520588280cSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "%g", tcoords[d]);CHKERRQ(ierr); 753552f7358SJed Brown } 7540588280cSMatthew G. Knepley color = colors[rank%numColors]; 7550588280cSMatthew G. Knepley for (l = 0; l < numLabels; ++l) { 7560588280cSMatthew G. Knepley PetscInt val; 757c58f1c22SToby Isaac ierr = DMGetLabelValue(dm, names[l], v, &val);CHKERRQ(ierr); 7580588280cSMatthew G. Knepley if (val >= 0) {color = lcolors[l%numLColors]; isLabeled = PETSC_TRUE; break;} 7590588280cSMatthew G. Knepley } 7600588280cSMatthew G. Knepley if (useNumbers) { 761e4b003c7SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer, ") node(%D_%d) [draw,shape=circle,color=%s] {%D};\n", v, rank, color, v);CHKERRQ(ierr); 7620588280cSMatthew G. Knepley } else { 763e4b003c7SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer, ") node(%D_%d) [fill,inner sep=%dpt,shape=circle,color=%s] {};\n", v, rank, !isLabeled ? 1 : 2, color);CHKERRQ(ierr); 7640588280cSMatthew G. Knepley } 765552f7358SJed Brown } 766552f7358SJed Brown ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 767552f7358SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 768846a3e8bSMatthew G. Knepley /* Plot cells */ 769846a3e8bSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 77078081901SStefano Zampini ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 771846a3e8bSMatthew G. Knepley if (dim == 3 || !useNumbers) { 772846a3e8bSMatthew G. Knepley for (e = eStart; e < eEnd; ++e) { 773846a3e8bSMatthew G. Knepley const PetscInt *cone; 774846a3e8bSMatthew G. Knepley 775846a3e8bSMatthew G. Knepley color = colors[rank%numColors]; 776846a3e8bSMatthew G. Knepley for (l = 0; l < numLabels; ++l) { 777846a3e8bSMatthew G. Knepley PetscInt val; 778846a3e8bSMatthew G. Knepley ierr = DMGetLabelValue(dm, names[l], e, &val);CHKERRQ(ierr); 779846a3e8bSMatthew G. Knepley if (val >= 0) {color = lcolors[l%numLColors]; break;} 780846a3e8bSMatthew G. Knepley } 781846a3e8bSMatthew G. Knepley ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 782846a3e8bSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "\\draw[color=%s] (%D_%d) -- (%D_%d);\n", color, cone[0], rank, cone[1], rank);CHKERRQ(ierr); 783846a3e8bSMatthew G. Knepley } 784846a3e8bSMatthew G. Knepley } else { 785846a3e8bSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 786846a3e8bSMatthew G. Knepley PetscInt *closure = NULL; 787846a3e8bSMatthew G. Knepley PetscInt closureSize, firstPoint = -1; 788846a3e8bSMatthew G. Knepley 789846a3e8bSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 790846a3e8bSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "\\draw[color=%s] ", colors[rank%numColors]);CHKERRQ(ierr); 791846a3e8bSMatthew G. Knepley for (p = 0; p < closureSize*2; p += 2) { 792846a3e8bSMatthew G. Knepley const PetscInt point = closure[p]; 793846a3e8bSMatthew G. Knepley 794846a3e8bSMatthew G. Knepley if ((point < vStart) || (point >= vEnd)) continue; 795846a3e8bSMatthew G. Knepley if (firstPoint >= 0) {ierr = PetscViewerASCIISynchronizedPrintf(viewer, " -- ");CHKERRQ(ierr);} 796846a3e8bSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "(%D_%d)", point, rank);CHKERRQ(ierr); 797846a3e8bSMatthew G. Knepley if (firstPoint < 0) firstPoint = point; 798846a3e8bSMatthew G. Knepley } 799846a3e8bSMatthew G. Knepley /* Why doesn't this work? ierr = PetscViewerASCIISynchronizedPrintf(viewer, " -- cycle;\n");CHKERRQ(ierr); */ 800846a3e8bSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, " -- (%D_%d);\n", firstPoint, rank);CHKERRQ(ierr); 801846a3e8bSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 802846a3e8bSMatthew G. Knepley } 803846a3e8bSMatthew G. Knepley } 804846a3e8bSMatthew G. Knepley ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 805846a3e8bSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 806846a3e8bSMatthew G. Knepley double ccoords[3] = {0.0, 0.0, 0.0}; 807846a3e8bSMatthew G. Knepley PetscBool isLabeled = PETSC_FALSE; 808846a3e8bSMatthew G. Knepley PetscInt *closure = NULL; 809846a3e8bSMatthew G. Knepley PetscInt closureSize, dof, d, n = 0; 810846a3e8bSMatthew G. Knepley 811846a3e8bSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 812846a3e8bSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "\\path (");CHKERRQ(ierr); 813846a3e8bSMatthew G. Knepley for (p = 0; p < closureSize*2; p += 2) { 814846a3e8bSMatthew G. Knepley const PetscInt point = closure[p]; 815846a3e8bSMatthew G. Knepley PetscInt off; 816846a3e8bSMatthew G. Knepley 817846a3e8bSMatthew G. Knepley if ((point < vStart) || (point >= vEnd)) continue; 818846a3e8bSMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, point, &dof);CHKERRQ(ierr); 819846a3e8bSMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, point, &off);CHKERRQ(ierr); 820846a3e8bSMatthew G. Knepley for (d = 0; d < dof; ++d) { 821846a3e8bSMatthew G. Knepley tcoords[d] = (double) (scale*PetscRealPart(coords[off+d])); 822846a3e8bSMatthew G. Knepley tcoords[d] = PetscAbs(tcoords[d]) < 1e-10 ? 0.0 : tcoords[d]; 823846a3e8bSMatthew G. Knepley } 824846a3e8bSMatthew G. Knepley /* Rotate coordinates since PGF makes z point out of the page instead of up */ 825846a3e8bSMatthew G. Knepley if (dof == 3) {PetscReal tmp = tcoords[1]; tcoords[1] = tcoords[2]; tcoords[2] = -tmp;} 826846a3e8bSMatthew G. Knepley for (d = 0; d < dof; ++d) {ccoords[d] += tcoords[d];} 827846a3e8bSMatthew G. Knepley ++n; 828846a3e8bSMatthew G. Knepley } 829846a3e8bSMatthew G. Knepley for (d = 0; d < dof; ++d) {ccoords[d] /= n;} 830846a3e8bSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 831846a3e8bSMatthew G. Knepley for (d = 0; d < dof; ++d) { 832846a3e8bSMatthew G. Knepley if (d > 0) {ierr = PetscViewerASCIISynchronizedPrintf(viewer, ",");CHKERRQ(ierr);} 833846a3e8bSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "%g", ccoords[d]);CHKERRQ(ierr); 834846a3e8bSMatthew G. Knepley } 835846a3e8bSMatthew G. Knepley color = colors[rank%numColors]; 836846a3e8bSMatthew G. Knepley for (l = 0; l < numLabels; ++l) { 837846a3e8bSMatthew G. Knepley PetscInt val; 838846a3e8bSMatthew G. Knepley ierr = DMGetLabelValue(dm, names[l], c, &val);CHKERRQ(ierr); 839846a3e8bSMatthew G. Knepley if (val >= 0) {color = lcolors[l%numLColors]; isLabeled = PETSC_TRUE; break;} 840846a3e8bSMatthew G. Knepley } 841846a3e8bSMatthew G. Knepley if (useNumbers) { 842846a3e8bSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, ") node(%D_%d) [draw,shape=circle,color=%s] {%D};\n", c, rank, color, c);CHKERRQ(ierr); 843846a3e8bSMatthew G. Knepley } else { 844846a3e8bSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, ") node(%D_%d) [fill,inner sep=%dpt,shape=circle,color=%s] {};\n", c, rank, !isLabeled ? 1 : 2, color);CHKERRQ(ierr); 845846a3e8bSMatthew G. Knepley } 846846a3e8bSMatthew G. Knepley } 847846a3e8bSMatthew G. Knepley ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 848552f7358SJed Brown /* Plot edges */ 849202fd40aSStefano Zampini if (plotEdges) { 850552f7358SJed Brown ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 851552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, "\\path\n");CHKERRQ(ierr); 852552f7358SJed Brown for (e = eStart; e < eEnd; ++e) { 853552f7358SJed Brown const PetscInt *cone; 854552f7358SJed Brown PetscInt coneSize, offA, offB, dof, d; 855552f7358SJed Brown 856552f7358SJed Brown ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr); 857f347f43bSBarry Smith if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %D cone should have two vertices, not %D", e, coneSize); 858552f7358SJed Brown ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 859552f7358SJed Brown ierr = PetscSectionGetDof(coordSection, cone[0], &dof);CHKERRQ(ierr); 860552f7358SJed Brown ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr); 861552f7358SJed Brown ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr); 862552f7358SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer, "(");CHKERRQ(ierr); 863552f7358SJed Brown for (d = 0; d < dof; ++d) { 864202fd40aSStefano Zampini tcoords[d] = (double) (0.5*scale*PetscRealPart(coords[offA+d]+coords[offB+d])); 865c068d9bbSLisandro Dalcin tcoords[d] = PetscAbs(tcoords[d]) < 1e-10 ? 0.0 : tcoords[d]; 866552f7358SJed Brown } 8670588280cSMatthew G. Knepley /* Rotate coordinates since PGF makes z point out of the page instead of up */ 8680588280cSMatthew G. Knepley if (dim == 3) {PetscReal tmp = tcoords[1]; tcoords[1] = tcoords[2]; tcoords[2] = -tmp;} 8690588280cSMatthew G. Knepley for (d = 0; d < dof; ++d) { 8700588280cSMatthew G. Knepley if (d > 0) {ierr = PetscViewerASCIISynchronizedPrintf(viewer, ",");CHKERRQ(ierr);} 871f347f43bSBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer, "%g", (double)tcoords[d]);CHKERRQ(ierr); 8720588280cSMatthew G. Knepley } 8730588280cSMatthew G. Knepley color = colors[rank%numColors]; 8740588280cSMatthew G. Knepley for (l = 0; l < numLabels; ++l) { 8750588280cSMatthew G. Knepley PetscInt val; 876c58f1c22SToby Isaac ierr = DMGetLabelValue(dm, names[l], v, &val);CHKERRQ(ierr); 8770750fff4SMatthew G. Knepley if (val >= 0) {color = lcolors[l%numLColors]; break;} 8780588280cSMatthew G. Knepley } 879e4b003c7SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer, ") node(%D_%d) [draw,shape=circle,color=%s] {%D} --\n", e, rank, color, e);CHKERRQ(ierr); 880552f7358SJed Brown } 881552f7358SJed Brown ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 882552f7358SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 883552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, "(0,0);\n");CHKERRQ(ierr); 8840588280cSMatthew G. Knepley } 885552f7358SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 8864d4c343aSBarry Smith ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); 8870588280cSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "\\end{tikzpicture}\n");CHKERRQ(ierr); 888770b213bSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, "\\end{document}\n", name);CHKERRQ(ierr); 8890588280cSMatthew G. Knepley for (l = 0; l < numLabels; ++l) {ierr = PetscFree(names[l]);CHKERRQ(ierr);} 8900588280cSMatthew G. Knepley for (c = 0; c < numColors; ++c) {ierr = PetscFree(colors[c]);CHKERRQ(ierr);} 8910588280cSMatthew G. Knepley for (c = 0; c < numLColors; ++c) {ierr = PetscFree(lcolors[c]);CHKERRQ(ierr);} 8920588280cSMatthew G. Knepley ierr = PetscFree3(names, colors, lcolors);CHKERRQ(ierr); 893552f7358SJed Brown } else { 89482f516ccSBarry Smith MPI_Comm comm; 895834065abSMatthew G. Knepley PetscInt *sizes, *hybsizes; 896f73eea6eSMatthew G. Knepley PetscInt locDepth, depth, cellHeight, dim, d, pMax[4]; 897552f7358SJed Brown PetscInt pStart, pEnd, p; 898a57dd577SMatthew G Knepley PetscInt numLabels, l; 8991143a3c0SMatthew G. Knepley const char *name; 900552f7358SJed Brown PetscMPIInt size; 901552f7358SJed Brown 90282f516ccSBarry Smith ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 903552f7358SJed Brown ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 904c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 905f73eea6eSMatthew G. Knepley ierr = DMPlexGetVTKCellHeight(dm, &cellHeight);CHKERRQ(ierr); 9065f64d76eSMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) dm, &name);CHKERRQ(ierr); 907f73eea6eSMatthew G. Knepley if (name) {ierr = PetscViewerASCIIPrintf(viewer, "%s in %D dimension%s:\n", name, dim, dim == 1 ? "" : "s");CHKERRQ(ierr);} 908f73eea6eSMatthew G. Knepley else {ierr = PetscViewerASCIIPrintf(viewer, "Mesh in %D dimension%s:\n", dim, dim == 1 ? "" : "s");CHKERRQ(ierr);} 909f73eea6eSMatthew G. Knepley if (cellHeight) {ierr = PetscViewerASCIIPrintf(viewer, " Cells are at height %D\n", cellHeight);CHKERRQ(ierr);} 910552f7358SJed Brown ierr = DMPlexGetDepth(dm, &locDepth);CHKERRQ(ierr); 911b2566f29SBarry Smith ierr = MPIU_Allreduce(&locDepth, &depth, 1, MPIU_INT, MPI_MAX, comm);CHKERRQ(ierr); 912a04427b4SStefano Zampini ierr = DMPlexGetHybridBounds(dm, &pMax[depth], depth > 0 ? &pMax[depth-1] : NULL, depth > 1 ? &pMax[depth - 2] : NULL, &pMax[0]);CHKERRQ(ierr); 913b0138d5dSStefano Zampini ierr = PetscCalloc2(size,&sizes,size,&hybsizes);CHKERRQ(ierr); 914552f7358SJed Brown if (depth == 1) { 915552f7358SJed Brown ierr = DMPlexGetDepthStratum(dm, 0, &pStart, &pEnd);CHKERRQ(ierr); 916552f7358SJed Brown pEnd = pEnd - pStart; 917a04427b4SStefano Zampini pMax[0] -= pStart; 918552f7358SJed Brown ierr = MPI_Gather(&pEnd, 1, MPIU_INT, sizes, 1, MPIU_INT, 0, comm);CHKERRQ(ierr); 919a04427b4SStefano Zampini ierr = MPI_Gather(&pMax[0], 1, MPIU_INT, hybsizes, 1, MPIU_INT, 0, comm);CHKERRQ(ierr); 920f347f43bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer, " %d-cells:", 0);CHKERRQ(ierr); 921a04427b4SStefano Zampini for (p = 0; p < size; ++p) { 922a04427b4SStefano Zampini if (hybsizes[p] >= 0) {ierr = PetscViewerASCIIPrintf(viewer, " %D (%D)", sizes[p], sizes[p] - hybsizes[p]);CHKERRQ(ierr);} 923a04427b4SStefano Zampini else {ierr = PetscViewerASCIIPrintf(viewer, " %D", sizes[p]);CHKERRQ(ierr);} 924a04427b4SStefano Zampini } 925552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, "\n");CHKERRQ(ierr); 926552f7358SJed Brown ierr = DMPlexGetHeightStratum(dm, 0, &pStart, &pEnd);CHKERRQ(ierr); 927552f7358SJed Brown pEnd = pEnd - pStart; 928a04427b4SStefano Zampini pMax[depth] -= pStart; 929552f7358SJed Brown ierr = MPI_Gather(&pEnd, 1, MPIU_INT, sizes, 1, MPIU_INT, 0, comm);CHKERRQ(ierr); 930a04427b4SStefano Zampini ierr = MPI_Gather(&pMax[depth], 1, MPIU_INT, hybsizes, 1, MPIU_INT, 0, comm);CHKERRQ(ierr); 931552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, " %D-cells:", dim);CHKERRQ(ierr); 932a04427b4SStefano Zampini for (p = 0; p < size; ++p) { 933a04427b4SStefano Zampini if (hybsizes[p] >= 0) {ierr = PetscViewerASCIIPrintf(viewer, " %D (%D)", sizes[p], sizes[p] - hybsizes[p]);CHKERRQ(ierr);} 934a04427b4SStefano Zampini else {ierr = PetscViewerASCIIPrintf(viewer, " %D", sizes[p]);CHKERRQ(ierr);} 935a04427b4SStefano Zampini } 936552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, "\n");CHKERRQ(ierr); 937552f7358SJed Brown } else { 938cbb7f117SMark Adams PetscMPIInt rank; 939cbb7f117SMark Adams ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 940552f7358SJed Brown for (d = 0; d <= dim; d++) { 941552f7358SJed Brown ierr = DMPlexGetDepthStratum(dm, d, &pStart, &pEnd);CHKERRQ(ierr); 942834065abSMatthew G. Knepley pEnd -= pStart; 943834065abSMatthew G. Knepley pMax[d] -= pStart; 944552f7358SJed Brown ierr = MPI_Gather(&pEnd, 1, MPIU_INT, sizes, 1, MPIU_INT, 0, comm);CHKERRQ(ierr); 945834065abSMatthew G. Knepley ierr = MPI_Gather(&pMax[d], 1, MPIU_INT, hybsizes, 1, MPIU_INT, 0, comm);CHKERRQ(ierr); 946552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, " %D-cells:", d);CHKERRQ(ierr); 947834065abSMatthew G. Knepley for (p = 0; p < size; ++p) { 948cbb7f117SMark Adams if (!rank) { 949834065abSMatthew G. Knepley if (hybsizes[p] >= 0) {ierr = PetscViewerASCIIPrintf(viewer, " %D (%D)", sizes[p], sizes[p] - hybsizes[p]);CHKERRQ(ierr);} 950834065abSMatthew G. Knepley else {ierr = PetscViewerASCIIPrintf(viewer, " %D", sizes[p]);CHKERRQ(ierr);} 951834065abSMatthew G. Knepley } 952cbb7f117SMark Adams } 953552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, "\n");CHKERRQ(ierr); 954552f7358SJed Brown } 955552f7358SJed Brown } 956834065abSMatthew G. Knepley ierr = PetscFree2(sizes,hybsizes);CHKERRQ(ierr); 957c58f1c22SToby Isaac ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 958a57dd577SMatthew G Knepley if (numLabels) {ierr = PetscViewerASCIIPrintf(viewer, "Labels:\n");CHKERRQ(ierr);} 959a57dd577SMatthew G Knepley for (l = 0; l < numLabels; ++l) { 960a57dd577SMatthew G Knepley DMLabel label; 961a57dd577SMatthew G Knepley const char *name; 962a57dd577SMatthew G Knepley IS valueIS; 963a57dd577SMatthew G Knepley const PetscInt *values; 964a57dd577SMatthew G Knepley PetscInt numValues, v; 965a57dd577SMatthew G Knepley 966c58f1c22SToby Isaac ierr = DMGetLabelName(dm, l, &name);CHKERRQ(ierr); 967c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 968a57dd577SMatthew G Knepley ierr = DMLabelGetNumValues(label, &numValues);CHKERRQ(ierr); 969d72f73ffSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " %s: %D strata with value/size (", name, numValues);CHKERRQ(ierr); 970a57dd577SMatthew G Knepley ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 971a57dd577SMatthew G Knepley ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 972120dea56SMatthew G. Knepley ierr = PetscViewerASCIIUseTabs(viewer, PETSC_FALSE);CHKERRQ(ierr); 973a57dd577SMatthew G Knepley for (v = 0; v < numValues; ++v) { 974a57dd577SMatthew G Knepley PetscInt size; 975a57dd577SMatthew G Knepley 976a57dd577SMatthew G Knepley ierr = DMLabelGetStratumSize(label, values[v], &size);CHKERRQ(ierr); 977a57dd577SMatthew G Knepley if (v > 0) {ierr = PetscViewerASCIIPrintf(viewer, ", ");CHKERRQ(ierr);} 978d72f73ffSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "%D (%D)", values[v], size);CHKERRQ(ierr); 979a57dd577SMatthew G Knepley } 980a57dd577SMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, ")\n");CHKERRQ(ierr); 981120dea56SMatthew G. Knepley ierr = PetscViewerASCIIUseTabs(viewer, PETSC_TRUE);CHKERRQ(ierr); 982a57dd577SMatthew G Knepley ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 9834d41221fSMatthew G Knepley ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 984a57dd577SMatthew G Knepley } 98534aa8a36SMatthew G. Knepley /* If no fields are specified, people do not want to see adjacency */ 98634aa8a36SMatthew G. Knepley if (dm->Nf) { 98734aa8a36SMatthew G. Knepley PetscInt f; 98834aa8a36SMatthew G. Knepley 98934aa8a36SMatthew G. Knepley for (f = 0; f < dm->Nf; ++f) { 99034aa8a36SMatthew G. Knepley const char *name; 99134aa8a36SMatthew G. Knepley 99234aa8a36SMatthew G. Knepley ierr = PetscObjectGetName(dm->fields[f].disc, &name);CHKERRQ(ierr); 99334aa8a36SMatthew G. Knepley if (numLabels) {ierr = PetscViewerASCIIPrintf(viewer, "Field %s:\n", name);CHKERRQ(ierr);} 99434aa8a36SMatthew G. Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 99534aa8a36SMatthew G. Knepley if (dm->fields[f].label) {ierr = DMLabelView(dm->fields[f].label, viewer);CHKERRQ(ierr);} 99634aa8a36SMatthew G. Knepley if (dm->fields[f].adjacency[0]) { 99734aa8a36SMatthew G. Knepley if (dm->fields[f].adjacency[1]) {ierr = PetscViewerASCIIPrintf(viewer, "adjacency FVM++\n");CHKERRQ(ierr);} 998ed59e46eSMatthew G. Knepley else {ierr = PetscViewerASCIIPrintf(viewer, "adjacency FVM\n");CHKERRQ(ierr);} 99934aa8a36SMatthew G. Knepley } else { 100034aa8a36SMatthew G. Knepley if (dm->fields[f].adjacency[1]) {ierr = PetscViewerASCIIPrintf(viewer, "adjacency FEM\n");CHKERRQ(ierr);} 100134aa8a36SMatthew G. Knepley else {ierr = PetscViewerASCIIPrintf(viewer, "adjacency FUNKY\n");CHKERRQ(ierr);} 100234aa8a36SMatthew G. Knepley } 100334aa8a36SMatthew G. Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 100434aa8a36SMatthew G. Knepley } 100534aa8a36SMatthew G. Knepley } 1006a8fb8f29SToby Isaac ierr = DMGetCoarseDM(dm, &cdm);CHKERRQ(ierr); 10078e7ff633SMatthew G. Knepley if (cdm) { 10088e7ff633SMatthew G. Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 10098e7ff633SMatthew G. Knepley ierr = DMPlexView_Ascii(cdm, viewer);CHKERRQ(ierr); 10108e7ff633SMatthew G. Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 10118e7ff633SMatthew G. Knepley } 1012552f7358SJed Brown } 1013552f7358SJed Brown PetscFunctionReturn(0); 1014552f7358SJed Brown } 1015552f7358SJed Brown 10167cd05799SMatthew G. Knepley static PetscErrorCode DMPlexView_Draw(DM dm, PetscViewer viewer) 1017e412dcbdSMatthew G. Knepley { 1018e412dcbdSMatthew G. Knepley PetscDraw draw; 1019e412dcbdSMatthew G. Knepley DM cdm; 1020e412dcbdSMatthew G. Knepley PetscSection coordSection; 1021e412dcbdSMatthew G. Knepley Vec coordinates; 1022e412dcbdSMatthew G. Knepley const PetscScalar *coords; 102329494db1SLisandro Dalcin PetscReal xyl[2],xyr[2],bound[4] = {PETSC_MAX_REAL, PETSC_MAX_REAL, PETSC_MIN_REAL, PETSC_MIN_REAL}; 1024e412dcbdSMatthew G. Knepley PetscBool isnull; 1025e412dcbdSMatthew G. Knepley PetscInt dim, vStart, vEnd, cStart, cEnd, c, N; 1026cf3064d3SMatthew G. Knepley PetscMPIInt rank; 1027e412dcbdSMatthew G. Knepley PetscErrorCode ierr; 1028e412dcbdSMatthew G. Knepley 1029e412dcbdSMatthew G. Knepley PetscFunctionBegin; 1030e412dcbdSMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dim);CHKERRQ(ierr); 1031e412dcbdSMatthew G. Knepley if (dim != 2) SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Cannot draw meshes of dimension %D", dim); 1032e412dcbdSMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 1033e87a4003SBarry Smith ierr = DMGetSection(cdm, &coordSection);CHKERRQ(ierr); 1034e412dcbdSMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 1035e412dcbdSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 1036e412dcbdSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 1037e412dcbdSMatthew G. Knepley 1038e412dcbdSMatthew G. Knepley ierr = PetscViewerDrawGetDraw(viewer, 0, &draw);CHKERRQ(ierr); 1039e412dcbdSMatthew G. Knepley ierr = PetscDrawIsNull(draw, &isnull);CHKERRQ(ierr); 1040e412dcbdSMatthew G. Knepley if (isnull) PetscFunctionReturn(0); 1041e412dcbdSMatthew G. Knepley ierr = PetscDrawSetTitle(draw, "Mesh");CHKERRQ(ierr); 1042e412dcbdSMatthew G. Knepley 1043e412dcbdSMatthew G. Knepley ierr = VecGetLocalSize(coordinates, &N);CHKERRQ(ierr); 1044e412dcbdSMatthew G. Knepley ierr = VecGetArrayRead(coordinates, &coords);CHKERRQ(ierr); 1045e412dcbdSMatthew G. Knepley for (c = 0; c < N; c += dim) { 10460c81f2a8SMatthew G. Knepley bound[0] = PetscMin(bound[0], PetscRealPart(coords[c])); bound[2] = PetscMax(bound[2], PetscRealPart(coords[c])); 10470c81f2a8SMatthew G. Knepley bound[1] = PetscMin(bound[1], PetscRealPart(coords[c+1])); bound[3] = PetscMax(bound[3], PetscRealPart(coords[c+1])); 1048e412dcbdSMatthew G. Knepley } 1049e412dcbdSMatthew G. Knepley ierr = VecRestoreArrayRead(coordinates, &coords);CHKERRQ(ierr); 105029494db1SLisandro Dalcin ierr = MPIU_Allreduce(&bound[0],xyl,2,MPIU_REAL,MPIU_MIN,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 105129494db1SLisandro Dalcin ierr = MPIU_Allreduce(&bound[2],xyr,2,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 105229494db1SLisandro Dalcin ierr = PetscDrawSetCoordinates(draw, xyl[0], xyl[1], xyr[0], xyr[1]);CHKERRQ(ierr); 1053e412dcbdSMatthew G. Knepley ierr = PetscDrawClear(draw);CHKERRQ(ierr); 1054e412dcbdSMatthew G. Knepley 1055cf3064d3SMatthew G. Knepley ierr = MPI_Comm_rank(PetscObjectComm((PetscObject) dm), &rank);CHKERRQ(ierr); 1056cf3064d3SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 1057cf3064d3SMatthew G. Knepley PetscScalar *coords = NULL; 1058cf3064d3SMatthew G. Knepley PetscInt numCoords,coneSize; 1059cf3064d3SMatthew G. Knepley 1060cf3064d3SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, c, &coneSize);CHKERRQ(ierr); 1061cf3064d3SMatthew G. Knepley ierr = DMPlexVecGetClosure(dm, coordSection, coordinates, c, &numCoords, &coords);CHKERRQ(ierr); 1062cf3064d3SMatthew G. Knepley switch (coneSize) { 1063cf3064d3SMatthew G. Knepley case 3: 1064cf3064d3SMatthew G. Knepley ierr = PetscDrawTriangle(draw, PetscRealPart(coords[0]), PetscRealPart(coords[1]), PetscRealPart(coords[2]), PetscRealPart(coords[3]), PetscRealPart(coords[4]), PetscRealPart(coords[5]), 1065cf3064d3SMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2, 1066cf3064d3SMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2, 1067cf3064d3SMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2);CHKERRQ(ierr); 1068cf3064d3SMatthew G. Knepley break; 1069cf3064d3SMatthew G. Knepley case 4: 1070cf3064d3SMatthew G. Knepley ierr = PetscDrawRectangle(draw, PetscRealPart(coords[0]), PetscRealPart(coords[1]), PetscRealPart(coords[4]), PetscRealPart(coords[5]), 1071cf3064d3SMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2, 1072cf3064d3SMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2, 1073cf3064d3SMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2, 1074cf3064d3SMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2);CHKERRQ(ierr); 1075cf3064d3SMatthew G. Knepley break; 1076cf3064d3SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot draw cells with %D facets", coneSize); 1077cf3064d3SMatthew G. Knepley } 1078cf3064d3SMatthew G. Knepley ierr = DMPlexVecRestoreClosure(dm, coordSection, coordinates, c, &numCoords, &coords);CHKERRQ(ierr); 1079cf3064d3SMatthew G. Knepley } 1080e412dcbdSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 1081e412dcbdSMatthew G. Knepley PetscScalar *coords = NULL; 108229494db1SLisandro Dalcin PetscInt numCoords,coneSize; 1083e412dcbdSMatthew G. Knepley 108429494db1SLisandro Dalcin ierr = DMPlexGetConeSize(dm, c, &coneSize);CHKERRQ(ierr); 1085e412dcbdSMatthew G. Knepley ierr = DMPlexVecGetClosure(dm, coordSection, coordinates, c, &numCoords, &coords);CHKERRQ(ierr); 108629494db1SLisandro Dalcin switch (coneSize) { 108729494db1SLisandro Dalcin case 3: 10880c81f2a8SMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[0]), PetscRealPart(coords[1]), PetscRealPart(coords[2]), PetscRealPart(coords[3]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 10890c81f2a8SMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[2]), PetscRealPart(coords[3]), PetscRealPart(coords[4]), PetscRealPart(coords[5]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 10900c81f2a8SMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[4]), PetscRealPart(coords[5]), PetscRealPart(coords[0]), PetscRealPart(coords[1]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 1091e412dcbdSMatthew G. Knepley break; 109229494db1SLisandro Dalcin case 4: 10930c81f2a8SMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[0]), PetscRealPart(coords[1]), PetscRealPart(coords[2]), PetscRealPart(coords[3]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 10940c81f2a8SMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[2]), PetscRealPart(coords[3]), PetscRealPart(coords[4]), PetscRealPart(coords[5]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 10950c81f2a8SMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[4]), PetscRealPart(coords[5]), PetscRealPart(coords[6]), PetscRealPart(coords[7]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 10960c81f2a8SMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[6]), PetscRealPart(coords[7]), PetscRealPart(coords[0]), PetscRealPart(coords[1]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 1097e412dcbdSMatthew G. Knepley break; 109829494db1SLisandro Dalcin default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot draw cells with %D facets", coneSize); 1099e412dcbdSMatthew G. Knepley } 1100e412dcbdSMatthew G. Knepley ierr = DMPlexVecRestoreClosure(dm, coordSection, coordinates, c, &numCoords, &coords);CHKERRQ(ierr); 1101e412dcbdSMatthew G. Knepley } 1102e412dcbdSMatthew G. Knepley ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 1103e412dcbdSMatthew G. Knepley ierr = PetscDrawPause(draw);CHKERRQ(ierr); 1104e412dcbdSMatthew G. Knepley ierr = PetscDrawSave(draw);CHKERRQ(ierr); 1105e412dcbdSMatthew G. Knepley PetscFunctionReturn(0); 1106e412dcbdSMatthew G. Knepley } 1107e412dcbdSMatthew G. Knepley 1108552f7358SJed Brown PetscErrorCode DMView_Plex(DM dm, PetscViewer viewer) 1109552f7358SJed Brown { 1110e655db49SSatish Balay PetscBool iascii, ishdf5, isvtk, isdraw, flg, isglvis; 1111002a2709SMatthew G. Knepley char name[PETSC_MAX_PATH_LEN]; 1112552f7358SJed Brown PetscErrorCode ierr; 1113552f7358SJed Brown 1114552f7358SJed Brown PetscFunctionBegin; 1115552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1116552f7358SJed Brown PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1117552f7358SJed Brown ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 1118fcf6c8fdSToby Isaac ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERVTK, &isvtk);CHKERRQ(ierr); 1119c6ccd67eSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 1120e412dcbdSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERDRAW, &isdraw);CHKERRQ(ierr); 11218135c375SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERGLVIS, &isglvis);CHKERRQ(ierr); 1122552f7358SJed Brown if (iascii) { 11238135c375SStefano Zampini PetscViewerFormat format; 11248135c375SStefano Zampini ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 11258135c375SStefano Zampini if (format == PETSC_VIEWER_ASCII_GLVIS) { 11268135c375SStefano Zampini ierr = DMPlexView_GLVis(dm, viewer);CHKERRQ(ierr); 11278135c375SStefano Zampini } else { 1128552f7358SJed Brown ierr = DMPlexView_Ascii(dm, viewer);CHKERRQ(ierr); 11298135c375SStefano Zampini } 1130c6ccd67eSMatthew G. Knepley } else if (ishdf5) { 1131c6ccd67eSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 113239d25373SMatthew G. Knepley ierr = DMPlexView_HDF5_Internal(dm, viewer);CHKERRQ(ierr); 1133c6ccd67eSMatthew G. Knepley #else 1134c6ccd67eSMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 1135552f7358SJed Brown #endif 1136e412dcbdSMatthew G. Knepley } else if (isvtk) { 1137fcf6c8fdSToby Isaac ierr = DMPlexVTKWriteAll((PetscObject) dm,viewer);CHKERRQ(ierr); 1138e412dcbdSMatthew G. Knepley } else if (isdraw) { 1139e412dcbdSMatthew G. Knepley ierr = DMPlexView_Draw(dm, viewer);CHKERRQ(ierr); 11408135c375SStefano Zampini } else if (isglvis) { 11418135c375SStefano Zampini ierr = DMPlexView_GLVis(dm, viewer);CHKERRQ(ierr); 114262201deeSVaclav Hapla } else { 1143a94aea51SVaclav Hapla SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Viewer type %s not yet supported for DMPlex writing", ((PetscObject)viewer)->type_name); 1144fcf6c8fdSToby Isaac } 1145cb3ba0daSMatthew G. Knepley /* Optionally view the partition */ 1146cb3ba0daSMatthew G. Knepley ierr = PetscOptionsHasName(((PetscObject) dm)->options, ((PetscObject) dm)->prefix, "-dm_partition_view", &flg);CHKERRQ(ierr); 1147cb3ba0daSMatthew G. Knepley if (flg) { 1148cb3ba0daSMatthew G. Knepley Vec ranks; 1149cb3ba0daSMatthew G. Knepley ierr = DMPlexCreateRankField(dm, &ranks);CHKERRQ(ierr); 1150cb3ba0daSMatthew G. Knepley ierr = VecView(ranks, viewer);CHKERRQ(ierr); 1151cb3ba0daSMatthew G. Knepley ierr = VecDestroy(&ranks);CHKERRQ(ierr); 1152cb3ba0daSMatthew G. Knepley } 1153002a2709SMatthew G. Knepley /* Optionally view a label */ 1154002a2709SMatthew G. Knepley ierr = PetscOptionsGetString(((PetscObject) dm)->options, ((PetscObject) dm)->prefix, "-dm_label_view", name, PETSC_MAX_PATH_LEN, &flg);CHKERRQ(ierr); 1155002a2709SMatthew G. Knepley if (flg) { 1156002a2709SMatthew G. Knepley DMLabel label; 1157002a2709SMatthew G. Knepley Vec val; 1158002a2709SMatthew G. Knepley 1159002a2709SMatthew G. Knepley ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 1160002a2709SMatthew G. Knepley if (!label) SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Label %s provided to -dm_label_view does not exist in this DM", name); 1161002a2709SMatthew G. Knepley ierr = DMPlexCreateLabelField(dm, label, &val);CHKERRQ(ierr); 1162002a2709SMatthew G. Knepley ierr = VecView(val, viewer);CHKERRQ(ierr); 1163002a2709SMatthew G. Knepley ierr = VecDestroy(&val);CHKERRQ(ierr); 1164002a2709SMatthew G. Knepley } 1165552f7358SJed Brown PetscFunctionReturn(0); 1166552f7358SJed Brown } 1167552f7358SJed Brown 11682c40f234SMatthew G. Knepley PetscErrorCode DMLoad_Plex(DM dm, PetscViewer viewer) 11692c40f234SMatthew G. Knepley { 1170d4f5a9a0SVaclav Hapla PetscBool ishdf5; 11712c40f234SMatthew G. Knepley PetscErrorCode ierr; 11722c40f234SMatthew G. Knepley 11732c40f234SMatthew G. Knepley PetscFunctionBegin; 11742c40f234SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 11752c40f234SMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 11762c40f234SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 1177d4f5a9a0SVaclav Hapla if (ishdf5) { 11782c40f234SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 11799c48423bSVaclav Hapla PetscViewerFormat format; 11809c48423bSVaclav Hapla ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 11819c48423bSVaclav Hapla if (format == PETSC_VIEWER_HDF5_XDMF || format == PETSC_VIEWER_HDF5_VIZ) { 11829c48423bSVaclav Hapla ierr = DMPlexLoad_HDF5_Xdmf_Internal(dm, viewer);CHKERRQ(ierr); 1183509517efSVaclav Hapla } else if (format == PETSC_VIEWER_HDF5_PETSC || format == PETSC_VIEWER_DEFAULT || format == PETSC_VIEWER_NATIVE) { 118439d25373SMatthew G. Knepley ierr = DMPlexLoad_HDF5_Internal(dm, viewer);CHKERRQ(ierr); 1185509517efSVaclav Hapla } else SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "PetscViewerFormat %s not supported for HDF5 input.", PetscViewerFormats[format]); 11862c40f234SMatthew G. Knepley #else 11872c40f234SMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 1188552f7358SJed Brown #endif 1189d4f5a9a0SVaclav Hapla } else { 1190d4f5a9a0SVaclav Hapla SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Viewer type %s not yet supported for DMPlex loading", ((PetscObject)viewer)->type_name); 1191552f7358SJed Brown } 1192552f7358SJed Brown PetscFunctionReturn(0); 1193552f7358SJed Brown } 1194552f7358SJed Brown 1195552f7358SJed Brown PetscErrorCode DMDestroy_Plex(DM dm) 1196552f7358SJed Brown { 1197552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1198552f7358SJed Brown PetscErrorCode ierr; 1199552f7358SJed Brown 1200552f7358SJed Brown PetscFunctionBegin; 12018135c375SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)dm,"DMSetUpGLVisViewer_C",NULL);CHKERRQ(ierr); 12028135c375SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)dm,"DMPlexInsertBoundaryValues_C", NULL);CHKERRQ(ierr); 12030d644c17SKarl Rupp if (--mesh->refct > 0) PetscFunctionReturn(0); 1204552f7358SJed Brown ierr = PetscSectionDestroy(&mesh->coneSection);CHKERRQ(ierr); 1205552f7358SJed Brown ierr = PetscFree(mesh->cones);CHKERRQ(ierr); 1206552f7358SJed Brown ierr = PetscFree(mesh->coneOrientations);CHKERRQ(ierr); 1207552f7358SJed Brown ierr = PetscSectionDestroy(&mesh->supportSection);CHKERRQ(ierr); 1208be36d101SStefano Zampini ierr = PetscSectionDestroy(&mesh->subdomainSection);CHKERRQ(ierr); 1209552f7358SJed Brown ierr = PetscFree(mesh->supports);CHKERRQ(ierr); 1210552f7358SJed Brown ierr = PetscFree(mesh->facesTmp);CHKERRQ(ierr); 1211d9deefdfSMatthew G. Knepley ierr = PetscFree(mesh->tetgenOpts);CHKERRQ(ierr); 1212d9deefdfSMatthew G. Knepley ierr = PetscFree(mesh->triangleOpts);CHKERRQ(ierr); 121377623264SMatthew G. Knepley ierr = PetscPartitionerDestroy(&mesh->partitioner);CHKERRQ(ierr); 1214a89082eeSMatthew G Knepley ierr = DMLabelDestroy(&mesh->subpointMap);CHKERRQ(ierr); 1215552f7358SJed Brown ierr = ISDestroy(&mesh->globalVertexNumbers);CHKERRQ(ierr); 1216552f7358SJed Brown ierr = ISDestroy(&mesh->globalCellNumbers);CHKERRQ(ierr); 1217a68b90caSToby Isaac ierr = PetscSectionDestroy(&mesh->anchorSection);CHKERRQ(ierr); 1218a68b90caSToby Isaac ierr = ISDestroy(&mesh->anchorIS);CHKERRQ(ierr); 1219d961a43aSToby Isaac ierr = PetscSectionDestroy(&mesh->parentSection);CHKERRQ(ierr); 1220d961a43aSToby Isaac ierr = PetscFree(mesh->parents);CHKERRQ(ierr); 1221d961a43aSToby Isaac ierr = PetscFree(mesh->childIDs);CHKERRQ(ierr); 1222d961a43aSToby Isaac ierr = PetscSectionDestroy(&mesh->childSection);CHKERRQ(ierr); 1223d961a43aSToby Isaac ierr = PetscFree(mesh->children);CHKERRQ(ierr); 1224d6a7ad0dSToby Isaac ierr = DMDestroy(&mesh->referenceTree);CHKERRQ(ierr); 1225fec49543SMatthew G. Knepley ierr = PetscGridHashDestroy(&mesh->lbox);CHKERRQ(ierr); 1226552f7358SJed Brown /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */ 1227552f7358SJed Brown ierr = PetscFree(mesh);CHKERRQ(ierr); 1228552f7358SJed Brown PetscFunctionReturn(0); 1229552f7358SJed Brown } 1230552f7358SJed Brown 1231b412c318SBarry Smith PetscErrorCode DMCreateMatrix_Plex(DM dm, Mat *J) 1232552f7358SJed Brown { 12338d1174e4SMatthew G. Knepley PetscSection sectionGlobal; 1234acd755d7SMatthew G. Knepley PetscInt bs = -1, mbs; 1235552f7358SJed Brown PetscInt localSize; 1236837628f4SStefano Zampini PetscBool isShell, isBlock, isSeqBlock, isMPIBlock, isSymBlock, isSymSeqBlock, isSymMPIBlock, isMatIS; 1237552f7358SJed Brown PetscErrorCode ierr; 1238b412c318SBarry Smith MatType mtype; 12391428887cSShri Abhyankar ISLocalToGlobalMapping ltog; 1240552f7358SJed Brown 1241552f7358SJed Brown PetscFunctionBegin; 1242607a6623SBarry Smith ierr = MatInitializePackage();CHKERRQ(ierr); 1243b412c318SBarry Smith mtype = dm->mattype; 1244e87a4003SBarry Smith ierr = DMGetGlobalSection(dm, §ionGlobal);CHKERRQ(ierr); 1245552f7358SJed Brown /* ierr = PetscSectionGetStorageSize(sectionGlobal, &localSize);CHKERRQ(ierr); */ 1246552f7358SJed Brown ierr = PetscSectionGetConstrainedStorageSize(sectionGlobal, &localSize);CHKERRQ(ierr); 124782f516ccSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)dm), J);CHKERRQ(ierr); 1248552f7358SJed Brown ierr = MatSetSizes(*J, localSize, localSize, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 1249552f7358SJed Brown ierr = MatSetType(*J, mtype);CHKERRQ(ierr); 1250552f7358SJed Brown ierr = MatSetFromOptions(*J);CHKERRQ(ierr); 1251acd755d7SMatthew G. Knepley ierr = MatGetBlockSize(*J, &mbs);CHKERRQ(ierr); 1252acd755d7SMatthew G. Knepley if (mbs > 1) bs = mbs; 1253552f7358SJed Brown ierr = PetscStrcmp(mtype, MATSHELL, &isShell);CHKERRQ(ierr); 1254552f7358SJed Brown ierr = PetscStrcmp(mtype, MATBAIJ, &isBlock);CHKERRQ(ierr); 1255552f7358SJed Brown ierr = PetscStrcmp(mtype, MATSEQBAIJ, &isSeqBlock);CHKERRQ(ierr); 1256552f7358SJed Brown ierr = PetscStrcmp(mtype, MATMPIBAIJ, &isMPIBlock);CHKERRQ(ierr); 1257552f7358SJed Brown ierr = PetscStrcmp(mtype, MATSBAIJ, &isSymBlock);CHKERRQ(ierr); 1258552f7358SJed Brown ierr = PetscStrcmp(mtype, MATSEQSBAIJ, &isSymSeqBlock);CHKERRQ(ierr); 1259552f7358SJed Brown ierr = PetscStrcmp(mtype, MATMPISBAIJ, &isSymMPIBlock);CHKERRQ(ierr); 1260837628f4SStefano Zampini ierr = PetscStrcmp(mtype, MATIS, &isMatIS);CHKERRQ(ierr); 1261552f7358SJed Brown if (!isShell) { 1262be36d101SStefano Zampini PetscSection subSection; 1263837628f4SStefano Zampini PetscBool fillMatrix = (PetscBool)(!dm->prealloc_only && !isMatIS); 12640be3e97aSMatthew G. Knepley PetscInt *dnz, *onz, *dnzu, *onzu, bsLocal[2], bsMinMax[2], *ltogidx, lsize; 1265fad22124SMatthew G Knepley PetscInt pStart, pEnd, p, dof, cdof; 1266552f7358SJed Brown 126700140cc3SStefano Zampini /* Set localtoglobalmapping on the matrix for MatSetValuesLocal() to work (it also creates the local matrices in case of MATIS) */ 1268be36d101SStefano Zampini if (isMatIS) { /* need a different l2g map than the one computed by DMGetLocalToGlobalMapping */ 1269be36d101SStefano Zampini PetscSection section; 1270be36d101SStefano Zampini PetscInt size; 1271be36d101SStefano Zampini 1272e87a4003SBarry Smith ierr = DMGetSection(dm, §ion);CHKERRQ(ierr); 1273be36d101SStefano Zampini ierr = PetscSectionGetStorageSize(section, &size);CHKERRQ(ierr); 1274be36d101SStefano Zampini ierr = PetscMalloc1(size,<ogidx);CHKERRQ(ierr); 1275be36d101SStefano Zampini ierr = DMPlexGetSubdomainSection(dm, &subSection);CHKERRQ(ierr); 1276be36d101SStefano Zampini } else { 127700140cc3SStefano Zampini ierr = DMGetLocalToGlobalMapping(dm,<og);CHKERRQ(ierr); 1278be36d101SStefano Zampini } 1279552f7358SJed Brown ierr = PetscSectionGetChart(sectionGlobal, &pStart, &pEnd);CHKERRQ(ierr); 1280be36d101SStefano Zampini for (p = pStart, lsize = 0; p < pEnd; ++p) { 1281a9d99c84SMatthew G. Knepley PetscInt bdof; 1282a9d99c84SMatthew G. Knepley 1283552f7358SJed Brown ierr = PetscSectionGetDof(sectionGlobal, p, &dof);CHKERRQ(ierr); 1284fad22124SMatthew G Knepley ierr = PetscSectionGetConstraintDof(sectionGlobal, p, &cdof);CHKERRQ(ierr); 12851d17a0a3SMatthew G. Knepley dof = dof < 0 ? -(dof+1) : dof; 12861d17a0a3SMatthew G. Knepley bdof = cdof && (dof-cdof) ? 1 : dof; 12871d17a0a3SMatthew G. Knepley if (dof) { 12881d17a0a3SMatthew G. Knepley if (bs < 0) {bs = bdof;} 1289be36d101SStefano Zampini else if (bs != bdof) {bs = 1; if (!isMatIS) break;} 1290be36d101SStefano Zampini } 1291be36d101SStefano Zampini if (isMatIS) { 1292be36d101SStefano Zampini PetscInt loff,c,off; 1293be36d101SStefano Zampini ierr = PetscSectionGetOffset(subSection, p, &loff);CHKERRQ(ierr); 1294be36d101SStefano Zampini ierr = PetscSectionGetOffset(sectionGlobal, p, &off);CHKERRQ(ierr); 1295be36d101SStefano Zampini for (c = 0; c < dof-cdof; ++c, ++lsize) ltogidx[loff+c] = off > -1 ? off+c : -(off+1)+c; 1296552f7358SJed Brown } 12972a28c762SMatthew G Knepley } 12982a28c762SMatthew G Knepley /* Must have same blocksize on all procs (some might have no points) */ 12990be3e97aSMatthew G. Knepley bsLocal[0] = bs < 0 ? PETSC_MAX_INT : bs; bsLocal[1] = bs; 13000be3e97aSMatthew G. Knepley ierr = PetscGlobalMinMaxInt(PetscObjectComm((PetscObject) dm), bsLocal, bsMinMax);CHKERRQ(ierr); 13010be3e97aSMatthew G. Knepley if (bsMinMax[0] != bsMinMax[1]) {bs = 1;} 13020be3e97aSMatthew G. Knepley else {bs = bsMinMax[0];} 13034fa26246SMatthew G. Knepley bs = bs < 0 ? 1 : bs; 1304be36d101SStefano Zampini if (isMatIS) { 13054fa26246SMatthew G. Knepley PetscInt l; 13064fa26246SMatthew G. Knepley /* Must reduce indices by blocksize */ 13074fa26246SMatthew G. Knepley if (bs > 1) for (l = 0; l < lsize; ++l) ltogidx[l] /= bs; 13084fa26246SMatthew G. Knepley ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)dm), bs, lsize, ltogidx, PETSC_OWN_POINTER, <og);CHKERRQ(ierr); 1309be36d101SStefano Zampini } 1310be36d101SStefano Zampini ierr = MatSetLocalToGlobalMapping(*J,ltog,ltog);CHKERRQ(ierr); 1311be36d101SStefano Zampini if (isMatIS) { 1312be36d101SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(<og);CHKERRQ(ierr); 1313be36d101SStefano Zampini } 13141795a4d1SJed Brown ierr = PetscCalloc4(localSize/bs, &dnz, localSize/bs, &onz, localSize/bs, &dnzu, localSize/bs, &onzu);CHKERRQ(ierr); 13158d1174e4SMatthew G. Knepley ierr = DMPlexPreallocateOperator(dm, bs, dnz, onz, dnzu, onzu, *J, fillMatrix);CHKERRQ(ierr); 1316552f7358SJed Brown ierr = PetscFree4(dnz, onz, dnzu, onzu);CHKERRQ(ierr); 1317552f7358SJed Brown } 1318b1f74addSMatthew G. Knepley ierr = MatSetDM(*J, dm);CHKERRQ(ierr); 1319552f7358SJed Brown PetscFunctionReturn(0); 1320552f7358SJed Brown } 1321552f7358SJed Brown 13227cd05799SMatthew G. Knepley /*@ 1323a8f00d21SMatthew G. Knepley DMPlexGetSubdomainSection - Returns the section associated with the subdomain 1324be36d101SStefano Zampini 1325be36d101SStefano Zampini Not collective 1326be36d101SStefano Zampini 1327be36d101SStefano Zampini Input Parameter: 1328be36d101SStefano Zampini . mesh - The DMPlex 1329be36d101SStefano Zampini 1330be36d101SStefano Zampini Output Parameters: 1331be36d101SStefano Zampini . subsection - The subdomain section 1332be36d101SStefano Zampini 1333be36d101SStefano Zampini Level: developer 1334be36d101SStefano Zampini 1335be36d101SStefano Zampini .seealso: 13367cd05799SMatthew G. Knepley @*/ 1337be36d101SStefano Zampini PetscErrorCode DMPlexGetSubdomainSection(DM dm, PetscSection *subsection) 1338be36d101SStefano Zampini { 1339be36d101SStefano Zampini DM_Plex *mesh = (DM_Plex*) dm->data; 1340be36d101SStefano Zampini PetscErrorCode ierr; 1341be36d101SStefano Zampini 1342be36d101SStefano Zampini PetscFunctionBegin; 1343be36d101SStefano Zampini PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1344be36d101SStefano Zampini if (!mesh->subdomainSection) { 1345be36d101SStefano Zampini PetscSection section; 1346be36d101SStefano Zampini PetscSF sf; 1347be36d101SStefano Zampini 1348be36d101SStefano Zampini ierr = PetscSFCreate(PETSC_COMM_SELF,&sf);CHKERRQ(ierr); 1349e87a4003SBarry Smith ierr = DMGetSection(dm,§ion);CHKERRQ(ierr); 1350be36d101SStefano Zampini ierr = PetscSectionCreateGlobalSection(section,sf,PETSC_FALSE,PETSC_TRUE,&mesh->subdomainSection);CHKERRQ(ierr); 1351be36d101SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 1352be36d101SStefano Zampini } 1353be36d101SStefano Zampini *subsection = mesh->subdomainSection; 1354be36d101SStefano Zampini PetscFunctionReturn(0); 1355be36d101SStefano Zampini } 1356be36d101SStefano Zampini 1357552f7358SJed Brown /*@ 1358552f7358SJed Brown DMPlexGetChart - Return the interval for all mesh points [pStart, pEnd) 1359552f7358SJed Brown 1360552f7358SJed Brown Not collective 1361552f7358SJed Brown 1362552f7358SJed Brown Input Parameter: 1363552f7358SJed Brown . mesh - The DMPlex 1364552f7358SJed Brown 1365552f7358SJed Brown Output Parameters: 1366552f7358SJed Brown + pStart - The first mesh point 1367552f7358SJed Brown - pEnd - The upper bound for mesh points 1368552f7358SJed Brown 1369552f7358SJed Brown Level: beginner 1370552f7358SJed Brown 1371552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetChart() 1372552f7358SJed Brown @*/ 1373552f7358SJed Brown PetscErrorCode DMPlexGetChart(DM dm, PetscInt *pStart, PetscInt *pEnd) 1374552f7358SJed Brown { 1375552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1376552f7358SJed Brown PetscErrorCode ierr; 1377552f7358SJed Brown 1378552f7358SJed Brown PetscFunctionBegin; 1379552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1380552f7358SJed Brown ierr = PetscSectionGetChart(mesh->coneSection, pStart, pEnd);CHKERRQ(ierr); 1381552f7358SJed Brown PetscFunctionReturn(0); 1382552f7358SJed Brown } 1383552f7358SJed Brown 1384552f7358SJed Brown /*@ 1385552f7358SJed Brown DMPlexSetChart - Set the interval for all mesh points [pStart, pEnd) 1386552f7358SJed Brown 1387552f7358SJed Brown Not collective 1388552f7358SJed Brown 1389552f7358SJed Brown Input Parameters: 1390552f7358SJed Brown + mesh - The DMPlex 1391552f7358SJed Brown . pStart - The first mesh point 1392552f7358SJed Brown - pEnd - The upper bound for mesh points 1393552f7358SJed Brown 1394552f7358SJed Brown Output Parameters: 1395552f7358SJed Brown 1396552f7358SJed Brown Level: beginner 1397552f7358SJed Brown 1398552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetChart() 1399552f7358SJed Brown @*/ 1400552f7358SJed Brown PetscErrorCode DMPlexSetChart(DM dm, PetscInt pStart, PetscInt pEnd) 1401552f7358SJed Brown { 1402552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1403552f7358SJed Brown PetscErrorCode ierr; 1404552f7358SJed Brown 1405552f7358SJed Brown PetscFunctionBegin; 1406552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1407552f7358SJed Brown ierr = PetscSectionSetChart(mesh->coneSection, pStart, pEnd);CHKERRQ(ierr); 1408552f7358SJed Brown ierr = PetscSectionSetChart(mesh->supportSection, pStart, pEnd);CHKERRQ(ierr); 1409552f7358SJed Brown PetscFunctionReturn(0); 1410552f7358SJed Brown } 1411552f7358SJed Brown 1412552f7358SJed Brown /*@ 1413eaf898f9SPatrick Sanan DMPlexGetConeSize - Return the number of in-edges for this point in the DAG 1414552f7358SJed Brown 1415552f7358SJed Brown Not collective 1416552f7358SJed Brown 1417552f7358SJed Brown Input Parameters: 1418552f7358SJed Brown + mesh - The DMPlex 1419eaf898f9SPatrick Sanan - p - The point, which must lie in the chart set with DMPlexSetChart() 1420552f7358SJed Brown 1421552f7358SJed Brown Output Parameter: 1422552f7358SJed Brown . size - The cone size for point p 1423552f7358SJed Brown 1424552f7358SJed Brown Level: beginner 1425552f7358SJed Brown 1426552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetConeSize(), DMPlexSetChart() 1427552f7358SJed Brown @*/ 1428552f7358SJed Brown PetscErrorCode DMPlexGetConeSize(DM dm, PetscInt p, PetscInt *size) 1429552f7358SJed Brown { 1430552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1431552f7358SJed Brown PetscErrorCode ierr; 1432552f7358SJed Brown 1433552f7358SJed Brown PetscFunctionBegin; 1434552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1435552f7358SJed Brown PetscValidPointer(size, 3); 1436552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, size);CHKERRQ(ierr); 1437552f7358SJed Brown PetscFunctionReturn(0); 1438552f7358SJed Brown } 1439552f7358SJed Brown 1440552f7358SJed Brown /*@ 1441eaf898f9SPatrick Sanan DMPlexSetConeSize - Set the number of in-edges for this point in the DAG 1442552f7358SJed Brown 1443552f7358SJed Brown Not collective 1444552f7358SJed Brown 1445552f7358SJed Brown Input Parameters: 1446552f7358SJed Brown + mesh - The DMPlex 1447eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 1448552f7358SJed Brown - size - The cone size for point p 1449552f7358SJed Brown 1450552f7358SJed Brown Output Parameter: 1451552f7358SJed Brown 1452552f7358SJed Brown Note: 1453552f7358SJed Brown This should be called after DMPlexSetChart(). 1454552f7358SJed Brown 1455552f7358SJed Brown Level: beginner 1456552f7358SJed Brown 1457552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetConeSize(), DMPlexSetChart() 1458552f7358SJed Brown @*/ 1459552f7358SJed Brown PetscErrorCode DMPlexSetConeSize(DM dm, PetscInt p, PetscInt size) 1460552f7358SJed Brown { 1461552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1462552f7358SJed Brown PetscErrorCode ierr; 1463552f7358SJed Brown 1464552f7358SJed Brown PetscFunctionBegin; 1465552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1466552f7358SJed Brown ierr = PetscSectionSetDof(mesh->coneSection, p, size);CHKERRQ(ierr); 14670d644c17SKarl Rupp 1468552f7358SJed Brown mesh->maxConeSize = PetscMax(mesh->maxConeSize, size); 1469552f7358SJed Brown PetscFunctionReturn(0); 1470552f7358SJed Brown } 1471552f7358SJed Brown 1472f5a469b9SMatthew G. Knepley /*@ 1473eaf898f9SPatrick Sanan DMPlexAddConeSize - Add the given number of in-edges to this point in the DAG 1474f5a469b9SMatthew G. Knepley 1475f5a469b9SMatthew G. Knepley Not collective 1476f5a469b9SMatthew G. Knepley 1477f5a469b9SMatthew G. Knepley Input Parameters: 1478f5a469b9SMatthew G. Knepley + mesh - The DMPlex 1479eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 1480f5a469b9SMatthew G. Knepley - size - The additional cone size for point p 1481f5a469b9SMatthew G. Knepley 1482f5a469b9SMatthew G. Knepley Output Parameter: 1483f5a469b9SMatthew G. Knepley 1484f5a469b9SMatthew G. Knepley Note: 1485f5a469b9SMatthew G. Knepley This should be called after DMPlexSetChart(). 1486f5a469b9SMatthew G. Knepley 1487f5a469b9SMatthew G. Knepley Level: beginner 1488f5a469b9SMatthew G. Knepley 1489f5a469b9SMatthew G. Knepley .seealso: DMPlexCreate(), DMPlexSetConeSize(), DMPlexGetConeSize(), DMPlexSetChart() 1490f5a469b9SMatthew G. Knepley @*/ 1491f5a469b9SMatthew G. Knepley PetscErrorCode DMPlexAddConeSize(DM dm, PetscInt p, PetscInt size) 1492f5a469b9SMatthew G. Knepley { 1493f5a469b9SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 1494f5a469b9SMatthew G. Knepley PetscInt csize; 1495f5a469b9SMatthew G. Knepley PetscErrorCode ierr; 1496f5a469b9SMatthew G. Knepley 1497f5a469b9SMatthew G. Knepley PetscFunctionBegin; 1498f5a469b9SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1499f5a469b9SMatthew G. Knepley ierr = PetscSectionAddDof(mesh->coneSection, p, size);CHKERRQ(ierr); 1500f5a469b9SMatthew G. Knepley ierr = PetscSectionGetDof(mesh->coneSection, p, &csize);CHKERRQ(ierr); 1501f5a469b9SMatthew G. Knepley 1502f5a469b9SMatthew G. Knepley mesh->maxConeSize = PetscMax(mesh->maxConeSize, csize); 1503f5a469b9SMatthew G. Knepley PetscFunctionReturn(0); 1504f5a469b9SMatthew G. Knepley } 1505f5a469b9SMatthew G. Knepley 1506552f7358SJed Brown /*@C 1507eaf898f9SPatrick Sanan DMPlexGetCone - Return the points on the in-edges for this point in the DAG 1508552f7358SJed Brown 1509552f7358SJed Brown Not collective 1510552f7358SJed Brown 1511552f7358SJed Brown Input Parameters: 1512833c876bSVaclav Hapla + dm - The DMPlex 1513eaf898f9SPatrick Sanan - p - The point, which must lie in the chart set with DMPlexSetChart() 1514552f7358SJed Brown 1515552f7358SJed Brown Output Parameter: 1516552f7358SJed Brown . cone - An array of points which are on the in-edges for point p 1517552f7358SJed Brown 1518552f7358SJed Brown Level: beginner 1519552f7358SJed Brown 15203813dfbdSMatthew G Knepley Fortran Notes: 15213813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 15223813dfbdSMatthew G Knepley include petsc.h90 in your code. 15233813dfbdSMatthew G Knepley 15240ce7577fSVaclav Hapla .seealso: DMPlexCreate(), DMPlexSetCone(), DMPlexGetConeTuple(), DMPlexSetChart() 1525552f7358SJed Brown @*/ 1526552f7358SJed Brown PetscErrorCode DMPlexGetCone(DM dm, PetscInt p, const PetscInt *cone[]) 1527552f7358SJed Brown { 1528552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1529552f7358SJed Brown PetscInt off; 1530552f7358SJed Brown PetscErrorCode ierr; 1531552f7358SJed Brown 1532552f7358SJed Brown PetscFunctionBegin; 1533552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1534552f7358SJed Brown PetscValidPointer(cone, 3); 1535552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 1536552f7358SJed Brown *cone = &mesh->cones[off]; 1537552f7358SJed Brown PetscFunctionReturn(0); 1538552f7358SJed Brown } 1539552f7358SJed Brown 15400ce7577fSVaclav Hapla /*@C 15410ce7577fSVaclav Hapla DMPlexGetConeTuple - Return the points on the in-edges of several points in the DAG 15420ce7577fSVaclav Hapla 15430ce7577fSVaclav Hapla Not collective 15440ce7577fSVaclav Hapla 15450ce7577fSVaclav Hapla Input Parameters: 15460ce7577fSVaclav Hapla + dm - The DMPlex 15470ce7577fSVaclav Hapla - p - The IS of points, which must lie in the chart set with DMPlexSetChart() 15480ce7577fSVaclav Hapla 15490ce7577fSVaclav Hapla Output Parameter: 15500ce7577fSVaclav Hapla + pConesSection - PetscSection describing the layout of pCones 15510ce7577fSVaclav Hapla - pCones - An array of points which are on the in-edges for the point set p 15520ce7577fSVaclav Hapla 15530ce7577fSVaclav Hapla Level: intermediate 15540ce7577fSVaclav Hapla 1555d4636a37SVaclav Hapla .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexGetConeRecursive(), DMPlexSetChart() 15560ce7577fSVaclav Hapla @*/ 15570ce7577fSVaclav Hapla PetscErrorCode DMPlexGetConeTuple(DM dm, IS p, PetscSection *pConesSection, IS *pCones) 15580ce7577fSVaclav Hapla { 15590ce7577fSVaclav Hapla PetscSection cs, newcs; 15600ce7577fSVaclav Hapla PetscInt *cones; 15610ce7577fSVaclav Hapla PetscInt *newarr=NULL; 15620ce7577fSVaclav Hapla PetscInt n; 15630ce7577fSVaclav Hapla PetscErrorCode ierr; 15640ce7577fSVaclav Hapla 15650ce7577fSVaclav Hapla PetscFunctionBegin; 15660ce7577fSVaclav Hapla ierr = DMPlexGetCones(dm, &cones);CHKERRQ(ierr); 15670ce7577fSVaclav Hapla ierr = DMPlexGetConeSection(dm, &cs);CHKERRQ(ierr); 15680ce7577fSVaclav Hapla ierr = PetscSectionExtractDofsFromArray(cs, MPIU_INT, cones, p, &newcs, pCones ? ((void**)&newarr) : NULL);CHKERRQ(ierr); 15690ce7577fSVaclav Hapla if (pConesSection) *pConesSection = newcs; 15700ce7577fSVaclav Hapla if (pCones) { 15710ce7577fSVaclav Hapla ierr = PetscSectionGetStorageSize(newcs, &n);CHKERRQ(ierr); 15720ce7577fSVaclav Hapla ierr = ISCreateGeneral(PetscObjectComm((PetscObject)p), n, newarr, PETSC_OWN_POINTER, pCones);CHKERRQ(ierr); 15730ce7577fSVaclav Hapla } 15740ce7577fSVaclav Hapla PetscFunctionReturn(0); 15750ce7577fSVaclav Hapla } 15760ce7577fSVaclav Hapla 1577d4636a37SVaclav Hapla static PetscErrorCode DMPlexGetConeRecursive_Private(DM dm, PetscInt *n_inout, const PetscInt points[], PetscInt *offset_inout, PetscInt buf[]) 1578d4636a37SVaclav Hapla { 1579d4636a37SVaclav Hapla PetscInt p, n, cn, i; 1580d4636a37SVaclav Hapla const PetscInt *cone; 1581d4636a37SVaclav Hapla PetscErrorCode ierr; 1582d4636a37SVaclav Hapla 1583d4636a37SVaclav Hapla PetscFunctionBegin; 1584d4636a37SVaclav Hapla n = *n_inout; 1585d4636a37SVaclav Hapla *n_inout = 0; 1586d4636a37SVaclav Hapla for (i=0; i<n; i++) { 1587d4636a37SVaclav Hapla p = points[i]; 1588d4636a37SVaclav Hapla ierr = DMPlexGetConeSize(dm, p, &cn);CHKERRQ(ierr); 1589d4636a37SVaclav Hapla if (!cn) { 1590d4636a37SVaclav Hapla cn = 1; 1591d4636a37SVaclav Hapla if (buf) { 1592d4636a37SVaclav Hapla buf[*offset_inout] = p; 1593d4636a37SVaclav Hapla ++(*offset_inout); 1594d4636a37SVaclav Hapla } 1595d4636a37SVaclav Hapla } else { 1596d4636a37SVaclav Hapla ierr = DMPlexGetCone(dm, p, &cone);CHKERRQ(ierr); 1597d4636a37SVaclav Hapla ierr = DMPlexGetConeRecursive_Private(dm, &cn, cone, offset_inout, buf);CHKERRQ(ierr); 1598d4636a37SVaclav Hapla } 1599d4636a37SVaclav Hapla *n_inout += cn; 1600d4636a37SVaclav Hapla } 1601d4636a37SVaclav Hapla PetscFunctionReturn(0); 1602d4636a37SVaclav Hapla } 1603d4636a37SVaclav Hapla 1604d4636a37SVaclav Hapla /*@C 1605d4636a37SVaclav Hapla DMPlexGetConeRecursive - Like DMPlexGetConeTuple() but recursive, i.e. each cone point is expanded into a set of its own cone points until a vertex (DAG point with no cone) is reached. 1606d4636a37SVaclav Hapla 1607d4636a37SVaclav Hapla Not collective 1608d4636a37SVaclav Hapla 1609d4636a37SVaclav Hapla Input Parameters: 1610d4636a37SVaclav Hapla + dm - The DMPlex 1611d4636a37SVaclav Hapla - p - The IS of points, which must lie in the chart set with DMPlexSetChart() 1612d4636a37SVaclav Hapla 1613d4636a37SVaclav Hapla Output Parameter: 1614d4636a37SVaclav Hapla . pCones - An array of recursively expanded cones, i.e. containing only vertices, and each of them can be present multiple times 1615d4636a37SVaclav Hapla 1616d4636a37SVaclav Hapla Level: advanced 1617d4636a37SVaclav Hapla 1618d4636a37SVaclav Hapla .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexGetConeTuple() 1619d4636a37SVaclav Hapla @*/ 1620d4636a37SVaclav Hapla PetscErrorCode DMPlexGetConeRecursive(DM dm, IS p, IS *pCones) 1621d4636a37SVaclav Hapla { 1622d4636a37SVaclav Hapla const PetscInt *arr=NULL; 1623d4636a37SVaclav Hapla PetscInt *cpoints=NULL; 1624d4636a37SVaclav Hapla PetscInt n, cn; 1625d4636a37SVaclav Hapla PetscInt zero; 1626d4636a37SVaclav Hapla PetscErrorCode ierr; 1627d4636a37SVaclav Hapla 1628d4636a37SVaclav Hapla PetscFunctionBegin; 1629d4636a37SVaclav Hapla ierr = ISGetLocalSize(p, &n);CHKERRQ(ierr); 1630d4636a37SVaclav Hapla ierr = ISGetIndices(p, &arr);CHKERRQ(ierr); 1631d4636a37SVaclav Hapla zero = 0; 1632d4636a37SVaclav Hapla /* first figure out the total number of returned points */ 1633d4636a37SVaclav Hapla cn = n; 1634d4636a37SVaclav Hapla ierr = DMPlexGetConeRecursive_Private(dm, &cn, arr, &zero, NULL);CHKERRQ(ierr); 1635d4636a37SVaclav Hapla ierr = PetscMalloc1(cn, &cpoints);CHKERRQ(ierr); 1636d4636a37SVaclav Hapla /* now get recursive cones themselves */ 1637d4636a37SVaclav Hapla ierr = DMPlexGetConeRecursive_Private(dm, &n, arr, &zero, cpoints);CHKERRQ(ierr); 1638d4636a37SVaclav Hapla ierr = ISCreateGeneral(PetscObjectComm((PetscObject)p), n, cpoints, PETSC_OWN_POINTER, pCones);CHKERRQ(ierr); 1639d4636a37SVaclav Hapla ierr = ISRestoreIndices(p, &arr);CHKERRQ(ierr); 1640d4636a37SVaclav Hapla PetscFunctionReturn(0); 1641d4636a37SVaclav Hapla } 1642d4636a37SVaclav Hapla 1643552f7358SJed Brown /*@ 164492371b87SBarry Smith DMPlexSetCone - Set the points on the in-edges for this point in the DAG; that is these are the points that cover the specific point 1645552f7358SJed Brown 1646552f7358SJed Brown Not collective 1647552f7358SJed Brown 1648552f7358SJed Brown Input Parameters: 1649552f7358SJed Brown + mesh - The DMPlex 1650eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 1651552f7358SJed Brown - cone - An array of points which are on the in-edges for point p 1652552f7358SJed Brown 1653552f7358SJed Brown Output Parameter: 1654552f7358SJed Brown 1655552f7358SJed Brown Note: 1656552f7358SJed Brown This should be called after all calls to DMPlexSetConeSize() and DMSetUp(). 1657552f7358SJed Brown 165892371b87SBarry Smith Developer Note: Why not call this DMPlexSetCover() 165992371b87SBarry Smith 1660552f7358SJed Brown Level: beginner 1661552f7358SJed Brown 166292371b87SBarry Smith .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexSetChart(), DMPlexSetConeSize(), DMSetUp(), DMPlexSetSupport(), DMPlexSetSupportSize() 1663552f7358SJed Brown @*/ 1664552f7358SJed Brown PetscErrorCode DMPlexSetCone(DM dm, PetscInt p, const PetscInt cone[]) 1665552f7358SJed Brown { 1666552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1667552f7358SJed Brown PetscInt pStart, pEnd; 1668552f7358SJed Brown PetscInt dof, off, c; 1669552f7358SJed Brown PetscErrorCode ierr; 1670552f7358SJed Brown 1671552f7358SJed Brown PetscFunctionBegin; 1672552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1673552f7358SJed Brown ierr = PetscSectionGetChart(mesh->coneSection, &pStart, &pEnd);CHKERRQ(ierr); 1674552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 1675552f7358SJed Brown if (dof) PetscValidPointer(cone, 3); 1676552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 167782f516ccSBarry Smith if ((p < pStart) || (p >= pEnd)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Mesh point %D is not in the valid range [%D, %D)", p, pStart, pEnd); 1678552f7358SJed Brown for (c = 0; c < dof; ++c) { 167982f516ccSBarry Smith if ((cone[c] < pStart) || (cone[c] >= pEnd)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cone point %D is not in the valid range [%D, %D)", cone[c], pStart, pEnd); 1680552f7358SJed Brown mesh->cones[off+c] = cone[c]; 1681552f7358SJed Brown } 1682552f7358SJed Brown PetscFunctionReturn(0); 1683552f7358SJed Brown } 1684552f7358SJed Brown 1685552f7358SJed Brown /*@C 1686eaf898f9SPatrick Sanan DMPlexGetConeOrientation - Return the orientations on the in-edges for this point in the DAG 1687552f7358SJed Brown 1688552f7358SJed Brown Not collective 1689552f7358SJed Brown 1690552f7358SJed Brown Input Parameters: 1691552f7358SJed Brown + mesh - The DMPlex 1692eaf898f9SPatrick Sanan - p - The point, which must lie in the chart set with DMPlexSetChart() 1693552f7358SJed Brown 1694552f7358SJed Brown Output Parameter: 1695552f7358SJed Brown . coneOrientation - An array of orientations which are on the in-edges for point p. An orientation is an 1696552f7358SJed Brown integer giving the prescription for cone traversal. If it is negative, the cone is 1697552f7358SJed Brown traversed in the opposite direction. Its value 'o', or if negative '-(o+1)', gives 1698552f7358SJed Brown the index of the cone point on which to start. 1699552f7358SJed Brown 1700552f7358SJed Brown Level: beginner 1701552f7358SJed Brown 17023813dfbdSMatthew G Knepley Fortran Notes: 17033813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 17043813dfbdSMatthew G Knepley include petsc.h90 in your code. 17053813dfbdSMatthew G Knepley 17063813dfbdSMatthew G Knepley You must also call DMPlexRestoreConeOrientation() after you finish using the returned array. 1707552f7358SJed Brown 1708552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexSetCone(), DMPlexSetChart() 1709552f7358SJed Brown @*/ 1710552f7358SJed Brown PetscErrorCode DMPlexGetConeOrientation(DM dm, PetscInt p, const PetscInt *coneOrientation[]) 1711552f7358SJed Brown { 1712552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1713552f7358SJed Brown PetscInt off; 1714552f7358SJed Brown PetscErrorCode ierr; 1715552f7358SJed Brown 1716552f7358SJed Brown PetscFunctionBegin; 1717552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1718552f7358SJed Brown #if defined(PETSC_USE_DEBUG) 1719552f7358SJed Brown { 1720552f7358SJed Brown PetscInt dof; 1721552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 1722552f7358SJed Brown if (dof) PetscValidPointer(coneOrientation, 3); 1723552f7358SJed Brown } 1724552f7358SJed Brown #endif 1725552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 17260d644c17SKarl Rupp 1727552f7358SJed Brown *coneOrientation = &mesh->coneOrientations[off]; 1728552f7358SJed Brown PetscFunctionReturn(0); 1729552f7358SJed Brown } 1730552f7358SJed Brown 1731552f7358SJed Brown /*@ 1732eaf898f9SPatrick Sanan DMPlexSetConeOrientation - Set the orientations on the in-edges for this point in the DAG 1733552f7358SJed Brown 1734552f7358SJed Brown Not collective 1735552f7358SJed Brown 1736552f7358SJed Brown Input Parameters: 1737552f7358SJed Brown + mesh - The DMPlex 1738eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 1739552f7358SJed Brown - coneOrientation - An array of orientations which are on the in-edges for point p. An orientation is an 1740552f7358SJed Brown integer giving the prescription for cone traversal. If it is negative, the cone is 1741552f7358SJed Brown traversed in the opposite direction. Its value 'o', or if negative '-(o+1)', gives 1742552f7358SJed Brown the index of the cone point on which to start. 1743552f7358SJed Brown 1744552f7358SJed Brown Output Parameter: 1745552f7358SJed Brown 1746552f7358SJed Brown Note: 1747552f7358SJed Brown This should be called after all calls to DMPlexSetConeSize() and DMSetUp(). 1748552f7358SJed Brown 1749552f7358SJed Brown Level: beginner 1750552f7358SJed Brown 1751552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetConeOrientation(), DMPlexSetCone(), DMPlexSetChart(), DMPlexSetConeSize(), DMSetUp() 1752552f7358SJed Brown @*/ 1753552f7358SJed Brown PetscErrorCode DMPlexSetConeOrientation(DM dm, PetscInt p, const PetscInt coneOrientation[]) 1754552f7358SJed Brown { 1755552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1756552f7358SJed Brown PetscInt pStart, pEnd; 1757552f7358SJed Brown PetscInt dof, off, c; 1758552f7358SJed Brown PetscErrorCode ierr; 1759552f7358SJed Brown 1760552f7358SJed Brown PetscFunctionBegin; 1761552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1762552f7358SJed Brown ierr = PetscSectionGetChart(mesh->coneSection, &pStart, &pEnd);CHKERRQ(ierr); 1763552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 1764552f7358SJed Brown if (dof) PetscValidPointer(coneOrientation, 3); 1765552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 176682f516ccSBarry Smith if ((p < pStart) || (p >= pEnd)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Mesh point %D is not in the valid range [%D, %D)", p, pStart, pEnd); 1767552f7358SJed Brown for (c = 0; c < dof; ++c) { 1768552f7358SJed Brown PetscInt cdof, o = coneOrientation[c]; 1769552f7358SJed Brown 1770552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, mesh->cones[off+c], &cdof);CHKERRQ(ierr); 177182f516ccSBarry Smith if (o && ((o < -(cdof+1)) || (o >= cdof))) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cone orientation %D is not in the valid range [%D. %D)", o, -(cdof+1), cdof); 1772552f7358SJed Brown mesh->coneOrientations[off+c] = o; 1773552f7358SJed Brown } 1774552f7358SJed Brown PetscFunctionReturn(0); 1775552f7358SJed Brown } 1776552f7358SJed Brown 17777cd05799SMatthew G. Knepley /*@ 1778eaf898f9SPatrick Sanan DMPlexInsertCone - Insert a point into the in-edges for the point p in the DAG 17797cd05799SMatthew G. Knepley 17807cd05799SMatthew G. Knepley Not collective 17817cd05799SMatthew G. Knepley 17827cd05799SMatthew G. Knepley Input Parameters: 17837cd05799SMatthew G. Knepley + mesh - The DMPlex 1784eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 17857cd05799SMatthew G. Knepley . conePos - The local index in the cone where the point should be put 17867cd05799SMatthew G. Knepley - conePoint - The mesh point to insert 17877cd05799SMatthew G. Knepley 17887cd05799SMatthew G. Knepley Level: beginner 17897cd05799SMatthew G. Knepley 17907cd05799SMatthew G. Knepley .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexSetChart(), DMPlexSetConeSize(), DMSetUp() 17917cd05799SMatthew G. Knepley @*/ 1792552f7358SJed Brown PetscErrorCode DMPlexInsertCone(DM dm, PetscInt p, PetscInt conePos, PetscInt conePoint) 1793552f7358SJed Brown { 1794552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1795552f7358SJed Brown PetscInt pStart, pEnd; 1796552f7358SJed Brown PetscInt dof, off; 1797552f7358SJed Brown PetscErrorCode ierr; 1798552f7358SJed Brown 1799552f7358SJed Brown PetscFunctionBegin; 1800552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1801552f7358SJed Brown ierr = PetscSectionGetChart(mesh->coneSection, &pStart, &pEnd);CHKERRQ(ierr); 180282f516ccSBarry Smith if ((p < pStart) || (p >= pEnd)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Mesh point %D is not in the valid range [%D, %D)", p, pStart, pEnd); 180382f516ccSBarry Smith if ((conePoint < pStart) || (conePoint >= pEnd)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cone point %D is not in the valid range [%D, %D)", conePoint, pStart, pEnd); 180477c88f5bSMatthew G Knepley ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 180577c88f5bSMatthew G Knepley ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 180677c88f5bSMatthew G Knepley if ((conePos < 0) || (conePos >= dof)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cone position %D of point %D is not in the valid range [0, %D)", conePos, p, dof); 1807552f7358SJed Brown mesh->cones[off+conePos] = conePoint; 1808552f7358SJed Brown PetscFunctionReturn(0); 1809552f7358SJed Brown } 1810552f7358SJed Brown 18117cd05799SMatthew G. Knepley /*@ 1812eaf898f9SPatrick Sanan DMPlexInsertConeOrientation - Insert a point orientation for the in-edge for the point p in the DAG 18137cd05799SMatthew G. Knepley 18147cd05799SMatthew G. Knepley Not collective 18157cd05799SMatthew G. Knepley 18167cd05799SMatthew G. Knepley Input Parameters: 18177cd05799SMatthew G. Knepley + mesh - The DMPlex 1818eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 18197cd05799SMatthew G. Knepley . conePos - The local index in the cone where the point should be put 18207cd05799SMatthew G. Knepley - coneOrientation - The point orientation to insert 18217cd05799SMatthew G. Knepley 18227cd05799SMatthew G. Knepley Level: beginner 18237cd05799SMatthew G. Knepley 18247cd05799SMatthew G. Knepley .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexSetChart(), DMPlexSetConeSize(), DMSetUp() 18257cd05799SMatthew G. Knepley @*/ 182677c88f5bSMatthew G Knepley PetscErrorCode DMPlexInsertConeOrientation(DM dm, PetscInt p, PetscInt conePos, PetscInt coneOrientation) 182777c88f5bSMatthew G Knepley { 182877c88f5bSMatthew G Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 182977c88f5bSMatthew G Knepley PetscInt pStart, pEnd; 183077c88f5bSMatthew G Knepley PetscInt dof, off; 183177c88f5bSMatthew G Knepley PetscErrorCode ierr; 183277c88f5bSMatthew G Knepley 183377c88f5bSMatthew G Knepley PetscFunctionBegin; 183477c88f5bSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 183577c88f5bSMatthew G Knepley ierr = PetscSectionGetChart(mesh->coneSection, &pStart, &pEnd);CHKERRQ(ierr); 183677c88f5bSMatthew G Knepley if ((p < pStart) || (p >= pEnd)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Mesh point %D is not in the valid range [%D, %D)", p, pStart, pEnd); 183777c88f5bSMatthew G Knepley ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 183877c88f5bSMatthew G Knepley ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 183977c88f5bSMatthew G Knepley if ((conePos < 0) || (conePos >= dof)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cone position %D of point %D is not in the valid range [0, %D)", conePos, p, dof); 184077c88f5bSMatthew G Knepley mesh->coneOrientations[off+conePos] = coneOrientation; 184177c88f5bSMatthew G Knepley PetscFunctionReturn(0); 184277c88f5bSMatthew G Knepley } 184377c88f5bSMatthew G Knepley 1844552f7358SJed Brown /*@ 1845eaf898f9SPatrick Sanan DMPlexGetSupportSize - Return the number of out-edges for this point in the DAG 1846552f7358SJed Brown 1847552f7358SJed Brown Not collective 1848552f7358SJed Brown 1849552f7358SJed Brown Input Parameters: 1850552f7358SJed Brown + mesh - The DMPlex 1851eaf898f9SPatrick Sanan - p - The point, which must lie in the chart set with DMPlexSetChart() 1852552f7358SJed Brown 1853552f7358SJed Brown Output Parameter: 1854552f7358SJed Brown . size - The support size for point p 1855552f7358SJed Brown 1856552f7358SJed Brown Level: beginner 1857552f7358SJed Brown 1858552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetConeSize(), DMPlexSetChart(), DMPlexGetConeSize() 1859552f7358SJed Brown @*/ 1860552f7358SJed Brown PetscErrorCode DMPlexGetSupportSize(DM dm, PetscInt p, PetscInt *size) 1861552f7358SJed Brown { 1862552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1863552f7358SJed Brown PetscErrorCode ierr; 1864552f7358SJed Brown 1865552f7358SJed Brown PetscFunctionBegin; 1866552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1867552f7358SJed Brown PetscValidPointer(size, 3); 1868552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, size);CHKERRQ(ierr); 1869552f7358SJed Brown PetscFunctionReturn(0); 1870552f7358SJed Brown } 1871552f7358SJed Brown 1872552f7358SJed Brown /*@ 1873eaf898f9SPatrick Sanan DMPlexSetSupportSize - Set the number of out-edges for this point in the DAG 1874552f7358SJed Brown 1875552f7358SJed Brown Not collective 1876552f7358SJed Brown 1877552f7358SJed Brown Input Parameters: 1878552f7358SJed Brown + mesh - The DMPlex 1879eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 1880552f7358SJed Brown - size - The support size for point p 1881552f7358SJed Brown 1882552f7358SJed Brown Output Parameter: 1883552f7358SJed Brown 1884552f7358SJed Brown Note: 1885552f7358SJed Brown This should be called after DMPlexSetChart(). 1886552f7358SJed Brown 1887552f7358SJed Brown Level: beginner 1888552f7358SJed Brown 1889552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetSupportSize(), DMPlexSetChart() 1890552f7358SJed Brown @*/ 1891552f7358SJed Brown PetscErrorCode DMPlexSetSupportSize(DM dm, PetscInt p, PetscInt size) 1892552f7358SJed Brown { 1893552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1894552f7358SJed Brown PetscErrorCode ierr; 1895552f7358SJed Brown 1896552f7358SJed Brown PetscFunctionBegin; 1897552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1898552f7358SJed Brown ierr = PetscSectionSetDof(mesh->supportSection, p, size);CHKERRQ(ierr); 18990d644c17SKarl Rupp 1900552f7358SJed Brown mesh->maxSupportSize = PetscMax(mesh->maxSupportSize, size); 1901552f7358SJed Brown PetscFunctionReturn(0); 1902552f7358SJed Brown } 1903552f7358SJed Brown 1904552f7358SJed Brown /*@C 1905eaf898f9SPatrick Sanan DMPlexGetSupport - Return the points on the out-edges for this point in the DAG 1906552f7358SJed Brown 1907552f7358SJed Brown Not collective 1908552f7358SJed Brown 1909552f7358SJed Brown Input Parameters: 1910552f7358SJed Brown + mesh - The DMPlex 1911eaf898f9SPatrick Sanan - p - The point, which must lie in the chart set with DMPlexSetChart() 1912552f7358SJed Brown 1913552f7358SJed Brown Output Parameter: 1914552f7358SJed Brown . support - An array of points which are on the out-edges for point p 1915552f7358SJed Brown 1916552f7358SJed Brown Level: beginner 1917552f7358SJed Brown 19183813dfbdSMatthew G Knepley Fortran Notes: 19193813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 19203813dfbdSMatthew G Knepley include petsc.h90 in your code. 19213813dfbdSMatthew G Knepley 19223813dfbdSMatthew G Knepley You must also call DMPlexRestoreSupport() after you finish using the returned array. 19233813dfbdSMatthew G Knepley 1924552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetCone(), DMPlexSetChart(), DMPlexGetCone() 1925552f7358SJed Brown @*/ 1926552f7358SJed Brown PetscErrorCode DMPlexGetSupport(DM dm, PetscInt p, const PetscInt *support[]) 1927552f7358SJed Brown { 1928552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1929552f7358SJed Brown PetscInt off; 1930552f7358SJed Brown PetscErrorCode ierr; 1931552f7358SJed Brown 1932552f7358SJed Brown PetscFunctionBegin; 1933552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1934552f7358SJed Brown PetscValidPointer(support, 3); 1935552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, p, &off);CHKERRQ(ierr); 1936552f7358SJed Brown *support = &mesh->supports[off]; 1937552f7358SJed Brown PetscFunctionReturn(0); 1938552f7358SJed Brown } 1939552f7358SJed Brown 1940552f7358SJed Brown /*@ 194192371b87SBarry Smith DMPlexSetSupport - Set the points on the out-edges for this point in the DAG, that is the list of points that this point covers 1942552f7358SJed Brown 1943552f7358SJed Brown Not collective 1944552f7358SJed Brown 1945552f7358SJed Brown Input Parameters: 1946552f7358SJed Brown + mesh - The DMPlex 1947eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 194892371b87SBarry Smith - support - An array of points which are on the out-edges for point p 1949552f7358SJed Brown 1950552f7358SJed Brown Output Parameter: 1951552f7358SJed Brown 1952552f7358SJed Brown Note: 1953552f7358SJed Brown This should be called after all calls to DMPlexSetSupportSize() and DMSetUp(). 1954552f7358SJed Brown 1955552f7358SJed Brown Level: beginner 1956552f7358SJed Brown 195792371b87SBarry Smith .seealso: DMPlexSetCone(), DMPlexSetConeSize(), DMPlexCreate(), DMPlexGetSupport(), DMPlexSetChart(), DMPlexSetSupportSize(), DMSetUp() 1958552f7358SJed Brown @*/ 1959552f7358SJed Brown PetscErrorCode DMPlexSetSupport(DM dm, PetscInt p, const PetscInt support[]) 1960552f7358SJed Brown { 1961552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1962552f7358SJed Brown PetscInt pStart, pEnd; 1963552f7358SJed Brown PetscInt dof, off, c; 1964552f7358SJed Brown PetscErrorCode ierr; 1965552f7358SJed Brown 1966552f7358SJed Brown PetscFunctionBegin; 1967552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1968552f7358SJed Brown ierr = PetscSectionGetChart(mesh->supportSection, &pStart, &pEnd);CHKERRQ(ierr); 1969552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, &dof);CHKERRQ(ierr); 1970552f7358SJed Brown if (dof) PetscValidPointer(support, 3); 1971552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, p, &off);CHKERRQ(ierr); 197282f516ccSBarry Smith if ((p < pStart) || (p >= pEnd)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Mesh point %D is not in the valid range [%D, %D)", p, pStart, pEnd); 1973552f7358SJed Brown for (c = 0; c < dof; ++c) { 197482f516ccSBarry Smith if ((support[c] < pStart) || (support[c] >= pEnd)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Support point %D is not in the valid range [%D, %D)", support[c], pStart, pEnd); 1975552f7358SJed Brown mesh->supports[off+c] = support[c]; 1976552f7358SJed Brown } 1977552f7358SJed Brown PetscFunctionReturn(0); 1978552f7358SJed Brown } 1979552f7358SJed Brown 19807cd05799SMatthew G. Knepley /*@ 1981eaf898f9SPatrick Sanan DMPlexInsertSupport - Insert a point into the out-edges for the point p in the DAG 19827cd05799SMatthew G. Knepley 19837cd05799SMatthew G. Knepley Not collective 19847cd05799SMatthew G. Knepley 19857cd05799SMatthew G. Knepley Input Parameters: 19867cd05799SMatthew G. Knepley + mesh - The DMPlex 1987eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 19887cd05799SMatthew G. Knepley . supportPos - The local index in the cone where the point should be put 19897cd05799SMatthew G. Knepley - supportPoint - The mesh point to insert 19907cd05799SMatthew G. Knepley 19917cd05799SMatthew G. Knepley Level: beginner 19927cd05799SMatthew G. Knepley 19937cd05799SMatthew G. Knepley .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexSetChart(), DMPlexSetConeSize(), DMSetUp() 19947cd05799SMatthew G. Knepley @*/ 1995552f7358SJed Brown PetscErrorCode DMPlexInsertSupport(DM dm, PetscInt p, PetscInt supportPos, PetscInt supportPoint) 1996552f7358SJed Brown { 1997552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1998552f7358SJed Brown PetscInt pStart, pEnd; 1999552f7358SJed Brown PetscInt dof, off; 2000552f7358SJed Brown PetscErrorCode ierr; 2001552f7358SJed Brown 2002552f7358SJed Brown PetscFunctionBegin; 2003552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2004552f7358SJed Brown ierr = PetscSectionGetChart(mesh->supportSection, &pStart, &pEnd);CHKERRQ(ierr); 2005552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, &dof);CHKERRQ(ierr); 2006552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, p, &off);CHKERRQ(ierr); 200782f516ccSBarry Smith if ((p < pStart) || (p >= pEnd)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Mesh point %D is not in the valid range [%D, %D)", p, pStart, pEnd); 200882f516ccSBarry Smith if ((supportPoint < pStart) || (supportPoint >= pEnd)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Support point %D is not in the valid range [%D, %D)", supportPoint, pStart, pEnd); 200982f516ccSBarry Smith if (supportPos >= dof) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Support position %D of point %D is not in the valid range [0, %D)", supportPos, p, dof); 2010552f7358SJed Brown mesh->supports[off+supportPos] = supportPoint; 2011552f7358SJed Brown PetscFunctionReturn(0); 2012552f7358SJed Brown } 2013552f7358SJed Brown 2014552f7358SJed Brown /*@C 2015eaf898f9SPatrick Sanan DMPlexGetTransitiveClosure - Return the points on the transitive closure of the in-edges or out-edges for this point in the DAG 2016552f7358SJed Brown 2017552f7358SJed Brown Not collective 2018552f7358SJed Brown 2019552f7358SJed Brown Input Parameters: 2020552f7358SJed Brown + mesh - The DMPlex 2021eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 2022552f7358SJed Brown . useCone - PETSC_TRUE for in-edges, otherwise use out-edges 20230298fd71SBarry Smith - points - If points is NULL on input, internal storage will be returned, otherwise the provided array is used 2024552f7358SJed Brown 2025552f7358SJed Brown Output Parameters: 2026552f7358SJed Brown + numPoints - The number of points in the closure, so points[] is of size 2*numPoints 2027552f7358SJed Brown - points - The points and point orientations, interleaved as pairs [p0, o0, p1, o1, ...] 2028552f7358SJed Brown 2029552f7358SJed Brown Note: 20300298fd71SBarry Smith If using internal storage (points is NULL on input), each call overwrites the last output. 2031552f7358SJed Brown 20323813dfbdSMatthew G Knepley Fortran Notes: 20333813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 20343813dfbdSMatthew G Knepley include petsc.h90 in your code. 20353813dfbdSMatthew G Knepley 20363813dfbdSMatthew G Knepley The numPoints argument is not present in the Fortran 90 binding since it is internal to the array. 20373813dfbdSMatthew G Knepley 2038552f7358SJed Brown Level: beginner 2039552f7358SJed Brown 2040552f7358SJed Brown .seealso: DMPlexRestoreTransitiveClosure(), DMPlexCreate(), DMPlexSetCone(), DMPlexSetChart(), DMPlexGetCone() 2041552f7358SJed Brown @*/ 2042552f7358SJed Brown PetscErrorCode DMPlexGetTransitiveClosure(DM dm, PetscInt p, PetscBool useCone, PetscInt *numPoints, PetscInt *points[]) 2043552f7358SJed Brown { 2044552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2045552f7358SJed Brown PetscInt *closure, *fifo; 20460298fd71SBarry Smith const PetscInt *tmp = NULL, *tmpO = NULL; 2047552f7358SJed Brown PetscInt tmpSize, t; 2048552f7358SJed Brown PetscInt depth = 0, maxSize; 2049552f7358SJed Brown PetscInt closureSize = 2, fifoSize = 0, fifoStart = 0; 2050552f7358SJed Brown PetscErrorCode ierr; 2051552f7358SJed Brown 2052552f7358SJed Brown PetscFunctionBegin; 2053552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2054552f7358SJed Brown ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 2055552f7358SJed Brown /* This is only 1-level */ 2056552f7358SJed Brown if (useCone) { 2057552f7358SJed Brown ierr = DMPlexGetConeSize(dm, p, &tmpSize);CHKERRQ(ierr); 2058552f7358SJed Brown ierr = DMPlexGetCone(dm, p, &tmp);CHKERRQ(ierr); 2059552f7358SJed Brown ierr = DMPlexGetConeOrientation(dm, p, &tmpO);CHKERRQ(ierr); 2060552f7358SJed Brown } else { 2061552f7358SJed Brown ierr = DMPlexGetSupportSize(dm, p, &tmpSize);CHKERRQ(ierr); 2062552f7358SJed Brown ierr = DMPlexGetSupport(dm, p, &tmp);CHKERRQ(ierr); 2063552f7358SJed Brown } 2064bfbcdd7aSMatthew G. Knepley if (depth == 1) { 2065bfbcdd7aSMatthew G. Knepley if (*points) { 2066bfbcdd7aSMatthew G. Knepley closure = *points; 2067bfbcdd7aSMatthew G. Knepley } else { 2068bfbcdd7aSMatthew G. Knepley maxSize = 2*(PetscMax(mesh->maxConeSize, mesh->maxSupportSize)+1); 206969291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &closure);CHKERRQ(ierr); 2070bfbcdd7aSMatthew G. Knepley } 2071bfbcdd7aSMatthew G. Knepley closure[0] = p; closure[1] = 0; 2072bfbcdd7aSMatthew G. Knepley for (t = 0; t < tmpSize; ++t, closureSize += 2) { 2073bfbcdd7aSMatthew G. Knepley closure[closureSize] = tmp[t]; 2074bfbcdd7aSMatthew G. Knepley closure[closureSize+1] = tmpO ? tmpO[t] : 0; 2075bfbcdd7aSMatthew G. Knepley } 2076bfbcdd7aSMatthew G. Knepley if (numPoints) *numPoints = closureSize/2; 2077bfbcdd7aSMatthew G. Knepley if (points) *points = closure; 2078bfbcdd7aSMatthew G. Knepley PetscFunctionReturn(0); 2079bfbcdd7aSMatthew G. Knepley } 208024c766afSToby Isaac { 208124c766afSToby Isaac PetscInt c, coneSeries, s,supportSeries; 208224c766afSToby Isaac 208324c766afSToby Isaac c = mesh->maxConeSize; 208424c766afSToby Isaac coneSeries = (c > 1) ? ((PetscPowInt(c,depth+1)-1)/(c-1)) : depth+1; 208524c766afSToby Isaac s = mesh->maxSupportSize; 208624c766afSToby Isaac supportSeries = (s > 1) ? ((PetscPowInt(s,depth+1)-1)/(s-1)) : depth+1; 208724c766afSToby Isaac maxSize = 2*PetscMax(coneSeries,supportSeries); 208824c766afSToby Isaac } 208969291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &fifo);CHKERRQ(ierr); 2090bfbcdd7aSMatthew G. Knepley if (*points) { 2091bfbcdd7aSMatthew G. Knepley closure = *points; 2092bfbcdd7aSMatthew G. Knepley } else { 209369291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &closure);CHKERRQ(ierr); 2094bfbcdd7aSMatthew G. Knepley } 2095bfbcdd7aSMatthew G. Knepley closure[0] = p; closure[1] = 0; 2096552f7358SJed Brown for (t = 0; t < tmpSize; ++t, closureSize += 2, fifoSize += 2) { 2097552f7358SJed Brown const PetscInt cp = tmp[t]; 2098552f7358SJed Brown const PetscInt co = tmpO ? tmpO[t] : 0; 2099552f7358SJed Brown 2100552f7358SJed Brown closure[closureSize] = cp; 2101552f7358SJed Brown closure[closureSize+1] = co; 2102552f7358SJed Brown fifo[fifoSize] = cp; 2103552f7358SJed Brown fifo[fifoSize+1] = co; 2104552f7358SJed Brown } 2105bfbcdd7aSMatthew G. Knepley /* Should kick out early when depth is reached, rather than checking all vertices for empty cones */ 2106552f7358SJed Brown while (fifoSize - fifoStart) { 2107552f7358SJed Brown const PetscInt q = fifo[fifoStart]; 2108552f7358SJed Brown const PetscInt o = fifo[fifoStart+1]; 2109552f7358SJed Brown const PetscInt rev = o >= 0 ? 0 : 1; 2110552f7358SJed Brown const PetscInt off = rev ? -(o+1) : o; 2111552f7358SJed Brown 2112552f7358SJed Brown if (useCone) { 2113552f7358SJed Brown ierr = DMPlexGetConeSize(dm, q, &tmpSize);CHKERRQ(ierr); 2114552f7358SJed Brown ierr = DMPlexGetCone(dm, q, &tmp);CHKERRQ(ierr); 2115552f7358SJed Brown ierr = DMPlexGetConeOrientation(dm, q, &tmpO);CHKERRQ(ierr); 2116552f7358SJed Brown } else { 2117552f7358SJed Brown ierr = DMPlexGetSupportSize(dm, q, &tmpSize);CHKERRQ(ierr); 2118552f7358SJed Brown ierr = DMPlexGetSupport(dm, q, &tmp);CHKERRQ(ierr); 21190298fd71SBarry Smith tmpO = NULL; 2120552f7358SJed Brown } 2121552f7358SJed Brown for (t = 0; t < tmpSize; ++t) { 2122552f7358SJed Brown const PetscInt i = ((rev ? tmpSize-t : t) + off)%tmpSize; 2123552f7358SJed Brown const PetscInt cp = tmp[i]; 21242e1b13c2SMatthew G. Knepley /* Must propogate orientation: When we reverse orientation, we both reverse the direction of iteration and start at the other end of the chain. */ 21252e1b13c2SMatthew G. Knepley /* HACK: It is worse to get the size here, than to change the interpretation of -(*+1) 21262e1b13c2SMatthew G. Knepley const PetscInt co = tmpO ? (rev ? -(tmpO[i]+1) : tmpO[i]) : 0; */ 21272e1b13c2SMatthew G. Knepley PetscInt co = tmpO ? tmpO[i] : 0; 2128552f7358SJed Brown PetscInt c; 2129552f7358SJed Brown 21302e1b13c2SMatthew G. Knepley if (rev) { 21312e1b13c2SMatthew G. Knepley PetscInt childSize, coff; 21322e1b13c2SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, cp, &childSize);CHKERRQ(ierr); 21332e1b13c2SMatthew G. Knepley coff = tmpO[i] < 0 ? -(tmpO[i]+1) : tmpO[i]; 21342e1b13c2SMatthew G. Knepley co = childSize ? -(((coff+childSize-1)%childSize)+1) : 0; 21352e1b13c2SMatthew G. Knepley } 2136552f7358SJed Brown /* Check for duplicate */ 2137552f7358SJed Brown for (c = 0; c < closureSize; c += 2) { 2138552f7358SJed Brown if (closure[c] == cp) break; 2139552f7358SJed Brown } 2140552f7358SJed Brown if (c == closureSize) { 2141552f7358SJed Brown closure[closureSize] = cp; 2142552f7358SJed Brown closure[closureSize+1] = co; 2143552f7358SJed Brown fifo[fifoSize] = cp; 2144552f7358SJed Brown fifo[fifoSize+1] = co; 2145552f7358SJed Brown closureSize += 2; 2146552f7358SJed Brown fifoSize += 2; 2147552f7358SJed Brown } 2148552f7358SJed Brown } 2149552f7358SJed Brown fifoStart += 2; 2150552f7358SJed Brown } 2151552f7358SJed Brown if (numPoints) *numPoints = closureSize/2; 2152552f7358SJed Brown if (points) *points = closure; 215369291d52SBarry Smith ierr = DMRestoreWorkArray(dm, maxSize, MPIU_INT, &fifo);CHKERRQ(ierr); 2154552f7358SJed Brown PetscFunctionReturn(0); 2155552f7358SJed Brown } 2156552f7358SJed Brown 21579bf0dad6SMatthew G. Knepley /*@C 2158eaf898f9SPatrick Sanan DMPlexGetTransitiveClosure_Internal - Return the points on the transitive closure of the in-edges or out-edges for this point in the DAG with a specified initial orientation 21599bf0dad6SMatthew G. Knepley 21609bf0dad6SMatthew G. Knepley Not collective 21619bf0dad6SMatthew G. Knepley 21629bf0dad6SMatthew G. Knepley Input Parameters: 21639bf0dad6SMatthew G. Knepley + mesh - The DMPlex 2164eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 21659bf0dad6SMatthew G. Knepley . orientation - The orientation of the point 21669bf0dad6SMatthew G. Knepley . useCone - PETSC_TRUE for in-edges, otherwise use out-edges 21679bf0dad6SMatthew G. Knepley - points - If points is NULL on input, internal storage will be returned, otherwise the provided array is used 21689bf0dad6SMatthew G. Knepley 21699bf0dad6SMatthew G. Knepley Output Parameters: 21709bf0dad6SMatthew G. Knepley + numPoints - The number of points in the closure, so points[] is of size 2*numPoints 21719bf0dad6SMatthew G. Knepley - points - The points and point orientations, interleaved as pairs [p0, o0, p1, o1, ...] 21729bf0dad6SMatthew G. Knepley 21739bf0dad6SMatthew G. Knepley Note: 21749bf0dad6SMatthew G. Knepley If using internal storage (points is NULL on input), each call overwrites the last output. 21759bf0dad6SMatthew G. Knepley 21769bf0dad6SMatthew G. Knepley Fortran Notes: 21779bf0dad6SMatthew G. Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 21789bf0dad6SMatthew G. Knepley include petsc.h90 in your code. 21799bf0dad6SMatthew G. Knepley 21809bf0dad6SMatthew G. Knepley The numPoints argument is not present in the Fortran 90 binding since it is internal to the array. 21819bf0dad6SMatthew G. Knepley 21829bf0dad6SMatthew G. Knepley Level: beginner 21839bf0dad6SMatthew G. Knepley 21849bf0dad6SMatthew G. Knepley .seealso: DMPlexRestoreTransitiveClosure(), DMPlexCreate(), DMPlexSetCone(), DMPlexSetChart(), DMPlexGetCone() 21859bf0dad6SMatthew G. Knepley @*/ 21869bf0dad6SMatthew G. Knepley PetscErrorCode DMPlexGetTransitiveClosure_Internal(DM dm, PetscInt p, PetscInt ornt, PetscBool useCone, PetscInt *numPoints, PetscInt *points[]) 21879bf0dad6SMatthew G. Knepley { 21889bf0dad6SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 21899bf0dad6SMatthew G. Knepley PetscInt *closure, *fifo; 21909bf0dad6SMatthew G. Knepley const PetscInt *tmp = NULL, *tmpO = NULL; 21919bf0dad6SMatthew G. Knepley PetscInt tmpSize, t; 21929bf0dad6SMatthew G. Knepley PetscInt depth = 0, maxSize; 21939bf0dad6SMatthew G. Knepley PetscInt closureSize = 2, fifoSize = 0, fifoStart = 0; 21949bf0dad6SMatthew G. Knepley PetscErrorCode ierr; 21959bf0dad6SMatthew G. Knepley 21969bf0dad6SMatthew G. Knepley PetscFunctionBegin; 21979bf0dad6SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 21989bf0dad6SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 21999bf0dad6SMatthew G. Knepley /* This is only 1-level */ 22009bf0dad6SMatthew G. Knepley if (useCone) { 22019bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, p, &tmpSize);CHKERRQ(ierr); 22029bf0dad6SMatthew G. Knepley ierr = DMPlexGetCone(dm, p, &tmp);CHKERRQ(ierr); 22039bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, p, &tmpO);CHKERRQ(ierr); 22049bf0dad6SMatthew G. Knepley } else { 22059bf0dad6SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, p, &tmpSize);CHKERRQ(ierr); 22069bf0dad6SMatthew G. Knepley ierr = DMPlexGetSupport(dm, p, &tmp);CHKERRQ(ierr); 22079bf0dad6SMatthew G. Knepley } 22089bf0dad6SMatthew G. Knepley if (depth == 1) { 22099bf0dad6SMatthew G. Knepley if (*points) { 22109bf0dad6SMatthew G. Knepley closure = *points; 22119bf0dad6SMatthew G. Knepley } else { 22129bf0dad6SMatthew G. Knepley maxSize = 2*(PetscMax(mesh->maxConeSize, mesh->maxSupportSize)+1); 221369291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &closure);CHKERRQ(ierr); 22149bf0dad6SMatthew G. Knepley } 22159bf0dad6SMatthew G. Knepley closure[0] = p; closure[1] = ornt; 22169bf0dad6SMatthew G. Knepley for (t = 0; t < tmpSize; ++t, closureSize += 2) { 22179bf0dad6SMatthew G. Knepley const PetscInt i = ornt >= 0 ? (t+ornt)%tmpSize : (-(ornt+1) + tmpSize-t)%tmpSize; 22189bf0dad6SMatthew G. Knepley closure[closureSize] = tmp[i]; 22199bf0dad6SMatthew G. Knepley closure[closureSize+1] = tmpO ? tmpO[i] : 0; 22209bf0dad6SMatthew G. Knepley } 22219bf0dad6SMatthew G. Knepley if (numPoints) *numPoints = closureSize/2; 22229bf0dad6SMatthew G. Knepley if (points) *points = closure; 22239bf0dad6SMatthew G. Knepley PetscFunctionReturn(0); 22249bf0dad6SMatthew G. Knepley } 222524c766afSToby Isaac { 222624c766afSToby Isaac PetscInt c, coneSeries, s,supportSeries; 222724c766afSToby Isaac 222824c766afSToby Isaac c = mesh->maxConeSize; 222924c766afSToby Isaac coneSeries = (c > 1) ? ((PetscPowInt(c,depth+1)-1)/(c-1)) : depth+1; 223024c766afSToby Isaac s = mesh->maxSupportSize; 223124c766afSToby Isaac supportSeries = (s > 1) ? ((PetscPowInt(s,depth+1)-1)/(s-1)) : depth+1; 223224c766afSToby Isaac maxSize = 2*PetscMax(coneSeries,supportSeries); 223324c766afSToby Isaac } 223469291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &fifo);CHKERRQ(ierr); 22359bf0dad6SMatthew G. Knepley if (*points) { 22369bf0dad6SMatthew G. Knepley closure = *points; 22379bf0dad6SMatthew G. Knepley } else { 223869291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &closure);CHKERRQ(ierr); 22399bf0dad6SMatthew G. Knepley } 22409bf0dad6SMatthew G. Knepley closure[0] = p; closure[1] = ornt; 22419bf0dad6SMatthew G. Knepley for (t = 0; t < tmpSize; ++t, closureSize += 2, fifoSize += 2) { 22429bf0dad6SMatthew G. Knepley const PetscInt i = ornt >= 0 ? (t+ornt)%tmpSize : (-(ornt+1) + tmpSize-t)%tmpSize; 22439bf0dad6SMatthew G. Knepley const PetscInt cp = tmp[i]; 22449bf0dad6SMatthew G. Knepley PetscInt co = tmpO ? tmpO[i] : 0; 22459bf0dad6SMatthew G. Knepley 22469bf0dad6SMatthew G. Knepley if (ornt < 0) { 22479bf0dad6SMatthew G. Knepley PetscInt childSize, coff; 22489bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, cp, &childSize);CHKERRQ(ierr); 224986b63641SMatthew G. Knepley coff = co < 0 ? -(tmpO[i]+1) : tmpO[i]; 22509bf0dad6SMatthew G. Knepley co = childSize ? -(((coff+childSize-1)%childSize)+1) : 0; 22519bf0dad6SMatthew G. Knepley } 22529bf0dad6SMatthew G. Knepley closure[closureSize] = cp; 22539bf0dad6SMatthew G. Knepley closure[closureSize+1] = co; 22549bf0dad6SMatthew G. Knepley fifo[fifoSize] = cp; 22559bf0dad6SMatthew G. Knepley fifo[fifoSize+1] = co; 22569bf0dad6SMatthew G. Knepley } 22579bf0dad6SMatthew G. Knepley /* Should kick out early when depth is reached, rather than checking all vertices for empty cones */ 22589bf0dad6SMatthew G. Knepley while (fifoSize - fifoStart) { 22599bf0dad6SMatthew G. Knepley const PetscInt q = fifo[fifoStart]; 22609bf0dad6SMatthew G. Knepley const PetscInt o = fifo[fifoStart+1]; 22619bf0dad6SMatthew G. Knepley const PetscInt rev = o >= 0 ? 0 : 1; 22629bf0dad6SMatthew G. Knepley const PetscInt off = rev ? -(o+1) : o; 22639bf0dad6SMatthew G. Knepley 22649bf0dad6SMatthew G. Knepley if (useCone) { 22659bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, q, &tmpSize);CHKERRQ(ierr); 22669bf0dad6SMatthew G. Knepley ierr = DMPlexGetCone(dm, q, &tmp);CHKERRQ(ierr); 22679bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, q, &tmpO);CHKERRQ(ierr); 22689bf0dad6SMatthew G. Knepley } else { 22699bf0dad6SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, q, &tmpSize);CHKERRQ(ierr); 22709bf0dad6SMatthew G. Knepley ierr = DMPlexGetSupport(dm, q, &tmp);CHKERRQ(ierr); 22719bf0dad6SMatthew G. Knepley tmpO = NULL; 22729bf0dad6SMatthew G. Knepley } 22739bf0dad6SMatthew G. Knepley for (t = 0; t < tmpSize; ++t) { 22749bf0dad6SMatthew G. Knepley const PetscInt i = ((rev ? tmpSize-t : t) + off)%tmpSize; 22759bf0dad6SMatthew G. Knepley const PetscInt cp = tmp[i]; 22769bf0dad6SMatthew G. Knepley /* Must propogate orientation: When we reverse orientation, we both reverse the direction of iteration and start at the other end of the chain. */ 22779bf0dad6SMatthew G. Knepley /* HACK: It is worse to get the size here, than to change the interpretation of -(*+1) 22789bf0dad6SMatthew G. Knepley const PetscInt co = tmpO ? (rev ? -(tmpO[i]+1) : tmpO[i]) : 0; */ 22799bf0dad6SMatthew G. Knepley PetscInt co = tmpO ? tmpO[i] : 0; 22809bf0dad6SMatthew G. Knepley PetscInt c; 22819bf0dad6SMatthew G. Knepley 22829bf0dad6SMatthew G. Knepley if (rev) { 22839bf0dad6SMatthew G. Knepley PetscInt childSize, coff; 22849bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, cp, &childSize);CHKERRQ(ierr); 22859bf0dad6SMatthew G. Knepley coff = tmpO[i] < 0 ? -(tmpO[i]+1) : tmpO[i]; 22869bf0dad6SMatthew G. Knepley co = childSize ? -(((coff+childSize-1)%childSize)+1) : 0; 22879bf0dad6SMatthew G. Knepley } 22889bf0dad6SMatthew G. Knepley /* Check for duplicate */ 22899bf0dad6SMatthew G. Knepley for (c = 0; c < closureSize; c += 2) { 22909bf0dad6SMatthew G. Knepley if (closure[c] == cp) break; 22919bf0dad6SMatthew G. Knepley } 22929bf0dad6SMatthew G. Knepley if (c == closureSize) { 22939bf0dad6SMatthew G. Knepley closure[closureSize] = cp; 22949bf0dad6SMatthew G. Knepley closure[closureSize+1] = co; 22959bf0dad6SMatthew G. Knepley fifo[fifoSize] = cp; 22969bf0dad6SMatthew G. Knepley fifo[fifoSize+1] = co; 22979bf0dad6SMatthew G. Knepley closureSize += 2; 22989bf0dad6SMatthew G. Knepley fifoSize += 2; 22999bf0dad6SMatthew G. Knepley } 23009bf0dad6SMatthew G. Knepley } 23019bf0dad6SMatthew G. Knepley fifoStart += 2; 23029bf0dad6SMatthew G. Knepley } 23039bf0dad6SMatthew G. Knepley if (numPoints) *numPoints = closureSize/2; 23049bf0dad6SMatthew G. Knepley if (points) *points = closure; 230569291d52SBarry Smith ierr = DMRestoreWorkArray(dm, maxSize, MPIU_INT, &fifo);CHKERRQ(ierr); 23069bf0dad6SMatthew G. Knepley PetscFunctionReturn(0); 23079bf0dad6SMatthew G. Knepley } 23089bf0dad6SMatthew G. Knepley 2309552f7358SJed Brown /*@C 2310eaf898f9SPatrick Sanan DMPlexRestoreTransitiveClosure - Restore the array of points on the transitive closure of the in-edges or out-edges for this point in the DAG 2311552f7358SJed Brown 2312552f7358SJed Brown Not collective 2313552f7358SJed Brown 2314552f7358SJed Brown Input Parameters: 2315552f7358SJed Brown + mesh - The DMPlex 2316eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 2317552f7358SJed Brown . useCone - PETSC_TRUE for in-edges, otherwise use out-edges 2318e5c84f05SJed Brown . numPoints - The number of points in the closure, so points[] is of size 2*numPoints, zeroed on exit 2319e5c84f05SJed Brown - points - The points and point orientations, interleaved as pairs [p0, o0, p1, o1, ...], zeroed on exit 2320552f7358SJed Brown 2321552f7358SJed Brown Note: 23220298fd71SBarry Smith If not using internal storage (points is not NULL on input), this call is unnecessary 2323552f7358SJed Brown 23243813dfbdSMatthew G Knepley Fortran Notes: 23253813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 23263813dfbdSMatthew G Knepley include petsc.h90 in your code. 23273813dfbdSMatthew G Knepley 23283813dfbdSMatthew G Knepley The numPoints argument is not present in the Fortran 90 binding since it is internal to the array. 23293813dfbdSMatthew G Knepley 2330552f7358SJed Brown Level: beginner 2331552f7358SJed Brown 2332552f7358SJed Brown .seealso: DMPlexGetTransitiveClosure(), DMPlexCreate(), DMPlexSetCone(), DMPlexSetChart(), DMPlexGetCone() 2333552f7358SJed Brown @*/ 2334552f7358SJed Brown PetscErrorCode DMPlexRestoreTransitiveClosure(DM dm, PetscInt p, PetscBool useCone, PetscInt *numPoints, PetscInt *points[]) 2335552f7358SJed Brown { 2336552f7358SJed Brown PetscErrorCode ierr; 2337552f7358SJed Brown 2338552f7358SJed Brown PetscFunctionBegin; 2339552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2340e5c84f05SJed Brown if (numPoints) PetscValidIntPointer(numPoints,4); 2341e5c84f05SJed Brown if (points) PetscValidPointer(points,5); 234269291d52SBarry Smith ierr = DMRestoreWorkArray(dm, 0, MPIU_INT, points);CHKERRQ(ierr); 23434ff43b2cSJed Brown if (numPoints) *numPoints = 0; 2344552f7358SJed Brown PetscFunctionReturn(0); 2345552f7358SJed Brown } 2346552f7358SJed Brown 2347552f7358SJed Brown /*@ 2348eaf898f9SPatrick Sanan DMPlexGetMaxSizes - Return the maximum number of in-edges (cone) and out-edges (support) for any point in the DAG 2349552f7358SJed Brown 2350552f7358SJed Brown Not collective 2351552f7358SJed Brown 2352552f7358SJed Brown Input Parameter: 2353552f7358SJed Brown . mesh - The DMPlex 2354552f7358SJed Brown 2355552f7358SJed Brown Output Parameters: 2356552f7358SJed Brown + maxConeSize - The maximum number of in-edges 2357552f7358SJed Brown - maxSupportSize - The maximum number of out-edges 2358552f7358SJed Brown 2359552f7358SJed Brown Level: beginner 2360552f7358SJed Brown 2361552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetConeSize(), DMPlexSetChart() 2362552f7358SJed Brown @*/ 2363552f7358SJed Brown PetscErrorCode DMPlexGetMaxSizes(DM dm, PetscInt *maxConeSize, PetscInt *maxSupportSize) 2364552f7358SJed Brown { 2365552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2366552f7358SJed Brown 2367552f7358SJed Brown PetscFunctionBegin; 2368552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2369552f7358SJed Brown if (maxConeSize) *maxConeSize = mesh->maxConeSize; 2370552f7358SJed Brown if (maxSupportSize) *maxSupportSize = mesh->maxSupportSize; 2371552f7358SJed Brown PetscFunctionReturn(0); 2372552f7358SJed Brown } 2373552f7358SJed Brown 2374552f7358SJed Brown PetscErrorCode DMSetUp_Plex(DM dm) 2375552f7358SJed Brown { 2376552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2377552f7358SJed Brown PetscInt size; 2378552f7358SJed Brown PetscErrorCode ierr; 2379552f7358SJed Brown 2380552f7358SJed Brown PetscFunctionBegin; 2381552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2382552f7358SJed Brown ierr = PetscSectionSetUp(mesh->coneSection);CHKERRQ(ierr); 2383552f7358SJed Brown ierr = PetscSectionGetStorageSize(mesh->coneSection, &size);CHKERRQ(ierr); 23841795a4d1SJed Brown ierr = PetscMalloc1(size, &mesh->cones);CHKERRQ(ierr); 23851795a4d1SJed Brown ierr = PetscCalloc1(size, &mesh->coneOrientations);CHKERRQ(ierr); 2386552f7358SJed Brown if (mesh->maxSupportSize) { 2387552f7358SJed Brown ierr = PetscSectionSetUp(mesh->supportSection);CHKERRQ(ierr); 2388552f7358SJed Brown ierr = PetscSectionGetStorageSize(mesh->supportSection, &size);CHKERRQ(ierr); 23891795a4d1SJed Brown ierr = PetscMalloc1(size, &mesh->supports);CHKERRQ(ierr); 2390552f7358SJed Brown } 2391552f7358SJed Brown PetscFunctionReturn(0); 2392552f7358SJed Brown } 2393552f7358SJed Brown 2394276c5506SMatthew G. Knepley PetscErrorCode DMCreateSubDM_Plex(DM dm, PetscInt numFields, const PetscInt fields[], IS *is, DM *subdm) 2395552f7358SJed Brown { 2396552f7358SJed Brown PetscErrorCode ierr; 2397552f7358SJed Brown 2398552f7358SJed Brown PetscFunctionBegin; 23994d9407bcSMatthew G. Knepley if (subdm) {ierr = DMClone(dm, subdm);CHKERRQ(ierr);} 2400792b654fSMatthew G. Knepley ierr = DMCreateSectionSubDM(dm, numFields, fields, is, subdm);CHKERRQ(ierr); 2401c2939958SSatish Balay if (subdm) {(*subdm)->useNatural = dm->useNatural;} 2402736995cdSBlaise Bourdin if (dm->useNatural && dm->sfMigration) { 2403f94b4a02SBlaise Bourdin PetscSF sfMigrationInv,sfNatural; 2404f94b4a02SBlaise Bourdin PetscSection section, sectionSeq; 2405f94b4a02SBlaise Bourdin 24063dcd263cSBlaise Bourdin (*subdm)->sfMigration = dm->sfMigration; 24073dcd263cSBlaise Bourdin ierr = PetscObjectReference((PetscObject) dm->sfMigration);CHKERRQ(ierr); 2408e87a4003SBarry Smith ierr = DMGetSection((*subdm), §ion);CHKERRQ(ierr);CHKERRQ(ierr); 2409f94b4a02SBlaise Bourdin ierr = PetscSFCreateInverseSF((*subdm)->sfMigration, &sfMigrationInv);CHKERRQ(ierr); 2410f94b4a02SBlaise Bourdin ierr = PetscSectionCreate(PetscObjectComm((PetscObject) (*subdm)), §ionSeq);CHKERRQ(ierr); 2411f94b4a02SBlaise Bourdin ierr = PetscSFDistributeSection(sfMigrationInv, section, NULL, sectionSeq);CHKERRQ(ierr); 2412f94b4a02SBlaise Bourdin 2413f94b4a02SBlaise Bourdin ierr = DMPlexCreateGlobalToNaturalSF(*subdm, sectionSeq, (*subdm)->sfMigration, &sfNatural);CHKERRQ(ierr); 2414c40e9495SBlaise Bourdin (*subdm)->sfNatural = sfNatural; 2415f94b4a02SBlaise Bourdin ierr = PetscSectionDestroy(§ionSeq);CHKERRQ(ierr); 2416f94b4a02SBlaise Bourdin ierr = PetscSFDestroy(&sfMigrationInv);CHKERRQ(ierr); 2417f94b4a02SBlaise Bourdin } 2418552f7358SJed Brown PetscFunctionReturn(0); 2419552f7358SJed Brown } 2420552f7358SJed Brown 24212adcc780SMatthew G. Knepley PetscErrorCode DMCreateSuperDM_Plex(DM dms[], PetscInt len, IS **is, DM *superdm) 24222adcc780SMatthew G. Knepley { 24232adcc780SMatthew G. Knepley PetscErrorCode ierr; 24243dcd263cSBlaise Bourdin PetscInt i = 0; 24252adcc780SMatthew G. Knepley 24262adcc780SMatthew G. Knepley PetscFunctionBegin; 2427435bcee1SStefano Zampini ierr = DMClone(dms[0], superdm);CHKERRQ(ierr); 2428792b654fSMatthew G. Knepley ierr = DMCreateSectionSuperDM(dms, len, is, superdm);CHKERRQ(ierr); 2429c40e9495SBlaise Bourdin (*superdm)->useNatural = PETSC_FALSE; 24303dcd263cSBlaise Bourdin for (i = 0; i < len; i++){ 24313dcd263cSBlaise Bourdin if (dms[i]->useNatural && dms[i]->sfMigration) { 24323dcd263cSBlaise Bourdin PetscSF sfMigrationInv,sfNatural; 24333dcd263cSBlaise Bourdin PetscSection section, sectionSeq; 24343dcd263cSBlaise Bourdin 24353dcd263cSBlaise Bourdin (*superdm)->sfMigration = dms[i]->sfMigration; 24363dcd263cSBlaise Bourdin ierr = PetscObjectReference((PetscObject) dms[i]->sfMigration);CHKERRQ(ierr); 2437c40e9495SBlaise Bourdin (*superdm)->useNatural = PETSC_TRUE; 2438cf0b7c11SKarl Rupp ierr = DMGetSection((*superdm), §ion);CHKERRQ(ierr); 24393dcd263cSBlaise Bourdin ierr = PetscSFCreateInverseSF((*superdm)->sfMigration, &sfMigrationInv);CHKERRQ(ierr); 24403dcd263cSBlaise Bourdin ierr = PetscSectionCreate(PetscObjectComm((PetscObject) (*superdm)), §ionSeq);CHKERRQ(ierr); 24413dcd263cSBlaise Bourdin ierr = PetscSFDistributeSection(sfMigrationInv, section, NULL, sectionSeq);CHKERRQ(ierr); 24423dcd263cSBlaise Bourdin 24433dcd263cSBlaise Bourdin ierr = DMPlexCreateGlobalToNaturalSF(*superdm, sectionSeq, (*superdm)->sfMigration, &sfNatural);CHKERRQ(ierr); 2444c40e9495SBlaise Bourdin (*superdm)->sfNatural = sfNatural; 24453dcd263cSBlaise Bourdin ierr = PetscSectionDestroy(§ionSeq);CHKERRQ(ierr); 24463dcd263cSBlaise Bourdin ierr = PetscSFDestroy(&sfMigrationInv);CHKERRQ(ierr); 24473dcd263cSBlaise Bourdin break; 24483dcd263cSBlaise Bourdin } 24493dcd263cSBlaise Bourdin } 24502adcc780SMatthew G. Knepley PetscFunctionReturn(0); 24512adcc780SMatthew G. Knepley } 24522adcc780SMatthew G. Knepley 2453552f7358SJed Brown /*@ 2454eaf898f9SPatrick Sanan DMPlexSymmetrize - Create support (out-edge) information from cone (in-edge) information 2455552f7358SJed Brown 2456552f7358SJed Brown Not collective 2457552f7358SJed Brown 2458552f7358SJed Brown Input Parameter: 2459552f7358SJed Brown . mesh - The DMPlex 2460552f7358SJed Brown 2461552f7358SJed Brown Output Parameter: 2462552f7358SJed Brown 2463552f7358SJed Brown Note: 2464552f7358SJed Brown This should be called after all calls to DMPlexSetCone() 2465552f7358SJed Brown 2466552f7358SJed Brown Level: beginner 2467552f7358SJed Brown 2468552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetChart(), DMPlexSetConeSize(), DMPlexSetCone() 2469552f7358SJed Brown @*/ 2470552f7358SJed Brown PetscErrorCode DMPlexSymmetrize(DM dm) 2471552f7358SJed Brown { 2472552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2473552f7358SJed Brown PetscInt *offsets; 2474552f7358SJed Brown PetscInt supportSize; 2475552f7358SJed Brown PetscInt pStart, pEnd, p; 2476552f7358SJed Brown PetscErrorCode ierr; 2477552f7358SJed Brown 2478552f7358SJed Brown PetscFunctionBegin; 2479552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 248082f516ccSBarry Smith if (mesh->supports) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Supports were already setup in this DMPlex"); 2481552f7358SJed Brown /* Calculate support sizes */ 2482552f7358SJed Brown ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 2483552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 2484552f7358SJed Brown PetscInt dof, off, c; 2485552f7358SJed Brown 2486552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 2487552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 2488552f7358SJed Brown for (c = off; c < off+dof; ++c) { 2489552f7358SJed Brown ierr = PetscSectionAddDof(mesh->supportSection, mesh->cones[c], 1);CHKERRQ(ierr); 2490552f7358SJed Brown } 2491552f7358SJed Brown } 2492552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 2493552f7358SJed Brown PetscInt dof; 2494552f7358SJed Brown 2495552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, &dof);CHKERRQ(ierr); 24960d644c17SKarl Rupp 2497552f7358SJed Brown mesh->maxSupportSize = PetscMax(mesh->maxSupportSize, dof); 2498552f7358SJed Brown } 2499552f7358SJed Brown ierr = PetscSectionSetUp(mesh->supportSection);CHKERRQ(ierr); 2500552f7358SJed Brown /* Calculate supports */ 2501552f7358SJed Brown ierr = PetscSectionGetStorageSize(mesh->supportSection, &supportSize);CHKERRQ(ierr); 25021795a4d1SJed Brown ierr = PetscMalloc1(supportSize, &mesh->supports);CHKERRQ(ierr); 25031795a4d1SJed Brown ierr = PetscCalloc1(pEnd - pStart, &offsets);CHKERRQ(ierr); 2504552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 2505552f7358SJed Brown PetscInt dof, off, c; 2506552f7358SJed Brown 2507552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 2508552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 2509552f7358SJed Brown for (c = off; c < off+dof; ++c) { 2510552f7358SJed Brown const PetscInt q = mesh->cones[c]; 2511552f7358SJed Brown PetscInt offS; 2512552f7358SJed Brown 2513552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, q, &offS);CHKERRQ(ierr); 25140d644c17SKarl Rupp 2515552f7358SJed Brown mesh->supports[offS+offsets[q]] = p; 2516552f7358SJed Brown ++offsets[q]; 2517552f7358SJed Brown } 2518552f7358SJed Brown } 2519552f7358SJed Brown ierr = PetscFree(offsets);CHKERRQ(ierr); 2520552f7358SJed Brown PetscFunctionReturn(0); 2521552f7358SJed Brown } 2522552f7358SJed Brown 2523*277ea44aSLisandro Dalcin static PetscErrorCode DMPlexCreateDepthStratum(DM dm, DMLabel label, PetscInt depth, PetscInt pStart, PetscInt pEnd) 2524*277ea44aSLisandro Dalcin { 2525*277ea44aSLisandro Dalcin IS stratumIS; 2526*277ea44aSLisandro Dalcin PetscErrorCode ierr; 2527*277ea44aSLisandro Dalcin 2528*277ea44aSLisandro Dalcin PetscFunctionBegin; 2529*277ea44aSLisandro Dalcin if (pStart >= pEnd) PetscFunctionReturn(0); 2530*277ea44aSLisandro Dalcin #if defined(PETSC_USE_DEBUG) 2531*277ea44aSLisandro Dalcin { 2532*277ea44aSLisandro Dalcin PetscInt qStart, qEnd, numLevels, level; 2533*277ea44aSLisandro Dalcin PetscBool overlap = PETSC_FALSE; 2534*277ea44aSLisandro Dalcin ierr = DMLabelGetNumValues(label, &numLevels);CHKERRQ(ierr); 2535*277ea44aSLisandro Dalcin for (level = 0; level < numLevels; level++) { 2536*277ea44aSLisandro Dalcin ierr = DMLabelGetStratumBounds(label, level, &qStart, &qEnd);CHKERRQ(ierr); 2537*277ea44aSLisandro Dalcin if ((pStart >= qStart && pStart < qEnd) || (pEnd > qStart && pEnd <= qEnd)) {overlap = PETSC_TRUE; break;} 2538*277ea44aSLisandro Dalcin } 2539*277ea44aSLisandro Dalcin if (overlap) SETERRQ6(PETSC_COMM_SELF, PETSC_ERR_PLIB, "New depth %D range [%D,%D) overlaps with depth %D range [%D,%D)", depth, pStart, pEnd, level, qStart, qEnd); 2540*277ea44aSLisandro Dalcin } 2541*277ea44aSLisandro Dalcin #endif 2542*277ea44aSLisandro Dalcin ierr = ISCreateStride(PETSC_COMM_SELF, pEnd-pStart, pStart, 1, &stratumIS);CHKERRQ(ierr); 2543*277ea44aSLisandro Dalcin ierr = DMLabelSetStratumIS(label, depth, stratumIS);CHKERRQ(ierr); 2544*277ea44aSLisandro Dalcin ierr = ISDestroy(&stratumIS);CHKERRQ(ierr); 2545*277ea44aSLisandro Dalcin PetscFunctionReturn(0); 2546*277ea44aSLisandro Dalcin } 2547*277ea44aSLisandro Dalcin 25487d5acc75SStefano Zampini static PetscErrorCode DMPlexCreateDimStratum(DM,DMLabel,DMLabel,PetscInt,PetscInt); 25497d5acc75SStefano Zampini 2550552f7358SJed Brown /*@ 2551eaf898f9SPatrick Sanan DMPlexStratify - The DAG for most topologies is a graded poset (http://en.wikipedia.org/wiki/Graded_poset), and 2552eaf898f9SPatrick Sanan can be illustrated by a Hasse Diagram (a http://en.wikipedia.org/wiki/Hasse_diagram). The strata group all points of the 2553552f7358SJed Brown same grade, and this function calculates the strata. This grade can be seen as the height (or depth) of the point in 2554552f7358SJed Brown the DAG. 2555552f7358SJed Brown 2556bf4602e4SToby Isaac Collective on dm 2557552f7358SJed Brown 2558552f7358SJed Brown Input Parameter: 2559552f7358SJed Brown . mesh - The DMPlex 2560552f7358SJed Brown 2561552f7358SJed Brown Output Parameter: 2562552f7358SJed Brown 2563552f7358SJed Brown Notes: 2564150b719bSJed Brown Concretely, DMPlexStratify() creates a new label named "depth" containing the dimension of each element: 0 for vertices, 2565150b719bSJed Brown 1 for edges, and so on. The depth label can be accessed through DMPlexGetDepthLabel() or DMPlexGetDepthStratum(), or 2566c58f1c22SToby Isaac manually via DMGetLabel(). The height is defined implicitly by height = maxDimension - depth, and can be accessed 2567150b719bSJed Brown via DMPlexGetHeightStratum(). For example, cells have height 0 and faces have height 1. 2568552f7358SJed Brown 2569150b719bSJed Brown DMPlexStratify() should be called after all calls to DMPlexSymmetrize() 2570552f7358SJed Brown 2571552f7358SJed Brown Level: beginner 2572552f7358SJed Brown 2573552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSymmetrize() 2574552f7358SJed Brown @*/ 2575552f7358SJed Brown PetscErrorCode DMPlexStratify(DM dm) 2576552f7358SJed Brown { 2577df0420ecSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 2578aa50250dSMatthew G. Knepley DMLabel label; 2579552f7358SJed Brown PetscInt pStart, pEnd, p; 2580552f7358SJed Brown PetscInt numRoots = 0, numLeaves = 0; 25817d5acc75SStefano Zampini PetscInt cMax, fMax, eMax, vMax; 2582552f7358SJed Brown PetscErrorCode ierr; 2583552f7358SJed Brown 2584552f7358SJed Brown PetscFunctionBegin; 2585552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2586552f7358SJed Brown ierr = PetscLogEventBegin(DMPLEX_Stratify,dm,0,0,0);CHKERRQ(ierr); 2587*277ea44aSLisandro Dalcin 2588*277ea44aSLisandro Dalcin /* Create depth label */ 2589aa50250dSMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 2590c58f1c22SToby Isaac ierr = DMCreateLabel(dm, "depth");CHKERRQ(ierr); 2591aa50250dSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 2592*277ea44aSLisandro Dalcin 2593*277ea44aSLisandro Dalcin { 2594552f7358SJed Brown /* Initialize roots and count leaves */ 2595*277ea44aSLisandro Dalcin PetscInt sMin = PETSC_MAX_INT; 2596*277ea44aSLisandro Dalcin PetscInt sMax = PETSC_MIN_INT; 2597552f7358SJed Brown PetscInt coneSize, supportSize; 2598552f7358SJed Brown 2599*277ea44aSLisandro Dalcin for (p = pStart; p < pEnd; ++p) { 2600552f7358SJed Brown ierr = DMPlexGetConeSize(dm, p, &coneSize);CHKERRQ(ierr); 2601552f7358SJed Brown ierr = DMPlexGetSupportSize(dm, p, &supportSize);CHKERRQ(ierr); 2602552f7358SJed Brown if (!coneSize && supportSize) { 2603*277ea44aSLisandro Dalcin sMin = PetscMin(p, sMin); 2604*277ea44aSLisandro Dalcin sMax = PetscMax(p, sMax); 2605552f7358SJed Brown ++numRoots; 2606552f7358SJed Brown } else if (!supportSize && coneSize) { 2607552f7358SJed Brown ++numLeaves; 2608552f7358SJed Brown } else if (!supportSize && !coneSize) { 2609552f7358SJed Brown /* Isolated points */ 2610*277ea44aSLisandro Dalcin sMin = PetscMin(p, sMin); 2611*277ea44aSLisandro Dalcin sMax = PetscMax(p, sMax); 2612552f7358SJed Brown } 2613552f7358SJed Brown } 2614*277ea44aSLisandro Dalcin ierr = DMPlexCreateDepthStratum(dm, label, 0, sMin, sMax+1);CHKERRQ(ierr); 2615*277ea44aSLisandro Dalcin } 2616*277ea44aSLisandro Dalcin 2617552f7358SJed Brown if (numRoots + numLeaves == (pEnd - pStart)) { 2618*277ea44aSLisandro Dalcin PetscInt sMin = PETSC_MAX_INT; 2619*277ea44aSLisandro Dalcin PetscInt sMax = PETSC_MIN_INT; 2620552f7358SJed Brown PetscInt coneSize, supportSize; 2621552f7358SJed Brown 2622*277ea44aSLisandro Dalcin for (p = pStart; p < pEnd; ++p) { 2623552f7358SJed Brown ierr = DMPlexGetConeSize(dm, p, &coneSize);CHKERRQ(ierr); 2624552f7358SJed Brown ierr = DMPlexGetSupportSize(dm, p, &supportSize);CHKERRQ(ierr); 2625552f7358SJed Brown if (!supportSize && coneSize) { 2626*277ea44aSLisandro Dalcin sMin = PetscMin(p, sMin); 2627*277ea44aSLisandro Dalcin sMax = PetscMax(p, sMax); 2628552f7358SJed Brown } 2629552f7358SJed Brown } 2630*277ea44aSLisandro Dalcin ierr = DMPlexCreateDepthStratum(dm, label, 1, sMin, sMax+1);CHKERRQ(ierr); 2631552f7358SJed Brown } else { 2632*277ea44aSLisandro Dalcin PetscInt level = 0; 2633*277ea44aSLisandro Dalcin PetscInt qStart, qEnd, q; 2634552f7358SJed Brown 2635*277ea44aSLisandro Dalcin ierr = DMLabelGetStratumBounds(label, level, &qStart, &qEnd);CHKERRQ(ierr); 2636*277ea44aSLisandro Dalcin while (qEnd > qStart) { 2637*277ea44aSLisandro Dalcin PetscInt sMin = PETSC_MAX_INT; 2638*277ea44aSLisandro Dalcin PetscInt sMax = PETSC_MIN_INT; 263974ef644bSMatthew G. Knepley 2640*277ea44aSLisandro Dalcin for (q = qStart; q < qEnd; ++q) { 264174ef644bSMatthew G. Knepley const PetscInt *support; 264274ef644bSMatthew G. Knepley PetscInt supportSize, s; 264374ef644bSMatthew G. Knepley 2644*277ea44aSLisandro Dalcin ierr = DMPlexGetSupportSize(dm, q, &supportSize);CHKERRQ(ierr); 2645*277ea44aSLisandro Dalcin ierr = DMPlexGetSupport(dm, q, &support);CHKERRQ(ierr); 264674ef644bSMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 2647*277ea44aSLisandro Dalcin sMin = PetscMin(support[s], sMin); 2648*277ea44aSLisandro Dalcin sMax = PetscMax(support[s], sMax); 2649552f7358SJed Brown } 2650552f7358SJed Brown } 2651*277ea44aSLisandro Dalcin ierr = DMLabelGetNumValues(label, &level);CHKERRQ(ierr); 2652*277ea44aSLisandro Dalcin ierr = DMPlexCreateDepthStratum(dm, label, level, sMin, sMax+1);CHKERRQ(ierr); 2653*277ea44aSLisandro Dalcin ierr = DMLabelGetStratumBounds(label, level, &qStart, &qEnd);CHKERRQ(ierr); 265474ef644bSMatthew G. Knepley } 265574ef644bSMatthew G. Knepley } 2656bf4602e4SToby Isaac { /* just in case there is an empty process */ 2657bf4602e4SToby Isaac PetscInt numValues, maxValues = 0, v; 2658bf4602e4SToby Isaac 2659bf4602e4SToby Isaac ierr = DMLabelGetNumValues(label, &numValues);CHKERRQ(ierr); 26606d1e82d3SBarry Smith ierr = MPI_Allreduce(&numValues,&maxValues,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 2661bf4602e4SToby Isaac for (v = numValues; v < maxValues; v++) { 2662367003a6SStefano Zampini ierr = DMLabelAddStratum(label, v);CHKERRQ(ierr); 2663bf4602e4SToby Isaac } 2664bf4602e4SToby Isaac } 2665d67d17b1SMatthew G. Knepley ierr = PetscObjectStateGet((PetscObject) label, &mesh->depthState);CHKERRQ(ierr); 26667d5acc75SStefano Zampini 26677d5acc75SStefano Zampini ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 26687d5acc75SStefano Zampini if (cMax >= 0 || fMax >= 0 || eMax >= 0 || vMax >= 0) { 26697d5acc75SStefano Zampini PetscInt dim; 2670*277ea44aSLisandro Dalcin DMLabel dimLabel; 26717d5acc75SStefano Zampini 26727d5acc75SStefano Zampini ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 26737d5acc75SStefano Zampini ierr = DMCreateLabel(dm, "dim");CHKERRQ(ierr); 26747d5acc75SStefano Zampini ierr = DMGetLabel(dm, "dim", &dimLabel);CHKERRQ(ierr); 26757d5acc75SStefano Zampini if (cMax >= 0) {ierr = DMPlexCreateDimStratum(dm, label, dimLabel, dim, cMax);CHKERRQ(ierr);} 26767d5acc75SStefano Zampini if (fMax >= 0) {ierr = DMPlexCreateDimStratum(dm, label, dimLabel, dim - 1, fMax);CHKERRQ(ierr);} 26777d5acc75SStefano Zampini if (eMax >= 0) {ierr = DMPlexCreateDimStratum(dm, label, dimLabel, 1, eMax);CHKERRQ(ierr);} 26787d5acc75SStefano Zampini if (vMax >= 0) {ierr = DMPlexCreateDimStratum(dm, label, dimLabel, 0, vMax);CHKERRQ(ierr);} 26797d5acc75SStefano Zampini } 2680552f7358SJed Brown ierr = PetscLogEventEnd(DMPLEX_Stratify,dm,0,0,0);CHKERRQ(ierr); 2681552f7358SJed Brown PetscFunctionReturn(0); 2682552f7358SJed Brown } 2683552f7358SJed Brown 2684552f7358SJed Brown /*@C 2685552f7358SJed Brown DMPlexGetJoin - Get an array for the join of the set of points 2686552f7358SJed Brown 2687552f7358SJed Brown Not Collective 2688552f7358SJed Brown 2689552f7358SJed Brown Input Parameters: 2690552f7358SJed Brown + dm - The DMPlex object 2691552f7358SJed Brown . numPoints - The number of input points for the join 2692552f7358SJed Brown - points - The input points 2693552f7358SJed Brown 2694552f7358SJed Brown Output Parameters: 2695552f7358SJed Brown + numCoveredPoints - The number of points in the join 2696552f7358SJed Brown - coveredPoints - The points in the join 2697552f7358SJed Brown 2698552f7358SJed Brown Level: intermediate 2699552f7358SJed Brown 2700552f7358SJed Brown Note: Currently, this is restricted to a single level join 2701552f7358SJed Brown 27023813dfbdSMatthew G Knepley Fortran Notes: 27033813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 27043813dfbdSMatthew G Knepley include petsc.h90 in your code. 27053813dfbdSMatthew G Knepley 27063813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 27073813dfbdSMatthew G Knepley 2708552f7358SJed Brown .keywords: mesh 2709552f7358SJed Brown .seealso: DMPlexRestoreJoin(), DMPlexGetMeet() 2710552f7358SJed Brown @*/ 2711552f7358SJed Brown PetscErrorCode DMPlexGetJoin(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 2712552f7358SJed Brown { 2713552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2714552f7358SJed Brown PetscInt *join[2]; 2715552f7358SJed Brown PetscInt joinSize, i = 0; 2716552f7358SJed Brown PetscInt dof, off, p, c, m; 2717552f7358SJed Brown PetscErrorCode ierr; 2718552f7358SJed Brown 2719552f7358SJed Brown PetscFunctionBegin; 2720552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 272148bb261cSVaclav Hapla PetscValidIntPointer(points, 3); 272248bb261cSVaclav Hapla PetscValidIntPointer(numCoveredPoints, 4); 272348bb261cSVaclav Hapla PetscValidPointer(coveredPoints, 5); 272469291d52SBarry Smith ierr = DMGetWorkArray(dm, mesh->maxSupportSize, MPIU_INT, &join[0]);CHKERRQ(ierr); 272569291d52SBarry Smith ierr = DMGetWorkArray(dm, mesh->maxSupportSize, MPIU_INT, &join[1]);CHKERRQ(ierr); 2726552f7358SJed Brown /* Copy in support of first point */ 2727552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, points[0], &dof);CHKERRQ(ierr); 2728552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, points[0], &off);CHKERRQ(ierr); 2729552f7358SJed Brown for (joinSize = 0; joinSize < dof; ++joinSize) { 2730552f7358SJed Brown join[i][joinSize] = mesh->supports[off+joinSize]; 2731552f7358SJed Brown } 2732552f7358SJed Brown /* Check each successive support */ 2733552f7358SJed Brown for (p = 1; p < numPoints; ++p) { 2734552f7358SJed Brown PetscInt newJoinSize = 0; 2735552f7358SJed Brown 2736552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, points[p], &dof);CHKERRQ(ierr); 2737552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, points[p], &off);CHKERRQ(ierr); 2738552f7358SJed Brown for (c = 0; c < dof; ++c) { 2739552f7358SJed Brown const PetscInt point = mesh->supports[off+c]; 2740552f7358SJed Brown 2741552f7358SJed Brown for (m = 0; m < joinSize; ++m) { 2742552f7358SJed Brown if (point == join[i][m]) { 2743552f7358SJed Brown join[1-i][newJoinSize++] = point; 2744552f7358SJed Brown break; 2745552f7358SJed Brown } 2746552f7358SJed Brown } 2747552f7358SJed Brown } 2748552f7358SJed Brown joinSize = newJoinSize; 2749552f7358SJed Brown i = 1-i; 2750552f7358SJed Brown } 2751552f7358SJed Brown *numCoveredPoints = joinSize; 2752552f7358SJed Brown *coveredPoints = join[i]; 275369291d52SBarry Smith ierr = DMRestoreWorkArray(dm, mesh->maxSupportSize, MPIU_INT, &join[1-i]);CHKERRQ(ierr); 2754552f7358SJed Brown PetscFunctionReturn(0); 2755552f7358SJed Brown } 2756552f7358SJed Brown 2757552f7358SJed Brown /*@C 2758552f7358SJed Brown DMPlexRestoreJoin - Restore an array for the join of the set of points 2759552f7358SJed Brown 2760552f7358SJed Brown Not Collective 2761552f7358SJed Brown 2762552f7358SJed Brown Input Parameters: 2763552f7358SJed Brown + dm - The DMPlex object 2764552f7358SJed Brown . numPoints - The number of input points for the join 2765552f7358SJed Brown - points - The input points 2766552f7358SJed Brown 2767552f7358SJed Brown Output Parameters: 2768552f7358SJed Brown + numCoveredPoints - The number of points in the join 2769552f7358SJed Brown - coveredPoints - The points in the join 2770552f7358SJed Brown 27713813dfbdSMatthew G Knepley Fortran Notes: 27723813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 27733813dfbdSMatthew G Knepley include petsc.h90 in your code. 27743813dfbdSMatthew G Knepley 27753813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 27763813dfbdSMatthew G Knepley 2777552f7358SJed Brown Level: intermediate 2778552f7358SJed Brown 2779552f7358SJed Brown .keywords: mesh 2780552f7358SJed Brown .seealso: DMPlexGetJoin(), DMPlexGetFullJoin(), DMPlexGetMeet() 2781552f7358SJed Brown @*/ 2782552f7358SJed Brown PetscErrorCode DMPlexRestoreJoin(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 2783552f7358SJed Brown { 2784552f7358SJed Brown PetscErrorCode ierr; 2785552f7358SJed Brown 2786552f7358SJed Brown PetscFunctionBegin; 2787552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2788d7902bd2SMatthew G. Knepley if (points) PetscValidIntPointer(points,3); 2789d7902bd2SMatthew G. Knepley if (numCoveredPoints) PetscValidIntPointer(numCoveredPoints,4); 2790d7902bd2SMatthew G. Knepley PetscValidPointer(coveredPoints, 5); 279169291d52SBarry Smith ierr = DMRestoreWorkArray(dm, 0, MPIU_INT, (void*) coveredPoints);CHKERRQ(ierr); 2792d7902bd2SMatthew G. Knepley if (numCoveredPoints) *numCoveredPoints = 0; 2793552f7358SJed Brown PetscFunctionReturn(0); 2794552f7358SJed Brown } 2795552f7358SJed Brown 2796552f7358SJed Brown /*@C 2797552f7358SJed Brown DMPlexGetFullJoin - Get an array for the join of the set of points 2798552f7358SJed Brown 2799552f7358SJed Brown Not Collective 2800552f7358SJed Brown 2801552f7358SJed Brown Input Parameters: 2802552f7358SJed Brown + dm - The DMPlex object 2803552f7358SJed Brown . numPoints - The number of input points for the join 2804552f7358SJed Brown - points - The input points 2805552f7358SJed Brown 2806552f7358SJed Brown Output Parameters: 2807552f7358SJed Brown + numCoveredPoints - The number of points in the join 2808552f7358SJed Brown - coveredPoints - The points in the join 2809552f7358SJed Brown 28103813dfbdSMatthew G Knepley Fortran Notes: 28113813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 28123813dfbdSMatthew G Knepley include petsc.h90 in your code. 28133813dfbdSMatthew G Knepley 28143813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 28153813dfbdSMatthew G Knepley 2816552f7358SJed Brown Level: intermediate 2817552f7358SJed Brown 2818552f7358SJed Brown .keywords: mesh 2819552f7358SJed Brown .seealso: DMPlexGetJoin(), DMPlexRestoreJoin(), DMPlexGetMeet() 2820552f7358SJed Brown @*/ 2821552f7358SJed Brown PetscErrorCode DMPlexGetFullJoin(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 2822552f7358SJed Brown { 2823552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2824552f7358SJed Brown PetscInt *offsets, **closures; 2825552f7358SJed Brown PetscInt *join[2]; 2826552f7358SJed Brown PetscInt depth = 0, maxSize, joinSize = 0, i = 0; 282724c766afSToby Isaac PetscInt p, d, c, m, ms; 2828552f7358SJed Brown PetscErrorCode ierr; 2829552f7358SJed Brown 2830552f7358SJed Brown PetscFunctionBegin; 2831552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 283248bb261cSVaclav Hapla PetscValidIntPointer(points, 3); 283348bb261cSVaclav Hapla PetscValidIntPointer(numCoveredPoints, 4); 283448bb261cSVaclav Hapla PetscValidPointer(coveredPoints, 5); 2835552f7358SJed Brown 2836552f7358SJed Brown ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 28371795a4d1SJed Brown ierr = PetscCalloc1(numPoints, &closures);CHKERRQ(ierr); 283869291d52SBarry Smith ierr = DMGetWorkArray(dm, numPoints*(depth+2), MPIU_INT, &offsets);CHKERRQ(ierr); 283924c766afSToby Isaac ms = mesh->maxSupportSize; 284024c766afSToby Isaac maxSize = (ms > 1) ? ((PetscPowInt(ms,depth+1)-1)/(ms-1)) : depth + 1; 284169291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &join[0]);CHKERRQ(ierr); 284269291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &join[1]);CHKERRQ(ierr); 2843552f7358SJed Brown 2844552f7358SJed Brown for (p = 0; p < numPoints; ++p) { 2845552f7358SJed Brown PetscInt closureSize; 2846552f7358SJed Brown 2847552f7358SJed Brown ierr = DMPlexGetTransitiveClosure(dm, points[p], PETSC_FALSE, &closureSize, &closures[p]);CHKERRQ(ierr); 28480d644c17SKarl Rupp 2849552f7358SJed Brown offsets[p*(depth+2)+0] = 0; 2850552f7358SJed Brown for (d = 0; d < depth+1; ++d) { 2851552f7358SJed Brown PetscInt pStart, pEnd, i; 2852552f7358SJed Brown 2853552f7358SJed Brown ierr = DMPlexGetDepthStratum(dm, d, &pStart, &pEnd);CHKERRQ(ierr); 2854552f7358SJed Brown for (i = offsets[p*(depth+2)+d]; i < closureSize; ++i) { 2855552f7358SJed Brown if ((pStart > closures[p][i*2]) || (pEnd <= closures[p][i*2])) { 2856552f7358SJed Brown offsets[p*(depth+2)+d+1] = i; 2857552f7358SJed Brown break; 2858552f7358SJed Brown } 2859552f7358SJed Brown } 2860552f7358SJed Brown if (i == closureSize) offsets[p*(depth+2)+d+1] = i; 2861552f7358SJed Brown } 286282f516ccSBarry Smith if (offsets[p*(depth+2)+depth+1] != closureSize) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Total size of closure %D should be %D", offsets[p*(depth+2)+depth+1], closureSize); 2863552f7358SJed Brown } 2864552f7358SJed Brown for (d = 0; d < depth+1; ++d) { 2865552f7358SJed Brown PetscInt dof; 2866552f7358SJed Brown 2867552f7358SJed Brown /* Copy in support of first point */ 2868552f7358SJed Brown dof = offsets[d+1] - offsets[d]; 2869552f7358SJed Brown for (joinSize = 0; joinSize < dof; ++joinSize) { 2870552f7358SJed Brown join[i][joinSize] = closures[0][(offsets[d]+joinSize)*2]; 2871552f7358SJed Brown } 2872552f7358SJed Brown /* Check each successive cone */ 2873552f7358SJed Brown for (p = 1; p < numPoints && joinSize; ++p) { 2874552f7358SJed Brown PetscInt newJoinSize = 0; 2875552f7358SJed Brown 2876552f7358SJed Brown dof = offsets[p*(depth+2)+d+1] - offsets[p*(depth+2)+d]; 2877552f7358SJed Brown for (c = 0; c < dof; ++c) { 2878552f7358SJed Brown const PetscInt point = closures[p][(offsets[p*(depth+2)+d]+c)*2]; 2879552f7358SJed Brown 2880552f7358SJed Brown for (m = 0; m < joinSize; ++m) { 2881552f7358SJed Brown if (point == join[i][m]) { 2882552f7358SJed Brown join[1-i][newJoinSize++] = point; 2883552f7358SJed Brown break; 2884552f7358SJed Brown } 2885552f7358SJed Brown } 2886552f7358SJed Brown } 2887552f7358SJed Brown joinSize = newJoinSize; 2888552f7358SJed Brown i = 1-i; 2889552f7358SJed Brown } 2890552f7358SJed Brown if (joinSize) break; 2891552f7358SJed Brown } 2892552f7358SJed Brown *numCoveredPoints = joinSize; 2893552f7358SJed Brown *coveredPoints = join[i]; 2894552f7358SJed Brown for (p = 0; p < numPoints; ++p) { 28950298fd71SBarry Smith ierr = DMPlexRestoreTransitiveClosure(dm, points[p], PETSC_FALSE, NULL, &closures[p]);CHKERRQ(ierr); 2896552f7358SJed Brown } 2897552f7358SJed Brown ierr = PetscFree(closures);CHKERRQ(ierr); 289869291d52SBarry Smith ierr = DMRestoreWorkArray(dm, numPoints*(depth+2), MPIU_INT, &offsets);CHKERRQ(ierr); 289969291d52SBarry Smith ierr = DMRestoreWorkArray(dm, mesh->maxSupportSize, MPIU_INT, &join[1-i]);CHKERRQ(ierr); 2900552f7358SJed Brown PetscFunctionReturn(0); 2901552f7358SJed Brown } 2902552f7358SJed Brown 2903552f7358SJed Brown /*@C 2904552f7358SJed Brown DMPlexGetMeet - Get an array for the meet of the set of points 2905552f7358SJed Brown 2906552f7358SJed Brown Not Collective 2907552f7358SJed Brown 2908552f7358SJed Brown Input Parameters: 2909552f7358SJed Brown + dm - The DMPlex object 2910552f7358SJed Brown . numPoints - The number of input points for the meet 2911552f7358SJed Brown - points - The input points 2912552f7358SJed Brown 2913552f7358SJed Brown Output Parameters: 2914552f7358SJed Brown + numCoveredPoints - The number of points in the meet 2915552f7358SJed Brown - coveredPoints - The points in the meet 2916552f7358SJed Brown 2917552f7358SJed Brown Level: intermediate 2918552f7358SJed Brown 2919552f7358SJed Brown Note: Currently, this is restricted to a single level meet 2920552f7358SJed Brown 29213813dfbdSMatthew G Knepley Fortran Notes: 29223813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 29233813dfbdSMatthew G Knepley include petsc.h90 in your code. 29243813dfbdSMatthew G Knepley 29253813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 29263813dfbdSMatthew G Knepley 2927552f7358SJed Brown .keywords: mesh 2928552f7358SJed Brown .seealso: DMPlexRestoreMeet(), DMPlexGetJoin() 2929552f7358SJed Brown @*/ 2930552f7358SJed Brown PetscErrorCode DMPlexGetMeet(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveringPoints, const PetscInt **coveringPoints) 2931552f7358SJed Brown { 2932552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2933552f7358SJed Brown PetscInt *meet[2]; 2934552f7358SJed Brown PetscInt meetSize, i = 0; 2935552f7358SJed Brown PetscInt dof, off, p, c, m; 2936552f7358SJed Brown PetscErrorCode ierr; 2937552f7358SJed Brown 2938552f7358SJed Brown PetscFunctionBegin; 2939552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2940552f7358SJed Brown PetscValidPointer(points, 2); 2941552f7358SJed Brown PetscValidPointer(numCoveringPoints, 3); 2942552f7358SJed Brown PetscValidPointer(coveringPoints, 4); 294369291d52SBarry Smith ierr = DMGetWorkArray(dm, mesh->maxConeSize, MPIU_INT, &meet[0]);CHKERRQ(ierr); 294469291d52SBarry Smith ierr = DMGetWorkArray(dm, mesh->maxConeSize, MPIU_INT, &meet[1]);CHKERRQ(ierr); 2945552f7358SJed Brown /* Copy in cone of first point */ 2946552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, points[0], &dof);CHKERRQ(ierr); 2947552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, points[0], &off);CHKERRQ(ierr); 2948552f7358SJed Brown for (meetSize = 0; meetSize < dof; ++meetSize) { 2949552f7358SJed Brown meet[i][meetSize] = mesh->cones[off+meetSize]; 2950552f7358SJed Brown } 2951552f7358SJed Brown /* Check each successive cone */ 2952552f7358SJed Brown for (p = 1; p < numPoints; ++p) { 2953552f7358SJed Brown PetscInt newMeetSize = 0; 2954552f7358SJed Brown 2955552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, points[p], &dof);CHKERRQ(ierr); 2956552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, points[p], &off);CHKERRQ(ierr); 2957552f7358SJed Brown for (c = 0; c < dof; ++c) { 2958552f7358SJed Brown const PetscInt point = mesh->cones[off+c]; 2959552f7358SJed Brown 2960552f7358SJed Brown for (m = 0; m < meetSize; ++m) { 2961552f7358SJed Brown if (point == meet[i][m]) { 2962552f7358SJed Brown meet[1-i][newMeetSize++] = point; 2963552f7358SJed Brown break; 2964552f7358SJed Brown } 2965552f7358SJed Brown } 2966552f7358SJed Brown } 2967552f7358SJed Brown meetSize = newMeetSize; 2968552f7358SJed Brown i = 1-i; 2969552f7358SJed Brown } 2970552f7358SJed Brown *numCoveringPoints = meetSize; 2971552f7358SJed Brown *coveringPoints = meet[i]; 297269291d52SBarry Smith ierr = DMRestoreWorkArray(dm, mesh->maxConeSize, MPIU_INT, &meet[1-i]);CHKERRQ(ierr); 2973552f7358SJed Brown PetscFunctionReturn(0); 2974552f7358SJed Brown } 2975552f7358SJed Brown 2976552f7358SJed Brown /*@C 2977552f7358SJed Brown DMPlexRestoreMeet - Restore an array for the meet of the set of points 2978552f7358SJed Brown 2979552f7358SJed Brown Not Collective 2980552f7358SJed Brown 2981552f7358SJed Brown Input Parameters: 2982552f7358SJed Brown + dm - The DMPlex object 2983552f7358SJed Brown . numPoints - The number of input points for the meet 2984552f7358SJed Brown - points - The input points 2985552f7358SJed Brown 2986552f7358SJed Brown Output Parameters: 2987552f7358SJed Brown + numCoveredPoints - The number of points in the meet 2988552f7358SJed Brown - coveredPoints - The points in the meet 2989552f7358SJed Brown 2990552f7358SJed Brown Level: intermediate 2991552f7358SJed Brown 29923813dfbdSMatthew G Knepley Fortran Notes: 29933813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 29943813dfbdSMatthew G Knepley include petsc.h90 in your code. 29953813dfbdSMatthew G Knepley 29963813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 29973813dfbdSMatthew G Knepley 2998552f7358SJed Brown .keywords: mesh 2999552f7358SJed Brown .seealso: DMPlexGetMeet(), DMPlexGetFullMeet(), DMPlexGetJoin() 3000552f7358SJed Brown @*/ 3001552f7358SJed Brown PetscErrorCode DMPlexRestoreMeet(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 3002552f7358SJed Brown { 3003552f7358SJed Brown PetscErrorCode ierr; 3004552f7358SJed Brown 3005552f7358SJed Brown PetscFunctionBegin; 3006552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3007d7902bd2SMatthew G. Knepley if (points) PetscValidIntPointer(points,3); 3008d7902bd2SMatthew G. Knepley if (numCoveredPoints) PetscValidIntPointer(numCoveredPoints,4); 3009d7902bd2SMatthew G. Knepley PetscValidPointer(coveredPoints,5); 301069291d52SBarry Smith ierr = DMRestoreWorkArray(dm, 0, MPIU_INT, (void*) coveredPoints);CHKERRQ(ierr); 3011d7902bd2SMatthew G. Knepley if (numCoveredPoints) *numCoveredPoints = 0; 3012552f7358SJed Brown PetscFunctionReturn(0); 3013552f7358SJed Brown } 3014552f7358SJed Brown 3015552f7358SJed Brown /*@C 3016552f7358SJed Brown DMPlexGetFullMeet - Get an array for the meet of the set of points 3017552f7358SJed Brown 3018552f7358SJed Brown Not Collective 3019552f7358SJed Brown 3020552f7358SJed Brown Input Parameters: 3021552f7358SJed Brown + dm - The DMPlex object 3022552f7358SJed Brown . numPoints - The number of input points for the meet 3023552f7358SJed Brown - points - The input points 3024552f7358SJed Brown 3025552f7358SJed Brown Output Parameters: 3026552f7358SJed Brown + numCoveredPoints - The number of points in the meet 3027552f7358SJed Brown - coveredPoints - The points in the meet 3028552f7358SJed Brown 3029552f7358SJed Brown Level: intermediate 3030552f7358SJed Brown 30313813dfbdSMatthew G Knepley Fortran Notes: 30323813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 30333813dfbdSMatthew G Knepley include petsc.h90 in your code. 30343813dfbdSMatthew G Knepley 30353813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 30363813dfbdSMatthew G Knepley 3037552f7358SJed Brown .keywords: mesh 3038552f7358SJed Brown .seealso: DMPlexGetMeet(), DMPlexRestoreMeet(), DMPlexGetJoin() 3039552f7358SJed Brown @*/ 3040552f7358SJed Brown PetscErrorCode DMPlexGetFullMeet(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 3041552f7358SJed Brown { 3042552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3043552f7358SJed Brown PetscInt *offsets, **closures; 3044552f7358SJed Brown PetscInt *meet[2]; 3045552f7358SJed Brown PetscInt height = 0, maxSize, meetSize = 0, i = 0; 304624c766afSToby Isaac PetscInt p, h, c, m, mc; 3047552f7358SJed Brown PetscErrorCode ierr; 3048552f7358SJed Brown 3049552f7358SJed Brown PetscFunctionBegin; 3050552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3051552f7358SJed Brown PetscValidPointer(points, 2); 3052552f7358SJed Brown PetscValidPointer(numCoveredPoints, 3); 3053552f7358SJed Brown PetscValidPointer(coveredPoints, 4); 3054552f7358SJed Brown 3055552f7358SJed Brown ierr = DMPlexGetDepth(dm, &height);CHKERRQ(ierr); 3056785e854fSJed Brown ierr = PetscMalloc1(numPoints, &closures);CHKERRQ(ierr); 305769291d52SBarry Smith ierr = DMGetWorkArray(dm, numPoints*(height+2), MPIU_INT, &offsets);CHKERRQ(ierr); 305824c766afSToby Isaac mc = mesh->maxConeSize; 305924c766afSToby Isaac maxSize = (mc > 1) ? ((PetscPowInt(mc,height+1)-1)/(mc-1)) : height + 1; 306069291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &meet[0]);CHKERRQ(ierr); 306169291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &meet[1]);CHKERRQ(ierr); 3062552f7358SJed Brown 3063552f7358SJed Brown for (p = 0; p < numPoints; ++p) { 3064552f7358SJed Brown PetscInt closureSize; 3065552f7358SJed Brown 3066552f7358SJed Brown ierr = DMPlexGetTransitiveClosure(dm, points[p], PETSC_TRUE, &closureSize, &closures[p]);CHKERRQ(ierr); 30670d644c17SKarl Rupp 3068552f7358SJed Brown offsets[p*(height+2)+0] = 0; 3069552f7358SJed Brown for (h = 0; h < height+1; ++h) { 3070552f7358SJed Brown PetscInt pStart, pEnd, i; 3071552f7358SJed Brown 3072552f7358SJed Brown ierr = DMPlexGetHeightStratum(dm, h, &pStart, &pEnd);CHKERRQ(ierr); 3073552f7358SJed Brown for (i = offsets[p*(height+2)+h]; i < closureSize; ++i) { 3074552f7358SJed Brown if ((pStart > closures[p][i*2]) || (pEnd <= closures[p][i*2])) { 3075552f7358SJed Brown offsets[p*(height+2)+h+1] = i; 3076552f7358SJed Brown break; 3077552f7358SJed Brown } 3078552f7358SJed Brown } 3079552f7358SJed Brown if (i == closureSize) offsets[p*(height+2)+h+1] = i; 3080552f7358SJed Brown } 308182f516ccSBarry Smith if (offsets[p*(height+2)+height+1] != closureSize) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Total size of closure %D should be %D", offsets[p*(height+2)+height+1], closureSize); 3082552f7358SJed Brown } 3083552f7358SJed Brown for (h = 0; h < height+1; ++h) { 3084552f7358SJed Brown PetscInt dof; 3085552f7358SJed Brown 3086552f7358SJed Brown /* Copy in cone of first point */ 3087552f7358SJed Brown dof = offsets[h+1] - offsets[h]; 3088552f7358SJed Brown for (meetSize = 0; meetSize < dof; ++meetSize) { 3089552f7358SJed Brown meet[i][meetSize] = closures[0][(offsets[h]+meetSize)*2]; 3090552f7358SJed Brown } 3091552f7358SJed Brown /* Check each successive cone */ 3092552f7358SJed Brown for (p = 1; p < numPoints && meetSize; ++p) { 3093552f7358SJed Brown PetscInt newMeetSize = 0; 3094552f7358SJed Brown 3095552f7358SJed Brown dof = offsets[p*(height+2)+h+1] - offsets[p*(height+2)+h]; 3096552f7358SJed Brown for (c = 0; c < dof; ++c) { 3097552f7358SJed Brown const PetscInt point = closures[p][(offsets[p*(height+2)+h]+c)*2]; 3098552f7358SJed Brown 3099552f7358SJed Brown for (m = 0; m < meetSize; ++m) { 3100552f7358SJed Brown if (point == meet[i][m]) { 3101552f7358SJed Brown meet[1-i][newMeetSize++] = point; 3102552f7358SJed Brown break; 3103552f7358SJed Brown } 3104552f7358SJed Brown } 3105552f7358SJed Brown } 3106552f7358SJed Brown meetSize = newMeetSize; 3107552f7358SJed Brown i = 1-i; 3108552f7358SJed Brown } 3109552f7358SJed Brown if (meetSize) break; 3110552f7358SJed Brown } 3111552f7358SJed Brown *numCoveredPoints = meetSize; 3112552f7358SJed Brown *coveredPoints = meet[i]; 3113552f7358SJed Brown for (p = 0; p < numPoints; ++p) { 31140298fd71SBarry Smith ierr = DMPlexRestoreTransitiveClosure(dm, points[p], PETSC_TRUE, NULL, &closures[p]);CHKERRQ(ierr); 3115552f7358SJed Brown } 3116552f7358SJed Brown ierr = PetscFree(closures);CHKERRQ(ierr); 311769291d52SBarry Smith ierr = DMRestoreWorkArray(dm, numPoints*(height+2), MPIU_INT, &offsets);CHKERRQ(ierr); 311869291d52SBarry Smith ierr = DMRestoreWorkArray(dm, mesh->maxConeSize, MPIU_INT, &meet[1-i]);CHKERRQ(ierr); 3119552f7358SJed Brown PetscFunctionReturn(0); 3120552f7358SJed Brown } 3121552f7358SJed Brown 31224e3744c5SMatthew G. Knepley /*@C 31234e3744c5SMatthew G. Knepley DMPlexEqual - Determine if two DMs have the same topology 31244e3744c5SMatthew G. Knepley 31254e3744c5SMatthew G. Knepley Not Collective 31264e3744c5SMatthew G. Knepley 31274e3744c5SMatthew G. Knepley Input Parameters: 31284e3744c5SMatthew G. Knepley + dmA - A DMPlex object 31294e3744c5SMatthew G. Knepley - dmB - A DMPlex object 31304e3744c5SMatthew G. Knepley 31314e3744c5SMatthew G. Knepley Output Parameters: 31324e3744c5SMatthew G. Knepley . equal - PETSC_TRUE if the topologies are identical 31334e3744c5SMatthew G. Knepley 31344e3744c5SMatthew G. Knepley Level: intermediate 31354e3744c5SMatthew G. Knepley 31364e3744c5SMatthew G. Knepley Notes: 31374e3744c5SMatthew G. Knepley We are not solving graph isomorphism, so we do not permutation. 31384e3744c5SMatthew G. Knepley 31394e3744c5SMatthew G. Knepley .keywords: mesh 31404e3744c5SMatthew G. Knepley .seealso: DMPlexGetCone() 31414e3744c5SMatthew G. Knepley @*/ 31424e3744c5SMatthew G. Knepley PetscErrorCode DMPlexEqual(DM dmA, DM dmB, PetscBool *equal) 31434e3744c5SMatthew G. Knepley { 31444e3744c5SMatthew G. Knepley PetscInt depth, depthB, pStart, pEnd, pStartB, pEndB, p; 31454e3744c5SMatthew G. Knepley PetscErrorCode ierr; 31464e3744c5SMatthew G. Knepley 31474e3744c5SMatthew G. Knepley PetscFunctionBegin; 31484e3744c5SMatthew G. Knepley PetscValidHeaderSpecific(dmA, DM_CLASSID, 1); 31494e3744c5SMatthew G. Knepley PetscValidHeaderSpecific(dmB, DM_CLASSID, 2); 31504e3744c5SMatthew G. Knepley PetscValidPointer(equal, 3); 31514e3744c5SMatthew G. Knepley 31524e3744c5SMatthew G. Knepley *equal = PETSC_FALSE; 31534e3744c5SMatthew G. Knepley ierr = DMPlexGetDepth(dmA, &depth);CHKERRQ(ierr); 31544e3744c5SMatthew G. Knepley ierr = DMPlexGetDepth(dmB, &depthB);CHKERRQ(ierr); 31554e3744c5SMatthew G. Knepley if (depth != depthB) PetscFunctionReturn(0); 31564e3744c5SMatthew G. Knepley ierr = DMPlexGetChart(dmA, &pStart, &pEnd);CHKERRQ(ierr); 31574e3744c5SMatthew G. Knepley ierr = DMPlexGetChart(dmB, &pStartB, &pEndB);CHKERRQ(ierr); 31584e3744c5SMatthew G. Knepley if ((pStart != pStartB) || (pEnd != pEndB)) PetscFunctionReturn(0); 31594e3744c5SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 31604e3744c5SMatthew G. Knepley const PetscInt *cone, *coneB, *ornt, *orntB, *support, *supportB; 31614e3744c5SMatthew G. Knepley PetscInt coneSize, coneSizeB, c, supportSize, supportSizeB, s; 31624e3744c5SMatthew G. Knepley 31634e3744c5SMatthew G. Knepley ierr = DMPlexGetConeSize(dmA, p, &coneSize);CHKERRQ(ierr); 31644e3744c5SMatthew G. Knepley ierr = DMPlexGetCone(dmA, p, &cone);CHKERRQ(ierr); 31654e3744c5SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dmA, p, &ornt);CHKERRQ(ierr); 31664e3744c5SMatthew G. Knepley ierr = DMPlexGetConeSize(dmB, p, &coneSizeB);CHKERRQ(ierr); 31674e3744c5SMatthew G. Knepley ierr = DMPlexGetCone(dmB, p, &coneB);CHKERRQ(ierr); 31684e3744c5SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dmB, p, &orntB);CHKERRQ(ierr); 31694e3744c5SMatthew G. Knepley if (coneSize != coneSizeB) PetscFunctionReturn(0); 31704e3744c5SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 31714e3744c5SMatthew G. Knepley if (cone[c] != coneB[c]) PetscFunctionReturn(0); 31724e3744c5SMatthew G. Knepley if (ornt[c] != orntB[c]) PetscFunctionReturn(0); 31734e3744c5SMatthew G. Knepley } 31744e3744c5SMatthew G. Knepley ierr = DMPlexGetSupportSize(dmA, p, &supportSize);CHKERRQ(ierr); 31754e3744c5SMatthew G. Knepley ierr = DMPlexGetSupport(dmA, p, &support);CHKERRQ(ierr); 31764e3744c5SMatthew G. Knepley ierr = DMPlexGetSupportSize(dmB, p, &supportSizeB);CHKERRQ(ierr); 31774e3744c5SMatthew G. Knepley ierr = DMPlexGetSupport(dmB, p, &supportB);CHKERRQ(ierr); 31784e3744c5SMatthew G. Knepley if (supportSize != supportSizeB) PetscFunctionReturn(0); 31794e3744c5SMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 31804e3744c5SMatthew G. Knepley if (support[s] != supportB[s]) PetscFunctionReturn(0); 31814e3744c5SMatthew G. Knepley } 31824e3744c5SMatthew G. Knepley } 31834e3744c5SMatthew G. Knepley *equal = PETSC_TRUE; 31844e3744c5SMatthew G. Knepley PetscFunctionReturn(0); 31854e3744c5SMatthew G. Knepley } 31864e3744c5SMatthew G. Knepley 31877cd05799SMatthew G. Knepley /*@C 31887cd05799SMatthew G. Knepley DMPlexGetNumFaceVertices - Returns the number of vertices on a face 31897cd05799SMatthew G. Knepley 31907cd05799SMatthew G. Knepley Not Collective 31917cd05799SMatthew G. Knepley 31927cd05799SMatthew G. Knepley Input Parameters: 31937cd05799SMatthew G. Knepley + dm - The DMPlex 31947cd05799SMatthew G. Knepley . cellDim - The cell dimension 31957cd05799SMatthew G. Knepley - numCorners - The number of vertices on a cell 31967cd05799SMatthew G. Knepley 31977cd05799SMatthew G. Knepley Output Parameters: 31987cd05799SMatthew G. Knepley . numFaceVertices - The number of vertices on a face 31997cd05799SMatthew G. Knepley 32007cd05799SMatthew G. Knepley Level: developer 32017cd05799SMatthew G. Knepley 32027cd05799SMatthew G. Knepley Notes: 32037cd05799SMatthew G. Knepley Of course this can only work for a restricted set of symmetric shapes 32047cd05799SMatthew G. Knepley 32057cd05799SMatthew G. Knepley .seealso: DMPlexGetCone() 32067cd05799SMatthew G. Knepley @*/ 320718ad9376SMatthew G. Knepley PetscErrorCode DMPlexGetNumFaceVertices(DM dm, PetscInt cellDim, PetscInt numCorners, PetscInt *numFaceVertices) 3208a6dfd86eSKarl Rupp { 320982f516ccSBarry Smith MPI_Comm comm; 3210552f7358SJed Brown PetscErrorCode ierr; 3211552f7358SJed Brown 3212552f7358SJed Brown PetscFunctionBegin; 321382f516ccSBarry Smith ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 3214552f7358SJed Brown PetscValidPointer(numFaceVertices,3); 3215552f7358SJed Brown switch (cellDim) { 3216552f7358SJed Brown case 0: 3217552f7358SJed Brown *numFaceVertices = 0; 3218552f7358SJed Brown break; 3219552f7358SJed Brown case 1: 3220552f7358SJed Brown *numFaceVertices = 1; 3221552f7358SJed Brown break; 3222552f7358SJed Brown case 2: 3223552f7358SJed Brown switch (numCorners) { 322419436ca2SJed Brown case 3: /* triangle */ 322519436ca2SJed Brown *numFaceVertices = 2; /* Edge has 2 vertices */ 3226552f7358SJed Brown break; 322719436ca2SJed Brown case 4: /* quadrilateral */ 322819436ca2SJed Brown *numFaceVertices = 2; /* Edge has 2 vertices */ 3229552f7358SJed Brown break; 323019436ca2SJed Brown case 6: /* quadratic triangle, tri and quad cohesive Lagrange cells */ 323119436ca2SJed Brown *numFaceVertices = 3; /* Edge has 3 vertices */ 3232552f7358SJed Brown break; 323319436ca2SJed Brown case 9: /* quadratic quadrilateral, quadratic quad cohesive Lagrange cells */ 323419436ca2SJed Brown *numFaceVertices = 3; /* Edge has 3 vertices */ 3235552f7358SJed Brown break; 3236552f7358SJed Brown default: 3237f347f43bSBarry Smith SETERRQ2(comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid number of face corners %D for dimension %D", numCorners, cellDim); 3238552f7358SJed Brown } 3239552f7358SJed Brown break; 3240552f7358SJed Brown case 3: 3241552f7358SJed Brown switch (numCorners) { 324219436ca2SJed Brown case 4: /* tetradehdron */ 324319436ca2SJed Brown *numFaceVertices = 3; /* Face has 3 vertices */ 3244552f7358SJed Brown break; 324519436ca2SJed Brown case 6: /* tet cohesive cells */ 324619436ca2SJed Brown *numFaceVertices = 4; /* Face has 4 vertices */ 3247552f7358SJed Brown break; 324819436ca2SJed Brown case 8: /* hexahedron */ 324919436ca2SJed Brown *numFaceVertices = 4; /* Face has 4 vertices */ 3250552f7358SJed Brown break; 325119436ca2SJed Brown case 9: /* tet cohesive Lagrange cells */ 325219436ca2SJed Brown *numFaceVertices = 6; /* Face has 6 vertices */ 3253552f7358SJed Brown break; 325419436ca2SJed Brown case 10: /* quadratic tetrahedron */ 325519436ca2SJed Brown *numFaceVertices = 6; /* Face has 6 vertices */ 3256552f7358SJed Brown break; 325719436ca2SJed Brown case 12: /* hex cohesive Lagrange cells */ 325819436ca2SJed Brown *numFaceVertices = 6; /* Face has 6 vertices */ 3259552f7358SJed Brown break; 326019436ca2SJed Brown case 18: /* quadratic tet cohesive Lagrange cells */ 326119436ca2SJed Brown *numFaceVertices = 6; /* Face has 6 vertices */ 3262552f7358SJed Brown break; 326319436ca2SJed Brown case 27: /* quadratic hexahedron, quadratic hex cohesive Lagrange cells */ 326419436ca2SJed Brown *numFaceVertices = 9; /* Face has 9 vertices */ 3265552f7358SJed Brown break; 3266552f7358SJed Brown default: 3267f347f43bSBarry Smith SETERRQ2(comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid number of face corners %D for dimension %D", numCorners, cellDim); 3268552f7358SJed Brown } 3269552f7358SJed Brown break; 3270552f7358SJed Brown default: 3271f347f43bSBarry Smith SETERRQ1(comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid cell dimension %D", cellDim); 3272552f7358SJed Brown } 3273552f7358SJed Brown PetscFunctionReturn(0); 3274552f7358SJed Brown } 3275552f7358SJed Brown 3276552f7358SJed Brown /*@ 3277aa50250dSMatthew G. Knepley DMPlexGetDepthLabel - Get the DMLabel recording the depth of each point 3278552f7358SJed Brown 3279552f7358SJed Brown Not Collective 3280552f7358SJed Brown 3281aa50250dSMatthew G. Knepley Input Parameter: 3282552f7358SJed Brown . dm - The DMPlex object 3283552f7358SJed Brown 3284aa50250dSMatthew G. Knepley Output Parameter: 3285aa50250dSMatthew G. Knepley . depthLabel - The DMLabel recording point depth 3286552f7358SJed Brown 3287552f7358SJed Brown Level: developer 3288552f7358SJed Brown 3289aa50250dSMatthew G. Knepley .keywords: mesh, points 3290aa50250dSMatthew G. Knepley .seealso: DMPlexGetDepth(), DMPlexGetHeightStratum(), DMPlexGetDepthStratum() 3291aa50250dSMatthew G. Knepley @*/ 3292aa50250dSMatthew G. Knepley PetscErrorCode DMPlexGetDepthLabel(DM dm, DMLabel *depthLabel) 3293aa50250dSMatthew G. Knepley { 3294aa50250dSMatthew G. Knepley PetscErrorCode ierr; 3295aa50250dSMatthew G. Knepley 3296aa50250dSMatthew G. Knepley PetscFunctionBegin; 3297aa50250dSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3298aa50250dSMatthew G. Knepley PetscValidPointer(depthLabel, 2); 3299c58f1c22SToby Isaac if (!dm->depthLabel) {ierr = DMGetLabel(dm, "depth", &dm->depthLabel);CHKERRQ(ierr);} 3300c58f1c22SToby Isaac *depthLabel = dm->depthLabel; 3301aa50250dSMatthew G. Knepley PetscFunctionReturn(0); 3302aa50250dSMatthew G. Knepley } 3303aa50250dSMatthew G. Knepley 3304aa50250dSMatthew G. Knepley /*@ 3305aa50250dSMatthew G. Knepley DMPlexGetDepth - Get the depth of the DAG representing this mesh 3306aa50250dSMatthew G. Knepley 3307aa50250dSMatthew G. Knepley Not Collective 3308aa50250dSMatthew G. Knepley 3309aa50250dSMatthew G. Knepley Input Parameter: 3310aa50250dSMatthew G. Knepley . dm - The DMPlex object 3311aa50250dSMatthew G. Knepley 3312aa50250dSMatthew G. Knepley Output Parameter: 3313aa50250dSMatthew G. Knepley . depth - The number of strata (breadth first levels) in the DAG 3314aa50250dSMatthew G. Knepley 3315aa50250dSMatthew G. Knepley Level: developer 3316552f7358SJed Brown 3317552f7358SJed Brown .keywords: mesh, points 3318aa50250dSMatthew G. Knepley .seealso: DMPlexGetDepthLabel(), DMPlexGetHeightStratum(), DMPlexGetDepthStratum() 3319552f7358SJed Brown @*/ 3320552f7358SJed Brown PetscErrorCode DMPlexGetDepth(DM dm, PetscInt *depth) 3321552f7358SJed Brown { 3322aa50250dSMatthew G. Knepley DMLabel label; 3323aa50250dSMatthew G. Knepley PetscInt d = 0; 3324552f7358SJed Brown PetscErrorCode ierr; 3325552f7358SJed Brown 3326552f7358SJed Brown PetscFunctionBegin; 3327552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3328552f7358SJed Brown PetscValidPointer(depth, 2); 3329aa50250dSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 3330aa50250dSMatthew G. Knepley if (label) {ierr = DMLabelGetNumValues(label, &d);CHKERRQ(ierr);} 3331552f7358SJed Brown *depth = d-1; 3332552f7358SJed Brown PetscFunctionReturn(0); 3333552f7358SJed Brown } 3334552f7358SJed Brown 3335552f7358SJed Brown /*@ 3336552f7358SJed Brown DMPlexGetDepthStratum - Get the bounds [start, end) for all points at a certain depth. 3337552f7358SJed Brown 3338552f7358SJed Brown Not Collective 3339552f7358SJed Brown 3340552f7358SJed Brown Input Parameters: 3341552f7358SJed Brown + dm - The DMPlex object 3342552f7358SJed Brown - stratumValue - The requested depth 3343552f7358SJed Brown 3344552f7358SJed Brown Output Parameters: 3345552f7358SJed Brown + start - The first point at this depth 3346552f7358SJed Brown - end - One beyond the last point at this depth 3347552f7358SJed Brown 3348647867b2SJed Brown Notes: 3349647867b2SJed Brown Depth indexing is related to topological dimension. Depth stratum 0 contains the lowest topological dimension points, 3350647867b2SJed Brown often "vertices". If the mesh is "interpolated" (see DMPlexInterpolate()), then depth stratum 1 contains the next 3351647867b2SJed Brown higher dimension, e.g., "edges". 3352647867b2SJed Brown 3353552f7358SJed Brown Level: developer 3354552f7358SJed Brown 3355552f7358SJed Brown .keywords: mesh, points 3356552f7358SJed Brown .seealso: DMPlexGetHeightStratum(), DMPlexGetDepth() 3357552f7358SJed Brown @*/ 33580adebc6cSBarry Smith PetscErrorCode DMPlexGetDepthStratum(DM dm, PetscInt stratumValue, PetscInt *start, PetscInt *end) 33590adebc6cSBarry Smith { 3360aa50250dSMatthew G. Knepley DMLabel label; 336163d1a920SMatthew G. Knepley PetscInt pStart, pEnd; 3362552f7358SJed Brown PetscErrorCode ierr; 3363552f7358SJed Brown 3364552f7358SJed Brown PetscFunctionBegin; 3365552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 336663d1a920SMatthew G. Knepley if (start) {PetscValidPointer(start, 3); *start = 0;} 336763d1a920SMatthew G. Knepley if (end) {PetscValidPointer(end, 4); *end = 0;} 3368552f7358SJed Brown ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 33690d644c17SKarl Rupp if (pStart == pEnd) PetscFunctionReturn(0); 337063d1a920SMatthew G. Knepley if (stratumValue < 0) { 337163d1a920SMatthew G. Knepley if (start) *start = pStart; 337263d1a920SMatthew G. Knepley if (end) *end = pEnd; 337363d1a920SMatthew G. Knepley PetscFunctionReturn(0); 3374552f7358SJed Brown } 3375aa50250dSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 337663d1a920SMatthew G. Knepley if (!label) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "No label named depth was found"); 337763d1a920SMatthew G. Knepley ierr = DMLabelGetStratumBounds(label, stratumValue, start, end);CHKERRQ(ierr); 3378552f7358SJed Brown PetscFunctionReturn(0); 3379552f7358SJed Brown } 3380552f7358SJed Brown 3381552f7358SJed Brown /*@ 3382552f7358SJed Brown DMPlexGetHeightStratum - Get the bounds [start, end) for all points at a certain height. 3383552f7358SJed Brown 3384552f7358SJed Brown Not Collective 3385552f7358SJed Brown 3386552f7358SJed Brown Input Parameters: 3387552f7358SJed Brown + dm - The DMPlex object 3388552f7358SJed Brown - stratumValue - The requested height 3389552f7358SJed Brown 3390552f7358SJed Brown Output Parameters: 3391552f7358SJed Brown + start - The first point at this height 3392552f7358SJed Brown - end - One beyond the last point at this height 3393552f7358SJed Brown 3394647867b2SJed Brown Notes: 3395647867b2SJed Brown Height indexing is related to topological codimension. Height stratum 0 contains the highest topological dimension 3396647867b2SJed Brown points, often called "cells" or "elements". If the mesh is "interpolated" (see DMPlexInterpolate()), then height 3397647867b2SJed Brown stratum 1 contains the boundary of these "cells", often called "faces" or "facets". 3398647867b2SJed Brown 3399552f7358SJed Brown Level: developer 3400552f7358SJed Brown 3401552f7358SJed Brown .keywords: mesh, points 3402552f7358SJed Brown .seealso: DMPlexGetDepthStratum(), DMPlexGetDepth() 3403552f7358SJed Brown @*/ 34040adebc6cSBarry Smith PetscErrorCode DMPlexGetHeightStratum(DM dm, PetscInt stratumValue, PetscInt *start, PetscInt *end) 34050adebc6cSBarry Smith { 3406aa50250dSMatthew G. Knepley DMLabel label; 340763d1a920SMatthew G. Knepley PetscInt depth, pStart, pEnd; 3408552f7358SJed Brown PetscErrorCode ierr; 3409552f7358SJed Brown 3410552f7358SJed Brown PetscFunctionBegin; 3411552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 341263d1a920SMatthew G. Knepley if (start) {PetscValidPointer(start, 3); *start = 0;} 341363d1a920SMatthew G. Knepley if (end) {PetscValidPointer(end, 4); *end = 0;} 3414552f7358SJed Brown ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 34150d644c17SKarl Rupp if (pStart == pEnd) PetscFunctionReturn(0); 341663d1a920SMatthew G. Knepley if (stratumValue < 0) { 341763d1a920SMatthew G. Knepley if (start) *start = pStart; 341863d1a920SMatthew G. Knepley if (end) *end = pEnd; 341963d1a920SMatthew G. Knepley PetscFunctionReturn(0); 3420552f7358SJed Brown } 3421aa50250dSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 342213903a91SSatish Balay if (!label) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "No label named depth was found"); 342363d1a920SMatthew G. Knepley ierr = DMLabelGetNumValues(label, &depth);CHKERRQ(ierr); 342463d1a920SMatthew G. Knepley ierr = DMLabelGetStratumBounds(label, depth-1-stratumValue, start, end);CHKERRQ(ierr); 3425552f7358SJed Brown PetscFunctionReturn(0); 3426552f7358SJed Brown } 3427552f7358SJed Brown 34280adebc6cSBarry Smith PetscErrorCode DMCreateCoordinateDM_Plex(DM dm, DM *cdm) 34290adebc6cSBarry Smith { 3430efe440bfSMatthew G. Knepley PetscSection section, s; 3431efe440bfSMatthew G. Knepley Mat m; 34323e922f36SToby Isaac PetscInt maxHeight; 3433552f7358SJed Brown PetscErrorCode ierr; 3434552f7358SJed Brown 3435552f7358SJed Brown PetscFunctionBegin; 343638221697SMatthew G. Knepley ierr = DMClone(dm, cdm);CHKERRQ(ierr); 34373e922f36SToby Isaac ierr = DMPlexGetMaxProjectionHeight(dm, &maxHeight);CHKERRQ(ierr); 34383e922f36SToby Isaac ierr = DMPlexSetMaxProjectionHeight(*cdm, maxHeight);CHKERRQ(ierr); 343982f516ccSBarry Smith ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), §ion);CHKERRQ(ierr); 3440e87a4003SBarry Smith ierr = DMSetSection(*cdm, section);CHKERRQ(ierr); 34411d799100SJed Brown ierr = PetscSectionDestroy(§ion);CHKERRQ(ierr); 3442efe440bfSMatthew G. Knepley ierr = PetscSectionCreate(PETSC_COMM_SELF, &s);CHKERRQ(ierr); 3443efe440bfSMatthew G. Knepley ierr = MatCreate(PETSC_COMM_SELF, &m);CHKERRQ(ierr); 3444efe440bfSMatthew G. Knepley ierr = DMSetDefaultConstraints(*cdm, s, m);CHKERRQ(ierr); 3445efe440bfSMatthew G. Knepley ierr = PetscSectionDestroy(&s);CHKERRQ(ierr); 3446efe440bfSMatthew G. Knepley ierr = MatDestroy(&m);CHKERRQ(ierr); 34478f4c458bSMatthew G. Knepley 34488f4c458bSMatthew G. Knepley ierr = DMSetNumFields(*cdm, 1);CHKERRQ(ierr); 34498f4c458bSMatthew G. Knepley ierr = DMCreateDS(*cdm);CHKERRQ(ierr); 3450552f7358SJed Brown PetscFunctionReturn(0); 3451552f7358SJed Brown } 3452552f7358SJed Brown 3453f19dbd58SToby Isaac PetscErrorCode DMCreateCoordinateField_Plex(DM dm, DMField *field) 3454f19dbd58SToby Isaac { 3455f19dbd58SToby Isaac Vec coordsLocal; 3456f19dbd58SToby Isaac DM coordsDM; 3457f19dbd58SToby Isaac PetscErrorCode ierr; 3458f19dbd58SToby Isaac 3459f19dbd58SToby Isaac PetscFunctionBegin; 3460f19dbd58SToby Isaac *field = NULL; 3461f19dbd58SToby Isaac ierr = DMGetCoordinatesLocal(dm,&coordsLocal);CHKERRQ(ierr); 3462f19dbd58SToby Isaac ierr = DMGetCoordinateDM(dm,&coordsDM);CHKERRQ(ierr); 3463f19dbd58SToby Isaac if (coordsLocal && coordsDM) { 3464f19dbd58SToby Isaac ierr = DMFieldCreateDS(coordsDM, 0, coordsLocal, field);CHKERRQ(ierr); 3465f19dbd58SToby Isaac } 3466f19dbd58SToby Isaac PetscFunctionReturn(0); 3467f19dbd58SToby Isaac } 3468f19dbd58SToby Isaac 34697cd05799SMatthew G. Knepley /*@C 34707cd05799SMatthew G. Knepley DMPlexGetConeSection - Return a section which describes the layout of cone data 34717cd05799SMatthew G. Knepley 34727cd05799SMatthew G. Knepley Not Collective 34737cd05799SMatthew G. Knepley 34747cd05799SMatthew G. Knepley Input Parameters: 34757cd05799SMatthew G. Knepley . dm - The DMPlex object 34767cd05799SMatthew G. Knepley 34777cd05799SMatthew G. Knepley Output Parameter: 34787cd05799SMatthew G. Knepley . section - The PetscSection object 34797cd05799SMatthew G. Knepley 34807cd05799SMatthew G. Knepley Level: developer 34817cd05799SMatthew G. Knepley 34827cd05799SMatthew G. Knepley .seealso: DMPlexGetSupportSection(), DMPlexGetCones(), DMPlexGetConeOrientations() 34837cd05799SMatthew G. Knepley @*/ 34840adebc6cSBarry Smith PetscErrorCode DMPlexGetConeSection(DM dm, PetscSection *section) 34850adebc6cSBarry Smith { 3486552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3487552f7358SJed Brown 3488552f7358SJed Brown PetscFunctionBegin; 3489552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3490552f7358SJed Brown if (section) *section = mesh->coneSection; 3491552f7358SJed Brown PetscFunctionReturn(0); 3492552f7358SJed Brown } 3493552f7358SJed Brown 34947cd05799SMatthew G. Knepley /*@C 34957cd05799SMatthew G. Knepley DMPlexGetSupportSection - Return a section which describes the layout of support data 34967cd05799SMatthew G. Knepley 34977cd05799SMatthew G. Knepley Not Collective 34987cd05799SMatthew G. Knepley 34997cd05799SMatthew G. Knepley Input Parameters: 35007cd05799SMatthew G. Knepley . dm - The DMPlex object 35017cd05799SMatthew G. Knepley 35027cd05799SMatthew G. Knepley Output Parameter: 35037cd05799SMatthew G. Knepley . section - The PetscSection object 35047cd05799SMatthew G. Knepley 35057cd05799SMatthew G. Knepley Level: developer 35067cd05799SMatthew G. Knepley 35077cd05799SMatthew G. Knepley .seealso: DMPlexGetConeSection() 35087cd05799SMatthew G. Knepley @*/ 35098cb4d582SMatthew G. Knepley PetscErrorCode DMPlexGetSupportSection(DM dm, PetscSection *section) 35108cb4d582SMatthew G. Knepley { 35118cb4d582SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 35128cb4d582SMatthew G. Knepley 35138cb4d582SMatthew G. Knepley PetscFunctionBegin; 35148cb4d582SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 35158cb4d582SMatthew G. Knepley if (section) *section = mesh->supportSection; 35168cb4d582SMatthew G. Knepley PetscFunctionReturn(0); 35178cb4d582SMatthew G. Knepley } 35188cb4d582SMatthew G. Knepley 35197cd05799SMatthew G. Knepley /*@C 35207cd05799SMatthew G. Knepley DMPlexGetCones - Return cone data 35217cd05799SMatthew G. Knepley 35227cd05799SMatthew G. Knepley Not Collective 35237cd05799SMatthew G. Knepley 35247cd05799SMatthew G. Knepley Input Parameters: 35257cd05799SMatthew G. Knepley . dm - The DMPlex object 35267cd05799SMatthew G. Knepley 35277cd05799SMatthew G. Knepley Output Parameter: 35287cd05799SMatthew G. Knepley . cones - The cone for each point 35297cd05799SMatthew G. Knepley 35307cd05799SMatthew G. Knepley Level: developer 35317cd05799SMatthew G. Knepley 35327cd05799SMatthew G. Knepley .seealso: DMPlexGetConeSection() 35337cd05799SMatthew G. Knepley @*/ 3534a6dfd86eSKarl Rupp PetscErrorCode DMPlexGetCones(DM dm, PetscInt *cones[]) 3535a6dfd86eSKarl Rupp { 3536552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3537552f7358SJed Brown 3538552f7358SJed Brown PetscFunctionBegin; 3539552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3540552f7358SJed Brown if (cones) *cones = mesh->cones; 3541552f7358SJed Brown PetscFunctionReturn(0); 3542552f7358SJed Brown } 3543552f7358SJed Brown 35447cd05799SMatthew G. Knepley /*@C 35457cd05799SMatthew G. Knepley DMPlexGetConeOrientations - Return cone orientation data 35467cd05799SMatthew G. Knepley 35477cd05799SMatthew G. Knepley Not Collective 35487cd05799SMatthew G. Knepley 35497cd05799SMatthew G. Knepley Input Parameters: 35507cd05799SMatthew G. Knepley . dm - The DMPlex object 35517cd05799SMatthew G. Knepley 35527cd05799SMatthew G. Knepley Output Parameter: 35537cd05799SMatthew G. Knepley . coneOrientations - The cone orientation for each point 35547cd05799SMatthew G. Knepley 35557cd05799SMatthew G. Knepley Level: developer 35567cd05799SMatthew G. Knepley 35577cd05799SMatthew G. Knepley .seealso: DMPlexGetConeSection() 35587cd05799SMatthew G. Knepley @*/ 3559a6dfd86eSKarl Rupp PetscErrorCode DMPlexGetConeOrientations(DM dm, PetscInt *coneOrientations[]) 3560a6dfd86eSKarl Rupp { 3561552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3562552f7358SJed Brown 3563552f7358SJed Brown PetscFunctionBegin; 3564552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3565552f7358SJed Brown if (coneOrientations) *coneOrientations = mesh->coneOrientations; 3566552f7358SJed Brown PetscFunctionReturn(0); 3567552f7358SJed Brown } 3568552f7358SJed Brown 3569552f7358SJed Brown /******************************** FEM Support **********************************/ 3570552f7358SJed Brown 3571a4355906SMatthew Knepley /*@ 3572bc1eb3faSJed Brown 3573bc1eb3faSJed Brown DMPlexSetClosurePermutationTensor - Create a permutation from the default (BFS) point ordering in the closure, to a 3574bc1eb3faSJed Brown lexicographic ordering over the tensor product cell (i.e., line, quad, hex, etc.), and set this permutation in the 3575bc1eb3faSJed Brown section provided (or default section of the DM). 3576a4355906SMatthew Knepley 3577a4355906SMatthew Knepley Input Parameters: 3578a4355906SMatthew Knepley + dm - The DM 3579a4355906SMatthew Knepley . point - Either a cell (highest dim point) or an edge (dim 1 point), or PETSC_DETERMINE 3580a4355906SMatthew Knepley - section - The PetscSection to reorder, or NULL for the default section 3581a4355906SMatthew Knepley 3582a4355906SMatthew Knepley Note: The point is used to determine the number of dofs/field on an edge. For SEM, this is related to the polynomial 3583a4355906SMatthew Knepley degree of the basis. 3584a4355906SMatthew Knepley 3585bc1eb3faSJed Brown Example: 3586bc1eb3faSJed Brown A typical interpolated single-quad mesh might order points as 3587bc1eb3faSJed Brown .vb 3588bc1eb3faSJed Brown [c0, v1, v2, v3, v4, e5, e6, e7, e8] 3589bc1eb3faSJed Brown 3590bc1eb3faSJed Brown v4 -- e6 -- v3 3591bc1eb3faSJed Brown | | 3592bc1eb3faSJed Brown e7 c0 e8 3593bc1eb3faSJed Brown | | 3594bc1eb3faSJed Brown v1 -- e5 -- v2 3595bc1eb3faSJed Brown .ve 3596bc1eb3faSJed Brown 3597bc1eb3faSJed Brown (There is no significance to the ordering described here.) The default section for a Q3 quad might typically assign 3598bc1eb3faSJed Brown dofs in the order of points, e.g., 3599bc1eb3faSJed Brown .vb 3600bc1eb3faSJed Brown c0 -> [0,1,2,3] 3601bc1eb3faSJed Brown v1 -> [4] 3602bc1eb3faSJed Brown ... 3603bc1eb3faSJed Brown e5 -> [8, 9] 3604bc1eb3faSJed Brown .ve 3605bc1eb3faSJed Brown 3606bc1eb3faSJed Brown which corresponds to the dofs 3607bc1eb3faSJed Brown .vb 3608bc1eb3faSJed Brown 6 10 11 7 3609bc1eb3faSJed Brown 13 2 3 15 3610bc1eb3faSJed Brown 12 0 1 14 3611bc1eb3faSJed Brown 4 8 9 5 3612bc1eb3faSJed Brown .ve 3613bc1eb3faSJed Brown 3614bc1eb3faSJed Brown The closure in BFS ordering works through height strata (cells, edges, vertices) to produce the ordering 3615bc1eb3faSJed Brown .vb 3616bc1eb3faSJed Brown 0 1 2 3 8 9 14 15 11 10 13 12 4 5 7 6 3617bc1eb3faSJed Brown .ve 3618bc1eb3faSJed Brown 3619bc1eb3faSJed Brown After calling DMPlexSetClosurePermutationTensor(), the closure will be ordered lexicographically, 3620bc1eb3faSJed Brown .vb 3621bc1eb3faSJed Brown 4 8 9 5 12 0 1 14 13 2 3 15 6 10 11 7 3622bc1eb3faSJed Brown .ve 3623bc1eb3faSJed Brown 3624a4355906SMatthew Knepley Level: developer 3625a4355906SMatthew Knepley 3626a4355906SMatthew Knepley .seealso: DMGetSection(), PetscSectionSetClosurePermutation() 3627a4355906SMatthew Knepley @*/ 3628bc1eb3faSJed Brown PetscErrorCode DMPlexSetClosurePermutationTensor(DM dm, PetscInt point, PetscSection section) 36293194fc30SMatthew G. Knepley { 36307391a63aSMatthew G. Knepley DMLabel label; 36313194fc30SMatthew G. Knepley PetscInt *perm; 36327391a63aSMatthew G. Knepley PetscInt dim, depth, eStart, k, Nf, f, Nc, c, i, j, size = 0, offset = 0, foffset = 0; 36333194fc30SMatthew G. Knepley PetscErrorCode ierr; 36343194fc30SMatthew G. Knepley 36353194fc30SMatthew G. Knepley PetscFunctionBegin; 36367391a63aSMatthew G. Knepley if (point < 0) {ierr = DMPlexGetDepthStratum(dm, 1, &point, NULL);CHKERRQ(ierr);} 36373194fc30SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 36387391a63aSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 36397391a63aSMatthew G. Knepley ierr = DMLabelGetValue(label, point, &depth);CHKERRQ(ierr); 36407391a63aSMatthew G. Knepley if (depth == 1) {eStart = point;} 36417391a63aSMatthew G. Knepley else if (depth == dim) { 36427391a63aSMatthew G. Knepley const PetscInt *cone; 36437391a63aSMatthew G. Knepley 36447391a63aSMatthew G. Knepley ierr = DMPlexGetCone(dm, point, &cone);CHKERRQ(ierr); 3645d4e6627bSStefano Zampini if (dim == 2) eStart = cone[0]; 3646d4e6627bSStefano Zampini else if (dim == 3) { 3647d4e6627bSStefano Zampini const PetscInt *cone2; 3648d4e6627bSStefano Zampini ierr = DMPlexGetCone(dm, cone[0], &cone2);CHKERRQ(ierr); 3649d4e6627bSStefano Zampini eStart = cone2[0]; 3650d4e6627bSStefano Zampini } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Point %D of depth %D cannot be used to bootstrap spectral ordering for dim %D", point, depth, dim); 3651d4e6627bSStefano Zampini } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Point %D of depth %D cannot be used to bootstrap spectral ordering for dim %D", point, depth, dim); 3652e87a4003SBarry Smith if (!section) {ierr = DMGetSection(dm, §ion);CHKERRQ(ierr);} 36533194fc30SMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &Nf);CHKERRQ(ierr); 3654babf31e0SJed Brown if (dim < 1) PetscFunctionReturn(0); 36553194fc30SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 36563194fc30SMatthew G. Knepley /* An order k SEM disc has k-1 dofs on an edge */ 36573194fc30SMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, eStart, f, &k);CHKERRQ(ierr); 36583194fc30SMatthew G. Knepley ierr = PetscSectionGetFieldComponents(section, f, &Nc);CHKERRQ(ierr); 36593194fc30SMatthew G. Knepley k = k/Nc + 1; 366089eabcffSMatthew G. Knepley size += PetscPowInt(k+1, dim)*Nc; 36613194fc30SMatthew G. Knepley } 36623194fc30SMatthew G. Knepley ierr = PetscMalloc1(size, &perm);CHKERRQ(ierr); 36633194fc30SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 366489eabcffSMatthew G. Knepley switch (dim) { 3665babf31e0SJed Brown case 1: 3666babf31e0SJed Brown ierr = PetscSectionGetFieldDof(section, eStart, f, &k);CHKERRQ(ierr); 3667babf31e0SJed Brown ierr = PetscSectionGetFieldComponents(section, f, &Nc);CHKERRQ(ierr); 3668babf31e0SJed Brown k = k/Nc + 1; 3669babf31e0SJed Brown /* 3670babf31e0SJed Brown Original ordering is [ edge of length k-1; vtx0; vtx1 ] 3671babf31e0SJed Brown We want [ vtx0; edge of length k-1; vtx1 ] 3672babf31e0SJed Brown */ 3673babf31e0SJed Brown for (c=0; c<Nc; c++,offset++) perm[offset] = (k-1)*Nc + c + foffset; 3674babf31e0SJed Brown for (i=0; i<k-1; i++) for (c=0; c<Nc; c++,offset++) perm[offset] = i*Nc + c + foffset; 3675babf31e0SJed Brown for (c=0; c<Nc; c++,offset++) perm[offset] = k*Nc + c + foffset; 3676babf31e0SJed Brown foffset = offset; 3677babf31e0SJed Brown break; 367889eabcffSMatthew G. Knepley case 2: 36793194fc30SMatthew G. Knepley /* The original quad closure is oriented clockwise, {f, e_b, e_r, e_t, e_l, v_lb, v_rb, v_tr, v_tl} */ 36803194fc30SMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, eStart, f, &k);CHKERRQ(ierr); 36813194fc30SMatthew G. Knepley ierr = PetscSectionGetFieldComponents(section, f, &Nc);CHKERRQ(ierr); 36823194fc30SMatthew G. Knepley k = k/Nc + 1; 36833194fc30SMatthew G. Knepley /* The SEM order is 36843194fc30SMatthew G. Knepley 36853194fc30SMatthew G. Knepley v_lb, {e_b}, v_rb, 368689eabcffSMatthew G. Knepley e^{(k-1)-i}_l, {f^{i*(k-1)}}, e^i_r, 36873194fc30SMatthew G. Knepley v_lt, reverse {e_t}, v_rt 36883194fc30SMatthew G. Knepley */ 36893194fc30SMatthew G. Knepley { 36903194fc30SMatthew G. Knepley const PetscInt of = 0; 36913194fc30SMatthew G. Knepley const PetscInt oeb = of + PetscSqr(k-1); 36923194fc30SMatthew G. Knepley const PetscInt oer = oeb + (k-1); 36933194fc30SMatthew G. Knepley const PetscInt oet = oer + (k-1); 36943194fc30SMatthew G. Knepley const PetscInt oel = oet + (k-1); 36953194fc30SMatthew G. Knepley const PetscInt ovlb = oel + (k-1); 36963194fc30SMatthew G. Knepley const PetscInt ovrb = ovlb + 1; 36973194fc30SMatthew G. Knepley const PetscInt ovrt = ovrb + 1; 36983194fc30SMatthew G. Knepley const PetscInt ovlt = ovrt + 1; 36993194fc30SMatthew G. Knepley PetscInt o; 37003194fc30SMatthew G. Knepley 37013194fc30SMatthew G. Knepley /* bottom */ 37023194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovlb*Nc + c + foffset; 37033194fc30SMatthew G. Knepley for (o = oeb; o < oer; ++o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 37043194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovrb*Nc + c + foffset; 37053194fc30SMatthew G. Knepley /* middle */ 37063194fc30SMatthew G. Knepley for (i = 0; i < k-1; ++i) { 37073194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oel+(k-2)-i)*Nc + c + foffset; 37083194fc30SMatthew G. Knepley for (o = of+(k-1)*i; o < of+(k-1)*(i+1); ++o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 37093194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oer+i)*Nc + c + foffset; 37103194fc30SMatthew G. Knepley } 37113194fc30SMatthew G. Knepley /* top */ 37123194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovlt*Nc + c + foffset; 37133194fc30SMatthew G. Knepley for (o = oel-1; o >= oet; --o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 37143194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovrt*Nc + c + foffset; 37153194fc30SMatthew G. Knepley foffset = offset; 37163194fc30SMatthew G. Knepley } 371789eabcffSMatthew G. Knepley break; 371889eabcffSMatthew G. Knepley case 3: 371989eabcffSMatthew G. Knepley /* The original hex closure is 372089eabcffSMatthew G. Knepley 372189eabcffSMatthew G. Knepley {c, 372289eabcffSMatthew G. Knepley f_b, f_t, f_f, f_b, f_r, f_l, 372389eabcffSMatthew G. Knepley e_bl, e_bb, e_br, e_bf, e_tf, e_tr, e_tb, e_tl, e_rf, e_lf, e_lb, e_rb, 372489eabcffSMatthew G. Knepley v_blf, v_blb, v_brb, v_brf, v_tlf, v_trf, v_trb, v_tlb} 372589eabcffSMatthew G. Knepley */ 372689eabcffSMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, eStart, f, &k);CHKERRQ(ierr); 372789eabcffSMatthew G. Knepley ierr = PetscSectionGetFieldComponents(section, f, &Nc);CHKERRQ(ierr); 372889eabcffSMatthew G. Knepley k = k/Nc + 1; 372989eabcffSMatthew G. Knepley /* The SEM order is 373089eabcffSMatthew G. Knepley Bottom Slice 373189eabcffSMatthew G. Knepley v_blf, {e^{(k-1)-n}_bf}, v_brf, 373289eabcffSMatthew G. Knepley e^{i}_bl, f^{n*(k-1)+(k-1)-i}_b, e^{(k-1)-i}_br, 373389eabcffSMatthew G. Knepley v_blb, {e_bb}, v_brb, 373489eabcffSMatthew G. Knepley 373589eabcffSMatthew G. Knepley Middle Slice (j) 373689eabcffSMatthew G. Knepley {e^{(k-1)-j}_lf}, {f^{j*(k-1)+n}_f}, e^j_rf, 373789eabcffSMatthew G. Knepley f^{i*(k-1)+j}_l, {c^{(j*(k-1) + i)*(k-1)+n}_t}, f^{j*(k-1)+i}_r, 373889eabcffSMatthew G. Knepley e^j_lb, {f^{j*(k-1)+(k-1)-n}_b}, e^{(k-1)-j}_rb, 373989eabcffSMatthew G. Knepley 374089eabcffSMatthew G. Knepley Top Slice 374189eabcffSMatthew G. Knepley v_tlf, {e_tf}, v_trf, 374289eabcffSMatthew G. Knepley e^{(k-1)-i}_tl, {f^{i*(k-1)}_t}, e^{i}_tr, 374389eabcffSMatthew G. Knepley v_tlb, {e^{(k-1)-n}_tb}, v_trb, 374489eabcffSMatthew G. Knepley */ 374589eabcffSMatthew G. Knepley { 374689eabcffSMatthew G. Knepley const PetscInt oc = 0; 374789eabcffSMatthew G. Knepley const PetscInt ofb = oc + PetscSqr(k-1)*(k-1); 374889eabcffSMatthew G. Knepley const PetscInt oft = ofb + PetscSqr(k-1); 374989eabcffSMatthew G. Knepley const PetscInt off = oft + PetscSqr(k-1); 375089eabcffSMatthew G. Knepley const PetscInt ofk = off + PetscSqr(k-1); 375189eabcffSMatthew G. Knepley const PetscInt ofr = ofk + PetscSqr(k-1); 375289eabcffSMatthew G. Knepley const PetscInt ofl = ofr + PetscSqr(k-1); 375389eabcffSMatthew G. Knepley const PetscInt oebl = ofl + PetscSqr(k-1); 375489eabcffSMatthew G. Knepley const PetscInt oebb = oebl + (k-1); 375589eabcffSMatthew G. Knepley const PetscInt oebr = oebb + (k-1); 375689eabcffSMatthew G. Knepley const PetscInt oebf = oebr + (k-1); 375789eabcffSMatthew G. Knepley const PetscInt oetf = oebf + (k-1); 375889eabcffSMatthew G. Knepley const PetscInt oetr = oetf + (k-1); 375989eabcffSMatthew G. Knepley const PetscInt oetb = oetr + (k-1); 376089eabcffSMatthew G. Knepley const PetscInt oetl = oetb + (k-1); 376189eabcffSMatthew G. Knepley const PetscInt oerf = oetl + (k-1); 376289eabcffSMatthew G. Knepley const PetscInt oelf = oerf + (k-1); 376389eabcffSMatthew G. Knepley const PetscInt oelb = oelf + (k-1); 376489eabcffSMatthew G. Knepley const PetscInt oerb = oelb + (k-1); 376589eabcffSMatthew G. Knepley const PetscInt ovblf = oerb + (k-1); 376689eabcffSMatthew G. Knepley const PetscInt ovblb = ovblf + 1; 376789eabcffSMatthew G. Knepley const PetscInt ovbrb = ovblb + 1; 376889eabcffSMatthew G. Knepley const PetscInt ovbrf = ovbrb + 1; 376989eabcffSMatthew G. Knepley const PetscInt ovtlf = ovbrf + 1; 377089eabcffSMatthew G. Knepley const PetscInt ovtrf = ovtlf + 1; 377189eabcffSMatthew G. Knepley const PetscInt ovtrb = ovtrf + 1; 377289eabcffSMatthew G. Knepley const PetscInt ovtlb = ovtrb + 1; 377389eabcffSMatthew G. Knepley PetscInt o, n; 377489eabcffSMatthew G. Knepley 377589eabcffSMatthew G. Knepley /* Bottom Slice */ 377689eabcffSMatthew G. Knepley /* bottom */ 377789eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovblf*Nc + c + foffset; 377889eabcffSMatthew G. Knepley for (o = oetf-1; o >= oebf; --o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 377989eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovbrf*Nc + c + foffset; 378089eabcffSMatthew G. Knepley /* middle */ 378189eabcffSMatthew G. Knepley for (i = 0; i < k-1; ++i) { 378289eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oebl+i)*Nc + c + foffset; 3783316b7f87SMax Rietmann for (n = 0; n < k-1; ++n) {o = ofb+n*(k-1)+i; for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset;} 378489eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oebr+(k-2)-i)*Nc + c + foffset; 37853194fc30SMatthew G. Knepley } 378689eabcffSMatthew G. Knepley /* top */ 378789eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovblb*Nc + c + foffset; 378889eabcffSMatthew G. Knepley for (o = oebb; o < oebr; ++o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 378989eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovbrb*Nc + c + foffset; 379089eabcffSMatthew G. Knepley 379189eabcffSMatthew G. Knepley /* Middle Slice */ 379289eabcffSMatthew G. Knepley for (j = 0; j < k-1; ++j) { 379389eabcffSMatthew G. Knepley /* bottom */ 379489eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oelf+(k-2)-j)*Nc + c + foffset; 379589eabcffSMatthew G. Knepley for (o = off+j*(k-1); o < off+(j+1)*(k-1); ++o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 379689eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oerf+j)*Nc + c + foffset; 379789eabcffSMatthew G. Knepley /* middle */ 379889eabcffSMatthew G. Knepley for (i = 0; i < k-1; ++i) { 379989eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (ofl+i*(k-1)+j)*Nc + c + foffset; 380089eabcffSMatthew G. Knepley for (n = 0; n < k-1; ++n) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oc+(j*(k-1)+i)*(k-1)+n)*Nc + c + foffset; 380189eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (ofr+j*(k-1)+i)*Nc + c + foffset; 380289eabcffSMatthew G. Knepley } 380389eabcffSMatthew G. Knepley /* top */ 380489eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oelb+j)*Nc + c + foffset; 380589eabcffSMatthew G. Knepley for (o = ofk+j*(k-1)+(k-2); o >= ofk+j*(k-1); --o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 380689eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oerb+(k-2)-j)*Nc + c + foffset; 380789eabcffSMatthew G. Knepley } 380889eabcffSMatthew G. Knepley 380989eabcffSMatthew G. Knepley /* Top Slice */ 381089eabcffSMatthew G. Knepley /* bottom */ 381189eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovtlf*Nc + c + foffset; 381289eabcffSMatthew G. Knepley for (o = oetf; o < oetr; ++o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 381389eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovtrf*Nc + c + foffset; 381489eabcffSMatthew G. Knepley /* middle */ 381589eabcffSMatthew G. Knepley for (i = 0; i < k-1; ++i) { 381689eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oetl+(k-2)-i)*Nc + c + foffset; 381789eabcffSMatthew G. Knepley for (n = 0; n < k-1; ++n) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oft+i*(k-1)+n)*Nc + c + foffset; 381889eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oetr+i)*Nc + c + foffset; 381989eabcffSMatthew G. Knepley } 382089eabcffSMatthew G. Knepley /* top */ 382189eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovtlb*Nc + c + foffset; 382289eabcffSMatthew G. Knepley for (o = oetl-1; o >= oetb; --o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 382389eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovtrb*Nc + c + foffset; 382489eabcffSMatthew G. Knepley 382589eabcffSMatthew G. Knepley foffset = offset; 382689eabcffSMatthew G. Knepley } 382789eabcffSMatthew G. Knepley break; 382889eabcffSMatthew G. Knepley default: SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "No spectral ordering for dimension %D", dim); 382989eabcffSMatthew G. Knepley } 383089eabcffSMatthew G. Knepley } 383189eabcffSMatthew G. Knepley if (offset != size) SETERRQ2(PetscObjectComm((PetscObject) dm), PETSC_ERR_PLIB, "Number of permutation entries %D != %D", offset, size); 38323194fc30SMatthew G. Knepley /* Check permutation */ 38333194fc30SMatthew G. Knepley { 38343194fc30SMatthew G. Knepley PetscInt *check; 38353194fc30SMatthew G. Knepley 38363194fc30SMatthew G. Knepley ierr = PetscMalloc1(size, &check);CHKERRQ(ierr); 38373194fc30SMatthew G. Knepley for (i = 0; i < size; ++i) {check[i] = -1; if (perm[i] < 0 || perm[i] >= size) SETERRQ2(PetscObjectComm((PetscObject) dm), PETSC_ERR_PLIB, "Invalid permutation index p[%D] = %D", i, perm[i]);} 38383194fc30SMatthew G. Knepley for (i = 0; i < size; ++i) check[perm[i]] = i; 38393194fc30SMatthew G. Knepley for (i = 0; i < size; ++i) {if (check[i] < 0) SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_PLIB, "Missing permutation index %D", i);} 38403194fc30SMatthew G. Knepley ierr = PetscFree(check);CHKERRQ(ierr); 38413194fc30SMatthew G. Knepley } 38421fdd32a2SMatthew G. Knepley ierr = PetscSectionSetClosurePermutation_Internal(section, (PetscObject) dm, size, PETSC_OWN_POINTER, perm);CHKERRQ(ierr); 38433194fc30SMatthew G. Knepley PetscFunctionReturn(0); 38443194fc30SMatthew G. Knepley } 38453194fc30SMatthew G. Knepley 3846e071409bSToby Isaac PetscErrorCode DMPlexGetPointDualSpaceFEM(DM dm, PetscInt point, PetscInt field, PetscDualSpace *dspace) 3847e071409bSToby Isaac { 3848e071409bSToby Isaac PetscDS prob; 3849e071409bSToby Isaac PetscInt depth, Nf, h; 3850e071409bSToby Isaac DMLabel label; 3851e071409bSToby Isaac PetscErrorCode ierr; 3852e071409bSToby Isaac 3853e071409bSToby Isaac PetscFunctionBeginHot; 3854e5e52638SMatthew G. Knepley ierr = DMGetDS(dm, &prob);CHKERRQ(ierr); 3855e071409bSToby Isaac Nf = prob->Nf; 3856e071409bSToby Isaac label = dm->depthLabel; 3857e071409bSToby Isaac *dspace = NULL; 3858e071409bSToby Isaac if (field < Nf) { 3859e071409bSToby Isaac PetscObject disc = prob->disc[field]; 3860e071409bSToby Isaac 3861e071409bSToby Isaac if (disc->classid == PETSCFE_CLASSID) { 3862e071409bSToby Isaac PetscDualSpace dsp; 3863e071409bSToby Isaac 3864e071409bSToby Isaac ierr = PetscFEGetDualSpace((PetscFE)disc,&dsp);CHKERRQ(ierr); 3865e071409bSToby Isaac ierr = DMLabelGetNumValues(label,&depth);CHKERRQ(ierr); 3866e071409bSToby Isaac ierr = DMLabelGetValue(label,point,&h);CHKERRQ(ierr); 3867e071409bSToby Isaac h = depth - 1 - h; 3868e071409bSToby Isaac if (h) { 3869e071409bSToby Isaac ierr = PetscDualSpaceGetHeightSubspace(dsp,h,dspace);CHKERRQ(ierr); 3870e071409bSToby Isaac } else { 3871e071409bSToby Isaac *dspace = dsp; 3872e071409bSToby Isaac } 3873e071409bSToby Isaac } 3874e071409bSToby Isaac } 3875e071409bSToby Isaac PetscFunctionReturn(0); 3876e071409bSToby Isaac } 3877e071409bSToby Isaac 3878e071409bSToby Isaac 38791a271a75SMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode DMPlexVecGetClosure_Depth1_Static(DM dm, PetscSection section, Vec v, PetscInt point, PetscInt *csize, PetscScalar *values[]) 3880a6dfd86eSKarl Rupp { 3881552f7358SJed Brown PetscScalar *array, *vArray; 3882d9917b9dSMatthew G. Knepley const PetscInt *cone, *coneO; 38831a271a75SMatthew G. Knepley PetscInt pStart, pEnd, p, numPoints, size = 0, offset = 0; 3884552f7358SJed Brown PetscErrorCode ierr; 3885552f7358SJed Brown 38861b406b76SMatthew G. Knepley PetscFunctionBeginHot; 38872a3aaacfSMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 38885a1bb5cfSMatthew G. Knepley ierr = DMPlexGetConeSize(dm, point, &numPoints);CHKERRQ(ierr); 38895a1bb5cfSMatthew G. Knepley ierr = DMPlexGetCone(dm, point, &cone);CHKERRQ(ierr); 38905a1bb5cfSMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, point, &coneO);CHKERRQ(ierr); 38913f7cbbe7SMatthew G. Knepley if (!values || !*values) { 38929df71ca4SMatthew G. Knepley if ((point >= pStart) && (point < pEnd)) { 38939df71ca4SMatthew G. Knepley PetscInt dof; 3894d9917b9dSMatthew G. Knepley 38959df71ca4SMatthew G. Knepley ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 38969df71ca4SMatthew G. Knepley size += dof; 38979df71ca4SMatthew G. Knepley } 38989df71ca4SMatthew G. Knepley for (p = 0; p < numPoints; ++p) { 38999df71ca4SMatthew G. Knepley const PetscInt cp = cone[p]; 39002a3aaacfSMatthew G. Knepley PetscInt dof; 39015a1bb5cfSMatthew G. Knepley 39025a1bb5cfSMatthew G. Knepley if ((cp < pStart) || (cp >= pEnd)) continue; 39032a3aaacfSMatthew G. Knepley ierr = PetscSectionGetDof(section, cp, &dof);CHKERRQ(ierr); 39045a1bb5cfSMatthew G. Knepley size += dof; 39055a1bb5cfSMatthew G. Knepley } 39063f7cbbe7SMatthew G. Knepley if (!values) { 39073f7cbbe7SMatthew G. Knepley if (csize) *csize = size; 39083f7cbbe7SMatthew G. Knepley PetscFunctionReturn(0); 39093f7cbbe7SMatthew G. Knepley } 391069291d52SBarry Smith ierr = DMGetWorkArray(dm, size, MPIU_SCALAR, &array);CHKERRQ(ierr); 3911982e9ed1SMatthew G. Knepley } else { 3912982e9ed1SMatthew G. Knepley array = *values; 3913982e9ed1SMatthew G. Knepley } 39149df71ca4SMatthew G. Knepley size = 0; 39155a1bb5cfSMatthew G. Knepley ierr = VecGetArray(v, &vArray);CHKERRQ(ierr); 39169df71ca4SMatthew G. Knepley if ((point >= pStart) && (point < pEnd)) { 39179df71ca4SMatthew G. Knepley PetscInt dof, off, d; 39189df71ca4SMatthew G. Knepley PetscScalar *varr; 3919d9917b9dSMatthew G. Knepley 39209df71ca4SMatthew G. Knepley ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 39219df71ca4SMatthew G. Knepley ierr = PetscSectionGetOffset(section, point, &off);CHKERRQ(ierr); 39229df71ca4SMatthew G. Knepley varr = &vArray[off]; 39231a271a75SMatthew G. Knepley for (d = 0; d < dof; ++d, ++offset) { 39241a271a75SMatthew G. Knepley array[offset] = varr[d]; 39259df71ca4SMatthew G. Knepley } 39269df71ca4SMatthew G. Knepley size += dof; 39279df71ca4SMatthew G. Knepley } 39289df71ca4SMatthew G. Knepley for (p = 0; p < numPoints; ++p) { 39299df71ca4SMatthew G. Knepley const PetscInt cp = cone[p]; 39309df71ca4SMatthew G. Knepley PetscInt o = coneO[p]; 39315a1bb5cfSMatthew G. Knepley PetscInt dof, off, d; 39325a1bb5cfSMatthew G. Knepley PetscScalar *varr; 39335a1bb5cfSMatthew G. Knepley 393452ed52e8SMatthew G. Knepley if ((cp < pStart) || (cp >= pEnd)) continue; 39355a1bb5cfSMatthew G. Knepley ierr = PetscSectionGetDof(section, cp, &dof);CHKERRQ(ierr); 39365a1bb5cfSMatthew G. Knepley ierr = PetscSectionGetOffset(section, cp, &off);CHKERRQ(ierr); 39375a1bb5cfSMatthew G. Knepley varr = &vArray[off]; 39385a1bb5cfSMatthew G. Knepley if (o >= 0) { 39391a271a75SMatthew G. Knepley for (d = 0; d < dof; ++d, ++offset) { 39401a271a75SMatthew G. Knepley array[offset] = varr[d]; 39415a1bb5cfSMatthew G. Knepley } 39425a1bb5cfSMatthew G. Knepley } else { 39431a271a75SMatthew G. Knepley for (d = dof-1; d >= 0; --d, ++offset) { 39441a271a75SMatthew G. Knepley array[offset] = varr[d]; 39455a1bb5cfSMatthew G. Knepley } 39465a1bb5cfSMatthew G. Knepley } 39479df71ca4SMatthew G. Knepley size += dof; 39485a1bb5cfSMatthew G. Knepley } 39495a1bb5cfSMatthew G. Knepley ierr = VecRestoreArray(v, &vArray);CHKERRQ(ierr); 39509df71ca4SMatthew G. Knepley if (!*values) { 39515a1bb5cfSMatthew G. Knepley if (csize) *csize = size; 39525a1bb5cfSMatthew G. Knepley *values = array; 39539df71ca4SMatthew G. Knepley } else { 39548ccfff9cSToby Isaac if (size > *csize) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Size of input array %D < actual size %D", *csize, size); 39558c312ff3SMatthew G. Knepley *csize = size; 39569df71ca4SMatthew G. Knepley } 39575a1bb5cfSMatthew G. Knepley PetscFunctionReturn(0); 39585a1bb5cfSMatthew G. Knepley } 3959d9917b9dSMatthew G. Knepley 39601dc59d61SMatthew G. Knepley PetscErrorCode DMPlexGetCompressedClosure(DM dm, PetscSection section, PetscInt point, PetscInt *numPoints, PetscInt **points, PetscSection *clSec, IS *clPoints, const PetscInt **clp) 3961923c78e0SToby Isaac { 3962923c78e0SToby Isaac const PetscInt *cla; 3963923c78e0SToby Isaac PetscInt np, *pts = NULL; 3964923c78e0SToby Isaac PetscErrorCode ierr; 3965923c78e0SToby Isaac 3966923c78e0SToby Isaac PetscFunctionBeginHot; 3967923c78e0SToby Isaac ierr = PetscSectionGetClosureIndex(section, (PetscObject) dm, clSec, clPoints);CHKERRQ(ierr); 3968923c78e0SToby Isaac if (!*clPoints) { 3969923c78e0SToby Isaac PetscInt pStart, pEnd, p, q; 3970923c78e0SToby Isaac 3971923c78e0SToby Isaac ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 3972923c78e0SToby Isaac ierr = DMPlexGetTransitiveClosure(dm, point, PETSC_TRUE, &np, &pts);CHKERRQ(ierr); 3973923c78e0SToby Isaac /* Compress out points not in the section */ 3974923c78e0SToby Isaac for (p = 0, q = 0; p < np; p++) { 3975923c78e0SToby Isaac PetscInt r = pts[2*p]; 3976923c78e0SToby Isaac if ((r >= pStart) && (r < pEnd)) { 3977923c78e0SToby Isaac pts[q*2] = r; 3978923c78e0SToby Isaac pts[q*2+1] = pts[2*p+1]; 3979923c78e0SToby Isaac ++q; 3980923c78e0SToby Isaac } 3981923c78e0SToby Isaac } 3982923c78e0SToby Isaac np = q; 3983923c78e0SToby Isaac cla = NULL; 3984923c78e0SToby Isaac } else { 3985923c78e0SToby Isaac PetscInt dof, off; 3986923c78e0SToby Isaac 3987923c78e0SToby Isaac ierr = PetscSectionGetDof(*clSec, point, &dof);CHKERRQ(ierr); 3988923c78e0SToby Isaac ierr = PetscSectionGetOffset(*clSec, point, &off);CHKERRQ(ierr); 3989923c78e0SToby Isaac ierr = ISGetIndices(*clPoints, &cla);CHKERRQ(ierr); 3990923c78e0SToby Isaac np = dof/2; 3991923c78e0SToby Isaac pts = (PetscInt *) &cla[off]; 3992923c78e0SToby Isaac } 3993923c78e0SToby Isaac *numPoints = np; 3994923c78e0SToby Isaac *points = pts; 3995923c78e0SToby Isaac *clp = cla; 3996923c78e0SToby Isaac 3997923c78e0SToby Isaac PetscFunctionReturn(0); 3998923c78e0SToby Isaac } 3999923c78e0SToby Isaac 40001dc59d61SMatthew G. Knepley PetscErrorCode DMPlexRestoreCompressedClosure(DM dm, PetscSection section, PetscInt point, PetscInt *numPoints, PetscInt **points, PetscSection *clSec, IS *clPoints, const PetscInt **clp) 4001923c78e0SToby Isaac { 4002923c78e0SToby Isaac PetscErrorCode ierr; 4003923c78e0SToby Isaac 4004923c78e0SToby Isaac PetscFunctionBeginHot; 4005923c78e0SToby Isaac if (!*clPoints) { 4006923c78e0SToby Isaac ierr = DMPlexRestoreTransitiveClosure(dm, point, PETSC_TRUE, numPoints, points);CHKERRQ(ierr); 4007923c78e0SToby Isaac } else { 4008923c78e0SToby Isaac ierr = ISRestoreIndices(*clPoints, clp);CHKERRQ(ierr); 4009923c78e0SToby Isaac } 4010923c78e0SToby Isaac *numPoints = 0; 4011923c78e0SToby Isaac *points = NULL; 4012923c78e0SToby Isaac *clSec = NULL; 4013923c78e0SToby Isaac *clPoints = NULL; 4014923c78e0SToby Isaac *clp = NULL; 4015923c78e0SToby Isaac PetscFunctionReturn(0); 4016923c78e0SToby Isaac } 4017923c78e0SToby Isaac 401897e99dd9SToby Isaac PETSC_STATIC_INLINE PetscErrorCode DMPlexVecGetClosure_Static(DM dm, PetscSection section, PetscInt numPoints, const PetscInt points[], const PetscInt clperm[], const PetscScalar vArray[], PetscInt *size, PetscScalar array[]) 40191a271a75SMatthew G. Knepley { 40201a271a75SMatthew G. Knepley PetscInt offset = 0, p; 402197e99dd9SToby Isaac const PetscInt **perms = NULL; 402297e99dd9SToby Isaac const PetscScalar **flips = NULL; 40231a271a75SMatthew G. Knepley PetscErrorCode ierr; 40241a271a75SMatthew G. Knepley 40251a271a75SMatthew G. Knepley PetscFunctionBeginHot; 4026fe02ba77SJed Brown *size = 0; 402797e99dd9SToby Isaac ierr = PetscSectionGetPointSyms(section,numPoints,points,&perms,&flips);CHKERRQ(ierr); 402897e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 402997e99dd9SToby Isaac const PetscInt point = points[2*p]; 403097e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 403197e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 40321a271a75SMatthew G. Knepley PetscInt dof, off, d; 40331a271a75SMatthew G. Knepley const PetscScalar *varr; 40341a271a75SMatthew G. Knepley 40351a271a75SMatthew G. Knepley ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 40361a271a75SMatthew G. Knepley ierr = PetscSectionGetOffset(section, point, &off);CHKERRQ(ierr); 40371a271a75SMatthew G. Knepley varr = &vArray[off]; 403897e99dd9SToby Isaac if (clperm) { 403997e99dd9SToby Isaac if (perm) { 404097e99dd9SToby Isaac for (d = 0; d < dof; d++) array[clperm[offset + perm[d]]] = varr[d]; 40411a271a75SMatthew G. Knepley } else { 404297e99dd9SToby Isaac for (d = 0; d < dof; d++) array[clperm[offset + d ]] = varr[d]; 404397e99dd9SToby Isaac } 404497e99dd9SToby Isaac if (flip) { 404597e99dd9SToby Isaac for (d = 0; d < dof; d++) array[clperm[offset + d ]] *= flip[d]; 404697e99dd9SToby Isaac } 404797e99dd9SToby Isaac } else { 404897e99dd9SToby Isaac if (perm) { 404997e99dd9SToby Isaac for (d = 0; d < dof; d++) array[offset + perm[d]] = varr[d]; 405097e99dd9SToby Isaac } else { 405197e99dd9SToby Isaac for (d = 0; d < dof; d++) array[offset + d ] = varr[d]; 405297e99dd9SToby Isaac } 405397e99dd9SToby Isaac if (flip) { 405497e99dd9SToby Isaac for (d = 0; d < dof; d++) array[offset + d ] *= flip[d]; 40551a271a75SMatthew G. Knepley } 40561a271a75SMatthew G. Knepley } 405797e99dd9SToby Isaac offset += dof; 405897e99dd9SToby Isaac } 405997e99dd9SToby Isaac ierr = PetscSectionRestorePointSyms(section,numPoints,points,&perms,&flips);CHKERRQ(ierr); 40601a271a75SMatthew G. Knepley *size = offset; 40611a271a75SMatthew G. Knepley PetscFunctionReturn(0); 40621a271a75SMatthew G. Knepley } 40631a271a75SMatthew G. Knepley 406497e99dd9SToby Isaac PETSC_STATIC_INLINE PetscErrorCode DMPlexVecGetClosure_Fields_Static(DM dm, PetscSection section, PetscInt numPoints, const PetscInt points[], PetscInt numFields, const PetscInt clperm[], const PetscScalar vArray[], PetscInt *size, PetscScalar array[]) 40651a271a75SMatthew G. Knepley { 40661a271a75SMatthew G. Knepley PetscInt offset = 0, f; 40671a271a75SMatthew G. Knepley PetscErrorCode ierr; 40681a271a75SMatthew G. Knepley 40691a271a75SMatthew G. Knepley PetscFunctionBeginHot; 4070fe02ba77SJed Brown *size = 0; 40711a271a75SMatthew G. Knepley for (f = 0; f < numFields; ++f) { 407297e99dd9SToby Isaac PetscInt p; 407397e99dd9SToby Isaac const PetscInt **perms = NULL; 407497e99dd9SToby Isaac const PetscScalar **flips = NULL; 40751a271a75SMatthew G. Knepley 407697e99dd9SToby Isaac ierr = PetscSectionGetFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 407797e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 407897e99dd9SToby Isaac const PetscInt point = points[2*p]; 407997e99dd9SToby Isaac PetscInt fdof, foff, b; 40801a271a75SMatthew G. Knepley const PetscScalar *varr; 408197e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 408297e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 40831a271a75SMatthew G. Knepley 40841a271a75SMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 40851a271a75SMatthew G. Knepley ierr = PetscSectionGetFieldOffset(section, point, f, &foff);CHKERRQ(ierr); 40861a271a75SMatthew G. Knepley varr = &vArray[foff]; 408797e99dd9SToby Isaac if (clperm) { 408897e99dd9SToby Isaac if (perm) {for (b = 0; b < fdof; b++) {array[clperm[offset + perm[b]]] = varr[b];}} 408997e99dd9SToby Isaac else {for (b = 0; b < fdof; b++) {array[clperm[offset + b ]] = varr[b];}} 409097e99dd9SToby Isaac if (flip) {for (b = 0; b < fdof; b++) {array[clperm[offset + b ]] *= flip[b];}} 40911a271a75SMatthew G. Knepley } else { 409297e99dd9SToby Isaac if (perm) {for (b = 0; b < fdof; b++) {array[offset + perm[b]] = varr[b];}} 409397e99dd9SToby Isaac else {for (b = 0; b < fdof; b++) {array[offset + b ] = varr[b];}} 409497e99dd9SToby Isaac if (flip) {for (b = 0; b < fdof; b++) {array[offset + b ] *= flip[b];}} 40951a271a75SMatthew G. Knepley } 409697e99dd9SToby Isaac offset += fdof; 40971a271a75SMatthew G. Knepley } 409897e99dd9SToby Isaac ierr = PetscSectionRestoreFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 40991a271a75SMatthew G. Knepley } 41001a271a75SMatthew G. Knepley *size = offset; 41011a271a75SMatthew G. Knepley PetscFunctionReturn(0); 41021a271a75SMatthew G. Knepley } 41031a271a75SMatthew G. Knepley 4104552f7358SJed Brown /*@C 4105552f7358SJed Brown DMPlexVecGetClosure - Get an array of the values on the closure of 'point' 4106552f7358SJed Brown 4107552f7358SJed Brown Not collective 4108552f7358SJed Brown 4109552f7358SJed Brown Input Parameters: 4110552f7358SJed Brown + dm - The DM 4111552f7358SJed Brown . section - The section describing the layout in v, or NULL to use the default section 4112552f7358SJed Brown . v - The local vector 411322c1ee49SMatthew G. Knepley . point - The point in the DM 411422c1ee49SMatthew G. Knepley . csize - The size of the input values array, or NULL 411522c1ee49SMatthew G. Knepley - values - An array to use for the values, or NULL to have it allocated automatically 4116552f7358SJed Brown 4117552f7358SJed Brown Output Parameters: 411822c1ee49SMatthew G. Knepley + csize - The number of values in the closure 411922c1ee49SMatthew G. Knepley - values - The array of values. If the user provided NULL, it is a borrowed array and should not be freed 412022c1ee49SMatthew G. Knepley 412122c1ee49SMatthew G. Knepley $ Note that DMPlexVecGetClosure/DMPlexVecRestoreClosure only allocates the values array if it set to NULL in the 412222c1ee49SMatthew G. Knepley $ calling function. This is because DMPlexVecGetClosure() is typically called in the inner loop of a Vec or Mat 412322c1ee49SMatthew G. Knepley $ assembly function, and a user may already have allocated storage for this operation. 412422c1ee49SMatthew G. Knepley $ 412522c1ee49SMatthew G. Knepley $ A typical use could be 412622c1ee49SMatthew G. Knepley $ 412722c1ee49SMatthew G. Knepley $ values = NULL; 412822c1ee49SMatthew G. Knepley $ ierr = DMPlexVecGetClosure(dm, NULL, v, p, &clSize, &values);CHKERRQ(ierr); 412922c1ee49SMatthew G. Knepley $ for (cl = 0; cl < clSize; ++cl) { 413022c1ee49SMatthew G. Knepley $ <Compute on closure> 413122c1ee49SMatthew G. Knepley $ } 413222c1ee49SMatthew G. Knepley $ ierr = DMPlexVecRestoreClosure(dm, NULL, v, p, &clSize, &values);CHKERRQ(ierr); 413322c1ee49SMatthew G. Knepley $ 413422c1ee49SMatthew G. Knepley $ or 413522c1ee49SMatthew G. Knepley $ 413622c1ee49SMatthew G. Knepley $ PetscMalloc1(clMaxSize, &values); 413722c1ee49SMatthew G. Knepley $ for (p = pStart; p < pEnd; ++p) { 413822c1ee49SMatthew G. Knepley $ clSize = clMaxSize; 413922c1ee49SMatthew G. Knepley $ ierr = DMPlexVecGetClosure(dm, NULL, v, p, &clSize, &values);CHKERRQ(ierr); 414022c1ee49SMatthew G. Knepley $ for (cl = 0; cl < clSize; ++cl) { 414122c1ee49SMatthew G. Knepley $ <Compute on closure> 414222c1ee49SMatthew G. Knepley $ } 414322c1ee49SMatthew G. Knepley $ } 414422c1ee49SMatthew G. Knepley $ PetscFree(values); 4145552f7358SJed Brown 4146552f7358SJed Brown Fortran Notes: 4147552f7358SJed Brown Since it returns an array, this routine is only available in Fortran 90, and you must 4148552f7358SJed Brown include petsc.h90 in your code. 4149552f7358SJed Brown 4150552f7358SJed Brown The csize argument is not present in the Fortran 90 binding since it is internal to the array. 4151552f7358SJed Brown 4152552f7358SJed Brown Level: intermediate 4153552f7358SJed Brown 4154552f7358SJed Brown .seealso DMPlexVecRestoreClosure(), DMPlexVecSetClosure(), DMPlexMatSetClosure() 4155552f7358SJed Brown @*/ 4156552f7358SJed Brown PetscErrorCode DMPlexVecGetClosure(DM dm, PetscSection section, Vec v, PetscInt point, PetscInt *csize, PetscScalar *values[]) 4157552f7358SJed Brown { 4158552f7358SJed Brown PetscSection clSection; 4159d9917b9dSMatthew G. Knepley IS clPoints; 41608a84db2dSMatthew G. Knepley PetscScalar *array; 41618a84db2dSMatthew G. Knepley const PetscScalar *vArray; 4162552f7358SJed Brown PetscInt *points = NULL; 41638f3be42fSMatthew G. Knepley const PetscInt *clp, *perm; 41641a271a75SMatthew G. Knepley PetscInt depth, numFields, numPoints, size; 4165552f7358SJed Brown PetscErrorCode ierr; 4166552f7358SJed Brown 4167d9917b9dSMatthew G. Knepley PetscFunctionBeginHot; 4168552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4169e87a4003SBarry Smith if (!section) {ierr = DMGetSection(dm, §ion);CHKERRQ(ierr);} 41701a271a75SMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 41711a271a75SMatthew G. Knepley PetscValidHeaderSpecific(v, VEC_CLASSID, 3); 4172552f7358SJed Brown ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 4173552f7358SJed Brown ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 4174552f7358SJed Brown if (depth == 1 && numFields < 2) { 41751a271a75SMatthew G. Knepley ierr = DMPlexVecGetClosure_Depth1_Static(dm, section, v, point, csize, values);CHKERRQ(ierr); 4176552f7358SJed Brown PetscFunctionReturn(0); 4177552f7358SJed Brown } 41781a271a75SMatthew G. Knepley /* Get points */ 4179923c78e0SToby Isaac ierr = DMPlexGetCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 41801fdd32a2SMatthew G. Knepley ierr = PetscSectionGetClosureInversePermutation_Internal(section, (PetscObject) dm, NULL, &perm);CHKERRQ(ierr); 41811a271a75SMatthew G. Knepley /* Get array */ 4182bd6c0d32SMatthew G. Knepley if (!values || !*values) { 41831a271a75SMatthew G. Knepley PetscInt asize = 0, dof, p; 4184552f7358SJed Brown 41851a271a75SMatthew G. Knepley for (p = 0; p < numPoints*2; p += 2) { 4186552f7358SJed Brown ierr = PetscSectionGetDof(section, points[p], &dof);CHKERRQ(ierr); 41871a271a75SMatthew G. Knepley asize += dof; 4188552f7358SJed Brown } 4189bd6c0d32SMatthew G. Knepley if (!values) { 4190923c78e0SToby Isaac ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 41911a271a75SMatthew G. Knepley if (csize) *csize = asize; 4192bd6c0d32SMatthew G. Knepley PetscFunctionReturn(0); 4193bd6c0d32SMatthew G. Knepley } 419469291d52SBarry Smith ierr = DMGetWorkArray(dm, asize, MPIU_SCALAR, &array);CHKERRQ(ierr); 4195d0f6b257SMatthew G. Knepley } else { 4196d0f6b257SMatthew G. Knepley array = *values; 4197d0f6b257SMatthew G. Knepley } 41988a84db2dSMatthew G. Knepley ierr = VecGetArrayRead(v, &vArray);CHKERRQ(ierr); 41991a271a75SMatthew G. Knepley /* Get values */ 420097e99dd9SToby Isaac if (numFields > 0) {ierr = DMPlexVecGetClosure_Fields_Static(dm, section, numPoints, points, numFields, perm, vArray, &size, array);CHKERRQ(ierr);} 420197e99dd9SToby Isaac else {ierr = DMPlexVecGetClosure_Static(dm, section, numPoints, points, perm, vArray, &size, array);CHKERRQ(ierr);} 42021a271a75SMatthew G. Knepley /* Cleanup points */ 4203923c78e0SToby Isaac ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 42041a271a75SMatthew G. Knepley /* Cleanup array */ 42058a84db2dSMatthew G. Knepley ierr = VecRestoreArrayRead(v, &vArray);CHKERRQ(ierr); 4206d0f6b257SMatthew G. Knepley if (!*values) { 4207552f7358SJed Brown if (csize) *csize = size; 4208552f7358SJed Brown *values = array; 4209d0f6b257SMatthew G. Knepley } else { 4210f347f43bSBarry Smith if (size > *csize) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Size of input array %D < actual size %D", *csize, size); 4211d0f6b257SMatthew G. Knepley *csize = size; 4212d0f6b257SMatthew G. Knepley } 4213552f7358SJed Brown PetscFunctionReturn(0); 4214552f7358SJed Brown } 4215552f7358SJed Brown 4216552f7358SJed Brown /*@C 4217552f7358SJed Brown DMPlexVecRestoreClosure - Restore the array of the values on the closure of 'point' 4218552f7358SJed Brown 4219552f7358SJed Brown Not collective 4220552f7358SJed Brown 4221552f7358SJed Brown Input Parameters: 4222552f7358SJed Brown + dm - The DM 42230298fd71SBarry Smith . section - The section describing the layout in v, or NULL to use the default section 4224552f7358SJed Brown . v - The local vector 4225eaf898f9SPatrick Sanan . point - The point in the DM 42260298fd71SBarry Smith . csize - The number of values in the closure, or NULL 4227552f7358SJed Brown - values - The array of values, which is a borrowed array and should not be freed 4228552f7358SJed Brown 422922c1ee49SMatthew G. Knepley Note that the array values are discarded and not copied back into v. In order to copy values back to v, use DMPlexVecSetClosure() 423022c1ee49SMatthew G. Knepley 42313813dfbdSMatthew G Knepley Fortran Notes: 42323813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 42333813dfbdSMatthew G Knepley include petsc.h90 in your code. 42343813dfbdSMatthew G Knepley 42353813dfbdSMatthew G Knepley The csize argument is not present in the Fortran 90 binding since it is internal to the array. 42363813dfbdSMatthew G Knepley 4237552f7358SJed Brown Level: intermediate 4238552f7358SJed Brown 4239552f7358SJed Brown .seealso DMPlexVecGetClosure(), DMPlexVecSetClosure(), DMPlexMatSetClosure() 4240552f7358SJed Brown @*/ 42417c1f9639SMatthew G Knepley PetscErrorCode DMPlexVecRestoreClosure(DM dm, PetscSection section, Vec v, PetscInt point, PetscInt *csize, PetscScalar *values[]) 4242a6dfd86eSKarl Rupp { 4243552f7358SJed Brown PetscInt size = 0; 4244552f7358SJed Brown PetscErrorCode ierr; 4245552f7358SJed Brown 4246552f7358SJed Brown PetscFunctionBegin; 4247552f7358SJed Brown /* Should work without recalculating size */ 424869291d52SBarry Smith ierr = DMRestoreWorkArray(dm, size, MPIU_SCALAR, (void*) values);CHKERRQ(ierr); 4249c9fdaa05SMatthew G. Knepley *values = NULL; 4250552f7358SJed Brown PetscFunctionReturn(0); 4251552f7358SJed Brown } 4252552f7358SJed Brown 4253552f7358SJed Brown PETSC_STATIC_INLINE void add (PetscScalar *x, PetscScalar y) {*x += y;} 4254552f7358SJed Brown PETSC_STATIC_INLINE void insert(PetscScalar *x, PetscScalar y) {*x = y;} 4255552f7358SJed Brown 425697e99dd9SToby Isaac PETSC_STATIC_INLINE PetscErrorCode updatePoint_private(PetscSection section, PetscInt point, PetscInt dof, void (*fuse)(PetscScalar*, PetscScalar), PetscBool setBC, const PetscInt perm[], const PetscScalar flip[], const PetscInt clperm[], const PetscScalar values[], PetscInt offset, PetscScalar array[]) 4257552f7358SJed Brown { 4258552f7358SJed Brown PetscInt cdof; /* The number of constraints on this point */ 4259552f7358SJed Brown const PetscInt *cdofs; /* The indices of the constrained dofs on this point */ 4260552f7358SJed Brown PetscScalar *a; 4261552f7358SJed Brown PetscInt off, cind = 0, k; 4262552f7358SJed Brown PetscErrorCode ierr; 4263552f7358SJed Brown 4264552f7358SJed Brown PetscFunctionBegin; 4265552f7358SJed Brown ierr = PetscSectionGetConstraintDof(section, point, &cdof);CHKERRQ(ierr); 4266552f7358SJed Brown ierr = PetscSectionGetOffset(section, point, &off);CHKERRQ(ierr); 4267552f7358SJed Brown a = &array[off]; 4268552f7358SJed Brown if (!cdof || setBC) { 426997e99dd9SToby Isaac if (clperm) { 427097e99dd9SToby Isaac if (perm) {for (k = 0; k < dof; ++k) {fuse(&a[k], values[clperm[offset+perm[k]]] * (flip ? flip[perm[k]] : 1.));}} 427197e99dd9SToby Isaac else {for (k = 0; k < dof; ++k) {fuse(&a[k], values[clperm[offset+ k ]] * (flip ? flip[ k ] : 1.));}} 4272552f7358SJed Brown } else { 427397e99dd9SToby Isaac if (perm) {for (k = 0; k < dof; ++k) {fuse(&a[k], values[offset+perm[k]] * (flip ? flip[perm[k]] : 1.));}} 427497e99dd9SToby Isaac else {for (k = 0; k < dof; ++k) {fuse(&a[k], values[offset+ k ] * (flip ? flip[ k ] : 1.));}} 4275552f7358SJed Brown } 4276552f7358SJed Brown } else { 4277552f7358SJed Brown ierr = PetscSectionGetConstraintIndices(section, point, &cdofs);CHKERRQ(ierr); 427897e99dd9SToby Isaac if (clperm) { 427997e99dd9SToby Isaac if (perm) {for (k = 0; k < dof; ++k) { 4280552f7358SJed Brown if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 428197e99dd9SToby Isaac fuse(&a[k], values[clperm[offset+perm[k]]] * (flip ? flip[perm[k]] : 1.)); 4282552f7358SJed Brown } 4283552f7358SJed Brown } else { 4284552f7358SJed Brown for (k = 0; k < dof; ++k) { 4285552f7358SJed Brown if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 428697e99dd9SToby Isaac fuse(&a[k], values[clperm[offset+ k ]] * (flip ? flip[ k ] : 1.)); 428797e99dd9SToby Isaac } 428897e99dd9SToby Isaac } 428997e99dd9SToby Isaac } else { 429097e99dd9SToby Isaac if (perm) { 429197e99dd9SToby Isaac for (k = 0; k < dof; ++k) { 429297e99dd9SToby Isaac if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 429397e99dd9SToby Isaac fuse(&a[k], values[offset+perm[k]] * (flip ? flip[perm[k]] : 1.)); 429497e99dd9SToby Isaac } 429597e99dd9SToby Isaac } else { 429697e99dd9SToby Isaac for (k = 0; k < dof; ++k) { 429797e99dd9SToby Isaac if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 429897e99dd9SToby Isaac fuse(&a[k], values[offset+ k ] * (flip ? flip[ k ] : 1.)); 429997e99dd9SToby Isaac } 4300552f7358SJed Brown } 4301552f7358SJed Brown } 4302552f7358SJed Brown } 4303552f7358SJed Brown PetscFunctionReturn(0); 4304552f7358SJed Brown } 4305552f7358SJed Brown 430697e99dd9SToby Isaac PETSC_STATIC_INLINE PetscErrorCode updatePointBC_private(PetscSection section, PetscInt point, PetscInt dof, void (*fuse)(PetscScalar*, PetscScalar), const PetscInt perm[], const PetscScalar flip[], const PetscInt clperm[], const PetscScalar values[], PetscInt offset, PetscScalar array[]) 4307a5e93ea8SMatthew G. Knepley { 4308a5e93ea8SMatthew G. Knepley PetscInt cdof; /* The number of constraints on this point */ 4309a5e93ea8SMatthew G. Knepley const PetscInt *cdofs; /* The indices of the constrained dofs on this point */ 4310a5e93ea8SMatthew G. Knepley PetscScalar *a; 4311a5e93ea8SMatthew G. Knepley PetscInt off, cind = 0, k; 4312a5e93ea8SMatthew G. Knepley PetscErrorCode ierr; 4313a5e93ea8SMatthew G. Knepley 4314a5e93ea8SMatthew G. Knepley PetscFunctionBegin; 4315a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(section, point, &cdof);CHKERRQ(ierr); 4316a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetOffset(section, point, &off);CHKERRQ(ierr); 4317a5e93ea8SMatthew G. Knepley a = &array[off]; 4318a5e93ea8SMatthew G. Knepley if (cdof) { 4319a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetConstraintIndices(section, point, &cdofs);CHKERRQ(ierr); 432097e99dd9SToby Isaac if (clperm) { 432197e99dd9SToby Isaac if (perm) { 4322a5e93ea8SMatthew G. Knepley for (k = 0; k < dof; ++k) { 4323a5e93ea8SMatthew G. Knepley if ((cind < cdof) && (k == cdofs[cind])) { 432497e99dd9SToby Isaac fuse(&a[k], values[clperm[offset+perm[k]]] * (flip ? flip[perm[k]] : 1.)); 432597e99dd9SToby Isaac cind++; 4326a5e93ea8SMatthew G. Knepley } 4327a5e93ea8SMatthew G. Knepley } 4328a5e93ea8SMatthew G. Knepley } else { 4329a5e93ea8SMatthew G. Knepley for (k = 0; k < dof; ++k) { 4330a5e93ea8SMatthew G. Knepley if ((cind < cdof) && (k == cdofs[cind])) { 433197e99dd9SToby Isaac fuse(&a[k], values[clperm[offset+ k ]] * (flip ? flip[ k ] : 1.)); 433297e99dd9SToby Isaac cind++; 433397e99dd9SToby Isaac } 433497e99dd9SToby Isaac } 433597e99dd9SToby Isaac } 433697e99dd9SToby Isaac } else { 433797e99dd9SToby Isaac if (perm) { 433897e99dd9SToby Isaac for (k = 0; k < dof; ++k) { 433997e99dd9SToby Isaac if ((cind < cdof) && (k == cdofs[cind])) { 434097e99dd9SToby Isaac fuse(&a[k], values[offset+perm[k]] * (flip ? flip[perm[k]] : 1.)); 434197e99dd9SToby Isaac cind++; 434297e99dd9SToby Isaac } 434397e99dd9SToby Isaac } 434497e99dd9SToby Isaac } else { 434597e99dd9SToby Isaac for (k = 0; k < dof; ++k) { 434697e99dd9SToby Isaac if ((cind < cdof) && (k == cdofs[cind])) { 434797e99dd9SToby Isaac fuse(&a[k], values[offset+ k ] * (flip ? flip[ k ] : 1.)); 434897e99dd9SToby Isaac cind++; 434997e99dd9SToby Isaac } 4350a5e93ea8SMatthew G. Knepley } 4351a5e93ea8SMatthew G. Knepley } 4352a5e93ea8SMatthew G. Knepley } 4353a5e93ea8SMatthew G. Knepley } 4354a5e93ea8SMatthew G. Knepley PetscFunctionReturn(0); 4355a5e93ea8SMatthew G. Knepley } 4356a5e93ea8SMatthew G. Knepley 435797e99dd9SToby Isaac PETSC_STATIC_INLINE PetscErrorCode updatePointFields_private(PetscSection section, PetscInt point, const PetscInt *perm, const PetscScalar *flip, PetscInt f, void (*fuse)(PetscScalar*, PetscScalar), PetscBool setBC, const PetscInt clperm[], const PetscScalar values[], PetscInt *offset, PetscScalar array[]) 4358a6dfd86eSKarl Rupp { 4359552f7358SJed Brown PetscScalar *a; 43601a271a75SMatthew G. Knepley PetscInt fdof, foff, fcdof, foffset = *offset; 43611a271a75SMatthew G. Knepley const PetscInt *fcdofs; /* The indices of the constrained dofs for field f on this point */ 436297e99dd9SToby Isaac PetscInt cind = 0, b; 4363552f7358SJed Brown PetscErrorCode ierr; 4364552f7358SJed Brown 4365552f7358SJed Brown PetscFunctionBegin; 4366552f7358SJed Brown ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 4367552f7358SJed Brown ierr = PetscSectionGetFieldConstraintDof(section, point, f, &fcdof);CHKERRQ(ierr); 43681a271a75SMatthew G. Knepley ierr = PetscSectionGetFieldOffset(section, point, f, &foff);CHKERRQ(ierr); 43691a271a75SMatthew G. Knepley a = &array[foff]; 4370552f7358SJed Brown if (!fcdof || setBC) { 437197e99dd9SToby Isaac if (clperm) { 437297e99dd9SToby Isaac if (perm) {for (b = 0; b < fdof; b++) {fuse(&a[b], values[clperm[foffset+perm[b]]] * (flip ? flip[perm[b]] : 1.));}} 437397e99dd9SToby Isaac else {for (b = 0; b < fdof; b++) {fuse(&a[b], values[clperm[foffset+ b ]] * (flip ? flip[ b ] : 1.));}} 4374552f7358SJed Brown } else { 437597e99dd9SToby Isaac if (perm) {for (b = 0; b < fdof; b++) {fuse(&a[b], values[foffset+perm[b]] * (flip ? flip[perm[b]] : 1.));}} 437697e99dd9SToby Isaac else {for (b = 0; b < fdof; b++) {fuse(&a[b], values[foffset+ b ] * (flip ? flip[ b ] : 1.));}} 4377552f7358SJed Brown } 4378552f7358SJed Brown } else { 4379552f7358SJed Brown ierr = PetscSectionGetFieldConstraintIndices(section, point, f, &fcdofs);CHKERRQ(ierr); 438097e99dd9SToby Isaac if (clperm) { 438197e99dd9SToby Isaac if (perm) { 438297e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 438397e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; continue;} 438497e99dd9SToby Isaac fuse(&a[b], values[clperm[foffset+perm[b]]] * (flip ? flip[perm[b]] : 1.)); 4385552f7358SJed Brown } 4386552f7358SJed Brown } else { 438797e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 438897e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; continue;} 438997e99dd9SToby Isaac fuse(&a[b], values[clperm[foffset+ b ]] * (flip ? flip[ b ] : 1.)); 439097e99dd9SToby Isaac } 439197e99dd9SToby Isaac } 439297e99dd9SToby Isaac } else { 439397e99dd9SToby Isaac if (perm) { 439497e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 439597e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; continue;} 439697e99dd9SToby Isaac fuse(&a[b], values[foffset+perm[b]] * (flip ? flip[perm[b]] : 1.)); 439797e99dd9SToby Isaac } 439897e99dd9SToby Isaac } else { 439997e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 440097e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; continue;} 440197e99dd9SToby Isaac fuse(&a[b], values[foffset+ b ] * (flip ? flip[ b ] : 1.)); 4402552f7358SJed Brown } 4403552f7358SJed Brown } 4404552f7358SJed Brown } 4405552f7358SJed Brown } 44061a271a75SMatthew G. Knepley *offset += fdof; 4407552f7358SJed Brown PetscFunctionReturn(0); 4408552f7358SJed Brown } 4409552f7358SJed Brown 4410ba322698SMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode updatePointFieldsBC_private(PetscSection section, PetscInt point, const PetscInt perm[], const PetscScalar flip[], PetscInt f, PetscInt Ncc, const PetscInt comps[], void (*fuse)(PetscScalar*, PetscScalar), const PetscInt clperm[], const PetscScalar values[], PetscInt *offset, PetscScalar array[]) 4411a5e93ea8SMatthew G. Knepley { 4412a5e93ea8SMatthew G. Knepley PetscScalar *a; 44131a271a75SMatthew G. Knepley PetscInt fdof, foff, fcdof, foffset = *offset; 44141a271a75SMatthew G. Knepley const PetscInt *fcdofs; /* The indices of the constrained dofs for field f on this point */ 4415ba322698SMatthew G. Knepley PetscInt cind = 0, ncind = 0, b; 4416ba322698SMatthew G. Knepley PetscBool ncSet, fcSet; 4417a5e93ea8SMatthew G. Knepley PetscErrorCode ierr; 4418a5e93ea8SMatthew G. Knepley 4419a5e93ea8SMatthew G. Knepley PetscFunctionBegin; 4420a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 4421a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetFieldConstraintDof(section, point, f, &fcdof);CHKERRQ(ierr); 44221a271a75SMatthew G. Knepley ierr = PetscSectionGetFieldOffset(section, point, f, &foff);CHKERRQ(ierr); 44231a271a75SMatthew G. Knepley a = &array[foff]; 4424a5e93ea8SMatthew G. Knepley if (fcdof) { 4425ba322698SMatthew G. Knepley /* We just override fcdof and fcdofs with Ncc and comps */ 4426a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetFieldConstraintIndices(section, point, f, &fcdofs);CHKERRQ(ierr); 442797e99dd9SToby Isaac if (clperm) { 442897e99dd9SToby Isaac if (perm) { 4429ba322698SMatthew G. Knepley if (comps) { 4430ba322698SMatthew G. Knepley for (b = 0; b < fdof; b++) { 4431ba322698SMatthew G. Knepley ncSet = fcSet = PETSC_FALSE; 4432ba322698SMatthew G. Knepley if ((ncind < Ncc) && (b == comps[ncind])) {++ncind; ncSet = PETSC_TRUE;} 4433ba322698SMatthew G. Knepley if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; fcSet = PETSC_TRUE;} 4434ba322698SMatthew G. Knepley if (ncSet && fcSet) {fuse(&a[b], values[clperm[foffset+perm[b]]] * (flip ? flip[perm[b]] : 1.));} 4435ba322698SMatthew G. Knepley } 4436ba322698SMatthew G. Knepley } else { 443797e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 443897e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) { 443997e99dd9SToby Isaac fuse(&a[b], values[clperm[foffset+perm[b]]] * (flip ? flip[perm[b]] : 1.)); 4440a5e93ea8SMatthew G. Knepley ++cind; 4441a5e93ea8SMatthew G. Knepley } 4442a5e93ea8SMatthew G. Knepley } 4443ba322698SMatthew G. Knepley } 4444ba322698SMatthew G. Knepley } else { 4445ba322698SMatthew G. Knepley if (comps) { 4446ba322698SMatthew G. Knepley for (b = 0; b < fdof; b++) { 4447ba322698SMatthew G. Knepley ncSet = fcSet = PETSC_FALSE; 4448ba322698SMatthew G. Knepley if ((ncind < Ncc) && (b == comps[ncind])) {++ncind; ncSet = PETSC_TRUE;} 4449ba322698SMatthew G. Knepley if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; fcSet = PETSC_TRUE;} 4450ba322698SMatthew G. Knepley if (ncSet && fcSet) {fuse(&a[b], values[clperm[foffset+ b ]] * (flip ? flip[ b ] : 1.));} 4451ba322698SMatthew G. Knepley } 4452a5e93ea8SMatthew G. Knepley } else { 445397e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 445497e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) { 445597e99dd9SToby Isaac fuse(&a[b], values[clperm[foffset+ b ]] * (flip ? flip[ b ] : 1.)); 445697e99dd9SToby Isaac ++cind; 445797e99dd9SToby Isaac } 445897e99dd9SToby Isaac } 445997e99dd9SToby Isaac } 4460ba322698SMatthew G. Knepley } 446197e99dd9SToby Isaac } else { 446297e99dd9SToby Isaac if (perm) { 4463ba322698SMatthew G. Knepley if (comps) { 4464ba322698SMatthew G. Knepley for (b = 0; b < fdof; b++) { 4465ba322698SMatthew G. Knepley ncSet = fcSet = PETSC_FALSE; 4466ba322698SMatthew G. Knepley if ((ncind < Ncc) && (b == comps[ncind])) {++ncind; ncSet = PETSC_TRUE;} 4467ba322698SMatthew G. Knepley if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; fcSet = PETSC_TRUE;} 4468ba322698SMatthew G. Knepley if (ncSet && fcSet) {fuse(&a[b], values[foffset+perm[b]] * (flip ? flip[perm[b]] : 1.));} 4469ba322698SMatthew G. Knepley } 4470ba322698SMatthew G. Knepley } else { 447197e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 447297e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) { 447397e99dd9SToby Isaac fuse(&a[b], values[foffset+perm[b]] * (flip ? flip[perm[b]] : 1.)); 447497e99dd9SToby Isaac ++cind; 447597e99dd9SToby Isaac } 447697e99dd9SToby Isaac } 4477ba322698SMatthew G. Knepley } 4478ba322698SMatthew G. Knepley } else { 4479ba322698SMatthew G. Knepley if (comps) { 4480ba322698SMatthew G. Knepley for (b = 0; b < fdof; b++) { 4481ba322698SMatthew G. Knepley ncSet = fcSet = PETSC_FALSE; 4482ba322698SMatthew G. Knepley if ((ncind < Ncc) && (b == comps[ncind])) {++ncind; ncSet = PETSC_TRUE;} 4483ba322698SMatthew G. Knepley if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; fcSet = PETSC_TRUE;} 4484ba322698SMatthew G. Knepley if (ncSet && fcSet) {fuse(&a[b], values[foffset+ b ] * (flip ? flip[ b ] : 1.));} 4485ba322698SMatthew G. Knepley } 448697e99dd9SToby Isaac } else { 448797e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 448897e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) { 448997e99dd9SToby Isaac fuse(&a[b], values[foffset+ b ] * (flip ? flip[ b ] : 1.)); 4490a5e93ea8SMatthew G. Knepley ++cind; 4491a5e93ea8SMatthew G. Knepley } 4492a5e93ea8SMatthew G. Knepley } 4493a5e93ea8SMatthew G. Knepley } 4494a5e93ea8SMatthew G. Knepley } 4495a5e93ea8SMatthew G. Knepley } 4496ba322698SMatthew G. Knepley } 44971a271a75SMatthew G. Knepley *offset += fdof; 4498a5e93ea8SMatthew G. Knepley PetscFunctionReturn(0); 4499a5e93ea8SMatthew G. Knepley } 4500a5e93ea8SMatthew G. Knepley 45018f3be42fSMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode DMPlexVecSetClosure_Depth1_Static(DM dm, PetscSection section, Vec v, PetscInt point, const PetscScalar values[], InsertMode mode) 4502a6dfd86eSKarl Rupp { 4503552f7358SJed Brown PetscScalar *array; 45041b406b76SMatthew G. Knepley const PetscInt *cone, *coneO; 45051b406b76SMatthew G. Knepley PetscInt pStart, pEnd, p, numPoints, off, dof; 4506552f7358SJed Brown PetscErrorCode ierr; 4507552f7358SJed Brown 45081b406b76SMatthew G. Knepley PetscFunctionBeginHot; 4509b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 4510b6ebb6e6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, point, &numPoints);CHKERRQ(ierr); 4511b6ebb6e6SMatthew G. Knepley ierr = DMPlexGetCone(dm, point, &cone);CHKERRQ(ierr); 4512b6ebb6e6SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, point, &coneO);CHKERRQ(ierr); 4513b6ebb6e6SMatthew G. Knepley ierr = VecGetArray(v, &array);CHKERRQ(ierr); 4514b6ebb6e6SMatthew G. Knepley for (p = 0, off = 0; p <= numPoints; ++p, off += dof) { 4515b6ebb6e6SMatthew G. Knepley const PetscInt cp = !p ? point : cone[p-1]; 4516b6ebb6e6SMatthew G. Knepley const PetscInt o = !p ? 0 : coneO[p-1]; 4517b6ebb6e6SMatthew G. Knepley 4518b6ebb6e6SMatthew G. Knepley if ((cp < pStart) || (cp >= pEnd)) {dof = 0; continue;} 4519b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetDof(section, cp, &dof);CHKERRQ(ierr); 4520b6ebb6e6SMatthew G. Knepley /* ADD_VALUES */ 4521b6ebb6e6SMatthew G. Knepley { 4522b6ebb6e6SMatthew G. Knepley const PetscInt *cdofs; /* The indices of the constrained dofs on this point */ 4523b6ebb6e6SMatthew G. Knepley PetscScalar *a; 4524b6ebb6e6SMatthew G. Knepley PetscInt cdof, coff, cind = 0, k; 4525b6ebb6e6SMatthew G. Knepley 4526b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(section, cp, &cdof);CHKERRQ(ierr); 4527b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetOffset(section, cp, &coff);CHKERRQ(ierr); 4528b6ebb6e6SMatthew G. Knepley a = &array[coff]; 4529b6ebb6e6SMatthew G. Knepley if (!cdof) { 4530b6ebb6e6SMatthew G. Knepley if (o >= 0) { 4531b6ebb6e6SMatthew G. Knepley for (k = 0; k < dof; ++k) { 4532b6ebb6e6SMatthew G. Knepley a[k] += values[off+k]; 4533b6ebb6e6SMatthew G. Knepley } 4534b6ebb6e6SMatthew G. Knepley } else { 4535b6ebb6e6SMatthew G. Knepley for (k = 0; k < dof; ++k) { 4536b6ebb6e6SMatthew G. Knepley a[k] += values[off+dof-k-1]; 4537b6ebb6e6SMatthew G. Knepley } 4538b6ebb6e6SMatthew G. Knepley } 4539b6ebb6e6SMatthew G. Knepley } else { 4540b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetConstraintIndices(section, cp, &cdofs);CHKERRQ(ierr); 4541b6ebb6e6SMatthew G. Knepley if (o >= 0) { 4542b6ebb6e6SMatthew G. Knepley for (k = 0; k < dof; ++k) { 4543b6ebb6e6SMatthew G. Knepley if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 4544b6ebb6e6SMatthew G. Knepley a[k] += values[off+k]; 4545b6ebb6e6SMatthew G. Knepley } 4546b6ebb6e6SMatthew G. Knepley } else { 4547b6ebb6e6SMatthew G. Knepley for (k = 0; k < dof; ++k) { 4548b6ebb6e6SMatthew G. Knepley if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 4549b6ebb6e6SMatthew G. Knepley a[k] += values[off+dof-k-1]; 4550b6ebb6e6SMatthew G. Knepley } 4551b6ebb6e6SMatthew G. Knepley } 4552b6ebb6e6SMatthew G. Knepley } 4553b6ebb6e6SMatthew G. Knepley } 4554b6ebb6e6SMatthew G. Knepley } 4555b6ebb6e6SMatthew G. Knepley ierr = VecRestoreArray(v, &array);CHKERRQ(ierr); 4556b6ebb6e6SMatthew G. Knepley PetscFunctionReturn(0); 4557b6ebb6e6SMatthew G. Knepley } 45581b406b76SMatthew G. Knepley 45591b406b76SMatthew G. Knepley /*@C 45601b406b76SMatthew G. Knepley DMPlexVecSetClosure - Set an array of the values on the closure of 'point' 45611b406b76SMatthew G. Knepley 45621b406b76SMatthew G. Knepley Not collective 45631b406b76SMatthew G. Knepley 45641b406b76SMatthew G. Knepley Input Parameters: 45651b406b76SMatthew G. Knepley + dm - The DM 45661b406b76SMatthew G. Knepley . section - The section describing the layout in v, or NULL to use the default section 45671b406b76SMatthew G. Knepley . v - The local vector 4568eaf898f9SPatrick Sanan . point - The point in the DM 45691b406b76SMatthew G. Knepley . values - The array of values 457022c1ee49SMatthew G. Knepley - mode - The insert mode. One of INSERT_ALL_VALUES, ADD_ALL_VALUES, INSERT_VALUES, ADD_VALUES, INSERT_BC_VALUES, and ADD_BC_VALUES, 457122c1ee49SMatthew G. Knepley where INSERT_ALL_VALUES and ADD_ALL_VALUES also overwrite boundary conditions. 45721b406b76SMatthew G. Knepley 45731b406b76SMatthew G. Knepley Fortran Notes: 45741b406b76SMatthew G. Knepley This routine is only available in Fortran 90, and you must include petsc.h90 in your code. 45751b406b76SMatthew G. Knepley 45761b406b76SMatthew G. Knepley Level: intermediate 45771b406b76SMatthew G. Knepley 45781b406b76SMatthew G. Knepley .seealso DMPlexVecGetClosure(), DMPlexMatSetClosure() 45791b406b76SMatthew G. Knepley @*/ 45801b406b76SMatthew G. Knepley PetscErrorCode DMPlexVecSetClosure(DM dm, PetscSection section, Vec v, PetscInt point, const PetscScalar values[], InsertMode mode) 45811b406b76SMatthew G. Knepley { 45821b406b76SMatthew G. Knepley PetscSection clSection; 45831b406b76SMatthew G. Knepley IS clPoints; 45841b406b76SMatthew G. Knepley PetscScalar *array; 45851b406b76SMatthew G. Knepley PetscInt *points = NULL; 458697e99dd9SToby Isaac const PetscInt *clp, *clperm; 45871a271a75SMatthew G. Knepley PetscInt depth, numFields, numPoints, p; 45881b406b76SMatthew G. Knepley PetscErrorCode ierr; 45891b406b76SMatthew G. Knepley 45901a271a75SMatthew G. Knepley PetscFunctionBeginHot; 45911b406b76SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4592e87a4003SBarry Smith if (!section) {ierr = DMGetSection(dm, §ion);CHKERRQ(ierr);} 45931a271a75SMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 45941a271a75SMatthew G. Knepley PetscValidHeaderSpecific(v, VEC_CLASSID, 3); 45951b406b76SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 45961b406b76SMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 45971b406b76SMatthew G. Knepley if (depth == 1 && numFields < 2 && mode == ADD_VALUES) { 45988f3be42fSMatthew G. Knepley ierr = DMPlexVecSetClosure_Depth1_Static(dm, section, v, point, values, mode);CHKERRQ(ierr); 45991b406b76SMatthew G. Knepley PetscFunctionReturn(0); 46001b406b76SMatthew G. Knepley } 46011a271a75SMatthew G. Knepley /* Get points */ 460297e99dd9SToby Isaac ierr = PetscSectionGetClosureInversePermutation_Internal(section, (PetscObject) dm, NULL, &clperm);CHKERRQ(ierr); 4603923c78e0SToby Isaac ierr = DMPlexGetCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 46041a271a75SMatthew G. Knepley /* Get array */ 4605552f7358SJed Brown ierr = VecGetArray(v, &array);CHKERRQ(ierr); 46061a271a75SMatthew G. Knepley /* Get values */ 4607ef90cfe2SMatthew G. Knepley if (numFields > 0) { 460897e99dd9SToby Isaac PetscInt offset = 0, f; 4609552f7358SJed Brown for (f = 0; f < numFields; ++f) { 461097e99dd9SToby Isaac const PetscInt **perms = NULL; 461197e99dd9SToby Isaac const PetscScalar **flips = NULL; 461297e99dd9SToby Isaac 461397e99dd9SToby Isaac ierr = PetscSectionGetFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 4614552f7358SJed Brown switch (mode) { 4615552f7358SJed Brown case INSERT_VALUES: 461697e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 461797e99dd9SToby Isaac const PetscInt point = points[2*p]; 461897e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 461997e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 462097e99dd9SToby Isaac updatePointFields_private(section, point, perm, flip, f, insert, PETSC_FALSE, clperm, values, &offset, array); 4621552f7358SJed Brown } break; 4622552f7358SJed Brown case INSERT_ALL_VALUES: 462397e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 462497e99dd9SToby Isaac const PetscInt point = points[2*p]; 462597e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 462697e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 462797e99dd9SToby Isaac updatePointFields_private(section, point, perm, flip, f, insert, PETSC_TRUE, clperm, values, &offset, array); 4628552f7358SJed Brown } break; 4629a5e93ea8SMatthew G. Knepley case INSERT_BC_VALUES: 463097e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 463197e99dd9SToby Isaac const PetscInt point = points[2*p]; 463297e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 463397e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 4634ba322698SMatthew G. Knepley updatePointFieldsBC_private(section, point, perm, flip, f, -1, NULL, insert, clperm, values, &offset, array); 4635a5e93ea8SMatthew G. Knepley } break; 4636552f7358SJed Brown case ADD_VALUES: 463797e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 463897e99dd9SToby Isaac const PetscInt point = points[2*p]; 463997e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 464097e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 464197e99dd9SToby Isaac updatePointFields_private(section, point, perm, flip, f, add, PETSC_FALSE, clperm, values, &offset, array); 4642552f7358SJed Brown } break; 4643552f7358SJed Brown case ADD_ALL_VALUES: 464497e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 464597e99dd9SToby Isaac const PetscInt point = points[2*p]; 464697e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 464797e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 464897e99dd9SToby Isaac updatePointFields_private(section, point, perm, flip, f, add, PETSC_TRUE, clperm, values, &offset, array); 4649552f7358SJed Brown } break; 4650304ab55fSMatthew G. Knepley case ADD_BC_VALUES: 465197e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 465297e99dd9SToby Isaac const PetscInt point = points[2*p]; 465397e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 465497e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 4655ba322698SMatthew G. Knepley updatePointFieldsBC_private(section, point, perm, flip, f, -1, NULL, add, clperm, values, &offset, array); 4656304ab55fSMatthew G. Knepley } break; 4657552f7358SJed Brown default: 4658f347f43bSBarry Smith SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insert mode %d", mode); 4659552f7358SJed Brown } 466097e99dd9SToby Isaac ierr = PetscSectionRestoreFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 46611a271a75SMatthew G. Knepley } 4662552f7358SJed Brown } else { 46631a271a75SMatthew G. Knepley PetscInt dof, off; 466497e99dd9SToby Isaac const PetscInt **perms = NULL; 466597e99dd9SToby Isaac const PetscScalar **flips = NULL; 46661a271a75SMatthew G. Knepley 466797e99dd9SToby Isaac ierr = PetscSectionGetPointSyms(section,numPoints,points,&perms,&flips);CHKERRQ(ierr); 4668552f7358SJed Brown switch (mode) { 4669552f7358SJed Brown case INSERT_VALUES: 467097e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 467197e99dd9SToby Isaac const PetscInt point = points[2*p]; 467297e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 467397e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 467497e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 467597e99dd9SToby Isaac updatePoint_private(section, point, dof, insert, PETSC_FALSE, perm, flip, clperm, values, off, array); 4676552f7358SJed Brown } break; 4677552f7358SJed Brown case INSERT_ALL_VALUES: 467897e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 467997e99dd9SToby Isaac const PetscInt point = points[2*p]; 468097e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 468197e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 468297e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 468397e99dd9SToby Isaac updatePoint_private(section, point, dof, insert, PETSC_TRUE, perm, flip, clperm, values, off, array); 4684552f7358SJed Brown } break; 4685a5e93ea8SMatthew G. Knepley case INSERT_BC_VALUES: 468697e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 468797e99dd9SToby Isaac const PetscInt point = points[2*p]; 468897e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 468997e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 469097e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 469197e99dd9SToby Isaac updatePointBC_private(section, point, dof, insert, perm, flip, clperm, values, off, array); 4692a5e93ea8SMatthew G. Knepley } break; 4693552f7358SJed Brown case ADD_VALUES: 469497e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 469597e99dd9SToby Isaac const PetscInt point = points[2*p]; 469697e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 469797e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 469897e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 469997e99dd9SToby Isaac updatePoint_private(section, point, dof, add, PETSC_FALSE, perm, flip, clperm, values, off, array); 4700552f7358SJed Brown } break; 4701552f7358SJed Brown case ADD_ALL_VALUES: 470297e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 470397e99dd9SToby Isaac const PetscInt point = points[2*p]; 470497e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 470597e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 470697e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 470797e99dd9SToby Isaac updatePoint_private(section, point, dof, add, PETSC_TRUE, perm, flip, clperm, values, off, array); 4708552f7358SJed Brown } break; 4709304ab55fSMatthew G. Knepley case ADD_BC_VALUES: 471097e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 471197e99dd9SToby Isaac const PetscInt point = points[2*p]; 471297e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 471397e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 471497e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 471597e99dd9SToby Isaac updatePointBC_private(section, point, dof, add, perm, flip, clperm, values, off, array); 4716304ab55fSMatthew G. Knepley } break; 4717552f7358SJed Brown default: 4718f347f43bSBarry Smith SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insert mode %d", mode); 4719552f7358SJed Brown } 472097e99dd9SToby Isaac ierr = PetscSectionRestorePointSyms(section,numPoints,points,&perms,&flips);CHKERRQ(ierr); 4721552f7358SJed Brown } 47221a271a75SMatthew G. Knepley /* Cleanup points */ 4723923c78e0SToby Isaac ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 47241a271a75SMatthew G. Knepley /* Cleanup array */ 4725552f7358SJed Brown ierr = VecRestoreArray(v, &array);CHKERRQ(ierr); 4726552f7358SJed Brown PetscFunctionReturn(0); 4727552f7358SJed Brown } 4728552f7358SJed Brown 4729ba322698SMatthew G. Knepley PetscErrorCode DMPlexVecSetFieldClosure_Internal(DM dm, PetscSection section, Vec v, PetscBool fieldActive[], PetscInt point, PetscInt Ncc, const PetscInt comps[], const PetscScalar values[], InsertMode mode) 4730e07394fbSMatthew G. Knepley { 4731e07394fbSMatthew G. Knepley PetscSection clSection; 4732e07394fbSMatthew G. Knepley IS clPoints; 4733e07394fbSMatthew G. Knepley PetscScalar *array; 4734e07394fbSMatthew G. Knepley PetscInt *points = NULL; 4735b04c866fSMatthew G. Knepley const PetscInt *clp, *clperm; 4736e07394fbSMatthew G. Knepley PetscInt numFields, numPoints, p; 473797e99dd9SToby Isaac PetscInt offset = 0, f; 4738e07394fbSMatthew G. Knepley PetscErrorCode ierr; 4739e07394fbSMatthew G. Knepley 4740e07394fbSMatthew G. Knepley PetscFunctionBeginHot; 4741e07394fbSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4742e87a4003SBarry Smith if (!section) {ierr = DMGetSection(dm, §ion);CHKERRQ(ierr);} 4743e07394fbSMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 4744e07394fbSMatthew G. Knepley PetscValidHeaderSpecific(v, VEC_CLASSID, 3); 4745e07394fbSMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 4746e07394fbSMatthew G. Knepley /* Get points */ 4747b04c866fSMatthew G. Knepley ierr = PetscSectionGetClosureInversePermutation_Internal(section, (PetscObject) dm, NULL, &clperm);CHKERRQ(ierr); 4748923c78e0SToby Isaac ierr = DMPlexGetCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 4749e07394fbSMatthew G. Knepley /* Get array */ 4750e07394fbSMatthew G. Knepley ierr = VecGetArray(v, &array);CHKERRQ(ierr); 4751e07394fbSMatthew G. Knepley /* Get values */ 4752e07394fbSMatthew G. Knepley for (f = 0; f < numFields; ++f) { 475397e99dd9SToby Isaac const PetscInt **perms = NULL; 475497e99dd9SToby Isaac const PetscScalar **flips = NULL; 475597e99dd9SToby Isaac 4756e07394fbSMatthew G. Knepley if (!fieldActive[f]) { 4757e07394fbSMatthew G. Knepley for (p = 0; p < numPoints*2; p += 2) { 4758e07394fbSMatthew G. Knepley PetscInt fdof; 4759e07394fbSMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, points[p], f, &fdof);CHKERRQ(ierr); 4760e07394fbSMatthew G. Knepley offset += fdof; 4761e07394fbSMatthew G. Knepley } 4762e07394fbSMatthew G. Knepley continue; 4763e07394fbSMatthew G. Knepley } 476497e99dd9SToby Isaac ierr = PetscSectionGetFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 4765e07394fbSMatthew G. Knepley switch (mode) { 4766e07394fbSMatthew G. Knepley case INSERT_VALUES: 476797e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 476897e99dd9SToby Isaac const PetscInt point = points[2*p]; 476997e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 477097e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 4771b04c866fSMatthew G. Knepley updatePointFields_private(section, point, perm, flip, f, insert, PETSC_FALSE, clperm, values, &offset, array); 4772e07394fbSMatthew G. Knepley } break; 4773e07394fbSMatthew G. Knepley case INSERT_ALL_VALUES: 477497e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 477597e99dd9SToby Isaac const PetscInt point = points[2*p]; 477697e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 477797e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 4778b04c866fSMatthew G. Knepley updatePointFields_private(section, point, perm, flip, f, insert, PETSC_TRUE, clperm, values, &offset, array); 4779e07394fbSMatthew G. Knepley } break; 4780e07394fbSMatthew G. Knepley case INSERT_BC_VALUES: 478197e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 478297e99dd9SToby Isaac const PetscInt point = points[2*p]; 478397e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 478497e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 4785ba322698SMatthew G. Knepley updatePointFieldsBC_private(section, point, perm, flip, f, Ncc, comps, insert, clperm, values, &offset, array); 4786e07394fbSMatthew G. Knepley } break; 4787e07394fbSMatthew G. Knepley case ADD_VALUES: 478897e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 478997e99dd9SToby Isaac const PetscInt point = points[2*p]; 479097e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 479197e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 4792b04c866fSMatthew G. Knepley updatePointFields_private(section, point, perm, flip, f, add, PETSC_FALSE, clperm, values, &offset, array); 4793e07394fbSMatthew G. Knepley } break; 4794e07394fbSMatthew G. Knepley case ADD_ALL_VALUES: 479597e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 479697e99dd9SToby Isaac const PetscInt point = points[2*p]; 479797e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 479897e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 4799b04c866fSMatthew G. Knepley updatePointFields_private(section, point, perm, flip, f, add, PETSC_TRUE, clperm, values, &offset, array); 4800e07394fbSMatthew G. Knepley } break; 4801e07394fbSMatthew G. Knepley default: 4802f347f43bSBarry Smith SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insert mode %d", mode); 4803e07394fbSMatthew G. Knepley } 480497e99dd9SToby Isaac ierr = PetscSectionRestoreFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 4805e07394fbSMatthew G. Knepley } 4806e07394fbSMatthew G. Knepley /* Cleanup points */ 4807923c78e0SToby Isaac ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 4808e07394fbSMatthew G. Knepley /* Cleanup array */ 4809e07394fbSMatthew G. Knepley ierr = VecRestoreArray(v, &array);CHKERRQ(ierr); 4810e07394fbSMatthew G. Knepley PetscFunctionReturn(0); 4811e07394fbSMatthew G. Knepley } 4812e07394fbSMatthew G. Knepley 48137cd05799SMatthew G. Knepley static PetscErrorCode DMPlexPrintMatSetValues(PetscViewer viewer, Mat A, PetscInt point, PetscInt numRIndices, const PetscInt rindices[], PetscInt numCIndices, const PetscInt cindices[], const PetscScalar values[]) 4814552f7358SJed Brown { 4815552f7358SJed Brown PetscMPIInt rank; 4816552f7358SJed Brown PetscInt i, j; 4817552f7358SJed Brown PetscErrorCode ierr; 4818552f7358SJed Brown 4819552f7358SJed Brown PetscFunctionBegin; 482082f516ccSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)A), &rank);CHKERRQ(ierr); 4821eaf898f9SPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer, "[%d]mat for point %D\n", rank, point);CHKERRQ(ierr); 4822e4b003c7SBarry Smith for (i = 0; i < numRIndices; i++) {ierr = PetscViewerASCIIPrintf(viewer, "[%d]mat row indices[%D] = %D\n", rank, i, rindices[i]);CHKERRQ(ierr);} 4823e4b003c7SBarry Smith for (i = 0; i < numCIndices; i++) {ierr = PetscViewerASCIIPrintf(viewer, "[%d]mat col indices[%D] = %D\n", rank, i, cindices[i]);CHKERRQ(ierr);} 4824b0ecff45SMatthew G. Knepley numCIndices = numCIndices ? numCIndices : numRIndices; 4825b0ecff45SMatthew G. Knepley for (i = 0; i < numRIndices; i++) { 4826e4b003c7SBarry Smith ierr = PetscViewerASCIIPrintf(viewer, "[%d]", rank);CHKERRQ(ierr); 4827b0ecff45SMatthew G. Knepley for (j = 0; j < numCIndices; j++) { 4828519f805aSKarl Rupp #if defined(PETSC_USE_COMPLEX) 48297eba1a17SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " (%g,%g)", (double)PetscRealPart(values[i*numCIndices+j]), (double)PetscImaginaryPart(values[i*numCIndices+j]));CHKERRQ(ierr); 4830552f7358SJed Brown #else 4831b0ecff45SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " %g", (double)values[i*numCIndices+j]);CHKERRQ(ierr); 4832552f7358SJed Brown #endif 4833552f7358SJed Brown } 483477a6746dSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, "\n");CHKERRQ(ierr); 4835552f7358SJed Brown } 4836552f7358SJed Brown PetscFunctionReturn(0); 4837552f7358SJed Brown } 4838552f7358SJed Brown 483905586334SMatthew G. Knepley /* 484005586334SMatthew G. Knepley DMPlexGetIndicesPoint_Internal - Add the indices for dofs on a point to an index array 484105586334SMatthew G. Knepley 484205586334SMatthew G. Knepley Input Parameters: 484305586334SMatthew G. Knepley + section - The section for this data layout 484405586334SMatthew G. Knepley . point - The point contributing dofs with these indices 484505586334SMatthew G. Knepley . off - The global offset of this point 484605586334SMatthew G. Knepley . loff - The local offset of each field 484705586334SMatthew G. Knepley . setBC - The flag determining whether to include indices of bounsary values 484805586334SMatthew G. Knepley . perm - A permutation of the dofs on this point, or NULL 484905586334SMatthew G. Knepley - indperm - A permutation of the entire indices array, or NULL 485005586334SMatthew G. Knepley 485105586334SMatthew G. Knepley Output Parameter: 485205586334SMatthew G. Knepley . indices - Indices for dofs on this point 485305586334SMatthew G. Knepley 485405586334SMatthew G. Knepley Level: developer 485505586334SMatthew G. Knepley 485605586334SMatthew G. Knepley Note: The indices could be local or global, depending on the value of 'off'. 485705586334SMatthew G. Knepley */ 485805586334SMatthew G. Knepley PetscErrorCode DMPlexGetIndicesPoint_Internal(PetscSection section, PetscInt point, PetscInt off, PetscInt *loff, PetscBool setBC, const PetscInt perm[], const PetscInt indperm[], PetscInt indices[]) 4859a6dfd86eSKarl Rupp { 4860e6ccafaeSMatthew G Knepley PetscInt dof; /* The number of unknowns on this point */ 4861552f7358SJed Brown PetscInt cdof; /* The number of constraints on this point */ 4862552f7358SJed Brown const PetscInt *cdofs; /* The indices of the constrained dofs on this point */ 4863552f7358SJed Brown PetscInt cind = 0, k; 4864552f7358SJed Brown PetscErrorCode ierr; 4865552f7358SJed Brown 4866552f7358SJed Brown PetscFunctionBegin; 4867552f7358SJed Brown ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 4868552f7358SJed Brown ierr = PetscSectionGetConstraintDof(section, point, &cdof);CHKERRQ(ierr); 4869552f7358SJed Brown if (!cdof || setBC) { 487005586334SMatthew G. Knepley for (k = 0; k < dof; ++k) { 487105586334SMatthew G. Knepley const PetscInt preind = perm ? *loff+perm[k] : *loff+k; 487205586334SMatthew G. Knepley const PetscInt ind = indperm ? indperm[preind] : preind; 487305586334SMatthew G. Knepley 487405586334SMatthew G. Knepley indices[ind] = off + k; 4875552f7358SJed Brown } 4876552f7358SJed Brown } else { 4877552f7358SJed Brown ierr = PetscSectionGetConstraintIndices(section, point, &cdofs);CHKERRQ(ierr); 48784acb8e1eSToby Isaac for (k = 0; k < dof; ++k) { 487905586334SMatthew G. Knepley const PetscInt preind = perm ? *loff+perm[k] : *loff+k; 488005586334SMatthew G. Knepley const PetscInt ind = indperm ? indperm[preind] : preind; 488105586334SMatthew G. Knepley 48824acb8e1eSToby Isaac if ((cind < cdof) && (k == cdofs[cind])) { 48834acb8e1eSToby Isaac /* Insert check for returning constrained indices */ 488405586334SMatthew G. Knepley indices[ind] = -(off+k+1); 48854acb8e1eSToby Isaac ++cind; 48864acb8e1eSToby Isaac } else { 488705586334SMatthew G. Knepley indices[ind] = off+k-cind; 4888552f7358SJed Brown } 4889552f7358SJed Brown } 4890552f7358SJed Brown } 4891e6ccafaeSMatthew G Knepley *loff += dof; 4892552f7358SJed Brown PetscFunctionReturn(0); 4893552f7358SJed Brown } 4894552f7358SJed Brown 48957e29afd2SMatthew G. Knepley /* 48967e29afd2SMatthew G. Knepley This version only believes the point offset from the globalSection 48977e29afd2SMatthew G. Knepley 48987e29afd2SMatthew G. Knepley . off - The global offset of this point 48997e29afd2SMatthew G. Knepley */ 490005586334SMatthew G. Knepley PetscErrorCode DMPlexGetIndicesPointFields_Internal(PetscSection section, PetscInt point, PetscInt off, PetscInt foffs[], PetscBool setBC, const PetscInt ***perms, PetscInt permsoff, const PetscInt indperm[], PetscInt indices[]) 4901a6dfd86eSKarl Rupp { 4902552f7358SJed Brown PetscInt numFields, foff, f; 4903552f7358SJed Brown PetscErrorCode ierr; 4904552f7358SJed Brown 4905552f7358SJed Brown PetscFunctionBegin; 4906552f7358SJed Brown ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 4907552f7358SJed Brown for (f = 0, foff = 0; f < numFields; ++f) { 49084acb8e1eSToby Isaac PetscInt fdof, cfdof; 4909552f7358SJed Brown const PetscInt *fcdofs; /* The indices of the constrained dofs for field f on this point */ 49104acb8e1eSToby Isaac PetscInt cind = 0, b; 49114acb8e1eSToby Isaac const PetscInt *perm = (perms && perms[f]) ? perms[f][permsoff] : NULL; 4912552f7358SJed Brown 4913552f7358SJed Brown ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 4914552f7358SJed Brown ierr = PetscSectionGetFieldConstraintDof(section, point, f, &cfdof);CHKERRQ(ierr); 4915552f7358SJed Brown if (!cfdof || setBC) { 491605586334SMatthew G. Knepley for (b = 0; b < fdof; ++b) { 491705586334SMatthew G. Knepley const PetscInt preind = perm ? foffs[f]+perm[b] : foffs[f]+b; 491805586334SMatthew G. Knepley const PetscInt ind = indperm ? indperm[preind] : preind; 491905586334SMatthew G. Knepley 492005586334SMatthew G. Knepley indices[ind] = off+foff+b; 492105586334SMatthew G. Knepley } 4922552f7358SJed Brown } else { 4923552f7358SJed Brown ierr = PetscSectionGetFieldConstraintIndices(section, point, f, &fcdofs);CHKERRQ(ierr); 492405586334SMatthew G. Knepley for (b = 0; b < fdof; ++b) { 492505586334SMatthew G. Knepley const PetscInt preind = perm ? foffs[f]+perm[b] : foffs[f]+b; 492605586334SMatthew G. Knepley const PetscInt ind = indperm ? indperm[preind] : preind; 492705586334SMatthew G. Knepley 49284acb8e1eSToby Isaac if ((cind < cfdof) && (b == fcdofs[cind])) { 492905586334SMatthew G. Knepley indices[ind] = -(off+foff+b+1); 4930552f7358SJed Brown ++cind; 4931552f7358SJed Brown } else { 493205586334SMatthew G. Knepley indices[ind] = off+foff+b-cind; 4933552f7358SJed Brown } 4934552f7358SJed Brown } 4935552f7358SJed Brown } 4936a9096520SToby Isaac foff += (setBC ? fdof : (fdof - cfdof)); 4937552f7358SJed Brown foffs[f] += fdof; 4938552f7358SJed Brown } 4939552f7358SJed Brown PetscFunctionReturn(0); 4940552f7358SJed Brown } 4941552f7358SJed Brown 49427e29afd2SMatthew G. Knepley /* 49437e29afd2SMatthew G. Knepley This version believes the globalSection offsets for each field, rather than just the point offset 49447e29afd2SMatthew G. Knepley 49457e29afd2SMatthew G. Knepley . foffs - The offset into 'indices' for each field, since it is segregated by field 49467e29afd2SMatthew G. Knepley */ 494705586334SMatthew G. Knepley PetscErrorCode DMPlexGetIndicesPointFieldsSplit_Internal(PetscSection section, PetscSection globalSection, PetscInt point, PetscInt foffs[], PetscBool setBC, const PetscInt ***perms, PetscInt permsoff, const PetscInt indperm[], PetscInt indices[]) 49487e29afd2SMatthew G. Knepley { 49497e29afd2SMatthew G. Knepley PetscInt numFields, foff, f; 49507e29afd2SMatthew G. Knepley PetscErrorCode ierr; 49517e29afd2SMatthew G. Knepley 49527e29afd2SMatthew G. Knepley PetscFunctionBegin; 49537e29afd2SMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 49547e29afd2SMatthew G. Knepley for (f = 0; f < numFields; ++f) { 49557e29afd2SMatthew G. Knepley PetscInt fdof, cfdof; 49567e29afd2SMatthew G. Knepley const PetscInt *fcdofs; /* The indices of the constrained dofs for field f on this point */ 49577e29afd2SMatthew G. Knepley PetscInt cind = 0, b; 49587e29afd2SMatthew G. Knepley const PetscInt *perm = (perms && perms[f]) ? perms[f][permsoff] : NULL; 49597e29afd2SMatthew G. Knepley 49607e29afd2SMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 49617e29afd2SMatthew G. Knepley ierr = PetscSectionGetFieldConstraintDof(section, point, f, &cfdof);CHKERRQ(ierr); 49627e29afd2SMatthew G. Knepley ierr = PetscSectionGetFieldOffset(globalSection, point, f, &foff);CHKERRQ(ierr); 49637e29afd2SMatthew G. Knepley if (!cfdof || setBC) { 496405586334SMatthew G. Knepley for (b = 0; b < fdof; ++b) { 496505586334SMatthew G. Knepley const PetscInt preind = perm ? foffs[f]+perm[b] : foffs[f]+b; 496605586334SMatthew G. Knepley const PetscInt ind = indperm ? indperm[preind] : preind; 496705586334SMatthew G. Knepley 496805586334SMatthew G. Knepley indices[ind] = foff+b; 496905586334SMatthew G. Knepley } 49707e29afd2SMatthew G. Knepley } else { 49717e29afd2SMatthew G. Knepley ierr = PetscSectionGetFieldConstraintIndices(section, point, f, &fcdofs);CHKERRQ(ierr); 497205586334SMatthew G. Knepley for (b = 0; b < fdof; ++b) { 497305586334SMatthew G. Knepley const PetscInt preind = perm ? foffs[f]+perm[b] : foffs[f]+b; 497405586334SMatthew G. Knepley const PetscInt ind = indperm ? indperm[preind] : preind; 497505586334SMatthew G. Knepley 49767e29afd2SMatthew G. Knepley if ((cind < cfdof) && (b == fcdofs[cind])) { 497705586334SMatthew G. Knepley indices[ind] = -(foff+b+1); 49787e29afd2SMatthew G. Knepley ++cind; 49797e29afd2SMatthew G. Knepley } else { 498005586334SMatthew G. Knepley indices[ind] = foff+b-cind; 49817e29afd2SMatthew G. Knepley } 49827e29afd2SMatthew G. Knepley } 49837e29afd2SMatthew G. Knepley } 49847e29afd2SMatthew G. Knepley foffs[f] += fdof; 49857e29afd2SMatthew G. Knepley } 49867e29afd2SMatthew G. Knepley PetscFunctionReturn(0); 49877e29afd2SMatthew G. Knepley } 49887e29afd2SMatthew G. Knepley 49894acb8e1eSToby Isaac PetscErrorCode DMPlexAnchorsModifyMat(DM dm, PetscSection section, PetscInt numPoints, PetscInt numIndices, const PetscInt points[], const PetscInt ***perms, const PetscScalar values[], PetscInt *outNumPoints, PetscInt *outNumIndices, PetscInt *outPoints[], PetscScalar *outValues[], PetscInt offsets[], PetscBool multiplyLeft) 4990d3d1a6afSToby Isaac { 4991d3d1a6afSToby Isaac Mat cMat; 4992d3d1a6afSToby Isaac PetscSection aSec, cSec; 4993d3d1a6afSToby Isaac IS aIS; 4994d3d1a6afSToby Isaac PetscInt aStart = -1, aEnd = -1; 4995d3d1a6afSToby Isaac const PetscInt *anchors; 4996e17c06e0SMatthew G. Knepley PetscInt numFields, f, p, q, newP = 0; 4997d3d1a6afSToby Isaac PetscInt newNumPoints = 0, newNumIndices = 0; 4998d3d1a6afSToby Isaac PetscInt *newPoints, *indices, *newIndices; 4999d3d1a6afSToby Isaac PetscInt maxAnchor, maxDof; 5000d3d1a6afSToby Isaac PetscInt newOffsets[32]; 5001d3d1a6afSToby Isaac PetscInt *pointMatOffsets[32]; 5002d3d1a6afSToby Isaac PetscInt *newPointOffsets[32]; 5003d3d1a6afSToby Isaac PetscScalar *pointMat[32]; 50046ecaa68aSToby Isaac PetscScalar *newValues=NULL,*tmpValues; 5005d3d1a6afSToby Isaac PetscBool anyConstrained = PETSC_FALSE; 5006d3d1a6afSToby Isaac PetscErrorCode ierr; 5007d3d1a6afSToby Isaac 5008d3d1a6afSToby Isaac PetscFunctionBegin; 5009d3d1a6afSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5010d3d1a6afSToby Isaac PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 5011d3d1a6afSToby Isaac ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 5012d3d1a6afSToby Isaac 5013a17985deSToby Isaac ierr = DMPlexGetAnchors(dm,&aSec,&aIS);CHKERRQ(ierr); 5014d3d1a6afSToby Isaac /* if there are point-to-point constraints */ 5015d3d1a6afSToby Isaac if (aSec) { 5016d3d1a6afSToby Isaac ierr = PetscMemzero(newOffsets, 32 * sizeof(PetscInt));CHKERRQ(ierr); 5017d3d1a6afSToby Isaac ierr = ISGetIndices(aIS,&anchors);CHKERRQ(ierr); 5018d3d1a6afSToby Isaac ierr = PetscSectionGetChart(aSec,&aStart,&aEnd);CHKERRQ(ierr); 5019d3d1a6afSToby Isaac /* figure out how many points are going to be in the new element matrix 5020d3d1a6afSToby Isaac * (we allow double counting, because it's all just going to be summed 5021d3d1a6afSToby Isaac * into the global matrix anyway) */ 5022d3d1a6afSToby Isaac for (p = 0; p < 2*numPoints; p+=2) { 5023d3d1a6afSToby Isaac PetscInt b = points[p]; 50244b2f2278SToby Isaac PetscInt bDof = 0, bSecDof; 5025d3d1a6afSToby Isaac 50264b2f2278SToby Isaac ierr = PetscSectionGetDof(section,b,&bSecDof);CHKERRQ(ierr); 50274b2f2278SToby Isaac if (!bSecDof) { 50284b2f2278SToby Isaac continue; 50294b2f2278SToby Isaac } 5030d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 5031d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec,b,&bDof);CHKERRQ(ierr); 5032d3d1a6afSToby Isaac } 5033d3d1a6afSToby Isaac if (bDof) { 5034d3d1a6afSToby Isaac /* this point is constrained */ 5035d3d1a6afSToby Isaac /* it is going to be replaced by its anchors */ 5036d3d1a6afSToby Isaac PetscInt bOff, q; 5037d3d1a6afSToby Isaac 5038d3d1a6afSToby Isaac anyConstrained = PETSC_TRUE; 5039d3d1a6afSToby Isaac newNumPoints += bDof; 5040d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(aSec,b,&bOff);CHKERRQ(ierr); 5041d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 5042d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q]; 5043d3d1a6afSToby Isaac PetscInt aDof; 5044d3d1a6afSToby Isaac 5045d3d1a6afSToby Isaac ierr = PetscSectionGetDof(section,a,&aDof);CHKERRQ(ierr); 5046d3d1a6afSToby Isaac newNumIndices += aDof; 5047d3d1a6afSToby Isaac for (f = 0; f < numFields; ++f) { 5048d3d1a6afSToby Isaac PetscInt fDof; 5049d3d1a6afSToby Isaac 5050d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, a, f, &fDof);CHKERRQ(ierr); 5051d3d1a6afSToby Isaac newOffsets[f+1] += fDof; 5052d3d1a6afSToby Isaac } 5053d3d1a6afSToby Isaac } 5054d3d1a6afSToby Isaac } 5055d3d1a6afSToby Isaac else { 5056d3d1a6afSToby Isaac /* this point is not constrained */ 5057d3d1a6afSToby Isaac newNumPoints++; 50584b2f2278SToby Isaac newNumIndices += bSecDof; 5059d3d1a6afSToby Isaac for (f = 0; f < numFields; ++f) { 5060d3d1a6afSToby Isaac PetscInt fDof; 5061d3d1a6afSToby Isaac 5062d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, b, f, &fDof);CHKERRQ(ierr); 5063d3d1a6afSToby Isaac newOffsets[f+1] += fDof; 5064d3d1a6afSToby Isaac } 5065d3d1a6afSToby Isaac } 5066d3d1a6afSToby Isaac } 5067d3d1a6afSToby Isaac } 5068d3d1a6afSToby Isaac if (!anyConstrained) { 506972b80496SMatthew G. Knepley if (outNumPoints) *outNumPoints = 0; 507072b80496SMatthew G. Knepley if (outNumIndices) *outNumIndices = 0; 507172b80496SMatthew G. Knepley if (outPoints) *outPoints = NULL; 507272b80496SMatthew G. Knepley if (outValues) *outValues = NULL; 507372b80496SMatthew G. Knepley if (aSec) {ierr = ISRestoreIndices(aIS,&anchors);CHKERRQ(ierr);} 5074d3d1a6afSToby Isaac PetscFunctionReturn(0); 5075d3d1a6afSToby Isaac } 5076d3d1a6afSToby Isaac 50776ecaa68aSToby Isaac if (outNumPoints) *outNumPoints = newNumPoints; 50786ecaa68aSToby Isaac if (outNumIndices) *outNumIndices = newNumIndices; 50796ecaa68aSToby Isaac 5080f13f9184SToby Isaac for (f = 0; f < numFields; ++f) newOffsets[f+1] += newOffsets[f]; 5081d3d1a6afSToby Isaac 50826ecaa68aSToby Isaac if (!outPoints && !outValues) { 50836ecaa68aSToby Isaac if (offsets) { 50846ecaa68aSToby Isaac for (f = 0; f <= numFields; f++) { 50856ecaa68aSToby Isaac offsets[f] = newOffsets[f]; 50866ecaa68aSToby Isaac } 50876ecaa68aSToby Isaac } 50886ecaa68aSToby Isaac if (aSec) {ierr = ISRestoreIndices(aIS,&anchors);CHKERRQ(ierr);} 50896ecaa68aSToby Isaac PetscFunctionReturn(0); 50906ecaa68aSToby Isaac } 50916ecaa68aSToby Isaac 5092f347f43bSBarry Smith if (numFields && newOffsets[numFields] != newNumIndices) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", newOffsets[numFields], newNumIndices); 5093d3d1a6afSToby Isaac 5094f7c74593SToby Isaac ierr = DMGetDefaultConstraints(dm, &cSec, &cMat);CHKERRQ(ierr); 5095d3d1a6afSToby Isaac 5096d3d1a6afSToby Isaac /* workspaces */ 5097d3d1a6afSToby Isaac if (numFields) { 5098d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 509969291d52SBarry Smith ierr = DMGetWorkArray(dm,numPoints+1,MPIU_INT,&pointMatOffsets[f]);CHKERRQ(ierr); 510069291d52SBarry Smith ierr = DMGetWorkArray(dm,numPoints+1,MPIU_INT,&newPointOffsets[f]);CHKERRQ(ierr); 5101d3d1a6afSToby Isaac } 5102d3d1a6afSToby Isaac } 5103d3d1a6afSToby Isaac else { 510469291d52SBarry Smith ierr = DMGetWorkArray(dm,numPoints+1,MPIU_INT,&pointMatOffsets[0]);CHKERRQ(ierr); 510569291d52SBarry Smith ierr = DMGetWorkArray(dm,numPoints,MPIU_INT,&newPointOffsets[0]);CHKERRQ(ierr); 5106d3d1a6afSToby Isaac } 5107d3d1a6afSToby Isaac 5108d3d1a6afSToby Isaac /* get workspaces for the point-to-point matrices */ 5109d3d1a6afSToby Isaac if (numFields) { 51104b2f2278SToby Isaac PetscInt totalOffset, totalMatOffset; 51114b2f2278SToby Isaac 5112d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 5113d3d1a6afSToby Isaac PetscInt b = points[2*p]; 51144b2f2278SToby Isaac PetscInt bDof = 0, bSecDof; 5115d3d1a6afSToby Isaac 51164b2f2278SToby Isaac ierr = PetscSectionGetDof(section,b,&bSecDof);CHKERRQ(ierr); 51174b2f2278SToby Isaac if (!bSecDof) { 51184b2f2278SToby Isaac for (f = 0; f < numFields; f++) { 51194b2f2278SToby Isaac newPointOffsets[f][p + 1] = 0; 51204b2f2278SToby Isaac pointMatOffsets[f][p + 1] = 0; 51214b2f2278SToby Isaac } 51224b2f2278SToby Isaac continue; 51234b2f2278SToby Isaac } 5124d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 5125d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec, b, &bDof);CHKERRQ(ierr); 5126d3d1a6afSToby Isaac } 5127d3d1a6afSToby Isaac if (bDof) { 5128d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 5129d3d1a6afSToby Isaac PetscInt fDof, q, bOff, allFDof = 0; 5130d3d1a6afSToby Isaac 5131d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, b, f, &fDof);CHKERRQ(ierr); 5132d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(aSec, b, &bOff);CHKERRQ(ierr); 5133d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 5134d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q]; 5135d3d1a6afSToby Isaac PetscInt aFDof; 5136d3d1a6afSToby Isaac 5137d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, a, f, &aFDof);CHKERRQ(ierr); 5138d3d1a6afSToby Isaac allFDof += aFDof; 5139d3d1a6afSToby Isaac } 5140d3d1a6afSToby Isaac newPointOffsets[f][p+1] = allFDof; 5141d3d1a6afSToby Isaac pointMatOffsets[f][p+1] = fDof * allFDof; 5142d3d1a6afSToby Isaac } 5143d3d1a6afSToby Isaac } 5144d3d1a6afSToby Isaac else { 5145d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 5146d3d1a6afSToby Isaac PetscInt fDof; 5147d3d1a6afSToby Isaac 5148d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, b, f, &fDof);CHKERRQ(ierr); 5149d3d1a6afSToby Isaac newPointOffsets[f][p+1] = fDof; 5150d3d1a6afSToby Isaac pointMatOffsets[f][p+1] = 0; 5151d3d1a6afSToby Isaac } 5152d3d1a6afSToby Isaac } 5153d3d1a6afSToby Isaac } 51544b2f2278SToby Isaac for (f = 0, totalOffset = 0, totalMatOffset = 0; f < numFields; f++) { 51554b2f2278SToby Isaac newPointOffsets[f][0] = totalOffset; 51564b2f2278SToby Isaac pointMatOffsets[f][0] = totalMatOffset; 5157d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 5158d3d1a6afSToby Isaac newPointOffsets[f][p+1] += newPointOffsets[f][p]; 5159d3d1a6afSToby Isaac pointMatOffsets[f][p+1] += pointMatOffsets[f][p]; 5160d3d1a6afSToby Isaac } 516119f70fd5SToby Isaac totalOffset = newPointOffsets[f][numPoints]; 516219f70fd5SToby Isaac totalMatOffset = pointMatOffsets[f][numPoints]; 516369291d52SBarry Smith ierr = DMGetWorkArray(dm,pointMatOffsets[f][numPoints],MPIU_SCALAR,&pointMat[f]);CHKERRQ(ierr); 5164d3d1a6afSToby Isaac } 5165d3d1a6afSToby Isaac } 5166d3d1a6afSToby Isaac else { 5167d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 5168d3d1a6afSToby Isaac PetscInt b = points[2*p]; 51694b2f2278SToby Isaac PetscInt bDof = 0, bSecDof; 5170d3d1a6afSToby Isaac 51714b2f2278SToby Isaac ierr = PetscSectionGetDof(section,b,&bSecDof);CHKERRQ(ierr); 51724b2f2278SToby Isaac if (!bSecDof) { 51734b2f2278SToby Isaac newPointOffsets[0][p + 1] = 0; 51744b2f2278SToby Isaac pointMatOffsets[0][p + 1] = 0; 51754b2f2278SToby Isaac continue; 51764b2f2278SToby Isaac } 5177d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 5178d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec, b, &bDof);CHKERRQ(ierr); 5179d3d1a6afSToby Isaac } 5180d3d1a6afSToby Isaac if (bDof) { 51814b2f2278SToby Isaac PetscInt bOff, q, allDof = 0; 5182d3d1a6afSToby Isaac 5183d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(aSec, b, &bOff);CHKERRQ(ierr); 5184d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 5185d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q], aDof; 5186d3d1a6afSToby Isaac 5187d3d1a6afSToby Isaac ierr = PetscSectionGetDof(section, a, &aDof);CHKERRQ(ierr); 5188d3d1a6afSToby Isaac allDof += aDof; 5189d3d1a6afSToby Isaac } 5190d3d1a6afSToby Isaac newPointOffsets[0][p+1] = allDof; 51914b2f2278SToby Isaac pointMatOffsets[0][p+1] = bSecDof * allDof; 5192d3d1a6afSToby Isaac } 5193d3d1a6afSToby Isaac else { 51944b2f2278SToby Isaac newPointOffsets[0][p+1] = bSecDof; 5195d3d1a6afSToby Isaac pointMatOffsets[0][p+1] = 0; 5196d3d1a6afSToby Isaac } 5197d3d1a6afSToby Isaac } 5198d3d1a6afSToby Isaac newPointOffsets[0][0] = 0; 5199d3d1a6afSToby Isaac pointMatOffsets[0][0] = 0; 5200d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 5201d3d1a6afSToby Isaac newPointOffsets[0][p+1] += newPointOffsets[0][p]; 5202d3d1a6afSToby Isaac pointMatOffsets[0][p+1] += pointMatOffsets[0][p]; 5203d3d1a6afSToby Isaac } 520469291d52SBarry Smith ierr = DMGetWorkArray(dm,pointMatOffsets[0][numPoints],MPIU_SCALAR,&pointMat[0]);CHKERRQ(ierr); 5205d3d1a6afSToby Isaac } 5206d3d1a6afSToby Isaac 52076ecaa68aSToby Isaac /* output arrays */ 520869291d52SBarry Smith ierr = DMGetWorkArray(dm,2*newNumPoints,MPIU_INT,&newPoints);CHKERRQ(ierr); 52096ecaa68aSToby Isaac 5210d3d1a6afSToby Isaac /* get the point-to-point matrices; construct newPoints */ 5211d3d1a6afSToby Isaac ierr = PetscSectionGetMaxDof(aSec, &maxAnchor);CHKERRQ(ierr); 5212d3d1a6afSToby Isaac ierr = PetscSectionGetMaxDof(section, &maxDof);CHKERRQ(ierr); 521369291d52SBarry Smith ierr = DMGetWorkArray(dm,maxDof,MPIU_INT,&indices);CHKERRQ(ierr); 521469291d52SBarry Smith ierr = DMGetWorkArray(dm,maxAnchor*maxDof,MPIU_INT,&newIndices);CHKERRQ(ierr); 5215d3d1a6afSToby Isaac if (numFields) { 5216d3d1a6afSToby Isaac for (p = 0, newP = 0; p < numPoints; p++) { 5217d3d1a6afSToby Isaac PetscInt b = points[2*p]; 5218d3d1a6afSToby Isaac PetscInt o = points[2*p+1]; 52194b2f2278SToby Isaac PetscInt bDof = 0, bSecDof; 5220d3d1a6afSToby Isaac 52214b2f2278SToby Isaac ierr = PetscSectionGetDof(section, b, &bSecDof);CHKERRQ(ierr); 52224b2f2278SToby Isaac if (!bSecDof) { 52234b2f2278SToby Isaac continue; 52244b2f2278SToby Isaac } 5225d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 5226d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec, b, &bDof);CHKERRQ(ierr); 5227d3d1a6afSToby Isaac } 5228d3d1a6afSToby Isaac if (bDof) { 5229d3d1a6afSToby Isaac PetscInt fStart[32], fEnd[32], fAnchorStart[32], fAnchorEnd[32], bOff, q; 5230d3d1a6afSToby Isaac 5231d3d1a6afSToby Isaac fStart[0] = 0; 5232d3d1a6afSToby Isaac fEnd[0] = 0; 5233d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 5234d3d1a6afSToby Isaac PetscInt fDof; 5235d3d1a6afSToby Isaac 5236d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(cSec, b, f, &fDof);CHKERRQ(ierr); 5237d3d1a6afSToby Isaac fStart[f+1] = fStart[f] + fDof; 5238d3d1a6afSToby Isaac fEnd[f+1] = fStart[f+1]; 5239d3d1a6afSToby Isaac } 5240d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(cSec, b, &bOff);CHKERRQ(ierr); 524105586334SMatthew G. Knepley ierr = DMPlexGetIndicesPointFields_Internal(cSec, b, bOff, fEnd, PETSC_TRUE, perms, p, NULL, indices);CHKERRQ(ierr); 5242d3d1a6afSToby Isaac 5243d3d1a6afSToby Isaac fAnchorStart[0] = 0; 5244d3d1a6afSToby Isaac fAnchorEnd[0] = 0; 5245d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 5246d3d1a6afSToby Isaac PetscInt fDof = newPointOffsets[f][p + 1] - newPointOffsets[f][p]; 5247d3d1a6afSToby Isaac 5248d3d1a6afSToby Isaac fAnchorStart[f+1] = fAnchorStart[f] + fDof; 5249d3d1a6afSToby Isaac fAnchorEnd[f+1] = fAnchorStart[f + 1]; 5250d3d1a6afSToby Isaac } 5251d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(aSec, b, &bOff);CHKERRQ(ierr); 5252d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 5253d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q], aOff; 5254d3d1a6afSToby Isaac 5255d3d1a6afSToby Isaac /* we take the orientation of ap into account in the order that we constructed the indices above: the newly added points have no orientation */ 5256d3d1a6afSToby Isaac newPoints[2*(newP + q)] = a; 5257d3d1a6afSToby Isaac newPoints[2*(newP + q) + 1] = 0; 5258302440fdSBarry Smith ierr = PetscSectionGetOffset(section, a, &aOff);CHKERRQ(ierr); 525905586334SMatthew G. Knepley ierr = DMPlexGetIndicesPointFields_Internal(section, a, aOff, fAnchorEnd, PETSC_TRUE, NULL, -1, NULL, newIndices);CHKERRQ(ierr); 5260d3d1a6afSToby Isaac } 5261d3d1a6afSToby Isaac newP += bDof; 5262d3d1a6afSToby Isaac 52636ecaa68aSToby Isaac if (outValues) { 5264d3d1a6afSToby Isaac /* get the point-to-point submatrix */ 5265d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 5266d3d1a6afSToby Isaac ierr = MatGetValues(cMat,fEnd[f]-fStart[f],indices + fStart[f],fAnchorEnd[f] - fAnchorStart[f],newIndices + fAnchorStart[f],pointMat[f] + pointMatOffsets[f][p]);CHKERRQ(ierr); 5267d3d1a6afSToby Isaac } 5268d3d1a6afSToby Isaac } 52696ecaa68aSToby Isaac } 5270d3d1a6afSToby Isaac else { 5271d3d1a6afSToby Isaac newPoints[2 * newP] = b; 5272d3d1a6afSToby Isaac newPoints[2 * newP + 1] = o; 5273d3d1a6afSToby Isaac newP++; 5274d3d1a6afSToby Isaac } 5275d3d1a6afSToby Isaac } 5276d3d1a6afSToby Isaac } else { 5277d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 5278d3d1a6afSToby Isaac PetscInt b = points[2*p]; 5279d3d1a6afSToby Isaac PetscInt o = points[2*p+1]; 52804b2f2278SToby Isaac PetscInt bDof = 0, bSecDof; 5281d3d1a6afSToby Isaac 52824b2f2278SToby Isaac ierr = PetscSectionGetDof(section, b, &bSecDof);CHKERRQ(ierr); 52834b2f2278SToby Isaac if (!bSecDof) { 52844b2f2278SToby Isaac continue; 52854b2f2278SToby Isaac } 5286d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 5287d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec, b, &bDof);CHKERRQ(ierr); 5288d3d1a6afSToby Isaac } 5289d3d1a6afSToby Isaac if (bDof) { 5290d3d1a6afSToby Isaac PetscInt bEnd = 0, bAnchorEnd = 0, bOff; 5291d3d1a6afSToby Isaac 5292d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(cSec, b, &bOff);CHKERRQ(ierr); 529305586334SMatthew G. Knepley ierr = DMPlexGetIndicesPoint_Internal(cSec, b, bOff, &bEnd, PETSC_TRUE, (perms && perms[0]) ? perms[0][p] : NULL, NULL, indices);CHKERRQ(ierr); 5294d3d1a6afSToby Isaac 5295d3d1a6afSToby Isaac ierr = PetscSectionGetOffset (aSec, b, &bOff);CHKERRQ(ierr); 5296d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 5297d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q], aOff; 5298d3d1a6afSToby Isaac 5299d3d1a6afSToby Isaac /* we take the orientation of ap into account in the order that we constructed the indices above: the newly added points have no orientation */ 5300d3d1a6afSToby Isaac 5301d3d1a6afSToby Isaac newPoints[2*(newP + q)] = a; 5302d3d1a6afSToby Isaac newPoints[2*(newP + q) + 1] = 0; 5303302440fdSBarry Smith ierr = PetscSectionGetOffset(section, a, &aOff);CHKERRQ(ierr); 530405586334SMatthew G. Knepley ierr = DMPlexGetIndicesPoint_Internal(section, a, aOff, &bAnchorEnd, PETSC_TRUE, NULL, NULL, newIndices);CHKERRQ(ierr); 5305d3d1a6afSToby Isaac } 5306d3d1a6afSToby Isaac newP += bDof; 5307d3d1a6afSToby Isaac 5308d3d1a6afSToby Isaac /* get the point-to-point submatrix */ 53096ecaa68aSToby Isaac if (outValues) { 5310d3d1a6afSToby Isaac ierr = MatGetValues(cMat,bEnd,indices,bAnchorEnd,newIndices,pointMat[0] + pointMatOffsets[0][p]);CHKERRQ(ierr); 5311d3d1a6afSToby Isaac } 53126ecaa68aSToby Isaac } 5313d3d1a6afSToby Isaac else { 5314d3d1a6afSToby Isaac newPoints[2 * newP] = b; 5315d3d1a6afSToby Isaac newPoints[2 * newP + 1] = o; 5316d3d1a6afSToby Isaac newP++; 5317d3d1a6afSToby Isaac } 5318d3d1a6afSToby Isaac } 5319d3d1a6afSToby Isaac } 5320d3d1a6afSToby Isaac 53216ecaa68aSToby Isaac if (outValues) { 532269291d52SBarry Smith ierr = DMGetWorkArray(dm,newNumIndices*numIndices,MPIU_SCALAR,&tmpValues);CHKERRQ(ierr); 5323d3d1a6afSToby Isaac ierr = PetscMemzero(tmpValues,newNumIndices*numIndices*sizeof(*tmpValues));CHKERRQ(ierr); 5324d3d1a6afSToby Isaac /* multiply constraints on the right */ 5325d3d1a6afSToby Isaac if (numFields) { 5326d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 5327d3d1a6afSToby Isaac PetscInt oldOff = offsets[f]; 5328d3d1a6afSToby Isaac 5329d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 5330d3d1a6afSToby Isaac PetscInt cStart = newPointOffsets[f][p]; 5331d3d1a6afSToby Isaac PetscInt b = points[2 * p]; 5332d3d1a6afSToby Isaac PetscInt c, r, k; 5333d3d1a6afSToby Isaac PetscInt dof; 5334d3d1a6afSToby Isaac 5335d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section,b,f,&dof);CHKERRQ(ierr); 53364b2f2278SToby Isaac if (!dof) { 53374b2f2278SToby Isaac continue; 53384b2f2278SToby Isaac } 5339d3d1a6afSToby Isaac if (pointMatOffsets[f][p] < pointMatOffsets[f][p + 1]) { 5340d3d1a6afSToby Isaac PetscInt nCols = newPointOffsets[f][p+1]-cStart; 5341d3d1a6afSToby Isaac const PetscScalar *mat = pointMat[f] + pointMatOffsets[f][p]; 5342d3d1a6afSToby Isaac 5343d3d1a6afSToby Isaac for (r = 0; r < numIndices; r++) { 5344d3d1a6afSToby Isaac for (c = 0; c < nCols; c++) { 5345d3d1a6afSToby Isaac for (k = 0; k < dof; k++) { 53464acb8e1eSToby Isaac tmpValues[r * newNumIndices + cStart + c] += values[r * numIndices + oldOff + k] * mat[k * nCols + c]; 5347d3d1a6afSToby Isaac } 5348d3d1a6afSToby Isaac } 5349d3d1a6afSToby Isaac } 5350d3d1a6afSToby Isaac } 5351d3d1a6afSToby Isaac else { 5352d3d1a6afSToby Isaac /* copy this column as is */ 5353d3d1a6afSToby Isaac for (r = 0; r < numIndices; r++) { 5354d3d1a6afSToby Isaac for (c = 0; c < dof; c++) { 5355d3d1a6afSToby Isaac tmpValues[r * newNumIndices + cStart + c] = values[r * numIndices + oldOff + c]; 5356d3d1a6afSToby Isaac } 5357d3d1a6afSToby Isaac } 5358d3d1a6afSToby Isaac } 5359d3d1a6afSToby Isaac oldOff += dof; 5360d3d1a6afSToby Isaac } 5361d3d1a6afSToby Isaac } 5362d3d1a6afSToby Isaac } 5363d3d1a6afSToby Isaac else { 5364d3d1a6afSToby Isaac PetscInt oldOff = 0; 5365d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 5366d3d1a6afSToby Isaac PetscInt cStart = newPointOffsets[0][p]; 5367d3d1a6afSToby Isaac PetscInt b = points[2 * p]; 5368d3d1a6afSToby Isaac PetscInt c, r, k; 5369d3d1a6afSToby Isaac PetscInt dof; 5370d3d1a6afSToby Isaac 5371d3d1a6afSToby Isaac ierr = PetscSectionGetDof(section,b,&dof);CHKERRQ(ierr); 53724b2f2278SToby Isaac if (!dof) { 53734b2f2278SToby Isaac continue; 53744b2f2278SToby Isaac } 5375d3d1a6afSToby Isaac if (pointMatOffsets[0][p] < pointMatOffsets[0][p + 1]) { 5376d3d1a6afSToby Isaac PetscInt nCols = newPointOffsets[0][p+1]-cStart; 5377d3d1a6afSToby Isaac const PetscScalar *mat = pointMat[0] + pointMatOffsets[0][p]; 5378d3d1a6afSToby Isaac 5379d3d1a6afSToby Isaac for (r = 0; r < numIndices; r++) { 5380d3d1a6afSToby Isaac for (c = 0; c < nCols; c++) { 5381d3d1a6afSToby Isaac for (k = 0; k < dof; k++) { 5382d3d1a6afSToby Isaac tmpValues[r * newNumIndices + cStart + c] += mat[k * nCols + c] * values[r * numIndices + oldOff + k]; 5383d3d1a6afSToby Isaac } 5384d3d1a6afSToby Isaac } 5385d3d1a6afSToby Isaac } 5386d3d1a6afSToby Isaac } 5387d3d1a6afSToby Isaac else { 5388d3d1a6afSToby Isaac /* copy this column as is */ 5389d3d1a6afSToby Isaac for (r = 0; r < numIndices; r++) { 5390d3d1a6afSToby Isaac for (c = 0; c < dof; c++) { 5391d3d1a6afSToby Isaac tmpValues[r * newNumIndices + cStart + c] = values[r * numIndices + oldOff + c]; 5392d3d1a6afSToby Isaac } 5393d3d1a6afSToby Isaac } 5394d3d1a6afSToby Isaac } 5395d3d1a6afSToby Isaac oldOff += dof; 5396d3d1a6afSToby Isaac } 5397d3d1a6afSToby Isaac } 5398d3d1a6afSToby Isaac 53996ecaa68aSToby Isaac if (multiplyLeft) { 540069291d52SBarry Smith ierr = DMGetWorkArray(dm,newNumIndices*newNumIndices,MPIU_SCALAR,&newValues);CHKERRQ(ierr); 5401d3d1a6afSToby Isaac ierr = PetscMemzero(newValues,newNumIndices*newNumIndices*sizeof(*newValues));CHKERRQ(ierr); 5402d3d1a6afSToby Isaac /* multiply constraints transpose on the left */ 5403d3d1a6afSToby Isaac if (numFields) { 5404d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 5405d3d1a6afSToby Isaac PetscInt oldOff = offsets[f]; 5406d3d1a6afSToby Isaac 5407d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 5408d3d1a6afSToby Isaac PetscInt rStart = newPointOffsets[f][p]; 5409d3d1a6afSToby Isaac PetscInt b = points[2 * p]; 5410d3d1a6afSToby Isaac PetscInt c, r, k; 5411d3d1a6afSToby Isaac PetscInt dof; 5412d3d1a6afSToby Isaac 5413d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section,b,f,&dof);CHKERRQ(ierr); 5414d3d1a6afSToby Isaac if (pointMatOffsets[f][p] < pointMatOffsets[f][p + 1]) { 5415d3d1a6afSToby Isaac PetscInt nRows = newPointOffsets[f][p+1]-rStart; 5416d3d1a6afSToby Isaac const PetscScalar *PETSC_RESTRICT mat = pointMat[f] + pointMatOffsets[f][p]; 5417d3d1a6afSToby Isaac 5418d3d1a6afSToby Isaac for (r = 0; r < nRows; r++) { 5419d3d1a6afSToby Isaac for (c = 0; c < newNumIndices; c++) { 5420d3d1a6afSToby Isaac for (k = 0; k < dof; k++) { 5421d3d1a6afSToby Isaac newValues[(rStart + r) * newNumIndices + c] += mat[k * nRows + r] * tmpValues[(oldOff + k) * newNumIndices + c]; 5422d3d1a6afSToby Isaac } 5423d3d1a6afSToby Isaac } 5424d3d1a6afSToby Isaac } 5425d3d1a6afSToby Isaac } 5426d3d1a6afSToby Isaac else { 5427d3d1a6afSToby Isaac /* copy this row as is */ 5428d3d1a6afSToby Isaac for (r = 0; r < dof; r++) { 5429d3d1a6afSToby Isaac for (c = 0; c < newNumIndices; c++) { 5430d3d1a6afSToby Isaac newValues[(rStart + r) * newNumIndices + c] = tmpValues[(oldOff + r) * newNumIndices + c]; 5431d3d1a6afSToby Isaac } 5432d3d1a6afSToby Isaac } 5433d3d1a6afSToby Isaac } 5434d3d1a6afSToby Isaac oldOff += dof; 5435d3d1a6afSToby Isaac } 5436d3d1a6afSToby Isaac } 5437d3d1a6afSToby Isaac } 5438d3d1a6afSToby Isaac else { 5439d3d1a6afSToby Isaac PetscInt oldOff = 0; 5440d3d1a6afSToby Isaac 5441d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 5442d3d1a6afSToby Isaac PetscInt rStart = newPointOffsets[0][p]; 5443d3d1a6afSToby Isaac PetscInt b = points[2 * p]; 5444d3d1a6afSToby Isaac PetscInt c, r, k; 5445d3d1a6afSToby Isaac PetscInt dof; 5446d3d1a6afSToby Isaac 5447d3d1a6afSToby Isaac ierr = PetscSectionGetDof(section,b,&dof);CHKERRQ(ierr); 5448d3d1a6afSToby Isaac if (pointMatOffsets[0][p] < pointMatOffsets[0][p + 1]) { 5449d3d1a6afSToby Isaac PetscInt nRows = newPointOffsets[0][p+1]-rStart; 5450d3d1a6afSToby Isaac const PetscScalar *PETSC_RESTRICT mat = pointMat[0] + pointMatOffsets[0][p]; 5451d3d1a6afSToby Isaac 5452d3d1a6afSToby Isaac for (r = 0; r < nRows; r++) { 5453d3d1a6afSToby Isaac for (c = 0; c < newNumIndices; c++) { 5454d3d1a6afSToby Isaac for (k = 0; k < dof; k++) { 5455d3d1a6afSToby Isaac newValues[(rStart + r) * newNumIndices + c] += mat[k * nRows + r] * tmpValues[(oldOff + k) * newNumIndices + c]; 5456d3d1a6afSToby Isaac } 5457d3d1a6afSToby Isaac } 5458d3d1a6afSToby Isaac } 5459d3d1a6afSToby Isaac } 5460d3d1a6afSToby Isaac else { 5461d3d1a6afSToby Isaac /* copy this row as is */ 54629fc93327SToby Isaac for (r = 0; r < dof; r++) { 5463d3d1a6afSToby Isaac for (c = 0; c < newNumIndices; c++) { 5464d3d1a6afSToby Isaac newValues[(rStart + r) * newNumIndices + c] = tmpValues[(oldOff + r) * newNumIndices + c]; 5465d3d1a6afSToby Isaac } 5466d3d1a6afSToby Isaac } 5467d3d1a6afSToby Isaac } 5468d3d1a6afSToby Isaac oldOff += dof; 5469d3d1a6afSToby Isaac } 5470d3d1a6afSToby Isaac } 5471d3d1a6afSToby Isaac 547269291d52SBarry Smith ierr = DMRestoreWorkArray(dm,newNumIndices*numIndices,MPIU_SCALAR,&tmpValues);CHKERRQ(ierr); 54736ecaa68aSToby Isaac } 54746ecaa68aSToby Isaac else { 54756ecaa68aSToby Isaac newValues = tmpValues; 54766ecaa68aSToby Isaac } 54776ecaa68aSToby Isaac } 54786ecaa68aSToby Isaac 5479d3d1a6afSToby Isaac /* clean up */ 548069291d52SBarry Smith ierr = DMRestoreWorkArray(dm,maxDof,MPIU_INT,&indices);CHKERRQ(ierr); 548169291d52SBarry Smith ierr = DMRestoreWorkArray(dm,maxAnchor*maxDof,MPIU_INT,&newIndices);CHKERRQ(ierr); 54826ecaa68aSToby Isaac 5483d3d1a6afSToby Isaac if (numFields) { 5484d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 548569291d52SBarry Smith ierr = DMRestoreWorkArray(dm,pointMatOffsets[f][numPoints],MPIU_SCALAR,&pointMat[f]);CHKERRQ(ierr); 548669291d52SBarry Smith ierr = DMRestoreWorkArray(dm,numPoints+1,MPIU_INT,&pointMatOffsets[f]);CHKERRQ(ierr); 548769291d52SBarry Smith ierr = DMRestoreWorkArray(dm,numPoints+1,MPIU_INT,&newPointOffsets[f]);CHKERRQ(ierr); 5488d3d1a6afSToby Isaac } 5489d3d1a6afSToby Isaac } 5490d3d1a6afSToby Isaac else { 549169291d52SBarry Smith ierr = DMRestoreWorkArray(dm,pointMatOffsets[0][numPoints],MPIU_SCALAR,&pointMat[0]);CHKERRQ(ierr); 549269291d52SBarry Smith ierr = DMRestoreWorkArray(dm,numPoints+1,MPIU_INT,&pointMatOffsets[0]);CHKERRQ(ierr); 549369291d52SBarry Smith ierr = DMRestoreWorkArray(dm,numPoints+1,MPIU_INT,&newPointOffsets[0]);CHKERRQ(ierr); 5494d3d1a6afSToby Isaac } 5495d3d1a6afSToby Isaac ierr = ISRestoreIndices(aIS,&anchors);CHKERRQ(ierr); 5496d3d1a6afSToby Isaac 5497d3d1a6afSToby Isaac /* output */ 54986ecaa68aSToby Isaac if (outPoints) { 5499d3d1a6afSToby Isaac *outPoints = newPoints; 55006ecaa68aSToby Isaac } 55016ecaa68aSToby Isaac else { 550269291d52SBarry Smith ierr = DMRestoreWorkArray(dm,2*newNumPoints,MPIU_INT,&newPoints);CHKERRQ(ierr); 55036ecaa68aSToby Isaac } 550431620726SToby Isaac if (outValues) { 5505d3d1a6afSToby Isaac *outValues = newValues; 55066ecaa68aSToby Isaac } 55076ecaa68aSToby Isaac for (f = 0; f <= numFields; f++) { 5508d3d1a6afSToby Isaac offsets[f] = newOffsets[f]; 5509d3d1a6afSToby Isaac } 5510d3d1a6afSToby Isaac PetscFunctionReturn(0); 5511d3d1a6afSToby Isaac } 5512d3d1a6afSToby Isaac 55137cd05799SMatthew G. Knepley /*@C 5514a87adde4SMatthew G. Knepley DMPlexGetClosureIndices - Get the global indices in a vector v for all points in the closure of the given point 55157cd05799SMatthew G. Knepley 55167cd05799SMatthew G. Knepley Not collective 55177cd05799SMatthew G. Knepley 55187cd05799SMatthew G. Knepley Input Parameters: 55197cd05799SMatthew G. Knepley + dm - The DM 55207cd05799SMatthew G. Knepley . section - The section describing the layout in v, or NULL to use the default section 55217cd05799SMatthew G. Knepley . globalSection - The section describing the parallel layout in v, or NULL to use the default section 55227cd05799SMatthew G. Knepley - point - The mesh point 55237cd05799SMatthew G. Knepley 55247cd05799SMatthew G. Knepley Output parameters: 55257cd05799SMatthew G. Knepley + numIndices - The number of indices 55267cd05799SMatthew G. Knepley . indices - The indices 55277cd05799SMatthew G. Knepley - outOffsets - Field offset if not NULL 55287cd05799SMatthew G. Knepley 55297cd05799SMatthew G. Knepley Note: Must call DMPlexRestoreClosureIndices() to free allocated memory 55307cd05799SMatthew G. Knepley 55317cd05799SMatthew G. Knepley Level: advanced 55327cd05799SMatthew G. Knepley 55337cd05799SMatthew G. Knepley .seealso DMPlexRestoreClosureIndices(), DMPlexVecGetClosure(), DMPlexMatSetClosure() 55347cd05799SMatthew G. Knepley @*/ 55356ecaa68aSToby Isaac PetscErrorCode DMPlexGetClosureIndices(DM dm, PetscSection section, PetscSection globalSection, PetscInt point, PetscInt *numIndices, PetscInt **indices, PetscInt *outOffsets) 55367773e69fSMatthew G. Knepley { 55377773e69fSMatthew G. Knepley PetscSection clSection; 55387773e69fSMatthew G. Knepley IS clPoints; 553905586334SMatthew G. Knepley const PetscInt *clp, *clperm; 55404acb8e1eSToby Isaac const PetscInt **perms[32] = {NULL}; 55417773e69fSMatthew G. Knepley PetscInt *points = NULL, *pointsNew; 55427773e69fSMatthew G. Knepley PetscInt numPoints, numPointsNew; 55437773e69fSMatthew G. Knepley PetscInt offsets[32]; 55447773e69fSMatthew G. Knepley PetscInt Nf, Nind, NindNew, off, globalOff, f, p; 55457773e69fSMatthew G. Knepley PetscErrorCode ierr; 55467773e69fSMatthew G. Knepley 55477773e69fSMatthew G. Knepley PetscFunctionBegin; 55487773e69fSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 55497773e69fSMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 55507773e69fSMatthew G. Knepley PetscValidHeaderSpecific(globalSection, PETSC_SECTION_CLASSID, 3); 55517773e69fSMatthew G. Knepley if (numIndices) PetscValidPointer(numIndices, 4); 55527773e69fSMatthew G. Knepley PetscValidPointer(indices, 5); 55537773e69fSMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &Nf);CHKERRQ(ierr); 55547773e69fSMatthew G. Knepley if (Nf > 31) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Number of fields %D limited to 31", Nf); 55557773e69fSMatthew G. Knepley ierr = PetscMemzero(offsets, 32 * sizeof(PetscInt));CHKERRQ(ierr); 55567773e69fSMatthew G. Knepley /* Get points in closure */ 5557923c78e0SToby Isaac ierr = DMPlexGetCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 555805586334SMatthew G. Knepley ierr = PetscSectionGetClosureInversePermutation_Internal(section, (PetscObject) dm, NULL, &clperm);CHKERRQ(ierr); 55597773e69fSMatthew G. Knepley /* Get number of indices and indices per field */ 55607773e69fSMatthew G. Knepley for (p = 0, Nind = 0; p < numPoints*2; p += 2) { 55617773e69fSMatthew G. Knepley PetscInt dof, fdof; 55627773e69fSMatthew G. Knepley 55637773e69fSMatthew G. Knepley ierr = PetscSectionGetDof(section, points[p], &dof);CHKERRQ(ierr); 55647773e69fSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 55657773e69fSMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, points[p], f, &fdof);CHKERRQ(ierr); 55667773e69fSMatthew G. Knepley offsets[f+1] += fdof; 55677773e69fSMatthew G. Knepley } 55687773e69fSMatthew G. Knepley Nind += dof; 55697773e69fSMatthew G. Knepley } 55707773e69fSMatthew G. Knepley for (f = 1; f < Nf; ++f) offsets[f+1] += offsets[f]; 55718ccfff9cSToby Isaac if (Nf && offsets[Nf] != Nind) SETERRQ2(PetscObjectComm((PetscObject) dm), PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", offsets[Nf], Nind); 55724acb8e1eSToby Isaac if (!Nf) offsets[1] = Nind; 55734acb8e1eSToby Isaac /* Get dual space symmetries */ 55744acb8e1eSToby Isaac for (f = 0; f < PetscMax(1,Nf); f++) { 55754acb8e1eSToby Isaac if (Nf) {ierr = PetscSectionGetFieldPointSyms(section,f,numPoints,points,&perms[f],NULL);CHKERRQ(ierr);} 55764acb8e1eSToby Isaac else {ierr = PetscSectionGetPointSyms(section,numPoints,points,&perms[f],NULL);CHKERRQ(ierr);} 55774acb8e1eSToby Isaac } 55787773e69fSMatthew G. Knepley /* Correct for hanging node constraints */ 55797773e69fSMatthew G. Knepley { 55804acb8e1eSToby Isaac ierr = DMPlexAnchorsModifyMat(dm, section, numPoints, Nind, points, perms, NULL, &numPointsNew, &NindNew, &pointsNew, NULL, offsets, PETSC_TRUE);CHKERRQ(ierr); 55817773e69fSMatthew G. Knepley if (numPointsNew) { 55824acb8e1eSToby Isaac for (f = 0; f < PetscMax(1,Nf); f++) { 55834acb8e1eSToby Isaac if (Nf) {ierr = PetscSectionRestoreFieldPointSyms(section,f,numPoints,points,&perms[f],NULL);CHKERRQ(ierr);} 55844acb8e1eSToby Isaac else {ierr = PetscSectionRestorePointSyms(section,numPoints,points,&perms[f],NULL);CHKERRQ(ierr);} 55854acb8e1eSToby Isaac } 55864acb8e1eSToby Isaac for (f = 0; f < PetscMax(1,Nf); f++) { 55874acb8e1eSToby Isaac if (Nf) {ierr = PetscSectionGetFieldPointSyms(section,f,numPointsNew,pointsNew,&perms[f],NULL);CHKERRQ(ierr);} 55884acb8e1eSToby Isaac else {ierr = PetscSectionGetPointSyms(section,numPointsNew,pointsNew,&perms[f],NULL);CHKERRQ(ierr);} 55894acb8e1eSToby Isaac } 5590923c78e0SToby Isaac ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 55917773e69fSMatthew G. Knepley numPoints = numPointsNew; 55927773e69fSMatthew G. Knepley Nind = NindNew; 55937773e69fSMatthew G. Knepley points = pointsNew; 55947773e69fSMatthew G. Knepley } 55957773e69fSMatthew G. Knepley } 55967773e69fSMatthew G. Knepley /* Calculate indices */ 559769291d52SBarry Smith ierr = DMGetWorkArray(dm, Nind, MPIU_INT, indices);CHKERRQ(ierr); 55987773e69fSMatthew G. Knepley if (Nf) { 55996ecaa68aSToby Isaac if (outOffsets) { 56006ecaa68aSToby Isaac PetscInt f; 56016ecaa68aSToby Isaac 560246bdb399SToby Isaac for (f = 0; f <= Nf; f++) { 56036ecaa68aSToby Isaac outOffsets[f] = offsets[f]; 56046ecaa68aSToby Isaac } 56056ecaa68aSToby Isaac } 56064acb8e1eSToby Isaac for (p = 0; p < numPoints; p++) { 56074acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalSection, points[2*p], &globalOff);CHKERRQ(ierr); 560805586334SMatthew G. Knepley DMPlexGetIndicesPointFields_Internal(section, points[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, offsets, PETSC_FALSE, perms, p, clperm, *indices); 56097773e69fSMatthew G. Knepley } 56107773e69fSMatthew G. Knepley } else { 56114acb8e1eSToby Isaac for (p = 0, off = 0; p < numPoints; p++) { 56124acb8e1eSToby Isaac const PetscInt *perm = perms[0] ? perms[0][p] : NULL; 56134acb8e1eSToby Isaac 56144acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalSection, points[2*p], &globalOff);CHKERRQ(ierr); 561505586334SMatthew G. Knepley DMPlexGetIndicesPoint_Internal(section, points[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, perm, clperm, *indices); 56167773e69fSMatthew G. Knepley } 56177773e69fSMatthew G. Knepley } 56187773e69fSMatthew G. Knepley /* Cleanup points */ 56194acb8e1eSToby Isaac for (f = 0; f < PetscMax(1,Nf); f++) { 56204acb8e1eSToby Isaac if (Nf) {ierr = PetscSectionRestoreFieldPointSyms(section,f,numPoints,points,&perms[f],NULL);CHKERRQ(ierr);} 56214acb8e1eSToby Isaac else {ierr = PetscSectionRestorePointSyms(section,numPoints,points,&perms[f],NULL);CHKERRQ(ierr);} 56224acb8e1eSToby Isaac } 56237773e69fSMatthew G. Knepley if (numPointsNew) { 562469291d52SBarry Smith ierr = DMRestoreWorkArray(dm, 2*numPointsNew, MPIU_INT, &pointsNew);CHKERRQ(ierr); 56257773e69fSMatthew G. Knepley } else { 5626923c78e0SToby Isaac ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 56277773e69fSMatthew G. Knepley } 56287773e69fSMatthew G. Knepley if (numIndices) *numIndices = Nind; 56297773e69fSMatthew G. Knepley PetscFunctionReturn(0); 56307773e69fSMatthew G. Knepley } 56317773e69fSMatthew G. Knepley 56327cd05799SMatthew G. Knepley /*@C 56337cd05799SMatthew G. Knepley DMPlexRestoreClosureIndices - Restore the indices in a vector v for all points in the closure of the given point 56347cd05799SMatthew G. Knepley 56357cd05799SMatthew G. Knepley Not collective 56367cd05799SMatthew G. Knepley 56377cd05799SMatthew G. Knepley Input Parameters: 56387cd05799SMatthew G. Knepley + dm - The DM 56397cd05799SMatthew G. Knepley . section - The section describing the layout in v, or NULL to use the default section 56407cd05799SMatthew G. Knepley . globalSection - The section describing the parallel layout in v, or NULL to use the default section 56417cd05799SMatthew G. Knepley . point - The mesh point 56427cd05799SMatthew G. Knepley . numIndices - The number of indices 56437cd05799SMatthew G. Knepley . indices - The indices 56447cd05799SMatthew G. Knepley - outOffsets - Field offset if not NULL 56457cd05799SMatthew G. Knepley 56467cd05799SMatthew G. Knepley Level: advanced 56477cd05799SMatthew G. Knepley 56487cd05799SMatthew G. Knepley .seealso DMPlexGetClosureIndices(), DMPlexVecGetClosure(), DMPlexMatSetClosure() 56497cd05799SMatthew G. Knepley @*/ 565046bdb399SToby Isaac PetscErrorCode DMPlexRestoreClosureIndices(DM dm, PetscSection section, PetscSection globalSection, PetscInt point, PetscInt *numIndices, PetscInt **indices,PetscInt *outOffsets) 56517773e69fSMatthew G. Knepley { 56527773e69fSMatthew G. Knepley PetscErrorCode ierr; 56537773e69fSMatthew G. Knepley 56547773e69fSMatthew G. Knepley PetscFunctionBegin; 56557773e69fSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 56567773e69fSMatthew G. Knepley PetscValidPointer(indices, 5); 565769291d52SBarry Smith ierr = DMRestoreWorkArray(dm, 0, MPIU_INT, indices);CHKERRQ(ierr); 56587773e69fSMatthew G. Knepley PetscFunctionReturn(0); 56597773e69fSMatthew G. Knepley } 56607773e69fSMatthew G. Knepley 56617f5d1fdeSMatthew G. Knepley /*@C 56627f5d1fdeSMatthew G. Knepley DMPlexMatSetClosure - Set an array of the values on the closure of 'point' 56637f5d1fdeSMatthew G. Knepley 56647f5d1fdeSMatthew G. Knepley Not collective 56657f5d1fdeSMatthew G. Knepley 56667f5d1fdeSMatthew G. Knepley Input Parameters: 56677f5d1fdeSMatthew G. Knepley + dm - The DM 5668ebd6d717SJed Brown . section - The section describing the layout in v, or NULL to use the default section 5669ebd6d717SJed Brown . globalSection - The section describing the layout in v, or NULL to use the default global section 56707f5d1fdeSMatthew G. Knepley . A - The matrix 5671eaf898f9SPatrick Sanan . point - The point in the DM 56727f5d1fdeSMatthew G. Knepley . values - The array of values 56737f5d1fdeSMatthew G. Knepley - mode - The insert mode, where INSERT_ALL_VALUES and ADD_ALL_VALUES also overwrite boundary conditions 56747f5d1fdeSMatthew G. Knepley 56757f5d1fdeSMatthew G. Knepley Fortran Notes: 56767f5d1fdeSMatthew G. Knepley This routine is only available in Fortran 90, and you must include petsc.h90 in your code. 56777f5d1fdeSMatthew G. Knepley 56787f5d1fdeSMatthew G. Knepley Level: intermediate 56797f5d1fdeSMatthew G. Knepley 56807f5d1fdeSMatthew G. Knepley .seealso DMPlexVecGetClosure(), DMPlexVecSetClosure() 56817f5d1fdeSMatthew G. Knepley @*/ 56827c1f9639SMatthew G Knepley PetscErrorCode DMPlexMatSetClosure(DM dm, PetscSection section, PetscSection globalSection, Mat A, PetscInt point, const PetscScalar values[], InsertMode mode) 5683552f7358SJed Brown { 5684552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 56851b406b76SMatthew G. Knepley PetscSection clSection; 56861b406b76SMatthew G. Knepley IS clPoints; 5687d3d1a6afSToby Isaac PetscInt *points = NULL, *newPoints; 568805586334SMatthew G. Knepley const PetscInt *clp, *clperm; 5689552f7358SJed Brown PetscInt *indices; 5690552f7358SJed Brown PetscInt offsets[32]; 56914acb8e1eSToby Isaac const PetscInt **perms[32] = {NULL}; 56924acb8e1eSToby Isaac const PetscScalar **flips[32] = {NULL}; 5693923c78e0SToby Isaac PetscInt numFields, numPoints, newNumPoints, numIndices, newNumIndices, dof, off, globalOff, p, f; 56944acb8e1eSToby Isaac PetscScalar *valCopy = NULL; 5695d3d1a6afSToby Isaac PetscScalar *newValues; 5696552f7358SJed Brown PetscErrorCode ierr; 5697552f7358SJed Brown 5698552f7358SJed Brown PetscFunctionBegin; 5699552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5700e87a4003SBarry Smith if (!section) {ierr = DMGetSection(dm, §ion);CHKERRQ(ierr);} 57013dc93601SMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 5702e87a4003SBarry Smith if (!globalSection) {ierr = DMGetGlobalSection(dm, &globalSection);CHKERRQ(ierr);} 57033dc93601SMatthew G. Knepley PetscValidHeaderSpecific(globalSection, PETSC_SECTION_CLASSID, 3); 57043dc93601SMatthew G. Knepley PetscValidHeaderSpecific(A, MAT_CLASSID, 4); 5705552f7358SJed Brown ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 570682f516ccSBarry Smith if (numFields > 31) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Number of fields %D limited to 31", numFields); 5707552f7358SJed Brown ierr = PetscMemzero(offsets, 32 * sizeof(PetscInt));CHKERRQ(ierr); 570805586334SMatthew G. Knepley ierr = PetscSectionGetClosureInversePermutation_Internal(section, (PetscObject) dm, NULL, &clperm);CHKERRQ(ierr); 5709923c78e0SToby Isaac ierr = DMPlexGetCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 5710552f7358SJed Brown for (p = 0, numIndices = 0; p < numPoints*2; p += 2) { 5711552f7358SJed Brown PetscInt fdof; 5712552f7358SJed Brown 5713552f7358SJed Brown ierr = PetscSectionGetDof(section, points[p], &dof);CHKERRQ(ierr); 5714552f7358SJed Brown for (f = 0; f < numFields; ++f) { 5715552f7358SJed Brown ierr = PetscSectionGetFieldDof(section, points[p], f, &fdof);CHKERRQ(ierr); 5716552f7358SJed Brown offsets[f+1] += fdof; 5717552f7358SJed Brown } 5718552f7358SJed Brown numIndices += dof; 5719552f7358SJed Brown } 57200d644c17SKarl Rupp for (f = 1; f < numFields; ++f) offsets[f+1] += offsets[f]; 57210d644c17SKarl Rupp 57228ccfff9cSToby Isaac if (numFields && offsets[numFields] != numIndices) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", offsets[numFields], numIndices); 57234acb8e1eSToby Isaac /* Get symmetries */ 57244acb8e1eSToby Isaac for (f = 0; f < PetscMax(1,numFields); f++) { 57254acb8e1eSToby Isaac if (numFields) {ierr = PetscSectionGetFieldPointSyms(section,f,numPoints,points,&perms[f],&flips[f]);CHKERRQ(ierr);} 57264acb8e1eSToby Isaac else {ierr = PetscSectionGetPointSyms(section,numPoints,points,&perms[f],&flips[f]);CHKERRQ(ierr);} 57274acb8e1eSToby Isaac if (values && flips[f]) { /* may need to apply sign changes to the element matrix */ 57284acb8e1eSToby Isaac PetscInt foffset = offsets[f]; 57294acb8e1eSToby Isaac 57304acb8e1eSToby Isaac for (p = 0; p < numPoints; p++) { 57314acb8e1eSToby Isaac PetscInt point = points[2*p], fdof; 57324acb8e1eSToby Isaac const PetscScalar *flip = flips[f] ? flips[f][p] : NULL; 57334acb8e1eSToby Isaac 57344acb8e1eSToby Isaac if (!numFields) { 57354acb8e1eSToby Isaac ierr = PetscSectionGetDof(section,point,&fdof);CHKERRQ(ierr); 57364acb8e1eSToby Isaac } else { 57374acb8e1eSToby Isaac ierr = PetscSectionGetFieldDof(section,point,f,&fdof);CHKERRQ(ierr); 57384acb8e1eSToby Isaac } 57394acb8e1eSToby Isaac if (flip) { 57404acb8e1eSToby Isaac PetscInt i, j, k; 57414acb8e1eSToby Isaac 57424acb8e1eSToby Isaac if (!valCopy) { 574369291d52SBarry Smith ierr = DMGetWorkArray(dm,numIndices*numIndices,MPIU_SCALAR,&valCopy);CHKERRQ(ierr); 57444acb8e1eSToby Isaac for (j = 0; j < numIndices * numIndices; j++) valCopy[j] = values[j]; 57454acb8e1eSToby Isaac values = valCopy; 57464acb8e1eSToby Isaac } 57474acb8e1eSToby Isaac for (i = 0; i < fdof; i++) { 5748775f7be2SToby Isaac PetscScalar fval = flip[i]; 57494acb8e1eSToby Isaac 57504acb8e1eSToby Isaac for (k = 0; k < numIndices; k++) { 57514acb8e1eSToby Isaac valCopy[numIndices * (foffset + i) + k] *= fval; 57524acb8e1eSToby Isaac valCopy[numIndices * k + (foffset + i)] *= fval; 57534acb8e1eSToby Isaac } 57544acb8e1eSToby Isaac } 57554acb8e1eSToby Isaac } 57564acb8e1eSToby Isaac foffset += fdof; 57574acb8e1eSToby Isaac } 57584acb8e1eSToby Isaac } 57594acb8e1eSToby Isaac } 57604acb8e1eSToby Isaac ierr = DMPlexAnchorsModifyMat(dm,section,numPoints,numIndices,points,perms,values,&newNumPoints,&newNumIndices,&newPoints,&newValues,offsets,PETSC_TRUE);CHKERRQ(ierr); 5761d3d1a6afSToby Isaac if (newNumPoints) { 57624acb8e1eSToby Isaac if (valCopy) { 576369291d52SBarry Smith ierr = DMRestoreWorkArray(dm,numIndices*numIndices,MPIU_SCALAR,&valCopy);CHKERRQ(ierr); 57644acb8e1eSToby Isaac } 57654acb8e1eSToby Isaac for (f = 0; f < PetscMax(1,numFields); f++) { 57664acb8e1eSToby Isaac if (numFields) {ierr = PetscSectionRestoreFieldPointSyms(section,f,numPoints,points,&perms[f],&flips[f]);CHKERRQ(ierr);} 57674acb8e1eSToby Isaac else {ierr = PetscSectionRestorePointSyms(section,numPoints,points,&perms[f],&flips[f]);CHKERRQ(ierr);} 57684acb8e1eSToby Isaac } 57694acb8e1eSToby Isaac for (f = 0; f < PetscMax(1,numFields); f++) { 57704acb8e1eSToby Isaac if (numFields) {ierr = PetscSectionGetFieldPointSyms(section,f,newNumPoints,newPoints,&perms[f],&flips[f]);CHKERRQ(ierr);} 57714acb8e1eSToby Isaac else {ierr = PetscSectionGetPointSyms(section,newNumPoints,newPoints,&perms[f],&flips[f]);CHKERRQ(ierr);} 57724acb8e1eSToby Isaac } 5773923c78e0SToby Isaac ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 5774d3d1a6afSToby Isaac numPoints = newNumPoints; 5775d3d1a6afSToby Isaac numIndices = newNumIndices; 5776d3d1a6afSToby Isaac points = newPoints; 5777d3d1a6afSToby Isaac values = newValues; 5778d3d1a6afSToby Isaac } 577969291d52SBarry Smith ierr = DMGetWorkArray(dm, numIndices, MPIU_INT, &indices);CHKERRQ(ierr); 5780552f7358SJed Brown if (numFields) { 57817e29afd2SMatthew G. Knepley PetscBool useFieldOffsets; 57827e29afd2SMatthew G. Knepley 57837e29afd2SMatthew G. Knepley ierr = PetscSectionGetUseFieldOffsets(globalSection, &useFieldOffsets);CHKERRQ(ierr); 57847e29afd2SMatthew G. Knepley if (useFieldOffsets) { 57857e29afd2SMatthew G. Knepley for (p = 0; p < numPoints; p++) { 578605586334SMatthew G. Knepley DMPlexGetIndicesPointFieldsSplit_Internal(section, globalSection, points[2*p], offsets, PETSC_FALSE, perms, p, clperm, indices); 57877e29afd2SMatthew G. Knepley } 57887e29afd2SMatthew G. Knepley } else { 57894acb8e1eSToby Isaac for (p = 0; p < numPoints; p++) { 57904acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalSection, points[2*p], &globalOff);CHKERRQ(ierr); 579105586334SMatthew G. Knepley DMPlexGetIndicesPointFields_Internal(section, points[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, offsets, PETSC_FALSE, perms, p, clperm, indices); 5792552f7358SJed Brown } 57937e29afd2SMatthew G. Knepley } 5794552f7358SJed Brown } else { 57954acb8e1eSToby Isaac for (p = 0, off = 0; p < numPoints; p++) { 57964acb8e1eSToby Isaac const PetscInt *perm = perms[0] ? perms[0][p] : NULL; 57974acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalSection, points[2*p], &globalOff);CHKERRQ(ierr); 579805586334SMatthew G. Knepley DMPlexGetIndicesPoint_Internal(section, points[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, perm, clperm, indices); 5799552f7358SJed Brown } 5800552f7358SJed Brown } 5801b0ecff45SMatthew G. Knepley if (mesh->printSetValues) {ierr = DMPlexPrintMatSetValues(PETSC_VIEWER_STDOUT_SELF, A, point, numIndices, indices, 0, NULL, values);CHKERRQ(ierr);} 5802552f7358SJed Brown ierr = MatSetValues(A, numIndices, indices, numIndices, indices, values, mode); 5803ab1d0545SMatthew G. Knepley if (mesh->printFEM > 1) { 5804ab1d0545SMatthew G. Knepley PetscInt i; 5805ab1d0545SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " Indices:");CHKERRQ(ierr); 58068ccfff9cSToby Isaac for (i = 0; i < numIndices; ++i) {ierr = PetscPrintf(PETSC_COMM_SELF, " %D", indices[i]);CHKERRQ(ierr);} 5807ab1d0545SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 5808ab1d0545SMatthew G. Knepley } 5809552f7358SJed Brown if (ierr) { 5810552f7358SJed Brown PetscMPIInt rank; 5811552f7358SJed Brown PetscErrorCode ierr2; 5812552f7358SJed Brown 581382f516ccSBarry Smith ierr2 = MPI_Comm_rank(PetscObjectComm((PetscObject)A), &rank);CHKERRQ(ierr2); 5814e4b003c7SBarry Smith ierr2 = (*PetscErrorPrintf)("[%d]ERROR in DMPlexMatSetClosure\n", rank);CHKERRQ(ierr2); 5815b0ecff45SMatthew G. Knepley ierr2 = DMPlexPrintMatSetValues(PETSC_VIEWER_STDERR_SELF, A, point, numIndices, indices, 0, NULL, values);CHKERRQ(ierr2); 581669291d52SBarry Smith ierr2 = DMRestoreWorkArray(dm, numIndices, MPIU_INT, &indices);CHKERRQ(ierr2); 5817552f7358SJed Brown CHKERRQ(ierr); 5818552f7358SJed Brown } 58194acb8e1eSToby Isaac for (f = 0; f < PetscMax(1,numFields); f++) { 58204acb8e1eSToby Isaac if (numFields) {ierr = PetscSectionRestoreFieldPointSyms(section,f,numPoints,points,&perms[f],&flips[f]);CHKERRQ(ierr);} 58214acb8e1eSToby Isaac else {ierr = PetscSectionRestorePointSyms(section,numPoints,points,&perms[f],&flips[f]);CHKERRQ(ierr);} 58224acb8e1eSToby Isaac } 5823d3d1a6afSToby Isaac if (newNumPoints) { 582469291d52SBarry Smith ierr = DMRestoreWorkArray(dm,newNumIndices*newNumIndices,MPIU_SCALAR,&newValues);CHKERRQ(ierr); 582569291d52SBarry Smith ierr = DMRestoreWorkArray(dm,2*newNumPoints,MPIU_INT,&newPoints);CHKERRQ(ierr); 5826d3d1a6afSToby Isaac } 5827d3d1a6afSToby Isaac else { 58284acb8e1eSToby Isaac if (valCopy) { 582969291d52SBarry Smith ierr = DMRestoreWorkArray(dm,numIndices*numIndices,MPIU_SCALAR,&valCopy);CHKERRQ(ierr); 58304acb8e1eSToby Isaac } 5831923c78e0SToby Isaac ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 5832d3d1a6afSToby Isaac } 583369291d52SBarry Smith ierr = DMRestoreWorkArray(dm, numIndices, MPIU_INT, &indices);CHKERRQ(ierr); 5834552f7358SJed Brown PetscFunctionReturn(0); 5835552f7358SJed Brown } 5836552f7358SJed Brown 5837de41b84cSMatthew G. Knepley PetscErrorCode DMPlexMatSetClosureRefined(DM dmf, PetscSection fsection, PetscSection globalFSection, DM dmc, PetscSection csection, PetscSection globalCSection, Mat A, PetscInt point, const PetscScalar values[], InsertMode mode) 5838de41b84cSMatthew G. Knepley { 5839de41b84cSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dmf->data; 5840de41b84cSMatthew G. Knepley PetscInt *fpoints = NULL, *ftotpoints = NULL; 5841de41b84cSMatthew G. Knepley PetscInt *cpoints = NULL; 5842de41b84cSMatthew G. Knepley PetscInt *findices, *cindices; 584305586334SMatthew G. Knepley const PetscInt *fclperm, *cclperm; 5844de41b84cSMatthew G. Knepley PetscInt foffsets[32], coffsets[32]; 5845de41b84cSMatthew G. Knepley CellRefiner cellRefiner; 58464ca5e9f5SMatthew G. Knepley PetscInt numFields, numSubcells, maxFPoints, numFPoints, numCPoints, numFIndices, numCIndices, dof, off, globalOff, pStart, pEnd, p, q, r, s, f; 5847de41b84cSMatthew G. Knepley PetscErrorCode ierr; 5848de41b84cSMatthew G. Knepley 5849de41b84cSMatthew G. Knepley PetscFunctionBegin; 5850de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(dmf, DM_CLASSID, 1); 5851de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(dmc, DM_CLASSID, 4); 5852e87a4003SBarry Smith if (!fsection) {ierr = DMGetSection(dmf, &fsection);CHKERRQ(ierr);} 5853de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(fsection, PETSC_SECTION_CLASSID, 2); 5854e87a4003SBarry Smith if (!csection) {ierr = DMGetSection(dmc, &csection);CHKERRQ(ierr);} 5855de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(csection, PETSC_SECTION_CLASSID, 5); 5856e87a4003SBarry Smith if (!globalFSection) {ierr = DMGetGlobalSection(dmf, &globalFSection);CHKERRQ(ierr);} 5857de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(globalFSection, PETSC_SECTION_CLASSID, 3); 5858e87a4003SBarry Smith if (!globalCSection) {ierr = DMGetGlobalSection(dmc, &globalCSection);CHKERRQ(ierr);} 5859de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(globalCSection, PETSC_SECTION_CLASSID, 6); 5860de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(A, MAT_CLASSID, 7); 5861de41b84cSMatthew G. Knepley ierr = PetscSectionGetNumFields(fsection, &numFields);CHKERRQ(ierr); 5862de41b84cSMatthew G. Knepley if (numFields > 31) SETERRQ1(PetscObjectComm((PetscObject)dmf), PETSC_ERR_ARG_OUTOFRANGE, "Number of fields %D limited to 31", numFields); 5863de41b84cSMatthew G. Knepley ierr = PetscMemzero(foffsets, 32 * sizeof(PetscInt));CHKERRQ(ierr); 5864de41b84cSMatthew G. Knepley ierr = PetscMemzero(coffsets, 32 * sizeof(PetscInt));CHKERRQ(ierr); 586505586334SMatthew G. Knepley ierr = PetscSectionGetClosureInversePermutation_Internal(fsection, (PetscObject) dmf, NULL, &fclperm);CHKERRQ(ierr); 586605586334SMatthew G. Knepley ierr = PetscSectionGetClosureInversePermutation_Internal(csection, (PetscObject) dmc, NULL, &cclperm);CHKERRQ(ierr); 5867de41b84cSMatthew G. Knepley /* Column indices */ 5868de41b84cSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dmc, point, PETSC_TRUE, &numCPoints, &cpoints);CHKERRQ(ierr); 58694ca5e9f5SMatthew G. Knepley maxFPoints = numCPoints; 5870de41b84cSMatthew G. Knepley /* Compress out points not in the section */ 5871de41b84cSMatthew G. Knepley /* TODO: Squeeze out points with 0 dof as well */ 5872de41b84cSMatthew G. Knepley ierr = PetscSectionGetChart(csection, &pStart, &pEnd);CHKERRQ(ierr); 5873de41b84cSMatthew G. Knepley for (p = 0, q = 0; p < numCPoints*2; p += 2) { 5874de41b84cSMatthew G. Knepley if ((cpoints[p] >= pStart) && (cpoints[p] < pEnd)) { 5875de41b84cSMatthew G. Knepley cpoints[q*2] = cpoints[p]; 5876de41b84cSMatthew G. Knepley cpoints[q*2+1] = cpoints[p+1]; 5877de41b84cSMatthew G. Knepley ++q; 5878de41b84cSMatthew G. Knepley } 5879de41b84cSMatthew G. Knepley } 5880de41b84cSMatthew G. Knepley numCPoints = q; 5881de41b84cSMatthew G. Knepley for (p = 0, numCIndices = 0; p < numCPoints*2; p += 2) { 5882de41b84cSMatthew G. Knepley PetscInt fdof; 5883de41b84cSMatthew G. Knepley 5884de41b84cSMatthew G. Knepley ierr = PetscSectionGetDof(csection, cpoints[p], &dof);CHKERRQ(ierr); 58854ca5e9f5SMatthew G. Knepley if (!dof) continue; 5886de41b84cSMatthew G. Knepley for (f = 0; f < numFields; ++f) { 5887de41b84cSMatthew G. Knepley ierr = PetscSectionGetFieldDof(csection, cpoints[p], f, &fdof);CHKERRQ(ierr); 5888de41b84cSMatthew G. Knepley coffsets[f+1] += fdof; 5889de41b84cSMatthew G. Knepley } 5890de41b84cSMatthew G. Knepley numCIndices += dof; 5891de41b84cSMatthew G. Knepley } 5892de41b84cSMatthew G. Knepley for (f = 1; f < numFields; ++f) coffsets[f+1] += coffsets[f]; 5893de41b84cSMatthew G. Knepley /* Row indices */ 5894de41b84cSMatthew G. Knepley ierr = DMPlexGetCellRefiner_Internal(dmc, &cellRefiner);CHKERRQ(ierr); 5895de41b84cSMatthew G. Knepley ierr = CellRefinerGetAffineTransforms_Internal(cellRefiner, &numSubcells, NULL, NULL, NULL);CHKERRQ(ierr); 589669291d52SBarry Smith ierr = DMGetWorkArray(dmf, maxFPoints*2*numSubcells, MPIU_INT, &ftotpoints);CHKERRQ(ierr); 5897de41b84cSMatthew G. Knepley for (r = 0, q = 0; r < numSubcells; ++r) { 5898de41b84cSMatthew G. Knepley /* TODO Map from coarse to fine cells */ 5899de41b84cSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dmf, point*numSubcells + r, PETSC_TRUE, &numFPoints, &fpoints);CHKERRQ(ierr); 5900de41b84cSMatthew G. Knepley /* Compress out points not in the section */ 5901de41b84cSMatthew G. Knepley ierr = PetscSectionGetChart(fsection, &pStart, &pEnd);CHKERRQ(ierr); 5902de41b84cSMatthew G. Knepley for (p = 0; p < numFPoints*2; p += 2) { 5903de41b84cSMatthew G. Knepley if ((fpoints[p] >= pStart) && (fpoints[p] < pEnd)) { 59044ca5e9f5SMatthew G. Knepley ierr = PetscSectionGetDof(fsection, fpoints[p], &dof);CHKERRQ(ierr); 59054ca5e9f5SMatthew G. Knepley if (!dof) continue; 59064ca5e9f5SMatthew G. Knepley for (s = 0; s < q; ++s) if (fpoints[p] == ftotpoints[s*2]) break; 59074ca5e9f5SMatthew G. Knepley if (s < q) continue; 5908de41b84cSMatthew G. Knepley ftotpoints[q*2] = fpoints[p]; 5909de41b84cSMatthew G. Knepley ftotpoints[q*2+1] = fpoints[p+1]; 5910de41b84cSMatthew G. Knepley ++q; 5911de41b84cSMatthew G. Knepley } 5912de41b84cSMatthew G. Knepley } 5913de41b84cSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dmf, point, PETSC_TRUE, &numFPoints, &fpoints);CHKERRQ(ierr); 5914de41b84cSMatthew G. Knepley } 5915de41b84cSMatthew G. Knepley numFPoints = q; 5916de41b84cSMatthew G. Knepley for (p = 0, numFIndices = 0; p < numFPoints*2; p += 2) { 5917de41b84cSMatthew G. Knepley PetscInt fdof; 5918de41b84cSMatthew G. Knepley 5919de41b84cSMatthew G. Knepley ierr = PetscSectionGetDof(fsection, ftotpoints[p], &dof);CHKERRQ(ierr); 59204ca5e9f5SMatthew G. Knepley if (!dof) continue; 5921de41b84cSMatthew G. Knepley for (f = 0; f < numFields; ++f) { 5922de41b84cSMatthew G. Knepley ierr = PetscSectionGetFieldDof(fsection, ftotpoints[p], f, &fdof);CHKERRQ(ierr); 5923de41b84cSMatthew G. Knepley foffsets[f+1] += fdof; 5924de41b84cSMatthew G. Knepley } 5925de41b84cSMatthew G. Knepley numFIndices += dof; 5926de41b84cSMatthew G. Knepley } 5927de41b84cSMatthew G. Knepley for (f = 1; f < numFields; ++f) foffsets[f+1] += foffsets[f]; 5928de41b84cSMatthew G. Knepley 59298ccfff9cSToby Isaac if (numFields && foffsets[numFields] != numFIndices) SETERRQ2(PetscObjectComm((PetscObject)dmf), PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", foffsets[numFields], numFIndices); 59308ccfff9cSToby Isaac if (numFields && coffsets[numFields] != numCIndices) SETERRQ2(PetscObjectComm((PetscObject)dmc), PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", coffsets[numFields], numCIndices); 593169291d52SBarry Smith ierr = DMGetWorkArray(dmf, numFIndices, MPIU_INT, &findices);CHKERRQ(ierr); 593269291d52SBarry Smith ierr = DMGetWorkArray(dmc, numCIndices, MPIU_INT, &cindices);CHKERRQ(ierr); 5933de41b84cSMatthew G. Knepley if (numFields) { 59344acb8e1eSToby Isaac const PetscInt **permsF[32] = {NULL}; 59354acb8e1eSToby Isaac const PetscInt **permsC[32] = {NULL}; 59364acb8e1eSToby Isaac 59374acb8e1eSToby Isaac for (f = 0; f < numFields; f++) { 59384acb8e1eSToby Isaac ierr = PetscSectionGetFieldPointSyms(fsection,f,numFPoints,ftotpoints,&permsF[f],NULL);CHKERRQ(ierr); 59394acb8e1eSToby Isaac ierr = PetscSectionGetFieldPointSyms(csection,f,numCPoints,cpoints,&permsC[f],NULL);CHKERRQ(ierr); 5940de41b84cSMatthew G. Knepley } 59414acb8e1eSToby Isaac for (p = 0; p < numFPoints; p++) { 59424acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalFSection, ftotpoints[2*p], &globalOff);CHKERRQ(ierr); 594305586334SMatthew G. Knepley ierr = DMPlexGetIndicesPointFields_Internal(fsection, ftotpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, foffsets, PETSC_FALSE, permsF, p, fclperm, findices);CHKERRQ(ierr); 59444acb8e1eSToby Isaac } 59454acb8e1eSToby Isaac for (p = 0; p < numCPoints; p++) { 59464acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalCSection, cpoints[2*p], &globalOff);CHKERRQ(ierr); 594705586334SMatthew G. Knepley ierr = DMPlexGetIndicesPointFields_Internal(csection, cpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, coffsets, PETSC_FALSE, permsC, p, cclperm, cindices);CHKERRQ(ierr); 59484acb8e1eSToby Isaac } 59494acb8e1eSToby Isaac for (f = 0; f < numFields; f++) { 59504acb8e1eSToby Isaac ierr = PetscSectionRestoreFieldPointSyms(fsection,f,numFPoints,ftotpoints,&permsF[f],NULL);CHKERRQ(ierr); 59514acb8e1eSToby Isaac ierr = PetscSectionRestoreFieldPointSyms(csection,f,numCPoints,cpoints,&permsC[f],NULL);CHKERRQ(ierr); 5952de41b84cSMatthew G. Knepley } 5953de41b84cSMatthew G. Knepley } else { 59544acb8e1eSToby Isaac const PetscInt **permsF = NULL; 59554acb8e1eSToby Isaac const PetscInt **permsC = NULL; 59564acb8e1eSToby Isaac 59574acb8e1eSToby Isaac ierr = PetscSectionGetPointSyms(fsection,numFPoints,ftotpoints,&permsF,NULL);CHKERRQ(ierr); 59584acb8e1eSToby Isaac ierr = PetscSectionGetPointSyms(csection,numCPoints,cpoints,&permsC,NULL);CHKERRQ(ierr); 59594acb8e1eSToby Isaac for (p = 0, off = 0; p < numFPoints; p++) { 59604acb8e1eSToby Isaac const PetscInt *perm = permsF ? permsF[p] : NULL; 59614acb8e1eSToby Isaac 59624acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalFSection, ftotpoints[2*p], &globalOff);CHKERRQ(ierr); 596305586334SMatthew G. Knepley ierr = DMPlexGetIndicesPoint_Internal(fsection, ftotpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, perm, fclperm, findices);CHKERRQ(ierr); 5964de41b84cSMatthew G. Knepley } 59654acb8e1eSToby Isaac for (p = 0, off = 0; p < numCPoints; p++) { 59664acb8e1eSToby Isaac const PetscInt *perm = permsC ? permsC[p] : NULL; 59674acb8e1eSToby Isaac 59684acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalCSection, cpoints[2*p], &globalOff);CHKERRQ(ierr); 596905586334SMatthew G. Knepley ierr = DMPlexGetIndicesPoint_Internal(csection, cpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, perm, cclperm, cindices);CHKERRQ(ierr); 5970de41b84cSMatthew G. Knepley } 59714acb8e1eSToby Isaac ierr = PetscSectionRestorePointSyms(fsection,numFPoints,ftotpoints,&permsF,NULL);CHKERRQ(ierr); 59724acb8e1eSToby Isaac ierr = PetscSectionRestorePointSyms(csection,numCPoints,cpoints,&permsC,NULL);CHKERRQ(ierr); 5973de41b84cSMatthew G. Knepley } 5974de41b84cSMatthew G. Knepley if (mesh->printSetValues) {ierr = DMPlexPrintMatSetValues(PETSC_VIEWER_STDOUT_SELF, A, point, numFIndices, findices, numCIndices, cindices, values);CHKERRQ(ierr);} 59754acb8e1eSToby Isaac /* TODO: flips */ 5976de41b84cSMatthew G. Knepley ierr = MatSetValues(A, numFIndices, findices, numCIndices, cindices, values, mode); 5977de41b84cSMatthew G. Knepley if (ierr) { 5978de41b84cSMatthew G. Knepley PetscMPIInt rank; 5979de41b84cSMatthew G. Knepley PetscErrorCode ierr2; 5980de41b84cSMatthew G. Knepley 5981de41b84cSMatthew G. Knepley ierr2 = MPI_Comm_rank(PetscObjectComm((PetscObject)A), &rank);CHKERRQ(ierr2); 5982e4b003c7SBarry Smith ierr2 = (*PetscErrorPrintf)("[%d]ERROR in DMPlexMatSetClosure\n", rank);CHKERRQ(ierr2); 5983de41b84cSMatthew G. Knepley ierr2 = DMPlexPrintMatSetValues(PETSC_VIEWER_STDERR_SELF, A, point, numFIndices, findices, numCIndices, cindices, values);CHKERRQ(ierr2); 598469291d52SBarry Smith ierr2 = DMRestoreWorkArray(dmf, numFIndices, MPIU_INT, &findices);CHKERRQ(ierr2); 598569291d52SBarry Smith ierr2 = DMRestoreWorkArray(dmc, numCIndices, MPIU_INT, &cindices);CHKERRQ(ierr2); 5986de41b84cSMatthew G. Knepley CHKERRQ(ierr); 5987de41b84cSMatthew G. Knepley } 598869291d52SBarry Smith ierr = DMRestoreWorkArray(dmf, numCPoints*2*4, MPIU_INT, &ftotpoints);CHKERRQ(ierr); 5989de41b84cSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dmc, point, PETSC_TRUE, &numCPoints, &cpoints);CHKERRQ(ierr); 599069291d52SBarry Smith ierr = DMRestoreWorkArray(dmf, numFIndices, MPIU_INT, &findices);CHKERRQ(ierr); 599169291d52SBarry Smith ierr = DMRestoreWorkArray(dmc, numCIndices, MPIU_INT, &cindices);CHKERRQ(ierr); 5992de41b84cSMatthew G. Knepley PetscFunctionReturn(0); 5993de41b84cSMatthew G. Knepley } 5994de41b84cSMatthew G. Knepley 59957c927364SMatthew G. Knepley PetscErrorCode DMPlexMatGetClosureIndicesRefined(DM dmf, PetscSection fsection, PetscSection globalFSection, DM dmc, PetscSection csection, PetscSection globalCSection, PetscInt point, PetscInt cindices[], PetscInt findices[]) 59967c927364SMatthew G. Knepley { 59977c927364SMatthew G. Knepley PetscInt *fpoints = NULL, *ftotpoints = NULL; 59987c927364SMatthew G. Knepley PetscInt *cpoints = NULL; 59997c927364SMatthew G. Knepley PetscInt foffsets[32], coffsets[32]; 600005586334SMatthew G. Knepley const PetscInt *fclperm, *cclperm; 60017c927364SMatthew G. Knepley CellRefiner cellRefiner; 60027c927364SMatthew G. Knepley PetscInt numFields, numSubcells, maxFPoints, numFPoints, numCPoints, numFIndices, numCIndices, dof, off, globalOff, pStart, pEnd, p, q, r, s, f; 60037c927364SMatthew G. Knepley PetscErrorCode ierr; 60047c927364SMatthew G. Knepley 60057c927364SMatthew G. Knepley PetscFunctionBegin; 60067c927364SMatthew G. Knepley PetscValidHeaderSpecific(dmf, DM_CLASSID, 1); 60077c927364SMatthew G. Knepley PetscValidHeaderSpecific(dmc, DM_CLASSID, 4); 6008e87a4003SBarry Smith if (!fsection) {ierr = DMGetSection(dmf, &fsection);CHKERRQ(ierr);} 60097c927364SMatthew G. Knepley PetscValidHeaderSpecific(fsection, PETSC_SECTION_CLASSID, 2); 6010e87a4003SBarry Smith if (!csection) {ierr = DMGetSection(dmc, &csection);CHKERRQ(ierr);} 60117c927364SMatthew G. Knepley PetscValidHeaderSpecific(csection, PETSC_SECTION_CLASSID, 5); 6012e87a4003SBarry Smith if (!globalFSection) {ierr = DMGetGlobalSection(dmf, &globalFSection);CHKERRQ(ierr);} 60137c927364SMatthew G. Knepley PetscValidHeaderSpecific(globalFSection, PETSC_SECTION_CLASSID, 3); 6014e87a4003SBarry Smith if (!globalCSection) {ierr = DMGetGlobalSection(dmc, &globalCSection);CHKERRQ(ierr);} 60157c927364SMatthew G. Knepley PetscValidHeaderSpecific(globalCSection, PETSC_SECTION_CLASSID, 6); 60167c927364SMatthew G. Knepley ierr = PetscSectionGetNumFields(fsection, &numFields);CHKERRQ(ierr); 60177c927364SMatthew G. Knepley if (numFields > 31) SETERRQ1(PetscObjectComm((PetscObject)dmf), PETSC_ERR_ARG_OUTOFRANGE, "Number of fields %D limited to 31", numFields); 60187c927364SMatthew G. Knepley ierr = PetscMemzero(foffsets, 32 * sizeof(PetscInt));CHKERRQ(ierr); 60197c927364SMatthew G. Knepley ierr = PetscMemzero(coffsets, 32 * sizeof(PetscInt));CHKERRQ(ierr); 602005586334SMatthew G. Knepley ierr = PetscSectionGetClosureInversePermutation_Internal(fsection, (PetscObject) dmf, NULL, &fclperm);CHKERRQ(ierr); 602105586334SMatthew G. Knepley ierr = PetscSectionGetClosureInversePermutation_Internal(csection, (PetscObject) dmc, NULL, &cclperm);CHKERRQ(ierr); 60227c927364SMatthew G. Knepley /* Column indices */ 60237c927364SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dmc, point, PETSC_TRUE, &numCPoints, &cpoints);CHKERRQ(ierr); 60247c927364SMatthew G. Knepley maxFPoints = numCPoints; 60257c927364SMatthew G. Knepley /* Compress out points not in the section */ 60267c927364SMatthew G. Knepley /* TODO: Squeeze out points with 0 dof as well */ 60277c927364SMatthew G. Knepley ierr = PetscSectionGetChart(csection, &pStart, &pEnd);CHKERRQ(ierr); 60287c927364SMatthew G. Knepley for (p = 0, q = 0; p < numCPoints*2; p += 2) { 60297c927364SMatthew G. Knepley if ((cpoints[p] >= pStart) && (cpoints[p] < pEnd)) { 60307c927364SMatthew G. Knepley cpoints[q*2] = cpoints[p]; 60317c927364SMatthew G. Knepley cpoints[q*2+1] = cpoints[p+1]; 60327c927364SMatthew G. Knepley ++q; 60337c927364SMatthew G. Knepley } 60347c927364SMatthew G. Knepley } 60357c927364SMatthew G. Knepley numCPoints = q; 60367c927364SMatthew G. Knepley for (p = 0, numCIndices = 0; p < numCPoints*2; p += 2) { 60377c927364SMatthew G. Knepley PetscInt fdof; 60387c927364SMatthew G. Knepley 60397c927364SMatthew G. Knepley ierr = PetscSectionGetDof(csection, cpoints[p], &dof);CHKERRQ(ierr); 60407c927364SMatthew G. Knepley if (!dof) continue; 60417c927364SMatthew G. Knepley for (f = 0; f < numFields; ++f) { 60427c927364SMatthew G. Knepley ierr = PetscSectionGetFieldDof(csection, cpoints[p], f, &fdof);CHKERRQ(ierr); 60437c927364SMatthew G. Knepley coffsets[f+1] += fdof; 60447c927364SMatthew G. Knepley } 60457c927364SMatthew G. Knepley numCIndices += dof; 60467c927364SMatthew G. Knepley } 60477c927364SMatthew G. Knepley for (f = 1; f < numFields; ++f) coffsets[f+1] += coffsets[f]; 60487c927364SMatthew G. Knepley /* Row indices */ 60497c927364SMatthew G. Knepley ierr = DMPlexGetCellRefiner_Internal(dmc, &cellRefiner);CHKERRQ(ierr); 60507c927364SMatthew G. Knepley ierr = CellRefinerGetAffineTransforms_Internal(cellRefiner, &numSubcells, NULL, NULL, NULL);CHKERRQ(ierr); 605169291d52SBarry Smith ierr = DMGetWorkArray(dmf, maxFPoints*2*numSubcells, MPIU_INT, &ftotpoints);CHKERRQ(ierr); 60527c927364SMatthew G. Knepley for (r = 0, q = 0; r < numSubcells; ++r) { 60537c927364SMatthew G. Knepley /* TODO Map from coarse to fine cells */ 60547c927364SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dmf, point*numSubcells + r, PETSC_TRUE, &numFPoints, &fpoints);CHKERRQ(ierr); 60557c927364SMatthew G. Knepley /* Compress out points not in the section */ 60567c927364SMatthew G. Knepley ierr = PetscSectionGetChart(fsection, &pStart, &pEnd);CHKERRQ(ierr); 60577c927364SMatthew G. Knepley for (p = 0; p < numFPoints*2; p += 2) { 60587c927364SMatthew G. Knepley if ((fpoints[p] >= pStart) && (fpoints[p] < pEnd)) { 60597c927364SMatthew G. Knepley ierr = PetscSectionGetDof(fsection, fpoints[p], &dof);CHKERRQ(ierr); 60607c927364SMatthew G. Knepley if (!dof) continue; 60617c927364SMatthew G. Knepley for (s = 0; s < q; ++s) if (fpoints[p] == ftotpoints[s*2]) break; 60627c927364SMatthew G. Knepley if (s < q) continue; 60637c927364SMatthew G. Knepley ftotpoints[q*2] = fpoints[p]; 60647c927364SMatthew G. Knepley ftotpoints[q*2+1] = fpoints[p+1]; 60657c927364SMatthew G. Knepley ++q; 60667c927364SMatthew G. Knepley } 60677c927364SMatthew G. Knepley } 60687c927364SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dmf, point, PETSC_TRUE, &numFPoints, &fpoints);CHKERRQ(ierr); 60697c927364SMatthew G. Knepley } 60707c927364SMatthew G. Knepley numFPoints = q; 60717c927364SMatthew G. Knepley for (p = 0, numFIndices = 0; p < numFPoints*2; p += 2) { 60727c927364SMatthew G. Knepley PetscInt fdof; 60737c927364SMatthew G. Knepley 60747c927364SMatthew G. Knepley ierr = PetscSectionGetDof(fsection, ftotpoints[p], &dof);CHKERRQ(ierr); 60757c927364SMatthew G. Knepley if (!dof) continue; 60767c927364SMatthew G. Knepley for (f = 0; f < numFields; ++f) { 60777c927364SMatthew G. Knepley ierr = PetscSectionGetFieldDof(fsection, ftotpoints[p], f, &fdof);CHKERRQ(ierr); 60787c927364SMatthew G. Knepley foffsets[f+1] += fdof; 60797c927364SMatthew G. Knepley } 60807c927364SMatthew G. Knepley numFIndices += dof; 60817c927364SMatthew G. Knepley } 60827c927364SMatthew G. Knepley for (f = 1; f < numFields; ++f) foffsets[f+1] += foffsets[f]; 60837c927364SMatthew G. Knepley 60848ccfff9cSToby Isaac if (numFields && foffsets[numFields] != numFIndices) SETERRQ2(PetscObjectComm((PetscObject)dmf), PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", foffsets[numFields], numFIndices); 60858ccfff9cSToby Isaac if (numFields && coffsets[numFields] != numCIndices) SETERRQ2(PetscObjectComm((PetscObject)dmc), PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", coffsets[numFields], numCIndices); 60867c927364SMatthew G. Knepley if (numFields) { 60874acb8e1eSToby Isaac const PetscInt **permsF[32] = {NULL}; 60884acb8e1eSToby Isaac const PetscInt **permsC[32] = {NULL}; 60894acb8e1eSToby Isaac 60904acb8e1eSToby Isaac for (f = 0; f < numFields; f++) { 60914acb8e1eSToby Isaac ierr = PetscSectionGetFieldPointSyms(fsection,f,numFPoints,ftotpoints,&permsF[f],NULL);CHKERRQ(ierr); 60924acb8e1eSToby Isaac ierr = PetscSectionGetFieldPointSyms(csection,f,numCPoints,cpoints,&permsC[f],NULL);CHKERRQ(ierr); 60937c927364SMatthew G. Knepley } 60944acb8e1eSToby Isaac for (p = 0; p < numFPoints; p++) { 60954acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalFSection, ftotpoints[2*p], &globalOff);CHKERRQ(ierr); 609605586334SMatthew G. Knepley DMPlexGetIndicesPointFields_Internal(fsection, ftotpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, foffsets, PETSC_FALSE, permsF, p, fclperm, findices); 60974acb8e1eSToby Isaac } 60984acb8e1eSToby Isaac for (p = 0; p < numCPoints; p++) { 60994acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalCSection, cpoints[2*p], &globalOff);CHKERRQ(ierr); 610005586334SMatthew G. Knepley DMPlexGetIndicesPointFields_Internal(csection, cpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, coffsets, PETSC_FALSE, permsC, p, cclperm, cindices); 61014acb8e1eSToby Isaac } 61024acb8e1eSToby Isaac for (f = 0; f < numFields; f++) { 61034acb8e1eSToby Isaac ierr = PetscSectionRestoreFieldPointSyms(fsection,f,numFPoints,ftotpoints,&permsF[f],NULL);CHKERRQ(ierr); 61044acb8e1eSToby Isaac ierr = PetscSectionRestoreFieldPointSyms(csection,f,numCPoints,cpoints,&permsC[f],NULL);CHKERRQ(ierr); 61057c927364SMatthew G. Knepley } 61067c927364SMatthew G. Knepley } else { 61074acb8e1eSToby Isaac const PetscInt **permsF = NULL; 61084acb8e1eSToby Isaac const PetscInt **permsC = NULL; 61094acb8e1eSToby Isaac 61104acb8e1eSToby Isaac ierr = PetscSectionGetPointSyms(fsection,numFPoints,ftotpoints,&permsF,NULL);CHKERRQ(ierr); 61114acb8e1eSToby Isaac ierr = PetscSectionGetPointSyms(csection,numCPoints,cpoints,&permsC,NULL);CHKERRQ(ierr); 61124acb8e1eSToby Isaac for (p = 0, off = 0; p < numFPoints; p++) { 61134acb8e1eSToby Isaac const PetscInt *perm = permsF ? permsF[p] : NULL; 61144acb8e1eSToby Isaac 61154acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalFSection, ftotpoints[2*p], &globalOff);CHKERRQ(ierr); 611605586334SMatthew G. Knepley DMPlexGetIndicesPoint_Internal(fsection, ftotpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, perm, fclperm, findices); 61177c927364SMatthew G. Knepley } 61184acb8e1eSToby Isaac for (p = 0, off = 0; p < numCPoints; p++) { 61194acb8e1eSToby Isaac const PetscInt *perm = permsC ? permsC[p] : NULL; 61204acb8e1eSToby Isaac 61214acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalCSection, cpoints[2*p], &globalOff);CHKERRQ(ierr); 612205586334SMatthew G. Knepley DMPlexGetIndicesPoint_Internal(csection, cpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, perm, cclperm, cindices); 61237c927364SMatthew G. Knepley } 61244acb8e1eSToby Isaac ierr = PetscSectionRestorePointSyms(fsection,numFPoints,ftotpoints,&permsF,NULL);CHKERRQ(ierr); 61254acb8e1eSToby Isaac ierr = PetscSectionRestorePointSyms(csection,numCPoints,cpoints,&permsC,NULL);CHKERRQ(ierr); 61267c927364SMatthew G. Knepley } 612769291d52SBarry Smith ierr = DMRestoreWorkArray(dmf, numCPoints*2*4, MPIU_INT, &ftotpoints);CHKERRQ(ierr); 61287c927364SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dmc, point, PETSC_TRUE, &numCPoints, &cpoints);CHKERRQ(ierr); 61297c927364SMatthew G. Knepley PetscFunctionReturn(0); 61307c927364SMatthew G. Knepley } 61317c927364SMatthew G. Knepley 6132f96281f8SMatthew G. Knepley /*@ 6133f96281f8SMatthew G. Knepley DMPlexGetHybridBounds - Get the first mesh point of each dimension which is a hybrid 6134f96281f8SMatthew G. Knepley 6135f96281f8SMatthew G. Knepley Input Parameter: 6136f96281f8SMatthew G. Knepley . dm - The DMPlex object 6137f96281f8SMatthew G. Knepley 6138f96281f8SMatthew G. Knepley Output Parameters: 6139f96281f8SMatthew G. Knepley + cMax - The first hybrid cell 6140dc5a3409SMatthew G. Knepley . fMax - The first hybrid face 6141dc5a3409SMatthew G. Knepley . eMax - The first hybrid edge 6142dc5a3409SMatthew G. Knepley - vMax - The first hybrid vertex 6143f96281f8SMatthew G. Knepley 6144f96281f8SMatthew G. Knepley Level: developer 6145f96281f8SMatthew G. Knepley 6146dc5a3409SMatthew G. Knepley .seealso DMPlexCreateHybridMesh(), DMPlexSetHybridBounds() 6147f96281f8SMatthew G. Knepley @*/ 6148770b213bSMatthew G Knepley PetscErrorCode DMPlexGetHybridBounds(DM dm, PetscInt *cMax, PetscInt *fMax, PetscInt *eMax, PetscInt *vMax) 6149552f7358SJed Brown { 6150552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 6151770b213bSMatthew G Knepley PetscInt dim; 6152770b213bSMatthew G Knepley PetscErrorCode ierr; 6153552f7358SJed Brown 6154552f7358SJed Brown PetscFunctionBegin; 6155552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6156c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 61577d5acc75SStefano Zampini if (dim < 0) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM dimension not yet set"); 6158770b213bSMatthew G Knepley if (cMax) *cMax = mesh->hybridPointMax[dim]; 61597d5acc75SStefano Zampini if (fMax) *fMax = mesh->hybridPointMax[PetscMax(dim-1,0)]; 6160770b213bSMatthew G Knepley if (eMax) *eMax = mesh->hybridPointMax[1]; 6161770b213bSMatthew G Knepley if (vMax) *vMax = mesh->hybridPointMax[0]; 6162552f7358SJed Brown PetscFunctionReturn(0); 6163552f7358SJed Brown } 6164552f7358SJed Brown 6165aeadca18SToby Isaac static PetscErrorCode DMPlexCreateDimStratum(DM dm, DMLabel depthLabel, DMLabel dimLabel, PetscInt d, PetscInt dMax) 61664a3e9fdbSToby Isaac { 61674a3e9fdbSToby Isaac IS is, his; 61687d5acc75SStefano Zampini PetscInt first = 0, stride; 61694a3e9fdbSToby Isaac PetscBool isStride; 61704a3e9fdbSToby Isaac PetscErrorCode ierr; 61714a3e9fdbSToby Isaac 61724a3e9fdbSToby Isaac PetscFunctionBegin; 61734a3e9fdbSToby Isaac ierr = DMLabelGetStratumIS(depthLabel, d, &is);CHKERRQ(ierr); 61744a3e9fdbSToby Isaac ierr = PetscObjectTypeCompare((PetscObject) is, ISSTRIDE, &isStride);CHKERRQ(ierr); 61754a3e9fdbSToby Isaac if (isStride) { 61764a3e9fdbSToby Isaac ierr = ISStrideGetInfo(is, &first, &stride);CHKERRQ(ierr); 61774a3e9fdbSToby Isaac } 61787d5acc75SStefano Zampini if (is && (!isStride || stride != 1)) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "DM is not stratified: depth %D IS is not contiguous", d); 61794a3e9fdbSToby Isaac ierr = ISCreateStride(PETSC_COMM_SELF, (dMax - first), first, 1, &his);CHKERRQ(ierr); 6180aeadca18SToby Isaac ierr = DMLabelSetStratumIS(dimLabel, d, his);CHKERRQ(ierr); 61814a3e9fdbSToby Isaac ierr = ISDestroy(&his);CHKERRQ(ierr); 61824a3e9fdbSToby Isaac ierr = ISDestroy(&is);CHKERRQ(ierr); 61834a3e9fdbSToby Isaac PetscFunctionReturn(0); 61844a3e9fdbSToby Isaac } 61854a3e9fdbSToby Isaac 6186dc5a3409SMatthew G. Knepley /*@ 6187dc5a3409SMatthew G. Knepley DMPlexSetHybridBounds - Set the first mesh point of each dimension which is a hybrid 6188dc5a3409SMatthew G. Knepley 6189dc5a3409SMatthew G. Knepley Input Parameters: 6190dc5a3409SMatthew G. Knepley . dm - The DMPlex object 6191dc5a3409SMatthew G. Knepley . cMax - The first hybrid cell 6192dc5a3409SMatthew G. Knepley . fMax - The first hybrid face 6193dc5a3409SMatthew G. Knepley . eMax - The first hybrid edge 6194dc5a3409SMatthew G. Knepley - vMax - The first hybrid vertex 6195dc5a3409SMatthew G. Knepley 6196dc5a3409SMatthew G. Knepley Level: developer 6197dc5a3409SMatthew G. Knepley 6198dc5a3409SMatthew G. Knepley .seealso DMPlexCreateHybridMesh(), DMPlexGetHybridBounds() 6199dc5a3409SMatthew G. Knepley @*/ 6200770b213bSMatthew G Knepley PetscErrorCode DMPlexSetHybridBounds(DM dm, PetscInt cMax, PetscInt fMax, PetscInt eMax, PetscInt vMax) 6201552f7358SJed Brown { 6202552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 6203770b213bSMatthew G Knepley PetscInt dim; 6204770b213bSMatthew G Knepley PetscErrorCode ierr; 6205552f7358SJed Brown 6206552f7358SJed Brown PetscFunctionBegin; 6207552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6208c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 62097d5acc75SStefano Zampini if (dim < 0) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM dimension not yet set"); 6210770b213bSMatthew G Knepley if (cMax >= 0) mesh->hybridPointMax[dim] = cMax; 62117d5acc75SStefano Zampini if (fMax >= 0) mesh->hybridPointMax[PetscMax(dim-1,0)] = fMax; 6212770b213bSMatthew G Knepley if (eMax >= 0) mesh->hybridPointMax[1] = eMax; 6213770b213bSMatthew G Knepley if (vMax >= 0) mesh->hybridPointMax[0] = vMax; 6214552f7358SJed Brown PetscFunctionReturn(0); 6215552f7358SJed Brown } 6216552f7358SJed Brown 62177cd05799SMatthew G. Knepley /*@C 62187cd05799SMatthew G. Knepley DMPlexGetVTKCellHeight - Returns the height in the DAG used to determine which points are cells (normally 0) 62197cd05799SMatthew G. Knepley 62207cd05799SMatthew G. Knepley Input Parameter: 62217cd05799SMatthew G. Knepley . dm - The DMPlex object 62227cd05799SMatthew G. Knepley 62237cd05799SMatthew G. Knepley Output Parameter: 62247cd05799SMatthew G. Knepley . cellHeight - The height of a cell 62257cd05799SMatthew G. Knepley 62267cd05799SMatthew G. Knepley Level: developer 62277cd05799SMatthew G. Knepley 62287cd05799SMatthew G. Knepley .seealso DMPlexSetVTKCellHeight() 62297cd05799SMatthew G. Knepley @*/ 6230552f7358SJed Brown PetscErrorCode DMPlexGetVTKCellHeight(DM dm, PetscInt *cellHeight) 6231552f7358SJed Brown { 6232552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 6233552f7358SJed Brown 6234552f7358SJed Brown PetscFunctionBegin; 6235552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6236552f7358SJed Brown PetscValidPointer(cellHeight, 2); 6237552f7358SJed Brown *cellHeight = mesh->vtkCellHeight; 6238552f7358SJed Brown PetscFunctionReturn(0); 6239552f7358SJed Brown } 6240552f7358SJed Brown 62417cd05799SMatthew G. Knepley /*@C 62427cd05799SMatthew G. Knepley DMPlexSetVTKCellHeight - Sets the height in the DAG used to determine which points are cells (normally 0) 62437cd05799SMatthew G. Knepley 62447cd05799SMatthew G. Knepley Input Parameters: 62457cd05799SMatthew G. Knepley + dm - The DMPlex object 62467cd05799SMatthew G. Knepley - cellHeight - The height of a cell 62477cd05799SMatthew G. Knepley 62487cd05799SMatthew G. Knepley Level: developer 62497cd05799SMatthew G. Knepley 62507cd05799SMatthew G. Knepley .seealso DMPlexGetVTKCellHeight() 62517cd05799SMatthew G. Knepley @*/ 6252552f7358SJed Brown PetscErrorCode DMPlexSetVTKCellHeight(DM dm, PetscInt cellHeight) 6253552f7358SJed Brown { 6254552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 6255552f7358SJed Brown 6256552f7358SJed Brown PetscFunctionBegin; 6257552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6258552f7358SJed Brown mesh->vtkCellHeight = cellHeight; 6259552f7358SJed Brown PetscFunctionReturn(0); 6260552f7358SJed Brown } 6261552f7358SJed Brown 6262552f7358SJed Brown /* We can easily have a form that takes an IS instead */ 626350ad7711SMatthew G. Knepley PetscErrorCode DMPlexCreateNumbering_Internal(DM dm, PetscInt pStart, PetscInt pEnd, PetscInt shift, PetscInt *globalSize, PetscSF sf, IS *numbering) 6264552f7358SJed Brown { 6265552f7358SJed Brown PetscSection section, globalSection; 6266552f7358SJed Brown PetscInt *numbers, p; 6267552f7358SJed Brown PetscErrorCode ierr; 6268552f7358SJed Brown 6269552f7358SJed Brown PetscFunctionBegin; 627082f516ccSBarry Smith ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), §ion);CHKERRQ(ierr); 6271552f7358SJed Brown ierr = PetscSectionSetChart(section, pStart, pEnd);CHKERRQ(ierr); 6272552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 6273552f7358SJed Brown ierr = PetscSectionSetDof(section, p, 1);CHKERRQ(ierr); 6274552f7358SJed Brown } 6275552f7358SJed Brown ierr = PetscSectionSetUp(section);CHKERRQ(ierr); 627615b58121SMatthew G. Knepley ierr = PetscSectionCreateGlobalSection(section, sf, PETSC_FALSE, PETSC_FALSE, &globalSection);CHKERRQ(ierr); 6277854ce69bSBarry Smith ierr = PetscMalloc1(pEnd - pStart, &numbers);CHKERRQ(ierr); 6278552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 6279552f7358SJed Brown ierr = PetscSectionGetOffset(globalSection, p, &numbers[p-pStart]);CHKERRQ(ierr); 6280ef48cebcSMatthew G. Knepley if (numbers[p-pStart] < 0) numbers[p-pStart] -= shift; 6281ef48cebcSMatthew G. Knepley else numbers[p-pStart] += shift; 6282552f7358SJed Brown } 628382f516ccSBarry Smith ierr = ISCreateGeneral(PetscObjectComm((PetscObject) dm), pEnd - pStart, numbers, PETSC_OWN_POINTER, numbering);CHKERRQ(ierr); 6284ef48cebcSMatthew G. Knepley if (globalSize) { 6285ef48cebcSMatthew G. Knepley PetscLayout layout; 6286ef48cebcSMatthew G. Knepley ierr = PetscSectionGetPointLayout(PetscObjectComm((PetscObject) dm), globalSection, &layout);CHKERRQ(ierr); 6287ef48cebcSMatthew G. Knepley ierr = PetscLayoutGetSize(layout, globalSize);CHKERRQ(ierr); 6288ef48cebcSMatthew G. Knepley ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr); 6289ef48cebcSMatthew G. Knepley } 6290552f7358SJed Brown ierr = PetscSectionDestroy(§ion);CHKERRQ(ierr); 6291552f7358SJed Brown ierr = PetscSectionDestroy(&globalSection);CHKERRQ(ierr); 6292552f7358SJed Brown PetscFunctionReturn(0); 6293552f7358SJed Brown } 6294552f7358SJed Brown 629581ed3555SMatthew G. Knepley PetscErrorCode DMPlexCreateCellNumbering_Internal(DM dm, PetscBool includeHybrid, IS *globalCellNumbers) 6296552f7358SJed Brown { 6297552f7358SJed Brown PetscInt cellHeight, cStart, cEnd, cMax; 6298552f7358SJed Brown PetscErrorCode ierr; 6299552f7358SJed Brown 6300552f7358SJed Brown PetscFunctionBegin; 6301552f7358SJed Brown ierr = DMPlexGetVTKCellHeight(dm, &cellHeight);CHKERRQ(ierr); 6302552f7358SJed Brown ierr = DMPlexGetHeightStratum(dm, cellHeight, &cStart, &cEnd);CHKERRQ(ierr); 63030298fd71SBarry Smith ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr); 630481ed3555SMatthew G. Knepley if (cMax >= 0 && !includeHybrid) cEnd = PetscMin(cEnd, cMax); 630550ad7711SMatthew G. Knepley ierr = DMPlexCreateNumbering_Internal(dm, cStart, cEnd, 0, NULL, dm->sf, globalCellNumbers);CHKERRQ(ierr); 630681ed3555SMatthew G. Knepley PetscFunctionReturn(0); 6307552f7358SJed Brown } 630881ed3555SMatthew G. Knepley 63098dab3259SMatthew G. Knepley /*@ 63107cd05799SMatthew G. Knepley DMPlexGetCellNumbering - Get a global cell numbering for all cells on this process 63117cd05799SMatthew G. Knepley 63127cd05799SMatthew G. Knepley Input Parameter: 63137cd05799SMatthew G. Knepley . dm - The DMPlex object 63147cd05799SMatthew G. Knepley 63157cd05799SMatthew G. Knepley Output Parameter: 63167cd05799SMatthew G. Knepley . globalCellNumbers - Global cell numbers for all cells on this process 63177cd05799SMatthew G. Knepley 63187cd05799SMatthew G. Knepley Level: developer 63197cd05799SMatthew G. Knepley 63207cd05799SMatthew G. Knepley .seealso DMPlexGetVertexNumbering() 63217cd05799SMatthew G. Knepley @*/ 632281ed3555SMatthew G. Knepley PetscErrorCode DMPlexGetCellNumbering(DM dm, IS *globalCellNumbers) 632381ed3555SMatthew G. Knepley { 632481ed3555SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 632581ed3555SMatthew G. Knepley PetscErrorCode ierr; 632681ed3555SMatthew G. Knepley 632781ed3555SMatthew G. Knepley PetscFunctionBegin; 632881ed3555SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 632981ed3555SMatthew G. Knepley if (!mesh->globalCellNumbers) {ierr = DMPlexCreateCellNumbering_Internal(dm, PETSC_FALSE, &mesh->globalCellNumbers);CHKERRQ(ierr);} 6330552f7358SJed Brown *globalCellNumbers = mesh->globalCellNumbers; 6331552f7358SJed Brown PetscFunctionReturn(0); 6332552f7358SJed Brown } 6333552f7358SJed Brown 633481ed3555SMatthew G. Knepley PetscErrorCode DMPlexCreateVertexNumbering_Internal(DM dm, PetscBool includeHybrid, IS *globalVertexNumbers) 633581ed3555SMatthew G. Knepley { 633681ed3555SMatthew G. Knepley PetscInt vStart, vEnd, vMax; 633781ed3555SMatthew G. Knepley PetscErrorCode ierr; 633881ed3555SMatthew G. Knepley 633981ed3555SMatthew G. Knepley PetscFunctionBegin; 634081ed3555SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 634181ed3555SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 634281ed3555SMatthew G. Knepley ierr = DMPlexGetHybridBounds(dm, NULL, NULL, NULL, &vMax);CHKERRQ(ierr); 634381ed3555SMatthew G. Knepley if (vMax >= 0 && !includeHybrid) vEnd = PetscMin(vEnd, vMax); 634450ad7711SMatthew G. Knepley ierr = DMPlexCreateNumbering_Internal(dm, vStart, vEnd, 0, NULL, dm->sf, globalVertexNumbers);CHKERRQ(ierr); 634581ed3555SMatthew G. Knepley PetscFunctionReturn(0); 634681ed3555SMatthew G. Knepley } 634781ed3555SMatthew G. Knepley 63488dab3259SMatthew G. Knepley /*@ 63497cd05799SMatthew G. Knepley DMPlexGetVertexNumbering - Get a global certex numbering for all vertices on this process 63507cd05799SMatthew G. Knepley 63517cd05799SMatthew G. Knepley Input Parameter: 63527cd05799SMatthew G. Knepley . dm - The DMPlex object 63537cd05799SMatthew G. Knepley 63547cd05799SMatthew G. Knepley Output Parameter: 63557cd05799SMatthew G. Knepley . globalVertexNumbers - Global vertex numbers for all vertices on this process 63567cd05799SMatthew G. Knepley 63577cd05799SMatthew G. Knepley Level: developer 63587cd05799SMatthew G. Knepley 63597cd05799SMatthew G. Knepley .seealso DMPlexGetCellNumbering() 63607cd05799SMatthew G. Knepley @*/ 6361552f7358SJed Brown PetscErrorCode DMPlexGetVertexNumbering(DM dm, IS *globalVertexNumbers) 6362552f7358SJed Brown { 6363552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 6364552f7358SJed Brown PetscErrorCode ierr; 6365552f7358SJed Brown 6366552f7358SJed Brown PetscFunctionBegin; 6367552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 636881ed3555SMatthew G. Knepley if (!mesh->globalVertexNumbers) {ierr = DMPlexCreateVertexNumbering_Internal(dm, PETSC_FALSE, &mesh->globalVertexNumbers);CHKERRQ(ierr);} 6369552f7358SJed Brown *globalVertexNumbers = mesh->globalVertexNumbers; 6370552f7358SJed Brown PetscFunctionReturn(0); 6371552f7358SJed Brown } 6372552f7358SJed Brown 63738dab3259SMatthew G. Knepley /*@ 63747cd05799SMatthew G. Knepley DMPlexCreatePointNumbering - Create a global numbering for all points on this process 63757cd05799SMatthew G. Knepley 63767cd05799SMatthew G. Knepley Input Parameter: 63777cd05799SMatthew G. Knepley . dm - The DMPlex object 63787cd05799SMatthew G. Knepley 63797cd05799SMatthew G. Knepley Output Parameter: 63807cd05799SMatthew G. Knepley . globalPointNumbers - Global numbers for all points on this process 63817cd05799SMatthew G. Knepley 63827cd05799SMatthew G. Knepley Level: developer 63837cd05799SMatthew G. Knepley 63847cd05799SMatthew G. Knepley .seealso DMPlexGetCellNumbering() 63857cd05799SMatthew G. Knepley @*/ 6386ef48cebcSMatthew G. Knepley PetscErrorCode DMPlexCreatePointNumbering(DM dm, IS *globalPointNumbers) 6387ef48cebcSMatthew G. Knepley { 6388ef48cebcSMatthew G. Knepley IS nums[4]; 6389862913ffSStefano Zampini PetscInt depths[4], gdepths[4], starts[4]; 6390ef48cebcSMatthew G. Knepley PetscInt depth, d, shift = 0; 6391ef48cebcSMatthew G. Knepley PetscErrorCode ierr; 6392ef48cebcSMatthew G. Knepley 6393ef48cebcSMatthew G. Knepley PetscFunctionBegin; 6394ef48cebcSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6395ef48cebcSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 63968abc87a0SMichael Lange /* For unstratified meshes use dim instead of depth */ 63978abc87a0SMichael Lange if (depth < 0) {ierr = DMGetDimension(dm, &depth);CHKERRQ(ierr);} 6398862913ffSStefano Zampini for (d = 0; d <= depth; ++d) { 6399862913ffSStefano Zampini PetscInt end; 6400862913ffSStefano Zampini 6401862913ffSStefano Zampini depths[d] = depth-d; 6402862913ffSStefano Zampini ierr = DMPlexGetDepthStratum(dm, depths[d], &starts[d], &end);CHKERRQ(ierr); 6403862913ffSStefano Zampini if (!(starts[d]-end)) { starts[d] = depths[d] = -1; } 6404862913ffSStefano Zampini } 6405862913ffSStefano Zampini ierr = PetscSortIntWithArray(depth+1, starts, depths);CHKERRQ(ierr); 6406862913ffSStefano Zampini ierr = MPIU_Allreduce(depths, gdepths, depth+1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject) dm));CHKERRQ(ierr); 6407862913ffSStefano Zampini for (d = 0; d <= depth; ++d) { 6408862913ffSStefano Zampini if (starts[d] >= 0 && depths[d] != gdepths[d]) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Expected depth %D, found %D",depths[d],gdepths[d]); 6409862913ffSStefano Zampini } 6410ef48cebcSMatthew G. Knepley for (d = 0; d <= depth; ++d) { 6411ef48cebcSMatthew G. Knepley PetscInt pStart, pEnd, gsize; 6412ef48cebcSMatthew G. Knepley 6413862913ffSStefano Zampini ierr = DMPlexGetDepthStratum(dm, gdepths[d], &pStart, &pEnd);CHKERRQ(ierr); 641450ad7711SMatthew G. Knepley ierr = DMPlexCreateNumbering_Internal(dm, pStart, pEnd, shift, &gsize, dm->sf, &nums[d]);CHKERRQ(ierr); 6415ef48cebcSMatthew G. Knepley shift += gsize; 6416ef48cebcSMatthew G. Knepley } 6417302440fdSBarry Smith ierr = ISConcatenate(PetscObjectComm((PetscObject) dm), depth+1, nums, globalPointNumbers);CHKERRQ(ierr); 6418ef48cebcSMatthew G. Knepley for (d = 0; d <= depth; ++d) {ierr = ISDestroy(&nums[d]);CHKERRQ(ierr);} 6419ef48cebcSMatthew G. Knepley PetscFunctionReturn(0); 6420ef48cebcSMatthew G. Knepley } 6421ef48cebcSMatthew G. Knepley 642208a22f4bSMatthew G. Knepley 642308a22f4bSMatthew G. Knepley /*@ 642408a22f4bSMatthew G. Knepley DMPlexCreateRankField - Create a cell field whose value is the rank of the owner 642508a22f4bSMatthew G. Knepley 642608a22f4bSMatthew G. Knepley Input Parameter: 642708a22f4bSMatthew G. Knepley . dm - The DMPlex object 642808a22f4bSMatthew G. Knepley 642908a22f4bSMatthew G. Knepley Output Parameter: 643008a22f4bSMatthew G. Knepley . ranks - The rank field 643108a22f4bSMatthew G. Knepley 643208a22f4bSMatthew G. Knepley Options Database Keys: 643308a22f4bSMatthew G. Knepley . -dm_partition_view - Adds the rank field into the DM output from -dm_view using the same viewer 643408a22f4bSMatthew G. Knepley 643508a22f4bSMatthew G. Knepley Level: intermediate 643608a22f4bSMatthew G. Knepley 643708a22f4bSMatthew G. Knepley .seealso: DMView() 643808a22f4bSMatthew G. Knepley @*/ 643908a22f4bSMatthew G. Knepley PetscErrorCode DMPlexCreateRankField(DM dm, Vec *ranks) 644008a22f4bSMatthew G. Knepley { 644108a22f4bSMatthew G. Knepley DM rdm; 644208a22f4bSMatthew G. Knepley PetscFE fe; 644308a22f4bSMatthew G. Knepley PetscScalar *r; 644408a22f4bSMatthew G. Knepley PetscMPIInt rank; 644508a22f4bSMatthew G. Knepley PetscInt dim, cStart, cEnd, c; 644608a22f4bSMatthew G. Knepley PetscErrorCode ierr; 644708a22f4bSMatthew G. Knepley 644808a22f4bSMatthew G. Knepley PetscFunctionBeginUser; 6449f95ace6aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6450f95ace6aSMatthew G. Knepley PetscValidPointer(ranks, 2); 645108a22f4bSMatthew G. Knepley ierr = MPI_Comm_rank(PetscObjectComm((PetscObject) dm), &rank);CHKERRQ(ierr); 645208a22f4bSMatthew G. Knepley ierr = DMClone(dm, &rdm);CHKERRQ(ierr); 645308a22f4bSMatthew G. Knepley ierr = DMGetDimension(rdm, &dim);CHKERRQ(ierr); 6454f95ace6aSMatthew G. Knepley ierr = PetscFECreateDefault(PetscObjectComm((PetscObject) rdm), dim, 1, PETSC_TRUE, "PETSc___rank_", -1, &fe);CHKERRQ(ierr); 645508a22f4bSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) fe, "rank");CHKERRQ(ierr); 6456e5e52638SMatthew G. Knepley ierr = DMSetField(rdm, 0, NULL, (PetscObject) fe);CHKERRQ(ierr); 645708a22f4bSMatthew G. Knepley ierr = PetscFEDestroy(&fe);CHKERRQ(ierr); 6458e5e52638SMatthew G. Knepley ierr = DMCreateDS(rdm);CHKERRQ(ierr); 645908a22f4bSMatthew G. Knepley ierr = DMPlexGetHeightStratum(rdm, 0, &cStart, &cEnd);CHKERRQ(ierr); 646008a22f4bSMatthew G. Knepley ierr = DMCreateGlobalVector(rdm, ranks);CHKERRQ(ierr); 646108a22f4bSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) *ranks, "partition");CHKERRQ(ierr); 646208a22f4bSMatthew G. Knepley ierr = VecGetArray(*ranks, &r);CHKERRQ(ierr); 646308a22f4bSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 646408a22f4bSMatthew G. Knepley PetscScalar *lr; 646508a22f4bSMatthew G. Knepley 646608a22f4bSMatthew G. Knepley ierr = DMPlexPointGlobalRef(rdm, c, r, &lr);CHKERRQ(ierr); 646708a22f4bSMatthew G. Knepley *lr = rank; 646808a22f4bSMatthew G. Knepley } 646908a22f4bSMatthew G. Knepley ierr = VecRestoreArray(*ranks, &r);CHKERRQ(ierr); 647008a22f4bSMatthew G. Knepley ierr = DMDestroy(&rdm);CHKERRQ(ierr); 647108a22f4bSMatthew G. Knepley PetscFunctionReturn(0); 647208a22f4bSMatthew G. Knepley } 647308a22f4bSMatthew G. Knepley 6474ca8062c8SMatthew G. Knepley /*@ 647518e14f0cSMatthew G. Knepley DMPlexCreateLabelField - Create a cell field whose value is the label value for that cell 647618e14f0cSMatthew G. Knepley 647718e14f0cSMatthew G. Knepley Input Parameters: 647818e14f0cSMatthew G. Knepley + dm - The DMPlex 647918e14f0cSMatthew G. Knepley - label - The DMLabel 648018e14f0cSMatthew G. Knepley 648118e14f0cSMatthew G. Knepley Output Parameter: 648218e14f0cSMatthew G. Knepley . val - The label value field 648318e14f0cSMatthew G. Knepley 648418e14f0cSMatthew G. Knepley Options Database Keys: 648518e14f0cSMatthew G. Knepley . -dm_label_view - Adds the label value field into the DM output from -dm_view using the same viewer 648618e14f0cSMatthew G. Knepley 648718e14f0cSMatthew G. Knepley Level: intermediate 648818e14f0cSMatthew G. Knepley 648918e14f0cSMatthew G. Knepley .seealso: DMView() 649018e14f0cSMatthew G. Knepley @*/ 649118e14f0cSMatthew G. Knepley PetscErrorCode DMPlexCreateLabelField(DM dm, DMLabel label, Vec *val) 649218e14f0cSMatthew G. Knepley { 649318e14f0cSMatthew G. Knepley DM rdm; 649418e14f0cSMatthew G. Knepley PetscFE fe; 649518e14f0cSMatthew G. Knepley PetscScalar *v; 649618e14f0cSMatthew G. Knepley PetscInt dim, cStart, cEnd, c; 649718e14f0cSMatthew G. Knepley PetscErrorCode ierr; 649818e14f0cSMatthew G. Knepley 649918e14f0cSMatthew G. Knepley PetscFunctionBeginUser; 650018e14f0cSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 650118e14f0cSMatthew G. Knepley PetscValidPointer(label, 2); 650218e14f0cSMatthew G. Knepley PetscValidPointer(val, 3); 650318e14f0cSMatthew G. Knepley ierr = DMClone(dm, &rdm);CHKERRQ(ierr); 650418e14f0cSMatthew G. Knepley ierr = DMGetDimension(rdm, &dim);CHKERRQ(ierr); 650518e14f0cSMatthew G. Knepley ierr = PetscFECreateDefault(PetscObjectComm((PetscObject) rdm), dim, 1, PETSC_TRUE, "PETSc___label_value_", -1, &fe);CHKERRQ(ierr); 650618e14f0cSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) fe, "label_value");CHKERRQ(ierr); 6507e5e52638SMatthew G. Knepley ierr = DMSetField(rdm, 0, NULL, (PetscObject) fe);CHKERRQ(ierr); 650818e14f0cSMatthew G. Knepley ierr = PetscFEDestroy(&fe);CHKERRQ(ierr); 6509e5e52638SMatthew G. Knepley ierr = DMCreateDS(rdm);CHKERRQ(ierr); 651018e14f0cSMatthew G. Knepley ierr = DMPlexGetHeightStratum(rdm, 0, &cStart, &cEnd);CHKERRQ(ierr); 651118e14f0cSMatthew G. Knepley ierr = DMCreateGlobalVector(rdm, val);CHKERRQ(ierr); 6512effbd7cbSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) *val, "label_value");CHKERRQ(ierr); 651318e14f0cSMatthew G. Knepley ierr = VecGetArray(*val, &v);CHKERRQ(ierr); 651418e14f0cSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 651518e14f0cSMatthew G. Knepley PetscScalar *lv; 651618e14f0cSMatthew G. Knepley PetscInt cval; 651718e14f0cSMatthew G. Knepley 651818e14f0cSMatthew G. Knepley ierr = DMPlexPointGlobalRef(rdm, c, v, &lv);CHKERRQ(ierr); 651918e14f0cSMatthew G. Knepley ierr = DMLabelGetValue(label, c, &cval);CHKERRQ(ierr); 652018e14f0cSMatthew G. Knepley *lv = cval; 652118e14f0cSMatthew G. Knepley } 652218e14f0cSMatthew G. Knepley ierr = VecRestoreArray(*val, &v);CHKERRQ(ierr); 652318e14f0cSMatthew G. Knepley ierr = DMDestroy(&rdm);CHKERRQ(ierr); 652418e14f0cSMatthew G. Knepley PetscFunctionReturn(0); 652518e14f0cSMatthew G. Knepley } 652618e14f0cSMatthew G. Knepley 652718e14f0cSMatthew G. Knepley /*@ 6528ca8062c8SMatthew G. Knepley DMPlexCheckSymmetry - Check that the adjacency information in the mesh is symmetric. 6529ca8062c8SMatthew G. Knepley 653069916449SMatthew G. Knepley Input Parameter: 653169916449SMatthew G. Knepley . dm - The DMPlex object 6532ca8062c8SMatthew G. Knepley 6533ca8062c8SMatthew G. Knepley Note: This is a useful diagnostic when creating meshes programmatically. 6534ca8062c8SMatthew G. Knepley 6535ca8062c8SMatthew G. Knepley Level: developer 6536ca8062c8SMatthew G. Knepley 65377d5acc75SStefano Zampini .seealso: DMCreate(), DMPlexCheckSkeleton(), DMPlexCheckFaces() 6538ca8062c8SMatthew G. Knepley @*/ 6539ca8062c8SMatthew G. Knepley PetscErrorCode DMPlexCheckSymmetry(DM dm) 6540ca8062c8SMatthew G. Knepley { 6541ca8062c8SMatthew G. Knepley PetscSection coneSection, supportSection; 6542ca8062c8SMatthew G. Knepley const PetscInt *cone, *support; 6543ca8062c8SMatthew G. Knepley PetscInt coneSize, c, supportSize, s; 654457beb4faSStefano Zampini PetscInt pStart, pEnd, p, pp, csize, ssize; 654557beb4faSStefano Zampini PetscBool storagecheck = PETSC_TRUE; 6546ca8062c8SMatthew G. Knepley PetscErrorCode ierr; 6547ca8062c8SMatthew G. Knepley 6548ca8062c8SMatthew G. Knepley PetscFunctionBegin; 6549ca8062c8SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6550ca8062c8SMatthew G. Knepley ierr = DMPlexGetConeSection(dm, &coneSection);CHKERRQ(ierr); 6551ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupportSection(dm, &supportSection);CHKERRQ(ierr); 6552ca8062c8SMatthew G. Knepley /* Check that point p is found in the support of its cone points, and vice versa */ 6553ca8062c8SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 6554ca8062c8SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 6555ca8062c8SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, p, &coneSize);CHKERRQ(ierr); 6556ca8062c8SMatthew G. Knepley ierr = DMPlexGetCone(dm, p, &cone);CHKERRQ(ierr); 6557ca8062c8SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 655842e66dfaSMatthew G. Knepley PetscBool dup = PETSC_FALSE; 655942e66dfaSMatthew G. Knepley PetscInt d; 656042e66dfaSMatthew G. Knepley for (d = c-1; d >= 0; --d) { 656142e66dfaSMatthew G. Knepley if (cone[c] == cone[d]) {dup = PETSC_TRUE; break;} 656242e66dfaSMatthew G. Knepley } 6563ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, cone[c], &supportSize);CHKERRQ(ierr); 6564ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupport(dm, cone[c], &support);CHKERRQ(ierr); 6565ca8062c8SMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 6566ca8062c8SMatthew G. Knepley if (support[s] == p) break; 6567ca8062c8SMatthew G. Knepley } 656842e66dfaSMatthew G. Knepley if ((s >= supportSize) || (dup && (support[s+1] != p))) { 65698ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "p: %D cone: ", p);CHKERRQ(ierr); 6570ca8062c8SMatthew G. Knepley for (s = 0; s < coneSize; ++s) { 65718ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "%D, ", cone[s]);CHKERRQ(ierr); 6572ca8062c8SMatthew G. Knepley } 6573302440fdSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 65748ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "p: %D support: ", cone[c]);CHKERRQ(ierr); 6575ca8062c8SMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 65768ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "%D, ", support[s]);CHKERRQ(ierr); 6577ca8062c8SMatthew G. Knepley } 6578302440fdSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 65798ccfff9cSToby Isaac if (dup) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D not repeatedly found in support of repeated cone point %D", p, cone[c]); 65808ccfff9cSToby Isaac else SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D not found in support of cone point %D", p, cone[c]); 6581ca8062c8SMatthew G. Knepley } 658242e66dfaSMatthew G. Knepley } 658357beb4faSStefano Zampini ierr = DMPlexGetTreeParent(dm, p, &pp, NULL);CHKERRQ(ierr); 658457beb4faSStefano Zampini if (p != pp) { storagecheck = PETSC_FALSE; continue; } 6585ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, p, &supportSize);CHKERRQ(ierr); 6586ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupport(dm, p, &support);CHKERRQ(ierr); 6587ca8062c8SMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 6588ca8062c8SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6589ca8062c8SMatthew G. Knepley ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6590ca8062c8SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 659157beb4faSStefano Zampini ierr = DMPlexGetTreeParent(dm, cone[c], &pp, NULL);CHKERRQ(ierr); 659257beb4faSStefano Zampini if (cone[c] != pp) { c = 0; break; } 6593ca8062c8SMatthew G. Knepley if (cone[c] == p) break; 6594ca8062c8SMatthew G. Knepley } 6595ca8062c8SMatthew G. Knepley if (c >= coneSize) { 65968ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "p: %D support: ", p);CHKERRQ(ierr); 6597ca8062c8SMatthew G. Knepley for (c = 0; c < supportSize; ++c) { 65988ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "%D, ", support[c]);CHKERRQ(ierr); 6599ca8062c8SMatthew G. Knepley } 6600302440fdSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 66018ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "p: %D cone: ", support[s]);CHKERRQ(ierr); 6602ca8062c8SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 66038ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "%D, ", cone[c]);CHKERRQ(ierr); 6604ca8062c8SMatthew G. Knepley } 6605302440fdSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 66068ccfff9cSToby Isaac SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D not found in cone of support point %D", p, support[s]); 6607ca8062c8SMatthew G. Knepley } 6608ca8062c8SMatthew G. Knepley } 6609ca8062c8SMatthew G. Knepley } 661057beb4faSStefano Zampini if (storagecheck) { 6611ca8062c8SMatthew G. Knepley ierr = PetscSectionGetStorageSize(coneSection, &csize);CHKERRQ(ierr); 6612ca8062c8SMatthew G. Knepley ierr = PetscSectionGetStorageSize(supportSection, &ssize);CHKERRQ(ierr); 66138ccfff9cSToby Isaac if (csize != ssize) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Total cone size %D != Total support size %D", csize, ssize); 661457beb4faSStefano Zampini } 6615ca8062c8SMatthew G. Knepley PetscFunctionReturn(0); 6616ca8062c8SMatthew G. Knepley } 6617ca8062c8SMatthew G. Knepley 6618ca8062c8SMatthew G. Knepley /*@ 6619ca8062c8SMatthew G. Knepley DMPlexCheckSkeleton - Check that each cell has the correct number of vertices 6620ca8062c8SMatthew G. Knepley 6621ca8062c8SMatthew G. Knepley Input Parameters: 6622ca8062c8SMatthew G. Knepley + dm - The DMPlex object 662358723a97SMatthew G. Knepley - cellHeight - Normally 0 6624ca8062c8SMatthew G. Knepley 6625ca8062c8SMatthew G. Knepley Note: This is a useful diagnostic when creating meshes programmatically. 662625c50c26SVaclav Hapla Currently applicable only to homogeneous simplex or tensor meshes. 6627ca8062c8SMatthew G. Knepley 6628ca8062c8SMatthew G. Knepley Level: developer 6629ca8062c8SMatthew G. Knepley 66307d5acc75SStefano Zampini .seealso: DMCreate(), DMPlexCheckSymmetry(), DMPlexCheckFaces() 6631ca8062c8SMatthew G. Knepley @*/ 663225c50c26SVaclav Hapla PetscErrorCode DMPlexCheckSkeleton(DM dm, PetscInt cellHeight) 6633ca8062c8SMatthew G. Knepley { 663442363296SMatthew G. Knepley PetscInt dim, numCorners, numHybridCorners, vStart, vEnd, cStart, cEnd, cMax, c; 663525c50c26SVaclav Hapla PetscBool isSimplex = PETSC_FALSE; 6636ca8062c8SMatthew G. Knepley PetscErrorCode ierr; 6637ca8062c8SMatthew G. Knepley 6638ca8062c8SMatthew G. Knepley PetscFunctionBegin; 6639ca8062c8SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6640c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 664125c50c26SVaclav Hapla ierr = DMPlexGetHeightStratum(dm, cellHeight, &cStart, &cEnd);CHKERRQ(ierr); 664225c50c26SVaclav Hapla if (cStart < cEnd) { 664325c50c26SVaclav Hapla ierr = DMPlexGetConeSize(dm, cStart, &c);CHKERRQ(ierr); 664425c50c26SVaclav Hapla isSimplex = c == dim+1 ? PETSC_TRUE : PETSC_FALSE; 664525c50c26SVaclav Hapla } 6646ca8062c8SMatthew G. Knepley switch (dim) { 664742363296SMatthew G. Knepley case 1: numCorners = isSimplex ? 2 : 2; numHybridCorners = isSimplex ? 2 : 2; break; 664842363296SMatthew G. Knepley case 2: numCorners = isSimplex ? 3 : 4; numHybridCorners = isSimplex ? 4 : 4; break; 664942363296SMatthew G. Knepley case 3: numCorners = isSimplex ? 4 : 8; numHybridCorners = isSimplex ? 6 : 8; break; 6650ca8062c8SMatthew G. Knepley default: 66518ccfff9cSToby Isaac SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle meshes of dimension %D", dim); 6652ca8062c8SMatthew G. Knepley } 665358723a97SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 6654ca8062c8SMatthew G. Knepley ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr); 6655ca8062c8SMatthew G. Knepley cMax = cMax >= 0 ? cMax : cEnd; 6656ca8062c8SMatthew G. Knepley for (c = cStart; c < cMax; ++c) { 665758723a97SMatthew G. Knepley PetscInt *closure = NULL, closureSize, cl, coneSize = 0; 665858723a97SMatthew G. Knepley 665958723a97SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 666058723a97SMatthew G. Knepley for (cl = 0; cl < closureSize*2; cl += 2) { 666158723a97SMatthew G. Knepley const PetscInt p = closure[cl]; 666258723a97SMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) ++coneSize; 666358723a97SMatthew G. Knepley } 666458723a97SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 66658ccfff9cSToby Isaac if (coneSize != numCorners) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cell %D has %D vertices != %D", c, coneSize, numCorners); 6666ca8062c8SMatthew G. Knepley } 666742363296SMatthew G. Knepley for (c = cMax; c < cEnd; ++c) { 666842363296SMatthew G. Knepley PetscInt *closure = NULL, closureSize, cl, coneSize = 0; 666942363296SMatthew G. Knepley 667042363296SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 667142363296SMatthew G. Knepley for (cl = 0; cl < closureSize*2; cl += 2) { 667242363296SMatthew G. Knepley const PetscInt p = closure[cl]; 667342363296SMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) ++coneSize; 667442363296SMatthew G. Knepley } 667542363296SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 66768ccfff9cSToby Isaac if (coneSize > numHybridCorners) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Hybrid cell %D has %D vertices > %D", c, coneSize, numHybridCorners); 667742363296SMatthew G. Knepley } 6678ca8062c8SMatthew G. Knepley PetscFunctionReturn(0); 6679ca8062c8SMatthew G. Knepley } 66809bf0dad6SMatthew G. Knepley 66819bf0dad6SMatthew G. Knepley /*@ 66829bf0dad6SMatthew G. Knepley DMPlexCheckFaces - Check that the faces of each cell give a vertex order this is consistent with what we expect from the cell type 66839bf0dad6SMatthew G. Knepley 66849bf0dad6SMatthew G. Knepley Input Parameters: 66859bf0dad6SMatthew G. Knepley + dm - The DMPlex object 66869bf0dad6SMatthew G. Knepley - cellHeight - Normally 0 66879bf0dad6SMatthew G. Knepley 66889bf0dad6SMatthew G. Knepley Note: This is a useful diagnostic when creating meshes programmatically. 66899bf0dad6SMatthew G. Knepley 66909bf0dad6SMatthew G. Knepley Level: developer 66919bf0dad6SMatthew G. Knepley 66927d5acc75SStefano Zampini .seealso: DMCreate(), DMPlexCheckSymmetry(), DMPlexCheckSkeleton() 66939bf0dad6SMatthew G. Knepley @*/ 669425c50c26SVaclav Hapla PetscErrorCode DMPlexCheckFaces(DM dm, PetscInt cellHeight) 66959bf0dad6SMatthew G. Knepley { 66963554e41dSMatthew G. Knepley PetscInt pMax[4]; 6697ab91121cSMatthew G. Knepley PetscInt dim, depth, vStart, vEnd, cStart, cEnd, c, h; 66989bf0dad6SMatthew G. Knepley PetscErrorCode ierr; 66999bf0dad6SMatthew G. Knepley 67009bf0dad6SMatthew G. Knepley PetscFunctionBegin; 67019bf0dad6SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6702c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 6703ab91121cSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 67049bf0dad6SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 670525abba81SMatthew G. Knepley ierr = DMPlexGetHybridBounds(dm, &pMax[dim], &pMax[dim-1], &pMax[1], &pMax[0]);CHKERRQ(ierr); 6706ab91121cSMatthew G. Knepley for (h = cellHeight; h < PetscMin(depth, dim); ++h) { 67073554e41dSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, h, &cStart, &cEnd);CHKERRQ(ierr); 67083554e41dSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 67099bf0dad6SMatthew G. Knepley const PetscInt *cone, *ornt, *faces; 67109bf0dad6SMatthew G. Knepley PetscInt numFaces, faceSize, coneSize,f; 67119bf0dad6SMatthew G. Knepley PetscInt *closure = NULL, closureSize, cl, numCorners = 0; 67129bf0dad6SMatthew G. Knepley 671325abba81SMatthew G. Knepley if (pMax[dim-h] >= 0 && c >= pMax[dim-h]) continue; 67149bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, c, &coneSize);CHKERRQ(ierr); 67159bf0dad6SMatthew G. Knepley ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 67169bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 67179bf0dad6SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 67189bf0dad6SMatthew G. Knepley for (cl = 0; cl < closureSize*2; cl += 2) { 67199bf0dad6SMatthew G. Knepley const PetscInt p = closure[cl]; 67209bf0dad6SMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) closure[numCorners++] = p; 67219bf0dad6SMatthew G. Knepley } 67223554e41dSMatthew G. Knepley ierr = DMPlexGetRawFaces_Internal(dm, dim-h, numCorners, closure, &numFaces, &faceSize, &faces);CHKERRQ(ierr); 67238ccfff9cSToby Isaac if (coneSize != numFaces) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cell %D has %D faces but should have %D", c, coneSize, numFaces); 67249bf0dad6SMatthew G. Knepley for (f = 0; f < numFaces; ++f) { 67259bf0dad6SMatthew G. Knepley PetscInt *fclosure = NULL, fclosureSize, cl, fnumCorners = 0, v; 67269bf0dad6SMatthew G. Knepley 67279bf0dad6SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure_Internal(dm, cone[f], ornt[f], PETSC_TRUE, &fclosureSize, &fclosure);CHKERRQ(ierr); 67289bf0dad6SMatthew G. Knepley for (cl = 0; cl < fclosureSize*2; cl += 2) { 67299bf0dad6SMatthew G. Knepley const PetscInt p = fclosure[cl]; 67309bf0dad6SMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) fclosure[fnumCorners++] = p; 67319bf0dad6SMatthew G. Knepley } 67328ccfff9cSToby Isaac if (fnumCorners != faceSize) SETERRQ5(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Face %D (%D) of cell %D has %D vertices but should have %D", cone[f], f, c, fnumCorners, faceSize); 67339bf0dad6SMatthew G. Knepley for (v = 0; v < fnumCorners; ++v) { 67348ccfff9cSToby Isaac if (fclosure[v] != faces[f*faceSize+v]) SETERRQ6(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Face %D (%d) of cell %D vertex %D, %D != %D", cone[f], f, c, v, fclosure[v], faces[f*faceSize+v]); 67359bf0dad6SMatthew G. Knepley } 67369bf0dad6SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, cone[f], PETSC_TRUE, &fclosureSize, &fclosure);CHKERRQ(ierr); 67379bf0dad6SMatthew G. Knepley } 67389bf0dad6SMatthew G. Knepley ierr = DMPlexRestoreFaces_Internal(dm, dim, c, &numFaces, &faceSize, &faces);CHKERRQ(ierr); 67399bf0dad6SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 67409bf0dad6SMatthew G. Knepley } 67413554e41dSMatthew G. Knepley } 6742552f7358SJed Brown PetscFunctionReturn(0); 6743552f7358SJed Brown } 67443913d7c8SMatthew G. Knepley 6745bb6a34a8SMatthew G. Knepley /*@ 6746bb6a34a8SMatthew G. Knepley DMPlexCheckGeometry - Check the geometry of mesh cells 6747bb6a34a8SMatthew G. Knepley 6748bb6a34a8SMatthew G. Knepley Input Parameter: 6749bb6a34a8SMatthew G. Knepley . dm - The DMPlex object 6750bb6a34a8SMatthew G. Knepley 6751bb6a34a8SMatthew G. Knepley Note: This is a useful diagnostic when creating meshes programmatically. 6752bb6a34a8SMatthew G. Knepley 6753bb6a34a8SMatthew G. Knepley Level: developer 6754bb6a34a8SMatthew G. Knepley 6755bb6a34a8SMatthew G. Knepley .seealso: DMCreate(), DMCheckSymmetry(), DMCheckSkeleton(), DMCheckFaces() 6756bb6a34a8SMatthew G. Knepley @*/ 6757bb6a34a8SMatthew G. Knepley PetscErrorCode DMPlexCheckGeometry(DM dm) 6758bb6a34a8SMatthew G. Knepley { 6759bb6a34a8SMatthew G. Knepley PetscReal detJ, J[9], refVol = 1.0; 6760bb6a34a8SMatthew G. Knepley PetscReal vol; 6761bb6a34a8SMatthew G. Knepley PetscInt dim, depth, d, cStart, cEnd, c; 6762bb6a34a8SMatthew G. Knepley PetscErrorCode ierr; 6763bb6a34a8SMatthew G. Knepley 6764bb6a34a8SMatthew G. Knepley PetscFunctionBegin; 6765bb6a34a8SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 6766bb6a34a8SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 6767bb6a34a8SMatthew G. Knepley for (d = 0; d < dim; ++d) refVol *= 2.0; 6768bb6a34a8SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 6769bb6a34a8SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 6770bb6a34a8SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFEM(dm, c, NULL, NULL, J, NULL, &detJ);CHKERRQ(ierr); 6771bb6a34a8SMatthew G. Knepley if (detJ <= 0.0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Mesh cell %D is inverted, |J| = %g", c, (double) detJ); 6772bb6a34a8SMatthew G. Knepley ierr = PetscInfo2(dm, "Cell %D FEM Volume %g\n", c, (double) detJ*refVol);CHKERRQ(ierr); 6773bb6a34a8SMatthew G. Knepley if (depth > 1) { 6774bb6a34a8SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFVM(dm, c, &vol, NULL, NULL);CHKERRQ(ierr); 6775bb6a34a8SMatthew G. Knepley if (vol <= 0.0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Mesh cell %d is inverted, vol = %g", c, (double) vol); 6776bb6a34a8SMatthew G. Knepley ierr = PetscInfo2(dm, "Cell %D FVM Volume %g\n", c, (double) vol);CHKERRQ(ierr); 6777bb6a34a8SMatthew G. Knepley } 6778bb6a34a8SMatthew G. Knepley } 6779bb6a34a8SMatthew G. Knepley PetscFunctionReturn(0); 6780bb6a34a8SMatthew G. Knepley } 6781bb6a34a8SMatthew G. Knepley 678203da9461SVaclav Hapla static PetscErrorCode DMPlexAreAllConePointsInArray_Private(DM dm, PetscInt p, PetscInt npoints, const PetscInt *points, PetscInt *missingPoint) 678303da9461SVaclav Hapla { 678403da9461SVaclav Hapla PetscInt i,l,n; 678503da9461SVaclav Hapla const PetscInt *cone; 678603da9461SVaclav Hapla PetscErrorCode ierr; 678703da9461SVaclav Hapla 678803da9461SVaclav Hapla PetscFunctionBegin; 678903da9461SVaclav Hapla *missingPoint = -1; 679003da9461SVaclav Hapla ierr = DMPlexGetConeSize(dm, p, &n);CHKERRQ(ierr); 679103da9461SVaclav Hapla ierr = DMPlexGetCone(dm, p, &cone);CHKERRQ(ierr); 679203da9461SVaclav Hapla for (i=0; i<n; i++) { 679303da9461SVaclav Hapla ierr = PetscFindInt(cone[i], npoints, points, &l);CHKERRQ(ierr); 679403da9461SVaclav Hapla if (l < 0) { 679503da9461SVaclav Hapla *missingPoint = cone[i]; 679603da9461SVaclav Hapla break; 679703da9461SVaclav Hapla } 679803da9461SVaclav Hapla } 679903da9461SVaclav Hapla PetscFunctionReturn(0); 680003da9461SVaclav Hapla } 680103da9461SVaclav Hapla 680203da9461SVaclav Hapla /*@ 680303da9461SVaclav Hapla DMPlexCheckPointSF - Check that several sufficient conditions are met for the point SF of this plex. 680403da9461SVaclav Hapla 680503da9461SVaclav Hapla Input Parameters: 680603da9461SVaclav Hapla . dm - The DMPlex object 680703da9461SVaclav Hapla 680803da9461SVaclav Hapla Note: This is mainly intended for debugging/testing purposes. 680903da9461SVaclav Hapla 681003da9461SVaclav Hapla Level: developer 681103da9461SVaclav Hapla 681203da9461SVaclav Hapla .seealso: DMGetPointSF(), DMPlexCheckSymmetry(), DMPlexCheckSkeleton(), DMPlexCheckFaces() 681303da9461SVaclav Hapla @*/ 681403da9461SVaclav Hapla PetscErrorCode DMPlexCheckPointSF(DM dm) 681503da9461SVaclav Hapla { 681603da9461SVaclav Hapla PetscSF sf; 681703da9461SVaclav Hapla PetscInt d,depth,i,nleaves,p,plo,phi,missingPoint; 681803da9461SVaclav Hapla const PetscInt *locals; 681903da9461SVaclav Hapla PetscErrorCode ierr; 682003da9461SVaclav Hapla 682103da9461SVaclav Hapla PetscFunctionBegin; 682203da9461SVaclav Hapla PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 682303da9461SVaclav Hapla ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 682403da9461SVaclav Hapla ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 682503da9461SVaclav Hapla ierr = PetscSFGetGraph(sf, NULL, &nleaves, &locals, NULL);CHKERRQ(ierr); 682603da9461SVaclav Hapla 6827ece87651SVaclav Hapla /* 1) check there are no faces in 2D, cells in 3D, in interface */ 682803da9461SVaclav Hapla ierr = DMPlexGetVTKCellHeight(dm, &d);CHKERRQ(ierr); 682903da9461SVaclav Hapla ierr = DMPlexGetHeightStratum(dm, d, &plo, &phi);CHKERRQ(ierr); 683003da9461SVaclav Hapla for (i=0; i<nleaves; i++) { 683103da9461SVaclav Hapla p = locals[i]; 683203da9461SVaclav Hapla if (p >= plo && p < phi) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "point SF contains %d which is a cell",p); 683303da9461SVaclav Hapla } 6834ece87651SVaclav Hapla 6835ece87651SVaclav Hapla /* 2) if some point is in interface, then all its cone points must be also in interface */ 6836ece87651SVaclav Hapla for (i=0; i<nleaves; i++) { 6837ece87651SVaclav Hapla p = locals[i]; 6838ece87651SVaclav Hapla ierr = DMPlexAreAllConePointsInArray_Private(dm, p, nleaves, locals, &missingPoint);CHKERRQ(ierr); 6839ece87651SVaclav Hapla if (missingPoint >= 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "point SF contains %d but not %d from its cone",p,missingPoint); 6840ece87651SVaclav Hapla } 684103da9461SVaclav Hapla PetscFunctionReturn(0); 684203da9461SVaclav Hapla } 684303da9461SVaclav Hapla 6844068a5610SStefano Zampini typedef struct cell_stats 6845068a5610SStefano Zampini { 6846068a5610SStefano Zampini PetscReal min, max, sum, squaresum; 6847068a5610SStefano Zampini PetscInt count; 6848068a5610SStefano Zampini } cell_stats_t; 6849068a5610SStefano Zampini 6850068a5610SStefano Zampini static void cell_stats_reduce(void *a, void *b, int * len, MPI_Datatype *datatype) 6851068a5610SStefano Zampini { 6852068a5610SStefano Zampini PetscInt i, N = *len; 6853068a5610SStefano Zampini 6854068a5610SStefano Zampini for (i = 0; i < N; i++) { 6855068a5610SStefano Zampini cell_stats_t *A = (cell_stats_t *) a; 6856068a5610SStefano Zampini cell_stats_t *B = (cell_stats_t *) b; 6857068a5610SStefano Zampini 6858068a5610SStefano Zampini B->min = PetscMin(A->min,B->min); 6859068a5610SStefano Zampini B->max = PetscMax(A->max,B->max); 6860068a5610SStefano Zampini B->sum += A->sum; 6861068a5610SStefano Zampini B->squaresum += A->squaresum; 6862068a5610SStefano Zampini B->count += A->count; 6863068a5610SStefano Zampini } 6864068a5610SStefano Zampini } 6865068a5610SStefano Zampini 6866068a5610SStefano Zampini /*@ 6867068a5610SStefano Zampini DMPlexCheckCellShape - Checks the Jacobian of the mapping and computes some minimal statistics. 6868068a5610SStefano Zampini 6869068a5610SStefano Zampini Input Parameters: 6870068a5610SStefano Zampini + dm - The DMPlex object 6871068a5610SStefano Zampini - output - If true, statistics will be displayed on stdout 6872068a5610SStefano Zampini 6873068a5610SStefano Zampini Note: This is mainly intended for debugging/testing purposes. 6874068a5610SStefano Zampini 6875068a5610SStefano Zampini Level: developer 6876068a5610SStefano Zampini 6877068a5610SStefano Zampini .seealso: DMPlexCheckSymmetry(), DMPlexCheckSkeleton(), DMPlexCheckFaces() 6878068a5610SStefano Zampini @*/ 6879068a5610SStefano Zampini PetscErrorCode DMPlexCheckCellShape(DM dm, PetscBool output) 6880068a5610SStefano Zampini { 6881068a5610SStefano Zampini PetscMPIInt rank,size; 6882068a5610SStefano Zampini PetscInt dim, c, cStart, cEnd, cMax, count = 0; 6883068a5610SStefano Zampini cell_stats_t stats, globalStats; 6884068a5610SStefano Zampini PetscReal *J, *invJ, min = 0, max = 0, mean = 0, stdev = 0; 6885068a5610SStefano Zampini MPI_Comm comm = PetscObjectComm((PetscObject)dm); 6886068a5610SStefano Zampini DM dmCoarse; 6887068a5610SStefano Zampini PetscErrorCode ierr; 6888068a5610SStefano Zampini 6889068a5610SStefano Zampini PetscFunctionBegin; 6890068a5610SStefano Zampini PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6891068a5610SStefano Zampini stats.min = PETSC_MAX_REAL; 6892068a5610SStefano Zampini stats.max = PETSC_MIN_REAL; 6893068a5610SStefano Zampini stats.sum = stats.squaresum = 0.; 6894068a5610SStefano Zampini stats.count = 0; 6895068a5610SStefano Zampini 6896068a5610SStefano Zampini ierr = DMGetCoordinateDim(dm,&dim);CHKERRQ(ierr); 6897068a5610SStefano Zampini ierr = PetscMalloc2(dim * dim, &J, dim * dim, &invJ);CHKERRQ(ierr); 6898068a5610SStefano Zampini ierr = DMPlexGetHeightStratum(dm,0,&cStart,&cEnd);CHKERRQ(ierr); 6899068a5610SStefano Zampini ierr = DMPlexGetHybridBounds(dm,&cMax,NULL,NULL,NULL);CHKERRQ(ierr); 6900068a5610SStefano Zampini cMax = cMax < 0 ? cEnd : cMax; 6901068a5610SStefano Zampini for (c = cStart; c < cMax; c++) { 6902068a5610SStefano Zampini PetscInt i; 6903068a5610SStefano Zampini PetscReal frobJ = 0., frobInvJ = 0., cond2, cond, detJ; 6904068a5610SStefano Zampini 6905068a5610SStefano Zampini ierr = DMPlexComputeCellGeometryAffineFEM(dm,c,NULL,J,invJ,&detJ);CHKERRQ(ierr); 6906068a5610SStefano Zampini if (detJ < 0.0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Mesh cell %D is inverted", c); 6907068a5610SStefano Zampini for (i = 0; i < dim * dim; i++) { 6908068a5610SStefano Zampini frobJ += J[i] * J[i]; 6909068a5610SStefano Zampini frobInvJ += invJ[i] * invJ[i]; 6910068a5610SStefano Zampini } 6911068a5610SStefano Zampini cond2 = frobJ * frobInvJ; 6912068a5610SStefano Zampini cond = PetscSqrtReal(cond2); 6913068a5610SStefano Zampini 6914068a5610SStefano Zampini stats.min = PetscMin(stats.min,cond); 6915068a5610SStefano Zampini stats.max = PetscMax(stats.max,cond); 6916068a5610SStefano Zampini stats.sum += cond; 6917068a5610SStefano Zampini stats.squaresum += cond2; 6918068a5610SStefano Zampini stats.count++; 6919068a5610SStefano Zampini } 6920068a5610SStefano Zampini 6921068a5610SStefano Zampini ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 6922068a5610SStefano Zampini if (size > 1) { 6923068a5610SStefano Zampini PetscMPIInt blockLengths[2] = {4,1}; 6924068a5610SStefano Zampini MPI_Aint blockOffsets[2] = {offsetof(cell_stats_t,min),offsetof(cell_stats_t,count)}; 6925068a5610SStefano Zampini MPI_Datatype blockTypes[2] = {MPIU_REAL,MPIU_INT}, statType; 6926068a5610SStefano Zampini MPI_Op statReduce; 6927068a5610SStefano Zampini 6928068a5610SStefano Zampini ierr = MPI_Type_create_struct(2,blockLengths,blockOffsets,blockTypes,&statType);CHKERRQ(ierr); 6929068a5610SStefano Zampini ierr = MPI_Type_commit(&statType);CHKERRQ(ierr); 6930068a5610SStefano Zampini ierr = MPI_Op_create(cell_stats_reduce, PETSC_TRUE, &statReduce);CHKERRQ(ierr); 6931068a5610SStefano Zampini ierr = MPI_Reduce(&stats,&globalStats,1,statType,statReduce,0,comm);CHKERRQ(ierr); 6932068a5610SStefano Zampini ierr = MPI_Op_free(&statReduce);CHKERRQ(ierr); 6933068a5610SStefano Zampini ierr = MPI_Type_free(&statType);CHKERRQ(ierr); 6934068a5610SStefano Zampini } else { 6935068a5610SStefano Zampini ierr = PetscMemcpy(&globalStats,&stats,sizeof(stats));CHKERRQ(ierr); 6936068a5610SStefano Zampini } 6937068a5610SStefano Zampini 6938068a5610SStefano Zampini ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 6939068a5610SStefano Zampini if (!rank) { 6940068a5610SStefano Zampini count = globalStats.count; 6941068a5610SStefano Zampini min = globalStats.min; 6942068a5610SStefano Zampini max = globalStats.max; 6943068a5610SStefano Zampini mean = globalStats.sum / globalStats.count; 6944068a5610SStefano Zampini stdev = globalStats.count > 1 ? PetscSqrtReal(PetscMax((globalStats.squaresum - globalStats.count * mean * mean) / (globalStats.count - 1),0)) : 0.0; 6945068a5610SStefano Zampini } 6946068a5610SStefano Zampini 6947068a5610SStefano Zampini if (output) { 6948068a5610SStefano Zampini ierr = PetscPrintf(comm,"Mesh with %D cells, shape condition numbers: min = %g, max = %g, mean = %g, stddev = %g\n", count, (double) min, (double) max, (double) mean, (double) stdev);CHKERRQ(ierr); 6949068a5610SStefano Zampini } 6950068a5610SStefano Zampini ierr = PetscFree2(J,invJ);CHKERRQ(ierr); 6951068a5610SStefano Zampini 6952068a5610SStefano Zampini ierr = DMGetCoarseDM(dm,&dmCoarse);CHKERRQ(ierr); 6953068a5610SStefano Zampini if (dmCoarse) { 6954068a5610SStefano Zampini PetscBool isplex; 6955068a5610SStefano Zampini 6956068a5610SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)dmCoarse,DMPLEX,&isplex);CHKERRQ(ierr); 6957068a5610SStefano Zampini if (isplex) { 6958068a5610SStefano Zampini ierr = DMPlexCheckCellShape(dmCoarse,output);CHKERRQ(ierr); 6959068a5610SStefano Zampini } 6960068a5610SStefano Zampini } 6961068a5610SStefano Zampini PetscFunctionReturn(0); 6962068a5610SStefano Zampini } 6963068a5610SStefano Zampini 6964bceba477SMatthew G. Knepley /* Pointwise interpolation 6965bceba477SMatthew G. Knepley Just code FEM for now 6966bceba477SMatthew G. Knepley u^f = I u^c 69674ca5e9f5SMatthew G. Knepley sum_k u^f_k phi^f_k = I sum_j u^c_j phi^c_j 69684ca5e9f5SMatthew G. Knepley u^f_i = sum_j psi^f_i I phi^c_j u^c_j 69694ca5e9f5SMatthew G. Knepley I_{ij} = psi^f_i phi^c_j 6970bceba477SMatthew G. Knepley */ 6971bceba477SMatthew G. Knepley PetscErrorCode DMCreateInterpolation_Plex(DM dmCoarse, DM dmFine, Mat *interpolation, Vec *scaling) 6972bceba477SMatthew G. Knepley { 6973bceba477SMatthew G. Knepley PetscSection gsc, gsf; 6974bceba477SMatthew G. Knepley PetscInt m, n; 6975a063dac3SMatthew G. Knepley void *ctx; 697668132eb9SMatthew G. Knepley DM cdm; 6977fd194bc8SStefano Zampini PetscBool regular, ismatis; 6978bceba477SMatthew G. Knepley PetscErrorCode ierr; 6979bceba477SMatthew G. Knepley 6980bceba477SMatthew G. Knepley PetscFunctionBegin; 6981e87a4003SBarry Smith ierr = DMGetGlobalSection(dmFine, &gsf);CHKERRQ(ierr); 6982bceba477SMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(gsf, &m);CHKERRQ(ierr); 6983e87a4003SBarry Smith ierr = DMGetGlobalSection(dmCoarse, &gsc);CHKERRQ(ierr); 6984bceba477SMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(gsc, &n);CHKERRQ(ierr); 698568132eb9SMatthew G. Knepley 6986fd194bc8SStefano Zampini ierr = PetscStrcmp(dmCoarse->mattype, MATIS, &ismatis);CHKERRQ(ierr); 6987bceba477SMatthew G. Knepley ierr = MatCreate(PetscObjectComm((PetscObject) dmCoarse), interpolation);CHKERRQ(ierr); 6988bceba477SMatthew G. Knepley ierr = MatSetSizes(*interpolation, m, n, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 6989fd194bc8SStefano Zampini ierr = MatSetType(*interpolation, ismatis ? MATAIJ : dmCoarse->mattype);CHKERRQ(ierr); 6990a063dac3SMatthew G. Knepley ierr = DMGetApplicationContext(dmFine, &ctx);CHKERRQ(ierr); 699168132eb9SMatthew G. Knepley 6992a8fb8f29SToby Isaac ierr = DMGetCoarseDM(dmFine, &cdm);CHKERRQ(ierr); 699368132eb9SMatthew G. Knepley ierr = DMPlexGetRegularRefinement(dmFine, ®ular);CHKERRQ(ierr); 699468132eb9SMatthew G. Knepley if (regular && cdm == dmCoarse) {ierr = DMPlexComputeInterpolatorNested(dmCoarse, dmFine, *interpolation, ctx);CHKERRQ(ierr);} 699568132eb9SMatthew G. Knepley else {ierr = DMPlexComputeInterpolatorGeneral(dmCoarse, dmFine, *interpolation, ctx);CHKERRQ(ierr);} 699668132eb9SMatthew G. Knepley ierr = MatViewFromOptions(*interpolation, NULL, "-interp_mat_view");CHKERRQ(ierr); 69974db47ee9SStefano Zampini if (scaling) { 69985d1c2e58SMatthew G. Knepley /* Use naive scaling */ 69995d1c2e58SMatthew G. Knepley ierr = DMCreateInterpolationScale(dmCoarse, dmFine, *interpolation, scaling);CHKERRQ(ierr); 70004db47ee9SStefano Zampini } 7001a063dac3SMatthew G. Knepley PetscFunctionReturn(0); 7002a063dac3SMatthew G. Knepley } 7003bceba477SMatthew G. Knepley 70046dbf9973SLawrence Mitchell PetscErrorCode DMCreateInjection_Plex(DM dmCoarse, DM dmFine, Mat *mat) 7005a063dac3SMatthew G. Knepley { 700690748bafSMatthew G. Knepley PetscErrorCode ierr; 70076dbf9973SLawrence Mitchell VecScatter ctx; 700890748bafSMatthew G. Knepley 7009a063dac3SMatthew G. Knepley PetscFunctionBegin; 70106dbf9973SLawrence Mitchell ierr = DMPlexComputeInjectorFEM(dmCoarse, dmFine, &ctx, NULL);CHKERRQ(ierr); 70116dbf9973SLawrence Mitchell ierr = MatCreateScatter(PetscObjectComm((PetscObject)ctx), ctx, mat);CHKERRQ(ierr); 70126dbf9973SLawrence Mitchell ierr = VecScatterDestroy(&ctx);CHKERRQ(ierr); 7013bceba477SMatthew G. Knepley PetscFunctionReturn(0); 7014bceba477SMatthew G. Knepley } 7015bceba477SMatthew G. Knepley 7016bd041c0cSMatthew G. Knepley PetscErrorCode DMCreateMassMatrix_Plex(DM dmCoarse, DM dmFine, Mat *mass) 7017bd041c0cSMatthew G. Knepley { 7018bd041c0cSMatthew G. Knepley PetscSection gsc, gsf; 7019bd041c0cSMatthew G. Knepley PetscInt m, n; 7020bd041c0cSMatthew G. Knepley void *ctx; 7021bd041c0cSMatthew G. Knepley DM cdm; 7022bd041c0cSMatthew G. Knepley PetscBool regular; 7023bd041c0cSMatthew G. Knepley PetscErrorCode ierr; 7024bd041c0cSMatthew G. Knepley 7025bd041c0cSMatthew G. Knepley PetscFunctionBegin; 7026e87a4003SBarry Smith ierr = DMGetGlobalSection(dmFine, &gsf);CHKERRQ(ierr); 7027bd041c0cSMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(gsf, &m);CHKERRQ(ierr); 7028e87a4003SBarry Smith ierr = DMGetGlobalSection(dmCoarse, &gsc);CHKERRQ(ierr); 7029bd041c0cSMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(gsc, &n);CHKERRQ(ierr); 7030bd041c0cSMatthew G. Knepley 7031bd041c0cSMatthew G. Knepley ierr = MatCreate(PetscObjectComm((PetscObject) dmCoarse), mass);CHKERRQ(ierr); 7032bd041c0cSMatthew G. Knepley ierr = MatSetSizes(*mass, m, n, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 7033bd041c0cSMatthew G. Knepley ierr = MatSetType(*mass, dmCoarse->mattype);CHKERRQ(ierr); 7034bd041c0cSMatthew G. Knepley ierr = DMGetApplicationContext(dmFine, &ctx);CHKERRQ(ierr); 7035bd041c0cSMatthew G. Knepley 7036bd041c0cSMatthew G. Knepley ierr = DMGetCoarseDM(dmFine, &cdm);CHKERRQ(ierr); 7037bd041c0cSMatthew G. Knepley ierr = DMPlexGetRegularRefinement(dmFine, ®ular);CHKERRQ(ierr); 7038bd041c0cSMatthew G. Knepley if (regular && cdm == dmCoarse) {ierr = DMPlexComputeMassMatrixNested(dmCoarse, dmFine, *mass, ctx);CHKERRQ(ierr);} 7039bd041c0cSMatthew G. Knepley else {ierr = DMPlexComputeMassMatrixGeneral(dmCoarse, dmFine, *mass, ctx);CHKERRQ(ierr);} 7040bd041c0cSMatthew G. Knepley ierr = MatViewFromOptions(*mass, NULL, "-mass_mat_view");CHKERRQ(ierr); 7041bd041c0cSMatthew G. Knepley PetscFunctionReturn(0); 7042bd041c0cSMatthew G. Knepley } 7043bd041c0cSMatthew G. Knepley 70440aef6b92SMatthew G. Knepley /*@ 70450aef6b92SMatthew G. Knepley DMPlexGetRegularRefinement - Get the flag indicating that this mesh was obtained by regular refinement from its coarse mesh 70460aef6b92SMatthew G. Knepley 70470aef6b92SMatthew G. Knepley Input Parameter: 70480aef6b92SMatthew G. Knepley . dm - The DMPlex object 70490aef6b92SMatthew G. Knepley 70500aef6b92SMatthew G. Knepley Output Parameter: 70510aef6b92SMatthew G. Knepley . regular - The flag 70520aef6b92SMatthew G. Knepley 70530aef6b92SMatthew G. Knepley Level: intermediate 70540aef6b92SMatthew G. Knepley 70550aef6b92SMatthew G. Knepley .seealso: DMPlexSetRegularRefinement() 70560aef6b92SMatthew G. Knepley @*/ 70570aef6b92SMatthew G. Knepley PetscErrorCode DMPlexGetRegularRefinement(DM dm, PetscBool *regular) 70580aef6b92SMatthew G. Knepley { 70590aef6b92SMatthew G. Knepley PetscFunctionBegin; 70600aef6b92SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 70610aef6b92SMatthew G. Knepley PetscValidPointer(regular, 2); 70620aef6b92SMatthew G. Knepley *regular = ((DM_Plex *) dm->data)->regularRefinement; 70630aef6b92SMatthew G. Knepley PetscFunctionReturn(0); 70640aef6b92SMatthew G. Knepley } 70650aef6b92SMatthew G. Knepley 70660aef6b92SMatthew G. Knepley /*@ 70670aef6b92SMatthew G. Knepley DMPlexSetRegularRefinement - Set the flag indicating that this mesh was obtained by regular refinement from its coarse mesh 70680aef6b92SMatthew G. Knepley 70690aef6b92SMatthew G. Knepley Input Parameters: 70700aef6b92SMatthew G. Knepley + dm - The DMPlex object 70710aef6b92SMatthew G. Knepley - regular - The flag 70720aef6b92SMatthew G. Knepley 70730aef6b92SMatthew G. Knepley Level: intermediate 70740aef6b92SMatthew G. Knepley 70750aef6b92SMatthew G. Knepley .seealso: DMPlexGetRegularRefinement() 70760aef6b92SMatthew G. Knepley @*/ 70770aef6b92SMatthew G. Knepley PetscErrorCode DMPlexSetRegularRefinement(DM dm, PetscBool regular) 70780aef6b92SMatthew G. Knepley { 70790aef6b92SMatthew G. Knepley PetscFunctionBegin; 70800aef6b92SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 70810aef6b92SMatthew G. Knepley ((DM_Plex *) dm->data)->regularRefinement = regular; 70820aef6b92SMatthew G. Knepley PetscFunctionReturn(0); 70830aef6b92SMatthew G. Knepley } 70840aef6b92SMatthew G. Knepley 7085f7c74593SToby Isaac /* anchors */ 7086a68b90caSToby Isaac /*@ 7087f7c74593SToby Isaac DMPlexGetAnchors - Get the layout of the anchor (point-to-point) constraints. Typically, the user will not have to 7088f7c74593SToby Isaac call DMPlexGetAnchors() directly: if there are anchors, then DMPlexGetAnchors() is called during DMGetConstraints(). 7089a68b90caSToby Isaac 7090e228b242SToby Isaac not collective 7091a68b90caSToby Isaac 7092a68b90caSToby Isaac Input Parameters: 7093a68b90caSToby Isaac . dm - The DMPlex object 7094a68b90caSToby Isaac 7095a68b90caSToby Isaac Output Parameters: 7096a68b90caSToby Isaac + anchorSection - If not NULL, set to the section describing which points anchor the constrained points. 7097a68b90caSToby Isaac - anchorIS - If not NULL, set to the list of anchors indexed by anchorSection 7098a68b90caSToby Isaac 7099a68b90caSToby Isaac 7100a68b90caSToby Isaac Level: intermediate 7101a68b90caSToby Isaac 7102f7c74593SToby Isaac .seealso: DMPlexSetAnchors(), DMGetConstraints(), DMSetConstraints() 7103a68b90caSToby Isaac @*/ 7104a17985deSToby Isaac PetscErrorCode DMPlexGetAnchors(DM dm, PetscSection *anchorSection, IS *anchorIS) 7105a68b90caSToby Isaac { 7106a68b90caSToby Isaac DM_Plex *plex = (DM_Plex *)dm->data; 710741e6d900SToby Isaac PetscErrorCode ierr; 7108a68b90caSToby Isaac 7109a68b90caSToby Isaac PetscFunctionBegin; 7110a68b90caSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 711141e6d900SToby Isaac if (!plex->anchorSection && !plex->anchorIS && plex->createanchors) {ierr = (*plex->createanchors)(dm);CHKERRQ(ierr);} 7112a68b90caSToby Isaac if (anchorSection) *anchorSection = plex->anchorSection; 7113a68b90caSToby Isaac if (anchorIS) *anchorIS = plex->anchorIS; 7114a68b90caSToby Isaac PetscFunctionReturn(0); 7115a68b90caSToby Isaac } 7116a68b90caSToby Isaac 7117a68b90caSToby Isaac /*@ 7118f7c74593SToby Isaac DMPlexSetAnchors - Set the layout of the local anchor (point-to-point) constraints. Unlike boundary conditions, 7119f7c74593SToby Isaac when a point's degrees of freedom in a section are constrained to an outside value, the anchor constraints set a 7120a68b90caSToby Isaac point's degrees of freedom to be a linear combination of other points' degrees of freedom. 7121a68b90caSToby Isaac 7122a17985deSToby Isaac After specifying the layout of constraints with DMPlexSetAnchors(), one specifies the constraints by calling 7123f7c74593SToby Isaac DMGetConstraints() and filling in the entries in the constraint matrix. 7124a68b90caSToby Isaac 7125e228b242SToby Isaac collective on dm 7126a68b90caSToby Isaac 7127a68b90caSToby Isaac Input Parameters: 7128a68b90caSToby Isaac + dm - The DMPlex object 7129e228b242SToby Isaac . anchorSection - The section that describes the mapping from constrained points to the anchor points listed in anchorIS. Must have a local communicator (PETSC_COMM_SELF or derivative). 7130e228b242SToby Isaac - anchorIS - The list of all anchor points. Must have a local communicator (PETSC_COMM_SELF or derivative). 7131a68b90caSToby Isaac 7132a68b90caSToby Isaac The reference counts of anchorSection and anchorIS are incremented. 7133a68b90caSToby Isaac 7134a68b90caSToby Isaac Level: intermediate 7135a68b90caSToby Isaac 7136f7c74593SToby Isaac .seealso: DMPlexGetAnchors(), DMGetConstraints(), DMSetConstraints() 7137a68b90caSToby Isaac @*/ 7138a17985deSToby Isaac PetscErrorCode DMPlexSetAnchors(DM dm, PetscSection anchorSection, IS anchorIS) 7139a68b90caSToby Isaac { 7140a68b90caSToby Isaac DM_Plex *plex = (DM_Plex *)dm->data; 7141e228b242SToby Isaac PetscMPIInt result; 7142a68b90caSToby Isaac PetscErrorCode ierr; 7143a68b90caSToby Isaac 7144a68b90caSToby Isaac PetscFunctionBegin; 7145a68b90caSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7146e228b242SToby Isaac if (anchorSection) { 7147e228b242SToby Isaac PetscValidHeaderSpecific(anchorSection,PETSC_SECTION_CLASSID,2); 7148e228b242SToby Isaac ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)anchorSection),&result);CHKERRQ(ierr); 7149f6a3d38cSToby Isaac if (result != MPI_CONGRUENT && result != MPI_IDENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"anchor section must have local communicator"); 7150e228b242SToby Isaac } 7151e228b242SToby Isaac if (anchorIS) { 7152e228b242SToby Isaac PetscValidHeaderSpecific(anchorIS,IS_CLASSID,3); 7153e228b242SToby Isaac ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)anchorIS),&result);CHKERRQ(ierr); 7154f6a3d38cSToby Isaac if (result != MPI_CONGRUENT && result != MPI_IDENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"anchor IS must have local communicator"); 7155e228b242SToby Isaac } 7156a68b90caSToby Isaac 7157a68b90caSToby Isaac ierr = PetscObjectReference((PetscObject)anchorSection);CHKERRQ(ierr); 7158a68b90caSToby Isaac ierr = PetscSectionDestroy(&plex->anchorSection);CHKERRQ(ierr); 7159a68b90caSToby Isaac plex->anchorSection = anchorSection; 7160a68b90caSToby Isaac 7161a68b90caSToby Isaac ierr = PetscObjectReference((PetscObject)anchorIS);CHKERRQ(ierr); 7162a68b90caSToby Isaac ierr = ISDestroy(&plex->anchorIS);CHKERRQ(ierr); 7163a68b90caSToby Isaac plex->anchorIS = anchorIS; 7164a68b90caSToby Isaac 7165a68b90caSToby Isaac #if defined(PETSC_USE_DEBUG) 7166a68b90caSToby Isaac if (anchorIS && anchorSection) { 7167a68b90caSToby Isaac PetscInt size, a, pStart, pEnd; 7168a68b90caSToby Isaac const PetscInt *anchors; 7169a68b90caSToby Isaac 7170a68b90caSToby Isaac ierr = PetscSectionGetChart(anchorSection,&pStart,&pEnd);CHKERRQ(ierr); 7171a68b90caSToby Isaac ierr = ISGetLocalSize(anchorIS,&size);CHKERRQ(ierr); 7172a68b90caSToby Isaac ierr = ISGetIndices(anchorIS,&anchors);CHKERRQ(ierr); 7173a68b90caSToby Isaac for (a = 0; a < size; a++) { 7174a68b90caSToby Isaac PetscInt p; 7175a68b90caSToby Isaac 7176a68b90caSToby Isaac p = anchors[a]; 7177a68b90caSToby Isaac if (p >= pStart && p < pEnd) { 7178a68b90caSToby Isaac PetscInt dof; 7179a68b90caSToby Isaac 7180a68b90caSToby Isaac ierr = PetscSectionGetDof(anchorSection,p,&dof);CHKERRQ(ierr); 7181a68b90caSToby Isaac if (dof) { 7182a68b90caSToby Isaac PetscErrorCode ierr2; 7183a68b90caSToby Isaac 7184a68b90caSToby Isaac ierr2 = ISRestoreIndices(anchorIS,&anchors);CHKERRQ(ierr2); 71858ccfff9cSToby Isaac SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Point %D cannot be constrained and an anchor",p); 7186a68b90caSToby Isaac } 7187a68b90caSToby Isaac } 7188a68b90caSToby Isaac } 7189a68b90caSToby Isaac ierr = ISRestoreIndices(anchorIS,&anchors);CHKERRQ(ierr); 7190a68b90caSToby Isaac } 7191a68b90caSToby Isaac #endif 7192f7c74593SToby Isaac /* reset the generic constraints */ 7193f7c74593SToby Isaac ierr = DMSetDefaultConstraints(dm,NULL,NULL);CHKERRQ(ierr); 7194a68b90caSToby Isaac PetscFunctionReturn(0); 7195a68b90caSToby Isaac } 7196a68b90caSToby Isaac 7197f7c74593SToby Isaac static PetscErrorCode DMPlexCreateConstraintSection_Anchors(DM dm, PetscSection section, PetscSection *cSec) 7198a68b90caSToby Isaac { 7199f7c74593SToby Isaac PetscSection anchorSection; 72006995de1eSToby Isaac PetscInt pStart, pEnd, sStart, sEnd, p, dof, numFields, f; 7201a68b90caSToby Isaac PetscErrorCode ierr; 7202a68b90caSToby Isaac 7203a68b90caSToby Isaac PetscFunctionBegin; 7204a68b90caSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7205a17985deSToby Isaac ierr = DMPlexGetAnchors(dm,&anchorSection,NULL);CHKERRQ(ierr); 7206e228b242SToby Isaac ierr = PetscSectionCreate(PETSC_COMM_SELF,cSec);CHKERRQ(ierr); 7207a68b90caSToby Isaac ierr = PetscSectionGetNumFields(section,&numFields);CHKERRQ(ierr); 72086995de1eSToby Isaac if (numFields) { 7209719ab38cSToby Isaac PetscInt f; 7210a68b90caSToby Isaac ierr = PetscSectionSetNumFields(*cSec,numFields);CHKERRQ(ierr); 7211719ab38cSToby Isaac 7212719ab38cSToby Isaac for (f = 0; f < numFields; f++) { 7213719ab38cSToby Isaac PetscInt numComp; 7214719ab38cSToby Isaac 7215719ab38cSToby Isaac ierr = PetscSectionGetFieldComponents(section,f,&numComp);CHKERRQ(ierr); 7216719ab38cSToby Isaac ierr = PetscSectionSetFieldComponents(*cSec,f,numComp);CHKERRQ(ierr); 7217719ab38cSToby Isaac } 72186995de1eSToby Isaac } 7219a68b90caSToby Isaac ierr = PetscSectionGetChart(anchorSection,&pStart,&pEnd);CHKERRQ(ierr); 72206995de1eSToby Isaac ierr = PetscSectionGetChart(section,&sStart,&sEnd);CHKERRQ(ierr); 72216995de1eSToby Isaac pStart = PetscMax(pStart,sStart); 72226995de1eSToby Isaac pEnd = PetscMin(pEnd,sEnd); 72236995de1eSToby Isaac pEnd = PetscMax(pStart,pEnd); 7224a68b90caSToby Isaac ierr = PetscSectionSetChart(*cSec,pStart,pEnd);CHKERRQ(ierr); 7225a68b90caSToby Isaac for (p = pStart; p < pEnd; p++) { 7226a68b90caSToby Isaac ierr = PetscSectionGetDof(anchorSection,p,&dof);CHKERRQ(ierr); 7227a68b90caSToby Isaac if (dof) { 7228a68b90caSToby Isaac ierr = PetscSectionGetDof(section,p,&dof);CHKERRQ(ierr); 7229a68b90caSToby Isaac ierr = PetscSectionSetDof(*cSec,p,dof);CHKERRQ(ierr); 7230a68b90caSToby Isaac for (f = 0; f < numFields; f++) { 7231a68b90caSToby Isaac ierr = PetscSectionGetFieldDof(section,p,f,&dof);CHKERRQ(ierr); 7232a68b90caSToby Isaac ierr = PetscSectionSetFieldDof(*cSec,p,f,dof);CHKERRQ(ierr); 7233a68b90caSToby Isaac } 7234a68b90caSToby Isaac } 7235a68b90caSToby Isaac } 7236a68b90caSToby Isaac ierr = PetscSectionSetUp(*cSec);CHKERRQ(ierr); 7237a68b90caSToby Isaac PetscFunctionReturn(0); 7238a68b90caSToby Isaac } 7239a68b90caSToby Isaac 7240f7c74593SToby Isaac static PetscErrorCode DMPlexCreateConstraintMatrix_Anchors(DM dm, PetscSection section, PetscSection cSec, Mat *cMat) 7241a68b90caSToby Isaac { 7242f7c74593SToby Isaac PetscSection aSec; 72430ac89760SToby Isaac PetscInt pStart, pEnd, p, dof, aDof, aOff, off, nnz, annz, m, n, q, a, offset, *i, *j; 72440ac89760SToby Isaac const PetscInt *anchors; 72450ac89760SToby Isaac PetscInt numFields, f; 724666ad2231SToby Isaac IS aIS; 72470ac89760SToby Isaac PetscErrorCode ierr; 72480ac89760SToby Isaac 72490ac89760SToby Isaac PetscFunctionBegin; 72500ac89760SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 72510ac89760SToby Isaac ierr = PetscSectionGetStorageSize(cSec, &m);CHKERRQ(ierr); 72520ac89760SToby Isaac ierr = PetscSectionGetStorageSize(section, &n);CHKERRQ(ierr); 72530ac89760SToby Isaac ierr = MatCreate(PETSC_COMM_SELF,cMat);CHKERRQ(ierr); 72540ac89760SToby Isaac ierr = MatSetSizes(*cMat,m,n,m,n);CHKERRQ(ierr); 7255302440fdSBarry Smith ierr = MatSetType(*cMat,MATSEQAIJ);CHKERRQ(ierr); 7256a17985deSToby Isaac ierr = DMPlexGetAnchors(dm,&aSec,&aIS);CHKERRQ(ierr); 725766ad2231SToby Isaac ierr = ISGetIndices(aIS,&anchors);CHKERRQ(ierr); 72586995de1eSToby Isaac /* cSec will be a subset of aSec and section */ 72596995de1eSToby Isaac ierr = PetscSectionGetChart(cSec,&pStart,&pEnd);CHKERRQ(ierr); 72600ac89760SToby Isaac ierr = PetscMalloc1(m+1,&i);CHKERRQ(ierr); 72610ac89760SToby Isaac i[0] = 0; 72620ac89760SToby Isaac ierr = PetscSectionGetNumFields(section,&numFields);CHKERRQ(ierr); 72630ac89760SToby Isaac for (p = pStart; p < pEnd; p++) { 7264f19733c5SToby Isaac PetscInt rDof, rOff, r; 7265f19733c5SToby Isaac 7266f19733c5SToby Isaac ierr = PetscSectionGetDof(aSec,p,&rDof);CHKERRQ(ierr); 7267f19733c5SToby Isaac if (!rDof) continue; 7268f19733c5SToby Isaac ierr = PetscSectionGetOffset(aSec,p,&rOff);CHKERRQ(ierr); 72690ac89760SToby Isaac if (numFields) { 72700ac89760SToby Isaac for (f = 0; f < numFields; f++) { 72710ac89760SToby Isaac annz = 0; 7272f19733c5SToby Isaac for (r = 0; r < rDof; r++) { 7273f19733c5SToby Isaac a = anchors[rOff + r]; 72740ac89760SToby Isaac ierr = PetscSectionGetFieldDof(section,a,f,&aDof);CHKERRQ(ierr); 72750ac89760SToby Isaac annz += aDof; 72760ac89760SToby Isaac } 72770ac89760SToby Isaac ierr = PetscSectionGetFieldDof(cSec,p,f,&dof);CHKERRQ(ierr); 72780ac89760SToby Isaac ierr = PetscSectionGetFieldOffset(cSec,p,f,&off);CHKERRQ(ierr); 72790ac89760SToby Isaac for (q = 0; q < dof; q++) { 72800ac89760SToby Isaac i[off + q + 1] = i[off + q] + annz; 72810ac89760SToby Isaac } 72820ac89760SToby Isaac } 72830ac89760SToby Isaac } 72840ac89760SToby Isaac else { 72850ac89760SToby Isaac annz = 0; 72860ac89760SToby Isaac for (q = 0; q < dof; q++) { 72870ac89760SToby Isaac a = anchors[off + q]; 72880ac89760SToby Isaac ierr = PetscSectionGetDof(section,a,&aDof);CHKERRQ(ierr); 72890ac89760SToby Isaac annz += aDof; 72900ac89760SToby Isaac } 72910ac89760SToby Isaac ierr = PetscSectionGetDof(cSec,p,&dof);CHKERRQ(ierr); 72920ac89760SToby Isaac ierr = PetscSectionGetOffset(cSec,p,&off);CHKERRQ(ierr); 72930ac89760SToby Isaac for (q = 0; q < dof; q++) { 72940ac89760SToby Isaac i[off + q + 1] = i[off + q] + annz; 72950ac89760SToby Isaac } 72960ac89760SToby Isaac } 72970ac89760SToby Isaac } 72980ac89760SToby Isaac nnz = i[m]; 72990ac89760SToby Isaac ierr = PetscMalloc1(nnz,&j);CHKERRQ(ierr); 73000ac89760SToby Isaac offset = 0; 73010ac89760SToby Isaac for (p = pStart; p < pEnd; p++) { 73020ac89760SToby Isaac if (numFields) { 73030ac89760SToby Isaac for (f = 0; f < numFields; f++) { 73040ac89760SToby Isaac ierr = PetscSectionGetFieldDof(cSec,p,f,&dof);CHKERRQ(ierr); 73050ac89760SToby Isaac for (q = 0; q < dof; q++) { 73060ac89760SToby Isaac PetscInt rDof, rOff, r; 73070ac89760SToby Isaac ierr = PetscSectionGetDof(aSec,p,&rDof);CHKERRQ(ierr); 73080ac89760SToby Isaac ierr = PetscSectionGetOffset(aSec,p,&rOff);CHKERRQ(ierr); 73090ac89760SToby Isaac for (r = 0; r < rDof; r++) { 73100ac89760SToby Isaac PetscInt s; 73110ac89760SToby Isaac 73120ac89760SToby Isaac a = anchors[rOff + r]; 73130ac89760SToby Isaac ierr = PetscSectionGetFieldDof(section,a,f,&aDof);CHKERRQ(ierr); 73140ac89760SToby Isaac ierr = PetscSectionGetFieldOffset(section,a,f,&aOff);CHKERRQ(ierr); 73150ac89760SToby Isaac for (s = 0; s < aDof; s++) { 73160ac89760SToby Isaac j[offset++] = aOff + s; 73170ac89760SToby Isaac } 73180ac89760SToby Isaac } 73190ac89760SToby Isaac } 73200ac89760SToby Isaac } 73210ac89760SToby Isaac } 73220ac89760SToby Isaac else { 73230ac89760SToby Isaac ierr = PetscSectionGetDof(cSec,p,&dof);CHKERRQ(ierr); 73240ac89760SToby Isaac for (q = 0; q < dof; q++) { 73250ac89760SToby Isaac PetscInt rDof, rOff, r; 73260ac89760SToby Isaac ierr = PetscSectionGetDof(aSec,p,&rDof);CHKERRQ(ierr); 73270ac89760SToby Isaac ierr = PetscSectionGetOffset(aSec,p,&rOff);CHKERRQ(ierr); 73280ac89760SToby Isaac for (r = 0; r < rDof; r++) { 73290ac89760SToby Isaac PetscInt s; 73300ac89760SToby Isaac 73310ac89760SToby Isaac a = anchors[rOff + r]; 73320ac89760SToby Isaac ierr = PetscSectionGetDof(section,a,&aDof);CHKERRQ(ierr); 73330ac89760SToby Isaac ierr = PetscSectionGetOffset(section,a,&aOff);CHKERRQ(ierr); 73340ac89760SToby Isaac for (s = 0; s < aDof; s++) { 73350ac89760SToby Isaac j[offset++] = aOff + s; 73360ac89760SToby Isaac } 73370ac89760SToby Isaac } 73380ac89760SToby Isaac } 73390ac89760SToby Isaac } 73400ac89760SToby Isaac } 73410ac89760SToby Isaac ierr = MatSeqAIJSetPreallocationCSR(*cMat,i,j,NULL);CHKERRQ(ierr); 734225570a81SToby Isaac ierr = PetscFree(i);CHKERRQ(ierr); 734325570a81SToby Isaac ierr = PetscFree(j);CHKERRQ(ierr); 734466ad2231SToby Isaac ierr = ISRestoreIndices(aIS,&anchors);CHKERRQ(ierr); 73450ac89760SToby Isaac PetscFunctionReturn(0); 73460ac89760SToby Isaac } 73470ac89760SToby Isaac 734866ad2231SToby Isaac PetscErrorCode DMCreateDefaultConstraints_Plex(DM dm) 734966ad2231SToby Isaac { 7350f7c74593SToby Isaac DM_Plex *plex = (DM_Plex *)dm->data; 7351f7c74593SToby Isaac PetscSection anchorSection, section, cSec; 735266ad2231SToby Isaac Mat cMat; 735366ad2231SToby Isaac PetscErrorCode ierr; 735466ad2231SToby Isaac 735566ad2231SToby Isaac PetscFunctionBegin; 735666ad2231SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7357a17985deSToby Isaac ierr = DMPlexGetAnchors(dm,&anchorSection,NULL);CHKERRQ(ierr); 735866ad2231SToby Isaac if (anchorSection) { 735944a7f3ddSMatthew G. Knepley PetscInt Nf; 7360e228b242SToby Isaac 7361e87a4003SBarry Smith ierr = DMGetSection(dm,§ion);CHKERRQ(ierr); 7362f7c74593SToby Isaac ierr = DMPlexCreateConstraintSection_Anchors(dm,section,&cSec);CHKERRQ(ierr); 7363f7c74593SToby Isaac ierr = DMPlexCreateConstraintMatrix_Anchors(dm,section,cSec,&cMat);CHKERRQ(ierr); 736444a7f3ddSMatthew G. Knepley ierr = DMGetNumFields(dm,&Nf);CHKERRQ(ierr); 736544a7f3ddSMatthew G. Knepley if (Nf && plex->computeanchormatrix) {ierr = (*plex->computeanchormatrix)(dm,section,cSec,cMat);CHKERRQ(ierr);} 736666ad2231SToby Isaac ierr = DMSetDefaultConstraints(dm,cSec,cMat);CHKERRQ(ierr); 736766ad2231SToby Isaac ierr = PetscSectionDestroy(&cSec);CHKERRQ(ierr); 736866ad2231SToby Isaac ierr = MatDestroy(&cMat);CHKERRQ(ierr); 736966ad2231SToby Isaac } 737066ad2231SToby Isaac PetscFunctionReturn(0); 737166ad2231SToby Isaac } 7372a93c429eSMatthew G. Knepley 7373a93c429eSMatthew G. Knepley PetscErrorCode DMCreateSubDomainDM_Plex(DM dm, DMLabel label, PetscInt value, IS *is, DM *subdm) 7374a93c429eSMatthew G. Knepley { 7375a93c429eSMatthew G. Knepley IS subis; 7376a93c429eSMatthew G. Knepley PetscSection section, subsection; 7377a93c429eSMatthew G. Knepley PetscErrorCode ierr; 7378a93c429eSMatthew G. Knepley 7379a93c429eSMatthew G. Knepley PetscFunctionBegin; 7380a93c429eSMatthew G. Knepley ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr); 7381a93c429eSMatthew G. Knepley if (!section) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Must set default section for DM before splitting subdomain"); 7382a93c429eSMatthew G. Knepley if (!subdm) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Must set output subDM for splitting subdomain"); 7383a93c429eSMatthew G. Knepley /* Create subdomain */ 7384a93c429eSMatthew G. Knepley ierr = DMPlexFilter(dm, label, value, subdm);CHKERRQ(ierr); 7385a93c429eSMatthew G. Knepley /* Create submodel */ 7386a93c429eSMatthew G. Knepley ierr = DMPlexCreateSubpointIS(*subdm, &subis);CHKERRQ(ierr); 7387a93c429eSMatthew G. Knepley ierr = PetscSectionCreateSubmeshSection(section, subis, &subsection);CHKERRQ(ierr); 7388a93c429eSMatthew G. Knepley ierr = ISDestroy(&subis);CHKERRQ(ierr); 7389a93c429eSMatthew G. Knepley ierr = DMSetDefaultSection(*subdm, subsection);CHKERRQ(ierr); 7390a93c429eSMatthew G. Knepley ierr = PetscSectionDestroy(&subsection);CHKERRQ(ierr); 7391e5e52638SMatthew G. Knepley ierr = DMCopyDisc(dm, *subdm);CHKERRQ(ierr); 7392a93c429eSMatthew G. Knepley /* Create map from submodel to global model */ 7393a93c429eSMatthew G. Knepley if (is) { 7394a93c429eSMatthew G. Knepley PetscSection sectionGlobal, subsectionGlobal; 7395a93c429eSMatthew G. Knepley IS spIS; 7396a93c429eSMatthew G. Knepley const PetscInt *spmap; 7397a93c429eSMatthew G. Knepley PetscInt *subIndices; 7398a93c429eSMatthew G. Knepley PetscInt subSize = 0, subOff = 0, pStart, pEnd, p; 7399a93c429eSMatthew G. Knepley PetscInt Nf, f, bs = -1, bsLocal[2], bsMinMax[2]; 7400a93c429eSMatthew G. Knepley 7401a93c429eSMatthew G. Knepley ierr = DMPlexCreateSubpointIS(*subdm, &spIS);CHKERRQ(ierr); 7402a93c429eSMatthew G. Knepley ierr = ISGetIndices(spIS, &spmap);CHKERRQ(ierr); 7403a93c429eSMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &Nf);CHKERRQ(ierr); 7404a93c429eSMatthew G. Knepley ierr = DMGetDefaultGlobalSection(dm, §ionGlobal);CHKERRQ(ierr); 7405a93c429eSMatthew G. Knepley ierr = DMGetDefaultGlobalSection(*subdm, &subsectionGlobal);CHKERRQ(ierr); 7406a93c429eSMatthew G. Knepley ierr = PetscSectionGetChart(subsection, &pStart, &pEnd);CHKERRQ(ierr); 7407a93c429eSMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 7408a93c429eSMatthew G. Knepley PetscInt gdof, pSubSize = 0; 7409a93c429eSMatthew G. Knepley 7410a93c429eSMatthew G. Knepley ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr); 7411a93c429eSMatthew G. Knepley if (gdof > 0) { 7412a93c429eSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 7413a93c429eSMatthew G. Knepley PetscInt fdof, fcdof; 7414a93c429eSMatthew G. Knepley 7415a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldDof(subsection, p, f, &fdof);CHKERRQ(ierr); 7416a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldConstraintDof(subsection, p, f, &fcdof);CHKERRQ(ierr); 7417a93c429eSMatthew G. Knepley pSubSize += fdof-fcdof; 7418a93c429eSMatthew G. Knepley } 7419a93c429eSMatthew G. Knepley subSize += pSubSize; 7420a93c429eSMatthew G. Knepley if (pSubSize) { 7421a93c429eSMatthew G. Knepley if (bs < 0) { 7422a93c429eSMatthew G. Knepley bs = pSubSize; 7423a93c429eSMatthew G. Knepley } else if (bs != pSubSize) { 7424a93c429eSMatthew G. Knepley /* Layout does not admit a pointwise block size */ 7425a93c429eSMatthew G. Knepley bs = 1; 7426a93c429eSMatthew G. Knepley } 7427a93c429eSMatthew G. Knepley } 7428a93c429eSMatthew G. Knepley } 7429a93c429eSMatthew G. Knepley } 7430a93c429eSMatthew G. Knepley /* Must have same blocksize on all procs (some might have no points) */ 7431a93c429eSMatthew G. Knepley bsLocal[0] = bs < 0 ? PETSC_MAX_INT : bs; bsLocal[1] = bs; 7432a93c429eSMatthew G. Knepley ierr = PetscGlobalMinMaxInt(PetscObjectComm((PetscObject) dm), bsLocal, bsMinMax);CHKERRQ(ierr); 7433a93c429eSMatthew G. Knepley if (bsMinMax[0] != bsMinMax[1]) {bs = 1;} 7434a93c429eSMatthew G. Knepley else {bs = bsMinMax[0];} 7435a93c429eSMatthew G. Knepley ierr = PetscMalloc1(subSize, &subIndices);CHKERRQ(ierr); 7436a93c429eSMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 7437a93c429eSMatthew G. Knepley PetscInt gdof, goff; 7438a93c429eSMatthew G. Knepley 7439a93c429eSMatthew G. Knepley ierr = PetscSectionGetDof(subsectionGlobal, p, &gdof);CHKERRQ(ierr); 7440a93c429eSMatthew G. Knepley if (gdof > 0) { 7441a93c429eSMatthew G. Knepley const PetscInt point = spmap[p]; 7442a93c429eSMatthew G. Knepley 7443a93c429eSMatthew G. Knepley ierr = PetscSectionGetOffset(sectionGlobal, point, &goff);CHKERRQ(ierr); 7444a93c429eSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 7445a93c429eSMatthew G. Knepley PetscInt fdof, fcdof, fc, f2, poff = 0; 7446a93c429eSMatthew G. Knepley 7447a93c429eSMatthew G. Knepley /* Can get rid of this loop by storing field information in the global section */ 7448a93c429eSMatthew G. Knepley for (f2 = 0; f2 < f; ++f2) { 7449a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, p, f2, &fdof);CHKERRQ(ierr); 7450a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldConstraintDof(section, p, f2, &fcdof);CHKERRQ(ierr); 7451a93c429eSMatthew G. Knepley poff += fdof-fcdof; 7452a93c429eSMatthew G. Knepley } 7453a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr); 7454a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr); 7455a93c429eSMatthew G. Knepley for (fc = 0; fc < fdof-fcdof; ++fc, ++subOff) { 7456a93c429eSMatthew G. Knepley subIndices[subOff] = goff+poff+fc; 7457a93c429eSMatthew G. Knepley } 7458a93c429eSMatthew G. Knepley } 7459a93c429eSMatthew G. Knepley } 7460a93c429eSMatthew G. Knepley } 7461a93c429eSMatthew G. Knepley ierr = ISRestoreIndices(spIS, &spmap);CHKERRQ(ierr); 7462a93c429eSMatthew G. Knepley ierr = ISDestroy(&spIS);CHKERRQ(ierr); 7463a93c429eSMatthew G. Knepley ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), subSize, subIndices, PETSC_OWN_POINTER, is);CHKERRQ(ierr); 7464a93c429eSMatthew G. Knepley if (bs > 1) { 7465a93c429eSMatthew G. Knepley /* We need to check that the block size does not come from non-contiguous fields */ 7466a93c429eSMatthew G. Knepley PetscInt i, j, set = 1; 7467a93c429eSMatthew G. Knepley for (i = 0; i < subSize; i += bs) { 7468a93c429eSMatthew G. Knepley for (j = 0; j < bs; ++j) { 7469a93c429eSMatthew G. Knepley if (subIndices[i+j] != subIndices[i]+j) {set = 0; break;} 7470a93c429eSMatthew G. Knepley } 7471a93c429eSMatthew G. Knepley } 7472a93c429eSMatthew G. Knepley if (set) {ierr = ISSetBlockSize(*is, bs);CHKERRQ(ierr);} 7473a93c429eSMatthew G. Knepley } 7474a93c429eSMatthew G. Knepley /* Attach nullspace */ 7475a93c429eSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 7476a93c429eSMatthew G. Knepley (*subdm)->nullspaceConstructors[f] = dm->nullspaceConstructors[f]; 7477a93c429eSMatthew G. Knepley if ((*subdm)->nullspaceConstructors[f]) break; 7478a93c429eSMatthew G. Knepley } 7479a93c429eSMatthew G. Knepley if (f < Nf) { 7480a93c429eSMatthew G. Knepley MatNullSpace nullSpace; 7481a93c429eSMatthew G. Knepley 7482a93c429eSMatthew G. Knepley ierr = (*(*subdm)->nullspaceConstructors[f])(*subdm, f, &nullSpace);CHKERRQ(ierr); 7483a93c429eSMatthew G. Knepley ierr = PetscObjectCompose((PetscObject) *is, "nullspace", (PetscObject) nullSpace);CHKERRQ(ierr); 7484a93c429eSMatthew G. Knepley ierr = MatNullSpaceDestroy(&nullSpace);CHKERRQ(ierr); 7485a93c429eSMatthew G. Knepley } 7486a93c429eSMatthew G. Knepley } 7487a93c429eSMatthew G. Knepley PetscFunctionReturn(0); 7488a93c429eSMatthew G. Knepley } 7489