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> 9012bc364SMatthew G. Knepley #include <petscdmplextransform.h> 10552f7358SJed Brown 11552f7358SJed Brown /* Logging support */ 1202f7d72cSksagiyam 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,DMPLEX_LocatePoints,DMPLEX_TopologyView,DMPLEX_LabelsView,DMPLEX_CoordinatesView,DMPLEX_SectionView,DMPLEX_GlobalVectorView,DMPLEX_LocalVectorView,DMPLEX_TopologyLoad,DMPLEX_LabelsLoad,DMPLEX_CoordinatesLoad,DMPLEX_SectionLoad,DMPLEX_GlobalVectorLoad,DMPLEX_LocalVectorLoad; 13552f7358SJed Brown 145a576424SJed Brown PETSC_EXTERN PetscErrorCode VecView_MPI(Vec, PetscViewer); 15552f7358SJed Brown 16e5337592SStefano Zampini /*@ 179318fe57SMatthew G. Knepley DMPlexIsSimplex - Is the first cell in this mesh a simplex? 189318fe57SMatthew G. Knepley 199318fe57SMatthew G. Knepley Input Parameter: 209318fe57SMatthew G. Knepley . dm - The DMPlex object 219318fe57SMatthew G. Knepley 229318fe57SMatthew G. Knepley Output Parameter: 239318fe57SMatthew G. Knepley . simplex - Flag checking for a simplex 249318fe57SMatthew G. Knepley 259318fe57SMatthew G. Knepley Note: This just gives the first range of cells found. If the mesh has several cell types, it will only give the first. 269318fe57SMatthew G. Knepley If the mesh has no cells, this returns PETSC_FALSE. 279318fe57SMatthew G. Knepley 289318fe57SMatthew G. Knepley Level: intermediate 299318fe57SMatthew G. Knepley 309318fe57SMatthew G. Knepley .seealso DMPlexGetSimplexOrBoxCells(), DMPlexGetCellType(), DMPlexGetHeightStratum(), DMPolytopeTypeGetNumVertices() 319318fe57SMatthew G. Knepley @*/ 329318fe57SMatthew G. Knepley PetscErrorCode DMPlexIsSimplex(DM dm, PetscBool *simplex) 339318fe57SMatthew G. Knepley { 349318fe57SMatthew G. Knepley DMPolytopeType ct; 359318fe57SMatthew G. Knepley PetscInt cStart, cEnd; 369318fe57SMatthew G. Knepley PetscErrorCode ierr; 379318fe57SMatthew G. Knepley 389318fe57SMatthew G. Knepley PetscFunctionBegin; 399318fe57SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 409318fe57SMatthew G. Knepley if (cEnd <= cStart) {*simplex = PETSC_FALSE; PetscFunctionReturn(0);} 419318fe57SMatthew G. Knepley ierr = DMPlexGetCellType(dm, cStart, &ct);CHKERRQ(ierr); 429318fe57SMatthew G. Knepley *simplex = DMPolytopeTypeGetNumVertices(ct) == DMPolytopeTypeGetDim(ct)+1 ? PETSC_TRUE : PETSC_FALSE; 439318fe57SMatthew G. Knepley PetscFunctionReturn(0); 449318fe57SMatthew G. Knepley } 459318fe57SMatthew G. Knepley 469318fe57SMatthew G. Knepley /*@ 47412e9a14SMatthew G. Knepley DMPlexGetSimplexOrBoxCells - Get the range of cells which are neither prisms nor ghost FV cells 48e5337592SStefano Zampini 49d8d19677SJose E. Roman Input Parameters: 50412e9a14SMatthew G. Knepley + dm - The DMPlex object 51412e9a14SMatthew G. Knepley - height - The cell height in the Plex, 0 is the default 52e5337592SStefano Zampini 53e5337592SStefano Zampini Output Parameters: 54412e9a14SMatthew G. Knepley + cStart - The first "normal" cell 55412e9a14SMatthew G. Knepley - cEnd - The upper bound on "normal"" cells 56e5337592SStefano Zampini 57412e9a14SMatthew G. Knepley Note: This just gives the first range of cells found. If the mesh has several cell types, it will only give the first. 58e5337592SStefano Zampini 59412e9a14SMatthew G. Knepley Level: developer 60e5337592SStefano Zampini 618065b584SMatthew Knepley .seealso DMPlexConstructGhostCells(), DMPlexGetGhostCellStratum() 62e5337592SStefano Zampini @*/ 63412e9a14SMatthew G. Knepley PetscErrorCode DMPlexGetSimplexOrBoxCells(DM dm, PetscInt height, PetscInt *cStart, PetscInt *cEnd) 64e5337592SStefano Zampini { 65412e9a14SMatthew G. Knepley DMPolytopeType ct = DM_POLYTOPE_UNKNOWN; 66412e9a14SMatthew G. Knepley PetscInt cS, cE, c; 67e5337592SStefano Zampini PetscErrorCode ierr; 68e5337592SStefano Zampini 69e5337592SStefano Zampini PetscFunctionBegin; 70412e9a14SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, PetscMax(height, 0), &cS, &cE);CHKERRQ(ierr); 71412e9a14SMatthew G. Knepley for (c = cS; c < cE; ++c) { 72412e9a14SMatthew G. Knepley DMPolytopeType cct; 73412e9a14SMatthew G. Knepley 74412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, c, &cct);CHKERRQ(ierr); 75412e9a14SMatthew G. Knepley if ((PetscInt) cct < 0) break; 76412e9a14SMatthew G. Knepley switch (cct) { 77ba2698f1SMatthew G. Knepley case DM_POLYTOPE_POINT: 78ba2698f1SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 79ba2698f1SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 80ba2698f1SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 81ba2698f1SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 82ba2698f1SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 83412e9a14SMatthew G. Knepley ct = cct; 84e5337592SStefano Zampini break; 85412e9a14SMatthew G. Knepley default: break; 86e5337592SStefano Zampini } 87412e9a14SMatthew G. Knepley if (ct != DM_POLYTOPE_UNKNOWN) break; 88e5337592SStefano Zampini } 89412e9a14SMatthew G. Knepley if (ct != DM_POLYTOPE_UNKNOWN) { 90412e9a14SMatthew G. Knepley DMLabel ctLabel; 91412e9a14SMatthew G. Knepley 92412e9a14SMatthew G. Knepley ierr = DMPlexGetCellTypeLabel(dm, &ctLabel);CHKERRQ(ierr); 93412e9a14SMatthew G. Knepley ierr = DMLabelGetStratumBounds(ctLabel, ct, &cS, &cE);CHKERRQ(ierr); 94e5337592SStefano Zampini } 95412e9a14SMatthew G. Knepley if (cStart) *cStart = cS; 96412e9a14SMatthew G. Knepley if (cEnd) *cEnd = cE; 97e5337592SStefano Zampini PetscFunctionReturn(0); 98e5337592SStefano Zampini } 99e5337592SStefano Zampini 1007afe7537SMatthew G. Knepley PetscErrorCode DMPlexGetFieldType_Internal(DM dm, PetscSection section, PetscInt field, PetscInt *sStart, PetscInt *sEnd, PetscViewerVTKFieldType *ft) 1017e42fee7SMatthew G. Knepley { 102412e9a14SMatthew G. Knepley PetscInt cdim, pStart, pEnd, vStart, vEnd, cStart, cEnd; 103a99a26bcSAdrian Croucher PetscInt vcdof[2] = {0,0}, globalvcdof[2]; 1047e42fee7SMatthew G. Knepley PetscErrorCode ierr; 1057e42fee7SMatthew G. Knepley 1067e42fee7SMatthew G. Knepley PetscFunctionBegin; 107e630c359SToby Isaac *ft = PETSC_VTK_INVALID; 108f094498dSMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr); 1097e42fee7SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 110412e9a14SMatthew G. Knepley ierr = DMPlexGetSimplexOrBoxCells(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 1117e42fee7SMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 1127e42fee7SMatthew G. Knepley if (field >= 0) { 113a99a26bcSAdrian Croucher if ((vStart >= pStart) && (vStart < pEnd)) {ierr = PetscSectionGetFieldDof(section, vStart, field, &vcdof[0]);CHKERRQ(ierr);} 114a99a26bcSAdrian Croucher if ((cStart >= pStart) && (cStart < pEnd)) {ierr = PetscSectionGetFieldDof(section, cStart, field, &vcdof[1]);CHKERRQ(ierr);} 1157e42fee7SMatthew G. Knepley } else { 116a99a26bcSAdrian Croucher if ((vStart >= pStart) && (vStart < pEnd)) {ierr = PetscSectionGetDof(section, vStart, &vcdof[0]);CHKERRQ(ierr);} 117a99a26bcSAdrian Croucher if ((cStart >= pStart) && (cStart < pEnd)) {ierr = PetscSectionGetDof(section, cStart, &vcdof[1]);CHKERRQ(ierr);} 1187e42fee7SMatthew G. Knepley } 119ffc4695bSBarry Smith ierr = MPI_Allreduce(vcdof, globalvcdof, 2, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject)dm));CHKERRMPI(ierr); 120a99a26bcSAdrian Croucher if (globalvcdof[0]) { 1217e42fee7SMatthew G. Knepley *sStart = vStart; 1227e42fee7SMatthew G. Knepley *sEnd = vEnd; 123f094498dSMatthew G. Knepley if (globalvcdof[0] == cdim) *ft = PETSC_VTK_POINT_VECTOR_FIELD; 1247e42fee7SMatthew G. Knepley else *ft = PETSC_VTK_POINT_FIELD; 125a99a26bcSAdrian Croucher } else if (globalvcdof[1]) { 1267e42fee7SMatthew G. Knepley *sStart = cStart; 1277e42fee7SMatthew G. Knepley *sEnd = cEnd; 128f094498dSMatthew G. Knepley if (globalvcdof[1] == cdim) *ft = PETSC_VTK_CELL_VECTOR_FIELD; 1297e42fee7SMatthew G. Knepley else *ft = PETSC_VTK_CELL_FIELD; 130e630c359SToby Isaac } else { 131e630c359SToby Isaac if (field >= 0) { 132e630c359SToby Isaac const char *fieldname; 133e630c359SToby Isaac 134e630c359SToby Isaac ierr = PetscSectionGetFieldName(section, field, &fieldname);CHKERRQ(ierr); 1357d3de750SJacob Faibussowitsch ierr = PetscInfo((PetscObject) dm, "Could not classify VTK output type of section field %D \"%s\"\n", field, fieldname);CHKERRQ(ierr); 136e630c359SToby Isaac } else { 1376823f3c5SBlaise Bourdin ierr = PetscInfo((PetscObject) dm, "Could not classify VTK output type of section\"%s\"\n");CHKERRQ(ierr); 138e630c359SToby Isaac } 139e630c359SToby Isaac } 1407e42fee7SMatthew G. Knepley PetscFunctionReturn(0); 1417e42fee7SMatthew G. Knepley } 1427e42fee7SMatthew G. Knepley 1437cd05799SMatthew G. Knepley static PetscErrorCode VecView_Plex_Local_Draw(Vec v, PetscViewer viewer) 144e412dcbdSMatthew G. Knepley { 145e412dcbdSMatthew G. Knepley DM dm; 146d1df6f1dSMatthew G. Knepley PetscSection s; 147e412dcbdSMatthew G. Knepley PetscDraw draw, popup; 148e412dcbdSMatthew G. Knepley DM cdm; 149e412dcbdSMatthew G. Knepley PetscSection coordSection; 150e412dcbdSMatthew G. Knepley Vec coordinates; 151e412dcbdSMatthew G. Knepley const PetscScalar *coords, *array; 152e412dcbdSMatthew G. Knepley PetscReal bound[4] = {PETSC_MAX_REAL, PETSC_MAX_REAL, PETSC_MIN_REAL, PETSC_MIN_REAL}; 153339e3443SMatthew G. Knepley PetscReal vbound[2], time; 154339e3443SMatthew G. Knepley PetscBool isnull, flg; 155d1df6f1dSMatthew G. Knepley PetscInt dim, Nf, f, Nc, comp, vStart, vEnd, cStart, cEnd, c, N, level, step, w = 0; 156e412dcbdSMatthew G. Knepley const char *name; 157339e3443SMatthew G. Knepley char title[PETSC_MAX_PATH_LEN]; 158e412dcbdSMatthew G. Knepley PetscErrorCode ierr; 159e412dcbdSMatthew G. Knepley 160e412dcbdSMatthew G. Knepley PetscFunctionBegin; 161d1df6f1dSMatthew G. Knepley ierr = PetscViewerDrawGetDraw(viewer, 0, &draw);CHKERRQ(ierr); 162d1df6f1dSMatthew G. Knepley ierr = PetscDrawIsNull(draw, &isnull);CHKERRQ(ierr); 163d1df6f1dSMatthew G. Knepley if (isnull) PetscFunctionReturn(0); 164d1df6f1dSMatthew G. Knepley 165e412dcbdSMatthew G. Knepley ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 166e412dcbdSMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dim);CHKERRQ(ierr); 1672c71b3e2SJacob Faibussowitsch PetscCheckFalse(dim != 2,PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Cannot draw meshes of dimension %D. Use PETSCVIEWERGLVIS", dim); 16892fd8e1eSJed Brown ierr = DMGetLocalSection(dm, &s);CHKERRQ(ierr); 169d1df6f1dSMatthew G. Knepley ierr = PetscSectionGetNumFields(s, &Nf);CHKERRQ(ierr); 170e412dcbdSMatthew G. Knepley ierr = DMGetCoarsenLevel(dm, &level);CHKERRQ(ierr); 171e412dcbdSMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 17292fd8e1eSJed Brown ierr = DMGetLocalSection(cdm, &coordSection);CHKERRQ(ierr); 173e412dcbdSMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 174e412dcbdSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 175e412dcbdSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 176e412dcbdSMatthew G. Knepley 177e412dcbdSMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) v, &name);CHKERRQ(ierr); 178339e3443SMatthew G. Knepley ierr = DMGetOutputSequenceNumber(dm, &step, &time);CHKERRQ(ierr); 179e412dcbdSMatthew G. Knepley 180e412dcbdSMatthew G. Knepley ierr = VecGetLocalSize(coordinates, &N);CHKERRQ(ierr); 181e412dcbdSMatthew G. Knepley ierr = VecGetArrayRead(coordinates, &coords);CHKERRQ(ierr); 182e412dcbdSMatthew G. Knepley for (c = 0; c < N; c += dim) { 1830c81f2a8SMatthew G. Knepley bound[0] = PetscMin(bound[0], PetscRealPart(coords[c])); bound[2] = PetscMax(bound[2], PetscRealPart(coords[c])); 1840c81f2a8SMatthew G. Knepley bound[1] = PetscMin(bound[1], PetscRealPart(coords[c+1])); bound[3] = PetscMax(bound[3], PetscRealPart(coords[c+1])); 185e412dcbdSMatthew G. Knepley } 186e412dcbdSMatthew G. Knepley ierr = VecRestoreArrayRead(coordinates, &coords);CHKERRQ(ierr); 187e412dcbdSMatthew G. Knepley ierr = PetscDrawClear(draw);CHKERRQ(ierr); 188e412dcbdSMatthew G. Knepley 189d1df6f1dSMatthew G. Knepley /* Could implement something like DMDASelectFields() */ 190d1df6f1dSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 191d1df6f1dSMatthew G. Knepley DM fdm = dm; 192d1df6f1dSMatthew G. Knepley Vec fv = v; 193d1df6f1dSMatthew G. Knepley IS fis; 194d1df6f1dSMatthew G. Knepley char prefix[PETSC_MAX_PATH_LEN]; 195d1df6f1dSMatthew G. Knepley const char *fname; 196d1df6f1dSMatthew G. Knepley 197d1df6f1dSMatthew G. Knepley ierr = PetscSectionGetFieldComponents(s, f, &Nc);CHKERRQ(ierr); 198d1df6f1dSMatthew G. Knepley ierr = PetscSectionGetFieldName(s, f, &fname);CHKERRQ(ierr); 199d1df6f1dSMatthew G. Knepley 200a126751eSBarry Smith if (v->hdr.prefix) {ierr = PetscStrncpy(prefix, v->hdr.prefix,sizeof(prefix));CHKERRQ(ierr);} 201d1df6f1dSMatthew G. Knepley else {prefix[0] = '\0';} 202d1df6f1dSMatthew G. Knepley if (Nf > 1) { 203d1df6f1dSMatthew G. Knepley ierr = DMCreateSubDM(dm, 1, &f, &fis, &fdm);CHKERRQ(ierr); 204d1df6f1dSMatthew G. Knepley ierr = VecGetSubVector(v, fis, &fv);CHKERRQ(ierr); 205a126751eSBarry Smith ierr = PetscStrlcat(prefix, fname,sizeof(prefix));CHKERRQ(ierr); 206a126751eSBarry Smith ierr = PetscStrlcat(prefix, "_",sizeof(prefix));CHKERRQ(ierr); 207d1df6f1dSMatthew G. Knepley } 208d1df6f1dSMatthew G. Knepley for (comp = 0; comp < Nc; ++comp, ++w) { 209d1df6f1dSMatthew G. Knepley PetscInt nmax = 2; 210d1df6f1dSMatthew G. Knepley 211d1df6f1dSMatthew G. Knepley ierr = PetscViewerDrawGetDraw(viewer, w, &draw);CHKERRQ(ierr); 212d1df6f1dSMatthew G. Knepley if (Nc > 1) {ierr = PetscSNPrintf(title, sizeof(title), "%s:%s_%D Step: %D Time: %.4g", name, fname, comp, step, time);CHKERRQ(ierr);} 213d1df6f1dSMatthew G. Knepley else {ierr = PetscSNPrintf(title, sizeof(title), "%s:%s Step: %D Time: %.4g", name, fname, step, time);CHKERRQ(ierr);} 214d1df6f1dSMatthew G. Knepley ierr = PetscDrawSetTitle(draw, title);CHKERRQ(ierr); 215d1df6f1dSMatthew G. Knepley 216d1df6f1dSMatthew G. Knepley /* TODO Get max and min only for this component */ 217d1df6f1dSMatthew G. Knepley ierr = PetscOptionsGetRealArray(NULL, prefix, "-vec_view_bounds", vbound, &nmax, &flg);CHKERRQ(ierr); 218339e3443SMatthew G. Knepley if (!flg) { 219d1df6f1dSMatthew G. Knepley ierr = VecMin(fv, NULL, &vbound[0]);CHKERRQ(ierr); 220d1df6f1dSMatthew G. Knepley ierr = VecMax(fv, NULL, &vbound[1]);CHKERRQ(ierr); 221d1df6f1dSMatthew G. Knepley if (vbound[1] <= vbound[0]) vbound[1] = vbound[0] + 1.0; 222339e3443SMatthew G. Knepley } 223e412dcbdSMatthew G. Knepley ierr = PetscDrawGetPopup(draw, &popup);CHKERRQ(ierr); 224339e3443SMatthew G. Knepley ierr = PetscDrawScalePopup(popup, vbound[0], vbound[1]);CHKERRQ(ierr); 225d1df6f1dSMatthew G. Knepley ierr = PetscDrawSetCoordinates(draw, bound[0], bound[1], bound[2], bound[3]);CHKERRQ(ierr); 226e412dcbdSMatthew G. Knepley 227d1df6f1dSMatthew G. Knepley ierr = VecGetArrayRead(fv, &array);CHKERRQ(ierr); 228e412dcbdSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 22999a2f7bcSMatthew G. Knepley PetscScalar *coords = NULL, *a = NULL; 230e56f9228SJed Brown PetscInt numCoords, color[4] = {-1,-1,-1,-1}; 231e412dcbdSMatthew G. Knepley 232d1df6f1dSMatthew G. Knepley ierr = DMPlexPointLocalRead(fdm, c, array, &a);CHKERRQ(ierr); 233339e3443SMatthew G. Knepley if (a) { 234d1df6f1dSMatthew G. Knepley color[0] = PetscDrawRealToColor(PetscRealPart(a[comp]), vbound[0], vbound[1]); 235339e3443SMatthew G. Knepley color[1] = color[2] = color[3] = color[0]; 236339e3443SMatthew G. Knepley } else { 237339e3443SMatthew G. Knepley PetscScalar *vals = NULL; 238339e3443SMatthew G. Knepley PetscInt numVals, va; 239339e3443SMatthew G. Knepley 240d1df6f1dSMatthew G. Knepley ierr = DMPlexVecGetClosure(fdm, NULL, fv, c, &numVals, &vals);CHKERRQ(ierr); 2412c71b3e2SJacob Faibussowitsch PetscCheckFalse(numVals % Nc,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); 242d1df6f1dSMatthew G. Knepley switch (numVals/Nc) { 243d1df6f1dSMatthew G. Knepley case 3: /* P1 Triangle */ 244d1df6f1dSMatthew G. Knepley case 4: /* P1 Quadrangle */ 245d1df6f1dSMatthew G. Knepley for (va = 0; va < numVals/Nc; ++va) color[va] = PetscDrawRealToColor(PetscRealPart(vals[va*Nc+comp]), vbound[0], vbound[1]); 246339e3443SMatthew G. Knepley break; 247d1df6f1dSMatthew G. Knepley case 6: /* P2 Triangle */ 248d1df6f1dSMatthew G. Knepley case 8: /* P2 Quadrangle */ 249d1df6f1dSMatthew 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]); 250d1df6f1dSMatthew G. Knepley break; 25198921bdaSJacob Faibussowitsch default: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Number of values for cell closure %D cannot be handled", numVals/Nc); 252339e3443SMatthew G. Knepley } 253d1df6f1dSMatthew G. Knepley ierr = DMPlexVecRestoreClosure(fdm, NULL, fv, c, &numVals, &vals);CHKERRQ(ierr); 254339e3443SMatthew G. Knepley } 255e412dcbdSMatthew G. Knepley ierr = DMPlexVecGetClosure(dm, coordSection, coordinates, c, &numCoords, &coords);CHKERRQ(ierr); 256e412dcbdSMatthew G. Knepley switch (numCoords) { 257e412dcbdSMatthew G. Knepley case 6: 2589edc3542SMatthew Knepley case 12: /* Localized triangle */ 259339e3443SMatthew 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); 260e412dcbdSMatthew G. Knepley break; 261e412dcbdSMatthew G. Knepley case 8: 2629edc3542SMatthew Knepley case 16: /* Localized quadrilateral */ 263339e3443SMatthew 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); 264339e3443SMatthew 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); 265e412dcbdSMatthew G. Knepley break; 26698921bdaSJacob Faibussowitsch default: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot draw cells with %D coordinates", numCoords); 267e412dcbdSMatthew G. Knepley } 268e412dcbdSMatthew G. Knepley ierr = DMPlexVecRestoreClosure(dm, coordSection, coordinates, c, &numCoords, &coords);CHKERRQ(ierr); 269e412dcbdSMatthew G. Knepley } 270d1df6f1dSMatthew G. Knepley ierr = VecRestoreArrayRead(fv, &array);CHKERRQ(ierr); 271e412dcbdSMatthew G. Knepley ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 272e412dcbdSMatthew G. Knepley ierr = PetscDrawPause(draw);CHKERRQ(ierr); 273e412dcbdSMatthew G. Knepley ierr = PetscDrawSave(draw);CHKERRQ(ierr); 274d1df6f1dSMatthew G. Knepley } 275d1df6f1dSMatthew G. Knepley if (Nf > 1) { 276d1df6f1dSMatthew G. Knepley ierr = VecRestoreSubVector(v, fis, &fv);CHKERRQ(ierr); 277d1df6f1dSMatthew G. Knepley ierr = ISDestroy(&fis);CHKERRQ(ierr); 278d1df6f1dSMatthew G. Knepley ierr = DMDestroy(&fdm);CHKERRQ(ierr); 279d1df6f1dSMatthew G. Knepley } 280d1df6f1dSMatthew G. Knepley } 281e412dcbdSMatthew G. Knepley PetscFunctionReturn(0); 282e412dcbdSMatthew G. Knepley } 283e412dcbdSMatthew G. Knepley 284684b87d9SLisandro Dalcin static PetscErrorCode VecView_Plex_Local_VTK(Vec v, PetscViewer viewer) 285684b87d9SLisandro Dalcin { 286684b87d9SLisandro Dalcin DM dm; 287684b87d9SLisandro Dalcin Vec locv; 288684b87d9SLisandro Dalcin const char *name; 289684b87d9SLisandro Dalcin PetscSection section; 290684b87d9SLisandro Dalcin PetscInt pStart, pEnd; 291e630c359SToby Isaac PetscInt numFields; 292684b87d9SLisandro Dalcin PetscViewerVTKFieldType ft; 293684b87d9SLisandro Dalcin PetscErrorCode ierr; 294684b87d9SLisandro Dalcin 295684b87d9SLisandro Dalcin PetscFunctionBegin; 296684b87d9SLisandro Dalcin ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 297684b87d9SLisandro Dalcin ierr = DMCreateLocalVector(dm, &locv);CHKERRQ(ierr); /* VTK viewer requires exclusive ownership of the vector */ 298684b87d9SLisandro Dalcin ierr = PetscObjectGetName((PetscObject) v, &name);CHKERRQ(ierr); 299684b87d9SLisandro Dalcin ierr = PetscObjectSetName((PetscObject) locv, name);CHKERRQ(ierr); 300684b87d9SLisandro Dalcin ierr = VecCopy(v, locv);CHKERRQ(ierr); 30192fd8e1eSJed Brown ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr); 302e630c359SToby Isaac ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 303e630c359SToby Isaac if (!numFields) { 304684b87d9SLisandro Dalcin ierr = DMPlexGetFieldType_Internal(dm, section, PETSC_DETERMINE, &pStart, &pEnd, &ft);CHKERRQ(ierr); 305e630c359SToby Isaac ierr = PetscViewerVTKAddField(viewer, (PetscObject) dm, DMPlexVTKWriteAll, PETSC_DEFAULT, ft, PETSC_TRUE,(PetscObject) locv);CHKERRQ(ierr); 306e630c359SToby Isaac } else { 307e630c359SToby Isaac PetscInt f; 308e630c359SToby Isaac 309e630c359SToby Isaac for (f = 0; f < numFields; f++) { 310e630c359SToby Isaac ierr = DMPlexGetFieldType_Internal(dm, section, f, &pStart, &pEnd, &ft);CHKERRQ(ierr); 311e630c359SToby Isaac if (ft == PETSC_VTK_INVALID) continue; 312e630c359SToby Isaac ierr = PetscObjectReference((PetscObject)locv);CHKERRQ(ierr); 313e630c359SToby Isaac ierr = PetscViewerVTKAddField(viewer, (PetscObject) dm, DMPlexVTKWriteAll, f, ft, PETSC_TRUE,(PetscObject) locv);CHKERRQ(ierr); 314e630c359SToby Isaac } 315e630c359SToby Isaac ierr = VecDestroy(&locv);CHKERRQ(ierr); 316e630c359SToby Isaac } 317684b87d9SLisandro Dalcin PetscFunctionReturn(0); 318684b87d9SLisandro Dalcin } 319684b87d9SLisandro Dalcin 320552f7358SJed Brown PetscErrorCode VecView_Plex_Local(Vec v, PetscViewer viewer) 321552f7358SJed Brown { 322552f7358SJed Brown DM dm; 323684b87d9SLisandro Dalcin PetscBool isvtk, ishdf5, isdraw, isglvis; 324552f7358SJed Brown PetscErrorCode ierr; 325552f7358SJed Brown 326552f7358SJed Brown PetscFunctionBegin; 327552f7358SJed Brown ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 3282c71b3e2SJacob Faibussowitsch PetscCheckFalse(!dm,PetscObjectComm((PetscObject)v), PETSC_ERR_ARG_WRONG, "Vector not generated from a DM"); 329552f7358SJed Brown ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERVTK, &isvtk);CHKERRQ(ierr); 330b136c2c9SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 331f13a32a3SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERDRAW, &isdraw);CHKERRQ(ierr); 3328135c375SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERGLVIS, &isglvis);CHKERRQ(ierr); 333684b87d9SLisandro Dalcin if (isvtk || ishdf5 || isdraw || isglvis) { 334684b87d9SLisandro Dalcin PetscInt i,numFields; 335684b87d9SLisandro Dalcin PetscObject fe; 336ef31f671SMatthew G. Knepley PetscBool fem = PETSC_FALSE; 337684b87d9SLisandro Dalcin Vec locv = v; 338684b87d9SLisandro Dalcin const char *name; 339684b87d9SLisandro Dalcin PetscInt step; 340684b87d9SLisandro Dalcin PetscReal time; 341ef31f671SMatthew G. Knepley 342ef31f671SMatthew G. Knepley ierr = DMGetNumFields(dm, &numFields);CHKERRQ(ierr); 343684b87d9SLisandro Dalcin for (i=0; i<numFields; i++) { 34444a7f3ddSMatthew G. Knepley ierr = DMGetField(dm, i, NULL, &fe);CHKERRQ(ierr); 345684b87d9SLisandro Dalcin if (fe->classid == PETSCFE_CLASSID) { fem = PETSC_TRUE; break; } 346ef31f671SMatthew G. Knepley } 347684b87d9SLisandro Dalcin if (fem) { 348798534f6SMatthew G. Knepley PetscObject isZero; 349798534f6SMatthew G. Knepley 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); 353798534f6SMatthew G. Knepley ierr = PetscObjectQuery((PetscObject) v, "__Vec_bc_zero__", &isZero);CHKERRQ(ierr); 354798534f6SMatthew G. Knepley ierr = PetscObjectCompose((PetscObject) locv, "__Vec_bc_zero__", isZero);CHKERRQ(ierr); 355684b87d9SLisandro Dalcin ierr = VecCopy(v, locv);CHKERRQ(ierr); 356684b87d9SLisandro Dalcin ierr = DMGetOutputSequenceNumber(dm, NULL, &time);CHKERRQ(ierr); 357684b87d9SLisandro Dalcin ierr = DMPlexInsertBoundaryValues(dm, PETSC_TRUE, locv, time, NULL, NULL, NULL);CHKERRQ(ierr); 358ef31f671SMatthew G. Knepley } 359552f7358SJed Brown if (isvtk) { 360684b87d9SLisandro Dalcin ierr = VecView_Plex_Local_VTK(locv, viewer);CHKERRQ(ierr); 361b136c2c9SMatthew G. Knepley } else if (ishdf5) { 362b136c2c9SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 363684b87d9SLisandro Dalcin ierr = VecView_Plex_Local_HDF5_Internal(locv, viewer);CHKERRQ(ierr); 364b136c2c9SMatthew G. Knepley #else 365b136c2c9SMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 366b136c2c9SMatthew G. Knepley #endif 367f13a32a3SMatthew G. Knepley } else if (isdraw) { 368684b87d9SLisandro Dalcin ierr = VecView_Plex_Local_Draw(locv, viewer);CHKERRQ(ierr); 369684b87d9SLisandro Dalcin } else if (isglvis) { 370684b87d9SLisandro Dalcin ierr = DMGetOutputSequenceNumber(dm, &step, NULL);CHKERRQ(ierr); 371684b87d9SLisandro Dalcin ierr = PetscViewerGLVisSetSnapId(viewer, step);CHKERRQ(ierr); 372684b87d9SLisandro Dalcin ierr = VecView_GLVis(locv, viewer);CHKERRQ(ierr); 373684b87d9SLisandro Dalcin } 374798534f6SMatthew G. Knepley if (fem) { 375798534f6SMatthew G. Knepley ierr = PetscObjectCompose((PetscObject) locv, "__Vec_bc_zero__", NULL);CHKERRQ(ierr); 376798534f6SMatthew G. Knepley ierr = DMRestoreLocalVector(dm, &locv);CHKERRQ(ierr); 377798534f6SMatthew G. Knepley } 378552f7358SJed Brown } else { 379684b87d9SLisandro Dalcin PetscBool isseq; 380684b87d9SLisandro Dalcin 381684b87d9SLisandro Dalcin ierr = PetscObjectTypeCompare((PetscObject) v, VECSEQ, &isseq);CHKERRQ(ierr); 38255f2e967SMatthew G. Knepley if (isseq) {ierr = VecView_Seq(v, viewer);CHKERRQ(ierr);} 38355f2e967SMatthew G. Knepley else {ierr = VecView_MPI(v, viewer);CHKERRQ(ierr);} 384552f7358SJed Brown } 385552f7358SJed Brown PetscFunctionReturn(0); 386552f7358SJed Brown } 387552f7358SJed Brown 388552f7358SJed Brown PetscErrorCode VecView_Plex(Vec v, PetscViewer viewer) 389552f7358SJed Brown { 390552f7358SJed Brown DM dm; 3916823f3c5SBlaise Bourdin PetscBool isvtk, ishdf5, isdraw, isglvis, isexodusii; 392552f7358SJed Brown PetscErrorCode ierr; 393552f7358SJed Brown 394552f7358SJed Brown PetscFunctionBegin; 395552f7358SJed Brown ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 3962c71b3e2SJacob Faibussowitsch PetscCheckFalse(!dm,PetscObjectComm((PetscObject)v), PETSC_ERR_ARG_WRONG, "Vector not generated from a DM"); 397552f7358SJed Brown ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERVTK, &isvtk);CHKERRQ(ierr); 39833c3e6b4SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 399e412dcbdSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERDRAW, &isdraw);CHKERRQ(ierr); 4008135c375SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERGLVIS, &isglvis);CHKERRQ(ierr); 4016823f3c5SBlaise Bourdin ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWEREXODUSII, &isexodusii);CHKERRQ(ierr); 402684b87d9SLisandro Dalcin if (isvtk || isdraw || isglvis) { 403552f7358SJed Brown Vec locv; 404798534f6SMatthew G. Knepley PetscObject isZero; 405552f7358SJed Brown const char *name; 406552f7358SJed Brown 407c8dd51e9SBarry Smith ierr = DMGetLocalVector(dm, &locv);CHKERRQ(ierr); 408552f7358SJed Brown ierr = PetscObjectGetName((PetscObject) v, &name);CHKERRQ(ierr); 409552f7358SJed Brown ierr = PetscObjectSetName((PetscObject) locv, name);CHKERRQ(ierr); 410552f7358SJed Brown ierr = DMGlobalToLocalBegin(dm, v, INSERT_VALUES, locv);CHKERRQ(ierr); 411552f7358SJed Brown ierr = DMGlobalToLocalEnd(dm, v, INSERT_VALUES, locv);CHKERRQ(ierr); 412798534f6SMatthew G. Knepley ierr = PetscObjectQuery((PetscObject) v, "__Vec_bc_zero__", &isZero);CHKERRQ(ierr); 413798534f6SMatthew G. Knepley ierr = PetscObjectCompose((PetscObject) locv, "__Vec_bc_zero__", isZero);CHKERRQ(ierr); 414552f7358SJed Brown ierr = VecView_Plex_Local(locv, viewer);CHKERRQ(ierr); 415798534f6SMatthew G. Knepley ierr = PetscObjectCompose((PetscObject) locv, "__Vec_bc_zero__", NULL);CHKERRQ(ierr); 416c8dd51e9SBarry Smith ierr = DMRestoreLocalVector(dm, &locv);CHKERRQ(ierr); 417b136c2c9SMatthew G. Knepley } else if (ishdf5) { 418b136c2c9SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 41939d25373SMatthew G. Knepley ierr = VecView_Plex_HDF5_Internal(v, viewer);CHKERRQ(ierr); 420b136c2c9SMatthew G. Knepley #else 421b136c2c9SMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 422b136c2c9SMatthew G. Knepley #endif 4236823f3c5SBlaise Bourdin } else if (isexodusii) { 4246823f3c5SBlaise Bourdin #if defined(PETSC_HAVE_EXODUSII) 4256823f3c5SBlaise Bourdin ierr = VecView_PlexExodusII_Internal(v, viewer);CHKERRQ(ierr); 4266823f3c5SBlaise Bourdin #else 4276823f3c5SBlaise Bourdin SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "ExodusII not supported in this build.\nPlease reconfigure using --download-exodusii"); 4286823f3c5SBlaise Bourdin #endif 429552f7358SJed Brown } else { 430684b87d9SLisandro Dalcin PetscBool isseq; 431684b87d9SLisandro Dalcin 432684b87d9SLisandro Dalcin ierr = PetscObjectTypeCompare((PetscObject) v, VECSEQ, &isseq);CHKERRQ(ierr); 43355f2e967SMatthew G. Knepley if (isseq) {ierr = VecView_Seq(v, viewer);CHKERRQ(ierr);} 43455f2e967SMatthew G. Knepley else {ierr = VecView_MPI(v, viewer);CHKERRQ(ierr);} 435552f7358SJed Brown } 436552f7358SJed Brown PetscFunctionReturn(0); 437552f7358SJed Brown } 438552f7358SJed Brown 439d930f514SMatthew G. Knepley PetscErrorCode VecView_Plex_Native(Vec originalv, PetscViewer viewer) 440d930f514SMatthew G. Knepley { 441d930f514SMatthew G. Knepley DM dm; 442d930f514SMatthew G. Knepley MPI_Comm comm; 443d930f514SMatthew G. Knepley PetscViewerFormat format; 444d930f514SMatthew G. Knepley Vec v; 445d930f514SMatthew G. Knepley PetscBool isvtk, ishdf5; 446d930f514SMatthew G. Knepley PetscErrorCode ierr; 447d930f514SMatthew G. Knepley 448d930f514SMatthew G. Knepley PetscFunctionBegin; 449d930f514SMatthew G. Knepley ierr = VecGetDM(originalv, &dm);CHKERRQ(ierr); 450d930f514SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject) originalv, &comm);CHKERRQ(ierr); 4512c71b3e2SJacob Faibussowitsch PetscCheckFalse(!dm,comm, PETSC_ERR_ARG_WRONG, "Vector not generated from a DM"); 452d930f514SMatthew G. Knepley ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 453d930f514SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 454d930f514SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERVTK, &isvtk);CHKERRQ(ierr); 455d930f514SMatthew G. Knepley if (format == PETSC_VIEWER_NATIVE) { 456a8ad634aSStefano Zampini /* Natural ordering is the common case for DMDA, NATIVE means plain vector, for PLEX is the opposite */ 457a8ad634aSStefano Zampini /* this need a better fix */ 458a8ad634aSStefano Zampini if (dm->useNatural) { 459a8ad634aSStefano Zampini if (dm->sfNatural) { 460d930f514SMatthew G. Knepley const char *vecname; 461d930f514SMatthew G. Knepley PetscInt n, nroots; 462d930f514SMatthew G. Knepley 463ca43db0aSBarry Smith ierr = VecGetLocalSize(originalv, &n);CHKERRQ(ierr); 464d930f514SMatthew G. Knepley ierr = PetscSFGetGraph(dm->sfNatural, &nroots, NULL, NULL, NULL);CHKERRQ(ierr); 465d930f514SMatthew G. Knepley if (n == nroots) { 466d930f514SMatthew G. Knepley ierr = DMGetGlobalVector(dm, &v);CHKERRQ(ierr); 467d930f514SMatthew G. Knepley ierr = DMPlexGlobalToNaturalBegin(dm, originalv, v);CHKERRQ(ierr); 468d930f514SMatthew G. Knepley ierr = DMPlexGlobalToNaturalEnd(dm, originalv, v);CHKERRQ(ierr); 469d930f514SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) originalv, &vecname);CHKERRQ(ierr); 470d930f514SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) v, vecname);CHKERRQ(ierr); 471d930f514SMatthew G. Knepley } else SETERRQ(comm, PETSC_ERR_ARG_WRONG, "DM global to natural SF only handles global vectors"); 472d930f514SMatthew G. Knepley } else SETERRQ(comm, PETSC_ERR_ARG_WRONGSTATE, "DM global to natural SF was not created"); 473a8ad634aSStefano Zampini } else v = originalv; 474a8ad634aSStefano Zampini } else v = originalv; 475a8ad634aSStefano Zampini 476d930f514SMatthew G. Knepley if (ishdf5) { 477d930f514SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 47839d25373SMatthew G. Knepley ierr = VecView_Plex_HDF5_Native_Internal(v, viewer);CHKERRQ(ierr); 479d930f514SMatthew G. Knepley #else 480d930f514SMatthew G. Knepley SETERRQ(comm, PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 481d930f514SMatthew G. Knepley #endif 482d930f514SMatthew G. Knepley } else if (isvtk) { 483d930f514SMatthew G. Knepley SETERRQ(comm, PETSC_ERR_SUP, "VTK format does not support viewing in natural order. Please switch to HDF5."); 484d930f514SMatthew G. Knepley } else { 485d930f514SMatthew G. Knepley PetscBool isseq; 486d930f514SMatthew G. Knepley 487d930f514SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) v, VECSEQ, &isseq);CHKERRQ(ierr); 488d930f514SMatthew G. Knepley if (isseq) {ierr = VecView_Seq(v, viewer);CHKERRQ(ierr);} 489d930f514SMatthew G. Knepley else {ierr = VecView_MPI(v, viewer);CHKERRQ(ierr);} 490d930f514SMatthew G. Knepley } 491a8ad634aSStefano Zampini if (v != originalv) {ierr = DMRestoreGlobalVector(dm, &v);CHKERRQ(ierr);} 492d930f514SMatthew G. Knepley PetscFunctionReturn(0); 493d930f514SMatthew G. Knepley } 494d930f514SMatthew G. Knepley 4952c40f234SMatthew G. Knepley PetscErrorCode VecLoad_Plex_Local(Vec v, PetscViewer viewer) 4962c40f234SMatthew G. Knepley { 4972c40f234SMatthew G. Knepley DM dm; 4982c40f234SMatthew G. Knepley PetscBool ishdf5; 4992c40f234SMatthew G. Knepley PetscErrorCode ierr; 5002c40f234SMatthew G. Knepley 5012c40f234SMatthew G. Knepley PetscFunctionBegin; 5022c40f234SMatthew G. Knepley ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 5032c71b3e2SJacob Faibussowitsch PetscCheckFalse(!dm,PetscObjectComm((PetscObject)v), PETSC_ERR_ARG_WRONG, "Vector not generated from a DM"); 5042c40f234SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 5052c40f234SMatthew G. Knepley if (ishdf5) { 5062c40f234SMatthew G. Knepley DM dmBC; 5072c40f234SMatthew G. Knepley Vec gv; 5082c40f234SMatthew G. Knepley const char *name; 5092c40f234SMatthew G. Knepley 5102c40f234SMatthew G. Knepley ierr = DMGetOutputDM(dm, &dmBC);CHKERRQ(ierr); 5112c40f234SMatthew G. Knepley ierr = DMGetGlobalVector(dmBC, &gv);CHKERRQ(ierr); 5122c40f234SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) v, &name);CHKERRQ(ierr); 5132c40f234SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) gv, name);CHKERRQ(ierr); 5142c40f234SMatthew G. Knepley ierr = VecLoad_Default(gv, viewer);CHKERRQ(ierr); 5152c40f234SMatthew G. Knepley ierr = DMGlobalToLocalBegin(dmBC, gv, INSERT_VALUES, v);CHKERRQ(ierr); 5162c40f234SMatthew G. Knepley ierr = DMGlobalToLocalEnd(dmBC, gv, INSERT_VALUES, v);CHKERRQ(ierr); 5172c40f234SMatthew G. Knepley ierr = DMRestoreGlobalVector(dmBC, &gv);CHKERRQ(ierr); 5182c40f234SMatthew G. Knepley } else { 5192c40f234SMatthew G. Knepley ierr = VecLoad_Default(v, viewer);CHKERRQ(ierr); 5202c40f234SMatthew G. Knepley } 5212c40f234SMatthew G. Knepley PetscFunctionReturn(0); 5222c40f234SMatthew G. Knepley } 5232c40f234SMatthew G. Knepley 5242c40f234SMatthew G. Knepley PetscErrorCode VecLoad_Plex(Vec v, PetscViewer viewer) 5252c40f234SMatthew G. Knepley { 5262c40f234SMatthew G. Knepley DM dm; 5276823f3c5SBlaise Bourdin PetscBool ishdf5,isexodusii; 5282c40f234SMatthew G. Knepley PetscErrorCode ierr; 5292c40f234SMatthew G. Knepley 5302c40f234SMatthew G. Knepley PetscFunctionBegin; 5312c40f234SMatthew G. Knepley ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 5322c71b3e2SJacob Faibussowitsch PetscCheckFalse(!dm,PetscObjectComm((PetscObject)v), PETSC_ERR_ARG_WRONG, "Vector not generated from a DM"); 5332c40f234SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 5346823f3c5SBlaise Bourdin ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWEREXODUSII, &isexodusii);CHKERRQ(ierr); 5352c40f234SMatthew G. Knepley if (ishdf5) { 536878b459fSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 53739d25373SMatthew G. Knepley ierr = VecLoad_Plex_HDF5_Internal(v, viewer);CHKERRQ(ierr); 538b136c2c9SMatthew G. Knepley #else 539b136c2c9SMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 540878b459fSMatthew G. Knepley #endif 5416823f3c5SBlaise Bourdin } else if (isexodusii) { 5426823f3c5SBlaise Bourdin #if defined(PETSC_HAVE_EXODUSII) 5436823f3c5SBlaise Bourdin ierr = VecLoad_PlexExodusII_Internal(v, viewer);CHKERRQ(ierr); 5446823f3c5SBlaise Bourdin #else 5456823f3c5SBlaise Bourdin SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "ExodusII not supported in this build.\nPlease reconfigure using --download-exodusii"); 5466823f3c5SBlaise Bourdin #endif 5472c40f234SMatthew G. Knepley } else { 5482c40f234SMatthew G. Knepley ierr = VecLoad_Default(v, viewer);CHKERRQ(ierr); 549552f7358SJed Brown } 550552f7358SJed Brown PetscFunctionReturn(0); 551552f7358SJed Brown } 552552f7358SJed Brown 553d930f514SMatthew G. Knepley PetscErrorCode VecLoad_Plex_Native(Vec originalv, PetscViewer viewer) 554d930f514SMatthew G. Knepley { 555d930f514SMatthew G. Knepley DM dm; 556d930f514SMatthew G. Knepley PetscViewerFormat format; 557d930f514SMatthew G. Knepley PetscBool ishdf5; 558d930f514SMatthew G. Knepley PetscErrorCode ierr; 559d930f514SMatthew G. Knepley 560d930f514SMatthew G. Knepley PetscFunctionBegin; 561d930f514SMatthew G. Knepley ierr = VecGetDM(originalv, &dm);CHKERRQ(ierr); 5622c71b3e2SJacob Faibussowitsch PetscCheckFalse(!dm,PetscObjectComm((PetscObject) originalv), PETSC_ERR_ARG_WRONG, "Vector not generated from a DM"); 563d930f514SMatthew G. Knepley ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 564d930f514SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 565d930f514SMatthew G. Knepley if (format == PETSC_VIEWER_NATIVE) { 566a8ad634aSStefano Zampini if (dm->useNatural) { 567d930f514SMatthew G. Knepley if (dm->sfNatural) { 568d930f514SMatthew G. Knepley if (ishdf5) { 569d930f514SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 570d930f514SMatthew G. Knepley Vec v; 571d930f514SMatthew G. Knepley const char *vecname; 572d930f514SMatthew G. Knepley 573d930f514SMatthew G. Knepley ierr = DMGetGlobalVector(dm, &v);CHKERRQ(ierr); 574d930f514SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) originalv, &vecname);CHKERRQ(ierr); 575d930f514SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) v, vecname);CHKERRQ(ierr); 57639d25373SMatthew G. Knepley ierr = VecLoad_Plex_HDF5_Native_Internal(v, viewer);CHKERRQ(ierr); 577d930f514SMatthew G. Knepley ierr = DMPlexNaturalToGlobalBegin(dm, v, originalv);CHKERRQ(ierr); 578d930f514SMatthew G. Knepley ierr = DMPlexNaturalToGlobalEnd(dm, v, originalv);CHKERRQ(ierr); 579d930f514SMatthew G. Knepley ierr = DMRestoreGlobalVector(dm, &v);CHKERRQ(ierr); 580d930f514SMatthew G. Knepley #else 581d930f514SMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 582d930f514SMatthew G. Knepley #endif 583d930f514SMatthew G. Knepley } else SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Reading in natural order is not supported for anything but HDF5."); 584d930f514SMatthew G. Knepley } 585a8ad634aSStefano Zampini } else { 586a8ad634aSStefano Zampini ierr = VecLoad_Default(originalv, viewer);CHKERRQ(ierr); 587a8ad634aSStefano Zampini } 588d930f514SMatthew G. Knepley } 589d930f514SMatthew G. Knepley PetscFunctionReturn(0); 590d930f514SMatthew G. Knepley } 591d930f514SMatthew G. Knepley 5927cd05799SMatthew G. Knepley PETSC_UNUSED static PetscErrorCode DMPlexView_Ascii_Geometry(DM dm, PetscViewer viewer) 593731e8ddeSMatthew G. Knepley { 594731e8ddeSMatthew G. Knepley PetscSection coordSection; 595731e8ddeSMatthew G. Knepley Vec coordinates; 596ba2698f1SMatthew G. Knepley DMLabel depthLabel, celltypeLabel; 597731e8ddeSMatthew G. Knepley const char *name[4]; 598731e8ddeSMatthew G. Knepley const PetscScalar *a; 599731e8ddeSMatthew G. Knepley PetscInt dim, pStart, pEnd, cStart, cEnd, c; 600731e8ddeSMatthew G. Knepley PetscErrorCode ierr; 601731e8ddeSMatthew G. Knepley 602731e8ddeSMatthew G. Knepley PetscFunctionBegin; 603731e8ddeSMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 604731e8ddeSMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 605731e8ddeSMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 606731e8ddeSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &depthLabel);CHKERRQ(ierr); 607ba2698f1SMatthew G. Knepley ierr = DMPlexGetCellTypeLabel(dm, &celltypeLabel);CHKERRQ(ierr); 608731e8ddeSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 609731e8ddeSMatthew G. Knepley ierr = PetscSectionGetChart(coordSection, &pStart, &pEnd);CHKERRQ(ierr); 610731e8ddeSMatthew G. Knepley ierr = VecGetArrayRead(coordinates, &a);CHKERRQ(ierr); 611731e8ddeSMatthew G. Knepley name[0] = "vertex"; 612731e8ddeSMatthew G. Knepley name[1] = "edge"; 613731e8ddeSMatthew G. Knepley name[dim-1] = "face"; 614731e8ddeSMatthew G. Knepley name[dim] = "cell"; 615731e8ddeSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 616731e8ddeSMatthew G. Knepley PetscInt *closure = NULL; 617ba2698f1SMatthew G. Knepley PetscInt closureSize, cl, ct; 618731e8ddeSMatthew G. Knepley 619ba2698f1SMatthew G. Knepley ierr = DMLabelGetValue(celltypeLabel, c, &ct);CHKERRQ(ierr); 620ba2698f1SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "Geometry for cell %D polytope type %s:\n", c, DMPolytopeTypes[ct]);CHKERRQ(ierr); 621731e8ddeSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 622731e8ddeSMatthew G. Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 623731e8ddeSMatthew G. Knepley for (cl = 0; cl < closureSize*2; cl += 2) { 624731e8ddeSMatthew G. Knepley PetscInt point = closure[cl], depth, dof, off, d, p; 625731e8ddeSMatthew G. Knepley 626731e8ddeSMatthew G. Knepley if ((point < pStart) || (point >= pEnd)) continue; 627731e8ddeSMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, point, &dof);CHKERRQ(ierr); 628731e8ddeSMatthew G. Knepley if (!dof) continue; 629731e8ddeSMatthew G. Knepley ierr = DMLabelGetValue(depthLabel, point, &depth);CHKERRQ(ierr); 630731e8ddeSMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, point, &off);CHKERRQ(ierr); 631f347f43bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer, "%s %D coords:", name[depth], point);CHKERRQ(ierr); 632731e8ddeSMatthew G. Knepley for (p = 0; p < dof/dim; ++p) { 633731e8ddeSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " (");CHKERRQ(ierr); 634731e8ddeSMatthew G. Knepley for (d = 0; d < dim; ++d) { 635731e8ddeSMatthew G. Knepley if (d > 0) {ierr = PetscViewerASCIIPrintf(viewer, ", ");CHKERRQ(ierr);} 636087ef6b2SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "%g", (double) PetscRealPart(a[off+p*dim+d]));CHKERRQ(ierr); 637731e8ddeSMatthew G. Knepley } 638731e8ddeSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, ")");CHKERRQ(ierr); 639731e8ddeSMatthew G. Knepley } 640731e8ddeSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "\n");CHKERRQ(ierr); 641731e8ddeSMatthew G. Knepley } 642731e8ddeSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 643731e8ddeSMatthew G. Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 644731e8ddeSMatthew G. Knepley } 645731e8ddeSMatthew G. Knepley ierr = VecRestoreArrayRead(coordinates, &a);CHKERRQ(ierr); 646731e8ddeSMatthew G. Knepley PetscFunctionReturn(0); 647731e8ddeSMatthew G. Knepley } 648731e8ddeSMatthew G. Knepley 64919ad8254SMatthew G. Knepley typedef enum {CS_CARTESIAN, CS_POLAR, CS_CYLINDRICAL, CS_SPHERICAL} CoordSystem; 65019ad8254SMatthew G. Knepley const char *CoordSystems[] = {"cartesian", "polar", "cylindrical", "spherical", "CoordSystem", "CS_", NULL}; 65119ad8254SMatthew G. Knepley 65219ad8254SMatthew G. Knepley static PetscErrorCode DMPlexView_Ascii_Coordinates(PetscViewer viewer, CoordSystem cs, PetscInt dim, const PetscScalar x[]) 65319ad8254SMatthew G. Knepley { 65419ad8254SMatthew G. Knepley PetscInt i; 65519ad8254SMatthew G. Knepley PetscErrorCode ierr; 65619ad8254SMatthew G. Knepley 65719ad8254SMatthew G. Knepley PetscFunctionBegin; 65819ad8254SMatthew G. Knepley if (dim > 3) { 65919ad8254SMatthew G. Knepley for (i = 0; i < dim; ++i) {ierr = PetscViewerASCIISynchronizedPrintf(viewer, " %g", (double) PetscRealPart(x[i]));CHKERRQ(ierr);} 66019ad8254SMatthew G. Knepley } else { 66119ad8254SMatthew G. Knepley PetscReal coords[3], trcoords[3]; 66219ad8254SMatthew G. Knepley 66319ad8254SMatthew G. Knepley for (i = 0; i < dim; ++i) coords[i] = PetscRealPart(x[i]); 66419ad8254SMatthew G. Knepley switch (cs) { 66519ad8254SMatthew G. Knepley case CS_CARTESIAN: for (i = 0; i < dim; ++i) trcoords[i] = coords[i];break; 66619ad8254SMatthew G. Knepley case CS_POLAR: 6672c71b3e2SJacob Faibussowitsch PetscCheckFalse(dim != 2,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Polar coordinates are for 2 dimension, not %D", dim); 66819ad8254SMatthew G. Knepley trcoords[0] = PetscSqrtReal(PetscSqr(coords[0]) + PetscSqr(coords[1])); 66919ad8254SMatthew G. Knepley trcoords[1] = PetscAtan2Real(coords[1], coords[0]); 67019ad8254SMatthew G. Knepley break; 67119ad8254SMatthew G. Knepley case CS_CYLINDRICAL: 6722c71b3e2SJacob Faibussowitsch PetscCheckFalse(dim != 3,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cylindrical coordinates are for 3 dimension, not %D", dim); 67319ad8254SMatthew G. Knepley trcoords[0] = PetscSqrtReal(PetscSqr(coords[0]) + PetscSqr(coords[1])); 67419ad8254SMatthew G. Knepley trcoords[1] = PetscAtan2Real(coords[1], coords[0]); 67519ad8254SMatthew G. Knepley trcoords[2] = coords[2]; 67619ad8254SMatthew G. Knepley break; 67719ad8254SMatthew G. Knepley case CS_SPHERICAL: 6782c71b3e2SJacob Faibussowitsch PetscCheckFalse(dim != 3,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Spherical coordinates are for 3 dimension, not %D", dim); 67919ad8254SMatthew G. Knepley trcoords[0] = PetscSqrtReal(PetscSqr(coords[0]) + PetscSqr(coords[1]) + PetscSqr(coords[2])); 68019ad8254SMatthew G. Knepley trcoords[1] = PetscAtan2Real(PetscSqrtReal(PetscSqr(coords[0]) + PetscSqr(coords[1])), coords[2]); 68119ad8254SMatthew G. Knepley trcoords[2] = PetscAtan2Real(coords[1], coords[0]); 68219ad8254SMatthew G. Knepley break; 68319ad8254SMatthew G. Knepley } 68419ad8254SMatthew G. Knepley for (i = 0; i < dim; ++i) {ierr = PetscViewerASCIISynchronizedPrintf(viewer, " %g", (double) trcoords[i]);CHKERRQ(ierr);} 68519ad8254SMatthew G. Knepley } 68619ad8254SMatthew G. Knepley PetscFunctionReturn(0); 68719ad8254SMatthew G. Knepley } 68819ad8254SMatthew G. Knepley 6897cd05799SMatthew G. Knepley static PetscErrorCode DMPlexView_Ascii(DM dm, PetscViewer viewer) 690552f7358SJed Brown { 691552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 692552f7358SJed Brown DM cdm; 693552f7358SJed Brown PetscSection coordSection; 694552f7358SJed Brown Vec coordinates; 695552f7358SJed Brown PetscViewerFormat format; 696552f7358SJed Brown PetscErrorCode ierr; 697552f7358SJed Brown 698552f7358SJed Brown PetscFunctionBegin; 699552f7358SJed Brown ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 70092fd8e1eSJed Brown ierr = DMGetLocalSection(cdm, &coordSection);CHKERRQ(ierr); 701552f7358SJed Brown ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 702552f7358SJed Brown ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 703552f7358SJed Brown if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 704552f7358SJed Brown const char *name; 705f73eea6eSMatthew G. Knepley PetscInt dim, cellHeight, maxConeSize, maxSupportSize; 7069318fe57SMatthew G. Knepley PetscInt pStart, pEnd, p, numLabels, l; 707552f7358SJed Brown PetscMPIInt rank, size; 708552f7358SJed Brown 709ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank);CHKERRMPI(ierr); 710ffc4695bSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)dm), &size);CHKERRMPI(ierr); 711552f7358SJed Brown ierr = PetscObjectGetName((PetscObject) dm, &name);CHKERRQ(ierr); 712552f7358SJed Brown ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 713552f7358SJed Brown ierr = DMPlexGetMaxSizes(dm, &maxConeSize, &maxSupportSize);CHKERRQ(ierr); 714f73eea6eSMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 715f73eea6eSMatthew G. Knepley ierr = DMPlexGetVTKCellHeight(dm, &cellHeight);CHKERRQ(ierr); 716f73eea6eSMatthew G. Knepley if (name) {ierr = PetscViewerASCIIPrintf(viewer, "%s in %D dimension%s:\n", name, dim, dim == 1 ? "" : "s");CHKERRQ(ierr);} 717f73eea6eSMatthew G. Knepley else {ierr = PetscViewerASCIIPrintf(viewer, "Mesh in %D dimension%s:\n", dim, dim == 1 ? "" : "s");CHKERRQ(ierr);} 718f73eea6eSMatthew G. Knepley if (cellHeight) {ierr = PetscViewerASCIIPrintf(viewer, " Cells are at height %D\n", cellHeight);CHKERRQ(ierr);} 719e9cb465cSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "Supports:\n", name);CHKERRQ(ierr); 7204d4c343aSBarry Smith ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 721e9cb465cSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "[%d] Max support size: %D\n", rank, maxSupportSize);CHKERRQ(ierr); 722552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 723552f7358SJed Brown PetscInt dof, off, s; 724552f7358SJed Brown 725552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, &dof);CHKERRQ(ierr); 726552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, p, &off);CHKERRQ(ierr); 727552f7358SJed Brown for (s = off; s < off+dof; ++s) { 728e4b003c7SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer, "[%d]: %D ----> %D\n", rank, p, mesh->supports[s]);CHKERRQ(ierr); 729552f7358SJed Brown } 730552f7358SJed Brown } 731552f7358SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 732e9cb465cSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "Cones:\n", name);CHKERRQ(ierr); 733e9cb465cSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "[%d] Max cone size: %D\n", rank, maxConeSize);CHKERRQ(ierr); 734552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 735552f7358SJed Brown PetscInt dof, off, c; 736552f7358SJed Brown 737552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 738552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 739552f7358SJed Brown for (c = off; c < off+dof; ++c) { 740e4b003c7SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer, "[%d]: %D <---- %D (%D)\n", rank, p, mesh->cones[c], mesh->coneOrientations[c]);CHKERRQ(ierr); 741552f7358SJed Brown } 742552f7358SJed Brown } 743552f7358SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 7444d4c343aSBarry Smith ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); 7453d2e540fSStefano Zampini if (coordSection && coordinates) { 74619ad8254SMatthew G. Knepley CoordSystem cs = CS_CARTESIAN; 74719ad8254SMatthew G. Knepley const PetscScalar *array; 74819ad8254SMatthew G. Knepley PetscInt Nf, Nc, pStart, pEnd, p; 74919ad8254SMatthew G. Knepley PetscMPIInt rank; 75019ad8254SMatthew G. Knepley const char *name; 75119ad8254SMatthew G. Knepley 75219ad8254SMatthew G. Knepley ierr = PetscOptionsGetEnum(((PetscObject) viewer)->options, ((PetscObject) viewer)->prefix, "-dm_plex_view_coord_system", CoordSystems, (PetscEnum *) &cs, NULL);CHKERRQ(ierr); 75319ad8254SMatthew G. Knepley ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank);CHKERRMPI(ierr); 75419ad8254SMatthew G. Knepley ierr = PetscSectionGetNumFields(coordSection, &Nf);CHKERRQ(ierr); 7552c71b3e2SJacob Faibussowitsch PetscCheckFalse(Nf != 1,PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Coordinate section should have 1 field, not %D", Nf); 75619ad8254SMatthew G. Knepley ierr = PetscSectionGetFieldComponents(coordSection, 0, &Nc);CHKERRQ(ierr); 75719ad8254SMatthew G. Knepley ierr = PetscSectionGetChart(coordSection, &pStart, &pEnd);CHKERRQ(ierr); 75819ad8254SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) coordinates, &name);CHKERRQ(ierr); 75919ad8254SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "%s with %D fields\n", name, Nf);CHKERRQ(ierr); 760d410b0cfSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " field 0 with %D components\n", Nc);CHKERRQ(ierr); 76119ad8254SMatthew G. Knepley if (cs != CS_CARTESIAN) {ierr = PetscViewerASCIIPrintf(viewer, " output coordinate system: %s\n", CoordSystems[cs]);CHKERRQ(ierr);} 76219ad8254SMatthew G. Knepley 76319ad8254SMatthew G. Knepley ierr = VecGetArrayRead(coordinates, &array);CHKERRQ(ierr); 76419ad8254SMatthew G. Knepley ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 76519ad8254SMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "Process %d:\n", rank);CHKERRQ(ierr); 76619ad8254SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 76719ad8254SMatthew G. Knepley PetscInt dof, off; 76819ad8254SMatthew G. Knepley 76919ad8254SMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, p, &dof);CHKERRQ(ierr); 77019ad8254SMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, p, &off);CHKERRQ(ierr); 77119ad8254SMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, " (%4D) dim %2D offset %3D", p, dof, off);CHKERRQ(ierr); 77219ad8254SMatthew G. Knepley ierr = DMPlexView_Ascii_Coordinates(viewer, cs, dof, &array[off]);CHKERRQ(ierr); 77319ad8254SMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "\n");CHKERRQ(ierr); 77419ad8254SMatthew G. Knepley } 77519ad8254SMatthew G. Knepley ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 77619ad8254SMatthew G. Knepley ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); 77719ad8254SMatthew G. Knepley ierr = VecRestoreArrayRead(coordinates, &array);CHKERRQ(ierr); 7783d2e540fSStefano Zampini } 7799318fe57SMatthew G. Knepley ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 7809318fe57SMatthew G. Knepley if (numLabels) {ierr = PetscViewerASCIIPrintf(viewer, "Labels:\n");CHKERRQ(ierr);} 7819318fe57SMatthew G. Knepley for (l = 0; l < numLabels; ++l) { 7829318fe57SMatthew G. Knepley DMLabel label; 7839318fe57SMatthew G. Knepley PetscBool isdepth; 7849318fe57SMatthew G. Knepley const char *name; 7859318fe57SMatthew G. Knepley 7869318fe57SMatthew G. Knepley ierr = DMGetLabelName(dm, l, &name);CHKERRQ(ierr); 7879318fe57SMatthew G. Knepley ierr = PetscStrcmp(name, "depth", &isdepth);CHKERRQ(ierr); 7889318fe57SMatthew G. Knepley if (isdepth) continue; 7899318fe57SMatthew G. Knepley ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7909318fe57SMatthew G. Knepley ierr = DMLabelView(label, viewer);CHKERRQ(ierr); 7919318fe57SMatthew G. Knepley } 792552f7358SJed Brown if (size > 1) { 793552f7358SJed Brown PetscSF sf; 794552f7358SJed Brown 795552f7358SJed Brown ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 796552f7358SJed Brown ierr = PetscSFView(sf, viewer);CHKERRQ(ierr); 797552f7358SJed Brown } 798552f7358SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 799552f7358SJed Brown } else if (format == PETSC_VIEWER_ASCII_LATEX) { 8000588280cSMatthew G. Knepley const char *name, *color; 8010588280cSMatthew G. Knepley const char *defcolors[3] = {"gray", "orange", "green"}; 8020588280cSMatthew G. Knepley const char *deflcolors[4] = {"blue", "cyan", "red", "magenta"}; 803fe1cc32dSStefano Zampini char lname[PETSC_MAX_PATH_LEN]; 804552f7358SJed Brown PetscReal scale = 2.0; 80578081901SStefano Zampini PetscReal tikzscale = 1.0; 806b7f6ffafSMatthew G. Knepley PetscBool useNumbers = PETSC_TRUE, drawNumbers[4], drawColors[4], useLabels, useColors, plotEdges, drawHasse = PETSC_FALSE; 8070588280cSMatthew G. Knepley double tcoords[3]; 808552f7358SJed Brown PetscScalar *coords; 809b7f6ffafSMatthew G. Knepley PetscInt numLabels, l, numColors, numLColors, dim, d, depth, cStart, cEnd, c, vStart, vEnd, v, eStart = 0, eEnd = 0, e, p, n; 810552f7358SJed Brown PetscMPIInt rank, size; 8110588280cSMatthew G. Knepley char **names, **colors, **lcolors; 812b7f6ffafSMatthew G. Knepley PetscBool flg, lflg; 813fe1cc32dSStefano Zampini PetscBT wp = NULL; 814fe1cc32dSStefano Zampini PetscInt pEnd, pStart; 815552f7358SJed Brown 8160588280cSMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 817552f7358SJed Brown ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 818c58f1c22SToby Isaac ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 8190588280cSMatthew G. Knepley numLabels = PetscMax(numLabels, 10); 8200588280cSMatthew G. Knepley numColors = 10; 8210588280cSMatthew G. Knepley numLColors = 10; 8220588280cSMatthew G. Knepley ierr = PetscCalloc3(numLabels, &names, numColors, &colors, numLColors, &lcolors);CHKERRQ(ierr); 823c5929fdfSBarry Smith ierr = PetscOptionsGetReal(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_scale", &scale, NULL);CHKERRQ(ierr); 82478081901SStefano Zampini ierr = PetscOptionsGetReal(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_tikzscale", &tikzscale, NULL);CHKERRQ(ierr); 825c5929fdfSBarry Smith ierr = PetscOptionsGetBool(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_numbers", &useNumbers, NULL);CHKERRQ(ierr); 826b7f6ffafSMatthew G. Knepley for (d = 0; d < 4; ++d) drawNumbers[d] = useNumbers; 827b7f6ffafSMatthew G. Knepley for (d = 0; d < 4; ++d) drawColors[d] = PETSC_TRUE; 828b7f6ffafSMatthew G. Knepley n = 4; 829b7f6ffafSMatthew G. Knepley ierr = PetscOptionsGetBoolArray(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_numbers_depth", drawNumbers, &n, &flg);CHKERRQ(ierr); 8302c71b3e2SJacob Faibussowitsch PetscCheckFalse(flg && n != dim+1,PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_SIZ, "Number of flags %D != %D dim+1", n, dim+1); 831b7f6ffafSMatthew G. Knepley ierr = PetscOptionsGetBoolArray(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_colors_depth", drawColors, &n, &flg);CHKERRQ(ierr); 8322c71b3e2SJacob Faibussowitsch PetscCheckFalse(flg && n != dim+1,PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_SIZ, "Number of flags %D != %D dim+1", n, dim+1); 833c5929fdfSBarry Smith ierr = PetscOptionsGetStringArray(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_labels", names, &numLabels, &useLabels);CHKERRQ(ierr); 8340588280cSMatthew G. Knepley if (!useLabels) numLabels = 0; 835c5929fdfSBarry Smith ierr = PetscOptionsGetStringArray(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_colors", colors, &numColors, &useColors);CHKERRQ(ierr); 8360588280cSMatthew G. Knepley if (!useColors) { 8370588280cSMatthew G. Knepley numColors = 3; 8380588280cSMatthew G. Knepley for (c = 0; c < numColors; ++c) {ierr = PetscStrallocpy(defcolors[c], &colors[c]);CHKERRQ(ierr);} 8390588280cSMatthew G. Knepley } 840c5929fdfSBarry Smith ierr = PetscOptionsGetStringArray(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_lcolors", lcolors, &numLColors, &useColors);CHKERRQ(ierr); 8410588280cSMatthew G. Knepley if (!useColors) { 8420588280cSMatthew G. Knepley numLColors = 4; 8430588280cSMatthew G. Knepley for (c = 0; c < numLColors; ++c) {ierr = PetscStrallocpy(deflcolors[c], &lcolors[c]);CHKERRQ(ierr);} 8440588280cSMatthew G. Knepley } 845589a23caSBarry Smith ierr = PetscOptionsGetString(((PetscObject) viewer)->options, ((PetscObject) viewer)->prefix, "-dm_plex_view_label_filter", lname, sizeof(lname), &lflg);CHKERRQ(ierr); 846b7f6ffafSMatthew G. Knepley plotEdges = (PetscBool)(depth > 1 && drawNumbers[1] && dim < 3); 847202fd40aSStefano Zampini ierr = PetscOptionsGetBool(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_edges", &plotEdges, &flg);CHKERRQ(ierr); 8482c71b3e2SJacob Faibussowitsch PetscCheckFalse(flg && plotEdges && depth < dim,PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Mesh must be interpolated"); 849202fd40aSStefano Zampini if (depth < dim) plotEdges = PETSC_FALSE; 850b7f6ffafSMatthew G. Knepley ierr = PetscOptionsGetBool(((PetscObject) viewer)->options, ((PetscObject) viewer)->prefix, "-dm_plex_view_hasse", &drawHasse, NULL);CHKERRQ(ierr); 851fe1cc32dSStefano Zampini 852fe1cc32dSStefano Zampini /* filter points with labelvalue != labeldefaultvalue */ 853fe1cc32dSStefano Zampini ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 854b7f6ffafSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 855b7f6ffafSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 856b7f6ffafSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 857fe1cc32dSStefano Zampini if (lflg) { 858fe1cc32dSStefano Zampini DMLabel lbl; 859fe1cc32dSStefano Zampini 860fe1cc32dSStefano Zampini ierr = DMGetLabel(dm, lname, &lbl);CHKERRQ(ierr); 861fe1cc32dSStefano Zampini if (lbl) { 862fe1cc32dSStefano Zampini PetscInt val, defval; 863fe1cc32dSStefano Zampini 864fe1cc32dSStefano Zampini ierr = DMLabelGetDefaultValue(lbl, &defval);CHKERRQ(ierr); 865fe1cc32dSStefano Zampini ierr = PetscBTCreate(pEnd-pStart, &wp);CHKERRQ(ierr); 866fe1cc32dSStefano Zampini for (c = pStart; c < pEnd; c++) { 867fe1cc32dSStefano Zampini PetscInt *closure = NULL; 868fe1cc32dSStefano Zampini PetscInt closureSize; 869fe1cc32dSStefano Zampini 870fe1cc32dSStefano Zampini ierr = DMLabelGetValue(lbl, c, &val);CHKERRQ(ierr); 871fe1cc32dSStefano Zampini if (val == defval) continue; 872fe1cc32dSStefano Zampini 873fe1cc32dSStefano Zampini ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 874fe1cc32dSStefano Zampini for (p = 0; p < closureSize*2; p += 2) { 875fe1cc32dSStefano Zampini ierr = PetscBTSet(wp, closure[p] - pStart);CHKERRQ(ierr); 876fe1cc32dSStefano Zampini } 877fe1cc32dSStefano Zampini ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 878fe1cc32dSStefano Zampini } 879fe1cc32dSStefano Zampini } 880fe1cc32dSStefano Zampini } 881fe1cc32dSStefano Zampini 882ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank);CHKERRMPI(ierr); 883ffc4695bSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)dm), &size);CHKERRMPI(ierr); 884552f7358SJed Brown ierr = PetscObjectGetName((PetscObject) dm, &name);CHKERRQ(ierr); 885770b213bSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, "\ 8860588280cSMatthew G. Knepley \\documentclass[tikz]{standalone}\n\n\ 887552f7358SJed Brown \\usepackage{pgflibraryshapes}\n\ 888552f7358SJed Brown \\usetikzlibrary{backgrounds}\n\ 889552f7358SJed Brown \\usetikzlibrary{arrows}\n\ 8900588280cSMatthew G. Knepley \\begin{document}\n");CHKERRQ(ierr); 8910588280cSMatthew G. Knepley if (size > 1) { 892f738dd31SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "%s for process ", name);CHKERRQ(ierr); 893770b213bSMatthew G Knepley for (p = 0; p < size; ++p) { 894770b213bSMatthew G Knepley if (p > 0 && p == size-1) { 895770b213bSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, ", and ", colors[p%numColors], p);CHKERRQ(ierr); 896770b213bSMatthew G Knepley } else if (p > 0) { 897770b213bSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, ", ", colors[p%numColors], p);CHKERRQ(ierr); 898770b213bSMatthew G Knepley } 899770b213bSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, "{\\textcolor{%s}%D}", colors[p%numColors], p);CHKERRQ(ierr); 900770b213bSMatthew G Knepley } 9010588280cSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, ".\n\n\n");CHKERRQ(ierr); 9020588280cSMatthew G. Knepley } 903b7f6ffafSMatthew G. Knepley if (drawHasse) { 904b7f6ffafSMatthew G. Knepley PetscInt maxStratum = PetscMax(vEnd-vStart, PetscMax(eEnd-eStart, cEnd-cStart)); 905b7f6ffafSMatthew G. Knepley 906b7f6ffafSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "\\newcommand{\\vStart}{%D}\n", vStart);CHKERRQ(ierr); 907b7f6ffafSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "\\newcommand{\\vEnd}{%D}\n", vEnd-1);CHKERRQ(ierr); 908b7f6ffafSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "\\newcommand{\\numVertices}{%D}\n", vEnd-vStart);CHKERRQ(ierr); 909b7f6ffafSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "\\newcommand{\\vShift}{%.2f}\n", 3 + (maxStratum-(vEnd-vStart))/2.);CHKERRQ(ierr); 910b7f6ffafSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "\\newcommand{\\eStart}{%D}\n", eStart);CHKERRQ(ierr); 911b7f6ffafSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "\\newcommand{\\eEnd}{%D}\n", eEnd-1);CHKERRQ(ierr); 912b7f6ffafSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "\\newcommand{\\eShift}{%.2f}\n", 3 + (maxStratum-(eEnd-eStart))/2.);CHKERRQ(ierr); 913b7f6ffafSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "\\newcommand{\\numEdges}{%D}\n", eEnd-eStart);CHKERRQ(ierr); 914b7f6ffafSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "\\newcommand{\\cStart}{%D}\n", cStart);CHKERRQ(ierr); 915b7f6ffafSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "\\newcommand{\\cEnd}{%D}\n", cEnd-1);CHKERRQ(ierr); 916b7f6ffafSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "\\newcommand{\\numCells}{%D}\n", cEnd-cStart);CHKERRQ(ierr); 917b7f6ffafSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "\\newcommand{\\cShift}{%.2f}\n", 3 + (maxStratum-(cEnd-cStart))/2.);CHKERRQ(ierr); 918b7f6ffafSMatthew G. Knepley } 919087ef6b2SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "\\begin{tikzpicture}[scale = %g,font=\\fontsize{8}{8}\\selectfont]\n", (double) tikzscale);CHKERRQ(ierr); 920fe1cc32dSStefano Zampini 921552f7358SJed Brown /* Plot vertices */ 922552f7358SJed Brown ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 9234d4c343aSBarry Smith ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 924552f7358SJed Brown for (v = vStart; v < vEnd; ++v) { 925552f7358SJed Brown PetscInt off, dof, d; 9260588280cSMatthew G. Knepley PetscBool isLabeled = PETSC_FALSE; 927552f7358SJed Brown 928fe1cc32dSStefano Zampini if (wp && !PetscBTLookup(wp,v - pStart)) continue; 929552f7358SJed Brown ierr = PetscSectionGetDof(coordSection, v, &dof);CHKERRQ(ierr); 930552f7358SJed Brown ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 9310588280cSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "\\path (");CHKERRQ(ierr); 9322c71b3e2SJacob Faibussowitsch PetscCheckFalse(dof > 3,PETSC_COMM_SELF,PETSC_ERR_PLIB,"coordSection vertex %D has dof %D > 3",v,dof); 9330588280cSMatthew G. Knepley for (d = 0; d < dof; ++d) { 9340588280cSMatthew G. Knepley tcoords[d] = (double) (scale*PetscRealPart(coords[off+d])); 935c068d9bbSLisandro Dalcin tcoords[d] = PetscAbs(tcoords[d]) < 1e-10 ? 0.0 : tcoords[d]; 9360588280cSMatthew G. Knepley } 9370588280cSMatthew G. Knepley /* Rotate coordinates since PGF makes z point out of the page instead of up */ 9380588280cSMatthew G. Knepley if (dim == 3) {PetscReal tmp = tcoords[1]; tcoords[1] = tcoords[2]; tcoords[2] = -tmp;} 939552f7358SJed Brown for (d = 0; d < dof; ++d) { 940552f7358SJed Brown if (d > 0) {ierr = PetscViewerASCIISynchronizedPrintf(viewer, ",");CHKERRQ(ierr);} 941087ef6b2SMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "%g", (double) tcoords[d]);CHKERRQ(ierr); 942552f7358SJed Brown } 943b7f6ffafSMatthew G. Knepley if (drawHasse) color = colors[0%numColors]; 944b7f6ffafSMatthew G. Knepley else color = colors[rank%numColors]; 9450588280cSMatthew G. Knepley for (l = 0; l < numLabels; ++l) { 9460588280cSMatthew G. Knepley PetscInt val; 947c58f1c22SToby Isaac ierr = DMGetLabelValue(dm, names[l], v, &val);CHKERRQ(ierr); 9480588280cSMatthew G. Knepley if (val >= 0) {color = lcolors[l%numLColors]; isLabeled = PETSC_TRUE; break;} 9490588280cSMatthew G. Knepley } 950b7f6ffafSMatthew G. Knepley if (drawNumbers[0]) { 951e4b003c7SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer, ") node(%D_%d) [draw,shape=circle,color=%s] {%D};\n", v, rank, color, v);CHKERRQ(ierr); 952b7f6ffafSMatthew G. Knepley } else if (drawColors[0]) { 953e4b003c7SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer, ") node(%D_%d) [fill,inner sep=%dpt,shape=circle,color=%s] {};\n", v, rank, !isLabeled ? 1 : 2, color);CHKERRQ(ierr); 954b7f6ffafSMatthew G. Knepley } else { 955b7f6ffafSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, ") node(%D_%d) [] {};\n", v, rank);CHKERRQ(ierr); 9560588280cSMatthew G. Knepley } 957552f7358SJed Brown } 958552f7358SJed Brown ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 959552f7358SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 960b7f6ffafSMatthew G. Knepley /* Plot edges */ 961b7f6ffafSMatthew G. Knepley if (plotEdges) { 962b7f6ffafSMatthew G. Knepley ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 963b7f6ffafSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "\\path\n");CHKERRQ(ierr); 964b7f6ffafSMatthew G. Knepley for (e = eStart; e < eEnd; ++e) { 965b7f6ffafSMatthew G. Knepley const PetscInt *cone; 966b7f6ffafSMatthew G. Knepley PetscInt coneSize, offA, offB, dof, d; 967b7f6ffafSMatthew G. Knepley 968b7f6ffafSMatthew G. Knepley if (wp && !PetscBTLookup(wp,e - pStart)) continue; 969b7f6ffafSMatthew G. Knepley ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr); 9702c71b3e2SJacob Faibussowitsch PetscCheckFalse(coneSize != 2,PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %D cone should have two vertices, not %D", e, coneSize); 971b7f6ffafSMatthew G. Knepley ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 972b7f6ffafSMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, cone[0], &dof);CHKERRQ(ierr); 973b7f6ffafSMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr); 974b7f6ffafSMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr); 975b7f6ffafSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "(");CHKERRQ(ierr); 976b7f6ffafSMatthew G. Knepley for (d = 0; d < dof; ++d) { 977b7f6ffafSMatthew G. Knepley tcoords[d] = (double) (0.5*scale*PetscRealPart(coords[offA+d]+coords[offB+d])); 978b7f6ffafSMatthew G. Knepley tcoords[d] = PetscAbs(tcoords[d]) < 1e-10 ? 0.0 : tcoords[d]; 979b7f6ffafSMatthew G. Knepley } 980b7f6ffafSMatthew G. Knepley /* Rotate coordinates since PGF makes z point out of the page instead of up */ 981b7f6ffafSMatthew G. Knepley if (dim == 3) {PetscReal tmp = tcoords[1]; tcoords[1] = tcoords[2]; tcoords[2] = -tmp;} 982b7f6ffafSMatthew G. Knepley for (d = 0; d < dof; ++d) { 983b7f6ffafSMatthew G. Knepley if (d > 0) {ierr = PetscViewerASCIISynchronizedPrintf(viewer, ",");CHKERRQ(ierr);} 984b7f6ffafSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "%g", (double)tcoords[d]);CHKERRQ(ierr); 985b7f6ffafSMatthew G. Knepley } 986b7f6ffafSMatthew G. Knepley if (drawHasse) color = colors[1%numColors]; 987b7f6ffafSMatthew G. Knepley else color = colors[rank%numColors]; 988b7f6ffafSMatthew G. Knepley for (l = 0; l < numLabels; ++l) { 989b7f6ffafSMatthew G. Knepley PetscInt val; 990b7f6ffafSMatthew G. Knepley ierr = DMGetLabelValue(dm, names[l], v, &val);CHKERRQ(ierr); 991b7f6ffafSMatthew G. Knepley if (val >= 0) {color = lcolors[l%numLColors]; break;} 992b7f6ffafSMatthew G. Knepley } 993b7f6ffafSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, ") node(%D_%d) [draw,shape=circle,color=%s] {%D} --\n", e, rank, color, e);CHKERRQ(ierr); 994b7f6ffafSMatthew G. Knepley } 995b7f6ffafSMatthew G. Knepley ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 996b7f6ffafSMatthew G. Knepley ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 997b7f6ffafSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "(0,0);\n");CHKERRQ(ierr); 998b7f6ffafSMatthew G. Knepley } 999846a3e8bSMatthew G. Knepley /* Plot cells */ 1000b7f6ffafSMatthew G. Knepley if (dim == 3 || !drawNumbers[1]) { 1001846a3e8bSMatthew G. Knepley for (e = eStart; e < eEnd; ++e) { 1002846a3e8bSMatthew G. Knepley const PetscInt *cone; 1003846a3e8bSMatthew G. Knepley 1004fe1cc32dSStefano Zampini if (wp && !PetscBTLookup(wp,e - pStart)) continue; 1005846a3e8bSMatthew G. Knepley color = colors[rank%numColors]; 1006846a3e8bSMatthew G. Knepley for (l = 0; l < numLabels; ++l) { 1007846a3e8bSMatthew G. Knepley PetscInt val; 1008846a3e8bSMatthew G. Knepley ierr = DMGetLabelValue(dm, names[l], e, &val);CHKERRQ(ierr); 1009846a3e8bSMatthew G. Knepley if (val >= 0) {color = lcolors[l%numLColors]; break;} 1010846a3e8bSMatthew G. Knepley } 1011846a3e8bSMatthew G. Knepley ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 1012846a3e8bSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "\\draw[color=%s] (%D_%d) -- (%D_%d);\n", color, cone[0], rank, cone[1], rank);CHKERRQ(ierr); 1013846a3e8bSMatthew G. Knepley } 1014846a3e8bSMatthew G. Knepley } else { 1015b7f6ffafSMatthew G. Knepley DMPolytopeType ct; 1016846a3e8bSMatthew G. Knepley 1017b7f6ffafSMatthew G. Knepley /* Drawing a 2D polygon */ 1018b7f6ffafSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 1019fe1cc32dSStefano Zampini if (wp && !PetscBTLookup(wp, c - pStart)) continue; 1020b7f6ffafSMatthew G. Knepley ierr = DMPlexGetCellType(dm, c, &ct);CHKERRQ(ierr); 1021b7f6ffafSMatthew G. Knepley if (ct == DM_POLYTOPE_SEG_PRISM_TENSOR || 1022b7f6ffafSMatthew G. Knepley ct == DM_POLYTOPE_TRI_PRISM_TENSOR || 1023b7f6ffafSMatthew G. Knepley ct == DM_POLYTOPE_QUAD_PRISM_TENSOR) { 1024b7f6ffafSMatthew G. Knepley const PetscInt *cone; 1025b7f6ffafSMatthew G. Knepley PetscInt coneSize, e; 1026b7f6ffafSMatthew G. Knepley 1027b7f6ffafSMatthew G. Knepley ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1028b7f6ffafSMatthew G. Knepley ierr = DMPlexGetConeSize(dm, c, &coneSize);CHKERRQ(ierr); 1029b7f6ffafSMatthew G. Knepley for (e = 0; e < coneSize; ++e) { 1030b7f6ffafSMatthew G. Knepley const PetscInt *econe; 1031b7f6ffafSMatthew G. Knepley 1032b7f6ffafSMatthew G. Knepley ierr = DMPlexGetCone(dm, cone[e], &econe);CHKERRQ(ierr); 1033b7f6ffafSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "\\draw[color=%s] (%D_%d) -- (%D_%d) -- (%D_%d);\n", colors[rank%numColors], econe[0], rank, cone[e], rank, econe[1], rank);CHKERRQ(ierr); 1034b7f6ffafSMatthew G. Knepley } 1035b7f6ffafSMatthew G. Knepley } else { 1036b7f6ffafSMatthew G. Knepley PetscInt *closure = NULL; 1037b7f6ffafSMatthew G. Knepley PetscInt closureSize, Nv = 0, v; 1038b7f6ffafSMatthew G. Knepley 1039846a3e8bSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 1040846a3e8bSMatthew G. Knepley for (p = 0; p < closureSize*2; p += 2) { 1041846a3e8bSMatthew G. Knepley const PetscInt point = closure[p]; 1042846a3e8bSMatthew G. Knepley 1043b7f6ffafSMatthew G. Knepley if ((point >= vStart) && (point < vEnd)) closure[Nv++] = point; 1044846a3e8bSMatthew G. Knepley } 1045b7f6ffafSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "\\draw[color=%s] ", colors[rank%numColors]);CHKERRQ(ierr); 1046b7f6ffafSMatthew G. Knepley for (v = 0; v <= Nv; ++v) { 1047b7f6ffafSMatthew G. Knepley const PetscInt vertex = closure[v%Nv]; 1048b7f6ffafSMatthew G. Knepley 1049b7f6ffafSMatthew G. Knepley if (v > 0) { 1050b7f6ffafSMatthew G. Knepley if (plotEdges) { 1051b7f6ffafSMatthew G. Knepley const PetscInt *edge; 1052b7f6ffafSMatthew G. Knepley PetscInt endpoints[2], ne; 1053b7f6ffafSMatthew G. Knepley 1054b7f6ffafSMatthew G. Knepley endpoints[0] = closure[v-1]; endpoints[1] = vertex; 1055b7f6ffafSMatthew G. Knepley ierr = DMPlexGetJoin(dm, 2, endpoints, &ne, &edge);CHKERRQ(ierr); 10562c71b3e2SJacob Faibussowitsch PetscCheckFalse(ne != 1,PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find edge for vertices %D, %D", endpoints[0], endpoints[1]); 1057b7f6ffafSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, " -- (%D_%d) -- ", edge[0], rank);CHKERRQ(ierr); 1058b7f6ffafSMatthew G. Knepley ierr = DMPlexRestoreJoin(dm, 2, endpoints, &ne, &edge);CHKERRQ(ierr); 1059b7f6ffafSMatthew G. Knepley } else { 1060b7f6ffafSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, " -- ");CHKERRQ(ierr); 1061b7f6ffafSMatthew G. Knepley } 1062b7f6ffafSMatthew G. Knepley } 1063b7f6ffafSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "(%D_%d)", vertex, rank);CHKERRQ(ierr); 1064b7f6ffafSMatthew G. Knepley } 1065b7f6ffafSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, ";\n");CHKERRQ(ierr); 1066846a3e8bSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 1067846a3e8bSMatthew G. Knepley } 1068846a3e8bSMatthew G. Knepley } 1069b7f6ffafSMatthew G. Knepley } 1070846a3e8bSMatthew G. Knepley ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 1071846a3e8bSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 1072846a3e8bSMatthew G. Knepley double ccoords[3] = {0.0, 0.0, 0.0}; 1073846a3e8bSMatthew G. Knepley PetscBool isLabeled = PETSC_FALSE; 1074846a3e8bSMatthew G. Knepley PetscInt *closure = NULL; 1075846a3e8bSMatthew G. Knepley PetscInt closureSize, dof, d, n = 0; 1076846a3e8bSMatthew G. Knepley 1077fe1cc32dSStefano Zampini if (wp && !PetscBTLookup(wp,c - pStart)) continue; 1078846a3e8bSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 1079846a3e8bSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "\\path (");CHKERRQ(ierr); 1080846a3e8bSMatthew G. Knepley for (p = 0; p < closureSize*2; p += 2) { 1081846a3e8bSMatthew G. Knepley const PetscInt point = closure[p]; 1082846a3e8bSMatthew G. Knepley PetscInt off; 1083846a3e8bSMatthew G. Knepley 1084846a3e8bSMatthew G. Knepley if ((point < vStart) || (point >= vEnd)) continue; 1085846a3e8bSMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, point, &dof);CHKERRQ(ierr); 1086846a3e8bSMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, point, &off);CHKERRQ(ierr); 1087846a3e8bSMatthew G. Knepley for (d = 0; d < dof; ++d) { 1088846a3e8bSMatthew G. Knepley tcoords[d] = (double) (scale*PetscRealPart(coords[off+d])); 1089846a3e8bSMatthew G. Knepley tcoords[d] = PetscAbs(tcoords[d]) < 1e-10 ? 0.0 : tcoords[d]; 1090846a3e8bSMatthew G. Knepley } 1091846a3e8bSMatthew G. Knepley /* Rotate coordinates since PGF makes z point out of the page instead of up */ 1092846a3e8bSMatthew G. Knepley if (dof == 3) {PetscReal tmp = tcoords[1]; tcoords[1] = tcoords[2]; tcoords[2] = -tmp;} 1093846a3e8bSMatthew G. Knepley for (d = 0; d < dof; ++d) {ccoords[d] += tcoords[d];} 1094846a3e8bSMatthew G. Knepley ++n; 1095846a3e8bSMatthew G. Knepley } 1096846a3e8bSMatthew G. Knepley for (d = 0; d < dof; ++d) {ccoords[d] /= n;} 1097846a3e8bSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 1098846a3e8bSMatthew G. Knepley for (d = 0; d < dof; ++d) { 1099846a3e8bSMatthew G. Knepley if (d > 0) {ierr = PetscViewerASCIISynchronizedPrintf(viewer, ",");CHKERRQ(ierr);} 1100087ef6b2SMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "%g", (double) ccoords[d]);CHKERRQ(ierr); 1101846a3e8bSMatthew G. Knepley } 1102b7f6ffafSMatthew G. Knepley if (drawHasse) color = colors[depth%numColors]; 1103b7f6ffafSMatthew G. Knepley else color = colors[rank%numColors]; 1104846a3e8bSMatthew G. Knepley for (l = 0; l < numLabels; ++l) { 1105846a3e8bSMatthew G. Knepley PetscInt val; 1106846a3e8bSMatthew G. Knepley ierr = DMGetLabelValue(dm, names[l], c, &val);CHKERRQ(ierr); 1107846a3e8bSMatthew G. Knepley if (val >= 0) {color = lcolors[l%numLColors]; isLabeled = PETSC_TRUE; break;} 1108846a3e8bSMatthew G. Knepley } 1109b7f6ffafSMatthew G. Knepley if (drawNumbers[dim]) { 1110846a3e8bSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, ") node(%D_%d) [draw,shape=circle,color=%s] {%D};\n", c, rank, color, c);CHKERRQ(ierr); 1111b7f6ffafSMatthew G. Knepley } else if (drawColors[dim]) { 1112846a3e8bSMatthew 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); 1113b7f6ffafSMatthew G. Knepley } else { 1114b7f6ffafSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, ") node(%D_%d) [] {};\n", c, rank);CHKERRQ(ierr); 1115846a3e8bSMatthew G. Knepley } 1116846a3e8bSMatthew G. Knepley } 1117846a3e8bSMatthew G. Knepley ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 1118b7f6ffafSMatthew G. Knepley if (drawHasse) { 1119b7f6ffafSMatthew G. Knepley color = colors[depth%numColors]; 1120b7f6ffafSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "%% Cells\n");CHKERRQ(ierr); 1121b7f6ffafSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "\\foreach \\c in {\\cStart,...,\\cEnd}\n");CHKERRQ(ierr); 1122b7f6ffafSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "{\n");CHKERRQ(ierr); 1123b7f6ffafSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " \\node(\\c_%d) [draw,shape=circle,color=%s,minimum size = 6mm] at (\\cShift+\\c-\\cStart,0) {\\c};\n", rank, color);CHKERRQ(ierr); 1124b7f6ffafSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "}\n");CHKERRQ(ierr); 1125552f7358SJed Brown 1126b7f6ffafSMatthew G. Knepley color = colors[1%numColors]; 1127b7f6ffafSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "%% Edges\n");CHKERRQ(ierr); 1128b7f6ffafSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "\\foreach \\e in {\\eStart,...,\\eEnd}\n");CHKERRQ(ierr); 1129b7f6ffafSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "{\n");CHKERRQ(ierr); 1130b7f6ffafSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " \\node(\\e_%d) [draw,shape=circle,color=%s,minimum size = 6mm] at (\\eShift+\\e-\\eStart,1) {\\e};\n", rank, color);CHKERRQ(ierr); 1131b7f6ffafSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "}\n");CHKERRQ(ierr); 1132b7f6ffafSMatthew G. Knepley 1133b7f6ffafSMatthew G. Knepley color = colors[0%numColors]; 1134b7f6ffafSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "%% Vertices\n");CHKERRQ(ierr); 1135b7f6ffafSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "\\foreach \\v in {\\vStart,...,\\vEnd}\n");CHKERRQ(ierr); 1136b7f6ffafSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "{\n");CHKERRQ(ierr); 1137b7f6ffafSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " \\node(\\v_%d) [draw,shape=circle,color=%s,minimum size = 6mm] at (\\vShift+\\v-\\vStart,2) {\\v};\n", rank, color);CHKERRQ(ierr); 1138b7f6ffafSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "}\n");CHKERRQ(ierr); 1139b7f6ffafSMatthew G. Knepley 1140b7f6ffafSMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 1141b7f6ffafSMatthew G. Knepley const PetscInt *cone; 1142b7f6ffafSMatthew G. Knepley PetscInt coneSize, cp; 1143b7f6ffafSMatthew G. Knepley 1144b7f6ffafSMatthew G. Knepley ierr = DMPlexGetCone(dm, p, &cone);CHKERRQ(ierr); 1145b7f6ffafSMatthew G. Knepley ierr = DMPlexGetConeSize(dm, p, &coneSize);CHKERRQ(ierr); 1146b7f6ffafSMatthew G. Knepley for (cp = 0; cp < coneSize; ++cp) { 1147b7f6ffafSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "\\draw[->, shorten >=1pt] (%D_%d) -- (%D_%d);\n", cone[cp], rank, p, rank);CHKERRQ(ierr); 1148552f7358SJed Brown } 11490588280cSMatthew G. Knepley } 11500588280cSMatthew G. Knepley } 1151552f7358SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 11524d4c343aSBarry Smith ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); 11530588280cSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "\\end{tikzpicture}\n");CHKERRQ(ierr); 1154770b213bSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, "\\end{document}\n", name);CHKERRQ(ierr); 11550588280cSMatthew G. Knepley for (l = 0; l < numLabels; ++l) {ierr = PetscFree(names[l]);CHKERRQ(ierr);} 11560588280cSMatthew G. Knepley for (c = 0; c < numColors; ++c) {ierr = PetscFree(colors[c]);CHKERRQ(ierr);} 11570588280cSMatthew G. Knepley for (c = 0; c < numLColors; ++c) {ierr = PetscFree(lcolors[c]);CHKERRQ(ierr);} 11580588280cSMatthew G. Knepley ierr = PetscFree3(names, colors, lcolors);CHKERRQ(ierr); 1159fe1cc32dSStefano Zampini ierr = PetscBTDestroy(&wp);CHKERRQ(ierr); 11600f7d6e4aSStefano Zampini } else if (format == PETSC_VIEWER_LOAD_BALANCE) { 11610f7d6e4aSStefano Zampini Vec cown,acown; 11620f7d6e4aSStefano Zampini VecScatter sct; 11630f7d6e4aSStefano Zampini ISLocalToGlobalMapping g2l; 11640f7d6e4aSStefano Zampini IS gid,acis; 11650f7d6e4aSStefano Zampini MPI_Comm comm,ncomm = MPI_COMM_NULL; 11660f7d6e4aSStefano Zampini MPI_Group ggroup,ngroup; 11670f7d6e4aSStefano Zampini PetscScalar *array,nid; 11680f7d6e4aSStefano Zampini const PetscInt *idxs; 11690f7d6e4aSStefano Zampini PetscInt *idxs2,*start,*adjacency,*work; 11700f7d6e4aSStefano Zampini PetscInt64 lm[3],gm[3]; 11710f7d6e4aSStefano Zampini PetscInt i,c,cStart,cEnd,cum,numVertices,ect,ectn,cellHeight; 11720f7d6e4aSStefano Zampini PetscMPIInt d1,d2,rank; 11730f7d6e4aSStefano Zampini 11740f7d6e4aSStefano Zampini ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 1175ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 1176b674149eSJunchao Zhang #if defined(PETSC_HAVE_MPI_PROCESS_SHARED_MEMORY) 1177ffc4695bSBarry Smith ierr = MPI_Comm_split_type(comm,MPI_COMM_TYPE_SHARED,rank,MPI_INFO_NULL,&ncomm);CHKERRMPI(ierr); 11780f7d6e4aSStefano Zampini #endif 11790f7d6e4aSStefano Zampini if (ncomm != MPI_COMM_NULL) { 1180ffc4695bSBarry Smith ierr = MPI_Comm_group(comm,&ggroup);CHKERRMPI(ierr); 1181ffc4695bSBarry Smith ierr = MPI_Comm_group(ncomm,&ngroup);CHKERRMPI(ierr); 11820f7d6e4aSStefano Zampini d1 = 0; 1183ffc4695bSBarry Smith ierr = MPI_Group_translate_ranks(ngroup,1,&d1,ggroup,&d2);CHKERRMPI(ierr); 11840f7d6e4aSStefano Zampini nid = d2; 1185ffc4695bSBarry Smith ierr = MPI_Group_free(&ggroup);CHKERRMPI(ierr); 1186ffc4695bSBarry Smith ierr = MPI_Group_free(&ngroup);CHKERRMPI(ierr); 1187ffc4695bSBarry Smith ierr = MPI_Comm_free(&ncomm);CHKERRMPI(ierr); 11880f7d6e4aSStefano Zampini } else nid = 0.0; 11890f7d6e4aSStefano Zampini 11900f7d6e4aSStefano Zampini /* Get connectivity */ 11910f7d6e4aSStefano Zampini ierr = DMPlexGetVTKCellHeight(dm,&cellHeight);CHKERRQ(ierr); 11920f7d6e4aSStefano Zampini ierr = DMPlexCreatePartitionerGraph(dm,cellHeight,&numVertices,&start,&adjacency,&gid);CHKERRQ(ierr); 11930f7d6e4aSStefano Zampini 11940f7d6e4aSStefano Zampini /* filter overlapped local cells */ 11950f7d6e4aSStefano Zampini ierr = DMPlexGetHeightStratum(dm,cellHeight,&cStart,&cEnd);CHKERRQ(ierr); 11960f7d6e4aSStefano Zampini ierr = ISGetIndices(gid,&idxs);CHKERRQ(ierr); 11970f7d6e4aSStefano Zampini ierr = ISGetLocalSize(gid,&cum);CHKERRQ(ierr); 11980f7d6e4aSStefano Zampini ierr = PetscMalloc1(cum,&idxs2);CHKERRQ(ierr); 11990f7d6e4aSStefano Zampini for (c = cStart, cum = 0; c < cEnd; c++) { 12000f7d6e4aSStefano Zampini if (idxs[c-cStart] < 0) continue; 12010f7d6e4aSStefano Zampini idxs2[cum++] = idxs[c-cStart]; 12020f7d6e4aSStefano Zampini } 12030f7d6e4aSStefano Zampini ierr = ISRestoreIndices(gid,&idxs);CHKERRQ(ierr); 12042c71b3e2SJacob Faibussowitsch PetscCheckFalse(numVertices != cum,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected %D != %D",numVertices,cum); 12050f7d6e4aSStefano Zampini ierr = ISDestroy(&gid);CHKERRQ(ierr); 12060f7d6e4aSStefano Zampini ierr = ISCreateGeneral(comm,numVertices,idxs2,PETSC_OWN_POINTER,&gid);CHKERRQ(ierr); 12070f7d6e4aSStefano Zampini 12080f7d6e4aSStefano Zampini /* support for node-aware cell locality */ 12090f7d6e4aSStefano Zampini ierr = ISCreateGeneral(comm,start[numVertices],adjacency,PETSC_USE_POINTER,&acis);CHKERRQ(ierr); 12100f7d6e4aSStefano Zampini ierr = VecCreateSeq(PETSC_COMM_SELF,start[numVertices],&acown);CHKERRQ(ierr); 12110f7d6e4aSStefano Zampini ierr = VecCreateMPI(comm,numVertices,PETSC_DECIDE,&cown);CHKERRQ(ierr); 12120f7d6e4aSStefano Zampini ierr = VecGetArray(cown,&array);CHKERRQ(ierr); 12130f7d6e4aSStefano Zampini for (c = 0; c < numVertices; c++) array[c] = nid; 12140f7d6e4aSStefano Zampini ierr = VecRestoreArray(cown,&array);CHKERRQ(ierr); 12150f7d6e4aSStefano Zampini ierr = VecScatterCreate(cown,acis,acown,NULL,&sct);CHKERRQ(ierr); 12160f7d6e4aSStefano Zampini ierr = VecScatterBegin(sct,cown,acown,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12170f7d6e4aSStefano Zampini ierr = VecScatterEnd(sct,cown,acown,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12180f7d6e4aSStefano Zampini ierr = ISDestroy(&acis);CHKERRQ(ierr); 12190f7d6e4aSStefano Zampini ierr = VecScatterDestroy(&sct);CHKERRQ(ierr); 12200f7d6e4aSStefano Zampini ierr = VecDestroy(&cown);CHKERRQ(ierr); 12210f7d6e4aSStefano Zampini 12220f7d6e4aSStefano Zampini /* compute edgeCut */ 12230f7d6e4aSStefano Zampini for (c = 0, cum = 0; c < numVertices; c++) cum = PetscMax(cum,start[c+1]-start[c]); 12240f7d6e4aSStefano Zampini ierr = PetscMalloc1(cum,&work);CHKERRQ(ierr); 12250f7d6e4aSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(gid,&g2l);CHKERRQ(ierr); 12260f7d6e4aSStefano Zampini ierr = ISLocalToGlobalMappingSetType(g2l,ISLOCALTOGLOBALMAPPINGHASH);CHKERRQ(ierr); 12270f7d6e4aSStefano Zampini ierr = ISDestroy(&gid);CHKERRQ(ierr); 12280f7d6e4aSStefano Zampini ierr = VecGetArray(acown,&array);CHKERRQ(ierr); 12290f7d6e4aSStefano Zampini for (c = 0, ect = 0, ectn = 0; c < numVertices; c++) { 12300f7d6e4aSStefano Zampini PetscInt totl; 12310f7d6e4aSStefano Zampini 12320f7d6e4aSStefano Zampini totl = start[c+1]-start[c]; 12330f7d6e4aSStefano Zampini ierr = ISGlobalToLocalMappingApply(g2l,IS_GTOLM_MASK,totl,adjacency+start[c],NULL,work);CHKERRQ(ierr); 12340f7d6e4aSStefano Zampini for (i = 0; i < totl; i++) { 12350f7d6e4aSStefano Zampini if (work[i] < 0) { 12360f7d6e4aSStefano Zampini ect += 1; 12370f7d6e4aSStefano Zampini ectn += (array[i + start[c]] != nid) ? 0 : 1; 12380f7d6e4aSStefano Zampini } 12390f7d6e4aSStefano Zampini } 12400f7d6e4aSStefano Zampini } 12410f7d6e4aSStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 12420f7d6e4aSStefano Zampini ierr = VecRestoreArray(acown,&array);CHKERRQ(ierr); 12430f7d6e4aSStefano Zampini lm[0] = numVertices > 0 ? numVertices : PETSC_MAX_INT; 12440f7d6e4aSStefano Zampini lm[1] = -numVertices; 1245820f2d46SBarry Smith ierr = MPIU_Allreduce(lm,gm,2,MPIU_INT64,MPI_MIN,comm);CHKERRMPI(ierr); 12460f7d6e4aSStefano 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); 12470f7d6e4aSStefano Zampini lm[0] = ect; /* edgeCut */ 12480f7d6e4aSStefano Zampini lm[1] = ectn; /* node-aware edgeCut */ 12490f7d6e4aSStefano Zampini lm[2] = numVertices > 0 ? 0 : 1; /* empty processes */ 1250820f2d46SBarry Smith ierr = MPIU_Allreduce(lm,gm,3,MPIU_INT64,MPI_SUM,comm);CHKERRMPI(ierr); 12510f7d6e4aSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,", empty %D)\n",(PetscInt)gm[2]);CHKERRQ(ierr); 1252b674149eSJunchao Zhang #if defined(PETSC_HAVE_MPI_PROCESS_SHARED_MEMORY) 12530f7d6e4aSStefano 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); 12540f7d6e4aSStefano Zampini #else 12550f7d6e4aSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Edge Cut: %D (on node %.3f)\n",(PetscInt)(gm[0]/2),0.0);CHKERRQ(ierr); 12560f7d6e4aSStefano Zampini #endif 12570f7d6e4aSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&g2l);CHKERRQ(ierr); 12580f7d6e4aSStefano Zampini ierr = PetscFree(start);CHKERRQ(ierr); 12590f7d6e4aSStefano Zampini ierr = PetscFree(adjacency);CHKERRQ(ierr); 12600f7d6e4aSStefano Zampini ierr = VecDestroy(&acown);CHKERRQ(ierr); 1261552f7358SJed Brown } else { 1262412e9a14SMatthew G. Knepley const char *name; 1263d80ece95SMatthew G. Knepley PetscInt *sizes, *hybsizes, *ghostsizes; 1264412e9a14SMatthew G. Knepley PetscInt locDepth, depth, cellHeight, dim, d; 1265d80ece95SMatthew G. Knepley PetscInt pStart, pEnd, p, gcStart, gcEnd, gcNum; 1266ca7bf7eeSMatthew G. Knepley PetscInt numLabels, l, maxSize = 17; 12679318fe57SMatthew G. Knepley DMPolytopeType ct0 = DM_POLYTOPE_UNKNOWN; 1268412e9a14SMatthew G. Knepley MPI_Comm comm; 1269412e9a14SMatthew G. Knepley PetscMPIInt size, rank; 1270552f7358SJed Brown 127182f516ccSBarry Smith ierr = PetscObjectGetComm((PetscObject) dm, &comm);CHKERRQ(ierr); 1272ffc4695bSBarry Smith ierr = MPI_Comm_size(comm, &size);CHKERRMPI(ierr); 1273ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 1274c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 1275f73eea6eSMatthew G. Knepley ierr = DMPlexGetVTKCellHeight(dm, &cellHeight);CHKERRQ(ierr); 12765f64d76eSMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) dm, &name);CHKERRQ(ierr); 1277f73eea6eSMatthew G. Knepley if (name) {ierr = PetscViewerASCIIPrintf(viewer, "%s in %D dimension%s:\n", name, dim, dim == 1 ? "" : "s");CHKERRQ(ierr);} 1278f73eea6eSMatthew G. Knepley else {ierr = PetscViewerASCIIPrintf(viewer, "Mesh in %D dimension%s:\n", dim, dim == 1 ? "" : "s");CHKERRQ(ierr);} 1279f73eea6eSMatthew G. Knepley if (cellHeight) {ierr = PetscViewerASCIIPrintf(viewer, " Cells are at height %D\n", cellHeight);CHKERRQ(ierr);} 1280552f7358SJed Brown ierr = DMPlexGetDepth(dm, &locDepth);CHKERRQ(ierr); 1281820f2d46SBarry Smith ierr = MPIU_Allreduce(&locDepth, &depth, 1, MPIU_INT, MPI_MAX, comm);CHKERRMPI(ierr); 1282d80ece95SMatthew G. Knepley ierr = DMPlexGetGhostCellStratum(dm, &gcStart, &gcEnd);CHKERRQ(ierr); 1283d80ece95SMatthew G. Knepley gcNum = gcEnd - gcStart; 1284ca7bf7eeSMatthew G. Knepley if (size < maxSize) {ierr = PetscCalloc3(size, &sizes, size, &hybsizes, size, &ghostsizes);CHKERRQ(ierr);} 1285ca7bf7eeSMatthew G. Knepley else {ierr = PetscCalloc3(3, &sizes, 3, &hybsizes, 3, &ghostsizes);CHKERRQ(ierr);} 1286412e9a14SMatthew G. Knepley for (d = 0; d <= depth; d++) { 1287412e9a14SMatthew G. Knepley PetscInt Nc[2] = {0, 0}, ict; 1288412e9a14SMatthew G. Knepley 1289552f7358SJed Brown ierr = DMPlexGetDepthStratum(dm, d, &pStart, &pEnd);CHKERRQ(ierr); 12909318fe57SMatthew G. Knepley if (pStart < pEnd) {ierr = DMPlexGetCellType(dm, pStart, &ct0);CHKERRQ(ierr);} 1291412e9a14SMatthew G. Knepley ict = ct0; 1292ffc4695bSBarry Smith ierr = MPI_Bcast(&ict, 1, MPIU_INT, 0, comm);CHKERRMPI(ierr); 1293412e9a14SMatthew G. Knepley ct0 = (DMPolytopeType) ict; 1294412e9a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 1295412e9a14SMatthew G. Knepley DMPolytopeType ct; 1296412e9a14SMatthew G. Knepley 1297412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 1298412e9a14SMatthew G. Knepley if (ct == ct0) ++Nc[0]; 1299412e9a14SMatthew G. Knepley else ++Nc[1]; 1300412e9a14SMatthew G. Knepley } 1301ca7bf7eeSMatthew G. Knepley if (size < maxSize) { 1302ffc4695bSBarry Smith ierr = MPI_Gather(&Nc[0], 1, MPIU_INT, sizes, 1, MPIU_INT, 0, comm);CHKERRMPI(ierr); 1303ffc4695bSBarry Smith ierr = MPI_Gather(&Nc[1], 1, MPIU_INT, hybsizes, 1, MPIU_INT, 0, comm);CHKERRMPI(ierr); 1304ffc4695bSBarry Smith if (d == depth) {ierr = MPI_Gather(&gcNum, 1, MPIU_INT, ghostsizes, 1, MPIU_INT, 0, comm);CHKERRMPI(ierr);} 13059880b877SBarry Smith ierr = PetscViewerASCIIPrintf(viewer, " Number of %D-cells per rank:", (depth == 1) && d ? dim : d);CHKERRQ(ierr); 1306834065abSMatthew G. Knepley for (p = 0; p < size; ++p) { 1307dd400576SPatrick Sanan if (rank == 0) { 1308412e9a14SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " %D", sizes[p]+hybsizes[p]);CHKERRQ(ierr); 1309412e9a14SMatthew G. Knepley if (hybsizes[p] > 0) {ierr = PetscViewerASCIIPrintf(viewer, " (%D)", hybsizes[p]);CHKERRQ(ierr);} 1310412e9a14SMatthew G. Knepley if (ghostsizes[p] > 0) {ierr = PetscViewerASCIIPrintf(viewer, " [%D]", ghostsizes[p]);CHKERRQ(ierr);} 1311834065abSMatthew G. Knepley } 1312cbb7f117SMark Adams } 1313ca7bf7eeSMatthew G. Knepley } else { 1314ca7bf7eeSMatthew G. Knepley PetscInt locMinMax[2]; 1315ca7bf7eeSMatthew G. Knepley 1316ca7bf7eeSMatthew G. Knepley locMinMax[0] = Nc[0]+Nc[1]; locMinMax[1] = Nc[0]+Nc[1]; 1317ca7bf7eeSMatthew G. Knepley ierr = PetscGlobalMinMaxInt(comm, locMinMax, sizes);CHKERRQ(ierr); 1318ca7bf7eeSMatthew G. Knepley locMinMax[0] = Nc[1]; locMinMax[1] = Nc[1]; 1319ca7bf7eeSMatthew G. Knepley ierr = PetscGlobalMinMaxInt(comm, locMinMax, hybsizes);CHKERRQ(ierr); 1320ca7bf7eeSMatthew G. Knepley if (d == depth) { 1321ca7bf7eeSMatthew G. Knepley locMinMax[0] = gcNum; locMinMax[1] = gcNum; 1322ca7bf7eeSMatthew G. Knepley ierr = PetscGlobalMinMaxInt(comm, locMinMax, ghostsizes);CHKERRQ(ierr); 1323ca7bf7eeSMatthew G. Knepley } 1324ca7bf7eeSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " Min/Max of %D-cells per rank:", (depth == 1) && d ? dim : d);CHKERRQ(ierr); 1325ca7bf7eeSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " %" PetscInt_FMT "/%" PetscInt_FMT, sizes[0], sizes[1]);CHKERRQ(ierr); 1326ca7bf7eeSMatthew G. Knepley if (hybsizes[0] > 0) {ierr = PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT "/%" PetscInt_FMT ")", hybsizes[0], hybsizes[1]);CHKERRQ(ierr);} 1327ca7bf7eeSMatthew G. Knepley if (ghostsizes[0] > 0) {ierr = PetscViewerASCIIPrintf(viewer, " [%" PetscInt_FMT "/%" PetscInt_FMT "]", ghostsizes[0], ghostsizes[1]);CHKERRQ(ierr);} 1328ca7bf7eeSMatthew G. Knepley } 1329552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, "\n");CHKERRQ(ierr); 1330552f7358SJed Brown } 1331d80ece95SMatthew G. Knepley ierr = PetscFree3(sizes, hybsizes, ghostsizes);CHKERRQ(ierr); 13329318fe57SMatthew G. Knepley { 13339318fe57SMatthew G. Knepley const PetscReal *maxCell; 13349318fe57SMatthew G. Knepley const PetscReal *L; 13359318fe57SMatthew G. Knepley const DMBoundaryType *bd; 13369318fe57SMatthew G. Knepley PetscBool per, localized; 13379318fe57SMatthew G. Knepley 13389318fe57SMatthew G. Knepley ierr = DMGetPeriodicity(dm, &per, &maxCell, &L, &bd);CHKERRQ(ierr); 13399318fe57SMatthew G. Knepley ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 13409318fe57SMatthew G. Knepley if (per) { 13419318fe57SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "Periodic mesh (");CHKERRQ(ierr); 13429318fe57SMatthew G. Knepley ierr = PetscViewerASCIIUseTabs(viewer, PETSC_FALSE);CHKERRQ(ierr); 13439318fe57SMatthew G. Knepley for (d = 0; d < dim; ++d) { 13449318fe57SMatthew G. Knepley if (bd && d > 0) {ierr = PetscViewerASCIIPrintf(viewer, ", ");CHKERRQ(ierr);} 13459318fe57SMatthew G. Knepley if (bd) {ierr = PetscViewerASCIIPrintf(viewer, "%s", DMBoundaryTypes[bd[d]]);CHKERRQ(ierr);} 13469318fe57SMatthew G. Knepley } 13479318fe57SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, ") coordinates %s\n", localized ? "localized" : "not localized");CHKERRQ(ierr); 13489318fe57SMatthew G. Knepley ierr = PetscViewerASCIIUseTabs(viewer, PETSC_TRUE);CHKERRQ(ierr); 13499318fe57SMatthew G. Knepley } 13509318fe57SMatthew G. Knepley } 1351c58f1c22SToby Isaac ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 1352a57dd577SMatthew G Knepley if (numLabels) {ierr = PetscViewerASCIIPrintf(viewer, "Labels:\n");CHKERRQ(ierr);} 1353a57dd577SMatthew G Knepley for (l = 0; l < numLabels; ++l) { 1354a57dd577SMatthew G Knepley DMLabel label; 1355a57dd577SMatthew G Knepley const char *name; 1356a57dd577SMatthew G Knepley IS valueIS; 1357a57dd577SMatthew G Knepley const PetscInt *values; 1358a57dd577SMatthew G Knepley PetscInt numValues, v; 1359a57dd577SMatthew G Knepley 1360c58f1c22SToby Isaac ierr = DMGetLabelName(dm, l, &name);CHKERRQ(ierr); 1361c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 1362a57dd577SMatthew G Knepley ierr = DMLabelGetNumValues(label, &numValues);CHKERRQ(ierr); 1363d72f73ffSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " %s: %D strata with value/size (", name, numValues);CHKERRQ(ierr); 1364a57dd577SMatthew G Knepley ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 1365a57dd577SMatthew G Knepley ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 1366120dea56SMatthew G. Knepley ierr = PetscViewerASCIIUseTabs(viewer, PETSC_FALSE);CHKERRQ(ierr); 1367a57dd577SMatthew G Knepley for (v = 0; v < numValues; ++v) { 1368a57dd577SMatthew G Knepley PetscInt size; 1369a57dd577SMatthew G Knepley 1370a57dd577SMatthew G Knepley ierr = DMLabelGetStratumSize(label, values[v], &size);CHKERRQ(ierr); 1371a57dd577SMatthew G Knepley if (v > 0) {ierr = PetscViewerASCIIPrintf(viewer, ", ");CHKERRQ(ierr);} 1372d72f73ffSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "%D (%D)", values[v], size);CHKERRQ(ierr); 1373a57dd577SMatthew G Knepley } 1374a57dd577SMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, ")\n");CHKERRQ(ierr); 1375120dea56SMatthew G. Knepley ierr = PetscViewerASCIIUseTabs(viewer, PETSC_TRUE);CHKERRQ(ierr); 1376a57dd577SMatthew G Knepley ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 13774d41221fSMatthew G Knepley ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 1378a57dd577SMatthew G Knepley } 1379c1cad2e7SMatthew G. Knepley { 1380c1cad2e7SMatthew G. Knepley char **labelNames; 1381c1cad2e7SMatthew G. Knepley PetscInt Nl = numLabels; 1382c1cad2e7SMatthew G. Knepley PetscBool flg; 1383c1cad2e7SMatthew G. Knepley 1384c1cad2e7SMatthew G. Knepley ierr = PetscMalloc1(Nl, &labelNames);CHKERRQ(ierr); 1385c1cad2e7SMatthew G. Knepley ierr = PetscOptionsGetStringArray(((PetscObject) dm)->options, ((PetscObject) dm)->prefix, "-dm_plex_view_labels", labelNames, &Nl, &flg);CHKERRQ(ierr); 1386c1cad2e7SMatthew G. Knepley for (l = 0; l < Nl; ++l) { 1387c1cad2e7SMatthew G. Knepley DMLabel label; 1388c1cad2e7SMatthew G. Knepley 1389c1cad2e7SMatthew G. Knepley ierr = DMHasLabel(dm, labelNames[l], &flg);CHKERRQ(ierr); 1390c1cad2e7SMatthew G. Knepley if (flg) { 1391c1cad2e7SMatthew G. Knepley ierr = DMGetLabel(dm, labelNames[l], &label);CHKERRQ(ierr); 1392c1cad2e7SMatthew G. Knepley ierr = DMLabelView(label, viewer);CHKERRQ(ierr); 1393c1cad2e7SMatthew G. Knepley } 1394c1cad2e7SMatthew G. Knepley ierr = PetscFree(labelNames[l]);CHKERRQ(ierr); 1395c1cad2e7SMatthew G. Knepley } 1396c1cad2e7SMatthew G. Knepley ierr = PetscFree(labelNames);CHKERRQ(ierr); 1397c1cad2e7SMatthew G. Knepley } 139834aa8a36SMatthew G. Knepley /* If no fields are specified, people do not want to see adjacency */ 139934aa8a36SMatthew G. Knepley if (dm->Nf) { 140034aa8a36SMatthew G. Knepley PetscInt f; 140134aa8a36SMatthew G. Knepley 140234aa8a36SMatthew G. Knepley for (f = 0; f < dm->Nf; ++f) { 140334aa8a36SMatthew G. Knepley const char *name; 140434aa8a36SMatthew G. Knepley 140534aa8a36SMatthew G. Knepley ierr = PetscObjectGetName(dm->fields[f].disc, &name);CHKERRQ(ierr); 140634aa8a36SMatthew G. Knepley if (numLabels) {ierr = PetscViewerASCIIPrintf(viewer, "Field %s:\n", name);CHKERRQ(ierr);} 140734aa8a36SMatthew G. Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 140834aa8a36SMatthew G. Knepley if (dm->fields[f].label) {ierr = DMLabelView(dm->fields[f].label, viewer);CHKERRQ(ierr);} 140934aa8a36SMatthew G. Knepley if (dm->fields[f].adjacency[0]) { 141034aa8a36SMatthew G. Knepley if (dm->fields[f].adjacency[1]) {ierr = PetscViewerASCIIPrintf(viewer, "adjacency FVM++\n");CHKERRQ(ierr);} 1411ed59e46eSMatthew G. Knepley else {ierr = PetscViewerASCIIPrintf(viewer, "adjacency FVM\n");CHKERRQ(ierr);} 141234aa8a36SMatthew G. Knepley } else { 141334aa8a36SMatthew G. Knepley if (dm->fields[f].adjacency[1]) {ierr = PetscViewerASCIIPrintf(viewer, "adjacency FEM\n");CHKERRQ(ierr);} 141434aa8a36SMatthew G. Knepley else {ierr = PetscViewerASCIIPrintf(viewer, "adjacency FUNKY\n");CHKERRQ(ierr);} 141534aa8a36SMatthew G. Knepley } 141634aa8a36SMatthew G. Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 141734aa8a36SMatthew G. Knepley } 141834aa8a36SMatthew G. Knepley } 1419a8fb8f29SToby Isaac ierr = DMGetCoarseDM(dm, &cdm);CHKERRQ(ierr); 14208e7ff633SMatthew G. Knepley if (cdm) { 14218e7ff633SMatthew G. Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 14228e7ff633SMatthew G. Knepley ierr = DMPlexView_Ascii(cdm, viewer);CHKERRQ(ierr); 14238e7ff633SMatthew G. Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 14248e7ff633SMatthew G. Knepley } 1425552f7358SJed Brown } 1426552f7358SJed Brown PetscFunctionReturn(0); 1427552f7358SJed Brown } 1428552f7358SJed Brown 1429e5c487bfSMatthew G. Knepley static PetscErrorCode DMPlexDrawCell(DM dm, PetscDraw draw, PetscInt cell, const PetscScalar coords[]) 1430e5c487bfSMatthew G. Knepley { 1431e5c487bfSMatthew G. Knepley DMPolytopeType ct; 1432e5c487bfSMatthew G. Knepley PetscMPIInt rank; 1433a12d352dSMatthew G. Knepley PetscInt cdim; 1434e5c487bfSMatthew G. Knepley PetscErrorCode ierr; 1435e5c487bfSMatthew G. Knepley 1436e5c487bfSMatthew G. Knepley PetscFunctionBegin; 1437ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject) dm), &rank);CHKERRMPI(ierr); 1438e5c487bfSMatthew G. Knepley ierr = DMPlexGetCellType(dm, cell, &ct);CHKERRQ(ierr); 1439a12d352dSMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr); 1440e5c487bfSMatthew G. Knepley switch (ct) { 1441a12d352dSMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 1442a12d352dSMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 1443a12d352dSMatthew G. Knepley switch (cdim) { 1444a12d352dSMatthew G. Knepley case 1: 1445a12d352dSMatthew G. Knepley { 1446a12d352dSMatthew G. Knepley const PetscReal y = 0.5; /* TODO Put it in the middle of the viewport */ 1447a12d352dSMatthew G. Knepley const PetscReal dy = 0.05; /* TODO Make it a fraction of the total length */ 1448a12d352dSMatthew G. Knepley 1449a12d352dSMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[0]), y, PetscRealPart(coords[1]), y, PETSC_DRAW_BLACK);CHKERRQ(ierr); 1450a12d352dSMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[0]), y+dy, PetscRealPart(coords[0]), y-dy, PETSC_DRAW_BLACK);CHKERRQ(ierr); 1451a12d352dSMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[1]), y+dy, PetscRealPart(coords[1]), y-dy, PETSC_DRAW_BLACK);CHKERRQ(ierr); 1452a12d352dSMatthew G. Knepley } 1453a12d352dSMatthew G. Knepley break; 1454a12d352dSMatthew G. Knepley case 2: 1455a12d352dSMatthew G. Knepley { 1456a12d352dSMatthew G. Knepley const PetscReal dx = (PetscRealPart(coords[3]) - PetscRealPart(coords[1])); 1457a12d352dSMatthew G. Knepley const PetscReal dy = (PetscRealPart(coords[2]) - PetscRealPart(coords[0])); 1458a12d352dSMatthew G. Knepley const PetscReal l = 0.1/PetscSqrtReal(dx*dx + dy*dy); 1459a12d352dSMatthew G. Knepley 1460a12d352dSMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[0]), PetscRealPart(coords[1]), PetscRealPart(coords[2]), PetscRealPart(coords[3]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 1461a12d352dSMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[0])+l*dx, PetscRealPart(coords[1])+l*dy, PetscRealPart(coords[0])-l*dx, PetscRealPart(coords[1])-l*dy, PETSC_DRAW_BLACK);CHKERRQ(ierr); 1462a12d352dSMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[2])+l*dx, PetscRealPart(coords[3])+l*dy, PetscRealPart(coords[2])-l*dx, PetscRealPart(coords[3])-l*dy, PETSC_DRAW_BLACK);CHKERRQ(ierr); 1463a12d352dSMatthew G. Knepley } 1464a12d352dSMatthew G. Knepley break; 146598921bdaSJacob Faibussowitsch default: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot draw cells of dimension %D", cdim); 1466a12d352dSMatthew G. Knepley } 1467a12d352dSMatthew G. Knepley break; 1468e5c487bfSMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 1469e5c487bfSMatthew G. Knepley ierr = PetscDrawTriangle(draw, PetscRealPart(coords[0]), PetscRealPart(coords[1]), PetscRealPart(coords[2]), PetscRealPart(coords[3]), PetscRealPart(coords[4]), PetscRealPart(coords[5]), 1470e5c487bfSMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2, 1471e5c487bfSMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2, 1472e5c487bfSMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2);CHKERRQ(ierr); 1473e5c487bfSMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[0]), PetscRealPart(coords[1]), PetscRealPart(coords[2]), PetscRealPart(coords[3]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 1474e5c487bfSMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[2]), PetscRealPart(coords[3]), PetscRealPart(coords[4]), PetscRealPart(coords[5]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 1475e5c487bfSMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[4]), PetscRealPart(coords[5]), PetscRealPart(coords[0]), PetscRealPart(coords[1]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 1476e5c487bfSMatthew G. Knepley break; 1477e5c487bfSMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 1478e5c487bfSMatthew G. Knepley ierr = PetscDrawTriangle(draw, PetscRealPart(coords[0]), PetscRealPart(coords[1]), PetscRealPart(coords[2]), PetscRealPart(coords[3]), PetscRealPart(coords[4]), PetscRealPart(coords[5]), 1479e5c487bfSMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2, 1480e5c487bfSMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2, 1481e5c487bfSMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2);CHKERRQ(ierr); 1482e5c487bfSMatthew G. Knepley ierr = PetscDrawTriangle(draw, PetscRealPart(coords[0]), PetscRealPart(coords[1]), PetscRealPart(coords[4]), PetscRealPart(coords[5]), PetscRealPart(coords[6]), PetscRealPart(coords[7]), 1483e5c487bfSMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2, 1484e5c487bfSMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2, 1485e5c487bfSMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2);CHKERRQ(ierr); 1486e5c487bfSMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[0]), PetscRealPart(coords[1]), PetscRealPart(coords[2]), PetscRealPart(coords[3]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 1487e5c487bfSMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[2]), PetscRealPart(coords[3]), PetscRealPart(coords[4]), PetscRealPart(coords[5]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 1488e5c487bfSMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[4]), PetscRealPart(coords[5]), PetscRealPart(coords[6]), PetscRealPart(coords[7]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 1489e5c487bfSMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[6]), PetscRealPart(coords[7]), PetscRealPart(coords[0]), PetscRealPart(coords[1]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 1490e5c487bfSMatthew G. Knepley break; 149198921bdaSJacob Faibussowitsch default: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot draw cells of type %s", DMPolytopeTypes[ct]); 1492e5c487bfSMatthew G. Knepley } 1493e5c487bfSMatthew G. Knepley PetscFunctionReturn(0); 1494e5c487bfSMatthew G. Knepley } 1495e5c487bfSMatthew G. Knepley 1496e5c487bfSMatthew G. Knepley static PetscErrorCode DMPlexDrawCellHighOrder(DM dm, PetscDraw draw, PetscInt cell, const PetscScalar coords[], PetscInt edgeDiv, PetscReal refCoords[], PetscReal edgeCoords[]) 1497e5c487bfSMatthew G. Knepley { 1498e5c487bfSMatthew G. Knepley DMPolytopeType ct; 1499e5c487bfSMatthew G. Knepley PetscReal centroid[2] = {0., 0.}; 1500e5c487bfSMatthew G. Knepley PetscMPIInt rank; 1501e5c487bfSMatthew G. Knepley PetscInt fillColor, v, e, d; 1502e5c487bfSMatthew G. Knepley PetscErrorCode ierr; 1503e5c487bfSMatthew G. Knepley 1504e5c487bfSMatthew G. Knepley PetscFunctionBegin; 1505ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject) dm), &rank);CHKERRMPI(ierr); 1506e5c487bfSMatthew G. Knepley ierr = DMPlexGetCellType(dm, cell, &ct);CHKERRQ(ierr); 1507e5c487bfSMatthew G. Knepley fillColor = PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2; 1508e5c487bfSMatthew G. Knepley switch (ct) { 1509e5c487bfSMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 1510e5c487bfSMatthew G. Knepley { 1511e5c487bfSMatthew G. Knepley PetscReal refVertices[6] = {-1., -1., 1., -1., -1., 1.}; 1512e5c487bfSMatthew G. Knepley 1513e5c487bfSMatthew G. Knepley for (v = 0; v < 3; ++v) {centroid[0] += PetscRealPart(coords[v*2+0])/3.;centroid[1] += PetscRealPart(coords[v*2+1])/3.;} 1514e5c487bfSMatthew G. Knepley for (e = 0; e < 3; ++e) { 1515e5c487bfSMatthew G. Knepley refCoords[0] = refVertices[e*2+0]; 1516e5c487bfSMatthew G. Knepley refCoords[1] = refVertices[e*2+1]; 1517e5c487bfSMatthew G. Knepley for (d = 1; d <= edgeDiv; ++d) { 1518e5c487bfSMatthew G. Knepley refCoords[d*2+0] = refCoords[0] + (refVertices[(e+1)%3 * 2 + 0] - refCoords[0])*d/edgeDiv; 1519e5c487bfSMatthew G. Knepley refCoords[d*2+1] = refCoords[1] + (refVertices[(e+1)%3 * 2 + 1] - refCoords[1])*d/edgeDiv; 1520e5c487bfSMatthew G. Knepley } 1521e5c487bfSMatthew G. Knepley ierr = DMPlexReferenceToCoordinates(dm, cell, edgeDiv+1, refCoords, edgeCoords);CHKERRQ(ierr); 1522e5c487bfSMatthew G. Knepley for (d = 0; d < edgeDiv; ++d) { 1523e5c487bfSMatthew G. Knepley ierr = PetscDrawTriangle(draw, centroid[0], centroid[1], edgeCoords[d*2+0], edgeCoords[d*2+1], edgeCoords[(d+1)*2+0], edgeCoords[(d+1)*2+1], fillColor, fillColor, fillColor);CHKERRQ(ierr); 1524e5c487bfSMatthew G. Knepley ierr = PetscDrawLine(draw, edgeCoords[d*2+0], edgeCoords[d*2+1], edgeCoords[(d+1)*2+0], edgeCoords[(d+1)*2+1], PETSC_DRAW_BLACK);CHKERRQ(ierr); 1525e5c487bfSMatthew G. Knepley } 1526e5c487bfSMatthew G. Knepley } 1527e5c487bfSMatthew G. Knepley } 1528e5c487bfSMatthew G. Knepley break; 152998921bdaSJacob Faibussowitsch default: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot draw cells of type %s", DMPolytopeTypes[ct]); 1530e5c487bfSMatthew G. Knepley } 1531e5c487bfSMatthew G. Knepley PetscFunctionReturn(0); 1532e5c487bfSMatthew G. Knepley } 1533e5c487bfSMatthew G. Knepley 15347cd05799SMatthew G. Knepley static PetscErrorCode DMPlexView_Draw(DM dm, PetscViewer viewer) 1535e412dcbdSMatthew G. Knepley { 1536e412dcbdSMatthew G. Knepley PetscDraw draw; 1537e412dcbdSMatthew G. Knepley DM cdm; 1538e412dcbdSMatthew G. Knepley PetscSection coordSection; 1539e412dcbdSMatthew G. Knepley Vec coordinates; 1540e412dcbdSMatthew G. Knepley const PetscScalar *coords; 154129494db1SLisandro Dalcin PetscReal xyl[2],xyr[2],bound[4] = {PETSC_MAX_REAL, PETSC_MAX_REAL, PETSC_MIN_REAL, PETSC_MIN_REAL}; 1542e5c487bfSMatthew G. Knepley PetscReal *refCoords, *edgeCoords; 1543e5c487bfSMatthew G. Knepley PetscBool isnull, drawAffine = PETSC_TRUE; 1544e5c487bfSMatthew G. Knepley PetscInt dim, vStart, vEnd, cStart, cEnd, c, N, edgeDiv = 4; 1545e412dcbdSMatthew G. Knepley PetscErrorCode ierr; 1546e412dcbdSMatthew G. Knepley 1547e412dcbdSMatthew G. Knepley PetscFunctionBegin; 1548e412dcbdSMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dim);CHKERRQ(ierr); 15492c71b3e2SJacob Faibussowitsch PetscCheckFalse(dim > 2,PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Cannot draw meshes of dimension %D", dim); 1550e5c487bfSMatthew G. Knepley ierr = PetscOptionsGetBool(((PetscObject) dm)->options, ((PetscObject) dm)->prefix, "-dm_view_draw_affine", &drawAffine, NULL);CHKERRQ(ierr); 1551e5c487bfSMatthew G. Knepley if (!drawAffine) {ierr = PetscMalloc2((edgeDiv+1)*dim, &refCoords, (edgeDiv+1)*dim, &edgeCoords);CHKERRQ(ierr);} 1552e412dcbdSMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 155392fd8e1eSJed Brown ierr = DMGetLocalSection(cdm, &coordSection);CHKERRQ(ierr); 1554e412dcbdSMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 1555e412dcbdSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 1556e412dcbdSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 1557e412dcbdSMatthew G. Knepley 1558e412dcbdSMatthew G. Knepley ierr = PetscViewerDrawGetDraw(viewer, 0, &draw);CHKERRQ(ierr); 1559e412dcbdSMatthew G. Knepley ierr = PetscDrawIsNull(draw, &isnull);CHKERRQ(ierr); 1560e412dcbdSMatthew G. Knepley if (isnull) PetscFunctionReturn(0); 1561e412dcbdSMatthew G. Knepley ierr = PetscDrawSetTitle(draw, "Mesh");CHKERRQ(ierr); 1562e412dcbdSMatthew G. Knepley 1563e412dcbdSMatthew G. Knepley ierr = VecGetLocalSize(coordinates, &N);CHKERRQ(ierr); 1564e412dcbdSMatthew G. Knepley ierr = VecGetArrayRead(coordinates, &coords);CHKERRQ(ierr); 1565e412dcbdSMatthew G. Knepley for (c = 0; c < N; c += dim) { 15660c81f2a8SMatthew G. Knepley bound[0] = PetscMin(bound[0], PetscRealPart(coords[c])); bound[2] = PetscMax(bound[2], PetscRealPart(coords[c])); 15670c81f2a8SMatthew G. Knepley bound[1] = PetscMin(bound[1], PetscRealPart(coords[c+1])); bound[3] = PetscMax(bound[3], PetscRealPart(coords[c+1])); 1568e412dcbdSMatthew G. Knepley } 1569e412dcbdSMatthew G. Knepley ierr = VecRestoreArrayRead(coordinates, &coords);CHKERRQ(ierr); 1570820f2d46SBarry Smith ierr = MPIU_Allreduce(&bound[0],xyl,2,MPIU_REAL,MPIU_MIN,PetscObjectComm((PetscObject)dm));CHKERRMPI(ierr); 1571820f2d46SBarry Smith ierr = MPIU_Allreduce(&bound[2],xyr,2,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)dm));CHKERRMPI(ierr); 157229494db1SLisandro Dalcin ierr = PetscDrawSetCoordinates(draw, xyl[0], xyl[1], xyr[0], xyr[1]);CHKERRQ(ierr); 1573e412dcbdSMatthew G. Knepley ierr = PetscDrawClear(draw);CHKERRQ(ierr); 1574e412dcbdSMatthew G. Knepley 1575cf3064d3SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 1576cf3064d3SMatthew G. Knepley PetscScalar *coords = NULL; 1577ba2698f1SMatthew G. Knepley PetscInt numCoords; 1578cf3064d3SMatthew G. Knepley 1579e5c487bfSMatthew G. Knepley ierr = DMPlexVecGetClosureAtDepth_Internal(dm, coordSection, coordinates, c, 0, &numCoords, &coords);CHKERRQ(ierr); 1580e5c487bfSMatthew G. Knepley if (drawAffine) { 1581e5c487bfSMatthew G. Knepley ierr = DMPlexDrawCell(dm, draw, c, coords);CHKERRQ(ierr); 1582e5c487bfSMatthew G. Knepley } else { 1583e5c487bfSMatthew G. Knepley ierr = DMPlexDrawCellHighOrder(dm, draw, c, coords, edgeDiv, refCoords, edgeCoords);CHKERRQ(ierr); 1584cf3064d3SMatthew G. Knepley } 1585cf3064d3SMatthew G. Knepley ierr = DMPlexVecRestoreClosure(dm, coordSection, coordinates, c, &numCoords, &coords);CHKERRQ(ierr); 1586cf3064d3SMatthew G. Knepley } 1587e5c487bfSMatthew G. Knepley if (!drawAffine) {ierr = PetscFree2(refCoords, edgeCoords);CHKERRQ(ierr);} 1588e412dcbdSMatthew G. Knepley ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 1589e412dcbdSMatthew G. Knepley ierr = PetscDrawPause(draw);CHKERRQ(ierr); 1590e412dcbdSMatthew G. Knepley ierr = PetscDrawSave(draw);CHKERRQ(ierr); 1591e412dcbdSMatthew G. Knepley PetscFunctionReturn(0); 1592e412dcbdSMatthew G. Knepley } 1593e412dcbdSMatthew G. Knepley 15941e50132fSMatthew G. Knepley #if defined(PETSC_HAVE_EXODUSII) 15951e50132fSMatthew G. Knepley #include <exodusII.h> 15966823f3c5SBlaise Bourdin #include <petscviewerexodusii.h> 15971e50132fSMatthew G. Knepley #endif 15981e50132fSMatthew G. Knepley 1599552f7358SJed Brown PetscErrorCode DMView_Plex(DM dm, PetscViewer viewer) 1600552f7358SJed Brown { 16011e50132fSMatthew G. Knepley PetscBool iascii, ishdf5, isvtk, isdraw, flg, isglvis, isexodus; 1602002a2709SMatthew G. Knepley char name[PETSC_MAX_PATH_LEN]; 1603552f7358SJed Brown PetscErrorCode ierr; 1604552f7358SJed Brown 1605552f7358SJed Brown PetscFunctionBegin; 1606552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1607552f7358SJed Brown PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1608552f7358SJed Brown ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 1609fcf6c8fdSToby Isaac ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERVTK, &isvtk);CHKERRQ(ierr); 1610c6ccd67eSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 1611e412dcbdSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERDRAW, &isdraw);CHKERRQ(ierr); 16128135c375SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERGLVIS, &isglvis);CHKERRQ(ierr); 16131e50132fSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWEREXODUSII, &isexodus);CHKERRQ(ierr); 1614552f7358SJed Brown if (iascii) { 16158135c375SStefano Zampini PetscViewerFormat format; 16168135c375SStefano Zampini ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 16178135c375SStefano Zampini if (format == PETSC_VIEWER_ASCII_GLVIS) { 16188135c375SStefano Zampini ierr = DMPlexView_GLVis(dm, viewer);CHKERRQ(ierr); 16198135c375SStefano Zampini } else { 1620552f7358SJed Brown ierr = DMPlexView_Ascii(dm, viewer);CHKERRQ(ierr); 16218135c375SStefano Zampini } 1622c6ccd67eSMatthew G. Knepley } else if (ishdf5) { 1623c6ccd67eSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 162439d25373SMatthew G. Knepley ierr = DMPlexView_HDF5_Internal(dm, viewer);CHKERRQ(ierr); 1625c6ccd67eSMatthew G. Knepley #else 1626c6ccd67eSMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 1627552f7358SJed Brown #endif 1628e412dcbdSMatthew G. Knepley } else if (isvtk) { 1629fcf6c8fdSToby Isaac ierr = DMPlexVTKWriteAll((PetscObject) dm,viewer);CHKERRQ(ierr); 1630e412dcbdSMatthew G. Knepley } else if (isdraw) { 1631e412dcbdSMatthew G. Knepley ierr = DMPlexView_Draw(dm, viewer);CHKERRQ(ierr); 16328135c375SStefano Zampini } else if (isglvis) { 16338135c375SStefano Zampini ierr = DMPlexView_GLVis(dm, viewer);CHKERRQ(ierr); 16341e50132fSMatthew G. Knepley #if defined(PETSC_HAVE_EXODUSII) 16351e50132fSMatthew G. Knepley } else if (isexodus) { 16366823f3c5SBlaise Bourdin /* 16376823f3c5SBlaise Bourdin exodusII requires that all sets be part of exactly one cell set. 16386823f3c5SBlaise Bourdin If the dm does not have a "Cell Sets" label defined, we create one 16396823f3c5SBlaise Bourdin with ID 1, containig all cells. 16406823f3c5SBlaise Bourdin Note that if the Cell Sets label is defined but does not cover all cells, 16416823f3c5SBlaise Bourdin we may still have a problem. This should probably be checked here or in the viewer; 16426823f3c5SBlaise Bourdin */ 16436823f3c5SBlaise Bourdin PetscInt numCS; 16446823f3c5SBlaise Bourdin ierr = DMGetLabelSize(dm,"Cell Sets",&numCS);CHKERRQ(ierr); 16456823f3c5SBlaise Bourdin if (!numCS) { 16461e50132fSMatthew G. Knepley PetscInt cStart, cEnd, c; 16471e50132fSMatthew G. Knepley ierr = DMCreateLabel(dm, "Cell Sets");CHKERRQ(ierr); 16481e50132fSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 16491e50132fSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) {ierr = DMSetLabelValue(dm, "Cell Sets", c, 1);CHKERRQ(ierr);} 16506823f3c5SBlaise Bourdin } 16516823f3c5SBlaise Bourdin ierr = DMView_PlexExodusII(dm, viewer);CHKERRQ(ierr); 16521e50132fSMatthew G. Knepley #endif 165362201deeSVaclav Hapla } else { 165498921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Viewer type %s not yet supported for DMPlex writing", ((PetscObject)viewer)->type_name); 1655fcf6c8fdSToby Isaac } 1656cb3ba0daSMatthew G. Knepley /* Optionally view the partition */ 1657cb3ba0daSMatthew G. Knepley ierr = PetscOptionsHasName(((PetscObject) dm)->options, ((PetscObject) dm)->prefix, "-dm_partition_view", &flg);CHKERRQ(ierr); 1658cb3ba0daSMatthew G. Knepley if (flg) { 1659cb3ba0daSMatthew G. Knepley Vec ranks; 1660cb3ba0daSMatthew G. Knepley ierr = DMPlexCreateRankField(dm, &ranks);CHKERRQ(ierr); 1661cb3ba0daSMatthew G. Knepley ierr = VecView(ranks, viewer);CHKERRQ(ierr); 1662cb3ba0daSMatthew G. Knepley ierr = VecDestroy(&ranks);CHKERRQ(ierr); 1663cb3ba0daSMatthew G. Knepley } 1664002a2709SMatthew G. Knepley /* Optionally view a label */ 1665589a23caSBarry Smith ierr = PetscOptionsGetString(((PetscObject) dm)->options, ((PetscObject) dm)->prefix, "-dm_label_view", name, sizeof(name), &flg);CHKERRQ(ierr); 1666002a2709SMatthew G. Knepley if (flg) { 1667002a2709SMatthew G. Knepley DMLabel label; 1668002a2709SMatthew G. Knepley Vec val; 1669002a2709SMatthew G. Knepley 1670002a2709SMatthew G. Knepley ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 16712c71b3e2SJacob Faibussowitsch PetscCheckFalse(!label,PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Label %s provided to -dm_label_view does not exist in this DM", name); 1672002a2709SMatthew G. Knepley ierr = DMPlexCreateLabelField(dm, label, &val);CHKERRQ(ierr); 1673002a2709SMatthew G. Knepley ierr = VecView(val, viewer);CHKERRQ(ierr); 1674002a2709SMatthew G. Knepley ierr = VecDestroy(&val);CHKERRQ(ierr); 1675002a2709SMatthew G. Knepley } 1676552f7358SJed Brown PetscFunctionReturn(0); 1677552f7358SJed Brown } 1678552f7358SJed Brown 16797f96f51bSksagiyam /*@ 16807f96f51bSksagiyam DMPlexTopologyView - Saves a DMPlex topology into a file 16817f96f51bSksagiyam 16827f96f51bSksagiyam Collective on DM 16837f96f51bSksagiyam 16847f96f51bSksagiyam Input Parameters: 16857f96f51bSksagiyam + dm - The DM whose topology is to be saved 16867f96f51bSksagiyam - viewer - The PetscViewer for saving 16877f96f51bSksagiyam 16887f96f51bSksagiyam Level: advanced 16897f96f51bSksagiyam 16907f96f51bSksagiyam .seealso: DMView(), DMPlexCoordinatesView(), DMPlexLabelsView(), DMPlexTopologyLoad() 16917f96f51bSksagiyam @*/ 16927f96f51bSksagiyam PetscErrorCode DMPlexTopologyView(DM dm, PetscViewer viewer) 16937f96f51bSksagiyam { 16947f96f51bSksagiyam PetscBool ishdf5; 16957f96f51bSksagiyam PetscErrorCode ierr; 16967f96f51bSksagiyam 16977f96f51bSksagiyam PetscFunctionBegin; 16987f96f51bSksagiyam PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 16997f96f51bSksagiyam PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 17007f96f51bSksagiyam ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 170102f7d72cSksagiyam ierr = PetscLogEventBegin(DMPLEX_TopologyView,viewer,0,0,0);CHKERRQ(ierr); 17027f96f51bSksagiyam if (ishdf5) { 17037f96f51bSksagiyam #if defined(PETSC_HAVE_HDF5) 17047f96f51bSksagiyam PetscViewerFormat format; 17057f96f51bSksagiyam ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 17067f96f51bSksagiyam if (format == PETSC_VIEWER_HDF5_PETSC || format == PETSC_VIEWER_DEFAULT || format == PETSC_VIEWER_NATIVE) { 17077f96f51bSksagiyam IS globalPointNumbering; 17087f96f51bSksagiyam 17097f96f51bSksagiyam ierr = DMPlexCreatePointNumbering(dm, &globalPointNumbering);CHKERRQ(ierr); 17107f96f51bSksagiyam ierr = DMPlexTopologyView_HDF5_Internal(dm, globalPointNumbering, viewer);CHKERRQ(ierr); 17117f96f51bSksagiyam ierr = ISDestroy(&globalPointNumbering);CHKERRQ(ierr); 171298921bdaSJacob Faibussowitsch } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "PetscViewerFormat %s not supported for HDF5 output.", PetscViewerFormats[format]); 17137f96f51bSksagiyam #else 17147f96f51bSksagiyam SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 17157f96f51bSksagiyam #endif 17167f96f51bSksagiyam } 171702f7d72cSksagiyam ierr = PetscLogEventEnd(DMPLEX_TopologyView,viewer,0,0,0);CHKERRQ(ierr); 17187f96f51bSksagiyam PetscFunctionReturn(0); 17197f96f51bSksagiyam } 17207f96f51bSksagiyam 172177b8e257Sksagiyam /*@ 172277b8e257Sksagiyam DMPlexCoordinatesView - Saves DMPlex coordinates into a file 172377b8e257Sksagiyam 172477b8e257Sksagiyam Collective on DM 172577b8e257Sksagiyam 172677b8e257Sksagiyam Input Parameters: 172777b8e257Sksagiyam + dm - The DM whose coordinates are to be saved 172877b8e257Sksagiyam - viewer - The PetscViewer for saving 172977b8e257Sksagiyam 173077b8e257Sksagiyam Level: advanced 173177b8e257Sksagiyam 173277b8e257Sksagiyam .seealso: DMView(), DMPlexTopologyView(), DMPlexLabelsView(), DMPlexCoordinatesLoad() 173377b8e257Sksagiyam @*/ 173477b8e257Sksagiyam PetscErrorCode DMPlexCoordinatesView(DM dm, PetscViewer viewer) 173577b8e257Sksagiyam { 173677b8e257Sksagiyam PetscBool ishdf5; 173777b8e257Sksagiyam PetscErrorCode ierr; 173877b8e257Sksagiyam 173977b8e257Sksagiyam PetscFunctionBegin; 174077b8e257Sksagiyam PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 174177b8e257Sksagiyam PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 174277b8e257Sksagiyam ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 174302f7d72cSksagiyam ierr = PetscLogEventBegin(DMPLEX_CoordinatesView,viewer,0,0,0);CHKERRQ(ierr); 174477b8e257Sksagiyam if (ishdf5) { 174577b8e257Sksagiyam #if defined(PETSC_HAVE_HDF5) 174677b8e257Sksagiyam PetscViewerFormat format; 174777b8e257Sksagiyam ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 174877b8e257Sksagiyam if (format == PETSC_VIEWER_HDF5_PETSC || format == PETSC_VIEWER_DEFAULT || format == PETSC_VIEWER_NATIVE) { 174977b8e257Sksagiyam ierr = DMPlexCoordinatesView_HDF5_Internal(dm, viewer);CHKERRQ(ierr); 175098921bdaSJacob Faibussowitsch } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "PetscViewerFormat %s not supported for HDF5 input.", PetscViewerFormats[format]); 175177b8e257Sksagiyam #else 175277b8e257Sksagiyam SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 175377b8e257Sksagiyam #endif 175477b8e257Sksagiyam } 175502f7d72cSksagiyam ierr = PetscLogEventEnd(DMPLEX_CoordinatesView,viewer,0,0,0);CHKERRQ(ierr); 175677b8e257Sksagiyam PetscFunctionReturn(0); 175777b8e257Sksagiyam } 175877b8e257Sksagiyam 1759bd6565f1Sksagiyam /*@ 1760bd6565f1Sksagiyam DMPlexLabelsView - Saves DMPlex labels into a file 1761bd6565f1Sksagiyam 1762bd6565f1Sksagiyam Collective on DM 1763bd6565f1Sksagiyam 1764bd6565f1Sksagiyam Input Parameters: 1765bd6565f1Sksagiyam + dm - The DM whose labels are to be saved 1766bd6565f1Sksagiyam - viewer - The PetscViewer for saving 1767bd6565f1Sksagiyam 1768bd6565f1Sksagiyam Level: advanced 1769bd6565f1Sksagiyam 1770bd6565f1Sksagiyam .seealso: DMView(), DMPlexTopologyView(), DMPlexCoordinatesView(), DMPlexLabelsLoad() 1771bd6565f1Sksagiyam @*/ 1772bd6565f1Sksagiyam PetscErrorCode DMPlexLabelsView(DM dm, PetscViewer viewer) 1773bd6565f1Sksagiyam { 1774bd6565f1Sksagiyam PetscBool ishdf5; 1775bd6565f1Sksagiyam PetscErrorCode ierr; 1776bd6565f1Sksagiyam 1777bd6565f1Sksagiyam PetscFunctionBegin; 1778bd6565f1Sksagiyam PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1779bd6565f1Sksagiyam PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1780bd6565f1Sksagiyam ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 178102f7d72cSksagiyam ierr = PetscLogEventBegin(DMPLEX_LabelsView,viewer,0,0,0);CHKERRQ(ierr); 1782bd6565f1Sksagiyam if (ishdf5) { 1783bd6565f1Sksagiyam #if defined(PETSC_HAVE_HDF5) 1784bd6565f1Sksagiyam IS globalPointNumbering; 1785bd6565f1Sksagiyam PetscViewerFormat format; 1786bd6565f1Sksagiyam 1787bd6565f1Sksagiyam ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 1788bd6565f1Sksagiyam if (format == PETSC_VIEWER_HDF5_PETSC || format == PETSC_VIEWER_DEFAULT || format == PETSC_VIEWER_NATIVE) { 1789bd6565f1Sksagiyam ierr = DMPlexCreatePointNumbering(dm, &globalPointNumbering);CHKERRQ(ierr); 1790bd6565f1Sksagiyam ierr = DMPlexLabelsView_HDF5_Internal(dm, globalPointNumbering, viewer);CHKERRQ(ierr); 1791bd6565f1Sksagiyam ierr = ISDestroy(&globalPointNumbering);CHKERRQ(ierr); 179298921bdaSJacob Faibussowitsch } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "PetscViewerFormat %s not supported for HDF5 input.", PetscViewerFormats[format]); 1793bd6565f1Sksagiyam #else 1794bd6565f1Sksagiyam SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 1795bd6565f1Sksagiyam #endif 1796bd6565f1Sksagiyam } 179702f7d72cSksagiyam ierr = PetscLogEventEnd(DMPLEX_LabelsView,viewer,0,0,0);CHKERRQ(ierr); 1798bd6565f1Sksagiyam PetscFunctionReturn(0); 1799bd6565f1Sksagiyam } 1800bd6565f1Sksagiyam 1801021affd3Sksagiyam /*@ 1802021affd3Sksagiyam DMPlexSectionView - Saves a section associated with a DMPlex 1803021affd3Sksagiyam 1804021affd3Sksagiyam Collective on DM 1805021affd3Sksagiyam 1806021affd3Sksagiyam Input Parameters: 1807021affd3Sksagiyam + dm - The DM that contains the topology on which the section to be saved is defined 1808021affd3Sksagiyam . viewer - The PetscViewer for saving 1809021affd3Sksagiyam - sectiondm - The DM that contains the section to be saved 1810021affd3Sksagiyam 1811021affd3Sksagiyam Level: advanced 1812021affd3Sksagiyam 1813021affd3Sksagiyam Notes: 1814021affd3Sksagiyam This function is a wrapper around PetscSectionView(); in addition to the raw section, it saves information that associates the section points to the topology (dm) points. When the topology (dm) and the section are later loaded with DMPlexTopologyLoad() and DMPlexSectionLoad(), respectively, this information is used to match section points with topology points. 1815021affd3Sksagiyam 1816021affd3Sksagiyam In general dm and sectiondm are two different objects, the former carrying the topology and the latter carrying the section, and have been given a topology name and a section name, respectively, with PetscObjectSetName(). In practice, however, they can be the same object if it carries both topology and section; in that case the name of the object is used as both the topology name and the section name. 1817021affd3Sksagiyam 1818021affd3Sksagiyam .seealso: DMView(), DMPlexTopologyView(), DMPlexCoordinatesView(), DMPlexLabelsView(), DMPlexGlobalVectorView(), DMPlexLocalVectorView(), PetscSectionView(), DMPlexSectionLoad() 1819021affd3Sksagiyam @*/ 1820021affd3Sksagiyam PetscErrorCode DMPlexSectionView(DM dm, PetscViewer viewer, DM sectiondm) 1821021affd3Sksagiyam { 1822021affd3Sksagiyam PetscBool ishdf5; 1823021affd3Sksagiyam PetscErrorCode ierr; 1824021affd3Sksagiyam 1825021affd3Sksagiyam PetscFunctionBegin; 1826021affd3Sksagiyam PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1827021affd3Sksagiyam PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1828021affd3Sksagiyam PetscValidHeaderSpecific(sectiondm, DM_CLASSID, 3); 1829021affd3Sksagiyam ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5);CHKERRQ(ierr); 183002f7d72cSksagiyam ierr = PetscLogEventBegin(DMPLEX_SectionView,viewer,0,0,0);CHKERRQ(ierr); 1831021affd3Sksagiyam if (ishdf5) { 1832021affd3Sksagiyam #if defined(PETSC_HAVE_HDF5) 1833021affd3Sksagiyam ierr = DMPlexSectionView_HDF5_Internal(dm, viewer, sectiondm);CHKERRQ(ierr); 1834021affd3Sksagiyam #else 1835021affd3Sksagiyam SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 1836021affd3Sksagiyam #endif 1837021affd3Sksagiyam } 183802f7d72cSksagiyam ierr = PetscLogEventEnd(DMPLEX_SectionView,viewer,0,0,0);CHKERRQ(ierr); 1839021affd3Sksagiyam PetscFunctionReturn(0); 1840021affd3Sksagiyam } 1841021affd3Sksagiyam 18423e97647fSksagiyam /*@ 18433e97647fSksagiyam DMPlexGlobalVectorView - Saves a global vector 18443e97647fSksagiyam 18453e97647fSksagiyam Collective on DM 18463e97647fSksagiyam 18473e97647fSksagiyam Input Parameters: 18483e97647fSksagiyam + dm - The DM that represents the topology 18493e97647fSksagiyam . viewer - The PetscViewer to save data with 18503e97647fSksagiyam . sectiondm - The DM that contains the global section on which vec is defined 18513e97647fSksagiyam - vec - The global vector to be saved 18523e97647fSksagiyam 18533e97647fSksagiyam Level: advanced 18543e97647fSksagiyam 18553e97647fSksagiyam Notes: 18563e97647fSksagiyam In general dm and sectiondm are two different objects, the former carrying the topology and the latter carrying the section, and have been given a topology name and a section name, respectively, with PetscObjectSetName(). In practice, however, they can be the same object if it carries both topology and section; in that case the name of the object is used as both the topology name and the section name. 18573e97647fSksagiyam 18583e97647fSksagiyam Typical calling sequence 18593e97647fSksagiyam $ DMCreate(PETSC_COMM_WORLD, &dm); 18603e97647fSksagiyam $ DMSetType(dm, DMPLEX); 18613e97647fSksagiyam $ PetscObjectSetName((PetscObject)dm, "topologydm_name"); 18623e97647fSksagiyam $ DMClone(dm, §iondm); 18633e97647fSksagiyam $ PetscObjectSetName((PetscObject)sectiondm, "sectiondm_name"); 18643e97647fSksagiyam $ PetscSectionCreate(PETSC_COMM_WORLD, §ion); 18653e97647fSksagiyam $ DMPlexGetChart(sectiondm, &pStart, &pEnd); 18663e97647fSksagiyam $ PetscSectionSetChart(section, pStart, pEnd); 18673e97647fSksagiyam $ PetscSectionSetUp(section); 18683e97647fSksagiyam $ DMSetLocalSection(sectiondm, section); 18693e97647fSksagiyam $ PetscSectionDestroy(§ion); 18703e97647fSksagiyam $ DMGetGlobalVector(sectiondm, &vec); 18713e97647fSksagiyam $ PetscObjectSetName((PetscObject)vec, "vec_name"); 18723e97647fSksagiyam $ DMPlexTopologyView(dm, viewer); 18733e97647fSksagiyam $ DMPlexSectionView(dm, viewer, sectiondm); 18743e97647fSksagiyam $ DMPlexGlobalVectorView(dm, viewer, sectiondm, vec); 18753e97647fSksagiyam $ DMRestoreGlobalVector(sectiondm, &vec); 18763e97647fSksagiyam $ DMDestroy(§iondm); 18773e97647fSksagiyam $ DMDestroy(&dm); 18783e97647fSksagiyam 18793e97647fSksagiyam .seealso: DMPlexTopologyView(), DMPlexSectionView(), DMPlexLocalVectorView(), DMPlexGlobalVectorLoad(), DMPlexLocalVectorLoad() 18803e97647fSksagiyam @*/ 18813e97647fSksagiyam PetscErrorCode DMPlexGlobalVectorView(DM dm, PetscViewer viewer, DM sectiondm, Vec vec) 18823e97647fSksagiyam { 18833e97647fSksagiyam PetscBool ishdf5; 18843e97647fSksagiyam PetscErrorCode ierr; 18853e97647fSksagiyam 18863e97647fSksagiyam PetscFunctionBegin; 18873e97647fSksagiyam PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 18883e97647fSksagiyam PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 18893e97647fSksagiyam PetscValidHeaderSpecific(sectiondm, DM_CLASSID, 3); 18903e97647fSksagiyam PetscValidHeaderSpecific(vec, VEC_CLASSID, 4); 18913e97647fSksagiyam /* Check consistency */ 18923e97647fSksagiyam { 18933e97647fSksagiyam PetscSection section; 18943e97647fSksagiyam PetscBool includesConstraints; 18953e97647fSksagiyam PetscInt m, m1; 18963e97647fSksagiyam 18973e97647fSksagiyam ierr = VecGetLocalSize(vec, &m1);CHKERRQ(ierr); 18983e97647fSksagiyam ierr = DMGetGlobalSection(sectiondm, §ion);CHKERRQ(ierr); 18993e97647fSksagiyam ierr = PetscSectionGetIncludesConstraints(section, &includesConstraints);CHKERRQ(ierr); 19003e97647fSksagiyam if (includesConstraints) {ierr = PetscSectionGetStorageSize(section, &m);CHKERRQ(ierr);} 19013e97647fSksagiyam else {ierr = PetscSectionGetConstrainedStorageSize(section, &m);CHKERRQ(ierr);} 19022c71b3e2SJacob Faibussowitsch PetscCheckFalse(m1 != m,PETSC_COMM_SELF, PETSC_ERR_PLIB, "Global vector size (%D) != global section storage size (%D)", m1, m); 19033e97647fSksagiyam } 19043e97647fSksagiyam ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 190502f7d72cSksagiyam ierr = PetscLogEventBegin(DMPLEX_GlobalVectorView,viewer,0,0,0);CHKERRQ(ierr); 19063e97647fSksagiyam if (ishdf5) { 19073e97647fSksagiyam #if defined(PETSC_HAVE_HDF5) 19083e97647fSksagiyam ierr = DMPlexGlobalVectorView_HDF5_Internal(dm, viewer, sectiondm, vec);CHKERRQ(ierr); 19093e97647fSksagiyam #else 19103e97647fSksagiyam SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 19113e97647fSksagiyam #endif 19123e97647fSksagiyam } 191302f7d72cSksagiyam ierr = PetscLogEventEnd(DMPLEX_GlobalVectorView,viewer,0,0,0);CHKERRQ(ierr); 19143e97647fSksagiyam PetscFunctionReturn(0); 19153e97647fSksagiyam } 19163e97647fSksagiyam 19173e97647fSksagiyam /*@ 19183e97647fSksagiyam DMPlexLocalVectorView - Saves a local vector 19193e97647fSksagiyam 19203e97647fSksagiyam Collective on DM 19213e97647fSksagiyam 19223e97647fSksagiyam Input Parameters: 19233e97647fSksagiyam + dm - The DM that represents the topology 19243e97647fSksagiyam . viewer - The PetscViewer to save data with 19253e97647fSksagiyam . sectiondm - The DM that contains the local section on which vec is defined; may be the same as dm 19263e97647fSksagiyam - vec - The local vector to be saved 19273e97647fSksagiyam 19283e97647fSksagiyam Level: advanced 19293e97647fSksagiyam 19303e97647fSksagiyam Notes: 19313e97647fSksagiyam In general dm and sectiondm are two different objects, the former carrying the topology and the latter carrying the section, and have been given a topology name and a section name, respectively, with PetscObjectSetName(). In practice, however, they can be the same object if it carries both topology and section; in that case the name of the object is used as both the topology name and the section name. 19323e97647fSksagiyam 19333e97647fSksagiyam Typical calling sequence 19343e97647fSksagiyam $ DMCreate(PETSC_COMM_WORLD, &dm); 19353e97647fSksagiyam $ DMSetType(dm, DMPLEX); 19363e97647fSksagiyam $ PetscObjectSetName((PetscObject)dm, "topologydm_name"); 19373e97647fSksagiyam $ DMClone(dm, §iondm); 19383e97647fSksagiyam $ PetscObjectSetName((PetscObject)sectiondm, "sectiondm_name"); 19393e97647fSksagiyam $ PetscSectionCreate(PETSC_COMM_WORLD, §ion); 19403e97647fSksagiyam $ DMPlexGetChart(sectiondm, &pStart, &pEnd); 19413e97647fSksagiyam $ PetscSectionSetChart(section, pStart, pEnd); 19423e97647fSksagiyam $ PetscSectionSetUp(section); 19433e97647fSksagiyam $ DMSetLocalSection(sectiondm, section); 19443e97647fSksagiyam $ DMGetLocalVector(sectiondm, &vec); 19453e97647fSksagiyam $ PetscObjectSetName((PetscObject)vec, "vec_name"); 19463e97647fSksagiyam $ DMPlexTopologyView(dm, viewer); 19473e97647fSksagiyam $ DMPlexSectionView(dm, viewer, sectiondm); 19483e97647fSksagiyam $ DMPlexLocalVectorView(dm, viewer, sectiondm, vec); 19493e97647fSksagiyam $ DMRestoreLocalVector(sectiondm, &vec); 19503e97647fSksagiyam $ DMDestroy(§iondm); 19513e97647fSksagiyam $ DMDestroy(&dm); 19523e97647fSksagiyam 19533e97647fSksagiyam .seealso: DMPlexTopologyView(), DMPlexSectionView(), DMPlexGlobalVectorView(), DMPlexGlobalVectorLoad(), DMPlexLocalVectorLoad() 19543e97647fSksagiyam @*/ 19553e97647fSksagiyam PetscErrorCode DMPlexLocalVectorView(DM dm, PetscViewer viewer, DM sectiondm, Vec vec) 19563e97647fSksagiyam { 19573e97647fSksagiyam PetscBool ishdf5; 19583e97647fSksagiyam PetscErrorCode ierr; 19593e97647fSksagiyam 19603e97647fSksagiyam PetscFunctionBegin; 19613e97647fSksagiyam PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 19623e97647fSksagiyam PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 19633e97647fSksagiyam PetscValidHeaderSpecific(sectiondm, DM_CLASSID, 3); 19643e97647fSksagiyam PetscValidHeaderSpecific(vec, VEC_CLASSID, 4); 19653e97647fSksagiyam /* Check consistency */ 19663e97647fSksagiyam { 19673e97647fSksagiyam PetscSection section; 19683e97647fSksagiyam PetscBool includesConstraints; 19693e97647fSksagiyam PetscInt m, m1; 19703e97647fSksagiyam 19713e97647fSksagiyam ierr = VecGetLocalSize(vec, &m1);CHKERRQ(ierr); 19723e97647fSksagiyam ierr = DMGetLocalSection(sectiondm, §ion);CHKERRQ(ierr); 19733e97647fSksagiyam ierr = PetscSectionGetIncludesConstraints(section, &includesConstraints);CHKERRQ(ierr); 19743e97647fSksagiyam if (includesConstraints) {ierr = PetscSectionGetStorageSize(section, &m);CHKERRQ(ierr);} 19753e97647fSksagiyam else {ierr = PetscSectionGetConstrainedStorageSize(section, &m);CHKERRQ(ierr);} 19762c71b3e2SJacob Faibussowitsch PetscCheckFalse(m1 != m,PETSC_COMM_SELF, PETSC_ERR_PLIB, "Local vector size (%D) != local section storage size (%D)", m1, m); 19773e97647fSksagiyam } 19783e97647fSksagiyam ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 197902f7d72cSksagiyam ierr = PetscLogEventBegin(DMPLEX_LocalVectorView,viewer,0,0,0);CHKERRQ(ierr); 19803e97647fSksagiyam if (ishdf5) { 19813e97647fSksagiyam #if defined(PETSC_HAVE_HDF5) 19823e97647fSksagiyam ierr = DMPlexLocalVectorView_HDF5_Internal(dm, viewer, sectiondm, vec);CHKERRQ(ierr); 19833e97647fSksagiyam #else 19843e97647fSksagiyam SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 19853e97647fSksagiyam #endif 19863e97647fSksagiyam } 198702f7d72cSksagiyam ierr = PetscLogEventEnd(DMPLEX_LocalVectorView,viewer,0,0,0);CHKERRQ(ierr); 19883e97647fSksagiyam PetscFunctionReturn(0); 19893e97647fSksagiyam } 19903e97647fSksagiyam 19912c40f234SMatthew G. Knepley PetscErrorCode DMLoad_Plex(DM dm, PetscViewer viewer) 19922c40f234SMatthew G. Knepley { 1993d4f5a9a0SVaclav Hapla PetscBool ishdf5; 19942c40f234SMatthew G. Knepley PetscErrorCode ierr; 19952c40f234SMatthew G. Knepley 19962c40f234SMatthew G. Knepley PetscFunctionBegin; 19972c40f234SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 19982c40f234SMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 19992c40f234SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 2000d4f5a9a0SVaclav Hapla if (ishdf5) { 20012c40f234SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 20029c48423bSVaclav Hapla PetscViewerFormat format; 20039c48423bSVaclav Hapla ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 20049c48423bSVaclav Hapla if (format == PETSC_VIEWER_HDF5_XDMF || format == PETSC_VIEWER_HDF5_VIZ) { 20059c48423bSVaclav Hapla ierr = DMPlexLoad_HDF5_Xdmf_Internal(dm, viewer);CHKERRQ(ierr); 2006509517efSVaclav Hapla } else if (format == PETSC_VIEWER_HDF5_PETSC || format == PETSC_VIEWER_DEFAULT || format == PETSC_VIEWER_NATIVE) { 200739d25373SMatthew G. Knepley ierr = DMPlexLoad_HDF5_Internal(dm, viewer);CHKERRQ(ierr); 200898921bdaSJacob Faibussowitsch } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "PetscViewerFormat %s not supported for HDF5 input.", PetscViewerFormats[format]); 2009b458e8f1SJose E. Roman PetscFunctionReturn(0); 20102c40f234SMatthew G. Knepley #else 20112c40f234SMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 2012552f7358SJed Brown #endif 201398921bdaSJacob Faibussowitsch } else SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Viewer type %s not yet supported for DMPlex loading", ((PetscObject)viewer)->type_name); 2014552f7358SJed Brown } 2015552f7358SJed Brown 2016ea8e1828Sksagiyam /*@ 2017ea8e1828Sksagiyam DMPlexTopologyLoad - Loads a topology into a DMPlex 2018ea8e1828Sksagiyam 2019ea8e1828Sksagiyam Collective on DM 2020ea8e1828Sksagiyam 2021ea8e1828Sksagiyam Input Parameters: 2022ea8e1828Sksagiyam + dm - The DM into which the topology is loaded 2023ea8e1828Sksagiyam - viewer - The PetscViewer for the saved topology 2024ea8e1828Sksagiyam 2025dec9e869Sksagiyam Output Parameters: 2026f84dd6b4Sksagiyam . globalToLocalPointSF - The PetscSF that pushes points in [0, N) to the associated points in the loaded plex, where N is the global number of points; NULL if unneeded 2027dec9e869Sksagiyam 2028ea8e1828Sksagiyam Level: advanced 2029ea8e1828Sksagiyam 2030b08ad5deSksagiyam .seealso: DMLoad(), DMPlexCoordinatesLoad(), DMPlexLabelsLoad(), DMView(), PetscViewerHDF5Open(), PetscViewerPushFormat() 2031ea8e1828Sksagiyam @*/ 2032f84dd6b4Sksagiyam PetscErrorCode DMPlexTopologyLoad(DM dm, PetscViewer viewer, PetscSF *globalToLocalPointSF) 2033ea8e1828Sksagiyam { 2034ea8e1828Sksagiyam PetscBool ishdf5; 2035ea8e1828Sksagiyam PetscErrorCode ierr; 2036ea8e1828Sksagiyam 2037ea8e1828Sksagiyam PetscFunctionBegin; 2038ea8e1828Sksagiyam PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2039ea8e1828Sksagiyam PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 2040f84dd6b4Sksagiyam if (globalToLocalPointSF) PetscValidPointer(globalToLocalPointSF, 3); 2041ea8e1828Sksagiyam ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 204202f7d72cSksagiyam ierr = PetscLogEventBegin(DMPLEX_TopologyLoad,viewer,0,0,0);CHKERRQ(ierr); 2043ea8e1828Sksagiyam if (ishdf5) { 2044ea8e1828Sksagiyam #if defined(PETSC_HAVE_HDF5) 2045ea8e1828Sksagiyam PetscViewerFormat format; 2046ea8e1828Sksagiyam ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 2047ea8e1828Sksagiyam if (format == PETSC_VIEWER_HDF5_PETSC || format == PETSC_VIEWER_DEFAULT || format == PETSC_VIEWER_NATIVE) { 2048f84dd6b4Sksagiyam ierr = DMPlexTopologyLoad_HDF5_Internal(dm, viewer, globalToLocalPointSF);CHKERRQ(ierr); 204998921bdaSJacob Faibussowitsch } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "PetscViewerFormat %s not supported for HDF5 input.", PetscViewerFormats[format]); 2050ea8e1828Sksagiyam #else 2051ea8e1828Sksagiyam SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 2052ea8e1828Sksagiyam #endif 2053ea8e1828Sksagiyam } 205402f7d72cSksagiyam ierr = PetscLogEventEnd(DMPLEX_TopologyLoad,viewer,0,0,0);CHKERRQ(ierr); 2055ea8e1828Sksagiyam PetscFunctionReturn(0); 2056ea8e1828Sksagiyam } 2057ea8e1828Sksagiyam 20583e701f1cSksagiyam /*@ 20593e701f1cSksagiyam DMPlexCoordinatesLoad - Loads coordinates into a DMPlex 20603e701f1cSksagiyam 20613e701f1cSksagiyam Collective on DM 20623e701f1cSksagiyam 20633e701f1cSksagiyam Input Parameters: 20643e701f1cSksagiyam + dm - The DM into which the coordinates are loaded 2065c9ad657eSksagiyam . viewer - The PetscViewer for the saved coordinates 2066c9ad657eSksagiyam - globalToLocalPointSF - The SF returned by DMPlexTopologyLoad() when loading dm from viewer 20673e701f1cSksagiyam 20683e701f1cSksagiyam Level: advanced 20693e701f1cSksagiyam 2070b08ad5deSksagiyam .seealso: DMLoad(), DMPlexTopologyLoad(), DMPlexLabelsLoad(), DMView(), PetscViewerHDF5Open(), PetscViewerPushFormat() 20713e701f1cSksagiyam @*/ 2072c9ad657eSksagiyam PetscErrorCode DMPlexCoordinatesLoad(DM dm, PetscViewer viewer, PetscSF globalToLocalPointSF) 20733e701f1cSksagiyam { 20743e701f1cSksagiyam PetscBool ishdf5; 20753e701f1cSksagiyam PetscErrorCode ierr; 20763e701f1cSksagiyam 20773e701f1cSksagiyam PetscFunctionBegin; 20783e701f1cSksagiyam PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 20793e701f1cSksagiyam PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 2080c9ad657eSksagiyam PetscValidHeaderSpecific(globalToLocalPointSF, PETSCSF_CLASSID, 3); 20813e701f1cSksagiyam ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 208202f7d72cSksagiyam ierr = PetscLogEventBegin(DMPLEX_CoordinatesLoad,viewer,0,0,0);CHKERRQ(ierr); 20833e701f1cSksagiyam if (ishdf5) { 20843e701f1cSksagiyam #if defined(PETSC_HAVE_HDF5) 20853e701f1cSksagiyam PetscViewerFormat format; 20863e701f1cSksagiyam ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 20873e701f1cSksagiyam if (format == PETSC_VIEWER_HDF5_PETSC || format == PETSC_VIEWER_DEFAULT || format == PETSC_VIEWER_NATIVE) { 2088c9ad657eSksagiyam ierr = DMPlexCoordinatesLoad_HDF5_Internal(dm, viewer, globalToLocalPointSF);CHKERRQ(ierr); 208998921bdaSJacob Faibussowitsch } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "PetscViewerFormat %s not supported for HDF5 input.", PetscViewerFormats[format]); 20903e701f1cSksagiyam #else 20913e701f1cSksagiyam SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 20923e701f1cSksagiyam #endif 20933e701f1cSksagiyam } 209402f7d72cSksagiyam ierr = PetscLogEventEnd(DMPLEX_CoordinatesLoad,viewer,0,0,0);CHKERRQ(ierr); 20953e701f1cSksagiyam PetscFunctionReturn(0); 20963e701f1cSksagiyam } 20973e701f1cSksagiyam 2098b08ad5deSksagiyam /*@ 2099b08ad5deSksagiyam DMPlexLabelsLoad - Loads labels into a DMPlex 2100b08ad5deSksagiyam 2101b08ad5deSksagiyam Collective on DM 2102b08ad5deSksagiyam 2103b08ad5deSksagiyam Input Parameters: 2104b08ad5deSksagiyam + dm - The DM into which the labels are loaded 2105e6368b79SVaclav Hapla . viewer - The PetscViewer for the saved labels 2106e6368b79SVaclav Hapla - globalToLocalPointSF - The SF returned by DMPlexTopologyLoad() when loading dm from viewer 2107b08ad5deSksagiyam 2108b08ad5deSksagiyam Level: advanced 2109b08ad5deSksagiyam 2110e6368b79SVaclav Hapla Notes: 2111e6368b79SVaclav Hapla The PetscSF argument must not be NULL if the DM is distributed, otherwise an error occurs. 2112e6368b79SVaclav Hapla 2113b08ad5deSksagiyam .seealso: DMLoad(), DMPlexTopologyLoad(), DMPlexCoordinatesLoad(), DMView(), PetscViewerHDF5Open(), PetscViewerPushFormat() 2114b08ad5deSksagiyam @*/ 2115e6368b79SVaclav Hapla PetscErrorCode DMPlexLabelsLoad(DM dm, PetscViewer viewer, PetscSF globalToLocalPointSF) 2116b08ad5deSksagiyam { 2117b08ad5deSksagiyam PetscBool ishdf5; 2118b08ad5deSksagiyam PetscErrorCode ierr; 2119b08ad5deSksagiyam 2120b08ad5deSksagiyam PetscFunctionBegin; 2121b08ad5deSksagiyam PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2122b08ad5deSksagiyam PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 2123e6368b79SVaclav Hapla if (globalToLocalPointSF) PetscValidHeaderSpecific(globalToLocalPointSF, PETSCSF_CLASSID, 3); 2124b08ad5deSksagiyam ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 212502f7d72cSksagiyam ierr = PetscLogEventBegin(DMPLEX_LabelsLoad,viewer,0,0,0);CHKERRQ(ierr); 2126b08ad5deSksagiyam if (ishdf5) { 2127b08ad5deSksagiyam #if defined(PETSC_HAVE_HDF5) 2128b08ad5deSksagiyam PetscViewerFormat format; 2129b08ad5deSksagiyam 2130b08ad5deSksagiyam ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 2131b08ad5deSksagiyam if (format == PETSC_VIEWER_HDF5_PETSC || format == PETSC_VIEWER_DEFAULT || format == PETSC_VIEWER_NATIVE) { 2132e6368b79SVaclav Hapla ierr = DMPlexLabelsLoad_HDF5_Internal(dm, viewer, globalToLocalPointSF);CHKERRQ(ierr); 213398921bdaSJacob Faibussowitsch } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "PetscViewerFormat %s not supported for HDF5 input.", PetscViewerFormats[format]); 2134b08ad5deSksagiyam #else 2135b08ad5deSksagiyam SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 2136b08ad5deSksagiyam #endif 2137b08ad5deSksagiyam } 213802f7d72cSksagiyam ierr = PetscLogEventEnd(DMPLEX_LabelsLoad,viewer,0,0,0);CHKERRQ(ierr); 2139b08ad5deSksagiyam PetscFunctionReturn(0); 2140b08ad5deSksagiyam } 2141b08ad5deSksagiyam 2142f84dd6b4Sksagiyam /*@ 2143f84dd6b4Sksagiyam DMPlexSectionLoad - Loads section into a DMPlex 2144f84dd6b4Sksagiyam 2145f84dd6b4Sksagiyam Collective on DM 2146f84dd6b4Sksagiyam 2147f84dd6b4Sksagiyam Input Parameters: 2148f84dd6b4Sksagiyam + dm - The DM that represents the topology 2149f84dd6b4Sksagiyam . viewer - The PetscViewer that represents the on-disk section (sectionA) 2150f84dd6b4Sksagiyam . sectiondm - The DM into which the on-disk section (sectionA) is migrated 2151f84dd6b4Sksagiyam - globalToLocalPointSF - The SF returned by DMPlexTopologyLoad() when loading dm from viewer 2152f84dd6b4Sksagiyam 2153f84dd6b4Sksagiyam Output Parameters 2154f84dd6b4Sksagiyam + globalDofSF - The SF that migrates any on-disk Vec data associated with sectionA into a global Vec associated with the sectiondm's global section (NULL if not needed) 2155f84dd6b4Sksagiyam - localDofSF - The SF that migrates any on-disk Vec data associated with sectionA into a local Vec associated with the sectiondm's local section (NULL if not needed) 2156f84dd6b4Sksagiyam 2157f84dd6b4Sksagiyam Level: advanced 2158f84dd6b4Sksagiyam 2159f84dd6b4Sksagiyam Notes: 2160f84dd6b4Sksagiyam This function is a wrapper around PetscSectionLoad(); it loads, in addition to the raw section, a list of global point numbers that associates each on-disk section point with a global point number in [0, NX), where NX is the number of topology points in dm. Noting that globalToLocalPointSF associates each topology point in dm with a global number in [0, NX), one can readily establish an association of the on-disk section points with the topology points. 2161f84dd6b4Sksagiyam 2162f84dd6b4Sksagiyam In general dm and sectiondm are two different objects, the former carrying the topology and the latter carrying the section, and have been given a topology name and a section name, respectively, with PetscObjectSetName(). In practice, however, they can be the same object if it carries both topology and section; in that case the name of the object is used as both the topology name and the section name. 2163f84dd6b4Sksagiyam 2164f84dd6b4Sksagiyam The output parameter, globalDofSF (localDofSF), can later be used with DMPlexGlobalVectorLoad() (DMPlexLocalVectorLoad()) to load on-disk vectors into global (local) vectors associated with sectiondm's global (local) section. 2165f84dd6b4Sksagiyam 2166f84dd6b4Sksagiyam Example using 2 processes: 2167f84dd6b4Sksagiyam $ NX (number of points on dm): 4 2168f84dd6b4Sksagiyam $ sectionA : the on-disk section 2169f84dd6b4Sksagiyam $ vecA : a vector associated with sectionA 2170f84dd6b4Sksagiyam $ sectionB : sectiondm's local section constructed in this function 2171f84dd6b4Sksagiyam $ vecB (local) : a vector associated with sectiondm's local section 2172f84dd6b4Sksagiyam $ vecB (global) : a vector associated with sectiondm's global section 2173f84dd6b4Sksagiyam $ 2174f84dd6b4Sksagiyam $ rank 0 rank 1 2175f84dd6b4Sksagiyam $ vecA (global) : [.0 .4 .1 | .2 .3] <- to be loaded in DMPlexGlobalVectorLoad() or DMPlexLocalVectorLoad() 2176f84dd6b4Sksagiyam $ sectionA->atlasOff : 0 2 | 1 <- loaded in PetscSectionLoad() 2177f84dd6b4Sksagiyam $ sectionA->atlasDof : 1 3 | 1 <- loaded in PetscSectionLoad() 2178f84dd6b4Sksagiyam $ sectionA's global point numbers: 0 2 | 3 <- loaded in DMPlexSectionLoad() 2179f84dd6b4Sksagiyam $ [0, NX) : 0 1 | 2 3 <- conceptual partition used in globalToLocalPointSF 2180f84dd6b4Sksagiyam $ sectionB's global point numbers: 0 1 3 | 3 2 <- associated with [0, NX) by globalToLocalPointSF 2181f84dd6b4Sksagiyam $ sectionB->atlasDof : 1 0 1 | 1 3 2182f84dd6b4Sksagiyam $ sectionB->atlasOff (no perm) : 0 1 1 | 0 1 2183f84dd6b4Sksagiyam $ vecB (local) : [.0 .4] | [.4 .1 .2 .3] <- to be constructed by calling DMPlexLocalVectorLoad() with localDofSF 2184f84dd6b4Sksagiyam $ vecB (global) : [.0 .4 | .1 .2 .3] <- to be constructed by calling DMPlexGlobalVectorLoad() with globalDofSF 2185f84dd6b4Sksagiyam $ 2186f84dd6b4Sksagiyam $ where "|" represents a partition of loaded data, and global point 3 is assumed to be owned by rank 0. 2187f84dd6b4Sksagiyam 2188f84dd6b4Sksagiyam .seealso: DMLoad(), DMPlexTopologyLoad(), DMPlexCoordinatesLoad(), DMPlexLabelsLoad(), DMPlexGlobalVectorLoad(), DMPlexLocalVectorLoad(), PetscSectionLoad(), DMPlexSectionView() 2189f84dd6b4Sksagiyam @*/ 2190f84dd6b4Sksagiyam PetscErrorCode DMPlexSectionLoad(DM dm, PetscViewer viewer, DM sectiondm, PetscSF globalToLocalPointSF, PetscSF *globalDofSF, PetscSF *localDofSF) 2191f84dd6b4Sksagiyam { 2192f84dd6b4Sksagiyam PetscBool ishdf5; 2193f84dd6b4Sksagiyam PetscErrorCode ierr; 2194f84dd6b4Sksagiyam 2195f84dd6b4Sksagiyam PetscFunctionBegin; 2196f84dd6b4Sksagiyam PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2197f84dd6b4Sksagiyam PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 2198f84dd6b4Sksagiyam PetscValidHeaderSpecific(sectiondm, DM_CLASSID, 3); 2199f84dd6b4Sksagiyam PetscValidHeaderSpecific(globalToLocalPointSF, PETSCSF_CLASSID, 4); 2200f84dd6b4Sksagiyam if (globalDofSF) PetscValidPointer(globalDofSF, 5); 2201f84dd6b4Sksagiyam if (localDofSF) PetscValidPointer(localDofSF, 6); 2202f84dd6b4Sksagiyam ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5);CHKERRQ(ierr); 220302f7d72cSksagiyam ierr = PetscLogEventBegin(DMPLEX_SectionLoad,viewer,0,0,0);CHKERRQ(ierr); 2204f84dd6b4Sksagiyam if (ishdf5) { 2205f84dd6b4Sksagiyam #if defined(PETSC_HAVE_HDF5) 2206f84dd6b4Sksagiyam ierr = DMPlexSectionLoad_HDF5_Internal(dm, viewer, sectiondm, globalToLocalPointSF, globalDofSF, localDofSF);CHKERRQ(ierr); 2207f84dd6b4Sksagiyam #else 2208f84dd6b4Sksagiyam SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 2209f84dd6b4Sksagiyam #endif 2210f84dd6b4Sksagiyam } 221102f7d72cSksagiyam ierr = PetscLogEventEnd(DMPLEX_SectionLoad,viewer,0,0,0);CHKERRQ(ierr); 2212f84dd6b4Sksagiyam PetscFunctionReturn(0); 2213f84dd6b4Sksagiyam } 2214f84dd6b4Sksagiyam 22158be3dfe1Sksagiyam /*@ 22168be3dfe1Sksagiyam DMPlexGlobalVectorLoad - Loads on-disk vector data into a global vector 22178be3dfe1Sksagiyam 22188be3dfe1Sksagiyam Collective on DM 22198be3dfe1Sksagiyam 22208be3dfe1Sksagiyam Input Parameters: 22218be3dfe1Sksagiyam + dm - The DM that represents the topology 22228be3dfe1Sksagiyam . viewer - The PetscViewer that represents the on-disk vector data 22238be3dfe1Sksagiyam . sectiondm - The DM that contains the global section on which vec is defined 22248be3dfe1Sksagiyam . sf - The SF that migrates the on-disk vector data into vec 22258be3dfe1Sksagiyam - vec - The global vector to set values of 22268be3dfe1Sksagiyam 22278be3dfe1Sksagiyam Level: advanced 22288be3dfe1Sksagiyam 22298be3dfe1Sksagiyam Notes: 22308be3dfe1Sksagiyam In general dm and sectiondm are two different objects, the former carrying the topology and the latter carrying the section, and have been given a topology name and a section name, respectively, with PetscObjectSetName(). In practice, however, they can be the same object if it carries both topology and section; in that case the name of the object is used as both the topology name and the section name. 22318be3dfe1Sksagiyam 22328be3dfe1Sksagiyam Typical calling sequence 22338be3dfe1Sksagiyam $ DMCreate(PETSC_COMM_WORLD, &dm); 22348be3dfe1Sksagiyam $ DMSetType(dm, DMPLEX); 22358be3dfe1Sksagiyam $ PetscObjectSetName((PetscObject)dm, "topologydm_name"); 22368be3dfe1Sksagiyam $ DMPlexTopologyLoad(dm, viewer, &sfX); 22378be3dfe1Sksagiyam $ DMClone(dm, §iondm); 22388be3dfe1Sksagiyam $ PetscObjectSetName((PetscObject)sectiondm, "sectiondm_name"); 22398be3dfe1Sksagiyam $ DMPlexSectionLoad(dm, viewer, sectiondm, sfX, &gsf, NULL); 22408be3dfe1Sksagiyam $ DMGetGlobalVector(sectiondm, &vec); 22418be3dfe1Sksagiyam $ PetscObjectSetName((PetscObject)vec, "vec_name"); 22428be3dfe1Sksagiyam $ DMPlexGlobalVectorLoad(dm, viewer, sectiondm, gsf, vec); 22438be3dfe1Sksagiyam $ DMRestoreGlobalVector(sectiondm, &vec); 22448be3dfe1Sksagiyam $ PetscSFDestroy(&gsf); 22458be3dfe1Sksagiyam $ PetscSFDestroy(&sfX); 22468be3dfe1Sksagiyam $ DMDestroy(§iondm); 22478be3dfe1Sksagiyam $ DMDestroy(&dm); 22488be3dfe1Sksagiyam 22498be3dfe1Sksagiyam .seealso: DMPlexTopologyLoad(), DMPlexSectionLoad(), DMPlexLocalVectorLoad(), DMPlexGlobalVectorView(), DMPlexLocalVectorView() 22508be3dfe1Sksagiyam @*/ 22518be3dfe1Sksagiyam PetscErrorCode DMPlexGlobalVectorLoad(DM dm, PetscViewer viewer, DM sectiondm, PetscSF sf, Vec vec) 22528be3dfe1Sksagiyam { 22538be3dfe1Sksagiyam PetscBool ishdf5; 22548be3dfe1Sksagiyam PetscErrorCode ierr; 22558be3dfe1Sksagiyam 22568be3dfe1Sksagiyam PetscFunctionBegin; 22578be3dfe1Sksagiyam PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 22588be3dfe1Sksagiyam PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 22598be3dfe1Sksagiyam PetscValidHeaderSpecific(sectiondm, DM_CLASSID, 3); 22608be3dfe1Sksagiyam PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 4); 22618be3dfe1Sksagiyam PetscValidHeaderSpecific(vec, VEC_CLASSID, 5); 22628be3dfe1Sksagiyam /* Check consistency */ 22638be3dfe1Sksagiyam { 22648be3dfe1Sksagiyam PetscSection section; 22658be3dfe1Sksagiyam PetscBool includesConstraints; 22668be3dfe1Sksagiyam PetscInt m, m1; 22678be3dfe1Sksagiyam 22688be3dfe1Sksagiyam ierr = VecGetLocalSize(vec, &m1);CHKERRQ(ierr); 22698be3dfe1Sksagiyam ierr = DMGetGlobalSection(sectiondm, §ion);CHKERRQ(ierr); 22708be3dfe1Sksagiyam ierr = PetscSectionGetIncludesConstraints(section, &includesConstraints);CHKERRQ(ierr); 22718be3dfe1Sksagiyam if (includesConstraints) {ierr = PetscSectionGetStorageSize(section, &m);CHKERRQ(ierr);} 22728be3dfe1Sksagiyam else {ierr = PetscSectionGetConstrainedStorageSize(section, &m);CHKERRQ(ierr);} 22732c71b3e2SJacob Faibussowitsch PetscCheckFalse(m1 != m,PETSC_COMM_SELF, PETSC_ERR_PLIB, "Global vector size (%D) != global section storage size (%D)", m1, m); 22748be3dfe1Sksagiyam } 22758be3dfe1Sksagiyam ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5);CHKERRQ(ierr); 227602f7d72cSksagiyam ierr = PetscLogEventBegin(DMPLEX_GlobalVectorLoad,viewer,0,0,0);CHKERRQ(ierr); 22778be3dfe1Sksagiyam if (ishdf5) { 22788be3dfe1Sksagiyam #if defined(PETSC_HAVE_HDF5) 22798be3dfe1Sksagiyam ierr = DMPlexVecLoad_HDF5_Internal(dm, viewer, sectiondm, sf, vec);CHKERRQ(ierr); 22808be3dfe1Sksagiyam #else 22818be3dfe1Sksagiyam SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 22828be3dfe1Sksagiyam #endif 22838be3dfe1Sksagiyam } 228402f7d72cSksagiyam ierr = PetscLogEventEnd(DMPLEX_GlobalVectorLoad,viewer,0,0,0);CHKERRQ(ierr); 22858be3dfe1Sksagiyam PetscFunctionReturn(0); 22868be3dfe1Sksagiyam } 22878be3dfe1Sksagiyam 22888be3dfe1Sksagiyam /*@ 22898be3dfe1Sksagiyam DMPlexLocalVectorLoad - Loads on-disk vector data into a local vector 22908be3dfe1Sksagiyam 22918be3dfe1Sksagiyam Collective on DM 22928be3dfe1Sksagiyam 22938be3dfe1Sksagiyam Input Parameters: 22948be3dfe1Sksagiyam + dm - The DM that represents the topology 22958be3dfe1Sksagiyam . viewer - The PetscViewer that represents the on-disk vector data 22968be3dfe1Sksagiyam . sectiondm - The DM that contains the local section on which vec is defined 22978be3dfe1Sksagiyam . sf - The SF that migrates the on-disk vector data into vec 22988be3dfe1Sksagiyam - vec - The local vector to set values of 22998be3dfe1Sksagiyam 23008be3dfe1Sksagiyam Level: advanced 23018be3dfe1Sksagiyam 23028be3dfe1Sksagiyam Notes: 23038be3dfe1Sksagiyam In general dm and sectiondm are two different objects, the former carrying the topology and the latter carrying the section, and have been given a topology name and a section name, respectively, with PetscObjectSetName(). In practice, however, they can be the same object if it carries both topology and section; in that case the name of the object is used as both the topology name and the section name. 23048be3dfe1Sksagiyam 23058be3dfe1Sksagiyam Typical calling sequence 23068be3dfe1Sksagiyam $ DMCreate(PETSC_COMM_WORLD, &dm); 23078be3dfe1Sksagiyam $ DMSetType(dm, DMPLEX); 23088be3dfe1Sksagiyam $ PetscObjectSetName((PetscObject)dm, "topologydm_name"); 23098be3dfe1Sksagiyam $ DMPlexTopologyLoad(dm, viewer, &sfX); 23108be3dfe1Sksagiyam $ DMClone(dm, §iondm); 23118be3dfe1Sksagiyam $ PetscObjectSetName((PetscObject)sectiondm, "sectiondm_name"); 23128be3dfe1Sksagiyam $ DMPlexSectionLoad(dm, viewer, sectiondm, sfX, NULL, &lsf); 23138be3dfe1Sksagiyam $ DMGetLocalVector(sectiondm, &vec); 23148be3dfe1Sksagiyam $ PetscObjectSetName((PetscObject)vec, "vec_name"); 23158be3dfe1Sksagiyam $ DMPlexLocalVectorLoad(dm, viewer, sectiondm, lsf, vec); 23168be3dfe1Sksagiyam $ DMRestoreLocalVector(sectiondm, &vec); 23178be3dfe1Sksagiyam $ PetscSFDestroy(&lsf); 23188be3dfe1Sksagiyam $ PetscSFDestroy(&sfX); 23198be3dfe1Sksagiyam $ DMDestroy(§iondm); 23208be3dfe1Sksagiyam $ DMDestroy(&dm); 23218be3dfe1Sksagiyam 23228be3dfe1Sksagiyam .seealso: DMPlexTopologyLoad(), DMPlexSectionLoad(), DMPlexGlobalVectorLoad(), DMPlexGlobalVectorView(), DMPlexLocalVectorView() 23238be3dfe1Sksagiyam @*/ 23248be3dfe1Sksagiyam PetscErrorCode DMPlexLocalVectorLoad(DM dm, PetscViewer viewer, DM sectiondm, PetscSF sf, Vec vec) 23258be3dfe1Sksagiyam { 23268be3dfe1Sksagiyam PetscBool ishdf5; 23278be3dfe1Sksagiyam PetscErrorCode ierr; 23288be3dfe1Sksagiyam 23298be3dfe1Sksagiyam PetscFunctionBegin; 23308be3dfe1Sksagiyam PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 23318be3dfe1Sksagiyam PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 23328be3dfe1Sksagiyam PetscValidHeaderSpecific(sectiondm, DM_CLASSID, 3); 23338be3dfe1Sksagiyam PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 4); 23348be3dfe1Sksagiyam PetscValidHeaderSpecific(vec, VEC_CLASSID, 5); 23358be3dfe1Sksagiyam /* Check consistency */ 23368be3dfe1Sksagiyam { 23378be3dfe1Sksagiyam PetscSection section; 23388be3dfe1Sksagiyam PetscBool includesConstraints; 23398be3dfe1Sksagiyam PetscInt m, m1; 23408be3dfe1Sksagiyam 23418be3dfe1Sksagiyam ierr = VecGetLocalSize(vec, &m1);CHKERRQ(ierr); 23428be3dfe1Sksagiyam ierr = DMGetLocalSection(sectiondm, §ion);CHKERRQ(ierr); 23438be3dfe1Sksagiyam ierr = PetscSectionGetIncludesConstraints(section, &includesConstraints);CHKERRQ(ierr); 23448be3dfe1Sksagiyam if (includesConstraints) {ierr = PetscSectionGetStorageSize(section, &m);CHKERRQ(ierr);} 23458be3dfe1Sksagiyam else {ierr = PetscSectionGetConstrainedStorageSize(section, &m);CHKERRQ(ierr);} 23462c71b3e2SJacob Faibussowitsch PetscCheckFalse(m1 != m,PETSC_COMM_SELF, PETSC_ERR_PLIB, "Local vector size (%D) != local section storage size (%D)", m1, m); 23478be3dfe1Sksagiyam } 23488be3dfe1Sksagiyam ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5);CHKERRQ(ierr); 234902f7d72cSksagiyam ierr = PetscLogEventBegin(DMPLEX_LocalVectorLoad,viewer,0,0,0);CHKERRQ(ierr); 23508be3dfe1Sksagiyam if (ishdf5) { 23518be3dfe1Sksagiyam #if defined(PETSC_HAVE_HDF5) 23528be3dfe1Sksagiyam ierr = DMPlexVecLoad_HDF5_Internal(dm, viewer, sectiondm, sf, vec);CHKERRQ(ierr); 23538be3dfe1Sksagiyam #else 23548be3dfe1Sksagiyam SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 23558be3dfe1Sksagiyam #endif 23568be3dfe1Sksagiyam } 235702f7d72cSksagiyam ierr = PetscLogEventEnd(DMPLEX_LocalVectorLoad,viewer,0,0,0);CHKERRQ(ierr); 23588be3dfe1Sksagiyam PetscFunctionReturn(0); 23598be3dfe1Sksagiyam } 23608be3dfe1Sksagiyam 2361552f7358SJed Brown PetscErrorCode DMDestroy_Plex(DM dm) 2362552f7358SJed Brown { 2363552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2364552f7358SJed Brown PetscErrorCode ierr; 2365552f7358SJed Brown 2366552f7358SJed Brown PetscFunctionBegin; 23678135c375SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)dm,"DMSetUpGLVisViewer_C",NULL);CHKERRQ(ierr); 23688135c375SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)dm,"DMPlexInsertBoundaryValues_C", NULL);CHKERRQ(ierr); 236928d58a37SPierre Jolivet ierr = PetscObjectComposeFunction((PetscObject)dm,"DMCreateNeumannOverlap_C", NULL);CHKERRQ(ierr); 23701eb70e55SToby Isaac ierr = PetscObjectComposeFunction((PetscObject)dm,"DMInterpolateSolution_C", NULL);CHKERRQ(ierr); 23710d644c17SKarl Rupp if (--mesh->refct > 0) PetscFunctionReturn(0); 2372552f7358SJed Brown ierr = PetscSectionDestroy(&mesh->coneSection);CHKERRQ(ierr); 2373552f7358SJed Brown ierr = PetscFree(mesh->cones);CHKERRQ(ierr); 2374552f7358SJed Brown ierr = PetscFree(mesh->coneOrientations);CHKERRQ(ierr); 2375552f7358SJed Brown ierr = PetscSectionDestroy(&mesh->supportSection);CHKERRQ(ierr); 2376be36d101SStefano Zampini ierr = PetscSectionDestroy(&mesh->subdomainSection);CHKERRQ(ierr); 2377552f7358SJed Brown ierr = PetscFree(mesh->supports);CHKERRQ(ierr); 2378552f7358SJed Brown ierr = PetscFree(mesh->facesTmp);CHKERRQ(ierr); 2379d9deefdfSMatthew G. Knepley ierr = PetscFree(mesh->tetgenOpts);CHKERRQ(ierr); 2380d9deefdfSMatthew G. Knepley ierr = PetscFree(mesh->triangleOpts);CHKERRQ(ierr); 2381012bc364SMatthew G. Knepley ierr = PetscFree(mesh->transformType);CHKERRQ(ierr); 238277623264SMatthew G. Knepley ierr = PetscPartitionerDestroy(&mesh->partitioner);CHKERRQ(ierr); 2383a89082eeSMatthew G Knepley ierr = DMLabelDestroy(&mesh->subpointMap);CHKERRQ(ierr); 238497d8846cSMatthew Knepley ierr = ISDestroy(&mesh->subpointIS);CHKERRQ(ierr); 2385552f7358SJed Brown ierr = ISDestroy(&mesh->globalVertexNumbers);CHKERRQ(ierr); 2386552f7358SJed Brown ierr = ISDestroy(&mesh->globalCellNumbers);CHKERRQ(ierr); 2387a68b90caSToby Isaac ierr = PetscSectionDestroy(&mesh->anchorSection);CHKERRQ(ierr); 2388a68b90caSToby Isaac ierr = ISDestroy(&mesh->anchorIS);CHKERRQ(ierr); 2389d961a43aSToby Isaac ierr = PetscSectionDestroy(&mesh->parentSection);CHKERRQ(ierr); 2390d961a43aSToby Isaac ierr = PetscFree(mesh->parents);CHKERRQ(ierr); 2391d961a43aSToby Isaac ierr = PetscFree(mesh->childIDs);CHKERRQ(ierr); 2392d961a43aSToby Isaac ierr = PetscSectionDestroy(&mesh->childSection);CHKERRQ(ierr); 2393d961a43aSToby Isaac ierr = PetscFree(mesh->children);CHKERRQ(ierr); 2394d6a7ad0dSToby Isaac ierr = DMDestroy(&mesh->referenceTree);CHKERRQ(ierr); 2395fec49543SMatthew G. Knepley ierr = PetscGridHashDestroy(&mesh->lbox);CHKERRQ(ierr); 23960a19bb7dSprj- ierr = PetscFree(mesh->neighbors);CHKERRQ(ierr); 239731b70465SJoe Wallwork if (mesh->metricCtx) { ierr = PetscFree(mesh->metricCtx);CHKERRQ(ierr); } 2398552f7358SJed Brown /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */ 2399552f7358SJed Brown ierr = PetscFree(mesh);CHKERRQ(ierr); 2400552f7358SJed Brown PetscFunctionReturn(0); 2401552f7358SJed Brown } 2402552f7358SJed Brown 2403b412c318SBarry Smith PetscErrorCode DMCreateMatrix_Plex(DM dm, Mat *J) 2404552f7358SJed Brown { 24058d1174e4SMatthew G. Knepley PetscSection sectionGlobal; 2406acd755d7SMatthew G. Knepley PetscInt bs = -1, mbs; 2407552f7358SJed Brown PetscInt localSize; 2408837628f4SStefano Zampini PetscBool isShell, isBlock, isSeqBlock, isMPIBlock, isSymBlock, isSymSeqBlock, isSymMPIBlock, isMatIS; 2409552f7358SJed Brown PetscErrorCode ierr; 2410b412c318SBarry Smith MatType mtype; 24111428887cSShri Abhyankar ISLocalToGlobalMapping ltog; 2412552f7358SJed Brown 2413552f7358SJed Brown PetscFunctionBegin; 2414607a6623SBarry Smith ierr = MatInitializePackage();CHKERRQ(ierr); 2415b412c318SBarry Smith mtype = dm->mattype; 2416e87a4003SBarry Smith ierr = DMGetGlobalSection(dm, §ionGlobal);CHKERRQ(ierr); 2417552f7358SJed Brown /* ierr = PetscSectionGetStorageSize(sectionGlobal, &localSize);CHKERRQ(ierr); */ 2418552f7358SJed Brown ierr = PetscSectionGetConstrainedStorageSize(sectionGlobal, &localSize);CHKERRQ(ierr); 241982f516ccSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)dm), J);CHKERRQ(ierr); 2420552f7358SJed Brown ierr = MatSetSizes(*J, localSize, localSize, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 2421552f7358SJed Brown ierr = MatSetType(*J, mtype);CHKERRQ(ierr); 2422552f7358SJed Brown ierr = MatSetFromOptions(*J);CHKERRQ(ierr); 2423acd755d7SMatthew G. Knepley ierr = MatGetBlockSize(*J, &mbs);CHKERRQ(ierr); 2424acd755d7SMatthew G. Knepley if (mbs > 1) bs = mbs; 2425552f7358SJed Brown ierr = PetscStrcmp(mtype, MATSHELL, &isShell);CHKERRQ(ierr); 2426552f7358SJed Brown ierr = PetscStrcmp(mtype, MATBAIJ, &isBlock);CHKERRQ(ierr); 2427552f7358SJed Brown ierr = PetscStrcmp(mtype, MATSEQBAIJ, &isSeqBlock);CHKERRQ(ierr); 2428552f7358SJed Brown ierr = PetscStrcmp(mtype, MATMPIBAIJ, &isMPIBlock);CHKERRQ(ierr); 2429552f7358SJed Brown ierr = PetscStrcmp(mtype, MATSBAIJ, &isSymBlock);CHKERRQ(ierr); 2430552f7358SJed Brown ierr = PetscStrcmp(mtype, MATSEQSBAIJ, &isSymSeqBlock);CHKERRQ(ierr); 2431552f7358SJed Brown ierr = PetscStrcmp(mtype, MATMPISBAIJ, &isSymMPIBlock);CHKERRQ(ierr); 2432837628f4SStefano Zampini ierr = PetscStrcmp(mtype, MATIS, &isMatIS);CHKERRQ(ierr); 2433552f7358SJed Brown if (!isShell) { 2434837628f4SStefano Zampini PetscBool fillMatrix = (PetscBool)(!dm->prealloc_only && !isMatIS); 2435e432b41dSStefano Zampini PetscInt *dnz, *onz, *dnzu, *onzu, bsLocal[2], bsMinMax[2]; 2436fad22124SMatthew G Knepley PetscInt pStart, pEnd, p, dof, cdof; 2437552f7358SJed Brown 243800140cc3SStefano Zampini ierr = DMGetLocalToGlobalMapping(dm,<og);CHKERRQ(ierr); 2439552f7358SJed Brown ierr = PetscSectionGetChart(sectionGlobal, &pStart, &pEnd);CHKERRQ(ierr); 2440e432b41dSStefano Zampini for (p = pStart; p < pEnd; ++p) { 2441a9d99c84SMatthew G. Knepley PetscInt bdof; 2442a9d99c84SMatthew G. Knepley 2443552f7358SJed Brown ierr = PetscSectionGetDof(sectionGlobal, p, &dof);CHKERRQ(ierr); 2444fad22124SMatthew G Knepley ierr = PetscSectionGetConstraintDof(sectionGlobal, p, &cdof);CHKERRQ(ierr); 24451d17a0a3SMatthew G. Knepley dof = dof < 0 ? -(dof+1) : dof; 24461d17a0a3SMatthew G. Knepley bdof = cdof && (dof-cdof) ? 1 : dof; 24471d17a0a3SMatthew G. Knepley if (dof) { 24481d17a0a3SMatthew G. Knepley if (bs < 0) {bs = bdof;} 2449e432b41dSStefano Zampini else if (bs != bdof) {bs = 1; break;} 2450552f7358SJed Brown } 24512a28c762SMatthew G Knepley } 24522a28c762SMatthew G Knepley /* Must have same blocksize on all procs (some might have no points) */ 2453e432b41dSStefano Zampini bsLocal[0] = bs < 0 ? PETSC_MAX_INT : bs; 2454e432b41dSStefano Zampini bsLocal[1] = bs; 24550be3e97aSMatthew G. Knepley ierr = PetscGlobalMinMaxInt(PetscObjectComm((PetscObject) dm), bsLocal, bsMinMax);CHKERRQ(ierr); 2456e432b41dSStefano Zampini if (bsMinMax[0] != bsMinMax[1]) bs = 1; 2457e432b41dSStefano Zampini else bs = bsMinMax[0]; 24586fd5c86aSStefano Zampini bs = PetscMax(1,bs); 2459be36d101SStefano Zampini ierr = MatSetLocalToGlobalMapping(*J,ltog,ltog);CHKERRQ(ierr); 2460*0682b8bbSJed Brown if (dm->prealloc_skip) { // User will likely use MatSetPreallocationCOO(), but still set structural parameters 2461*0682b8bbSJed Brown ierr = MatSetBlockSize(*J, bs);CHKERRQ(ierr); 2462*0682b8bbSJed Brown ierr = MatSetUp(*J);CHKERRQ(ierr); 2463*0682b8bbSJed Brown } else { 24641795a4d1SJed Brown ierr = PetscCalloc4(localSize/bs, &dnz, localSize/bs, &onz, localSize/bs, &dnzu, localSize/bs, &onzu);CHKERRQ(ierr); 24658d1174e4SMatthew G. Knepley ierr = DMPlexPreallocateOperator(dm, bs, dnz, onz, dnzu, onzu, *J, fillMatrix);CHKERRQ(ierr); 2466552f7358SJed Brown ierr = PetscFree4(dnz, onz, dnzu, onzu);CHKERRQ(ierr); 2467552f7358SJed Brown } 2468aa0f6e3cSJed Brown } 2469b1f74addSMatthew G. Knepley ierr = MatSetDM(*J, dm);CHKERRQ(ierr); 2470552f7358SJed Brown PetscFunctionReturn(0); 2471552f7358SJed Brown } 2472552f7358SJed Brown 24737cd05799SMatthew G. Knepley /*@ 2474a8f00d21SMatthew G. Knepley DMPlexGetSubdomainSection - Returns the section associated with the subdomain 2475be36d101SStefano Zampini 2476be36d101SStefano Zampini Not collective 2477be36d101SStefano Zampini 2478be36d101SStefano Zampini Input Parameter: 2479be36d101SStefano Zampini . mesh - The DMPlex 2480be36d101SStefano Zampini 2481be36d101SStefano Zampini Output Parameters: 2482be36d101SStefano Zampini . subsection - The subdomain section 2483be36d101SStefano Zampini 2484be36d101SStefano Zampini Level: developer 2485be36d101SStefano Zampini 2486be36d101SStefano Zampini .seealso: 24877cd05799SMatthew G. Knepley @*/ 2488be36d101SStefano Zampini PetscErrorCode DMPlexGetSubdomainSection(DM dm, PetscSection *subsection) 2489be36d101SStefano Zampini { 2490be36d101SStefano Zampini DM_Plex *mesh = (DM_Plex*) dm->data; 2491be36d101SStefano Zampini PetscErrorCode ierr; 2492be36d101SStefano Zampini 2493be36d101SStefano Zampini PetscFunctionBegin; 2494be36d101SStefano Zampini PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2495be36d101SStefano Zampini if (!mesh->subdomainSection) { 2496be36d101SStefano Zampini PetscSection section; 2497be36d101SStefano Zampini PetscSF sf; 2498be36d101SStefano Zampini 2499be36d101SStefano Zampini ierr = PetscSFCreate(PETSC_COMM_SELF,&sf);CHKERRQ(ierr); 250092fd8e1eSJed Brown ierr = DMGetLocalSection(dm,§ion);CHKERRQ(ierr); 2501be36d101SStefano Zampini ierr = PetscSectionCreateGlobalSection(section,sf,PETSC_FALSE,PETSC_TRUE,&mesh->subdomainSection);CHKERRQ(ierr); 2502be36d101SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 2503be36d101SStefano Zampini } 2504be36d101SStefano Zampini *subsection = mesh->subdomainSection; 2505be36d101SStefano Zampini PetscFunctionReturn(0); 2506be36d101SStefano Zampini } 2507be36d101SStefano Zampini 2508552f7358SJed Brown /*@ 2509552f7358SJed Brown DMPlexGetChart - Return the interval for all mesh points [pStart, pEnd) 2510552f7358SJed Brown 2511552f7358SJed Brown Not collective 2512552f7358SJed Brown 2513552f7358SJed Brown Input Parameter: 2514552f7358SJed Brown . mesh - The DMPlex 2515552f7358SJed Brown 2516552f7358SJed Brown Output Parameters: 2517552f7358SJed Brown + pStart - The first mesh point 2518552f7358SJed Brown - pEnd - The upper bound for mesh points 2519552f7358SJed Brown 2520552f7358SJed Brown Level: beginner 2521552f7358SJed Brown 2522552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetChart() 2523552f7358SJed Brown @*/ 2524552f7358SJed Brown PetscErrorCode DMPlexGetChart(DM dm, PetscInt *pStart, PetscInt *pEnd) 2525552f7358SJed Brown { 2526552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2527552f7358SJed Brown PetscErrorCode ierr; 2528552f7358SJed Brown 2529552f7358SJed Brown PetscFunctionBegin; 2530552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2531552f7358SJed Brown ierr = PetscSectionGetChart(mesh->coneSection, pStart, pEnd);CHKERRQ(ierr); 2532552f7358SJed Brown PetscFunctionReturn(0); 2533552f7358SJed Brown } 2534552f7358SJed Brown 2535552f7358SJed Brown /*@ 2536552f7358SJed Brown DMPlexSetChart - Set the interval for all mesh points [pStart, pEnd) 2537552f7358SJed Brown 2538552f7358SJed Brown Not collective 2539552f7358SJed Brown 2540552f7358SJed Brown Input Parameters: 2541552f7358SJed Brown + mesh - The DMPlex 2542552f7358SJed Brown . pStart - The first mesh point 2543552f7358SJed Brown - pEnd - The upper bound for mesh points 2544552f7358SJed Brown 2545552f7358SJed Brown Output Parameters: 2546552f7358SJed Brown 2547552f7358SJed Brown Level: beginner 2548552f7358SJed Brown 2549552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetChart() 2550552f7358SJed Brown @*/ 2551552f7358SJed Brown PetscErrorCode DMPlexSetChart(DM dm, PetscInt pStart, PetscInt pEnd) 2552552f7358SJed Brown { 2553552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2554552f7358SJed Brown PetscErrorCode ierr; 2555552f7358SJed Brown 2556552f7358SJed Brown PetscFunctionBegin; 2557552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2558552f7358SJed Brown ierr = PetscSectionSetChart(mesh->coneSection, pStart, pEnd);CHKERRQ(ierr); 2559552f7358SJed Brown ierr = PetscSectionSetChart(mesh->supportSection, pStart, pEnd);CHKERRQ(ierr); 2560552f7358SJed Brown PetscFunctionReturn(0); 2561552f7358SJed Brown } 2562552f7358SJed Brown 2563552f7358SJed Brown /*@ 2564eaf898f9SPatrick Sanan DMPlexGetConeSize - Return the number of in-edges for this point in the DAG 2565552f7358SJed Brown 2566552f7358SJed Brown Not collective 2567552f7358SJed Brown 2568552f7358SJed Brown Input Parameters: 2569552f7358SJed Brown + mesh - The DMPlex 2570eaf898f9SPatrick Sanan - p - The point, which must lie in the chart set with DMPlexSetChart() 2571552f7358SJed Brown 2572552f7358SJed Brown Output Parameter: 2573552f7358SJed Brown . size - The cone size for point p 2574552f7358SJed Brown 2575552f7358SJed Brown Level: beginner 2576552f7358SJed Brown 2577552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetConeSize(), DMPlexSetChart() 2578552f7358SJed Brown @*/ 2579552f7358SJed Brown PetscErrorCode DMPlexGetConeSize(DM dm, PetscInt p, PetscInt *size) 2580552f7358SJed Brown { 2581552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2582552f7358SJed Brown PetscErrorCode ierr; 2583552f7358SJed Brown 2584552f7358SJed Brown PetscFunctionBegin; 2585552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2586552f7358SJed Brown PetscValidPointer(size, 3); 2587552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, size);CHKERRQ(ierr); 2588552f7358SJed Brown PetscFunctionReturn(0); 2589552f7358SJed Brown } 2590552f7358SJed Brown 2591552f7358SJed Brown /*@ 2592eaf898f9SPatrick Sanan DMPlexSetConeSize - Set the number of in-edges for this point in the DAG 2593552f7358SJed Brown 2594552f7358SJed Brown Not collective 2595552f7358SJed Brown 2596552f7358SJed Brown Input Parameters: 2597552f7358SJed Brown + mesh - The DMPlex 2598eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 2599552f7358SJed Brown - size - The cone size for point p 2600552f7358SJed Brown 2601552f7358SJed Brown Output Parameter: 2602552f7358SJed Brown 2603552f7358SJed Brown Note: 2604552f7358SJed Brown This should be called after DMPlexSetChart(). 2605552f7358SJed Brown 2606552f7358SJed Brown Level: beginner 2607552f7358SJed Brown 2608552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetConeSize(), DMPlexSetChart() 2609552f7358SJed Brown @*/ 2610552f7358SJed Brown PetscErrorCode DMPlexSetConeSize(DM dm, PetscInt p, PetscInt size) 2611552f7358SJed Brown { 2612552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2613552f7358SJed Brown PetscErrorCode ierr; 2614552f7358SJed Brown 2615552f7358SJed Brown PetscFunctionBegin; 2616552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2617552f7358SJed Brown ierr = PetscSectionSetDof(mesh->coneSection, p, size);CHKERRQ(ierr); 26180d644c17SKarl Rupp 2619552f7358SJed Brown mesh->maxConeSize = PetscMax(mesh->maxConeSize, size); 2620552f7358SJed Brown PetscFunctionReturn(0); 2621552f7358SJed Brown } 2622552f7358SJed Brown 2623f5a469b9SMatthew G. Knepley /*@ 2624eaf898f9SPatrick Sanan DMPlexAddConeSize - Add the given number of in-edges to this point in the DAG 2625f5a469b9SMatthew G. Knepley 2626f5a469b9SMatthew G. Knepley Not collective 2627f5a469b9SMatthew G. Knepley 2628f5a469b9SMatthew G. Knepley Input Parameters: 2629f5a469b9SMatthew G. Knepley + mesh - The DMPlex 2630eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 2631f5a469b9SMatthew G. Knepley - size - The additional cone size for point p 2632f5a469b9SMatthew G. Knepley 2633f5a469b9SMatthew G. Knepley Output Parameter: 2634f5a469b9SMatthew G. Knepley 2635f5a469b9SMatthew G. Knepley Note: 2636f5a469b9SMatthew G. Knepley This should be called after DMPlexSetChart(). 2637f5a469b9SMatthew G. Knepley 2638f5a469b9SMatthew G. Knepley Level: beginner 2639f5a469b9SMatthew G. Knepley 2640f5a469b9SMatthew G. Knepley .seealso: DMPlexCreate(), DMPlexSetConeSize(), DMPlexGetConeSize(), DMPlexSetChart() 2641f5a469b9SMatthew G. Knepley @*/ 2642f5a469b9SMatthew G. Knepley PetscErrorCode DMPlexAddConeSize(DM dm, PetscInt p, PetscInt size) 2643f5a469b9SMatthew G. Knepley { 2644f5a469b9SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 2645f5a469b9SMatthew G. Knepley PetscInt csize; 2646f5a469b9SMatthew G. Knepley PetscErrorCode ierr; 2647f5a469b9SMatthew G. Knepley 2648f5a469b9SMatthew G. Knepley PetscFunctionBegin; 2649f5a469b9SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2650f5a469b9SMatthew G. Knepley ierr = PetscSectionAddDof(mesh->coneSection, p, size);CHKERRQ(ierr); 2651f5a469b9SMatthew G. Knepley ierr = PetscSectionGetDof(mesh->coneSection, p, &csize);CHKERRQ(ierr); 2652f5a469b9SMatthew G. Knepley 2653f5a469b9SMatthew G. Knepley mesh->maxConeSize = PetscMax(mesh->maxConeSize, csize); 2654f5a469b9SMatthew G. Knepley PetscFunctionReturn(0); 2655f5a469b9SMatthew G. Knepley } 2656f5a469b9SMatthew G. Knepley 2657552f7358SJed Brown /*@C 2658eaf898f9SPatrick Sanan DMPlexGetCone - Return the points on the in-edges for this point in the DAG 2659552f7358SJed Brown 2660552f7358SJed Brown Not collective 2661552f7358SJed Brown 2662552f7358SJed Brown Input Parameters: 2663833c876bSVaclav Hapla + dm - The DMPlex 2664eaf898f9SPatrick Sanan - p - The point, which must lie in the chart set with DMPlexSetChart() 2665552f7358SJed Brown 2666552f7358SJed Brown Output Parameter: 2667552f7358SJed Brown . cone - An array of points which are on the in-edges for point p 2668552f7358SJed Brown 2669552f7358SJed Brown Level: beginner 2670552f7358SJed Brown 26713813dfbdSMatthew G Knepley Fortran Notes: 26723813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 26733813dfbdSMatthew G Knepley include petsc.h90 in your code. 2674922102d1SVaclav Hapla You must also call DMPlexRestoreCone() after you finish using the returned array. 2675922102d1SVaclav Hapla DMPlexRestoreCone() is not needed/available in C. 26763813dfbdSMatthew G Knepley 2677e45f02b0SMatthew G. Knepley .seealso: DMPlexGetConeSize(), DMPlexSetCone(), DMPlexGetConeTuple(), DMPlexSetChart() 2678552f7358SJed Brown @*/ 2679552f7358SJed Brown PetscErrorCode DMPlexGetCone(DM dm, PetscInt p, const PetscInt *cone[]) 2680552f7358SJed Brown { 2681552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2682552f7358SJed Brown PetscInt off; 2683552f7358SJed Brown PetscErrorCode ierr; 2684552f7358SJed Brown 2685552f7358SJed Brown PetscFunctionBegin; 2686552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2687552f7358SJed Brown PetscValidPointer(cone, 3); 2688552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 2689552f7358SJed Brown *cone = &mesh->cones[off]; 2690552f7358SJed Brown PetscFunctionReturn(0); 2691552f7358SJed Brown } 2692552f7358SJed Brown 26930ce7577fSVaclav Hapla /*@C 26940ce7577fSVaclav Hapla DMPlexGetConeTuple - Return the points on the in-edges of several points in the DAG 26950ce7577fSVaclav Hapla 26960ce7577fSVaclav Hapla Not collective 26970ce7577fSVaclav Hapla 26980ce7577fSVaclav Hapla Input Parameters: 26990ce7577fSVaclav Hapla + dm - The DMPlex 27000ce7577fSVaclav Hapla - p - The IS of points, which must lie in the chart set with DMPlexSetChart() 27010ce7577fSVaclav Hapla 2702d8d19677SJose E. Roman Output Parameters: 27030ce7577fSVaclav Hapla + pConesSection - PetscSection describing the layout of pCones 27040ce7577fSVaclav Hapla - pCones - An array of points which are on the in-edges for the point set p 27050ce7577fSVaclav Hapla 27060ce7577fSVaclav Hapla Level: intermediate 27070ce7577fSVaclav Hapla 2708d4636a37SVaclav Hapla .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexGetConeRecursive(), DMPlexSetChart() 27090ce7577fSVaclav Hapla @*/ 27100ce7577fSVaclav Hapla PetscErrorCode DMPlexGetConeTuple(DM dm, IS p, PetscSection *pConesSection, IS *pCones) 27110ce7577fSVaclav Hapla { 27120ce7577fSVaclav Hapla PetscSection cs, newcs; 27130ce7577fSVaclav Hapla PetscInt *cones; 27140ce7577fSVaclav Hapla PetscInt *newarr=NULL; 27150ce7577fSVaclav Hapla PetscInt n; 27160ce7577fSVaclav Hapla PetscErrorCode ierr; 27170ce7577fSVaclav Hapla 27180ce7577fSVaclav Hapla PetscFunctionBegin; 27190ce7577fSVaclav Hapla ierr = DMPlexGetCones(dm, &cones);CHKERRQ(ierr); 27200ce7577fSVaclav Hapla ierr = DMPlexGetConeSection(dm, &cs);CHKERRQ(ierr); 27210ce7577fSVaclav Hapla ierr = PetscSectionExtractDofsFromArray(cs, MPIU_INT, cones, p, &newcs, pCones ? ((void**)&newarr) : NULL);CHKERRQ(ierr); 27220ce7577fSVaclav Hapla if (pConesSection) *pConesSection = newcs; 27230ce7577fSVaclav Hapla if (pCones) { 27240ce7577fSVaclav Hapla ierr = PetscSectionGetStorageSize(newcs, &n);CHKERRQ(ierr); 27250ce7577fSVaclav Hapla ierr = ISCreateGeneral(PetscObjectComm((PetscObject)p), n, newarr, PETSC_OWN_POINTER, pCones);CHKERRQ(ierr); 27260ce7577fSVaclav Hapla } 27270ce7577fSVaclav Hapla PetscFunctionReturn(0); 27280ce7577fSVaclav Hapla } 27290ce7577fSVaclav Hapla 2730af9eab45SVaclav Hapla /*@ 2731af9eab45SVaclav Hapla DMPlexGetConeRecursiveVertices - Expand each given point into its cone points and do that recursively until we end up just with vertices. 2732d4636a37SVaclav Hapla 2733d4636a37SVaclav Hapla Not collective 2734d4636a37SVaclav Hapla 2735d4636a37SVaclav Hapla Input Parameters: 2736d4636a37SVaclav Hapla + dm - The DMPlex 2737af9eab45SVaclav Hapla - points - The IS of points, which must lie in the chart set with DMPlexSetChart() 2738d4636a37SVaclav Hapla 2739d4636a37SVaclav Hapla Output Parameter: 2740af9eab45SVaclav Hapla . expandedPoints - An array of vertices recursively expanded from input points 2741d4636a37SVaclav Hapla 2742d4636a37SVaclav Hapla Level: advanced 2743d4636a37SVaclav Hapla 2744af9eab45SVaclav Hapla Notes: 2745af9eab45SVaclav Hapla Like DMPlexGetConeRecursive but returns only the 0-depth IS (i.e. vertices only) and no sections. 2746af9eab45SVaclav Hapla There is no corresponding Restore function, just call ISDestroy() on the returned IS to deallocate. 2747af9eab45SVaclav Hapla 2748af9eab45SVaclav Hapla .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexGetConeTuple(), DMPlexGetConeRecursive(), DMPlexRestoreConeRecursive(), DMPlexGetDepth() 2749d4636a37SVaclav Hapla @*/ 2750af9eab45SVaclav Hapla PetscErrorCode DMPlexGetConeRecursiveVertices(DM dm, IS points, IS *expandedPoints) 2751d4636a37SVaclav Hapla { 2752af9eab45SVaclav Hapla IS *expandedPointsAll; 2753af9eab45SVaclav Hapla PetscInt depth; 2754d4636a37SVaclav Hapla PetscErrorCode ierr; 2755d4636a37SVaclav Hapla 2756d4636a37SVaclav Hapla PetscFunctionBegin; 2757af9eab45SVaclav Hapla PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2758af9eab45SVaclav Hapla PetscValidHeaderSpecific(points, IS_CLASSID, 2); 2759af9eab45SVaclav Hapla PetscValidPointer(expandedPoints, 3); 2760af9eab45SVaclav Hapla ierr = DMPlexGetConeRecursive(dm, points, &depth, &expandedPointsAll, NULL);CHKERRQ(ierr); 2761af9eab45SVaclav Hapla *expandedPoints = expandedPointsAll[0]; 27621e1ea65dSPierre Jolivet ierr = PetscObjectReference((PetscObject)expandedPointsAll[0]);CHKERRQ(ierr); 2763af9eab45SVaclav Hapla ierr = DMPlexRestoreConeRecursive(dm, points, &depth, &expandedPointsAll, NULL);CHKERRQ(ierr); 2764af9eab45SVaclav Hapla PetscFunctionReturn(0); 2765af9eab45SVaclav Hapla } 2766af9eab45SVaclav Hapla 2767af9eab45SVaclav Hapla /*@ 2768af9eab45SVaclav 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). 2769af9eab45SVaclav Hapla 2770af9eab45SVaclav Hapla Not collective 2771af9eab45SVaclav Hapla 2772af9eab45SVaclav Hapla Input Parameters: 2773af9eab45SVaclav Hapla + dm - The DMPlex 2774af9eab45SVaclav Hapla - points - The IS of points, which must lie in the chart set with DMPlexSetChart() 2775af9eab45SVaclav Hapla 2776d8d19677SJose E. Roman Output Parameters: 2777af9eab45SVaclav Hapla + depth - (optional) Size of the output arrays, equal to DMPlex depth, returned by DMPlexGetDepth() 2778af9eab45SVaclav Hapla . expandedPoints - (optional) An array of index sets with recursively expanded cones 2779af9eab45SVaclav Hapla - sections - (optional) An array of sections which describe mappings from points to their cone points 2780af9eab45SVaclav Hapla 2781af9eab45SVaclav Hapla Level: advanced 2782af9eab45SVaclav Hapla 2783af9eab45SVaclav Hapla Notes: 2784af9eab45SVaclav Hapla Like DMPlexGetConeTuple() but recursive. 2785af9eab45SVaclav Hapla 2786af9eab45SVaclav 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. 2787af9eab45SVaclav Hapla For example, for d=0 it contains only vertices, for d=1 it can contain vertices and edges, etc. 2788af9eab45SVaclav Hapla 2789af9eab45SVaclav 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: 2790af9eab45SVaclav Hapla (1) DAG points in expandedPoints[d+1] with depth d+1 to their cone points in expandedPoints[d]; 2791af9eab45SVaclav Hapla (2) DAG points in expandedPoints[d+1] with depth in [0,d] to the same points in expandedPoints[d]. 2792af9eab45SVaclav Hapla 2793af9eab45SVaclav Hapla .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexGetConeTuple(), DMPlexRestoreConeRecursive(), DMPlexGetConeRecursiveVertices(), DMPlexGetDepth() 2794af9eab45SVaclav Hapla @*/ 2795af9eab45SVaclav Hapla PetscErrorCode DMPlexGetConeRecursive(DM dm, IS points, PetscInt *depth, IS *expandedPoints[], PetscSection *sections[]) 2796af9eab45SVaclav Hapla { 2797af9eab45SVaclav Hapla const PetscInt *arr0=NULL, *cone=NULL; 2798af9eab45SVaclav Hapla PetscInt *arr=NULL, *newarr=NULL; 2799af9eab45SVaclav Hapla PetscInt d, depth_, i, n, newn, cn, co, start, end; 2800af9eab45SVaclav Hapla IS *expandedPoints_; 2801af9eab45SVaclav Hapla PetscSection *sections_; 2802af9eab45SVaclav Hapla PetscErrorCode ierr; 2803af9eab45SVaclav Hapla 2804af9eab45SVaclav Hapla PetscFunctionBegin; 2805af9eab45SVaclav Hapla PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2806af9eab45SVaclav Hapla PetscValidHeaderSpecific(points, IS_CLASSID, 2); 2807af9eab45SVaclav Hapla if (depth) PetscValidIntPointer(depth, 3); 2808af9eab45SVaclav Hapla if (expandedPoints) PetscValidPointer(expandedPoints, 4); 2809af9eab45SVaclav Hapla if (sections) PetscValidPointer(sections, 5); 2810af9eab45SVaclav Hapla ierr = ISGetLocalSize(points, &n);CHKERRQ(ierr); 2811af9eab45SVaclav Hapla ierr = ISGetIndices(points, &arr0);CHKERRQ(ierr); 2812af9eab45SVaclav Hapla ierr = DMPlexGetDepth(dm, &depth_);CHKERRQ(ierr); 2813af9eab45SVaclav Hapla ierr = PetscCalloc1(depth_, &expandedPoints_);CHKERRQ(ierr); 2814af9eab45SVaclav Hapla ierr = PetscCalloc1(depth_, §ions_);CHKERRQ(ierr); 2815af9eab45SVaclav Hapla arr = (PetscInt*) arr0; /* this is ok because first generation of arr is not modified */ 2816af9eab45SVaclav Hapla for (d=depth_-1; d>=0; d--) { 2817af9eab45SVaclav Hapla ierr = PetscSectionCreate(PETSC_COMM_SELF, §ions_[d]);CHKERRQ(ierr); 2818af9eab45SVaclav Hapla ierr = PetscSectionSetChart(sections_[d], 0, n);CHKERRQ(ierr); 2819af9eab45SVaclav Hapla for (i=0; i<n; i++) { 2820af9eab45SVaclav Hapla ierr = DMPlexGetDepthStratum(dm, d+1, &start, &end);CHKERRQ(ierr); 2821af9eab45SVaclav Hapla if (arr[i] >= start && arr[i] < end) { 2822af9eab45SVaclav Hapla ierr = DMPlexGetConeSize(dm, arr[i], &cn);CHKERRQ(ierr); 2823af9eab45SVaclav Hapla ierr = PetscSectionSetDof(sections_[d], i, cn);CHKERRQ(ierr); 2824af9eab45SVaclav Hapla } else { 2825af9eab45SVaclav Hapla ierr = PetscSectionSetDof(sections_[d], i, 1);CHKERRQ(ierr); 2826af9eab45SVaclav Hapla } 2827af9eab45SVaclav Hapla } 2828af9eab45SVaclav Hapla ierr = PetscSectionSetUp(sections_[d]);CHKERRQ(ierr); 2829af9eab45SVaclav Hapla ierr = PetscSectionGetStorageSize(sections_[d], &newn);CHKERRQ(ierr); 2830af9eab45SVaclav Hapla ierr = PetscMalloc1(newn, &newarr);CHKERRQ(ierr); 2831af9eab45SVaclav Hapla for (i=0; i<n; i++) { 2832af9eab45SVaclav Hapla ierr = PetscSectionGetDof(sections_[d], i, &cn);CHKERRQ(ierr); 2833af9eab45SVaclav Hapla ierr = PetscSectionGetOffset(sections_[d], i, &co);CHKERRQ(ierr); 2834af9eab45SVaclav Hapla if (cn > 1) { 2835af9eab45SVaclav Hapla ierr = DMPlexGetCone(dm, arr[i], &cone);CHKERRQ(ierr); 2836af9eab45SVaclav Hapla ierr = PetscMemcpy(&newarr[co], cone, cn*sizeof(PetscInt));CHKERRQ(ierr); 2837af9eab45SVaclav Hapla } else { 2838af9eab45SVaclav Hapla newarr[co] = arr[i]; 2839af9eab45SVaclav Hapla } 2840af9eab45SVaclav Hapla } 2841af9eab45SVaclav Hapla ierr = ISCreateGeneral(PETSC_COMM_SELF, newn, newarr, PETSC_OWN_POINTER, &expandedPoints_[d]);CHKERRQ(ierr); 2842af9eab45SVaclav Hapla arr = newarr; 2843af9eab45SVaclav Hapla n = newn; 2844af9eab45SVaclav Hapla } 2845ba2698f1SMatthew G. Knepley ierr = ISRestoreIndices(points, &arr0);CHKERRQ(ierr); 2846af9eab45SVaclav Hapla *depth = depth_; 2847af9eab45SVaclav Hapla if (expandedPoints) *expandedPoints = expandedPoints_; 2848af9eab45SVaclav Hapla else { 2849af9eab45SVaclav Hapla for (d=0; d<depth_; d++) {ierr = ISDestroy(&expandedPoints_[d]);CHKERRQ(ierr);} 2850af9eab45SVaclav Hapla ierr = PetscFree(expandedPoints_);CHKERRQ(ierr); 2851af9eab45SVaclav Hapla } 2852af9eab45SVaclav Hapla if (sections) *sections = sections_; 2853af9eab45SVaclav Hapla else { 2854af9eab45SVaclav Hapla for (d=0; d<depth_; d++) {ierr = PetscSectionDestroy(§ions_[d]);CHKERRQ(ierr);} 2855af9eab45SVaclav Hapla ierr = PetscFree(sections_);CHKERRQ(ierr); 2856af9eab45SVaclav Hapla } 2857af9eab45SVaclav Hapla PetscFunctionReturn(0); 2858af9eab45SVaclav Hapla } 2859af9eab45SVaclav Hapla 2860af9eab45SVaclav Hapla /*@ 2861af9eab45SVaclav Hapla DMPlexRestoreConeRecursive - Deallocates arrays created by DMPlexGetConeRecursive 2862af9eab45SVaclav Hapla 2863af9eab45SVaclav Hapla Not collective 2864af9eab45SVaclav Hapla 2865af9eab45SVaclav Hapla Input Parameters: 2866af9eab45SVaclav Hapla + dm - The DMPlex 2867af9eab45SVaclav Hapla - points - The IS of points, which must lie in the chart set with DMPlexSetChart() 2868af9eab45SVaclav Hapla 2869d8d19677SJose E. Roman Output Parameters: 2870af9eab45SVaclav Hapla + depth - (optional) Size of the output arrays, equal to DMPlex depth, returned by DMPlexGetDepth() 2871af9eab45SVaclav Hapla . expandedPoints - (optional) An array of recursively expanded cones 2872af9eab45SVaclav Hapla - sections - (optional) An array of sections which describe mappings from points to their cone points 2873af9eab45SVaclav Hapla 2874af9eab45SVaclav Hapla Level: advanced 2875af9eab45SVaclav Hapla 2876af9eab45SVaclav Hapla Notes: 2877af9eab45SVaclav Hapla See DMPlexGetConeRecursive() for details. 2878af9eab45SVaclav Hapla 2879af9eab45SVaclav Hapla .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexGetConeTuple(), DMPlexGetConeRecursive(), DMPlexGetConeRecursiveVertices(), DMPlexGetDepth() 2880af9eab45SVaclav Hapla @*/ 2881af9eab45SVaclav Hapla PetscErrorCode DMPlexRestoreConeRecursive(DM dm, IS points, PetscInt *depth, IS *expandedPoints[], PetscSection *sections[]) 2882af9eab45SVaclav Hapla { 2883af9eab45SVaclav Hapla PetscInt d, depth_; 2884af9eab45SVaclav Hapla PetscErrorCode ierr; 2885af9eab45SVaclav Hapla 2886af9eab45SVaclav Hapla PetscFunctionBegin; 2887af9eab45SVaclav Hapla ierr = DMPlexGetDepth(dm, &depth_);CHKERRQ(ierr); 28882c71b3e2SJacob Faibussowitsch PetscCheckFalse(depth && *depth != depth_,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "depth changed since last call to DMPlexGetConeRecursive"); 2889af9eab45SVaclav Hapla if (depth) *depth = 0; 2890af9eab45SVaclav Hapla if (expandedPoints) { 2891af9eab45SVaclav Hapla for (d=0; d<depth_; d++) {ierr = ISDestroy(&((*expandedPoints)[d]));CHKERRQ(ierr);} 2892af9eab45SVaclav Hapla ierr = PetscFree(*expandedPoints);CHKERRQ(ierr); 2893af9eab45SVaclav Hapla } 2894af9eab45SVaclav Hapla if (sections) { 2895af9eab45SVaclav Hapla for (d=0; d<depth_; d++) {ierr = PetscSectionDestroy(&((*sections)[d]));CHKERRQ(ierr);} 2896af9eab45SVaclav Hapla ierr = PetscFree(*sections);CHKERRQ(ierr); 2897af9eab45SVaclav Hapla } 2898d4636a37SVaclav Hapla PetscFunctionReturn(0); 2899d4636a37SVaclav Hapla } 2900d4636a37SVaclav Hapla 2901552f7358SJed Brown /*@ 290292371b87SBarry 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 2903552f7358SJed Brown 2904552f7358SJed Brown Not collective 2905552f7358SJed Brown 2906552f7358SJed Brown Input Parameters: 2907552f7358SJed Brown + mesh - The DMPlex 2908eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 2909552f7358SJed Brown - cone - An array of points which are on the in-edges for point p 2910552f7358SJed Brown 2911552f7358SJed Brown Output Parameter: 2912552f7358SJed Brown 2913552f7358SJed Brown Note: 2914552f7358SJed Brown This should be called after all calls to DMPlexSetConeSize() and DMSetUp(). 2915552f7358SJed Brown 2916552f7358SJed Brown Level: beginner 2917552f7358SJed Brown 291892371b87SBarry Smith .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexSetChart(), DMPlexSetConeSize(), DMSetUp(), DMPlexSetSupport(), DMPlexSetSupportSize() 2919552f7358SJed Brown @*/ 2920552f7358SJed Brown PetscErrorCode DMPlexSetCone(DM dm, PetscInt p, const PetscInt cone[]) 2921552f7358SJed Brown { 2922552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2923552f7358SJed Brown PetscInt pStart, pEnd; 2924552f7358SJed Brown PetscInt dof, off, c; 2925552f7358SJed Brown PetscErrorCode ierr; 2926552f7358SJed Brown 2927552f7358SJed Brown PetscFunctionBegin; 2928552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2929552f7358SJed Brown ierr = PetscSectionGetChart(mesh->coneSection, &pStart, &pEnd);CHKERRQ(ierr); 2930552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 2931552f7358SJed Brown if (dof) PetscValidPointer(cone, 3); 2932552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 29332c71b3e2SJacob Faibussowitsch PetscCheckFalse((p < pStart) || (p >= pEnd),PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Mesh point %D is not in the valid range [%D, %D)", p, pStart, pEnd); 2934552f7358SJed Brown for (c = 0; c < dof; ++c) { 29352c71b3e2SJacob Faibussowitsch PetscCheckFalse((cone[c] < pStart) || (cone[c] >= pEnd),PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cone point %D is not in the valid range [%D, %D)", cone[c], pStart, pEnd); 2936552f7358SJed Brown mesh->cones[off+c] = cone[c]; 2937552f7358SJed Brown } 2938552f7358SJed Brown PetscFunctionReturn(0); 2939552f7358SJed Brown } 2940552f7358SJed Brown 2941552f7358SJed Brown /*@C 2942eaf898f9SPatrick Sanan DMPlexGetConeOrientation - Return the orientations on the in-edges for this point in the DAG 2943552f7358SJed Brown 2944552f7358SJed Brown Not collective 2945552f7358SJed Brown 2946552f7358SJed Brown Input Parameters: 2947552f7358SJed Brown + mesh - The DMPlex 2948eaf898f9SPatrick Sanan - p - The point, which must lie in the chart set with DMPlexSetChart() 2949552f7358SJed Brown 2950552f7358SJed Brown Output Parameter: 2951552f7358SJed Brown . coneOrientation - An array of orientations which are on the in-edges for point p. An orientation is an 2952b5a892a1SMatthew G. Knepley integer giving the prescription for cone traversal. 2953552f7358SJed Brown 2954552f7358SJed Brown Level: beginner 2955552f7358SJed Brown 2956b5a892a1SMatthew G. Knepley Notes: 2957b5a892a1SMatthew G. Knepley The number indexes the symmetry transformations for the cell type (see manual). Orientation 0 is always 2958b5a892a1SMatthew G. Knepley the identity transformation. Negative orientation indicates reflection so that -(o+1) is the reflection 2959b5a892a1SMatthew G. Knepley of o, however it is not necessarily the inverse. To get the inverse, use DMPolytopeTypeComposeOrientationInv() 2960b5a892a1SMatthew G. Knepley with the identity. 2961b5a892a1SMatthew G. Knepley 29623813dfbdSMatthew G Knepley Fortran Notes: 29633813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 29643813dfbdSMatthew G Knepley include petsc.h90 in your code. 29653b12b3d8SVaclav Hapla You must also call DMPlexRestoreConeOrientation() after you finish using the returned array. 2966922102d1SVaclav Hapla DMPlexRestoreConeOrientation() is not needed/available in C. 29673813dfbdSMatthew G Knepley 2968b5a892a1SMatthew G. Knepley .seealso: DMPolytopeTypeComposeOrientation(), DMPolytopeTypeComposeOrientationInv(), DMPlexCreate(), DMPlexGetCone(), DMPlexSetCone(), DMPlexSetChart() 2969552f7358SJed Brown @*/ 2970552f7358SJed Brown PetscErrorCode DMPlexGetConeOrientation(DM dm, PetscInt p, const PetscInt *coneOrientation[]) 2971552f7358SJed Brown { 2972552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2973552f7358SJed Brown PetscInt off; 2974552f7358SJed Brown PetscErrorCode ierr; 2975552f7358SJed Brown 2976552f7358SJed Brown PetscFunctionBegin; 2977552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 297876bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 2979552f7358SJed Brown PetscInt dof; 2980552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 2981552f7358SJed Brown if (dof) PetscValidPointer(coneOrientation, 3); 2982552f7358SJed Brown } 2983552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 29840d644c17SKarl Rupp 2985552f7358SJed Brown *coneOrientation = &mesh->coneOrientations[off]; 2986552f7358SJed Brown PetscFunctionReturn(0); 2987552f7358SJed Brown } 2988552f7358SJed Brown 2989552f7358SJed Brown /*@ 2990eaf898f9SPatrick Sanan DMPlexSetConeOrientation - Set the orientations on the in-edges for this point in the DAG 2991552f7358SJed Brown 2992552f7358SJed Brown Not collective 2993552f7358SJed Brown 2994552f7358SJed Brown Input Parameters: 2995552f7358SJed Brown + mesh - The DMPlex 2996eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 2997b5a892a1SMatthew G. Knepley - coneOrientation - An array of orientations 2998552f7358SJed Brown Output Parameter: 2999552f7358SJed Brown 3000b5a892a1SMatthew G. Knepley Notes: 3001552f7358SJed Brown This should be called after all calls to DMPlexSetConeSize() and DMSetUp(). 3002552f7358SJed Brown 3003b5a892a1SMatthew G. Knepley The meaning of coneOrientation is detailed in DMPlexGetConeOrientation(). 3004b5a892a1SMatthew G. Knepley 3005552f7358SJed Brown Level: beginner 3006552f7358SJed Brown 3007552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetConeOrientation(), DMPlexSetCone(), DMPlexSetChart(), DMPlexSetConeSize(), DMSetUp() 3008552f7358SJed Brown @*/ 3009552f7358SJed Brown PetscErrorCode DMPlexSetConeOrientation(DM dm, PetscInt p, const PetscInt coneOrientation[]) 3010552f7358SJed Brown { 3011552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3012552f7358SJed Brown PetscInt pStart, pEnd; 3013552f7358SJed Brown PetscInt dof, off, c; 3014552f7358SJed Brown PetscErrorCode ierr; 3015552f7358SJed Brown 3016552f7358SJed Brown PetscFunctionBegin; 3017552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3018552f7358SJed Brown ierr = PetscSectionGetChart(mesh->coneSection, &pStart, &pEnd);CHKERRQ(ierr); 3019552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 3020552f7358SJed Brown if (dof) PetscValidPointer(coneOrientation, 3); 3021552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 30222c71b3e2SJacob Faibussowitsch PetscCheckFalse((p < pStart) || (p >= pEnd),PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Mesh point %D is not in the valid range [%D, %D)", p, pStart, pEnd); 3023552f7358SJed Brown for (c = 0; c < dof; ++c) { 3024552f7358SJed Brown PetscInt cdof, o = coneOrientation[c]; 3025552f7358SJed Brown 3026552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, mesh->cones[off+c], &cdof);CHKERRQ(ierr); 30272c71b3e2SJacob Faibussowitsch PetscCheckFalse(o && ((o < -(cdof+1)) || (o >= cdof)),PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cone orientation %D is not in the valid range [%D. %D)", o, -(cdof+1), cdof); 3028552f7358SJed Brown mesh->coneOrientations[off+c] = o; 3029552f7358SJed Brown } 3030552f7358SJed Brown PetscFunctionReturn(0); 3031552f7358SJed Brown } 3032552f7358SJed Brown 30337cd05799SMatthew G. Knepley /*@ 3034eaf898f9SPatrick Sanan DMPlexInsertCone - Insert a point into the in-edges for the point p in the DAG 30357cd05799SMatthew G. Knepley 30367cd05799SMatthew G. Knepley Not collective 30377cd05799SMatthew G. Knepley 30387cd05799SMatthew G. Knepley Input Parameters: 30397cd05799SMatthew G. Knepley + mesh - The DMPlex 3040eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 30417cd05799SMatthew G. Knepley . conePos - The local index in the cone where the point should be put 30427cd05799SMatthew G. Knepley - conePoint - The mesh point to insert 30437cd05799SMatthew G. Knepley 30447cd05799SMatthew G. Knepley Level: beginner 30457cd05799SMatthew G. Knepley 30467cd05799SMatthew G. Knepley .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexSetChart(), DMPlexSetConeSize(), DMSetUp() 30477cd05799SMatthew G. Knepley @*/ 3048552f7358SJed Brown PetscErrorCode DMPlexInsertCone(DM dm, PetscInt p, PetscInt conePos, PetscInt conePoint) 3049552f7358SJed Brown { 3050552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3051552f7358SJed Brown PetscInt pStart, pEnd; 3052552f7358SJed Brown PetscInt dof, off; 3053552f7358SJed Brown PetscErrorCode ierr; 3054552f7358SJed Brown 3055552f7358SJed Brown PetscFunctionBegin; 3056552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3057552f7358SJed Brown ierr = PetscSectionGetChart(mesh->coneSection, &pStart, &pEnd);CHKERRQ(ierr); 30582c71b3e2SJacob Faibussowitsch PetscCheckFalse((p < pStart) || (p >= pEnd),PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Mesh point %D is not in the valid range [%D, %D)", p, pStart, pEnd); 30592c71b3e2SJacob Faibussowitsch PetscCheckFalse((conePoint < pStart) || (conePoint >= pEnd),PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cone point %D is not in the valid range [%D, %D)", conePoint, pStart, pEnd); 306077c88f5bSMatthew G Knepley ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 306177c88f5bSMatthew G Knepley ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 30622c71b3e2SJacob Faibussowitsch PetscCheckFalse((conePos < 0) || (conePos >= dof),PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cone position %D of point %D is not in the valid range [0, %D)", conePos, p, dof); 3063552f7358SJed Brown mesh->cones[off+conePos] = conePoint; 3064552f7358SJed Brown PetscFunctionReturn(0); 3065552f7358SJed Brown } 3066552f7358SJed Brown 30677cd05799SMatthew G. Knepley /*@ 3068eaf898f9SPatrick Sanan DMPlexInsertConeOrientation - Insert a point orientation for the in-edge for the point p in the DAG 30697cd05799SMatthew G. Knepley 30707cd05799SMatthew G. Knepley Not collective 30717cd05799SMatthew G. Knepley 30727cd05799SMatthew G. Knepley Input Parameters: 30737cd05799SMatthew G. Knepley + mesh - The DMPlex 3074eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 30757cd05799SMatthew G. Knepley . conePos - The local index in the cone where the point should be put 30767cd05799SMatthew G. Knepley - coneOrientation - The point orientation to insert 30777cd05799SMatthew G. Knepley 30787cd05799SMatthew G. Knepley Level: beginner 30797cd05799SMatthew G. Knepley 3080b5a892a1SMatthew G. Knepley Notes: 3081b5a892a1SMatthew G. Knepley The meaning of coneOrientation values is detailed in DMPlexGetConeOrientation(). 3082b5a892a1SMatthew G. Knepley 30837cd05799SMatthew G. Knepley .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexSetChart(), DMPlexSetConeSize(), DMSetUp() 30847cd05799SMatthew G. Knepley @*/ 308577c88f5bSMatthew G Knepley PetscErrorCode DMPlexInsertConeOrientation(DM dm, PetscInt p, PetscInt conePos, PetscInt coneOrientation) 308677c88f5bSMatthew G Knepley { 308777c88f5bSMatthew G Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 308877c88f5bSMatthew G Knepley PetscInt pStart, pEnd; 308977c88f5bSMatthew G Knepley PetscInt dof, off; 309077c88f5bSMatthew G Knepley PetscErrorCode ierr; 309177c88f5bSMatthew G Knepley 309277c88f5bSMatthew G Knepley PetscFunctionBegin; 309377c88f5bSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 309477c88f5bSMatthew G Knepley ierr = PetscSectionGetChart(mesh->coneSection, &pStart, &pEnd);CHKERRQ(ierr); 30952c71b3e2SJacob Faibussowitsch PetscCheckFalse((p < pStart) || (p >= pEnd),PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Mesh point %D is not in the valid range [%D, %D)", p, pStart, pEnd); 309677c88f5bSMatthew G Knepley ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 309777c88f5bSMatthew G Knepley ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 30982c71b3e2SJacob Faibussowitsch PetscCheckFalse((conePos < 0) || (conePos >= dof),PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cone position %D of point %D is not in the valid range [0, %D)", conePos, p, dof); 309977c88f5bSMatthew G Knepley mesh->coneOrientations[off+conePos] = coneOrientation; 310077c88f5bSMatthew G Knepley PetscFunctionReturn(0); 310177c88f5bSMatthew G Knepley } 310277c88f5bSMatthew G Knepley 3103552f7358SJed Brown /*@ 3104eaf898f9SPatrick Sanan DMPlexGetSupportSize - Return the number of out-edges for this point in the DAG 3105552f7358SJed Brown 3106552f7358SJed Brown Not collective 3107552f7358SJed Brown 3108552f7358SJed Brown Input Parameters: 3109552f7358SJed Brown + mesh - The DMPlex 3110eaf898f9SPatrick Sanan - p - The point, which must lie in the chart set with DMPlexSetChart() 3111552f7358SJed Brown 3112552f7358SJed Brown Output Parameter: 3113552f7358SJed Brown . size - The support size for point p 3114552f7358SJed Brown 3115552f7358SJed Brown Level: beginner 3116552f7358SJed Brown 3117552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetConeSize(), DMPlexSetChart(), DMPlexGetConeSize() 3118552f7358SJed Brown @*/ 3119552f7358SJed Brown PetscErrorCode DMPlexGetSupportSize(DM dm, PetscInt p, PetscInt *size) 3120552f7358SJed Brown { 3121552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3122552f7358SJed Brown PetscErrorCode ierr; 3123552f7358SJed Brown 3124552f7358SJed Brown PetscFunctionBegin; 3125552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3126552f7358SJed Brown PetscValidPointer(size, 3); 3127552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, size);CHKERRQ(ierr); 3128552f7358SJed Brown PetscFunctionReturn(0); 3129552f7358SJed Brown } 3130552f7358SJed Brown 3131552f7358SJed Brown /*@ 3132eaf898f9SPatrick Sanan DMPlexSetSupportSize - Set the number of out-edges for this point in the DAG 3133552f7358SJed Brown 3134552f7358SJed Brown Not collective 3135552f7358SJed Brown 3136552f7358SJed Brown Input Parameters: 3137552f7358SJed Brown + mesh - The DMPlex 3138eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 3139552f7358SJed Brown - size - The support size for point p 3140552f7358SJed Brown 3141552f7358SJed Brown Output Parameter: 3142552f7358SJed Brown 3143552f7358SJed Brown Note: 3144552f7358SJed Brown This should be called after DMPlexSetChart(). 3145552f7358SJed Brown 3146552f7358SJed Brown Level: beginner 3147552f7358SJed Brown 3148552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetSupportSize(), DMPlexSetChart() 3149552f7358SJed Brown @*/ 3150552f7358SJed Brown PetscErrorCode DMPlexSetSupportSize(DM dm, PetscInt p, PetscInt size) 3151552f7358SJed Brown { 3152552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3153552f7358SJed Brown PetscErrorCode ierr; 3154552f7358SJed Brown 3155552f7358SJed Brown PetscFunctionBegin; 3156552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3157552f7358SJed Brown ierr = PetscSectionSetDof(mesh->supportSection, p, size);CHKERRQ(ierr); 31580d644c17SKarl Rupp 3159552f7358SJed Brown mesh->maxSupportSize = PetscMax(mesh->maxSupportSize, size); 3160552f7358SJed Brown PetscFunctionReturn(0); 3161552f7358SJed Brown } 3162552f7358SJed Brown 3163552f7358SJed Brown /*@C 3164eaf898f9SPatrick Sanan DMPlexGetSupport - Return the points on the out-edges for this point in the DAG 3165552f7358SJed Brown 3166552f7358SJed Brown Not collective 3167552f7358SJed Brown 3168552f7358SJed Brown Input Parameters: 3169552f7358SJed Brown + mesh - The DMPlex 3170eaf898f9SPatrick Sanan - p - The point, which must lie in the chart set with DMPlexSetChart() 3171552f7358SJed Brown 3172552f7358SJed Brown Output Parameter: 3173552f7358SJed Brown . support - An array of points which are on the out-edges for point p 3174552f7358SJed Brown 3175552f7358SJed Brown Level: beginner 3176552f7358SJed Brown 31773813dfbdSMatthew G Knepley Fortran Notes: 31783813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 31793813dfbdSMatthew G Knepley include petsc.h90 in your code. 31803b12b3d8SVaclav Hapla You must also call DMPlexRestoreSupport() after you finish using the returned array. 3181922102d1SVaclav Hapla DMPlexRestoreSupport() is not needed/available in C. 31823813dfbdSMatthew G Knepley 3183e45f02b0SMatthew G. Knepley .seealso: DMPlexGetSupportSize(), DMPlexSetSupport(), DMPlexGetCone(), DMPlexSetChart() 3184552f7358SJed Brown @*/ 3185552f7358SJed Brown PetscErrorCode DMPlexGetSupport(DM dm, PetscInt p, const PetscInt *support[]) 3186552f7358SJed Brown { 3187552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3188552f7358SJed Brown PetscInt off; 3189552f7358SJed Brown PetscErrorCode ierr; 3190552f7358SJed Brown 3191552f7358SJed Brown PetscFunctionBegin; 3192552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3193552f7358SJed Brown PetscValidPointer(support, 3); 3194552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, p, &off);CHKERRQ(ierr); 3195552f7358SJed Brown *support = &mesh->supports[off]; 3196552f7358SJed Brown PetscFunctionReturn(0); 3197552f7358SJed Brown } 3198552f7358SJed Brown 3199552f7358SJed Brown /*@ 320092371b87SBarry 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 3201552f7358SJed Brown 3202552f7358SJed Brown Not collective 3203552f7358SJed Brown 3204552f7358SJed Brown Input Parameters: 3205552f7358SJed Brown + mesh - The DMPlex 3206eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 320792371b87SBarry Smith - support - An array of points which are on the out-edges for point p 3208552f7358SJed Brown 3209552f7358SJed Brown Output Parameter: 3210552f7358SJed Brown 3211552f7358SJed Brown Note: 3212552f7358SJed Brown This should be called after all calls to DMPlexSetSupportSize() and DMSetUp(). 3213552f7358SJed Brown 3214552f7358SJed Brown Level: beginner 3215552f7358SJed Brown 321692371b87SBarry Smith .seealso: DMPlexSetCone(), DMPlexSetConeSize(), DMPlexCreate(), DMPlexGetSupport(), DMPlexSetChart(), DMPlexSetSupportSize(), DMSetUp() 3217552f7358SJed Brown @*/ 3218552f7358SJed Brown PetscErrorCode DMPlexSetSupport(DM dm, PetscInt p, const PetscInt support[]) 3219552f7358SJed Brown { 3220552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3221552f7358SJed Brown PetscInt pStart, pEnd; 3222552f7358SJed Brown PetscInt dof, off, c; 3223552f7358SJed Brown PetscErrorCode ierr; 3224552f7358SJed Brown 3225552f7358SJed Brown PetscFunctionBegin; 3226552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3227552f7358SJed Brown ierr = PetscSectionGetChart(mesh->supportSection, &pStart, &pEnd);CHKERRQ(ierr); 3228552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, &dof);CHKERRQ(ierr); 3229552f7358SJed Brown if (dof) PetscValidPointer(support, 3); 3230552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, p, &off);CHKERRQ(ierr); 32312c71b3e2SJacob Faibussowitsch PetscCheckFalse((p < pStart) || (p >= pEnd),PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Mesh point %D is not in the valid range [%D, %D)", p, pStart, pEnd); 3232552f7358SJed Brown for (c = 0; c < dof; ++c) { 32332c71b3e2SJacob Faibussowitsch PetscCheckFalse((support[c] < pStart) || (support[c] >= pEnd),PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Support point %D is not in the valid range [%D, %D)", support[c], pStart, pEnd); 3234552f7358SJed Brown mesh->supports[off+c] = support[c]; 3235552f7358SJed Brown } 3236552f7358SJed Brown PetscFunctionReturn(0); 3237552f7358SJed Brown } 3238552f7358SJed Brown 32397cd05799SMatthew G. Knepley /*@ 3240eaf898f9SPatrick Sanan DMPlexInsertSupport - Insert a point into the out-edges for the point p in the DAG 32417cd05799SMatthew G. Knepley 32427cd05799SMatthew G. Knepley Not collective 32437cd05799SMatthew G. Knepley 32447cd05799SMatthew G. Knepley Input Parameters: 32457cd05799SMatthew G. Knepley + mesh - The DMPlex 3246eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 32477cd05799SMatthew G. Knepley . supportPos - The local index in the cone where the point should be put 32487cd05799SMatthew G. Knepley - supportPoint - The mesh point to insert 32497cd05799SMatthew G. Knepley 32507cd05799SMatthew G. Knepley Level: beginner 32517cd05799SMatthew G. Knepley 32527cd05799SMatthew G. Knepley .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexSetChart(), DMPlexSetConeSize(), DMSetUp() 32537cd05799SMatthew G. Knepley @*/ 3254552f7358SJed Brown PetscErrorCode DMPlexInsertSupport(DM dm, PetscInt p, PetscInt supportPos, PetscInt supportPoint) 3255552f7358SJed Brown { 3256552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3257552f7358SJed Brown PetscInt pStart, pEnd; 3258552f7358SJed Brown PetscInt dof, off; 3259552f7358SJed Brown PetscErrorCode ierr; 3260552f7358SJed Brown 3261552f7358SJed Brown PetscFunctionBegin; 3262552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3263552f7358SJed Brown ierr = PetscSectionGetChart(mesh->supportSection, &pStart, &pEnd);CHKERRQ(ierr); 3264552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, &dof);CHKERRQ(ierr); 3265552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, p, &off);CHKERRQ(ierr); 32662c71b3e2SJacob Faibussowitsch PetscCheckFalse((p < pStart) || (p >= pEnd),PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Mesh point %D is not in the valid range [%D, %D)", p, pStart, pEnd); 32672c71b3e2SJacob Faibussowitsch PetscCheckFalse((supportPoint < pStart) || (supportPoint >= pEnd),PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Support point %D is not in the valid range [%D, %D)", supportPoint, pStart, pEnd); 32682c71b3e2SJacob Faibussowitsch PetscCheckFalse(supportPos >= dof,PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Support position %D of point %D is not in the valid range [0, %D)", supportPos, p, dof); 3269552f7358SJed Brown mesh->supports[off+supportPos] = supportPoint; 3270552f7358SJed Brown PetscFunctionReturn(0); 3271552f7358SJed Brown } 3272552f7358SJed Brown 3273b5a892a1SMatthew G. Knepley /* Converts an orientation o in the current numbering to the previous scheme used in Plex */ 3274b5a892a1SMatthew G. Knepley PetscInt DMPolytopeConvertNewOrientation_Internal(DMPolytopeType ct, PetscInt o) 3275b5a892a1SMatthew G. Knepley { 3276b5a892a1SMatthew G. Knepley switch (ct) { 3277b5a892a1SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 3278b5a892a1SMatthew G. Knepley if (o == -1) return -2; 3279b5a892a1SMatthew G. Knepley break; 3280b5a892a1SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 3281b5a892a1SMatthew G. Knepley if (o == -3) return -1; 3282b5a892a1SMatthew G. Knepley if (o == -2) return -3; 3283b5a892a1SMatthew G. Knepley if (o == -1) return -2; 3284b5a892a1SMatthew G. Knepley break; 3285b5a892a1SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 3286b5a892a1SMatthew G. Knepley if (o == -4) return -2; 3287b5a892a1SMatthew G. Knepley if (o == -3) return -1; 3288b5a892a1SMatthew G. Knepley if (o == -2) return -4; 3289b5a892a1SMatthew G. Knepley if (o == -1) return -3; 3290b5a892a1SMatthew G. Knepley break; 3291b5a892a1SMatthew G. Knepley default: return o; 3292b5a892a1SMatthew G. Knepley } 3293b5a892a1SMatthew G. Knepley return o; 3294b5a892a1SMatthew G. Knepley } 3295b5a892a1SMatthew G. Knepley 3296b5a892a1SMatthew G. Knepley /* Converts an orientation o in the previous scheme used in Plex to the current numbering */ 3297b5a892a1SMatthew G. Knepley PetscInt DMPolytopeConvertOldOrientation_Internal(DMPolytopeType ct, PetscInt o) 3298b5a892a1SMatthew G. Knepley { 3299b5a892a1SMatthew G. Knepley switch (ct) { 3300b5a892a1SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 3301b5a892a1SMatthew G. Knepley if ((o == -2) || (o == 1)) return -1; 3302b5a892a1SMatthew G. Knepley if (o == -1) return 0; 3303b5a892a1SMatthew G. Knepley break; 3304b5a892a1SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 3305b5a892a1SMatthew G. Knepley if (o == -3) return -2; 3306b5a892a1SMatthew G. Knepley if (o == -2) return -1; 3307b5a892a1SMatthew G. Knepley if (o == -1) return -3; 3308b5a892a1SMatthew G. Knepley break; 3309b5a892a1SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 3310b5a892a1SMatthew G. Knepley if (o == -4) return -2; 3311b5a892a1SMatthew G. Knepley if (o == -3) return -1; 3312b5a892a1SMatthew G. Knepley if (o == -2) return -4; 3313b5a892a1SMatthew G. Knepley if (o == -1) return -3; 3314b5a892a1SMatthew G. Knepley break; 3315b5a892a1SMatthew G. Knepley default: return o; 3316b5a892a1SMatthew G. Knepley } 3317b5a892a1SMatthew G. Knepley return o; 3318b5a892a1SMatthew G. Knepley } 3319b5a892a1SMatthew G. Knepley 3320b5a892a1SMatthew G. Knepley /* Takes in a mesh whose orientations are in the previous scheme and converts them all to the current numbering */ 3321b5a892a1SMatthew G. Knepley PetscErrorCode DMPlexConvertOldOrientations_Internal(DM dm) 3322b5a892a1SMatthew G. Knepley { 3323b5a892a1SMatthew G. Knepley PetscInt pStart, pEnd, p; 3324b5a892a1SMatthew G. Knepley PetscErrorCode ierr; 3325b5a892a1SMatthew G. Knepley 3326b5a892a1SMatthew G. Knepley PetscFunctionBegin; 3327b5a892a1SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 3328b5a892a1SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 3329b5a892a1SMatthew G. Knepley const PetscInt *cone, *ornt; 3330b5a892a1SMatthew G. Knepley PetscInt coneSize, c; 3331b5a892a1SMatthew G. Knepley 3332b5a892a1SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, p, &coneSize);CHKERRQ(ierr); 3333b5a892a1SMatthew G. Knepley ierr = DMPlexGetCone(dm, p, &cone);CHKERRQ(ierr); 3334b5a892a1SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, p, &ornt);CHKERRQ(ierr); 3335b5a892a1SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 3336b5a892a1SMatthew G. Knepley DMPolytopeType ct; 3337b5a892a1SMatthew G. Knepley const PetscInt o = ornt[c]; 3338b5a892a1SMatthew G. Knepley 3339b5a892a1SMatthew G. Knepley ierr = DMPlexGetCellType(dm, cone[c], &ct);CHKERRQ(ierr); 3340b5a892a1SMatthew G. Knepley switch (ct) { 3341b5a892a1SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 3342b5a892a1SMatthew G. Knepley if ((o == -2) || (o == 1)) {ierr = DMPlexInsertConeOrientation(dm, p, c, -1);CHKERRQ(ierr);} 3343b5a892a1SMatthew G. Knepley if (o == -1) {ierr = DMPlexInsertConeOrientation(dm, p, c, 0);CHKERRQ(ierr);} 3344b5a892a1SMatthew G. Knepley break; 3345b5a892a1SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 3346b5a892a1SMatthew G. Knepley if (o == -3) {ierr = DMPlexInsertConeOrientation(dm, p, c, -2);CHKERRQ(ierr);} 3347b5a892a1SMatthew G. Knepley if (o == -2) {ierr = DMPlexInsertConeOrientation(dm, p, c, -1);CHKERRQ(ierr);} 3348b5a892a1SMatthew G. Knepley if (o == -1) {ierr = DMPlexInsertConeOrientation(dm, p, c, -3);CHKERRQ(ierr);} 3349b5a892a1SMatthew G. Knepley break; 3350b5a892a1SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 3351b5a892a1SMatthew G. Knepley if (o == -4) {ierr = DMPlexInsertConeOrientation(dm, p, c, -2);CHKERRQ(ierr);} 3352b5a892a1SMatthew G. Knepley if (o == -3) {ierr = DMPlexInsertConeOrientation(dm, p, c, -1);CHKERRQ(ierr);} 3353b5a892a1SMatthew G. Knepley if (o == -2) {ierr = DMPlexInsertConeOrientation(dm, p, c, -4);CHKERRQ(ierr);} 3354b5a892a1SMatthew G. Knepley if (o == -1) {ierr = DMPlexInsertConeOrientation(dm, p, c, -3);CHKERRQ(ierr);} 3355b5a892a1SMatthew G. Knepley break; 3356b5a892a1SMatthew G. Knepley default: break; 3357b5a892a1SMatthew G. Knepley } 3358b5a892a1SMatthew G. Knepley } 3359b5a892a1SMatthew G. Knepley } 3360b5a892a1SMatthew G. Knepley PetscFunctionReturn(0); 3361b5a892a1SMatthew G. Knepley } 3362b5a892a1SMatthew G. Knepley 3363012bc364SMatthew G. Knepley static PetscErrorCode DMPlexGetTransitiveClosure_Depth1_Private(DM dm, PetscInt p, PetscInt ornt, PetscBool useCone, PetscInt *numPoints, PetscInt *points[]) 3364b5a892a1SMatthew G. Knepley { 3365b5a892a1SMatthew G. Knepley DMPolytopeType ct = DM_POLYTOPE_UNKNOWN; 3366b5a892a1SMatthew G. Knepley PetscInt *closure; 3367b5a892a1SMatthew G. Knepley const PetscInt *tmp = NULL, *tmpO = NULL; 3368b5a892a1SMatthew G. Knepley PetscInt off = 0, tmpSize, t; 3369b5a892a1SMatthew G. Knepley PetscErrorCode ierr; 3370b5a892a1SMatthew G. Knepley 3371b5a892a1SMatthew G. Knepley PetscFunctionBeginHot; 3372b5a892a1SMatthew G. Knepley if (ornt) { 3373b5a892a1SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 3374b5a892a1SMatthew G. Knepley if (ct == DM_POLYTOPE_FV_GHOST || ct == DM_POLYTOPE_INTERIOR_GHOST || ct == DM_POLYTOPE_UNKNOWN) ct = DM_POLYTOPE_UNKNOWN; 3375b5a892a1SMatthew G. Knepley } 3376b5a892a1SMatthew G. Knepley if (*points) { 3377b5a892a1SMatthew G. Knepley closure = *points; 3378b5a892a1SMatthew G. Knepley } else { 3379b5a892a1SMatthew G. Knepley PetscInt maxConeSize, maxSupportSize; 3380b5a892a1SMatthew G. Knepley ierr = DMPlexGetMaxSizes(dm, &maxConeSize, &maxSupportSize);CHKERRQ(ierr); 3381b5a892a1SMatthew G. Knepley ierr = DMGetWorkArray(dm, 2*(PetscMax(maxConeSize, maxSupportSize)+1), MPIU_INT, &closure);CHKERRQ(ierr); 3382b5a892a1SMatthew G. Knepley } 3383b5a892a1SMatthew G. Knepley if (useCone) { 3384b5a892a1SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, p, &tmpSize);CHKERRQ(ierr); 3385b5a892a1SMatthew G. Knepley ierr = DMPlexGetCone(dm, p, &tmp);CHKERRQ(ierr); 3386b5a892a1SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, p, &tmpO);CHKERRQ(ierr); 3387b5a892a1SMatthew G. Knepley } else { 3388b5a892a1SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, p, &tmpSize);CHKERRQ(ierr); 3389b5a892a1SMatthew G. Knepley ierr = DMPlexGetSupport(dm, p, &tmp);CHKERRQ(ierr); 3390b5a892a1SMatthew G. Knepley } 3391b5a892a1SMatthew G. Knepley if (ct == DM_POLYTOPE_UNKNOWN) { 3392b5a892a1SMatthew G. Knepley closure[off++] = p; 3393b5a892a1SMatthew G. Knepley closure[off++] = 0; 3394b5a892a1SMatthew G. Knepley for (t = 0; t < tmpSize; ++t) { 3395b5a892a1SMatthew G. Knepley closure[off++] = tmp[t]; 3396b5a892a1SMatthew G. Knepley closure[off++] = tmpO ? tmpO[t] : 0; 3397b5a892a1SMatthew G. Knepley } 3398b5a892a1SMatthew G. Knepley } else { 3399b5a892a1SMatthew G. Knepley const PetscInt *arr = DMPolytopeTypeGetArrangment(ct, ornt);CHKERRQ(ierr); 3400b5a892a1SMatthew G. Knepley 3401b5a892a1SMatthew G. Knepley /* We assume that cells with a valid type have faces with a valid type */ 3402b5a892a1SMatthew G. Knepley closure[off++] = p; 3403b5a892a1SMatthew G. Knepley closure[off++] = ornt; 3404b5a892a1SMatthew G. Knepley for (t = 0; t < tmpSize; ++t) { 3405b5a892a1SMatthew G. Knepley DMPolytopeType ft; 3406b5a892a1SMatthew G. Knepley 3407b5a892a1SMatthew G. Knepley ierr = DMPlexGetCellType(dm, tmp[t], &ft);CHKERRQ(ierr); 3408b5a892a1SMatthew G. Knepley closure[off++] = tmp[arr[t]]; 3409b5a892a1SMatthew G. Knepley closure[off++] = tmpO ? DMPolytopeTypeComposeOrientation(ft, ornt, tmpO[t]) : 0; 3410b5a892a1SMatthew G. Knepley } 3411b5a892a1SMatthew G. Knepley } 3412b5a892a1SMatthew G. Knepley if (numPoints) *numPoints = tmpSize+1; 3413b5a892a1SMatthew G. Knepley if (points) *points = closure; 3414b5a892a1SMatthew G. Knepley PetscFunctionReturn(0); 3415b5a892a1SMatthew G. Knepley } 3416b5a892a1SMatthew G. Knepley 3417b5a892a1SMatthew G. Knepley /* We need a special tensor verison becasue we want to allow duplicate points in the endcaps for hybrid cells */ 3418b5a892a1SMatthew G. Knepley static PetscErrorCode DMPlexTransitiveClosure_Tensor_Internal(DM dm, PetscInt point, DMPolytopeType ct, PetscInt o, PetscBool useCone, PetscInt *numPoints, PetscInt **points) 3419b5a892a1SMatthew G. Knepley { 3420b5a892a1SMatthew G. Knepley const PetscInt *arr = DMPolytopeTypeGetArrangment(ct, o); 3421b5a892a1SMatthew G. Knepley const PetscInt *cone, *ornt; 3422b5a892a1SMatthew G. Knepley PetscInt *pts, *closure = NULL; 3423b5a892a1SMatthew G. Knepley DMPolytopeType ft; 3424b5a892a1SMatthew G. Knepley PetscInt maxConeSize, maxSupportSize, coneSeries, supportSeries, maxSize; 3425b5a892a1SMatthew G. Knepley PetscInt dim, coneSize, c, d, clSize, cl; 3426b5a892a1SMatthew G. Knepley PetscErrorCode ierr; 3427b5a892a1SMatthew G. Knepley 3428b5a892a1SMatthew G. Knepley PetscFunctionBeginHot; 3429b5a892a1SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 3430b5a892a1SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, point, &coneSize);CHKERRQ(ierr); 3431b5a892a1SMatthew G. Knepley ierr = DMPlexGetCone(dm, point, &cone);CHKERRQ(ierr); 3432b5a892a1SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, point, &ornt);CHKERRQ(ierr); 3433b5a892a1SMatthew G. Knepley ierr = DMPlexGetMaxSizes(dm, &maxConeSize, &maxSupportSize);CHKERRQ(ierr); 3434b5a892a1SMatthew G. Knepley coneSeries = (maxConeSize > 1) ? ((PetscPowInt(maxConeSize, dim+1)-1)/(maxConeSize-1)) : dim+1; 3435b5a892a1SMatthew G. Knepley supportSeries = (maxSupportSize > 1) ? ((PetscPowInt(maxSupportSize, dim+1)-1)/(maxSupportSize-1)) : dim+1; 3436b5a892a1SMatthew G. Knepley maxSize = PetscMax(coneSeries, supportSeries); 3437b5a892a1SMatthew G. Knepley if (*points) {pts = *points;} 3438b5a892a1SMatthew G. Knepley else {ierr = DMGetWorkArray(dm, 2*maxSize, MPIU_INT, &pts);CHKERRQ(ierr);} 3439b5a892a1SMatthew G. Knepley c = 0; 3440b5a892a1SMatthew G. Knepley pts[c++] = point; 3441b5a892a1SMatthew G. Knepley pts[c++] = o; 3442b5a892a1SMatthew G. Knepley ierr = DMPlexGetCellType(dm, cone[arr[0*2+0]], &ft);CHKERRQ(ierr); 3443b5a892a1SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure_Internal(dm, cone[arr[0*2+0]], DMPolytopeTypeComposeOrientation(ft, arr[0*2+1], ornt[0]), useCone, &clSize, &closure);CHKERRQ(ierr); 3444b5a892a1SMatthew G. Knepley for (cl = 0; cl < clSize*2; cl += 2) {pts[c++] = closure[cl]; pts[c++] = closure[cl+1];} 3445b5a892a1SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure_Internal(dm, cone[arr[1*2+0]], DMPolytopeTypeComposeOrientation(ft, arr[1*2+1], ornt[1]), useCone, &clSize, &closure);CHKERRQ(ierr); 3446b5a892a1SMatthew G. Knepley for (cl = 0; cl < clSize*2; cl += 2) {pts[c++] = closure[cl]; pts[c++] = closure[cl+1];} 3447b5a892a1SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, cone[0], useCone, &clSize, &closure);CHKERRQ(ierr); 3448b5a892a1SMatthew G. Knepley for (d = 2; d < coneSize; ++d) { 3449b5a892a1SMatthew G. Knepley ierr = DMPlexGetCellType(dm, cone[arr[d*2+0]], &ft);CHKERRQ(ierr); 3450b5a892a1SMatthew G. Knepley pts[c++] = cone[arr[d*2+0]]; 3451b5a892a1SMatthew G. Knepley pts[c++] = DMPolytopeTypeComposeOrientation(ft, arr[d*2+1], ornt[d]); 3452b5a892a1SMatthew G. Knepley } 3453b5a892a1SMatthew G. Knepley if (dim >= 3) { 3454b5a892a1SMatthew G. Knepley for (d = 2; d < coneSize; ++d) { 3455b5a892a1SMatthew G. Knepley const PetscInt fpoint = cone[arr[d*2+0]]; 3456b5a892a1SMatthew G. Knepley const PetscInt *fcone, *fornt; 3457b5a892a1SMatthew G. Knepley PetscInt fconeSize, fc, i; 3458b5a892a1SMatthew G. Knepley 3459b5a892a1SMatthew G. Knepley ierr = DMPlexGetCellType(dm, fpoint, &ft);CHKERRQ(ierr); 3460b5a892a1SMatthew G. Knepley const PetscInt *farr = DMPolytopeTypeGetArrangment(ft, DMPolytopeTypeComposeOrientation(ft, arr[d*2+1], ornt[d])); 3461b5a892a1SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, fpoint, &fconeSize);CHKERRQ(ierr); 3462b5a892a1SMatthew G. Knepley ierr = DMPlexGetCone(dm, fpoint, &fcone);CHKERRQ(ierr); 3463b5a892a1SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, fpoint, &fornt);CHKERRQ(ierr); 3464b5a892a1SMatthew G. Knepley for (fc = 0; fc < fconeSize; ++fc) { 3465b5a892a1SMatthew G. Knepley const PetscInt cp = fcone[farr[fc*2+0]]; 3466b5a892a1SMatthew G. Knepley const PetscInt co = farr[fc*2+1]; 3467b5a892a1SMatthew G. Knepley 3468b5a892a1SMatthew G. Knepley for (i = 0; i < c; i += 2) if (pts[i] == cp) break; 3469b5a892a1SMatthew G. Knepley if (i == c) { 3470b5a892a1SMatthew G. Knepley ierr = DMPlexGetCellType(dm, cp, &ft);CHKERRQ(ierr); 3471b5a892a1SMatthew G. Knepley pts[c++] = cp; 3472b5a892a1SMatthew G. Knepley pts[c++] = DMPolytopeTypeComposeOrientation(ft, co, fornt[farr[fc*2+0]]); 3473b5a892a1SMatthew G. Knepley } 3474b5a892a1SMatthew G. Knepley } 3475b5a892a1SMatthew G. Knepley } 3476b5a892a1SMatthew G. Knepley } 3477b5a892a1SMatthew G. Knepley *numPoints = c/2; 3478b5a892a1SMatthew G. Knepley *points = pts; 3479b5a892a1SMatthew G. Knepley PetscFunctionReturn(0); 3480b5a892a1SMatthew G. Knepley } 3481b5a892a1SMatthew G. Knepley 3482b5a892a1SMatthew G. Knepley PetscErrorCode DMPlexGetTransitiveClosure_Internal(DM dm, PetscInt p, PetscInt ornt, PetscBool useCone, PetscInt *numPoints, PetscInt *points[]) 3483b5a892a1SMatthew G. Knepley { 3484b5a892a1SMatthew G. Knepley DMPolytopeType ct; 3485b5a892a1SMatthew G. Knepley PetscInt *closure, *fifo; 3486b5a892a1SMatthew G. Knepley PetscInt closureSize = 0, fifoStart = 0, fifoSize = 0; 3487b5a892a1SMatthew G. Knepley PetscInt maxConeSize, maxSupportSize, coneSeries, supportSeries; 3488b5a892a1SMatthew G. Knepley PetscInt depth, maxSize; 3489b5a892a1SMatthew G. Knepley PetscErrorCode ierr; 3490b5a892a1SMatthew G. Knepley 3491b5a892a1SMatthew G. Knepley PetscFunctionBeginHot; 3492b5a892a1SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 3493b5a892a1SMatthew G. Knepley if (depth == 1) { 3494012bc364SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure_Depth1_Private(dm, p, ornt, useCone, numPoints, points);CHKERRQ(ierr); 3495b5a892a1SMatthew G. Knepley PetscFunctionReturn(0); 3496b5a892a1SMatthew G. Knepley } 3497b5a892a1SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 3498b5a892a1SMatthew G. Knepley if (ct == DM_POLYTOPE_FV_GHOST || ct == DM_POLYTOPE_INTERIOR_GHOST || ct == DM_POLYTOPE_UNKNOWN) ct = DM_POLYTOPE_UNKNOWN; 3499b5a892a1SMatthew G. Knepley if (ct == DM_POLYTOPE_SEG_PRISM_TENSOR || ct == DM_POLYTOPE_TRI_PRISM_TENSOR || ct == DM_POLYTOPE_QUAD_PRISM_TENSOR) { 3500b5a892a1SMatthew G. Knepley ierr = DMPlexTransitiveClosure_Tensor_Internal(dm, p, ct, ornt, useCone, numPoints, points);CHKERRQ(ierr); 3501b5a892a1SMatthew G. Knepley PetscFunctionReturn(0); 3502b5a892a1SMatthew G. Knepley } 3503b5a892a1SMatthew G. Knepley ierr = DMPlexGetMaxSizes(dm, &maxConeSize, &maxSupportSize);CHKERRQ(ierr); 3504b5a892a1SMatthew G. Knepley coneSeries = (maxConeSize > 1) ? ((PetscPowInt(maxConeSize, depth+1)-1)/(maxConeSize-1)) : depth+1; 3505b5a892a1SMatthew G. Knepley supportSeries = (maxSupportSize > 1) ? ((PetscPowInt(maxSupportSize, depth+1)-1)/(maxSupportSize-1)) : depth+1; 3506b5a892a1SMatthew G. Knepley maxSize = PetscMax(coneSeries, supportSeries); 3507b5a892a1SMatthew G. Knepley ierr = DMGetWorkArray(dm, 3*maxSize, MPIU_INT, &fifo);CHKERRQ(ierr); 3508b5a892a1SMatthew G. Knepley if (*points) {closure = *points;} 3509b5a892a1SMatthew G. Knepley else {ierr = DMGetWorkArray(dm, 2*maxSize, MPIU_INT, &closure);CHKERRQ(ierr);} 3510b5a892a1SMatthew G. Knepley closure[closureSize++] = p; 3511b5a892a1SMatthew G. Knepley closure[closureSize++] = ornt; 3512b5a892a1SMatthew G. Knepley fifo[fifoSize++] = p; 3513b5a892a1SMatthew G. Knepley fifo[fifoSize++] = ornt; 3514b5a892a1SMatthew G. Knepley fifo[fifoSize++] = ct; 3515b5a892a1SMatthew G. Knepley /* Should kick out early when depth is reached, rather than checking all vertices for empty cones */ 3516b5a892a1SMatthew G. Knepley while (fifoSize - fifoStart) { 3517b5a892a1SMatthew G. Knepley const PetscInt q = fifo[fifoStart++]; 3518b5a892a1SMatthew G. Knepley const PetscInt o = fifo[fifoStart++]; 3519b5a892a1SMatthew G. Knepley const DMPolytopeType qt = (DMPolytopeType) fifo[fifoStart++]; 3520b5a892a1SMatthew G. Knepley const PetscInt *qarr = DMPolytopeTypeGetArrangment(qt, o); 3521b5a892a1SMatthew G. Knepley const PetscInt *tmp, *tmpO; 3522b5a892a1SMatthew G. Knepley PetscInt tmpSize, t; 3523b5a892a1SMatthew G. Knepley 3524b5a892a1SMatthew G. Knepley if (PetscDefined(USE_DEBUG)) { 3525b5a892a1SMatthew G. Knepley PetscInt nO = DMPolytopeTypeGetNumArrangments(qt)/2; 35262c71b3e2SJacob Faibussowitsch PetscCheckFalse(o && (o >= nO || o < -nO),PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid orientation %D not in [%D,%D) for %s %D", o, -nO, nO, DMPolytopeTypes[qt], q); 3527b5a892a1SMatthew G. Knepley } 3528b5a892a1SMatthew G. Knepley if (useCone) { 3529b5a892a1SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, q, &tmpSize);CHKERRQ(ierr); 3530b5a892a1SMatthew G. Knepley ierr = DMPlexGetCone(dm, q, &tmp);CHKERRQ(ierr); 3531b5a892a1SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, q, &tmpO);CHKERRQ(ierr); 3532b5a892a1SMatthew G. Knepley } else { 3533b5a892a1SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, q, &tmpSize);CHKERRQ(ierr); 3534b5a892a1SMatthew G. Knepley ierr = DMPlexGetSupport(dm, q, &tmp);CHKERRQ(ierr); 3535b5a892a1SMatthew G. Knepley tmpO = NULL; 3536b5a892a1SMatthew G. Knepley } 3537b5a892a1SMatthew G. Knepley for (t = 0; t < tmpSize; ++t) { 3538b5a892a1SMatthew G. Knepley const PetscInt ip = useCone && qarr ? qarr[t*2] : t; 3539b5a892a1SMatthew G. Knepley const PetscInt io = useCone && qarr ? qarr[t*2+1] : 0; 3540b5a892a1SMatthew G. Knepley const PetscInt cp = tmp[ip]; 3541b5a892a1SMatthew G. Knepley ierr = DMPlexGetCellType(dm, cp, &ct);CHKERRQ(ierr); 3542b5a892a1SMatthew G. Knepley const PetscInt co = tmpO ? DMPolytopeTypeComposeOrientation(ct, io, tmpO[ip]) : 0; 3543b5a892a1SMatthew G. Knepley PetscInt c; 3544b5a892a1SMatthew G. Knepley 3545b5a892a1SMatthew G. Knepley /* Check for duplicate */ 3546b5a892a1SMatthew G. Knepley for (c = 0; c < closureSize; c += 2) { 3547b5a892a1SMatthew G. Knepley if (closure[c] == cp) break; 3548b5a892a1SMatthew G. Knepley } 3549b5a892a1SMatthew G. Knepley if (c == closureSize) { 3550b5a892a1SMatthew G. Knepley closure[closureSize++] = cp; 3551b5a892a1SMatthew G. Knepley closure[closureSize++] = co; 3552b5a892a1SMatthew G. Knepley fifo[fifoSize++] = cp; 3553b5a892a1SMatthew G. Knepley fifo[fifoSize++] = co; 3554b5a892a1SMatthew G. Knepley fifo[fifoSize++] = ct; 3555b5a892a1SMatthew G. Knepley } 3556b5a892a1SMatthew G. Knepley } 3557b5a892a1SMatthew G. Knepley } 3558b5a892a1SMatthew G. Knepley ierr = DMRestoreWorkArray(dm, 3*maxSize, MPIU_INT, &fifo);CHKERRQ(ierr); 3559b5a892a1SMatthew G. Knepley if (numPoints) *numPoints = closureSize/2; 3560b5a892a1SMatthew G. Knepley if (points) *points = closure; 3561b5a892a1SMatthew G. Knepley PetscFunctionReturn(0); 3562b5a892a1SMatthew G. Knepley } 3563b5a892a1SMatthew G. Knepley 3564552f7358SJed Brown /*@C 3565eaf898f9SPatrick Sanan DMPlexGetTransitiveClosure - Return the points on the transitive closure of the in-edges or out-edges for this point in the DAG 3566552f7358SJed Brown 3567552f7358SJed Brown Not collective 3568552f7358SJed Brown 3569552f7358SJed Brown Input Parameters: 3570b5a892a1SMatthew G. Knepley + dm - The DMPlex 3571b5a892a1SMatthew G. Knepley . p - The mesh point 35726b867d5aSJose E. Roman - useCone - PETSC_TRUE for the closure, otherwise return the star 3573552f7358SJed Brown 35746b867d5aSJose E. Roman Input/Output Parameter: 35756b867d5aSJose E. Roman . points - The points and point orientations, interleaved as pairs [p0, o0, p1, o1, ...]; 35766b867d5aSJose E. Roman if NULL on input, internal storage will be returned, otherwise the provided array is used 35776b867d5aSJose E. Roman 35786b867d5aSJose E. Roman Output Parameter: 35796b867d5aSJose E. Roman . numPoints - The number of points in the closure, so points[] is of size 2*numPoints 3580552f7358SJed Brown 3581552f7358SJed Brown Note: 35820298fd71SBarry Smith If using internal storage (points is NULL on input), each call overwrites the last output. 3583552f7358SJed Brown 35843813dfbdSMatthew G Knepley Fortran Notes: 3585b5a892a1SMatthew G. Knepley Since it returns an array, this routine is only available in Fortran 90, and you must include petsc.h90 in your code. 35863813dfbdSMatthew G Knepley 35873813dfbdSMatthew G Knepley The numPoints argument is not present in the Fortran 90 binding since it is internal to the array. 35883813dfbdSMatthew G Knepley 3589552f7358SJed Brown Level: beginner 3590552f7358SJed Brown 3591552f7358SJed Brown .seealso: DMPlexRestoreTransitiveClosure(), DMPlexCreate(), DMPlexSetCone(), DMPlexSetChart(), DMPlexGetCone() 3592552f7358SJed Brown @*/ 3593552f7358SJed Brown PetscErrorCode DMPlexGetTransitiveClosure(DM dm, PetscInt p, PetscBool useCone, PetscInt *numPoints, PetscInt *points[]) 3594552f7358SJed Brown { 3595552f7358SJed Brown PetscErrorCode ierr; 3596552f7358SJed Brown 3597b5a892a1SMatthew G. Knepley PetscFunctionBeginHot; 3598552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3599b5a892a1SMatthew G. Knepley if (numPoints) PetscValidIntPointer(numPoints, 4); 3600b5a892a1SMatthew G. Knepley if (points) PetscValidPointer(points, 5); 3601b5a892a1SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure_Internal(dm, p, 0, useCone, numPoints, points);CHKERRQ(ierr); 36029bf0dad6SMatthew G. Knepley PetscFunctionReturn(0); 36039bf0dad6SMatthew G. Knepley } 36049bf0dad6SMatthew G. Knepley 3605552f7358SJed Brown /*@C 3606eaf898f9SPatrick Sanan DMPlexRestoreTransitiveClosure - Restore the array of points on the transitive closure of the in-edges or out-edges for this point in the DAG 3607552f7358SJed Brown 3608552f7358SJed Brown Not collective 3609552f7358SJed Brown 3610552f7358SJed Brown Input Parameters: 3611b5a892a1SMatthew G. Knepley + dm - The DMPlex 3612b5a892a1SMatthew G. Knepley . p - The mesh point 3613b5a892a1SMatthew G. Knepley . useCone - PETSC_TRUE for the closure, otherwise return the star 3614b5a892a1SMatthew G. Knepley . numPoints - The number of points in the closure, so points[] is of size 2*numPoints 3615b5a892a1SMatthew G. Knepley - points - The points and point orientations, interleaved as pairs [p0, o0, p1, o1, ...] 3616552f7358SJed Brown 3617552f7358SJed Brown Note: 36180298fd71SBarry Smith If not using internal storage (points is not NULL on input), this call is unnecessary 3619552f7358SJed Brown 36203813dfbdSMatthew G Knepley Fortran Notes: 3621b5a892a1SMatthew G. Knepley Since it returns an array, this routine is only available in Fortran 90, and you must include petsc.h90 in your code. 36223813dfbdSMatthew G Knepley 36233813dfbdSMatthew G Knepley The numPoints argument is not present in the Fortran 90 binding since it is internal to the array. 36243813dfbdSMatthew G Knepley 3625552f7358SJed Brown Level: beginner 3626552f7358SJed Brown 3627552f7358SJed Brown .seealso: DMPlexGetTransitiveClosure(), DMPlexCreate(), DMPlexSetCone(), DMPlexSetChart(), DMPlexGetCone() 3628552f7358SJed Brown @*/ 3629552f7358SJed Brown PetscErrorCode DMPlexRestoreTransitiveClosure(DM dm, PetscInt p, PetscBool useCone, PetscInt *numPoints, PetscInt *points[]) 3630552f7358SJed Brown { 3631552f7358SJed Brown PetscErrorCode ierr; 3632552f7358SJed Brown 3633b5a892a1SMatthew G. Knepley PetscFunctionBeginHot; 3634552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 36354ff43b2cSJed Brown if (numPoints) *numPoints = 0; 3636b5a892a1SMatthew G. Knepley ierr = DMRestoreWorkArray(dm, 0, MPIU_INT, points);CHKERRQ(ierr); 3637552f7358SJed Brown PetscFunctionReturn(0); 3638552f7358SJed Brown } 3639552f7358SJed Brown 3640552f7358SJed Brown /*@ 3641eaf898f9SPatrick Sanan DMPlexGetMaxSizes - Return the maximum number of in-edges (cone) and out-edges (support) for any point in the DAG 3642552f7358SJed Brown 3643552f7358SJed Brown Not collective 3644552f7358SJed Brown 3645552f7358SJed Brown Input Parameter: 3646552f7358SJed Brown . mesh - The DMPlex 3647552f7358SJed Brown 3648552f7358SJed Brown Output Parameters: 3649552f7358SJed Brown + maxConeSize - The maximum number of in-edges 3650552f7358SJed Brown - maxSupportSize - The maximum number of out-edges 3651552f7358SJed Brown 3652552f7358SJed Brown Level: beginner 3653552f7358SJed Brown 3654552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetConeSize(), DMPlexSetChart() 3655552f7358SJed Brown @*/ 3656552f7358SJed Brown PetscErrorCode DMPlexGetMaxSizes(DM dm, PetscInt *maxConeSize, PetscInt *maxSupportSize) 3657552f7358SJed Brown { 3658552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3659552f7358SJed Brown 3660552f7358SJed Brown PetscFunctionBegin; 3661552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3662552f7358SJed Brown if (maxConeSize) *maxConeSize = mesh->maxConeSize; 3663552f7358SJed Brown if (maxSupportSize) *maxSupportSize = mesh->maxSupportSize; 3664552f7358SJed Brown PetscFunctionReturn(0); 3665552f7358SJed Brown } 3666552f7358SJed Brown 3667552f7358SJed Brown PetscErrorCode DMSetUp_Plex(DM dm) 3668552f7358SJed Brown { 3669552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3670552f7358SJed Brown PetscInt size; 3671552f7358SJed Brown PetscErrorCode ierr; 3672552f7358SJed Brown 3673552f7358SJed Brown PetscFunctionBegin; 3674552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3675552f7358SJed Brown ierr = PetscSectionSetUp(mesh->coneSection);CHKERRQ(ierr); 3676552f7358SJed Brown ierr = PetscSectionGetStorageSize(mesh->coneSection, &size);CHKERRQ(ierr); 36771795a4d1SJed Brown ierr = PetscMalloc1(size, &mesh->cones);CHKERRQ(ierr); 36781795a4d1SJed Brown ierr = PetscCalloc1(size, &mesh->coneOrientations);CHKERRQ(ierr); 3679ef1259faSMatthew G. Knepley ierr = PetscLogObjectMemory((PetscObject) dm, size*2*sizeof(PetscInt));CHKERRQ(ierr); 3680552f7358SJed Brown if (mesh->maxSupportSize) { 3681552f7358SJed Brown ierr = PetscSectionSetUp(mesh->supportSection);CHKERRQ(ierr); 3682552f7358SJed Brown ierr = PetscSectionGetStorageSize(mesh->supportSection, &size);CHKERRQ(ierr); 36831795a4d1SJed Brown ierr = PetscMalloc1(size, &mesh->supports);CHKERRQ(ierr); 3684ef1259faSMatthew G. Knepley ierr = PetscLogObjectMemory((PetscObject) dm, size*sizeof(PetscInt));CHKERRQ(ierr); 3685552f7358SJed Brown } 3686552f7358SJed Brown PetscFunctionReturn(0); 3687552f7358SJed Brown } 3688552f7358SJed Brown 3689276c5506SMatthew G. Knepley PetscErrorCode DMCreateSubDM_Plex(DM dm, PetscInt numFields, const PetscInt fields[], IS *is, DM *subdm) 3690552f7358SJed Brown { 3691552f7358SJed Brown PetscErrorCode ierr; 3692552f7358SJed Brown 3693552f7358SJed Brown PetscFunctionBegin; 36944d9407bcSMatthew G. Knepley if (subdm) {ierr = DMClone(dm, subdm);CHKERRQ(ierr);} 3695792b654fSMatthew G. Knepley ierr = DMCreateSectionSubDM(dm, numFields, fields, is, subdm);CHKERRQ(ierr); 3696c2939958SSatish Balay if (subdm) {(*subdm)->useNatural = dm->useNatural;} 3697736995cdSBlaise Bourdin if (dm->useNatural && dm->sfMigration) { 3698f94b4a02SBlaise Bourdin PetscSF sfMigrationInv,sfNatural; 3699f94b4a02SBlaise Bourdin PetscSection section, sectionSeq; 3700f94b4a02SBlaise Bourdin 37013dcd263cSBlaise Bourdin (*subdm)->sfMigration = dm->sfMigration; 37023dcd263cSBlaise Bourdin ierr = PetscObjectReference((PetscObject) dm->sfMigration);CHKERRQ(ierr); 3703c3b366b1Sprj- ierr = DMGetLocalSection((*subdm), §ion);CHKERRQ(ierr); 3704f94b4a02SBlaise Bourdin ierr = PetscSFCreateInverseSF((*subdm)->sfMigration, &sfMigrationInv);CHKERRQ(ierr); 3705f94b4a02SBlaise Bourdin ierr = PetscSectionCreate(PetscObjectComm((PetscObject) (*subdm)), §ionSeq);CHKERRQ(ierr); 3706f94b4a02SBlaise Bourdin ierr = PetscSFDistributeSection(sfMigrationInv, section, NULL, sectionSeq);CHKERRQ(ierr); 3707f94b4a02SBlaise Bourdin 3708f94b4a02SBlaise Bourdin ierr = DMPlexCreateGlobalToNaturalSF(*subdm, sectionSeq, (*subdm)->sfMigration, &sfNatural);CHKERRQ(ierr); 3709c40e9495SBlaise Bourdin (*subdm)->sfNatural = sfNatural; 3710f94b4a02SBlaise Bourdin ierr = PetscSectionDestroy(§ionSeq);CHKERRQ(ierr); 3711f94b4a02SBlaise Bourdin ierr = PetscSFDestroy(&sfMigrationInv);CHKERRQ(ierr); 3712f94b4a02SBlaise Bourdin } 3713552f7358SJed Brown PetscFunctionReturn(0); 3714552f7358SJed Brown } 3715552f7358SJed Brown 37162adcc780SMatthew G. Knepley PetscErrorCode DMCreateSuperDM_Plex(DM dms[], PetscInt len, IS **is, DM *superdm) 37172adcc780SMatthew G. Knepley { 37182adcc780SMatthew G. Knepley PetscErrorCode ierr; 37193dcd263cSBlaise Bourdin PetscInt i = 0; 37202adcc780SMatthew G. Knepley 37212adcc780SMatthew G. Knepley PetscFunctionBegin; 3722435bcee1SStefano Zampini ierr = DMClone(dms[0], superdm);CHKERRQ(ierr); 3723792b654fSMatthew G. Knepley ierr = DMCreateSectionSuperDM(dms, len, is, superdm);CHKERRQ(ierr); 3724c40e9495SBlaise Bourdin (*superdm)->useNatural = PETSC_FALSE; 37253dcd263cSBlaise Bourdin for (i = 0; i < len; i++) { 37263dcd263cSBlaise Bourdin if (dms[i]->useNatural && dms[i]->sfMigration) { 37273dcd263cSBlaise Bourdin PetscSF sfMigrationInv,sfNatural; 37283dcd263cSBlaise Bourdin PetscSection section, sectionSeq; 37293dcd263cSBlaise Bourdin 37303dcd263cSBlaise Bourdin (*superdm)->sfMigration = dms[i]->sfMigration; 37313dcd263cSBlaise Bourdin ierr = PetscObjectReference((PetscObject) dms[i]->sfMigration);CHKERRQ(ierr); 3732c40e9495SBlaise Bourdin (*superdm)->useNatural = PETSC_TRUE; 373392fd8e1eSJed Brown ierr = DMGetLocalSection((*superdm), §ion);CHKERRQ(ierr); 37343dcd263cSBlaise Bourdin ierr = PetscSFCreateInverseSF((*superdm)->sfMigration, &sfMigrationInv);CHKERRQ(ierr); 37353dcd263cSBlaise Bourdin ierr = PetscSectionCreate(PetscObjectComm((PetscObject) (*superdm)), §ionSeq);CHKERRQ(ierr); 37363dcd263cSBlaise Bourdin ierr = PetscSFDistributeSection(sfMigrationInv, section, NULL, sectionSeq);CHKERRQ(ierr); 37373dcd263cSBlaise Bourdin 37383dcd263cSBlaise Bourdin ierr = DMPlexCreateGlobalToNaturalSF(*superdm, sectionSeq, (*superdm)->sfMigration, &sfNatural);CHKERRQ(ierr); 3739c40e9495SBlaise Bourdin (*superdm)->sfNatural = sfNatural; 37403dcd263cSBlaise Bourdin ierr = PetscSectionDestroy(§ionSeq);CHKERRQ(ierr); 37413dcd263cSBlaise Bourdin ierr = PetscSFDestroy(&sfMigrationInv);CHKERRQ(ierr); 37423dcd263cSBlaise Bourdin break; 37433dcd263cSBlaise Bourdin } 37443dcd263cSBlaise Bourdin } 37452adcc780SMatthew G. Knepley PetscFunctionReturn(0); 37462adcc780SMatthew G. Knepley } 37472adcc780SMatthew G. Knepley 3748552f7358SJed Brown /*@ 3749eaf898f9SPatrick Sanan DMPlexSymmetrize - Create support (out-edge) information from cone (in-edge) information 3750552f7358SJed Brown 3751552f7358SJed Brown Not collective 3752552f7358SJed Brown 3753552f7358SJed Brown Input Parameter: 3754552f7358SJed Brown . mesh - The DMPlex 3755552f7358SJed Brown 3756552f7358SJed Brown Output Parameter: 3757552f7358SJed Brown 3758552f7358SJed Brown Note: 3759552f7358SJed Brown This should be called after all calls to DMPlexSetCone() 3760552f7358SJed Brown 3761552f7358SJed Brown Level: beginner 3762552f7358SJed Brown 3763552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetChart(), DMPlexSetConeSize(), DMPlexSetCone() 3764552f7358SJed Brown @*/ 3765552f7358SJed Brown PetscErrorCode DMPlexSymmetrize(DM dm) 3766552f7358SJed Brown { 3767552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3768552f7358SJed Brown PetscInt *offsets; 3769552f7358SJed Brown PetscInt supportSize; 3770552f7358SJed Brown PetscInt pStart, pEnd, p; 3771552f7358SJed Brown PetscErrorCode ierr; 3772552f7358SJed Brown 3773552f7358SJed Brown PetscFunctionBegin; 3774552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 37752c71b3e2SJacob Faibussowitsch PetscCheckFalse(mesh->supports,PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Supports were already setup in this DMPlex"); 377630b0ce1bSStefano Zampini ierr = PetscLogEventBegin(DMPLEX_Symmetrize,dm,0,0,0);CHKERRQ(ierr); 3777552f7358SJed Brown /* Calculate support sizes */ 3778552f7358SJed Brown ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 3779552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 3780552f7358SJed Brown PetscInt dof, off, c; 3781552f7358SJed Brown 3782552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 3783552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 3784552f7358SJed Brown for (c = off; c < off+dof; ++c) { 3785552f7358SJed Brown ierr = PetscSectionAddDof(mesh->supportSection, mesh->cones[c], 1);CHKERRQ(ierr); 3786552f7358SJed Brown } 3787552f7358SJed Brown } 3788552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 3789552f7358SJed Brown PetscInt dof; 3790552f7358SJed Brown 3791552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, &dof);CHKERRQ(ierr); 37920d644c17SKarl Rupp 3793552f7358SJed Brown mesh->maxSupportSize = PetscMax(mesh->maxSupportSize, dof); 3794552f7358SJed Brown } 3795552f7358SJed Brown ierr = PetscSectionSetUp(mesh->supportSection);CHKERRQ(ierr); 3796552f7358SJed Brown /* Calculate supports */ 3797552f7358SJed Brown ierr = PetscSectionGetStorageSize(mesh->supportSection, &supportSize);CHKERRQ(ierr); 37981795a4d1SJed Brown ierr = PetscMalloc1(supportSize, &mesh->supports);CHKERRQ(ierr); 37991795a4d1SJed Brown ierr = PetscCalloc1(pEnd - pStart, &offsets);CHKERRQ(ierr); 3800552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 3801552f7358SJed Brown PetscInt dof, off, c; 3802552f7358SJed Brown 3803552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 3804552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 3805552f7358SJed Brown for (c = off; c < off+dof; ++c) { 3806552f7358SJed Brown const PetscInt q = mesh->cones[c]; 3807552f7358SJed Brown PetscInt offS; 3808552f7358SJed Brown 3809552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, q, &offS);CHKERRQ(ierr); 38100d644c17SKarl Rupp 3811552f7358SJed Brown mesh->supports[offS+offsets[q]] = p; 3812552f7358SJed Brown ++offsets[q]; 3813552f7358SJed Brown } 3814552f7358SJed Brown } 3815552f7358SJed Brown ierr = PetscFree(offsets);CHKERRQ(ierr); 381630b0ce1bSStefano Zampini ierr = PetscLogEventEnd(DMPLEX_Symmetrize,dm,0,0,0);CHKERRQ(ierr); 3817552f7358SJed Brown PetscFunctionReturn(0); 3818552f7358SJed Brown } 3819552f7358SJed Brown 3820277ea44aSLisandro Dalcin static PetscErrorCode DMPlexCreateDepthStratum(DM dm, DMLabel label, PetscInt depth, PetscInt pStart, PetscInt pEnd) 3821277ea44aSLisandro Dalcin { 3822277ea44aSLisandro Dalcin IS stratumIS; 3823277ea44aSLisandro Dalcin PetscErrorCode ierr; 3824277ea44aSLisandro Dalcin 3825277ea44aSLisandro Dalcin PetscFunctionBegin; 3826277ea44aSLisandro Dalcin if (pStart >= pEnd) PetscFunctionReturn(0); 382776bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 3828277ea44aSLisandro Dalcin PetscInt qStart, qEnd, numLevels, level; 3829277ea44aSLisandro Dalcin PetscBool overlap = PETSC_FALSE; 3830277ea44aSLisandro Dalcin ierr = DMLabelGetNumValues(label, &numLevels);CHKERRQ(ierr); 3831277ea44aSLisandro Dalcin for (level = 0; level < numLevels; level++) { 3832277ea44aSLisandro Dalcin ierr = DMLabelGetStratumBounds(label, level, &qStart, &qEnd);CHKERRQ(ierr); 3833277ea44aSLisandro Dalcin if ((pStart >= qStart && pStart < qEnd) || (pEnd > qStart && pEnd <= qEnd)) {overlap = PETSC_TRUE; break;} 3834277ea44aSLisandro Dalcin } 38352c71b3e2SJacob Faibussowitsch PetscCheckFalse(overlap,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); 3836277ea44aSLisandro Dalcin } 3837277ea44aSLisandro Dalcin ierr = ISCreateStride(PETSC_COMM_SELF, pEnd-pStart, pStart, 1, &stratumIS);CHKERRQ(ierr); 3838277ea44aSLisandro Dalcin ierr = DMLabelSetStratumIS(label, depth, stratumIS);CHKERRQ(ierr); 3839277ea44aSLisandro Dalcin ierr = ISDestroy(&stratumIS);CHKERRQ(ierr); 3840277ea44aSLisandro Dalcin PetscFunctionReturn(0); 3841277ea44aSLisandro Dalcin } 3842277ea44aSLisandro Dalcin 3843552f7358SJed Brown /*@ 3844a8d69d7bSBarry Smith DMPlexStratify - The DAG for most topologies is a graded poset (https://en.wikipedia.org/wiki/Graded_poset), and 38456dd80730SBarry Smith can be illustrated by a Hasse Diagram (https://en.wikipedia.org/wiki/Hasse_diagram). The strata group all points of the 3846552f7358SJed Brown same grade, and this function calculates the strata. This grade can be seen as the height (or depth) of the point in 3847552f7358SJed Brown the DAG. 3848552f7358SJed Brown 3849bf4602e4SToby Isaac Collective on dm 3850552f7358SJed Brown 3851552f7358SJed Brown Input Parameter: 3852552f7358SJed Brown . mesh - The DMPlex 3853552f7358SJed Brown 3854552f7358SJed Brown Output Parameter: 3855552f7358SJed Brown 3856552f7358SJed Brown Notes: 3857b1bb481bSMatthew Knepley Concretely, DMPlexStratify() creates a new label named "depth" containing the depth in the DAG of each point. For cell-vertex 3858b1bb481bSMatthew 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 3859b1bb481bSMatthew Knepley until cells have depth equal to the dimension of the mesh. The depth label can be accessed through DMPlexGetDepthLabel() or DMPlexGetDepthStratum(), or 3860c58f1c22SToby Isaac manually via DMGetLabel(). The height is defined implicitly by height = maxDimension - depth, and can be accessed 3861150b719bSJed Brown via DMPlexGetHeightStratum(). For example, cells have height 0 and faces have height 1. 3862552f7358SJed Brown 3863b1bb481bSMatthew Knepley The depth of a point is calculated by executing a breadth-first search (BFS) on the DAG. This could produce surprising results 3864b1bb481bSMatthew Knepley if run on a partially interpolated mesh, meaning one that had some edges and faces, but not others. For example, suppose that 3865b1bb481bSMatthew 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 3866b1bb481bSMatthew Knepley to interpolate only that one (e0), so that 3867b1bb481bSMatthew Knepley $ cone(c0) = {e0, v2} 3868b1bb481bSMatthew Knepley $ cone(e0) = {v0, v1} 3869b1bb481bSMatthew Knepley If DMPlexStratify() is run on this mesh, it will give depths 3870b1bb481bSMatthew Knepley $ depth 0 = {v0, v1, v2} 3871b1bb481bSMatthew Knepley $ depth 1 = {e0, c0} 3872b1bb481bSMatthew Knepley where the triangle has been given depth 1, instead of 2, because it is reachable from vertex v2. 3873b1bb481bSMatthew Knepley 3874150b719bSJed Brown DMPlexStratify() should be called after all calls to DMPlexSymmetrize() 3875552f7358SJed Brown 3876552f7358SJed Brown Level: beginner 3877552f7358SJed Brown 3878ba2698f1SMatthew G. Knepley .seealso: DMPlexCreate(), DMPlexSymmetrize(), DMPlexComputeCellTypes() 3879552f7358SJed Brown @*/ 3880552f7358SJed Brown PetscErrorCode DMPlexStratify(DM dm) 3881552f7358SJed Brown { 3882df0420ecSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 3883aa50250dSMatthew G. Knepley DMLabel label; 3884552f7358SJed Brown PetscInt pStart, pEnd, p; 3885552f7358SJed Brown PetscInt numRoots = 0, numLeaves = 0; 3886552f7358SJed Brown PetscErrorCode ierr; 3887552f7358SJed Brown 3888552f7358SJed Brown PetscFunctionBegin; 3889552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3890552f7358SJed Brown ierr = PetscLogEventBegin(DMPLEX_Stratify,dm,0,0,0);CHKERRQ(ierr); 3891277ea44aSLisandro Dalcin 3892277ea44aSLisandro Dalcin /* Create depth label */ 3893aa50250dSMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 3894c58f1c22SToby Isaac ierr = DMCreateLabel(dm, "depth");CHKERRQ(ierr); 3895aa50250dSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 3896277ea44aSLisandro Dalcin 3897277ea44aSLisandro Dalcin { 3898552f7358SJed Brown /* Initialize roots and count leaves */ 3899277ea44aSLisandro Dalcin PetscInt sMin = PETSC_MAX_INT; 3900277ea44aSLisandro Dalcin PetscInt sMax = PETSC_MIN_INT; 3901552f7358SJed Brown PetscInt coneSize, supportSize; 3902552f7358SJed Brown 3903277ea44aSLisandro Dalcin for (p = pStart; p < pEnd; ++p) { 3904552f7358SJed Brown ierr = DMPlexGetConeSize(dm, p, &coneSize);CHKERRQ(ierr); 3905552f7358SJed Brown ierr = DMPlexGetSupportSize(dm, p, &supportSize);CHKERRQ(ierr); 3906552f7358SJed Brown if (!coneSize && supportSize) { 3907277ea44aSLisandro Dalcin sMin = PetscMin(p, sMin); 3908277ea44aSLisandro Dalcin sMax = PetscMax(p, sMax); 3909552f7358SJed Brown ++numRoots; 3910552f7358SJed Brown } else if (!supportSize && coneSize) { 3911552f7358SJed Brown ++numLeaves; 3912552f7358SJed Brown } else if (!supportSize && !coneSize) { 3913552f7358SJed Brown /* Isolated points */ 3914277ea44aSLisandro Dalcin sMin = PetscMin(p, sMin); 3915277ea44aSLisandro Dalcin sMax = PetscMax(p, sMax); 3916552f7358SJed Brown } 3917552f7358SJed Brown } 3918277ea44aSLisandro Dalcin ierr = DMPlexCreateDepthStratum(dm, label, 0, sMin, sMax+1);CHKERRQ(ierr); 3919277ea44aSLisandro Dalcin } 3920277ea44aSLisandro Dalcin 3921552f7358SJed Brown if (numRoots + numLeaves == (pEnd - pStart)) { 3922277ea44aSLisandro Dalcin PetscInt sMin = PETSC_MAX_INT; 3923277ea44aSLisandro Dalcin PetscInt sMax = PETSC_MIN_INT; 3924552f7358SJed Brown PetscInt coneSize, supportSize; 3925552f7358SJed Brown 3926277ea44aSLisandro Dalcin for (p = pStart; p < pEnd; ++p) { 3927552f7358SJed Brown ierr = DMPlexGetConeSize(dm, p, &coneSize);CHKERRQ(ierr); 3928552f7358SJed Brown ierr = DMPlexGetSupportSize(dm, p, &supportSize);CHKERRQ(ierr); 3929552f7358SJed Brown if (!supportSize && coneSize) { 3930277ea44aSLisandro Dalcin sMin = PetscMin(p, sMin); 3931277ea44aSLisandro Dalcin sMax = PetscMax(p, sMax); 3932552f7358SJed Brown } 3933552f7358SJed Brown } 3934277ea44aSLisandro Dalcin ierr = DMPlexCreateDepthStratum(dm, label, 1, sMin, sMax+1);CHKERRQ(ierr); 3935552f7358SJed Brown } else { 3936277ea44aSLisandro Dalcin PetscInt level = 0; 3937277ea44aSLisandro Dalcin PetscInt qStart, qEnd, q; 3938552f7358SJed Brown 3939277ea44aSLisandro Dalcin ierr = DMLabelGetStratumBounds(label, level, &qStart, &qEnd);CHKERRQ(ierr); 3940277ea44aSLisandro Dalcin while (qEnd > qStart) { 3941277ea44aSLisandro Dalcin PetscInt sMin = PETSC_MAX_INT; 3942277ea44aSLisandro Dalcin PetscInt sMax = PETSC_MIN_INT; 394374ef644bSMatthew G. Knepley 3944277ea44aSLisandro Dalcin for (q = qStart; q < qEnd; ++q) { 394574ef644bSMatthew G. Knepley const PetscInt *support; 394674ef644bSMatthew G. Knepley PetscInt supportSize, s; 394774ef644bSMatthew G. Knepley 3948277ea44aSLisandro Dalcin ierr = DMPlexGetSupportSize(dm, q, &supportSize);CHKERRQ(ierr); 3949277ea44aSLisandro Dalcin ierr = DMPlexGetSupport(dm, q, &support);CHKERRQ(ierr); 395074ef644bSMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 3951277ea44aSLisandro Dalcin sMin = PetscMin(support[s], sMin); 3952277ea44aSLisandro Dalcin sMax = PetscMax(support[s], sMax); 3953552f7358SJed Brown } 3954552f7358SJed Brown } 3955277ea44aSLisandro Dalcin ierr = DMLabelGetNumValues(label, &level);CHKERRQ(ierr); 3956277ea44aSLisandro Dalcin ierr = DMPlexCreateDepthStratum(dm, label, level, sMin, sMax+1);CHKERRQ(ierr); 3957277ea44aSLisandro Dalcin ierr = DMLabelGetStratumBounds(label, level, &qStart, &qEnd);CHKERRQ(ierr); 395874ef644bSMatthew G. Knepley } 395974ef644bSMatthew G. Knepley } 3960bf4602e4SToby Isaac { /* just in case there is an empty process */ 3961bf4602e4SToby Isaac PetscInt numValues, maxValues = 0, v; 3962bf4602e4SToby Isaac 3963bf4602e4SToby Isaac ierr = DMLabelGetNumValues(label, &numValues);CHKERRQ(ierr); 3964ffc4695bSBarry Smith ierr = MPI_Allreduce(&numValues,&maxValues,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)dm));CHKERRMPI(ierr); 3965bf4602e4SToby Isaac for (v = numValues; v < maxValues; v++) { 3966367003a6SStefano Zampini ierr = DMLabelAddStratum(label, v);CHKERRQ(ierr); 3967bf4602e4SToby Isaac } 3968bf4602e4SToby Isaac } 3969d67d17b1SMatthew G. Knepley ierr = PetscObjectStateGet((PetscObject) label, &mesh->depthState);CHKERRQ(ierr); 3970552f7358SJed Brown ierr = PetscLogEventEnd(DMPLEX_Stratify,dm,0,0,0);CHKERRQ(ierr); 3971552f7358SJed Brown PetscFunctionReturn(0); 3972552f7358SJed Brown } 3973552f7358SJed Brown 3974412e9a14SMatthew G. Knepley PetscErrorCode DMPlexComputeCellType_Internal(DM dm, PetscInt p, PetscInt pdepth, DMPolytopeType *pt) 3975ba2698f1SMatthew G. Knepley { 3976412e9a14SMatthew G. Knepley DMPolytopeType ct = DM_POLYTOPE_UNKNOWN; 3977412e9a14SMatthew G. Knepley PetscInt dim, depth, pheight, coneSize; 3978ba2698f1SMatthew G. Knepley PetscErrorCode ierr; 3979ba2698f1SMatthew G. Knepley 3980412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 3981ba2698f1SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 3982ba2698f1SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 3983ba2698f1SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, p, &coneSize);CHKERRQ(ierr); 3984ba2698f1SMatthew G. Knepley pheight = depth - pdepth; 3985ba2698f1SMatthew G. Knepley if (depth <= 1) { 3986ba2698f1SMatthew G. Knepley switch (pdepth) { 3987ba2698f1SMatthew G. Knepley case 0: ct = DM_POLYTOPE_POINT;break; 3988ba2698f1SMatthew G. Knepley case 1: 3989ba2698f1SMatthew G. Knepley switch (coneSize) { 3990ba2698f1SMatthew G. Knepley case 2: ct = DM_POLYTOPE_SEGMENT;break; 3991ba2698f1SMatthew G. Knepley case 3: ct = DM_POLYTOPE_TRIANGLE;break; 3992ba2698f1SMatthew G. Knepley case 4: 3993ba2698f1SMatthew G. Knepley switch (dim) { 3994ba2698f1SMatthew G. Knepley case 2: ct = DM_POLYTOPE_QUADRILATERAL;break; 3995ba2698f1SMatthew G. Knepley case 3: ct = DM_POLYTOPE_TETRAHEDRON;break; 3996ba2698f1SMatthew G. Knepley default: break; 3997ba2698f1SMatthew G. Knepley } 3998ba2698f1SMatthew G. Knepley break; 3999da9060c4SMatthew G. Knepley case 5: ct = DM_POLYTOPE_PYRAMID;break; 4000ba2698f1SMatthew G. Knepley case 6: ct = DM_POLYTOPE_TRI_PRISM_TENSOR;break; 4001ba2698f1SMatthew G. Knepley case 8: ct = DM_POLYTOPE_HEXAHEDRON;break; 4002ba2698f1SMatthew G. Knepley default: break; 4003ba2698f1SMatthew G. Knepley } 4004ba2698f1SMatthew G. Knepley } 4005ba2698f1SMatthew G. Knepley } else { 4006ba2698f1SMatthew G. Knepley if (pdepth == 0) { 4007ba2698f1SMatthew G. Knepley ct = DM_POLYTOPE_POINT; 4008ba2698f1SMatthew G. Knepley } else if (pheight == 0) { 4009ba2698f1SMatthew G. Knepley switch (dim) { 4010ba2698f1SMatthew G. Knepley case 1: 4011ba2698f1SMatthew G. Knepley switch (coneSize) { 4012ba2698f1SMatthew G. Knepley case 2: ct = DM_POLYTOPE_SEGMENT;break; 4013ba2698f1SMatthew G. Knepley default: break; 4014ba2698f1SMatthew G. Knepley } 4015ba2698f1SMatthew G. Knepley break; 4016ba2698f1SMatthew G. Knepley case 2: 4017ba2698f1SMatthew G. Knepley switch (coneSize) { 4018ba2698f1SMatthew G. Knepley case 3: ct = DM_POLYTOPE_TRIANGLE;break; 4019ba2698f1SMatthew G. Knepley case 4: ct = DM_POLYTOPE_QUADRILATERAL;break; 4020ba2698f1SMatthew G. Knepley default: break; 4021ba2698f1SMatthew G. Knepley } 4022ba2698f1SMatthew G. Knepley break; 4023ba2698f1SMatthew G. Knepley case 3: 4024ba2698f1SMatthew G. Knepley switch (coneSize) { 4025ba2698f1SMatthew G. Knepley case 4: ct = DM_POLYTOPE_TETRAHEDRON;break; 4026da9060c4SMatthew G. Knepley case 5: 4027da9060c4SMatthew G. Knepley { 4028da9060c4SMatthew G. Knepley const PetscInt *cone; 4029da9060c4SMatthew G. Knepley PetscInt faceConeSize; 4030da9060c4SMatthew G. Knepley 4031da9060c4SMatthew G. Knepley ierr = DMPlexGetCone(dm, p, &cone);CHKERRQ(ierr); 4032da9060c4SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, cone[0], &faceConeSize);CHKERRQ(ierr); 4033da9060c4SMatthew G. Knepley switch (faceConeSize) { 4034da9060c4SMatthew G. Knepley case 3: ct = DM_POLYTOPE_TRI_PRISM_TENSOR;break; 4035da9060c4SMatthew G. Knepley case 4: ct = DM_POLYTOPE_PYRAMID;break; 4036da9060c4SMatthew G. Knepley } 4037da9060c4SMatthew G. Knepley } 4038da9060c4SMatthew G. Knepley break; 4039ba2698f1SMatthew G. Knepley case 6: ct = DM_POLYTOPE_HEXAHEDRON;break; 4040ba2698f1SMatthew G. Knepley default: break; 4041ba2698f1SMatthew G. Knepley } 4042ba2698f1SMatthew G. Knepley break; 4043ba2698f1SMatthew G. Knepley default: break; 4044ba2698f1SMatthew G. Knepley } 4045ba2698f1SMatthew G. Knepley } else if (pheight > 0) { 4046ba2698f1SMatthew G. Knepley switch (coneSize) { 4047ba2698f1SMatthew G. Knepley case 2: ct = DM_POLYTOPE_SEGMENT;break; 4048ba2698f1SMatthew G. Knepley case 3: ct = DM_POLYTOPE_TRIANGLE;break; 4049ba2698f1SMatthew G. Knepley case 4: ct = DM_POLYTOPE_QUADRILATERAL;break; 4050ba2698f1SMatthew G. Knepley default: break; 4051ba2698f1SMatthew G. Knepley } 4052ba2698f1SMatthew G. Knepley } 4053ba2698f1SMatthew G. Knepley } 4054412e9a14SMatthew G. Knepley *pt = ct; 4055412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 4056ba2698f1SMatthew G. Knepley } 4057412e9a14SMatthew G. Knepley 4058412e9a14SMatthew G. Knepley /*@ 4059412e9a14SMatthew G. Knepley DMPlexComputeCellTypes - Infer the polytope type of every cell using its dimension and cone size. 4060412e9a14SMatthew G. Knepley 4061412e9a14SMatthew G. Knepley Collective on dm 4062412e9a14SMatthew G. Knepley 4063412e9a14SMatthew G. Knepley Input Parameter: 4064412e9a14SMatthew G. Knepley . mesh - The DMPlex 4065412e9a14SMatthew G. Knepley 4066412e9a14SMatthew G. Knepley DMPlexComputeCellTypes() should be called after all calls to DMPlexSymmetrize() and DMPlexStratify() 4067412e9a14SMatthew G. Knepley 4068412e9a14SMatthew G. Knepley Level: developer 4069412e9a14SMatthew G. Knepley 4070412e9a14SMatthew G. Knepley Note: This function is normally called automatically by Plex when a cell type is requested. It creates an 4071412e9a14SMatthew G. Knepley internal DMLabel named "celltype" which can be directly accessed using DMGetLabel(). A user may disable 4072412e9a14SMatthew G. Knepley automatic creation by creating the label manually, using DMCreateLabel(dm, "celltype"). 4073412e9a14SMatthew G. Knepley 4074412e9a14SMatthew G. Knepley .seealso: DMPlexCreate(), DMPlexSymmetrize(), DMPlexStratify(), DMGetLabel(), DMCreateLabel() 4075412e9a14SMatthew G. Knepley @*/ 4076412e9a14SMatthew G. Knepley PetscErrorCode DMPlexComputeCellTypes(DM dm) 4077412e9a14SMatthew G. Knepley { 4078412e9a14SMatthew G. Knepley DM_Plex *mesh; 4079412e9a14SMatthew G. Knepley DMLabel ctLabel; 4080412e9a14SMatthew G. Knepley PetscInt pStart, pEnd, p; 4081412e9a14SMatthew G. Knepley PetscErrorCode ierr; 4082412e9a14SMatthew G. Knepley 4083412e9a14SMatthew G. Knepley PetscFunctionBegin; 4084412e9a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4085412e9a14SMatthew G. Knepley mesh = (DM_Plex *) dm->data; 4086412e9a14SMatthew G. Knepley ierr = DMCreateLabel(dm, "celltype");CHKERRQ(ierr); 4087412e9a14SMatthew G. Knepley ierr = DMPlexGetCellTypeLabel(dm, &ctLabel);CHKERRQ(ierr); 4088412e9a14SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 4089412e9a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 4090327c2912SStefano Zampini DMPolytopeType ct = DM_POLYTOPE_UNKNOWN; 4091412e9a14SMatthew G. Knepley PetscInt pdepth; 4092412e9a14SMatthew G. Knepley 4093412e9a14SMatthew G. Knepley ierr = DMPlexGetPointDepth(dm, p, &pdepth);CHKERRQ(ierr); 4094412e9a14SMatthew G. Knepley ierr = DMPlexComputeCellType_Internal(dm, p, pdepth, &ct);CHKERRQ(ierr); 40952c71b3e2SJacob Faibussowitsch PetscCheckFalse(ct == DM_POLYTOPE_UNKNOWN,PETSC_COMM_SELF, PETSC_ERR_SUP, "Point %D is screwed up", p); 4096412e9a14SMatthew G. Knepley ierr = DMLabelSetValue(ctLabel, p, ct);CHKERRQ(ierr); 4097412e9a14SMatthew G. Knepley } 4098412e9a14SMatthew G. Knepley ierr = PetscObjectStateGet((PetscObject) ctLabel, &mesh->celltypeState);CHKERRQ(ierr); 4099412e9a14SMatthew G. Knepley ierr = PetscObjectViewFromOptions((PetscObject) ctLabel, NULL, "-dm_plex_celltypes_view");CHKERRQ(ierr); 4100ba2698f1SMatthew G. Knepley PetscFunctionReturn(0); 4101ba2698f1SMatthew G. Knepley } 4102ba2698f1SMatthew G. Knepley 4103552f7358SJed Brown /*@C 4104552f7358SJed Brown DMPlexGetJoin - Get an array for the join of the set of points 4105552f7358SJed Brown 4106552f7358SJed Brown Not Collective 4107552f7358SJed Brown 4108552f7358SJed Brown Input Parameters: 4109552f7358SJed Brown + dm - The DMPlex object 4110552f7358SJed Brown . numPoints - The number of input points for the join 4111552f7358SJed Brown - points - The input points 4112552f7358SJed Brown 4113552f7358SJed Brown Output Parameters: 4114552f7358SJed Brown + numCoveredPoints - The number of points in the join 4115552f7358SJed Brown - coveredPoints - The points in the join 4116552f7358SJed Brown 4117552f7358SJed Brown Level: intermediate 4118552f7358SJed Brown 4119552f7358SJed Brown Note: Currently, this is restricted to a single level join 4120552f7358SJed Brown 41213813dfbdSMatthew G Knepley Fortran Notes: 41223813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 41233813dfbdSMatthew G Knepley include petsc.h90 in your code. 41243813dfbdSMatthew G Knepley 41253813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 41263813dfbdSMatthew G Knepley 4127552f7358SJed Brown .seealso: DMPlexRestoreJoin(), DMPlexGetMeet() 4128552f7358SJed Brown @*/ 4129552f7358SJed Brown PetscErrorCode DMPlexGetJoin(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 4130552f7358SJed Brown { 4131552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 4132552f7358SJed Brown PetscInt *join[2]; 4133552f7358SJed Brown PetscInt joinSize, i = 0; 4134552f7358SJed Brown PetscInt dof, off, p, c, m; 4135552f7358SJed Brown PetscErrorCode ierr; 4136552f7358SJed Brown 4137552f7358SJed Brown PetscFunctionBegin; 4138552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 413948bb261cSVaclav Hapla PetscValidIntPointer(points, 3); 414048bb261cSVaclav Hapla PetscValidIntPointer(numCoveredPoints, 4); 414148bb261cSVaclav Hapla PetscValidPointer(coveredPoints, 5); 414269291d52SBarry Smith ierr = DMGetWorkArray(dm, mesh->maxSupportSize, MPIU_INT, &join[0]);CHKERRQ(ierr); 414369291d52SBarry Smith ierr = DMGetWorkArray(dm, mesh->maxSupportSize, MPIU_INT, &join[1]);CHKERRQ(ierr); 4144552f7358SJed Brown /* Copy in support of first point */ 4145552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, points[0], &dof);CHKERRQ(ierr); 4146552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, points[0], &off);CHKERRQ(ierr); 4147552f7358SJed Brown for (joinSize = 0; joinSize < dof; ++joinSize) { 4148552f7358SJed Brown join[i][joinSize] = mesh->supports[off+joinSize]; 4149552f7358SJed Brown } 4150552f7358SJed Brown /* Check each successive support */ 4151552f7358SJed Brown for (p = 1; p < numPoints; ++p) { 4152552f7358SJed Brown PetscInt newJoinSize = 0; 4153552f7358SJed Brown 4154552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, points[p], &dof);CHKERRQ(ierr); 4155552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, points[p], &off);CHKERRQ(ierr); 4156552f7358SJed Brown for (c = 0; c < dof; ++c) { 4157552f7358SJed Brown const PetscInt point = mesh->supports[off+c]; 4158552f7358SJed Brown 4159552f7358SJed Brown for (m = 0; m < joinSize; ++m) { 4160552f7358SJed Brown if (point == join[i][m]) { 4161552f7358SJed Brown join[1-i][newJoinSize++] = point; 4162552f7358SJed Brown break; 4163552f7358SJed Brown } 4164552f7358SJed Brown } 4165552f7358SJed Brown } 4166552f7358SJed Brown joinSize = newJoinSize; 4167552f7358SJed Brown i = 1-i; 4168552f7358SJed Brown } 4169552f7358SJed Brown *numCoveredPoints = joinSize; 4170552f7358SJed Brown *coveredPoints = join[i]; 417169291d52SBarry Smith ierr = DMRestoreWorkArray(dm, mesh->maxSupportSize, MPIU_INT, &join[1-i]);CHKERRQ(ierr); 4172552f7358SJed Brown PetscFunctionReturn(0); 4173552f7358SJed Brown } 4174552f7358SJed Brown 4175552f7358SJed Brown /*@C 4176552f7358SJed Brown DMPlexRestoreJoin - Restore an array for the join of the set of points 4177552f7358SJed Brown 4178552f7358SJed Brown Not Collective 4179552f7358SJed Brown 4180552f7358SJed Brown Input Parameters: 4181552f7358SJed Brown + dm - The DMPlex object 4182552f7358SJed Brown . numPoints - The number of input points for the join 4183552f7358SJed Brown - points - The input points 4184552f7358SJed Brown 4185552f7358SJed Brown Output Parameters: 4186552f7358SJed Brown + numCoveredPoints - The number of points in the join 4187552f7358SJed Brown - coveredPoints - The points in the join 4188552f7358SJed Brown 41893813dfbdSMatthew G Knepley Fortran Notes: 41903813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 41913813dfbdSMatthew G Knepley include petsc.h90 in your code. 41923813dfbdSMatthew G Knepley 41933813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 41943813dfbdSMatthew G Knepley 4195552f7358SJed Brown Level: intermediate 4196552f7358SJed Brown 4197552f7358SJed Brown .seealso: DMPlexGetJoin(), DMPlexGetFullJoin(), DMPlexGetMeet() 4198552f7358SJed Brown @*/ 4199552f7358SJed Brown PetscErrorCode DMPlexRestoreJoin(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 4200552f7358SJed Brown { 4201552f7358SJed Brown PetscErrorCode ierr; 4202552f7358SJed Brown 4203552f7358SJed Brown PetscFunctionBegin; 4204552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4205d7902bd2SMatthew G. Knepley if (points) PetscValidIntPointer(points,3); 4206d7902bd2SMatthew G. Knepley if (numCoveredPoints) PetscValidIntPointer(numCoveredPoints,4); 4207d7902bd2SMatthew G. Knepley PetscValidPointer(coveredPoints, 5); 420869291d52SBarry Smith ierr = DMRestoreWorkArray(dm, 0, MPIU_INT, (void*) coveredPoints);CHKERRQ(ierr); 4209d7902bd2SMatthew G. Knepley if (numCoveredPoints) *numCoveredPoints = 0; 4210552f7358SJed Brown PetscFunctionReturn(0); 4211552f7358SJed Brown } 4212552f7358SJed Brown 4213552f7358SJed Brown /*@C 4214552f7358SJed Brown DMPlexGetFullJoin - Get an array for the join of the set of points 4215552f7358SJed Brown 4216552f7358SJed Brown Not Collective 4217552f7358SJed Brown 4218552f7358SJed Brown Input Parameters: 4219552f7358SJed Brown + dm - The DMPlex object 4220552f7358SJed Brown . numPoints - The number of input points for the join 4221552f7358SJed Brown - points - The input points 4222552f7358SJed Brown 4223552f7358SJed Brown Output Parameters: 4224552f7358SJed Brown + numCoveredPoints - The number of points in the join 4225552f7358SJed Brown - coveredPoints - The points in the join 4226552f7358SJed Brown 42273813dfbdSMatthew G Knepley Fortran Notes: 42283813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 42293813dfbdSMatthew G Knepley include petsc.h90 in your code. 42303813dfbdSMatthew G Knepley 42313813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 42323813dfbdSMatthew G Knepley 4233552f7358SJed Brown Level: intermediate 4234552f7358SJed Brown 4235552f7358SJed Brown .seealso: DMPlexGetJoin(), DMPlexRestoreJoin(), DMPlexGetMeet() 4236552f7358SJed Brown @*/ 4237552f7358SJed Brown PetscErrorCode DMPlexGetFullJoin(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 4238552f7358SJed Brown { 4239552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 4240552f7358SJed Brown PetscInt *offsets, **closures; 4241552f7358SJed Brown PetscInt *join[2]; 4242552f7358SJed Brown PetscInt depth = 0, maxSize, joinSize = 0, i = 0; 424324c766afSToby Isaac PetscInt p, d, c, m, ms; 4244552f7358SJed Brown PetscErrorCode ierr; 4245552f7358SJed Brown 4246552f7358SJed Brown PetscFunctionBegin; 4247552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 424848bb261cSVaclav Hapla PetscValidIntPointer(points, 3); 424948bb261cSVaclav Hapla PetscValidIntPointer(numCoveredPoints, 4); 425048bb261cSVaclav Hapla PetscValidPointer(coveredPoints, 5); 4251552f7358SJed Brown 4252552f7358SJed Brown ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 42531795a4d1SJed Brown ierr = PetscCalloc1(numPoints, &closures);CHKERRQ(ierr); 425469291d52SBarry Smith ierr = DMGetWorkArray(dm, numPoints*(depth+2), MPIU_INT, &offsets);CHKERRQ(ierr); 425524c766afSToby Isaac ms = mesh->maxSupportSize; 425624c766afSToby Isaac maxSize = (ms > 1) ? ((PetscPowInt(ms,depth+1)-1)/(ms-1)) : depth + 1; 425769291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &join[0]);CHKERRQ(ierr); 425869291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &join[1]);CHKERRQ(ierr); 4259552f7358SJed Brown 4260552f7358SJed Brown for (p = 0; p < numPoints; ++p) { 4261552f7358SJed Brown PetscInt closureSize; 4262552f7358SJed Brown 4263552f7358SJed Brown ierr = DMPlexGetTransitiveClosure(dm, points[p], PETSC_FALSE, &closureSize, &closures[p]);CHKERRQ(ierr); 42640d644c17SKarl Rupp 4265552f7358SJed Brown offsets[p*(depth+2)+0] = 0; 4266552f7358SJed Brown for (d = 0; d < depth+1; ++d) { 4267552f7358SJed Brown PetscInt pStart, pEnd, i; 4268552f7358SJed Brown 4269552f7358SJed Brown ierr = DMPlexGetDepthStratum(dm, d, &pStart, &pEnd);CHKERRQ(ierr); 4270552f7358SJed Brown for (i = offsets[p*(depth+2)+d]; i < closureSize; ++i) { 4271552f7358SJed Brown if ((pStart > closures[p][i*2]) || (pEnd <= closures[p][i*2])) { 4272552f7358SJed Brown offsets[p*(depth+2)+d+1] = i; 4273552f7358SJed Brown break; 4274552f7358SJed Brown } 4275552f7358SJed Brown } 4276552f7358SJed Brown if (i == closureSize) offsets[p*(depth+2)+d+1] = i; 4277552f7358SJed Brown } 42782c71b3e2SJacob Faibussowitsch PetscCheckFalse(offsets[p*(depth+2)+depth+1] != closureSize,PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Total size of closure %D should be %D", offsets[p*(depth+2)+depth+1], closureSize); 4279552f7358SJed Brown } 4280552f7358SJed Brown for (d = 0; d < depth+1; ++d) { 4281552f7358SJed Brown PetscInt dof; 4282552f7358SJed Brown 4283552f7358SJed Brown /* Copy in support of first point */ 4284552f7358SJed Brown dof = offsets[d+1] - offsets[d]; 4285552f7358SJed Brown for (joinSize = 0; joinSize < dof; ++joinSize) { 4286552f7358SJed Brown join[i][joinSize] = closures[0][(offsets[d]+joinSize)*2]; 4287552f7358SJed Brown } 4288552f7358SJed Brown /* Check each successive cone */ 4289552f7358SJed Brown for (p = 1; p < numPoints && joinSize; ++p) { 4290552f7358SJed Brown PetscInt newJoinSize = 0; 4291552f7358SJed Brown 4292552f7358SJed Brown dof = offsets[p*(depth+2)+d+1] - offsets[p*(depth+2)+d]; 4293552f7358SJed Brown for (c = 0; c < dof; ++c) { 4294552f7358SJed Brown const PetscInt point = closures[p][(offsets[p*(depth+2)+d]+c)*2]; 4295552f7358SJed Brown 4296552f7358SJed Brown for (m = 0; m < joinSize; ++m) { 4297552f7358SJed Brown if (point == join[i][m]) { 4298552f7358SJed Brown join[1-i][newJoinSize++] = point; 4299552f7358SJed Brown break; 4300552f7358SJed Brown } 4301552f7358SJed Brown } 4302552f7358SJed Brown } 4303552f7358SJed Brown joinSize = newJoinSize; 4304552f7358SJed Brown i = 1-i; 4305552f7358SJed Brown } 4306552f7358SJed Brown if (joinSize) break; 4307552f7358SJed Brown } 4308552f7358SJed Brown *numCoveredPoints = joinSize; 4309552f7358SJed Brown *coveredPoints = join[i]; 4310552f7358SJed Brown for (p = 0; p < numPoints; ++p) { 43110298fd71SBarry Smith ierr = DMPlexRestoreTransitiveClosure(dm, points[p], PETSC_FALSE, NULL, &closures[p]);CHKERRQ(ierr); 4312552f7358SJed Brown } 4313552f7358SJed Brown ierr = PetscFree(closures);CHKERRQ(ierr); 431469291d52SBarry Smith ierr = DMRestoreWorkArray(dm, numPoints*(depth+2), MPIU_INT, &offsets);CHKERRQ(ierr); 431569291d52SBarry Smith ierr = DMRestoreWorkArray(dm, mesh->maxSupportSize, MPIU_INT, &join[1-i]);CHKERRQ(ierr); 4316552f7358SJed Brown PetscFunctionReturn(0); 4317552f7358SJed Brown } 4318552f7358SJed Brown 4319552f7358SJed Brown /*@C 4320552f7358SJed Brown DMPlexGetMeet - Get an array for the meet of the set of points 4321552f7358SJed Brown 4322552f7358SJed Brown Not Collective 4323552f7358SJed Brown 4324552f7358SJed Brown Input Parameters: 4325552f7358SJed Brown + dm - The DMPlex object 4326552f7358SJed Brown . numPoints - The number of input points for the meet 4327552f7358SJed Brown - points - The input points 4328552f7358SJed Brown 4329552f7358SJed Brown Output Parameters: 4330552f7358SJed Brown + numCoveredPoints - The number of points in the meet 4331552f7358SJed Brown - coveredPoints - The points in the meet 4332552f7358SJed Brown 4333552f7358SJed Brown Level: intermediate 4334552f7358SJed Brown 4335552f7358SJed Brown Note: Currently, this is restricted to a single level meet 4336552f7358SJed Brown 43373813dfbdSMatthew G Knepley Fortran Notes: 43383813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 43393813dfbdSMatthew G Knepley include petsc.h90 in your code. 43403813dfbdSMatthew G Knepley 43413813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 43423813dfbdSMatthew G Knepley 4343552f7358SJed Brown .seealso: DMPlexRestoreMeet(), DMPlexGetJoin() 4344552f7358SJed Brown @*/ 4345552f7358SJed Brown PetscErrorCode DMPlexGetMeet(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveringPoints, const PetscInt **coveringPoints) 4346552f7358SJed Brown { 4347552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 4348552f7358SJed Brown PetscInt *meet[2]; 4349552f7358SJed Brown PetscInt meetSize, i = 0; 4350552f7358SJed Brown PetscInt dof, off, p, c, m; 4351552f7358SJed Brown PetscErrorCode ierr; 4352552f7358SJed Brown 4353552f7358SJed Brown PetscFunctionBegin; 4354552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4355064a246eSJacob Faibussowitsch PetscValidPointer(points, 3); 4356064a246eSJacob Faibussowitsch PetscValidPointer(numCoveringPoints, 4); 4357064a246eSJacob Faibussowitsch PetscValidPointer(coveringPoints, 5); 435869291d52SBarry Smith ierr = DMGetWorkArray(dm, mesh->maxConeSize, MPIU_INT, &meet[0]);CHKERRQ(ierr); 435969291d52SBarry Smith ierr = DMGetWorkArray(dm, mesh->maxConeSize, MPIU_INT, &meet[1]);CHKERRQ(ierr); 4360552f7358SJed Brown /* Copy in cone of first point */ 4361552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, points[0], &dof);CHKERRQ(ierr); 4362552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, points[0], &off);CHKERRQ(ierr); 4363552f7358SJed Brown for (meetSize = 0; meetSize < dof; ++meetSize) { 4364552f7358SJed Brown meet[i][meetSize] = mesh->cones[off+meetSize]; 4365552f7358SJed Brown } 4366552f7358SJed Brown /* Check each successive cone */ 4367552f7358SJed Brown for (p = 1; p < numPoints; ++p) { 4368552f7358SJed Brown PetscInt newMeetSize = 0; 4369552f7358SJed Brown 4370552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, points[p], &dof);CHKERRQ(ierr); 4371552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, points[p], &off);CHKERRQ(ierr); 4372552f7358SJed Brown for (c = 0; c < dof; ++c) { 4373552f7358SJed Brown const PetscInt point = mesh->cones[off+c]; 4374552f7358SJed Brown 4375552f7358SJed Brown for (m = 0; m < meetSize; ++m) { 4376552f7358SJed Brown if (point == meet[i][m]) { 4377552f7358SJed Brown meet[1-i][newMeetSize++] = point; 4378552f7358SJed Brown break; 4379552f7358SJed Brown } 4380552f7358SJed Brown } 4381552f7358SJed Brown } 4382552f7358SJed Brown meetSize = newMeetSize; 4383552f7358SJed Brown i = 1-i; 4384552f7358SJed Brown } 4385552f7358SJed Brown *numCoveringPoints = meetSize; 4386552f7358SJed Brown *coveringPoints = meet[i]; 438769291d52SBarry Smith ierr = DMRestoreWorkArray(dm, mesh->maxConeSize, MPIU_INT, &meet[1-i]);CHKERRQ(ierr); 4388552f7358SJed Brown PetscFunctionReturn(0); 4389552f7358SJed Brown } 4390552f7358SJed Brown 4391552f7358SJed Brown /*@C 4392552f7358SJed Brown DMPlexRestoreMeet - Restore an array for the meet of the set of points 4393552f7358SJed Brown 4394552f7358SJed Brown Not Collective 4395552f7358SJed Brown 4396552f7358SJed Brown Input Parameters: 4397552f7358SJed Brown + dm - The DMPlex object 4398552f7358SJed Brown . numPoints - The number of input points for the meet 4399552f7358SJed Brown - points - The input points 4400552f7358SJed Brown 4401552f7358SJed Brown Output Parameters: 4402552f7358SJed Brown + numCoveredPoints - The number of points in the meet 4403552f7358SJed Brown - coveredPoints - The points in the meet 4404552f7358SJed Brown 4405552f7358SJed Brown Level: intermediate 4406552f7358SJed Brown 44073813dfbdSMatthew G Knepley Fortran Notes: 44083813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 44093813dfbdSMatthew G Knepley include petsc.h90 in your code. 44103813dfbdSMatthew G Knepley 44113813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 44123813dfbdSMatthew G Knepley 4413552f7358SJed Brown .seealso: DMPlexGetMeet(), DMPlexGetFullMeet(), DMPlexGetJoin() 4414552f7358SJed Brown @*/ 4415552f7358SJed Brown PetscErrorCode DMPlexRestoreMeet(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 4416552f7358SJed Brown { 4417552f7358SJed Brown PetscErrorCode ierr; 4418552f7358SJed Brown 4419552f7358SJed Brown PetscFunctionBegin; 4420552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4421d7902bd2SMatthew G. Knepley if (points) PetscValidIntPointer(points,3); 4422d7902bd2SMatthew G. Knepley if (numCoveredPoints) PetscValidIntPointer(numCoveredPoints,4); 4423d7902bd2SMatthew G. Knepley PetscValidPointer(coveredPoints,5); 442469291d52SBarry Smith ierr = DMRestoreWorkArray(dm, 0, MPIU_INT, (void*) coveredPoints);CHKERRQ(ierr); 4425d7902bd2SMatthew G. Knepley if (numCoveredPoints) *numCoveredPoints = 0; 4426552f7358SJed Brown PetscFunctionReturn(0); 4427552f7358SJed Brown } 4428552f7358SJed Brown 4429552f7358SJed Brown /*@C 4430552f7358SJed Brown DMPlexGetFullMeet - Get an array for the meet of the set of points 4431552f7358SJed Brown 4432552f7358SJed Brown Not Collective 4433552f7358SJed Brown 4434552f7358SJed Brown Input Parameters: 4435552f7358SJed Brown + dm - The DMPlex object 4436552f7358SJed Brown . numPoints - The number of input points for the meet 4437552f7358SJed Brown - points - The input points 4438552f7358SJed Brown 4439552f7358SJed Brown Output Parameters: 4440552f7358SJed Brown + numCoveredPoints - The number of points in the meet 4441552f7358SJed Brown - coveredPoints - The points in the meet 4442552f7358SJed Brown 4443552f7358SJed Brown Level: intermediate 4444552f7358SJed Brown 44453813dfbdSMatthew G Knepley Fortran Notes: 44463813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 44473813dfbdSMatthew G Knepley include petsc.h90 in your code. 44483813dfbdSMatthew G Knepley 44493813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 44503813dfbdSMatthew G Knepley 4451552f7358SJed Brown .seealso: DMPlexGetMeet(), DMPlexRestoreMeet(), DMPlexGetJoin() 4452552f7358SJed Brown @*/ 4453552f7358SJed Brown PetscErrorCode DMPlexGetFullMeet(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 4454552f7358SJed Brown { 4455552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 4456552f7358SJed Brown PetscInt *offsets, **closures; 4457552f7358SJed Brown PetscInt *meet[2]; 4458552f7358SJed Brown PetscInt height = 0, maxSize, meetSize = 0, i = 0; 445924c766afSToby Isaac PetscInt p, h, c, m, mc; 4460552f7358SJed Brown PetscErrorCode ierr; 4461552f7358SJed Brown 4462552f7358SJed Brown PetscFunctionBegin; 4463552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4464064a246eSJacob Faibussowitsch PetscValidPointer(points, 3); 4465064a246eSJacob Faibussowitsch PetscValidPointer(numCoveredPoints, 4); 4466064a246eSJacob Faibussowitsch PetscValidPointer(coveredPoints, 5); 4467552f7358SJed Brown 4468552f7358SJed Brown ierr = DMPlexGetDepth(dm, &height);CHKERRQ(ierr); 4469785e854fSJed Brown ierr = PetscMalloc1(numPoints, &closures);CHKERRQ(ierr); 447069291d52SBarry Smith ierr = DMGetWorkArray(dm, numPoints*(height+2), MPIU_INT, &offsets);CHKERRQ(ierr); 447124c766afSToby Isaac mc = mesh->maxConeSize; 447224c766afSToby Isaac maxSize = (mc > 1) ? ((PetscPowInt(mc,height+1)-1)/(mc-1)) : height + 1; 447369291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &meet[0]);CHKERRQ(ierr); 447469291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &meet[1]);CHKERRQ(ierr); 4475552f7358SJed Brown 4476552f7358SJed Brown for (p = 0; p < numPoints; ++p) { 4477552f7358SJed Brown PetscInt closureSize; 4478552f7358SJed Brown 4479552f7358SJed Brown ierr = DMPlexGetTransitiveClosure(dm, points[p], PETSC_TRUE, &closureSize, &closures[p]);CHKERRQ(ierr); 44800d644c17SKarl Rupp 4481552f7358SJed Brown offsets[p*(height+2)+0] = 0; 4482552f7358SJed Brown for (h = 0; h < height+1; ++h) { 4483552f7358SJed Brown PetscInt pStart, pEnd, i; 4484552f7358SJed Brown 4485552f7358SJed Brown ierr = DMPlexGetHeightStratum(dm, h, &pStart, &pEnd);CHKERRQ(ierr); 4486552f7358SJed Brown for (i = offsets[p*(height+2)+h]; i < closureSize; ++i) { 4487552f7358SJed Brown if ((pStart > closures[p][i*2]) || (pEnd <= closures[p][i*2])) { 4488552f7358SJed Brown offsets[p*(height+2)+h+1] = i; 4489552f7358SJed Brown break; 4490552f7358SJed Brown } 4491552f7358SJed Brown } 4492552f7358SJed Brown if (i == closureSize) offsets[p*(height+2)+h+1] = i; 4493552f7358SJed Brown } 44942c71b3e2SJacob Faibussowitsch PetscCheckFalse(offsets[p*(height+2)+height+1] != closureSize,PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Total size of closure %D should be %D", offsets[p*(height+2)+height+1], closureSize); 4495552f7358SJed Brown } 4496552f7358SJed Brown for (h = 0; h < height+1; ++h) { 4497552f7358SJed Brown PetscInt dof; 4498552f7358SJed Brown 4499552f7358SJed Brown /* Copy in cone of first point */ 4500552f7358SJed Brown dof = offsets[h+1] - offsets[h]; 4501552f7358SJed Brown for (meetSize = 0; meetSize < dof; ++meetSize) { 4502552f7358SJed Brown meet[i][meetSize] = closures[0][(offsets[h]+meetSize)*2]; 4503552f7358SJed Brown } 4504552f7358SJed Brown /* Check each successive cone */ 4505552f7358SJed Brown for (p = 1; p < numPoints && meetSize; ++p) { 4506552f7358SJed Brown PetscInt newMeetSize = 0; 4507552f7358SJed Brown 4508552f7358SJed Brown dof = offsets[p*(height+2)+h+1] - offsets[p*(height+2)+h]; 4509552f7358SJed Brown for (c = 0; c < dof; ++c) { 4510552f7358SJed Brown const PetscInt point = closures[p][(offsets[p*(height+2)+h]+c)*2]; 4511552f7358SJed Brown 4512552f7358SJed Brown for (m = 0; m < meetSize; ++m) { 4513552f7358SJed Brown if (point == meet[i][m]) { 4514552f7358SJed Brown meet[1-i][newMeetSize++] = point; 4515552f7358SJed Brown break; 4516552f7358SJed Brown } 4517552f7358SJed Brown } 4518552f7358SJed Brown } 4519552f7358SJed Brown meetSize = newMeetSize; 4520552f7358SJed Brown i = 1-i; 4521552f7358SJed Brown } 4522552f7358SJed Brown if (meetSize) break; 4523552f7358SJed Brown } 4524552f7358SJed Brown *numCoveredPoints = meetSize; 4525552f7358SJed Brown *coveredPoints = meet[i]; 4526552f7358SJed Brown for (p = 0; p < numPoints; ++p) { 45270298fd71SBarry Smith ierr = DMPlexRestoreTransitiveClosure(dm, points[p], PETSC_TRUE, NULL, &closures[p]);CHKERRQ(ierr); 4528552f7358SJed Brown } 4529552f7358SJed Brown ierr = PetscFree(closures);CHKERRQ(ierr); 453069291d52SBarry Smith ierr = DMRestoreWorkArray(dm, numPoints*(height+2), MPIU_INT, &offsets);CHKERRQ(ierr); 453169291d52SBarry Smith ierr = DMRestoreWorkArray(dm, mesh->maxConeSize, MPIU_INT, &meet[1-i]);CHKERRQ(ierr); 4532552f7358SJed Brown PetscFunctionReturn(0); 4533552f7358SJed Brown } 4534552f7358SJed Brown 45354e3744c5SMatthew G. Knepley /*@C 45364e3744c5SMatthew G. Knepley DMPlexEqual - Determine if two DMs have the same topology 45374e3744c5SMatthew G. Knepley 45384e3744c5SMatthew G. Knepley Not Collective 45394e3744c5SMatthew G. Knepley 45404e3744c5SMatthew G. Knepley Input Parameters: 45414e3744c5SMatthew G. Knepley + dmA - A DMPlex object 45424e3744c5SMatthew G. Knepley - dmB - A DMPlex object 45434e3744c5SMatthew G. Knepley 45444e3744c5SMatthew G. Knepley Output Parameters: 45454e3744c5SMatthew G. Knepley . equal - PETSC_TRUE if the topologies are identical 45464e3744c5SMatthew G. Knepley 45474e3744c5SMatthew G. Knepley Level: intermediate 45484e3744c5SMatthew G. Knepley 45494e3744c5SMatthew G. Knepley Notes: 45504e3744c5SMatthew G. Knepley We are not solving graph isomorphism, so we do not permutation. 45514e3744c5SMatthew G. Knepley 45524e3744c5SMatthew G. Knepley .seealso: DMPlexGetCone() 45534e3744c5SMatthew G. Knepley @*/ 45544e3744c5SMatthew G. Knepley PetscErrorCode DMPlexEqual(DM dmA, DM dmB, PetscBool *equal) 45554e3744c5SMatthew G. Knepley { 45564e3744c5SMatthew G. Knepley PetscInt depth, depthB, pStart, pEnd, pStartB, pEndB, p; 45574e3744c5SMatthew G. Knepley PetscErrorCode ierr; 45584e3744c5SMatthew G. Knepley 45594e3744c5SMatthew G. Knepley PetscFunctionBegin; 45604e3744c5SMatthew G. Knepley PetscValidHeaderSpecific(dmA, DM_CLASSID, 1); 45614e3744c5SMatthew G. Knepley PetscValidHeaderSpecific(dmB, DM_CLASSID, 2); 45624e3744c5SMatthew G. Knepley PetscValidPointer(equal, 3); 45634e3744c5SMatthew G. Knepley 45644e3744c5SMatthew G. Knepley *equal = PETSC_FALSE; 45654e3744c5SMatthew G. Knepley ierr = DMPlexGetDepth(dmA, &depth);CHKERRQ(ierr); 45664e3744c5SMatthew G. Knepley ierr = DMPlexGetDepth(dmB, &depthB);CHKERRQ(ierr); 45674e3744c5SMatthew G. Knepley if (depth != depthB) PetscFunctionReturn(0); 45684e3744c5SMatthew G. Knepley ierr = DMPlexGetChart(dmA, &pStart, &pEnd);CHKERRQ(ierr); 45694e3744c5SMatthew G. Knepley ierr = DMPlexGetChart(dmB, &pStartB, &pEndB);CHKERRQ(ierr); 45704e3744c5SMatthew G. Knepley if ((pStart != pStartB) || (pEnd != pEndB)) PetscFunctionReturn(0); 45714e3744c5SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 45724e3744c5SMatthew G. Knepley const PetscInt *cone, *coneB, *ornt, *orntB, *support, *supportB; 45734e3744c5SMatthew G. Knepley PetscInt coneSize, coneSizeB, c, supportSize, supportSizeB, s; 45744e3744c5SMatthew G. Knepley 45754e3744c5SMatthew G. Knepley ierr = DMPlexGetConeSize(dmA, p, &coneSize);CHKERRQ(ierr); 45764e3744c5SMatthew G. Knepley ierr = DMPlexGetCone(dmA, p, &cone);CHKERRQ(ierr); 45774e3744c5SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dmA, p, &ornt);CHKERRQ(ierr); 45784e3744c5SMatthew G. Knepley ierr = DMPlexGetConeSize(dmB, p, &coneSizeB);CHKERRQ(ierr); 45794e3744c5SMatthew G. Knepley ierr = DMPlexGetCone(dmB, p, &coneB);CHKERRQ(ierr); 45804e3744c5SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dmB, p, &orntB);CHKERRQ(ierr); 45814e3744c5SMatthew G. Knepley if (coneSize != coneSizeB) PetscFunctionReturn(0); 45824e3744c5SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 45834e3744c5SMatthew G. Knepley if (cone[c] != coneB[c]) PetscFunctionReturn(0); 45844e3744c5SMatthew G. Knepley if (ornt[c] != orntB[c]) PetscFunctionReturn(0); 45854e3744c5SMatthew G. Knepley } 45864e3744c5SMatthew G. Knepley ierr = DMPlexGetSupportSize(dmA, p, &supportSize);CHKERRQ(ierr); 45874e3744c5SMatthew G. Knepley ierr = DMPlexGetSupport(dmA, p, &support);CHKERRQ(ierr); 45884e3744c5SMatthew G. Knepley ierr = DMPlexGetSupportSize(dmB, p, &supportSizeB);CHKERRQ(ierr); 45894e3744c5SMatthew G. Knepley ierr = DMPlexGetSupport(dmB, p, &supportB);CHKERRQ(ierr); 45904e3744c5SMatthew G. Knepley if (supportSize != supportSizeB) PetscFunctionReturn(0); 45914e3744c5SMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 45924e3744c5SMatthew G. Knepley if (support[s] != supportB[s]) PetscFunctionReturn(0); 45934e3744c5SMatthew G. Knepley } 45944e3744c5SMatthew G. Knepley } 45954e3744c5SMatthew G. Knepley *equal = PETSC_TRUE; 45964e3744c5SMatthew G. Knepley PetscFunctionReturn(0); 45974e3744c5SMatthew G. Knepley } 45984e3744c5SMatthew G. Knepley 45997cd05799SMatthew G. Knepley /*@C 46007cd05799SMatthew G. Knepley DMPlexGetNumFaceVertices - Returns the number of vertices on a face 46017cd05799SMatthew G. Knepley 46027cd05799SMatthew G. Knepley Not Collective 46037cd05799SMatthew G. Knepley 46047cd05799SMatthew G. Knepley Input Parameters: 46057cd05799SMatthew G. Knepley + dm - The DMPlex 46067cd05799SMatthew G. Knepley . cellDim - The cell dimension 46077cd05799SMatthew G. Knepley - numCorners - The number of vertices on a cell 46087cd05799SMatthew G. Knepley 46097cd05799SMatthew G. Knepley Output Parameters: 46107cd05799SMatthew G. Knepley . numFaceVertices - The number of vertices on a face 46117cd05799SMatthew G. Knepley 46127cd05799SMatthew G. Knepley Level: developer 46137cd05799SMatthew G. Knepley 46147cd05799SMatthew G. Knepley Notes: 46157cd05799SMatthew G. Knepley Of course this can only work for a restricted set of symmetric shapes 46167cd05799SMatthew G. Knepley 46177cd05799SMatthew G. Knepley .seealso: DMPlexGetCone() 46187cd05799SMatthew G. Knepley @*/ 461918ad9376SMatthew G. Knepley PetscErrorCode DMPlexGetNumFaceVertices(DM dm, PetscInt cellDim, PetscInt numCorners, PetscInt *numFaceVertices) 4620a6dfd86eSKarl Rupp { 462182f516ccSBarry Smith MPI_Comm comm; 4622552f7358SJed Brown PetscErrorCode ierr; 4623552f7358SJed Brown 4624552f7358SJed Brown PetscFunctionBegin; 462582f516ccSBarry Smith ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 4626064a246eSJacob Faibussowitsch PetscValidPointer(numFaceVertices,4); 4627552f7358SJed Brown switch (cellDim) { 4628552f7358SJed Brown case 0: 4629552f7358SJed Brown *numFaceVertices = 0; 4630552f7358SJed Brown break; 4631552f7358SJed Brown case 1: 4632552f7358SJed Brown *numFaceVertices = 1; 4633552f7358SJed Brown break; 4634552f7358SJed Brown case 2: 4635552f7358SJed Brown switch (numCorners) { 463619436ca2SJed Brown case 3: /* triangle */ 463719436ca2SJed Brown *numFaceVertices = 2; /* Edge has 2 vertices */ 4638552f7358SJed Brown break; 463919436ca2SJed Brown case 4: /* quadrilateral */ 464019436ca2SJed Brown *numFaceVertices = 2; /* Edge has 2 vertices */ 4641552f7358SJed Brown break; 464219436ca2SJed Brown case 6: /* quadratic triangle, tri and quad cohesive Lagrange cells */ 464319436ca2SJed Brown *numFaceVertices = 3; /* Edge has 3 vertices */ 4644552f7358SJed Brown break; 464519436ca2SJed Brown case 9: /* quadratic quadrilateral, quadratic quad cohesive Lagrange cells */ 464619436ca2SJed Brown *numFaceVertices = 3; /* Edge has 3 vertices */ 4647552f7358SJed Brown break; 4648552f7358SJed Brown default: 464998921bdaSJacob Faibussowitsch SETERRQ(comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid number of face corners %D for dimension %D", numCorners, cellDim); 4650552f7358SJed Brown } 4651552f7358SJed Brown break; 4652552f7358SJed Brown case 3: 4653552f7358SJed Brown switch (numCorners) { 465419436ca2SJed Brown case 4: /* tetradehdron */ 465519436ca2SJed Brown *numFaceVertices = 3; /* Face has 3 vertices */ 4656552f7358SJed Brown break; 465719436ca2SJed Brown case 6: /* tet cohesive cells */ 465819436ca2SJed Brown *numFaceVertices = 4; /* Face has 4 vertices */ 4659552f7358SJed Brown break; 466019436ca2SJed Brown case 8: /* hexahedron */ 466119436ca2SJed Brown *numFaceVertices = 4; /* Face has 4 vertices */ 4662552f7358SJed Brown break; 466319436ca2SJed Brown case 9: /* tet cohesive Lagrange cells */ 466419436ca2SJed Brown *numFaceVertices = 6; /* Face has 6 vertices */ 4665552f7358SJed Brown break; 466619436ca2SJed Brown case 10: /* quadratic tetrahedron */ 466719436ca2SJed Brown *numFaceVertices = 6; /* Face has 6 vertices */ 4668552f7358SJed Brown break; 466919436ca2SJed Brown case 12: /* hex cohesive Lagrange cells */ 467019436ca2SJed Brown *numFaceVertices = 6; /* Face has 6 vertices */ 4671552f7358SJed Brown break; 467219436ca2SJed Brown case 18: /* quadratic tet cohesive Lagrange cells */ 467319436ca2SJed Brown *numFaceVertices = 6; /* Face has 6 vertices */ 4674552f7358SJed Brown break; 467519436ca2SJed Brown case 27: /* quadratic hexahedron, quadratic hex cohesive Lagrange cells */ 467619436ca2SJed Brown *numFaceVertices = 9; /* Face has 9 vertices */ 4677552f7358SJed Brown break; 4678552f7358SJed Brown default: 467998921bdaSJacob Faibussowitsch SETERRQ(comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid number of face corners %D for dimension %D", numCorners, cellDim); 4680552f7358SJed Brown } 4681552f7358SJed Brown break; 4682552f7358SJed Brown default: 468398921bdaSJacob Faibussowitsch SETERRQ(comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid cell dimension %D", cellDim); 4684552f7358SJed Brown } 4685552f7358SJed Brown PetscFunctionReturn(0); 4686552f7358SJed Brown } 4687552f7358SJed Brown 4688552f7358SJed Brown /*@ 4689aa50250dSMatthew G. Knepley DMPlexGetDepthLabel - Get the DMLabel recording the depth of each point 4690552f7358SJed Brown 4691552f7358SJed Brown Not Collective 4692552f7358SJed Brown 4693aa50250dSMatthew G. Knepley Input Parameter: 4694552f7358SJed Brown . dm - The DMPlex object 4695552f7358SJed Brown 4696aa50250dSMatthew G. Knepley Output Parameter: 4697aa50250dSMatthew G. Knepley . depthLabel - The DMLabel recording point depth 4698552f7358SJed Brown 4699552f7358SJed Brown Level: developer 4700552f7358SJed Brown 4701dc287ab2SVaclav Hapla .seealso: DMPlexGetDepth(), DMPlexGetHeightStratum(), DMPlexGetDepthStratum(), DMPlexGetPointDepth(), 4702aa50250dSMatthew G. Knepley @*/ 4703aa50250dSMatthew G. Knepley PetscErrorCode DMPlexGetDepthLabel(DM dm, DMLabel *depthLabel) 4704aa50250dSMatthew G. Knepley { 4705aa50250dSMatthew G. Knepley PetscFunctionBegin; 4706aa50250dSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4707aa50250dSMatthew G. Knepley PetscValidPointer(depthLabel, 2); 4708c58f1c22SToby Isaac *depthLabel = dm->depthLabel; 4709aa50250dSMatthew G. Knepley PetscFunctionReturn(0); 4710aa50250dSMatthew G. Knepley } 4711aa50250dSMatthew G. Knepley 4712aa50250dSMatthew G. Knepley /*@ 4713aa50250dSMatthew G. Knepley DMPlexGetDepth - Get the depth of the DAG representing this mesh 4714aa50250dSMatthew G. Knepley 4715aa50250dSMatthew G. Knepley Not Collective 4716aa50250dSMatthew G. Knepley 4717aa50250dSMatthew G. Knepley Input Parameter: 4718aa50250dSMatthew G. Knepley . dm - The DMPlex object 4719aa50250dSMatthew G. Knepley 4720aa50250dSMatthew G. Knepley Output Parameter: 4721aa50250dSMatthew G. Knepley . depth - The number of strata (breadth first levels) in the DAG 4722aa50250dSMatthew G. Knepley 4723aa50250dSMatthew G. Knepley Level: developer 4724552f7358SJed Brown 4725b1bb481bSMatthew Knepley Notes: 4726b1bb481bSMatthew Knepley This returns maximum of point depths over all points, i.e. maximum value of the label returned by DMPlexGetDepthLabel(). 4727dc287ab2SVaclav Hapla The point depth is described more in detail in DMPlexGetDepthStratum(). 4728dc287ab2SVaclav Hapla An empty mesh gives -1. 4729b1bb481bSMatthew Knepley 4730dc287ab2SVaclav Hapla .seealso: DMPlexGetDepthLabel(), DMPlexGetDepthStratum(), DMPlexGetPointDepth(), DMPlexSymmetrize() 4731552f7358SJed Brown @*/ 4732552f7358SJed Brown PetscErrorCode DMPlexGetDepth(DM dm, PetscInt *depth) 4733552f7358SJed Brown { 4734aa50250dSMatthew G. Knepley DMLabel label; 4735aa50250dSMatthew G. Knepley PetscInt d = 0; 4736552f7358SJed Brown PetscErrorCode ierr; 4737552f7358SJed Brown 4738552f7358SJed Brown PetscFunctionBegin; 4739552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4740552f7358SJed Brown PetscValidPointer(depth, 2); 4741aa50250dSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 4742aa50250dSMatthew G. Knepley if (label) {ierr = DMLabelGetNumValues(label, &d);CHKERRQ(ierr);} 4743552f7358SJed Brown *depth = d-1; 4744552f7358SJed Brown PetscFunctionReturn(0); 4745552f7358SJed Brown } 4746552f7358SJed Brown 4747552f7358SJed Brown /*@ 4748552f7358SJed Brown DMPlexGetDepthStratum - Get the bounds [start, end) for all points at a certain depth. 4749552f7358SJed Brown 4750552f7358SJed Brown Not Collective 4751552f7358SJed Brown 4752552f7358SJed Brown Input Parameters: 4753552f7358SJed Brown + dm - The DMPlex object 4754552f7358SJed Brown - stratumValue - The requested depth 4755552f7358SJed Brown 4756552f7358SJed Brown Output Parameters: 4757552f7358SJed Brown + start - The first point at this depth 4758552f7358SJed Brown - end - One beyond the last point at this depth 4759552f7358SJed Brown 4760647867b2SJed Brown Notes: 4761647867b2SJed Brown Depth indexing is related to topological dimension. Depth stratum 0 contains the lowest topological dimension points, 4762647867b2SJed Brown often "vertices". If the mesh is "interpolated" (see DMPlexInterpolate()), then depth stratum 1 contains the next 4763647867b2SJed Brown higher dimension, e.g., "edges". 4764647867b2SJed Brown 4765552f7358SJed Brown Level: developer 4766552f7358SJed Brown 4767dc287ab2SVaclav Hapla .seealso: DMPlexGetHeightStratum(), DMPlexGetDepth(), DMPlexGetDepthLabel(), DMPlexGetPointDepth(), DMPlexSymmetrize(), DMPlexInterpolate() 4768552f7358SJed Brown @*/ 47690adebc6cSBarry Smith PetscErrorCode DMPlexGetDepthStratum(DM dm, PetscInt stratumValue, PetscInt *start, PetscInt *end) 47700adebc6cSBarry Smith { 4771aa50250dSMatthew G. Knepley DMLabel label; 477263d1a920SMatthew G. Knepley PetscInt pStart, pEnd; 4773552f7358SJed Brown PetscErrorCode ierr; 4774552f7358SJed Brown 4775552f7358SJed Brown PetscFunctionBegin; 4776552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 477763d1a920SMatthew G. Knepley if (start) {PetscValidPointer(start, 3); *start = 0;} 477863d1a920SMatthew G. Knepley if (end) {PetscValidPointer(end, 4); *end = 0;} 4779552f7358SJed Brown ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 47800d644c17SKarl Rupp if (pStart == pEnd) PetscFunctionReturn(0); 478163d1a920SMatthew G. Knepley if (stratumValue < 0) { 478263d1a920SMatthew G. Knepley if (start) *start = pStart; 478363d1a920SMatthew G. Knepley if (end) *end = pEnd; 478463d1a920SMatthew G. Knepley PetscFunctionReturn(0); 4785552f7358SJed Brown } 4786aa50250dSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 47872c71b3e2SJacob Faibussowitsch PetscCheckFalse(!label,PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "No label named depth was found"); 478863d1a920SMatthew G. Knepley ierr = DMLabelGetStratumBounds(label, stratumValue, start, end);CHKERRQ(ierr); 4789552f7358SJed Brown PetscFunctionReturn(0); 4790552f7358SJed Brown } 4791552f7358SJed Brown 4792552f7358SJed Brown /*@ 4793552f7358SJed Brown DMPlexGetHeightStratum - Get the bounds [start, end) for all points at a certain height. 4794552f7358SJed Brown 4795552f7358SJed Brown Not Collective 4796552f7358SJed Brown 4797552f7358SJed Brown Input Parameters: 4798552f7358SJed Brown + dm - The DMPlex object 4799552f7358SJed Brown - stratumValue - The requested height 4800552f7358SJed Brown 4801552f7358SJed Brown Output Parameters: 4802552f7358SJed Brown + start - The first point at this height 4803552f7358SJed Brown - end - One beyond the last point at this height 4804552f7358SJed Brown 4805647867b2SJed Brown Notes: 4806647867b2SJed Brown Height indexing is related to topological codimension. Height stratum 0 contains the highest topological dimension 4807647867b2SJed Brown points, often called "cells" or "elements". If the mesh is "interpolated" (see DMPlexInterpolate()), then height 4808647867b2SJed Brown stratum 1 contains the boundary of these "cells", often called "faces" or "facets". 4809647867b2SJed Brown 4810552f7358SJed Brown Level: developer 4811552f7358SJed Brown 48123dc9a465SVaclav Hapla .seealso: DMPlexGetDepthStratum(), DMPlexGetDepth(), DMPlexGetPointHeight() 4813552f7358SJed Brown @*/ 48140adebc6cSBarry Smith PetscErrorCode DMPlexGetHeightStratum(DM dm, PetscInt stratumValue, PetscInt *start, PetscInt *end) 48150adebc6cSBarry Smith { 4816aa50250dSMatthew G. Knepley DMLabel label; 481763d1a920SMatthew G. Knepley PetscInt depth, pStart, pEnd; 4818552f7358SJed Brown PetscErrorCode ierr; 4819552f7358SJed Brown 4820552f7358SJed Brown PetscFunctionBegin; 4821552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 482263d1a920SMatthew G. Knepley if (start) {PetscValidPointer(start, 3); *start = 0;} 482363d1a920SMatthew G. Knepley if (end) {PetscValidPointer(end, 4); *end = 0;} 4824552f7358SJed Brown ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 48250d644c17SKarl Rupp if (pStart == pEnd) PetscFunctionReturn(0); 482663d1a920SMatthew G. Knepley if (stratumValue < 0) { 482763d1a920SMatthew G. Knepley if (start) *start = pStart; 482863d1a920SMatthew G. Knepley if (end) *end = pEnd; 482963d1a920SMatthew G. Knepley PetscFunctionReturn(0); 4830552f7358SJed Brown } 4831aa50250dSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 48322c71b3e2SJacob Faibussowitsch PetscCheckFalse(!label,PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "No label named depth was found"); 483363d1a920SMatthew G. Knepley ierr = DMLabelGetNumValues(label, &depth);CHKERRQ(ierr); 483463d1a920SMatthew G. Knepley ierr = DMLabelGetStratumBounds(label, depth-1-stratumValue, start, end);CHKERRQ(ierr); 4835552f7358SJed Brown PetscFunctionReturn(0); 4836552f7358SJed Brown } 4837552f7358SJed Brown 4838ba2698f1SMatthew G. Knepley /*@ 4839ba2698f1SMatthew G. Knepley DMPlexGetPointDepth - Get the depth of a given point 4840ba2698f1SMatthew G. Knepley 4841ba2698f1SMatthew G. Knepley Not Collective 4842ba2698f1SMatthew G. Knepley 4843d8d19677SJose E. Roman Input Parameters: 4844ba2698f1SMatthew G. Knepley + dm - The DMPlex object 4845ba2698f1SMatthew G. Knepley - point - The point 4846ba2698f1SMatthew G. Knepley 4847ba2698f1SMatthew G. Knepley Output Parameter: 4848ba2698f1SMatthew G. Knepley . depth - The depth of the point 4849ba2698f1SMatthew G. Knepley 4850ba2698f1SMatthew G. Knepley Level: intermediate 4851ba2698f1SMatthew G. Knepley 48523dc9a465SVaclav Hapla .seealso: DMPlexGetCellType(), DMPlexGetDepthLabel(), DMPlexGetDepth(), DMPlexGetPointHeight() 4853ba2698f1SMatthew G. Knepley @*/ 4854ba2698f1SMatthew G. Knepley PetscErrorCode DMPlexGetPointDepth(DM dm, PetscInt point, PetscInt *depth) 4855ba2698f1SMatthew G. Knepley { 4856ba2698f1SMatthew G. Knepley PetscErrorCode ierr; 4857ba2698f1SMatthew G. Knepley 4858ba2698f1SMatthew G. Knepley PetscFunctionBegin; 4859ba2698f1SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 486040a2aa30SMatthew G. Knepley PetscValidIntPointer(depth, 3); 4861ba2698f1SMatthew G. Knepley ierr = DMLabelGetValue(dm->depthLabel, point, depth);CHKERRQ(ierr); 4862ba2698f1SMatthew G. Knepley PetscFunctionReturn(0); 4863ba2698f1SMatthew G. Knepley } 4864ba2698f1SMatthew G. Knepley 4865ba2698f1SMatthew G. Knepley /*@ 48660c0a32dcSVaclav Hapla DMPlexGetPointHeight - Get the height of a given point 48670c0a32dcSVaclav Hapla 48680c0a32dcSVaclav Hapla Not Collective 48690c0a32dcSVaclav Hapla 4870d8d19677SJose E. Roman Input Parameters: 48710c0a32dcSVaclav Hapla + dm - The DMPlex object 48720c0a32dcSVaclav Hapla - point - The point 48730c0a32dcSVaclav Hapla 48740c0a32dcSVaclav Hapla Output Parameter: 48750c0a32dcSVaclav Hapla . height - The height of the point 48760c0a32dcSVaclav Hapla 48770c0a32dcSVaclav Hapla Level: intermediate 48780c0a32dcSVaclav Hapla 48793dc9a465SVaclav Hapla .seealso: DMPlexGetCellType(), DMPlexGetDepthLabel(), DMPlexGetDepth(), DMPlexGetPointDepth() 48800c0a32dcSVaclav Hapla @*/ 48810c0a32dcSVaclav Hapla PetscErrorCode DMPlexGetPointHeight(DM dm, PetscInt point, PetscInt *height) 48820c0a32dcSVaclav Hapla { 48830c0a32dcSVaclav Hapla PetscInt n, pDepth; 48840c0a32dcSVaclav Hapla PetscErrorCode ierr; 48850c0a32dcSVaclav Hapla 48860c0a32dcSVaclav Hapla PetscFunctionBegin; 48870c0a32dcSVaclav Hapla PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 48880c0a32dcSVaclav Hapla PetscValidIntPointer(height, 3); 48890c0a32dcSVaclav Hapla ierr = DMLabelGetNumValues(dm->depthLabel, &n);CHKERRQ(ierr); 48900c0a32dcSVaclav Hapla ierr = DMLabelGetValue(dm->depthLabel, point, &pDepth);CHKERRQ(ierr); 48910c0a32dcSVaclav Hapla *height = n - 1 - pDepth; /* DAG depth is n-1 */ 48920c0a32dcSVaclav Hapla PetscFunctionReturn(0); 48930c0a32dcSVaclav Hapla } 48940c0a32dcSVaclav Hapla 48950c0a32dcSVaclav Hapla /*@ 4896ba2698f1SMatthew G. Knepley DMPlexGetCellTypeLabel - Get the DMLabel recording the polytope type of each cell 4897ba2698f1SMatthew G. Knepley 4898ba2698f1SMatthew G. Knepley Not Collective 4899ba2698f1SMatthew G. Knepley 4900ba2698f1SMatthew G. Knepley Input Parameter: 4901ba2698f1SMatthew G. Knepley . dm - The DMPlex object 4902ba2698f1SMatthew G. Knepley 4903ba2698f1SMatthew G. Knepley Output Parameter: 4904ba2698f1SMatthew G. Knepley . celltypeLabel - The DMLabel recording cell polytope type 4905ba2698f1SMatthew G. Knepley 4906412e9a14SMatthew G. Knepley Note: This function will trigger automatica computation of cell types. This can be disabled by calling 4907412e9a14SMatthew G. Knepley DMCreateLabel(dm, "celltype") beforehand. 4908412e9a14SMatthew G. Knepley 4909ba2698f1SMatthew G. Knepley Level: developer 4910ba2698f1SMatthew G. Knepley 4911dc287ab2SVaclav Hapla .seealso: DMPlexGetCellType(), DMPlexGetDepthLabel(), DMCreateLabel() 4912ba2698f1SMatthew G. Knepley @*/ 4913ba2698f1SMatthew G. Knepley PetscErrorCode DMPlexGetCellTypeLabel(DM dm, DMLabel *celltypeLabel) 4914ba2698f1SMatthew G. Knepley { 4915ba2698f1SMatthew G. Knepley PetscErrorCode ierr; 4916ba2698f1SMatthew G. Knepley 4917ba2698f1SMatthew G. Knepley PetscFunctionBegin; 4918ba2698f1SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4919ba2698f1SMatthew G. Knepley PetscValidPointer(celltypeLabel, 2); 4920ba2698f1SMatthew G. Knepley if (!dm->celltypeLabel) {ierr = DMPlexComputeCellTypes(dm);CHKERRQ(ierr);} 4921ba2698f1SMatthew G. Knepley *celltypeLabel = dm->celltypeLabel; 4922ba2698f1SMatthew G. Knepley PetscFunctionReturn(0); 4923ba2698f1SMatthew G. Knepley } 4924ba2698f1SMatthew G. Knepley 4925ba2698f1SMatthew G. Knepley /*@ 4926ba2698f1SMatthew G. Knepley DMPlexGetCellType - Get the polytope type of a given cell 4927ba2698f1SMatthew G. Knepley 4928ba2698f1SMatthew G. Knepley Not Collective 4929ba2698f1SMatthew G. Knepley 4930d8d19677SJose E. Roman Input Parameters: 4931ba2698f1SMatthew G. Knepley + dm - The DMPlex object 4932ba2698f1SMatthew G. Knepley - cell - The cell 4933ba2698f1SMatthew G. Knepley 4934ba2698f1SMatthew G. Knepley Output Parameter: 4935ba2698f1SMatthew G. Knepley . celltype - The polytope type of the cell 4936ba2698f1SMatthew G. Knepley 4937ba2698f1SMatthew G. Knepley Level: intermediate 4938ba2698f1SMatthew G. Knepley 4939ba2698f1SMatthew G. Knepley .seealso: DMPlexGetCellTypeLabel(), DMPlexGetDepthLabel(), DMPlexGetDepth() 4940ba2698f1SMatthew G. Knepley @*/ 4941ba2698f1SMatthew G. Knepley PetscErrorCode DMPlexGetCellType(DM dm, PetscInt cell, DMPolytopeType *celltype) 4942ba2698f1SMatthew G. Knepley { 4943ba2698f1SMatthew G. Knepley DMLabel label; 4944ba2698f1SMatthew G. Knepley PetscInt ct; 4945ba2698f1SMatthew G. Knepley PetscErrorCode ierr; 4946ba2698f1SMatthew G. Knepley 4947ba2698f1SMatthew G. Knepley PetscFunctionBegin; 4948ba2698f1SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4949ba2698f1SMatthew G. Knepley PetscValidPointer(celltype, 3); 4950ba2698f1SMatthew G. Knepley ierr = DMPlexGetCellTypeLabel(dm, &label);CHKERRQ(ierr); 4951ba2698f1SMatthew G. Knepley ierr = DMLabelGetValue(label, cell, &ct);CHKERRQ(ierr); 49522c71b3e2SJacob Faibussowitsch PetscCheckFalse(ct < 0,PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Cell %D has not been assigned a cell type", cell); 4953ba2698f1SMatthew G. Knepley *celltype = (DMPolytopeType) ct; 4954ba2698f1SMatthew G. Knepley PetscFunctionReturn(0); 4955ba2698f1SMatthew G. Knepley } 4956ba2698f1SMatthew G. Knepley 4957412e9a14SMatthew G. Knepley /*@ 4958412e9a14SMatthew G. Knepley DMPlexSetCellType - Set the polytope type of a given cell 4959412e9a14SMatthew G. Knepley 4960412e9a14SMatthew G. Knepley Not Collective 4961412e9a14SMatthew G. Knepley 4962412e9a14SMatthew G. Knepley Input Parameters: 4963412e9a14SMatthew G. Knepley + dm - The DMPlex object 4964412e9a14SMatthew G. Knepley . cell - The cell 4965412e9a14SMatthew G. Knepley - celltype - The polytope type of the cell 4966412e9a14SMatthew G. Knepley 4967412e9a14SMatthew G. Knepley Note: By default, cell types will be automatically computed using DMPlexComputeCellTypes() before this function 4968412e9a14SMatthew G. Knepley is executed. This function will override the computed type. However, if automatic classification will not succeed 4969412e9a14SMatthew G. Knepley and a user wants to manually specify all types, the classification must be disabled by calling 4970412e9a14SMatthew G. Knepley DMCreaateLabel(dm, "celltype") before getting or setting any cell types. 4971412e9a14SMatthew G. Knepley 4972412e9a14SMatthew G. Knepley Level: advanced 4973412e9a14SMatthew G. Knepley 4974412e9a14SMatthew G. Knepley .seealso: DMPlexGetCellTypeLabel(), DMPlexGetDepthLabel(), DMPlexGetDepth(), DMPlexComputeCellTypes(), DMCreateLabel() 4975412e9a14SMatthew G. Knepley @*/ 4976412e9a14SMatthew G. Knepley PetscErrorCode DMPlexSetCellType(DM dm, PetscInt cell, DMPolytopeType celltype) 4977412e9a14SMatthew G. Knepley { 4978412e9a14SMatthew G. Knepley DMLabel label; 4979412e9a14SMatthew G. Knepley PetscErrorCode ierr; 4980412e9a14SMatthew G. Knepley 4981412e9a14SMatthew G. Knepley PetscFunctionBegin; 4982412e9a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4983412e9a14SMatthew G. Knepley ierr = DMPlexGetCellTypeLabel(dm, &label);CHKERRQ(ierr); 4984412e9a14SMatthew G. Knepley ierr = DMLabelSetValue(label, cell, celltype);CHKERRQ(ierr); 4985412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 4986412e9a14SMatthew G. Knepley } 4987412e9a14SMatthew G. Knepley 49880adebc6cSBarry Smith PetscErrorCode DMCreateCoordinateDM_Plex(DM dm, DM *cdm) 49890adebc6cSBarry Smith { 4990efe440bfSMatthew G. Knepley PetscSection section, s; 4991efe440bfSMatthew G. Knepley Mat m; 49923e922f36SToby Isaac PetscInt maxHeight; 4993552f7358SJed Brown PetscErrorCode ierr; 4994552f7358SJed Brown 4995552f7358SJed Brown PetscFunctionBegin; 499638221697SMatthew G. Knepley ierr = DMClone(dm, cdm);CHKERRQ(ierr); 49973e922f36SToby Isaac ierr = DMPlexGetMaxProjectionHeight(dm, &maxHeight);CHKERRQ(ierr); 49983e922f36SToby Isaac ierr = DMPlexSetMaxProjectionHeight(*cdm, maxHeight);CHKERRQ(ierr); 499982f516ccSBarry Smith ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), §ion);CHKERRQ(ierr); 500092fd8e1eSJed Brown ierr = DMSetLocalSection(*cdm, section);CHKERRQ(ierr); 50011d799100SJed Brown ierr = PetscSectionDestroy(§ion);CHKERRQ(ierr); 5002efe440bfSMatthew G. Knepley ierr = PetscSectionCreate(PETSC_COMM_SELF, &s);CHKERRQ(ierr); 5003efe440bfSMatthew G. Knepley ierr = MatCreate(PETSC_COMM_SELF, &m);CHKERRQ(ierr); 500479769bd5SJed Brown ierr = DMSetDefaultConstraints(*cdm, s, m, NULL);CHKERRQ(ierr); 5005efe440bfSMatthew G. Knepley ierr = PetscSectionDestroy(&s);CHKERRQ(ierr); 5006efe440bfSMatthew G. Knepley ierr = MatDestroy(&m);CHKERRQ(ierr); 50078f4c458bSMatthew G. Knepley 50088f4c458bSMatthew G. Knepley ierr = DMSetNumFields(*cdm, 1);CHKERRQ(ierr); 50098f4c458bSMatthew G. Knepley ierr = DMCreateDS(*cdm);CHKERRQ(ierr); 5010552f7358SJed Brown PetscFunctionReturn(0); 5011552f7358SJed Brown } 5012552f7358SJed Brown 5013f19dbd58SToby Isaac PetscErrorCode DMCreateCoordinateField_Plex(DM dm, DMField *field) 5014f19dbd58SToby Isaac { 5015f19dbd58SToby Isaac Vec coordsLocal; 5016f19dbd58SToby Isaac DM coordsDM; 5017f19dbd58SToby Isaac PetscErrorCode ierr; 5018f19dbd58SToby Isaac 5019f19dbd58SToby Isaac PetscFunctionBegin; 5020f19dbd58SToby Isaac *field = NULL; 5021f19dbd58SToby Isaac ierr = DMGetCoordinatesLocal(dm,&coordsLocal);CHKERRQ(ierr); 5022f19dbd58SToby Isaac ierr = DMGetCoordinateDM(dm,&coordsDM);CHKERRQ(ierr); 5023f19dbd58SToby Isaac if (coordsLocal && coordsDM) { 5024f19dbd58SToby Isaac ierr = DMFieldCreateDS(coordsDM, 0, coordsLocal, field);CHKERRQ(ierr); 5025f19dbd58SToby Isaac } 5026f19dbd58SToby Isaac PetscFunctionReturn(0); 5027f19dbd58SToby Isaac } 5028f19dbd58SToby Isaac 50297cd05799SMatthew G. Knepley /*@C 50307cd05799SMatthew G. Knepley DMPlexGetConeSection - Return a section which describes the layout of cone data 50317cd05799SMatthew G. Knepley 50327cd05799SMatthew G. Knepley Not Collective 50337cd05799SMatthew G. Knepley 50347cd05799SMatthew G. Knepley Input Parameters: 50357cd05799SMatthew G. Knepley . dm - The DMPlex object 50367cd05799SMatthew G. Knepley 50377cd05799SMatthew G. Knepley Output Parameter: 50387cd05799SMatthew G. Knepley . section - The PetscSection object 50397cd05799SMatthew G. Knepley 50407cd05799SMatthew G. Knepley Level: developer 50417cd05799SMatthew G. Knepley 50427cd05799SMatthew G. Knepley .seealso: DMPlexGetSupportSection(), DMPlexGetCones(), DMPlexGetConeOrientations() 50437cd05799SMatthew G. Knepley @*/ 50440adebc6cSBarry Smith PetscErrorCode DMPlexGetConeSection(DM dm, PetscSection *section) 50450adebc6cSBarry Smith { 5046552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 5047552f7358SJed Brown 5048552f7358SJed Brown PetscFunctionBegin; 5049552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5050552f7358SJed Brown if (section) *section = mesh->coneSection; 5051552f7358SJed Brown PetscFunctionReturn(0); 5052552f7358SJed Brown } 5053552f7358SJed Brown 50547cd05799SMatthew G. Knepley /*@C 50557cd05799SMatthew G. Knepley DMPlexGetSupportSection - Return a section which describes the layout of support data 50567cd05799SMatthew G. Knepley 50577cd05799SMatthew G. Knepley Not Collective 50587cd05799SMatthew G. Knepley 50597cd05799SMatthew G. Knepley Input Parameters: 50607cd05799SMatthew G. Knepley . dm - The DMPlex object 50617cd05799SMatthew G. Knepley 50627cd05799SMatthew G. Knepley Output Parameter: 50637cd05799SMatthew G. Knepley . section - The PetscSection object 50647cd05799SMatthew G. Knepley 50657cd05799SMatthew G. Knepley Level: developer 50667cd05799SMatthew G. Knepley 50677cd05799SMatthew G. Knepley .seealso: DMPlexGetConeSection() 50687cd05799SMatthew G. Knepley @*/ 50698cb4d582SMatthew G. Knepley PetscErrorCode DMPlexGetSupportSection(DM dm, PetscSection *section) 50708cb4d582SMatthew G. Knepley { 50718cb4d582SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 50728cb4d582SMatthew G. Knepley 50738cb4d582SMatthew G. Knepley PetscFunctionBegin; 50748cb4d582SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 50758cb4d582SMatthew G. Knepley if (section) *section = mesh->supportSection; 50768cb4d582SMatthew G. Knepley PetscFunctionReturn(0); 50778cb4d582SMatthew G. Knepley } 50788cb4d582SMatthew G. Knepley 50797cd05799SMatthew G. Knepley /*@C 50807cd05799SMatthew G. Knepley DMPlexGetCones - Return cone data 50817cd05799SMatthew G. Knepley 50827cd05799SMatthew G. Knepley Not Collective 50837cd05799SMatthew G. Knepley 50847cd05799SMatthew G. Knepley Input Parameters: 50857cd05799SMatthew G. Knepley . dm - The DMPlex object 50867cd05799SMatthew G. Knepley 50877cd05799SMatthew G. Knepley Output Parameter: 50887cd05799SMatthew G. Knepley . cones - The cone for each point 50897cd05799SMatthew G. Knepley 50907cd05799SMatthew G. Knepley Level: developer 50917cd05799SMatthew G. Knepley 50927cd05799SMatthew G. Knepley .seealso: DMPlexGetConeSection() 50937cd05799SMatthew G. Knepley @*/ 5094a6dfd86eSKarl Rupp PetscErrorCode DMPlexGetCones(DM dm, PetscInt *cones[]) 5095a6dfd86eSKarl Rupp { 5096552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 5097552f7358SJed Brown 5098552f7358SJed Brown PetscFunctionBegin; 5099552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5100552f7358SJed Brown if (cones) *cones = mesh->cones; 5101552f7358SJed Brown PetscFunctionReturn(0); 5102552f7358SJed Brown } 5103552f7358SJed Brown 51047cd05799SMatthew G. Knepley /*@C 51057cd05799SMatthew G. Knepley DMPlexGetConeOrientations - Return cone orientation data 51067cd05799SMatthew G. Knepley 51077cd05799SMatthew G. Knepley Not Collective 51087cd05799SMatthew G. Knepley 51097cd05799SMatthew G. Knepley Input Parameters: 51107cd05799SMatthew G. Knepley . dm - The DMPlex object 51117cd05799SMatthew G. Knepley 51127cd05799SMatthew G. Knepley Output Parameter: 5113b5a892a1SMatthew G. Knepley . coneOrientations - The array of cone orientations for all points 51147cd05799SMatthew G. Knepley 51157cd05799SMatthew G. Knepley Level: developer 51167cd05799SMatthew G. Knepley 5117b5a892a1SMatthew G. Knepley Notes: 5118b5a892a1SMatthew G. Knepley The PetscSection returned by DMPlexGetConeSection() partitions coneOrientations into cone orientations of particular points as returned by DMPlexGetConeOrientation(). 5119b5a892a1SMatthew G. Knepley 5120b5a892a1SMatthew G. Knepley The meaning of coneOrientations values is detailed in DMPlexGetConeOrientation(). 5121b5a892a1SMatthew G. Knepley 5122b5a892a1SMatthew G. Knepley .seealso: DMPlexGetConeSection(), DMPlexGetConeOrientation() 51237cd05799SMatthew G. Knepley @*/ 5124a6dfd86eSKarl Rupp PetscErrorCode DMPlexGetConeOrientations(DM dm, PetscInt *coneOrientations[]) 5125a6dfd86eSKarl Rupp { 5126552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 5127552f7358SJed Brown 5128552f7358SJed Brown PetscFunctionBegin; 5129552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5130552f7358SJed Brown if (coneOrientations) *coneOrientations = mesh->coneOrientations; 5131552f7358SJed Brown PetscFunctionReturn(0); 5132552f7358SJed Brown } 5133552f7358SJed Brown 5134552f7358SJed Brown /******************************** FEM Support **********************************/ 5135552f7358SJed Brown 51369e8305c2SJed Brown /* 51379e8305c2SJed Brown Returns number of components and tensor degree for the field. For interpolated meshes, line should be a point 51389e8305c2SJed Brown representing a line in the section. 51399e8305c2SJed Brown */ 51409e8305c2SJed Brown static PetscErrorCode PetscSectionFieldGetTensorDegree_Private(PetscSection section,PetscInt field,PetscInt line,PetscBool vertexchart,PetscInt *Nc,PetscInt *k) 51419e8305c2SJed Brown { 51429e8305c2SJed Brown PetscErrorCode ierr; 51439e8305c2SJed Brown 51449e8305c2SJed Brown PetscFunctionBeginHot; 51459e8305c2SJed Brown ierr = PetscSectionGetFieldComponents(section, field, Nc);CHKERRQ(ierr); 5146a433471fSStefano Zampini if (line < 0) { 5147a433471fSStefano Zampini *k = 0; 5148a433471fSStefano Zampini *Nc = 0; 5149a433471fSStefano Zampini } else if (vertexchart) { /* If we only have a vertex chart, we must have degree k=1 */ 51509e8305c2SJed Brown *k = 1; 51519e8305c2SJed Brown } else { /* Assume the full interpolated mesh is in the chart; lines in particular */ 51529e8305c2SJed Brown /* An order k SEM disc has k-1 dofs on an edge */ 51539e8305c2SJed Brown ierr = PetscSectionGetFieldDof(section, line, field, k);CHKERRQ(ierr); 51549e8305c2SJed Brown *k = *k / *Nc + 1; 51559e8305c2SJed Brown } 51569e8305c2SJed Brown PetscFunctionReturn(0); 51579e8305c2SJed Brown } 51589e8305c2SJed Brown 5159a4355906SMatthew Knepley /*@ 5160bc1eb3faSJed Brown 5161bc1eb3faSJed Brown DMPlexSetClosurePermutationTensor - Create a permutation from the default (BFS) point ordering in the closure, to a 5162bc1eb3faSJed Brown lexicographic ordering over the tensor product cell (i.e., line, quad, hex, etc.), and set this permutation in the 51631bb6d2a8SBarry Smith section provided (or the section of the DM). 5164a4355906SMatthew Knepley 5165a4355906SMatthew Knepley Input Parameters: 5166a4355906SMatthew Knepley + dm - The DM 5167a4355906SMatthew Knepley . point - Either a cell (highest dim point) or an edge (dim 1 point), or PETSC_DETERMINE 5168a4355906SMatthew Knepley - section - The PetscSection to reorder, or NULL for the default section 5169a4355906SMatthew Knepley 5170a4355906SMatthew Knepley Note: The point is used to determine the number of dofs/field on an edge. For SEM, this is related to the polynomial 5171a4355906SMatthew Knepley degree of the basis. 5172a4355906SMatthew Knepley 5173bc1eb3faSJed Brown Example: 5174bc1eb3faSJed Brown A typical interpolated single-quad mesh might order points as 5175bc1eb3faSJed Brown .vb 5176bc1eb3faSJed Brown [c0, v1, v2, v3, v4, e5, e6, e7, e8] 5177bc1eb3faSJed Brown 5178bc1eb3faSJed Brown v4 -- e6 -- v3 5179bc1eb3faSJed Brown | | 5180bc1eb3faSJed Brown e7 c0 e8 5181bc1eb3faSJed Brown | | 5182bc1eb3faSJed Brown v1 -- e5 -- v2 5183bc1eb3faSJed Brown .ve 5184bc1eb3faSJed Brown 5185bc1eb3faSJed Brown (There is no significance to the ordering described here.) The default section for a Q3 quad might typically assign 5186bc1eb3faSJed Brown dofs in the order of points, e.g., 5187bc1eb3faSJed Brown .vb 5188bc1eb3faSJed Brown c0 -> [0,1,2,3] 5189bc1eb3faSJed Brown v1 -> [4] 5190bc1eb3faSJed Brown ... 5191bc1eb3faSJed Brown e5 -> [8, 9] 5192bc1eb3faSJed Brown .ve 5193bc1eb3faSJed Brown 5194bc1eb3faSJed Brown which corresponds to the dofs 5195bc1eb3faSJed Brown .vb 5196bc1eb3faSJed Brown 6 10 11 7 5197bc1eb3faSJed Brown 13 2 3 15 5198bc1eb3faSJed Brown 12 0 1 14 5199bc1eb3faSJed Brown 4 8 9 5 5200bc1eb3faSJed Brown .ve 5201bc1eb3faSJed Brown 5202bc1eb3faSJed Brown The closure in BFS ordering works through height strata (cells, edges, vertices) to produce the ordering 5203bc1eb3faSJed Brown .vb 5204bc1eb3faSJed Brown 0 1 2 3 8 9 14 15 11 10 13 12 4 5 7 6 5205bc1eb3faSJed Brown .ve 5206bc1eb3faSJed Brown 5207bc1eb3faSJed Brown After calling DMPlexSetClosurePermutationTensor(), the closure will be ordered lexicographically, 5208bc1eb3faSJed Brown .vb 5209bc1eb3faSJed Brown 4 8 9 5 12 0 1 14 13 2 3 15 6 10 11 7 5210bc1eb3faSJed Brown .ve 5211bc1eb3faSJed Brown 5212a4355906SMatthew Knepley Level: developer 5213a4355906SMatthew Knepley 52149df75925SJed Brown .seealso: DMGetLocalSection(), PetscSectionSetClosurePermutation(), DMSetGlobalSection() 5215a4355906SMatthew Knepley @*/ 5216bc1eb3faSJed Brown PetscErrorCode DMPlexSetClosurePermutationTensor(DM dm, PetscInt point, PetscSection section) 52173194fc30SMatthew G. Knepley { 52187391a63aSMatthew G. Knepley DMLabel label; 5219bb197d40SJed Brown PetscInt dim, depth = -1, eStart = -1, Nf; 52209e8305c2SJed Brown PetscBool vertexchart; 52213194fc30SMatthew G. Knepley PetscErrorCode ierr; 52223194fc30SMatthew G. Knepley 52233194fc30SMatthew G. Knepley PetscFunctionBegin; 52243194fc30SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 5225a433471fSStefano Zampini if (dim < 1) PetscFunctionReturn(0); 5226a433471fSStefano Zampini if (point < 0) { 5227a433471fSStefano Zampini PetscInt sStart,sEnd; 5228a433471fSStefano Zampini 5229a433471fSStefano Zampini ierr = DMPlexGetDepthStratum(dm, 1, &sStart, &sEnd);CHKERRQ(ierr); 5230a433471fSStefano Zampini point = sEnd-sStart ? sStart : point; 5231a433471fSStefano Zampini } 52327391a63aSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 5233a433471fSStefano Zampini if (point >= 0) { ierr = DMLabelGetValue(label, point, &depth);CHKERRQ(ierr); } 5234a433471fSStefano Zampini if (!section) {ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr);} 52357391a63aSMatthew G. Knepley if (depth == 1) {eStart = point;} 52367391a63aSMatthew G. Knepley else if (depth == dim) { 52377391a63aSMatthew G. Knepley const PetscInt *cone; 52387391a63aSMatthew G. Knepley 52397391a63aSMatthew G. Knepley ierr = DMPlexGetCone(dm, point, &cone);CHKERRQ(ierr); 5240d4e6627bSStefano Zampini if (dim == 2) eStart = cone[0]; 5241d4e6627bSStefano Zampini else if (dim == 3) { 5242d4e6627bSStefano Zampini const PetscInt *cone2; 5243d4e6627bSStefano Zampini ierr = DMPlexGetCone(dm, cone[0], &cone2);CHKERRQ(ierr); 5244d4e6627bSStefano Zampini eStart = cone2[0]; 524598921bdaSJacob Faibussowitsch } else SETERRQ(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); 52462c71b3e2SJacob Faibussowitsch } else PetscCheckFalse(depth >= 0,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); 52479e8305c2SJed Brown { /* Determine whether the chart covers all points or just vertices. */ 52489e8305c2SJed Brown PetscInt pStart,pEnd,cStart,cEnd; 52499e8305c2SJed Brown ierr = DMPlexGetDepthStratum(dm,0,&pStart,&pEnd);CHKERRQ(ierr); 52509e8305c2SJed Brown ierr = PetscSectionGetChart(section,&cStart,&cEnd);CHKERRQ(ierr); 5251796d0a68SJed Brown if (pStart == cStart && pEnd == cEnd) vertexchart = PETSC_TRUE; /* Only vertices are in the chart */ 5252796d0a68SJed Brown else if (cStart <= point && point < cEnd) vertexchart = PETSC_FALSE; /* Some interpolated points exist in the chart */ 5253796d0a68SJed Brown else vertexchart = PETSC_TRUE; /* Some interpolated points are not in chart; assume dofs only at cells and vertices */ 52549e8305c2SJed Brown } 52553194fc30SMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &Nf);CHKERRQ(ierr); 5256bb197d40SJed Brown for (PetscInt d=1; d<=dim; d++) { 5257bb197d40SJed Brown PetscInt k, f, Nc, c, i, j, size = 0, offset = 0, foffset = 0; 5258bb197d40SJed Brown PetscInt *perm; 5259bb197d40SJed Brown 52603194fc30SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 52619e8305c2SJed Brown ierr = PetscSectionFieldGetTensorDegree_Private(section,f,eStart,vertexchart,&Nc,&k);CHKERRQ(ierr); 5262bb197d40SJed Brown size += PetscPowInt(k+1, d)*Nc; 52633194fc30SMatthew G. Knepley } 52643194fc30SMatthew G. Knepley ierr = PetscMalloc1(size, &perm);CHKERRQ(ierr); 52653194fc30SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 5266bb197d40SJed Brown switch (d) { 5267babf31e0SJed Brown case 1: 52689e8305c2SJed Brown ierr = PetscSectionFieldGetTensorDegree_Private(section,f,eStart,vertexchart,&Nc,&k);CHKERRQ(ierr); 5269babf31e0SJed Brown /* 5270babf31e0SJed Brown Original ordering is [ edge of length k-1; vtx0; vtx1 ] 5271babf31e0SJed Brown We want [ vtx0; edge of length k-1; vtx1 ] 5272babf31e0SJed Brown */ 5273babf31e0SJed Brown for (c=0; c<Nc; c++,offset++) perm[offset] = (k-1)*Nc + c + foffset; 5274babf31e0SJed Brown for (i=0; i<k-1; i++) for (c=0; c<Nc; c++,offset++) perm[offset] = i*Nc + c + foffset; 5275babf31e0SJed Brown for (c=0; c<Nc; c++,offset++) perm[offset] = k*Nc + c + foffset; 5276babf31e0SJed Brown foffset = offset; 5277babf31e0SJed Brown break; 527889eabcffSMatthew G. Knepley case 2: 52793194fc30SMatthew 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} */ 52809e8305c2SJed Brown ierr = PetscSectionFieldGetTensorDegree_Private(section,f,eStart,vertexchart,&Nc,&k);CHKERRQ(ierr); 52813194fc30SMatthew G. Knepley /* The SEM order is 52823194fc30SMatthew G. Knepley 52833194fc30SMatthew G. Knepley v_lb, {e_b}, v_rb, 528489eabcffSMatthew G. Knepley e^{(k-1)-i}_l, {f^{i*(k-1)}}, e^i_r, 52853194fc30SMatthew G. Knepley v_lt, reverse {e_t}, v_rt 52863194fc30SMatthew G. Knepley */ 52873194fc30SMatthew G. Knepley { 52883194fc30SMatthew G. Knepley const PetscInt of = 0; 52893194fc30SMatthew G. Knepley const PetscInt oeb = of + PetscSqr(k-1); 52903194fc30SMatthew G. Knepley const PetscInt oer = oeb + (k-1); 52913194fc30SMatthew G. Knepley const PetscInt oet = oer + (k-1); 52923194fc30SMatthew G. Knepley const PetscInt oel = oet + (k-1); 52933194fc30SMatthew G. Knepley const PetscInt ovlb = oel + (k-1); 52943194fc30SMatthew G. Knepley const PetscInt ovrb = ovlb + 1; 52953194fc30SMatthew G. Knepley const PetscInt ovrt = ovrb + 1; 52963194fc30SMatthew G. Knepley const PetscInt ovlt = ovrt + 1; 52973194fc30SMatthew G. Knepley PetscInt o; 52983194fc30SMatthew G. Knepley 52993194fc30SMatthew G. Knepley /* bottom */ 53003194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovlb*Nc + c + foffset; 53013194fc30SMatthew G. Knepley for (o = oeb; o < oer; ++o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 53023194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovrb*Nc + c + foffset; 53033194fc30SMatthew G. Knepley /* middle */ 53043194fc30SMatthew G. Knepley for (i = 0; i < k-1; ++i) { 53053194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oel+(k-2)-i)*Nc + c + foffset; 53063194fc30SMatthew 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; 53073194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oer+i)*Nc + c + foffset; 53083194fc30SMatthew G. Knepley } 53093194fc30SMatthew G. Knepley /* top */ 53103194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovlt*Nc + c + foffset; 53113194fc30SMatthew G. Knepley for (o = oel-1; o >= oet; --o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 53123194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovrt*Nc + c + foffset; 53133194fc30SMatthew G. Knepley foffset = offset; 53143194fc30SMatthew G. Knepley } 531589eabcffSMatthew G. Knepley break; 531689eabcffSMatthew G. Knepley case 3: 531789eabcffSMatthew G. Knepley /* The original hex closure is 531889eabcffSMatthew G. Knepley 531989eabcffSMatthew G. Knepley {c, 532089eabcffSMatthew G. Knepley f_b, f_t, f_f, f_b, f_r, f_l, 532189eabcffSMatthew 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, 532289eabcffSMatthew G. Knepley v_blf, v_blb, v_brb, v_brf, v_tlf, v_trf, v_trb, v_tlb} 532389eabcffSMatthew G. Knepley */ 53249e8305c2SJed Brown ierr = PetscSectionFieldGetTensorDegree_Private(section,f,eStart,vertexchart,&Nc,&k);CHKERRQ(ierr); 532589eabcffSMatthew G. Knepley /* The SEM order is 532689eabcffSMatthew G. Knepley Bottom Slice 532789eabcffSMatthew G. Knepley v_blf, {e^{(k-1)-n}_bf}, v_brf, 532889eabcffSMatthew G. Knepley e^{i}_bl, f^{n*(k-1)+(k-1)-i}_b, e^{(k-1)-i}_br, 532989eabcffSMatthew G. Knepley v_blb, {e_bb}, v_brb, 533089eabcffSMatthew G. Knepley 533189eabcffSMatthew G. Knepley Middle Slice (j) 533289eabcffSMatthew G. Knepley {e^{(k-1)-j}_lf}, {f^{j*(k-1)+n}_f}, e^j_rf, 533389eabcffSMatthew G. Knepley f^{i*(k-1)+j}_l, {c^{(j*(k-1) + i)*(k-1)+n}_t}, f^{j*(k-1)+i}_r, 533489eabcffSMatthew G. Knepley e^j_lb, {f^{j*(k-1)+(k-1)-n}_b}, e^{(k-1)-j}_rb, 533589eabcffSMatthew G. Knepley 533689eabcffSMatthew G. Knepley Top Slice 533789eabcffSMatthew G. Knepley v_tlf, {e_tf}, v_trf, 533889eabcffSMatthew G. Knepley e^{(k-1)-i}_tl, {f^{i*(k-1)}_t}, e^{i}_tr, 533989eabcffSMatthew G. Knepley v_tlb, {e^{(k-1)-n}_tb}, v_trb, 534089eabcffSMatthew G. Knepley */ 534189eabcffSMatthew G. Knepley { 534289eabcffSMatthew G. Knepley const PetscInt oc = 0; 534389eabcffSMatthew G. Knepley const PetscInt ofb = oc + PetscSqr(k-1)*(k-1); 534489eabcffSMatthew G. Knepley const PetscInt oft = ofb + PetscSqr(k-1); 534589eabcffSMatthew G. Knepley const PetscInt off = oft + PetscSqr(k-1); 534689eabcffSMatthew G. Knepley const PetscInt ofk = off + PetscSqr(k-1); 534789eabcffSMatthew G. Knepley const PetscInt ofr = ofk + PetscSqr(k-1); 534889eabcffSMatthew G. Knepley const PetscInt ofl = ofr + PetscSqr(k-1); 534989eabcffSMatthew G. Knepley const PetscInt oebl = ofl + PetscSqr(k-1); 535089eabcffSMatthew G. Knepley const PetscInt oebb = oebl + (k-1); 535189eabcffSMatthew G. Knepley const PetscInt oebr = oebb + (k-1); 535289eabcffSMatthew G. Knepley const PetscInt oebf = oebr + (k-1); 535389eabcffSMatthew G. Knepley const PetscInt oetf = oebf + (k-1); 535489eabcffSMatthew G. Knepley const PetscInt oetr = oetf + (k-1); 535589eabcffSMatthew G. Knepley const PetscInt oetb = oetr + (k-1); 535689eabcffSMatthew G. Knepley const PetscInt oetl = oetb + (k-1); 535789eabcffSMatthew G. Knepley const PetscInt oerf = oetl + (k-1); 535889eabcffSMatthew G. Knepley const PetscInt oelf = oerf + (k-1); 535989eabcffSMatthew G. Knepley const PetscInt oelb = oelf + (k-1); 536089eabcffSMatthew G. Knepley const PetscInt oerb = oelb + (k-1); 536189eabcffSMatthew G. Knepley const PetscInt ovblf = oerb + (k-1); 536289eabcffSMatthew G. Knepley const PetscInt ovblb = ovblf + 1; 536389eabcffSMatthew G. Knepley const PetscInt ovbrb = ovblb + 1; 536489eabcffSMatthew G. Knepley const PetscInt ovbrf = ovbrb + 1; 536589eabcffSMatthew G. Knepley const PetscInt ovtlf = ovbrf + 1; 536689eabcffSMatthew G. Knepley const PetscInt ovtrf = ovtlf + 1; 536789eabcffSMatthew G. Knepley const PetscInt ovtrb = ovtrf + 1; 536889eabcffSMatthew G. Knepley const PetscInt ovtlb = ovtrb + 1; 536989eabcffSMatthew G. Knepley PetscInt o, n; 537089eabcffSMatthew G. Knepley 537189eabcffSMatthew G. Knepley /* Bottom Slice */ 537289eabcffSMatthew G. Knepley /* bottom */ 537389eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovblf*Nc + c + foffset; 537489eabcffSMatthew G. Knepley for (o = oetf-1; o >= oebf; --o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 537589eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovbrf*Nc + c + foffset; 537689eabcffSMatthew G. Knepley /* middle */ 537789eabcffSMatthew G. Knepley for (i = 0; i < k-1; ++i) { 537889eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oebl+i)*Nc + c + foffset; 5379316b7f87SMax 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;} 538089eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oebr+(k-2)-i)*Nc + c + foffset; 53813194fc30SMatthew G. Knepley } 538289eabcffSMatthew G. Knepley /* top */ 538389eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovblb*Nc + c + foffset; 538489eabcffSMatthew G. Knepley for (o = oebb; o < oebr; ++o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 538589eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovbrb*Nc + c + foffset; 538689eabcffSMatthew G. Knepley 538789eabcffSMatthew G. Knepley /* Middle Slice */ 538889eabcffSMatthew G. Knepley for (j = 0; j < k-1; ++j) { 538989eabcffSMatthew G. Knepley /* bottom */ 539089eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oelf+(k-2)-j)*Nc + c + foffset; 539189eabcffSMatthew 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; 539289eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oerf+j)*Nc + c + foffset; 539389eabcffSMatthew G. Knepley /* middle */ 539489eabcffSMatthew G. Knepley for (i = 0; i < k-1; ++i) { 539589eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (ofl+i*(k-1)+j)*Nc + c + foffset; 539689eabcffSMatthew 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; 539789eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (ofr+j*(k-1)+i)*Nc + c + foffset; 539889eabcffSMatthew G. Knepley } 539989eabcffSMatthew G. Knepley /* top */ 540089eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oelb+j)*Nc + c + foffset; 540189eabcffSMatthew 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; 540289eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oerb+(k-2)-j)*Nc + c + foffset; 540389eabcffSMatthew G. Knepley } 540489eabcffSMatthew G. Knepley 540589eabcffSMatthew G. Knepley /* Top Slice */ 540689eabcffSMatthew G. Knepley /* bottom */ 540789eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovtlf*Nc + c + foffset; 540889eabcffSMatthew G. Knepley for (o = oetf; o < oetr; ++o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 540989eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovtrf*Nc + c + foffset; 541089eabcffSMatthew G. Knepley /* middle */ 541189eabcffSMatthew G. Knepley for (i = 0; i < k-1; ++i) { 541289eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oetl+(k-2)-i)*Nc + c + foffset; 541389eabcffSMatthew 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; 541489eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oetr+i)*Nc + c + foffset; 541589eabcffSMatthew G. Knepley } 541689eabcffSMatthew G. Knepley /* top */ 541789eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovtlb*Nc + c + foffset; 541889eabcffSMatthew G. Knepley for (o = oetl-1; o >= oetb; --o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 541989eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovtrb*Nc + c + foffset; 542089eabcffSMatthew G. Knepley 542189eabcffSMatthew G. Knepley foffset = offset; 542289eabcffSMatthew G. Knepley } 542389eabcffSMatthew G. Knepley break; 542498921bdaSJacob Faibussowitsch default: SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "No spectral ordering for dimension %D", d); 542589eabcffSMatthew G. Knepley } 542689eabcffSMatthew G. Knepley } 54272c71b3e2SJacob Faibussowitsch PetscCheckFalse(offset != size,PetscObjectComm((PetscObject) dm), PETSC_ERR_PLIB, "Number of permutation entries %D != %D", offset, size); 54283194fc30SMatthew G. Knepley /* Check permutation */ 54293194fc30SMatthew G. Knepley { 54303194fc30SMatthew G. Knepley PetscInt *check; 54313194fc30SMatthew G. Knepley 54323194fc30SMatthew G. Knepley ierr = PetscMalloc1(size, &check);CHKERRQ(ierr); 54332c71b3e2SJacob Faibussowitsch for (i = 0; i < size; ++i) {check[i] = -1; PetscCheckFalse(perm[i] < 0 || perm[i] >= size,PetscObjectComm((PetscObject) dm), PETSC_ERR_PLIB, "Invalid permutation index p[%D] = %D", i, perm[i]);} 54343194fc30SMatthew G. Knepley for (i = 0; i < size; ++i) check[perm[i]] = i; 54352c71b3e2SJacob Faibussowitsch for (i = 0; i < size; ++i) {PetscCheckFalse(check[i] < 0,PetscObjectComm((PetscObject) dm), PETSC_ERR_PLIB, "Missing permutation index %D", i);} 54363194fc30SMatthew G. Knepley ierr = PetscFree(check);CHKERRQ(ierr); 54373194fc30SMatthew G. Knepley } 5438bb197d40SJed Brown ierr = PetscSectionSetClosurePermutation_Internal(section, (PetscObject) dm, d, size, PETSC_OWN_POINTER, perm);CHKERRQ(ierr); 5439a05c9aa3SJed Brown if (d == dim) { // Add permutation for localized (in case this is a coordinate DM) 5440a05c9aa3SJed Brown PetscInt *loc_perm; 5441a05c9aa3SJed Brown ierr = PetscMalloc1(size*2, &loc_perm);CHKERRQ(ierr); 5442a05c9aa3SJed Brown for (PetscInt i=0; i<size; i++) { 5443a05c9aa3SJed Brown loc_perm[i] = perm[i]; 5444a05c9aa3SJed Brown loc_perm[size+i] = size + perm[i]; 5445a05c9aa3SJed Brown } 5446a05c9aa3SJed Brown ierr = PetscSectionSetClosurePermutation_Internal(section, (PetscObject) dm, d, size*2, PETSC_OWN_POINTER, loc_perm);CHKERRQ(ierr); 5447a05c9aa3SJed Brown } 5448bb197d40SJed Brown } 54493194fc30SMatthew G. Knepley PetscFunctionReturn(0); 54503194fc30SMatthew G. Knepley } 54513194fc30SMatthew G. Knepley 5452e071409bSToby Isaac PetscErrorCode DMPlexGetPointDualSpaceFEM(DM dm, PetscInt point, PetscInt field, PetscDualSpace *dspace) 5453e071409bSToby Isaac { 5454e071409bSToby Isaac PetscDS prob; 5455e071409bSToby Isaac PetscInt depth, Nf, h; 5456e071409bSToby Isaac DMLabel label; 5457e071409bSToby Isaac PetscErrorCode ierr; 5458e071409bSToby Isaac 5459e071409bSToby Isaac PetscFunctionBeginHot; 5460e5e52638SMatthew G. Knepley ierr = DMGetDS(dm, &prob);CHKERRQ(ierr); 5461e071409bSToby Isaac Nf = prob->Nf; 5462e071409bSToby Isaac label = dm->depthLabel; 5463e071409bSToby Isaac *dspace = NULL; 5464e071409bSToby Isaac if (field < Nf) { 5465e071409bSToby Isaac PetscObject disc = prob->disc[field]; 5466e071409bSToby Isaac 5467e071409bSToby Isaac if (disc->classid == PETSCFE_CLASSID) { 5468e071409bSToby Isaac PetscDualSpace dsp; 5469e071409bSToby Isaac 5470e071409bSToby Isaac ierr = PetscFEGetDualSpace((PetscFE)disc,&dsp);CHKERRQ(ierr); 5471e071409bSToby Isaac ierr = DMLabelGetNumValues(label,&depth);CHKERRQ(ierr); 5472e071409bSToby Isaac ierr = DMLabelGetValue(label,point,&h);CHKERRQ(ierr); 5473e071409bSToby Isaac h = depth - 1 - h; 5474e071409bSToby Isaac if (h) { 5475e071409bSToby Isaac ierr = PetscDualSpaceGetHeightSubspace(dsp,h,dspace);CHKERRQ(ierr); 5476e071409bSToby Isaac } else { 5477e071409bSToby Isaac *dspace = dsp; 5478e071409bSToby Isaac } 5479e071409bSToby Isaac } 5480e071409bSToby Isaac } 5481e071409bSToby Isaac PetscFunctionReturn(0); 5482e071409bSToby Isaac } 5483e071409bSToby Isaac 54849fbee547SJacob Faibussowitsch static inline PetscErrorCode DMPlexVecGetClosure_Depth1_Static(DM dm, PetscSection section, Vec v, PetscInt point, PetscInt *csize, PetscScalar *values[]) 5485a6dfd86eSKarl Rupp { 5486552f7358SJed Brown PetscScalar *array, *vArray; 5487d9917b9dSMatthew G. Knepley const PetscInt *cone, *coneO; 54881a271a75SMatthew G. Knepley PetscInt pStart, pEnd, p, numPoints, size = 0, offset = 0; 5489552f7358SJed Brown PetscErrorCode ierr; 5490552f7358SJed Brown 54911b406b76SMatthew G. Knepley PetscFunctionBeginHot; 54922a3aaacfSMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 54935a1bb5cfSMatthew G. Knepley ierr = DMPlexGetConeSize(dm, point, &numPoints);CHKERRQ(ierr); 54945a1bb5cfSMatthew G. Knepley ierr = DMPlexGetCone(dm, point, &cone);CHKERRQ(ierr); 54955a1bb5cfSMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, point, &coneO);CHKERRQ(ierr); 54963f7cbbe7SMatthew G. Knepley if (!values || !*values) { 54979df71ca4SMatthew G. Knepley if ((point >= pStart) && (point < pEnd)) { 54989df71ca4SMatthew G. Knepley PetscInt dof; 5499d9917b9dSMatthew G. Knepley 55009df71ca4SMatthew G. Knepley ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 55019df71ca4SMatthew G. Knepley size += dof; 55029df71ca4SMatthew G. Knepley } 55039df71ca4SMatthew G. Knepley for (p = 0; p < numPoints; ++p) { 55049df71ca4SMatthew G. Knepley const PetscInt cp = cone[p]; 55052a3aaacfSMatthew G. Knepley PetscInt dof; 55065a1bb5cfSMatthew G. Knepley 55075a1bb5cfSMatthew G. Knepley if ((cp < pStart) || (cp >= pEnd)) continue; 55082a3aaacfSMatthew G. Knepley ierr = PetscSectionGetDof(section, cp, &dof);CHKERRQ(ierr); 55095a1bb5cfSMatthew G. Knepley size += dof; 55105a1bb5cfSMatthew G. Knepley } 55113f7cbbe7SMatthew G. Knepley if (!values) { 55123f7cbbe7SMatthew G. Knepley if (csize) *csize = size; 55133f7cbbe7SMatthew G. Knepley PetscFunctionReturn(0); 55143f7cbbe7SMatthew G. Knepley } 551569291d52SBarry Smith ierr = DMGetWorkArray(dm, size, MPIU_SCALAR, &array);CHKERRQ(ierr); 5516982e9ed1SMatthew G. Knepley } else { 5517982e9ed1SMatthew G. Knepley array = *values; 5518982e9ed1SMatthew G. Knepley } 55199df71ca4SMatthew G. Knepley size = 0; 55205a1bb5cfSMatthew G. Knepley ierr = VecGetArray(v, &vArray);CHKERRQ(ierr); 55219df71ca4SMatthew G. Knepley if ((point >= pStart) && (point < pEnd)) { 55229df71ca4SMatthew G. Knepley PetscInt dof, off, d; 55239df71ca4SMatthew G. Knepley PetscScalar *varr; 5524d9917b9dSMatthew G. Knepley 55259df71ca4SMatthew G. Knepley ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 55269df71ca4SMatthew G. Knepley ierr = PetscSectionGetOffset(section, point, &off);CHKERRQ(ierr); 55279df71ca4SMatthew G. Knepley varr = &vArray[off]; 55281a271a75SMatthew G. Knepley for (d = 0; d < dof; ++d, ++offset) { 55291a271a75SMatthew G. Knepley array[offset] = varr[d]; 55309df71ca4SMatthew G. Knepley } 55319df71ca4SMatthew G. Knepley size += dof; 55329df71ca4SMatthew G. Knepley } 55339df71ca4SMatthew G. Knepley for (p = 0; p < numPoints; ++p) { 55349df71ca4SMatthew G. Knepley const PetscInt cp = cone[p]; 55359df71ca4SMatthew G. Knepley PetscInt o = coneO[p]; 55365a1bb5cfSMatthew G. Knepley PetscInt dof, off, d; 55375a1bb5cfSMatthew G. Knepley PetscScalar *varr; 55385a1bb5cfSMatthew G. Knepley 553952ed52e8SMatthew G. Knepley if ((cp < pStart) || (cp >= pEnd)) continue; 55405a1bb5cfSMatthew G. Knepley ierr = PetscSectionGetDof(section, cp, &dof);CHKERRQ(ierr); 55415a1bb5cfSMatthew G. Knepley ierr = PetscSectionGetOffset(section, cp, &off);CHKERRQ(ierr); 55425a1bb5cfSMatthew G. Knepley varr = &vArray[off]; 55435a1bb5cfSMatthew G. Knepley if (o >= 0) { 55441a271a75SMatthew G. Knepley for (d = 0; d < dof; ++d, ++offset) { 55451a271a75SMatthew G. Knepley array[offset] = varr[d]; 55465a1bb5cfSMatthew G. Knepley } 55475a1bb5cfSMatthew G. Knepley } else { 55481a271a75SMatthew G. Knepley for (d = dof-1; d >= 0; --d, ++offset) { 55491a271a75SMatthew G. Knepley array[offset] = varr[d]; 55505a1bb5cfSMatthew G. Knepley } 55515a1bb5cfSMatthew G. Knepley } 55529df71ca4SMatthew G. Knepley size += dof; 55535a1bb5cfSMatthew G. Knepley } 55545a1bb5cfSMatthew G. Knepley ierr = VecRestoreArray(v, &vArray);CHKERRQ(ierr); 55559df71ca4SMatthew G. Knepley if (!*values) { 55565a1bb5cfSMatthew G. Knepley if (csize) *csize = size; 55575a1bb5cfSMatthew G. Knepley *values = array; 55589df71ca4SMatthew G. Knepley } else { 55592c71b3e2SJacob Faibussowitsch PetscCheckFalse(size > *csize,PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Size of input array %D < actual size %D", *csize, size); 55608c312ff3SMatthew G. Knepley *csize = size; 55619df71ca4SMatthew G. Knepley } 55625a1bb5cfSMatthew G. Knepley PetscFunctionReturn(0); 55635a1bb5cfSMatthew G. Knepley } 5564d9917b9dSMatthew G. Knepley 556527f02ce8SMatthew G. Knepley /* Compress out points not in the section */ 55669fbee547SJacob Faibussowitsch static inline PetscErrorCode CompressPoints_Private(PetscSection section, PetscInt *numPoints, PetscInt points[]) 556727f02ce8SMatthew G. Knepley { 556827f02ce8SMatthew G. Knepley const PetscInt np = *numPoints; 556927f02ce8SMatthew G. Knepley PetscInt pStart, pEnd, p, q; 557027f02ce8SMatthew G. Knepley PetscErrorCode ierr; 557127f02ce8SMatthew G. Knepley 557227f02ce8SMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 557327f02ce8SMatthew G. Knepley for (p = 0, q = 0; p < np; ++p) { 557427f02ce8SMatthew G. Knepley const PetscInt r = points[p*2]; 557527f02ce8SMatthew G. Knepley if ((r >= pStart) && (r < pEnd)) { 557627f02ce8SMatthew G. Knepley points[q*2] = r; 557727f02ce8SMatthew G. Knepley points[q*2+1] = points[p*2+1]; 557827f02ce8SMatthew G. Knepley ++q; 557927f02ce8SMatthew G. Knepley } 558027f02ce8SMatthew G. Knepley } 558127f02ce8SMatthew G. Knepley *numPoints = q; 558227f02ce8SMatthew G. Knepley return 0; 558327f02ce8SMatthew G. Knepley } 558427f02ce8SMatthew G. Knepley 558597529cf3SJed Brown /* Compressed closure does not apply closure permutation */ 55861dc59d61SMatthew G. Knepley PetscErrorCode DMPlexGetCompressedClosure(DM dm, PetscSection section, PetscInt point, PetscInt *numPoints, PetscInt **points, PetscSection *clSec, IS *clPoints, const PetscInt **clp) 5587923c78e0SToby Isaac { 558827f02ce8SMatthew G. Knepley const PetscInt *cla = NULL; 5589923c78e0SToby Isaac PetscInt np, *pts = NULL; 5590923c78e0SToby Isaac PetscErrorCode ierr; 5591923c78e0SToby Isaac 5592923c78e0SToby Isaac PetscFunctionBeginHot; 5593923c78e0SToby Isaac ierr = PetscSectionGetClosureIndex(section, (PetscObject) dm, clSec, clPoints);CHKERRQ(ierr); 559427f02ce8SMatthew G. Knepley if (*clPoints) { 5595923c78e0SToby Isaac PetscInt dof, off; 5596923c78e0SToby Isaac 5597923c78e0SToby Isaac ierr = PetscSectionGetDof(*clSec, point, &dof);CHKERRQ(ierr); 5598923c78e0SToby Isaac ierr = PetscSectionGetOffset(*clSec, point, &off);CHKERRQ(ierr); 5599923c78e0SToby Isaac ierr = ISGetIndices(*clPoints, &cla);CHKERRQ(ierr); 5600923c78e0SToby Isaac np = dof/2; 5601923c78e0SToby Isaac pts = (PetscInt *) &cla[off]; 560227f02ce8SMatthew G. Knepley } else { 560327f02ce8SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, point, PETSC_TRUE, &np, &pts);CHKERRQ(ierr); 560427f02ce8SMatthew G. Knepley ierr = CompressPoints_Private(section, &np, pts);CHKERRQ(ierr); 5605923c78e0SToby Isaac } 5606923c78e0SToby Isaac *numPoints = np; 5607923c78e0SToby Isaac *points = pts; 5608923c78e0SToby Isaac *clp = cla; 5609923c78e0SToby Isaac PetscFunctionReturn(0); 5610923c78e0SToby Isaac } 5611923c78e0SToby Isaac 56121dc59d61SMatthew G. Knepley PetscErrorCode DMPlexRestoreCompressedClosure(DM dm, PetscSection section, PetscInt point, PetscInt *numPoints, PetscInt **points, PetscSection *clSec, IS *clPoints, const PetscInt **clp) 5613923c78e0SToby Isaac { 5614923c78e0SToby Isaac PetscErrorCode ierr; 5615923c78e0SToby Isaac 5616923c78e0SToby Isaac PetscFunctionBeginHot; 5617923c78e0SToby Isaac if (!*clPoints) { 5618923c78e0SToby Isaac ierr = DMPlexRestoreTransitiveClosure(dm, point, PETSC_TRUE, numPoints, points);CHKERRQ(ierr); 5619923c78e0SToby Isaac } else { 5620923c78e0SToby Isaac ierr = ISRestoreIndices(*clPoints, clp);CHKERRQ(ierr); 5621923c78e0SToby Isaac } 5622923c78e0SToby Isaac *numPoints = 0; 5623923c78e0SToby Isaac *points = NULL; 5624923c78e0SToby Isaac *clSec = NULL; 5625923c78e0SToby Isaac *clPoints = NULL; 5626923c78e0SToby Isaac *clp = NULL; 5627923c78e0SToby Isaac PetscFunctionReturn(0); 5628923c78e0SToby Isaac } 5629923c78e0SToby Isaac 56309fbee547SJacob Faibussowitsch static inline PetscErrorCode DMPlexVecGetClosure_Static(DM dm, PetscSection section, PetscInt numPoints, const PetscInt points[], const PetscInt clperm[], const PetscScalar vArray[], PetscInt *size, PetscScalar array[]) 56311a271a75SMatthew G. Knepley { 56321a271a75SMatthew G. Knepley PetscInt offset = 0, p; 563397e99dd9SToby Isaac const PetscInt **perms = NULL; 563497e99dd9SToby Isaac const PetscScalar **flips = NULL; 56351a271a75SMatthew G. Knepley PetscErrorCode ierr; 56361a271a75SMatthew G. Knepley 56371a271a75SMatthew G. Knepley PetscFunctionBeginHot; 5638fe02ba77SJed Brown *size = 0; 563997e99dd9SToby Isaac ierr = PetscSectionGetPointSyms(section,numPoints,points,&perms,&flips);CHKERRQ(ierr); 564097e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 564197e99dd9SToby Isaac const PetscInt point = points[2*p]; 564297e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 564397e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 56441a271a75SMatthew G. Knepley PetscInt dof, off, d; 56451a271a75SMatthew G. Knepley const PetscScalar *varr; 56461a271a75SMatthew G. Knepley 56471a271a75SMatthew G. Knepley ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 56481a271a75SMatthew G. Knepley ierr = PetscSectionGetOffset(section, point, &off);CHKERRQ(ierr); 56491a271a75SMatthew G. Knepley varr = &vArray[off]; 565097e99dd9SToby Isaac if (clperm) { 565197e99dd9SToby Isaac if (perm) { 565297e99dd9SToby Isaac for (d = 0; d < dof; d++) array[clperm[offset + perm[d]]] = varr[d]; 56531a271a75SMatthew G. Knepley } else { 565497e99dd9SToby Isaac for (d = 0; d < dof; d++) array[clperm[offset + d ]] = varr[d]; 565597e99dd9SToby Isaac } 565697e99dd9SToby Isaac if (flip) { 565797e99dd9SToby Isaac for (d = 0; d < dof; d++) array[clperm[offset + d ]] *= flip[d]; 565897e99dd9SToby Isaac } 565997e99dd9SToby Isaac } else { 566097e99dd9SToby Isaac if (perm) { 566197e99dd9SToby Isaac for (d = 0; d < dof; d++) array[offset + perm[d]] = varr[d]; 566297e99dd9SToby Isaac } else { 566397e99dd9SToby Isaac for (d = 0; d < dof; d++) array[offset + d ] = varr[d]; 566497e99dd9SToby Isaac } 566597e99dd9SToby Isaac if (flip) { 566697e99dd9SToby Isaac for (d = 0; d < dof; d++) array[offset + d ] *= flip[d]; 56671a271a75SMatthew G. Knepley } 56681a271a75SMatthew G. Knepley } 566997e99dd9SToby Isaac offset += dof; 567097e99dd9SToby Isaac } 567197e99dd9SToby Isaac ierr = PetscSectionRestorePointSyms(section,numPoints,points,&perms,&flips);CHKERRQ(ierr); 56721a271a75SMatthew G. Knepley *size = offset; 56731a271a75SMatthew G. Knepley PetscFunctionReturn(0); 56741a271a75SMatthew G. Knepley } 56751a271a75SMatthew G. Knepley 56769fbee547SJacob Faibussowitsch 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[]) 56771a271a75SMatthew G. Knepley { 56781a271a75SMatthew G. Knepley PetscInt offset = 0, f; 56791a271a75SMatthew G. Knepley PetscErrorCode ierr; 56801a271a75SMatthew G. Knepley 56811a271a75SMatthew G. Knepley PetscFunctionBeginHot; 5682fe02ba77SJed Brown *size = 0; 56831a271a75SMatthew G. Knepley for (f = 0; f < numFields; ++f) { 568497e99dd9SToby Isaac PetscInt p; 568597e99dd9SToby Isaac const PetscInt **perms = NULL; 568697e99dd9SToby Isaac const PetscScalar **flips = NULL; 56871a271a75SMatthew G. Knepley 568897e99dd9SToby Isaac ierr = PetscSectionGetFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 568997e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 569097e99dd9SToby Isaac const PetscInt point = points[2*p]; 569197e99dd9SToby Isaac PetscInt fdof, foff, b; 56921a271a75SMatthew G. Knepley const PetscScalar *varr; 569397e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 569497e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 56951a271a75SMatthew G. Knepley 56961a271a75SMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 56971a271a75SMatthew G. Knepley ierr = PetscSectionGetFieldOffset(section, point, f, &foff);CHKERRQ(ierr); 56981a271a75SMatthew G. Knepley varr = &vArray[foff]; 569997e99dd9SToby Isaac if (clperm) { 570097e99dd9SToby Isaac if (perm) {for (b = 0; b < fdof; b++) {array[clperm[offset + perm[b]]] = varr[b];}} 570197e99dd9SToby Isaac else {for (b = 0; b < fdof; b++) {array[clperm[offset + b ]] = varr[b];}} 570297e99dd9SToby Isaac if (flip) {for (b = 0; b < fdof; b++) {array[clperm[offset + b ]] *= flip[b];}} 57031a271a75SMatthew G. Knepley } else { 570497e99dd9SToby Isaac if (perm) {for (b = 0; b < fdof; b++) {array[offset + perm[b]] = varr[b];}} 570597e99dd9SToby Isaac else {for (b = 0; b < fdof; b++) {array[offset + b ] = varr[b];}} 570697e99dd9SToby Isaac if (flip) {for (b = 0; b < fdof; b++) {array[offset + b ] *= flip[b];}} 57071a271a75SMatthew G. Knepley } 570897e99dd9SToby Isaac offset += fdof; 57091a271a75SMatthew G. Knepley } 571097e99dd9SToby Isaac ierr = PetscSectionRestoreFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 57111a271a75SMatthew G. Knepley } 57121a271a75SMatthew G. Knepley *size = offset; 57131a271a75SMatthew G. Knepley PetscFunctionReturn(0); 57141a271a75SMatthew G. Knepley } 57151a271a75SMatthew G. Knepley 5716552f7358SJed Brown /*@C 5717552f7358SJed Brown DMPlexVecGetClosure - Get an array of the values on the closure of 'point' 5718552f7358SJed Brown 5719552f7358SJed Brown Not collective 5720552f7358SJed Brown 5721552f7358SJed Brown Input Parameters: 5722552f7358SJed Brown + dm - The DM 5723552f7358SJed Brown . section - The section describing the layout in v, or NULL to use the default section 5724552f7358SJed Brown . v - The local vector 57256b867d5aSJose E. Roman - point - The point in the DM 5726552f7358SJed Brown 57276b867d5aSJose E. Roman Input/Output Parameters: 57286b867d5aSJose E. Roman + csize - The size of the input values array, or NULL; on output the number of values in the closure 57296b867d5aSJose E. Roman - values - An array to use for the values, or NULL to have it allocated automatically; 57306b867d5aSJose E. Roman if the user provided NULL, it is a borrowed array and should not be freed 573122c1ee49SMatthew G. Knepley 573222c1ee49SMatthew G. Knepley $ Note that DMPlexVecGetClosure/DMPlexVecRestoreClosure only allocates the values array if it set to NULL in the 573322c1ee49SMatthew G. Knepley $ calling function. This is because DMPlexVecGetClosure() is typically called in the inner loop of a Vec or Mat 573422c1ee49SMatthew G. Knepley $ assembly function, and a user may already have allocated storage for this operation. 573522c1ee49SMatthew G. Knepley $ 573622c1ee49SMatthew G. Knepley $ A typical use could be 573722c1ee49SMatthew G. Knepley $ 573822c1ee49SMatthew G. Knepley $ values = NULL; 573922c1ee49SMatthew G. Knepley $ ierr = DMPlexVecGetClosure(dm, NULL, v, p, &clSize, &values);CHKERRQ(ierr); 574022c1ee49SMatthew G. Knepley $ for (cl = 0; cl < clSize; ++cl) { 574122c1ee49SMatthew G. Knepley $ <Compute on closure> 574222c1ee49SMatthew G. Knepley $ } 574322c1ee49SMatthew G. Knepley $ ierr = DMPlexVecRestoreClosure(dm, NULL, v, p, &clSize, &values);CHKERRQ(ierr); 574422c1ee49SMatthew G. Knepley $ 574522c1ee49SMatthew G. Knepley $ or 574622c1ee49SMatthew G. Knepley $ 574722c1ee49SMatthew G. Knepley $ PetscMalloc1(clMaxSize, &values); 574822c1ee49SMatthew G. Knepley $ for (p = pStart; p < pEnd; ++p) { 574922c1ee49SMatthew G. Knepley $ clSize = clMaxSize; 575022c1ee49SMatthew G. Knepley $ ierr = DMPlexVecGetClosure(dm, NULL, v, p, &clSize, &values);CHKERRQ(ierr); 575122c1ee49SMatthew G. Knepley $ for (cl = 0; cl < clSize; ++cl) { 575222c1ee49SMatthew G. Knepley $ <Compute on closure> 575322c1ee49SMatthew G. Knepley $ } 575422c1ee49SMatthew G. Knepley $ } 575522c1ee49SMatthew G. Knepley $ PetscFree(values); 5756552f7358SJed Brown 5757552f7358SJed Brown Fortran Notes: 5758552f7358SJed Brown Since it returns an array, this routine is only available in Fortran 90, and you must 5759552f7358SJed Brown include petsc.h90 in your code. 5760552f7358SJed Brown 5761552f7358SJed Brown The csize argument is not present in the Fortran 90 binding since it is internal to the array. 5762552f7358SJed Brown 5763552f7358SJed Brown Level: intermediate 5764552f7358SJed Brown 5765552f7358SJed Brown .seealso DMPlexVecRestoreClosure(), DMPlexVecSetClosure(), DMPlexMatSetClosure() 5766552f7358SJed Brown @*/ 5767552f7358SJed Brown PetscErrorCode DMPlexVecGetClosure(DM dm, PetscSection section, Vec v, PetscInt point, PetscInt *csize, PetscScalar *values[]) 5768552f7358SJed Brown { 5769552f7358SJed Brown PetscSection clSection; 5770d9917b9dSMatthew G. Knepley IS clPoints; 5771552f7358SJed Brown PetscInt *points = NULL; 5772c459fbc1SJed Brown const PetscInt *clp, *perm; 5773c459fbc1SJed Brown PetscInt depth, numFields, numPoints, asize; 5774552f7358SJed Brown PetscErrorCode ierr; 5775552f7358SJed Brown 5776d9917b9dSMatthew G. Knepley PetscFunctionBeginHot; 5777552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 577892fd8e1eSJed Brown if (!section) {ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr);} 57791a271a75SMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 57801a271a75SMatthew G. Knepley PetscValidHeaderSpecific(v, VEC_CLASSID, 3); 5781552f7358SJed Brown ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 5782552f7358SJed Brown ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 5783552f7358SJed Brown if (depth == 1 && numFields < 2) { 57841a271a75SMatthew G. Knepley ierr = DMPlexVecGetClosure_Depth1_Static(dm, section, v, point, csize, values);CHKERRQ(ierr); 5785552f7358SJed Brown PetscFunctionReturn(0); 5786552f7358SJed Brown } 57871a271a75SMatthew G. Knepley /* Get points */ 5788923c78e0SToby Isaac ierr = DMPlexGetCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 5789c459fbc1SJed Brown /* Get sizes */ 5790c459fbc1SJed Brown asize = 0; 5791c459fbc1SJed Brown for (PetscInt p = 0; p < numPoints*2; p += 2) { 5792c459fbc1SJed Brown PetscInt dof; 5793552f7358SJed Brown ierr = PetscSectionGetDof(section, points[p], &dof);CHKERRQ(ierr); 57941a271a75SMatthew G. Knepley asize += dof; 5795552f7358SJed Brown } 5796c459fbc1SJed Brown if (values) { 5797c459fbc1SJed Brown const PetscScalar *vArray; 5798c459fbc1SJed Brown PetscInt size; 5799c459fbc1SJed Brown 5800c459fbc1SJed Brown if (*values) { 58012c71b3e2SJacob Faibussowitsch PetscCheckFalse(*csize < asize,PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Provided array size %D not sufficient to hold closure size %D", *csize, asize); 5802c459fbc1SJed Brown } else {ierr = DMGetWorkArray(dm, asize, MPIU_SCALAR, values);CHKERRQ(ierr);} 5803c459fbc1SJed Brown ierr = PetscSectionGetClosureInversePermutation_Internal(section, (PetscObject) dm, depth, asize, &perm);CHKERRQ(ierr); 58048a84db2dSMatthew G. Knepley ierr = VecGetArrayRead(v, &vArray);CHKERRQ(ierr); 58051a271a75SMatthew G. Knepley /* Get values */ 5806c459fbc1SJed Brown if (numFields > 0) {ierr = DMPlexVecGetClosure_Fields_Static(dm, section, numPoints, points, numFields, perm, vArray, &size, *values);CHKERRQ(ierr);} 5807c459fbc1SJed Brown else {ierr = DMPlexVecGetClosure_Static(dm, section, numPoints, points, perm, vArray, &size, *values);CHKERRQ(ierr);} 58082c71b3e2SJacob Faibussowitsch PetscCheckFalse(asize != size,PETSC_COMM_SELF, PETSC_ERR_PLIB, "Section size %D does not match Vec closure size %D", asize, size); 58091a271a75SMatthew G. Knepley /* Cleanup array */ 58108a84db2dSMatthew G. Knepley ierr = VecRestoreArrayRead(v, &vArray);CHKERRQ(ierr); 5811d0f6b257SMatthew G. Knepley } 5812c459fbc1SJed Brown if (csize) *csize = asize; 5813c459fbc1SJed Brown /* Cleanup points */ 5814c459fbc1SJed Brown ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 5815552f7358SJed Brown PetscFunctionReturn(0); 5816552f7358SJed Brown } 5817552f7358SJed Brown 5818e5c487bfSMatthew G. Knepley PetscErrorCode DMPlexVecGetClosureAtDepth_Internal(DM dm, PetscSection section, Vec v, PetscInt point, PetscInt depth, PetscInt *csize, PetscScalar *values[]) 5819e5c487bfSMatthew G. Knepley { 5820e5c487bfSMatthew G. Knepley DMLabel depthLabel; 5821e5c487bfSMatthew G. Knepley PetscSection clSection; 5822e5c487bfSMatthew G. Knepley IS clPoints; 5823e5c487bfSMatthew G. Knepley PetscScalar *array; 5824e5c487bfSMatthew G. Knepley const PetscScalar *vArray; 5825e5c487bfSMatthew G. Knepley PetscInt *points = NULL; 5826c459fbc1SJed Brown const PetscInt *clp, *perm = NULL; 5827c459fbc1SJed Brown PetscInt mdepth, numFields, numPoints, Np = 0, p, clsize, size; 5828e5c487bfSMatthew G. Knepley PetscErrorCode ierr; 5829e5c487bfSMatthew G. Knepley 5830e5c487bfSMatthew G. Knepley PetscFunctionBeginHot; 5831e5c487bfSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5832e5c487bfSMatthew G. Knepley if (!section) {ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr);} 5833e5c487bfSMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 5834e5c487bfSMatthew G. Knepley PetscValidHeaderSpecific(v, VEC_CLASSID, 3); 5835e5c487bfSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &mdepth);CHKERRQ(ierr); 5836e5c487bfSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &depthLabel);CHKERRQ(ierr); 5837e5c487bfSMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 5838e5c487bfSMatthew G. Knepley if (mdepth == 1 && numFields < 2) { 5839e5c487bfSMatthew G. Knepley ierr = DMPlexVecGetClosure_Depth1_Static(dm, section, v, point, csize, values);CHKERRQ(ierr); 5840e5c487bfSMatthew G. Knepley PetscFunctionReturn(0); 5841e5c487bfSMatthew G. Knepley } 5842e5c487bfSMatthew G. Knepley /* Get points */ 5843e5c487bfSMatthew G. Knepley ierr = DMPlexGetCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 5844c459fbc1SJed Brown for (clsize=0,p=0; p<Np; p++) { 5845c459fbc1SJed Brown PetscInt dof; 5846c459fbc1SJed Brown ierr = PetscSectionGetDof(section, points[2*p], &dof);CHKERRQ(ierr); 5847c459fbc1SJed Brown clsize += dof; 5848c459fbc1SJed Brown } 5849c459fbc1SJed Brown ierr = PetscSectionGetClosureInversePermutation_Internal(section, (PetscObject) dm, depth, clsize, &perm);CHKERRQ(ierr); 5850e5c487bfSMatthew G. Knepley /* Filter points */ 5851e5c487bfSMatthew G. Knepley for (p = 0; p < numPoints*2; p += 2) { 5852e5c487bfSMatthew G. Knepley PetscInt dep; 5853e5c487bfSMatthew G. Knepley 5854e5c487bfSMatthew G. Knepley ierr = DMLabelGetValue(depthLabel, points[p], &dep);CHKERRQ(ierr); 5855e5c487bfSMatthew G. Knepley if (dep != depth) continue; 5856e5c487bfSMatthew G. Knepley points[Np*2+0] = points[p]; 5857e5c487bfSMatthew G. Knepley points[Np*2+1] = points[p+1]; 5858e5c487bfSMatthew G. Knepley ++Np; 5859e5c487bfSMatthew G. Knepley } 5860e5c487bfSMatthew G. Knepley /* Get array */ 5861e5c487bfSMatthew G. Knepley if (!values || !*values) { 5862e5c487bfSMatthew G. Knepley PetscInt asize = 0, dof; 5863e5c487bfSMatthew G. Knepley 5864e5c487bfSMatthew G. Knepley for (p = 0; p < Np*2; p += 2) { 5865e5c487bfSMatthew G. Knepley ierr = PetscSectionGetDof(section, points[p], &dof);CHKERRQ(ierr); 5866e5c487bfSMatthew G. Knepley asize += dof; 5867e5c487bfSMatthew G. Knepley } 5868e5c487bfSMatthew G. Knepley if (!values) { 5869e5c487bfSMatthew G. Knepley ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 5870e5c487bfSMatthew G. Knepley if (csize) *csize = asize; 5871e5c487bfSMatthew G. Knepley PetscFunctionReturn(0); 5872e5c487bfSMatthew G. Knepley } 5873e5c487bfSMatthew G. Knepley ierr = DMGetWorkArray(dm, asize, MPIU_SCALAR, &array);CHKERRQ(ierr); 5874e5c487bfSMatthew G. Knepley } else { 5875e5c487bfSMatthew G. Knepley array = *values; 5876e5c487bfSMatthew G. Knepley } 5877e5c487bfSMatthew G. Knepley ierr = VecGetArrayRead(v, &vArray);CHKERRQ(ierr); 5878e5c487bfSMatthew G. Knepley /* Get values */ 5879e5c487bfSMatthew G. Knepley if (numFields > 0) {ierr = DMPlexVecGetClosure_Fields_Static(dm, section, Np, points, numFields, perm, vArray, &size, array);CHKERRQ(ierr);} 5880e5c487bfSMatthew G. Knepley else {ierr = DMPlexVecGetClosure_Static(dm, section, Np, points, perm, vArray, &size, array);CHKERRQ(ierr);} 5881e5c487bfSMatthew G. Knepley /* Cleanup points */ 5882e5c487bfSMatthew G. Knepley ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 5883e5c487bfSMatthew G. Knepley /* Cleanup array */ 5884e5c487bfSMatthew G. Knepley ierr = VecRestoreArrayRead(v, &vArray);CHKERRQ(ierr); 5885e5c487bfSMatthew G. Knepley if (!*values) { 5886e5c487bfSMatthew G. Knepley if (csize) *csize = size; 5887e5c487bfSMatthew G. Knepley *values = array; 5888e5c487bfSMatthew G. Knepley } else { 58892c71b3e2SJacob Faibussowitsch PetscCheckFalse(size > *csize,PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Size of input array %D < actual size %D", *csize, size); 5890e5c487bfSMatthew G. Knepley *csize = size; 5891e5c487bfSMatthew G. Knepley } 5892e5c487bfSMatthew G. Knepley PetscFunctionReturn(0); 5893e5c487bfSMatthew G. Knepley } 5894e5c487bfSMatthew G. Knepley 5895552f7358SJed Brown /*@C 5896552f7358SJed Brown DMPlexVecRestoreClosure - Restore the array of the values on the closure of 'point' 5897552f7358SJed Brown 5898552f7358SJed Brown Not collective 5899552f7358SJed Brown 5900552f7358SJed Brown Input Parameters: 5901552f7358SJed Brown + dm - The DM 59020298fd71SBarry Smith . section - The section describing the layout in v, or NULL to use the default section 5903552f7358SJed Brown . v - The local vector 5904eaf898f9SPatrick Sanan . point - The point in the DM 59050298fd71SBarry Smith . csize - The number of values in the closure, or NULL 5906552f7358SJed Brown - values - The array of values, which is a borrowed array and should not be freed 5907552f7358SJed Brown 590822c1ee49SMatthew 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() 590922c1ee49SMatthew G. Knepley 59103813dfbdSMatthew G Knepley Fortran Notes: 59113813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 59123813dfbdSMatthew G Knepley include petsc.h90 in your code. 59133813dfbdSMatthew G Knepley 59143813dfbdSMatthew G Knepley The csize argument is not present in the Fortran 90 binding since it is internal to the array. 59153813dfbdSMatthew G Knepley 5916552f7358SJed Brown Level: intermediate 5917552f7358SJed Brown 5918552f7358SJed Brown .seealso DMPlexVecGetClosure(), DMPlexVecSetClosure(), DMPlexMatSetClosure() 5919552f7358SJed Brown @*/ 59207c1f9639SMatthew G Knepley PetscErrorCode DMPlexVecRestoreClosure(DM dm, PetscSection section, Vec v, PetscInt point, PetscInt *csize, PetscScalar *values[]) 5921a6dfd86eSKarl Rupp { 5922552f7358SJed Brown PetscInt size = 0; 5923552f7358SJed Brown PetscErrorCode ierr; 5924552f7358SJed Brown 5925552f7358SJed Brown PetscFunctionBegin; 5926552f7358SJed Brown /* Should work without recalculating size */ 592769291d52SBarry Smith ierr = DMRestoreWorkArray(dm, size, MPIU_SCALAR, (void*) values);CHKERRQ(ierr); 5928c9fdaa05SMatthew G. Knepley *values = NULL; 5929552f7358SJed Brown PetscFunctionReturn(0); 5930552f7358SJed Brown } 5931552f7358SJed Brown 59329fbee547SJacob Faibussowitsch static inline void add (PetscScalar *x, PetscScalar y) {*x += y;} 59339fbee547SJacob Faibussowitsch static inline void insert(PetscScalar *x, PetscScalar y) {*x = y;} 5934552f7358SJed Brown 59359fbee547SJacob Faibussowitsch 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[]) 5936552f7358SJed Brown { 5937552f7358SJed Brown PetscInt cdof; /* The number of constraints on this point */ 5938552f7358SJed Brown const PetscInt *cdofs; /* The indices of the constrained dofs on this point */ 5939552f7358SJed Brown PetscScalar *a; 5940552f7358SJed Brown PetscInt off, cind = 0, k; 5941552f7358SJed Brown PetscErrorCode ierr; 5942552f7358SJed Brown 5943552f7358SJed Brown PetscFunctionBegin; 5944552f7358SJed Brown ierr = PetscSectionGetConstraintDof(section, point, &cdof);CHKERRQ(ierr); 5945552f7358SJed Brown ierr = PetscSectionGetOffset(section, point, &off);CHKERRQ(ierr); 5946552f7358SJed Brown a = &array[off]; 5947552f7358SJed Brown if (!cdof || setBC) { 594897e99dd9SToby Isaac if (clperm) { 594997e99dd9SToby Isaac if (perm) {for (k = 0; k < dof; ++k) {fuse(&a[k], values[clperm[offset+perm[k]]] * (flip ? flip[perm[k]] : 1.));}} 595097e99dd9SToby Isaac else {for (k = 0; k < dof; ++k) {fuse(&a[k], values[clperm[offset+ k ]] * (flip ? flip[ k ] : 1.));}} 5951552f7358SJed Brown } else { 595297e99dd9SToby Isaac if (perm) {for (k = 0; k < dof; ++k) {fuse(&a[k], values[offset+perm[k]] * (flip ? flip[perm[k]] : 1.));}} 595397e99dd9SToby Isaac else {for (k = 0; k < dof; ++k) {fuse(&a[k], values[offset+ k ] * (flip ? flip[ k ] : 1.));}} 5954552f7358SJed Brown } 5955552f7358SJed Brown } else { 5956552f7358SJed Brown ierr = PetscSectionGetConstraintIndices(section, point, &cdofs);CHKERRQ(ierr); 595797e99dd9SToby Isaac if (clperm) { 595897e99dd9SToby Isaac if (perm) {for (k = 0; k < dof; ++k) { 5959552f7358SJed Brown if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 596097e99dd9SToby Isaac fuse(&a[k], values[clperm[offset+perm[k]]] * (flip ? flip[perm[k]] : 1.)); 5961552f7358SJed Brown } 5962552f7358SJed Brown } else { 5963552f7358SJed Brown for (k = 0; k < dof; ++k) { 5964552f7358SJed Brown if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 596597e99dd9SToby Isaac fuse(&a[k], values[clperm[offset+ k ]] * (flip ? flip[ k ] : 1.)); 596697e99dd9SToby Isaac } 596797e99dd9SToby Isaac } 596897e99dd9SToby Isaac } else { 596997e99dd9SToby Isaac if (perm) { 597097e99dd9SToby Isaac for (k = 0; k < dof; ++k) { 597197e99dd9SToby Isaac if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 597297e99dd9SToby Isaac fuse(&a[k], values[offset+perm[k]] * (flip ? flip[perm[k]] : 1.)); 597397e99dd9SToby Isaac } 597497e99dd9SToby Isaac } else { 597597e99dd9SToby Isaac for (k = 0; k < dof; ++k) { 597697e99dd9SToby Isaac if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 597797e99dd9SToby Isaac fuse(&a[k], values[offset+ k ] * (flip ? flip[ k ] : 1.)); 597897e99dd9SToby Isaac } 5979552f7358SJed Brown } 5980552f7358SJed Brown } 5981552f7358SJed Brown } 5982552f7358SJed Brown PetscFunctionReturn(0); 5983552f7358SJed Brown } 5984552f7358SJed Brown 59859fbee547SJacob Faibussowitsch 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[]) 5986a5e93ea8SMatthew G. Knepley { 5987a5e93ea8SMatthew G. Knepley PetscInt cdof; /* The number of constraints on this point */ 5988a5e93ea8SMatthew G. Knepley const PetscInt *cdofs; /* The indices of the constrained dofs on this point */ 5989a5e93ea8SMatthew G. Knepley PetscScalar *a; 5990a5e93ea8SMatthew G. Knepley PetscInt off, cind = 0, k; 5991a5e93ea8SMatthew G. Knepley PetscErrorCode ierr; 5992a5e93ea8SMatthew G. Knepley 5993a5e93ea8SMatthew G. Knepley PetscFunctionBegin; 5994a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(section, point, &cdof);CHKERRQ(ierr); 5995a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetOffset(section, point, &off);CHKERRQ(ierr); 5996a5e93ea8SMatthew G. Knepley a = &array[off]; 5997a5e93ea8SMatthew G. Knepley if (cdof) { 5998a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetConstraintIndices(section, point, &cdofs);CHKERRQ(ierr); 599997e99dd9SToby Isaac if (clperm) { 600097e99dd9SToby Isaac if (perm) { 6001a5e93ea8SMatthew G. Knepley for (k = 0; k < dof; ++k) { 6002a5e93ea8SMatthew G. Knepley if ((cind < cdof) && (k == cdofs[cind])) { 600397e99dd9SToby Isaac fuse(&a[k], values[clperm[offset+perm[k]]] * (flip ? flip[perm[k]] : 1.)); 600497e99dd9SToby Isaac cind++; 6005a5e93ea8SMatthew G. Knepley } 6006a5e93ea8SMatthew G. Knepley } 6007a5e93ea8SMatthew G. Knepley } else { 6008a5e93ea8SMatthew G. Knepley for (k = 0; k < dof; ++k) { 6009a5e93ea8SMatthew G. Knepley if ((cind < cdof) && (k == cdofs[cind])) { 601097e99dd9SToby Isaac fuse(&a[k], values[clperm[offset+ k ]] * (flip ? flip[ k ] : 1.)); 601197e99dd9SToby Isaac cind++; 601297e99dd9SToby Isaac } 601397e99dd9SToby Isaac } 601497e99dd9SToby Isaac } 601597e99dd9SToby Isaac } else { 601697e99dd9SToby Isaac if (perm) { 601797e99dd9SToby Isaac for (k = 0; k < dof; ++k) { 601897e99dd9SToby Isaac if ((cind < cdof) && (k == cdofs[cind])) { 601997e99dd9SToby Isaac fuse(&a[k], values[offset+perm[k]] * (flip ? flip[perm[k]] : 1.)); 602097e99dd9SToby Isaac cind++; 602197e99dd9SToby Isaac } 602297e99dd9SToby Isaac } 602397e99dd9SToby Isaac } else { 602497e99dd9SToby Isaac for (k = 0; k < dof; ++k) { 602597e99dd9SToby Isaac if ((cind < cdof) && (k == cdofs[cind])) { 602697e99dd9SToby Isaac fuse(&a[k], values[offset+ k ] * (flip ? flip[ k ] : 1.)); 602797e99dd9SToby Isaac cind++; 602897e99dd9SToby Isaac } 6029a5e93ea8SMatthew G. Knepley } 6030a5e93ea8SMatthew G. Knepley } 6031a5e93ea8SMatthew G. Knepley } 6032a5e93ea8SMatthew G. Knepley } 6033a5e93ea8SMatthew G. Knepley PetscFunctionReturn(0); 6034a5e93ea8SMatthew G. Knepley } 6035a5e93ea8SMatthew G. Knepley 60369fbee547SJacob Faibussowitsch 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[]) 6037a6dfd86eSKarl Rupp { 6038552f7358SJed Brown PetscScalar *a; 60391a271a75SMatthew G. Knepley PetscInt fdof, foff, fcdof, foffset = *offset; 60401a271a75SMatthew G. Knepley const PetscInt *fcdofs; /* The indices of the constrained dofs for field f on this point */ 604197e99dd9SToby Isaac PetscInt cind = 0, b; 6042552f7358SJed Brown PetscErrorCode ierr; 6043552f7358SJed Brown 6044552f7358SJed Brown PetscFunctionBegin; 6045552f7358SJed Brown ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 6046552f7358SJed Brown ierr = PetscSectionGetFieldConstraintDof(section, point, f, &fcdof);CHKERRQ(ierr); 60471a271a75SMatthew G. Knepley ierr = PetscSectionGetFieldOffset(section, point, f, &foff);CHKERRQ(ierr); 60481a271a75SMatthew G. Knepley a = &array[foff]; 6049552f7358SJed Brown if (!fcdof || setBC) { 605097e99dd9SToby Isaac if (clperm) { 605197e99dd9SToby Isaac if (perm) {for (b = 0; b < fdof; b++) {fuse(&a[b], values[clperm[foffset+perm[b]]] * (flip ? flip[perm[b]] : 1.));}} 605297e99dd9SToby Isaac else {for (b = 0; b < fdof; b++) {fuse(&a[b], values[clperm[foffset+ b ]] * (flip ? flip[ b ] : 1.));}} 6053552f7358SJed Brown } else { 605497e99dd9SToby Isaac if (perm) {for (b = 0; b < fdof; b++) {fuse(&a[b], values[foffset+perm[b]] * (flip ? flip[perm[b]] : 1.));}} 605597e99dd9SToby Isaac else {for (b = 0; b < fdof; b++) {fuse(&a[b], values[foffset+ b ] * (flip ? flip[ b ] : 1.));}} 6056552f7358SJed Brown } 6057552f7358SJed Brown } else { 6058552f7358SJed Brown ierr = PetscSectionGetFieldConstraintIndices(section, point, f, &fcdofs);CHKERRQ(ierr); 605997e99dd9SToby Isaac if (clperm) { 606097e99dd9SToby Isaac if (perm) { 606197e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 606297e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; continue;} 606397e99dd9SToby Isaac fuse(&a[b], values[clperm[foffset+perm[b]]] * (flip ? flip[perm[b]] : 1.)); 6064552f7358SJed Brown } 6065552f7358SJed Brown } else { 606697e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 606797e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; continue;} 606897e99dd9SToby Isaac fuse(&a[b], values[clperm[foffset+ b ]] * (flip ? flip[ b ] : 1.)); 606997e99dd9SToby Isaac } 607097e99dd9SToby Isaac } 607197e99dd9SToby Isaac } else { 607297e99dd9SToby Isaac if (perm) { 607397e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 607497e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; continue;} 607597e99dd9SToby Isaac fuse(&a[b], values[foffset+perm[b]] * (flip ? flip[perm[b]] : 1.)); 607697e99dd9SToby Isaac } 607797e99dd9SToby Isaac } else { 607897e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 607997e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; continue;} 608097e99dd9SToby Isaac fuse(&a[b], values[foffset+ b ] * (flip ? flip[ b ] : 1.)); 6081552f7358SJed Brown } 6082552f7358SJed Brown } 6083552f7358SJed Brown } 6084552f7358SJed Brown } 60851a271a75SMatthew G. Knepley *offset += fdof; 6086552f7358SJed Brown PetscFunctionReturn(0); 6087552f7358SJed Brown } 6088552f7358SJed Brown 60899fbee547SJacob Faibussowitsch 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[]) 6090a5e93ea8SMatthew G. Knepley { 6091a5e93ea8SMatthew G. Knepley PetscScalar *a; 60921a271a75SMatthew G. Knepley PetscInt fdof, foff, fcdof, foffset = *offset; 60931a271a75SMatthew G. Knepley const PetscInt *fcdofs; /* The indices of the constrained dofs for field f on this point */ 60945da9d227SMatthew G. Knepley PetscInt Nc, cind = 0, ncind = 0, b; 6095ba322698SMatthew G. Knepley PetscBool ncSet, fcSet; 6096a5e93ea8SMatthew G. Knepley PetscErrorCode ierr; 6097a5e93ea8SMatthew G. Knepley 6098a5e93ea8SMatthew G. Knepley PetscFunctionBegin; 60995da9d227SMatthew G. Knepley ierr = PetscSectionGetFieldComponents(section, f, &Nc);CHKERRQ(ierr); 6100a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 6101a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetFieldConstraintDof(section, point, f, &fcdof);CHKERRQ(ierr); 61021a271a75SMatthew G. Knepley ierr = PetscSectionGetFieldOffset(section, point, f, &foff);CHKERRQ(ierr); 61031a271a75SMatthew G. Knepley a = &array[foff]; 6104a5e93ea8SMatthew G. Knepley if (fcdof) { 6105ba322698SMatthew G. Knepley /* We just override fcdof and fcdofs with Ncc and comps */ 6106a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetFieldConstraintIndices(section, point, f, &fcdofs);CHKERRQ(ierr); 610797e99dd9SToby Isaac if (clperm) { 610897e99dd9SToby Isaac if (perm) { 6109ba322698SMatthew G. Knepley if (comps) { 6110ba322698SMatthew G. Knepley for (b = 0; b < fdof; b++) { 6111ba322698SMatthew G. Knepley ncSet = fcSet = PETSC_FALSE; 61125da9d227SMatthew G. Knepley if (b%Nc == comps[ncind]) {ncind = (ncind+1)%Ncc; ncSet = PETSC_TRUE;} 6113ba322698SMatthew G. Knepley if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; fcSet = PETSC_TRUE;} 6114ba322698SMatthew G. Knepley if (ncSet && fcSet) {fuse(&a[b], values[clperm[foffset+perm[b]]] * (flip ? flip[perm[b]] : 1.));} 6115ba322698SMatthew G. Knepley } 6116ba322698SMatthew G. Knepley } else { 611797e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 611897e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) { 611997e99dd9SToby Isaac fuse(&a[b], values[clperm[foffset+perm[b]]] * (flip ? flip[perm[b]] : 1.)); 6120a5e93ea8SMatthew G. Knepley ++cind; 6121a5e93ea8SMatthew G. Knepley } 6122a5e93ea8SMatthew G. Knepley } 6123ba322698SMatthew G. Knepley } 6124ba322698SMatthew G. Knepley } else { 6125ba322698SMatthew G. Knepley if (comps) { 6126ba322698SMatthew G. Knepley for (b = 0; b < fdof; b++) { 6127ba322698SMatthew G. Knepley ncSet = fcSet = PETSC_FALSE; 61285da9d227SMatthew G. Knepley if (b%Nc == comps[ncind]) {ncind = (ncind+1)%Ncc; ncSet = PETSC_TRUE;} 6129ba322698SMatthew G. Knepley if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; fcSet = PETSC_TRUE;} 6130ba322698SMatthew G. Knepley if (ncSet && fcSet) {fuse(&a[b], values[clperm[foffset+ b ]] * (flip ? flip[ b ] : 1.));} 6131ba322698SMatthew G. Knepley } 6132a5e93ea8SMatthew G. Knepley } else { 613397e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 613497e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) { 613597e99dd9SToby Isaac fuse(&a[b], values[clperm[foffset+ b ]] * (flip ? flip[ b ] : 1.)); 613697e99dd9SToby Isaac ++cind; 613797e99dd9SToby Isaac } 613897e99dd9SToby Isaac } 613997e99dd9SToby Isaac } 6140ba322698SMatthew G. Knepley } 614197e99dd9SToby Isaac } else { 614297e99dd9SToby Isaac if (perm) { 6143ba322698SMatthew G. Knepley if (comps) { 6144ba322698SMatthew G. Knepley for (b = 0; b < fdof; b++) { 6145ba322698SMatthew G. Knepley ncSet = fcSet = PETSC_FALSE; 61465da9d227SMatthew G. Knepley if (b%Nc == comps[ncind]) {ncind = (ncind+1)%Ncc; ncSet = PETSC_TRUE;} 6147ba322698SMatthew G. Knepley if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; fcSet = PETSC_TRUE;} 6148ba322698SMatthew G. Knepley if (ncSet && fcSet) {fuse(&a[b], values[foffset+perm[b]] * (flip ? flip[perm[b]] : 1.));} 6149ba322698SMatthew G. Knepley } 6150ba322698SMatthew G. Knepley } else { 615197e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 615297e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) { 615397e99dd9SToby Isaac fuse(&a[b], values[foffset+perm[b]] * (flip ? flip[perm[b]] : 1.)); 615497e99dd9SToby Isaac ++cind; 615597e99dd9SToby Isaac } 615697e99dd9SToby Isaac } 6157ba322698SMatthew G. Knepley } 6158ba322698SMatthew G. Knepley } else { 6159ba322698SMatthew G. Knepley if (comps) { 6160ba322698SMatthew G. Knepley for (b = 0; b < fdof; b++) { 6161ba322698SMatthew G. Knepley ncSet = fcSet = PETSC_FALSE; 61625da9d227SMatthew G. Knepley if (b%Nc == comps[ncind]) {ncind = (ncind+1)%Ncc; ncSet = PETSC_TRUE;} 6163ba322698SMatthew G. Knepley if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; fcSet = PETSC_TRUE;} 6164ba322698SMatthew G. Knepley if (ncSet && fcSet) {fuse(&a[b], values[foffset+ b ] * (flip ? flip[ b ] : 1.));} 6165ba322698SMatthew G. Knepley } 616697e99dd9SToby Isaac } else { 616797e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 616897e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) { 616997e99dd9SToby Isaac fuse(&a[b], values[foffset+ b ] * (flip ? flip[ b ] : 1.)); 6170a5e93ea8SMatthew G. Knepley ++cind; 6171a5e93ea8SMatthew G. Knepley } 6172a5e93ea8SMatthew G. Knepley } 6173a5e93ea8SMatthew G. Knepley } 6174a5e93ea8SMatthew G. Knepley } 6175a5e93ea8SMatthew G. Knepley } 6176ba322698SMatthew G. Knepley } 61771a271a75SMatthew G. Knepley *offset += fdof; 6178a5e93ea8SMatthew G. Knepley PetscFunctionReturn(0); 6179a5e93ea8SMatthew G. Knepley } 6180a5e93ea8SMatthew G. Knepley 61819fbee547SJacob Faibussowitsch static inline PetscErrorCode DMPlexVecSetClosure_Depth1_Static(DM dm, PetscSection section, Vec v, PetscInt point, const PetscScalar values[], InsertMode mode) 6182a6dfd86eSKarl Rupp { 6183552f7358SJed Brown PetscScalar *array; 61841b406b76SMatthew G. Knepley const PetscInt *cone, *coneO; 61851b406b76SMatthew G. Knepley PetscInt pStart, pEnd, p, numPoints, off, dof; 6186552f7358SJed Brown PetscErrorCode ierr; 6187552f7358SJed Brown 61881b406b76SMatthew G. Knepley PetscFunctionBeginHot; 6189b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 6190b6ebb6e6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, point, &numPoints);CHKERRQ(ierr); 6191b6ebb6e6SMatthew G. Knepley ierr = DMPlexGetCone(dm, point, &cone);CHKERRQ(ierr); 6192b6ebb6e6SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, point, &coneO);CHKERRQ(ierr); 6193b6ebb6e6SMatthew G. Knepley ierr = VecGetArray(v, &array);CHKERRQ(ierr); 6194b6ebb6e6SMatthew G. Knepley for (p = 0, off = 0; p <= numPoints; ++p, off += dof) { 6195b6ebb6e6SMatthew G. Knepley const PetscInt cp = !p ? point : cone[p-1]; 6196b6ebb6e6SMatthew G. Knepley const PetscInt o = !p ? 0 : coneO[p-1]; 6197b6ebb6e6SMatthew G. Knepley 6198b6ebb6e6SMatthew G. Knepley if ((cp < pStart) || (cp >= pEnd)) {dof = 0; continue;} 6199b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetDof(section, cp, &dof);CHKERRQ(ierr); 6200b6ebb6e6SMatthew G. Knepley /* ADD_VALUES */ 6201b6ebb6e6SMatthew G. Knepley { 6202b6ebb6e6SMatthew G. Knepley const PetscInt *cdofs; /* The indices of the constrained dofs on this point */ 6203b6ebb6e6SMatthew G. Knepley PetscScalar *a; 6204b6ebb6e6SMatthew G. Knepley PetscInt cdof, coff, cind = 0, k; 6205b6ebb6e6SMatthew G. Knepley 6206b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(section, cp, &cdof);CHKERRQ(ierr); 6207b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetOffset(section, cp, &coff);CHKERRQ(ierr); 6208b6ebb6e6SMatthew G. Knepley a = &array[coff]; 6209b6ebb6e6SMatthew G. Knepley if (!cdof) { 6210b6ebb6e6SMatthew G. Knepley if (o >= 0) { 6211b6ebb6e6SMatthew G. Knepley for (k = 0; k < dof; ++k) { 6212b6ebb6e6SMatthew G. Knepley a[k] += values[off+k]; 6213b6ebb6e6SMatthew G. Knepley } 6214b6ebb6e6SMatthew G. Knepley } else { 6215b6ebb6e6SMatthew G. Knepley for (k = 0; k < dof; ++k) { 6216b6ebb6e6SMatthew G. Knepley a[k] += values[off+dof-k-1]; 6217b6ebb6e6SMatthew G. Knepley } 6218b6ebb6e6SMatthew G. Knepley } 6219b6ebb6e6SMatthew G. Knepley } else { 6220b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetConstraintIndices(section, cp, &cdofs);CHKERRQ(ierr); 6221b6ebb6e6SMatthew G. Knepley if (o >= 0) { 6222b6ebb6e6SMatthew G. Knepley for (k = 0; k < dof; ++k) { 6223b6ebb6e6SMatthew G. Knepley if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 6224b6ebb6e6SMatthew G. Knepley a[k] += values[off+k]; 6225b6ebb6e6SMatthew G. Knepley } 6226b6ebb6e6SMatthew G. Knepley } else { 6227b6ebb6e6SMatthew G. Knepley for (k = 0; k < dof; ++k) { 6228b6ebb6e6SMatthew G. Knepley if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 6229b6ebb6e6SMatthew G. Knepley a[k] += values[off+dof-k-1]; 6230b6ebb6e6SMatthew G. Knepley } 6231b6ebb6e6SMatthew G. Knepley } 6232b6ebb6e6SMatthew G. Knepley } 6233b6ebb6e6SMatthew G. Knepley } 6234b6ebb6e6SMatthew G. Knepley } 6235b6ebb6e6SMatthew G. Knepley ierr = VecRestoreArray(v, &array);CHKERRQ(ierr); 6236b6ebb6e6SMatthew G. Knepley PetscFunctionReturn(0); 6237b6ebb6e6SMatthew G. Knepley } 62381b406b76SMatthew G. Knepley 62391b406b76SMatthew G. Knepley /*@C 62401b406b76SMatthew G. Knepley DMPlexVecSetClosure - Set an array of the values on the closure of 'point' 62411b406b76SMatthew G. Knepley 62421b406b76SMatthew G. Knepley Not collective 62431b406b76SMatthew G. Knepley 62441b406b76SMatthew G. Knepley Input Parameters: 62451b406b76SMatthew G. Knepley + dm - The DM 62461b406b76SMatthew G. Knepley . section - The section describing the layout in v, or NULL to use the default section 62471b406b76SMatthew G. Knepley . v - The local vector 6248eaf898f9SPatrick Sanan . point - The point in the DM 62491b406b76SMatthew G. Knepley . values - The array of values 625022c1ee49SMatthew 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, 625122c1ee49SMatthew G. Knepley where INSERT_ALL_VALUES and ADD_ALL_VALUES also overwrite boundary conditions. 62521b406b76SMatthew G. Knepley 62531b406b76SMatthew G. Knepley Fortran Notes: 62541b406b76SMatthew G. Knepley This routine is only available in Fortran 90, and you must include petsc.h90 in your code. 62551b406b76SMatthew G. Knepley 62561b406b76SMatthew G. Knepley Level: intermediate 62571b406b76SMatthew G. Knepley 62581b406b76SMatthew G. Knepley .seealso DMPlexVecGetClosure(), DMPlexMatSetClosure() 62591b406b76SMatthew G. Knepley @*/ 62601b406b76SMatthew G. Knepley PetscErrorCode DMPlexVecSetClosure(DM dm, PetscSection section, Vec v, PetscInt point, const PetscScalar values[], InsertMode mode) 62611b406b76SMatthew G. Knepley { 62621b406b76SMatthew G. Knepley PetscSection clSection; 62631b406b76SMatthew G. Knepley IS clPoints; 62641b406b76SMatthew G. Knepley PetscScalar *array; 62651b406b76SMatthew G. Knepley PetscInt *points = NULL; 626627f02ce8SMatthew G. Knepley const PetscInt *clp, *clperm = NULL; 6267c459fbc1SJed Brown PetscInt depth, numFields, numPoints, p, clsize; 62681b406b76SMatthew G. Knepley PetscErrorCode ierr; 62691b406b76SMatthew G. Knepley 62701a271a75SMatthew G. Knepley PetscFunctionBeginHot; 62711b406b76SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 627292fd8e1eSJed Brown if (!section) {ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr);} 62731a271a75SMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 62741a271a75SMatthew G. Knepley PetscValidHeaderSpecific(v, VEC_CLASSID, 3); 62751b406b76SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 62761b406b76SMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 62771b406b76SMatthew G. Knepley if (depth == 1 && numFields < 2 && mode == ADD_VALUES) { 62788f3be42fSMatthew G. Knepley ierr = DMPlexVecSetClosure_Depth1_Static(dm, section, v, point, values, mode);CHKERRQ(ierr); 62791b406b76SMatthew G. Knepley PetscFunctionReturn(0); 62801b406b76SMatthew G. Knepley } 62811a271a75SMatthew G. Knepley /* Get points */ 6282923c78e0SToby Isaac ierr = DMPlexGetCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 6283c459fbc1SJed Brown for (clsize=0,p=0; p<numPoints; p++) { 6284c459fbc1SJed Brown PetscInt dof; 6285c459fbc1SJed Brown ierr = PetscSectionGetDof(section, points[2*p], &dof);CHKERRQ(ierr); 6286c459fbc1SJed Brown clsize += dof; 6287c459fbc1SJed Brown } 6288c459fbc1SJed Brown ierr = PetscSectionGetClosureInversePermutation_Internal(section, (PetscObject) dm, depth, clsize, &clperm);CHKERRQ(ierr); 62891a271a75SMatthew G. Knepley /* Get array */ 6290552f7358SJed Brown ierr = VecGetArray(v, &array);CHKERRQ(ierr); 62911a271a75SMatthew G. Knepley /* Get values */ 6292ef90cfe2SMatthew G. Knepley if (numFields > 0) { 629397e99dd9SToby Isaac PetscInt offset = 0, f; 6294552f7358SJed Brown for (f = 0; f < numFields; ++f) { 629597e99dd9SToby Isaac const PetscInt **perms = NULL; 629697e99dd9SToby Isaac const PetscScalar **flips = NULL; 629797e99dd9SToby Isaac 629897e99dd9SToby Isaac ierr = PetscSectionGetFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 6299552f7358SJed Brown switch (mode) { 6300552f7358SJed Brown case INSERT_VALUES: 630197e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 630297e99dd9SToby Isaac const PetscInt point = points[2*p]; 630397e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 630497e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 630597e99dd9SToby Isaac updatePointFields_private(section, point, perm, flip, f, insert, PETSC_FALSE, clperm, values, &offset, array); 6306552f7358SJed Brown } break; 6307552f7358SJed Brown case INSERT_ALL_VALUES: 630897e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 630997e99dd9SToby Isaac const PetscInt point = points[2*p]; 631097e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 631197e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 631297e99dd9SToby Isaac updatePointFields_private(section, point, perm, flip, f, insert, PETSC_TRUE, clperm, values, &offset, array); 6313552f7358SJed Brown } break; 6314a5e93ea8SMatthew G. Knepley case INSERT_BC_VALUES: 631597e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 631697e99dd9SToby Isaac const PetscInt point = points[2*p]; 631797e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 631897e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 6319ba322698SMatthew G. Knepley updatePointFieldsBC_private(section, point, perm, flip, f, -1, NULL, insert, clperm, values, &offset, array); 6320a5e93ea8SMatthew G. Knepley } break; 6321552f7358SJed Brown case ADD_VALUES: 632297e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 632397e99dd9SToby Isaac const PetscInt point = points[2*p]; 632497e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 632597e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 632697e99dd9SToby Isaac updatePointFields_private(section, point, perm, flip, f, add, PETSC_FALSE, clperm, values, &offset, array); 6327552f7358SJed Brown } break; 6328552f7358SJed Brown case ADD_ALL_VALUES: 632997e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 633097e99dd9SToby Isaac const PetscInt point = points[2*p]; 633197e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 633297e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 633397e99dd9SToby Isaac updatePointFields_private(section, point, perm, flip, f, add, PETSC_TRUE, clperm, values, &offset, array); 6334552f7358SJed Brown } break; 6335304ab55fSMatthew G. Knepley case ADD_BC_VALUES: 633697e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 633797e99dd9SToby Isaac const PetscInt point = points[2*p]; 633897e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 633997e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 6340ba322698SMatthew G. Knepley updatePointFieldsBC_private(section, point, perm, flip, f, -1, NULL, add, clperm, values, &offset, array); 6341304ab55fSMatthew G. Knepley } break; 6342552f7358SJed Brown default: 634398921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insert mode %d", mode); 6344552f7358SJed Brown } 634597e99dd9SToby Isaac ierr = PetscSectionRestoreFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 63461a271a75SMatthew G. Knepley } 6347552f7358SJed Brown } else { 63481a271a75SMatthew G. Knepley PetscInt dof, off; 634997e99dd9SToby Isaac const PetscInt **perms = NULL; 635097e99dd9SToby Isaac const PetscScalar **flips = NULL; 63511a271a75SMatthew G. Knepley 635297e99dd9SToby Isaac ierr = PetscSectionGetPointSyms(section,numPoints,points,&perms,&flips);CHKERRQ(ierr); 6353552f7358SJed Brown switch (mode) { 6354552f7358SJed Brown case INSERT_VALUES: 635597e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 635697e99dd9SToby Isaac const PetscInt point = points[2*p]; 635797e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 635897e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 635997e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 636097e99dd9SToby Isaac updatePoint_private(section, point, dof, insert, PETSC_FALSE, perm, flip, clperm, values, off, array); 6361552f7358SJed Brown } break; 6362552f7358SJed Brown case INSERT_ALL_VALUES: 636397e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 636497e99dd9SToby Isaac const PetscInt point = points[2*p]; 636597e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 636697e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 636797e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 636897e99dd9SToby Isaac updatePoint_private(section, point, dof, insert, PETSC_TRUE, perm, flip, clperm, values, off, array); 6369552f7358SJed Brown } break; 6370a5e93ea8SMatthew G. Knepley case INSERT_BC_VALUES: 637197e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 637297e99dd9SToby Isaac const PetscInt point = points[2*p]; 637397e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 637497e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 637597e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 637697e99dd9SToby Isaac updatePointBC_private(section, point, dof, insert, perm, flip, clperm, values, off, array); 6377a5e93ea8SMatthew G. Knepley } break; 6378552f7358SJed Brown case ADD_VALUES: 637997e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 638097e99dd9SToby Isaac const PetscInt point = points[2*p]; 638197e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 638297e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 638397e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 638497e99dd9SToby Isaac updatePoint_private(section, point, dof, add, PETSC_FALSE, perm, flip, clperm, values, off, array); 6385552f7358SJed Brown } break; 6386552f7358SJed Brown case ADD_ALL_VALUES: 638797e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 638897e99dd9SToby Isaac const PetscInt point = points[2*p]; 638997e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 639097e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 639197e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 639297e99dd9SToby Isaac updatePoint_private(section, point, dof, add, PETSC_TRUE, perm, flip, clperm, values, off, array); 6393552f7358SJed Brown } break; 6394304ab55fSMatthew G. Knepley case ADD_BC_VALUES: 639597e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 639697e99dd9SToby Isaac const PetscInt point = points[2*p]; 639797e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 639897e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 639997e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 640097e99dd9SToby Isaac updatePointBC_private(section, point, dof, add, perm, flip, clperm, values, off, array); 6401304ab55fSMatthew G. Knepley } break; 6402552f7358SJed Brown default: 640398921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insert mode %d", mode); 6404552f7358SJed Brown } 640597e99dd9SToby Isaac ierr = PetscSectionRestorePointSyms(section,numPoints,points,&perms,&flips);CHKERRQ(ierr); 6406552f7358SJed Brown } 64071a271a75SMatthew G. Knepley /* Cleanup points */ 6408923c78e0SToby Isaac ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 64091a271a75SMatthew G. Knepley /* Cleanup array */ 6410552f7358SJed Brown ierr = VecRestoreArray(v, &array);CHKERRQ(ierr); 6411552f7358SJed Brown PetscFunctionReturn(0); 6412552f7358SJed Brown } 6413552f7358SJed Brown 64145f790a90SMatthew G. Knepley /* Check whether the given point is in the label. If not, update the offset to skip this point */ 64159fbee547SJacob Faibussowitsch static inline PetscErrorCode CheckPoint_Private(DMLabel label, PetscInt labelId, PetscSection section, PetscInt point, PetscInt f, PetscInt *offset) 64165f790a90SMatthew G. Knepley { 64175f790a90SMatthew G. Knepley PetscFunctionBegin; 64185f790a90SMatthew G. Knepley if (label) { 64195f790a90SMatthew G. Knepley PetscInt val, fdof; 64205f790a90SMatthew G. Knepley PetscErrorCode ierr; 64215f790a90SMatthew G. Knepley 64225f790a90SMatthew G. Knepley /* There is a problem with this: 64235f790a90SMatthew G. Knepley Suppose we have two label values, defining surfaces, interecting along a line in 3D. When we add cells to the label, the cells that 64245f790a90SMatthew G. Knepley touch both surfaces must pick a label value. Thus we miss setting values for the surface with that other value intersecting that cell. 64255f790a90SMatthew G. Knepley Thus I am only going to check val != -1, not val != labelId 64265f790a90SMatthew G. Knepley */ 64275f790a90SMatthew G. Knepley ierr = DMLabelGetValue(label, point, &val);CHKERRQ(ierr); 64285f790a90SMatthew G. Knepley if (val < 0) { 64295f790a90SMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 64305f790a90SMatthew G. Knepley *offset += fdof; 64315f790a90SMatthew G. Knepley PetscFunctionReturn(1); 64325f790a90SMatthew G. Knepley } 64335f790a90SMatthew G. Knepley } 64345f790a90SMatthew G. Knepley PetscFunctionReturn(0); 64355f790a90SMatthew G. Knepley } 64365f790a90SMatthew G. Knepley 643797529cf3SJed Brown /* Unlike DMPlexVecSetClosure(), this uses plex-native closure permutation, not a user-specified permutation such as DMPlexSetClosurePermutationTensor(). */ 64385f790a90SMatthew G. Knepley PetscErrorCode DMPlexVecSetFieldClosure_Internal(DM dm, PetscSection section, Vec v, PetscBool fieldActive[], PetscInt point, PetscInt Ncc, const PetscInt comps[], DMLabel label, PetscInt labelId, const PetscScalar values[], InsertMode mode) 6439e07394fbSMatthew G. Knepley { 6440e07394fbSMatthew G. Knepley PetscSection clSection; 6441e07394fbSMatthew G. Knepley IS clPoints; 6442e07394fbSMatthew G. Knepley PetscScalar *array; 6443e07394fbSMatthew G. Knepley PetscInt *points = NULL; 644497529cf3SJed Brown const PetscInt *clp; 6445e07394fbSMatthew G. Knepley PetscInt numFields, numPoints, p; 644697e99dd9SToby Isaac PetscInt offset = 0, f; 6447e07394fbSMatthew G. Knepley PetscErrorCode ierr; 6448e07394fbSMatthew G. Knepley 6449e07394fbSMatthew G. Knepley PetscFunctionBeginHot; 6450e07394fbSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 645192fd8e1eSJed Brown if (!section) {ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr);} 6452e07394fbSMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 6453e07394fbSMatthew G. Knepley PetscValidHeaderSpecific(v, VEC_CLASSID, 3); 6454e07394fbSMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 6455e07394fbSMatthew G. Knepley /* Get points */ 6456923c78e0SToby Isaac ierr = DMPlexGetCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 6457e07394fbSMatthew G. Knepley /* Get array */ 6458e07394fbSMatthew G. Knepley ierr = VecGetArray(v, &array);CHKERRQ(ierr); 6459e07394fbSMatthew G. Knepley /* Get values */ 6460e07394fbSMatthew G. Knepley for (f = 0; f < numFields; ++f) { 646197e99dd9SToby Isaac const PetscInt **perms = NULL; 646297e99dd9SToby Isaac const PetscScalar **flips = NULL; 646397e99dd9SToby Isaac 6464e07394fbSMatthew G. Knepley if (!fieldActive[f]) { 6465e07394fbSMatthew G. Knepley for (p = 0; p < numPoints*2; p += 2) { 6466e07394fbSMatthew G. Knepley PetscInt fdof; 6467e07394fbSMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, points[p], f, &fdof);CHKERRQ(ierr); 6468e07394fbSMatthew G. Knepley offset += fdof; 6469e07394fbSMatthew G. Knepley } 6470e07394fbSMatthew G. Knepley continue; 6471e07394fbSMatthew G. Knepley } 647297e99dd9SToby Isaac ierr = PetscSectionGetFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 6473e07394fbSMatthew G. Knepley switch (mode) { 6474e07394fbSMatthew G. Knepley case INSERT_VALUES: 647597e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 647697e99dd9SToby Isaac const PetscInt point = points[2*p]; 647797e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 647897e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 64795f790a90SMatthew G. Knepley ierr = CheckPoint_Private(label, labelId, section, point, f, &offset); if (ierr) continue; 648097529cf3SJed Brown updatePointFields_private(section, point, perm, flip, f, insert, PETSC_FALSE, NULL, values, &offset, array); 6481e07394fbSMatthew G. Knepley } break; 6482e07394fbSMatthew G. Knepley case INSERT_ALL_VALUES: 648397e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 648497e99dd9SToby Isaac const PetscInt point = points[2*p]; 648597e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 648697e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 64875f790a90SMatthew G. Knepley ierr = CheckPoint_Private(label, labelId, section, point, f, &offset); if (ierr) continue; 648897529cf3SJed Brown updatePointFields_private(section, point, perm, flip, f, insert, PETSC_TRUE, NULL, values, &offset, array); 6489e07394fbSMatthew G. Knepley } break; 6490e07394fbSMatthew G. Knepley case INSERT_BC_VALUES: 649197e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 649297e99dd9SToby Isaac const PetscInt point = points[2*p]; 649397e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 649497e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 64955f790a90SMatthew G. Knepley ierr = CheckPoint_Private(label, labelId, section, point, f, &offset); if (ierr) continue; 649697529cf3SJed Brown updatePointFieldsBC_private(section, point, perm, flip, f, Ncc, comps, insert, NULL, values, &offset, array); 6497e07394fbSMatthew G. Knepley } break; 6498e07394fbSMatthew G. Knepley case ADD_VALUES: 649997e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 650097e99dd9SToby Isaac const PetscInt point = points[2*p]; 650197e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 650297e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 65035f790a90SMatthew G. Knepley ierr = CheckPoint_Private(label, labelId, section, point, f, &offset); if (ierr) continue; 650497529cf3SJed Brown updatePointFields_private(section, point, perm, flip, f, add, PETSC_FALSE, NULL, values, &offset, array); 6505e07394fbSMatthew G. Knepley } break; 6506e07394fbSMatthew G. Knepley case ADD_ALL_VALUES: 650797e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 650897e99dd9SToby Isaac const PetscInt point = points[2*p]; 650997e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 651097e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 65115f790a90SMatthew G. Knepley ierr = CheckPoint_Private(label, labelId, section, point, f, &offset); if (ierr) continue; 651297529cf3SJed Brown updatePointFields_private(section, point, perm, flip, f, add, PETSC_TRUE, NULL, values, &offset, array); 6513e07394fbSMatthew G. Knepley } break; 6514e07394fbSMatthew G. Knepley default: 651598921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insert mode %d", mode); 6516e07394fbSMatthew G. Knepley } 651797e99dd9SToby Isaac ierr = PetscSectionRestoreFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 6518e07394fbSMatthew G. Knepley } 6519e07394fbSMatthew G. Knepley /* Cleanup points */ 6520923c78e0SToby Isaac ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 6521e07394fbSMatthew G. Knepley /* Cleanup array */ 6522e07394fbSMatthew G. Knepley ierr = VecRestoreArray(v, &array);CHKERRQ(ierr); 6523e07394fbSMatthew G. Knepley PetscFunctionReturn(0); 6524e07394fbSMatthew G. Knepley } 6525e07394fbSMatthew G. Knepley 65267cd05799SMatthew G. Knepley static PetscErrorCode DMPlexPrintMatSetValues(PetscViewer viewer, Mat A, PetscInt point, PetscInt numRIndices, const PetscInt rindices[], PetscInt numCIndices, const PetscInt cindices[], const PetscScalar values[]) 6527552f7358SJed Brown { 6528552f7358SJed Brown PetscMPIInt rank; 6529552f7358SJed Brown PetscInt i, j; 6530552f7358SJed Brown PetscErrorCode ierr; 6531552f7358SJed Brown 6532552f7358SJed Brown PetscFunctionBegin; 6533ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)A), &rank);CHKERRMPI(ierr); 6534eaf898f9SPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer, "[%d]mat for point %D\n", rank, point);CHKERRQ(ierr); 6535e4b003c7SBarry Smith for (i = 0; i < numRIndices; i++) {ierr = PetscViewerASCIIPrintf(viewer, "[%d]mat row indices[%D] = %D\n", rank, i, rindices[i]);CHKERRQ(ierr);} 6536e4b003c7SBarry Smith for (i = 0; i < numCIndices; i++) {ierr = PetscViewerASCIIPrintf(viewer, "[%d]mat col indices[%D] = %D\n", rank, i, cindices[i]);CHKERRQ(ierr);} 6537b0ecff45SMatthew G. Knepley numCIndices = numCIndices ? numCIndices : numRIndices; 6538557cf195SMatthew G. Knepley if (!values) PetscFunctionReturn(0); 6539b0ecff45SMatthew G. Knepley for (i = 0; i < numRIndices; i++) { 6540e4b003c7SBarry Smith ierr = PetscViewerASCIIPrintf(viewer, "[%d]", rank);CHKERRQ(ierr); 6541b0ecff45SMatthew G. Knepley for (j = 0; j < numCIndices; j++) { 6542519f805aSKarl Rupp #if defined(PETSC_USE_COMPLEX) 65437eba1a17SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " (%g,%g)", (double)PetscRealPart(values[i*numCIndices+j]), (double)PetscImaginaryPart(values[i*numCIndices+j]));CHKERRQ(ierr); 6544552f7358SJed Brown #else 6545b0ecff45SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " %g", (double)values[i*numCIndices+j]);CHKERRQ(ierr); 6546552f7358SJed Brown #endif 6547552f7358SJed Brown } 654877a6746dSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, "\n");CHKERRQ(ierr); 6549552f7358SJed Brown } 6550552f7358SJed Brown PetscFunctionReturn(0); 6551552f7358SJed Brown } 6552552f7358SJed Brown 655305586334SMatthew G. Knepley /* 655405586334SMatthew G. Knepley DMPlexGetIndicesPoint_Internal - Add the indices for dofs on a point to an index array 655505586334SMatthew G. Knepley 655605586334SMatthew G. Knepley Input Parameters: 655705586334SMatthew G. Knepley + section - The section for this data layout 655836fa2b79SJed Brown . islocal - Is the section (and thus indices being requested) local or global? 655905586334SMatthew G. Knepley . point - The point contributing dofs with these indices 656005586334SMatthew G. Knepley . off - The global offset of this point 656105586334SMatthew G. Knepley . loff - The local offset of each field 6562a5b23f4aSJose E. Roman . setBC - The flag determining whether to include indices of boundary values 656305586334SMatthew G. Knepley . perm - A permutation of the dofs on this point, or NULL 656405586334SMatthew G. Knepley - indperm - A permutation of the entire indices array, or NULL 656505586334SMatthew G. Knepley 656605586334SMatthew G. Knepley Output Parameter: 656705586334SMatthew G. Knepley . indices - Indices for dofs on this point 656805586334SMatthew G. Knepley 656905586334SMatthew G. Knepley Level: developer 657005586334SMatthew G. Knepley 657105586334SMatthew G. Knepley Note: The indices could be local or global, depending on the value of 'off'. 657205586334SMatthew G. Knepley */ 657336fa2b79SJed Brown PetscErrorCode DMPlexGetIndicesPoint_Internal(PetscSection section, PetscBool islocal,PetscInt point, PetscInt off, PetscInt *loff, PetscBool setBC, const PetscInt perm[], const PetscInt indperm[], PetscInt indices[]) 6574a6dfd86eSKarl Rupp { 6575e6ccafaeSMatthew G Knepley PetscInt dof; /* The number of unknowns on this point */ 6576552f7358SJed Brown PetscInt cdof; /* The number of constraints on this point */ 6577552f7358SJed Brown const PetscInt *cdofs; /* The indices of the constrained dofs on this point */ 6578552f7358SJed Brown PetscInt cind = 0, k; 6579552f7358SJed Brown PetscErrorCode ierr; 6580552f7358SJed Brown 6581552f7358SJed Brown PetscFunctionBegin; 65822c71b3e2SJacob Faibussowitsch PetscCheckFalse(!islocal && setBC,PetscObjectComm((PetscObject)section),PETSC_ERR_ARG_INCOMP,"setBC incompatible with global indices; use a local section or disable setBC"); 6583552f7358SJed Brown ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 6584552f7358SJed Brown ierr = PetscSectionGetConstraintDof(section, point, &cdof);CHKERRQ(ierr); 6585552f7358SJed Brown if (!cdof || setBC) { 658605586334SMatthew G. Knepley for (k = 0; k < dof; ++k) { 658705586334SMatthew G. Knepley const PetscInt preind = perm ? *loff+perm[k] : *loff+k; 658805586334SMatthew G. Knepley const PetscInt ind = indperm ? indperm[preind] : preind; 658905586334SMatthew G. Knepley 659005586334SMatthew G. Knepley indices[ind] = off + k; 6591552f7358SJed Brown } 6592552f7358SJed Brown } else { 6593552f7358SJed Brown ierr = PetscSectionGetConstraintIndices(section, point, &cdofs);CHKERRQ(ierr); 65944acb8e1eSToby Isaac for (k = 0; k < dof; ++k) { 659505586334SMatthew G. Knepley const PetscInt preind = perm ? *loff+perm[k] : *loff+k; 659605586334SMatthew G. Knepley const PetscInt ind = indperm ? indperm[preind] : preind; 659705586334SMatthew G. Knepley 65984acb8e1eSToby Isaac if ((cind < cdof) && (k == cdofs[cind])) { 65994acb8e1eSToby Isaac /* Insert check for returning constrained indices */ 660005586334SMatthew G. Knepley indices[ind] = -(off+k+1); 66014acb8e1eSToby Isaac ++cind; 66024acb8e1eSToby Isaac } else { 660336fa2b79SJed Brown indices[ind] = off + k - (islocal ? 0 : cind); 6604552f7358SJed Brown } 6605552f7358SJed Brown } 6606552f7358SJed Brown } 6607e6ccafaeSMatthew G Knepley *loff += dof; 6608552f7358SJed Brown PetscFunctionReturn(0); 6609552f7358SJed Brown } 6610552f7358SJed Brown 66117e29afd2SMatthew G. Knepley /* 661236fa2b79SJed Brown DMPlexGetIndicesPointFields_Internal - gets section indices for a point in its canonical ordering. 66137e29afd2SMatthew G. Knepley 661436fa2b79SJed Brown Input Parameters: 661536fa2b79SJed Brown + section - a section (global or local) 661636fa2b79SJed Brown - islocal - PETSC_TRUE if requesting local indices (i.e., section is local); PETSC_FALSE for global 661736fa2b79SJed Brown . point - point within section 661836fa2b79SJed Brown . off - The offset of this point in the (local or global) indexed space - should match islocal and (usually) the section 661936fa2b79SJed Brown . foffs - array of length numFields containing the offset in canonical point ordering (the location in indices) of each field 662036fa2b79SJed Brown . setBC - identify constrained (boundary condition) points via involution. 662136fa2b79SJed Brown . perms - perms[f][permsoff][:] is a permutation of dofs within each field 662236fa2b79SJed Brown . permsoff - offset 662336fa2b79SJed Brown - indperm - index permutation 662436fa2b79SJed Brown 662536fa2b79SJed Brown Output Parameter: 662636fa2b79SJed Brown . foffs - each entry is incremented by the number of (unconstrained if setBC=FALSE) dofs in that field 662736fa2b79SJed Brown . indices - array to hold indices (as defined by section) of each dof associated with point 662836fa2b79SJed Brown 662936fa2b79SJed Brown Notes: 663036fa2b79SJed Brown If section is local and setBC=true, there is no distinction between constrained and unconstrained dofs. 663136fa2b79SJed Brown If section is local and setBC=false, the indices for constrained points are the involution -(i+1) of their position 663236fa2b79SJed Brown in the local vector. 663336fa2b79SJed Brown 663436fa2b79SJed Brown If section is global and setBC=false, the indices for constrained points are negative (and their value is not 663536fa2b79SJed Brown significant). It is invalid to call with a global section and setBC=true. 663636fa2b79SJed Brown 663736fa2b79SJed Brown Developer Note: 663836fa2b79SJed Brown The section is only used for field layout, so islocal is technically a statement about the offset (off). At some point 663936fa2b79SJed Brown in the future, global sections may have fields set, in which case we could pass the global section and obtain the 664036fa2b79SJed Brown offset could be obtained from the section instead of passing it explicitly as we do now. 664136fa2b79SJed Brown 664236fa2b79SJed Brown Example: 664336fa2b79SJed Brown Suppose a point contains one field with three components, and for which the unconstrained indices are {10, 11, 12}. 664436fa2b79SJed Brown When the middle component is constrained, we get the array {10, -12, 12} for (islocal=TRUE, setBC=FALSE). 664536fa2b79SJed Brown Note that -12 is the involution of 11, so the user can involute negative indices to recover local indices. 664636fa2b79SJed Brown The global vector does not store constrained dofs, so when this function returns global indices, say {110, -112, 111}, the value of -112 is an arbitrary flag that should not be interpreted beyond its sign. 664736fa2b79SJed Brown 664836fa2b79SJed Brown Level: developer 66497e29afd2SMatthew G. Knepley */ 665036fa2b79SJed Brown PetscErrorCode DMPlexGetIndicesPointFields_Internal(PetscSection section, PetscBool islocal, PetscInt point, PetscInt off, PetscInt foffs[], PetscBool setBC, const PetscInt ***perms, PetscInt permsoff, const PetscInt indperm[], PetscInt indices[]) 6651a6dfd86eSKarl Rupp { 6652552f7358SJed Brown PetscInt numFields, foff, f; 6653552f7358SJed Brown PetscErrorCode ierr; 6654552f7358SJed Brown 6655552f7358SJed Brown PetscFunctionBegin; 66562c71b3e2SJacob Faibussowitsch PetscCheckFalse(!islocal && setBC,PetscObjectComm((PetscObject)section),PETSC_ERR_ARG_INCOMP,"setBC incompatible with global indices; use a local section or disable setBC"); 6657552f7358SJed Brown ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 6658552f7358SJed Brown for (f = 0, foff = 0; f < numFields; ++f) { 66594acb8e1eSToby Isaac PetscInt fdof, cfdof; 6660552f7358SJed Brown const PetscInt *fcdofs; /* The indices of the constrained dofs for field f on this point */ 66614acb8e1eSToby Isaac PetscInt cind = 0, b; 66624acb8e1eSToby Isaac const PetscInt *perm = (perms && perms[f]) ? perms[f][permsoff] : NULL; 6663552f7358SJed Brown 6664552f7358SJed Brown ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 6665552f7358SJed Brown ierr = PetscSectionGetFieldConstraintDof(section, point, f, &cfdof);CHKERRQ(ierr); 6666552f7358SJed Brown if (!cfdof || setBC) { 666705586334SMatthew G. Knepley for (b = 0; b < fdof; ++b) { 666805586334SMatthew G. Knepley const PetscInt preind = perm ? foffs[f]+perm[b] : foffs[f]+b; 666905586334SMatthew G. Knepley const PetscInt ind = indperm ? indperm[preind] : preind; 667005586334SMatthew G. Knepley 667105586334SMatthew G. Knepley indices[ind] = off+foff+b; 667205586334SMatthew G. Knepley } 6673552f7358SJed Brown } else { 6674552f7358SJed Brown ierr = PetscSectionGetFieldConstraintIndices(section, point, f, &fcdofs);CHKERRQ(ierr); 667505586334SMatthew G. Knepley for (b = 0; b < fdof; ++b) { 667605586334SMatthew G. Knepley const PetscInt preind = perm ? foffs[f]+perm[b] : foffs[f]+b; 667705586334SMatthew G. Knepley const PetscInt ind = indperm ? indperm[preind] : preind; 667805586334SMatthew G. Knepley 66794acb8e1eSToby Isaac if ((cind < cfdof) && (b == fcdofs[cind])) { 668005586334SMatthew G. Knepley indices[ind] = -(off+foff+b+1); 6681552f7358SJed Brown ++cind; 6682552f7358SJed Brown } else { 668336fa2b79SJed Brown indices[ind] = off + foff + b - (islocal ? 0 : cind); 6684552f7358SJed Brown } 6685552f7358SJed Brown } 6686552f7358SJed Brown } 668736fa2b79SJed Brown foff += (setBC || islocal ? fdof : (fdof - cfdof)); 6688552f7358SJed Brown foffs[f] += fdof; 6689552f7358SJed Brown } 6690552f7358SJed Brown PetscFunctionReturn(0); 6691552f7358SJed Brown } 6692552f7358SJed Brown 66937e29afd2SMatthew G. Knepley /* 66947e29afd2SMatthew G. Knepley This version believes the globalSection offsets for each field, rather than just the point offset 66957e29afd2SMatthew G. Knepley 66967e29afd2SMatthew G. Knepley . foffs - The offset into 'indices' for each field, since it is segregated by field 6697645102dcSJed Brown 6698645102dcSJed Brown Notes: 6699645102dcSJed Brown The semantics of this function relate to that of setBC=FALSE in DMPlexGetIndicesPointFields_Internal. 6700645102dcSJed Brown Since this function uses global indices, setBC=TRUE would be invalid, so no such argument exists. 67017e29afd2SMatthew G. Knepley */ 6702645102dcSJed Brown static PetscErrorCode DMPlexGetIndicesPointFieldsSplit_Internal(PetscSection section, PetscSection globalSection, PetscInt point, PetscInt foffs[], const PetscInt ***perms, PetscInt permsoff, const PetscInt indperm[], PetscInt indices[]) 67037e29afd2SMatthew G. Knepley { 67047e29afd2SMatthew G. Knepley PetscInt numFields, foff, f; 67057e29afd2SMatthew G. Knepley PetscErrorCode ierr; 67067e29afd2SMatthew G. Knepley 67077e29afd2SMatthew G. Knepley PetscFunctionBegin; 67087e29afd2SMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 67097e29afd2SMatthew G. Knepley for (f = 0; f < numFields; ++f) { 67107e29afd2SMatthew G. Knepley PetscInt fdof, cfdof; 67117e29afd2SMatthew G. Knepley const PetscInt *fcdofs; /* The indices of the constrained dofs for field f on this point */ 67127e29afd2SMatthew G. Knepley PetscInt cind = 0, b; 67137e29afd2SMatthew G. Knepley const PetscInt *perm = (perms && perms[f]) ? perms[f][permsoff] : NULL; 67147e29afd2SMatthew G. Knepley 67157e29afd2SMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 67167e29afd2SMatthew G. Knepley ierr = PetscSectionGetFieldConstraintDof(section, point, f, &cfdof);CHKERRQ(ierr); 67177e29afd2SMatthew G. Knepley ierr = PetscSectionGetFieldOffset(globalSection, point, f, &foff);CHKERRQ(ierr); 6718645102dcSJed Brown if (!cfdof) { 671905586334SMatthew G. Knepley for (b = 0; b < fdof; ++b) { 672005586334SMatthew G. Knepley const PetscInt preind = perm ? foffs[f]+perm[b] : foffs[f]+b; 672105586334SMatthew G. Knepley const PetscInt ind = indperm ? indperm[preind] : preind; 672205586334SMatthew G. Knepley 672305586334SMatthew G. Knepley indices[ind] = foff+b; 672405586334SMatthew G. Knepley } 67257e29afd2SMatthew G. Knepley } else { 67267e29afd2SMatthew G. Knepley ierr = PetscSectionGetFieldConstraintIndices(section, point, f, &fcdofs);CHKERRQ(ierr); 672705586334SMatthew G. Knepley for (b = 0; b < fdof; ++b) { 672805586334SMatthew G. Knepley const PetscInt preind = perm ? foffs[f]+perm[b] : foffs[f]+b; 672905586334SMatthew G. Knepley const PetscInt ind = indperm ? indperm[preind] : preind; 673005586334SMatthew G. Knepley 67317e29afd2SMatthew G. Knepley if ((cind < cfdof) && (b == fcdofs[cind])) { 673205586334SMatthew G. Knepley indices[ind] = -(foff+b+1); 67337e29afd2SMatthew G. Knepley ++cind; 67347e29afd2SMatthew G. Knepley } else { 673505586334SMatthew G. Knepley indices[ind] = foff+b-cind; 67367e29afd2SMatthew G. Knepley } 67377e29afd2SMatthew G. Knepley } 67387e29afd2SMatthew G. Knepley } 67397e29afd2SMatthew G. Knepley foffs[f] += fdof; 67407e29afd2SMatthew G. Knepley } 67417e29afd2SMatthew G. Knepley PetscFunctionReturn(0); 67427e29afd2SMatthew G. Knepley } 67437e29afd2SMatthew G. Knepley 67444acb8e1eSToby 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) 6745d3d1a6afSToby Isaac { 6746d3d1a6afSToby Isaac Mat cMat; 6747d3d1a6afSToby Isaac PetscSection aSec, cSec; 6748d3d1a6afSToby Isaac IS aIS; 6749d3d1a6afSToby Isaac PetscInt aStart = -1, aEnd = -1; 6750d3d1a6afSToby Isaac const PetscInt *anchors; 6751e17c06e0SMatthew G. Knepley PetscInt numFields, f, p, q, newP = 0; 6752d3d1a6afSToby Isaac PetscInt newNumPoints = 0, newNumIndices = 0; 6753d3d1a6afSToby Isaac PetscInt *newPoints, *indices, *newIndices; 6754d3d1a6afSToby Isaac PetscInt maxAnchor, maxDof; 6755d3d1a6afSToby Isaac PetscInt newOffsets[32]; 6756d3d1a6afSToby Isaac PetscInt *pointMatOffsets[32]; 6757d3d1a6afSToby Isaac PetscInt *newPointOffsets[32]; 6758d3d1a6afSToby Isaac PetscScalar *pointMat[32]; 67596ecaa68aSToby Isaac PetscScalar *newValues=NULL,*tmpValues; 6760d3d1a6afSToby Isaac PetscBool anyConstrained = PETSC_FALSE; 6761d3d1a6afSToby Isaac PetscErrorCode ierr; 6762d3d1a6afSToby Isaac 6763d3d1a6afSToby Isaac PetscFunctionBegin; 6764d3d1a6afSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6765d3d1a6afSToby Isaac PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 6766d3d1a6afSToby Isaac ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 6767d3d1a6afSToby Isaac 6768a17985deSToby Isaac ierr = DMPlexGetAnchors(dm,&aSec,&aIS);CHKERRQ(ierr); 6769d3d1a6afSToby Isaac /* if there are point-to-point constraints */ 6770d3d1a6afSToby Isaac if (aSec) { 6771580bdb30SBarry Smith ierr = PetscArrayzero(newOffsets, 32);CHKERRQ(ierr); 6772d3d1a6afSToby Isaac ierr = ISGetIndices(aIS,&anchors);CHKERRQ(ierr); 6773d3d1a6afSToby Isaac ierr = PetscSectionGetChart(aSec,&aStart,&aEnd);CHKERRQ(ierr); 6774d3d1a6afSToby Isaac /* figure out how many points are going to be in the new element matrix 6775d3d1a6afSToby Isaac * (we allow double counting, because it's all just going to be summed 6776d3d1a6afSToby Isaac * into the global matrix anyway) */ 6777d3d1a6afSToby Isaac for (p = 0; p < 2*numPoints; p+=2) { 6778d3d1a6afSToby Isaac PetscInt b = points[p]; 67794b2f2278SToby Isaac PetscInt bDof = 0, bSecDof; 6780d3d1a6afSToby Isaac 67814b2f2278SToby Isaac ierr = PetscSectionGetDof(section,b,&bSecDof);CHKERRQ(ierr); 67824b2f2278SToby Isaac if (!bSecDof) { 67834b2f2278SToby Isaac continue; 67844b2f2278SToby Isaac } 6785d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 6786d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec,b,&bDof);CHKERRQ(ierr); 6787d3d1a6afSToby Isaac } 6788d3d1a6afSToby Isaac if (bDof) { 6789d3d1a6afSToby Isaac /* this point is constrained */ 6790d3d1a6afSToby Isaac /* it is going to be replaced by its anchors */ 6791d3d1a6afSToby Isaac PetscInt bOff, q; 6792d3d1a6afSToby Isaac 6793d3d1a6afSToby Isaac anyConstrained = PETSC_TRUE; 6794d3d1a6afSToby Isaac newNumPoints += bDof; 6795d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(aSec,b,&bOff);CHKERRQ(ierr); 6796d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 6797d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q]; 6798d3d1a6afSToby Isaac PetscInt aDof; 6799d3d1a6afSToby Isaac 6800d3d1a6afSToby Isaac ierr = PetscSectionGetDof(section,a,&aDof);CHKERRQ(ierr); 6801d3d1a6afSToby Isaac newNumIndices += aDof; 6802d3d1a6afSToby Isaac for (f = 0; f < numFields; ++f) { 6803d3d1a6afSToby Isaac PetscInt fDof; 6804d3d1a6afSToby Isaac 6805d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, a, f, &fDof);CHKERRQ(ierr); 6806d3d1a6afSToby Isaac newOffsets[f+1] += fDof; 6807d3d1a6afSToby Isaac } 6808d3d1a6afSToby Isaac } 6809d3d1a6afSToby Isaac } 6810d3d1a6afSToby Isaac else { 6811d3d1a6afSToby Isaac /* this point is not constrained */ 6812d3d1a6afSToby Isaac newNumPoints++; 68134b2f2278SToby Isaac newNumIndices += bSecDof; 6814d3d1a6afSToby Isaac for (f = 0; f < numFields; ++f) { 6815d3d1a6afSToby Isaac PetscInt fDof; 6816d3d1a6afSToby Isaac 6817d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, b, f, &fDof);CHKERRQ(ierr); 6818d3d1a6afSToby Isaac newOffsets[f+1] += fDof; 6819d3d1a6afSToby Isaac } 6820d3d1a6afSToby Isaac } 6821d3d1a6afSToby Isaac } 6822d3d1a6afSToby Isaac } 6823d3d1a6afSToby Isaac if (!anyConstrained) { 682472b80496SMatthew G. Knepley if (outNumPoints) *outNumPoints = 0; 682572b80496SMatthew G. Knepley if (outNumIndices) *outNumIndices = 0; 682672b80496SMatthew G. Knepley if (outPoints) *outPoints = NULL; 682772b80496SMatthew G. Knepley if (outValues) *outValues = NULL; 682872b80496SMatthew G. Knepley if (aSec) {ierr = ISRestoreIndices(aIS,&anchors);CHKERRQ(ierr);} 6829d3d1a6afSToby Isaac PetscFunctionReturn(0); 6830d3d1a6afSToby Isaac } 6831d3d1a6afSToby Isaac 68326ecaa68aSToby Isaac if (outNumPoints) *outNumPoints = newNumPoints; 68336ecaa68aSToby Isaac if (outNumIndices) *outNumIndices = newNumIndices; 68346ecaa68aSToby Isaac 6835f13f9184SToby Isaac for (f = 0; f < numFields; ++f) newOffsets[f+1] += newOffsets[f]; 6836d3d1a6afSToby Isaac 68376ecaa68aSToby Isaac if (!outPoints && !outValues) { 68386ecaa68aSToby Isaac if (offsets) { 68396ecaa68aSToby Isaac for (f = 0; f <= numFields; f++) { 68406ecaa68aSToby Isaac offsets[f] = newOffsets[f]; 68416ecaa68aSToby Isaac } 68426ecaa68aSToby Isaac } 68436ecaa68aSToby Isaac if (aSec) {ierr = ISRestoreIndices(aIS,&anchors);CHKERRQ(ierr);} 68446ecaa68aSToby Isaac PetscFunctionReturn(0); 68456ecaa68aSToby Isaac } 68466ecaa68aSToby Isaac 68472c71b3e2SJacob Faibussowitsch PetscCheckFalse(numFields && newOffsets[numFields] != newNumIndices,PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", newOffsets[numFields], newNumIndices); 6848d3d1a6afSToby Isaac 684979769bd5SJed Brown ierr = DMGetDefaultConstraints(dm, &cSec, &cMat, NULL);CHKERRQ(ierr); 6850d3d1a6afSToby Isaac 6851d3d1a6afSToby Isaac /* workspaces */ 6852d3d1a6afSToby Isaac if (numFields) { 6853d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 685469291d52SBarry Smith ierr = DMGetWorkArray(dm,numPoints+1,MPIU_INT,&pointMatOffsets[f]);CHKERRQ(ierr); 685569291d52SBarry Smith ierr = DMGetWorkArray(dm,numPoints+1,MPIU_INT,&newPointOffsets[f]);CHKERRQ(ierr); 6856d3d1a6afSToby Isaac } 6857d3d1a6afSToby Isaac } 6858d3d1a6afSToby Isaac else { 685969291d52SBarry Smith ierr = DMGetWorkArray(dm,numPoints+1,MPIU_INT,&pointMatOffsets[0]);CHKERRQ(ierr); 686069291d52SBarry Smith ierr = DMGetWorkArray(dm,numPoints,MPIU_INT,&newPointOffsets[0]);CHKERRQ(ierr); 6861d3d1a6afSToby Isaac } 6862d3d1a6afSToby Isaac 6863d3d1a6afSToby Isaac /* get workspaces for the point-to-point matrices */ 6864d3d1a6afSToby Isaac if (numFields) { 68654b2f2278SToby Isaac PetscInt totalOffset, totalMatOffset; 68664b2f2278SToby Isaac 6867d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 6868d3d1a6afSToby Isaac PetscInt b = points[2*p]; 68694b2f2278SToby Isaac PetscInt bDof = 0, bSecDof; 6870d3d1a6afSToby Isaac 68714b2f2278SToby Isaac ierr = PetscSectionGetDof(section,b,&bSecDof);CHKERRQ(ierr); 68724b2f2278SToby Isaac if (!bSecDof) { 68734b2f2278SToby Isaac for (f = 0; f < numFields; f++) { 68744b2f2278SToby Isaac newPointOffsets[f][p + 1] = 0; 68754b2f2278SToby Isaac pointMatOffsets[f][p + 1] = 0; 68764b2f2278SToby Isaac } 68774b2f2278SToby Isaac continue; 68784b2f2278SToby Isaac } 6879d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 6880d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec, b, &bDof);CHKERRQ(ierr); 6881d3d1a6afSToby Isaac } 6882d3d1a6afSToby Isaac if (bDof) { 6883d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 6884d3d1a6afSToby Isaac PetscInt fDof, q, bOff, allFDof = 0; 6885d3d1a6afSToby Isaac 6886d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, b, f, &fDof);CHKERRQ(ierr); 6887d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(aSec, b, &bOff);CHKERRQ(ierr); 6888d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 6889d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q]; 6890d3d1a6afSToby Isaac PetscInt aFDof; 6891d3d1a6afSToby Isaac 6892d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, a, f, &aFDof);CHKERRQ(ierr); 6893d3d1a6afSToby Isaac allFDof += aFDof; 6894d3d1a6afSToby Isaac } 6895d3d1a6afSToby Isaac newPointOffsets[f][p+1] = allFDof; 6896d3d1a6afSToby Isaac pointMatOffsets[f][p+1] = fDof * allFDof; 6897d3d1a6afSToby Isaac } 6898d3d1a6afSToby Isaac } 6899d3d1a6afSToby Isaac else { 6900d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 6901d3d1a6afSToby Isaac PetscInt fDof; 6902d3d1a6afSToby Isaac 6903d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, b, f, &fDof);CHKERRQ(ierr); 6904d3d1a6afSToby Isaac newPointOffsets[f][p+1] = fDof; 6905d3d1a6afSToby Isaac pointMatOffsets[f][p+1] = 0; 6906d3d1a6afSToby Isaac } 6907d3d1a6afSToby Isaac } 6908d3d1a6afSToby Isaac } 69094b2f2278SToby Isaac for (f = 0, totalOffset = 0, totalMatOffset = 0; f < numFields; f++) { 69104b2f2278SToby Isaac newPointOffsets[f][0] = totalOffset; 69114b2f2278SToby Isaac pointMatOffsets[f][0] = totalMatOffset; 6912d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 6913d3d1a6afSToby Isaac newPointOffsets[f][p+1] += newPointOffsets[f][p]; 6914d3d1a6afSToby Isaac pointMatOffsets[f][p+1] += pointMatOffsets[f][p]; 6915d3d1a6afSToby Isaac } 691619f70fd5SToby Isaac totalOffset = newPointOffsets[f][numPoints]; 691719f70fd5SToby Isaac totalMatOffset = pointMatOffsets[f][numPoints]; 691869291d52SBarry Smith ierr = DMGetWorkArray(dm,pointMatOffsets[f][numPoints],MPIU_SCALAR,&pointMat[f]);CHKERRQ(ierr); 6919d3d1a6afSToby Isaac } 6920d3d1a6afSToby Isaac } 6921d3d1a6afSToby Isaac else { 6922d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 6923d3d1a6afSToby Isaac PetscInt b = points[2*p]; 69244b2f2278SToby Isaac PetscInt bDof = 0, bSecDof; 6925d3d1a6afSToby Isaac 69264b2f2278SToby Isaac ierr = PetscSectionGetDof(section,b,&bSecDof);CHKERRQ(ierr); 69274b2f2278SToby Isaac if (!bSecDof) { 69284b2f2278SToby Isaac newPointOffsets[0][p + 1] = 0; 69294b2f2278SToby Isaac pointMatOffsets[0][p + 1] = 0; 69304b2f2278SToby Isaac continue; 69314b2f2278SToby Isaac } 6932d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 6933d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec, b, &bDof);CHKERRQ(ierr); 6934d3d1a6afSToby Isaac } 6935d3d1a6afSToby Isaac if (bDof) { 69364b2f2278SToby Isaac PetscInt bOff, q, allDof = 0; 6937d3d1a6afSToby Isaac 6938d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(aSec, b, &bOff);CHKERRQ(ierr); 6939d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 6940d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q], aDof; 6941d3d1a6afSToby Isaac 6942d3d1a6afSToby Isaac ierr = PetscSectionGetDof(section, a, &aDof);CHKERRQ(ierr); 6943d3d1a6afSToby Isaac allDof += aDof; 6944d3d1a6afSToby Isaac } 6945d3d1a6afSToby Isaac newPointOffsets[0][p+1] = allDof; 69464b2f2278SToby Isaac pointMatOffsets[0][p+1] = bSecDof * allDof; 6947d3d1a6afSToby Isaac } 6948d3d1a6afSToby Isaac else { 69494b2f2278SToby Isaac newPointOffsets[0][p+1] = bSecDof; 6950d3d1a6afSToby Isaac pointMatOffsets[0][p+1] = 0; 6951d3d1a6afSToby Isaac } 6952d3d1a6afSToby Isaac } 6953d3d1a6afSToby Isaac newPointOffsets[0][0] = 0; 6954d3d1a6afSToby Isaac pointMatOffsets[0][0] = 0; 6955d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 6956d3d1a6afSToby Isaac newPointOffsets[0][p+1] += newPointOffsets[0][p]; 6957d3d1a6afSToby Isaac pointMatOffsets[0][p+1] += pointMatOffsets[0][p]; 6958d3d1a6afSToby Isaac } 695969291d52SBarry Smith ierr = DMGetWorkArray(dm,pointMatOffsets[0][numPoints],MPIU_SCALAR,&pointMat[0]);CHKERRQ(ierr); 6960d3d1a6afSToby Isaac } 6961d3d1a6afSToby Isaac 69626ecaa68aSToby Isaac /* output arrays */ 696369291d52SBarry Smith ierr = DMGetWorkArray(dm,2*newNumPoints,MPIU_INT,&newPoints);CHKERRQ(ierr); 69646ecaa68aSToby Isaac 6965d3d1a6afSToby Isaac /* get the point-to-point matrices; construct newPoints */ 6966d3d1a6afSToby Isaac ierr = PetscSectionGetMaxDof(aSec, &maxAnchor);CHKERRQ(ierr); 6967d3d1a6afSToby Isaac ierr = PetscSectionGetMaxDof(section, &maxDof);CHKERRQ(ierr); 696869291d52SBarry Smith ierr = DMGetWorkArray(dm,maxDof,MPIU_INT,&indices);CHKERRQ(ierr); 696969291d52SBarry Smith ierr = DMGetWorkArray(dm,maxAnchor*maxDof,MPIU_INT,&newIndices);CHKERRQ(ierr); 6970d3d1a6afSToby Isaac if (numFields) { 6971d3d1a6afSToby Isaac for (p = 0, newP = 0; p < numPoints; p++) { 6972d3d1a6afSToby Isaac PetscInt b = points[2*p]; 6973d3d1a6afSToby Isaac PetscInt o = points[2*p+1]; 69744b2f2278SToby Isaac PetscInt bDof = 0, bSecDof; 6975d3d1a6afSToby Isaac 69764b2f2278SToby Isaac ierr = PetscSectionGetDof(section, b, &bSecDof);CHKERRQ(ierr); 69774b2f2278SToby Isaac if (!bSecDof) { 69784b2f2278SToby Isaac continue; 69794b2f2278SToby Isaac } 6980d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 6981d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec, b, &bDof);CHKERRQ(ierr); 6982d3d1a6afSToby Isaac } 6983d3d1a6afSToby Isaac if (bDof) { 6984d3d1a6afSToby Isaac PetscInt fStart[32], fEnd[32], fAnchorStart[32], fAnchorEnd[32], bOff, q; 6985d3d1a6afSToby Isaac 6986d3d1a6afSToby Isaac fStart[0] = 0; 6987d3d1a6afSToby Isaac fEnd[0] = 0; 6988d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 6989d3d1a6afSToby Isaac PetscInt fDof; 6990d3d1a6afSToby Isaac 6991d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(cSec, b, f, &fDof);CHKERRQ(ierr); 6992d3d1a6afSToby Isaac fStart[f+1] = fStart[f] + fDof; 6993d3d1a6afSToby Isaac fEnd[f+1] = fStart[f+1]; 6994d3d1a6afSToby Isaac } 6995d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(cSec, b, &bOff);CHKERRQ(ierr); 699636fa2b79SJed Brown ierr = DMPlexGetIndicesPointFields_Internal(cSec, PETSC_TRUE, b, bOff, fEnd, PETSC_TRUE, perms, p, NULL, indices);CHKERRQ(ierr); 6997d3d1a6afSToby Isaac 6998d3d1a6afSToby Isaac fAnchorStart[0] = 0; 6999d3d1a6afSToby Isaac fAnchorEnd[0] = 0; 7000d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 7001d3d1a6afSToby Isaac PetscInt fDof = newPointOffsets[f][p + 1] - newPointOffsets[f][p]; 7002d3d1a6afSToby Isaac 7003d3d1a6afSToby Isaac fAnchorStart[f+1] = fAnchorStart[f] + fDof; 7004d3d1a6afSToby Isaac fAnchorEnd[f+1] = fAnchorStart[f + 1]; 7005d3d1a6afSToby Isaac } 7006d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(aSec, b, &bOff);CHKERRQ(ierr); 7007d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 7008d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q], aOff; 7009d3d1a6afSToby Isaac 7010d3d1a6afSToby 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 */ 7011d3d1a6afSToby Isaac newPoints[2*(newP + q)] = a; 7012d3d1a6afSToby Isaac newPoints[2*(newP + q) + 1] = 0; 7013302440fdSBarry Smith ierr = PetscSectionGetOffset(section, a, &aOff);CHKERRQ(ierr); 701436fa2b79SJed Brown ierr = DMPlexGetIndicesPointFields_Internal(section, PETSC_TRUE, a, aOff, fAnchorEnd, PETSC_TRUE, NULL, -1, NULL, newIndices);CHKERRQ(ierr); 7015d3d1a6afSToby Isaac } 7016d3d1a6afSToby Isaac newP += bDof; 7017d3d1a6afSToby Isaac 70186ecaa68aSToby Isaac if (outValues) { 7019d3d1a6afSToby Isaac /* get the point-to-point submatrix */ 7020d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 7021d3d1a6afSToby 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); 7022d3d1a6afSToby Isaac } 7023d3d1a6afSToby Isaac } 70246ecaa68aSToby Isaac } 7025d3d1a6afSToby Isaac else { 7026d3d1a6afSToby Isaac newPoints[2 * newP] = b; 7027d3d1a6afSToby Isaac newPoints[2 * newP + 1] = o; 7028d3d1a6afSToby Isaac newP++; 7029d3d1a6afSToby Isaac } 7030d3d1a6afSToby Isaac } 7031d3d1a6afSToby Isaac } else { 7032d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 7033d3d1a6afSToby Isaac PetscInt b = points[2*p]; 7034d3d1a6afSToby Isaac PetscInt o = points[2*p+1]; 70354b2f2278SToby Isaac PetscInt bDof = 0, bSecDof; 7036d3d1a6afSToby Isaac 70374b2f2278SToby Isaac ierr = PetscSectionGetDof(section, b, &bSecDof);CHKERRQ(ierr); 70384b2f2278SToby Isaac if (!bSecDof) { 70394b2f2278SToby Isaac continue; 70404b2f2278SToby Isaac } 7041d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 7042d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec, b, &bDof);CHKERRQ(ierr); 7043d3d1a6afSToby Isaac } 7044d3d1a6afSToby Isaac if (bDof) { 7045d3d1a6afSToby Isaac PetscInt bEnd = 0, bAnchorEnd = 0, bOff; 7046d3d1a6afSToby Isaac 7047d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(cSec, b, &bOff);CHKERRQ(ierr); 704836fa2b79SJed Brown ierr = DMPlexGetIndicesPoint_Internal(cSec, PETSC_TRUE, b, bOff, &bEnd, PETSC_TRUE, (perms && perms[0]) ? perms[0][p] : NULL, NULL, indices);CHKERRQ(ierr); 7049d3d1a6afSToby Isaac 7050d3d1a6afSToby Isaac ierr = PetscSectionGetOffset (aSec, b, &bOff);CHKERRQ(ierr); 7051d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 7052d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q], aOff; 7053d3d1a6afSToby Isaac 7054d3d1a6afSToby 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 */ 7055d3d1a6afSToby Isaac 7056d3d1a6afSToby Isaac newPoints[2*(newP + q)] = a; 7057d3d1a6afSToby Isaac newPoints[2*(newP + q) + 1] = 0; 7058302440fdSBarry Smith ierr = PetscSectionGetOffset(section, a, &aOff);CHKERRQ(ierr); 705936fa2b79SJed Brown ierr = DMPlexGetIndicesPoint_Internal(section, PETSC_TRUE, a, aOff, &bAnchorEnd, PETSC_TRUE, NULL, NULL, newIndices);CHKERRQ(ierr); 7060d3d1a6afSToby Isaac } 7061d3d1a6afSToby Isaac newP += bDof; 7062d3d1a6afSToby Isaac 7063d3d1a6afSToby Isaac /* get the point-to-point submatrix */ 70646ecaa68aSToby Isaac if (outValues) { 7065d3d1a6afSToby Isaac ierr = MatGetValues(cMat,bEnd,indices,bAnchorEnd,newIndices,pointMat[0] + pointMatOffsets[0][p]);CHKERRQ(ierr); 7066d3d1a6afSToby Isaac } 70676ecaa68aSToby Isaac } 7068d3d1a6afSToby Isaac else { 7069d3d1a6afSToby Isaac newPoints[2 * newP] = b; 7070d3d1a6afSToby Isaac newPoints[2 * newP + 1] = o; 7071d3d1a6afSToby Isaac newP++; 7072d3d1a6afSToby Isaac } 7073d3d1a6afSToby Isaac } 7074d3d1a6afSToby Isaac } 7075d3d1a6afSToby Isaac 70766ecaa68aSToby Isaac if (outValues) { 707769291d52SBarry Smith ierr = DMGetWorkArray(dm,newNumIndices*numIndices,MPIU_SCALAR,&tmpValues);CHKERRQ(ierr); 7078580bdb30SBarry Smith ierr = PetscArrayzero(tmpValues,newNumIndices*numIndices);CHKERRQ(ierr); 7079d3d1a6afSToby Isaac /* multiply constraints on the right */ 7080d3d1a6afSToby Isaac if (numFields) { 7081d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 7082d3d1a6afSToby Isaac PetscInt oldOff = offsets[f]; 7083d3d1a6afSToby Isaac 7084d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 7085d3d1a6afSToby Isaac PetscInt cStart = newPointOffsets[f][p]; 7086d3d1a6afSToby Isaac PetscInt b = points[2 * p]; 7087d3d1a6afSToby Isaac PetscInt c, r, k; 7088d3d1a6afSToby Isaac PetscInt dof; 7089d3d1a6afSToby Isaac 7090d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section,b,f,&dof);CHKERRQ(ierr); 70914b2f2278SToby Isaac if (!dof) { 70924b2f2278SToby Isaac continue; 70934b2f2278SToby Isaac } 7094d3d1a6afSToby Isaac if (pointMatOffsets[f][p] < pointMatOffsets[f][p + 1]) { 7095d3d1a6afSToby Isaac PetscInt nCols = newPointOffsets[f][p+1]-cStart; 7096d3d1a6afSToby Isaac const PetscScalar *mat = pointMat[f] + pointMatOffsets[f][p]; 7097d3d1a6afSToby Isaac 7098d3d1a6afSToby Isaac for (r = 0; r < numIndices; r++) { 7099d3d1a6afSToby Isaac for (c = 0; c < nCols; c++) { 7100d3d1a6afSToby Isaac for (k = 0; k < dof; k++) { 71014acb8e1eSToby Isaac tmpValues[r * newNumIndices + cStart + c] += values[r * numIndices + oldOff + k] * mat[k * nCols + c]; 7102d3d1a6afSToby Isaac } 7103d3d1a6afSToby Isaac } 7104d3d1a6afSToby Isaac } 7105d3d1a6afSToby Isaac } 7106d3d1a6afSToby Isaac else { 7107d3d1a6afSToby Isaac /* copy this column as is */ 7108d3d1a6afSToby Isaac for (r = 0; r < numIndices; r++) { 7109d3d1a6afSToby Isaac for (c = 0; c < dof; c++) { 7110d3d1a6afSToby Isaac tmpValues[r * newNumIndices + cStart + c] = values[r * numIndices + oldOff + c]; 7111d3d1a6afSToby Isaac } 7112d3d1a6afSToby Isaac } 7113d3d1a6afSToby Isaac } 7114d3d1a6afSToby Isaac oldOff += dof; 7115d3d1a6afSToby Isaac } 7116d3d1a6afSToby Isaac } 7117d3d1a6afSToby Isaac } 7118d3d1a6afSToby Isaac else { 7119d3d1a6afSToby Isaac PetscInt oldOff = 0; 7120d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 7121d3d1a6afSToby Isaac PetscInt cStart = newPointOffsets[0][p]; 7122d3d1a6afSToby Isaac PetscInt b = points[2 * p]; 7123d3d1a6afSToby Isaac PetscInt c, r, k; 7124d3d1a6afSToby Isaac PetscInt dof; 7125d3d1a6afSToby Isaac 7126d3d1a6afSToby Isaac ierr = PetscSectionGetDof(section,b,&dof);CHKERRQ(ierr); 71274b2f2278SToby Isaac if (!dof) { 71284b2f2278SToby Isaac continue; 71294b2f2278SToby Isaac } 7130d3d1a6afSToby Isaac if (pointMatOffsets[0][p] < pointMatOffsets[0][p + 1]) { 7131d3d1a6afSToby Isaac PetscInt nCols = newPointOffsets[0][p+1]-cStart; 7132d3d1a6afSToby Isaac const PetscScalar *mat = pointMat[0] + pointMatOffsets[0][p]; 7133d3d1a6afSToby Isaac 7134d3d1a6afSToby Isaac for (r = 0; r < numIndices; r++) { 7135d3d1a6afSToby Isaac for (c = 0; c < nCols; c++) { 7136d3d1a6afSToby Isaac for (k = 0; k < dof; k++) { 7137d3d1a6afSToby Isaac tmpValues[r * newNumIndices + cStart + c] += mat[k * nCols + c] * values[r * numIndices + oldOff + k]; 7138d3d1a6afSToby Isaac } 7139d3d1a6afSToby Isaac } 7140d3d1a6afSToby Isaac } 7141d3d1a6afSToby Isaac } 7142d3d1a6afSToby Isaac else { 7143d3d1a6afSToby Isaac /* copy this column as is */ 7144d3d1a6afSToby Isaac for (r = 0; r < numIndices; r++) { 7145d3d1a6afSToby Isaac for (c = 0; c < dof; c++) { 7146d3d1a6afSToby Isaac tmpValues[r * newNumIndices + cStart + c] = values[r * numIndices + oldOff + c]; 7147d3d1a6afSToby Isaac } 7148d3d1a6afSToby Isaac } 7149d3d1a6afSToby Isaac } 7150d3d1a6afSToby Isaac oldOff += dof; 7151d3d1a6afSToby Isaac } 7152d3d1a6afSToby Isaac } 7153d3d1a6afSToby Isaac 71546ecaa68aSToby Isaac if (multiplyLeft) { 715569291d52SBarry Smith ierr = DMGetWorkArray(dm,newNumIndices*newNumIndices,MPIU_SCALAR,&newValues);CHKERRQ(ierr); 7156580bdb30SBarry Smith ierr = PetscArrayzero(newValues,newNumIndices*newNumIndices);CHKERRQ(ierr); 7157d3d1a6afSToby Isaac /* multiply constraints transpose on the left */ 7158d3d1a6afSToby Isaac if (numFields) { 7159d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 7160d3d1a6afSToby Isaac PetscInt oldOff = offsets[f]; 7161d3d1a6afSToby Isaac 7162d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 7163d3d1a6afSToby Isaac PetscInt rStart = newPointOffsets[f][p]; 7164d3d1a6afSToby Isaac PetscInt b = points[2 * p]; 7165d3d1a6afSToby Isaac PetscInt c, r, k; 7166d3d1a6afSToby Isaac PetscInt dof; 7167d3d1a6afSToby Isaac 7168d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section,b,f,&dof);CHKERRQ(ierr); 7169d3d1a6afSToby Isaac if (pointMatOffsets[f][p] < pointMatOffsets[f][p + 1]) { 7170d3d1a6afSToby Isaac PetscInt nRows = newPointOffsets[f][p+1]-rStart; 7171d3d1a6afSToby Isaac const PetscScalar *PETSC_RESTRICT mat = pointMat[f] + pointMatOffsets[f][p]; 7172d3d1a6afSToby Isaac 7173d3d1a6afSToby Isaac for (r = 0; r < nRows; r++) { 7174d3d1a6afSToby Isaac for (c = 0; c < newNumIndices; c++) { 7175d3d1a6afSToby Isaac for (k = 0; k < dof; k++) { 7176d3d1a6afSToby Isaac newValues[(rStart + r) * newNumIndices + c] += mat[k * nRows + r] * tmpValues[(oldOff + k) * newNumIndices + c]; 7177d3d1a6afSToby Isaac } 7178d3d1a6afSToby Isaac } 7179d3d1a6afSToby Isaac } 7180d3d1a6afSToby Isaac } 7181d3d1a6afSToby Isaac else { 7182d3d1a6afSToby Isaac /* copy this row as is */ 7183d3d1a6afSToby Isaac for (r = 0; r < dof; r++) { 7184d3d1a6afSToby Isaac for (c = 0; c < newNumIndices; c++) { 7185d3d1a6afSToby Isaac newValues[(rStart + r) * newNumIndices + c] = tmpValues[(oldOff + r) * newNumIndices + c]; 7186d3d1a6afSToby Isaac } 7187d3d1a6afSToby Isaac } 7188d3d1a6afSToby Isaac } 7189d3d1a6afSToby Isaac oldOff += dof; 7190d3d1a6afSToby Isaac } 7191d3d1a6afSToby Isaac } 7192d3d1a6afSToby Isaac } 7193d3d1a6afSToby Isaac else { 7194d3d1a6afSToby Isaac PetscInt oldOff = 0; 7195d3d1a6afSToby Isaac 7196d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 7197d3d1a6afSToby Isaac PetscInt rStart = newPointOffsets[0][p]; 7198d3d1a6afSToby Isaac PetscInt b = points[2 * p]; 7199d3d1a6afSToby Isaac PetscInt c, r, k; 7200d3d1a6afSToby Isaac PetscInt dof; 7201d3d1a6afSToby Isaac 7202d3d1a6afSToby Isaac ierr = PetscSectionGetDof(section,b,&dof);CHKERRQ(ierr); 7203d3d1a6afSToby Isaac if (pointMatOffsets[0][p] < pointMatOffsets[0][p + 1]) { 7204d3d1a6afSToby Isaac PetscInt nRows = newPointOffsets[0][p+1]-rStart; 7205d3d1a6afSToby Isaac const PetscScalar *PETSC_RESTRICT mat = pointMat[0] + pointMatOffsets[0][p]; 7206d3d1a6afSToby Isaac 7207d3d1a6afSToby Isaac for (r = 0; r < nRows; r++) { 7208d3d1a6afSToby Isaac for (c = 0; c < newNumIndices; c++) { 7209d3d1a6afSToby Isaac for (k = 0; k < dof; k++) { 7210d3d1a6afSToby Isaac newValues[(rStart + r) * newNumIndices + c] += mat[k * nRows + r] * tmpValues[(oldOff + k) * newNumIndices + c]; 7211d3d1a6afSToby Isaac } 7212d3d1a6afSToby Isaac } 7213d3d1a6afSToby Isaac } 7214d3d1a6afSToby Isaac } 7215d3d1a6afSToby Isaac else { 7216d3d1a6afSToby Isaac /* copy this row as is */ 72179fc93327SToby Isaac for (r = 0; r < dof; r++) { 7218d3d1a6afSToby Isaac for (c = 0; c < newNumIndices; c++) { 7219d3d1a6afSToby Isaac newValues[(rStart + r) * newNumIndices + c] = tmpValues[(oldOff + r) * newNumIndices + c]; 7220d3d1a6afSToby Isaac } 7221d3d1a6afSToby Isaac } 7222d3d1a6afSToby Isaac } 7223d3d1a6afSToby Isaac oldOff += dof; 7224d3d1a6afSToby Isaac } 7225d3d1a6afSToby Isaac } 7226d3d1a6afSToby Isaac 722769291d52SBarry Smith ierr = DMRestoreWorkArray(dm,newNumIndices*numIndices,MPIU_SCALAR,&tmpValues);CHKERRQ(ierr); 72286ecaa68aSToby Isaac } 72296ecaa68aSToby Isaac else { 72306ecaa68aSToby Isaac newValues = tmpValues; 72316ecaa68aSToby Isaac } 72326ecaa68aSToby Isaac } 72336ecaa68aSToby Isaac 7234d3d1a6afSToby Isaac /* clean up */ 723569291d52SBarry Smith ierr = DMRestoreWorkArray(dm,maxDof,MPIU_INT,&indices);CHKERRQ(ierr); 723669291d52SBarry Smith ierr = DMRestoreWorkArray(dm,maxAnchor*maxDof,MPIU_INT,&newIndices);CHKERRQ(ierr); 72376ecaa68aSToby Isaac 7238d3d1a6afSToby Isaac if (numFields) { 7239d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 724069291d52SBarry Smith ierr = DMRestoreWorkArray(dm,pointMatOffsets[f][numPoints],MPIU_SCALAR,&pointMat[f]);CHKERRQ(ierr); 724169291d52SBarry Smith ierr = DMRestoreWorkArray(dm,numPoints+1,MPIU_INT,&pointMatOffsets[f]);CHKERRQ(ierr); 724269291d52SBarry Smith ierr = DMRestoreWorkArray(dm,numPoints+1,MPIU_INT,&newPointOffsets[f]);CHKERRQ(ierr); 7243d3d1a6afSToby Isaac } 7244d3d1a6afSToby Isaac } 7245d3d1a6afSToby Isaac else { 724669291d52SBarry Smith ierr = DMRestoreWorkArray(dm,pointMatOffsets[0][numPoints],MPIU_SCALAR,&pointMat[0]);CHKERRQ(ierr); 724769291d52SBarry Smith ierr = DMRestoreWorkArray(dm,numPoints+1,MPIU_INT,&pointMatOffsets[0]);CHKERRQ(ierr); 724869291d52SBarry Smith ierr = DMRestoreWorkArray(dm,numPoints+1,MPIU_INT,&newPointOffsets[0]);CHKERRQ(ierr); 7249d3d1a6afSToby Isaac } 7250d3d1a6afSToby Isaac ierr = ISRestoreIndices(aIS,&anchors);CHKERRQ(ierr); 7251d3d1a6afSToby Isaac 7252d3d1a6afSToby Isaac /* output */ 72536ecaa68aSToby Isaac if (outPoints) { 7254d3d1a6afSToby Isaac *outPoints = newPoints; 72556ecaa68aSToby Isaac } 72566ecaa68aSToby Isaac else { 725769291d52SBarry Smith ierr = DMRestoreWorkArray(dm,2*newNumPoints,MPIU_INT,&newPoints);CHKERRQ(ierr); 72586ecaa68aSToby Isaac } 725931620726SToby Isaac if (outValues) { 7260d3d1a6afSToby Isaac *outValues = newValues; 72616ecaa68aSToby Isaac } 72626ecaa68aSToby Isaac for (f = 0; f <= numFields; f++) { 7263d3d1a6afSToby Isaac offsets[f] = newOffsets[f]; 7264d3d1a6afSToby Isaac } 7265d3d1a6afSToby Isaac PetscFunctionReturn(0); 7266d3d1a6afSToby Isaac } 7267d3d1a6afSToby Isaac 72684a1e0b3eSMatthew G. Knepley /*@C 726971f0bbf9SMatthew G. Knepley DMPlexGetClosureIndices - Gets the global dof indices associated with the closure of the given point within the provided sections. 72707cd05799SMatthew G. Knepley 72717cd05799SMatthew G. Knepley Not collective 72727cd05799SMatthew G. Knepley 72737cd05799SMatthew G. Knepley Input Parameters: 72747cd05799SMatthew G. Knepley + dm - The DM 727571f0bbf9SMatthew G. Knepley . section - The PetscSection describing the points (a local section) 727671f0bbf9SMatthew G. Knepley . idxSection - The PetscSection from which to obtain indices (may be local or global) 727771f0bbf9SMatthew G. Knepley . point - The point defining the closure 727871f0bbf9SMatthew G. Knepley - useClPerm - Use the closure point permutation if available 72797cd05799SMatthew G. Knepley 728071f0bbf9SMatthew G. Knepley Output Parameters: 728171f0bbf9SMatthew G. Knepley + numIndices - The number of dof indices in the closure of point with the input sections 728271f0bbf9SMatthew G. Knepley . indices - The dof indices 728371f0bbf9SMatthew G. Knepley . outOffsets - Array to write the field offsets into, or NULL 728471f0bbf9SMatthew G. Knepley - values - The input values, which may be modified if sign flips are induced by the point symmetries, or NULL 72857cd05799SMatthew G. Knepley 728636fa2b79SJed Brown Notes: 728736fa2b79SJed Brown Must call DMPlexRestoreClosureIndices() to free allocated memory 728836fa2b79SJed Brown 728936fa2b79SJed Brown If idxSection is global, any constrained dofs (see DMAddBoundary(), for example) will get negative indices. The value 729036fa2b79SJed Brown of those indices is not significant. If idxSection is local, the constrained dofs will yield the involution -(idx+1) 729136fa2b79SJed Brown of their index in a local vector. A caller who does not wish to distinguish those points may recover the nonnegative 729236fa2b79SJed Brown indices via involution, -(-(idx+1)+1)==idx. Local indices are provided when idxSection == section, otherwise global 729336fa2b79SJed Brown indices (with the above semantics) are implied. 72947cd05799SMatthew G. Knepley 72957cd05799SMatthew G. Knepley Level: advanced 72967cd05799SMatthew G. Knepley 729736fa2b79SJed Brown .seealso DMPlexRestoreClosureIndices(), DMPlexVecGetClosure(), DMPlexMatSetClosure(), DMGetLocalSection(), DMGetGlobalSection() 72984a1e0b3eSMatthew G. Knepley @*/ 729971f0bbf9SMatthew G. Knepley PetscErrorCode DMPlexGetClosureIndices(DM dm, PetscSection section, PetscSection idxSection, PetscInt point, PetscBool useClPerm, 730071f0bbf9SMatthew G. Knepley PetscInt *numIndices, PetscInt *indices[], PetscInt outOffsets[], PetscScalar *values[]) 73017773e69fSMatthew G. Knepley { 730271f0bbf9SMatthew G. Knepley /* Closure ordering */ 73037773e69fSMatthew G. Knepley PetscSection clSection; 73047773e69fSMatthew G. Knepley IS clPoints; 730571f0bbf9SMatthew G. Knepley const PetscInt *clp; 730671f0bbf9SMatthew G. Knepley PetscInt *points; 730771f0bbf9SMatthew G. Knepley const PetscInt *clperm = NULL; 730871f0bbf9SMatthew G. Knepley /* Dof permutation and sign flips */ 73094acb8e1eSToby Isaac const PetscInt **perms[32] = {NULL}; 731071f0bbf9SMatthew G. Knepley const PetscScalar **flips[32] = {NULL}; 731171f0bbf9SMatthew G. Knepley PetscScalar *valCopy = NULL; 731271f0bbf9SMatthew G. Knepley /* Hanging node constraints */ 731371f0bbf9SMatthew G. Knepley PetscInt *pointsC = NULL; 731471f0bbf9SMatthew G. Knepley PetscScalar *valuesC = NULL; 731571f0bbf9SMatthew G. Knepley PetscInt NclC, NiC; 731671f0bbf9SMatthew G. Knepley 731771f0bbf9SMatthew G. Knepley PetscInt *idx; 731871f0bbf9SMatthew G. Knepley PetscInt Nf, Ncl, Ni = 0, offsets[32], p, f; 731971f0bbf9SMatthew G. Knepley PetscBool isLocal = (section == idxSection) ? PETSC_TRUE : PETSC_FALSE; 73207773e69fSMatthew G. Knepley PetscErrorCode ierr; 73217773e69fSMatthew G. Knepley 732271f0bbf9SMatthew G. Knepley PetscFunctionBeginHot; 73237773e69fSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 73247773e69fSMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 732536fa2b79SJed Brown PetscValidHeaderSpecific(idxSection, PETSC_SECTION_CLASSID, 3); 732671f0bbf9SMatthew G. Knepley if (numIndices) PetscValidPointer(numIndices, 6); 732771f0bbf9SMatthew G. Knepley if (indices) PetscValidPointer(indices, 7); 732871f0bbf9SMatthew G. Knepley if (outOffsets) PetscValidPointer(outOffsets, 8); 732971f0bbf9SMatthew G. Knepley if (values) PetscValidPointer(values, 9); 73307773e69fSMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &Nf);CHKERRQ(ierr); 73312c71b3e2SJacob Faibussowitsch PetscCheckFalse(Nf > 31,PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Number of fields %D limited to 31", Nf); 7332580bdb30SBarry Smith ierr = PetscArrayzero(offsets, 32);CHKERRQ(ierr); 733371f0bbf9SMatthew G. Knepley /* 1) Get points in closure */ 733471f0bbf9SMatthew G. Knepley ierr = DMPlexGetCompressedClosure(dm, section, point, &Ncl, &points, &clSection, &clPoints, &clp);CHKERRQ(ierr); 7335c459fbc1SJed Brown if (useClPerm) { 7336c459fbc1SJed Brown PetscInt depth, clsize; 7337c459fbc1SJed Brown ierr = DMPlexGetPointDepth(dm, point, &depth);CHKERRQ(ierr); 7338c459fbc1SJed Brown for (clsize=0,p=0; p<Ncl; p++) { 7339c459fbc1SJed Brown PetscInt dof; 7340c459fbc1SJed Brown ierr = PetscSectionGetDof(section, points[2*p], &dof);CHKERRQ(ierr); 7341c459fbc1SJed Brown clsize += dof; 7342c459fbc1SJed Brown } 7343c459fbc1SJed Brown ierr = PetscSectionGetClosureInversePermutation_Internal(section, (PetscObject) dm, depth, clsize, &clperm);CHKERRQ(ierr); 7344c459fbc1SJed Brown } 734571f0bbf9SMatthew G. Knepley /* 2) Get number of indices on these points and field offsets from section */ 734671f0bbf9SMatthew G. Knepley for (p = 0; p < Ncl*2; p += 2) { 73477773e69fSMatthew G. Knepley PetscInt dof, fdof; 73487773e69fSMatthew G. Knepley 73497773e69fSMatthew G. Knepley ierr = PetscSectionGetDof(section, points[p], &dof);CHKERRQ(ierr); 73507773e69fSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 73517773e69fSMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, points[p], f, &fdof);CHKERRQ(ierr); 73527773e69fSMatthew G. Knepley offsets[f+1] += fdof; 73537773e69fSMatthew G. Knepley } 735471f0bbf9SMatthew G. Knepley Ni += dof; 73557773e69fSMatthew G. Knepley } 73567773e69fSMatthew G. Knepley for (f = 1; f < Nf; ++f) offsets[f+1] += offsets[f]; 73572c71b3e2SJacob Faibussowitsch PetscCheckFalse(Nf && offsets[Nf] != Ni,PetscObjectComm((PetscObject) dm), PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", offsets[Nf], Ni); 735871f0bbf9SMatthew G. Knepley /* 3) Get symmetries and sign flips. Apply sign flips to values if passed in (only works for square values matrix) */ 735971f0bbf9SMatthew G. Knepley for (f = 0; f < PetscMax(1, Nf); ++f) { 736071f0bbf9SMatthew G. Knepley if (Nf) {ierr = PetscSectionGetFieldPointSyms(section, f, Ncl, points, &perms[f], &flips[f]);CHKERRQ(ierr);} 736171f0bbf9SMatthew G. Knepley else {ierr = PetscSectionGetPointSyms(section, Ncl, points, &perms[f], &flips[f]);CHKERRQ(ierr);} 736271f0bbf9SMatthew G. Knepley /* may need to apply sign changes to the element matrix */ 736371f0bbf9SMatthew G. Knepley if (values && flips[f]) { 736471f0bbf9SMatthew G. Knepley PetscInt foffset = offsets[f]; 73656ecaa68aSToby Isaac 736671f0bbf9SMatthew G. Knepley for (p = 0; p < Ncl; ++p) { 736771f0bbf9SMatthew G. Knepley PetscInt pnt = points[2*p], fdof; 736871f0bbf9SMatthew G. Knepley const PetscScalar *flip = flips[f] ? flips[f][p] : NULL; 736971f0bbf9SMatthew G. Knepley 737071f0bbf9SMatthew G. Knepley if (!Nf) {ierr = PetscSectionGetDof(section, pnt, &fdof);CHKERRQ(ierr);} 737171f0bbf9SMatthew G. Knepley else {ierr = PetscSectionGetFieldDof(section, pnt, f, &fdof);CHKERRQ(ierr);} 737271f0bbf9SMatthew G. Knepley if (flip) { 737371f0bbf9SMatthew G. Knepley PetscInt i, j, k; 737471f0bbf9SMatthew G. Knepley 737571f0bbf9SMatthew G. Knepley if (!valCopy) { 737671f0bbf9SMatthew G. Knepley ierr = DMGetWorkArray(dm, Ni*Ni, MPIU_SCALAR, &valCopy);CHKERRQ(ierr); 737771f0bbf9SMatthew G. Knepley for (j = 0; j < Ni * Ni; ++j) valCopy[j] = (*values)[j]; 737871f0bbf9SMatthew G. Knepley *values = valCopy; 737971f0bbf9SMatthew G. Knepley } 738071f0bbf9SMatthew G. Knepley for (i = 0; i < fdof; ++i) { 738171f0bbf9SMatthew G. Knepley PetscScalar fval = flip[i]; 738271f0bbf9SMatthew G. Knepley 738371f0bbf9SMatthew G. Knepley for (k = 0; k < Ni; ++k) { 738471f0bbf9SMatthew G. Knepley valCopy[Ni * (foffset + i) + k] *= fval; 738571f0bbf9SMatthew G. Knepley valCopy[Ni * k + (foffset + i)] *= fval; 73866ecaa68aSToby Isaac } 73876ecaa68aSToby Isaac } 738871f0bbf9SMatthew G. Knepley } 738971f0bbf9SMatthew G. Knepley foffset += fdof; 739071f0bbf9SMatthew G. Knepley } 739171f0bbf9SMatthew G. Knepley } 739271f0bbf9SMatthew G. Knepley } 739371f0bbf9SMatthew G. Knepley /* 4) Apply hanging node constraints. Get new symmetries and replace all storage with constrained storage */ 739471f0bbf9SMatthew G. Knepley ierr = DMPlexAnchorsModifyMat(dm, section, Ncl, Ni, points, perms, values ? *values : NULL, &NclC, &NiC, &pointsC, values ? &valuesC : NULL, offsets, PETSC_TRUE);CHKERRQ(ierr); 739571f0bbf9SMatthew G. Knepley if (NclC) { 739671f0bbf9SMatthew G. Knepley if (valCopy) {ierr = DMRestoreWorkArray(dm, Ni*Ni, MPIU_SCALAR, &valCopy);CHKERRQ(ierr);} 739771f0bbf9SMatthew G. Knepley for (f = 0; f < PetscMax(1, Nf); ++f) { 739871f0bbf9SMatthew G. Knepley if (Nf) {ierr = PetscSectionRestoreFieldPointSyms(section, f, Ncl, points, &perms[f], &flips[f]);CHKERRQ(ierr);} 739971f0bbf9SMatthew G. Knepley else {ierr = PetscSectionRestorePointSyms(section, Ncl, points, &perms[f], &flips[f]);CHKERRQ(ierr);} 740071f0bbf9SMatthew G. Knepley } 740171f0bbf9SMatthew G. Knepley for (f = 0; f < PetscMax(1, Nf); ++f) { 740271f0bbf9SMatthew G. Knepley if (Nf) {ierr = PetscSectionGetFieldPointSyms(section, f, NclC, pointsC, &perms[f], &flips[f]);CHKERRQ(ierr);} 740371f0bbf9SMatthew G. Knepley else {ierr = PetscSectionGetPointSyms(section, NclC, pointsC, &perms[f], &flips[f]);CHKERRQ(ierr);} 740471f0bbf9SMatthew G. Knepley } 740571f0bbf9SMatthew G. Knepley ierr = DMPlexRestoreCompressedClosure(dm, section, point, &Ncl, &points, &clSection, &clPoints, &clp);CHKERRQ(ierr); 740671f0bbf9SMatthew G. Knepley Ncl = NclC; 740771f0bbf9SMatthew G. Knepley Ni = NiC; 740871f0bbf9SMatthew G. Knepley points = pointsC; 740971f0bbf9SMatthew G. Knepley if (values) *values = valuesC; 741071f0bbf9SMatthew G. Knepley } 741171f0bbf9SMatthew G. Knepley /* 5) Calculate indices */ 741271f0bbf9SMatthew G. Knepley ierr = DMGetWorkArray(dm, Ni, MPIU_INT, &idx);CHKERRQ(ierr); 741371f0bbf9SMatthew G. Knepley if (Nf) { 741471f0bbf9SMatthew G. Knepley PetscInt idxOff; 741571f0bbf9SMatthew G. Knepley PetscBool useFieldOffsets; 741671f0bbf9SMatthew G. Knepley 741771f0bbf9SMatthew G. Knepley if (outOffsets) {for (f = 0; f <= Nf; f++) outOffsets[f] = offsets[f];} 741871f0bbf9SMatthew G. Knepley ierr = PetscSectionGetUseFieldOffsets(idxSection, &useFieldOffsets);CHKERRQ(ierr); 741971f0bbf9SMatthew G. Knepley if (useFieldOffsets) { 742071f0bbf9SMatthew G. Knepley for (p = 0; p < Ncl; ++p) { 742171f0bbf9SMatthew G. Knepley const PetscInt pnt = points[p*2]; 742271f0bbf9SMatthew G. Knepley 742371f0bbf9SMatthew G. Knepley ierr = DMPlexGetIndicesPointFieldsSplit_Internal(section, idxSection, pnt, offsets, perms, p, clperm, idx);CHKERRQ(ierr); 74247773e69fSMatthew G. Knepley } 74257773e69fSMatthew G. Knepley } else { 742671f0bbf9SMatthew G. Knepley for (p = 0; p < Ncl; ++p) { 742771f0bbf9SMatthew G. Knepley const PetscInt pnt = points[p*2]; 742871f0bbf9SMatthew G. Knepley 742971f0bbf9SMatthew G. Knepley ierr = PetscSectionGetOffset(idxSection, pnt, &idxOff);CHKERRQ(ierr); 743071f0bbf9SMatthew G. Knepley /* Note that we pass a local section even though we're using global offsets. This is because global sections do 743171f0bbf9SMatthew G. Knepley * not (at the time of this writing) have fields set. They probably should, in which case we would pass the 743271f0bbf9SMatthew G. Knepley * global section. */ 743371f0bbf9SMatthew G. Knepley ierr = DMPlexGetIndicesPointFields_Internal(section, isLocal, pnt, idxOff < 0 ? -(idxOff+1) : idxOff, offsets, PETSC_FALSE, perms, p, clperm, idx);CHKERRQ(ierr); 743471f0bbf9SMatthew G. Knepley } 743571f0bbf9SMatthew G. Knepley } 743671f0bbf9SMatthew G. Knepley } else { 743771f0bbf9SMatthew G. Knepley PetscInt off = 0, idxOff; 743871f0bbf9SMatthew G. Knepley 743971f0bbf9SMatthew G. Knepley for (p = 0; p < Ncl; ++p) { 744071f0bbf9SMatthew G. Knepley const PetscInt pnt = points[p*2]; 74414acb8e1eSToby Isaac const PetscInt *perm = perms[0] ? perms[0][p] : NULL; 74424acb8e1eSToby Isaac 744371f0bbf9SMatthew G. Knepley ierr = PetscSectionGetOffset(idxSection, pnt, &idxOff);CHKERRQ(ierr); 744471f0bbf9SMatthew G. Knepley /* Note that we pass a local section even though we're using global offsets. This is because global sections do 744571f0bbf9SMatthew G. Knepley * not (at the time of this writing) have fields set. They probably should, in which case we would pass the global section. */ 744671f0bbf9SMatthew G. Knepley ierr = DMPlexGetIndicesPoint_Internal(section, isLocal, pnt, idxOff < 0 ? -(idxOff+1) : idxOff, &off, PETSC_FALSE, perm, clperm, idx);CHKERRQ(ierr); 74477773e69fSMatthew G. Knepley } 74487773e69fSMatthew G. Knepley } 744971f0bbf9SMatthew G. Knepley /* 6) Cleanup */ 745071f0bbf9SMatthew G. Knepley for (f = 0; f < PetscMax(1, Nf); ++f) { 745171f0bbf9SMatthew G. Knepley if (Nf) {ierr = PetscSectionRestoreFieldPointSyms(section, f, Ncl, points, &perms[f], &flips[f]);CHKERRQ(ierr);} 745271f0bbf9SMatthew G. Knepley else {ierr = PetscSectionRestorePointSyms(section, Ncl, points, &perms[f], &flips[f]);CHKERRQ(ierr);} 74534acb8e1eSToby Isaac } 745471f0bbf9SMatthew G. Knepley if (NclC) { 745571f0bbf9SMatthew G. Knepley ierr = DMRestoreWorkArray(dm, NclC*2, MPIU_INT, &pointsC);CHKERRQ(ierr); 74567773e69fSMatthew G. Knepley } else { 745771f0bbf9SMatthew G. Knepley ierr = DMPlexRestoreCompressedClosure(dm, section, point, &Ncl, &points, &clSection, &clPoints, &clp);CHKERRQ(ierr); 74587773e69fSMatthew G. Knepley } 745971f0bbf9SMatthew G. Knepley 746071f0bbf9SMatthew G. Knepley if (numIndices) *numIndices = Ni; 746171f0bbf9SMatthew G. Knepley if (indices) *indices = idx; 74627773e69fSMatthew G. Knepley PetscFunctionReturn(0); 74637773e69fSMatthew G. Knepley } 74647773e69fSMatthew G. Knepley 74657cd05799SMatthew G. Knepley /*@C 746671f0bbf9SMatthew G. Knepley DMPlexRestoreClosureIndices - Restores the global dof indices associated with the closure of the given point within the provided sections. 74677cd05799SMatthew G. Knepley 74687cd05799SMatthew G. Knepley Not collective 74697cd05799SMatthew G. Knepley 74707cd05799SMatthew G. Knepley Input Parameters: 74717cd05799SMatthew G. Knepley + dm - The DM 747271f0bbf9SMatthew G. Knepley . section - The PetscSection describing the points (a local section) 747371f0bbf9SMatthew G. Knepley . idxSection - The PetscSection from which to obtain indices (may be local or global) 747471f0bbf9SMatthew G. Knepley . point - The point defining the closure 747571f0bbf9SMatthew G. Knepley - useClPerm - Use the closure point permutation if available 747671f0bbf9SMatthew G. Knepley 747771f0bbf9SMatthew G. Knepley Output Parameters: 747871f0bbf9SMatthew G. Knepley + numIndices - The number of dof indices in the closure of point with the input sections 747971f0bbf9SMatthew G. Knepley . indices - The dof indices 748071f0bbf9SMatthew G. Knepley . outOffsets - Array to write the field offsets into, or NULL 748171f0bbf9SMatthew G. Knepley - values - The input values, which may be modified if sign flips are induced by the point symmetries, or NULL 748271f0bbf9SMatthew G. Knepley 748371f0bbf9SMatthew G. Knepley Notes: 748471f0bbf9SMatthew G. Knepley If values were modified, the user is responsible for calling DMRestoreWorkArray(dm, 0, MPIU_SCALAR, &values). 748571f0bbf9SMatthew G. Knepley 748671f0bbf9SMatthew G. Knepley If idxSection is global, any constrained dofs (see DMAddBoundary(), for example) will get negative indices. The value 748771f0bbf9SMatthew G. Knepley of those indices is not significant. If idxSection is local, the constrained dofs will yield the involution -(idx+1) 748871f0bbf9SMatthew G. Knepley of their index in a local vector. A caller who does not wish to distinguish those points may recover the nonnegative 748971f0bbf9SMatthew G. Knepley indices via involution, -(-(idx+1)+1)==idx. Local indices are provided when idxSection == section, otherwise global 749071f0bbf9SMatthew G. Knepley indices (with the above semantics) are implied. 74917cd05799SMatthew G. Knepley 74927cd05799SMatthew G. Knepley Level: advanced 74937cd05799SMatthew G. Knepley 749471f0bbf9SMatthew G. Knepley .seealso DMPlexGetClosureIndices(), DMPlexVecGetClosure(), DMPlexMatSetClosure(), DMGetLocalSection(), DMGetGlobalSection() 74957cd05799SMatthew G. Knepley @*/ 749671f0bbf9SMatthew G. Knepley PetscErrorCode DMPlexRestoreClosureIndices(DM dm, PetscSection section, PetscSection idxSection, PetscInt point, PetscBool useClPerm, 749771f0bbf9SMatthew G. Knepley PetscInt *numIndices, PetscInt *indices[], PetscInt outOffsets[], PetscScalar *values[]) 74987773e69fSMatthew G. Knepley { 74997773e69fSMatthew G. Knepley PetscErrorCode ierr; 75007773e69fSMatthew G. Knepley 75017773e69fSMatthew G. Knepley PetscFunctionBegin; 75027773e69fSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7503064a246eSJacob Faibussowitsch PetscValidPointer(indices, 7); 750469291d52SBarry Smith ierr = DMRestoreWorkArray(dm, 0, MPIU_INT, indices);CHKERRQ(ierr); 75057773e69fSMatthew G. Knepley PetscFunctionReturn(0); 75067773e69fSMatthew G. Knepley } 75077773e69fSMatthew G. Knepley 75087f5d1fdeSMatthew G. Knepley /*@C 75097f5d1fdeSMatthew G. Knepley DMPlexMatSetClosure - Set an array of the values on the closure of 'point' 75107f5d1fdeSMatthew G. Knepley 75117f5d1fdeSMatthew G. Knepley Not collective 75127f5d1fdeSMatthew G. Knepley 75137f5d1fdeSMatthew G. Knepley Input Parameters: 75147f5d1fdeSMatthew G. Knepley + dm - The DM 7515ebd6d717SJed Brown . section - The section describing the layout in v, or NULL to use the default section 7516ebd6d717SJed Brown . globalSection - The section describing the layout in v, or NULL to use the default global section 75177f5d1fdeSMatthew G. Knepley . A - The matrix 7518eaf898f9SPatrick Sanan . point - The point in the DM 75197f5d1fdeSMatthew G. Knepley . values - The array of values 75207f5d1fdeSMatthew G. Knepley - mode - The insert mode, where INSERT_ALL_VALUES and ADD_ALL_VALUES also overwrite boundary conditions 75217f5d1fdeSMatthew G. Knepley 75227f5d1fdeSMatthew G. Knepley Fortran Notes: 75237f5d1fdeSMatthew G. Knepley This routine is only available in Fortran 90, and you must include petsc.h90 in your code. 75247f5d1fdeSMatthew G. Knepley 75257f5d1fdeSMatthew G. Knepley Level: intermediate 75267f5d1fdeSMatthew G. Knepley 75274a1e0b3eSMatthew G. Knepley .seealso DMPlexMatSetClosureGeneral(), DMPlexVecGetClosure(), DMPlexVecSetClosure() 75287f5d1fdeSMatthew G. Knepley @*/ 75297c1f9639SMatthew G Knepley PetscErrorCode DMPlexMatSetClosure(DM dm, PetscSection section, PetscSection globalSection, Mat A, PetscInt point, const PetscScalar values[], InsertMode mode) 7530552f7358SJed Brown { 7531552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 7532552f7358SJed Brown PetscInt *indices; 753371f0bbf9SMatthew G. Knepley PetscInt numIndices; 753471f0bbf9SMatthew G. Knepley const PetscScalar *valuesOrig = values; 7535552f7358SJed Brown PetscErrorCode ierr; 7536552f7358SJed Brown 7537552f7358SJed Brown PetscFunctionBegin; 7538552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 753992fd8e1eSJed Brown if (!section) {ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr);} 75403dc93601SMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 7541e87a4003SBarry Smith if (!globalSection) {ierr = DMGetGlobalSection(dm, &globalSection);CHKERRQ(ierr);} 75423dc93601SMatthew G. Knepley PetscValidHeaderSpecific(globalSection, PETSC_SECTION_CLASSID, 3); 75433dc93601SMatthew G. Knepley PetscValidHeaderSpecific(A, MAT_CLASSID, 4); 7544552f7358SJed Brown 754571f0bbf9SMatthew G. Knepley ierr = DMPlexGetClosureIndices(dm, section, globalSection, point, PETSC_TRUE, &numIndices, &indices, NULL, (PetscScalar **) &values);CHKERRQ(ierr); 75460d644c17SKarl Rupp 7547b0ecff45SMatthew G. Knepley if (mesh->printSetValues) {ierr = DMPlexPrintMatSetValues(PETSC_VIEWER_STDOUT_SELF, A, point, numIndices, indices, 0, NULL, values);CHKERRQ(ierr);} 75484a1e0b3eSMatthew G. Knepley ierr = MatSetValues(A, numIndices, indices, numIndices, indices, values, mode); 7549552f7358SJed Brown if (ierr) { 7550552f7358SJed Brown PetscMPIInt rank; 7551552f7358SJed Brown PetscErrorCode ierr2; 7552552f7358SJed Brown 755355b25c41SPierre Jolivet ierr2 = MPI_Comm_rank(PetscObjectComm((PetscObject)A), &rank);CHKERRMPI(ierr2); 7554e4b003c7SBarry Smith ierr2 = (*PetscErrorPrintf)("[%d]ERROR in DMPlexMatSetClosure\n", rank);CHKERRQ(ierr2); 7555b0ecff45SMatthew G. Knepley ierr2 = DMPlexPrintMatSetValues(PETSC_VIEWER_STDERR_SELF, A, point, numIndices, indices, 0, NULL, values);CHKERRQ(ierr2); 755671f0bbf9SMatthew G. Knepley ierr2 = DMPlexRestoreClosureIndices(dm, section, globalSection, point, PETSC_TRUE, &numIndices, &indices, NULL, (PetscScalar **) &values);CHKERRQ(ierr2); 755771f0bbf9SMatthew G. Knepley if (values != valuesOrig) {ierr2 = DMRestoreWorkArray(dm, 0, MPIU_SCALAR, &values);CHKERRQ(ierr2);} 7558c3e24edfSBarry Smith SETERRQ(PetscObjectComm((PetscObject)dm),ierr,"Not possible to set matrix values"); 7559552f7358SJed Brown } 75604a1e0b3eSMatthew G. Knepley if (mesh->printFEM > 1) { 75614a1e0b3eSMatthew G. Knepley PetscInt i; 75624a1e0b3eSMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " Indices:");CHKERRQ(ierr); 75634a1e0b3eSMatthew G. Knepley for (i = 0; i < numIndices; ++i) {ierr = PetscPrintf(PETSC_COMM_SELF, " %D", indices[i]);CHKERRQ(ierr);} 75644a1e0b3eSMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 75654a1e0b3eSMatthew G. Knepley } 756671f0bbf9SMatthew G. Knepley 756771f0bbf9SMatthew G. Knepley ierr = DMPlexRestoreClosureIndices(dm, section, globalSection, point, PETSC_TRUE, &numIndices, &indices, NULL, (PetscScalar **) &values);CHKERRQ(ierr); 756871f0bbf9SMatthew G. Knepley if (values != valuesOrig) {ierr = DMRestoreWorkArray(dm, 0, MPIU_SCALAR, &values);CHKERRQ(ierr);} 756971f0bbf9SMatthew G. Knepley PetscFunctionReturn(0); 75704acb8e1eSToby Isaac } 757171f0bbf9SMatthew G. Knepley 75724a1e0b3eSMatthew G. Knepley /*@C 75734a1e0b3eSMatthew G. Knepley DMPlexMatSetClosure - Set an array of the values on the closure of 'point' using a different row and column section 75744a1e0b3eSMatthew G. Knepley 75754a1e0b3eSMatthew G. Knepley Not collective 75764a1e0b3eSMatthew G. Knepley 75774a1e0b3eSMatthew G. Knepley Input Parameters: 75784a1e0b3eSMatthew G. Knepley + dmRow - The DM for the row fields 75794a1e0b3eSMatthew G. Knepley . sectionRow - The section describing the layout, or NULL to use the default section in dmRow 75804a1e0b3eSMatthew G. Knepley . globalSectionRow - The section describing the layout, or NULL to use the default global section in dmRow 75814a1e0b3eSMatthew G. Knepley . dmCol - The DM for the column fields 75824a1e0b3eSMatthew G. Knepley . sectionCol - The section describing the layout, or NULL to use the default section in dmCol 75834a1e0b3eSMatthew G. Knepley . globalSectionCol - The section describing the layout, or NULL to use the default global section in dmCol 75844a1e0b3eSMatthew G. Knepley . A - The matrix 75854a1e0b3eSMatthew G. Knepley . point - The point in the DMs 75864a1e0b3eSMatthew G. Knepley . values - The array of values 75874a1e0b3eSMatthew G. Knepley - mode - The insert mode, where INSERT_ALL_VALUES and ADD_ALL_VALUES also overwrite boundary conditions 75884a1e0b3eSMatthew G. Knepley 75894a1e0b3eSMatthew G. Knepley Level: intermediate 75904a1e0b3eSMatthew G. Knepley 75914a1e0b3eSMatthew G. Knepley .seealso DMPlexMatSetClosure(), DMPlexVecGetClosure(), DMPlexVecSetClosure() 75924a1e0b3eSMatthew G. Knepley @*/ 759371f0bbf9SMatthew G. Knepley PetscErrorCode DMPlexMatSetClosureGeneral(DM dmRow, PetscSection sectionRow, PetscSection globalSectionRow, DM dmCol, PetscSection sectionCol, PetscSection globalSectionCol, Mat A, PetscInt point, const PetscScalar values[], InsertMode mode) 759471f0bbf9SMatthew G. Knepley { 759571f0bbf9SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dmRow->data; 759671f0bbf9SMatthew G. Knepley PetscInt *indicesRow, *indicesCol; 759771f0bbf9SMatthew G. Knepley PetscInt numIndicesRow, numIndicesCol; 759871f0bbf9SMatthew G. Knepley const PetscScalar *valuesOrig = values; 759971f0bbf9SMatthew G. Knepley PetscErrorCode ierr; 760071f0bbf9SMatthew G. Knepley 760171f0bbf9SMatthew G. Knepley PetscFunctionBegin; 760271f0bbf9SMatthew G. Knepley PetscValidHeaderSpecific(dmRow, DM_CLASSID, 1); 760371f0bbf9SMatthew G. Knepley if (!sectionRow) {ierr = DMGetLocalSection(dmRow, §ionRow);CHKERRQ(ierr);} 760471f0bbf9SMatthew G. Knepley PetscValidHeaderSpecific(sectionRow, PETSC_SECTION_CLASSID, 2); 760571f0bbf9SMatthew G. Knepley if (!globalSectionRow) {ierr = DMGetGlobalSection(dmRow, &globalSectionRow);CHKERRQ(ierr);} 760671f0bbf9SMatthew G. Knepley PetscValidHeaderSpecific(globalSectionRow, PETSC_SECTION_CLASSID, 3); 760771f0bbf9SMatthew G. Knepley PetscValidHeaderSpecific(dmCol, DM_CLASSID, 4); 760871f0bbf9SMatthew G. Knepley if (!sectionCol) {ierr = DMGetLocalSection(dmCol, §ionCol);CHKERRQ(ierr);} 760971f0bbf9SMatthew G. Knepley PetscValidHeaderSpecific(sectionCol, PETSC_SECTION_CLASSID, 5); 761071f0bbf9SMatthew G. Knepley if (!globalSectionCol) {ierr = DMGetGlobalSection(dmCol, &globalSectionCol);CHKERRQ(ierr);} 761171f0bbf9SMatthew G. Knepley PetscValidHeaderSpecific(globalSectionCol, PETSC_SECTION_CLASSID, 6); 761271f0bbf9SMatthew G. Knepley PetscValidHeaderSpecific(A, MAT_CLASSID, 7); 761371f0bbf9SMatthew G. Knepley 761471f0bbf9SMatthew G. Knepley ierr = DMPlexGetClosureIndices(dmRow, sectionRow, globalSectionRow, point, PETSC_TRUE, &numIndicesRow, &indicesRow, NULL, (PetscScalar **) &values);CHKERRQ(ierr); 761571f0bbf9SMatthew G. Knepley ierr = DMPlexGetClosureIndices(dmCol, sectionCol, globalSectionCol, point, PETSC_TRUE, &numIndicesCol, &indicesCol, NULL, (PetscScalar **) &values);CHKERRQ(ierr); 761671f0bbf9SMatthew G. Knepley 761771f0bbf9SMatthew G. Knepley if (mesh->printSetValues) {ierr = DMPlexPrintMatSetValues(PETSC_VIEWER_STDOUT_SELF, A, point, numIndicesRow, indicesRow, numIndicesCol, indicesCol, values);CHKERRQ(ierr);} 76184a1e0b3eSMatthew G. Knepley ierr = MatSetValues(A, numIndicesRow, indicesRow, numIndicesCol, indicesCol, values, mode); 761971f0bbf9SMatthew G. Knepley if (ierr) { 762071f0bbf9SMatthew G. Knepley PetscMPIInt rank; 762171f0bbf9SMatthew G. Knepley PetscErrorCode ierr2; 762271f0bbf9SMatthew G. Knepley 762355b25c41SPierre Jolivet ierr2 = MPI_Comm_rank(PetscObjectComm((PetscObject)A), &rank);CHKERRMPI(ierr2); 762471f0bbf9SMatthew G. Knepley ierr2 = (*PetscErrorPrintf)("[%d]ERROR in DMPlexMatSetClosure\n", rank);CHKERRQ(ierr2); 762571f0bbf9SMatthew G. Knepley ierr2 = DMPlexPrintMatSetValues(PETSC_VIEWER_STDERR_SELF, A, point, numIndicesRow, indicesRow, numIndicesCol, indicesCol, values);CHKERRQ(ierr2); 762671f0bbf9SMatthew G. Knepley ierr2 = DMPlexRestoreClosureIndices(dmRow, sectionRow, globalSectionRow, point, PETSC_TRUE, &numIndicesRow, &indicesRow, NULL, (PetscScalar **) &values);CHKERRQ(ierr2); 762771f0bbf9SMatthew G. Knepley ierr2 = DMPlexRestoreClosureIndices(dmCol, sectionCol, globalSectionCol, point, PETSC_TRUE, &numIndicesCol, &indicesRow, NULL, (PetscScalar **) &values);CHKERRQ(ierr2); 762871f0bbf9SMatthew G. Knepley if (values != valuesOrig) {ierr2 = DMRestoreWorkArray(dmRow, 0, MPIU_SCALAR, &values);CHKERRQ(ierr2);} 762971f0bbf9SMatthew G. Knepley CHKERRQ(ierr); 7630d3d1a6afSToby Isaac } 763171f0bbf9SMatthew G. Knepley 763271f0bbf9SMatthew G. Knepley ierr = DMPlexRestoreClosureIndices(dmRow, sectionRow, globalSectionRow, point, PETSC_TRUE, &numIndicesRow, &indicesRow, NULL, (PetscScalar **) &values);CHKERRQ(ierr); 763371f0bbf9SMatthew G. Knepley ierr = DMPlexRestoreClosureIndices(dmCol, sectionCol, globalSectionCol, point, PETSC_TRUE, &numIndicesCol, &indicesCol, NULL, (PetscScalar **) &values);CHKERRQ(ierr); 763471f0bbf9SMatthew G. Knepley if (values != valuesOrig) {ierr = DMRestoreWorkArray(dmRow, 0, MPIU_SCALAR, &values);CHKERRQ(ierr);} 7635552f7358SJed Brown PetscFunctionReturn(0); 7636552f7358SJed Brown } 7637552f7358SJed Brown 7638de41b84cSMatthew 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) 7639de41b84cSMatthew G. Knepley { 7640de41b84cSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dmf->data; 7641de41b84cSMatthew G. Knepley PetscInt *fpoints = NULL, *ftotpoints = NULL; 7642de41b84cSMatthew G. Knepley PetscInt *cpoints = NULL; 7643de41b84cSMatthew G. Knepley PetscInt *findices, *cindices; 764417c0192bSMatthew G. Knepley const PetscInt *fclperm = NULL, *cclperm = NULL; /* Closure permutations cannot work here */ 7645de41b84cSMatthew G. Knepley PetscInt foffsets[32], coffsets[32]; 7646412e9a14SMatthew G. Knepley DMPolytopeType ct; 76474ca5e9f5SMatthew G. Knepley PetscInt numFields, numSubcells, maxFPoints, numFPoints, numCPoints, numFIndices, numCIndices, dof, off, globalOff, pStart, pEnd, p, q, r, s, f; 7648de41b84cSMatthew G. Knepley PetscErrorCode ierr; 7649de41b84cSMatthew G. Knepley 7650de41b84cSMatthew G. Knepley PetscFunctionBegin; 7651de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(dmf, DM_CLASSID, 1); 7652de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(dmc, DM_CLASSID, 4); 765392fd8e1eSJed Brown if (!fsection) {ierr = DMGetLocalSection(dmf, &fsection);CHKERRQ(ierr);} 7654de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(fsection, PETSC_SECTION_CLASSID, 2); 765592fd8e1eSJed Brown if (!csection) {ierr = DMGetLocalSection(dmc, &csection);CHKERRQ(ierr);} 7656de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(csection, PETSC_SECTION_CLASSID, 5); 7657e87a4003SBarry Smith if (!globalFSection) {ierr = DMGetGlobalSection(dmf, &globalFSection);CHKERRQ(ierr);} 7658de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(globalFSection, PETSC_SECTION_CLASSID, 3); 7659e87a4003SBarry Smith if (!globalCSection) {ierr = DMGetGlobalSection(dmc, &globalCSection);CHKERRQ(ierr);} 7660de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(globalCSection, PETSC_SECTION_CLASSID, 6); 7661de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(A, MAT_CLASSID, 7); 7662de41b84cSMatthew G. Knepley ierr = PetscSectionGetNumFields(fsection, &numFields);CHKERRQ(ierr); 76632c71b3e2SJacob Faibussowitsch PetscCheckFalse(numFields > 31,PetscObjectComm((PetscObject)dmf), PETSC_ERR_ARG_OUTOFRANGE, "Number of fields %D limited to 31", numFields); 7664580bdb30SBarry Smith ierr = PetscArrayzero(foffsets, 32);CHKERRQ(ierr); 7665580bdb30SBarry Smith ierr = PetscArrayzero(coffsets, 32);CHKERRQ(ierr); 7666de41b84cSMatthew G. Knepley /* Column indices */ 7667de41b84cSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dmc, point, PETSC_TRUE, &numCPoints, &cpoints);CHKERRQ(ierr); 76684ca5e9f5SMatthew G. Knepley maxFPoints = numCPoints; 7669de41b84cSMatthew G. Knepley /* Compress out points not in the section */ 7670de41b84cSMatthew G. Knepley /* TODO: Squeeze out points with 0 dof as well */ 7671de41b84cSMatthew G. Knepley ierr = PetscSectionGetChart(csection, &pStart, &pEnd);CHKERRQ(ierr); 7672de41b84cSMatthew G. Knepley for (p = 0, q = 0; p < numCPoints*2; p += 2) { 7673de41b84cSMatthew G. Knepley if ((cpoints[p] >= pStart) && (cpoints[p] < pEnd)) { 7674de41b84cSMatthew G. Knepley cpoints[q*2] = cpoints[p]; 7675de41b84cSMatthew G. Knepley cpoints[q*2+1] = cpoints[p+1]; 7676de41b84cSMatthew G. Knepley ++q; 7677de41b84cSMatthew G. Knepley } 7678de41b84cSMatthew G. Knepley } 7679de41b84cSMatthew G. Knepley numCPoints = q; 7680de41b84cSMatthew G. Knepley for (p = 0, numCIndices = 0; p < numCPoints*2; p += 2) { 7681de41b84cSMatthew G. Knepley PetscInt fdof; 7682de41b84cSMatthew G. Knepley 7683de41b84cSMatthew G. Knepley ierr = PetscSectionGetDof(csection, cpoints[p], &dof);CHKERRQ(ierr); 76844ca5e9f5SMatthew G. Knepley if (!dof) continue; 7685de41b84cSMatthew G. Knepley for (f = 0; f < numFields; ++f) { 7686de41b84cSMatthew G. Knepley ierr = PetscSectionGetFieldDof(csection, cpoints[p], f, &fdof);CHKERRQ(ierr); 7687de41b84cSMatthew G. Knepley coffsets[f+1] += fdof; 7688de41b84cSMatthew G. Knepley } 7689de41b84cSMatthew G. Knepley numCIndices += dof; 7690de41b84cSMatthew G. Knepley } 7691de41b84cSMatthew G. Knepley for (f = 1; f < numFields; ++f) coffsets[f+1] += coffsets[f]; 7692de41b84cSMatthew G. Knepley /* Row indices */ 7693412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dmc, point, &ct);CHKERRQ(ierr); 7694412e9a14SMatthew G. Knepley { 7695012bc364SMatthew G. Knepley DMPlexTransform tr; 7696012bc364SMatthew G. Knepley DMPolytopeType *rct; 7697012bc364SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt, Nt; 7698012bc364SMatthew G. Knepley 7699012bc364SMatthew G. Knepley ierr = DMPlexTransformCreate(PETSC_COMM_SELF, &tr);CHKERRQ(ierr); 7700012bc364SMatthew G. Knepley ierr = DMPlexTransformSetType(tr, DMPLEXREFINEREGULAR);CHKERRQ(ierr); 7701012bc364SMatthew G. Knepley ierr = DMPlexTransformCellTransform(tr, ct, point, NULL, &Nt, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 7702012bc364SMatthew G. Knepley numSubcells = rsize[Nt-1]; 7703012bc364SMatthew G. Knepley ierr = DMPlexTransformDestroy(&tr);CHKERRQ(ierr); 7704412e9a14SMatthew G. Knepley } 770569291d52SBarry Smith ierr = DMGetWorkArray(dmf, maxFPoints*2*numSubcells, MPIU_INT, &ftotpoints);CHKERRQ(ierr); 7706de41b84cSMatthew G. Knepley for (r = 0, q = 0; r < numSubcells; ++r) { 7707de41b84cSMatthew G. Knepley /* TODO Map from coarse to fine cells */ 7708de41b84cSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dmf, point*numSubcells + r, PETSC_TRUE, &numFPoints, &fpoints);CHKERRQ(ierr); 7709de41b84cSMatthew G. Knepley /* Compress out points not in the section */ 7710de41b84cSMatthew G. Knepley ierr = PetscSectionGetChart(fsection, &pStart, &pEnd);CHKERRQ(ierr); 7711de41b84cSMatthew G. Knepley for (p = 0; p < numFPoints*2; p += 2) { 7712de41b84cSMatthew G. Knepley if ((fpoints[p] >= pStart) && (fpoints[p] < pEnd)) { 77134ca5e9f5SMatthew G. Knepley ierr = PetscSectionGetDof(fsection, fpoints[p], &dof);CHKERRQ(ierr); 77144ca5e9f5SMatthew G. Knepley if (!dof) continue; 77154ca5e9f5SMatthew G. Knepley for (s = 0; s < q; ++s) if (fpoints[p] == ftotpoints[s*2]) break; 77164ca5e9f5SMatthew G. Knepley if (s < q) continue; 7717de41b84cSMatthew G. Knepley ftotpoints[q*2] = fpoints[p]; 7718de41b84cSMatthew G. Knepley ftotpoints[q*2+1] = fpoints[p+1]; 7719de41b84cSMatthew G. Knepley ++q; 7720de41b84cSMatthew G. Knepley } 7721de41b84cSMatthew G. Knepley } 7722de41b84cSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dmf, point, PETSC_TRUE, &numFPoints, &fpoints);CHKERRQ(ierr); 7723de41b84cSMatthew G. Knepley } 7724de41b84cSMatthew G. Knepley numFPoints = q; 7725de41b84cSMatthew G. Knepley for (p = 0, numFIndices = 0; p < numFPoints*2; p += 2) { 7726de41b84cSMatthew G. Knepley PetscInt fdof; 7727de41b84cSMatthew G. Knepley 7728de41b84cSMatthew G. Knepley ierr = PetscSectionGetDof(fsection, ftotpoints[p], &dof);CHKERRQ(ierr); 77294ca5e9f5SMatthew G. Knepley if (!dof) continue; 7730de41b84cSMatthew G. Knepley for (f = 0; f < numFields; ++f) { 7731de41b84cSMatthew G. Knepley ierr = PetscSectionGetFieldDof(fsection, ftotpoints[p], f, &fdof);CHKERRQ(ierr); 7732de41b84cSMatthew G. Knepley foffsets[f+1] += fdof; 7733de41b84cSMatthew G. Knepley } 7734de41b84cSMatthew G. Knepley numFIndices += dof; 7735de41b84cSMatthew G. Knepley } 7736de41b84cSMatthew G. Knepley for (f = 1; f < numFields; ++f) foffsets[f+1] += foffsets[f]; 7737de41b84cSMatthew G. Knepley 77382c71b3e2SJacob Faibussowitsch PetscCheckFalse(numFields && foffsets[numFields] != numFIndices,PetscObjectComm((PetscObject)dmf), PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", foffsets[numFields], numFIndices); 77392c71b3e2SJacob Faibussowitsch PetscCheckFalse(numFields && coffsets[numFields] != numCIndices,PetscObjectComm((PetscObject)dmc), PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", coffsets[numFields], numCIndices); 774069291d52SBarry Smith ierr = DMGetWorkArray(dmf, numFIndices, MPIU_INT, &findices);CHKERRQ(ierr); 774169291d52SBarry Smith ierr = DMGetWorkArray(dmc, numCIndices, MPIU_INT, &cindices);CHKERRQ(ierr); 7742de41b84cSMatthew G. Knepley if (numFields) { 77434acb8e1eSToby Isaac const PetscInt **permsF[32] = {NULL}; 77444acb8e1eSToby Isaac const PetscInt **permsC[32] = {NULL}; 77454acb8e1eSToby Isaac 77464acb8e1eSToby Isaac for (f = 0; f < numFields; f++) { 77474acb8e1eSToby Isaac ierr = PetscSectionGetFieldPointSyms(fsection,f,numFPoints,ftotpoints,&permsF[f],NULL);CHKERRQ(ierr); 77484acb8e1eSToby Isaac ierr = PetscSectionGetFieldPointSyms(csection,f,numCPoints,cpoints,&permsC[f],NULL);CHKERRQ(ierr); 7749de41b84cSMatthew G. Knepley } 77504acb8e1eSToby Isaac for (p = 0; p < numFPoints; p++) { 77514acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalFSection, ftotpoints[2*p], &globalOff);CHKERRQ(ierr); 775236fa2b79SJed Brown ierr = DMPlexGetIndicesPointFields_Internal(fsection, PETSC_FALSE, ftotpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, foffsets, PETSC_FALSE, permsF, p, fclperm, findices);CHKERRQ(ierr); 77534acb8e1eSToby Isaac } 77544acb8e1eSToby Isaac for (p = 0; p < numCPoints; p++) { 77554acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalCSection, cpoints[2*p], &globalOff);CHKERRQ(ierr); 775636fa2b79SJed Brown ierr = DMPlexGetIndicesPointFields_Internal(csection, PETSC_FALSE, cpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, coffsets, PETSC_FALSE, permsC, p, cclperm, cindices);CHKERRQ(ierr); 77574acb8e1eSToby Isaac } 77584acb8e1eSToby Isaac for (f = 0; f < numFields; f++) { 77594acb8e1eSToby Isaac ierr = PetscSectionRestoreFieldPointSyms(fsection,f,numFPoints,ftotpoints,&permsF[f],NULL);CHKERRQ(ierr); 77604acb8e1eSToby Isaac ierr = PetscSectionRestoreFieldPointSyms(csection,f,numCPoints,cpoints,&permsC[f],NULL);CHKERRQ(ierr); 7761de41b84cSMatthew G. Knepley } 7762de41b84cSMatthew G. Knepley } else { 77634acb8e1eSToby Isaac const PetscInt **permsF = NULL; 77644acb8e1eSToby Isaac const PetscInt **permsC = NULL; 77654acb8e1eSToby Isaac 77664acb8e1eSToby Isaac ierr = PetscSectionGetPointSyms(fsection,numFPoints,ftotpoints,&permsF,NULL);CHKERRQ(ierr); 77674acb8e1eSToby Isaac ierr = PetscSectionGetPointSyms(csection,numCPoints,cpoints,&permsC,NULL);CHKERRQ(ierr); 77684acb8e1eSToby Isaac for (p = 0, off = 0; p < numFPoints; p++) { 77694acb8e1eSToby Isaac const PetscInt *perm = permsF ? permsF[p] : NULL; 77704acb8e1eSToby Isaac 77714acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalFSection, ftotpoints[2*p], &globalOff);CHKERRQ(ierr); 777236fa2b79SJed Brown ierr = DMPlexGetIndicesPoint_Internal(fsection, PETSC_FALSE, ftotpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, perm, fclperm, findices);CHKERRQ(ierr); 7773de41b84cSMatthew G. Knepley } 77744acb8e1eSToby Isaac for (p = 0, off = 0; p < numCPoints; p++) { 77754acb8e1eSToby Isaac const PetscInt *perm = permsC ? permsC[p] : NULL; 77764acb8e1eSToby Isaac 77774acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalCSection, cpoints[2*p], &globalOff);CHKERRQ(ierr); 777836fa2b79SJed Brown ierr = DMPlexGetIndicesPoint_Internal(csection, PETSC_FALSE, cpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, perm, cclperm, cindices);CHKERRQ(ierr); 7779de41b84cSMatthew G. Knepley } 77804acb8e1eSToby Isaac ierr = PetscSectionRestorePointSyms(fsection,numFPoints,ftotpoints,&permsF,NULL);CHKERRQ(ierr); 77814acb8e1eSToby Isaac ierr = PetscSectionRestorePointSyms(csection,numCPoints,cpoints,&permsC,NULL);CHKERRQ(ierr); 7782de41b84cSMatthew G. Knepley } 7783de41b84cSMatthew G. Knepley if (mesh->printSetValues) {ierr = DMPlexPrintMatSetValues(PETSC_VIEWER_STDOUT_SELF, A, point, numFIndices, findices, numCIndices, cindices, values);CHKERRQ(ierr);} 77844acb8e1eSToby Isaac /* TODO: flips */ 7785de41b84cSMatthew G. Knepley ierr = MatSetValues(A, numFIndices, findices, numCIndices, cindices, values, mode); 7786de41b84cSMatthew G. Knepley if (ierr) { 7787de41b84cSMatthew G. Knepley PetscMPIInt rank; 7788de41b84cSMatthew G. Knepley PetscErrorCode ierr2; 7789de41b84cSMatthew G. Knepley 779055b25c41SPierre Jolivet ierr2 = MPI_Comm_rank(PetscObjectComm((PetscObject)A), &rank);CHKERRMPI(ierr2); 7791e4b003c7SBarry Smith ierr2 = (*PetscErrorPrintf)("[%d]ERROR in DMPlexMatSetClosure\n", rank);CHKERRQ(ierr2); 7792de41b84cSMatthew G. Knepley ierr2 = DMPlexPrintMatSetValues(PETSC_VIEWER_STDERR_SELF, A, point, numFIndices, findices, numCIndices, cindices, values);CHKERRQ(ierr2); 779369291d52SBarry Smith ierr2 = DMRestoreWorkArray(dmf, numFIndices, MPIU_INT, &findices);CHKERRQ(ierr2); 779469291d52SBarry Smith ierr2 = DMRestoreWorkArray(dmc, numCIndices, MPIU_INT, &cindices);CHKERRQ(ierr2); 7795de41b84cSMatthew G. Knepley CHKERRQ(ierr); 7796de41b84cSMatthew G. Knepley } 779769291d52SBarry Smith ierr = DMRestoreWorkArray(dmf, numCPoints*2*4, MPIU_INT, &ftotpoints);CHKERRQ(ierr); 7798de41b84cSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dmc, point, PETSC_TRUE, &numCPoints, &cpoints);CHKERRQ(ierr); 779969291d52SBarry Smith ierr = DMRestoreWorkArray(dmf, numFIndices, MPIU_INT, &findices);CHKERRQ(ierr); 780069291d52SBarry Smith ierr = DMRestoreWorkArray(dmc, numCIndices, MPIU_INT, &cindices);CHKERRQ(ierr); 7801de41b84cSMatthew G. Knepley PetscFunctionReturn(0); 7802de41b84cSMatthew G. Knepley } 7803de41b84cSMatthew G. Knepley 78047c927364SMatthew G. Knepley PetscErrorCode DMPlexMatGetClosureIndicesRefined(DM dmf, PetscSection fsection, PetscSection globalFSection, DM dmc, PetscSection csection, PetscSection globalCSection, PetscInt point, PetscInt cindices[], PetscInt findices[]) 78057c927364SMatthew G. Knepley { 78067c927364SMatthew G. Knepley PetscInt *fpoints = NULL, *ftotpoints = NULL; 78077c927364SMatthew G. Knepley PetscInt *cpoints = NULL; 78087c927364SMatthew G. Knepley PetscInt foffsets[32], coffsets[32]; 780917c0192bSMatthew G. Knepley const PetscInt *fclperm = NULL, *cclperm = NULL; /* Closure permutations cannot work here */ 7810412e9a14SMatthew G. Knepley DMPolytopeType ct; 78117c927364SMatthew G. Knepley PetscInt numFields, numSubcells, maxFPoints, numFPoints, numCPoints, numFIndices, numCIndices, dof, off, globalOff, pStart, pEnd, p, q, r, s, f; 78127c927364SMatthew G. Knepley PetscErrorCode ierr; 78137c927364SMatthew G. Knepley 78147c927364SMatthew G. Knepley PetscFunctionBegin; 78157c927364SMatthew G. Knepley PetscValidHeaderSpecific(dmf, DM_CLASSID, 1); 78167c927364SMatthew G. Knepley PetscValidHeaderSpecific(dmc, DM_CLASSID, 4); 781792fd8e1eSJed Brown if (!fsection) {ierr = DMGetLocalSection(dmf, &fsection);CHKERRQ(ierr);} 78187c927364SMatthew G. Knepley PetscValidHeaderSpecific(fsection, PETSC_SECTION_CLASSID, 2); 781992fd8e1eSJed Brown if (!csection) {ierr = DMGetLocalSection(dmc, &csection);CHKERRQ(ierr);} 78207c927364SMatthew G. Knepley PetscValidHeaderSpecific(csection, PETSC_SECTION_CLASSID, 5); 7821e87a4003SBarry Smith if (!globalFSection) {ierr = DMGetGlobalSection(dmf, &globalFSection);CHKERRQ(ierr);} 78227c927364SMatthew G. Knepley PetscValidHeaderSpecific(globalFSection, PETSC_SECTION_CLASSID, 3); 7823e87a4003SBarry Smith if (!globalCSection) {ierr = DMGetGlobalSection(dmc, &globalCSection);CHKERRQ(ierr);} 78247c927364SMatthew G. Knepley PetscValidHeaderSpecific(globalCSection, PETSC_SECTION_CLASSID, 6); 78257c927364SMatthew G. Knepley ierr = PetscSectionGetNumFields(fsection, &numFields);CHKERRQ(ierr); 78262c71b3e2SJacob Faibussowitsch PetscCheckFalse(numFields > 31,PetscObjectComm((PetscObject)dmf), PETSC_ERR_ARG_OUTOFRANGE, "Number of fields %D limited to 31", numFields); 7827580bdb30SBarry Smith ierr = PetscArrayzero(foffsets, 32);CHKERRQ(ierr); 7828580bdb30SBarry Smith ierr = PetscArrayzero(coffsets, 32);CHKERRQ(ierr); 78297c927364SMatthew G. Knepley /* Column indices */ 78307c927364SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dmc, point, PETSC_TRUE, &numCPoints, &cpoints);CHKERRQ(ierr); 78317c927364SMatthew G. Knepley maxFPoints = numCPoints; 78327c927364SMatthew G. Knepley /* Compress out points not in the section */ 78337c927364SMatthew G. Knepley /* TODO: Squeeze out points with 0 dof as well */ 78347c927364SMatthew G. Knepley ierr = PetscSectionGetChart(csection, &pStart, &pEnd);CHKERRQ(ierr); 78357c927364SMatthew G. Knepley for (p = 0, q = 0; p < numCPoints*2; p += 2) { 78367c927364SMatthew G. Knepley if ((cpoints[p] >= pStart) && (cpoints[p] < pEnd)) { 78377c927364SMatthew G. Knepley cpoints[q*2] = cpoints[p]; 78387c927364SMatthew G. Knepley cpoints[q*2+1] = cpoints[p+1]; 78397c927364SMatthew G. Knepley ++q; 78407c927364SMatthew G. Knepley } 78417c927364SMatthew G. Knepley } 78427c927364SMatthew G. Knepley numCPoints = q; 78437c927364SMatthew G. Knepley for (p = 0, numCIndices = 0; p < numCPoints*2; p += 2) { 78447c927364SMatthew G. Knepley PetscInt fdof; 78457c927364SMatthew G. Knepley 78467c927364SMatthew G. Knepley ierr = PetscSectionGetDof(csection, cpoints[p], &dof);CHKERRQ(ierr); 78477c927364SMatthew G. Knepley if (!dof) continue; 78487c927364SMatthew G. Knepley for (f = 0; f < numFields; ++f) { 78497c927364SMatthew G. Knepley ierr = PetscSectionGetFieldDof(csection, cpoints[p], f, &fdof);CHKERRQ(ierr); 78507c927364SMatthew G. Knepley coffsets[f+1] += fdof; 78517c927364SMatthew G. Knepley } 78527c927364SMatthew G. Knepley numCIndices += dof; 78537c927364SMatthew G. Knepley } 78547c927364SMatthew G. Knepley for (f = 1; f < numFields; ++f) coffsets[f+1] += coffsets[f]; 78557c927364SMatthew G. Knepley /* Row indices */ 7856412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dmc, point, &ct);CHKERRQ(ierr); 7857412e9a14SMatthew G. Knepley { 7858012bc364SMatthew G. Knepley DMPlexTransform tr; 7859012bc364SMatthew G. Knepley DMPolytopeType *rct; 7860012bc364SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt, Nt; 7861012bc364SMatthew G. Knepley 7862012bc364SMatthew G. Knepley ierr = DMPlexTransformCreate(PETSC_COMM_SELF, &tr);CHKERRQ(ierr); 7863012bc364SMatthew G. Knepley ierr = DMPlexTransformSetType(tr, DMPLEXREFINEREGULAR);CHKERRQ(ierr); 7864012bc364SMatthew G. Knepley ierr = DMPlexTransformCellTransform(tr, ct, point, NULL, &Nt, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 7865012bc364SMatthew G. Knepley numSubcells = rsize[Nt-1]; 7866012bc364SMatthew G. Knepley ierr = DMPlexTransformDestroy(&tr);CHKERRQ(ierr); 7867412e9a14SMatthew G. Knepley } 786869291d52SBarry Smith ierr = DMGetWorkArray(dmf, maxFPoints*2*numSubcells, MPIU_INT, &ftotpoints);CHKERRQ(ierr); 78697c927364SMatthew G. Knepley for (r = 0, q = 0; r < numSubcells; ++r) { 78707c927364SMatthew G. Knepley /* TODO Map from coarse to fine cells */ 78717c927364SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dmf, point*numSubcells + r, PETSC_TRUE, &numFPoints, &fpoints);CHKERRQ(ierr); 78727c927364SMatthew G. Knepley /* Compress out points not in the section */ 78737c927364SMatthew G. Knepley ierr = PetscSectionGetChart(fsection, &pStart, &pEnd);CHKERRQ(ierr); 78747c927364SMatthew G. Knepley for (p = 0; p < numFPoints*2; p += 2) { 78757c927364SMatthew G. Knepley if ((fpoints[p] >= pStart) && (fpoints[p] < pEnd)) { 78767c927364SMatthew G. Knepley ierr = PetscSectionGetDof(fsection, fpoints[p], &dof);CHKERRQ(ierr); 78777c927364SMatthew G. Knepley if (!dof) continue; 78787c927364SMatthew G. Knepley for (s = 0; s < q; ++s) if (fpoints[p] == ftotpoints[s*2]) break; 78797c927364SMatthew G. Knepley if (s < q) continue; 78807c927364SMatthew G. Knepley ftotpoints[q*2] = fpoints[p]; 78817c927364SMatthew G. Knepley ftotpoints[q*2+1] = fpoints[p+1]; 78827c927364SMatthew G. Knepley ++q; 78837c927364SMatthew G. Knepley } 78847c927364SMatthew G. Knepley } 78857c927364SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dmf, point, PETSC_TRUE, &numFPoints, &fpoints);CHKERRQ(ierr); 78867c927364SMatthew G. Knepley } 78877c927364SMatthew G. Knepley numFPoints = q; 78887c927364SMatthew G. Knepley for (p = 0, numFIndices = 0; p < numFPoints*2; p += 2) { 78897c927364SMatthew G. Knepley PetscInt fdof; 78907c927364SMatthew G. Knepley 78917c927364SMatthew G. Knepley ierr = PetscSectionGetDof(fsection, ftotpoints[p], &dof);CHKERRQ(ierr); 78927c927364SMatthew G. Knepley if (!dof) continue; 78937c927364SMatthew G. Knepley for (f = 0; f < numFields; ++f) { 78947c927364SMatthew G. Knepley ierr = PetscSectionGetFieldDof(fsection, ftotpoints[p], f, &fdof);CHKERRQ(ierr); 78957c927364SMatthew G. Knepley foffsets[f+1] += fdof; 78967c927364SMatthew G. Knepley } 78977c927364SMatthew G. Knepley numFIndices += dof; 78987c927364SMatthew G. Knepley } 78997c927364SMatthew G. Knepley for (f = 1; f < numFields; ++f) foffsets[f+1] += foffsets[f]; 79007c927364SMatthew G. Knepley 79012c71b3e2SJacob Faibussowitsch PetscCheckFalse(numFields && foffsets[numFields] != numFIndices,PetscObjectComm((PetscObject)dmf), PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", foffsets[numFields], numFIndices); 79022c71b3e2SJacob Faibussowitsch PetscCheckFalse(numFields && coffsets[numFields] != numCIndices,PetscObjectComm((PetscObject)dmc), PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", coffsets[numFields], numCIndices); 79037c927364SMatthew G. Knepley if (numFields) { 79044acb8e1eSToby Isaac const PetscInt **permsF[32] = {NULL}; 79054acb8e1eSToby Isaac const PetscInt **permsC[32] = {NULL}; 79064acb8e1eSToby Isaac 79074acb8e1eSToby Isaac for (f = 0; f < numFields; f++) { 79084acb8e1eSToby Isaac ierr = PetscSectionGetFieldPointSyms(fsection,f,numFPoints,ftotpoints,&permsF[f],NULL);CHKERRQ(ierr); 79094acb8e1eSToby Isaac ierr = PetscSectionGetFieldPointSyms(csection,f,numCPoints,cpoints,&permsC[f],NULL);CHKERRQ(ierr); 79107c927364SMatthew G. Knepley } 79114acb8e1eSToby Isaac for (p = 0; p < numFPoints; p++) { 79124acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalFSection, ftotpoints[2*p], &globalOff);CHKERRQ(ierr); 791336fa2b79SJed Brown ierr = DMPlexGetIndicesPointFields_Internal(fsection, PETSC_FALSE, ftotpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, foffsets, PETSC_FALSE, permsF, p, fclperm, findices);CHKERRQ(ierr); 79144acb8e1eSToby Isaac } 79154acb8e1eSToby Isaac for (p = 0; p < numCPoints; p++) { 79164acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalCSection, cpoints[2*p], &globalOff);CHKERRQ(ierr); 791736fa2b79SJed Brown ierr = DMPlexGetIndicesPointFields_Internal(csection, PETSC_FALSE, cpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, coffsets, PETSC_FALSE, permsC, p, cclperm, cindices);CHKERRQ(ierr); 79184acb8e1eSToby Isaac } 79194acb8e1eSToby Isaac for (f = 0; f < numFields; f++) { 79204acb8e1eSToby Isaac ierr = PetscSectionRestoreFieldPointSyms(fsection,f,numFPoints,ftotpoints,&permsF[f],NULL);CHKERRQ(ierr); 79214acb8e1eSToby Isaac ierr = PetscSectionRestoreFieldPointSyms(csection,f,numCPoints,cpoints,&permsC[f],NULL);CHKERRQ(ierr); 79227c927364SMatthew G. Knepley } 79237c927364SMatthew G. Knepley } else { 79244acb8e1eSToby Isaac const PetscInt **permsF = NULL; 79254acb8e1eSToby Isaac const PetscInt **permsC = NULL; 79264acb8e1eSToby Isaac 79274acb8e1eSToby Isaac ierr = PetscSectionGetPointSyms(fsection,numFPoints,ftotpoints,&permsF,NULL);CHKERRQ(ierr); 79284acb8e1eSToby Isaac ierr = PetscSectionGetPointSyms(csection,numCPoints,cpoints,&permsC,NULL);CHKERRQ(ierr); 79294acb8e1eSToby Isaac for (p = 0, off = 0; p < numFPoints; p++) { 79304acb8e1eSToby Isaac const PetscInt *perm = permsF ? permsF[p] : NULL; 79314acb8e1eSToby Isaac 79324acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalFSection, ftotpoints[2*p], &globalOff);CHKERRQ(ierr); 793336fa2b79SJed Brown ierr = DMPlexGetIndicesPoint_Internal(fsection, PETSC_FALSE, ftotpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, perm, fclperm, findices);CHKERRQ(ierr); 79347c927364SMatthew G. Knepley } 79354acb8e1eSToby Isaac for (p = 0, off = 0; p < numCPoints; p++) { 79364acb8e1eSToby Isaac const PetscInt *perm = permsC ? permsC[p] : NULL; 79374acb8e1eSToby Isaac 79384acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalCSection, cpoints[2*p], &globalOff);CHKERRQ(ierr); 793936fa2b79SJed Brown ierr = DMPlexGetIndicesPoint_Internal(csection, PETSC_FALSE, cpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, perm, cclperm, cindices);CHKERRQ(ierr); 79407c927364SMatthew G. Knepley } 79414acb8e1eSToby Isaac ierr = PetscSectionRestorePointSyms(fsection,numFPoints,ftotpoints,&permsF,NULL);CHKERRQ(ierr); 79424acb8e1eSToby Isaac ierr = PetscSectionRestorePointSyms(csection,numCPoints,cpoints,&permsC,NULL);CHKERRQ(ierr); 79437c927364SMatthew G. Knepley } 794469291d52SBarry Smith ierr = DMRestoreWorkArray(dmf, numCPoints*2*4, MPIU_INT, &ftotpoints);CHKERRQ(ierr); 79457c927364SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dmc, point, PETSC_TRUE, &numCPoints, &cpoints);CHKERRQ(ierr); 79467c927364SMatthew G. Knepley PetscFunctionReturn(0); 79477c927364SMatthew G. Knepley } 79487c927364SMatthew G. Knepley 79497cd05799SMatthew G. Knepley /*@C 79507cd05799SMatthew G. Knepley DMPlexGetVTKCellHeight - Returns the height in the DAG used to determine which points are cells (normally 0) 79517cd05799SMatthew G. Knepley 79527cd05799SMatthew G. Knepley Input Parameter: 79537cd05799SMatthew G. Knepley . dm - The DMPlex object 79547cd05799SMatthew G. Knepley 79557cd05799SMatthew G. Knepley Output Parameter: 79567cd05799SMatthew G. Knepley . cellHeight - The height of a cell 79577cd05799SMatthew G. Knepley 79587cd05799SMatthew G. Knepley Level: developer 79597cd05799SMatthew G. Knepley 79607cd05799SMatthew G. Knepley .seealso DMPlexSetVTKCellHeight() 79617cd05799SMatthew G. Knepley @*/ 7962552f7358SJed Brown PetscErrorCode DMPlexGetVTKCellHeight(DM dm, PetscInt *cellHeight) 7963552f7358SJed Brown { 7964552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 7965552f7358SJed Brown 7966552f7358SJed Brown PetscFunctionBegin; 7967552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7968552f7358SJed Brown PetscValidPointer(cellHeight, 2); 7969552f7358SJed Brown *cellHeight = mesh->vtkCellHeight; 7970552f7358SJed Brown PetscFunctionReturn(0); 7971552f7358SJed Brown } 7972552f7358SJed Brown 79737cd05799SMatthew G. Knepley /*@C 79747cd05799SMatthew G. Knepley DMPlexSetVTKCellHeight - Sets the height in the DAG used to determine which points are cells (normally 0) 79757cd05799SMatthew G. Knepley 79767cd05799SMatthew G. Knepley Input Parameters: 79777cd05799SMatthew G. Knepley + dm - The DMPlex object 79787cd05799SMatthew G. Knepley - cellHeight - The height of a cell 79797cd05799SMatthew G. Knepley 79807cd05799SMatthew G. Knepley Level: developer 79817cd05799SMatthew G. Knepley 79827cd05799SMatthew G. Knepley .seealso DMPlexGetVTKCellHeight() 79837cd05799SMatthew G. Knepley @*/ 7984552f7358SJed Brown PetscErrorCode DMPlexSetVTKCellHeight(DM dm, PetscInt cellHeight) 7985552f7358SJed Brown { 7986552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 7987552f7358SJed Brown 7988552f7358SJed Brown PetscFunctionBegin; 7989552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7990552f7358SJed Brown mesh->vtkCellHeight = cellHeight; 7991552f7358SJed Brown PetscFunctionReturn(0); 7992552f7358SJed Brown } 7993552f7358SJed Brown 7994e6139122SMatthew G. Knepley /*@ 7995e6139122SMatthew G. Knepley DMPlexGetGhostCellStratum - Get the range of cells which are used to enforce FV boundary conditions 7996e6139122SMatthew G. Knepley 7997e6139122SMatthew G. Knepley Input Parameter: 7998e6139122SMatthew G. Knepley . dm - The DMPlex object 7999e6139122SMatthew G. Knepley 8000e6139122SMatthew G. Knepley Output Parameters: 80012a9f31c0SMatthew G. Knepley + gcStart - The first ghost cell, or NULL 80022a9f31c0SMatthew G. Knepley - gcEnd - The upper bound on ghost cells, or NULL 8003e6139122SMatthew G. Knepley 80042a9f31c0SMatthew G. Knepley Level: advanced 8005e6139122SMatthew G. Knepley 80068065b584SMatthew Knepley .seealso DMPlexConstructGhostCells(), DMPlexGetGhostCellStratum() 8007e6139122SMatthew G. Knepley @*/ 8008e6139122SMatthew G. Knepley PetscErrorCode DMPlexGetGhostCellStratum(DM dm, PetscInt *gcStart, PetscInt *gcEnd) 8009e6139122SMatthew G. Knepley { 8010412e9a14SMatthew G. Knepley DMLabel ctLabel; 8011e6139122SMatthew G. Knepley PetscErrorCode ierr; 8012e6139122SMatthew G. Knepley 8013e6139122SMatthew G. Knepley PetscFunctionBegin; 8014e6139122SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8015412e9a14SMatthew G. Knepley ierr = DMPlexGetCellTypeLabel(dm, &ctLabel);CHKERRQ(ierr); 8016412e9a14SMatthew G. Knepley ierr = DMLabelGetStratumBounds(ctLabel, DM_POLYTOPE_FV_GHOST, gcStart, gcEnd);CHKERRQ(ierr); 8017e6139122SMatthew G. Knepley PetscFunctionReturn(0); 8018e6139122SMatthew G. Knepley } 8019e6139122SMatthew G. Knepley 80209886b8cfSStefano Zampini PetscErrorCode DMPlexCreateNumbering_Plex(DM dm, PetscInt pStart, PetscInt pEnd, PetscInt shift, PetscInt *globalSize, PetscSF sf, IS *numbering) 8021552f7358SJed Brown { 8022552f7358SJed Brown PetscSection section, globalSection; 8023552f7358SJed Brown PetscInt *numbers, p; 8024552f7358SJed Brown PetscErrorCode ierr; 8025552f7358SJed Brown 8026552f7358SJed Brown PetscFunctionBegin; 802782f516ccSBarry Smith ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), §ion);CHKERRQ(ierr); 8028552f7358SJed Brown ierr = PetscSectionSetChart(section, pStart, pEnd);CHKERRQ(ierr); 8029552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 8030552f7358SJed Brown ierr = PetscSectionSetDof(section, p, 1);CHKERRQ(ierr); 8031552f7358SJed Brown } 8032552f7358SJed Brown ierr = PetscSectionSetUp(section);CHKERRQ(ierr); 803315b58121SMatthew G. Knepley ierr = PetscSectionCreateGlobalSection(section, sf, PETSC_FALSE, PETSC_FALSE, &globalSection);CHKERRQ(ierr); 8034854ce69bSBarry Smith ierr = PetscMalloc1(pEnd - pStart, &numbers);CHKERRQ(ierr); 8035552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 8036552f7358SJed Brown ierr = PetscSectionGetOffset(globalSection, p, &numbers[p-pStart]);CHKERRQ(ierr); 8037ef48cebcSMatthew G. Knepley if (numbers[p-pStart] < 0) numbers[p-pStart] -= shift; 8038ef48cebcSMatthew G. Knepley else numbers[p-pStart] += shift; 8039552f7358SJed Brown } 804082f516ccSBarry Smith ierr = ISCreateGeneral(PetscObjectComm((PetscObject) dm), pEnd - pStart, numbers, PETSC_OWN_POINTER, numbering);CHKERRQ(ierr); 8041ef48cebcSMatthew G. Knepley if (globalSize) { 8042ef48cebcSMatthew G. Knepley PetscLayout layout; 8043ef48cebcSMatthew G. Knepley ierr = PetscSectionGetPointLayout(PetscObjectComm((PetscObject) dm), globalSection, &layout);CHKERRQ(ierr); 8044ef48cebcSMatthew G. Knepley ierr = PetscLayoutGetSize(layout, globalSize);CHKERRQ(ierr); 8045ef48cebcSMatthew G. Knepley ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr); 8046ef48cebcSMatthew G. Knepley } 8047552f7358SJed Brown ierr = PetscSectionDestroy(§ion);CHKERRQ(ierr); 8048552f7358SJed Brown ierr = PetscSectionDestroy(&globalSection);CHKERRQ(ierr); 8049552f7358SJed Brown PetscFunctionReturn(0); 8050552f7358SJed Brown } 8051552f7358SJed Brown 805281ed3555SMatthew G. Knepley PetscErrorCode DMPlexCreateCellNumbering_Internal(DM dm, PetscBool includeHybrid, IS *globalCellNumbers) 8053552f7358SJed Brown { 8054412e9a14SMatthew G. Knepley PetscInt cellHeight, cStart, cEnd; 8055552f7358SJed Brown PetscErrorCode ierr; 8056552f7358SJed Brown 8057552f7358SJed Brown PetscFunctionBegin; 8058552f7358SJed Brown ierr = DMPlexGetVTKCellHeight(dm, &cellHeight);CHKERRQ(ierr); 8059412e9a14SMatthew G. Knepley if (includeHybrid) {ierr = DMPlexGetHeightStratum(dm, cellHeight, &cStart, &cEnd);CHKERRQ(ierr);} 8060412e9a14SMatthew G. Knepley else {ierr = DMPlexGetSimplexOrBoxCells(dm, cellHeight, &cStart, &cEnd);CHKERRQ(ierr);} 80619886b8cfSStefano Zampini ierr = DMPlexCreateNumbering_Plex(dm, cStart, cEnd, 0, NULL, dm->sf, globalCellNumbers);CHKERRQ(ierr); 806281ed3555SMatthew G. Knepley PetscFunctionReturn(0); 8063552f7358SJed Brown } 806481ed3555SMatthew G. Knepley 80658dab3259SMatthew G. Knepley /*@ 80667cd05799SMatthew G. Knepley DMPlexGetCellNumbering - Get a global cell numbering for all cells on this process 80677cd05799SMatthew G. Knepley 80687cd05799SMatthew G. Knepley Input Parameter: 80697cd05799SMatthew G. Knepley . dm - The DMPlex object 80707cd05799SMatthew G. Knepley 80717cd05799SMatthew G. Knepley Output Parameter: 80727cd05799SMatthew G. Knepley . globalCellNumbers - Global cell numbers for all cells on this process 80737cd05799SMatthew G. Knepley 80747cd05799SMatthew G. Knepley Level: developer 80757cd05799SMatthew G. Knepley 80767cd05799SMatthew G. Knepley .seealso DMPlexGetVertexNumbering() 80777cd05799SMatthew G. Knepley @*/ 807881ed3555SMatthew G. Knepley PetscErrorCode DMPlexGetCellNumbering(DM dm, IS *globalCellNumbers) 807981ed3555SMatthew G. Knepley { 808081ed3555SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 808181ed3555SMatthew G. Knepley PetscErrorCode ierr; 808281ed3555SMatthew G. Knepley 808381ed3555SMatthew G. Knepley PetscFunctionBegin; 808481ed3555SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 808581ed3555SMatthew G. Knepley if (!mesh->globalCellNumbers) {ierr = DMPlexCreateCellNumbering_Internal(dm, PETSC_FALSE, &mesh->globalCellNumbers);CHKERRQ(ierr);} 8086552f7358SJed Brown *globalCellNumbers = mesh->globalCellNumbers; 8087552f7358SJed Brown PetscFunctionReturn(0); 8088552f7358SJed Brown } 8089552f7358SJed Brown 809081ed3555SMatthew G. Knepley PetscErrorCode DMPlexCreateVertexNumbering_Internal(DM dm, PetscBool includeHybrid, IS *globalVertexNumbers) 809181ed3555SMatthew G. Knepley { 8092412e9a14SMatthew G. Knepley PetscInt vStart, vEnd; 809381ed3555SMatthew G. Knepley PetscErrorCode ierr; 809481ed3555SMatthew G. Knepley 809581ed3555SMatthew G. Knepley PetscFunctionBegin; 809681ed3555SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 809781ed3555SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 80989886b8cfSStefano Zampini ierr = DMPlexCreateNumbering_Plex(dm, vStart, vEnd, 0, NULL, dm->sf, globalVertexNumbers);CHKERRQ(ierr); 809981ed3555SMatthew G. Knepley PetscFunctionReturn(0); 810081ed3555SMatthew G. Knepley } 810181ed3555SMatthew G. Knepley 81028dab3259SMatthew G. Knepley /*@ 81036aa51ba9SJacob Faibussowitsch DMPlexGetVertexNumbering - Get a global vertex numbering for all vertices on this process 81047cd05799SMatthew G. Knepley 81057cd05799SMatthew G. Knepley Input Parameter: 81067cd05799SMatthew G. Knepley . dm - The DMPlex object 81077cd05799SMatthew G. Knepley 81087cd05799SMatthew G. Knepley Output Parameter: 81097cd05799SMatthew G. Knepley . globalVertexNumbers - Global vertex numbers for all vertices on this process 81107cd05799SMatthew G. Knepley 81117cd05799SMatthew G. Knepley Level: developer 81127cd05799SMatthew G. Knepley 81137cd05799SMatthew G. Knepley .seealso DMPlexGetCellNumbering() 81147cd05799SMatthew G. Knepley @*/ 8115552f7358SJed Brown PetscErrorCode DMPlexGetVertexNumbering(DM dm, IS *globalVertexNumbers) 8116552f7358SJed Brown { 8117552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 8118552f7358SJed Brown PetscErrorCode ierr; 8119552f7358SJed Brown 8120552f7358SJed Brown PetscFunctionBegin; 8121552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 812281ed3555SMatthew G. Knepley if (!mesh->globalVertexNumbers) {ierr = DMPlexCreateVertexNumbering_Internal(dm, PETSC_FALSE, &mesh->globalVertexNumbers);CHKERRQ(ierr);} 8123552f7358SJed Brown *globalVertexNumbers = mesh->globalVertexNumbers; 8124552f7358SJed Brown PetscFunctionReturn(0); 8125552f7358SJed Brown } 8126552f7358SJed Brown 81278dab3259SMatthew G. Knepley /*@ 81287cd05799SMatthew G. Knepley DMPlexCreatePointNumbering - Create a global numbering for all points on this process 81297cd05799SMatthew G. Knepley 81307cd05799SMatthew G. Knepley Input Parameter: 81317cd05799SMatthew G. Knepley . dm - The DMPlex object 81327cd05799SMatthew G. Knepley 81337cd05799SMatthew G. Knepley Output Parameter: 81347cd05799SMatthew G. Knepley . globalPointNumbers - Global numbers for all points on this process 81357cd05799SMatthew G. Knepley 81367cd05799SMatthew G. Knepley Level: developer 81377cd05799SMatthew G. Knepley 81387cd05799SMatthew G. Knepley .seealso DMPlexGetCellNumbering() 81397cd05799SMatthew G. Knepley @*/ 8140ef48cebcSMatthew G. Knepley PetscErrorCode DMPlexCreatePointNumbering(DM dm, IS *globalPointNumbers) 8141ef48cebcSMatthew G. Knepley { 8142ef48cebcSMatthew G. Knepley IS nums[4]; 8143862913ffSStefano Zampini PetscInt depths[4], gdepths[4], starts[4]; 8144ef48cebcSMatthew G. Knepley PetscInt depth, d, shift = 0; 8145ef48cebcSMatthew G. Knepley PetscErrorCode ierr; 8146ef48cebcSMatthew G. Knepley 8147ef48cebcSMatthew G. Knepley PetscFunctionBegin; 8148ef48cebcSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8149ef48cebcSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 81508abc87a0SMichael Lange /* For unstratified meshes use dim instead of depth */ 81518abc87a0SMichael Lange if (depth < 0) {ierr = DMGetDimension(dm, &depth);CHKERRQ(ierr);} 8152862913ffSStefano Zampini for (d = 0; d <= depth; ++d) { 8153862913ffSStefano Zampini PetscInt end; 8154862913ffSStefano Zampini 8155862913ffSStefano Zampini depths[d] = depth-d; 8156862913ffSStefano Zampini ierr = DMPlexGetDepthStratum(dm, depths[d], &starts[d], &end);CHKERRQ(ierr); 8157862913ffSStefano Zampini if (!(starts[d]-end)) { starts[d] = depths[d] = -1; } 8158862913ffSStefano Zampini } 8159862913ffSStefano Zampini ierr = PetscSortIntWithArray(depth+1, starts, depths);CHKERRQ(ierr); 8160820f2d46SBarry Smith ierr = MPIU_Allreduce(depths, gdepths, depth+1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject) dm));CHKERRMPI(ierr); 8161862913ffSStefano Zampini for (d = 0; d <= depth; ++d) { 81622c71b3e2SJacob Faibussowitsch PetscCheckFalse(starts[d] >= 0 && depths[d] != gdepths[d],PETSC_COMM_SELF,PETSC_ERR_PLIB,"Expected depth %D, found %D",depths[d],gdepths[d]); 8163862913ffSStefano Zampini } 8164ef48cebcSMatthew G. Knepley for (d = 0; d <= depth; ++d) { 8165ef48cebcSMatthew G. Knepley PetscInt pStart, pEnd, gsize; 8166ef48cebcSMatthew G. Knepley 8167862913ffSStefano Zampini ierr = DMPlexGetDepthStratum(dm, gdepths[d], &pStart, &pEnd);CHKERRQ(ierr); 81689886b8cfSStefano Zampini ierr = DMPlexCreateNumbering_Plex(dm, pStart, pEnd, shift, &gsize, dm->sf, &nums[d]);CHKERRQ(ierr); 8169ef48cebcSMatthew G. Knepley shift += gsize; 8170ef48cebcSMatthew G. Knepley } 8171302440fdSBarry Smith ierr = ISConcatenate(PetscObjectComm((PetscObject) dm), depth+1, nums, globalPointNumbers);CHKERRQ(ierr); 8172ef48cebcSMatthew G. Knepley for (d = 0; d <= depth; ++d) {ierr = ISDestroy(&nums[d]);CHKERRQ(ierr);} 8173ef48cebcSMatthew G. Knepley PetscFunctionReturn(0); 8174ef48cebcSMatthew G. Knepley } 8175ef48cebcSMatthew G. Knepley 817608a22f4bSMatthew G. Knepley /*@ 817708a22f4bSMatthew G. Knepley DMPlexCreateRankField - Create a cell field whose value is the rank of the owner 817808a22f4bSMatthew G. Knepley 817908a22f4bSMatthew G. Knepley Input Parameter: 818008a22f4bSMatthew G. Knepley . dm - The DMPlex object 818108a22f4bSMatthew G. Knepley 818208a22f4bSMatthew G. Knepley Output Parameter: 818308a22f4bSMatthew G. Knepley . ranks - The rank field 818408a22f4bSMatthew G. Knepley 818508a22f4bSMatthew G. Knepley Options Database Keys: 818608a22f4bSMatthew G. Knepley . -dm_partition_view - Adds the rank field into the DM output from -dm_view using the same viewer 818708a22f4bSMatthew G. Knepley 818808a22f4bSMatthew G. Knepley Level: intermediate 818908a22f4bSMatthew G. Knepley 819008a22f4bSMatthew G. Knepley .seealso: DMView() 819108a22f4bSMatthew G. Knepley @*/ 819208a22f4bSMatthew G. Knepley PetscErrorCode DMPlexCreateRankField(DM dm, Vec *ranks) 819308a22f4bSMatthew G. Knepley { 819408a22f4bSMatthew G. Knepley DM rdm; 819508a22f4bSMatthew G. Knepley PetscFE fe; 819608a22f4bSMatthew G. Knepley PetscScalar *r; 819708a22f4bSMatthew G. Knepley PetscMPIInt rank; 8198a55f9a55SMatthew G. Knepley DMPolytopeType ct; 819908a22f4bSMatthew G. Knepley PetscInt dim, cStart, cEnd, c; 8200a55f9a55SMatthew G. Knepley PetscBool simplex; 820108a22f4bSMatthew G. Knepley PetscErrorCode ierr; 820208a22f4bSMatthew G. Knepley 820308a22f4bSMatthew G. Knepley PetscFunctionBeginUser; 8204f95ace6aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8205f95ace6aSMatthew G. Knepley PetscValidPointer(ranks, 2); 8206ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject) dm), &rank);CHKERRMPI(ierr); 820708a22f4bSMatthew G. Knepley ierr = DMClone(dm, &rdm);CHKERRQ(ierr); 820808a22f4bSMatthew G. Knepley ierr = DMGetDimension(rdm, &dim);CHKERRQ(ierr); 8209a55f9a55SMatthew G. Knepley ierr = DMPlexGetHeightStratum(rdm, 0, &cStart, &cEnd);CHKERRQ(ierr); 8210a55f9a55SMatthew G. Knepley ierr = DMPlexGetCellType(dm, cStart, &ct);CHKERRQ(ierr); 8211a55f9a55SMatthew G. Knepley simplex = DMPolytopeTypeGetNumVertices(ct) == DMPolytopeTypeGetDim(ct)+1 ? PETSC_TRUE : PETSC_FALSE; 8212a55f9a55SMatthew G. Knepley ierr = PetscFECreateDefault(PETSC_COMM_SELF, dim, 1, simplex, "PETSc___rank_", -1, &fe);CHKERRQ(ierr); 821308a22f4bSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) fe, "rank");CHKERRQ(ierr); 8214e5e52638SMatthew G. Knepley ierr = DMSetField(rdm, 0, NULL, (PetscObject) fe);CHKERRQ(ierr); 821508a22f4bSMatthew G. Knepley ierr = PetscFEDestroy(&fe);CHKERRQ(ierr); 8216e5e52638SMatthew G. Knepley ierr = DMCreateDS(rdm);CHKERRQ(ierr); 821708a22f4bSMatthew G. Knepley ierr = DMCreateGlobalVector(rdm, ranks);CHKERRQ(ierr); 821808a22f4bSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) *ranks, "partition");CHKERRQ(ierr); 821908a22f4bSMatthew G. Knepley ierr = VecGetArray(*ranks, &r);CHKERRQ(ierr); 822008a22f4bSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 822108a22f4bSMatthew G. Knepley PetscScalar *lr; 822208a22f4bSMatthew G. Knepley 822308a22f4bSMatthew G. Knepley ierr = DMPlexPointGlobalRef(rdm, c, r, &lr);CHKERRQ(ierr); 822471f09efeSPierre Jolivet if (lr) *lr = rank; 822508a22f4bSMatthew G. Knepley } 822608a22f4bSMatthew G. Knepley ierr = VecRestoreArray(*ranks, &r);CHKERRQ(ierr); 822708a22f4bSMatthew G. Knepley ierr = DMDestroy(&rdm);CHKERRQ(ierr); 822808a22f4bSMatthew G. Knepley PetscFunctionReturn(0); 822908a22f4bSMatthew G. Knepley } 823008a22f4bSMatthew G. Knepley 8231ca8062c8SMatthew G. Knepley /*@ 823218e14f0cSMatthew G. Knepley DMPlexCreateLabelField - Create a cell field whose value is the label value for that cell 823318e14f0cSMatthew G. Knepley 823418e14f0cSMatthew G. Knepley Input Parameters: 823518e14f0cSMatthew G. Knepley + dm - The DMPlex 823618e14f0cSMatthew G. Knepley - label - The DMLabel 823718e14f0cSMatthew G. Knepley 823818e14f0cSMatthew G. Knepley Output Parameter: 823918e14f0cSMatthew G. Knepley . val - The label value field 824018e14f0cSMatthew G. Knepley 824118e14f0cSMatthew G. Knepley Options Database Keys: 824218e14f0cSMatthew G. Knepley . -dm_label_view - Adds the label value field into the DM output from -dm_view using the same viewer 824318e14f0cSMatthew G. Knepley 824418e14f0cSMatthew G. Knepley Level: intermediate 824518e14f0cSMatthew G. Knepley 824618e14f0cSMatthew G. Knepley .seealso: DMView() 824718e14f0cSMatthew G. Knepley @*/ 824818e14f0cSMatthew G. Knepley PetscErrorCode DMPlexCreateLabelField(DM dm, DMLabel label, Vec *val) 824918e14f0cSMatthew G. Knepley { 825018e14f0cSMatthew G. Knepley DM rdm; 825118e14f0cSMatthew G. Knepley PetscFE fe; 825218e14f0cSMatthew G. Knepley PetscScalar *v; 825318e14f0cSMatthew G. Knepley PetscInt dim, cStart, cEnd, c; 825418e14f0cSMatthew G. Knepley PetscErrorCode ierr; 825518e14f0cSMatthew G. Knepley 825618e14f0cSMatthew G. Knepley PetscFunctionBeginUser; 825718e14f0cSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 825818e14f0cSMatthew G. Knepley PetscValidPointer(label, 2); 825918e14f0cSMatthew G. Knepley PetscValidPointer(val, 3); 826018e14f0cSMatthew G. Knepley ierr = DMClone(dm, &rdm);CHKERRQ(ierr); 826118e14f0cSMatthew G. Knepley ierr = DMGetDimension(rdm, &dim);CHKERRQ(ierr); 826218e14f0cSMatthew G. Knepley ierr = PetscFECreateDefault(PetscObjectComm((PetscObject) rdm), dim, 1, PETSC_TRUE, "PETSc___label_value_", -1, &fe);CHKERRQ(ierr); 826318e14f0cSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) fe, "label_value");CHKERRQ(ierr); 8264e5e52638SMatthew G. Knepley ierr = DMSetField(rdm, 0, NULL, (PetscObject) fe);CHKERRQ(ierr); 826518e14f0cSMatthew G. Knepley ierr = PetscFEDestroy(&fe);CHKERRQ(ierr); 8266e5e52638SMatthew G. Knepley ierr = DMCreateDS(rdm);CHKERRQ(ierr); 826718e14f0cSMatthew G. Knepley ierr = DMPlexGetHeightStratum(rdm, 0, &cStart, &cEnd);CHKERRQ(ierr); 826818e14f0cSMatthew G. Knepley ierr = DMCreateGlobalVector(rdm, val);CHKERRQ(ierr); 8269effbd7cbSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) *val, "label_value");CHKERRQ(ierr); 827018e14f0cSMatthew G. Knepley ierr = VecGetArray(*val, &v);CHKERRQ(ierr); 827118e14f0cSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 827218e14f0cSMatthew G. Knepley PetscScalar *lv; 827318e14f0cSMatthew G. Knepley PetscInt cval; 827418e14f0cSMatthew G. Knepley 827518e14f0cSMatthew G. Knepley ierr = DMPlexPointGlobalRef(rdm, c, v, &lv);CHKERRQ(ierr); 827618e14f0cSMatthew G. Knepley ierr = DMLabelGetValue(label, c, &cval);CHKERRQ(ierr); 827718e14f0cSMatthew G. Knepley *lv = cval; 827818e14f0cSMatthew G. Knepley } 827918e14f0cSMatthew G. Knepley ierr = VecRestoreArray(*val, &v);CHKERRQ(ierr); 828018e14f0cSMatthew G. Knepley ierr = DMDestroy(&rdm);CHKERRQ(ierr); 828118e14f0cSMatthew G. Knepley PetscFunctionReturn(0); 828218e14f0cSMatthew G. Knepley } 828318e14f0cSMatthew G. Knepley 828418e14f0cSMatthew G. Knepley /*@ 8285ca8062c8SMatthew G. Knepley DMPlexCheckSymmetry - Check that the adjacency information in the mesh is symmetric. 8286ca8062c8SMatthew G. Knepley 828769916449SMatthew G. Knepley Input Parameter: 828869916449SMatthew G. Knepley . dm - The DMPlex object 8289ca8062c8SMatthew G. Knepley 829095eb5ee5SVaclav Hapla Notes: 829195eb5ee5SVaclav Hapla This is a useful diagnostic when creating meshes programmatically. 829295eb5ee5SVaclav Hapla 829395eb5ee5SVaclav Hapla For the complete list of DMPlexCheck* functions, see DMSetFromOptions(). 8294ca8062c8SMatthew G. Knepley 8295ca8062c8SMatthew G. Knepley Level: developer 8296ca8062c8SMatthew G. Knepley 829795eb5ee5SVaclav Hapla .seealso: DMCreate(), DMSetFromOptions() 8298ca8062c8SMatthew G. Knepley @*/ 8299ca8062c8SMatthew G. Knepley PetscErrorCode DMPlexCheckSymmetry(DM dm) 8300ca8062c8SMatthew G. Knepley { 8301ca8062c8SMatthew G. Knepley PetscSection coneSection, supportSection; 8302ca8062c8SMatthew G. Knepley const PetscInt *cone, *support; 8303ca8062c8SMatthew G. Knepley PetscInt coneSize, c, supportSize, s; 830457beb4faSStefano Zampini PetscInt pStart, pEnd, p, pp, csize, ssize; 830557beb4faSStefano Zampini PetscBool storagecheck = PETSC_TRUE; 8306ca8062c8SMatthew G. Knepley PetscErrorCode ierr; 8307ca8062c8SMatthew G. Knepley 8308ca8062c8SMatthew G. Knepley PetscFunctionBegin; 8309ca8062c8SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8310412e9a14SMatthew G. Knepley ierr = DMViewFromOptions(dm, NULL, "-sym_dm_view");CHKERRQ(ierr); 8311ca8062c8SMatthew G. Knepley ierr = DMPlexGetConeSection(dm, &coneSection);CHKERRQ(ierr); 8312ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupportSection(dm, &supportSection);CHKERRQ(ierr); 8313ca8062c8SMatthew G. Knepley /* Check that point p is found in the support of its cone points, and vice versa */ 8314ca8062c8SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 8315ca8062c8SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 8316ca8062c8SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, p, &coneSize);CHKERRQ(ierr); 8317ca8062c8SMatthew G. Knepley ierr = DMPlexGetCone(dm, p, &cone);CHKERRQ(ierr); 8318ca8062c8SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 831942e66dfaSMatthew G. Knepley PetscBool dup = PETSC_FALSE; 832042e66dfaSMatthew G. Knepley PetscInt d; 832142e66dfaSMatthew G. Knepley for (d = c-1; d >= 0; --d) { 832242e66dfaSMatthew G. Knepley if (cone[c] == cone[d]) {dup = PETSC_TRUE; break;} 832342e66dfaSMatthew G. Knepley } 8324ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, cone[c], &supportSize);CHKERRQ(ierr); 8325ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupport(dm, cone[c], &support);CHKERRQ(ierr); 8326ca8062c8SMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 8327ca8062c8SMatthew G. Knepley if (support[s] == p) break; 8328ca8062c8SMatthew G. Knepley } 832942e66dfaSMatthew G. Knepley if ((s >= supportSize) || (dup && (support[s+1] != p))) { 83308ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "p: %D cone: ", p);CHKERRQ(ierr); 8331ca8062c8SMatthew G. Knepley for (s = 0; s < coneSize; ++s) { 83328ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "%D, ", cone[s]);CHKERRQ(ierr); 8333ca8062c8SMatthew G. Knepley } 8334302440fdSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 83358ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "p: %D support: ", cone[c]);CHKERRQ(ierr); 8336ca8062c8SMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 83378ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "%D, ", support[s]);CHKERRQ(ierr); 8338ca8062c8SMatthew G. Knepley } 8339302440fdSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 83402c71b3e2SJacob Faibussowitsch PetscCheckFalse(dup,PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D not repeatedly found in support of repeated cone point %D", p, cone[c]); 834198921bdaSJacob Faibussowitsch else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D not found in support of cone point %D", p, cone[c]); 8342ca8062c8SMatthew G. Knepley } 834342e66dfaSMatthew G. Knepley } 834457beb4faSStefano Zampini ierr = DMPlexGetTreeParent(dm, p, &pp, NULL);CHKERRQ(ierr); 834557beb4faSStefano Zampini if (p != pp) { storagecheck = PETSC_FALSE; continue; } 8346ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, p, &supportSize);CHKERRQ(ierr); 8347ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupport(dm, p, &support);CHKERRQ(ierr); 8348ca8062c8SMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 8349ca8062c8SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 8350ca8062c8SMatthew G. Knepley ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 8351ca8062c8SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 835257beb4faSStefano Zampini ierr = DMPlexGetTreeParent(dm, cone[c], &pp, NULL);CHKERRQ(ierr); 835357beb4faSStefano Zampini if (cone[c] != pp) { c = 0; break; } 8354ca8062c8SMatthew G. Knepley if (cone[c] == p) break; 8355ca8062c8SMatthew G. Knepley } 8356ca8062c8SMatthew G. Knepley if (c >= coneSize) { 83578ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "p: %D support: ", p);CHKERRQ(ierr); 8358ca8062c8SMatthew G. Knepley for (c = 0; c < supportSize; ++c) { 83598ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "%D, ", support[c]);CHKERRQ(ierr); 8360ca8062c8SMatthew G. Knepley } 8361302440fdSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 83628ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "p: %D cone: ", support[s]);CHKERRQ(ierr); 8363ca8062c8SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 83648ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "%D, ", cone[c]);CHKERRQ(ierr); 8365ca8062c8SMatthew G. Knepley } 8366302440fdSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 836798921bdaSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D not found in cone of support point %D", p, support[s]); 8368ca8062c8SMatthew G. Knepley } 8369ca8062c8SMatthew G. Knepley } 8370ca8062c8SMatthew G. Knepley } 837157beb4faSStefano Zampini if (storagecheck) { 8372ca8062c8SMatthew G. Knepley ierr = PetscSectionGetStorageSize(coneSection, &csize);CHKERRQ(ierr); 8373ca8062c8SMatthew G. Knepley ierr = PetscSectionGetStorageSize(supportSection, &ssize);CHKERRQ(ierr); 83742c71b3e2SJacob Faibussowitsch PetscCheckFalse(csize != ssize,PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Total cone size %D != Total support size %D", csize, ssize); 837557beb4faSStefano Zampini } 8376ca8062c8SMatthew G. Knepley PetscFunctionReturn(0); 8377ca8062c8SMatthew G. Knepley } 8378ca8062c8SMatthew G. Knepley 8379412e9a14SMatthew G. Knepley /* 8380412e9a14SMatthew G. Knepley For submeshes with cohesive cells (see DMPlexConstructCohesiveCells()), we allow a special case where some of the boundary of a face (edges and vertices) are not duplicated. We call these special boundary points "unsplit", since the same edge or vertex appears in both copies of the face. These unsplit points throw off our counting, so we have to explicitly account for them here. 8381412e9a14SMatthew G. Knepley */ 8382412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellUnsplitVertices_Private(DM dm, PetscInt c, DMPolytopeType ct, PetscInt *unsplit) 8383412e9a14SMatthew G. Knepley { 8384412e9a14SMatthew G. Knepley DMPolytopeType cct; 8385412e9a14SMatthew G. Knepley PetscInt ptpoints[4]; 8386412e9a14SMatthew G. Knepley const PetscInt *cone, *ccone, *ptcone; 8387412e9a14SMatthew G. Knepley PetscInt coneSize, cp, cconeSize, ccp, npt = 0, pt; 8388412e9a14SMatthew G. Knepley PetscErrorCode ierr; 8389412e9a14SMatthew G. Knepley 8390412e9a14SMatthew G. Knepley PetscFunctionBegin; 8391412e9a14SMatthew G. Knepley *unsplit = 0; 8392412e9a14SMatthew G. Knepley switch (ct) { 8393b5a892a1SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 8394b5a892a1SMatthew G. Knepley ptpoints[npt++] = c; 8395b5a892a1SMatthew G. Knepley break; 8396412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 8397412e9a14SMatthew G. Knepley ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 8398412e9a14SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, c, &coneSize);CHKERRQ(ierr); 8399412e9a14SMatthew G. Knepley for (cp = 0; cp < coneSize; ++cp) { 8400412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, cone[cp], &cct);CHKERRQ(ierr); 8401412e9a14SMatthew G. Knepley if (cct == DM_POLYTOPE_POINT_PRISM_TENSOR) ptpoints[npt++] = cone[cp]; 8402412e9a14SMatthew G. Knepley } 8403412e9a14SMatthew G. Knepley break; 8404412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 8405412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 8406412e9a14SMatthew G. Knepley ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 8407412e9a14SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, c, &coneSize);CHKERRQ(ierr); 8408412e9a14SMatthew G. Knepley for (cp = 0; cp < coneSize; ++cp) { 8409412e9a14SMatthew G. Knepley ierr = DMPlexGetCone(dm, cone[cp], &ccone);CHKERRQ(ierr); 8410412e9a14SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, cone[cp], &cconeSize);CHKERRQ(ierr); 8411412e9a14SMatthew G. Knepley for (ccp = 0; ccp < cconeSize; ++ccp) { 8412412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, ccone[ccp], &cct);CHKERRQ(ierr); 8413412e9a14SMatthew G. Knepley if (cct == DM_POLYTOPE_POINT_PRISM_TENSOR) { 8414412e9a14SMatthew G. Knepley PetscInt p; 8415412e9a14SMatthew G. Knepley for (p = 0; p < npt; ++p) if (ptpoints[p] == ccone[ccp]) break; 8416412e9a14SMatthew G. Knepley if (p == npt) ptpoints[npt++] = ccone[ccp]; 8417412e9a14SMatthew G. Knepley } 8418412e9a14SMatthew G. Knepley } 8419412e9a14SMatthew G. Knepley } 8420412e9a14SMatthew G. Knepley break; 8421412e9a14SMatthew G. Knepley default: break; 8422412e9a14SMatthew G. Knepley } 8423412e9a14SMatthew G. Knepley for (pt = 0; pt < npt; ++pt) { 8424412e9a14SMatthew G. Knepley ierr = DMPlexGetCone(dm, ptpoints[pt], &ptcone);CHKERRQ(ierr); 8425412e9a14SMatthew G. Knepley if (ptcone[0] == ptcone[1]) ++(*unsplit); 8426412e9a14SMatthew G. Knepley } 8427412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 8428412e9a14SMatthew G. Knepley } 8429412e9a14SMatthew G. Knepley 8430ca8062c8SMatthew G. Knepley /*@ 8431ca8062c8SMatthew G. Knepley DMPlexCheckSkeleton - Check that each cell has the correct number of vertices 8432ca8062c8SMatthew G. Knepley 8433ca8062c8SMatthew G. Knepley Input Parameters: 8434ca8062c8SMatthew G. Knepley + dm - The DMPlex object 843558723a97SMatthew G. Knepley - cellHeight - Normally 0 8436ca8062c8SMatthew G. Knepley 843795eb5ee5SVaclav Hapla Notes: 843895eb5ee5SVaclav Hapla This is a useful diagnostic when creating meshes programmatically. 843925c50c26SVaclav Hapla Currently applicable only to homogeneous simplex or tensor meshes. 8440ca8062c8SMatthew G. Knepley 844195eb5ee5SVaclav Hapla For the complete list of DMPlexCheck* functions, see DMSetFromOptions(). 844295eb5ee5SVaclav Hapla 8443ca8062c8SMatthew G. Knepley Level: developer 8444ca8062c8SMatthew G. Knepley 844595eb5ee5SVaclav Hapla .seealso: DMCreate(), DMSetFromOptions() 8446ca8062c8SMatthew G. Knepley @*/ 844725c50c26SVaclav Hapla PetscErrorCode DMPlexCheckSkeleton(DM dm, PetscInt cellHeight) 8448ca8062c8SMatthew G. Knepley { 8449412e9a14SMatthew G. Knepley DMPlexInterpolatedFlag interp; 8450412e9a14SMatthew G. Knepley DMPolytopeType ct; 8451412e9a14SMatthew G. Knepley PetscInt vStart, vEnd, cStart, cEnd, c; 8452ca8062c8SMatthew G. Knepley PetscErrorCode ierr; 8453ca8062c8SMatthew G. Knepley 8454ca8062c8SMatthew G. Knepley PetscFunctionBegin; 8455ca8062c8SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8456412e9a14SMatthew G. Knepley ierr = DMPlexIsInterpolated(dm, &interp);CHKERRQ(ierr); 845725c50c26SVaclav Hapla ierr = DMPlexGetHeightStratum(dm, cellHeight, &cStart, &cEnd);CHKERRQ(ierr); 845858723a97SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 8459412e9a14SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 8460412e9a14SMatthew G. Knepley PetscInt *closure = NULL; 8461412e9a14SMatthew G. Knepley PetscInt coneSize, closureSize, cl, Nv = 0; 846258723a97SMatthew G. Knepley 8463412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, c, &ct);CHKERRQ(ierr); 84642c71b3e2SJacob Faibussowitsch PetscCheckFalse((PetscInt) ct < 0,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cell %D has no cell type", c); 8465412e9a14SMatthew G. Knepley if (ct == DM_POLYTOPE_UNKNOWN) continue; 8466412e9a14SMatthew G. Knepley if (interp == DMPLEX_INTERPOLATED_FULL) { 8467412e9a14SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, c, &coneSize);CHKERRQ(ierr); 84682c71b3e2SJacob Faibussowitsch PetscCheckFalse(coneSize != DMPolytopeTypeGetConeSize(ct),PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cell %D of type %s has cone size %D != %D", c, DMPolytopeTypes[ct], coneSize, DMPolytopeTypeGetConeSize(ct)); 8469412e9a14SMatthew G. Knepley } 847058723a97SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 847158723a97SMatthew G. Knepley for (cl = 0; cl < closureSize*2; cl += 2) { 847258723a97SMatthew G. Knepley const PetscInt p = closure[cl]; 8473412e9a14SMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) ++Nv; 847458723a97SMatthew G. Knepley } 847558723a97SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 8476412e9a14SMatthew G. Knepley /* Special Case: Tensor faces with identified vertices */ 8477412e9a14SMatthew G. Knepley if (Nv < DMPolytopeTypeGetNumVertices(ct)) { 8478412e9a14SMatthew G. Knepley PetscInt unsplit; 847942363296SMatthew G. Knepley 8480412e9a14SMatthew G. Knepley ierr = DMPlexCellUnsplitVertices_Private(dm, c, ct, &unsplit);CHKERRQ(ierr); 8481412e9a14SMatthew G. Knepley if (Nv + unsplit == DMPolytopeTypeGetNumVertices(ct)) continue; 848242363296SMatthew G. Knepley } 84832c71b3e2SJacob Faibussowitsch PetscCheckFalse(Nv != DMPolytopeTypeGetNumVertices(ct),PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cell %D of type %s has %D vertices != %D", c, DMPolytopeTypes[ct], Nv, DMPolytopeTypeGetNumVertices(ct)); 848442363296SMatthew G. Knepley } 8485ca8062c8SMatthew G. Knepley PetscFunctionReturn(0); 8486ca8062c8SMatthew G. Knepley } 84879bf0dad6SMatthew G. Knepley 84889bf0dad6SMatthew G. Knepley /*@ 84899bf0dad6SMatthew 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 84909bf0dad6SMatthew G. Knepley 8491899ea2b8SJacob Faibussowitsch Not Collective 8492899ea2b8SJacob Faibussowitsch 84939bf0dad6SMatthew G. Knepley Input Parameters: 84949bf0dad6SMatthew G. Knepley + dm - The DMPlex object 84959bf0dad6SMatthew G. Knepley - cellHeight - Normally 0 84969bf0dad6SMatthew G. Knepley 849745da879fSVaclav Hapla Notes: 849845da879fSVaclav Hapla This is a useful diagnostic when creating meshes programmatically. 849945da879fSVaclav Hapla This routine is only relevant for meshes that are fully interpolated across all ranks. 850045da879fSVaclav Hapla It will error out if a partially interpolated mesh is given on some rank. 850145da879fSVaclav Hapla It will do nothing for locally uninterpolated mesh (as there is nothing to check). 85029bf0dad6SMatthew G. Knepley 850395eb5ee5SVaclav Hapla For the complete list of DMPlexCheck* functions, see DMSetFromOptions(). 850495eb5ee5SVaclav Hapla 85059bf0dad6SMatthew G. Knepley Level: developer 85069bf0dad6SMatthew G. Knepley 850795eb5ee5SVaclav Hapla .seealso: DMCreate(), DMPlexGetVTKCellHeight(), DMSetFromOptions() 85089bf0dad6SMatthew G. Knepley @*/ 850925c50c26SVaclav Hapla PetscErrorCode DMPlexCheckFaces(DM dm, PetscInt cellHeight) 85109bf0dad6SMatthew G. Knepley { 8511ab91121cSMatthew G. Knepley PetscInt dim, depth, vStart, vEnd, cStart, cEnd, c, h; 85129bf0dad6SMatthew G. Knepley PetscErrorCode ierr; 8513899ea2b8SJacob Faibussowitsch DMPlexInterpolatedFlag interpEnum; 85149bf0dad6SMatthew G. Knepley 85159bf0dad6SMatthew G. Knepley PetscFunctionBegin; 85169bf0dad6SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8517899ea2b8SJacob Faibussowitsch ierr = DMPlexIsInterpolated(dm, &interpEnum);CHKERRQ(ierr); 851845da879fSVaclav Hapla if (interpEnum == DMPLEX_INTERPOLATED_NONE) PetscFunctionReturn(0); 851945da879fSVaclav Hapla if (interpEnum == DMPLEX_INTERPOLATED_PARTIAL) { 8520899ea2b8SJacob Faibussowitsch PetscMPIInt rank; 8521899ea2b8SJacob Faibussowitsch MPI_Comm comm; 8522899ea2b8SJacob Faibussowitsch 8523899ea2b8SJacob Faibussowitsch ierr = PetscObjectGetComm((PetscObject) dm, &comm);CHKERRQ(ierr); 8524ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 852598921bdaSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Mesh is only partially interpolated on rank %d, this is currently not supported", rank); 8526899ea2b8SJacob Faibussowitsch } 8527899ea2b8SJacob Faibussowitsch 8528c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 8529ab91121cSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 85309bf0dad6SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 8531ab91121cSMatthew G. Knepley for (h = cellHeight; h < PetscMin(depth, dim); ++h) { 85323554e41dSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, h, &cStart, &cEnd);CHKERRQ(ierr); 85333554e41dSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 8534412e9a14SMatthew G. Knepley const PetscInt *cone, *ornt, *faceSizes, *faces; 8535412e9a14SMatthew G. Knepley const DMPolytopeType *faceTypes; 8536ba2698f1SMatthew G. Knepley DMPolytopeType ct; 8537412e9a14SMatthew G. Knepley PetscInt numFaces, coneSize, f; 8538412e9a14SMatthew G. Knepley PetscInt *closure = NULL, closureSize, cl, numCorners = 0, fOff = 0, unsplit; 85399bf0dad6SMatthew G. Knepley 8540ba2698f1SMatthew G. Knepley ierr = DMPlexGetCellType(dm, c, &ct);CHKERRQ(ierr); 8541412e9a14SMatthew G. Knepley ierr = DMPlexCellUnsplitVertices_Private(dm, c, ct, &unsplit);CHKERRQ(ierr); 8542412e9a14SMatthew G. Knepley if (unsplit) continue; 85439bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, c, &coneSize);CHKERRQ(ierr); 85449bf0dad6SMatthew G. Knepley ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 85459bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 85469bf0dad6SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 85479bf0dad6SMatthew G. Knepley for (cl = 0; cl < closureSize*2; cl += 2) { 85489bf0dad6SMatthew G. Knepley const PetscInt p = closure[cl]; 85499bf0dad6SMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) closure[numCorners++] = p; 85509bf0dad6SMatthew G. Knepley } 8551412e9a14SMatthew G. Knepley ierr = DMPlexGetRawFaces_Internal(dm, ct, closure, &numFaces, &faceTypes, &faceSizes, &faces);CHKERRQ(ierr); 85522c71b3e2SJacob Faibussowitsch PetscCheckFalse(coneSize != numFaces,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cell %D of type %s has %D faces but should have %D", c, DMPolytopeTypes[ct], coneSize, numFaces); 85539bf0dad6SMatthew G. Knepley for (f = 0; f < numFaces; ++f) { 8554d4961f80SStefano Zampini DMPolytopeType fct; 85559bf0dad6SMatthew G. Knepley PetscInt *fclosure = NULL, fclosureSize, cl, fnumCorners = 0, v; 85569bf0dad6SMatthew G. Knepley 8557d4961f80SStefano Zampini ierr = DMPlexGetCellType(dm, cone[f], &fct);CHKERRQ(ierr); 85589bf0dad6SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure_Internal(dm, cone[f], ornt[f], PETSC_TRUE, &fclosureSize, &fclosure);CHKERRQ(ierr); 85599bf0dad6SMatthew G. Knepley for (cl = 0; cl < fclosureSize*2; cl += 2) { 85609bf0dad6SMatthew G. Knepley const PetscInt p = fclosure[cl]; 85619bf0dad6SMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) fclosure[fnumCorners++] = p; 85629bf0dad6SMatthew G. Knepley } 85632c71b3e2SJacob Faibussowitsch PetscCheckFalse(fnumCorners != faceSizes[f],PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Face %D of type %s (cone idx %D) of cell %D of type %s has %D vertices but should have %D", cone[f], DMPolytopeTypes[fct], f, c, DMPolytopeTypes[ct], fnumCorners, faceSizes[f]); 85649bf0dad6SMatthew G. Knepley for (v = 0; v < fnumCorners; ++v) { 8565b5a892a1SMatthew G. Knepley if (fclosure[v] != faces[fOff+v]) { 8566b5a892a1SMatthew G. Knepley PetscInt v1; 8567b5a892a1SMatthew G. Knepley 8568b5a892a1SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, "face closure:");CHKERRQ(ierr); 8569b5a892a1SMatthew G. Knepley for (v1 = 0; v1 < fnumCorners; ++v1) {ierr = PetscPrintf(PETSC_COMM_SELF, " %D", fclosure[v1]);CHKERRQ(ierr);} 8570b5a892a1SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, "\ncell face:");CHKERRQ(ierr); 8571b5a892a1SMatthew G. Knepley for (v1 = 0; v1 < fnumCorners; ++v1) {ierr = PetscPrintf(PETSC_COMM_SELF, " %D", faces[fOff+v1]);CHKERRQ(ierr);} 8572b5a892a1SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 857398921bdaSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Face %D of type %s (cone idx %d, ornt %D) of cell %D of type %s vertex %D, %D != %D", cone[f], DMPolytopeTypes[fct], f, ornt[f], c, DMPolytopeTypes[ct], v, fclosure[v], faces[fOff+v]); 8574b5a892a1SMatthew G. Knepley } 85759bf0dad6SMatthew G. Knepley } 85769bf0dad6SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, cone[f], PETSC_TRUE, &fclosureSize, &fclosure);CHKERRQ(ierr); 8577412e9a14SMatthew G. Knepley fOff += faceSizes[f]; 85789bf0dad6SMatthew G. Knepley } 8579412e9a14SMatthew G. Knepley ierr = DMPlexRestoreRawFaces_Internal(dm, ct, closure, &numFaces, &faceTypes, &faceSizes, &faces);CHKERRQ(ierr); 85809bf0dad6SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 85819bf0dad6SMatthew G. Knepley } 85823554e41dSMatthew G. Knepley } 8583552f7358SJed Brown PetscFunctionReturn(0); 8584552f7358SJed Brown } 85853913d7c8SMatthew G. Knepley 8586bb6a34a8SMatthew G. Knepley /*@ 8587bb6a34a8SMatthew G. Knepley DMPlexCheckGeometry - Check the geometry of mesh cells 8588bb6a34a8SMatthew G. Knepley 8589bb6a34a8SMatthew G. Knepley Input Parameter: 8590bb6a34a8SMatthew G. Knepley . dm - The DMPlex object 8591bb6a34a8SMatthew G. Knepley 859295eb5ee5SVaclav Hapla Notes: 859395eb5ee5SVaclav Hapla This is a useful diagnostic when creating meshes programmatically. 859495eb5ee5SVaclav Hapla 859595eb5ee5SVaclav Hapla For the complete list of DMPlexCheck* functions, see DMSetFromOptions(). 8596bb6a34a8SMatthew G. Knepley 8597bb6a34a8SMatthew G. Knepley Level: developer 8598bb6a34a8SMatthew G. Knepley 859995eb5ee5SVaclav Hapla .seealso: DMCreate(), DMSetFromOptions() 8600bb6a34a8SMatthew G. Knepley @*/ 8601bb6a34a8SMatthew G. Knepley PetscErrorCode DMPlexCheckGeometry(DM dm) 8602bb6a34a8SMatthew G. Knepley { 8603a2a9e04cSMatthew G. Knepley Vec coordinates; 8604bb6a34a8SMatthew G. Knepley PetscReal detJ, J[9], refVol = 1.0; 8605bb6a34a8SMatthew G. Knepley PetscReal vol; 8606412e9a14SMatthew G. Knepley PetscBool periodic; 860751a74b61SMatthew G. Knepley PetscInt dim, depth, dE, d, cStart, cEnd, c; 8608bb6a34a8SMatthew G. Knepley PetscErrorCode ierr; 8609bb6a34a8SMatthew G. Knepley 8610bb6a34a8SMatthew G. Knepley PetscFunctionBegin; 8611bb6a34a8SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 861251a74b61SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dE);CHKERRQ(ierr); 861351a74b61SMatthew G. Knepley if (dim != dE) PetscFunctionReturn(0); 8614bb6a34a8SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 8615412e9a14SMatthew G. Knepley ierr = DMGetPeriodicity(dm, &periodic, NULL, NULL, NULL);CHKERRQ(ierr); 8616bb6a34a8SMatthew G. Knepley for (d = 0; d < dim; ++d) refVol *= 2.0; 8617bb6a34a8SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 8618a2a9e04cSMatthew G. Knepley /* Make sure local coordinates are created, because that step is collective */ 8619a2a9e04cSMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 8620412e9a14SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 8621412e9a14SMatthew G. Knepley DMPolytopeType ct; 8622412e9a14SMatthew G. Knepley PetscInt unsplit; 8623412e9a14SMatthew G. Knepley PetscBool ignoreZeroVol = PETSC_FALSE; 8624412e9a14SMatthew G. Knepley 8625412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, c, &ct);CHKERRQ(ierr); 8626412e9a14SMatthew G. Knepley switch (ct) { 8627412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 8628412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 8629412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 8630412e9a14SMatthew G. Knepley ignoreZeroVol = PETSC_TRUE; break; 8631412e9a14SMatthew G. Knepley default: break; 8632412e9a14SMatthew G. Knepley } 8633412e9a14SMatthew G. Knepley switch (ct) { 8634412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: 8635412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 8636412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 8637a2a9e04cSMatthew G. Knepley case DM_POLYTOPE_PYRAMID: 8638412e9a14SMatthew G. Knepley continue; 8639412e9a14SMatthew G. Knepley default: break; 8640412e9a14SMatthew G. Knepley } 8641412e9a14SMatthew G. Knepley ierr = DMPlexCellUnsplitVertices_Private(dm, c, ct, &unsplit);CHKERRQ(ierr); 8642412e9a14SMatthew G. Knepley if (unsplit) continue; 8643bb6a34a8SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFEM(dm, c, NULL, NULL, J, NULL, &detJ);CHKERRQ(ierr); 86442c71b3e2SJacob Faibussowitsch PetscCheckFalse(detJ < -PETSC_SMALL || (detJ <= 0.0 && !ignoreZeroVol),PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Mesh cell %D of type %s is inverted, |J| = %g", c, DMPolytopeTypes[ct], (double) detJ); 86457d3de750SJacob Faibussowitsch ierr = PetscInfo(dm, "Cell %D FEM Volume %g\n", c, (double) detJ*refVol);CHKERRQ(ierr); 8646412e9a14SMatthew G. Knepley if (depth > 1 && !periodic) { 8647bb6a34a8SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFVM(dm, c, &vol, NULL, NULL);CHKERRQ(ierr); 86482c71b3e2SJacob Faibussowitsch PetscCheckFalse(vol < -PETSC_SMALL || (vol <= 0.0 && !ignoreZeroVol),PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Mesh cell %D of type %s is inverted, vol = %g", c, DMPolytopeTypes[ct], (double) vol); 86497d3de750SJacob Faibussowitsch ierr = PetscInfo(dm, "Cell %D FVM Volume %g\n", c, (double) vol);CHKERRQ(ierr); 8650bb6a34a8SMatthew G. Knepley } 8651bb6a34a8SMatthew G. Knepley } 8652bb6a34a8SMatthew G. Knepley PetscFunctionReturn(0); 8653bb6a34a8SMatthew G. Knepley } 8654bb6a34a8SMatthew G. Knepley 865503da9461SVaclav Hapla /*@ 8656e83a0d2dSVaclav Hapla DMPlexCheckPointSF - Check that several necessary conditions are met for the point SF of this plex. 865703da9461SVaclav Hapla 865803da9461SVaclav Hapla Input Parameters: 865903da9461SVaclav Hapla . dm - The DMPlex object 866003da9461SVaclav Hapla 8661e83a0d2dSVaclav Hapla Notes: 8662e83a0d2dSVaclav Hapla This is mainly intended for debugging/testing purposes. 86638918e3e2SVaclav Hapla It currently checks only meshes with no partition overlapping. 866403da9461SVaclav Hapla 866595eb5ee5SVaclav Hapla For the complete list of DMPlexCheck* functions, see DMSetFromOptions(). 866695eb5ee5SVaclav Hapla 866703da9461SVaclav Hapla Level: developer 866803da9461SVaclav Hapla 866995eb5ee5SVaclav Hapla .seealso: DMGetPointSF(), DMSetFromOptions() 867003da9461SVaclav Hapla @*/ 867103da9461SVaclav Hapla PetscErrorCode DMPlexCheckPointSF(DM dm) 867203da9461SVaclav Hapla { 8673f0cfc026SVaclav Hapla PetscSF pointSF; 8674f5869d18SMatthew G. Knepley PetscInt cellHeight, cStart, cEnd, l, nleaves, nroots, overlap; 8675f5869d18SMatthew G. Knepley const PetscInt *locals, *rootdegree; 8676f0cfc026SVaclav Hapla PetscBool distributed; 867703da9461SVaclav Hapla PetscErrorCode ierr; 867803da9461SVaclav Hapla 867903da9461SVaclav Hapla PetscFunctionBegin; 868003da9461SVaclav Hapla PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8681f0cfc026SVaclav Hapla ierr = DMGetPointSF(dm, &pointSF);CHKERRQ(ierr); 8682f0cfc026SVaclav Hapla ierr = DMPlexIsDistributed(dm, &distributed);CHKERRQ(ierr); 8683f0cfc026SVaclav Hapla if (!distributed) PetscFunctionReturn(0); 8684f0cfc026SVaclav Hapla ierr = DMPlexGetOverlap(dm, &overlap);CHKERRQ(ierr); 8685f0cfc026SVaclav Hapla if (overlap) { 86861e1ea65dSPierre Jolivet ierr = PetscPrintf(PetscObjectComm((PetscObject)dm), "Warning: DMPlexCheckPointSF() is currently not implemented for meshes with partition overlapping");CHKERRQ(ierr); 86878918e3e2SVaclav Hapla PetscFunctionReturn(0); 86888918e3e2SVaclav Hapla } 86892c71b3e2SJacob Faibussowitsch PetscCheckFalse(!pointSF,PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "This DMPlex is distributed but does not have PointSF attached"); 8690f0cfc026SVaclav Hapla ierr = PetscSFGetGraph(pointSF, &nroots, &nleaves, &locals, NULL);CHKERRQ(ierr); 86912c71b3e2SJacob Faibussowitsch PetscCheckFalse(nroots < 0,PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "This DMPlex is distributed but its PointSF has no graph set"); 8692f5869d18SMatthew G. Knepley ierr = PetscSFComputeDegreeBegin(pointSF, &rootdegree);CHKERRQ(ierr); 8693f5869d18SMatthew G. Knepley ierr = PetscSFComputeDegreeEnd(pointSF, &rootdegree);CHKERRQ(ierr); 869403da9461SVaclav Hapla 8695ece87651SVaclav Hapla /* 1) check there are no faces in 2D, cells in 3D, in interface */ 8696f5869d18SMatthew G. Knepley ierr = DMPlexGetVTKCellHeight(dm, &cellHeight);CHKERRQ(ierr); 8697f5869d18SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, cellHeight, &cStart, &cEnd);CHKERRQ(ierr); 8698f5869d18SMatthew G. Knepley for (l = 0; l < nleaves; ++l) { 8699f5869d18SMatthew G. Knepley const PetscInt point = locals[l]; 8700f5869d18SMatthew G. Knepley 87012c71b3e2SJacob Faibussowitsch PetscCheckFalse(point >= cStart && point < cEnd,PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point SF contains %D which is a cell", point); 870203da9461SVaclav Hapla } 8703ece87651SVaclav Hapla 8704f5869d18SMatthew G. Knepley /* 2) if some point is in interface, then all its cone points must be also in interface (either as leaves or roots) */ 8705f5869d18SMatthew G. Knepley for (l = 0; l < nleaves; ++l) { 8706f5869d18SMatthew G. Knepley const PetscInt point = locals[l]; 8707f5869d18SMatthew G. Knepley const PetscInt *cone; 8708f5869d18SMatthew G. Knepley PetscInt coneSize, c, idx; 8709f5869d18SMatthew G. Knepley 8710f5869d18SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, point, &coneSize);CHKERRQ(ierr); 8711f5869d18SMatthew G. Knepley ierr = DMPlexGetCone(dm, point, &cone);CHKERRQ(ierr); 8712f5869d18SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 8713f5869d18SMatthew G. Knepley if (!rootdegree[cone[c]]) { 8714f5869d18SMatthew G. Knepley ierr = PetscFindInt(cone[c], nleaves, locals, &idx);CHKERRQ(ierr); 87152c71b3e2SJacob Faibussowitsch PetscCheckFalse(idx < 0,PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point SF contains %D but not %D from its cone", point, cone[c]); 8716f5869d18SMatthew G. Knepley } 8717f5869d18SMatthew G. Knepley } 8718ece87651SVaclav Hapla } 871903da9461SVaclav Hapla PetscFunctionReturn(0); 872003da9461SVaclav Hapla } 872103da9461SVaclav Hapla 8722b5a892a1SMatthew G. Knepley PetscErrorCode DMPlexCheckAll_Internal(DM dm, PetscInt cellHeight) 8723b5a892a1SMatthew G. Knepley { 8724b5a892a1SMatthew G. Knepley PetscErrorCode ierr; 8725b5a892a1SMatthew G. Knepley 8726b5a892a1SMatthew G. Knepley PetscFunctionBegin; 8727b5a892a1SMatthew G. Knepley ierr = DMPlexCheckSymmetry(dm);CHKERRQ(ierr); 8728b5a892a1SMatthew G. Knepley ierr = DMPlexCheckSkeleton(dm, cellHeight);CHKERRQ(ierr); 8729b5a892a1SMatthew G. Knepley ierr = DMPlexCheckFaces(dm, cellHeight);CHKERRQ(ierr); 8730b5a892a1SMatthew G. Knepley ierr = DMPlexCheckGeometry(dm);CHKERRQ(ierr); 8731b5a892a1SMatthew G. Knepley ierr = DMPlexCheckPointSF(dm);CHKERRQ(ierr); 8732b5a892a1SMatthew G. Knepley ierr = DMPlexCheckInterfaceCones(dm);CHKERRQ(ierr); 8733b5a892a1SMatthew G. Knepley PetscFunctionReturn(0); 8734b5a892a1SMatthew G. Knepley } 8735b5a892a1SMatthew G. Knepley 8736068a5610SStefano Zampini typedef struct cell_stats 8737068a5610SStefano Zampini { 8738068a5610SStefano Zampini PetscReal min, max, sum, squaresum; 8739068a5610SStefano Zampini PetscInt count; 8740068a5610SStefano Zampini } cell_stats_t; 8741068a5610SStefano Zampini 874225befc3bSSatish Balay static void MPIAPI cell_stats_reduce(void *a, void *b, int * len, MPI_Datatype *datatype) 8743068a5610SStefano Zampini { 8744068a5610SStefano Zampini PetscInt i, N = *len; 8745068a5610SStefano Zampini 8746068a5610SStefano Zampini for (i = 0; i < N; i++) { 8747068a5610SStefano Zampini cell_stats_t *A = (cell_stats_t *) a; 8748068a5610SStefano Zampini cell_stats_t *B = (cell_stats_t *) b; 8749068a5610SStefano Zampini 8750068a5610SStefano Zampini B->min = PetscMin(A->min,B->min); 8751068a5610SStefano Zampini B->max = PetscMax(A->max,B->max); 8752068a5610SStefano Zampini B->sum += A->sum; 8753068a5610SStefano Zampini B->squaresum += A->squaresum; 8754068a5610SStefano Zampini B->count += A->count; 8755068a5610SStefano Zampini } 8756068a5610SStefano Zampini } 8757068a5610SStefano Zampini 8758068a5610SStefano Zampini /*@ 875943fa8764SMatthew G. Knepley DMPlexCheckCellShape - Checks the Jacobian of the mapping from reference to real cells and computes some minimal statistics. 8760068a5610SStefano Zampini 87618261a58bSMatthew G. Knepley Collective on dm 87628261a58bSMatthew G. Knepley 8763068a5610SStefano Zampini Input Parameters: 8764068a5610SStefano Zampini + dm - The DMPlex object 876543fa8764SMatthew G. Knepley . output - If true, statistics will be displayed on stdout 876643fa8764SMatthew G. Knepley - condLimit - Display all cells above this condition number, or PETSC_DETERMINE for no cell output 8767068a5610SStefano Zampini 876895eb5ee5SVaclav Hapla Notes: 876995eb5ee5SVaclav Hapla This is mainly intended for debugging/testing purposes. 877095eb5ee5SVaclav Hapla 877195eb5ee5SVaclav Hapla For the complete list of DMPlexCheck* functions, see DMSetFromOptions(). 8772068a5610SStefano Zampini 8773068a5610SStefano Zampini Level: developer 8774068a5610SStefano Zampini 8775f108dbd7SJacob Faibussowitsch .seealso: DMSetFromOptions(), DMPlexComputeOrthogonalQuality() 8776068a5610SStefano Zampini @*/ 877743fa8764SMatthew G. Knepley PetscErrorCode DMPlexCheckCellShape(DM dm, PetscBool output, PetscReal condLimit) 8778068a5610SStefano Zampini { 8779068a5610SStefano Zampini DM dmCoarse; 878043fa8764SMatthew G. Knepley cell_stats_t stats, globalStats; 878143fa8764SMatthew G. Knepley MPI_Comm comm = PetscObjectComm((PetscObject)dm); 878243fa8764SMatthew G. Knepley PetscReal *J, *invJ, min = 0, max = 0, mean = 0, stdev = 0; 878343fa8764SMatthew G. Knepley PetscReal limit = condLimit > 0 ? condLimit : PETSC_MAX_REAL; 8784412e9a14SMatthew G. Knepley PetscInt cdim, cStart, cEnd, c, eStart, eEnd, count = 0; 878543fa8764SMatthew G. Knepley PetscMPIInt rank,size; 8786068a5610SStefano Zampini PetscErrorCode ierr; 8787068a5610SStefano Zampini 8788068a5610SStefano Zampini PetscFunctionBegin; 8789068a5610SStefano Zampini PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8790068a5610SStefano Zampini stats.min = PETSC_MAX_REAL; 8791068a5610SStefano Zampini stats.max = PETSC_MIN_REAL; 8792068a5610SStefano Zampini stats.sum = stats.squaresum = 0.; 8793068a5610SStefano Zampini stats.count = 0; 8794068a5610SStefano Zampini 8795ffc4695bSBarry Smith ierr = MPI_Comm_size(comm, &size);CHKERRMPI(ierr); 8796ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 879743fa8764SMatthew G. Knepley ierr = DMGetCoordinateDim(dm,&cdim);CHKERRQ(ierr); 879843fa8764SMatthew G. Knepley ierr = PetscMalloc2(PetscSqr(cdim), &J, PetscSqr(cdim), &invJ);CHKERRQ(ierr); 8799412e9a14SMatthew G. Knepley ierr = DMPlexGetSimplexOrBoxCells(dm,0,&cStart,&cEnd);CHKERRQ(ierr); 880043fa8764SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm,1,&eStart,&eEnd);CHKERRQ(ierr); 8801412e9a14SMatthew G. Knepley for (c = cStart; c < cEnd; c++) { 8802068a5610SStefano Zampini PetscInt i; 8803068a5610SStefano Zampini PetscReal frobJ = 0., frobInvJ = 0., cond2, cond, detJ; 8804068a5610SStefano Zampini 8805068a5610SStefano Zampini ierr = DMPlexComputeCellGeometryAffineFEM(dm,c,NULL,J,invJ,&detJ);CHKERRQ(ierr); 88062c71b3e2SJacob Faibussowitsch PetscCheckFalse(detJ < 0.0,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Mesh cell %D is inverted", c); 880743fa8764SMatthew G. Knepley for (i = 0; i < PetscSqr(cdim); ++i) { 8808068a5610SStefano Zampini frobJ += J[i] * J[i]; 8809068a5610SStefano Zampini frobInvJ += invJ[i] * invJ[i]; 8810068a5610SStefano Zampini } 8811068a5610SStefano Zampini cond2 = frobJ * frobInvJ; 8812068a5610SStefano Zampini cond = PetscSqrtReal(cond2); 8813068a5610SStefano Zampini 8814068a5610SStefano Zampini stats.min = PetscMin(stats.min,cond); 8815068a5610SStefano Zampini stats.max = PetscMax(stats.max,cond); 8816068a5610SStefano Zampini stats.sum += cond; 8817068a5610SStefano Zampini stats.squaresum += cond2; 8818068a5610SStefano Zampini stats.count++; 88198261a58bSMatthew G. Knepley if (output && cond > limit) { 882043fa8764SMatthew G. Knepley PetscSection coordSection; 882143fa8764SMatthew G. Knepley Vec coordsLocal; 882243fa8764SMatthew G. Knepley PetscScalar *coords = NULL; 882343fa8764SMatthew G. Knepley PetscInt Nv, d, clSize, cl, *closure = NULL; 882443fa8764SMatthew G. Knepley 882543fa8764SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordsLocal);CHKERRQ(ierr); 882643fa8764SMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 882743fa8764SMatthew G. Knepley ierr = DMPlexVecGetClosure(dm, coordSection, coordsLocal, c, &Nv, &coords);CHKERRQ(ierr); 8828087ef6b2SMatthew G. Knepley ierr = PetscSynchronizedPrintf(comm, "[%d] Cell %D cond %g\n", rank, c, (double) cond);CHKERRQ(ierr); 882943fa8764SMatthew G. Knepley for (i = 0; i < Nv/cdim; ++i) { 883043fa8764SMatthew G. Knepley ierr = PetscSynchronizedPrintf(comm, " Vertex %D: (", i);CHKERRQ(ierr); 883143fa8764SMatthew G. Knepley for (d = 0; d < cdim; ++d) { 883243fa8764SMatthew G. Knepley if (d > 0) {ierr = PetscSynchronizedPrintf(comm, ", ");CHKERRQ(ierr);} 883348afe810SSatish Balay ierr = PetscSynchronizedPrintf(comm, "%g", (double) PetscRealPart(coords[i*cdim+d]));CHKERRQ(ierr); 883443fa8764SMatthew G. Knepley } 883543fa8764SMatthew G. Knepley ierr = PetscSynchronizedPrintf(comm, ")\n");CHKERRQ(ierr); 883643fa8764SMatthew G. Knepley } 883743fa8764SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &clSize, &closure);CHKERRQ(ierr); 883843fa8764SMatthew G. Knepley for (cl = 0; cl < clSize*2; cl += 2) { 883943fa8764SMatthew G. Knepley const PetscInt edge = closure[cl]; 884043fa8764SMatthew G. Knepley 884143fa8764SMatthew G. Knepley if ((edge >= eStart) && (edge < eEnd)) { 884243fa8764SMatthew G. Knepley PetscReal len; 884343fa8764SMatthew G. Knepley 884443fa8764SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFVM(dm, edge, &len, NULL, NULL);CHKERRQ(ierr); 8845087ef6b2SMatthew G. Knepley ierr = PetscSynchronizedPrintf(comm, " Edge %D: length %g\n", edge, (double) len);CHKERRQ(ierr); 884643fa8764SMatthew G. Knepley } 884743fa8764SMatthew G. Knepley } 884843fa8764SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &clSize, &closure);CHKERRQ(ierr); 884943fa8764SMatthew G. Knepley ierr = DMPlexVecRestoreClosure(dm, coordSection, coordsLocal, c, &Nv, &coords);CHKERRQ(ierr); 885043fa8764SMatthew G. Knepley } 8851068a5610SStefano Zampini } 88528261a58bSMatthew G. Knepley if (output) {ierr = PetscSynchronizedFlush(comm, NULL);CHKERRQ(ierr);} 8853068a5610SStefano Zampini 8854068a5610SStefano Zampini if (size > 1) { 8855068a5610SStefano Zampini PetscMPIInt blockLengths[2] = {4,1}; 8856068a5610SStefano Zampini MPI_Aint blockOffsets[2] = {offsetof(cell_stats_t,min),offsetof(cell_stats_t,count)}; 8857068a5610SStefano Zampini MPI_Datatype blockTypes[2] = {MPIU_REAL,MPIU_INT}, statType; 8858068a5610SStefano Zampini MPI_Op statReduce; 8859068a5610SStefano Zampini 8860ffc4695bSBarry Smith ierr = MPI_Type_create_struct(2,blockLengths,blockOffsets,blockTypes,&statType);CHKERRMPI(ierr); 8861ffc4695bSBarry Smith ierr = MPI_Type_commit(&statType);CHKERRMPI(ierr); 8862ffc4695bSBarry Smith ierr = MPI_Op_create(cell_stats_reduce, PETSC_TRUE, &statReduce);CHKERRMPI(ierr); 8863ffc4695bSBarry Smith ierr = MPI_Reduce(&stats,&globalStats,1,statType,statReduce,0,comm);CHKERRMPI(ierr); 8864ffc4695bSBarry Smith ierr = MPI_Op_free(&statReduce);CHKERRMPI(ierr); 8865ffc4695bSBarry Smith ierr = MPI_Type_free(&statType);CHKERRMPI(ierr); 8866068a5610SStefano Zampini } else { 8867580bdb30SBarry Smith ierr = PetscArraycpy(&globalStats,&stats,1);CHKERRQ(ierr); 8868068a5610SStefano Zampini } 8869dd400576SPatrick Sanan if (rank == 0) { 8870068a5610SStefano Zampini count = globalStats.count; 8871068a5610SStefano Zampini min = globalStats.min; 8872068a5610SStefano Zampini max = globalStats.max; 8873068a5610SStefano Zampini mean = globalStats.sum / globalStats.count; 8874068a5610SStefano Zampini stdev = globalStats.count > 1 ? PetscSqrtReal(PetscMax((globalStats.squaresum - globalStats.count * mean * mean) / (globalStats.count - 1),0)) : 0.0; 8875068a5610SStefano Zampini } 8876068a5610SStefano Zampini 8877068a5610SStefano Zampini if (output) { 8878068a5610SStefano 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); 8879068a5610SStefano Zampini } 8880068a5610SStefano Zampini ierr = PetscFree2(J,invJ);CHKERRQ(ierr); 8881068a5610SStefano Zampini 8882068a5610SStefano Zampini ierr = DMGetCoarseDM(dm,&dmCoarse);CHKERRQ(ierr); 8883068a5610SStefano Zampini if (dmCoarse) { 8884068a5610SStefano Zampini PetscBool isplex; 8885068a5610SStefano Zampini 8886068a5610SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)dmCoarse,DMPLEX,&isplex);CHKERRQ(ierr); 8887068a5610SStefano Zampini if (isplex) { 888843fa8764SMatthew G. Knepley ierr = DMPlexCheckCellShape(dmCoarse,output,condLimit);CHKERRQ(ierr); 8889068a5610SStefano Zampini } 8890068a5610SStefano Zampini } 8891068a5610SStefano Zampini PetscFunctionReturn(0); 8892068a5610SStefano Zampini } 8893068a5610SStefano Zampini 8894f108dbd7SJacob Faibussowitsch /*@ 8895f108dbd7SJacob Faibussowitsch DMPlexComputeOrthogonalQuality - Compute cell-wise orthogonal quality mesh statistic. Optionally tags all cells with 8896f108dbd7SJacob Faibussowitsch orthogonal quality below given tolerance. 8897f108dbd7SJacob Faibussowitsch 88986ed19f2fSJacob Faibussowitsch Collective on dm 8899f108dbd7SJacob Faibussowitsch 8900f108dbd7SJacob Faibussowitsch Input Parameters: 8901f108dbd7SJacob Faibussowitsch + dm - The DMPlex object 8902f108dbd7SJacob Faibussowitsch . fv - Optional PetscFV object for pre-computed cell/face centroid information 8903f108dbd7SJacob Faibussowitsch - atol - [0, 1] Absolute tolerance for tagging cells. 8904f108dbd7SJacob Faibussowitsch 8905f108dbd7SJacob Faibussowitsch Output Parameters: 8906f108dbd7SJacob Faibussowitsch + OrthQual - Vec containing orthogonal quality per cell 8907f108dbd7SJacob Faibussowitsch - OrthQualLabel - DMLabel tagging cells below atol with DM_ADAPT_REFINE 8908f108dbd7SJacob Faibussowitsch 8909f108dbd7SJacob Faibussowitsch Options Database Keys: 8910f108dbd7SJacob Faibussowitsch + -dm_plex_orthogonal_quality_label_view - view OrthQualLabel if label is requested. Currently only PETSCVIEWERASCII is 8911f108dbd7SJacob Faibussowitsch supported. 8912f108dbd7SJacob Faibussowitsch - -dm_plex_orthogonal_quality_vec_view - view OrthQual vector. 8913f108dbd7SJacob Faibussowitsch 8914f108dbd7SJacob Faibussowitsch Notes: 8915f108dbd7SJacob Faibussowitsch Orthogonal quality is given by the following formula: 8916f108dbd7SJacob Faibussowitsch 8917f108dbd7SJacob Faibussowitsch \min \left[ \frac{A_i \cdot f_i}{\|A_i\| \|f_i\|} , \frac{A_i \cdot c_i}{\|A_i\| \|c_i\|} \right] 8918f108dbd7SJacob Faibussowitsch 8919f108dbd7SJacob Faibussowitsch Where A_i is the i'th face-normal vector, f_i is the vector from the cell centroid to the i'th face centroid, and c_i 8920f108dbd7SJacob Faibussowitsch is the vector from the current cells centroid to the centroid of its i'th neighbor (which shares a face with the 8921f108dbd7SJacob Faibussowitsch current cell). This computes the vector similarity between each cell face and its corresponding neighbor centroid by 8922f108dbd7SJacob Faibussowitsch calculating the cosine of the angle between these vectors. 8923f108dbd7SJacob Faibussowitsch 8924f108dbd7SJacob Faibussowitsch Orthogonal quality ranges from 1 (best) to 0 (worst). 8925f108dbd7SJacob Faibussowitsch 8926f108dbd7SJacob Faibussowitsch This routine is mainly useful for FVM, however is not restricted to only FVM. The PetscFV object is optionally used to check for 8927f108dbd7SJacob Faibussowitsch pre-computed FVM cell data, but if it is not passed in then this data will be computed. 8928f108dbd7SJacob Faibussowitsch 8929f108dbd7SJacob Faibussowitsch Cells are tagged if they have an orthogonal quality less than or equal to the absolute tolerance. 8930f108dbd7SJacob Faibussowitsch 8931f108dbd7SJacob Faibussowitsch Level: intermediate 8932f108dbd7SJacob Faibussowitsch 8933f108dbd7SJacob Faibussowitsch .seealso: DMPlexCheckCellShape(), DMCreateLabel() 8934f108dbd7SJacob Faibussowitsch @*/ 8935f108dbd7SJacob Faibussowitsch PetscErrorCode DMPlexComputeOrthogonalQuality(DM dm, PetscFV fv, PetscReal atol, Vec *OrthQual, DMLabel *OrthQualLabel) 8936f108dbd7SJacob Faibussowitsch { 89376ed19f2fSJacob Faibussowitsch PetscInt nc, cellHeight, cStart, cEnd, cell, cellIter = 0; 89386ed19f2fSJacob Faibussowitsch PetscInt *idx; 89396ed19f2fSJacob Faibussowitsch PetscScalar *oqVals; 8940f108dbd7SJacob Faibussowitsch const PetscScalar *cellGeomArr, *faceGeomArr; 89416ed19f2fSJacob Faibussowitsch PetscReal *ci, *fi, *Ai; 8942f108dbd7SJacob Faibussowitsch MPI_Comm comm; 8943f108dbd7SJacob Faibussowitsch Vec cellgeom, facegeom; 8944f108dbd7SJacob Faibussowitsch DM dmFace, dmCell; 8945f108dbd7SJacob Faibussowitsch IS glob; 8946f108dbd7SJacob Faibussowitsch ISLocalToGlobalMapping ltog; 8947f108dbd7SJacob Faibussowitsch PetscViewer vwr; 8948f108dbd7SJacob Faibussowitsch PetscErrorCode ierr; 8949f108dbd7SJacob Faibussowitsch 8950f108dbd7SJacob Faibussowitsch PetscFunctionBegin; 8951f108dbd7SJacob Faibussowitsch PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 89526ed19f2fSJacob Faibussowitsch if (fv) {PetscValidHeaderSpecific(fv, PETSCFV_CLASSID, 2);} 8953f108dbd7SJacob Faibussowitsch PetscValidPointer(OrthQual, 4); 89546bdcaf15SBarry Smith PetscCheck(atol >= 0.0 && atol <= 1.0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %g not in [0,1]",(double)atol); 8955f108dbd7SJacob Faibussowitsch ierr = PetscObjectGetComm((PetscObject) dm, &comm);CHKERRQ(ierr); 8956f108dbd7SJacob Faibussowitsch ierr = DMGetDimension(dm, &nc);CHKERRQ(ierr); 89572c71b3e2SJacob Faibussowitsch PetscCheckFalse(nc < 2,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "DM must have dimension >= 2 (current %D)", nc); 89586ed19f2fSJacob Faibussowitsch { 89596ed19f2fSJacob Faibussowitsch DMPlexInterpolatedFlag interpFlag; 89606ed19f2fSJacob Faibussowitsch 8961f108dbd7SJacob Faibussowitsch ierr = DMPlexIsInterpolated(dm, &interpFlag);CHKERRQ(ierr); 8962f108dbd7SJacob Faibussowitsch if (interpFlag != DMPLEX_INTERPOLATED_FULL) { 8963f108dbd7SJacob Faibussowitsch PetscMPIInt rank; 8964f108dbd7SJacob Faibussowitsch 8965ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 896698921bdaSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "DM must be fully interpolated, DM on rank %d is not fully interpolated", rank); 8967f108dbd7SJacob Faibussowitsch } 89686ed19f2fSJacob Faibussowitsch } 8969f108dbd7SJacob Faibussowitsch if (OrthQualLabel) { 8970f108dbd7SJacob Faibussowitsch PetscValidPointer(OrthQualLabel, 5); 8971f108dbd7SJacob Faibussowitsch ierr = DMCreateLabel(dm, "Orthogonal_Quality");CHKERRQ(ierr); 8972f108dbd7SJacob Faibussowitsch ierr = DMGetLabel(dm, "Orthogonal_Quality", OrthQualLabel);CHKERRQ(ierr); 89736ed19f2fSJacob Faibussowitsch } else {*OrthQualLabel = NULL;} 8974f108dbd7SJacob Faibussowitsch ierr = DMPlexGetVTKCellHeight(dm, &cellHeight);CHKERRQ(ierr); 8975f108dbd7SJacob Faibussowitsch ierr = DMPlexGetHeightStratum(dm, cellHeight, &cStart, &cEnd);CHKERRQ(ierr); 8976f108dbd7SJacob Faibussowitsch ierr = DMPlexCreateCellNumbering_Internal(dm, PETSC_TRUE, &glob);CHKERRQ(ierr); 8977f108dbd7SJacob Faibussowitsch ierr = ISLocalToGlobalMappingCreateIS(glob, <og);CHKERRQ(ierr); 8978f108dbd7SJacob Faibussowitsch ierr = ISLocalToGlobalMappingSetType(ltog, ISLOCALTOGLOBALMAPPINGHASH);CHKERRQ(ierr); 8979f108dbd7SJacob Faibussowitsch ierr = VecCreate(comm, OrthQual);CHKERRQ(ierr); 8980f108dbd7SJacob Faibussowitsch ierr = VecSetType(*OrthQual, VECSTANDARD);CHKERRQ(ierr); 8981f108dbd7SJacob Faibussowitsch ierr = VecSetSizes(*OrthQual, cEnd-cStart, PETSC_DETERMINE);CHKERRQ(ierr); 8982f108dbd7SJacob Faibussowitsch ierr = VecSetLocalToGlobalMapping(*OrthQual, ltog);CHKERRQ(ierr); 8983f108dbd7SJacob Faibussowitsch ierr = VecSetUp(*OrthQual);CHKERRQ(ierr); 8984f108dbd7SJacob Faibussowitsch ierr = ISDestroy(&glob);CHKERRQ(ierr); 8985f108dbd7SJacob Faibussowitsch ierr = ISLocalToGlobalMappingDestroy(<og);CHKERRQ(ierr); 8986f108dbd7SJacob Faibussowitsch ierr = DMPlexGetDataFVM(dm, fv, &cellgeom, &facegeom, NULL);CHKERRQ(ierr); 8987f108dbd7SJacob Faibussowitsch ierr = VecGetArrayRead(cellgeom, &cellGeomArr);CHKERRQ(ierr); 8988f108dbd7SJacob Faibussowitsch ierr = VecGetArrayRead(facegeom, &faceGeomArr);CHKERRQ(ierr); 8989f108dbd7SJacob Faibussowitsch ierr = VecGetDM(cellgeom, &dmCell);CHKERRQ(ierr); 8990f108dbd7SJacob Faibussowitsch ierr = VecGetDM(facegeom, &dmFace);CHKERRQ(ierr); 89916ed19f2fSJacob Faibussowitsch ierr = PetscMalloc5(cEnd-cStart, &idx, cEnd-cStart, &oqVals, nc, &ci, nc, &fi, nc, &Ai);CHKERRQ(ierr); 89926ed19f2fSJacob Faibussowitsch for (cell = cStart; cell < cEnd; cellIter++,cell++) { 89936ed19f2fSJacob Faibussowitsch PetscInt cellneigh, cellneighiter = 0, adjSize = PETSC_DETERMINE; 8994f108dbd7SJacob Faibussowitsch PetscInt cellarr[2], *adj = NULL; 8995f108dbd7SJacob Faibussowitsch PetscScalar *cArr, *fArr; 8996898cd552SSatish Balay PetscReal minvalc = 1.0, minvalf = 1.0; 8997f108dbd7SJacob Faibussowitsch PetscFVCellGeom *cg; 8998f108dbd7SJacob Faibussowitsch 89996ed19f2fSJacob Faibussowitsch idx[cellIter] = cell-cStart; 9000f108dbd7SJacob Faibussowitsch cellarr[0] = cell; 9001f108dbd7SJacob Faibussowitsch /* Make indexing into cellGeom easier */ 9002f108dbd7SJacob Faibussowitsch ierr = DMPlexPointLocalRead(dmCell, cell, cellGeomArr, &cg);CHKERRQ(ierr); 9003f108dbd7SJacob Faibussowitsch ierr = DMPlexGetAdjacency_Internal(dm, cell, PETSC_TRUE, PETSC_FALSE, PETSC_FALSE, &adjSize, &adj);CHKERRQ(ierr); 9004f108dbd7SJacob Faibussowitsch /* Technically 1 too big, but easier than fiddling with empty adjacency array */ 9005f108dbd7SJacob Faibussowitsch ierr = PetscCalloc2(adjSize, &cArr, adjSize, &fArr);CHKERRQ(ierr); 90066ed19f2fSJacob Faibussowitsch for (cellneigh = 0; cellneigh < adjSize; cellneighiter++,cellneigh++) { 90076ed19f2fSJacob Faibussowitsch PetscInt i; 90086ed19f2fSJacob Faibussowitsch const PetscInt neigh = adj[cellneigh]; 9009f108dbd7SJacob Faibussowitsch PetscReal normci = 0, normfi = 0, normai = 0; 9010f108dbd7SJacob Faibussowitsch PetscFVCellGeom *cgneigh; 9011f108dbd7SJacob Faibussowitsch PetscFVFaceGeom *fg; 9012f108dbd7SJacob Faibussowitsch 9013f108dbd7SJacob Faibussowitsch /* Don't count ourselves in the neighbor list */ 9014f108dbd7SJacob Faibussowitsch if (neigh == cell) continue; 9015f108dbd7SJacob Faibussowitsch ierr = DMPlexPointLocalRead(dmCell, neigh, cellGeomArr, &cgneigh);CHKERRQ(ierr); 9016f108dbd7SJacob Faibussowitsch cellarr[1] = neigh; 90176ed19f2fSJacob Faibussowitsch { 90186ed19f2fSJacob Faibussowitsch PetscInt numcovpts; 90196ed19f2fSJacob Faibussowitsch const PetscInt *covpts; 90206ed19f2fSJacob Faibussowitsch 9021f108dbd7SJacob Faibussowitsch ierr = DMPlexGetMeet(dm, 2, cellarr, &numcovpts, &covpts);CHKERRQ(ierr); 9022f108dbd7SJacob Faibussowitsch ierr = DMPlexPointLocalRead(dmFace, covpts[0], faceGeomArr, &fg);CHKERRQ(ierr); 9023f108dbd7SJacob Faibussowitsch ierr = DMPlexRestoreMeet(dm, 2, cellarr, &numcovpts, &covpts);CHKERRQ(ierr); 90246ed19f2fSJacob Faibussowitsch } 9025f108dbd7SJacob Faibussowitsch 9026f108dbd7SJacob Faibussowitsch /* Compute c_i, f_i and their norms */ 9027f108dbd7SJacob Faibussowitsch for (i = 0; i < nc; i++) { 9028f108dbd7SJacob Faibussowitsch ci[i] = cgneigh->centroid[i] - cg->centroid[i]; 9029f108dbd7SJacob Faibussowitsch fi[i] = fg->centroid[i] - cg->centroid[i]; 9030f108dbd7SJacob Faibussowitsch Ai[i] = fg->normal[i]; 9031addd1e01SJunchao Zhang normci += PetscPowReal(ci[i], 2); 9032addd1e01SJunchao Zhang normfi += PetscPowReal(fi[i], 2); 9033addd1e01SJunchao Zhang normai += PetscPowReal(Ai[i], 2); 9034f108dbd7SJacob Faibussowitsch } 9035addd1e01SJunchao Zhang normci = PetscSqrtReal(normci); 9036addd1e01SJunchao Zhang normfi = PetscSqrtReal(normfi); 9037addd1e01SJunchao Zhang normai = PetscSqrtReal(normai); 9038f108dbd7SJacob Faibussowitsch 9039f108dbd7SJacob Faibussowitsch /* Normalize and compute for each face-cell-normal pair */ 9040f108dbd7SJacob Faibussowitsch for (i = 0; i < nc; i++) { 9041f108dbd7SJacob Faibussowitsch ci[i] = ci[i]/normci; 9042f108dbd7SJacob Faibussowitsch fi[i] = fi[i]/normfi; 9043f108dbd7SJacob Faibussowitsch Ai[i] = Ai[i]/normai; 9044f108dbd7SJacob Faibussowitsch /* PetscAbs because I don't know if normals are guaranteed to point out */ 9045f108dbd7SJacob Faibussowitsch cArr[cellneighiter] += PetscAbs(Ai[i]*ci[i]); 9046f108dbd7SJacob Faibussowitsch fArr[cellneighiter] += PetscAbs(Ai[i]*fi[i]); 9047f108dbd7SJacob Faibussowitsch } 9048f108dbd7SJacob Faibussowitsch if (PetscRealPart(cArr[cellneighiter]) < minvalc) { 9049f108dbd7SJacob Faibussowitsch minvalc = PetscRealPart(cArr[cellneighiter]); 9050f108dbd7SJacob Faibussowitsch } 9051f108dbd7SJacob Faibussowitsch if (PetscRealPart(fArr[cellneighiter]) < minvalf) { 9052f108dbd7SJacob Faibussowitsch minvalf = PetscRealPart(fArr[cellneighiter]); 9053f108dbd7SJacob Faibussowitsch } 9054f108dbd7SJacob Faibussowitsch } 9055f108dbd7SJacob Faibussowitsch ierr = PetscFree(adj);CHKERRQ(ierr); 9056f108dbd7SJacob Faibussowitsch ierr = PetscFree2(cArr, fArr);CHKERRQ(ierr); 9057f108dbd7SJacob Faibussowitsch /* Defer to cell if they're equal */ 90586ed19f2fSJacob Faibussowitsch oqVals[cellIter] = PetscMin(minvalf, minvalc); 9059f108dbd7SJacob Faibussowitsch if (OrthQualLabel) { 90606ed19f2fSJacob Faibussowitsch if (PetscRealPart(oqVals[cellIter]) <= atol) {ierr = DMLabelSetValue(*OrthQualLabel, cell, DM_ADAPT_REFINE);CHKERRQ(ierr);} 9061f108dbd7SJacob Faibussowitsch } 9062f108dbd7SJacob Faibussowitsch } 90636ed19f2fSJacob Faibussowitsch ierr = VecSetValuesLocal(*OrthQual, cEnd-cStart, idx, oqVals, INSERT_VALUES);CHKERRQ(ierr); 9064f108dbd7SJacob Faibussowitsch ierr = VecAssemblyBegin(*OrthQual);CHKERRQ(ierr); 9065f108dbd7SJacob Faibussowitsch ierr = VecAssemblyEnd(*OrthQual);CHKERRQ(ierr); 9066f108dbd7SJacob Faibussowitsch ierr = VecRestoreArrayRead(cellgeom, &cellGeomArr);CHKERRQ(ierr); 9067f108dbd7SJacob Faibussowitsch ierr = VecRestoreArrayRead(facegeom, &faceGeomArr);CHKERRQ(ierr); 9068f108dbd7SJacob Faibussowitsch ierr = PetscOptionsGetViewer(comm, NULL, NULL, "-dm_plex_orthogonal_quality_label_view", &vwr, NULL, NULL);CHKERRQ(ierr); 9069f108dbd7SJacob Faibussowitsch if (OrthQualLabel) { 90706ed19f2fSJacob Faibussowitsch if (vwr) {ierr = DMLabelView(*OrthQualLabel, vwr);CHKERRQ(ierr);} 9071f108dbd7SJacob Faibussowitsch } 90726ed19f2fSJacob Faibussowitsch ierr = PetscFree5(idx, oqVals, ci, fi, Ai);CHKERRQ(ierr); 9073f108dbd7SJacob Faibussowitsch ierr = PetscViewerDestroy(&vwr);CHKERRQ(ierr); 9074f108dbd7SJacob Faibussowitsch ierr = VecViewFromOptions(*OrthQual, NULL, "-dm_plex_orthogonal_quality_vec_view");CHKERRQ(ierr); 9075f108dbd7SJacob Faibussowitsch PetscFunctionReturn(0); 9076f108dbd7SJacob Faibussowitsch } 9077f108dbd7SJacob Faibussowitsch 90781eb70e55SToby Isaac /* this is here insead of DMGetOutputDM because output DM still has constraints in the local indices that affect 90791eb70e55SToby Isaac * interpolator construction */ 90801eb70e55SToby Isaac static PetscErrorCode DMGetFullDM(DM dm, DM *odm) 90811eb70e55SToby Isaac { 90821eb70e55SToby Isaac PetscSection section, newSection, gsection; 90831eb70e55SToby Isaac PetscSF sf; 90841eb70e55SToby Isaac PetscBool hasConstraints, ghasConstraints; 90851eb70e55SToby Isaac PetscErrorCode ierr; 90861eb70e55SToby Isaac 90871eb70e55SToby Isaac PetscFunctionBegin; 90881eb70e55SToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 90891eb70e55SToby Isaac PetscValidPointer(odm,2); 90901eb70e55SToby Isaac ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr); 90911eb70e55SToby Isaac ierr = PetscSectionHasConstraints(section, &hasConstraints);CHKERRQ(ierr); 90921eb70e55SToby Isaac ierr = MPI_Allreduce(&hasConstraints, &ghasConstraints, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject) dm));CHKERRMPI(ierr); 90931eb70e55SToby Isaac if (!ghasConstraints) { 90941eb70e55SToby Isaac ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 90951eb70e55SToby Isaac *odm = dm; 90961eb70e55SToby Isaac PetscFunctionReturn(0); 90971eb70e55SToby Isaac } 90981eb70e55SToby Isaac ierr = DMClone(dm, odm);CHKERRQ(ierr); 90991eb70e55SToby Isaac ierr = DMCopyFields(dm, *odm);CHKERRQ(ierr); 91001eb70e55SToby Isaac ierr = DMGetLocalSection(*odm, &newSection);CHKERRQ(ierr); 91011eb70e55SToby Isaac ierr = DMGetPointSF(*odm, &sf);CHKERRQ(ierr); 91021eb70e55SToby Isaac ierr = PetscSectionCreateGlobalSection(newSection, sf, PETSC_TRUE, PETSC_FALSE, &gsection);CHKERRQ(ierr); 91031eb70e55SToby Isaac ierr = DMSetGlobalSection(*odm, gsection);CHKERRQ(ierr); 91041eb70e55SToby Isaac ierr = PetscSectionDestroy(&gsection);CHKERRQ(ierr); 91051eb70e55SToby Isaac PetscFunctionReturn(0); 91061eb70e55SToby Isaac } 91071eb70e55SToby Isaac 91081eb70e55SToby Isaac static PetscErrorCode DMCreateAffineInterpolationCorrection_Plex(DM dmc, DM dmf, Vec *shift) 91091eb70e55SToby Isaac { 91101eb70e55SToby Isaac DM dmco, dmfo; 91111eb70e55SToby Isaac Mat interpo; 91121eb70e55SToby Isaac Vec rscale; 91131eb70e55SToby Isaac Vec cglobalo, clocal; 91141eb70e55SToby Isaac Vec fglobal, fglobalo, flocal; 91151eb70e55SToby Isaac PetscBool regular; 91161eb70e55SToby Isaac PetscErrorCode ierr; 91171eb70e55SToby Isaac 91181eb70e55SToby Isaac PetscFunctionBegin; 91191eb70e55SToby Isaac ierr = DMGetFullDM(dmc, &dmco);CHKERRQ(ierr); 91201eb70e55SToby Isaac ierr = DMGetFullDM(dmf, &dmfo);CHKERRQ(ierr); 91211eb70e55SToby Isaac ierr = DMSetCoarseDM(dmfo, dmco);CHKERRQ(ierr); 91221eb70e55SToby Isaac ierr = DMPlexGetRegularRefinement(dmf, ®ular);CHKERRQ(ierr); 91231eb70e55SToby Isaac ierr = DMPlexSetRegularRefinement(dmfo, regular);CHKERRQ(ierr); 91241eb70e55SToby Isaac ierr = DMCreateInterpolation(dmco, dmfo, &interpo, &rscale);CHKERRQ(ierr); 91251eb70e55SToby Isaac ierr = DMCreateGlobalVector(dmco, &cglobalo);CHKERRQ(ierr); 91261eb70e55SToby Isaac ierr = DMCreateLocalVector(dmc, &clocal);CHKERRQ(ierr); 91271eb70e55SToby Isaac ierr = VecSet(cglobalo, 0.);CHKERRQ(ierr); 91281eb70e55SToby Isaac ierr = VecSet(clocal, 0.);CHKERRQ(ierr); 91291eb70e55SToby Isaac ierr = DMCreateGlobalVector(dmf, &fglobal);CHKERRQ(ierr); 91301eb70e55SToby Isaac ierr = DMCreateGlobalVector(dmfo, &fglobalo);CHKERRQ(ierr); 91311eb70e55SToby Isaac ierr = DMCreateLocalVector(dmf, &flocal);CHKERRQ(ierr); 91321eb70e55SToby Isaac ierr = VecSet(fglobal, 0.);CHKERRQ(ierr); 91331eb70e55SToby Isaac ierr = VecSet(fglobalo, 0.);CHKERRQ(ierr); 91341eb70e55SToby Isaac ierr = VecSet(flocal, 0.);CHKERRQ(ierr); 91351eb70e55SToby Isaac ierr = DMPlexInsertBoundaryValues(dmc, PETSC_TRUE, clocal, 0., NULL, NULL, NULL);CHKERRQ(ierr); 91361eb70e55SToby Isaac ierr = DMLocalToGlobalBegin(dmco, clocal, INSERT_VALUES, cglobalo);CHKERRQ(ierr); 91371eb70e55SToby Isaac ierr = DMLocalToGlobalEnd(dmco, clocal, INSERT_VALUES, cglobalo);CHKERRQ(ierr); 91381eb70e55SToby Isaac ierr = MatMult(interpo, cglobalo, fglobalo);CHKERRQ(ierr); 91391eb70e55SToby Isaac ierr = DMGlobalToLocalBegin(dmfo, fglobalo, INSERT_VALUES, flocal);CHKERRQ(ierr); 91401eb70e55SToby Isaac ierr = DMGlobalToLocalEnd(dmfo, fglobalo, INSERT_VALUES, flocal);CHKERRQ(ierr); 91411eb70e55SToby Isaac ierr = DMLocalToGlobalBegin(dmf, flocal, INSERT_VALUES, fglobal);CHKERRQ(ierr); 91421eb70e55SToby Isaac ierr = DMLocalToGlobalEnd(dmf, flocal, INSERT_VALUES, fglobal);CHKERRQ(ierr); 91431eb70e55SToby Isaac *shift = fglobal; 91441eb70e55SToby Isaac ierr = VecDestroy(&flocal);CHKERRQ(ierr); 91451eb70e55SToby Isaac ierr = VecDestroy(&fglobalo);CHKERRQ(ierr); 91461eb70e55SToby Isaac ierr = VecDestroy(&clocal);CHKERRQ(ierr); 91471eb70e55SToby Isaac ierr = VecDestroy(&cglobalo);CHKERRQ(ierr); 91481eb70e55SToby Isaac ierr = VecDestroy(&rscale);CHKERRQ(ierr); 91491eb70e55SToby Isaac ierr = MatDestroy(&interpo);CHKERRQ(ierr); 91501eb70e55SToby Isaac ierr = DMDestroy(&dmfo);CHKERRQ(ierr); 91511eb70e55SToby Isaac ierr = DMDestroy(&dmco);CHKERRQ(ierr); 91521eb70e55SToby Isaac PetscFunctionReturn(0); 91531eb70e55SToby Isaac } 91541eb70e55SToby Isaac 91551eb70e55SToby Isaac PETSC_INTERN PetscErrorCode DMInterpolateSolution_Plex(DM coarse, DM fine, Mat interp, Vec coarseSol, Vec fineSol) 91561eb70e55SToby Isaac { 91571eb70e55SToby Isaac PetscObject shifto; 91581eb70e55SToby Isaac Vec shift; 91591eb70e55SToby Isaac 91601eb70e55SToby Isaac PetscErrorCode ierr; 91611eb70e55SToby Isaac 91621eb70e55SToby Isaac PetscFunctionBegin; 91631eb70e55SToby Isaac if (!interp) { 91641eb70e55SToby Isaac Vec rscale; 91651eb70e55SToby Isaac 91661eb70e55SToby Isaac ierr = DMCreateInterpolation(coarse, fine, &interp, &rscale);CHKERRQ(ierr); 91671eb70e55SToby Isaac ierr = VecDestroy(&rscale);CHKERRQ(ierr); 91681eb70e55SToby Isaac } else { 91691eb70e55SToby Isaac ierr = PetscObjectReference((PetscObject)interp);CHKERRQ(ierr); 91701eb70e55SToby Isaac } 91711eb70e55SToby Isaac ierr = PetscObjectQuery((PetscObject)interp, "_DMInterpolateSolution_Plex_Vec", &shifto);CHKERRQ(ierr); 91721eb70e55SToby Isaac if (!shifto) { 91731eb70e55SToby Isaac ierr = DMCreateAffineInterpolationCorrection_Plex(coarse, fine, &shift);CHKERRQ(ierr); 91741eb70e55SToby Isaac ierr = PetscObjectCompose((PetscObject)interp, "_DMInterpolateSolution_Plex_Vec", (PetscObject) shift);CHKERRQ(ierr); 91751eb70e55SToby Isaac shifto = (PetscObject) shift; 91761eb70e55SToby Isaac ierr = VecDestroy(&shift);CHKERRQ(ierr); 91771eb70e55SToby Isaac } 91781eb70e55SToby Isaac shift = (Vec) shifto; 91791eb70e55SToby Isaac ierr = MatInterpolate(interp, coarseSol, fineSol);CHKERRQ(ierr); 91801eb70e55SToby Isaac ierr = VecAXPY(fineSol, 1.0, shift);CHKERRQ(ierr); 91811eb70e55SToby Isaac ierr = MatDestroy(&interp);CHKERRQ(ierr); 91821eb70e55SToby Isaac PetscFunctionReturn(0); 91831eb70e55SToby Isaac } 91841eb70e55SToby Isaac 9185bceba477SMatthew G. Knepley /* Pointwise interpolation 9186bceba477SMatthew G. Knepley Just code FEM for now 9187bceba477SMatthew G. Knepley u^f = I u^c 91884ca5e9f5SMatthew G. Knepley sum_k u^f_k phi^f_k = I sum_j u^c_j phi^c_j 91894ca5e9f5SMatthew G. Knepley u^f_i = sum_j psi^f_i I phi^c_j u^c_j 91904ca5e9f5SMatthew G. Knepley I_{ij} = psi^f_i phi^c_j 9191bceba477SMatthew G. Knepley */ 9192bceba477SMatthew G. Knepley PetscErrorCode DMCreateInterpolation_Plex(DM dmCoarse, DM dmFine, Mat *interpolation, Vec *scaling) 9193bceba477SMatthew G. Knepley { 9194bceba477SMatthew G. Knepley PetscSection gsc, gsf; 9195bceba477SMatthew G. Knepley PetscInt m, n; 9196a063dac3SMatthew G. Knepley void *ctx; 919768132eb9SMatthew G. Knepley DM cdm; 9198cf51de39SMatthew G. Knepley PetscBool regular, ismatis, isRefined = dmCoarse->data == dmFine->data ? PETSC_FALSE : PETSC_TRUE; 9199bceba477SMatthew G. Knepley PetscErrorCode ierr; 9200bceba477SMatthew G. Knepley 9201bceba477SMatthew G. Knepley PetscFunctionBegin; 9202e87a4003SBarry Smith ierr = DMGetGlobalSection(dmFine, &gsf);CHKERRQ(ierr); 9203bceba477SMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(gsf, &m);CHKERRQ(ierr); 9204e87a4003SBarry Smith ierr = DMGetGlobalSection(dmCoarse, &gsc);CHKERRQ(ierr); 9205bceba477SMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(gsc, &n);CHKERRQ(ierr); 920668132eb9SMatthew G. Knepley 9207fd194bc8SStefano Zampini ierr = PetscStrcmp(dmCoarse->mattype, MATIS, &ismatis);CHKERRQ(ierr); 9208bceba477SMatthew G. Knepley ierr = MatCreate(PetscObjectComm((PetscObject) dmCoarse), interpolation);CHKERRQ(ierr); 9209bceba477SMatthew G. Knepley ierr = MatSetSizes(*interpolation, m, n, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 9210fd194bc8SStefano Zampini ierr = MatSetType(*interpolation, ismatis ? MATAIJ : dmCoarse->mattype);CHKERRQ(ierr); 9211a063dac3SMatthew G. Knepley ierr = DMGetApplicationContext(dmFine, &ctx);CHKERRQ(ierr); 921268132eb9SMatthew G. Knepley 9213a8fb8f29SToby Isaac ierr = DMGetCoarseDM(dmFine, &cdm);CHKERRQ(ierr); 921468132eb9SMatthew G. Knepley ierr = DMPlexGetRegularRefinement(dmFine, ®ular);CHKERRQ(ierr); 9215cf51de39SMatthew G. Knepley if (!isRefined || (regular && cdm == dmCoarse)) {ierr = DMPlexComputeInterpolatorNested(dmCoarse, dmFine, isRefined, *interpolation, ctx);CHKERRQ(ierr);} 921668132eb9SMatthew G. Knepley else {ierr = DMPlexComputeInterpolatorGeneral(dmCoarse, dmFine, *interpolation, ctx);CHKERRQ(ierr);} 921768132eb9SMatthew G. Knepley ierr = MatViewFromOptions(*interpolation, NULL, "-interp_mat_view");CHKERRQ(ierr); 92184db47ee9SStefano Zampini if (scaling) { 92195d1c2e58SMatthew G. Knepley /* Use naive scaling */ 92205d1c2e58SMatthew G. Knepley ierr = DMCreateInterpolationScale(dmCoarse, dmFine, *interpolation, scaling);CHKERRQ(ierr); 92214db47ee9SStefano Zampini } 9222a063dac3SMatthew G. Knepley PetscFunctionReturn(0); 9223a063dac3SMatthew G. Knepley } 9224bceba477SMatthew G. Knepley 92256dbf9973SLawrence Mitchell PetscErrorCode DMCreateInjection_Plex(DM dmCoarse, DM dmFine, Mat *mat) 9226a063dac3SMatthew G. Knepley { 922790748bafSMatthew G. Knepley PetscErrorCode ierr; 92286dbf9973SLawrence Mitchell VecScatter ctx; 922990748bafSMatthew G. Knepley 9230a063dac3SMatthew G. Knepley PetscFunctionBegin; 92316dbf9973SLawrence Mitchell ierr = DMPlexComputeInjectorFEM(dmCoarse, dmFine, &ctx, NULL);CHKERRQ(ierr); 92326dbf9973SLawrence Mitchell ierr = MatCreateScatter(PetscObjectComm((PetscObject)ctx), ctx, mat);CHKERRQ(ierr); 92336dbf9973SLawrence Mitchell ierr = VecScatterDestroy(&ctx);CHKERRQ(ierr); 9234bceba477SMatthew G. Knepley PetscFunctionReturn(0); 9235bceba477SMatthew G. Knepley } 9236bceba477SMatthew G. Knepley 92373e9753d6SMatthew G. Knepley static void g0_identity_private(PetscInt dim, PetscInt Nf, PetscInt NfAux, 92383e9753d6SMatthew G. Knepley const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 92393e9753d6SMatthew G. Knepley const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 92403e9753d6SMatthew G. Knepley PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]) 92413e9753d6SMatthew G. Knepley { 924200635df3SMatthew G. Knepley const PetscInt Nc = uOff[1] - uOff[0]; 924300635df3SMatthew G. Knepley PetscInt c; 924400635df3SMatthew G. Knepley for (c = 0; c < Nc; ++c) g0[c*Nc+c] = 1.0; 92453e9753d6SMatthew G. Knepley } 92463e9753d6SMatthew G. Knepley 9247b4937a87SMatthew G. Knepley PetscErrorCode DMCreateMassMatrixLumped_Plex(DM dm, Vec *mass) 9248b4937a87SMatthew G. Knepley { 9249b4937a87SMatthew G. Knepley DM dmc; 9250b4937a87SMatthew G. Knepley PetscDS ds; 9251b4937a87SMatthew G. Knepley Vec ones, locmass; 9252b4937a87SMatthew G. Knepley IS cellIS; 9253b4937a87SMatthew G. Knepley PetscFormKey key; 9254b4937a87SMatthew G. Knepley PetscInt depth; 9255b4937a87SMatthew G. Knepley PetscErrorCode ierr; 9256b4937a87SMatthew G. Knepley 9257b4937a87SMatthew G. Knepley PetscFunctionBegin; 9258b4937a87SMatthew G. Knepley ierr = DMClone(dm, &dmc);CHKERRQ(ierr); 9259b4937a87SMatthew G. Knepley ierr = DMCopyDisc(dm, dmc);CHKERRQ(ierr); 9260b4937a87SMatthew G. Knepley ierr = DMGetDS(dmc, &ds);CHKERRQ(ierr); 9261b4937a87SMatthew G. Knepley ierr = PetscDSSetJacobian(ds, 0, 0, g0_identity_private, NULL, NULL, NULL);CHKERRQ(ierr); 9262b4937a87SMatthew G. Knepley ierr = DMCreateGlobalVector(dmc, mass);CHKERRQ(ierr); 9263b4937a87SMatthew G. Knepley ierr = DMGetLocalVector(dmc, &ones);CHKERRQ(ierr); 9264b4937a87SMatthew G. Knepley ierr = DMGetLocalVector(dmc, &locmass);CHKERRQ(ierr); 9265b4937a87SMatthew G. Knepley ierr = DMPlexGetDepth(dmc, &depth);CHKERRQ(ierr); 9266b4937a87SMatthew G. Knepley ierr = DMGetStratumIS(dmc, "depth", depth, &cellIS);CHKERRQ(ierr); 9267b4937a87SMatthew G. Knepley ierr = VecSet(locmass, 0.0);CHKERRQ(ierr); 9268b4937a87SMatthew G. Knepley ierr = VecSet(ones, 1.0);CHKERRQ(ierr); 9269b4937a87SMatthew G. Knepley key.label = NULL; 9270b4937a87SMatthew G. Knepley key.value = 0; 9271b4937a87SMatthew G. Knepley key.field = 0; 9272b4937a87SMatthew G. Knepley key.part = 0; 9273b4937a87SMatthew G. Knepley ierr = DMPlexComputeJacobian_Action_Internal(dmc, key, cellIS, 0.0, 0.0, ones, NULL, ones, locmass, NULL);CHKERRQ(ierr); 9274b4937a87SMatthew G. Knepley ierr = ISDestroy(&cellIS);CHKERRQ(ierr); 9275b4937a87SMatthew G. Knepley ierr = VecSet(*mass, 0.0);CHKERRQ(ierr); 9276b4937a87SMatthew G. Knepley ierr = DMLocalToGlobalBegin(dmc, locmass, ADD_VALUES, *mass);CHKERRQ(ierr); 9277b4937a87SMatthew G. Knepley ierr = DMLocalToGlobalEnd(dmc, locmass, ADD_VALUES, *mass);CHKERRQ(ierr); 9278b4937a87SMatthew G. Knepley ierr = DMRestoreLocalVector(dmc, &ones);CHKERRQ(ierr); 9279b4937a87SMatthew G. Knepley ierr = DMRestoreLocalVector(dmc, &locmass);CHKERRQ(ierr); 9280b4937a87SMatthew G. Knepley ierr = DMDestroy(&dmc);CHKERRQ(ierr); 9281b4937a87SMatthew G. Knepley PetscFunctionReturn(0); 9282b4937a87SMatthew G. Knepley } 9283b4937a87SMatthew G. Knepley 9284bd041c0cSMatthew G. Knepley PetscErrorCode DMCreateMassMatrix_Plex(DM dmCoarse, DM dmFine, Mat *mass) 9285bd041c0cSMatthew G. Knepley { 9286bd041c0cSMatthew G. Knepley PetscSection gsc, gsf; 9287bd041c0cSMatthew G. Knepley PetscInt m, n; 9288bd041c0cSMatthew G. Knepley void *ctx; 9289bd041c0cSMatthew G. Knepley DM cdm; 9290bd041c0cSMatthew G. Knepley PetscBool regular; 9291bd041c0cSMatthew G. Knepley PetscErrorCode ierr; 9292bd041c0cSMatthew G. Knepley 9293bd041c0cSMatthew G. Knepley PetscFunctionBegin; 92943e9753d6SMatthew G. Knepley if (dmFine == dmCoarse) { 92953e9753d6SMatthew G. Knepley DM dmc; 92963e9753d6SMatthew G. Knepley PetscDS ds; 9297b4937a87SMatthew G. Knepley PetscWeakForm wf; 92983e9753d6SMatthew G. Knepley Vec u; 92993e9753d6SMatthew G. Knepley IS cellIS; 930006ad1575SMatthew G. Knepley PetscFormKey key; 93013e9753d6SMatthew G. Knepley PetscInt depth; 93023e9753d6SMatthew G. Knepley 93033e9753d6SMatthew G. Knepley ierr = DMClone(dmFine, &dmc);CHKERRQ(ierr); 93043e9753d6SMatthew G. Knepley ierr = DMCopyDisc(dmFine, dmc);CHKERRQ(ierr); 93053e9753d6SMatthew G. Knepley ierr = DMGetDS(dmc, &ds);CHKERRQ(ierr); 9306b4937a87SMatthew G. Knepley ierr = PetscDSGetWeakForm(ds, &wf);CHKERRQ(ierr); 9307b4937a87SMatthew G. Knepley ierr = PetscWeakFormClear(wf);CHKERRQ(ierr); 93083e9753d6SMatthew G. Knepley ierr = PetscDSSetJacobian(ds, 0, 0, g0_identity_private, NULL, NULL, NULL);CHKERRQ(ierr); 93093e9753d6SMatthew G. Knepley ierr = DMCreateMatrix(dmc, mass);CHKERRQ(ierr); 93103e9753d6SMatthew G. Knepley ierr = DMGetGlobalVector(dmc, &u);CHKERRQ(ierr); 93113e9753d6SMatthew G. Knepley ierr = DMPlexGetDepth(dmc, &depth);CHKERRQ(ierr); 93123e9753d6SMatthew G. Knepley ierr = DMGetStratumIS(dmc, "depth", depth, &cellIS);CHKERRQ(ierr); 93133e9753d6SMatthew G. Knepley ierr = MatZeroEntries(*mass);CHKERRQ(ierr); 93146528b96dSMatthew G. Knepley key.label = NULL; 93156528b96dSMatthew G. Knepley key.value = 0; 93166528b96dSMatthew G. Knepley key.field = 0; 931706ad1575SMatthew G. Knepley key.part = 0; 93186528b96dSMatthew G. Knepley ierr = DMPlexComputeJacobian_Internal(dmc, key, cellIS, 0.0, 0.0, u, NULL, *mass, *mass, NULL);CHKERRQ(ierr); 93193e9753d6SMatthew G. Knepley ierr = ISDestroy(&cellIS);CHKERRQ(ierr); 93203e9753d6SMatthew G. Knepley ierr = DMRestoreGlobalVector(dmc, &u);CHKERRQ(ierr); 93213e9753d6SMatthew G. Knepley ierr = DMDestroy(&dmc);CHKERRQ(ierr); 93223e9753d6SMatthew G. Knepley } else { 9323e87a4003SBarry Smith ierr = DMGetGlobalSection(dmFine, &gsf);CHKERRQ(ierr); 9324bd041c0cSMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(gsf, &m);CHKERRQ(ierr); 9325e87a4003SBarry Smith ierr = DMGetGlobalSection(dmCoarse, &gsc);CHKERRQ(ierr); 9326bd041c0cSMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(gsc, &n);CHKERRQ(ierr); 9327bd041c0cSMatthew G. Knepley 9328bd041c0cSMatthew G. Knepley ierr = MatCreate(PetscObjectComm((PetscObject) dmCoarse), mass);CHKERRQ(ierr); 9329bd041c0cSMatthew G. Knepley ierr = MatSetSizes(*mass, m, n, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 9330bd041c0cSMatthew G. Knepley ierr = MatSetType(*mass, dmCoarse->mattype);CHKERRQ(ierr); 9331bd041c0cSMatthew G. Knepley ierr = DMGetApplicationContext(dmFine, &ctx);CHKERRQ(ierr); 9332bd041c0cSMatthew G. Knepley 9333bd041c0cSMatthew G. Knepley ierr = DMGetCoarseDM(dmFine, &cdm);CHKERRQ(ierr); 9334bd041c0cSMatthew G. Knepley ierr = DMPlexGetRegularRefinement(dmFine, ®ular);CHKERRQ(ierr); 9335bd041c0cSMatthew G. Knepley if (regular && cdm == dmCoarse) {ierr = DMPlexComputeMassMatrixNested(dmCoarse, dmFine, *mass, ctx);CHKERRQ(ierr);} 9336bd041c0cSMatthew G. Knepley else {ierr = DMPlexComputeMassMatrixGeneral(dmCoarse, dmFine, *mass, ctx);CHKERRQ(ierr);} 93373e9753d6SMatthew G. Knepley } 9338bd041c0cSMatthew G. Knepley ierr = MatViewFromOptions(*mass, NULL, "-mass_mat_view");CHKERRQ(ierr); 9339bd041c0cSMatthew G. Knepley PetscFunctionReturn(0); 9340bd041c0cSMatthew G. Knepley } 9341bd041c0cSMatthew G. Knepley 93420aef6b92SMatthew G. Knepley /*@ 93430aef6b92SMatthew G. Knepley DMPlexGetRegularRefinement - Get the flag indicating that this mesh was obtained by regular refinement from its coarse mesh 93440aef6b92SMatthew G. Knepley 93450aef6b92SMatthew G. Knepley Input Parameter: 93460aef6b92SMatthew G. Knepley . dm - The DMPlex object 93470aef6b92SMatthew G. Knepley 93480aef6b92SMatthew G. Knepley Output Parameter: 93490aef6b92SMatthew G. Knepley . regular - The flag 93500aef6b92SMatthew G. Knepley 93510aef6b92SMatthew G. Knepley Level: intermediate 93520aef6b92SMatthew G. Knepley 93530aef6b92SMatthew G. Knepley .seealso: DMPlexSetRegularRefinement() 93540aef6b92SMatthew G. Knepley @*/ 93550aef6b92SMatthew G. Knepley PetscErrorCode DMPlexGetRegularRefinement(DM dm, PetscBool *regular) 93560aef6b92SMatthew G. Knepley { 93570aef6b92SMatthew G. Knepley PetscFunctionBegin; 93580aef6b92SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 93590aef6b92SMatthew G. Knepley PetscValidPointer(regular, 2); 93600aef6b92SMatthew G. Knepley *regular = ((DM_Plex *) dm->data)->regularRefinement; 93610aef6b92SMatthew G. Knepley PetscFunctionReturn(0); 93620aef6b92SMatthew G. Knepley } 93630aef6b92SMatthew G. Knepley 93640aef6b92SMatthew G. Knepley /*@ 93650aef6b92SMatthew G. Knepley DMPlexSetRegularRefinement - Set the flag indicating that this mesh was obtained by regular refinement from its coarse mesh 93660aef6b92SMatthew G. Knepley 93670aef6b92SMatthew G. Knepley Input Parameters: 93680aef6b92SMatthew G. Knepley + dm - The DMPlex object 93690aef6b92SMatthew G. Knepley - regular - The flag 93700aef6b92SMatthew G. Knepley 93710aef6b92SMatthew G. Knepley Level: intermediate 93720aef6b92SMatthew G. Knepley 93730aef6b92SMatthew G. Knepley .seealso: DMPlexGetRegularRefinement() 93740aef6b92SMatthew G. Knepley @*/ 93750aef6b92SMatthew G. Knepley PetscErrorCode DMPlexSetRegularRefinement(DM dm, PetscBool regular) 93760aef6b92SMatthew G. Knepley { 93770aef6b92SMatthew G. Knepley PetscFunctionBegin; 93780aef6b92SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 93790aef6b92SMatthew G. Knepley ((DM_Plex *) dm->data)->regularRefinement = regular; 93800aef6b92SMatthew G. Knepley PetscFunctionReturn(0); 93810aef6b92SMatthew G. Knepley } 93820aef6b92SMatthew G. Knepley 9383f7c74593SToby Isaac /* anchors */ 9384a68b90caSToby Isaac /*@ 9385f7c74593SToby Isaac DMPlexGetAnchors - Get the layout of the anchor (point-to-point) constraints. Typically, the user will not have to 9386ebdb1bfaSJed Brown call DMPlexGetAnchors() directly: if there are anchors, then DMPlexGetAnchors() is called during DMGetDefaultConstraints(). 9387a68b90caSToby Isaac 9388e228b242SToby Isaac not collective 9389a68b90caSToby Isaac 9390f899ff85SJose E. Roman Input Parameter: 9391a68b90caSToby Isaac . dm - The DMPlex object 9392a68b90caSToby Isaac 9393a68b90caSToby Isaac Output Parameters: 9394a68b90caSToby Isaac + anchorSection - If not NULL, set to the section describing which points anchor the constrained points. 9395a68b90caSToby Isaac - anchorIS - If not NULL, set to the list of anchors indexed by anchorSection 9396a68b90caSToby Isaac 9397a68b90caSToby Isaac Level: intermediate 9398a68b90caSToby Isaac 9399ebdb1bfaSJed Brown .seealso: DMPlexSetAnchors(), DMGetDefaultConstraints(), DMSetDefaultConstraints() 9400a68b90caSToby Isaac @*/ 9401a17985deSToby Isaac PetscErrorCode DMPlexGetAnchors(DM dm, PetscSection *anchorSection, IS *anchorIS) 9402a68b90caSToby Isaac { 9403a68b90caSToby Isaac DM_Plex *plex = (DM_Plex *)dm->data; 940441e6d900SToby Isaac PetscErrorCode ierr; 9405a68b90caSToby Isaac 9406a68b90caSToby Isaac PetscFunctionBegin; 9407a68b90caSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 940841e6d900SToby Isaac if (!plex->anchorSection && !plex->anchorIS && plex->createanchors) {ierr = (*plex->createanchors)(dm);CHKERRQ(ierr);} 9409a68b90caSToby Isaac if (anchorSection) *anchorSection = plex->anchorSection; 9410a68b90caSToby Isaac if (anchorIS) *anchorIS = plex->anchorIS; 9411a68b90caSToby Isaac PetscFunctionReturn(0); 9412a68b90caSToby Isaac } 9413a68b90caSToby Isaac 9414a68b90caSToby Isaac /*@ 9415f7c74593SToby Isaac DMPlexSetAnchors - Set the layout of the local anchor (point-to-point) constraints. Unlike boundary conditions, 9416f7c74593SToby Isaac when a point's degrees of freedom in a section are constrained to an outside value, the anchor constraints set a 9417a68b90caSToby Isaac point's degrees of freedom to be a linear combination of other points' degrees of freedom. 9418a68b90caSToby Isaac 9419a17985deSToby Isaac After specifying the layout of constraints with DMPlexSetAnchors(), one specifies the constraints by calling 9420ebdb1bfaSJed Brown DMGetDefaultConstraints() and filling in the entries in the constraint matrix. 9421a68b90caSToby Isaac 9422e228b242SToby Isaac collective on dm 9423a68b90caSToby Isaac 9424a68b90caSToby Isaac Input Parameters: 9425a68b90caSToby Isaac + dm - The DMPlex object 9426e228b242SToby 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). 9427e228b242SToby Isaac - anchorIS - The list of all anchor points. Must have a local communicator (PETSC_COMM_SELF or derivative). 9428a68b90caSToby Isaac 9429a68b90caSToby Isaac The reference counts of anchorSection and anchorIS are incremented. 9430a68b90caSToby Isaac 9431a68b90caSToby Isaac Level: intermediate 9432a68b90caSToby Isaac 9433ebdb1bfaSJed Brown .seealso: DMPlexGetAnchors(), DMGetDefaultConstraints(), DMSetDefaultConstraints() 9434a68b90caSToby Isaac @*/ 9435a17985deSToby Isaac PetscErrorCode DMPlexSetAnchors(DM dm, PetscSection anchorSection, IS anchorIS) 9436a68b90caSToby Isaac { 9437a68b90caSToby Isaac DM_Plex *plex = (DM_Plex *)dm->data; 9438e228b242SToby Isaac PetscMPIInt result; 9439a68b90caSToby Isaac PetscErrorCode ierr; 9440a68b90caSToby Isaac 9441a68b90caSToby Isaac PetscFunctionBegin; 9442a68b90caSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9443e228b242SToby Isaac if (anchorSection) { 9444e228b242SToby Isaac PetscValidHeaderSpecific(anchorSection,PETSC_SECTION_CLASSID,2); 9445ffc4695bSBarry Smith ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)anchorSection),&result);CHKERRMPI(ierr); 94462c71b3e2SJacob Faibussowitsch PetscCheckFalse(result != MPI_CONGRUENT && result != MPI_IDENT,PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"anchor section must have local communicator"); 9447e228b242SToby Isaac } 9448e228b242SToby Isaac if (anchorIS) { 9449e228b242SToby Isaac PetscValidHeaderSpecific(anchorIS,IS_CLASSID,3); 9450ffc4695bSBarry Smith ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)anchorIS),&result);CHKERRMPI(ierr); 94512c71b3e2SJacob Faibussowitsch PetscCheckFalse(result != MPI_CONGRUENT && result != MPI_IDENT,PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"anchor IS must have local communicator"); 9452e228b242SToby Isaac } 9453a68b90caSToby Isaac 9454a68b90caSToby Isaac ierr = PetscObjectReference((PetscObject)anchorSection);CHKERRQ(ierr); 9455a68b90caSToby Isaac ierr = PetscSectionDestroy(&plex->anchorSection);CHKERRQ(ierr); 9456a68b90caSToby Isaac plex->anchorSection = anchorSection; 9457a68b90caSToby Isaac 9458a68b90caSToby Isaac ierr = PetscObjectReference((PetscObject)anchorIS);CHKERRQ(ierr); 9459a68b90caSToby Isaac ierr = ISDestroy(&plex->anchorIS);CHKERRQ(ierr); 9460a68b90caSToby Isaac plex->anchorIS = anchorIS; 9461a68b90caSToby Isaac 9462cf9c20a2SJed Brown if (PetscUnlikelyDebug(anchorIS && anchorSection)) { 9463a68b90caSToby Isaac PetscInt size, a, pStart, pEnd; 9464a68b90caSToby Isaac const PetscInt *anchors; 9465a68b90caSToby Isaac 9466a68b90caSToby Isaac ierr = PetscSectionGetChart(anchorSection,&pStart,&pEnd);CHKERRQ(ierr); 9467a68b90caSToby Isaac ierr = ISGetLocalSize(anchorIS,&size);CHKERRQ(ierr); 9468a68b90caSToby Isaac ierr = ISGetIndices(anchorIS,&anchors);CHKERRQ(ierr); 9469a68b90caSToby Isaac for (a = 0; a < size; a++) { 9470a68b90caSToby Isaac PetscInt p; 9471a68b90caSToby Isaac 9472a68b90caSToby Isaac p = anchors[a]; 9473a68b90caSToby Isaac if (p >= pStart && p < pEnd) { 9474a68b90caSToby Isaac PetscInt dof; 9475a68b90caSToby Isaac 9476a68b90caSToby Isaac ierr = PetscSectionGetDof(anchorSection,p,&dof);CHKERRQ(ierr); 9477a68b90caSToby Isaac if (dof) { 9478a68b90caSToby Isaac PetscErrorCode ierr2; 9479a68b90caSToby Isaac 9480a68b90caSToby Isaac ierr2 = ISRestoreIndices(anchorIS,&anchors);CHKERRQ(ierr2); 948198921bdaSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Point %D cannot be constrained and an anchor",p); 9482a68b90caSToby Isaac } 9483a68b90caSToby Isaac } 9484a68b90caSToby Isaac } 9485a68b90caSToby Isaac ierr = ISRestoreIndices(anchorIS,&anchors);CHKERRQ(ierr); 9486a68b90caSToby Isaac } 9487f7c74593SToby Isaac /* reset the generic constraints */ 948879769bd5SJed Brown ierr = DMSetDefaultConstraints(dm,NULL,NULL,NULL);CHKERRQ(ierr); 9489a68b90caSToby Isaac PetscFunctionReturn(0); 9490a68b90caSToby Isaac } 9491a68b90caSToby Isaac 9492f7c74593SToby Isaac static PetscErrorCode DMPlexCreateConstraintSection_Anchors(DM dm, PetscSection section, PetscSection *cSec) 9493a68b90caSToby Isaac { 9494f7c74593SToby Isaac PetscSection anchorSection; 94956995de1eSToby Isaac PetscInt pStart, pEnd, sStart, sEnd, p, dof, numFields, f; 9496a68b90caSToby Isaac PetscErrorCode ierr; 9497a68b90caSToby Isaac 9498a68b90caSToby Isaac PetscFunctionBegin; 9499a68b90caSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9500a17985deSToby Isaac ierr = DMPlexGetAnchors(dm,&anchorSection,NULL);CHKERRQ(ierr); 9501e228b242SToby Isaac ierr = PetscSectionCreate(PETSC_COMM_SELF,cSec);CHKERRQ(ierr); 9502a68b90caSToby Isaac ierr = PetscSectionGetNumFields(section,&numFields);CHKERRQ(ierr); 95036995de1eSToby Isaac if (numFields) { 9504719ab38cSToby Isaac PetscInt f; 9505a68b90caSToby Isaac ierr = PetscSectionSetNumFields(*cSec,numFields);CHKERRQ(ierr); 9506719ab38cSToby Isaac 9507719ab38cSToby Isaac for (f = 0; f < numFields; f++) { 9508719ab38cSToby Isaac PetscInt numComp; 9509719ab38cSToby Isaac 9510719ab38cSToby Isaac ierr = PetscSectionGetFieldComponents(section,f,&numComp);CHKERRQ(ierr); 9511719ab38cSToby Isaac ierr = PetscSectionSetFieldComponents(*cSec,f,numComp);CHKERRQ(ierr); 9512719ab38cSToby Isaac } 95136995de1eSToby Isaac } 9514a68b90caSToby Isaac ierr = PetscSectionGetChart(anchorSection,&pStart,&pEnd);CHKERRQ(ierr); 95156995de1eSToby Isaac ierr = PetscSectionGetChart(section,&sStart,&sEnd);CHKERRQ(ierr); 95166995de1eSToby Isaac pStart = PetscMax(pStart,sStart); 95176995de1eSToby Isaac pEnd = PetscMin(pEnd,sEnd); 95186995de1eSToby Isaac pEnd = PetscMax(pStart,pEnd); 9519a68b90caSToby Isaac ierr = PetscSectionSetChart(*cSec,pStart,pEnd);CHKERRQ(ierr); 9520a68b90caSToby Isaac for (p = pStart; p < pEnd; p++) { 9521a68b90caSToby Isaac ierr = PetscSectionGetDof(anchorSection,p,&dof);CHKERRQ(ierr); 9522a68b90caSToby Isaac if (dof) { 9523a68b90caSToby Isaac ierr = PetscSectionGetDof(section,p,&dof);CHKERRQ(ierr); 9524a68b90caSToby Isaac ierr = PetscSectionSetDof(*cSec,p,dof);CHKERRQ(ierr); 9525a68b90caSToby Isaac for (f = 0; f < numFields; f++) { 9526a68b90caSToby Isaac ierr = PetscSectionGetFieldDof(section,p,f,&dof);CHKERRQ(ierr); 9527a68b90caSToby Isaac ierr = PetscSectionSetFieldDof(*cSec,p,f,dof);CHKERRQ(ierr); 9528a68b90caSToby Isaac } 9529a68b90caSToby Isaac } 9530a68b90caSToby Isaac } 9531a68b90caSToby Isaac ierr = PetscSectionSetUp(*cSec);CHKERRQ(ierr); 9532ae65431dSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) *cSec, "Constraint Section");CHKERRQ(ierr); 9533a68b90caSToby Isaac PetscFunctionReturn(0); 9534a68b90caSToby Isaac } 9535a68b90caSToby Isaac 9536f7c74593SToby Isaac static PetscErrorCode DMPlexCreateConstraintMatrix_Anchors(DM dm, PetscSection section, PetscSection cSec, Mat *cMat) 9537a68b90caSToby Isaac { 9538f7c74593SToby Isaac PetscSection aSec; 9539ae65431dSMatthew G. Knepley PetscInt pStart, pEnd, p, sStart, sEnd, dof, aDof, aOff, off, nnz, annz, m, n, q, a, offset, *i, *j; 95400ac89760SToby Isaac const PetscInt *anchors; 95410ac89760SToby Isaac PetscInt numFields, f; 954266ad2231SToby Isaac IS aIS; 95430ac89760SToby Isaac PetscErrorCode ierr; 9544e19f7ee6SMark Adams MatType mtype; 9545e19f7ee6SMark Adams PetscBool iscuda,iskokkos; 95460ac89760SToby Isaac 95470ac89760SToby Isaac PetscFunctionBegin; 95480ac89760SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 95490ac89760SToby Isaac ierr = PetscSectionGetStorageSize(cSec, &m);CHKERRQ(ierr); 95500ac89760SToby Isaac ierr = PetscSectionGetStorageSize(section, &n);CHKERRQ(ierr); 95510ac89760SToby Isaac ierr = MatCreate(PETSC_COMM_SELF,cMat);CHKERRQ(ierr); 95520ac89760SToby Isaac ierr = MatSetSizes(*cMat,m,n,m,n);CHKERRQ(ierr); 9553e19f7ee6SMark Adams ierr = PetscStrcmp(dm->mattype,MATSEQAIJCUSPARSE,&iscuda);CHKERRQ(ierr); 9554e19f7ee6SMark Adams if (!iscuda) { ierr = PetscStrcmp(dm->mattype,MATMPIAIJCUSPARSE,&iscuda);CHKERRQ(ierr); } 9555e19f7ee6SMark Adams ierr = PetscStrcmp(dm->mattype,MATSEQAIJKOKKOS,&iskokkos);CHKERRQ(ierr); 9556e19f7ee6SMark Adams if (!iskokkos) { ierr = PetscStrcmp(dm->mattype,MATMPIAIJKOKKOS,&iskokkos);CHKERRQ(ierr); } 9557e19f7ee6SMark Adams if (iscuda) mtype = MATSEQAIJCUSPARSE; 9558e19f7ee6SMark Adams else if (iskokkos) mtype = MATSEQAIJKOKKOS; 9559e19f7ee6SMark Adams else mtype = MATSEQAIJ; 9560e19f7ee6SMark Adams ierr = MatSetType(*cMat,mtype);CHKERRQ(ierr); 9561a17985deSToby Isaac ierr = DMPlexGetAnchors(dm,&aSec,&aIS);CHKERRQ(ierr); 956266ad2231SToby Isaac ierr = ISGetIndices(aIS,&anchors);CHKERRQ(ierr); 95636995de1eSToby Isaac /* cSec will be a subset of aSec and section */ 95646995de1eSToby Isaac ierr = PetscSectionGetChart(cSec,&pStart,&pEnd);CHKERRQ(ierr); 9565ae65431dSMatthew G. Knepley ierr = PetscSectionGetChart(section,&sStart,&sEnd);CHKERRQ(ierr); 95660ac89760SToby Isaac ierr = PetscMalloc1(m+1,&i);CHKERRQ(ierr); 95670ac89760SToby Isaac i[0] = 0; 95680ac89760SToby Isaac ierr = PetscSectionGetNumFields(section,&numFields);CHKERRQ(ierr); 95690ac89760SToby Isaac for (p = pStart; p < pEnd; p++) { 9570f19733c5SToby Isaac PetscInt rDof, rOff, r; 9571f19733c5SToby Isaac 9572f19733c5SToby Isaac ierr = PetscSectionGetDof(aSec,p,&rDof);CHKERRQ(ierr); 9573f19733c5SToby Isaac if (!rDof) continue; 9574f19733c5SToby Isaac ierr = PetscSectionGetOffset(aSec,p,&rOff);CHKERRQ(ierr); 95750ac89760SToby Isaac if (numFields) { 95760ac89760SToby Isaac for (f = 0; f < numFields; f++) { 95770ac89760SToby Isaac annz = 0; 9578f19733c5SToby Isaac for (r = 0; r < rDof; r++) { 9579f19733c5SToby Isaac a = anchors[rOff + r]; 9580ae65431dSMatthew G. Knepley if (a < sStart || a >= sEnd) continue; 95810ac89760SToby Isaac ierr = PetscSectionGetFieldDof(section,a,f,&aDof);CHKERRQ(ierr); 95820ac89760SToby Isaac annz += aDof; 95830ac89760SToby Isaac } 95840ac89760SToby Isaac ierr = PetscSectionGetFieldDof(cSec,p,f,&dof);CHKERRQ(ierr); 95850ac89760SToby Isaac ierr = PetscSectionGetFieldOffset(cSec,p,f,&off);CHKERRQ(ierr); 95860ac89760SToby Isaac for (q = 0; q < dof; q++) { 95870ac89760SToby Isaac i[off + q + 1] = i[off + q] + annz; 95880ac89760SToby Isaac } 95890ac89760SToby Isaac } 95902f7452b8SBarry Smith } else { 95910ac89760SToby Isaac annz = 0; 9592326b8f31SMatthew G. Knepley ierr = PetscSectionGetDof(cSec,p,&dof);CHKERRQ(ierr); 95930ac89760SToby Isaac for (q = 0; q < dof; q++) { 9594ae65431dSMatthew G. Knepley a = anchors[rOff + q]; 9595ae65431dSMatthew G. Knepley if (a < sStart || a >= sEnd) continue; 95960ac89760SToby Isaac ierr = PetscSectionGetDof(section,a,&aDof);CHKERRQ(ierr); 95970ac89760SToby Isaac annz += aDof; 95980ac89760SToby Isaac } 95990ac89760SToby Isaac ierr = PetscSectionGetDof(cSec,p,&dof);CHKERRQ(ierr); 96000ac89760SToby Isaac ierr = PetscSectionGetOffset(cSec,p,&off);CHKERRQ(ierr); 96010ac89760SToby Isaac for (q = 0; q < dof; q++) { 96020ac89760SToby Isaac i[off + q + 1] = i[off + q] + annz; 96030ac89760SToby Isaac } 96040ac89760SToby Isaac } 96050ac89760SToby Isaac } 96060ac89760SToby Isaac nnz = i[m]; 96070ac89760SToby Isaac ierr = PetscMalloc1(nnz,&j);CHKERRQ(ierr); 96080ac89760SToby Isaac offset = 0; 96090ac89760SToby Isaac for (p = pStart; p < pEnd; p++) { 96100ac89760SToby Isaac if (numFields) { 96110ac89760SToby Isaac for (f = 0; f < numFields; f++) { 96120ac89760SToby Isaac ierr = PetscSectionGetFieldDof(cSec,p,f,&dof);CHKERRQ(ierr); 96130ac89760SToby Isaac for (q = 0; q < dof; q++) { 96140ac89760SToby Isaac PetscInt rDof, rOff, r; 96150ac89760SToby Isaac ierr = PetscSectionGetDof(aSec,p,&rDof);CHKERRQ(ierr); 96160ac89760SToby Isaac ierr = PetscSectionGetOffset(aSec,p,&rOff);CHKERRQ(ierr); 96170ac89760SToby Isaac for (r = 0; r < rDof; r++) { 96180ac89760SToby Isaac PetscInt s; 96190ac89760SToby Isaac 96200ac89760SToby Isaac a = anchors[rOff + r]; 9621ae65431dSMatthew G. Knepley if (a < sStart || a >= sEnd) continue; 96220ac89760SToby Isaac ierr = PetscSectionGetFieldDof(section,a,f,&aDof);CHKERRQ(ierr); 96230ac89760SToby Isaac ierr = PetscSectionGetFieldOffset(section,a,f,&aOff);CHKERRQ(ierr); 96240ac89760SToby Isaac for (s = 0; s < aDof; s++) { 96250ac89760SToby Isaac j[offset++] = aOff + s; 96260ac89760SToby Isaac } 96270ac89760SToby Isaac } 96280ac89760SToby Isaac } 96290ac89760SToby Isaac } 96302f7452b8SBarry Smith } else { 96310ac89760SToby Isaac ierr = PetscSectionGetDof(cSec,p,&dof);CHKERRQ(ierr); 96320ac89760SToby Isaac for (q = 0; q < dof; q++) { 96330ac89760SToby Isaac PetscInt rDof, rOff, r; 96340ac89760SToby Isaac ierr = PetscSectionGetDof(aSec,p,&rDof);CHKERRQ(ierr); 96350ac89760SToby Isaac ierr = PetscSectionGetOffset(aSec,p,&rOff);CHKERRQ(ierr); 96360ac89760SToby Isaac for (r = 0; r < rDof; r++) { 96370ac89760SToby Isaac PetscInt s; 96380ac89760SToby Isaac 96390ac89760SToby Isaac a = anchors[rOff + r]; 9640ae65431dSMatthew G. Knepley if (a < sStart || a >= sEnd) continue; 96410ac89760SToby Isaac ierr = PetscSectionGetDof(section,a,&aDof);CHKERRQ(ierr); 96420ac89760SToby Isaac ierr = PetscSectionGetOffset(section,a,&aOff);CHKERRQ(ierr); 96430ac89760SToby Isaac for (s = 0; s < aDof; s++) { 96440ac89760SToby Isaac j[offset++] = aOff + s; 96450ac89760SToby Isaac } 96460ac89760SToby Isaac } 96470ac89760SToby Isaac } 96480ac89760SToby Isaac } 96490ac89760SToby Isaac } 96500ac89760SToby Isaac ierr = MatSeqAIJSetPreallocationCSR(*cMat,i,j,NULL);CHKERRQ(ierr); 965125570a81SToby Isaac ierr = PetscFree(i);CHKERRQ(ierr); 965225570a81SToby Isaac ierr = PetscFree(j);CHKERRQ(ierr); 965366ad2231SToby Isaac ierr = ISRestoreIndices(aIS,&anchors);CHKERRQ(ierr); 96540ac89760SToby Isaac PetscFunctionReturn(0); 96550ac89760SToby Isaac } 96560ac89760SToby Isaac 965766ad2231SToby Isaac PetscErrorCode DMCreateDefaultConstraints_Plex(DM dm) 965866ad2231SToby Isaac { 9659f7c74593SToby Isaac DM_Plex *plex = (DM_Plex *)dm->data; 9660f7c74593SToby Isaac PetscSection anchorSection, section, cSec; 966166ad2231SToby Isaac Mat cMat; 966266ad2231SToby Isaac PetscErrorCode ierr; 966366ad2231SToby Isaac 966466ad2231SToby Isaac PetscFunctionBegin; 966566ad2231SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9666a17985deSToby Isaac ierr = DMPlexGetAnchors(dm,&anchorSection,NULL);CHKERRQ(ierr); 966766ad2231SToby Isaac if (anchorSection) { 966844a7f3ddSMatthew G. Knepley PetscInt Nf; 9669e228b242SToby Isaac 967092fd8e1eSJed Brown ierr = DMGetLocalSection(dm,§ion);CHKERRQ(ierr); 9671f7c74593SToby Isaac ierr = DMPlexCreateConstraintSection_Anchors(dm,section,&cSec);CHKERRQ(ierr); 9672f7c74593SToby Isaac ierr = DMPlexCreateConstraintMatrix_Anchors(dm,section,cSec,&cMat);CHKERRQ(ierr); 967344a7f3ddSMatthew G. Knepley ierr = DMGetNumFields(dm,&Nf);CHKERRQ(ierr); 967444a7f3ddSMatthew G. Knepley if (Nf && plex->computeanchormatrix) {ierr = (*plex->computeanchormatrix)(dm,section,cSec,cMat);CHKERRQ(ierr);} 967579769bd5SJed Brown ierr = DMSetDefaultConstraints(dm,cSec,cMat,NULL);CHKERRQ(ierr); 967666ad2231SToby Isaac ierr = PetscSectionDestroy(&cSec);CHKERRQ(ierr); 967766ad2231SToby Isaac ierr = MatDestroy(&cMat);CHKERRQ(ierr); 967866ad2231SToby Isaac } 967966ad2231SToby Isaac PetscFunctionReturn(0); 968066ad2231SToby Isaac } 9681a93c429eSMatthew G. Knepley 9682a93c429eSMatthew G. Knepley PetscErrorCode DMCreateSubDomainDM_Plex(DM dm, DMLabel label, PetscInt value, IS *is, DM *subdm) 9683a93c429eSMatthew G. Knepley { 9684a93c429eSMatthew G. Knepley IS subis; 9685a93c429eSMatthew G. Knepley PetscSection section, subsection; 9686a93c429eSMatthew G. Knepley PetscErrorCode ierr; 9687a93c429eSMatthew G. Knepley 9688a93c429eSMatthew G. Knepley PetscFunctionBegin; 968992fd8e1eSJed Brown ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr); 96902c71b3e2SJacob Faibussowitsch PetscCheckFalse(!section,PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Must set default section for DM before splitting subdomain"); 96912c71b3e2SJacob Faibussowitsch PetscCheckFalse(!subdm,PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Must set output subDM for splitting subdomain"); 9692a93c429eSMatthew G. Knepley /* Create subdomain */ 9693a93c429eSMatthew G. Knepley ierr = DMPlexFilter(dm, label, value, subdm);CHKERRQ(ierr); 9694a93c429eSMatthew G. Knepley /* Create submodel */ 969597d8846cSMatthew Knepley ierr = DMPlexGetSubpointIS(*subdm, &subis);CHKERRQ(ierr); 9696a93c429eSMatthew G. Knepley ierr = PetscSectionCreateSubmeshSection(section, subis, &subsection);CHKERRQ(ierr); 969792fd8e1eSJed Brown ierr = DMSetLocalSection(*subdm, subsection);CHKERRQ(ierr); 9698a93c429eSMatthew G. Knepley ierr = PetscSectionDestroy(&subsection);CHKERRQ(ierr); 9699e5e52638SMatthew G. Knepley ierr = DMCopyDisc(dm, *subdm);CHKERRQ(ierr); 9700a93c429eSMatthew G. Knepley /* Create map from submodel to global model */ 9701a93c429eSMatthew G. Knepley if (is) { 9702a93c429eSMatthew G. Knepley PetscSection sectionGlobal, subsectionGlobal; 9703a93c429eSMatthew G. Knepley IS spIS; 9704a93c429eSMatthew G. Knepley const PetscInt *spmap; 9705a93c429eSMatthew G. Knepley PetscInt *subIndices; 9706a93c429eSMatthew G. Knepley PetscInt subSize = 0, subOff = 0, pStart, pEnd, p; 9707a93c429eSMatthew G. Knepley PetscInt Nf, f, bs = -1, bsLocal[2], bsMinMax[2]; 9708a93c429eSMatthew G. Knepley 970997d8846cSMatthew Knepley ierr = DMPlexGetSubpointIS(*subdm, &spIS);CHKERRQ(ierr); 9710a93c429eSMatthew G. Knepley ierr = ISGetIndices(spIS, &spmap);CHKERRQ(ierr); 9711a93c429eSMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &Nf);CHKERRQ(ierr); 97126f0eb057SJed Brown ierr = DMGetGlobalSection(dm, §ionGlobal);CHKERRQ(ierr); 97136f0eb057SJed Brown ierr = DMGetGlobalSection(*subdm, &subsectionGlobal);CHKERRQ(ierr); 9714a93c429eSMatthew G. Knepley ierr = PetscSectionGetChart(subsection, &pStart, &pEnd);CHKERRQ(ierr); 9715a93c429eSMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 9716a93c429eSMatthew G. Knepley PetscInt gdof, pSubSize = 0; 9717a93c429eSMatthew G. Knepley 9718a93c429eSMatthew G. Knepley ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr); 9719a93c429eSMatthew G. Knepley if (gdof > 0) { 9720a93c429eSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 9721a93c429eSMatthew G. Knepley PetscInt fdof, fcdof; 9722a93c429eSMatthew G. Knepley 9723a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldDof(subsection, p, f, &fdof);CHKERRQ(ierr); 9724a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldConstraintDof(subsection, p, f, &fcdof);CHKERRQ(ierr); 9725a93c429eSMatthew G. Knepley pSubSize += fdof-fcdof; 9726a93c429eSMatthew G. Knepley } 9727a93c429eSMatthew G. Knepley subSize += pSubSize; 9728a93c429eSMatthew G. Knepley if (pSubSize) { 9729a93c429eSMatthew G. Knepley if (bs < 0) { 9730a93c429eSMatthew G. Knepley bs = pSubSize; 9731a93c429eSMatthew G. Knepley } else if (bs != pSubSize) { 9732a93c429eSMatthew G. Knepley /* Layout does not admit a pointwise block size */ 9733a93c429eSMatthew G. Knepley bs = 1; 9734a93c429eSMatthew G. Knepley } 9735a93c429eSMatthew G. Knepley } 9736a93c429eSMatthew G. Knepley } 9737a93c429eSMatthew G. Knepley } 9738a93c429eSMatthew G. Knepley /* Must have same blocksize on all procs (some might have no points) */ 9739a93c429eSMatthew G. Knepley bsLocal[0] = bs < 0 ? PETSC_MAX_INT : bs; bsLocal[1] = bs; 9740a93c429eSMatthew G. Knepley ierr = PetscGlobalMinMaxInt(PetscObjectComm((PetscObject) dm), bsLocal, bsMinMax);CHKERRQ(ierr); 9741a93c429eSMatthew G. Knepley if (bsMinMax[0] != bsMinMax[1]) {bs = 1;} 9742a93c429eSMatthew G. Knepley else {bs = bsMinMax[0];} 9743a93c429eSMatthew G. Knepley ierr = PetscMalloc1(subSize, &subIndices);CHKERRQ(ierr); 9744a93c429eSMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 9745a93c429eSMatthew G. Knepley PetscInt gdof, goff; 9746a93c429eSMatthew G. Knepley 9747a93c429eSMatthew G. Knepley ierr = PetscSectionGetDof(subsectionGlobal, p, &gdof);CHKERRQ(ierr); 9748a93c429eSMatthew G. Knepley if (gdof > 0) { 9749a93c429eSMatthew G. Knepley const PetscInt point = spmap[p]; 9750a93c429eSMatthew G. Knepley 9751a93c429eSMatthew G. Knepley ierr = PetscSectionGetOffset(sectionGlobal, point, &goff);CHKERRQ(ierr); 9752a93c429eSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 9753a93c429eSMatthew G. Knepley PetscInt fdof, fcdof, fc, f2, poff = 0; 9754a93c429eSMatthew G. Knepley 9755a93c429eSMatthew G. Knepley /* Can get rid of this loop by storing field information in the global section */ 9756a93c429eSMatthew G. Knepley for (f2 = 0; f2 < f; ++f2) { 9757a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, p, f2, &fdof);CHKERRQ(ierr); 9758a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldConstraintDof(section, p, f2, &fcdof);CHKERRQ(ierr); 9759a93c429eSMatthew G. Knepley poff += fdof-fcdof; 9760a93c429eSMatthew G. Knepley } 9761a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr); 9762a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr); 9763a93c429eSMatthew G. Knepley for (fc = 0; fc < fdof-fcdof; ++fc, ++subOff) { 9764a93c429eSMatthew G. Knepley subIndices[subOff] = goff+poff+fc; 9765a93c429eSMatthew G. Knepley } 9766a93c429eSMatthew G. Knepley } 9767a93c429eSMatthew G. Knepley } 9768a93c429eSMatthew G. Knepley } 9769a93c429eSMatthew G. Knepley ierr = ISRestoreIndices(spIS, &spmap);CHKERRQ(ierr); 9770a93c429eSMatthew G. Knepley ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), subSize, subIndices, PETSC_OWN_POINTER, is);CHKERRQ(ierr); 9771a93c429eSMatthew G. Knepley if (bs > 1) { 9772a93c429eSMatthew G. Knepley /* We need to check that the block size does not come from non-contiguous fields */ 9773a93c429eSMatthew G. Knepley PetscInt i, j, set = 1; 9774a93c429eSMatthew G. Knepley for (i = 0; i < subSize; i += bs) { 9775a93c429eSMatthew G. Knepley for (j = 0; j < bs; ++j) { 9776a93c429eSMatthew G. Knepley if (subIndices[i+j] != subIndices[i]+j) {set = 0; break;} 9777a93c429eSMatthew G. Knepley } 9778a93c429eSMatthew G. Knepley } 9779a93c429eSMatthew G. Knepley if (set) {ierr = ISSetBlockSize(*is, bs);CHKERRQ(ierr);} 9780a93c429eSMatthew G. Knepley } 9781a93c429eSMatthew G. Knepley /* Attach nullspace */ 9782a93c429eSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 9783a93c429eSMatthew G. Knepley (*subdm)->nullspaceConstructors[f] = dm->nullspaceConstructors[f]; 9784a93c429eSMatthew G. Knepley if ((*subdm)->nullspaceConstructors[f]) break; 9785a93c429eSMatthew G. Knepley } 9786a93c429eSMatthew G. Knepley if (f < Nf) { 9787a93c429eSMatthew G. Knepley MatNullSpace nullSpace; 97888cda7954SMatthew G. Knepley ierr = (*(*subdm)->nullspaceConstructors[f])(*subdm, f, f, &nullSpace);CHKERRQ(ierr); 97896823f3c5SBlaise Bourdin 9790a93c429eSMatthew G. Knepley ierr = PetscObjectCompose((PetscObject) *is, "nullspace", (PetscObject) nullSpace);CHKERRQ(ierr); 9791a93c429eSMatthew G. Knepley ierr = MatNullSpaceDestroy(&nullSpace);CHKERRQ(ierr); 9792a93c429eSMatthew G. Knepley } 9793a93c429eSMatthew G. Knepley } 9794a93c429eSMatthew G. Knepley PetscFunctionReturn(0); 9795a93c429eSMatthew G. Knepley } 9796c0f0dcc3SMatthew G. Knepley 9797c0f0dcc3SMatthew G. Knepley /*@ 9798c0f0dcc3SMatthew G. Knepley DMPlexMonitorThroughput - Report the cell throughput of FE integration 9799c0f0dcc3SMatthew G. Knepley 9800c0f0dcc3SMatthew G. Knepley Input Parameter: 9801c0f0dcc3SMatthew G. Knepley - dm - The DM 9802c0f0dcc3SMatthew G. Knepley 9803c0f0dcc3SMatthew G. Knepley Level: developer 9804c0f0dcc3SMatthew G. Knepley 9805c0f0dcc3SMatthew G. Knepley Options Database Keys: 9806c0f0dcc3SMatthew G. Knepley . -dm_plex_monitor_throughput - Activate the monitor 9807c0f0dcc3SMatthew G. Knepley 9808c0f0dcc3SMatthew G. Knepley .seealso: DMSetFromOptions(), DMPlexCreate() 9809c0f0dcc3SMatthew G. Knepley @*/ 9810c0f0dcc3SMatthew G. Knepley PetscErrorCode DMPlexMonitorThroughput(DM dm, void *dummy) 9811c0f0dcc3SMatthew G. Knepley { 9812e5ed2c37SJose E. Roman #if defined(PETSC_USE_LOG) 9813c0f0dcc3SMatthew G. Knepley PetscStageLog stageLog; 9814c0f0dcc3SMatthew G. Knepley PetscLogEvent event; 9815c0f0dcc3SMatthew G. Knepley PetscLogStage stage; 9816c0f0dcc3SMatthew G. Knepley PetscEventPerfInfo eventInfo; 9817c0f0dcc3SMatthew G. Knepley PetscReal cellRate, flopRate; 9818c0f0dcc3SMatthew G. Knepley PetscInt cStart, cEnd, Nf, N; 9819c0f0dcc3SMatthew G. Knepley const char *name; 9820c0f0dcc3SMatthew G. Knepley PetscErrorCode ierr; 9821e5ed2c37SJose E. Roman #endif 9822c0f0dcc3SMatthew G. Knepley 9823c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 9824c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9825c0f0dcc3SMatthew G. Knepley #if defined(PETSC_USE_LOG) 9826c0f0dcc3SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) dm, &name);CHKERRQ(ierr); 9827c0f0dcc3SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 9828c0f0dcc3SMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 9829c0f0dcc3SMatthew G. Knepley ierr = PetscLogGetStageLog(&stageLog);CHKERRQ(ierr); 9830c0f0dcc3SMatthew G. Knepley ierr = PetscStageLogGetCurrent(stageLog, &stage);CHKERRQ(ierr); 9831c0f0dcc3SMatthew G. Knepley ierr = PetscLogEventGetId("DMPlexResidualFE", &event);CHKERRQ(ierr); 9832c0f0dcc3SMatthew G. Knepley ierr = PetscLogEventGetPerfInfo(stage, event, &eventInfo);CHKERRQ(ierr); 9833c0f0dcc3SMatthew G. Knepley N = (cEnd - cStart)*Nf*eventInfo.count; 9834c0f0dcc3SMatthew G. Knepley flopRate = eventInfo.flops/eventInfo.time; 9835c0f0dcc3SMatthew G. Knepley cellRate = N/eventInfo.time; 9836fae64647SBarry Smith ierr = PetscPrintf(PetscObjectComm((PetscObject) dm), "DM (%s) FE Residual Integration: %D integrals %D reps\n Cell rate: %.2g/s flop rate: %.2g MF/s\n", name ? name : "unknown", N, eventInfo.count, (double) cellRate, (double) (flopRate/1.e6));CHKERRQ(ierr); 9837c0f0dcc3SMatthew G. Knepley #else 9838c0f0dcc3SMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Plex Throughput Monitor is not supported if logging is turned off. Reconfigure using --with-log."); 9839c0f0dcc3SMatthew G. Knepley #endif 9840c0f0dcc3SMatthew G. Knepley PetscFunctionReturn(0); 9841c0f0dcc3SMatthew G. Knepley } 9842