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 */ 1130b0ce1bSStefano Zampini 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_Symmetrize, DMPLEX_Preallocate, DMPLEX_ResidualFEM, DMPLEX_JacobianFEM, DMPLEX_InterpolatorFEM, DMPLEX_InjectorFEM, DMPLEX_IntegralFEM, DMPLEX_CreateGmsh, DMPLEX_RebalanceSharedPoints, DMPLEX_PartSelf, DMPLEX_PartLabelInvert, DMPLEX_PartLabelCreateSF, DMPLEX_PartStratSF, DMPLEX_CreatePointSF; 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 { 104485ad865SMatthew G. Knepley PetscInt dim, pStart, pEnd, vStart, vEnd, cStart, cEnd, cMax; 105a99a26bcSAdrian Croucher PetscInt vcdof[2] = {0,0}, globalvcdof[2]; 1067e42fee7SMatthew G. Knepley PetscErrorCode ierr; 1077e42fee7SMatthew G. Knepley 1087e42fee7SMatthew G. Knepley PetscFunctionBegin; 109e630c359SToby Isaac *ft = PETSC_VTK_INVALID; 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); 113485ad865SMatthew G. Knepley ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr); 114485ad865SMatthew G. Knepley cEnd = cMax < 0 ? cEnd : cMax; 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; 134e630c359SToby Isaac } else { 135e630c359SToby Isaac if (field >= 0) { 136e630c359SToby Isaac const char *fieldname; 137e630c359SToby Isaac 138e630c359SToby Isaac ierr = PetscSectionGetFieldName(section, field, &fieldname);CHKERRQ(ierr); 139e630c359SToby Isaac ierr = PetscInfo2((PetscObject) dm, "Could not classify VTK output type of section field %D \"%s\"\n", field, fieldname);CHKERRQ(ierr); 140e630c359SToby Isaac } else { 141e630c359SToby Isaac ierr = PetscInfo((PetscObject) dm, "Could not classify VTK output typp of section\"%s\"\n");CHKERRQ(ierr); 142e630c359SToby Isaac } 143e630c359SToby Isaac } 1447e42fee7SMatthew G. Knepley PetscFunctionReturn(0); 1457e42fee7SMatthew G. Knepley } 1467e42fee7SMatthew G. Knepley 1477cd05799SMatthew G. Knepley static PetscErrorCode VecView_Plex_Local_Draw(Vec v, PetscViewer viewer) 148e412dcbdSMatthew G. Knepley { 149e412dcbdSMatthew G. Knepley DM dm; 150d1df6f1dSMatthew G. Knepley PetscSection s; 151e412dcbdSMatthew G. Knepley PetscDraw draw, popup; 152e412dcbdSMatthew G. Knepley DM cdm; 153e412dcbdSMatthew G. Knepley PetscSection coordSection; 154e412dcbdSMatthew G. Knepley Vec coordinates; 155e412dcbdSMatthew G. Knepley const PetscScalar *coords, *array; 156e412dcbdSMatthew G. Knepley PetscReal bound[4] = {PETSC_MAX_REAL, PETSC_MAX_REAL, PETSC_MIN_REAL, PETSC_MIN_REAL}; 157339e3443SMatthew G. Knepley PetscReal vbound[2], time; 158339e3443SMatthew G. Knepley PetscBool isnull, flg; 159d1df6f1dSMatthew G. Knepley PetscInt dim, Nf, f, Nc, comp, vStart, vEnd, cStart, cEnd, c, N, level, step, w = 0; 160e412dcbdSMatthew G. Knepley const char *name; 161339e3443SMatthew G. Knepley char title[PETSC_MAX_PATH_LEN]; 162e412dcbdSMatthew G. Knepley PetscErrorCode ierr; 163e412dcbdSMatthew G. Knepley 164e412dcbdSMatthew G. Knepley PetscFunctionBegin; 165d1df6f1dSMatthew G. Knepley ierr = PetscViewerDrawGetDraw(viewer, 0, &draw);CHKERRQ(ierr); 166d1df6f1dSMatthew G. Knepley ierr = PetscDrawIsNull(draw, &isnull);CHKERRQ(ierr); 167d1df6f1dSMatthew G. Knepley if (isnull) PetscFunctionReturn(0); 168d1df6f1dSMatthew G. Knepley 169e412dcbdSMatthew G. Knepley ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 170e412dcbdSMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dim);CHKERRQ(ierr); 1718135c375SStefano Zampini if (dim != 2) SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Cannot draw meshes of dimension %D. Use PETSCVIEWERGLVIS", dim); 17292fd8e1eSJed Brown ierr = DMGetLocalSection(dm, &s);CHKERRQ(ierr); 173d1df6f1dSMatthew G. Knepley ierr = PetscSectionGetNumFields(s, &Nf);CHKERRQ(ierr); 174e412dcbdSMatthew G. Knepley ierr = DMGetCoarsenLevel(dm, &level);CHKERRQ(ierr); 175e412dcbdSMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 17692fd8e1eSJed Brown ierr = DMGetLocalSection(cdm, &coordSection);CHKERRQ(ierr); 177e412dcbdSMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 178e412dcbdSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 179e412dcbdSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 180e412dcbdSMatthew G. Knepley 181e412dcbdSMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) v, &name);CHKERRQ(ierr); 182339e3443SMatthew G. Knepley ierr = DMGetOutputSequenceNumber(dm, &step, &time);CHKERRQ(ierr); 183e412dcbdSMatthew G. Knepley 184e412dcbdSMatthew G. Knepley ierr = VecGetLocalSize(coordinates, &N);CHKERRQ(ierr); 185e412dcbdSMatthew G. Knepley ierr = VecGetArrayRead(coordinates, &coords);CHKERRQ(ierr); 186e412dcbdSMatthew G. Knepley for (c = 0; c < N; c += dim) { 1870c81f2a8SMatthew G. Knepley bound[0] = PetscMin(bound[0], PetscRealPart(coords[c])); bound[2] = PetscMax(bound[2], PetscRealPart(coords[c])); 1880c81f2a8SMatthew G. Knepley bound[1] = PetscMin(bound[1], PetscRealPart(coords[c+1])); bound[3] = PetscMax(bound[3], PetscRealPart(coords[c+1])); 189e412dcbdSMatthew G. Knepley } 190e412dcbdSMatthew G. Knepley ierr = VecRestoreArrayRead(coordinates, &coords);CHKERRQ(ierr); 191e412dcbdSMatthew G. Knepley ierr = PetscDrawClear(draw);CHKERRQ(ierr); 192e412dcbdSMatthew G. Knepley 193d1df6f1dSMatthew G. Knepley /* Could implement something like DMDASelectFields() */ 194d1df6f1dSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 195d1df6f1dSMatthew G. Knepley DM fdm = dm; 196d1df6f1dSMatthew G. Knepley Vec fv = v; 197d1df6f1dSMatthew G. Knepley IS fis; 198d1df6f1dSMatthew G. Knepley char prefix[PETSC_MAX_PATH_LEN]; 199d1df6f1dSMatthew G. Knepley const char *fname; 200d1df6f1dSMatthew G. Knepley 201d1df6f1dSMatthew G. Knepley ierr = PetscSectionGetFieldComponents(s, f, &Nc);CHKERRQ(ierr); 202d1df6f1dSMatthew G. Knepley ierr = PetscSectionGetFieldName(s, f, &fname);CHKERRQ(ierr); 203d1df6f1dSMatthew G. Knepley 204a126751eSBarry Smith if (v->hdr.prefix) {ierr = PetscStrncpy(prefix, v->hdr.prefix,sizeof(prefix));CHKERRQ(ierr);} 205d1df6f1dSMatthew G. Knepley else {prefix[0] = '\0';} 206d1df6f1dSMatthew G. Knepley if (Nf > 1) { 207d1df6f1dSMatthew G. Knepley ierr = DMCreateSubDM(dm, 1, &f, &fis, &fdm);CHKERRQ(ierr); 208d1df6f1dSMatthew G. Knepley ierr = VecGetSubVector(v, fis, &fv);CHKERRQ(ierr); 209a126751eSBarry Smith ierr = PetscStrlcat(prefix, fname,sizeof(prefix));CHKERRQ(ierr); 210a126751eSBarry Smith ierr = PetscStrlcat(prefix, "_",sizeof(prefix));CHKERRQ(ierr); 211d1df6f1dSMatthew G. Knepley } 212d1df6f1dSMatthew G. Knepley for (comp = 0; comp < Nc; ++comp, ++w) { 213d1df6f1dSMatthew G. Knepley PetscInt nmax = 2; 214d1df6f1dSMatthew G. Knepley 215d1df6f1dSMatthew G. Knepley ierr = PetscViewerDrawGetDraw(viewer, w, &draw);CHKERRQ(ierr); 216d1df6f1dSMatthew G. Knepley if (Nc > 1) {ierr = PetscSNPrintf(title, sizeof(title), "%s:%s_%D Step: %D Time: %.4g", name, fname, comp, step, time);CHKERRQ(ierr);} 217d1df6f1dSMatthew G. Knepley else {ierr = PetscSNPrintf(title, sizeof(title), "%s:%s Step: %D Time: %.4g", name, fname, step, time);CHKERRQ(ierr);} 218d1df6f1dSMatthew G. Knepley ierr = PetscDrawSetTitle(draw, title);CHKERRQ(ierr); 219d1df6f1dSMatthew G. Knepley 220d1df6f1dSMatthew G. Knepley /* TODO Get max and min only for this component */ 221d1df6f1dSMatthew G. Knepley ierr = PetscOptionsGetRealArray(NULL, prefix, "-vec_view_bounds", vbound, &nmax, &flg);CHKERRQ(ierr); 222339e3443SMatthew G. Knepley if (!flg) { 223d1df6f1dSMatthew G. Knepley ierr = VecMin(fv, NULL, &vbound[0]);CHKERRQ(ierr); 224d1df6f1dSMatthew G. Knepley ierr = VecMax(fv, NULL, &vbound[1]);CHKERRQ(ierr); 225d1df6f1dSMatthew G. Knepley if (vbound[1] <= vbound[0]) vbound[1] = vbound[0] + 1.0; 226339e3443SMatthew G. Knepley } 227e412dcbdSMatthew G. Knepley ierr = PetscDrawGetPopup(draw, &popup);CHKERRQ(ierr); 228339e3443SMatthew G. Knepley ierr = PetscDrawScalePopup(popup, vbound[0], vbound[1]);CHKERRQ(ierr); 229d1df6f1dSMatthew G. Knepley ierr = PetscDrawSetCoordinates(draw, bound[0], bound[1], bound[2], bound[3]);CHKERRQ(ierr); 230e412dcbdSMatthew G. Knepley 231d1df6f1dSMatthew G. Knepley ierr = VecGetArrayRead(fv, &array);CHKERRQ(ierr); 232e412dcbdSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 23399a2f7bcSMatthew G. Knepley PetscScalar *coords = NULL, *a = NULL; 234e56f9228SJed Brown PetscInt numCoords, color[4] = {-1,-1,-1,-1}; 235e412dcbdSMatthew G. Knepley 236d1df6f1dSMatthew G. Knepley ierr = DMPlexPointLocalRead(fdm, c, array, &a);CHKERRQ(ierr); 237339e3443SMatthew G. Knepley if (a) { 238d1df6f1dSMatthew G. Knepley color[0] = PetscDrawRealToColor(PetscRealPart(a[comp]), vbound[0], vbound[1]); 239339e3443SMatthew G. Knepley color[1] = color[2] = color[3] = color[0]; 240339e3443SMatthew G. Knepley } else { 241339e3443SMatthew G. Knepley PetscScalar *vals = NULL; 242339e3443SMatthew G. Knepley PetscInt numVals, va; 243339e3443SMatthew G. Knepley 244d1df6f1dSMatthew G. Knepley ierr = DMPlexVecGetClosure(fdm, NULL, fv, c, &numVals, &vals);CHKERRQ(ierr); 245d1df6f1dSMatthew 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); 246d1df6f1dSMatthew G. Knepley switch (numVals/Nc) { 247d1df6f1dSMatthew G. Knepley case 3: /* P1 Triangle */ 248d1df6f1dSMatthew G. Knepley case 4: /* P1 Quadrangle */ 249d1df6f1dSMatthew G. Knepley for (va = 0; va < numVals/Nc; ++va) color[va] = PetscDrawRealToColor(PetscRealPart(vals[va*Nc+comp]), vbound[0], vbound[1]); 250339e3443SMatthew G. Knepley break; 251d1df6f1dSMatthew G. Knepley case 6: /* P2 Triangle */ 252d1df6f1dSMatthew G. Knepley case 8: /* P2 Quadrangle */ 253d1df6f1dSMatthew 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]); 254d1df6f1dSMatthew G. Knepley break; 255d1df6f1dSMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Number of values for cell closure %D cannot be handled", numVals/Nc); 256339e3443SMatthew G. Knepley } 257d1df6f1dSMatthew G. Knepley ierr = DMPlexVecRestoreClosure(fdm, NULL, fv, c, &numVals, &vals);CHKERRQ(ierr); 258339e3443SMatthew G. Knepley } 259e412dcbdSMatthew G. Knepley ierr = DMPlexVecGetClosure(dm, coordSection, coordinates, c, &numCoords, &coords);CHKERRQ(ierr); 260e412dcbdSMatthew G. Knepley switch (numCoords) { 261e412dcbdSMatthew G. Knepley case 6: 262339e3443SMatthew 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); 263e412dcbdSMatthew G. Knepley break; 264e412dcbdSMatthew G. Knepley case 8: 265339e3443SMatthew 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); 266339e3443SMatthew 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); 267e412dcbdSMatthew G. Knepley break; 268e412dcbdSMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot draw cells with %D coordinates", numCoords); 269e412dcbdSMatthew G. Knepley } 270e412dcbdSMatthew G. Knepley ierr = DMPlexVecRestoreClosure(dm, coordSection, coordinates, c, &numCoords, &coords);CHKERRQ(ierr); 271e412dcbdSMatthew G. Knepley } 272d1df6f1dSMatthew G. Knepley ierr = VecRestoreArrayRead(fv, &array);CHKERRQ(ierr); 273e412dcbdSMatthew G. Knepley ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 274e412dcbdSMatthew G. Knepley ierr = PetscDrawPause(draw);CHKERRQ(ierr); 275e412dcbdSMatthew G. Knepley ierr = PetscDrawSave(draw);CHKERRQ(ierr); 276d1df6f1dSMatthew G. Knepley } 277d1df6f1dSMatthew G. Knepley if (Nf > 1) { 278d1df6f1dSMatthew G. Knepley ierr = VecRestoreSubVector(v, fis, &fv);CHKERRQ(ierr); 279d1df6f1dSMatthew G. Knepley ierr = ISDestroy(&fis);CHKERRQ(ierr); 280d1df6f1dSMatthew G. Knepley ierr = DMDestroy(&fdm);CHKERRQ(ierr); 281d1df6f1dSMatthew G. Knepley } 282d1df6f1dSMatthew G. Knepley } 283e412dcbdSMatthew G. Knepley PetscFunctionReturn(0); 284e412dcbdSMatthew G. Knepley } 285e412dcbdSMatthew G. Knepley 286684b87d9SLisandro Dalcin static PetscErrorCode VecView_Plex_Local_VTK(Vec v, PetscViewer viewer) 287684b87d9SLisandro Dalcin { 288684b87d9SLisandro Dalcin DM dm; 289684b87d9SLisandro Dalcin Vec locv; 290684b87d9SLisandro Dalcin const char *name; 291684b87d9SLisandro Dalcin PetscSection section; 292684b87d9SLisandro Dalcin PetscInt pStart, pEnd; 293e630c359SToby Isaac PetscInt numFields; 294684b87d9SLisandro Dalcin PetscViewerVTKFieldType ft; 295684b87d9SLisandro Dalcin PetscErrorCode ierr; 296684b87d9SLisandro Dalcin 297684b87d9SLisandro Dalcin PetscFunctionBegin; 298684b87d9SLisandro Dalcin ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 299684b87d9SLisandro Dalcin ierr = DMCreateLocalVector(dm, &locv);CHKERRQ(ierr); /* VTK viewer requires exclusive ownership of the vector */ 300684b87d9SLisandro Dalcin ierr = PetscObjectGetName((PetscObject) v, &name);CHKERRQ(ierr); 301684b87d9SLisandro Dalcin ierr = PetscObjectSetName((PetscObject) locv, name);CHKERRQ(ierr); 302684b87d9SLisandro Dalcin ierr = VecCopy(v, locv);CHKERRQ(ierr); 30392fd8e1eSJed Brown ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr); 304e630c359SToby Isaac ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 305e630c359SToby Isaac if (!numFields) { 306684b87d9SLisandro Dalcin ierr = DMPlexGetFieldType_Internal(dm, section, PETSC_DETERMINE, &pStart, &pEnd, &ft);CHKERRQ(ierr); 307e630c359SToby Isaac ierr = PetscViewerVTKAddField(viewer, (PetscObject) dm, DMPlexVTKWriteAll, PETSC_DEFAULT, ft, PETSC_TRUE,(PetscObject) locv);CHKERRQ(ierr); 308e630c359SToby Isaac } else { 309e630c359SToby Isaac PetscInt f; 310e630c359SToby Isaac 311e630c359SToby Isaac for (f = 0; f < numFields; f++) { 312e630c359SToby Isaac ierr = DMPlexGetFieldType_Internal(dm, section, f, &pStart, &pEnd, &ft);CHKERRQ(ierr); 313e630c359SToby Isaac if (ft == PETSC_VTK_INVALID) continue; 314e630c359SToby Isaac ierr = PetscObjectReference((PetscObject)locv);CHKERRQ(ierr); 315e630c359SToby Isaac ierr = PetscViewerVTKAddField(viewer, (PetscObject) dm, DMPlexVTKWriteAll, f, ft, PETSC_TRUE,(PetscObject) locv);CHKERRQ(ierr); 316e630c359SToby Isaac } 317e630c359SToby Isaac ierr = VecDestroy(&locv);CHKERRQ(ierr); 318e630c359SToby Isaac } 319684b87d9SLisandro Dalcin PetscFunctionReturn(0); 320684b87d9SLisandro Dalcin } 321684b87d9SLisandro Dalcin 322552f7358SJed Brown PetscErrorCode VecView_Plex_Local(Vec v, PetscViewer viewer) 323552f7358SJed Brown { 324552f7358SJed Brown DM dm; 325684b87d9SLisandro Dalcin PetscBool isvtk, ishdf5, isdraw, isglvis; 326552f7358SJed Brown PetscErrorCode ierr; 327552f7358SJed Brown 328552f7358SJed Brown PetscFunctionBegin; 329552f7358SJed Brown ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 33082f516ccSBarry Smith if (!dm) SETERRQ(PetscObjectComm((PetscObject)v), PETSC_ERR_ARG_WRONG, "Vector not generated from a DM"); 331552f7358SJed Brown ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERVTK, &isvtk);CHKERRQ(ierr); 332b136c2c9SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 333f13a32a3SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERDRAW, &isdraw);CHKERRQ(ierr); 3348135c375SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERGLVIS, &isglvis);CHKERRQ(ierr); 335684b87d9SLisandro Dalcin if (isvtk || ishdf5 || isdraw || isglvis) { 336684b87d9SLisandro Dalcin PetscInt i,numFields; 337684b87d9SLisandro Dalcin PetscObject fe; 338ef31f671SMatthew G. Knepley PetscBool fem = PETSC_FALSE; 339684b87d9SLisandro Dalcin Vec locv = v; 340684b87d9SLisandro Dalcin const char *name; 341684b87d9SLisandro Dalcin PetscInt step; 342684b87d9SLisandro Dalcin PetscReal time; 343ef31f671SMatthew G. Knepley 344ef31f671SMatthew G. Knepley ierr = DMGetNumFields(dm, &numFields);CHKERRQ(ierr); 345684b87d9SLisandro Dalcin for (i=0; i<numFields; i++) { 34644a7f3ddSMatthew G. Knepley ierr = DMGetField(dm, i, NULL, &fe);CHKERRQ(ierr); 347684b87d9SLisandro Dalcin if (fe->classid == PETSCFE_CLASSID) { fem = PETSC_TRUE; break; } 348ef31f671SMatthew G. Knepley } 349684b87d9SLisandro Dalcin if (fem) { 350684b87d9SLisandro Dalcin ierr = DMGetLocalVector(dm, &locv);CHKERRQ(ierr); 351684b87d9SLisandro Dalcin ierr = PetscObjectGetName((PetscObject) v, &name);CHKERRQ(ierr); 352684b87d9SLisandro Dalcin ierr = PetscObjectSetName((PetscObject) locv, name);CHKERRQ(ierr); 353684b87d9SLisandro Dalcin ierr = VecCopy(v, locv);CHKERRQ(ierr); 354684b87d9SLisandro Dalcin ierr = DMGetOutputSequenceNumber(dm, NULL, &time);CHKERRQ(ierr); 355684b87d9SLisandro Dalcin ierr = DMPlexInsertBoundaryValues(dm, PETSC_TRUE, locv, time, NULL, NULL, NULL);CHKERRQ(ierr); 356ef31f671SMatthew G. Knepley } 357552f7358SJed Brown if (isvtk) { 358684b87d9SLisandro Dalcin ierr = VecView_Plex_Local_VTK(locv, viewer);CHKERRQ(ierr); 359b136c2c9SMatthew G. Knepley } else if (ishdf5) { 360b136c2c9SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 361684b87d9SLisandro Dalcin ierr = VecView_Plex_Local_HDF5_Internal(locv, viewer);CHKERRQ(ierr); 362b136c2c9SMatthew G. Knepley #else 363b136c2c9SMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 364b136c2c9SMatthew G. Knepley #endif 365f13a32a3SMatthew G. Knepley } else if (isdraw) { 366684b87d9SLisandro Dalcin ierr = VecView_Plex_Local_Draw(locv, viewer);CHKERRQ(ierr); 367684b87d9SLisandro Dalcin } else if (isglvis) { 368684b87d9SLisandro Dalcin ierr = DMGetOutputSequenceNumber(dm, &step, NULL);CHKERRQ(ierr); 369684b87d9SLisandro Dalcin ierr = PetscViewerGLVisSetSnapId(viewer, step);CHKERRQ(ierr); 370684b87d9SLisandro Dalcin ierr = VecView_GLVis(locv, viewer);CHKERRQ(ierr); 371684b87d9SLisandro Dalcin } 372684b87d9SLisandro Dalcin if (fem) {ierr = DMRestoreLocalVector(dm, &locv);CHKERRQ(ierr);} 373552f7358SJed Brown } else { 374684b87d9SLisandro Dalcin PetscBool isseq; 375684b87d9SLisandro Dalcin 376684b87d9SLisandro Dalcin ierr = PetscObjectTypeCompare((PetscObject) v, VECSEQ, &isseq);CHKERRQ(ierr); 37755f2e967SMatthew G. Knepley if (isseq) {ierr = VecView_Seq(v, viewer);CHKERRQ(ierr);} 37855f2e967SMatthew G. Knepley else {ierr = VecView_MPI(v, viewer);CHKERRQ(ierr);} 379552f7358SJed Brown } 380552f7358SJed Brown PetscFunctionReturn(0); 381552f7358SJed Brown } 382552f7358SJed Brown 383552f7358SJed Brown PetscErrorCode VecView_Plex(Vec v, PetscViewer viewer) 384552f7358SJed Brown { 385552f7358SJed Brown DM dm; 386684b87d9SLisandro Dalcin PetscBool isvtk, ishdf5, isdraw, isglvis; 387552f7358SJed Brown PetscErrorCode ierr; 388552f7358SJed Brown 389552f7358SJed Brown PetscFunctionBegin; 390552f7358SJed Brown ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 39182f516ccSBarry Smith if (!dm) SETERRQ(PetscObjectComm((PetscObject)v), PETSC_ERR_ARG_WRONG, "Vector not generated from a DM"); 392552f7358SJed Brown ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERVTK, &isvtk);CHKERRQ(ierr); 39333c3e6b4SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 394e412dcbdSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERDRAW, &isdraw);CHKERRQ(ierr); 3958135c375SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERGLVIS, &isglvis);CHKERRQ(ierr); 396684b87d9SLisandro Dalcin if (isvtk || isdraw || isglvis) { 397552f7358SJed Brown Vec locv; 398552f7358SJed Brown const char *name; 399552f7358SJed Brown 400c8dd51e9SBarry Smith ierr = DMGetLocalVector(dm, &locv);CHKERRQ(ierr); 401552f7358SJed Brown ierr = PetscObjectGetName((PetscObject) v, &name);CHKERRQ(ierr); 402552f7358SJed Brown ierr = PetscObjectSetName((PetscObject) locv, name);CHKERRQ(ierr); 403552f7358SJed Brown ierr = DMGlobalToLocalBegin(dm, v, INSERT_VALUES, locv);CHKERRQ(ierr); 404552f7358SJed Brown ierr = DMGlobalToLocalEnd(dm, v, INSERT_VALUES, locv);CHKERRQ(ierr); 405552f7358SJed Brown ierr = VecView_Plex_Local(locv, viewer);CHKERRQ(ierr); 406c8dd51e9SBarry Smith ierr = DMRestoreLocalVector(dm, &locv);CHKERRQ(ierr); 407b136c2c9SMatthew G. Knepley } else if (ishdf5) { 408b136c2c9SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 40939d25373SMatthew G. Knepley ierr = VecView_Plex_HDF5_Internal(v, viewer);CHKERRQ(ierr); 410b136c2c9SMatthew G. Knepley #else 411b136c2c9SMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 412b136c2c9SMatthew G. Knepley #endif 413552f7358SJed Brown } else { 414684b87d9SLisandro Dalcin PetscBool isseq; 415684b87d9SLisandro Dalcin 416684b87d9SLisandro Dalcin ierr = PetscObjectTypeCompare((PetscObject) v, VECSEQ, &isseq);CHKERRQ(ierr); 41755f2e967SMatthew G. Knepley if (isseq) {ierr = VecView_Seq(v, viewer);CHKERRQ(ierr);} 41855f2e967SMatthew G. Knepley else {ierr = VecView_MPI(v, viewer);CHKERRQ(ierr);} 419552f7358SJed Brown } 420552f7358SJed Brown PetscFunctionReturn(0); 421552f7358SJed Brown } 422552f7358SJed Brown 423d930f514SMatthew G. Knepley PetscErrorCode VecView_Plex_Native(Vec originalv, PetscViewer viewer) 424d930f514SMatthew G. Knepley { 425d930f514SMatthew G. Knepley DM dm; 426d930f514SMatthew G. Knepley MPI_Comm comm; 427d930f514SMatthew G. Knepley PetscViewerFormat format; 428d930f514SMatthew G. Knepley Vec v; 429d930f514SMatthew G. Knepley PetscBool isvtk, ishdf5; 430d930f514SMatthew G. Knepley PetscErrorCode ierr; 431d930f514SMatthew G. Knepley 432d930f514SMatthew G. Knepley PetscFunctionBegin; 433d930f514SMatthew G. Knepley ierr = VecGetDM(originalv, &dm);CHKERRQ(ierr); 434d930f514SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject) originalv, &comm);CHKERRQ(ierr); 4352c4c0c81SMatthew G. Knepley if (!dm) SETERRQ(comm, PETSC_ERR_ARG_WRONG, "Vector not generated from a DM"); 436d930f514SMatthew G. Knepley ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 437d930f514SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 438d930f514SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERVTK, &isvtk);CHKERRQ(ierr); 439d930f514SMatthew G. Knepley if (format == PETSC_VIEWER_NATIVE) { 440a8ad634aSStefano Zampini /* Natural ordering is the common case for DMDA, NATIVE means plain vector, for PLEX is the opposite */ 441a8ad634aSStefano Zampini /* this need a better fix */ 442a8ad634aSStefano Zampini if (dm->useNatural) { 443a8ad634aSStefano Zampini if (dm->sfNatural) { 444d930f514SMatthew G. Knepley const char *vecname; 445d930f514SMatthew G. Knepley PetscInt n, nroots; 446d930f514SMatthew G. Knepley 447ca43db0aSBarry Smith ierr = VecGetLocalSize(originalv, &n);CHKERRQ(ierr); 448d930f514SMatthew G. Knepley ierr = PetscSFGetGraph(dm->sfNatural, &nroots, NULL, NULL, NULL);CHKERRQ(ierr); 449d930f514SMatthew G. Knepley if (n == nroots) { 450d930f514SMatthew G. Knepley ierr = DMGetGlobalVector(dm, &v);CHKERRQ(ierr); 451d930f514SMatthew G. Knepley ierr = DMPlexGlobalToNaturalBegin(dm, originalv, v);CHKERRQ(ierr); 452d930f514SMatthew G. Knepley ierr = DMPlexGlobalToNaturalEnd(dm, originalv, v);CHKERRQ(ierr); 453d930f514SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) originalv, &vecname);CHKERRQ(ierr); 454d930f514SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) v, vecname);CHKERRQ(ierr); 455d930f514SMatthew G. Knepley } else SETERRQ(comm, PETSC_ERR_ARG_WRONG, "DM global to natural SF only handles global vectors"); 456d930f514SMatthew G. Knepley } else SETERRQ(comm, PETSC_ERR_ARG_WRONGSTATE, "DM global to natural SF was not created"); 457a8ad634aSStefano Zampini } else v = originalv; 458a8ad634aSStefano Zampini } else v = originalv; 459a8ad634aSStefano Zampini 460d930f514SMatthew G. Knepley if (ishdf5) { 461d930f514SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 46239d25373SMatthew G. Knepley ierr = VecView_Plex_HDF5_Native_Internal(v, viewer);CHKERRQ(ierr); 463d930f514SMatthew G. Knepley #else 464d930f514SMatthew G. Knepley SETERRQ(comm, PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 465d930f514SMatthew G. Knepley #endif 466d930f514SMatthew G. Knepley } else if (isvtk) { 467d930f514SMatthew G. Knepley SETERRQ(comm, PETSC_ERR_SUP, "VTK format does not support viewing in natural order. Please switch to HDF5."); 468d930f514SMatthew G. Knepley } else { 469d930f514SMatthew G. Knepley PetscBool isseq; 470d930f514SMatthew G. Knepley 471d930f514SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) v, VECSEQ, &isseq);CHKERRQ(ierr); 472d930f514SMatthew G. Knepley if (isseq) {ierr = VecView_Seq(v, viewer);CHKERRQ(ierr);} 473d930f514SMatthew G. Knepley else {ierr = VecView_MPI(v, viewer);CHKERRQ(ierr);} 474d930f514SMatthew G. Knepley } 475a8ad634aSStefano Zampini if (v != originalv) {ierr = DMRestoreGlobalVector(dm, &v);CHKERRQ(ierr);} 476d930f514SMatthew G. Knepley PetscFunctionReturn(0); 477d930f514SMatthew G. Knepley } 478d930f514SMatthew G. Knepley 4792c40f234SMatthew G. Knepley PetscErrorCode VecLoad_Plex_Local(Vec v, PetscViewer viewer) 4802c40f234SMatthew G. Knepley { 4812c40f234SMatthew G. Knepley DM dm; 4822c40f234SMatthew G. Knepley PetscBool ishdf5; 4832c40f234SMatthew G. Knepley PetscErrorCode ierr; 4842c40f234SMatthew G. Knepley 4852c40f234SMatthew G. Knepley PetscFunctionBegin; 4862c40f234SMatthew G. Knepley ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 4872c40f234SMatthew G. Knepley if (!dm) SETERRQ(PetscObjectComm((PetscObject)v), PETSC_ERR_ARG_WRONG, "Vector not generated from a DM"); 4882c40f234SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 4892c40f234SMatthew G. Knepley if (ishdf5) { 4902c40f234SMatthew G. Knepley DM dmBC; 4912c40f234SMatthew G. Knepley Vec gv; 4922c40f234SMatthew G. Knepley const char *name; 4932c40f234SMatthew G. Knepley 4942c40f234SMatthew G. Knepley ierr = DMGetOutputDM(dm, &dmBC);CHKERRQ(ierr); 4952c40f234SMatthew G. Knepley ierr = DMGetGlobalVector(dmBC, &gv);CHKERRQ(ierr); 4962c40f234SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) v, &name);CHKERRQ(ierr); 4972c40f234SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) gv, name);CHKERRQ(ierr); 4982c40f234SMatthew G. Knepley ierr = VecLoad_Default(gv, viewer);CHKERRQ(ierr); 4992c40f234SMatthew G. Knepley ierr = DMGlobalToLocalBegin(dmBC, gv, INSERT_VALUES, v);CHKERRQ(ierr); 5002c40f234SMatthew G. Knepley ierr = DMGlobalToLocalEnd(dmBC, gv, INSERT_VALUES, v);CHKERRQ(ierr); 5012c40f234SMatthew G. Knepley ierr = DMRestoreGlobalVector(dmBC, &gv);CHKERRQ(ierr); 5022c40f234SMatthew G. Knepley } else { 5032c40f234SMatthew G. Knepley ierr = VecLoad_Default(v, viewer);CHKERRQ(ierr); 5042c40f234SMatthew G. Knepley } 5052c40f234SMatthew G. Knepley PetscFunctionReturn(0); 5062c40f234SMatthew G. Knepley } 5072c40f234SMatthew G. Knepley 5082c40f234SMatthew G. Knepley PetscErrorCode VecLoad_Plex(Vec v, PetscViewer viewer) 5092c40f234SMatthew G. Knepley { 5102c40f234SMatthew G. Knepley DM dm; 5112c40f234SMatthew G. Knepley PetscBool ishdf5; 5122c40f234SMatthew G. Knepley PetscErrorCode ierr; 5132c40f234SMatthew G. Knepley 5142c40f234SMatthew G. Knepley PetscFunctionBegin; 5152c40f234SMatthew G. Knepley ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 5162c40f234SMatthew G. Knepley if (!dm) SETERRQ(PetscObjectComm((PetscObject)v), PETSC_ERR_ARG_WRONG, "Vector not generated from a DM"); 5172c40f234SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 5182c40f234SMatthew G. Knepley if (ishdf5) { 519878b459fSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 52039d25373SMatthew G. Knepley ierr = VecLoad_Plex_HDF5_Internal(v, viewer);CHKERRQ(ierr); 521b136c2c9SMatthew G. Knepley #else 522b136c2c9SMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 523878b459fSMatthew G. Knepley #endif 5242c40f234SMatthew G. Knepley } else { 5252c40f234SMatthew G. Knepley ierr = VecLoad_Default(v, viewer);CHKERRQ(ierr); 526552f7358SJed Brown } 527552f7358SJed Brown PetscFunctionReturn(0); 528552f7358SJed Brown } 529552f7358SJed Brown 530d930f514SMatthew G. Knepley PetscErrorCode VecLoad_Plex_Native(Vec originalv, PetscViewer viewer) 531d930f514SMatthew G. Knepley { 532d930f514SMatthew G. Knepley DM dm; 533d930f514SMatthew G. Knepley PetscViewerFormat format; 534d930f514SMatthew G. Knepley PetscBool ishdf5; 535d930f514SMatthew G. Knepley PetscErrorCode ierr; 536d930f514SMatthew G. Knepley 537d930f514SMatthew G. Knepley PetscFunctionBegin; 538d930f514SMatthew G. Knepley ierr = VecGetDM(originalv, &dm);CHKERRQ(ierr); 539d930f514SMatthew G. Knepley if (!dm) SETERRQ(PetscObjectComm((PetscObject) originalv), PETSC_ERR_ARG_WRONG, "Vector not generated from a DM"); 540d930f514SMatthew G. Knepley ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 541d930f514SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 542d930f514SMatthew G. Knepley if (format == PETSC_VIEWER_NATIVE) { 543a8ad634aSStefano Zampini if (dm->useNatural) { 544d930f514SMatthew G. Knepley if (dm->sfNatural) { 545d930f514SMatthew G. Knepley if (ishdf5) { 546d930f514SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 547d930f514SMatthew G. Knepley Vec v; 548d930f514SMatthew G. Knepley const char *vecname; 549d930f514SMatthew G. Knepley 550d930f514SMatthew G. Knepley ierr = DMGetGlobalVector(dm, &v);CHKERRQ(ierr); 551d930f514SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) originalv, &vecname);CHKERRQ(ierr); 552d930f514SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) v, vecname);CHKERRQ(ierr); 55339d25373SMatthew G. Knepley ierr = VecLoad_Plex_HDF5_Native_Internal(v, viewer);CHKERRQ(ierr); 554d930f514SMatthew G. Knepley ierr = DMPlexNaturalToGlobalBegin(dm, v, originalv);CHKERRQ(ierr); 555d930f514SMatthew G. Knepley ierr = DMPlexNaturalToGlobalEnd(dm, v, originalv);CHKERRQ(ierr); 556d930f514SMatthew G. Knepley ierr = DMRestoreGlobalVector(dm, &v);CHKERRQ(ierr); 557d930f514SMatthew G. Knepley #else 558d930f514SMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 559d930f514SMatthew G. Knepley #endif 560d930f514SMatthew G. Knepley } else SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Reading in natural order is not supported for anything but HDF5."); 561d930f514SMatthew G. Knepley } 562a8ad634aSStefano Zampini } else { 563a8ad634aSStefano Zampini ierr = VecLoad_Default(originalv, viewer);CHKERRQ(ierr); 564a8ad634aSStefano Zampini } 565d930f514SMatthew G. Knepley } 566d930f514SMatthew G. Knepley PetscFunctionReturn(0); 567d930f514SMatthew G. Knepley } 568d930f514SMatthew G. Knepley 5697cd05799SMatthew G. Knepley PETSC_UNUSED static PetscErrorCode DMPlexView_Ascii_Geometry(DM dm, PetscViewer viewer) 570731e8ddeSMatthew G. Knepley { 571731e8ddeSMatthew G. Knepley PetscSection coordSection; 572731e8ddeSMatthew G. Knepley Vec coordinates; 573731e8ddeSMatthew G. Knepley DMLabel depthLabel; 574731e8ddeSMatthew G. Knepley const char *name[4]; 575731e8ddeSMatthew G. Knepley const PetscScalar *a; 576731e8ddeSMatthew G. Knepley PetscInt dim, pStart, pEnd, cStart, cEnd, c; 577731e8ddeSMatthew G. Knepley PetscErrorCode ierr; 578731e8ddeSMatthew G. Knepley 579731e8ddeSMatthew G. Knepley PetscFunctionBegin; 580731e8ddeSMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 581731e8ddeSMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 582731e8ddeSMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 583731e8ddeSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &depthLabel);CHKERRQ(ierr); 584731e8ddeSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 585731e8ddeSMatthew G. Knepley ierr = PetscSectionGetChart(coordSection, &pStart, &pEnd);CHKERRQ(ierr); 586731e8ddeSMatthew G. Knepley ierr = VecGetArrayRead(coordinates, &a);CHKERRQ(ierr); 587731e8ddeSMatthew G. Knepley name[0] = "vertex"; 588731e8ddeSMatthew G. Knepley name[1] = "edge"; 589731e8ddeSMatthew G. Knepley name[dim-1] = "face"; 590731e8ddeSMatthew G. Knepley name[dim] = "cell"; 591731e8ddeSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 592731e8ddeSMatthew G. Knepley PetscInt *closure = NULL; 593731e8ddeSMatthew G. Knepley PetscInt closureSize, cl; 594731e8ddeSMatthew G. Knepley 595f347f43bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer, "Geometry for cell %D:\n", c);CHKERRQ(ierr); 596731e8ddeSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 597731e8ddeSMatthew G. Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 598731e8ddeSMatthew G. Knepley for (cl = 0; cl < closureSize*2; cl += 2) { 599731e8ddeSMatthew G. Knepley PetscInt point = closure[cl], depth, dof, off, d, p; 600731e8ddeSMatthew G. Knepley 601731e8ddeSMatthew G. Knepley if ((point < pStart) || (point >= pEnd)) continue; 602731e8ddeSMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, point, &dof);CHKERRQ(ierr); 603731e8ddeSMatthew G. Knepley if (!dof) continue; 604731e8ddeSMatthew G. Knepley ierr = DMLabelGetValue(depthLabel, point, &depth);CHKERRQ(ierr); 605731e8ddeSMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, point, &off);CHKERRQ(ierr); 606f347f43bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer, "%s %D coords:", name[depth], point);CHKERRQ(ierr); 607731e8ddeSMatthew G. Knepley for (p = 0; p < dof/dim; ++p) { 608731e8ddeSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " (");CHKERRQ(ierr); 609731e8ddeSMatthew G. Knepley for (d = 0; d < dim; ++d) { 610731e8ddeSMatthew G. Knepley if (d > 0) {ierr = PetscViewerASCIIPrintf(viewer, ", ");CHKERRQ(ierr);} 611087ef6b2SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "%g", (double) PetscRealPart(a[off+p*dim+d]));CHKERRQ(ierr); 612731e8ddeSMatthew G. Knepley } 613731e8ddeSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, ")");CHKERRQ(ierr); 614731e8ddeSMatthew G. Knepley } 615731e8ddeSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "\n");CHKERRQ(ierr); 616731e8ddeSMatthew G. Knepley } 617731e8ddeSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 618731e8ddeSMatthew G. Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 619731e8ddeSMatthew G. Knepley } 620731e8ddeSMatthew G. Knepley ierr = VecRestoreArrayRead(coordinates, &a);CHKERRQ(ierr); 621731e8ddeSMatthew G. Knepley PetscFunctionReturn(0); 622731e8ddeSMatthew G. Knepley } 623731e8ddeSMatthew G. Knepley 6247cd05799SMatthew G. Knepley static PetscErrorCode DMPlexView_Ascii(DM dm, PetscViewer viewer) 625552f7358SJed Brown { 626552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 627552f7358SJed Brown DM cdm; 628552f7358SJed Brown DMLabel markers; 629552f7358SJed Brown PetscSection coordSection; 630552f7358SJed Brown Vec coordinates; 631552f7358SJed Brown PetscViewerFormat format; 632552f7358SJed Brown PetscErrorCode ierr; 633552f7358SJed Brown 634552f7358SJed Brown PetscFunctionBegin; 635552f7358SJed Brown ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 63692fd8e1eSJed Brown ierr = DMGetLocalSection(cdm, &coordSection);CHKERRQ(ierr); 637552f7358SJed Brown ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 638552f7358SJed Brown ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 639552f7358SJed Brown if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 640552f7358SJed Brown const char *name; 641f73eea6eSMatthew G. Knepley PetscInt dim, cellHeight, maxConeSize, maxSupportSize; 642552f7358SJed Brown PetscInt pStart, pEnd, p; 643552f7358SJed Brown PetscMPIInt rank, size; 644552f7358SJed Brown 64582f516ccSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank);CHKERRQ(ierr); 64682f516ccSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)dm), &size);CHKERRQ(ierr); 647552f7358SJed Brown ierr = PetscObjectGetName((PetscObject) dm, &name);CHKERRQ(ierr); 648552f7358SJed Brown ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 649552f7358SJed Brown ierr = DMPlexGetMaxSizes(dm, &maxConeSize, &maxSupportSize);CHKERRQ(ierr); 650f73eea6eSMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 651f73eea6eSMatthew G. Knepley ierr = DMPlexGetVTKCellHeight(dm, &cellHeight);CHKERRQ(ierr); 652f73eea6eSMatthew G. Knepley if (name) {ierr = PetscViewerASCIIPrintf(viewer, "%s in %D dimension%s:\n", name, dim, dim == 1 ? "" : "s");CHKERRQ(ierr);} 653f73eea6eSMatthew G. Knepley else {ierr = PetscViewerASCIIPrintf(viewer, "Mesh in %D dimension%s:\n", dim, dim == 1 ? "" : "s");CHKERRQ(ierr);} 654f73eea6eSMatthew G. Knepley if (cellHeight) {ierr = PetscViewerASCIIPrintf(viewer, " Cells are at height %D\n", cellHeight);CHKERRQ(ierr);} 655e9cb465cSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "Supports:\n", name);CHKERRQ(ierr); 6564d4c343aSBarry Smith ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 657e9cb465cSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "[%d] Max support size: %D\n", rank, maxSupportSize);CHKERRQ(ierr); 658552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 659552f7358SJed Brown PetscInt dof, off, s; 660552f7358SJed Brown 661552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, &dof);CHKERRQ(ierr); 662552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, p, &off);CHKERRQ(ierr); 663552f7358SJed Brown for (s = off; s < off+dof; ++s) { 664e4b003c7SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer, "[%d]: %D ----> %D\n", rank, p, mesh->supports[s]);CHKERRQ(ierr); 665552f7358SJed Brown } 666552f7358SJed Brown } 667552f7358SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 668e9cb465cSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "Cones:\n", name);CHKERRQ(ierr); 669e9cb465cSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "[%d] Max cone size: %D\n", rank, maxConeSize);CHKERRQ(ierr); 670552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 671552f7358SJed Brown PetscInt dof, off, c; 672552f7358SJed Brown 673552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 674552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 675552f7358SJed Brown for (c = off; c < off+dof; ++c) { 676e4b003c7SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer, "[%d]: %D <---- %D (%D)\n", rank, p, mesh->cones[c], mesh->coneOrientations[c]);CHKERRQ(ierr); 677552f7358SJed Brown } 678552f7358SJed Brown } 679552f7358SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 6804d4c343aSBarry Smith ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); 6813d2e540fSStefano Zampini if (coordSection && coordinates) { 68280180ce3SStefano Zampini ierr = PetscSectionVecView(coordSection, coordinates, viewer);CHKERRQ(ierr); 6833d2e540fSStefano Zampini } 684c58f1c22SToby Isaac ierr = DMGetLabel(dm, "marker", &markers);CHKERRQ(ierr); 6857422c0d1SMatthew G. Knepley if (markers) {ierr = DMLabelView(markers,viewer);CHKERRQ(ierr);} 686552f7358SJed Brown if (size > 1) { 687552f7358SJed Brown PetscSF sf; 688552f7358SJed Brown 689552f7358SJed Brown ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 690552f7358SJed Brown ierr = PetscSFView(sf, viewer);CHKERRQ(ierr); 691552f7358SJed Brown } 692552f7358SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 693552f7358SJed Brown } else if (format == PETSC_VIEWER_ASCII_LATEX) { 6940588280cSMatthew G. Knepley const char *name, *color; 6950588280cSMatthew G. Knepley const char *defcolors[3] = {"gray", "orange", "green"}; 6960588280cSMatthew G. Knepley const char *deflcolors[4] = {"blue", "cyan", "red", "magenta"}; 697fe1cc32dSStefano Zampini char lname[PETSC_MAX_PATH_LEN]; 698552f7358SJed Brown PetscReal scale = 2.0; 69978081901SStefano Zampini PetscReal tikzscale = 1.0; 7000588280cSMatthew G. Knepley PetscBool useNumbers = PETSC_TRUE, useLabels, useColors; 7010588280cSMatthew G. Knepley double tcoords[3]; 702552f7358SJed Brown PetscScalar *coords; 7030588280cSMatthew G. Knepley PetscInt numLabels, l, numColors, numLColors, dim, depth, cStart, cEnd, c, vStart, vEnd, v, eStart = 0, eEnd = 0, e, p; 704552f7358SJed Brown PetscMPIInt rank, size; 7050588280cSMatthew G. Knepley char **names, **colors, **lcolors; 706fe1cc32dSStefano Zampini PetscBool plotEdges, flg, lflg; 707fe1cc32dSStefano Zampini PetscBT wp = NULL; 708fe1cc32dSStefano Zampini PetscInt pEnd, pStart; 709552f7358SJed Brown 7100588280cSMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 711552f7358SJed Brown ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 712c58f1c22SToby Isaac ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 7130588280cSMatthew G. Knepley numLabels = PetscMax(numLabels, 10); 7140588280cSMatthew G. Knepley numColors = 10; 7150588280cSMatthew G. Knepley numLColors = 10; 7160588280cSMatthew G. Knepley ierr = PetscCalloc3(numLabels, &names, numColors, &colors, numLColors, &lcolors);CHKERRQ(ierr); 717c5929fdfSBarry Smith ierr = PetscOptionsGetReal(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_scale", &scale, NULL);CHKERRQ(ierr); 71878081901SStefano Zampini ierr = PetscOptionsGetReal(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_tikzscale", &tikzscale, NULL);CHKERRQ(ierr); 719c5929fdfSBarry Smith ierr = PetscOptionsGetBool(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_numbers", &useNumbers, NULL);CHKERRQ(ierr); 720c5929fdfSBarry Smith ierr = PetscOptionsGetStringArray(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_labels", names, &numLabels, &useLabels);CHKERRQ(ierr); 7210588280cSMatthew G. Knepley if (!useLabels) numLabels = 0; 722c5929fdfSBarry Smith ierr = PetscOptionsGetStringArray(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_colors", colors, &numColors, &useColors);CHKERRQ(ierr); 7230588280cSMatthew G. Knepley if (!useColors) { 7240588280cSMatthew G. Knepley numColors = 3; 7250588280cSMatthew G. Knepley for (c = 0; c < numColors; ++c) {ierr = PetscStrallocpy(defcolors[c], &colors[c]);CHKERRQ(ierr);} 7260588280cSMatthew G. Knepley } 727c5929fdfSBarry Smith ierr = PetscOptionsGetStringArray(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_lcolors", lcolors, &numLColors, &useColors);CHKERRQ(ierr); 7280588280cSMatthew G. Knepley if (!useColors) { 7290588280cSMatthew G. Knepley numLColors = 4; 7300588280cSMatthew G. Knepley for (c = 0; c < numLColors; ++c) {ierr = PetscStrallocpy(deflcolors[c], &lcolors[c]);CHKERRQ(ierr);} 7310588280cSMatthew G. Knepley } 732fe1cc32dSStefano Zampini ierr = PetscOptionsGetString(((PetscObject) viewer)->options, ((PetscObject) viewer)->prefix, "-dm_plex_view_label_filter", lname, PETSC_MAX_PATH_LEN, &lflg);CHKERRQ(ierr); 733202fd40aSStefano Zampini plotEdges = (PetscBool)(depth > 1 && useNumbers && dim < 3); 734202fd40aSStefano Zampini ierr = PetscOptionsGetBool(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_edges", &plotEdges, &flg);CHKERRQ(ierr); 735202fd40aSStefano Zampini if (flg && plotEdges && depth < dim) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Mesh must be interpolated"); 736202fd40aSStefano Zampini if (depth < dim) plotEdges = PETSC_FALSE; 737fe1cc32dSStefano Zampini 738fe1cc32dSStefano Zampini /* filter points with labelvalue != labeldefaultvalue */ 739fe1cc32dSStefano Zampini ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 740fe1cc32dSStefano Zampini if (lflg) { 741fe1cc32dSStefano Zampini DMLabel lbl; 742fe1cc32dSStefano Zampini 743fe1cc32dSStefano Zampini ierr = DMGetLabel(dm, lname, &lbl);CHKERRQ(ierr); 744fe1cc32dSStefano Zampini if (lbl) { 745fe1cc32dSStefano Zampini PetscInt val, defval; 746fe1cc32dSStefano Zampini 747fe1cc32dSStefano Zampini ierr = DMLabelGetDefaultValue(lbl, &defval);CHKERRQ(ierr); 748fe1cc32dSStefano Zampini ierr = PetscBTCreate(pEnd-pStart, &wp);CHKERRQ(ierr); 749fe1cc32dSStefano Zampini for (c = pStart; c < pEnd; c++) { 750fe1cc32dSStefano Zampini PetscInt *closure = NULL; 751fe1cc32dSStefano Zampini PetscInt closureSize; 752fe1cc32dSStefano Zampini 753fe1cc32dSStefano Zampini ierr = DMLabelGetValue(lbl, c, &val);CHKERRQ(ierr); 754fe1cc32dSStefano Zampini if (val == defval) continue; 755fe1cc32dSStefano Zampini 756fe1cc32dSStefano Zampini ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 757fe1cc32dSStefano Zampini for (p = 0; p < closureSize*2; p += 2) { 758fe1cc32dSStefano Zampini ierr = PetscBTSet(wp, closure[p] - pStart);CHKERRQ(ierr); 759fe1cc32dSStefano Zampini } 760fe1cc32dSStefano Zampini ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 761fe1cc32dSStefano Zampini } 762fe1cc32dSStefano Zampini } 763fe1cc32dSStefano Zampini } 764fe1cc32dSStefano Zampini 76582f516ccSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank);CHKERRQ(ierr); 76682f516ccSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)dm), &size);CHKERRQ(ierr); 767552f7358SJed Brown ierr = PetscObjectGetName((PetscObject) dm, &name);CHKERRQ(ierr); 768770b213bSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, "\ 7690588280cSMatthew G. Knepley \\documentclass[tikz]{standalone}\n\n\ 770552f7358SJed Brown \\usepackage{pgflibraryshapes}\n\ 771552f7358SJed Brown \\usetikzlibrary{backgrounds}\n\ 772552f7358SJed Brown \\usetikzlibrary{arrows}\n\ 7730588280cSMatthew G. Knepley \\begin{document}\n");CHKERRQ(ierr); 7740588280cSMatthew G. Knepley if (size > 1) { 775f738dd31SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "%s for process ", name);CHKERRQ(ierr); 776770b213bSMatthew G Knepley for (p = 0; p < size; ++p) { 777770b213bSMatthew G Knepley if (p > 0 && p == size-1) { 778770b213bSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, ", and ", colors[p%numColors], p);CHKERRQ(ierr); 779770b213bSMatthew G Knepley } else if (p > 0) { 780770b213bSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, ", ", colors[p%numColors], p);CHKERRQ(ierr); 781770b213bSMatthew G Knepley } 782770b213bSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, "{\\textcolor{%s}%D}", colors[p%numColors], p);CHKERRQ(ierr); 783770b213bSMatthew G Knepley } 7840588280cSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, ".\n\n\n");CHKERRQ(ierr); 7850588280cSMatthew G. Knepley } 786087ef6b2SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "\\begin{tikzpicture}[scale = %g,font=\\fontsize{8}{8}\\selectfont]\n", (double) tikzscale);CHKERRQ(ierr); 787fe1cc32dSStefano Zampini 788552f7358SJed Brown /* Plot vertices */ 789552f7358SJed Brown ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 790552f7358SJed Brown ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 7914d4c343aSBarry Smith ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 792552f7358SJed Brown for (v = vStart; v < vEnd; ++v) { 793552f7358SJed Brown PetscInt off, dof, d; 7940588280cSMatthew G. Knepley PetscBool isLabeled = PETSC_FALSE; 795552f7358SJed Brown 796fe1cc32dSStefano Zampini if (wp && !PetscBTLookup(wp,v - pStart)) continue; 797552f7358SJed Brown ierr = PetscSectionGetDof(coordSection, v, &dof);CHKERRQ(ierr); 798552f7358SJed Brown ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 7990588280cSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "\\path (");CHKERRQ(ierr); 800f6dae198SJed Brown if (PetscUnlikely(dof > 3)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"coordSection vertex %D has dof %D > 3",v,dof); 8010588280cSMatthew G. Knepley for (d = 0; d < dof; ++d) { 8020588280cSMatthew G. Knepley tcoords[d] = (double) (scale*PetscRealPart(coords[off+d])); 803c068d9bbSLisandro Dalcin tcoords[d] = PetscAbs(tcoords[d]) < 1e-10 ? 0.0 : tcoords[d]; 8040588280cSMatthew G. Knepley } 8050588280cSMatthew G. Knepley /* Rotate coordinates since PGF makes z point out of the page instead of up */ 8060588280cSMatthew G. Knepley if (dim == 3) {PetscReal tmp = tcoords[1]; tcoords[1] = tcoords[2]; tcoords[2] = -tmp;} 807552f7358SJed Brown for (d = 0; d < dof; ++d) { 808552f7358SJed Brown if (d > 0) {ierr = PetscViewerASCIISynchronizedPrintf(viewer, ",");CHKERRQ(ierr);} 809087ef6b2SMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "%g", (double) tcoords[d]);CHKERRQ(ierr); 810552f7358SJed Brown } 8110588280cSMatthew G. Knepley color = colors[rank%numColors]; 8120588280cSMatthew G. Knepley for (l = 0; l < numLabels; ++l) { 8130588280cSMatthew G. Knepley PetscInt val; 814c58f1c22SToby Isaac ierr = DMGetLabelValue(dm, names[l], v, &val);CHKERRQ(ierr); 8150588280cSMatthew G. Knepley if (val >= 0) {color = lcolors[l%numLColors]; isLabeled = PETSC_TRUE; break;} 8160588280cSMatthew G. Knepley } 8170588280cSMatthew G. Knepley if (useNumbers) { 818e4b003c7SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer, ") node(%D_%d) [draw,shape=circle,color=%s] {%D};\n", v, rank, color, v);CHKERRQ(ierr); 8190588280cSMatthew G. Knepley } else { 820e4b003c7SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer, ") node(%D_%d) [fill,inner sep=%dpt,shape=circle,color=%s] {};\n", v, rank, !isLabeled ? 1 : 2, color);CHKERRQ(ierr); 8210588280cSMatthew G. Knepley } 822552f7358SJed Brown } 823552f7358SJed Brown ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 824552f7358SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 825846a3e8bSMatthew G. Knepley /* Plot cells */ 826846a3e8bSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 82778081901SStefano Zampini ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 828846a3e8bSMatthew G. Knepley if (dim == 3 || !useNumbers) { 829846a3e8bSMatthew G. Knepley for (e = eStart; e < eEnd; ++e) { 830846a3e8bSMatthew G. Knepley const PetscInt *cone; 831846a3e8bSMatthew G. Knepley 832fe1cc32dSStefano Zampini if (wp && !PetscBTLookup(wp,e - pStart)) continue; 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], e, &val);CHKERRQ(ierr); 837846a3e8bSMatthew G. Knepley if (val >= 0) {color = lcolors[l%numLColors]; break;} 838846a3e8bSMatthew G. Knepley } 839846a3e8bSMatthew G. Knepley ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 840846a3e8bSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "\\draw[color=%s] (%D_%d) -- (%D_%d);\n", color, cone[0], rank, cone[1], rank);CHKERRQ(ierr); 841846a3e8bSMatthew G. Knepley } 842846a3e8bSMatthew G. Knepley } else { 843846a3e8bSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 844846a3e8bSMatthew G. Knepley PetscInt *closure = NULL; 845846a3e8bSMatthew G. Knepley PetscInt closureSize, firstPoint = -1; 846846a3e8bSMatthew G. Knepley 847fe1cc32dSStefano Zampini if (wp && !PetscBTLookup(wp,c - pStart)) continue; 848846a3e8bSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 849846a3e8bSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "\\draw[color=%s] ", colors[rank%numColors]);CHKERRQ(ierr); 850846a3e8bSMatthew G. Knepley for (p = 0; p < closureSize*2; p += 2) { 851846a3e8bSMatthew G. Knepley const PetscInt point = closure[p]; 852846a3e8bSMatthew G. Knepley 853846a3e8bSMatthew G. Knepley if ((point < vStart) || (point >= vEnd)) continue; 854846a3e8bSMatthew G. Knepley if (firstPoint >= 0) {ierr = PetscViewerASCIISynchronizedPrintf(viewer, " -- ");CHKERRQ(ierr);} 855846a3e8bSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "(%D_%d)", point, rank);CHKERRQ(ierr); 856846a3e8bSMatthew G. Knepley if (firstPoint < 0) firstPoint = point; 857846a3e8bSMatthew G. Knepley } 858846a3e8bSMatthew G. Knepley /* Why doesn't this work? ierr = PetscViewerASCIISynchronizedPrintf(viewer, " -- cycle;\n");CHKERRQ(ierr); */ 859846a3e8bSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, " -- (%D_%d);\n", firstPoint, rank);CHKERRQ(ierr); 860846a3e8bSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 861846a3e8bSMatthew G. Knepley } 862846a3e8bSMatthew G. Knepley } 863846a3e8bSMatthew G. Knepley ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 864846a3e8bSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 865846a3e8bSMatthew G. Knepley double ccoords[3] = {0.0, 0.0, 0.0}; 866846a3e8bSMatthew G. Knepley PetscBool isLabeled = PETSC_FALSE; 867846a3e8bSMatthew G. Knepley PetscInt *closure = NULL; 868846a3e8bSMatthew G. Knepley PetscInt closureSize, dof, d, n = 0; 869846a3e8bSMatthew G. Knepley 870fe1cc32dSStefano Zampini if (wp && !PetscBTLookup(wp,c - pStart)) continue; 871846a3e8bSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 872846a3e8bSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "\\path (");CHKERRQ(ierr); 873846a3e8bSMatthew G. Knepley for (p = 0; p < closureSize*2; p += 2) { 874846a3e8bSMatthew G. Knepley const PetscInt point = closure[p]; 875846a3e8bSMatthew G. Knepley PetscInt off; 876846a3e8bSMatthew G. Knepley 877846a3e8bSMatthew G. Knepley if ((point < vStart) || (point >= vEnd)) continue; 878846a3e8bSMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, point, &dof);CHKERRQ(ierr); 879846a3e8bSMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, point, &off);CHKERRQ(ierr); 880846a3e8bSMatthew G. Knepley for (d = 0; d < dof; ++d) { 881846a3e8bSMatthew G. Knepley tcoords[d] = (double) (scale*PetscRealPart(coords[off+d])); 882846a3e8bSMatthew G. Knepley tcoords[d] = PetscAbs(tcoords[d]) < 1e-10 ? 0.0 : tcoords[d]; 883846a3e8bSMatthew G. Knepley } 884846a3e8bSMatthew G. Knepley /* Rotate coordinates since PGF makes z point out of the page instead of up */ 885846a3e8bSMatthew G. Knepley if (dof == 3) {PetscReal tmp = tcoords[1]; tcoords[1] = tcoords[2]; tcoords[2] = -tmp;} 886846a3e8bSMatthew G. Knepley for (d = 0; d < dof; ++d) {ccoords[d] += tcoords[d];} 887846a3e8bSMatthew G. Knepley ++n; 888846a3e8bSMatthew G. Knepley } 889846a3e8bSMatthew G. Knepley for (d = 0; d < dof; ++d) {ccoords[d] /= n;} 890846a3e8bSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 891846a3e8bSMatthew G. Knepley for (d = 0; d < dof; ++d) { 892846a3e8bSMatthew G. Knepley if (d > 0) {ierr = PetscViewerASCIISynchronizedPrintf(viewer, ",");CHKERRQ(ierr);} 893087ef6b2SMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "%g", (double) ccoords[d]);CHKERRQ(ierr); 894846a3e8bSMatthew G. Knepley } 895846a3e8bSMatthew G. Knepley color = colors[rank%numColors]; 896846a3e8bSMatthew G. Knepley for (l = 0; l < numLabels; ++l) { 897846a3e8bSMatthew G. Knepley PetscInt val; 898846a3e8bSMatthew G. Knepley ierr = DMGetLabelValue(dm, names[l], c, &val);CHKERRQ(ierr); 899846a3e8bSMatthew G. Knepley if (val >= 0) {color = lcolors[l%numLColors]; isLabeled = PETSC_TRUE; break;} 900846a3e8bSMatthew G. Knepley } 901846a3e8bSMatthew G. Knepley if (useNumbers) { 902846a3e8bSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, ") node(%D_%d) [draw,shape=circle,color=%s] {%D};\n", c, rank, color, c);CHKERRQ(ierr); 903846a3e8bSMatthew G. Knepley } else { 904846a3e8bSMatthew 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); 905846a3e8bSMatthew G. Knepley } 906846a3e8bSMatthew G. Knepley } 907846a3e8bSMatthew G. Knepley ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 908552f7358SJed Brown /* Plot edges */ 909202fd40aSStefano Zampini if (plotEdges) { 910552f7358SJed Brown ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 911552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, "\\path\n");CHKERRQ(ierr); 912552f7358SJed Brown for (e = eStart; e < eEnd; ++e) { 913552f7358SJed Brown const PetscInt *cone; 914552f7358SJed Brown PetscInt coneSize, offA, offB, dof, d; 915552f7358SJed Brown 916fe1cc32dSStefano Zampini if (wp && !PetscBTLookup(wp,e - pStart)) continue; 917552f7358SJed Brown ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr); 918f347f43bSBarry Smith if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %D cone should have two vertices, not %D", e, coneSize); 919552f7358SJed Brown ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 920552f7358SJed Brown ierr = PetscSectionGetDof(coordSection, cone[0], &dof);CHKERRQ(ierr); 921552f7358SJed Brown ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr); 922552f7358SJed Brown ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr); 923552f7358SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer, "(");CHKERRQ(ierr); 924552f7358SJed Brown for (d = 0; d < dof; ++d) { 925202fd40aSStefano Zampini tcoords[d] = (double) (0.5*scale*PetscRealPart(coords[offA+d]+coords[offB+d])); 926c068d9bbSLisandro Dalcin tcoords[d] = PetscAbs(tcoords[d]) < 1e-10 ? 0.0 : tcoords[d]; 927552f7358SJed Brown } 9280588280cSMatthew G. Knepley /* Rotate coordinates since PGF makes z point out of the page instead of up */ 9290588280cSMatthew G. Knepley if (dim == 3) {PetscReal tmp = tcoords[1]; tcoords[1] = tcoords[2]; tcoords[2] = -tmp;} 9300588280cSMatthew G. Knepley for (d = 0; d < dof; ++d) { 9310588280cSMatthew G. Knepley if (d > 0) {ierr = PetscViewerASCIISynchronizedPrintf(viewer, ",");CHKERRQ(ierr);} 932f347f43bSBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer, "%g", (double)tcoords[d]);CHKERRQ(ierr); 9330588280cSMatthew G. Knepley } 9340588280cSMatthew G. Knepley color = colors[rank%numColors]; 9350588280cSMatthew G. Knepley for (l = 0; l < numLabels; ++l) { 9360588280cSMatthew G. Knepley PetscInt val; 937c58f1c22SToby Isaac ierr = DMGetLabelValue(dm, names[l], v, &val);CHKERRQ(ierr); 9380750fff4SMatthew G. Knepley if (val >= 0) {color = lcolors[l%numLColors]; break;} 9390588280cSMatthew G. Knepley } 940e4b003c7SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer, ") node(%D_%d) [draw,shape=circle,color=%s] {%D} --\n", e, rank, color, e);CHKERRQ(ierr); 941552f7358SJed Brown } 942552f7358SJed Brown ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 943552f7358SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 944552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, "(0,0);\n");CHKERRQ(ierr); 9450588280cSMatthew G. Knepley } 946552f7358SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 9474d4c343aSBarry Smith ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); 9480588280cSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "\\end{tikzpicture}\n");CHKERRQ(ierr); 949770b213bSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, "\\end{document}\n", name);CHKERRQ(ierr); 9500588280cSMatthew G. Knepley for (l = 0; l < numLabels; ++l) {ierr = PetscFree(names[l]);CHKERRQ(ierr);} 9510588280cSMatthew G. Knepley for (c = 0; c < numColors; ++c) {ierr = PetscFree(colors[c]);CHKERRQ(ierr);} 9520588280cSMatthew G. Knepley for (c = 0; c < numLColors; ++c) {ierr = PetscFree(lcolors[c]);CHKERRQ(ierr);} 9530588280cSMatthew G. Knepley ierr = PetscFree3(names, colors, lcolors);CHKERRQ(ierr); 954fe1cc32dSStefano Zampini ierr = PetscBTDestroy(&wp);CHKERRQ(ierr); 9550f7d6e4aSStefano Zampini } else if (format == PETSC_VIEWER_LOAD_BALANCE) { 9560f7d6e4aSStefano Zampini Vec cown,acown; 9570f7d6e4aSStefano Zampini VecScatter sct; 9580f7d6e4aSStefano Zampini ISLocalToGlobalMapping g2l; 9590f7d6e4aSStefano Zampini IS gid,acis; 9600f7d6e4aSStefano Zampini MPI_Comm comm,ncomm = MPI_COMM_NULL; 9610f7d6e4aSStefano Zampini MPI_Group ggroup,ngroup; 9620f7d6e4aSStefano Zampini PetscScalar *array,nid; 9630f7d6e4aSStefano Zampini const PetscInt *idxs; 9640f7d6e4aSStefano Zampini PetscInt *idxs2,*start,*adjacency,*work; 9650f7d6e4aSStefano Zampini PetscInt64 lm[3],gm[3]; 9660f7d6e4aSStefano Zampini PetscInt i,c,cStart,cEnd,cum,numVertices,ect,ectn,cellHeight; 9670f7d6e4aSStefano Zampini PetscMPIInt d1,d2,rank; 9680f7d6e4aSStefano Zampini 9690f7d6e4aSStefano Zampini ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 9700f7d6e4aSStefano Zampini ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 971b674149eSJunchao Zhang #if defined(PETSC_HAVE_MPI_PROCESS_SHARED_MEMORY) 9720f7d6e4aSStefano Zampini ierr = MPI_Comm_split_type(comm,MPI_COMM_TYPE_SHARED,rank,MPI_INFO_NULL,&ncomm);CHKERRQ(ierr); 9730f7d6e4aSStefano Zampini #endif 9740f7d6e4aSStefano Zampini if (ncomm != MPI_COMM_NULL) { 9750f7d6e4aSStefano Zampini ierr = MPI_Comm_group(comm,&ggroup);CHKERRQ(ierr); 9760f7d6e4aSStefano Zampini ierr = MPI_Comm_group(ncomm,&ngroup);CHKERRQ(ierr); 9770f7d6e4aSStefano Zampini d1 = 0; 9780f7d6e4aSStefano Zampini ierr = MPI_Group_translate_ranks(ngroup,1,&d1,ggroup,&d2);CHKERRQ(ierr); 9790f7d6e4aSStefano Zampini nid = d2; 9800f7d6e4aSStefano Zampini ierr = MPI_Group_free(&ggroup);CHKERRQ(ierr); 9810f7d6e4aSStefano Zampini ierr = MPI_Group_free(&ngroup);CHKERRQ(ierr); 9820f7d6e4aSStefano Zampini ierr = MPI_Comm_free(&ncomm);CHKERRQ(ierr); 9830f7d6e4aSStefano Zampini } else nid = 0.0; 9840f7d6e4aSStefano Zampini 9850f7d6e4aSStefano Zampini /* Get connectivity */ 9860f7d6e4aSStefano Zampini ierr = DMPlexGetVTKCellHeight(dm,&cellHeight);CHKERRQ(ierr); 9870f7d6e4aSStefano Zampini ierr = DMPlexCreatePartitionerGraph(dm,cellHeight,&numVertices,&start,&adjacency,&gid);CHKERRQ(ierr); 9880f7d6e4aSStefano Zampini 9890f7d6e4aSStefano Zampini /* filter overlapped local cells */ 9900f7d6e4aSStefano Zampini ierr = DMPlexGetHeightStratum(dm,cellHeight,&cStart,&cEnd);CHKERRQ(ierr); 9910f7d6e4aSStefano Zampini ierr = ISGetIndices(gid,&idxs);CHKERRQ(ierr); 9920f7d6e4aSStefano Zampini ierr = ISGetLocalSize(gid,&cum);CHKERRQ(ierr); 9930f7d6e4aSStefano Zampini ierr = PetscMalloc1(cum,&idxs2);CHKERRQ(ierr); 9940f7d6e4aSStefano Zampini for (c = cStart, cum = 0; c < cEnd; c++) { 9950f7d6e4aSStefano Zampini if (idxs[c-cStart] < 0) continue; 9960f7d6e4aSStefano Zampini idxs2[cum++] = idxs[c-cStart]; 9970f7d6e4aSStefano Zampini } 9980f7d6e4aSStefano Zampini ierr = ISRestoreIndices(gid,&idxs);CHKERRQ(ierr); 9990f7d6e4aSStefano Zampini if (numVertices != cum) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected %D != %D",numVertices,cum); 10000f7d6e4aSStefano Zampini ierr = ISDestroy(&gid);CHKERRQ(ierr); 10010f7d6e4aSStefano Zampini ierr = ISCreateGeneral(comm,numVertices,idxs2,PETSC_OWN_POINTER,&gid);CHKERRQ(ierr); 10020f7d6e4aSStefano Zampini 10030f7d6e4aSStefano Zampini /* support for node-aware cell locality */ 10040f7d6e4aSStefano Zampini ierr = ISCreateGeneral(comm,start[numVertices],adjacency,PETSC_USE_POINTER,&acis);CHKERRQ(ierr); 10050f7d6e4aSStefano Zampini ierr = VecCreateSeq(PETSC_COMM_SELF,start[numVertices],&acown);CHKERRQ(ierr); 10060f7d6e4aSStefano Zampini ierr = VecCreateMPI(comm,numVertices,PETSC_DECIDE,&cown);CHKERRQ(ierr); 10070f7d6e4aSStefano Zampini ierr = VecGetArray(cown,&array);CHKERRQ(ierr); 10080f7d6e4aSStefano Zampini for (c = 0; c < numVertices; c++) array[c] = nid; 10090f7d6e4aSStefano Zampini ierr = VecRestoreArray(cown,&array);CHKERRQ(ierr); 10100f7d6e4aSStefano Zampini ierr = VecScatterCreate(cown,acis,acown,NULL,&sct);CHKERRQ(ierr); 10110f7d6e4aSStefano Zampini ierr = VecScatterBegin(sct,cown,acown,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 10120f7d6e4aSStefano Zampini ierr = VecScatterEnd(sct,cown,acown,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 10130f7d6e4aSStefano Zampini ierr = ISDestroy(&acis);CHKERRQ(ierr); 10140f7d6e4aSStefano Zampini ierr = VecScatterDestroy(&sct);CHKERRQ(ierr); 10150f7d6e4aSStefano Zampini ierr = VecDestroy(&cown);CHKERRQ(ierr); 10160f7d6e4aSStefano Zampini 10170f7d6e4aSStefano Zampini /* compute edgeCut */ 10180f7d6e4aSStefano Zampini for (c = 0, cum = 0; c < numVertices; c++) cum = PetscMax(cum,start[c+1]-start[c]); 10190f7d6e4aSStefano Zampini ierr = PetscMalloc1(cum,&work);CHKERRQ(ierr); 10200f7d6e4aSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(gid,&g2l);CHKERRQ(ierr); 10210f7d6e4aSStefano Zampini ierr = ISLocalToGlobalMappingSetType(g2l,ISLOCALTOGLOBALMAPPINGHASH);CHKERRQ(ierr); 10220f7d6e4aSStefano Zampini ierr = ISDestroy(&gid);CHKERRQ(ierr); 10230f7d6e4aSStefano Zampini ierr = VecGetArray(acown,&array);CHKERRQ(ierr); 10240f7d6e4aSStefano Zampini for (c = 0, ect = 0, ectn = 0; c < numVertices; c++) { 10250f7d6e4aSStefano Zampini PetscInt totl; 10260f7d6e4aSStefano Zampini 10270f7d6e4aSStefano Zampini totl = start[c+1]-start[c]; 10280f7d6e4aSStefano Zampini ierr = ISGlobalToLocalMappingApply(g2l,IS_GTOLM_MASK,totl,adjacency+start[c],NULL,work);CHKERRQ(ierr); 10290f7d6e4aSStefano Zampini for (i = 0; i < totl; i++) { 10300f7d6e4aSStefano Zampini if (work[i] < 0) { 10310f7d6e4aSStefano Zampini ect += 1; 10320f7d6e4aSStefano Zampini ectn += (array[i + start[c]] != nid) ? 0 : 1; 10330f7d6e4aSStefano Zampini } 10340f7d6e4aSStefano Zampini } 10350f7d6e4aSStefano Zampini } 10360f7d6e4aSStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 10370f7d6e4aSStefano Zampini ierr = VecRestoreArray(acown,&array);CHKERRQ(ierr); 10380f7d6e4aSStefano Zampini lm[0] = numVertices > 0 ? numVertices : PETSC_MAX_INT; 10390f7d6e4aSStefano Zampini lm[1] = -numVertices; 10400f7d6e4aSStefano Zampini ierr = MPIU_Allreduce(lm,gm,2,MPIU_INT64,MPI_MIN,comm);CHKERRQ(ierr); 10410f7d6e4aSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Cell balance: %.2f (max %D, min %D",-((double)gm[1])/((double)gm[0]),-(PetscInt)gm[1],(PetscInt)gm[0]);CHKERRQ(ierr); 10420f7d6e4aSStefano Zampini lm[0] = ect; /* edgeCut */ 10430f7d6e4aSStefano Zampini lm[1] = ectn; /* node-aware edgeCut */ 10440f7d6e4aSStefano Zampini lm[2] = numVertices > 0 ? 0 : 1; /* empty processes */ 10450f7d6e4aSStefano Zampini ierr = MPIU_Allreduce(lm,gm,3,MPIU_INT64,MPI_SUM,comm);CHKERRQ(ierr); 10460f7d6e4aSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,", empty %D)\n",(PetscInt)gm[2]);CHKERRQ(ierr); 1047b674149eSJunchao Zhang #if defined(PETSC_HAVE_MPI_PROCESS_SHARED_MEMORY) 10480f7d6e4aSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Edge Cut: %D (on node %.3f)\n",(PetscInt)(gm[0]/2),gm[0] ? ((double)(gm[1]))/((double)gm[0]) : 1.);CHKERRQ(ierr); 10490f7d6e4aSStefano Zampini #else 10500f7d6e4aSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Edge Cut: %D (on node %.3f)\n",(PetscInt)(gm[0]/2),0.0);CHKERRQ(ierr); 10510f7d6e4aSStefano Zampini #endif 10520f7d6e4aSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&g2l);CHKERRQ(ierr); 10530f7d6e4aSStefano Zampini ierr = PetscFree(start);CHKERRQ(ierr); 10540f7d6e4aSStefano Zampini ierr = PetscFree(adjacency);CHKERRQ(ierr); 10550f7d6e4aSStefano Zampini ierr = VecDestroy(&acown);CHKERRQ(ierr); 1056552f7358SJed Brown } else { 105782f516ccSBarry Smith MPI_Comm comm; 1058d80ece95SMatthew G. Knepley PetscInt *sizes, *hybsizes, *ghostsizes; 1059f73eea6eSMatthew G. Knepley PetscInt locDepth, depth, cellHeight, dim, d, pMax[4]; 1060d80ece95SMatthew G. Knepley PetscInt pStart, pEnd, p, gcStart, gcEnd, gcNum; 1061a57dd577SMatthew G Knepley PetscInt numLabels, l; 10621143a3c0SMatthew G. Knepley const char *name; 1063552f7358SJed Brown PetscMPIInt size; 1064552f7358SJed Brown 106582f516ccSBarry Smith ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 1066552f7358SJed Brown ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 1067c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 1068f73eea6eSMatthew G. Knepley ierr = DMPlexGetVTKCellHeight(dm, &cellHeight);CHKERRQ(ierr); 10695f64d76eSMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) dm, &name);CHKERRQ(ierr); 1070f73eea6eSMatthew G. Knepley if (name) {ierr = PetscViewerASCIIPrintf(viewer, "%s in %D dimension%s:\n", name, dim, dim == 1 ? "" : "s");CHKERRQ(ierr);} 1071f73eea6eSMatthew G. Knepley else {ierr = PetscViewerASCIIPrintf(viewer, "Mesh in %D dimension%s:\n", dim, dim == 1 ? "" : "s");CHKERRQ(ierr);} 1072f73eea6eSMatthew G. Knepley if (cellHeight) {ierr = PetscViewerASCIIPrintf(viewer, " Cells are at height %D\n", cellHeight);CHKERRQ(ierr);} 1073552f7358SJed Brown ierr = DMPlexGetDepth(dm, &locDepth);CHKERRQ(ierr); 1074b2566f29SBarry Smith ierr = MPIU_Allreduce(&locDepth, &depth, 1, MPIU_INT, MPI_MAX, comm);CHKERRQ(ierr); 1075a04427b4SStefano Zampini ierr = DMPlexGetHybridBounds(dm, &pMax[depth], depth > 0 ? &pMax[depth-1] : NULL, depth > 1 ? &pMax[depth - 2] : NULL, &pMax[0]);CHKERRQ(ierr); 1076d80ece95SMatthew G. Knepley ierr = DMPlexGetGhostCellStratum(dm, &gcStart, &gcEnd);CHKERRQ(ierr); 1077d80ece95SMatthew G. Knepley gcNum = gcEnd - gcStart; 1078d80ece95SMatthew G. Knepley ierr = PetscCalloc3(size,&sizes,size,&hybsizes,size,&ghostsizes);CHKERRQ(ierr); 1079552f7358SJed Brown if (depth == 1) { 1080552f7358SJed Brown ierr = DMPlexGetDepthStratum(dm, 0, &pStart, &pEnd);CHKERRQ(ierr); 1081552f7358SJed Brown pEnd = pEnd - pStart; 1082a04427b4SStefano Zampini pMax[0] -= pStart; 1083552f7358SJed Brown ierr = MPI_Gather(&pEnd, 1, MPIU_INT, sizes, 1, MPIU_INT, 0, comm);CHKERRQ(ierr); 1084a04427b4SStefano Zampini ierr = MPI_Gather(&pMax[0], 1, MPIU_INT, hybsizes, 1, MPIU_INT, 0, comm);CHKERRQ(ierr); 1085d80ece95SMatthew G. Knepley ierr = MPI_Gather(&gcNum, 1, MPIU_INT, ghostsizes, 1, MPIU_INT, 0, comm);CHKERRQ(ierr); 1086f347f43bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer, " %d-cells:", 0);CHKERRQ(ierr); 1087a04427b4SStefano Zampini for (p = 0; p < size; ++p) { 1088a04427b4SStefano Zampini if (hybsizes[p] >= 0) {ierr = PetscViewerASCIIPrintf(viewer, " %D (%D)", sizes[p], sizes[p] - hybsizes[p]);CHKERRQ(ierr);} 1089a04427b4SStefano Zampini else {ierr = PetscViewerASCIIPrintf(viewer, " %D", sizes[p]);CHKERRQ(ierr);} 1090a04427b4SStefano Zampini } 1091552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, "\n");CHKERRQ(ierr); 1092552f7358SJed Brown ierr = DMPlexGetHeightStratum(dm, 0, &pStart, &pEnd);CHKERRQ(ierr); 1093552f7358SJed Brown pEnd = pEnd - pStart; 1094a04427b4SStefano Zampini pMax[depth] -= pStart; 1095552f7358SJed Brown ierr = MPI_Gather(&pEnd, 1, MPIU_INT, sizes, 1, MPIU_INT, 0, comm);CHKERRQ(ierr); 1096a04427b4SStefano Zampini ierr = MPI_Gather(&pMax[depth], 1, MPIU_INT, hybsizes, 1, MPIU_INT, 0, comm);CHKERRQ(ierr); 1097552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, " %D-cells:", dim);CHKERRQ(ierr); 1098a04427b4SStefano Zampini for (p = 0; p < size; ++p) { 1099d80ece95SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " %D", sizes[p]);CHKERRQ(ierr); 1100d80ece95SMatthew G. Knepley if (hybsizes[p] >= 0) {ierr = PetscViewerASCIIPrintf(viewer, " (%D)", sizes[p] - hybsizes[p]);CHKERRQ(ierr);} 1101d80ece95SMatthew G. Knepley if (ghostsizes[p] > 0) {ierr = PetscViewerASCIIPrintf(viewer, " [%D]", ghostsizes[p]);CHKERRQ(ierr);} 1102a04427b4SStefano Zampini } 1103552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, "\n");CHKERRQ(ierr); 1104552f7358SJed Brown } else { 1105cbb7f117SMark Adams PetscMPIInt rank; 1106cbb7f117SMark Adams ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 1107552f7358SJed Brown for (d = 0; d <= dim; d++) { 1108552f7358SJed Brown ierr = DMPlexGetDepthStratum(dm, d, &pStart, &pEnd);CHKERRQ(ierr); 1109834065abSMatthew G. Knepley pEnd -= pStart; 1110834065abSMatthew G. Knepley pMax[d] -= pStart; 1111552f7358SJed Brown ierr = MPI_Gather(&pEnd, 1, MPIU_INT, sizes, 1, MPIU_INT, 0, comm);CHKERRQ(ierr); 1112834065abSMatthew G. Knepley ierr = MPI_Gather(&pMax[d], 1, MPIU_INT, hybsizes, 1, MPIU_INT, 0, comm);CHKERRQ(ierr); 1113d80ece95SMatthew G. Knepley if (d == dim) {ierr = MPI_Gather(&gcNum, 1, MPIU_INT, ghostsizes, 1, MPIU_INT, 0, comm);CHKERRQ(ierr);} 1114552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, " %D-cells:", d);CHKERRQ(ierr); 1115834065abSMatthew G. Knepley for (p = 0; p < size; ++p) { 1116cbb7f117SMark Adams if (!rank) { 1117d80ece95SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " %D", sizes[p]);CHKERRQ(ierr); 1118d80ece95SMatthew G. Knepley if (hybsizes[p] >= 0) {ierr = PetscViewerASCIIPrintf(viewer, " (%D)", sizes[p] - hybsizes[p]);CHKERRQ(ierr);} 1119d80ece95SMatthew G. Knepley if (d == dim && ghostsizes[p] > 0) {ierr = PetscViewerASCIIPrintf(viewer, " [%D]", ghostsizes[p]);CHKERRQ(ierr);} 1120834065abSMatthew G. Knepley } 1121cbb7f117SMark Adams } 1122552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, "\n");CHKERRQ(ierr); 1123552f7358SJed Brown } 1124552f7358SJed Brown } 1125d80ece95SMatthew G. Knepley ierr = PetscFree3(sizes,hybsizes,ghostsizes);CHKERRQ(ierr); 1126c58f1c22SToby Isaac ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 1127a57dd577SMatthew G Knepley if (numLabels) {ierr = PetscViewerASCIIPrintf(viewer, "Labels:\n");CHKERRQ(ierr);} 1128a57dd577SMatthew G Knepley for (l = 0; l < numLabels; ++l) { 1129a57dd577SMatthew G Knepley DMLabel label; 1130a57dd577SMatthew G Knepley const char *name; 1131a57dd577SMatthew G Knepley IS valueIS; 1132a57dd577SMatthew G Knepley const PetscInt *values; 1133a57dd577SMatthew G Knepley PetscInt numValues, v; 1134a57dd577SMatthew G Knepley 1135c58f1c22SToby Isaac ierr = DMGetLabelName(dm, l, &name);CHKERRQ(ierr); 1136c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 1137a57dd577SMatthew G Knepley ierr = DMLabelGetNumValues(label, &numValues);CHKERRQ(ierr); 1138d72f73ffSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " %s: %D strata with value/size (", name, numValues);CHKERRQ(ierr); 1139a57dd577SMatthew G Knepley ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 1140a57dd577SMatthew G Knepley ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 1141120dea56SMatthew G. Knepley ierr = PetscViewerASCIIUseTabs(viewer, PETSC_FALSE);CHKERRQ(ierr); 1142a57dd577SMatthew G Knepley for (v = 0; v < numValues; ++v) { 1143a57dd577SMatthew G Knepley PetscInt size; 1144a57dd577SMatthew G Knepley 1145a57dd577SMatthew G Knepley ierr = DMLabelGetStratumSize(label, values[v], &size);CHKERRQ(ierr); 1146a57dd577SMatthew G Knepley if (v > 0) {ierr = PetscViewerASCIIPrintf(viewer, ", ");CHKERRQ(ierr);} 1147d72f73ffSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "%D (%D)", values[v], size);CHKERRQ(ierr); 1148a57dd577SMatthew G Knepley } 1149a57dd577SMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, ")\n");CHKERRQ(ierr); 1150120dea56SMatthew G. Knepley ierr = PetscViewerASCIIUseTabs(viewer, PETSC_TRUE);CHKERRQ(ierr); 1151a57dd577SMatthew G Knepley ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 11524d41221fSMatthew G Knepley ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 1153a57dd577SMatthew G Knepley } 115434aa8a36SMatthew G. Knepley /* If no fields are specified, people do not want to see adjacency */ 115534aa8a36SMatthew G. Knepley if (dm->Nf) { 115634aa8a36SMatthew G. Knepley PetscInt f; 115734aa8a36SMatthew G. Knepley 115834aa8a36SMatthew G. Knepley for (f = 0; f < dm->Nf; ++f) { 115934aa8a36SMatthew G. Knepley const char *name; 116034aa8a36SMatthew G. Knepley 116134aa8a36SMatthew G. Knepley ierr = PetscObjectGetName(dm->fields[f].disc, &name);CHKERRQ(ierr); 116234aa8a36SMatthew G. Knepley if (numLabels) {ierr = PetscViewerASCIIPrintf(viewer, "Field %s:\n", name);CHKERRQ(ierr);} 116334aa8a36SMatthew G. Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 116434aa8a36SMatthew G. Knepley if (dm->fields[f].label) {ierr = DMLabelView(dm->fields[f].label, viewer);CHKERRQ(ierr);} 116534aa8a36SMatthew G. Knepley if (dm->fields[f].adjacency[0]) { 116634aa8a36SMatthew G. Knepley if (dm->fields[f].adjacency[1]) {ierr = PetscViewerASCIIPrintf(viewer, "adjacency FVM++\n");CHKERRQ(ierr);} 1167ed59e46eSMatthew G. Knepley else {ierr = PetscViewerASCIIPrintf(viewer, "adjacency FVM\n");CHKERRQ(ierr);} 116834aa8a36SMatthew G. Knepley } else { 116934aa8a36SMatthew G. Knepley if (dm->fields[f].adjacency[1]) {ierr = PetscViewerASCIIPrintf(viewer, "adjacency FEM\n");CHKERRQ(ierr);} 117034aa8a36SMatthew G. Knepley else {ierr = PetscViewerASCIIPrintf(viewer, "adjacency FUNKY\n");CHKERRQ(ierr);} 117134aa8a36SMatthew G. Knepley } 117234aa8a36SMatthew G. Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 117334aa8a36SMatthew G. Knepley } 117434aa8a36SMatthew G. Knepley } 1175a8fb8f29SToby Isaac ierr = DMGetCoarseDM(dm, &cdm);CHKERRQ(ierr); 11768e7ff633SMatthew G. Knepley if (cdm) { 11778e7ff633SMatthew G. Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 11788e7ff633SMatthew G. Knepley ierr = DMPlexView_Ascii(cdm, viewer);CHKERRQ(ierr); 11798e7ff633SMatthew G. Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 11808e7ff633SMatthew G. Knepley } 1181552f7358SJed Brown } 1182552f7358SJed Brown PetscFunctionReturn(0); 1183552f7358SJed Brown } 1184552f7358SJed Brown 11857cd05799SMatthew G. Knepley static PetscErrorCode DMPlexView_Draw(DM dm, PetscViewer viewer) 1186e412dcbdSMatthew G. Knepley { 1187e412dcbdSMatthew G. Knepley PetscDraw draw; 1188e412dcbdSMatthew G. Knepley DM cdm; 1189e412dcbdSMatthew G. Knepley PetscSection coordSection; 1190e412dcbdSMatthew G. Knepley Vec coordinates; 1191e412dcbdSMatthew G. Knepley const PetscScalar *coords; 119229494db1SLisandro Dalcin PetscReal xyl[2],xyr[2],bound[4] = {PETSC_MAX_REAL, PETSC_MAX_REAL, PETSC_MIN_REAL, PETSC_MIN_REAL}; 1193e412dcbdSMatthew G. Knepley PetscBool isnull; 1194e412dcbdSMatthew G. Knepley PetscInt dim, vStart, vEnd, cStart, cEnd, c, N; 1195cf3064d3SMatthew G. Knepley PetscMPIInt rank; 1196e412dcbdSMatthew G. Knepley PetscErrorCode ierr; 1197e412dcbdSMatthew G. Knepley 1198e412dcbdSMatthew G. Knepley PetscFunctionBegin; 1199e412dcbdSMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dim);CHKERRQ(ierr); 1200e412dcbdSMatthew G. Knepley if (dim != 2) SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Cannot draw meshes of dimension %D", dim); 1201e412dcbdSMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 120292fd8e1eSJed Brown ierr = DMGetLocalSection(cdm, &coordSection);CHKERRQ(ierr); 1203e412dcbdSMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 1204e412dcbdSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 1205e412dcbdSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 1206e412dcbdSMatthew G. Knepley 1207e412dcbdSMatthew G. Knepley ierr = PetscViewerDrawGetDraw(viewer, 0, &draw);CHKERRQ(ierr); 1208e412dcbdSMatthew G. Knepley ierr = PetscDrawIsNull(draw, &isnull);CHKERRQ(ierr); 1209e412dcbdSMatthew G. Knepley if (isnull) PetscFunctionReturn(0); 1210e412dcbdSMatthew G. Knepley ierr = PetscDrawSetTitle(draw, "Mesh");CHKERRQ(ierr); 1211e412dcbdSMatthew G. Knepley 1212e412dcbdSMatthew G. Knepley ierr = VecGetLocalSize(coordinates, &N);CHKERRQ(ierr); 1213e412dcbdSMatthew G. Knepley ierr = VecGetArrayRead(coordinates, &coords);CHKERRQ(ierr); 1214e412dcbdSMatthew G. Knepley for (c = 0; c < N; c += dim) { 12150c81f2a8SMatthew G. Knepley bound[0] = PetscMin(bound[0], PetscRealPart(coords[c])); bound[2] = PetscMax(bound[2], PetscRealPart(coords[c])); 12160c81f2a8SMatthew G. Knepley bound[1] = PetscMin(bound[1], PetscRealPart(coords[c+1])); bound[3] = PetscMax(bound[3], PetscRealPart(coords[c+1])); 1217e412dcbdSMatthew G. Knepley } 1218e412dcbdSMatthew G. Knepley ierr = VecRestoreArrayRead(coordinates, &coords);CHKERRQ(ierr); 121929494db1SLisandro Dalcin ierr = MPIU_Allreduce(&bound[0],xyl,2,MPIU_REAL,MPIU_MIN,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 122029494db1SLisandro Dalcin ierr = MPIU_Allreduce(&bound[2],xyr,2,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 122129494db1SLisandro Dalcin ierr = PetscDrawSetCoordinates(draw, xyl[0], xyl[1], xyr[0], xyr[1]);CHKERRQ(ierr); 1222e412dcbdSMatthew G. Knepley ierr = PetscDrawClear(draw);CHKERRQ(ierr); 1223e412dcbdSMatthew G. Knepley 1224cf3064d3SMatthew G. Knepley ierr = MPI_Comm_rank(PetscObjectComm((PetscObject) dm), &rank);CHKERRQ(ierr); 1225cf3064d3SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 1226cf3064d3SMatthew G. Knepley PetscScalar *coords = NULL; 1227cf3064d3SMatthew G. Knepley PetscInt numCoords,coneSize; 1228cf3064d3SMatthew G. Knepley 1229cf3064d3SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, c, &coneSize);CHKERRQ(ierr); 1230cf3064d3SMatthew G. Knepley ierr = DMPlexVecGetClosure(dm, coordSection, coordinates, c, &numCoords, &coords);CHKERRQ(ierr); 1231cf3064d3SMatthew G. Knepley switch (coneSize) { 1232cf3064d3SMatthew G. Knepley case 3: 1233cf3064d3SMatthew G. Knepley ierr = PetscDrawTriangle(draw, PetscRealPart(coords[0]), PetscRealPart(coords[1]), PetscRealPart(coords[2]), PetscRealPart(coords[3]), PetscRealPart(coords[4]), PetscRealPart(coords[5]), 1234cf3064d3SMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2, 1235cf3064d3SMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2, 1236cf3064d3SMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2);CHKERRQ(ierr); 1237cf3064d3SMatthew G. Knepley break; 1238cf3064d3SMatthew G. Knepley case 4: 1239a46c2b5aSMatthew G. Knepley ierr = PetscDrawTriangle(draw, PetscRealPart(coords[0]), PetscRealPart(coords[1]), PetscRealPart(coords[2]), PetscRealPart(coords[3]), PetscRealPart(coords[4]), PetscRealPart(coords[5]), 1240cf3064d3SMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2, 1241cf3064d3SMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2, 1242a46c2b5aSMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2);CHKERRQ(ierr); 1243a46c2b5aSMatthew G. Knepley ierr = PetscDrawTriangle(draw, PetscRealPart(coords[0]), PetscRealPart(coords[1]), PetscRealPart(coords[4]), PetscRealPart(coords[5]), PetscRealPart(coords[6]), PetscRealPart(coords[7]), 1244a46c2b5aSMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2, 1245cf3064d3SMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2, 1246cf3064d3SMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2);CHKERRQ(ierr); 1247cf3064d3SMatthew G. Knepley break; 1248cf3064d3SMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot draw cells with %D facets", coneSize); 1249cf3064d3SMatthew G. Knepley } 1250cf3064d3SMatthew G. Knepley ierr = DMPlexVecRestoreClosure(dm, coordSection, coordinates, c, &numCoords, &coords);CHKERRQ(ierr); 1251cf3064d3SMatthew G. Knepley } 1252e412dcbdSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 1253e412dcbdSMatthew G. Knepley PetscScalar *coords = NULL; 125429494db1SLisandro Dalcin PetscInt numCoords,coneSize; 1255e412dcbdSMatthew G. Knepley 125629494db1SLisandro Dalcin ierr = DMPlexGetConeSize(dm, c, &coneSize);CHKERRQ(ierr); 1257e412dcbdSMatthew G. Knepley ierr = DMPlexVecGetClosure(dm, coordSection, coordinates, c, &numCoords, &coords);CHKERRQ(ierr); 125829494db1SLisandro Dalcin switch (coneSize) { 125929494db1SLisandro Dalcin case 3: 12600c81f2a8SMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[0]), PetscRealPart(coords[1]), PetscRealPart(coords[2]), PetscRealPart(coords[3]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 12610c81f2a8SMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[2]), PetscRealPart(coords[3]), PetscRealPart(coords[4]), PetscRealPart(coords[5]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 12620c81f2a8SMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[4]), PetscRealPart(coords[5]), PetscRealPart(coords[0]), PetscRealPart(coords[1]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 1263e412dcbdSMatthew G. Knepley break; 126429494db1SLisandro Dalcin case 4: 12650c81f2a8SMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[0]), PetscRealPart(coords[1]), PetscRealPart(coords[2]), PetscRealPart(coords[3]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 12660c81f2a8SMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[2]), PetscRealPart(coords[3]), PetscRealPart(coords[4]), PetscRealPart(coords[5]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 12670c81f2a8SMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[4]), PetscRealPart(coords[5]), PetscRealPart(coords[6]), PetscRealPart(coords[7]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 12680c81f2a8SMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[6]), PetscRealPart(coords[7]), PetscRealPart(coords[0]), PetscRealPart(coords[1]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 1269e412dcbdSMatthew G. Knepley break; 127029494db1SLisandro Dalcin default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot draw cells with %D facets", coneSize); 1271e412dcbdSMatthew G. Knepley } 1272e412dcbdSMatthew G. Knepley ierr = DMPlexVecRestoreClosure(dm, coordSection, coordinates, c, &numCoords, &coords);CHKERRQ(ierr); 1273e412dcbdSMatthew G. Knepley } 1274e412dcbdSMatthew G. Knepley ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 1275e412dcbdSMatthew G. Knepley ierr = PetscDrawPause(draw);CHKERRQ(ierr); 1276e412dcbdSMatthew G. Knepley ierr = PetscDrawSave(draw);CHKERRQ(ierr); 1277e412dcbdSMatthew G. Knepley PetscFunctionReturn(0); 1278e412dcbdSMatthew G. Knepley } 1279e412dcbdSMatthew G. Knepley 1280552f7358SJed Brown PetscErrorCode DMView_Plex(DM dm, PetscViewer viewer) 1281552f7358SJed Brown { 1282e655db49SSatish Balay PetscBool iascii, ishdf5, isvtk, isdraw, flg, isglvis; 1283002a2709SMatthew G. Knepley char name[PETSC_MAX_PATH_LEN]; 1284552f7358SJed Brown PetscErrorCode ierr; 1285552f7358SJed Brown 1286552f7358SJed Brown PetscFunctionBegin; 1287552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1288552f7358SJed Brown PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1289552f7358SJed Brown ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 1290fcf6c8fdSToby Isaac ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERVTK, &isvtk);CHKERRQ(ierr); 1291c6ccd67eSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 1292e412dcbdSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERDRAW, &isdraw);CHKERRQ(ierr); 12938135c375SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERGLVIS, &isglvis);CHKERRQ(ierr); 1294552f7358SJed Brown if (iascii) { 12958135c375SStefano Zampini PetscViewerFormat format; 12968135c375SStefano Zampini ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 12978135c375SStefano Zampini if (format == PETSC_VIEWER_ASCII_GLVIS) { 12988135c375SStefano Zampini ierr = DMPlexView_GLVis(dm, viewer);CHKERRQ(ierr); 12998135c375SStefano Zampini } else { 1300552f7358SJed Brown ierr = DMPlexView_Ascii(dm, viewer);CHKERRQ(ierr); 13018135c375SStefano Zampini } 1302c6ccd67eSMatthew G. Knepley } else if (ishdf5) { 1303c6ccd67eSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 130439d25373SMatthew G. Knepley ierr = DMPlexView_HDF5_Internal(dm, viewer);CHKERRQ(ierr); 1305c6ccd67eSMatthew G. Knepley #else 1306c6ccd67eSMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 1307552f7358SJed Brown #endif 1308e412dcbdSMatthew G. Knepley } else if (isvtk) { 1309fcf6c8fdSToby Isaac ierr = DMPlexVTKWriteAll((PetscObject) dm,viewer);CHKERRQ(ierr); 1310e412dcbdSMatthew G. Knepley } else if (isdraw) { 1311e412dcbdSMatthew G. Knepley ierr = DMPlexView_Draw(dm, viewer);CHKERRQ(ierr); 13128135c375SStefano Zampini } else if (isglvis) { 13138135c375SStefano Zampini ierr = DMPlexView_GLVis(dm, viewer);CHKERRQ(ierr); 131462201deeSVaclav Hapla } else { 1315a94aea51SVaclav Hapla SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Viewer type %s not yet supported for DMPlex writing", ((PetscObject)viewer)->type_name); 1316fcf6c8fdSToby Isaac } 1317cb3ba0daSMatthew G. Knepley /* Optionally view the partition */ 1318cb3ba0daSMatthew G. Knepley ierr = PetscOptionsHasName(((PetscObject) dm)->options, ((PetscObject) dm)->prefix, "-dm_partition_view", &flg);CHKERRQ(ierr); 1319cb3ba0daSMatthew G. Knepley if (flg) { 1320cb3ba0daSMatthew G. Knepley Vec ranks; 1321cb3ba0daSMatthew G. Knepley ierr = DMPlexCreateRankField(dm, &ranks);CHKERRQ(ierr); 1322cb3ba0daSMatthew G. Knepley ierr = VecView(ranks, viewer);CHKERRQ(ierr); 1323cb3ba0daSMatthew G. Knepley ierr = VecDestroy(&ranks);CHKERRQ(ierr); 1324cb3ba0daSMatthew G. Knepley } 1325002a2709SMatthew G. Knepley /* Optionally view a label */ 1326002a2709SMatthew G. Knepley ierr = PetscOptionsGetString(((PetscObject) dm)->options, ((PetscObject) dm)->prefix, "-dm_label_view", name, PETSC_MAX_PATH_LEN, &flg);CHKERRQ(ierr); 1327002a2709SMatthew G. Knepley if (flg) { 1328002a2709SMatthew G. Knepley DMLabel label; 1329002a2709SMatthew G. Knepley Vec val; 1330002a2709SMatthew G. Knepley 1331002a2709SMatthew G. Knepley ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 1332002a2709SMatthew 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); 1333002a2709SMatthew G. Knepley ierr = DMPlexCreateLabelField(dm, label, &val);CHKERRQ(ierr); 1334002a2709SMatthew G. Knepley ierr = VecView(val, viewer);CHKERRQ(ierr); 1335002a2709SMatthew G. Knepley ierr = VecDestroy(&val);CHKERRQ(ierr); 1336002a2709SMatthew G. Knepley } 1337552f7358SJed Brown PetscFunctionReturn(0); 1338552f7358SJed Brown } 1339552f7358SJed Brown 13402c40f234SMatthew G. Knepley PetscErrorCode DMLoad_Plex(DM dm, PetscViewer viewer) 13412c40f234SMatthew G. Knepley { 1342d4f5a9a0SVaclav Hapla PetscBool ishdf5; 13432c40f234SMatthew G. Knepley PetscErrorCode ierr; 13442c40f234SMatthew G. Knepley 13452c40f234SMatthew G. Knepley PetscFunctionBegin; 13462c40f234SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 13472c40f234SMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 13482c40f234SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 1349d4f5a9a0SVaclav Hapla if (ishdf5) { 13502c40f234SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 13519c48423bSVaclav Hapla PetscViewerFormat format; 13529c48423bSVaclav Hapla ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 13539c48423bSVaclav Hapla if (format == PETSC_VIEWER_HDF5_XDMF || format == PETSC_VIEWER_HDF5_VIZ) { 13549c48423bSVaclav Hapla ierr = DMPlexLoad_HDF5_Xdmf_Internal(dm, viewer);CHKERRQ(ierr); 1355509517efSVaclav Hapla } else if (format == PETSC_VIEWER_HDF5_PETSC || format == PETSC_VIEWER_DEFAULT || format == PETSC_VIEWER_NATIVE) { 135639d25373SMatthew G. Knepley ierr = DMPlexLoad_HDF5_Internal(dm, viewer);CHKERRQ(ierr); 1357509517efSVaclav Hapla } else SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "PetscViewerFormat %s not supported for HDF5 input.", PetscViewerFormats[format]); 13582c40f234SMatthew G. Knepley #else 13592c40f234SMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 1360552f7358SJed Brown #endif 1361d4f5a9a0SVaclav Hapla } else { 1362d4f5a9a0SVaclav Hapla SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Viewer type %s not yet supported for DMPlex loading", ((PetscObject)viewer)->type_name); 1363552f7358SJed Brown } 1364552f7358SJed Brown PetscFunctionReturn(0); 1365552f7358SJed Brown } 1366552f7358SJed Brown 1367552f7358SJed Brown PetscErrorCode DMDestroy_Plex(DM dm) 1368552f7358SJed Brown { 1369552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1370552f7358SJed Brown PetscErrorCode ierr; 1371552f7358SJed Brown 1372552f7358SJed Brown PetscFunctionBegin; 13738135c375SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)dm,"DMSetUpGLVisViewer_C",NULL);CHKERRQ(ierr); 13748135c375SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)dm,"DMPlexInsertBoundaryValues_C", NULL);CHKERRQ(ierr); 137528d58a37SPierre Jolivet ierr = PetscObjectComposeFunction((PetscObject)dm,"DMCreateNeumannOverlap_C", NULL);CHKERRQ(ierr); 13760d644c17SKarl Rupp if (--mesh->refct > 0) PetscFunctionReturn(0); 1377552f7358SJed Brown ierr = PetscSectionDestroy(&mesh->coneSection);CHKERRQ(ierr); 1378552f7358SJed Brown ierr = PetscFree(mesh->cones);CHKERRQ(ierr); 1379552f7358SJed Brown ierr = PetscFree(mesh->coneOrientations);CHKERRQ(ierr); 1380552f7358SJed Brown ierr = PetscSectionDestroy(&mesh->supportSection);CHKERRQ(ierr); 1381be36d101SStefano Zampini ierr = PetscSectionDestroy(&mesh->subdomainSection);CHKERRQ(ierr); 1382552f7358SJed Brown ierr = PetscFree(mesh->supports);CHKERRQ(ierr); 1383552f7358SJed Brown ierr = PetscFree(mesh->facesTmp);CHKERRQ(ierr); 1384d9deefdfSMatthew G. Knepley ierr = PetscFree(mesh->tetgenOpts);CHKERRQ(ierr); 1385d9deefdfSMatthew G. Knepley ierr = PetscFree(mesh->triangleOpts);CHKERRQ(ierr); 138677623264SMatthew G. Knepley ierr = PetscPartitionerDestroy(&mesh->partitioner);CHKERRQ(ierr); 1387a89082eeSMatthew G Knepley ierr = DMLabelDestroy(&mesh->subpointMap);CHKERRQ(ierr); 1388552f7358SJed Brown ierr = ISDestroy(&mesh->globalVertexNumbers);CHKERRQ(ierr); 1389552f7358SJed Brown ierr = ISDestroy(&mesh->globalCellNumbers);CHKERRQ(ierr); 1390a68b90caSToby Isaac ierr = PetscSectionDestroy(&mesh->anchorSection);CHKERRQ(ierr); 1391a68b90caSToby Isaac ierr = ISDestroy(&mesh->anchorIS);CHKERRQ(ierr); 1392d961a43aSToby Isaac ierr = PetscSectionDestroy(&mesh->parentSection);CHKERRQ(ierr); 1393d961a43aSToby Isaac ierr = PetscFree(mesh->parents);CHKERRQ(ierr); 1394d961a43aSToby Isaac ierr = PetscFree(mesh->childIDs);CHKERRQ(ierr); 1395d961a43aSToby Isaac ierr = PetscSectionDestroy(&mesh->childSection);CHKERRQ(ierr); 1396d961a43aSToby Isaac ierr = PetscFree(mesh->children);CHKERRQ(ierr); 1397d6a7ad0dSToby Isaac ierr = DMDestroy(&mesh->referenceTree);CHKERRQ(ierr); 1398fec49543SMatthew G. Knepley ierr = PetscGridHashDestroy(&mesh->lbox);CHKERRQ(ierr); 1399552f7358SJed Brown /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */ 1400552f7358SJed Brown ierr = PetscFree(mesh);CHKERRQ(ierr); 1401552f7358SJed Brown PetscFunctionReturn(0); 1402552f7358SJed Brown } 1403552f7358SJed Brown 1404b412c318SBarry Smith PetscErrorCode DMCreateMatrix_Plex(DM dm, Mat *J) 1405552f7358SJed Brown { 14068d1174e4SMatthew G. Knepley PetscSection sectionGlobal; 1407acd755d7SMatthew G. Knepley PetscInt bs = -1, mbs; 1408552f7358SJed Brown PetscInt localSize; 1409837628f4SStefano Zampini PetscBool isShell, isBlock, isSeqBlock, isMPIBlock, isSymBlock, isSymSeqBlock, isSymMPIBlock, isMatIS; 1410552f7358SJed Brown PetscErrorCode ierr; 1411b412c318SBarry Smith MatType mtype; 14121428887cSShri Abhyankar ISLocalToGlobalMapping ltog; 1413552f7358SJed Brown 1414552f7358SJed Brown PetscFunctionBegin; 1415607a6623SBarry Smith ierr = MatInitializePackage();CHKERRQ(ierr); 1416b412c318SBarry Smith mtype = dm->mattype; 1417e87a4003SBarry Smith ierr = DMGetGlobalSection(dm, §ionGlobal);CHKERRQ(ierr); 1418552f7358SJed Brown /* ierr = PetscSectionGetStorageSize(sectionGlobal, &localSize);CHKERRQ(ierr); */ 1419552f7358SJed Brown ierr = PetscSectionGetConstrainedStorageSize(sectionGlobal, &localSize);CHKERRQ(ierr); 142082f516ccSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)dm), J);CHKERRQ(ierr); 1421552f7358SJed Brown ierr = MatSetSizes(*J, localSize, localSize, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 1422552f7358SJed Brown ierr = MatSetType(*J, mtype);CHKERRQ(ierr); 1423552f7358SJed Brown ierr = MatSetFromOptions(*J);CHKERRQ(ierr); 1424acd755d7SMatthew G. Knepley ierr = MatGetBlockSize(*J, &mbs);CHKERRQ(ierr); 1425acd755d7SMatthew G. Knepley if (mbs > 1) bs = mbs; 1426552f7358SJed Brown ierr = PetscStrcmp(mtype, MATSHELL, &isShell);CHKERRQ(ierr); 1427552f7358SJed Brown ierr = PetscStrcmp(mtype, MATBAIJ, &isBlock);CHKERRQ(ierr); 1428552f7358SJed Brown ierr = PetscStrcmp(mtype, MATSEQBAIJ, &isSeqBlock);CHKERRQ(ierr); 1429552f7358SJed Brown ierr = PetscStrcmp(mtype, MATMPIBAIJ, &isMPIBlock);CHKERRQ(ierr); 1430552f7358SJed Brown ierr = PetscStrcmp(mtype, MATSBAIJ, &isSymBlock);CHKERRQ(ierr); 1431552f7358SJed Brown ierr = PetscStrcmp(mtype, MATSEQSBAIJ, &isSymSeqBlock);CHKERRQ(ierr); 1432552f7358SJed Brown ierr = PetscStrcmp(mtype, MATMPISBAIJ, &isSymMPIBlock);CHKERRQ(ierr); 1433837628f4SStefano Zampini ierr = PetscStrcmp(mtype, MATIS, &isMatIS);CHKERRQ(ierr); 1434552f7358SJed Brown if (!isShell) { 1435be36d101SStefano Zampini PetscSection subSection; 1436837628f4SStefano Zampini PetscBool fillMatrix = (PetscBool)(!dm->prealloc_only && !isMatIS); 14370be3e97aSMatthew G. Knepley PetscInt *dnz, *onz, *dnzu, *onzu, bsLocal[2], bsMinMax[2], *ltogidx, lsize; 1438fad22124SMatthew G Knepley PetscInt pStart, pEnd, p, dof, cdof; 1439552f7358SJed Brown 144000140cc3SStefano Zampini /* Set localtoglobalmapping on the matrix for MatSetValuesLocal() to work (it also creates the local matrices in case of MATIS) */ 1441be36d101SStefano Zampini if (isMatIS) { /* need a different l2g map than the one computed by DMGetLocalToGlobalMapping */ 1442be36d101SStefano Zampini PetscSection section; 1443be36d101SStefano Zampini PetscInt size; 1444be36d101SStefano Zampini 144592fd8e1eSJed Brown ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr); 1446be36d101SStefano Zampini ierr = PetscSectionGetStorageSize(section, &size);CHKERRQ(ierr); 1447be36d101SStefano Zampini ierr = PetscMalloc1(size,<ogidx);CHKERRQ(ierr); 1448be36d101SStefano Zampini ierr = DMPlexGetSubdomainSection(dm, &subSection);CHKERRQ(ierr); 1449be36d101SStefano Zampini } else { 145000140cc3SStefano Zampini ierr = DMGetLocalToGlobalMapping(dm,<og);CHKERRQ(ierr); 1451be36d101SStefano Zampini } 1452552f7358SJed Brown ierr = PetscSectionGetChart(sectionGlobal, &pStart, &pEnd);CHKERRQ(ierr); 1453be36d101SStefano Zampini for (p = pStart, lsize = 0; p < pEnd; ++p) { 1454a9d99c84SMatthew G. Knepley PetscInt bdof; 1455a9d99c84SMatthew G. Knepley 1456552f7358SJed Brown ierr = PetscSectionGetDof(sectionGlobal, p, &dof);CHKERRQ(ierr); 1457fad22124SMatthew G Knepley ierr = PetscSectionGetConstraintDof(sectionGlobal, p, &cdof);CHKERRQ(ierr); 14581d17a0a3SMatthew G. Knepley dof = dof < 0 ? -(dof+1) : dof; 14591d17a0a3SMatthew G. Knepley bdof = cdof && (dof-cdof) ? 1 : dof; 14601d17a0a3SMatthew G. Knepley if (dof) { 14611d17a0a3SMatthew G. Knepley if (bs < 0) {bs = bdof;} 1462be36d101SStefano Zampini else if (bs != bdof) {bs = 1; if (!isMatIS) break;} 1463be36d101SStefano Zampini } 1464be36d101SStefano Zampini if (isMatIS) { 1465be36d101SStefano Zampini PetscInt loff,c,off; 1466be36d101SStefano Zampini ierr = PetscSectionGetOffset(subSection, p, &loff);CHKERRQ(ierr); 1467be36d101SStefano Zampini ierr = PetscSectionGetOffset(sectionGlobal, p, &off);CHKERRQ(ierr); 1468be36d101SStefano Zampini for (c = 0; c < dof-cdof; ++c, ++lsize) ltogidx[loff+c] = off > -1 ? off+c : -(off+1)+c; 1469552f7358SJed Brown } 14702a28c762SMatthew G Knepley } 14712a28c762SMatthew G Knepley /* Must have same blocksize on all procs (some might have no points) */ 14720be3e97aSMatthew G. Knepley bsLocal[0] = bs < 0 ? PETSC_MAX_INT : bs; bsLocal[1] = bs; 14730be3e97aSMatthew G. Knepley ierr = PetscGlobalMinMaxInt(PetscObjectComm((PetscObject) dm), bsLocal, bsMinMax);CHKERRQ(ierr); 14740be3e97aSMatthew G. Knepley if (bsMinMax[0] != bsMinMax[1]) {bs = 1;} 14750be3e97aSMatthew G. Knepley else {bs = bsMinMax[0];} 14766fd5c86aSStefano Zampini bs = PetscMax(1,bs); 14776fd5c86aSStefano Zampini if (isMatIS) { /* Must reduce indices by blocksize */ 14784fa26246SMatthew G. Knepley PetscInt l; 14796fd5c86aSStefano Zampini 14806fd5c86aSStefano Zampini lsize = lsize/bs; 14816fd5c86aSStefano Zampini if (bs > 1) for (l = 0; l < lsize; ++l) ltogidx[l] = ltogidx[l*bs]/bs; 14824fa26246SMatthew G. Knepley ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)dm), bs, lsize, ltogidx, PETSC_OWN_POINTER, <og);CHKERRQ(ierr); 1483be36d101SStefano Zampini } 1484be36d101SStefano Zampini ierr = MatSetLocalToGlobalMapping(*J,ltog,ltog);CHKERRQ(ierr); 1485be36d101SStefano Zampini if (isMatIS) { 1486be36d101SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(<og);CHKERRQ(ierr); 1487be36d101SStefano Zampini } 14881795a4d1SJed Brown ierr = PetscCalloc4(localSize/bs, &dnz, localSize/bs, &onz, localSize/bs, &dnzu, localSize/bs, &onzu);CHKERRQ(ierr); 14898d1174e4SMatthew G. Knepley ierr = DMPlexPreallocateOperator(dm, bs, dnz, onz, dnzu, onzu, *J, fillMatrix);CHKERRQ(ierr); 1490552f7358SJed Brown ierr = PetscFree4(dnz, onz, dnzu, onzu);CHKERRQ(ierr); 1491552f7358SJed Brown } 1492b1f74addSMatthew G. Knepley ierr = MatSetDM(*J, dm);CHKERRQ(ierr); 1493552f7358SJed Brown PetscFunctionReturn(0); 1494552f7358SJed Brown } 1495552f7358SJed Brown 14967cd05799SMatthew G. Knepley /*@ 1497a8f00d21SMatthew G. Knepley DMPlexGetSubdomainSection - Returns the section associated with the subdomain 1498be36d101SStefano Zampini 1499be36d101SStefano Zampini Not collective 1500be36d101SStefano Zampini 1501be36d101SStefano Zampini Input Parameter: 1502be36d101SStefano Zampini . mesh - The DMPlex 1503be36d101SStefano Zampini 1504be36d101SStefano Zampini Output Parameters: 1505be36d101SStefano Zampini . subsection - The subdomain section 1506be36d101SStefano Zampini 1507be36d101SStefano Zampini Level: developer 1508be36d101SStefano Zampini 1509be36d101SStefano Zampini .seealso: 15107cd05799SMatthew G. Knepley @*/ 1511be36d101SStefano Zampini PetscErrorCode DMPlexGetSubdomainSection(DM dm, PetscSection *subsection) 1512be36d101SStefano Zampini { 1513be36d101SStefano Zampini DM_Plex *mesh = (DM_Plex*) dm->data; 1514be36d101SStefano Zampini PetscErrorCode ierr; 1515be36d101SStefano Zampini 1516be36d101SStefano Zampini PetscFunctionBegin; 1517be36d101SStefano Zampini PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1518be36d101SStefano Zampini if (!mesh->subdomainSection) { 1519be36d101SStefano Zampini PetscSection section; 1520be36d101SStefano Zampini PetscSF sf; 1521be36d101SStefano Zampini 1522be36d101SStefano Zampini ierr = PetscSFCreate(PETSC_COMM_SELF,&sf);CHKERRQ(ierr); 152392fd8e1eSJed Brown ierr = DMGetLocalSection(dm,§ion);CHKERRQ(ierr); 1524be36d101SStefano Zampini ierr = PetscSectionCreateGlobalSection(section,sf,PETSC_FALSE,PETSC_TRUE,&mesh->subdomainSection);CHKERRQ(ierr); 1525be36d101SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 1526be36d101SStefano Zampini } 1527be36d101SStefano Zampini *subsection = mesh->subdomainSection; 1528be36d101SStefano Zampini PetscFunctionReturn(0); 1529be36d101SStefano Zampini } 1530be36d101SStefano Zampini 1531552f7358SJed Brown /*@ 1532552f7358SJed Brown DMPlexGetChart - Return the interval for all mesh points [pStart, pEnd) 1533552f7358SJed Brown 1534552f7358SJed Brown Not collective 1535552f7358SJed Brown 1536552f7358SJed Brown Input Parameter: 1537552f7358SJed Brown . mesh - The DMPlex 1538552f7358SJed Brown 1539552f7358SJed Brown Output Parameters: 1540552f7358SJed Brown + pStart - The first mesh point 1541552f7358SJed Brown - pEnd - The upper bound for mesh points 1542552f7358SJed Brown 1543552f7358SJed Brown Level: beginner 1544552f7358SJed Brown 1545552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetChart() 1546552f7358SJed Brown @*/ 1547552f7358SJed Brown PetscErrorCode DMPlexGetChart(DM dm, PetscInt *pStart, PetscInt *pEnd) 1548552f7358SJed Brown { 1549552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1550552f7358SJed Brown PetscErrorCode ierr; 1551552f7358SJed Brown 1552552f7358SJed Brown PetscFunctionBegin; 1553552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1554552f7358SJed Brown ierr = PetscSectionGetChart(mesh->coneSection, pStart, pEnd);CHKERRQ(ierr); 1555552f7358SJed Brown PetscFunctionReturn(0); 1556552f7358SJed Brown } 1557552f7358SJed Brown 1558552f7358SJed Brown /*@ 1559552f7358SJed Brown DMPlexSetChart - Set the interval for all mesh points [pStart, pEnd) 1560552f7358SJed Brown 1561552f7358SJed Brown Not collective 1562552f7358SJed Brown 1563552f7358SJed Brown Input Parameters: 1564552f7358SJed Brown + mesh - The DMPlex 1565552f7358SJed Brown . pStart - The first mesh point 1566552f7358SJed Brown - pEnd - The upper bound for mesh points 1567552f7358SJed Brown 1568552f7358SJed Brown Output Parameters: 1569552f7358SJed Brown 1570552f7358SJed Brown Level: beginner 1571552f7358SJed Brown 1572552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetChart() 1573552f7358SJed Brown @*/ 1574552f7358SJed Brown PetscErrorCode DMPlexSetChart(DM dm, PetscInt pStart, PetscInt pEnd) 1575552f7358SJed Brown { 1576552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1577552f7358SJed Brown PetscErrorCode ierr; 1578552f7358SJed Brown 1579552f7358SJed Brown PetscFunctionBegin; 1580552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1581552f7358SJed Brown ierr = PetscSectionSetChart(mesh->coneSection, pStart, pEnd);CHKERRQ(ierr); 1582552f7358SJed Brown ierr = PetscSectionSetChart(mesh->supportSection, pStart, pEnd);CHKERRQ(ierr); 1583552f7358SJed Brown PetscFunctionReturn(0); 1584552f7358SJed Brown } 1585552f7358SJed Brown 1586552f7358SJed Brown /*@ 1587eaf898f9SPatrick Sanan DMPlexGetConeSize - Return the number of in-edges for this point in the DAG 1588552f7358SJed Brown 1589552f7358SJed Brown Not collective 1590552f7358SJed Brown 1591552f7358SJed Brown Input Parameters: 1592552f7358SJed Brown + mesh - The DMPlex 1593eaf898f9SPatrick Sanan - p - The point, which must lie in the chart set with DMPlexSetChart() 1594552f7358SJed Brown 1595552f7358SJed Brown Output Parameter: 1596552f7358SJed Brown . size - The cone size for point p 1597552f7358SJed Brown 1598552f7358SJed Brown Level: beginner 1599552f7358SJed Brown 1600552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetConeSize(), DMPlexSetChart() 1601552f7358SJed Brown @*/ 1602552f7358SJed Brown PetscErrorCode DMPlexGetConeSize(DM dm, PetscInt p, PetscInt *size) 1603552f7358SJed Brown { 1604552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1605552f7358SJed Brown PetscErrorCode ierr; 1606552f7358SJed Brown 1607552f7358SJed Brown PetscFunctionBegin; 1608552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1609552f7358SJed Brown PetscValidPointer(size, 3); 1610552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, size);CHKERRQ(ierr); 1611552f7358SJed Brown PetscFunctionReturn(0); 1612552f7358SJed Brown } 1613552f7358SJed Brown 1614552f7358SJed Brown /*@ 1615eaf898f9SPatrick Sanan DMPlexSetConeSize - Set the number of in-edges for this point in the DAG 1616552f7358SJed Brown 1617552f7358SJed Brown Not collective 1618552f7358SJed Brown 1619552f7358SJed Brown Input Parameters: 1620552f7358SJed Brown + mesh - The DMPlex 1621eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 1622552f7358SJed Brown - size - The cone size for point p 1623552f7358SJed Brown 1624552f7358SJed Brown Output Parameter: 1625552f7358SJed Brown 1626552f7358SJed Brown Note: 1627552f7358SJed Brown This should be called after DMPlexSetChart(). 1628552f7358SJed Brown 1629552f7358SJed Brown Level: beginner 1630552f7358SJed Brown 1631552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetConeSize(), DMPlexSetChart() 1632552f7358SJed Brown @*/ 1633552f7358SJed Brown PetscErrorCode DMPlexSetConeSize(DM dm, PetscInt p, PetscInt size) 1634552f7358SJed Brown { 1635552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1636552f7358SJed Brown PetscErrorCode ierr; 1637552f7358SJed Brown 1638552f7358SJed Brown PetscFunctionBegin; 1639552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1640552f7358SJed Brown ierr = PetscSectionSetDof(mesh->coneSection, p, size);CHKERRQ(ierr); 16410d644c17SKarl Rupp 1642552f7358SJed Brown mesh->maxConeSize = PetscMax(mesh->maxConeSize, size); 1643552f7358SJed Brown PetscFunctionReturn(0); 1644552f7358SJed Brown } 1645552f7358SJed Brown 1646f5a469b9SMatthew G. Knepley /*@ 1647eaf898f9SPatrick Sanan DMPlexAddConeSize - Add the given number of in-edges to this point in the DAG 1648f5a469b9SMatthew G. Knepley 1649f5a469b9SMatthew G. Knepley Not collective 1650f5a469b9SMatthew G. Knepley 1651f5a469b9SMatthew G. Knepley Input Parameters: 1652f5a469b9SMatthew G. Knepley + mesh - The DMPlex 1653eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 1654f5a469b9SMatthew G. Knepley - size - The additional cone size for point p 1655f5a469b9SMatthew G. Knepley 1656f5a469b9SMatthew G. Knepley Output Parameter: 1657f5a469b9SMatthew G. Knepley 1658f5a469b9SMatthew G. Knepley Note: 1659f5a469b9SMatthew G. Knepley This should be called after DMPlexSetChart(). 1660f5a469b9SMatthew G. Knepley 1661f5a469b9SMatthew G. Knepley Level: beginner 1662f5a469b9SMatthew G. Knepley 1663f5a469b9SMatthew G. Knepley .seealso: DMPlexCreate(), DMPlexSetConeSize(), DMPlexGetConeSize(), DMPlexSetChart() 1664f5a469b9SMatthew G. Knepley @*/ 1665f5a469b9SMatthew G. Knepley PetscErrorCode DMPlexAddConeSize(DM dm, PetscInt p, PetscInt size) 1666f5a469b9SMatthew G. Knepley { 1667f5a469b9SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 1668f5a469b9SMatthew G. Knepley PetscInt csize; 1669f5a469b9SMatthew G. Knepley PetscErrorCode ierr; 1670f5a469b9SMatthew G. Knepley 1671f5a469b9SMatthew G. Knepley PetscFunctionBegin; 1672f5a469b9SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1673f5a469b9SMatthew G. Knepley ierr = PetscSectionAddDof(mesh->coneSection, p, size);CHKERRQ(ierr); 1674f5a469b9SMatthew G. Knepley ierr = PetscSectionGetDof(mesh->coneSection, p, &csize);CHKERRQ(ierr); 1675f5a469b9SMatthew G. Knepley 1676f5a469b9SMatthew G. Knepley mesh->maxConeSize = PetscMax(mesh->maxConeSize, csize); 1677f5a469b9SMatthew G. Knepley PetscFunctionReturn(0); 1678f5a469b9SMatthew G. Knepley } 1679f5a469b9SMatthew G. Knepley 1680552f7358SJed Brown /*@C 1681eaf898f9SPatrick Sanan DMPlexGetCone - Return the points on the in-edges for this point in the DAG 1682552f7358SJed Brown 1683552f7358SJed Brown Not collective 1684552f7358SJed Brown 1685552f7358SJed Brown Input Parameters: 1686833c876bSVaclav Hapla + dm - The DMPlex 1687eaf898f9SPatrick Sanan - p - The point, which must lie in the chart set with DMPlexSetChart() 1688552f7358SJed Brown 1689552f7358SJed Brown Output Parameter: 1690552f7358SJed Brown . cone - An array of points which are on the in-edges for point p 1691552f7358SJed Brown 1692552f7358SJed Brown Level: beginner 1693552f7358SJed Brown 16943813dfbdSMatthew G Knepley Fortran Notes: 16953813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 16963813dfbdSMatthew G Knepley include petsc.h90 in your code. 1697922102d1SVaclav Hapla You must also call DMPlexRestoreCone() after you finish using the returned array. 1698922102d1SVaclav Hapla DMPlexRestoreCone() is not needed/available in C. 16993813dfbdSMatthew G Knepley 17000ce7577fSVaclav Hapla .seealso: DMPlexCreate(), DMPlexSetCone(), DMPlexGetConeTuple(), DMPlexSetChart() 1701552f7358SJed Brown @*/ 1702552f7358SJed Brown PetscErrorCode DMPlexGetCone(DM dm, PetscInt p, const PetscInt *cone[]) 1703552f7358SJed Brown { 1704552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1705552f7358SJed Brown PetscInt off; 1706552f7358SJed Brown PetscErrorCode ierr; 1707552f7358SJed Brown 1708552f7358SJed Brown PetscFunctionBegin; 1709552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1710552f7358SJed Brown PetscValidPointer(cone, 3); 1711552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 1712552f7358SJed Brown *cone = &mesh->cones[off]; 1713552f7358SJed Brown PetscFunctionReturn(0); 1714552f7358SJed Brown } 1715552f7358SJed Brown 17160ce7577fSVaclav Hapla /*@C 17170ce7577fSVaclav Hapla DMPlexGetConeTuple - Return the points on the in-edges of several points in the DAG 17180ce7577fSVaclav Hapla 17190ce7577fSVaclav Hapla Not collective 17200ce7577fSVaclav Hapla 17210ce7577fSVaclav Hapla Input Parameters: 17220ce7577fSVaclav Hapla + dm - The DMPlex 17230ce7577fSVaclav Hapla - p - The IS of points, which must lie in the chart set with DMPlexSetChart() 17240ce7577fSVaclav Hapla 17250ce7577fSVaclav Hapla Output Parameter: 17260ce7577fSVaclav Hapla + pConesSection - PetscSection describing the layout of pCones 17270ce7577fSVaclav Hapla - pCones - An array of points which are on the in-edges for the point set p 17280ce7577fSVaclav Hapla 17290ce7577fSVaclav Hapla Level: intermediate 17300ce7577fSVaclav Hapla 1731d4636a37SVaclav Hapla .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexGetConeRecursive(), DMPlexSetChart() 17320ce7577fSVaclav Hapla @*/ 17330ce7577fSVaclav Hapla PetscErrorCode DMPlexGetConeTuple(DM dm, IS p, PetscSection *pConesSection, IS *pCones) 17340ce7577fSVaclav Hapla { 17350ce7577fSVaclav Hapla PetscSection cs, newcs; 17360ce7577fSVaclav Hapla PetscInt *cones; 17370ce7577fSVaclav Hapla PetscInt *newarr=NULL; 17380ce7577fSVaclav Hapla PetscInt n; 17390ce7577fSVaclav Hapla PetscErrorCode ierr; 17400ce7577fSVaclav Hapla 17410ce7577fSVaclav Hapla PetscFunctionBegin; 17420ce7577fSVaclav Hapla ierr = DMPlexGetCones(dm, &cones);CHKERRQ(ierr); 17430ce7577fSVaclav Hapla ierr = DMPlexGetConeSection(dm, &cs);CHKERRQ(ierr); 17440ce7577fSVaclav Hapla ierr = PetscSectionExtractDofsFromArray(cs, MPIU_INT, cones, p, &newcs, pCones ? ((void**)&newarr) : NULL);CHKERRQ(ierr); 17450ce7577fSVaclav Hapla if (pConesSection) *pConesSection = newcs; 17460ce7577fSVaclav Hapla if (pCones) { 17470ce7577fSVaclav Hapla ierr = PetscSectionGetStorageSize(newcs, &n);CHKERRQ(ierr); 17480ce7577fSVaclav Hapla ierr = ISCreateGeneral(PetscObjectComm((PetscObject)p), n, newarr, PETSC_OWN_POINTER, pCones);CHKERRQ(ierr); 17490ce7577fSVaclav Hapla } 17500ce7577fSVaclav Hapla PetscFunctionReturn(0); 17510ce7577fSVaclav Hapla } 17520ce7577fSVaclav Hapla 1753af9eab45SVaclav Hapla /*@ 1754af9eab45SVaclav Hapla DMPlexGetConeRecursiveVertices - Expand each given point into its cone points and do that recursively until we end up just with vertices. 1755d4636a37SVaclav Hapla 1756d4636a37SVaclav Hapla Not collective 1757d4636a37SVaclav Hapla 1758d4636a37SVaclav Hapla Input Parameters: 1759d4636a37SVaclav Hapla + dm - The DMPlex 1760af9eab45SVaclav Hapla - points - The IS of points, which must lie in the chart set with DMPlexSetChart() 1761d4636a37SVaclav Hapla 1762d4636a37SVaclav Hapla Output Parameter: 1763af9eab45SVaclav Hapla . expandedPoints - An array of vertices recursively expanded from input points 1764d4636a37SVaclav Hapla 1765d4636a37SVaclav Hapla Level: advanced 1766d4636a37SVaclav Hapla 1767af9eab45SVaclav Hapla Notes: 1768af9eab45SVaclav Hapla Like DMPlexGetConeRecursive but returns only the 0-depth IS (i.e. vertices only) and no sections. 1769af9eab45SVaclav Hapla There is no corresponding Restore function, just call ISDestroy() on the returned IS to deallocate. 1770af9eab45SVaclav Hapla 1771af9eab45SVaclav Hapla .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexGetConeTuple(), DMPlexGetConeRecursive(), DMPlexRestoreConeRecursive(), DMPlexGetDepth() 1772d4636a37SVaclav Hapla @*/ 1773af9eab45SVaclav Hapla PetscErrorCode DMPlexGetConeRecursiveVertices(DM dm, IS points, IS *expandedPoints) 1774d4636a37SVaclav Hapla { 1775af9eab45SVaclav Hapla IS *expandedPointsAll; 1776af9eab45SVaclav Hapla PetscInt depth; 1777d4636a37SVaclav Hapla PetscErrorCode ierr; 1778d4636a37SVaclav Hapla 1779d4636a37SVaclav Hapla PetscFunctionBegin; 1780af9eab45SVaclav Hapla PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1781af9eab45SVaclav Hapla PetscValidHeaderSpecific(points, IS_CLASSID, 2); 1782af9eab45SVaclav Hapla PetscValidPointer(expandedPoints, 3); 1783af9eab45SVaclav Hapla ierr = DMPlexGetConeRecursive(dm, points, &depth, &expandedPointsAll, NULL);CHKERRQ(ierr); 1784af9eab45SVaclav Hapla *expandedPoints = expandedPointsAll[0]; 1785af9eab45SVaclav Hapla ierr = PetscObjectReference((PetscObject)expandedPointsAll[0]); 1786af9eab45SVaclav Hapla ierr = DMPlexRestoreConeRecursive(dm, points, &depth, &expandedPointsAll, NULL);CHKERRQ(ierr); 1787af9eab45SVaclav Hapla PetscFunctionReturn(0); 1788af9eab45SVaclav Hapla } 1789af9eab45SVaclav Hapla 1790af9eab45SVaclav Hapla /*@ 1791af9eab45SVaclav Hapla DMPlexGetConeRecursive - Expand each given point into its cone points and do that recursively until we end up just with vertices (DAG points of depth 0, i.e. without cones). 1792af9eab45SVaclav Hapla 1793af9eab45SVaclav Hapla Not collective 1794af9eab45SVaclav Hapla 1795af9eab45SVaclav Hapla Input Parameters: 1796af9eab45SVaclav Hapla + dm - The DMPlex 1797af9eab45SVaclav Hapla - points - The IS of points, which must lie in the chart set with DMPlexSetChart() 1798af9eab45SVaclav Hapla 1799af9eab45SVaclav Hapla Output Parameter: 1800af9eab45SVaclav Hapla + depth - (optional) Size of the output arrays, equal to DMPlex depth, returned by DMPlexGetDepth() 1801af9eab45SVaclav Hapla . expandedPoints - (optional) An array of index sets with recursively expanded cones 1802af9eab45SVaclav Hapla - sections - (optional) An array of sections which describe mappings from points to their cone points 1803af9eab45SVaclav Hapla 1804af9eab45SVaclav Hapla Level: advanced 1805af9eab45SVaclav Hapla 1806af9eab45SVaclav Hapla Notes: 1807af9eab45SVaclav Hapla Like DMPlexGetConeTuple() but recursive. 1808af9eab45SVaclav Hapla 1809af9eab45SVaclav Hapla Array expandedPoints has size equal to depth. Each expandedPoints[d] contains DAG points with maximum depth d, recursively cone-wise expanded from the input points. 1810af9eab45SVaclav Hapla For example, for d=0 it contains only vertices, for d=1 it can contain vertices and edges, etc. 1811af9eab45SVaclav Hapla 1812af9eab45SVaclav Hapla Array section has size equal to depth. Each PetscSection sections[d] realizes mapping from expandedPoints[d+1] (section points) to expandedPoints[d] (section dofs) as follows: 1813af9eab45SVaclav Hapla (1) DAG points in expandedPoints[d+1] with depth d+1 to their cone points in expandedPoints[d]; 1814af9eab45SVaclav Hapla (2) DAG points in expandedPoints[d+1] with depth in [0,d] to the same points in expandedPoints[d]. 1815af9eab45SVaclav Hapla 1816af9eab45SVaclav Hapla .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexGetConeTuple(), DMPlexRestoreConeRecursive(), DMPlexGetConeRecursiveVertices(), DMPlexGetDepth() 1817af9eab45SVaclav Hapla @*/ 1818af9eab45SVaclav Hapla PetscErrorCode DMPlexGetConeRecursive(DM dm, IS points, PetscInt *depth, IS *expandedPoints[], PetscSection *sections[]) 1819af9eab45SVaclav Hapla { 1820af9eab45SVaclav Hapla const PetscInt *arr0=NULL, *cone=NULL; 1821af9eab45SVaclav Hapla PetscInt *arr=NULL, *newarr=NULL; 1822af9eab45SVaclav Hapla PetscInt d, depth_, i, n, newn, cn, co, start, end; 1823af9eab45SVaclav Hapla IS *expandedPoints_; 1824af9eab45SVaclav Hapla PetscSection *sections_; 1825af9eab45SVaclav Hapla PetscErrorCode ierr; 1826af9eab45SVaclav Hapla 1827af9eab45SVaclav Hapla PetscFunctionBegin; 1828af9eab45SVaclav Hapla PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1829af9eab45SVaclav Hapla PetscValidHeaderSpecific(points, IS_CLASSID, 2); 1830af9eab45SVaclav Hapla if (depth) PetscValidIntPointer(depth, 3); 1831af9eab45SVaclav Hapla if (expandedPoints) PetscValidPointer(expandedPoints, 4); 1832af9eab45SVaclav Hapla if (sections) PetscValidPointer(sections, 5); 1833af9eab45SVaclav Hapla ierr = ISGetLocalSize(points, &n);CHKERRQ(ierr); 1834af9eab45SVaclav Hapla ierr = ISGetIndices(points, &arr0);CHKERRQ(ierr); 1835af9eab45SVaclav Hapla ierr = DMPlexGetDepth(dm, &depth_);CHKERRQ(ierr); 1836af9eab45SVaclav Hapla ierr = PetscCalloc1(depth_, &expandedPoints_);CHKERRQ(ierr); 1837af9eab45SVaclav Hapla ierr = PetscCalloc1(depth_, §ions_);CHKERRQ(ierr); 1838af9eab45SVaclav Hapla arr = (PetscInt*) arr0; /* this is ok because first generation of arr is not modified */ 1839af9eab45SVaclav Hapla for (d=depth_-1; d>=0; d--) { 1840af9eab45SVaclav Hapla ierr = PetscSectionCreate(PETSC_COMM_SELF, §ions_[d]);CHKERRQ(ierr); 1841af9eab45SVaclav Hapla ierr = PetscSectionSetChart(sections_[d], 0, n);CHKERRQ(ierr); 1842af9eab45SVaclav Hapla for (i=0; i<n; i++) { 1843af9eab45SVaclav Hapla ierr = DMPlexGetDepthStratum(dm, d+1, &start, &end);CHKERRQ(ierr); 1844af9eab45SVaclav Hapla if (arr[i] >= start && arr[i] < end) { 1845af9eab45SVaclav Hapla ierr = DMPlexGetConeSize(dm, arr[i], &cn);CHKERRQ(ierr); 1846af9eab45SVaclav Hapla ierr = PetscSectionSetDof(sections_[d], i, cn);CHKERRQ(ierr); 1847af9eab45SVaclav Hapla } else { 1848af9eab45SVaclav Hapla ierr = PetscSectionSetDof(sections_[d], i, 1);CHKERRQ(ierr); 1849af9eab45SVaclav Hapla } 1850af9eab45SVaclav Hapla } 1851af9eab45SVaclav Hapla ierr = PetscSectionSetUp(sections_[d]);CHKERRQ(ierr); 1852af9eab45SVaclav Hapla ierr = PetscSectionGetStorageSize(sections_[d], &newn);CHKERRQ(ierr); 1853af9eab45SVaclav Hapla ierr = PetscMalloc1(newn, &newarr);CHKERRQ(ierr); 1854af9eab45SVaclav Hapla for (i=0; i<n; i++) { 1855af9eab45SVaclav Hapla ierr = PetscSectionGetDof(sections_[d], i, &cn);CHKERRQ(ierr); 1856af9eab45SVaclav Hapla ierr = PetscSectionGetOffset(sections_[d], i, &co);CHKERRQ(ierr); 1857af9eab45SVaclav Hapla if (cn > 1) { 1858af9eab45SVaclav Hapla ierr = DMPlexGetCone(dm, arr[i], &cone);CHKERRQ(ierr); 1859af9eab45SVaclav Hapla ierr = PetscMemcpy(&newarr[co], cone, cn*sizeof(PetscInt));CHKERRQ(ierr); 1860af9eab45SVaclav Hapla } else { 1861af9eab45SVaclav Hapla newarr[co] = arr[i]; 1862af9eab45SVaclav Hapla } 1863af9eab45SVaclav Hapla } 1864af9eab45SVaclav Hapla ierr = ISCreateGeneral(PETSC_COMM_SELF, newn, newarr, PETSC_OWN_POINTER, &expandedPoints_[d]);CHKERRQ(ierr); 1865af9eab45SVaclav Hapla arr = newarr; 1866af9eab45SVaclav Hapla n = newn; 1867af9eab45SVaclav Hapla } 1868af9eab45SVaclav Hapla *depth = depth_; 1869af9eab45SVaclav Hapla if (expandedPoints) *expandedPoints = expandedPoints_; 1870af9eab45SVaclav Hapla else { 1871af9eab45SVaclav Hapla for (d=0; d<depth_; d++) {ierr = ISDestroy(&expandedPoints_[d]);CHKERRQ(ierr);} 1872af9eab45SVaclav Hapla ierr = PetscFree(expandedPoints_);CHKERRQ(ierr); 1873af9eab45SVaclav Hapla } 1874af9eab45SVaclav Hapla if (sections) *sections = sections_; 1875af9eab45SVaclav Hapla else { 1876af9eab45SVaclav Hapla for (d=0; d<depth_; d++) {ierr = PetscSectionDestroy(§ions_[d]);CHKERRQ(ierr);} 1877af9eab45SVaclav Hapla ierr = PetscFree(sections_);CHKERRQ(ierr); 1878af9eab45SVaclav Hapla } 1879af9eab45SVaclav Hapla PetscFunctionReturn(0); 1880af9eab45SVaclav Hapla } 1881af9eab45SVaclav Hapla 1882af9eab45SVaclav Hapla /*@ 1883af9eab45SVaclav Hapla DMPlexRestoreConeRecursive - Deallocates arrays created by DMPlexGetConeRecursive 1884af9eab45SVaclav Hapla 1885af9eab45SVaclav Hapla Not collective 1886af9eab45SVaclav Hapla 1887af9eab45SVaclav Hapla Input Parameters: 1888af9eab45SVaclav Hapla + dm - The DMPlex 1889af9eab45SVaclav Hapla - points - The IS of points, which must lie in the chart set with DMPlexSetChart() 1890af9eab45SVaclav Hapla 1891af9eab45SVaclav Hapla Output Parameter: 1892af9eab45SVaclav Hapla + depth - (optional) Size of the output arrays, equal to DMPlex depth, returned by DMPlexGetDepth() 1893af9eab45SVaclav Hapla . expandedPoints - (optional) An array of recursively expanded cones 1894af9eab45SVaclav Hapla - sections - (optional) An array of sections which describe mappings from points to their cone points 1895af9eab45SVaclav Hapla 1896af9eab45SVaclav Hapla Level: advanced 1897af9eab45SVaclav Hapla 1898af9eab45SVaclav Hapla Notes: 1899af9eab45SVaclav Hapla See DMPlexGetConeRecursive() for details. 1900af9eab45SVaclav Hapla 1901af9eab45SVaclav Hapla .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexGetConeTuple(), DMPlexGetConeRecursive(), DMPlexGetConeRecursiveVertices(), DMPlexGetDepth() 1902af9eab45SVaclav Hapla @*/ 1903af9eab45SVaclav Hapla PetscErrorCode DMPlexRestoreConeRecursive(DM dm, IS points, PetscInt *depth, IS *expandedPoints[], PetscSection *sections[]) 1904af9eab45SVaclav Hapla { 1905af9eab45SVaclav Hapla PetscInt d, depth_; 1906af9eab45SVaclav Hapla PetscErrorCode ierr; 1907af9eab45SVaclav Hapla 1908af9eab45SVaclav Hapla PetscFunctionBegin; 1909af9eab45SVaclav Hapla ierr = DMPlexGetDepth(dm, &depth_);CHKERRQ(ierr); 1910af9eab45SVaclav Hapla if (depth && *depth != depth_) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "depth changed since last call to DMPlexGetConeRecursive"); 1911af9eab45SVaclav Hapla if (depth) *depth = 0; 1912af9eab45SVaclav Hapla if (expandedPoints) { 1913af9eab45SVaclav Hapla for (d=0; d<depth_; d++) {ierr = ISDestroy(&((*expandedPoints)[d]));CHKERRQ(ierr);} 1914af9eab45SVaclav Hapla ierr = PetscFree(*expandedPoints);CHKERRQ(ierr); 1915af9eab45SVaclav Hapla } 1916af9eab45SVaclav Hapla if (sections) { 1917af9eab45SVaclav Hapla for (d=0; d<depth_; d++) {ierr = PetscSectionDestroy(&((*sections)[d]));CHKERRQ(ierr);} 1918af9eab45SVaclav Hapla ierr = PetscFree(*sections);CHKERRQ(ierr); 1919af9eab45SVaclav Hapla } 1920d4636a37SVaclav Hapla PetscFunctionReturn(0); 1921d4636a37SVaclav Hapla } 1922d4636a37SVaclav Hapla 1923552f7358SJed Brown /*@ 192492371b87SBarry 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 1925552f7358SJed Brown 1926552f7358SJed Brown Not collective 1927552f7358SJed Brown 1928552f7358SJed Brown Input Parameters: 1929552f7358SJed Brown + mesh - The DMPlex 1930eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 1931552f7358SJed Brown - cone - An array of points which are on the in-edges for point p 1932552f7358SJed Brown 1933552f7358SJed Brown Output Parameter: 1934552f7358SJed Brown 1935552f7358SJed Brown Note: 1936552f7358SJed Brown This should be called after all calls to DMPlexSetConeSize() and DMSetUp(). 1937552f7358SJed Brown 193892371b87SBarry Smith Developer Note: Why not call this DMPlexSetCover() 193992371b87SBarry Smith 1940552f7358SJed Brown Level: beginner 1941552f7358SJed Brown 194292371b87SBarry Smith .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexSetChart(), DMPlexSetConeSize(), DMSetUp(), DMPlexSetSupport(), DMPlexSetSupportSize() 1943552f7358SJed Brown @*/ 1944552f7358SJed Brown PetscErrorCode DMPlexSetCone(DM dm, PetscInt p, const PetscInt cone[]) 1945552f7358SJed Brown { 1946552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1947552f7358SJed Brown PetscInt pStart, pEnd; 1948552f7358SJed Brown PetscInt dof, off, c; 1949552f7358SJed Brown PetscErrorCode ierr; 1950552f7358SJed Brown 1951552f7358SJed Brown PetscFunctionBegin; 1952552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1953552f7358SJed Brown ierr = PetscSectionGetChart(mesh->coneSection, &pStart, &pEnd);CHKERRQ(ierr); 1954552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 1955552f7358SJed Brown if (dof) PetscValidPointer(cone, 3); 1956552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 195782f516ccSBarry 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); 1958552f7358SJed Brown for (c = 0; c < dof; ++c) { 195982f516ccSBarry 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); 1960552f7358SJed Brown mesh->cones[off+c] = cone[c]; 1961552f7358SJed Brown } 1962552f7358SJed Brown PetscFunctionReturn(0); 1963552f7358SJed Brown } 1964552f7358SJed Brown 1965552f7358SJed Brown /*@C 1966eaf898f9SPatrick Sanan DMPlexGetConeOrientation - Return the orientations on the in-edges for this point in the DAG 1967552f7358SJed Brown 1968552f7358SJed Brown Not collective 1969552f7358SJed Brown 1970552f7358SJed Brown Input Parameters: 1971552f7358SJed Brown + mesh - The DMPlex 1972eaf898f9SPatrick Sanan - p - The point, which must lie in the chart set with DMPlexSetChart() 1973552f7358SJed Brown 1974552f7358SJed Brown Output Parameter: 1975552f7358SJed Brown . coneOrientation - An array of orientations which are on the in-edges for point p. An orientation is an 1976552f7358SJed Brown integer giving the prescription for cone traversal. If it is negative, the cone is 1977552f7358SJed Brown traversed in the opposite direction. Its value 'o', or if negative '-(o+1)', gives 1978552f7358SJed Brown the index of the cone point on which to start. 1979552f7358SJed Brown 1980552f7358SJed Brown Level: beginner 1981552f7358SJed Brown 19823813dfbdSMatthew G Knepley Fortran Notes: 19833813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 19843813dfbdSMatthew G Knepley include petsc.h90 in your code. 19853b12b3d8SVaclav Hapla You must also call DMPlexRestoreConeOrientation() after you finish using the returned array. 1986922102d1SVaclav Hapla DMPlexRestoreConeOrientation() is not needed/available in C. 19873813dfbdSMatthew G Knepley 1988552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexSetCone(), DMPlexSetChart() 1989552f7358SJed Brown @*/ 1990552f7358SJed Brown PetscErrorCode DMPlexGetConeOrientation(DM dm, PetscInt p, const PetscInt *coneOrientation[]) 1991552f7358SJed Brown { 1992552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 1993552f7358SJed Brown PetscInt off; 1994552f7358SJed Brown PetscErrorCode ierr; 1995552f7358SJed Brown 1996552f7358SJed Brown PetscFunctionBegin; 1997552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1998552f7358SJed Brown #if defined(PETSC_USE_DEBUG) 1999552f7358SJed Brown { 2000552f7358SJed Brown PetscInt dof; 2001552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 2002552f7358SJed Brown if (dof) PetscValidPointer(coneOrientation, 3); 2003552f7358SJed Brown } 2004552f7358SJed Brown #endif 2005552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 20060d644c17SKarl Rupp 2007552f7358SJed Brown *coneOrientation = &mesh->coneOrientations[off]; 2008552f7358SJed Brown PetscFunctionReturn(0); 2009552f7358SJed Brown } 2010552f7358SJed Brown 2011552f7358SJed Brown /*@ 2012eaf898f9SPatrick Sanan DMPlexSetConeOrientation - Set the orientations on the in-edges for this point in the DAG 2013552f7358SJed Brown 2014552f7358SJed Brown Not collective 2015552f7358SJed Brown 2016552f7358SJed Brown Input Parameters: 2017552f7358SJed Brown + mesh - The DMPlex 2018eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 2019552f7358SJed Brown - coneOrientation - An array of orientations which are on the in-edges for point p. An orientation is an 2020552f7358SJed Brown integer giving the prescription for cone traversal. If it is negative, the cone is 2021552f7358SJed Brown traversed in the opposite direction. Its value 'o', or if negative '-(o+1)', gives 2022552f7358SJed Brown the index of the cone point on which to start. 2023552f7358SJed Brown 2024552f7358SJed Brown Output Parameter: 2025552f7358SJed Brown 2026552f7358SJed Brown Note: 2027552f7358SJed Brown This should be called after all calls to DMPlexSetConeSize() and DMSetUp(). 2028552f7358SJed Brown 2029552f7358SJed Brown Level: beginner 2030552f7358SJed Brown 2031552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetConeOrientation(), DMPlexSetCone(), DMPlexSetChart(), DMPlexSetConeSize(), DMSetUp() 2032552f7358SJed Brown @*/ 2033552f7358SJed Brown PetscErrorCode DMPlexSetConeOrientation(DM dm, PetscInt p, const PetscInt coneOrientation[]) 2034552f7358SJed Brown { 2035552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2036552f7358SJed Brown PetscInt pStart, pEnd; 2037552f7358SJed Brown PetscInt dof, off, c; 2038552f7358SJed Brown PetscErrorCode ierr; 2039552f7358SJed Brown 2040552f7358SJed Brown PetscFunctionBegin; 2041552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2042552f7358SJed Brown ierr = PetscSectionGetChart(mesh->coneSection, &pStart, &pEnd);CHKERRQ(ierr); 2043552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 2044552f7358SJed Brown if (dof) PetscValidPointer(coneOrientation, 3); 2045552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 204682f516ccSBarry 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); 2047552f7358SJed Brown for (c = 0; c < dof; ++c) { 2048552f7358SJed Brown PetscInt cdof, o = coneOrientation[c]; 2049552f7358SJed Brown 2050552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, mesh->cones[off+c], &cdof);CHKERRQ(ierr); 205182f516ccSBarry 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); 2052552f7358SJed Brown mesh->coneOrientations[off+c] = o; 2053552f7358SJed Brown } 2054552f7358SJed Brown PetscFunctionReturn(0); 2055552f7358SJed Brown } 2056552f7358SJed Brown 20577cd05799SMatthew G. Knepley /*@ 2058eaf898f9SPatrick Sanan DMPlexInsertCone - Insert a point into the in-edges for the point p in the DAG 20597cd05799SMatthew G. Knepley 20607cd05799SMatthew G. Knepley Not collective 20617cd05799SMatthew G. Knepley 20627cd05799SMatthew G. Knepley Input Parameters: 20637cd05799SMatthew G. Knepley + mesh - The DMPlex 2064eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 20657cd05799SMatthew G. Knepley . conePos - The local index in the cone where the point should be put 20667cd05799SMatthew G. Knepley - conePoint - The mesh point to insert 20677cd05799SMatthew G. Knepley 20687cd05799SMatthew G. Knepley Level: beginner 20697cd05799SMatthew G. Knepley 20707cd05799SMatthew G. Knepley .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexSetChart(), DMPlexSetConeSize(), DMSetUp() 20717cd05799SMatthew G. Knepley @*/ 2072552f7358SJed Brown PetscErrorCode DMPlexInsertCone(DM dm, PetscInt p, PetscInt conePos, PetscInt conePoint) 2073552f7358SJed Brown { 2074552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2075552f7358SJed Brown PetscInt pStart, pEnd; 2076552f7358SJed Brown PetscInt dof, off; 2077552f7358SJed Brown PetscErrorCode ierr; 2078552f7358SJed Brown 2079552f7358SJed Brown PetscFunctionBegin; 2080552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2081552f7358SJed Brown ierr = PetscSectionGetChart(mesh->coneSection, &pStart, &pEnd);CHKERRQ(ierr); 208282f516ccSBarry 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); 208382f516ccSBarry 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); 208477c88f5bSMatthew G Knepley ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 208577c88f5bSMatthew G Knepley ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 208677c88f5bSMatthew 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); 2087552f7358SJed Brown mesh->cones[off+conePos] = conePoint; 2088552f7358SJed Brown PetscFunctionReturn(0); 2089552f7358SJed Brown } 2090552f7358SJed Brown 20917cd05799SMatthew G. Knepley /*@ 2092eaf898f9SPatrick Sanan DMPlexInsertConeOrientation - Insert a point orientation for the in-edge for the point p in the DAG 20937cd05799SMatthew G. Knepley 20947cd05799SMatthew G. Knepley Not collective 20957cd05799SMatthew G. Knepley 20967cd05799SMatthew G. Knepley Input Parameters: 20977cd05799SMatthew G. Knepley + mesh - The DMPlex 2098eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 20997cd05799SMatthew G. Knepley . conePos - The local index in the cone where the point should be put 21007cd05799SMatthew G. Knepley - coneOrientation - The point orientation to insert 21017cd05799SMatthew G. Knepley 21027cd05799SMatthew G. Knepley Level: beginner 21037cd05799SMatthew G. Knepley 21047cd05799SMatthew G. Knepley .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexSetChart(), DMPlexSetConeSize(), DMSetUp() 21057cd05799SMatthew G. Knepley @*/ 210677c88f5bSMatthew G Knepley PetscErrorCode DMPlexInsertConeOrientation(DM dm, PetscInt p, PetscInt conePos, PetscInt coneOrientation) 210777c88f5bSMatthew G Knepley { 210877c88f5bSMatthew G Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 210977c88f5bSMatthew G Knepley PetscInt pStart, pEnd; 211077c88f5bSMatthew G Knepley PetscInt dof, off; 211177c88f5bSMatthew G Knepley PetscErrorCode ierr; 211277c88f5bSMatthew G Knepley 211377c88f5bSMatthew G Knepley PetscFunctionBegin; 211477c88f5bSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 211577c88f5bSMatthew G Knepley ierr = PetscSectionGetChart(mesh->coneSection, &pStart, &pEnd);CHKERRQ(ierr); 211677c88f5bSMatthew 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); 211777c88f5bSMatthew G Knepley ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 211877c88f5bSMatthew G Knepley ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 211977c88f5bSMatthew 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); 212077c88f5bSMatthew G Knepley mesh->coneOrientations[off+conePos] = coneOrientation; 212177c88f5bSMatthew G Knepley PetscFunctionReturn(0); 212277c88f5bSMatthew G Knepley } 212377c88f5bSMatthew G Knepley 2124552f7358SJed Brown /*@ 2125eaf898f9SPatrick Sanan DMPlexGetSupportSize - Return the number of out-edges for this point in the DAG 2126552f7358SJed Brown 2127552f7358SJed Brown Not collective 2128552f7358SJed Brown 2129552f7358SJed Brown Input Parameters: 2130552f7358SJed Brown + mesh - The DMPlex 2131eaf898f9SPatrick Sanan - p - The point, which must lie in the chart set with DMPlexSetChart() 2132552f7358SJed Brown 2133552f7358SJed Brown Output Parameter: 2134552f7358SJed Brown . size - The support size for point p 2135552f7358SJed Brown 2136552f7358SJed Brown Level: beginner 2137552f7358SJed Brown 2138552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetConeSize(), DMPlexSetChart(), DMPlexGetConeSize() 2139552f7358SJed Brown @*/ 2140552f7358SJed Brown PetscErrorCode DMPlexGetSupportSize(DM dm, PetscInt p, PetscInt *size) 2141552f7358SJed Brown { 2142552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2143552f7358SJed Brown PetscErrorCode ierr; 2144552f7358SJed Brown 2145552f7358SJed Brown PetscFunctionBegin; 2146552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2147552f7358SJed Brown PetscValidPointer(size, 3); 2148552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, size);CHKERRQ(ierr); 2149552f7358SJed Brown PetscFunctionReturn(0); 2150552f7358SJed Brown } 2151552f7358SJed Brown 2152552f7358SJed Brown /*@ 2153eaf898f9SPatrick Sanan DMPlexSetSupportSize - Set the number of out-edges for this point in the DAG 2154552f7358SJed Brown 2155552f7358SJed Brown Not collective 2156552f7358SJed Brown 2157552f7358SJed Brown Input Parameters: 2158552f7358SJed Brown + mesh - The DMPlex 2159eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 2160552f7358SJed Brown - size - The support size for point p 2161552f7358SJed Brown 2162552f7358SJed Brown Output Parameter: 2163552f7358SJed Brown 2164552f7358SJed Brown Note: 2165552f7358SJed Brown This should be called after DMPlexSetChart(). 2166552f7358SJed Brown 2167552f7358SJed Brown Level: beginner 2168552f7358SJed Brown 2169552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetSupportSize(), DMPlexSetChart() 2170552f7358SJed Brown @*/ 2171552f7358SJed Brown PetscErrorCode DMPlexSetSupportSize(DM dm, PetscInt p, PetscInt size) 2172552f7358SJed Brown { 2173552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2174552f7358SJed Brown PetscErrorCode ierr; 2175552f7358SJed Brown 2176552f7358SJed Brown PetscFunctionBegin; 2177552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2178552f7358SJed Brown ierr = PetscSectionSetDof(mesh->supportSection, p, size);CHKERRQ(ierr); 21790d644c17SKarl Rupp 2180552f7358SJed Brown mesh->maxSupportSize = PetscMax(mesh->maxSupportSize, size); 2181552f7358SJed Brown PetscFunctionReturn(0); 2182552f7358SJed Brown } 2183552f7358SJed Brown 2184552f7358SJed Brown /*@C 2185eaf898f9SPatrick Sanan DMPlexGetSupport - Return the points on the out-edges for this point in the DAG 2186552f7358SJed Brown 2187552f7358SJed Brown Not collective 2188552f7358SJed Brown 2189552f7358SJed Brown Input Parameters: 2190552f7358SJed Brown + mesh - The DMPlex 2191eaf898f9SPatrick Sanan - p - The point, which must lie in the chart set with DMPlexSetChart() 2192552f7358SJed Brown 2193552f7358SJed Brown Output Parameter: 2194552f7358SJed Brown . support - An array of points which are on the out-edges for point p 2195552f7358SJed Brown 2196552f7358SJed Brown Level: beginner 2197552f7358SJed Brown 21983813dfbdSMatthew G Knepley Fortran Notes: 21993813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 22003813dfbdSMatthew G Knepley include petsc.h90 in your code. 22013b12b3d8SVaclav Hapla You must also call DMPlexRestoreSupport() after you finish using the returned array. 2202922102d1SVaclav Hapla DMPlexRestoreSupport() is not needed/available in C. 22033813dfbdSMatthew G Knepley 2204552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetCone(), DMPlexSetChart(), DMPlexGetCone() 2205552f7358SJed Brown @*/ 2206552f7358SJed Brown PetscErrorCode DMPlexGetSupport(DM dm, PetscInt p, const PetscInt *support[]) 2207552f7358SJed Brown { 2208552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2209552f7358SJed Brown PetscInt off; 2210552f7358SJed Brown PetscErrorCode ierr; 2211552f7358SJed Brown 2212552f7358SJed Brown PetscFunctionBegin; 2213552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2214552f7358SJed Brown PetscValidPointer(support, 3); 2215552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, p, &off);CHKERRQ(ierr); 2216552f7358SJed Brown *support = &mesh->supports[off]; 2217552f7358SJed Brown PetscFunctionReturn(0); 2218552f7358SJed Brown } 2219552f7358SJed Brown 2220552f7358SJed Brown /*@ 222192371b87SBarry 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 2222552f7358SJed Brown 2223552f7358SJed Brown Not collective 2224552f7358SJed Brown 2225552f7358SJed Brown Input Parameters: 2226552f7358SJed Brown + mesh - The DMPlex 2227eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 222892371b87SBarry Smith - support - An array of points which are on the out-edges for point p 2229552f7358SJed Brown 2230552f7358SJed Brown Output Parameter: 2231552f7358SJed Brown 2232552f7358SJed Brown Note: 2233552f7358SJed Brown This should be called after all calls to DMPlexSetSupportSize() and DMSetUp(). 2234552f7358SJed Brown 2235552f7358SJed Brown Level: beginner 2236552f7358SJed Brown 223792371b87SBarry Smith .seealso: DMPlexSetCone(), DMPlexSetConeSize(), DMPlexCreate(), DMPlexGetSupport(), DMPlexSetChart(), DMPlexSetSupportSize(), DMSetUp() 2238552f7358SJed Brown @*/ 2239552f7358SJed Brown PetscErrorCode DMPlexSetSupport(DM dm, PetscInt p, const PetscInt support[]) 2240552f7358SJed Brown { 2241552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2242552f7358SJed Brown PetscInt pStart, pEnd; 2243552f7358SJed Brown PetscInt dof, off, c; 2244552f7358SJed Brown PetscErrorCode ierr; 2245552f7358SJed Brown 2246552f7358SJed Brown PetscFunctionBegin; 2247552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2248552f7358SJed Brown ierr = PetscSectionGetChart(mesh->supportSection, &pStart, &pEnd);CHKERRQ(ierr); 2249552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, &dof);CHKERRQ(ierr); 2250552f7358SJed Brown if (dof) PetscValidPointer(support, 3); 2251552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, p, &off);CHKERRQ(ierr); 225282f516ccSBarry 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); 2253552f7358SJed Brown for (c = 0; c < dof; ++c) { 225482f516ccSBarry 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); 2255552f7358SJed Brown mesh->supports[off+c] = support[c]; 2256552f7358SJed Brown } 2257552f7358SJed Brown PetscFunctionReturn(0); 2258552f7358SJed Brown } 2259552f7358SJed Brown 22607cd05799SMatthew G. Knepley /*@ 2261eaf898f9SPatrick Sanan DMPlexInsertSupport - Insert a point into the out-edges for the point p in the DAG 22627cd05799SMatthew G. Knepley 22637cd05799SMatthew G. Knepley Not collective 22647cd05799SMatthew G. Knepley 22657cd05799SMatthew G. Knepley Input Parameters: 22667cd05799SMatthew G. Knepley + mesh - The DMPlex 2267eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 22687cd05799SMatthew G. Knepley . supportPos - The local index in the cone where the point should be put 22697cd05799SMatthew G. Knepley - supportPoint - The mesh point to insert 22707cd05799SMatthew G. Knepley 22717cd05799SMatthew G. Knepley Level: beginner 22727cd05799SMatthew G. Knepley 22737cd05799SMatthew G. Knepley .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexSetChart(), DMPlexSetConeSize(), DMSetUp() 22747cd05799SMatthew G. Knepley @*/ 2275552f7358SJed Brown PetscErrorCode DMPlexInsertSupport(DM dm, PetscInt p, PetscInt supportPos, PetscInt supportPoint) 2276552f7358SJed Brown { 2277552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2278552f7358SJed Brown PetscInt pStart, pEnd; 2279552f7358SJed Brown PetscInt dof, off; 2280552f7358SJed Brown PetscErrorCode ierr; 2281552f7358SJed Brown 2282552f7358SJed Brown PetscFunctionBegin; 2283552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2284552f7358SJed Brown ierr = PetscSectionGetChart(mesh->supportSection, &pStart, &pEnd);CHKERRQ(ierr); 2285552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, &dof);CHKERRQ(ierr); 2286552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, p, &off);CHKERRQ(ierr); 228782f516ccSBarry 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); 228882f516ccSBarry 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); 228982f516ccSBarry 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); 2290552f7358SJed Brown mesh->supports[off+supportPos] = supportPoint; 2291552f7358SJed Brown PetscFunctionReturn(0); 2292552f7358SJed Brown } 2293552f7358SJed Brown 2294552f7358SJed Brown /*@C 2295eaf898f9SPatrick Sanan DMPlexGetTransitiveClosure - Return the points on the transitive closure of the in-edges or out-edges for this point in the DAG 2296552f7358SJed Brown 2297552f7358SJed Brown Not collective 2298552f7358SJed Brown 2299552f7358SJed Brown Input Parameters: 2300552f7358SJed Brown + mesh - The DMPlex 2301eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 2302552f7358SJed Brown . useCone - PETSC_TRUE for in-edges, otherwise use out-edges 23030298fd71SBarry Smith - points - If points is NULL on input, internal storage will be returned, otherwise the provided array is used 2304552f7358SJed Brown 2305552f7358SJed Brown Output Parameters: 2306552f7358SJed Brown + numPoints - The number of points in the closure, so points[] is of size 2*numPoints 2307552f7358SJed Brown - points - The points and point orientations, interleaved as pairs [p0, o0, p1, o1, ...] 2308552f7358SJed Brown 2309552f7358SJed Brown Note: 23100298fd71SBarry Smith If using internal storage (points is NULL on input), each call overwrites the last output. 2311552f7358SJed Brown 23123813dfbdSMatthew G Knepley Fortran Notes: 23133813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 23143813dfbdSMatthew G Knepley include petsc.h90 in your code. 23153813dfbdSMatthew G Knepley 23163813dfbdSMatthew G Knepley The numPoints argument is not present in the Fortran 90 binding since it is internal to the array. 23173813dfbdSMatthew G Knepley 2318552f7358SJed Brown Level: beginner 2319552f7358SJed Brown 2320552f7358SJed Brown .seealso: DMPlexRestoreTransitiveClosure(), DMPlexCreate(), DMPlexSetCone(), DMPlexSetChart(), DMPlexGetCone() 2321552f7358SJed Brown @*/ 2322552f7358SJed Brown PetscErrorCode DMPlexGetTransitiveClosure(DM dm, PetscInt p, PetscBool useCone, PetscInt *numPoints, PetscInt *points[]) 2323552f7358SJed Brown { 2324552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2325552f7358SJed Brown PetscInt *closure, *fifo; 23260298fd71SBarry Smith const PetscInt *tmp = NULL, *tmpO = NULL; 2327552f7358SJed Brown PetscInt tmpSize, t; 2328552f7358SJed Brown PetscInt depth = 0, maxSize; 2329552f7358SJed Brown PetscInt closureSize = 2, fifoSize = 0, fifoStart = 0; 2330552f7358SJed Brown PetscErrorCode ierr; 2331552f7358SJed Brown 2332552f7358SJed Brown PetscFunctionBegin; 2333552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2334552f7358SJed Brown ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 2335552f7358SJed Brown /* This is only 1-level */ 2336552f7358SJed Brown if (useCone) { 2337552f7358SJed Brown ierr = DMPlexGetConeSize(dm, p, &tmpSize);CHKERRQ(ierr); 2338552f7358SJed Brown ierr = DMPlexGetCone(dm, p, &tmp);CHKERRQ(ierr); 2339552f7358SJed Brown ierr = DMPlexGetConeOrientation(dm, p, &tmpO);CHKERRQ(ierr); 2340552f7358SJed Brown } else { 2341552f7358SJed Brown ierr = DMPlexGetSupportSize(dm, p, &tmpSize);CHKERRQ(ierr); 2342552f7358SJed Brown ierr = DMPlexGetSupport(dm, p, &tmp);CHKERRQ(ierr); 2343552f7358SJed Brown } 2344bfbcdd7aSMatthew G. Knepley if (depth == 1) { 2345bfbcdd7aSMatthew G. Knepley if (*points) { 2346bfbcdd7aSMatthew G. Knepley closure = *points; 2347bfbcdd7aSMatthew G. Knepley } else { 2348bfbcdd7aSMatthew G. Knepley maxSize = 2*(PetscMax(mesh->maxConeSize, mesh->maxSupportSize)+1); 234969291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &closure);CHKERRQ(ierr); 2350bfbcdd7aSMatthew G. Knepley } 2351bfbcdd7aSMatthew G. Knepley closure[0] = p; closure[1] = 0; 2352bfbcdd7aSMatthew G. Knepley for (t = 0; t < tmpSize; ++t, closureSize += 2) { 2353bfbcdd7aSMatthew G. Knepley closure[closureSize] = tmp[t]; 2354bfbcdd7aSMatthew G. Knepley closure[closureSize+1] = tmpO ? tmpO[t] : 0; 2355bfbcdd7aSMatthew G. Knepley } 2356bfbcdd7aSMatthew G. Knepley if (numPoints) *numPoints = closureSize/2; 2357bfbcdd7aSMatthew G. Knepley if (points) *points = closure; 2358bfbcdd7aSMatthew G. Knepley PetscFunctionReturn(0); 2359bfbcdd7aSMatthew G. Knepley } 236024c766afSToby Isaac { 236124c766afSToby Isaac PetscInt c, coneSeries, s,supportSeries; 236224c766afSToby Isaac 236324c766afSToby Isaac c = mesh->maxConeSize; 236424c766afSToby Isaac coneSeries = (c > 1) ? ((PetscPowInt(c,depth+1)-1)/(c-1)) : depth+1; 236524c766afSToby Isaac s = mesh->maxSupportSize; 236624c766afSToby Isaac supportSeries = (s > 1) ? ((PetscPowInt(s,depth+1)-1)/(s-1)) : depth+1; 236724c766afSToby Isaac maxSize = 2*PetscMax(coneSeries,supportSeries); 236824c766afSToby Isaac } 236969291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &fifo);CHKERRQ(ierr); 2370bfbcdd7aSMatthew G. Knepley if (*points) { 2371bfbcdd7aSMatthew G. Knepley closure = *points; 2372bfbcdd7aSMatthew G. Knepley } else { 237369291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &closure);CHKERRQ(ierr); 2374bfbcdd7aSMatthew G. Knepley } 2375bfbcdd7aSMatthew G. Knepley closure[0] = p; closure[1] = 0; 2376552f7358SJed Brown for (t = 0; t < tmpSize; ++t, closureSize += 2, fifoSize += 2) { 2377552f7358SJed Brown const PetscInt cp = tmp[t]; 2378552f7358SJed Brown const PetscInt co = tmpO ? tmpO[t] : 0; 2379552f7358SJed Brown 2380552f7358SJed Brown closure[closureSize] = cp; 2381552f7358SJed Brown closure[closureSize+1] = co; 2382552f7358SJed Brown fifo[fifoSize] = cp; 2383552f7358SJed Brown fifo[fifoSize+1] = co; 2384552f7358SJed Brown } 2385bfbcdd7aSMatthew G. Knepley /* Should kick out early when depth is reached, rather than checking all vertices for empty cones */ 2386552f7358SJed Brown while (fifoSize - fifoStart) { 2387552f7358SJed Brown const PetscInt q = fifo[fifoStart]; 2388552f7358SJed Brown const PetscInt o = fifo[fifoStart+1]; 2389552f7358SJed Brown const PetscInt rev = o >= 0 ? 0 : 1; 2390552f7358SJed Brown const PetscInt off = rev ? -(o+1) : o; 2391552f7358SJed Brown 2392552f7358SJed Brown if (useCone) { 2393552f7358SJed Brown ierr = DMPlexGetConeSize(dm, q, &tmpSize);CHKERRQ(ierr); 2394552f7358SJed Brown ierr = DMPlexGetCone(dm, q, &tmp);CHKERRQ(ierr); 2395552f7358SJed Brown ierr = DMPlexGetConeOrientation(dm, q, &tmpO);CHKERRQ(ierr); 2396552f7358SJed Brown } else { 2397552f7358SJed Brown ierr = DMPlexGetSupportSize(dm, q, &tmpSize);CHKERRQ(ierr); 2398552f7358SJed Brown ierr = DMPlexGetSupport(dm, q, &tmp);CHKERRQ(ierr); 23990298fd71SBarry Smith tmpO = NULL; 2400552f7358SJed Brown } 2401552f7358SJed Brown for (t = 0; t < tmpSize; ++t) { 2402552f7358SJed Brown const PetscInt i = ((rev ? tmpSize-t : t) + off)%tmpSize; 2403552f7358SJed Brown const PetscInt cp = tmp[i]; 24042e1b13c2SMatthew 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. */ 24052e1b13c2SMatthew G. Knepley /* HACK: It is worse to get the size here, than to change the interpretation of -(*+1) 24062e1b13c2SMatthew G. Knepley const PetscInt co = tmpO ? (rev ? -(tmpO[i]+1) : tmpO[i]) : 0; */ 24072e1b13c2SMatthew G. Knepley PetscInt co = tmpO ? tmpO[i] : 0; 2408552f7358SJed Brown PetscInt c; 2409552f7358SJed Brown 24102e1b13c2SMatthew G. Knepley if (rev) { 24112e1b13c2SMatthew G. Knepley PetscInt childSize, coff; 24122e1b13c2SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, cp, &childSize);CHKERRQ(ierr); 24132e1b13c2SMatthew G. Knepley coff = tmpO[i] < 0 ? -(tmpO[i]+1) : tmpO[i]; 24142e1b13c2SMatthew G. Knepley co = childSize ? -(((coff+childSize-1)%childSize)+1) : 0; 24152e1b13c2SMatthew G. Knepley } 2416552f7358SJed Brown /* Check for duplicate */ 2417552f7358SJed Brown for (c = 0; c < closureSize; c += 2) { 2418552f7358SJed Brown if (closure[c] == cp) break; 2419552f7358SJed Brown } 2420552f7358SJed Brown if (c == closureSize) { 2421552f7358SJed Brown closure[closureSize] = cp; 2422552f7358SJed Brown closure[closureSize+1] = co; 2423552f7358SJed Brown fifo[fifoSize] = cp; 2424552f7358SJed Brown fifo[fifoSize+1] = co; 2425552f7358SJed Brown closureSize += 2; 2426552f7358SJed Brown fifoSize += 2; 2427552f7358SJed Brown } 2428552f7358SJed Brown } 2429552f7358SJed Brown fifoStart += 2; 2430552f7358SJed Brown } 2431552f7358SJed Brown if (numPoints) *numPoints = closureSize/2; 2432552f7358SJed Brown if (points) *points = closure; 243369291d52SBarry Smith ierr = DMRestoreWorkArray(dm, maxSize, MPIU_INT, &fifo);CHKERRQ(ierr); 2434552f7358SJed Brown PetscFunctionReturn(0); 2435552f7358SJed Brown } 2436552f7358SJed Brown 24379bf0dad6SMatthew G. Knepley /*@C 2438eaf898f9SPatrick 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 24399bf0dad6SMatthew G. Knepley 24409bf0dad6SMatthew G. Knepley Not collective 24419bf0dad6SMatthew G. Knepley 24429bf0dad6SMatthew G. Knepley Input Parameters: 24439bf0dad6SMatthew G. Knepley + mesh - The DMPlex 2444eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 24459bf0dad6SMatthew G. Knepley . orientation - The orientation of the point 24469bf0dad6SMatthew G. Knepley . useCone - PETSC_TRUE for in-edges, otherwise use out-edges 24479bf0dad6SMatthew G. Knepley - points - If points is NULL on input, internal storage will be returned, otherwise the provided array is used 24489bf0dad6SMatthew G. Knepley 24499bf0dad6SMatthew G. Knepley Output Parameters: 24509bf0dad6SMatthew G. Knepley + numPoints - The number of points in the closure, so points[] is of size 2*numPoints 24519bf0dad6SMatthew G. Knepley - points - The points and point orientations, interleaved as pairs [p0, o0, p1, o1, ...] 24529bf0dad6SMatthew G. Knepley 24539bf0dad6SMatthew G. Knepley Note: 24549bf0dad6SMatthew G. Knepley If using internal storage (points is NULL on input), each call overwrites the last output. 24559bf0dad6SMatthew G. Knepley 24569bf0dad6SMatthew G. Knepley Fortran Notes: 24579bf0dad6SMatthew G. Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 24589bf0dad6SMatthew G. Knepley include petsc.h90 in your code. 24599bf0dad6SMatthew G. Knepley 24609bf0dad6SMatthew G. Knepley The numPoints argument is not present in the Fortran 90 binding since it is internal to the array. 24619bf0dad6SMatthew G. Knepley 24629bf0dad6SMatthew G. Knepley Level: beginner 24639bf0dad6SMatthew G. Knepley 24649bf0dad6SMatthew G. Knepley .seealso: DMPlexRestoreTransitiveClosure(), DMPlexCreate(), DMPlexSetCone(), DMPlexSetChart(), DMPlexGetCone() 24659bf0dad6SMatthew G. Knepley @*/ 24669bf0dad6SMatthew G. Knepley PetscErrorCode DMPlexGetTransitiveClosure_Internal(DM dm, PetscInt p, PetscInt ornt, PetscBool useCone, PetscInt *numPoints, PetscInt *points[]) 24679bf0dad6SMatthew G. Knepley { 24689bf0dad6SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 24699bf0dad6SMatthew G. Knepley PetscInt *closure, *fifo; 24709bf0dad6SMatthew G. Knepley const PetscInt *tmp = NULL, *tmpO = NULL; 24719bf0dad6SMatthew G. Knepley PetscInt tmpSize, t; 24729bf0dad6SMatthew G. Knepley PetscInt depth = 0, maxSize; 24739bf0dad6SMatthew G. Knepley PetscInt closureSize = 2, fifoSize = 0, fifoStart = 0; 24749bf0dad6SMatthew G. Knepley PetscErrorCode ierr; 24759bf0dad6SMatthew G. Knepley 24769bf0dad6SMatthew G. Knepley PetscFunctionBegin; 24779bf0dad6SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 24789bf0dad6SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 24799bf0dad6SMatthew G. Knepley /* This is only 1-level */ 24809bf0dad6SMatthew G. Knepley if (useCone) { 24819bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, p, &tmpSize);CHKERRQ(ierr); 24829bf0dad6SMatthew G. Knepley ierr = DMPlexGetCone(dm, p, &tmp);CHKERRQ(ierr); 24839bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, p, &tmpO);CHKERRQ(ierr); 24849bf0dad6SMatthew G. Knepley } else { 24859bf0dad6SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, p, &tmpSize);CHKERRQ(ierr); 24869bf0dad6SMatthew G. Knepley ierr = DMPlexGetSupport(dm, p, &tmp);CHKERRQ(ierr); 24879bf0dad6SMatthew G. Knepley } 24889bf0dad6SMatthew G. Knepley if (depth == 1) { 24899bf0dad6SMatthew G. Knepley if (*points) { 24909bf0dad6SMatthew G. Knepley closure = *points; 24919bf0dad6SMatthew G. Knepley } else { 24929bf0dad6SMatthew G. Knepley maxSize = 2*(PetscMax(mesh->maxConeSize, mesh->maxSupportSize)+1); 249369291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &closure);CHKERRQ(ierr); 24949bf0dad6SMatthew G. Knepley } 24959bf0dad6SMatthew G. Knepley closure[0] = p; closure[1] = ornt; 24969bf0dad6SMatthew G. Knepley for (t = 0; t < tmpSize; ++t, closureSize += 2) { 24979bf0dad6SMatthew G. Knepley const PetscInt i = ornt >= 0 ? (t+ornt)%tmpSize : (-(ornt+1) + tmpSize-t)%tmpSize; 24989bf0dad6SMatthew G. Knepley closure[closureSize] = tmp[i]; 24999bf0dad6SMatthew G. Knepley closure[closureSize+1] = tmpO ? tmpO[i] : 0; 25009bf0dad6SMatthew G. Knepley } 25019bf0dad6SMatthew G. Knepley if (numPoints) *numPoints = closureSize/2; 25029bf0dad6SMatthew G. Knepley if (points) *points = closure; 25039bf0dad6SMatthew G. Knepley PetscFunctionReturn(0); 25049bf0dad6SMatthew G. Knepley } 250524c766afSToby Isaac { 250624c766afSToby Isaac PetscInt c, coneSeries, s,supportSeries; 250724c766afSToby Isaac 250824c766afSToby Isaac c = mesh->maxConeSize; 250924c766afSToby Isaac coneSeries = (c > 1) ? ((PetscPowInt(c,depth+1)-1)/(c-1)) : depth+1; 251024c766afSToby Isaac s = mesh->maxSupportSize; 251124c766afSToby Isaac supportSeries = (s > 1) ? ((PetscPowInt(s,depth+1)-1)/(s-1)) : depth+1; 251224c766afSToby Isaac maxSize = 2*PetscMax(coneSeries,supportSeries); 251324c766afSToby Isaac } 251469291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &fifo);CHKERRQ(ierr); 25159bf0dad6SMatthew G. Knepley if (*points) { 25169bf0dad6SMatthew G. Knepley closure = *points; 25179bf0dad6SMatthew G. Knepley } else { 251869291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &closure);CHKERRQ(ierr); 25199bf0dad6SMatthew G. Knepley } 25209bf0dad6SMatthew G. Knepley closure[0] = p; closure[1] = ornt; 25219bf0dad6SMatthew G. Knepley for (t = 0; t < tmpSize; ++t, closureSize += 2, fifoSize += 2) { 25229bf0dad6SMatthew G. Knepley const PetscInt i = ornt >= 0 ? (t+ornt)%tmpSize : (-(ornt+1) + tmpSize-t)%tmpSize; 25239bf0dad6SMatthew G. Knepley const PetscInt cp = tmp[i]; 25249bf0dad6SMatthew G. Knepley PetscInt co = tmpO ? tmpO[i] : 0; 25259bf0dad6SMatthew G. Knepley 25269bf0dad6SMatthew G. Knepley if (ornt < 0) { 25279bf0dad6SMatthew G. Knepley PetscInt childSize, coff; 25289bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, cp, &childSize);CHKERRQ(ierr); 252986b63641SMatthew G. Knepley coff = co < 0 ? -(tmpO[i]+1) : tmpO[i]; 25309bf0dad6SMatthew G. Knepley co = childSize ? -(((coff+childSize-1)%childSize)+1) : 0; 25319bf0dad6SMatthew G. Knepley } 25329bf0dad6SMatthew G. Knepley closure[closureSize] = cp; 25339bf0dad6SMatthew G. Knepley closure[closureSize+1] = co; 25349bf0dad6SMatthew G. Knepley fifo[fifoSize] = cp; 25359bf0dad6SMatthew G. Knepley fifo[fifoSize+1] = co; 25369bf0dad6SMatthew G. Knepley } 25379bf0dad6SMatthew G. Knepley /* Should kick out early when depth is reached, rather than checking all vertices for empty cones */ 25389bf0dad6SMatthew G. Knepley while (fifoSize - fifoStart) { 25399bf0dad6SMatthew G. Knepley const PetscInt q = fifo[fifoStart]; 25409bf0dad6SMatthew G. Knepley const PetscInt o = fifo[fifoStart+1]; 25419bf0dad6SMatthew G. Knepley const PetscInt rev = o >= 0 ? 0 : 1; 25429bf0dad6SMatthew G. Knepley const PetscInt off = rev ? -(o+1) : o; 25439bf0dad6SMatthew G. Knepley 25449bf0dad6SMatthew G. Knepley if (useCone) { 25459bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, q, &tmpSize);CHKERRQ(ierr); 25469bf0dad6SMatthew G. Knepley ierr = DMPlexGetCone(dm, q, &tmp);CHKERRQ(ierr); 25479bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, q, &tmpO);CHKERRQ(ierr); 25489bf0dad6SMatthew G. Knepley } else { 25499bf0dad6SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, q, &tmpSize);CHKERRQ(ierr); 25509bf0dad6SMatthew G. Knepley ierr = DMPlexGetSupport(dm, q, &tmp);CHKERRQ(ierr); 25519bf0dad6SMatthew G. Knepley tmpO = NULL; 25529bf0dad6SMatthew G. Knepley } 25539bf0dad6SMatthew G. Knepley for (t = 0; t < tmpSize; ++t) { 25549bf0dad6SMatthew G. Knepley const PetscInt i = ((rev ? tmpSize-t : t) + off)%tmpSize; 25559bf0dad6SMatthew G. Knepley const PetscInt cp = tmp[i]; 25569bf0dad6SMatthew 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. */ 25579bf0dad6SMatthew G. Knepley /* HACK: It is worse to get the size here, than to change the interpretation of -(*+1) 25589bf0dad6SMatthew G. Knepley const PetscInt co = tmpO ? (rev ? -(tmpO[i]+1) : tmpO[i]) : 0; */ 25599bf0dad6SMatthew G. Knepley PetscInt co = tmpO ? tmpO[i] : 0; 25609bf0dad6SMatthew G. Knepley PetscInt c; 25619bf0dad6SMatthew G. Knepley 25629bf0dad6SMatthew G. Knepley if (rev) { 25639bf0dad6SMatthew G. Knepley PetscInt childSize, coff; 25649bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, cp, &childSize);CHKERRQ(ierr); 25659bf0dad6SMatthew G. Knepley coff = tmpO[i] < 0 ? -(tmpO[i]+1) : tmpO[i]; 25669bf0dad6SMatthew G. Knepley co = childSize ? -(((coff+childSize-1)%childSize)+1) : 0; 25679bf0dad6SMatthew G. Knepley } 25689bf0dad6SMatthew G. Knepley /* Check for duplicate */ 25699bf0dad6SMatthew G. Knepley for (c = 0; c < closureSize; c += 2) { 25709bf0dad6SMatthew G. Knepley if (closure[c] == cp) break; 25719bf0dad6SMatthew G. Knepley } 25729bf0dad6SMatthew G. Knepley if (c == closureSize) { 25739bf0dad6SMatthew G. Knepley closure[closureSize] = cp; 25749bf0dad6SMatthew G. Knepley closure[closureSize+1] = co; 25759bf0dad6SMatthew G. Knepley fifo[fifoSize] = cp; 25769bf0dad6SMatthew G. Knepley fifo[fifoSize+1] = co; 25779bf0dad6SMatthew G. Knepley closureSize += 2; 25789bf0dad6SMatthew G. Knepley fifoSize += 2; 25799bf0dad6SMatthew G. Knepley } 25809bf0dad6SMatthew G. Knepley } 25819bf0dad6SMatthew G. Knepley fifoStart += 2; 25829bf0dad6SMatthew G. Knepley } 25839bf0dad6SMatthew G. Knepley if (numPoints) *numPoints = closureSize/2; 25849bf0dad6SMatthew G. Knepley if (points) *points = closure; 258569291d52SBarry Smith ierr = DMRestoreWorkArray(dm, maxSize, MPIU_INT, &fifo);CHKERRQ(ierr); 25869bf0dad6SMatthew G. Knepley PetscFunctionReturn(0); 25879bf0dad6SMatthew G. Knepley } 25889bf0dad6SMatthew G. Knepley 2589552f7358SJed Brown /*@C 2590eaf898f9SPatrick Sanan DMPlexRestoreTransitiveClosure - Restore the array of points on the transitive closure of the in-edges or out-edges for this point in the DAG 2591552f7358SJed Brown 2592552f7358SJed Brown Not collective 2593552f7358SJed Brown 2594552f7358SJed Brown Input Parameters: 2595552f7358SJed Brown + mesh - The DMPlex 2596eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 2597552f7358SJed Brown . useCone - PETSC_TRUE for in-edges, otherwise use out-edges 2598e5c84f05SJed Brown . numPoints - The number of points in the closure, so points[] is of size 2*numPoints, zeroed on exit 2599e5c84f05SJed Brown - points - The points and point orientations, interleaved as pairs [p0, o0, p1, o1, ...], zeroed on exit 2600552f7358SJed Brown 2601552f7358SJed Brown Note: 26020298fd71SBarry Smith If not using internal storage (points is not NULL on input), this call is unnecessary 2603552f7358SJed Brown 26043813dfbdSMatthew G Knepley Fortran Notes: 26053813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 26063813dfbdSMatthew G Knepley include petsc.h90 in your code. 26073813dfbdSMatthew G Knepley 26083813dfbdSMatthew G Knepley The numPoints argument is not present in the Fortran 90 binding since it is internal to the array. 26093813dfbdSMatthew G Knepley 2610552f7358SJed Brown Level: beginner 2611552f7358SJed Brown 2612552f7358SJed Brown .seealso: DMPlexGetTransitiveClosure(), DMPlexCreate(), DMPlexSetCone(), DMPlexSetChart(), DMPlexGetCone() 2613552f7358SJed Brown @*/ 2614552f7358SJed Brown PetscErrorCode DMPlexRestoreTransitiveClosure(DM dm, PetscInt p, PetscBool useCone, PetscInt *numPoints, PetscInt *points[]) 2615552f7358SJed Brown { 2616552f7358SJed Brown PetscErrorCode ierr; 2617552f7358SJed Brown 2618552f7358SJed Brown PetscFunctionBegin; 2619552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2620e5c84f05SJed Brown if (numPoints) PetscValidIntPointer(numPoints,4); 2621e5c84f05SJed Brown if (points) PetscValidPointer(points,5); 262269291d52SBarry Smith ierr = DMRestoreWorkArray(dm, 0, MPIU_INT, points);CHKERRQ(ierr); 26234ff43b2cSJed Brown if (numPoints) *numPoints = 0; 2624552f7358SJed Brown PetscFunctionReturn(0); 2625552f7358SJed Brown } 2626552f7358SJed Brown 2627552f7358SJed Brown /*@ 2628eaf898f9SPatrick Sanan DMPlexGetMaxSizes - Return the maximum number of in-edges (cone) and out-edges (support) for any point in the DAG 2629552f7358SJed Brown 2630552f7358SJed Brown Not collective 2631552f7358SJed Brown 2632552f7358SJed Brown Input Parameter: 2633552f7358SJed Brown . mesh - The DMPlex 2634552f7358SJed Brown 2635552f7358SJed Brown Output Parameters: 2636552f7358SJed Brown + maxConeSize - The maximum number of in-edges 2637552f7358SJed Brown - maxSupportSize - The maximum number of out-edges 2638552f7358SJed Brown 2639552f7358SJed Brown Level: beginner 2640552f7358SJed Brown 2641552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetConeSize(), DMPlexSetChart() 2642552f7358SJed Brown @*/ 2643552f7358SJed Brown PetscErrorCode DMPlexGetMaxSizes(DM dm, PetscInt *maxConeSize, PetscInt *maxSupportSize) 2644552f7358SJed Brown { 2645552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2646552f7358SJed Brown 2647552f7358SJed Brown PetscFunctionBegin; 2648552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2649552f7358SJed Brown if (maxConeSize) *maxConeSize = mesh->maxConeSize; 2650552f7358SJed Brown if (maxSupportSize) *maxSupportSize = mesh->maxSupportSize; 2651552f7358SJed Brown PetscFunctionReturn(0); 2652552f7358SJed Brown } 2653552f7358SJed Brown 2654552f7358SJed Brown PetscErrorCode DMSetUp_Plex(DM dm) 2655552f7358SJed Brown { 2656552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2657552f7358SJed Brown PetscInt size; 2658552f7358SJed Brown PetscErrorCode ierr; 2659552f7358SJed Brown 2660552f7358SJed Brown PetscFunctionBegin; 2661552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2662552f7358SJed Brown ierr = PetscSectionSetUp(mesh->coneSection);CHKERRQ(ierr); 2663552f7358SJed Brown ierr = PetscSectionGetStorageSize(mesh->coneSection, &size);CHKERRQ(ierr); 26641795a4d1SJed Brown ierr = PetscMalloc1(size, &mesh->cones);CHKERRQ(ierr); 26651795a4d1SJed Brown ierr = PetscCalloc1(size, &mesh->coneOrientations);CHKERRQ(ierr); 2666552f7358SJed Brown if (mesh->maxSupportSize) { 2667552f7358SJed Brown ierr = PetscSectionSetUp(mesh->supportSection);CHKERRQ(ierr); 2668552f7358SJed Brown ierr = PetscSectionGetStorageSize(mesh->supportSection, &size);CHKERRQ(ierr); 26691795a4d1SJed Brown ierr = PetscMalloc1(size, &mesh->supports);CHKERRQ(ierr); 2670552f7358SJed Brown } 2671552f7358SJed Brown PetscFunctionReturn(0); 2672552f7358SJed Brown } 2673552f7358SJed Brown 2674276c5506SMatthew G. Knepley PetscErrorCode DMCreateSubDM_Plex(DM dm, PetscInt numFields, const PetscInt fields[], IS *is, DM *subdm) 2675552f7358SJed Brown { 2676552f7358SJed Brown PetscErrorCode ierr; 2677552f7358SJed Brown 2678552f7358SJed Brown PetscFunctionBegin; 26794d9407bcSMatthew G. Knepley if (subdm) {ierr = DMClone(dm, subdm);CHKERRQ(ierr);} 2680792b654fSMatthew G. Knepley ierr = DMCreateSectionSubDM(dm, numFields, fields, is, subdm);CHKERRQ(ierr); 2681c2939958SSatish Balay if (subdm) {(*subdm)->useNatural = dm->useNatural;} 2682736995cdSBlaise Bourdin if (dm->useNatural && dm->sfMigration) { 2683f94b4a02SBlaise Bourdin PetscSF sfMigrationInv,sfNatural; 2684f94b4a02SBlaise Bourdin PetscSection section, sectionSeq; 2685f94b4a02SBlaise Bourdin 26863dcd263cSBlaise Bourdin (*subdm)->sfMigration = dm->sfMigration; 26873dcd263cSBlaise Bourdin ierr = PetscObjectReference((PetscObject) dm->sfMigration);CHKERRQ(ierr); 268892fd8e1eSJed Brown ierr = DMGetLocalSection((*subdm), §ion);CHKERRQ(ierr);CHKERRQ(ierr); 2689f94b4a02SBlaise Bourdin ierr = PetscSFCreateInverseSF((*subdm)->sfMigration, &sfMigrationInv);CHKERRQ(ierr); 2690f94b4a02SBlaise Bourdin ierr = PetscSectionCreate(PetscObjectComm((PetscObject) (*subdm)), §ionSeq);CHKERRQ(ierr); 2691f94b4a02SBlaise Bourdin ierr = PetscSFDistributeSection(sfMigrationInv, section, NULL, sectionSeq);CHKERRQ(ierr); 2692f94b4a02SBlaise Bourdin 2693f94b4a02SBlaise Bourdin ierr = DMPlexCreateGlobalToNaturalSF(*subdm, sectionSeq, (*subdm)->sfMigration, &sfNatural);CHKERRQ(ierr); 2694c40e9495SBlaise Bourdin (*subdm)->sfNatural = sfNatural; 2695f94b4a02SBlaise Bourdin ierr = PetscSectionDestroy(§ionSeq);CHKERRQ(ierr); 2696f94b4a02SBlaise Bourdin ierr = PetscSFDestroy(&sfMigrationInv);CHKERRQ(ierr); 2697f94b4a02SBlaise Bourdin } 2698552f7358SJed Brown PetscFunctionReturn(0); 2699552f7358SJed Brown } 2700552f7358SJed Brown 27012adcc780SMatthew G. Knepley PetscErrorCode DMCreateSuperDM_Plex(DM dms[], PetscInt len, IS **is, DM *superdm) 27022adcc780SMatthew G. Knepley { 27032adcc780SMatthew G. Knepley PetscErrorCode ierr; 27043dcd263cSBlaise Bourdin PetscInt i = 0; 27052adcc780SMatthew G. Knepley 27062adcc780SMatthew G. Knepley PetscFunctionBegin; 2707435bcee1SStefano Zampini ierr = DMClone(dms[0], superdm);CHKERRQ(ierr); 2708792b654fSMatthew G. Knepley ierr = DMCreateSectionSuperDM(dms, len, is, superdm);CHKERRQ(ierr); 2709c40e9495SBlaise Bourdin (*superdm)->useNatural = PETSC_FALSE; 27103dcd263cSBlaise Bourdin for (i = 0; i < len; i++){ 27113dcd263cSBlaise Bourdin if (dms[i]->useNatural && dms[i]->sfMigration) { 27123dcd263cSBlaise Bourdin PetscSF sfMigrationInv,sfNatural; 27133dcd263cSBlaise Bourdin PetscSection section, sectionSeq; 27143dcd263cSBlaise Bourdin 27153dcd263cSBlaise Bourdin (*superdm)->sfMigration = dms[i]->sfMigration; 27163dcd263cSBlaise Bourdin ierr = PetscObjectReference((PetscObject) dms[i]->sfMigration);CHKERRQ(ierr); 2717c40e9495SBlaise Bourdin (*superdm)->useNatural = PETSC_TRUE; 271892fd8e1eSJed Brown ierr = DMGetLocalSection((*superdm), §ion);CHKERRQ(ierr); 27193dcd263cSBlaise Bourdin ierr = PetscSFCreateInverseSF((*superdm)->sfMigration, &sfMigrationInv);CHKERRQ(ierr); 27203dcd263cSBlaise Bourdin ierr = PetscSectionCreate(PetscObjectComm((PetscObject) (*superdm)), §ionSeq);CHKERRQ(ierr); 27213dcd263cSBlaise Bourdin ierr = PetscSFDistributeSection(sfMigrationInv, section, NULL, sectionSeq);CHKERRQ(ierr); 27223dcd263cSBlaise Bourdin 27233dcd263cSBlaise Bourdin ierr = DMPlexCreateGlobalToNaturalSF(*superdm, sectionSeq, (*superdm)->sfMigration, &sfNatural);CHKERRQ(ierr); 2724c40e9495SBlaise Bourdin (*superdm)->sfNatural = sfNatural; 27253dcd263cSBlaise Bourdin ierr = PetscSectionDestroy(§ionSeq);CHKERRQ(ierr); 27263dcd263cSBlaise Bourdin ierr = PetscSFDestroy(&sfMigrationInv);CHKERRQ(ierr); 27273dcd263cSBlaise Bourdin break; 27283dcd263cSBlaise Bourdin } 27293dcd263cSBlaise Bourdin } 27302adcc780SMatthew G. Knepley PetscFunctionReturn(0); 27312adcc780SMatthew G. Knepley } 27322adcc780SMatthew G. Knepley 2733552f7358SJed Brown /*@ 2734eaf898f9SPatrick Sanan DMPlexSymmetrize - Create support (out-edge) information from cone (in-edge) information 2735552f7358SJed Brown 2736552f7358SJed Brown Not collective 2737552f7358SJed Brown 2738552f7358SJed Brown Input Parameter: 2739552f7358SJed Brown . mesh - The DMPlex 2740552f7358SJed Brown 2741552f7358SJed Brown Output Parameter: 2742552f7358SJed Brown 2743552f7358SJed Brown Note: 2744552f7358SJed Brown This should be called after all calls to DMPlexSetCone() 2745552f7358SJed Brown 2746552f7358SJed Brown Level: beginner 2747552f7358SJed Brown 2748552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetChart(), DMPlexSetConeSize(), DMPlexSetCone() 2749552f7358SJed Brown @*/ 2750552f7358SJed Brown PetscErrorCode DMPlexSymmetrize(DM dm) 2751552f7358SJed Brown { 2752552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2753552f7358SJed Brown PetscInt *offsets; 2754552f7358SJed Brown PetscInt supportSize; 2755552f7358SJed Brown PetscInt pStart, pEnd, p; 2756552f7358SJed Brown PetscErrorCode ierr; 2757552f7358SJed Brown 2758552f7358SJed Brown PetscFunctionBegin; 2759552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 276082f516ccSBarry Smith if (mesh->supports) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Supports were already setup in this DMPlex"); 276130b0ce1bSStefano Zampini ierr = PetscLogEventBegin(DMPLEX_Symmetrize,dm,0,0,0);CHKERRQ(ierr); 2762552f7358SJed Brown /* Calculate support sizes */ 2763552f7358SJed Brown ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 2764552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 2765552f7358SJed Brown PetscInt dof, off, c; 2766552f7358SJed Brown 2767552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 2768552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 2769552f7358SJed Brown for (c = off; c < off+dof; ++c) { 2770552f7358SJed Brown ierr = PetscSectionAddDof(mesh->supportSection, mesh->cones[c], 1);CHKERRQ(ierr); 2771552f7358SJed Brown } 2772552f7358SJed Brown } 2773552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 2774552f7358SJed Brown PetscInt dof; 2775552f7358SJed Brown 2776552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, &dof);CHKERRQ(ierr); 27770d644c17SKarl Rupp 2778552f7358SJed Brown mesh->maxSupportSize = PetscMax(mesh->maxSupportSize, dof); 2779552f7358SJed Brown } 2780552f7358SJed Brown ierr = PetscSectionSetUp(mesh->supportSection);CHKERRQ(ierr); 2781552f7358SJed Brown /* Calculate supports */ 2782552f7358SJed Brown ierr = PetscSectionGetStorageSize(mesh->supportSection, &supportSize);CHKERRQ(ierr); 27831795a4d1SJed Brown ierr = PetscMalloc1(supportSize, &mesh->supports);CHKERRQ(ierr); 27841795a4d1SJed Brown ierr = PetscCalloc1(pEnd - pStart, &offsets);CHKERRQ(ierr); 2785552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 2786552f7358SJed Brown PetscInt dof, off, c; 2787552f7358SJed Brown 2788552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 2789552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 2790552f7358SJed Brown for (c = off; c < off+dof; ++c) { 2791552f7358SJed Brown const PetscInt q = mesh->cones[c]; 2792552f7358SJed Brown PetscInt offS; 2793552f7358SJed Brown 2794552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, q, &offS);CHKERRQ(ierr); 27950d644c17SKarl Rupp 2796552f7358SJed Brown mesh->supports[offS+offsets[q]] = p; 2797552f7358SJed Brown ++offsets[q]; 2798552f7358SJed Brown } 2799552f7358SJed Brown } 2800552f7358SJed Brown ierr = PetscFree(offsets);CHKERRQ(ierr); 280130b0ce1bSStefano Zampini ierr = PetscLogEventEnd(DMPLEX_Symmetrize,dm,0,0,0);CHKERRQ(ierr); 2802552f7358SJed Brown PetscFunctionReturn(0); 2803552f7358SJed Brown } 2804552f7358SJed Brown 2805277ea44aSLisandro Dalcin static PetscErrorCode DMPlexCreateDepthStratum(DM dm, DMLabel label, PetscInt depth, PetscInt pStart, PetscInt pEnd) 2806277ea44aSLisandro Dalcin { 2807277ea44aSLisandro Dalcin IS stratumIS; 2808277ea44aSLisandro Dalcin PetscErrorCode ierr; 2809277ea44aSLisandro Dalcin 2810277ea44aSLisandro Dalcin PetscFunctionBegin; 2811277ea44aSLisandro Dalcin if (pStart >= pEnd) PetscFunctionReturn(0); 2812277ea44aSLisandro Dalcin #if defined(PETSC_USE_DEBUG) 2813277ea44aSLisandro Dalcin { 2814277ea44aSLisandro Dalcin PetscInt qStart, qEnd, numLevels, level; 2815277ea44aSLisandro Dalcin PetscBool overlap = PETSC_FALSE; 2816277ea44aSLisandro Dalcin ierr = DMLabelGetNumValues(label, &numLevels);CHKERRQ(ierr); 2817277ea44aSLisandro Dalcin for (level = 0; level < numLevels; level++) { 2818277ea44aSLisandro Dalcin ierr = DMLabelGetStratumBounds(label, level, &qStart, &qEnd);CHKERRQ(ierr); 2819277ea44aSLisandro Dalcin if ((pStart >= qStart && pStart < qEnd) || (pEnd > qStart && pEnd <= qEnd)) {overlap = PETSC_TRUE; break;} 2820277ea44aSLisandro Dalcin } 2821277ea44aSLisandro Dalcin if (overlap) SETERRQ6(PETSC_COMM_SELF, PETSC_ERR_PLIB, "New depth %D range [%D,%D) overlaps with depth %D range [%D,%D)", depth, pStart, pEnd, level, qStart, qEnd); 2822277ea44aSLisandro Dalcin } 2823277ea44aSLisandro Dalcin #endif 2824277ea44aSLisandro Dalcin ierr = ISCreateStride(PETSC_COMM_SELF, pEnd-pStart, pStart, 1, &stratumIS);CHKERRQ(ierr); 2825277ea44aSLisandro Dalcin ierr = DMLabelSetStratumIS(label, depth, stratumIS);CHKERRQ(ierr); 2826277ea44aSLisandro Dalcin ierr = ISDestroy(&stratumIS);CHKERRQ(ierr); 2827277ea44aSLisandro Dalcin PetscFunctionReturn(0); 2828277ea44aSLisandro Dalcin } 2829277ea44aSLisandro Dalcin 28307d5acc75SStefano Zampini static PetscErrorCode DMPlexCreateDimStratum(DM,DMLabel,DMLabel,PetscInt,PetscInt); 28317d5acc75SStefano Zampini 2832552f7358SJed Brown /*@ 2833a8d69d7bSBarry Smith DMPlexStratify - The DAG for most topologies is a graded poset (https://en.wikipedia.org/wiki/Graded_poset), and 28346dd80730SBarry Smith can be illustrated by a Hasse Diagram (https://en.wikipedia.org/wiki/Hasse_diagram). The strata group all points of the 2835552f7358SJed Brown same grade, and this function calculates the strata. This grade can be seen as the height (or depth) of the point in 2836552f7358SJed Brown the DAG. 2837552f7358SJed Brown 2838bf4602e4SToby Isaac Collective on dm 2839552f7358SJed Brown 2840552f7358SJed Brown Input Parameter: 2841552f7358SJed Brown . mesh - The DMPlex 2842552f7358SJed Brown 2843552f7358SJed Brown Output Parameter: 2844552f7358SJed Brown 2845552f7358SJed Brown Notes: 2846b1bb481bSMatthew Knepley Concretely, DMPlexStratify() creates a new label named "depth" containing the depth in the DAG of each point. For cell-vertex 2847b1bb481bSMatthew Knepley meshes, vertices are depth 0 and cells are depth 1. For fully interpolated meshes, depth 0 for vertices, 1 for edges, and so on 2848b1bb481bSMatthew Knepley until cells have depth equal to the dimension of the mesh. The depth label can be accessed through DMPlexGetDepthLabel() or DMPlexGetDepthStratum(), or 2849c58f1c22SToby Isaac manually via DMGetLabel(). The height is defined implicitly by height = maxDimension - depth, and can be accessed 2850150b719bSJed Brown via DMPlexGetHeightStratum(). For example, cells have height 0 and faces have height 1. 2851552f7358SJed Brown 2852b1bb481bSMatthew Knepley The depth of a point is calculated by executing a breadth-first search (BFS) on the DAG. This could produce surprising results 2853b1bb481bSMatthew Knepley if run on a partially interpolated mesh, meaning one that had some edges and faces, but not others. For example, suppose that 2854b1bb481bSMatthew Knepley we had a mesh consisting of one triangle (c0) and three vertices (v0, v1, v2), and only one edge is on the boundary so we choose 2855b1bb481bSMatthew Knepley to interpolate only that one (e0), so that 2856b1bb481bSMatthew Knepley $ cone(c0) = {e0, v2} 2857b1bb481bSMatthew Knepley $ cone(e0) = {v0, v1} 2858b1bb481bSMatthew Knepley If DMPlexStratify() is run on this mesh, it will give depths 2859b1bb481bSMatthew Knepley $ depth 0 = {v0, v1, v2} 2860b1bb481bSMatthew Knepley $ depth 1 = {e0, c0} 2861b1bb481bSMatthew Knepley where the triangle has been given depth 1, instead of 2, because it is reachable from vertex v2. 2862b1bb481bSMatthew Knepley 2863150b719bSJed Brown DMPlexStratify() should be called after all calls to DMPlexSymmetrize() 2864552f7358SJed Brown 2865552f7358SJed Brown Level: beginner 2866552f7358SJed Brown 2867552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSymmetrize() 2868552f7358SJed Brown @*/ 2869552f7358SJed Brown PetscErrorCode DMPlexStratify(DM dm) 2870552f7358SJed Brown { 2871df0420ecSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 2872aa50250dSMatthew G. Knepley DMLabel label; 2873552f7358SJed Brown PetscInt pStart, pEnd, p; 2874552f7358SJed Brown PetscInt numRoots = 0, numLeaves = 0; 28757d5acc75SStefano Zampini PetscInt cMax, fMax, eMax, vMax; 2876552f7358SJed Brown PetscErrorCode ierr; 2877552f7358SJed Brown 2878552f7358SJed Brown PetscFunctionBegin; 2879552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2880552f7358SJed Brown ierr = PetscLogEventBegin(DMPLEX_Stratify,dm,0,0,0);CHKERRQ(ierr); 2881277ea44aSLisandro Dalcin 2882277ea44aSLisandro Dalcin /* Create depth label */ 2883aa50250dSMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 2884c58f1c22SToby Isaac ierr = DMCreateLabel(dm, "depth");CHKERRQ(ierr); 2885aa50250dSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 2886277ea44aSLisandro Dalcin 2887277ea44aSLisandro Dalcin { 2888552f7358SJed Brown /* Initialize roots and count leaves */ 2889277ea44aSLisandro Dalcin PetscInt sMin = PETSC_MAX_INT; 2890277ea44aSLisandro Dalcin PetscInt sMax = PETSC_MIN_INT; 2891552f7358SJed Brown PetscInt coneSize, supportSize; 2892552f7358SJed Brown 2893277ea44aSLisandro Dalcin for (p = pStart; p < pEnd; ++p) { 2894552f7358SJed Brown ierr = DMPlexGetConeSize(dm, p, &coneSize);CHKERRQ(ierr); 2895552f7358SJed Brown ierr = DMPlexGetSupportSize(dm, p, &supportSize);CHKERRQ(ierr); 2896552f7358SJed Brown if (!coneSize && supportSize) { 2897277ea44aSLisandro Dalcin sMin = PetscMin(p, sMin); 2898277ea44aSLisandro Dalcin sMax = PetscMax(p, sMax); 2899552f7358SJed Brown ++numRoots; 2900552f7358SJed Brown } else if (!supportSize && coneSize) { 2901552f7358SJed Brown ++numLeaves; 2902552f7358SJed Brown } else if (!supportSize && !coneSize) { 2903552f7358SJed Brown /* Isolated points */ 2904277ea44aSLisandro Dalcin sMin = PetscMin(p, sMin); 2905277ea44aSLisandro Dalcin sMax = PetscMax(p, sMax); 2906552f7358SJed Brown } 2907552f7358SJed Brown } 2908277ea44aSLisandro Dalcin ierr = DMPlexCreateDepthStratum(dm, label, 0, sMin, sMax+1);CHKERRQ(ierr); 2909277ea44aSLisandro Dalcin } 2910277ea44aSLisandro Dalcin 2911552f7358SJed Brown if (numRoots + numLeaves == (pEnd - pStart)) { 2912277ea44aSLisandro Dalcin PetscInt sMin = PETSC_MAX_INT; 2913277ea44aSLisandro Dalcin PetscInt sMax = PETSC_MIN_INT; 2914552f7358SJed Brown PetscInt coneSize, supportSize; 2915552f7358SJed Brown 2916277ea44aSLisandro Dalcin for (p = pStart; p < pEnd; ++p) { 2917552f7358SJed Brown ierr = DMPlexGetConeSize(dm, p, &coneSize);CHKERRQ(ierr); 2918552f7358SJed Brown ierr = DMPlexGetSupportSize(dm, p, &supportSize);CHKERRQ(ierr); 2919552f7358SJed Brown if (!supportSize && coneSize) { 2920277ea44aSLisandro Dalcin sMin = PetscMin(p, sMin); 2921277ea44aSLisandro Dalcin sMax = PetscMax(p, sMax); 2922552f7358SJed Brown } 2923552f7358SJed Brown } 2924277ea44aSLisandro Dalcin ierr = DMPlexCreateDepthStratum(dm, label, 1, sMin, sMax+1);CHKERRQ(ierr); 2925552f7358SJed Brown } else { 2926277ea44aSLisandro Dalcin PetscInt level = 0; 2927277ea44aSLisandro Dalcin PetscInt qStart, qEnd, q; 2928552f7358SJed Brown 2929277ea44aSLisandro Dalcin ierr = DMLabelGetStratumBounds(label, level, &qStart, &qEnd);CHKERRQ(ierr); 2930277ea44aSLisandro Dalcin while (qEnd > qStart) { 2931277ea44aSLisandro Dalcin PetscInt sMin = PETSC_MAX_INT; 2932277ea44aSLisandro Dalcin PetscInt sMax = PETSC_MIN_INT; 293374ef644bSMatthew G. Knepley 2934277ea44aSLisandro Dalcin for (q = qStart; q < qEnd; ++q) { 293574ef644bSMatthew G. Knepley const PetscInt *support; 293674ef644bSMatthew G. Knepley PetscInt supportSize, s; 293774ef644bSMatthew G. Knepley 2938277ea44aSLisandro Dalcin ierr = DMPlexGetSupportSize(dm, q, &supportSize);CHKERRQ(ierr); 2939277ea44aSLisandro Dalcin ierr = DMPlexGetSupport(dm, q, &support);CHKERRQ(ierr); 294074ef644bSMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 2941277ea44aSLisandro Dalcin sMin = PetscMin(support[s], sMin); 2942277ea44aSLisandro Dalcin sMax = PetscMax(support[s], sMax); 2943552f7358SJed Brown } 2944552f7358SJed Brown } 2945277ea44aSLisandro Dalcin ierr = DMLabelGetNumValues(label, &level);CHKERRQ(ierr); 2946277ea44aSLisandro Dalcin ierr = DMPlexCreateDepthStratum(dm, label, level, sMin, sMax+1);CHKERRQ(ierr); 2947277ea44aSLisandro Dalcin ierr = DMLabelGetStratumBounds(label, level, &qStart, &qEnd);CHKERRQ(ierr); 294874ef644bSMatthew G. Knepley } 294974ef644bSMatthew G. Knepley } 2950bf4602e4SToby Isaac { /* just in case there is an empty process */ 2951bf4602e4SToby Isaac PetscInt numValues, maxValues = 0, v; 2952bf4602e4SToby Isaac 2953bf4602e4SToby Isaac ierr = DMLabelGetNumValues(label, &numValues);CHKERRQ(ierr); 29546d1e82d3SBarry Smith ierr = MPI_Allreduce(&numValues,&maxValues,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 2955bf4602e4SToby Isaac for (v = numValues; v < maxValues; v++) { 2956367003a6SStefano Zampini ierr = DMLabelAddStratum(label, v);CHKERRQ(ierr); 2957bf4602e4SToby Isaac } 2958bf4602e4SToby Isaac } 2959d67d17b1SMatthew G. Knepley ierr = PetscObjectStateGet((PetscObject) label, &mesh->depthState);CHKERRQ(ierr); 29607d5acc75SStefano Zampini 29617d5acc75SStefano Zampini ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 29627d5acc75SStefano Zampini if (cMax >= 0 || fMax >= 0 || eMax >= 0 || vMax >= 0) { 29637d5acc75SStefano Zampini PetscInt dim; 2964277ea44aSLisandro Dalcin DMLabel dimLabel; 29657d5acc75SStefano Zampini 29667d5acc75SStefano Zampini ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 29677d5acc75SStefano Zampini ierr = DMCreateLabel(dm, "dim");CHKERRQ(ierr); 29687d5acc75SStefano Zampini ierr = DMGetLabel(dm, "dim", &dimLabel);CHKERRQ(ierr); 29697d5acc75SStefano Zampini if (cMax >= 0) {ierr = DMPlexCreateDimStratum(dm, label, dimLabel, dim, cMax);CHKERRQ(ierr);} 29707d5acc75SStefano Zampini if (fMax >= 0) {ierr = DMPlexCreateDimStratum(dm, label, dimLabel, dim - 1, fMax);CHKERRQ(ierr);} 29717d5acc75SStefano Zampini if (eMax >= 0) {ierr = DMPlexCreateDimStratum(dm, label, dimLabel, 1, eMax);CHKERRQ(ierr);} 29727d5acc75SStefano Zampini if (vMax >= 0) {ierr = DMPlexCreateDimStratum(dm, label, dimLabel, 0, vMax);CHKERRQ(ierr);} 29737d5acc75SStefano Zampini } 2974552f7358SJed Brown ierr = PetscLogEventEnd(DMPLEX_Stratify,dm,0,0,0);CHKERRQ(ierr); 2975552f7358SJed Brown PetscFunctionReturn(0); 2976552f7358SJed Brown } 2977552f7358SJed Brown 2978552f7358SJed Brown /*@C 2979552f7358SJed Brown DMPlexGetJoin - Get an array for the join of the set of points 2980552f7358SJed Brown 2981552f7358SJed Brown Not Collective 2982552f7358SJed Brown 2983552f7358SJed Brown Input Parameters: 2984552f7358SJed Brown + dm - The DMPlex object 2985552f7358SJed Brown . numPoints - The number of input points for the join 2986552f7358SJed Brown - points - The input points 2987552f7358SJed Brown 2988552f7358SJed Brown Output Parameters: 2989552f7358SJed Brown + numCoveredPoints - The number of points in the join 2990552f7358SJed Brown - coveredPoints - The points in the join 2991552f7358SJed Brown 2992552f7358SJed Brown Level: intermediate 2993552f7358SJed Brown 2994552f7358SJed Brown Note: Currently, this is restricted to a single level join 2995552f7358SJed Brown 29963813dfbdSMatthew G Knepley Fortran Notes: 29973813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 29983813dfbdSMatthew G Knepley include petsc.h90 in your code. 29993813dfbdSMatthew G Knepley 30003813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 30013813dfbdSMatthew G Knepley 3002552f7358SJed Brown .seealso: DMPlexRestoreJoin(), DMPlexGetMeet() 3003552f7358SJed Brown @*/ 3004552f7358SJed Brown PetscErrorCode DMPlexGetJoin(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 3005552f7358SJed Brown { 3006552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3007552f7358SJed Brown PetscInt *join[2]; 3008552f7358SJed Brown PetscInt joinSize, i = 0; 3009552f7358SJed Brown PetscInt dof, off, p, c, m; 3010552f7358SJed Brown PetscErrorCode ierr; 3011552f7358SJed Brown 3012552f7358SJed Brown PetscFunctionBegin; 3013552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 301448bb261cSVaclav Hapla PetscValidIntPointer(points, 3); 301548bb261cSVaclav Hapla PetscValidIntPointer(numCoveredPoints, 4); 301648bb261cSVaclav Hapla PetscValidPointer(coveredPoints, 5); 301769291d52SBarry Smith ierr = DMGetWorkArray(dm, mesh->maxSupportSize, MPIU_INT, &join[0]);CHKERRQ(ierr); 301869291d52SBarry Smith ierr = DMGetWorkArray(dm, mesh->maxSupportSize, MPIU_INT, &join[1]);CHKERRQ(ierr); 3019552f7358SJed Brown /* Copy in support of first point */ 3020552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, points[0], &dof);CHKERRQ(ierr); 3021552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, points[0], &off);CHKERRQ(ierr); 3022552f7358SJed Brown for (joinSize = 0; joinSize < dof; ++joinSize) { 3023552f7358SJed Brown join[i][joinSize] = mesh->supports[off+joinSize]; 3024552f7358SJed Brown } 3025552f7358SJed Brown /* Check each successive support */ 3026552f7358SJed Brown for (p = 1; p < numPoints; ++p) { 3027552f7358SJed Brown PetscInt newJoinSize = 0; 3028552f7358SJed Brown 3029552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, points[p], &dof);CHKERRQ(ierr); 3030552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, points[p], &off);CHKERRQ(ierr); 3031552f7358SJed Brown for (c = 0; c < dof; ++c) { 3032552f7358SJed Brown const PetscInt point = mesh->supports[off+c]; 3033552f7358SJed Brown 3034552f7358SJed Brown for (m = 0; m < joinSize; ++m) { 3035552f7358SJed Brown if (point == join[i][m]) { 3036552f7358SJed Brown join[1-i][newJoinSize++] = point; 3037552f7358SJed Brown break; 3038552f7358SJed Brown } 3039552f7358SJed Brown } 3040552f7358SJed Brown } 3041552f7358SJed Brown joinSize = newJoinSize; 3042552f7358SJed Brown i = 1-i; 3043552f7358SJed Brown } 3044552f7358SJed Brown *numCoveredPoints = joinSize; 3045552f7358SJed Brown *coveredPoints = join[i]; 304669291d52SBarry Smith ierr = DMRestoreWorkArray(dm, mesh->maxSupportSize, MPIU_INT, &join[1-i]);CHKERRQ(ierr); 3047552f7358SJed Brown PetscFunctionReturn(0); 3048552f7358SJed Brown } 3049552f7358SJed Brown 3050552f7358SJed Brown /*@C 3051552f7358SJed Brown DMPlexRestoreJoin - Restore an array for the join of the set of points 3052552f7358SJed Brown 3053552f7358SJed Brown Not Collective 3054552f7358SJed Brown 3055552f7358SJed Brown Input Parameters: 3056552f7358SJed Brown + dm - The DMPlex object 3057552f7358SJed Brown . numPoints - The number of input points for the join 3058552f7358SJed Brown - points - The input points 3059552f7358SJed Brown 3060552f7358SJed Brown Output Parameters: 3061552f7358SJed Brown + numCoveredPoints - The number of points in the join 3062552f7358SJed Brown - coveredPoints - The points in the join 3063552f7358SJed Brown 30643813dfbdSMatthew G Knepley Fortran Notes: 30653813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 30663813dfbdSMatthew G Knepley include petsc.h90 in your code. 30673813dfbdSMatthew G Knepley 30683813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 30693813dfbdSMatthew G Knepley 3070552f7358SJed Brown Level: intermediate 3071552f7358SJed Brown 3072552f7358SJed Brown .seealso: DMPlexGetJoin(), DMPlexGetFullJoin(), DMPlexGetMeet() 3073552f7358SJed Brown @*/ 3074552f7358SJed Brown PetscErrorCode DMPlexRestoreJoin(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 3075552f7358SJed Brown { 3076552f7358SJed Brown PetscErrorCode ierr; 3077552f7358SJed Brown 3078552f7358SJed Brown PetscFunctionBegin; 3079552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3080d7902bd2SMatthew G. Knepley if (points) PetscValidIntPointer(points,3); 3081d7902bd2SMatthew G. Knepley if (numCoveredPoints) PetscValidIntPointer(numCoveredPoints,4); 3082d7902bd2SMatthew G. Knepley PetscValidPointer(coveredPoints, 5); 308369291d52SBarry Smith ierr = DMRestoreWorkArray(dm, 0, MPIU_INT, (void*) coveredPoints);CHKERRQ(ierr); 3084d7902bd2SMatthew G. Knepley if (numCoveredPoints) *numCoveredPoints = 0; 3085552f7358SJed Brown PetscFunctionReturn(0); 3086552f7358SJed Brown } 3087552f7358SJed Brown 3088552f7358SJed Brown /*@C 3089552f7358SJed Brown DMPlexGetFullJoin - Get an array for the join of the set of points 3090552f7358SJed Brown 3091552f7358SJed Brown Not Collective 3092552f7358SJed Brown 3093552f7358SJed Brown Input Parameters: 3094552f7358SJed Brown + dm - The DMPlex object 3095552f7358SJed Brown . numPoints - The number of input points for the join 3096552f7358SJed Brown - points - The input points 3097552f7358SJed Brown 3098552f7358SJed Brown Output Parameters: 3099552f7358SJed Brown + numCoveredPoints - The number of points in the join 3100552f7358SJed Brown - coveredPoints - The points in the join 3101552f7358SJed Brown 31023813dfbdSMatthew G Knepley Fortran Notes: 31033813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 31043813dfbdSMatthew G Knepley include petsc.h90 in your code. 31053813dfbdSMatthew G Knepley 31063813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 31073813dfbdSMatthew G Knepley 3108552f7358SJed Brown Level: intermediate 3109552f7358SJed Brown 3110552f7358SJed Brown .seealso: DMPlexGetJoin(), DMPlexRestoreJoin(), DMPlexGetMeet() 3111552f7358SJed Brown @*/ 3112552f7358SJed Brown PetscErrorCode DMPlexGetFullJoin(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 3113552f7358SJed Brown { 3114552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3115552f7358SJed Brown PetscInt *offsets, **closures; 3116552f7358SJed Brown PetscInt *join[2]; 3117552f7358SJed Brown PetscInt depth = 0, maxSize, joinSize = 0, i = 0; 311824c766afSToby Isaac PetscInt p, d, c, m, ms; 3119552f7358SJed Brown PetscErrorCode ierr; 3120552f7358SJed Brown 3121552f7358SJed Brown PetscFunctionBegin; 3122552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 312348bb261cSVaclav Hapla PetscValidIntPointer(points, 3); 312448bb261cSVaclav Hapla PetscValidIntPointer(numCoveredPoints, 4); 312548bb261cSVaclav Hapla PetscValidPointer(coveredPoints, 5); 3126552f7358SJed Brown 3127552f7358SJed Brown ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 31281795a4d1SJed Brown ierr = PetscCalloc1(numPoints, &closures);CHKERRQ(ierr); 312969291d52SBarry Smith ierr = DMGetWorkArray(dm, numPoints*(depth+2), MPIU_INT, &offsets);CHKERRQ(ierr); 313024c766afSToby Isaac ms = mesh->maxSupportSize; 313124c766afSToby Isaac maxSize = (ms > 1) ? ((PetscPowInt(ms,depth+1)-1)/(ms-1)) : depth + 1; 313269291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &join[0]);CHKERRQ(ierr); 313369291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &join[1]);CHKERRQ(ierr); 3134552f7358SJed Brown 3135552f7358SJed Brown for (p = 0; p < numPoints; ++p) { 3136552f7358SJed Brown PetscInt closureSize; 3137552f7358SJed Brown 3138552f7358SJed Brown ierr = DMPlexGetTransitiveClosure(dm, points[p], PETSC_FALSE, &closureSize, &closures[p]);CHKERRQ(ierr); 31390d644c17SKarl Rupp 3140552f7358SJed Brown offsets[p*(depth+2)+0] = 0; 3141552f7358SJed Brown for (d = 0; d < depth+1; ++d) { 3142552f7358SJed Brown PetscInt pStart, pEnd, i; 3143552f7358SJed Brown 3144552f7358SJed Brown ierr = DMPlexGetDepthStratum(dm, d, &pStart, &pEnd);CHKERRQ(ierr); 3145552f7358SJed Brown for (i = offsets[p*(depth+2)+d]; i < closureSize; ++i) { 3146552f7358SJed Brown if ((pStart > closures[p][i*2]) || (pEnd <= closures[p][i*2])) { 3147552f7358SJed Brown offsets[p*(depth+2)+d+1] = i; 3148552f7358SJed Brown break; 3149552f7358SJed Brown } 3150552f7358SJed Brown } 3151552f7358SJed Brown if (i == closureSize) offsets[p*(depth+2)+d+1] = i; 3152552f7358SJed Brown } 315382f516ccSBarry 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); 3154552f7358SJed Brown } 3155552f7358SJed Brown for (d = 0; d < depth+1; ++d) { 3156552f7358SJed Brown PetscInt dof; 3157552f7358SJed Brown 3158552f7358SJed Brown /* Copy in support of first point */ 3159552f7358SJed Brown dof = offsets[d+1] - offsets[d]; 3160552f7358SJed Brown for (joinSize = 0; joinSize < dof; ++joinSize) { 3161552f7358SJed Brown join[i][joinSize] = closures[0][(offsets[d]+joinSize)*2]; 3162552f7358SJed Brown } 3163552f7358SJed Brown /* Check each successive cone */ 3164552f7358SJed Brown for (p = 1; p < numPoints && joinSize; ++p) { 3165552f7358SJed Brown PetscInt newJoinSize = 0; 3166552f7358SJed Brown 3167552f7358SJed Brown dof = offsets[p*(depth+2)+d+1] - offsets[p*(depth+2)+d]; 3168552f7358SJed Brown for (c = 0; c < dof; ++c) { 3169552f7358SJed Brown const PetscInt point = closures[p][(offsets[p*(depth+2)+d]+c)*2]; 3170552f7358SJed Brown 3171552f7358SJed Brown for (m = 0; m < joinSize; ++m) { 3172552f7358SJed Brown if (point == join[i][m]) { 3173552f7358SJed Brown join[1-i][newJoinSize++] = point; 3174552f7358SJed Brown break; 3175552f7358SJed Brown } 3176552f7358SJed Brown } 3177552f7358SJed Brown } 3178552f7358SJed Brown joinSize = newJoinSize; 3179552f7358SJed Brown i = 1-i; 3180552f7358SJed Brown } 3181552f7358SJed Brown if (joinSize) break; 3182552f7358SJed Brown } 3183552f7358SJed Brown *numCoveredPoints = joinSize; 3184552f7358SJed Brown *coveredPoints = join[i]; 3185552f7358SJed Brown for (p = 0; p < numPoints; ++p) { 31860298fd71SBarry Smith ierr = DMPlexRestoreTransitiveClosure(dm, points[p], PETSC_FALSE, NULL, &closures[p]);CHKERRQ(ierr); 3187552f7358SJed Brown } 3188552f7358SJed Brown ierr = PetscFree(closures);CHKERRQ(ierr); 318969291d52SBarry Smith ierr = DMRestoreWorkArray(dm, numPoints*(depth+2), MPIU_INT, &offsets);CHKERRQ(ierr); 319069291d52SBarry Smith ierr = DMRestoreWorkArray(dm, mesh->maxSupportSize, MPIU_INT, &join[1-i]);CHKERRQ(ierr); 3191552f7358SJed Brown PetscFunctionReturn(0); 3192552f7358SJed Brown } 3193552f7358SJed Brown 3194552f7358SJed Brown /*@C 3195552f7358SJed Brown DMPlexGetMeet - Get an array for the meet of the set of points 3196552f7358SJed Brown 3197552f7358SJed Brown Not Collective 3198552f7358SJed Brown 3199552f7358SJed Brown Input Parameters: 3200552f7358SJed Brown + dm - The DMPlex object 3201552f7358SJed Brown . numPoints - The number of input points for the meet 3202552f7358SJed Brown - points - The input points 3203552f7358SJed Brown 3204552f7358SJed Brown Output Parameters: 3205552f7358SJed Brown + numCoveredPoints - The number of points in the meet 3206552f7358SJed Brown - coveredPoints - The points in the meet 3207552f7358SJed Brown 3208552f7358SJed Brown Level: intermediate 3209552f7358SJed Brown 3210552f7358SJed Brown Note: Currently, this is restricted to a single level meet 3211552f7358SJed Brown 32123813dfbdSMatthew G Knepley Fortran Notes: 32133813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 32143813dfbdSMatthew G Knepley include petsc.h90 in your code. 32153813dfbdSMatthew G Knepley 32163813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 32173813dfbdSMatthew G Knepley 3218552f7358SJed Brown .seealso: DMPlexRestoreMeet(), DMPlexGetJoin() 3219552f7358SJed Brown @*/ 3220552f7358SJed Brown PetscErrorCode DMPlexGetMeet(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveringPoints, const PetscInt **coveringPoints) 3221552f7358SJed Brown { 3222552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3223552f7358SJed Brown PetscInt *meet[2]; 3224552f7358SJed Brown PetscInt meetSize, i = 0; 3225552f7358SJed Brown PetscInt dof, off, p, c, m; 3226552f7358SJed Brown PetscErrorCode ierr; 3227552f7358SJed Brown 3228552f7358SJed Brown PetscFunctionBegin; 3229552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3230552f7358SJed Brown PetscValidPointer(points, 2); 3231552f7358SJed Brown PetscValidPointer(numCoveringPoints, 3); 3232552f7358SJed Brown PetscValidPointer(coveringPoints, 4); 323369291d52SBarry Smith ierr = DMGetWorkArray(dm, mesh->maxConeSize, MPIU_INT, &meet[0]);CHKERRQ(ierr); 323469291d52SBarry Smith ierr = DMGetWorkArray(dm, mesh->maxConeSize, MPIU_INT, &meet[1]);CHKERRQ(ierr); 3235552f7358SJed Brown /* Copy in cone of first point */ 3236552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, points[0], &dof);CHKERRQ(ierr); 3237552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, points[0], &off);CHKERRQ(ierr); 3238552f7358SJed Brown for (meetSize = 0; meetSize < dof; ++meetSize) { 3239552f7358SJed Brown meet[i][meetSize] = mesh->cones[off+meetSize]; 3240552f7358SJed Brown } 3241552f7358SJed Brown /* Check each successive cone */ 3242552f7358SJed Brown for (p = 1; p < numPoints; ++p) { 3243552f7358SJed Brown PetscInt newMeetSize = 0; 3244552f7358SJed Brown 3245552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, points[p], &dof);CHKERRQ(ierr); 3246552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, points[p], &off);CHKERRQ(ierr); 3247552f7358SJed Brown for (c = 0; c < dof; ++c) { 3248552f7358SJed Brown const PetscInt point = mesh->cones[off+c]; 3249552f7358SJed Brown 3250552f7358SJed Brown for (m = 0; m < meetSize; ++m) { 3251552f7358SJed Brown if (point == meet[i][m]) { 3252552f7358SJed Brown meet[1-i][newMeetSize++] = point; 3253552f7358SJed Brown break; 3254552f7358SJed Brown } 3255552f7358SJed Brown } 3256552f7358SJed Brown } 3257552f7358SJed Brown meetSize = newMeetSize; 3258552f7358SJed Brown i = 1-i; 3259552f7358SJed Brown } 3260552f7358SJed Brown *numCoveringPoints = meetSize; 3261552f7358SJed Brown *coveringPoints = meet[i]; 326269291d52SBarry Smith ierr = DMRestoreWorkArray(dm, mesh->maxConeSize, MPIU_INT, &meet[1-i]);CHKERRQ(ierr); 3263552f7358SJed Brown PetscFunctionReturn(0); 3264552f7358SJed Brown } 3265552f7358SJed Brown 3266552f7358SJed Brown /*@C 3267552f7358SJed Brown DMPlexRestoreMeet - Restore an array for the meet of the set of points 3268552f7358SJed Brown 3269552f7358SJed Brown Not Collective 3270552f7358SJed Brown 3271552f7358SJed Brown Input Parameters: 3272552f7358SJed Brown + dm - The DMPlex object 3273552f7358SJed Brown . numPoints - The number of input points for the meet 3274552f7358SJed Brown - points - The input points 3275552f7358SJed Brown 3276552f7358SJed Brown Output Parameters: 3277552f7358SJed Brown + numCoveredPoints - The number of points in the meet 3278552f7358SJed Brown - coveredPoints - The points in the meet 3279552f7358SJed Brown 3280552f7358SJed Brown Level: intermediate 3281552f7358SJed Brown 32823813dfbdSMatthew G Knepley Fortran Notes: 32833813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 32843813dfbdSMatthew G Knepley include petsc.h90 in your code. 32853813dfbdSMatthew G Knepley 32863813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 32873813dfbdSMatthew G Knepley 3288552f7358SJed Brown .seealso: DMPlexGetMeet(), DMPlexGetFullMeet(), DMPlexGetJoin() 3289552f7358SJed Brown @*/ 3290552f7358SJed Brown PetscErrorCode DMPlexRestoreMeet(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 3291552f7358SJed Brown { 3292552f7358SJed Brown PetscErrorCode ierr; 3293552f7358SJed Brown 3294552f7358SJed Brown PetscFunctionBegin; 3295552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3296d7902bd2SMatthew G. Knepley if (points) PetscValidIntPointer(points,3); 3297d7902bd2SMatthew G. Knepley if (numCoveredPoints) PetscValidIntPointer(numCoveredPoints,4); 3298d7902bd2SMatthew G. Knepley PetscValidPointer(coveredPoints,5); 329969291d52SBarry Smith ierr = DMRestoreWorkArray(dm, 0, MPIU_INT, (void*) coveredPoints);CHKERRQ(ierr); 3300d7902bd2SMatthew G. Knepley if (numCoveredPoints) *numCoveredPoints = 0; 3301552f7358SJed Brown PetscFunctionReturn(0); 3302552f7358SJed Brown } 3303552f7358SJed Brown 3304552f7358SJed Brown /*@C 3305552f7358SJed Brown DMPlexGetFullMeet - Get an array for the meet of the set of points 3306552f7358SJed Brown 3307552f7358SJed Brown Not Collective 3308552f7358SJed Brown 3309552f7358SJed Brown Input Parameters: 3310552f7358SJed Brown + dm - The DMPlex object 3311552f7358SJed Brown . numPoints - The number of input points for the meet 3312552f7358SJed Brown - points - The input points 3313552f7358SJed Brown 3314552f7358SJed Brown Output Parameters: 3315552f7358SJed Brown + numCoveredPoints - The number of points in the meet 3316552f7358SJed Brown - coveredPoints - The points in the meet 3317552f7358SJed Brown 3318552f7358SJed Brown Level: intermediate 3319552f7358SJed Brown 33203813dfbdSMatthew G Knepley Fortran Notes: 33213813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 33223813dfbdSMatthew G Knepley include petsc.h90 in your code. 33233813dfbdSMatthew G Knepley 33243813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 33253813dfbdSMatthew G Knepley 3326552f7358SJed Brown .seealso: DMPlexGetMeet(), DMPlexRestoreMeet(), DMPlexGetJoin() 3327552f7358SJed Brown @*/ 3328552f7358SJed Brown PetscErrorCode DMPlexGetFullMeet(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 3329552f7358SJed Brown { 3330552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3331552f7358SJed Brown PetscInt *offsets, **closures; 3332552f7358SJed Brown PetscInt *meet[2]; 3333552f7358SJed Brown PetscInt height = 0, maxSize, meetSize = 0, i = 0; 333424c766afSToby Isaac PetscInt p, h, c, m, mc; 3335552f7358SJed Brown PetscErrorCode ierr; 3336552f7358SJed Brown 3337552f7358SJed Brown PetscFunctionBegin; 3338552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3339552f7358SJed Brown PetscValidPointer(points, 2); 3340552f7358SJed Brown PetscValidPointer(numCoveredPoints, 3); 3341552f7358SJed Brown PetscValidPointer(coveredPoints, 4); 3342552f7358SJed Brown 3343552f7358SJed Brown ierr = DMPlexGetDepth(dm, &height);CHKERRQ(ierr); 3344785e854fSJed Brown ierr = PetscMalloc1(numPoints, &closures);CHKERRQ(ierr); 334569291d52SBarry Smith ierr = DMGetWorkArray(dm, numPoints*(height+2), MPIU_INT, &offsets);CHKERRQ(ierr); 334624c766afSToby Isaac mc = mesh->maxConeSize; 334724c766afSToby Isaac maxSize = (mc > 1) ? ((PetscPowInt(mc,height+1)-1)/(mc-1)) : height + 1; 334869291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &meet[0]);CHKERRQ(ierr); 334969291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &meet[1]);CHKERRQ(ierr); 3350552f7358SJed Brown 3351552f7358SJed Brown for (p = 0; p < numPoints; ++p) { 3352552f7358SJed Brown PetscInt closureSize; 3353552f7358SJed Brown 3354552f7358SJed Brown ierr = DMPlexGetTransitiveClosure(dm, points[p], PETSC_TRUE, &closureSize, &closures[p]);CHKERRQ(ierr); 33550d644c17SKarl Rupp 3356552f7358SJed Brown offsets[p*(height+2)+0] = 0; 3357552f7358SJed Brown for (h = 0; h < height+1; ++h) { 3358552f7358SJed Brown PetscInt pStart, pEnd, i; 3359552f7358SJed Brown 3360552f7358SJed Brown ierr = DMPlexGetHeightStratum(dm, h, &pStart, &pEnd);CHKERRQ(ierr); 3361552f7358SJed Brown for (i = offsets[p*(height+2)+h]; i < closureSize; ++i) { 3362552f7358SJed Brown if ((pStart > closures[p][i*2]) || (pEnd <= closures[p][i*2])) { 3363552f7358SJed Brown offsets[p*(height+2)+h+1] = i; 3364552f7358SJed Brown break; 3365552f7358SJed Brown } 3366552f7358SJed Brown } 3367552f7358SJed Brown if (i == closureSize) offsets[p*(height+2)+h+1] = i; 3368552f7358SJed Brown } 336982f516ccSBarry 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); 3370552f7358SJed Brown } 3371552f7358SJed Brown for (h = 0; h < height+1; ++h) { 3372552f7358SJed Brown PetscInt dof; 3373552f7358SJed Brown 3374552f7358SJed Brown /* Copy in cone of first point */ 3375552f7358SJed Brown dof = offsets[h+1] - offsets[h]; 3376552f7358SJed Brown for (meetSize = 0; meetSize < dof; ++meetSize) { 3377552f7358SJed Brown meet[i][meetSize] = closures[0][(offsets[h]+meetSize)*2]; 3378552f7358SJed Brown } 3379552f7358SJed Brown /* Check each successive cone */ 3380552f7358SJed Brown for (p = 1; p < numPoints && meetSize; ++p) { 3381552f7358SJed Brown PetscInt newMeetSize = 0; 3382552f7358SJed Brown 3383552f7358SJed Brown dof = offsets[p*(height+2)+h+1] - offsets[p*(height+2)+h]; 3384552f7358SJed Brown for (c = 0; c < dof; ++c) { 3385552f7358SJed Brown const PetscInt point = closures[p][(offsets[p*(height+2)+h]+c)*2]; 3386552f7358SJed Brown 3387552f7358SJed Brown for (m = 0; m < meetSize; ++m) { 3388552f7358SJed Brown if (point == meet[i][m]) { 3389552f7358SJed Brown meet[1-i][newMeetSize++] = point; 3390552f7358SJed Brown break; 3391552f7358SJed Brown } 3392552f7358SJed Brown } 3393552f7358SJed Brown } 3394552f7358SJed Brown meetSize = newMeetSize; 3395552f7358SJed Brown i = 1-i; 3396552f7358SJed Brown } 3397552f7358SJed Brown if (meetSize) break; 3398552f7358SJed Brown } 3399552f7358SJed Brown *numCoveredPoints = meetSize; 3400552f7358SJed Brown *coveredPoints = meet[i]; 3401552f7358SJed Brown for (p = 0; p < numPoints; ++p) { 34020298fd71SBarry Smith ierr = DMPlexRestoreTransitiveClosure(dm, points[p], PETSC_TRUE, NULL, &closures[p]);CHKERRQ(ierr); 3403552f7358SJed Brown } 3404552f7358SJed Brown ierr = PetscFree(closures);CHKERRQ(ierr); 340569291d52SBarry Smith ierr = DMRestoreWorkArray(dm, numPoints*(height+2), MPIU_INT, &offsets);CHKERRQ(ierr); 340669291d52SBarry Smith ierr = DMRestoreWorkArray(dm, mesh->maxConeSize, MPIU_INT, &meet[1-i]);CHKERRQ(ierr); 3407552f7358SJed Brown PetscFunctionReturn(0); 3408552f7358SJed Brown } 3409552f7358SJed Brown 34104e3744c5SMatthew G. Knepley /*@C 34114e3744c5SMatthew G. Knepley DMPlexEqual - Determine if two DMs have the same topology 34124e3744c5SMatthew G. Knepley 34134e3744c5SMatthew G. Knepley Not Collective 34144e3744c5SMatthew G. Knepley 34154e3744c5SMatthew G. Knepley Input Parameters: 34164e3744c5SMatthew G. Knepley + dmA - A DMPlex object 34174e3744c5SMatthew G. Knepley - dmB - A DMPlex object 34184e3744c5SMatthew G. Knepley 34194e3744c5SMatthew G. Knepley Output Parameters: 34204e3744c5SMatthew G. Knepley . equal - PETSC_TRUE if the topologies are identical 34214e3744c5SMatthew G. Knepley 34224e3744c5SMatthew G. Knepley Level: intermediate 34234e3744c5SMatthew G. Knepley 34244e3744c5SMatthew G. Knepley Notes: 34254e3744c5SMatthew G. Knepley We are not solving graph isomorphism, so we do not permutation. 34264e3744c5SMatthew G. Knepley 34274e3744c5SMatthew G. Knepley .seealso: DMPlexGetCone() 34284e3744c5SMatthew G. Knepley @*/ 34294e3744c5SMatthew G. Knepley PetscErrorCode DMPlexEqual(DM dmA, DM dmB, PetscBool *equal) 34304e3744c5SMatthew G. Knepley { 34314e3744c5SMatthew G. Knepley PetscInt depth, depthB, pStart, pEnd, pStartB, pEndB, p; 34324e3744c5SMatthew G. Knepley PetscErrorCode ierr; 34334e3744c5SMatthew G. Knepley 34344e3744c5SMatthew G. Knepley PetscFunctionBegin; 34354e3744c5SMatthew G. Knepley PetscValidHeaderSpecific(dmA, DM_CLASSID, 1); 34364e3744c5SMatthew G. Knepley PetscValidHeaderSpecific(dmB, DM_CLASSID, 2); 34374e3744c5SMatthew G. Knepley PetscValidPointer(equal, 3); 34384e3744c5SMatthew G. Knepley 34394e3744c5SMatthew G. Knepley *equal = PETSC_FALSE; 34404e3744c5SMatthew G. Knepley ierr = DMPlexGetDepth(dmA, &depth);CHKERRQ(ierr); 34414e3744c5SMatthew G. Knepley ierr = DMPlexGetDepth(dmB, &depthB);CHKERRQ(ierr); 34424e3744c5SMatthew G. Knepley if (depth != depthB) PetscFunctionReturn(0); 34434e3744c5SMatthew G. Knepley ierr = DMPlexGetChart(dmA, &pStart, &pEnd);CHKERRQ(ierr); 34444e3744c5SMatthew G. Knepley ierr = DMPlexGetChart(dmB, &pStartB, &pEndB);CHKERRQ(ierr); 34454e3744c5SMatthew G. Knepley if ((pStart != pStartB) || (pEnd != pEndB)) PetscFunctionReturn(0); 34464e3744c5SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 34474e3744c5SMatthew G. Knepley const PetscInt *cone, *coneB, *ornt, *orntB, *support, *supportB; 34484e3744c5SMatthew G. Knepley PetscInt coneSize, coneSizeB, c, supportSize, supportSizeB, s; 34494e3744c5SMatthew G. Knepley 34504e3744c5SMatthew G. Knepley ierr = DMPlexGetConeSize(dmA, p, &coneSize);CHKERRQ(ierr); 34514e3744c5SMatthew G. Knepley ierr = DMPlexGetCone(dmA, p, &cone);CHKERRQ(ierr); 34524e3744c5SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dmA, p, &ornt);CHKERRQ(ierr); 34534e3744c5SMatthew G. Knepley ierr = DMPlexGetConeSize(dmB, p, &coneSizeB);CHKERRQ(ierr); 34544e3744c5SMatthew G. Knepley ierr = DMPlexGetCone(dmB, p, &coneB);CHKERRQ(ierr); 34554e3744c5SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dmB, p, &orntB);CHKERRQ(ierr); 34564e3744c5SMatthew G. Knepley if (coneSize != coneSizeB) PetscFunctionReturn(0); 34574e3744c5SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 34584e3744c5SMatthew G. Knepley if (cone[c] != coneB[c]) PetscFunctionReturn(0); 34594e3744c5SMatthew G. Knepley if (ornt[c] != orntB[c]) PetscFunctionReturn(0); 34604e3744c5SMatthew G. Knepley } 34614e3744c5SMatthew G. Knepley ierr = DMPlexGetSupportSize(dmA, p, &supportSize);CHKERRQ(ierr); 34624e3744c5SMatthew G. Knepley ierr = DMPlexGetSupport(dmA, p, &support);CHKERRQ(ierr); 34634e3744c5SMatthew G. Knepley ierr = DMPlexGetSupportSize(dmB, p, &supportSizeB);CHKERRQ(ierr); 34644e3744c5SMatthew G. Knepley ierr = DMPlexGetSupport(dmB, p, &supportB);CHKERRQ(ierr); 34654e3744c5SMatthew G. Knepley if (supportSize != supportSizeB) PetscFunctionReturn(0); 34664e3744c5SMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 34674e3744c5SMatthew G. Knepley if (support[s] != supportB[s]) PetscFunctionReturn(0); 34684e3744c5SMatthew G. Knepley } 34694e3744c5SMatthew G. Knepley } 34704e3744c5SMatthew G. Knepley *equal = PETSC_TRUE; 34714e3744c5SMatthew G. Knepley PetscFunctionReturn(0); 34724e3744c5SMatthew G. Knepley } 34734e3744c5SMatthew G. Knepley 34747cd05799SMatthew G. Knepley /*@C 34757cd05799SMatthew G. Knepley DMPlexGetNumFaceVertices - Returns the number of vertices on a face 34767cd05799SMatthew G. Knepley 34777cd05799SMatthew G. Knepley Not Collective 34787cd05799SMatthew G. Knepley 34797cd05799SMatthew G. Knepley Input Parameters: 34807cd05799SMatthew G. Knepley + dm - The DMPlex 34817cd05799SMatthew G. Knepley . cellDim - The cell dimension 34827cd05799SMatthew G. Knepley - numCorners - The number of vertices on a cell 34837cd05799SMatthew G. Knepley 34847cd05799SMatthew G. Knepley Output Parameters: 34857cd05799SMatthew G. Knepley . numFaceVertices - The number of vertices on a face 34867cd05799SMatthew G. Knepley 34877cd05799SMatthew G. Knepley Level: developer 34887cd05799SMatthew G. Knepley 34897cd05799SMatthew G. Knepley Notes: 34907cd05799SMatthew G. Knepley Of course this can only work for a restricted set of symmetric shapes 34917cd05799SMatthew G. Knepley 34927cd05799SMatthew G. Knepley .seealso: DMPlexGetCone() 34937cd05799SMatthew G. Knepley @*/ 349418ad9376SMatthew G. Knepley PetscErrorCode DMPlexGetNumFaceVertices(DM dm, PetscInt cellDim, PetscInt numCorners, PetscInt *numFaceVertices) 3495a6dfd86eSKarl Rupp { 349682f516ccSBarry Smith MPI_Comm comm; 3497552f7358SJed Brown PetscErrorCode ierr; 3498552f7358SJed Brown 3499552f7358SJed Brown PetscFunctionBegin; 350082f516ccSBarry Smith ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 3501552f7358SJed Brown PetscValidPointer(numFaceVertices,3); 3502552f7358SJed Brown switch (cellDim) { 3503552f7358SJed Brown case 0: 3504552f7358SJed Brown *numFaceVertices = 0; 3505552f7358SJed Brown break; 3506552f7358SJed Brown case 1: 3507552f7358SJed Brown *numFaceVertices = 1; 3508552f7358SJed Brown break; 3509552f7358SJed Brown case 2: 3510552f7358SJed Brown switch (numCorners) { 351119436ca2SJed Brown case 3: /* triangle */ 351219436ca2SJed Brown *numFaceVertices = 2; /* Edge has 2 vertices */ 3513552f7358SJed Brown break; 351419436ca2SJed Brown case 4: /* quadrilateral */ 351519436ca2SJed Brown *numFaceVertices = 2; /* Edge has 2 vertices */ 3516552f7358SJed Brown break; 351719436ca2SJed Brown case 6: /* quadratic triangle, tri and quad cohesive Lagrange cells */ 351819436ca2SJed Brown *numFaceVertices = 3; /* Edge has 3 vertices */ 3519552f7358SJed Brown break; 352019436ca2SJed Brown case 9: /* quadratic quadrilateral, quadratic quad cohesive Lagrange cells */ 352119436ca2SJed Brown *numFaceVertices = 3; /* Edge has 3 vertices */ 3522552f7358SJed Brown break; 3523552f7358SJed Brown default: 3524f347f43bSBarry Smith SETERRQ2(comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid number of face corners %D for dimension %D", numCorners, cellDim); 3525552f7358SJed Brown } 3526552f7358SJed Brown break; 3527552f7358SJed Brown case 3: 3528552f7358SJed Brown switch (numCorners) { 352919436ca2SJed Brown case 4: /* tetradehdron */ 353019436ca2SJed Brown *numFaceVertices = 3; /* Face has 3 vertices */ 3531552f7358SJed Brown break; 353219436ca2SJed Brown case 6: /* tet cohesive cells */ 353319436ca2SJed Brown *numFaceVertices = 4; /* Face has 4 vertices */ 3534552f7358SJed Brown break; 353519436ca2SJed Brown case 8: /* hexahedron */ 353619436ca2SJed Brown *numFaceVertices = 4; /* Face has 4 vertices */ 3537552f7358SJed Brown break; 353819436ca2SJed Brown case 9: /* tet cohesive Lagrange cells */ 353919436ca2SJed Brown *numFaceVertices = 6; /* Face has 6 vertices */ 3540552f7358SJed Brown break; 354119436ca2SJed Brown case 10: /* quadratic tetrahedron */ 354219436ca2SJed Brown *numFaceVertices = 6; /* Face has 6 vertices */ 3543552f7358SJed Brown break; 354419436ca2SJed Brown case 12: /* hex cohesive Lagrange cells */ 354519436ca2SJed Brown *numFaceVertices = 6; /* Face has 6 vertices */ 3546552f7358SJed Brown break; 354719436ca2SJed Brown case 18: /* quadratic tet cohesive Lagrange cells */ 354819436ca2SJed Brown *numFaceVertices = 6; /* Face has 6 vertices */ 3549552f7358SJed Brown break; 355019436ca2SJed Brown case 27: /* quadratic hexahedron, quadratic hex cohesive Lagrange cells */ 355119436ca2SJed Brown *numFaceVertices = 9; /* Face has 9 vertices */ 3552552f7358SJed Brown break; 3553552f7358SJed Brown default: 3554f347f43bSBarry Smith SETERRQ2(comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid number of face corners %D for dimension %D", numCorners, cellDim); 3555552f7358SJed Brown } 3556552f7358SJed Brown break; 3557552f7358SJed Brown default: 3558f347f43bSBarry Smith SETERRQ1(comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid cell dimension %D", cellDim); 3559552f7358SJed Brown } 3560552f7358SJed Brown PetscFunctionReturn(0); 3561552f7358SJed Brown } 3562552f7358SJed Brown 3563552f7358SJed Brown /*@ 3564aa50250dSMatthew G. Knepley DMPlexGetDepthLabel - Get the DMLabel recording the depth of each point 3565552f7358SJed Brown 3566552f7358SJed Brown Not Collective 3567552f7358SJed Brown 3568aa50250dSMatthew G. Knepley Input Parameter: 3569552f7358SJed Brown . dm - The DMPlex object 3570552f7358SJed Brown 3571aa50250dSMatthew G. Knepley Output Parameter: 3572aa50250dSMatthew G. Knepley . depthLabel - The DMLabel recording point depth 3573552f7358SJed Brown 3574552f7358SJed Brown Level: developer 3575552f7358SJed Brown 3576aa50250dSMatthew G. Knepley .seealso: DMPlexGetDepth(), DMPlexGetHeightStratum(), DMPlexGetDepthStratum() 3577aa50250dSMatthew G. Knepley @*/ 3578aa50250dSMatthew G. Knepley PetscErrorCode DMPlexGetDepthLabel(DM dm, DMLabel *depthLabel) 3579aa50250dSMatthew G. Knepley { 3580aa50250dSMatthew G. Knepley PetscFunctionBegin; 3581aa50250dSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3582aa50250dSMatthew G. Knepley PetscValidPointer(depthLabel, 2); 3583c58f1c22SToby Isaac *depthLabel = dm->depthLabel; 3584aa50250dSMatthew G. Knepley PetscFunctionReturn(0); 3585aa50250dSMatthew G. Knepley } 3586aa50250dSMatthew G. Knepley 3587aa50250dSMatthew G. Knepley /*@ 3588aa50250dSMatthew G. Knepley DMPlexGetDepth - Get the depth of the DAG representing this mesh 3589aa50250dSMatthew G. Knepley 3590aa50250dSMatthew G. Knepley Not Collective 3591aa50250dSMatthew G. Knepley 3592aa50250dSMatthew G. Knepley Input Parameter: 3593aa50250dSMatthew G. Knepley . dm - The DMPlex object 3594aa50250dSMatthew G. Knepley 3595aa50250dSMatthew G. Knepley Output Parameter: 3596aa50250dSMatthew G. Knepley . depth - The number of strata (breadth first levels) in the DAG 3597aa50250dSMatthew G. Knepley 3598aa50250dSMatthew G. Knepley Level: developer 3599552f7358SJed Brown 3600b1bb481bSMatthew Knepley Notes: 3601b1bb481bSMatthew Knepley This returns maximum of point depths over all points, i.e. maximum value of the label returned by DMPlexGetDepthLabel(). 3602b1bb481bSMatthew Knepley The point depth is described more in detail in DMPlexSymmetrize(). 3603b1bb481bSMatthew Knepley 3604b1bb481bSMatthew Knepley .seealso: DMPlexGetDepthLabel(), DMPlexGetHeightStratum(), DMPlexGetDepthStratum(), DMPlexSymmetrize() 3605552f7358SJed Brown @*/ 3606552f7358SJed Brown PetscErrorCode DMPlexGetDepth(DM dm, PetscInt *depth) 3607552f7358SJed Brown { 3608aa50250dSMatthew G. Knepley DMLabel label; 3609aa50250dSMatthew G. Knepley PetscInt d = 0; 3610552f7358SJed Brown PetscErrorCode ierr; 3611552f7358SJed Brown 3612552f7358SJed Brown PetscFunctionBegin; 3613552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3614552f7358SJed Brown PetscValidPointer(depth, 2); 3615aa50250dSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 3616aa50250dSMatthew G. Knepley if (label) {ierr = DMLabelGetNumValues(label, &d);CHKERRQ(ierr);} 3617552f7358SJed Brown *depth = d-1; 3618552f7358SJed Brown PetscFunctionReturn(0); 3619552f7358SJed Brown } 3620552f7358SJed Brown 3621552f7358SJed Brown /*@ 3622552f7358SJed Brown DMPlexGetDepthStratum - Get the bounds [start, end) for all points at a certain depth. 3623552f7358SJed Brown 3624552f7358SJed Brown Not Collective 3625552f7358SJed Brown 3626552f7358SJed Brown Input Parameters: 3627552f7358SJed Brown + dm - The DMPlex object 3628552f7358SJed Brown - stratumValue - The requested depth 3629552f7358SJed Brown 3630552f7358SJed Brown Output Parameters: 3631552f7358SJed Brown + start - The first point at this depth 3632552f7358SJed Brown - end - One beyond the last point at this depth 3633552f7358SJed Brown 3634647867b2SJed Brown Notes: 3635647867b2SJed Brown Depth indexing is related to topological dimension. Depth stratum 0 contains the lowest topological dimension points, 3636647867b2SJed Brown often "vertices". If the mesh is "interpolated" (see DMPlexInterpolate()), then depth stratum 1 contains the next 3637647867b2SJed Brown higher dimension, e.g., "edges". 3638647867b2SJed Brown 3639552f7358SJed Brown Level: developer 3640552f7358SJed Brown 3641552f7358SJed Brown .seealso: DMPlexGetHeightStratum(), DMPlexGetDepth() 3642552f7358SJed Brown @*/ 36430adebc6cSBarry Smith PetscErrorCode DMPlexGetDepthStratum(DM dm, PetscInt stratumValue, PetscInt *start, PetscInt *end) 36440adebc6cSBarry Smith { 3645aa50250dSMatthew G. Knepley DMLabel label; 364663d1a920SMatthew G. Knepley PetscInt pStart, pEnd; 3647552f7358SJed Brown PetscErrorCode ierr; 3648552f7358SJed Brown 3649552f7358SJed Brown PetscFunctionBegin; 3650552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 365163d1a920SMatthew G. Knepley if (start) {PetscValidPointer(start, 3); *start = 0;} 365263d1a920SMatthew G. Knepley if (end) {PetscValidPointer(end, 4); *end = 0;} 3653552f7358SJed Brown ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 36540d644c17SKarl Rupp if (pStart == pEnd) PetscFunctionReturn(0); 365563d1a920SMatthew G. Knepley if (stratumValue < 0) { 365663d1a920SMatthew G. Knepley if (start) *start = pStart; 365763d1a920SMatthew G. Knepley if (end) *end = pEnd; 365863d1a920SMatthew G. Knepley PetscFunctionReturn(0); 3659552f7358SJed Brown } 3660aa50250dSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 366163d1a920SMatthew G. Knepley if (!label) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "No label named depth was found"); 366263d1a920SMatthew G. Knepley ierr = DMLabelGetStratumBounds(label, stratumValue, start, end);CHKERRQ(ierr); 3663552f7358SJed Brown PetscFunctionReturn(0); 3664552f7358SJed Brown } 3665552f7358SJed Brown 3666552f7358SJed Brown /*@ 3667552f7358SJed Brown DMPlexGetHeightStratum - Get the bounds [start, end) for all points at a certain height. 3668552f7358SJed Brown 3669552f7358SJed Brown Not Collective 3670552f7358SJed Brown 3671552f7358SJed Brown Input Parameters: 3672552f7358SJed Brown + dm - The DMPlex object 3673552f7358SJed Brown - stratumValue - The requested height 3674552f7358SJed Brown 3675552f7358SJed Brown Output Parameters: 3676552f7358SJed Brown + start - The first point at this height 3677552f7358SJed Brown - end - One beyond the last point at this height 3678552f7358SJed Brown 3679647867b2SJed Brown Notes: 3680647867b2SJed Brown Height indexing is related to topological codimension. Height stratum 0 contains the highest topological dimension 3681647867b2SJed Brown points, often called "cells" or "elements". If the mesh is "interpolated" (see DMPlexInterpolate()), then height 3682647867b2SJed Brown stratum 1 contains the boundary of these "cells", often called "faces" or "facets". 3683647867b2SJed Brown 3684552f7358SJed Brown Level: developer 3685552f7358SJed Brown 3686552f7358SJed Brown .seealso: DMPlexGetDepthStratum(), DMPlexGetDepth() 3687552f7358SJed Brown @*/ 36880adebc6cSBarry Smith PetscErrorCode DMPlexGetHeightStratum(DM dm, PetscInt stratumValue, PetscInt *start, PetscInt *end) 36890adebc6cSBarry Smith { 3690aa50250dSMatthew G. Knepley DMLabel label; 369163d1a920SMatthew G. Knepley PetscInt depth, pStart, pEnd; 3692552f7358SJed Brown PetscErrorCode ierr; 3693552f7358SJed Brown 3694552f7358SJed Brown PetscFunctionBegin; 3695552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 369663d1a920SMatthew G. Knepley if (start) {PetscValidPointer(start, 3); *start = 0;} 369763d1a920SMatthew G. Knepley if (end) {PetscValidPointer(end, 4); *end = 0;} 3698552f7358SJed Brown ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 36990d644c17SKarl Rupp if (pStart == pEnd) PetscFunctionReturn(0); 370063d1a920SMatthew G. Knepley if (stratumValue < 0) { 370163d1a920SMatthew G. Knepley if (start) *start = pStart; 370263d1a920SMatthew G. Knepley if (end) *end = pEnd; 370363d1a920SMatthew G. Knepley PetscFunctionReturn(0); 3704552f7358SJed Brown } 3705aa50250dSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 370613903a91SSatish Balay if (!label) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "No label named depth was found"); 370763d1a920SMatthew G. Knepley ierr = DMLabelGetNumValues(label, &depth);CHKERRQ(ierr); 370863d1a920SMatthew G. Knepley ierr = DMLabelGetStratumBounds(label, depth-1-stratumValue, start, end);CHKERRQ(ierr); 3709552f7358SJed Brown PetscFunctionReturn(0); 3710552f7358SJed Brown } 3711552f7358SJed Brown 37120adebc6cSBarry Smith PetscErrorCode DMCreateCoordinateDM_Plex(DM dm, DM *cdm) 37130adebc6cSBarry Smith { 3714efe440bfSMatthew G. Knepley PetscSection section, s; 3715efe440bfSMatthew G. Knepley Mat m; 37163e922f36SToby Isaac PetscInt maxHeight; 3717552f7358SJed Brown PetscErrorCode ierr; 3718552f7358SJed Brown 3719552f7358SJed Brown PetscFunctionBegin; 372038221697SMatthew G. Knepley ierr = DMClone(dm, cdm);CHKERRQ(ierr); 37213e922f36SToby Isaac ierr = DMPlexGetMaxProjectionHeight(dm, &maxHeight);CHKERRQ(ierr); 37223e922f36SToby Isaac ierr = DMPlexSetMaxProjectionHeight(*cdm, maxHeight);CHKERRQ(ierr); 372382f516ccSBarry Smith ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), §ion);CHKERRQ(ierr); 372492fd8e1eSJed Brown ierr = DMSetLocalSection(*cdm, section);CHKERRQ(ierr); 37251d799100SJed Brown ierr = PetscSectionDestroy(§ion);CHKERRQ(ierr); 3726efe440bfSMatthew G. Knepley ierr = PetscSectionCreate(PETSC_COMM_SELF, &s);CHKERRQ(ierr); 3727efe440bfSMatthew G. Knepley ierr = MatCreate(PETSC_COMM_SELF, &m);CHKERRQ(ierr); 3728efe440bfSMatthew G. Knepley ierr = DMSetDefaultConstraints(*cdm, s, m);CHKERRQ(ierr); 3729efe440bfSMatthew G. Knepley ierr = PetscSectionDestroy(&s);CHKERRQ(ierr); 3730efe440bfSMatthew G. Knepley ierr = MatDestroy(&m);CHKERRQ(ierr); 37318f4c458bSMatthew G. Knepley 37328f4c458bSMatthew G. Knepley ierr = DMSetNumFields(*cdm, 1);CHKERRQ(ierr); 37338f4c458bSMatthew G. Knepley ierr = DMCreateDS(*cdm);CHKERRQ(ierr); 3734552f7358SJed Brown PetscFunctionReturn(0); 3735552f7358SJed Brown } 3736552f7358SJed Brown 3737f19dbd58SToby Isaac PetscErrorCode DMCreateCoordinateField_Plex(DM dm, DMField *field) 3738f19dbd58SToby Isaac { 3739f19dbd58SToby Isaac Vec coordsLocal; 3740f19dbd58SToby Isaac DM coordsDM; 3741f19dbd58SToby Isaac PetscErrorCode ierr; 3742f19dbd58SToby Isaac 3743f19dbd58SToby Isaac PetscFunctionBegin; 3744f19dbd58SToby Isaac *field = NULL; 3745f19dbd58SToby Isaac ierr = DMGetCoordinatesLocal(dm,&coordsLocal);CHKERRQ(ierr); 3746f19dbd58SToby Isaac ierr = DMGetCoordinateDM(dm,&coordsDM);CHKERRQ(ierr); 3747f19dbd58SToby Isaac if (coordsLocal && coordsDM) { 3748f19dbd58SToby Isaac ierr = DMFieldCreateDS(coordsDM, 0, coordsLocal, field);CHKERRQ(ierr); 3749f19dbd58SToby Isaac } 3750f19dbd58SToby Isaac PetscFunctionReturn(0); 3751f19dbd58SToby Isaac } 3752f19dbd58SToby Isaac 37537cd05799SMatthew G. Knepley /*@C 37547cd05799SMatthew G. Knepley DMPlexGetConeSection - Return a section which describes the layout of cone data 37557cd05799SMatthew G. Knepley 37567cd05799SMatthew G. Knepley Not Collective 37577cd05799SMatthew G. Knepley 37587cd05799SMatthew G. Knepley Input Parameters: 37597cd05799SMatthew G. Knepley . dm - The DMPlex object 37607cd05799SMatthew G. Knepley 37617cd05799SMatthew G. Knepley Output Parameter: 37627cd05799SMatthew G. Knepley . section - The PetscSection object 37637cd05799SMatthew G. Knepley 37647cd05799SMatthew G. Knepley Level: developer 37657cd05799SMatthew G. Knepley 37667cd05799SMatthew G. Knepley .seealso: DMPlexGetSupportSection(), DMPlexGetCones(), DMPlexGetConeOrientations() 37677cd05799SMatthew G. Knepley @*/ 37680adebc6cSBarry Smith PetscErrorCode DMPlexGetConeSection(DM dm, PetscSection *section) 37690adebc6cSBarry Smith { 3770552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3771552f7358SJed Brown 3772552f7358SJed Brown PetscFunctionBegin; 3773552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3774552f7358SJed Brown if (section) *section = mesh->coneSection; 3775552f7358SJed Brown PetscFunctionReturn(0); 3776552f7358SJed Brown } 3777552f7358SJed Brown 37787cd05799SMatthew G. Knepley /*@C 37797cd05799SMatthew G. Knepley DMPlexGetSupportSection - Return a section which describes the layout of support data 37807cd05799SMatthew G. Knepley 37817cd05799SMatthew G. Knepley Not Collective 37827cd05799SMatthew G. Knepley 37837cd05799SMatthew G. Knepley Input Parameters: 37847cd05799SMatthew G. Knepley . dm - The DMPlex object 37857cd05799SMatthew G. Knepley 37867cd05799SMatthew G. Knepley Output Parameter: 37877cd05799SMatthew G. Knepley . section - The PetscSection object 37887cd05799SMatthew G. Knepley 37897cd05799SMatthew G. Knepley Level: developer 37907cd05799SMatthew G. Knepley 37917cd05799SMatthew G. Knepley .seealso: DMPlexGetConeSection() 37927cd05799SMatthew G. Knepley @*/ 37938cb4d582SMatthew G. Knepley PetscErrorCode DMPlexGetSupportSection(DM dm, PetscSection *section) 37948cb4d582SMatthew G. Knepley { 37958cb4d582SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 37968cb4d582SMatthew G. Knepley 37978cb4d582SMatthew G. Knepley PetscFunctionBegin; 37988cb4d582SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 37998cb4d582SMatthew G. Knepley if (section) *section = mesh->supportSection; 38008cb4d582SMatthew G. Knepley PetscFunctionReturn(0); 38018cb4d582SMatthew G. Knepley } 38028cb4d582SMatthew G. Knepley 38037cd05799SMatthew G. Knepley /*@C 38047cd05799SMatthew G. Knepley DMPlexGetCones - Return cone data 38057cd05799SMatthew G. Knepley 38067cd05799SMatthew G. Knepley Not Collective 38077cd05799SMatthew G. Knepley 38087cd05799SMatthew G. Knepley Input Parameters: 38097cd05799SMatthew G. Knepley . dm - The DMPlex object 38107cd05799SMatthew G. Knepley 38117cd05799SMatthew G. Knepley Output Parameter: 38127cd05799SMatthew G. Knepley . cones - The cone for each point 38137cd05799SMatthew G. Knepley 38147cd05799SMatthew G. Knepley Level: developer 38157cd05799SMatthew G. Knepley 38167cd05799SMatthew G. Knepley .seealso: DMPlexGetConeSection() 38177cd05799SMatthew G. Knepley @*/ 3818a6dfd86eSKarl Rupp PetscErrorCode DMPlexGetCones(DM dm, PetscInt *cones[]) 3819a6dfd86eSKarl Rupp { 3820552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3821552f7358SJed Brown 3822552f7358SJed Brown PetscFunctionBegin; 3823552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3824552f7358SJed Brown if (cones) *cones = mesh->cones; 3825552f7358SJed Brown PetscFunctionReturn(0); 3826552f7358SJed Brown } 3827552f7358SJed Brown 38287cd05799SMatthew G. Knepley /*@C 38297cd05799SMatthew G. Knepley DMPlexGetConeOrientations - Return cone orientation data 38307cd05799SMatthew G. Knepley 38317cd05799SMatthew G. Knepley Not Collective 38327cd05799SMatthew G. Knepley 38337cd05799SMatthew G. Knepley Input Parameters: 38347cd05799SMatthew G. Knepley . dm - The DMPlex object 38357cd05799SMatthew G. Knepley 38367cd05799SMatthew G. Knepley Output Parameter: 38377cd05799SMatthew G. Knepley . coneOrientations - The cone orientation for each point 38387cd05799SMatthew G. Knepley 38397cd05799SMatthew G. Knepley Level: developer 38407cd05799SMatthew G. Knepley 38417cd05799SMatthew G. Knepley .seealso: DMPlexGetConeSection() 38427cd05799SMatthew G. Knepley @*/ 3843a6dfd86eSKarl Rupp PetscErrorCode DMPlexGetConeOrientations(DM dm, PetscInt *coneOrientations[]) 3844a6dfd86eSKarl Rupp { 3845552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3846552f7358SJed Brown 3847552f7358SJed Brown PetscFunctionBegin; 3848552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3849552f7358SJed Brown if (coneOrientations) *coneOrientations = mesh->coneOrientations; 3850552f7358SJed Brown PetscFunctionReturn(0); 3851552f7358SJed Brown } 3852552f7358SJed Brown 3853552f7358SJed Brown /******************************** FEM Support **********************************/ 3854552f7358SJed Brown 38559e8305c2SJed Brown /* 38569e8305c2SJed Brown Returns number of components and tensor degree for the field. For interpolated meshes, line should be a point 38579e8305c2SJed Brown representing a line in the section. 38589e8305c2SJed Brown */ 38599e8305c2SJed Brown static PetscErrorCode PetscSectionFieldGetTensorDegree_Private(PetscSection section,PetscInt field,PetscInt line,PetscBool vertexchart,PetscInt *Nc,PetscInt *k) 38609e8305c2SJed Brown { 38619e8305c2SJed Brown PetscErrorCode ierr; 38629e8305c2SJed Brown 38639e8305c2SJed Brown PetscFunctionBeginHot; 38649e8305c2SJed Brown ierr = PetscSectionGetFieldComponents(section, field, Nc);CHKERRQ(ierr); 3865a433471fSStefano Zampini if (line < 0) { 3866a433471fSStefano Zampini *k = 0; 3867a433471fSStefano Zampini *Nc = 0; 3868a433471fSStefano Zampini } else if (vertexchart) { /* If we only have a vertex chart, we must have degree k=1 */ 38699e8305c2SJed Brown *k = 1; 38709e8305c2SJed Brown } else { /* Assume the full interpolated mesh is in the chart; lines in particular */ 38719e8305c2SJed Brown /* An order k SEM disc has k-1 dofs on an edge */ 38729e8305c2SJed Brown ierr = PetscSectionGetFieldDof(section, line, field, k);CHKERRQ(ierr); 38739e8305c2SJed Brown *k = *k / *Nc + 1; 38749e8305c2SJed Brown } 38759e8305c2SJed Brown PetscFunctionReturn(0); 38769e8305c2SJed Brown } 38779e8305c2SJed Brown 3878a4355906SMatthew Knepley /*@ 3879bc1eb3faSJed Brown 3880bc1eb3faSJed Brown DMPlexSetClosurePermutationTensor - Create a permutation from the default (BFS) point ordering in the closure, to a 3881bc1eb3faSJed Brown lexicographic ordering over the tensor product cell (i.e., line, quad, hex, etc.), and set this permutation in the 38821bb6d2a8SBarry Smith section provided (or the section of the DM). 3883a4355906SMatthew Knepley 3884a4355906SMatthew Knepley Input Parameters: 3885a4355906SMatthew Knepley + dm - The DM 3886a4355906SMatthew Knepley . point - Either a cell (highest dim point) or an edge (dim 1 point), or PETSC_DETERMINE 3887a4355906SMatthew Knepley - section - The PetscSection to reorder, or NULL for the default section 3888a4355906SMatthew Knepley 3889a4355906SMatthew Knepley Note: The point is used to determine the number of dofs/field on an edge. For SEM, this is related to the polynomial 3890a4355906SMatthew Knepley degree of the basis. 3891a4355906SMatthew Knepley 3892bc1eb3faSJed Brown Example: 3893bc1eb3faSJed Brown A typical interpolated single-quad mesh might order points as 3894bc1eb3faSJed Brown .vb 3895bc1eb3faSJed Brown [c0, v1, v2, v3, v4, e5, e6, e7, e8] 3896bc1eb3faSJed Brown 3897bc1eb3faSJed Brown v4 -- e6 -- v3 3898bc1eb3faSJed Brown | | 3899bc1eb3faSJed Brown e7 c0 e8 3900bc1eb3faSJed Brown | | 3901bc1eb3faSJed Brown v1 -- e5 -- v2 3902bc1eb3faSJed Brown .ve 3903bc1eb3faSJed Brown 3904bc1eb3faSJed Brown (There is no significance to the ordering described here.) The default section for a Q3 quad might typically assign 3905bc1eb3faSJed Brown dofs in the order of points, e.g., 3906bc1eb3faSJed Brown .vb 3907bc1eb3faSJed Brown c0 -> [0,1,2,3] 3908bc1eb3faSJed Brown v1 -> [4] 3909bc1eb3faSJed Brown ... 3910bc1eb3faSJed Brown e5 -> [8, 9] 3911bc1eb3faSJed Brown .ve 3912bc1eb3faSJed Brown 3913bc1eb3faSJed Brown which corresponds to the dofs 3914bc1eb3faSJed Brown .vb 3915bc1eb3faSJed Brown 6 10 11 7 3916bc1eb3faSJed Brown 13 2 3 15 3917bc1eb3faSJed Brown 12 0 1 14 3918bc1eb3faSJed Brown 4 8 9 5 3919bc1eb3faSJed Brown .ve 3920bc1eb3faSJed Brown 3921bc1eb3faSJed Brown The closure in BFS ordering works through height strata (cells, edges, vertices) to produce the ordering 3922bc1eb3faSJed Brown .vb 3923bc1eb3faSJed Brown 0 1 2 3 8 9 14 15 11 10 13 12 4 5 7 6 3924bc1eb3faSJed Brown .ve 3925bc1eb3faSJed Brown 3926bc1eb3faSJed Brown After calling DMPlexSetClosurePermutationTensor(), the closure will be ordered lexicographically, 3927bc1eb3faSJed Brown .vb 3928bc1eb3faSJed Brown 4 8 9 5 12 0 1 14 13 2 3 15 6 10 11 7 3929bc1eb3faSJed Brown .ve 3930bc1eb3faSJed Brown 3931a4355906SMatthew Knepley Level: developer 3932a4355906SMatthew Knepley 39331bb6d2a8SBarry Smith .seealso: DMGetLocalSection(), PetscSectionSetClosurePermutation(), DMSetGlocalSection() 3934a4355906SMatthew Knepley @*/ 3935bc1eb3faSJed Brown PetscErrorCode DMPlexSetClosurePermutationTensor(DM dm, PetscInt point, PetscSection section) 39363194fc30SMatthew G. Knepley { 39377391a63aSMatthew G. Knepley DMLabel label; 39383194fc30SMatthew G. Knepley PetscInt *perm; 3939a433471fSStefano Zampini PetscInt dim, depth = -1, eStart = -1, k, Nf, f, Nc, c, i, j, size = 0, offset = 0, foffset = 0; 39409e8305c2SJed Brown PetscBool vertexchart; 39413194fc30SMatthew G. Knepley PetscErrorCode ierr; 39423194fc30SMatthew G. Knepley 39433194fc30SMatthew G. Knepley PetscFunctionBegin; 39443194fc30SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 3945a433471fSStefano Zampini if (dim < 1) PetscFunctionReturn(0); 3946a433471fSStefano Zampini if (point < 0) { 3947a433471fSStefano Zampini PetscInt sStart,sEnd; 3948a433471fSStefano Zampini 3949a433471fSStefano Zampini ierr = DMPlexGetDepthStratum(dm, 1, &sStart, &sEnd);CHKERRQ(ierr); 3950a433471fSStefano Zampini point = sEnd-sStart ? sStart : point; 3951a433471fSStefano Zampini } 39527391a63aSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 3953a433471fSStefano Zampini if (point >= 0) { ierr = DMLabelGetValue(label, point, &depth);CHKERRQ(ierr); } 3954a433471fSStefano Zampini if (!section) {ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr);} 39557391a63aSMatthew G. Knepley if (depth == 1) {eStart = point;} 39567391a63aSMatthew G. Knepley else if (depth == dim) { 39577391a63aSMatthew G. Knepley const PetscInt *cone; 39587391a63aSMatthew G. Knepley 39597391a63aSMatthew G. Knepley ierr = DMPlexGetCone(dm, point, &cone);CHKERRQ(ierr); 3960d4e6627bSStefano Zampini if (dim == 2) eStart = cone[0]; 3961d4e6627bSStefano Zampini else if (dim == 3) { 3962d4e6627bSStefano Zampini const PetscInt *cone2; 3963d4e6627bSStefano Zampini ierr = DMPlexGetCone(dm, cone[0], &cone2);CHKERRQ(ierr); 3964d4e6627bSStefano Zampini eStart = cone2[0]; 3965d4e6627bSStefano 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); 3966a433471fSStefano Zampini } else if (depth >= 0) 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); 39679e8305c2SJed Brown { /* Determine whether the chart covers all points or just vertices. */ 39689e8305c2SJed Brown PetscInt pStart,pEnd,cStart,cEnd; 39699e8305c2SJed Brown ierr = DMPlexGetDepthStratum(dm,0,&pStart,&pEnd);CHKERRQ(ierr); 39709e8305c2SJed Brown ierr = PetscSectionGetChart(section,&cStart,&cEnd);CHKERRQ(ierr); 39719e8305c2SJed Brown if (pStart == cStart && pEnd == cEnd) vertexchart = PETSC_TRUE; /* Just vertices */ 39729e8305c2SJed Brown else vertexchart = PETSC_FALSE; /* Assume all interpolated points are in chart */ 39739e8305c2SJed Brown } 39743194fc30SMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &Nf);CHKERRQ(ierr); 39753194fc30SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 39769e8305c2SJed Brown ierr = PetscSectionFieldGetTensorDegree_Private(section,f,eStart,vertexchart,&Nc,&k);CHKERRQ(ierr); 397789eabcffSMatthew G. Knepley size += PetscPowInt(k+1, dim)*Nc; 39783194fc30SMatthew G. Knepley } 39793194fc30SMatthew G. Knepley ierr = PetscMalloc1(size, &perm);CHKERRQ(ierr); 39803194fc30SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 398189eabcffSMatthew G. Knepley switch (dim) { 3982babf31e0SJed Brown case 1: 39839e8305c2SJed Brown ierr = PetscSectionFieldGetTensorDegree_Private(section,f,eStart,vertexchart,&Nc,&k);CHKERRQ(ierr); 3984babf31e0SJed Brown /* 3985babf31e0SJed Brown Original ordering is [ edge of length k-1; vtx0; vtx1 ] 3986babf31e0SJed Brown We want [ vtx0; edge of length k-1; vtx1 ] 3987babf31e0SJed Brown */ 3988babf31e0SJed Brown for (c=0; c<Nc; c++,offset++) perm[offset] = (k-1)*Nc + c + foffset; 3989babf31e0SJed Brown for (i=0; i<k-1; i++) for (c=0; c<Nc; c++,offset++) perm[offset] = i*Nc + c + foffset; 3990babf31e0SJed Brown for (c=0; c<Nc; c++,offset++) perm[offset] = k*Nc + c + foffset; 3991babf31e0SJed Brown foffset = offset; 3992babf31e0SJed Brown break; 399389eabcffSMatthew G. Knepley case 2: 39943194fc30SMatthew 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} */ 39959e8305c2SJed Brown ierr = PetscSectionFieldGetTensorDegree_Private(section,f,eStart,vertexchart,&Nc,&k);CHKERRQ(ierr); 39963194fc30SMatthew G. Knepley /* The SEM order is 39973194fc30SMatthew G. Knepley 39983194fc30SMatthew G. Knepley v_lb, {e_b}, v_rb, 399989eabcffSMatthew G. Knepley e^{(k-1)-i}_l, {f^{i*(k-1)}}, e^i_r, 40003194fc30SMatthew G. Knepley v_lt, reverse {e_t}, v_rt 40013194fc30SMatthew G. Knepley */ 40023194fc30SMatthew G. Knepley { 40033194fc30SMatthew G. Knepley const PetscInt of = 0; 40043194fc30SMatthew G. Knepley const PetscInt oeb = of + PetscSqr(k-1); 40053194fc30SMatthew G. Knepley const PetscInt oer = oeb + (k-1); 40063194fc30SMatthew G. Knepley const PetscInt oet = oer + (k-1); 40073194fc30SMatthew G. Knepley const PetscInt oel = oet + (k-1); 40083194fc30SMatthew G. Knepley const PetscInt ovlb = oel + (k-1); 40093194fc30SMatthew G. Knepley const PetscInt ovrb = ovlb + 1; 40103194fc30SMatthew G. Knepley const PetscInt ovrt = ovrb + 1; 40113194fc30SMatthew G. Knepley const PetscInt ovlt = ovrt + 1; 40123194fc30SMatthew G. Knepley PetscInt o; 40133194fc30SMatthew G. Knepley 40143194fc30SMatthew G. Knepley /* bottom */ 40153194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovlb*Nc + c + foffset; 40163194fc30SMatthew G. Knepley for (o = oeb; o < oer; ++o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 40173194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovrb*Nc + c + foffset; 40183194fc30SMatthew G. Knepley /* middle */ 40193194fc30SMatthew G. Knepley for (i = 0; i < k-1; ++i) { 40203194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oel+(k-2)-i)*Nc + c + foffset; 40213194fc30SMatthew 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; 40223194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oer+i)*Nc + c + foffset; 40233194fc30SMatthew G. Knepley } 40243194fc30SMatthew G. Knepley /* top */ 40253194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovlt*Nc + c + foffset; 40263194fc30SMatthew G. Knepley for (o = oel-1; o >= oet; --o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 40273194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovrt*Nc + c + foffset; 40283194fc30SMatthew G. Knepley foffset = offset; 40293194fc30SMatthew G. Knepley } 403089eabcffSMatthew G. Knepley break; 403189eabcffSMatthew G. Knepley case 3: 403289eabcffSMatthew G. Knepley /* The original hex closure is 403389eabcffSMatthew G. Knepley 403489eabcffSMatthew G. Knepley {c, 403589eabcffSMatthew G. Knepley f_b, f_t, f_f, f_b, f_r, f_l, 403689eabcffSMatthew 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, 403789eabcffSMatthew G. Knepley v_blf, v_blb, v_brb, v_brf, v_tlf, v_trf, v_trb, v_tlb} 403889eabcffSMatthew G. Knepley */ 40399e8305c2SJed Brown ierr = PetscSectionFieldGetTensorDegree_Private(section,f,eStart,vertexchart,&Nc,&k);CHKERRQ(ierr); 404089eabcffSMatthew G. Knepley /* The SEM order is 404189eabcffSMatthew G. Knepley Bottom Slice 404289eabcffSMatthew G. Knepley v_blf, {e^{(k-1)-n}_bf}, v_brf, 404389eabcffSMatthew G. Knepley e^{i}_bl, f^{n*(k-1)+(k-1)-i}_b, e^{(k-1)-i}_br, 404489eabcffSMatthew G. Knepley v_blb, {e_bb}, v_brb, 404589eabcffSMatthew G. Knepley 404689eabcffSMatthew G. Knepley Middle Slice (j) 404789eabcffSMatthew G. Knepley {e^{(k-1)-j}_lf}, {f^{j*(k-1)+n}_f}, e^j_rf, 404889eabcffSMatthew G. Knepley f^{i*(k-1)+j}_l, {c^{(j*(k-1) + i)*(k-1)+n}_t}, f^{j*(k-1)+i}_r, 404989eabcffSMatthew G. Knepley e^j_lb, {f^{j*(k-1)+(k-1)-n}_b}, e^{(k-1)-j}_rb, 405089eabcffSMatthew G. Knepley 405189eabcffSMatthew G. Knepley Top Slice 405289eabcffSMatthew G. Knepley v_tlf, {e_tf}, v_trf, 405389eabcffSMatthew G. Knepley e^{(k-1)-i}_tl, {f^{i*(k-1)}_t}, e^{i}_tr, 405489eabcffSMatthew G. Knepley v_tlb, {e^{(k-1)-n}_tb}, v_trb, 405589eabcffSMatthew G. Knepley */ 405689eabcffSMatthew G. Knepley { 405789eabcffSMatthew G. Knepley const PetscInt oc = 0; 405889eabcffSMatthew G. Knepley const PetscInt ofb = oc + PetscSqr(k-1)*(k-1); 405989eabcffSMatthew G. Knepley const PetscInt oft = ofb + PetscSqr(k-1); 406089eabcffSMatthew G. Knepley const PetscInt off = oft + PetscSqr(k-1); 406189eabcffSMatthew G. Knepley const PetscInt ofk = off + PetscSqr(k-1); 406289eabcffSMatthew G. Knepley const PetscInt ofr = ofk + PetscSqr(k-1); 406389eabcffSMatthew G. Knepley const PetscInt ofl = ofr + PetscSqr(k-1); 406489eabcffSMatthew G. Knepley const PetscInt oebl = ofl + PetscSqr(k-1); 406589eabcffSMatthew G. Knepley const PetscInt oebb = oebl + (k-1); 406689eabcffSMatthew G. Knepley const PetscInt oebr = oebb + (k-1); 406789eabcffSMatthew G. Knepley const PetscInt oebf = oebr + (k-1); 406889eabcffSMatthew G. Knepley const PetscInt oetf = oebf + (k-1); 406989eabcffSMatthew G. Knepley const PetscInt oetr = oetf + (k-1); 407089eabcffSMatthew G. Knepley const PetscInt oetb = oetr + (k-1); 407189eabcffSMatthew G. Knepley const PetscInt oetl = oetb + (k-1); 407289eabcffSMatthew G. Knepley const PetscInt oerf = oetl + (k-1); 407389eabcffSMatthew G. Knepley const PetscInt oelf = oerf + (k-1); 407489eabcffSMatthew G. Knepley const PetscInt oelb = oelf + (k-1); 407589eabcffSMatthew G. Knepley const PetscInt oerb = oelb + (k-1); 407689eabcffSMatthew G. Knepley const PetscInt ovblf = oerb + (k-1); 407789eabcffSMatthew G. Knepley const PetscInt ovblb = ovblf + 1; 407889eabcffSMatthew G. Knepley const PetscInt ovbrb = ovblb + 1; 407989eabcffSMatthew G. Knepley const PetscInt ovbrf = ovbrb + 1; 408089eabcffSMatthew G. Knepley const PetscInt ovtlf = ovbrf + 1; 408189eabcffSMatthew G. Knepley const PetscInt ovtrf = ovtlf + 1; 408289eabcffSMatthew G. Knepley const PetscInt ovtrb = ovtrf + 1; 408389eabcffSMatthew G. Knepley const PetscInt ovtlb = ovtrb + 1; 408489eabcffSMatthew G. Knepley PetscInt o, n; 408589eabcffSMatthew G. Knepley 408689eabcffSMatthew G. Knepley /* Bottom Slice */ 408789eabcffSMatthew G. Knepley /* bottom */ 408889eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovblf*Nc + c + foffset; 408989eabcffSMatthew G. Knepley for (o = oetf-1; o >= oebf; --o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 409089eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovbrf*Nc + c + foffset; 409189eabcffSMatthew G. Knepley /* middle */ 409289eabcffSMatthew G. Knepley for (i = 0; i < k-1; ++i) { 409389eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oebl+i)*Nc + c + foffset; 4094316b7f87SMax 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;} 409589eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oebr+(k-2)-i)*Nc + c + foffset; 40963194fc30SMatthew G. Knepley } 409789eabcffSMatthew G. Knepley /* top */ 409889eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovblb*Nc + c + foffset; 409989eabcffSMatthew G. Knepley for (o = oebb; o < oebr; ++o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 410089eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovbrb*Nc + c + foffset; 410189eabcffSMatthew G. Knepley 410289eabcffSMatthew G. Knepley /* Middle Slice */ 410389eabcffSMatthew G. Knepley for (j = 0; j < k-1; ++j) { 410489eabcffSMatthew G. Knepley /* bottom */ 410589eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oelf+(k-2)-j)*Nc + c + foffset; 410689eabcffSMatthew 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; 410789eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oerf+j)*Nc + c + foffset; 410889eabcffSMatthew G. Knepley /* middle */ 410989eabcffSMatthew G. Knepley for (i = 0; i < k-1; ++i) { 411089eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (ofl+i*(k-1)+j)*Nc + c + foffset; 411189eabcffSMatthew 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; 411289eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (ofr+j*(k-1)+i)*Nc + c + foffset; 411389eabcffSMatthew G. Knepley } 411489eabcffSMatthew G. Knepley /* top */ 411589eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oelb+j)*Nc + c + foffset; 411689eabcffSMatthew 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; 411789eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oerb+(k-2)-j)*Nc + c + foffset; 411889eabcffSMatthew G. Knepley } 411989eabcffSMatthew G. Knepley 412089eabcffSMatthew G. Knepley /* Top Slice */ 412189eabcffSMatthew G. Knepley /* bottom */ 412289eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovtlf*Nc + c + foffset; 412389eabcffSMatthew G. Knepley for (o = oetf; o < oetr; ++o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 412489eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovtrf*Nc + c + foffset; 412589eabcffSMatthew G. Knepley /* middle */ 412689eabcffSMatthew G. Knepley for (i = 0; i < k-1; ++i) { 412789eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oetl+(k-2)-i)*Nc + c + foffset; 412889eabcffSMatthew 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; 412989eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oetr+i)*Nc + c + foffset; 413089eabcffSMatthew G. Knepley } 413189eabcffSMatthew G. Knepley /* top */ 413289eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovtlb*Nc + c + foffset; 413389eabcffSMatthew G. Knepley for (o = oetl-1; o >= oetb; --o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 413489eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovtrb*Nc + c + foffset; 413589eabcffSMatthew G. Knepley 413689eabcffSMatthew G. Knepley foffset = offset; 413789eabcffSMatthew G. Knepley } 413889eabcffSMatthew G. Knepley break; 413989eabcffSMatthew G. Knepley default: SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "No spectral ordering for dimension %D", dim); 414089eabcffSMatthew G. Knepley } 414189eabcffSMatthew G. Knepley } 414289eabcffSMatthew G. Knepley if (offset != size) SETERRQ2(PetscObjectComm((PetscObject) dm), PETSC_ERR_PLIB, "Number of permutation entries %D != %D", offset, size); 41433194fc30SMatthew G. Knepley /* Check permutation */ 41443194fc30SMatthew G. Knepley { 41453194fc30SMatthew G. Knepley PetscInt *check; 41463194fc30SMatthew G. Knepley 41473194fc30SMatthew G. Knepley ierr = PetscMalloc1(size, &check);CHKERRQ(ierr); 41483194fc30SMatthew 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]);} 41493194fc30SMatthew G. Knepley for (i = 0; i < size; ++i) check[perm[i]] = i; 41503194fc30SMatthew G. Knepley for (i = 0; i < size; ++i) {if (check[i] < 0) SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_PLIB, "Missing permutation index %D", i);} 41513194fc30SMatthew G. Knepley ierr = PetscFree(check);CHKERRQ(ierr); 41523194fc30SMatthew G. Knepley } 41531fdd32a2SMatthew G. Knepley ierr = PetscSectionSetClosurePermutation_Internal(section, (PetscObject) dm, size, PETSC_OWN_POINTER, perm);CHKERRQ(ierr); 41543194fc30SMatthew G. Knepley PetscFunctionReturn(0); 41553194fc30SMatthew G. Knepley } 41563194fc30SMatthew G. Knepley 4157e071409bSToby Isaac PetscErrorCode DMPlexGetPointDualSpaceFEM(DM dm, PetscInt point, PetscInt field, PetscDualSpace *dspace) 4158e071409bSToby Isaac { 4159e071409bSToby Isaac PetscDS prob; 4160e071409bSToby Isaac PetscInt depth, Nf, h; 4161e071409bSToby Isaac DMLabel label; 4162e071409bSToby Isaac PetscErrorCode ierr; 4163e071409bSToby Isaac 4164e071409bSToby Isaac PetscFunctionBeginHot; 4165e5e52638SMatthew G. Knepley ierr = DMGetDS(dm, &prob);CHKERRQ(ierr); 4166e071409bSToby Isaac Nf = prob->Nf; 4167e071409bSToby Isaac label = dm->depthLabel; 4168e071409bSToby Isaac *dspace = NULL; 4169e071409bSToby Isaac if (field < Nf) { 4170e071409bSToby Isaac PetscObject disc = prob->disc[field]; 4171e071409bSToby Isaac 4172e071409bSToby Isaac if (disc->classid == PETSCFE_CLASSID) { 4173e071409bSToby Isaac PetscDualSpace dsp; 4174e071409bSToby Isaac 4175e071409bSToby Isaac ierr = PetscFEGetDualSpace((PetscFE)disc,&dsp);CHKERRQ(ierr); 4176e071409bSToby Isaac ierr = DMLabelGetNumValues(label,&depth);CHKERRQ(ierr); 4177e071409bSToby Isaac ierr = DMLabelGetValue(label,point,&h);CHKERRQ(ierr); 4178e071409bSToby Isaac h = depth - 1 - h; 4179e071409bSToby Isaac if (h) { 4180e071409bSToby Isaac ierr = PetscDualSpaceGetHeightSubspace(dsp,h,dspace);CHKERRQ(ierr); 4181e071409bSToby Isaac } else { 4182e071409bSToby Isaac *dspace = dsp; 4183e071409bSToby Isaac } 4184e071409bSToby Isaac } 4185e071409bSToby Isaac } 4186e071409bSToby Isaac PetscFunctionReturn(0); 4187e071409bSToby Isaac } 4188e071409bSToby Isaac 4189e071409bSToby Isaac 41901a271a75SMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode DMPlexVecGetClosure_Depth1_Static(DM dm, PetscSection section, Vec v, PetscInt point, PetscInt *csize, PetscScalar *values[]) 4191a6dfd86eSKarl Rupp { 4192552f7358SJed Brown PetscScalar *array, *vArray; 4193d9917b9dSMatthew G. Knepley const PetscInt *cone, *coneO; 41941a271a75SMatthew G. Knepley PetscInt pStart, pEnd, p, numPoints, size = 0, offset = 0; 4195552f7358SJed Brown PetscErrorCode ierr; 4196552f7358SJed Brown 41971b406b76SMatthew G. Knepley PetscFunctionBeginHot; 41982a3aaacfSMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 41995a1bb5cfSMatthew G. Knepley ierr = DMPlexGetConeSize(dm, point, &numPoints);CHKERRQ(ierr); 42005a1bb5cfSMatthew G. Knepley ierr = DMPlexGetCone(dm, point, &cone);CHKERRQ(ierr); 42015a1bb5cfSMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, point, &coneO);CHKERRQ(ierr); 42023f7cbbe7SMatthew G. Knepley if (!values || !*values) { 42039df71ca4SMatthew G. Knepley if ((point >= pStart) && (point < pEnd)) { 42049df71ca4SMatthew G. Knepley PetscInt dof; 4205d9917b9dSMatthew G. Knepley 42069df71ca4SMatthew G. Knepley ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 42079df71ca4SMatthew G. Knepley size += dof; 42089df71ca4SMatthew G. Knepley } 42099df71ca4SMatthew G. Knepley for (p = 0; p < numPoints; ++p) { 42109df71ca4SMatthew G. Knepley const PetscInt cp = cone[p]; 42112a3aaacfSMatthew G. Knepley PetscInt dof; 42125a1bb5cfSMatthew G. Knepley 42135a1bb5cfSMatthew G. Knepley if ((cp < pStart) || (cp >= pEnd)) continue; 42142a3aaacfSMatthew G. Knepley ierr = PetscSectionGetDof(section, cp, &dof);CHKERRQ(ierr); 42155a1bb5cfSMatthew G. Knepley size += dof; 42165a1bb5cfSMatthew G. Knepley } 42173f7cbbe7SMatthew G. Knepley if (!values) { 42183f7cbbe7SMatthew G. Knepley if (csize) *csize = size; 42193f7cbbe7SMatthew G. Knepley PetscFunctionReturn(0); 42203f7cbbe7SMatthew G. Knepley } 422169291d52SBarry Smith ierr = DMGetWorkArray(dm, size, MPIU_SCALAR, &array);CHKERRQ(ierr); 4222982e9ed1SMatthew G. Knepley } else { 4223982e9ed1SMatthew G. Knepley array = *values; 4224982e9ed1SMatthew G. Knepley } 42259df71ca4SMatthew G. Knepley size = 0; 42265a1bb5cfSMatthew G. Knepley ierr = VecGetArray(v, &vArray);CHKERRQ(ierr); 42279df71ca4SMatthew G. Knepley if ((point >= pStart) && (point < pEnd)) { 42289df71ca4SMatthew G. Knepley PetscInt dof, off, d; 42299df71ca4SMatthew G. Knepley PetscScalar *varr; 4230d9917b9dSMatthew G. Knepley 42319df71ca4SMatthew G. Knepley ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 42329df71ca4SMatthew G. Knepley ierr = PetscSectionGetOffset(section, point, &off);CHKERRQ(ierr); 42339df71ca4SMatthew G. Knepley varr = &vArray[off]; 42341a271a75SMatthew G. Knepley for (d = 0; d < dof; ++d, ++offset) { 42351a271a75SMatthew G. Knepley array[offset] = varr[d]; 42369df71ca4SMatthew G. Knepley } 42379df71ca4SMatthew G. Knepley size += dof; 42389df71ca4SMatthew G. Knepley } 42399df71ca4SMatthew G. Knepley for (p = 0; p < numPoints; ++p) { 42409df71ca4SMatthew G. Knepley const PetscInt cp = cone[p]; 42419df71ca4SMatthew G. Knepley PetscInt o = coneO[p]; 42425a1bb5cfSMatthew G. Knepley PetscInt dof, off, d; 42435a1bb5cfSMatthew G. Knepley PetscScalar *varr; 42445a1bb5cfSMatthew G. Knepley 424552ed52e8SMatthew G. Knepley if ((cp < pStart) || (cp >= pEnd)) continue; 42465a1bb5cfSMatthew G. Knepley ierr = PetscSectionGetDof(section, cp, &dof);CHKERRQ(ierr); 42475a1bb5cfSMatthew G. Knepley ierr = PetscSectionGetOffset(section, cp, &off);CHKERRQ(ierr); 42485a1bb5cfSMatthew G. Knepley varr = &vArray[off]; 42495a1bb5cfSMatthew G. Knepley if (o >= 0) { 42501a271a75SMatthew G. Knepley for (d = 0; d < dof; ++d, ++offset) { 42511a271a75SMatthew G. Knepley array[offset] = varr[d]; 42525a1bb5cfSMatthew G. Knepley } 42535a1bb5cfSMatthew G. Knepley } else { 42541a271a75SMatthew G. Knepley for (d = dof-1; d >= 0; --d, ++offset) { 42551a271a75SMatthew G. Knepley array[offset] = varr[d]; 42565a1bb5cfSMatthew G. Knepley } 42575a1bb5cfSMatthew G. Knepley } 42589df71ca4SMatthew G. Knepley size += dof; 42595a1bb5cfSMatthew G. Knepley } 42605a1bb5cfSMatthew G. Knepley ierr = VecRestoreArray(v, &vArray);CHKERRQ(ierr); 42619df71ca4SMatthew G. Knepley if (!*values) { 42625a1bb5cfSMatthew G. Knepley if (csize) *csize = size; 42635a1bb5cfSMatthew G. Knepley *values = array; 42649df71ca4SMatthew G. Knepley } else { 42658ccfff9cSToby Isaac if (size > *csize) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Size of input array %D < actual size %D", *csize, size); 42668c312ff3SMatthew G. Knepley *csize = size; 42679df71ca4SMatthew G. Knepley } 42685a1bb5cfSMatthew G. Knepley PetscFunctionReturn(0); 42695a1bb5cfSMatthew G. Knepley } 4270d9917b9dSMatthew G. Knepley 42711dc59d61SMatthew G. Knepley PetscErrorCode DMPlexGetCompressedClosure(DM dm, PetscSection section, PetscInt point, PetscInt *numPoints, PetscInt **points, PetscSection *clSec, IS *clPoints, const PetscInt **clp) 4272923c78e0SToby Isaac { 4273923c78e0SToby Isaac const PetscInt *cla; 4274923c78e0SToby Isaac PetscInt np, *pts = NULL; 4275923c78e0SToby Isaac PetscErrorCode ierr; 4276923c78e0SToby Isaac 4277923c78e0SToby Isaac PetscFunctionBeginHot; 4278923c78e0SToby Isaac ierr = PetscSectionGetClosureIndex(section, (PetscObject) dm, clSec, clPoints);CHKERRQ(ierr); 4279923c78e0SToby Isaac if (!*clPoints) { 4280923c78e0SToby Isaac PetscInt pStart, pEnd, p, q; 4281923c78e0SToby Isaac 4282923c78e0SToby Isaac ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 4283923c78e0SToby Isaac ierr = DMPlexGetTransitiveClosure(dm, point, PETSC_TRUE, &np, &pts);CHKERRQ(ierr); 4284923c78e0SToby Isaac /* Compress out points not in the section */ 4285923c78e0SToby Isaac for (p = 0, q = 0; p < np; p++) { 4286923c78e0SToby Isaac PetscInt r = pts[2*p]; 4287923c78e0SToby Isaac if ((r >= pStart) && (r < pEnd)) { 4288923c78e0SToby Isaac pts[q*2] = r; 4289923c78e0SToby Isaac pts[q*2+1] = pts[2*p+1]; 4290923c78e0SToby Isaac ++q; 4291923c78e0SToby Isaac } 4292923c78e0SToby Isaac } 4293923c78e0SToby Isaac np = q; 4294923c78e0SToby Isaac cla = NULL; 4295923c78e0SToby Isaac } else { 4296923c78e0SToby Isaac PetscInt dof, off; 4297923c78e0SToby Isaac 4298923c78e0SToby Isaac ierr = PetscSectionGetDof(*clSec, point, &dof);CHKERRQ(ierr); 4299923c78e0SToby Isaac ierr = PetscSectionGetOffset(*clSec, point, &off);CHKERRQ(ierr); 4300923c78e0SToby Isaac ierr = ISGetIndices(*clPoints, &cla);CHKERRQ(ierr); 4301923c78e0SToby Isaac np = dof/2; 4302923c78e0SToby Isaac pts = (PetscInt *) &cla[off]; 4303923c78e0SToby Isaac } 4304923c78e0SToby Isaac *numPoints = np; 4305923c78e0SToby Isaac *points = pts; 4306923c78e0SToby Isaac *clp = cla; 4307923c78e0SToby Isaac 4308923c78e0SToby Isaac PetscFunctionReturn(0); 4309923c78e0SToby Isaac } 4310923c78e0SToby Isaac 43111dc59d61SMatthew G. Knepley PetscErrorCode DMPlexRestoreCompressedClosure(DM dm, PetscSection section, PetscInt point, PetscInt *numPoints, PetscInt **points, PetscSection *clSec, IS *clPoints, const PetscInt **clp) 4312923c78e0SToby Isaac { 4313923c78e0SToby Isaac PetscErrorCode ierr; 4314923c78e0SToby Isaac 4315923c78e0SToby Isaac PetscFunctionBeginHot; 4316923c78e0SToby Isaac if (!*clPoints) { 4317923c78e0SToby Isaac ierr = DMPlexRestoreTransitiveClosure(dm, point, PETSC_TRUE, numPoints, points);CHKERRQ(ierr); 4318923c78e0SToby Isaac } else { 4319923c78e0SToby Isaac ierr = ISRestoreIndices(*clPoints, clp);CHKERRQ(ierr); 4320923c78e0SToby Isaac } 4321923c78e0SToby Isaac *numPoints = 0; 4322923c78e0SToby Isaac *points = NULL; 4323923c78e0SToby Isaac *clSec = NULL; 4324923c78e0SToby Isaac *clPoints = NULL; 4325923c78e0SToby Isaac *clp = NULL; 4326923c78e0SToby Isaac PetscFunctionReturn(0); 4327923c78e0SToby Isaac } 4328923c78e0SToby Isaac 432997e99dd9SToby 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[]) 43301a271a75SMatthew G. Knepley { 43311a271a75SMatthew G. Knepley PetscInt offset = 0, p; 433297e99dd9SToby Isaac const PetscInt **perms = NULL; 433397e99dd9SToby Isaac const PetscScalar **flips = NULL; 43341a271a75SMatthew G. Knepley PetscErrorCode ierr; 43351a271a75SMatthew G. Knepley 43361a271a75SMatthew G. Knepley PetscFunctionBeginHot; 4337fe02ba77SJed Brown *size = 0; 433897e99dd9SToby Isaac ierr = PetscSectionGetPointSyms(section,numPoints,points,&perms,&flips);CHKERRQ(ierr); 433997e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 434097e99dd9SToby Isaac const PetscInt point = points[2*p]; 434197e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 434297e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 43431a271a75SMatthew G. Knepley PetscInt dof, off, d; 43441a271a75SMatthew G. Knepley const PetscScalar *varr; 43451a271a75SMatthew G. Knepley 43461a271a75SMatthew G. Knepley ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 43471a271a75SMatthew G. Knepley ierr = PetscSectionGetOffset(section, point, &off);CHKERRQ(ierr); 43481a271a75SMatthew G. Knepley varr = &vArray[off]; 434997e99dd9SToby Isaac if (clperm) { 435097e99dd9SToby Isaac if (perm) { 435197e99dd9SToby Isaac for (d = 0; d < dof; d++) array[clperm[offset + perm[d]]] = varr[d]; 43521a271a75SMatthew G. Knepley } else { 435397e99dd9SToby Isaac for (d = 0; d < dof; d++) array[clperm[offset + d ]] = varr[d]; 435497e99dd9SToby Isaac } 435597e99dd9SToby Isaac if (flip) { 435697e99dd9SToby Isaac for (d = 0; d < dof; d++) array[clperm[offset + d ]] *= flip[d]; 435797e99dd9SToby Isaac } 435897e99dd9SToby Isaac } else { 435997e99dd9SToby Isaac if (perm) { 436097e99dd9SToby Isaac for (d = 0; d < dof; d++) array[offset + perm[d]] = varr[d]; 436197e99dd9SToby Isaac } else { 436297e99dd9SToby Isaac for (d = 0; d < dof; d++) array[offset + d ] = varr[d]; 436397e99dd9SToby Isaac } 436497e99dd9SToby Isaac if (flip) { 436597e99dd9SToby Isaac for (d = 0; d < dof; d++) array[offset + d ] *= flip[d]; 43661a271a75SMatthew G. Knepley } 43671a271a75SMatthew G. Knepley } 436897e99dd9SToby Isaac offset += dof; 436997e99dd9SToby Isaac } 437097e99dd9SToby Isaac ierr = PetscSectionRestorePointSyms(section,numPoints,points,&perms,&flips);CHKERRQ(ierr); 43711a271a75SMatthew G. Knepley *size = offset; 43721a271a75SMatthew G. Knepley PetscFunctionReturn(0); 43731a271a75SMatthew G. Knepley } 43741a271a75SMatthew G. Knepley 437597e99dd9SToby 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[]) 43761a271a75SMatthew G. Knepley { 43771a271a75SMatthew G. Knepley PetscInt offset = 0, f; 43781a271a75SMatthew G. Knepley PetscErrorCode ierr; 43791a271a75SMatthew G. Knepley 43801a271a75SMatthew G. Knepley PetscFunctionBeginHot; 4381fe02ba77SJed Brown *size = 0; 43821a271a75SMatthew G. Knepley for (f = 0; f < numFields; ++f) { 438397e99dd9SToby Isaac PetscInt p; 438497e99dd9SToby Isaac const PetscInt **perms = NULL; 438597e99dd9SToby Isaac const PetscScalar **flips = NULL; 43861a271a75SMatthew G. Knepley 438797e99dd9SToby Isaac ierr = PetscSectionGetFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 438897e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 438997e99dd9SToby Isaac const PetscInt point = points[2*p]; 439097e99dd9SToby Isaac PetscInt fdof, foff, b; 43911a271a75SMatthew G. Knepley const PetscScalar *varr; 439297e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 439397e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 43941a271a75SMatthew G. Knepley 43951a271a75SMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 43961a271a75SMatthew G. Knepley ierr = PetscSectionGetFieldOffset(section, point, f, &foff);CHKERRQ(ierr); 43971a271a75SMatthew G. Knepley varr = &vArray[foff]; 439897e99dd9SToby Isaac if (clperm) { 439997e99dd9SToby Isaac if (perm) {for (b = 0; b < fdof; b++) {array[clperm[offset + perm[b]]] = varr[b];}} 440097e99dd9SToby Isaac else {for (b = 0; b < fdof; b++) {array[clperm[offset + b ]] = varr[b];}} 440197e99dd9SToby Isaac if (flip) {for (b = 0; b < fdof; b++) {array[clperm[offset + b ]] *= flip[b];}} 44021a271a75SMatthew G. Knepley } else { 440397e99dd9SToby Isaac if (perm) {for (b = 0; b < fdof; b++) {array[offset + perm[b]] = varr[b];}} 440497e99dd9SToby Isaac else {for (b = 0; b < fdof; b++) {array[offset + b ] = varr[b];}} 440597e99dd9SToby Isaac if (flip) {for (b = 0; b < fdof; b++) {array[offset + b ] *= flip[b];}} 44061a271a75SMatthew G. Knepley } 440797e99dd9SToby Isaac offset += fdof; 44081a271a75SMatthew G. Knepley } 440997e99dd9SToby Isaac ierr = PetscSectionRestoreFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 44101a271a75SMatthew G. Knepley } 44111a271a75SMatthew G. Knepley *size = offset; 44121a271a75SMatthew G. Knepley PetscFunctionReturn(0); 44131a271a75SMatthew G. Knepley } 44141a271a75SMatthew G. Knepley 4415552f7358SJed Brown /*@C 4416552f7358SJed Brown DMPlexVecGetClosure - Get an array of the values on the closure of 'point' 4417552f7358SJed Brown 4418552f7358SJed Brown Not collective 4419552f7358SJed Brown 4420552f7358SJed Brown Input Parameters: 4421552f7358SJed Brown + dm - The DM 4422552f7358SJed Brown . section - The section describing the layout in v, or NULL to use the default section 4423552f7358SJed Brown . v - The local vector 442422c1ee49SMatthew G. Knepley . point - The point in the DM 442522c1ee49SMatthew G. Knepley . csize - The size of the input values array, or NULL 442622c1ee49SMatthew G. Knepley - values - An array to use for the values, or NULL to have it allocated automatically 4427552f7358SJed Brown 4428552f7358SJed Brown Output Parameters: 442922c1ee49SMatthew G. Knepley + csize - The number of values in the closure 443022c1ee49SMatthew G. Knepley - values - The array of values. If the user provided NULL, it is a borrowed array and should not be freed 443122c1ee49SMatthew G. Knepley 443222c1ee49SMatthew G. Knepley $ Note that DMPlexVecGetClosure/DMPlexVecRestoreClosure only allocates the values array if it set to NULL in the 443322c1ee49SMatthew G. Knepley $ calling function. This is because DMPlexVecGetClosure() is typically called in the inner loop of a Vec or Mat 443422c1ee49SMatthew G. Knepley $ assembly function, and a user may already have allocated storage for this operation. 443522c1ee49SMatthew G. Knepley $ 443622c1ee49SMatthew G. Knepley $ A typical use could be 443722c1ee49SMatthew G. Knepley $ 443822c1ee49SMatthew G. Knepley $ values = NULL; 443922c1ee49SMatthew G. Knepley $ ierr = DMPlexVecGetClosure(dm, NULL, v, p, &clSize, &values);CHKERRQ(ierr); 444022c1ee49SMatthew G. Knepley $ for (cl = 0; cl < clSize; ++cl) { 444122c1ee49SMatthew G. Knepley $ <Compute on closure> 444222c1ee49SMatthew G. Knepley $ } 444322c1ee49SMatthew G. Knepley $ ierr = DMPlexVecRestoreClosure(dm, NULL, v, p, &clSize, &values);CHKERRQ(ierr); 444422c1ee49SMatthew G. Knepley $ 444522c1ee49SMatthew G. Knepley $ or 444622c1ee49SMatthew G. Knepley $ 444722c1ee49SMatthew G. Knepley $ PetscMalloc1(clMaxSize, &values); 444822c1ee49SMatthew G. Knepley $ for (p = pStart; p < pEnd; ++p) { 444922c1ee49SMatthew G. Knepley $ clSize = clMaxSize; 445022c1ee49SMatthew G. Knepley $ ierr = DMPlexVecGetClosure(dm, NULL, v, p, &clSize, &values);CHKERRQ(ierr); 445122c1ee49SMatthew G. Knepley $ for (cl = 0; cl < clSize; ++cl) { 445222c1ee49SMatthew G. Knepley $ <Compute on closure> 445322c1ee49SMatthew G. Knepley $ } 445422c1ee49SMatthew G. Knepley $ } 445522c1ee49SMatthew G. Knepley $ PetscFree(values); 4456552f7358SJed Brown 4457552f7358SJed Brown Fortran Notes: 4458552f7358SJed Brown Since it returns an array, this routine is only available in Fortran 90, and you must 4459552f7358SJed Brown include petsc.h90 in your code. 4460552f7358SJed Brown 4461552f7358SJed Brown The csize argument is not present in the Fortran 90 binding since it is internal to the array. 4462552f7358SJed Brown 4463552f7358SJed Brown Level: intermediate 4464552f7358SJed Brown 4465552f7358SJed Brown .seealso DMPlexVecRestoreClosure(), DMPlexVecSetClosure(), DMPlexMatSetClosure() 4466552f7358SJed Brown @*/ 4467552f7358SJed Brown PetscErrorCode DMPlexVecGetClosure(DM dm, PetscSection section, Vec v, PetscInt point, PetscInt *csize, PetscScalar *values[]) 4468552f7358SJed Brown { 4469552f7358SJed Brown PetscSection clSection; 4470d9917b9dSMatthew G. Knepley IS clPoints; 44718a84db2dSMatthew G. Knepley PetscScalar *array; 44728a84db2dSMatthew G. Knepley const PetscScalar *vArray; 4473552f7358SJed Brown PetscInt *points = NULL; 44748f3be42fSMatthew G. Knepley const PetscInt *clp, *perm; 44751a271a75SMatthew G. Knepley PetscInt depth, numFields, numPoints, size; 4476552f7358SJed Brown PetscErrorCode ierr; 4477552f7358SJed Brown 4478d9917b9dSMatthew G. Knepley PetscFunctionBeginHot; 4479552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 448092fd8e1eSJed Brown if (!section) {ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr);} 44811a271a75SMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 44821a271a75SMatthew G. Knepley PetscValidHeaderSpecific(v, VEC_CLASSID, 3); 4483552f7358SJed Brown ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 4484552f7358SJed Brown ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 4485552f7358SJed Brown if (depth == 1 && numFields < 2) { 44861a271a75SMatthew G. Knepley ierr = DMPlexVecGetClosure_Depth1_Static(dm, section, v, point, csize, values);CHKERRQ(ierr); 4487552f7358SJed Brown PetscFunctionReturn(0); 4488552f7358SJed Brown } 44891a271a75SMatthew G. Knepley /* Get points */ 4490923c78e0SToby Isaac ierr = DMPlexGetCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 44911fdd32a2SMatthew G. Knepley ierr = PetscSectionGetClosureInversePermutation_Internal(section, (PetscObject) dm, NULL, &perm);CHKERRQ(ierr); 44921a271a75SMatthew G. Knepley /* Get array */ 4493bd6c0d32SMatthew G. Knepley if (!values || !*values) { 44941a271a75SMatthew G. Knepley PetscInt asize = 0, dof, p; 4495552f7358SJed Brown 44961a271a75SMatthew G. Knepley for (p = 0; p < numPoints*2; p += 2) { 4497552f7358SJed Brown ierr = PetscSectionGetDof(section, points[p], &dof);CHKERRQ(ierr); 44981a271a75SMatthew G. Knepley asize += dof; 4499552f7358SJed Brown } 4500bd6c0d32SMatthew G. Knepley if (!values) { 4501923c78e0SToby Isaac ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 45021a271a75SMatthew G. Knepley if (csize) *csize = asize; 4503bd6c0d32SMatthew G. Knepley PetscFunctionReturn(0); 4504bd6c0d32SMatthew G. Knepley } 450569291d52SBarry Smith ierr = DMGetWorkArray(dm, asize, MPIU_SCALAR, &array);CHKERRQ(ierr); 4506d0f6b257SMatthew G. Knepley } else { 4507d0f6b257SMatthew G. Knepley array = *values; 4508d0f6b257SMatthew G. Knepley } 45098a84db2dSMatthew G. Knepley ierr = VecGetArrayRead(v, &vArray);CHKERRQ(ierr); 45101a271a75SMatthew G. Knepley /* Get values */ 451197e99dd9SToby Isaac if (numFields > 0) {ierr = DMPlexVecGetClosure_Fields_Static(dm, section, numPoints, points, numFields, perm, vArray, &size, array);CHKERRQ(ierr);} 451297e99dd9SToby Isaac else {ierr = DMPlexVecGetClosure_Static(dm, section, numPoints, points, perm, vArray, &size, array);CHKERRQ(ierr);} 45131a271a75SMatthew G. Knepley /* Cleanup points */ 4514923c78e0SToby Isaac ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 45151a271a75SMatthew G. Knepley /* Cleanup array */ 45168a84db2dSMatthew G. Knepley ierr = VecRestoreArrayRead(v, &vArray);CHKERRQ(ierr); 4517d0f6b257SMatthew G. Knepley if (!*values) { 4518552f7358SJed Brown if (csize) *csize = size; 4519552f7358SJed Brown *values = array; 4520d0f6b257SMatthew G. Knepley } else { 4521f347f43bSBarry Smith if (size > *csize) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Size of input array %D < actual size %D", *csize, size); 4522d0f6b257SMatthew G. Knepley *csize = size; 4523d0f6b257SMatthew G. Knepley } 4524552f7358SJed Brown PetscFunctionReturn(0); 4525552f7358SJed Brown } 4526552f7358SJed Brown 4527552f7358SJed Brown /*@C 4528552f7358SJed Brown DMPlexVecRestoreClosure - Restore the array of the values on the closure of 'point' 4529552f7358SJed Brown 4530552f7358SJed Brown Not collective 4531552f7358SJed Brown 4532552f7358SJed Brown Input Parameters: 4533552f7358SJed Brown + dm - The DM 45340298fd71SBarry Smith . section - The section describing the layout in v, or NULL to use the default section 4535552f7358SJed Brown . v - The local vector 4536eaf898f9SPatrick Sanan . point - The point in the DM 45370298fd71SBarry Smith . csize - The number of values in the closure, or NULL 4538552f7358SJed Brown - values - The array of values, which is a borrowed array and should not be freed 4539552f7358SJed Brown 454022c1ee49SMatthew 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() 454122c1ee49SMatthew G. Knepley 45423813dfbdSMatthew G Knepley Fortran Notes: 45433813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 45443813dfbdSMatthew G Knepley include petsc.h90 in your code. 45453813dfbdSMatthew G Knepley 45463813dfbdSMatthew G Knepley The csize argument is not present in the Fortran 90 binding since it is internal to the array. 45473813dfbdSMatthew G Knepley 4548552f7358SJed Brown Level: intermediate 4549552f7358SJed Brown 4550552f7358SJed Brown .seealso DMPlexVecGetClosure(), DMPlexVecSetClosure(), DMPlexMatSetClosure() 4551552f7358SJed Brown @*/ 45527c1f9639SMatthew G Knepley PetscErrorCode DMPlexVecRestoreClosure(DM dm, PetscSection section, Vec v, PetscInt point, PetscInt *csize, PetscScalar *values[]) 4553a6dfd86eSKarl Rupp { 4554552f7358SJed Brown PetscInt size = 0; 4555552f7358SJed Brown PetscErrorCode ierr; 4556552f7358SJed Brown 4557552f7358SJed Brown PetscFunctionBegin; 4558552f7358SJed Brown /* Should work without recalculating size */ 455969291d52SBarry Smith ierr = DMRestoreWorkArray(dm, size, MPIU_SCALAR, (void*) values);CHKERRQ(ierr); 4560c9fdaa05SMatthew G. Knepley *values = NULL; 4561552f7358SJed Brown PetscFunctionReturn(0); 4562552f7358SJed Brown } 4563552f7358SJed Brown 4564552f7358SJed Brown PETSC_STATIC_INLINE void add (PetscScalar *x, PetscScalar y) {*x += y;} 4565552f7358SJed Brown PETSC_STATIC_INLINE void insert(PetscScalar *x, PetscScalar y) {*x = y;} 4566552f7358SJed Brown 456797e99dd9SToby 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[]) 4568552f7358SJed Brown { 4569552f7358SJed Brown PetscInt cdof; /* The number of constraints on this point */ 4570552f7358SJed Brown const PetscInt *cdofs; /* The indices of the constrained dofs on this point */ 4571552f7358SJed Brown PetscScalar *a; 4572552f7358SJed Brown PetscInt off, cind = 0, k; 4573552f7358SJed Brown PetscErrorCode ierr; 4574552f7358SJed Brown 4575552f7358SJed Brown PetscFunctionBegin; 4576552f7358SJed Brown ierr = PetscSectionGetConstraintDof(section, point, &cdof);CHKERRQ(ierr); 4577552f7358SJed Brown ierr = PetscSectionGetOffset(section, point, &off);CHKERRQ(ierr); 4578552f7358SJed Brown a = &array[off]; 4579552f7358SJed Brown if (!cdof || setBC) { 458097e99dd9SToby Isaac if (clperm) { 458197e99dd9SToby Isaac if (perm) {for (k = 0; k < dof; ++k) {fuse(&a[k], values[clperm[offset+perm[k]]] * (flip ? flip[perm[k]] : 1.));}} 458297e99dd9SToby Isaac else {for (k = 0; k < dof; ++k) {fuse(&a[k], values[clperm[offset+ k ]] * (flip ? flip[ k ] : 1.));}} 4583552f7358SJed Brown } else { 458497e99dd9SToby Isaac if (perm) {for (k = 0; k < dof; ++k) {fuse(&a[k], values[offset+perm[k]] * (flip ? flip[perm[k]] : 1.));}} 458597e99dd9SToby Isaac else {for (k = 0; k < dof; ++k) {fuse(&a[k], values[offset+ k ] * (flip ? flip[ k ] : 1.));}} 4586552f7358SJed Brown } 4587552f7358SJed Brown } else { 4588552f7358SJed Brown ierr = PetscSectionGetConstraintIndices(section, point, &cdofs);CHKERRQ(ierr); 458997e99dd9SToby Isaac if (clperm) { 459097e99dd9SToby Isaac if (perm) {for (k = 0; k < dof; ++k) { 4591552f7358SJed Brown if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 459297e99dd9SToby Isaac fuse(&a[k], values[clperm[offset+perm[k]]] * (flip ? flip[perm[k]] : 1.)); 4593552f7358SJed Brown } 4594552f7358SJed Brown } else { 4595552f7358SJed Brown for (k = 0; k < dof; ++k) { 4596552f7358SJed Brown if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 459797e99dd9SToby Isaac fuse(&a[k], values[clperm[offset+ k ]] * (flip ? flip[ k ] : 1.)); 459897e99dd9SToby Isaac } 459997e99dd9SToby Isaac } 460097e99dd9SToby Isaac } else { 460197e99dd9SToby Isaac if (perm) { 460297e99dd9SToby Isaac for (k = 0; k < dof; ++k) { 460397e99dd9SToby Isaac if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 460497e99dd9SToby Isaac fuse(&a[k], values[offset+perm[k]] * (flip ? flip[perm[k]] : 1.)); 460597e99dd9SToby Isaac } 460697e99dd9SToby Isaac } else { 460797e99dd9SToby Isaac for (k = 0; k < dof; ++k) { 460897e99dd9SToby Isaac if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 460997e99dd9SToby Isaac fuse(&a[k], values[offset+ k ] * (flip ? flip[ k ] : 1.)); 461097e99dd9SToby Isaac } 4611552f7358SJed Brown } 4612552f7358SJed Brown } 4613552f7358SJed Brown } 4614552f7358SJed Brown PetscFunctionReturn(0); 4615552f7358SJed Brown } 4616552f7358SJed Brown 461797e99dd9SToby 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[]) 4618a5e93ea8SMatthew G. Knepley { 4619a5e93ea8SMatthew G. Knepley PetscInt cdof; /* The number of constraints on this point */ 4620a5e93ea8SMatthew G. Knepley const PetscInt *cdofs; /* The indices of the constrained dofs on this point */ 4621a5e93ea8SMatthew G. Knepley PetscScalar *a; 4622a5e93ea8SMatthew G. Knepley PetscInt off, cind = 0, k; 4623a5e93ea8SMatthew G. Knepley PetscErrorCode ierr; 4624a5e93ea8SMatthew G. Knepley 4625a5e93ea8SMatthew G. Knepley PetscFunctionBegin; 4626a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(section, point, &cdof);CHKERRQ(ierr); 4627a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetOffset(section, point, &off);CHKERRQ(ierr); 4628a5e93ea8SMatthew G. Knepley a = &array[off]; 4629a5e93ea8SMatthew G. Knepley if (cdof) { 4630a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetConstraintIndices(section, point, &cdofs);CHKERRQ(ierr); 463197e99dd9SToby Isaac if (clperm) { 463297e99dd9SToby Isaac if (perm) { 4633a5e93ea8SMatthew G. Knepley for (k = 0; k < dof; ++k) { 4634a5e93ea8SMatthew G. Knepley if ((cind < cdof) && (k == cdofs[cind])) { 463597e99dd9SToby Isaac fuse(&a[k], values[clperm[offset+perm[k]]] * (flip ? flip[perm[k]] : 1.)); 463697e99dd9SToby Isaac cind++; 4637a5e93ea8SMatthew G. Knepley } 4638a5e93ea8SMatthew G. Knepley } 4639a5e93ea8SMatthew G. Knepley } else { 4640a5e93ea8SMatthew G. Knepley for (k = 0; k < dof; ++k) { 4641a5e93ea8SMatthew G. Knepley if ((cind < cdof) && (k == cdofs[cind])) { 464297e99dd9SToby Isaac fuse(&a[k], values[clperm[offset+ k ]] * (flip ? flip[ k ] : 1.)); 464397e99dd9SToby Isaac cind++; 464497e99dd9SToby Isaac } 464597e99dd9SToby Isaac } 464697e99dd9SToby Isaac } 464797e99dd9SToby Isaac } else { 464897e99dd9SToby Isaac if (perm) { 464997e99dd9SToby Isaac for (k = 0; k < dof; ++k) { 465097e99dd9SToby Isaac if ((cind < cdof) && (k == cdofs[cind])) { 465197e99dd9SToby Isaac fuse(&a[k], values[offset+perm[k]] * (flip ? flip[perm[k]] : 1.)); 465297e99dd9SToby Isaac cind++; 465397e99dd9SToby Isaac } 465497e99dd9SToby Isaac } 465597e99dd9SToby Isaac } else { 465697e99dd9SToby Isaac for (k = 0; k < dof; ++k) { 465797e99dd9SToby Isaac if ((cind < cdof) && (k == cdofs[cind])) { 465897e99dd9SToby Isaac fuse(&a[k], values[offset+ k ] * (flip ? flip[ k ] : 1.)); 465997e99dd9SToby Isaac cind++; 466097e99dd9SToby Isaac } 4661a5e93ea8SMatthew G. Knepley } 4662a5e93ea8SMatthew G. Knepley } 4663a5e93ea8SMatthew G. Knepley } 4664a5e93ea8SMatthew G. Knepley } 4665a5e93ea8SMatthew G. Knepley PetscFunctionReturn(0); 4666a5e93ea8SMatthew G. Knepley } 4667a5e93ea8SMatthew G. Knepley 466897e99dd9SToby 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[]) 4669a6dfd86eSKarl Rupp { 4670552f7358SJed Brown PetscScalar *a; 46711a271a75SMatthew G. Knepley PetscInt fdof, foff, fcdof, foffset = *offset; 46721a271a75SMatthew G. Knepley const PetscInt *fcdofs; /* The indices of the constrained dofs for field f on this point */ 467397e99dd9SToby Isaac PetscInt cind = 0, b; 4674552f7358SJed Brown PetscErrorCode ierr; 4675552f7358SJed Brown 4676552f7358SJed Brown PetscFunctionBegin; 4677552f7358SJed Brown ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 4678552f7358SJed Brown ierr = PetscSectionGetFieldConstraintDof(section, point, f, &fcdof);CHKERRQ(ierr); 46791a271a75SMatthew G. Knepley ierr = PetscSectionGetFieldOffset(section, point, f, &foff);CHKERRQ(ierr); 46801a271a75SMatthew G. Knepley a = &array[foff]; 4681552f7358SJed Brown if (!fcdof || setBC) { 468297e99dd9SToby Isaac if (clperm) { 468397e99dd9SToby Isaac if (perm) {for (b = 0; b < fdof; b++) {fuse(&a[b], values[clperm[foffset+perm[b]]] * (flip ? flip[perm[b]] : 1.));}} 468497e99dd9SToby Isaac else {for (b = 0; b < fdof; b++) {fuse(&a[b], values[clperm[foffset+ b ]] * (flip ? flip[ b ] : 1.));}} 4685552f7358SJed Brown } else { 468697e99dd9SToby Isaac if (perm) {for (b = 0; b < fdof; b++) {fuse(&a[b], values[foffset+perm[b]] * (flip ? flip[perm[b]] : 1.));}} 468797e99dd9SToby Isaac else {for (b = 0; b < fdof; b++) {fuse(&a[b], values[foffset+ b ] * (flip ? flip[ b ] : 1.));}} 4688552f7358SJed Brown } 4689552f7358SJed Brown } else { 4690552f7358SJed Brown ierr = PetscSectionGetFieldConstraintIndices(section, point, f, &fcdofs);CHKERRQ(ierr); 469197e99dd9SToby Isaac if (clperm) { 469297e99dd9SToby Isaac if (perm) { 469397e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 469497e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; continue;} 469597e99dd9SToby Isaac fuse(&a[b], values[clperm[foffset+perm[b]]] * (flip ? flip[perm[b]] : 1.)); 4696552f7358SJed Brown } 4697552f7358SJed Brown } else { 469897e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 469997e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; continue;} 470097e99dd9SToby Isaac fuse(&a[b], values[clperm[foffset+ b ]] * (flip ? flip[ b ] : 1.)); 470197e99dd9SToby Isaac } 470297e99dd9SToby Isaac } 470397e99dd9SToby Isaac } else { 470497e99dd9SToby Isaac if (perm) { 470597e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 470697e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; continue;} 470797e99dd9SToby Isaac fuse(&a[b], values[foffset+perm[b]] * (flip ? flip[perm[b]] : 1.)); 470897e99dd9SToby Isaac } 470997e99dd9SToby Isaac } else { 471097e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 471197e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; continue;} 471297e99dd9SToby Isaac fuse(&a[b], values[foffset+ b ] * (flip ? flip[ b ] : 1.)); 4713552f7358SJed Brown } 4714552f7358SJed Brown } 4715552f7358SJed Brown } 4716552f7358SJed Brown } 47171a271a75SMatthew G. Knepley *offset += fdof; 4718552f7358SJed Brown PetscFunctionReturn(0); 4719552f7358SJed Brown } 4720552f7358SJed Brown 4721ba322698SMatthew 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[]) 4722a5e93ea8SMatthew G. Knepley { 4723a5e93ea8SMatthew G. Knepley PetscScalar *a; 47241a271a75SMatthew G. Knepley PetscInt fdof, foff, fcdof, foffset = *offset; 47251a271a75SMatthew G. Knepley const PetscInt *fcdofs; /* The indices of the constrained dofs for field f on this point */ 4726ba322698SMatthew G. Knepley PetscInt cind = 0, ncind = 0, b; 4727ba322698SMatthew G. Knepley PetscBool ncSet, fcSet; 4728a5e93ea8SMatthew G. Knepley PetscErrorCode ierr; 4729a5e93ea8SMatthew G. Knepley 4730a5e93ea8SMatthew G. Knepley PetscFunctionBegin; 4731a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 4732a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetFieldConstraintDof(section, point, f, &fcdof);CHKERRQ(ierr); 47331a271a75SMatthew G. Knepley ierr = PetscSectionGetFieldOffset(section, point, f, &foff);CHKERRQ(ierr); 47341a271a75SMatthew G. Knepley a = &array[foff]; 4735a5e93ea8SMatthew G. Knepley if (fcdof) { 4736ba322698SMatthew G. Knepley /* We just override fcdof and fcdofs with Ncc and comps */ 4737a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetFieldConstraintIndices(section, point, f, &fcdofs);CHKERRQ(ierr); 473897e99dd9SToby Isaac if (clperm) { 473997e99dd9SToby Isaac if (perm) { 4740ba322698SMatthew G. Knepley if (comps) { 4741ba322698SMatthew G. Knepley for (b = 0; b < fdof; b++) { 4742ba322698SMatthew G. Knepley ncSet = fcSet = PETSC_FALSE; 4743ba322698SMatthew G. Knepley if ((ncind < Ncc) && (b == comps[ncind])) {++ncind; ncSet = PETSC_TRUE;} 4744ba322698SMatthew G. Knepley if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; fcSet = PETSC_TRUE;} 4745ba322698SMatthew G. Knepley if (ncSet && fcSet) {fuse(&a[b], values[clperm[foffset+perm[b]]] * (flip ? flip[perm[b]] : 1.));} 4746ba322698SMatthew G. Knepley } 4747ba322698SMatthew G. Knepley } else { 474897e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 474997e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) { 475097e99dd9SToby Isaac fuse(&a[b], values[clperm[foffset+perm[b]]] * (flip ? flip[perm[b]] : 1.)); 4751a5e93ea8SMatthew G. Knepley ++cind; 4752a5e93ea8SMatthew G. Knepley } 4753a5e93ea8SMatthew G. Knepley } 4754ba322698SMatthew G. Knepley } 4755ba322698SMatthew G. Knepley } else { 4756ba322698SMatthew G. Knepley if (comps) { 4757ba322698SMatthew G. Knepley for (b = 0; b < fdof; b++) { 4758ba322698SMatthew G. Knepley ncSet = fcSet = PETSC_FALSE; 4759ba322698SMatthew G. Knepley if ((ncind < Ncc) && (b == comps[ncind])) {++ncind; ncSet = PETSC_TRUE;} 4760ba322698SMatthew G. Knepley if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; fcSet = PETSC_TRUE;} 4761ba322698SMatthew G. Knepley if (ncSet && fcSet) {fuse(&a[b], values[clperm[foffset+ b ]] * (flip ? flip[ b ] : 1.));} 4762ba322698SMatthew G. Knepley } 4763a5e93ea8SMatthew G. Knepley } else { 476497e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 476597e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) { 476697e99dd9SToby Isaac fuse(&a[b], values[clperm[foffset+ b ]] * (flip ? flip[ b ] : 1.)); 476797e99dd9SToby Isaac ++cind; 476897e99dd9SToby Isaac } 476997e99dd9SToby Isaac } 477097e99dd9SToby Isaac } 4771ba322698SMatthew G. Knepley } 477297e99dd9SToby Isaac } else { 477397e99dd9SToby Isaac if (perm) { 4774ba322698SMatthew G. Knepley if (comps) { 4775ba322698SMatthew G. Knepley for (b = 0; b < fdof; b++) { 4776ba322698SMatthew G. Knepley ncSet = fcSet = PETSC_FALSE; 4777ba322698SMatthew G. Knepley if ((ncind < Ncc) && (b == comps[ncind])) {++ncind; ncSet = PETSC_TRUE;} 4778ba322698SMatthew G. Knepley if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; fcSet = PETSC_TRUE;} 4779ba322698SMatthew G. Knepley if (ncSet && fcSet) {fuse(&a[b], values[foffset+perm[b]] * (flip ? flip[perm[b]] : 1.));} 4780ba322698SMatthew G. Knepley } 4781ba322698SMatthew G. Knepley } else { 478297e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 478397e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) { 478497e99dd9SToby Isaac fuse(&a[b], values[foffset+perm[b]] * (flip ? flip[perm[b]] : 1.)); 478597e99dd9SToby Isaac ++cind; 478697e99dd9SToby Isaac } 478797e99dd9SToby Isaac } 4788ba322698SMatthew G. Knepley } 4789ba322698SMatthew G. Knepley } else { 4790ba322698SMatthew G. Knepley if (comps) { 4791ba322698SMatthew G. Knepley for (b = 0; b < fdof; b++) { 4792ba322698SMatthew G. Knepley ncSet = fcSet = PETSC_FALSE; 4793ba322698SMatthew G. Knepley if ((ncind < Ncc) && (b == comps[ncind])) {++ncind; ncSet = PETSC_TRUE;} 4794ba322698SMatthew G. Knepley if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; fcSet = PETSC_TRUE;} 4795ba322698SMatthew G. Knepley if (ncSet && fcSet) {fuse(&a[b], values[foffset+ b ] * (flip ? flip[ b ] : 1.));} 4796ba322698SMatthew G. Knepley } 479797e99dd9SToby Isaac } else { 479897e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 479997e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) { 480097e99dd9SToby Isaac fuse(&a[b], values[foffset+ b ] * (flip ? flip[ b ] : 1.)); 4801a5e93ea8SMatthew G. Knepley ++cind; 4802a5e93ea8SMatthew G. Knepley } 4803a5e93ea8SMatthew G. Knepley } 4804a5e93ea8SMatthew G. Knepley } 4805a5e93ea8SMatthew G. Knepley } 4806a5e93ea8SMatthew G. Knepley } 4807ba322698SMatthew G. Knepley } 48081a271a75SMatthew G. Knepley *offset += fdof; 4809a5e93ea8SMatthew G. Knepley PetscFunctionReturn(0); 4810a5e93ea8SMatthew G. Knepley } 4811a5e93ea8SMatthew G. Knepley 48128f3be42fSMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode DMPlexVecSetClosure_Depth1_Static(DM dm, PetscSection section, Vec v, PetscInt point, const PetscScalar values[], InsertMode mode) 4813a6dfd86eSKarl Rupp { 4814552f7358SJed Brown PetscScalar *array; 48151b406b76SMatthew G. Knepley const PetscInt *cone, *coneO; 48161b406b76SMatthew G. Knepley PetscInt pStart, pEnd, p, numPoints, off, dof; 4817552f7358SJed Brown PetscErrorCode ierr; 4818552f7358SJed Brown 48191b406b76SMatthew G. Knepley PetscFunctionBeginHot; 4820b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 4821b6ebb6e6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, point, &numPoints);CHKERRQ(ierr); 4822b6ebb6e6SMatthew G. Knepley ierr = DMPlexGetCone(dm, point, &cone);CHKERRQ(ierr); 4823b6ebb6e6SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, point, &coneO);CHKERRQ(ierr); 4824b6ebb6e6SMatthew G. Knepley ierr = VecGetArray(v, &array);CHKERRQ(ierr); 4825b6ebb6e6SMatthew G. Knepley for (p = 0, off = 0; p <= numPoints; ++p, off += dof) { 4826b6ebb6e6SMatthew G. Knepley const PetscInt cp = !p ? point : cone[p-1]; 4827b6ebb6e6SMatthew G. Knepley const PetscInt o = !p ? 0 : coneO[p-1]; 4828b6ebb6e6SMatthew G. Knepley 4829b6ebb6e6SMatthew G. Knepley if ((cp < pStart) || (cp >= pEnd)) {dof = 0; continue;} 4830b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetDof(section, cp, &dof);CHKERRQ(ierr); 4831b6ebb6e6SMatthew G. Knepley /* ADD_VALUES */ 4832b6ebb6e6SMatthew G. Knepley { 4833b6ebb6e6SMatthew G. Knepley const PetscInt *cdofs; /* The indices of the constrained dofs on this point */ 4834b6ebb6e6SMatthew G. Knepley PetscScalar *a; 4835b6ebb6e6SMatthew G. Knepley PetscInt cdof, coff, cind = 0, k; 4836b6ebb6e6SMatthew G. Knepley 4837b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(section, cp, &cdof);CHKERRQ(ierr); 4838b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetOffset(section, cp, &coff);CHKERRQ(ierr); 4839b6ebb6e6SMatthew G. Knepley a = &array[coff]; 4840b6ebb6e6SMatthew G. Knepley if (!cdof) { 4841b6ebb6e6SMatthew G. Knepley if (o >= 0) { 4842b6ebb6e6SMatthew G. Knepley for (k = 0; k < dof; ++k) { 4843b6ebb6e6SMatthew G. Knepley a[k] += values[off+k]; 4844b6ebb6e6SMatthew G. Knepley } 4845b6ebb6e6SMatthew G. Knepley } else { 4846b6ebb6e6SMatthew G. Knepley for (k = 0; k < dof; ++k) { 4847b6ebb6e6SMatthew G. Knepley a[k] += values[off+dof-k-1]; 4848b6ebb6e6SMatthew G. Knepley } 4849b6ebb6e6SMatthew G. Knepley } 4850b6ebb6e6SMatthew G. Knepley } else { 4851b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetConstraintIndices(section, cp, &cdofs);CHKERRQ(ierr); 4852b6ebb6e6SMatthew G. Knepley if (o >= 0) { 4853b6ebb6e6SMatthew G. Knepley for (k = 0; k < dof; ++k) { 4854b6ebb6e6SMatthew G. Knepley if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 4855b6ebb6e6SMatthew G. Knepley a[k] += values[off+k]; 4856b6ebb6e6SMatthew G. Knepley } 4857b6ebb6e6SMatthew G. Knepley } else { 4858b6ebb6e6SMatthew G. Knepley for (k = 0; k < dof; ++k) { 4859b6ebb6e6SMatthew G. Knepley if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 4860b6ebb6e6SMatthew G. Knepley a[k] += values[off+dof-k-1]; 4861b6ebb6e6SMatthew G. Knepley } 4862b6ebb6e6SMatthew G. Knepley } 4863b6ebb6e6SMatthew G. Knepley } 4864b6ebb6e6SMatthew G. Knepley } 4865b6ebb6e6SMatthew G. Knepley } 4866b6ebb6e6SMatthew G. Knepley ierr = VecRestoreArray(v, &array);CHKERRQ(ierr); 4867b6ebb6e6SMatthew G. Knepley PetscFunctionReturn(0); 4868b6ebb6e6SMatthew G. Knepley } 48691b406b76SMatthew G. Knepley 48701b406b76SMatthew G. Knepley /*@C 48711b406b76SMatthew G. Knepley DMPlexVecSetClosure - Set an array of the values on the closure of 'point' 48721b406b76SMatthew G. Knepley 48731b406b76SMatthew G. Knepley Not collective 48741b406b76SMatthew G. Knepley 48751b406b76SMatthew G. Knepley Input Parameters: 48761b406b76SMatthew G. Knepley + dm - The DM 48771b406b76SMatthew G. Knepley . section - The section describing the layout in v, or NULL to use the default section 48781b406b76SMatthew G. Knepley . v - The local vector 4879eaf898f9SPatrick Sanan . point - The point in the DM 48801b406b76SMatthew G. Knepley . values - The array of values 488122c1ee49SMatthew 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, 488222c1ee49SMatthew G. Knepley where INSERT_ALL_VALUES and ADD_ALL_VALUES also overwrite boundary conditions. 48831b406b76SMatthew G. Knepley 48841b406b76SMatthew G. Knepley Fortran Notes: 48851b406b76SMatthew G. Knepley This routine is only available in Fortran 90, and you must include petsc.h90 in your code. 48861b406b76SMatthew G. Knepley 48871b406b76SMatthew G. Knepley Level: intermediate 48881b406b76SMatthew G. Knepley 48891b406b76SMatthew G. Knepley .seealso DMPlexVecGetClosure(), DMPlexMatSetClosure() 48901b406b76SMatthew G. Knepley @*/ 48911b406b76SMatthew G. Knepley PetscErrorCode DMPlexVecSetClosure(DM dm, PetscSection section, Vec v, PetscInt point, const PetscScalar values[], InsertMode mode) 48921b406b76SMatthew G. Knepley { 48931b406b76SMatthew G. Knepley PetscSection clSection; 48941b406b76SMatthew G. Knepley IS clPoints; 48951b406b76SMatthew G. Knepley PetscScalar *array; 48961b406b76SMatthew G. Knepley PetscInt *points = NULL; 489797e99dd9SToby Isaac const PetscInt *clp, *clperm; 48981a271a75SMatthew G. Knepley PetscInt depth, numFields, numPoints, p; 48991b406b76SMatthew G. Knepley PetscErrorCode ierr; 49001b406b76SMatthew G. Knepley 49011a271a75SMatthew G. Knepley PetscFunctionBeginHot; 49021b406b76SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 490392fd8e1eSJed Brown if (!section) {ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr);} 49041a271a75SMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 49051a271a75SMatthew G. Knepley PetscValidHeaderSpecific(v, VEC_CLASSID, 3); 49061b406b76SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 49071b406b76SMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 49081b406b76SMatthew G. Knepley if (depth == 1 && numFields < 2 && mode == ADD_VALUES) { 49098f3be42fSMatthew G. Knepley ierr = DMPlexVecSetClosure_Depth1_Static(dm, section, v, point, values, mode);CHKERRQ(ierr); 49101b406b76SMatthew G. Knepley PetscFunctionReturn(0); 49111b406b76SMatthew G. Knepley } 49121a271a75SMatthew G. Knepley /* Get points */ 491397e99dd9SToby Isaac ierr = PetscSectionGetClosureInversePermutation_Internal(section, (PetscObject) dm, NULL, &clperm);CHKERRQ(ierr); 4914923c78e0SToby Isaac ierr = DMPlexGetCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 49151a271a75SMatthew G. Knepley /* Get array */ 4916552f7358SJed Brown ierr = VecGetArray(v, &array);CHKERRQ(ierr); 49171a271a75SMatthew G. Knepley /* Get values */ 4918ef90cfe2SMatthew G. Knepley if (numFields > 0) { 491997e99dd9SToby Isaac PetscInt offset = 0, f; 4920552f7358SJed Brown for (f = 0; f < numFields; ++f) { 492197e99dd9SToby Isaac const PetscInt **perms = NULL; 492297e99dd9SToby Isaac const PetscScalar **flips = NULL; 492397e99dd9SToby Isaac 492497e99dd9SToby Isaac ierr = PetscSectionGetFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 4925552f7358SJed Brown switch (mode) { 4926552f7358SJed Brown case INSERT_VALUES: 492797e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 492897e99dd9SToby Isaac const PetscInt point = points[2*p]; 492997e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 493097e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 493197e99dd9SToby Isaac updatePointFields_private(section, point, perm, flip, f, insert, PETSC_FALSE, clperm, values, &offset, array); 4932552f7358SJed Brown } break; 4933552f7358SJed Brown case INSERT_ALL_VALUES: 493497e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 493597e99dd9SToby Isaac const PetscInt point = points[2*p]; 493697e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 493797e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 493897e99dd9SToby Isaac updatePointFields_private(section, point, perm, flip, f, insert, PETSC_TRUE, clperm, values, &offset, array); 4939552f7358SJed Brown } break; 4940a5e93ea8SMatthew G. Knepley case INSERT_BC_VALUES: 494197e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 494297e99dd9SToby Isaac const PetscInt point = points[2*p]; 494397e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 494497e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 4945ba322698SMatthew G. Knepley updatePointFieldsBC_private(section, point, perm, flip, f, -1, NULL, insert, clperm, values, &offset, array); 4946a5e93ea8SMatthew G. Knepley } break; 4947552f7358SJed Brown case ADD_VALUES: 494897e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 494997e99dd9SToby Isaac const PetscInt point = points[2*p]; 495097e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 495197e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 495297e99dd9SToby Isaac updatePointFields_private(section, point, perm, flip, f, add, PETSC_FALSE, clperm, values, &offset, array); 4953552f7358SJed Brown } break; 4954552f7358SJed Brown case ADD_ALL_VALUES: 495597e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 495697e99dd9SToby Isaac const PetscInt point = points[2*p]; 495797e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 495897e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 495997e99dd9SToby Isaac updatePointFields_private(section, point, perm, flip, f, add, PETSC_TRUE, clperm, values, &offset, array); 4960552f7358SJed Brown } break; 4961304ab55fSMatthew G. Knepley case ADD_BC_VALUES: 496297e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 496397e99dd9SToby Isaac const PetscInt point = points[2*p]; 496497e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 496597e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 4966ba322698SMatthew G. Knepley updatePointFieldsBC_private(section, point, perm, flip, f, -1, NULL, add, clperm, values, &offset, array); 4967304ab55fSMatthew G. Knepley } break; 4968552f7358SJed Brown default: 4969f347f43bSBarry Smith SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insert mode %d", mode); 4970552f7358SJed Brown } 497197e99dd9SToby Isaac ierr = PetscSectionRestoreFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 49721a271a75SMatthew G. Knepley } 4973552f7358SJed Brown } else { 49741a271a75SMatthew G. Knepley PetscInt dof, off; 497597e99dd9SToby Isaac const PetscInt **perms = NULL; 497697e99dd9SToby Isaac const PetscScalar **flips = NULL; 49771a271a75SMatthew G. Knepley 497897e99dd9SToby Isaac ierr = PetscSectionGetPointSyms(section,numPoints,points,&perms,&flips);CHKERRQ(ierr); 4979552f7358SJed Brown switch (mode) { 4980552f7358SJed Brown case INSERT_VALUES: 498197e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 498297e99dd9SToby Isaac const PetscInt point = points[2*p]; 498397e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 498497e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 498597e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 498697e99dd9SToby Isaac updatePoint_private(section, point, dof, insert, PETSC_FALSE, perm, flip, clperm, values, off, array); 4987552f7358SJed Brown } break; 4988552f7358SJed Brown case INSERT_ALL_VALUES: 498997e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 499097e99dd9SToby Isaac const PetscInt point = points[2*p]; 499197e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 499297e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 499397e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 499497e99dd9SToby Isaac updatePoint_private(section, point, dof, insert, PETSC_TRUE, perm, flip, clperm, values, off, array); 4995552f7358SJed Brown } break; 4996a5e93ea8SMatthew G. Knepley case INSERT_BC_VALUES: 499797e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 499897e99dd9SToby Isaac const PetscInt point = points[2*p]; 499997e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 500097e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 500197e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 500297e99dd9SToby Isaac updatePointBC_private(section, point, dof, insert, perm, flip, clperm, values, off, array); 5003a5e93ea8SMatthew G. Knepley } break; 5004552f7358SJed Brown case ADD_VALUES: 500597e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 500697e99dd9SToby Isaac const PetscInt point = points[2*p]; 500797e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 500897e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 500997e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 501097e99dd9SToby Isaac updatePoint_private(section, point, dof, add, PETSC_FALSE, perm, flip, clperm, values, off, array); 5011552f7358SJed Brown } break; 5012552f7358SJed Brown case ADD_ALL_VALUES: 501397e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 501497e99dd9SToby Isaac const PetscInt point = points[2*p]; 501597e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 501697e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 501797e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 501897e99dd9SToby Isaac updatePoint_private(section, point, dof, add, PETSC_TRUE, perm, flip, clperm, values, off, array); 5019552f7358SJed Brown } break; 5020304ab55fSMatthew G. Knepley case ADD_BC_VALUES: 502197e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 502297e99dd9SToby Isaac const PetscInt point = points[2*p]; 502397e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 502497e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 502597e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 502697e99dd9SToby Isaac updatePointBC_private(section, point, dof, add, perm, flip, clperm, values, off, array); 5027304ab55fSMatthew G. Knepley } break; 5028552f7358SJed Brown default: 5029f347f43bSBarry Smith SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insert mode %d", mode); 5030552f7358SJed Brown } 503197e99dd9SToby Isaac ierr = PetscSectionRestorePointSyms(section,numPoints,points,&perms,&flips);CHKERRQ(ierr); 5032552f7358SJed Brown } 50331a271a75SMatthew G. Knepley /* Cleanup points */ 5034923c78e0SToby Isaac ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 50351a271a75SMatthew G. Knepley /* Cleanup array */ 5036552f7358SJed Brown ierr = VecRestoreArray(v, &array);CHKERRQ(ierr); 5037552f7358SJed Brown PetscFunctionReturn(0); 5038552f7358SJed Brown } 5039552f7358SJed Brown 5040ba322698SMatthew 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) 5041e07394fbSMatthew G. Knepley { 5042e07394fbSMatthew G. Knepley PetscSection clSection; 5043e07394fbSMatthew G. Knepley IS clPoints; 5044e07394fbSMatthew G. Knepley PetscScalar *array; 5045e07394fbSMatthew G. Knepley PetscInt *points = NULL; 5046b04c866fSMatthew G. Knepley const PetscInt *clp, *clperm; 5047e07394fbSMatthew G. Knepley PetscInt numFields, numPoints, p; 504897e99dd9SToby Isaac PetscInt offset = 0, f; 5049e07394fbSMatthew G. Knepley PetscErrorCode ierr; 5050e07394fbSMatthew G. Knepley 5051e07394fbSMatthew G. Knepley PetscFunctionBeginHot; 5052e07394fbSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 505392fd8e1eSJed Brown if (!section) {ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr);} 5054e07394fbSMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 5055e07394fbSMatthew G. Knepley PetscValidHeaderSpecific(v, VEC_CLASSID, 3); 5056e07394fbSMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 5057e07394fbSMatthew G. Knepley /* Get points */ 5058b04c866fSMatthew G. Knepley ierr = PetscSectionGetClosureInversePermutation_Internal(section, (PetscObject) dm, NULL, &clperm);CHKERRQ(ierr); 5059923c78e0SToby Isaac ierr = DMPlexGetCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 5060e07394fbSMatthew G. Knepley /* Get array */ 5061e07394fbSMatthew G. Knepley ierr = VecGetArray(v, &array);CHKERRQ(ierr); 5062e07394fbSMatthew G. Knepley /* Get values */ 5063e07394fbSMatthew G. Knepley for (f = 0; f < numFields; ++f) { 506497e99dd9SToby Isaac const PetscInt **perms = NULL; 506597e99dd9SToby Isaac const PetscScalar **flips = NULL; 506697e99dd9SToby Isaac 5067e07394fbSMatthew G. Knepley if (!fieldActive[f]) { 5068e07394fbSMatthew G. Knepley for (p = 0; p < numPoints*2; p += 2) { 5069e07394fbSMatthew G. Knepley PetscInt fdof; 5070e07394fbSMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, points[p], f, &fdof);CHKERRQ(ierr); 5071e07394fbSMatthew G. Knepley offset += fdof; 5072e07394fbSMatthew G. Knepley } 5073e07394fbSMatthew G. Knepley continue; 5074e07394fbSMatthew G. Knepley } 507597e99dd9SToby Isaac ierr = PetscSectionGetFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 5076e07394fbSMatthew G. Knepley switch (mode) { 5077e07394fbSMatthew G. Knepley case INSERT_VALUES: 507897e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 507997e99dd9SToby Isaac const PetscInt point = points[2*p]; 508097e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 508197e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 5082b04c866fSMatthew G. Knepley updatePointFields_private(section, point, perm, flip, f, insert, PETSC_FALSE, clperm, values, &offset, array); 5083e07394fbSMatthew G. Knepley } break; 5084e07394fbSMatthew G. Knepley case INSERT_ALL_VALUES: 508597e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 508697e99dd9SToby Isaac const PetscInt point = points[2*p]; 508797e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 508897e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 5089b04c866fSMatthew G. Knepley updatePointFields_private(section, point, perm, flip, f, insert, PETSC_TRUE, clperm, values, &offset, array); 5090e07394fbSMatthew G. Knepley } break; 5091e07394fbSMatthew G. Knepley case INSERT_BC_VALUES: 509297e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 509397e99dd9SToby Isaac const PetscInt point = points[2*p]; 509497e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 509597e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 5096ba322698SMatthew G. Knepley updatePointFieldsBC_private(section, point, perm, flip, f, Ncc, comps, insert, clperm, values, &offset, array); 5097e07394fbSMatthew G. Knepley } break; 5098e07394fbSMatthew G. Knepley case ADD_VALUES: 509997e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 510097e99dd9SToby Isaac const PetscInt point = points[2*p]; 510197e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 510297e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 5103b04c866fSMatthew G. Knepley updatePointFields_private(section, point, perm, flip, f, add, PETSC_FALSE, clperm, values, &offset, array); 5104e07394fbSMatthew G. Knepley } break; 5105e07394fbSMatthew G. Knepley case ADD_ALL_VALUES: 510697e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 510797e99dd9SToby Isaac const PetscInt point = points[2*p]; 510897e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 510997e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 5110b04c866fSMatthew G. Knepley updatePointFields_private(section, point, perm, flip, f, add, PETSC_TRUE, clperm, values, &offset, array); 5111e07394fbSMatthew G. Knepley } break; 5112e07394fbSMatthew G. Knepley default: 5113f347f43bSBarry Smith SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insert mode %d", mode); 5114e07394fbSMatthew G. Knepley } 511597e99dd9SToby Isaac ierr = PetscSectionRestoreFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 5116e07394fbSMatthew G. Knepley } 5117e07394fbSMatthew G. Knepley /* Cleanup points */ 5118923c78e0SToby Isaac ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 5119e07394fbSMatthew G. Knepley /* Cleanup array */ 5120e07394fbSMatthew G. Knepley ierr = VecRestoreArray(v, &array);CHKERRQ(ierr); 5121e07394fbSMatthew G. Knepley PetscFunctionReturn(0); 5122e07394fbSMatthew G. Knepley } 5123e07394fbSMatthew G. Knepley 51247cd05799SMatthew G. Knepley static PetscErrorCode DMPlexPrintMatSetValues(PetscViewer viewer, Mat A, PetscInt point, PetscInt numRIndices, const PetscInt rindices[], PetscInt numCIndices, const PetscInt cindices[], const PetscScalar values[]) 5125552f7358SJed Brown { 5126552f7358SJed Brown PetscMPIInt rank; 5127552f7358SJed Brown PetscInt i, j; 5128552f7358SJed Brown PetscErrorCode ierr; 5129552f7358SJed Brown 5130552f7358SJed Brown PetscFunctionBegin; 513182f516ccSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)A), &rank);CHKERRQ(ierr); 5132eaf898f9SPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer, "[%d]mat for point %D\n", rank, point);CHKERRQ(ierr); 5133e4b003c7SBarry Smith for (i = 0; i < numRIndices; i++) {ierr = PetscViewerASCIIPrintf(viewer, "[%d]mat row indices[%D] = %D\n", rank, i, rindices[i]);CHKERRQ(ierr);} 5134e4b003c7SBarry Smith for (i = 0; i < numCIndices; i++) {ierr = PetscViewerASCIIPrintf(viewer, "[%d]mat col indices[%D] = %D\n", rank, i, cindices[i]);CHKERRQ(ierr);} 5135b0ecff45SMatthew G. Knepley numCIndices = numCIndices ? numCIndices : numRIndices; 5136b0ecff45SMatthew G. Knepley for (i = 0; i < numRIndices; i++) { 5137e4b003c7SBarry Smith ierr = PetscViewerASCIIPrintf(viewer, "[%d]", rank);CHKERRQ(ierr); 5138b0ecff45SMatthew G. Knepley for (j = 0; j < numCIndices; j++) { 5139519f805aSKarl Rupp #if defined(PETSC_USE_COMPLEX) 51407eba1a17SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " (%g,%g)", (double)PetscRealPart(values[i*numCIndices+j]), (double)PetscImaginaryPart(values[i*numCIndices+j]));CHKERRQ(ierr); 5141552f7358SJed Brown #else 5142b0ecff45SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " %g", (double)values[i*numCIndices+j]);CHKERRQ(ierr); 5143552f7358SJed Brown #endif 5144552f7358SJed Brown } 514577a6746dSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, "\n");CHKERRQ(ierr); 5146552f7358SJed Brown } 5147552f7358SJed Brown PetscFunctionReturn(0); 5148552f7358SJed Brown } 5149552f7358SJed Brown 515005586334SMatthew G. Knepley /* 515105586334SMatthew G. Knepley DMPlexGetIndicesPoint_Internal - Add the indices for dofs on a point to an index array 515205586334SMatthew G. Knepley 515305586334SMatthew G. Knepley Input Parameters: 515405586334SMatthew G. Knepley + section - The section for this data layout 515505586334SMatthew G. Knepley . point - The point contributing dofs with these indices 515605586334SMatthew G. Knepley . off - The global offset of this point 515705586334SMatthew G. Knepley . loff - The local offset of each field 515805586334SMatthew G. Knepley . setBC - The flag determining whether to include indices of bounsary values 515905586334SMatthew G. Knepley . perm - A permutation of the dofs on this point, or NULL 516005586334SMatthew G. Knepley - indperm - A permutation of the entire indices array, or NULL 516105586334SMatthew G. Knepley 516205586334SMatthew G. Knepley Output Parameter: 516305586334SMatthew G. Knepley . indices - Indices for dofs on this point 516405586334SMatthew G. Knepley 516505586334SMatthew G. Knepley Level: developer 516605586334SMatthew G. Knepley 516705586334SMatthew G. Knepley Note: The indices could be local or global, depending on the value of 'off'. 516805586334SMatthew G. Knepley */ 516905586334SMatthew G. Knepley PetscErrorCode DMPlexGetIndicesPoint_Internal(PetscSection section, PetscInt point, PetscInt off, PetscInt *loff, PetscBool setBC, const PetscInt perm[], const PetscInt indperm[], PetscInt indices[]) 5170a6dfd86eSKarl Rupp { 5171e6ccafaeSMatthew G Knepley PetscInt dof; /* The number of unknowns on this point */ 5172552f7358SJed Brown PetscInt cdof; /* The number of constraints on this point */ 5173552f7358SJed Brown const PetscInt *cdofs; /* The indices of the constrained dofs on this point */ 5174552f7358SJed Brown PetscInt cind = 0, k; 5175552f7358SJed Brown PetscErrorCode ierr; 5176552f7358SJed Brown 5177552f7358SJed Brown PetscFunctionBegin; 5178552f7358SJed Brown ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 5179552f7358SJed Brown ierr = PetscSectionGetConstraintDof(section, point, &cdof);CHKERRQ(ierr); 5180552f7358SJed Brown if (!cdof || setBC) { 518105586334SMatthew G. Knepley for (k = 0; k < dof; ++k) { 518205586334SMatthew G. Knepley const PetscInt preind = perm ? *loff+perm[k] : *loff+k; 518305586334SMatthew G. Knepley const PetscInt ind = indperm ? indperm[preind] : preind; 518405586334SMatthew G. Knepley 518505586334SMatthew G. Knepley indices[ind] = off + k; 5186552f7358SJed Brown } 5187552f7358SJed Brown } else { 5188552f7358SJed Brown ierr = PetscSectionGetConstraintIndices(section, point, &cdofs);CHKERRQ(ierr); 51894acb8e1eSToby Isaac for (k = 0; k < dof; ++k) { 519005586334SMatthew G. Knepley const PetscInt preind = perm ? *loff+perm[k] : *loff+k; 519105586334SMatthew G. Knepley const PetscInt ind = indperm ? indperm[preind] : preind; 519205586334SMatthew G. Knepley 51934acb8e1eSToby Isaac if ((cind < cdof) && (k == cdofs[cind])) { 51944acb8e1eSToby Isaac /* Insert check for returning constrained indices */ 519505586334SMatthew G. Knepley indices[ind] = -(off+k+1); 51964acb8e1eSToby Isaac ++cind; 51974acb8e1eSToby Isaac } else { 519805586334SMatthew G. Knepley indices[ind] = off+k-cind; 5199552f7358SJed Brown } 5200552f7358SJed Brown } 5201552f7358SJed Brown } 5202e6ccafaeSMatthew G Knepley *loff += dof; 5203552f7358SJed Brown PetscFunctionReturn(0); 5204552f7358SJed Brown } 5205552f7358SJed Brown 52067e29afd2SMatthew G. Knepley /* 52077e29afd2SMatthew G. Knepley This version only believes the point offset from the globalSection 52087e29afd2SMatthew G. Knepley 52097e29afd2SMatthew G. Knepley . off - The global offset of this point 52107e29afd2SMatthew G. Knepley */ 521105586334SMatthew G. Knepley PetscErrorCode DMPlexGetIndicesPointFields_Internal(PetscSection section, PetscInt point, PetscInt off, PetscInt foffs[], PetscBool setBC, const PetscInt ***perms, PetscInt permsoff, const PetscInt indperm[], PetscInt indices[]) 5212a6dfd86eSKarl Rupp { 5213552f7358SJed Brown PetscInt numFields, foff, f; 5214552f7358SJed Brown PetscErrorCode ierr; 5215552f7358SJed Brown 5216552f7358SJed Brown PetscFunctionBegin; 5217552f7358SJed Brown ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 5218552f7358SJed Brown for (f = 0, foff = 0; f < numFields; ++f) { 52194acb8e1eSToby Isaac PetscInt fdof, cfdof; 5220552f7358SJed Brown const PetscInt *fcdofs; /* The indices of the constrained dofs for field f on this point */ 52214acb8e1eSToby Isaac PetscInt cind = 0, b; 52224acb8e1eSToby Isaac const PetscInt *perm = (perms && perms[f]) ? perms[f][permsoff] : NULL; 5223552f7358SJed Brown 5224552f7358SJed Brown ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 5225552f7358SJed Brown ierr = PetscSectionGetFieldConstraintDof(section, point, f, &cfdof);CHKERRQ(ierr); 5226552f7358SJed Brown if (!cfdof || setBC) { 522705586334SMatthew G. Knepley for (b = 0; b < fdof; ++b) { 522805586334SMatthew G. Knepley const PetscInt preind = perm ? foffs[f]+perm[b] : foffs[f]+b; 522905586334SMatthew G. Knepley const PetscInt ind = indperm ? indperm[preind] : preind; 523005586334SMatthew G. Knepley 523105586334SMatthew G. Knepley indices[ind] = off+foff+b; 523205586334SMatthew G. Knepley } 5233552f7358SJed Brown } else { 5234552f7358SJed Brown ierr = PetscSectionGetFieldConstraintIndices(section, point, f, &fcdofs);CHKERRQ(ierr); 523505586334SMatthew G. Knepley for (b = 0; b < fdof; ++b) { 523605586334SMatthew G. Knepley const PetscInt preind = perm ? foffs[f]+perm[b] : foffs[f]+b; 523705586334SMatthew G. Knepley const PetscInt ind = indperm ? indperm[preind] : preind; 523805586334SMatthew G. Knepley 52394acb8e1eSToby Isaac if ((cind < cfdof) && (b == fcdofs[cind])) { 524005586334SMatthew G. Knepley indices[ind] = -(off+foff+b+1); 5241552f7358SJed Brown ++cind; 5242552f7358SJed Brown } else { 524305586334SMatthew G. Knepley indices[ind] = off+foff+b-cind; 5244552f7358SJed Brown } 5245552f7358SJed Brown } 5246552f7358SJed Brown } 5247a9096520SToby Isaac foff += (setBC ? fdof : (fdof - cfdof)); 5248552f7358SJed Brown foffs[f] += fdof; 5249552f7358SJed Brown } 5250552f7358SJed Brown PetscFunctionReturn(0); 5251552f7358SJed Brown } 5252552f7358SJed Brown 52537e29afd2SMatthew G. Knepley /* 52547e29afd2SMatthew G. Knepley This version believes the globalSection offsets for each field, rather than just the point offset 52557e29afd2SMatthew G. Knepley 52567e29afd2SMatthew G. Knepley . foffs - The offset into 'indices' for each field, since it is segregated by field 52577e29afd2SMatthew G. Knepley */ 525805586334SMatthew G. Knepley PetscErrorCode DMPlexGetIndicesPointFieldsSplit_Internal(PetscSection section, PetscSection globalSection, PetscInt point, PetscInt foffs[], PetscBool setBC, const PetscInt ***perms, PetscInt permsoff, const PetscInt indperm[], PetscInt indices[]) 52597e29afd2SMatthew G. Knepley { 52607e29afd2SMatthew G. Knepley PetscInt numFields, foff, f; 52617e29afd2SMatthew G. Knepley PetscErrorCode ierr; 52627e29afd2SMatthew G. Knepley 52637e29afd2SMatthew G. Knepley PetscFunctionBegin; 52647e29afd2SMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 52657e29afd2SMatthew G. Knepley for (f = 0; f < numFields; ++f) { 52667e29afd2SMatthew G. Knepley PetscInt fdof, cfdof; 52677e29afd2SMatthew G. Knepley const PetscInt *fcdofs; /* The indices of the constrained dofs for field f on this point */ 52687e29afd2SMatthew G. Knepley PetscInt cind = 0, b; 52697e29afd2SMatthew G. Knepley const PetscInt *perm = (perms && perms[f]) ? perms[f][permsoff] : NULL; 52707e29afd2SMatthew G. Knepley 52717e29afd2SMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 52727e29afd2SMatthew G. Knepley ierr = PetscSectionGetFieldConstraintDof(section, point, f, &cfdof);CHKERRQ(ierr); 52737e29afd2SMatthew G. Knepley ierr = PetscSectionGetFieldOffset(globalSection, point, f, &foff);CHKERRQ(ierr); 52747e29afd2SMatthew G. Knepley if (!cfdof || setBC) { 527505586334SMatthew G. Knepley for (b = 0; b < fdof; ++b) { 527605586334SMatthew G. Knepley const PetscInt preind = perm ? foffs[f]+perm[b] : foffs[f]+b; 527705586334SMatthew G. Knepley const PetscInt ind = indperm ? indperm[preind] : preind; 527805586334SMatthew G. Knepley 527905586334SMatthew G. Knepley indices[ind] = foff+b; 528005586334SMatthew G. Knepley } 52817e29afd2SMatthew G. Knepley } else { 52827e29afd2SMatthew G. Knepley ierr = PetscSectionGetFieldConstraintIndices(section, point, f, &fcdofs);CHKERRQ(ierr); 528305586334SMatthew G. Knepley for (b = 0; b < fdof; ++b) { 528405586334SMatthew G. Knepley const PetscInt preind = perm ? foffs[f]+perm[b] : foffs[f]+b; 528505586334SMatthew G. Knepley const PetscInt ind = indperm ? indperm[preind] : preind; 528605586334SMatthew G. Knepley 52877e29afd2SMatthew G. Knepley if ((cind < cfdof) && (b == fcdofs[cind])) { 528805586334SMatthew G. Knepley indices[ind] = -(foff+b+1); 52897e29afd2SMatthew G. Knepley ++cind; 52907e29afd2SMatthew G. Knepley } else { 529105586334SMatthew G. Knepley indices[ind] = foff+b-cind; 52927e29afd2SMatthew G. Knepley } 52937e29afd2SMatthew G. Knepley } 52947e29afd2SMatthew G. Knepley } 52957e29afd2SMatthew G. Knepley foffs[f] += fdof; 52967e29afd2SMatthew G. Knepley } 52977e29afd2SMatthew G. Knepley PetscFunctionReturn(0); 52987e29afd2SMatthew G. Knepley } 52997e29afd2SMatthew G. Knepley 53004acb8e1eSToby 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) 5301d3d1a6afSToby Isaac { 5302d3d1a6afSToby Isaac Mat cMat; 5303d3d1a6afSToby Isaac PetscSection aSec, cSec; 5304d3d1a6afSToby Isaac IS aIS; 5305d3d1a6afSToby Isaac PetscInt aStart = -1, aEnd = -1; 5306d3d1a6afSToby Isaac const PetscInt *anchors; 5307e17c06e0SMatthew G. Knepley PetscInt numFields, f, p, q, newP = 0; 5308d3d1a6afSToby Isaac PetscInt newNumPoints = 0, newNumIndices = 0; 5309d3d1a6afSToby Isaac PetscInt *newPoints, *indices, *newIndices; 5310d3d1a6afSToby Isaac PetscInt maxAnchor, maxDof; 5311d3d1a6afSToby Isaac PetscInt newOffsets[32]; 5312d3d1a6afSToby Isaac PetscInt *pointMatOffsets[32]; 5313d3d1a6afSToby Isaac PetscInt *newPointOffsets[32]; 5314d3d1a6afSToby Isaac PetscScalar *pointMat[32]; 53156ecaa68aSToby Isaac PetscScalar *newValues=NULL,*tmpValues; 5316d3d1a6afSToby Isaac PetscBool anyConstrained = PETSC_FALSE; 5317d3d1a6afSToby Isaac PetscErrorCode ierr; 5318d3d1a6afSToby Isaac 5319d3d1a6afSToby Isaac PetscFunctionBegin; 5320d3d1a6afSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5321d3d1a6afSToby Isaac PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 5322d3d1a6afSToby Isaac ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 5323d3d1a6afSToby Isaac 5324a17985deSToby Isaac ierr = DMPlexGetAnchors(dm,&aSec,&aIS);CHKERRQ(ierr); 5325d3d1a6afSToby Isaac /* if there are point-to-point constraints */ 5326d3d1a6afSToby Isaac if (aSec) { 5327580bdb30SBarry Smith ierr = PetscArrayzero(newOffsets, 32);CHKERRQ(ierr); 5328d3d1a6afSToby Isaac ierr = ISGetIndices(aIS,&anchors);CHKERRQ(ierr); 5329d3d1a6afSToby Isaac ierr = PetscSectionGetChart(aSec,&aStart,&aEnd);CHKERRQ(ierr); 5330d3d1a6afSToby Isaac /* figure out how many points are going to be in the new element matrix 5331d3d1a6afSToby Isaac * (we allow double counting, because it's all just going to be summed 5332d3d1a6afSToby Isaac * into the global matrix anyway) */ 5333d3d1a6afSToby Isaac for (p = 0; p < 2*numPoints; p+=2) { 5334d3d1a6afSToby Isaac PetscInt b = points[p]; 53354b2f2278SToby Isaac PetscInt bDof = 0, bSecDof; 5336d3d1a6afSToby Isaac 53374b2f2278SToby Isaac ierr = PetscSectionGetDof(section,b,&bSecDof);CHKERRQ(ierr); 53384b2f2278SToby Isaac if (!bSecDof) { 53394b2f2278SToby Isaac continue; 53404b2f2278SToby Isaac } 5341d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 5342d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec,b,&bDof);CHKERRQ(ierr); 5343d3d1a6afSToby Isaac } 5344d3d1a6afSToby Isaac if (bDof) { 5345d3d1a6afSToby Isaac /* this point is constrained */ 5346d3d1a6afSToby Isaac /* it is going to be replaced by its anchors */ 5347d3d1a6afSToby Isaac PetscInt bOff, q; 5348d3d1a6afSToby Isaac 5349d3d1a6afSToby Isaac anyConstrained = PETSC_TRUE; 5350d3d1a6afSToby Isaac newNumPoints += bDof; 5351d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(aSec,b,&bOff);CHKERRQ(ierr); 5352d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 5353d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q]; 5354d3d1a6afSToby Isaac PetscInt aDof; 5355d3d1a6afSToby Isaac 5356d3d1a6afSToby Isaac ierr = PetscSectionGetDof(section,a,&aDof);CHKERRQ(ierr); 5357d3d1a6afSToby Isaac newNumIndices += aDof; 5358d3d1a6afSToby Isaac for (f = 0; f < numFields; ++f) { 5359d3d1a6afSToby Isaac PetscInt fDof; 5360d3d1a6afSToby Isaac 5361d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, a, f, &fDof);CHKERRQ(ierr); 5362d3d1a6afSToby Isaac newOffsets[f+1] += fDof; 5363d3d1a6afSToby Isaac } 5364d3d1a6afSToby Isaac } 5365d3d1a6afSToby Isaac } 5366d3d1a6afSToby Isaac else { 5367d3d1a6afSToby Isaac /* this point is not constrained */ 5368d3d1a6afSToby Isaac newNumPoints++; 53694b2f2278SToby Isaac newNumIndices += bSecDof; 5370d3d1a6afSToby Isaac for (f = 0; f < numFields; ++f) { 5371d3d1a6afSToby Isaac PetscInt fDof; 5372d3d1a6afSToby Isaac 5373d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, b, f, &fDof);CHKERRQ(ierr); 5374d3d1a6afSToby Isaac newOffsets[f+1] += fDof; 5375d3d1a6afSToby Isaac } 5376d3d1a6afSToby Isaac } 5377d3d1a6afSToby Isaac } 5378d3d1a6afSToby Isaac } 5379d3d1a6afSToby Isaac if (!anyConstrained) { 538072b80496SMatthew G. Knepley if (outNumPoints) *outNumPoints = 0; 538172b80496SMatthew G. Knepley if (outNumIndices) *outNumIndices = 0; 538272b80496SMatthew G. Knepley if (outPoints) *outPoints = NULL; 538372b80496SMatthew G. Knepley if (outValues) *outValues = NULL; 538472b80496SMatthew G. Knepley if (aSec) {ierr = ISRestoreIndices(aIS,&anchors);CHKERRQ(ierr);} 5385d3d1a6afSToby Isaac PetscFunctionReturn(0); 5386d3d1a6afSToby Isaac } 5387d3d1a6afSToby Isaac 53886ecaa68aSToby Isaac if (outNumPoints) *outNumPoints = newNumPoints; 53896ecaa68aSToby Isaac if (outNumIndices) *outNumIndices = newNumIndices; 53906ecaa68aSToby Isaac 5391f13f9184SToby Isaac for (f = 0; f < numFields; ++f) newOffsets[f+1] += newOffsets[f]; 5392d3d1a6afSToby Isaac 53936ecaa68aSToby Isaac if (!outPoints && !outValues) { 53946ecaa68aSToby Isaac if (offsets) { 53956ecaa68aSToby Isaac for (f = 0; f <= numFields; f++) { 53966ecaa68aSToby Isaac offsets[f] = newOffsets[f]; 53976ecaa68aSToby Isaac } 53986ecaa68aSToby Isaac } 53996ecaa68aSToby Isaac if (aSec) {ierr = ISRestoreIndices(aIS,&anchors);CHKERRQ(ierr);} 54006ecaa68aSToby Isaac PetscFunctionReturn(0); 54016ecaa68aSToby Isaac } 54026ecaa68aSToby Isaac 5403f347f43bSBarry Smith if (numFields && newOffsets[numFields] != newNumIndices) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", newOffsets[numFields], newNumIndices); 5404d3d1a6afSToby Isaac 5405f7c74593SToby Isaac ierr = DMGetDefaultConstraints(dm, &cSec, &cMat);CHKERRQ(ierr); 5406d3d1a6afSToby Isaac 5407d3d1a6afSToby Isaac /* workspaces */ 5408d3d1a6afSToby Isaac if (numFields) { 5409d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 541069291d52SBarry Smith ierr = DMGetWorkArray(dm,numPoints+1,MPIU_INT,&pointMatOffsets[f]);CHKERRQ(ierr); 541169291d52SBarry Smith ierr = DMGetWorkArray(dm,numPoints+1,MPIU_INT,&newPointOffsets[f]);CHKERRQ(ierr); 5412d3d1a6afSToby Isaac } 5413d3d1a6afSToby Isaac } 5414d3d1a6afSToby Isaac else { 541569291d52SBarry Smith ierr = DMGetWorkArray(dm,numPoints+1,MPIU_INT,&pointMatOffsets[0]);CHKERRQ(ierr); 541669291d52SBarry Smith ierr = DMGetWorkArray(dm,numPoints,MPIU_INT,&newPointOffsets[0]);CHKERRQ(ierr); 5417d3d1a6afSToby Isaac } 5418d3d1a6afSToby Isaac 5419d3d1a6afSToby Isaac /* get workspaces for the point-to-point matrices */ 5420d3d1a6afSToby Isaac if (numFields) { 54214b2f2278SToby Isaac PetscInt totalOffset, totalMatOffset; 54224b2f2278SToby Isaac 5423d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 5424d3d1a6afSToby Isaac PetscInt b = points[2*p]; 54254b2f2278SToby Isaac PetscInt bDof = 0, bSecDof; 5426d3d1a6afSToby Isaac 54274b2f2278SToby Isaac ierr = PetscSectionGetDof(section,b,&bSecDof);CHKERRQ(ierr); 54284b2f2278SToby Isaac if (!bSecDof) { 54294b2f2278SToby Isaac for (f = 0; f < numFields; f++) { 54304b2f2278SToby Isaac newPointOffsets[f][p + 1] = 0; 54314b2f2278SToby Isaac pointMatOffsets[f][p + 1] = 0; 54324b2f2278SToby Isaac } 54334b2f2278SToby Isaac continue; 54344b2f2278SToby Isaac } 5435d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 5436d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec, b, &bDof);CHKERRQ(ierr); 5437d3d1a6afSToby Isaac } 5438d3d1a6afSToby Isaac if (bDof) { 5439d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 5440d3d1a6afSToby Isaac PetscInt fDof, q, bOff, allFDof = 0; 5441d3d1a6afSToby Isaac 5442d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, b, f, &fDof);CHKERRQ(ierr); 5443d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(aSec, b, &bOff);CHKERRQ(ierr); 5444d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 5445d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q]; 5446d3d1a6afSToby Isaac PetscInt aFDof; 5447d3d1a6afSToby Isaac 5448d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, a, f, &aFDof);CHKERRQ(ierr); 5449d3d1a6afSToby Isaac allFDof += aFDof; 5450d3d1a6afSToby Isaac } 5451d3d1a6afSToby Isaac newPointOffsets[f][p+1] = allFDof; 5452d3d1a6afSToby Isaac pointMatOffsets[f][p+1] = fDof * allFDof; 5453d3d1a6afSToby Isaac } 5454d3d1a6afSToby Isaac } 5455d3d1a6afSToby Isaac else { 5456d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 5457d3d1a6afSToby Isaac PetscInt fDof; 5458d3d1a6afSToby Isaac 5459d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, b, f, &fDof);CHKERRQ(ierr); 5460d3d1a6afSToby Isaac newPointOffsets[f][p+1] = fDof; 5461d3d1a6afSToby Isaac pointMatOffsets[f][p+1] = 0; 5462d3d1a6afSToby Isaac } 5463d3d1a6afSToby Isaac } 5464d3d1a6afSToby Isaac } 54654b2f2278SToby Isaac for (f = 0, totalOffset = 0, totalMatOffset = 0; f < numFields; f++) { 54664b2f2278SToby Isaac newPointOffsets[f][0] = totalOffset; 54674b2f2278SToby Isaac pointMatOffsets[f][0] = totalMatOffset; 5468d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 5469d3d1a6afSToby Isaac newPointOffsets[f][p+1] += newPointOffsets[f][p]; 5470d3d1a6afSToby Isaac pointMatOffsets[f][p+1] += pointMatOffsets[f][p]; 5471d3d1a6afSToby Isaac } 547219f70fd5SToby Isaac totalOffset = newPointOffsets[f][numPoints]; 547319f70fd5SToby Isaac totalMatOffset = pointMatOffsets[f][numPoints]; 547469291d52SBarry Smith ierr = DMGetWorkArray(dm,pointMatOffsets[f][numPoints],MPIU_SCALAR,&pointMat[f]);CHKERRQ(ierr); 5475d3d1a6afSToby Isaac } 5476d3d1a6afSToby Isaac } 5477d3d1a6afSToby Isaac else { 5478d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 5479d3d1a6afSToby Isaac PetscInt b = points[2*p]; 54804b2f2278SToby Isaac PetscInt bDof = 0, bSecDof; 5481d3d1a6afSToby Isaac 54824b2f2278SToby Isaac ierr = PetscSectionGetDof(section,b,&bSecDof);CHKERRQ(ierr); 54834b2f2278SToby Isaac if (!bSecDof) { 54844b2f2278SToby Isaac newPointOffsets[0][p + 1] = 0; 54854b2f2278SToby Isaac pointMatOffsets[0][p + 1] = 0; 54864b2f2278SToby Isaac continue; 54874b2f2278SToby Isaac } 5488d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 5489d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec, b, &bDof);CHKERRQ(ierr); 5490d3d1a6afSToby Isaac } 5491d3d1a6afSToby Isaac if (bDof) { 54924b2f2278SToby Isaac PetscInt bOff, q, allDof = 0; 5493d3d1a6afSToby Isaac 5494d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(aSec, b, &bOff);CHKERRQ(ierr); 5495d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 5496d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q], aDof; 5497d3d1a6afSToby Isaac 5498d3d1a6afSToby Isaac ierr = PetscSectionGetDof(section, a, &aDof);CHKERRQ(ierr); 5499d3d1a6afSToby Isaac allDof += aDof; 5500d3d1a6afSToby Isaac } 5501d3d1a6afSToby Isaac newPointOffsets[0][p+1] = allDof; 55024b2f2278SToby Isaac pointMatOffsets[0][p+1] = bSecDof * allDof; 5503d3d1a6afSToby Isaac } 5504d3d1a6afSToby Isaac else { 55054b2f2278SToby Isaac newPointOffsets[0][p+1] = bSecDof; 5506d3d1a6afSToby Isaac pointMatOffsets[0][p+1] = 0; 5507d3d1a6afSToby Isaac } 5508d3d1a6afSToby Isaac } 5509d3d1a6afSToby Isaac newPointOffsets[0][0] = 0; 5510d3d1a6afSToby Isaac pointMatOffsets[0][0] = 0; 5511d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 5512d3d1a6afSToby Isaac newPointOffsets[0][p+1] += newPointOffsets[0][p]; 5513d3d1a6afSToby Isaac pointMatOffsets[0][p+1] += pointMatOffsets[0][p]; 5514d3d1a6afSToby Isaac } 551569291d52SBarry Smith ierr = DMGetWorkArray(dm,pointMatOffsets[0][numPoints],MPIU_SCALAR,&pointMat[0]);CHKERRQ(ierr); 5516d3d1a6afSToby Isaac } 5517d3d1a6afSToby Isaac 55186ecaa68aSToby Isaac /* output arrays */ 551969291d52SBarry Smith ierr = DMGetWorkArray(dm,2*newNumPoints,MPIU_INT,&newPoints);CHKERRQ(ierr); 55206ecaa68aSToby Isaac 5521d3d1a6afSToby Isaac /* get the point-to-point matrices; construct newPoints */ 5522d3d1a6afSToby Isaac ierr = PetscSectionGetMaxDof(aSec, &maxAnchor);CHKERRQ(ierr); 5523d3d1a6afSToby Isaac ierr = PetscSectionGetMaxDof(section, &maxDof);CHKERRQ(ierr); 552469291d52SBarry Smith ierr = DMGetWorkArray(dm,maxDof,MPIU_INT,&indices);CHKERRQ(ierr); 552569291d52SBarry Smith ierr = DMGetWorkArray(dm,maxAnchor*maxDof,MPIU_INT,&newIndices);CHKERRQ(ierr); 5526d3d1a6afSToby Isaac if (numFields) { 5527d3d1a6afSToby Isaac for (p = 0, newP = 0; p < numPoints; p++) { 5528d3d1a6afSToby Isaac PetscInt b = points[2*p]; 5529d3d1a6afSToby Isaac PetscInt o = points[2*p+1]; 55304b2f2278SToby Isaac PetscInt bDof = 0, bSecDof; 5531d3d1a6afSToby Isaac 55324b2f2278SToby Isaac ierr = PetscSectionGetDof(section, b, &bSecDof);CHKERRQ(ierr); 55334b2f2278SToby Isaac if (!bSecDof) { 55344b2f2278SToby Isaac continue; 55354b2f2278SToby Isaac } 5536d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 5537d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec, b, &bDof);CHKERRQ(ierr); 5538d3d1a6afSToby Isaac } 5539d3d1a6afSToby Isaac if (bDof) { 5540d3d1a6afSToby Isaac PetscInt fStart[32], fEnd[32], fAnchorStart[32], fAnchorEnd[32], bOff, q; 5541d3d1a6afSToby Isaac 5542d3d1a6afSToby Isaac fStart[0] = 0; 5543d3d1a6afSToby Isaac fEnd[0] = 0; 5544d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 5545d3d1a6afSToby Isaac PetscInt fDof; 5546d3d1a6afSToby Isaac 5547d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(cSec, b, f, &fDof);CHKERRQ(ierr); 5548d3d1a6afSToby Isaac fStart[f+1] = fStart[f] + fDof; 5549d3d1a6afSToby Isaac fEnd[f+1] = fStart[f+1]; 5550d3d1a6afSToby Isaac } 5551d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(cSec, b, &bOff);CHKERRQ(ierr); 555205586334SMatthew G. Knepley ierr = DMPlexGetIndicesPointFields_Internal(cSec, b, bOff, fEnd, PETSC_TRUE, perms, p, NULL, indices);CHKERRQ(ierr); 5553d3d1a6afSToby Isaac 5554d3d1a6afSToby Isaac fAnchorStart[0] = 0; 5555d3d1a6afSToby Isaac fAnchorEnd[0] = 0; 5556d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 5557d3d1a6afSToby Isaac PetscInt fDof = newPointOffsets[f][p + 1] - newPointOffsets[f][p]; 5558d3d1a6afSToby Isaac 5559d3d1a6afSToby Isaac fAnchorStart[f+1] = fAnchorStart[f] + fDof; 5560d3d1a6afSToby Isaac fAnchorEnd[f+1] = fAnchorStart[f + 1]; 5561d3d1a6afSToby Isaac } 5562d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(aSec, b, &bOff);CHKERRQ(ierr); 5563d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 5564d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q], aOff; 5565d3d1a6afSToby Isaac 5566d3d1a6afSToby 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 */ 5567d3d1a6afSToby Isaac newPoints[2*(newP + q)] = a; 5568d3d1a6afSToby Isaac newPoints[2*(newP + q) + 1] = 0; 5569302440fdSBarry Smith ierr = PetscSectionGetOffset(section, a, &aOff);CHKERRQ(ierr); 557005586334SMatthew G. Knepley ierr = DMPlexGetIndicesPointFields_Internal(section, a, aOff, fAnchorEnd, PETSC_TRUE, NULL, -1, NULL, newIndices);CHKERRQ(ierr); 5571d3d1a6afSToby Isaac } 5572d3d1a6afSToby Isaac newP += bDof; 5573d3d1a6afSToby Isaac 55746ecaa68aSToby Isaac if (outValues) { 5575d3d1a6afSToby Isaac /* get the point-to-point submatrix */ 5576d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 5577d3d1a6afSToby 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); 5578d3d1a6afSToby Isaac } 5579d3d1a6afSToby Isaac } 55806ecaa68aSToby Isaac } 5581d3d1a6afSToby Isaac else { 5582d3d1a6afSToby Isaac newPoints[2 * newP] = b; 5583d3d1a6afSToby Isaac newPoints[2 * newP + 1] = o; 5584d3d1a6afSToby Isaac newP++; 5585d3d1a6afSToby Isaac } 5586d3d1a6afSToby Isaac } 5587d3d1a6afSToby Isaac } else { 5588d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 5589d3d1a6afSToby Isaac PetscInt b = points[2*p]; 5590d3d1a6afSToby Isaac PetscInt o = points[2*p+1]; 55914b2f2278SToby Isaac PetscInt bDof = 0, bSecDof; 5592d3d1a6afSToby Isaac 55934b2f2278SToby Isaac ierr = PetscSectionGetDof(section, b, &bSecDof);CHKERRQ(ierr); 55944b2f2278SToby Isaac if (!bSecDof) { 55954b2f2278SToby Isaac continue; 55964b2f2278SToby Isaac } 5597d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 5598d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec, b, &bDof);CHKERRQ(ierr); 5599d3d1a6afSToby Isaac } 5600d3d1a6afSToby Isaac if (bDof) { 5601d3d1a6afSToby Isaac PetscInt bEnd = 0, bAnchorEnd = 0, bOff; 5602d3d1a6afSToby Isaac 5603d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(cSec, b, &bOff);CHKERRQ(ierr); 560405586334SMatthew G. Knepley ierr = DMPlexGetIndicesPoint_Internal(cSec, b, bOff, &bEnd, PETSC_TRUE, (perms && perms[0]) ? perms[0][p] : NULL, NULL, indices);CHKERRQ(ierr); 5605d3d1a6afSToby Isaac 5606d3d1a6afSToby Isaac ierr = PetscSectionGetOffset (aSec, b, &bOff);CHKERRQ(ierr); 5607d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 5608d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q], aOff; 5609d3d1a6afSToby Isaac 5610d3d1a6afSToby 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 */ 5611d3d1a6afSToby Isaac 5612d3d1a6afSToby Isaac newPoints[2*(newP + q)] = a; 5613d3d1a6afSToby Isaac newPoints[2*(newP + q) + 1] = 0; 5614302440fdSBarry Smith ierr = PetscSectionGetOffset(section, a, &aOff);CHKERRQ(ierr); 561505586334SMatthew G. Knepley ierr = DMPlexGetIndicesPoint_Internal(section, a, aOff, &bAnchorEnd, PETSC_TRUE, NULL, NULL, newIndices);CHKERRQ(ierr); 5616d3d1a6afSToby Isaac } 5617d3d1a6afSToby Isaac newP += bDof; 5618d3d1a6afSToby Isaac 5619d3d1a6afSToby Isaac /* get the point-to-point submatrix */ 56206ecaa68aSToby Isaac if (outValues) { 5621d3d1a6afSToby Isaac ierr = MatGetValues(cMat,bEnd,indices,bAnchorEnd,newIndices,pointMat[0] + pointMatOffsets[0][p]);CHKERRQ(ierr); 5622d3d1a6afSToby Isaac } 56236ecaa68aSToby Isaac } 5624d3d1a6afSToby Isaac else { 5625d3d1a6afSToby Isaac newPoints[2 * newP] = b; 5626d3d1a6afSToby Isaac newPoints[2 * newP + 1] = o; 5627d3d1a6afSToby Isaac newP++; 5628d3d1a6afSToby Isaac } 5629d3d1a6afSToby Isaac } 5630d3d1a6afSToby Isaac } 5631d3d1a6afSToby Isaac 56326ecaa68aSToby Isaac if (outValues) { 563369291d52SBarry Smith ierr = DMGetWorkArray(dm,newNumIndices*numIndices,MPIU_SCALAR,&tmpValues);CHKERRQ(ierr); 5634580bdb30SBarry Smith ierr = PetscArrayzero(tmpValues,newNumIndices*numIndices);CHKERRQ(ierr); 5635d3d1a6afSToby Isaac /* multiply constraints on the right */ 5636d3d1a6afSToby Isaac if (numFields) { 5637d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 5638d3d1a6afSToby Isaac PetscInt oldOff = offsets[f]; 5639d3d1a6afSToby Isaac 5640d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 5641d3d1a6afSToby Isaac PetscInt cStart = newPointOffsets[f][p]; 5642d3d1a6afSToby Isaac PetscInt b = points[2 * p]; 5643d3d1a6afSToby Isaac PetscInt c, r, k; 5644d3d1a6afSToby Isaac PetscInt dof; 5645d3d1a6afSToby Isaac 5646d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section,b,f,&dof);CHKERRQ(ierr); 56474b2f2278SToby Isaac if (!dof) { 56484b2f2278SToby Isaac continue; 56494b2f2278SToby Isaac } 5650d3d1a6afSToby Isaac if (pointMatOffsets[f][p] < pointMatOffsets[f][p + 1]) { 5651d3d1a6afSToby Isaac PetscInt nCols = newPointOffsets[f][p+1]-cStart; 5652d3d1a6afSToby Isaac const PetscScalar *mat = pointMat[f] + pointMatOffsets[f][p]; 5653d3d1a6afSToby Isaac 5654d3d1a6afSToby Isaac for (r = 0; r < numIndices; r++) { 5655d3d1a6afSToby Isaac for (c = 0; c < nCols; c++) { 5656d3d1a6afSToby Isaac for (k = 0; k < dof; k++) { 56574acb8e1eSToby Isaac tmpValues[r * newNumIndices + cStart + c] += values[r * numIndices + oldOff + k] * mat[k * nCols + c]; 5658d3d1a6afSToby Isaac } 5659d3d1a6afSToby Isaac } 5660d3d1a6afSToby Isaac } 5661d3d1a6afSToby Isaac } 5662d3d1a6afSToby Isaac else { 5663d3d1a6afSToby Isaac /* copy this column as is */ 5664d3d1a6afSToby Isaac for (r = 0; r < numIndices; r++) { 5665d3d1a6afSToby Isaac for (c = 0; c < dof; c++) { 5666d3d1a6afSToby Isaac tmpValues[r * newNumIndices + cStart + c] = values[r * numIndices + oldOff + c]; 5667d3d1a6afSToby Isaac } 5668d3d1a6afSToby Isaac } 5669d3d1a6afSToby Isaac } 5670d3d1a6afSToby Isaac oldOff += dof; 5671d3d1a6afSToby Isaac } 5672d3d1a6afSToby Isaac } 5673d3d1a6afSToby Isaac } 5674d3d1a6afSToby Isaac else { 5675d3d1a6afSToby Isaac PetscInt oldOff = 0; 5676d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 5677d3d1a6afSToby Isaac PetscInt cStart = newPointOffsets[0][p]; 5678d3d1a6afSToby Isaac PetscInt b = points[2 * p]; 5679d3d1a6afSToby Isaac PetscInt c, r, k; 5680d3d1a6afSToby Isaac PetscInt dof; 5681d3d1a6afSToby Isaac 5682d3d1a6afSToby Isaac ierr = PetscSectionGetDof(section,b,&dof);CHKERRQ(ierr); 56834b2f2278SToby Isaac if (!dof) { 56844b2f2278SToby Isaac continue; 56854b2f2278SToby Isaac } 5686d3d1a6afSToby Isaac if (pointMatOffsets[0][p] < pointMatOffsets[0][p + 1]) { 5687d3d1a6afSToby Isaac PetscInt nCols = newPointOffsets[0][p+1]-cStart; 5688d3d1a6afSToby Isaac const PetscScalar *mat = pointMat[0] + pointMatOffsets[0][p]; 5689d3d1a6afSToby Isaac 5690d3d1a6afSToby Isaac for (r = 0; r < numIndices; r++) { 5691d3d1a6afSToby Isaac for (c = 0; c < nCols; c++) { 5692d3d1a6afSToby Isaac for (k = 0; k < dof; k++) { 5693d3d1a6afSToby Isaac tmpValues[r * newNumIndices + cStart + c] += mat[k * nCols + c] * values[r * numIndices + oldOff + k]; 5694d3d1a6afSToby Isaac } 5695d3d1a6afSToby Isaac } 5696d3d1a6afSToby Isaac } 5697d3d1a6afSToby Isaac } 5698d3d1a6afSToby Isaac else { 5699d3d1a6afSToby Isaac /* copy this column as is */ 5700d3d1a6afSToby Isaac for (r = 0; r < numIndices; r++) { 5701d3d1a6afSToby Isaac for (c = 0; c < dof; c++) { 5702d3d1a6afSToby Isaac tmpValues[r * newNumIndices + cStart + c] = values[r * numIndices + oldOff + c]; 5703d3d1a6afSToby Isaac } 5704d3d1a6afSToby Isaac } 5705d3d1a6afSToby Isaac } 5706d3d1a6afSToby Isaac oldOff += dof; 5707d3d1a6afSToby Isaac } 5708d3d1a6afSToby Isaac } 5709d3d1a6afSToby Isaac 57106ecaa68aSToby Isaac if (multiplyLeft) { 571169291d52SBarry Smith ierr = DMGetWorkArray(dm,newNumIndices*newNumIndices,MPIU_SCALAR,&newValues);CHKERRQ(ierr); 5712580bdb30SBarry Smith ierr = PetscArrayzero(newValues,newNumIndices*newNumIndices);CHKERRQ(ierr); 5713d3d1a6afSToby Isaac /* multiply constraints transpose on the left */ 5714d3d1a6afSToby Isaac if (numFields) { 5715d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 5716d3d1a6afSToby Isaac PetscInt oldOff = offsets[f]; 5717d3d1a6afSToby Isaac 5718d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 5719d3d1a6afSToby Isaac PetscInt rStart = newPointOffsets[f][p]; 5720d3d1a6afSToby Isaac PetscInt b = points[2 * p]; 5721d3d1a6afSToby Isaac PetscInt c, r, k; 5722d3d1a6afSToby Isaac PetscInt dof; 5723d3d1a6afSToby Isaac 5724d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section,b,f,&dof);CHKERRQ(ierr); 5725d3d1a6afSToby Isaac if (pointMatOffsets[f][p] < pointMatOffsets[f][p + 1]) { 5726d3d1a6afSToby Isaac PetscInt nRows = newPointOffsets[f][p+1]-rStart; 5727d3d1a6afSToby Isaac const PetscScalar *PETSC_RESTRICT mat = pointMat[f] + pointMatOffsets[f][p]; 5728d3d1a6afSToby Isaac 5729d3d1a6afSToby Isaac for (r = 0; r < nRows; r++) { 5730d3d1a6afSToby Isaac for (c = 0; c < newNumIndices; c++) { 5731d3d1a6afSToby Isaac for (k = 0; k < dof; k++) { 5732d3d1a6afSToby Isaac newValues[(rStart + r) * newNumIndices + c] += mat[k * nRows + r] * tmpValues[(oldOff + k) * newNumIndices + c]; 5733d3d1a6afSToby Isaac } 5734d3d1a6afSToby Isaac } 5735d3d1a6afSToby Isaac } 5736d3d1a6afSToby Isaac } 5737d3d1a6afSToby Isaac else { 5738d3d1a6afSToby Isaac /* copy this row as is */ 5739d3d1a6afSToby Isaac for (r = 0; r < dof; r++) { 5740d3d1a6afSToby Isaac for (c = 0; c < newNumIndices; c++) { 5741d3d1a6afSToby Isaac newValues[(rStart + r) * newNumIndices + c] = tmpValues[(oldOff + r) * newNumIndices + c]; 5742d3d1a6afSToby Isaac } 5743d3d1a6afSToby Isaac } 5744d3d1a6afSToby Isaac } 5745d3d1a6afSToby Isaac oldOff += dof; 5746d3d1a6afSToby Isaac } 5747d3d1a6afSToby Isaac } 5748d3d1a6afSToby Isaac } 5749d3d1a6afSToby Isaac else { 5750d3d1a6afSToby Isaac PetscInt oldOff = 0; 5751d3d1a6afSToby Isaac 5752d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 5753d3d1a6afSToby Isaac PetscInt rStart = newPointOffsets[0][p]; 5754d3d1a6afSToby Isaac PetscInt b = points[2 * p]; 5755d3d1a6afSToby Isaac PetscInt c, r, k; 5756d3d1a6afSToby Isaac PetscInt dof; 5757d3d1a6afSToby Isaac 5758d3d1a6afSToby Isaac ierr = PetscSectionGetDof(section,b,&dof);CHKERRQ(ierr); 5759d3d1a6afSToby Isaac if (pointMatOffsets[0][p] < pointMatOffsets[0][p + 1]) { 5760d3d1a6afSToby Isaac PetscInt nRows = newPointOffsets[0][p+1]-rStart; 5761d3d1a6afSToby Isaac const PetscScalar *PETSC_RESTRICT mat = pointMat[0] + pointMatOffsets[0][p]; 5762d3d1a6afSToby Isaac 5763d3d1a6afSToby Isaac for (r = 0; r < nRows; r++) { 5764d3d1a6afSToby Isaac for (c = 0; c < newNumIndices; c++) { 5765d3d1a6afSToby Isaac for (k = 0; k < dof; k++) { 5766d3d1a6afSToby Isaac newValues[(rStart + r) * newNumIndices + c] += mat[k * nRows + r] * tmpValues[(oldOff + k) * newNumIndices + c]; 5767d3d1a6afSToby Isaac } 5768d3d1a6afSToby Isaac } 5769d3d1a6afSToby Isaac } 5770d3d1a6afSToby Isaac } 5771d3d1a6afSToby Isaac else { 5772d3d1a6afSToby Isaac /* copy this row as is */ 57739fc93327SToby Isaac for (r = 0; r < dof; r++) { 5774d3d1a6afSToby Isaac for (c = 0; c < newNumIndices; c++) { 5775d3d1a6afSToby Isaac newValues[(rStart + r) * newNumIndices + c] = tmpValues[(oldOff + r) * newNumIndices + c]; 5776d3d1a6afSToby Isaac } 5777d3d1a6afSToby Isaac } 5778d3d1a6afSToby Isaac } 5779d3d1a6afSToby Isaac oldOff += dof; 5780d3d1a6afSToby Isaac } 5781d3d1a6afSToby Isaac } 5782d3d1a6afSToby Isaac 578369291d52SBarry Smith ierr = DMRestoreWorkArray(dm,newNumIndices*numIndices,MPIU_SCALAR,&tmpValues);CHKERRQ(ierr); 57846ecaa68aSToby Isaac } 57856ecaa68aSToby Isaac else { 57866ecaa68aSToby Isaac newValues = tmpValues; 57876ecaa68aSToby Isaac } 57886ecaa68aSToby Isaac } 57896ecaa68aSToby Isaac 5790d3d1a6afSToby Isaac /* clean up */ 579169291d52SBarry Smith ierr = DMRestoreWorkArray(dm,maxDof,MPIU_INT,&indices);CHKERRQ(ierr); 579269291d52SBarry Smith ierr = DMRestoreWorkArray(dm,maxAnchor*maxDof,MPIU_INT,&newIndices);CHKERRQ(ierr); 57936ecaa68aSToby Isaac 5794d3d1a6afSToby Isaac if (numFields) { 5795d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 579669291d52SBarry Smith ierr = DMRestoreWorkArray(dm,pointMatOffsets[f][numPoints],MPIU_SCALAR,&pointMat[f]);CHKERRQ(ierr); 579769291d52SBarry Smith ierr = DMRestoreWorkArray(dm,numPoints+1,MPIU_INT,&pointMatOffsets[f]);CHKERRQ(ierr); 579869291d52SBarry Smith ierr = DMRestoreWorkArray(dm,numPoints+1,MPIU_INT,&newPointOffsets[f]);CHKERRQ(ierr); 5799d3d1a6afSToby Isaac } 5800d3d1a6afSToby Isaac } 5801d3d1a6afSToby Isaac else { 580269291d52SBarry Smith ierr = DMRestoreWorkArray(dm,pointMatOffsets[0][numPoints],MPIU_SCALAR,&pointMat[0]);CHKERRQ(ierr); 580369291d52SBarry Smith ierr = DMRestoreWorkArray(dm,numPoints+1,MPIU_INT,&pointMatOffsets[0]);CHKERRQ(ierr); 580469291d52SBarry Smith ierr = DMRestoreWorkArray(dm,numPoints+1,MPIU_INT,&newPointOffsets[0]);CHKERRQ(ierr); 5805d3d1a6afSToby Isaac } 5806d3d1a6afSToby Isaac ierr = ISRestoreIndices(aIS,&anchors);CHKERRQ(ierr); 5807d3d1a6afSToby Isaac 5808d3d1a6afSToby Isaac /* output */ 58096ecaa68aSToby Isaac if (outPoints) { 5810d3d1a6afSToby Isaac *outPoints = newPoints; 58116ecaa68aSToby Isaac } 58126ecaa68aSToby Isaac else { 581369291d52SBarry Smith ierr = DMRestoreWorkArray(dm,2*newNumPoints,MPIU_INT,&newPoints);CHKERRQ(ierr); 58146ecaa68aSToby Isaac } 581531620726SToby Isaac if (outValues) { 5816d3d1a6afSToby Isaac *outValues = newValues; 58176ecaa68aSToby Isaac } 58186ecaa68aSToby Isaac for (f = 0; f <= numFields; f++) { 5819d3d1a6afSToby Isaac offsets[f] = newOffsets[f]; 5820d3d1a6afSToby Isaac } 5821d3d1a6afSToby Isaac PetscFunctionReturn(0); 5822d3d1a6afSToby Isaac } 5823d3d1a6afSToby Isaac 58247cd05799SMatthew G. Knepley /*@C 58252cdc749cSStefano Zampini DMPlexGetClosureIndices - Get the global indices for all local points in the closure of the given point 58267cd05799SMatthew G. Knepley 58277cd05799SMatthew G. Knepley Not collective 58287cd05799SMatthew G. Knepley 58297cd05799SMatthew G. Knepley Input Parameters: 58307cd05799SMatthew G. Knepley + dm - The DM 58312cdc749cSStefano Zampini . section - The section describing the local layout 58322cdc749cSStefano Zampini . globalSection - The section describing the parallel layout 58337cd05799SMatthew G. Knepley - point - The mesh point 58347cd05799SMatthew G. Knepley 58357cd05799SMatthew G. Knepley Output parameters: 58367cd05799SMatthew G. Knepley + numIndices - The number of indices 58377cd05799SMatthew G. Knepley . indices - The indices 58387cd05799SMatthew G. Knepley - outOffsets - Field offset if not NULL 58397cd05799SMatthew G. Knepley 58407cd05799SMatthew G. Knepley Note: Must call DMPlexRestoreClosureIndices() to free allocated memory 58417cd05799SMatthew G. Knepley 58427cd05799SMatthew G. Knepley Level: advanced 58437cd05799SMatthew G. Knepley 58447cd05799SMatthew G. Knepley .seealso DMPlexRestoreClosureIndices(), DMPlexVecGetClosure(), DMPlexMatSetClosure() 58457cd05799SMatthew G. Knepley @*/ 58466ecaa68aSToby Isaac PetscErrorCode DMPlexGetClosureIndices(DM dm, PetscSection section, PetscSection globalSection, PetscInt point, PetscInt *numIndices, PetscInt **indices, PetscInt *outOffsets) 58477773e69fSMatthew G. Knepley { 58487773e69fSMatthew G. Knepley PetscSection clSection; 58497773e69fSMatthew G. Knepley IS clPoints; 585005586334SMatthew G. Knepley const PetscInt *clp, *clperm; 58514acb8e1eSToby Isaac const PetscInt **perms[32] = {NULL}; 58527773e69fSMatthew G. Knepley PetscInt *points = NULL, *pointsNew; 58537773e69fSMatthew G. Knepley PetscInt numPoints, numPointsNew; 58547773e69fSMatthew G. Knepley PetscInt offsets[32]; 58557773e69fSMatthew G. Knepley PetscInt Nf, Nind, NindNew, off, globalOff, f, p; 58567773e69fSMatthew G. Knepley PetscErrorCode ierr; 58577773e69fSMatthew G. Knepley 58587773e69fSMatthew G. Knepley PetscFunctionBegin; 58597773e69fSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 58607773e69fSMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 58617773e69fSMatthew G. Knepley PetscValidHeaderSpecific(globalSection, PETSC_SECTION_CLASSID, 3); 58627773e69fSMatthew G. Knepley if (numIndices) PetscValidPointer(numIndices, 4); 58637773e69fSMatthew G. Knepley PetscValidPointer(indices, 5); 58647773e69fSMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &Nf);CHKERRQ(ierr); 58657773e69fSMatthew G. Knepley if (Nf > 31) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Number of fields %D limited to 31", Nf); 5866580bdb30SBarry Smith ierr = PetscArrayzero(offsets, 32);CHKERRQ(ierr); 58677773e69fSMatthew G. Knepley /* Get points in closure */ 5868923c78e0SToby Isaac ierr = DMPlexGetCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 586905586334SMatthew G. Knepley ierr = PetscSectionGetClosureInversePermutation_Internal(section, (PetscObject) dm, NULL, &clperm);CHKERRQ(ierr); 58707773e69fSMatthew G. Knepley /* Get number of indices and indices per field */ 58717773e69fSMatthew G. Knepley for (p = 0, Nind = 0; p < numPoints*2; p += 2) { 58727773e69fSMatthew G. Knepley PetscInt dof, fdof; 58737773e69fSMatthew G. Knepley 58747773e69fSMatthew G. Knepley ierr = PetscSectionGetDof(section, points[p], &dof);CHKERRQ(ierr); 58757773e69fSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 58767773e69fSMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, points[p], f, &fdof);CHKERRQ(ierr); 58777773e69fSMatthew G. Knepley offsets[f+1] += fdof; 58787773e69fSMatthew G. Knepley } 58797773e69fSMatthew G. Knepley Nind += dof; 58807773e69fSMatthew G. Knepley } 58817773e69fSMatthew G. Knepley for (f = 1; f < Nf; ++f) offsets[f+1] += offsets[f]; 58828ccfff9cSToby Isaac if (Nf && offsets[Nf] != Nind) SETERRQ2(PetscObjectComm((PetscObject) dm), PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", offsets[Nf], Nind); 58834acb8e1eSToby Isaac if (!Nf) offsets[1] = Nind; 58844acb8e1eSToby Isaac /* Get dual space symmetries */ 58854acb8e1eSToby Isaac for (f = 0; f < PetscMax(1,Nf); f++) { 58864acb8e1eSToby Isaac if (Nf) {ierr = PetscSectionGetFieldPointSyms(section,f,numPoints,points,&perms[f],NULL);CHKERRQ(ierr);} 58874acb8e1eSToby Isaac else {ierr = PetscSectionGetPointSyms(section,numPoints,points,&perms[f],NULL);CHKERRQ(ierr);} 58884acb8e1eSToby Isaac } 58897773e69fSMatthew G. Knepley /* Correct for hanging node constraints */ 58907773e69fSMatthew G. Knepley { 58914acb8e1eSToby Isaac ierr = DMPlexAnchorsModifyMat(dm, section, numPoints, Nind, points, perms, NULL, &numPointsNew, &NindNew, &pointsNew, NULL, offsets, PETSC_TRUE);CHKERRQ(ierr); 58927773e69fSMatthew G. Knepley if (numPointsNew) { 58934acb8e1eSToby Isaac for (f = 0; f < PetscMax(1,Nf); f++) { 58944acb8e1eSToby Isaac if (Nf) {ierr = PetscSectionRestoreFieldPointSyms(section,f,numPoints,points,&perms[f],NULL);CHKERRQ(ierr);} 58954acb8e1eSToby Isaac else {ierr = PetscSectionRestorePointSyms(section,numPoints,points,&perms[f],NULL);CHKERRQ(ierr);} 58964acb8e1eSToby Isaac } 58974acb8e1eSToby Isaac for (f = 0; f < PetscMax(1,Nf); f++) { 58984acb8e1eSToby Isaac if (Nf) {ierr = PetscSectionGetFieldPointSyms(section,f,numPointsNew,pointsNew,&perms[f],NULL);CHKERRQ(ierr);} 58994acb8e1eSToby Isaac else {ierr = PetscSectionGetPointSyms(section,numPointsNew,pointsNew,&perms[f],NULL);CHKERRQ(ierr);} 59004acb8e1eSToby Isaac } 5901923c78e0SToby Isaac ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 59027773e69fSMatthew G. Knepley numPoints = numPointsNew; 59037773e69fSMatthew G. Knepley Nind = NindNew; 59047773e69fSMatthew G. Knepley points = pointsNew; 59057773e69fSMatthew G. Knepley } 59067773e69fSMatthew G. Knepley } 59077773e69fSMatthew G. Knepley /* Calculate indices */ 590869291d52SBarry Smith ierr = DMGetWorkArray(dm, Nind, MPIU_INT, indices);CHKERRQ(ierr); 59097773e69fSMatthew G. Knepley if (Nf) { 59106ecaa68aSToby Isaac if (outOffsets) { 59116ecaa68aSToby Isaac PetscInt f; 59126ecaa68aSToby Isaac 591346bdb399SToby Isaac for (f = 0; f <= Nf; f++) { 59146ecaa68aSToby Isaac outOffsets[f] = offsets[f]; 59156ecaa68aSToby Isaac } 59166ecaa68aSToby Isaac } 59174acb8e1eSToby Isaac for (p = 0; p < numPoints; p++) { 59184acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalSection, points[2*p], &globalOff);CHKERRQ(ierr); 59192cdc749cSStefano Zampini ierr = DMPlexGetIndicesPointFields_Internal(section, points[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, offsets, PETSC_FALSE, perms, p, clperm, *indices);CHKERRQ(ierr); 59207773e69fSMatthew G. Knepley } 59217773e69fSMatthew G. Knepley } else { 59224acb8e1eSToby Isaac for (p = 0, off = 0; p < numPoints; p++) { 59234acb8e1eSToby Isaac const PetscInt *perm = perms[0] ? perms[0][p] : NULL; 59244acb8e1eSToby Isaac 59254acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalSection, points[2*p], &globalOff);CHKERRQ(ierr); 59262cdc749cSStefano Zampini ierr = DMPlexGetIndicesPoint_Internal(section, points[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, perm, clperm, *indices);CHKERRQ(ierr); 59277773e69fSMatthew G. Knepley } 59287773e69fSMatthew G. Knepley } 59297773e69fSMatthew G. Knepley /* Cleanup points */ 59304acb8e1eSToby Isaac for (f = 0; f < PetscMax(1,Nf); f++) { 59314acb8e1eSToby Isaac if (Nf) {ierr = PetscSectionRestoreFieldPointSyms(section,f,numPoints,points,&perms[f],NULL);CHKERRQ(ierr);} 59324acb8e1eSToby Isaac else {ierr = PetscSectionRestorePointSyms(section,numPoints,points,&perms[f],NULL);CHKERRQ(ierr);} 59334acb8e1eSToby Isaac } 59347773e69fSMatthew G. Knepley if (numPointsNew) { 593569291d52SBarry Smith ierr = DMRestoreWorkArray(dm, 2*numPointsNew, MPIU_INT, &pointsNew);CHKERRQ(ierr); 59367773e69fSMatthew G. Knepley } else { 5937923c78e0SToby Isaac ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 59387773e69fSMatthew G. Knepley } 59397773e69fSMatthew G. Knepley if (numIndices) *numIndices = Nind; 59407773e69fSMatthew G. Knepley PetscFunctionReturn(0); 59417773e69fSMatthew G. Knepley } 59427773e69fSMatthew G. Knepley 59437cd05799SMatthew G. Knepley /*@C 59447cd05799SMatthew G. Knepley DMPlexRestoreClosureIndices - Restore the indices in a vector v for all points in the closure of the given point 59457cd05799SMatthew G. Knepley 59467cd05799SMatthew G. Knepley Not collective 59477cd05799SMatthew G. Knepley 59487cd05799SMatthew G. Knepley Input Parameters: 59497cd05799SMatthew G. Knepley + dm - The DM 59507cd05799SMatthew G. Knepley . section - The section describing the layout in v, or NULL to use the default section 59517cd05799SMatthew G. Knepley . globalSection - The section describing the parallel layout in v, or NULL to use the default section 59527cd05799SMatthew G. Knepley . point - The mesh point 59537cd05799SMatthew G. Knepley . numIndices - The number of indices 59547cd05799SMatthew G. Knepley . indices - The indices 59557cd05799SMatthew G. Knepley - outOffsets - Field offset if not NULL 59567cd05799SMatthew G. Knepley 59577cd05799SMatthew G. Knepley Level: advanced 59587cd05799SMatthew G. Knepley 59597cd05799SMatthew G. Knepley .seealso DMPlexGetClosureIndices(), DMPlexVecGetClosure(), DMPlexMatSetClosure() 59607cd05799SMatthew G. Knepley @*/ 596146bdb399SToby Isaac PetscErrorCode DMPlexRestoreClosureIndices(DM dm, PetscSection section, PetscSection globalSection, PetscInt point, PetscInt *numIndices, PetscInt **indices,PetscInt *outOffsets) 59627773e69fSMatthew G. Knepley { 59637773e69fSMatthew G. Knepley PetscErrorCode ierr; 59647773e69fSMatthew G. Knepley 59657773e69fSMatthew G. Knepley PetscFunctionBegin; 59667773e69fSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 59677773e69fSMatthew G. Knepley PetscValidPointer(indices, 5); 596869291d52SBarry Smith ierr = DMRestoreWorkArray(dm, 0, MPIU_INT, indices);CHKERRQ(ierr); 59697773e69fSMatthew G. Knepley PetscFunctionReturn(0); 59707773e69fSMatthew G. Knepley } 59717773e69fSMatthew G. Knepley 59727f5d1fdeSMatthew G. Knepley /*@C 59737f5d1fdeSMatthew G. Knepley DMPlexMatSetClosure - Set an array of the values on the closure of 'point' 59747f5d1fdeSMatthew G. Knepley 59757f5d1fdeSMatthew G. Knepley Not collective 59767f5d1fdeSMatthew G. Knepley 59777f5d1fdeSMatthew G. Knepley Input Parameters: 59787f5d1fdeSMatthew G. Knepley + dm - The DM 5979ebd6d717SJed Brown . section - The section describing the layout in v, or NULL to use the default section 5980ebd6d717SJed Brown . globalSection - The section describing the layout in v, or NULL to use the default global section 59817f5d1fdeSMatthew G. Knepley . A - The matrix 5982eaf898f9SPatrick Sanan . point - The point in the DM 59837f5d1fdeSMatthew G. Knepley . values - The array of values 59847f5d1fdeSMatthew G. Knepley - mode - The insert mode, where INSERT_ALL_VALUES and ADD_ALL_VALUES also overwrite boundary conditions 59857f5d1fdeSMatthew G. Knepley 59867f5d1fdeSMatthew G. Knepley Fortran Notes: 59877f5d1fdeSMatthew G. Knepley This routine is only available in Fortran 90, and you must include petsc.h90 in your code. 59887f5d1fdeSMatthew G. Knepley 59897f5d1fdeSMatthew G. Knepley Level: intermediate 59907f5d1fdeSMatthew G. Knepley 59917f5d1fdeSMatthew G. Knepley .seealso DMPlexVecGetClosure(), DMPlexVecSetClosure() 59927f5d1fdeSMatthew G. Knepley @*/ 59937c1f9639SMatthew G Knepley PetscErrorCode DMPlexMatSetClosure(DM dm, PetscSection section, PetscSection globalSection, Mat A, PetscInt point, const PetscScalar values[], InsertMode mode) 5994552f7358SJed Brown { 5995552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 59961b406b76SMatthew G. Knepley PetscSection clSection; 59971b406b76SMatthew G. Knepley IS clPoints; 5998d3d1a6afSToby Isaac PetscInt *points = NULL, *newPoints; 599905586334SMatthew G. Knepley const PetscInt *clp, *clperm; 6000552f7358SJed Brown PetscInt *indices; 6001552f7358SJed Brown PetscInt offsets[32]; 60024acb8e1eSToby Isaac const PetscInt **perms[32] = {NULL}; 60034acb8e1eSToby Isaac const PetscScalar **flips[32] = {NULL}; 6004923c78e0SToby Isaac PetscInt numFields, numPoints, newNumPoints, numIndices, newNumIndices, dof, off, globalOff, p, f; 60054acb8e1eSToby Isaac PetscScalar *valCopy = NULL; 6006d3d1a6afSToby Isaac PetscScalar *newValues; 6007552f7358SJed Brown PetscErrorCode ierr; 6008552f7358SJed Brown 6009552f7358SJed Brown PetscFunctionBegin; 6010552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 601192fd8e1eSJed Brown if (!section) {ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr);} 60123dc93601SMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 6013e87a4003SBarry Smith if (!globalSection) {ierr = DMGetGlobalSection(dm, &globalSection);CHKERRQ(ierr);} 60143dc93601SMatthew G. Knepley PetscValidHeaderSpecific(globalSection, PETSC_SECTION_CLASSID, 3); 60153dc93601SMatthew G. Knepley PetscValidHeaderSpecific(A, MAT_CLASSID, 4); 6016552f7358SJed Brown ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 601782f516ccSBarry Smith if (numFields > 31) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Number of fields %D limited to 31", numFields); 6018580bdb30SBarry Smith ierr = PetscArrayzero(offsets, 32);CHKERRQ(ierr); 601905586334SMatthew G. Knepley ierr = PetscSectionGetClosureInversePermutation_Internal(section, (PetscObject) dm, NULL, &clperm);CHKERRQ(ierr); 6020923c78e0SToby Isaac ierr = DMPlexGetCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 6021552f7358SJed Brown for (p = 0, numIndices = 0; p < numPoints*2; p += 2) { 6022552f7358SJed Brown PetscInt fdof; 6023552f7358SJed Brown 6024552f7358SJed Brown ierr = PetscSectionGetDof(section, points[p], &dof);CHKERRQ(ierr); 6025552f7358SJed Brown for (f = 0; f < numFields; ++f) { 6026552f7358SJed Brown ierr = PetscSectionGetFieldDof(section, points[p], f, &fdof);CHKERRQ(ierr); 6027552f7358SJed Brown offsets[f+1] += fdof; 6028552f7358SJed Brown } 6029552f7358SJed Brown numIndices += dof; 6030552f7358SJed Brown } 60310d644c17SKarl Rupp for (f = 1; f < numFields; ++f) offsets[f+1] += offsets[f]; 60320d644c17SKarl Rupp 60338ccfff9cSToby Isaac if (numFields && offsets[numFields] != numIndices) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", offsets[numFields], numIndices); 60344acb8e1eSToby Isaac /* Get symmetries */ 60354acb8e1eSToby Isaac for (f = 0; f < PetscMax(1,numFields); f++) { 60364acb8e1eSToby Isaac if (numFields) {ierr = PetscSectionGetFieldPointSyms(section,f,numPoints,points,&perms[f],&flips[f]);CHKERRQ(ierr);} 60374acb8e1eSToby Isaac else {ierr = PetscSectionGetPointSyms(section,numPoints,points,&perms[f],&flips[f]);CHKERRQ(ierr);} 60384acb8e1eSToby Isaac if (values && flips[f]) { /* may need to apply sign changes to the element matrix */ 60394acb8e1eSToby Isaac PetscInt foffset = offsets[f]; 60404acb8e1eSToby Isaac 60414acb8e1eSToby Isaac for (p = 0; p < numPoints; p++) { 60424acb8e1eSToby Isaac PetscInt point = points[2*p], fdof; 60434acb8e1eSToby Isaac const PetscScalar *flip = flips[f] ? flips[f][p] : NULL; 60444acb8e1eSToby Isaac 60454acb8e1eSToby Isaac if (!numFields) { 60464acb8e1eSToby Isaac ierr = PetscSectionGetDof(section,point,&fdof);CHKERRQ(ierr); 60474acb8e1eSToby Isaac } else { 60484acb8e1eSToby Isaac ierr = PetscSectionGetFieldDof(section,point,f,&fdof);CHKERRQ(ierr); 60494acb8e1eSToby Isaac } 60504acb8e1eSToby Isaac if (flip) { 60514acb8e1eSToby Isaac PetscInt i, j, k; 60524acb8e1eSToby Isaac 60534acb8e1eSToby Isaac if (!valCopy) { 605469291d52SBarry Smith ierr = DMGetWorkArray(dm,numIndices*numIndices,MPIU_SCALAR,&valCopy);CHKERRQ(ierr); 60554acb8e1eSToby Isaac for (j = 0; j < numIndices * numIndices; j++) valCopy[j] = values[j]; 60564acb8e1eSToby Isaac values = valCopy; 60574acb8e1eSToby Isaac } 60584acb8e1eSToby Isaac for (i = 0; i < fdof; i++) { 6059775f7be2SToby Isaac PetscScalar fval = flip[i]; 60604acb8e1eSToby Isaac 60614acb8e1eSToby Isaac for (k = 0; k < numIndices; k++) { 60624acb8e1eSToby Isaac valCopy[numIndices * (foffset + i) + k] *= fval; 60634acb8e1eSToby Isaac valCopy[numIndices * k + (foffset + i)] *= fval; 60644acb8e1eSToby Isaac } 60654acb8e1eSToby Isaac } 60664acb8e1eSToby Isaac } 60674acb8e1eSToby Isaac foffset += fdof; 60684acb8e1eSToby Isaac } 60694acb8e1eSToby Isaac } 60704acb8e1eSToby Isaac } 60714acb8e1eSToby Isaac ierr = DMPlexAnchorsModifyMat(dm,section,numPoints,numIndices,points,perms,values,&newNumPoints,&newNumIndices,&newPoints,&newValues,offsets,PETSC_TRUE);CHKERRQ(ierr); 6072d3d1a6afSToby Isaac if (newNumPoints) { 60734acb8e1eSToby Isaac if (valCopy) { 607469291d52SBarry Smith ierr = DMRestoreWorkArray(dm,numIndices*numIndices,MPIU_SCALAR,&valCopy);CHKERRQ(ierr); 60754acb8e1eSToby Isaac } 60764acb8e1eSToby Isaac for (f = 0; f < PetscMax(1,numFields); f++) { 60774acb8e1eSToby Isaac if (numFields) {ierr = PetscSectionRestoreFieldPointSyms(section,f,numPoints,points,&perms[f],&flips[f]);CHKERRQ(ierr);} 60784acb8e1eSToby Isaac else {ierr = PetscSectionRestorePointSyms(section,numPoints,points,&perms[f],&flips[f]);CHKERRQ(ierr);} 60794acb8e1eSToby Isaac } 60804acb8e1eSToby Isaac for (f = 0; f < PetscMax(1,numFields); f++) { 60814acb8e1eSToby Isaac if (numFields) {ierr = PetscSectionGetFieldPointSyms(section,f,newNumPoints,newPoints,&perms[f],&flips[f]);CHKERRQ(ierr);} 60824acb8e1eSToby Isaac else {ierr = PetscSectionGetPointSyms(section,newNumPoints,newPoints,&perms[f],&flips[f]);CHKERRQ(ierr);} 60834acb8e1eSToby Isaac } 6084923c78e0SToby Isaac ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 6085d3d1a6afSToby Isaac numPoints = newNumPoints; 6086d3d1a6afSToby Isaac numIndices = newNumIndices; 6087d3d1a6afSToby Isaac points = newPoints; 6088d3d1a6afSToby Isaac values = newValues; 6089d3d1a6afSToby Isaac } 609069291d52SBarry Smith ierr = DMGetWorkArray(dm, numIndices, MPIU_INT, &indices);CHKERRQ(ierr); 6091552f7358SJed Brown if (numFields) { 60927e29afd2SMatthew G. Knepley PetscBool useFieldOffsets; 60937e29afd2SMatthew G. Knepley 60947e29afd2SMatthew G. Knepley ierr = PetscSectionGetUseFieldOffsets(globalSection, &useFieldOffsets);CHKERRQ(ierr); 60957e29afd2SMatthew G. Knepley if (useFieldOffsets) { 60967e29afd2SMatthew G. Knepley for (p = 0; p < numPoints; p++) { 609705586334SMatthew G. Knepley DMPlexGetIndicesPointFieldsSplit_Internal(section, globalSection, points[2*p], offsets, PETSC_FALSE, perms, p, clperm, indices); 60987e29afd2SMatthew G. Knepley } 60997e29afd2SMatthew G. Knepley } else { 61004acb8e1eSToby Isaac for (p = 0; p < numPoints; p++) { 61014acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalSection, points[2*p], &globalOff);CHKERRQ(ierr); 610205586334SMatthew G. Knepley DMPlexGetIndicesPointFields_Internal(section, points[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, offsets, PETSC_FALSE, perms, p, clperm, indices); 6103552f7358SJed Brown } 61047e29afd2SMatthew G. Knepley } 6105552f7358SJed Brown } else { 61064acb8e1eSToby Isaac for (p = 0, off = 0; p < numPoints; p++) { 61074acb8e1eSToby Isaac const PetscInt *perm = perms[0] ? perms[0][p] : NULL; 61084acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalSection, points[2*p], &globalOff);CHKERRQ(ierr); 610905586334SMatthew G. Knepley DMPlexGetIndicesPoint_Internal(section, points[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, perm, clperm, indices); 6110552f7358SJed Brown } 6111552f7358SJed Brown } 6112b0ecff45SMatthew G. Knepley if (mesh->printSetValues) {ierr = DMPlexPrintMatSetValues(PETSC_VIEWER_STDOUT_SELF, A, point, numIndices, indices, 0, NULL, values);CHKERRQ(ierr);} 6113552f7358SJed Brown ierr = MatSetValues(A, numIndices, indices, numIndices, indices, values, mode); 6114ab1d0545SMatthew G. Knepley if (mesh->printFEM > 1) { 6115ab1d0545SMatthew G. Knepley PetscInt i; 6116ab1d0545SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " Indices:");CHKERRQ(ierr); 61178ccfff9cSToby Isaac for (i = 0; i < numIndices; ++i) {ierr = PetscPrintf(PETSC_COMM_SELF, " %D", indices[i]);CHKERRQ(ierr);} 6118ab1d0545SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 6119ab1d0545SMatthew G. Knepley } 6120552f7358SJed Brown if (ierr) { 6121552f7358SJed Brown PetscMPIInt rank; 6122552f7358SJed Brown PetscErrorCode ierr2; 6123552f7358SJed Brown 612482f516ccSBarry Smith ierr2 = MPI_Comm_rank(PetscObjectComm((PetscObject)A), &rank);CHKERRQ(ierr2); 6125e4b003c7SBarry Smith ierr2 = (*PetscErrorPrintf)("[%d]ERROR in DMPlexMatSetClosure\n", rank);CHKERRQ(ierr2); 6126b0ecff45SMatthew G. Knepley ierr2 = DMPlexPrintMatSetValues(PETSC_VIEWER_STDERR_SELF, A, point, numIndices, indices, 0, NULL, values);CHKERRQ(ierr2); 612769291d52SBarry Smith ierr2 = DMRestoreWorkArray(dm, numIndices, MPIU_INT, &indices);CHKERRQ(ierr2); 6128552f7358SJed Brown CHKERRQ(ierr); 6129552f7358SJed Brown } 61304acb8e1eSToby Isaac for (f = 0; f < PetscMax(1,numFields); f++) { 61314acb8e1eSToby Isaac if (numFields) {ierr = PetscSectionRestoreFieldPointSyms(section,f,numPoints,points,&perms[f],&flips[f]);CHKERRQ(ierr);} 61324acb8e1eSToby Isaac else {ierr = PetscSectionRestorePointSyms(section,numPoints,points,&perms[f],&flips[f]);CHKERRQ(ierr);} 61334acb8e1eSToby Isaac } 6134d3d1a6afSToby Isaac if (newNumPoints) { 613569291d52SBarry Smith ierr = DMRestoreWorkArray(dm,newNumIndices*newNumIndices,MPIU_SCALAR,&newValues);CHKERRQ(ierr); 613669291d52SBarry Smith ierr = DMRestoreWorkArray(dm,2*newNumPoints,MPIU_INT,&newPoints);CHKERRQ(ierr); 6137d3d1a6afSToby Isaac } 6138d3d1a6afSToby Isaac else { 61394acb8e1eSToby Isaac if (valCopy) { 614069291d52SBarry Smith ierr = DMRestoreWorkArray(dm,numIndices*numIndices,MPIU_SCALAR,&valCopy);CHKERRQ(ierr); 61414acb8e1eSToby Isaac } 6142923c78e0SToby Isaac ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 6143d3d1a6afSToby Isaac } 614469291d52SBarry Smith ierr = DMRestoreWorkArray(dm, numIndices, MPIU_INT, &indices);CHKERRQ(ierr); 6145552f7358SJed Brown PetscFunctionReturn(0); 6146552f7358SJed Brown } 6147552f7358SJed Brown 6148de41b84cSMatthew 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) 6149de41b84cSMatthew G. Knepley { 6150de41b84cSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dmf->data; 6151de41b84cSMatthew G. Knepley PetscInt *fpoints = NULL, *ftotpoints = NULL; 6152de41b84cSMatthew G. Knepley PetscInt *cpoints = NULL; 6153de41b84cSMatthew G. Knepley PetscInt *findices, *cindices; 615405586334SMatthew G. Knepley const PetscInt *fclperm, *cclperm; 6155de41b84cSMatthew G. Knepley PetscInt foffsets[32], coffsets[32]; 6156de41b84cSMatthew G. Knepley CellRefiner cellRefiner; 61574ca5e9f5SMatthew G. Knepley PetscInt numFields, numSubcells, maxFPoints, numFPoints, numCPoints, numFIndices, numCIndices, dof, off, globalOff, pStart, pEnd, p, q, r, s, f; 6158de41b84cSMatthew G. Knepley PetscErrorCode ierr; 6159de41b84cSMatthew G. Knepley 6160de41b84cSMatthew G. Knepley PetscFunctionBegin; 6161de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(dmf, DM_CLASSID, 1); 6162de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(dmc, DM_CLASSID, 4); 616392fd8e1eSJed Brown if (!fsection) {ierr = DMGetLocalSection(dmf, &fsection);CHKERRQ(ierr);} 6164de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(fsection, PETSC_SECTION_CLASSID, 2); 616592fd8e1eSJed Brown if (!csection) {ierr = DMGetLocalSection(dmc, &csection);CHKERRQ(ierr);} 6166de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(csection, PETSC_SECTION_CLASSID, 5); 6167e87a4003SBarry Smith if (!globalFSection) {ierr = DMGetGlobalSection(dmf, &globalFSection);CHKERRQ(ierr);} 6168de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(globalFSection, PETSC_SECTION_CLASSID, 3); 6169e87a4003SBarry Smith if (!globalCSection) {ierr = DMGetGlobalSection(dmc, &globalCSection);CHKERRQ(ierr);} 6170de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(globalCSection, PETSC_SECTION_CLASSID, 6); 6171de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(A, MAT_CLASSID, 7); 6172de41b84cSMatthew G. Knepley ierr = PetscSectionGetNumFields(fsection, &numFields);CHKERRQ(ierr); 6173de41b84cSMatthew G. Knepley if (numFields > 31) SETERRQ1(PetscObjectComm((PetscObject)dmf), PETSC_ERR_ARG_OUTOFRANGE, "Number of fields %D limited to 31", numFields); 6174580bdb30SBarry Smith ierr = PetscArrayzero(foffsets, 32);CHKERRQ(ierr); 6175580bdb30SBarry Smith ierr = PetscArrayzero(coffsets, 32);CHKERRQ(ierr); 617605586334SMatthew G. Knepley ierr = PetscSectionGetClosureInversePermutation_Internal(fsection, (PetscObject) dmf, NULL, &fclperm);CHKERRQ(ierr); 617705586334SMatthew G. Knepley ierr = PetscSectionGetClosureInversePermutation_Internal(csection, (PetscObject) dmc, NULL, &cclperm);CHKERRQ(ierr); 6178de41b84cSMatthew G. Knepley /* Column indices */ 6179de41b84cSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dmc, point, PETSC_TRUE, &numCPoints, &cpoints);CHKERRQ(ierr); 61804ca5e9f5SMatthew G. Knepley maxFPoints = numCPoints; 6181de41b84cSMatthew G. Knepley /* Compress out points not in the section */ 6182de41b84cSMatthew G. Knepley /* TODO: Squeeze out points with 0 dof as well */ 6183de41b84cSMatthew G. Knepley ierr = PetscSectionGetChart(csection, &pStart, &pEnd);CHKERRQ(ierr); 6184de41b84cSMatthew G. Knepley for (p = 0, q = 0; p < numCPoints*2; p += 2) { 6185de41b84cSMatthew G. Knepley if ((cpoints[p] >= pStart) && (cpoints[p] < pEnd)) { 6186de41b84cSMatthew G. Knepley cpoints[q*2] = cpoints[p]; 6187de41b84cSMatthew G. Knepley cpoints[q*2+1] = cpoints[p+1]; 6188de41b84cSMatthew G. Knepley ++q; 6189de41b84cSMatthew G. Knepley } 6190de41b84cSMatthew G. Knepley } 6191de41b84cSMatthew G. Knepley numCPoints = q; 6192de41b84cSMatthew G. Knepley for (p = 0, numCIndices = 0; p < numCPoints*2; p += 2) { 6193de41b84cSMatthew G. Knepley PetscInt fdof; 6194de41b84cSMatthew G. Knepley 6195de41b84cSMatthew G. Knepley ierr = PetscSectionGetDof(csection, cpoints[p], &dof);CHKERRQ(ierr); 61964ca5e9f5SMatthew G. Knepley if (!dof) continue; 6197de41b84cSMatthew G. Knepley for (f = 0; f < numFields; ++f) { 6198de41b84cSMatthew G. Knepley ierr = PetscSectionGetFieldDof(csection, cpoints[p], f, &fdof);CHKERRQ(ierr); 6199de41b84cSMatthew G. Knepley coffsets[f+1] += fdof; 6200de41b84cSMatthew G. Knepley } 6201de41b84cSMatthew G. Knepley numCIndices += dof; 6202de41b84cSMatthew G. Knepley } 6203de41b84cSMatthew G. Knepley for (f = 1; f < numFields; ++f) coffsets[f+1] += coffsets[f]; 6204de41b84cSMatthew G. Knepley /* Row indices */ 6205de41b84cSMatthew G. Knepley ierr = DMPlexGetCellRefiner_Internal(dmc, &cellRefiner);CHKERRQ(ierr); 6206de41b84cSMatthew G. Knepley ierr = CellRefinerGetAffineTransforms_Internal(cellRefiner, &numSubcells, NULL, NULL, NULL);CHKERRQ(ierr); 620769291d52SBarry Smith ierr = DMGetWorkArray(dmf, maxFPoints*2*numSubcells, MPIU_INT, &ftotpoints);CHKERRQ(ierr); 6208de41b84cSMatthew G. Knepley for (r = 0, q = 0; r < numSubcells; ++r) { 6209de41b84cSMatthew G. Knepley /* TODO Map from coarse to fine cells */ 6210de41b84cSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dmf, point*numSubcells + r, PETSC_TRUE, &numFPoints, &fpoints);CHKERRQ(ierr); 6211de41b84cSMatthew G. Knepley /* Compress out points not in the section */ 6212de41b84cSMatthew G. Knepley ierr = PetscSectionGetChart(fsection, &pStart, &pEnd);CHKERRQ(ierr); 6213de41b84cSMatthew G. Knepley for (p = 0; p < numFPoints*2; p += 2) { 6214de41b84cSMatthew G. Knepley if ((fpoints[p] >= pStart) && (fpoints[p] < pEnd)) { 62154ca5e9f5SMatthew G. Knepley ierr = PetscSectionGetDof(fsection, fpoints[p], &dof);CHKERRQ(ierr); 62164ca5e9f5SMatthew G. Knepley if (!dof) continue; 62174ca5e9f5SMatthew G. Knepley for (s = 0; s < q; ++s) if (fpoints[p] == ftotpoints[s*2]) break; 62184ca5e9f5SMatthew G. Knepley if (s < q) continue; 6219de41b84cSMatthew G. Knepley ftotpoints[q*2] = fpoints[p]; 6220de41b84cSMatthew G. Knepley ftotpoints[q*2+1] = fpoints[p+1]; 6221de41b84cSMatthew G. Knepley ++q; 6222de41b84cSMatthew G. Knepley } 6223de41b84cSMatthew G. Knepley } 6224de41b84cSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dmf, point, PETSC_TRUE, &numFPoints, &fpoints);CHKERRQ(ierr); 6225de41b84cSMatthew G. Knepley } 6226de41b84cSMatthew G. Knepley numFPoints = q; 6227de41b84cSMatthew G. Knepley for (p = 0, numFIndices = 0; p < numFPoints*2; p += 2) { 6228de41b84cSMatthew G. Knepley PetscInt fdof; 6229de41b84cSMatthew G. Knepley 6230de41b84cSMatthew G. Knepley ierr = PetscSectionGetDof(fsection, ftotpoints[p], &dof);CHKERRQ(ierr); 62314ca5e9f5SMatthew G. Knepley if (!dof) continue; 6232de41b84cSMatthew G. Knepley for (f = 0; f < numFields; ++f) { 6233de41b84cSMatthew G. Knepley ierr = PetscSectionGetFieldDof(fsection, ftotpoints[p], f, &fdof);CHKERRQ(ierr); 6234de41b84cSMatthew G. Knepley foffsets[f+1] += fdof; 6235de41b84cSMatthew G. Knepley } 6236de41b84cSMatthew G. Knepley numFIndices += dof; 6237de41b84cSMatthew G. Knepley } 6238de41b84cSMatthew G. Knepley for (f = 1; f < numFields; ++f) foffsets[f+1] += foffsets[f]; 6239de41b84cSMatthew G. Knepley 62408ccfff9cSToby Isaac if (numFields && foffsets[numFields] != numFIndices) SETERRQ2(PetscObjectComm((PetscObject)dmf), PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", foffsets[numFields], numFIndices); 62418ccfff9cSToby Isaac if (numFields && coffsets[numFields] != numCIndices) SETERRQ2(PetscObjectComm((PetscObject)dmc), PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", coffsets[numFields], numCIndices); 624269291d52SBarry Smith ierr = DMGetWorkArray(dmf, numFIndices, MPIU_INT, &findices);CHKERRQ(ierr); 624369291d52SBarry Smith ierr = DMGetWorkArray(dmc, numCIndices, MPIU_INT, &cindices);CHKERRQ(ierr); 6244de41b84cSMatthew G. Knepley if (numFields) { 62454acb8e1eSToby Isaac const PetscInt **permsF[32] = {NULL}; 62464acb8e1eSToby Isaac const PetscInt **permsC[32] = {NULL}; 62474acb8e1eSToby Isaac 62484acb8e1eSToby Isaac for (f = 0; f < numFields; f++) { 62494acb8e1eSToby Isaac ierr = PetscSectionGetFieldPointSyms(fsection,f,numFPoints,ftotpoints,&permsF[f],NULL);CHKERRQ(ierr); 62504acb8e1eSToby Isaac ierr = PetscSectionGetFieldPointSyms(csection,f,numCPoints,cpoints,&permsC[f],NULL);CHKERRQ(ierr); 6251de41b84cSMatthew G. Knepley } 62524acb8e1eSToby Isaac for (p = 0; p < numFPoints; p++) { 62534acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalFSection, ftotpoints[2*p], &globalOff);CHKERRQ(ierr); 625405586334SMatthew G. Knepley ierr = DMPlexGetIndicesPointFields_Internal(fsection, ftotpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, foffsets, PETSC_FALSE, permsF, p, fclperm, findices);CHKERRQ(ierr); 62554acb8e1eSToby Isaac } 62564acb8e1eSToby Isaac for (p = 0; p < numCPoints; p++) { 62574acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalCSection, cpoints[2*p], &globalOff);CHKERRQ(ierr); 625805586334SMatthew G. Knepley ierr = DMPlexGetIndicesPointFields_Internal(csection, cpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, coffsets, PETSC_FALSE, permsC, p, cclperm, cindices);CHKERRQ(ierr); 62594acb8e1eSToby Isaac } 62604acb8e1eSToby Isaac for (f = 0; f < numFields; f++) { 62614acb8e1eSToby Isaac ierr = PetscSectionRestoreFieldPointSyms(fsection,f,numFPoints,ftotpoints,&permsF[f],NULL);CHKERRQ(ierr); 62624acb8e1eSToby Isaac ierr = PetscSectionRestoreFieldPointSyms(csection,f,numCPoints,cpoints,&permsC[f],NULL);CHKERRQ(ierr); 6263de41b84cSMatthew G. Knepley } 6264de41b84cSMatthew G. Knepley } else { 62654acb8e1eSToby Isaac const PetscInt **permsF = NULL; 62664acb8e1eSToby Isaac const PetscInt **permsC = NULL; 62674acb8e1eSToby Isaac 62684acb8e1eSToby Isaac ierr = PetscSectionGetPointSyms(fsection,numFPoints,ftotpoints,&permsF,NULL);CHKERRQ(ierr); 62694acb8e1eSToby Isaac ierr = PetscSectionGetPointSyms(csection,numCPoints,cpoints,&permsC,NULL);CHKERRQ(ierr); 62704acb8e1eSToby Isaac for (p = 0, off = 0; p < numFPoints; p++) { 62714acb8e1eSToby Isaac const PetscInt *perm = permsF ? permsF[p] : NULL; 62724acb8e1eSToby Isaac 62734acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalFSection, ftotpoints[2*p], &globalOff);CHKERRQ(ierr); 627405586334SMatthew G. Knepley ierr = DMPlexGetIndicesPoint_Internal(fsection, ftotpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, perm, fclperm, findices);CHKERRQ(ierr); 6275de41b84cSMatthew G. Knepley } 62764acb8e1eSToby Isaac for (p = 0, off = 0; p < numCPoints; p++) { 62774acb8e1eSToby Isaac const PetscInt *perm = permsC ? permsC[p] : NULL; 62784acb8e1eSToby Isaac 62794acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalCSection, cpoints[2*p], &globalOff);CHKERRQ(ierr); 628005586334SMatthew G. Knepley ierr = DMPlexGetIndicesPoint_Internal(csection, cpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, perm, cclperm, cindices);CHKERRQ(ierr); 6281de41b84cSMatthew G. Knepley } 62824acb8e1eSToby Isaac ierr = PetscSectionRestorePointSyms(fsection,numFPoints,ftotpoints,&permsF,NULL);CHKERRQ(ierr); 62834acb8e1eSToby Isaac ierr = PetscSectionRestorePointSyms(csection,numCPoints,cpoints,&permsC,NULL);CHKERRQ(ierr); 6284de41b84cSMatthew G. Knepley } 6285de41b84cSMatthew G. Knepley if (mesh->printSetValues) {ierr = DMPlexPrintMatSetValues(PETSC_VIEWER_STDOUT_SELF, A, point, numFIndices, findices, numCIndices, cindices, values);CHKERRQ(ierr);} 62864acb8e1eSToby Isaac /* TODO: flips */ 6287de41b84cSMatthew G. Knepley ierr = MatSetValues(A, numFIndices, findices, numCIndices, cindices, values, mode); 6288de41b84cSMatthew G. Knepley if (ierr) { 6289de41b84cSMatthew G. Knepley PetscMPIInt rank; 6290de41b84cSMatthew G. Knepley PetscErrorCode ierr2; 6291de41b84cSMatthew G. Knepley 6292de41b84cSMatthew G. Knepley ierr2 = MPI_Comm_rank(PetscObjectComm((PetscObject)A), &rank);CHKERRQ(ierr2); 6293e4b003c7SBarry Smith ierr2 = (*PetscErrorPrintf)("[%d]ERROR in DMPlexMatSetClosure\n", rank);CHKERRQ(ierr2); 6294de41b84cSMatthew G. Knepley ierr2 = DMPlexPrintMatSetValues(PETSC_VIEWER_STDERR_SELF, A, point, numFIndices, findices, numCIndices, cindices, values);CHKERRQ(ierr2); 629569291d52SBarry Smith ierr2 = DMRestoreWorkArray(dmf, numFIndices, MPIU_INT, &findices);CHKERRQ(ierr2); 629669291d52SBarry Smith ierr2 = DMRestoreWorkArray(dmc, numCIndices, MPIU_INT, &cindices);CHKERRQ(ierr2); 6297de41b84cSMatthew G. Knepley CHKERRQ(ierr); 6298de41b84cSMatthew G. Knepley } 629969291d52SBarry Smith ierr = DMRestoreWorkArray(dmf, numCPoints*2*4, MPIU_INT, &ftotpoints);CHKERRQ(ierr); 6300de41b84cSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dmc, point, PETSC_TRUE, &numCPoints, &cpoints);CHKERRQ(ierr); 630169291d52SBarry Smith ierr = DMRestoreWorkArray(dmf, numFIndices, MPIU_INT, &findices);CHKERRQ(ierr); 630269291d52SBarry Smith ierr = DMRestoreWorkArray(dmc, numCIndices, MPIU_INT, &cindices);CHKERRQ(ierr); 6303de41b84cSMatthew G. Knepley PetscFunctionReturn(0); 6304de41b84cSMatthew G. Knepley } 6305de41b84cSMatthew G. Knepley 63067c927364SMatthew G. Knepley PetscErrorCode DMPlexMatGetClosureIndicesRefined(DM dmf, PetscSection fsection, PetscSection globalFSection, DM dmc, PetscSection csection, PetscSection globalCSection, PetscInt point, PetscInt cindices[], PetscInt findices[]) 63077c927364SMatthew G. Knepley { 63087c927364SMatthew G. Knepley PetscInt *fpoints = NULL, *ftotpoints = NULL; 63097c927364SMatthew G. Knepley PetscInt *cpoints = NULL; 63107c927364SMatthew G. Knepley PetscInt foffsets[32], coffsets[32]; 631105586334SMatthew G. Knepley const PetscInt *fclperm, *cclperm; 63127c927364SMatthew G. Knepley CellRefiner cellRefiner; 63137c927364SMatthew G. Knepley PetscInt numFields, numSubcells, maxFPoints, numFPoints, numCPoints, numFIndices, numCIndices, dof, off, globalOff, pStart, pEnd, p, q, r, s, f; 63147c927364SMatthew G. Knepley PetscErrorCode ierr; 63157c927364SMatthew G. Knepley 63167c927364SMatthew G. Knepley PetscFunctionBegin; 63177c927364SMatthew G. Knepley PetscValidHeaderSpecific(dmf, DM_CLASSID, 1); 63187c927364SMatthew G. Knepley PetscValidHeaderSpecific(dmc, DM_CLASSID, 4); 631992fd8e1eSJed Brown if (!fsection) {ierr = DMGetLocalSection(dmf, &fsection);CHKERRQ(ierr);} 63207c927364SMatthew G. Knepley PetscValidHeaderSpecific(fsection, PETSC_SECTION_CLASSID, 2); 632192fd8e1eSJed Brown if (!csection) {ierr = DMGetLocalSection(dmc, &csection);CHKERRQ(ierr);} 63227c927364SMatthew G. Knepley PetscValidHeaderSpecific(csection, PETSC_SECTION_CLASSID, 5); 6323e87a4003SBarry Smith if (!globalFSection) {ierr = DMGetGlobalSection(dmf, &globalFSection);CHKERRQ(ierr);} 63247c927364SMatthew G. Knepley PetscValidHeaderSpecific(globalFSection, PETSC_SECTION_CLASSID, 3); 6325e87a4003SBarry Smith if (!globalCSection) {ierr = DMGetGlobalSection(dmc, &globalCSection);CHKERRQ(ierr);} 63267c927364SMatthew G. Knepley PetscValidHeaderSpecific(globalCSection, PETSC_SECTION_CLASSID, 6); 63277c927364SMatthew G. Knepley ierr = PetscSectionGetNumFields(fsection, &numFields);CHKERRQ(ierr); 63287c927364SMatthew G. Knepley if (numFields > 31) SETERRQ1(PetscObjectComm((PetscObject)dmf), PETSC_ERR_ARG_OUTOFRANGE, "Number of fields %D limited to 31", numFields); 6329580bdb30SBarry Smith ierr = PetscArrayzero(foffsets, 32);CHKERRQ(ierr); 6330580bdb30SBarry Smith ierr = PetscArrayzero(coffsets, 32);CHKERRQ(ierr); 633105586334SMatthew G. Knepley ierr = PetscSectionGetClosureInversePermutation_Internal(fsection, (PetscObject) dmf, NULL, &fclperm);CHKERRQ(ierr); 633205586334SMatthew G. Knepley ierr = PetscSectionGetClosureInversePermutation_Internal(csection, (PetscObject) dmc, NULL, &cclperm);CHKERRQ(ierr); 63337c927364SMatthew G. Knepley /* Column indices */ 63347c927364SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dmc, point, PETSC_TRUE, &numCPoints, &cpoints);CHKERRQ(ierr); 63357c927364SMatthew G. Knepley maxFPoints = numCPoints; 63367c927364SMatthew G. Knepley /* Compress out points not in the section */ 63377c927364SMatthew G. Knepley /* TODO: Squeeze out points with 0 dof as well */ 63387c927364SMatthew G. Knepley ierr = PetscSectionGetChart(csection, &pStart, &pEnd);CHKERRQ(ierr); 63397c927364SMatthew G. Knepley for (p = 0, q = 0; p < numCPoints*2; p += 2) { 63407c927364SMatthew G. Knepley if ((cpoints[p] >= pStart) && (cpoints[p] < pEnd)) { 63417c927364SMatthew G. Knepley cpoints[q*2] = cpoints[p]; 63427c927364SMatthew G. Knepley cpoints[q*2+1] = cpoints[p+1]; 63437c927364SMatthew G. Knepley ++q; 63447c927364SMatthew G. Knepley } 63457c927364SMatthew G. Knepley } 63467c927364SMatthew G. Knepley numCPoints = q; 63477c927364SMatthew G. Knepley for (p = 0, numCIndices = 0; p < numCPoints*2; p += 2) { 63487c927364SMatthew G. Knepley PetscInt fdof; 63497c927364SMatthew G. Knepley 63507c927364SMatthew G. Knepley ierr = PetscSectionGetDof(csection, cpoints[p], &dof);CHKERRQ(ierr); 63517c927364SMatthew G. Knepley if (!dof) continue; 63527c927364SMatthew G. Knepley for (f = 0; f < numFields; ++f) { 63537c927364SMatthew G. Knepley ierr = PetscSectionGetFieldDof(csection, cpoints[p], f, &fdof);CHKERRQ(ierr); 63547c927364SMatthew G. Knepley coffsets[f+1] += fdof; 63557c927364SMatthew G. Knepley } 63567c927364SMatthew G. Knepley numCIndices += dof; 63577c927364SMatthew G. Knepley } 63587c927364SMatthew G. Knepley for (f = 1; f < numFields; ++f) coffsets[f+1] += coffsets[f]; 63597c927364SMatthew G. Knepley /* Row indices */ 63607c927364SMatthew G. Knepley ierr = DMPlexGetCellRefiner_Internal(dmc, &cellRefiner);CHKERRQ(ierr); 63617c927364SMatthew G. Knepley ierr = CellRefinerGetAffineTransforms_Internal(cellRefiner, &numSubcells, NULL, NULL, NULL);CHKERRQ(ierr); 636269291d52SBarry Smith ierr = DMGetWorkArray(dmf, maxFPoints*2*numSubcells, MPIU_INT, &ftotpoints);CHKERRQ(ierr); 63637c927364SMatthew G. Knepley for (r = 0, q = 0; r < numSubcells; ++r) { 63647c927364SMatthew G. Knepley /* TODO Map from coarse to fine cells */ 63657c927364SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dmf, point*numSubcells + r, PETSC_TRUE, &numFPoints, &fpoints);CHKERRQ(ierr); 63667c927364SMatthew G. Knepley /* Compress out points not in the section */ 63677c927364SMatthew G. Knepley ierr = PetscSectionGetChart(fsection, &pStart, &pEnd);CHKERRQ(ierr); 63687c927364SMatthew G. Knepley for (p = 0; p < numFPoints*2; p += 2) { 63697c927364SMatthew G. Knepley if ((fpoints[p] >= pStart) && (fpoints[p] < pEnd)) { 63707c927364SMatthew G. Knepley ierr = PetscSectionGetDof(fsection, fpoints[p], &dof);CHKERRQ(ierr); 63717c927364SMatthew G. Knepley if (!dof) continue; 63727c927364SMatthew G. Knepley for (s = 0; s < q; ++s) if (fpoints[p] == ftotpoints[s*2]) break; 63737c927364SMatthew G. Knepley if (s < q) continue; 63747c927364SMatthew G. Knepley ftotpoints[q*2] = fpoints[p]; 63757c927364SMatthew G. Knepley ftotpoints[q*2+1] = fpoints[p+1]; 63767c927364SMatthew G. Knepley ++q; 63777c927364SMatthew G. Knepley } 63787c927364SMatthew G. Knepley } 63797c927364SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dmf, point, PETSC_TRUE, &numFPoints, &fpoints);CHKERRQ(ierr); 63807c927364SMatthew G. Knepley } 63817c927364SMatthew G. Knepley numFPoints = q; 63827c927364SMatthew G. Knepley for (p = 0, numFIndices = 0; p < numFPoints*2; p += 2) { 63837c927364SMatthew G. Knepley PetscInt fdof; 63847c927364SMatthew G. Knepley 63857c927364SMatthew G. Knepley ierr = PetscSectionGetDof(fsection, ftotpoints[p], &dof);CHKERRQ(ierr); 63867c927364SMatthew G. Knepley if (!dof) continue; 63877c927364SMatthew G. Knepley for (f = 0; f < numFields; ++f) { 63887c927364SMatthew G. Knepley ierr = PetscSectionGetFieldDof(fsection, ftotpoints[p], f, &fdof);CHKERRQ(ierr); 63897c927364SMatthew G. Knepley foffsets[f+1] += fdof; 63907c927364SMatthew G. Knepley } 63917c927364SMatthew G. Knepley numFIndices += dof; 63927c927364SMatthew G. Knepley } 63937c927364SMatthew G. Knepley for (f = 1; f < numFields; ++f) foffsets[f+1] += foffsets[f]; 63947c927364SMatthew G. Knepley 63958ccfff9cSToby Isaac if (numFields && foffsets[numFields] != numFIndices) SETERRQ2(PetscObjectComm((PetscObject)dmf), PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", foffsets[numFields], numFIndices); 63968ccfff9cSToby Isaac if (numFields && coffsets[numFields] != numCIndices) SETERRQ2(PetscObjectComm((PetscObject)dmc), PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", coffsets[numFields], numCIndices); 63977c927364SMatthew G. Knepley if (numFields) { 63984acb8e1eSToby Isaac const PetscInt **permsF[32] = {NULL}; 63994acb8e1eSToby Isaac const PetscInt **permsC[32] = {NULL}; 64004acb8e1eSToby Isaac 64014acb8e1eSToby Isaac for (f = 0; f < numFields; f++) { 64024acb8e1eSToby Isaac ierr = PetscSectionGetFieldPointSyms(fsection,f,numFPoints,ftotpoints,&permsF[f],NULL);CHKERRQ(ierr); 64034acb8e1eSToby Isaac ierr = PetscSectionGetFieldPointSyms(csection,f,numCPoints,cpoints,&permsC[f],NULL);CHKERRQ(ierr); 64047c927364SMatthew G. Knepley } 64054acb8e1eSToby Isaac for (p = 0; p < numFPoints; p++) { 64064acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalFSection, ftotpoints[2*p], &globalOff);CHKERRQ(ierr); 640705586334SMatthew G. Knepley DMPlexGetIndicesPointFields_Internal(fsection, ftotpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, foffsets, PETSC_FALSE, permsF, p, fclperm, findices); 64084acb8e1eSToby Isaac } 64094acb8e1eSToby Isaac for (p = 0; p < numCPoints; p++) { 64104acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalCSection, cpoints[2*p], &globalOff);CHKERRQ(ierr); 641105586334SMatthew G. Knepley DMPlexGetIndicesPointFields_Internal(csection, cpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, coffsets, PETSC_FALSE, permsC, p, cclperm, cindices); 64124acb8e1eSToby Isaac } 64134acb8e1eSToby Isaac for (f = 0; f < numFields; f++) { 64144acb8e1eSToby Isaac ierr = PetscSectionRestoreFieldPointSyms(fsection,f,numFPoints,ftotpoints,&permsF[f],NULL);CHKERRQ(ierr); 64154acb8e1eSToby Isaac ierr = PetscSectionRestoreFieldPointSyms(csection,f,numCPoints,cpoints,&permsC[f],NULL);CHKERRQ(ierr); 64167c927364SMatthew G. Knepley } 64177c927364SMatthew G. Knepley } else { 64184acb8e1eSToby Isaac const PetscInt **permsF = NULL; 64194acb8e1eSToby Isaac const PetscInt **permsC = NULL; 64204acb8e1eSToby Isaac 64214acb8e1eSToby Isaac ierr = PetscSectionGetPointSyms(fsection,numFPoints,ftotpoints,&permsF,NULL);CHKERRQ(ierr); 64224acb8e1eSToby Isaac ierr = PetscSectionGetPointSyms(csection,numCPoints,cpoints,&permsC,NULL);CHKERRQ(ierr); 64234acb8e1eSToby Isaac for (p = 0, off = 0; p < numFPoints; p++) { 64244acb8e1eSToby Isaac const PetscInt *perm = permsF ? permsF[p] : NULL; 64254acb8e1eSToby Isaac 64264acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalFSection, ftotpoints[2*p], &globalOff);CHKERRQ(ierr); 642705586334SMatthew G. Knepley DMPlexGetIndicesPoint_Internal(fsection, ftotpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, perm, fclperm, findices); 64287c927364SMatthew G. Knepley } 64294acb8e1eSToby Isaac for (p = 0, off = 0; p < numCPoints; p++) { 64304acb8e1eSToby Isaac const PetscInt *perm = permsC ? permsC[p] : NULL; 64314acb8e1eSToby Isaac 64324acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalCSection, cpoints[2*p], &globalOff);CHKERRQ(ierr); 643305586334SMatthew G. Knepley DMPlexGetIndicesPoint_Internal(csection, cpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, perm, cclperm, cindices); 64347c927364SMatthew G. Knepley } 64354acb8e1eSToby Isaac ierr = PetscSectionRestorePointSyms(fsection,numFPoints,ftotpoints,&permsF,NULL);CHKERRQ(ierr); 64364acb8e1eSToby Isaac ierr = PetscSectionRestorePointSyms(csection,numCPoints,cpoints,&permsC,NULL);CHKERRQ(ierr); 64377c927364SMatthew G. Knepley } 643869291d52SBarry Smith ierr = DMRestoreWorkArray(dmf, numCPoints*2*4, MPIU_INT, &ftotpoints);CHKERRQ(ierr); 64397c927364SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dmc, point, PETSC_TRUE, &numCPoints, &cpoints);CHKERRQ(ierr); 64407c927364SMatthew G. Knepley PetscFunctionReturn(0); 64417c927364SMatthew G. Knepley } 64427c927364SMatthew G. Knepley 6443f96281f8SMatthew G. Knepley /*@ 6444f96281f8SMatthew G. Knepley DMPlexGetHybridBounds - Get the first mesh point of each dimension which is a hybrid 6445f96281f8SMatthew G. Knepley 6446f96281f8SMatthew G. Knepley Input Parameter: 6447f96281f8SMatthew G. Knepley . dm - The DMPlex object 6448f96281f8SMatthew G. Knepley 6449f96281f8SMatthew G. Knepley Output Parameters: 6450f96281f8SMatthew G. Knepley + cMax - The first hybrid cell 6451dc5a3409SMatthew G. Knepley . fMax - The first hybrid face 6452dc5a3409SMatthew G. Knepley . eMax - The first hybrid edge 6453dc5a3409SMatthew G. Knepley - vMax - The first hybrid vertex 6454f96281f8SMatthew G. Knepley 6455f96281f8SMatthew G. Knepley Level: developer 6456f96281f8SMatthew G. Knepley 6457dc5a3409SMatthew G. Knepley .seealso DMPlexCreateHybridMesh(), DMPlexSetHybridBounds() 6458f96281f8SMatthew G. Knepley @*/ 6459770b213bSMatthew G Knepley PetscErrorCode DMPlexGetHybridBounds(DM dm, PetscInt *cMax, PetscInt *fMax, PetscInt *eMax, PetscInt *vMax) 6460552f7358SJed Brown { 6461552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 6462770b213bSMatthew G Knepley PetscInt dim; 6463770b213bSMatthew G Knepley PetscErrorCode ierr; 6464552f7358SJed Brown 6465552f7358SJed Brown PetscFunctionBegin; 6466552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6467c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 64687d5acc75SStefano Zampini if (dim < 0) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM dimension not yet set"); 6469770b213bSMatthew G Knepley if (cMax) *cMax = mesh->hybridPointMax[dim]; 64707d5acc75SStefano Zampini if (fMax) *fMax = mesh->hybridPointMax[PetscMax(dim-1,0)]; 6471770b213bSMatthew G Knepley if (eMax) *eMax = mesh->hybridPointMax[1]; 6472770b213bSMatthew G Knepley if (vMax) *vMax = mesh->hybridPointMax[0]; 6473552f7358SJed Brown PetscFunctionReturn(0); 6474552f7358SJed Brown } 6475552f7358SJed Brown 6476aeadca18SToby Isaac static PetscErrorCode DMPlexCreateDimStratum(DM dm, DMLabel depthLabel, DMLabel dimLabel, PetscInt d, PetscInt dMax) 64774a3e9fdbSToby Isaac { 64784a3e9fdbSToby Isaac IS is, his; 64797d5acc75SStefano Zampini PetscInt first = 0, stride; 64804a3e9fdbSToby Isaac PetscBool isStride; 64814a3e9fdbSToby Isaac PetscErrorCode ierr; 64824a3e9fdbSToby Isaac 64834a3e9fdbSToby Isaac PetscFunctionBegin; 64844a3e9fdbSToby Isaac ierr = DMLabelGetStratumIS(depthLabel, d, &is);CHKERRQ(ierr); 64854a3e9fdbSToby Isaac ierr = PetscObjectTypeCompare((PetscObject) is, ISSTRIDE, &isStride);CHKERRQ(ierr); 64864a3e9fdbSToby Isaac if (isStride) { 64874a3e9fdbSToby Isaac ierr = ISStrideGetInfo(is, &first, &stride);CHKERRQ(ierr); 64884a3e9fdbSToby Isaac } 64897d5acc75SStefano 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); 64904a3e9fdbSToby Isaac ierr = ISCreateStride(PETSC_COMM_SELF, (dMax - first), first, 1, &his);CHKERRQ(ierr); 6491aeadca18SToby Isaac ierr = DMLabelSetStratumIS(dimLabel, d, his);CHKERRQ(ierr); 64924a3e9fdbSToby Isaac ierr = ISDestroy(&his);CHKERRQ(ierr); 64934a3e9fdbSToby Isaac ierr = ISDestroy(&is);CHKERRQ(ierr); 64944a3e9fdbSToby Isaac PetscFunctionReturn(0); 64954a3e9fdbSToby Isaac } 64964a3e9fdbSToby Isaac 6497dc5a3409SMatthew G. Knepley /*@ 6498dc5a3409SMatthew G. Knepley DMPlexSetHybridBounds - Set the first mesh point of each dimension which is a hybrid 6499dc5a3409SMatthew G. Knepley 6500dc5a3409SMatthew G. Knepley Input Parameters: 6501a2b725a8SWilliam Gropp + dm - The DMPlex object 6502dc5a3409SMatthew G. Knepley . cMax - The first hybrid cell 6503dc5a3409SMatthew G. Knepley . fMax - The first hybrid face 6504dc5a3409SMatthew G. Knepley . eMax - The first hybrid edge 6505dc5a3409SMatthew G. Knepley - vMax - The first hybrid vertex 6506dc5a3409SMatthew G. Knepley 6507dc5a3409SMatthew G. Knepley Level: developer 6508dc5a3409SMatthew G. Knepley 6509dc5a3409SMatthew G. Knepley .seealso DMPlexCreateHybridMesh(), DMPlexGetHybridBounds() 6510dc5a3409SMatthew G. Knepley @*/ 6511770b213bSMatthew G Knepley PetscErrorCode DMPlexSetHybridBounds(DM dm, PetscInt cMax, PetscInt fMax, PetscInt eMax, PetscInt vMax) 6512552f7358SJed Brown { 6513552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 6514770b213bSMatthew G Knepley PetscInt dim; 6515770b213bSMatthew G Knepley PetscErrorCode ierr; 6516552f7358SJed Brown 6517552f7358SJed Brown PetscFunctionBegin; 6518552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6519c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 65207d5acc75SStefano Zampini if (dim < 0) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM dimension not yet set"); 6521770b213bSMatthew G Knepley if (cMax >= 0) mesh->hybridPointMax[dim] = cMax; 65227d5acc75SStefano Zampini if (fMax >= 0) mesh->hybridPointMax[PetscMax(dim-1,0)] = fMax; 6523770b213bSMatthew G Knepley if (eMax >= 0) mesh->hybridPointMax[1] = eMax; 6524770b213bSMatthew G Knepley if (vMax >= 0) mesh->hybridPointMax[0] = vMax; 6525552f7358SJed Brown PetscFunctionReturn(0); 6526552f7358SJed Brown } 6527552f7358SJed Brown 65287cd05799SMatthew G. Knepley /*@C 65297cd05799SMatthew G. Knepley DMPlexGetVTKCellHeight - Returns the height in the DAG used to determine which points are cells (normally 0) 65307cd05799SMatthew G. Knepley 65317cd05799SMatthew G. Knepley Input Parameter: 65327cd05799SMatthew G. Knepley . dm - The DMPlex object 65337cd05799SMatthew G. Knepley 65347cd05799SMatthew G. Knepley Output Parameter: 65357cd05799SMatthew G. Knepley . cellHeight - The height of a cell 65367cd05799SMatthew G. Knepley 65377cd05799SMatthew G. Knepley Level: developer 65387cd05799SMatthew G. Knepley 65397cd05799SMatthew G. Knepley .seealso DMPlexSetVTKCellHeight() 65407cd05799SMatthew G. Knepley @*/ 6541552f7358SJed Brown PetscErrorCode DMPlexGetVTKCellHeight(DM dm, PetscInt *cellHeight) 6542552f7358SJed Brown { 6543552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 6544552f7358SJed Brown 6545552f7358SJed Brown PetscFunctionBegin; 6546552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6547552f7358SJed Brown PetscValidPointer(cellHeight, 2); 6548552f7358SJed Brown *cellHeight = mesh->vtkCellHeight; 6549552f7358SJed Brown PetscFunctionReturn(0); 6550552f7358SJed Brown } 6551552f7358SJed Brown 65527cd05799SMatthew G. Knepley /*@C 65537cd05799SMatthew G. Knepley DMPlexSetVTKCellHeight - Sets the height in the DAG used to determine which points are cells (normally 0) 65547cd05799SMatthew G. Knepley 65557cd05799SMatthew G. Knepley Input Parameters: 65567cd05799SMatthew G. Knepley + dm - The DMPlex object 65577cd05799SMatthew G. Knepley - cellHeight - The height of a cell 65587cd05799SMatthew G. Knepley 65597cd05799SMatthew G. Knepley Level: developer 65607cd05799SMatthew G. Knepley 65617cd05799SMatthew G. Knepley .seealso DMPlexGetVTKCellHeight() 65627cd05799SMatthew G. Knepley @*/ 6563552f7358SJed Brown PetscErrorCode DMPlexSetVTKCellHeight(DM dm, PetscInt cellHeight) 6564552f7358SJed Brown { 6565552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 6566552f7358SJed Brown 6567552f7358SJed Brown PetscFunctionBegin; 6568552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6569552f7358SJed Brown mesh->vtkCellHeight = cellHeight; 6570552f7358SJed Brown PetscFunctionReturn(0); 6571552f7358SJed Brown } 6572552f7358SJed Brown 6573e6139122SMatthew G. Knepley /*@ 6574e6139122SMatthew G. Knepley DMPlexGetGhostCellStratum - Get the range of cells which are used to enforce FV boundary conditions 6575e6139122SMatthew G. Knepley 6576e6139122SMatthew G. Knepley Input Parameter: 6577e6139122SMatthew G. Knepley . dm - The DMPlex object 6578e6139122SMatthew G. Knepley 6579e6139122SMatthew G. Knepley Output Parameters: 65802a9f31c0SMatthew G. Knepley + gcStart - The first ghost cell, or NULL 65812a9f31c0SMatthew G. Knepley - gcEnd - The upper bound on ghost cells, or NULL 6582e6139122SMatthew G. Knepley 65832a9f31c0SMatthew G. Knepley Level: advanced 6584e6139122SMatthew G. Knepley 6585e6139122SMatthew G. Knepley .seealso DMPlexConstructGhostCells(), DMPlexSetGhostCellStratum(), DMPlexGetHybridBounds() 6586e6139122SMatthew G. Knepley @*/ 6587e6139122SMatthew G. Knepley PetscErrorCode DMPlexGetGhostCellStratum(DM dm, PetscInt *gcStart, PetscInt *gcEnd) 6588e6139122SMatthew G. Knepley { 6589e6139122SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 6590e6139122SMatthew G. Knepley PetscInt dim; 6591e6139122SMatthew G. Knepley PetscErrorCode ierr; 6592e6139122SMatthew G. Knepley 6593e6139122SMatthew G. Knepley PetscFunctionBegin; 6594e6139122SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6595e6139122SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 6596e6139122SMatthew G. Knepley if (dim < 0) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM dimension not yet set"); 6597e6139122SMatthew G. Knepley if (gcStart) {PetscValidIntPointer(gcStart, 2); *gcStart = mesh->ghostCellStart;} 6598e6139122SMatthew G. Knepley if (gcEnd) { 6599e6139122SMatthew G. Knepley PetscValidIntPointer(gcEnd, 3); 6600e6139122SMatthew G. Knepley if (mesh->ghostCellStart >= 0) {ierr = DMPlexGetHeightStratum(dm, 0, NULL, gcEnd);CHKERRQ(ierr);} 6601e6139122SMatthew G. Knepley else {*gcEnd = -1;} 6602e6139122SMatthew G. Knepley } 6603e6139122SMatthew G. Knepley PetscFunctionReturn(0); 6604e6139122SMatthew G. Knepley } 6605e6139122SMatthew G. Knepley 6606e6139122SMatthew G. Knepley /*@ 6607e6139122SMatthew G. Knepley DMPlexSetGhostCellStratum - Set the range of cells which are used to enforce FV boundary conditions 6608e6139122SMatthew G. Knepley 6609e6139122SMatthew G. Knepley Input Parameters: 6610e6139122SMatthew G. Knepley + dm - The DMPlex object 66112a9f31c0SMatthew G. Knepley . gcStart - The first ghost cell, or PETSC_DETERMINE 66122a9f31c0SMatthew G. Knepley - gcEnd - The upper bound on ghost cells, or PETSC_DETERMINE 6613e6139122SMatthew G. Knepley 66142a9f31c0SMatthew G. Knepley Level: advanced 66152a9f31c0SMatthew G. Knepley 66162a9f31c0SMatthew G. Knepley Note: This is not usually called directly by a user. 6617e6139122SMatthew G. Knepley 6618e6139122SMatthew G. Knepley .seealso DMPlexConstructGhostCells(), DMPlexGetGhostCellStratum(), DMPlexSetHybridBounds() 6619e6139122SMatthew G. Knepley @*/ 6620e6139122SMatthew G. Knepley PetscErrorCode DMPlexSetGhostCellStratum(DM dm, PetscInt gcStart, PetscInt gcEnd) 6621e6139122SMatthew G. Knepley { 6622e6139122SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 6623e6139122SMatthew G. Knepley PetscInt dim; 6624e6139122SMatthew G. Knepley PetscErrorCode ierr; 6625e6139122SMatthew G. Knepley 6626e6139122SMatthew G. Knepley PetscFunctionBegin; 6627e6139122SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6628e6139122SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 6629e6139122SMatthew G. Knepley if (dim < 0) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "DM dimension not yet set"); 6630e6139122SMatthew G. Knepley mesh->ghostCellStart = gcStart; 6631e6139122SMatthew G. Knepley if (gcEnd >= 0) { 6632e6139122SMatthew G. Knepley PetscInt cEnd; 6633e6139122SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, NULL, &cEnd);CHKERRQ(ierr); 6634e6139122SMatthew G. Knepley if (gcEnd != cEnd) SETERRQ2(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Ghost cells must appear at the end of the cell range, but gcEnd %D is not equal to cEnd %D", gcEnd, cEnd); 6635e6139122SMatthew G. Knepley } 6636e6139122SMatthew G. Knepley PetscFunctionReturn(0); 6637e6139122SMatthew G. Knepley } 6638e6139122SMatthew G. Knepley 6639e6139122SMatthew G. Knepley /*@ 6640e6139122SMatthew G. Knepley DMPlexGetInteriorCellStratum - Get the range of cells which are neither hybrid nor ghost FV cells 6641e6139122SMatthew G. Knepley 6642e6139122SMatthew G. Knepley Input Parameter: 6643e6139122SMatthew G. Knepley . dm - The DMPlex object 6644e6139122SMatthew G. Knepley 6645e6139122SMatthew G. Knepley Output Parameters: 6646e6139122SMatthew G. Knepley + cStartInterior - The first ghost cell 6647e6139122SMatthew G. Knepley - cEndInterior - The upper bound on ghost cells 6648e6139122SMatthew G. Knepley 6649e6139122SMatthew G. Knepley Level: developer 6650e6139122SMatthew G. Knepley 6651e6139122SMatthew G. Knepley .seealso DMPlexConstructGhostCells(), DMPlexSetGhostCellStratum(), DMPlexGetHybridBounds() 6652e6139122SMatthew G. Knepley @*/ 6653e6139122SMatthew G. Knepley PetscErrorCode DMPlexGetInteriorCellStratum(DM dm, PetscInt *cStartInterior, PetscInt *cEndInterior) 6654e6139122SMatthew G. Knepley { 6655e6139122SMatthew G. Knepley PetscInt gcEnd, cMax; 6656e6139122SMatthew G. Knepley PetscErrorCode ierr; 6657e6139122SMatthew G. Knepley 6658e6139122SMatthew G. Knepley PetscFunctionBegin; 6659e6139122SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, cStartInterior, cEndInterior);CHKERRQ(ierr); 6660e6139122SMatthew G. Knepley ierr = DMPlexGetGhostCellStratum(dm, &gcEnd, NULL);CHKERRQ(ierr); 6661e6139122SMatthew G. Knepley *cEndInterior = gcEnd < 0 ? *cEndInterior : gcEnd; 6662e6139122SMatthew G. Knepley ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr); 6663e6139122SMatthew G. Knepley *cEndInterior = cMax < 0 ? *cEndInterior : cMax; 6664e6139122SMatthew G. Knepley PetscFunctionReturn(0); 6665e6139122SMatthew G. Knepley } 6666e6139122SMatthew G. Knepley 6667552f7358SJed Brown /* We can easily have a form that takes an IS instead */ 666850ad7711SMatthew G. Knepley PetscErrorCode DMPlexCreateNumbering_Internal(DM dm, PetscInt pStart, PetscInt pEnd, PetscInt shift, PetscInt *globalSize, PetscSF sf, IS *numbering) 6669552f7358SJed Brown { 6670552f7358SJed Brown PetscSection section, globalSection; 6671552f7358SJed Brown PetscInt *numbers, p; 6672552f7358SJed Brown PetscErrorCode ierr; 6673552f7358SJed Brown 6674552f7358SJed Brown PetscFunctionBegin; 667582f516ccSBarry Smith ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), §ion);CHKERRQ(ierr); 6676552f7358SJed Brown ierr = PetscSectionSetChart(section, pStart, pEnd);CHKERRQ(ierr); 6677552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 6678552f7358SJed Brown ierr = PetscSectionSetDof(section, p, 1);CHKERRQ(ierr); 6679552f7358SJed Brown } 6680552f7358SJed Brown ierr = PetscSectionSetUp(section);CHKERRQ(ierr); 668115b58121SMatthew G. Knepley ierr = PetscSectionCreateGlobalSection(section, sf, PETSC_FALSE, PETSC_FALSE, &globalSection);CHKERRQ(ierr); 6682854ce69bSBarry Smith ierr = PetscMalloc1(pEnd - pStart, &numbers);CHKERRQ(ierr); 6683552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 6684552f7358SJed Brown ierr = PetscSectionGetOffset(globalSection, p, &numbers[p-pStart]);CHKERRQ(ierr); 6685ef48cebcSMatthew G. Knepley if (numbers[p-pStart] < 0) numbers[p-pStart] -= shift; 6686ef48cebcSMatthew G. Knepley else numbers[p-pStart] += shift; 6687552f7358SJed Brown } 668882f516ccSBarry Smith ierr = ISCreateGeneral(PetscObjectComm((PetscObject) dm), pEnd - pStart, numbers, PETSC_OWN_POINTER, numbering);CHKERRQ(ierr); 6689ef48cebcSMatthew G. Knepley if (globalSize) { 6690ef48cebcSMatthew G. Knepley PetscLayout layout; 6691ef48cebcSMatthew G. Knepley ierr = PetscSectionGetPointLayout(PetscObjectComm((PetscObject) dm), globalSection, &layout);CHKERRQ(ierr); 6692ef48cebcSMatthew G. Knepley ierr = PetscLayoutGetSize(layout, globalSize);CHKERRQ(ierr); 6693ef48cebcSMatthew G. Knepley ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr); 6694ef48cebcSMatthew G. Knepley } 6695552f7358SJed Brown ierr = PetscSectionDestroy(§ion);CHKERRQ(ierr); 6696552f7358SJed Brown ierr = PetscSectionDestroy(&globalSection);CHKERRQ(ierr); 6697552f7358SJed Brown PetscFunctionReturn(0); 6698552f7358SJed Brown } 6699552f7358SJed Brown 670081ed3555SMatthew G. Knepley PetscErrorCode DMPlexCreateCellNumbering_Internal(DM dm, PetscBool includeHybrid, IS *globalCellNumbers) 6701552f7358SJed Brown { 6702552f7358SJed Brown PetscInt cellHeight, cStart, cEnd, cMax; 6703552f7358SJed Brown PetscErrorCode ierr; 6704552f7358SJed Brown 6705552f7358SJed Brown PetscFunctionBegin; 6706552f7358SJed Brown ierr = DMPlexGetVTKCellHeight(dm, &cellHeight);CHKERRQ(ierr); 6707552f7358SJed Brown ierr = DMPlexGetHeightStratum(dm, cellHeight, &cStart, &cEnd);CHKERRQ(ierr); 67080298fd71SBarry Smith ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr); 670981ed3555SMatthew G. Knepley if (cMax >= 0 && !includeHybrid) cEnd = PetscMin(cEnd, cMax); 671050ad7711SMatthew G. Knepley ierr = DMPlexCreateNumbering_Internal(dm, cStart, cEnd, 0, NULL, dm->sf, globalCellNumbers);CHKERRQ(ierr); 671181ed3555SMatthew G. Knepley PetscFunctionReturn(0); 6712552f7358SJed Brown } 671381ed3555SMatthew G. Knepley 67148dab3259SMatthew G. Knepley /*@ 67157cd05799SMatthew G. Knepley DMPlexGetCellNumbering - Get a global cell numbering for all cells on this process 67167cd05799SMatthew G. Knepley 67177cd05799SMatthew G. Knepley Input Parameter: 67187cd05799SMatthew G. Knepley . dm - The DMPlex object 67197cd05799SMatthew G. Knepley 67207cd05799SMatthew G. Knepley Output Parameter: 67217cd05799SMatthew G. Knepley . globalCellNumbers - Global cell numbers for all cells on this process 67227cd05799SMatthew G. Knepley 67237cd05799SMatthew G. Knepley Level: developer 67247cd05799SMatthew G. Knepley 67257cd05799SMatthew G. Knepley .seealso DMPlexGetVertexNumbering() 67267cd05799SMatthew G. Knepley @*/ 672781ed3555SMatthew G. Knepley PetscErrorCode DMPlexGetCellNumbering(DM dm, IS *globalCellNumbers) 672881ed3555SMatthew G. Knepley { 672981ed3555SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 673081ed3555SMatthew G. Knepley PetscErrorCode ierr; 673181ed3555SMatthew G. Knepley 673281ed3555SMatthew G. Knepley PetscFunctionBegin; 673381ed3555SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 673481ed3555SMatthew G. Knepley if (!mesh->globalCellNumbers) {ierr = DMPlexCreateCellNumbering_Internal(dm, PETSC_FALSE, &mesh->globalCellNumbers);CHKERRQ(ierr);} 6735552f7358SJed Brown *globalCellNumbers = mesh->globalCellNumbers; 6736552f7358SJed Brown PetscFunctionReturn(0); 6737552f7358SJed Brown } 6738552f7358SJed Brown 673981ed3555SMatthew G. Knepley PetscErrorCode DMPlexCreateVertexNumbering_Internal(DM dm, PetscBool includeHybrid, IS *globalVertexNumbers) 674081ed3555SMatthew G. Knepley { 674181ed3555SMatthew G. Knepley PetscInt vStart, vEnd, vMax; 674281ed3555SMatthew G. Knepley PetscErrorCode ierr; 674381ed3555SMatthew G. Knepley 674481ed3555SMatthew G. Knepley PetscFunctionBegin; 674581ed3555SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 674681ed3555SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 674781ed3555SMatthew G. Knepley ierr = DMPlexGetHybridBounds(dm, NULL, NULL, NULL, &vMax);CHKERRQ(ierr); 674881ed3555SMatthew G. Knepley if (vMax >= 0 && !includeHybrid) vEnd = PetscMin(vEnd, vMax); 674950ad7711SMatthew G. Knepley ierr = DMPlexCreateNumbering_Internal(dm, vStart, vEnd, 0, NULL, dm->sf, globalVertexNumbers);CHKERRQ(ierr); 675081ed3555SMatthew G. Knepley PetscFunctionReturn(0); 675181ed3555SMatthew G. Knepley } 675281ed3555SMatthew G. Knepley 67538dab3259SMatthew G. Knepley /*@ 67546aa51ba9SJacob Faibussowitsch DMPlexGetVertexNumbering - Get a global vertex numbering for all vertices on this process 67557cd05799SMatthew G. Knepley 67567cd05799SMatthew G. Knepley Input Parameter: 67577cd05799SMatthew G. Knepley . dm - The DMPlex object 67587cd05799SMatthew G. Knepley 67597cd05799SMatthew G. Knepley Output Parameter: 67607cd05799SMatthew G. Knepley . globalVertexNumbers - Global vertex numbers for all vertices on this process 67617cd05799SMatthew G. Knepley 67627cd05799SMatthew G. Knepley Level: developer 67637cd05799SMatthew G. Knepley 67647cd05799SMatthew G. Knepley .seealso DMPlexGetCellNumbering() 67657cd05799SMatthew G. Knepley @*/ 6766552f7358SJed Brown PetscErrorCode DMPlexGetVertexNumbering(DM dm, IS *globalVertexNumbers) 6767552f7358SJed Brown { 6768552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 6769552f7358SJed Brown PetscErrorCode ierr; 6770552f7358SJed Brown 6771552f7358SJed Brown PetscFunctionBegin; 6772552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 677381ed3555SMatthew G. Knepley if (!mesh->globalVertexNumbers) {ierr = DMPlexCreateVertexNumbering_Internal(dm, PETSC_FALSE, &mesh->globalVertexNumbers);CHKERRQ(ierr);} 6774552f7358SJed Brown *globalVertexNumbers = mesh->globalVertexNumbers; 6775552f7358SJed Brown PetscFunctionReturn(0); 6776552f7358SJed Brown } 6777552f7358SJed Brown 67788dab3259SMatthew G. Knepley /*@ 67797cd05799SMatthew G. Knepley DMPlexCreatePointNumbering - Create a global numbering for all points on this process 67807cd05799SMatthew G. Knepley 67817cd05799SMatthew G. Knepley Input Parameter: 67827cd05799SMatthew G. Knepley . dm - The DMPlex object 67837cd05799SMatthew G. Knepley 67847cd05799SMatthew G. Knepley Output Parameter: 67857cd05799SMatthew G. Knepley . globalPointNumbers - Global numbers for all points on this process 67867cd05799SMatthew G. Knepley 67877cd05799SMatthew G. Knepley Level: developer 67887cd05799SMatthew G. Knepley 67897cd05799SMatthew G. Knepley .seealso DMPlexGetCellNumbering() 67907cd05799SMatthew G. Knepley @*/ 6791ef48cebcSMatthew G. Knepley PetscErrorCode DMPlexCreatePointNumbering(DM dm, IS *globalPointNumbers) 6792ef48cebcSMatthew G. Knepley { 6793ef48cebcSMatthew G. Knepley IS nums[4]; 6794862913ffSStefano Zampini PetscInt depths[4], gdepths[4], starts[4]; 6795ef48cebcSMatthew G. Knepley PetscInt depth, d, shift = 0; 6796ef48cebcSMatthew G. Knepley PetscErrorCode ierr; 6797ef48cebcSMatthew G. Knepley 6798ef48cebcSMatthew G. Knepley PetscFunctionBegin; 6799ef48cebcSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6800ef48cebcSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 68018abc87a0SMichael Lange /* For unstratified meshes use dim instead of depth */ 68028abc87a0SMichael Lange if (depth < 0) {ierr = DMGetDimension(dm, &depth);CHKERRQ(ierr);} 6803862913ffSStefano Zampini for (d = 0; d <= depth; ++d) { 6804862913ffSStefano Zampini PetscInt end; 6805862913ffSStefano Zampini 6806862913ffSStefano Zampini depths[d] = depth-d; 6807862913ffSStefano Zampini ierr = DMPlexGetDepthStratum(dm, depths[d], &starts[d], &end);CHKERRQ(ierr); 6808862913ffSStefano Zampini if (!(starts[d]-end)) { starts[d] = depths[d] = -1; } 6809862913ffSStefano Zampini } 6810862913ffSStefano Zampini ierr = PetscSortIntWithArray(depth+1, starts, depths);CHKERRQ(ierr); 6811862913ffSStefano Zampini ierr = MPIU_Allreduce(depths, gdepths, depth+1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject) dm));CHKERRQ(ierr); 6812862913ffSStefano Zampini for (d = 0; d <= depth; ++d) { 6813862913ffSStefano 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]); 6814862913ffSStefano Zampini } 6815ef48cebcSMatthew G. Knepley for (d = 0; d <= depth; ++d) { 6816ef48cebcSMatthew G. Knepley PetscInt pStart, pEnd, gsize; 6817ef48cebcSMatthew G. Knepley 6818862913ffSStefano Zampini ierr = DMPlexGetDepthStratum(dm, gdepths[d], &pStart, &pEnd);CHKERRQ(ierr); 681950ad7711SMatthew G. Knepley ierr = DMPlexCreateNumbering_Internal(dm, pStart, pEnd, shift, &gsize, dm->sf, &nums[d]);CHKERRQ(ierr); 6820ef48cebcSMatthew G. Knepley shift += gsize; 6821ef48cebcSMatthew G. Knepley } 6822302440fdSBarry Smith ierr = ISConcatenate(PetscObjectComm((PetscObject) dm), depth+1, nums, globalPointNumbers);CHKERRQ(ierr); 6823ef48cebcSMatthew G. Knepley for (d = 0; d <= depth; ++d) {ierr = ISDestroy(&nums[d]);CHKERRQ(ierr);} 6824ef48cebcSMatthew G. Knepley PetscFunctionReturn(0); 6825ef48cebcSMatthew G. Knepley } 6826ef48cebcSMatthew G. Knepley 682708a22f4bSMatthew G. Knepley 682808a22f4bSMatthew G. Knepley /*@ 682908a22f4bSMatthew G. Knepley DMPlexCreateRankField - Create a cell field whose value is the rank of the owner 683008a22f4bSMatthew G. Knepley 683108a22f4bSMatthew G. Knepley Input Parameter: 683208a22f4bSMatthew G. Knepley . dm - The DMPlex object 683308a22f4bSMatthew G. Knepley 683408a22f4bSMatthew G. Knepley Output Parameter: 683508a22f4bSMatthew G. Knepley . ranks - The rank field 683608a22f4bSMatthew G. Knepley 683708a22f4bSMatthew G. Knepley Options Database Keys: 683808a22f4bSMatthew G. Knepley . -dm_partition_view - Adds the rank field into the DM output from -dm_view using the same viewer 683908a22f4bSMatthew G. Knepley 684008a22f4bSMatthew G. Knepley Level: intermediate 684108a22f4bSMatthew G. Knepley 684208a22f4bSMatthew G. Knepley .seealso: DMView() 684308a22f4bSMatthew G. Knepley @*/ 684408a22f4bSMatthew G. Knepley PetscErrorCode DMPlexCreateRankField(DM dm, Vec *ranks) 684508a22f4bSMatthew G. Knepley { 684608a22f4bSMatthew G. Knepley DM rdm; 684708a22f4bSMatthew G. Knepley PetscFE fe; 684808a22f4bSMatthew G. Knepley PetscScalar *r; 684908a22f4bSMatthew G. Knepley PetscMPIInt rank; 685008a22f4bSMatthew G. Knepley PetscInt dim, cStart, cEnd, c; 685108a22f4bSMatthew G. Knepley PetscErrorCode ierr; 685208a22f4bSMatthew G. Knepley 685308a22f4bSMatthew G. Knepley PetscFunctionBeginUser; 6854f95ace6aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6855f95ace6aSMatthew G. Knepley PetscValidPointer(ranks, 2); 685608a22f4bSMatthew G. Knepley ierr = MPI_Comm_rank(PetscObjectComm((PetscObject) dm), &rank);CHKERRQ(ierr); 685708a22f4bSMatthew G. Knepley ierr = DMClone(dm, &rdm);CHKERRQ(ierr); 685808a22f4bSMatthew G. Knepley ierr = DMGetDimension(rdm, &dim);CHKERRQ(ierr); 6859f95ace6aSMatthew G. Knepley ierr = PetscFECreateDefault(PetscObjectComm((PetscObject) rdm), dim, 1, PETSC_TRUE, "PETSc___rank_", -1, &fe);CHKERRQ(ierr); 686008a22f4bSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) fe, "rank");CHKERRQ(ierr); 6861e5e52638SMatthew G. Knepley ierr = DMSetField(rdm, 0, NULL, (PetscObject) fe);CHKERRQ(ierr); 686208a22f4bSMatthew G. Knepley ierr = PetscFEDestroy(&fe);CHKERRQ(ierr); 6863e5e52638SMatthew G. Knepley ierr = DMCreateDS(rdm);CHKERRQ(ierr); 686408a22f4bSMatthew G. Knepley ierr = DMPlexGetHeightStratum(rdm, 0, &cStart, &cEnd);CHKERRQ(ierr); 686508a22f4bSMatthew G. Knepley ierr = DMCreateGlobalVector(rdm, ranks);CHKERRQ(ierr); 686608a22f4bSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) *ranks, "partition");CHKERRQ(ierr); 686708a22f4bSMatthew G. Knepley ierr = VecGetArray(*ranks, &r);CHKERRQ(ierr); 686808a22f4bSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 686908a22f4bSMatthew G. Knepley PetscScalar *lr; 687008a22f4bSMatthew G. Knepley 687108a22f4bSMatthew G. Knepley ierr = DMPlexPointGlobalRef(rdm, c, r, &lr);CHKERRQ(ierr); 687208a22f4bSMatthew G. Knepley *lr = rank; 687308a22f4bSMatthew G. Knepley } 687408a22f4bSMatthew G. Knepley ierr = VecRestoreArray(*ranks, &r);CHKERRQ(ierr); 687508a22f4bSMatthew G. Knepley ierr = DMDestroy(&rdm);CHKERRQ(ierr); 687608a22f4bSMatthew G. Knepley PetscFunctionReturn(0); 687708a22f4bSMatthew G. Knepley } 687808a22f4bSMatthew G. Knepley 6879ca8062c8SMatthew G. Knepley /*@ 688018e14f0cSMatthew G. Knepley DMPlexCreateLabelField - Create a cell field whose value is the label value for that cell 688118e14f0cSMatthew G. Knepley 688218e14f0cSMatthew G. Knepley Input Parameters: 688318e14f0cSMatthew G. Knepley + dm - The DMPlex 688418e14f0cSMatthew G. Knepley - label - The DMLabel 688518e14f0cSMatthew G. Knepley 688618e14f0cSMatthew G. Knepley Output Parameter: 688718e14f0cSMatthew G. Knepley . val - The label value field 688818e14f0cSMatthew G. Knepley 688918e14f0cSMatthew G. Knepley Options Database Keys: 689018e14f0cSMatthew G. Knepley . -dm_label_view - Adds the label value field into the DM output from -dm_view using the same viewer 689118e14f0cSMatthew G. Knepley 689218e14f0cSMatthew G. Knepley Level: intermediate 689318e14f0cSMatthew G. Knepley 689418e14f0cSMatthew G. Knepley .seealso: DMView() 689518e14f0cSMatthew G. Knepley @*/ 689618e14f0cSMatthew G. Knepley PetscErrorCode DMPlexCreateLabelField(DM dm, DMLabel label, Vec *val) 689718e14f0cSMatthew G. Knepley { 689818e14f0cSMatthew G. Knepley DM rdm; 689918e14f0cSMatthew G. Knepley PetscFE fe; 690018e14f0cSMatthew G. Knepley PetscScalar *v; 690118e14f0cSMatthew G. Knepley PetscInt dim, cStart, cEnd, c; 690218e14f0cSMatthew G. Knepley PetscErrorCode ierr; 690318e14f0cSMatthew G. Knepley 690418e14f0cSMatthew G. Knepley PetscFunctionBeginUser; 690518e14f0cSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 690618e14f0cSMatthew G. Knepley PetscValidPointer(label, 2); 690718e14f0cSMatthew G. Knepley PetscValidPointer(val, 3); 690818e14f0cSMatthew G. Knepley ierr = DMClone(dm, &rdm);CHKERRQ(ierr); 690918e14f0cSMatthew G. Knepley ierr = DMGetDimension(rdm, &dim);CHKERRQ(ierr); 691018e14f0cSMatthew G. Knepley ierr = PetscFECreateDefault(PetscObjectComm((PetscObject) rdm), dim, 1, PETSC_TRUE, "PETSc___label_value_", -1, &fe);CHKERRQ(ierr); 691118e14f0cSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) fe, "label_value");CHKERRQ(ierr); 6912e5e52638SMatthew G. Knepley ierr = DMSetField(rdm, 0, NULL, (PetscObject) fe);CHKERRQ(ierr); 691318e14f0cSMatthew G. Knepley ierr = PetscFEDestroy(&fe);CHKERRQ(ierr); 6914e5e52638SMatthew G. Knepley ierr = DMCreateDS(rdm);CHKERRQ(ierr); 691518e14f0cSMatthew G. Knepley ierr = DMPlexGetHeightStratum(rdm, 0, &cStart, &cEnd);CHKERRQ(ierr); 691618e14f0cSMatthew G. Knepley ierr = DMCreateGlobalVector(rdm, val);CHKERRQ(ierr); 6917effbd7cbSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) *val, "label_value");CHKERRQ(ierr); 691818e14f0cSMatthew G. Knepley ierr = VecGetArray(*val, &v);CHKERRQ(ierr); 691918e14f0cSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 692018e14f0cSMatthew G. Knepley PetscScalar *lv; 692118e14f0cSMatthew G. Knepley PetscInt cval; 692218e14f0cSMatthew G. Knepley 692318e14f0cSMatthew G. Knepley ierr = DMPlexPointGlobalRef(rdm, c, v, &lv);CHKERRQ(ierr); 692418e14f0cSMatthew G. Knepley ierr = DMLabelGetValue(label, c, &cval);CHKERRQ(ierr); 692518e14f0cSMatthew G. Knepley *lv = cval; 692618e14f0cSMatthew G. Knepley } 692718e14f0cSMatthew G. Knepley ierr = VecRestoreArray(*val, &v);CHKERRQ(ierr); 692818e14f0cSMatthew G. Knepley ierr = DMDestroy(&rdm);CHKERRQ(ierr); 692918e14f0cSMatthew G. Knepley PetscFunctionReturn(0); 693018e14f0cSMatthew G. Knepley } 693118e14f0cSMatthew G. Knepley 693218e14f0cSMatthew G. Knepley /*@ 6933ca8062c8SMatthew G. Knepley DMPlexCheckSymmetry - Check that the adjacency information in the mesh is symmetric. 6934ca8062c8SMatthew G. Knepley 693569916449SMatthew G. Knepley Input Parameter: 693669916449SMatthew G. Knepley . dm - The DMPlex object 6937ca8062c8SMatthew G. Knepley 6938ca8062c8SMatthew G. Knepley Note: This is a useful diagnostic when creating meshes programmatically. 6939ca8062c8SMatthew G. Knepley 6940ca8062c8SMatthew G. Knepley Level: developer 6941ca8062c8SMatthew G. Knepley 69427d5acc75SStefano Zampini .seealso: DMCreate(), DMPlexCheckSkeleton(), DMPlexCheckFaces() 6943ca8062c8SMatthew G. Knepley @*/ 6944ca8062c8SMatthew G. Knepley PetscErrorCode DMPlexCheckSymmetry(DM dm) 6945ca8062c8SMatthew G. Knepley { 6946ca8062c8SMatthew G. Knepley PetscSection coneSection, supportSection; 6947ca8062c8SMatthew G. Knepley const PetscInt *cone, *support; 6948ca8062c8SMatthew G. Knepley PetscInt coneSize, c, supportSize, s; 694957beb4faSStefano Zampini PetscInt pStart, pEnd, p, pp, csize, ssize; 695057beb4faSStefano Zampini PetscBool storagecheck = PETSC_TRUE; 6951ca8062c8SMatthew G. Knepley PetscErrorCode ierr; 6952ca8062c8SMatthew G. Knepley 6953ca8062c8SMatthew G. Knepley PetscFunctionBegin; 6954ca8062c8SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6955ca8062c8SMatthew G. Knepley ierr = DMPlexGetConeSection(dm, &coneSection);CHKERRQ(ierr); 6956ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupportSection(dm, &supportSection);CHKERRQ(ierr); 6957ca8062c8SMatthew G. Knepley /* Check that point p is found in the support of its cone points, and vice versa */ 6958ca8062c8SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 6959ca8062c8SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 6960ca8062c8SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, p, &coneSize);CHKERRQ(ierr); 6961ca8062c8SMatthew G. Knepley ierr = DMPlexGetCone(dm, p, &cone);CHKERRQ(ierr); 6962ca8062c8SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 696342e66dfaSMatthew G. Knepley PetscBool dup = PETSC_FALSE; 696442e66dfaSMatthew G. Knepley PetscInt d; 696542e66dfaSMatthew G. Knepley for (d = c-1; d >= 0; --d) { 696642e66dfaSMatthew G. Knepley if (cone[c] == cone[d]) {dup = PETSC_TRUE; break;} 696742e66dfaSMatthew G. Knepley } 6968ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, cone[c], &supportSize);CHKERRQ(ierr); 6969ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupport(dm, cone[c], &support);CHKERRQ(ierr); 6970ca8062c8SMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 6971ca8062c8SMatthew G. Knepley if (support[s] == p) break; 6972ca8062c8SMatthew G. Knepley } 697342e66dfaSMatthew G. Knepley if ((s >= supportSize) || (dup && (support[s+1] != p))) { 69748ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "p: %D cone: ", p);CHKERRQ(ierr); 6975ca8062c8SMatthew G. Knepley for (s = 0; s < coneSize; ++s) { 69768ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "%D, ", cone[s]);CHKERRQ(ierr); 6977ca8062c8SMatthew G. Knepley } 6978302440fdSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 69798ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "p: %D support: ", cone[c]);CHKERRQ(ierr); 6980ca8062c8SMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 69818ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "%D, ", support[s]);CHKERRQ(ierr); 6982ca8062c8SMatthew G. Knepley } 6983302440fdSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 69848ccfff9cSToby 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]); 69858ccfff9cSToby Isaac else SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D not found in support of cone point %D", p, cone[c]); 6986ca8062c8SMatthew G. Knepley } 698742e66dfaSMatthew G. Knepley } 698857beb4faSStefano Zampini ierr = DMPlexGetTreeParent(dm, p, &pp, NULL);CHKERRQ(ierr); 698957beb4faSStefano Zampini if (p != pp) { storagecheck = PETSC_FALSE; continue; } 6990ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, p, &supportSize);CHKERRQ(ierr); 6991ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupport(dm, p, &support);CHKERRQ(ierr); 6992ca8062c8SMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 6993ca8062c8SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6994ca8062c8SMatthew G. Knepley ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6995ca8062c8SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 699657beb4faSStefano Zampini ierr = DMPlexGetTreeParent(dm, cone[c], &pp, NULL);CHKERRQ(ierr); 699757beb4faSStefano Zampini if (cone[c] != pp) { c = 0; break; } 6998ca8062c8SMatthew G. Knepley if (cone[c] == p) break; 6999ca8062c8SMatthew G. Knepley } 7000ca8062c8SMatthew G. Knepley if (c >= coneSize) { 70018ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "p: %D support: ", p);CHKERRQ(ierr); 7002ca8062c8SMatthew G. Knepley for (c = 0; c < supportSize; ++c) { 70038ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "%D, ", support[c]);CHKERRQ(ierr); 7004ca8062c8SMatthew G. Knepley } 7005302440fdSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 70068ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "p: %D cone: ", support[s]);CHKERRQ(ierr); 7007ca8062c8SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 70088ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "%D, ", cone[c]);CHKERRQ(ierr); 7009ca8062c8SMatthew G. Knepley } 7010302440fdSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 70118ccfff9cSToby Isaac SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D not found in cone of support point %D", p, support[s]); 7012ca8062c8SMatthew G. Knepley } 7013ca8062c8SMatthew G. Knepley } 7014ca8062c8SMatthew G. Knepley } 701557beb4faSStefano Zampini if (storagecheck) { 7016ca8062c8SMatthew G. Knepley ierr = PetscSectionGetStorageSize(coneSection, &csize);CHKERRQ(ierr); 7017ca8062c8SMatthew G. Knepley ierr = PetscSectionGetStorageSize(supportSection, &ssize);CHKERRQ(ierr); 70188ccfff9cSToby Isaac if (csize != ssize) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Total cone size %D != Total support size %D", csize, ssize); 701957beb4faSStefano Zampini } 7020ca8062c8SMatthew G. Knepley PetscFunctionReturn(0); 7021ca8062c8SMatthew G. Knepley } 7022ca8062c8SMatthew G. Knepley 7023ca8062c8SMatthew G. Knepley /*@ 7024ca8062c8SMatthew G. Knepley DMPlexCheckSkeleton - Check that each cell has the correct number of vertices 7025ca8062c8SMatthew G. Knepley 7026ca8062c8SMatthew G. Knepley Input Parameters: 7027ca8062c8SMatthew G. Knepley + dm - The DMPlex object 702858723a97SMatthew G. Knepley - cellHeight - Normally 0 7029ca8062c8SMatthew G. Knepley 7030ca8062c8SMatthew G. Knepley Note: This is a useful diagnostic when creating meshes programmatically. 703125c50c26SVaclav Hapla Currently applicable only to homogeneous simplex or tensor meshes. 7032ca8062c8SMatthew G. Knepley 7033ca8062c8SMatthew G. Knepley Level: developer 7034ca8062c8SMatthew G. Knepley 70357d5acc75SStefano Zampini .seealso: DMCreate(), DMPlexCheckSymmetry(), DMPlexCheckFaces() 7036ca8062c8SMatthew G. Knepley @*/ 703725c50c26SVaclav Hapla PetscErrorCode DMPlexCheckSkeleton(DM dm, PetscInt cellHeight) 7038ca8062c8SMatthew G. Knepley { 703942363296SMatthew G. Knepley PetscInt dim, numCorners, numHybridCorners, vStart, vEnd, cStart, cEnd, cMax, c; 704025c50c26SVaclav Hapla PetscBool isSimplex = PETSC_FALSE; 7041ca8062c8SMatthew G. Knepley PetscErrorCode ierr; 7042ca8062c8SMatthew G. Knepley 7043ca8062c8SMatthew G. Knepley PetscFunctionBegin; 7044ca8062c8SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7045c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 704625c50c26SVaclav Hapla ierr = DMPlexGetHeightStratum(dm, cellHeight, &cStart, &cEnd);CHKERRQ(ierr); 704725c50c26SVaclav Hapla if (cStart < cEnd) { 704825c50c26SVaclav Hapla ierr = DMPlexGetConeSize(dm, cStart, &c);CHKERRQ(ierr); 704925c50c26SVaclav Hapla isSimplex = c == dim+1 ? PETSC_TRUE : PETSC_FALSE; 705025c50c26SVaclav Hapla } 7051ca8062c8SMatthew G. Knepley switch (dim) { 705242363296SMatthew G. Knepley case 1: numCorners = isSimplex ? 2 : 2; numHybridCorners = isSimplex ? 2 : 2; break; 705342363296SMatthew G. Knepley case 2: numCorners = isSimplex ? 3 : 4; numHybridCorners = isSimplex ? 4 : 4; break; 705442363296SMatthew G. Knepley case 3: numCorners = isSimplex ? 4 : 8; numHybridCorners = isSimplex ? 6 : 8; break; 7055ca8062c8SMatthew G. Knepley default: 70568ccfff9cSToby Isaac SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Cannot handle meshes of dimension %D", dim); 7057ca8062c8SMatthew G. Knepley } 705858723a97SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 7059ca8062c8SMatthew G. Knepley ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr); 7060ca8062c8SMatthew G. Knepley cMax = cMax >= 0 ? cMax : cEnd; 7061ca8062c8SMatthew G. Knepley for (c = cStart; c < cMax; ++c) { 706258723a97SMatthew G. Knepley PetscInt *closure = NULL, closureSize, cl, coneSize = 0; 706358723a97SMatthew G. Knepley 706458723a97SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 706558723a97SMatthew G. Knepley for (cl = 0; cl < closureSize*2; cl += 2) { 706658723a97SMatthew G. Knepley const PetscInt p = closure[cl]; 706758723a97SMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) ++coneSize; 706858723a97SMatthew G. Knepley } 706958723a97SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 70708ccfff9cSToby Isaac if (coneSize != numCorners) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cell %D has %D vertices != %D", c, coneSize, numCorners); 7071ca8062c8SMatthew G. Knepley } 707242363296SMatthew G. Knepley for (c = cMax; c < cEnd; ++c) { 707342363296SMatthew G. Knepley PetscInt *closure = NULL, closureSize, cl, coneSize = 0; 707442363296SMatthew G. Knepley 707542363296SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 707642363296SMatthew G. Knepley for (cl = 0; cl < closureSize*2; cl += 2) { 707742363296SMatthew G. Knepley const PetscInt p = closure[cl]; 707842363296SMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) ++coneSize; 707942363296SMatthew G. Knepley } 708042363296SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 70818ccfff9cSToby Isaac if (coneSize > numHybridCorners) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Hybrid cell %D has %D vertices > %D", c, coneSize, numHybridCorners); 708242363296SMatthew G. Knepley } 7083ca8062c8SMatthew G. Knepley PetscFunctionReturn(0); 7084ca8062c8SMatthew G. Knepley } 70859bf0dad6SMatthew G. Knepley 70869bf0dad6SMatthew G. Knepley /*@ 70879bf0dad6SMatthew 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 70889bf0dad6SMatthew G. Knepley 7089*899ea2b8SJacob Faibussowitsch Not Collective 7090*899ea2b8SJacob Faibussowitsch 70919bf0dad6SMatthew G. Knepley Input Parameters: 70929bf0dad6SMatthew G. Knepley + dm - The DMPlex object 70939bf0dad6SMatthew G. Knepley - cellHeight - Normally 0 70949bf0dad6SMatthew G. Knepley 7095*899ea2b8SJacob Faibussowitsch Note: This routine is only relevant for meshes that are fully interpolated across all ranks, and will error out if a non-interpolated mesh is 7096*899ea2b8SJacob Faibussowitsch given. This is a useful diagnostic when creating meshes programmatically. 7097*899ea2b8SJacob Faibussowitsch 7098*899ea2b8SJacob Faibussowitsch Options Database Keys: 7099*899ea2b8SJacob Faibussowitsch . -dm_plex_force_check_faces <bool> : Force DMPlexCheckFaces() to run even on uninterpolated meshes 71009bf0dad6SMatthew G. Knepley 71019bf0dad6SMatthew G. Knepley Level: developer 71029bf0dad6SMatthew G. Knepley 7103*899ea2b8SJacob Faibussowitsch .seealso: DMCreate(), DMPlexGetVTKCellHeight(), DMPlexCheckSymmetry(), DMPlexCheckSkeleton(), DMPlexInterpolate(), DMPlexIsInterpolated() 71049bf0dad6SMatthew G. Knepley @*/ 710525c50c26SVaclav Hapla PetscErrorCode DMPlexCheckFaces(DM dm, PetscInt cellHeight) 71069bf0dad6SMatthew G. Knepley { 71073554e41dSMatthew G. Knepley PetscInt pMax[4]; 7108ab91121cSMatthew G. Knepley PetscInt dim, depth, vStart, vEnd, cStart, cEnd, c, h; 71099bf0dad6SMatthew G. Knepley PetscErrorCode ierr; 7110*899ea2b8SJacob Faibussowitsch DMPlexInterpolatedFlag interpEnum; 7111*899ea2b8SJacob Faibussowitsch PetscBool override = PETSC_FALSE, oset = PETSC_FALSE; 71129bf0dad6SMatthew G. Knepley 71139bf0dad6SMatthew G. Knepley PetscFunctionBegin; 71149bf0dad6SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7115*899ea2b8SJacob Faibussowitsch 7116*899ea2b8SJacob Faibussowitsch ierr = DMPlexIsInterpolated(dm, &interpEnum);CHKERRQ(ierr); 7117*899ea2b8SJacob Faibussowitsch ierr = PetscOptionsGetBool(NULL, NULL, "-dm_plex_force_check_faces", &override, &oset);CHKERRQ(ierr); 7118*899ea2b8SJacob Faibussowitsch if (interpEnum != DMPLEX_INTERPOLATED_FULL && !(override && oset)) { 7119*899ea2b8SJacob Faibussowitsch PetscMPIInt rank; 7120*899ea2b8SJacob Faibussowitsch MPI_Comm comm; 7121*899ea2b8SJacob Faibussowitsch 7122*899ea2b8SJacob Faibussowitsch ierr = PetscObjectGetComm((PetscObject) dm, &comm);CHKERRQ(ierr); 7123*899ea2b8SJacob Faibussowitsch ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 7124*899ea2b8SJacob Faibussowitsch SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "Mesh is not fully interpolated on rank %d!", rank); 7125*899ea2b8SJacob Faibussowitsch } 7126*899ea2b8SJacob Faibussowitsch 7127c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 7128ab91121cSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 71299bf0dad6SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 713025abba81SMatthew G. Knepley ierr = DMPlexGetHybridBounds(dm, &pMax[dim], &pMax[dim-1], &pMax[1], &pMax[0]);CHKERRQ(ierr); 7131ab91121cSMatthew G. Knepley for (h = cellHeight; h < PetscMin(depth, dim); ++h) { 71323554e41dSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, h, &cStart, &cEnd);CHKERRQ(ierr); 71333554e41dSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 71349bf0dad6SMatthew G. Knepley const PetscInt *cone, *ornt, *faces; 71359bf0dad6SMatthew G. Knepley PetscInt numFaces, faceSize, coneSize,f; 71369bf0dad6SMatthew G. Knepley PetscInt *closure = NULL, closureSize, cl, numCorners = 0; 71379bf0dad6SMatthew G. Knepley 713825abba81SMatthew G. Knepley if (pMax[dim-h] >= 0 && c >= pMax[dim-h]) continue; 71399bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, c, &coneSize);CHKERRQ(ierr); 71409bf0dad6SMatthew G. Knepley ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 71419bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 71429bf0dad6SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 71439bf0dad6SMatthew G. Knepley for (cl = 0; cl < closureSize*2; cl += 2) { 71449bf0dad6SMatthew G. Knepley const PetscInt p = closure[cl]; 71459bf0dad6SMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) closure[numCorners++] = p; 71469bf0dad6SMatthew G. Knepley } 71473554e41dSMatthew G. Knepley ierr = DMPlexGetRawFaces_Internal(dm, dim-h, numCorners, closure, &numFaces, &faceSize, &faces);CHKERRQ(ierr); 71488ccfff9cSToby Isaac if (coneSize != numFaces) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cell %D has %D faces but should have %D", c, coneSize, numFaces); 71499bf0dad6SMatthew G. Knepley for (f = 0; f < numFaces; ++f) { 71509bf0dad6SMatthew G. Knepley PetscInt *fclosure = NULL, fclosureSize, cl, fnumCorners = 0, v; 71519bf0dad6SMatthew G. Knepley 71529bf0dad6SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure_Internal(dm, cone[f], ornt[f], PETSC_TRUE, &fclosureSize, &fclosure);CHKERRQ(ierr); 71539bf0dad6SMatthew G. Knepley for (cl = 0; cl < fclosureSize*2; cl += 2) { 71549bf0dad6SMatthew G. Knepley const PetscInt p = fclosure[cl]; 71559bf0dad6SMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) fclosure[fnumCorners++] = p; 71569bf0dad6SMatthew G. Knepley } 71578ccfff9cSToby 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); 71589bf0dad6SMatthew G. Knepley for (v = 0; v < fnumCorners; ++v) { 71598ccfff9cSToby 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]); 71609bf0dad6SMatthew G. Knepley } 71619bf0dad6SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, cone[f], PETSC_TRUE, &fclosureSize, &fclosure);CHKERRQ(ierr); 71629bf0dad6SMatthew G. Knepley } 71639bf0dad6SMatthew G. Knepley ierr = DMPlexRestoreFaces_Internal(dm, dim, c, &numFaces, &faceSize, &faces);CHKERRQ(ierr); 71649bf0dad6SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 71659bf0dad6SMatthew G. Knepley } 71663554e41dSMatthew G. Knepley } 7167552f7358SJed Brown PetscFunctionReturn(0); 7168552f7358SJed Brown } 71693913d7c8SMatthew G. Knepley 7170bb6a34a8SMatthew G. Knepley /*@ 7171bb6a34a8SMatthew G. Knepley DMPlexCheckGeometry - Check the geometry of mesh cells 7172bb6a34a8SMatthew G. Knepley 7173bb6a34a8SMatthew G. Knepley Input Parameter: 7174bb6a34a8SMatthew G. Knepley . dm - The DMPlex object 7175bb6a34a8SMatthew G. Knepley 7176bb6a34a8SMatthew G. Knepley Note: This is a useful diagnostic when creating meshes programmatically. 7177bb6a34a8SMatthew G. Knepley 7178bb6a34a8SMatthew G. Knepley Level: developer 7179bb6a34a8SMatthew G. Knepley 7180bb6a34a8SMatthew G. Knepley .seealso: DMCreate(), DMCheckSymmetry(), DMCheckSkeleton(), DMCheckFaces() 7181bb6a34a8SMatthew G. Knepley @*/ 7182bb6a34a8SMatthew G. Knepley PetscErrorCode DMPlexCheckGeometry(DM dm) 7183bb6a34a8SMatthew G. Knepley { 7184bb6a34a8SMatthew G. Knepley PetscReal detJ, J[9], refVol = 1.0; 7185bb6a34a8SMatthew G. Knepley PetscReal vol; 71866210d0f3SStefano Zampini PetscInt dim, depth, d, cStart, cEnd, c, cMax; 7187bb6a34a8SMatthew G. Knepley PetscErrorCode ierr; 7188bb6a34a8SMatthew G. Knepley 7189bb6a34a8SMatthew G. Knepley PetscFunctionBegin; 7190bb6a34a8SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 7191bb6a34a8SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 7192bb6a34a8SMatthew G. Knepley for (d = 0; d < dim; ++d) refVol *= 2.0; 7193bb6a34a8SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 71946210d0f3SStefano Zampini ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr); 71956210d0f3SStefano Zampini cMax = cMax < 0 ? cEnd : cMax; 71966210d0f3SStefano Zampini for (c = cStart; c < cMax; ++c) { 7197bb6a34a8SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFEM(dm, c, NULL, NULL, J, NULL, &detJ);CHKERRQ(ierr); 7198bb6a34a8SMatthew G. Knepley if (detJ <= 0.0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Mesh cell %D is inverted, |J| = %g", c, (double) detJ); 7199bb6a34a8SMatthew G. Knepley ierr = PetscInfo2(dm, "Cell %D FEM Volume %g\n", c, (double) detJ*refVol);CHKERRQ(ierr); 7200bb6a34a8SMatthew G. Knepley if (depth > 1) { 7201bb6a34a8SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFVM(dm, c, &vol, NULL, NULL);CHKERRQ(ierr); 7202bb6a34a8SMatthew G. Knepley if (vol <= 0.0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Mesh cell %d is inverted, vol = %g", c, (double) vol); 7203bb6a34a8SMatthew G. Knepley ierr = PetscInfo2(dm, "Cell %D FVM Volume %g\n", c, (double) vol);CHKERRQ(ierr); 7204bb6a34a8SMatthew G. Knepley } 7205bb6a34a8SMatthew G. Knepley } 7206bb6a34a8SMatthew G. Knepley PetscFunctionReturn(0); 7207bb6a34a8SMatthew G. Knepley } 7208bb6a34a8SMatthew G. Knepley 720903da9461SVaclav Hapla static PetscErrorCode DMPlexAreAllConePointsInArray_Private(DM dm, PetscInt p, PetscInt npoints, const PetscInt *points, PetscInt *missingPoint) 721003da9461SVaclav Hapla { 721103da9461SVaclav Hapla PetscInt i,l,n; 721203da9461SVaclav Hapla const PetscInt *cone; 721303da9461SVaclav Hapla PetscErrorCode ierr; 721403da9461SVaclav Hapla 721503da9461SVaclav Hapla PetscFunctionBegin; 721603da9461SVaclav Hapla *missingPoint = -1; 721703da9461SVaclav Hapla ierr = DMPlexGetConeSize(dm, p, &n);CHKERRQ(ierr); 721803da9461SVaclav Hapla ierr = DMPlexGetCone(dm, p, &cone);CHKERRQ(ierr); 721903da9461SVaclav Hapla for (i=0; i<n; i++) { 722003da9461SVaclav Hapla ierr = PetscFindInt(cone[i], npoints, points, &l);CHKERRQ(ierr); 722103da9461SVaclav Hapla if (l < 0) { 722203da9461SVaclav Hapla *missingPoint = cone[i]; 722303da9461SVaclav Hapla break; 722403da9461SVaclav Hapla } 722503da9461SVaclav Hapla } 722603da9461SVaclav Hapla PetscFunctionReturn(0); 722703da9461SVaclav Hapla } 722803da9461SVaclav Hapla 722903da9461SVaclav Hapla /*@ 7230e83a0d2dSVaclav Hapla DMPlexCheckPointSF - Check that several necessary conditions are met for the point SF of this plex. 723103da9461SVaclav Hapla 723203da9461SVaclav Hapla Input Parameters: 723303da9461SVaclav Hapla . dm - The DMPlex object 723403da9461SVaclav Hapla 7235e83a0d2dSVaclav Hapla Notes: 7236e83a0d2dSVaclav Hapla This is mainly intended for debugging/testing purposes. 72378918e3e2SVaclav Hapla It currently checks only meshes with no partition overlapping. 723803da9461SVaclav Hapla 723903da9461SVaclav Hapla Level: developer 724003da9461SVaclav Hapla 724103da9461SVaclav Hapla .seealso: DMGetPointSF(), DMPlexCheckSymmetry(), DMPlexCheckSkeleton(), DMPlexCheckFaces() 724203da9461SVaclav Hapla @*/ 724303da9461SVaclav Hapla PetscErrorCode DMPlexCheckPointSF(DM dm) 724403da9461SVaclav Hapla { 7245f0cfc026SVaclav Hapla PetscSF pointSF; 724603da9461SVaclav Hapla PetscInt d,depth,i,nleaves,p,plo,phi,missingPoint; 7247f0cfc026SVaclav Hapla PetscInt nroots,overlap; 724803da9461SVaclav Hapla const PetscInt *locals; 7249f0cfc026SVaclav Hapla PetscBool distributed; 725003da9461SVaclav Hapla PetscErrorCode ierr; 725103da9461SVaclav Hapla 725203da9461SVaclav Hapla PetscFunctionBegin; 725303da9461SVaclav Hapla PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 725403da9461SVaclav Hapla ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 7255f0cfc026SVaclav Hapla ierr = DMGetPointSF(dm, &pointSF);CHKERRQ(ierr); 7256f0cfc026SVaclav Hapla ierr = DMPlexIsDistributed(dm, &distributed);CHKERRQ(ierr); 7257f0cfc026SVaclav Hapla if (!distributed) PetscFunctionReturn(0); 7258f0cfc026SVaclav Hapla ierr = DMPlexGetOverlap(dm, &overlap);CHKERRQ(ierr); 7259f0cfc026SVaclav Hapla if (overlap) { 72608918e3e2SVaclav Hapla ierr = PetscPrintf(PetscObjectComm((PetscObject)dm), "Warning: DMPlexCheckPointSF() is currently not implemented for meshes with partition overlapping"); 72618918e3e2SVaclav Hapla PetscFunctionReturn(0); 72628918e3e2SVaclav Hapla } 7263f0cfc026SVaclav Hapla if (!pointSF) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "This DMPlex is distributed but does not have PointSF attached"); 7264f0cfc026SVaclav Hapla ierr = PetscSFGetGraph(pointSF, &nroots, &nleaves, &locals, NULL);CHKERRQ(ierr); 7265f0cfc026SVaclav Hapla if (nroots < 0) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "This DMPlex is distributed but its PointSF has no graph set"); 726603da9461SVaclav Hapla 7267ece87651SVaclav Hapla /* 1) check there are no faces in 2D, cells in 3D, in interface */ 726803da9461SVaclav Hapla ierr = DMPlexGetVTKCellHeight(dm, &d);CHKERRQ(ierr); 726903da9461SVaclav Hapla ierr = DMPlexGetHeightStratum(dm, d, &plo, &phi);CHKERRQ(ierr); 727003da9461SVaclav Hapla for (i=0; i<nleaves; i++) { 727103da9461SVaclav Hapla p = locals[i]; 727203da9461SVaclav Hapla if (p >= plo && p < phi) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "point SF contains %d which is a cell",p); 727303da9461SVaclav Hapla } 7274ece87651SVaclav Hapla 7275ece87651SVaclav Hapla /* 2) if some point is in interface, then all its cone points must be also in interface */ 7276ece87651SVaclav Hapla for (i=0; i<nleaves; i++) { 7277ece87651SVaclav Hapla p = locals[i]; 7278ece87651SVaclav Hapla ierr = DMPlexAreAllConePointsInArray_Private(dm, p, nleaves, locals, &missingPoint);CHKERRQ(ierr); 7279ece87651SVaclav Hapla if (missingPoint >= 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "point SF contains %d but not %d from its cone",p,missingPoint); 7280ece87651SVaclav Hapla } 728103da9461SVaclav Hapla PetscFunctionReturn(0); 728203da9461SVaclav Hapla } 728303da9461SVaclav Hapla 7284068a5610SStefano Zampini typedef struct cell_stats 7285068a5610SStefano Zampini { 7286068a5610SStefano Zampini PetscReal min, max, sum, squaresum; 7287068a5610SStefano Zampini PetscInt count; 7288068a5610SStefano Zampini } cell_stats_t; 7289068a5610SStefano Zampini 729025befc3bSSatish Balay static void MPIAPI cell_stats_reduce(void *a, void *b, int * len, MPI_Datatype *datatype) 7291068a5610SStefano Zampini { 7292068a5610SStefano Zampini PetscInt i, N = *len; 7293068a5610SStefano Zampini 7294068a5610SStefano Zampini for (i = 0; i < N; i++) { 7295068a5610SStefano Zampini cell_stats_t *A = (cell_stats_t *) a; 7296068a5610SStefano Zampini cell_stats_t *B = (cell_stats_t *) b; 7297068a5610SStefano Zampini 7298068a5610SStefano Zampini B->min = PetscMin(A->min,B->min); 7299068a5610SStefano Zampini B->max = PetscMax(A->max,B->max); 7300068a5610SStefano Zampini B->sum += A->sum; 7301068a5610SStefano Zampini B->squaresum += A->squaresum; 7302068a5610SStefano Zampini B->count += A->count; 7303068a5610SStefano Zampini } 7304068a5610SStefano Zampini } 7305068a5610SStefano Zampini 7306068a5610SStefano Zampini /*@ 730743fa8764SMatthew G. Knepley DMPlexCheckCellShape - Checks the Jacobian of the mapping from reference to real cells and computes some minimal statistics. 7308068a5610SStefano Zampini 73098261a58bSMatthew G. Knepley Collective on dm 73108261a58bSMatthew G. Knepley 7311068a5610SStefano Zampini Input Parameters: 7312068a5610SStefano Zampini + dm - The DMPlex object 731343fa8764SMatthew G. Knepley . output - If true, statistics will be displayed on stdout 731443fa8764SMatthew G. Knepley - condLimit - Display all cells above this condition number, or PETSC_DETERMINE for no cell output 7315068a5610SStefano Zampini 7316068a5610SStefano Zampini Note: This is mainly intended for debugging/testing purposes. 7317068a5610SStefano Zampini 7318068a5610SStefano Zampini Level: developer 7319068a5610SStefano Zampini 7320068a5610SStefano Zampini .seealso: DMPlexCheckSymmetry(), DMPlexCheckSkeleton(), DMPlexCheckFaces() 7321068a5610SStefano Zampini @*/ 732243fa8764SMatthew G. Knepley PetscErrorCode DMPlexCheckCellShape(DM dm, PetscBool output, PetscReal condLimit) 7323068a5610SStefano Zampini { 7324068a5610SStefano Zampini DM dmCoarse; 732543fa8764SMatthew G. Knepley cell_stats_t stats, globalStats; 732643fa8764SMatthew G. Knepley MPI_Comm comm = PetscObjectComm((PetscObject)dm); 732743fa8764SMatthew G. Knepley PetscReal *J, *invJ, min = 0, max = 0, mean = 0, stdev = 0; 732843fa8764SMatthew G. Knepley PetscReal limit = condLimit > 0 ? condLimit : PETSC_MAX_REAL; 732943fa8764SMatthew G. Knepley PetscInt cdim, cStart, cEnd, cMax, c, eStart, eEnd, count = 0; 733043fa8764SMatthew G. Knepley PetscMPIInt rank,size; 7331068a5610SStefano Zampini PetscErrorCode ierr; 7332068a5610SStefano Zampini 7333068a5610SStefano Zampini PetscFunctionBegin; 7334068a5610SStefano Zampini PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7335068a5610SStefano Zampini stats.min = PETSC_MAX_REAL; 7336068a5610SStefano Zampini stats.max = PETSC_MIN_REAL; 7337068a5610SStefano Zampini stats.sum = stats.squaresum = 0.; 7338068a5610SStefano Zampini stats.count = 0; 7339068a5610SStefano Zampini 734043fa8764SMatthew G. Knepley ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 734143fa8764SMatthew G. Knepley ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); 734243fa8764SMatthew G. Knepley ierr = DMGetCoordinateDim(dm,&cdim);CHKERRQ(ierr); 734343fa8764SMatthew G. Knepley ierr = PetscMalloc2(PetscSqr(cdim), &J, PetscSqr(cdim), &invJ);CHKERRQ(ierr); 7344068a5610SStefano Zampini ierr = DMPlexGetHeightStratum(dm,0,&cStart,&cEnd);CHKERRQ(ierr); 734543fa8764SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm,1,&eStart,&eEnd);CHKERRQ(ierr); 7346068a5610SStefano Zampini ierr = DMPlexGetHybridBounds(dm,&cMax,NULL,NULL,NULL);CHKERRQ(ierr); 7347068a5610SStefano Zampini cMax = cMax < 0 ? cEnd : cMax; 7348068a5610SStefano Zampini for (c = cStart; c < cMax; c++) { 7349068a5610SStefano Zampini PetscInt i; 7350068a5610SStefano Zampini PetscReal frobJ = 0., frobInvJ = 0., cond2, cond, detJ; 7351068a5610SStefano Zampini 7352068a5610SStefano Zampini ierr = DMPlexComputeCellGeometryAffineFEM(dm,c,NULL,J,invJ,&detJ);CHKERRQ(ierr); 7353068a5610SStefano Zampini if (detJ < 0.0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Mesh cell %D is inverted", c); 735443fa8764SMatthew G. Knepley for (i = 0; i < PetscSqr(cdim); ++i) { 7355068a5610SStefano Zampini frobJ += J[i] * J[i]; 7356068a5610SStefano Zampini frobInvJ += invJ[i] * invJ[i]; 7357068a5610SStefano Zampini } 7358068a5610SStefano Zampini cond2 = frobJ * frobInvJ; 7359068a5610SStefano Zampini cond = PetscSqrtReal(cond2); 7360068a5610SStefano Zampini 7361068a5610SStefano Zampini stats.min = PetscMin(stats.min,cond); 7362068a5610SStefano Zampini stats.max = PetscMax(stats.max,cond); 7363068a5610SStefano Zampini stats.sum += cond; 7364068a5610SStefano Zampini stats.squaresum += cond2; 7365068a5610SStefano Zampini stats.count++; 73668261a58bSMatthew G. Knepley if (output && cond > limit) { 736743fa8764SMatthew G. Knepley PetscSection coordSection; 736843fa8764SMatthew G. Knepley Vec coordsLocal; 736943fa8764SMatthew G. Knepley PetscScalar *coords = NULL; 737043fa8764SMatthew G. Knepley PetscInt Nv, d, clSize, cl, *closure = NULL; 737143fa8764SMatthew G. Knepley 737243fa8764SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordsLocal);CHKERRQ(ierr); 737343fa8764SMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 737443fa8764SMatthew G. Knepley ierr = DMPlexVecGetClosure(dm, coordSection, coordsLocal, c, &Nv, &coords);CHKERRQ(ierr); 7375087ef6b2SMatthew G. Knepley ierr = PetscSynchronizedPrintf(comm, "[%d] Cell %D cond %g\n", rank, c, (double) cond);CHKERRQ(ierr); 737643fa8764SMatthew G. Knepley for (i = 0; i < Nv/cdim; ++i) { 737743fa8764SMatthew G. Knepley ierr = PetscSynchronizedPrintf(comm, " Vertex %D: (", i);CHKERRQ(ierr); 737843fa8764SMatthew G. Knepley for (d = 0; d < cdim; ++d) { 737943fa8764SMatthew G. Knepley if (d > 0) {ierr = PetscSynchronizedPrintf(comm, ", ");CHKERRQ(ierr);} 738048afe810SSatish Balay ierr = PetscSynchronizedPrintf(comm, "%g", (double) PetscRealPart(coords[i*cdim+d]));CHKERRQ(ierr); 738143fa8764SMatthew G. Knepley } 738243fa8764SMatthew G. Knepley ierr = PetscSynchronizedPrintf(comm, ")\n");CHKERRQ(ierr); 738343fa8764SMatthew G. Knepley } 738443fa8764SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &clSize, &closure);CHKERRQ(ierr); 738543fa8764SMatthew G. Knepley for (cl = 0; cl < clSize*2; cl += 2) { 738643fa8764SMatthew G. Knepley const PetscInt edge = closure[cl]; 738743fa8764SMatthew G. Knepley 738843fa8764SMatthew G. Knepley if ((edge >= eStart) && (edge < eEnd)) { 738943fa8764SMatthew G. Knepley PetscReal len; 739043fa8764SMatthew G. Knepley 739143fa8764SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFVM(dm, edge, &len, NULL, NULL);CHKERRQ(ierr); 7392087ef6b2SMatthew G. Knepley ierr = PetscSynchronizedPrintf(comm, " Edge %D: length %g\n", edge, (double) len);CHKERRQ(ierr); 739343fa8764SMatthew G. Knepley } 739443fa8764SMatthew G. Knepley } 739543fa8764SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &clSize, &closure);CHKERRQ(ierr); 739643fa8764SMatthew G. Knepley ierr = DMPlexVecRestoreClosure(dm, coordSection, coordsLocal, c, &Nv, &coords);CHKERRQ(ierr); 739743fa8764SMatthew G. Knepley } 7398068a5610SStefano Zampini } 73998261a58bSMatthew G. Knepley if (output) {ierr = PetscSynchronizedFlush(comm, NULL);CHKERRQ(ierr);} 7400068a5610SStefano Zampini 7401068a5610SStefano Zampini if (size > 1) { 7402068a5610SStefano Zampini PetscMPIInt blockLengths[2] = {4,1}; 7403068a5610SStefano Zampini MPI_Aint blockOffsets[2] = {offsetof(cell_stats_t,min),offsetof(cell_stats_t,count)}; 7404068a5610SStefano Zampini MPI_Datatype blockTypes[2] = {MPIU_REAL,MPIU_INT}, statType; 7405068a5610SStefano Zampini MPI_Op statReduce; 7406068a5610SStefano Zampini 7407068a5610SStefano Zampini ierr = MPI_Type_create_struct(2,blockLengths,blockOffsets,blockTypes,&statType);CHKERRQ(ierr); 7408068a5610SStefano Zampini ierr = MPI_Type_commit(&statType);CHKERRQ(ierr); 7409068a5610SStefano Zampini ierr = MPI_Op_create(cell_stats_reduce, PETSC_TRUE, &statReduce);CHKERRQ(ierr); 7410068a5610SStefano Zampini ierr = MPI_Reduce(&stats,&globalStats,1,statType,statReduce,0,comm);CHKERRQ(ierr); 7411068a5610SStefano Zampini ierr = MPI_Op_free(&statReduce);CHKERRQ(ierr); 7412068a5610SStefano Zampini ierr = MPI_Type_free(&statType);CHKERRQ(ierr); 7413068a5610SStefano Zampini } else { 7414580bdb30SBarry Smith ierr = PetscArraycpy(&globalStats,&stats,1);CHKERRQ(ierr); 7415068a5610SStefano Zampini } 7416068a5610SStefano Zampini if (!rank) { 7417068a5610SStefano Zampini count = globalStats.count; 7418068a5610SStefano Zampini min = globalStats.min; 7419068a5610SStefano Zampini max = globalStats.max; 7420068a5610SStefano Zampini mean = globalStats.sum / globalStats.count; 7421068a5610SStefano Zampini stdev = globalStats.count > 1 ? PetscSqrtReal(PetscMax((globalStats.squaresum - globalStats.count * mean * mean) / (globalStats.count - 1),0)) : 0.0; 7422068a5610SStefano Zampini } 7423068a5610SStefano Zampini 7424068a5610SStefano Zampini if (output) { 7425068a5610SStefano 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); 7426068a5610SStefano Zampini } 7427068a5610SStefano Zampini ierr = PetscFree2(J,invJ);CHKERRQ(ierr); 7428068a5610SStefano Zampini 7429068a5610SStefano Zampini ierr = DMGetCoarseDM(dm,&dmCoarse);CHKERRQ(ierr); 7430068a5610SStefano Zampini if (dmCoarse) { 7431068a5610SStefano Zampini PetscBool isplex; 7432068a5610SStefano Zampini 7433068a5610SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)dmCoarse,DMPLEX,&isplex);CHKERRQ(ierr); 7434068a5610SStefano Zampini if (isplex) { 743543fa8764SMatthew G. Knepley ierr = DMPlexCheckCellShape(dmCoarse,output,condLimit);CHKERRQ(ierr); 7436068a5610SStefano Zampini } 7437068a5610SStefano Zampini } 7438068a5610SStefano Zampini PetscFunctionReturn(0); 7439068a5610SStefano Zampini } 7440068a5610SStefano Zampini 7441bceba477SMatthew G. Knepley /* Pointwise interpolation 7442bceba477SMatthew G. Knepley Just code FEM for now 7443bceba477SMatthew G. Knepley u^f = I u^c 74444ca5e9f5SMatthew G. Knepley sum_k u^f_k phi^f_k = I sum_j u^c_j phi^c_j 74454ca5e9f5SMatthew G. Knepley u^f_i = sum_j psi^f_i I phi^c_j u^c_j 74464ca5e9f5SMatthew G. Knepley I_{ij} = psi^f_i phi^c_j 7447bceba477SMatthew G. Knepley */ 7448bceba477SMatthew G. Knepley PetscErrorCode DMCreateInterpolation_Plex(DM dmCoarse, DM dmFine, Mat *interpolation, Vec *scaling) 7449bceba477SMatthew G. Knepley { 7450bceba477SMatthew G. Knepley PetscSection gsc, gsf; 7451bceba477SMatthew G. Knepley PetscInt m, n; 7452a063dac3SMatthew G. Knepley void *ctx; 745368132eb9SMatthew G. Knepley DM cdm; 7454fd194bc8SStefano Zampini PetscBool regular, ismatis; 7455bceba477SMatthew G. Knepley PetscErrorCode ierr; 7456bceba477SMatthew G. Knepley 7457bceba477SMatthew G. Knepley PetscFunctionBegin; 7458e87a4003SBarry Smith ierr = DMGetGlobalSection(dmFine, &gsf);CHKERRQ(ierr); 7459bceba477SMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(gsf, &m);CHKERRQ(ierr); 7460e87a4003SBarry Smith ierr = DMGetGlobalSection(dmCoarse, &gsc);CHKERRQ(ierr); 7461bceba477SMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(gsc, &n);CHKERRQ(ierr); 746268132eb9SMatthew G. Knepley 7463fd194bc8SStefano Zampini ierr = PetscStrcmp(dmCoarse->mattype, MATIS, &ismatis);CHKERRQ(ierr); 7464bceba477SMatthew G. Knepley ierr = MatCreate(PetscObjectComm((PetscObject) dmCoarse), interpolation);CHKERRQ(ierr); 7465bceba477SMatthew G. Knepley ierr = MatSetSizes(*interpolation, m, n, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 7466fd194bc8SStefano Zampini ierr = MatSetType(*interpolation, ismatis ? MATAIJ : dmCoarse->mattype);CHKERRQ(ierr); 7467a063dac3SMatthew G. Knepley ierr = DMGetApplicationContext(dmFine, &ctx);CHKERRQ(ierr); 746868132eb9SMatthew G. Knepley 7469a8fb8f29SToby Isaac ierr = DMGetCoarseDM(dmFine, &cdm);CHKERRQ(ierr); 747068132eb9SMatthew G. Knepley ierr = DMPlexGetRegularRefinement(dmFine, ®ular);CHKERRQ(ierr); 747168132eb9SMatthew G. Knepley if (regular && cdm == dmCoarse) {ierr = DMPlexComputeInterpolatorNested(dmCoarse, dmFine, *interpolation, ctx);CHKERRQ(ierr);} 747268132eb9SMatthew G. Knepley else {ierr = DMPlexComputeInterpolatorGeneral(dmCoarse, dmFine, *interpolation, ctx);CHKERRQ(ierr);} 747368132eb9SMatthew G. Knepley ierr = MatViewFromOptions(*interpolation, NULL, "-interp_mat_view");CHKERRQ(ierr); 74744db47ee9SStefano Zampini if (scaling) { 74755d1c2e58SMatthew G. Knepley /* Use naive scaling */ 74765d1c2e58SMatthew G. Knepley ierr = DMCreateInterpolationScale(dmCoarse, dmFine, *interpolation, scaling);CHKERRQ(ierr); 74774db47ee9SStefano Zampini } 7478a063dac3SMatthew G. Knepley PetscFunctionReturn(0); 7479a063dac3SMatthew G. Knepley } 7480bceba477SMatthew G. Knepley 74816dbf9973SLawrence Mitchell PetscErrorCode DMCreateInjection_Plex(DM dmCoarse, DM dmFine, Mat *mat) 7482a063dac3SMatthew G. Knepley { 748390748bafSMatthew G. Knepley PetscErrorCode ierr; 74846dbf9973SLawrence Mitchell VecScatter ctx; 748590748bafSMatthew G. Knepley 7486a063dac3SMatthew G. Knepley PetscFunctionBegin; 74876dbf9973SLawrence Mitchell ierr = DMPlexComputeInjectorFEM(dmCoarse, dmFine, &ctx, NULL);CHKERRQ(ierr); 74886dbf9973SLawrence Mitchell ierr = MatCreateScatter(PetscObjectComm((PetscObject)ctx), ctx, mat);CHKERRQ(ierr); 74896dbf9973SLawrence Mitchell ierr = VecScatterDestroy(&ctx);CHKERRQ(ierr); 7490bceba477SMatthew G. Knepley PetscFunctionReturn(0); 7491bceba477SMatthew G. Knepley } 7492bceba477SMatthew G. Knepley 7493bd041c0cSMatthew G. Knepley PetscErrorCode DMCreateMassMatrix_Plex(DM dmCoarse, DM dmFine, Mat *mass) 7494bd041c0cSMatthew G. Knepley { 7495bd041c0cSMatthew G. Knepley PetscSection gsc, gsf; 7496bd041c0cSMatthew G. Knepley PetscInt m, n; 7497bd041c0cSMatthew G. Knepley void *ctx; 7498bd041c0cSMatthew G. Knepley DM cdm; 7499bd041c0cSMatthew G. Knepley PetscBool regular; 7500bd041c0cSMatthew G. Knepley PetscErrorCode ierr; 7501bd041c0cSMatthew G. Knepley 7502bd041c0cSMatthew G. Knepley PetscFunctionBegin; 7503e87a4003SBarry Smith ierr = DMGetGlobalSection(dmFine, &gsf);CHKERRQ(ierr); 7504bd041c0cSMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(gsf, &m);CHKERRQ(ierr); 7505e87a4003SBarry Smith ierr = DMGetGlobalSection(dmCoarse, &gsc);CHKERRQ(ierr); 7506bd041c0cSMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(gsc, &n);CHKERRQ(ierr); 7507bd041c0cSMatthew G. Knepley 7508bd041c0cSMatthew G. Knepley ierr = MatCreate(PetscObjectComm((PetscObject) dmCoarse), mass);CHKERRQ(ierr); 7509bd041c0cSMatthew G. Knepley ierr = MatSetSizes(*mass, m, n, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 7510bd041c0cSMatthew G. Knepley ierr = MatSetType(*mass, dmCoarse->mattype);CHKERRQ(ierr); 7511bd041c0cSMatthew G. Knepley ierr = DMGetApplicationContext(dmFine, &ctx);CHKERRQ(ierr); 7512bd041c0cSMatthew G. Knepley 7513bd041c0cSMatthew G. Knepley ierr = DMGetCoarseDM(dmFine, &cdm);CHKERRQ(ierr); 7514bd041c0cSMatthew G. Knepley ierr = DMPlexGetRegularRefinement(dmFine, ®ular);CHKERRQ(ierr); 7515bd041c0cSMatthew G. Knepley if (regular && cdm == dmCoarse) {ierr = DMPlexComputeMassMatrixNested(dmCoarse, dmFine, *mass, ctx);CHKERRQ(ierr);} 7516bd041c0cSMatthew G. Knepley else {ierr = DMPlexComputeMassMatrixGeneral(dmCoarse, dmFine, *mass, ctx);CHKERRQ(ierr);} 7517bd041c0cSMatthew G. Knepley ierr = MatViewFromOptions(*mass, NULL, "-mass_mat_view");CHKERRQ(ierr); 7518bd041c0cSMatthew G. Knepley PetscFunctionReturn(0); 7519bd041c0cSMatthew G. Knepley } 7520bd041c0cSMatthew G. Knepley 75210aef6b92SMatthew G. Knepley /*@ 75220aef6b92SMatthew G. Knepley DMPlexGetRegularRefinement - Get the flag indicating that this mesh was obtained by regular refinement from its coarse mesh 75230aef6b92SMatthew G. Knepley 75240aef6b92SMatthew G. Knepley Input Parameter: 75250aef6b92SMatthew G. Knepley . dm - The DMPlex object 75260aef6b92SMatthew G. Knepley 75270aef6b92SMatthew G. Knepley Output Parameter: 75280aef6b92SMatthew G. Knepley . regular - The flag 75290aef6b92SMatthew G. Knepley 75300aef6b92SMatthew G. Knepley Level: intermediate 75310aef6b92SMatthew G. Knepley 75320aef6b92SMatthew G. Knepley .seealso: DMPlexSetRegularRefinement() 75330aef6b92SMatthew G. Knepley @*/ 75340aef6b92SMatthew G. Knepley PetscErrorCode DMPlexGetRegularRefinement(DM dm, PetscBool *regular) 75350aef6b92SMatthew G. Knepley { 75360aef6b92SMatthew G. Knepley PetscFunctionBegin; 75370aef6b92SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 75380aef6b92SMatthew G. Knepley PetscValidPointer(regular, 2); 75390aef6b92SMatthew G. Knepley *regular = ((DM_Plex *) dm->data)->regularRefinement; 75400aef6b92SMatthew G. Knepley PetscFunctionReturn(0); 75410aef6b92SMatthew G. Knepley } 75420aef6b92SMatthew G. Knepley 75430aef6b92SMatthew G. Knepley /*@ 75440aef6b92SMatthew G. Knepley DMPlexSetRegularRefinement - Set the flag indicating that this mesh was obtained by regular refinement from its coarse mesh 75450aef6b92SMatthew G. Knepley 75460aef6b92SMatthew G. Knepley Input Parameters: 75470aef6b92SMatthew G. Knepley + dm - The DMPlex object 75480aef6b92SMatthew G. Knepley - regular - The flag 75490aef6b92SMatthew G. Knepley 75500aef6b92SMatthew G. Knepley Level: intermediate 75510aef6b92SMatthew G. Knepley 75520aef6b92SMatthew G. Knepley .seealso: DMPlexGetRegularRefinement() 75530aef6b92SMatthew G. Knepley @*/ 75540aef6b92SMatthew G. Knepley PetscErrorCode DMPlexSetRegularRefinement(DM dm, PetscBool regular) 75550aef6b92SMatthew G. Knepley { 75560aef6b92SMatthew G. Knepley PetscFunctionBegin; 75570aef6b92SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 75580aef6b92SMatthew G. Knepley ((DM_Plex *) dm->data)->regularRefinement = regular; 75590aef6b92SMatthew G. Knepley PetscFunctionReturn(0); 75600aef6b92SMatthew G. Knepley } 75610aef6b92SMatthew G. Knepley 7562f7c74593SToby Isaac /* anchors */ 7563a68b90caSToby Isaac /*@ 7564f7c74593SToby Isaac DMPlexGetAnchors - Get the layout of the anchor (point-to-point) constraints. Typically, the user will not have to 7565f7c74593SToby Isaac call DMPlexGetAnchors() directly: if there are anchors, then DMPlexGetAnchors() is called during DMGetConstraints(). 7566a68b90caSToby Isaac 7567e228b242SToby Isaac not collective 7568a68b90caSToby Isaac 7569a68b90caSToby Isaac Input Parameters: 7570a68b90caSToby Isaac . dm - The DMPlex object 7571a68b90caSToby Isaac 7572a68b90caSToby Isaac Output Parameters: 7573a68b90caSToby Isaac + anchorSection - If not NULL, set to the section describing which points anchor the constrained points. 7574a68b90caSToby Isaac - anchorIS - If not NULL, set to the list of anchors indexed by anchorSection 7575a68b90caSToby Isaac 7576a68b90caSToby Isaac 7577a68b90caSToby Isaac Level: intermediate 7578a68b90caSToby Isaac 7579f7c74593SToby Isaac .seealso: DMPlexSetAnchors(), DMGetConstraints(), DMSetConstraints() 7580a68b90caSToby Isaac @*/ 7581a17985deSToby Isaac PetscErrorCode DMPlexGetAnchors(DM dm, PetscSection *anchorSection, IS *anchorIS) 7582a68b90caSToby Isaac { 7583a68b90caSToby Isaac DM_Plex *plex = (DM_Plex *)dm->data; 758441e6d900SToby Isaac PetscErrorCode ierr; 7585a68b90caSToby Isaac 7586a68b90caSToby Isaac PetscFunctionBegin; 7587a68b90caSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 758841e6d900SToby Isaac if (!plex->anchorSection && !plex->anchorIS && plex->createanchors) {ierr = (*plex->createanchors)(dm);CHKERRQ(ierr);} 7589a68b90caSToby Isaac if (anchorSection) *anchorSection = plex->anchorSection; 7590a68b90caSToby Isaac if (anchorIS) *anchorIS = plex->anchorIS; 7591a68b90caSToby Isaac PetscFunctionReturn(0); 7592a68b90caSToby Isaac } 7593a68b90caSToby Isaac 7594a68b90caSToby Isaac /*@ 7595f7c74593SToby Isaac DMPlexSetAnchors - Set the layout of the local anchor (point-to-point) constraints. Unlike boundary conditions, 7596f7c74593SToby Isaac when a point's degrees of freedom in a section are constrained to an outside value, the anchor constraints set a 7597a68b90caSToby Isaac point's degrees of freedom to be a linear combination of other points' degrees of freedom. 7598a68b90caSToby Isaac 7599a17985deSToby Isaac After specifying the layout of constraints with DMPlexSetAnchors(), one specifies the constraints by calling 7600f7c74593SToby Isaac DMGetConstraints() and filling in the entries in the constraint matrix. 7601a68b90caSToby Isaac 7602e228b242SToby Isaac collective on dm 7603a68b90caSToby Isaac 7604a68b90caSToby Isaac Input Parameters: 7605a68b90caSToby Isaac + dm - The DMPlex object 7606e228b242SToby 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). 7607e228b242SToby Isaac - anchorIS - The list of all anchor points. Must have a local communicator (PETSC_COMM_SELF or derivative). 7608a68b90caSToby Isaac 7609a68b90caSToby Isaac The reference counts of anchorSection and anchorIS are incremented. 7610a68b90caSToby Isaac 7611a68b90caSToby Isaac Level: intermediate 7612a68b90caSToby Isaac 7613f7c74593SToby Isaac .seealso: DMPlexGetAnchors(), DMGetConstraints(), DMSetConstraints() 7614a68b90caSToby Isaac @*/ 7615a17985deSToby Isaac PetscErrorCode DMPlexSetAnchors(DM dm, PetscSection anchorSection, IS anchorIS) 7616a68b90caSToby Isaac { 7617a68b90caSToby Isaac DM_Plex *plex = (DM_Plex *)dm->data; 7618e228b242SToby Isaac PetscMPIInt result; 7619a68b90caSToby Isaac PetscErrorCode ierr; 7620a68b90caSToby Isaac 7621a68b90caSToby Isaac PetscFunctionBegin; 7622a68b90caSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7623e228b242SToby Isaac if (anchorSection) { 7624e228b242SToby Isaac PetscValidHeaderSpecific(anchorSection,PETSC_SECTION_CLASSID,2); 7625e228b242SToby Isaac ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)anchorSection),&result);CHKERRQ(ierr); 7626f6a3d38cSToby Isaac if (result != MPI_CONGRUENT && result != MPI_IDENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"anchor section must have local communicator"); 7627e228b242SToby Isaac } 7628e228b242SToby Isaac if (anchorIS) { 7629e228b242SToby Isaac PetscValidHeaderSpecific(anchorIS,IS_CLASSID,3); 7630e228b242SToby Isaac ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)anchorIS),&result);CHKERRQ(ierr); 7631f6a3d38cSToby Isaac if (result != MPI_CONGRUENT && result != MPI_IDENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"anchor IS must have local communicator"); 7632e228b242SToby Isaac } 7633a68b90caSToby Isaac 7634a68b90caSToby Isaac ierr = PetscObjectReference((PetscObject)anchorSection);CHKERRQ(ierr); 7635a68b90caSToby Isaac ierr = PetscSectionDestroy(&plex->anchorSection);CHKERRQ(ierr); 7636a68b90caSToby Isaac plex->anchorSection = anchorSection; 7637a68b90caSToby Isaac 7638a68b90caSToby Isaac ierr = PetscObjectReference((PetscObject)anchorIS);CHKERRQ(ierr); 7639a68b90caSToby Isaac ierr = ISDestroy(&plex->anchorIS);CHKERRQ(ierr); 7640a68b90caSToby Isaac plex->anchorIS = anchorIS; 7641a68b90caSToby Isaac 7642a68b90caSToby Isaac #if defined(PETSC_USE_DEBUG) 7643a68b90caSToby Isaac if (anchorIS && anchorSection) { 7644a68b90caSToby Isaac PetscInt size, a, pStart, pEnd; 7645a68b90caSToby Isaac const PetscInt *anchors; 7646a68b90caSToby Isaac 7647a68b90caSToby Isaac ierr = PetscSectionGetChart(anchorSection,&pStart,&pEnd);CHKERRQ(ierr); 7648a68b90caSToby Isaac ierr = ISGetLocalSize(anchorIS,&size);CHKERRQ(ierr); 7649a68b90caSToby Isaac ierr = ISGetIndices(anchorIS,&anchors);CHKERRQ(ierr); 7650a68b90caSToby Isaac for (a = 0; a < size; a++) { 7651a68b90caSToby Isaac PetscInt p; 7652a68b90caSToby Isaac 7653a68b90caSToby Isaac p = anchors[a]; 7654a68b90caSToby Isaac if (p >= pStart && p < pEnd) { 7655a68b90caSToby Isaac PetscInt dof; 7656a68b90caSToby Isaac 7657a68b90caSToby Isaac ierr = PetscSectionGetDof(anchorSection,p,&dof);CHKERRQ(ierr); 7658a68b90caSToby Isaac if (dof) { 7659a68b90caSToby Isaac PetscErrorCode ierr2; 7660a68b90caSToby Isaac 7661a68b90caSToby Isaac ierr2 = ISRestoreIndices(anchorIS,&anchors);CHKERRQ(ierr2); 76628ccfff9cSToby Isaac SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Point %D cannot be constrained and an anchor",p); 7663a68b90caSToby Isaac } 7664a68b90caSToby Isaac } 7665a68b90caSToby Isaac } 7666a68b90caSToby Isaac ierr = ISRestoreIndices(anchorIS,&anchors);CHKERRQ(ierr); 7667a68b90caSToby Isaac } 7668a68b90caSToby Isaac #endif 7669f7c74593SToby Isaac /* reset the generic constraints */ 7670f7c74593SToby Isaac ierr = DMSetDefaultConstraints(dm,NULL,NULL);CHKERRQ(ierr); 7671a68b90caSToby Isaac PetscFunctionReturn(0); 7672a68b90caSToby Isaac } 7673a68b90caSToby Isaac 7674f7c74593SToby Isaac static PetscErrorCode DMPlexCreateConstraintSection_Anchors(DM dm, PetscSection section, PetscSection *cSec) 7675a68b90caSToby Isaac { 7676f7c74593SToby Isaac PetscSection anchorSection; 76776995de1eSToby Isaac PetscInt pStart, pEnd, sStart, sEnd, p, dof, numFields, f; 7678a68b90caSToby Isaac PetscErrorCode ierr; 7679a68b90caSToby Isaac 7680a68b90caSToby Isaac PetscFunctionBegin; 7681a68b90caSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7682a17985deSToby Isaac ierr = DMPlexGetAnchors(dm,&anchorSection,NULL);CHKERRQ(ierr); 7683e228b242SToby Isaac ierr = PetscSectionCreate(PETSC_COMM_SELF,cSec);CHKERRQ(ierr); 7684a68b90caSToby Isaac ierr = PetscSectionGetNumFields(section,&numFields);CHKERRQ(ierr); 76856995de1eSToby Isaac if (numFields) { 7686719ab38cSToby Isaac PetscInt f; 7687a68b90caSToby Isaac ierr = PetscSectionSetNumFields(*cSec,numFields);CHKERRQ(ierr); 7688719ab38cSToby Isaac 7689719ab38cSToby Isaac for (f = 0; f < numFields; f++) { 7690719ab38cSToby Isaac PetscInt numComp; 7691719ab38cSToby Isaac 7692719ab38cSToby Isaac ierr = PetscSectionGetFieldComponents(section,f,&numComp);CHKERRQ(ierr); 7693719ab38cSToby Isaac ierr = PetscSectionSetFieldComponents(*cSec,f,numComp);CHKERRQ(ierr); 7694719ab38cSToby Isaac } 76956995de1eSToby Isaac } 7696a68b90caSToby Isaac ierr = PetscSectionGetChart(anchorSection,&pStart,&pEnd);CHKERRQ(ierr); 76976995de1eSToby Isaac ierr = PetscSectionGetChart(section,&sStart,&sEnd);CHKERRQ(ierr); 76986995de1eSToby Isaac pStart = PetscMax(pStart,sStart); 76996995de1eSToby Isaac pEnd = PetscMin(pEnd,sEnd); 77006995de1eSToby Isaac pEnd = PetscMax(pStart,pEnd); 7701a68b90caSToby Isaac ierr = PetscSectionSetChart(*cSec,pStart,pEnd);CHKERRQ(ierr); 7702a68b90caSToby Isaac for (p = pStart; p < pEnd; p++) { 7703a68b90caSToby Isaac ierr = PetscSectionGetDof(anchorSection,p,&dof);CHKERRQ(ierr); 7704a68b90caSToby Isaac if (dof) { 7705a68b90caSToby Isaac ierr = PetscSectionGetDof(section,p,&dof);CHKERRQ(ierr); 7706a68b90caSToby Isaac ierr = PetscSectionSetDof(*cSec,p,dof);CHKERRQ(ierr); 7707a68b90caSToby Isaac for (f = 0; f < numFields; f++) { 7708a68b90caSToby Isaac ierr = PetscSectionGetFieldDof(section,p,f,&dof);CHKERRQ(ierr); 7709a68b90caSToby Isaac ierr = PetscSectionSetFieldDof(*cSec,p,f,dof);CHKERRQ(ierr); 7710a68b90caSToby Isaac } 7711a68b90caSToby Isaac } 7712a68b90caSToby Isaac } 7713a68b90caSToby Isaac ierr = PetscSectionSetUp(*cSec);CHKERRQ(ierr); 7714a68b90caSToby Isaac PetscFunctionReturn(0); 7715a68b90caSToby Isaac } 7716a68b90caSToby Isaac 7717f7c74593SToby Isaac static PetscErrorCode DMPlexCreateConstraintMatrix_Anchors(DM dm, PetscSection section, PetscSection cSec, Mat *cMat) 7718a68b90caSToby Isaac { 7719f7c74593SToby Isaac PetscSection aSec; 77200ac89760SToby Isaac PetscInt pStart, pEnd, p, dof, aDof, aOff, off, nnz, annz, m, n, q, a, offset, *i, *j; 77210ac89760SToby Isaac const PetscInt *anchors; 77220ac89760SToby Isaac PetscInt numFields, f; 772366ad2231SToby Isaac IS aIS; 77240ac89760SToby Isaac PetscErrorCode ierr; 77250ac89760SToby Isaac 77260ac89760SToby Isaac PetscFunctionBegin; 77270ac89760SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 77280ac89760SToby Isaac ierr = PetscSectionGetStorageSize(cSec, &m);CHKERRQ(ierr); 77290ac89760SToby Isaac ierr = PetscSectionGetStorageSize(section, &n);CHKERRQ(ierr); 77300ac89760SToby Isaac ierr = MatCreate(PETSC_COMM_SELF,cMat);CHKERRQ(ierr); 77310ac89760SToby Isaac ierr = MatSetSizes(*cMat,m,n,m,n);CHKERRQ(ierr); 7732302440fdSBarry Smith ierr = MatSetType(*cMat,MATSEQAIJ);CHKERRQ(ierr); 7733a17985deSToby Isaac ierr = DMPlexGetAnchors(dm,&aSec,&aIS);CHKERRQ(ierr); 773466ad2231SToby Isaac ierr = ISGetIndices(aIS,&anchors);CHKERRQ(ierr); 77356995de1eSToby Isaac /* cSec will be a subset of aSec and section */ 77366995de1eSToby Isaac ierr = PetscSectionGetChart(cSec,&pStart,&pEnd);CHKERRQ(ierr); 77370ac89760SToby Isaac ierr = PetscMalloc1(m+1,&i);CHKERRQ(ierr); 77380ac89760SToby Isaac i[0] = 0; 77390ac89760SToby Isaac ierr = PetscSectionGetNumFields(section,&numFields);CHKERRQ(ierr); 77400ac89760SToby Isaac for (p = pStart; p < pEnd; p++) { 7741f19733c5SToby Isaac PetscInt rDof, rOff, r; 7742f19733c5SToby Isaac 7743f19733c5SToby Isaac ierr = PetscSectionGetDof(aSec,p,&rDof);CHKERRQ(ierr); 7744f19733c5SToby Isaac if (!rDof) continue; 7745f19733c5SToby Isaac ierr = PetscSectionGetOffset(aSec,p,&rOff);CHKERRQ(ierr); 77460ac89760SToby Isaac if (numFields) { 77470ac89760SToby Isaac for (f = 0; f < numFields; f++) { 77480ac89760SToby Isaac annz = 0; 7749f19733c5SToby Isaac for (r = 0; r < rDof; r++) { 7750f19733c5SToby Isaac a = anchors[rOff + r]; 77510ac89760SToby Isaac ierr = PetscSectionGetFieldDof(section,a,f,&aDof);CHKERRQ(ierr); 77520ac89760SToby Isaac annz += aDof; 77530ac89760SToby Isaac } 77540ac89760SToby Isaac ierr = PetscSectionGetFieldDof(cSec,p,f,&dof);CHKERRQ(ierr); 77550ac89760SToby Isaac ierr = PetscSectionGetFieldOffset(cSec,p,f,&off);CHKERRQ(ierr); 77560ac89760SToby Isaac for (q = 0; q < dof; q++) { 77570ac89760SToby Isaac i[off + q + 1] = i[off + q] + annz; 77580ac89760SToby Isaac } 77590ac89760SToby Isaac } 77600ac89760SToby Isaac } 77610ac89760SToby Isaac else { 77620ac89760SToby Isaac annz = 0; 77630ac89760SToby Isaac for (q = 0; q < dof; q++) { 77640ac89760SToby Isaac a = anchors[off + q]; 77650ac89760SToby Isaac ierr = PetscSectionGetDof(section,a,&aDof);CHKERRQ(ierr); 77660ac89760SToby Isaac annz += aDof; 77670ac89760SToby Isaac } 77680ac89760SToby Isaac ierr = PetscSectionGetDof(cSec,p,&dof);CHKERRQ(ierr); 77690ac89760SToby Isaac ierr = PetscSectionGetOffset(cSec,p,&off);CHKERRQ(ierr); 77700ac89760SToby Isaac for (q = 0; q < dof; q++) { 77710ac89760SToby Isaac i[off + q + 1] = i[off + q] + annz; 77720ac89760SToby Isaac } 77730ac89760SToby Isaac } 77740ac89760SToby Isaac } 77750ac89760SToby Isaac nnz = i[m]; 77760ac89760SToby Isaac ierr = PetscMalloc1(nnz,&j);CHKERRQ(ierr); 77770ac89760SToby Isaac offset = 0; 77780ac89760SToby Isaac for (p = pStart; p < pEnd; p++) { 77790ac89760SToby Isaac if (numFields) { 77800ac89760SToby Isaac for (f = 0; f < numFields; f++) { 77810ac89760SToby Isaac ierr = PetscSectionGetFieldDof(cSec,p,f,&dof);CHKERRQ(ierr); 77820ac89760SToby Isaac for (q = 0; q < dof; q++) { 77830ac89760SToby Isaac PetscInt rDof, rOff, r; 77840ac89760SToby Isaac ierr = PetscSectionGetDof(aSec,p,&rDof);CHKERRQ(ierr); 77850ac89760SToby Isaac ierr = PetscSectionGetOffset(aSec,p,&rOff);CHKERRQ(ierr); 77860ac89760SToby Isaac for (r = 0; r < rDof; r++) { 77870ac89760SToby Isaac PetscInt s; 77880ac89760SToby Isaac 77890ac89760SToby Isaac a = anchors[rOff + r]; 77900ac89760SToby Isaac ierr = PetscSectionGetFieldDof(section,a,f,&aDof);CHKERRQ(ierr); 77910ac89760SToby Isaac ierr = PetscSectionGetFieldOffset(section,a,f,&aOff);CHKERRQ(ierr); 77920ac89760SToby Isaac for (s = 0; s < aDof; s++) { 77930ac89760SToby Isaac j[offset++] = aOff + s; 77940ac89760SToby Isaac } 77950ac89760SToby Isaac } 77960ac89760SToby Isaac } 77970ac89760SToby Isaac } 77980ac89760SToby Isaac } 77990ac89760SToby Isaac else { 78000ac89760SToby Isaac ierr = PetscSectionGetDof(cSec,p,&dof);CHKERRQ(ierr); 78010ac89760SToby Isaac for (q = 0; q < dof; q++) { 78020ac89760SToby Isaac PetscInt rDof, rOff, r; 78030ac89760SToby Isaac ierr = PetscSectionGetDof(aSec,p,&rDof);CHKERRQ(ierr); 78040ac89760SToby Isaac ierr = PetscSectionGetOffset(aSec,p,&rOff);CHKERRQ(ierr); 78050ac89760SToby Isaac for (r = 0; r < rDof; r++) { 78060ac89760SToby Isaac PetscInt s; 78070ac89760SToby Isaac 78080ac89760SToby Isaac a = anchors[rOff + r]; 78090ac89760SToby Isaac ierr = PetscSectionGetDof(section,a,&aDof);CHKERRQ(ierr); 78100ac89760SToby Isaac ierr = PetscSectionGetOffset(section,a,&aOff);CHKERRQ(ierr); 78110ac89760SToby Isaac for (s = 0; s < aDof; s++) { 78120ac89760SToby Isaac j[offset++] = aOff + s; 78130ac89760SToby Isaac } 78140ac89760SToby Isaac } 78150ac89760SToby Isaac } 78160ac89760SToby Isaac } 78170ac89760SToby Isaac } 78180ac89760SToby Isaac ierr = MatSeqAIJSetPreallocationCSR(*cMat,i,j,NULL);CHKERRQ(ierr); 781925570a81SToby Isaac ierr = PetscFree(i);CHKERRQ(ierr); 782025570a81SToby Isaac ierr = PetscFree(j);CHKERRQ(ierr); 782166ad2231SToby Isaac ierr = ISRestoreIndices(aIS,&anchors);CHKERRQ(ierr); 78220ac89760SToby Isaac PetscFunctionReturn(0); 78230ac89760SToby Isaac } 78240ac89760SToby Isaac 782566ad2231SToby Isaac PetscErrorCode DMCreateDefaultConstraints_Plex(DM dm) 782666ad2231SToby Isaac { 7827f7c74593SToby Isaac DM_Plex *plex = (DM_Plex *)dm->data; 7828f7c74593SToby Isaac PetscSection anchorSection, section, cSec; 782966ad2231SToby Isaac Mat cMat; 783066ad2231SToby Isaac PetscErrorCode ierr; 783166ad2231SToby Isaac 783266ad2231SToby Isaac PetscFunctionBegin; 783366ad2231SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7834a17985deSToby Isaac ierr = DMPlexGetAnchors(dm,&anchorSection,NULL);CHKERRQ(ierr); 783566ad2231SToby Isaac if (anchorSection) { 783644a7f3ddSMatthew G. Knepley PetscInt Nf; 7837e228b242SToby Isaac 783892fd8e1eSJed Brown ierr = DMGetLocalSection(dm,§ion);CHKERRQ(ierr); 7839f7c74593SToby Isaac ierr = DMPlexCreateConstraintSection_Anchors(dm,section,&cSec);CHKERRQ(ierr); 7840f7c74593SToby Isaac ierr = DMPlexCreateConstraintMatrix_Anchors(dm,section,cSec,&cMat);CHKERRQ(ierr); 784144a7f3ddSMatthew G. Knepley ierr = DMGetNumFields(dm,&Nf);CHKERRQ(ierr); 784244a7f3ddSMatthew G. Knepley if (Nf && plex->computeanchormatrix) {ierr = (*plex->computeanchormatrix)(dm,section,cSec,cMat);CHKERRQ(ierr);} 784366ad2231SToby Isaac ierr = DMSetDefaultConstraints(dm,cSec,cMat);CHKERRQ(ierr); 784466ad2231SToby Isaac ierr = PetscSectionDestroy(&cSec);CHKERRQ(ierr); 784566ad2231SToby Isaac ierr = MatDestroy(&cMat);CHKERRQ(ierr); 784666ad2231SToby Isaac } 784766ad2231SToby Isaac PetscFunctionReturn(0); 784866ad2231SToby Isaac } 7849a93c429eSMatthew G. Knepley 7850a93c429eSMatthew G. Knepley PetscErrorCode DMCreateSubDomainDM_Plex(DM dm, DMLabel label, PetscInt value, IS *is, DM *subdm) 7851a93c429eSMatthew G. Knepley { 7852a93c429eSMatthew G. Knepley IS subis; 7853a93c429eSMatthew G. Knepley PetscSection section, subsection; 7854a93c429eSMatthew G. Knepley PetscErrorCode ierr; 7855a93c429eSMatthew G. Knepley 7856a93c429eSMatthew G. Knepley PetscFunctionBegin; 785792fd8e1eSJed Brown ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr); 7858a93c429eSMatthew G. Knepley if (!section) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Must set default section for DM before splitting subdomain"); 7859a93c429eSMatthew G. Knepley if (!subdm) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Must set output subDM for splitting subdomain"); 7860a93c429eSMatthew G. Knepley /* Create subdomain */ 7861a93c429eSMatthew G. Knepley ierr = DMPlexFilter(dm, label, value, subdm);CHKERRQ(ierr); 7862a93c429eSMatthew G. Knepley /* Create submodel */ 7863a93c429eSMatthew G. Knepley ierr = DMPlexCreateSubpointIS(*subdm, &subis);CHKERRQ(ierr); 7864a93c429eSMatthew G. Knepley ierr = PetscSectionCreateSubmeshSection(section, subis, &subsection);CHKERRQ(ierr); 7865a93c429eSMatthew G. Knepley ierr = ISDestroy(&subis);CHKERRQ(ierr); 786692fd8e1eSJed Brown ierr = DMSetLocalSection(*subdm, subsection);CHKERRQ(ierr); 7867a93c429eSMatthew G. Knepley ierr = PetscSectionDestroy(&subsection);CHKERRQ(ierr); 7868e5e52638SMatthew G. Knepley ierr = DMCopyDisc(dm, *subdm);CHKERRQ(ierr); 7869a93c429eSMatthew G. Knepley /* Create map from submodel to global model */ 7870a93c429eSMatthew G. Knepley if (is) { 7871a93c429eSMatthew G. Knepley PetscSection sectionGlobal, subsectionGlobal; 7872a93c429eSMatthew G. Knepley IS spIS; 7873a93c429eSMatthew G. Knepley const PetscInt *spmap; 7874a93c429eSMatthew G. Knepley PetscInt *subIndices; 7875a93c429eSMatthew G. Knepley PetscInt subSize = 0, subOff = 0, pStart, pEnd, p; 7876a93c429eSMatthew G. Knepley PetscInt Nf, f, bs = -1, bsLocal[2], bsMinMax[2]; 7877a93c429eSMatthew G. Knepley 7878a93c429eSMatthew G. Knepley ierr = DMPlexCreateSubpointIS(*subdm, &spIS);CHKERRQ(ierr); 7879a93c429eSMatthew G. Knepley ierr = ISGetIndices(spIS, &spmap);CHKERRQ(ierr); 7880a93c429eSMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &Nf);CHKERRQ(ierr); 78816f0eb057SJed Brown ierr = DMGetGlobalSection(dm, §ionGlobal);CHKERRQ(ierr); 78826f0eb057SJed Brown ierr = DMGetGlobalSection(*subdm, &subsectionGlobal);CHKERRQ(ierr); 7883a93c429eSMatthew G. Knepley ierr = PetscSectionGetChart(subsection, &pStart, &pEnd);CHKERRQ(ierr); 7884a93c429eSMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 7885a93c429eSMatthew G. Knepley PetscInt gdof, pSubSize = 0; 7886a93c429eSMatthew G. Knepley 7887a93c429eSMatthew G. Knepley ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr); 7888a93c429eSMatthew G. Knepley if (gdof > 0) { 7889a93c429eSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 7890a93c429eSMatthew G. Knepley PetscInt fdof, fcdof; 7891a93c429eSMatthew G. Knepley 7892a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldDof(subsection, p, f, &fdof);CHKERRQ(ierr); 7893a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldConstraintDof(subsection, p, f, &fcdof);CHKERRQ(ierr); 7894a93c429eSMatthew G. Knepley pSubSize += fdof-fcdof; 7895a93c429eSMatthew G. Knepley } 7896a93c429eSMatthew G. Knepley subSize += pSubSize; 7897a93c429eSMatthew G. Knepley if (pSubSize) { 7898a93c429eSMatthew G. Knepley if (bs < 0) { 7899a93c429eSMatthew G. Knepley bs = pSubSize; 7900a93c429eSMatthew G. Knepley } else if (bs != pSubSize) { 7901a93c429eSMatthew G. Knepley /* Layout does not admit a pointwise block size */ 7902a93c429eSMatthew G. Knepley bs = 1; 7903a93c429eSMatthew G. Knepley } 7904a93c429eSMatthew G. Knepley } 7905a93c429eSMatthew G. Knepley } 7906a93c429eSMatthew G. Knepley } 7907a93c429eSMatthew G. Knepley /* Must have same blocksize on all procs (some might have no points) */ 7908a93c429eSMatthew G. Knepley bsLocal[0] = bs < 0 ? PETSC_MAX_INT : bs; bsLocal[1] = bs; 7909a93c429eSMatthew G. Knepley ierr = PetscGlobalMinMaxInt(PetscObjectComm((PetscObject) dm), bsLocal, bsMinMax);CHKERRQ(ierr); 7910a93c429eSMatthew G. Knepley if (bsMinMax[0] != bsMinMax[1]) {bs = 1;} 7911a93c429eSMatthew G. Knepley else {bs = bsMinMax[0];} 7912a93c429eSMatthew G. Knepley ierr = PetscMalloc1(subSize, &subIndices);CHKERRQ(ierr); 7913a93c429eSMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 7914a93c429eSMatthew G. Knepley PetscInt gdof, goff; 7915a93c429eSMatthew G. Knepley 7916a93c429eSMatthew G. Knepley ierr = PetscSectionGetDof(subsectionGlobal, p, &gdof);CHKERRQ(ierr); 7917a93c429eSMatthew G. Knepley if (gdof > 0) { 7918a93c429eSMatthew G. Knepley const PetscInt point = spmap[p]; 7919a93c429eSMatthew G. Knepley 7920a93c429eSMatthew G. Knepley ierr = PetscSectionGetOffset(sectionGlobal, point, &goff);CHKERRQ(ierr); 7921a93c429eSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 7922a93c429eSMatthew G. Knepley PetscInt fdof, fcdof, fc, f2, poff = 0; 7923a93c429eSMatthew G. Knepley 7924a93c429eSMatthew G. Knepley /* Can get rid of this loop by storing field information in the global section */ 7925a93c429eSMatthew G. Knepley for (f2 = 0; f2 < f; ++f2) { 7926a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, p, f2, &fdof);CHKERRQ(ierr); 7927a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldConstraintDof(section, p, f2, &fcdof);CHKERRQ(ierr); 7928a93c429eSMatthew G. Knepley poff += fdof-fcdof; 7929a93c429eSMatthew G. Knepley } 7930a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr); 7931a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr); 7932a93c429eSMatthew G. Knepley for (fc = 0; fc < fdof-fcdof; ++fc, ++subOff) { 7933a93c429eSMatthew G. Knepley subIndices[subOff] = goff+poff+fc; 7934a93c429eSMatthew G. Knepley } 7935a93c429eSMatthew G. Knepley } 7936a93c429eSMatthew G. Knepley } 7937a93c429eSMatthew G. Knepley } 7938a93c429eSMatthew G. Knepley ierr = ISRestoreIndices(spIS, &spmap);CHKERRQ(ierr); 7939a93c429eSMatthew G. Knepley ierr = ISDestroy(&spIS);CHKERRQ(ierr); 7940a93c429eSMatthew G. Knepley ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), subSize, subIndices, PETSC_OWN_POINTER, is);CHKERRQ(ierr); 7941a93c429eSMatthew G. Knepley if (bs > 1) { 7942a93c429eSMatthew G. Knepley /* We need to check that the block size does not come from non-contiguous fields */ 7943a93c429eSMatthew G. Knepley PetscInt i, j, set = 1; 7944a93c429eSMatthew G. Knepley for (i = 0; i < subSize; i += bs) { 7945a93c429eSMatthew G. Knepley for (j = 0; j < bs; ++j) { 7946a93c429eSMatthew G. Knepley if (subIndices[i+j] != subIndices[i]+j) {set = 0; break;} 7947a93c429eSMatthew G. Knepley } 7948a93c429eSMatthew G. Knepley } 7949a93c429eSMatthew G. Knepley if (set) {ierr = ISSetBlockSize(*is, bs);CHKERRQ(ierr);} 7950a93c429eSMatthew G. Knepley } 7951a93c429eSMatthew G. Knepley /* Attach nullspace */ 7952a93c429eSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 7953a93c429eSMatthew G. Knepley (*subdm)->nullspaceConstructors[f] = dm->nullspaceConstructors[f]; 7954a93c429eSMatthew G. Knepley if ((*subdm)->nullspaceConstructors[f]) break; 7955a93c429eSMatthew G. Knepley } 7956a93c429eSMatthew G. Knepley if (f < Nf) { 7957a93c429eSMatthew G. Knepley MatNullSpace nullSpace; 7958a93c429eSMatthew G. Knepley 7959a93c429eSMatthew G. Knepley ierr = (*(*subdm)->nullspaceConstructors[f])(*subdm, f, &nullSpace);CHKERRQ(ierr); 7960a93c429eSMatthew G. Knepley ierr = PetscObjectCompose((PetscObject) *is, "nullspace", (PetscObject) nullSpace);CHKERRQ(ierr); 7961a93c429eSMatthew G. Knepley ierr = MatNullSpaceDestroy(&nullSpace);CHKERRQ(ierr); 7962a93c429eSMatthew G. Knepley } 7963a93c429eSMatthew G. Knepley } 7964a93c429eSMatthew G. Knepley PetscFunctionReturn(0); 7965a93c429eSMatthew G. Knepley } 7966