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 */ 1167eb269bSLisandro Dalcin 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; 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) { 417*a8ad634aSStefano Zampini /* Natural ordering is the common case for DMDA, NATIVE means plain vector, for PLEX is the opposite */ 418*a8ad634aSStefano Zampini /* this need a better fix */ 419*a8ad634aSStefano Zampini if (dm->useNatural) { 420*a8ad634aSStefano 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"); 434*a8ad634aSStefano Zampini } else v = originalv; 435*a8ad634aSStefano Zampini } else v = originalv; 436*a8ad634aSStefano 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 } 452*a8ad634aSStefano 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) { 520*a8ad634aSStefano 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 } 539*a8ad634aSStefano Zampini } else { 540*a8ad634aSStefano Zampini ierr = VecLoad_Default(originalv, viewer);CHKERRQ(ierr); 541*a8ad634aSStefano 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); 65880180ce3SStefano Zampini ierr = PetscSectionVecView(coordSection, coordinates, viewer);CHKERRQ(ierr); 659c58f1c22SToby Isaac ierr = DMGetLabel(dm, "marker", &markers);CHKERRQ(ierr); 6607422c0d1SMatthew G. Knepley if (markers) {ierr = DMLabelView(markers,viewer);CHKERRQ(ierr);} 661552f7358SJed Brown if (size > 1) { 662552f7358SJed Brown PetscSF sf; 663552f7358SJed Brown 664552f7358SJed Brown ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 665552f7358SJed Brown ierr = PetscSFView(sf, viewer);CHKERRQ(ierr); 666552f7358SJed Brown } 667552f7358SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 668552f7358SJed Brown } else if (format == PETSC_VIEWER_ASCII_LATEX) { 6690588280cSMatthew G. Knepley const char *name, *color; 6700588280cSMatthew G. Knepley const char *defcolors[3] = {"gray", "orange", "green"}; 6710588280cSMatthew G. Knepley const char *deflcolors[4] = {"blue", "cyan", "red", "magenta"}; 672552f7358SJed Brown PetscReal scale = 2.0; 67378081901SStefano Zampini PetscReal tikzscale = 1.0; 6740588280cSMatthew G. Knepley PetscBool useNumbers = PETSC_TRUE, useLabels, useColors; 6750588280cSMatthew G. Knepley double tcoords[3]; 676552f7358SJed Brown PetscScalar *coords; 6770588280cSMatthew G. Knepley PetscInt numLabels, l, numColors, numLColors, dim, depth, cStart, cEnd, c, vStart, vEnd, v, eStart = 0, eEnd = 0, e, p; 678552f7358SJed Brown PetscMPIInt rank, size; 6790588280cSMatthew G. Knepley char **names, **colors, **lcolors; 680202fd40aSStefano Zampini PetscBool plotEdges, flg; 681552f7358SJed Brown 6820588280cSMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 683552f7358SJed Brown ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 684c58f1c22SToby Isaac ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 6850588280cSMatthew G. Knepley numLabels = PetscMax(numLabels, 10); 6860588280cSMatthew G. Knepley numColors = 10; 6870588280cSMatthew G. Knepley numLColors = 10; 6880588280cSMatthew G. Knepley ierr = PetscCalloc3(numLabels, &names, numColors, &colors, numLColors, &lcolors);CHKERRQ(ierr); 689c5929fdfSBarry Smith ierr = PetscOptionsGetReal(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_scale", &scale, NULL);CHKERRQ(ierr); 69078081901SStefano Zampini ierr = PetscOptionsGetReal(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_tikzscale", &tikzscale, NULL);CHKERRQ(ierr); 691c5929fdfSBarry Smith ierr = PetscOptionsGetBool(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_numbers", &useNumbers, NULL);CHKERRQ(ierr); 692c5929fdfSBarry Smith ierr = PetscOptionsGetStringArray(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_labels", names, &numLabels, &useLabels);CHKERRQ(ierr); 6930588280cSMatthew G. Knepley if (!useLabels) numLabels = 0; 694c5929fdfSBarry Smith ierr = PetscOptionsGetStringArray(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_colors", colors, &numColors, &useColors);CHKERRQ(ierr); 6950588280cSMatthew G. Knepley if (!useColors) { 6960588280cSMatthew G. Knepley numColors = 3; 6970588280cSMatthew G. Knepley for (c = 0; c < numColors; ++c) {ierr = PetscStrallocpy(defcolors[c], &colors[c]);CHKERRQ(ierr);} 6980588280cSMatthew G. Knepley } 699c5929fdfSBarry Smith ierr = PetscOptionsGetStringArray(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_lcolors", lcolors, &numLColors, &useColors);CHKERRQ(ierr); 7000588280cSMatthew G. Knepley if (!useColors) { 7010588280cSMatthew G. Knepley numLColors = 4; 7020588280cSMatthew G. Knepley for (c = 0; c < numLColors; ++c) {ierr = PetscStrallocpy(deflcolors[c], &lcolors[c]);CHKERRQ(ierr);} 7030588280cSMatthew G. Knepley } 704202fd40aSStefano Zampini plotEdges = (PetscBool)(depth > 1 && useNumbers && dim < 3); 705202fd40aSStefano Zampini ierr = PetscOptionsGetBool(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_edges", &plotEdges, &flg);CHKERRQ(ierr); 706202fd40aSStefano Zampini if (flg && plotEdges && depth < dim) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Mesh must be interpolated"); 707202fd40aSStefano Zampini if (depth < dim) plotEdges = PETSC_FALSE; 70882f516ccSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank);CHKERRQ(ierr); 70982f516ccSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)dm), &size);CHKERRQ(ierr); 710552f7358SJed Brown ierr = PetscObjectGetName((PetscObject) dm, &name);CHKERRQ(ierr); 711770b213bSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, "\ 7120588280cSMatthew G. Knepley \\documentclass[tikz]{standalone}\n\n\ 713552f7358SJed Brown \\usepackage{pgflibraryshapes}\n\ 714552f7358SJed Brown \\usetikzlibrary{backgrounds}\n\ 715552f7358SJed Brown \\usetikzlibrary{arrows}\n\ 7160588280cSMatthew G. Knepley \\begin{document}\n");CHKERRQ(ierr); 7170588280cSMatthew G. Knepley if (size > 1) { 718f738dd31SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "%s for process ", name);CHKERRQ(ierr); 719770b213bSMatthew G Knepley for (p = 0; p < size; ++p) { 720770b213bSMatthew G Knepley if (p > 0 && p == size-1) { 721770b213bSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, ", and ", colors[p%numColors], p);CHKERRQ(ierr); 722770b213bSMatthew G Knepley } else if (p > 0) { 723770b213bSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, ", ", colors[p%numColors], p);CHKERRQ(ierr); 724770b213bSMatthew G Knepley } 725770b213bSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, "{\\textcolor{%s}%D}", colors[p%numColors], p);CHKERRQ(ierr); 726770b213bSMatthew G Knepley } 7270588280cSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, ".\n\n\n");CHKERRQ(ierr); 7280588280cSMatthew G. Knepley } 72978081901SStefano Zampini ierr = PetscViewerASCIIPrintf(viewer, "\\begin{tikzpicture}[scale = %g,font=\\fontsize{8}{8}\\selectfont]\n", tikzscale);CHKERRQ(ierr); 730552f7358SJed Brown /* Plot vertices */ 731552f7358SJed Brown ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 732552f7358SJed Brown ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 7334d4c343aSBarry Smith ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 734552f7358SJed Brown for (v = vStart; v < vEnd; ++v) { 735552f7358SJed Brown PetscInt off, dof, d; 7360588280cSMatthew G. Knepley PetscBool isLabeled = PETSC_FALSE; 737552f7358SJed Brown 738552f7358SJed Brown ierr = PetscSectionGetDof(coordSection, v, &dof);CHKERRQ(ierr); 739552f7358SJed Brown ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 7400588280cSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "\\path (");CHKERRQ(ierr); 741f6dae198SJed Brown if (PetscUnlikely(dof > 3)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"coordSection vertex %D has dof %D > 3",v,dof); 7420588280cSMatthew G. Knepley for (d = 0; d < dof; ++d) { 7430588280cSMatthew G. Knepley tcoords[d] = (double) (scale*PetscRealPart(coords[off+d])); 744c068d9bbSLisandro Dalcin tcoords[d] = PetscAbs(tcoords[d]) < 1e-10 ? 0.0 : tcoords[d]; 7450588280cSMatthew G. Knepley } 7460588280cSMatthew G. Knepley /* Rotate coordinates since PGF makes z point out of the page instead of up */ 7470588280cSMatthew G. Knepley if (dim == 3) {PetscReal tmp = tcoords[1]; tcoords[1] = tcoords[2]; tcoords[2] = -tmp;} 748552f7358SJed Brown for (d = 0; d < dof; ++d) { 749552f7358SJed Brown if (d > 0) {ierr = PetscViewerASCIISynchronizedPrintf(viewer, ",");CHKERRQ(ierr);} 7500588280cSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "%g", tcoords[d]);CHKERRQ(ierr); 751552f7358SJed Brown } 7520588280cSMatthew G. Knepley color = colors[rank%numColors]; 7530588280cSMatthew G. Knepley for (l = 0; l < numLabels; ++l) { 7540588280cSMatthew G. Knepley PetscInt val; 755c58f1c22SToby Isaac ierr = DMGetLabelValue(dm, names[l], v, &val);CHKERRQ(ierr); 7560588280cSMatthew G. Knepley if (val >= 0) {color = lcolors[l%numLColors]; isLabeled = PETSC_TRUE; break;} 7570588280cSMatthew G. Knepley } 7580588280cSMatthew G. Knepley if (useNumbers) { 759e4b003c7SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer, ") node(%D_%d) [draw,shape=circle,color=%s] {%D};\n", v, rank, color, v);CHKERRQ(ierr); 7600588280cSMatthew G. Knepley } else { 761e4b003c7SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer, ") node(%D_%d) [fill,inner sep=%dpt,shape=circle,color=%s] {};\n", v, rank, !isLabeled ? 1 : 2, color);CHKERRQ(ierr); 7620588280cSMatthew G. Knepley } 763552f7358SJed Brown } 764552f7358SJed Brown ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 765552f7358SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 766846a3e8bSMatthew G. Knepley /* Plot cells */ 767846a3e8bSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 76878081901SStefano Zampini ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 769846a3e8bSMatthew G. Knepley if (dim == 3 || !useNumbers) { 770846a3e8bSMatthew G. Knepley for (e = eStart; e < eEnd; ++e) { 771846a3e8bSMatthew G. Knepley const PetscInt *cone; 772846a3e8bSMatthew G. Knepley 773846a3e8bSMatthew G. Knepley color = colors[rank%numColors]; 774846a3e8bSMatthew G. Knepley for (l = 0; l < numLabels; ++l) { 775846a3e8bSMatthew G. Knepley PetscInt val; 776846a3e8bSMatthew G. Knepley ierr = DMGetLabelValue(dm, names[l], e, &val);CHKERRQ(ierr); 777846a3e8bSMatthew G. Knepley if (val >= 0) {color = lcolors[l%numLColors]; break;} 778846a3e8bSMatthew G. Knepley } 779846a3e8bSMatthew G. Knepley ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 780846a3e8bSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "\\draw[color=%s] (%D_%d) -- (%D_%d);\n", color, cone[0], rank, cone[1], rank);CHKERRQ(ierr); 781846a3e8bSMatthew G. Knepley } 782846a3e8bSMatthew G. Knepley } else { 783846a3e8bSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 784846a3e8bSMatthew G. Knepley PetscInt *closure = NULL; 785846a3e8bSMatthew G. Knepley PetscInt closureSize, firstPoint = -1; 786846a3e8bSMatthew G. Knepley 787846a3e8bSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 788846a3e8bSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "\\draw[color=%s] ", colors[rank%numColors]);CHKERRQ(ierr); 789846a3e8bSMatthew G. Knepley for (p = 0; p < closureSize*2; p += 2) { 790846a3e8bSMatthew G. Knepley const PetscInt point = closure[p]; 791846a3e8bSMatthew G. Knepley 792846a3e8bSMatthew G. Knepley if ((point < vStart) || (point >= vEnd)) continue; 793846a3e8bSMatthew G. Knepley if (firstPoint >= 0) {ierr = PetscViewerASCIISynchronizedPrintf(viewer, " -- ");CHKERRQ(ierr);} 794846a3e8bSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "(%D_%d)", point, rank);CHKERRQ(ierr); 795846a3e8bSMatthew G. Knepley if (firstPoint < 0) firstPoint = point; 796846a3e8bSMatthew G. Knepley } 797846a3e8bSMatthew G. Knepley /* Why doesn't this work? ierr = PetscViewerASCIISynchronizedPrintf(viewer, " -- cycle;\n");CHKERRQ(ierr); */ 798846a3e8bSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, " -- (%D_%d);\n", firstPoint, rank);CHKERRQ(ierr); 799846a3e8bSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 800846a3e8bSMatthew G. Knepley } 801846a3e8bSMatthew G. Knepley } 802846a3e8bSMatthew G. Knepley ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 803846a3e8bSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 804846a3e8bSMatthew G. Knepley double ccoords[3] = {0.0, 0.0, 0.0}; 805846a3e8bSMatthew G. Knepley PetscBool isLabeled = PETSC_FALSE; 806846a3e8bSMatthew G. Knepley PetscInt *closure = NULL; 807846a3e8bSMatthew G. Knepley PetscInt closureSize, dof, d, n = 0; 808846a3e8bSMatthew G. Knepley 809846a3e8bSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 810846a3e8bSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "\\path (");CHKERRQ(ierr); 811846a3e8bSMatthew G. Knepley for (p = 0; p < closureSize*2; p += 2) { 812846a3e8bSMatthew G. Knepley const PetscInt point = closure[p]; 813846a3e8bSMatthew G. Knepley PetscInt off; 814846a3e8bSMatthew G. Knepley 815846a3e8bSMatthew G. Knepley if ((point < vStart) || (point >= vEnd)) continue; 816846a3e8bSMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, point, &dof);CHKERRQ(ierr); 817846a3e8bSMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, point, &off);CHKERRQ(ierr); 818846a3e8bSMatthew G. Knepley for (d = 0; d < dof; ++d) { 819846a3e8bSMatthew G. Knepley tcoords[d] = (double) (scale*PetscRealPart(coords[off+d])); 820846a3e8bSMatthew G. Knepley tcoords[d] = PetscAbs(tcoords[d]) < 1e-10 ? 0.0 : tcoords[d]; 821846a3e8bSMatthew G. Knepley } 822846a3e8bSMatthew G. Knepley /* Rotate coordinates since PGF makes z point out of the page instead of up */ 823846a3e8bSMatthew G. Knepley if (dof == 3) {PetscReal tmp = tcoords[1]; tcoords[1] = tcoords[2]; tcoords[2] = -tmp;} 824846a3e8bSMatthew G. Knepley for (d = 0; d < dof; ++d) {ccoords[d] += tcoords[d];} 825846a3e8bSMatthew G. Knepley ++n; 826846a3e8bSMatthew G. Knepley } 827846a3e8bSMatthew G. Knepley for (d = 0; d < dof; ++d) {ccoords[d] /= n;} 828846a3e8bSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 829846a3e8bSMatthew G. Knepley for (d = 0; d < dof; ++d) { 830846a3e8bSMatthew G. Knepley if (d > 0) {ierr = PetscViewerASCIISynchronizedPrintf(viewer, ",");CHKERRQ(ierr);} 831846a3e8bSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "%g", ccoords[d]);CHKERRQ(ierr); 832846a3e8bSMatthew G. Knepley } 833846a3e8bSMatthew G. Knepley color = colors[rank%numColors]; 834846a3e8bSMatthew G. Knepley for (l = 0; l < numLabels; ++l) { 835846a3e8bSMatthew G. Knepley PetscInt val; 836846a3e8bSMatthew G. Knepley ierr = DMGetLabelValue(dm, names[l], c, &val);CHKERRQ(ierr); 837846a3e8bSMatthew G. Knepley if (val >= 0) {color = lcolors[l%numLColors]; isLabeled = PETSC_TRUE; break;} 838846a3e8bSMatthew G. Knepley } 839846a3e8bSMatthew G. Knepley if (useNumbers) { 840846a3e8bSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, ") node(%D_%d) [draw,shape=circle,color=%s] {%D};\n", c, rank, color, c);CHKERRQ(ierr); 841846a3e8bSMatthew G. Knepley } else { 842846a3e8bSMatthew 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); 843846a3e8bSMatthew G. Knepley } 844846a3e8bSMatthew G. Knepley } 845846a3e8bSMatthew G. Knepley ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 846552f7358SJed Brown /* Plot edges */ 847202fd40aSStefano Zampini if (plotEdges) { 848552f7358SJed Brown ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 849552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, "\\path\n");CHKERRQ(ierr); 850552f7358SJed Brown for (e = eStart; e < eEnd; ++e) { 851552f7358SJed Brown const PetscInt *cone; 852552f7358SJed Brown PetscInt coneSize, offA, offB, dof, d; 853552f7358SJed Brown 854552f7358SJed Brown ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr); 855f347f43bSBarry Smith if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %D cone should have two vertices, not %D", e, coneSize); 856552f7358SJed Brown ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 857552f7358SJed Brown ierr = PetscSectionGetDof(coordSection, cone[0], &dof);CHKERRQ(ierr); 858552f7358SJed Brown ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr); 859552f7358SJed Brown ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr); 860552f7358SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer, "(");CHKERRQ(ierr); 861552f7358SJed Brown for (d = 0; d < dof; ++d) { 862202fd40aSStefano Zampini tcoords[d] = (double) (0.5*scale*PetscRealPart(coords[offA+d]+coords[offB+d])); 863c068d9bbSLisandro Dalcin tcoords[d] = PetscAbs(tcoords[d]) < 1e-10 ? 0.0 : tcoords[d]; 864552f7358SJed Brown } 8650588280cSMatthew G. Knepley /* Rotate coordinates since PGF makes z point out of the page instead of up */ 8660588280cSMatthew G. Knepley if (dim == 3) {PetscReal tmp = tcoords[1]; tcoords[1] = tcoords[2]; tcoords[2] = -tmp;} 8670588280cSMatthew G. Knepley for (d = 0; d < dof; ++d) { 8680588280cSMatthew G. Knepley if (d > 0) {ierr = PetscViewerASCIISynchronizedPrintf(viewer, ",");CHKERRQ(ierr);} 869f347f43bSBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer, "%g", (double)tcoords[d]);CHKERRQ(ierr); 8700588280cSMatthew G. Knepley } 8710588280cSMatthew G. Knepley color = colors[rank%numColors]; 8720588280cSMatthew G. Knepley for (l = 0; l < numLabels; ++l) { 8730588280cSMatthew G. Knepley PetscInt val; 874c58f1c22SToby Isaac ierr = DMGetLabelValue(dm, names[l], v, &val);CHKERRQ(ierr); 8750750fff4SMatthew G. Knepley if (val >= 0) {color = lcolors[l%numLColors]; break;} 8760588280cSMatthew G. Knepley } 877e4b003c7SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer, ") node(%D_%d) [draw,shape=circle,color=%s] {%D} --\n", e, rank, color, e);CHKERRQ(ierr); 878552f7358SJed Brown } 879552f7358SJed Brown ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 880552f7358SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 881552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, "(0,0);\n");CHKERRQ(ierr); 8820588280cSMatthew G. Knepley } 883552f7358SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 8844d4c343aSBarry Smith ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); 8850588280cSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "\\end{tikzpicture}\n");CHKERRQ(ierr); 886770b213bSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, "\\end{document}\n", name);CHKERRQ(ierr); 8870588280cSMatthew G. Knepley for (l = 0; l < numLabels; ++l) {ierr = PetscFree(names[l]);CHKERRQ(ierr);} 8880588280cSMatthew G. Knepley for (c = 0; c < numColors; ++c) {ierr = PetscFree(colors[c]);CHKERRQ(ierr);} 8890588280cSMatthew G. Knepley for (c = 0; c < numLColors; ++c) {ierr = PetscFree(lcolors[c]);CHKERRQ(ierr);} 8900588280cSMatthew G. Knepley ierr = PetscFree3(names, colors, lcolors);CHKERRQ(ierr); 891552f7358SJed Brown } else { 89282f516ccSBarry Smith MPI_Comm comm; 893834065abSMatthew G. Knepley PetscInt *sizes, *hybsizes; 894f73eea6eSMatthew G. Knepley PetscInt locDepth, depth, cellHeight, dim, d, pMax[4]; 895552f7358SJed Brown PetscInt pStart, pEnd, p; 896a57dd577SMatthew G Knepley PetscInt numLabels, l; 8971143a3c0SMatthew G. Knepley const char *name; 898552f7358SJed Brown PetscMPIInt size; 899552f7358SJed Brown 90082f516ccSBarry Smith ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 901552f7358SJed Brown ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 902c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 903f73eea6eSMatthew G. Knepley ierr = DMPlexGetVTKCellHeight(dm, &cellHeight);CHKERRQ(ierr); 9045f64d76eSMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) dm, &name);CHKERRQ(ierr); 905f73eea6eSMatthew G. Knepley if (name) {ierr = PetscViewerASCIIPrintf(viewer, "%s in %D dimension%s:\n", name, dim, dim == 1 ? "" : "s");CHKERRQ(ierr);} 906f73eea6eSMatthew G. Knepley else {ierr = PetscViewerASCIIPrintf(viewer, "Mesh in %D dimension%s:\n", dim, dim == 1 ? "" : "s");CHKERRQ(ierr);} 907f73eea6eSMatthew G. Knepley if (cellHeight) {ierr = PetscViewerASCIIPrintf(viewer, " Cells are at height %D\n", cellHeight);CHKERRQ(ierr);} 908552f7358SJed Brown ierr = DMPlexGetDepth(dm, &locDepth);CHKERRQ(ierr); 909b2566f29SBarry Smith ierr = MPIU_Allreduce(&locDepth, &depth, 1, MPIU_INT, MPI_MAX, comm);CHKERRQ(ierr); 910a04427b4SStefano Zampini ierr = DMPlexGetHybridBounds(dm, &pMax[depth], depth > 0 ? &pMax[depth-1] : NULL, depth > 1 ? &pMax[depth - 2] : NULL, &pMax[0]);CHKERRQ(ierr); 911b0138d5dSStefano Zampini ierr = PetscCalloc2(size,&sizes,size,&hybsizes);CHKERRQ(ierr); 912552f7358SJed Brown if (depth == 1) { 913552f7358SJed Brown ierr = DMPlexGetDepthStratum(dm, 0, &pStart, &pEnd);CHKERRQ(ierr); 914552f7358SJed Brown pEnd = pEnd - pStart; 915a04427b4SStefano Zampini pMax[0] -= pStart; 916552f7358SJed Brown ierr = MPI_Gather(&pEnd, 1, MPIU_INT, sizes, 1, MPIU_INT, 0, comm);CHKERRQ(ierr); 917a04427b4SStefano Zampini ierr = MPI_Gather(&pMax[0], 1, MPIU_INT, hybsizes, 1, MPIU_INT, 0, comm);CHKERRQ(ierr); 918f347f43bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer, " %d-cells:", 0);CHKERRQ(ierr); 919a04427b4SStefano Zampini for (p = 0; p < size; ++p) { 920a04427b4SStefano Zampini if (hybsizes[p] >= 0) {ierr = PetscViewerASCIIPrintf(viewer, " %D (%D)", sizes[p], sizes[p] - hybsizes[p]);CHKERRQ(ierr);} 921a04427b4SStefano Zampini else {ierr = PetscViewerASCIIPrintf(viewer, " %D", sizes[p]);CHKERRQ(ierr);} 922a04427b4SStefano Zampini } 923552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, "\n");CHKERRQ(ierr); 924552f7358SJed Brown ierr = DMPlexGetHeightStratum(dm, 0, &pStart, &pEnd);CHKERRQ(ierr); 925552f7358SJed Brown pEnd = pEnd - pStart; 926a04427b4SStefano Zampini pMax[depth] -= pStart; 927552f7358SJed Brown ierr = MPI_Gather(&pEnd, 1, MPIU_INT, sizes, 1, MPIU_INT, 0, comm);CHKERRQ(ierr); 928a04427b4SStefano Zampini ierr = MPI_Gather(&pMax[depth], 1, MPIU_INT, hybsizes, 1, MPIU_INT, 0, comm);CHKERRQ(ierr); 929552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, " %D-cells:", dim);CHKERRQ(ierr); 930a04427b4SStefano Zampini for (p = 0; p < size; ++p) { 931a04427b4SStefano Zampini if (hybsizes[p] >= 0) {ierr = PetscViewerASCIIPrintf(viewer, " %D (%D)", sizes[p], sizes[p] - hybsizes[p]);CHKERRQ(ierr);} 932a04427b4SStefano Zampini else {ierr = PetscViewerASCIIPrintf(viewer, " %D", sizes[p]);CHKERRQ(ierr);} 933a04427b4SStefano Zampini } 934552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, "\n");CHKERRQ(ierr); 935552f7358SJed Brown } else { 936cbb7f117SMark Adams PetscMPIInt rank; 937cbb7f117SMark Adams ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 938552f7358SJed Brown for (d = 0; d <= dim; d++) { 939552f7358SJed Brown ierr = DMPlexGetDepthStratum(dm, d, &pStart, &pEnd);CHKERRQ(ierr); 940834065abSMatthew G. Knepley pEnd -= pStart; 941834065abSMatthew G. Knepley pMax[d] -= pStart; 942552f7358SJed Brown ierr = MPI_Gather(&pEnd, 1, MPIU_INT, sizes, 1, MPIU_INT, 0, comm);CHKERRQ(ierr); 943834065abSMatthew G. Knepley ierr = MPI_Gather(&pMax[d], 1, MPIU_INT, hybsizes, 1, MPIU_INT, 0, comm);CHKERRQ(ierr); 944552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, " %D-cells:", d);CHKERRQ(ierr); 945834065abSMatthew G. Knepley for (p = 0; p < size; ++p) { 946cbb7f117SMark Adams if (!rank) { 947834065abSMatthew G. Knepley if (hybsizes[p] >= 0) {ierr = PetscViewerASCIIPrintf(viewer, " %D (%D)", sizes[p], sizes[p] - hybsizes[p]);CHKERRQ(ierr);} 948834065abSMatthew G. Knepley else {ierr = PetscViewerASCIIPrintf(viewer, " %D", sizes[p]);CHKERRQ(ierr);} 949834065abSMatthew G. Knepley } 950cbb7f117SMark Adams } 951552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, "\n");CHKERRQ(ierr); 952552f7358SJed Brown } 953552f7358SJed Brown } 954834065abSMatthew G. Knepley ierr = PetscFree2(sizes,hybsizes);CHKERRQ(ierr); 955c58f1c22SToby Isaac ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 956a57dd577SMatthew G Knepley if (numLabels) {ierr = PetscViewerASCIIPrintf(viewer, "Labels:\n");CHKERRQ(ierr);} 957a57dd577SMatthew G Knepley for (l = 0; l < numLabels; ++l) { 958a57dd577SMatthew G Knepley DMLabel label; 959a57dd577SMatthew G Knepley const char *name; 960a57dd577SMatthew G Knepley IS valueIS; 961a57dd577SMatthew G Knepley const PetscInt *values; 962a57dd577SMatthew G Knepley PetscInt numValues, v; 963a57dd577SMatthew G Knepley 964c58f1c22SToby Isaac ierr = DMGetLabelName(dm, l, &name);CHKERRQ(ierr); 965c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 966a57dd577SMatthew G Knepley ierr = DMLabelGetNumValues(label, &numValues);CHKERRQ(ierr); 967d72f73ffSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " %s: %D strata with value/size (", name, numValues);CHKERRQ(ierr); 968a57dd577SMatthew G Knepley ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 969a57dd577SMatthew G Knepley ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 970120dea56SMatthew G. Knepley ierr = PetscViewerASCIIUseTabs(viewer, PETSC_FALSE);CHKERRQ(ierr); 971a57dd577SMatthew G Knepley for (v = 0; v < numValues; ++v) { 972a57dd577SMatthew G Knepley PetscInt size; 973a57dd577SMatthew G Knepley 974a57dd577SMatthew G Knepley ierr = DMLabelGetStratumSize(label, values[v], &size);CHKERRQ(ierr); 975a57dd577SMatthew G Knepley if (v > 0) {ierr = PetscViewerASCIIPrintf(viewer, ", ");CHKERRQ(ierr);} 976d72f73ffSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "%D (%D)", values[v], size);CHKERRQ(ierr); 977a57dd577SMatthew G Knepley } 978a57dd577SMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, ")\n");CHKERRQ(ierr); 979120dea56SMatthew G. Knepley ierr = PetscViewerASCIIUseTabs(viewer, PETSC_TRUE);CHKERRQ(ierr); 980a57dd577SMatthew G Knepley ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 9814d41221fSMatthew G Knepley ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 982a57dd577SMatthew G Knepley } 98334aa8a36SMatthew G. Knepley /* If no fields are specified, people do not want to see adjacency */ 98434aa8a36SMatthew G. Knepley if (dm->Nf) { 98534aa8a36SMatthew G. Knepley PetscInt f; 98634aa8a36SMatthew G. Knepley 98734aa8a36SMatthew G. Knepley for (f = 0; f < dm->Nf; ++f) { 98834aa8a36SMatthew G. Knepley const char *name; 98934aa8a36SMatthew G. Knepley 99034aa8a36SMatthew G. Knepley ierr = PetscObjectGetName(dm->fields[f].disc, &name);CHKERRQ(ierr); 99134aa8a36SMatthew G. Knepley if (numLabels) {ierr = PetscViewerASCIIPrintf(viewer, "Field %s:\n", name);CHKERRQ(ierr);} 99234aa8a36SMatthew G. Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 99334aa8a36SMatthew G. Knepley if (dm->fields[f].label) {ierr = DMLabelView(dm->fields[f].label, viewer);CHKERRQ(ierr);} 99434aa8a36SMatthew G. Knepley if (dm->fields[f].adjacency[0]) { 99534aa8a36SMatthew G. Knepley if (dm->fields[f].adjacency[1]) {ierr = PetscViewerASCIIPrintf(viewer, "adjacency FVM++\n");CHKERRQ(ierr);} 996ed59e46eSMatthew G. Knepley else {ierr = PetscViewerASCIIPrintf(viewer, "adjacency FVM\n");CHKERRQ(ierr);} 99734aa8a36SMatthew G. Knepley } else { 99834aa8a36SMatthew G. Knepley if (dm->fields[f].adjacency[1]) {ierr = PetscViewerASCIIPrintf(viewer, "adjacency FEM\n");CHKERRQ(ierr);} 99934aa8a36SMatthew G. Knepley else {ierr = PetscViewerASCIIPrintf(viewer, "adjacency FUNKY\n");CHKERRQ(ierr);} 100034aa8a36SMatthew G. Knepley } 100134aa8a36SMatthew G. Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 100234aa8a36SMatthew G. Knepley } 100334aa8a36SMatthew G. Knepley } 1004a8fb8f29SToby Isaac ierr = DMGetCoarseDM(dm, &cdm);CHKERRQ(ierr); 10058e7ff633SMatthew G. Knepley if (cdm) { 10068e7ff633SMatthew G. Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 10078e7ff633SMatthew G. Knepley ierr = DMPlexView_Ascii(cdm, viewer);CHKERRQ(ierr); 10088e7ff633SMatthew G. Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 10098e7ff633SMatthew G. Knepley } 1010552f7358SJed Brown } 1011552f7358SJed Brown PetscFunctionReturn(0); 1012552f7358SJed Brown } 1013552f7358SJed Brown 10147cd05799SMatthew G. Knepley static PetscErrorCode DMPlexView_Draw(DM dm, PetscViewer viewer) 1015e412dcbdSMatthew G. Knepley { 1016e412dcbdSMatthew G. Knepley PetscDraw draw; 1017e412dcbdSMatthew G. Knepley DM cdm; 1018e412dcbdSMatthew G. Knepley PetscSection coordSection; 1019e412dcbdSMatthew G. Knepley Vec coordinates; 1020e412dcbdSMatthew G. Knepley const PetscScalar *coords; 102129494db1SLisandro Dalcin PetscReal xyl[2],xyr[2],bound[4] = {PETSC_MAX_REAL, PETSC_MAX_REAL, PETSC_MIN_REAL, PETSC_MIN_REAL}; 1022e412dcbdSMatthew G. Knepley PetscBool isnull; 1023e412dcbdSMatthew G. Knepley PetscInt dim, vStart, vEnd, cStart, cEnd, c, N; 1024cf3064d3SMatthew G. Knepley PetscMPIInt rank; 1025e412dcbdSMatthew G. Knepley PetscErrorCode ierr; 1026e412dcbdSMatthew G. Knepley 1027e412dcbdSMatthew G. Knepley PetscFunctionBegin; 1028e412dcbdSMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dim);CHKERRQ(ierr); 1029e412dcbdSMatthew G. Knepley if (dim != 2) SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Cannot draw meshes of dimension %D", dim); 1030e412dcbdSMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 1031e87a4003SBarry Smith ierr = DMGetSection(cdm, &coordSection);CHKERRQ(ierr); 1032e412dcbdSMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 1033e412dcbdSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 1034e412dcbdSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 1035e412dcbdSMatthew G. Knepley 1036e412dcbdSMatthew G. Knepley ierr = PetscViewerDrawGetDraw(viewer, 0, &draw);CHKERRQ(ierr); 1037e412dcbdSMatthew G. Knepley ierr = PetscDrawIsNull(draw, &isnull);CHKERRQ(ierr); 1038e412dcbdSMatthew G. Knepley if (isnull) PetscFunctionReturn(0); 1039e412dcbdSMatthew G. Knepley ierr = PetscDrawSetTitle(draw, "Mesh");CHKERRQ(ierr); 1040e412dcbdSMatthew G. Knepley 1041e412dcbdSMatthew G. Knepley ierr = VecGetLocalSize(coordinates, &N);CHKERRQ(ierr); 1042e412dcbdSMatthew G. Knepley ierr = VecGetArrayRead(coordinates, &coords);CHKERRQ(ierr); 1043e412dcbdSMatthew G. Knepley for (c = 0; c < N; c += dim) { 10440c81f2a8SMatthew G. Knepley bound[0] = PetscMin(bound[0], PetscRealPart(coords[c])); bound[2] = PetscMax(bound[2], PetscRealPart(coords[c])); 10450c81f2a8SMatthew G. Knepley bound[1] = PetscMin(bound[1], PetscRealPart(coords[c+1])); bound[3] = PetscMax(bound[3], PetscRealPart(coords[c+1])); 1046e412dcbdSMatthew G. Knepley } 1047e412dcbdSMatthew G. Knepley ierr = VecRestoreArrayRead(coordinates, &coords);CHKERRQ(ierr); 104829494db1SLisandro Dalcin ierr = MPIU_Allreduce(&bound[0],xyl,2,MPIU_REAL,MPIU_MIN,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 104929494db1SLisandro Dalcin ierr = MPIU_Allreduce(&bound[2],xyr,2,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 105029494db1SLisandro Dalcin ierr = PetscDrawSetCoordinates(draw, xyl[0], xyl[1], xyr[0], xyr[1]);CHKERRQ(ierr); 1051e412dcbdSMatthew G. Knepley ierr = PetscDrawClear(draw);CHKERRQ(ierr); 1052e412dcbdSMatthew G. Knepley 1053cf3064d3SMatthew G. Knepley ierr = MPI_Comm_rank(PetscObjectComm((PetscObject) dm), &rank);CHKERRQ(ierr); 1054cf3064d3SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 1055cf3064d3SMatthew G. Knepley PetscScalar *coords = NULL; 1056cf3064d3SMatthew G. Knepley PetscInt numCoords,coneSize; 1057cf3064d3SMatthew G. Knepley 1058cf3064d3SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, c, &coneSize);CHKERRQ(ierr); 1059cf3064d3SMatthew G. Knepley ierr = DMPlexVecGetClosure(dm, coordSection, coordinates, c, &numCoords, &coords);CHKERRQ(ierr); 1060cf3064d3SMatthew G. Knepley switch (coneSize) { 1061cf3064d3SMatthew G. Knepley case 3: 1062cf3064d3SMatthew G. Knepley ierr = PetscDrawTriangle(draw, PetscRealPart(coords[0]), PetscRealPart(coords[1]), PetscRealPart(coords[2]), PetscRealPart(coords[3]), PetscRealPart(coords[4]), PetscRealPart(coords[5]), 1063cf3064d3SMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2, 1064cf3064d3SMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2, 1065cf3064d3SMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2);CHKERRQ(ierr); 1066cf3064d3SMatthew G. Knepley break; 1067cf3064d3SMatthew G. Knepley case 4: 1068cf3064d3SMatthew G. Knepley ierr = PetscDrawRectangle(draw, PetscRealPart(coords[0]), PetscRealPart(coords[1]), PetscRealPart(coords[4]), PetscRealPart(coords[5]), 1069cf3064d3SMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2, 1070cf3064d3SMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2, 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);CHKERRQ(ierr); 1073cf3064d3SMatthew G. Knepley break; 1074cf3064d3SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot draw cells with %D facets", coneSize); 1075cf3064d3SMatthew G. Knepley } 1076cf3064d3SMatthew G. Knepley ierr = DMPlexVecRestoreClosure(dm, coordSection, coordinates, c, &numCoords, &coords);CHKERRQ(ierr); 1077cf3064d3SMatthew G. Knepley } 1078e412dcbdSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 1079e412dcbdSMatthew G. Knepley PetscScalar *coords = NULL; 108029494db1SLisandro Dalcin PetscInt numCoords,coneSize; 1081e412dcbdSMatthew G. Knepley 108229494db1SLisandro Dalcin ierr = DMPlexGetConeSize(dm, c, &coneSize);CHKERRQ(ierr); 1083e412dcbdSMatthew G. Knepley ierr = DMPlexVecGetClosure(dm, coordSection, coordinates, c, &numCoords, &coords);CHKERRQ(ierr); 108429494db1SLisandro Dalcin switch (coneSize) { 108529494db1SLisandro Dalcin case 3: 10860c81f2a8SMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[0]), PetscRealPart(coords[1]), PetscRealPart(coords[2]), PetscRealPart(coords[3]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 10870c81f2a8SMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[2]), PetscRealPart(coords[3]), PetscRealPart(coords[4]), PetscRealPart(coords[5]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 10880c81f2a8SMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[4]), PetscRealPart(coords[5]), PetscRealPart(coords[0]), PetscRealPart(coords[1]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 1089e412dcbdSMatthew G. Knepley break; 109029494db1SLisandro Dalcin case 4: 10910c81f2a8SMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[0]), PetscRealPart(coords[1]), PetscRealPart(coords[2]), PetscRealPart(coords[3]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 10920c81f2a8SMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[2]), PetscRealPart(coords[3]), PetscRealPart(coords[4]), PetscRealPart(coords[5]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 10930c81f2a8SMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[4]), PetscRealPart(coords[5]), PetscRealPart(coords[6]), PetscRealPart(coords[7]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 10940c81f2a8SMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[6]), PetscRealPart(coords[7]), PetscRealPart(coords[0]), PetscRealPart(coords[1]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 1095e412dcbdSMatthew G. Knepley break; 109629494db1SLisandro Dalcin default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot draw cells with %D facets", coneSize); 1097e412dcbdSMatthew G. Knepley } 1098e412dcbdSMatthew G. Knepley ierr = DMPlexVecRestoreClosure(dm, coordSection, coordinates, c, &numCoords, &coords);CHKERRQ(ierr); 1099e412dcbdSMatthew G. Knepley } 1100e412dcbdSMatthew G. Knepley ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 1101e412dcbdSMatthew G. Knepley ierr = PetscDrawPause(draw);CHKERRQ(ierr); 1102e412dcbdSMatthew G. Knepley ierr = PetscDrawSave(draw);CHKERRQ(ierr); 1103e412dcbdSMatthew G. Knepley PetscFunctionReturn(0); 1104e412dcbdSMatthew G. Knepley } 1105e412dcbdSMatthew G. Knepley 1106552f7358SJed Brown PetscErrorCode DMView_Plex(DM dm, PetscViewer viewer) 1107552f7358SJed Brown { 1108e655db49SSatish Balay PetscBool iascii, ishdf5, isvtk, isdraw, flg, isglvis; 1109002a2709SMatthew G. Knepley char name[PETSC_MAX_PATH_LEN]; 1110552f7358SJed Brown PetscErrorCode ierr; 1111552f7358SJed Brown 1112552f7358SJed Brown PetscFunctionBegin; 1113552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1114552f7358SJed Brown PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1115552f7358SJed Brown ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 1116fcf6c8fdSToby Isaac ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERVTK, &isvtk);CHKERRQ(ierr); 1117c6ccd67eSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 1118e412dcbdSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERDRAW, &isdraw);CHKERRQ(ierr); 11198135c375SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERGLVIS, &isglvis);CHKERRQ(ierr); 1120552f7358SJed Brown if (iascii) { 11218135c375SStefano Zampini PetscViewerFormat format; 11228135c375SStefano Zampini ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 11238135c375SStefano Zampini if (format == PETSC_VIEWER_ASCII_GLVIS) { 11248135c375SStefano Zampini ierr = DMPlexView_GLVis(dm, viewer);CHKERRQ(ierr); 11258135c375SStefano Zampini } else { 1126552f7358SJed Brown ierr = DMPlexView_Ascii(dm, viewer);CHKERRQ(ierr); 11278135c375SStefano Zampini } 1128c6ccd67eSMatthew G. Knepley } else if (ishdf5) { 1129c6ccd67eSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 113039d25373SMatthew G. Knepley ierr = DMPlexView_HDF5_Internal(dm, viewer);CHKERRQ(ierr); 1131c6ccd67eSMatthew G. Knepley #else 1132c6ccd67eSMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 1133552f7358SJed Brown #endif 1134e412dcbdSMatthew G. Knepley } else if (isvtk) { 1135fcf6c8fdSToby Isaac ierr = DMPlexVTKWriteAll((PetscObject) dm,viewer);CHKERRQ(ierr); 1136e412dcbdSMatthew G. Knepley } else if (isdraw) { 1137e412dcbdSMatthew G. Knepley ierr = DMPlexView_Draw(dm, viewer);CHKERRQ(ierr); 11388135c375SStefano Zampini } else if (isglvis) { 11398135c375SStefano Zampini ierr = DMPlexView_GLVis(dm, viewer);CHKERRQ(ierr); 114062201deeSVaclav Hapla } else { 1141a94aea51SVaclav Hapla SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Viewer type %s not yet supported for DMPlex writing", ((PetscObject)viewer)->type_name); 1142fcf6c8fdSToby Isaac } 1143cb3ba0daSMatthew G. Knepley /* Optionally view the partition */ 1144cb3ba0daSMatthew G. Knepley ierr = PetscOptionsHasName(((PetscObject) dm)->options, ((PetscObject) dm)->prefix, "-dm_partition_view", &flg);CHKERRQ(ierr); 1145cb3ba0daSMatthew G. Knepley if (flg) { 1146cb3ba0daSMatthew G. Knepley Vec ranks; 1147cb3ba0daSMatthew G. Knepley ierr = DMPlexCreateRankField(dm, &ranks);CHKERRQ(ierr); 1148cb3ba0daSMatthew G. Knepley ierr = VecView(ranks, viewer);CHKERRQ(ierr); 1149cb3ba0daSMatthew G. Knepley ierr = VecDestroy(&ranks);CHKERRQ(ierr); 1150cb3ba0daSMatthew G. Knepley } 1151002a2709SMatthew G. Knepley /* Optionally view a label */ 1152002a2709SMatthew G. Knepley ierr = PetscOptionsGetString(((PetscObject) dm)->options, ((PetscObject) dm)->prefix, "-dm_label_view", name, PETSC_MAX_PATH_LEN, &flg);CHKERRQ(ierr); 1153002a2709SMatthew G. Knepley if (flg) { 1154002a2709SMatthew G. Knepley DMLabel label; 1155002a2709SMatthew G. Knepley Vec val; 1156002a2709SMatthew G. Knepley 1157002a2709SMatthew G. Knepley ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 1158002a2709SMatthew 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); 1159002a2709SMatthew G. Knepley ierr = DMPlexCreateLabelField(dm, label, &val);CHKERRQ(ierr); 1160002a2709SMatthew G. Knepley ierr = VecView(val, viewer);CHKERRQ(ierr); 1161002a2709SMatthew G. Knepley ierr = VecDestroy(&val);CHKERRQ(ierr); 1162002a2709SMatthew G. Knepley } 1163552f7358SJed Brown PetscFunctionReturn(0); 1164552f7358SJed Brown } 1165552f7358SJed Brown 11662c40f234SMatthew G. Knepley PetscErrorCode DMLoad_Plex(DM dm, PetscViewer viewer) 11672c40f234SMatthew G. Knepley { 1168d4f5a9a0SVaclav Hapla PetscBool ishdf5; 11692c40f234SMatthew G. Knepley PetscErrorCode ierr; 11702c40f234SMatthew G. Knepley 11712c40f234SMatthew G. Knepley PetscFunctionBegin; 11722c40f234SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 11732c40f234SMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 11742c40f234SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 1175d4f5a9a0SVaclav Hapla if (ishdf5) { 11762c40f234SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 11779c48423bSVaclav Hapla PetscViewerFormat format; 11789c48423bSVaclav Hapla ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 11799c48423bSVaclav Hapla if (format == PETSC_VIEWER_HDF5_XDMF || format == PETSC_VIEWER_HDF5_VIZ) { 11809c48423bSVaclav Hapla ierr = DMPlexLoad_HDF5_Xdmf_Internal(dm, viewer);CHKERRQ(ierr); 1181509517efSVaclav Hapla } else if (format == PETSC_VIEWER_HDF5_PETSC || format == PETSC_VIEWER_DEFAULT || format == PETSC_VIEWER_NATIVE) { 118239d25373SMatthew G. Knepley ierr = DMPlexLoad_HDF5_Internal(dm, viewer);CHKERRQ(ierr); 1183509517efSVaclav Hapla } else SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "PetscViewerFormat %s not supported for HDF5 input.", PetscViewerFormats[format]); 11842c40f234SMatthew G. Knepley #else 11852c40f234SMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 1186552f7358SJed Brown #endif 1187d4f5a9a0SVaclav Hapla } else { 1188d4f5a9a0SVaclav Hapla SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Viewer type %s not yet supported for DMPlex loading", ((PetscObject)viewer)->type_name); 1189552f7358SJed Brown } 1190552f7358SJed Brown PetscFunctionReturn(0); 1191552f7358SJed Brown } 1192552f7358SJed Brown 1193552f7358SJed Brown PetscErrorCode DMDestroy_Plex(DM dm) 1194552f7358SJed Brown { 1195552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1196552f7358SJed Brown PetscErrorCode ierr; 1197552f7358SJed Brown 1198552f7358SJed Brown PetscFunctionBegin; 11998135c375SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)dm,"DMSetUpGLVisViewer_C",NULL);CHKERRQ(ierr); 12008135c375SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)dm,"DMPlexInsertBoundaryValues_C", NULL);CHKERRQ(ierr); 12010d644c17SKarl Rupp if (--mesh->refct > 0) PetscFunctionReturn(0); 1202552f7358SJed Brown ierr = PetscSectionDestroy(&mesh->coneSection);CHKERRQ(ierr); 1203552f7358SJed Brown ierr = PetscFree(mesh->cones);CHKERRQ(ierr); 1204552f7358SJed Brown ierr = PetscFree(mesh->coneOrientations);CHKERRQ(ierr); 1205552f7358SJed Brown ierr = PetscSectionDestroy(&mesh->supportSection);CHKERRQ(ierr); 1206be36d101SStefano Zampini ierr = PetscSectionDestroy(&mesh->subdomainSection);CHKERRQ(ierr); 1207552f7358SJed Brown ierr = PetscFree(mesh->supports);CHKERRQ(ierr); 1208552f7358SJed Brown ierr = PetscFree(mesh->facesTmp);CHKERRQ(ierr); 1209d9deefdfSMatthew G. Knepley ierr = PetscFree(mesh->tetgenOpts);CHKERRQ(ierr); 1210d9deefdfSMatthew G. Knepley ierr = PetscFree(mesh->triangleOpts);CHKERRQ(ierr); 121177623264SMatthew G. Knepley ierr = PetscPartitionerDestroy(&mesh->partitioner);CHKERRQ(ierr); 1212a89082eeSMatthew G Knepley ierr = DMLabelDestroy(&mesh->subpointMap);CHKERRQ(ierr); 1213552f7358SJed Brown ierr = ISDestroy(&mesh->globalVertexNumbers);CHKERRQ(ierr); 1214552f7358SJed Brown ierr = ISDestroy(&mesh->globalCellNumbers);CHKERRQ(ierr); 1215a68b90caSToby Isaac ierr = PetscSectionDestroy(&mesh->anchorSection);CHKERRQ(ierr); 1216a68b90caSToby Isaac ierr = ISDestroy(&mesh->anchorIS);CHKERRQ(ierr); 1217d961a43aSToby Isaac ierr = PetscSectionDestroy(&mesh->parentSection);CHKERRQ(ierr); 1218d961a43aSToby Isaac ierr = PetscFree(mesh->parents);CHKERRQ(ierr); 1219d961a43aSToby Isaac ierr = PetscFree(mesh->childIDs);CHKERRQ(ierr); 1220d961a43aSToby Isaac ierr = PetscSectionDestroy(&mesh->childSection);CHKERRQ(ierr); 1221d961a43aSToby Isaac ierr = PetscFree(mesh->children);CHKERRQ(ierr); 1222d6a7ad0dSToby Isaac ierr = DMDestroy(&mesh->referenceTree);CHKERRQ(ierr); 1223fec49543SMatthew G. Knepley ierr = PetscGridHashDestroy(&mesh->lbox);CHKERRQ(ierr); 1224552f7358SJed Brown /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */ 1225552f7358SJed Brown ierr = PetscFree(mesh);CHKERRQ(ierr); 1226552f7358SJed Brown PetscFunctionReturn(0); 1227552f7358SJed Brown } 1228552f7358SJed Brown 1229b412c318SBarry Smith PetscErrorCode DMCreateMatrix_Plex(DM dm, Mat *J) 1230552f7358SJed Brown { 12318d1174e4SMatthew G. Knepley PetscSection sectionGlobal; 1232acd755d7SMatthew G. Knepley PetscInt bs = -1, mbs; 1233552f7358SJed Brown PetscInt localSize; 1234837628f4SStefano Zampini PetscBool isShell, isBlock, isSeqBlock, isMPIBlock, isSymBlock, isSymSeqBlock, isSymMPIBlock, isMatIS; 1235552f7358SJed Brown PetscErrorCode ierr; 1236b412c318SBarry Smith MatType mtype; 12371428887cSShri Abhyankar ISLocalToGlobalMapping ltog; 1238552f7358SJed Brown 1239552f7358SJed Brown PetscFunctionBegin; 1240607a6623SBarry Smith ierr = MatInitializePackage();CHKERRQ(ierr); 1241b412c318SBarry Smith mtype = dm->mattype; 1242e87a4003SBarry Smith ierr = DMGetGlobalSection(dm, §ionGlobal);CHKERRQ(ierr); 1243552f7358SJed Brown /* ierr = PetscSectionGetStorageSize(sectionGlobal, &localSize);CHKERRQ(ierr); */ 1244552f7358SJed Brown ierr = PetscSectionGetConstrainedStorageSize(sectionGlobal, &localSize);CHKERRQ(ierr); 124582f516ccSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)dm), J);CHKERRQ(ierr); 1246552f7358SJed Brown ierr = MatSetSizes(*J, localSize, localSize, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 1247552f7358SJed Brown ierr = MatSetType(*J, mtype);CHKERRQ(ierr); 1248552f7358SJed Brown ierr = MatSetFromOptions(*J);CHKERRQ(ierr); 1249acd755d7SMatthew G. Knepley ierr = MatGetBlockSize(*J, &mbs);CHKERRQ(ierr); 1250acd755d7SMatthew G. Knepley if (mbs > 1) bs = mbs; 1251552f7358SJed Brown ierr = PetscStrcmp(mtype, MATSHELL, &isShell);CHKERRQ(ierr); 1252552f7358SJed Brown ierr = PetscStrcmp(mtype, MATBAIJ, &isBlock);CHKERRQ(ierr); 1253552f7358SJed Brown ierr = PetscStrcmp(mtype, MATSEQBAIJ, &isSeqBlock);CHKERRQ(ierr); 1254552f7358SJed Brown ierr = PetscStrcmp(mtype, MATMPIBAIJ, &isMPIBlock);CHKERRQ(ierr); 1255552f7358SJed Brown ierr = PetscStrcmp(mtype, MATSBAIJ, &isSymBlock);CHKERRQ(ierr); 1256552f7358SJed Brown ierr = PetscStrcmp(mtype, MATSEQSBAIJ, &isSymSeqBlock);CHKERRQ(ierr); 1257552f7358SJed Brown ierr = PetscStrcmp(mtype, MATMPISBAIJ, &isSymMPIBlock);CHKERRQ(ierr); 1258837628f4SStefano Zampini ierr = PetscStrcmp(mtype, MATIS, &isMatIS);CHKERRQ(ierr); 1259552f7358SJed Brown if (!isShell) { 1260be36d101SStefano Zampini PetscSection subSection; 1261837628f4SStefano Zampini PetscBool fillMatrix = (PetscBool)(!dm->prealloc_only && !isMatIS); 12620be3e97aSMatthew G. Knepley PetscInt *dnz, *onz, *dnzu, *onzu, bsLocal[2], bsMinMax[2], *ltogidx, lsize; 1263fad22124SMatthew G Knepley PetscInt pStart, pEnd, p, dof, cdof; 1264552f7358SJed Brown 126500140cc3SStefano Zampini /* Set localtoglobalmapping on the matrix for MatSetValuesLocal() to work (it also creates the local matrices in case of MATIS) */ 1266be36d101SStefano Zampini if (isMatIS) { /* need a different l2g map than the one computed by DMGetLocalToGlobalMapping */ 1267be36d101SStefano Zampini PetscSection section; 1268be36d101SStefano Zampini PetscInt size; 1269be36d101SStefano Zampini 1270e87a4003SBarry Smith ierr = DMGetSection(dm, §ion);CHKERRQ(ierr); 1271be36d101SStefano Zampini ierr = PetscSectionGetStorageSize(section, &size);CHKERRQ(ierr); 1272be36d101SStefano Zampini ierr = PetscMalloc1(size,<ogidx);CHKERRQ(ierr); 1273be36d101SStefano Zampini ierr = DMPlexGetSubdomainSection(dm, &subSection);CHKERRQ(ierr); 1274be36d101SStefano Zampini } else { 127500140cc3SStefano Zampini ierr = DMGetLocalToGlobalMapping(dm,<og);CHKERRQ(ierr); 1276be36d101SStefano Zampini } 1277552f7358SJed Brown ierr = PetscSectionGetChart(sectionGlobal, &pStart, &pEnd);CHKERRQ(ierr); 1278be36d101SStefano Zampini for (p = pStart, lsize = 0; p < pEnd; ++p) { 1279a9d99c84SMatthew G. Knepley PetscInt bdof; 1280a9d99c84SMatthew G. Knepley 1281552f7358SJed Brown ierr = PetscSectionGetDof(sectionGlobal, p, &dof);CHKERRQ(ierr); 1282fad22124SMatthew G Knepley ierr = PetscSectionGetConstraintDof(sectionGlobal, p, &cdof);CHKERRQ(ierr); 12831d17a0a3SMatthew G. Knepley dof = dof < 0 ? -(dof+1) : dof; 12841d17a0a3SMatthew G. Knepley bdof = cdof && (dof-cdof) ? 1 : dof; 12851d17a0a3SMatthew G. Knepley if (dof) { 12861d17a0a3SMatthew G. Knepley if (bs < 0) {bs = bdof;} 1287be36d101SStefano Zampini else if (bs != bdof) {bs = 1; if (!isMatIS) break;} 1288be36d101SStefano Zampini } 1289be36d101SStefano Zampini if (isMatIS) { 1290be36d101SStefano Zampini PetscInt loff,c,off; 1291be36d101SStefano Zampini ierr = PetscSectionGetOffset(subSection, p, &loff);CHKERRQ(ierr); 1292be36d101SStefano Zampini ierr = PetscSectionGetOffset(sectionGlobal, p, &off);CHKERRQ(ierr); 1293be36d101SStefano Zampini for (c = 0; c < dof-cdof; ++c, ++lsize) ltogidx[loff+c] = off > -1 ? off+c : -(off+1)+c; 1294552f7358SJed Brown } 12952a28c762SMatthew G Knepley } 12962a28c762SMatthew G Knepley /* Must have same blocksize on all procs (some might have no points) */ 12970be3e97aSMatthew G. Knepley bsLocal[0] = bs < 0 ? PETSC_MAX_INT : bs; bsLocal[1] = bs; 12980be3e97aSMatthew G. Knepley ierr = PetscGlobalMinMaxInt(PetscObjectComm((PetscObject) dm), bsLocal, bsMinMax);CHKERRQ(ierr); 12990be3e97aSMatthew G. Knepley if (bsMinMax[0] != bsMinMax[1]) {bs = 1;} 13000be3e97aSMatthew G. Knepley else {bs = bsMinMax[0];} 13014fa26246SMatthew G. Knepley bs = bs < 0 ? 1 : bs; 1302be36d101SStefano Zampini if (isMatIS) { 13034fa26246SMatthew G. Knepley PetscInt l; 13044fa26246SMatthew G. Knepley /* Must reduce indices by blocksize */ 13054fa26246SMatthew G. Knepley if (bs > 1) for (l = 0; l < lsize; ++l) ltogidx[l] /= bs; 13064fa26246SMatthew G. Knepley ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)dm), bs, lsize, ltogidx, PETSC_OWN_POINTER, <og);CHKERRQ(ierr); 1307be36d101SStefano Zampini } 1308be36d101SStefano Zampini ierr = MatSetLocalToGlobalMapping(*J,ltog,ltog);CHKERRQ(ierr); 1309be36d101SStefano Zampini if (isMatIS) { 1310be36d101SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(<og);CHKERRQ(ierr); 1311be36d101SStefano Zampini } 13121795a4d1SJed Brown ierr = PetscCalloc4(localSize/bs, &dnz, localSize/bs, &onz, localSize/bs, &dnzu, localSize/bs, &onzu);CHKERRQ(ierr); 13138d1174e4SMatthew G. Knepley ierr = DMPlexPreallocateOperator(dm, bs, dnz, onz, dnzu, onzu, *J, fillMatrix);CHKERRQ(ierr); 1314552f7358SJed Brown ierr = PetscFree4(dnz, onz, dnzu, onzu);CHKERRQ(ierr); 1315552f7358SJed Brown } 1316b1f74addSMatthew G. Knepley ierr = MatSetDM(*J, dm);CHKERRQ(ierr); 1317552f7358SJed Brown PetscFunctionReturn(0); 1318552f7358SJed Brown } 1319552f7358SJed Brown 13207cd05799SMatthew G. Knepley /*@ 1321a8f00d21SMatthew G. Knepley DMPlexGetSubdomainSection - Returns the section associated with the subdomain 1322be36d101SStefano Zampini 1323be36d101SStefano Zampini Not collective 1324be36d101SStefano Zampini 1325be36d101SStefano Zampini Input Parameter: 1326be36d101SStefano Zampini . mesh - The DMPlex 1327be36d101SStefano Zampini 1328be36d101SStefano Zampini Output Parameters: 1329be36d101SStefano Zampini . subsection - The subdomain section 1330be36d101SStefano Zampini 1331be36d101SStefano Zampini Level: developer 1332be36d101SStefano Zampini 1333be36d101SStefano Zampini .seealso: 13347cd05799SMatthew G. Knepley @*/ 1335be36d101SStefano Zampini PetscErrorCode DMPlexGetSubdomainSection(DM dm, PetscSection *subsection) 1336be36d101SStefano Zampini { 1337be36d101SStefano Zampini DM_Plex *mesh = (DM_Plex*) dm->data; 1338be36d101SStefano Zampini PetscErrorCode ierr; 1339be36d101SStefano Zampini 1340be36d101SStefano Zampini PetscFunctionBegin; 1341be36d101SStefano Zampini PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1342be36d101SStefano Zampini if (!mesh->subdomainSection) { 1343be36d101SStefano Zampini PetscSection section; 1344be36d101SStefano Zampini PetscSF sf; 1345be36d101SStefano Zampini 1346be36d101SStefano Zampini ierr = PetscSFCreate(PETSC_COMM_SELF,&sf);CHKERRQ(ierr); 1347e87a4003SBarry Smith ierr = DMGetSection(dm,§ion);CHKERRQ(ierr); 1348be36d101SStefano Zampini ierr = PetscSectionCreateGlobalSection(section,sf,PETSC_FALSE,PETSC_TRUE,&mesh->subdomainSection);CHKERRQ(ierr); 1349be36d101SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 1350be36d101SStefano Zampini } 1351be36d101SStefano Zampini *subsection = mesh->subdomainSection; 1352be36d101SStefano Zampini PetscFunctionReturn(0); 1353be36d101SStefano Zampini } 1354be36d101SStefano Zampini 1355552f7358SJed Brown /*@ 1356552f7358SJed Brown DMPlexGetChart - Return the interval for all mesh points [pStart, pEnd) 1357552f7358SJed Brown 1358552f7358SJed Brown Not collective 1359552f7358SJed Brown 1360552f7358SJed Brown Input Parameter: 1361552f7358SJed Brown . mesh - The DMPlex 1362552f7358SJed Brown 1363552f7358SJed Brown Output Parameters: 1364552f7358SJed Brown + pStart - The first mesh point 1365552f7358SJed Brown - pEnd - The upper bound for mesh points 1366552f7358SJed Brown 1367552f7358SJed Brown Level: beginner 1368552f7358SJed Brown 1369552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetChart() 1370552f7358SJed Brown @*/ 1371552f7358SJed Brown PetscErrorCode DMPlexGetChart(DM dm, PetscInt *pStart, PetscInt *pEnd) 1372552f7358SJed Brown { 1373552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1374552f7358SJed Brown PetscErrorCode ierr; 1375552f7358SJed Brown 1376552f7358SJed Brown PetscFunctionBegin; 1377552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1378552f7358SJed Brown ierr = PetscSectionGetChart(mesh->coneSection, pStart, pEnd);CHKERRQ(ierr); 1379552f7358SJed Brown PetscFunctionReturn(0); 1380552f7358SJed Brown } 1381552f7358SJed Brown 1382552f7358SJed Brown /*@ 1383552f7358SJed Brown DMPlexSetChart - Set the interval for all mesh points [pStart, pEnd) 1384552f7358SJed Brown 1385552f7358SJed Brown Not collective 1386552f7358SJed Brown 1387552f7358SJed Brown Input Parameters: 1388552f7358SJed Brown + mesh - The DMPlex 1389552f7358SJed Brown . pStart - The first mesh point 1390552f7358SJed Brown - pEnd - The upper bound for mesh points 1391552f7358SJed Brown 1392552f7358SJed Brown Output Parameters: 1393552f7358SJed Brown 1394552f7358SJed Brown Level: beginner 1395552f7358SJed Brown 1396552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetChart() 1397552f7358SJed Brown @*/ 1398552f7358SJed Brown PetscErrorCode DMPlexSetChart(DM dm, PetscInt pStart, PetscInt pEnd) 1399552f7358SJed Brown { 1400552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1401552f7358SJed Brown PetscErrorCode ierr; 1402552f7358SJed Brown 1403552f7358SJed Brown PetscFunctionBegin; 1404552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1405552f7358SJed Brown ierr = PetscSectionSetChart(mesh->coneSection, pStart, pEnd);CHKERRQ(ierr); 1406552f7358SJed Brown ierr = PetscSectionSetChart(mesh->supportSection, pStart, pEnd);CHKERRQ(ierr); 1407552f7358SJed Brown PetscFunctionReturn(0); 1408552f7358SJed Brown } 1409552f7358SJed Brown 1410552f7358SJed Brown /*@ 1411eaf898f9SPatrick Sanan DMPlexGetConeSize - Return the number of in-edges for this point in the DAG 1412552f7358SJed Brown 1413552f7358SJed Brown Not collective 1414552f7358SJed Brown 1415552f7358SJed Brown Input Parameters: 1416552f7358SJed Brown + mesh - The DMPlex 1417eaf898f9SPatrick Sanan - p - The point, which must lie in the chart set with DMPlexSetChart() 1418552f7358SJed Brown 1419552f7358SJed Brown Output Parameter: 1420552f7358SJed Brown . size - The cone size for point p 1421552f7358SJed Brown 1422552f7358SJed Brown Level: beginner 1423552f7358SJed Brown 1424552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetConeSize(), DMPlexSetChart() 1425552f7358SJed Brown @*/ 1426552f7358SJed Brown PetscErrorCode DMPlexGetConeSize(DM dm, PetscInt p, PetscInt *size) 1427552f7358SJed Brown { 1428552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1429552f7358SJed Brown PetscErrorCode ierr; 1430552f7358SJed Brown 1431552f7358SJed Brown PetscFunctionBegin; 1432552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1433552f7358SJed Brown PetscValidPointer(size, 3); 1434552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, size);CHKERRQ(ierr); 1435552f7358SJed Brown PetscFunctionReturn(0); 1436552f7358SJed Brown } 1437552f7358SJed Brown 1438552f7358SJed Brown /*@ 1439eaf898f9SPatrick Sanan DMPlexSetConeSize - Set the number of in-edges for this point in the DAG 1440552f7358SJed Brown 1441552f7358SJed Brown Not collective 1442552f7358SJed Brown 1443552f7358SJed Brown Input Parameters: 1444552f7358SJed Brown + mesh - The DMPlex 1445eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 1446552f7358SJed Brown - size - The cone size for point p 1447552f7358SJed Brown 1448552f7358SJed Brown Output Parameter: 1449552f7358SJed Brown 1450552f7358SJed Brown Note: 1451552f7358SJed Brown This should be called after DMPlexSetChart(). 1452552f7358SJed Brown 1453552f7358SJed Brown Level: beginner 1454552f7358SJed Brown 1455552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetConeSize(), DMPlexSetChart() 1456552f7358SJed Brown @*/ 1457552f7358SJed Brown PetscErrorCode DMPlexSetConeSize(DM dm, PetscInt p, PetscInt size) 1458552f7358SJed Brown { 1459552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1460552f7358SJed Brown PetscErrorCode ierr; 1461552f7358SJed Brown 1462552f7358SJed Brown PetscFunctionBegin; 1463552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1464552f7358SJed Brown ierr = PetscSectionSetDof(mesh->coneSection, p, size);CHKERRQ(ierr); 14650d644c17SKarl Rupp 1466552f7358SJed Brown mesh->maxConeSize = PetscMax(mesh->maxConeSize, size); 1467552f7358SJed Brown PetscFunctionReturn(0); 1468552f7358SJed Brown } 1469552f7358SJed Brown 1470f5a469b9SMatthew G. Knepley /*@ 1471eaf898f9SPatrick Sanan DMPlexAddConeSize - Add the given number of in-edges to this point in the DAG 1472f5a469b9SMatthew G. Knepley 1473f5a469b9SMatthew G. Knepley Not collective 1474f5a469b9SMatthew G. Knepley 1475f5a469b9SMatthew G. Knepley Input Parameters: 1476f5a469b9SMatthew G. Knepley + mesh - The DMPlex 1477eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 1478f5a469b9SMatthew G. Knepley - size - The additional cone size for point p 1479f5a469b9SMatthew G. Knepley 1480f5a469b9SMatthew G. Knepley Output Parameter: 1481f5a469b9SMatthew G. Knepley 1482f5a469b9SMatthew G. Knepley Note: 1483f5a469b9SMatthew G. Knepley This should be called after DMPlexSetChart(). 1484f5a469b9SMatthew G. Knepley 1485f5a469b9SMatthew G. Knepley Level: beginner 1486f5a469b9SMatthew G. Knepley 1487f5a469b9SMatthew G. Knepley .seealso: DMPlexCreate(), DMPlexSetConeSize(), DMPlexGetConeSize(), DMPlexSetChart() 1488f5a469b9SMatthew G. Knepley @*/ 1489f5a469b9SMatthew G. Knepley PetscErrorCode DMPlexAddConeSize(DM dm, PetscInt p, PetscInt size) 1490f5a469b9SMatthew G. Knepley { 1491f5a469b9SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 1492f5a469b9SMatthew G. Knepley PetscInt csize; 1493f5a469b9SMatthew G. Knepley PetscErrorCode ierr; 1494f5a469b9SMatthew G. Knepley 1495f5a469b9SMatthew G. Knepley PetscFunctionBegin; 1496f5a469b9SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1497f5a469b9SMatthew G. Knepley ierr = PetscSectionAddDof(mesh->coneSection, p, size);CHKERRQ(ierr); 1498f5a469b9SMatthew G. Knepley ierr = PetscSectionGetDof(mesh->coneSection, p, &csize);CHKERRQ(ierr); 1499f5a469b9SMatthew G. Knepley 1500f5a469b9SMatthew G. Knepley mesh->maxConeSize = PetscMax(mesh->maxConeSize, csize); 1501f5a469b9SMatthew G. Knepley PetscFunctionReturn(0); 1502f5a469b9SMatthew G. Knepley } 1503f5a469b9SMatthew G. Knepley 1504552f7358SJed Brown /*@C 1505eaf898f9SPatrick Sanan DMPlexGetCone - Return the points on the in-edges for this point in the DAG 1506552f7358SJed Brown 1507552f7358SJed Brown Not collective 1508552f7358SJed Brown 1509552f7358SJed Brown Input Parameters: 1510833c876bSVaclav Hapla + dm - The DMPlex 1511eaf898f9SPatrick Sanan - p - The point, which must lie in the chart set with DMPlexSetChart() 1512552f7358SJed Brown 1513552f7358SJed Brown Output Parameter: 1514552f7358SJed Brown . cone - An array of points which are on the in-edges for point p 1515552f7358SJed Brown 1516552f7358SJed Brown Level: beginner 1517552f7358SJed Brown 15183813dfbdSMatthew G Knepley Fortran Notes: 15193813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 15203813dfbdSMatthew G Knepley include petsc.h90 in your code. 15213813dfbdSMatthew G Knepley 15220ce7577fSVaclav Hapla .seealso: DMPlexCreate(), DMPlexSetCone(), DMPlexGetConeTuple(), DMPlexSetChart() 1523552f7358SJed Brown @*/ 1524552f7358SJed Brown PetscErrorCode DMPlexGetCone(DM dm, PetscInt p, const PetscInt *cone[]) 1525552f7358SJed Brown { 1526552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1527552f7358SJed Brown PetscInt off; 1528552f7358SJed Brown PetscErrorCode ierr; 1529552f7358SJed Brown 1530552f7358SJed Brown PetscFunctionBegin; 1531552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1532552f7358SJed Brown PetscValidPointer(cone, 3); 1533552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 1534552f7358SJed Brown *cone = &mesh->cones[off]; 1535552f7358SJed Brown PetscFunctionReturn(0); 1536552f7358SJed Brown } 1537552f7358SJed Brown 15380ce7577fSVaclav Hapla /*@C 15390ce7577fSVaclav Hapla DMPlexGetConeTuple - Return the points on the in-edges of several points in the DAG 15400ce7577fSVaclav Hapla 15410ce7577fSVaclav Hapla Not collective 15420ce7577fSVaclav Hapla 15430ce7577fSVaclav Hapla Input Parameters: 15440ce7577fSVaclav Hapla + dm - The DMPlex 15450ce7577fSVaclav Hapla - p - The IS of points, which must lie in the chart set with DMPlexSetChart() 15460ce7577fSVaclav Hapla 15470ce7577fSVaclav Hapla Output Parameter: 15480ce7577fSVaclav Hapla + pConesSection - PetscSection describing the layout of pCones 15490ce7577fSVaclav Hapla - pCones - An array of points which are on the in-edges for the point set p 15500ce7577fSVaclav Hapla 15510ce7577fSVaclav Hapla Level: intermediate 15520ce7577fSVaclav Hapla 1553d4636a37SVaclav Hapla .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexGetConeRecursive(), DMPlexSetChart() 15540ce7577fSVaclav Hapla @*/ 15550ce7577fSVaclav Hapla PetscErrorCode DMPlexGetConeTuple(DM dm, IS p, PetscSection *pConesSection, IS *pCones) 15560ce7577fSVaclav Hapla { 15570ce7577fSVaclav Hapla PetscSection cs, newcs; 15580ce7577fSVaclav Hapla PetscInt *cones; 15590ce7577fSVaclav Hapla PetscInt *newarr=NULL; 15600ce7577fSVaclav Hapla PetscInt n; 15610ce7577fSVaclav Hapla PetscErrorCode ierr; 15620ce7577fSVaclav Hapla 15630ce7577fSVaclav Hapla PetscFunctionBegin; 15640ce7577fSVaclav Hapla ierr = DMPlexGetCones(dm, &cones);CHKERRQ(ierr); 15650ce7577fSVaclav Hapla ierr = DMPlexGetConeSection(dm, &cs);CHKERRQ(ierr); 15660ce7577fSVaclav Hapla ierr = PetscSectionExtractDofsFromArray(cs, MPIU_INT, cones, p, &newcs, pCones ? ((void**)&newarr) : NULL);CHKERRQ(ierr); 15670ce7577fSVaclav Hapla if (pConesSection) *pConesSection = newcs; 15680ce7577fSVaclav Hapla if (pCones) { 15690ce7577fSVaclav Hapla ierr = PetscSectionGetStorageSize(newcs, &n);CHKERRQ(ierr); 15700ce7577fSVaclav Hapla ierr = ISCreateGeneral(PetscObjectComm((PetscObject)p), n, newarr, PETSC_OWN_POINTER, pCones);CHKERRQ(ierr); 15710ce7577fSVaclav Hapla } 15720ce7577fSVaclav Hapla PetscFunctionReturn(0); 15730ce7577fSVaclav Hapla } 15740ce7577fSVaclav Hapla 1575d4636a37SVaclav Hapla static PetscErrorCode DMPlexGetConeRecursive_Private(DM dm, PetscInt *n_inout, const PetscInt points[], PetscInt *offset_inout, PetscInt buf[]) 1576d4636a37SVaclav Hapla { 1577d4636a37SVaclav Hapla PetscInt p, n, cn, i; 1578d4636a37SVaclav Hapla const PetscInt *cone; 1579d4636a37SVaclav Hapla PetscErrorCode ierr; 1580d4636a37SVaclav Hapla 1581d4636a37SVaclav Hapla PetscFunctionBegin; 1582d4636a37SVaclav Hapla n = *n_inout; 1583d4636a37SVaclav Hapla *n_inout = 0; 1584d4636a37SVaclav Hapla for (i=0; i<n; i++) { 1585d4636a37SVaclav Hapla p = points[i]; 1586d4636a37SVaclav Hapla ierr = DMPlexGetConeSize(dm, p, &cn);CHKERRQ(ierr); 1587d4636a37SVaclav Hapla if (!cn) { 1588d4636a37SVaclav Hapla cn = 1; 1589d4636a37SVaclav Hapla if (buf) { 1590d4636a37SVaclav Hapla buf[*offset_inout] = p; 1591d4636a37SVaclav Hapla ++(*offset_inout); 1592d4636a37SVaclav Hapla } 1593d4636a37SVaclav Hapla } else { 1594d4636a37SVaclav Hapla ierr = DMPlexGetCone(dm, p, &cone);CHKERRQ(ierr); 1595d4636a37SVaclav Hapla ierr = DMPlexGetConeRecursive_Private(dm, &cn, cone, offset_inout, buf);CHKERRQ(ierr); 1596d4636a37SVaclav Hapla } 1597d4636a37SVaclav Hapla *n_inout += cn; 1598d4636a37SVaclav Hapla } 1599d4636a37SVaclav Hapla PetscFunctionReturn(0); 1600d4636a37SVaclav Hapla } 1601d4636a37SVaclav Hapla 1602d4636a37SVaclav Hapla /*@C 1603d4636a37SVaclav 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. 1604d4636a37SVaclav Hapla 1605d4636a37SVaclav Hapla Not collective 1606d4636a37SVaclav Hapla 1607d4636a37SVaclav Hapla Input Parameters: 1608d4636a37SVaclav Hapla + dm - The DMPlex 1609d4636a37SVaclav Hapla - p - The IS of points, which must lie in the chart set with DMPlexSetChart() 1610d4636a37SVaclav Hapla 1611d4636a37SVaclav Hapla Output Parameter: 1612d4636a37SVaclav Hapla . pCones - An array of recursively expanded cones, i.e. containing only vertices, and each of them can be present multiple times 1613d4636a37SVaclav Hapla 1614d4636a37SVaclav Hapla Level: advanced 1615d4636a37SVaclav Hapla 1616d4636a37SVaclav Hapla .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexGetConeTuple() 1617d4636a37SVaclav Hapla @*/ 1618d4636a37SVaclav Hapla PetscErrorCode DMPlexGetConeRecursive(DM dm, IS p, IS *pCones) 1619d4636a37SVaclav Hapla { 1620d4636a37SVaclav Hapla const PetscInt *arr=NULL; 1621d4636a37SVaclav Hapla PetscInt *cpoints=NULL; 1622d4636a37SVaclav Hapla PetscInt n, cn; 1623d4636a37SVaclav Hapla PetscInt zero; 1624d4636a37SVaclav Hapla PetscErrorCode ierr; 1625d4636a37SVaclav Hapla 1626d4636a37SVaclav Hapla PetscFunctionBegin; 1627d4636a37SVaclav Hapla ierr = ISGetLocalSize(p, &n);CHKERRQ(ierr); 1628d4636a37SVaclav Hapla ierr = ISGetIndices(p, &arr);CHKERRQ(ierr); 1629d4636a37SVaclav Hapla zero = 0; 1630d4636a37SVaclav Hapla /* first figure out the total number of returned points */ 1631d4636a37SVaclav Hapla cn = n; 1632d4636a37SVaclav Hapla ierr = DMPlexGetConeRecursive_Private(dm, &cn, arr, &zero, NULL);CHKERRQ(ierr); 1633d4636a37SVaclav Hapla ierr = PetscMalloc1(cn, &cpoints);CHKERRQ(ierr); 1634d4636a37SVaclav Hapla /* now get recursive cones themselves */ 1635d4636a37SVaclav Hapla ierr = DMPlexGetConeRecursive_Private(dm, &n, arr, &zero, cpoints);CHKERRQ(ierr); 1636d4636a37SVaclav Hapla ierr = ISCreateGeneral(PetscObjectComm((PetscObject)p), n, cpoints, PETSC_OWN_POINTER, pCones);CHKERRQ(ierr); 1637d4636a37SVaclav Hapla ierr = ISRestoreIndices(p, &arr);CHKERRQ(ierr); 1638d4636a37SVaclav Hapla PetscFunctionReturn(0); 1639d4636a37SVaclav Hapla } 1640d4636a37SVaclav Hapla 1641552f7358SJed Brown /*@ 164292371b87SBarry 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 1643552f7358SJed Brown 1644552f7358SJed Brown Not collective 1645552f7358SJed Brown 1646552f7358SJed Brown Input Parameters: 1647552f7358SJed Brown + mesh - The DMPlex 1648eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 1649552f7358SJed Brown - cone - An array of points which are on the in-edges for point p 1650552f7358SJed Brown 1651552f7358SJed Brown Output Parameter: 1652552f7358SJed Brown 1653552f7358SJed Brown Note: 1654552f7358SJed Brown This should be called after all calls to DMPlexSetConeSize() and DMSetUp(). 1655552f7358SJed Brown 165692371b87SBarry Smith Developer Note: Why not call this DMPlexSetCover() 165792371b87SBarry Smith 1658552f7358SJed Brown Level: beginner 1659552f7358SJed Brown 166092371b87SBarry Smith .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexSetChart(), DMPlexSetConeSize(), DMSetUp(), DMPlexSetSupport(), DMPlexSetSupportSize() 1661552f7358SJed Brown @*/ 1662552f7358SJed Brown PetscErrorCode DMPlexSetCone(DM dm, PetscInt p, const PetscInt cone[]) 1663552f7358SJed Brown { 1664552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1665552f7358SJed Brown PetscInt pStart, pEnd; 1666552f7358SJed Brown PetscInt dof, off, c; 1667552f7358SJed Brown PetscErrorCode ierr; 1668552f7358SJed Brown 1669552f7358SJed Brown PetscFunctionBegin; 1670552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1671552f7358SJed Brown ierr = PetscSectionGetChart(mesh->coneSection, &pStart, &pEnd);CHKERRQ(ierr); 1672552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 1673552f7358SJed Brown if (dof) PetscValidPointer(cone, 3); 1674552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 167582f516ccSBarry 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); 1676552f7358SJed Brown for (c = 0; c < dof; ++c) { 167782f516ccSBarry 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); 1678552f7358SJed Brown mesh->cones[off+c] = cone[c]; 1679552f7358SJed Brown } 1680552f7358SJed Brown PetscFunctionReturn(0); 1681552f7358SJed Brown } 1682552f7358SJed Brown 1683552f7358SJed Brown /*@C 1684eaf898f9SPatrick Sanan DMPlexGetConeOrientation - Return the orientations on the in-edges for this point in the DAG 1685552f7358SJed Brown 1686552f7358SJed Brown Not collective 1687552f7358SJed Brown 1688552f7358SJed Brown Input Parameters: 1689552f7358SJed Brown + mesh - The DMPlex 1690eaf898f9SPatrick Sanan - p - The point, which must lie in the chart set with DMPlexSetChart() 1691552f7358SJed Brown 1692552f7358SJed Brown Output Parameter: 1693552f7358SJed Brown . coneOrientation - An array of orientations which are on the in-edges for point p. An orientation is an 1694552f7358SJed Brown integer giving the prescription for cone traversal. If it is negative, the cone is 1695552f7358SJed Brown traversed in the opposite direction. Its value 'o', or if negative '-(o+1)', gives 1696552f7358SJed Brown the index of the cone point on which to start. 1697552f7358SJed Brown 1698552f7358SJed Brown Level: beginner 1699552f7358SJed Brown 17003813dfbdSMatthew G Knepley Fortran Notes: 17013813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 17023813dfbdSMatthew G Knepley include petsc.h90 in your code. 17033813dfbdSMatthew G Knepley 17043813dfbdSMatthew G Knepley You must also call DMPlexRestoreConeOrientation() after you finish using the returned array. 1705552f7358SJed Brown 1706552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexSetCone(), DMPlexSetChart() 1707552f7358SJed Brown @*/ 1708552f7358SJed Brown PetscErrorCode DMPlexGetConeOrientation(DM dm, PetscInt p, const PetscInt *coneOrientation[]) 1709552f7358SJed Brown { 1710552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1711552f7358SJed Brown PetscInt off; 1712552f7358SJed Brown PetscErrorCode ierr; 1713552f7358SJed Brown 1714552f7358SJed Brown PetscFunctionBegin; 1715552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1716552f7358SJed Brown #if defined(PETSC_USE_DEBUG) 1717552f7358SJed Brown { 1718552f7358SJed Brown PetscInt dof; 1719552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 1720552f7358SJed Brown if (dof) PetscValidPointer(coneOrientation, 3); 1721552f7358SJed Brown } 1722552f7358SJed Brown #endif 1723552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 17240d644c17SKarl Rupp 1725552f7358SJed Brown *coneOrientation = &mesh->coneOrientations[off]; 1726552f7358SJed Brown PetscFunctionReturn(0); 1727552f7358SJed Brown } 1728552f7358SJed Brown 1729552f7358SJed Brown /*@ 1730eaf898f9SPatrick Sanan DMPlexSetConeOrientation - Set the orientations on the in-edges for this point in the DAG 1731552f7358SJed Brown 1732552f7358SJed Brown Not collective 1733552f7358SJed Brown 1734552f7358SJed Brown Input Parameters: 1735552f7358SJed Brown + mesh - The DMPlex 1736eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 1737552f7358SJed Brown - coneOrientation - An array of orientations which are on the in-edges for point p. An orientation is an 1738552f7358SJed Brown integer giving the prescription for cone traversal. If it is negative, the cone is 1739552f7358SJed Brown traversed in the opposite direction. Its value 'o', or if negative '-(o+1)', gives 1740552f7358SJed Brown the index of the cone point on which to start. 1741552f7358SJed Brown 1742552f7358SJed Brown Output Parameter: 1743552f7358SJed Brown 1744552f7358SJed Brown Note: 1745552f7358SJed Brown This should be called after all calls to DMPlexSetConeSize() and DMSetUp(). 1746552f7358SJed Brown 1747552f7358SJed Brown Level: beginner 1748552f7358SJed Brown 1749552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetConeOrientation(), DMPlexSetCone(), DMPlexSetChart(), DMPlexSetConeSize(), DMSetUp() 1750552f7358SJed Brown @*/ 1751552f7358SJed Brown PetscErrorCode DMPlexSetConeOrientation(DM dm, PetscInt p, const PetscInt coneOrientation[]) 1752552f7358SJed Brown { 1753552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1754552f7358SJed Brown PetscInt pStart, pEnd; 1755552f7358SJed Brown PetscInt dof, off, c; 1756552f7358SJed Brown PetscErrorCode ierr; 1757552f7358SJed Brown 1758552f7358SJed Brown PetscFunctionBegin; 1759552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1760552f7358SJed Brown ierr = PetscSectionGetChart(mesh->coneSection, &pStart, &pEnd);CHKERRQ(ierr); 1761552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 1762552f7358SJed Brown if (dof) PetscValidPointer(coneOrientation, 3); 1763552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 176482f516ccSBarry 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); 1765552f7358SJed Brown for (c = 0; c < dof; ++c) { 1766552f7358SJed Brown PetscInt cdof, o = coneOrientation[c]; 1767552f7358SJed Brown 1768552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, mesh->cones[off+c], &cdof);CHKERRQ(ierr); 176982f516ccSBarry 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); 1770552f7358SJed Brown mesh->coneOrientations[off+c] = o; 1771552f7358SJed Brown } 1772552f7358SJed Brown PetscFunctionReturn(0); 1773552f7358SJed Brown } 1774552f7358SJed Brown 17757cd05799SMatthew G. Knepley /*@ 1776eaf898f9SPatrick Sanan DMPlexInsertCone - Insert a point into the in-edges for the point p in the DAG 17777cd05799SMatthew G. Knepley 17787cd05799SMatthew G. Knepley Not collective 17797cd05799SMatthew G. Knepley 17807cd05799SMatthew G. Knepley Input Parameters: 17817cd05799SMatthew G. Knepley + mesh - The DMPlex 1782eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 17837cd05799SMatthew G. Knepley . conePos - The local index in the cone where the point should be put 17847cd05799SMatthew G. Knepley - conePoint - The mesh point to insert 17857cd05799SMatthew G. Knepley 17867cd05799SMatthew G. Knepley Level: beginner 17877cd05799SMatthew G. Knepley 17887cd05799SMatthew G. Knepley .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexSetChart(), DMPlexSetConeSize(), DMSetUp() 17897cd05799SMatthew G. Knepley @*/ 1790552f7358SJed Brown PetscErrorCode DMPlexInsertCone(DM dm, PetscInt p, PetscInt conePos, PetscInt conePoint) 1791552f7358SJed Brown { 1792552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1793552f7358SJed Brown PetscInt pStart, pEnd; 1794552f7358SJed Brown PetscInt dof, off; 1795552f7358SJed Brown PetscErrorCode ierr; 1796552f7358SJed Brown 1797552f7358SJed Brown PetscFunctionBegin; 1798552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1799552f7358SJed Brown ierr = PetscSectionGetChart(mesh->coneSection, &pStart, &pEnd);CHKERRQ(ierr); 180082f516ccSBarry 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); 180182f516ccSBarry 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); 180277c88f5bSMatthew G Knepley ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 180377c88f5bSMatthew G Knepley ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 180477c88f5bSMatthew 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); 1805552f7358SJed Brown mesh->cones[off+conePos] = conePoint; 1806552f7358SJed Brown PetscFunctionReturn(0); 1807552f7358SJed Brown } 1808552f7358SJed Brown 18097cd05799SMatthew G. Knepley /*@ 1810eaf898f9SPatrick Sanan DMPlexInsertConeOrientation - Insert a point orientation for the in-edge for the point p in the DAG 18117cd05799SMatthew G. Knepley 18127cd05799SMatthew G. Knepley Not collective 18137cd05799SMatthew G. Knepley 18147cd05799SMatthew G. Knepley Input Parameters: 18157cd05799SMatthew G. Knepley + mesh - The DMPlex 1816eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 18177cd05799SMatthew G. Knepley . conePos - The local index in the cone where the point should be put 18187cd05799SMatthew G. Knepley - coneOrientation - The point orientation to insert 18197cd05799SMatthew G. Knepley 18207cd05799SMatthew G. Knepley Level: beginner 18217cd05799SMatthew G. Knepley 18227cd05799SMatthew G. Knepley .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexSetChart(), DMPlexSetConeSize(), DMSetUp() 18237cd05799SMatthew G. Knepley @*/ 182477c88f5bSMatthew G Knepley PetscErrorCode DMPlexInsertConeOrientation(DM dm, PetscInt p, PetscInt conePos, PetscInt coneOrientation) 182577c88f5bSMatthew G Knepley { 182677c88f5bSMatthew G Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 182777c88f5bSMatthew G Knepley PetscInt pStart, pEnd; 182877c88f5bSMatthew G Knepley PetscInt dof, off; 182977c88f5bSMatthew G Knepley PetscErrorCode ierr; 183077c88f5bSMatthew G Knepley 183177c88f5bSMatthew G Knepley PetscFunctionBegin; 183277c88f5bSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 183377c88f5bSMatthew G Knepley ierr = PetscSectionGetChart(mesh->coneSection, &pStart, &pEnd);CHKERRQ(ierr); 183477c88f5bSMatthew 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); 183577c88f5bSMatthew G Knepley ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 183677c88f5bSMatthew G Knepley ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 183777c88f5bSMatthew 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); 183877c88f5bSMatthew G Knepley mesh->coneOrientations[off+conePos] = coneOrientation; 183977c88f5bSMatthew G Knepley PetscFunctionReturn(0); 184077c88f5bSMatthew G Knepley } 184177c88f5bSMatthew G Knepley 1842552f7358SJed Brown /*@ 1843eaf898f9SPatrick Sanan DMPlexGetSupportSize - Return the number of out-edges for this point in the DAG 1844552f7358SJed Brown 1845552f7358SJed Brown Not collective 1846552f7358SJed Brown 1847552f7358SJed Brown Input Parameters: 1848552f7358SJed Brown + mesh - The DMPlex 1849eaf898f9SPatrick Sanan - p - The point, which must lie in the chart set with DMPlexSetChart() 1850552f7358SJed Brown 1851552f7358SJed Brown Output Parameter: 1852552f7358SJed Brown . size - The support size for point p 1853552f7358SJed Brown 1854552f7358SJed Brown Level: beginner 1855552f7358SJed Brown 1856552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetConeSize(), DMPlexSetChart(), DMPlexGetConeSize() 1857552f7358SJed Brown @*/ 1858552f7358SJed Brown PetscErrorCode DMPlexGetSupportSize(DM dm, PetscInt p, PetscInt *size) 1859552f7358SJed Brown { 1860552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1861552f7358SJed Brown PetscErrorCode ierr; 1862552f7358SJed Brown 1863552f7358SJed Brown PetscFunctionBegin; 1864552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1865552f7358SJed Brown PetscValidPointer(size, 3); 1866552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, size);CHKERRQ(ierr); 1867552f7358SJed Brown PetscFunctionReturn(0); 1868552f7358SJed Brown } 1869552f7358SJed Brown 1870552f7358SJed Brown /*@ 1871eaf898f9SPatrick Sanan DMPlexSetSupportSize - Set the number of out-edges for this point in the DAG 1872552f7358SJed Brown 1873552f7358SJed Brown Not collective 1874552f7358SJed Brown 1875552f7358SJed Brown Input Parameters: 1876552f7358SJed Brown + mesh - The DMPlex 1877eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 1878552f7358SJed Brown - size - The support size for point p 1879552f7358SJed Brown 1880552f7358SJed Brown Output Parameter: 1881552f7358SJed Brown 1882552f7358SJed Brown Note: 1883552f7358SJed Brown This should be called after DMPlexSetChart(). 1884552f7358SJed Brown 1885552f7358SJed Brown Level: beginner 1886552f7358SJed Brown 1887552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetSupportSize(), DMPlexSetChart() 1888552f7358SJed Brown @*/ 1889552f7358SJed Brown PetscErrorCode DMPlexSetSupportSize(DM dm, PetscInt p, PetscInt size) 1890552f7358SJed Brown { 1891552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1892552f7358SJed Brown PetscErrorCode ierr; 1893552f7358SJed Brown 1894552f7358SJed Brown PetscFunctionBegin; 1895552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1896552f7358SJed Brown ierr = PetscSectionSetDof(mesh->supportSection, p, size);CHKERRQ(ierr); 18970d644c17SKarl Rupp 1898552f7358SJed Brown mesh->maxSupportSize = PetscMax(mesh->maxSupportSize, size); 1899552f7358SJed Brown PetscFunctionReturn(0); 1900552f7358SJed Brown } 1901552f7358SJed Brown 1902552f7358SJed Brown /*@C 1903eaf898f9SPatrick Sanan DMPlexGetSupport - Return the points on the out-edges for this point in the DAG 1904552f7358SJed Brown 1905552f7358SJed Brown Not collective 1906552f7358SJed Brown 1907552f7358SJed Brown Input Parameters: 1908552f7358SJed Brown + mesh - The DMPlex 1909eaf898f9SPatrick Sanan - p - The point, which must lie in the chart set with DMPlexSetChart() 1910552f7358SJed Brown 1911552f7358SJed Brown Output Parameter: 1912552f7358SJed Brown . support - An array of points which are on the out-edges for point p 1913552f7358SJed Brown 1914552f7358SJed Brown Level: beginner 1915552f7358SJed Brown 19163813dfbdSMatthew G Knepley Fortran Notes: 19173813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 19183813dfbdSMatthew G Knepley include petsc.h90 in your code. 19193813dfbdSMatthew G Knepley 19203813dfbdSMatthew G Knepley You must also call DMPlexRestoreSupport() after you finish using the returned array. 19213813dfbdSMatthew G Knepley 1922552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetCone(), DMPlexSetChart(), DMPlexGetCone() 1923552f7358SJed Brown @*/ 1924552f7358SJed Brown PetscErrorCode DMPlexGetSupport(DM dm, PetscInt p, const PetscInt *support[]) 1925552f7358SJed Brown { 1926552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1927552f7358SJed Brown PetscInt off; 1928552f7358SJed Brown PetscErrorCode ierr; 1929552f7358SJed Brown 1930552f7358SJed Brown PetscFunctionBegin; 1931552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1932552f7358SJed Brown PetscValidPointer(support, 3); 1933552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, p, &off);CHKERRQ(ierr); 1934552f7358SJed Brown *support = &mesh->supports[off]; 1935552f7358SJed Brown PetscFunctionReturn(0); 1936552f7358SJed Brown } 1937552f7358SJed Brown 1938552f7358SJed Brown /*@ 193992371b87SBarry 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 1940552f7358SJed Brown 1941552f7358SJed Brown Not collective 1942552f7358SJed Brown 1943552f7358SJed Brown Input Parameters: 1944552f7358SJed Brown + mesh - The DMPlex 1945eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 194692371b87SBarry Smith - support - An array of points which are on the out-edges for point p 1947552f7358SJed Brown 1948552f7358SJed Brown Output Parameter: 1949552f7358SJed Brown 1950552f7358SJed Brown Note: 1951552f7358SJed Brown This should be called after all calls to DMPlexSetSupportSize() and DMSetUp(). 1952552f7358SJed Brown 1953552f7358SJed Brown Level: beginner 1954552f7358SJed Brown 195592371b87SBarry Smith .seealso: DMPlexSetCone(), DMPlexSetConeSize(), DMPlexCreate(), DMPlexGetSupport(), DMPlexSetChart(), DMPlexSetSupportSize(), DMSetUp() 1956552f7358SJed Brown @*/ 1957552f7358SJed Brown PetscErrorCode DMPlexSetSupport(DM dm, PetscInt p, const PetscInt support[]) 1958552f7358SJed Brown { 1959552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1960552f7358SJed Brown PetscInt pStart, pEnd; 1961552f7358SJed Brown PetscInt dof, off, c; 1962552f7358SJed Brown PetscErrorCode ierr; 1963552f7358SJed Brown 1964552f7358SJed Brown PetscFunctionBegin; 1965552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1966552f7358SJed Brown ierr = PetscSectionGetChart(mesh->supportSection, &pStart, &pEnd);CHKERRQ(ierr); 1967552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, &dof);CHKERRQ(ierr); 1968552f7358SJed Brown if (dof) PetscValidPointer(support, 3); 1969552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, p, &off);CHKERRQ(ierr); 197082f516ccSBarry 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); 1971552f7358SJed Brown for (c = 0; c < dof; ++c) { 197282f516ccSBarry 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); 1973552f7358SJed Brown mesh->supports[off+c] = support[c]; 1974552f7358SJed Brown } 1975552f7358SJed Brown PetscFunctionReturn(0); 1976552f7358SJed Brown } 1977552f7358SJed Brown 19787cd05799SMatthew G. Knepley /*@ 1979eaf898f9SPatrick Sanan DMPlexInsertSupport - Insert a point into the out-edges for the point p in the DAG 19807cd05799SMatthew G. Knepley 19817cd05799SMatthew G. Knepley Not collective 19827cd05799SMatthew G. Knepley 19837cd05799SMatthew G. Knepley Input Parameters: 19847cd05799SMatthew G. Knepley + mesh - The DMPlex 1985eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 19867cd05799SMatthew G. Knepley . supportPos - The local index in the cone where the point should be put 19877cd05799SMatthew G. Knepley - supportPoint - The mesh point to insert 19887cd05799SMatthew G. Knepley 19897cd05799SMatthew G. Knepley Level: beginner 19907cd05799SMatthew G. Knepley 19917cd05799SMatthew G. Knepley .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexSetChart(), DMPlexSetConeSize(), DMSetUp() 19927cd05799SMatthew G. Knepley @*/ 1993552f7358SJed Brown PetscErrorCode DMPlexInsertSupport(DM dm, PetscInt p, PetscInt supportPos, PetscInt supportPoint) 1994552f7358SJed Brown { 1995552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1996552f7358SJed Brown PetscInt pStart, pEnd; 1997552f7358SJed Brown PetscInt dof, off; 1998552f7358SJed Brown PetscErrorCode ierr; 1999552f7358SJed Brown 2000552f7358SJed Brown PetscFunctionBegin; 2001552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2002552f7358SJed Brown ierr = PetscSectionGetChart(mesh->supportSection, &pStart, &pEnd);CHKERRQ(ierr); 2003552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, &dof);CHKERRQ(ierr); 2004552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, p, &off);CHKERRQ(ierr); 200582f516ccSBarry 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); 200682f516ccSBarry 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); 200782f516ccSBarry 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); 2008552f7358SJed Brown mesh->supports[off+supportPos] = supportPoint; 2009552f7358SJed Brown PetscFunctionReturn(0); 2010552f7358SJed Brown } 2011552f7358SJed Brown 2012552f7358SJed Brown /*@C 2013eaf898f9SPatrick Sanan DMPlexGetTransitiveClosure - Return the points on the transitive closure of the in-edges or out-edges for this point in the DAG 2014552f7358SJed Brown 2015552f7358SJed Brown Not collective 2016552f7358SJed Brown 2017552f7358SJed Brown Input Parameters: 2018552f7358SJed Brown + mesh - The DMPlex 2019eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 2020552f7358SJed Brown . useCone - PETSC_TRUE for in-edges, otherwise use out-edges 20210298fd71SBarry Smith - points - If points is NULL on input, internal storage will be returned, otherwise the provided array is used 2022552f7358SJed Brown 2023552f7358SJed Brown Output Parameters: 2024552f7358SJed Brown + numPoints - The number of points in the closure, so points[] is of size 2*numPoints 2025552f7358SJed Brown - points - The points and point orientations, interleaved as pairs [p0, o0, p1, o1, ...] 2026552f7358SJed Brown 2027552f7358SJed Brown Note: 20280298fd71SBarry Smith If using internal storage (points is NULL on input), each call overwrites the last output. 2029552f7358SJed Brown 20303813dfbdSMatthew G Knepley Fortran Notes: 20313813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 20323813dfbdSMatthew G Knepley include petsc.h90 in your code. 20333813dfbdSMatthew G Knepley 20343813dfbdSMatthew G Knepley The numPoints argument is not present in the Fortran 90 binding since it is internal to the array. 20353813dfbdSMatthew G Knepley 2036552f7358SJed Brown Level: beginner 2037552f7358SJed Brown 2038552f7358SJed Brown .seealso: DMPlexRestoreTransitiveClosure(), DMPlexCreate(), DMPlexSetCone(), DMPlexSetChart(), DMPlexGetCone() 2039552f7358SJed Brown @*/ 2040552f7358SJed Brown PetscErrorCode DMPlexGetTransitiveClosure(DM dm, PetscInt p, PetscBool useCone, PetscInt *numPoints, PetscInt *points[]) 2041552f7358SJed Brown { 2042552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2043552f7358SJed Brown PetscInt *closure, *fifo; 20440298fd71SBarry Smith const PetscInt *tmp = NULL, *tmpO = NULL; 2045552f7358SJed Brown PetscInt tmpSize, t; 2046552f7358SJed Brown PetscInt depth = 0, maxSize; 2047552f7358SJed Brown PetscInt closureSize = 2, fifoSize = 0, fifoStart = 0; 2048552f7358SJed Brown PetscErrorCode ierr; 2049552f7358SJed Brown 2050552f7358SJed Brown PetscFunctionBegin; 2051552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2052552f7358SJed Brown ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 2053552f7358SJed Brown /* This is only 1-level */ 2054552f7358SJed Brown if (useCone) { 2055552f7358SJed Brown ierr = DMPlexGetConeSize(dm, p, &tmpSize);CHKERRQ(ierr); 2056552f7358SJed Brown ierr = DMPlexGetCone(dm, p, &tmp);CHKERRQ(ierr); 2057552f7358SJed Brown ierr = DMPlexGetConeOrientation(dm, p, &tmpO);CHKERRQ(ierr); 2058552f7358SJed Brown } else { 2059552f7358SJed Brown ierr = DMPlexGetSupportSize(dm, p, &tmpSize);CHKERRQ(ierr); 2060552f7358SJed Brown ierr = DMPlexGetSupport(dm, p, &tmp);CHKERRQ(ierr); 2061552f7358SJed Brown } 2062bfbcdd7aSMatthew G. Knepley if (depth == 1) { 2063bfbcdd7aSMatthew G. Knepley if (*points) { 2064bfbcdd7aSMatthew G. Knepley closure = *points; 2065bfbcdd7aSMatthew G. Knepley } else { 2066bfbcdd7aSMatthew G. Knepley maxSize = 2*(PetscMax(mesh->maxConeSize, mesh->maxSupportSize)+1); 206769291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &closure);CHKERRQ(ierr); 2068bfbcdd7aSMatthew G. Knepley } 2069bfbcdd7aSMatthew G. Knepley closure[0] = p; closure[1] = 0; 2070bfbcdd7aSMatthew G. Knepley for (t = 0; t < tmpSize; ++t, closureSize += 2) { 2071bfbcdd7aSMatthew G. Knepley closure[closureSize] = tmp[t]; 2072bfbcdd7aSMatthew G. Knepley closure[closureSize+1] = tmpO ? tmpO[t] : 0; 2073bfbcdd7aSMatthew G. Knepley } 2074bfbcdd7aSMatthew G. Knepley if (numPoints) *numPoints = closureSize/2; 2075bfbcdd7aSMatthew G. Knepley if (points) *points = closure; 2076bfbcdd7aSMatthew G. Knepley PetscFunctionReturn(0); 2077bfbcdd7aSMatthew G. Knepley } 207824c766afSToby Isaac { 207924c766afSToby Isaac PetscInt c, coneSeries, s,supportSeries; 208024c766afSToby Isaac 208124c766afSToby Isaac c = mesh->maxConeSize; 208224c766afSToby Isaac coneSeries = (c > 1) ? ((PetscPowInt(c,depth+1)-1)/(c-1)) : depth+1; 208324c766afSToby Isaac s = mesh->maxSupportSize; 208424c766afSToby Isaac supportSeries = (s > 1) ? ((PetscPowInt(s,depth+1)-1)/(s-1)) : depth+1; 208524c766afSToby Isaac maxSize = 2*PetscMax(coneSeries,supportSeries); 208624c766afSToby Isaac } 208769291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &fifo);CHKERRQ(ierr); 2088bfbcdd7aSMatthew G. Knepley if (*points) { 2089bfbcdd7aSMatthew G. Knepley closure = *points; 2090bfbcdd7aSMatthew G. Knepley } else { 209169291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &closure);CHKERRQ(ierr); 2092bfbcdd7aSMatthew G. Knepley } 2093bfbcdd7aSMatthew G. Knepley closure[0] = p; closure[1] = 0; 2094552f7358SJed Brown for (t = 0; t < tmpSize; ++t, closureSize += 2, fifoSize += 2) { 2095552f7358SJed Brown const PetscInt cp = tmp[t]; 2096552f7358SJed Brown const PetscInt co = tmpO ? tmpO[t] : 0; 2097552f7358SJed Brown 2098552f7358SJed Brown closure[closureSize] = cp; 2099552f7358SJed Brown closure[closureSize+1] = co; 2100552f7358SJed Brown fifo[fifoSize] = cp; 2101552f7358SJed Brown fifo[fifoSize+1] = co; 2102552f7358SJed Brown } 2103bfbcdd7aSMatthew G. Knepley /* Should kick out early when depth is reached, rather than checking all vertices for empty cones */ 2104552f7358SJed Brown while (fifoSize - fifoStart) { 2105552f7358SJed Brown const PetscInt q = fifo[fifoStart]; 2106552f7358SJed Brown const PetscInt o = fifo[fifoStart+1]; 2107552f7358SJed Brown const PetscInt rev = o >= 0 ? 0 : 1; 2108552f7358SJed Brown const PetscInt off = rev ? -(o+1) : o; 2109552f7358SJed Brown 2110552f7358SJed Brown if (useCone) { 2111552f7358SJed Brown ierr = DMPlexGetConeSize(dm, q, &tmpSize);CHKERRQ(ierr); 2112552f7358SJed Brown ierr = DMPlexGetCone(dm, q, &tmp);CHKERRQ(ierr); 2113552f7358SJed Brown ierr = DMPlexGetConeOrientation(dm, q, &tmpO);CHKERRQ(ierr); 2114552f7358SJed Brown } else { 2115552f7358SJed Brown ierr = DMPlexGetSupportSize(dm, q, &tmpSize);CHKERRQ(ierr); 2116552f7358SJed Brown ierr = DMPlexGetSupport(dm, q, &tmp);CHKERRQ(ierr); 21170298fd71SBarry Smith tmpO = NULL; 2118552f7358SJed Brown } 2119552f7358SJed Brown for (t = 0; t < tmpSize; ++t) { 2120552f7358SJed Brown const PetscInt i = ((rev ? tmpSize-t : t) + off)%tmpSize; 2121552f7358SJed Brown const PetscInt cp = tmp[i]; 21222e1b13c2SMatthew 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. */ 21232e1b13c2SMatthew G. Knepley /* HACK: It is worse to get the size here, than to change the interpretation of -(*+1) 21242e1b13c2SMatthew G. Knepley const PetscInt co = tmpO ? (rev ? -(tmpO[i]+1) : tmpO[i]) : 0; */ 21252e1b13c2SMatthew G. Knepley PetscInt co = tmpO ? tmpO[i] : 0; 2126552f7358SJed Brown PetscInt c; 2127552f7358SJed Brown 21282e1b13c2SMatthew G. Knepley if (rev) { 21292e1b13c2SMatthew G. Knepley PetscInt childSize, coff; 21302e1b13c2SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, cp, &childSize);CHKERRQ(ierr); 21312e1b13c2SMatthew G. Knepley coff = tmpO[i] < 0 ? -(tmpO[i]+1) : tmpO[i]; 21322e1b13c2SMatthew G. Knepley co = childSize ? -(((coff+childSize-1)%childSize)+1) : 0; 21332e1b13c2SMatthew G. Knepley } 2134552f7358SJed Brown /* Check for duplicate */ 2135552f7358SJed Brown for (c = 0; c < closureSize; c += 2) { 2136552f7358SJed Brown if (closure[c] == cp) break; 2137552f7358SJed Brown } 2138552f7358SJed Brown if (c == closureSize) { 2139552f7358SJed Brown closure[closureSize] = cp; 2140552f7358SJed Brown closure[closureSize+1] = co; 2141552f7358SJed Brown fifo[fifoSize] = cp; 2142552f7358SJed Brown fifo[fifoSize+1] = co; 2143552f7358SJed Brown closureSize += 2; 2144552f7358SJed Brown fifoSize += 2; 2145552f7358SJed Brown } 2146552f7358SJed Brown } 2147552f7358SJed Brown fifoStart += 2; 2148552f7358SJed Brown } 2149552f7358SJed Brown if (numPoints) *numPoints = closureSize/2; 2150552f7358SJed Brown if (points) *points = closure; 215169291d52SBarry Smith ierr = DMRestoreWorkArray(dm, maxSize, MPIU_INT, &fifo);CHKERRQ(ierr); 2152552f7358SJed Brown PetscFunctionReturn(0); 2153552f7358SJed Brown } 2154552f7358SJed Brown 21559bf0dad6SMatthew G. Knepley /*@C 2156eaf898f9SPatrick 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 21579bf0dad6SMatthew G. Knepley 21589bf0dad6SMatthew G. Knepley Not collective 21599bf0dad6SMatthew G. Knepley 21609bf0dad6SMatthew G. Knepley Input Parameters: 21619bf0dad6SMatthew G. Knepley + mesh - The DMPlex 2162eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 21639bf0dad6SMatthew G. Knepley . orientation - The orientation of the point 21649bf0dad6SMatthew G. Knepley . useCone - PETSC_TRUE for in-edges, otherwise use out-edges 21659bf0dad6SMatthew G. Knepley - points - If points is NULL on input, internal storage will be returned, otherwise the provided array is used 21669bf0dad6SMatthew G. Knepley 21679bf0dad6SMatthew G. Knepley Output Parameters: 21689bf0dad6SMatthew G. Knepley + numPoints - The number of points in the closure, so points[] is of size 2*numPoints 21699bf0dad6SMatthew G. Knepley - points - The points and point orientations, interleaved as pairs [p0, o0, p1, o1, ...] 21709bf0dad6SMatthew G. Knepley 21719bf0dad6SMatthew G. Knepley Note: 21729bf0dad6SMatthew G. Knepley If using internal storage (points is NULL on input), each call overwrites the last output. 21739bf0dad6SMatthew G. Knepley 21749bf0dad6SMatthew G. Knepley Fortran Notes: 21759bf0dad6SMatthew G. Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 21769bf0dad6SMatthew G. Knepley include petsc.h90 in your code. 21779bf0dad6SMatthew G. Knepley 21789bf0dad6SMatthew G. Knepley The numPoints argument is not present in the Fortran 90 binding since it is internal to the array. 21799bf0dad6SMatthew G. Knepley 21809bf0dad6SMatthew G. Knepley Level: beginner 21819bf0dad6SMatthew G. Knepley 21829bf0dad6SMatthew G. Knepley .seealso: DMPlexRestoreTransitiveClosure(), DMPlexCreate(), DMPlexSetCone(), DMPlexSetChart(), DMPlexGetCone() 21839bf0dad6SMatthew G. Knepley @*/ 21849bf0dad6SMatthew G. Knepley PetscErrorCode DMPlexGetTransitiveClosure_Internal(DM dm, PetscInt p, PetscInt ornt, PetscBool useCone, PetscInt *numPoints, PetscInt *points[]) 21859bf0dad6SMatthew G. Knepley { 21869bf0dad6SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 21879bf0dad6SMatthew G. Knepley PetscInt *closure, *fifo; 21889bf0dad6SMatthew G. Knepley const PetscInt *tmp = NULL, *tmpO = NULL; 21899bf0dad6SMatthew G. Knepley PetscInt tmpSize, t; 21909bf0dad6SMatthew G. Knepley PetscInt depth = 0, maxSize; 21919bf0dad6SMatthew G. Knepley PetscInt closureSize = 2, fifoSize = 0, fifoStart = 0; 21929bf0dad6SMatthew G. Knepley PetscErrorCode ierr; 21939bf0dad6SMatthew G. Knepley 21949bf0dad6SMatthew G. Knepley PetscFunctionBegin; 21959bf0dad6SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 21969bf0dad6SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 21979bf0dad6SMatthew G. Knepley /* This is only 1-level */ 21989bf0dad6SMatthew G. Knepley if (useCone) { 21999bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, p, &tmpSize);CHKERRQ(ierr); 22009bf0dad6SMatthew G. Knepley ierr = DMPlexGetCone(dm, p, &tmp);CHKERRQ(ierr); 22019bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, p, &tmpO);CHKERRQ(ierr); 22029bf0dad6SMatthew G. Knepley } else { 22039bf0dad6SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, p, &tmpSize);CHKERRQ(ierr); 22049bf0dad6SMatthew G. Knepley ierr = DMPlexGetSupport(dm, p, &tmp);CHKERRQ(ierr); 22059bf0dad6SMatthew G. Knepley } 22069bf0dad6SMatthew G. Knepley if (depth == 1) { 22079bf0dad6SMatthew G. Knepley if (*points) { 22089bf0dad6SMatthew G. Knepley closure = *points; 22099bf0dad6SMatthew G. Knepley } else { 22109bf0dad6SMatthew G. Knepley maxSize = 2*(PetscMax(mesh->maxConeSize, mesh->maxSupportSize)+1); 221169291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &closure);CHKERRQ(ierr); 22129bf0dad6SMatthew G. Knepley } 22139bf0dad6SMatthew G. Knepley closure[0] = p; closure[1] = ornt; 22149bf0dad6SMatthew G. Knepley for (t = 0; t < tmpSize; ++t, closureSize += 2) { 22159bf0dad6SMatthew G. Knepley const PetscInt i = ornt >= 0 ? (t+ornt)%tmpSize : (-(ornt+1) + tmpSize-t)%tmpSize; 22169bf0dad6SMatthew G. Knepley closure[closureSize] = tmp[i]; 22179bf0dad6SMatthew G. Knepley closure[closureSize+1] = tmpO ? tmpO[i] : 0; 22189bf0dad6SMatthew G. Knepley } 22199bf0dad6SMatthew G. Knepley if (numPoints) *numPoints = closureSize/2; 22209bf0dad6SMatthew G. Knepley if (points) *points = closure; 22219bf0dad6SMatthew G. Knepley PetscFunctionReturn(0); 22229bf0dad6SMatthew G. Knepley } 222324c766afSToby Isaac { 222424c766afSToby Isaac PetscInt c, coneSeries, s,supportSeries; 222524c766afSToby Isaac 222624c766afSToby Isaac c = mesh->maxConeSize; 222724c766afSToby Isaac coneSeries = (c > 1) ? ((PetscPowInt(c,depth+1)-1)/(c-1)) : depth+1; 222824c766afSToby Isaac s = mesh->maxSupportSize; 222924c766afSToby Isaac supportSeries = (s > 1) ? ((PetscPowInt(s,depth+1)-1)/(s-1)) : depth+1; 223024c766afSToby Isaac maxSize = 2*PetscMax(coneSeries,supportSeries); 223124c766afSToby Isaac } 223269291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &fifo);CHKERRQ(ierr); 22339bf0dad6SMatthew G. Knepley if (*points) { 22349bf0dad6SMatthew G. Knepley closure = *points; 22359bf0dad6SMatthew G. Knepley } else { 223669291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &closure);CHKERRQ(ierr); 22379bf0dad6SMatthew G. Knepley } 22389bf0dad6SMatthew G. Knepley closure[0] = p; closure[1] = ornt; 22399bf0dad6SMatthew G. Knepley for (t = 0; t < tmpSize; ++t, closureSize += 2, fifoSize += 2) { 22409bf0dad6SMatthew G. Knepley const PetscInt i = ornt >= 0 ? (t+ornt)%tmpSize : (-(ornt+1) + tmpSize-t)%tmpSize; 22419bf0dad6SMatthew G. Knepley const PetscInt cp = tmp[i]; 22429bf0dad6SMatthew G. Knepley PetscInt co = tmpO ? tmpO[i] : 0; 22439bf0dad6SMatthew G. Knepley 22449bf0dad6SMatthew G. Knepley if (ornt < 0) { 22459bf0dad6SMatthew G. Knepley PetscInt childSize, coff; 22469bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, cp, &childSize);CHKERRQ(ierr); 224786b63641SMatthew G. Knepley coff = co < 0 ? -(tmpO[i]+1) : tmpO[i]; 22489bf0dad6SMatthew G. Knepley co = childSize ? -(((coff+childSize-1)%childSize)+1) : 0; 22499bf0dad6SMatthew G. Knepley } 22509bf0dad6SMatthew G. Knepley closure[closureSize] = cp; 22519bf0dad6SMatthew G. Knepley closure[closureSize+1] = co; 22529bf0dad6SMatthew G. Knepley fifo[fifoSize] = cp; 22539bf0dad6SMatthew G. Knepley fifo[fifoSize+1] = co; 22549bf0dad6SMatthew G. Knepley } 22559bf0dad6SMatthew G. Knepley /* Should kick out early when depth is reached, rather than checking all vertices for empty cones */ 22569bf0dad6SMatthew G. Knepley while (fifoSize - fifoStart) { 22579bf0dad6SMatthew G. Knepley const PetscInt q = fifo[fifoStart]; 22589bf0dad6SMatthew G. Knepley const PetscInt o = fifo[fifoStart+1]; 22599bf0dad6SMatthew G. Knepley const PetscInt rev = o >= 0 ? 0 : 1; 22609bf0dad6SMatthew G. Knepley const PetscInt off = rev ? -(o+1) : o; 22619bf0dad6SMatthew G. Knepley 22629bf0dad6SMatthew G. Knepley if (useCone) { 22639bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, q, &tmpSize);CHKERRQ(ierr); 22649bf0dad6SMatthew G. Knepley ierr = DMPlexGetCone(dm, q, &tmp);CHKERRQ(ierr); 22659bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, q, &tmpO);CHKERRQ(ierr); 22669bf0dad6SMatthew G. Knepley } else { 22679bf0dad6SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, q, &tmpSize);CHKERRQ(ierr); 22689bf0dad6SMatthew G. Knepley ierr = DMPlexGetSupport(dm, q, &tmp);CHKERRQ(ierr); 22699bf0dad6SMatthew G. Knepley tmpO = NULL; 22709bf0dad6SMatthew G. Knepley } 22719bf0dad6SMatthew G. Knepley for (t = 0; t < tmpSize; ++t) { 22729bf0dad6SMatthew G. Knepley const PetscInt i = ((rev ? tmpSize-t : t) + off)%tmpSize; 22739bf0dad6SMatthew G. Knepley const PetscInt cp = tmp[i]; 22749bf0dad6SMatthew 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. */ 22759bf0dad6SMatthew G. Knepley /* HACK: It is worse to get the size here, than to change the interpretation of -(*+1) 22769bf0dad6SMatthew G. Knepley const PetscInt co = tmpO ? (rev ? -(tmpO[i]+1) : tmpO[i]) : 0; */ 22779bf0dad6SMatthew G. Knepley PetscInt co = tmpO ? tmpO[i] : 0; 22789bf0dad6SMatthew G. Knepley PetscInt c; 22799bf0dad6SMatthew G. Knepley 22809bf0dad6SMatthew G. Knepley if (rev) { 22819bf0dad6SMatthew G. Knepley PetscInt childSize, coff; 22829bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, cp, &childSize);CHKERRQ(ierr); 22839bf0dad6SMatthew G. Knepley coff = tmpO[i] < 0 ? -(tmpO[i]+1) : tmpO[i]; 22849bf0dad6SMatthew G. Knepley co = childSize ? -(((coff+childSize-1)%childSize)+1) : 0; 22859bf0dad6SMatthew G. Knepley } 22869bf0dad6SMatthew G. Knepley /* Check for duplicate */ 22879bf0dad6SMatthew G. Knepley for (c = 0; c < closureSize; c += 2) { 22889bf0dad6SMatthew G. Knepley if (closure[c] == cp) break; 22899bf0dad6SMatthew G. Knepley } 22909bf0dad6SMatthew G. Knepley if (c == closureSize) { 22919bf0dad6SMatthew G. Knepley closure[closureSize] = cp; 22929bf0dad6SMatthew G. Knepley closure[closureSize+1] = co; 22939bf0dad6SMatthew G. Knepley fifo[fifoSize] = cp; 22949bf0dad6SMatthew G. Knepley fifo[fifoSize+1] = co; 22959bf0dad6SMatthew G. Knepley closureSize += 2; 22969bf0dad6SMatthew G. Knepley fifoSize += 2; 22979bf0dad6SMatthew G. Knepley } 22989bf0dad6SMatthew G. Knepley } 22999bf0dad6SMatthew G. Knepley fifoStart += 2; 23009bf0dad6SMatthew G. Knepley } 23019bf0dad6SMatthew G. Knepley if (numPoints) *numPoints = closureSize/2; 23029bf0dad6SMatthew G. Knepley if (points) *points = closure; 230369291d52SBarry Smith ierr = DMRestoreWorkArray(dm, maxSize, MPIU_INT, &fifo);CHKERRQ(ierr); 23049bf0dad6SMatthew G. Knepley PetscFunctionReturn(0); 23059bf0dad6SMatthew G. Knepley } 23069bf0dad6SMatthew G. Knepley 2307552f7358SJed Brown /*@C 2308eaf898f9SPatrick Sanan DMPlexRestoreTransitiveClosure - Restore the array of points on the transitive closure of the in-edges or out-edges for this point in the DAG 2309552f7358SJed Brown 2310552f7358SJed Brown Not collective 2311552f7358SJed Brown 2312552f7358SJed Brown Input Parameters: 2313552f7358SJed Brown + mesh - The DMPlex 2314eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 2315552f7358SJed Brown . useCone - PETSC_TRUE for in-edges, otherwise use out-edges 2316e5c84f05SJed Brown . numPoints - The number of points in the closure, so points[] is of size 2*numPoints, zeroed on exit 2317e5c84f05SJed Brown - points - The points and point orientations, interleaved as pairs [p0, o0, p1, o1, ...], zeroed on exit 2318552f7358SJed Brown 2319552f7358SJed Brown Note: 23200298fd71SBarry Smith If not using internal storage (points is not NULL on input), this call is unnecessary 2321552f7358SJed Brown 23223813dfbdSMatthew G Knepley Fortran Notes: 23233813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 23243813dfbdSMatthew G Knepley include petsc.h90 in your code. 23253813dfbdSMatthew G Knepley 23263813dfbdSMatthew G Knepley The numPoints argument is not present in the Fortran 90 binding since it is internal to the array. 23273813dfbdSMatthew G Knepley 2328552f7358SJed Brown Level: beginner 2329552f7358SJed Brown 2330552f7358SJed Brown .seealso: DMPlexGetTransitiveClosure(), DMPlexCreate(), DMPlexSetCone(), DMPlexSetChart(), DMPlexGetCone() 2331552f7358SJed Brown @*/ 2332552f7358SJed Brown PetscErrorCode DMPlexRestoreTransitiveClosure(DM dm, PetscInt p, PetscBool useCone, PetscInt *numPoints, PetscInt *points[]) 2333552f7358SJed Brown { 2334552f7358SJed Brown PetscErrorCode ierr; 2335552f7358SJed Brown 2336552f7358SJed Brown PetscFunctionBegin; 2337552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2338e5c84f05SJed Brown if (numPoints) PetscValidIntPointer(numPoints,4); 2339e5c84f05SJed Brown if (points) PetscValidPointer(points,5); 234069291d52SBarry Smith ierr = DMRestoreWorkArray(dm, 0, MPIU_INT, points);CHKERRQ(ierr); 23414ff43b2cSJed Brown if (numPoints) *numPoints = 0; 2342552f7358SJed Brown PetscFunctionReturn(0); 2343552f7358SJed Brown } 2344552f7358SJed Brown 2345552f7358SJed Brown /*@ 2346eaf898f9SPatrick Sanan DMPlexGetMaxSizes - Return the maximum number of in-edges (cone) and out-edges (support) for any point in the DAG 2347552f7358SJed Brown 2348552f7358SJed Brown Not collective 2349552f7358SJed Brown 2350552f7358SJed Brown Input Parameter: 2351552f7358SJed Brown . mesh - The DMPlex 2352552f7358SJed Brown 2353552f7358SJed Brown Output Parameters: 2354552f7358SJed Brown + maxConeSize - The maximum number of in-edges 2355552f7358SJed Brown - maxSupportSize - The maximum number of out-edges 2356552f7358SJed Brown 2357552f7358SJed Brown Level: beginner 2358552f7358SJed Brown 2359552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetConeSize(), DMPlexSetChart() 2360552f7358SJed Brown @*/ 2361552f7358SJed Brown PetscErrorCode DMPlexGetMaxSizes(DM dm, PetscInt *maxConeSize, PetscInt *maxSupportSize) 2362552f7358SJed Brown { 2363552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2364552f7358SJed Brown 2365552f7358SJed Brown PetscFunctionBegin; 2366552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2367552f7358SJed Brown if (maxConeSize) *maxConeSize = mesh->maxConeSize; 2368552f7358SJed Brown if (maxSupportSize) *maxSupportSize = mesh->maxSupportSize; 2369552f7358SJed Brown PetscFunctionReturn(0); 2370552f7358SJed Brown } 2371552f7358SJed Brown 2372552f7358SJed Brown PetscErrorCode DMSetUp_Plex(DM dm) 2373552f7358SJed Brown { 2374552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2375552f7358SJed Brown PetscInt size; 2376552f7358SJed Brown PetscErrorCode ierr; 2377552f7358SJed Brown 2378552f7358SJed Brown PetscFunctionBegin; 2379552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2380552f7358SJed Brown ierr = PetscSectionSetUp(mesh->coneSection);CHKERRQ(ierr); 2381552f7358SJed Brown ierr = PetscSectionGetStorageSize(mesh->coneSection, &size);CHKERRQ(ierr); 23821795a4d1SJed Brown ierr = PetscMalloc1(size, &mesh->cones);CHKERRQ(ierr); 23831795a4d1SJed Brown ierr = PetscCalloc1(size, &mesh->coneOrientations);CHKERRQ(ierr); 2384552f7358SJed Brown if (mesh->maxSupportSize) { 2385552f7358SJed Brown ierr = PetscSectionSetUp(mesh->supportSection);CHKERRQ(ierr); 2386552f7358SJed Brown ierr = PetscSectionGetStorageSize(mesh->supportSection, &size);CHKERRQ(ierr); 23871795a4d1SJed Brown ierr = PetscMalloc1(size, &mesh->supports);CHKERRQ(ierr); 2388552f7358SJed Brown } 2389552f7358SJed Brown PetscFunctionReturn(0); 2390552f7358SJed Brown } 2391552f7358SJed Brown 2392276c5506SMatthew G. Knepley PetscErrorCode DMCreateSubDM_Plex(DM dm, PetscInt numFields, const PetscInt fields[], IS *is, DM *subdm) 2393552f7358SJed Brown { 2394552f7358SJed Brown PetscErrorCode ierr; 2395552f7358SJed Brown 2396552f7358SJed Brown PetscFunctionBegin; 23974d9407bcSMatthew G. Knepley if (subdm) {ierr = DMClone(dm, subdm);CHKERRQ(ierr);} 2398792b654fSMatthew G. Knepley ierr = DMCreateSectionSubDM(dm, numFields, fields, is, subdm);CHKERRQ(ierr); 2399c2939958SSatish Balay if (subdm) {(*subdm)->useNatural = dm->useNatural;} 2400736995cdSBlaise Bourdin if (dm->useNatural && dm->sfMigration) { 2401f94b4a02SBlaise Bourdin PetscSF sfMigrationInv,sfNatural; 2402f94b4a02SBlaise Bourdin PetscSection section, sectionSeq; 2403f94b4a02SBlaise Bourdin 24043dcd263cSBlaise Bourdin (*subdm)->sfMigration = dm->sfMigration; 24053dcd263cSBlaise Bourdin ierr = PetscObjectReference((PetscObject) dm->sfMigration);CHKERRQ(ierr); 2406e87a4003SBarry Smith ierr = DMGetSection((*subdm), §ion);CHKERRQ(ierr);CHKERRQ(ierr); 2407f94b4a02SBlaise Bourdin ierr = PetscSFCreateInverseSF((*subdm)->sfMigration, &sfMigrationInv);CHKERRQ(ierr); 2408f94b4a02SBlaise Bourdin ierr = PetscSectionCreate(PetscObjectComm((PetscObject) (*subdm)), §ionSeq);CHKERRQ(ierr); 2409f94b4a02SBlaise Bourdin ierr = PetscSFDistributeSection(sfMigrationInv, section, NULL, sectionSeq);CHKERRQ(ierr); 2410f94b4a02SBlaise Bourdin 2411f94b4a02SBlaise Bourdin ierr = DMPlexCreateGlobalToNaturalSF(*subdm, sectionSeq, (*subdm)->sfMigration, &sfNatural);CHKERRQ(ierr); 2412c40e9495SBlaise Bourdin (*subdm)->sfNatural = sfNatural; 2413f94b4a02SBlaise Bourdin ierr = PetscSectionDestroy(§ionSeq);CHKERRQ(ierr); 2414f94b4a02SBlaise Bourdin ierr = PetscSFDestroy(&sfMigrationInv);CHKERRQ(ierr); 2415f94b4a02SBlaise Bourdin } 2416552f7358SJed Brown PetscFunctionReturn(0); 2417552f7358SJed Brown } 2418552f7358SJed Brown 24192adcc780SMatthew G. Knepley PetscErrorCode DMCreateSuperDM_Plex(DM dms[], PetscInt len, IS **is, DM *superdm) 24202adcc780SMatthew G. Knepley { 24212adcc780SMatthew G. Knepley PetscErrorCode ierr; 24223dcd263cSBlaise Bourdin PetscInt i = 0; 24232adcc780SMatthew G. Knepley 24242adcc780SMatthew G. Knepley PetscFunctionBegin; 2425435bcee1SStefano Zampini ierr = DMClone(dms[0], superdm);CHKERRQ(ierr); 2426792b654fSMatthew G. Knepley ierr = DMCreateSectionSuperDM(dms, len, is, superdm);CHKERRQ(ierr); 2427c40e9495SBlaise Bourdin (*superdm)->useNatural = PETSC_FALSE; 24283dcd263cSBlaise Bourdin for (i = 0; i < len; i++){ 24293dcd263cSBlaise Bourdin if (dms[i]->useNatural && dms[i]->sfMigration) { 24303dcd263cSBlaise Bourdin PetscSF sfMigrationInv,sfNatural; 24313dcd263cSBlaise Bourdin PetscSection section, sectionSeq; 24323dcd263cSBlaise Bourdin 24333dcd263cSBlaise Bourdin (*superdm)->sfMigration = dms[i]->sfMigration; 24343dcd263cSBlaise Bourdin ierr = PetscObjectReference((PetscObject) dms[i]->sfMigration);CHKERRQ(ierr); 2435c40e9495SBlaise Bourdin (*superdm)->useNatural = PETSC_TRUE; 2436cf0b7c11SKarl Rupp ierr = DMGetSection((*superdm), §ion);CHKERRQ(ierr); 24373dcd263cSBlaise Bourdin ierr = PetscSFCreateInverseSF((*superdm)->sfMigration, &sfMigrationInv);CHKERRQ(ierr); 24383dcd263cSBlaise Bourdin ierr = PetscSectionCreate(PetscObjectComm((PetscObject) (*superdm)), §ionSeq);CHKERRQ(ierr); 24393dcd263cSBlaise Bourdin ierr = PetscSFDistributeSection(sfMigrationInv, section, NULL, sectionSeq);CHKERRQ(ierr); 24403dcd263cSBlaise Bourdin 24413dcd263cSBlaise Bourdin ierr = DMPlexCreateGlobalToNaturalSF(*superdm, sectionSeq, (*superdm)->sfMigration, &sfNatural);CHKERRQ(ierr); 2442c40e9495SBlaise Bourdin (*superdm)->sfNatural = sfNatural; 24433dcd263cSBlaise Bourdin ierr = PetscSectionDestroy(§ionSeq);CHKERRQ(ierr); 24443dcd263cSBlaise Bourdin ierr = PetscSFDestroy(&sfMigrationInv);CHKERRQ(ierr); 24453dcd263cSBlaise Bourdin break; 24463dcd263cSBlaise Bourdin } 24473dcd263cSBlaise Bourdin } 24482adcc780SMatthew G. Knepley PetscFunctionReturn(0); 24492adcc780SMatthew G. Knepley } 24502adcc780SMatthew G. Knepley 2451552f7358SJed Brown /*@ 2452eaf898f9SPatrick Sanan DMPlexSymmetrize - Create support (out-edge) information from cone (in-edge) information 2453552f7358SJed Brown 2454552f7358SJed Brown Not collective 2455552f7358SJed Brown 2456552f7358SJed Brown Input Parameter: 2457552f7358SJed Brown . mesh - The DMPlex 2458552f7358SJed Brown 2459552f7358SJed Brown Output Parameter: 2460552f7358SJed Brown 2461552f7358SJed Brown Note: 2462552f7358SJed Brown This should be called after all calls to DMPlexSetCone() 2463552f7358SJed Brown 2464552f7358SJed Brown Level: beginner 2465552f7358SJed Brown 2466552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetChart(), DMPlexSetConeSize(), DMPlexSetCone() 2467552f7358SJed Brown @*/ 2468552f7358SJed Brown PetscErrorCode DMPlexSymmetrize(DM dm) 2469552f7358SJed Brown { 2470552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2471552f7358SJed Brown PetscInt *offsets; 2472552f7358SJed Brown PetscInt supportSize; 2473552f7358SJed Brown PetscInt pStart, pEnd, p; 2474552f7358SJed Brown PetscErrorCode ierr; 2475552f7358SJed Brown 2476552f7358SJed Brown PetscFunctionBegin; 2477552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 247882f516ccSBarry Smith if (mesh->supports) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Supports were already setup in this DMPlex"); 2479552f7358SJed Brown /* Calculate support sizes */ 2480552f7358SJed Brown ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 2481552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 2482552f7358SJed Brown PetscInt dof, off, c; 2483552f7358SJed Brown 2484552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 2485552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 2486552f7358SJed Brown for (c = off; c < off+dof; ++c) { 2487552f7358SJed Brown ierr = PetscSectionAddDof(mesh->supportSection, mesh->cones[c], 1);CHKERRQ(ierr); 2488552f7358SJed Brown } 2489552f7358SJed Brown } 2490552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 2491552f7358SJed Brown PetscInt dof; 2492552f7358SJed Brown 2493552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, &dof);CHKERRQ(ierr); 24940d644c17SKarl Rupp 2495552f7358SJed Brown mesh->maxSupportSize = PetscMax(mesh->maxSupportSize, dof); 2496552f7358SJed Brown } 2497552f7358SJed Brown ierr = PetscSectionSetUp(mesh->supportSection);CHKERRQ(ierr); 2498552f7358SJed Brown /* Calculate supports */ 2499552f7358SJed Brown ierr = PetscSectionGetStorageSize(mesh->supportSection, &supportSize);CHKERRQ(ierr); 25001795a4d1SJed Brown ierr = PetscMalloc1(supportSize, &mesh->supports);CHKERRQ(ierr); 25011795a4d1SJed Brown ierr = PetscCalloc1(pEnd - pStart, &offsets);CHKERRQ(ierr); 2502552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 2503552f7358SJed Brown PetscInt dof, off, c; 2504552f7358SJed Brown 2505552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 2506552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 2507552f7358SJed Brown for (c = off; c < off+dof; ++c) { 2508552f7358SJed Brown const PetscInt q = mesh->cones[c]; 2509552f7358SJed Brown PetscInt offS; 2510552f7358SJed Brown 2511552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, q, &offS);CHKERRQ(ierr); 25120d644c17SKarl Rupp 2513552f7358SJed Brown mesh->supports[offS+offsets[q]] = p; 2514552f7358SJed Brown ++offsets[q]; 2515552f7358SJed Brown } 2516552f7358SJed Brown } 2517552f7358SJed Brown ierr = PetscFree(offsets);CHKERRQ(ierr); 2518552f7358SJed Brown PetscFunctionReturn(0); 2519552f7358SJed Brown } 2520552f7358SJed Brown 25217d5acc75SStefano Zampini static PetscErrorCode DMPlexCreateDimStratum(DM,DMLabel,DMLabel,PetscInt,PetscInt); 25227d5acc75SStefano Zampini 2523552f7358SJed Brown /*@ 2524eaf898f9SPatrick Sanan DMPlexStratify - The DAG for most topologies is a graded poset (http://en.wikipedia.org/wiki/Graded_poset), and 2525eaf898f9SPatrick Sanan can be illustrated by a Hasse Diagram (a http://en.wikipedia.org/wiki/Hasse_diagram). The strata group all points of the 2526552f7358SJed Brown same grade, and this function calculates the strata. This grade can be seen as the height (or depth) of the point in 2527552f7358SJed Brown the DAG. 2528552f7358SJed Brown 2529bf4602e4SToby Isaac Collective on dm 2530552f7358SJed Brown 2531552f7358SJed Brown Input Parameter: 2532552f7358SJed Brown . mesh - The DMPlex 2533552f7358SJed Brown 2534552f7358SJed Brown Output Parameter: 2535552f7358SJed Brown 2536552f7358SJed Brown Notes: 2537150b719bSJed Brown Concretely, DMPlexStratify() creates a new label named "depth" containing the dimension of each element: 0 for vertices, 2538150b719bSJed Brown 1 for edges, and so on. The depth label can be accessed through DMPlexGetDepthLabel() or DMPlexGetDepthStratum(), or 2539c58f1c22SToby Isaac manually via DMGetLabel(). The height is defined implicitly by height = maxDimension - depth, and can be accessed 2540150b719bSJed Brown via DMPlexGetHeightStratum(). For example, cells have height 0 and faces have height 1. 2541552f7358SJed Brown 2542150b719bSJed Brown DMPlexStratify() should be called after all calls to DMPlexSymmetrize() 2543552f7358SJed Brown 2544552f7358SJed Brown Level: beginner 2545552f7358SJed Brown 2546552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSymmetrize() 2547552f7358SJed Brown @*/ 2548552f7358SJed Brown PetscErrorCode DMPlexStratify(DM dm) 2549552f7358SJed Brown { 2550df0420ecSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 2551aa50250dSMatthew G. Knepley DMLabel label; 2552552f7358SJed Brown PetscInt pStart, pEnd, p; 2553552f7358SJed Brown PetscInt numRoots = 0, numLeaves = 0; 25547d5acc75SStefano Zampini PetscInt cMax, fMax, eMax, vMax; 2555552f7358SJed Brown PetscErrorCode ierr; 2556552f7358SJed Brown 2557552f7358SJed Brown PetscFunctionBegin; 2558552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2559552f7358SJed Brown ierr = PetscLogEventBegin(DMPLEX_Stratify,dm,0,0,0);CHKERRQ(ierr); 2560552f7358SJed Brown /* Calculate depth */ 2561aa50250dSMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 2562c58f1c22SToby Isaac ierr = DMCreateLabel(dm, "depth");CHKERRQ(ierr); 2563aa50250dSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 2564552f7358SJed Brown /* Initialize roots and count leaves */ 2565552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 2566552f7358SJed Brown PetscInt coneSize, supportSize; 2567552f7358SJed Brown 2568552f7358SJed Brown ierr = DMPlexGetConeSize(dm, p, &coneSize);CHKERRQ(ierr); 2569552f7358SJed Brown ierr = DMPlexGetSupportSize(dm, p, &supportSize);CHKERRQ(ierr); 2570552f7358SJed Brown if (!coneSize && supportSize) { 2571552f7358SJed Brown ++numRoots; 2572aa50250dSMatthew G. Knepley ierr = DMLabelSetValue(label, p, 0);CHKERRQ(ierr); 2573552f7358SJed Brown } else if (!supportSize && coneSize) { 2574552f7358SJed Brown ++numLeaves; 2575552f7358SJed Brown } else if (!supportSize && !coneSize) { 2576552f7358SJed Brown /* Isolated points */ 2577aa50250dSMatthew G. Knepley ierr = DMLabelSetValue(label, p, 0);CHKERRQ(ierr); 2578552f7358SJed Brown } 2579552f7358SJed Brown } 2580552f7358SJed Brown if (numRoots + numLeaves == (pEnd - pStart)) { 2581552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 2582552f7358SJed Brown PetscInt coneSize, supportSize; 2583552f7358SJed Brown 2584552f7358SJed Brown ierr = DMPlexGetConeSize(dm, p, &coneSize);CHKERRQ(ierr); 2585552f7358SJed Brown ierr = DMPlexGetSupportSize(dm, p, &supportSize);CHKERRQ(ierr); 2586552f7358SJed Brown if (!supportSize && coneSize) { 2587aa50250dSMatthew G. Knepley ierr = DMLabelSetValue(label, p, 1);CHKERRQ(ierr); 2588552f7358SJed Brown } 2589552f7358SJed Brown } 2590552f7358SJed Brown } else { 259174ef644bSMatthew G. Knepley IS pointIS; 259274ef644bSMatthew G. Knepley PetscInt numPoints = 0, level = 0; 2593552f7358SJed Brown 259474ef644bSMatthew G. Knepley ierr = DMLabelGetStratumIS(label, level, &pointIS);CHKERRQ(ierr); 259574ef644bSMatthew G. Knepley if (pointIS) {ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr);} 259674ef644bSMatthew G. Knepley while (numPoints) { 259774ef644bSMatthew G. Knepley const PetscInt *points; 259874ef644bSMatthew G. Knepley const PetscInt newLevel = level+1; 259974ef644bSMatthew G. Knepley 260074ef644bSMatthew G. Knepley ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 260174ef644bSMatthew G. Knepley for (p = 0; p < numPoints; ++p) { 260274ef644bSMatthew G. Knepley const PetscInt point = points[p]; 260374ef644bSMatthew G. Knepley const PetscInt *support; 260474ef644bSMatthew G. Knepley PetscInt supportSize, s; 260574ef644bSMatthew G. Knepley 260674ef644bSMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, point, &supportSize);CHKERRQ(ierr); 260774ef644bSMatthew G. Knepley ierr = DMPlexGetSupport(dm, point, &support);CHKERRQ(ierr); 260874ef644bSMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 260974ef644bSMatthew G. Knepley ierr = DMLabelSetValue(label, support[s], newLevel);CHKERRQ(ierr); 2610552f7358SJed Brown } 2611552f7358SJed Brown } 26125edfc765SMatthew G. Knepley ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 261374ef644bSMatthew G. Knepley ++level; 261474ef644bSMatthew G. Knepley ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 261574ef644bSMatthew G. Knepley ierr = DMLabelGetStratumIS(label, level, &pointIS);CHKERRQ(ierr); 261674ef644bSMatthew G. Knepley if (pointIS) {ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr);} 261774ef644bSMatthew G. Knepley else {numPoints = 0;} 261874ef644bSMatthew G. Knepley } 261974ef644bSMatthew G. Knepley ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 262074ef644bSMatthew G. Knepley } 2621bf4602e4SToby Isaac { /* just in case there is an empty process */ 2622bf4602e4SToby Isaac PetscInt numValues, maxValues = 0, v; 2623bf4602e4SToby Isaac 2624bf4602e4SToby Isaac ierr = DMLabelGetNumValues(label,&numValues);CHKERRQ(ierr); 26254de306b1SToby Isaac for (v = 0; v < numValues; v++) { 26264de306b1SToby Isaac IS pointIS; 26274de306b1SToby Isaac 26284de306b1SToby Isaac ierr = DMLabelGetStratumIS(label, v, &pointIS);CHKERRQ(ierr); 26294de306b1SToby Isaac if (pointIS) { 26304de306b1SToby Isaac PetscInt min, max, numPoints; 26314de306b1SToby Isaac PetscInt start; 26324de306b1SToby Isaac PetscBool contig; 26334de306b1SToby Isaac 26344de306b1SToby Isaac ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr); 26354de306b1SToby Isaac ierr = ISGetMinMax(pointIS, &min, &max);CHKERRQ(ierr); 26364de306b1SToby Isaac ierr = ISContiguousLocal(pointIS,min,max+1,&start,&contig);CHKERRQ(ierr); 26374de306b1SToby Isaac if (start == 0 && contig) { 26384de306b1SToby Isaac ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 26394de306b1SToby Isaac ierr = ISCreateStride(PETSC_COMM_SELF,numPoints,min,1,&pointIS);CHKERRQ(ierr); 26404de306b1SToby Isaac ierr = DMLabelSetStratumIS(label, v, pointIS);CHKERRQ(ierr); 26414de306b1SToby Isaac } 26424de306b1SToby Isaac } 26434de306b1SToby Isaac ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 26444de306b1SToby Isaac } 26456d1e82d3SBarry Smith ierr = MPI_Allreduce(&numValues,&maxValues,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 2646bf4602e4SToby Isaac for (v = numValues; v < maxValues; v++) { 2647367003a6SStefano Zampini ierr = DMLabelAddStratum(label,v);CHKERRQ(ierr); 2648bf4602e4SToby Isaac } 2649bf4602e4SToby Isaac } 2650d67d17b1SMatthew G. Knepley ierr = PetscObjectStateGet((PetscObject) label, &mesh->depthState);CHKERRQ(ierr); 26517d5acc75SStefano Zampini 26527d5acc75SStefano Zampini ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 26537d5acc75SStefano Zampini if (cMax >= 0 || fMax >= 0 || eMax >= 0 || vMax >= 0) { 26547d5acc75SStefano Zampini DMLabel dimLabel; 26557d5acc75SStefano Zampini PetscInt dim; 26567d5acc75SStefano Zampini 26577d5acc75SStefano Zampini ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 26587d5acc75SStefano Zampini ierr = DMGetLabel(dm, "dim", &dimLabel);CHKERRQ(ierr); 26597d5acc75SStefano Zampini if (!dimLabel) { 26607d5acc75SStefano Zampini ierr = DMCreateLabel(dm, "dim");CHKERRQ(ierr); 26617d5acc75SStefano Zampini ierr = DMGetLabel(dm, "dim", &dimLabel);CHKERRQ(ierr); 26627d5acc75SStefano Zampini } 26637d5acc75SStefano Zampini if (cMax >= 0) {ierr = DMPlexCreateDimStratum(dm, label, dimLabel, dim, cMax);CHKERRQ(ierr);} 26647d5acc75SStefano Zampini if (fMax >= 0) {ierr = DMPlexCreateDimStratum(dm, label, dimLabel, dim - 1, fMax);CHKERRQ(ierr);} 26657d5acc75SStefano Zampini if (eMax >= 0) {ierr = DMPlexCreateDimStratum(dm, label, dimLabel, 1, eMax);CHKERRQ(ierr);} 26667d5acc75SStefano Zampini if (vMax >= 0) {ierr = DMPlexCreateDimStratum(dm, label, dimLabel, 0, vMax);CHKERRQ(ierr);} 26677d5acc75SStefano Zampini } 2668552f7358SJed Brown ierr = PetscLogEventEnd(DMPLEX_Stratify,dm,0,0,0);CHKERRQ(ierr); 2669552f7358SJed Brown PetscFunctionReturn(0); 2670552f7358SJed Brown } 2671552f7358SJed Brown 2672552f7358SJed Brown /*@C 2673552f7358SJed Brown DMPlexGetJoin - Get an array for the join of the set of points 2674552f7358SJed Brown 2675552f7358SJed Brown Not Collective 2676552f7358SJed Brown 2677552f7358SJed Brown Input Parameters: 2678552f7358SJed Brown + dm - The DMPlex object 2679552f7358SJed Brown . numPoints - The number of input points for the join 2680552f7358SJed Brown - points - The input points 2681552f7358SJed Brown 2682552f7358SJed Brown Output Parameters: 2683552f7358SJed Brown + numCoveredPoints - The number of points in the join 2684552f7358SJed Brown - coveredPoints - The points in the join 2685552f7358SJed Brown 2686552f7358SJed Brown Level: intermediate 2687552f7358SJed Brown 2688552f7358SJed Brown Note: Currently, this is restricted to a single level join 2689552f7358SJed Brown 26903813dfbdSMatthew G Knepley Fortran Notes: 26913813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 26923813dfbdSMatthew G Knepley include petsc.h90 in your code. 26933813dfbdSMatthew G Knepley 26943813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 26953813dfbdSMatthew G Knepley 2696552f7358SJed Brown .keywords: mesh 2697552f7358SJed Brown .seealso: DMPlexRestoreJoin(), DMPlexGetMeet() 2698552f7358SJed Brown @*/ 2699552f7358SJed Brown PetscErrorCode DMPlexGetJoin(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 2700552f7358SJed Brown { 2701552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2702552f7358SJed Brown PetscInt *join[2]; 2703552f7358SJed Brown PetscInt joinSize, i = 0; 2704552f7358SJed Brown PetscInt dof, off, p, c, m; 2705552f7358SJed Brown PetscErrorCode ierr; 2706552f7358SJed Brown 2707552f7358SJed Brown PetscFunctionBegin; 2708552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 270948bb261cSVaclav Hapla PetscValidIntPointer(points, 3); 271048bb261cSVaclav Hapla PetscValidIntPointer(numCoveredPoints, 4); 271148bb261cSVaclav Hapla PetscValidPointer(coveredPoints, 5); 271269291d52SBarry Smith ierr = DMGetWorkArray(dm, mesh->maxSupportSize, MPIU_INT, &join[0]);CHKERRQ(ierr); 271369291d52SBarry Smith ierr = DMGetWorkArray(dm, mesh->maxSupportSize, MPIU_INT, &join[1]);CHKERRQ(ierr); 2714552f7358SJed Brown /* Copy in support of first point */ 2715552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, points[0], &dof);CHKERRQ(ierr); 2716552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, points[0], &off);CHKERRQ(ierr); 2717552f7358SJed Brown for (joinSize = 0; joinSize < dof; ++joinSize) { 2718552f7358SJed Brown join[i][joinSize] = mesh->supports[off+joinSize]; 2719552f7358SJed Brown } 2720552f7358SJed Brown /* Check each successive support */ 2721552f7358SJed Brown for (p = 1; p < numPoints; ++p) { 2722552f7358SJed Brown PetscInt newJoinSize = 0; 2723552f7358SJed Brown 2724552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, points[p], &dof);CHKERRQ(ierr); 2725552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, points[p], &off);CHKERRQ(ierr); 2726552f7358SJed Brown for (c = 0; c < dof; ++c) { 2727552f7358SJed Brown const PetscInt point = mesh->supports[off+c]; 2728552f7358SJed Brown 2729552f7358SJed Brown for (m = 0; m < joinSize; ++m) { 2730552f7358SJed Brown if (point == join[i][m]) { 2731552f7358SJed Brown join[1-i][newJoinSize++] = point; 2732552f7358SJed Brown break; 2733552f7358SJed Brown } 2734552f7358SJed Brown } 2735552f7358SJed Brown } 2736552f7358SJed Brown joinSize = newJoinSize; 2737552f7358SJed Brown i = 1-i; 2738552f7358SJed Brown } 2739552f7358SJed Brown *numCoveredPoints = joinSize; 2740552f7358SJed Brown *coveredPoints = join[i]; 274169291d52SBarry Smith ierr = DMRestoreWorkArray(dm, mesh->maxSupportSize, MPIU_INT, &join[1-i]);CHKERRQ(ierr); 2742552f7358SJed Brown PetscFunctionReturn(0); 2743552f7358SJed Brown } 2744552f7358SJed Brown 2745552f7358SJed Brown /*@C 2746552f7358SJed Brown DMPlexRestoreJoin - Restore an array for the join of the set of points 2747552f7358SJed Brown 2748552f7358SJed Brown Not Collective 2749552f7358SJed Brown 2750552f7358SJed Brown Input Parameters: 2751552f7358SJed Brown + dm - The DMPlex object 2752552f7358SJed Brown . numPoints - The number of input points for the join 2753552f7358SJed Brown - points - The input points 2754552f7358SJed Brown 2755552f7358SJed Brown Output Parameters: 2756552f7358SJed Brown + numCoveredPoints - The number of points in the join 2757552f7358SJed Brown - coveredPoints - The points in the join 2758552f7358SJed Brown 27593813dfbdSMatthew G Knepley Fortran Notes: 27603813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 27613813dfbdSMatthew G Knepley include petsc.h90 in your code. 27623813dfbdSMatthew G Knepley 27633813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 27643813dfbdSMatthew G Knepley 2765552f7358SJed Brown Level: intermediate 2766552f7358SJed Brown 2767552f7358SJed Brown .keywords: mesh 2768552f7358SJed Brown .seealso: DMPlexGetJoin(), DMPlexGetFullJoin(), DMPlexGetMeet() 2769552f7358SJed Brown @*/ 2770552f7358SJed Brown PetscErrorCode DMPlexRestoreJoin(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 2771552f7358SJed Brown { 2772552f7358SJed Brown PetscErrorCode ierr; 2773552f7358SJed Brown 2774552f7358SJed Brown PetscFunctionBegin; 2775552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2776d7902bd2SMatthew G. Knepley if (points) PetscValidIntPointer(points,3); 2777d7902bd2SMatthew G. Knepley if (numCoveredPoints) PetscValidIntPointer(numCoveredPoints,4); 2778d7902bd2SMatthew G. Knepley PetscValidPointer(coveredPoints, 5); 277969291d52SBarry Smith ierr = DMRestoreWorkArray(dm, 0, MPIU_INT, (void*) coveredPoints);CHKERRQ(ierr); 2780d7902bd2SMatthew G. Knepley if (numCoveredPoints) *numCoveredPoints = 0; 2781552f7358SJed Brown PetscFunctionReturn(0); 2782552f7358SJed Brown } 2783552f7358SJed Brown 2784552f7358SJed Brown /*@C 2785552f7358SJed Brown DMPlexGetFullJoin - Get an array for the join of the set of points 2786552f7358SJed Brown 2787552f7358SJed Brown Not Collective 2788552f7358SJed Brown 2789552f7358SJed Brown Input Parameters: 2790552f7358SJed Brown + dm - The DMPlex object 2791552f7358SJed Brown . numPoints - The number of input points for the join 2792552f7358SJed Brown - points - The input points 2793552f7358SJed Brown 2794552f7358SJed Brown Output Parameters: 2795552f7358SJed Brown + numCoveredPoints - The number of points in the join 2796552f7358SJed Brown - coveredPoints - The points in the join 2797552f7358SJed Brown 27983813dfbdSMatthew G Knepley Fortran Notes: 27993813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 28003813dfbdSMatthew G Knepley include petsc.h90 in your code. 28013813dfbdSMatthew G Knepley 28023813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 28033813dfbdSMatthew G Knepley 2804552f7358SJed Brown Level: intermediate 2805552f7358SJed Brown 2806552f7358SJed Brown .keywords: mesh 2807552f7358SJed Brown .seealso: DMPlexGetJoin(), DMPlexRestoreJoin(), DMPlexGetMeet() 2808552f7358SJed Brown @*/ 2809552f7358SJed Brown PetscErrorCode DMPlexGetFullJoin(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 2810552f7358SJed Brown { 2811552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2812552f7358SJed Brown PetscInt *offsets, **closures; 2813552f7358SJed Brown PetscInt *join[2]; 2814552f7358SJed Brown PetscInt depth = 0, maxSize, joinSize = 0, i = 0; 281524c766afSToby Isaac PetscInt p, d, c, m, ms; 2816552f7358SJed Brown PetscErrorCode ierr; 2817552f7358SJed Brown 2818552f7358SJed Brown PetscFunctionBegin; 2819552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 282048bb261cSVaclav Hapla PetscValidIntPointer(points, 3); 282148bb261cSVaclav Hapla PetscValidIntPointer(numCoveredPoints, 4); 282248bb261cSVaclav Hapla PetscValidPointer(coveredPoints, 5); 2823552f7358SJed Brown 2824552f7358SJed Brown ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 28251795a4d1SJed Brown ierr = PetscCalloc1(numPoints, &closures);CHKERRQ(ierr); 282669291d52SBarry Smith ierr = DMGetWorkArray(dm, numPoints*(depth+2), MPIU_INT, &offsets);CHKERRQ(ierr); 282724c766afSToby Isaac ms = mesh->maxSupportSize; 282824c766afSToby Isaac maxSize = (ms > 1) ? ((PetscPowInt(ms,depth+1)-1)/(ms-1)) : depth + 1; 282969291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &join[0]);CHKERRQ(ierr); 283069291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &join[1]);CHKERRQ(ierr); 2831552f7358SJed Brown 2832552f7358SJed Brown for (p = 0; p < numPoints; ++p) { 2833552f7358SJed Brown PetscInt closureSize; 2834552f7358SJed Brown 2835552f7358SJed Brown ierr = DMPlexGetTransitiveClosure(dm, points[p], PETSC_FALSE, &closureSize, &closures[p]);CHKERRQ(ierr); 28360d644c17SKarl Rupp 2837552f7358SJed Brown offsets[p*(depth+2)+0] = 0; 2838552f7358SJed Brown for (d = 0; d < depth+1; ++d) { 2839552f7358SJed Brown PetscInt pStart, pEnd, i; 2840552f7358SJed Brown 2841552f7358SJed Brown ierr = DMPlexGetDepthStratum(dm, d, &pStart, &pEnd);CHKERRQ(ierr); 2842552f7358SJed Brown for (i = offsets[p*(depth+2)+d]; i < closureSize; ++i) { 2843552f7358SJed Brown if ((pStart > closures[p][i*2]) || (pEnd <= closures[p][i*2])) { 2844552f7358SJed Brown offsets[p*(depth+2)+d+1] = i; 2845552f7358SJed Brown break; 2846552f7358SJed Brown } 2847552f7358SJed Brown } 2848552f7358SJed Brown if (i == closureSize) offsets[p*(depth+2)+d+1] = i; 2849552f7358SJed Brown } 285082f516ccSBarry 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); 2851552f7358SJed Brown } 2852552f7358SJed Brown for (d = 0; d < depth+1; ++d) { 2853552f7358SJed Brown PetscInt dof; 2854552f7358SJed Brown 2855552f7358SJed Brown /* Copy in support of first point */ 2856552f7358SJed Brown dof = offsets[d+1] - offsets[d]; 2857552f7358SJed Brown for (joinSize = 0; joinSize < dof; ++joinSize) { 2858552f7358SJed Brown join[i][joinSize] = closures[0][(offsets[d]+joinSize)*2]; 2859552f7358SJed Brown } 2860552f7358SJed Brown /* Check each successive cone */ 2861552f7358SJed Brown for (p = 1; p < numPoints && joinSize; ++p) { 2862552f7358SJed Brown PetscInt newJoinSize = 0; 2863552f7358SJed Brown 2864552f7358SJed Brown dof = offsets[p*(depth+2)+d+1] - offsets[p*(depth+2)+d]; 2865552f7358SJed Brown for (c = 0; c < dof; ++c) { 2866552f7358SJed Brown const PetscInt point = closures[p][(offsets[p*(depth+2)+d]+c)*2]; 2867552f7358SJed Brown 2868552f7358SJed Brown for (m = 0; m < joinSize; ++m) { 2869552f7358SJed Brown if (point == join[i][m]) { 2870552f7358SJed Brown join[1-i][newJoinSize++] = point; 2871552f7358SJed Brown break; 2872552f7358SJed Brown } 2873552f7358SJed Brown } 2874552f7358SJed Brown } 2875552f7358SJed Brown joinSize = newJoinSize; 2876552f7358SJed Brown i = 1-i; 2877552f7358SJed Brown } 2878552f7358SJed Brown if (joinSize) break; 2879552f7358SJed Brown } 2880552f7358SJed Brown *numCoveredPoints = joinSize; 2881552f7358SJed Brown *coveredPoints = join[i]; 2882552f7358SJed Brown for (p = 0; p < numPoints; ++p) { 28830298fd71SBarry Smith ierr = DMPlexRestoreTransitiveClosure(dm, points[p], PETSC_FALSE, NULL, &closures[p]);CHKERRQ(ierr); 2884552f7358SJed Brown } 2885552f7358SJed Brown ierr = PetscFree(closures);CHKERRQ(ierr); 288669291d52SBarry Smith ierr = DMRestoreWorkArray(dm, numPoints*(depth+2), MPIU_INT, &offsets);CHKERRQ(ierr); 288769291d52SBarry Smith ierr = DMRestoreWorkArray(dm, mesh->maxSupportSize, MPIU_INT, &join[1-i]);CHKERRQ(ierr); 2888552f7358SJed Brown PetscFunctionReturn(0); 2889552f7358SJed Brown } 2890552f7358SJed Brown 2891552f7358SJed Brown /*@C 2892552f7358SJed Brown DMPlexGetMeet - Get an array for the meet of the set of points 2893552f7358SJed Brown 2894552f7358SJed Brown Not Collective 2895552f7358SJed Brown 2896552f7358SJed Brown Input Parameters: 2897552f7358SJed Brown + dm - The DMPlex object 2898552f7358SJed Brown . numPoints - The number of input points for the meet 2899552f7358SJed Brown - points - The input points 2900552f7358SJed Brown 2901552f7358SJed Brown Output Parameters: 2902552f7358SJed Brown + numCoveredPoints - The number of points in the meet 2903552f7358SJed Brown - coveredPoints - The points in the meet 2904552f7358SJed Brown 2905552f7358SJed Brown Level: intermediate 2906552f7358SJed Brown 2907552f7358SJed Brown Note: Currently, this is restricted to a single level meet 2908552f7358SJed Brown 29093813dfbdSMatthew G Knepley Fortran Notes: 29103813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 29113813dfbdSMatthew G Knepley include petsc.h90 in your code. 29123813dfbdSMatthew G Knepley 29133813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 29143813dfbdSMatthew G Knepley 2915552f7358SJed Brown .keywords: mesh 2916552f7358SJed Brown .seealso: DMPlexRestoreMeet(), DMPlexGetJoin() 2917552f7358SJed Brown @*/ 2918552f7358SJed Brown PetscErrorCode DMPlexGetMeet(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveringPoints, const PetscInt **coveringPoints) 2919552f7358SJed Brown { 2920552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2921552f7358SJed Brown PetscInt *meet[2]; 2922552f7358SJed Brown PetscInt meetSize, i = 0; 2923552f7358SJed Brown PetscInt dof, off, p, c, m; 2924552f7358SJed Brown PetscErrorCode ierr; 2925552f7358SJed Brown 2926552f7358SJed Brown PetscFunctionBegin; 2927552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2928552f7358SJed Brown PetscValidPointer(points, 2); 2929552f7358SJed Brown PetscValidPointer(numCoveringPoints, 3); 2930552f7358SJed Brown PetscValidPointer(coveringPoints, 4); 293169291d52SBarry Smith ierr = DMGetWorkArray(dm, mesh->maxConeSize, MPIU_INT, &meet[0]);CHKERRQ(ierr); 293269291d52SBarry Smith ierr = DMGetWorkArray(dm, mesh->maxConeSize, MPIU_INT, &meet[1]);CHKERRQ(ierr); 2933552f7358SJed Brown /* Copy in cone of first point */ 2934552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, points[0], &dof);CHKERRQ(ierr); 2935552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, points[0], &off);CHKERRQ(ierr); 2936552f7358SJed Brown for (meetSize = 0; meetSize < dof; ++meetSize) { 2937552f7358SJed Brown meet[i][meetSize] = mesh->cones[off+meetSize]; 2938552f7358SJed Brown } 2939552f7358SJed Brown /* Check each successive cone */ 2940552f7358SJed Brown for (p = 1; p < numPoints; ++p) { 2941552f7358SJed Brown PetscInt newMeetSize = 0; 2942552f7358SJed Brown 2943552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, points[p], &dof);CHKERRQ(ierr); 2944552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, points[p], &off);CHKERRQ(ierr); 2945552f7358SJed Brown for (c = 0; c < dof; ++c) { 2946552f7358SJed Brown const PetscInt point = mesh->cones[off+c]; 2947552f7358SJed Brown 2948552f7358SJed Brown for (m = 0; m < meetSize; ++m) { 2949552f7358SJed Brown if (point == meet[i][m]) { 2950552f7358SJed Brown meet[1-i][newMeetSize++] = point; 2951552f7358SJed Brown break; 2952552f7358SJed Brown } 2953552f7358SJed Brown } 2954552f7358SJed Brown } 2955552f7358SJed Brown meetSize = newMeetSize; 2956552f7358SJed Brown i = 1-i; 2957552f7358SJed Brown } 2958552f7358SJed Brown *numCoveringPoints = meetSize; 2959552f7358SJed Brown *coveringPoints = meet[i]; 296069291d52SBarry Smith ierr = DMRestoreWorkArray(dm, mesh->maxConeSize, MPIU_INT, &meet[1-i]);CHKERRQ(ierr); 2961552f7358SJed Brown PetscFunctionReturn(0); 2962552f7358SJed Brown } 2963552f7358SJed Brown 2964552f7358SJed Brown /*@C 2965552f7358SJed Brown DMPlexRestoreMeet - Restore an array for the meet of the set of points 2966552f7358SJed Brown 2967552f7358SJed Brown Not Collective 2968552f7358SJed Brown 2969552f7358SJed Brown Input Parameters: 2970552f7358SJed Brown + dm - The DMPlex object 2971552f7358SJed Brown . numPoints - The number of input points for the meet 2972552f7358SJed Brown - points - The input points 2973552f7358SJed Brown 2974552f7358SJed Brown Output Parameters: 2975552f7358SJed Brown + numCoveredPoints - The number of points in the meet 2976552f7358SJed Brown - coveredPoints - The points in the meet 2977552f7358SJed Brown 2978552f7358SJed Brown Level: intermediate 2979552f7358SJed Brown 29803813dfbdSMatthew G Knepley Fortran Notes: 29813813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 29823813dfbdSMatthew G Knepley include petsc.h90 in your code. 29833813dfbdSMatthew G Knepley 29843813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 29853813dfbdSMatthew G Knepley 2986552f7358SJed Brown .keywords: mesh 2987552f7358SJed Brown .seealso: DMPlexGetMeet(), DMPlexGetFullMeet(), DMPlexGetJoin() 2988552f7358SJed Brown @*/ 2989552f7358SJed Brown PetscErrorCode DMPlexRestoreMeet(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 2990552f7358SJed Brown { 2991552f7358SJed Brown PetscErrorCode ierr; 2992552f7358SJed Brown 2993552f7358SJed Brown PetscFunctionBegin; 2994552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2995d7902bd2SMatthew G. Knepley if (points) PetscValidIntPointer(points,3); 2996d7902bd2SMatthew G. Knepley if (numCoveredPoints) PetscValidIntPointer(numCoveredPoints,4); 2997d7902bd2SMatthew G. Knepley PetscValidPointer(coveredPoints,5); 299869291d52SBarry Smith ierr = DMRestoreWorkArray(dm, 0, MPIU_INT, (void*) coveredPoints);CHKERRQ(ierr); 2999d7902bd2SMatthew G. Knepley if (numCoveredPoints) *numCoveredPoints = 0; 3000552f7358SJed Brown PetscFunctionReturn(0); 3001552f7358SJed Brown } 3002552f7358SJed Brown 3003552f7358SJed Brown /*@C 3004552f7358SJed Brown DMPlexGetFullMeet - Get an array for the meet of the set of points 3005552f7358SJed Brown 3006552f7358SJed Brown Not Collective 3007552f7358SJed Brown 3008552f7358SJed Brown Input Parameters: 3009552f7358SJed Brown + dm - The DMPlex object 3010552f7358SJed Brown . numPoints - The number of input points for the meet 3011552f7358SJed Brown - points - The input points 3012552f7358SJed Brown 3013552f7358SJed Brown Output Parameters: 3014552f7358SJed Brown + numCoveredPoints - The number of points in the meet 3015552f7358SJed Brown - coveredPoints - The points in the meet 3016552f7358SJed Brown 3017552f7358SJed Brown Level: intermediate 3018552f7358SJed Brown 30193813dfbdSMatthew G Knepley Fortran Notes: 30203813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 30213813dfbdSMatthew G Knepley include petsc.h90 in your code. 30223813dfbdSMatthew G Knepley 30233813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 30243813dfbdSMatthew G Knepley 3025552f7358SJed Brown .keywords: mesh 3026552f7358SJed Brown .seealso: DMPlexGetMeet(), DMPlexRestoreMeet(), DMPlexGetJoin() 3027552f7358SJed Brown @*/ 3028552f7358SJed Brown PetscErrorCode DMPlexGetFullMeet(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 3029552f7358SJed Brown { 3030552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3031552f7358SJed Brown PetscInt *offsets, **closures; 3032552f7358SJed Brown PetscInt *meet[2]; 3033552f7358SJed Brown PetscInt height = 0, maxSize, meetSize = 0, i = 0; 303424c766afSToby Isaac PetscInt p, h, c, m, mc; 3035552f7358SJed Brown PetscErrorCode ierr; 3036552f7358SJed Brown 3037552f7358SJed Brown PetscFunctionBegin; 3038552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3039552f7358SJed Brown PetscValidPointer(points, 2); 3040552f7358SJed Brown PetscValidPointer(numCoveredPoints, 3); 3041552f7358SJed Brown PetscValidPointer(coveredPoints, 4); 3042552f7358SJed Brown 3043552f7358SJed Brown ierr = DMPlexGetDepth(dm, &height);CHKERRQ(ierr); 3044785e854fSJed Brown ierr = PetscMalloc1(numPoints, &closures);CHKERRQ(ierr); 304569291d52SBarry Smith ierr = DMGetWorkArray(dm, numPoints*(height+2), MPIU_INT, &offsets);CHKERRQ(ierr); 304624c766afSToby Isaac mc = mesh->maxConeSize; 304724c766afSToby Isaac maxSize = (mc > 1) ? ((PetscPowInt(mc,height+1)-1)/(mc-1)) : height + 1; 304869291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &meet[0]);CHKERRQ(ierr); 304969291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &meet[1]);CHKERRQ(ierr); 3050552f7358SJed Brown 3051552f7358SJed Brown for (p = 0; p < numPoints; ++p) { 3052552f7358SJed Brown PetscInt closureSize; 3053552f7358SJed Brown 3054552f7358SJed Brown ierr = DMPlexGetTransitiveClosure(dm, points[p], PETSC_TRUE, &closureSize, &closures[p]);CHKERRQ(ierr); 30550d644c17SKarl Rupp 3056552f7358SJed Brown offsets[p*(height+2)+0] = 0; 3057552f7358SJed Brown for (h = 0; h < height+1; ++h) { 3058552f7358SJed Brown PetscInt pStart, pEnd, i; 3059552f7358SJed Brown 3060552f7358SJed Brown ierr = DMPlexGetHeightStratum(dm, h, &pStart, &pEnd);CHKERRQ(ierr); 3061552f7358SJed Brown for (i = offsets[p*(height+2)+h]; i < closureSize; ++i) { 3062552f7358SJed Brown if ((pStart > closures[p][i*2]) || (pEnd <= closures[p][i*2])) { 3063552f7358SJed Brown offsets[p*(height+2)+h+1] = i; 3064552f7358SJed Brown break; 3065552f7358SJed Brown } 3066552f7358SJed Brown } 3067552f7358SJed Brown if (i == closureSize) offsets[p*(height+2)+h+1] = i; 3068552f7358SJed Brown } 306982f516ccSBarry 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); 3070552f7358SJed Brown } 3071552f7358SJed Brown for (h = 0; h < height+1; ++h) { 3072552f7358SJed Brown PetscInt dof; 3073552f7358SJed Brown 3074552f7358SJed Brown /* Copy in cone of first point */ 3075552f7358SJed Brown dof = offsets[h+1] - offsets[h]; 3076552f7358SJed Brown for (meetSize = 0; meetSize < dof; ++meetSize) { 3077552f7358SJed Brown meet[i][meetSize] = closures[0][(offsets[h]+meetSize)*2]; 3078552f7358SJed Brown } 3079552f7358SJed Brown /* Check each successive cone */ 3080552f7358SJed Brown for (p = 1; p < numPoints && meetSize; ++p) { 3081552f7358SJed Brown PetscInt newMeetSize = 0; 3082552f7358SJed Brown 3083552f7358SJed Brown dof = offsets[p*(height+2)+h+1] - offsets[p*(height+2)+h]; 3084552f7358SJed Brown for (c = 0; c < dof; ++c) { 3085552f7358SJed Brown const PetscInt point = closures[p][(offsets[p*(height+2)+h]+c)*2]; 3086552f7358SJed Brown 3087552f7358SJed Brown for (m = 0; m < meetSize; ++m) { 3088552f7358SJed Brown if (point == meet[i][m]) { 3089552f7358SJed Brown meet[1-i][newMeetSize++] = point; 3090552f7358SJed Brown break; 3091552f7358SJed Brown } 3092552f7358SJed Brown } 3093552f7358SJed Brown } 3094552f7358SJed Brown meetSize = newMeetSize; 3095552f7358SJed Brown i = 1-i; 3096552f7358SJed Brown } 3097552f7358SJed Brown if (meetSize) break; 3098552f7358SJed Brown } 3099552f7358SJed Brown *numCoveredPoints = meetSize; 3100552f7358SJed Brown *coveredPoints = meet[i]; 3101552f7358SJed Brown for (p = 0; p < numPoints; ++p) { 31020298fd71SBarry Smith ierr = DMPlexRestoreTransitiveClosure(dm, points[p], PETSC_TRUE, NULL, &closures[p]);CHKERRQ(ierr); 3103552f7358SJed Brown } 3104552f7358SJed Brown ierr = PetscFree(closures);CHKERRQ(ierr); 310569291d52SBarry Smith ierr = DMRestoreWorkArray(dm, numPoints*(height+2), MPIU_INT, &offsets);CHKERRQ(ierr); 310669291d52SBarry Smith ierr = DMRestoreWorkArray(dm, mesh->maxConeSize, MPIU_INT, &meet[1-i]);CHKERRQ(ierr); 3107552f7358SJed Brown PetscFunctionReturn(0); 3108552f7358SJed Brown } 3109552f7358SJed Brown 31104e3744c5SMatthew G. Knepley /*@C 31114e3744c5SMatthew G. Knepley DMPlexEqual - Determine if two DMs have the same topology 31124e3744c5SMatthew G. Knepley 31134e3744c5SMatthew G. Knepley Not Collective 31144e3744c5SMatthew G. Knepley 31154e3744c5SMatthew G. Knepley Input Parameters: 31164e3744c5SMatthew G. Knepley + dmA - A DMPlex object 31174e3744c5SMatthew G. Knepley - dmB - A DMPlex object 31184e3744c5SMatthew G. Knepley 31194e3744c5SMatthew G. Knepley Output Parameters: 31204e3744c5SMatthew G. Knepley . equal - PETSC_TRUE if the topologies are identical 31214e3744c5SMatthew G. Knepley 31224e3744c5SMatthew G. Knepley Level: intermediate 31234e3744c5SMatthew G. Knepley 31244e3744c5SMatthew G. Knepley Notes: 31254e3744c5SMatthew G. Knepley We are not solving graph isomorphism, so we do not permutation. 31264e3744c5SMatthew G. Knepley 31274e3744c5SMatthew G. Knepley .keywords: mesh 31284e3744c5SMatthew G. Knepley .seealso: DMPlexGetCone() 31294e3744c5SMatthew G. Knepley @*/ 31304e3744c5SMatthew G. Knepley PetscErrorCode DMPlexEqual(DM dmA, DM dmB, PetscBool *equal) 31314e3744c5SMatthew G. Knepley { 31324e3744c5SMatthew G. Knepley PetscInt depth, depthB, pStart, pEnd, pStartB, pEndB, p; 31334e3744c5SMatthew G. Knepley PetscErrorCode ierr; 31344e3744c5SMatthew G. Knepley 31354e3744c5SMatthew G. Knepley PetscFunctionBegin; 31364e3744c5SMatthew G. Knepley PetscValidHeaderSpecific(dmA, DM_CLASSID, 1); 31374e3744c5SMatthew G. Knepley PetscValidHeaderSpecific(dmB, DM_CLASSID, 2); 31384e3744c5SMatthew G. Knepley PetscValidPointer(equal, 3); 31394e3744c5SMatthew G. Knepley 31404e3744c5SMatthew G. Knepley *equal = PETSC_FALSE; 31414e3744c5SMatthew G. Knepley ierr = DMPlexGetDepth(dmA, &depth);CHKERRQ(ierr); 31424e3744c5SMatthew G. Knepley ierr = DMPlexGetDepth(dmB, &depthB);CHKERRQ(ierr); 31434e3744c5SMatthew G. Knepley if (depth != depthB) PetscFunctionReturn(0); 31444e3744c5SMatthew G. Knepley ierr = DMPlexGetChart(dmA, &pStart, &pEnd);CHKERRQ(ierr); 31454e3744c5SMatthew G. Knepley ierr = DMPlexGetChart(dmB, &pStartB, &pEndB);CHKERRQ(ierr); 31464e3744c5SMatthew G. Knepley if ((pStart != pStartB) || (pEnd != pEndB)) PetscFunctionReturn(0); 31474e3744c5SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 31484e3744c5SMatthew G. Knepley const PetscInt *cone, *coneB, *ornt, *orntB, *support, *supportB; 31494e3744c5SMatthew G. Knepley PetscInt coneSize, coneSizeB, c, supportSize, supportSizeB, s; 31504e3744c5SMatthew G. Knepley 31514e3744c5SMatthew G. Knepley ierr = DMPlexGetConeSize(dmA, p, &coneSize);CHKERRQ(ierr); 31524e3744c5SMatthew G. Knepley ierr = DMPlexGetCone(dmA, p, &cone);CHKERRQ(ierr); 31534e3744c5SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dmA, p, &ornt);CHKERRQ(ierr); 31544e3744c5SMatthew G. Knepley ierr = DMPlexGetConeSize(dmB, p, &coneSizeB);CHKERRQ(ierr); 31554e3744c5SMatthew G. Knepley ierr = DMPlexGetCone(dmB, p, &coneB);CHKERRQ(ierr); 31564e3744c5SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dmB, p, &orntB);CHKERRQ(ierr); 31574e3744c5SMatthew G. Knepley if (coneSize != coneSizeB) PetscFunctionReturn(0); 31584e3744c5SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 31594e3744c5SMatthew G. Knepley if (cone[c] != coneB[c]) PetscFunctionReturn(0); 31604e3744c5SMatthew G. Knepley if (ornt[c] != orntB[c]) PetscFunctionReturn(0); 31614e3744c5SMatthew G. Knepley } 31624e3744c5SMatthew G. Knepley ierr = DMPlexGetSupportSize(dmA, p, &supportSize);CHKERRQ(ierr); 31634e3744c5SMatthew G. Knepley ierr = DMPlexGetSupport(dmA, p, &support);CHKERRQ(ierr); 31644e3744c5SMatthew G. Knepley ierr = DMPlexGetSupportSize(dmB, p, &supportSizeB);CHKERRQ(ierr); 31654e3744c5SMatthew G. Knepley ierr = DMPlexGetSupport(dmB, p, &supportB);CHKERRQ(ierr); 31664e3744c5SMatthew G. Knepley if (supportSize != supportSizeB) PetscFunctionReturn(0); 31674e3744c5SMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 31684e3744c5SMatthew G. Knepley if (support[s] != supportB[s]) PetscFunctionReturn(0); 31694e3744c5SMatthew G. Knepley } 31704e3744c5SMatthew G. Knepley } 31714e3744c5SMatthew G. Knepley *equal = PETSC_TRUE; 31724e3744c5SMatthew G. Knepley PetscFunctionReturn(0); 31734e3744c5SMatthew G. Knepley } 31744e3744c5SMatthew G. Knepley 31757cd05799SMatthew G. Knepley /*@C 31767cd05799SMatthew G. Knepley DMPlexGetNumFaceVertices - Returns the number of vertices on a face 31777cd05799SMatthew G. Knepley 31787cd05799SMatthew G. Knepley Not Collective 31797cd05799SMatthew G. Knepley 31807cd05799SMatthew G. Knepley Input Parameters: 31817cd05799SMatthew G. Knepley + dm - The DMPlex 31827cd05799SMatthew G. Knepley . cellDim - The cell dimension 31837cd05799SMatthew G. Knepley - numCorners - The number of vertices on a cell 31847cd05799SMatthew G. Knepley 31857cd05799SMatthew G. Knepley Output Parameters: 31867cd05799SMatthew G. Knepley . numFaceVertices - The number of vertices on a face 31877cd05799SMatthew G. Knepley 31887cd05799SMatthew G. Knepley Level: developer 31897cd05799SMatthew G. Knepley 31907cd05799SMatthew G. Knepley Notes: 31917cd05799SMatthew G. Knepley Of course this can only work for a restricted set of symmetric shapes 31927cd05799SMatthew G. Knepley 31937cd05799SMatthew G. Knepley .seealso: DMPlexGetCone() 31947cd05799SMatthew G. Knepley @*/ 319518ad9376SMatthew G. Knepley PetscErrorCode DMPlexGetNumFaceVertices(DM dm, PetscInt cellDim, PetscInt numCorners, PetscInt *numFaceVertices) 3196a6dfd86eSKarl Rupp { 319782f516ccSBarry Smith MPI_Comm comm; 3198552f7358SJed Brown PetscErrorCode ierr; 3199552f7358SJed Brown 3200552f7358SJed Brown PetscFunctionBegin; 320182f516ccSBarry Smith ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 3202552f7358SJed Brown PetscValidPointer(numFaceVertices,3); 3203552f7358SJed Brown switch (cellDim) { 3204552f7358SJed Brown case 0: 3205552f7358SJed Brown *numFaceVertices = 0; 3206552f7358SJed Brown break; 3207552f7358SJed Brown case 1: 3208552f7358SJed Brown *numFaceVertices = 1; 3209552f7358SJed Brown break; 3210552f7358SJed Brown case 2: 3211552f7358SJed Brown switch (numCorners) { 321219436ca2SJed Brown case 3: /* triangle */ 321319436ca2SJed Brown *numFaceVertices = 2; /* Edge has 2 vertices */ 3214552f7358SJed Brown break; 321519436ca2SJed Brown case 4: /* quadrilateral */ 321619436ca2SJed Brown *numFaceVertices = 2; /* Edge has 2 vertices */ 3217552f7358SJed Brown break; 321819436ca2SJed Brown case 6: /* quadratic triangle, tri and quad cohesive Lagrange cells */ 321919436ca2SJed Brown *numFaceVertices = 3; /* Edge has 3 vertices */ 3220552f7358SJed Brown break; 322119436ca2SJed Brown case 9: /* quadratic quadrilateral, quadratic quad cohesive Lagrange cells */ 322219436ca2SJed Brown *numFaceVertices = 3; /* Edge has 3 vertices */ 3223552f7358SJed Brown break; 3224552f7358SJed Brown default: 3225f347f43bSBarry Smith SETERRQ2(comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid number of face corners %D for dimension %D", numCorners, cellDim); 3226552f7358SJed Brown } 3227552f7358SJed Brown break; 3228552f7358SJed Brown case 3: 3229552f7358SJed Brown switch (numCorners) { 323019436ca2SJed Brown case 4: /* tetradehdron */ 323119436ca2SJed Brown *numFaceVertices = 3; /* Face has 3 vertices */ 3232552f7358SJed Brown break; 323319436ca2SJed Brown case 6: /* tet cohesive cells */ 323419436ca2SJed Brown *numFaceVertices = 4; /* Face has 4 vertices */ 3235552f7358SJed Brown break; 323619436ca2SJed Brown case 8: /* hexahedron */ 323719436ca2SJed Brown *numFaceVertices = 4; /* Face has 4 vertices */ 3238552f7358SJed Brown break; 323919436ca2SJed Brown case 9: /* tet cohesive Lagrange cells */ 324019436ca2SJed Brown *numFaceVertices = 6; /* Face has 6 vertices */ 3241552f7358SJed Brown break; 324219436ca2SJed Brown case 10: /* quadratic tetrahedron */ 324319436ca2SJed Brown *numFaceVertices = 6; /* Face has 6 vertices */ 3244552f7358SJed Brown break; 324519436ca2SJed Brown case 12: /* hex cohesive Lagrange cells */ 324619436ca2SJed Brown *numFaceVertices = 6; /* Face has 6 vertices */ 3247552f7358SJed Brown break; 324819436ca2SJed Brown case 18: /* quadratic tet cohesive Lagrange cells */ 324919436ca2SJed Brown *numFaceVertices = 6; /* Face has 6 vertices */ 3250552f7358SJed Brown break; 325119436ca2SJed Brown case 27: /* quadratic hexahedron, quadratic hex cohesive Lagrange cells */ 325219436ca2SJed Brown *numFaceVertices = 9; /* Face has 9 vertices */ 3253552f7358SJed Brown break; 3254552f7358SJed Brown default: 3255f347f43bSBarry Smith SETERRQ2(comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid number of face corners %D for dimension %D", numCorners, cellDim); 3256552f7358SJed Brown } 3257552f7358SJed Brown break; 3258552f7358SJed Brown default: 3259f347f43bSBarry Smith SETERRQ1(comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid cell dimension %D", cellDim); 3260552f7358SJed Brown } 3261552f7358SJed Brown PetscFunctionReturn(0); 3262552f7358SJed Brown } 3263552f7358SJed Brown 3264552f7358SJed Brown /*@ 3265aa50250dSMatthew G. Knepley DMPlexGetDepthLabel - Get the DMLabel recording the depth of each point 3266552f7358SJed Brown 3267552f7358SJed Brown Not Collective 3268552f7358SJed Brown 3269aa50250dSMatthew G. Knepley Input Parameter: 3270552f7358SJed Brown . dm - The DMPlex object 3271552f7358SJed Brown 3272aa50250dSMatthew G. Knepley Output Parameter: 3273aa50250dSMatthew G. Knepley . depthLabel - The DMLabel recording point depth 3274552f7358SJed Brown 3275552f7358SJed Brown Level: developer 3276552f7358SJed Brown 3277aa50250dSMatthew G. Knepley .keywords: mesh, points 3278aa50250dSMatthew G. Knepley .seealso: DMPlexGetDepth(), DMPlexGetHeightStratum(), DMPlexGetDepthStratum() 3279aa50250dSMatthew G. Knepley @*/ 3280aa50250dSMatthew G. Knepley PetscErrorCode DMPlexGetDepthLabel(DM dm, DMLabel *depthLabel) 3281aa50250dSMatthew G. Knepley { 3282aa50250dSMatthew G. Knepley PetscErrorCode ierr; 3283aa50250dSMatthew G. Knepley 3284aa50250dSMatthew G. Knepley PetscFunctionBegin; 3285aa50250dSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3286aa50250dSMatthew G. Knepley PetscValidPointer(depthLabel, 2); 3287c58f1c22SToby Isaac if (!dm->depthLabel) {ierr = DMGetLabel(dm, "depth", &dm->depthLabel);CHKERRQ(ierr);} 3288c58f1c22SToby Isaac *depthLabel = dm->depthLabel; 3289aa50250dSMatthew G. Knepley PetscFunctionReturn(0); 3290aa50250dSMatthew G. Knepley } 3291aa50250dSMatthew G. Knepley 3292aa50250dSMatthew G. Knepley /*@ 3293aa50250dSMatthew G. Knepley DMPlexGetDepth - Get the depth of the DAG representing this mesh 3294aa50250dSMatthew G. Knepley 3295aa50250dSMatthew G. Knepley Not Collective 3296aa50250dSMatthew G. Knepley 3297aa50250dSMatthew G. Knepley Input Parameter: 3298aa50250dSMatthew G. Knepley . dm - The DMPlex object 3299aa50250dSMatthew G. Knepley 3300aa50250dSMatthew G. Knepley Output Parameter: 3301aa50250dSMatthew G. Knepley . depth - The number of strata (breadth first levels) in the DAG 3302aa50250dSMatthew G. Knepley 3303aa50250dSMatthew G. Knepley Level: developer 3304552f7358SJed Brown 3305552f7358SJed Brown .keywords: mesh, points 3306aa50250dSMatthew G. Knepley .seealso: DMPlexGetDepthLabel(), DMPlexGetHeightStratum(), DMPlexGetDepthStratum() 3307552f7358SJed Brown @*/ 3308552f7358SJed Brown PetscErrorCode DMPlexGetDepth(DM dm, PetscInt *depth) 3309552f7358SJed Brown { 3310aa50250dSMatthew G. Knepley DMLabel label; 3311aa50250dSMatthew G. Knepley PetscInt d = 0; 3312552f7358SJed Brown PetscErrorCode ierr; 3313552f7358SJed Brown 3314552f7358SJed Brown PetscFunctionBegin; 3315552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3316552f7358SJed Brown PetscValidPointer(depth, 2); 3317aa50250dSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 3318aa50250dSMatthew G. Knepley if (label) {ierr = DMLabelGetNumValues(label, &d);CHKERRQ(ierr);} 3319552f7358SJed Brown *depth = d-1; 3320552f7358SJed Brown PetscFunctionReturn(0); 3321552f7358SJed Brown } 3322552f7358SJed Brown 3323552f7358SJed Brown /*@ 3324552f7358SJed Brown DMPlexGetDepthStratum - Get the bounds [start, end) for all points at a certain depth. 3325552f7358SJed Brown 3326552f7358SJed Brown Not Collective 3327552f7358SJed Brown 3328552f7358SJed Brown Input Parameters: 3329552f7358SJed Brown + dm - The DMPlex object 3330552f7358SJed Brown - stratumValue - The requested depth 3331552f7358SJed Brown 3332552f7358SJed Brown Output Parameters: 3333552f7358SJed Brown + start - The first point at this depth 3334552f7358SJed Brown - end - One beyond the last point at this depth 3335552f7358SJed Brown 3336552f7358SJed Brown Level: developer 3337552f7358SJed Brown 3338552f7358SJed Brown .keywords: mesh, points 3339552f7358SJed Brown .seealso: DMPlexGetHeightStratum(), DMPlexGetDepth() 3340552f7358SJed Brown @*/ 33410adebc6cSBarry Smith PetscErrorCode DMPlexGetDepthStratum(DM dm, PetscInt stratumValue, PetscInt *start, PetscInt *end) 33420adebc6cSBarry Smith { 3343aa50250dSMatthew G. Knepley DMLabel label; 334463d1a920SMatthew G. Knepley PetscInt pStart, pEnd; 3345552f7358SJed Brown PetscErrorCode ierr; 3346552f7358SJed Brown 3347552f7358SJed Brown PetscFunctionBegin; 3348552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 334963d1a920SMatthew G. Knepley if (start) {PetscValidPointer(start, 3); *start = 0;} 335063d1a920SMatthew G. Knepley if (end) {PetscValidPointer(end, 4); *end = 0;} 3351552f7358SJed Brown ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 33520d644c17SKarl Rupp if (pStart == pEnd) PetscFunctionReturn(0); 335363d1a920SMatthew G. Knepley if (stratumValue < 0) { 335463d1a920SMatthew G. Knepley if (start) *start = pStart; 335563d1a920SMatthew G. Knepley if (end) *end = pEnd; 335663d1a920SMatthew G. Knepley PetscFunctionReturn(0); 3357552f7358SJed Brown } 3358aa50250dSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 335963d1a920SMatthew G. Knepley if (!label) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "No label named depth was found"); 336063d1a920SMatthew G. Knepley ierr = DMLabelGetStratumBounds(label, stratumValue, start, end);CHKERRQ(ierr); 3361552f7358SJed Brown PetscFunctionReturn(0); 3362552f7358SJed Brown } 3363552f7358SJed Brown 3364552f7358SJed Brown /*@ 3365552f7358SJed Brown DMPlexGetHeightStratum - Get the bounds [start, end) for all points at a certain height. 3366552f7358SJed Brown 3367552f7358SJed Brown Not Collective 3368552f7358SJed Brown 3369552f7358SJed Brown Input Parameters: 3370552f7358SJed Brown + dm - The DMPlex object 3371552f7358SJed Brown - stratumValue - The requested height 3372552f7358SJed Brown 3373552f7358SJed Brown Output Parameters: 3374552f7358SJed Brown + start - The first point at this height 3375552f7358SJed Brown - end - One beyond the last point at this height 3376552f7358SJed Brown 3377552f7358SJed Brown Level: developer 3378552f7358SJed Brown 3379552f7358SJed Brown .keywords: mesh, points 3380552f7358SJed Brown .seealso: DMPlexGetDepthStratum(), DMPlexGetDepth() 3381552f7358SJed Brown @*/ 33820adebc6cSBarry Smith PetscErrorCode DMPlexGetHeightStratum(DM dm, PetscInt stratumValue, PetscInt *start, PetscInt *end) 33830adebc6cSBarry Smith { 3384aa50250dSMatthew G. Knepley DMLabel label; 338563d1a920SMatthew G. Knepley PetscInt depth, pStart, pEnd; 3386552f7358SJed Brown PetscErrorCode ierr; 3387552f7358SJed Brown 3388552f7358SJed Brown PetscFunctionBegin; 3389552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 339063d1a920SMatthew G. Knepley if (start) {PetscValidPointer(start, 3); *start = 0;} 339163d1a920SMatthew G. Knepley if (end) {PetscValidPointer(end, 4); *end = 0;} 3392552f7358SJed Brown ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 33930d644c17SKarl Rupp if (pStart == pEnd) PetscFunctionReturn(0); 339463d1a920SMatthew G. Knepley if (stratumValue < 0) { 339563d1a920SMatthew G. Knepley if (start) *start = pStart; 339663d1a920SMatthew G. Knepley if (end) *end = pEnd; 339763d1a920SMatthew G. Knepley PetscFunctionReturn(0); 3398552f7358SJed Brown } 3399aa50250dSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 340013903a91SSatish Balay if (!label) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "No label named depth was found"); 340163d1a920SMatthew G. Knepley ierr = DMLabelGetNumValues(label, &depth);CHKERRQ(ierr); 340263d1a920SMatthew G. Knepley ierr = DMLabelGetStratumBounds(label, depth-1-stratumValue, start, end);CHKERRQ(ierr); 3403552f7358SJed Brown PetscFunctionReturn(0); 3404552f7358SJed Brown } 3405552f7358SJed Brown 34060adebc6cSBarry Smith PetscErrorCode DMCreateCoordinateDM_Plex(DM dm, DM *cdm) 34070adebc6cSBarry Smith { 3408efe440bfSMatthew G. Knepley PetscSection section, s; 3409efe440bfSMatthew G. Knepley Mat m; 34103e922f36SToby Isaac PetscInt maxHeight; 3411552f7358SJed Brown PetscErrorCode ierr; 3412552f7358SJed Brown 3413552f7358SJed Brown PetscFunctionBegin; 341438221697SMatthew G. Knepley ierr = DMClone(dm, cdm);CHKERRQ(ierr); 34153e922f36SToby Isaac ierr = DMPlexGetMaxProjectionHeight(dm, &maxHeight);CHKERRQ(ierr); 34163e922f36SToby Isaac ierr = DMPlexSetMaxProjectionHeight(*cdm, maxHeight);CHKERRQ(ierr); 341782f516ccSBarry Smith ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), §ion);CHKERRQ(ierr); 3418e87a4003SBarry Smith ierr = DMSetSection(*cdm, section);CHKERRQ(ierr); 34191d799100SJed Brown ierr = PetscSectionDestroy(§ion);CHKERRQ(ierr); 3420efe440bfSMatthew G. Knepley ierr = PetscSectionCreate(PETSC_COMM_SELF, &s);CHKERRQ(ierr); 3421efe440bfSMatthew G. Knepley ierr = MatCreate(PETSC_COMM_SELF, &m);CHKERRQ(ierr); 3422efe440bfSMatthew G. Knepley ierr = DMSetDefaultConstraints(*cdm, s, m);CHKERRQ(ierr); 3423efe440bfSMatthew G. Knepley ierr = PetscSectionDestroy(&s);CHKERRQ(ierr); 3424efe440bfSMatthew G. Knepley ierr = MatDestroy(&m);CHKERRQ(ierr); 34258f4c458bSMatthew G. Knepley 34268f4c458bSMatthew G. Knepley ierr = DMSetNumFields(*cdm, 1);CHKERRQ(ierr); 34278f4c458bSMatthew G. Knepley ierr = DMCreateDS(*cdm);CHKERRQ(ierr); 3428552f7358SJed Brown PetscFunctionReturn(0); 3429552f7358SJed Brown } 3430552f7358SJed Brown 3431f19dbd58SToby Isaac PetscErrorCode DMCreateCoordinateField_Plex(DM dm, DMField *field) 3432f19dbd58SToby Isaac { 3433f19dbd58SToby Isaac Vec coordsLocal; 3434f19dbd58SToby Isaac DM coordsDM; 3435f19dbd58SToby Isaac PetscErrorCode ierr; 3436f19dbd58SToby Isaac 3437f19dbd58SToby Isaac PetscFunctionBegin; 3438f19dbd58SToby Isaac *field = NULL; 3439f19dbd58SToby Isaac ierr = DMGetCoordinatesLocal(dm,&coordsLocal);CHKERRQ(ierr); 3440f19dbd58SToby Isaac ierr = DMGetCoordinateDM(dm,&coordsDM);CHKERRQ(ierr); 3441f19dbd58SToby Isaac if (coordsLocal && coordsDM) { 3442f19dbd58SToby Isaac ierr = DMFieldCreateDS(coordsDM, 0, coordsLocal, field);CHKERRQ(ierr); 3443f19dbd58SToby Isaac } 3444f19dbd58SToby Isaac PetscFunctionReturn(0); 3445f19dbd58SToby Isaac } 3446f19dbd58SToby Isaac 34477cd05799SMatthew G. Knepley /*@C 34487cd05799SMatthew G. Knepley DMPlexGetConeSection - Return a section which describes the layout of cone data 34497cd05799SMatthew G. Knepley 34507cd05799SMatthew G. Knepley Not Collective 34517cd05799SMatthew G. Knepley 34527cd05799SMatthew G. Knepley Input Parameters: 34537cd05799SMatthew G. Knepley . dm - The DMPlex object 34547cd05799SMatthew G. Knepley 34557cd05799SMatthew G. Knepley Output Parameter: 34567cd05799SMatthew G. Knepley . section - The PetscSection object 34577cd05799SMatthew G. Knepley 34587cd05799SMatthew G. Knepley Level: developer 34597cd05799SMatthew G. Knepley 34607cd05799SMatthew G. Knepley .seealso: DMPlexGetSupportSection(), DMPlexGetCones(), DMPlexGetConeOrientations() 34617cd05799SMatthew G. Knepley @*/ 34620adebc6cSBarry Smith PetscErrorCode DMPlexGetConeSection(DM dm, PetscSection *section) 34630adebc6cSBarry Smith { 3464552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3465552f7358SJed Brown 3466552f7358SJed Brown PetscFunctionBegin; 3467552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3468552f7358SJed Brown if (section) *section = mesh->coneSection; 3469552f7358SJed Brown PetscFunctionReturn(0); 3470552f7358SJed Brown } 3471552f7358SJed Brown 34727cd05799SMatthew G. Knepley /*@C 34737cd05799SMatthew G. Knepley DMPlexGetSupportSection - Return a section which describes the layout of support data 34747cd05799SMatthew G. Knepley 34757cd05799SMatthew G. Knepley Not Collective 34767cd05799SMatthew G. Knepley 34777cd05799SMatthew G. Knepley Input Parameters: 34787cd05799SMatthew G. Knepley . dm - The DMPlex object 34797cd05799SMatthew G. Knepley 34807cd05799SMatthew G. Knepley Output Parameter: 34817cd05799SMatthew G. Knepley . section - The PetscSection object 34827cd05799SMatthew G. Knepley 34837cd05799SMatthew G. Knepley Level: developer 34847cd05799SMatthew G. Knepley 34857cd05799SMatthew G. Knepley .seealso: DMPlexGetConeSection() 34867cd05799SMatthew G. Knepley @*/ 34878cb4d582SMatthew G. Knepley PetscErrorCode DMPlexGetSupportSection(DM dm, PetscSection *section) 34888cb4d582SMatthew G. Knepley { 34898cb4d582SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 34908cb4d582SMatthew G. Knepley 34918cb4d582SMatthew G. Knepley PetscFunctionBegin; 34928cb4d582SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 34938cb4d582SMatthew G. Knepley if (section) *section = mesh->supportSection; 34948cb4d582SMatthew G. Knepley PetscFunctionReturn(0); 34958cb4d582SMatthew G. Knepley } 34968cb4d582SMatthew G. Knepley 34977cd05799SMatthew G. Knepley /*@C 34987cd05799SMatthew G. Knepley DMPlexGetCones - Return cone data 34997cd05799SMatthew G. Knepley 35007cd05799SMatthew G. Knepley Not Collective 35017cd05799SMatthew G. Knepley 35027cd05799SMatthew G. Knepley Input Parameters: 35037cd05799SMatthew G. Knepley . dm - The DMPlex object 35047cd05799SMatthew G. Knepley 35057cd05799SMatthew G. Knepley Output Parameter: 35067cd05799SMatthew G. Knepley . cones - The cone for each point 35077cd05799SMatthew G. Knepley 35087cd05799SMatthew G. Knepley Level: developer 35097cd05799SMatthew G. Knepley 35107cd05799SMatthew G. Knepley .seealso: DMPlexGetConeSection() 35117cd05799SMatthew G. Knepley @*/ 3512a6dfd86eSKarl Rupp PetscErrorCode DMPlexGetCones(DM dm, PetscInt *cones[]) 3513a6dfd86eSKarl Rupp { 3514552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3515552f7358SJed Brown 3516552f7358SJed Brown PetscFunctionBegin; 3517552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3518552f7358SJed Brown if (cones) *cones = mesh->cones; 3519552f7358SJed Brown PetscFunctionReturn(0); 3520552f7358SJed Brown } 3521552f7358SJed Brown 35227cd05799SMatthew G. Knepley /*@C 35237cd05799SMatthew G. Knepley DMPlexGetConeOrientations - Return cone orientation data 35247cd05799SMatthew G. Knepley 35257cd05799SMatthew G. Knepley Not Collective 35267cd05799SMatthew G. Knepley 35277cd05799SMatthew G. Knepley Input Parameters: 35287cd05799SMatthew G. Knepley . dm - The DMPlex object 35297cd05799SMatthew G. Knepley 35307cd05799SMatthew G. Knepley Output Parameter: 35317cd05799SMatthew G. Knepley . coneOrientations - The cone orientation for each point 35327cd05799SMatthew G. Knepley 35337cd05799SMatthew G. Knepley Level: developer 35347cd05799SMatthew G. Knepley 35357cd05799SMatthew G. Knepley .seealso: DMPlexGetConeSection() 35367cd05799SMatthew G. Knepley @*/ 3537a6dfd86eSKarl Rupp PetscErrorCode DMPlexGetConeOrientations(DM dm, PetscInt *coneOrientations[]) 3538a6dfd86eSKarl Rupp { 3539552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3540552f7358SJed Brown 3541552f7358SJed Brown PetscFunctionBegin; 3542552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3543552f7358SJed Brown if (coneOrientations) *coneOrientations = mesh->coneOrientations; 3544552f7358SJed Brown PetscFunctionReturn(0); 3545552f7358SJed Brown } 3546552f7358SJed Brown 3547552f7358SJed Brown /******************************** FEM Support **********************************/ 3548552f7358SJed Brown 35497391a63aSMatthew G. Knepley PetscErrorCode DMPlexCreateSpectralClosurePermutation(DM dm, PetscInt point, PetscSection section) 35503194fc30SMatthew G. Knepley { 35517391a63aSMatthew G. Knepley DMLabel label; 35523194fc30SMatthew G. Knepley PetscInt *perm; 35537391a63aSMatthew G. Knepley PetscInt dim, depth, eStart, k, Nf, f, Nc, c, i, j, size = 0, offset = 0, foffset = 0; 35543194fc30SMatthew G. Knepley PetscErrorCode ierr; 35553194fc30SMatthew G. Knepley 35563194fc30SMatthew G. Knepley PetscFunctionBegin; 35577391a63aSMatthew G. Knepley if (point < 0) {ierr = DMPlexGetDepthStratum(dm, 1, &point, NULL);CHKERRQ(ierr);} 35583194fc30SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 35597391a63aSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 35607391a63aSMatthew G. Knepley ierr = DMLabelGetValue(label, point, &depth);CHKERRQ(ierr); 35617391a63aSMatthew G. Knepley if (depth == 1) {eStart = point;} 35627391a63aSMatthew G. Knepley else if (depth == dim) { 35637391a63aSMatthew G. Knepley const PetscInt *cone; 35647391a63aSMatthew G. Knepley 35657391a63aSMatthew G. Knepley ierr = DMPlexGetCone(dm, point, &cone);CHKERRQ(ierr); 3566d4e6627bSStefano Zampini if (dim == 2) eStart = cone[0]; 3567d4e6627bSStefano Zampini else if (dim == 3) { 3568d4e6627bSStefano Zampini const PetscInt *cone2; 3569d4e6627bSStefano Zampini ierr = DMPlexGetCone(dm, cone[0], &cone2);CHKERRQ(ierr); 3570d4e6627bSStefano Zampini eStart = cone2[0]; 3571d4e6627bSStefano 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); 3572d4e6627bSStefano 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); 3573e87a4003SBarry Smith if (!section) {ierr = DMGetSection(dm, §ion);CHKERRQ(ierr);} 35743194fc30SMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &Nf);CHKERRQ(ierr); 357589eabcffSMatthew G. Knepley if (dim <= 1) PetscFunctionReturn(0); 35763194fc30SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 35773194fc30SMatthew G. Knepley /* An order k SEM disc has k-1 dofs on an edge */ 35783194fc30SMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, eStart, f, &k);CHKERRQ(ierr); 35793194fc30SMatthew G. Knepley ierr = PetscSectionGetFieldComponents(section, f, &Nc);CHKERRQ(ierr); 35803194fc30SMatthew G. Knepley k = k/Nc + 1; 358189eabcffSMatthew G. Knepley size += PetscPowInt(k+1, dim)*Nc; 35823194fc30SMatthew G. Knepley } 35833194fc30SMatthew G. Knepley ierr = PetscMalloc1(size, &perm);CHKERRQ(ierr); 35843194fc30SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 358589eabcffSMatthew G. Knepley switch (dim) { 358689eabcffSMatthew G. Knepley case 2: 35873194fc30SMatthew 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} */ 35883194fc30SMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, eStart, f, &k);CHKERRQ(ierr); 35893194fc30SMatthew G. Knepley ierr = PetscSectionGetFieldComponents(section, f, &Nc);CHKERRQ(ierr); 35903194fc30SMatthew G. Knepley k = k/Nc + 1; 35913194fc30SMatthew G. Knepley /* The SEM order is 35923194fc30SMatthew G. Knepley 35933194fc30SMatthew G. Knepley v_lb, {e_b}, v_rb, 359489eabcffSMatthew G. Knepley e^{(k-1)-i}_l, {f^{i*(k-1)}}, e^i_r, 35953194fc30SMatthew G. Knepley v_lt, reverse {e_t}, v_rt 35963194fc30SMatthew G. Knepley */ 35973194fc30SMatthew G. Knepley { 35983194fc30SMatthew G. Knepley const PetscInt of = 0; 35993194fc30SMatthew G. Knepley const PetscInt oeb = of + PetscSqr(k-1); 36003194fc30SMatthew G. Knepley const PetscInt oer = oeb + (k-1); 36013194fc30SMatthew G. Knepley const PetscInt oet = oer + (k-1); 36023194fc30SMatthew G. Knepley const PetscInt oel = oet + (k-1); 36033194fc30SMatthew G. Knepley const PetscInt ovlb = oel + (k-1); 36043194fc30SMatthew G. Knepley const PetscInt ovrb = ovlb + 1; 36053194fc30SMatthew G. Knepley const PetscInt ovrt = ovrb + 1; 36063194fc30SMatthew G. Knepley const PetscInt ovlt = ovrt + 1; 36073194fc30SMatthew G. Knepley PetscInt o; 36083194fc30SMatthew G. Knepley 36093194fc30SMatthew G. Knepley /* bottom */ 36103194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovlb*Nc + c + foffset; 36113194fc30SMatthew G. Knepley for (o = oeb; o < oer; ++o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 36123194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovrb*Nc + c + foffset; 36133194fc30SMatthew G. Knepley /* middle */ 36143194fc30SMatthew G. Knepley for (i = 0; i < k-1; ++i) { 36153194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oel+(k-2)-i)*Nc + c + foffset; 36163194fc30SMatthew 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; 36173194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oer+i)*Nc + c + foffset; 36183194fc30SMatthew G. Knepley } 36193194fc30SMatthew G. Knepley /* top */ 36203194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovlt*Nc + c + foffset; 36213194fc30SMatthew G. Knepley for (o = oel-1; o >= oet; --o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 36223194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovrt*Nc + c + foffset; 36233194fc30SMatthew G. Knepley foffset = offset; 36243194fc30SMatthew G. Knepley } 362589eabcffSMatthew G. Knepley break; 362689eabcffSMatthew G. Knepley case 3: 362789eabcffSMatthew G. Knepley /* The original hex closure is 362889eabcffSMatthew G. Knepley 362989eabcffSMatthew G. Knepley {c, 363089eabcffSMatthew G. Knepley f_b, f_t, f_f, f_b, f_r, f_l, 363189eabcffSMatthew 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, 363289eabcffSMatthew G. Knepley v_blf, v_blb, v_brb, v_brf, v_tlf, v_trf, v_trb, v_tlb} 363389eabcffSMatthew G. Knepley */ 363489eabcffSMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, eStart, f, &k);CHKERRQ(ierr); 363589eabcffSMatthew G. Knepley ierr = PetscSectionGetFieldComponents(section, f, &Nc);CHKERRQ(ierr); 363689eabcffSMatthew G. Knepley k = k/Nc + 1; 363789eabcffSMatthew G. Knepley /* The SEM order is 363889eabcffSMatthew G. Knepley Bottom Slice 363989eabcffSMatthew G. Knepley v_blf, {e^{(k-1)-n}_bf}, v_brf, 364089eabcffSMatthew G. Knepley e^{i}_bl, f^{n*(k-1)+(k-1)-i}_b, e^{(k-1)-i}_br, 364189eabcffSMatthew G. Knepley v_blb, {e_bb}, v_brb, 364289eabcffSMatthew G. Knepley 364389eabcffSMatthew G. Knepley Middle Slice (j) 364489eabcffSMatthew G. Knepley {e^{(k-1)-j}_lf}, {f^{j*(k-1)+n}_f}, e^j_rf, 364589eabcffSMatthew G. Knepley f^{i*(k-1)+j}_l, {c^{(j*(k-1) + i)*(k-1)+n}_t}, f^{j*(k-1)+i}_r, 364689eabcffSMatthew G. Knepley e^j_lb, {f^{j*(k-1)+(k-1)-n}_b}, e^{(k-1)-j}_rb, 364789eabcffSMatthew G. Knepley 364889eabcffSMatthew G. Knepley Top Slice 364989eabcffSMatthew G. Knepley v_tlf, {e_tf}, v_trf, 365089eabcffSMatthew G. Knepley e^{(k-1)-i}_tl, {f^{i*(k-1)}_t}, e^{i}_tr, 365189eabcffSMatthew G. Knepley v_tlb, {e^{(k-1)-n}_tb}, v_trb, 365289eabcffSMatthew G. Knepley */ 365389eabcffSMatthew G. Knepley { 365489eabcffSMatthew G. Knepley const PetscInt oc = 0; 365589eabcffSMatthew G. Knepley const PetscInt ofb = oc + PetscSqr(k-1)*(k-1); 365689eabcffSMatthew G. Knepley const PetscInt oft = ofb + PetscSqr(k-1); 365789eabcffSMatthew G. Knepley const PetscInt off = oft + PetscSqr(k-1); 365889eabcffSMatthew G. Knepley const PetscInt ofk = off + PetscSqr(k-1); 365989eabcffSMatthew G. Knepley const PetscInt ofr = ofk + PetscSqr(k-1); 366089eabcffSMatthew G. Knepley const PetscInt ofl = ofr + PetscSqr(k-1); 366189eabcffSMatthew G. Knepley const PetscInt oebl = ofl + PetscSqr(k-1); 366289eabcffSMatthew G. Knepley const PetscInt oebb = oebl + (k-1); 366389eabcffSMatthew G. Knepley const PetscInt oebr = oebb + (k-1); 366489eabcffSMatthew G. Knepley const PetscInt oebf = oebr + (k-1); 366589eabcffSMatthew G. Knepley const PetscInt oetf = oebf + (k-1); 366689eabcffSMatthew G. Knepley const PetscInt oetr = oetf + (k-1); 366789eabcffSMatthew G. Knepley const PetscInt oetb = oetr + (k-1); 366889eabcffSMatthew G. Knepley const PetscInt oetl = oetb + (k-1); 366989eabcffSMatthew G. Knepley const PetscInt oerf = oetl + (k-1); 367089eabcffSMatthew G. Knepley const PetscInt oelf = oerf + (k-1); 367189eabcffSMatthew G. Knepley const PetscInt oelb = oelf + (k-1); 367289eabcffSMatthew G. Knepley const PetscInt oerb = oelb + (k-1); 367389eabcffSMatthew G. Knepley const PetscInt ovblf = oerb + (k-1); 367489eabcffSMatthew G. Knepley const PetscInt ovblb = ovblf + 1; 367589eabcffSMatthew G. Knepley const PetscInt ovbrb = ovblb + 1; 367689eabcffSMatthew G. Knepley const PetscInt ovbrf = ovbrb + 1; 367789eabcffSMatthew G. Knepley const PetscInt ovtlf = ovbrf + 1; 367889eabcffSMatthew G. Knepley const PetscInt ovtrf = ovtlf + 1; 367989eabcffSMatthew G. Knepley const PetscInt ovtrb = ovtrf + 1; 368089eabcffSMatthew G. Knepley const PetscInt ovtlb = ovtrb + 1; 368189eabcffSMatthew G. Knepley PetscInt o, n; 368289eabcffSMatthew G. Knepley 368389eabcffSMatthew G. Knepley /* Bottom Slice */ 368489eabcffSMatthew G. Knepley /* bottom */ 368589eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovblf*Nc + c + foffset; 368689eabcffSMatthew G. Knepley for (o = oetf-1; o >= oebf; --o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 368789eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovbrf*Nc + c + foffset; 368889eabcffSMatthew G. Knepley /* middle */ 368989eabcffSMatthew G. Knepley for (i = 0; i < k-1; ++i) { 369089eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oebl+i)*Nc + c + foffset; 3691316b7f87SMax 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;} 369289eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oebr+(k-2)-i)*Nc + c + foffset; 36933194fc30SMatthew G. Knepley } 369489eabcffSMatthew G. Knepley /* top */ 369589eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovblb*Nc + c + foffset; 369689eabcffSMatthew G. Knepley for (o = oebb; o < oebr; ++o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 369789eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovbrb*Nc + c + foffset; 369889eabcffSMatthew G. Knepley 369989eabcffSMatthew G. Knepley /* Middle Slice */ 370089eabcffSMatthew G. Knepley for (j = 0; j < k-1; ++j) { 370189eabcffSMatthew G. Knepley /* bottom */ 370289eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oelf+(k-2)-j)*Nc + c + foffset; 370389eabcffSMatthew 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; 370489eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oerf+j)*Nc + c + foffset; 370589eabcffSMatthew G. Knepley /* middle */ 370689eabcffSMatthew G. Knepley for (i = 0; i < k-1; ++i) { 370789eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (ofl+i*(k-1)+j)*Nc + c + foffset; 370889eabcffSMatthew 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; 370989eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (ofr+j*(k-1)+i)*Nc + c + foffset; 371089eabcffSMatthew G. Knepley } 371189eabcffSMatthew G. Knepley /* top */ 371289eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oelb+j)*Nc + c + foffset; 371389eabcffSMatthew 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; 371489eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oerb+(k-2)-j)*Nc + c + foffset; 371589eabcffSMatthew G. Knepley } 371689eabcffSMatthew G. Knepley 371789eabcffSMatthew G. Knepley /* Top Slice */ 371889eabcffSMatthew G. Knepley /* bottom */ 371989eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovtlf*Nc + c + foffset; 372089eabcffSMatthew G. Knepley for (o = oetf; o < oetr; ++o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 372189eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovtrf*Nc + c + foffset; 372289eabcffSMatthew G. Knepley /* middle */ 372389eabcffSMatthew G. Knepley for (i = 0; i < k-1; ++i) { 372489eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oetl+(k-2)-i)*Nc + c + foffset; 372589eabcffSMatthew 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; 372689eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oetr+i)*Nc + c + foffset; 372789eabcffSMatthew G. Knepley } 372889eabcffSMatthew G. Knepley /* top */ 372989eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovtlb*Nc + c + foffset; 373089eabcffSMatthew G. Knepley for (o = oetl-1; o >= oetb; --o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 373189eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovtrb*Nc + c + foffset; 373289eabcffSMatthew G. Knepley 373389eabcffSMatthew G. Knepley foffset = offset; 373489eabcffSMatthew G. Knepley } 373589eabcffSMatthew G. Knepley break; 373689eabcffSMatthew G. Knepley default: SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "No spectral ordering for dimension %D", dim); 373789eabcffSMatthew G. Knepley } 373889eabcffSMatthew G. Knepley } 373989eabcffSMatthew G. Knepley if (offset != size) SETERRQ2(PetscObjectComm((PetscObject) dm), PETSC_ERR_PLIB, "Number of permutation entries %D != %D", offset, size); 37403194fc30SMatthew G. Knepley /* Check permutation */ 37413194fc30SMatthew G. Knepley { 37423194fc30SMatthew G. Knepley PetscInt *check; 37433194fc30SMatthew G. Knepley 37443194fc30SMatthew G. Knepley ierr = PetscMalloc1(size, &check);CHKERRQ(ierr); 37453194fc30SMatthew 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]);} 37463194fc30SMatthew G. Knepley for (i = 0; i < size; ++i) check[perm[i]] = i; 37473194fc30SMatthew G. Knepley for (i = 0; i < size; ++i) {if (check[i] < 0) SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_PLIB, "Missing permutation index %D", i);} 37483194fc30SMatthew G. Knepley ierr = PetscFree(check);CHKERRQ(ierr); 37493194fc30SMatthew G. Knepley } 37501fdd32a2SMatthew G. Knepley ierr = PetscSectionSetClosurePermutation_Internal(section, (PetscObject) dm, size, PETSC_OWN_POINTER, perm);CHKERRQ(ierr); 37513194fc30SMatthew G. Knepley PetscFunctionReturn(0); 37523194fc30SMatthew G. Knepley } 37533194fc30SMatthew G. Knepley 3754e071409bSToby Isaac PetscErrorCode DMPlexGetPointDualSpaceFEM(DM dm, PetscInt point, PetscInt field, PetscDualSpace *dspace) 3755e071409bSToby Isaac { 3756e071409bSToby Isaac PetscDS prob; 3757e071409bSToby Isaac PetscInt depth, Nf, h; 3758e071409bSToby Isaac DMLabel label; 3759e071409bSToby Isaac PetscErrorCode ierr; 3760e071409bSToby Isaac 3761e071409bSToby Isaac PetscFunctionBeginHot; 3762e5e52638SMatthew G. Knepley ierr = DMGetDS(dm, &prob);CHKERRQ(ierr); 3763e071409bSToby Isaac Nf = prob->Nf; 3764e071409bSToby Isaac label = dm->depthLabel; 3765e071409bSToby Isaac *dspace = NULL; 3766e071409bSToby Isaac if (field < Nf) { 3767e071409bSToby Isaac PetscObject disc = prob->disc[field]; 3768e071409bSToby Isaac 3769e071409bSToby Isaac if (disc->classid == PETSCFE_CLASSID) { 3770e071409bSToby Isaac PetscDualSpace dsp; 3771e071409bSToby Isaac 3772e071409bSToby Isaac ierr = PetscFEGetDualSpace((PetscFE)disc,&dsp);CHKERRQ(ierr); 3773e071409bSToby Isaac ierr = DMLabelGetNumValues(label,&depth);CHKERRQ(ierr); 3774e071409bSToby Isaac ierr = DMLabelGetValue(label,point,&h);CHKERRQ(ierr); 3775e071409bSToby Isaac h = depth - 1 - h; 3776e071409bSToby Isaac if (h) { 3777e071409bSToby Isaac ierr = PetscDualSpaceGetHeightSubspace(dsp,h,dspace);CHKERRQ(ierr); 3778e071409bSToby Isaac } else { 3779e071409bSToby Isaac *dspace = dsp; 3780e071409bSToby Isaac } 3781e071409bSToby Isaac } 3782e071409bSToby Isaac } 3783e071409bSToby Isaac PetscFunctionReturn(0); 3784e071409bSToby Isaac } 3785e071409bSToby Isaac 3786e071409bSToby Isaac 37871a271a75SMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode DMPlexVecGetClosure_Depth1_Static(DM dm, PetscSection section, Vec v, PetscInt point, PetscInt *csize, PetscScalar *values[]) 3788a6dfd86eSKarl Rupp { 3789552f7358SJed Brown PetscScalar *array, *vArray; 3790d9917b9dSMatthew G. Knepley const PetscInt *cone, *coneO; 37911a271a75SMatthew G. Knepley PetscInt pStart, pEnd, p, numPoints, size = 0, offset = 0; 3792552f7358SJed Brown PetscErrorCode ierr; 3793552f7358SJed Brown 37941b406b76SMatthew G. Knepley PetscFunctionBeginHot; 37952a3aaacfSMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 37965a1bb5cfSMatthew G. Knepley ierr = DMPlexGetConeSize(dm, point, &numPoints);CHKERRQ(ierr); 37975a1bb5cfSMatthew G. Knepley ierr = DMPlexGetCone(dm, point, &cone);CHKERRQ(ierr); 37985a1bb5cfSMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, point, &coneO);CHKERRQ(ierr); 37993f7cbbe7SMatthew G. Knepley if (!values || !*values) { 38009df71ca4SMatthew G. Knepley if ((point >= pStart) && (point < pEnd)) { 38019df71ca4SMatthew G. Knepley PetscInt dof; 3802d9917b9dSMatthew G. Knepley 38039df71ca4SMatthew G. Knepley ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 38049df71ca4SMatthew G. Knepley size += dof; 38059df71ca4SMatthew G. Knepley } 38069df71ca4SMatthew G. Knepley for (p = 0; p < numPoints; ++p) { 38079df71ca4SMatthew G. Knepley const PetscInt cp = cone[p]; 38082a3aaacfSMatthew G. Knepley PetscInt dof; 38095a1bb5cfSMatthew G. Knepley 38105a1bb5cfSMatthew G. Knepley if ((cp < pStart) || (cp >= pEnd)) continue; 38112a3aaacfSMatthew G. Knepley ierr = PetscSectionGetDof(section, cp, &dof);CHKERRQ(ierr); 38125a1bb5cfSMatthew G. Knepley size += dof; 38135a1bb5cfSMatthew G. Knepley } 38143f7cbbe7SMatthew G. Knepley if (!values) { 38153f7cbbe7SMatthew G. Knepley if (csize) *csize = size; 38163f7cbbe7SMatthew G. Knepley PetscFunctionReturn(0); 38173f7cbbe7SMatthew G. Knepley } 381869291d52SBarry Smith ierr = DMGetWorkArray(dm, size, MPIU_SCALAR, &array);CHKERRQ(ierr); 3819982e9ed1SMatthew G. Knepley } else { 3820982e9ed1SMatthew G. Knepley array = *values; 3821982e9ed1SMatthew G. Knepley } 38229df71ca4SMatthew G. Knepley size = 0; 38235a1bb5cfSMatthew G. Knepley ierr = VecGetArray(v, &vArray);CHKERRQ(ierr); 38249df71ca4SMatthew G. Knepley if ((point >= pStart) && (point < pEnd)) { 38259df71ca4SMatthew G. Knepley PetscInt dof, off, d; 38269df71ca4SMatthew G. Knepley PetscScalar *varr; 3827d9917b9dSMatthew G. Knepley 38289df71ca4SMatthew G. Knepley ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 38299df71ca4SMatthew G. Knepley ierr = PetscSectionGetOffset(section, point, &off);CHKERRQ(ierr); 38309df71ca4SMatthew G. Knepley varr = &vArray[off]; 38311a271a75SMatthew G. Knepley for (d = 0; d < dof; ++d, ++offset) { 38321a271a75SMatthew G. Knepley array[offset] = varr[d]; 38339df71ca4SMatthew G. Knepley } 38349df71ca4SMatthew G. Knepley size += dof; 38359df71ca4SMatthew G. Knepley } 38369df71ca4SMatthew G. Knepley for (p = 0; p < numPoints; ++p) { 38379df71ca4SMatthew G. Knepley const PetscInt cp = cone[p]; 38389df71ca4SMatthew G. Knepley PetscInt o = coneO[p]; 38395a1bb5cfSMatthew G. Knepley PetscInt dof, off, d; 38405a1bb5cfSMatthew G. Knepley PetscScalar *varr; 38415a1bb5cfSMatthew G. Knepley 384252ed52e8SMatthew G. Knepley if ((cp < pStart) || (cp >= pEnd)) continue; 38435a1bb5cfSMatthew G. Knepley ierr = PetscSectionGetDof(section, cp, &dof);CHKERRQ(ierr); 38445a1bb5cfSMatthew G. Knepley ierr = PetscSectionGetOffset(section, cp, &off);CHKERRQ(ierr); 38455a1bb5cfSMatthew G. Knepley varr = &vArray[off]; 38465a1bb5cfSMatthew G. Knepley if (o >= 0) { 38471a271a75SMatthew G. Knepley for (d = 0; d < dof; ++d, ++offset) { 38481a271a75SMatthew G. Knepley array[offset] = varr[d]; 38495a1bb5cfSMatthew G. Knepley } 38505a1bb5cfSMatthew G. Knepley } else { 38511a271a75SMatthew G. Knepley for (d = dof-1; d >= 0; --d, ++offset) { 38521a271a75SMatthew G. Knepley array[offset] = varr[d]; 38535a1bb5cfSMatthew G. Knepley } 38545a1bb5cfSMatthew G. Knepley } 38559df71ca4SMatthew G. Knepley size += dof; 38565a1bb5cfSMatthew G. Knepley } 38575a1bb5cfSMatthew G. Knepley ierr = VecRestoreArray(v, &vArray);CHKERRQ(ierr); 38589df71ca4SMatthew G. Knepley if (!*values) { 38595a1bb5cfSMatthew G. Knepley if (csize) *csize = size; 38605a1bb5cfSMatthew G. Knepley *values = array; 38619df71ca4SMatthew G. Knepley } else { 38628ccfff9cSToby Isaac if (size > *csize) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Size of input array %D < actual size %D", *csize, size); 38638c312ff3SMatthew G. Knepley *csize = size; 38649df71ca4SMatthew G. Knepley } 38655a1bb5cfSMatthew G. Knepley PetscFunctionReturn(0); 38665a1bb5cfSMatthew G. Knepley } 3867d9917b9dSMatthew G. Knepley 3868923c78e0SToby Isaac static PetscErrorCode DMPlexGetCompressedClosure(DM dm, PetscSection section, PetscInt point, PetscInt *numPoints, PetscInt **points, PetscSection *clSec, IS *clPoints, const PetscInt **clp) 3869923c78e0SToby Isaac { 3870923c78e0SToby Isaac const PetscInt *cla; 3871923c78e0SToby Isaac PetscInt np, *pts = NULL; 3872923c78e0SToby Isaac PetscErrorCode ierr; 3873923c78e0SToby Isaac 3874923c78e0SToby Isaac PetscFunctionBeginHot; 3875923c78e0SToby Isaac ierr = PetscSectionGetClosureIndex(section, (PetscObject) dm, clSec, clPoints);CHKERRQ(ierr); 3876923c78e0SToby Isaac if (!*clPoints) { 3877923c78e0SToby Isaac PetscInt pStart, pEnd, p, q; 3878923c78e0SToby Isaac 3879923c78e0SToby Isaac ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 3880923c78e0SToby Isaac ierr = DMPlexGetTransitiveClosure(dm, point, PETSC_TRUE, &np, &pts);CHKERRQ(ierr); 3881923c78e0SToby Isaac /* Compress out points not in the section */ 3882923c78e0SToby Isaac for (p = 0, q = 0; p < np; p++) { 3883923c78e0SToby Isaac PetscInt r = pts[2*p]; 3884923c78e0SToby Isaac if ((r >= pStart) && (r < pEnd)) { 3885923c78e0SToby Isaac pts[q*2] = r; 3886923c78e0SToby Isaac pts[q*2+1] = pts[2*p+1]; 3887923c78e0SToby Isaac ++q; 3888923c78e0SToby Isaac } 3889923c78e0SToby Isaac } 3890923c78e0SToby Isaac np = q; 3891923c78e0SToby Isaac cla = NULL; 3892923c78e0SToby Isaac } else { 3893923c78e0SToby Isaac PetscInt dof, off; 3894923c78e0SToby Isaac 3895923c78e0SToby Isaac ierr = PetscSectionGetDof(*clSec, point, &dof);CHKERRQ(ierr); 3896923c78e0SToby Isaac ierr = PetscSectionGetOffset(*clSec, point, &off);CHKERRQ(ierr); 3897923c78e0SToby Isaac ierr = ISGetIndices(*clPoints, &cla);CHKERRQ(ierr); 3898923c78e0SToby Isaac np = dof/2; 3899923c78e0SToby Isaac pts = (PetscInt *) &cla[off]; 3900923c78e0SToby Isaac } 3901923c78e0SToby Isaac *numPoints = np; 3902923c78e0SToby Isaac *points = pts; 3903923c78e0SToby Isaac *clp = cla; 3904923c78e0SToby Isaac 3905923c78e0SToby Isaac PetscFunctionReturn(0); 3906923c78e0SToby Isaac } 3907923c78e0SToby Isaac 3908923c78e0SToby Isaac static PetscErrorCode DMPlexRestoreCompressedClosure(DM dm, PetscSection section, PetscInt point, PetscInt *numPoints, PetscInt **points, PetscSection *clSec, IS *clPoints, const PetscInt **clp) 3909923c78e0SToby Isaac { 3910923c78e0SToby Isaac PetscErrorCode ierr; 3911923c78e0SToby Isaac 3912923c78e0SToby Isaac PetscFunctionBeginHot; 3913923c78e0SToby Isaac if (!*clPoints) { 3914923c78e0SToby Isaac ierr = DMPlexRestoreTransitiveClosure(dm, point, PETSC_TRUE, numPoints, points);CHKERRQ(ierr); 3915923c78e0SToby Isaac } else { 3916923c78e0SToby Isaac ierr = ISRestoreIndices(*clPoints, clp);CHKERRQ(ierr); 3917923c78e0SToby Isaac } 3918923c78e0SToby Isaac *numPoints = 0; 3919923c78e0SToby Isaac *points = NULL; 3920923c78e0SToby Isaac *clSec = NULL; 3921923c78e0SToby Isaac *clPoints = NULL; 3922923c78e0SToby Isaac *clp = NULL; 3923923c78e0SToby Isaac PetscFunctionReturn(0); 3924923c78e0SToby Isaac } 3925923c78e0SToby Isaac 392697e99dd9SToby 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[]) 39271a271a75SMatthew G. Knepley { 39281a271a75SMatthew G. Knepley PetscInt offset = 0, p; 392997e99dd9SToby Isaac const PetscInt **perms = NULL; 393097e99dd9SToby Isaac const PetscScalar **flips = NULL; 39311a271a75SMatthew G. Knepley PetscErrorCode ierr; 39321a271a75SMatthew G. Knepley 39331a271a75SMatthew G. Knepley PetscFunctionBeginHot; 3934fe02ba77SJed Brown *size = 0; 393597e99dd9SToby Isaac ierr = PetscSectionGetPointSyms(section,numPoints,points,&perms,&flips);CHKERRQ(ierr); 393697e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 393797e99dd9SToby Isaac const PetscInt point = points[2*p]; 393897e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 393997e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 39401a271a75SMatthew G. Knepley PetscInt dof, off, d; 39411a271a75SMatthew G. Knepley const PetscScalar *varr; 39421a271a75SMatthew G. Knepley 39431a271a75SMatthew G. Knepley ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 39441a271a75SMatthew G. Knepley ierr = PetscSectionGetOffset(section, point, &off);CHKERRQ(ierr); 39451a271a75SMatthew G. Knepley varr = &vArray[off]; 394697e99dd9SToby Isaac if (clperm) { 394797e99dd9SToby Isaac if (perm) { 394897e99dd9SToby Isaac for (d = 0; d < dof; d++) array[clperm[offset + perm[d]]] = varr[d]; 39491a271a75SMatthew G. Knepley } else { 395097e99dd9SToby Isaac for (d = 0; d < dof; d++) array[clperm[offset + d ]] = varr[d]; 395197e99dd9SToby Isaac } 395297e99dd9SToby Isaac if (flip) { 395397e99dd9SToby Isaac for (d = 0; d < dof; d++) array[clperm[offset + d ]] *= flip[d]; 395497e99dd9SToby Isaac } 395597e99dd9SToby Isaac } else { 395697e99dd9SToby Isaac if (perm) { 395797e99dd9SToby Isaac for (d = 0; d < dof; d++) array[offset + perm[d]] = varr[d]; 395897e99dd9SToby Isaac } else { 395997e99dd9SToby Isaac for (d = 0; d < dof; d++) array[offset + d ] = varr[d]; 396097e99dd9SToby Isaac } 396197e99dd9SToby Isaac if (flip) { 396297e99dd9SToby Isaac for (d = 0; d < dof; d++) array[offset + d ] *= flip[d]; 39631a271a75SMatthew G. Knepley } 39641a271a75SMatthew G. Knepley } 396597e99dd9SToby Isaac offset += dof; 396697e99dd9SToby Isaac } 396797e99dd9SToby Isaac ierr = PetscSectionRestorePointSyms(section,numPoints,points,&perms,&flips);CHKERRQ(ierr); 39681a271a75SMatthew G. Knepley *size = offset; 39691a271a75SMatthew G. Knepley PetscFunctionReturn(0); 39701a271a75SMatthew G. Knepley } 39711a271a75SMatthew G. Knepley 397297e99dd9SToby 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[]) 39731a271a75SMatthew G. Knepley { 39741a271a75SMatthew G. Knepley PetscInt offset = 0, f; 39751a271a75SMatthew G. Knepley PetscErrorCode ierr; 39761a271a75SMatthew G. Knepley 39771a271a75SMatthew G. Knepley PetscFunctionBeginHot; 3978fe02ba77SJed Brown *size = 0; 39791a271a75SMatthew G. Knepley for (f = 0; f < numFields; ++f) { 398097e99dd9SToby Isaac PetscInt p; 398197e99dd9SToby Isaac const PetscInt **perms = NULL; 398297e99dd9SToby Isaac const PetscScalar **flips = NULL; 39831a271a75SMatthew G. Knepley 398497e99dd9SToby Isaac ierr = PetscSectionGetFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 398597e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 398697e99dd9SToby Isaac const PetscInt point = points[2*p]; 398797e99dd9SToby Isaac PetscInt fdof, foff, b; 39881a271a75SMatthew G. Knepley const PetscScalar *varr; 398997e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 399097e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 39911a271a75SMatthew G. Knepley 39921a271a75SMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 39931a271a75SMatthew G. Knepley ierr = PetscSectionGetFieldOffset(section, point, f, &foff);CHKERRQ(ierr); 39941a271a75SMatthew G. Knepley varr = &vArray[foff]; 399597e99dd9SToby Isaac if (clperm) { 399697e99dd9SToby Isaac if (perm) {for (b = 0; b < fdof; b++) {array[clperm[offset + perm[b]]] = varr[b];}} 399797e99dd9SToby Isaac else {for (b = 0; b < fdof; b++) {array[clperm[offset + b ]] = varr[b];}} 399897e99dd9SToby Isaac if (flip) {for (b = 0; b < fdof; b++) {array[clperm[offset + b ]] *= flip[b];}} 39991a271a75SMatthew G. Knepley } else { 400097e99dd9SToby Isaac if (perm) {for (b = 0; b < fdof; b++) {array[offset + perm[b]] = varr[b];}} 400197e99dd9SToby Isaac else {for (b = 0; b < fdof; b++) {array[offset + b ] = varr[b];}} 400297e99dd9SToby Isaac if (flip) {for (b = 0; b < fdof; b++) {array[offset + b ] *= flip[b];}} 40031a271a75SMatthew G. Knepley } 400497e99dd9SToby Isaac offset += fdof; 40051a271a75SMatthew G. Knepley } 400697e99dd9SToby Isaac ierr = PetscSectionRestoreFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 40071a271a75SMatthew G. Knepley } 40081a271a75SMatthew G. Knepley *size = offset; 40091a271a75SMatthew G. Knepley PetscFunctionReturn(0); 40101a271a75SMatthew G. Knepley } 40111a271a75SMatthew G. Knepley 4012552f7358SJed Brown /*@C 4013552f7358SJed Brown DMPlexVecGetClosure - Get an array of the values on the closure of 'point' 4014552f7358SJed Brown 4015552f7358SJed Brown Not collective 4016552f7358SJed Brown 4017552f7358SJed Brown Input Parameters: 4018552f7358SJed Brown + dm - The DM 4019552f7358SJed Brown . section - The section describing the layout in v, or NULL to use the default section 4020552f7358SJed Brown . v - The local vector 402122c1ee49SMatthew G. Knepley . point - The point in the DM 402222c1ee49SMatthew G. Knepley . csize - The size of the input values array, or NULL 402322c1ee49SMatthew G. Knepley - values - An array to use for the values, or NULL to have it allocated automatically 4024552f7358SJed Brown 4025552f7358SJed Brown Output Parameters: 402622c1ee49SMatthew G. Knepley + csize - The number of values in the closure 402722c1ee49SMatthew G. Knepley - values - The array of values. If the user provided NULL, it is a borrowed array and should not be freed 402822c1ee49SMatthew G. Knepley 402922c1ee49SMatthew G. Knepley $ Note that DMPlexVecGetClosure/DMPlexVecRestoreClosure only allocates the values array if it set to NULL in the 403022c1ee49SMatthew G. Knepley $ calling function. This is because DMPlexVecGetClosure() is typically called in the inner loop of a Vec or Mat 403122c1ee49SMatthew G. Knepley $ assembly function, and a user may already have allocated storage for this operation. 403222c1ee49SMatthew G. Knepley $ 403322c1ee49SMatthew G. Knepley $ A typical use could be 403422c1ee49SMatthew G. Knepley $ 403522c1ee49SMatthew G. Knepley $ values = NULL; 403622c1ee49SMatthew G. Knepley $ ierr = DMPlexVecGetClosure(dm, NULL, v, p, &clSize, &values);CHKERRQ(ierr); 403722c1ee49SMatthew G. Knepley $ for (cl = 0; cl < clSize; ++cl) { 403822c1ee49SMatthew G. Knepley $ <Compute on closure> 403922c1ee49SMatthew G. Knepley $ } 404022c1ee49SMatthew G. Knepley $ ierr = DMPlexVecRestoreClosure(dm, NULL, v, p, &clSize, &values);CHKERRQ(ierr); 404122c1ee49SMatthew G. Knepley $ 404222c1ee49SMatthew G. Knepley $ or 404322c1ee49SMatthew G. Knepley $ 404422c1ee49SMatthew G. Knepley $ PetscMalloc1(clMaxSize, &values); 404522c1ee49SMatthew G. Knepley $ for (p = pStart; p < pEnd; ++p) { 404622c1ee49SMatthew G. Knepley $ clSize = clMaxSize; 404722c1ee49SMatthew G. Knepley $ ierr = DMPlexVecGetClosure(dm, NULL, v, p, &clSize, &values);CHKERRQ(ierr); 404822c1ee49SMatthew G. Knepley $ for (cl = 0; cl < clSize; ++cl) { 404922c1ee49SMatthew G. Knepley $ <Compute on closure> 405022c1ee49SMatthew G. Knepley $ } 405122c1ee49SMatthew G. Knepley $ } 405222c1ee49SMatthew G. Knepley $ PetscFree(values); 4053552f7358SJed Brown 4054552f7358SJed Brown Fortran Notes: 4055552f7358SJed Brown Since it returns an array, this routine is only available in Fortran 90, and you must 4056552f7358SJed Brown include petsc.h90 in your code. 4057552f7358SJed Brown 4058552f7358SJed Brown The csize argument is not present in the Fortran 90 binding since it is internal to the array. 4059552f7358SJed Brown 4060552f7358SJed Brown Level: intermediate 4061552f7358SJed Brown 4062552f7358SJed Brown .seealso DMPlexVecRestoreClosure(), DMPlexVecSetClosure(), DMPlexMatSetClosure() 4063552f7358SJed Brown @*/ 4064552f7358SJed Brown PetscErrorCode DMPlexVecGetClosure(DM dm, PetscSection section, Vec v, PetscInt point, PetscInt *csize, PetscScalar *values[]) 4065552f7358SJed Brown { 4066552f7358SJed Brown PetscSection clSection; 4067d9917b9dSMatthew G. Knepley IS clPoints; 40688a84db2dSMatthew G. Knepley PetscScalar *array; 40698a84db2dSMatthew G. Knepley const PetscScalar *vArray; 4070552f7358SJed Brown PetscInt *points = NULL; 40718f3be42fSMatthew G. Knepley const PetscInt *clp, *perm; 40721a271a75SMatthew G. Knepley PetscInt depth, numFields, numPoints, size; 4073552f7358SJed Brown PetscErrorCode ierr; 4074552f7358SJed Brown 4075d9917b9dSMatthew G. Knepley PetscFunctionBeginHot; 4076552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4077e87a4003SBarry Smith if (!section) {ierr = DMGetSection(dm, §ion);CHKERRQ(ierr);} 40781a271a75SMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 40791a271a75SMatthew G. Knepley PetscValidHeaderSpecific(v, VEC_CLASSID, 3); 4080552f7358SJed Brown ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 4081552f7358SJed Brown ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 4082552f7358SJed Brown if (depth == 1 && numFields < 2) { 40831a271a75SMatthew G. Knepley ierr = DMPlexVecGetClosure_Depth1_Static(dm, section, v, point, csize, values);CHKERRQ(ierr); 4084552f7358SJed Brown PetscFunctionReturn(0); 4085552f7358SJed Brown } 40861a271a75SMatthew G. Knepley /* Get points */ 4087923c78e0SToby Isaac ierr = DMPlexGetCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 40881fdd32a2SMatthew G. Knepley ierr = PetscSectionGetClosureInversePermutation_Internal(section, (PetscObject) dm, NULL, &perm);CHKERRQ(ierr); 40891a271a75SMatthew G. Knepley /* Get array */ 4090bd6c0d32SMatthew G. Knepley if (!values || !*values) { 40911a271a75SMatthew G. Knepley PetscInt asize = 0, dof, p; 4092552f7358SJed Brown 40931a271a75SMatthew G. Knepley for (p = 0; p < numPoints*2; p += 2) { 4094552f7358SJed Brown ierr = PetscSectionGetDof(section, points[p], &dof);CHKERRQ(ierr); 40951a271a75SMatthew G. Knepley asize += dof; 4096552f7358SJed Brown } 4097bd6c0d32SMatthew G. Knepley if (!values) { 4098923c78e0SToby Isaac ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 40991a271a75SMatthew G. Knepley if (csize) *csize = asize; 4100bd6c0d32SMatthew G. Knepley PetscFunctionReturn(0); 4101bd6c0d32SMatthew G. Knepley } 410269291d52SBarry Smith ierr = DMGetWorkArray(dm, asize, MPIU_SCALAR, &array);CHKERRQ(ierr); 4103d0f6b257SMatthew G. Knepley } else { 4104d0f6b257SMatthew G. Knepley array = *values; 4105d0f6b257SMatthew G. Knepley } 41068a84db2dSMatthew G. Knepley ierr = VecGetArrayRead(v, &vArray);CHKERRQ(ierr); 41071a271a75SMatthew G. Knepley /* Get values */ 410897e99dd9SToby Isaac if (numFields > 0) {ierr = DMPlexVecGetClosure_Fields_Static(dm, section, numPoints, points, numFields, perm, vArray, &size, array);CHKERRQ(ierr);} 410997e99dd9SToby Isaac else {ierr = DMPlexVecGetClosure_Static(dm, section, numPoints, points, perm, vArray, &size, array);CHKERRQ(ierr);} 41101a271a75SMatthew G. Knepley /* Cleanup points */ 4111923c78e0SToby Isaac ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 41121a271a75SMatthew G. Knepley /* Cleanup array */ 41138a84db2dSMatthew G. Knepley ierr = VecRestoreArrayRead(v, &vArray);CHKERRQ(ierr); 4114d0f6b257SMatthew G. Knepley if (!*values) { 4115552f7358SJed Brown if (csize) *csize = size; 4116552f7358SJed Brown *values = array; 4117d0f6b257SMatthew G. Knepley } else { 4118f347f43bSBarry Smith if (size > *csize) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Size of input array %D < actual size %D", *csize, size); 4119d0f6b257SMatthew G. Knepley *csize = size; 4120d0f6b257SMatthew G. Knepley } 4121552f7358SJed Brown PetscFunctionReturn(0); 4122552f7358SJed Brown } 4123552f7358SJed Brown 4124552f7358SJed Brown /*@C 4125552f7358SJed Brown DMPlexVecRestoreClosure - Restore the array of the values on the closure of 'point' 4126552f7358SJed Brown 4127552f7358SJed Brown Not collective 4128552f7358SJed Brown 4129552f7358SJed Brown Input Parameters: 4130552f7358SJed Brown + dm - The DM 41310298fd71SBarry Smith . section - The section describing the layout in v, or NULL to use the default section 4132552f7358SJed Brown . v - The local vector 4133eaf898f9SPatrick Sanan . point - The point in the DM 41340298fd71SBarry Smith . csize - The number of values in the closure, or NULL 4135552f7358SJed Brown - values - The array of values, which is a borrowed array and should not be freed 4136552f7358SJed Brown 413722c1ee49SMatthew 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() 413822c1ee49SMatthew G. Knepley 41393813dfbdSMatthew G Knepley Fortran Notes: 41403813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 41413813dfbdSMatthew G Knepley include petsc.h90 in your code. 41423813dfbdSMatthew G Knepley 41433813dfbdSMatthew G Knepley The csize argument is not present in the Fortran 90 binding since it is internal to the array. 41443813dfbdSMatthew G Knepley 4145552f7358SJed Brown Level: intermediate 4146552f7358SJed Brown 4147552f7358SJed Brown .seealso DMPlexVecGetClosure(), DMPlexVecSetClosure(), DMPlexMatSetClosure() 4148552f7358SJed Brown @*/ 41497c1f9639SMatthew G Knepley PetscErrorCode DMPlexVecRestoreClosure(DM dm, PetscSection section, Vec v, PetscInt point, PetscInt *csize, PetscScalar *values[]) 4150a6dfd86eSKarl Rupp { 4151552f7358SJed Brown PetscInt size = 0; 4152552f7358SJed Brown PetscErrorCode ierr; 4153552f7358SJed Brown 4154552f7358SJed Brown PetscFunctionBegin; 4155552f7358SJed Brown /* Should work without recalculating size */ 415669291d52SBarry Smith ierr = DMRestoreWorkArray(dm, size, MPIU_SCALAR, (void*) values);CHKERRQ(ierr); 4157c9fdaa05SMatthew G. Knepley *values = NULL; 4158552f7358SJed Brown PetscFunctionReturn(0); 4159552f7358SJed Brown } 4160552f7358SJed Brown 4161552f7358SJed Brown PETSC_STATIC_INLINE void add (PetscScalar *x, PetscScalar y) {*x += y;} 4162552f7358SJed Brown PETSC_STATIC_INLINE void insert(PetscScalar *x, PetscScalar y) {*x = y;} 4163552f7358SJed Brown 416497e99dd9SToby 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[]) 4165552f7358SJed Brown { 4166552f7358SJed Brown PetscInt cdof; /* The number of constraints on this point */ 4167552f7358SJed Brown const PetscInt *cdofs; /* The indices of the constrained dofs on this point */ 4168552f7358SJed Brown PetscScalar *a; 4169552f7358SJed Brown PetscInt off, cind = 0, k; 4170552f7358SJed Brown PetscErrorCode ierr; 4171552f7358SJed Brown 4172552f7358SJed Brown PetscFunctionBegin; 4173552f7358SJed Brown ierr = PetscSectionGetConstraintDof(section, point, &cdof);CHKERRQ(ierr); 4174552f7358SJed Brown ierr = PetscSectionGetOffset(section, point, &off);CHKERRQ(ierr); 4175552f7358SJed Brown a = &array[off]; 4176552f7358SJed Brown if (!cdof || setBC) { 417797e99dd9SToby Isaac if (clperm) { 417897e99dd9SToby Isaac if (perm) {for (k = 0; k < dof; ++k) {fuse(&a[k], values[clperm[offset+perm[k]]] * (flip ? flip[perm[k]] : 1.));}} 417997e99dd9SToby Isaac else {for (k = 0; k < dof; ++k) {fuse(&a[k], values[clperm[offset+ k ]] * (flip ? flip[ k ] : 1.));}} 4180552f7358SJed Brown } else { 418197e99dd9SToby Isaac if (perm) {for (k = 0; k < dof; ++k) {fuse(&a[k], values[offset+perm[k]] * (flip ? flip[perm[k]] : 1.));}} 418297e99dd9SToby Isaac else {for (k = 0; k < dof; ++k) {fuse(&a[k], values[offset+ k ] * (flip ? flip[ k ] : 1.));}} 4183552f7358SJed Brown } 4184552f7358SJed Brown } else { 4185552f7358SJed Brown ierr = PetscSectionGetConstraintIndices(section, point, &cdofs);CHKERRQ(ierr); 418697e99dd9SToby Isaac if (clperm) { 418797e99dd9SToby Isaac if (perm) {for (k = 0; k < dof; ++k) { 4188552f7358SJed Brown if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 418997e99dd9SToby Isaac fuse(&a[k], values[clperm[offset+perm[k]]] * (flip ? flip[perm[k]] : 1.)); 4190552f7358SJed Brown } 4191552f7358SJed Brown } else { 4192552f7358SJed Brown for (k = 0; k < dof; ++k) { 4193552f7358SJed Brown if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 419497e99dd9SToby Isaac fuse(&a[k], values[clperm[offset+ k ]] * (flip ? flip[ k ] : 1.)); 419597e99dd9SToby Isaac } 419697e99dd9SToby Isaac } 419797e99dd9SToby Isaac } else { 419897e99dd9SToby Isaac if (perm) { 419997e99dd9SToby Isaac for (k = 0; k < dof; ++k) { 420097e99dd9SToby Isaac if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 420197e99dd9SToby Isaac fuse(&a[k], values[offset+perm[k]] * (flip ? flip[perm[k]] : 1.)); 420297e99dd9SToby Isaac } 420397e99dd9SToby Isaac } else { 420497e99dd9SToby Isaac for (k = 0; k < dof; ++k) { 420597e99dd9SToby Isaac if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 420697e99dd9SToby Isaac fuse(&a[k], values[offset+ k ] * (flip ? flip[ k ] : 1.)); 420797e99dd9SToby Isaac } 4208552f7358SJed Brown } 4209552f7358SJed Brown } 4210552f7358SJed Brown } 4211552f7358SJed Brown PetscFunctionReturn(0); 4212552f7358SJed Brown } 4213552f7358SJed Brown 421497e99dd9SToby 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[]) 4215a5e93ea8SMatthew G. Knepley { 4216a5e93ea8SMatthew G. Knepley PetscInt cdof; /* The number of constraints on this point */ 4217a5e93ea8SMatthew G. Knepley const PetscInt *cdofs; /* The indices of the constrained dofs on this point */ 4218a5e93ea8SMatthew G. Knepley PetscScalar *a; 4219a5e93ea8SMatthew G. Knepley PetscInt off, cind = 0, k; 4220a5e93ea8SMatthew G. Knepley PetscErrorCode ierr; 4221a5e93ea8SMatthew G. Knepley 4222a5e93ea8SMatthew G. Knepley PetscFunctionBegin; 4223a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(section, point, &cdof);CHKERRQ(ierr); 4224a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetOffset(section, point, &off);CHKERRQ(ierr); 4225a5e93ea8SMatthew G. Knepley a = &array[off]; 4226a5e93ea8SMatthew G. Knepley if (cdof) { 4227a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetConstraintIndices(section, point, &cdofs);CHKERRQ(ierr); 422897e99dd9SToby Isaac if (clperm) { 422997e99dd9SToby Isaac if (perm) { 4230a5e93ea8SMatthew G. Knepley for (k = 0; k < dof; ++k) { 4231a5e93ea8SMatthew G. Knepley if ((cind < cdof) && (k == cdofs[cind])) { 423297e99dd9SToby Isaac fuse(&a[k], values[clperm[offset+perm[k]]] * (flip ? flip[perm[k]] : 1.)); 423397e99dd9SToby Isaac cind++; 4234a5e93ea8SMatthew G. Knepley } 4235a5e93ea8SMatthew G. Knepley } 4236a5e93ea8SMatthew G. Knepley } else { 4237a5e93ea8SMatthew G. Knepley for (k = 0; k < dof; ++k) { 4238a5e93ea8SMatthew G. Knepley if ((cind < cdof) && (k == cdofs[cind])) { 423997e99dd9SToby Isaac fuse(&a[k], values[clperm[offset+ k ]] * (flip ? flip[ k ] : 1.)); 424097e99dd9SToby Isaac cind++; 424197e99dd9SToby Isaac } 424297e99dd9SToby Isaac } 424397e99dd9SToby Isaac } 424497e99dd9SToby Isaac } else { 424597e99dd9SToby Isaac if (perm) { 424697e99dd9SToby Isaac for (k = 0; k < dof; ++k) { 424797e99dd9SToby Isaac if ((cind < cdof) && (k == cdofs[cind])) { 424897e99dd9SToby Isaac fuse(&a[k], values[offset+perm[k]] * (flip ? flip[perm[k]] : 1.)); 424997e99dd9SToby Isaac cind++; 425097e99dd9SToby Isaac } 425197e99dd9SToby Isaac } 425297e99dd9SToby Isaac } else { 425397e99dd9SToby Isaac for (k = 0; k < dof; ++k) { 425497e99dd9SToby Isaac if ((cind < cdof) && (k == cdofs[cind])) { 425597e99dd9SToby Isaac fuse(&a[k], values[offset+ k ] * (flip ? flip[ k ] : 1.)); 425697e99dd9SToby Isaac cind++; 425797e99dd9SToby Isaac } 4258a5e93ea8SMatthew G. Knepley } 4259a5e93ea8SMatthew G. Knepley } 4260a5e93ea8SMatthew G. Knepley } 4261a5e93ea8SMatthew G. Knepley } 4262a5e93ea8SMatthew G. Knepley PetscFunctionReturn(0); 4263a5e93ea8SMatthew G. Knepley } 4264a5e93ea8SMatthew G. Knepley 426597e99dd9SToby 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[]) 4266a6dfd86eSKarl Rupp { 4267552f7358SJed Brown PetscScalar *a; 42681a271a75SMatthew G. Knepley PetscInt fdof, foff, fcdof, foffset = *offset; 42691a271a75SMatthew G. Knepley const PetscInt *fcdofs; /* The indices of the constrained dofs for field f on this point */ 427097e99dd9SToby Isaac PetscInt cind = 0, b; 4271552f7358SJed Brown PetscErrorCode ierr; 4272552f7358SJed Brown 4273552f7358SJed Brown PetscFunctionBegin; 4274552f7358SJed Brown ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 4275552f7358SJed Brown ierr = PetscSectionGetFieldConstraintDof(section, point, f, &fcdof);CHKERRQ(ierr); 42761a271a75SMatthew G. Knepley ierr = PetscSectionGetFieldOffset(section, point, f, &foff);CHKERRQ(ierr); 42771a271a75SMatthew G. Knepley a = &array[foff]; 4278552f7358SJed Brown if (!fcdof || setBC) { 427997e99dd9SToby Isaac if (clperm) { 428097e99dd9SToby Isaac if (perm) {for (b = 0; b < fdof; b++) {fuse(&a[b], values[clperm[foffset+perm[b]]] * (flip ? flip[perm[b]] : 1.));}} 428197e99dd9SToby Isaac else {for (b = 0; b < fdof; b++) {fuse(&a[b], values[clperm[foffset+ b ]] * (flip ? flip[ b ] : 1.));}} 4282552f7358SJed Brown } else { 428397e99dd9SToby Isaac if (perm) {for (b = 0; b < fdof; b++) {fuse(&a[b], values[foffset+perm[b]] * (flip ? flip[perm[b]] : 1.));}} 428497e99dd9SToby Isaac else {for (b = 0; b < fdof; b++) {fuse(&a[b], values[foffset+ b ] * (flip ? flip[ b ] : 1.));}} 4285552f7358SJed Brown } 4286552f7358SJed Brown } else { 4287552f7358SJed Brown ierr = PetscSectionGetFieldConstraintIndices(section, point, f, &fcdofs);CHKERRQ(ierr); 428897e99dd9SToby Isaac if (clperm) { 428997e99dd9SToby Isaac if (perm) { 429097e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 429197e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; continue;} 429297e99dd9SToby Isaac fuse(&a[b], values[clperm[foffset+perm[b]]] * (flip ? flip[perm[b]] : 1.)); 4293552f7358SJed Brown } 4294552f7358SJed Brown } else { 429597e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 429697e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; continue;} 429797e99dd9SToby Isaac fuse(&a[b], values[clperm[foffset+ b ]] * (flip ? flip[ b ] : 1.)); 429897e99dd9SToby Isaac } 429997e99dd9SToby Isaac } 430097e99dd9SToby Isaac } else { 430197e99dd9SToby Isaac if (perm) { 430297e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 430397e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; continue;} 430497e99dd9SToby Isaac fuse(&a[b], values[foffset+perm[b]] * (flip ? flip[perm[b]] : 1.)); 430597e99dd9SToby Isaac } 430697e99dd9SToby Isaac } else { 430797e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 430897e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; continue;} 430997e99dd9SToby Isaac fuse(&a[b], values[foffset+ b ] * (flip ? flip[ b ] : 1.)); 4310552f7358SJed Brown } 4311552f7358SJed Brown } 4312552f7358SJed Brown } 4313552f7358SJed Brown } 43141a271a75SMatthew G. Knepley *offset += fdof; 4315552f7358SJed Brown PetscFunctionReturn(0); 4316552f7358SJed Brown } 4317552f7358SJed Brown 4318ba322698SMatthew 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[]) 4319a5e93ea8SMatthew G. Knepley { 4320a5e93ea8SMatthew G. Knepley PetscScalar *a; 43211a271a75SMatthew G. Knepley PetscInt fdof, foff, fcdof, foffset = *offset; 43221a271a75SMatthew G. Knepley const PetscInt *fcdofs; /* The indices of the constrained dofs for field f on this point */ 4323ba322698SMatthew G. Knepley PetscInt cind = 0, ncind = 0, b; 4324ba322698SMatthew G. Knepley PetscBool ncSet, fcSet; 4325a5e93ea8SMatthew G. Knepley PetscErrorCode ierr; 4326a5e93ea8SMatthew G. Knepley 4327a5e93ea8SMatthew G. Knepley PetscFunctionBegin; 4328a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 4329a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetFieldConstraintDof(section, point, f, &fcdof);CHKERRQ(ierr); 43301a271a75SMatthew G. Knepley ierr = PetscSectionGetFieldOffset(section, point, f, &foff);CHKERRQ(ierr); 43311a271a75SMatthew G. Knepley a = &array[foff]; 4332a5e93ea8SMatthew G. Knepley if (fcdof) { 4333ba322698SMatthew G. Knepley /* We just override fcdof and fcdofs with Ncc and comps */ 4334a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetFieldConstraintIndices(section, point, f, &fcdofs);CHKERRQ(ierr); 433597e99dd9SToby Isaac if (clperm) { 433697e99dd9SToby Isaac if (perm) { 4337ba322698SMatthew G. Knepley if (comps) { 4338ba322698SMatthew G. Knepley for (b = 0; b < fdof; b++) { 4339ba322698SMatthew G. Knepley ncSet = fcSet = PETSC_FALSE; 4340ba322698SMatthew G. Knepley if ((ncind < Ncc) && (b == comps[ncind])) {++ncind; ncSet = PETSC_TRUE;} 4341ba322698SMatthew G. Knepley if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; fcSet = PETSC_TRUE;} 4342ba322698SMatthew G. Knepley if (ncSet && fcSet) {fuse(&a[b], values[clperm[foffset+perm[b]]] * (flip ? flip[perm[b]] : 1.));} 4343ba322698SMatthew G. Knepley } 4344ba322698SMatthew G. Knepley } else { 434597e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 434697e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) { 434797e99dd9SToby Isaac fuse(&a[b], values[clperm[foffset+perm[b]]] * (flip ? flip[perm[b]] : 1.)); 4348a5e93ea8SMatthew G. Knepley ++cind; 4349a5e93ea8SMatthew G. Knepley } 4350a5e93ea8SMatthew G. Knepley } 4351ba322698SMatthew G. Knepley } 4352ba322698SMatthew G. Knepley } else { 4353ba322698SMatthew G. Knepley if (comps) { 4354ba322698SMatthew G. Knepley for (b = 0; b < fdof; b++) { 4355ba322698SMatthew G. Knepley ncSet = fcSet = PETSC_FALSE; 4356ba322698SMatthew G. Knepley if ((ncind < Ncc) && (b == comps[ncind])) {++ncind; ncSet = PETSC_TRUE;} 4357ba322698SMatthew G. Knepley if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; fcSet = PETSC_TRUE;} 4358ba322698SMatthew G. Knepley if (ncSet && fcSet) {fuse(&a[b], values[clperm[foffset+ b ]] * (flip ? flip[ b ] : 1.));} 4359ba322698SMatthew G. Knepley } 4360a5e93ea8SMatthew G. Knepley } else { 436197e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 436297e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) { 436397e99dd9SToby Isaac fuse(&a[b], values[clperm[foffset+ b ]] * (flip ? flip[ b ] : 1.)); 436497e99dd9SToby Isaac ++cind; 436597e99dd9SToby Isaac } 436697e99dd9SToby Isaac } 436797e99dd9SToby Isaac } 4368ba322698SMatthew G. Knepley } 436997e99dd9SToby Isaac } else { 437097e99dd9SToby Isaac if (perm) { 4371ba322698SMatthew G. Knepley if (comps) { 4372ba322698SMatthew G. Knepley for (b = 0; b < fdof; b++) { 4373ba322698SMatthew G. Knepley ncSet = fcSet = PETSC_FALSE; 4374ba322698SMatthew G. Knepley if ((ncind < Ncc) && (b == comps[ncind])) {++ncind; ncSet = PETSC_TRUE;} 4375ba322698SMatthew G. Knepley if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; fcSet = PETSC_TRUE;} 4376ba322698SMatthew G. Knepley if (ncSet && fcSet) {fuse(&a[b], values[foffset+perm[b]] * (flip ? flip[perm[b]] : 1.));} 4377ba322698SMatthew G. Knepley } 4378ba322698SMatthew G. Knepley } else { 437997e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 438097e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) { 438197e99dd9SToby Isaac fuse(&a[b], values[foffset+perm[b]] * (flip ? flip[perm[b]] : 1.)); 438297e99dd9SToby Isaac ++cind; 438397e99dd9SToby Isaac } 438497e99dd9SToby Isaac } 4385ba322698SMatthew G. Knepley } 4386ba322698SMatthew G. Knepley } else { 4387ba322698SMatthew G. Knepley if (comps) { 4388ba322698SMatthew G. Knepley for (b = 0; b < fdof; b++) { 4389ba322698SMatthew G. Knepley ncSet = fcSet = PETSC_FALSE; 4390ba322698SMatthew G. Knepley if ((ncind < Ncc) && (b == comps[ncind])) {++ncind; ncSet = PETSC_TRUE;} 4391ba322698SMatthew G. Knepley if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; fcSet = PETSC_TRUE;} 4392ba322698SMatthew G. Knepley if (ncSet && fcSet) {fuse(&a[b], values[foffset+ b ] * (flip ? flip[ b ] : 1.));} 4393ba322698SMatthew G. Knepley } 439497e99dd9SToby Isaac } else { 439597e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 439697e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) { 439797e99dd9SToby Isaac fuse(&a[b], values[foffset+ b ] * (flip ? flip[ b ] : 1.)); 4398a5e93ea8SMatthew G. Knepley ++cind; 4399a5e93ea8SMatthew G. Knepley } 4400a5e93ea8SMatthew G. Knepley } 4401a5e93ea8SMatthew G. Knepley } 4402a5e93ea8SMatthew G. Knepley } 4403a5e93ea8SMatthew G. Knepley } 4404ba322698SMatthew G. Knepley } 44051a271a75SMatthew G. Knepley *offset += fdof; 4406a5e93ea8SMatthew G. Knepley PetscFunctionReturn(0); 4407a5e93ea8SMatthew G. Knepley } 4408a5e93ea8SMatthew G. Knepley 44098f3be42fSMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode DMPlexVecSetClosure_Depth1_Static(DM dm, PetscSection section, Vec v, PetscInt point, const PetscScalar values[], InsertMode mode) 4410a6dfd86eSKarl Rupp { 4411552f7358SJed Brown PetscScalar *array; 44121b406b76SMatthew G. Knepley const PetscInt *cone, *coneO; 44131b406b76SMatthew G. Knepley PetscInt pStart, pEnd, p, numPoints, off, dof; 4414552f7358SJed Brown PetscErrorCode ierr; 4415552f7358SJed Brown 44161b406b76SMatthew G. Knepley PetscFunctionBeginHot; 4417b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 4418b6ebb6e6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, point, &numPoints);CHKERRQ(ierr); 4419b6ebb6e6SMatthew G. Knepley ierr = DMPlexGetCone(dm, point, &cone);CHKERRQ(ierr); 4420b6ebb6e6SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, point, &coneO);CHKERRQ(ierr); 4421b6ebb6e6SMatthew G. Knepley ierr = VecGetArray(v, &array);CHKERRQ(ierr); 4422b6ebb6e6SMatthew G. Knepley for (p = 0, off = 0; p <= numPoints; ++p, off += dof) { 4423b6ebb6e6SMatthew G. Knepley const PetscInt cp = !p ? point : cone[p-1]; 4424b6ebb6e6SMatthew G. Knepley const PetscInt o = !p ? 0 : coneO[p-1]; 4425b6ebb6e6SMatthew G. Knepley 4426b6ebb6e6SMatthew G. Knepley if ((cp < pStart) || (cp >= pEnd)) {dof = 0; continue;} 4427b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetDof(section, cp, &dof);CHKERRQ(ierr); 4428b6ebb6e6SMatthew G. Knepley /* ADD_VALUES */ 4429b6ebb6e6SMatthew G. Knepley { 4430b6ebb6e6SMatthew G. Knepley const PetscInt *cdofs; /* The indices of the constrained dofs on this point */ 4431b6ebb6e6SMatthew G. Knepley PetscScalar *a; 4432b6ebb6e6SMatthew G. Knepley PetscInt cdof, coff, cind = 0, k; 4433b6ebb6e6SMatthew G. Knepley 4434b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(section, cp, &cdof);CHKERRQ(ierr); 4435b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetOffset(section, cp, &coff);CHKERRQ(ierr); 4436b6ebb6e6SMatthew G. Knepley a = &array[coff]; 4437b6ebb6e6SMatthew G. Knepley if (!cdof) { 4438b6ebb6e6SMatthew G. Knepley if (o >= 0) { 4439b6ebb6e6SMatthew G. Knepley for (k = 0; k < dof; ++k) { 4440b6ebb6e6SMatthew G. Knepley a[k] += values[off+k]; 4441b6ebb6e6SMatthew G. Knepley } 4442b6ebb6e6SMatthew G. Knepley } else { 4443b6ebb6e6SMatthew G. Knepley for (k = 0; k < dof; ++k) { 4444b6ebb6e6SMatthew G. Knepley a[k] += values[off+dof-k-1]; 4445b6ebb6e6SMatthew G. Knepley } 4446b6ebb6e6SMatthew G. Knepley } 4447b6ebb6e6SMatthew G. Knepley } else { 4448b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetConstraintIndices(section, cp, &cdofs);CHKERRQ(ierr); 4449b6ebb6e6SMatthew G. Knepley if (o >= 0) { 4450b6ebb6e6SMatthew G. Knepley for (k = 0; k < dof; ++k) { 4451b6ebb6e6SMatthew G. Knepley if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 4452b6ebb6e6SMatthew G. Knepley a[k] += values[off+k]; 4453b6ebb6e6SMatthew G. Knepley } 4454b6ebb6e6SMatthew G. Knepley } else { 4455b6ebb6e6SMatthew G. Knepley for (k = 0; k < dof; ++k) { 4456b6ebb6e6SMatthew G. Knepley if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 4457b6ebb6e6SMatthew G. Knepley a[k] += values[off+dof-k-1]; 4458b6ebb6e6SMatthew G. Knepley } 4459b6ebb6e6SMatthew G. Knepley } 4460b6ebb6e6SMatthew G. Knepley } 4461b6ebb6e6SMatthew G. Knepley } 4462b6ebb6e6SMatthew G. Knepley } 4463b6ebb6e6SMatthew G. Knepley ierr = VecRestoreArray(v, &array);CHKERRQ(ierr); 4464b6ebb6e6SMatthew G. Knepley PetscFunctionReturn(0); 4465b6ebb6e6SMatthew G. Knepley } 44661b406b76SMatthew G. Knepley 44671b406b76SMatthew G. Knepley /*@C 44681b406b76SMatthew G. Knepley DMPlexVecSetClosure - Set an array of the values on the closure of 'point' 44691b406b76SMatthew G. Knepley 44701b406b76SMatthew G. Knepley Not collective 44711b406b76SMatthew G. Knepley 44721b406b76SMatthew G. Knepley Input Parameters: 44731b406b76SMatthew G. Knepley + dm - The DM 44741b406b76SMatthew G. Knepley . section - The section describing the layout in v, or NULL to use the default section 44751b406b76SMatthew G. Knepley . v - The local vector 4476eaf898f9SPatrick Sanan . point - The point in the DM 44771b406b76SMatthew G. Knepley . values - The array of values 447822c1ee49SMatthew 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, 447922c1ee49SMatthew G. Knepley where INSERT_ALL_VALUES and ADD_ALL_VALUES also overwrite boundary conditions. 44801b406b76SMatthew G. Knepley 44811b406b76SMatthew G. Knepley Fortran Notes: 44821b406b76SMatthew G. Knepley This routine is only available in Fortran 90, and you must include petsc.h90 in your code. 44831b406b76SMatthew G. Knepley 44841b406b76SMatthew G. Knepley Level: intermediate 44851b406b76SMatthew G. Knepley 44861b406b76SMatthew G. Knepley .seealso DMPlexVecGetClosure(), DMPlexMatSetClosure() 44871b406b76SMatthew G. Knepley @*/ 44881b406b76SMatthew G. Knepley PetscErrorCode DMPlexVecSetClosure(DM dm, PetscSection section, Vec v, PetscInt point, const PetscScalar values[], InsertMode mode) 44891b406b76SMatthew G. Knepley { 44901b406b76SMatthew G. Knepley PetscSection clSection; 44911b406b76SMatthew G. Knepley IS clPoints; 44921b406b76SMatthew G. Knepley PetscScalar *array; 44931b406b76SMatthew G. Knepley PetscInt *points = NULL; 449497e99dd9SToby Isaac const PetscInt *clp, *clperm; 44951a271a75SMatthew G. Knepley PetscInt depth, numFields, numPoints, p; 44961b406b76SMatthew G. Knepley PetscErrorCode ierr; 44971b406b76SMatthew G. Knepley 44981a271a75SMatthew G. Knepley PetscFunctionBeginHot; 44991b406b76SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4500e87a4003SBarry Smith if (!section) {ierr = DMGetSection(dm, §ion);CHKERRQ(ierr);} 45011a271a75SMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 45021a271a75SMatthew G. Knepley PetscValidHeaderSpecific(v, VEC_CLASSID, 3); 45031b406b76SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 45041b406b76SMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 45051b406b76SMatthew G. Knepley if (depth == 1 && numFields < 2 && mode == ADD_VALUES) { 45068f3be42fSMatthew G. Knepley ierr = DMPlexVecSetClosure_Depth1_Static(dm, section, v, point, values, mode);CHKERRQ(ierr); 45071b406b76SMatthew G. Knepley PetscFunctionReturn(0); 45081b406b76SMatthew G. Knepley } 45091a271a75SMatthew G. Knepley /* Get points */ 451097e99dd9SToby Isaac ierr = PetscSectionGetClosureInversePermutation_Internal(section, (PetscObject) dm, NULL, &clperm);CHKERRQ(ierr); 4511923c78e0SToby Isaac ierr = DMPlexGetCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 45121a271a75SMatthew G. Knepley /* Get array */ 4513552f7358SJed Brown ierr = VecGetArray(v, &array);CHKERRQ(ierr); 45141a271a75SMatthew G. Knepley /* Get values */ 4515ef90cfe2SMatthew G. Knepley if (numFields > 0) { 451697e99dd9SToby Isaac PetscInt offset = 0, f; 4517552f7358SJed Brown for (f = 0; f < numFields; ++f) { 451897e99dd9SToby Isaac const PetscInt **perms = NULL; 451997e99dd9SToby Isaac const PetscScalar **flips = NULL; 452097e99dd9SToby Isaac 452197e99dd9SToby Isaac ierr = PetscSectionGetFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 4522552f7358SJed Brown switch (mode) { 4523552f7358SJed Brown case INSERT_VALUES: 452497e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 452597e99dd9SToby Isaac const PetscInt point = points[2*p]; 452697e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 452797e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 452897e99dd9SToby Isaac updatePointFields_private(section, point, perm, flip, f, insert, PETSC_FALSE, clperm, values, &offset, array); 4529552f7358SJed Brown } break; 4530552f7358SJed Brown case INSERT_ALL_VALUES: 453197e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 453297e99dd9SToby Isaac const PetscInt point = points[2*p]; 453397e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 453497e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 453597e99dd9SToby Isaac updatePointFields_private(section, point, perm, flip, f, insert, PETSC_TRUE, clperm, values, &offset, array); 4536552f7358SJed Brown } break; 4537a5e93ea8SMatthew G. Knepley case INSERT_BC_VALUES: 453897e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 453997e99dd9SToby Isaac const PetscInt point = points[2*p]; 454097e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 454197e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 4542ba322698SMatthew G. Knepley updatePointFieldsBC_private(section, point, perm, flip, f, -1, NULL, insert, clperm, values, &offset, array); 4543a5e93ea8SMatthew G. Knepley } break; 4544552f7358SJed Brown case ADD_VALUES: 454597e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 454697e99dd9SToby Isaac const PetscInt point = points[2*p]; 454797e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 454897e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 454997e99dd9SToby Isaac updatePointFields_private(section, point, perm, flip, f, add, PETSC_FALSE, clperm, values, &offset, array); 4550552f7358SJed Brown } break; 4551552f7358SJed Brown case ADD_ALL_VALUES: 455297e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 455397e99dd9SToby Isaac const PetscInt point = points[2*p]; 455497e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 455597e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 455697e99dd9SToby Isaac updatePointFields_private(section, point, perm, flip, f, add, PETSC_TRUE, clperm, values, &offset, array); 4557552f7358SJed Brown } break; 4558304ab55fSMatthew G. Knepley case ADD_BC_VALUES: 455997e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 456097e99dd9SToby Isaac const PetscInt point = points[2*p]; 456197e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 456297e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 4563ba322698SMatthew G. Knepley updatePointFieldsBC_private(section, point, perm, flip, f, -1, NULL, add, clperm, values, &offset, array); 4564304ab55fSMatthew G. Knepley } break; 4565552f7358SJed Brown default: 4566f347f43bSBarry Smith SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insert mode %d", mode); 4567552f7358SJed Brown } 456897e99dd9SToby Isaac ierr = PetscSectionRestoreFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 45691a271a75SMatthew G. Knepley } 4570552f7358SJed Brown } else { 45711a271a75SMatthew G. Knepley PetscInt dof, off; 457297e99dd9SToby Isaac const PetscInt **perms = NULL; 457397e99dd9SToby Isaac const PetscScalar **flips = NULL; 45741a271a75SMatthew G. Knepley 457597e99dd9SToby Isaac ierr = PetscSectionGetPointSyms(section,numPoints,points,&perms,&flips);CHKERRQ(ierr); 4576552f7358SJed Brown switch (mode) { 4577552f7358SJed Brown case INSERT_VALUES: 457897e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 457997e99dd9SToby Isaac const PetscInt point = points[2*p]; 458097e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 458197e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 458297e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 458397e99dd9SToby Isaac updatePoint_private(section, point, dof, insert, PETSC_FALSE, perm, flip, clperm, values, off, array); 4584552f7358SJed Brown } break; 4585552f7358SJed Brown case INSERT_ALL_VALUES: 458697e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 458797e99dd9SToby Isaac const PetscInt point = points[2*p]; 458897e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 458997e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 459097e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 459197e99dd9SToby Isaac updatePoint_private(section, point, dof, insert, PETSC_TRUE, perm, flip, clperm, values, off, array); 4592552f7358SJed Brown } break; 4593a5e93ea8SMatthew G. Knepley case INSERT_BC_VALUES: 459497e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 459597e99dd9SToby Isaac const PetscInt point = points[2*p]; 459697e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 459797e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 459897e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 459997e99dd9SToby Isaac updatePointBC_private(section, point, dof, insert, perm, flip, clperm, values, off, array); 4600a5e93ea8SMatthew G. Knepley } break; 4601552f7358SJed Brown case ADD_VALUES: 460297e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 460397e99dd9SToby Isaac const PetscInt point = points[2*p]; 460497e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 460597e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 460697e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 460797e99dd9SToby Isaac updatePoint_private(section, point, dof, add, PETSC_FALSE, perm, flip, clperm, values, off, array); 4608552f7358SJed Brown } break; 4609552f7358SJed Brown case ADD_ALL_VALUES: 461097e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 461197e99dd9SToby Isaac const PetscInt point = points[2*p]; 461297e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 461397e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 461497e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 461597e99dd9SToby Isaac updatePoint_private(section, point, dof, add, PETSC_TRUE, perm, flip, clperm, values, off, array); 4616552f7358SJed Brown } break; 4617304ab55fSMatthew G. Knepley case ADD_BC_VALUES: 461897e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 461997e99dd9SToby Isaac const PetscInt point = points[2*p]; 462097e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 462197e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 462297e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 462397e99dd9SToby Isaac updatePointBC_private(section, point, dof, add, perm, flip, clperm, values, off, array); 4624304ab55fSMatthew G. Knepley } break; 4625552f7358SJed Brown default: 4626f347f43bSBarry Smith SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insert mode %d", mode); 4627552f7358SJed Brown } 462897e99dd9SToby Isaac ierr = PetscSectionRestorePointSyms(section,numPoints,points,&perms,&flips);CHKERRQ(ierr); 4629552f7358SJed Brown } 46301a271a75SMatthew G. Knepley /* Cleanup points */ 4631923c78e0SToby Isaac ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 46321a271a75SMatthew G. Knepley /* Cleanup array */ 4633552f7358SJed Brown ierr = VecRestoreArray(v, &array);CHKERRQ(ierr); 4634552f7358SJed Brown PetscFunctionReturn(0); 4635552f7358SJed Brown } 4636552f7358SJed Brown 4637ba322698SMatthew 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) 4638e07394fbSMatthew G. Knepley { 4639e07394fbSMatthew G. Knepley PetscSection clSection; 4640e07394fbSMatthew G. Knepley IS clPoints; 4641e07394fbSMatthew G. Knepley PetscScalar *array; 4642e07394fbSMatthew G. Knepley PetscInt *points = NULL; 4643b04c866fSMatthew G. Knepley const PetscInt *clp, *clperm; 4644e07394fbSMatthew G. Knepley PetscInt numFields, numPoints, p; 464597e99dd9SToby Isaac PetscInt offset = 0, f; 4646e07394fbSMatthew G. Knepley PetscErrorCode ierr; 4647e07394fbSMatthew G. Knepley 4648e07394fbSMatthew G. Knepley PetscFunctionBeginHot; 4649e07394fbSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4650e87a4003SBarry Smith if (!section) {ierr = DMGetSection(dm, §ion);CHKERRQ(ierr);} 4651e07394fbSMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 4652e07394fbSMatthew G. Knepley PetscValidHeaderSpecific(v, VEC_CLASSID, 3); 4653e07394fbSMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 4654e07394fbSMatthew G. Knepley /* Get points */ 4655b04c866fSMatthew G. Knepley ierr = PetscSectionGetClosureInversePermutation_Internal(section, (PetscObject) dm, NULL, &clperm);CHKERRQ(ierr); 4656923c78e0SToby Isaac ierr = DMPlexGetCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 4657e07394fbSMatthew G. Knepley /* Get array */ 4658e07394fbSMatthew G. Knepley ierr = VecGetArray(v, &array);CHKERRQ(ierr); 4659e07394fbSMatthew G. Knepley /* Get values */ 4660e07394fbSMatthew G. Knepley for (f = 0; f < numFields; ++f) { 466197e99dd9SToby Isaac const PetscInt **perms = NULL; 466297e99dd9SToby Isaac const PetscScalar **flips = NULL; 466397e99dd9SToby Isaac 4664e07394fbSMatthew G. Knepley if (!fieldActive[f]) { 4665e07394fbSMatthew G. Knepley for (p = 0; p < numPoints*2; p += 2) { 4666e07394fbSMatthew G. Knepley PetscInt fdof; 4667e07394fbSMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, points[p], f, &fdof);CHKERRQ(ierr); 4668e07394fbSMatthew G. Knepley offset += fdof; 4669e07394fbSMatthew G. Knepley } 4670e07394fbSMatthew G. Knepley continue; 4671e07394fbSMatthew G. Knepley } 467297e99dd9SToby Isaac ierr = PetscSectionGetFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 4673e07394fbSMatthew G. Knepley switch (mode) { 4674e07394fbSMatthew G. Knepley case INSERT_VALUES: 467597e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 467697e99dd9SToby Isaac const PetscInt point = points[2*p]; 467797e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 467897e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 4679b04c866fSMatthew G. Knepley updatePointFields_private(section, point, perm, flip, f, insert, PETSC_FALSE, clperm, values, &offset, array); 4680e07394fbSMatthew G. Knepley } break; 4681e07394fbSMatthew G. Knepley case INSERT_ALL_VALUES: 468297e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 468397e99dd9SToby Isaac const PetscInt point = points[2*p]; 468497e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 468597e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 4686b04c866fSMatthew G. Knepley updatePointFields_private(section, point, perm, flip, f, insert, PETSC_TRUE, clperm, values, &offset, array); 4687e07394fbSMatthew G. Knepley } break; 4688e07394fbSMatthew G. Knepley case INSERT_BC_VALUES: 468997e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 469097e99dd9SToby Isaac const PetscInt point = points[2*p]; 469197e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 469297e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 4693ba322698SMatthew G. Knepley updatePointFieldsBC_private(section, point, perm, flip, f, Ncc, comps, insert, clperm, values, &offset, array); 4694e07394fbSMatthew G. Knepley } break; 4695e07394fbSMatthew G. Knepley case ADD_VALUES: 469697e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 469797e99dd9SToby Isaac const PetscInt point = points[2*p]; 469897e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 469997e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 4700b04c866fSMatthew G. Knepley updatePointFields_private(section, point, perm, flip, f, add, PETSC_FALSE, clperm, values, &offset, array); 4701e07394fbSMatthew G. Knepley } break; 4702e07394fbSMatthew G. Knepley case ADD_ALL_VALUES: 470397e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 470497e99dd9SToby Isaac const PetscInt point = points[2*p]; 470597e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 470697e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 4707b04c866fSMatthew G. Knepley updatePointFields_private(section, point, perm, flip, f, add, PETSC_TRUE, clperm, values, &offset, array); 4708e07394fbSMatthew G. Knepley } break; 4709e07394fbSMatthew G. Knepley default: 4710f347f43bSBarry Smith SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insert mode %d", mode); 4711e07394fbSMatthew G. Knepley } 471297e99dd9SToby Isaac ierr = PetscSectionRestoreFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 4713e07394fbSMatthew G. Knepley } 4714e07394fbSMatthew G. Knepley /* Cleanup points */ 4715923c78e0SToby Isaac ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 4716e07394fbSMatthew G. Knepley /* Cleanup array */ 4717e07394fbSMatthew G. Knepley ierr = VecRestoreArray(v, &array);CHKERRQ(ierr); 4718e07394fbSMatthew G. Knepley PetscFunctionReturn(0); 4719e07394fbSMatthew G. Knepley } 4720e07394fbSMatthew G. Knepley 47217cd05799SMatthew G. Knepley static PetscErrorCode DMPlexPrintMatSetValues(PetscViewer viewer, Mat A, PetscInt point, PetscInt numRIndices, const PetscInt rindices[], PetscInt numCIndices, const PetscInt cindices[], const PetscScalar values[]) 4722552f7358SJed Brown { 4723552f7358SJed Brown PetscMPIInt rank; 4724552f7358SJed Brown PetscInt i, j; 4725552f7358SJed Brown PetscErrorCode ierr; 4726552f7358SJed Brown 4727552f7358SJed Brown PetscFunctionBegin; 472882f516ccSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)A), &rank);CHKERRQ(ierr); 4729eaf898f9SPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer, "[%d]mat for point %D\n", rank, point);CHKERRQ(ierr); 4730e4b003c7SBarry Smith for (i = 0; i < numRIndices; i++) {ierr = PetscViewerASCIIPrintf(viewer, "[%d]mat row indices[%D] = %D\n", rank, i, rindices[i]);CHKERRQ(ierr);} 4731e4b003c7SBarry Smith for (i = 0; i < numCIndices; i++) {ierr = PetscViewerASCIIPrintf(viewer, "[%d]mat col indices[%D] = %D\n", rank, i, cindices[i]);CHKERRQ(ierr);} 4732b0ecff45SMatthew G. Knepley numCIndices = numCIndices ? numCIndices : numRIndices; 4733b0ecff45SMatthew G. Knepley for (i = 0; i < numRIndices; i++) { 4734e4b003c7SBarry Smith ierr = PetscViewerASCIIPrintf(viewer, "[%d]", rank);CHKERRQ(ierr); 4735b0ecff45SMatthew G. Knepley for (j = 0; j < numCIndices; j++) { 4736519f805aSKarl Rupp #if defined(PETSC_USE_COMPLEX) 47377eba1a17SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " (%g,%g)", (double)PetscRealPart(values[i*numCIndices+j]), (double)PetscImaginaryPart(values[i*numCIndices+j]));CHKERRQ(ierr); 4738552f7358SJed Brown #else 4739b0ecff45SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " %g", (double)values[i*numCIndices+j]);CHKERRQ(ierr); 4740552f7358SJed Brown #endif 4741552f7358SJed Brown } 474277a6746dSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, "\n");CHKERRQ(ierr); 4743552f7358SJed Brown } 4744552f7358SJed Brown PetscFunctionReturn(0); 4745552f7358SJed Brown } 4746552f7358SJed Brown 4747552f7358SJed Brown /* . off - The global offset of this point */ 47484acb8e1eSToby Isaac PetscErrorCode DMPlexGetIndicesPoint_Internal(PetscSection section, PetscInt point, PetscInt off, PetscInt *loff, PetscBool setBC, const PetscInt perm[], PetscInt indices[]) 4749a6dfd86eSKarl Rupp { 4750e6ccafaeSMatthew G Knepley PetscInt dof; /* The number of unknowns on this point */ 4751552f7358SJed Brown PetscInt cdof; /* The number of constraints on this point */ 4752552f7358SJed Brown const PetscInt *cdofs; /* The indices of the constrained dofs on this point */ 4753552f7358SJed Brown PetscInt cind = 0, k; 4754552f7358SJed Brown PetscErrorCode ierr; 4755552f7358SJed Brown 4756552f7358SJed Brown PetscFunctionBegin; 4757552f7358SJed Brown ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 4758552f7358SJed Brown ierr = PetscSectionGetConstraintDof(section, point, &cdof);CHKERRQ(ierr); 4759552f7358SJed Brown if (!cdof || setBC) { 47604acb8e1eSToby Isaac if (perm) { 47614acb8e1eSToby Isaac for (k = 0; k < dof; k++) indices[*loff+perm[k]] = off + k; 4762552f7358SJed Brown } else { 47634acb8e1eSToby Isaac for (k = 0; k < dof; k++) indices[*loff+k] = off + k; 4764552f7358SJed Brown } 4765552f7358SJed Brown } else { 4766552f7358SJed Brown ierr = PetscSectionGetConstraintIndices(section, point, &cdofs);CHKERRQ(ierr); 47674acb8e1eSToby Isaac if (perm) { 47684acb8e1eSToby Isaac for (k = 0; k < dof; ++k) { 47694acb8e1eSToby Isaac if ((cind < cdof) && (k == cdofs[cind])) { 47704acb8e1eSToby Isaac /* Insert check for returning constrained indices */ 47714acb8e1eSToby Isaac indices[*loff+perm[k]] = -(off+k+1); 47724acb8e1eSToby Isaac ++cind; 47734acb8e1eSToby Isaac } else { 47744acb8e1eSToby Isaac indices[*loff+perm[k]] = off+k-cind; 47754acb8e1eSToby Isaac } 47764acb8e1eSToby Isaac } 47774acb8e1eSToby Isaac } else { 4778552f7358SJed Brown for (k = 0; k < dof; ++k) { 4779552f7358SJed Brown if ((cind < cdof) && (k == cdofs[cind])) { 4780552f7358SJed Brown /* Insert check for returning constrained indices */ 4781e6ccafaeSMatthew G Knepley indices[*loff+k] = -(off+k+1); 4782552f7358SJed Brown ++cind; 4783552f7358SJed Brown } else { 4784e6ccafaeSMatthew G Knepley indices[*loff+k] = off+k-cind; 4785552f7358SJed Brown } 4786552f7358SJed Brown } 4787552f7358SJed Brown } 4788552f7358SJed Brown } 4789e6ccafaeSMatthew G Knepley *loff += dof; 4790552f7358SJed Brown PetscFunctionReturn(0); 4791552f7358SJed Brown } 4792552f7358SJed Brown 47937e29afd2SMatthew G. Knepley /* 47947e29afd2SMatthew G. Knepley This version only believes the point offset from the globalSection 47957e29afd2SMatthew G. Knepley 47967e29afd2SMatthew G. Knepley . off - The global offset of this point 47977e29afd2SMatthew G. Knepley */ 47984acb8e1eSToby Isaac PetscErrorCode DMPlexGetIndicesPointFields_Internal(PetscSection section, PetscInt point, PetscInt off, PetscInt foffs[], PetscBool setBC, const PetscInt ***perms, PetscInt permsoff, PetscInt indices[]) 4799a6dfd86eSKarl Rupp { 4800552f7358SJed Brown PetscInt numFields, foff, f; 4801552f7358SJed Brown PetscErrorCode ierr; 4802552f7358SJed Brown 4803552f7358SJed Brown PetscFunctionBegin; 4804552f7358SJed Brown ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 4805552f7358SJed Brown for (f = 0, foff = 0; f < numFields; ++f) { 48064acb8e1eSToby Isaac PetscInt fdof, cfdof; 4807552f7358SJed Brown const PetscInt *fcdofs; /* The indices of the constrained dofs for field f on this point */ 48084acb8e1eSToby Isaac PetscInt cind = 0, b; 48094acb8e1eSToby Isaac const PetscInt *perm = (perms && perms[f]) ? perms[f][permsoff] : NULL; 4810552f7358SJed Brown 4811552f7358SJed Brown ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 4812552f7358SJed Brown ierr = PetscSectionGetFieldConstraintDof(section, point, f, &cfdof);CHKERRQ(ierr); 4813552f7358SJed Brown if (!cfdof || setBC) { 48144acb8e1eSToby Isaac if (perm) {for (b = 0; b < fdof; b++) {indices[foffs[f]+perm[b]] = off+foff+b;}} 48154acb8e1eSToby Isaac else {for (b = 0; b < fdof; b++) {indices[foffs[f]+ b ] = off+foff+b;}} 4816552f7358SJed Brown } else { 4817552f7358SJed Brown ierr = PetscSectionGetFieldConstraintIndices(section, point, f, &fcdofs);CHKERRQ(ierr); 48184acb8e1eSToby Isaac if (perm) { 48194acb8e1eSToby Isaac for (b = 0; b < fdof; b++) { 48204acb8e1eSToby Isaac if ((cind < cfdof) && (b == fcdofs[cind])) { 48214acb8e1eSToby Isaac indices[foffs[f]+perm[b]] = -(off+foff+b+1); 4822552f7358SJed Brown ++cind; 4823552f7358SJed Brown } else { 48244acb8e1eSToby Isaac indices[foffs[f]+perm[b]] = off+foff+b-cind; 4825552f7358SJed Brown } 4826552f7358SJed Brown } 4827552f7358SJed Brown } else { 48284acb8e1eSToby Isaac for (b = 0; b < fdof; b++) { 48294acb8e1eSToby Isaac if ((cind < cfdof) && (b == fcdofs[cind])) { 48304acb8e1eSToby Isaac indices[foffs[f]+b] = -(off+foff+b+1); 4831552f7358SJed Brown ++cind; 4832552f7358SJed Brown } else { 48334acb8e1eSToby Isaac indices[foffs[f]+b] = off+foff+b-cind; 4834552f7358SJed Brown } 4835552f7358SJed Brown } 4836552f7358SJed Brown } 4837552f7358SJed Brown } 4838a9096520SToby Isaac foff += (setBC ? fdof : (fdof - cfdof)); 4839552f7358SJed Brown foffs[f] += fdof; 4840552f7358SJed Brown } 4841552f7358SJed Brown PetscFunctionReturn(0); 4842552f7358SJed Brown } 4843552f7358SJed Brown 48447e29afd2SMatthew G. Knepley /* 48457e29afd2SMatthew G. Knepley This version believes the globalSection offsets for each field, rather than just the point offset 48467e29afd2SMatthew G. Knepley 48477e29afd2SMatthew G. Knepley . foffs - The offset into 'indices' for each field, since it is segregated by field 48487e29afd2SMatthew G. Knepley */ 48497e29afd2SMatthew G. Knepley PetscErrorCode DMPlexGetIndicesPointFieldsSplit_Internal(PetscSection section, PetscSection globalSection, PetscInt point, PetscInt foffs[], PetscBool setBC, const PetscInt ***perms, PetscInt permsoff, PetscInt indices[]) 48507e29afd2SMatthew G. Knepley { 48517e29afd2SMatthew G. Knepley PetscInt numFields, foff, f; 48527e29afd2SMatthew G. Knepley PetscErrorCode ierr; 48537e29afd2SMatthew G. Knepley 48547e29afd2SMatthew G. Knepley PetscFunctionBegin; 48557e29afd2SMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 48567e29afd2SMatthew G. Knepley for (f = 0; f < numFields; ++f) { 48577e29afd2SMatthew G. Knepley PetscInt fdof, cfdof; 48587e29afd2SMatthew G. Knepley const PetscInt *fcdofs; /* The indices of the constrained dofs for field f on this point */ 48597e29afd2SMatthew G. Knepley PetscInt cind = 0, b; 48607e29afd2SMatthew G. Knepley const PetscInt *perm = (perms && perms[f]) ? perms[f][permsoff] : NULL; 48617e29afd2SMatthew G. Knepley 48627e29afd2SMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 48637e29afd2SMatthew G. Knepley ierr = PetscSectionGetFieldConstraintDof(section, point, f, &cfdof);CHKERRQ(ierr); 48647e29afd2SMatthew G. Knepley ierr = PetscSectionGetFieldOffset(globalSection, point, f, &foff);CHKERRQ(ierr); 48657e29afd2SMatthew G. Knepley if (!cfdof || setBC) { 48667e29afd2SMatthew G. Knepley if (perm) {for (b = 0; b < fdof; b++) {indices[foffs[f]+perm[b]] = foff+b;}} 48677e29afd2SMatthew G. Knepley else {for (b = 0; b < fdof; b++) {indices[foffs[f]+ b ] = foff+b;}} 48687e29afd2SMatthew G. Knepley } else { 48697e29afd2SMatthew G. Knepley ierr = PetscSectionGetFieldConstraintIndices(section, point, f, &fcdofs);CHKERRQ(ierr); 48707e29afd2SMatthew G. Knepley if (perm) { 48717e29afd2SMatthew G. Knepley for (b = 0; b < fdof; b++) { 48727e29afd2SMatthew G. Knepley if ((cind < cfdof) && (b == fcdofs[cind])) { 48737e29afd2SMatthew G. Knepley indices[foffs[f]+perm[b]] = -(foff+b+1); 48747e29afd2SMatthew G. Knepley ++cind; 48757e29afd2SMatthew G. Knepley } else { 48767e29afd2SMatthew G. Knepley indices[foffs[f]+perm[b]] = foff+b-cind; 48777e29afd2SMatthew G. Knepley } 48787e29afd2SMatthew G. Knepley } 48797e29afd2SMatthew G. Knepley } else { 48807e29afd2SMatthew G. Knepley for (b = 0; b < fdof; b++) { 48817e29afd2SMatthew G. Knepley if ((cind < cfdof) && (b == fcdofs[cind])) { 48827e29afd2SMatthew G. Knepley indices[foffs[f]+b] = -(foff+b+1); 48837e29afd2SMatthew G. Knepley ++cind; 48847e29afd2SMatthew G. Knepley } else { 48857e29afd2SMatthew G. Knepley indices[foffs[f]+b] = foff+b-cind; 48867e29afd2SMatthew G. Knepley } 48877e29afd2SMatthew G. Knepley } 48887e29afd2SMatthew G. Knepley } 48897e29afd2SMatthew G. Knepley } 48907e29afd2SMatthew G. Knepley foffs[f] += fdof; 48917e29afd2SMatthew G. Knepley } 48927e29afd2SMatthew G. Knepley PetscFunctionReturn(0); 48937e29afd2SMatthew G. Knepley } 48947e29afd2SMatthew G. Knepley 48954acb8e1eSToby 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) 4896d3d1a6afSToby Isaac { 4897d3d1a6afSToby Isaac Mat cMat; 4898d3d1a6afSToby Isaac PetscSection aSec, cSec; 4899d3d1a6afSToby Isaac IS aIS; 4900d3d1a6afSToby Isaac PetscInt aStart = -1, aEnd = -1; 4901d3d1a6afSToby Isaac const PetscInt *anchors; 4902e17c06e0SMatthew G. Knepley PetscInt numFields, f, p, q, newP = 0; 4903d3d1a6afSToby Isaac PetscInt newNumPoints = 0, newNumIndices = 0; 4904d3d1a6afSToby Isaac PetscInt *newPoints, *indices, *newIndices; 4905d3d1a6afSToby Isaac PetscInt maxAnchor, maxDof; 4906d3d1a6afSToby Isaac PetscInt newOffsets[32]; 4907d3d1a6afSToby Isaac PetscInt *pointMatOffsets[32]; 4908d3d1a6afSToby Isaac PetscInt *newPointOffsets[32]; 4909d3d1a6afSToby Isaac PetscScalar *pointMat[32]; 49106ecaa68aSToby Isaac PetscScalar *newValues=NULL,*tmpValues; 4911d3d1a6afSToby Isaac PetscBool anyConstrained = PETSC_FALSE; 4912d3d1a6afSToby Isaac PetscErrorCode ierr; 4913d3d1a6afSToby Isaac 4914d3d1a6afSToby Isaac PetscFunctionBegin; 4915d3d1a6afSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4916d3d1a6afSToby Isaac PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 4917d3d1a6afSToby Isaac ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 4918d3d1a6afSToby Isaac 4919a17985deSToby Isaac ierr = DMPlexGetAnchors(dm,&aSec,&aIS);CHKERRQ(ierr); 4920d3d1a6afSToby Isaac /* if there are point-to-point constraints */ 4921d3d1a6afSToby Isaac if (aSec) { 4922d3d1a6afSToby Isaac ierr = PetscMemzero(newOffsets, 32 * sizeof(PetscInt));CHKERRQ(ierr); 4923d3d1a6afSToby Isaac ierr = ISGetIndices(aIS,&anchors);CHKERRQ(ierr); 4924d3d1a6afSToby Isaac ierr = PetscSectionGetChart(aSec,&aStart,&aEnd);CHKERRQ(ierr); 4925d3d1a6afSToby Isaac /* figure out how many points are going to be in the new element matrix 4926d3d1a6afSToby Isaac * (we allow double counting, because it's all just going to be summed 4927d3d1a6afSToby Isaac * into the global matrix anyway) */ 4928d3d1a6afSToby Isaac for (p = 0; p < 2*numPoints; p+=2) { 4929d3d1a6afSToby Isaac PetscInt b = points[p]; 49304b2f2278SToby Isaac PetscInt bDof = 0, bSecDof; 4931d3d1a6afSToby Isaac 49324b2f2278SToby Isaac ierr = PetscSectionGetDof(section,b,&bSecDof);CHKERRQ(ierr); 49334b2f2278SToby Isaac if (!bSecDof) { 49344b2f2278SToby Isaac continue; 49354b2f2278SToby Isaac } 4936d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 4937d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec,b,&bDof);CHKERRQ(ierr); 4938d3d1a6afSToby Isaac } 4939d3d1a6afSToby Isaac if (bDof) { 4940d3d1a6afSToby Isaac /* this point is constrained */ 4941d3d1a6afSToby Isaac /* it is going to be replaced by its anchors */ 4942d3d1a6afSToby Isaac PetscInt bOff, q; 4943d3d1a6afSToby Isaac 4944d3d1a6afSToby Isaac anyConstrained = PETSC_TRUE; 4945d3d1a6afSToby Isaac newNumPoints += bDof; 4946d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(aSec,b,&bOff);CHKERRQ(ierr); 4947d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 4948d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q]; 4949d3d1a6afSToby Isaac PetscInt aDof; 4950d3d1a6afSToby Isaac 4951d3d1a6afSToby Isaac ierr = PetscSectionGetDof(section,a,&aDof);CHKERRQ(ierr); 4952d3d1a6afSToby Isaac newNumIndices += aDof; 4953d3d1a6afSToby Isaac for (f = 0; f < numFields; ++f) { 4954d3d1a6afSToby Isaac PetscInt fDof; 4955d3d1a6afSToby Isaac 4956d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, a, f, &fDof);CHKERRQ(ierr); 4957d3d1a6afSToby Isaac newOffsets[f+1] += fDof; 4958d3d1a6afSToby Isaac } 4959d3d1a6afSToby Isaac } 4960d3d1a6afSToby Isaac } 4961d3d1a6afSToby Isaac else { 4962d3d1a6afSToby Isaac /* this point is not constrained */ 4963d3d1a6afSToby Isaac newNumPoints++; 49644b2f2278SToby Isaac newNumIndices += bSecDof; 4965d3d1a6afSToby Isaac for (f = 0; f < numFields; ++f) { 4966d3d1a6afSToby Isaac PetscInt fDof; 4967d3d1a6afSToby Isaac 4968d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, b, f, &fDof);CHKERRQ(ierr); 4969d3d1a6afSToby Isaac newOffsets[f+1] += fDof; 4970d3d1a6afSToby Isaac } 4971d3d1a6afSToby Isaac } 4972d3d1a6afSToby Isaac } 4973d3d1a6afSToby Isaac } 4974d3d1a6afSToby Isaac if (!anyConstrained) { 497572b80496SMatthew G. Knepley if (outNumPoints) *outNumPoints = 0; 497672b80496SMatthew G. Knepley if (outNumIndices) *outNumIndices = 0; 497772b80496SMatthew G. Knepley if (outPoints) *outPoints = NULL; 497872b80496SMatthew G. Knepley if (outValues) *outValues = NULL; 497972b80496SMatthew G. Knepley if (aSec) {ierr = ISRestoreIndices(aIS,&anchors);CHKERRQ(ierr);} 4980d3d1a6afSToby Isaac PetscFunctionReturn(0); 4981d3d1a6afSToby Isaac } 4982d3d1a6afSToby Isaac 49836ecaa68aSToby Isaac if (outNumPoints) *outNumPoints = newNumPoints; 49846ecaa68aSToby Isaac if (outNumIndices) *outNumIndices = newNumIndices; 49856ecaa68aSToby Isaac 4986f13f9184SToby Isaac for (f = 0; f < numFields; ++f) newOffsets[f+1] += newOffsets[f]; 4987d3d1a6afSToby Isaac 49886ecaa68aSToby Isaac if (!outPoints && !outValues) { 49896ecaa68aSToby Isaac if (offsets) { 49906ecaa68aSToby Isaac for (f = 0; f <= numFields; f++) { 49916ecaa68aSToby Isaac offsets[f] = newOffsets[f]; 49926ecaa68aSToby Isaac } 49936ecaa68aSToby Isaac } 49946ecaa68aSToby Isaac if (aSec) {ierr = ISRestoreIndices(aIS,&anchors);CHKERRQ(ierr);} 49956ecaa68aSToby Isaac PetscFunctionReturn(0); 49966ecaa68aSToby Isaac } 49976ecaa68aSToby Isaac 4998f347f43bSBarry Smith if (numFields && newOffsets[numFields] != newNumIndices) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", newOffsets[numFields], newNumIndices); 4999d3d1a6afSToby Isaac 5000f7c74593SToby Isaac ierr = DMGetDefaultConstraints(dm, &cSec, &cMat);CHKERRQ(ierr); 5001d3d1a6afSToby Isaac 5002d3d1a6afSToby Isaac /* workspaces */ 5003d3d1a6afSToby Isaac if (numFields) { 5004d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 500569291d52SBarry Smith ierr = DMGetWorkArray(dm,numPoints+1,MPIU_INT,&pointMatOffsets[f]);CHKERRQ(ierr); 500669291d52SBarry Smith ierr = DMGetWorkArray(dm,numPoints+1,MPIU_INT,&newPointOffsets[f]);CHKERRQ(ierr); 5007d3d1a6afSToby Isaac } 5008d3d1a6afSToby Isaac } 5009d3d1a6afSToby Isaac else { 501069291d52SBarry Smith ierr = DMGetWorkArray(dm,numPoints+1,MPIU_INT,&pointMatOffsets[0]);CHKERRQ(ierr); 501169291d52SBarry Smith ierr = DMGetWorkArray(dm,numPoints,MPIU_INT,&newPointOffsets[0]);CHKERRQ(ierr); 5012d3d1a6afSToby Isaac } 5013d3d1a6afSToby Isaac 5014d3d1a6afSToby Isaac /* get workspaces for the point-to-point matrices */ 5015d3d1a6afSToby Isaac if (numFields) { 50164b2f2278SToby Isaac PetscInt totalOffset, totalMatOffset; 50174b2f2278SToby Isaac 5018d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 5019d3d1a6afSToby Isaac PetscInt b = points[2*p]; 50204b2f2278SToby Isaac PetscInt bDof = 0, bSecDof; 5021d3d1a6afSToby Isaac 50224b2f2278SToby Isaac ierr = PetscSectionGetDof(section,b,&bSecDof);CHKERRQ(ierr); 50234b2f2278SToby Isaac if (!bSecDof) { 50244b2f2278SToby Isaac for (f = 0; f < numFields; f++) { 50254b2f2278SToby Isaac newPointOffsets[f][p + 1] = 0; 50264b2f2278SToby Isaac pointMatOffsets[f][p + 1] = 0; 50274b2f2278SToby Isaac } 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 for (f = 0; f < numFields; f++) { 5035d3d1a6afSToby Isaac PetscInt fDof, q, bOff, allFDof = 0; 5036d3d1a6afSToby Isaac 5037d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, b, f, &fDof);CHKERRQ(ierr); 5038d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(aSec, b, &bOff);CHKERRQ(ierr); 5039d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 5040d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q]; 5041d3d1a6afSToby Isaac PetscInt aFDof; 5042d3d1a6afSToby Isaac 5043d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, a, f, &aFDof);CHKERRQ(ierr); 5044d3d1a6afSToby Isaac allFDof += aFDof; 5045d3d1a6afSToby Isaac } 5046d3d1a6afSToby Isaac newPointOffsets[f][p+1] = allFDof; 5047d3d1a6afSToby Isaac pointMatOffsets[f][p+1] = fDof * allFDof; 5048d3d1a6afSToby Isaac } 5049d3d1a6afSToby Isaac } 5050d3d1a6afSToby Isaac else { 5051d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 5052d3d1a6afSToby Isaac PetscInt fDof; 5053d3d1a6afSToby Isaac 5054d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, b, f, &fDof);CHKERRQ(ierr); 5055d3d1a6afSToby Isaac newPointOffsets[f][p+1] = fDof; 5056d3d1a6afSToby Isaac pointMatOffsets[f][p+1] = 0; 5057d3d1a6afSToby Isaac } 5058d3d1a6afSToby Isaac } 5059d3d1a6afSToby Isaac } 50604b2f2278SToby Isaac for (f = 0, totalOffset = 0, totalMatOffset = 0; f < numFields; f++) { 50614b2f2278SToby Isaac newPointOffsets[f][0] = totalOffset; 50624b2f2278SToby Isaac pointMatOffsets[f][0] = totalMatOffset; 5063d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 5064d3d1a6afSToby Isaac newPointOffsets[f][p+1] += newPointOffsets[f][p]; 5065d3d1a6afSToby Isaac pointMatOffsets[f][p+1] += pointMatOffsets[f][p]; 5066d3d1a6afSToby Isaac } 506719f70fd5SToby Isaac totalOffset = newPointOffsets[f][numPoints]; 506819f70fd5SToby Isaac totalMatOffset = pointMatOffsets[f][numPoints]; 506969291d52SBarry Smith ierr = DMGetWorkArray(dm,pointMatOffsets[f][numPoints],MPIU_SCALAR,&pointMat[f]);CHKERRQ(ierr); 5070d3d1a6afSToby Isaac } 5071d3d1a6afSToby Isaac } 5072d3d1a6afSToby Isaac else { 5073d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 5074d3d1a6afSToby Isaac PetscInt b = points[2*p]; 50754b2f2278SToby Isaac PetscInt bDof = 0, bSecDof; 5076d3d1a6afSToby Isaac 50774b2f2278SToby Isaac ierr = PetscSectionGetDof(section,b,&bSecDof);CHKERRQ(ierr); 50784b2f2278SToby Isaac if (!bSecDof) { 50794b2f2278SToby Isaac newPointOffsets[0][p + 1] = 0; 50804b2f2278SToby Isaac pointMatOffsets[0][p + 1] = 0; 50814b2f2278SToby Isaac continue; 50824b2f2278SToby Isaac } 5083d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 5084d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec, b, &bDof);CHKERRQ(ierr); 5085d3d1a6afSToby Isaac } 5086d3d1a6afSToby Isaac if (bDof) { 50874b2f2278SToby Isaac PetscInt bOff, q, allDof = 0; 5088d3d1a6afSToby Isaac 5089d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(aSec, b, &bOff);CHKERRQ(ierr); 5090d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 5091d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q], aDof; 5092d3d1a6afSToby Isaac 5093d3d1a6afSToby Isaac ierr = PetscSectionGetDof(section, a, &aDof);CHKERRQ(ierr); 5094d3d1a6afSToby Isaac allDof += aDof; 5095d3d1a6afSToby Isaac } 5096d3d1a6afSToby Isaac newPointOffsets[0][p+1] = allDof; 50974b2f2278SToby Isaac pointMatOffsets[0][p+1] = bSecDof * allDof; 5098d3d1a6afSToby Isaac } 5099d3d1a6afSToby Isaac else { 51004b2f2278SToby Isaac newPointOffsets[0][p+1] = bSecDof; 5101d3d1a6afSToby Isaac pointMatOffsets[0][p+1] = 0; 5102d3d1a6afSToby Isaac } 5103d3d1a6afSToby Isaac } 5104d3d1a6afSToby Isaac newPointOffsets[0][0] = 0; 5105d3d1a6afSToby Isaac pointMatOffsets[0][0] = 0; 5106d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 5107d3d1a6afSToby Isaac newPointOffsets[0][p+1] += newPointOffsets[0][p]; 5108d3d1a6afSToby Isaac pointMatOffsets[0][p+1] += pointMatOffsets[0][p]; 5109d3d1a6afSToby Isaac } 511069291d52SBarry Smith ierr = DMGetWorkArray(dm,pointMatOffsets[0][numPoints],MPIU_SCALAR,&pointMat[0]);CHKERRQ(ierr); 5111d3d1a6afSToby Isaac } 5112d3d1a6afSToby Isaac 51136ecaa68aSToby Isaac /* output arrays */ 511469291d52SBarry Smith ierr = DMGetWorkArray(dm,2*newNumPoints,MPIU_INT,&newPoints);CHKERRQ(ierr); 51156ecaa68aSToby Isaac 5116d3d1a6afSToby Isaac /* get the point-to-point matrices; construct newPoints */ 5117d3d1a6afSToby Isaac ierr = PetscSectionGetMaxDof(aSec, &maxAnchor);CHKERRQ(ierr); 5118d3d1a6afSToby Isaac ierr = PetscSectionGetMaxDof(section, &maxDof);CHKERRQ(ierr); 511969291d52SBarry Smith ierr = DMGetWorkArray(dm,maxDof,MPIU_INT,&indices);CHKERRQ(ierr); 512069291d52SBarry Smith ierr = DMGetWorkArray(dm,maxAnchor*maxDof,MPIU_INT,&newIndices);CHKERRQ(ierr); 5121d3d1a6afSToby Isaac if (numFields) { 5122d3d1a6afSToby Isaac for (p = 0, newP = 0; p < numPoints; p++) { 5123d3d1a6afSToby Isaac PetscInt b = points[2*p]; 5124d3d1a6afSToby Isaac PetscInt o = points[2*p+1]; 51254b2f2278SToby Isaac PetscInt bDof = 0, bSecDof; 5126d3d1a6afSToby Isaac 51274b2f2278SToby Isaac ierr = PetscSectionGetDof(section, b, &bSecDof);CHKERRQ(ierr); 51284b2f2278SToby Isaac if (!bSecDof) { 51294b2f2278SToby Isaac continue; 51304b2f2278SToby Isaac } 5131d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 5132d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec, b, &bDof);CHKERRQ(ierr); 5133d3d1a6afSToby Isaac } 5134d3d1a6afSToby Isaac if (bDof) { 5135d3d1a6afSToby Isaac PetscInt fStart[32], fEnd[32], fAnchorStart[32], fAnchorEnd[32], bOff, q; 5136d3d1a6afSToby Isaac 5137d3d1a6afSToby Isaac fStart[0] = 0; 5138d3d1a6afSToby Isaac fEnd[0] = 0; 5139d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 5140d3d1a6afSToby Isaac PetscInt fDof; 5141d3d1a6afSToby Isaac 5142d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(cSec, b, f, &fDof);CHKERRQ(ierr); 5143d3d1a6afSToby Isaac fStart[f+1] = fStart[f] + fDof; 5144d3d1a6afSToby Isaac fEnd[f+1] = fStart[f+1]; 5145d3d1a6afSToby Isaac } 5146d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(cSec, b, &bOff);CHKERRQ(ierr); 51474acb8e1eSToby Isaac ierr = DMPlexGetIndicesPointFields_Internal(cSec, b, bOff, fEnd, PETSC_TRUE, perms, p, indices);CHKERRQ(ierr); 5148d3d1a6afSToby Isaac 5149d3d1a6afSToby Isaac fAnchorStart[0] = 0; 5150d3d1a6afSToby Isaac fAnchorEnd[0] = 0; 5151d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 5152d3d1a6afSToby Isaac PetscInt fDof = newPointOffsets[f][p + 1] - newPointOffsets[f][p]; 5153d3d1a6afSToby Isaac 5154d3d1a6afSToby Isaac fAnchorStart[f+1] = fAnchorStart[f] + fDof; 5155d3d1a6afSToby Isaac fAnchorEnd[f+1] = fAnchorStart[f + 1]; 5156d3d1a6afSToby Isaac } 5157d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(aSec, b, &bOff);CHKERRQ(ierr); 5158d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 5159d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q], aOff; 5160d3d1a6afSToby Isaac 5161d3d1a6afSToby 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 */ 5162d3d1a6afSToby Isaac newPoints[2*(newP + q)] = a; 5163d3d1a6afSToby Isaac newPoints[2*(newP + q) + 1] = 0; 5164302440fdSBarry Smith ierr = PetscSectionGetOffset(section, a, &aOff);CHKERRQ(ierr); 51654acb8e1eSToby Isaac ierr = DMPlexGetIndicesPointFields_Internal(section, a, aOff, fAnchorEnd, PETSC_TRUE, NULL, -1, newIndices);CHKERRQ(ierr); 5166d3d1a6afSToby Isaac } 5167d3d1a6afSToby Isaac newP += bDof; 5168d3d1a6afSToby Isaac 51696ecaa68aSToby Isaac if (outValues) { 5170d3d1a6afSToby Isaac /* get the point-to-point submatrix */ 5171d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 5172d3d1a6afSToby 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); 5173d3d1a6afSToby Isaac } 5174d3d1a6afSToby Isaac } 51756ecaa68aSToby Isaac } 5176d3d1a6afSToby Isaac else { 5177d3d1a6afSToby Isaac newPoints[2 * newP] = b; 5178d3d1a6afSToby Isaac newPoints[2 * newP + 1] = o; 5179d3d1a6afSToby Isaac newP++; 5180d3d1a6afSToby Isaac } 5181d3d1a6afSToby Isaac } 5182d3d1a6afSToby Isaac } else { 5183d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 5184d3d1a6afSToby Isaac PetscInt b = points[2*p]; 5185d3d1a6afSToby Isaac PetscInt o = points[2*p+1]; 51864b2f2278SToby Isaac PetscInt bDof = 0, bSecDof; 5187d3d1a6afSToby Isaac 51884b2f2278SToby Isaac ierr = PetscSectionGetDof(section, b, &bSecDof);CHKERRQ(ierr); 51894b2f2278SToby Isaac if (!bSecDof) { 51904b2f2278SToby Isaac continue; 51914b2f2278SToby Isaac } 5192d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 5193d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec, b, &bDof);CHKERRQ(ierr); 5194d3d1a6afSToby Isaac } 5195d3d1a6afSToby Isaac if (bDof) { 5196d3d1a6afSToby Isaac PetscInt bEnd = 0, bAnchorEnd = 0, bOff; 5197d3d1a6afSToby Isaac 5198d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(cSec, b, &bOff);CHKERRQ(ierr); 51994acb8e1eSToby Isaac ierr = DMPlexGetIndicesPoint_Internal(cSec, b, bOff, &bEnd, PETSC_TRUE, (perms && perms[0]) ? perms[0][p] : NULL, indices);CHKERRQ(ierr); 5200d3d1a6afSToby Isaac 5201d3d1a6afSToby Isaac ierr = PetscSectionGetOffset (aSec, b, &bOff);CHKERRQ(ierr); 5202d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 5203d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q], aOff; 5204d3d1a6afSToby Isaac 5205d3d1a6afSToby 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 */ 5206d3d1a6afSToby Isaac 5207d3d1a6afSToby Isaac newPoints[2*(newP + q)] = a; 5208d3d1a6afSToby Isaac newPoints[2*(newP + q) + 1] = 0; 5209302440fdSBarry Smith ierr = PetscSectionGetOffset(section, a, &aOff);CHKERRQ(ierr); 52104acb8e1eSToby Isaac ierr = DMPlexGetIndicesPoint_Internal(section, a, aOff, &bAnchorEnd, PETSC_TRUE, NULL, newIndices);CHKERRQ(ierr); 5211d3d1a6afSToby Isaac } 5212d3d1a6afSToby Isaac newP += bDof; 5213d3d1a6afSToby Isaac 5214d3d1a6afSToby Isaac /* get the point-to-point submatrix */ 52156ecaa68aSToby Isaac if (outValues) { 5216d3d1a6afSToby Isaac ierr = MatGetValues(cMat,bEnd,indices,bAnchorEnd,newIndices,pointMat[0] + pointMatOffsets[0][p]);CHKERRQ(ierr); 5217d3d1a6afSToby Isaac } 52186ecaa68aSToby Isaac } 5219d3d1a6afSToby Isaac else { 5220d3d1a6afSToby Isaac newPoints[2 * newP] = b; 5221d3d1a6afSToby Isaac newPoints[2 * newP + 1] = o; 5222d3d1a6afSToby Isaac newP++; 5223d3d1a6afSToby Isaac } 5224d3d1a6afSToby Isaac } 5225d3d1a6afSToby Isaac } 5226d3d1a6afSToby Isaac 52276ecaa68aSToby Isaac if (outValues) { 522869291d52SBarry Smith ierr = DMGetWorkArray(dm,newNumIndices*numIndices,MPIU_SCALAR,&tmpValues);CHKERRQ(ierr); 5229d3d1a6afSToby Isaac ierr = PetscMemzero(tmpValues,newNumIndices*numIndices*sizeof(*tmpValues));CHKERRQ(ierr); 5230d3d1a6afSToby Isaac /* multiply constraints on the right */ 5231d3d1a6afSToby Isaac if (numFields) { 5232d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 5233d3d1a6afSToby Isaac PetscInt oldOff = offsets[f]; 5234d3d1a6afSToby Isaac 5235d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 5236d3d1a6afSToby Isaac PetscInt cStart = newPointOffsets[f][p]; 5237d3d1a6afSToby Isaac PetscInt b = points[2 * p]; 5238d3d1a6afSToby Isaac PetscInt c, r, k; 5239d3d1a6afSToby Isaac PetscInt dof; 5240d3d1a6afSToby Isaac 5241d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section,b,f,&dof);CHKERRQ(ierr); 52424b2f2278SToby Isaac if (!dof) { 52434b2f2278SToby Isaac continue; 52444b2f2278SToby Isaac } 5245d3d1a6afSToby Isaac if (pointMatOffsets[f][p] < pointMatOffsets[f][p + 1]) { 5246d3d1a6afSToby Isaac PetscInt nCols = newPointOffsets[f][p+1]-cStart; 5247d3d1a6afSToby Isaac const PetscScalar *mat = pointMat[f] + pointMatOffsets[f][p]; 5248d3d1a6afSToby Isaac 5249d3d1a6afSToby Isaac for (r = 0; r < numIndices; r++) { 5250d3d1a6afSToby Isaac for (c = 0; c < nCols; c++) { 5251d3d1a6afSToby Isaac for (k = 0; k < dof; k++) { 52524acb8e1eSToby Isaac tmpValues[r * newNumIndices + cStart + c] += values[r * numIndices + oldOff + k] * mat[k * nCols + c]; 5253d3d1a6afSToby Isaac } 5254d3d1a6afSToby Isaac } 5255d3d1a6afSToby Isaac } 5256d3d1a6afSToby Isaac } 5257d3d1a6afSToby Isaac else { 5258d3d1a6afSToby Isaac /* copy this column as is */ 5259d3d1a6afSToby Isaac for (r = 0; r < numIndices; r++) { 5260d3d1a6afSToby Isaac for (c = 0; c < dof; c++) { 5261d3d1a6afSToby Isaac tmpValues[r * newNumIndices + cStart + c] = values[r * numIndices + oldOff + c]; 5262d3d1a6afSToby Isaac } 5263d3d1a6afSToby Isaac } 5264d3d1a6afSToby Isaac } 5265d3d1a6afSToby Isaac oldOff += dof; 5266d3d1a6afSToby Isaac } 5267d3d1a6afSToby Isaac } 5268d3d1a6afSToby Isaac } 5269d3d1a6afSToby Isaac else { 5270d3d1a6afSToby Isaac PetscInt oldOff = 0; 5271d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 5272d3d1a6afSToby Isaac PetscInt cStart = newPointOffsets[0][p]; 5273d3d1a6afSToby Isaac PetscInt b = points[2 * p]; 5274d3d1a6afSToby Isaac PetscInt c, r, k; 5275d3d1a6afSToby Isaac PetscInt dof; 5276d3d1a6afSToby Isaac 5277d3d1a6afSToby Isaac ierr = PetscSectionGetDof(section,b,&dof);CHKERRQ(ierr); 52784b2f2278SToby Isaac if (!dof) { 52794b2f2278SToby Isaac continue; 52804b2f2278SToby Isaac } 5281d3d1a6afSToby Isaac if (pointMatOffsets[0][p] < pointMatOffsets[0][p + 1]) { 5282d3d1a6afSToby Isaac PetscInt nCols = newPointOffsets[0][p+1]-cStart; 5283d3d1a6afSToby Isaac const PetscScalar *mat = pointMat[0] + pointMatOffsets[0][p]; 5284d3d1a6afSToby Isaac 5285d3d1a6afSToby Isaac for (r = 0; r < numIndices; r++) { 5286d3d1a6afSToby Isaac for (c = 0; c < nCols; c++) { 5287d3d1a6afSToby Isaac for (k = 0; k < dof; k++) { 5288d3d1a6afSToby Isaac tmpValues[r * newNumIndices + cStart + c] += mat[k * nCols + c] * values[r * numIndices + oldOff + k]; 5289d3d1a6afSToby Isaac } 5290d3d1a6afSToby Isaac } 5291d3d1a6afSToby Isaac } 5292d3d1a6afSToby Isaac } 5293d3d1a6afSToby Isaac else { 5294d3d1a6afSToby Isaac /* copy this column as is */ 5295d3d1a6afSToby Isaac for (r = 0; r < numIndices; r++) { 5296d3d1a6afSToby Isaac for (c = 0; c < dof; c++) { 5297d3d1a6afSToby Isaac tmpValues[r * newNumIndices + cStart + c] = values[r * numIndices + oldOff + c]; 5298d3d1a6afSToby Isaac } 5299d3d1a6afSToby Isaac } 5300d3d1a6afSToby Isaac } 5301d3d1a6afSToby Isaac oldOff += dof; 5302d3d1a6afSToby Isaac } 5303d3d1a6afSToby Isaac } 5304d3d1a6afSToby Isaac 53056ecaa68aSToby Isaac if (multiplyLeft) { 530669291d52SBarry Smith ierr = DMGetWorkArray(dm,newNumIndices*newNumIndices,MPIU_SCALAR,&newValues);CHKERRQ(ierr); 5307d3d1a6afSToby Isaac ierr = PetscMemzero(newValues,newNumIndices*newNumIndices*sizeof(*newValues));CHKERRQ(ierr); 5308d3d1a6afSToby Isaac /* multiply constraints transpose on the left */ 5309d3d1a6afSToby Isaac if (numFields) { 5310d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 5311d3d1a6afSToby Isaac PetscInt oldOff = offsets[f]; 5312d3d1a6afSToby Isaac 5313d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 5314d3d1a6afSToby Isaac PetscInt rStart = newPointOffsets[f][p]; 5315d3d1a6afSToby Isaac PetscInt b = points[2 * p]; 5316d3d1a6afSToby Isaac PetscInt c, r, k; 5317d3d1a6afSToby Isaac PetscInt dof; 5318d3d1a6afSToby Isaac 5319d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section,b,f,&dof);CHKERRQ(ierr); 5320d3d1a6afSToby Isaac if (pointMatOffsets[f][p] < pointMatOffsets[f][p + 1]) { 5321d3d1a6afSToby Isaac PetscInt nRows = newPointOffsets[f][p+1]-rStart; 5322d3d1a6afSToby Isaac const PetscScalar *PETSC_RESTRICT mat = pointMat[f] + pointMatOffsets[f][p]; 5323d3d1a6afSToby Isaac 5324d3d1a6afSToby Isaac for (r = 0; r < nRows; r++) { 5325d3d1a6afSToby Isaac for (c = 0; c < newNumIndices; c++) { 5326d3d1a6afSToby Isaac for (k = 0; k < dof; k++) { 5327d3d1a6afSToby Isaac newValues[(rStart + r) * newNumIndices + c] += mat[k * nRows + r] * tmpValues[(oldOff + k) * newNumIndices + c]; 5328d3d1a6afSToby Isaac } 5329d3d1a6afSToby Isaac } 5330d3d1a6afSToby Isaac } 5331d3d1a6afSToby Isaac } 5332d3d1a6afSToby Isaac else { 5333d3d1a6afSToby Isaac /* copy this row as is */ 5334d3d1a6afSToby Isaac for (r = 0; r < dof; r++) { 5335d3d1a6afSToby Isaac for (c = 0; c < newNumIndices; c++) { 5336d3d1a6afSToby Isaac newValues[(rStart + r) * newNumIndices + c] = tmpValues[(oldOff + r) * newNumIndices + c]; 5337d3d1a6afSToby Isaac } 5338d3d1a6afSToby Isaac } 5339d3d1a6afSToby Isaac } 5340d3d1a6afSToby Isaac oldOff += dof; 5341d3d1a6afSToby Isaac } 5342d3d1a6afSToby Isaac } 5343d3d1a6afSToby Isaac } 5344d3d1a6afSToby Isaac else { 5345d3d1a6afSToby Isaac PetscInt oldOff = 0; 5346d3d1a6afSToby Isaac 5347d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 5348d3d1a6afSToby Isaac PetscInt rStart = newPointOffsets[0][p]; 5349d3d1a6afSToby Isaac PetscInt b = points[2 * p]; 5350d3d1a6afSToby Isaac PetscInt c, r, k; 5351d3d1a6afSToby Isaac PetscInt dof; 5352d3d1a6afSToby Isaac 5353d3d1a6afSToby Isaac ierr = PetscSectionGetDof(section,b,&dof);CHKERRQ(ierr); 5354d3d1a6afSToby Isaac if (pointMatOffsets[0][p] < pointMatOffsets[0][p + 1]) { 5355d3d1a6afSToby Isaac PetscInt nRows = newPointOffsets[0][p+1]-rStart; 5356d3d1a6afSToby Isaac const PetscScalar *PETSC_RESTRICT mat = pointMat[0] + pointMatOffsets[0][p]; 5357d3d1a6afSToby Isaac 5358d3d1a6afSToby Isaac for (r = 0; r < nRows; r++) { 5359d3d1a6afSToby Isaac for (c = 0; c < newNumIndices; c++) { 5360d3d1a6afSToby Isaac for (k = 0; k < dof; k++) { 5361d3d1a6afSToby Isaac newValues[(rStart + r) * newNumIndices + c] += mat[k * nRows + r] * tmpValues[(oldOff + k) * newNumIndices + c]; 5362d3d1a6afSToby Isaac } 5363d3d1a6afSToby Isaac } 5364d3d1a6afSToby Isaac } 5365d3d1a6afSToby Isaac } 5366d3d1a6afSToby Isaac else { 5367d3d1a6afSToby Isaac /* copy this row as is */ 53689fc93327SToby Isaac for (r = 0; r < dof; r++) { 5369d3d1a6afSToby Isaac for (c = 0; c < newNumIndices; c++) { 5370d3d1a6afSToby Isaac newValues[(rStart + r) * newNumIndices + c] = tmpValues[(oldOff + r) * newNumIndices + c]; 5371d3d1a6afSToby Isaac } 5372d3d1a6afSToby Isaac } 5373d3d1a6afSToby Isaac } 5374d3d1a6afSToby Isaac oldOff += dof; 5375d3d1a6afSToby Isaac } 5376d3d1a6afSToby Isaac } 5377d3d1a6afSToby Isaac 537869291d52SBarry Smith ierr = DMRestoreWorkArray(dm,newNumIndices*numIndices,MPIU_SCALAR,&tmpValues);CHKERRQ(ierr); 53796ecaa68aSToby Isaac } 53806ecaa68aSToby Isaac else { 53816ecaa68aSToby Isaac newValues = tmpValues; 53826ecaa68aSToby Isaac } 53836ecaa68aSToby Isaac } 53846ecaa68aSToby Isaac 5385d3d1a6afSToby Isaac /* clean up */ 538669291d52SBarry Smith ierr = DMRestoreWorkArray(dm,maxDof,MPIU_INT,&indices);CHKERRQ(ierr); 538769291d52SBarry Smith ierr = DMRestoreWorkArray(dm,maxAnchor*maxDof,MPIU_INT,&newIndices);CHKERRQ(ierr); 53886ecaa68aSToby Isaac 5389d3d1a6afSToby Isaac if (numFields) { 5390d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 539169291d52SBarry Smith ierr = DMRestoreWorkArray(dm,pointMatOffsets[f][numPoints],MPIU_SCALAR,&pointMat[f]);CHKERRQ(ierr); 539269291d52SBarry Smith ierr = DMRestoreWorkArray(dm,numPoints+1,MPIU_INT,&pointMatOffsets[f]);CHKERRQ(ierr); 539369291d52SBarry Smith ierr = DMRestoreWorkArray(dm,numPoints+1,MPIU_INT,&newPointOffsets[f]);CHKERRQ(ierr); 5394d3d1a6afSToby Isaac } 5395d3d1a6afSToby Isaac } 5396d3d1a6afSToby Isaac else { 539769291d52SBarry Smith ierr = DMRestoreWorkArray(dm,pointMatOffsets[0][numPoints],MPIU_SCALAR,&pointMat[0]);CHKERRQ(ierr); 539869291d52SBarry Smith ierr = DMRestoreWorkArray(dm,numPoints+1,MPIU_INT,&pointMatOffsets[0]);CHKERRQ(ierr); 539969291d52SBarry Smith ierr = DMRestoreWorkArray(dm,numPoints+1,MPIU_INT,&newPointOffsets[0]);CHKERRQ(ierr); 5400d3d1a6afSToby Isaac } 5401d3d1a6afSToby Isaac ierr = ISRestoreIndices(aIS,&anchors);CHKERRQ(ierr); 5402d3d1a6afSToby Isaac 5403d3d1a6afSToby Isaac /* output */ 54046ecaa68aSToby Isaac if (outPoints) { 5405d3d1a6afSToby Isaac *outPoints = newPoints; 54066ecaa68aSToby Isaac } 54076ecaa68aSToby Isaac else { 540869291d52SBarry Smith ierr = DMRestoreWorkArray(dm,2*newNumPoints,MPIU_INT,&newPoints);CHKERRQ(ierr); 54096ecaa68aSToby Isaac } 541031620726SToby Isaac if (outValues) { 5411d3d1a6afSToby Isaac *outValues = newValues; 54126ecaa68aSToby Isaac } 54136ecaa68aSToby Isaac for (f = 0; f <= numFields; f++) { 5414d3d1a6afSToby Isaac offsets[f] = newOffsets[f]; 5415d3d1a6afSToby Isaac } 5416d3d1a6afSToby Isaac PetscFunctionReturn(0); 5417d3d1a6afSToby Isaac } 5418d3d1a6afSToby Isaac 54197cd05799SMatthew G. Knepley /*@C 5420a87adde4SMatthew G. Knepley DMPlexGetClosureIndices - Get the global indices in a vector v for all points in the closure of the given point 54217cd05799SMatthew G. Knepley 54227cd05799SMatthew G. Knepley Not collective 54237cd05799SMatthew G. Knepley 54247cd05799SMatthew G. Knepley Input Parameters: 54257cd05799SMatthew G. Knepley + dm - The DM 54267cd05799SMatthew G. Knepley . section - The section describing the layout in v, or NULL to use the default section 54277cd05799SMatthew G. Knepley . globalSection - The section describing the parallel layout in v, or NULL to use the default section 54287cd05799SMatthew G. Knepley - point - The mesh point 54297cd05799SMatthew G. Knepley 54307cd05799SMatthew G. Knepley Output parameters: 54317cd05799SMatthew G. Knepley + numIndices - The number of indices 54327cd05799SMatthew G. Knepley . indices - The indices 54337cd05799SMatthew G. Knepley - outOffsets - Field offset if not NULL 54347cd05799SMatthew G. Knepley 54357cd05799SMatthew G. Knepley Note: Must call DMPlexRestoreClosureIndices() to free allocated memory 54367cd05799SMatthew G. Knepley 54377cd05799SMatthew G. Knepley Level: advanced 54387cd05799SMatthew G. Knepley 54397cd05799SMatthew G. Knepley .seealso DMPlexRestoreClosureIndices(), DMPlexVecGetClosure(), DMPlexMatSetClosure() 54407cd05799SMatthew G. Knepley @*/ 54416ecaa68aSToby Isaac PetscErrorCode DMPlexGetClosureIndices(DM dm, PetscSection section, PetscSection globalSection, PetscInt point, PetscInt *numIndices, PetscInt **indices, PetscInt *outOffsets) 54427773e69fSMatthew G. Knepley { 54437773e69fSMatthew G. Knepley PetscSection clSection; 54447773e69fSMatthew G. Knepley IS clPoints; 54457773e69fSMatthew G. Knepley const PetscInt *clp; 54464acb8e1eSToby Isaac const PetscInt **perms[32] = {NULL}; 54477773e69fSMatthew G. Knepley PetscInt *points = NULL, *pointsNew; 54487773e69fSMatthew G. Knepley PetscInt numPoints, numPointsNew; 54497773e69fSMatthew G. Knepley PetscInt offsets[32]; 54507773e69fSMatthew G. Knepley PetscInt Nf, Nind, NindNew, off, globalOff, f, p; 54517773e69fSMatthew G. Knepley PetscErrorCode ierr; 54527773e69fSMatthew G. Knepley 54537773e69fSMatthew G. Knepley PetscFunctionBegin; 54547773e69fSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 54557773e69fSMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 54567773e69fSMatthew G. Knepley PetscValidHeaderSpecific(globalSection, PETSC_SECTION_CLASSID, 3); 54577773e69fSMatthew G. Knepley if (numIndices) PetscValidPointer(numIndices, 4); 54587773e69fSMatthew G. Knepley PetscValidPointer(indices, 5); 54597773e69fSMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &Nf);CHKERRQ(ierr); 54607773e69fSMatthew G. Knepley if (Nf > 31) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Number of fields %D limited to 31", Nf); 54617773e69fSMatthew G. Knepley ierr = PetscMemzero(offsets, 32 * sizeof(PetscInt));CHKERRQ(ierr); 54627773e69fSMatthew G. Knepley /* Get points in closure */ 5463923c78e0SToby Isaac ierr = DMPlexGetCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 54647773e69fSMatthew G. Knepley /* Get number of indices and indices per field */ 54657773e69fSMatthew G. Knepley for (p = 0, Nind = 0; p < numPoints*2; p += 2) { 54667773e69fSMatthew G. Knepley PetscInt dof, fdof; 54677773e69fSMatthew G. Knepley 54687773e69fSMatthew G. Knepley ierr = PetscSectionGetDof(section, points[p], &dof);CHKERRQ(ierr); 54697773e69fSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 54707773e69fSMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, points[p], f, &fdof);CHKERRQ(ierr); 54717773e69fSMatthew G. Knepley offsets[f+1] += fdof; 54727773e69fSMatthew G. Knepley } 54737773e69fSMatthew G. Knepley Nind += dof; 54747773e69fSMatthew G. Knepley } 54757773e69fSMatthew G. Knepley for (f = 1; f < Nf; ++f) offsets[f+1] += offsets[f]; 54768ccfff9cSToby Isaac if (Nf && offsets[Nf] != Nind) SETERRQ2(PetscObjectComm((PetscObject) dm), PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", offsets[Nf], Nind); 54774acb8e1eSToby Isaac if (!Nf) offsets[1] = Nind; 54784acb8e1eSToby Isaac /* Get dual space symmetries */ 54794acb8e1eSToby Isaac for (f = 0; f < PetscMax(1,Nf); f++) { 54804acb8e1eSToby Isaac if (Nf) {ierr = PetscSectionGetFieldPointSyms(section,f,numPoints,points,&perms[f],NULL);CHKERRQ(ierr);} 54814acb8e1eSToby Isaac else {ierr = PetscSectionGetPointSyms(section,numPoints,points,&perms[f],NULL);CHKERRQ(ierr);} 54824acb8e1eSToby Isaac } 54837773e69fSMatthew G. Knepley /* Correct for hanging node constraints */ 54847773e69fSMatthew G. Knepley { 54854acb8e1eSToby Isaac ierr = DMPlexAnchorsModifyMat(dm, section, numPoints, Nind, points, perms, NULL, &numPointsNew, &NindNew, &pointsNew, NULL, offsets, PETSC_TRUE);CHKERRQ(ierr); 54867773e69fSMatthew G. Knepley if (numPointsNew) { 54874acb8e1eSToby Isaac for (f = 0; f < PetscMax(1,Nf); f++) { 54884acb8e1eSToby Isaac if (Nf) {ierr = PetscSectionRestoreFieldPointSyms(section,f,numPoints,points,&perms[f],NULL);CHKERRQ(ierr);} 54894acb8e1eSToby Isaac else {ierr = PetscSectionRestorePointSyms(section,numPoints,points,&perms[f],NULL);CHKERRQ(ierr);} 54904acb8e1eSToby Isaac } 54914acb8e1eSToby Isaac for (f = 0; f < PetscMax(1,Nf); f++) { 54924acb8e1eSToby Isaac if (Nf) {ierr = PetscSectionGetFieldPointSyms(section,f,numPointsNew,pointsNew,&perms[f],NULL);CHKERRQ(ierr);} 54934acb8e1eSToby Isaac else {ierr = PetscSectionGetPointSyms(section,numPointsNew,pointsNew,&perms[f],NULL);CHKERRQ(ierr);} 54944acb8e1eSToby Isaac } 5495923c78e0SToby Isaac ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 54967773e69fSMatthew G. Knepley numPoints = numPointsNew; 54977773e69fSMatthew G. Knepley Nind = NindNew; 54987773e69fSMatthew G. Knepley points = pointsNew; 54997773e69fSMatthew G. Knepley } 55007773e69fSMatthew G. Knepley } 55017773e69fSMatthew G. Knepley /* Calculate indices */ 550269291d52SBarry Smith ierr = DMGetWorkArray(dm, Nind, MPIU_INT, indices);CHKERRQ(ierr); 55037773e69fSMatthew G. Knepley if (Nf) { 55046ecaa68aSToby Isaac if (outOffsets) { 55056ecaa68aSToby Isaac PetscInt f; 55066ecaa68aSToby Isaac 550746bdb399SToby Isaac for (f = 0; f <= Nf; f++) { 55086ecaa68aSToby Isaac outOffsets[f] = offsets[f]; 55096ecaa68aSToby Isaac } 55106ecaa68aSToby Isaac } 55114acb8e1eSToby Isaac for (p = 0; p < numPoints; p++) { 55124acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalSection, points[2*p], &globalOff);CHKERRQ(ierr); 55134acb8e1eSToby Isaac DMPlexGetIndicesPointFields_Internal(section, points[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, offsets, PETSC_FALSE, perms, p, *indices); 55147773e69fSMatthew G. Knepley } 55157773e69fSMatthew G. Knepley } else { 55164acb8e1eSToby Isaac for (p = 0, off = 0; p < numPoints; p++) { 55174acb8e1eSToby Isaac const PetscInt *perm = perms[0] ? perms[0][p] : NULL; 55184acb8e1eSToby Isaac 55194acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalSection, points[2*p], &globalOff);CHKERRQ(ierr); 55204acb8e1eSToby Isaac DMPlexGetIndicesPoint_Internal(section, points[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, perm, *indices); 55217773e69fSMatthew G. Knepley } 55227773e69fSMatthew G. Knepley } 55237773e69fSMatthew G. Knepley /* Cleanup points */ 55244acb8e1eSToby Isaac for (f = 0; f < PetscMax(1,Nf); f++) { 55254acb8e1eSToby Isaac if (Nf) {ierr = PetscSectionRestoreFieldPointSyms(section,f,numPoints,points,&perms[f],NULL);CHKERRQ(ierr);} 55264acb8e1eSToby Isaac else {ierr = PetscSectionRestorePointSyms(section,numPoints,points,&perms[f],NULL);CHKERRQ(ierr);} 55274acb8e1eSToby Isaac } 55287773e69fSMatthew G. Knepley if (numPointsNew) { 552969291d52SBarry Smith ierr = DMRestoreWorkArray(dm, 2*numPointsNew, MPIU_INT, &pointsNew);CHKERRQ(ierr); 55307773e69fSMatthew G. Knepley } else { 5531923c78e0SToby Isaac ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 55327773e69fSMatthew G. Knepley } 55337773e69fSMatthew G. Knepley if (numIndices) *numIndices = Nind; 55347773e69fSMatthew G. Knepley PetscFunctionReturn(0); 55357773e69fSMatthew G. Knepley } 55367773e69fSMatthew G. Knepley 55377cd05799SMatthew G. Knepley /*@C 55387cd05799SMatthew G. Knepley DMPlexRestoreClosureIndices - Restore the indices in a vector v for all points in the closure of the given point 55397cd05799SMatthew G. Knepley 55407cd05799SMatthew G. Knepley Not collective 55417cd05799SMatthew G. Knepley 55427cd05799SMatthew G. Knepley Input Parameters: 55437cd05799SMatthew G. Knepley + dm - The DM 55447cd05799SMatthew G. Knepley . section - The section describing the layout in v, or NULL to use the default section 55457cd05799SMatthew G. Knepley . globalSection - The section describing the parallel layout in v, or NULL to use the default section 55467cd05799SMatthew G. Knepley . point - The mesh point 55477cd05799SMatthew G. Knepley . numIndices - The number of indices 55487cd05799SMatthew G. Knepley . indices - The indices 55497cd05799SMatthew G. Knepley - outOffsets - Field offset if not NULL 55507cd05799SMatthew G. Knepley 55517cd05799SMatthew G. Knepley Level: advanced 55527cd05799SMatthew G. Knepley 55537cd05799SMatthew G. Knepley .seealso DMPlexGetClosureIndices(), DMPlexVecGetClosure(), DMPlexMatSetClosure() 55547cd05799SMatthew G. Knepley @*/ 555546bdb399SToby Isaac PetscErrorCode DMPlexRestoreClosureIndices(DM dm, PetscSection section, PetscSection globalSection, PetscInt point, PetscInt *numIndices, PetscInt **indices,PetscInt *outOffsets) 55567773e69fSMatthew G. Knepley { 55577773e69fSMatthew G. Knepley PetscErrorCode ierr; 55587773e69fSMatthew G. Knepley 55597773e69fSMatthew G. Knepley PetscFunctionBegin; 55607773e69fSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 55617773e69fSMatthew G. Knepley PetscValidPointer(indices, 5); 556269291d52SBarry Smith ierr = DMRestoreWorkArray(dm, 0, MPIU_INT, indices);CHKERRQ(ierr); 55637773e69fSMatthew G. Knepley PetscFunctionReturn(0); 55647773e69fSMatthew G. Knepley } 55657773e69fSMatthew G. Knepley 55667f5d1fdeSMatthew G. Knepley /*@C 55677f5d1fdeSMatthew G. Knepley DMPlexMatSetClosure - Set an array of the values on the closure of 'point' 55687f5d1fdeSMatthew G. Knepley 55697f5d1fdeSMatthew G. Knepley Not collective 55707f5d1fdeSMatthew G. Knepley 55717f5d1fdeSMatthew G. Knepley Input Parameters: 55727f5d1fdeSMatthew G. Knepley + dm - The DM 5573ebd6d717SJed Brown . section - The section describing the layout in v, or NULL to use the default section 5574ebd6d717SJed Brown . globalSection - The section describing the layout in v, or NULL to use the default global section 55757f5d1fdeSMatthew G. Knepley . A - The matrix 5576eaf898f9SPatrick Sanan . point - The point in the DM 55777f5d1fdeSMatthew G. Knepley . values - The array of values 55787f5d1fdeSMatthew G. Knepley - mode - The insert mode, where INSERT_ALL_VALUES and ADD_ALL_VALUES also overwrite boundary conditions 55797f5d1fdeSMatthew G. Knepley 55807f5d1fdeSMatthew G. Knepley Fortran Notes: 55817f5d1fdeSMatthew G. Knepley This routine is only available in Fortran 90, and you must include petsc.h90 in your code. 55827f5d1fdeSMatthew G. Knepley 55837f5d1fdeSMatthew G. Knepley Level: intermediate 55847f5d1fdeSMatthew G. Knepley 55857f5d1fdeSMatthew G. Knepley .seealso DMPlexVecGetClosure(), DMPlexVecSetClosure() 55867f5d1fdeSMatthew G. Knepley @*/ 55877c1f9639SMatthew G Knepley PetscErrorCode DMPlexMatSetClosure(DM dm, PetscSection section, PetscSection globalSection, Mat A, PetscInt point, const PetscScalar values[], InsertMode mode) 5588552f7358SJed Brown { 5589552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 55901b406b76SMatthew G. Knepley PetscSection clSection; 55911b406b76SMatthew G. Knepley IS clPoints; 5592d3d1a6afSToby Isaac PetscInt *points = NULL, *newPoints; 55931b406b76SMatthew G. Knepley const PetscInt *clp; 5594552f7358SJed Brown PetscInt *indices; 5595552f7358SJed Brown PetscInt offsets[32]; 55964acb8e1eSToby Isaac const PetscInt **perms[32] = {NULL}; 55974acb8e1eSToby Isaac const PetscScalar **flips[32] = {NULL}; 5598923c78e0SToby Isaac PetscInt numFields, numPoints, newNumPoints, numIndices, newNumIndices, dof, off, globalOff, p, f; 55994acb8e1eSToby Isaac PetscScalar *valCopy = NULL; 5600d3d1a6afSToby Isaac PetscScalar *newValues; 5601552f7358SJed Brown PetscErrorCode ierr; 5602552f7358SJed Brown 5603552f7358SJed Brown PetscFunctionBegin; 5604552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5605e87a4003SBarry Smith if (!section) {ierr = DMGetSection(dm, §ion);CHKERRQ(ierr);} 56063dc93601SMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 5607e87a4003SBarry Smith if (!globalSection) {ierr = DMGetGlobalSection(dm, &globalSection);CHKERRQ(ierr);} 56083dc93601SMatthew G. Knepley PetscValidHeaderSpecific(globalSection, PETSC_SECTION_CLASSID, 3); 56093dc93601SMatthew G. Knepley PetscValidHeaderSpecific(A, MAT_CLASSID, 4); 5610552f7358SJed Brown ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 561182f516ccSBarry Smith if (numFields > 31) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Number of fields %D limited to 31", numFields); 5612552f7358SJed Brown ierr = PetscMemzero(offsets, 32 * sizeof(PetscInt));CHKERRQ(ierr); 5613923c78e0SToby Isaac ierr = DMPlexGetCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 5614552f7358SJed Brown for (p = 0, numIndices = 0; p < numPoints*2; p += 2) { 5615552f7358SJed Brown PetscInt fdof; 5616552f7358SJed Brown 5617552f7358SJed Brown ierr = PetscSectionGetDof(section, points[p], &dof);CHKERRQ(ierr); 5618552f7358SJed Brown for (f = 0; f < numFields; ++f) { 5619552f7358SJed Brown ierr = PetscSectionGetFieldDof(section, points[p], f, &fdof);CHKERRQ(ierr); 5620552f7358SJed Brown offsets[f+1] += fdof; 5621552f7358SJed Brown } 5622552f7358SJed Brown numIndices += dof; 5623552f7358SJed Brown } 56240d644c17SKarl Rupp for (f = 1; f < numFields; ++f) offsets[f+1] += offsets[f]; 56250d644c17SKarl Rupp 56268ccfff9cSToby Isaac if (numFields && offsets[numFields] != numIndices) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", offsets[numFields], numIndices); 56274acb8e1eSToby Isaac /* Get symmetries */ 56284acb8e1eSToby Isaac for (f = 0; f < PetscMax(1,numFields); f++) { 56294acb8e1eSToby Isaac if (numFields) {ierr = PetscSectionGetFieldPointSyms(section,f,numPoints,points,&perms[f],&flips[f]);CHKERRQ(ierr);} 56304acb8e1eSToby Isaac else {ierr = PetscSectionGetPointSyms(section,numPoints,points,&perms[f],&flips[f]);CHKERRQ(ierr);} 56314acb8e1eSToby Isaac if (values && flips[f]) { /* may need to apply sign changes to the element matrix */ 56324acb8e1eSToby Isaac PetscInt foffset = offsets[f]; 56334acb8e1eSToby Isaac 56344acb8e1eSToby Isaac for (p = 0; p < numPoints; p++) { 56354acb8e1eSToby Isaac PetscInt point = points[2*p], fdof; 56364acb8e1eSToby Isaac const PetscScalar *flip = flips[f] ? flips[f][p] : NULL; 56374acb8e1eSToby Isaac 56384acb8e1eSToby Isaac if (!numFields) { 56394acb8e1eSToby Isaac ierr = PetscSectionGetDof(section,point,&fdof);CHKERRQ(ierr); 56404acb8e1eSToby Isaac } else { 56414acb8e1eSToby Isaac ierr = PetscSectionGetFieldDof(section,point,f,&fdof);CHKERRQ(ierr); 56424acb8e1eSToby Isaac } 56434acb8e1eSToby Isaac if (flip) { 56444acb8e1eSToby Isaac PetscInt i, j, k; 56454acb8e1eSToby Isaac 56464acb8e1eSToby Isaac if (!valCopy) { 564769291d52SBarry Smith ierr = DMGetWorkArray(dm,numIndices*numIndices,MPIU_SCALAR,&valCopy);CHKERRQ(ierr); 56484acb8e1eSToby Isaac for (j = 0; j < numIndices * numIndices; j++) valCopy[j] = values[j]; 56494acb8e1eSToby Isaac values = valCopy; 56504acb8e1eSToby Isaac } 56514acb8e1eSToby Isaac for (i = 0; i < fdof; i++) { 5652775f7be2SToby Isaac PetscScalar fval = flip[i]; 56534acb8e1eSToby Isaac 56544acb8e1eSToby Isaac for (k = 0; k < numIndices; k++) { 56554acb8e1eSToby Isaac valCopy[numIndices * (foffset + i) + k] *= fval; 56564acb8e1eSToby Isaac valCopy[numIndices * k + (foffset + i)] *= fval; 56574acb8e1eSToby Isaac } 56584acb8e1eSToby Isaac } 56594acb8e1eSToby Isaac } 56604acb8e1eSToby Isaac foffset += fdof; 56614acb8e1eSToby Isaac } 56624acb8e1eSToby Isaac } 56634acb8e1eSToby Isaac } 56644acb8e1eSToby Isaac ierr = DMPlexAnchorsModifyMat(dm,section,numPoints,numIndices,points,perms,values,&newNumPoints,&newNumIndices,&newPoints,&newValues,offsets,PETSC_TRUE);CHKERRQ(ierr); 5665d3d1a6afSToby Isaac if (newNumPoints) { 56664acb8e1eSToby Isaac if (valCopy) { 566769291d52SBarry Smith ierr = DMRestoreWorkArray(dm,numIndices*numIndices,MPIU_SCALAR,&valCopy);CHKERRQ(ierr); 56684acb8e1eSToby Isaac } 56694acb8e1eSToby Isaac for (f = 0; f < PetscMax(1,numFields); f++) { 56704acb8e1eSToby Isaac if (numFields) {ierr = PetscSectionRestoreFieldPointSyms(section,f,numPoints,points,&perms[f],&flips[f]);CHKERRQ(ierr);} 56714acb8e1eSToby Isaac else {ierr = PetscSectionRestorePointSyms(section,numPoints,points,&perms[f],&flips[f]);CHKERRQ(ierr);} 56724acb8e1eSToby Isaac } 56734acb8e1eSToby Isaac for (f = 0; f < PetscMax(1,numFields); f++) { 56744acb8e1eSToby Isaac if (numFields) {ierr = PetscSectionGetFieldPointSyms(section,f,newNumPoints,newPoints,&perms[f],&flips[f]);CHKERRQ(ierr);} 56754acb8e1eSToby Isaac else {ierr = PetscSectionGetPointSyms(section,newNumPoints,newPoints,&perms[f],&flips[f]);CHKERRQ(ierr);} 56764acb8e1eSToby Isaac } 5677923c78e0SToby Isaac ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 5678d3d1a6afSToby Isaac numPoints = newNumPoints; 5679d3d1a6afSToby Isaac numIndices = newNumIndices; 5680d3d1a6afSToby Isaac points = newPoints; 5681d3d1a6afSToby Isaac values = newValues; 5682d3d1a6afSToby Isaac } 568369291d52SBarry Smith ierr = DMGetWorkArray(dm, numIndices, MPIU_INT, &indices);CHKERRQ(ierr); 5684552f7358SJed Brown if (numFields) { 56857e29afd2SMatthew G. Knepley PetscBool useFieldOffsets; 56867e29afd2SMatthew G. Knepley 56877e29afd2SMatthew G. Knepley ierr = PetscSectionGetUseFieldOffsets(globalSection, &useFieldOffsets);CHKERRQ(ierr); 56887e29afd2SMatthew G. Knepley if (useFieldOffsets) { 56897e29afd2SMatthew G. Knepley for (p = 0; p < numPoints; p++) { 56907e29afd2SMatthew G. Knepley DMPlexGetIndicesPointFieldsSplit_Internal(section, globalSection, points[2*p], offsets, PETSC_FALSE, perms, p, indices); 56917e29afd2SMatthew G. Knepley } 56927e29afd2SMatthew G. Knepley } else { 56934acb8e1eSToby Isaac for (p = 0; p < numPoints; p++) { 56944acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalSection, points[2*p], &globalOff);CHKERRQ(ierr); 56954acb8e1eSToby Isaac DMPlexGetIndicesPointFields_Internal(section, points[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, offsets, PETSC_FALSE, perms, p, indices); 5696552f7358SJed Brown } 56977e29afd2SMatthew G. Knepley } 5698552f7358SJed Brown } else { 56994acb8e1eSToby Isaac for (p = 0, off = 0; p < numPoints; p++) { 57004acb8e1eSToby Isaac const PetscInt *perm = perms[0] ? perms[0][p] : NULL; 57014acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalSection, points[2*p], &globalOff);CHKERRQ(ierr); 57024acb8e1eSToby Isaac DMPlexGetIndicesPoint_Internal(section, points[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, perm, indices); 5703552f7358SJed Brown } 5704552f7358SJed Brown } 5705b0ecff45SMatthew G. Knepley if (mesh->printSetValues) {ierr = DMPlexPrintMatSetValues(PETSC_VIEWER_STDOUT_SELF, A, point, numIndices, indices, 0, NULL, values);CHKERRQ(ierr);} 5706552f7358SJed Brown ierr = MatSetValues(A, numIndices, indices, numIndices, indices, values, mode); 5707ab1d0545SMatthew G. Knepley if (mesh->printFEM > 1) { 5708ab1d0545SMatthew G. Knepley PetscInt i; 5709ab1d0545SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " Indices:");CHKERRQ(ierr); 57108ccfff9cSToby Isaac for (i = 0; i < numIndices; ++i) {ierr = PetscPrintf(PETSC_COMM_SELF, " %D", indices[i]);CHKERRQ(ierr);} 5711ab1d0545SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 5712ab1d0545SMatthew G. Knepley } 5713552f7358SJed Brown if (ierr) { 5714552f7358SJed Brown PetscMPIInt rank; 5715552f7358SJed Brown PetscErrorCode ierr2; 5716552f7358SJed Brown 571782f516ccSBarry Smith ierr2 = MPI_Comm_rank(PetscObjectComm((PetscObject)A), &rank);CHKERRQ(ierr2); 5718e4b003c7SBarry Smith ierr2 = (*PetscErrorPrintf)("[%d]ERROR in DMPlexMatSetClosure\n", rank);CHKERRQ(ierr2); 5719b0ecff45SMatthew G. Knepley ierr2 = DMPlexPrintMatSetValues(PETSC_VIEWER_STDERR_SELF, A, point, numIndices, indices, 0, NULL, values);CHKERRQ(ierr2); 572069291d52SBarry Smith ierr2 = DMRestoreWorkArray(dm, numIndices, MPIU_INT, &indices);CHKERRQ(ierr2); 5721552f7358SJed Brown CHKERRQ(ierr); 5722552f7358SJed Brown } 57234acb8e1eSToby Isaac for (f = 0; f < PetscMax(1,numFields); f++) { 57244acb8e1eSToby Isaac if (numFields) {ierr = PetscSectionRestoreFieldPointSyms(section,f,numPoints,points,&perms[f],&flips[f]);CHKERRQ(ierr);} 57254acb8e1eSToby Isaac else {ierr = PetscSectionRestorePointSyms(section,numPoints,points,&perms[f],&flips[f]);CHKERRQ(ierr);} 57264acb8e1eSToby Isaac } 5727d3d1a6afSToby Isaac if (newNumPoints) { 572869291d52SBarry Smith ierr = DMRestoreWorkArray(dm,newNumIndices*newNumIndices,MPIU_SCALAR,&newValues);CHKERRQ(ierr); 572969291d52SBarry Smith ierr = DMRestoreWorkArray(dm,2*newNumPoints,MPIU_INT,&newPoints);CHKERRQ(ierr); 5730d3d1a6afSToby Isaac } 5731d3d1a6afSToby Isaac else { 57324acb8e1eSToby Isaac if (valCopy) { 573369291d52SBarry Smith ierr = DMRestoreWorkArray(dm,numIndices*numIndices,MPIU_SCALAR,&valCopy);CHKERRQ(ierr); 57344acb8e1eSToby Isaac } 5735923c78e0SToby Isaac ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 5736d3d1a6afSToby Isaac } 573769291d52SBarry Smith ierr = DMRestoreWorkArray(dm, numIndices, MPIU_INT, &indices);CHKERRQ(ierr); 5738552f7358SJed Brown PetscFunctionReturn(0); 5739552f7358SJed Brown } 5740552f7358SJed Brown 5741de41b84cSMatthew 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) 5742de41b84cSMatthew G. Knepley { 5743de41b84cSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dmf->data; 5744de41b84cSMatthew G. Knepley PetscInt *fpoints = NULL, *ftotpoints = NULL; 5745de41b84cSMatthew G. Knepley PetscInt *cpoints = NULL; 5746de41b84cSMatthew G. Knepley PetscInt *findices, *cindices; 5747de41b84cSMatthew G. Knepley PetscInt foffsets[32], coffsets[32]; 5748de41b84cSMatthew G. Knepley CellRefiner cellRefiner; 57494ca5e9f5SMatthew G. Knepley PetscInt numFields, numSubcells, maxFPoints, numFPoints, numCPoints, numFIndices, numCIndices, dof, off, globalOff, pStart, pEnd, p, q, r, s, f; 5750de41b84cSMatthew G. Knepley PetscErrorCode ierr; 5751de41b84cSMatthew G. Knepley 5752de41b84cSMatthew G. Knepley PetscFunctionBegin; 5753de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(dmf, DM_CLASSID, 1); 5754de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(dmc, DM_CLASSID, 4); 5755e87a4003SBarry Smith if (!fsection) {ierr = DMGetSection(dmf, &fsection);CHKERRQ(ierr);} 5756de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(fsection, PETSC_SECTION_CLASSID, 2); 5757e87a4003SBarry Smith if (!csection) {ierr = DMGetSection(dmc, &csection);CHKERRQ(ierr);} 5758de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(csection, PETSC_SECTION_CLASSID, 5); 5759e87a4003SBarry Smith if (!globalFSection) {ierr = DMGetGlobalSection(dmf, &globalFSection);CHKERRQ(ierr);} 5760de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(globalFSection, PETSC_SECTION_CLASSID, 3); 5761e87a4003SBarry Smith if (!globalCSection) {ierr = DMGetGlobalSection(dmc, &globalCSection);CHKERRQ(ierr);} 5762de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(globalCSection, PETSC_SECTION_CLASSID, 6); 5763de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(A, MAT_CLASSID, 7); 5764de41b84cSMatthew G. Knepley ierr = PetscSectionGetNumFields(fsection, &numFields);CHKERRQ(ierr); 5765de41b84cSMatthew G. Knepley if (numFields > 31) SETERRQ1(PetscObjectComm((PetscObject)dmf), PETSC_ERR_ARG_OUTOFRANGE, "Number of fields %D limited to 31", numFields); 5766de41b84cSMatthew G. Knepley ierr = PetscMemzero(foffsets, 32 * sizeof(PetscInt));CHKERRQ(ierr); 5767de41b84cSMatthew G. Knepley ierr = PetscMemzero(coffsets, 32 * sizeof(PetscInt));CHKERRQ(ierr); 5768de41b84cSMatthew G. Knepley /* Column indices */ 5769de41b84cSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dmc, point, PETSC_TRUE, &numCPoints, &cpoints);CHKERRQ(ierr); 57704ca5e9f5SMatthew G. Knepley maxFPoints = numCPoints; 5771de41b84cSMatthew G. Knepley /* Compress out points not in the section */ 5772de41b84cSMatthew G. Knepley /* TODO: Squeeze out points with 0 dof as well */ 5773de41b84cSMatthew G. Knepley ierr = PetscSectionGetChart(csection, &pStart, &pEnd);CHKERRQ(ierr); 5774de41b84cSMatthew G. Knepley for (p = 0, q = 0; p < numCPoints*2; p += 2) { 5775de41b84cSMatthew G. Knepley if ((cpoints[p] >= pStart) && (cpoints[p] < pEnd)) { 5776de41b84cSMatthew G. Knepley cpoints[q*2] = cpoints[p]; 5777de41b84cSMatthew G. Knepley cpoints[q*2+1] = cpoints[p+1]; 5778de41b84cSMatthew G. Knepley ++q; 5779de41b84cSMatthew G. Knepley } 5780de41b84cSMatthew G. Knepley } 5781de41b84cSMatthew G. Knepley numCPoints = q; 5782de41b84cSMatthew G. Knepley for (p = 0, numCIndices = 0; p < numCPoints*2; p += 2) { 5783de41b84cSMatthew G. Knepley PetscInt fdof; 5784de41b84cSMatthew G. Knepley 5785de41b84cSMatthew G. Knepley ierr = PetscSectionGetDof(csection, cpoints[p], &dof);CHKERRQ(ierr); 57864ca5e9f5SMatthew G. Knepley if (!dof) continue; 5787de41b84cSMatthew G. Knepley for (f = 0; f < numFields; ++f) { 5788de41b84cSMatthew G. Knepley ierr = PetscSectionGetFieldDof(csection, cpoints[p], f, &fdof);CHKERRQ(ierr); 5789de41b84cSMatthew G. Knepley coffsets[f+1] += fdof; 5790de41b84cSMatthew G. Knepley } 5791de41b84cSMatthew G. Knepley numCIndices += dof; 5792de41b84cSMatthew G. Knepley } 5793de41b84cSMatthew G. Knepley for (f = 1; f < numFields; ++f) coffsets[f+1] += coffsets[f]; 5794de41b84cSMatthew G. Knepley /* Row indices */ 5795de41b84cSMatthew G. Knepley ierr = DMPlexGetCellRefiner_Internal(dmc, &cellRefiner);CHKERRQ(ierr); 5796de41b84cSMatthew G. Knepley ierr = CellRefinerGetAffineTransforms_Internal(cellRefiner, &numSubcells, NULL, NULL, NULL);CHKERRQ(ierr); 579769291d52SBarry Smith ierr = DMGetWorkArray(dmf, maxFPoints*2*numSubcells, MPIU_INT, &ftotpoints);CHKERRQ(ierr); 5798de41b84cSMatthew G. Knepley for (r = 0, q = 0; r < numSubcells; ++r) { 5799de41b84cSMatthew G. Knepley /* TODO Map from coarse to fine cells */ 5800de41b84cSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dmf, point*numSubcells + r, PETSC_TRUE, &numFPoints, &fpoints);CHKERRQ(ierr); 5801de41b84cSMatthew G. Knepley /* Compress out points not in the section */ 5802de41b84cSMatthew G. Knepley ierr = PetscSectionGetChart(fsection, &pStart, &pEnd);CHKERRQ(ierr); 5803de41b84cSMatthew G. Knepley for (p = 0; p < numFPoints*2; p += 2) { 5804de41b84cSMatthew G. Knepley if ((fpoints[p] >= pStart) && (fpoints[p] < pEnd)) { 58054ca5e9f5SMatthew G. Knepley ierr = PetscSectionGetDof(fsection, fpoints[p], &dof);CHKERRQ(ierr); 58064ca5e9f5SMatthew G. Knepley if (!dof) continue; 58074ca5e9f5SMatthew G. Knepley for (s = 0; s < q; ++s) if (fpoints[p] == ftotpoints[s*2]) break; 58084ca5e9f5SMatthew G. Knepley if (s < q) continue; 5809de41b84cSMatthew G. Knepley ftotpoints[q*2] = fpoints[p]; 5810de41b84cSMatthew G. Knepley ftotpoints[q*2+1] = fpoints[p+1]; 5811de41b84cSMatthew G. Knepley ++q; 5812de41b84cSMatthew G. Knepley } 5813de41b84cSMatthew G. Knepley } 5814de41b84cSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dmf, point, PETSC_TRUE, &numFPoints, &fpoints);CHKERRQ(ierr); 5815de41b84cSMatthew G. Knepley } 5816de41b84cSMatthew G. Knepley numFPoints = q; 5817de41b84cSMatthew G. Knepley for (p = 0, numFIndices = 0; p < numFPoints*2; p += 2) { 5818de41b84cSMatthew G. Knepley PetscInt fdof; 5819de41b84cSMatthew G. Knepley 5820de41b84cSMatthew G. Knepley ierr = PetscSectionGetDof(fsection, ftotpoints[p], &dof);CHKERRQ(ierr); 58214ca5e9f5SMatthew G. Knepley if (!dof) continue; 5822de41b84cSMatthew G. Knepley for (f = 0; f < numFields; ++f) { 5823de41b84cSMatthew G. Knepley ierr = PetscSectionGetFieldDof(fsection, ftotpoints[p], f, &fdof);CHKERRQ(ierr); 5824de41b84cSMatthew G. Knepley foffsets[f+1] += fdof; 5825de41b84cSMatthew G. Knepley } 5826de41b84cSMatthew G. Knepley numFIndices += dof; 5827de41b84cSMatthew G. Knepley } 5828de41b84cSMatthew G. Knepley for (f = 1; f < numFields; ++f) foffsets[f+1] += foffsets[f]; 5829de41b84cSMatthew G. Knepley 58308ccfff9cSToby Isaac if (numFields && foffsets[numFields] != numFIndices) SETERRQ2(PetscObjectComm((PetscObject)dmf), PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", foffsets[numFields], numFIndices); 58318ccfff9cSToby Isaac if (numFields && coffsets[numFields] != numCIndices) SETERRQ2(PetscObjectComm((PetscObject)dmc), PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", coffsets[numFields], numCIndices); 583269291d52SBarry Smith ierr = DMGetWorkArray(dmf, numFIndices, MPIU_INT, &findices);CHKERRQ(ierr); 583369291d52SBarry Smith ierr = DMGetWorkArray(dmc, numCIndices, MPIU_INT, &cindices);CHKERRQ(ierr); 5834de41b84cSMatthew G. Knepley if (numFields) { 58354acb8e1eSToby Isaac const PetscInt **permsF[32] = {NULL}; 58364acb8e1eSToby Isaac const PetscInt **permsC[32] = {NULL}; 58374acb8e1eSToby Isaac 58384acb8e1eSToby Isaac for (f = 0; f < numFields; f++) { 58394acb8e1eSToby Isaac ierr = PetscSectionGetFieldPointSyms(fsection,f,numFPoints,ftotpoints,&permsF[f],NULL);CHKERRQ(ierr); 58404acb8e1eSToby Isaac ierr = PetscSectionGetFieldPointSyms(csection,f,numCPoints,cpoints,&permsC[f],NULL);CHKERRQ(ierr); 5841de41b84cSMatthew G. Knepley } 58424acb8e1eSToby Isaac for (p = 0; p < numFPoints; p++) { 58434acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalFSection, ftotpoints[2*p], &globalOff);CHKERRQ(ierr); 5844367003a6SStefano Zampini ierr = DMPlexGetIndicesPointFields_Internal(fsection, ftotpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, foffsets, PETSC_FALSE, permsF, p, findices);CHKERRQ(ierr); 58454acb8e1eSToby Isaac } 58464acb8e1eSToby Isaac for (p = 0; p < numCPoints; p++) { 58474acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalCSection, cpoints[2*p], &globalOff);CHKERRQ(ierr); 5848367003a6SStefano Zampini ierr = DMPlexGetIndicesPointFields_Internal(csection, cpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, coffsets, PETSC_FALSE, permsC, p, cindices);CHKERRQ(ierr); 58494acb8e1eSToby Isaac } 58504acb8e1eSToby Isaac for (f = 0; f < numFields; f++) { 58514acb8e1eSToby Isaac ierr = PetscSectionRestoreFieldPointSyms(fsection,f,numFPoints,ftotpoints,&permsF[f],NULL);CHKERRQ(ierr); 58524acb8e1eSToby Isaac ierr = PetscSectionRestoreFieldPointSyms(csection,f,numCPoints,cpoints,&permsC[f],NULL);CHKERRQ(ierr); 5853de41b84cSMatthew G. Knepley } 5854de41b84cSMatthew G. Knepley } else { 58554acb8e1eSToby Isaac const PetscInt **permsF = NULL; 58564acb8e1eSToby Isaac const PetscInt **permsC = NULL; 58574acb8e1eSToby Isaac 58584acb8e1eSToby Isaac ierr = PetscSectionGetPointSyms(fsection,numFPoints,ftotpoints,&permsF,NULL);CHKERRQ(ierr); 58594acb8e1eSToby Isaac ierr = PetscSectionGetPointSyms(csection,numCPoints,cpoints,&permsC,NULL);CHKERRQ(ierr); 58604acb8e1eSToby Isaac for (p = 0, off = 0; p < numFPoints; p++) { 58614acb8e1eSToby Isaac const PetscInt *perm = permsF ? permsF[p] : NULL; 58624acb8e1eSToby Isaac 58634acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalFSection, ftotpoints[2*p], &globalOff);CHKERRQ(ierr); 58644acb8e1eSToby Isaac ierr = DMPlexGetIndicesPoint_Internal(fsection, ftotpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, perm, findices);CHKERRQ(ierr); 5865de41b84cSMatthew G. Knepley } 58664acb8e1eSToby Isaac for (p = 0, off = 0; p < numCPoints; p++) { 58674acb8e1eSToby Isaac const PetscInt *perm = permsC ? permsC[p] : NULL; 58684acb8e1eSToby Isaac 58694acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalCSection, cpoints[2*p], &globalOff);CHKERRQ(ierr); 58704acb8e1eSToby Isaac ierr = DMPlexGetIndicesPoint_Internal(csection, cpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, perm, cindices);CHKERRQ(ierr); 5871de41b84cSMatthew G. Knepley } 58724acb8e1eSToby Isaac ierr = PetscSectionRestorePointSyms(fsection,numFPoints,ftotpoints,&permsF,NULL);CHKERRQ(ierr); 58734acb8e1eSToby Isaac ierr = PetscSectionRestorePointSyms(csection,numCPoints,cpoints,&permsC,NULL);CHKERRQ(ierr); 5874de41b84cSMatthew G. Knepley } 5875de41b84cSMatthew G. Knepley if (mesh->printSetValues) {ierr = DMPlexPrintMatSetValues(PETSC_VIEWER_STDOUT_SELF, A, point, numFIndices, findices, numCIndices, cindices, values);CHKERRQ(ierr);} 58764acb8e1eSToby Isaac /* TODO: flips */ 5877de41b84cSMatthew G. Knepley ierr = MatSetValues(A, numFIndices, findices, numCIndices, cindices, values, mode); 5878de41b84cSMatthew G. Knepley if (ierr) { 5879de41b84cSMatthew G. Knepley PetscMPIInt rank; 5880de41b84cSMatthew G. Knepley PetscErrorCode ierr2; 5881de41b84cSMatthew G. Knepley 5882de41b84cSMatthew G. Knepley ierr2 = MPI_Comm_rank(PetscObjectComm((PetscObject)A), &rank);CHKERRQ(ierr2); 5883e4b003c7SBarry Smith ierr2 = (*PetscErrorPrintf)("[%d]ERROR in DMPlexMatSetClosure\n", rank);CHKERRQ(ierr2); 5884de41b84cSMatthew G. Knepley ierr2 = DMPlexPrintMatSetValues(PETSC_VIEWER_STDERR_SELF, A, point, numFIndices, findices, numCIndices, cindices, values);CHKERRQ(ierr2); 588569291d52SBarry Smith ierr2 = DMRestoreWorkArray(dmf, numFIndices, MPIU_INT, &findices);CHKERRQ(ierr2); 588669291d52SBarry Smith ierr2 = DMRestoreWorkArray(dmc, numCIndices, MPIU_INT, &cindices);CHKERRQ(ierr2); 5887de41b84cSMatthew G. Knepley CHKERRQ(ierr); 5888de41b84cSMatthew G. Knepley } 588969291d52SBarry Smith ierr = DMRestoreWorkArray(dmf, numCPoints*2*4, MPIU_INT, &ftotpoints);CHKERRQ(ierr); 5890de41b84cSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dmc, point, PETSC_TRUE, &numCPoints, &cpoints);CHKERRQ(ierr); 589169291d52SBarry Smith ierr = DMRestoreWorkArray(dmf, numFIndices, MPIU_INT, &findices);CHKERRQ(ierr); 589269291d52SBarry Smith ierr = DMRestoreWorkArray(dmc, numCIndices, MPIU_INT, &cindices);CHKERRQ(ierr); 5893de41b84cSMatthew G. Knepley PetscFunctionReturn(0); 5894de41b84cSMatthew G. Knepley } 5895de41b84cSMatthew G. Knepley 58967c927364SMatthew G. Knepley PetscErrorCode DMPlexMatGetClosureIndicesRefined(DM dmf, PetscSection fsection, PetscSection globalFSection, DM dmc, PetscSection csection, PetscSection globalCSection, PetscInt point, PetscInt cindices[], PetscInt findices[]) 58977c927364SMatthew G. Knepley { 58987c927364SMatthew G. Knepley PetscInt *fpoints = NULL, *ftotpoints = NULL; 58997c927364SMatthew G. Knepley PetscInt *cpoints = NULL; 59007c927364SMatthew G. Knepley PetscInt foffsets[32], coffsets[32]; 59017c927364SMatthew G. Knepley CellRefiner cellRefiner; 59027c927364SMatthew G. Knepley PetscInt numFields, numSubcells, maxFPoints, numFPoints, numCPoints, numFIndices, numCIndices, dof, off, globalOff, pStart, pEnd, p, q, r, s, f; 59037c927364SMatthew G. Knepley PetscErrorCode ierr; 59047c927364SMatthew G. Knepley 59057c927364SMatthew G. Knepley PetscFunctionBegin; 59067c927364SMatthew G. Knepley PetscValidHeaderSpecific(dmf, DM_CLASSID, 1); 59077c927364SMatthew G. Knepley PetscValidHeaderSpecific(dmc, DM_CLASSID, 4); 5908e87a4003SBarry Smith if (!fsection) {ierr = DMGetSection(dmf, &fsection);CHKERRQ(ierr);} 59097c927364SMatthew G. Knepley PetscValidHeaderSpecific(fsection, PETSC_SECTION_CLASSID, 2); 5910e87a4003SBarry Smith if (!csection) {ierr = DMGetSection(dmc, &csection);CHKERRQ(ierr);} 59117c927364SMatthew G. Knepley PetscValidHeaderSpecific(csection, PETSC_SECTION_CLASSID, 5); 5912e87a4003SBarry Smith if (!globalFSection) {ierr = DMGetGlobalSection(dmf, &globalFSection);CHKERRQ(ierr);} 59137c927364SMatthew G. Knepley PetscValidHeaderSpecific(globalFSection, PETSC_SECTION_CLASSID, 3); 5914e87a4003SBarry Smith if (!globalCSection) {ierr = DMGetGlobalSection(dmc, &globalCSection);CHKERRQ(ierr);} 59157c927364SMatthew G. Knepley PetscValidHeaderSpecific(globalCSection, PETSC_SECTION_CLASSID, 6); 59167c927364SMatthew G. Knepley ierr = PetscSectionGetNumFields(fsection, &numFields);CHKERRQ(ierr); 59177c927364SMatthew G. Knepley if (numFields > 31) SETERRQ1(PetscObjectComm((PetscObject)dmf), PETSC_ERR_ARG_OUTOFRANGE, "Number of fields %D limited to 31", numFields); 59187c927364SMatthew G. Knepley ierr = PetscMemzero(foffsets, 32 * sizeof(PetscInt));CHKERRQ(ierr); 59197c927364SMatthew G. Knepley ierr = PetscMemzero(coffsets, 32 * sizeof(PetscInt));CHKERRQ(ierr); 59207c927364SMatthew G. Knepley /* Column indices */ 59217c927364SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dmc, point, PETSC_TRUE, &numCPoints, &cpoints);CHKERRQ(ierr); 59227c927364SMatthew G. Knepley maxFPoints = numCPoints; 59237c927364SMatthew G. Knepley /* Compress out points not in the section */ 59247c927364SMatthew G. Knepley /* TODO: Squeeze out points with 0 dof as well */ 59257c927364SMatthew G. Knepley ierr = PetscSectionGetChart(csection, &pStart, &pEnd);CHKERRQ(ierr); 59267c927364SMatthew G. Knepley for (p = 0, q = 0; p < numCPoints*2; p += 2) { 59277c927364SMatthew G. Knepley if ((cpoints[p] >= pStart) && (cpoints[p] < pEnd)) { 59287c927364SMatthew G. Knepley cpoints[q*2] = cpoints[p]; 59297c927364SMatthew G. Knepley cpoints[q*2+1] = cpoints[p+1]; 59307c927364SMatthew G. Knepley ++q; 59317c927364SMatthew G. Knepley } 59327c927364SMatthew G. Knepley } 59337c927364SMatthew G. Knepley numCPoints = q; 59347c927364SMatthew G. Knepley for (p = 0, numCIndices = 0; p < numCPoints*2; p += 2) { 59357c927364SMatthew G. Knepley PetscInt fdof; 59367c927364SMatthew G. Knepley 59377c927364SMatthew G. Knepley ierr = PetscSectionGetDof(csection, cpoints[p], &dof);CHKERRQ(ierr); 59387c927364SMatthew G. Knepley if (!dof) continue; 59397c927364SMatthew G. Knepley for (f = 0; f < numFields; ++f) { 59407c927364SMatthew G. Knepley ierr = PetscSectionGetFieldDof(csection, cpoints[p], f, &fdof);CHKERRQ(ierr); 59417c927364SMatthew G. Knepley coffsets[f+1] += fdof; 59427c927364SMatthew G. Knepley } 59437c927364SMatthew G. Knepley numCIndices += dof; 59447c927364SMatthew G. Knepley } 59457c927364SMatthew G. Knepley for (f = 1; f < numFields; ++f) coffsets[f+1] += coffsets[f]; 59467c927364SMatthew G. Knepley /* Row indices */ 59477c927364SMatthew G. Knepley ierr = DMPlexGetCellRefiner_Internal(dmc, &cellRefiner);CHKERRQ(ierr); 59487c927364SMatthew G. Knepley ierr = CellRefinerGetAffineTransforms_Internal(cellRefiner, &numSubcells, NULL, NULL, NULL);CHKERRQ(ierr); 594969291d52SBarry Smith ierr = DMGetWorkArray(dmf, maxFPoints*2*numSubcells, MPIU_INT, &ftotpoints);CHKERRQ(ierr); 59507c927364SMatthew G. Knepley for (r = 0, q = 0; r < numSubcells; ++r) { 59517c927364SMatthew G. Knepley /* TODO Map from coarse to fine cells */ 59527c927364SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dmf, point*numSubcells + r, PETSC_TRUE, &numFPoints, &fpoints);CHKERRQ(ierr); 59537c927364SMatthew G. Knepley /* Compress out points not in the section */ 59547c927364SMatthew G. Knepley ierr = PetscSectionGetChart(fsection, &pStart, &pEnd);CHKERRQ(ierr); 59557c927364SMatthew G. Knepley for (p = 0; p < numFPoints*2; p += 2) { 59567c927364SMatthew G. Knepley if ((fpoints[p] >= pStart) && (fpoints[p] < pEnd)) { 59577c927364SMatthew G. Knepley ierr = PetscSectionGetDof(fsection, fpoints[p], &dof);CHKERRQ(ierr); 59587c927364SMatthew G. Knepley if (!dof) continue; 59597c927364SMatthew G. Knepley for (s = 0; s < q; ++s) if (fpoints[p] == ftotpoints[s*2]) break; 59607c927364SMatthew G. Knepley if (s < q) continue; 59617c927364SMatthew G. Knepley ftotpoints[q*2] = fpoints[p]; 59627c927364SMatthew G. Knepley ftotpoints[q*2+1] = fpoints[p+1]; 59637c927364SMatthew G. Knepley ++q; 59647c927364SMatthew G. Knepley } 59657c927364SMatthew G. Knepley } 59667c927364SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dmf, point, PETSC_TRUE, &numFPoints, &fpoints);CHKERRQ(ierr); 59677c927364SMatthew G. Knepley } 59687c927364SMatthew G. Knepley numFPoints = q; 59697c927364SMatthew G. Knepley for (p = 0, numFIndices = 0; p < numFPoints*2; p += 2) { 59707c927364SMatthew G. Knepley PetscInt fdof; 59717c927364SMatthew G. Knepley 59727c927364SMatthew G. Knepley ierr = PetscSectionGetDof(fsection, ftotpoints[p], &dof);CHKERRQ(ierr); 59737c927364SMatthew G. Knepley if (!dof) continue; 59747c927364SMatthew G. Knepley for (f = 0; f < numFields; ++f) { 59757c927364SMatthew G. Knepley ierr = PetscSectionGetFieldDof(fsection, ftotpoints[p], f, &fdof);CHKERRQ(ierr); 59767c927364SMatthew G. Knepley foffsets[f+1] += fdof; 59777c927364SMatthew G. Knepley } 59787c927364SMatthew G. Knepley numFIndices += dof; 59797c927364SMatthew G. Knepley } 59807c927364SMatthew G. Knepley for (f = 1; f < numFields; ++f) foffsets[f+1] += foffsets[f]; 59817c927364SMatthew G. Knepley 59828ccfff9cSToby Isaac if (numFields && foffsets[numFields] != numFIndices) SETERRQ2(PetscObjectComm((PetscObject)dmf), PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", foffsets[numFields], numFIndices); 59838ccfff9cSToby Isaac if (numFields && coffsets[numFields] != numCIndices) SETERRQ2(PetscObjectComm((PetscObject)dmc), PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", coffsets[numFields], numCIndices); 59847c927364SMatthew G. Knepley if (numFields) { 59854acb8e1eSToby Isaac const PetscInt **permsF[32] = {NULL}; 59864acb8e1eSToby Isaac const PetscInt **permsC[32] = {NULL}; 59874acb8e1eSToby Isaac 59884acb8e1eSToby Isaac for (f = 0; f < numFields; f++) { 59894acb8e1eSToby Isaac ierr = PetscSectionGetFieldPointSyms(fsection,f,numFPoints,ftotpoints,&permsF[f],NULL);CHKERRQ(ierr); 59904acb8e1eSToby Isaac ierr = PetscSectionGetFieldPointSyms(csection,f,numCPoints,cpoints,&permsC[f],NULL);CHKERRQ(ierr); 59917c927364SMatthew G. Knepley } 59924acb8e1eSToby Isaac for (p = 0; p < numFPoints; p++) { 59934acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalFSection, ftotpoints[2*p], &globalOff);CHKERRQ(ierr); 59944acb8e1eSToby Isaac DMPlexGetIndicesPointFields_Internal(fsection, ftotpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, foffsets, PETSC_FALSE, permsF, p, findices); 59954acb8e1eSToby Isaac } 59964acb8e1eSToby Isaac for (p = 0; p < numCPoints; p++) { 59974acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalCSection, cpoints[2*p], &globalOff);CHKERRQ(ierr); 59984acb8e1eSToby Isaac DMPlexGetIndicesPointFields_Internal(csection, cpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, coffsets, PETSC_FALSE, permsC, p, cindices); 59994acb8e1eSToby Isaac } 60004acb8e1eSToby Isaac for (f = 0; f < numFields; f++) { 60014acb8e1eSToby Isaac ierr = PetscSectionRestoreFieldPointSyms(fsection,f,numFPoints,ftotpoints,&permsF[f],NULL);CHKERRQ(ierr); 60024acb8e1eSToby Isaac ierr = PetscSectionRestoreFieldPointSyms(csection,f,numCPoints,cpoints,&permsC[f],NULL);CHKERRQ(ierr); 60037c927364SMatthew G. Knepley } 60047c927364SMatthew G. Knepley } else { 60054acb8e1eSToby Isaac const PetscInt **permsF = NULL; 60064acb8e1eSToby Isaac const PetscInt **permsC = NULL; 60074acb8e1eSToby Isaac 60084acb8e1eSToby Isaac ierr = PetscSectionGetPointSyms(fsection,numFPoints,ftotpoints,&permsF,NULL);CHKERRQ(ierr); 60094acb8e1eSToby Isaac ierr = PetscSectionGetPointSyms(csection,numCPoints,cpoints,&permsC,NULL);CHKERRQ(ierr); 60104acb8e1eSToby Isaac for (p = 0, off = 0; p < numFPoints; p++) { 60114acb8e1eSToby Isaac const PetscInt *perm = permsF ? permsF[p] : NULL; 60124acb8e1eSToby Isaac 60134acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalFSection, ftotpoints[2*p], &globalOff);CHKERRQ(ierr); 60144acb8e1eSToby Isaac DMPlexGetIndicesPoint_Internal(fsection, ftotpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, perm, findices); 60157c927364SMatthew G. Knepley } 60164acb8e1eSToby Isaac for (p = 0, off = 0; p < numCPoints; p++) { 60174acb8e1eSToby Isaac const PetscInt *perm = permsC ? permsC[p] : NULL; 60184acb8e1eSToby Isaac 60194acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalCSection, cpoints[2*p], &globalOff);CHKERRQ(ierr); 60204acb8e1eSToby Isaac DMPlexGetIndicesPoint_Internal(csection, cpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, perm, cindices); 60217c927364SMatthew G. Knepley } 60224acb8e1eSToby Isaac ierr = PetscSectionRestorePointSyms(fsection,numFPoints,ftotpoints,&permsF,NULL);CHKERRQ(ierr); 60234acb8e1eSToby Isaac ierr = PetscSectionRestorePointSyms(csection,numCPoints,cpoints,&permsC,NULL);CHKERRQ(ierr); 60247c927364SMatthew G. Knepley } 602569291d52SBarry Smith ierr = DMRestoreWorkArray(dmf, numCPoints*2*4, MPIU_INT, &ftotpoints);CHKERRQ(ierr); 60267c927364SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dmc, point, PETSC_TRUE, &numCPoints, &cpoints);CHKERRQ(ierr); 60277c927364SMatthew G. Knepley PetscFunctionReturn(0); 60287c927364SMatthew G. Knepley } 60297c927364SMatthew G. Knepley 6030f96281f8SMatthew G. Knepley /*@ 6031f96281f8SMatthew G. Knepley DMPlexGetHybridBounds - Get the first mesh point of each dimension which is a hybrid 6032f96281f8SMatthew G. Knepley 6033f96281f8SMatthew G. Knepley Input Parameter: 6034f96281f8SMatthew G. Knepley . dm - The DMPlex object 6035f96281f8SMatthew G. Knepley 6036f96281f8SMatthew G. Knepley Output Parameters: 6037f96281f8SMatthew G. Knepley + cMax - The first hybrid cell 6038dc5a3409SMatthew G. Knepley . fMax - The first hybrid face 6039dc5a3409SMatthew G. Knepley . eMax - The first hybrid edge 6040dc5a3409SMatthew G. Knepley - vMax - The first hybrid vertex 6041f96281f8SMatthew G. Knepley 6042f96281f8SMatthew G. Knepley Level: developer 6043f96281f8SMatthew G. Knepley 6044dc5a3409SMatthew G. Knepley .seealso DMPlexCreateHybridMesh(), DMPlexSetHybridBounds() 6045f96281f8SMatthew G. Knepley @*/ 6046770b213bSMatthew G Knepley PetscErrorCode DMPlexGetHybridBounds(DM dm, PetscInt *cMax, PetscInt *fMax, PetscInt *eMax, PetscInt *vMax) 6047552f7358SJed Brown { 6048552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 6049770b213bSMatthew G Knepley PetscInt dim; 6050770b213bSMatthew G Knepley PetscErrorCode ierr; 6051552f7358SJed Brown 6052552f7358SJed Brown PetscFunctionBegin; 6053552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6054c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 60557d5acc75SStefano Zampini if (dim < 0) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM dimension not yet set"); 6056770b213bSMatthew G Knepley if (cMax) *cMax = mesh->hybridPointMax[dim]; 60577d5acc75SStefano Zampini if (fMax) *fMax = mesh->hybridPointMax[PetscMax(dim-1,0)]; 6058770b213bSMatthew G Knepley if (eMax) *eMax = mesh->hybridPointMax[1]; 6059770b213bSMatthew G Knepley if (vMax) *vMax = mesh->hybridPointMax[0]; 6060552f7358SJed Brown PetscFunctionReturn(0); 6061552f7358SJed Brown } 6062552f7358SJed Brown 6063aeadca18SToby Isaac static PetscErrorCode DMPlexCreateDimStratum(DM dm, DMLabel depthLabel, DMLabel dimLabel, PetscInt d, PetscInt dMax) 60644a3e9fdbSToby Isaac { 60654a3e9fdbSToby Isaac IS is, his; 60667d5acc75SStefano Zampini PetscInt first = 0, stride; 60674a3e9fdbSToby Isaac PetscBool isStride; 60684a3e9fdbSToby Isaac PetscErrorCode ierr; 60694a3e9fdbSToby Isaac 60704a3e9fdbSToby Isaac PetscFunctionBegin; 60714a3e9fdbSToby Isaac ierr = DMLabelGetStratumIS(depthLabel, d, &is);CHKERRQ(ierr); 60724a3e9fdbSToby Isaac ierr = PetscObjectTypeCompare((PetscObject) is, ISSTRIDE, &isStride);CHKERRQ(ierr); 60734a3e9fdbSToby Isaac if (isStride) { 60744a3e9fdbSToby Isaac ierr = ISStrideGetInfo(is, &first, &stride);CHKERRQ(ierr); 60754a3e9fdbSToby Isaac } 60767d5acc75SStefano 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); 60774a3e9fdbSToby Isaac ierr = ISCreateStride(PETSC_COMM_SELF, (dMax - first), first, 1, &his);CHKERRQ(ierr); 6078aeadca18SToby Isaac ierr = DMLabelSetStratumIS(dimLabel, d, his);CHKERRQ(ierr); 60794a3e9fdbSToby Isaac ierr = ISDestroy(&his);CHKERRQ(ierr); 60804a3e9fdbSToby Isaac ierr = ISDestroy(&is);CHKERRQ(ierr); 60814a3e9fdbSToby Isaac PetscFunctionReturn(0); 60824a3e9fdbSToby Isaac } 60834a3e9fdbSToby Isaac 6084dc5a3409SMatthew G. Knepley /*@ 6085dc5a3409SMatthew G. Knepley DMPlexSetHybridBounds - Set the first mesh point of each dimension which is a hybrid 6086dc5a3409SMatthew G. Knepley 6087dc5a3409SMatthew G. Knepley Input Parameters: 6088dc5a3409SMatthew G. Knepley . dm - The DMPlex object 6089dc5a3409SMatthew G. Knepley . cMax - The first hybrid cell 6090dc5a3409SMatthew G. Knepley . fMax - The first hybrid face 6091dc5a3409SMatthew G. Knepley . eMax - The first hybrid edge 6092dc5a3409SMatthew G. Knepley - vMax - The first hybrid vertex 6093dc5a3409SMatthew G. Knepley 6094dc5a3409SMatthew G. Knepley Level: developer 6095dc5a3409SMatthew G. Knepley 6096dc5a3409SMatthew G. Knepley .seealso DMPlexCreateHybridMesh(), DMPlexGetHybridBounds() 6097dc5a3409SMatthew G. Knepley @*/ 6098770b213bSMatthew G Knepley PetscErrorCode DMPlexSetHybridBounds(DM dm, PetscInt cMax, PetscInt fMax, PetscInt eMax, PetscInt vMax) 6099552f7358SJed Brown { 6100552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 6101770b213bSMatthew G Knepley PetscInt dim; 6102770b213bSMatthew G Knepley PetscErrorCode ierr; 6103552f7358SJed Brown 6104552f7358SJed Brown PetscFunctionBegin; 6105552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6106c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 61077d5acc75SStefano Zampini if (dim < 0) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM dimension not yet set"); 6108770b213bSMatthew G Knepley if (cMax >= 0) mesh->hybridPointMax[dim] = cMax; 61097d5acc75SStefano Zampini if (fMax >= 0) mesh->hybridPointMax[PetscMax(dim-1,0)] = fMax; 6110770b213bSMatthew G Knepley if (eMax >= 0) mesh->hybridPointMax[1] = eMax; 6111770b213bSMatthew G Knepley if (vMax >= 0) mesh->hybridPointMax[0] = vMax; 6112552f7358SJed Brown PetscFunctionReturn(0); 6113552f7358SJed Brown } 6114552f7358SJed Brown 61157cd05799SMatthew G. Knepley /*@C 61167cd05799SMatthew G. Knepley DMPlexGetVTKCellHeight - Returns the height in the DAG used to determine which points are cells (normally 0) 61177cd05799SMatthew G. Knepley 61187cd05799SMatthew G. Knepley Input Parameter: 61197cd05799SMatthew G. Knepley . dm - The DMPlex object 61207cd05799SMatthew G. Knepley 61217cd05799SMatthew G. Knepley Output Parameter: 61227cd05799SMatthew G. Knepley . cellHeight - The height of a cell 61237cd05799SMatthew G. Knepley 61247cd05799SMatthew G. Knepley Level: developer 61257cd05799SMatthew G. Knepley 61267cd05799SMatthew G. Knepley .seealso DMPlexSetVTKCellHeight() 61277cd05799SMatthew G. Knepley @*/ 6128552f7358SJed Brown PetscErrorCode DMPlexGetVTKCellHeight(DM dm, PetscInt *cellHeight) 6129552f7358SJed Brown { 6130552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 6131552f7358SJed Brown 6132552f7358SJed Brown PetscFunctionBegin; 6133552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6134552f7358SJed Brown PetscValidPointer(cellHeight, 2); 6135552f7358SJed Brown *cellHeight = mesh->vtkCellHeight; 6136552f7358SJed Brown PetscFunctionReturn(0); 6137552f7358SJed Brown } 6138552f7358SJed Brown 61397cd05799SMatthew G. Knepley /*@C 61407cd05799SMatthew G. Knepley DMPlexSetVTKCellHeight - Sets the height in the DAG used to determine which points are cells (normally 0) 61417cd05799SMatthew G. Knepley 61427cd05799SMatthew G. Knepley Input Parameters: 61437cd05799SMatthew G. Knepley + dm - The DMPlex object 61447cd05799SMatthew G. Knepley - cellHeight - The height of a cell 61457cd05799SMatthew G. Knepley 61467cd05799SMatthew G. Knepley Level: developer 61477cd05799SMatthew G. Knepley 61487cd05799SMatthew G. Knepley .seealso DMPlexGetVTKCellHeight() 61497cd05799SMatthew G. Knepley @*/ 6150552f7358SJed Brown PetscErrorCode DMPlexSetVTKCellHeight(DM dm, PetscInt cellHeight) 6151552f7358SJed Brown { 6152552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 6153552f7358SJed Brown 6154552f7358SJed Brown PetscFunctionBegin; 6155552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6156552f7358SJed Brown mesh->vtkCellHeight = cellHeight; 6157552f7358SJed Brown PetscFunctionReturn(0); 6158552f7358SJed Brown } 6159552f7358SJed Brown 6160552f7358SJed Brown /* We can easily have a form that takes an IS instead */ 616150ad7711SMatthew G. Knepley PetscErrorCode DMPlexCreateNumbering_Internal(DM dm, PetscInt pStart, PetscInt pEnd, PetscInt shift, PetscInt *globalSize, PetscSF sf, IS *numbering) 6162552f7358SJed Brown { 6163552f7358SJed Brown PetscSection section, globalSection; 6164552f7358SJed Brown PetscInt *numbers, p; 6165552f7358SJed Brown PetscErrorCode ierr; 6166552f7358SJed Brown 6167552f7358SJed Brown PetscFunctionBegin; 616882f516ccSBarry Smith ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), §ion);CHKERRQ(ierr); 6169552f7358SJed Brown ierr = PetscSectionSetChart(section, pStart, pEnd);CHKERRQ(ierr); 6170552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 6171552f7358SJed Brown ierr = PetscSectionSetDof(section, p, 1);CHKERRQ(ierr); 6172552f7358SJed Brown } 6173552f7358SJed Brown ierr = PetscSectionSetUp(section);CHKERRQ(ierr); 617415b58121SMatthew G. Knepley ierr = PetscSectionCreateGlobalSection(section, sf, PETSC_FALSE, PETSC_FALSE, &globalSection);CHKERRQ(ierr); 6175854ce69bSBarry Smith ierr = PetscMalloc1(pEnd - pStart, &numbers);CHKERRQ(ierr); 6176552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 6177552f7358SJed Brown ierr = PetscSectionGetOffset(globalSection, p, &numbers[p-pStart]);CHKERRQ(ierr); 6178ef48cebcSMatthew G. Knepley if (numbers[p-pStart] < 0) numbers[p-pStart] -= shift; 6179ef48cebcSMatthew G. Knepley else numbers[p-pStart] += shift; 6180552f7358SJed Brown } 618182f516ccSBarry Smith ierr = ISCreateGeneral(PetscObjectComm((PetscObject) dm), pEnd - pStart, numbers, PETSC_OWN_POINTER, numbering);CHKERRQ(ierr); 6182ef48cebcSMatthew G. Knepley if (globalSize) { 6183ef48cebcSMatthew G. Knepley PetscLayout layout; 6184ef48cebcSMatthew G. Knepley ierr = PetscSectionGetPointLayout(PetscObjectComm((PetscObject) dm), globalSection, &layout);CHKERRQ(ierr); 6185ef48cebcSMatthew G. Knepley ierr = PetscLayoutGetSize(layout, globalSize);CHKERRQ(ierr); 6186ef48cebcSMatthew G. Knepley ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr); 6187ef48cebcSMatthew G. Knepley } 6188552f7358SJed Brown ierr = PetscSectionDestroy(§ion);CHKERRQ(ierr); 6189552f7358SJed Brown ierr = PetscSectionDestroy(&globalSection);CHKERRQ(ierr); 6190552f7358SJed Brown PetscFunctionReturn(0); 6191552f7358SJed Brown } 6192552f7358SJed Brown 619381ed3555SMatthew G. Knepley PetscErrorCode DMPlexCreateCellNumbering_Internal(DM dm, PetscBool includeHybrid, IS *globalCellNumbers) 6194552f7358SJed Brown { 6195552f7358SJed Brown PetscInt cellHeight, cStart, cEnd, cMax; 6196552f7358SJed Brown PetscErrorCode ierr; 6197552f7358SJed Brown 6198552f7358SJed Brown PetscFunctionBegin; 6199552f7358SJed Brown ierr = DMPlexGetVTKCellHeight(dm, &cellHeight);CHKERRQ(ierr); 6200552f7358SJed Brown ierr = DMPlexGetHeightStratum(dm, cellHeight, &cStart, &cEnd);CHKERRQ(ierr); 62010298fd71SBarry Smith ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr); 620281ed3555SMatthew G. Knepley if (cMax >= 0 && !includeHybrid) cEnd = PetscMin(cEnd, cMax); 620350ad7711SMatthew G. Knepley ierr = DMPlexCreateNumbering_Internal(dm, cStart, cEnd, 0, NULL, dm->sf, globalCellNumbers);CHKERRQ(ierr); 620481ed3555SMatthew G. Knepley PetscFunctionReturn(0); 6205552f7358SJed Brown } 620681ed3555SMatthew G. Knepley 62078dab3259SMatthew G. Knepley /*@ 62087cd05799SMatthew G. Knepley DMPlexGetCellNumbering - Get a global cell numbering for all cells on this process 62097cd05799SMatthew G. Knepley 62107cd05799SMatthew G. Knepley Input Parameter: 62117cd05799SMatthew G. Knepley . dm - The DMPlex object 62127cd05799SMatthew G. Knepley 62137cd05799SMatthew G. Knepley Output Parameter: 62147cd05799SMatthew G. Knepley . globalCellNumbers - Global cell numbers for all cells on this process 62157cd05799SMatthew G. Knepley 62167cd05799SMatthew G. Knepley Level: developer 62177cd05799SMatthew G. Knepley 62187cd05799SMatthew G. Knepley .seealso DMPlexGetVertexNumbering() 62197cd05799SMatthew G. Knepley @*/ 622081ed3555SMatthew G. Knepley PetscErrorCode DMPlexGetCellNumbering(DM dm, IS *globalCellNumbers) 622181ed3555SMatthew G. Knepley { 622281ed3555SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 622381ed3555SMatthew G. Knepley PetscErrorCode ierr; 622481ed3555SMatthew G. Knepley 622581ed3555SMatthew G. Knepley PetscFunctionBegin; 622681ed3555SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 622781ed3555SMatthew G. Knepley if (!mesh->globalCellNumbers) {ierr = DMPlexCreateCellNumbering_Internal(dm, PETSC_FALSE, &mesh->globalCellNumbers);CHKERRQ(ierr);} 6228552f7358SJed Brown *globalCellNumbers = mesh->globalCellNumbers; 6229552f7358SJed Brown PetscFunctionReturn(0); 6230552f7358SJed Brown } 6231552f7358SJed Brown 623281ed3555SMatthew G. Knepley PetscErrorCode DMPlexCreateVertexNumbering_Internal(DM dm, PetscBool includeHybrid, IS *globalVertexNumbers) 623381ed3555SMatthew G. Knepley { 623481ed3555SMatthew G. Knepley PetscInt vStart, vEnd, vMax; 623581ed3555SMatthew G. Knepley PetscErrorCode ierr; 623681ed3555SMatthew G. Knepley 623781ed3555SMatthew G. Knepley PetscFunctionBegin; 623881ed3555SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 623981ed3555SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 624081ed3555SMatthew G. Knepley ierr = DMPlexGetHybridBounds(dm, NULL, NULL, NULL, &vMax);CHKERRQ(ierr); 624181ed3555SMatthew G. Knepley if (vMax >= 0 && !includeHybrid) vEnd = PetscMin(vEnd, vMax); 624250ad7711SMatthew G. Knepley ierr = DMPlexCreateNumbering_Internal(dm, vStart, vEnd, 0, NULL, dm->sf, globalVertexNumbers);CHKERRQ(ierr); 624381ed3555SMatthew G. Knepley PetscFunctionReturn(0); 624481ed3555SMatthew G. Knepley } 624581ed3555SMatthew G. Knepley 62468dab3259SMatthew G. Knepley /*@ 62477cd05799SMatthew G. Knepley DMPlexGetVertexNumbering - Get a global certex numbering for all vertices on this process 62487cd05799SMatthew G. Knepley 62497cd05799SMatthew G. Knepley Input Parameter: 62507cd05799SMatthew G. Knepley . dm - The DMPlex object 62517cd05799SMatthew G. Knepley 62527cd05799SMatthew G. Knepley Output Parameter: 62537cd05799SMatthew G. Knepley . globalVertexNumbers - Global vertex numbers for all vertices on this process 62547cd05799SMatthew G. Knepley 62557cd05799SMatthew G. Knepley Level: developer 62567cd05799SMatthew G. Knepley 62577cd05799SMatthew G. Knepley .seealso DMPlexGetCellNumbering() 62587cd05799SMatthew G. Knepley @*/ 6259552f7358SJed Brown PetscErrorCode DMPlexGetVertexNumbering(DM dm, IS *globalVertexNumbers) 6260552f7358SJed Brown { 6261552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 6262552f7358SJed Brown PetscErrorCode ierr; 6263552f7358SJed Brown 6264552f7358SJed Brown PetscFunctionBegin; 6265552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 626681ed3555SMatthew G. Knepley if (!mesh->globalVertexNumbers) {ierr = DMPlexCreateVertexNumbering_Internal(dm, PETSC_FALSE, &mesh->globalVertexNumbers);CHKERRQ(ierr);} 6267552f7358SJed Brown *globalVertexNumbers = mesh->globalVertexNumbers; 6268552f7358SJed Brown PetscFunctionReturn(0); 6269552f7358SJed Brown } 6270552f7358SJed Brown 62718dab3259SMatthew G. Knepley /*@ 62727cd05799SMatthew G. Knepley DMPlexCreatePointNumbering - Create a global numbering for all points on this process 62737cd05799SMatthew G. Knepley 62747cd05799SMatthew G. Knepley Input Parameter: 62757cd05799SMatthew G. Knepley . dm - The DMPlex object 62767cd05799SMatthew G. Knepley 62777cd05799SMatthew G. Knepley Output Parameter: 62787cd05799SMatthew G. Knepley . globalPointNumbers - Global numbers for all points on this process 62797cd05799SMatthew G. Knepley 62807cd05799SMatthew G. Knepley Level: developer 62817cd05799SMatthew G. Knepley 62827cd05799SMatthew G. Knepley .seealso DMPlexGetCellNumbering() 62837cd05799SMatthew G. Knepley @*/ 6284ef48cebcSMatthew G. Knepley PetscErrorCode DMPlexCreatePointNumbering(DM dm, IS *globalPointNumbers) 6285ef48cebcSMatthew G. Knepley { 6286ef48cebcSMatthew G. Knepley IS nums[4]; 6287862913ffSStefano Zampini PetscInt depths[4], gdepths[4], starts[4]; 6288ef48cebcSMatthew G. Knepley PetscInt depth, d, shift = 0; 6289ef48cebcSMatthew G. Knepley PetscErrorCode ierr; 6290ef48cebcSMatthew G. Knepley 6291ef48cebcSMatthew G. Knepley PetscFunctionBegin; 6292ef48cebcSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6293ef48cebcSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 62948abc87a0SMichael Lange /* For unstratified meshes use dim instead of depth */ 62958abc87a0SMichael Lange if (depth < 0) {ierr = DMGetDimension(dm, &depth);CHKERRQ(ierr);} 6296862913ffSStefano Zampini for (d = 0; d <= depth; ++d) { 6297862913ffSStefano Zampini PetscInt end; 6298862913ffSStefano Zampini 6299862913ffSStefano Zampini depths[d] = depth-d; 6300862913ffSStefano Zampini ierr = DMPlexGetDepthStratum(dm, depths[d], &starts[d], &end);CHKERRQ(ierr); 6301862913ffSStefano Zampini if (!(starts[d]-end)) { starts[d] = depths[d] = -1; } 6302862913ffSStefano Zampini } 6303862913ffSStefano Zampini ierr = PetscSortIntWithArray(depth+1, starts, depths);CHKERRQ(ierr); 6304862913ffSStefano Zampini ierr = MPIU_Allreduce(depths, gdepths, depth+1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject) dm));CHKERRQ(ierr); 6305862913ffSStefano Zampini for (d = 0; d <= depth; ++d) { 6306862913ffSStefano 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]); 6307862913ffSStefano Zampini } 6308ef48cebcSMatthew G. Knepley for (d = 0; d <= depth; ++d) { 6309ef48cebcSMatthew G. Knepley PetscInt pStart, pEnd, gsize; 6310ef48cebcSMatthew G. Knepley 6311862913ffSStefano Zampini ierr = DMPlexGetDepthStratum(dm, gdepths[d], &pStart, &pEnd);CHKERRQ(ierr); 631250ad7711SMatthew G. Knepley ierr = DMPlexCreateNumbering_Internal(dm, pStart, pEnd, shift, &gsize, dm->sf, &nums[d]);CHKERRQ(ierr); 6313ef48cebcSMatthew G. Knepley shift += gsize; 6314ef48cebcSMatthew G. Knepley } 6315302440fdSBarry Smith ierr = ISConcatenate(PetscObjectComm((PetscObject) dm), depth+1, nums, globalPointNumbers);CHKERRQ(ierr); 6316ef48cebcSMatthew G. Knepley for (d = 0; d <= depth; ++d) {ierr = ISDestroy(&nums[d]);CHKERRQ(ierr);} 6317ef48cebcSMatthew G. Knepley PetscFunctionReturn(0); 6318ef48cebcSMatthew G. Knepley } 6319ef48cebcSMatthew G. Knepley 632008a22f4bSMatthew G. Knepley 632108a22f4bSMatthew G. Knepley /*@ 632208a22f4bSMatthew G. Knepley DMPlexCreateRankField - Create a cell field whose value is the rank of the owner 632308a22f4bSMatthew G. Knepley 632408a22f4bSMatthew G. Knepley Input Parameter: 632508a22f4bSMatthew G. Knepley . dm - The DMPlex object 632608a22f4bSMatthew G. Knepley 632708a22f4bSMatthew G. Knepley Output Parameter: 632808a22f4bSMatthew G. Knepley . ranks - The rank field 632908a22f4bSMatthew G. Knepley 633008a22f4bSMatthew G. Knepley Options Database Keys: 633108a22f4bSMatthew G. Knepley . -dm_partition_view - Adds the rank field into the DM output from -dm_view using the same viewer 633208a22f4bSMatthew G. Knepley 633308a22f4bSMatthew G. Knepley Level: intermediate 633408a22f4bSMatthew G. Knepley 633508a22f4bSMatthew G. Knepley .seealso: DMView() 633608a22f4bSMatthew G. Knepley @*/ 633708a22f4bSMatthew G. Knepley PetscErrorCode DMPlexCreateRankField(DM dm, Vec *ranks) 633808a22f4bSMatthew G. Knepley { 633908a22f4bSMatthew G. Knepley DM rdm; 634008a22f4bSMatthew G. Knepley PetscFE fe; 634108a22f4bSMatthew G. Knepley PetscScalar *r; 634208a22f4bSMatthew G. Knepley PetscMPIInt rank; 634308a22f4bSMatthew G. Knepley PetscInt dim, cStart, cEnd, c; 634408a22f4bSMatthew G. Knepley PetscErrorCode ierr; 634508a22f4bSMatthew G. Knepley 634608a22f4bSMatthew G. Knepley PetscFunctionBeginUser; 6347f95ace6aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6348f95ace6aSMatthew G. Knepley PetscValidPointer(ranks, 2); 634908a22f4bSMatthew G. Knepley ierr = MPI_Comm_rank(PetscObjectComm((PetscObject) dm), &rank);CHKERRQ(ierr); 635008a22f4bSMatthew G. Knepley ierr = DMClone(dm, &rdm);CHKERRQ(ierr); 635108a22f4bSMatthew G. Knepley ierr = DMGetDimension(rdm, &dim);CHKERRQ(ierr); 6352f95ace6aSMatthew G. Knepley ierr = PetscFECreateDefault(PetscObjectComm((PetscObject) rdm), dim, 1, PETSC_TRUE, "PETSc___rank_", -1, &fe);CHKERRQ(ierr); 635308a22f4bSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) fe, "rank");CHKERRQ(ierr); 6354e5e52638SMatthew G. Knepley ierr = DMSetField(rdm, 0, NULL, (PetscObject) fe);CHKERRQ(ierr); 635508a22f4bSMatthew G. Knepley ierr = PetscFEDestroy(&fe);CHKERRQ(ierr); 6356e5e52638SMatthew G. Knepley ierr = DMCreateDS(rdm);CHKERRQ(ierr); 635708a22f4bSMatthew G. Knepley ierr = DMPlexGetHeightStratum(rdm, 0, &cStart, &cEnd);CHKERRQ(ierr); 635808a22f4bSMatthew G. Knepley ierr = DMCreateGlobalVector(rdm, ranks);CHKERRQ(ierr); 635908a22f4bSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) *ranks, "partition");CHKERRQ(ierr); 636008a22f4bSMatthew G. Knepley ierr = VecGetArray(*ranks, &r);CHKERRQ(ierr); 636108a22f4bSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 636208a22f4bSMatthew G. Knepley PetscScalar *lr; 636308a22f4bSMatthew G. Knepley 636408a22f4bSMatthew G. Knepley ierr = DMPlexPointGlobalRef(rdm, c, r, &lr);CHKERRQ(ierr); 636508a22f4bSMatthew G. Knepley *lr = rank; 636608a22f4bSMatthew G. Knepley } 636708a22f4bSMatthew G. Knepley ierr = VecRestoreArray(*ranks, &r);CHKERRQ(ierr); 636808a22f4bSMatthew G. Knepley ierr = DMDestroy(&rdm);CHKERRQ(ierr); 636908a22f4bSMatthew G. Knepley PetscFunctionReturn(0); 637008a22f4bSMatthew G. Knepley } 637108a22f4bSMatthew G. Knepley 6372ca8062c8SMatthew G. Knepley /*@ 637318e14f0cSMatthew G. Knepley DMPlexCreateLabelField - Create a cell field whose value is the label value for that cell 637418e14f0cSMatthew G. Knepley 637518e14f0cSMatthew G. Knepley Input Parameters: 637618e14f0cSMatthew G. Knepley + dm - The DMPlex 637718e14f0cSMatthew G. Knepley - label - The DMLabel 637818e14f0cSMatthew G. Knepley 637918e14f0cSMatthew G. Knepley Output Parameter: 638018e14f0cSMatthew G. Knepley . val - The label value field 638118e14f0cSMatthew G. Knepley 638218e14f0cSMatthew G. Knepley Options Database Keys: 638318e14f0cSMatthew G. Knepley . -dm_label_view - Adds the label value field into the DM output from -dm_view using the same viewer 638418e14f0cSMatthew G. Knepley 638518e14f0cSMatthew G. Knepley Level: intermediate 638618e14f0cSMatthew G. Knepley 638718e14f0cSMatthew G. Knepley .seealso: DMView() 638818e14f0cSMatthew G. Knepley @*/ 638918e14f0cSMatthew G. Knepley PetscErrorCode DMPlexCreateLabelField(DM dm, DMLabel label, Vec *val) 639018e14f0cSMatthew G. Knepley { 639118e14f0cSMatthew G. Knepley DM rdm; 639218e14f0cSMatthew G. Knepley PetscFE fe; 639318e14f0cSMatthew G. Knepley PetscScalar *v; 639418e14f0cSMatthew G. Knepley PetscInt dim, cStart, cEnd, c; 639518e14f0cSMatthew G. Knepley PetscErrorCode ierr; 639618e14f0cSMatthew G. Knepley 639718e14f0cSMatthew G. Knepley PetscFunctionBeginUser; 639818e14f0cSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 639918e14f0cSMatthew G. Knepley PetscValidPointer(label, 2); 640018e14f0cSMatthew G. Knepley PetscValidPointer(val, 3); 640118e14f0cSMatthew G. Knepley ierr = DMClone(dm, &rdm);CHKERRQ(ierr); 640218e14f0cSMatthew G. Knepley ierr = DMGetDimension(rdm, &dim);CHKERRQ(ierr); 640318e14f0cSMatthew G. Knepley ierr = PetscFECreateDefault(PetscObjectComm((PetscObject) rdm), dim, 1, PETSC_TRUE, "PETSc___label_value_", -1, &fe);CHKERRQ(ierr); 640418e14f0cSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) fe, "label_value");CHKERRQ(ierr); 6405e5e52638SMatthew G. Knepley ierr = DMSetField(rdm, 0, NULL, (PetscObject) fe);CHKERRQ(ierr); 640618e14f0cSMatthew G. Knepley ierr = PetscFEDestroy(&fe);CHKERRQ(ierr); 6407e5e52638SMatthew G. Knepley ierr = DMCreateDS(rdm);CHKERRQ(ierr); 640818e14f0cSMatthew G. Knepley ierr = DMPlexGetHeightStratum(rdm, 0, &cStart, &cEnd);CHKERRQ(ierr); 640918e14f0cSMatthew G. Knepley ierr = DMCreateGlobalVector(rdm, val);CHKERRQ(ierr); 6410effbd7cbSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) *val, "label_value");CHKERRQ(ierr); 641118e14f0cSMatthew G. Knepley ierr = VecGetArray(*val, &v);CHKERRQ(ierr); 641218e14f0cSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 641318e14f0cSMatthew G. Knepley PetscScalar *lv; 641418e14f0cSMatthew G. Knepley PetscInt cval; 641518e14f0cSMatthew G. Knepley 641618e14f0cSMatthew G. Knepley ierr = DMPlexPointGlobalRef(rdm, c, v, &lv);CHKERRQ(ierr); 641718e14f0cSMatthew G. Knepley ierr = DMLabelGetValue(label, c, &cval);CHKERRQ(ierr); 641818e14f0cSMatthew G. Knepley *lv = cval; 641918e14f0cSMatthew G. Knepley } 642018e14f0cSMatthew G. Knepley ierr = VecRestoreArray(*val, &v);CHKERRQ(ierr); 642118e14f0cSMatthew G. Knepley ierr = DMDestroy(&rdm);CHKERRQ(ierr); 642218e14f0cSMatthew G. Knepley PetscFunctionReturn(0); 642318e14f0cSMatthew G. Knepley } 642418e14f0cSMatthew G. Knepley 642518e14f0cSMatthew G. Knepley /*@ 6426ca8062c8SMatthew G. Knepley DMPlexCheckSymmetry - Check that the adjacency information in the mesh is symmetric. 6427ca8062c8SMatthew G. Knepley 642869916449SMatthew G. Knepley Input Parameter: 642969916449SMatthew G. Knepley . dm - The DMPlex object 6430ca8062c8SMatthew G. Knepley 6431ca8062c8SMatthew G. Knepley Note: This is a useful diagnostic when creating meshes programmatically. 6432ca8062c8SMatthew G. Knepley 6433ca8062c8SMatthew G. Knepley Level: developer 6434ca8062c8SMatthew G. Knepley 64357d5acc75SStefano Zampini .seealso: DMCreate(), DMPlexCheckSkeleton(), DMPlexCheckFaces() 6436ca8062c8SMatthew G. Knepley @*/ 6437ca8062c8SMatthew G. Knepley PetscErrorCode DMPlexCheckSymmetry(DM dm) 6438ca8062c8SMatthew G. Knepley { 6439ca8062c8SMatthew G. Knepley PetscSection coneSection, supportSection; 6440ca8062c8SMatthew G. Knepley const PetscInt *cone, *support; 6441ca8062c8SMatthew G. Knepley PetscInt coneSize, c, supportSize, s; 644257beb4faSStefano Zampini PetscInt pStart, pEnd, p, pp, csize, ssize; 644357beb4faSStefano Zampini PetscBool storagecheck = PETSC_TRUE; 6444ca8062c8SMatthew G. Knepley PetscErrorCode ierr; 6445ca8062c8SMatthew G. Knepley 6446ca8062c8SMatthew G. Knepley PetscFunctionBegin; 6447ca8062c8SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6448ca8062c8SMatthew G. Knepley ierr = DMPlexGetConeSection(dm, &coneSection);CHKERRQ(ierr); 6449ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupportSection(dm, &supportSection);CHKERRQ(ierr); 6450ca8062c8SMatthew G. Knepley /* Check that point p is found in the support of its cone points, and vice versa */ 6451ca8062c8SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 6452ca8062c8SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 6453ca8062c8SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, p, &coneSize);CHKERRQ(ierr); 6454ca8062c8SMatthew G. Knepley ierr = DMPlexGetCone(dm, p, &cone);CHKERRQ(ierr); 6455ca8062c8SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 645642e66dfaSMatthew G. Knepley PetscBool dup = PETSC_FALSE; 645742e66dfaSMatthew G. Knepley PetscInt d; 645842e66dfaSMatthew G. Knepley for (d = c-1; d >= 0; --d) { 645942e66dfaSMatthew G. Knepley if (cone[c] == cone[d]) {dup = PETSC_TRUE; break;} 646042e66dfaSMatthew G. Knepley } 6461ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, cone[c], &supportSize);CHKERRQ(ierr); 6462ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupport(dm, cone[c], &support);CHKERRQ(ierr); 6463ca8062c8SMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 6464ca8062c8SMatthew G. Knepley if (support[s] == p) break; 6465ca8062c8SMatthew G. Knepley } 646642e66dfaSMatthew G. Knepley if ((s >= supportSize) || (dup && (support[s+1] != p))) { 64678ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "p: %D cone: ", p);CHKERRQ(ierr); 6468ca8062c8SMatthew G. Knepley for (s = 0; s < coneSize; ++s) { 64698ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "%D, ", cone[s]);CHKERRQ(ierr); 6470ca8062c8SMatthew G. Knepley } 6471302440fdSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 64728ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "p: %D support: ", cone[c]);CHKERRQ(ierr); 6473ca8062c8SMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 64748ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "%D, ", support[s]);CHKERRQ(ierr); 6475ca8062c8SMatthew G. Knepley } 6476302440fdSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 64778ccfff9cSToby 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]); 64788ccfff9cSToby Isaac else SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D not found in support of cone point %D", p, cone[c]); 6479ca8062c8SMatthew G. Knepley } 648042e66dfaSMatthew G. Knepley } 648157beb4faSStefano Zampini ierr = DMPlexGetTreeParent(dm, p, &pp, NULL);CHKERRQ(ierr); 648257beb4faSStefano Zampini if (p != pp) { storagecheck = PETSC_FALSE; continue; } 6483ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, p, &supportSize);CHKERRQ(ierr); 6484ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupport(dm, p, &support);CHKERRQ(ierr); 6485ca8062c8SMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 6486ca8062c8SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6487ca8062c8SMatthew G. Knepley ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6488ca8062c8SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 648957beb4faSStefano Zampini ierr = DMPlexGetTreeParent(dm, cone[c], &pp, NULL);CHKERRQ(ierr); 649057beb4faSStefano Zampini if (cone[c] != pp) { c = 0; break; } 6491ca8062c8SMatthew G. Knepley if (cone[c] == p) break; 6492ca8062c8SMatthew G. Knepley } 6493ca8062c8SMatthew G. Knepley if (c >= coneSize) { 64948ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "p: %D support: ", p);CHKERRQ(ierr); 6495ca8062c8SMatthew G. Knepley for (c = 0; c < supportSize; ++c) { 64968ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "%D, ", support[c]);CHKERRQ(ierr); 6497ca8062c8SMatthew G. Knepley } 6498302440fdSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 64998ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "p: %D cone: ", support[s]);CHKERRQ(ierr); 6500ca8062c8SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 65018ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "%D, ", cone[c]);CHKERRQ(ierr); 6502ca8062c8SMatthew G. Knepley } 6503302440fdSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 65048ccfff9cSToby Isaac SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D not found in cone of support point %D", p, support[s]); 6505ca8062c8SMatthew G. Knepley } 6506ca8062c8SMatthew G. Knepley } 6507ca8062c8SMatthew G. Knepley } 650857beb4faSStefano Zampini if (storagecheck) { 6509ca8062c8SMatthew G. Knepley ierr = PetscSectionGetStorageSize(coneSection, &csize);CHKERRQ(ierr); 6510ca8062c8SMatthew G. Knepley ierr = PetscSectionGetStorageSize(supportSection, &ssize);CHKERRQ(ierr); 65118ccfff9cSToby Isaac if (csize != ssize) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Total cone size %D != Total support size %D", csize, ssize); 651257beb4faSStefano Zampini } 6513ca8062c8SMatthew G. Knepley PetscFunctionReturn(0); 6514ca8062c8SMatthew G. Knepley } 6515ca8062c8SMatthew G. Knepley 6516ca8062c8SMatthew G. Knepley /*@ 6517ca8062c8SMatthew G. Knepley DMPlexCheckSkeleton - Check that each cell has the correct number of vertices 6518ca8062c8SMatthew G. Knepley 6519ca8062c8SMatthew G. Knepley Input Parameters: 6520ca8062c8SMatthew G. Knepley + dm - The DMPlex object 652158723a97SMatthew G. Knepley . isSimplex - Are the cells simplices or tensor products 652258723a97SMatthew G. Knepley - cellHeight - Normally 0 6523ca8062c8SMatthew G. Knepley 6524ca8062c8SMatthew G. Knepley Note: This is a useful diagnostic when creating meshes programmatically. 6525ca8062c8SMatthew G. Knepley 6526ca8062c8SMatthew G. Knepley Level: developer 6527ca8062c8SMatthew G. Knepley 65287d5acc75SStefano Zampini .seealso: DMCreate(), DMPlexCheckSymmetry(), DMPlexCheckFaces() 6529ca8062c8SMatthew G. Knepley @*/ 653058723a97SMatthew G. Knepley PetscErrorCode DMPlexCheckSkeleton(DM dm, PetscBool isSimplex, PetscInt cellHeight) 6531ca8062c8SMatthew G. Knepley { 653242363296SMatthew G. Knepley PetscInt dim, numCorners, numHybridCorners, vStart, vEnd, cStart, cEnd, cMax, c; 6533ca8062c8SMatthew G. Knepley PetscErrorCode ierr; 6534ca8062c8SMatthew G. Knepley 6535ca8062c8SMatthew G. Knepley PetscFunctionBegin; 6536ca8062c8SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6537c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 6538ca8062c8SMatthew G. Knepley switch (dim) { 653942363296SMatthew G. Knepley case 1: numCorners = isSimplex ? 2 : 2; numHybridCorners = isSimplex ? 2 : 2; break; 654042363296SMatthew G. Knepley case 2: numCorners = isSimplex ? 3 : 4; numHybridCorners = isSimplex ? 4 : 4; break; 654142363296SMatthew G. Knepley case 3: numCorners = isSimplex ? 4 : 8; numHybridCorners = isSimplex ? 6 : 8; break; 6542ca8062c8SMatthew G. Knepley default: 65438ccfff9cSToby Isaac SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle meshes of dimension %D", dim); 6544ca8062c8SMatthew G. Knepley } 654558723a97SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 654658723a97SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, cellHeight, &cStart, &cEnd);CHKERRQ(ierr); 6547ca8062c8SMatthew G. Knepley ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr); 6548ca8062c8SMatthew G. Knepley cMax = cMax >= 0 ? cMax : cEnd; 6549ca8062c8SMatthew G. Knepley for (c = cStart; c < cMax; ++c) { 655058723a97SMatthew G. Knepley PetscInt *closure = NULL, closureSize, cl, coneSize = 0; 655158723a97SMatthew G. Knepley 655258723a97SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 655358723a97SMatthew G. Knepley for (cl = 0; cl < closureSize*2; cl += 2) { 655458723a97SMatthew G. Knepley const PetscInt p = closure[cl]; 655558723a97SMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) ++coneSize; 655658723a97SMatthew G. Knepley } 655758723a97SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 65588ccfff9cSToby Isaac if (coneSize != numCorners) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cell %D has %D vertices != %D", c, coneSize, numCorners); 6559ca8062c8SMatthew G. Knepley } 656042363296SMatthew G. Knepley for (c = cMax; c < cEnd; ++c) { 656142363296SMatthew G. Knepley PetscInt *closure = NULL, closureSize, cl, coneSize = 0; 656242363296SMatthew G. Knepley 656342363296SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 656442363296SMatthew G. Knepley for (cl = 0; cl < closureSize*2; cl += 2) { 656542363296SMatthew G. Knepley const PetscInt p = closure[cl]; 656642363296SMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) ++coneSize; 656742363296SMatthew G. Knepley } 656842363296SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 65698ccfff9cSToby Isaac if (coneSize > numHybridCorners) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Hybrid cell %D has %D vertices > %D", c, coneSize, numHybridCorners); 657042363296SMatthew G. Knepley } 6571ca8062c8SMatthew G. Knepley PetscFunctionReturn(0); 6572ca8062c8SMatthew G. Knepley } 65739bf0dad6SMatthew G. Knepley 65749bf0dad6SMatthew G. Knepley /*@ 65759bf0dad6SMatthew 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 65769bf0dad6SMatthew G. Knepley 65779bf0dad6SMatthew G. Knepley Input Parameters: 65789bf0dad6SMatthew G. Knepley + dm - The DMPlex object 65799bf0dad6SMatthew G. Knepley . isSimplex - Are the cells simplices or tensor products 65809bf0dad6SMatthew G. Knepley - cellHeight - Normally 0 65819bf0dad6SMatthew G. Knepley 65829bf0dad6SMatthew G. Knepley Note: This is a useful diagnostic when creating meshes programmatically. 65839bf0dad6SMatthew G. Knepley 65849bf0dad6SMatthew G. Knepley Level: developer 65859bf0dad6SMatthew G. Knepley 65867d5acc75SStefano Zampini .seealso: DMCreate(), DMPlexCheckSymmetry(), DMPlexCheckSkeleton() 65879bf0dad6SMatthew G. Knepley @*/ 65889bf0dad6SMatthew G. Knepley PetscErrorCode DMPlexCheckFaces(DM dm, PetscBool isSimplex, PetscInt cellHeight) 65899bf0dad6SMatthew G. Knepley { 65903554e41dSMatthew G. Knepley PetscInt pMax[4]; 6591ab91121cSMatthew G. Knepley PetscInt dim, depth, vStart, vEnd, cStart, cEnd, c, h; 65929bf0dad6SMatthew G. Knepley PetscErrorCode ierr; 65939bf0dad6SMatthew G. Knepley 65949bf0dad6SMatthew G. Knepley PetscFunctionBegin; 65959bf0dad6SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6596c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 6597ab91121cSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 65989bf0dad6SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 659925abba81SMatthew G. Knepley ierr = DMPlexGetHybridBounds(dm, &pMax[dim], &pMax[dim-1], &pMax[1], &pMax[0]);CHKERRQ(ierr); 6600ab91121cSMatthew G. Knepley for (h = cellHeight; h < PetscMin(depth, dim); ++h) { 66013554e41dSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, h, &cStart, &cEnd);CHKERRQ(ierr); 66023554e41dSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 66039bf0dad6SMatthew G. Knepley const PetscInt *cone, *ornt, *faces; 66049bf0dad6SMatthew G. Knepley PetscInt numFaces, faceSize, coneSize,f; 66059bf0dad6SMatthew G. Knepley PetscInt *closure = NULL, closureSize, cl, numCorners = 0; 66069bf0dad6SMatthew G. Knepley 660725abba81SMatthew G. Knepley if (pMax[dim-h] >= 0 && c >= pMax[dim-h]) continue; 66089bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, c, &coneSize);CHKERRQ(ierr); 66099bf0dad6SMatthew G. Knepley ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 66109bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 66119bf0dad6SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 66129bf0dad6SMatthew G. Knepley for (cl = 0; cl < closureSize*2; cl += 2) { 66139bf0dad6SMatthew G. Knepley const PetscInt p = closure[cl]; 66149bf0dad6SMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) closure[numCorners++] = p; 66159bf0dad6SMatthew G. Knepley } 66163554e41dSMatthew G. Knepley ierr = DMPlexGetRawFaces_Internal(dm, dim-h, numCorners, closure, &numFaces, &faceSize, &faces);CHKERRQ(ierr); 66178ccfff9cSToby Isaac if (coneSize != numFaces) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cell %D has %D faces but should have %D", c, coneSize, numFaces); 66189bf0dad6SMatthew G. Knepley for (f = 0; f < numFaces; ++f) { 66199bf0dad6SMatthew G. Knepley PetscInt *fclosure = NULL, fclosureSize, cl, fnumCorners = 0, v; 66209bf0dad6SMatthew G. Knepley 66219bf0dad6SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure_Internal(dm, cone[f], ornt[f], PETSC_TRUE, &fclosureSize, &fclosure);CHKERRQ(ierr); 66229bf0dad6SMatthew G. Knepley for (cl = 0; cl < fclosureSize*2; cl += 2) { 66239bf0dad6SMatthew G. Knepley const PetscInt p = fclosure[cl]; 66249bf0dad6SMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) fclosure[fnumCorners++] = p; 66259bf0dad6SMatthew G. Knepley } 66268ccfff9cSToby 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); 66279bf0dad6SMatthew G. Knepley for (v = 0; v < fnumCorners; ++v) { 66288ccfff9cSToby 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]); 66299bf0dad6SMatthew G. Knepley } 66309bf0dad6SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, cone[f], PETSC_TRUE, &fclosureSize, &fclosure);CHKERRQ(ierr); 66319bf0dad6SMatthew G. Knepley } 66329bf0dad6SMatthew G. Knepley ierr = DMPlexRestoreFaces_Internal(dm, dim, c, &numFaces, &faceSize, &faces);CHKERRQ(ierr); 66339bf0dad6SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 66349bf0dad6SMatthew G. Knepley } 66353554e41dSMatthew G. Knepley } 6636552f7358SJed Brown PetscFunctionReturn(0); 6637552f7358SJed Brown } 66383913d7c8SMatthew G. Knepley 6639bb6a34a8SMatthew G. Knepley /*@ 6640bb6a34a8SMatthew G. Knepley DMPlexCheckGeometry - Check the geometry of mesh cells 6641bb6a34a8SMatthew G. Knepley 6642bb6a34a8SMatthew G. Knepley Input Parameter: 6643bb6a34a8SMatthew G. Knepley . dm - The DMPlex object 6644bb6a34a8SMatthew G. Knepley 6645bb6a34a8SMatthew G. Knepley Note: This is a useful diagnostic when creating meshes programmatically. 6646bb6a34a8SMatthew G. Knepley 6647bb6a34a8SMatthew G. Knepley Level: developer 6648bb6a34a8SMatthew G. Knepley 6649bb6a34a8SMatthew G. Knepley .seealso: DMCreate(), DMCheckSymmetry(), DMCheckSkeleton(), DMCheckFaces() 6650bb6a34a8SMatthew G. Knepley @*/ 6651bb6a34a8SMatthew G. Knepley PetscErrorCode DMPlexCheckGeometry(DM dm) 6652bb6a34a8SMatthew G. Knepley { 6653bb6a34a8SMatthew G. Knepley PetscReal detJ, J[9], refVol = 1.0; 6654bb6a34a8SMatthew G. Knepley PetscReal vol; 6655bb6a34a8SMatthew G. Knepley PetscInt dim, depth, d, cStart, cEnd, c; 6656bb6a34a8SMatthew G. Knepley PetscErrorCode ierr; 6657bb6a34a8SMatthew G. Knepley 6658bb6a34a8SMatthew G. Knepley PetscFunctionBegin; 6659bb6a34a8SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 6660bb6a34a8SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 6661bb6a34a8SMatthew G. Knepley for (d = 0; d < dim; ++d) refVol *= 2.0; 6662bb6a34a8SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 6663bb6a34a8SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 6664bb6a34a8SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFEM(dm, c, NULL, NULL, J, NULL, &detJ);CHKERRQ(ierr); 6665bb6a34a8SMatthew G. Knepley if (detJ <= 0.0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Mesh cell %D is inverted, |J| = %g", c, (double) detJ); 6666bb6a34a8SMatthew G. Knepley ierr = PetscInfo2(dm, "Cell %D FEM Volume %g\n", c, (double) detJ*refVol);CHKERRQ(ierr); 6667bb6a34a8SMatthew G. Knepley if (depth > 1) { 6668bb6a34a8SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFVM(dm, c, &vol, NULL, NULL);CHKERRQ(ierr); 6669bb6a34a8SMatthew G. Knepley if (vol <= 0.0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Mesh cell %d is inverted, vol = %g", c, (double) vol); 6670bb6a34a8SMatthew G. Knepley ierr = PetscInfo2(dm, "Cell %D FVM Volume %g\n", c, (double) vol);CHKERRQ(ierr); 6671bb6a34a8SMatthew G. Knepley } 6672bb6a34a8SMatthew G. Knepley } 6673bb6a34a8SMatthew G. Knepley PetscFunctionReturn(0); 6674bb6a34a8SMatthew G. Knepley } 6675bb6a34a8SMatthew G. Knepley 667603da9461SVaclav Hapla static PetscErrorCode DMPlexAreAllConePointsInArray_Private(DM dm, PetscInt p, PetscInt npoints, const PetscInt *points, PetscInt *missingPoint) 667703da9461SVaclav Hapla { 667803da9461SVaclav Hapla PetscInt i,l,n; 667903da9461SVaclav Hapla const PetscInt *cone; 668003da9461SVaclav Hapla PetscErrorCode ierr; 668103da9461SVaclav Hapla 668203da9461SVaclav Hapla PetscFunctionBegin; 668303da9461SVaclav Hapla *missingPoint = -1; 668403da9461SVaclav Hapla ierr = DMPlexGetConeSize(dm, p, &n);CHKERRQ(ierr); 668503da9461SVaclav Hapla ierr = DMPlexGetCone(dm, p, &cone);CHKERRQ(ierr); 668603da9461SVaclav Hapla for (i=0; i<n; i++) { 668703da9461SVaclav Hapla ierr = PetscFindInt(cone[i], npoints, points, &l);CHKERRQ(ierr); 668803da9461SVaclav Hapla if (l < 0) { 668903da9461SVaclav Hapla *missingPoint = cone[i]; 669003da9461SVaclav Hapla break; 669103da9461SVaclav Hapla } 669203da9461SVaclav Hapla } 669303da9461SVaclav Hapla PetscFunctionReturn(0); 669403da9461SVaclav Hapla } 669503da9461SVaclav Hapla 669603da9461SVaclav Hapla /*@ 669703da9461SVaclav Hapla DMPlexCheckPointSF - Check that several sufficient conditions are met for the point SF of this plex. 669803da9461SVaclav Hapla 669903da9461SVaclav Hapla Input Parameters: 670003da9461SVaclav Hapla . dm - The DMPlex object 670103da9461SVaclav Hapla 670203da9461SVaclav Hapla Note: This is mainly intended for debugging/testing purposes. 670303da9461SVaclav Hapla 670403da9461SVaclav Hapla Level: developer 670503da9461SVaclav Hapla 670603da9461SVaclav Hapla .seealso: DMGetPointSF(), DMPlexCheckSymmetry(), DMPlexCheckSkeleton(), DMPlexCheckFaces() 670703da9461SVaclav Hapla @*/ 670803da9461SVaclav Hapla PetscErrorCode DMPlexCheckPointSF(DM dm) 670903da9461SVaclav Hapla { 671003da9461SVaclav Hapla PetscSF sf; 671103da9461SVaclav Hapla PetscInt d,depth,i,nleaves,p,plo,phi,missingPoint; 671203da9461SVaclav Hapla const PetscInt *locals; 671303da9461SVaclav Hapla PetscErrorCode ierr; 671403da9461SVaclav Hapla 671503da9461SVaclav Hapla PetscFunctionBegin; 671603da9461SVaclav Hapla PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 671703da9461SVaclav Hapla ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 671803da9461SVaclav Hapla ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 671903da9461SVaclav Hapla ierr = PetscSFGetGraph(sf, NULL, &nleaves, &locals, NULL);CHKERRQ(ierr); 672003da9461SVaclav Hapla 6721ece87651SVaclav Hapla /* 1) check there are no faces in 2D, cells in 3D, in interface */ 672203da9461SVaclav Hapla ierr = DMPlexGetVTKCellHeight(dm, &d);CHKERRQ(ierr); 672303da9461SVaclav Hapla ierr = DMPlexGetHeightStratum(dm, d, &plo, &phi);CHKERRQ(ierr); 672403da9461SVaclav Hapla for (i=0; i<nleaves; i++) { 672503da9461SVaclav Hapla p = locals[i]; 672603da9461SVaclav Hapla if (p >= plo && p < phi) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "point SF contains %d which is a cell",p); 672703da9461SVaclav Hapla } 6728ece87651SVaclav Hapla 6729ece87651SVaclav Hapla /* 2) if some point is in interface, then all its cone points must be also in interface */ 6730ece87651SVaclav Hapla for (i=0; i<nleaves; i++) { 6731ece87651SVaclav Hapla p = locals[i]; 6732ece87651SVaclav Hapla ierr = DMPlexAreAllConePointsInArray_Private(dm, p, nleaves, locals, &missingPoint);CHKERRQ(ierr); 6733ece87651SVaclav Hapla if (missingPoint >= 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "point SF contains %d but not %d from its cone",p,missingPoint); 6734ece87651SVaclav Hapla } 673503da9461SVaclav Hapla PetscFunctionReturn(0); 673603da9461SVaclav Hapla } 673703da9461SVaclav Hapla 6738068a5610SStefano Zampini typedef struct cell_stats 6739068a5610SStefano Zampini { 6740068a5610SStefano Zampini PetscReal min, max, sum, squaresum; 6741068a5610SStefano Zampini PetscInt count; 6742068a5610SStefano Zampini } cell_stats_t; 6743068a5610SStefano Zampini 6744068a5610SStefano Zampini static void cell_stats_reduce(void *a, void *b, int * len, MPI_Datatype *datatype) 6745068a5610SStefano Zampini { 6746068a5610SStefano Zampini PetscInt i, N = *len; 6747068a5610SStefano Zampini 6748068a5610SStefano Zampini for (i = 0; i < N; i++) { 6749068a5610SStefano Zampini cell_stats_t *A = (cell_stats_t *) a; 6750068a5610SStefano Zampini cell_stats_t *B = (cell_stats_t *) b; 6751068a5610SStefano Zampini 6752068a5610SStefano Zampini B->min = PetscMin(A->min,B->min); 6753068a5610SStefano Zampini B->max = PetscMax(A->max,B->max); 6754068a5610SStefano Zampini B->sum += A->sum; 6755068a5610SStefano Zampini B->squaresum += A->squaresum; 6756068a5610SStefano Zampini B->count += A->count; 6757068a5610SStefano Zampini } 6758068a5610SStefano Zampini } 6759068a5610SStefano Zampini 6760068a5610SStefano Zampini /*@ 6761068a5610SStefano Zampini DMPlexCheckCellShape - Checks the Jacobian of the mapping and computes some minimal statistics. 6762068a5610SStefano Zampini 6763068a5610SStefano Zampini Input Parameters: 6764068a5610SStefano Zampini + dm - The DMPlex object 6765068a5610SStefano Zampini - output - If true, statistics will be displayed on stdout 6766068a5610SStefano Zampini 6767068a5610SStefano Zampini Note: This is mainly intended for debugging/testing purposes. 6768068a5610SStefano Zampini 6769068a5610SStefano Zampini Level: developer 6770068a5610SStefano Zampini 6771068a5610SStefano Zampini .seealso: DMPlexCheckSymmetry(), DMPlexCheckSkeleton(), DMPlexCheckFaces() 6772068a5610SStefano Zampini @*/ 6773068a5610SStefano Zampini PetscErrorCode DMPlexCheckCellShape(DM dm, PetscBool output) 6774068a5610SStefano Zampini { 6775068a5610SStefano Zampini PetscMPIInt rank,size; 6776068a5610SStefano Zampini PetscInt dim, c, cStart, cEnd, cMax, count = 0; 6777068a5610SStefano Zampini cell_stats_t stats, globalStats; 6778068a5610SStefano Zampini PetscReal *J, *invJ, min = 0, max = 0, mean = 0, stdev = 0; 6779068a5610SStefano Zampini MPI_Comm comm = PetscObjectComm((PetscObject)dm); 6780068a5610SStefano Zampini DM dmCoarse; 6781068a5610SStefano Zampini PetscErrorCode ierr; 6782068a5610SStefano Zampini 6783068a5610SStefano Zampini PetscFunctionBegin; 6784068a5610SStefano Zampini PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6785068a5610SStefano Zampini stats.min = PETSC_MAX_REAL; 6786068a5610SStefano Zampini stats.max = PETSC_MIN_REAL; 6787068a5610SStefano Zampini stats.sum = stats.squaresum = 0.; 6788068a5610SStefano Zampini stats.count = 0; 6789068a5610SStefano Zampini 6790068a5610SStefano Zampini ierr = DMGetCoordinateDim(dm,&dim);CHKERRQ(ierr); 6791068a5610SStefano Zampini ierr = PetscMalloc2(dim * dim, &J, dim * dim, &invJ);CHKERRQ(ierr); 6792068a5610SStefano Zampini ierr = DMPlexGetHeightStratum(dm,0,&cStart,&cEnd);CHKERRQ(ierr); 6793068a5610SStefano Zampini ierr = DMPlexGetHybridBounds(dm,&cMax,NULL,NULL,NULL);CHKERRQ(ierr); 6794068a5610SStefano Zampini cMax = cMax < 0 ? cEnd : cMax; 6795068a5610SStefano Zampini for (c = cStart; c < cMax; c++) { 6796068a5610SStefano Zampini PetscInt i; 6797068a5610SStefano Zampini PetscReal frobJ = 0., frobInvJ = 0., cond2, cond, detJ; 6798068a5610SStefano Zampini 6799068a5610SStefano Zampini ierr = DMPlexComputeCellGeometryAffineFEM(dm,c,NULL,J,invJ,&detJ);CHKERRQ(ierr); 6800068a5610SStefano Zampini if (detJ < 0.0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Mesh cell %D is inverted", c); 6801068a5610SStefano Zampini for (i = 0; i < dim * dim; i++) { 6802068a5610SStefano Zampini frobJ += J[i] * J[i]; 6803068a5610SStefano Zampini frobInvJ += invJ[i] * invJ[i]; 6804068a5610SStefano Zampini } 6805068a5610SStefano Zampini cond2 = frobJ * frobInvJ; 6806068a5610SStefano Zampini cond = PetscSqrtReal(cond2); 6807068a5610SStefano Zampini 6808068a5610SStefano Zampini stats.min = PetscMin(stats.min,cond); 6809068a5610SStefano Zampini stats.max = PetscMax(stats.max,cond); 6810068a5610SStefano Zampini stats.sum += cond; 6811068a5610SStefano Zampini stats.squaresum += cond2; 6812068a5610SStefano Zampini stats.count++; 6813068a5610SStefano Zampini } 6814068a5610SStefano Zampini 6815068a5610SStefano Zampini ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 6816068a5610SStefano Zampini if (size > 1) { 6817068a5610SStefano Zampini PetscMPIInt blockLengths[2] = {4,1}; 6818068a5610SStefano Zampini MPI_Aint blockOffsets[2] = {offsetof(cell_stats_t,min),offsetof(cell_stats_t,count)}; 6819068a5610SStefano Zampini MPI_Datatype blockTypes[2] = {MPIU_REAL,MPIU_INT}, statType; 6820068a5610SStefano Zampini MPI_Op statReduce; 6821068a5610SStefano Zampini 6822068a5610SStefano Zampini ierr = MPI_Type_create_struct(2,blockLengths,blockOffsets,blockTypes,&statType);CHKERRQ(ierr); 6823068a5610SStefano Zampini ierr = MPI_Type_commit(&statType);CHKERRQ(ierr); 6824068a5610SStefano Zampini ierr = MPI_Op_create(cell_stats_reduce, PETSC_TRUE, &statReduce);CHKERRQ(ierr); 6825068a5610SStefano Zampini ierr = MPI_Reduce(&stats,&globalStats,1,statType,statReduce,0,comm);CHKERRQ(ierr); 6826068a5610SStefano Zampini ierr = MPI_Op_free(&statReduce);CHKERRQ(ierr); 6827068a5610SStefano Zampini ierr = MPI_Type_free(&statType);CHKERRQ(ierr); 6828068a5610SStefano Zampini } else { 6829068a5610SStefano Zampini ierr = PetscMemcpy(&globalStats,&stats,sizeof(stats));CHKERRQ(ierr); 6830068a5610SStefano Zampini } 6831068a5610SStefano Zampini 6832068a5610SStefano Zampini ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 6833068a5610SStefano Zampini if (!rank) { 6834068a5610SStefano Zampini count = globalStats.count; 6835068a5610SStefano Zampini min = globalStats.min; 6836068a5610SStefano Zampini max = globalStats.max; 6837068a5610SStefano Zampini mean = globalStats.sum / globalStats.count; 6838068a5610SStefano Zampini stdev = globalStats.count > 1 ? PetscSqrtReal(PetscMax((globalStats.squaresum - globalStats.count * mean * mean) / (globalStats.count - 1),0)) : 0.0; 6839068a5610SStefano Zampini } 6840068a5610SStefano Zampini 6841068a5610SStefano Zampini if (output) { 6842068a5610SStefano 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); 6843068a5610SStefano Zampini } 6844068a5610SStefano Zampini ierr = PetscFree2(J,invJ);CHKERRQ(ierr); 6845068a5610SStefano Zampini 6846068a5610SStefano Zampini ierr = DMGetCoarseDM(dm,&dmCoarse);CHKERRQ(ierr); 6847068a5610SStefano Zampini if (dmCoarse) { 6848068a5610SStefano Zampini PetscBool isplex; 6849068a5610SStefano Zampini 6850068a5610SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)dmCoarse,DMPLEX,&isplex);CHKERRQ(ierr); 6851068a5610SStefano Zampini if (isplex) { 6852068a5610SStefano Zampini ierr = DMPlexCheckCellShape(dmCoarse,output);CHKERRQ(ierr); 6853068a5610SStefano Zampini } 6854068a5610SStefano Zampini } 6855068a5610SStefano Zampini PetscFunctionReturn(0); 6856068a5610SStefano Zampini } 6857068a5610SStefano Zampini 6858bceba477SMatthew G. Knepley /* Pointwise interpolation 6859bceba477SMatthew G. Knepley Just code FEM for now 6860bceba477SMatthew G. Knepley u^f = I u^c 68614ca5e9f5SMatthew G. Knepley sum_k u^f_k phi^f_k = I sum_j u^c_j phi^c_j 68624ca5e9f5SMatthew G. Knepley u^f_i = sum_j psi^f_i I phi^c_j u^c_j 68634ca5e9f5SMatthew G. Knepley I_{ij} = psi^f_i phi^c_j 6864bceba477SMatthew G. Knepley */ 6865bceba477SMatthew G. Knepley PetscErrorCode DMCreateInterpolation_Plex(DM dmCoarse, DM dmFine, Mat *interpolation, Vec *scaling) 6866bceba477SMatthew G. Knepley { 6867bceba477SMatthew G. Knepley PetscSection gsc, gsf; 6868bceba477SMatthew G. Knepley PetscInt m, n; 6869a063dac3SMatthew G. Knepley void *ctx; 687068132eb9SMatthew G. Knepley DM cdm; 6871fd194bc8SStefano Zampini PetscBool regular, ismatis; 6872bceba477SMatthew G. Knepley PetscErrorCode ierr; 6873bceba477SMatthew G. Knepley 6874bceba477SMatthew G. Knepley PetscFunctionBegin; 6875e87a4003SBarry Smith ierr = DMGetGlobalSection(dmFine, &gsf);CHKERRQ(ierr); 6876bceba477SMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(gsf, &m);CHKERRQ(ierr); 6877e87a4003SBarry Smith ierr = DMGetGlobalSection(dmCoarse, &gsc);CHKERRQ(ierr); 6878bceba477SMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(gsc, &n);CHKERRQ(ierr); 687968132eb9SMatthew G. Knepley 6880fd194bc8SStefano Zampini ierr = PetscStrcmp(dmCoarse->mattype, MATIS, &ismatis);CHKERRQ(ierr); 6881bceba477SMatthew G. Knepley ierr = MatCreate(PetscObjectComm((PetscObject) dmCoarse), interpolation);CHKERRQ(ierr); 6882bceba477SMatthew G. Knepley ierr = MatSetSizes(*interpolation, m, n, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 6883fd194bc8SStefano Zampini ierr = MatSetType(*interpolation, ismatis ? MATAIJ : dmCoarse->mattype);CHKERRQ(ierr); 6884a063dac3SMatthew G. Knepley ierr = DMGetApplicationContext(dmFine, &ctx);CHKERRQ(ierr); 688568132eb9SMatthew G. Knepley 6886a8fb8f29SToby Isaac ierr = DMGetCoarseDM(dmFine, &cdm);CHKERRQ(ierr); 688768132eb9SMatthew G. Knepley ierr = DMPlexGetRegularRefinement(dmFine, ®ular);CHKERRQ(ierr); 688868132eb9SMatthew G. Knepley if (regular && cdm == dmCoarse) {ierr = DMPlexComputeInterpolatorNested(dmCoarse, dmFine, *interpolation, ctx);CHKERRQ(ierr);} 688968132eb9SMatthew G. Knepley else {ierr = DMPlexComputeInterpolatorGeneral(dmCoarse, dmFine, *interpolation, ctx);CHKERRQ(ierr);} 689068132eb9SMatthew G. Knepley ierr = MatViewFromOptions(*interpolation, NULL, "-interp_mat_view");CHKERRQ(ierr); 68914db47ee9SStefano Zampini if (scaling) { 68925d1c2e58SMatthew G. Knepley /* Use naive scaling */ 68935d1c2e58SMatthew G. Knepley ierr = DMCreateInterpolationScale(dmCoarse, dmFine, *interpolation, scaling);CHKERRQ(ierr); 68944db47ee9SStefano Zampini } 6895a063dac3SMatthew G. Knepley PetscFunctionReturn(0); 6896a063dac3SMatthew G. Knepley } 6897bceba477SMatthew G. Knepley 68986dbf9973SLawrence Mitchell PetscErrorCode DMCreateInjection_Plex(DM dmCoarse, DM dmFine, Mat *mat) 6899a063dac3SMatthew G. Knepley { 690090748bafSMatthew G. Knepley PetscErrorCode ierr; 69016dbf9973SLawrence Mitchell VecScatter ctx; 690290748bafSMatthew G. Knepley 6903a063dac3SMatthew G. Knepley PetscFunctionBegin; 69046dbf9973SLawrence Mitchell ierr = DMPlexComputeInjectorFEM(dmCoarse, dmFine, &ctx, NULL);CHKERRQ(ierr); 69056dbf9973SLawrence Mitchell ierr = MatCreateScatter(PetscObjectComm((PetscObject)ctx), ctx, mat);CHKERRQ(ierr); 69066dbf9973SLawrence Mitchell ierr = VecScatterDestroy(&ctx);CHKERRQ(ierr); 6907bceba477SMatthew G. Knepley PetscFunctionReturn(0); 6908bceba477SMatthew G. Knepley } 6909bceba477SMatthew G. Knepley 6910bd041c0cSMatthew G. Knepley PetscErrorCode DMCreateMassMatrix_Plex(DM dmCoarse, DM dmFine, Mat *mass) 6911bd041c0cSMatthew G. Knepley { 6912bd041c0cSMatthew G. Knepley PetscSection gsc, gsf; 6913bd041c0cSMatthew G. Knepley PetscInt m, n; 6914bd041c0cSMatthew G. Knepley void *ctx; 6915bd041c0cSMatthew G. Knepley DM cdm; 6916bd041c0cSMatthew G. Knepley PetscBool regular; 6917bd041c0cSMatthew G. Knepley PetscErrorCode ierr; 6918bd041c0cSMatthew G. Knepley 6919bd041c0cSMatthew G. Knepley PetscFunctionBegin; 6920e87a4003SBarry Smith ierr = DMGetGlobalSection(dmFine, &gsf);CHKERRQ(ierr); 6921bd041c0cSMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(gsf, &m);CHKERRQ(ierr); 6922e87a4003SBarry Smith ierr = DMGetGlobalSection(dmCoarse, &gsc);CHKERRQ(ierr); 6923bd041c0cSMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(gsc, &n);CHKERRQ(ierr); 6924bd041c0cSMatthew G. Knepley 6925bd041c0cSMatthew G. Knepley ierr = MatCreate(PetscObjectComm((PetscObject) dmCoarse), mass);CHKERRQ(ierr); 6926bd041c0cSMatthew G. Knepley ierr = MatSetSizes(*mass, m, n, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 6927bd041c0cSMatthew G. Knepley ierr = MatSetType(*mass, dmCoarse->mattype);CHKERRQ(ierr); 6928bd041c0cSMatthew G. Knepley ierr = DMGetApplicationContext(dmFine, &ctx);CHKERRQ(ierr); 6929bd041c0cSMatthew G. Knepley 6930bd041c0cSMatthew G. Knepley ierr = DMGetCoarseDM(dmFine, &cdm);CHKERRQ(ierr); 6931bd041c0cSMatthew G. Knepley ierr = DMPlexGetRegularRefinement(dmFine, ®ular);CHKERRQ(ierr); 6932bd041c0cSMatthew G. Knepley if (regular && cdm == dmCoarse) {ierr = DMPlexComputeMassMatrixNested(dmCoarse, dmFine, *mass, ctx);CHKERRQ(ierr);} 6933bd041c0cSMatthew G. Knepley else {ierr = DMPlexComputeMassMatrixGeneral(dmCoarse, dmFine, *mass, ctx);CHKERRQ(ierr);} 6934bd041c0cSMatthew G. Knepley ierr = MatViewFromOptions(*mass, NULL, "-mass_mat_view");CHKERRQ(ierr); 6935bd041c0cSMatthew G. Knepley PetscFunctionReturn(0); 6936bd041c0cSMatthew G. Knepley } 6937bd041c0cSMatthew G. Knepley 69380aef6b92SMatthew G. Knepley /*@ 69390aef6b92SMatthew G. Knepley DMPlexGetRegularRefinement - Get the flag indicating that this mesh was obtained by regular refinement from its coarse mesh 69400aef6b92SMatthew G. Knepley 69410aef6b92SMatthew G. Knepley Input Parameter: 69420aef6b92SMatthew G. Knepley . dm - The DMPlex object 69430aef6b92SMatthew G. Knepley 69440aef6b92SMatthew G. Knepley Output Parameter: 69450aef6b92SMatthew G. Knepley . regular - The flag 69460aef6b92SMatthew G. Knepley 69470aef6b92SMatthew G. Knepley Level: intermediate 69480aef6b92SMatthew G. Knepley 69490aef6b92SMatthew G. Knepley .seealso: DMPlexSetRegularRefinement() 69500aef6b92SMatthew G. Knepley @*/ 69510aef6b92SMatthew G. Knepley PetscErrorCode DMPlexGetRegularRefinement(DM dm, PetscBool *regular) 69520aef6b92SMatthew G. Knepley { 69530aef6b92SMatthew G. Knepley PetscFunctionBegin; 69540aef6b92SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 69550aef6b92SMatthew G. Knepley PetscValidPointer(regular, 2); 69560aef6b92SMatthew G. Knepley *regular = ((DM_Plex *) dm->data)->regularRefinement; 69570aef6b92SMatthew G. Knepley PetscFunctionReturn(0); 69580aef6b92SMatthew G. Knepley } 69590aef6b92SMatthew G. Knepley 69600aef6b92SMatthew G. Knepley /*@ 69610aef6b92SMatthew G. Knepley DMPlexSetRegularRefinement - Set the flag indicating that this mesh was obtained by regular refinement from its coarse mesh 69620aef6b92SMatthew G. Knepley 69630aef6b92SMatthew G. Knepley Input Parameters: 69640aef6b92SMatthew G. Knepley + dm - The DMPlex object 69650aef6b92SMatthew G. Knepley - regular - The flag 69660aef6b92SMatthew G. Knepley 69670aef6b92SMatthew G. Knepley Level: intermediate 69680aef6b92SMatthew G. Knepley 69690aef6b92SMatthew G. Knepley .seealso: DMPlexGetRegularRefinement() 69700aef6b92SMatthew G. Knepley @*/ 69710aef6b92SMatthew G. Knepley PetscErrorCode DMPlexSetRegularRefinement(DM dm, PetscBool regular) 69720aef6b92SMatthew G. Knepley { 69730aef6b92SMatthew G. Knepley PetscFunctionBegin; 69740aef6b92SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 69750aef6b92SMatthew G. Knepley ((DM_Plex *) dm->data)->regularRefinement = regular; 69760aef6b92SMatthew G. Knepley PetscFunctionReturn(0); 69770aef6b92SMatthew G. Knepley } 69780aef6b92SMatthew G. Knepley 6979f7c74593SToby Isaac /* anchors */ 6980a68b90caSToby Isaac /*@ 6981f7c74593SToby Isaac DMPlexGetAnchors - Get the layout of the anchor (point-to-point) constraints. Typically, the user will not have to 6982f7c74593SToby Isaac call DMPlexGetAnchors() directly: if there are anchors, then DMPlexGetAnchors() is called during DMGetConstraints(). 6983a68b90caSToby Isaac 6984e228b242SToby Isaac not collective 6985a68b90caSToby Isaac 6986a68b90caSToby Isaac Input Parameters: 6987a68b90caSToby Isaac . dm - The DMPlex object 6988a68b90caSToby Isaac 6989a68b90caSToby Isaac Output Parameters: 6990a68b90caSToby Isaac + anchorSection - If not NULL, set to the section describing which points anchor the constrained points. 6991a68b90caSToby Isaac - anchorIS - If not NULL, set to the list of anchors indexed by anchorSection 6992a68b90caSToby Isaac 6993a68b90caSToby Isaac 6994a68b90caSToby Isaac Level: intermediate 6995a68b90caSToby Isaac 6996f7c74593SToby Isaac .seealso: DMPlexSetAnchors(), DMGetConstraints(), DMSetConstraints() 6997a68b90caSToby Isaac @*/ 6998a17985deSToby Isaac PetscErrorCode DMPlexGetAnchors(DM dm, PetscSection *anchorSection, IS *anchorIS) 6999a68b90caSToby Isaac { 7000a68b90caSToby Isaac DM_Plex *plex = (DM_Plex *)dm->data; 700141e6d900SToby Isaac PetscErrorCode ierr; 7002a68b90caSToby Isaac 7003a68b90caSToby Isaac PetscFunctionBegin; 7004a68b90caSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 700541e6d900SToby Isaac if (!plex->anchorSection && !plex->anchorIS && plex->createanchors) {ierr = (*plex->createanchors)(dm);CHKERRQ(ierr);} 7006a68b90caSToby Isaac if (anchorSection) *anchorSection = plex->anchorSection; 7007a68b90caSToby Isaac if (anchorIS) *anchorIS = plex->anchorIS; 7008a68b90caSToby Isaac PetscFunctionReturn(0); 7009a68b90caSToby Isaac } 7010a68b90caSToby Isaac 7011a68b90caSToby Isaac /*@ 7012f7c74593SToby Isaac DMPlexSetAnchors - Set the layout of the local anchor (point-to-point) constraints. Unlike boundary conditions, 7013f7c74593SToby Isaac when a point's degrees of freedom in a section are constrained to an outside value, the anchor constraints set a 7014a68b90caSToby Isaac point's degrees of freedom to be a linear combination of other points' degrees of freedom. 7015a68b90caSToby Isaac 7016a17985deSToby Isaac After specifying the layout of constraints with DMPlexSetAnchors(), one specifies the constraints by calling 7017f7c74593SToby Isaac DMGetConstraints() and filling in the entries in the constraint matrix. 7018a68b90caSToby Isaac 7019e228b242SToby Isaac collective on dm 7020a68b90caSToby Isaac 7021a68b90caSToby Isaac Input Parameters: 7022a68b90caSToby Isaac + dm - The DMPlex object 7023e228b242SToby 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). 7024e228b242SToby Isaac - anchorIS - The list of all anchor points. Must have a local communicator (PETSC_COMM_SELF or derivative). 7025a68b90caSToby Isaac 7026a68b90caSToby Isaac The reference counts of anchorSection and anchorIS are incremented. 7027a68b90caSToby Isaac 7028a68b90caSToby Isaac Level: intermediate 7029a68b90caSToby Isaac 7030f7c74593SToby Isaac .seealso: DMPlexGetAnchors(), DMGetConstraints(), DMSetConstraints() 7031a68b90caSToby Isaac @*/ 7032a17985deSToby Isaac PetscErrorCode DMPlexSetAnchors(DM dm, PetscSection anchorSection, IS anchorIS) 7033a68b90caSToby Isaac { 7034a68b90caSToby Isaac DM_Plex *plex = (DM_Plex *)dm->data; 7035e228b242SToby Isaac PetscMPIInt result; 7036a68b90caSToby Isaac PetscErrorCode ierr; 7037a68b90caSToby Isaac 7038a68b90caSToby Isaac PetscFunctionBegin; 7039a68b90caSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7040e228b242SToby Isaac if (anchorSection) { 7041e228b242SToby Isaac PetscValidHeaderSpecific(anchorSection,PETSC_SECTION_CLASSID,2); 7042e228b242SToby Isaac ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)anchorSection),&result);CHKERRQ(ierr); 7043f6a3d38cSToby Isaac if (result != MPI_CONGRUENT && result != MPI_IDENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"anchor section must have local communicator"); 7044e228b242SToby Isaac } 7045e228b242SToby Isaac if (anchorIS) { 7046e228b242SToby Isaac PetscValidHeaderSpecific(anchorIS,IS_CLASSID,3); 7047e228b242SToby Isaac ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)anchorIS),&result);CHKERRQ(ierr); 7048f6a3d38cSToby Isaac if (result != MPI_CONGRUENT && result != MPI_IDENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"anchor IS must have local communicator"); 7049e228b242SToby Isaac } 7050a68b90caSToby Isaac 7051a68b90caSToby Isaac ierr = PetscObjectReference((PetscObject)anchorSection);CHKERRQ(ierr); 7052a68b90caSToby Isaac ierr = PetscSectionDestroy(&plex->anchorSection);CHKERRQ(ierr); 7053a68b90caSToby Isaac plex->anchorSection = anchorSection; 7054a68b90caSToby Isaac 7055a68b90caSToby Isaac ierr = PetscObjectReference((PetscObject)anchorIS);CHKERRQ(ierr); 7056a68b90caSToby Isaac ierr = ISDestroy(&plex->anchorIS);CHKERRQ(ierr); 7057a68b90caSToby Isaac plex->anchorIS = anchorIS; 7058a68b90caSToby Isaac 7059a68b90caSToby Isaac #if defined(PETSC_USE_DEBUG) 7060a68b90caSToby Isaac if (anchorIS && anchorSection) { 7061a68b90caSToby Isaac PetscInt size, a, pStart, pEnd; 7062a68b90caSToby Isaac const PetscInt *anchors; 7063a68b90caSToby Isaac 7064a68b90caSToby Isaac ierr = PetscSectionGetChart(anchorSection,&pStart,&pEnd);CHKERRQ(ierr); 7065a68b90caSToby Isaac ierr = ISGetLocalSize(anchorIS,&size);CHKERRQ(ierr); 7066a68b90caSToby Isaac ierr = ISGetIndices(anchorIS,&anchors);CHKERRQ(ierr); 7067a68b90caSToby Isaac for (a = 0; a < size; a++) { 7068a68b90caSToby Isaac PetscInt p; 7069a68b90caSToby Isaac 7070a68b90caSToby Isaac p = anchors[a]; 7071a68b90caSToby Isaac if (p >= pStart && p < pEnd) { 7072a68b90caSToby Isaac PetscInt dof; 7073a68b90caSToby Isaac 7074a68b90caSToby Isaac ierr = PetscSectionGetDof(anchorSection,p,&dof);CHKERRQ(ierr); 7075a68b90caSToby Isaac if (dof) { 7076a68b90caSToby Isaac PetscErrorCode ierr2; 7077a68b90caSToby Isaac 7078a68b90caSToby Isaac ierr2 = ISRestoreIndices(anchorIS,&anchors);CHKERRQ(ierr2); 70798ccfff9cSToby Isaac SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Point %D cannot be constrained and an anchor",p); 7080a68b90caSToby Isaac } 7081a68b90caSToby Isaac } 7082a68b90caSToby Isaac } 7083a68b90caSToby Isaac ierr = ISRestoreIndices(anchorIS,&anchors);CHKERRQ(ierr); 7084a68b90caSToby Isaac } 7085a68b90caSToby Isaac #endif 7086f7c74593SToby Isaac /* reset the generic constraints */ 7087f7c74593SToby Isaac ierr = DMSetDefaultConstraints(dm,NULL,NULL);CHKERRQ(ierr); 7088a68b90caSToby Isaac PetscFunctionReturn(0); 7089a68b90caSToby Isaac } 7090a68b90caSToby Isaac 7091f7c74593SToby Isaac static PetscErrorCode DMPlexCreateConstraintSection_Anchors(DM dm, PetscSection section, PetscSection *cSec) 7092a68b90caSToby Isaac { 7093f7c74593SToby Isaac PetscSection anchorSection; 70946995de1eSToby Isaac PetscInt pStart, pEnd, sStart, sEnd, p, dof, numFields, f; 7095a68b90caSToby Isaac PetscErrorCode ierr; 7096a68b90caSToby Isaac 7097a68b90caSToby Isaac PetscFunctionBegin; 7098a68b90caSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7099a17985deSToby Isaac ierr = DMPlexGetAnchors(dm,&anchorSection,NULL);CHKERRQ(ierr); 7100e228b242SToby Isaac ierr = PetscSectionCreate(PETSC_COMM_SELF,cSec);CHKERRQ(ierr); 7101a68b90caSToby Isaac ierr = PetscSectionGetNumFields(section,&numFields);CHKERRQ(ierr); 71026995de1eSToby Isaac if (numFields) { 7103719ab38cSToby Isaac PetscInt f; 7104a68b90caSToby Isaac ierr = PetscSectionSetNumFields(*cSec,numFields);CHKERRQ(ierr); 7105719ab38cSToby Isaac 7106719ab38cSToby Isaac for (f = 0; f < numFields; f++) { 7107719ab38cSToby Isaac PetscInt numComp; 7108719ab38cSToby Isaac 7109719ab38cSToby Isaac ierr = PetscSectionGetFieldComponents(section,f,&numComp);CHKERRQ(ierr); 7110719ab38cSToby Isaac ierr = PetscSectionSetFieldComponents(*cSec,f,numComp);CHKERRQ(ierr); 7111719ab38cSToby Isaac } 71126995de1eSToby Isaac } 7113a68b90caSToby Isaac ierr = PetscSectionGetChart(anchorSection,&pStart,&pEnd);CHKERRQ(ierr); 71146995de1eSToby Isaac ierr = PetscSectionGetChart(section,&sStart,&sEnd);CHKERRQ(ierr); 71156995de1eSToby Isaac pStart = PetscMax(pStart,sStart); 71166995de1eSToby Isaac pEnd = PetscMin(pEnd,sEnd); 71176995de1eSToby Isaac pEnd = PetscMax(pStart,pEnd); 7118a68b90caSToby Isaac ierr = PetscSectionSetChart(*cSec,pStart,pEnd);CHKERRQ(ierr); 7119a68b90caSToby Isaac for (p = pStart; p < pEnd; p++) { 7120a68b90caSToby Isaac ierr = PetscSectionGetDof(anchorSection,p,&dof);CHKERRQ(ierr); 7121a68b90caSToby Isaac if (dof) { 7122a68b90caSToby Isaac ierr = PetscSectionGetDof(section,p,&dof);CHKERRQ(ierr); 7123a68b90caSToby Isaac ierr = PetscSectionSetDof(*cSec,p,dof);CHKERRQ(ierr); 7124a68b90caSToby Isaac for (f = 0; f < numFields; f++) { 7125a68b90caSToby Isaac ierr = PetscSectionGetFieldDof(section,p,f,&dof);CHKERRQ(ierr); 7126a68b90caSToby Isaac ierr = PetscSectionSetFieldDof(*cSec,p,f,dof);CHKERRQ(ierr); 7127a68b90caSToby Isaac } 7128a68b90caSToby Isaac } 7129a68b90caSToby Isaac } 7130a68b90caSToby Isaac ierr = PetscSectionSetUp(*cSec);CHKERRQ(ierr); 7131a68b90caSToby Isaac PetscFunctionReturn(0); 7132a68b90caSToby Isaac } 7133a68b90caSToby Isaac 7134f7c74593SToby Isaac static PetscErrorCode DMPlexCreateConstraintMatrix_Anchors(DM dm, PetscSection section, PetscSection cSec, Mat *cMat) 7135a68b90caSToby Isaac { 7136f7c74593SToby Isaac PetscSection aSec; 71370ac89760SToby Isaac PetscInt pStart, pEnd, p, dof, aDof, aOff, off, nnz, annz, m, n, q, a, offset, *i, *j; 71380ac89760SToby Isaac const PetscInt *anchors; 71390ac89760SToby Isaac PetscInt numFields, f; 714066ad2231SToby Isaac IS aIS; 71410ac89760SToby Isaac PetscErrorCode ierr; 71420ac89760SToby Isaac 71430ac89760SToby Isaac PetscFunctionBegin; 71440ac89760SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 71450ac89760SToby Isaac ierr = PetscSectionGetStorageSize(cSec, &m);CHKERRQ(ierr); 71460ac89760SToby Isaac ierr = PetscSectionGetStorageSize(section, &n);CHKERRQ(ierr); 71470ac89760SToby Isaac ierr = MatCreate(PETSC_COMM_SELF,cMat);CHKERRQ(ierr); 71480ac89760SToby Isaac ierr = MatSetSizes(*cMat,m,n,m,n);CHKERRQ(ierr); 7149302440fdSBarry Smith ierr = MatSetType(*cMat,MATSEQAIJ);CHKERRQ(ierr); 7150a17985deSToby Isaac ierr = DMPlexGetAnchors(dm,&aSec,&aIS);CHKERRQ(ierr); 715166ad2231SToby Isaac ierr = ISGetIndices(aIS,&anchors);CHKERRQ(ierr); 71526995de1eSToby Isaac /* cSec will be a subset of aSec and section */ 71536995de1eSToby Isaac ierr = PetscSectionGetChart(cSec,&pStart,&pEnd);CHKERRQ(ierr); 71540ac89760SToby Isaac ierr = PetscMalloc1(m+1,&i);CHKERRQ(ierr); 71550ac89760SToby Isaac i[0] = 0; 71560ac89760SToby Isaac ierr = PetscSectionGetNumFields(section,&numFields);CHKERRQ(ierr); 71570ac89760SToby Isaac for (p = pStart; p < pEnd; p++) { 7158f19733c5SToby Isaac PetscInt rDof, rOff, r; 7159f19733c5SToby Isaac 7160f19733c5SToby Isaac ierr = PetscSectionGetDof(aSec,p,&rDof);CHKERRQ(ierr); 7161f19733c5SToby Isaac if (!rDof) continue; 7162f19733c5SToby Isaac ierr = PetscSectionGetOffset(aSec,p,&rOff);CHKERRQ(ierr); 71630ac89760SToby Isaac if (numFields) { 71640ac89760SToby Isaac for (f = 0; f < numFields; f++) { 71650ac89760SToby Isaac annz = 0; 7166f19733c5SToby Isaac for (r = 0; r < rDof; r++) { 7167f19733c5SToby Isaac a = anchors[rOff + r]; 71680ac89760SToby Isaac ierr = PetscSectionGetFieldDof(section,a,f,&aDof);CHKERRQ(ierr); 71690ac89760SToby Isaac annz += aDof; 71700ac89760SToby Isaac } 71710ac89760SToby Isaac ierr = PetscSectionGetFieldDof(cSec,p,f,&dof);CHKERRQ(ierr); 71720ac89760SToby Isaac ierr = PetscSectionGetFieldOffset(cSec,p,f,&off);CHKERRQ(ierr); 71730ac89760SToby Isaac for (q = 0; q < dof; q++) { 71740ac89760SToby Isaac i[off + q + 1] = i[off + q] + annz; 71750ac89760SToby Isaac } 71760ac89760SToby Isaac } 71770ac89760SToby Isaac } 71780ac89760SToby Isaac else { 71790ac89760SToby Isaac annz = 0; 71800ac89760SToby Isaac for (q = 0; q < dof; q++) { 71810ac89760SToby Isaac a = anchors[off + q]; 71820ac89760SToby Isaac ierr = PetscSectionGetDof(section,a,&aDof);CHKERRQ(ierr); 71830ac89760SToby Isaac annz += aDof; 71840ac89760SToby Isaac } 71850ac89760SToby Isaac ierr = PetscSectionGetDof(cSec,p,&dof);CHKERRQ(ierr); 71860ac89760SToby Isaac ierr = PetscSectionGetOffset(cSec,p,&off);CHKERRQ(ierr); 71870ac89760SToby Isaac for (q = 0; q < dof; q++) { 71880ac89760SToby Isaac i[off + q + 1] = i[off + q] + annz; 71890ac89760SToby Isaac } 71900ac89760SToby Isaac } 71910ac89760SToby Isaac } 71920ac89760SToby Isaac nnz = i[m]; 71930ac89760SToby Isaac ierr = PetscMalloc1(nnz,&j);CHKERRQ(ierr); 71940ac89760SToby Isaac offset = 0; 71950ac89760SToby Isaac for (p = pStart; p < pEnd; p++) { 71960ac89760SToby Isaac if (numFields) { 71970ac89760SToby Isaac for (f = 0; f < numFields; f++) { 71980ac89760SToby Isaac ierr = PetscSectionGetFieldDof(cSec,p,f,&dof);CHKERRQ(ierr); 71990ac89760SToby Isaac for (q = 0; q < dof; q++) { 72000ac89760SToby Isaac PetscInt rDof, rOff, r; 72010ac89760SToby Isaac ierr = PetscSectionGetDof(aSec,p,&rDof);CHKERRQ(ierr); 72020ac89760SToby Isaac ierr = PetscSectionGetOffset(aSec,p,&rOff);CHKERRQ(ierr); 72030ac89760SToby Isaac for (r = 0; r < rDof; r++) { 72040ac89760SToby Isaac PetscInt s; 72050ac89760SToby Isaac 72060ac89760SToby Isaac a = anchors[rOff + r]; 72070ac89760SToby Isaac ierr = PetscSectionGetFieldDof(section,a,f,&aDof);CHKERRQ(ierr); 72080ac89760SToby Isaac ierr = PetscSectionGetFieldOffset(section,a,f,&aOff);CHKERRQ(ierr); 72090ac89760SToby Isaac for (s = 0; s < aDof; s++) { 72100ac89760SToby Isaac j[offset++] = aOff + s; 72110ac89760SToby Isaac } 72120ac89760SToby Isaac } 72130ac89760SToby Isaac } 72140ac89760SToby Isaac } 72150ac89760SToby Isaac } 72160ac89760SToby Isaac else { 72170ac89760SToby Isaac ierr = PetscSectionGetDof(cSec,p,&dof);CHKERRQ(ierr); 72180ac89760SToby Isaac for (q = 0; q < dof; q++) { 72190ac89760SToby Isaac PetscInt rDof, rOff, r; 72200ac89760SToby Isaac ierr = PetscSectionGetDof(aSec,p,&rDof);CHKERRQ(ierr); 72210ac89760SToby Isaac ierr = PetscSectionGetOffset(aSec,p,&rOff);CHKERRQ(ierr); 72220ac89760SToby Isaac for (r = 0; r < rDof; r++) { 72230ac89760SToby Isaac PetscInt s; 72240ac89760SToby Isaac 72250ac89760SToby Isaac a = anchors[rOff + r]; 72260ac89760SToby Isaac ierr = PetscSectionGetDof(section,a,&aDof);CHKERRQ(ierr); 72270ac89760SToby Isaac ierr = PetscSectionGetOffset(section,a,&aOff);CHKERRQ(ierr); 72280ac89760SToby Isaac for (s = 0; s < aDof; s++) { 72290ac89760SToby Isaac j[offset++] = aOff + s; 72300ac89760SToby Isaac } 72310ac89760SToby Isaac } 72320ac89760SToby Isaac } 72330ac89760SToby Isaac } 72340ac89760SToby Isaac } 72350ac89760SToby Isaac ierr = MatSeqAIJSetPreallocationCSR(*cMat,i,j,NULL);CHKERRQ(ierr); 723625570a81SToby Isaac ierr = PetscFree(i);CHKERRQ(ierr); 723725570a81SToby Isaac ierr = PetscFree(j);CHKERRQ(ierr); 723866ad2231SToby Isaac ierr = ISRestoreIndices(aIS,&anchors);CHKERRQ(ierr); 72390ac89760SToby Isaac PetscFunctionReturn(0); 72400ac89760SToby Isaac } 72410ac89760SToby Isaac 724266ad2231SToby Isaac PetscErrorCode DMCreateDefaultConstraints_Plex(DM dm) 724366ad2231SToby Isaac { 7244f7c74593SToby Isaac DM_Plex *plex = (DM_Plex *)dm->data; 7245f7c74593SToby Isaac PetscSection anchorSection, section, cSec; 724666ad2231SToby Isaac Mat cMat; 724766ad2231SToby Isaac PetscErrorCode ierr; 724866ad2231SToby Isaac 724966ad2231SToby Isaac PetscFunctionBegin; 725066ad2231SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7251a17985deSToby Isaac ierr = DMPlexGetAnchors(dm,&anchorSection,NULL);CHKERRQ(ierr); 725266ad2231SToby Isaac if (anchorSection) { 725344a7f3ddSMatthew G. Knepley PetscInt Nf; 7254e228b242SToby Isaac 7255e87a4003SBarry Smith ierr = DMGetSection(dm,§ion);CHKERRQ(ierr); 7256f7c74593SToby Isaac ierr = DMPlexCreateConstraintSection_Anchors(dm,section,&cSec);CHKERRQ(ierr); 7257f7c74593SToby Isaac ierr = DMPlexCreateConstraintMatrix_Anchors(dm,section,cSec,&cMat);CHKERRQ(ierr); 725844a7f3ddSMatthew G. Knepley ierr = DMGetNumFields(dm,&Nf);CHKERRQ(ierr); 725944a7f3ddSMatthew G. Knepley if (Nf && plex->computeanchormatrix) {ierr = (*plex->computeanchormatrix)(dm,section,cSec,cMat);CHKERRQ(ierr);} 726066ad2231SToby Isaac ierr = DMSetDefaultConstraints(dm,cSec,cMat);CHKERRQ(ierr); 726166ad2231SToby Isaac ierr = PetscSectionDestroy(&cSec);CHKERRQ(ierr); 726266ad2231SToby Isaac ierr = MatDestroy(&cMat);CHKERRQ(ierr); 726366ad2231SToby Isaac } 726466ad2231SToby Isaac PetscFunctionReturn(0); 726566ad2231SToby Isaac } 7266a93c429eSMatthew G. Knepley 7267a93c429eSMatthew G. Knepley PetscErrorCode DMCreateSubDomainDM_Plex(DM dm, DMLabel label, PetscInt value, IS *is, DM *subdm) 7268a93c429eSMatthew G. Knepley { 7269a93c429eSMatthew G. Knepley IS subis; 7270a93c429eSMatthew G. Knepley PetscSection section, subsection; 7271a93c429eSMatthew G. Knepley PetscErrorCode ierr; 7272a93c429eSMatthew G. Knepley 7273a93c429eSMatthew G. Knepley PetscFunctionBegin; 7274a93c429eSMatthew G. Knepley ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr); 7275a93c429eSMatthew G. Knepley if (!section) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Must set default section for DM before splitting subdomain"); 7276a93c429eSMatthew G. Knepley if (!subdm) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Must set output subDM for splitting subdomain"); 7277a93c429eSMatthew G. Knepley /* Create subdomain */ 7278a93c429eSMatthew G. Knepley ierr = DMPlexFilter(dm, label, value, subdm);CHKERRQ(ierr); 7279a93c429eSMatthew G. Knepley /* Create submodel */ 7280a93c429eSMatthew G. Knepley ierr = DMPlexCreateSubpointIS(*subdm, &subis);CHKERRQ(ierr); 7281a93c429eSMatthew G. Knepley ierr = PetscSectionCreateSubmeshSection(section, subis, &subsection);CHKERRQ(ierr); 7282a93c429eSMatthew G. Knepley ierr = ISDestroy(&subis);CHKERRQ(ierr); 7283a93c429eSMatthew G. Knepley ierr = DMSetDefaultSection(*subdm, subsection);CHKERRQ(ierr); 7284a93c429eSMatthew G. Knepley ierr = PetscSectionDestroy(&subsection);CHKERRQ(ierr); 7285e5e52638SMatthew G. Knepley ierr = DMCopyDisc(dm, *subdm);CHKERRQ(ierr); 7286a93c429eSMatthew G. Knepley /* Create map from submodel to global model */ 7287a93c429eSMatthew G. Knepley if (is) { 7288a93c429eSMatthew G. Knepley PetscSection sectionGlobal, subsectionGlobal; 7289a93c429eSMatthew G. Knepley IS spIS; 7290a93c429eSMatthew G. Knepley const PetscInt *spmap; 7291a93c429eSMatthew G. Knepley PetscInt *subIndices; 7292a93c429eSMatthew G. Knepley PetscInt subSize = 0, subOff = 0, pStart, pEnd, p; 7293a93c429eSMatthew G. Knepley PetscInt Nf, f, bs = -1, bsLocal[2], bsMinMax[2]; 7294a93c429eSMatthew G. Knepley 7295a93c429eSMatthew G. Knepley ierr = DMPlexCreateSubpointIS(*subdm, &spIS);CHKERRQ(ierr); 7296a93c429eSMatthew G. Knepley ierr = ISGetIndices(spIS, &spmap);CHKERRQ(ierr); 7297a93c429eSMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &Nf);CHKERRQ(ierr); 7298a93c429eSMatthew G. Knepley ierr = DMGetDefaultGlobalSection(dm, §ionGlobal);CHKERRQ(ierr); 7299a93c429eSMatthew G. Knepley ierr = DMGetDefaultGlobalSection(*subdm, &subsectionGlobal);CHKERRQ(ierr); 7300a93c429eSMatthew G. Knepley ierr = PetscSectionGetChart(subsection, &pStart, &pEnd);CHKERRQ(ierr); 7301a93c429eSMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 7302a93c429eSMatthew G. Knepley PetscInt gdof, pSubSize = 0; 7303a93c429eSMatthew G. Knepley 7304a93c429eSMatthew G. Knepley ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr); 7305a93c429eSMatthew G. Knepley if (gdof > 0) { 7306a93c429eSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 7307a93c429eSMatthew G. Knepley PetscInt fdof, fcdof; 7308a93c429eSMatthew G. Knepley 7309a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldDof(subsection, p, f, &fdof);CHKERRQ(ierr); 7310a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldConstraintDof(subsection, p, f, &fcdof);CHKERRQ(ierr); 7311a93c429eSMatthew G. Knepley pSubSize += fdof-fcdof; 7312a93c429eSMatthew G. Knepley } 7313a93c429eSMatthew G. Knepley subSize += pSubSize; 7314a93c429eSMatthew G. Knepley if (pSubSize) { 7315a93c429eSMatthew G. Knepley if (bs < 0) { 7316a93c429eSMatthew G. Knepley bs = pSubSize; 7317a93c429eSMatthew G. Knepley } else if (bs != pSubSize) { 7318a93c429eSMatthew G. Knepley /* Layout does not admit a pointwise block size */ 7319a93c429eSMatthew G. Knepley bs = 1; 7320a93c429eSMatthew G. Knepley } 7321a93c429eSMatthew G. Knepley } 7322a93c429eSMatthew G. Knepley } 7323a93c429eSMatthew G. Knepley } 7324a93c429eSMatthew G. Knepley /* Must have same blocksize on all procs (some might have no points) */ 7325a93c429eSMatthew G. Knepley bsLocal[0] = bs < 0 ? PETSC_MAX_INT : bs; bsLocal[1] = bs; 7326a93c429eSMatthew G. Knepley ierr = PetscGlobalMinMaxInt(PetscObjectComm((PetscObject) dm), bsLocal, bsMinMax);CHKERRQ(ierr); 7327a93c429eSMatthew G. Knepley if (bsMinMax[0] != bsMinMax[1]) {bs = 1;} 7328a93c429eSMatthew G. Knepley else {bs = bsMinMax[0];} 7329a93c429eSMatthew G. Knepley ierr = PetscMalloc1(subSize, &subIndices);CHKERRQ(ierr); 7330a93c429eSMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 7331a93c429eSMatthew G. Knepley PetscInt gdof, goff; 7332a93c429eSMatthew G. Knepley 7333a93c429eSMatthew G. Knepley ierr = PetscSectionGetDof(subsectionGlobal, p, &gdof);CHKERRQ(ierr); 7334a93c429eSMatthew G. Knepley if (gdof > 0) { 7335a93c429eSMatthew G. Knepley const PetscInt point = spmap[p]; 7336a93c429eSMatthew G. Knepley 7337a93c429eSMatthew G. Knepley ierr = PetscSectionGetOffset(sectionGlobal, point, &goff);CHKERRQ(ierr); 7338a93c429eSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 7339a93c429eSMatthew G. Knepley PetscInt fdof, fcdof, fc, f2, poff = 0; 7340a93c429eSMatthew G. Knepley 7341a93c429eSMatthew G. Knepley /* Can get rid of this loop by storing field information in the global section */ 7342a93c429eSMatthew G. Knepley for (f2 = 0; f2 < f; ++f2) { 7343a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, p, f2, &fdof);CHKERRQ(ierr); 7344a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldConstraintDof(section, p, f2, &fcdof);CHKERRQ(ierr); 7345a93c429eSMatthew G. Knepley poff += fdof-fcdof; 7346a93c429eSMatthew G. Knepley } 7347a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr); 7348a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr); 7349a93c429eSMatthew G. Knepley for (fc = 0; fc < fdof-fcdof; ++fc, ++subOff) { 7350a93c429eSMatthew G. Knepley subIndices[subOff] = goff+poff+fc; 7351a93c429eSMatthew G. Knepley } 7352a93c429eSMatthew G. Knepley } 7353a93c429eSMatthew G. Knepley } 7354a93c429eSMatthew G. Knepley } 7355a93c429eSMatthew G. Knepley ierr = ISRestoreIndices(spIS, &spmap);CHKERRQ(ierr); 7356a93c429eSMatthew G. Knepley ierr = ISDestroy(&spIS);CHKERRQ(ierr); 7357a93c429eSMatthew G. Knepley ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), subSize, subIndices, PETSC_OWN_POINTER, is);CHKERRQ(ierr); 7358a93c429eSMatthew G. Knepley if (bs > 1) { 7359a93c429eSMatthew G. Knepley /* We need to check that the block size does not come from non-contiguous fields */ 7360a93c429eSMatthew G. Knepley PetscInt i, j, set = 1; 7361a93c429eSMatthew G. Knepley for (i = 0; i < subSize; i += bs) { 7362a93c429eSMatthew G. Knepley for (j = 0; j < bs; ++j) { 7363a93c429eSMatthew G. Knepley if (subIndices[i+j] != subIndices[i]+j) {set = 0; break;} 7364a93c429eSMatthew G. Knepley } 7365a93c429eSMatthew G. Knepley } 7366a93c429eSMatthew G. Knepley if (set) {ierr = ISSetBlockSize(*is, bs);CHKERRQ(ierr);} 7367a93c429eSMatthew G. Knepley } 7368a93c429eSMatthew G. Knepley /* Attach nullspace */ 7369a93c429eSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 7370a93c429eSMatthew G. Knepley (*subdm)->nullspaceConstructors[f] = dm->nullspaceConstructors[f]; 7371a93c429eSMatthew G. Knepley if ((*subdm)->nullspaceConstructors[f]) break; 7372a93c429eSMatthew G. Knepley } 7373a93c429eSMatthew G. Knepley if (f < Nf) { 7374a93c429eSMatthew G. Knepley MatNullSpace nullSpace; 7375a93c429eSMatthew G. Knepley 7376a93c429eSMatthew G. Knepley ierr = (*(*subdm)->nullspaceConstructors[f])(*subdm, f, &nullSpace);CHKERRQ(ierr); 7377a93c429eSMatthew G. Knepley ierr = PetscObjectCompose((PetscObject) *is, "nullspace", (PetscObject) nullSpace);CHKERRQ(ierr); 7378a93c429eSMatthew G. Knepley ierr = MatNullSpaceDestroy(&nullSpace);CHKERRQ(ierr); 7379a93c429eSMatthew G. Knepley } 7380a93c429eSMatthew G. Knepley } 7381a93c429eSMatthew G. Knepley PetscFunctionReturn(0); 7382a93c429eSMatthew G. Knepley } 7383