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; 1266*ca7bf7eeSMatthew 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; 1284*ca7bf7eeSMatthew G. Knepley if (size < maxSize) {ierr = PetscCalloc3(size, &sizes, size, &hybsizes, size, &ghostsizes);CHKERRQ(ierr);} 1285*ca7bf7eeSMatthew 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 } 1301*ca7bf7eeSMatthew 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 } 1313*ca7bf7eeSMatthew G. Knepley } else { 1314*ca7bf7eeSMatthew G. Knepley PetscInt locMinMax[2]; 1315*ca7bf7eeSMatthew G. Knepley 1316*ca7bf7eeSMatthew G. Knepley locMinMax[0] = Nc[0]+Nc[1]; locMinMax[1] = Nc[0]+Nc[1]; 1317*ca7bf7eeSMatthew G. Knepley ierr = PetscGlobalMinMaxInt(comm, locMinMax, sizes);CHKERRQ(ierr); 1318*ca7bf7eeSMatthew G. Knepley locMinMax[0] = Nc[1]; locMinMax[1] = Nc[1]; 1319*ca7bf7eeSMatthew G. Knepley ierr = PetscGlobalMinMaxInt(comm, locMinMax, hybsizes);CHKERRQ(ierr); 1320*ca7bf7eeSMatthew G. Knepley if (d == depth) { 1321*ca7bf7eeSMatthew G. Knepley locMinMax[0] = gcNum; locMinMax[1] = gcNum; 1322*ca7bf7eeSMatthew G. Knepley ierr = PetscGlobalMinMaxInt(comm, locMinMax, ghostsizes);CHKERRQ(ierr); 1323*ca7bf7eeSMatthew G. Knepley } 1324*ca7bf7eeSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " Min/Max of %D-cells per rank:", (depth == 1) && d ? dim : d);CHKERRQ(ierr); 1325*ca7bf7eeSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " %" PetscInt_FMT "/%" PetscInt_FMT, sizes[0], sizes[1]);CHKERRQ(ierr); 1326*ca7bf7eeSMatthew G. Knepley if (hybsizes[0] > 0) {ierr = PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT "/%" PetscInt_FMT ")", hybsizes[0], hybsizes[1]);CHKERRQ(ierr);} 1327*ca7bf7eeSMatthew G. Knepley if (ghostsizes[0] > 0) {ierr = PetscViewerASCIIPrintf(viewer, " [%" PetscInt_FMT "/%" PetscInt_FMT "]", ghostsizes[0], ghostsizes[1]);CHKERRQ(ierr);} 1328*ca7bf7eeSMatthew 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) { 2434be36d101SStefano Zampini PetscSection subSection; 2435837628f4SStefano Zampini PetscBool fillMatrix = (PetscBool)(!dm->prealloc_only && !isMatIS); 24360be3e97aSMatthew G. Knepley PetscInt *dnz, *onz, *dnzu, *onzu, bsLocal[2], bsMinMax[2], *ltogidx, lsize; 2437fad22124SMatthew G Knepley PetscInt pStart, pEnd, p, dof, cdof; 2438552f7358SJed Brown 243900140cc3SStefano Zampini /* Set localtoglobalmapping on the matrix for MatSetValuesLocal() to work (it also creates the local matrices in case of MATIS) */ 2440be36d101SStefano Zampini if (isMatIS) { /* need a different l2g map than the one computed by DMGetLocalToGlobalMapping */ 2441be36d101SStefano Zampini PetscSection section; 2442be36d101SStefano Zampini PetscInt size; 2443be36d101SStefano Zampini 244492fd8e1eSJed Brown ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr); 2445be36d101SStefano Zampini ierr = PetscSectionGetStorageSize(section, &size);CHKERRQ(ierr); 2446be36d101SStefano Zampini ierr = PetscMalloc1(size,<ogidx);CHKERRQ(ierr); 2447be36d101SStefano Zampini ierr = DMPlexGetSubdomainSection(dm, &subSection);CHKERRQ(ierr); 2448be36d101SStefano Zampini } else { 244900140cc3SStefano Zampini ierr = DMGetLocalToGlobalMapping(dm,<og);CHKERRQ(ierr); 2450be36d101SStefano Zampini } 2451552f7358SJed Brown ierr = PetscSectionGetChart(sectionGlobal, &pStart, &pEnd);CHKERRQ(ierr); 2452be36d101SStefano Zampini for (p = pStart, lsize = 0; p < pEnd; ++p) { 2453a9d99c84SMatthew G. Knepley PetscInt bdof; 2454a9d99c84SMatthew G. Knepley 2455552f7358SJed Brown ierr = PetscSectionGetDof(sectionGlobal, p, &dof);CHKERRQ(ierr); 2456fad22124SMatthew G Knepley ierr = PetscSectionGetConstraintDof(sectionGlobal, p, &cdof);CHKERRQ(ierr); 24571d17a0a3SMatthew G. Knepley dof = dof < 0 ? -(dof+1) : dof; 24581d17a0a3SMatthew G. Knepley bdof = cdof && (dof-cdof) ? 1 : dof; 24591d17a0a3SMatthew G. Knepley if (dof) { 24601d17a0a3SMatthew G. Knepley if (bs < 0) {bs = bdof;} 2461be36d101SStefano Zampini else if (bs != bdof) {bs = 1; if (!isMatIS) break;} 2462be36d101SStefano Zampini } 2463be36d101SStefano Zampini if (isMatIS) { 2464be36d101SStefano Zampini PetscInt loff,c,off; 2465be36d101SStefano Zampini ierr = PetscSectionGetOffset(subSection, p, &loff);CHKERRQ(ierr); 2466be36d101SStefano Zampini ierr = PetscSectionGetOffset(sectionGlobal, p, &off);CHKERRQ(ierr); 2467be36d101SStefano Zampini for (c = 0; c < dof-cdof; ++c, ++lsize) ltogidx[loff+c] = off > -1 ? off+c : -(off+1)+c; 2468552f7358SJed Brown } 24692a28c762SMatthew G Knepley } 24702a28c762SMatthew G Knepley /* Must have same blocksize on all procs (some might have no points) */ 24710be3e97aSMatthew G. Knepley bsLocal[0] = bs < 0 ? PETSC_MAX_INT : bs; bsLocal[1] = bs; 24720be3e97aSMatthew G. Knepley ierr = PetscGlobalMinMaxInt(PetscObjectComm((PetscObject) dm), bsLocal, bsMinMax);CHKERRQ(ierr); 24730be3e97aSMatthew G. Knepley if (bsMinMax[0] != bsMinMax[1]) {bs = 1;} 24740be3e97aSMatthew G. Knepley else {bs = bsMinMax[0];} 24756fd5c86aSStefano Zampini bs = PetscMax(1,bs); 24766fd5c86aSStefano Zampini if (isMatIS) { /* Must reduce indices by blocksize */ 24774fa26246SMatthew G. Knepley PetscInt l; 24786fd5c86aSStefano Zampini 24796fd5c86aSStefano Zampini lsize = lsize/bs; 24806fd5c86aSStefano Zampini if (bs > 1) for (l = 0; l < lsize; ++l) ltogidx[l] = ltogidx[l*bs]/bs; 24814fa26246SMatthew G. Knepley ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)dm), bs, lsize, ltogidx, PETSC_OWN_POINTER, <og);CHKERRQ(ierr); 2482be36d101SStefano Zampini } 2483be36d101SStefano Zampini ierr = MatSetLocalToGlobalMapping(*J,ltog,ltog);CHKERRQ(ierr); 2484be36d101SStefano Zampini if (isMatIS) { 2485be36d101SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(<og);CHKERRQ(ierr); 2486be36d101SStefano Zampini } 24871795a4d1SJed Brown ierr = PetscCalloc4(localSize/bs, &dnz, localSize/bs, &onz, localSize/bs, &dnzu, localSize/bs, &onzu);CHKERRQ(ierr); 24888d1174e4SMatthew G. Knepley ierr = DMPlexPreallocateOperator(dm, bs, dnz, onz, dnzu, onzu, *J, fillMatrix);CHKERRQ(ierr); 2489552f7358SJed Brown ierr = PetscFree4(dnz, onz, dnzu, onzu);CHKERRQ(ierr); 2490552f7358SJed Brown } 2491b1f74addSMatthew G. Knepley ierr = MatSetDM(*J, dm);CHKERRQ(ierr); 2492552f7358SJed Brown PetscFunctionReturn(0); 2493552f7358SJed Brown } 2494552f7358SJed Brown 24957cd05799SMatthew G. Knepley /*@ 2496a8f00d21SMatthew G. Knepley DMPlexGetSubdomainSection - Returns the section associated with the subdomain 2497be36d101SStefano Zampini 2498be36d101SStefano Zampini Not collective 2499be36d101SStefano Zampini 2500be36d101SStefano Zampini Input Parameter: 2501be36d101SStefano Zampini . mesh - The DMPlex 2502be36d101SStefano Zampini 2503be36d101SStefano Zampini Output Parameters: 2504be36d101SStefano Zampini . subsection - The subdomain section 2505be36d101SStefano Zampini 2506be36d101SStefano Zampini Level: developer 2507be36d101SStefano Zampini 2508be36d101SStefano Zampini .seealso: 25097cd05799SMatthew G. Knepley @*/ 2510be36d101SStefano Zampini PetscErrorCode DMPlexGetSubdomainSection(DM dm, PetscSection *subsection) 2511be36d101SStefano Zampini { 2512be36d101SStefano Zampini DM_Plex *mesh = (DM_Plex*) dm->data; 2513be36d101SStefano Zampini PetscErrorCode ierr; 2514be36d101SStefano Zampini 2515be36d101SStefano Zampini PetscFunctionBegin; 2516be36d101SStefano Zampini PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2517be36d101SStefano Zampini if (!mesh->subdomainSection) { 2518be36d101SStefano Zampini PetscSection section; 2519be36d101SStefano Zampini PetscSF sf; 2520be36d101SStefano Zampini 2521be36d101SStefano Zampini ierr = PetscSFCreate(PETSC_COMM_SELF,&sf);CHKERRQ(ierr); 252292fd8e1eSJed Brown ierr = DMGetLocalSection(dm,§ion);CHKERRQ(ierr); 2523be36d101SStefano Zampini ierr = PetscSectionCreateGlobalSection(section,sf,PETSC_FALSE,PETSC_TRUE,&mesh->subdomainSection);CHKERRQ(ierr); 2524be36d101SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 2525be36d101SStefano Zampini } 2526be36d101SStefano Zampini *subsection = mesh->subdomainSection; 2527be36d101SStefano Zampini PetscFunctionReturn(0); 2528be36d101SStefano Zampini } 2529be36d101SStefano Zampini 2530552f7358SJed Brown /*@ 2531552f7358SJed Brown DMPlexGetChart - Return the interval for all mesh points [pStart, pEnd) 2532552f7358SJed Brown 2533552f7358SJed Brown Not collective 2534552f7358SJed Brown 2535552f7358SJed Brown Input Parameter: 2536552f7358SJed Brown . mesh - The DMPlex 2537552f7358SJed Brown 2538552f7358SJed Brown Output Parameters: 2539552f7358SJed Brown + pStart - The first mesh point 2540552f7358SJed Brown - pEnd - The upper bound for mesh points 2541552f7358SJed Brown 2542552f7358SJed Brown Level: beginner 2543552f7358SJed Brown 2544552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetChart() 2545552f7358SJed Brown @*/ 2546552f7358SJed Brown PetscErrorCode DMPlexGetChart(DM dm, PetscInt *pStart, PetscInt *pEnd) 2547552f7358SJed Brown { 2548552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2549552f7358SJed Brown PetscErrorCode ierr; 2550552f7358SJed Brown 2551552f7358SJed Brown PetscFunctionBegin; 2552552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2553552f7358SJed Brown ierr = PetscSectionGetChart(mesh->coneSection, pStart, pEnd);CHKERRQ(ierr); 2554552f7358SJed Brown PetscFunctionReturn(0); 2555552f7358SJed Brown } 2556552f7358SJed Brown 2557552f7358SJed Brown /*@ 2558552f7358SJed Brown DMPlexSetChart - Set the interval for all mesh points [pStart, pEnd) 2559552f7358SJed Brown 2560552f7358SJed Brown Not collective 2561552f7358SJed Brown 2562552f7358SJed Brown Input Parameters: 2563552f7358SJed Brown + mesh - The DMPlex 2564552f7358SJed Brown . pStart - The first mesh point 2565552f7358SJed Brown - pEnd - The upper bound for mesh points 2566552f7358SJed Brown 2567552f7358SJed Brown Output Parameters: 2568552f7358SJed Brown 2569552f7358SJed Brown Level: beginner 2570552f7358SJed Brown 2571552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetChart() 2572552f7358SJed Brown @*/ 2573552f7358SJed Brown PetscErrorCode DMPlexSetChart(DM dm, PetscInt pStart, PetscInt pEnd) 2574552f7358SJed Brown { 2575552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2576552f7358SJed Brown PetscErrorCode ierr; 2577552f7358SJed Brown 2578552f7358SJed Brown PetscFunctionBegin; 2579552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2580552f7358SJed Brown ierr = PetscSectionSetChart(mesh->coneSection, pStart, pEnd);CHKERRQ(ierr); 2581552f7358SJed Brown ierr = PetscSectionSetChart(mesh->supportSection, pStart, pEnd);CHKERRQ(ierr); 2582552f7358SJed Brown PetscFunctionReturn(0); 2583552f7358SJed Brown } 2584552f7358SJed Brown 2585552f7358SJed Brown /*@ 2586eaf898f9SPatrick Sanan DMPlexGetConeSize - Return the number of in-edges for this point in the DAG 2587552f7358SJed Brown 2588552f7358SJed Brown Not collective 2589552f7358SJed Brown 2590552f7358SJed Brown Input Parameters: 2591552f7358SJed Brown + mesh - The DMPlex 2592eaf898f9SPatrick Sanan - p - The point, which must lie in the chart set with DMPlexSetChart() 2593552f7358SJed Brown 2594552f7358SJed Brown Output Parameter: 2595552f7358SJed Brown . size - The cone size for point p 2596552f7358SJed Brown 2597552f7358SJed Brown Level: beginner 2598552f7358SJed Brown 2599552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetConeSize(), DMPlexSetChart() 2600552f7358SJed Brown @*/ 2601552f7358SJed Brown PetscErrorCode DMPlexGetConeSize(DM dm, PetscInt p, PetscInt *size) 2602552f7358SJed Brown { 2603552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2604552f7358SJed Brown PetscErrorCode ierr; 2605552f7358SJed Brown 2606552f7358SJed Brown PetscFunctionBegin; 2607552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2608552f7358SJed Brown PetscValidPointer(size, 3); 2609552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, size);CHKERRQ(ierr); 2610552f7358SJed Brown PetscFunctionReturn(0); 2611552f7358SJed Brown } 2612552f7358SJed Brown 2613552f7358SJed Brown /*@ 2614eaf898f9SPatrick Sanan DMPlexSetConeSize - Set the number of in-edges for this point in the DAG 2615552f7358SJed Brown 2616552f7358SJed Brown Not collective 2617552f7358SJed Brown 2618552f7358SJed Brown Input Parameters: 2619552f7358SJed Brown + mesh - The DMPlex 2620eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 2621552f7358SJed Brown - size - The cone size for point p 2622552f7358SJed Brown 2623552f7358SJed Brown Output Parameter: 2624552f7358SJed Brown 2625552f7358SJed Brown Note: 2626552f7358SJed Brown This should be called after DMPlexSetChart(). 2627552f7358SJed Brown 2628552f7358SJed Brown Level: beginner 2629552f7358SJed Brown 2630552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetConeSize(), DMPlexSetChart() 2631552f7358SJed Brown @*/ 2632552f7358SJed Brown PetscErrorCode DMPlexSetConeSize(DM dm, PetscInt p, PetscInt size) 2633552f7358SJed Brown { 2634552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2635552f7358SJed Brown PetscErrorCode ierr; 2636552f7358SJed Brown 2637552f7358SJed Brown PetscFunctionBegin; 2638552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2639552f7358SJed Brown ierr = PetscSectionSetDof(mesh->coneSection, p, size);CHKERRQ(ierr); 26400d644c17SKarl Rupp 2641552f7358SJed Brown mesh->maxConeSize = PetscMax(mesh->maxConeSize, size); 2642552f7358SJed Brown PetscFunctionReturn(0); 2643552f7358SJed Brown } 2644552f7358SJed Brown 2645f5a469b9SMatthew G. Knepley /*@ 2646eaf898f9SPatrick Sanan DMPlexAddConeSize - Add the given number of in-edges to this point in the DAG 2647f5a469b9SMatthew G. Knepley 2648f5a469b9SMatthew G. Knepley Not collective 2649f5a469b9SMatthew G. Knepley 2650f5a469b9SMatthew G. Knepley Input Parameters: 2651f5a469b9SMatthew G. Knepley + mesh - The DMPlex 2652eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 2653f5a469b9SMatthew G. Knepley - size - The additional cone size for point p 2654f5a469b9SMatthew G. Knepley 2655f5a469b9SMatthew G. Knepley Output Parameter: 2656f5a469b9SMatthew G. Knepley 2657f5a469b9SMatthew G. Knepley Note: 2658f5a469b9SMatthew G. Knepley This should be called after DMPlexSetChart(). 2659f5a469b9SMatthew G. Knepley 2660f5a469b9SMatthew G. Knepley Level: beginner 2661f5a469b9SMatthew G. Knepley 2662f5a469b9SMatthew G. Knepley .seealso: DMPlexCreate(), DMPlexSetConeSize(), DMPlexGetConeSize(), DMPlexSetChart() 2663f5a469b9SMatthew G. Knepley @*/ 2664f5a469b9SMatthew G. Knepley PetscErrorCode DMPlexAddConeSize(DM dm, PetscInt p, PetscInt size) 2665f5a469b9SMatthew G. Knepley { 2666f5a469b9SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 2667f5a469b9SMatthew G. Knepley PetscInt csize; 2668f5a469b9SMatthew G. Knepley PetscErrorCode ierr; 2669f5a469b9SMatthew G. Knepley 2670f5a469b9SMatthew G. Knepley PetscFunctionBegin; 2671f5a469b9SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2672f5a469b9SMatthew G. Knepley ierr = PetscSectionAddDof(mesh->coneSection, p, size);CHKERRQ(ierr); 2673f5a469b9SMatthew G. Knepley ierr = PetscSectionGetDof(mesh->coneSection, p, &csize);CHKERRQ(ierr); 2674f5a469b9SMatthew G. Knepley 2675f5a469b9SMatthew G. Knepley mesh->maxConeSize = PetscMax(mesh->maxConeSize, csize); 2676f5a469b9SMatthew G. Knepley PetscFunctionReturn(0); 2677f5a469b9SMatthew G. Knepley } 2678f5a469b9SMatthew G. Knepley 2679552f7358SJed Brown /*@C 2680eaf898f9SPatrick Sanan DMPlexGetCone - Return the points on the in-edges for this point in the DAG 2681552f7358SJed Brown 2682552f7358SJed Brown Not collective 2683552f7358SJed Brown 2684552f7358SJed Brown Input Parameters: 2685833c876bSVaclav Hapla + dm - The DMPlex 2686eaf898f9SPatrick Sanan - p - The point, which must lie in the chart set with DMPlexSetChart() 2687552f7358SJed Brown 2688552f7358SJed Brown Output Parameter: 2689552f7358SJed Brown . cone - An array of points which are on the in-edges for point p 2690552f7358SJed Brown 2691552f7358SJed Brown Level: beginner 2692552f7358SJed Brown 26933813dfbdSMatthew G Knepley Fortran Notes: 26943813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 26953813dfbdSMatthew G Knepley include petsc.h90 in your code. 2696922102d1SVaclav Hapla You must also call DMPlexRestoreCone() after you finish using the returned array. 2697922102d1SVaclav Hapla DMPlexRestoreCone() is not needed/available in C. 26983813dfbdSMatthew G Knepley 2699e45f02b0SMatthew G. Knepley .seealso: DMPlexGetConeSize(), DMPlexSetCone(), DMPlexGetConeTuple(), DMPlexSetChart() 2700552f7358SJed Brown @*/ 2701552f7358SJed Brown PetscErrorCode DMPlexGetCone(DM dm, PetscInt p, const PetscInt *cone[]) 2702552f7358SJed Brown { 2703552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2704552f7358SJed Brown PetscInt off; 2705552f7358SJed Brown PetscErrorCode ierr; 2706552f7358SJed Brown 2707552f7358SJed Brown PetscFunctionBegin; 2708552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2709552f7358SJed Brown PetscValidPointer(cone, 3); 2710552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 2711552f7358SJed Brown *cone = &mesh->cones[off]; 2712552f7358SJed Brown PetscFunctionReturn(0); 2713552f7358SJed Brown } 2714552f7358SJed Brown 27150ce7577fSVaclav Hapla /*@C 27160ce7577fSVaclav Hapla DMPlexGetConeTuple - Return the points on the in-edges of several points in the DAG 27170ce7577fSVaclav Hapla 27180ce7577fSVaclav Hapla Not collective 27190ce7577fSVaclav Hapla 27200ce7577fSVaclav Hapla Input Parameters: 27210ce7577fSVaclav Hapla + dm - The DMPlex 27220ce7577fSVaclav Hapla - p - The IS of points, which must lie in the chart set with DMPlexSetChart() 27230ce7577fSVaclav Hapla 2724d8d19677SJose E. Roman Output Parameters: 27250ce7577fSVaclav Hapla + pConesSection - PetscSection describing the layout of pCones 27260ce7577fSVaclav Hapla - pCones - An array of points which are on the in-edges for the point set p 27270ce7577fSVaclav Hapla 27280ce7577fSVaclav Hapla Level: intermediate 27290ce7577fSVaclav Hapla 2730d4636a37SVaclav Hapla .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexGetConeRecursive(), DMPlexSetChart() 27310ce7577fSVaclav Hapla @*/ 27320ce7577fSVaclav Hapla PetscErrorCode DMPlexGetConeTuple(DM dm, IS p, PetscSection *pConesSection, IS *pCones) 27330ce7577fSVaclav Hapla { 27340ce7577fSVaclav Hapla PetscSection cs, newcs; 27350ce7577fSVaclav Hapla PetscInt *cones; 27360ce7577fSVaclav Hapla PetscInt *newarr=NULL; 27370ce7577fSVaclav Hapla PetscInt n; 27380ce7577fSVaclav Hapla PetscErrorCode ierr; 27390ce7577fSVaclav Hapla 27400ce7577fSVaclav Hapla PetscFunctionBegin; 27410ce7577fSVaclav Hapla ierr = DMPlexGetCones(dm, &cones);CHKERRQ(ierr); 27420ce7577fSVaclav Hapla ierr = DMPlexGetConeSection(dm, &cs);CHKERRQ(ierr); 27430ce7577fSVaclav Hapla ierr = PetscSectionExtractDofsFromArray(cs, MPIU_INT, cones, p, &newcs, pCones ? ((void**)&newarr) : NULL);CHKERRQ(ierr); 27440ce7577fSVaclav Hapla if (pConesSection) *pConesSection = newcs; 27450ce7577fSVaclav Hapla if (pCones) { 27460ce7577fSVaclav Hapla ierr = PetscSectionGetStorageSize(newcs, &n);CHKERRQ(ierr); 27470ce7577fSVaclav Hapla ierr = ISCreateGeneral(PetscObjectComm((PetscObject)p), n, newarr, PETSC_OWN_POINTER, pCones);CHKERRQ(ierr); 27480ce7577fSVaclav Hapla } 27490ce7577fSVaclav Hapla PetscFunctionReturn(0); 27500ce7577fSVaclav Hapla } 27510ce7577fSVaclav Hapla 2752af9eab45SVaclav Hapla /*@ 2753af9eab45SVaclav Hapla DMPlexGetConeRecursiveVertices - Expand each given point into its cone points and do that recursively until we end up just with vertices. 2754d4636a37SVaclav Hapla 2755d4636a37SVaclav Hapla Not collective 2756d4636a37SVaclav Hapla 2757d4636a37SVaclav Hapla Input Parameters: 2758d4636a37SVaclav Hapla + dm - The DMPlex 2759af9eab45SVaclav Hapla - points - The IS of points, which must lie in the chart set with DMPlexSetChart() 2760d4636a37SVaclav Hapla 2761d4636a37SVaclav Hapla Output Parameter: 2762af9eab45SVaclav Hapla . expandedPoints - An array of vertices recursively expanded from input points 2763d4636a37SVaclav Hapla 2764d4636a37SVaclav Hapla Level: advanced 2765d4636a37SVaclav Hapla 2766af9eab45SVaclav Hapla Notes: 2767af9eab45SVaclav Hapla Like DMPlexGetConeRecursive but returns only the 0-depth IS (i.e. vertices only) and no sections. 2768af9eab45SVaclav Hapla There is no corresponding Restore function, just call ISDestroy() on the returned IS to deallocate. 2769af9eab45SVaclav Hapla 2770af9eab45SVaclav Hapla .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexGetConeTuple(), DMPlexGetConeRecursive(), DMPlexRestoreConeRecursive(), DMPlexGetDepth() 2771d4636a37SVaclav Hapla @*/ 2772af9eab45SVaclav Hapla PetscErrorCode DMPlexGetConeRecursiveVertices(DM dm, IS points, IS *expandedPoints) 2773d4636a37SVaclav Hapla { 2774af9eab45SVaclav Hapla IS *expandedPointsAll; 2775af9eab45SVaclav Hapla PetscInt depth; 2776d4636a37SVaclav Hapla PetscErrorCode ierr; 2777d4636a37SVaclav Hapla 2778d4636a37SVaclav Hapla PetscFunctionBegin; 2779af9eab45SVaclav Hapla PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2780af9eab45SVaclav Hapla PetscValidHeaderSpecific(points, IS_CLASSID, 2); 2781af9eab45SVaclav Hapla PetscValidPointer(expandedPoints, 3); 2782af9eab45SVaclav Hapla ierr = DMPlexGetConeRecursive(dm, points, &depth, &expandedPointsAll, NULL);CHKERRQ(ierr); 2783af9eab45SVaclav Hapla *expandedPoints = expandedPointsAll[0]; 27841e1ea65dSPierre Jolivet ierr = PetscObjectReference((PetscObject)expandedPointsAll[0]);CHKERRQ(ierr); 2785af9eab45SVaclav Hapla ierr = DMPlexRestoreConeRecursive(dm, points, &depth, &expandedPointsAll, NULL);CHKERRQ(ierr); 2786af9eab45SVaclav Hapla PetscFunctionReturn(0); 2787af9eab45SVaclav Hapla } 2788af9eab45SVaclav Hapla 2789af9eab45SVaclav Hapla /*@ 2790af9eab45SVaclav 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). 2791af9eab45SVaclav Hapla 2792af9eab45SVaclav Hapla Not collective 2793af9eab45SVaclav Hapla 2794af9eab45SVaclav Hapla Input Parameters: 2795af9eab45SVaclav Hapla + dm - The DMPlex 2796af9eab45SVaclav Hapla - points - The IS of points, which must lie in the chart set with DMPlexSetChart() 2797af9eab45SVaclav Hapla 2798d8d19677SJose E. Roman Output Parameters: 2799af9eab45SVaclav Hapla + depth - (optional) Size of the output arrays, equal to DMPlex depth, returned by DMPlexGetDepth() 2800af9eab45SVaclav Hapla . expandedPoints - (optional) An array of index sets with recursively expanded cones 2801af9eab45SVaclav Hapla - sections - (optional) An array of sections which describe mappings from points to their cone points 2802af9eab45SVaclav Hapla 2803af9eab45SVaclav Hapla Level: advanced 2804af9eab45SVaclav Hapla 2805af9eab45SVaclav Hapla Notes: 2806af9eab45SVaclav Hapla Like DMPlexGetConeTuple() but recursive. 2807af9eab45SVaclav Hapla 2808af9eab45SVaclav 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. 2809af9eab45SVaclav Hapla For example, for d=0 it contains only vertices, for d=1 it can contain vertices and edges, etc. 2810af9eab45SVaclav Hapla 2811af9eab45SVaclav 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: 2812af9eab45SVaclav Hapla (1) DAG points in expandedPoints[d+1] with depth d+1 to their cone points in expandedPoints[d]; 2813af9eab45SVaclav Hapla (2) DAG points in expandedPoints[d+1] with depth in [0,d] to the same points in expandedPoints[d]. 2814af9eab45SVaclav Hapla 2815af9eab45SVaclav Hapla .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexGetConeTuple(), DMPlexRestoreConeRecursive(), DMPlexGetConeRecursiveVertices(), DMPlexGetDepth() 2816af9eab45SVaclav Hapla @*/ 2817af9eab45SVaclav Hapla PetscErrorCode DMPlexGetConeRecursive(DM dm, IS points, PetscInt *depth, IS *expandedPoints[], PetscSection *sections[]) 2818af9eab45SVaclav Hapla { 2819af9eab45SVaclav Hapla const PetscInt *arr0=NULL, *cone=NULL; 2820af9eab45SVaclav Hapla PetscInt *arr=NULL, *newarr=NULL; 2821af9eab45SVaclav Hapla PetscInt d, depth_, i, n, newn, cn, co, start, end; 2822af9eab45SVaclav Hapla IS *expandedPoints_; 2823af9eab45SVaclav Hapla PetscSection *sections_; 2824af9eab45SVaclav Hapla PetscErrorCode ierr; 2825af9eab45SVaclav Hapla 2826af9eab45SVaclav Hapla PetscFunctionBegin; 2827af9eab45SVaclav Hapla PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2828af9eab45SVaclav Hapla PetscValidHeaderSpecific(points, IS_CLASSID, 2); 2829af9eab45SVaclav Hapla if (depth) PetscValidIntPointer(depth, 3); 2830af9eab45SVaclav Hapla if (expandedPoints) PetscValidPointer(expandedPoints, 4); 2831af9eab45SVaclav Hapla if (sections) PetscValidPointer(sections, 5); 2832af9eab45SVaclav Hapla ierr = ISGetLocalSize(points, &n);CHKERRQ(ierr); 2833af9eab45SVaclav Hapla ierr = ISGetIndices(points, &arr0);CHKERRQ(ierr); 2834af9eab45SVaclav Hapla ierr = DMPlexGetDepth(dm, &depth_);CHKERRQ(ierr); 2835af9eab45SVaclav Hapla ierr = PetscCalloc1(depth_, &expandedPoints_);CHKERRQ(ierr); 2836af9eab45SVaclav Hapla ierr = PetscCalloc1(depth_, §ions_);CHKERRQ(ierr); 2837af9eab45SVaclav Hapla arr = (PetscInt*) arr0; /* this is ok because first generation of arr is not modified */ 2838af9eab45SVaclav Hapla for (d=depth_-1; d>=0; d--) { 2839af9eab45SVaclav Hapla ierr = PetscSectionCreate(PETSC_COMM_SELF, §ions_[d]);CHKERRQ(ierr); 2840af9eab45SVaclav Hapla ierr = PetscSectionSetChart(sections_[d], 0, n);CHKERRQ(ierr); 2841af9eab45SVaclav Hapla for (i=0; i<n; i++) { 2842af9eab45SVaclav Hapla ierr = DMPlexGetDepthStratum(dm, d+1, &start, &end);CHKERRQ(ierr); 2843af9eab45SVaclav Hapla if (arr[i] >= start && arr[i] < end) { 2844af9eab45SVaclav Hapla ierr = DMPlexGetConeSize(dm, arr[i], &cn);CHKERRQ(ierr); 2845af9eab45SVaclav Hapla ierr = PetscSectionSetDof(sections_[d], i, cn);CHKERRQ(ierr); 2846af9eab45SVaclav Hapla } else { 2847af9eab45SVaclav Hapla ierr = PetscSectionSetDof(sections_[d], i, 1);CHKERRQ(ierr); 2848af9eab45SVaclav Hapla } 2849af9eab45SVaclav Hapla } 2850af9eab45SVaclav Hapla ierr = PetscSectionSetUp(sections_[d]);CHKERRQ(ierr); 2851af9eab45SVaclav Hapla ierr = PetscSectionGetStorageSize(sections_[d], &newn);CHKERRQ(ierr); 2852af9eab45SVaclav Hapla ierr = PetscMalloc1(newn, &newarr);CHKERRQ(ierr); 2853af9eab45SVaclav Hapla for (i=0; i<n; i++) { 2854af9eab45SVaclav Hapla ierr = PetscSectionGetDof(sections_[d], i, &cn);CHKERRQ(ierr); 2855af9eab45SVaclav Hapla ierr = PetscSectionGetOffset(sections_[d], i, &co);CHKERRQ(ierr); 2856af9eab45SVaclav Hapla if (cn > 1) { 2857af9eab45SVaclav Hapla ierr = DMPlexGetCone(dm, arr[i], &cone);CHKERRQ(ierr); 2858af9eab45SVaclav Hapla ierr = PetscMemcpy(&newarr[co], cone, cn*sizeof(PetscInt));CHKERRQ(ierr); 2859af9eab45SVaclav Hapla } else { 2860af9eab45SVaclav Hapla newarr[co] = arr[i]; 2861af9eab45SVaclav Hapla } 2862af9eab45SVaclav Hapla } 2863af9eab45SVaclav Hapla ierr = ISCreateGeneral(PETSC_COMM_SELF, newn, newarr, PETSC_OWN_POINTER, &expandedPoints_[d]);CHKERRQ(ierr); 2864af9eab45SVaclav Hapla arr = newarr; 2865af9eab45SVaclav Hapla n = newn; 2866af9eab45SVaclav Hapla } 2867ba2698f1SMatthew G. Knepley ierr = ISRestoreIndices(points, &arr0);CHKERRQ(ierr); 2868af9eab45SVaclav Hapla *depth = depth_; 2869af9eab45SVaclav Hapla if (expandedPoints) *expandedPoints = expandedPoints_; 2870af9eab45SVaclav Hapla else { 2871af9eab45SVaclav Hapla for (d=0; d<depth_; d++) {ierr = ISDestroy(&expandedPoints_[d]);CHKERRQ(ierr);} 2872af9eab45SVaclav Hapla ierr = PetscFree(expandedPoints_);CHKERRQ(ierr); 2873af9eab45SVaclav Hapla } 2874af9eab45SVaclav Hapla if (sections) *sections = sections_; 2875af9eab45SVaclav Hapla else { 2876af9eab45SVaclav Hapla for (d=0; d<depth_; d++) {ierr = PetscSectionDestroy(§ions_[d]);CHKERRQ(ierr);} 2877af9eab45SVaclav Hapla ierr = PetscFree(sections_);CHKERRQ(ierr); 2878af9eab45SVaclav Hapla } 2879af9eab45SVaclav Hapla PetscFunctionReturn(0); 2880af9eab45SVaclav Hapla } 2881af9eab45SVaclav Hapla 2882af9eab45SVaclav Hapla /*@ 2883af9eab45SVaclav Hapla DMPlexRestoreConeRecursive - Deallocates arrays created by DMPlexGetConeRecursive 2884af9eab45SVaclav Hapla 2885af9eab45SVaclav Hapla Not collective 2886af9eab45SVaclav Hapla 2887af9eab45SVaclav Hapla Input Parameters: 2888af9eab45SVaclav Hapla + dm - The DMPlex 2889af9eab45SVaclav Hapla - points - The IS of points, which must lie in the chart set with DMPlexSetChart() 2890af9eab45SVaclav Hapla 2891d8d19677SJose E. Roman Output Parameters: 2892af9eab45SVaclav Hapla + depth - (optional) Size of the output arrays, equal to DMPlex depth, returned by DMPlexGetDepth() 2893af9eab45SVaclav Hapla . expandedPoints - (optional) An array of recursively expanded cones 2894af9eab45SVaclav Hapla - sections - (optional) An array of sections which describe mappings from points to their cone points 2895af9eab45SVaclav Hapla 2896af9eab45SVaclav Hapla Level: advanced 2897af9eab45SVaclav Hapla 2898af9eab45SVaclav Hapla Notes: 2899af9eab45SVaclav Hapla See DMPlexGetConeRecursive() for details. 2900af9eab45SVaclav Hapla 2901af9eab45SVaclav Hapla .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexGetConeTuple(), DMPlexGetConeRecursive(), DMPlexGetConeRecursiveVertices(), DMPlexGetDepth() 2902af9eab45SVaclav Hapla @*/ 2903af9eab45SVaclav Hapla PetscErrorCode DMPlexRestoreConeRecursive(DM dm, IS points, PetscInt *depth, IS *expandedPoints[], PetscSection *sections[]) 2904af9eab45SVaclav Hapla { 2905af9eab45SVaclav Hapla PetscInt d, depth_; 2906af9eab45SVaclav Hapla PetscErrorCode ierr; 2907af9eab45SVaclav Hapla 2908af9eab45SVaclav Hapla PetscFunctionBegin; 2909af9eab45SVaclav Hapla ierr = DMPlexGetDepth(dm, &depth_);CHKERRQ(ierr); 29102c71b3e2SJacob Faibussowitsch PetscCheckFalse(depth && *depth != depth_,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "depth changed since last call to DMPlexGetConeRecursive"); 2911af9eab45SVaclav Hapla if (depth) *depth = 0; 2912af9eab45SVaclav Hapla if (expandedPoints) { 2913af9eab45SVaclav Hapla for (d=0; d<depth_; d++) {ierr = ISDestroy(&((*expandedPoints)[d]));CHKERRQ(ierr);} 2914af9eab45SVaclav Hapla ierr = PetscFree(*expandedPoints);CHKERRQ(ierr); 2915af9eab45SVaclav Hapla } 2916af9eab45SVaclav Hapla if (sections) { 2917af9eab45SVaclav Hapla for (d=0; d<depth_; d++) {ierr = PetscSectionDestroy(&((*sections)[d]));CHKERRQ(ierr);} 2918af9eab45SVaclav Hapla ierr = PetscFree(*sections);CHKERRQ(ierr); 2919af9eab45SVaclav Hapla } 2920d4636a37SVaclav Hapla PetscFunctionReturn(0); 2921d4636a37SVaclav Hapla } 2922d4636a37SVaclav Hapla 2923552f7358SJed Brown /*@ 292492371b87SBarry 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 2925552f7358SJed Brown 2926552f7358SJed Brown Not collective 2927552f7358SJed Brown 2928552f7358SJed Brown Input Parameters: 2929552f7358SJed Brown + mesh - The DMPlex 2930eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 2931552f7358SJed Brown - cone - An array of points which are on the in-edges for point p 2932552f7358SJed Brown 2933552f7358SJed Brown Output Parameter: 2934552f7358SJed Brown 2935552f7358SJed Brown Note: 2936552f7358SJed Brown This should be called after all calls to DMPlexSetConeSize() and DMSetUp(). 2937552f7358SJed Brown 2938552f7358SJed Brown Level: beginner 2939552f7358SJed Brown 294092371b87SBarry Smith .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexSetChart(), DMPlexSetConeSize(), DMSetUp(), DMPlexSetSupport(), DMPlexSetSupportSize() 2941552f7358SJed Brown @*/ 2942552f7358SJed Brown PetscErrorCode DMPlexSetCone(DM dm, PetscInt p, const PetscInt cone[]) 2943552f7358SJed Brown { 2944552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2945552f7358SJed Brown PetscInt pStart, pEnd; 2946552f7358SJed Brown PetscInt dof, off, c; 2947552f7358SJed Brown PetscErrorCode ierr; 2948552f7358SJed Brown 2949552f7358SJed Brown PetscFunctionBegin; 2950552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2951552f7358SJed Brown ierr = PetscSectionGetChart(mesh->coneSection, &pStart, &pEnd);CHKERRQ(ierr); 2952552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 2953552f7358SJed Brown if (dof) PetscValidPointer(cone, 3); 2954552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 29552c71b3e2SJacob 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); 2956552f7358SJed Brown for (c = 0; c < dof; ++c) { 29572c71b3e2SJacob 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); 2958552f7358SJed Brown mesh->cones[off+c] = cone[c]; 2959552f7358SJed Brown } 2960552f7358SJed Brown PetscFunctionReturn(0); 2961552f7358SJed Brown } 2962552f7358SJed Brown 2963552f7358SJed Brown /*@C 2964eaf898f9SPatrick Sanan DMPlexGetConeOrientation - Return the orientations on the in-edges for this point in the DAG 2965552f7358SJed Brown 2966552f7358SJed Brown Not collective 2967552f7358SJed Brown 2968552f7358SJed Brown Input Parameters: 2969552f7358SJed Brown + mesh - The DMPlex 2970eaf898f9SPatrick Sanan - p - The point, which must lie in the chart set with DMPlexSetChart() 2971552f7358SJed Brown 2972552f7358SJed Brown Output Parameter: 2973552f7358SJed Brown . coneOrientation - An array of orientations which are on the in-edges for point p. An orientation is an 2974b5a892a1SMatthew G. Knepley integer giving the prescription for cone traversal. 2975552f7358SJed Brown 2976552f7358SJed Brown Level: beginner 2977552f7358SJed Brown 2978b5a892a1SMatthew G. Knepley Notes: 2979b5a892a1SMatthew G. Knepley The number indexes the symmetry transformations for the cell type (see manual). Orientation 0 is always 2980b5a892a1SMatthew G. Knepley the identity transformation. Negative orientation indicates reflection so that -(o+1) is the reflection 2981b5a892a1SMatthew G. Knepley of o, however it is not necessarily the inverse. To get the inverse, use DMPolytopeTypeComposeOrientationInv() 2982b5a892a1SMatthew G. Knepley with the identity. 2983b5a892a1SMatthew G. Knepley 29843813dfbdSMatthew G Knepley Fortran Notes: 29853813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 29863813dfbdSMatthew G Knepley include petsc.h90 in your code. 29873b12b3d8SVaclav Hapla You must also call DMPlexRestoreConeOrientation() after you finish using the returned array. 2988922102d1SVaclav Hapla DMPlexRestoreConeOrientation() is not needed/available in C. 29893813dfbdSMatthew G Knepley 2990b5a892a1SMatthew G. Knepley .seealso: DMPolytopeTypeComposeOrientation(), DMPolytopeTypeComposeOrientationInv(), DMPlexCreate(), DMPlexGetCone(), DMPlexSetCone(), DMPlexSetChart() 2991552f7358SJed Brown @*/ 2992552f7358SJed Brown PetscErrorCode DMPlexGetConeOrientation(DM dm, PetscInt p, const PetscInt *coneOrientation[]) 2993552f7358SJed Brown { 2994552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2995552f7358SJed Brown PetscInt off; 2996552f7358SJed Brown PetscErrorCode ierr; 2997552f7358SJed Brown 2998552f7358SJed Brown PetscFunctionBegin; 2999552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 300076bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 3001552f7358SJed Brown PetscInt dof; 3002552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 3003552f7358SJed Brown if (dof) PetscValidPointer(coneOrientation, 3); 3004552f7358SJed Brown } 3005552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 30060d644c17SKarl Rupp 3007552f7358SJed Brown *coneOrientation = &mesh->coneOrientations[off]; 3008552f7358SJed Brown PetscFunctionReturn(0); 3009552f7358SJed Brown } 3010552f7358SJed Brown 3011552f7358SJed Brown /*@ 3012eaf898f9SPatrick Sanan DMPlexSetConeOrientation - Set the orientations on the in-edges for this point in the DAG 3013552f7358SJed Brown 3014552f7358SJed Brown Not collective 3015552f7358SJed Brown 3016552f7358SJed Brown Input Parameters: 3017552f7358SJed Brown + mesh - The DMPlex 3018eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 3019b5a892a1SMatthew G. Knepley - coneOrientation - An array of orientations 3020552f7358SJed Brown Output Parameter: 3021552f7358SJed Brown 3022b5a892a1SMatthew G. Knepley Notes: 3023552f7358SJed Brown This should be called after all calls to DMPlexSetConeSize() and DMSetUp(). 3024552f7358SJed Brown 3025b5a892a1SMatthew G. Knepley The meaning of coneOrientation is detailed in DMPlexGetConeOrientation(). 3026b5a892a1SMatthew G. Knepley 3027552f7358SJed Brown Level: beginner 3028552f7358SJed Brown 3029552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetConeOrientation(), DMPlexSetCone(), DMPlexSetChart(), DMPlexSetConeSize(), DMSetUp() 3030552f7358SJed Brown @*/ 3031552f7358SJed Brown PetscErrorCode DMPlexSetConeOrientation(DM dm, PetscInt p, const PetscInt coneOrientation[]) 3032552f7358SJed Brown { 3033552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3034552f7358SJed Brown PetscInt pStart, pEnd; 3035552f7358SJed Brown PetscInt dof, off, c; 3036552f7358SJed Brown PetscErrorCode ierr; 3037552f7358SJed Brown 3038552f7358SJed Brown PetscFunctionBegin; 3039552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3040552f7358SJed Brown ierr = PetscSectionGetChart(mesh->coneSection, &pStart, &pEnd);CHKERRQ(ierr); 3041552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 3042552f7358SJed Brown if (dof) PetscValidPointer(coneOrientation, 3); 3043552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 30442c71b3e2SJacob 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); 3045552f7358SJed Brown for (c = 0; c < dof; ++c) { 3046552f7358SJed Brown PetscInt cdof, o = coneOrientation[c]; 3047552f7358SJed Brown 3048552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, mesh->cones[off+c], &cdof);CHKERRQ(ierr); 30492c71b3e2SJacob 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); 3050552f7358SJed Brown mesh->coneOrientations[off+c] = o; 3051552f7358SJed Brown } 3052552f7358SJed Brown PetscFunctionReturn(0); 3053552f7358SJed Brown } 3054552f7358SJed Brown 30557cd05799SMatthew G. Knepley /*@ 3056eaf898f9SPatrick Sanan DMPlexInsertCone - Insert a point into the in-edges for the point p in the DAG 30577cd05799SMatthew G. Knepley 30587cd05799SMatthew G. Knepley Not collective 30597cd05799SMatthew G. Knepley 30607cd05799SMatthew G. Knepley Input Parameters: 30617cd05799SMatthew G. Knepley + mesh - The DMPlex 3062eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 30637cd05799SMatthew G. Knepley . conePos - The local index in the cone where the point should be put 30647cd05799SMatthew G. Knepley - conePoint - The mesh point to insert 30657cd05799SMatthew G. Knepley 30667cd05799SMatthew G. Knepley Level: beginner 30677cd05799SMatthew G. Knepley 30687cd05799SMatthew G. Knepley .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexSetChart(), DMPlexSetConeSize(), DMSetUp() 30697cd05799SMatthew G. Knepley @*/ 3070552f7358SJed Brown PetscErrorCode DMPlexInsertCone(DM dm, PetscInt p, PetscInt conePos, PetscInt conePoint) 3071552f7358SJed Brown { 3072552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3073552f7358SJed Brown PetscInt pStart, pEnd; 3074552f7358SJed Brown PetscInt dof, off; 3075552f7358SJed Brown PetscErrorCode ierr; 3076552f7358SJed Brown 3077552f7358SJed Brown PetscFunctionBegin; 3078552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3079552f7358SJed Brown ierr = PetscSectionGetChart(mesh->coneSection, &pStart, &pEnd);CHKERRQ(ierr); 30802c71b3e2SJacob 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); 30812c71b3e2SJacob 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); 308277c88f5bSMatthew G Knepley ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 308377c88f5bSMatthew G Knepley ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 30842c71b3e2SJacob 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); 3085552f7358SJed Brown mesh->cones[off+conePos] = conePoint; 3086552f7358SJed Brown PetscFunctionReturn(0); 3087552f7358SJed Brown } 3088552f7358SJed Brown 30897cd05799SMatthew G. Knepley /*@ 3090eaf898f9SPatrick Sanan DMPlexInsertConeOrientation - Insert a point orientation for the in-edge for the point p in the DAG 30917cd05799SMatthew G. Knepley 30927cd05799SMatthew G. Knepley Not collective 30937cd05799SMatthew G. Knepley 30947cd05799SMatthew G. Knepley Input Parameters: 30957cd05799SMatthew G. Knepley + mesh - The DMPlex 3096eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 30977cd05799SMatthew G. Knepley . conePos - The local index in the cone where the point should be put 30987cd05799SMatthew G. Knepley - coneOrientation - The point orientation to insert 30997cd05799SMatthew G. Knepley 31007cd05799SMatthew G. Knepley Level: beginner 31017cd05799SMatthew G. Knepley 3102b5a892a1SMatthew G. Knepley Notes: 3103b5a892a1SMatthew G. Knepley The meaning of coneOrientation values is detailed in DMPlexGetConeOrientation(). 3104b5a892a1SMatthew G. Knepley 31057cd05799SMatthew G. Knepley .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexSetChart(), DMPlexSetConeSize(), DMSetUp() 31067cd05799SMatthew G. Knepley @*/ 310777c88f5bSMatthew G Knepley PetscErrorCode DMPlexInsertConeOrientation(DM dm, PetscInt p, PetscInt conePos, PetscInt coneOrientation) 310877c88f5bSMatthew G Knepley { 310977c88f5bSMatthew G Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 311077c88f5bSMatthew G Knepley PetscInt pStart, pEnd; 311177c88f5bSMatthew G Knepley PetscInt dof, off; 311277c88f5bSMatthew G Knepley PetscErrorCode ierr; 311377c88f5bSMatthew G Knepley 311477c88f5bSMatthew G Knepley PetscFunctionBegin; 311577c88f5bSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 311677c88f5bSMatthew G Knepley ierr = PetscSectionGetChart(mesh->coneSection, &pStart, &pEnd);CHKERRQ(ierr); 31172c71b3e2SJacob 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); 311877c88f5bSMatthew G Knepley ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 311977c88f5bSMatthew G Knepley ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 31202c71b3e2SJacob 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); 312177c88f5bSMatthew G Knepley mesh->coneOrientations[off+conePos] = coneOrientation; 312277c88f5bSMatthew G Knepley PetscFunctionReturn(0); 312377c88f5bSMatthew G Knepley } 312477c88f5bSMatthew G Knepley 3125552f7358SJed Brown /*@ 3126eaf898f9SPatrick Sanan DMPlexGetSupportSize - Return the number of out-edges for this point in the DAG 3127552f7358SJed Brown 3128552f7358SJed Brown Not collective 3129552f7358SJed Brown 3130552f7358SJed Brown Input Parameters: 3131552f7358SJed Brown + mesh - The DMPlex 3132eaf898f9SPatrick Sanan - p - The point, which must lie in the chart set with DMPlexSetChart() 3133552f7358SJed Brown 3134552f7358SJed Brown Output Parameter: 3135552f7358SJed Brown . size - The support size for point p 3136552f7358SJed Brown 3137552f7358SJed Brown Level: beginner 3138552f7358SJed Brown 3139552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetConeSize(), DMPlexSetChart(), DMPlexGetConeSize() 3140552f7358SJed Brown @*/ 3141552f7358SJed Brown PetscErrorCode DMPlexGetSupportSize(DM dm, PetscInt p, PetscInt *size) 3142552f7358SJed Brown { 3143552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3144552f7358SJed Brown PetscErrorCode ierr; 3145552f7358SJed Brown 3146552f7358SJed Brown PetscFunctionBegin; 3147552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3148552f7358SJed Brown PetscValidPointer(size, 3); 3149552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, size);CHKERRQ(ierr); 3150552f7358SJed Brown PetscFunctionReturn(0); 3151552f7358SJed Brown } 3152552f7358SJed Brown 3153552f7358SJed Brown /*@ 3154eaf898f9SPatrick Sanan DMPlexSetSupportSize - Set the number of out-edges for this point in the DAG 3155552f7358SJed Brown 3156552f7358SJed Brown Not collective 3157552f7358SJed Brown 3158552f7358SJed Brown Input Parameters: 3159552f7358SJed Brown + mesh - The DMPlex 3160eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 3161552f7358SJed Brown - size - The support size for point p 3162552f7358SJed Brown 3163552f7358SJed Brown Output Parameter: 3164552f7358SJed Brown 3165552f7358SJed Brown Note: 3166552f7358SJed Brown This should be called after DMPlexSetChart(). 3167552f7358SJed Brown 3168552f7358SJed Brown Level: beginner 3169552f7358SJed Brown 3170552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetSupportSize(), DMPlexSetChart() 3171552f7358SJed Brown @*/ 3172552f7358SJed Brown PetscErrorCode DMPlexSetSupportSize(DM dm, PetscInt p, PetscInt size) 3173552f7358SJed Brown { 3174552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3175552f7358SJed Brown PetscErrorCode ierr; 3176552f7358SJed Brown 3177552f7358SJed Brown PetscFunctionBegin; 3178552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3179552f7358SJed Brown ierr = PetscSectionSetDof(mesh->supportSection, p, size);CHKERRQ(ierr); 31800d644c17SKarl Rupp 3181552f7358SJed Brown mesh->maxSupportSize = PetscMax(mesh->maxSupportSize, size); 3182552f7358SJed Brown PetscFunctionReturn(0); 3183552f7358SJed Brown } 3184552f7358SJed Brown 3185552f7358SJed Brown /*@C 3186eaf898f9SPatrick Sanan DMPlexGetSupport - Return the points on the out-edges for this point in the DAG 3187552f7358SJed Brown 3188552f7358SJed Brown Not collective 3189552f7358SJed Brown 3190552f7358SJed Brown Input Parameters: 3191552f7358SJed Brown + mesh - The DMPlex 3192eaf898f9SPatrick Sanan - p - The point, which must lie in the chart set with DMPlexSetChart() 3193552f7358SJed Brown 3194552f7358SJed Brown Output Parameter: 3195552f7358SJed Brown . support - An array of points which are on the out-edges for point p 3196552f7358SJed Brown 3197552f7358SJed Brown Level: beginner 3198552f7358SJed Brown 31993813dfbdSMatthew G Knepley Fortran Notes: 32003813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 32013813dfbdSMatthew G Knepley include petsc.h90 in your code. 32023b12b3d8SVaclav Hapla You must also call DMPlexRestoreSupport() after you finish using the returned array. 3203922102d1SVaclav Hapla DMPlexRestoreSupport() is not needed/available in C. 32043813dfbdSMatthew G Knepley 3205e45f02b0SMatthew G. Knepley .seealso: DMPlexGetSupportSize(), DMPlexSetSupport(), DMPlexGetCone(), DMPlexSetChart() 3206552f7358SJed Brown @*/ 3207552f7358SJed Brown PetscErrorCode DMPlexGetSupport(DM dm, PetscInt p, const PetscInt *support[]) 3208552f7358SJed Brown { 3209552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3210552f7358SJed Brown PetscInt off; 3211552f7358SJed Brown PetscErrorCode ierr; 3212552f7358SJed Brown 3213552f7358SJed Brown PetscFunctionBegin; 3214552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3215552f7358SJed Brown PetscValidPointer(support, 3); 3216552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, p, &off);CHKERRQ(ierr); 3217552f7358SJed Brown *support = &mesh->supports[off]; 3218552f7358SJed Brown PetscFunctionReturn(0); 3219552f7358SJed Brown } 3220552f7358SJed Brown 3221552f7358SJed Brown /*@ 322292371b87SBarry 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 3223552f7358SJed Brown 3224552f7358SJed Brown Not collective 3225552f7358SJed Brown 3226552f7358SJed Brown Input Parameters: 3227552f7358SJed Brown + mesh - The DMPlex 3228eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 322992371b87SBarry Smith - support - An array of points which are on the out-edges for point p 3230552f7358SJed Brown 3231552f7358SJed Brown Output Parameter: 3232552f7358SJed Brown 3233552f7358SJed Brown Note: 3234552f7358SJed Brown This should be called after all calls to DMPlexSetSupportSize() and DMSetUp(). 3235552f7358SJed Brown 3236552f7358SJed Brown Level: beginner 3237552f7358SJed Brown 323892371b87SBarry Smith .seealso: DMPlexSetCone(), DMPlexSetConeSize(), DMPlexCreate(), DMPlexGetSupport(), DMPlexSetChart(), DMPlexSetSupportSize(), DMSetUp() 3239552f7358SJed Brown @*/ 3240552f7358SJed Brown PetscErrorCode DMPlexSetSupport(DM dm, PetscInt p, const PetscInt support[]) 3241552f7358SJed Brown { 3242552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3243552f7358SJed Brown PetscInt pStart, pEnd; 3244552f7358SJed Brown PetscInt dof, off, c; 3245552f7358SJed Brown PetscErrorCode ierr; 3246552f7358SJed Brown 3247552f7358SJed Brown PetscFunctionBegin; 3248552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3249552f7358SJed Brown ierr = PetscSectionGetChart(mesh->supportSection, &pStart, &pEnd);CHKERRQ(ierr); 3250552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, &dof);CHKERRQ(ierr); 3251552f7358SJed Brown if (dof) PetscValidPointer(support, 3); 3252552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, p, &off);CHKERRQ(ierr); 32532c71b3e2SJacob 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); 3254552f7358SJed Brown for (c = 0; c < dof; ++c) { 32552c71b3e2SJacob 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); 3256552f7358SJed Brown mesh->supports[off+c] = support[c]; 3257552f7358SJed Brown } 3258552f7358SJed Brown PetscFunctionReturn(0); 3259552f7358SJed Brown } 3260552f7358SJed Brown 32617cd05799SMatthew G. Knepley /*@ 3262eaf898f9SPatrick Sanan DMPlexInsertSupport - Insert a point into the out-edges for the point p in the DAG 32637cd05799SMatthew G. Knepley 32647cd05799SMatthew G. Knepley Not collective 32657cd05799SMatthew G. Knepley 32667cd05799SMatthew G. Knepley Input Parameters: 32677cd05799SMatthew G. Knepley + mesh - The DMPlex 3268eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 32697cd05799SMatthew G. Knepley . supportPos - The local index in the cone where the point should be put 32707cd05799SMatthew G. Knepley - supportPoint - The mesh point to insert 32717cd05799SMatthew G. Knepley 32727cd05799SMatthew G. Knepley Level: beginner 32737cd05799SMatthew G. Knepley 32747cd05799SMatthew G. Knepley .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexSetChart(), DMPlexSetConeSize(), DMSetUp() 32757cd05799SMatthew G. Knepley @*/ 3276552f7358SJed Brown PetscErrorCode DMPlexInsertSupport(DM dm, PetscInt p, PetscInt supportPos, PetscInt supportPoint) 3277552f7358SJed Brown { 3278552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3279552f7358SJed Brown PetscInt pStart, pEnd; 3280552f7358SJed Brown PetscInt dof, off; 3281552f7358SJed Brown PetscErrorCode ierr; 3282552f7358SJed Brown 3283552f7358SJed Brown PetscFunctionBegin; 3284552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3285552f7358SJed Brown ierr = PetscSectionGetChart(mesh->supportSection, &pStart, &pEnd);CHKERRQ(ierr); 3286552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, &dof);CHKERRQ(ierr); 3287552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, p, &off);CHKERRQ(ierr); 32882c71b3e2SJacob 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); 32892c71b3e2SJacob 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); 32902c71b3e2SJacob 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); 3291552f7358SJed Brown mesh->supports[off+supportPos] = supportPoint; 3292552f7358SJed Brown PetscFunctionReturn(0); 3293552f7358SJed Brown } 3294552f7358SJed Brown 3295b5a892a1SMatthew G. Knepley /* Converts an orientation o in the current numbering to the previous scheme used in Plex */ 3296b5a892a1SMatthew G. Knepley PetscInt DMPolytopeConvertNewOrientation_Internal(DMPolytopeType ct, PetscInt o) 3297b5a892a1SMatthew G. Knepley { 3298b5a892a1SMatthew G. Knepley switch (ct) { 3299b5a892a1SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 3300b5a892a1SMatthew G. Knepley if (o == -1) return -2; 3301b5a892a1SMatthew G. Knepley break; 3302b5a892a1SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 3303b5a892a1SMatthew G. Knepley if (o == -3) return -1; 3304b5a892a1SMatthew G. Knepley if (o == -2) return -3; 3305b5a892a1SMatthew G. Knepley if (o == -1) return -2; 3306b5a892a1SMatthew G. Knepley break; 3307b5a892a1SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 3308b5a892a1SMatthew G. Knepley if (o == -4) return -2; 3309b5a892a1SMatthew G. Knepley if (o == -3) return -1; 3310b5a892a1SMatthew G. Knepley if (o == -2) return -4; 3311b5a892a1SMatthew G. Knepley if (o == -1) return -3; 3312b5a892a1SMatthew G. Knepley break; 3313b5a892a1SMatthew G. Knepley default: return o; 3314b5a892a1SMatthew G. Knepley } 3315b5a892a1SMatthew G. Knepley return o; 3316b5a892a1SMatthew G. Knepley } 3317b5a892a1SMatthew G. Knepley 3318b5a892a1SMatthew G. Knepley /* Converts an orientation o in the previous scheme used in Plex to the current numbering */ 3319b5a892a1SMatthew G. Knepley PetscInt DMPolytopeConvertOldOrientation_Internal(DMPolytopeType ct, PetscInt o) 3320b5a892a1SMatthew G. Knepley { 3321b5a892a1SMatthew G. Knepley switch (ct) { 3322b5a892a1SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 3323b5a892a1SMatthew G. Knepley if ((o == -2) || (o == 1)) return -1; 3324b5a892a1SMatthew G. Knepley if (o == -1) return 0; 3325b5a892a1SMatthew G. Knepley break; 3326b5a892a1SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 3327b5a892a1SMatthew G. Knepley if (o == -3) return -2; 3328b5a892a1SMatthew G. Knepley if (o == -2) return -1; 3329b5a892a1SMatthew G. Knepley if (o == -1) return -3; 3330b5a892a1SMatthew G. Knepley break; 3331b5a892a1SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 3332b5a892a1SMatthew G. Knepley if (o == -4) return -2; 3333b5a892a1SMatthew G. Knepley if (o == -3) return -1; 3334b5a892a1SMatthew G. Knepley if (o == -2) return -4; 3335b5a892a1SMatthew G. Knepley if (o == -1) return -3; 3336b5a892a1SMatthew G. Knepley break; 3337b5a892a1SMatthew G. Knepley default: return o; 3338b5a892a1SMatthew G. Knepley } 3339b5a892a1SMatthew G. Knepley return o; 3340b5a892a1SMatthew G. Knepley } 3341b5a892a1SMatthew G. Knepley 3342b5a892a1SMatthew G. Knepley /* Takes in a mesh whose orientations are in the previous scheme and converts them all to the current numbering */ 3343b5a892a1SMatthew G. Knepley PetscErrorCode DMPlexConvertOldOrientations_Internal(DM dm) 3344b5a892a1SMatthew G. Knepley { 3345b5a892a1SMatthew G. Knepley PetscInt pStart, pEnd, p; 3346b5a892a1SMatthew G. Knepley PetscErrorCode ierr; 3347b5a892a1SMatthew G. Knepley 3348b5a892a1SMatthew G. Knepley PetscFunctionBegin; 3349b5a892a1SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 3350b5a892a1SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 3351b5a892a1SMatthew G. Knepley const PetscInt *cone, *ornt; 3352b5a892a1SMatthew G. Knepley PetscInt coneSize, c; 3353b5a892a1SMatthew G. Knepley 3354b5a892a1SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, p, &coneSize);CHKERRQ(ierr); 3355b5a892a1SMatthew G. Knepley ierr = DMPlexGetCone(dm, p, &cone);CHKERRQ(ierr); 3356b5a892a1SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, p, &ornt);CHKERRQ(ierr); 3357b5a892a1SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 3358b5a892a1SMatthew G. Knepley DMPolytopeType ct; 3359b5a892a1SMatthew G. Knepley const PetscInt o = ornt[c]; 3360b5a892a1SMatthew G. Knepley 3361b5a892a1SMatthew G. Knepley ierr = DMPlexGetCellType(dm, cone[c], &ct);CHKERRQ(ierr); 3362b5a892a1SMatthew G. Knepley switch (ct) { 3363b5a892a1SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 3364b5a892a1SMatthew G. Knepley if ((o == -2) || (o == 1)) {ierr = DMPlexInsertConeOrientation(dm, p, c, -1);CHKERRQ(ierr);} 3365b5a892a1SMatthew G. Knepley if (o == -1) {ierr = DMPlexInsertConeOrientation(dm, p, c, 0);CHKERRQ(ierr);} 3366b5a892a1SMatthew G. Knepley break; 3367b5a892a1SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 3368b5a892a1SMatthew G. Knepley if (o == -3) {ierr = DMPlexInsertConeOrientation(dm, p, c, -2);CHKERRQ(ierr);} 3369b5a892a1SMatthew G. Knepley if (o == -2) {ierr = DMPlexInsertConeOrientation(dm, p, c, -1);CHKERRQ(ierr);} 3370b5a892a1SMatthew G. Knepley if (o == -1) {ierr = DMPlexInsertConeOrientation(dm, p, c, -3);CHKERRQ(ierr);} 3371b5a892a1SMatthew G. Knepley break; 3372b5a892a1SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 3373b5a892a1SMatthew G. Knepley if (o == -4) {ierr = DMPlexInsertConeOrientation(dm, p, c, -2);CHKERRQ(ierr);} 3374b5a892a1SMatthew G. Knepley if (o == -3) {ierr = DMPlexInsertConeOrientation(dm, p, c, -1);CHKERRQ(ierr);} 3375b5a892a1SMatthew G. Knepley if (o == -2) {ierr = DMPlexInsertConeOrientation(dm, p, c, -4);CHKERRQ(ierr);} 3376b5a892a1SMatthew G. Knepley if (o == -1) {ierr = DMPlexInsertConeOrientation(dm, p, c, -3);CHKERRQ(ierr);} 3377b5a892a1SMatthew G. Knepley break; 3378b5a892a1SMatthew G. Knepley default: break; 3379b5a892a1SMatthew G. Knepley } 3380b5a892a1SMatthew G. Knepley } 3381b5a892a1SMatthew G. Knepley } 3382b5a892a1SMatthew G. Knepley PetscFunctionReturn(0); 3383b5a892a1SMatthew G. Knepley } 3384b5a892a1SMatthew G. Knepley 3385012bc364SMatthew G. Knepley static PetscErrorCode DMPlexGetTransitiveClosure_Depth1_Private(DM dm, PetscInt p, PetscInt ornt, PetscBool useCone, PetscInt *numPoints, PetscInt *points[]) 3386b5a892a1SMatthew G. Knepley { 3387b5a892a1SMatthew G. Knepley DMPolytopeType ct = DM_POLYTOPE_UNKNOWN; 3388b5a892a1SMatthew G. Knepley PetscInt *closure; 3389b5a892a1SMatthew G. Knepley const PetscInt *tmp = NULL, *tmpO = NULL; 3390b5a892a1SMatthew G. Knepley PetscInt off = 0, tmpSize, t; 3391b5a892a1SMatthew G. Knepley PetscErrorCode ierr; 3392b5a892a1SMatthew G. Knepley 3393b5a892a1SMatthew G. Knepley PetscFunctionBeginHot; 3394b5a892a1SMatthew G. Knepley if (ornt) { 3395b5a892a1SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 3396b5a892a1SMatthew G. Knepley if (ct == DM_POLYTOPE_FV_GHOST || ct == DM_POLYTOPE_INTERIOR_GHOST || ct == DM_POLYTOPE_UNKNOWN) ct = DM_POLYTOPE_UNKNOWN; 3397b5a892a1SMatthew G. Knepley } 3398b5a892a1SMatthew G. Knepley if (*points) { 3399b5a892a1SMatthew G. Knepley closure = *points; 3400b5a892a1SMatthew G. Knepley } else { 3401b5a892a1SMatthew G. Knepley PetscInt maxConeSize, maxSupportSize; 3402b5a892a1SMatthew G. Knepley ierr = DMPlexGetMaxSizes(dm, &maxConeSize, &maxSupportSize);CHKERRQ(ierr); 3403b5a892a1SMatthew G. Knepley ierr = DMGetWorkArray(dm, 2*(PetscMax(maxConeSize, maxSupportSize)+1), MPIU_INT, &closure);CHKERRQ(ierr); 3404b5a892a1SMatthew G. Knepley } 3405b5a892a1SMatthew G. Knepley if (useCone) { 3406b5a892a1SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, p, &tmpSize);CHKERRQ(ierr); 3407b5a892a1SMatthew G. Knepley ierr = DMPlexGetCone(dm, p, &tmp);CHKERRQ(ierr); 3408b5a892a1SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, p, &tmpO);CHKERRQ(ierr); 3409b5a892a1SMatthew G. Knepley } else { 3410b5a892a1SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, p, &tmpSize);CHKERRQ(ierr); 3411b5a892a1SMatthew G. Knepley ierr = DMPlexGetSupport(dm, p, &tmp);CHKERRQ(ierr); 3412b5a892a1SMatthew G. Knepley } 3413b5a892a1SMatthew G. Knepley if (ct == DM_POLYTOPE_UNKNOWN) { 3414b5a892a1SMatthew G. Knepley closure[off++] = p; 3415b5a892a1SMatthew G. Knepley closure[off++] = 0; 3416b5a892a1SMatthew G. Knepley for (t = 0; t < tmpSize; ++t) { 3417b5a892a1SMatthew G. Knepley closure[off++] = tmp[t]; 3418b5a892a1SMatthew G. Knepley closure[off++] = tmpO ? tmpO[t] : 0; 3419b5a892a1SMatthew G. Knepley } 3420b5a892a1SMatthew G. Knepley } else { 3421b5a892a1SMatthew G. Knepley const PetscInt *arr = DMPolytopeTypeGetArrangment(ct, ornt);CHKERRQ(ierr); 3422b5a892a1SMatthew G. Knepley 3423b5a892a1SMatthew G. Knepley /* We assume that cells with a valid type have faces with a valid type */ 3424b5a892a1SMatthew G. Knepley closure[off++] = p; 3425b5a892a1SMatthew G. Knepley closure[off++] = ornt; 3426b5a892a1SMatthew G. Knepley for (t = 0; t < tmpSize; ++t) { 3427b5a892a1SMatthew G. Knepley DMPolytopeType ft; 3428b5a892a1SMatthew G. Knepley 3429b5a892a1SMatthew G. Knepley ierr = DMPlexGetCellType(dm, tmp[t], &ft);CHKERRQ(ierr); 3430b5a892a1SMatthew G. Knepley closure[off++] = tmp[arr[t]]; 3431b5a892a1SMatthew G. Knepley closure[off++] = tmpO ? DMPolytopeTypeComposeOrientation(ft, ornt, tmpO[t]) : 0; 3432b5a892a1SMatthew G. Knepley } 3433b5a892a1SMatthew G. Knepley } 3434b5a892a1SMatthew G. Knepley if (numPoints) *numPoints = tmpSize+1; 3435b5a892a1SMatthew G. Knepley if (points) *points = closure; 3436b5a892a1SMatthew G. Knepley PetscFunctionReturn(0); 3437b5a892a1SMatthew G. Knepley } 3438b5a892a1SMatthew G. Knepley 3439b5a892a1SMatthew G. Knepley /* We need a special tensor verison becasue we want to allow duplicate points in the endcaps for hybrid cells */ 3440b5a892a1SMatthew G. Knepley static PetscErrorCode DMPlexTransitiveClosure_Tensor_Internal(DM dm, PetscInt point, DMPolytopeType ct, PetscInt o, PetscBool useCone, PetscInt *numPoints, PetscInt **points) 3441b5a892a1SMatthew G. Knepley { 3442b5a892a1SMatthew G. Knepley const PetscInt *arr = DMPolytopeTypeGetArrangment(ct, o); 3443b5a892a1SMatthew G. Knepley const PetscInt *cone, *ornt; 3444b5a892a1SMatthew G. Knepley PetscInt *pts, *closure = NULL; 3445b5a892a1SMatthew G. Knepley DMPolytopeType ft; 3446b5a892a1SMatthew G. Knepley PetscInt maxConeSize, maxSupportSize, coneSeries, supportSeries, maxSize; 3447b5a892a1SMatthew G. Knepley PetscInt dim, coneSize, c, d, clSize, cl; 3448b5a892a1SMatthew G. Knepley PetscErrorCode ierr; 3449b5a892a1SMatthew G. Knepley 3450b5a892a1SMatthew G. Knepley PetscFunctionBeginHot; 3451b5a892a1SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 3452b5a892a1SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, point, &coneSize);CHKERRQ(ierr); 3453b5a892a1SMatthew G. Knepley ierr = DMPlexGetCone(dm, point, &cone);CHKERRQ(ierr); 3454b5a892a1SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, point, &ornt);CHKERRQ(ierr); 3455b5a892a1SMatthew G. Knepley ierr = DMPlexGetMaxSizes(dm, &maxConeSize, &maxSupportSize);CHKERRQ(ierr); 3456b5a892a1SMatthew G. Knepley coneSeries = (maxConeSize > 1) ? ((PetscPowInt(maxConeSize, dim+1)-1)/(maxConeSize-1)) : dim+1; 3457b5a892a1SMatthew G. Knepley supportSeries = (maxSupportSize > 1) ? ((PetscPowInt(maxSupportSize, dim+1)-1)/(maxSupportSize-1)) : dim+1; 3458b5a892a1SMatthew G. Knepley maxSize = PetscMax(coneSeries, supportSeries); 3459b5a892a1SMatthew G. Knepley if (*points) {pts = *points;} 3460b5a892a1SMatthew G. Knepley else {ierr = DMGetWorkArray(dm, 2*maxSize, MPIU_INT, &pts);CHKERRQ(ierr);} 3461b5a892a1SMatthew G. Knepley c = 0; 3462b5a892a1SMatthew G. Knepley pts[c++] = point; 3463b5a892a1SMatthew G. Knepley pts[c++] = o; 3464b5a892a1SMatthew G. Knepley ierr = DMPlexGetCellType(dm, cone[arr[0*2+0]], &ft);CHKERRQ(ierr); 3465b5a892a1SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure_Internal(dm, cone[arr[0*2+0]], DMPolytopeTypeComposeOrientation(ft, arr[0*2+1], ornt[0]), useCone, &clSize, &closure);CHKERRQ(ierr); 3466b5a892a1SMatthew G. Knepley for (cl = 0; cl < clSize*2; cl += 2) {pts[c++] = closure[cl]; pts[c++] = closure[cl+1];} 3467b5a892a1SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure_Internal(dm, cone[arr[1*2+0]], DMPolytopeTypeComposeOrientation(ft, arr[1*2+1], ornt[1]), useCone, &clSize, &closure);CHKERRQ(ierr); 3468b5a892a1SMatthew G. Knepley for (cl = 0; cl < clSize*2; cl += 2) {pts[c++] = closure[cl]; pts[c++] = closure[cl+1];} 3469b5a892a1SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, cone[0], useCone, &clSize, &closure);CHKERRQ(ierr); 3470b5a892a1SMatthew G. Knepley for (d = 2; d < coneSize; ++d) { 3471b5a892a1SMatthew G. Knepley ierr = DMPlexGetCellType(dm, cone[arr[d*2+0]], &ft);CHKERRQ(ierr); 3472b5a892a1SMatthew G. Knepley pts[c++] = cone[arr[d*2+0]]; 3473b5a892a1SMatthew G. Knepley pts[c++] = DMPolytopeTypeComposeOrientation(ft, arr[d*2+1], ornt[d]); 3474b5a892a1SMatthew G. Knepley } 3475b5a892a1SMatthew G. Knepley if (dim >= 3) { 3476b5a892a1SMatthew G. Knepley for (d = 2; d < coneSize; ++d) { 3477b5a892a1SMatthew G. Knepley const PetscInt fpoint = cone[arr[d*2+0]]; 3478b5a892a1SMatthew G. Knepley const PetscInt *fcone, *fornt; 3479b5a892a1SMatthew G. Knepley PetscInt fconeSize, fc, i; 3480b5a892a1SMatthew G. Knepley 3481b5a892a1SMatthew G. Knepley ierr = DMPlexGetCellType(dm, fpoint, &ft);CHKERRQ(ierr); 3482b5a892a1SMatthew G. Knepley const PetscInt *farr = DMPolytopeTypeGetArrangment(ft, DMPolytopeTypeComposeOrientation(ft, arr[d*2+1], ornt[d])); 3483b5a892a1SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, fpoint, &fconeSize);CHKERRQ(ierr); 3484b5a892a1SMatthew G. Knepley ierr = DMPlexGetCone(dm, fpoint, &fcone);CHKERRQ(ierr); 3485b5a892a1SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, fpoint, &fornt);CHKERRQ(ierr); 3486b5a892a1SMatthew G. Knepley for (fc = 0; fc < fconeSize; ++fc) { 3487b5a892a1SMatthew G. Knepley const PetscInt cp = fcone[farr[fc*2+0]]; 3488b5a892a1SMatthew G. Knepley const PetscInt co = farr[fc*2+1]; 3489b5a892a1SMatthew G. Knepley 3490b5a892a1SMatthew G. Knepley for (i = 0; i < c; i += 2) if (pts[i] == cp) break; 3491b5a892a1SMatthew G. Knepley if (i == c) { 3492b5a892a1SMatthew G. Knepley ierr = DMPlexGetCellType(dm, cp, &ft);CHKERRQ(ierr); 3493b5a892a1SMatthew G. Knepley pts[c++] = cp; 3494b5a892a1SMatthew G. Knepley pts[c++] = DMPolytopeTypeComposeOrientation(ft, co, fornt[farr[fc*2+0]]); 3495b5a892a1SMatthew G. Knepley } 3496b5a892a1SMatthew G. Knepley } 3497b5a892a1SMatthew G. Knepley } 3498b5a892a1SMatthew G. Knepley } 3499b5a892a1SMatthew G. Knepley *numPoints = c/2; 3500b5a892a1SMatthew G. Knepley *points = pts; 3501b5a892a1SMatthew G. Knepley PetscFunctionReturn(0); 3502b5a892a1SMatthew G. Knepley } 3503b5a892a1SMatthew G. Knepley 3504b5a892a1SMatthew G. Knepley PetscErrorCode DMPlexGetTransitiveClosure_Internal(DM dm, PetscInt p, PetscInt ornt, PetscBool useCone, PetscInt *numPoints, PetscInt *points[]) 3505b5a892a1SMatthew G. Knepley { 3506b5a892a1SMatthew G. Knepley DMPolytopeType ct; 3507b5a892a1SMatthew G. Knepley PetscInt *closure, *fifo; 3508b5a892a1SMatthew G. Knepley PetscInt closureSize = 0, fifoStart = 0, fifoSize = 0; 3509b5a892a1SMatthew G. Knepley PetscInt maxConeSize, maxSupportSize, coneSeries, supportSeries; 3510b5a892a1SMatthew G. Knepley PetscInt depth, maxSize; 3511b5a892a1SMatthew G. Knepley PetscErrorCode ierr; 3512b5a892a1SMatthew G. Knepley 3513b5a892a1SMatthew G. Knepley PetscFunctionBeginHot; 3514b5a892a1SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 3515b5a892a1SMatthew G. Knepley if (depth == 1) { 3516012bc364SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure_Depth1_Private(dm, p, ornt, useCone, numPoints, points);CHKERRQ(ierr); 3517b5a892a1SMatthew G. Knepley PetscFunctionReturn(0); 3518b5a892a1SMatthew G. Knepley } 3519b5a892a1SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 3520b5a892a1SMatthew G. Knepley if (ct == DM_POLYTOPE_FV_GHOST || ct == DM_POLYTOPE_INTERIOR_GHOST || ct == DM_POLYTOPE_UNKNOWN) ct = DM_POLYTOPE_UNKNOWN; 3521b5a892a1SMatthew G. Knepley if (ct == DM_POLYTOPE_SEG_PRISM_TENSOR || ct == DM_POLYTOPE_TRI_PRISM_TENSOR || ct == DM_POLYTOPE_QUAD_PRISM_TENSOR) { 3522b5a892a1SMatthew G. Knepley ierr = DMPlexTransitiveClosure_Tensor_Internal(dm, p, ct, ornt, useCone, numPoints, points);CHKERRQ(ierr); 3523b5a892a1SMatthew G. Knepley PetscFunctionReturn(0); 3524b5a892a1SMatthew G. Knepley } 3525b5a892a1SMatthew G. Knepley ierr = DMPlexGetMaxSizes(dm, &maxConeSize, &maxSupportSize);CHKERRQ(ierr); 3526b5a892a1SMatthew G. Knepley coneSeries = (maxConeSize > 1) ? ((PetscPowInt(maxConeSize, depth+1)-1)/(maxConeSize-1)) : depth+1; 3527b5a892a1SMatthew G. Knepley supportSeries = (maxSupportSize > 1) ? ((PetscPowInt(maxSupportSize, depth+1)-1)/(maxSupportSize-1)) : depth+1; 3528b5a892a1SMatthew G. Knepley maxSize = PetscMax(coneSeries, supportSeries); 3529b5a892a1SMatthew G. Knepley ierr = DMGetWorkArray(dm, 3*maxSize, MPIU_INT, &fifo);CHKERRQ(ierr); 3530b5a892a1SMatthew G. Knepley if (*points) {closure = *points;} 3531b5a892a1SMatthew G. Knepley else {ierr = DMGetWorkArray(dm, 2*maxSize, MPIU_INT, &closure);CHKERRQ(ierr);} 3532b5a892a1SMatthew G. Knepley closure[closureSize++] = p; 3533b5a892a1SMatthew G. Knepley closure[closureSize++] = ornt; 3534b5a892a1SMatthew G. Knepley fifo[fifoSize++] = p; 3535b5a892a1SMatthew G. Knepley fifo[fifoSize++] = ornt; 3536b5a892a1SMatthew G. Knepley fifo[fifoSize++] = ct; 3537b5a892a1SMatthew G. Knepley /* Should kick out early when depth is reached, rather than checking all vertices for empty cones */ 3538b5a892a1SMatthew G. Knepley while (fifoSize - fifoStart) { 3539b5a892a1SMatthew G. Knepley const PetscInt q = fifo[fifoStart++]; 3540b5a892a1SMatthew G. Knepley const PetscInt o = fifo[fifoStart++]; 3541b5a892a1SMatthew G. Knepley const DMPolytopeType qt = (DMPolytopeType) fifo[fifoStart++]; 3542b5a892a1SMatthew G. Knepley const PetscInt *qarr = DMPolytopeTypeGetArrangment(qt, o); 3543b5a892a1SMatthew G. Knepley const PetscInt *tmp, *tmpO; 3544b5a892a1SMatthew G. Knepley PetscInt tmpSize, t; 3545b5a892a1SMatthew G. Knepley 3546b5a892a1SMatthew G. Knepley if (PetscDefined(USE_DEBUG)) { 3547b5a892a1SMatthew G. Knepley PetscInt nO = DMPolytopeTypeGetNumArrangments(qt)/2; 35482c71b3e2SJacob 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); 3549b5a892a1SMatthew G. Knepley } 3550b5a892a1SMatthew G. Knepley if (useCone) { 3551b5a892a1SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, q, &tmpSize);CHKERRQ(ierr); 3552b5a892a1SMatthew G. Knepley ierr = DMPlexGetCone(dm, q, &tmp);CHKERRQ(ierr); 3553b5a892a1SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, q, &tmpO);CHKERRQ(ierr); 3554b5a892a1SMatthew G. Knepley } else { 3555b5a892a1SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, q, &tmpSize);CHKERRQ(ierr); 3556b5a892a1SMatthew G. Knepley ierr = DMPlexGetSupport(dm, q, &tmp);CHKERRQ(ierr); 3557b5a892a1SMatthew G. Knepley tmpO = NULL; 3558b5a892a1SMatthew G. Knepley } 3559b5a892a1SMatthew G. Knepley for (t = 0; t < tmpSize; ++t) { 3560b5a892a1SMatthew G. Knepley const PetscInt ip = useCone && qarr ? qarr[t*2] : t; 3561b5a892a1SMatthew G. Knepley const PetscInt io = useCone && qarr ? qarr[t*2+1] : 0; 3562b5a892a1SMatthew G. Knepley const PetscInt cp = tmp[ip]; 3563b5a892a1SMatthew G. Knepley ierr = DMPlexGetCellType(dm, cp, &ct);CHKERRQ(ierr); 3564b5a892a1SMatthew G. Knepley const PetscInt co = tmpO ? DMPolytopeTypeComposeOrientation(ct, io, tmpO[ip]) : 0; 3565b5a892a1SMatthew G. Knepley PetscInt c; 3566b5a892a1SMatthew G. Knepley 3567b5a892a1SMatthew G. Knepley /* Check for duplicate */ 3568b5a892a1SMatthew G. Knepley for (c = 0; c < closureSize; c += 2) { 3569b5a892a1SMatthew G. Knepley if (closure[c] == cp) break; 3570b5a892a1SMatthew G. Knepley } 3571b5a892a1SMatthew G. Knepley if (c == closureSize) { 3572b5a892a1SMatthew G. Knepley closure[closureSize++] = cp; 3573b5a892a1SMatthew G. Knepley closure[closureSize++] = co; 3574b5a892a1SMatthew G. Knepley fifo[fifoSize++] = cp; 3575b5a892a1SMatthew G. Knepley fifo[fifoSize++] = co; 3576b5a892a1SMatthew G. Knepley fifo[fifoSize++] = ct; 3577b5a892a1SMatthew G. Knepley } 3578b5a892a1SMatthew G. Knepley } 3579b5a892a1SMatthew G. Knepley } 3580b5a892a1SMatthew G. Knepley ierr = DMRestoreWorkArray(dm, 3*maxSize, MPIU_INT, &fifo);CHKERRQ(ierr); 3581b5a892a1SMatthew G. Knepley if (numPoints) *numPoints = closureSize/2; 3582b5a892a1SMatthew G. Knepley if (points) *points = closure; 3583b5a892a1SMatthew G. Knepley PetscFunctionReturn(0); 3584b5a892a1SMatthew G. Knepley } 3585b5a892a1SMatthew G. Knepley 3586552f7358SJed Brown /*@C 3587eaf898f9SPatrick Sanan DMPlexGetTransitiveClosure - Return the points on the transitive closure of the in-edges or out-edges for this point in the DAG 3588552f7358SJed Brown 3589552f7358SJed Brown Not collective 3590552f7358SJed Brown 3591552f7358SJed Brown Input Parameters: 3592b5a892a1SMatthew G. Knepley + dm - The DMPlex 3593b5a892a1SMatthew G. Knepley . p - The mesh point 35946b867d5aSJose E. Roman - useCone - PETSC_TRUE for the closure, otherwise return the star 3595552f7358SJed Brown 35966b867d5aSJose E. Roman Input/Output Parameter: 35976b867d5aSJose E. Roman . points - The points and point orientations, interleaved as pairs [p0, o0, p1, o1, ...]; 35986b867d5aSJose E. Roman if NULL on input, internal storage will be returned, otherwise the provided array is used 35996b867d5aSJose E. Roman 36006b867d5aSJose E. Roman Output Parameter: 36016b867d5aSJose E. Roman . numPoints - The number of points in the closure, so points[] is of size 2*numPoints 3602552f7358SJed Brown 3603552f7358SJed Brown Note: 36040298fd71SBarry Smith If using internal storage (points is NULL on input), each call overwrites the last output. 3605552f7358SJed Brown 36063813dfbdSMatthew G Knepley Fortran Notes: 3607b5a892a1SMatthew G. Knepley Since it returns an array, this routine is only available in Fortran 90, and you must include petsc.h90 in your code. 36083813dfbdSMatthew G Knepley 36093813dfbdSMatthew G Knepley The numPoints argument is not present in the Fortran 90 binding since it is internal to the array. 36103813dfbdSMatthew G Knepley 3611552f7358SJed Brown Level: beginner 3612552f7358SJed Brown 3613552f7358SJed Brown .seealso: DMPlexRestoreTransitiveClosure(), DMPlexCreate(), DMPlexSetCone(), DMPlexSetChart(), DMPlexGetCone() 3614552f7358SJed Brown @*/ 3615552f7358SJed Brown PetscErrorCode DMPlexGetTransitiveClosure(DM dm, PetscInt p, PetscBool useCone, PetscInt *numPoints, PetscInt *points[]) 3616552f7358SJed Brown { 3617552f7358SJed Brown PetscErrorCode ierr; 3618552f7358SJed Brown 3619b5a892a1SMatthew G. Knepley PetscFunctionBeginHot; 3620552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3621b5a892a1SMatthew G. Knepley if (numPoints) PetscValidIntPointer(numPoints, 4); 3622b5a892a1SMatthew G. Knepley if (points) PetscValidPointer(points, 5); 3623b5a892a1SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure_Internal(dm, p, 0, useCone, numPoints, points);CHKERRQ(ierr); 36249bf0dad6SMatthew G. Knepley PetscFunctionReturn(0); 36259bf0dad6SMatthew G. Knepley } 36269bf0dad6SMatthew G. Knepley 3627552f7358SJed Brown /*@C 3628eaf898f9SPatrick Sanan DMPlexRestoreTransitiveClosure - Restore the array of points on the transitive closure of the in-edges or out-edges for this point in the DAG 3629552f7358SJed Brown 3630552f7358SJed Brown Not collective 3631552f7358SJed Brown 3632552f7358SJed Brown Input Parameters: 3633b5a892a1SMatthew G. Knepley + dm - The DMPlex 3634b5a892a1SMatthew G. Knepley . p - The mesh point 3635b5a892a1SMatthew G. Knepley . useCone - PETSC_TRUE for the closure, otherwise return the star 3636b5a892a1SMatthew G. Knepley . numPoints - The number of points in the closure, so points[] is of size 2*numPoints 3637b5a892a1SMatthew G. Knepley - points - The points and point orientations, interleaved as pairs [p0, o0, p1, o1, ...] 3638552f7358SJed Brown 3639552f7358SJed Brown Note: 36400298fd71SBarry Smith If not using internal storage (points is not NULL on input), this call is unnecessary 3641552f7358SJed Brown 36423813dfbdSMatthew G Knepley Fortran Notes: 3643b5a892a1SMatthew G. Knepley Since it returns an array, this routine is only available in Fortran 90, and you must include petsc.h90 in your code. 36443813dfbdSMatthew G Knepley 36453813dfbdSMatthew G Knepley The numPoints argument is not present in the Fortran 90 binding since it is internal to the array. 36463813dfbdSMatthew G Knepley 3647552f7358SJed Brown Level: beginner 3648552f7358SJed Brown 3649552f7358SJed Brown .seealso: DMPlexGetTransitiveClosure(), DMPlexCreate(), DMPlexSetCone(), DMPlexSetChart(), DMPlexGetCone() 3650552f7358SJed Brown @*/ 3651552f7358SJed Brown PetscErrorCode DMPlexRestoreTransitiveClosure(DM dm, PetscInt p, PetscBool useCone, PetscInt *numPoints, PetscInt *points[]) 3652552f7358SJed Brown { 3653552f7358SJed Brown PetscErrorCode ierr; 3654552f7358SJed Brown 3655b5a892a1SMatthew G. Knepley PetscFunctionBeginHot; 3656552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 36574ff43b2cSJed Brown if (numPoints) *numPoints = 0; 3658b5a892a1SMatthew G. Knepley ierr = DMRestoreWorkArray(dm, 0, MPIU_INT, points);CHKERRQ(ierr); 3659552f7358SJed Brown PetscFunctionReturn(0); 3660552f7358SJed Brown } 3661552f7358SJed Brown 3662552f7358SJed Brown /*@ 3663eaf898f9SPatrick Sanan DMPlexGetMaxSizes - Return the maximum number of in-edges (cone) and out-edges (support) for any point in the DAG 3664552f7358SJed Brown 3665552f7358SJed Brown Not collective 3666552f7358SJed Brown 3667552f7358SJed Brown Input Parameter: 3668552f7358SJed Brown . mesh - The DMPlex 3669552f7358SJed Brown 3670552f7358SJed Brown Output Parameters: 3671552f7358SJed Brown + maxConeSize - The maximum number of in-edges 3672552f7358SJed Brown - maxSupportSize - The maximum number of out-edges 3673552f7358SJed Brown 3674552f7358SJed Brown Level: beginner 3675552f7358SJed Brown 3676552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetConeSize(), DMPlexSetChart() 3677552f7358SJed Brown @*/ 3678552f7358SJed Brown PetscErrorCode DMPlexGetMaxSizes(DM dm, PetscInt *maxConeSize, PetscInt *maxSupportSize) 3679552f7358SJed Brown { 3680552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3681552f7358SJed Brown 3682552f7358SJed Brown PetscFunctionBegin; 3683552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3684552f7358SJed Brown if (maxConeSize) *maxConeSize = mesh->maxConeSize; 3685552f7358SJed Brown if (maxSupportSize) *maxSupportSize = mesh->maxSupportSize; 3686552f7358SJed Brown PetscFunctionReturn(0); 3687552f7358SJed Brown } 3688552f7358SJed Brown 3689552f7358SJed Brown PetscErrorCode DMSetUp_Plex(DM dm) 3690552f7358SJed Brown { 3691552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3692552f7358SJed Brown PetscInt size; 3693552f7358SJed Brown PetscErrorCode ierr; 3694552f7358SJed Brown 3695552f7358SJed Brown PetscFunctionBegin; 3696552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3697552f7358SJed Brown ierr = PetscSectionSetUp(mesh->coneSection);CHKERRQ(ierr); 3698552f7358SJed Brown ierr = PetscSectionGetStorageSize(mesh->coneSection, &size);CHKERRQ(ierr); 36991795a4d1SJed Brown ierr = PetscMalloc1(size, &mesh->cones);CHKERRQ(ierr); 37001795a4d1SJed Brown ierr = PetscCalloc1(size, &mesh->coneOrientations);CHKERRQ(ierr); 3701ef1259faSMatthew G. Knepley ierr = PetscLogObjectMemory((PetscObject) dm, size*2*sizeof(PetscInt));CHKERRQ(ierr); 3702552f7358SJed Brown if (mesh->maxSupportSize) { 3703552f7358SJed Brown ierr = PetscSectionSetUp(mesh->supportSection);CHKERRQ(ierr); 3704552f7358SJed Brown ierr = PetscSectionGetStorageSize(mesh->supportSection, &size);CHKERRQ(ierr); 37051795a4d1SJed Brown ierr = PetscMalloc1(size, &mesh->supports);CHKERRQ(ierr); 3706ef1259faSMatthew G. Knepley ierr = PetscLogObjectMemory((PetscObject) dm, size*sizeof(PetscInt));CHKERRQ(ierr); 3707552f7358SJed Brown } 3708552f7358SJed Brown PetscFunctionReturn(0); 3709552f7358SJed Brown } 3710552f7358SJed Brown 3711276c5506SMatthew G. Knepley PetscErrorCode DMCreateSubDM_Plex(DM dm, PetscInt numFields, const PetscInt fields[], IS *is, DM *subdm) 3712552f7358SJed Brown { 3713552f7358SJed Brown PetscErrorCode ierr; 3714552f7358SJed Brown 3715552f7358SJed Brown PetscFunctionBegin; 37164d9407bcSMatthew G. Knepley if (subdm) {ierr = DMClone(dm, subdm);CHKERRQ(ierr);} 3717792b654fSMatthew G. Knepley ierr = DMCreateSectionSubDM(dm, numFields, fields, is, subdm);CHKERRQ(ierr); 3718c2939958SSatish Balay if (subdm) {(*subdm)->useNatural = dm->useNatural;} 3719736995cdSBlaise Bourdin if (dm->useNatural && dm->sfMigration) { 3720f94b4a02SBlaise Bourdin PetscSF sfMigrationInv,sfNatural; 3721f94b4a02SBlaise Bourdin PetscSection section, sectionSeq; 3722f94b4a02SBlaise Bourdin 37233dcd263cSBlaise Bourdin (*subdm)->sfMigration = dm->sfMigration; 37243dcd263cSBlaise Bourdin ierr = PetscObjectReference((PetscObject) dm->sfMigration);CHKERRQ(ierr); 3725c3b366b1Sprj- ierr = DMGetLocalSection((*subdm), §ion);CHKERRQ(ierr); 3726f94b4a02SBlaise Bourdin ierr = PetscSFCreateInverseSF((*subdm)->sfMigration, &sfMigrationInv);CHKERRQ(ierr); 3727f94b4a02SBlaise Bourdin ierr = PetscSectionCreate(PetscObjectComm((PetscObject) (*subdm)), §ionSeq);CHKERRQ(ierr); 3728f94b4a02SBlaise Bourdin ierr = PetscSFDistributeSection(sfMigrationInv, section, NULL, sectionSeq);CHKERRQ(ierr); 3729f94b4a02SBlaise Bourdin 3730f94b4a02SBlaise Bourdin ierr = DMPlexCreateGlobalToNaturalSF(*subdm, sectionSeq, (*subdm)->sfMigration, &sfNatural);CHKERRQ(ierr); 3731c40e9495SBlaise Bourdin (*subdm)->sfNatural = sfNatural; 3732f94b4a02SBlaise Bourdin ierr = PetscSectionDestroy(§ionSeq);CHKERRQ(ierr); 3733f94b4a02SBlaise Bourdin ierr = PetscSFDestroy(&sfMigrationInv);CHKERRQ(ierr); 3734f94b4a02SBlaise Bourdin } 3735552f7358SJed Brown PetscFunctionReturn(0); 3736552f7358SJed Brown } 3737552f7358SJed Brown 37382adcc780SMatthew G. Knepley PetscErrorCode DMCreateSuperDM_Plex(DM dms[], PetscInt len, IS **is, DM *superdm) 37392adcc780SMatthew G. Knepley { 37402adcc780SMatthew G. Knepley PetscErrorCode ierr; 37413dcd263cSBlaise Bourdin PetscInt i = 0; 37422adcc780SMatthew G. Knepley 37432adcc780SMatthew G. Knepley PetscFunctionBegin; 3744435bcee1SStefano Zampini ierr = DMClone(dms[0], superdm);CHKERRQ(ierr); 3745792b654fSMatthew G. Knepley ierr = DMCreateSectionSuperDM(dms, len, is, superdm);CHKERRQ(ierr); 3746c40e9495SBlaise Bourdin (*superdm)->useNatural = PETSC_FALSE; 37473dcd263cSBlaise Bourdin for (i = 0; i < len; i++) { 37483dcd263cSBlaise Bourdin if (dms[i]->useNatural && dms[i]->sfMigration) { 37493dcd263cSBlaise Bourdin PetscSF sfMigrationInv,sfNatural; 37503dcd263cSBlaise Bourdin PetscSection section, sectionSeq; 37513dcd263cSBlaise Bourdin 37523dcd263cSBlaise Bourdin (*superdm)->sfMigration = dms[i]->sfMigration; 37533dcd263cSBlaise Bourdin ierr = PetscObjectReference((PetscObject) dms[i]->sfMigration);CHKERRQ(ierr); 3754c40e9495SBlaise Bourdin (*superdm)->useNatural = PETSC_TRUE; 375592fd8e1eSJed Brown ierr = DMGetLocalSection((*superdm), §ion);CHKERRQ(ierr); 37563dcd263cSBlaise Bourdin ierr = PetscSFCreateInverseSF((*superdm)->sfMigration, &sfMigrationInv);CHKERRQ(ierr); 37573dcd263cSBlaise Bourdin ierr = PetscSectionCreate(PetscObjectComm((PetscObject) (*superdm)), §ionSeq);CHKERRQ(ierr); 37583dcd263cSBlaise Bourdin ierr = PetscSFDistributeSection(sfMigrationInv, section, NULL, sectionSeq);CHKERRQ(ierr); 37593dcd263cSBlaise Bourdin 37603dcd263cSBlaise Bourdin ierr = DMPlexCreateGlobalToNaturalSF(*superdm, sectionSeq, (*superdm)->sfMigration, &sfNatural);CHKERRQ(ierr); 3761c40e9495SBlaise Bourdin (*superdm)->sfNatural = sfNatural; 37623dcd263cSBlaise Bourdin ierr = PetscSectionDestroy(§ionSeq);CHKERRQ(ierr); 37633dcd263cSBlaise Bourdin ierr = PetscSFDestroy(&sfMigrationInv);CHKERRQ(ierr); 37643dcd263cSBlaise Bourdin break; 37653dcd263cSBlaise Bourdin } 37663dcd263cSBlaise Bourdin } 37672adcc780SMatthew G. Knepley PetscFunctionReturn(0); 37682adcc780SMatthew G. Knepley } 37692adcc780SMatthew G. Knepley 3770552f7358SJed Brown /*@ 3771eaf898f9SPatrick Sanan DMPlexSymmetrize - Create support (out-edge) information from cone (in-edge) information 3772552f7358SJed Brown 3773552f7358SJed Brown Not collective 3774552f7358SJed Brown 3775552f7358SJed Brown Input Parameter: 3776552f7358SJed Brown . mesh - The DMPlex 3777552f7358SJed Brown 3778552f7358SJed Brown Output Parameter: 3779552f7358SJed Brown 3780552f7358SJed Brown Note: 3781552f7358SJed Brown This should be called after all calls to DMPlexSetCone() 3782552f7358SJed Brown 3783552f7358SJed Brown Level: beginner 3784552f7358SJed Brown 3785552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetChart(), DMPlexSetConeSize(), DMPlexSetCone() 3786552f7358SJed Brown @*/ 3787552f7358SJed Brown PetscErrorCode DMPlexSymmetrize(DM dm) 3788552f7358SJed Brown { 3789552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3790552f7358SJed Brown PetscInt *offsets; 3791552f7358SJed Brown PetscInt supportSize; 3792552f7358SJed Brown PetscInt pStart, pEnd, p; 3793552f7358SJed Brown PetscErrorCode ierr; 3794552f7358SJed Brown 3795552f7358SJed Brown PetscFunctionBegin; 3796552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 37972c71b3e2SJacob Faibussowitsch PetscCheckFalse(mesh->supports,PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Supports were already setup in this DMPlex"); 379830b0ce1bSStefano Zampini ierr = PetscLogEventBegin(DMPLEX_Symmetrize,dm,0,0,0);CHKERRQ(ierr); 3799552f7358SJed Brown /* Calculate support sizes */ 3800552f7358SJed Brown ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 3801552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 3802552f7358SJed Brown PetscInt dof, off, c; 3803552f7358SJed Brown 3804552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 3805552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 3806552f7358SJed Brown for (c = off; c < off+dof; ++c) { 3807552f7358SJed Brown ierr = PetscSectionAddDof(mesh->supportSection, mesh->cones[c], 1);CHKERRQ(ierr); 3808552f7358SJed Brown } 3809552f7358SJed Brown } 3810552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 3811552f7358SJed Brown PetscInt dof; 3812552f7358SJed Brown 3813552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, &dof);CHKERRQ(ierr); 38140d644c17SKarl Rupp 3815552f7358SJed Brown mesh->maxSupportSize = PetscMax(mesh->maxSupportSize, dof); 3816552f7358SJed Brown } 3817552f7358SJed Brown ierr = PetscSectionSetUp(mesh->supportSection);CHKERRQ(ierr); 3818552f7358SJed Brown /* Calculate supports */ 3819552f7358SJed Brown ierr = PetscSectionGetStorageSize(mesh->supportSection, &supportSize);CHKERRQ(ierr); 38201795a4d1SJed Brown ierr = PetscMalloc1(supportSize, &mesh->supports);CHKERRQ(ierr); 38211795a4d1SJed Brown ierr = PetscCalloc1(pEnd - pStart, &offsets);CHKERRQ(ierr); 3822552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 3823552f7358SJed Brown PetscInt dof, off, c; 3824552f7358SJed Brown 3825552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 3826552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 3827552f7358SJed Brown for (c = off; c < off+dof; ++c) { 3828552f7358SJed Brown const PetscInt q = mesh->cones[c]; 3829552f7358SJed Brown PetscInt offS; 3830552f7358SJed Brown 3831552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, q, &offS);CHKERRQ(ierr); 38320d644c17SKarl Rupp 3833552f7358SJed Brown mesh->supports[offS+offsets[q]] = p; 3834552f7358SJed Brown ++offsets[q]; 3835552f7358SJed Brown } 3836552f7358SJed Brown } 3837552f7358SJed Brown ierr = PetscFree(offsets);CHKERRQ(ierr); 383830b0ce1bSStefano Zampini ierr = PetscLogEventEnd(DMPLEX_Symmetrize,dm,0,0,0);CHKERRQ(ierr); 3839552f7358SJed Brown PetscFunctionReturn(0); 3840552f7358SJed Brown } 3841552f7358SJed Brown 3842277ea44aSLisandro Dalcin static PetscErrorCode DMPlexCreateDepthStratum(DM dm, DMLabel label, PetscInt depth, PetscInt pStart, PetscInt pEnd) 3843277ea44aSLisandro Dalcin { 3844277ea44aSLisandro Dalcin IS stratumIS; 3845277ea44aSLisandro Dalcin PetscErrorCode ierr; 3846277ea44aSLisandro Dalcin 3847277ea44aSLisandro Dalcin PetscFunctionBegin; 3848277ea44aSLisandro Dalcin if (pStart >= pEnd) PetscFunctionReturn(0); 384976bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 3850277ea44aSLisandro Dalcin PetscInt qStart, qEnd, numLevels, level; 3851277ea44aSLisandro Dalcin PetscBool overlap = PETSC_FALSE; 3852277ea44aSLisandro Dalcin ierr = DMLabelGetNumValues(label, &numLevels);CHKERRQ(ierr); 3853277ea44aSLisandro Dalcin for (level = 0; level < numLevels; level++) { 3854277ea44aSLisandro Dalcin ierr = DMLabelGetStratumBounds(label, level, &qStart, &qEnd);CHKERRQ(ierr); 3855277ea44aSLisandro Dalcin if ((pStart >= qStart && pStart < qEnd) || (pEnd > qStart && pEnd <= qEnd)) {overlap = PETSC_TRUE; break;} 3856277ea44aSLisandro Dalcin } 38572c71b3e2SJacob 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); 3858277ea44aSLisandro Dalcin } 3859277ea44aSLisandro Dalcin ierr = ISCreateStride(PETSC_COMM_SELF, pEnd-pStart, pStart, 1, &stratumIS);CHKERRQ(ierr); 3860277ea44aSLisandro Dalcin ierr = DMLabelSetStratumIS(label, depth, stratumIS);CHKERRQ(ierr); 3861277ea44aSLisandro Dalcin ierr = ISDestroy(&stratumIS);CHKERRQ(ierr); 3862277ea44aSLisandro Dalcin PetscFunctionReturn(0); 3863277ea44aSLisandro Dalcin } 3864277ea44aSLisandro Dalcin 3865552f7358SJed Brown /*@ 3866a8d69d7bSBarry Smith DMPlexStratify - The DAG for most topologies is a graded poset (https://en.wikipedia.org/wiki/Graded_poset), and 38676dd80730SBarry Smith can be illustrated by a Hasse Diagram (https://en.wikipedia.org/wiki/Hasse_diagram). The strata group all points of the 3868552f7358SJed Brown same grade, and this function calculates the strata. This grade can be seen as the height (or depth) of the point in 3869552f7358SJed Brown the DAG. 3870552f7358SJed Brown 3871bf4602e4SToby Isaac Collective on dm 3872552f7358SJed Brown 3873552f7358SJed Brown Input Parameter: 3874552f7358SJed Brown . mesh - The DMPlex 3875552f7358SJed Brown 3876552f7358SJed Brown Output Parameter: 3877552f7358SJed Brown 3878552f7358SJed Brown Notes: 3879b1bb481bSMatthew Knepley Concretely, DMPlexStratify() creates a new label named "depth" containing the depth in the DAG of each point. For cell-vertex 3880b1bb481bSMatthew 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 3881b1bb481bSMatthew Knepley until cells have depth equal to the dimension of the mesh. The depth label can be accessed through DMPlexGetDepthLabel() or DMPlexGetDepthStratum(), or 3882c58f1c22SToby Isaac manually via DMGetLabel(). The height is defined implicitly by height = maxDimension - depth, and can be accessed 3883150b719bSJed Brown via DMPlexGetHeightStratum(). For example, cells have height 0 and faces have height 1. 3884552f7358SJed Brown 3885b1bb481bSMatthew Knepley The depth of a point is calculated by executing a breadth-first search (BFS) on the DAG. This could produce surprising results 3886b1bb481bSMatthew Knepley if run on a partially interpolated mesh, meaning one that had some edges and faces, but not others. For example, suppose that 3887b1bb481bSMatthew 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 3888b1bb481bSMatthew Knepley to interpolate only that one (e0), so that 3889b1bb481bSMatthew Knepley $ cone(c0) = {e0, v2} 3890b1bb481bSMatthew Knepley $ cone(e0) = {v0, v1} 3891b1bb481bSMatthew Knepley If DMPlexStratify() is run on this mesh, it will give depths 3892b1bb481bSMatthew Knepley $ depth 0 = {v0, v1, v2} 3893b1bb481bSMatthew Knepley $ depth 1 = {e0, c0} 3894b1bb481bSMatthew Knepley where the triangle has been given depth 1, instead of 2, because it is reachable from vertex v2. 3895b1bb481bSMatthew Knepley 3896150b719bSJed Brown DMPlexStratify() should be called after all calls to DMPlexSymmetrize() 3897552f7358SJed Brown 3898552f7358SJed Brown Level: beginner 3899552f7358SJed Brown 3900ba2698f1SMatthew G. Knepley .seealso: DMPlexCreate(), DMPlexSymmetrize(), DMPlexComputeCellTypes() 3901552f7358SJed Brown @*/ 3902552f7358SJed Brown PetscErrorCode DMPlexStratify(DM dm) 3903552f7358SJed Brown { 3904df0420ecSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 3905aa50250dSMatthew G. Knepley DMLabel label; 3906552f7358SJed Brown PetscInt pStart, pEnd, p; 3907552f7358SJed Brown PetscInt numRoots = 0, numLeaves = 0; 3908552f7358SJed Brown PetscErrorCode ierr; 3909552f7358SJed Brown 3910552f7358SJed Brown PetscFunctionBegin; 3911552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3912552f7358SJed Brown ierr = PetscLogEventBegin(DMPLEX_Stratify,dm,0,0,0);CHKERRQ(ierr); 3913277ea44aSLisandro Dalcin 3914277ea44aSLisandro Dalcin /* Create depth label */ 3915aa50250dSMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 3916c58f1c22SToby Isaac ierr = DMCreateLabel(dm, "depth");CHKERRQ(ierr); 3917aa50250dSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 3918277ea44aSLisandro Dalcin 3919277ea44aSLisandro Dalcin { 3920552f7358SJed Brown /* Initialize roots and count leaves */ 3921277ea44aSLisandro Dalcin PetscInt sMin = PETSC_MAX_INT; 3922277ea44aSLisandro Dalcin PetscInt sMax = PETSC_MIN_INT; 3923552f7358SJed Brown PetscInt coneSize, supportSize; 3924552f7358SJed Brown 3925277ea44aSLisandro Dalcin for (p = pStart; p < pEnd; ++p) { 3926552f7358SJed Brown ierr = DMPlexGetConeSize(dm, p, &coneSize);CHKERRQ(ierr); 3927552f7358SJed Brown ierr = DMPlexGetSupportSize(dm, p, &supportSize);CHKERRQ(ierr); 3928552f7358SJed Brown if (!coneSize && supportSize) { 3929277ea44aSLisandro Dalcin sMin = PetscMin(p, sMin); 3930277ea44aSLisandro Dalcin sMax = PetscMax(p, sMax); 3931552f7358SJed Brown ++numRoots; 3932552f7358SJed Brown } else if (!supportSize && coneSize) { 3933552f7358SJed Brown ++numLeaves; 3934552f7358SJed Brown } else if (!supportSize && !coneSize) { 3935552f7358SJed Brown /* Isolated points */ 3936277ea44aSLisandro Dalcin sMin = PetscMin(p, sMin); 3937277ea44aSLisandro Dalcin sMax = PetscMax(p, sMax); 3938552f7358SJed Brown } 3939552f7358SJed Brown } 3940277ea44aSLisandro Dalcin ierr = DMPlexCreateDepthStratum(dm, label, 0, sMin, sMax+1);CHKERRQ(ierr); 3941277ea44aSLisandro Dalcin } 3942277ea44aSLisandro Dalcin 3943552f7358SJed Brown if (numRoots + numLeaves == (pEnd - pStart)) { 3944277ea44aSLisandro Dalcin PetscInt sMin = PETSC_MAX_INT; 3945277ea44aSLisandro Dalcin PetscInt sMax = PETSC_MIN_INT; 3946552f7358SJed Brown PetscInt coneSize, supportSize; 3947552f7358SJed Brown 3948277ea44aSLisandro Dalcin for (p = pStart; p < pEnd; ++p) { 3949552f7358SJed Brown ierr = DMPlexGetConeSize(dm, p, &coneSize);CHKERRQ(ierr); 3950552f7358SJed Brown ierr = DMPlexGetSupportSize(dm, p, &supportSize);CHKERRQ(ierr); 3951552f7358SJed Brown if (!supportSize && coneSize) { 3952277ea44aSLisandro Dalcin sMin = PetscMin(p, sMin); 3953277ea44aSLisandro Dalcin sMax = PetscMax(p, sMax); 3954552f7358SJed Brown } 3955552f7358SJed Brown } 3956277ea44aSLisandro Dalcin ierr = DMPlexCreateDepthStratum(dm, label, 1, sMin, sMax+1);CHKERRQ(ierr); 3957552f7358SJed Brown } else { 3958277ea44aSLisandro Dalcin PetscInt level = 0; 3959277ea44aSLisandro Dalcin PetscInt qStart, qEnd, q; 3960552f7358SJed Brown 3961277ea44aSLisandro Dalcin ierr = DMLabelGetStratumBounds(label, level, &qStart, &qEnd);CHKERRQ(ierr); 3962277ea44aSLisandro Dalcin while (qEnd > qStart) { 3963277ea44aSLisandro Dalcin PetscInt sMin = PETSC_MAX_INT; 3964277ea44aSLisandro Dalcin PetscInt sMax = PETSC_MIN_INT; 396574ef644bSMatthew G. Knepley 3966277ea44aSLisandro Dalcin for (q = qStart; q < qEnd; ++q) { 396774ef644bSMatthew G. Knepley const PetscInt *support; 396874ef644bSMatthew G. Knepley PetscInt supportSize, s; 396974ef644bSMatthew G. Knepley 3970277ea44aSLisandro Dalcin ierr = DMPlexGetSupportSize(dm, q, &supportSize);CHKERRQ(ierr); 3971277ea44aSLisandro Dalcin ierr = DMPlexGetSupport(dm, q, &support);CHKERRQ(ierr); 397274ef644bSMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 3973277ea44aSLisandro Dalcin sMin = PetscMin(support[s], sMin); 3974277ea44aSLisandro Dalcin sMax = PetscMax(support[s], sMax); 3975552f7358SJed Brown } 3976552f7358SJed Brown } 3977277ea44aSLisandro Dalcin ierr = DMLabelGetNumValues(label, &level);CHKERRQ(ierr); 3978277ea44aSLisandro Dalcin ierr = DMPlexCreateDepthStratum(dm, label, level, sMin, sMax+1);CHKERRQ(ierr); 3979277ea44aSLisandro Dalcin ierr = DMLabelGetStratumBounds(label, level, &qStart, &qEnd);CHKERRQ(ierr); 398074ef644bSMatthew G. Knepley } 398174ef644bSMatthew G. Knepley } 3982bf4602e4SToby Isaac { /* just in case there is an empty process */ 3983bf4602e4SToby Isaac PetscInt numValues, maxValues = 0, v; 3984bf4602e4SToby Isaac 3985bf4602e4SToby Isaac ierr = DMLabelGetNumValues(label, &numValues);CHKERRQ(ierr); 3986ffc4695bSBarry Smith ierr = MPI_Allreduce(&numValues,&maxValues,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)dm));CHKERRMPI(ierr); 3987bf4602e4SToby Isaac for (v = numValues; v < maxValues; v++) { 3988367003a6SStefano Zampini ierr = DMLabelAddStratum(label, v);CHKERRQ(ierr); 3989bf4602e4SToby Isaac } 3990bf4602e4SToby Isaac } 3991d67d17b1SMatthew G. Knepley ierr = PetscObjectStateGet((PetscObject) label, &mesh->depthState);CHKERRQ(ierr); 3992552f7358SJed Brown ierr = PetscLogEventEnd(DMPLEX_Stratify,dm,0,0,0);CHKERRQ(ierr); 3993552f7358SJed Brown PetscFunctionReturn(0); 3994552f7358SJed Brown } 3995552f7358SJed Brown 3996412e9a14SMatthew G. Knepley PetscErrorCode DMPlexComputeCellType_Internal(DM dm, PetscInt p, PetscInt pdepth, DMPolytopeType *pt) 3997ba2698f1SMatthew G. Knepley { 3998412e9a14SMatthew G. Knepley DMPolytopeType ct = DM_POLYTOPE_UNKNOWN; 3999412e9a14SMatthew G. Knepley PetscInt dim, depth, pheight, coneSize; 4000ba2698f1SMatthew G. Knepley PetscErrorCode ierr; 4001ba2698f1SMatthew G. Knepley 4002412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 4003ba2698f1SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 4004ba2698f1SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 4005ba2698f1SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, p, &coneSize);CHKERRQ(ierr); 4006ba2698f1SMatthew G. Knepley pheight = depth - pdepth; 4007ba2698f1SMatthew G. Knepley if (depth <= 1) { 4008ba2698f1SMatthew G. Knepley switch (pdepth) { 4009ba2698f1SMatthew G. Knepley case 0: ct = DM_POLYTOPE_POINT;break; 4010ba2698f1SMatthew G. Knepley case 1: 4011ba2698f1SMatthew G. Knepley switch (coneSize) { 4012ba2698f1SMatthew G. Knepley case 2: ct = DM_POLYTOPE_SEGMENT;break; 4013ba2698f1SMatthew G. Knepley case 3: ct = DM_POLYTOPE_TRIANGLE;break; 4014ba2698f1SMatthew G. Knepley case 4: 4015ba2698f1SMatthew G. Knepley switch (dim) { 4016ba2698f1SMatthew G. Knepley case 2: ct = DM_POLYTOPE_QUADRILATERAL;break; 4017ba2698f1SMatthew G. Knepley case 3: ct = DM_POLYTOPE_TETRAHEDRON;break; 4018ba2698f1SMatthew G. Knepley default: break; 4019ba2698f1SMatthew G. Knepley } 4020ba2698f1SMatthew G. Knepley break; 4021da9060c4SMatthew G. Knepley case 5: ct = DM_POLYTOPE_PYRAMID;break; 4022ba2698f1SMatthew G. Knepley case 6: ct = DM_POLYTOPE_TRI_PRISM_TENSOR;break; 4023ba2698f1SMatthew G. Knepley case 8: ct = DM_POLYTOPE_HEXAHEDRON;break; 4024ba2698f1SMatthew G. Knepley default: break; 4025ba2698f1SMatthew G. Knepley } 4026ba2698f1SMatthew G. Knepley } 4027ba2698f1SMatthew G. Knepley } else { 4028ba2698f1SMatthew G. Knepley if (pdepth == 0) { 4029ba2698f1SMatthew G. Knepley ct = DM_POLYTOPE_POINT; 4030ba2698f1SMatthew G. Knepley } else if (pheight == 0) { 4031ba2698f1SMatthew G. Knepley switch (dim) { 4032ba2698f1SMatthew G. Knepley case 1: 4033ba2698f1SMatthew G. Knepley switch (coneSize) { 4034ba2698f1SMatthew G. Knepley case 2: ct = DM_POLYTOPE_SEGMENT;break; 4035ba2698f1SMatthew G. Knepley default: break; 4036ba2698f1SMatthew G. Knepley } 4037ba2698f1SMatthew G. Knepley break; 4038ba2698f1SMatthew G. Knepley case 2: 4039ba2698f1SMatthew G. Knepley switch (coneSize) { 4040ba2698f1SMatthew G. Knepley case 3: ct = DM_POLYTOPE_TRIANGLE;break; 4041ba2698f1SMatthew G. Knepley case 4: ct = DM_POLYTOPE_QUADRILATERAL;break; 4042ba2698f1SMatthew G. Knepley default: break; 4043ba2698f1SMatthew G. Knepley } 4044ba2698f1SMatthew G. Knepley break; 4045ba2698f1SMatthew G. Knepley case 3: 4046ba2698f1SMatthew G. Knepley switch (coneSize) { 4047ba2698f1SMatthew G. Knepley case 4: ct = DM_POLYTOPE_TETRAHEDRON;break; 4048da9060c4SMatthew G. Knepley case 5: 4049da9060c4SMatthew G. Knepley { 4050da9060c4SMatthew G. Knepley const PetscInt *cone; 4051da9060c4SMatthew G. Knepley PetscInt faceConeSize; 4052da9060c4SMatthew G. Knepley 4053da9060c4SMatthew G. Knepley ierr = DMPlexGetCone(dm, p, &cone);CHKERRQ(ierr); 4054da9060c4SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, cone[0], &faceConeSize);CHKERRQ(ierr); 4055da9060c4SMatthew G. Knepley switch (faceConeSize) { 4056da9060c4SMatthew G. Knepley case 3: ct = DM_POLYTOPE_TRI_PRISM_TENSOR;break; 4057da9060c4SMatthew G. Knepley case 4: ct = DM_POLYTOPE_PYRAMID;break; 4058da9060c4SMatthew G. Knepley } 4059da9060c4SMatthew G. Knepley } 4060da9060c4SMatthew G. Knepley break; 4061ba2698f1SMatthew G. Knepley case 6: ct = DM_POLYTOPE_HEXAHEDRON;break; 4062ba2698f1SMatthew G. Knepley default: break; 4063ba2698f1SMatthew G. Knepley } 4064ba2698f1SMatthew G. Knepley break; 4065ba2698f1SMatthew G. Knepley default: break; 4066ba2698f1SMatthew G. Knepley } 4067ba2698f1SMatthew G. Knepley } else if (pheight > 0) { 4068ba2698f1SMatthew G. Knepley switch (coneSize) { 4069ba2698f1SMatthew G. Knepley case 2: ct = DM_POLYTOPE_SEGMENT;break; 4070ba2698f1SMatthew G. Knepley case 3: ct = DM_POLYTOPE_TRIANGLE;break; 4071ba2698f1SMatthew G. Knepley case 4: ct = DM_POLYTOPE_QUADRILATERAL;break; 4072ba2698f1SMatthew G. Knepley default: break; 4073ba2698f1SMatthew G. Knepley } 4074ba2698f1SMatthew G. Knepley } 4075ba2698f1SMatthew G. Knepley } 4076412e9a14SMatthew G. Knepley *pt = ct; 4077412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 4078ba2698f1SMatthew G. Knepley } 4079412e9a14SMatthew G. Knepley 4080412e9a14SMatthew G. Knepley /*@ 4081412e9a14SMatthew G. Knepley DMPlexComputeCellTypes - Infer the polytope type of every cell using its dimension and cone size. 4082412e9a14SMatthew G. Knepley 4083412e9a14SMatthew G. Knepley Collective on dm 4084412e9a14SMatthew G. Knepley 4085412e9a14SMatthew G. Knepley Input Parameter: 4086412e9a14SMatthew G. Knepley . mesh - The DMPlex 4087412e9a14SMatthew G. Knepley 4088412e9a14SMatthew G. Knepley DMPlexComputeCellTypes() should be called after all calls to DMPlexSymmetrize() and DMPlexStratify() 4089412e9a14SMatthew G. Knepley 4090412e9a14SMatthew G. Knepley Level: developer 4091412e9a14SMatthew G. Knepley 4092412e9a14SMatthew G. Knepley Note: This function is normally called automatically by Plex when a cell type is requested. It creates an 4093412e9a14SMatthew G. Knepley internal DMLabel named "celltype" which can be directly accessed using DMGetLabel(). A user may disable 4094412e9a14SMatthew G. Knepley automatic creation by creating the label manually, using DMCreateLabel(dm, "celltype"). 4095412e9a14SMatthew G. Knepley 4096412e9a14SMatthew G. Knepley .seealso: DMPlexCreate(), DMPlexSymmetrize(), DMPlexStratify(), DMGetLabel(), DMCreateLabel() 4097412e9a14SMatthew G. Knepley @*/ 4098412e9a14SMatthew G. Knepley PetscErrorCode DMPlexComputeCellTypes(DM dm) 4099412e9a14SMatthew G. Knepley { 4100412e9a14SMatthew G. Knepley DM_Plex *mesh; 4101412e9a14SMatthew G. Knepley DMLabel ctLabel; 4102412e9a14SMatthew G. Knepley PetscInt pStart, pEnd, p; 4103412e9a14SMatthew G. Knepley PetscErrorCode ierr; 4104412e9a14SMatthew G. Knepley 4105412e9a14SMatthew G. Knepley PetscFunctionBegin; 4106412e9a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4107412e9a14SMatthew G. Knepley mesh = (DM_Plex *) dm->data; 4108412e9a14SMatthew G. Knepley ierr = DMCreateLabel(dm, "celltype");CHKERRQ(ierr); 4109412e9a14SMatthew G. Knepley ierr = DMPlexGetCellTypeLabel(dm, &ctLabel);CHKERRQ(ierr); 4110412e9a14SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 4111412e9a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 4112327c2912SStefano Zampini DMPolytopeType ct = DM_POLYTOPE_UNKNOWN; 4113412e9a14SMatthew G. Knepley PetscInt pdepth; 4114412e9a14SMatthew G. Knepley 4115412e9a14SMatthew G. Knepley ierr = DMPlexGetPointDepth(dm, p, &pdepth);CHKERRQ(ierr); 4116412e9a14SMatthew G. Knepley ierr = DMPlexComputeCellType_Internal(dm, p, pdepth, &ct);CHKERRQ(ierr); 41172c71b3e2SJacob Faibussowitsch PetscCheckFalse(ct == DM_POLYTOPE_UNKNOWN,PETSC_COMM_SELF, PETSC_ERR_SUP, "Point %D is screwed up", p); 4118412e9a14SMatthew G. Knepley ierr = DMLabelSetValue(ctLabel, p, ct);CHKERRQ(ierr); 4119412e9a14SMatthew G. Knepley } 4120412e9a14SMatthew G. Knepley ierr = PetscObjectStateGet((PetscObject) ctLabel, &mesh->celltypeState);CHKERRQ(ierr); 4121412e9a14SMatthew G. Knepley ierr = PetscObjectViewFromOptions((PetscObject) ctLabel, NULL, "-dm_plex_celltypes_view");CHKERRQ(ierr); 4122ba2698f1SMatthew G. Knepley PetscFunctionReturn(0); 4123ba2698f1SMatthew G. Knepley } 4124ba2698f1SMatthew G. Knepley 4125552f7358SJed Brown /*@C 4126552f7358SJed Brown DMPlexGetJoin - Get an array for the join of the set of points 4127552f7358SJed Brown 4128552f7358SJed Brown Not Collective 4129552f7358SJed Brown 4130552f7358SJed Brown Input Parameters: 4131552f7358SJed Brown + dm - The DMPlex object 4132552f7358SJed Brown . numPoints - The number of input points for the join 4133552f7358SJed Brown - points - The input points 4134552f7358SJed Brown 4135552f7358SJed Brown Output Parameters: 4136552f7358SJed Brown + numCoveredPoints - The number of points in the join 4137552f7358SJed Brown - coveredPoints - The points in the join 4138552f7358SJed Brown 4139552f7358SJed Brown Level: intermediate 4140552f7358SJed Brown 4141552f7358SJed Brown Note: Currently, this is restricted to a single level join 4142552f7358SJed Brown 41433813dfbdSMatthew G Knepley Fortran Notes: 41443813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 41453813dfbdSMatthew G Knepley include petsc.h90 in your code. 41463813dfbdSMatthew G Knepley 41473813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 41483813dfbdSMatthew G Knepley 4149552f7358SJed Brown .seealso: DMPlexRestoreJoin(), DMPlexGetMeet() 4150552f7358SJed Brown @*/ 4151552f7358SJed Brown PetscErrorCode DMPlexGetJoin(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 4152552f7358SJed Brown { 4153552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 4154552f7358SJed Brown PetscInt *join[2]; 4155552f7358SJed Brown PetscInt joinSize, i = 0; 4156552f7358SJed Brown PetscInt dof, off, p, c, m; 4157552f7358SJed Brown PetscErrorCode ierr; 4158552f7358SJed Brown 4159552f7358SJed Brown PetscFunctionBegin; 4160552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 416148bb261cSVaclav Hapla PetscValidIntPointer(points, 3); 416248bb261cSVaclav Hapla PetscValidIntPointer(numCoveredPoints, 4); 416348bb261cSVaclav Hapla PetscValidPointer(coveredPoints, 5); 416469291d52SBarry Smith ierr = DMGetWorkArray(dm, mesh->maxSupportSize, MPIU_INT, &join[0]);CHKERRQ(ierr); 416569291d52SBarry Smith ierr = DMGetWorkArray(dm, mesh->maxSupportSize, MPIU_INT, &join[1]);CHKERRQ(ierr); 4166552f7358SJed Brown /* Copy in support of first point */ 4167552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, points[0], &dof);CHKERRQ(ierr); 4168552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, points[0], &off);CHKERRQ(ierr); 4169552f7358SJed Brown for (joinSize = 0; joinSize < dof; ++joinSize) { 4170552f7358SJed Brown join[i][joinSize] = mesh->supports[off+joinSize]; 4171552f7358SJed Brown } 4172552f7358SJed Brown /* Check each successive support */ 4173552f7358SJed Brown for (p = 1; p < numPoints; ++p) { 4174552f7358SJed Brown PetscInt newJoinSize = 0; 4175552f7358SJed Brown 4176552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, points[p], &dof);CHKERRQ(ierr); 4177552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, points[p], &off);CHKERRQ(ierr); 4178552f7358SJed Brown for (c = 0; c < dof; ++c) { 4179552f7358SJed Brown const PetscInt point = mesh->supports[off+c]; 4180552f7358SJed Brown 4181552f7358SJed Brown for (m = 0; m < joinSize; ++m) { 4182552f7358SJed Brown if (point == join[i][m]) { 4183552f7358SJed Brown join[1-i][newJoinSize++] = point; 4184552f7358SJed Brown break; 4185552f7358SJed Brown } 4186552f7358SJed Brown } 4187552f7358SJed Brown } 4188552f7358SJed Brown joinSize = newJoinSize; 4189552f7358SJed Brown i = 1-i; 4190552f7358SJed Brown } 4191552f7358SJed Brown *numCoveredPoints = joinSize; 4192552f7358SJed Brown *coveredPoints = join[i]; 419369291d52SBarry Smith ierr = DMRestoreWorkArray(dm, mesh->maxSupportSize, MPIU_INT, &join[1-i]);CHKERRQ(ierr); 4194552f7358SJed Brown PetscFunctionReturn(0); 4195552f7358SJed Brown } 4196552f7358SJed Brown 4197552f7358SJed Brown /*@C 4198552f7358SJed Brown DMPlexRestoreJoin - Restore an array for the join of the set of points 4199552f7358SJed Brown 4200552f7358SJed Brown Not Collective 4201552f7358SJed Brown 4202552f7358SJed Brown Input Parameters: 4203552f7358SJed Brown + dm - The DMPlex object 4204552f7358SJed Brown . numPoints - The number of input points for the join 4205552f7358SJed Brown - points - The input points 4206552f7358SJed Brown 4207552f7358SJed Brown Output Parameters: 4208552f7358SJed Brown + numCoveredPoints - The number of points in the join 4209552f7358SJed Brown - coveredPoints - The points in the join 4210552f7358SJed Brown 42113813dfbdSMatthew G Knepley Fortran Notes: 42123813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 42133813dfbdSMatthew G Knepley include petsc.h90 in your code. 42143813dfbdSMatthew G Knepley 42153813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 42163813dfbdSMatthew G Knepley 4217552f7358SJed Brown Level: intermediate 4218552f7358SJed Brown 4219552f7358SJed Brown .seealso: DMPlexGetJoin(), DMPlexGetFullJoin(), DMPlexGetMeet() 4220552f7358SJed Brown @*/ 4221552f7358SJed Brown PetscErrorCode DMPlexRestoreJoin(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 4222552f7358SJed Brown { 4223552f7358SJed Brown PetscErrorCode ierr; 4224552f7358SJed Brown 4225552f7358SJed Brown PetscFunctionBegin; 4226552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4227d7902bd2SMatthew G. Knepley if (points) PetscValidIntPointer(points,3); 4228d7902bd2SMatthew G. Knepley if (numCoveredPoints) PetscValidIntPointer(numCoveredPoints,4); 4229d7902bd2SMatthew G. Knepley PetscValidPointer(coveredPoints, 5); 423069291d52SBarry Smith ierr = DMRestoreWorkArray(dm, 0, MPIU_INT, (void*) coveredPoints);CHKERRQ(ierr); 4231d7902bd2SMatthew G. Knepley if (numCoveredPoints) *numCoveredPoints = 0; 4232552f7358SJed Brown PetscFunctionReturn(0); 4233552f7358SJed Brown } 4234552f7358SJed Brown 4235552f7358SJed Brown /*@C 4236552f7358SJed Brown DMPlexGetFullJoin - Get an array for the join of the set of points 4237552f7358SJed Brown 4238552f7358SJed Brown Not Collective 4239552f7358SJed Brown 4240552f7358SJed Brown Input Parameters: 4241552f7358SJed Brown + dm - The DMPlex object 4242552f7358SJed Brown . numPoints - The number of input points for the join 4243552f7358SJed Brown - points - The input points 4244552f7358SJed Brown 4245552f7358SJed Brown Output Parameters: 4246552f7358SJed Brown + numCoveredPoints - The number of points in the join 4247552f7358SJed Brown - coveredPoints - The points in the join 4248552f7358SJed Brown 42493813dfbdSMatthew G Knepley Fortran Notes: 42503813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 42513813dfbdSMatthew G Knepley include petsc.h90 in your code. 42523813dfbdSMatthew G Knepley 42533813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 42543813dfbdSMatthew G Knepley 4255552f7358SJed Brown Level: intermediate 4256552f7358SJed Brown 4257552f7358SJed Brown .seealso: DMPlexGetJoin(), DMPlexRestoreJoin(), DMPlexGetMeet() 4258552f7358SJed Brown @*/ 4259552f7358SJed Brown PetscErrorCode DMPlexGetFullJoin(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 4260552f7358SJed Brown { 4261552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 4262552f7358SJed Brown PetscInt *offsets, **closures; 4263552f7358SJed Brown PetscInt *join[2]; 4264552f7358SJed Brown PetscInt depth = 0, maxSize, joinSize = 0, i = 0; 426524c766afSToby Isaac PetscInt p, d, c, m, ms; 4266552f7358SJed Brown PetscErrorCode ierr; 4267552f7358SJed Brown 4268552f7358SJed Brown PetscFunctionBegin; 4269552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 427048bb261cSVaclav Hapla PetscValidIntPointer(points, 3); 427148bb261cSVaclav Hapla PetscValidIntPointer(numCoveredPoints, 4); 427248bb261cSVaclav Hapla PetscValidPointer(coveredPoints, 5); 4273552f7358SJed Brown 4274552f7358SJed Brown ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 42751795a4d1SJed Brown ierr = PetscCalloc1(numPoints, &closures);CHKERRQ(ierr); 427669291d52SBarry Smith ierr = DMGetWorkArray(dm, numPoints*(depth+2), MPIU_INT, &offsets);CHKERRQ(ierr); 427724c766afSToby Isaac ms = mesh->maxSupportSize; 427824c766afSToby Isaac maxSize = (ms > 1) ? ((PetscPowInt(ms,depth+1)-1)/(ms-1)) : depth + 1; 427969291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &join[0]);CHKERRQ(ierr); 428069291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &join[1]);CHKERRQ(ierr); 4281552f7358SJed Brown 4282552f7358SJed Brown for (p = 0; p < numPoints; ++p) { 4283552f7358SJed Brown PetscInt closureSize; 4284552f7358SJed Brown 4285552f7358SJed Brown ierr = DMPlexGetTransitiveClosure(dm, points[p], PETSC_FALSE, &closureSize, &closures[p]);CHKERRQ(ierr); 42860d644c17SKarl Rupp 4287552f7358SJed Brown offsets[p*(depth+2)+0] = 0; 4288552f7358SJed Brown for (d = 0; d < depth+1; ++d) { 4289552f7358SJed Brown PetscInt pStart, pEnd, i; 4290552f7358SJed Brown 4291552f7358SJed Brown ierr = DMPlexGetDepthStratum(dm, d, &pStart, &pEnd);CHKERRQ(ierr); 4292552f7358SJed Brown for (i = offsets[p*(depth+2)+d]; i < closureSize; ++i) { 4293552f7358SJed Brown if ((pStart > closures[p][i*2]) || (pEnd <= closures[p][i*2])) { 4294552f7358SJed Brown offsets[p*(depth+2)+d+1] = i; 4295552f7358SJed Brown break; 4296552f7358SJed Brown } 4297552f7358SJed Brown } 4298552f7358SJed Brown if (i == closureSize) offsets[p*(depth+2)+d+1] = i; 4299552f7358SJed Brown } 43002c71b3e2SJacob 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); 4301552f7358SJed Brown } 4302552f7358SJed Brown for (d = 0; d < depth+1; ++d) { 4303552f7358SJed Brown PetscInt dof; 4304552f7358SJed Brown 4305552f7358SJed Brown /* Copy in support of first point */ 4306552f7358SJed Brown dof = offsets[d+1] - offsets[d]; 4307552f7358SJed Brown for (joinSize = 0; joinSize < dof; ++joinSize) { 4308552f7358SJed Brown join[i][joinSize] = closures[0][(offsets[d]+joinSize)*2]; 4309552f7358SJed Brown } 4310552f7358SJed Brown /* Check each successive cone */ 4311552f7358SJed Brown for (p = 1; p < numPoints && joinSize; ++p) { 4312552f7358SJed Brown PetscInt newJoinSize = 0; 4313552f7358SJed Brown 4314552f7358SJed Brown dof = offsets[p*(depth+2)+d+1] - offsets[p*(depth+2)+d]; 4315552f7358SJed Brown for (c = 0; c < dof; ++c) { 4316552f7358SJed Brown const PetscInt point = closures[p][(offsets[p*(depth+2)+d]+c)*2]; 4317552f7358SJed Brown 4318552f7358SJed Brown for (m = 0; m < joinSize; ++m) { 4319552f7358SJed Brown if (point == join[i][m]) { 4320552f7358SJed Brown join[1-i][newJoinSize++] = point; 4321552f7358SJed Brown break; 4322552f7358SJed Brown } 4323552f7358SJed Brown } 4324552f7358SJed Brown } 4325552f7358SJed Brown joinSize = newJoinSize; 4326552f7358SJed Brown i = 1-i; 4327552f7358SJed Brown } 4328552f7358SJed Brown if (joinSize) break; 4329552f7358SJed Brown } 4330552f7358SJed Brown *numCoveredPoints = joinSize; 4331552f7358SJed Brown *coveredPoints = join[i]; 4332552f7358SJed Brown for (p = 0; p < numPoints; ++p) { 43330298fd71SBarry Smith ierr = DMPlexRestoreTransitiveClosure(dm, points[p], PETSC_FALSE, NULL, &closures[p]);CHKERRQ(ierr); 4334552f7358SJed Brown } 4335552f7358SJed Brown ierr = PetscFree(closures);CHKERRQ(ierr); 433669291d52SBarry Smith ierr = DMRestoreWorkArray(dm, numPoints*(depth+2), MPIU_INT, &offsets);CHKERRQ(ierr); 433769291d52SBarry Smith ierr = DMRestoreWorkArray(dm, mesh->maxSupportSize, MPIU_INT, &join[1-i]);CHKERRQ(ierr); 4338552f7358SJed Brown PetscFunctionReturn(0); 4339552f7358SJed Brown } 4340552f7358SJed Brown 4341552f7358SJed Brown /*@C 4342552f7358SJed Brown DMPlexGetMeet - Get an array for the meet of the set of points 4343552f7358SJed Brown 4344552f7358SJed Brown Not Collective 4345552f7358SJed Brown 4346552f7358SJed Brown Input Parameters: 4347552f7358SJed Brown + dm - The DMPlex object 4348552f7358SJed Brown . numPoints - The number of input points for the meet 4349552f7358SJed Brown - points - The input points 4350552f7358SJed Brown 4351552f7358SJed Brown Output Parameters: 4352552f7358SJed Brown + numCoveredPoints - The number of points in the meet 4353552f7358SJed Brown - coveredPoints - The points in the meet 4354552f7358SJed Brown 4355552f7358SJed Brown Level: intermediate 4356552f7358SJed Brown 4357552f7358SJed Brown Note: Currently, this is restricted to a single level meet 4358552f7358SJed Brown 43593813dfbdSMatthew G Knepley Fortran Notes: 43603813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 43613813dfbdSMatthew G Knepley include petsc.h90 in your code. 43623813dfbdSMatthew G Knepley 43633813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 43643813dfbdSMatthew G Knepley 4365552f7358SJed Brown .seealso: DMPlexRestoreMeet(), DMPlexGetJoin() 4366552f7358SJed Brown @*/ 4367552f7358SJed Brown PetscErrorCode DMPlexGetMeet(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveringPoints, const PetscInt **coveringPoints) 4368552f7358SJed Brown { 4369552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 4370552f7358SJed Brown PetscInt *meet[2]; 4371552f7358SJed Brown PetscInt meetSize, i = 0; 4372552f7358SJed Brown PetscInt dof, off, p, c, m; 4373552f7358SJed Brown PetscErrorCode ierr; 4374552f7358SJed Brown 4375552f7358SJed Brown PetscFunctionBegin; 4376552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4377064a246eSJacob Faibussowitsch PetscValidPointer(points, 3); 4378064a246eSJacob Faibussowitsch PetscValidPointer(numCoveringPoints, 4); 4379064a246eSJacob Faibussowitsch PetscValidPointer(coveringPoints, 5); 438069291d52SBarry Smith ierr = DMGetWorkArray(dm, mesh->maxConeSize, MPIU_INT, &meet[0]);CHKERRQ(ierr); 438169291d52SBarry Smith ierr = DMGetWorkArray(dm, mesh->maxConeSize, MPIU_INT, &meet[1]);CHKERRQ(ierr); 4382552f7358SJed Brown /* Copy in cone of first point */ 4383552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, points[0], &dof);CHKERRQ(ierr); 4384552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, points[0], &off);CHKERRQ(ierr); 4385552f7358SJed Brown for (meetSize = 0; meetSize < dof; ++meetSize) { 4386552f7358SJed Brown meet[i][meetSize] = mesh->cones[off+meetSize]; 4387552f7358SJed Brown } 4388552f7358SJed Brown /* Check each successive cone */ 4389552f7358SJed Brown for (p = 1; p < numPoints; ++p) { 4390552f7358SJed Brown PetscInt newMeetSize = 0; 4391552f7358SJed Brown 4392552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, points[p], &dof);CHKERRQ(ierr); 4393552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, points[p], &off);CHKERRQ(ierr); 4394552f7358SJed Brown for (c = 0; c < dof; ++c) { 4395552f7358SJed Brown const PetscInt point = mesh->cones[off+c]; 4396552f7358SJed Brown 4397552f7358SJed Brown for (m = 0; m < meetSize; ++m) { 4398552f7358SJed Brown if (point == meet[i][m]) { 4399552f7358SJed Brown meet[1-i][newMeetSize++] = point; 4400552f7358SJed Brown break; 4401552f7358SJed Brown } 4402552f7358SJed Brown } 4403552f7358SJed Brown } 4404552f7358SJed Brown meetSize = newMeetSize; 4405552f7358SJed Brown i = 1-i; 4406552f7358SJed Brown } 4407552f7358SJed Brown *numCoveringPoints = meetSize; 4408552f7358SJed Brown *coveringPoints = meet[i]; 440969291d52SBarry Smith ierr = DMRestoreWorkArray(dm, mesh->maxConeSize, MPIU_INT, &meet[1-i]);CHKERRQ(ierr); 4410552f7358SJed Brown PetscFunctionReturn(0); 4411552f7358SJed Brown } 4412552f7358SJed Brown 4413552f7358SJed Brown /*@C 4414552f7358SJed Brown DMPlexRestoreMeet - Restore an array for the meet of the set of points 4415552f7358SJed Brown 4416552f7358SJed Brown Not Collective 4417552f7358SJed Brown 4418552f7358SJed Brown Input Parameters: 4419552f7358SJed Brown + dm - The DMPlex object 4420552f7358SJed Brown . numPoints - The number of input points for the meet 4421552f7358SJed Brown - points - The input points 4422552f7358SJed Brown 4423552f7358SJed Brown Output Parameters: 4424552f7358SJed Brown + numCoveredPoints - The number of points in the meet 4425552f7358SJed Brown - coveredPoints - The points in the meet 4426552f7358SJed Brown 4427552f7358SJed Brown Level: intermediate 4428552f7358SJed Brown 44293813dfbdSMatthew G Knepley Fortran Notes: 44303813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 44313813dfbdSMatthew G Knepley include petsc.h90 in your code. 44323813dfbdSMatthew G Knepley 44333813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 44343813dfbdSMatthew G Knepley 4435552f7358SJed Brown .seealso: DMPlexGetMeet(), DMPlexGetFullMeet(), DMPlexGetJoin() 4436552f7358SJed Brown @*/ 4437552f7358SJed Brown PetscErrorCode DMPlexRestoreMeet(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 4438552f7358SJed Brown { 4439552f7358SJed Brown PetscErrorCode ierr; 4440552f7358SJed Brown 4441552f7358SJed Brown PetscFunctionBegin; 4442552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4443d7902bd2SMatthew G. Knepley if (points) PetscValidIntPointer(points,3); 4444d7902bd2SMatthew G. Knepley if (numCoveredPoints) PetscValidIntPointer(numCoveredPoints,4); 4445d7902bd2SMatthew G. Knepley PetscValidPointer(coveredPoints,5); 444669291d52SBarry Smith ierr = DMRestoreWorkArray(dm, 0, MPIU_INT, (void*) coveredPoints);CHKERRQ(ierr); 4447d7902bd2SMatthew G. Knepley if (numCoveredPoints) *numCoveredPoints = 0; 4448552f7358SJed Brown PetscFunctionReturn(0); 4449552f7358SJed Brown } 4450552f7358SJed Brown 4451552f7358SJed Brown /*@C 4452552f7358SJed Brown DMPlexGetFullMeet - Get an array for the meet of the set of points 4453552f7358SJed Brown 4454552f7358SJed Brown Not Collective 4455552f7358SJed Brown 4456552f7358SJed Brown Input Parameters: 4457552f7358SJed Brown + dm - The DMPlex object 4458552f7358SJed Brown . numPoints - The number of input points for the meet 4459552f7358SJed Brown - points - The input points 4460552f7358SJed Brown 4461552f7358SJed Brown Output Parameters: 4462552f7358SJed Brown + numCoveredPoints - The number of points in the meet 4463552f7358SJed Brown - coveredPoints - The points in the meet 4464552f7358SJed Brown 4465552f7358SJed Brown Level: intermediate 4466552f7358SJed Brown 44673813dfbdSMatthew G Knepley Fortran Notes: 44683813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 44693813dfbdSMatthew G Knepley include petsc.h90 in your code. 44703813dfbdSMatthew G Knepley 44713813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 44723813dfbdSMatthew G Knepley 4473552f7358SJed Brown .seealso: DMPlexGetMeet(), DMPlexRestoreMeet(), DMPlexGetJoin() 4474552f7358SJed Brown @*/ 4475552f7358SJed Brown PetscErrorCode DMPlexGetFullMeet(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 4476552f7358SJed Brown { 4477552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 4478552f7358SJed Brown PetscInt *offsets, **closures; 4479552f7358SJed Brown PetscInt *meet[2]; 4480552f7358SJed Brown PetscInt height = 0, maxSize, meetSize = 0, i = 0; 448124c766afSToby Isaac PetscInt p, h, c, m, mc; 4482552f7358SJed Brown PetscErrorCode ierr; 4483552f7358SJed Brown 4484552f7358SJed Brown PetscFunctionBegin; 4485552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4486064a246eSJacob Faibussowitsch PetscValidPointer(points, 3); 4487064a246eSJacob Faibussowitsch PetscValidPointer(numCoveredPoints, 4); 4488064a246eSJacob Faibussowitsch PetscValidPointer(coveredPoints, 5); 4489552f7358SJed Brown 4490552f7358SJed Brown ierr = DMPlexGetDepth(dm, &height);CHKERRQ(ierr); 4491785e854fSJed Brown ierr = PetscMalloc1(numPoints, &closures);CHKERRQ(ierr); 449269291d52SBarry Smith ierr = DMGetWorkArray(dm, numPoints*(height+2), MPIU_INT, &offsets);CHKERRQ(ierr); 449324c766afSToby Isaac mc = mesh->maxConeSize; 449424c766afSToby Isaac maxSize = (mc > 1) ? ((PetscPowInt(mc,height+1)-1)/(mc-1)) : height + 1; 449569291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &meet[0]);CHKERRQ(ierr); 449669291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &meet[1]);CHKERRQ(ierr); 4497552f7358SJed Brown 4498552f7358SJed Brown for (p = 0; p < numPoints; ++p) { 4499552f7358SJed Brown PetscInt closureSize; 4500552f7358SJed Brown 4501552f7358SJed Brown ierr = DMPlexGetTransitiveClosure(dm, points[p], PETSC_TRUE, &closureSize, &closures[p]);CHKERRQ(ierr); 45020d644c17SKarl Rupp 4503552f7358SJed Brown offsets[p*(height+2)+0] = 0; 4504552f7358SJed Brown for (h = 0; h < height+1; ++h) { 4505552f7358SJed Brown PetscInt pStart, pEnd, i; 4506552f7358SJed Brown 4507552f7358SJed Brown ierr = DMPlexGetHeightStratum(dm, h, &pStart, &pEnd);CHKERRQ(ierr); 4508552f7358SJed Brown for (i = offsets[p*(height+2)+h]; i < closureSize; ++i) { 4509552f7358SJed Brown if ((pStart > closures[p][i*2]) || (pEnd <= closures[p][i*2])) { 4510552f7358SJed Brown offsets[p*(height+2)+h+1] = i; 4511552f7358SJed Brown break; 4512552f7358SJed Brown } 4513552f7358SJed Brown } 4514552f7358SJed Brown if (i == closureSize) offsets[p*(height+2)+h+1] = i; 4515552f7358SJed Brown } 45162c71b3e2SJacob 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); 4517552f7358SJed Brown } 4518552f7358SJed Brown for (h = 0; h < height+1; ++h) { 4519552f7358SJed Brown PetscInt dof; 4520552f7358SJed Brown 4521552f7358SJed Brown /* Copy in cone of first point */ 4522552f7358SJed Brown dof = offsets[h+1] - offsets[h]; 4523552f7358SJed Brown for (meetSize = 0; meetSize < dof; ++meetSize) { 4524552f7358SJed Brown meet[i][meetSize] = closures[0][(offsets[h]+meetSize)*2]; 4525552f7358SJed Brown } 4526552f7358SJed Brown /* Check each successive cone */ 4527552f7358SJed Brown for (p = 1; p < numPoints && meetSize; ++p) { 4528552f7358SJed Brown PetscInt newMeetSize = 0; 4529552f7358SJed Brown 4530552f7358SJed Brown dof = offsets[p*(height+2)+h+1] - offsets[p*(height+2)+h]; 4531552f7358SJed Brown for (c = 0; c < dof; ++c) { 4532552f7358SJed Brown const PetscInt point = closures[p][(offsets[p*(height+2)+h]+c)*2]; 4533552f7358SJed Brown 4534552f7358SJed Brown for (m = 0; m < meetSize; ++m) { 4535552f7358SJed Brown if (point == meet[i][m]) { 4536552f7358SJed Brown meet[1-i][newMeetSize++] = point; 4537552f7358SJed Brown break; 4538552f7358SJed Brown } 4539552f7358SJed Brown } 4540552f7358SJed Brown } 4541552f7358SJed Brown meetSize = newMeetSize; 4542552f7358SJed Brown i = 1-i; 4543552f7358SJed Brown } 4544552f7358SJed Brown if (meetSize) break; 4545552f7358SJed Brown } 4546552f7358SJed Brown *numCoveredPoints = meetSize; 4547552f7358SJed Brown *coveredPoints = meet[i]; 4548552f7358SJed Brown for (p = 0; p < numPoints; ++p) { 45490298fd71SBarry Smith ierr = DMPlexRestoreTransitiveClosure(dm, points[p], PETSC_TRUE, NULL, &closures[p]);CHKERRQ(ierr); 4550552f7358SJed Brown } 4551552f7358SJed Brown ierr = PetscFree(closures);CHKERRQ(ierr); 455269291d52SBarry Smith ierr = DMRestoreWorkArray(dm, numPoints*(height+2), MPIU_INT, &offsets);CHKERRQ(ierr); 455369291d52SBarry Smith ierr = DMRestoreWorkArray(dm, mesh->maxConeSize, MPIU_INT, &meet[1-i]);CHKERRQ(ierr); 4554552f7358SJed Brown PetscFunctionReturn(0); 4555552f7358SJed Brown } 4556552f7358SJed Brown 45574e3744c5SMatthew G. Knepley /*@C 45584e3744c5SMatthew G. Knepley DMPlexEqual - Determine if two DMs have the same topology 45594e3744c5SMatthew G. Knepley 45604e3744c5SMatthew G. Knepley Not Collective 45614e3744c5SMatthew G. Knepley 45624e3744c5SMatthew G. Knepley Input Parameters: 45634e3744c5SMatthew G. Knepley + dmA - A DMPlex object 45644e3744c5SMatthew G. Knepley - dmB - A DMPlex object 45654e3744c5SMatthew G. Knepley 45664e3744c5SMatthew G. Knepley Output Parameters: 45674e3744c5SMatthew G. Knepley . equal - PETSC_TRUE if the topologies are identical 45684e3744c5SMatthew G. Knepley 45694e3744c5SMatthew G. Knepley Level: intermediate 45704e3744c5SMatthew G. Knepley 45714e3744c5SMatthew G. Knepley Notes: 45724e3744c5SMatthew G. Knepley We are not solving graph isomorphism, so we do not permutation. 45734e3744c5SMatthew G. Knepley 45744e3744c5SMatthew G. Knepley .seealso: DMPlexGetCone() 45754e3744c5SMatthew G. Knepley @*/ 45764e3744c5SMatthew G. Knepley PetscErrorCode DMPlexEqual(DM dmA, DM dmB, PetscBool *equal) 45774e3744c5SMatthew G. Knepley { 45784e3744c5SMatthew G. Knepley PetscInt depth, depthB, pStart, pEnd, pStartB, pEndB, p; 45794e3744c5SMatthew G. Knepley PetscErrorCode ierr; 45804e3744c5SMatthew G. Knepley 45814e3744c5SMatthew G. Knepley PetscFunctionBegin; 45824e3744c5SMatthew G. Knepley PetscValidHeaderSpecific(dmA, DM_CLASSID, 1); 45834e3744c5SMatthew G. Knepley PetscValidHeaderSpecific(dmB, DM_CLASSID, 2); 45844e3744c5SMatthew G. Knepley PetscValidPointer(equal, 3); 45854e3744c5SMatthew G. Knepley 45864e3744c5SMatthew G. Knepley *equal = PETSC_FALSE; 45874e3744c5SMatthew G. Knepley ierr = DMPlexGetDepth(dmA, &depth);CHKERRQ(ierr); 45884e3744c5SMatthew G. Knepley ierr = DMPlexGetDepth(dmB, &depthB);CHKERRQ(ierr); 45894e3744c5SMatthew G. Knepley if (depth != depthB) PetscFunctionReturn(0); 45904e3744c5SMatthew G. Knepley ierr = DMPlexGetChart(dmA, &pStart, &pEnd);CHKERRQ(ierr); 45914e3744c5SMatthew G. Knepley ierr = DMPlexGetChart(dmB, &pStartB, &pEndB);CHKERRQ(ierr); 45924e3744c5SMatthew G. Knepley if ((pStart != pStartB) || (pEnd != pEndB)) PetscFunctionReturn(0); 45934e3744c5SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 45944e3744c5SMatthew G. Knepley const PetscInt *cone, *coneB, *ornt, *orntB, *support, *supportB; 45954e3744c5SMatthew G. Knepley PetscInt coneSize, coneSizeB, c, supportSize, supportSizeB, s; 45964e3744c5SMatthew G. Knepley 45974e3744c5SMatthew G. Knepley ierr = DMPlexGetConeSize(dmA, p, &coneSize);CHKERRQ(ierr); 45984e3744c5SMatthew G. Knepley ierr = DMPlexGetCone(dmA, p, &cone);CHKERRQ(ierr); 45994e3744c5SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dmA, p, &ornt);CHKERRQ(ierr); 46004e3744c5SMatthew G. Knepley ierr = DMPlexGetConeSize(dmB, p, &coneSizeB);CHKERRQ(ierr); 46014e3744c5SMatthew G. Knepley ierr = DMPlexGetCone(dmB, p, &coneB);CHKERRQ(ierr); 46024e3744c5SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dmB, p, &orntB);CHKERRQ(ierr); 46034e3744c5SMatthew G. Knepley if (coneSize != coneSizeB) PetscFunctionReturn(0); 46044e3744c5SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 46054e3744c5SMatthew G. Knepley if (cone[c] != coneB[c]) PetscFunctionReturn(0); 46064e3744c5SMatthew G. Knepley if (ornt[c] != orntB[c]) PetscFunctionReturn(0); 46074e3744c5SMatthew G. Knepley } 46084e3744c5SMatthew G. Knepley ierr = DMPlexGetSupportSize(dmA, p, &supportSize);CHKERRQ(ierr); 46094e3744c5SMatthew G. Knepley ierr = DMPlexGetSupport(dmA, p, &support);CHKERRQ(ierr); 46104e3744c5SMatthew G. Knepley ierr = DMPlexGetSupportSize(dmB, p, &supportSizeB);CHKERRQ(ierr); 46114e3744c5SMatthew G. Knepley ierr = DMPlexGetSupport(dmB, p, &supportB);CHKERRQ(ierr); 46124e3744c5SMatthew G. Knepley if (supportSize != supportSizeB) PetscFunctionReturn(0); 46134e3744c5SMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 46144e3744c5SMatthew G. Knepley if (support[s] != supportB[s]) PetscFunctionReturn(0); 46154e3744c5SMatthew G. Knepley } 46164e3744c5SMatthew G. Knepley } 46174e3744c5SMatthew G. Knepley *equal = PETSC_TRUE; 46184e3744c5SMatthew G. Knepley PetscFunctionReturn(0); 46194e3744c5SMatthew G. Knepley } 46204e3744c5SMatthew G. Knepley 46217cd05799SMatthew G. Knepley /*@C 46227cd05799SMatthew G. Knepley DMPlexGetNumFaceVertices - Returns the number of vertices on a face 46237cd05799SMatthew G. Knepley 46247cd05799SMatthew G. Knepley Not Collective 46257cd05799SMatthew G. Knepley 46267cd05799SMatthew G. Knepley Input Parameters: 46277cd05799SMatthew G. Knepley + dm - The DMPlex 46287cd05799SMatthew G. Knepley . cellDim - The cell dimension 46297cd05799SMatthew G. Knepley - numCorners - The number of vertices on a cell 46307cd05799SMatthew G. Knepley 46317cd05799SMatthew G. Knepley Output Parameters: 46327cd05799SMatthew G. Knepley . numFaceVertices - The number of vertices on a face 46337cd05799SMatthew G. Knepley 46347cd05799SMatthew G. Knepley Level: developer 46357cd05799SMatthew G. Knepley 46367cd05799SMatthew G. Knepley Notes: 46377cd05799SMatthew G. Knepley Of course this can only work for a restricted set of symmetric shapes 46387cd05799SMatthew G. Knepley 46397cd05799SMatthew G. Knepley .seealso: DMPlexGetCone() 46407cd05799SMatthew G. Knepley @*/ 464118ad9376SMatthew G. Knepley PetscErrorCode DMPlexGetNumFaceVertices(DM dm, PetscInt cellDim, PetscInt numCorners, PetscInt *numFaceVertices) 4642a6dfd86eSKarl Rupp { 464382f516ccSBarry Smith MPI_Comm comm; 4644552f7358SJed Brown PetscErrorCode ierr; 4645552f7358SJed Brown 4646552f7358SJed Brown PetscFunctionBegin; 464782f516ccSBarry Smith ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 4648064a246eSJacob Faibussowitsch PetscValidPointer(numFaceVertices,4); 4649552f7358SJed Brown switch (cellDim) { 4650552f7358SJed Brown case 0: 4651552f7358SJed Brown *numFaceVertices = 0; 4652552f7358SJed Brown break; 4653552f7358SJed Brown case 1: 4654552f7358SJed Brown *numFaceVertices = 1; 4655552f7358SJed Brown break; 4656552f7358SJed Brown case 2: 4657552f7358SJed Brown switch (numCorners) { 465819436ca2SJed Brown case 3: /* triangle */ 465919436ca2SJed Brown *numFaceVertices = 2; /* Edge has 2 vertices */ 4660552f7358SJed Brown break; 466119436ca2SJed Brown case 4: /* quadrilateral */ 466219436ca2SJed Brown *numFaceVertices = 2; /* Edge has 2 vertices */ 4663552f7358SJed Brown break; 466419436ca2SJed Brown case 6: /* quadratic triangle, tri and quad cohesive Lagrange cells */ 466519436ca2SJed Brown *numFaceVertices = 3; /* Edge has 3 vertices */ 4666552f7358SJed Brown break; 466719436ca2SJed Brown case 9: /* quadratic quadrilateral, quadratic quad cohesive Lagrange cells */ 466819436ca2SJed Brown *numFaceVertices = 3; /* Edge has 3 vertices */ 4669552f7358SJed Brown break; 4670552f7358SJed Brown default: 467198921bdaSJacob Faibussowitsch SETERRQ(comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid number of face corners %D for dimension %D", numCorners, cellDim); 4672552f7358SJed Brown } 4673552f7358SJed Brown break; 4674552f7358SJed Brown case 3: 4675552f7358SJed Brown switch (numCorners) { 467619436ca2SJed Brown case 4: /* tetradehdron */ 467719436ca2SJed Brown *numFaceVertices = 3; /* Face has 3 vertices */ 4678552f7358SJed Brown break; 467919436ca2SJed Brown case 6: /* tet cohesive cells */ 468019436ca2SJed Brown *numFaceVertices = 4; /* Face has 4 vertices */ 4681552f7358SJed Brown break; 468219436ca2SJed Brown case 8: /* hexahedron */ 468319436ca2SJed Brown *numFaceVertices = 4; /* Face has 4 vertices */ 4684552f7358SJed Brown break; 468519436ca2SJed Brown case 9: /* tet cohesive Lagrange cells */ 468619436ca2SJed Brown *numFaceVertices = 6; /* Face has 6 vertices */ 4687552f7358SJed Brown break; 468819436ca2SJed Brown case 10: /* quadratic tetrahedron */ 468919436ca2SJed Brown *numFaceVertices = 6; /* Face has 6 vertices */ 4690552f7358SJed Brown break; 469119436ca2SJed Brown case 12: /* hex cohesive Lagrange cells */ 469219436ca2SJed Brown *numFaceVertices = 6; /* Face has 6 vertices */ 4693552f7358SJed Brown break; 469419436ca2SJed Brown case 18: /* quadratic tet cohesive Lagrange cells */ 469519436ca2SJed Brown *numFaceVertices = 6; /* Face has 6 vertices */ 4696552f7358SJed Brown break; 469719436ca2SJed Brown case 27: /* quadratic hexahedron, quadratic hex cohesive Lagrange cells */ 469819436ca2SJed Brown *numFaceVertices = 9; /* Face has 9 vertices */ 4699552f7358SJed Brown break; 4700552f7358SJed Brown default: 470198921bdaSJacob Faibussowitsch SETERRQ(comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid number of face corners %D for dimension %D", numCorners, cellDim); 4702552f7358SJed Brown } 4703552f7358SJed Brown break; 4704552f7358SJed Brown default: 470598921bdaSJacob Faibussowitsch SETERRQ(comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid cell dimension %D", cellDim); 4706552f7358SJed Brown } 4707552f7358SJed Brown PetscFunctionReturn(0); 4708552f7358SJed Brown } 4709552f7358SJed Brown 4710552f7358SJed Brown /*@ 4711aa50250dSMatthew G. Knepley DMPlexGetDepthLabel - Get the DMLabel recording the depth of each point 4712552f7358SJed Brown 4713552f7358SJed Brown Not Collective 4714552f7358SJed Brown 4715aa50250dSMatthew G. Knepley Input Parameter: 4716552f7358SJed Brown . dm - The DMPlex object 4717552f7358SJed Brown 4718aa50250dSMatthew G. Knepley Output Parameter: 4719aa50250dSMatthew G. Knepley . depthLabel - The DMLabel recording point depth 4720552f7358SJed Brown 4721552f7358SJed Brown Level: developer 4722552f7358SJed Brown 4723dc287ab2SVaclav Hapla .seealso: DMPlexGetDepth(), DMPlexGetHeightStratum(), DMPlexGetDepthStratum(), DMPlexGetPointDepth(), 4724aa50250dSMatthew G. Knepley @*/ 4725aa50250dSMatthew G. Knepley PetscErrorCode DMPlexGetDepthLabel(DM dm, DMLabel *depthLabel) 4726aa50250dSMatthew G. Knepley { 4727aa50250dSMatthew G. Knepley PetscFunctionBegin; 4728aa50250dSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4729aa50250dSMatthew G. Knepley PetscValidPointer(depthLabel, 2); 4730c58f1c22SToby Isaac *depthLabel = dm->depthLabel; 4731aa50250dSMatthew G. Knepley PetscFunctionReturn(0); 4732aa50250dSMatthew G. Knepley } 4733aa50250dSMatthew G. Knepley 4734aa50250dSMatthew G. Knepley /*@ 4735aa50250dSMatthew G. Knepley DMPlexGetDepth - Get the depth of the DAG representing this mesh 4736aa50250dSMatthew G. Knepley 4737aa50250dSMatthew G. Knepley Not Collective 4738aa50250dSMatthew G. Knepley 4739aa50250dSMatthew G. Knepley Input Parameter: 4740aa50250dSMatthew G. Knepley . dm - The DMPlex object 4741aa50250dSMatthew G. Knepley 4742aa50250dSMatthew G. Knepley Output Parameter: 4743aa50250dSMatthew G. Knepley . depth - The number of strata (breadth first levels) in the DAG 4744aa50250dSMatthew G. Knepley 4745aa50250dSMatthew G. Knepley Level: developer 4746552f7358SJed Brown 4747b1bb481bSMatthew Knepley Notes: 4748b1bb481bSMatthew Knepley This returns maximum of point depths over all points, i.e. maximum value of the label returned by DMPlexGetDepthLabel(). 4749dc287ab2SVaclav Hapla The point depth is described more in detail in DMPlexGetDepthStratum(). 4750dc287ab2SVaclav Hapla An empty mesh gives -1. 4751b1bb481bSMatthew Knepley 4752dc287ab2SVaclav Hapla .seealso: DMPlexGetDepthLabel(), DMPlexGetDepthStratum(), DMPlexGetPointDepth(), DMPlexSymmetrize() 4753552f7358SJed Brown @*/ 4754552f7358SJed Brown PetscErrorCode DMPlexGetDepth(DM dm, PetscInt *depth) 4755552f7358SJed Brown { 4756aa50250dSMatthew G. Knepley DMLabel label; 4757aa50250dSMatthew G. Knepley PetscInt d = 0; 4758552f7358SJed Brown PetscErrorCode ierr; 4759552f7358SJed Brown 4760552f7358SJed Brown PetscFunctionBegin; 4761552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4762552f7358SJed Brown PetscValidPointer(depth, 2); 4763aa50250dSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 4764aa50250dSMatthew G. Knepley if (label) {ierr = DMLabelGetNumValues(label, &d);CHKERRQ(ierr);} 4765552f7358SJed Brown *depth = d-1; 4766552f7358SJed Brown PetscFunctionReturn(0); 4767552f7358SJed Brown } 4768552f7358SJed Brown 4769552f7358SJed Brown /*@ 4770552f7358SJed Brown DMPlexGetDepthStratum - Get the bounds [start, end) for all points at a certain depth. 4771552f7358SJed Brown 4772552f7358SJed Brown Not Collective 4773552f7358SJed Brown 4774552f7358SJed Brown Input Parameters: 4775552f7358SJed Brown + dm - The DMPlex object 4776552f7358SJed Brown - stratumValue - The requested depth 4777552f7358SJed Brown 4778552f7358SJed Brown Output Parameters: 4779552f7358SJed Brown + start - The first point at this depth 4780552f7358SJed Brown - end - One beyond the last point at this depth 4781552f7358SJed Brown 4782647867b2SJed Brown Notes: 4783647867b2SJed Brown Depth indexing is related to topological dimension. Depth stratum 0 contains the lowest topological dimension points, 4784647867b2SJed Brown often "vertices". If the mesh is "interpolated" (see DMPlexInterpolate()), then depth stratum 1 contains the next 4785647867b2SJed Brown higher dimension, e.g., "edges". 4786647867b2SJed Brown 4787552f7358SJed Brown Level: developer 4788552f7358SJed Brown 4789dc287ab2SVaclav Hapla .seealso: DMPlexGetHeightStratum(), DMPlexGetDepth(), DMPlexGetDepthLabel(), DMPlexGetPointDepth(), DMPlexSymmetrize(), DMPlexInterpolate() 4790552f7358SJed Brown @*/ 47910adebc6cSBarry Smith PetscErrorCode DMPlexGetDepthStratum(DM dm, PetscInt stratumValue, PetscInt *start, PetscInt *end) 47920adebc6cSBarry Smith { 4793aa50250dSMatthew G. Knepley DMLabel label; 479463d1a920SMatthew G. Knepley PetscInt pStart, pEnd; 4795552f7358SJed Brown PetscErrorCode ierr; 4796552f7358SJed Brown 4797552f7358SJed Brown PetscFunctionBegin; 4798552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 479963d1a920SMatthew G. Knepley if (start) {PetscValidPointer(start, 3); *start = 0;} 480063d1a920SMatthew G. Knepley if (end) {PetscValidPointer(end, 4); *end = 0;} 4801552f7358SJed Brown ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 48020d644c17SKarl Rupp if (pStart == pEnd) PetscFunctionReturn(0); 480363d1a920SMatthew G. Knepley if (stratumValue < 0) { 480463d1a920SMatthew G. Knepley if (start) *start = pStart; 480563d1a920SMatthew G. Knepley if (end) *end = pEnd; 480663d1a920SMatthew G. Knepley PetscFunctionReturn(0); 4807552f7358SJed Brown } 4808aa50250dSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 48092c71b3e2SJacob Faibussowitsch PetscCheckFalse(!label,PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "No label named depth was found"); 481063d1a920SMatthew G. Knepley ierr = DMLabelGetStratumBounds(label, stratumValue, start, end);CHKERRQ(ierr); 4811552f7358SJed Brown PetscFunctionReturn(0); 4812552f7358SJed Brown } 4813552f7358SJed Brown 4814552f7358SJed Brown /*@ 4815552f7358SJed Brown DMPlexGetHeightStratum - Get the bounds [start, end) for all points at a certain height. 4816552f7358SJed Brown 4817552f7358SJed Brown Not Collective 4818552f7358SJed Brown 4819552f7358SJed Brown Input Parameters: 4820552f7358SJed Brown + dm - The DMPlex object 4821552f7358SJed Brown - stratumValue - The requested height 4822552f7358SJed Brown 4823552f7358SJed Brown Output Parameters: 4824552f7358SJed Brown + start - The first point at this height 4825552f7358SJed Brown - end - One beyond the last point at this height 4826552f7358SJed Brown 4827647867b2SJed Brown Notes: 4828647867b2SJed Brown Height indexing is related to topological codimension. Height stratum 0 contains the highest topological dimension 4829647867b2SJed Brown points, often called "cells" or "elements". If the mesh is "interpolated" (see DMPlexInterpolate()), then height 4830647867b2SJed Brown stratum 1 contains the boundary of these "cells", often called "faces" or "facets". 4831647867b2SJed Brown 4832552f7358SJed Brown Level: developer 4833552f7358SJed Brown 48343dc9a465SVaclav Hapla .seealso: DMPlexGetDepthStratum(), DMPlexGetDepth(), DMPlexGetPointHeight() 4835552f7358SJed Brown @*/ 48360adebc6cSBarry Smith PetscErrorCode DMPlexGetHeightStratum(DM dm, PetscInt stratumValue, PetscInt *start, PetscInt *end) 48370adebc6cSBarry Smith { 4838aa50250dSMatthew G. Knepley DMLabel label; 483963d1a920SMatthew G. Knepley PetscInt depth, pStart, pEnd; 4840552f7358SJed Brown PetscErrorCode ierr; 4841552f7358SJed Brown 4842552f7358SJed Brown PetscFunctionBegin; 4843552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 484463d1a920SMatthew G. Knepley if (start) {PetscValidPointer(start, 3); *start = 0;} 484563d1a920SMatthew G. Knepley if (end) {PetscValidPointer(end, 4); *end = 0;} 4846552f7358SJed Brown ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 48470d644c17SKarl Rupp if (pStart == pEnd) PetscFunctionReturn(0); 484863d1a920SMatthew G. Knepley if (stratumValue < 0) { 484963d1a920SMatthew G. Knepley if (start) *start = pStart; 485063d1a920SMatthew G. Knepley if (end) *end = pEnd; 485163d1a920SMatthew G. Knepley PetscFunctionReturn(0); 4852552f7358SJed Brown } 4853aa50250dSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 48542c71b3e2SJacob Faibussowitsch PetscCheckFalse(!label,PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "No label named depth was found"); 485563d1a920SMatthew G. Knepley ierr = DMLabelGetNumValues(label, &depth);CHKERRQ(ierr); 485663d1a920SMatthew G. Knepley ierr = DMLabelGetStratumBounds(label, depth-1-stratumValue, start, end);CHKERRQ(ierr); 4857552f7358SJed Brown PetscFunctionReturn(0); 4858552f7358SJed Brown } 4859552f7358SJed Brown 4860ba2698f1SMatthew G. Knepley /*@ 4861ba2698f1SMatthew G. Knepley DMPlexGetPointDepth - Get the depth of a given point 4862ba2698f1SMatthew G. Knepley 4863ba2698f1SMatthew G. Knepley Not Collective 4864ba2698f1SMatthew G. Knepley 4865d8d19677SJose E. Roman Input Parameters: 4866ba2698f1SMatthew G. Knepley + dm - The DMPlex object 4867ba2698f1SMatthew G. Knepley - point - The point 4868ba2698f1SMatthew G. Knepley 4869ba2698f1SMatthew G. Knepley Output Parameter: 4870ba2698f1SMatthew G. Knepley . depth - The depth of the point 4871ba2698f1SMatthew G. Knepley 4872ba2698f1SMatthew G. Knepley Level: intermediate 4873ba2698f1SMatthew G. Knepley 48743dc9a465SVaclav Hapla .seealso: DMPlexGetCellType(), DMPlexGetDepthLabel(), DMPlexGetDepth(), DMPlexGetPointHeight() 4875ba2698f1SMatthew G. Knepley @*/ 4876ba2698f1SMatthew G. Knepley PetscErrorCode DMPlexGetPointDepth(DM dm, PetscInt point, PetscInt *depth) 4877ba2698f1SMatthew G. Knepley { 4878ba2698f1SMatthew G. Knepley PetscErrorCode ierr; 4879ba2698f1SMatthew G. Knepley 4880ba2698f1SMatthew G. Knepley PetscFunctionBegin; 4881ba2698f1SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 488240a2aa30SMatthew G. Knepley PetscValidIntPointer(depth, 3); 4883ba2698f1SMatthew G. Knepley ierr = DMLabelGetValue(dm->depthLabel, point, depth);CHKERRQ(ierr); 4884ba2698f1SMatthew G. Knepley PetscFunctionReturn(0); 4885ba2698f1SMatthew G. Knepley } 4886ba2698f1SMatthew G. Knepley 4887ba2698f1SMatthew G. Knepley /*@ 48880c0a32dcSVaclav Hapla DMPlexGetPointHeight - Get the height of a given point 48890c0a32dcSVaclav Hapla 48900c0a32dcSVaclav Hapla Not Collective 48910c0a32dcSVaclav Hapla 4892d8d19677SJose E. Roman Input Parameters: 48930c0a32dcSVaclav Hapla + dm - The DMPlex object 48940c0a32dcSVaclav Hapla - point - The point 48950c0a32dcSVaclav Hapla 48960c0a32dcSVaclav Hapla Output Parameter: 48970c0a32dcSVaclav Hapla . height - The height of the point 48980c0a32dcSVaclav Hapla 48990c0a32dcSVaclav Hapla Level: intermediate 49000c0a32dcSVaclav Hapla 49013dc9a465SVaclav Hapla .seealso: DMPlexGetCellType(), DMPlexGetDepthLabel(), DMPlexGetDepth(), DMPlexGetPointDepth() 49020c0a32dcSVaclav Hapla @*/ 49030c0a32dcSVaclav Hapla PetscErrorCode DMPlexGetPointHeight(DM dm, PetscInt point, PetscInt *height) 49040c0a32dcSVaclav Hapla { 49050c0a32dcSVaclav Hapla PetscInt n, pDepth; 49060c0a32dcSVaclav Hapla PetscErrorCode ierr; 49070c0a32dcSVaclav Hapla 49080c0a32dcSVaclav Hapla PetscFunctionBegin; 49090c0a32dcSVaclav Hapla PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 49100c0a32dcSVaclav Hapla PetscValidIntPointer(height, 3); 49110c0a32dcSVaclav Hapla ierr = DMLabelGetNumValues(dm->depthLabel, &n);CHKERRQ(ierr); 49120c0a32dcSVaclav Hapla ierr = DMLabelGetValue(dm->depthLabel, point, &pDepth);CHKERRQ(ierr); 49130c0a32dcSVaclav Hapla *height = n - 1 - pDepth; /* DAG depth is n-1 */ 49140c0a32dcSVaclav Hapla PetscFunctionReturn(0); 49150c0a32dcSVaclav Hapla } 49160c0a32dcSVaclav Hapla 49170c0a32dcSVaclav Hapla /*@ 4918ba2698f1SMatthew G. Knepley DMPlexGetCellTypeLabel - Get the DMLabel recording the polytope type of each cell 4919ba2698f1SMatthew G. Knepley 4920ba2698f1SMatthew G. Knepley Not Collective 4921ba2698f1SMatthew G. Knepley 4922ba2698f1SMatthew G. Knepley Input Parameter: 4923ba2698f1SMatthew G. Knepley . dm - The DMPlex object 4924ba2698f1SMatthew G. Knepley 4925ba2698f1SMatthew G. Knepley Output Parameter: 4926ba2698f1SMatthew G. Knepley . celltypeLabel - The DMLabel recording cell polytope type 4927ba2698f1SMatthew G. Knepley 4928412e9a14SMatthew G. Knepley Note: This function will trigger automatica computation of cell types. This can be disabled by calling 4929412e9a14SMatthew G. Knepley DMCreateLabel(dm, "celltype") beforehand. 4930412e9a14SMatthew G. Knepley 4931ba2698f1SMatthew G. Knepley Level: developer 4932ba2698f1SMatthew G. Knepley 4933dc287ab2SVaclav Hapla .seealso: DMPlexGetCellType(), DMPlexGetDepthLabel(), DMCreateLabel() 4934ba2698f1SMatthew G. Knepley @*/ 4935ba2698f1SMatthew G. Knepley PetscErrorCode DMPlexGetCellTypeLabel(DM dm, DMLabel *celltypeLabel) 4936ba2698f1SMatthew G. Knepley { 4937ba2698f1SMatthew G. Knepley PetscErrorCode ierr; 4938ba2698f1SMatthew G. Knepley 4939ba2698f1SMatthew G. Knepley PetscFunctionBegin; 4940ba2698f1SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4941ba2698f1SMatthew G. Knepley PetscValidPointer(celltypeLabel, 2); 4942ba2698f1SMatthew G. Knepley if (!dm->celltypeLabel) {ierr = DMPlexComputeCellTypes(dm);CHKERRQ(ierr);} 4943ba2698f1SMatthew G. Knepley *celltypeLabel = dm->celltypeLabel; 4944ba2698f1SMatthew G. Knepley PetscFunctionReturn(0); 4945ba2698f1SMatthew G. Knepley } 4946ba2698f1SMatthew G. Knepley 4947ba2698f1SMatthew G. Knepley /*@ 4948ba2698f1SMatthew G. Knepley DMPlexGetCellType - Get the polytope type of a given cell 4949ba2698f1SMatthew G. Knepley 4950ba2698f1SMatthew G. Knepley Not Collective 4951ba2698f1SMatthew G. Knepley 4952d8d19677SJose E. Roman Input Parameters: 4953ba2698f1SMatthew G. Knepley + dm - The DMPlex object 4954ba2698f1SMatthew G. Knepley - cell - The cell 4955ba2698f1SMatthew G. Knepley 4956ba2698f1SMatthew G. Knepley Output Parameter: 4957ba2698f1SMatthew G. Knepley . celltype - The polytope type of the cell 4958ba2698f1SMatthew G. Knepley 4959ba2698f1SMatthew G. Knepley Level: intermediate 4960ba2698f1SMatthew G. Knepley 4961ba2698f1SMatthew G. Knepley .seealso: DMPlexGetCellTypeLabel(), DMPlexGetDepthLabel(), DMPlexGetDepth() 4962ba2698f1SMatthew G. Knepley @*/ 4963ba2698f1SMatthew G. Knepley PetscErrorCode DMPlexGetCellType(DM dm, PetscInt cell, DMPolytopeType *celltype) 4964ba2698f1SMatthew G. Knepley { 4965ba2698f1SMatthew G. Knepley DMLabel label; 4966ba2698f1SMatthew G. Knepley PetscInt ct; 4967ba2698f1SMatthew G. Knepley PetscErrorCode ierr; 4968ba2698f1SMatthew G. Knepley 4969ba2698f1SMatthew G. Knepley PetscFunctionBegin; 4970ba2698f1SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4971ba2698f1SMatthew G. Knepley PetscValidPointer(celltype, 3); 4972ba2698f1SMatthew G. Knepley ierr = DMPlexGetCellTypeLabel(dm, &label);CHKERRQ(ierr); 4973ba2698f1SMatthew G. Knepley ierr = DMLabelGetValue(label, cell, &ct);CHKERRQ(ierr); 49742c71b3e2SJacob Faibussowitsch PetscCheckFalse(ct < 0,PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Cell %D has not been assigned a cell type", cell); 4975ba2698f1SMatthew G. Knepley *celltype = (DMPolytopeType) ct; 4976ba2698f1SMatthew G. Knepley PetscFunctionReturn(0); 4977ba2698f1SMatthew G. Knepley } 4978ba2698f1SMatthew G. Knepley 4979412e9a14SMatthew G. Knepley /*@ 4980412e9a14SMatthew G. Knepley DMPlexSetCellType - Set the polytope type of a given cell 4981412e9a14SMatthew G. Knepley 4982412e9a14SMatthew G. Knepley Not Collective 4983412e9a14SMatthew G. Knepley 4984412e9a14SMatthew G. Knepley Input Parameters: 4985412e9a14SMatthew G. Knepley + dm - The DMPlex object 4986412e9a14SMatthew G. Knepley . cell - The cell 4987412e9a14SMatthew G. Knepley - celltype - The polytope type of the cell 4988412e9a14SMatthew G. Knepley 4989412e9a14SMatthew G. Knepley Note: By default, cell types will be automatically computed using DMPlexComputeCellTypes() before this function 4990412e9a14SMatthew G. Knepley is executed. This function will override the computed type. However, if automatic classification will not succeed 4991412e9a14SMatthew G. Knepley and a user wants to manually specify all types, the classification must be disabled by calling 4992412e9a14SMatthew G. Knepley DMCreaateLabel(dm, "celltype") before getting or setting any cell types. 4993412e9a14SMatthew G. Knepley 4994412e9a14SMatthew G. Knepley Level: advanced 4995412e9a14SMatthew G. Knepley 4996412e9a14SMatthew G. Knepley .seealso: DMPlexGetCellTypeLabel(), DMPlexGetDepthLabel(), DMPlexGetDepth(), DMPlexComputeCellTypes(), DMCreateLabel() 4997412e9a14SMatthew G. Knepley @*/ 4998412e9a14SMatthew G. Knepley PetscErrorCode DMPlexSetCellType(DM dm, PetscInt cell, DMPolytopeType celltype) 4999412e9a14SMatthew G. Knepley { 5000412e9a14SMatthew G. Knepley DMLabel label; 5001412e9a14SMatthew G. Knepley PetscErrorCode ierr; 5002412e9a14SMatthew G. Knepley 5003412e9a14SMatthew G. Knepley PetscFunctionBegin; 5004412e9a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5005412e9a14SMatthew G. Knepley ierr = DMPlexGetCellTypeLabel(dm, &label);CHKERRQ(ierr); 5006412e9a14SMatthew G. Knepley ierr = DMLabelSetValue(label, cell, celltype);CHKERRQ(ierr); 5007412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 5008412e9a14SMatthew G. Knepley } 5009412e9a14SMatthew G. Knepley 50100adebc6cSBarry Smith PetscErrorCode DMCreateCoordinateDM_Plex(DM dm, DM *cdm) 50110adebc6cSBarry Smith { 5012efe440bfSMatthew G. Knepley PetscSection section, s; 5013efe440bfSMatthew G. Knepley Mat m; 50143e922f36SToby Isaac PetscInt maxHeight; 5015552f7358SJed Brown PetscErrorCode ierr; 5016552f7358SJed Brown 5017552f7358SJed Brown PetscFunctionBegin; 501838221697SMatthew G. Knepley ierr = DMClone(dm, cdm);CHKERRQ(ierr); 50193e922f36SToby Isaac ierr = DMPlexGetMaxProjectionHeight(dm, &maxHeight);CHKERRQ(ierr); 50203e922f36SToby Isaac ierr = DMPlexSetMaxProjectionHeight(*cdm, maxHeight);CHKERRQ(ierr); 502182f516ccSBarry Smith ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), §ion);CHKERRQ(ierr); 502292fd8e1eSJed Brown ierr = DMSetLocalSection(*cdm, section);CHKERRQ(ierr); 50231d799100SJed Brown ierr = PetscSectionDestroy(§ion);CHKERRQ(ierr); 5024efe440bfSMatthew G. Knepley ierr = PetscSectionCreate(PETSC_COMM_SELF, &s);CHKERRQ(ierr); 5025efe440bfSMatthew G. Knepley ierr = MatCreate(PETSC_COMM_SELF, &m);CHKERRQ(ierr); 5026efe440bfSMatthew G. Knepley ierr = DMSetDefaultConstraints(*cdm, s, m);CHKERRQ(ierr); 5027efe440bfSMatthew G. Knepley ierr = PetscSectionDestroy(&s);CHKERRQ(ierr); 5028efe440bfSMatthew G. Knepley ierr = MatDestroy(&m);CHKERRQ(ierr); 50298f4c458bSMatthew G. Knepley 50308f4c458bSMatthew G. Knepley ierr = DMSetNumFields(*cdm, 1);CHKERRQ(ierr); 50318f4c458bSMatthew G. Knepley ierr = DMCreateDS(*cdm);CHKERRQ(ierr); 5032552f7358SJed Brown PetscFunctionReturn(0); 5033552f7358SJed Brown } 5034552f7358SJed Brown 5035f19dbd58SToby Isaac PetscErrorCode DMCreateCoordinateField_Plex(DM dm, DMField *field) 5036f19dbd58SToby Isaac { 5037f19dbd58SToby Isaac Vec coordsLocal; 5038f19dbd58SToby Isaac DM coordsDM; 5039f19dbd58SToby Isaac PetscErrorCode ierr; 5040f19dbd58SToby Isaac 5041f19dbd58SToby Isaac PetscFunctionBegin; 5042f19dbd58SToby Isaac *field = NULL; 5043f19dbd58SToby Isaac ierr = DMGetCoordinatesLocal(dm,&coordsLocal);CHKERRQ(ierr); 5044f19dbd58SToby Isaac ierr = DMGetCoordinateDM(dm,&coordsDM);CHKERRQ(ierr); 5045f19dbd58SToby Isaac if (coordsLocal && coordsDM) { 5046f19dbd58SToby Isaac ierr = DMFieldCreateDS(coordsDM, 0, coordsLocal, field);CHKERRQ(ierr); 5047f19dbd58SToby Isaac } 5048f19dbd58SToby Isaac PetscFunctionReturn(0); 5049f19dbd58SToby Isaac } 5050f19dbd58SToby Isaac 50517cd05799SMatthew G. Knepley /*@C 50527cd05799SMatthew G. Knepley DMPlexGetConeSection - Return a section which describes the layout of cone data 50537cd05799SMatthew G. Knepley 50547cd05799SMatthew G. Knepley Not Collective 50557cd05799SMatthew G. Knepley 50567cd05799SMatthew G. Knepley Input Parameters: 50577cd05799SMatthew G. Knepley . dm - The DMPlex object 50587cd05799SMatthew G. Knepley 50597cd05799SMatthew G. Knepley Output Parameter: 50607cd05799SMatthew G. Knepley . section - The PetscSection object 50617cd05799SMatthew G. Knepley 50627cd05799SMatthew G. Knepley Level: developer 50637cd05799SMatthew G. Knepley 50647cd05799SMatthew G. Knepley .seealso: DMPlexGetSupportSection(), DMPlexGetCones(), DMPlexGetConeOrientations() 50657cd05799SMatthew G. Knepley @*/ 50660adebc6cSBarry Smith PetscErrorCode DMPlexGetConeSection(DM dm, PetscSection *section) 50670adebc6cSBarry Smith { 5068552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 5069552f7358SJed Brown 5070552f7358SJed Brown PetscFunctionBegin; 5071552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5072552f7358SJed Brown if (section) *section = mesh->coneSection; 5073552f7358SJed Brown PetscFunctionReturn(0); 5074552f7358SJed Brown } 5075552f7358SJed Brown 50767cd05799SMatthew G. Knepley /*@C 50777cd05799SMatthew G. Knepley DMPlexGetSupportSection - Return a section which describes the layout of support data 50787cd05799SMatthew G. Knepley 50797cd05799SMatthew G. Knepley Not Collective 50807cd05799SMatthew G. Knepley 50817cd05799SMatthew G. Knepley Input Parameters: 50827cd05799SMatthew G. Knepley . dm - The DMPlex object 50837cd05799SMatthew G. Knepley 50847cd05799SMatthew G. Knepley Output Parameter: 50857cd05799SMatthew G. Knepley . section - The PetscSection object 50867cd05799SMatthew G. Knepley 50877cd05799SMatthew G. Knepley Level: developer 50887cd05799SMatthew G. Knepley 50897cd05799SMatthew G. Knepley .seealso: DMPlexGetConeSection() 50907cd05799SMatthew G. Knepley @*/ 50918cb4d582SMatthew G. Knepley PetscErrorCode DMPlexGetSupportSection(DM dm, PetscSection *section) 50928cb4d582SMatthew G. Knepley { 50938cb4d582SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 50948cb4d582SMatthew G. Knepley 50958cb4d582SMatthew G. Knepley PetscFunctionBegin; 50968cb4d582SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 50978cb4d582SMatthew G. Knepley if (section) *section = mesh->supportSection; 50988cb4d582SMatthew G. Knepley PetscFunctionReturn(0); 50998cb4d582SMatthew G. Knepley } 51008cb4d582SMatthew G. Knepley 51017cd05799SMatthew G. Knepley /*@C 51027cd05799SMatthew G. Knepley DMPlexGetCones - Return cone data 51037cd05799SMatthew G. Knepley 51047cd05799SMatthew G. Knepley Not Collective 51057cd05799SMatthew G. Knepley 51067cd05799SMatthew G. Knepley Input Parameters: 51077cd05799SMatthew G. Knepley . dm - The DMPlex object 51087cd05799SMatthew G. Knepley 51097cd05799SMatthew G. Knepley Output Parameter: 51107cd05799SMatthew G. Knepley . cones - The cone for each point 51117cd05799SMatthew G. Knepley 51127cd05799SMatthew G. Knepley Level: developer 51137cd05799SMatthew G. Knepley 51147cd05799SMatthew G. Knepley .seealso: DMPlexGetConeSection() 51157cd05799SMatthew G. Knepley @*/ 5116a6dfd86eSKarl Rupp PetscErrorCode DMPlexGetCones(DM dm, PetscInt *cones[]) 5117a6dfd86eSKarl Rupp { 5118552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 5119552f7358SJed Brown 5120552f7358SJed Brown PetscFunctionBegin; 5121552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5122552f7358SJed Brown if (cones) *cones = mesh->cones; 5123552f7358SJed Brown PetscFunctionReturn(0); 5124552f7358SJed Brown } 5125552f7358SJed Brown 51267cd05799SMatthew G. Knepley /*@C 51277cd05799SMatthew G. Knepley DMPlexGetConeOrientations - Return cone orientation data 51287cd05799SMatthew G. Knepley 51297cd05799SMatthew G. Knepley Not Collective 51307cd05799SMatthew G. Knepley 51317cd05799SMatthew G. Knepley Input Parameters: 51327cd05799SMatthew G. Knepley . dm - The DMPlex object 51337cd05799SMatthew G. Knepley 51347cd05799SMatthew G. Knepley Output Parameter: 5135b5a892a1SMatthew G. Knepley . coneOrientations - The array of cone orientations for all points 51367cd05799SMatthew G. Knepley 51377cd05799SMatthew G. Knepley Level: developer 51387cd05799SMatthew G. Knepley 5139b5a892a1SMatthew G. Knepley Notes: 5140b5a892a1SMatthew G. Knepley The PetscSection returned by DMPlexGetConeSection() partitions coneOrientations into cone orientations of particular points as returned by DMPlexGetConeOrientation(). 5141b5a892a1SMatthew G. Knepley 5142b5a892a1SMatthew G. Knepley The meaning of coneOrientations values is detailed in DMPlexGetConeOrientation(). 5143b5a892a1SMatthew G. Knepley 5144b5a892a1SMatthew G. Knepley .seealso: DMPlexGetConeSection(), DMPlexGetConeOrientation() 51457cd05799SMatthew G. Knepley @*/ 5146a6dfd86eSKarl Rupp PetscErrorCode DMPlexGetConeOrientations(DM dm, PetscInt *coneOrientations[]) 5147a6dfd86eSKarl Rupp { 5148552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 5149552f7358SJed Brown 5150552f7358SJed Brown PetscFunctionBegin; 5151552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5152552f7358SJed Brown if (coneOrientations) *coneOrientations = mesh->coneOrientations; 5153552f7358SJed Brown PetscFunctionReturn(0); 5154552f7358SJed Brown } 5155552f7358SJed Brown 5156552f7358SJed Brown /******************************** FEM Support **********************************/ 5157552f7358SJed Brown 51589e8305c2SJed Brown /* 51599e8305c2SJed Brown Returns number of components and tensor degree for the field. For interpolated meshes, line should be a point 51609e8305c2SJed Brown representing a line in the section. 51619e8305c2SJed Brown */ 51629e8305c2SJed Brown static PetscErrorCode PetscSectionFieldGetTensorDegree_Private(PetscSection section,PetscInt field,PetscInt line,PetscBool vertexchart,PetscInt *Nc,PetscInt *k) 51639e8305c2SJed Brown { 51649e8305c2SJed Brown PetscErrorCode ierr; 51659e8305c2SJed Brown 51669e8305c2SJed Brown PetscFunctionBeginHot; 51679e8305c2SJed Brown ierr = PetscSectionGetFieldComponents(section, field, Nc);CHKERRQ(ierr); 5168a433471fSStefano Zampini if (line < 0) { 5169a433471fSStefano Zampini *k = 0; 5170a433471fSStefano Zampini *Nc = 0; 5171a433471fSStefano Zampini } else if (vertexchart) { /* If we only have a vertex chart, we must have degree k=1 */ 51729e8305c2SJed Brown *k = 1; 51739e8305c2SJed Brown } else { /* Assume the full interpolated mesh is in the chart; lines in particular */ 51749e8305c2SJed Brown /* An order k SEM disc has k-1 dofs on an edge */ 51759e8305c2SJed Brown ierr = PetscSectionGetFieldDof(section, line, field, k);CHKERRQ(ierr); 51769e8305c2SJed Brown *k = *k / *Nc + 1; 51779e8305c2SJed Brown } 51789e8305c2SJed Brown PetscFunctionReturn(0); 51799e8305c2SJed Brown } 51809e8305c2SJed Brown 5181a4355906SMatthew Knepley /*@ 5182bc1eb3faSJed Brown 5183bc1eb3faSJed Brown DMPlexSetClosurePermutationTensor - Create a permutation from the default (BFS) point ordering in the closure, to a 5184bc1eb3faSJed Brown lexicographic ordering over the tensor product cell (i.e., line, quad, hex, etc.), and set this permutation in the 51851bb6d2a8SBarry Smith section provided (or the section of the DM). 5186a4355906SMatthew Knepley 5187a4355906SMatthew Knepley Input Parameters: 5188a4355906SMatthew Knepley + dm - The DM 5189a4355906SMatthew Knepley . point - Either a cell (highest dim point) or an edge (dim 1 point), or PETSC_DETERMINE 5190a4355906SMatthew Knepley - section - The PetscSection to reorder, or NULL for the default section 5191a4355906SMatthew Knepley 5192a4355906SMatthew Knepley Note: The point is used to determine the number of dofs/field on an edge. For SEM, this is related to the polynomial 5193a4355906SMatthew Knepley degree of the basis. 5194a4355906SMatthew Knepley 5195bc1eb3faSJed Brown Example: 5196bc1eb3faSJed Brown A typical interpolated single-quad mesh might order points as 5197bc1eb3faSJed Brown .vb 5198bc1eb3faSJed Brown [c0, v1, v2, v3, v4, e5, e6, e7, e8] 5199bc1eb3faSJed Brown 5200bc1eb3faSJed Brown v4 -- e6 -- v3 5201bc1eb3faSJed Brown | | 5202bc1eb3faSJed Brown e7 c0 e8 5203bc1eb3faSJed Brown | | 5204bc1eb3faSJed Brown v1 -- e5 -- v2 5205bc1eb3faSJed Brown .ve 5206bc1eb3faSJed Brown 5207bc1eb3faSJed Brown (There is no significance to the ordering described here.) The default section for a Q3 quad might typically assign 5208bc1eb3faSJed Brown dofs in the order of points, e.g., 5209bc1eb3faSJed Brown .vb 5210bc1eb3faSJed Brown c0 -> [0,1,2,3] 5211bc1eb3faSJed Brown v1 -> [4] 5212bc1eb3faSJed Brown ... 5213bc1eb3faSJed Brown e5 -> [8, 9] 5214bc1eb3faSJed Brown .ve 5215bc1eb3faSJed Brown 5216bc1eb3faSJed Brown which corresponds to the dofs 5217bc1eb3faSJed Brown .vb 5218bc1eb3faSJed Brown 6 10 11 7 5219bc1eb3faSJed Brown 13 2 3 15 5220bc1eb3faSJed Brown 12 0 1 14 5221bc1eb3faSJed Brown 4 8 9 5 5222bc1eb3faSJed Brown .ve 5223bc1eb3faSJed Brown 5224bc1eb3faSJed Brown The closure in BFS ordering works through height strata (cells, edges, vertices) to produce the ordering 5225bc1eb3faSJed Brown .vb 5226bc1eb3faSJed Brown 0 1 2 3 8 9 14 15 11 10 13 12 4 5 7 6 5227bc1eb3faSJed Brown .ve 5228bc1eb3faSJed Brown 5229bc1eb3faSJed Brown After calling DMPlexSetClosurePermutationTensor(), the closure will be ordered lexicographically, 5230bc1eb3faSJed Brown .vb 5231bc1eb3faSJed Brown 4 8 9 5 12 0 1 14 13 2 3 15 6 10 11 7 5232bc1eb3faSJed Brown .ve 5233bc1eb3faSJed Brown 5234a4355906SMatthew Knepley Level: developer 5235a4355906SMatthew Knepley 52369df75925SJed Brown .seealso: DMGetLocalSection(), PetscSectionSetClosurePermutation(), DMSetGlobalSection() 5237a4355906SMatthew Knepley @*/ 5238bc1eb3faSJed Brown PetscErrorCode DMPlexSetClosurePermutationTensor(DM dm, PetscInt point, PetscSection section) 52393194fc30SMatthew G. Knepley { 52407391a63aSMatthew G. Knepley DMLabel label; 5241bb197d40SJed Brown PetscInt dim, depth = -1, eStart = -1, Nf; 52429e8305c2SJed Brown PetscBool vertexchart; 52433194fc30SMatthew G. Knepley PetscErrorCode ierr; 52443194fc30SMatthew G. Knepley 52453194fc30SMatthew G. Knepley PetscFunctionBegin; 52463194fc30SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 5247a433471fSStefano Zampini if (dim < 1) PetscFunctionReturn(0); 5248a433471fSStefano Zampini if (point < 0) { 5249a433471fSStefano Zampini PetscInt sStart,sEnd; 5250a433471fSStefano Zampini 5251a433471fSStefano Zampini ierr = DMPlexGetDepthStratum(dm, 1, &sStart, &sEnd);CHKERRQ(ierr); 5252a433471fSStefano Zampini point = sEnd-sStart ? sStart : point; 5253a433471fSStefano Zampini } 52547391a63aSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 5255a433471fSStefano Zampini if (point >= 0) { ierr = DMLabelGetValue(label, point, &depth);CHKERRQ(ierr); } 5256a433471fSStefano Zampini if (!section) {ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr);} 52577391a63aSMatthew G. Knepley if (depth == 1) {eStart = point;} 52587391a63aSMatthew G. Knepley else if (depth == dim) { 52597391a63aSMatthew G. Knepley const PetscInt *cone; 52607391a63aSMatthew G. Knepley 52617391a63aSMatthew G. Knepley ierr = DMPlexGetCone(dm, point, &cone);CHKERRQ(ierr); 5262d4e6627bSStefano Zampini if (dim == 2) eStart = cone[0]; 5263d4e6627bSStefano Zampini else if (dim == 3) { 5264d4e6627bSStefano Zampini const PetscInt *cone2; 5265d4e6627bSStefano Zampini ierr = DMPlexGetCone(dm, cone[0], &cone2);CHKERRQ(ierr); 5266d4e6627bSStefano Zampini eStart = cone2[0]; 526798921bdaSJacob 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); 52682c71b3e2SJacob 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); 52699e8305c2SJed Brown { /* Determine whether the chart covers all points or just vertices. */ 52709e8305c2SJed Brown PetscInt pStart,pEnd,cStart,cEnd; 52719e8305c2SJed Brown ierr = DMPlexGetDepthStratum(dm,0,&pStart,&pEnd);CHKERRQ(ierr); 52729e8305c2SJed Brown ierr = PetscSectionGetChart(section,&cStart,&cEnd);CHKERRQ(ierr); 52739e8305c2SJed Brown if (pStart == cStart && pEnd == cEnd) vertexchart = PETSC_TRUE; /* Just vertices */ 52749e8305c2SJed Brown else vertexchart = PETSC_FALSE; /* Assume all interpolated points are in chart */ 52759e8305c2SJed Brown } 52763194fc30SMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &Nf);CHKERRQ(ierr); 5277bb197d40SJed Brown for (PetscInt d=1; d<=dim; d++) { 5278bb197d40SJed Brown PetscInt k, f, Nc, c, i, j, size = 0, offset = 0, foffset = 0; 5279bb197d40SJed Brown PetscInt *perm; 5280bb197d40SJed Brown 52813194fc30SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 52829e8305c2SJed Brown ierr = PetscSectionFieldGetTensorDegree_Private(section,f,eStart,vertexchart,&Nc,&k);CHKERRQ(ierr); 5283bb197d40SJed Brown size += PetscPowInt(k+1, d)*Nc; 52843194fc30SMatthew G. Knepley } 52853194fc30SMatthew G. Knepley ierr = PetscMalloc1(size, &perm);CHKERRQ(ierr); 52863194fc30SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 5287bb197d40SJed Brown switch (d) { 5288babf31e0SJed Brown case 1: 52899e8305c2SJed Brown ierr = PetscSectionFieldGetTensorDegree_Private(section,f,eStart,vertexchart,&Nc,&k);CHKERRQ(ierr); 5290babf31e0SJed Brown /* 5291babf31e0SJed Brown Original ordering is [ edge of length k-1; vtx0; vtx1 ] 5292babf31e0SJed Brown We want [ vtx0; edge of length k-1; vtx1 ] 5293babf31e0SJed Brown */ 5294babf31e0SJed Brown for (c=0; c<Nc; c++,offset++) perm[offset] = (k-1)*Nc + c + foffset; 5295babf31e0SJed Brown for (i=0; i<k-1; i++) for (c=0; c<Nc; c++,offset++) perm[offset] = i*Nc + c + foffset; 5296babf31e0SJed Brown for (c=0; c<Nc; c++,offset++) perm[offset] = k*Nc + c + foffset; 5297babf31e0SJed Brown foffset = offset; 5298babf31e0SJed Brown break; 529989eabcffSMatthew G. Knepley case 2: 53003194fc30SMatthew 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} */ 53019e8305c2SJed Brown ierr = PetscSectionFieldGetTensorDegree_Private(section,f,eStart,vertexchart,&Nc,&k);CHKERRQ(ierr); 53023194fc30SMatthew G. Knepley /* The SEM order is 53033194fc30SMatthew G. Knepley 53043194fc30SMatthew G. Knepley v_lb, {e_b}, v_rb, 530589eabcffSMatthew G. Knepley e^{(k-1)-i}_l, {f^{i*(k-1)}}, e^i_r, 53063194fc30SMatthew G. Knepley v_lt, reverse {e_t}, v_rt 53073194fc30SMatthew G. Knepley */ 53083194fc30SMatthew G. Knepley { 53093194fc30SMatthew G. Knepley const PetscInt of = 0; 53103194fc30SMatthew G. Knepley const PetscInt oeb = of + PetscSqr(k-1); 53113194fc30SMatthew G. Knepley const PetscInt oer = oeb + (k-1); 53123194fc30SMatthew G. Knepley const PetscInt oet = oer + (k-1); 53133194fc30SMatthew G. Knepley const PetscInt oel = oet + (k-1); 53143194fc30SMatthew G. Knepley const PetscInt ovlb = oel + (k-1); 53153194fc30SMatthew G. Knepley const PetscInt ovrb = ovlb + 1; 53163194fc30SMatthew G. Knepley const PetscInt ovrt = ovrb + 1; 53173194fc30SMatthew G. Knepley const PetscInt ovlt = ovrt + 1; 53183194fc30SMatthew G. Knepley PetscInt o; 53193194fc30SMatthew G. Knepley 53203194fc30SMatthew G. Knepley /* bottom */ 53213194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovlb*Nc + c + foffset; 53223194fc30SMatthew G. Knepley for (o = oeb; o < oer; ++o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 53233194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovrb*Nc + c + foffset; 53243194fc30SMatthew G. Knepley /* middle */ 53253194fc30SMatthew G. Knepley for (i = 0; i < k-1; ++i) { 53263194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oel+(k-2)-i)*Nc + c + foffset; 53273194fc30SMatthew 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; 53283194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oer+i)*Nc + c + foffset; 53293194fc30SMatthew G. Knepley } 53303194fc30SMatthew G. Knepley /* top */ 53313194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovlt*Nc + c + foffset; 53323194fc30SMatthew G. Knepley for (o = oel-1; o >= oet; --o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 53333194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovrt*Nc + c + foffset; 53343194fc30SMatthew G. Knepley foffset = offset; 53353194fc30SMatthew G. Knepley } 533689eabcffSMatthew G. Knepley break; 533789eabcffSMatthew G. Knepley case 3: 533889eabcffSMatthew G. Knepley /* The original hex closure is 533989eabcffSMatthew G. Knepley 534089eabcffSMatthew G. Knepley {c, 534189eabcffSMatthew G. Knepley f_b, f_t, f_f, f_b, f_r, f_l, 534289eabcffSMatthew 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, 534389eabcffSMatthew G. Knepley v_blf, v_blb, v_brb, v_brf, v_tlf, v_trf, v_trb, v_tlb} 534489eabcffSMatthew G. Knepley */ 53459e8305c2SJed Brown ierr = PetscSectionFieldGetTensorDegree_Private(section,f,eStart,vertexchart,&Nc,&k);CHKERRQ(ierr); 534689eabcffSMatthew G. Knepley /* The SEM order is 534789eabcffSMatthew G. Knepley Bottom Slice 534889eabcffSMatthew G. Knepley v_blf, {e^{(k-1)-n}_bf}, v_brf, 534989eabcffSMatthew G. Knepley e^{i}_bl, f^{n*(k-1)+(k-1)-i}_b, e^{(k-1)-i}_br, 535089eabcffSMatthew G. Knepley v_blb, {e_bb}, v_brb, 535189eabcffSMatthew G. Knepley 535289eabcffSMatthew G. Knepley Middle Slice (j) 535389eabcffSMatthew G. Knepley {e^{(k-1)-j}_lf}, {f^{j*(k-1)+n}_f}, e^j_rf, 535489eabcffSMatthew G. Knepley f^{i*(k-1)+j}_l, {c^{(j*(k-1) + i)*(k-1)+n}_t}, f^{j*(k-1)+i}_r, 535589eabcffSMatthew G. Knepley e^j_lb, {f^{j*(k-1)+(k-1)-n}_b}, e^{(k-1)-j}_rb, 535689eabcffSMatthew G. Knepley 535789eabcffSMatthew G. Knepley Top Slice 535889eabcffSMatthew G. Knepley v_tlf, {e_tf}, v_trf, 535989eabcffSMatthew G. Knepley e^{(k-1)-i}_tl, {f^{i*(k-1)}_t}, e^{i}_tr, 536089eabcffSMatthew G. Knepley v_tlb, {e^{(k-1)-n}_tb}, v_trb, 536189eabcffSMatthew G. Knepley */ 536289eabcffSMatthew G. Knepley { 536389eabcffSMatthew G. Knepley const PetscInt oc = 0; 536489eabcffSMatthew G. Knepley const PetscInt ofb = oc + PetscSqr(k-1)*(k-1); 536589eabcffSMatthew G. Knepley const PetscInt oft = ofb + PetscSqr(k-1); 536689eabcffSMatthew G. Knepley const PetscInt off = oft + PetscSqr(k-1); 536789eabcffSMatthew G. Knepley const PetscInt ofk = off + PetscSqr(k-1); 536889eabcffSMatthew G. Knepley const PetscInt ofr = ofk + PetscSqr(k-1); 536989eabcffSMatthew G. Knepley const PetscInt ofl = ofr + PetscSqr(k-1); 537089eabcffSMatthew G. Knepley const PetscInt oebl = ofl + PetscSqr(k-1); 537189eabcffSMatthew G. Knepley const PetscInt oebb = oebl + (k-1); 537289eabcffSMatthew G. Knepley const PetscInt oebr = oebb + (k-1); 537389eabcffSMatthew G. Knepley const PetscInt oebf = oebr + (k-1); 537489eabcffSMatthew G. Knepley const PetscInt oetf = oebf + (k-1); 537589eabcffSMatthew G. Knepley const PetscInt oetr = oetf + (k-1); 537689eabcffSMatthew G. Knepley const PetscInt oetb = oetr + (k-1); 537789eabcffSMatthew G. Knepley const PetscInt oetl = oetb + (k-1); 537889eabcffSMatthew G. Knepley const PetscInt oerf = oetl + (k-1); 537989eabcffSMatthew G. Knepley const PetscInt oelf = oerf + (k-1); 538089eabcffSMatthew G. Knepley const PetscInt oelb = oelf + (k-1); 538189eabcffSMatthew G. Knepley const PetscInt oerb = oelb + (k-1); 538289eabcffSMatthew G. Knepley const PetscInt ovblf = oerb + (k-1); 538389eabcffSMatthew G. Knepley const PetscInt ovblb = ovblf + 1; 538489eabcffSMatthew G. Knepley const PetscInt ovbrb = ovblb + 1; 538589eabcffSMatthew G. Knepley const PetscInt ovbrf = ovbrb + 1; 538689eabcffSMatthew G. Knepley const PetscInt ovtlf = ovbrf + 1; 538789eabcffSMatthew G. Knepley const PetscInt ovtrf = ovtlf + 1; 538889eabcffSMatthew G. Knepley const PetscInt ovtrb = ovtrf + 1; 538989eabcffSMatthew G. Knepley const PetscInt ovtlb = ovtrb + 1; 539089eabcffSMatthew G. Knepley PetscInt o, n; 539189eabcffSMatthew G. Knepley 539289eabcffSMatthew G. Knepley /* Bottom Slice */ 539389eabcffSMatthew G. Knepley /* bottom */ 539489eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovblf*Nc + c + foffset; 539589eabcffSMatthew G. Knepley for (o = oetf-1; o >= oebf; --o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 539689eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovbrf*Nc + c + foffset; 539789eabcffSMatthew G. Knepley /* middle */ 539889eabcffSMatthew G. Knepley for (i = 0; i < k-1; ++i) { 539989eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oebl+i)*Nc + c + foffset; 5400316b7f87SMax 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;} 540189eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oebr+(k-2)-i)*Nc + c + foffset; 54023194fc30SMatthew G. Knepley } 540389eabcffSMatthew G. Knepley /* top */ 540489eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovblb*Nc + c + foffset; 540589eabcffSMatthew G. Knepley for (o = oebb; o < oebr; ++o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 540689eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovbrb*Nc + c + foffset; 540789eabcffSMatthew G. Knepley 540889eabcffSMatthew G. Knepley /* Middle Slice */ 540989eabcffSMatthew G. Knepley for (j = 0; j < k-1; ++j) { 541089eabcffSMatthew G. Knepley /* bottom */ 541189eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oelf+(k-2)-j)*Nc + c + foffset; 541289eabcffSMatthew 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; 541389eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oerf+j)*Nc + c + foffset; 541489eabcffSMatthew G. Knepley /* middle */ 541589eabcffSMatthew G. Knepley for (i = 0; i < k-1; ++i) { 541689eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (ofl+i*(k-1)+j)*Nc + c + foffset; 541789eabcffSMatthew 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; 541889eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (ofr+j*(k-1)+i)*Nc + c + foffset; 541989eabcffSMatthew G. Knepley } 542089eabcffSMatthew G. Knepley /* top */ 542189eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oelb+j)*Nc + c + foffset; 542289eabcffSMatthew 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; 542389eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oerb+(k-2)-j)*Nc + c + foffset; 542489eabcffSMatthew G. Knepley } 542589eabcffSMatthew G. Knepley 542689eabcffSMatthew G. Knepley /* Top Slice */ 542789eabcffSMatthew G. Knepley /* bottom */ 542889eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovtlf*Nc + c + foffset; 542989eabcffSMatthew G. Knepley for (o = oetf; o < oetr; ++o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 543089eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovtrf*Nc + c + foffset; 543189eabcffSMatthew G. Knepley /* middle */ 543289eabcffSMatthew G. Knepley for (i = 0; i < k-1; ++i) { 543389eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oetl+(k-2)-i)*Nc + c + foffset; 543489eabcffSMatthew 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; 543589eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oetr+i)*Nc + c + foffset; 543689eabcffSMatthew G. Knepley } 543789eabcffSMatthew G. Knepley /* top */ 543889eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovtlb*Nc + c + foffset; 543989eabcffSMatthew G. Knepley for (o = oetl-1; o >= oetb; --o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 544089eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovtrb*Nc + c + foffset; 544189eabcffSMatthew G. Knepley 544289eabcffSMatthew G. Knepley foffset = offset; 544389eabcffSMatthew G. Knepley } 544489eabcffSMatthew G. Knepley break; 544598921bdaSJacob Faibussowitsch default: SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "No spectral ordering for dimension %D", d); 544689eabcffSMatthew G. Knepley } 544789eabcffSMatthew G. Knepley } 54482c71b3e2SJacob Faibussowitsch PetscCheckFalse(offset != size,PetscObjectComm((PetscObject) dm), PETSC_ERR_PLIB, "Number of permutation entries %D != %D", offset, size); 54493194fc30SMatthew G. Knepley /* Check permutation */ 54503194fc30SMatthew G. Knepley { 54513194fc30SMatthew G. Knepley PetscInt *check; 54523194fc30SMatthew G. Knepley 54533194fc30SMatthew G. Knepley ierr = PetscMalloc1(size, &check);CHKERRQ(ierr); 54542c71b3e2SJacob 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]);} 54553194fc30SMatthew G. Knepley for (i = 0; i < size; ++i) check[perm[i]] = i; 54562c71b3e2SJacob Faibussowitsch for (i = 0; i < size; ++i) {PetscCheckFalse(check[i] < 0,PetscObjectComm((PetscObject) dm), PETSC_ERR_PLIB, "Missing permutation index %D", i);} 54573194fc30SMatthew G. Knepley ierr = PetscFree(check);CHKERRQ(ierr); 54583194fc30SMatthew G. Knepley } 5459bb197d40SJed Brown ierr = PetscSectionSetClosurePermutation_Internal(section, (PetscObject) dm, d, size, PETSC_OWN_POINTER, perm);CHKERRQ(ierr); 5460bb197d40SJed Brown } 54613194fc30SMatthew G. Knepley PetscFunctionReturn(0); 54623194fc30SMatthew G. Knepley } 54633194fc30SMatthew G. Knepley 5464e071409bSToby Isaac PetscErrorCode DMPlexGetPointDualSpaceFEM(DM dm, PetscInt point, PetscInt field, PetscDualSpace *dspace) 5465e071409bSToby Isaac { 5466e071409bSToby Isaac PetscDS prob; 5467e071409bSToby Isaac PetscInt depth, Nf, h; 5468e071409bSToby Isaac DMLabel label; 5469e071409bSToby Isaac PetscErrorCode ierr; 5470e071409bSToby Isaac 5471e071409bSToby Isaac PetscFunctionBeginHot; 5472e5e52638SMatthew G. Knepley ierr = DMGetDS(dm, &prob);CHKERRQ(ierr); 5473e071409bSToby Isaac Nf = prob->Nf; 5474e071409bSToby Isaac label = dm->depthLabel; 5475e071409bSToby Isaac *dspace = NULL; 5476e071409bSToby Isaac if (field < Nf) { 5477e071409bSToby Isaac PetscObject disc = prob->disc[field]; 5478e071409bSToby Isaac 5479e071409bSToby Isaac if (disc->classid == PETSCFE_CLASSID) { 5480e071409bSToby Isaac PetscDualSpace dsp; 5481e071409bSToby Isaac 5482e071409bSToby Isaac ierr = PetscFEGetDualSpace((PetscFE)disc,&dsp);CHKERRQ(ierr); 5483e071409bSToby Isaac ierr = DMLabelGetNumValues(label,&depth);CHKERRQ(ierr); 5484e071409bSToby Isaac ierr = DMLabelGetValue(label,point,&h);CHKERRQ(ierr); 5485e071409bSToby Isaac h = depth - 1 - h; 5486e071409bSToby Isaac if (h) { 5487e071409bSToby Isaac ierr = PetscDualSpaceGetHeightSubspace(dsp,h,dspace);CHKERRQ(ierr); 5488e071409bSToby Isaac } else { 5489e071409bSToby Isaac *dspace = dsp; 5490e071409bSToby Isaac } 5491e071409bSToby Isaac } 5492e071409bSToby Isaac } 5493e071409bSToby Isaac PetscFunctionReturn(0); 5494e071409bSToby Isaac } 5495e071409bSToby Isaac 54969fbee547SJacob Faibussowitsch static inline PetscErrorCode DMPlexVecGetClosure_Depth1_Static(DM dm, PetscSection section, Vec v, PetscInt point, PetscInt *csize, PetscScalar *values[]) 5497a6dfd86eSKarl Rupp { 5498552f7358SJed Brown PetscScalar *array, *vArray; 5499d9917b9dSMatthew G. Knepley const PetscInt *cone, *coneO; 55001a271a75SMatthew G. Knepley PetscInt pStart, pEnd, p, numPoints, size = 0, offset = 0; 5501552f7358SJed Brown PetscErrorCode ierr; 5502552f7358SJed Brown 55031b406b76SMatthew G. Knepley PetscFunctionBeginHot; 55042a3aaacfSMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 55055a1bb5cfSMatthew G. Knepley ierr = DMPlexGetConeSize(dm, point, &numPoints);CHKERRQ(ierr); 55065a1bb5cfSMatthew G. Knepley ierr = DMPlexGetCone(dm, point, &cone);CHKERRQ(ierr); 55075a1bb5cfSMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, point, &coneO);CHKERRQ(ierr); 55083f7cbbe7SMatthew G. Knepley if (!values || !*values) { 55099df71ca4SMatthew G. Knepley if ((point >= pStart) && (point < pEnd)) { 55109df71ca4SMatthew G. Knepley PetscInt dof; 5511d9917b9dSMatthew G. Knepley 55129df71ca4SMatthew G. Knepley ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 55139df71ca4SMatthew G. Knepley size += dof; 55149df71ca4SMatthew G. Knepley } 55159df71ca4SMatthew G. Knepley for (p = 0; p < numPoints; ++p) { 55169df71ca4SMatthew G. Knepley const PetscInt cp = cone[p]; 55172a3aaacfSMatthew G. Knepley PetscInt dof; 55185a1bb5cfSMatthew G. Knepley 55195a1bb5cfSMatthew G. Knepley if ((cp < pStart) || (cp >= pEnd)) continue; 55202a3aaacfSMatthew G. Knepley ierr = PetscSectionGetDof(section, cp, &dof);CHKERRQ(ierr); 55215a1bb5cfSMatthew G. Knepley size += dof; 55225a1bb5cfSMatthew G. Knepley } 55233f7cbbe7SMatthew G. Knepley if (!values) { 55243f7cbbe7SMatthew G. Knepley if (csize) *csize = size; 55253f7cbbe7SMatthew G. Knepley PetscFunctionReturn(0); 55263f7cbbe7SMatthew G. Knepley } 552769291d52SBarry Smith ierr = DMGetWorkArray(dm, size, MPIU_SCALAR, &array);CHKERRQ(ierr); 5528982e9ed1SMatthew G. Knepley } else { 5529982e9ed1SMatthew G. Knepley array = *values; 5530982e9ed1SMatthew G. Knepley } 55319df71ca4SMatthew G. Knepley size = 0; 55325a1bb5cfSMatthew G. Knepley ierr = VecGetArray(v, &vArray);CHKERRQ(ierr); 55339df71ca4SMatthew G. Knepley if ((point >= pStart) && (point < pEnd)) { 55349df71ca4SMatthew G. Knepley PetscInt dof, off, d; 55359df71ca4SMatthew G. Knepley PetscScalar *varr; 5536d9917b9dSMatthew G. Knepley 55379df71ca4SMatthew G. Knepley ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 55389df71ca4SMatthew G. Knepley ierr = PetscSectionGetOffset(section, point, &off);CHKERRQ(ierr); 55399df71ca4SMatthew G. Knepley varr = &vArray[off]; 55401a271a75SMatthew G. Knepley for (d = 0; d < dof; ++d, ++offset) { 55411a271a75SMatthew G. Knepley array[offset] = varr[d]; 55429df71ca4SMatthew G. Knepley } 55439df71ca4SMatthew G. Knepley size += dof; 55449df71ca4SMatthew G. Knepley } 55459df71ca4SMatthew G. Knepley for (p = 0; p < numPoints; ++p) { 55469df71ca4SMatthew G. Knepley const PetscInt cp = cone[p]; 55479df71ca4SMatthew G. Knepley PetscInt o = coneO[p]; 55485a1bb5cfSMatthew G. Knepley PetscInt dof, off, d; 55495a1bb5cfSMatthew G. Knepley PetscScalar *varr; 55505a1bb5cfSMatthew G. Knepley 555152ed52e8SMatthew G. Knepley if ((cp < pStart) || (cp >= pEnd)) continue; 55525a1bb5cfSMatthew G. Knepley ierr = PetscSectionGetDof(section, cp, &dof);CHKERRQ(ierr); 55535a1bb5cfSMatthew G. Knepley ierr = PetscSectionGetOffset(section, cp, &off);CHKERRQ(ierr); 55545a1bb5cfSMatthew G. Knepley varr = &vArray[off]; 55555a1bb5cfSMatthew G. Knepley if (o >= 0) { 55561a271a75SMatthew G. Knepley for (d = 0; d < dof; ++d, ++offset) { 55571a271a75SMatthew G. Knepley array[offset] = varr[d]; 55585a1bb5cfSMatthew G. Knepley } 55595a1bb5cfSMatthew G. Knepley } else { 55601a271a75SMatthew G. Knepley for (d = dof-1; d >= 0; --d, ++offset) { 55611a271a75SMatthew G. Knepley array[offset] = varr[d]; 55625a1bb5cfSMatthew G. Knepley } 55635a1bb5cfSMatthew G. Knepley } 55649df71ca4SMatthew G. Knepley size += dof; 55655a1bb5cfSMatthew G. Knepley } 55665a1bb5cfSMatthew G. Knepley ierr = VecRestoreArray(v, &vArray);CHKERRQ(ierr); 55679df71ca4SMatthew G. Knepley if (!*values) { 55685a1bb5cfSMatthew G. Knepley if (csize) *csize = size; 55695a1bb5cfSMatthew G. Knepley *values = array; 55709df71ca4SMatthew G. Knepley } else { 55712c71b3e2SJacob Faibussowitsch PetscCheckFalse(size > *csize,PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Size of input array %D < actual size %D", *csize, size); 55728c312ff3SMatthew G. Knepley *csize = size; 55739df71ca4SMatthew G. Knepley } 55745a1bb5cfSMatthew G. Knepley PetscFunctionReturn(0); 55755a1bb5cfSMatthew G. Knepley } 5576d9917b9dSMatthew G. Knepley 557727f02ce8SMatthew G. Knepley /* Compress out points not in the section */ 55789fbee547SJacob Faibussowitsch static inline PetscErrorCode CompressPoints_Private(PetscSection section, PetscInt *numPoints, PetscInt points[]) 557927f02ce8SMatthew G. Knepley { 558027f02ce8SMatthew G. Knepley const PetscInt np = *numPoints; 558127f02ce8SMatthew G. Knepley PetscInt pStart, pEnd, p, q; 558227f02ce8SMatthew G. Knepley PetscErrorCode ierr; 558327f02ce8SMatthew G. Knepley 558427f02ce8SMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 558527f02ce8SMatthew G. Knepley for (p = 0, q = 0; p < np; ++p) { 558627f02ce8SMatthew G. Knepley const PetscInt r = points[p*2]; 558727f02ce8SMatthew G. Knepley if ((r >= pStart) && (r < pEnd)) { 558827f02ce8SMatthew G. Knepley points[q*2] = r; 558927f02ce8SMatthew G. Knepley points[q*2+1] = points[p*2+1]; 559027f02ce8SMatthew G. Knepley ++q; 559127f02ce8SMatthew G. Knepley } 559227f02ce8SMatthew G. Knepley } 559327f02ce8SMatthew G. Knepley *numPoints = q; 559427f02ce8SMatthew G. Knepley return 0; 559527f02ce8SMatthew G. Knepley } 559627f02ce8SMatthew G. Knepley 559797529cf3SJed Brown /* Compressed closure does not apply closure permutation */ 55981dc59d61SMatthew G. Knepley PetscErrorCode DMPlexGetCompressedClosure(DM dm, PetscSection section, PetscInt point, PetscInt *numPoints, PetscInt **points, PetscSection *clSec, IS *clPoints, const PetscInt **clp) 5599923c78e0SToby Isaac { 560027f02ce8SMatthew G. Knepley const PetscInt *cla = NULL; 5601923c78e0SToby Isaac PetscInt np, *pts = NULL; 5602923c78e0SToby Isaac PetscErrorCode ierr; 5603923c78e0SToby Isaac 5604923c78e0SToby Isaac PetscFunctionBeginHot; 5605923c78e0SToby Isaac ierr = PetscSectionGetClosureIndex(section, (PetscObject) dm, clSec, clPoints);CHKERRQ(ierr); 560627f02ce8SMatthew G. Knepley if (*clPoints) { 5607923c78e0SToby Isaac PetscInt dof, off; 5608923c78e0SToby Isaac 5609923c78e0SToby Isaac ierr = PetscSectionGetDof(*clSec, point, &dof);CHKERRQ(ierr); 5610923c78e0SToby Isaac ierr = PetscSectionGetOffset(*clSec, point, &off);CHKERRQ(ierr); 5611923c78e0SToby Isaac ierr = ISGetIndices(*clPoints, &cla);CHKERRQ(ierr); 5612923c78e0SToby Isaac np = dof/2; 5613923c78e0SToby Isaac pts = (PetscInt *) &cla[off]; 561427f02ce8SMatthew G. Knepley } else { 561527f02ce8SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, point, PETSC_TRUE, &np, &pts);CHKERRQ(ierr); 561627f02ce8SMatthew G. Knepley ierr = CompressPoints_Private(section, &np, pts);CHKERRQ(ierr); 5617923c78e0SToby Isaac } 5618923c78e0SToby Isaac *numPoints = np; 5619923c78e0SToby Isaac *points = pts; 5620923c78e0SToby Isaac *clp = cla; 5621923c78e0SToby Isaac PetscFunctionReturn(0); 5622923c78e0SToby Isaac } 5623923c78e0SToby Isaac 56241dc59d61SMatthew G. Knepley PetscErrorCode DMPlexRestoreCompressedClosure(DM dm, PetscSection section, PetscInt point, PetscInt *numPoints, PetscInt **points, PetscSection *clSec, IS *clPoints, const PetscInt **clp) 5625923c78e0SToby Isaac { 5626923c78e0SToby Isaac PetscErrorCode ierr; 5627923c78e0SToby Isaac 5628923c78e0SToby Isaac PetscFunctionBeginHot; 5629923c78e0SToby Isaac if (!*clPoints) { 5630923c78e0SToby Isaac ierr = DMPlexRestoreTransitiveClosure(dm, point, PETSC_TRUE, numPoints, points);CHKERRQ(ierr); 5631923c78e0SToby Isaac } else { 5632923c78e0SToby Isaac ierr = ISRestoreIndices(*clPoints, clp);CHKERRQ(ierr); 5633923c78e0SToby Isaac } 5634923c78e0SToby Isaac *numPoints = 0; 5635923c78e0SToby Isaac *points = NULL; 5636923c78e0SToby Isaac *clSec = NULL; 5637923c78e0SToby Isaac *clPoints = NULL; 5638923c78e0SToby Isaac *clp = NULL; 5639923c78e0SToby Isaac PetscFunctionReturn(0); 5640923c78e0SToby Isaac } 5641923c78e0SToby Isaac 56429fbee547SJacob 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[]) 56431a271a75SMatthew G. Knepley { 56441a271a75SMatthew G. Knepley PetscInt offset = 0, p; 564597e99dd9SToby Isaac const PetscInt **perms = NULL; 564697e99dd9SToby Isaac const PetscScalar **flips = NULL; 56471a271a75SMatthew G. Knepley PetscErrorCode ierr; 56481a271a75SMatthew G. Knepley 56491a271a75SMatthew G. Knepley PetscFunctionBeginHot; 5650fe02ba77SJed Brown *size = 0; 565197e99dd9SToby Isaac ierr = PetscSectionGetPointSyms(section,numPoints,points,&perms,&flips);CHKERRQ(ierr); 565297e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 565397e99dd9SToby Isaac const PetscInt point = points[2*p]; 565497e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 565597e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 56561a271a75SMatthew G. Knepley PetscInt dof, off, d; 56571a271a75SMatthew G. Knepley const PetscScalar *varr; 56581a271a75SMatthew G. Knepley 56591a271a75SMatthew G. Knepley ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 56601a271a75SMatthew G. Knepley ierr = PetscSectionGetOffset(section, point, &off);CHKERRQ(ierr); 56611a271a75SMatthew G. Knepley varr = &vArray[off]; 566297e99dd9SToby Isaac if (clperm) { 566397e99dd9SToby Isaac if (perm) { 566497e99dd9SToby Isaac for (d = 0; d < dof; d++) array[clperm[offset + perm[d]]] = varr[d]; 56651a271a75SMatthew G. Knepley } else { 566697e99dd9SToby Isaac for (d = 0; d < dof; d++) array[clperm[offset + d ]] = varr[d]; 566797e99dd9SToby Isaac } 566897e99dd9SToby Isaac if (flip) { 566997e99dd9SToby Isaac for (d = 0; d < dof; d++) array[clperm[offset + d ]] *= flip[d]; 567097e99dd9SToby Isaac } 567197e99dd9SToby Isaac } else { 567297e99dd9SToby Isaac if (perm) { 567397e99dd9SToby Isaac for (d = 0; d < dof; d++) array[offset + perm[d]] = varr[d]; 567497e99dd9SToby Isaac } else { 567597e99dd9SToby Isaac for (d = 0; d < dof; d++) array[offset + d ] = varr[d]; 567697e99dd9SToby Isaac } 567797e99dd9SToby Isaac if (flip) { 567897e99dd9SToby Isaac for (d = 0; d < dof; d++) array[offset + d ] *= flip[d]; 56791a271a75SMatthew G. Knepley } 56801a271a75SMatthew G. Knepley } 568197e99dd9SToby Isaac offset += dof; 568297e99dd9SToby Isaac } 568397e99dd9SToby Isaac ierr = PetscSectionRestorePointSyms(section,numPoints,points,&perms,&flips);CHKERRQ(ierr); 56841a271a75SMatthew G. Knepley *size = offset; 56851a271a75SMatthew G. Knepley PetscFunctionReturn(0); 56861a271a75SMatthew G. Knepley } 56871a271a75SMatthew G. Knepley 56889fbee547SJacob 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[]) 56891a271a75SMatthew G. Knepley { 56901a271a75SMatthew G. Knepley PetscInt offset = 0, f; 56911a271a75SMatthew G. Knepley PetscErrorCode ierr; 56921a271a75SMatthew G. Knepley 56931a271a75SMatthew G. Knepley PetscFunctionBeginHot; 5694fe02ba77SJed Brown *size = 0; 56951a271a75SMatthew G. Knepley for (f = 0; f < numFields; ++f) { 569697e99dd9SToby Isaac PetscInt p; 569797e99dd9SToby Isaac const PetscInt **perms = NULL; 569897e99dd9SToby Isaac const PetscScalar **flips = NULL; 56991a271a75SMatthew G. Knepley 570097e99dd9SToby Isaac ierr = PetscSectionGetFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 570197e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 570297e99dd9SToby Isaac const PetscInt point = points[2*p]; 570397e99dd9SToby Isaac PetscInt fdof, foff, b; 57041a271a75SMatthew G. Knepley const PetscScalar *varr; 570597e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 570697e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 57071a271a75SMatthew G. Knepley 57081a271a75SMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 57091a271a75SMatthew G. Knepley ierr = PetscSectionGetFieldOffset(section, point, f, &foff);CHKERRQ(ierr); 57101a271a75SMatthew G. Knepley varr = &vArray[foff]; 571197e99dd9SToby Isaac if (clperm) { 571297e99dd9SToby Isaac if (perm) {for (b = 0; b < fdof; b++) {array[clperm[offset + perm[b]]] = varr[b];}} 571397e99dd9SToby Isaac else {for (b = 0; b < fdof; b++) {array[clperm[offset + b ]] = varr[b];}} 571497e99dd9SToby Isaac if (flip) {for (b = 0; b < fdof; b++) {array[clperm[offset + b ]] *= flip[b];}} 57151a271a75SMatthew G. Knepley } else { 571697e99dd9SToby Isaac if (perm) {for (b = 0; b < fdof; b++) {array[offset + perm[b]] = varr[b];}} 571797e99dd9SToby Isaac else {for (b = 0; b < fdof; b++) {array[offset + b ] = varr[b];}} 571897e99dd9SToby Isaac if (flip) {for (b = 0; b < fdof; b++) {array[offset + b ] *= flip[b];}} 57191a271a75SMatthew G. Knepley } 572097e99dd9SToby Isaac offset += fdof; 57211a271a75SMatthew G. Knepley } 572297e99dd9SToby Isaac ierr = PetscSectionRestoreFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 57231a271a75SMatthew G. Knepley } 57241a271a75SMatthew G. Knepley *size = offset; 57251a271a75SMatthew G. Knepley PetscFunctionReturn(0); 57261a271a75SMatthew G. Knepley } 57271a271a75SMatthew G. Knepley 5728552f7358SJed Brown /*@C 5729552f7358SJed Brown DMPlexVecGetClosure - Get an array of the values on the closure of 'point' 5730552f7358SJed Brown 5731552f7358SJed Brown Not collective 5732552f7358SJed Brown 5733552f7358SJed Brown Input Parameters: 5734552f7358SJed Brown + dm - The DM 5735552f7358SJed Brown . section - The section describing the layout in v, or NULL to use the default section 5736552f7358SJed Brown . v - The local vector 57376b867d5aSJose E. Roman - point - The point in the DM 5738552f7358SJed Brown 57396b867d5aSJose E. Roman Input/Output Parameters: 57406b867d5aSJose E. Roman + csize - The size of the input values array, or NULL; on output the number of values in the closure 57416b867d5aSJose E. Roman - values - An array to use for the values, or NULL to have it allocated automatically; 57426b867d5aSJose E. Roman if the user provided NULL, it is a borrowed array and should not be freed 574322c1ee49SMatthew G. Knepley 574422c1ee49SMatthew G. Knepley $ Note that DMPlexVecGetClosure/DMPlexVecRestoreClosure only allocates the values array if it set to NULL in the 574522c1ee49SMatthew G. Knepley $ calling function. This is because DMPlexVecGetClosure() is typically called in the inner loop of a Vec or Mat 574622c1ee49SMatthew G. Knepley $ assembly function, and a user may already have allocated storage for this operation. 574722c1ee49SMatthew G. Knepley $ 574822c1ee49SMatthew G. Knepley $ A typical use could be 574922c1ee49SMatthew G. Knepley $ 575022c1ee49SMatthew G. Knepley $ values = NULL; 575122c1ee49SMatthew G. Knepley $ ierr = DMPlexVecGetClosure(dm, NULL, v, p, &clSize, &values);CHKERRQ(ierr); 575222c1ee49SMatthew G. Knepley $ for (cl = 0; cl < clSize; ++cl) { 575322c1ee49SMatthew G. Knepley $ <Compute on closure> 575422c1ee49SMatthew G. Knepley $ } 575522c1ee49SMatthew G. Knepley $ ierr = DMPlexVecRestoreClosure(dm, NULL, v, p, &clSize, &values);CHKERRQ(ierr); 575622c1ee49SMatthew G. Knepley $ 575722c1ee49SMatthew G. Knepley $ or 575822c1ee49SMatthew G. Knepley $ 575922c1ee49SMatthew G. Knepley $ PetscMalloc1(clMaxSize, &values); 576022c1ee49SMatthew G. Knepley $ for (p = pStart; p < pEnd; ++p) { 576122c1ee49SMatthew G. Knepley $ clSize = clMaxSize; 576222c1ee49SMatthew G. Knepley $ ierr = DMPlexVecGetClosure(dm, NULL, v, p, &clSize, &values);CHKERRQ(ierr); 576322c1ee49SMatthew G. Knepley $ for (cl = 0; cl < clSize; ++cl) { 576422c1ee49SMatthew G. Knepley $ <Compute on closure> 576522c1ee49SMatthew G. Knepley $ } 576622c1ee49SMatthew G. Knepley $ } 576722c1ee49SMatthew G. Knepley $ PetscFree(values); 5768552f7358SJed Brown 5769552f7358SJed Brown Fortran Notes: 5770552f7358SJed Brown Since it returns an array, this routine is only available in Fortran 90, and you must 5771552f7358SJed Brown include petsc.h90 in your code. 5772552f7358SJed Brown 5773552f7358SJed Brown The csize argument is not present in the Fortran 90 binding since it is internal to the array. 5774552f7358SJed Brown 5775552f7358SJed Brown Level: intermediate 5776552f7358SJed Brown 5777552f7358SJed Brown .seealso DMPlexVecRestoreClosure(), DMPlexVecSetClosure(), DMPlexMatSetClosure() 5778552f7358SJed Brown @*/ 5779552f7358SJed Brown PetscErrorCode DMPlexVecGetClosure(DM dm, PetscSection section, Vec v, PetscInt point, PetscInt *csize, PetscScalar *values[]) 5780552f7358SJed Brown { 5781552f7358SJed Brown PetscSection clSection; 5782d9917b9dSMatthew G. Knepley IS clPoints; 5783552f7358SJed Brown PetscInt *points = NULL; 5784c459fbc1SJed Brown const PetscInt *clp, *perm; 5785c459fbc1SJed Brown PetscInt depth, numFields, numPoints, asize; 5786552f7358SJed Brown PetscErrorCode ierr; 5787552f7358SJed Brown 5788d9917b9dSMatthew G. Knepley PetscFunctionBeginHot; 5789552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 579092fd8e1eSJed Brown if (!section) {ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr);} 57911a271a75SMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 57921a271a75SMatthew G. Knepley PetscValidHeaderSpecific(v, VEC_CLASSID, 3); 5793552f7358SJed Brown ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 5794552f7358SJed Brown ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 5795552f7358SJed Brown if (depth == 1 && numFields < 2) { 57961a271a75SMatthew G. Knepley ierr = DMPlexVecGetClosure_Depth1_Static(dm, section, v, point, csize, values);CHKERRQ(ierr); 5797552f7358SJed Brown PetscFunctionReturn(0); 5798552f7358SJed Brown } 57991a271a75SMatthew G. Knepley /* Get points */ 5800923c78e0SToby Isaac ierr = DMPlexGetCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 5801c459fbc1SJed Brown /* Get sizes */ 5802c459fbc1SJed Brown asize = 0; 5803c459fbc1SJed Brown for (PetscInt p = 0; p < numPoints*2; p += 2) { 5804c459fbc1SJed Brown PetscInt dof; 5805552f7358SJed Brown ierr = PetscSectionGetDof(section, points[p], &dof);CHKERRQ(ierr); 58061a271a75SMatthew G. Knepley asize += dof; 5807552f7358SJed Brown } 5808c459fbc1SJed Brown if (values) { 5809c459fbc1SJed Brown const PetscScalar *vArray; 5810c459fbc1SJed Brown PetscInt size; 5811c459fbc1SJed Brown 5812c459fbc1SJed Brown if (*values) { 58132c71b3e2SJacob Faibussowitsch PetscCheckFalse(*csize < asize,PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Provided array size %D not sufficient to hold closure size %D", *csize, asize); 5814c459fbc1SJed Brown } else {ierr = DMGetWorkArray(dm, asize, MPIU_SCALAR, values);CHKERRQ(ierr);} 5815c459fbc1SJed Brown ierr = PetscSectionGetClosureInversePermutation_Internal(section, (PetscObject) dm, depth, asize, &perm);CHKERRQ(ierr); 58168a84db2dSMatthew G. Knepley ierr = VecGetArrayRead(v, &vArray);CHKERRQ(ierr); 58171a271a75SMatthew G. Knepley /* Get values */ 5818c459fbc1SJed Brown if (numFields > 0) {ierr = DMPlexVecGetClosure_Fields_Static(dm, section, numPoints, points, numFields, perm, vArray, &size, *values);CHKERRQ(ierr);} 5819c459fbc1SJed Brown else {ierr = DMPlexVecGetClosure_Static(dm, section, numPoints, points, perm, vArray, &size, *values);CHKERRQ(ierr);} 58202c71b3e2SJacob Faibussowitsch PetscCheckFalse(asize != size,PETSC_COMM_SELF, PETSC_ERR_PLIB, "Section size %D does not match Vec closure size %D", asize, size); 58211a271a75SMatthew G. Knepley /* Cleanup array */ 58228a84db2dSMatthew G. Knepley ierr = VecRestoreArrayRead(v, &vArray);CHKERRQ(ierr); 5823d0f6b257SMatthew G. Knepley } 5824c459fbc1SJed Brown if (csize) *csize = asize; 5825c459fbc1SJed Brown /* Cleanup points */ 5826c459fbc1SJed Brown ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 5827552f7358SJed Brown PetscFunctionReturn(0); 5828552f7358SJed Brown } 5829552f7358SJed Brown 5830e5c487bfSMatthew G. Knepley PetscErrorCode DMPlexVecGetClosureAtDepth_Internal(DM dm, PetscSection section, Vec v, PetscInt point, PetscInt depth, PetscInt *csize, PetscScalar *values[]) 5831e5c487bfSMatthew G. Knepley { 5832e5c487bfSMatthew G. Knepley DMLabel depthLabel; 5833e5c487bfSMatthew G. Knepley PetscSection clSection; 5834e5c487bfSMatthew G. Knepley IS clPoints; 5835e5c487bfSMatthew G. Knepley PetscScalar *array; 5836e5c487bfSMatthew G. Knepley const PetscScalar *vArray; 5837e5c487bfSMatthew G. Knepley PetscInt *points = NULL; 5838c459fbc1SJed Brown const PetscInt *clp, *perm = NULL; 5839c459fbc1SJed Brown PetscInt mdepth, numFields, numPoints, Np = 0, p, clsize, size; 5840e5c487bfSMatthew G. Knepley PetscErrorCode ierr; 5841e5c487bfSMatthew G. Knepley 5842e5c487bfSMatthew G. Knepley PetscFunctionBeginHot; 5843e5c487bfSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5844e5c487bfSMatthew G. Knepley if (!section) {ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr);} 5845e5c487bfSMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 5846e5c487bfSMatthew G. Knepley PetscValidHeaderSpecific(v, VEC_CLASSID, 3); 5847e5c487bfSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &mdepth);CHKERRQ(ierr); 5848e5c487bfSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &depthLabel);CHKERRQ(ierr); 5849e5c487bfSMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 5850e5c487bfSMatthew G. Knepley if (mdepth == 1 && numFields < 2) { 5851e5c487bfSMatthew G. Knepley ierr = DMPlexVecGetClosure_Depth1_Static(dm, section, v, point, csize, values);CHKERRQ(ierr); 5852e5c487bfSMatthew G. Knepley PetscFunctionReturn(0); 5853e5c487bfSMatthew G. Knepley } 5854e5c487bfSMatthew G. Knepley /* Get points */ 5855e5c487bfSMatthew G. Knepley ierr = DMPlexGetCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 5856c459fbc1SJed Brown for (clsize=0,p=0; p<Np; p++) { 5857c459fbc1SJed Brown PetscInt dof; 5858c459fbc1SJed Brown ierr = PetscSectionGetDof(section, points[2*p], &dof);CHKERRQ(ierr); 5859c459fbc1SJed Brown clsize += dof; 5860c459fbc1SJed Brown } 5861c459fbc1SJed Brown ierr = PetscSectionGetClosureInversePermutation_Internal(section, (PetscObject) dm, depth, clsize, &perm);CHKERRQ(ierr); 5862e5c487bfSMatthew G. Knepley /* Filter points */ 5863e5c487bfSMatthew G. Knepley for (p = 0; p < numPoints*2; p += 2) { 5864e5c487bfSMatthew G. Knepley PetscInt dep; 5865e5c487bfSMatthew G. Knepley 5866e5c487bfSMatthew G. Knepley ierr = DMLabelGetValue(depthLabel, points[p], &dep);CHKERRQ(ierr); 5867e5c487bfSMatthew G. Knepley if (dep != depth) continue; 5868e5c487bfSMatthew G. Knepley points[Np*2+0] = points[p]; 5869e5c487bfSMatthew G. Knepley points[Np*2+1] = points[p+1]; 5870e5c487bfSMatthew G. Knepley ++Np; 5871e5c487bfSMatthew G. Knepley } 5872e5c487bfSMatthew G. Knepley /* Get array */ 5873e5c487bfSMatthew G. Knepley if (!values || !*values) { 5874e5c487bfSMatthew G. Knepley PetscInt asize = 0, dof; 5875e5c487bfSMatthew G. Knepley 5876e5c487bfSMatthew G. Knepley for (p = 0; p < Np*2; p += 2) { 5877e5c487bfSMatthew G. Knepley ierr = PetscSectionGetDof(section, points[p], &dof);CHKERRQ(ierr); 5878e5c487bfSMatthew G. Knepley asize += dof; 5879e5c487bfSMatthew G. Knepley } 5880e5c487bfSMatthew G. Knepley if (!values) { 5881e5c487bfSMatthew G. Knepley ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 5882e5c487bfSMatthew G. Knepley if (csize) *csize = asize; 5883e5c487bfSMatthew G. Knepley PetscFunctionReturn(0); 5884e5c487bfSMatthew G. Knepley } 5885e5c487bfSMatthew G. Knepley ierr = DMGetWorkArray(dm, asize, MPIU_SCALAR, &array);CHKERRQ(ierr); 5886e5c487bfSMatthew G. Knepley } else { 5887e5c487bfSMatthew G. Knepley array = *values; 5888e5c487bfSMatthew G. Knepley } 5889e5c487bfSMatthew G. Knepley ierr = VecGetArrayRead(v, &vArray);CHKERRQ(ierr); 5890e5c487bfSMatthew G. Knepley /* Get values */ 5891e5c487bfSMatthew G. Knepley if (numFields > 0) {ierr = DMPlexVecGetClosure_Fields_Static(dm, section, Np, points, numFields, perm, vArray, &size, array);CHKERRQ(ierr);} 5892e5c487bfSMatthew G. Knepley else {ierr = DMPlexVecGetClosure_Static(dm, section, Np, points, perm, vArray, &size, array);CHKERRQ(ierr);} 5893e5c487bfSMatthew G. Knepley /* Cleanup points */ 5894e5c487bfSMatthew G. Knepley ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 5895e5c487bfSMatthew G. Knepley /* Cleanup array */ 5896e5c487bfSMatthew G. Knepley ierr = VecRestoreArrayRead(v, &vArray);CHKERRQ(ierr); 5897e5c487bfSMatthew G. Knepley if (!*values) { 5898e5c487bfSMatthew G. Knepley if (csize) *csize = size; 5899e5c487bfSMatthew G. Knepley *values = array; 5900e5c487bfSMatthew G. Knepley } else { 59012c71b3e2SJacob Faibussowitsch PetscCheckFalse(size > *csize,PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Size of input array %D < actual size %D", *csize, size); 5902e5c487bfSMatthew G. Knepley *csize = size; 5903e5c487bfSMatthew G. Knepley } 5904e5c487bfSMatthew G. Knepley PetscFunctionReturn(0); 5905e5c487bfSMatthew G. Knepley } 5906e5c487bfSMatthew G. Knepley 5907552f7358SJed Brown /*@C 5908552f7358SJed Brown DMPlexVecRestoreClosure - Restore the array of the values on the closure of 'point' 5909552f7358SJed Brown 5910552f7358SJed Brown Not collective 5911552f7358SJed Brown 5912552f7358SJed Brown Input Parameters: 5913552f7358SJed Brown + dm - The DM 59140298fd71SBarry Smith . section - The section describing the layout in v, or NULL to use the default section 5915552f7358SJed Brown . v - The local vector 5916eaf898f9SPatrick Sanan . point - The point in the DM 59170298fd71SBarry Smith . csize - The number of values in the closure, or NULL 5918552f7358SJed Brown - values - The array of values, which is a borrowed array and should not be freed 5919552f7358SJed Brown 592022c1ee49SMatthew 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() 592122c1ee49SMatthew G. Knepley 59223813dfbdSMatthew G Knepley Fortran Notes: 59233813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 59243813dfbdSMatthew G Knepley include petsc.h90 in your code. 59253813dfbdSMatthew G Knepley 59263813dfbdSMatthew G Knepley The csize argument is not present in the Fortran 90 binding since it is internal to the array. 59273813dfbdSMatthew G Knepley 5928552f7358SJed Brown Level: intermediate 5929552f7358SJed Brown 5930552f7358SJed Brown .seealso DMPlexVecGetClosure(), DMPlexVecSetClosure(), DMPlexMatSetClosure() 5931552f7358SJed Brown @*/ 59327c1f9639SMatthew G Knepley PetscErrorCode DMPlexVecRestoreClosure(DM dm, PetscSection section, Vec v, PetscInt point, PetscInt *csize, PetscScalar *values[]) 5933a6dfd86eSKarl Rupp { 5934552f7358SJed Brown PetscInt size = 0; 5935552f7358SJed Brown PetscErrorCode ierr; 5936552f7358SJed Brown 5937552f7358SJed Brown PetscFunctionBegin; 5938552f7358SJed Brown /* Should work without recalculating size */ 593969291d52SBarry Smith ierr = DMRestoreWorkArray(dm, size, MPIU_SCALAR, (void*) values);CHKERRQ(ierr); 5940c9fdaa05SMatthew G. Knepley *values = NULL; 5941552f7358SJed Brown PetscFunctionReturn(0); 5942552f7358SJed Brown } 5943552f7358SJed Brown 59449fbee547SJacob Faibussowitsch static inline void add (PetscScalar *x, PetscScalar y) {*x += y;} 59459fbee547SJacob Faibussowitsch static inline void insert(PetscScalar *x, PetscScalar y) {*x = y;} 5946552f7358SJed Brown 59479fbee547SJacob 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[]) 5948552f7358SJed Brown { 5949552f7358SJed Brown PetscInt cdof; /* The number of constraints on this point */ 5950552f7358SJed Brown const PetscInt *cdofs; /* The indices of the constrained dofs on this point */ 5951552f7358SJed Brown PetscScalar *a; 5952552f7358SJed Brown PetscInt off, cind = 0, k; 5953552f7358SJed Brown PetscErrorCode ierr; 5954552f7358SJed Brown 5955552f7358SJed Brown PetscFunctionBegin; 5956552f7358SJed Brown ierr = PetscSectionGetConstraintDof(section, point, &cdof);CHKERRQ(ierr); 5957552f7358SJed Brown ierr = PetscSectionGetOffset(section, point, &off);CHKERRQ(ierr); 5958552f7358SJed Brown a = &array[off]; 5959552f7358SJed Brown if (!cdof || setBC) { 596097e99dd9SToby Isaac if (clperm) { 596197e99dd9SToby Isaac if (perm) {for (k = 0; k < dof; ++k) {fuse(&a[k], values[clperm[offset+perm[k]]] * (flip ? flip[perm[k]] : 1.));}} 596297e99dd9SToby Isaac else {for (k = 0; k < dof; ++k) {fuse(&a[k], values[clperm[offset+ k ]] * (flip ? flip[ k ] : 1.));}} 5963552f7358SJed Brown } else { 596497e99dd9SToby Isaac if (perm) {for (k = 0; k < dof; ++k) {fuse(&a[k], values[offset+perm[k]] * (flip ? flip[perm[k]] : 1.));}} 596597e99dd9SToby Isaac else {for (k = 0; k < dof; ++k) {fuse(&a[k], values[offset+ k ] * (flip ? flip[ k ] : 1.));}} 5966552f7358SJed Brown } 5967552f7358SJed Brown } else { 5968552f7358SJed Brown ierr = PetscSectionGetConstraintIndices(section, point, &cdofs);CHKERRQ(ierr); 596997e99dd9SToby Isaac if (clperm) { 597097e99dd9SToby Isaac if (perm) {for (k = 0; k < dof; ++k) { 5971552f7358SJed Brown if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 597297e99dd9SToby Isaac fuse(&a[k], values[clperm[offset+perm[k]]] * (flip ? flip[perm[k]] : 1.)); 5973552f7358SJed Brown } 5974552f7358SJed Brown } else { 5975552f7358SJed Brown for (k = 0; k < dof; ++k) { 5976552f7358SJed Brown if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 597797e99dd9SToby Isaac fuse(&a[k], values[clperm[offset+ k ]] * (flip ? flip[ k ] : 1.)); 597897e99dd9SToby Isaac } 597997e99dd9SToby Isaac } 598097e99dd9SToby Isaac } else { 598197e99dd9SToby Isaac if (perm) { 598297e99dd9SToby Isaac for (k = 0; k < dof; ++k) { 598397e99dd9SToby Isaac if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 598497e99dd9SToby Isaac fuse(&a[k], values[offset+perm[k]] * (flip ? flip[perm[k]] : 1.)); 598597e99dd9SToby Isaac } 598697e99dd9SToby Isaac } else { 598797e99dd9SToby Isaac for (k = 0; k < dof; ++k) { 598897e99dd9SToby Isaac if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 598997e99dd9SToby Isaac fuse(&a[k], values[offset+ k ] * (flip ? flip[ k ] : 1.)); 599097e99dd9SToby Isaac } 5991552f7358SJed Brown } 5992552f7358SJed Brown } 5993552f7358SJed Brown } 5994552f7358SJed Brown PetscFunctionReturn(0); 5995552f7358SJed Brown } 5996552f7358SJed Brown 59979fbee547SJacob 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[]) 5998a5e93ea8SMatthew G. Knepley { 5999a5e93ea8SMatthew G. Knepley PetscInt cdof; /* The number of constraints on this point */ 6000a5e93ea8SMatthew G. Knepley const PetscInt *cdofs; /* The indices of the constrained dofs on this point */ 6001a5e93ea8SMatthew G. Knepley PetscScalar *a; 6002a5e93ea8SMatthew G. Knepley PetscInt off, cind = 0, k; 6003a5e93ea8SMatthew G. Knepley PetscErrorCode ierr; 6004a5e93ea8SMatthew G. Knepley 6005a5e93ea8SMatthew G. Knepley PetscFunctionBegin; 6006a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(section, point, &cdof);CHKERRQ(ierr); 6007a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetOffset(section, point, &off);CHKERRQ(ierr); 6008a5e93ea8SMatthew G. Knepley a = &array[off]; 6009a5e93ea8SMatthew G. Knepley if (cdof) { 6010a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetConstraintIndices(section, point, &cdofs);CHKERRQ(ierr); 601197e99dd9SToby Isaac if (clperm) { 601297e99dd9SToby Isaac if (perm) { 6013a5e93ea8SMatthew G. Knepley for (k = 0; k < dof; ++k) { 6014a5e93ea8SMatthew G. Knepley if ((cind < cdof) && (k == cdofs[cind])) { 601597e99dd9SToby Isaac fuse(&a[k], values[clperm[offset+perm[k]]] * (flip ? flip[perm[k]] : 1.)); 601697e99dd9SToby Isaac cind++; 6017a5e93ea8SMatthew G. Knepley } 6018a5e93ea8SMatthew G. Knepley } 6019a5e93ea8SMatthew G. Knepley } else { 6020a5e93ea8SMatthew G. Knepley for (k = 0; k < dof; ++k) { 6021a5e93ea8SMatthew G. Knepley if ((cind < cdof) && (k == cdofs[cind])) { 602297e99dd9SToby Isaac fuse(&a[k], values[clperm[offset+ k ]] * (flip ? flip[ k ] : 1.)); 602397e99dd9SToby Isaac cind++; 602497e99dd9SToby Isaac } 602597e99dd9SToby Isaac } 602697e99dd9SToby Isaac } 602797e99dd9SToby Isaac } else { 602897e99dd9SToby Isaac if (perm) { 602997e99dd9SToby Isaac for (k = 0; k < dof; ++k) { 603097e99dd9SToby Isaac if ((cind < cdof) && (k == cdofs[cind])) { 603197e99dd9SToby Isaac fuse(&a[k], values[offset+perm[k]] * (flip ? flip[perm[k]] : 1.)); 603297e99dd9SToby Isaac cind++; 603397e99dd9SToby Isaac } 603497e99dd9SToby Isaac } 603597e99dd9SToby Isaac } else { 603697e99dd9SToby Isaac for (k = 0; k < dof; ++k) { 603797e99dd9SToby Isaac if ((cind < cdof) && (k == cdofs[cind])) { 603897e99dd9SToby Isaac fuse(&a[k], values[offset+ k ] * (flip ? flip[ k ] : 1.)); 603997e99dd9SToby Isaac cind++; 604097e99dd9SToby Isaac } 6041a5e93ea8SMatthew G. Knepley } 6042a5e93ea8SMatthew G. Knepley } 6043a5e93ea8SMatthew G. Knepley } 6044a5e93ea8SMatthew G. Knepley } 6045a5e93ea8SMatthew G. Knepley PetscFunctionReturn(0); 6046a5e93ea8SMatthew G. Knepley } 6047a5e93ea8SMatthew G. Knepley 60489fbee547SJacob 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[]) 6049a6dfd86eSKarl Rupp { 6050552f7358SJed Brown PetscScalar *a; 60511a271a75SMatthew G. Knepley PetscInt fdof, foff, fcdof, foffset = *offset; 60521a271a75SMatthew G. Knepley const PetscInt *fcdofs; /* The indices of the constrained dofs for field f on this point */ 605397e99dd9SToby Isaac PetscInt cind = 0, b; 6054552f7358SJed Brown PetscErrorCode ierr; 6055552f7358SJed Brown 6056552f7358SJed Brown PetscFunctionBegin; 6057552f7358SJed Brown ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 6058552f7358SJed Brown ierr = PetscSectionGetFieldConstraintDof(section, point, f, &fcdof);CHKERRQ(ierr); 60591a271a75SMatthew G. Knepley ierr = PetscSectionGetFieldOffset(section, point, f, &foff);CHKERRQ(ierr); 60601a271a75SMatthew G. Knepley a = &array[foff]; 6061552f7358SJed Brown if (!fcdof || setBC) { 606297e99dd9SToby Isaac if (clperm) { 606397e99dd9SToby Isaac if (perm) {for (b = 0; b < fdof; b++) {fuse(&a[b], values[clperm[foffset+perm[b]]] * (flip ? flip[perm[b]] : 1.));}} 606497e99dd9SToby Isaac else {for (b = 0; b < fdof; b++) {fuse(&a[b], values[clperm[foffset+ b ]] * (flip ? flip[ b ] : 1.));}} 6065552f7358SJed Brown } else { 606697e99dd9SToby Isaac if (perm) {for (b = 0; b < fdof; b++) {fuse(&a[b], values[foffset+perm[b]] * (flip ? flip[perm[b]] : 1.));}} 606797e99dd9SToby Isaac else {for (b = 0; b < fdof; b++) {fuse(&a[b], values[foffset+ b ] * (flip ? flip[ b ] : 1.));}} 6068552f7358SJed Brown } 6069552f7358SJed Brown } else { 6070552f7358SJed Brown ierr = PetscSectionGetFieldConstraintIndices(section, point, f, &fcdofs);CHKERRQ(ierr); 607197e99dd9SToby Isaac if (clperm) { 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[clperm[foffset+perm[b]]] * (flip ? flip[perm[b]] : 1.)); 6076552f7358SJed Brown } 6077552f7358SJed Brown } 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[clperm[foffset+ b ]] * (flip ? flip[ b ] : 1.)); 608197e99dd9SToby Isaac } 608297e99dd9SToby Isaac } 608397e99dd9SToby Isaac } else { 608497e99dd9SToby Isaac if (perm) { 608597e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 608697e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; continue;} 608797e99dd9SToby Isaac fuse(&a[b], values[foffset+perm[b]] * (flip ? flip[perm[b]] : 1.)); 608897e99dd9SToby Isaac } 608997e99dd9SToby Isaac } else { 609097e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 609197e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; continue;} 609297e99dd9SToby Isaac fuse(&a[b], values[foffset+ b ] * (flip ? flip[ b ] : 1.)); 6093552f7358SJed Brown } 6094552f7358SJed Brown } 6095552f7358SJed Brown } 6096552f7358SJed Brown } 60971a271a75SMatthew G. Knepley *offset += fdof; 6098552f7358SJed Brown PetscFunctionReturn(0); 6099552f7358SJed Brown } 6100552f7358SJed Brown 61019fbee547SJacob 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[]) 6102a5e93ea8SMatthew G. Knepley { 6103a5e93ea8SMatthew G. Knepley PetscScalar *a; 61041a271a75SMatthew G. Knepley PetscInt fdof, foff, fcdof, foffset = *offset; 61051a271a75SMatthew G. Knepley const PetscInt *fcdofs; /* The indices of the constrained dofs for field f on this point */ 61065da9d227SMatthew G. Knepley PetscInt Nc, cind = 0, ncind = 0, b; 6107ba322698SMatthew G. Knepley PetscBool ncSet, fcSet; 6108a5e93ea8SMatthew G. Knepley PetscErrorCode ierr; 6109a5e93ea8SMatthew G. Knepley 6110a5e93ea8SMatthew G. Knepley PetscFunctionBegin; 61115da9d227SMatthew G. Knepley ierr = PetscSectionGetFieldComponents(section, f, &Nc);CHKERRQ(ierr); 6112a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 6113a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetFieldConstraintDof(section, point, f, &fcdof);CHKERRQ(ierr); 61141a271a75SMatthew G. Knepley ierr = PetscSectionGetFieldOffset(section, point, f, &foff);CHKERRQ(ierr); 61151a271a75SMatthew G. Knepley a = &array[foff]; 6116a5e93ea8SMatthew G. Knepley if (fcdof) { 6117ba322698SMatthew G. Knepley /* We just override fcdof and fcdofs with Ncc and comps */ 6118a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetFieldConstraintIndices(section, point, f, &fcdofs);CHKERRQ(ierr); 611997e99dd9SToby Isaac if (clperm) { 612097e99dd9SToby Isaac if (perm) { 6121ba322698SMatthew G. Knepley if (comps) { 6122ba322698SMatthew G. Knepley for (b = 0; b < fdof; b++) { 6123ba322698SMatthew G. Knepley ncSet = fcSet = PETSC_FALSE; 61245da9d227SMatthew G. Knepley if (b%Nc == comps[ncind]) {ncind = (ncind+1)%Ncc; ncSet = PETSC_TRUE;} 6125ba322698SMatthew G. Knepley if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; fcSet = PETSC_TRUE;} 6126ba322698SMatthew G. Knepley if (ncSet && fcSet) {fuse(&a[b], values[clperm[foffset+perm[b]]] * (flip ? flip[perm[b]] : 1.));} 6127ba322698SMatthew G. Knepley } 6128ba322698SMatthew G. Knepley } else { 612997e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 613097e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) { 613197e99dd9SToby Isaac fuse(&a[b], values[clperm[foffset+perm[b]]] * (flip ? flip[perm[b]] : 1.)); 6132a5e93ea8SMatthew G. Knepley ++cind; 6133a5e93ea8SMatthew G. Knepley } 6134a5e93ea8SMatthew G. Knepley } 6135ba322698SMatthew G. Knepley } 6136ba322698SMatthew G. Knepley } else { 6137ba322698SMatthew G. Knepley if (comps) { 6138ba322698SMatthew G. Knepley for (b = 0; b < fdof; b++) { 6139ba322698SMatthew G. Knepley ncSet = fcSet = PETSC_FALSE; 61405da9d227SMatthew G. Knepley if (b%Nc == comps[ncind]) {ncind = (ncind+1)%Ncc; ncSet = PETSC_TRUE;} 6141ba322698SMatthew G. Knepley if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; fcSet = PETSC_TRUE;} 6142ba322698SMatthew G. Knepley if (ncSet && fcSet) {fuse(&a[b], values[clperm[foffset+ b ]] * (flip ? flip[ b ] : 1.));} 6143ba322698SMatthew G. Knepley } 6144a5e93ea8SMatthew G. Knepley } else { 614597e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 614697e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) { 614797e99dd9SToby Isaac fuse(&a[b], values[clperm[foffset+ b ]] * (flip ? flip[ b ] : 1.)); 614897e99dd9SToby Isaac ++cind; 614997e99dd9SToby Isaac } 615097e99dd9SToby Isaac } 615197e99dd9SToby Isaac } 6152ba322698SMatthew G. Knepley } 615397e99dd9SToby Isaac } else { 615497e99dd9SToby Isaac if (perm) { 6155ba322698SMatthew G. Knepley if (comps) { 6156ba322698SMatthew G. Knepley for (b = 0; b < fdof; b++) { 6157ba322698SMatthew G. Knepley ncSet = fcSet = PETSC_FALSE; 61585da9d227SMatthew G. Knepley if (b%Nc == comps[ncind]) {ncind = (ncind+1)%Ncc; ncSet = PETSC_TRUE;} 6159ba322698SMatthew G. Knepley if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; fcSet = PETSC_TRUE;} 6160ba322698SMatthew G. Knepley if (ncSet && fcSet) {fuse(&a[b], values[foffset+perm[b]] * (flip ? flip[perm[b]] : 1.));} 6161ba322698SMatthew G. Knepley } 6162ba322698SMatthew G. Knepley } else { 616397e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 616497e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) { 616597e99dd9SToby Isaac fuse(&a[b], values[foffset+perm[b]] * (flip ? flip[perm[b]] : 1.)); 616697e99dd9SToby Isaac ++cind; 616797e99dd9SToby Isaac } 616897e99dd9SToby Isaac } 6169ba322698SMatthew G. Knepley } 6170ba322698SMatthew G. Knepley } else { 6171ba322698SMatthew G. Knepley if (comps) { 6172ba322698SMatthew G. Knepley for (b = 0; b < fdof; b++) { 6173ba322698SMatthew G. Knepley ncSet = fcSet = PETSC_FALSE; 61745da9d227SMatthew G. Knepley if (b%Nc == comps[ncind]) {ncind = (ncind+1)%Ncc; ncSet = PETSC_TRUE;} 6175ba322698SMatthew G. Knepley if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; fcSet = PETSC_TRUE;} 6176ba322698SMatthew G. Knepley if (ncSet && fcSet) {fuse(&a[b], values[foffset+ b ] * (flip ? flip[ b ] : 1.));} 6177ba322698SMatthew G. Knepley } 617897e99dd9SToby Isaac } else { 617997e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 618097e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) { 618197e99dd9SToby Isaac fuse(&a[b], values[foffset+ b ] * (flip ? flip[ b ] : 1.)); 6182a5e93ea8SMatthew G. Knepley ++cind; 6183a5e93ea8SMatthew G. Knepley } 6184a5e93ea8SMatthew G. Knepley } 6185a5e93ea8SMatthew G. Knepley } 6186a5e93ea8SMatthew G. Knepley } 6187a5e93ea8SMatthew G. Knepley } 6188ba322698SMatthew G. Knepley } 61891a271a75SMatthew G. Knepley *offset += fdof; 6190a5e93ea8SMatthew G. Knepley PetscFunctionReturn(0); 6191a5e93ea8SMatthew G. Knepley } 6192a5e93ea8SMatthew G. Knepley 61939fbee547SJacob Faibussowitsch static inline PetscErrorCode DMPlexVecSetClosure_Depth1_Static(DM dm, PetscSection section, Vec v, PetscInt point, const PetscScalar values[], InsertMode mode) 6194a6dfd86eSKarl Rupp { 6195552f7358SJed Brown PetscScalar *array; 61961b406b76SMatthew G. Knepley const PetscInt *cone, *coneO; 61971b406b76SMatthew G. Knepley PetscInt pStart, pEnd, p, numPoints, off, dof; 6198552f7358SJed Brown PetscErrorCode ierr; 6199552f7358SJed Brown 62001b406b76SMatthew G. Knepley PetscFunctionBeginHot; 6201b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 6202b6ebb6e6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, point, &numPoints);CHKERRQ(ierr); 6203b6ebb6e6SMatthew G. Knepley ierr = DMPlexGetCone(dm, point, &cone);CHKERRQ(ierr); 6204b6ebb6e6SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, point, &coneO);CHKERRQ(ierr); 6205b6ebb6e6SMatthew G. Knepley ierr = VecGetArray(v, &array);CHKERRQ(ierr); 6206b6ebb6e6SMatthew G. Knepley for (p = 0, off = 0; p <= numPoints; ++p, off += dof) { 6207b6ebb6e6SMatthew G. Knepley const PetscInt cp = !p ? point : cone[p-1]; 6208b6ebb6e6SMatthew G. Knepley const PetscInt o = !p ? 0 : coneO[p-1]; 6209b6ebb6e6SMatthew G. Knepley 6210b6ebb6e6SMatthew G. Knepley if ((cp < pStart) || (cp >= pEnd)) {dof = 0; continue;} 6211b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetDof(section, cp, &dof);CHKERRQ(ierr); 6212b6ebb6e6SMatthew G. Knepley /* ADD_VALUES */ 6213b6ebb6e6SMatthew G. Knepley { 6214b6ebb6e6SMatthew G. Knepley const PetscInt *cdofs; /* The indices of the constrained dofs on this point */ 6215b6ebb6e6SMatthew G. Knepley PetscScalar *a; 6216b6ebb6e6SMatthew G. Knepley PetscInt cdof, coff, cind = 0, k; 6217b6ebb6e6SMatthew G. Knepley 6218b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(section, cp, &cdof);CHKERRQ(ierr); 6219b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetOffset(section, cp, &coff);CHKERRQ(ierr); 6220b6ebb6e6SMatthew G. Knepley a = &array[coff]; 6221b6ebb6e6SMatthew G. Knepley if (!cdof) { 6222b6ebb6e6SMatthew G. Knepley if (o >= 0) { 6223b6ebb6e6SMatthew G. Knepley for (k = 0; k < dof; ++k) { 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 a[k] += values[off+dof-k-1]; 6229b6ebb6e6SMatthew G. Knepley } 6230b6ebb6e6SMatthew G. Knepley } 6231b6ebb6e6SMatthew G. Knepley } else { 6232b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetConstraintIndices(section, cp, &cdofs);CHKERRQ(ierr); 6233b6ebb6e6SMatthew G. Knepley if (o >= 0) { 6234b6ebb6e6SMatthew G. Knepley for (k = 0; k < dof; ++k) { 6235b6ebb6e6SMatthew G. Knepley if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 6236b6ebb6e6SMatthew G. Knepley a[k] += values[off+k]; 6237b6ebb6e6SMatthew G. Knepley } 6238b6ebb6e6SMatthew G. Knepley } else { 6239b6ebb6e6SMatthew G. Knepley for (k = 0; k < dof; ++k) { 6240b6ebb6e6SMatthew G. Knepley if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 6241b6ebb6e6SMatthew G. Knepley a[k] += values[off+dof-k-1]; 6242b6ebb6e6SMatthew G. Knepley } 6243b6ebb6e6SMatthew G. Knepley } 6244b6ebb6e6SMatthew G. Knepley } 6245b6ebb6e6SMatthew G. Knepley } 6246b6ebb6e6SMatthew G. Knepley } 6247b6ebb6e6SMatthew G. Knepley ierr = VecRestoreArray(v, &array);CHKERRQ(ierr); 6248b6ebb6e6SMatthew G. Knepley PetscFunctionReturn(0); 6249b6ebb6e6SMatthew G. Knepley } 62501b406b76SMatthew G. Knepley 62511b406b76SMatthew G. Knepley /*@C 62521b406b76SMatthew G. Knepley DMPlexVecSetClosure - Set an array of the values on the closure of 'point' 62531b406b76SMatthew G. Knepley 62541b406b76SMatthew G. Knepley Not collective 62551b406b76SMatthew G. Knepley 62561b406b76SMatthew G. Knepley Input Parameters: 62571b406b76SMatthew G. Knepley + dm - The DM 62581b406b76SMatthew G. Knepley . section - The section describing the layout in v, or NULL to use the default section 62591b406b76SMatthew G. Knepley . v - The local vector 6260eaf898f9SPatrick Sanan . point - The point in the DM 62611b406b76SMatthew G. Knepley . values - The array of values 626222c1ee49SMatthew 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, 626322c1ee49SMatthew G. Knepley where INSERT_ALL_VALUES and ADD_ALL_VALUES also overwrite boundary conditions. 62641b406b76SMatthew G. Knepley 62651b406b76SMatthew G. Knepley Fortran Notes: 62661b406b76SMatthew G. Knepley This routine is only available in Fortran 90, and you must include petsc.h90 in your code. 62671b406b76SMatthew G. Knepley 62681b406b76SMatthew G. Knepley Level: intermediate 62691b406b76SMatthew G. Knepley 62701b406b76SMatthew G. Knepley .seealso DMPlexVecGetClosure(), DMPlexMatSetClosure() 62711b406b76SMatthew G. Knepley @*/ 62721b406b76SMatthew G. Knepley PetscErrorCode DMPlexVecSetClosure(DM dm, PetscSection section, Vec v, PetscInt point, const PetscScalar values[], InsertMode mode) 62731b406b76SMatthew G. Knepley { 62741b406b76SMatthew G. Knepley PetscSection clSection; 62751b406b76SMatthew G. Knepley IS clPoints; 62761b406b76SMatthew G. Knepley PetscScalar *array; 62771b406b76SMatthew G. Knepley PetscInt *points = NULL; 627827f02ce8SMatthew G. Knepley const PetscInt *clp, *clperm = NULL; 6279c459fbc1SJed Brown PetscInt depth, numFields, numPoints, p, clsize; 62801b406b76SMatthew G. Knepley PetscErrorCode ierr; 62811b406b76SMatthew G. Knepley 62821a271a75SMatthew G. Knepley PetscFunctionBeginHot; 62831b406b76SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 628492fd8e1eSJed Brown if (!section) {ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr);} 62851a271a75SMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 62861a271a75SMatthew G. Knepley PetscValidHeaderSpecific(v, VEC_CLASSID, 3); 62871b406b76SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 62881b406b76SMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 62891b406b76SMatthew G. Knepley if (depth == 1 && numFields < 2 && mode == ADD_VALUES) { 62908f3be42fSMatthew G. Knepley ierr = DMPlexVecSetClosure_Depth1_Static(dm, section, v, point, values, mode);CHKERRQ(ierr); 62911b406b76SMatthew G. Knepley PetscFunctionReturn(0); 62921b406b76SMatthew G. Knepley } 62931a271a75SMatthew G. Knepley /* Get points */ 6294923c78e0SToby Isaac ierr = DMPlexGetCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 6295c459fbc1SJed Brown for (clsize=0,p=0; p<numPoints; p++) { 6296c459fbc1SJed Brown PetscInt dof; 6297c459fbc1SJed Brown ierr = PetscSectionGetDof(section, points[2*p], &dof);CHKERRQ(ierr); 6298c459fbc1SJed Brown clsize += dof; 6299c459fbc1SJed Brown } 6300c459fbc1SJed Brown ierr = PetscSectionGetClosureInversePermutation_Internal(section, (PetscObject) dm, depth, clsize, &clperm);CHKERRQ(ierr); 63011a271a75SMatthew G. Knepley /* Get array */ 6302552f7358SJed Brown ierr = VecGetArray(v, &array);CHKERRQ(ierr); 63031a271a75SMatthew G. Knepley /* Get values */ 6304ef90cfe2SMatthew G. Knepley if (numFields > 0) { 630597e99dd9SToby Isaac PetscInt offset = 0, f; 6306552f7358SJed Brown for (f = 0; f < numFields; ++f) { 630797e99dd9SToby Isaac const PetscInt **perms = NULL; 630897e99dd9SToby Isaac const PetscScalar **flips = NULL; 630997e99dd9SToby Isaac 631097e99dd9SToby Isaac ierr = PetscSectionGetFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 6311552f7358SJed Brown switch (mode) { 6312552f7358SJed Brown case INSERT_VALUES: 631397e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 631497e99dd9SToby Isaac const PetscInt point = points[2*p]; 631597e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 631697e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 631797e99dd9SToby Isaac updatePointFields_private(section, point, perm, flip, f, insert, PETSC_FALSE, clperm, values, &offset, array); 6318552f7358SJed Brown } break; 6319552f7358SJed Brown case INSERT_ALL_VALUES: 632097e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 632197e99dd9SToby Isaac const PetscInt point = points[2*p]; 632297e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 632397e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 632497e99dd9SToby Isaac updatePointFields_private(section, point, perm, flip, f, insert, PETSC_TRUE, clperm, values, &offset, array); 6325552f7358SJed Brown } break; 6326a5e93ea8SMatthew G. Knepley case INSERT_BC_VALUES: 632797e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 632897e99dd9SToby Isaac const PetscInt point = points[2*p]; 632997e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 633097e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 6331ba322698SMatthew G. Knepley updatePointFieldsBC_private(section, point, perm, flip, f, -1, NULL, insert, clperm, values, &offset, array); 6332a5e93ea8SMatthew G. Knepley } break; 6333552f7358SJed Brown case ADD_VALUES: 633497e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 633597e99dd9SToby Isaac const PetscInt point = points[2*p]; 633697e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 633797e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 633897e99dd9SToby Isaac updatePointFields_private(section, point, perm, flip, f, add, PETSC_FALSE, clperm, values, &offset, array); 6339552f7358SJed Brown } break; 6340552f7358SJed Brown case ADD_ALL_VALUES: 634197e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 634297e99dd9SToby Isaac const PetscInt point = points[2*p]; 634397e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 634497e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 634597e99dd9SToby Isaac updatePointFields_private(section, point, perm, flip, f, add, PETSC_TRUE, clperm, values, &offset, array); 6346552f7358SJed Brown } break; 6347304ab55fSMatthew G. Knepley case ADD_BC_VALUES: 634897e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 634997e99dd9SToby Isaac const PetscInt point = points[2*p]; 635097e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 635197e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 6352ba322698SMatthew G. Knepley updatePointFieldsBC_private(section, point, perm, flip, f, -1, NULL, add, clperm, values, &offset, array); 6353304ab55fSMatthew G. Knepley } break; 6354552f7358SJed Brown default: 635598921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insert mode %d", mode); 6356552f7358SJed Brown } 635797e99dd9SToby Isaac ierr = PetscSectionRestoreFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 63581a271a75SMatthew G. Knepley } 6359552f7358SJed Brown } else { 63601a271a75SMatthew G. Knepley PetscInt dof, off; 636197e99dd9SToby Isaac const PetscInt **perms = NULL; 636297e99dd9SToby Isaac const PetscScalar **flips = NULL; 63631a271a75SMatthew G. Knepley 636497e99dd9SToby Isaac ierr = PetscSectionGetPointSyms(section,numPoints,points,&perms,&flips);CHKERRQ(ierr); 6365552f7358SJed Brown switch (mode) { 6366552f7358SJed Brown case INSERT_VALUES: 636797e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 636897e99dd9SToby Isaac const PetscInt point = points[2*p]; 636997e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 637097e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 637197e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 637297e99dd9SToby Isaac updatePoint_private(section, point, dof, insert, PETSC_FALSE, perm, flip, clperm, values, off, array); 6373552f7358SJed Brown } break; 6374552f7358SJed Brown case INSERT_ALL_VALUES: 637597e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 637697e99dd9SToby Isaac const PetscInt point = points[2*p]; 637797e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 637897e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 637997e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 638097e99dd9SToby Isaac updatePoint_private(section, point, dof, insert, PETSC_TRUE, perm, flip, clperm, values, off, array); 6381552f7358SJed Brown } break; 6382a5e93ea8SMatthew G. Knepley case INSERT_BC_VALUES: 638397e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 638497e99dd9SToby Isaac const PetscInt point = points[2*p]; 638597e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 638697e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 638797e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 638897e99dd9SToby Isaac updatePointBC_private(section, point, dof, insert, perm, flip, clperm, values, off, array); 6389a5e93ea8SMatthew G. Knepley } break; 6390552f7358SJed Brown case ADD_VALUES: 639197e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 639297e99dd9SToby Isaac const PetscInt point = points[2*p]; 639397e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 639497e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 639597e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 639697e99dd9SToby Isaac updatePoint_private(section, point, dof, add, PETSC_FALSE, perm, flip, clperm, values, off, array); 6397552f7358SJed Brown } break; 6398552f7358SJed Brown case ADD_ALL_VALUES: 639997e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 640097e99dd9SToby Isaac const PetscInt point = points[2*p]; 640197e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 640297e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 640397e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 640497e99dd9SToby Isaac updatePoint_private(section, point, dof, add, PETSC_TRUE, perm, flip, clperm, values, off, array); 6405552f7358SJed Brown } break; 6406304ab55fSMatthew G. Knepley case ADD_BC_VALUES: 640797e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 640897e99dd9SToby Isaac const PetscInt point = points[2*p]; 640997e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 641097e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 641197e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 641297e99dd9SToby Isaac updatePointBC_private(section, point, dof, add, perm, flip, clperm, values, off, array); 6413304ab55fSMatthew G. Knepley } break; 6414552f7358SJed Brown default: 641598921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insert mode %d", mode); 6416552f7358SJed Brown } 641797e99dd9SToby Isaac ierr = PetscSectionRestorePointSyms(section,numPoints,points,&perms,&flips);CHKERRQ(ierr); 6418552f7358SJed Brown } 64191a271a75SMatthew G. Knepley /* Cleanup points */ 6420923c78e0SToby Isaac ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 64211a271a75SMatthew G. Knepley /* Cleanup array */ 6422552f7358SJed Brown ierr = VecRestoreArray(v, &array);CHKERRQ(ierr); 6423552f7358SJed Brown PetscFunctionReturn(0); 6424552f7358SJed Brown } 6425552f7358SJed Brown 64265f790a90SMatthew G. Knepley /* Check whether the given point is in the label. If not, update the offset to skip this point */ 64279fbee547SJacob Faibussowitsch static inline PetscErrorCode CheckPoint_Private(DMLabel label, PetscInt labelId, PetscSection section, PetscInt point, PetscInt f, PetscInt *offset) 64285f790a90SMatthew G. Knepley { 64295f790a90SMatthew G. Knepley PetscFunctionBegin; 64305f790a90SMatthew G. Knepley if (label) { 64315f790a90SMatthew G. Knepley PetscInt val, fdof; 64325f790a90SMatthew G. Knepley PetscErrorCode ierr; 64335f790a90SMatthew G. Knepley 64345f790a90SMatthew G. Knepley /* There is a problem with this: 64355f790a90SMatthew 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 64365f790a90SMatthew 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. 64375f790a90SMatthew G. Knepley Thus I am only going to check val != -1, not val != labelId 64385f790a90SMatthew G. Knepley */ 64395f790a90SMatthew G. Knepley ierr = DMLabelGetValue(label, point, &val);CHKERRQ(ierr); 64405f790a90SMatthew G. Knepley if (val < 0) { 64415f790a90SMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 64425f790a90SMatthew G. Knepley *offset += fdof; 64435f790a90SMatthew G. Knepley PetscFunctionReturn(1); 64445f790a90SMatthew G. Knepley } 64455f790a90SMatthew G. Knepley } 64465f790a90SMatthew G. Knepley PetscFunctionReturn(0); 64475f790a90SMatthew G. Knepley } 64485f790a90SMatthew G. Knepley 644997529cf3SJed Brown /* Unlike DMPlexVecSetClosure(), this uses plex-native closure permutation, not a user-specified permutation such as DMPlexSetClosurePermutationTensor(). */ 64505f790a90SMatthew 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) 6451e07394fbSMatthew G. Knepley { 6452e07394fbSMatthew G. Knepley PetscSection clSection; 6453e07394fbSMatthew G. Knepley IS clPoints; 6454e07394fbSMatthew G. Knepley PetscScalar *array; 6455e07394fbSMatthew G. Knepley PetscInt *points = NULL; 645697529cf3SJed Brown const PetscInt *clp; 6457e07394fbSMatthew G. Knepley PetscInt numFields, numPoints, p; 645897e99dd9SToby Isaac PetscInt offset = 0, f; 6459e07394fbSMatthew G. Knepley PetscErrorCode ierr; 6460e07394fbSMatthew G. Knepley 6461e07394fbSMatthew G. Knepley PetscFunctionBeginHot; 6462e07394fbSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 646392fd8e1eSJed Brown if (!section) {ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr);} 6464e07394fbSMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 6465e07394fbSMatthew G. Knepley PetscValidHeaderSpecific(v, VEC_CLASSID, 3); 6466e07394fbSMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 6467e07394fbSMatthew G. Knepley /* Get points */ 6468923c78e0SToby Isaac ierr = DMPlexGetCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 6469e07394fbSMatthew G. Knepley /* Get array */ 6470e07394fbSMatthew G. Knepley ierr = VecGetArray(v, &array);CHKERRQ(ierr); 6471e07394fbSMatthew G. Knepley /* Get values */ 6472e07394fbSMatthew G. Knepley for (f = 0; f < numFields; ++f) { 647397e99dd9SToby Isaac const PetscInt **perms = NULL; 647497e99dd9SToby Isaac const PetscScalar **flips = NULL; 647597e99dd9SToby Isaac 6476e07394fbSMatthew G. Knepley if (!fieldActive[f]) { 6477e07394fbSMatthew G. Knepley for (p = 0; p < numPoints*2; p += 2) { 6478e07394fbSMatthew G. Knepley PetscInt fdof; 6479e07394fbSMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, points[p], f, &fdof);CHKERRQ(ierr); 6480e07394fbSMatthew G. Knepley offset += fdof; 6481e07394fbSMatthew G. Knepley } 6482e07394fbSMatthew G. Knepley continue; 6483e07394fbSMatthew G. Knepley } 648497e99dd9SToby Isaac ierr = PetscSectionGetFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 6485e07394fbSMatthew G. Knepley switch (mode) { 6486e07394fbSMatthew G. Knepley case INSERT_VALUES: 648797e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 648897e99dd9SToby Isaac const PetscInt point = points[2*p]; 648997e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 649097e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 64915f790a90SMatthew G. Knepley ierr = CheckPoint_Private(label, labelId, section, point, f, &offset); if (ierr) continue; 649297529cf3SJed Brown updatePointFields_private(section, point, perm, flip, f, insert, PETSC_FALSE, NULL, values, &offset, array); 6493e07394fbSMatthew G. Knepley } break; 6494e07394fbSMatthew G. Knepley case INSERT_ALL_VALUES: 649597e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 649697e99dd9SToby Isaac const PetscInt point = points[2*p]; 649797e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 649897e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 64995f790a90SMatthew G. Knepley ierr = CheckPoint_Private(label, labelId, section, point, f, &offset); if (ierr) continue; 650097529cf3SJed Brown updatePointFields_private(section, point, perm, flip, f, insert, PETSC_TRUE, NULL, values, &offset, array); 6501e07394fbSMatthew G. Knepley } break; 6502e07394fbSMatthew G. Knepley case INSERT_BC_VALUES: 650397e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 650497e99dd9SToby Isaac const PetscInt point = points[2*p]; 650597e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 650697e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 65075f790a90SMatthew G. Knepley ierr = CheckPoint_Private(label, labelId, section, point, f, &offset); if (ierr) continue; 650897529cf3SJed Brown updatePointFieldsBC_private(section, point, perm, flip, f, Ncc, comps, insert, NULL, values, &offset, array); 6509e07394fbSMatthew G. Knepley } break; 6510e07394fbSMatthew G. Knepley case ADD_VALUES: 651197e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 651297e99dd9SToby Isaac const PetscInt point = points[2*p]; 651397e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 651497e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 65155f790a90SMatthew G. Knepley ierr = CheckPoint_Private(label, labelId, section, point, f, &offset); if (ierr) continue; 651697529cf3SJed Brown updatePointFields_private(section, point, perm, flip, f, add, PETSC_FALSE, NULL, values, &offset, array); 6517e07394fbSMatthew G. Knepley } break; 6518e07394fbSMatthew G. Knepley case ADD_ALL_VALUES: 651997e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 652097e99dd9SToby Isaac const PetscInt point = points[2*p]; 652197e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 652297e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 65235f790a90SMatthew G. Knepley ierr = CheckPoint_Private(label, labelId, section, point, f, &offset); if (ierr) continue; 652497529cf3SJed Brown updatePointFields_private(section, point, perm, flip, f, add, PETSC_TRUE, NULL, values, &offset, array); 6525e07394fbSMatthew G. Knepley } break; 6526e07394fbSMatthew G. Knepley default: 652798921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insert mode %d", mode); 6528e07394fbSMatthew G. Knepley } 652997e99dd9SToby Isaac ierr = PetscSectionRestoreFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 6530e07394fbSMatthew G. Knepley } 6531e07394fbSMatthew G. Knepley /* Cleanup points */ 6532923c78e0SToby Isaac ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 6533e07394fbSMatthew G. Knepley /* Cleanup array */ 6534e07394fbSMatthew G. Knepley ierr = VecRestoreArray(v, &array);CHKERRQ(ierr); 6535e07394fbSMatthew G. Knepley PetscFunctionReturn(0); 6536e07394fbSMatthew G. Knepley } 6537e07394fbSMatthew G. Knepley 65387cd05799SMatthew G. Knepley static PetscErrorCode DMPlexPrintMatSetValues(PetscViewer viewer, Mat A, PetscInt point, PetscInt numRIndices, const PetscInt rindices[], PetscInt numCIndices, const PetscInt cindices[], const PetscScalar values[]) 6539552f7358SJed Brown { 6540552f7358SJed Brown PetscMPIInt rank; 6541552f7358SJed Brown PetscInt i, j; 6542552f7358SJed Brown PetscErrorCode ierr; 6543552f7358SJed Brown 6544552f7358SJed Brown PetscFunctionBegin; 6545ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)A), &rank);CHKERRMPI(ierr); 6546eaf898f9SPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer, "[%d]mat for point %D\n", rank, point);CHKERRQ(ierr); 6547e4b003c7SBarry Smith for (i = 0; i < numRIndices; i++) {ierr = PetscViewerASCIIPrintf(viewer, "[%d]mat row indices[%D] = %D\n", rank, i, rindices[i]);CHKERRQ(ierr);} 6548e4b003c7SBarry Smith for (i = 0; i < numCIndices; i++) {ierr = PetscViewerASCIIPrintf(viewer, "[%d]mat col indices[%D] = %D\n", rank, i, cindices[i]);CHKERRQ(ierr);} 6549b0ecff45SMatthew G. Knepley numCIndices = numCIndices ? numCIndices : numRIndices; 6550557cf195SMatthew G. Knepley if (!values) PetscFunctionReturn(0); 6551b0ecff45SMatthew G. Knepley for (i = 0; i < numRIndices; i++) { 6552e4b003c7SBarry Smith ierr = PetscViewerASCIIPrintf(viewer, "[%d]", rank);CHKERRQ(ierr); 6553b0ecff45SMatthew G. Knepley for (j = 0; j < numCIndices; j++) { 6554519f805aSKarl Rupp #if defined(PETSC_USE_COMPLEX) 65557eba1a17SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " (%g,%g)", (double)PetscRealPart(values[i*numCIndices+j]), (double)PetscImaginaryPart(values[i*numCIndices+j]));CHKERRQ(ierr); 6556552f7358SJed Brown #else 6557b0ecff45SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " %g", (double)values[i*numCIndices+j]);CHKERRQ(ierr); 6558552f7358SJed Brown #endif 6559552f7358SJed Brown } 656077a6746dSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, "\n");CHKERRQ(ierr); 6561552f7358SJed Brown } 6562552f7358SJed Brown PetscFunctionReturn(0); 6563552f7358SJed Brown } 6564552f7358SJed Brown 656505586334SMatthew G. Knepley /* 656605586334SMatthew G. Knepley DMPlexGetIndicesPoint_Internal - Add the indices for dofs on a point to an index array 656705586334SMatthew G. Knepley 656805586334SMatthew G. Knepley Input Parameters: 656905586334SMatthew G. Knepley + section - The section for this data layout 657036fa2b79SJed Brown . islocal - Is the section (and thus indices being requested) local or global? 657105586334SMatthew G. Knepley . point - The point contributing dofs with these indices 657205586334SMatthew G. Knepley . off - The global offset of this point 657305586334SMatthew G. Knepley . loff - The local offset of each field 6574a5b23f4aSJose E. Roman . setBC - The flag determining whether to include indices of boundary values 657505586334SMatthew G. Knepley . perm - A permutation of the dofs on this point, or NULL 657605586334SMatthew G. Knepley - indperm - A permutation of the entire indices array, or NULL 657705586334SMatthew G. Knepley 657805586334SMatthew G. Knepley Output Parameter: 657905586334SMatthew G. Knepley . indices - Indices for dofs on this point 658005586334SMatthew G. Knepley 658105586334SMatthew G. Knepley Level: developer 658205586334SMatthew G. Knepley 658305586334SMatthew G. Knepley Note: The indices could be local or global, depending on the value of 'off'. 658405586334SMatthew G. Knepley */ 658536fa2b79SJed Brown PetscErrorCode DMPlexGetIndicesPoint_Internal(PetscSection section, PetscBool islocal,PetscInt point, PetscInt off, PetscInt *loff, PetscBool setBC, const PetscInt perm[], const PetscInt indperm[], PetscInt indices[]) 6586a6dfd86eSKarl Rupp { 6587e6ccafaeSMatthew G Knepley PetscInt dof; /* The number of unknowns on this point */ 6588552f7358SJed Brown PetscInt cdof; /* The number of constraints on this point */ 6589552f7358SJed Brown const PetscInt *cdofs; /* The indices of the constrained dofs on this point */ 6590552f7358SJed Brown PetscInt cind = 0, k; 6591552f7358SJed Brown PetscErrorCode ierr; 6592552f7358SJed Brown 6593552f7358SJed Brown PetscFunctionBegin; 65942c71b3e2SJacob Faibussowitsch PetscCheckFalse(!islocal && setBC,PetscObjectComm((PetscObject)section),PETSC_ERR_ARG_INCOMP,"setBC incompatible with global indices; use a local section or disable setBC"); 6595552f7358SJed Brown ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 6596552f7358SJed Brown ierr = PetscSectionGetConstraintDof(section, point, &cdof);CHKERRQ(ierr); 6597552f7358SJed Brown if (!cdof || setBC) { 659805586334SMatthew G. Knepley for (k = 0; k < dof; ++k) { 659905586334SMatthew G. Knepley const PetscInt preind = perm ? *loff+perm[k] : *loff+k; 660005586334SMatthew G. Knepley const PetscInt ind = indperm ? indperm[preind] : preind; 660105586334SMatthew G. Knepley 660205586334SMatthew G. Knepley indices[ind] = off + k; 6603552f7358SJed Brown } 6604552f7358SJed Brown } else { 6605552f7358SJed Brown ierr = PetscSectionGetConstraintIndices(section, point, &cdofs);CHKERRQ(ierr); 66064acb8e1eSToby Isaac for (k = 0; k < dof; ++k) { 660705586334SMatthew G. Knepley const PetscInt preind = perm ? *loff+perm[k] : *loff+k; 660805586334SMatthew G. Knepley const PetscInt ind = indperm ? indperm[preind] : preind; 660905586334SMatthew G. Knepley 66104acb8e1eSToby Isaac if ((cind < cdof) && (k == cdofs[cind])) { 66114acb8e1eSToby Isaac /* Insert check for returning constrained indices */ 661205586334SMatthew G. Knepley indices[ind] = -(off+k+1); 66134acb8e1eSToby Isaac ++cind; 66144acb8e1eSToby Isaac } else { 661536fa2b79SJed Brown indices[ind] = off + k - (islocal ? 0 : cind); 6616552f7358SJed Brown } 6617552f7358SJed Brown } 6618552f7358SJed Brown } 6619e6ccafaeSMatthew G Knepley *loff += dof; 6620552f7358SJed Brown PetscFunctionReturn(0); 6621552f7358SJed Brown } 6622552f7358SJed Brown 66237e29afd2SMatthew G. Knepley /* 662436fa2b79SJed Brown DMPlexGetIndicesPointFields_Internal - gets section indices for a point in its canonical ordering. 66257e29afd2SMatthew G. Knepley 662636fa2b79SJed Brown Input Parameters: 662736fa2b79SJed Brown + section - a section (global or local) 662836fa2b79SJed Brown - islocal - PETSC_TRUE if requesting local indices (i.e., section is local); PETSC_FALSE for global 662936fa2b79SJed Brown . point - point within section 663036fa2b79SJed Brown . off - The offset of this point in the (local or global) indexed space - should match islocal and (usually) the section 663136fa2b79SJed Brown . foffs - array of length numFields containing the offset in canonical point ordering (the location in indices) of each field 663236fa2b79SJed Brown . setBC - identify constrained (boundary condition) points via involution. 663336fa2b79SJed Brown . perms - perms[f][permsoff][:] is a permutation of dofs within each field 663436fa2b79SJed Brown . permsoff - offset 663536fa2b79SJed Brown - indperm - index permutation 663636fa2b79SJed Brown 663736fa2b79SJed Brown Output Parameter: 663836fa2b79SJed Brown . foffs - each entry is incremented by the number of (unconstrained if setBC=FALSE) dofs in that field 663936fa2b79SJed Brown . indices - array to hold indices (as defined by section) of each dof associated with point 664036fa2b79SJed Brown 664136fa2b79SJed Brown Notes: 664236fa2b79SJed Brown If section is local and setBC=true, there is no distinction between constrained and unconstrained dofs. 664336fa2b79SJed Brown If section is local and setBC=false, the indices for constrained points are the involution -(i+1) of their position 664436fa2b79SJed Brown in the local vector. 664536fa2b79SJed Brown 664636fa2b79SJed Brown If section is global and setBC=false, the indices for constrained points are negative (and their value is not 664736fa2b79SJed Brown significant). It is invalid to call with a global section and setBC=true. 664836fa2b79SJed Brown 664936fa2b79SJed Brown Developer Note: 665036fa2b79SJed Brown The section is only used for field layout, so islocal is technically a statement about the offset (off). At some point 665136fa2b79SJed Brown in the future, global sections may have fields set, in which case we could pass the global section and obtain the 665236fa2b79SJed Brown offset could be obtained from the section instead of passing it explicitly as we do now. 665336fa2b79SJed Brown 665436fa2b79SJed Brown Example: 665536fa2b79SJed Brown Suppose a point contains one field with three components, and for which the unconstrained indices are {10, 11, 12}. 665636fa2b79SJed Brown When the middle component is constrained, we get the array {10, -12, 12} for (islocal=TRUE, setBC=FALSE). 665736fa2b79SJed Brown Note that -12 is the involution of 11, so the user can involute negative indices to recover local indices. 665836fa2b79SJed 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. 665936fa2b79SJed Brown 666036fa2b79SJed Brown Level: developer 66617e29afd2SMatthew G. Knepley */ 666236fa2b79SJed 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[]) 6663a6dfd86eSKarl Rupp { 6664552f7358SJed Brown PetscInt numFields, foff, f; 6665552f7358SJed Brown PetscErrorCode ierr; 6666552f7358SJed Brown 6667552f7358SJed Brown PetscFunctionBegin; 66682c71b3e2SJacob Faibussowitsch PetscCheckFalse(!islocal && setBC,PetscObjectComm((PetscObject)section),PETSC_ERR_ARG_INCOMP,"setBC incompatible with global indices; use a local section or disable setBC"); 6669552f7358SJed Brown ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 6670552f7358SJed Brown for (f = 0, foff = 0; f < numFields; ++f) { 66714acb8e1eSToby Isaac PetscInt fdof, cfdof; 6672552f7358SJed Brown const PetscInt *fcdofs; /* The indices of the constrained dofs for field f on this point */ 66734acb8e1eSToby Isaac PetscInt cind = 0, b; 66744acb8e1eSToby Isaac const PetscInt *perm = (perms && perms[f]) ? perms[f][permsoff] : NULL; 6675552f7358SJed Brown 6676552f7358SJed Brown ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 6677552f7358SJed Brown ierr = PetscSectionGetFieldConstraintDof(section, point, f, &cfdof);CHKERRQ(ierr); 6678552f7358SJed Brown if (!cfdof || setBC) { 667905586334SMatthew G. Knepley for (b = 0; b < fdof; ++b) { 668005586334SMatthew G. Knepley const PetscInt preind = perm ? foffs[f]+perm[b] : foffs[f]+b; 668105586334SMatthew G. Knepley const PetscInt ind = indperm ? indperm[preind] : preind; 668205586334SMatthew G. Knepley 668305586334SMatthew G. Knepley indices[ind] = off+foff+b; 668405586334SMatthew G. Knepley } 6685552f7358SJed Brown } else { 6686552f7358SJed Brown ierr = PetscSectionGetFieldConstraintIndices(section, point, f, &fcdofs);CHKERRQ(ierr); 668705586334SMatthew G. Knepley for (b = 0; b < fdof; ++b) { 668805586334SMatthew G. Knepley const PetscInt preind = perm ? foffs[f]+perm[b] : foffs[f]+b; 668905586334SMatthew G. Knepley const PetscInt ind = indperm ? indperm[preind] : preind; 669005586334SMatthew G. Knepley 66914acb8e1eSToby Isaac if ((cind < cfdof) && (b == fcdofs[cind])) { 669205586334SMatthew G. Knepley indices[ind] = -(off+foff+b+1); 6693552f7358SJed Brown ++cind; 6694552f7358SJed Brown } else { 669536fa2b79SJed Brown indices[ind] = off + foff + b - (islocal ? 0 : cind); 6696552f7358SJed Brown } 6697552f7358SJed Brown } 6698552f7358SJed Brown } 669936fa2b79SJed Brown foff += (setBC || islocal ? fdof : (fdof - cfdof)); 6700552f7358SJed Brown foffs[f] += fdof; 6701552f7358SJed Brown } 6702552f7358SJed Brown PetscFunctionReturn(0); 6703552f7358SJed Brown } 6704552f7358SJed Brown 67057e29afd2SMatthew G. Knepley /* 67067e29afd2SMatthew G. Knepley This version believes the globalSection offsets for each field, rather than just the point offset 67077e29afd2SMatthew G. Knepley 67087e29afd2SMatthew G. Knepley . foffs - The offset into 'indices' for each field, since it is segregated by field 6709645102dcSJed Brown 6710645102dcSJed Brown Notes: 6711645102dcSJed Brown The semantics of this function relate to that of setBC=FALSE in DMPlexGetIndicesPointFields_Internal. 6712645102dcSJed Brown Since this function uses global indices, setBC=TRUE would be invalid, so no such argument exists. 67137e29afd2SMatthew G. Knepley */ 6714645102dcSJed Brown static PetscErrorCode DMPlexGetIndicesPointFieldsSplit_Internal(PetscSection section, PetscSection globalSection, PetscInt point, PetscInt foffs[], const PetscInt ***perms, PetscInt permsoff, const PetscInt indperm[], PetscInt indices[]) 67157e29afd2SMatthew G. Knepley { 67167e29afd2SMatthew G. Knepley PetscInt numFields, foff, f; 67177e29afd2SMatthew G. Knepley PetscErrorCode ierr; 67187e29afd2SMatthew G. Knepley 67197e29afd2SMatthew G. Knepley PetscFunctionBegin; 67207e29afd2SMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 67217e29afd2SMatthew G. Knepley for (f = 0; f < numFields; ++f) { 67227e29afd2SMatthew G. Knepley PetscInt fdof, cfdof; 67237e29afd2SMatthew G. Knepley const PetscInt *fcdofs; /* The indices of the constrained dofs for field f on this point */ 67247e29afd2SMatthew G. Knepley PetscInt cind = 0, b; 67257e29afd2SMatthew G. Knepley const PetscInt *perm = (perms && perms[f]) ? perms[f][permsoff] : NULL; 67267e29afd2SMatthew G. Knepley 67277e29afd2SMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 67287e29afd2SMatthew G. Knepley ierr = PetscSectionGetFieldConstraintDof(section, point, f, &cfdof);CHKERRQ(ierr); 67297e29afd2SMatthew G. Knepley ierr = PetscSectionGetFieldOffset(globalSection, point, f, &foff);CHKERRQ(ierr); 6730645102dcSJed Brown if (!cfdof) { 673105586334SMatthew G. Knepley for (b = 0; b < fdof; ++b) { 673205586334SMatthew G. Knepley const PetscInt preind = perm ? foffs[f]+perm[b] : foffs[f]+b; 673305586334SMatthew G. Knepley const PetscInt ind = indperm ? indperm[preind] : preind; 673405586334SMatthew G. Knepley 673505586334SMatthew G. Knepley indices[ind] = foff+b; 673605586334SMatthew G. Knepley } 67377e29afd2SMatthew G. Knepley } else { 67387e29afd2SMatthew G. Knepley ierr = PetscSectionGetFieldConstraintIndices(section, point, f, &fcdofs);CHKERRQ(ierr); 673905586334SMatthew G. Knepley for (b = 0; b < fdof; ++b) { 674005586334SMatthew G. Knepley const PetscInt preind = perm ? foffs[f]+perm[b] : foffs[f]+b; 674105586334SMatthew G. Knepley const PetscInt ind = indperm ? indperm[preind] : preind; 674205586334SMatthew G. Knepley 67437e29afd2SMatthew G. Knepley if ((cind < cfdof) && (b == fcdofs[cind])) { 674405586334SMatthew G. Knepley indices[ind] = -(foff+b+1); 67457e29afd2SMatthew G. Knepley ++cind; 67467e29afd2SMatthew G. Knepley } else { 674705586334SMatthew G. Knepley indices[ind] = foff+b-cind; 67487e29afd2SMatthew G. Knepley } 67497e29afd2SMatthew G. Knepley } 67507e29afd2SMatthew G. Knepley } 67517e29afd2SMatthew G. Knepley foffs[f] += fdof; 67527e29afd2SMatthew G. Knepley } 67537e29afd2SMatthew G. Knepley PetscFunctionReturn(0); 67547e29afd2SMatthew G. Knepley } 67557e29afd2SMatthew G. Knepley 67564acb8e1eSToby 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) 6757d3d1a6afSToby Isaac { 6758d3d1a6afSToby Isaac Mat cMat; 6759d3d1a6afSToby Isaac PetscSection aSec, cSec; 6760d3d1a6afSToby Isaac IS aIS; 6761d3d1a6afSToby Isaac PetscInt aStart = -1, aEnd = -1; 6762d3d1a6afSToby Isaac const PetscInt *anchors; 6763e17c06e0SMatthew G. Knepley PetscInt numFields, f, p, q, newP = 0; 6764d3d1a6afSToby Isaac PetscInt newNumPoints = 0, newNumIndices = 0; 6765d3d1a6afSToby Isaac PetscInt *newPoints, *indices, *newIndices; 6766d3d1a6afSToby Isaac PetscInt maxAnchor, maxDof; 6767d3d1a6afSToby Isaac PetscInt newOffsets[32]; 6768d3d1a6afSToby Isaac PetscInt *pointMatOffsets[32]; 6769d3d1a6afSToby Isaac PetscInt *newPointOffsets[32]; 6770d3d1a6afSToby Isaac PetscScalar *pointMat[32]; 67716ecaa68aSToby Isaac PetscScalar *newValues=NULL,*tmpValues; 6772d3d1a6afSToby Isaac PetscBool anyConstrained = PETSC_FALSE; 6773d3d1a6afSToby Isaac PetscErrorCode ierr; 6774d3d1a6afSToby Isaac 6775d3d1a6afSToby Isaac PetscFunctionBegin; 6776d3d1a6afSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6777d3d1a6afSToby Isaac PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 6778d3d1a6afSToby Isaac ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 6779d3d1a6afSToby Isaac 6780a17985deSToby Isaac ierr = DMPlexGetAnchors(dm,&aSec,&aIS);CHKERRQ(ierr); 6781d3d1a6afSToby Isaac /* if there are point-to-point constraints */ 6782d3d1a6afSToby Isaac if (aSec) { 6783580bdb30SBarry Smith ierr = PetscArrayzero(newOffsets, 32);CHKERRQ(ierr); 6784d3d1a6afSToby Isaac ierr = ISGetIndices(aIS,&anchors);CHKERRQ(ierr); 6785d3d1a6afSToby Isaac ierr = PetscSectionGetChart(aSec,&aStart,&aEnd);CHKERRQ(ierr); 6786d3d1a6afSToby Isaac /* figure out how many points are going to be in the new element matrix 6787d3d1a6afSToby Isaac * (we allow double counting, because it's all just going to be summed 6788d3d1a6afSToby Isaac * into the global matrix anyway) */ 6789d3d1a6afSToby Isaac for (p = 0; p < 2*numPoints; p+=2) { 6790d3d1a6afSToby Isaac PetscInt b = points[p]; 67914b2f2278SToby Isaac PetscInt bDof = 0, bSecDof; 6792d3d1a6afSToby Isaac 67934b2f2278SToby Isaac ierr = PetscSectionGetDof(section,b,&bSecDof);CHKERRQ(ierr); 67944b2f2278SToby Isaac if (!bSecDof) { 67954b2f2278SToby Isaac continue; 67964b2f2278SToby Isaac } 6797d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 6798d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec,b,&bDof);CHKERRQ(ierr); 6799d3d1a6afSToby Isaac } 6800d3d1a6afSToby Isaac if (bDof) { 6801d3d1a6afSToby Isaac /* this point is constrained */ 6802d3d1a6afSToby Isaac /* it is going to be replaced by its anchors */ 6803d3d1a6afSToby Isaac PetscInt bOff, q; 6804d3d1a6afSToby Isaac 6805d3d1a6afSToby Isaac anyConstrained = PETSC_TRUE; 6806d3d1a6afSToby Isaac newNumPoints += bDof; 6807d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(aSec,b,&bOff);CHKERRQ(ierr); 6808d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 6809d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q]; 6810d3d1a6afSToby Isaac PetscInt aDof; 6811d3d1a6afSToby Isaac 6812d3d1a6afSToby Isaac ierr = PetscSectionGetDof(section,a,&aDof);CHKERRQ(ierr); 6813d3d1a6afSToby Isaac newNumIndices += aDof; 6814d3d1a6afSToby Isaac for (f = 0; f < numFields; ++f) { 6815d3d1a6afSToby Isaac PetscInt fDof; 6816d3d1a6afSToby Isaac 6817d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, a, f, &fDof);CHKERRQ(ierr); 6818d3d1a6afSToby Isaac newOffsets[f+1] += fDof; 6819d3d1a6afSToby Isaac } 6820d3d1a6afSToby Isaac } 6821d3d1a6afSToby Isaac } 6822d3d1a6afSToby Isaac else { 6823d3d1a6afSToby Isaac /* this point is not constrained */ 6824d3d1a6afSToby Isaac newNumPoints++; 68254b2f2278SToby Isaac newNumIndices += bSecDof; 6826d3d1a6afSToby Isaac for (f = 0; f < numFields; ++f) { 6827d3d1a6afSToby Isaac PetscInt fDof; 6828d3d1a6afSToby Isaac 6829d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, b, f, &fDof);CHKERRQ(ierr); 6830d3d1a6afSToby Isaac newOffsets[f+1] += fDof; 6831d3d1a6afSToby Isaac } 6832d3d1a6afSToby Isaac } 6833d3d1a6afSToby Isaac } 6834d3d1a6afSToby Isaac } 6835d3d1a6afSToby Isaac if (!anyConstrained) { 683672b80496SMatthew G. Knepley if (outNumPoints) *outNumPoints = 0; 683772b80496SMatthew G. Knepley if (outNumIndices) *outNumIndices = 0; 683872b80496SMatthew G. Knepley if (outPoints) *outPoints = NULL; 683972b80496SMatthew G. Knepley if (outValues) *outValues = NULL; 684072b80496SMatthew G. Knepley if (aSec) {ierr = ISRestoreIndices(aIS,&anchors);CHKERRQ(ierr);} 6841d3d1a6afSToby Isaac PetscFunctionReturn(0); 6842d3d1a6afSToby Isaac } 6843d3d1a6afSToby Isaac 68446ecaa68aSToby Isaac if (outNumPoints) *outNumPoints = newNumPoints; 68456ecaa68aSToby Isaac if (outNumIndices) *outNumIndices = newNumIndices; 68466ecaa68aSToby Isaac 6847f13f9184SToby Isaac for (f = 0; f < numFields; ++f) newOffsets[f+1] += newOffsets[f]; 6848d3d1a6afSToby Isaac 68496ecaa68aSToby Isaac if (!outPoints && !outValues) { 68506ecaa68aSToby Isaac if (offsets) { 68516ecaa68aSToby Isaac for (f = 0; f <= numFields; f++) { 68526ecaa68aSToby Isaac offsets[f] = newOffsets[f]; 68536ecaa68aSToby Isaac } 68546ecaa68aSToby Isaac } 68556ecaa68aSToby Isaac if (aSec) {ierr = ISRestoreIndices(aIS,&anchors);CHKERRQ(ierr);} 68566ecaa68aSToby Isaac PetscFunctionReturn(0); 68576ecaa68aSToby Isaac } 68586ecaa68aSToby Isaac 68592c71b3e2SJacob Faibussowitsch PetscCheckFalse(numFields && newOffsets[numFields] != newNumIndices,PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", newOffsets[numFields], newNumIndices); 6860d3d1a6afSToby Isaac 6861f7c74593SToby Isaac ierr = DMGetDefaultConstraints(dm, &cSec, &cMat);CHKERRQ(ierr); 6862d3d1a6afSToby Isaac 6863d3d1a6afSToby Isaac /* workspaces */ 6864d3d1a6afSToby Isaac if (numFields) { 6865d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 686669291d52SBarry Smith ierr = DMGetWorkArray(dm,numPoints+1,MPIU_INT,&pointMatOffsets[f]);CHKERRQ(ierr); 686769291d52SBarry Smith ierr = DMGetWorkArray(dm,numPoints+1,MPIU_INT,&newPointOffsets[f]);CHKERRQ(ierr); 6868d3d1a6afSToby Isaac } 6869d3d1a6afSToby Isaac } 6870d3d1a6afSToby Isaac else { 687169291d52SBarry Smith ierr = DMGetWorkArray(dm,numPoints+1,MPIU_INT,&pointMatOffsets[0]);CHKERRQ(ierr); 687269291d52SBarry Smith ierr = DMGetWorkArray(dm,numPoints,MPIU_INT,&newPointOffsets[0]);CHKERRQ(ierr); 6873d3d1a6afSToby Isaac } 6874d3d1a6afSToby Isaac 6875d3d1a6afSToby Isaac /* get workspaces for the point-to-point matrices */ 6876d3d1a6afSToby Isaac if (numFields) { 68774b2f2278SToby Isaac PetscInt totalOffset, totalMatOffset; 68784b2f2278SToby Isaac 6879d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 6880d3d1a6afSToby Isaac PetscInt b = points[2*p]; 68814b2f2278SToby Isaac PetscInt bDof = 0, bSecDof; 6882d3d1a6afSToby Isaac 68834b2f2278SToby Isaac ierr = PetscSectionGetDof(section,b,&bSecDof);CHKERRQ(ierr); 68844b2f2278SToby Isaac if (!bSecDof) { 68854b2f2278SToby Isaac for (f = 0; f < numFields; f++) { 68864b2f2278SToby Isaac newPointOffsets[f][p + 1] = 0; 68874b2f2278SToby Isaac pointMatOffsets[f][p + 1] = 0; 68884b2f2278SToby Isaac } 68894b2f2278SToby Isaac continue; 68904b2f2278SToby Isaac } 6891d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 6892d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec, b, &bDof);CHKERRQ(ierr); 6893d3d1a6afSToby Isaac } 6894d3d1a6afSToby Isaac if (bDof) { 6895d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 6896d3d1a6afSToby Isaac PetscInt fDof, q, bOff, allFDof = 0; 6897d3d1a6afSToby Isaac 6898d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, b, f, &fDof);CHKERRQ(ierr); 6899d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(aSec, b, &bOff);CHKERRQ(ierr); 6900d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 6901d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q]; 6902d3d1a6afSToby Isaac PetscInt aFDof; 6903d3d1a6afSToby Isaac 6904d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, a, f, &aFDof);CHKERRQ(ierr); 6905d3d1a6afSToby Isaac allFDof += aFDof; 6906d3d1a6afSToby Isaac } 6907d3d1a6afSToby Isaac newPointOffsets[f][p+1] = allFDof; 6908d3d1a6afSToby Isaac pointMatOffsets[f][p+1] = fDof * allFDof; 6909d3d1a6afSToby Isaac } 6910d3d1a6afSToby Isaac } 6911d3d1a6afSToby Isaac else { 6912d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 6913d3d1a6afSToby Isaac PetscInt fDof; 6914d3d1a6afSToby Isaac 6915d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, b, f, &fDof);CHKERRQ(ierr); 6916d3d1a6afSToby Isaac newPointOffsets[f][p+1] = fDof; 6917d3d1a6afSToby Isaac pointMatOffsets[f][p+1] = 0; 6918d3d1a6afSToby Isaac } 6919d3d1a6afSToby Isaac } 6920d3d1a6afSToby Isaac } 69214b2f2278SToby Isaac for (f = 0, totalOffset = 0, totalMatOffset = 0; f < numFields; f++) { 69224b2f2278SToby Isaac newPointOffsets[f][0] = totalOffset; 69234b2f2278SToby Isaac pointMatOffsets[f][0] = totalMatOffset; 6924d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 6925d3d1a6afSToby Isaac newPointOffsets[f][p+1] += newPointOffsets[f][p]; 6926d3d1a6afSToby Isaac pointMatOffsets[f][p+1] += pointMatOffsets[f][p]; 6927d3d1a6afSToby Isaac } 692819f70fd5SToby Isaac totalOffset = newPointOffsets[f][numPoints]; 692919f70fd5SToby Isaac totalMatOffset = pointMatOffsets[f][numPoints]; 693069291d52SBarry Smith ierr = DMGetWorkArray(dm,pointMatOffsets[f][numPoints],MPIU_SCALAR,&pointMat[f]);CHKERRQ(ierr); 6931d3d1a6afSToby Isaac } 6932d3d1a6afSToby Isaac } 6933d3d1a6afSToby Isaac else { 6934d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 6935d3d1a6afSToby Isaac PetscInt b = points[2*p]; 69364b2f2278SToby Isaac PetscInt bDof = 0, bSecDof; 6937d3d1a6afSToby Isaac 69384b2f2278SToby Isaac ierr = PetscSectionGetDof(section,b,&bSecDof);CHKERRQ(ierr); 69394b2f2278SToby Isaac if (!bSecDof) { 69404b2f2278SToby Isaac newPointOffsets[0][p + 1] = 0; 69414b2f2278SToby Isaac pointMatOffsets[0][p + 1] = 0; 69424b2f2278SToby Isaac continue; 69434b2f2278SToby Isaac } 6944d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 6945d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec, b, &bDof);CHKERRQ(ierr); 6946d3d1a6afSToby Isaac } 6947d3d1a6afSToby Isaac if (bDof) { 69484b2f2278SToby Isaac PetscInt bOff, q, allDof = 0; 6949d3d1a6afSToby Isaac 6950d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(aSec, b, &bOff);CHKERRQ(ierr); 6951d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 6952d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q], aDof; 6953d3d1a6afSToby Isaac 6954d3d1a6afSToby Isaac ierr = PetscSectionGetDof(section, a, &aDof);CHKERRQ(ierr); 6955d3d1a6afSToby Isaac allDof += aDof; 6956d3d1a6afSToby Isaac } 6957d3d1a6afSToby Isaac newPointOffsets[0][p+1] = allDof; 69584b2f2278SToby Isaac pointMatOffsets[0][p+1] = bSecDof * allDof; 6959d3d1a6afSToby Isaac } 6960d3d1a6afSToby Isaac else { 69614b2f2278SToby Isaac newPointOffsets[0][p+1] = bSecDof; 6962d3d1a6afSToby Isaac pointMatOffsets[0][p+1] = 0; 6963d3d1a6afSToby Isaac } 6964d3d1a6afSToby Isaac } 6965d3d1a6afSToby Isaac newPointOffsets[0][0] = 0; 6966d3d1a6afSToby Isaac pointMatOffsets[0][0] = 0; 6967d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 6968d3d1a6afSToby Isaac newPointOffsets[0][p+1] += newPointOffsets[0][p]; 6969d3d1a6afSToby Isaac pointMatOffsets[0][p+1] += pointMatOffsets[0][p]; 6970d3d1a6afSToby Isaac } 697169291d52SBarry Smith ierr = DMGetWorkArray(dm,pointMatOffsets[0][numPoints],MPIU_SCALAR,&pointMat[0]);CHKERRQ(ierr); 6972d3d1a6afSToby Isaac } 6973d3d1a6afSToby Isaac 69746ecaa68aSToby Isaac /* output arrays */ 697569291d52SBarry Smith ierr = DMGetWorkArray(dm,2*newNumPoints,MPIU_INT,&newPoints);CHKERRQ(ierr); 69766ecaa68aSToby Isaac 6977d3d1a6afSToby Isaac /* get the point-to-point matrices; construct newPoints */ 6978d3d1a6afSToby Isaac ierr = PetscSectionGetMaxDof(aSec, &maxAnchor);CHKERRQ(ierr); 6979d3d1a6afSToby Isaac ierr = PetscSectionGetMaxDof(section, &maxDof);CHKERRQ(ierr); 698069291d52SBarry Smith ierr = DMGetWorkArray(dm,maxDof,MPIU_INT,&indices);CHKERRQ(ierr); 698169291d52SBarry Smith ierr = DMGetWorkArray(dm,maxAnchor*maxDof,MPIU_INT,&newIndices);CHKERRQ(ierr); 6982d3d1a6afSToby Isaac if (numFields) { 6983d3d1a6afSToby Isaac for (p = 0, newP = 0; p < numPoints; p++) { 6984d3d1a6afSToby Isaac PetscInt b = points[2*p]; 6985d3d1a6afSToby Isaac PetscInt o = points[2*p+1]; 69864b2f2278SToby Isaac PetscInt bDof = 0, bSecDof; 6987d3d1a6afSToby Isaac 69884b2f2278SToby Isaac ierr = PetscSectionGetDof(section, b, &bSecDof);CHKERRQ(ierr); 69894b2f2278SToby Isaac if (!bSecDof) { 69904b2f2278SToby Isaac continue; 69914b2f2278SToby Isaac } 6992d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 6993d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec, b, &bDof);CHKERRQ(ierr); 6994d3d1a6afSToby Isaac } 6995d3d1a6afSToby Isaac if (bDof) { 6996d3d1a6afSToby Isaac PetscInt fStart[32], fEnd[32], fAnchorStart[32], fAnchorEnd[32], bOff, q; 6997d3d1a6afSToby Isaac 6998d3d1a6afSToby Isaac fStart[0] = 0; 6999d3d1a6afSToby Isaac fEnd[0] = 0; 7000d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 7001d3d1a6afSToby Isaac PetscInt fDof; 7002d3d1a6afSToby Isaac 7003d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(cSec, b, f, &fDof);CHKERRQ(ierr); 7004d3d1a6afSToby Isaac fStart[f+1] = fStart[f] + fDof; 7005d3d1a6afSToby Isaac fEnd[f+1] = fStart[f+1]; 7006d3d1a6afSToby Isaac } 7007d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(cSec, b, &bOff);CHKERRQ(ierr); 700836fa2b79SJed Brown ierr = DMPlexGetIndicesPointFields_Internal(cSec, PETSC_TRUE, b, bOff, fEnd, PETSC_TRUE, perms, p, NULL, indices);CHKERRQ(ierr); 7009d3d1a6afSToby Isaac 7010d3d1a6afSToby Isaac fAnchorStart[0] = 0; 7011d3d1a6afSToby Isaac fAnchorEnd[0] = 0; 7012d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 7013d3d1a6afSToby Isaac PetscInt fDof = newPointOffsets[f][p + 1] - newPointOffsets[f][p]; 7014d3d1a6afSToby Isaac 7015d3d1a6afSToby Isaac fAnchorStart[f+1] = fAnchorStart[f] + fDof; 7016d3d1a6afSToby Isaac fAnchorEnd[f+1] = fAnchorStart[f + 1]; 7017d3d1a6afSToby Isaac } 7018d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(aSec, b, &bOff);CHKERRQ(ierr); 7019d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 7020d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q], aOff; 7021d3d1a6afSToby Isaac 7022d3d1a6afSToby 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 */ 7023d3d1a6afSToby Isaac newPoints[2*(newP + q)] = a; 7024d3d1a6afSToby Isaac newPoints[2*(newP + q) + 1] = 0; 7025302440fdSBarry Smith ierr = PetscSectionGetOffset(section, a, &aOff);CHKERRQ(ierr); 702636fa2b79SJed Brown ierr = DMPlexGetIndicesPointFields_Internal(section, PETSC_TRUE, a, aOff, fAnchorEnd, PETSC_TRUE, NULL, -1, NULL, newIndices);CHKERRQ(ierr); 7027d3d1a6afSToby Isaac } 7028d3d1a6afSToby Isaac newP += bDof; 7029d3d1a6afSToby Isaac 70306ecaa68aSToby Isaac if (outValues) { 7031d3d1a6afSToby Isaac /* get the point-to-point submatrix */ 7032d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 7033d3d1a6afSToby 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); 7034d3d1a6afSToby Isaac } 7035d3d1a6afSToby Isaac } 70366ecaa68aSToby Isaac } 7037d3d1a6afSToby Isaac else { 7038d3d1a6afSToby Isaac newPoints[2 * newP] = b; 7039d3d1a6afSToby Isaac newPoints[2 * newP + 1] = o; 7040d3d1a6afSToby Isaac newP++; 7041d3d1a6afSToby Isaac } 7042d3d1a6afSToby Isaac } 7043d3d1a6afSToby Isaac } else { 7044d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 7045d3d1a6afSToby Isaac PetscInt b = points[2*p]; 7046d3d1a6afSToby Isaac PetscInt o = points[2*p+1]; 70474b2f2278SToby Isaac PetscInt bDof = 0, bSecDof; 7048d3d1a6afSToby Isaac 70494b2f2278SToby Isaac ierr = PetscSectionGetDof(section, b, &bSecDof);CHKERRQ(ierr); 70504b2f2278SToby Isaac if (!bSecDof) { 70514b2f2278SToby Isaac continue; 70524b2f2278SToby Isaac } 7053d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 7054d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec, b, &bDof);CHKERRQ(ierr); 7055d3d1a6afSToby Isaac } 7056d3d1a6afSToby Isaac if (bDof) { 7057d3d1a6afSToby Isaac PetscInt bEnd = 0, bAnchorEnd = 0, bOff; 7058d3d1a6afSToby Isaac 7059d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(cSec, b, &bOff);CHKERRQ(ierr); 706036fa2b79SJed Brown ierr = DMPlexGetIndicesPoint_Internal(cSec, PETSC_TRUE, b, bOff, &bEnd, PETSC_TRUE, (perms && perms[0]) ? perms[0][p] : NULL, NULL, indices);CHKERRQ(ierr); 7061d3d1a6afSToby Isaac 7062d3d1a6afSToby Isaac ierr = PetscSectionGetOffset (aSec, b, &bOff);CHKERRQ(ierr); 7063d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 7064d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q], aOff; 7065d3d1a6afSToby Isaac 7066d3d1a6afSToby 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 */ 7067d3d1a6afSToby Isaac 7068d3d1a6afSToby Isaac newPoints[2*(newP + q)] = a; 7069d3d1a6afSToby Isaac newPoints[2*(newP + q) + 1] = 0; 7070302440fdSBarry Smith ierr = PetscSectionGetOffset(section, a, &aOff);CHKERRQ(ierr); 707136fa2b79SJed Brown ierr = DMPlexGetIndicesPoint_Internal(section, PETSC_TRUE, a, aOff, &bAnchorEnd, PETSC_TRUE, NULL, NULL, newIndices);CHKERRQ(ierr); 7072d3d1a6afSToby Isaac } 7073d3d1a6afSToby Isaac newP += bDof; 7074d3d1a6afSToby Isaac 7075d3d1a6afSToby Isaac /* get the point-to-point submatrix */ 70766ecaa68aSToby Isaac if (outValues) { 7077d3d1a6afSToby Isaac ierr = MatGetValues(cMat,bEnd,indices,bAnchorEnd,newIndices,pointMat[0] + pointMatOffsets[0][p]);CHKERRQ(ierr); 7078d3d1a6afSToby Isaac } 70796ecaa68aSToby Isaac } 7080d3d1a6afSToby Isaac else { 7081d3d1a6afSToby Isaac newPoints[2 * newP] = b; 7082d3d1a6afSToby Isaac newPoints[2 * newP + 1] = o; 7083d3d1a6afSToby Isaac newP++; 7084d3d1a6afSToby Isaac } 7085d3d1a6afSToby Isaac } 7086d3d1a6afSToby Isaac } 7087d3d1a6afSToby Isaac 70886ecaa68aSToby Isaac if (outValues) { 708969291d52SBarry Smith ierr = DMGetWorkArray(dm,newNumIndices*numIndices,MPIU_SCALAR,&tmpValues);CHKERRQ(ierr); 7090580bdb30SBarry Smith ierr = PetscArrayzero(tmpValues,newNumIndices*numIndices);CHKERRQ(ierr); 7091d3d1a6afSToby Isaac /* multiply constraints on the right */ 7092d3d1a6afSToby Isaac if (numFields) { 7093d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 7094d3d1a6afSToby Isaac PetscInt oldOff = offsets[f]; 7095d3d1a6afSToby Isaac 7096d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 7097d3d1a6afSToby Isaac PetscInt cStart = newPointOffsets[f][p]; 7098d3d1a6afSToby Isaac PetscInt b = points[2 * p]; 7099d3d1a6afSToby Isaac PetscInt c, r, k; 7100d3d1a6afSToby Isaac PetscInt dof; 7101d3d1a6afSToby Isaac 7102d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section,b,f,&dof);CHKERRQ(ierr); 71034b2f2278SToby Isaac if (!dof) { 71044b2f2278SToby Isaac continue; 71054b2f2278SToby Isaac } 7106d3d1a6afSToby Isaac if (pointMatOffsets[f][p] < pointMatOffsets[f][p + 1]) { 7107d3d1a6afSToby Isaac PetscInt nCols = newPointOffsets[f][p+1]-cStart; 7108d3d1a6afSToby Isaac const PetscScalar *mat = pointMat[f] + pointMatOffsets[f][p]; 7109d3d1a6afSToby Isaac 7110d3d1a6afSToby Isaac for (r = 0; r < numIndices; r++) { 7111d3d1a6afSToby Isaac for (c = 0; c < nCols; c++) { 7112d3d1a6afSToby Isaac for (k = 0; k < dof; k++) { 71134acb8e1eSToby Isaac tmpValues[r * newNumIndices + cStart + c] += values[r * numIndices + oldOff + k] * mat[k * nCols + c]; 7114d3d1a6afSToby Isaac } 7115d3d1a6afSToby Isaac } 7116d3d1a6afSToby Isaac } 7117d3d1a6afSToby Isaac } 7118d3d1a6afSToby Isaac else { 7119d3d1a6afSToby Isaac /* copy this column as is */ 7120d3d1a6afSToby Isaac for (r = 0; r < numIndices; r++) { 7121d3d1a6afSToby Isaac for (c = 0; c < dof; c++) { 7122d3d1a6afSToby Isaac tmpValues[r * newNumIndices + cStart + c] = values[r * numIndices + oldOff + c]; 7123d3d1a6afSToby Isaac } 7124d3d1a6afSToby Isaac } 7125d3d1a6afSToby Isaac } 7126d3d1a6afSToby Isaac oldOff += dof; 7127d3d1a6afSToby Isaac } 7128d3d1a6afSToby Isaac } 7129d3d1a6afSToby Isaac } 7130d3d1a6afSToby Isaac else { 7131d3d1a6afSToby Isaac PetscInt oldOff = 0; 7132d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 7133d3d1a6afSToby Isaac PetscInt cStart = newPointOffsets[0][p]; 7134d3d1a6afSToby Isaac PetscInt b = points[2 * p]; 7135d3d1a6afSToby Isaac PetscInt c, r, k; 7136d3d1a6afSToby Isaac PetscInt dof; 7137d3d1a6afSToby Isaac 7138d3d1a6afSToby Isaac ierr = PetscSectionGetDof(section,b,&dof);CHKERRQ(ierr); 71394b2f2278SToby Isaac if (!dof) { 71404b2f2278SToby Isaac continue; 71414b2f2278SToby Isaac } 7142d3d1a6afSToby Isaac if (pointMatOffsets[0][p] < pointMatOffsets[0][p + 1]) { 7143d3d1a6afSToby Isaac PetscInt nCols = newPointOffsets[0][p+1]-cStart; 7144d3d1a6afSToby Isaac const PetscScalar *mat = pointMat[0] + pointMatOffsets[0][p]; 7145d3d1a6afSToby Isaac 7146d3d1a6afSToby Isaac for (r = 0; r < numIndices; r++) { 7147d3d1a6afSToby Isaac for (c = 0; c < nCols; c++) { 7148d3d1a6afSToby Isaac for (k = 0; k < dof; k++) { 7149d3d1a6afSToby Isaac tmpValues[r * newNumIndices + cStart + c] += mat[k * nCols + c] * values[r * numIndices + oldOff + k]; 7150d3d1a6afSToby Isaac } 7151d3d1a6afSToby Isaac } 7152d3d1a6afSToby Isaac } 7153d3d1a6afSToby Isaac } 7154d3d1a6afSToby Isaac else { 7155d3d1a6afSToby Isaac /* copy this column as is */ 7156d3d1a6afSToby Isaac for (r = 0; r < numIndices; r++) { 7157d3d1a6afSToby Isaac for (c = 0; c < dof; c++) { 7158d3d1a6afSToby Isaac tmpValues[r * newNumIndices + cStart + c] = values[r * numIndices + oldOff + c]; 7159d3d1a6afSToby Isaac } 7160d3d1a6afSToby Isaac } 7161d3d1a6afSToby Isaac } 7162d3d1a6afSToby Isaac oldOff += dof; 7163d3d1a6afSToby Isaac } 7164d3d1a6afSToby Isaac } 7165d3d1a6afSToby Isaac 71666ecaa68aSToby Isaac if (multiplyLeft) { 716769291d52SBarry Smith ierr = DMGetWorkArray(dm,newNumIndices*newNumIndices,MPIU_SCALAR,&newValues);CHKERRQ(ierr); 7168580bdb30SBarry Smith ierr = PetscArrayzero(newValues,newNumIndices*newNumIndices);CHKERRQ(ierr); 7169d3d1a6afSToby Isaac /* multiply constraints transpose on the left */ 7170d3d1a6afSToby Isaac if (numFields) { 7171d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 7172d3d1a6afSToby Isaac PetscInt oldOff = offsets[f]; 7173d3d1a6afSToby Isaac 7174d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 7175d3d1a6afSToby Isaac PetscInt rStart = newPointOffsets[f][p]; 7176d3d1a6afSToby Isaac PetscInt b = points[2 * p]; 7177d3d1a6afSToby Isaac PetscInt c, r, k; 7178d3d1a6afSToby Isaac PetscInt dof; 7179d3d1a6afSToby Isaac 7180d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section,b,f,&dof);CHKERRQ(ierr); 7181d3d1a6afSToby Isaac if (pointMatOffsets[f][p] < pointMatOffsets[f][p + 1]) { 7182d3d1a6afSToby Isaac PetscInt nRows = newPointOffsets[f][p+1]-rStart; 7183d3d1a6afSToby Isaac const PetscScalar *PETSC_RESTRICT mat = pointMat[f] + pointMatOffsets[f][p]; 7184d3d1a6afSToby Isaac 7185d3d1a6afSToby Isaac for (r = 0; r < nRows; r++) { 7186d3d1a6afSToby Isaac for (c = 0; c < newNumIndices; c++) { 7187d3d1a6afSToby Isaac for (k = 0; k < dof; k++) { 7188d3d1a6afSToby Isaac newValues[(rStart + r) * newNumIndices + c] += mat[k * nRows + r] * tmpValues[(oldOff + k) * newNumIndices + c]; 7189d3d1a6afSToby Isaac } 7190d3d1a6afSToby Isaac } 7191d3d1a6afSToby Isaac } 7192d3d1a6afSToby Isaac } 7193d3d1a6afSToby Isaac else { 7194d3d1a6afSToby Isaac /* copy this row as is */ 7195d3d1a6afSToby Isaac for (r = 0; r < dof; r++) { 7196d3d1a6afSToby Isaac for (c = 0; c < newNumIndices; c++) { 7197d3d1a6afSToby Isaac newValues[(rStart + r) * newNumIndices + c] = tmpValues[(oldOff + r) * newNumIndices + c]; 7198d3d1a6afSToby Isaac } 7199d3d1a6afSToby Isaac } 7200d3d1a6afSToby Isaac } 7201d3d1a6afSToby Isaac oldOff += dof; 7202d3d1a6afSToby Isaac } 7203d3d1a6afSToby Isaac } 7204d3d1a6afSToby Isaac } 7205d3d1a6afSToby Isaac else { 7206d3d1a6afSToby Isaac PetscInt oldOff = 0; 7207d3d1a6afSToby Isaac 7208d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 7209d3d1a6afSToby Isaac PetscInt rStart = newPointOffsets[0][p]; 7210d3d1a6afSToby Isaac PetscInt b = points[2 * p]; 7211d3d1a6afSToby Isaac PetscInt c, r, k; 7212d3d1a6afSToby Isaac PetscInt dof; 7213d3d1a6afSToby Isaac 7214d3d1a6afSToby Isaac ierr = PetscSectionGetDof(section,b,&dof);CHKERRQ(ierr); 7215d3d1a6afSToby Isaac if (pointMatOffsets[0][p] < pointMatOffsets[0][p + 1]) { 7216d3d1a6afSToby Isaac PetscInt nRows = newPointOffsets[0][p+1]-rStart; 7217d3d1a6afSToby Isaac const PetscScalar *PETSC_RESTRICT mat = pointMat[0] + pointMatOffsets[0][p]; 7218d3d1a6afSToby Isaac 7219d3d1a6afSToby Isaac for (r = 0; r < nRows; r++) { 7220d3d1a6afSToby Isaac for (c = 0; c < newNumIndices; c++) { 7221d3d1a6afSToby Isaac for (k = 0; k < dof; k++) { 7222d3d1a6afSToby Isaac newValues[(rStart + r) * newNumIndices + c] += mat[k * nRows + r] * tmpValues[(oldOff + k) * newNumIndices + c]; 7223d3d1a6afSToby Isaac } 7224d3d1a6afSToby Isaac } 7225d3d1a6afSToby Isaac } 7226d3d1a6afSToby Isaac } 7227d3d1a6afSToby Isaac else { 7228d3d1a6afSToby Isaac /* copy this row as is */ 72299fc93327SToby Isaac for (r = 0; r < dof; r++) { 7230d3d1a6afSToby Isaac for (c = 0; c < newNumIndices; c++) { 7231d3d1a6afSToby Isaac newValues[(rStart + r) * newNumIndices + c] = tmpValues[(oldOff + r) * newNumIndices + c]; 7232d3d1a6afSToby Isaac } 7233d3d1a6afSToby Isaac } 7234d3d1a6afSToby Isaac } 7235d3d1a6afSToby Isaac oldOff += dof; 7236d3d1a6afSToby Isaac } 7237d3d1a6afSToby Isaac } 7238d3d1a6afSToby Isaac 723969291d52SBarry Smith ierr = DMRestoreWorkArray(dm,newNumIndices*numIndices,MPIU_SCALAR,&tmpValues);CHKERRQ(ierr); 72406ecaa68aSToby Isaac } 72416ecaa68aSToby Isaac else { 72426ecaa68aSToby Isaac newValues = tmpValues; 72436ecaa68aSToby Isaac } 72446ecaa68aSToby Isaac } 72456ecaa68aSToby Isaac 7246d3d1a6afSToby Isaac /* clean up */ 724769291d52SBarry Smith ierr = DMRestoreWorkArray(dm,maxDof,MPIU_INT,&indices);CHKERRQ(ierr); 724869291d52SBarry Smith ierr = DMRestoreWorkArray(dm,maxAnchor*maxDof,MPIU_INT,&newIndices);CHKERRQ(ierr); 72496ecaa68aSToby Isaac 7250d3d1a6afSToby Isaac if (numFields) { 7251d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 725269291d52SBarry Smith ierr = DMRestoreWorkArray(dm,pointMatOffsets[f][numPoints],MPIU_SCALAR,&pointMat[f]);CHKERRQ(ierr); 725369291d52SBarry Smith ierr = DMRestoreWorkArray(dm,numPoints+1,MPIU_INT,&pointMatOffsets[f]);CHKERRQ(ierr); 725469291d52SBarry Smith ierr = DMRestoreWorkArray(dm,numPoints+1,MPIU_INT,&newPointOffsets[f]);CHKERRQ(ierr); 7255d3d1a6afSToby Isaac } 7256d3d1a6afSToby Isaac } 7257d3d1a6afSToby Isaac else { 725869291d52SBarry Smith ierr = DMRestoreWorkArray(dm,pointMatOffsets[0][numPoints],MPIU_SCALAR,&pointMat[0]);CHKERRQ(ierr); 725969291d52SBarry Smith ierr = DMRestoreWorkArray(dm,numPoints+1,MPIU_INT,&pointMatOffsets[0]);CHKERRQ(ierr); 726069291d52SBarry Smith ierr = DMRestoreWorkArray(dm,numPoints+1,MPIU_INT,&newPointOffsets[0]);CHKERRQ(ierr); 7261d3d1a6afSToby Isaac } 7262d3d1a6afSToby Isaac ierr = ISRestoreIndices(aIS,&anchors);CHKERRQ(ierr); 7263d3d1a6afSToby Isaac 7264d3d1a6afSToby Isaac /* output */ 72656ecaa68aSToby Isaac if (outPoints) { 7266d3d1a6afSToby Isaac *outPoints = newPoints; 72676ecaa68aSToby Isaac } 72686ecaa68aSToby Isaac else { 726969291d52SBarry Smith ierr = DMRestoreWorkArray(dm,2*newNumPoints,MPIU_INT,&newPoints);CHKERRQ(ierr); 72706ecaa68aSToby Isaac } 727131620726SToby Isaac if (outValues) { 7272d3d1a6afSToby Isaac *outValues = newValues; 72736ecaa68aSToby Isaac } 72746ecaa68aSToby Isaac for (f = 0; f <= numFields; f++) { 7275d3d1a6afSToby Isaac offsets[f] = newOffsets[f]; 7276d3d1a6afSToby Isaac } 7277d3d1a6afSToby Isaac PetscFunctionReturn(0); 7278d3d1a6afSToby Isaac } 7279d3d1a6afSToby Isaac 72804a1e0b3eSMatthew G. Knepley /*@C 728171f0bbf9SMatthew G. Knepley DMPlexGetClosureIndices - Gets the global dof indices associated with the closure of the given point within the provided sections. 72827cd05799SMatthew G. Knepley 72837cd05799SMatthew G. Knepley Not collective 72847cd05799SMatthew G. Knepley 72857cd05799SMatthew G. Knepley Input Parameters: 72867cd05799SMatthew G. Knepley + dm - The DM 728771f0bbf9SMatthew G. Knepley . section - The PetscSection describing the points (a local section) 728871f0bbf9SMatthew G. Knepley . idxSection - The PetscSection from which to obtain indices (may be local or global) 728971f0bbf9SMatthew G. Knepley . point - The point defining the closure 729071f0bbf9SMatthew G. Knepley - useClPerm - Use the closure point permutation if available 72917cd05799SMatthew G. Knepley 729271f0bbf9SMatthew G. Knepley Output Parameters: 729371f0bbf9SMatthew G. Knepley + numIndices - The number of dof indices in the closure of point with the input sections 729471f0bbf9SMatthew G. Knepley . indices - The dof indices 729571f0bbf9SMatthew G. Knepley . outOffsets - Array to write the field offsets into, or NULL 729671f0bbf9SMatthew G. Knepley - values - The input values, which may be modified if sign flips are induced by the point symmetries, or NULL 72977cd05799SMatthew G. Knepley 729836fa2b79SJed Brown Notes: 729936fa2b79SJed Brown Must call DMPlexRestoreClosureIndices() to free allocated memory 730036fa2b79SJed Brown 730136fa2b79SJed Brown If idxSection is global, any constrained dofs (see DMAddBoundary(), for example) will get negative indices. The value 730236fa2b79SJed Brown of those indices is not significant. If idxSection is local, the constrained dofs will yield the involution -(idx+1) 730336fa2b79SJed Brown of their index in a local vector. A caller who does not wish to distinguish those points may recover the nonnegative 730436fa2b79SJed Brown indices via involution, -(-(idx+1)+1)==idx. Local indices are provided when idxSection == section, otherwise global 730536fa2b79SJed Brown indices (with the above semantics) are implied. 73067cd05799SMatthew G. Knepley 73077cd05799SMatthew G. Knepley Level: advanced 73087cd05799SMatthew G. Knepley 730936fa2b79SJed Brown .seealso DMPlexRestoreClosureIndices(), DMPlexVecGetClosure(), DMPlexMatSetClosure(), DMGetLocalSection(), DMGetGlobalSection() 73104a1e0b3eSMatthew G. Knepley @*/ 731171f0bbf9SMatthew G. Knepley PetscErrorCode DMPlexGetClosureIndices(DM dm, PetscSection section, PetscSection idxSection, PetscInt point, PetscBool useClPerm, 731271f0bbf9SMatthew G. Knepley PetscInt *numIndices, PetscInt *indices[], PetscInt outOffsets[], PetscScalar *values[]) 73137773e69fSMatthew G. Knepley { 731471f0bbf9SMatthew G. Knepley /* Closure ordering */ 73157773e69fSMatthew G. Knepley PetscSection clSection; 73167773e69fSMatthew G. Knepley IS clPoints; 731771f0bbf9SMatthew G. Knepley const PetscInt *clp; 731871f0bbf9SMatthew G. Knepley PetscInt *points; 731971f0bbf9SMatthew G. Knepley const PetscInt *clperm = NULL; 732071f0bbf9SMatthew G. Knepley /* Dof permutation and sign flips */ 73214acb8e1eSToby Isaac const PetscInt **perms[32] = {NULL}; 732271f0bbf9SMatthew G. Knepley const PetscScalar **flips[32] = {NULL}; 732371f0bbf9SMatthew G. Knepley PetscScalar *valCopy = NULL; 732471f0bbf9SMatthew G. Knepley /* Hanging node constraints */ 732571f0bbf9SMatthew G. Knepley PetscInt *pointsC = NULL; 732671f0bbf9SMatthew G. Knepley PetscScalar *valuesC = NULL; 732771f0bbf9SMatthew G. Knepley PetscInt NclC, NiC; 732871f0bbf9SMatthew G. Knepley 732971f0bbf9SMatthew G. Knepley PetscInt *idx; 733071f0bbf9SMatthew G. Knepley PetscInt Nf, Ncl, Ni = 0, offsets[32], p, f; 733171f0bbf9SMatthew G. Knepley PetscBool isLocal = (section == idxSection) ? PETSC_TRUE : PETSC_FALSE; 73327773e69fSMatthew G. Knepley PetscErrorCode ierr; 73337773e69fSMatthew G. Knepley 733471f0bbf9SMatthew G. Knepley PetscFunctionBeginHot; 73357773e69fSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 73367773e69fSMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 733736fa2b79SJed Brown PetscValidHeaderSpecific(idxSection, PETSC_SECTION_CLASSID, 3); 733871f0bbf9SMatthew G. Knepley if (numIndices) PetscValidPointer(numIndices, 6); 733971f0bbf9SMatthew G. Knepley if (indices) PetscValidPointer(indices, 7); 734071f0bbf9SMatthew G. Knepley if (outOffsets) PetscValidPointer(outOffsets, 8); 734171f0bbf9SMatthew G. Knepley if (values) PetscValidPointer(values, 9); 73427773e69fSMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &Nf);CHKERRQ(ierr); 73432c71b3e2SJacob Faibussowitsch PetscCheckFalse(Nf > 31,PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Number of fields %D limited to 31", Nf); 7344580bdb30SBarry Smith ierr = PetscArrayzero(offsets, 32);CHKERRQ(ierr); 734571f0bbf9SMatthew G. Knepley /* 1) Get points in closure */ 734671f0bbf9SMatthew G. Knepley ierr = DMPlexGetCompressedClosure(dm, section, point, &Ncl, &points, &clSection, &clPoints, &clp);CHKERRQ(ierr); 7347c459fbc1SJed Brown if (useClPerm) { 7348c459fbc1SJed Brown PetscInt depth, clsize; 7349c459fbc1SJed Brown ierr = DMPlexGetPointDepth(dm, point, &depth);CHKERRQ(ierr); 7350c459fbc1SJed Brown for (clsize=0,p=0; p<Ncl; p++) { 7351c459fbc1SJed Brown PetscInt dof; 7352c459fbc1SJed Brown ierr = PetscSectionGetDof(section, points[2*p], &dof);CHKERRQ(ierr); 7353c459fbc1SJed Brown clsize += dof; 7354c459fbc1SJed Brown } 7355c459fbc1SJed Brown ierr = PetscSectionGetClosureInversePermutation_Internal(section, (PetscObject) dm, depth, clsize, &clperm);CHKERRQ(ierr); 7356c459fbc1SJed Brown } 735771f0bbf9SMatthew G. Knepley /* 2) Get number of indices on these points and field offsets from section */ 735871f0bbf9SMatthew G. Knepley for (p = 0; p < Ncl*2; p += 2) { 73597773e69fSMatthew G. Knepley PetscInt dof, fdof; 73607773e69fSMatthew G. Knepley 73617773e69fSMatthew G. Knepley ierr = PetscSectionGetDof(section, points[p], &dof);CHKERRQ(ierr); 73627773e69fSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 73637773e69fSMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, points[p], f, &fdof);CHKERRQ(ierr); 73647773e69fSMatthew G. Knepley offsets[f+1] += fdof; 73657773e69fSMatthew G. Knepley } 736671f0bbf9SMatthew G. Knepley Ni += dof; 73677773e69fSMatthew G. Knepley } 73687773e69fSMatthew G. Knepley for (f = 1; f < Nf; ++f) offsets[f+1] += offsets[f]; 73692c71b3e2SJacob Faibussowitsch PetscCheckFalse(Nf && offsets[Nf] != Ni,PetscObjectComm((PetscObject) dm), PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", offsets[Nf], Ni); 737071f0bbf9SMatthew G. Knepley /* 3) Get symmetries and sign flips. Apply sign flips to values if passed in (only works for square values matrix) */ 737171f0bbf9SMatthew G. Knepley for (f = 0; f < PetscMax(1, Nf); ++f) { 737271f0bbf9SMatthew G. Knepley if (Nf) {ierr = PetscSectionGetFieldPointSyms(section, f, Ncl, points, &perms[f], &flips[f]);CHKERRQ(ierr);} 737371f0bbf9SMatthew G. Knepley else {ierr = PetscSectionGetPointSyms(section, Ncl, points, &perms[f], &flips[f]);CHKERRQ(ierr);} 737471f0bbf9SMatthew G. Knepley /* may need to apply sign changes to the element matrix */ 737571f0bbf9SMatthew G. Knepley if (values && flips[f]) { 737671f0bbf9SMatthew G. Knepley PetscInt foffset = offsets[f]; 73776ecaa68aSToby Isaac 737871f0bbf9SMatthew G. Knepley for (p = 0; p < Ncl; ++p) { 737971f0bbf9SMatthew G. Knepley PetscInt pnt = points[2*p], fdof; 738071f0bbf9SMatthew G. Knepley const PetscScalar *flip = flips[f] ? flips[f][p] : NULL; 738171f0bbf9SMatthew G. Knepley 738271f0bbf9SMatthew G. Knepley if (!Nf) {ierr = PetscSectionGetDof(section, pnt, &fdof);CHKERRQ(ierr);} 738371f0bbf9SMatthew G. Knepley else {ierr = PetscSectionGetFieldDof(section, pnt, f, &fdof);CHKERRQ(ierr);} 738471f0bbf9SMatthew G. Knepley if (flip) { 738571f0bbf9SMatthew G. Knepley PetscInt i, j, k; 738671f0bbf9SMatthew G. Knepley 738771f0bbf9SMatthew G. Knepley if (!valCopy) { 738871f0bbf9SMatthew G. Knepley ierr = DMGetWorkArray(dm, Ni*Ni, MPIU_SCALAR, &valCopy);CHKERRQ(ierr); 738971f0bbf9SMatthew G. Knepley for (j = 0; j < Ni * Ni; ++j) valCopy[j] = (*values)[j]; 739071f0bbf9SMatthew G. Knepley *values = valCopy; 739171f0bbf9SMatthew G. Knepley } 739271f0bbf9SMatthew G. Knepley for (i = 0; i < fdof; ++i) { 739371f0bbf9SMatthew G. Knepley PetscScalar fval = flip[i]; 739471f0bbf9SMatthew G. Knepley 739571f0bbf9SMatthew G. Knepley for (k = 0; k < Ni; ++k) { 739671f0bbf9SMatthew G. Knepley valCopy[Ni * (foffset + i) + k] *= fval; 739771f0bbf9SMatthew G. Knepley valCopy[Ni * k + (foffset + i)] *= fval; 73986ecaa68aSToby Isaac } 73996ecaa68aSToby Isaac } 740071f0bbf9SMatthew G. Knepley } 740171f0bbf9SMatthew G. Knepley foffset += fdof; 740271f0bbf9SMatthew G. Knepley } 740371f0bbf9SMatthew G. Knepley } 740471f0bbf9SMatthew G. Knepley } 740571f0bbf9SMatthew G. Knepley /* 4) Apply hanging node constraints. Get new symmetries and replace all storage with constrained storage */ 740671f0bbf9SMatthew G. Knepley ierr = DMPlexAnchorsModifyMat(dm, section, Ncl, Ni, points, perms, values ? *values : NULL, &NclC, &NiC, &pointsC, values ? &valuesC : NULL, offsets, PETSC_TRUE);CHKERRQ(ierr); 740771f0bbf9SMatthew G. Knepley if (NclC) { 740871f0bbf9SMatthew G. Knepley if (valCopy) {ierr = DMRestoreWorkArray(dm, Ni*Ni, MPIU_SCALAR, &valCopy);CHKERRQ(ierr);} 740971f0bbf9SMatthew G. Knepley for (f = 0; f < PetscMax(1, Nf); ++f) { 741071f0bbf9SMatthew G. Knepley if (Nf) {ierr = PetscSectionRestoreFieldPointSyms(section, f, Ncl, points, &perms[f], &flips[f]);CHKERRQ(ierr);} 741171f0bbf9SMatthew G. Knepley else {ierr = PetscSectionRestorePointSyms(section, Ncl, points, &perms[f], &flips[f]);CHKERRQ(ierr);} 741271f0bbf9SMatthew G. Knepley } 741371f0bbf9SMatthew G. Knepley for (f = 0; f < PetscMax(1, Nf); ++f) { 741471f0bbf9SMatthew G. Knepley if (Nf) {ierr = PetscSectionGetFieldPointSyms(section, f, NclC, pointsC, &perms[f], &flips[f]);CHKERRQ(ierr);} 741571f0bbf9SMatthew G. Knepley else {ierr = PetscSectionGetPointSyms(section, NclC, pointsC, &perms[f], &flips[f]);CHKERRQ(ierr);} 741671f0bbf9SMatthew G. Knepley } 741771f0bbf9SMatthew G. Knepley ierr = DMPlexRestoreCompressedClosure(dm, section, point, &Ncl, &points, &clSection, &clPoints, &clp);CHKERRQ(ierr); 741871f0bbf9SMatthew G. Knepley Ncl = NclC; 741971f0bbf9SMatthew G. Knepley Ni = NiC; 742071f0bbf9SMatthew G. Knepley points = pointsC; 742171f0bbf9SMatthew G. Knepley if (values) *values = valuesC; 742271f0bbf9SMatthew G. Knepley } 742371f0bbf9SMatthew G. Knepley /* 5) Calculate indices */ 742471f0bbf9SMatthew G. Knepley ierr = DMGetWorkArray(dm, Ni, MPIU_INT, &idx);CHKERRQ(ierr); 742571f0bbf9SMatthew G. Knepley if (Nf) { 742671f0bbf9SMatthew G. Knepley PetscInt idxOff; 742771f0bbf9SMatthew G. Knepley PetscBool useFieldOffsets; 742871f0bbf9SMatthew G. Knepley 742971f0bbf9SMatthew G. Knepley if (outOffsets) {for (f = 0; f <= Nf; f++) outOffsets[f] = offsets[f];} 743071f0bbf9SMatthew G. Knepley ierr = PetscSectionGetUseFieldOffsets(idxSection, &useFieldOffsets);CHKERRQ(ierr); 743171f0bbf9SMatthew G. Knepley if (useFieldOffsets) { 743271f0bbf9SMatthew G. Knepley for (p = 0; p < Ncl; ++p) { 743371f0bbf9SMatthew G. Knepley const PetscInt pnt = points[p*2]; 743471f0bbf9SMatthew G. Knepley 743571f0bbf9SMatthew G. Knepley ierr = DMPlexGetIndicesPointFieldsSplit_Internal(section, idxSection, pnt, offsets, perms, p, clperm, idx);CHKERRQ(ierr); 74367773e69fSMatthew G. Knepley } 74377773e69fSMatthew G. Knepley } else { 743871f0bbf9SMatthew G. Knepley for (p = 0; p < Ncl; ++p) { 743971f0bbf9SMatthew G. Knepley const PetscInt pnt = points[p*2]; 744071f0bbf9SMatthew G. Knepley 744171f0bbf9SMatthew G. Knepley ierr = PetscSectionGetOffset(idxSection, pnt, &idxOff);CHKERRQ(ierr); 744271f0bbf9SMatthew G. Knepley /* Note that we pass a local section even though we're using global offsets. This is because global sections do 744371f0bbf9SMatthew G. Knepley * not (at the time of this writing) have fields set. They probably should, in which case we would pass the 744471f0bbf9SMatthew G. Knepley * global section. */ 744571f0bbf9SMatthew G. Knepley ierr = DMPlexGetIndicesPointFields_Internal(section, isLocal, pnt, idxOff < 0 ? -(idxOff+1) : idxOff, offsets, PETSC_FALSE, perms, p, clperm, idx);CHKERRQ(ierr); 744671f0bbf9SMatthew G. Knepley } 744771f0bbf9SMatthew G. Knepley } 744871f0bbf9SMatthew G. Knepley } else { 744971f0bbf9SMatthew G. Knepley PetscInt off = 0, idxOff; 745071f0bbf9SMatthew G. Knepley 745171f0bbf9SMatthew G. Knepley for (p = 0; p < Ncl; ++p) { 745271f0bbf9SMatthew G. Knepley const PetscInt pnt = points[p*2]; 74534acb8e1eSToby Isaac const PetscInt *perm = perms[0] ? perms[0][p] : NULL; 74544acb8e1eSToby Isaac 745571f0bbf9SMatthew G. Knepley ierr = PetscSectionGetOffset(idxSection, pnt, &idxOff);CHKERRQ(ierr); 745671f0bbf9SMatthew G. Knepley /* Note that we pass a local section even though we're using global offsets. This is because global sections do 745771f0bbf9SMatthew G. Knepley * not (at the time of this writing) have fields set. They probably should, in which case we would pass the global section. */ 745871f0bbf9SMatthew G. Knepley ierr = DMPlexGetIndicesPoint_Internal(section, isLocal, pnt, idxOff < 0 ? -(idxOff+1) : idxOff, &off, PETSC_FALSE, perm, clperm, idx);CHKERRQ(ierr); 74597773e69fSMatthew G. Knepley } 74607773e69fSMatthew G. Knepley } 746171f0bbf9SMatthew G. Knepley /* 6) Cleanup */ 746271f0bbf9SMatthew G. Knepley for (f = 0; f < PetscMax(1, Nf); ++f) { 746371f0bbf9SMatthew G. Knepley if (Nf) {ierr = PetscSectionRestoreFieldPointSyms(section, f, Ncl, points, &perms[f], &flips[f]);CHKERRQ(ierr);} 746471f0bbf9SMatthew G. Knepley else {ierr = PetscSectionRestorePointSyms(section, Ncl, points, &perms[f], &flips[f]);CHKERRQ(ierr);} 74654acb8e1eSToby Isaac } 746671f0bbf9SMatthew G. Knepley if (NclC) { 746771f0bbf9SMatthew G. Knepley ierr = DMRestoreWorkArray(dm, NclC*2, MPIU_INT, &pointsC);CHKERRQ(ierr); 74687773e69fSMatthew G. Knepley } else { 746971f0bbf9SMatthew G. Knepley ierr = DMPlexRestoreCompressedClosure(dm, section, point, &Ncl, &points, &clSection, &clPoints, &clp);CHKERRQ(ierr); 74707773e69fSMatthew G. Knepley } 747171f0bbf9SMatthew G. Knepley 747271f0bbf9SMatthew G. Knepley if (numIndices) *numIndices = Ni; 747371f0bbf9SMatthew G. Knepley if (indices) *indices = idx; 74747773e69fSMatthew G. Knepley PetscFunctionReturn(0); 74757773e69fSMatthew G. Knepley } 74767773e69fSMatthew G. Knepley 74777cd05799SMatthew G. Knepley /*@C 747871f0bbf9SMatthew G. Knepley DMPlexRestoreClosureIndices - Restores the global dof indices associated with the closure of the given point within the provided sections. 74797cd05799SMatthew G. Knepley 74807cd05799SMatthew G. Knepley Not collective 74817cd05799SMatthew G. Knepley 74827cd05799SMatthew G. Knepley Input Parameters: 74837cd05799SMatthew G. Knepley + dm - The DM 748471f0bbf9SMatthew G. Knepley . section - The PetscSection describing the points (a local section) 748571f0bbf9SMatthew G. Knepley . idxSection - The PetscSection from which to obtain indices (may be local or global) 748671f0bbf9SMatthew G. Knepley . point - The point defining the closure 748771f0bbf9SMatthew G. Knepley - useClPerm - Use the closure point permutation if available 748871f0bbf9SMatthew G. Knepley 748971f0bbf9SMatthew G. Knepley Output Parameters: 749071f0bbf9SMatthew G. Knepley + numIndices - The number of dof indices in the closure of point with the input sections 749171f0bbf9SMatthew G. Knepley . indices - The dof indices 749271f0bbf9SMatthew G. Knepley . outOffsets - Array to write the field offsets into, or NULL 749371f0bbf9SMatthew G. Knepley - values - The input values, which may be modified if sign flips are induced by the point symmetries, or NULL 749471f0bbf9SMatthew G. Knepley 749571f0bbf9SMatthew G. Knepley Notes: 749671f0bbf9SMatthew G. Knepley If values were modified, the user is responsible for calling DMRestoreWorkArray(dm, 0, MPIU_SCALAR, &values). 749771f0bbf9SMatthew G. Knepley 749871f0bbf9SMatthew G. Knepley If idxSection is global, any constrained dofs (see DMAddBoundary(), for example) will get negative indices. The value 749971f0bbf9SMatthew G. Knepley of those indices is not significant. If idxSection is local, the constrained dofs will yield the involution -(idx+1) 750071f0bbf9SMatthew G. Knepley of their index in a local vector. A caller who does not wish to distinguish those points may recover the nonnegative 750171f0bbf9SMatthew G. Knepley indices via involution, -(-(idx+1)+1)==idx. Local indices are provided when idxSection == section, otherwise global 750271f0bbf9SMatthew G. Knepley indices (with the above semantics) are implied. 75037cd05799SMatthew G. Knepley 75047cd05799SMatthew G. Knepley Level: advanced 75057cd05799SMatthew G. Knepley 750671f0bbf9SMatthew G. Knepley .seealso DMPlexGetClosureIndices(), DMPlexVecGetClosure(), DMPlexMatSetClosure(), DMGetLocalSection(), DMGetGlobalSection() 75077cd05799SMatthew G. Knepley @*/ 750871f0bbf9SMatthew G. Knepley PetscErrorCode DMPlexRestoreClosureIndices(DM dm, PetscSection section, PetscSection idxSection, PetscInt point, PetscBool useClPerm, 750971f0bbf9SMatthew G. Knepley PetscInt *numIndices, PetscInt *indices[], PetscInt outOffsets[], PetscScalar *values[]) 75107773e69fSMatthew G. Knepley { 75117773e69fSMatthew G. Knepley PetscErrorCode ierr; 75127773e69fSMatthew G. Knepley 75137773e69fSMatthew G. Knepley PetscFunctionBegin; 75147773e69fSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7515064a246eSJacob Faibussowitsch PetscValidPointer(indices, 7); 751669291d52SBarry Smith ierr = DMRestoreWorkArray(dm, 0, MPIU_INT, indices);CHKERRQ(ierr); 75177773e69fSMatthew G. Knepley PetscFunctionReturn(0); 75187773e69fSMatthew G. Knepley } 75197773e69fSMatthew G. Knepley 75207f5d1fdeSMatthew G. Knepley /*@C 75217f5d1fdeSMatthew G. Knepley DMPlexMatSetClosure - Set an array of the values on the closure of 'point' 75227f5d1fdeSMatthew G. Knepley 75237f5d1fdeSMatthew G. Knepley Not collective 75247f5d1fdeSMatthew G. Knepley 75257f5d1fdeSMatthew G. Knepley Input Parameters: 75267f5d1fdeSMatthew G. Knepley + dm - The DM 7527ebd6d717SJed Brown . section - The section describing the layout in v, or NULL to use the default section 7528ebd6d717SJed Brown . globalSection - The section describing the layout in v, or NULL to use the default global section 75297f5d1fdeSMatthew G. Knepley . A - The matrix 7530eaf898f9SPatrick Sanan . point - The point in the DM 75317f5d1fdeSMatthew G. Knepley . values - The array of values 75327f5d1fdeSMatthew G. Knepley - mode - The insert mode, where INSERT_ALL_VALUES and ADD_ALL_VALUES also overwrite boundary conditions 75337f5d1fdeSMatthew G. Knepley 75347f5d1fdeSMatthew G. Knepley Fortran Notes: 75357f5d1fdeSMatthew G. Knepley This routine is only available in Fortran 90, and you must include petsc.h90 in your code. 75367f5d1fdeSMatthew G. Knepley 75377f5d1fdeSMatthew G. Knepley Level: intermediate 75387f5d1fdeSMatthew G. Knepley 75394a1e0b3eSMatthew G. Knepley .seealso DMPlexMatSetClosureGeneral(), DMPlexVecGetClosure(), DMPlexVecSetClosure() 75407f5d1fdeSMatthew G. Knepley @*/ 75417c1f9639SMatthew G Knepley PetscErrorCode DMPlexMatSetClosure(DM dm, PetscSection section, PetscSection globalSection, Mat A, PetscInt point, const PetscScalar values[], InsertMode mode) 7542552f7358SJed Brown { 7543552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 7544552f7358SJed Brown PetscInt *indices; 754571f0bbf9SMatthew G. Knepley PetscInt numIndices; 754671f0bbf9SMatthew G. Knepley const PetscScalar *valuesOrig = values; 7547552f7358SJed Brown PetscErrorCode ierr; 7548552f7358SJed Brown 7549552f7358SJed Brown PetscFunctionBegin; 7550552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 755192fd8e1eSJed Brown if (!section) {ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr);} 75523dc93601SMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 7553e87a4003SBarry Smith if (!globalSection) {ierr = DMGetGlobalSection(dm, &globalSection);CHKERRQ(ierr);} 75543dc93601SMatthew G. Knepley PetscValidHeaderSpecific(globalSection, PETSC_SECTION_CLASSID, 3); 75553dc93601SMatthew G. Knepley PetscValidHeaderSpecific(A, MAT_CLASSID, 4); 7556552f7358SJed Brown 755771f0bbf9SMatthew G. Knepley ierr = DMPlexGetClosureIndices(dm, section, globalSection, point, PETSC_TRUE, &numIndices, &indices, NULL, (PetscScalar **) &values);CHKERRQ(ierr); 75580d644c17SKarl Rupp 7559b0ecff45SMatthew G. Knepley if (mesh->printSetValues) {ierr = DMPlexPrintMatSetValues(PETSC_VIEWER_STDOUT_SELF, A, point, numIndices, indices, 0, NULL, values);CHKERRQ(ierr);} 75604a1e0b3eSMatthew G. Knepley ierr = MatSetValues(A, numIndices, indices, numIndices, indices, values, mode); 7561552f7358SJed Brown if (ierr) { 7562552f7358SJed Brown PetscMPIInt rank; 7563552f7358SJed Brown PetscErrorCode ierr2; 7564552f7358SJed Brown 756555b25c41SPierre Jolivet ierr2 = MPI_Comm_rank(PetscObjectComm((PetscObject)A), &rank);CHKERRMPI(ierr2); 7566e4b003c7SBarry Smith ierr2 = (*PetscErrorPrintf)("[%d]ERROR in DMPlexMatSetClosure\n", rank);CHKERRQ(ierr2); 7567b0ecff45SMatthew G. Knepley ierr2 = DMPlexPrintMatSetValues(PETSC_VIEWER_STDERR_SELF, A, point, numIndices, indices, 0, NULL, values);CHKERRQ(ierr2); 756871f0bbf9SMatthew G. Knepley ierr2 = DMPlexRestoreClosureIndices(dm, section, globalSection, point, PETSC_TRUE, &numIndices, &indices, NULL, (PetscScalar **) &values);CHKERRQ(ierr2); 756971f0bbf9SMatthew G. Knepley if (values != valuesOrig) {ierr2 = DMRestoreWorkArray(dm, 0, MPIU_SCALAR, &values);CHKERRQ(ierr2);} 7570c3e24edfSBarry Smith SETERRQ(PetscObjectComm((PetscObject)dm),ierr,"Not possible to set matrix values"); 7571552f7358SJed Brown } 75724a1e0b3eSMatthew G. Knepley if (mesh->printFEM > 1) { 75734a1e0b3eSMatthew G. Knepley PetscInt i; 75744a1e0b3eSMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " Indices:");CHKERRQ(ierr); 75754a1e0b3eSMatthew G. Knepley for (i = 0; i < numIndices; ++i) {ierr = PetscPrintf(PETSC_COMM_SELF, " %D", indices[i]);CHKERRQ(ierr);} 75764a1e0b3eSMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 75774a1e0b3eSMatthew G. Knepley } 757871f0bbf9SMatthew G. Knepley 757971f0bbf9SMatthew G. Knepley ierr = DMPlexRestoreClosureIndices(dm, section, globalSection, point, PETSC_TRUE, &numIndices, &indices, NULL, (PetscScalar **) &values);CHKERRQ(ierr); 758071f0bbf9SMatthew G. Knepley if (values != valuesOrig) {ierr = DMRestoreWorkArray(dm, 0, MPIU_SCALAR, &values);CHKERRQ(ierr);} 758171f0bbf9SMatthew G. Knepley PetscFunctionReturn(0); 75824acb8e1eSToby Isaac } 758371f0bbf9SMatthew G. Knepley 75844a1e0b3eSMatthew G. Knepley /*@C 75854a1e0b3eSMatthew G. Knepley DMPlexMatSetClosure - Set an array of the values on the closure of 'point' using a different row and column section 75864a1e0b3eSMatthew G. Knepley 75874a1e0b3eSMatthew G. Knepley Not collective 75884a1e0b3eSMatthew G. Knepley 75894a1e0b3eSMatthew G. Knepley Input Parameters: 75904a1e0b3eSMatthew G. Knepley + dmRow - The DM for the row fields 75914a1e0b3eSMatthew G. Knepley . sectionRow - The section describing the layout, or NULL to use the default section in dmRow 75924a1e0b3eSMatthew G. Knepley . globalSectionRow - The section describing the layout, or NULL to use the default global section in dmRow 75934a1e0b3eSMatthew G. Knepley . dmCol - The DM for the column fields 75944a1e0b3eSMatthew G. Knepley . sectionCol - The section describing the layout, or NULL to use the default section in dmCol 75954a1e0b3eSMatthew G. Knepley . globalSectionCol - The section describing the layout, or NULL to use the default global section in dmCol 75964a1e0b3eSMatthew G. Knepley . A - The matrix 75974a1e0b3eSMatthew G. Knepley . point - The point in the DMs 75984a1e0b3eSMatthew G. Knepley . values - The array of values 75994a1e0b3eSMatthew G. Knepley - mode - The insert mode, where INSERT_ALL_VALUES and ADD_ALL_VALUES also overwrite boundary conditions 76004a1e0b3eSMatthew G. Knepley 76014a1e0b3eSMatthew G. Knepley Level: intermediate 76024a1e0b3eSMatthew G. Knepley 76034a1e0b3eSMatthew G. Knepley .seealso DMPlexMatSetClosure(), DMPlexVecGetClosure(), DMPlexVecSetClosure() 76044a1e0b3eSMatthew G. Knepley @*/ 760571f0bbf9SMatthew 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) 760671f0bbf9SMatthew G. Knepley { 760771f0bbf9SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dmRow->data; 760871f0bbf9SMatthew G. Knepley PetscInt *indicesRow, *indicesCol; 760971f0bbf9SMatthew G. Knepley PetscInt numIndicesRow, numIndicesCol; 761071f0bbf9SMatthew G. Knepley const PetscScalar *valuesOrig = values; 761171f0bbf9SMatthew G. Knepley PetscErrorCode ierr; 761271f0bbf9SMatthew G. Knepley 761371f0bbf9SMatthew G. Knepley PetscFunctionBegin; 761471f0bbf9SMatthew G. Knepley PetscValidHeaderSpecific(dmRow, DM_CLASSID, 1); 761571f0bbf9SMatthew G. Knepley if (!sectionRow) {ierr = DMGetLocalSection(dmRow, §ionRow);CHKERRQ(ierr);} 761671f0bbf9SMatthew G. Knepley PetscValidHeaderSpecific(sectionRow, PETSC_SECTION_CLASSID, 2); 761771f0bbf9SMatthew G. Knepley if (!globalSectionRow) {ierr = DMGetGlobalSection(dmRow, &globalSectionRow);CHKERRQ(ierr);} 761871f0bbf9SMatthew G. Knepley PetscValidHeaderSpecific(globalSectionRow, PETSC_SECTION_CLASSID, 3); 761971f0bbf9SMatthew G. Knepley PetscValidHeaderSpecific(dmCol, DM_CLASSID, 4); 762071f0bbf9SMatthew G. Knepley if (!sectionCol) {ierr = DMGetLocalSection(dmCol, §ionCol);CHKERRQ(ierr);} 762171f0bbf9SMatthew G. Knepley PetscValidHeaderSpecific(sectionCol, PETSC_SECTION_CLASSID, 5); 762271f0bbf9SMatthew G. Knepley if (!globalSectionCol) {ierr = DMGetGlobalSection(dmCol, &globalSectionCol);CHKERRQ(ierr);} 762371f0bbf9SMatthew G. Knepley PetscValidHeaderSpecific(globalSectionCol, PETSC_SECTION_CLASSID, 6); 762471f0bbf9SMatthew G. Knepley PetscValidHeaderSpecific(A, MAT_CLASSID, 7); 762571f0bbf9SMatthew G. Knepley 762671f0bbf9SMatthew G. Knepley ierr = DMPlexGetClosureIndices(dmRow, sectionRow, globalSectionRow, point, PETSC_TRUE, &numIndicesRow, &indicesRow, NULL, (PetscScalar **) &values);CHKERRQ(ierr); 762771f0bbf9SMatthew G. Knepley ierr = DMPlexGetClosureIndices(dmCol, sectionCol, globalSectionCol, point, PETSC_TRUE, &numIndicesCol, &indicesCol, NULL, (PetscScalar **) &values);CHKERRQ(ierr); 762871f0bbf9SMatthew G. Knepley 762971f0bbf9SMatthew G. Knepley if (mesh->printSetValues) {ierr = DMPlexPrintMatSetValues(PETSC_VIEWER_STDOUT_SELF, A, point, numIndicesRow, indicesRow, numIndicesCol, indicesCol, values);CHKERRQ(ierr);} 76304a1e0b3eSMatthew G. Knepley ierr = MatSetValues(A, numIndicesRow, indicesRow, numIndicesCol, indicesCol, values, mode); 763171f0bbf9SMatthew G. Knepley if (ierr) { 763271f0bbf9SMatthew G. Knepley PetscMPIInt rank; 763371f0bbf9SMatthew G. Knepley PetscErrorCode ierr2; 763471f0bbf9SMatthew G. Knepley 763555b25c41SPierre Jolivet ierr2 = MPI_Comm_rank(PetscObjectComm((PetscObject)A), &rank);CHKERRMPI(ierr2); 763671f0bbf9SMatthew G. Knepley ierr2 = (*PetscErrorPrintf)("[%d]ERROR in DMPlexMatSetClosure\n", rank);CHKERRQ(ierr2); 763771f0bbf9SMatthew G. Knepley ierr2 = DMPlexPrintMatSetValues(PETSC_VIEWER_STDERR_SELF, A, point, numIndicesRow, indicesRow, numIndicesCol, indicesCol, values);CHKERRQ(ierr2); 763871f0bbf9SMatthew G. Knepley ierr2 = DMPlexRestoreClosureIndices(dmRow, sectionRow, globalSectionRow, point, PETSC_TRUE, &numIndicesRow, &indicesRow, NULL, (PetscScalar **) &values);CHKERRQ(ierr2); 763971f0bbf9SMatthew G. Knepley ierr2 = DMPlexRestoreClosureIndices(dmCol, sectionCol, globalSectionCol, point, PETSC_TRUE, &numIndicesCol, &indicesRow, NULL, (PetscScalar **) &values);CHKERRQ(ierr2); 764071f0bbf9SMatthew G. Knepley if (values != valuesOrig) {ierr2 = DMRestoreWorkArray(dmRow, 0, MPIU_SCALAR, &values);CHKERRQ(ierr2);} 764171f0bbf9SMatthew G. Knepley CHKERRQ(ierr); 7642d3d1a6afSToby Isaac } 764371f0bbf9SMatthew G. Knepley 764471f0bbf9SMatthew G. Knepley ierr = DMPlexRestoreClosureIndices(dmRow, sectionRow, globalSectionRow, point, PETSC_TRUE, &numIndicesRow, &indicesRow, NULL, (PetscScalar **) &values);CHKERRQ(ierr); 764571f0bbf9SMatthew G. Knepley ierr = DMPlexRestoreClosureIndices(dmCol, sectionCol, globalSectionCol, point, PETSC_TRUE, &numIndicesCol, &indicesCol, NULL, (PetscScalar **) &values);CHKERRQ(ierr); 764671f0bbf9SMatthew G. Knepley if (values != valuesOrig) {ierr = DMRestoreWorkArray(dmRow, 0, MPIU_SCALAR, &values);CHKERRQ(ierr);} 7647552f7358SJed Brown PetscFunctionReturn(0); 7648552f7358SJed Brown } 7649552f7358SJed Brown 7650de41b84cSMatthew 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) 7651de41b84cSMatthew G. Knepley { 7652de41b84cSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dmf->data; 7653de41b84cSMatthew G. Knepley PetscInt *fpoints = NULL, *ftotpoints = NULL; 7654de41b84cSMatthew G. Knepley PetscInt *cpoints = NULL; 7655de41b84cSMatthew G. Knepley PetscInt *findices, *cindices; 765617c0192bSMatthew G. Knepley const PetscInt *fclperm = NULL, *cclperm = NULL; /* Closure permutations cannot work here */ 7657de41b84cSMatthew G. Knepley PetscInt foffsets[32], coffsets[32]; 7658412e9a14SMatthew G. Knepley DMPolytopeType ct; 76594ca5e9f5SMatthew G. Knepley PetscInt numFields, numSubcells, maxFPoints, numFPoints, numCPoints, numFIndices, numCIndices, dof, off, globalOff, pStart, pEnd, p, q, r, s, f; 7660de41b84cSMatthew G. Knepley PetscErrorCode ierr; 7661de41b84cSMatthew G. Knepley 7662de41b84cSMatthew G. Knepley PetscFunctionBegin; 7663de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(dmf, DM_CLASSID, 1); 7664de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(dmc, DM_CLASSID, 4); 766592fd8e1eSJed Brown if (!fsection) {ierr = DMGetLocalSection(dmf, &fsection);CHKERRQ(ierr);} 7666de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(fsection, PETSC_SECTION_CLASSID, 2); 766792fd8e1eSJed Brown if (!csection) {ierr = DMGetLocalSection(dmc, &csection);CHKERRQ(ierr);} 7668de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(csection, PETSC_SECTION_CLASSID, 5); 7669e87a4003SBarry Smith if (!globalFSection) {ierr = DMGetGlobalSection(dmf, &globalFSection);CHKERRQ(ierr);} 7670de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(globalFSection, PETSC_SECTION_CLASSID, 3); 7671e87a4003SBarry Smith if (!globalCSection) {ierr = DMGetGlobalSection(dmc, &globalCSection);CHKERRQ(ierr);} 7672de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(globalCSection, PETSC_SECTION_CLASSID, 6); 7673de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(A, MAT_CLASSID, 7); 7674de41b84cSMatthew G. Knepley ierr = PetscSectionGetNumFields(fsection, &numFields);CHKERRQ(ierr); 76752c71b3e2SJacob Faibussowitsch PetscCheckFalse(numFields > 31,PetscObjectComm((PetscObject)dmf), PETSC_ERR_ARG_OUTOFRANGE, "Number of fields %D limited to 31", numFields); 7676580bdb30SBarry Smith ierr = PetscArrayzero(foffsets, 32);CHKERRQ(ierr); 7677580bdb30SBarry Smith ierr = PetscArrayzero(coffsets, 32);CHKERRQ(ierr); 7678de41b84cSMatthew G. Knepley /* Column indices */ 7679de41b84cSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dmc, point, PETSC_TRUE, &numCPoints, &cpoints);CHKERRQ(ierr); 76804ca5e9f5SMatthew G. Knepley maxFPoints = numCPoints; 7681de41b84cSMatthew G. Knepley /* Compress out points not in the section */ 7682de41b84cSMatthew G. Knepley /* TODO: Squeeze out points with 0 dof as well */ 7683de41b84cSMatthew G. Knepley ierr = PetscSectionGetChart(csection, &pStart, &pEnd);CHKERRQ(ierr); 7684de41b84cSMatthew G. Knepley for (p = 0, q = 0; p < numCPoints*2; p += 2) { 7685de41b84cSMatthew G. Knepley if ((cpoints[p] >= pStart) && (cpoints[p] < pEnd)) { 7686de41b84cSMatthew G. Knepley cpoints[q*2] = cpoints[p]; 7687de41b84cSMatthew G. Knepley cpoints[q*2+1] = cpoints[p+1]; 7688de41b84cSMatthew G. Knepley ++q; 7689de41b84cSMatthew G. Knepley } 7690de41b84cSMatthew G. Knepley } 7691de41b84cSMatthew G. Knepley numCPoints = q; 7692de41b84cSMatthew G. Knepley for (p = 0, numCIndices = 0; p < numCPoints*2; p += 2) { 7693de41b84cSMatthew G. Knepley PetscInt fdof; 7694de41b84cSMatthew G. Knepley 7695de41b84cSMatthew G. Knepley ierr = PetscSectionGetDof(csection, cpoints[p], &dof);CHKERRQ(ierr); 76964ca5e9f5SMatthew G. Knepley if (!dof) continue; 7697de41b84cSMatthew G. Knepley for (f = 0; f < numFields; ++f) { 7698de41b84cSMatthew G. Knepley ierr = PetscSectionGetFieldDof(csection, cpoints[p], f, &fdof);CHKERRQ(ierr); 7699de41b84cSMatthew G. Knepley coffsets[f+1] += fdof; 7700de41b84cSMatthew G. Knepley } 7701de41b84cSMatthew G. Knepley numCIndices += dof; 7702de41b84cSMatthew G. Knepley } 7703de41b84cSMatthew G. Knepley for (f = 1; f < numFields; ++f) coffsets[f+1] += coffsets[f]; 7704de41b84cSMatthew G. Knepley /* Row indices */ 7705412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dmc, point, &ct);CHKERRQ(ierr); 7706412e9a14SMatthew G. Knepley { 7707012bc364SMatthew G. Knepley DMPlexTransform tr; 7708012bc364SMatthew G. Knepley DMPolytopeType *rct; 7709012bc364SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt, Nt; 7710012bc364SMatthew G. Knepley 7711012bc364SMatthew G. Knepley ierr = DMPlexTransformCreate(PETSC_COMM_SELF, &tr);CHKERRQ(ierr); 7712012bc364SMatthew G. Knepley ierr = DMPlexTransformSetType(tr, DMPLEXREFINEREGULAR);CHKERRQ(ierr); 7713012bc364SMatthew G. Knepley ierr = DMPlexTransformCellTransform(tr, ct, point, NULL, &Nt, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 7714012bc364SMatthew G. Knepley numSubcells = rsize[Nt-1]; 7715012bc364SMatthew G. Knepley ierr = DMPlexTransformDestroy(&tr);CHKERRQ(ierr); 7716412e9a14SMatthew G. Knepley } 771769291d52SBarry Smith ierr = DMGetWorkArray(dmf, maxFPoints*2*numSubcells, MPIU_INT, &ftotpoints);CHKERRQ(ierr); 7718de41b84cSMatthew G. Knepley for (r = 0, q = 0; r < numSubcells; ++r) { 7719de41b84cSMatthew G. Knepley /* TODO Map from coarse to fine cells */ 7720de41b84cSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dmf, point*numSubcells + r, PETSC_TRUE, &numFPoints, &fpoints);CHKERRQ(ierr); 7721de41b84cSMatthew G. Knepley /* Compress out points not in the section */ 7722de41b84cSMatthew G. Knepley ierr = PetscSectionGetChart(fsection, &pStart, &pEnd);CHKERRQ(ierr); 7723de41b84cSMatthew G. Knepley for (p = 0; p < numFPoints*2; p += 2) { 7724de41b84cSMatthew G. Knepley if ((fpoints[p] >= pStart) && (fpoints[p] < pEnd)) { 77254ca5e9f5SMatthew G. Knepley ierr = PetscSectionGetDof(fsection, fpoints[p], &dof);CHKERRQ(ierr); 77264ca5e9f5SMatthew G. Knepley if (!dof) continue; 77274ca5e9f5SMatthew G. Knepley for (s = 0; s < q; ++s) if (fpoints[p] == ftotpoints[s*2]) break; 77284ca5e9f5SMatthew G. Knepley if (s < q) continue; 7729de41b84cSMatthew G. Knepley ftotpoints[q*2] = fpoints[p]; 7730de41b84cSMatthew G. Knepley ftotpoints[q*2+1] = fpoints[p+1]; 7731de41b84cSMatthew G. Knepley ++q; 7732de41b84cSMatthew G. Knepley } 7733de41b84cSMatthew G. Knepley } 7734de41b84cSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dmf, point, PETSC_TRUE, &numFPoints, &fpoints);CHKERRQ(ierr); 7735de41b84cSMatthew G. Knepley } 7736de41b84cSMatthew G. Knepley numFPoints = q; 7737de41b84cSMatthew G. Knepley for (p = 0, numFIndices = 0; p < numFPoints*2; p += 2) { 7738de41b84cSMatthew G. Knepley PetscInt fdof; 7739de41b84cSMatthew G. Knepley 7740de41b84cSMatthew G. Knepley ierr = PetscSectionGetDof(fsection, ftotpoints[p], &dof);CHKERRQ(ierr); 77414ca5e9f5SMatthew G. Knepley if (!dof) continue; 7742de41b84cSMatthew G. Knepley for (f = 0; f < numFields; ++f) { 7743de41b84cSMatthew G. Knepley ierr = PetscSectionGetFieldDof(fsection, ftotpoints[p], f, &fdof);CHKERRQ(ierr); 7744de41b84cSMatthew G. Knepley foffsets[f+1] += fdof; 7745de41b84cSMatthew G. Knepley } 7746de41b84cSMatthew G. Knepley numFIndices += dof; 7747de41b84cSMatthew G. Knepley } 7748de41b84cSMatthew G. Knepley for (f = 1; f < numFields; ++f) foffsets[f+1] += foffsets[f]; 7749de41b84cSMatthew G. Knepley 77502c71b3e2SJacob Faibussowitsch PetscCheckFalse(numFields && foffsets[numFields] != numFIndices,PetscObjectComm((PetscObject)dmf), PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", foffsets[numFields], numFIndices); 77512c71b3e2SJacob Faibussowitsch PetscCheckFalse(numFields && coffsets[numFields] != numCIndices,PetscObjectComm((PetscObject)dmc), PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", coffsets[numFields], numCIndices); 775269291d52SBarry Smith ierr = DMGetWorkArray(dmf, numFIndices, MPIU_INT, &findices);CHKERRQ(ierr); 775369291d52SBarry Smith ierr = DMGetWorkArray(dmc, numCIndices, MPIU_INT, &cindices);CHKERRQ(ierr); 7754de41b84cSMatthew G. Knepley if (numFields) { 77554acb8e1eSToby Isaac const PetscInt **permsF[32] = {NULL}; 77564acb8e1eSToby Isaac const PetscInt **permsC[32] = {NULL}; 77574acb8e1eSToby Isaac 77584acb8e1eSToby Isaac for (f = 0; f < numFields; f++) { 77594acb8e1eSToby Isaac ierr = PetscSectionGetFieldPointSyms(fsection,f,numFPoints,ftotpoints,&permsF[f],NULL);CHKERRQ(ierr); 77604acb8e1eSToby Isaac ierr = PetscSectionGetFieldPointSyms(csection,f,numCPoints,cpoints,&permsC[f],NULL);CHKERRQ(ierr); 7761de41b84cSMatthew G. Knepley } 77624acb8e1eSToby Isaac for (p = 0; p < numFPoints; p++) { 77634acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalFSection, ftotpoints[2*p], &globalOff);CHKERRQ(ierr); 776436fa2b79SJed Brown ierr = DMPlexGetIndicesPointFields_Internal(fsection, PETSC_FALSE, ftotpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, foffsets, PETSC_FALSE, permsF, p, fclperm, findices);CHKERRQ(ierr); 77654acb8e1eSToby Isaac } 77664acb8e1eSToby Isaac for (p = 0; p < numCPoints; p++) { 77674acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalCSection, cpoints[2*p], &globalOff);CHKERRQ(ierr); 776836fa2b79SJed Brown ierr = DMPlexGetIndicesPointFields_Internal(csection, PETSC_FALSE, cpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, coffsets, PETSC_FALSE, permsC, p, cclperm, cindices);CHKERRQ(ierr); 77694acb8e1eSToby Isaac } 77704acb8e1eSToby Isaac for (f = 0; f < numFields; f++) { 77714acb8e1eSToby Isaac ierr = PetscSectionRestoreFieldPointSyms(fsection,f,numFPoints,ftotpoints,&permsF[f],NULL);CHKERRQ(ierr); 77724acb8e1eSToby Isaac ierr = PetscSectionRestoreFieldPointSyms(csection,f,numCPoints,cpoints,&permsC[f],NULL);CHKERRQ(ierr); 7773de41b84cSMatthew G. Knepley } 7774de41b84cSMatthew G. Knepley } else { 77754acb8e1eSToby Isaac const PetscInt **permsF = NULL; 77764acb8e1eSToby Isaac const PetscInt **permsC = NULL; 77774acb8e1eSToby Isaac 77784acb8e1eSToby Isaac ierr = PetscSectionGetPointSyms(fsection,numFPoints,ftotpoints,&permsF,NULL);CHKERRQ(ierr); 77794acb8e1eSToby Isaac ierr = PetscSectionGetPointSyms(csection,numCPoints,cpoints,&permsC,NULL);CHKERRQ(ierr); 77804acb8e1eSToby Isaac for (p = 0, off = 0; p < numFPoints; p++) { 77814acb8e1eSToby Isaac const PetscInt *perm = permsF ? permsF[p] : NULL; 77824acb8e1eSToby Isaac 77834acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalFSection, ftotpoints[2*p], &globalOff);CHKERRQ(ierr); 778436fa2b79SJed Brown ierr = DMPlexGetIndicesPoint_Internal(fsection, PETSC_FALSE, ftotpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, perm, fclperm, findices);CHKERRQ(ierr); 7785de41b84cSMatthew G. Knepley } 77864acb8e1eSToby Isaac for (p = 0, off = 0; p < numCPoints; p++) { 77874acb8e1eSToby Isaac const PetscInt *perm = permsC ? permsC[p] : NULL; 77884acb8e1eSToby Isaac 77894acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalCSection, cpoints[2*p], &globalOff);CHKERRQ(ierr); 779036fa2b79SJed Brown ierr = DMPlexGetIndicesPoint_Internal(csection, PETSC_FALSE, cpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, perm, cclperm, cindices);CHKERRQ(ierr); 7791de41b84cSMatthew G. Knepley } 77924acb8e1eSToby Isaac ierr = PetscSectionRestorePointSyms(fsection,numFPoints,ftotpoints,&permsF,NULL);CHKERRQ(ierr); 77934acb8e1eSToby Isaac ierr = PetscSectionRestorePointSyms(csection,numCPoints,cpoints,&permsC,NULL);CHKERRQ(ierr); 7794de41b84cSMatthew G. Knepley } 7795de41b84cSMatthew G. Knepley if (mesh->printSetValues) {ierr = DMPlexPrintMatSetValues(PETSC_VIEWER_STDOUT_SELF, A, point, numFIndices, findices, numCIndices, cindices, values);CHKERRQ(ierr);} 77964acb8e1eSToby Isaac /* TODO: flips */ 7797de41b84cSMatthew G. Knepley ierr = MatSetValues(A, numFIndices, findices, numCIndices, cindices, values, mode); 7798de41b84cSMatthew G. Knepley if (ierr) { 7799de41b84cSMatthew G. Knepley PetscMPIInt rank; 7800de41b84cSMatthew G. Knepley PetscErrorCode ierr2; 7801de41b84cSMatthew G. Knepley 780255b25c41SPierre Jolivet ierr2 = MPI_Comm_rank(PetscObjectComm((PetscObject)A), &rank);CHKERRMPI(ierr2); 7803e4b003c7SBarry Smith ierr2 = (*PetscErrorPrintf)("[%d]ERROR in DMPlexMatSetClosure\n", rank);CHKERRQ(ierr2); 7804de41b84cSMatthew G. Knepley ierr2 = DMPlexPrintMatSetValues(PETSC_VIEWER_STDERR_SELF, A, point, numFIndices, findices, numCIndices, cindices, values);CHKERRQ(ierr2); 780569291d52SBarry Smith ierr2 = DMRestoreWorkArray(dmf, numFIndices, MPIU_INT, &findices);CHKERRQ(ierr2); 780669291d52SBarry Smith ierr2 = DMRestoreWorkArray(dmc, numCIndices, MPIU_INT, &cindices);CHKERRQ(ierr2); 7807de41b84cSMatthew G. Knepley CHKERRQ(ierr); 7808de41b84cSMatthew G. Knepley } 780969291d52SBarry Smith ierr = DMRestoreWorkArray(dmf, numCPoints*2*4, MPIU_INT, &ftotpoints);CHKERRQ(ierr); 7810de41b84cSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dmc, point, PETSC_TRUE, &numCPoints, &cpoints);CHKERRQ(ierr); 781169291d52SBarry Smith ierr = DMRestoreWorkArray(dmf, numFIndices, MPIU_INT, &findices);CHKERRQ(ierr); 781269291d52SBarry Smith ierr = DMRestoreWorkArray(dmc, numCIndices, MPIU_INT, &cindices);CHKERRQ(ierr); 7813de41b84cSMatthew G. Knepley PetscFunctionReturn(0); 7814de41b84cSMatthew G. Knepley } 7815de41b84cSMatthew G. Knepley 78167c927364SMatthew G. Knepley PetscErrorCode DMPlexMatGetClosureIndicesRefined(DM dmf, PetscSection fsection, PetscSection globalFSection, DM dmc, PetscSection csection, PetscSection globalCSection, PetscInt point, PetscInt cindices[], PetscInt findices[]) 78177c927364SMatthew G. Knepley { 78187c927364SMatthew G. Knepley PetscInt *fpoints = NULL, *ftotpoints = NULL; 78197c927364SMatthew G. Knepley PetscInt *cpoints = NULL; 78207c927364SMatthew G. Knepley PetscInt foffsets[32], coffsets[32]; 782117c0192bSMatthew G. Knepley const PetscInt *fclperm = NULL, *cclperm = NULL; /* Closure permutations cannot work here */ 7822412e9a14SMatthew G. Knepley DMPolytopeType ct; 78237c927364SMatthew G. Knepley PetscInt numFields, numSubcells, maxFPoints, numFPoints, numCPoints, numFIndices, numCIndices, dof, off, globalOff, pStart, pEnd, p, q, r, s, f; 78247c927364SMatthew G. Knepley PetscErrorCode ierr; 78257c927364SMatthew G. Knepley 78267c927364SMatthew G. Knepley PetscFunctionBegin; 78277c927364SMatthew G. Knepley PetscValidHeaderSpecific(dmf, DM_CLASSID, 1); 78287c927364SMatthew G. Knepley PetscValidHeaderSpecific(dmc, DM_CLASSID, 4); 782992fd8e1eSJed Brown if (!fsection) {ierr = DMGetLocalSection(dmf, &fsection);CHKERRQ(ierr);} 78307c927364SMatthew G. Knepley PetscValidHeaderSpecific(fsection, PETSC_SECTION_CLASSID, 2); 783192fd8e1eSJed Brown if (!csection) {ierr = DMGetLocalSection(dmc, &csection);CHKERRQ(ierr);} 78327c927364SMatthew G. Knepley PetscValidHeaderSpecific(csection, PETSC_SECTION_CLASSID, 5); 7833e87a4003SBarry Smith if (!globalFSection) {ierr = DMGetGlobalSection(dmf, &globalFSection);CHKERRQ(ierr);} 78347c927364SMatthew G. Knepley PetscValidHeaderSpecific(globalFSection, PETSC_SECTION_CLASSID, 3); 7835e87a4003SBarry Smith if (!globalCSection) {ierr = DMGetGlobalSection(dmc, &globalCSection);CHKERRQ(ierr);} 78367c927364SMatthew G. Knepley PetscValidHeaderSpecific(globalCSection, PETSC_SECTION_CLASSID, 6); 78377c927364SMatthew G. Knepley ierr = PetscSectionGetNumFields(fsection, &numFields);CHKERRQ(ierr); 78382c71b3e2SJacob Faibussowitsch PetscCheckFalse(numFields > 31,PetscObjectComm((PetscObject)dmf), PETSC_ERR_ARG_OUTOFRANGE, "Number of fields %D limited to 31", numFields); 7839580bdb30SBarry Smith ierr = PetscArrayzero(foffsets, 32);CHKERRQ(ierr); 7840580bdb30SBarry Smith ierr = PetscArrayzero(coffsets, 32);CHKERRQ(ierr); 78417c927364SMatthew G. Knepley /* Column indices */ 78427c927364SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dmc, point, PETSC_TRUE, &numCPoints, &cpoints);CHKERRQ(ierr); 78437c927364SMatthew G. Knepley maxFPoints = numCPoints; 78447c927364SMatthew G. Knepley /* Compress out points not in the section */ 78457c927364SMatthew G. Knepley /* TODO: Squeeze out points with 0 dof as well */ 78467c927364SMatthew G. Knepley ierr = PetscSectionGetChart(csection, &pStart, &pEnd);CHKERRQ(ierr); 78477c927364SMatthew G. Knepley for (p = 0, q = 0; p < numCPoints*2; p += 2) { 78487c927364SMatthew G. Knepley if ((cpoints[p] >= pStart) && (cpoints[p] < pEnd)) { 78497c927364SMatthew G. Knepley cpoints[q*2] = cpoints[p]; 78507c927364SMatthew G. Knepley cpoints[q*2+1] = cpoints[p+1]; 78517c927364SMatthew G. Knepley ++q; 78527c927364SMatthew G. Knepley } 78537c927364SMatthew G. Knepley } 78547c927364SMatthew G. Knepley numCPoints = q; 78557c927364SMatthew G. Knepley for (p = 0, numCIndices = 0; p < numCPoints*2; p += 2) { 78567c927364SMatthew G. Knepley PetscInt fdof; 78577c927364SMatthew G. Knepley 78587c927364SMatthew G. Knepley ierr = PetscSectionGetDof(csection, cpoints[p], &dof);CHKERRQ(ierr); 78597c927364SMatthew G. Knepley if (!dof) continue; 78607c927364SMatthew G. Knepley for (f = 0; f < numFields; ++f) { 78617c927364SMatthew G. Knepley ierr = PetscSectionGetFieldDof(csection, cpoints[p], f, &fdof);CHKERRQ(ierr); 78627c927364SMatthew G. Knepley coffsets[f+1] += fdof; 78637c927364SMatthew G. Knepley } 78647c927364SMatthew G. Knepley numCIndices += dof; 78657c927364SMatthew G. Knepley } 78667c927364SMatthew G. Knepley for (f = 1; f < numFields; ++f) coffsets[f+1] += coffsets[f]; 78677c927364SMatthew G. Knepley /* Row indices */ 7868412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dmc, point, &ct);CHKERRQ(ierr); 7869412e9a14SMatthew G. Knepley { 7870012bc364SMatthew G. Knepley DMPlexTransform tr; 7871012bc364SMatthew G. Knepley DMPolytopeType *rct; 7872012bc364SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt, Nt; 7873012bc364SMatthew G. Knepley 7874012bc364SMatthew G. Knepley ierr = DMPlexTransformCreate(PETSC_COMM_SELF, &tr);CHKERRQ(ierr); 7875012bc364SMatthew G. Knepley ierr = DMPlexTransformSetType(tr, DMPLEXREFINEREGULAR);CHKERRQ(ierr); 7876012bc364SMatthew G. Knepley ierr = DMPlexTransformCellTransform(tr, ct, point, NULL, &Nt, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 7877012bc364SMatthew G. Knepley numSubcells = rsize[Nt-1]; 7878012bc364SMatthew G. Knepley ierr = DMPlexTransformDestroy(&tr);CHKERRQ(ierr); 7879412e9a14SMatthew G. Knepley } 788069291d52SBarry Smith ierr = DMGetWorkArray(dmf, maxFPoints*2*numSubcells, MPIU_INT, &ftotpoints);CHKERRQ(ierr); 78817c927364SMatthew G. Knepley for (r = 0, q = 0; r < numSubcells; ++r) { 78827c927364SMatthew G. Knepley /* TODO Map from coarse to fine cells */ 78837c927364SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dmf, point*numSubcells + r, PETSC_TRUE, &numFPoints, &fpoints);CHKERRQ(ierr); 78847c927364SMatthew G. Knepley /* Compress out points not in the section */ 78857c927364SMatthew G. Knepley ierr = PetscSectionGetChart(fsection, &pStart, &pEnd);CHKERRQ(ierr); 78867c927364SMatthew G. Knepley for (p = 0; p < numFPoints*2; p += 2) { 78877c927364SMatthew G. Knepley if ((fpoints[p] >= pStart) && (fpoints[p] < pEnd)) { 78887c927364SMatthew G. Knepley ierr = PetscSectionGetDof(fsection, fpoints[p], &dof);CHKERRQ(ierr); 78897c927364SMatthew G. Knepley if (!dof) continue; 78907c927364SMatthew G. Knepley for (s = 0; s < q; ++s) if (fpoints[p] == ftotpoints[s*2]) break; 78917c927364SMatthew G. Knepley if (s < q) continue; 78927c927364SMatthew G. Knepley ftotpoints[q*2] = fpoints[p]; 78937c927364SMatthew G. Knepley ftotpoints[q*2+1] = fpoints[p+1]; 78947c927364SMatthew G. Knepley ++q; 78957c927364SMatthew G. Knepley } 78967c927364SMatthew G. Knepley } 78977c927364SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dmf, point, PETSC_TRUE, &numFPoints, &fpoints);CHKERRQ(ierr); 78987c927364SMatthew G. Knepley } 78997c927364SMatthew G. Knepley numFPoints = q; 79007c927364SMatthew G. Knepley for (p = 0, numFIndices = 0; p < numFPoints*2; p += 2) { 79017c927364SMatthew G. Knepley PetscInt fdof; 79027c927364SMatthew G. Knepley 79037c927364SMatthew G. Knepley ierr = PetscSectionGetDof(fsection, ftotpoints[p], &dof);CHKERRQ(ierr); 79047c927364SMatthew G. Knepley if (!dof) continue; 79057c927364SMatthew G. Knepley for (f = 0; f < numFields; ++f) { 79067c927364SMatthew G. Knepley ierr = PetscSectionGetFieldDof(fsection, ftotpoints[p], f, &fdof);CHKERRQ(ierr); 79077c927364SMatthew G. Knepley foffsets[f+1] += fdof; 79087c927364SMatthew G. Knepley } 79097c927364SMatthew G. Knepley numFIndices += dof; 79107c927364SMatthew G. Knepley } 79117c927364SMatthew G. Knepley for (f = 1; f < numFields; ++f) foffsets[f+1] += foffsets[f]; 79127c927364SMatthew G. Knepley 79132c71b3e2SJacob Faibussowitsch PetscCheckFalse(numFields && foffsets[numFields] != numFIndices,PetscObjectComm((PetscObject)dmf), PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", foffsets[numFields], numFIndices); 79142c71b3e2SJacob Faibussowitsch PetscCheckFalse(numFields && coffsets[numFields] != numCIndices,PetscObjectComm((PetscObject)dmc), PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", coffsets[numFields], numCIndices); 79157c927364SMatthew G. Knepley if (numFields) { 79164acb8e1eSToby Isaac const PetscInt **permsF[32] = {NULL}; 79174acb8e1eSToby Isaac const PetscInt **permsC[32] = {NULL}; 79184acb8e1eSToby Isaac 79194acb8e1eSToby Isaac for (f = 0; f < numFields; f++) { 79204acb8e1eSToby Isaac ierr = PetscSectionGetFieldPointSyms(fsection,f,numFPoints,ftotpoints,&permsF[f],NULL);CHKERRQ(ierr); 79214acb8e1eSToby Isaac ierr = PetscSectionGetFieldPointSyms(csection,f,numCPoints,cpoints,&permsC[f],NULL);CHKERRQ(ierr); 79227c927364SMatthew G. Knepley } 79234acb8e1eSToby Isaac for (p = 0; p < numFPoints; p++) { 79244acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalFSection, ftotpoints[2*p], &globalOff);CHKERRQ(ierr); 792536fa2b79SJed Brown ierr = DMPlexGetIndicesPointFields_Internal(fsection, PETSC_FALSE, ftotpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, foffsets, PETSC_FALSE, permsF, p, fclperm, findices);CHKERRQ(ierr); 79264acb8e1eSToby Isaac } 79274acb8e1eSToby Isaac for (p = 0; p < numCPoints; p++) { 79284acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalCSection, cpoints[2*p], &globalOff);CHKERRQ(ierr); 792936fa2b79SJed Brown ierr = DMPlexGetIndicesPointFields_Internal(csection, PETSC_FALSE, cpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, coffsets, PETSC_FALSE, permsC, p, cclperm, cindices);CHKERRQ(ierr); 79304acb8e1eSToby Isaac } 79314acb8e1eSToby Isaac for (f = 0; f < numFields; f++) { 79324acb8e1eSToby Isaac ierr = PetscSectionRestoreFieldPointSyms(fsection,f,numFPoints,ftotpoints,&permsF[f],NULL);CHKERRQ(ierr); 79334acb8e1eSToby Isaac ierr = PetscSectionRestoreFieldPointSyms(csection,f,numCPoints,cpoints,&permsC[f],NULL);CHKERRQ(ierr); 79347c927364SMatthew G. Knepley } 79357c927364SMatthew G. Knepley } else { 79364acb8e1eSToby Isaac const PetscInt **permsF = NULL; 79374acb8e1eSToby Isaac const PetscInt **permsC = NULL; 79384acb8e1eSToby Isaac 79394acb8e1eSToby Isaac ierr = PetscSectionGetPointSyms(fsection,numFPoints,ftotpoints,&permsF,NULL);CHKERRQ(ierr); 79404acb8e1eSToby Isaac ierr = PetscSectionGetPointSyms(csection,numCPoints,cpoints,&permsC,NULL);CHKERRQ(ierr); 79414acb8e1eSToby Isaac for (p = 0, off = 0; p < numFPoints; p++) { 79424acb8e1eSToby Isaac const PetscInt *perm = permsF ? permsF[p] : NULL; 79434acb8e1eSToby Isaac 79444acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalFSection, ftotpoints[2*p], &globalOff);CHKERRQ(ierr); 794536fa2b79SJed Brown ierr = DMPlexGetIndicesPoint_Internal(fsection, PETSC_FALSE, ftotpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, perm, fclperm, findices);CHKERRQ(ierr); 79467c927364SMatthew G. Knepley } 79474acb8e1eSToby Isaac for (p = 0, off = 0; p < numCPoints; p++) { 79484acb8e1eSToby Isaac const PetscInt *perm = permsC ? permsC[p] : NULL; 79494acb8e1eSToby Isaac 79504acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalCSection, cpoints[2*p], &globalOff);CHKERRQ(ierr); 795136fa2b79SJed Brown ierr = DMPlexGetIndicesPoint_Internal(csection, PETSC_FALSE, cpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, perm, cclperm, cindices);CHKERRQ(ierr); 79527c927364SMatthew G. Knepley } 79534acb8e1eSToby Isaac ierr = PetscSectionRestorePointSyms(fsection,numFPoints,ftotpoints,&permsF,NULL);CHKERRQ(ierr); 79544acb8e1eSToby Isaac ierr = PetscSectionRestorePointSyms(csection,numCPoints,cpoints,&permsC,NULL);CHKERRQ(ierr); 79557c927364SMatthew G. Knepley } 795669291d52SBarry Smith ierr = DMRestoreWorkArray(dmf, numCPoints*2*4, MPIU_INT, &ftotpoints);CHKERRQ(ierr); 79577c927364SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dmc, point, PETSC_TRUE, &numCPoints, &cpoints);CHKERRQ(ierr); 79587c927364SMatthew G. Knepley PetscFunctionReturn(0); 79597c927364SMatthew G. Knepley } 79607c927364SMatthew G. Knepley 79617cd05799SMatthew G. Knepley /*@C 79627cd05799SMatthew G. Knepley DMPlexGetVTKCellHeight - Returns the height in the DAG used to determine which points are cells (normally 0) 79637cd05799SMatthew G. Knepley 79647cd05799SMatthew G. Knepley Input Parameter: 79657cd05799SMatthew G. Knepley . dm - The DMPlex object 79667cd05799SMatthew G. Knepley 79677cd05799SMatthew G. Knepley Output Parameter: 79687cd05799SMatthew G. Knepley . cellHeight - The height of a cell 79697cd05799SMatthew G. Knepley 79707cd05799SMatthew G. Knepley Level: developer 79717cd05799SMatthew G. Knepley 79727cd05799SMatthew G. Knepley .seealso DMPlexSetVTKCellHeight() 79737cd05799SMatthew G. Knepley @*/ 7974552f7358SJed Brown PetscErrorCode DMPlexGetVTKCellHeight(DM dm, PetscInt *cellHeight) 7975552f7358SJed Brown { 7976552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 7977552f7358SJed Brown 7978552f7358SJed Brown PetscFunctionBegin; 7979552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7980552f7358SJed Brown PetscValidPointer(cellHeight, 2); 7981552f7358SJed Brown *cellHeight = mesh->vtkCellHeight; 7982552f7358SJed Brown PetscFunctionReturn(0); 7983552f7358SJed Brown } 7984552f7358SJed Brown 79857cd05799SMatthew G. Knepley /*@C 79867cd05799SMatthew G. Knepley DMPlexSetVTKCellHeight - Sets the height in the DAG used to determine which points are cells (normally 0) 79877cd05799SMatthew G. Knepley 79887cd05799SMatthew G. Knepley Input Parameters: 79897cd05799SMatthew G. Knepley + dm - The DMPlex object 79907cd05799SMatthew G. Knepley - cellHeight - The height of a cell 79917cd05799SMatthew G. Knepley 79927cd05799SMatthew G. Knepley Level: developer 79937cd05799SMatthew G. Knepley 79947cd05799SMatthew G. Knepley .seealso DMPlexGetVTKCellHeight() 79957cd05799SMatthew G. Knepley @*/ 7996552f7358SJed Brown PetscErrorCode DMPlexSetVTKCellHeight(DM dm, PetscInt cellHeight) 7997552f7358SJed Brown { 7998552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 7999552f7358SJed Brown 8000552f7358SJed Brown PetscFunctionBegin; 8001552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8002552f7358SJed Brown mesh->vtkCellHeight = cellHeight; 8003552f7358SJed Brown PetscFunctionReturn(0); 8004552f7358SJed Brown } 8005552f7358SJed Brown 8006e6139122SMatthew G. Knepley /*@ 8007e6139122SMatthew G. Knepley DMPlexGetGhostCellStratum - Get the range of cells which are used to enforce FV boundary conditions 8008e6139122SMatthew G. Knepley 8009e6139122SMatthew G. Knepley Input Parameter: 8010e6139122SMatthew G. Knepley . dm - The DMPlex object 8011e6139122SMatthew G. Knepley 8012e6139122SMatthew G. Knepley Output Parameters: 80132a9f31c0SMatthew G. Knepley + gcStart - The first ghost cell, or NULL 80142a9f31c0SMatthew G. Knepley - gcEnd - The upper bound on ghost cells, or NULL 8015e6139122SMatthew G. Knepley 80162a9f31c0SMatthew G. Knepley Level: advanced 8017e6139122SMatthew G. Knepley 80188065b584SMatthew Knepley .seealso DMPlexConstructGhostCells(), DMPlexGetGhostCellStratum() 8019e6139122SMatthew G. Knepley @*/ 8020e6139122SMatthew G. Knepley PetscErrorCode DMPlexGetGhostCellStratum(DM dm, PetscInt *gcStart, PetscInt *gcEnd) 8021e6139122SMatthew G. Knepley { 8022412e9a14SMatthew G. Knepley DMLabel ctLabel; 8023e6139122SMatthew G. Knepley PetscErrorCode ierr; 8024e6139122SMatthew G. Knepley 8025e6139122SMatthew G. Knepley PetscFunctionBegin; 8026e6139122SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8027412e9a14SMatthew G. Knepley ierr = DMPlexGetCellTypeLabel(dm, &ctLabel);CHKERRQ(ierr); 8028412e9a14SMatthew G. Knepley ierr = DMLabelGetStratumBounds(ctLabel, DM_POLYTOPE_FV_GHOST, gcStart, gcEnd);CHKERRQ(ierr); 8029e6139122SMatthew G. Knepley PetscFunctionReturn(0); 8030e6139122SMatthew G. Knepley } 8031e6139122SMatthew G. Knepley 8032552f7358SJed Brown /* We can easily have a form that takes an IS instead */ 80339886b8cfSStefano Zampini PetscErrorCode DMPlexCreateNumbering_Plex(DM dm, PetscInt pStart, PetscInt pEnd, PetscInt shift, PetscInt *globalSize, PetscSF sf, IS *numbering) 8034552f7358SJed Brown { 8035552f7358SJed Brown PetscSection section, globalSection; 8036552f7358SJed Brown PetscInt *numbers, p; 8037552f7358SJed Brown PetscErrorCode ierr; 8038552f7358SJed Brown 8039552f7358SJed Brown PetscFunctionBegin; 804082f516ccSBarry Smith ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), §ion);CHKERRQ(ierr); 8041552f7358SJed Brown ierr = PetscSectionSetChart(section, pStart, pEnd);CHKERRQ(ierr); 8042552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 8043552f7358SJed Brown ierr = PetscSectionSetDof(section, p, 1);CHKERRQ(ierr); 8044552f7358SJed Brown } 8045552f7358SJed Brown ierr = PetscSectionSetUp(section);CHKERRQ(ierr); 804615b58121SMatthew G. Knepley ierr = PetscSectionCreateGlobalSection(section, sf, PETSC_FALSE, PETSC_FALSE, &globalSection);CHKERRQ(ierr); 8047854ce69bSBarry Smith ierr = PetscMalloc1(pEnd - pStart, &numbers);CHKERRQ(ierr); 8048552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 8049552f7358SJed Brown ierr = PetscSectionGetOffset(globalSection, p, &numbers[p-pStart]);CHKERRQ(ierr); 8050ef48cebcSMatthew G. Knepley if (numbers[p-pStart] < 0) numbers[p-pStart] -= shift; 8051ef48cebcSMatthew G. Knepley else numbers[p-pStart] += shift; 8052552f7358SJed Brown } 805382f516ccSBarry Smith ierr = ISCreateGeneral(PetscObjectComm((PetscObject) dm), pEnd - pStart, numbers, PETSC_OWN_POINTER, numbering);CHKERRQ(ierr); 8054ef48cebcSMatthew G. Knepley if (globalSize) { 8055ef48cebcSMatthew G. Knepley PetscLayout layout; 8056ef48cebcSMatthew G. Knepley ierr = PetscSectionGetPointLayout(PetscObjectComm((PetscObject) dm), globalSection, &layout);CHKERRQ(ierr); 8057ef48cebcSMatthew G. Knepley ierr = PetscLayoutGetSize(layout, globalSize);CHKERRQ(ierr); 8058ef48cebcSMatthew G. Knepley ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr); 8059ef48cebcSMatthew G. Knepley } 8060552f7358SJed Brown ierr = PetscSectionDestroy(§ion);CHKERRQ(ierr); 8061552f7358SJed Brown ierr = PetscSectionDestroy(&globalSection);CHKERRQ(ierr); 8062552f7358SJed Brown PetscFunctionReturn(0); 8063552f7358SJed Brown } 8064552f7358SJed Brown 806581ed3555SMatthew G. Knepley PetscErrorCode DMPlexCreateCellNumbering_Internal(DM dm, PetscBool includeHybrid, IS *globalCellNumbers) 8066552f7358SJed Brown { 8067412e9a14SMatthew G. Knepley PetscInt cellHeight, cStart, cEnd; 8068552f7358SJed Brown PetscErrorCode ierr; 8069552f7358SJed Brown 8070552f7358SJed Brown PetscFunctionBegin; 8071552f7358SJed Brown ierr = DMPlexGetVTKCellHeight(dm, &cellHeight);CHKERRQ(ierr); 8072412e9a14SMatthew G. Knepley if (includeHybrid) {ierr = DMPlexGetHeightStratum(dm, cellHeight, &cStart, &cEnd);CHKERRQ(ierr);} 8073412e9a14SMatthew G. Knepley else {ierr = DMPlexGetSimplexOrBoxCells(dm, cellHeight, &cStart, &cEnd);CHKERRQ(ierr);} 80749886b8cfSStefano Zampini ierr = DMPlexCreateNumbering_Plex(dm, cStart, cEnd, 0, NULL, dm->sf, globalCellNumbers);CHKERRQ(ierr); 807581ed3555SMatthew G. Knepley PetscFunctionReturn(0); 8076552f7358SJed Brown } 807781ed3555SMatthew G. Knepley 80788dab3259SMatthew G. Knepley /*@ 80797cd05799SMatthew G. Knepley DMPlexGetCellNumbering - Get a global cell numbering for all cells on this process 80807cd05799SMatthew G. Knepley 80817cd05799SMatthew G. Knepley Input Parameter: 80827cd05799SMatthew G. Knepley . dm - The DMPlex object 80837cd05799SMatthew G. Knepley 80847cd05799SMatthew G. Knepley Output Parameter: 80857cd05799SMatthew G. Knepley . globalCellNumbers - Global cell numbers for all cells on this process 80867cd05799SMatthew G. Knepley 80877cd05799SMatthew G. Knepley Level: developer 80887cd05799SMatthew G. Knepley 80897cd05799SMatthew G. Knepley .seealso DMPlexGetVertexNumbering() 80907cd05799SMatthew G. Knepley @*/ 809181ed3555SMatthew G. Knepley PetscErrorCode DMPlexGetCellNumbering(DM dm, IS *globalCellNumbers) 809281ed3555SMatthew G. Knepley { 809381ed3555SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 809481ed3555SMatthew G. Knepley PetscErrorCode ierr; 809581ed3555SMatthew G. Knepley 809681ed3555SMatthew G. Knepley PetscFunctionBegin; 809781ed3555SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 809881ed3555SMatthew G. Knepley if (!mesh->globalCellNumbers) {ierr = DMPlexCreateCellNumbering_Internal(dm, PETSC_FALSE, &mesh->globalCellNumbers);CHKERRQ(ierr);} 8099552f7358SJed Brown *globalCellNumbers = mesh->globalCellNumbers; 8100552f7358SJed Brown PetscFunctionReturn(0); 8101552f7358SJed Brown } 8102552f7358SJed Brown 810381ed3555SMatthew G. Knepley PetscErrorCode DMPlexCreateVertexNumbering_Internal(DM dm, PetscBool includeHybrid, IS *globalVertexNumbers) 810481ed3555SMatthew G. Knepley { 8105412e9a14SMatthew G. Knepley PetscInt vStart, vEnd; 810681ed3555SMatthew G. Knepley PetscErrorCode ierr; 810781ed3555SMatthew G. Knepley 810881ed3555SMatthew G. Knepley PetscFunctionBegin; 810981ed3555SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 811081ed3555SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 81119886b8cfSStefano Zampini ierr = DMPlexCreateNumbering_Plex(dm, vStart, vEnd, 0, NULL, dm->sf, globalVertexNumbers);CHKERRQ(ierr); 811281ed3555SMatthew G. Knepley PetscFunctionReturn(0); 811381ed3555SMatthew G. Knepley } 811481ed3555SMatthew G. Knepley 81158dab3259SMatthew G. Knepley /*@ 81166aa51ba9SJacob Faibussowitsch DMPlexGetVertexNumbering - Get a global vertex numbering for all vertices on this process 81177cd05799SMatthew G. Knepley 81187cd05799SMatthew G. Knepley Input Parameter: 81197cd05799SMatthew G. Knepley . dm - The DMPlex object 81207cd05799SMatthew G. Knepley 81217cd05799SMatthew G. Knepley Output Parameter: 81227cd05799SMatthew G. Knepley . globalVertexNumbers - Global vertex numbers for all vertices on this process 81237cd05799SMatthew G. Knepley 81247cd05799SMatthew G. Knepley Level: developer 81257cd05799SMatthew G. Knepley 81267cd05799SMatthew G. Knepley .seealso DMPlexGetCellNumbering() 81277cd05799SMatthew G. Knepley @*/ 8128552f7358SJed Brown PetscErrorCode DMPlexGetVertexNumbering(DM dm, IS *globalVertexNumbers) 8129552f7358SJed Brown { 8130552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 8131552f7358SJed Brown PetscErrorCode ierr; 8132552f7358SJed Brown 8133552f7358SJed Brown PetscFunctionBegin; 8134552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 813581ed3555SMatthew G. Knepley if (!mesh->globalVertexNumbers) {ierr = DMPlexCreateVertexNumbering_Internal(dm, PETSC_FALSE, &mesh->globalVertexNumbers);CHKERRQ(ierr);} 8136552f7358SJed Brown *globalVertexNumbers = mesh->globalVertexNumbers; 8137552f7358SJed Brown PetscFunctionReturn(0); 8138552f7358SJed Brown } 8139552f7358SJed Brown 81408dab3259SMatthew G. Knepley /*@ 81417cd05799SMatthew G. Knepley DMPlexCreatePointNumbering - Create a global numbering for all points on this process 81427cd05799SMatthew G. Knepley 81437cd05799SMatthew G. Knepley Input Parameter: 81447cd05799SMatthew G. Knepley . dm - The DMPlex object 81457cd05799SMatthew G. Knepley 81467cd05799SMatthew G. Knepley Output Parameter: 81477cd05799SMatthew G. Knepley . globalPointNumbers - Global numbers for all points on this process 81487cd05799SMatthew G. Knepley 81497cd05799SMatthew G. Knepley Level: developer 81507cd05799SMatthew G. Knepley 81517cd05799SMatthew G. Knepley .seealso DMPlexGetCellNumbering() 81527cd05799SMatthew G. Knepley @*/ 8153ef48cebcSMatthew G. Knepley PetscErrorCode DMPlexCreatePointNumbering(DM dm, IS *globalPointNumbers) 8154ef48cebcSMatthew G. Knepley { 8155ef48cebcSMatthew G. Knepley IS nums[4]; 8156862913ffSStefano Zampini PetscInt depths[4], gdepths[4], starts[4]; 8157ef48cebcSMatthew G. Knepley PetscInt depth, d, shift = 0; 8158ef48cebcSMatthew G. Knepley PetscErrorCode ierr; 8159ef48cebcSMatthew G. Knepley 8160ef48cebcSMatthew G. Knepley PetscFunctionBegin; 8161ef48cebcSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8162ef48cebcSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 81638abc87a0SMichael Lange /* For unstratified meshes use dim instead of depth */ 81648abc87a0SMichael Lange if (depth < 0) {ierr = DMGetDimension(dm, &depth);CHKERRQ(ierr);} 8165862913ffSStefano Zampini for (d = 0; d <= depth; ++d) { 8166862913ffSStefano Zampini PetscInt end; 8167862913ffSStefano Zampini 8168862913ffSStefano Zampini depths[d] = depth-d; 8169862913ffSStefano Zampini ierr = DMPlexGetDepthStratum(dm, depths[d], &starts[d], &end);CHKERRQ(ierr); 8170862913ffSStefano Zampini if (!(starts[d]-end)) { starts[d] = depths[d] = -1; } 8171862913ffSStefano Zampini } 8172862913ffSStefano Zampini ierr = PetscSortIntWithArray(depth+1, starts, depths);CHKERRQ(ierr); 8173820f2d46SBarry Smith ierr = MPIU_Allreduce(depths, gdepths, depth+1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject) dm));CHKERRMPI(ierr); 8174862913ffSStefano Zampini for (d = 0; d <= depth; ++d) { 81752c71b3e2SJacob Faibussowitsch PetscCheckFalse(starts[d] >= 0 && depths[d] != gdepths[d],PETSC_COMM_SELF,PETSC_ERR_PLIB,"Expected depth %D, found %D",depths[d],gdepths[d]); 8176862913ffSStefano Zampini } 8177ef48cebcSMatthew G. Knepley for (d = 0; d <= depth; ++d) { 8178ef48cebcSMatthew G. Knepley PetscInt pStart, pEnd, gsize; 8179ef48cebcSMatthew G. Knepley 8180862913ffSStefano Zampini ierr = DMPlexGetDepthStratum(dm, gdepths[d], &pStart, &pEnd);CHKERRQ(ierr); 81819886b8cfSStefano Zampini ierr = DMPlexCreateNumbering_Plex(dm, pStart, pEnd, shift, &gsize, dm->sf, &nums[d]);CHKERRQ(ierr); 8182ef48cebcSMatthew G. Knepley shift += gsize; 8183ef48cebcSMatthew G. Knepley } 8184302440fdSBarry Smith ierr = ISConcatenate(PetscObjectComm((PetscObject) dm), depth+1, nums, globalPointNumbers);CHKERRQ(ierr); 8185ef48cebcSMatthew G. Knepley for (d = 0; d <= depth; ++d) {ierr = ISDestroy(&nums[d]);CHKERRQ(ierr);} 8186ef48cebcSMatthew G. Knepley PetscFunctionReturn(0); 8187ef48cebcSMatthew G. Knepley } 8188ef48cebcSMatthew G. Knepley 818908a22f4bSMatthew G. Knepley /*@ 819008a22f4bSMatthew G. Knepley DMPlexCreateRankField - Create a cell field whose value is the rank of the owner 819108a22f4bSMatthew G. Knepley 819208a22f4bSMatthew G. Knepley Input Parameter: 819308a22f4bSMatthew G. Knepley . dm - The DMPlex object 819408a22f4bSMatthew G. Knepley 819508a22f4bSMatthew G. Knepley Output Parameter: 819608a22f4bSMatthew G. Knepley . ranks - The rank field 819708a22f4bSMatthew G. Knepley 819808a22f4bSMatthew G. Knepley Options Database Keys: 819908a22f4bSMatthew G. Knepley . -dm_partition_view - Adds the rank field into the DM output from -dm_view using the same viewer 820008a22f4bSMatthew G. Knepley 820108a22f4bSMatthew G. Knepley Level: intermediate 820208a22f4bSMatthew G. Knepley 820308a22f4bSMatthew G. Knepley .seealso: DMView() 820408a22f4bSMatthew G. Knepley @*/ 820508a22f4bSMatthew G. Knepley PetscErrorCode DMPlexCreateRankField(DM dm, Vec *ranks) 820608a22f4bSMatthew G. Knepley { 820708a22f4bSMatthew G. Knepley DM rdm; 820808a22f4bSMatthew G. Knepley PetscFE fe; 820908a22f4bSMatthew G. Knepley PetscScalar *r; 821008a22f4bSMatthew G. Knepley PetscMPIInt rank; 8211a55f9a55SMatthew G. Knepley DMPolytopeType ct; 821208a22f4bSMatthew G. Knepley PetscInt dim, cStart, cEnd, c; 8213a55f9a55SMatthew G. Knepley PetscBool simplex; 821408a22f4bSMatthew G. Knepley PetscErrorCode ierr; 821508a22f4bSMatthew G. Knepley 821608a22f4bSMatthew G. Knepley PetscFunctionBeginUser; 8217f95ace6aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8218f95ace6aSMatthew G. Knepley PetscValidPointer(ranks, 2); 8219ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject) dm), &rank);CHKERRMPI(ierr); 822008a22f4bSMatthew G. Knepley ierr = DMClone(dm, &rdm);CHKERRQ(ierr); 822108a22f4bSMatthew G. Knepley ierr = DMGetDimension(rdm, &dim);CHKERRQ(ierr); 8222a55f9a55SMatthew G. Knepley ierr = DMPlexGetHeightStratum(rdm, 0, &cStart, &cEnd);CHKERRQ(ierr); 8223a55f9a55SMatthew G. Knepley ierr = DMPlexGetCellType(dm, cStart, &ct);CHKERRQ(ierr); 8224a55f9a55SMatthew G. Knepley simplex = DMPolytopeTypeGetNumVertices(ct) == DMPolytopeTypeGetDim(ct)+1 ? PETSC_TRUE : PETSC_FALSE; 8225a55f9a55SMatthew G. Knepley ierr = PetscFECreateDefault(PETSC_COMM_SELF, dim, 1, simplex, "PETSc___rank_", -1, &fe);CHKERRQ(ierr); 822608a22f4bSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) fe, "rank");CHKERRQ(ierr); 8227e5e52638SMatthew G. Knepley ierr = DMSetField(rdm, 0, NULL, (PetscObject) fe);CHKERRQ(ierr); 822808a22f4bSMatthew G. Knepley ierr = PetscFEDestroy(&fe);CHKERRQ(ierr); 8229e5e52638SMatthew G. Knepley ierr = DMCreateDS(rdm);CHKERRQ(ierr); 823008a22f4bSMatthew G. Knepley ierr = DMCreateGlobalVector(rdm, ranks);CHKERRQ(ierr); 823108a22f4bSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) *ranks, "partition");CHKERRQ(ierr); 823208a22f4bSMatthew G. Knepley ierr = VecGetArray(*ranks, &r);CHKERRQ(ierr); 823308a22f4bSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 823408a22f4bSMatthew G. Knepley PetscScalar *lr; 823508a22f4bSMatthew G. Knepley 823608a22f4bSMatthew G. Knepley ierr = DMPlexPointGlobalRef(rdm, c, r, &lr);CHKERRQ(ierr); 823771f09efeSPierre Jolivet if (lr) *lr = rank; 823808a22f4bSMatthew G. Knepley } 823908a22f4bSMatthew G. Knepley ierr = VecRestoreArray(*ranks, &r);CHKERRQ(ierr); 824008a22f4bSMatthew G. Knepley ierr = DMDestroy(&rdm);CHKERRQ(ierr); 824108a22f4bSMatthew G. Knepley PetscFunctionReturn(0); 824208a22f4bSMatthew G. Knepley } 824308a22f4bSMatthew G. Knepley 8244ca8062c8SMatthew G. Knepley /*@ 824518e14f0cSMatthew G. Knepley DMPlexCreateLabelField - Create a cell field whose value is the label value for that cell 824618e14f0cSMatthew G. Knepley 824718e14f0cSMatthew G. Knepley Input Parameters: 824818e14f0cSMatthew G. Knepley + dm - The DMPlex 824918e14f0cSMatthew G. Knepley - label - The DMLabel 825018e14f0cSMatthew G. Knepley 825118e14f0cSMatthew G. Knepley Output Parameter: 825218e14f0cSMatthew G. Knepley . val - The label value field 825318e14f0cSMatthew G. Knepley 825418e14f0cSMatthew G. Knepley Options Database Keys: 825518e14f0cSMatthew G. Knepley . -dm_label_view - Adds the label value field into the DM output from -dm_view using the same viewer 825618e14f0cSMatthew G. Knepley 825718e14f0cSMatthew G. Knepley Level: intermediate 825818e14f0cSMatthew G. Knepley 825918e14f0cSMatthew G. Knepley .seealso: DMView() 826018e14f0cSMatthew G. Knepley @*/ 826118e14f0cSMatthew G. Knepley PetscErrorCode DMPlexCreateLabelField(DM dm, DMLabel label, Vec *val) 826218e14f0cSMatthew G. Knepley { 826318e14f0cSMatthew G. Knepley DM rdm; 826418e14f0cSMatthew G. Knepley PetscFE fe; 826518e14f0cSMatthew G. Knepley PetscScalar *v; 826618e14f0cSMatthew G. Knepley PetscInt dim, cStart, cEnd, c; 826718e14f0cSMatthew G. Knepley PetscErrorCode ierr; 826818e14f0cSMatthew G. Knepley 826918e14f0cSMatthew G. Knepley PetscFunctionBeginUser; 827018e14f0cSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 827118e14f0cSMatthew G. Knepley PetscValidPointer(label, 2); 827218e14f0cSMatthew G. Knepley PetscValidPointer(val, 3); 827318e14f0cSMatthew G. Knepley ierr = DMClone(dm, &rdm);CHKERRQ(ierr); 827418e14f0cSMatthew G. Knepley ierr = DMGetDimension(rdm, &dim);CHKERRQ(ierr); 827518e14f0cSMatthew G. Knepley ierr = PetscFECreateDefault(PetscObjectComm((PetscObject) rdm), dim, 1, PETSC_TRUE, "PETSc___label_value_", -1, &fe);CHKERRQ(ierr); 827618e14f0cSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) fe, "label_value");CHKERRQ(ierr); 8277e5e52638SMatthew G. Knepley ierr = DMSetField(rdm, 0, NULL, (PetscObject) fe);CHKERRQ(ierr); 827818e14f0cSMatthew G. Knepley ierr = PetscFEDestroy(&fe);CHKERRQ(ierr); 8279e5e52638SMatthew G. Knepley ierr = DMCreateDS(rdm);CHKERRQ(ierr); 828018e14f0cSMatthew G. Knepley ierr = DMPlexGetHeightStratum(rdm, 0, &cStart, &cEnd);CHKERRQ(ierr); 828118e14f0cSMatthew G. Knepley ierr = DMCreateGlobalVector(rdm, val);CHKERRQ(ierr); 8282effbd7cbSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) *val, "label_value");CHKERRQ(ierr); 828318e14f0cSMatthew G. Knepley ierr = VecGetArray(*val, &v);CHKERRQ(ierr); 828418e14f0cSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 828518e14f0cSMatthew G. Knepley PetscScalar *lv; 828618e14f0cSMatthew G. Knepley PetscInt cval; 828718e14f0cSMatthew G. Knepley 828818e14f0cSMatthew G. Knepley ierr = DMPlexPointGlobalRef(rdm, c, v, &lv);CHKERRQ(ierr); 828918e14f0cSMatthew G. Knepley ierr = DMLabelGetValue(label, c, &cval);CHKERRQ(ierr); 829018e14f0cSMatthew G. Knepley *lv = cval; 829118e14f0cSMatthew G. Knepley } 829218e14f0cSMatthew G. Knepley ierr = VecRestoreArray(*val, &v);CHKERRQ(ierr); 829318e14f0cSMatthew G. Knepley ierr = DMDestroy(&rdm);CHKERRQ(ierr); 829418e14f0cSMatthew G. Knepley PetscFunctionReturn(0); 829518e14f0cSMatthew G. Knepley } 829618e14f0cSMatthew G. Knepley 829718e14f0cSMatthew G. Knepley /*@ 8298ca8062c8SMatthew G. Knepley DMPlexCheckSymmetry - Check that the adjacency information in the mesh is symmetric. 8299ca8062c8SMatthew G. Knepley 830069916449SMatthew G. Knepley Input Parameter: 830169916449SMatthew G. Knepley . dm - The DMPlex object 8302ca8062c8SMatthew G. Knepley 830395eb5ee5SVaclav Hapla Notes: 830495eb5ee5SVaclav Hapla This is a useful diagnostic when creating meshes programmatically. 830595eb5ee5SVaclav Hapla 830695eb5ee5SVaclav Hapla For the complete list of DMPlexCheck* functions, see DMSetFromOptions(). 8307ca8062c8SMatthew G. Knepley 8308ca8062c8SMatthew G. Knepley Level: developer 8309ca8062c8SMatthew G. Knepley 831095eb5ee5SVaclav Hapla .seealso: DMCreate(), DMSetFromOptions() 8311ca8062c8SMatthew G. Knepley @*/ 8312ca8062c8SMatthew G. Knepley PetscErrorCode DMPlexCheckSymmetry(DM dm) 8313ca8062c8SMatthew G. Knepley { 8314ca8062c8SMatthew G. Knepley PetscSection coneSection, supportSection; 8315ca8062c8SMatthew G. Knepley const PetscInt *cone, *support; 8316ca8062c8SMatthew G. Knepley PetscInt coneSize, c, supportSize, s; 831757beb4faSStefano Zampini PetscInt pStart, pEnd, p, pp, csize, ssize; 831857beb4faSStefano Zampini PetscBool storagecheck = PETSC_TRUE; 8319ca8062c8SMatthew G. Knepley PetscErrorCode ierr; 8320ca8062c8SMatthew G. Knepley 8321ca8062c8SMatthew G. Knepley PetscFunctionBegin; 8322ca8062c8SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8323412e9a14SMatthew G. Knepley ierr = DMViewFromOptions(dm, NULL, "-sym_dm_view");CHKERRQ(ierr); 8324ca8062c8SMatthew G. Knepley ierr = DMPlexGetConeSection(dm, &coneSection);CHKERRQ(ierr); 8325ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupportSection(dm, &supportSection);CHKERRQ(ierr); 8326ca8062c8SMatthew G. Knepley /* Check that point p is found in the support of its cone points, and vice versa */ 8327ca8062c8SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 8328ca8062c8SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 8329ca8062c8SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, p, &coneSize);CHKERRQ(ierr); 8330ca8062c8SMatthew G. Knepley ierr = DMPlexGetCone(dm, p, &cone);CHKERRQ(ierr); 8331ca8062c8SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 833242e66dfaSMatthew G. Knepley PetscBool dup = PETSC_FALSE; 833342e66dfaSMatthew G. Knepley PetscInt d; 833442e66dfaSMatthew G. Knepley for (d = c-1; d >= 0; --d) { 833542e66dfaSMatthew G. Knepley if (cone[c] == cone[d]) {dup = PETSC_TRUE; break;} 833642e66dfaSMatthew G. Knepley } 8337ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, cone[c], &supportSize);CHKERRQ(ierr); 8338ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupport(dm, cone[c], &support);CHKERRQ(ierr); 8339ca8062c8SMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 8340ca8062c8SMatthew G. Knepley if (support[s] == p) break; 8341ca8062c8SMatthew G. Knepley } 834242e66dfaSMatthew G. Knepley if ((s >= supportSize) || (dup && (support[s+1] != p))) { 83438ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "p: %D cone: ", p);CHKERRQ(ierr); 8344ca8062c8SMatthew G. Knepley for (s = 0; s < coneSize; ++s) { 83458ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "%D, ", cone[s]);CHKERRQ(ierr); 8346ca8062c8SMatthew G. Knepley } 8347302440fdSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 83488ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "p: %D support: ", cone[c]);CHKERRQ(ierr); 8349ca8062c8SMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 83508ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "%D, ", support[s]);CHKERRQ(ierr); 8351ca8062c8SMatthew G. Knepley } 8352302440fdSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 83532c71b3e2SJacob Faibussowitsch PetscCheckFalse(dup,PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D not repeatedly found in support of repeated cone point %D", p, cone[c]); 835498921bdaSJacob Faibussowitsch else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D not found in support of cone point %D", p, cone[c]); 8355ca8062c8SMatthew G. Knepley } 835642e66dfaSMatthew G. Knepley } 835757beb4faSStefano Zampini ierr = DMPlexGetTreeParent(dm, p, &pp, NULL);CHKERRQ(ierr); 835857beb4faSStefano Zampini if (p != pp) { storagecheck = PETSC_FALSE; continue; } 8359ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, p, &supportSize);CHKERRQ(ierr); 8360ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupport(dm, p, &support);CHKERRQ(ierr); 8361ca8062c8SMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 8362ca8062c8SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 8363ca8062c8SMatthew G. Knepley ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 8364ca8062c8SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 836557beb4faSStefano Zampini ierr = DMPlexGetTreeParent(dm, cone[c], &pp, NULL);CHKERRQ(ierr); 836657beb4faSStefano Zampini if (cone[c] != pp) { c = 0; break; } 8367ca8062c8SMatthew G. Knepley if (cone[c] == p) break; 8368ca8062c8SMatthew G. Knepley } 8369ca8062c8SMatthew G. Knepley if (c >= coneSize) { 83708ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "p: %D support: ", p);CHKERRQ(ierr); 8371ca8062c8SMatthew G. Knepley for (c = 0; c < supportSize; ++c) { 83728ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "%D, ", support[c]);CHKERRQ(ierr); 8373ca8062c8SMatthew G. Knepley } 8374302440fdSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 83758ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "p: %D cone: ", support[s]);CHKERRQ(ierr); 8376ca8062c8SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 83778ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "%D, ", cone[c]);CHKERRQ(ierr); 8378ca8062c8SMatthew G. Knepley } 8379302440fdSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 838098921bdaSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D not found in cone of support point %D", p, support[s]); 8381ca8062c8SMatthew G. Knepley } 8382ca8062c8SMatthew G. Knepley } 8383ca8062c8SMatthew G. Knepley } 838457beb4faSStefano Zampini if (storagecheck) { 8385ca8062c8SMatthew G. Knepley ierr = PetscSectionGetStorageSize(coneSection, &csize);CHKERRQ(ierr); 8386ca8062c8SMatthew G. Knepley ierr = PetscSectionGetStorageSize(supportSection, &ssize);CHKERRQ(ierr); 83872c71b3e2SJacob Faibussowitsch PetscCheckFalse(csize != ssize,PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Total cone size %D != Total support size %D", csize, ssize); 838857beb4faSStefano Zampini } 8389ca8062c8SMatthew G. Knepley PetscFunctionReturn(0); 8390ca8062c8SMatthew G. Knepley } 8391ca8062c8SMatthew G. Knepley 8392412e9a14SMatthew G. Knepley /* 8393412e9a14SMatthew 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. 8394412e9a14SMatthew G. Knepley */ 8395412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellUnsplitVertices_Private(DM dm, PetscInt c, DMPolytopeType ct, PetscInt *unsplit) 8396412e9a14SMatthew G. Knepley { 8397412e9a14SMatthew G. Knepley DMPolytopeType cct; 8398412e9a14SMatthew G. Knepley PetscInt ptpoints[4]; 8399412e9a14SMatthew G. Knepley const PetscInt *cone, *ccone, *ptcone; 8400412e9a14SMatthew G. Knepley PetscInt coneSize, cp, cconeSize, ccp, npt = 0, pt; 8401412e9a14SMatthew G. Knepley PetscErrorCode ierr; 8402412e9a14SMatthew G. Knepley 8403412e9a14SMatthew G. Knepley PetscFunctionBegin; 8404412e9a14SMatthew G. Knepley *unsplit = 0; 8405412e9a14SMatthew G. Knepley switch (ct) { 8406b5a892a1SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 8407b5a892a1SMatthew G. Knepley ptpoints[npt++] = c; 8408b5a892a1SMatthew G. Knepley break; 8409412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 8410412e9a14SMatthew G. Knepley ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 8411412e9a14SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, c, &coneSize);CHKERRQ(ierr); 8412412e9a14SMatthew G. Knepley for (cp = 0; cp < coneSize; ++cp) { 8413412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, cone[cp], &cct);CHKERRQ(ierr); 8414412e9a14SMatthew G. Knepley if (cct == DM_POLYTOPE_POINT_PRISM_TENSOR) ptpoints[npt++] = cone[cp]; 8415412e9a14SMatthew G. Knepley } 8416412e9a14SMatthew G. Knepley break; 8417412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 8418412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 8419412e9a14SMatthew G. Knepley ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 8420412e9a14SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, c, &coneSize);CHKERRQ(ierr); 8421412e9a14SMatthew G. Knepley for (cp = 0; cp < coneSize; ++cp) { 8422412e9a14SMatthew G. Knepley ierr = DMPlexGetCone(dm, cone[cp], &ccone);CHKERRQ(ierr); 8423412e9a14SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, cone[cp], &cconeSize);CHKERRQ(ierr); 8424412e9a14SMatthew G. Knepley for (ccp = 0; ccp < cconeSize; ++ccp) { 8425412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, ccone[ccp], &cct);CHKERRQ(ierr); 8426412e9a14SMatthew G. Knepley if (cct == DM_POLYTOPE_POINT_PRISM_TENSOR) { 8427412e9a14SMatthew G. Knepley PetscInt p; 8428412e9a14SMatthew G. Knepley for (p = 0; p < npt; ++p) if (ptpoints[p] == ccone[ccp]) break; 8429412e9a14SMatthew G. Knepley if (p == npt) ptpoints[npt++] = ccone[ccp]; 8430412e9a14SMatthew G. Knepley } 8431412e9a14SMatthew G. Knepley } 8432412e9a14SMatthew G. Knepley } 8433412e9a14SMatthew G. Knepley break; 8434412e9a14SMatthew G. Knepley default: break; 8435412e9a14SMatthew G. Knepley } 8436412e9a14SMatthew G. Knepley for (pt = 0; pt < npt; ++pt) { 8437412e9a14SMatthew G. Knepley ierr = DMPlexGetCone(dm, ptpoints[pt], &ptcone);CHKERRQ(ierr); 8438412e9a14SMatthew G. Knepley if (ptcone[0] == ptcone[1]) ++(*unsplit); 8439412e9a14SMatthew G. Knepley } 8440412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 8441412e9a14SMatthew G. Knepley } 8442412e9a14SMatthew G. Knepley 8443ca8062c8SMatthew G. Knepley /*@ 8444ca8062c8SMatthew G. Knepley DMPlexCheckSkeleton - Check that each cell has the correct number of vertices 8445ca8062c8SMatthew G. Knepley 8446ca8062c8SMatthew G. Knepley Input Parameters: 8447ca8062c8SMatthew G. Knepley + dm - The DMPlex object 844858723a97SMatthew G. Knepley - cellHeight - Normally 0 8449ca8062c8SMatthew G. Knepley 845095eb5ee5SVaclav Hapla Notes: 845195eb5ee5SVaclav Hapla This is a useful diagnostic when creating meshes programmatically. 845225c50c26SVaclav Hapla Currently applicable only to homogeneous simplex or tensor meshes. 8453ca8062c8SMatthew G. Knepley 845495eb5ee5SVaclav Hapla For the complete list of DMPlexCheck* functions, see DMSetFromOptions(). 845595eb5ee5SVaclav Hapla 8456ca8062c8SMatthew G. Knepley Level: developer 8457ca8062c8SMatthew G. Knepley 845895eb5ee5SVaclav Hapla .seealso: DMCreate(), DMSetFromOptions() 8459ca8062c8SMatthew G. Knepley @*/ 846025c50c26SVaclav Hapla PetscErrorCode DMPlexCheckSkeleton(DM dm, PetscInt cellHeight) 8461ca8062c8SMatthew G. Knepley { 8462412e9a14SMatthew G. Knepley DMPlexInterpolatedFlag interp; 8463412e9a14SMatthew G. Knepley DMPolytopeType ct; 8464412e9a14SMatthew G. Knepley PetscInt vStart, vEnd, cStart, cEnd, c; 8465ca8062c8SMatthew G. Knepley PetscErrorCode ierr; 8466ca8062c8SMatthew G. Knepley 8467ca8062c8SMatthew G. Knepley PetscFunctionBegin; 8468ca8062c8SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8469412e9a14SMatthew G. Knepley ierr = DMPlexIsInterpolated(dm, &interp);CHKERRQ(ierr); 847025c50c26SVaclav Hapla ierr = DMPlexGetHeightStratum(dm, cellHeight, &cStart, &cEnd);CHKERRQ(ierr); 847158723a97SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 8472412e9a14SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 8473412e9a14SMatthew G. Knepley PetscInt *closure = NULL; 8474412e9a14SMatthew G. Knepley PetscInt coneSize, closureSize, cl, Nv = 0; 847558723a97SMatthew G. Knepley 8476412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, c, &ct);CHKERRQ(ierr); 84772c71b3e2SJacob Faibussowitsch PetscCheckFalse((PetscInt) ct < 0,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cell %D has no cell type", c); 8478412e9a14SMatthew G. Knepley if (ct == DM_POLYTOPE_UNKNOWN) continue; 8479412e9a14SMatthew G. Knepley if (interp == DMPLEX_INTERPOLATED_FULL) { 8480412e9a14SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, c, &coneSize);CHKERRQ(ierr); 84812c71b3e2SJacob 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)); 8482412e9a14SMatthew G. Knepley } 848358723a97SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 848458723a97SMatthew G. Knepley for (cl = 0; cl < closureSize*2; cl += 2) { 848558723a97SMatthew G. Knepley const PetscInt p = closure[cl]; 8486412e9a14SMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) ++Nv; 848758723a97SMatthew G. Knepley } 848858723a97SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 8489412e9a14SMatthew G. Knepley /* Special Case: Tensor faces with identified vertices */ 8490412e9a14SMatthew G. Knepley if (Nv < DMPolytopeTypeGetNumVertices(ct)) { 8491412e9a14SMatthew G. Knepley PetscInt unsplit; 849242363296SMatthew G. Knepley 8493412e9a14SMatthew G. Knepley ierr = DMPlexCellUnsplitVertices_Private(dm, c, ct, &unsplit);CHKERRQ(ierr); 8494412e9a14SMatthew G. Knepley if (Nv + unsplit == DMPolytopeTypeGetNumVertices(ct)) continue; 849542363296SMatthew G. Knepley } 84962c71b3e2SJacob 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)); 849742363296SMatthew G. Knepley } 8498ca8062c8SMatthew G. Knepley PetscFunctionReturn(0); 8499ca8062c8SMatthew G. Knepley } 85009bf0dad6SMatthew G. Knepley 85019bf0dad6SMatthew G. Knepley /*@ 85029bf0dad6SMatthew 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 85039bf0dad6SMatthew G. Knepley 8504899ea2b8SJacob Faibussowitsch Not Collective 8505899ea2b8SJacob Faibussowitsch 85069bf0dad6SMatthew G. Knepley Input Parameters: 85079bf0dad6SMatthew G. Knepley + dm - The DMPlex object 85089bf0dad6SMatthew G. Knepley - cellHeight - Normally 0 85099bf0dad6SMatthew G. Knepley 851045da879fSVaclav Hapla Notes: 851145da879fSVaclav Hapla This is a useful diagnostic when creating meshes programmatically. 851245da879fSVaclav Hapla This routine is only relevant for meshes that are fully interpolated across all ranks. 851345da879fSVaclav Hapla It will error out if a partially interpolated mesh is given on some rank. 851445da879fSVaclav Hapla It will do nothing for locally uninterpolated mesh (as there is nothing to check). 85159bf0dad6SMatthew G. Knepley 851695eb5ee5SVaclav Hapla For the complete list of DMPlexCheck* functions, see DMSetFromOptions(). 851795eb5ee5SVaclav Hapla 85189bf0dad6SMatthew G. Knepley Level: developer 85199bf0dad6SMatthew G. Knepley 852095eb5ee5SVaclav Hapla .seealso: DMCreate(), DMPlexGetVTKCellHeight(), DMSetFromOptions() 85219bf0dad6SMatthew G. Knepley @*/ 852225c50c26SVaclav Hapla PetscErrorCode DMPlexCheckFaces(DM dm, PetscInt cellHeight) 85239bf0dad6SMatthew G. Knepley { 8524ab91121cSMatthew G. Knepley PetscInt dim, depth, vStart, vEnd, cStart, cEnd, c, h; 85259bf0dad6SMatthew G. Knepley PetscErrorCode ierr; 8526899ea2b8SJacob Faibussowitsch DMPlexInterpolatedFlag interpEnum; 85279bf0dad6SMatthew G. Knepley 85289bf0dad6SMatthew G. Knepley PetscFunctionBegin; 85299bf0dad6SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8530899ea2b8SJacob Faibussowitsch ierr = DMPlexIsInterpolated(dm, &interpEnum);CHKERRQ(ierr); 853145da879fSVaclav Hapla if (interpEnum == DMPLEX_INTERPOLATED_NONE) PetscFunctionReturn(0); 853245da879fSVaclav Hapla if (interpEnum == DMPLEX_INTERPOLATED_PARTIAL) { 8533899ea2b8SJacob Faibussowitsch PetscMPIInt rank; 8534899ea2b8SJacob Faibussowitsch MPI_Comm comm; 8535899ea2b8SJacob Faibussowitsch 8536899ea2b8SJacob Faibussowitsch ierr = PetscObjectGetComm((PetscObject) dm, &comm);CHKERRQ(ierr); 8537ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 853898921bdaSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Mesh is only partially interpolated on rank %d, this is currently not supported", rank); 8539899ea2b8SJacob Faibussowitsch } 8540899ea2b8SJacob Faibussowitsch 8541c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 8542ab91121cSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 85439bf0dad6SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 8544ab91121cSMatthew G. Knepley for (h = cellHeight; h < PetscMin(depth, dim); ++h) { 85453554e41dSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, h, &cStart, &cEnd);CHKERRQ(ierr); 85463554e41dSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 8547412e9a14SMatthew G. Knepley const PetscInt *cone, *ornt, *faceSizes, *faces; 8548412e9a14SMatthew G. Knepley const DMPolytopeType *faceTypes; 8549ba2698f1SMatthew G. Knepley DMPolytopeType ct; 8550412e9a14SMatthew G. Knepley PetscInt numFaces, coneSize, f; 8551412e9a14SMatthew G. Knepley PetscInt *closure = NULL, closureSize, cl, numCorners = 0, fOff = 0, unsplit; 85529bf0dad6SMatthew G. Knepley 8553ba2698f1SMatthew G. Knepley ierr = DMPlexGetCellType(dm, c, &ct);CHKERRQ(ierr); 8554412e9a14SMatthew G. Knepley ierr = DMPlexCellUnsplitVertices_Private(dm, c, ct, &unsplit);CHKERRQ(ierr); 8555412e9a14SMatthew G. Knepley if (unsplit) continue; 85569bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, c, &coneSize);CHKERRQ(ierr); 85579bf0dad6SMatthew G. Knepley ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 85589bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 85599bf0dad6SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 85609bf0dad6SMatthew G. Knepley for (cl = 0; cl < closureSize*2; cl += 2) { 85619bf0dad6SMatthew G. Knepley const PetscInt p = closure[cl]; 85629bf0dad6SMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) closure[numCorners++] = p; 85639bf0dad6SMatthew G. Knepley } 8564412e9a14SMatthew G. Knepley ierr = DMPlexGetRawFaces_Internal(dm, ct, closure, &numFaces, &faceTypes, &faceSizes, &faces);CHKERRQ(ierr); 85652c71b3e2SJacob 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); 85669bf0dad6SMatthew G. Knepley for (f = 0; f < numFaces; ++f) { 8567d4961f80SStefano Zampini DMPolytopeType fct; 85689bf0dad6SMatthew G. Knepley PetscInt *fclosure = NULL, fclosureSize, cl, fnumCorners = 0, v; 85699bf0dad6SMatthew G. Knepley 8570d4961f80SStefano Zampini ierr = DMPlexGetCellType(dm, cone[f], &fct);CHKERRQ(ierr); 85719bf0dad6SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure_Internal(dm, cone[f], ornt[f], PETSC_TRUE, &fclosureSize, &fclosure);CHKERRQ(ierr); 85729bf0dad6SMatthew G. Knepley for (cl = 0; cl < fclosureSize*2; cl += 2) { 85739bf0dad6SMatthew G. Knepley const PetscInt p = fclosure[cl]; 85749bf0dad6SMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) fclosure[fnumCorners++] = p; 85759bf0dad6SMatthew G. Knepley } 85762c71b3e2SJacob 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]); 85779bf0dad6SMatthew G. Knepley for (v = 0; v < fnumCorners; ++v) { 8578b5a892a1SMatthew G. Knepley if (fclosure[v] != faces[fOff+v]) { 8579b5a892a1SMatthew G. Knepley PetscInt v1; 8580b5a892a1SMatthew G. Knepley 8581b5a892a1SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, "face closure:");CHKERRQ(ierr); 8582b5a892a1SMatthew G. Knepley for (v1 = 0; v1 < fnumCorners; ++v1) {ierr = PetscPrintf(PETSC_COMM_SELF, " %D", fclosure[v1]);CHKERRQ(ierr);} 8583b5a892a1SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, "\ncell face:");CHKERRQ(ierr); 8584b5a892a1SMatthew G. Knepley for (v1 = 0; v1 < fnumCorners; ++v1) {ierr = PetscPrintf(PETSC_COMM_SELF, " %D", faces[fOff+v1]);CHKERRQ(ierr);} 8585b5a892a1SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 858698921bdaSJacob 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]); 8587b5a892a1SMatthew G. Knepley } 85889bf0dad6SMatthew G. Knepley } 85899bf0dad6SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, cone[f], PETSC_TRUE, &fclosureSize, &fclosure);CHKERRQ(ierr); 8590412e9a14SMatthew G. Knepley fOff += faceSizes[f]; 85919bf0dad6SMatthew G. Knepley } 8592412e9a14SMatthew G. Knepley ierr = DMPlexRestoreRawFaces_Internal(dm, ct, closure, &numFaces, &faceTypes, &faceSizes, &faces);CHKERRQ(ierr); 85939bf0dad6SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 85949bf0dad6SMatthew G. Knepley } 85953554e41dSMatthew G. Knepley } 8596552f7358SJed Brown PetscFunctionReturn(0); 8597552f7358SJed Brown } 85983913d7c8SMatthew G. Knepley 8599bb6a34a8SMatthew G. Knepley /*@ 8600bb6a34a8SMatthew G. Knepley DMPlexCheckGeometry - Check the geometry of mesh cells 8601bb6a34a8SMatthew G. Knepley 8602bb6a34a8SMatthew G. Knepley Input Parameter: 8603bb6a34a8SMatthew G. Knepley . dm - The DMPlex object 8604bb6a34a8SMatthew G. Knepley 860595eb5ee5SVaclav Hapla Notes: 860695eb5ee5SVaclav Hapla This is a useful diagnostic when creating meshes programmatically. 860795eb5ee5SVaclav Hapla 860895eb5ee5SVaclav Hapla For the complete list of DMPlexCheck* functions, see DMSetFromOptions(). 8609bb6a34a8SMatthew G. Knepley 8610bb6a34a8SMatthew G. Knepley Level: developer 8611bb6a34a8SMatthew G. Knepley 861295eb5ee5SVaclav Hapla .seealso: DMCreate(), DMSetFromOptions() 8613bb6a34a8SMatthew G. Knepley @*/ 8614bb6a34a8SMatthew G. Knepley PetscErrorCode DMPlexCheckGeometry(DM dm) 8615bb6a34a8SMatthew G. Knepley { 8616a2a9e04cSMatthew G. Knepley Vec coordinates; 8617bb6a34a8SMatthew G. Knepley PetscReal detJ, J[9], refVol = 1.0; 8618bb6a34a8SMatthew G. Knepley PetscReal vol; 8619412e9a14SMatthew G. Knepley PetscBool periodic; 862051a74b61SMatthew G. Knepley PetscInt dim, depth, dE, d, cStart, cEnd, c; 8621bb6a34a8SMatthew G. Knepley PetscErrorCode ierr; 8622bb6a34a8SMatthew G. Knepley 8623bb6a34a8SMatthew G. Knepley PetscFunctionBegin; 8624bb6a34a8SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 862551a74b61SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dE);CHKERRQ(ierr); 862651a74b61SMatthew G. Knepley if (dim != dE) PetscFunctionReturn(0); 8627bb6a34a8SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 8628412e9a14SMatthew G. Knepley ierr = DMGetPeriodicity(dm, &periodic, NULL, NULL, NULL);CHKERRQ(ierr); 8629bb6a34a8SMatthew G. Knepley for (d = 0; d < dim; ++d) refVol *= 2.0; 8630bb6a34a8SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 8631a2a9e04cSMatthew G. Knepley /* Make sure local coordinates are created, because that step is collective */ 8632a2a9e04cSMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 8633412e9a14SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 8634412e9a14SMatthew G. Knepley DMPolytopeType ct; 8635412e9a14SMatthew G. Knepley PetscInt unsplit; 8636412e9a14SMatthew G. Knepley PetscBool ignoreZeroVol = PETSC_FALSE; 8637412e9a14SMatthew G. Knepley 8638412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, c, &ct);CHKERRQ(ierr); 8639412e9a14SMatthew G. Knepley switch (ct) { 8640412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 8641412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 8642412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 8643412e9a14SMatthew G. Knepley ignoreZeroVol = PETSC_TRUE; break; 8644412e9a14SMatthew G. Knepley default: break; 8645412e9a14SMatthew G. Knepley } 8646412e9a14SMatthew G. Knepley switch (ct) { 8647412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: 8648412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 8649412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 8650a2a9e04cSMatthew G. Knepley case DM_POLYTOPE_PYRAMID: 8651412e9a14SMatthew G. Knepley continue; 8652412e9a14SMatthew G. Knepley default: break; 8653412e9a14SMatthew G. Knepley } 8654412e9a14SMatthew G. Knepley ierr = DMPlexCellUnsplitVertices_Private(dm, c, ct, &unsplit);CHKERRQ(ierr); 8655412e9a14SMatthew G. Knepley if (unsplit) continue; 8656bb6a34a8SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFEM(dm, c, NULL, NULL, J, NULL, &detJ);CHKERRQ(ierr); 86572c71b3e2SJacob 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); 86587d3de750SJacob Faibussowitsch ierr = PetscInfo(dm, "Cell %D FEM Volume %g\n", c, (double) detJ*refVol);CHKERRQ(ierr); 8659412e9a14SMatthew G. Knepley if (depth > 1 && !periodic) { 8660bb6a34a8SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFVM(dm, c, &vol, NULL, NULL);CHKERRQ(ierr); 86612c71b3e2SJacob 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); 86627d3de750SJacob Faibussowitsch ierr = PetscInfo(dm, "Cell %D FVM Volume %g\n", c, (double) vol);CHKERRQ(ierr); 8663bb6a34a8SMatthew G. Knepley } 8664bb6a34a8SMatthew G. Knepley } 8665bb6a34a8SMatthew G. Knepley PetscFunctionReturn(0); 8666bb6a34a8SMatthew G. Knepley } 8667bb6a34a8SMatthew G. Knepley 866803da9461SVaclav Hapla /*@ 8669e83a0d2dSVaclav Hapla DMPlexCheckPointSF - Check that several necessary conditions are met for the point SF of this plex. 867003da9461SVaclav Hapla 867103da9461SVaclav Hapla Input Parameters: 867203da9461SVaclav Hapla . dm - The DMPlex object 867303da9461SVaclav Hapla 8674e83a0d2dSVaclav Hapla Notes: 8675e83a0d2dSVaclav Hapla This is mainly intended for debugging/testing purposes. 86768918e3e2SVaclav Hapla It currently checks only meshes with no partition overlapping. 867703da9461SVaclav Hapla 867895eb5ee5SVaclav Hapla For the complete list of DMPlexCheck* functions, see DMSetFromOptions(). 867995eb5ee5SVaclav Hapla 868003da9461SVaclav Hapla Level: developer 868103da9461SVaclav Hapla 868295eb5ee5SVaclav Hapla .seealso: DMGetPointSF(), DMSetFromOptions() 868303da9461SVaclav Hapla @*/ 868403da9461SVaclav Hapla PetscErrorCode DMPlexCheckPointSF(DM dm) 868503da9461SVaclav Hapla { 8686f0cfc026SVaclav Hapla PetscSF pointSF; 8687f5869d18SMatthew G. Knepley PetscInt cellHeight, cStart, cEnd, l, nleaves, nroots, overlap; 8688f5869d18SMatthew G. Knepley const PetscInt *locals, *rootdegree; 8689f0cfc026SVaclav Hapla PetscBool distributed; 869003da9461SVaclav Hapla PetscErrorCode ierr; 869103da9461SVaclav Hapla 869203da9461SVaclav Hapla PetscFunctionBegin; 869303da9461SVaclav Hapla PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8694f0cfc026SVaclav Hapla ierr = DMGetPointSF(dm, &pointSF);CHKERRQ(ierr); 8695f0cfc026SVaclav Hapla ierr = DMPlexIsDistributed(dm, &distributed);CHKERRQ(ierr); 8696f0cfc026SVaclav Hapla if (!distributed) PetscFunctionReturn(0); 8697f0cfc026SVaclav Hapla ierr = DMPlexGetOverlap(dm, &overlap);CHKERRQ(ierr); 8698f0cfc026SVaclav Hapla if (overlap) { 86991e1ea65dSPierre Jolivet ierr = PetscPrintf(PetscObjectComm((PetscObject)dm), "Warning: DMPlexCheckPointSF() is currently not implemented for meshes with partition overlapping");CHKERRQ(ierr); 87008918e3e2SVaclav Hapla PetscFunctionReturn(0); 87018918e3e2SVaclav Hapla } 87022c71b3e2SJacob Faibussowitsch PetscCheckFalse(!pointSF,PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "This DMPlex is distributed but does not have PointSF attached"); 8703f0cfc026SVaclav Hapla ierr = PetscSFGetGraph(pointSF, &nroots, &nleaves, &locals, NULL);CHKERRQ(ierr); 87042c71b3e2SJacob Faibussowitsch PetscCheckFalse(nroots < 0,PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "This DMPlex is distributed but its PointSF has no graph set"); 8705f5869d18SMatthew G. Knepley ierr = PetscSFComputeDegreeBegin(pointSF, &rootdegree);CHKERRQ(ierr); 8706f5869d18SMatthew G. Knepley ierr = PetscSFComputeDegreeEnd(pointSF, &rootdegree);CHKERRQ(ierr); 870703da9461SVaclav Hapla 8708ece87651SVaclav Hapla /* 1) check there are no faces in 2D, cells in 3D, in interface */ 8709f5869d18SMatthew G. Knepley ierr = DMPlexGetVTKCellHeight(dm, &cellHeight);CHKERRQ(ierr); 8710f5869d18SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, cellHeight, &cStart, &cEnd);CHKERRQ(ierr); 8711f5869d18SMatthew G. Knepley for (l = 0; l < nleaves; ++l) { 8712f5869d18SMatthew G. Knepley const PetscInt point = locals[l]; 8713f5869d18SMatthew G. Knepley 87142c71b3e2SJacob Faibussowitsch PetscCheckFalse(point >= cStart && point < cEnd,PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point SF contains %D which is a cell", point); 871503da9461SVaclav Hapla } 8716ece87651SVaclav Hapla 8717f5869d18SMatthew G. Knepley /* 2) if some point is in interface, then all its cone points must be also in interface (either as leaves or roots) */ 8718f5869d18SMatthew G. Knepley for (l = 0; l < nleaves; ++l) { 8719f5869d18SMatthew G. Knepley const PetscInt point = locals[l]; 8720f5869d18SMatthew G. Knepley const PetscInt *cone; 8721f5869d18SMatthew G. Knepley PetscInt coneSize, c, idx; 8722f5869d18SMatthew G. Knepley 8723f5869d18SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, point, &coneSize);CHKERRQ(ierr); 8724f5869d18SMatthew G. Knepley ierr = DMPlexGetCone(dm, point, &cone);CHKERRQ(ierr); 8725f5869d18SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 8726f5869d18SMatthew G. Knepley if (!rootdegree[cone[c]]) { 8727f5869d18SMatthew G. Knepley ierr = PetscFindInt(cone[c], nleaves, locals, &idx);CHKERRQ(ierr); 87282c71b3e2SJacob Faibussowitsch PetscCheckFalse(idx < 0,PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point SF contains %D but not %D from its cone", point, cone[c]); 8729f5869d18SMatthew G. Knepley } 8730f5869d18SMatthew G. Knepley } 8731ece87651SVaclav Hapla } 873203da9461SVaclav Hapla PetscFunctionReturn(0); 873303da9461SVaclav Hapla } 873403da9461SVaclav Hapla 8735b5a892a1SMatthew G. Knepley PetscErrorCode DMPlexCheckAll_Internal(DM dm, PetscInt cellHeight) 8736b5a892a1SMatthew G. Knepley { 8737b5a892a1SMatthew G. Knepley PetscErrorCode ierr; 8738b5a892a1SMatthew G. Knepley 8739b5a892a1SMatthew G. Knepley PetscFunctionBegin; 8740b5a892a1SMatthew G. Knepley ierr = DMPlexCheckSymmetry(dm);CHKERRQ(ierr); 8741b5a892a1SMatthew G. Knepley ierr = DMPlexCheckSkeleton(dm, cellHeight);CHKERRQ(ierr); 8742b5a892a1SMatthew G. Knepley ierr = DMPlexCheckFaces(dm, cellHeight);CHKERRQ(ierr); 8743b5a892a1SMatthew G. Knepley ierr = DMPlexCheckGeometry(dm);CHKERRQ(ierr); 8744b5a892a1SMatthew G. Knepley ierr = DMPlexCheckPointSF(dm);CHKERRQ(ierr); 8745b5a892a1SMatthew G. Knepley ierr = DMPlexCheckInterfaceCones(dm);CHKERRQ(ierr); 8746b5a892a1SMatthew G. Knepley PetscFunctionReturn(0); 8747b5a892a1SMatthew G. Knepley } 8748b5a892a1SMatthew G. Knepley 8749068a5610SStefano Zampini typedef struct cell_stats 8750068a5610SStefano Zampini { 8751068a5610SStefano Zampini PetscReal min, max, sum, squaresum; 8752068a5610SStefano Zampini PetscInt count; 8753068a5610SStefano Zampini } cell_stats_t; 8754068a5610SStefano Zampini 875525befc3bSSatish Balay static void MPIAPI cell_stats_reduce(void *a, void *b, int * len, MPI_Datatype *datatype) 8756068a5610SStefano Zampini { 8757068a5610SStefano Zampini PetscInt i, N = *len; 8758068a5610SStefano Zampini 8759068a5610SStefano Zampini for (i = 0; i < N; i++) { 8760068a5610SStefano Zampini cell_stats_t *A = (cell_stats_t *) a; 8761068a5610SStefano Zampini cell_stats_t *B = (cell_stats_t *) b; 8762068a5610SStefano Zampini 8763068a5610SStefano Zampini B->min = PetscMin(A->min,B->min); 8764068a5610SStefano Zampini B->max = PetscMax(A->max,B->max); 8765068a5610SStefano Zampini B->sum += A->sum; 8766068a5610SStefano Zampini B->squaresum += A->squaresum; 8767068a5610SStefano Zampini B->count += A->count; 8768068a5610SStefano Zampini } 8769068a5610SStefano Zampini } 8770068a5610SStefano Zampini 8771068a5610SStefano Zampini /*@ 877243fa8764SMatthew G. Knepley DMPlexCheckCellShape - Checks the Jacobian of the mapping from reference to real cells and computes some minimal statistics. 8773068a5610SStefano Zampini 87748261a58bSMatthew G. Knepley Collective on dm 87758261a58bSMatthew G. Knepley 8776068a5610SStefano Zampini Input Parameters: 8777068a5610SStefano Zampini + dm - The DMPlex object 877843fa8764SMatthew G. Knepley . output - If true, statistics will be displayed on stdout 877943fa8764SMatthew G. Knepley - condLimit - Display all cells above this condition number, or PETSC_DETERMINE for no cell output 8780068a5610SStefano Zampini 878195eb5ee5SVaclav Hapla Notes: 878295eb5ee5SVaclav Hapla This is mainly intended for debugging/testing purposes. 878395eb5ee5SVaclav Hapla 878495eb5ee5SVaclav Hapla For the complete list of DMPlexCheck* functions, see DMSetFromOptions(). 8785068a5610SStefano Zampini 8786068a5610SStefano Zampini Level: developer 8787068a5610SStefano Zampini 8788f108dbd7SJacob Faibussowitsch .seealso: DMSetFromOptions(), DMPlexComputeOrthogonalQuality() 8789068a5610SStefano Zampini @*/ 879043fa8764SMatthew G. Knepley PetscErrorCode DMPlexCheckCellShape(DM dm, PetscBool output, PetscReal condLimit) 8791068a5610SStefano Zampini { 8792068a5610SStefano Zampini DM dmCoarse; 879343fa8764SMatthew G. Knepley cell_stats_t stats, globalStats; 879443fa8764SMatthew G. Knepley MPI_Comm comm = PetscObjectComm((PetscObject)dm); 879543fa8764SMatthew G. Knepley PetscReal *J, *invJ, min = 0, max = 0, mean = 0, stdev = 0; 879643fa8764SMatthew G. Knepley PetscReal limit = condLimit > 0 ? condLimit : PETSC_MAX_REAL; 8797412e9a14SMatthew G. Knepley PetscInt cdim, cStart, cEnd, c, eStart, eEnd, count = 0; 879843fa8764SMatthew G. Knepley PetscMPIInt rank,size; 8799068a5610SStefano Zampini PetscErrorCode ierr; 8800068a5610SStefano Zampini 8801068a5610SStefano Zampini PetscFunctionBegin; 8802068a5610SStefano Zampini PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8803068a5610SStefano Zampini stats.min = PETSC_MAX_REAL; 8804068a5610SStefano Zampini stats.max = PETSC_MIN_REAL; 8805068a5610SStefano Zampini stats.sum = stats.squaresum = 0.; 8806068a5610SStefano Zampini stats.count = 0; 8807068a5610SStefano Zampini 8808ffc4695bSBarry Smith ierr = MPI_Comm_size(comm, &size);CHKERRMPI(ierr); 8809ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 881043fa8764SMatthew G. Knepley ierr = DMGetCoordinateDim(dm,&cdim);CHKERRQ(ierr); 881143fa8764SMatthew G. Knepley ierr = PetscMalloc2(PetscSqr(cdim), &J, PetscSqr(cdim), &invJ);CHKERRQ(ierr); 8812412e9a14SMatthew G. Knepley ierr = DMPlexGetSimplexOrBoxCells(dm,0,&cStart,&cEnd);CHKERRQ(ierr); 881343fa8764SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm,1,&eStart,&eEnd);CHKERRQ(ierr); 8814412e9a14SMatthew G. Knepley for (c = cStart; c < cEnd; c++) { 8815068a5610SStefano Zampini PetscInt i; 8816068a5610SStefano Zampini PetscReal frobJ = 0., frobInvJ = 0., cond2, cond, detJ; 8817068a5610SStefano Zampini 8818068a5610SStefano Zampini ierr = DMPlexComputeCellGeometryAffineFEM(dm,c,NULL,J,invJ,&detJ);CHKERRQ(ierr); 88192c71b3e2SJacob Faibussowitsch PetscCheckFalse(detJ < 0.0,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Mesh cell %D is inverted", c); 882043fa8764SMatthew G. Knepley for (i = 0; i < PetscSqr(cdim); ++i) { 8821068a5610SStefano Zampini frobJ += J[i] * J[i]; 8822068a5610SStefano Zampini frobInvJ += invJ[i] * invJ[i]; 8823068a5610SStefano Zampini } 8824068a5610SStefano Zampini cond2 = frobJ * frobInvJ; 8825068a5610SStefano Zampini cond = PetscSqrtReal(cond2); 8826068a5610SStefano Zampini 8827068a5610SStefano Zampini stats.min = PetscMin(stats.min,cond); 8828068a5610SStefano Zampini stats.max = PetscMax(stats.max,cond); 8829068a5610SStefano Zampini stats.sum += cond; 8830068a5610SStefano Zampini stats.squaresum += cond2; 8831068a5610SStefano Zampini stats.count++; 88328261a58bSMatthew G. Knepley if (output && cond > limit) { 883343fa8764SMatthew G. Knepley PetscSection coordSection; 883443fa8764SMatthew G. Knepley Vec coordsLocal; 883543fa8764SMatthew G. Knepley PetscScalar *coords = NULL; 883643fa8764SMatthew G. Knepley PetscInt Nv, d, clSize, cl, *closure = NULL; 883743fa8764SMatthew G. Knepley 883843fa8764SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordsLocal);CHKERRQ(ierr); 883943fa8764SMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 884043fa8764SMatthew G. Knepley ierr = DMPlexVecGetClosure(dm, coordSection, coordsLocal, c, &Nv, &coords);CHKERRQ(ierr); 8841087ef6b2SMatthew G. Knepley ierr = PetscSynchronizedPrintf(comm, "[%d] Cell %D cond %g\n", rank, c, (double) cond);CHKERRQ(ierr); 884243fa8764SMatthew G. Knepley for (i = 0; i < Nv/cdim; ++i) { 884343fa8764SMatthew G. Knepley ierr = PetscSynchronizedPrintf(comm, " Vertex %D: (", i);CHKERRQ(ierr); 884443fa8764SMatthew G. Knepley for (d = 0; d < cdim; ++d) { 884543fa8764SMatthew G. Knepley if (d > 0) {ierr = PetscSynchronizedPrintf(comm, ", ");CHKERRQ(ierr);} 884648afe810SSatish Balay ierr = PetscSynchronizedPrintf(comm, "%g", (double) PetscRealPart(coords[i*cdim+d]));CHKERRQ(ierr); 884743fa8764SMatthew G. Knepley } 884843fa8764SMatthew G. Knepley ierr = PetscSynchronizedPrintf(comm, ")\n");CHKERRQ(ierr); 884943fa8764SMatthew G. Knepley } 885043fa8764SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &clSize, &closure);CHKERRQ(ierr); 885143fa8764SMatthew G. Knepley for (cl = 0; cl < clSize*2; cl += 2) { 885243fa8764SMatthew G. Knepley const PetscInt edge = closure[cl]; 885343fa8764SMatthew G. Knepley 885443fa8764SMatthew G. Knepley if ((edge >= eStart) && (edge < eEnd)) { 885543fa8764SMatthew G. Knepley PetscReal len; 885643fa8764SMatthew G. Knepley 885743fa8764SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFVM(dm, edge, &len, NULL, NULL);CHKERRQ(ierr); 8858087ef6b2SMatthew G. Knepley ierr = PetscSynchronizedPrintf(comm, " Edge %D: length %g\n", edge, (double) len);CHKERRQ(ierr); 885943fa8764SMatthew G. Knepley } 886043fa8764SMatthew G. Knepley } 886143fa8764SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &clSize, &closure);CHKERRQ(ierr); 886243fa8764SMatthew G. Knepley ierr = DMPlexVecRestoreClosure(dm, coordSection, coordsLocal, c, &Nv, &coords);CHKERRQ(ierr); 886343fa8764SMatthew G. Knepley } 8864068a5610SStefano Zampini } 88658261a58bSMatthew G. Knepley if (output) {ierr = PetscSynchronizedFlush(comm, NULL);CHKERRQ(ierr);} 8866068a5610SStefano Zampini 8867068a5610SStefano Zampini if (size > 1) { 8868068a5610SStefano Zampini PetscMPIInt blockLengths[2] = {4,1}; 8869068a5610SStefano Zampini MPI_Aint blockOffsets[2] = {offsetof(cell_stats_t,min),offsetof(cell_stats_t,count)}; 8870068a5610SStefano Zampini MPI_Datatype blockTypes[2] = {MPIU_REAL,MPIU_INT}, statType; 8871068a5610SStefano Zampini MPI_Op statReduce; 8872068a5610SStefano Zampini 8873ffc4695bSBarry Smith ierr = MPI_Type_create_struct(2,blockLengths,blockOffsets,blockTypes,&statType);CHKERRMPI(ierr); 8874ffc4695bSBarry Smith ierr = MPI_Type_commit(&statType);CHKERRMPI(ierr); 8875ffc4695bSBarry Smith ierr = MPI_Op_create(cell_stats_reduce, PETSC_TRUE, &statReduce);CHKERRMPI(ierr); 8876ffc4695bSBarry Smith ierr = MPI_Reduce(&stats,&globalStats,1,statType,statReduce,0,comm);CHKERRMPI(ierr); 8877ffc4695bSBarry Smith ierr = MPI_Op_free(&statReduce);CHKERRMPI(ierr); 8878ffc4695bSBarry Smith ierr = MPI_Type_free(&statType);CHKERRMPI(ierr); 8879068a5610SStefano Zampini } else { 8880580bdb30SBarry Smith ierr = PetscArraycpy(&globalStats,&stats,1);CHKERRQ(ierr); 8881068a5610SStefano Zampini } 8882dd400576SPatrick Sanan if (rank == 0) { 8883068a5610SStefano Zampini count = globalStats.count; 8884068a5610SStefano Zampini min = globalStats.min; 8885068a5610SStefano Zampini max = globalStats.max; 8886068a5610SStefano Zampini mean = globalStats.sum / globalStats.count; 8887068a5610SStefano Zampini stdev = globalStats.count > 1 ? PetscSqrtReal(PetscMax((globalStats.squaresum - globalStats.count * mean * mean) / (globalStats.count - 1),0)) : 0.0; 8888068a5610SStefano Zampini } 8889068a5610SStefano Zampini 8890068a5610SStefano Zampini if (output) { 8891068a5610SStefano 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); 8892068a5610SStefano Zampini } 8893068a5610SStefano Zampini ierr = PetscFree2(J,invJ);CHKERRQ(ierr); 8894068a5610SStefano Zampini 8895068a5610SStefano Zampini ierr = DMGetCoarseDM(dm,&dmCoarse);CHKERRQ(ierr); 8896068a5610SStefano Zampini if (dmCoarse) { 8897068a5610SStefano Zampini PetscBool isplex; 8898068a5610SStefano Zampini 8899068a5610SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)dmCoarse,DMPLEX,&isplex);CHKERRQ(ierr); 8900068a5610SStefano Zampini if (isplex) { 890143fa8764SMatthew G. Knepley ierr = DMPlexCheckCellShape(dmCoarse,output,condLimit);CHKERRQ(ierr); 8902068a5610SStefano Zampini } 8903068a5610SStefano Zampini } 8904068a5610SStefano Zampini PetscFunctionReturn(0); 8905068a5610SStefano Zampini } 8906068a5610SStefano Zampini 8907f108dbd7SJacob Faibussowitsch /*@ 8908f108dbd7SJacob Faibussowitsch DMPlexComputeOrthogonalQuality - Compute cell-wise orthogonal quality mesh statistic. Optionally tags all cells with 8909f108dbd7SJacob Faibussowitsch orthogonal quality below given tolerance. 8910f108dbd7SJacob Faibussowitsch 89116ed19f2fSJacob Faibussowitsch Collective on dm 8912f108dbd7SJacob Faibussowitsch 8913f108dbd7SJacob Faibussowitsch Input Parameters: 8914f108dbd7SJacob Faibussowitsch + dm - The DMPlex object 8915f108dbd7SJacob Faibussowitsch . fv - Optional PetscFV object for pre-computed cell/face centroid information 8916f108dbd7SJacob Faibussowitsch - atol - [0, 1] Absolute tolerance for tagging cells. 8917f108dbd7SJacob Faibussowitsch 8918f108dbd7SJacob Faibussowitsch Output Parameters: 8919f108dbd7SJacob Faibussowitsch + OrthQual - Vec containing orthogonal quality per cell 8920f108dbd7SJacob Faibussowitsch - OrthQualLabel - DMLabel tagging cells below atol with DM_ADAPT_REFINE 8921f108dbd7SJacob Faibussowitsch 8922f108dbd7SJacob Faibussowitsch Options Database Keys: 8923f108dbd7SJacob Faibussowitsch + -dm_plex_orthogonal_quality_label_view - view OrthQualLabel if label is requested. Currently only PETSCVIEWERASCII is 8924f108dbd7SJacob Faibussowitsch supported. 8925f108dbd7SJacob Faibussowitsch - -dm_plex_orthogonal_quality_vec_view - view OrthQual vector. 8926f108dbd7SJacob Faibussowitsch 8927f108dbd7SJacob Faibussowitsch Notes: 8928f108dbd7SJacob Faibussowitsch Orthogonal quality is given by the following formula: 8929f108dbd7SJacob Faibussowitsch 8930f108dbd7SJacob Faibussowitsch \min \left[ \frac{A_i \cdot f_i}{\|A_i\| \|f_i\|} , \frac{A_i \cdot c_i}{\|A_i\| \|c_i\|} \right] 8931f108dbd7SJacob Faibussowitsch 8932f108dbd7SJacob 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 8933f108dbd7SJacob Faibussowitsch is the vector from the current cells centroid to the centroid of its i'th neighbor (which shares a face with the 8934f108dbd7SJacob Faibussowitsch current cell). This computes the vector similarity between each cell face and its corresponding neighbor centroid by 8935f108dbd7SJacob Faibussowitsch calculating the cosine of the angle between these vectors. 8936f108dbd7SJacob Faibussowitsch 8937f108dbd7SJacob Faibussowitsch Orthogonal quality ranges from 1 (best) to 0 (worst). 8938f108dbd7SJacob Faibussowitsch 8939f108dbd7SJacob Faibussowitsch This routine is mainly useful for FVM, however is not restricted to only FVM. The PetscFV object is optionally used to check for 8940f108dbd7SJacob Faibussowitsch pre-computed FVM cell data, but if it is not passed in then this data will be computed. 8941f108dbd7SJacob Faibussowitsch 8942f108dbd7SJacob Faibussowitsch Cells are tagged if they have an orthogonal quality less than or equal to the absolute tolerance. 8943f108dbd7SJacob Faibussowitsch 8944f108dbd7SJacob Faibussowitsch Level: intermediate 8945f108dbd7SJacob Faibussowitsch 8946f108dbd7SJacob Faibussowitsch .seealso: DMPlexCheckCellShape(), DMCreateLabel() 8947f108dbd7SJacob Faibussowitsch @*/ 8948f108dbd7SJacob Faibussowitsch PetscErrorCode DMPlexComputeOrthogonalQuality(DM dm, PetscFV fv, PetscReal atol, Vec *OrthQual, DMLabel *OrthQualLabel) 8949f108dbd7SJacob Faibussowitsch { 89506ed19f2fSJacob Faibussowitsch PetscInt nc, cellHeight, cStart, cEnd, cell, cellIter = 0; 89516ed19f2fSJacob Faibussowitsch PetscInt *idx; 89526ed19f2fSJacob Faibussowitsch PetscScalar *oqVals; 8953f108dbd7SJacob Faibussowitsch const PetscScalar *cellGeomArr, *faceGeomArr; 89546ed19f2fSJacob Faibussowitsch PetscReal *ci, *fi, *Ai; 8955f108dbd7SJacob Faibussowitsch MPI_Comm comm; 8956f108dbd7SJacob Faibussowitsch Vec cellgeom, facegeom; 8957f108dbd7SJacob Faibussowitsch DM dmFace, dmCell; 8958f108dbd7SJacob Faibussowitsch IS glob; 8959f108dbd7SJacob Faibussowitsch ISLocalToGlobalMapping ltog; 8960f108dbd7SJacob Faibussowitsch PetscViewer vwr; 8961f108dbd7SJacob Faibussowitsch PetscErrorCode ierr; 8962f108dbd7SJacob Faibussowitsch 8963f108dbd7SJacob Faibussowitsch PetscFunctionBegin; 8964f108dbd7SJacob Faibussowitsch PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 89656ed19f2fSJacob Faibussowitsch if (fv) {PetscValidHeaderSpecific(fv, PETSCFV_CLASSID, 2);} 8966f108dbd7SJacob Faibussowitsch PetscValidPointer(OrthQual, 4); 89672c71b3e2SJacob Faibussowitsch PetscAssertFalse(atol < 0.0 || atol > 1.0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %g not in [0,1]",(double)atol); 8968f108dbd7SJacob Faibussowitsch ierr = PetscObjectGetComm((PetscObject) dm, &comm);CHKERRQ(ierr); 8969f108dbd7SJacob Faibussowitsch ierr = DMGetDimension(dm, &nc);CHKERRQ(ierr); 89702c71b3e2SJacob Faibussowitsch PetscCheckFalse(nc < 2,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "DM must have dimension >= 2 (current %D)", nc); 89716ed19f2fSJacob Faibussowitsch { 89726ed19f2fSJacob Faibussowitsch DMPlexInterpolatedFlag interpFlag; 89736ed19f2fSJacob Faibussowitsch 8974f108dbd7SJacob Faibussowitsch ierr = DMPlexIsInterpolated(dm, &interpFlag);CHKERRQ(ierr); 8975f108dbd7SJacob Faibussowitsch if (interpFlag != DMPLEX_INTERPOLATED_FULL) { 8976f108dbd7SJacob Faibussowitsch PetscMPIInt rank; 8977f108dbd7SJacob Faibussowitsch 8978ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 897998921bdaSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "DM must be fully interpolated, DM on rank %d is not fully interpolated", rank); 8980f108dbd7SJacob Faibussowitsch } 89816ed19f2fSJacob Faibussowitsch } 8982f108dbd7SJacob Faibussowitsch if (OrthQualLabel) { 8983f108dbd7SJacob Faibussowitsch PetscValidPointer(OrthQualLabel, 5); 8984f108dbd7SJacob Faibussowitsch ierr = DMCreateLabel(dm, "Orthogonal_Quality");CHKERRQ(ierr); 8985f108dbd7SJacob Faibussowitsch ierr = DMGetLabel(dm, "Orthogonal_Quality", OrthQualLabel);CHKERRQ(ierr); 89866ed19f2fSJacob Faibussowitsch } else {*OrthQualLabel = NULL;} 8987f108dbd7SJacob Faibussowitsch ierr = DMPlexGetVTKCellHeight(dm, &cellHeight);CHKERRQ(ierr); 8988f108dbd7SJacob Faibussowitsch ierr = DMPlexGetHeightStratum(dm, cellHeight, &cStart, &cEnd);CHKERRQ(ierr); 8989f108dbd7SJacob Faibussowitsch ierr = DMPlexCreateCellNumbering_Internal(dm, PETSC_TRUE, &glob);CHKERRQ(ierr); 8990f108dbd7SJacob Faibussowitsch ierr = ISLocalToGlobalMappingCreateIS(glob, <og);CHKERRQ(ierr); 8991f108dbd7SJacob Faibussowitsch ierr = ISLocalToGlobalMappingSetType(ltog, ISLOCALTOGLOBALMAPPINGHASH);CHKERRQ(ierr); 8992f108dbd7SJacob Faibussowitsch ierr = VecCreate(comm, OrthQual);CHKERRQ(ierr); 8993f108dbd7SJacob Faibussowitsch ierr = VecSetType(*OrthQual, VECSTANDARD);CHKERRQ(ierr); 8994f108dbd7SJacob Faibussowitsch ierr = VecSetSizes(*OrthQual, cEnd-cStart, PETSC_DETERMINE);CHKERRQ(ierr); 8995f108dbd7SJacob Faibussowitsch ierr = VecSetLocalToGlobalMapping(*OrthQual, ltog);CHKERRQ(ierr); 8996f108dbd7SJacob Faibussowitsch ierr = VecSetUp(*OrthQual);CHKERRQ(ierr); 8997f108dbd7SJacob Faibussowitsch ierr = ISDestroy(&glob);CHKERRQ(ierr); 8998f108dbd7SJacob Faibussowitsch ierr = ISLocalToGlobalMappingDestroy(<og);CHKERRQ(ierr); 8999f108dbd7SJacob Faibussowitsch ierr = DMPlexGetDataFVM(dm, fv, &cellgeom, &facegeom, NULL);CHKERRQ(ierr); 9000f108dbd7SJacob Faibussowitsch ierr = VecGetArrayRead(cellgeom, &cellGeomArr);CHKERRQ(ierr); 9001f108dbd7SJacob Faibussowitsch ierr = VecGetArrayRead(facegeom, &faceGeomArr);CHKERRQ(ierr); 9002f108dbd7SJacob Faibussowitsch ierr = VecGetDM(cellgeom, &dmCell);CHKERRQ(ierr); 9003f108dbd7SJacob Faibussowitsch ierr = VecGetDM(facegeom, &dmFace);CHKERRQ(ierr); 90046ed19f2fSJacob Faibussowitsch ierr = PetscMalloc5(cEnd-cStart, &idx, cEnd-cStart, &oqVals, nc, &ci, nc, &fi, nc, &Ai);CHKERRQ(ierr); 90056ed19f2fSJacob Faibussowitsch for (cell = cStart; cell < cEnd; cellIter++,cell++) { 90066ed19f2fSJacob Faibussowitsch PetscInt cellneigh, cellneighiter = 0, adjSize = PETSC_DETERMINE; 9007f108dbd7SJacob Faibussowitsch PetscInt cellarr[2], *adj = NULL; 9008f108dbd7SJacob Faibussowitsch PetscScalar *cArr, *fArr; 9009898cd552SSatish Balay PetscReal minvalc = 1.0, minvalf = 1.0; 9010f108dbd7SJacob Faibussowitsch PetscFVCellGeom *cg; 9011f108dbd7SJacob Faibussowitsch 90126ed19f2fSJacob Faibussowitsch idx[cellIter] = cell-cStart; 9013f108dbd7SJacob Faibussowitsch cellarr[0] = cell; 9014f108dbd7SJacob Faibussowitsch /* Make indexing into cellGeom easier */ 9015f108dbd7SJacob Faibussowitsch ierr = DMPlexPointLocalRead(dmCell, cell, cellGeomArr, &cg);CHKERRQ(ierr); 9016f108dbd7SJacob Faibussowitsch ierr = DMPlexGetAdjacency_Internal(dm, cell, PETSC_TRUE, PETSC_FALSE, PETSC_FALSE, &adjSize, &adj);CHKERRQ(ierr); 9017f108dbd7SJacob Faibussowitsch /* Technically 1 too big, but easier than fiddling with empty adjacency array */ 9018f108dbd7SJacob Faibussowitsch ierr = PetscCalloc2(adjSize, &cArr, adjSize, &fArr);CHKERRQ(ierr); 90196ed19f2fSJacob Faibussowitsch for (cellneigh = 0; cellneigh < adjSize; cellneighiter++,cellneigh++) { 90206ed19f2fSJacob Faibussowitsch PetscInt i; 90216ed19f2fSJacob Faibussowitsch const PetscInt neigh = adj[cellneigh]; 9022f108dbd7SJacob Faibussowitsch PetscReal normci = 0, normfi = 0, normai = 0; 9023f108dbd7SJacob Faibussowitsch PetscFVCellGeom *cgneigh; 9024f108dbd7SJacob Faibussowitsch PetscFVFaceGeom *fg; 9025f108dbd7SJacob Faibussowitsch 9026f108dbd7SJacob Faibussowitsch /* Don't count ourselves in the neighbor list */ 9027f108dbd7SJacob Faibussowitsch if (neigh == cell) continue; 9028f108dbd7SJacob Faibussowitsch ierr = DMPlexPointLocalRead(dmCell, neigh, cellGeomArr, &cgneigh);CHKERRQ(ierr); 9029f108dbd7SJacob Faibussowitsch cellarr[1] = neigh; 90306ed19f2fSJacob Faibussowitsch { 90316ed19f2fSJacob Faibussowitsch PetscInt numcovpts; 90326ed19f2fSJacob Faibussowitsch const PetscInt *covpts; 90336ed19f2fSJacob Faibussowitsch 9034f108dbd7SJacob Faibussowitsch ierr = DMPlexGetMeet(dm, 2, cellarr, &numcovpts, &covpts);CHKERRQ(ierr); 9035f108dbd7SJacob Faibussowitsch ierr = DMPlexPointLocalRead(dmFace, covpts[0], faceGeomArr, &fg);CHKERRQ(ierr); 9036f108dbd7SJacob Faibussowitsch ierr = DMPlexRestoreMeet(dm, 2, cellarr, &numcovpts, &covpts);CHKERRQ(ierr); 90376ed19f2fSJacob Faibussowitsch } 9038f108dbd7SJacob Faibussowitsch 9039f108dbd7SJacob Faibussowitsch /* Compute c_i, f_i and their norms */ 9040f108dbd7SJacob Faibussowitsch for (i = 0; i < nc; i++) { 9041f108dbd7SJacob Faibussowitsch ci[i] = cgneigh->centroid[i] - cg->centroid[i]; 9042f108dbd7SJacob Faibussowitsch fi[i] = fg->centroid[i] - cg->centroid[i]; 9043f108dbd7SJacob Faibussowitsch Ai[i] = fg->normal[i]; 9044addd1e01SJunchao Zhang normci += PetscPowReal(ci[i], 2); 9045addd1e01SJunchao Zhang normfi += PetscPowReal(fi[i], 2); 9046addd1e01SJunchao Zhang normai += PetscPowReal(Ai[i], 2); 9047f108dbd7SJacob Faibussowitsch } 9048addd1e01SJunchao Zhang normci = PetscSqrtReal(normci); 9049addd1e01SJunchao Zhang normfi = PetscSqrtReal(normfi); 9050addd1e01SJunchao Zhang normai = PetscSqrtReal(normai); 9051f108dbd7SJacob Faibussowitsch 9052f108dbd7SJacob Faibussowitsch /* Normalize and compute for each face-cell-normal pair */ 9053f108dbd7SJacob Faibussowitsch for (i = 0; i < nc; i++) { 9054f108dbd7SJacob Faibussowitsch ci[i] = ci[i]/normci; 9055f108dbd7SJacob Faibussowitsch fi[i] = fi[i]/normfi; 9056f108dbd7SJacob Faibussowitsch Ai[i] = Ai[i]/normai; 9057f108dbd7SJacob Faibussowitsch /* PetscAbs because I don't know if normals are guaranteed to point out */ 9058f108dbd7SJacob Faibussowitsch cArr[cellneighiter] += PetscAbs(Ai[i]*ci[i]); 9059f108dbd7SJacob Faibussowitsch fArr[cellneighiter] += PetscAbs(Ai[i]*fi[i]); 9060f108dbd7SJacob Faibussowitsch } 9061f108dbd7SJacob Faibussowitsch if (PetscRealPart(cArr[cellneighiter]) < minvalc) { 9062f108dbd7SJacob Faibussowitsch minvalc = PetscRealPart(cArr[cellneighiter]); 9063f108dbd7SJacob Faibussowitsch } 9064f108dbd7SJacob Faibussowitsch if (PetscRealPart(fArr[cellneighiter]) < minvalf) { 9065f108dbd7SJacob Faibussowitsch minvalf = PetscRealPart(fArr[cellneighiter]); 9066f108dbd7SJacob Faibussowitsch } 9067f108dbd7SJacob Faibussowitsch } 9068f108dbd7SJacob Faibussowitsch ierr = PetscFree(adj);CHKERRQ(ierr); 9069f108dbd7SJacob Faibussowitsch ierr = PetscFree2(cArr, fArr);CHKERRQ(ierr); 9070f108dbd7SJacob Faibussowitsch /* Defer to cell if they're equal */ 90716ed19f2fSJacob Faibussowitsch oqVals[cellIter] = PetscMin(minvalf, minvalc); 9072f108dbd7SJacob Faibussowitsch if (OrthQualLabel) { 90736ed19f2fSJacob Faibussowitsch if (PetscRealPart(oqVals[cellIter]) <= atol) {ierr = DMLabelSetValue(*OrthQualLabel, cell, DM_ADAPT_REFINE);CHKERRQ(ierr);} 9074f108dbd7SJacob Faibussowitsch } 9075f108dbd7SJacob Faibussowitsch } 90766ed19f2fSJacob Faibussowitsch ierr = VecSetValuesLocal(*OrthQual, cEnd-cStart, idx, oqVals, INSERT_VALUES);CHKERRQ(ierr); 9077f108dbd7SJacob Faibussowitsch ierr = VecAssemblyBegin(*OrthQual);CHKERRQ(ierr); 9078f108dbd7SJacob Faibussowitsch ierr = VecAssemblyEnd(*OrthQual);CHKERRQ(ierr); 9079f108dbd7SJacob Faibussowitsch ierr = VecRestoreArrayRead(cellgeom, &cellGeomArr);CHKERRQ(ierr); 9080f108dbd7SJacob Faibussowitsch ierr = VecRestoreArrayRead(facegeom, &faceGeomArr);CHKERRQ(ierr); 9081f108dbd7SJacob Faibussowitsch ierr = PetscOptionsGetViewer(comm, NULL, NULL, "-dm_plex_orthogonal_quality_label_view", &vwr, NULL, NULL);CHKERRQ(ierr); 9082f108dbd7SJacob Faibussowitsch if (OrthQualLabel) { 90836ed19f2fSJacob Faibussowitsch if (vwr) {ierr = DMLabelView(*OrthQualLabel, vwr);CHKERRQ(ierr);} 9084f108dbd7SJacob Faibussowitsch } 90856ed19f2fSJacob Faibussowitsch ierr = PetscFree5(idx, oqVals, ci, fi, Ai);CHKERRQ(ierr); 9086f108dbd7SJacob Faibussowitsch ierr = PetscViewerDestroy(&vwr);CHKERRQ(ierr); 9087f108dbd7SJacob Faibussowitsch ierr = VecViewFromOptions(*OrthQual, NULL, "-dm_plex_orthogonal_quality_vec_view");CHKERRQ(ierr); 9088f108dbd7SJacob Faibussowitsch PetscFunctionReturn(0); 9089f108dbd7SJacob Faibussowitsch } 9090f108dbd7SJacob Faibussowitsch 90911eb70e55SToby Isaac /* this is here insead of DMGetOutputDM because output DM still has constraints in the local indices that affect 90921eb70e55SToby Isaac * interpolator construction */ 90931eb70e55SToby Isaac static PetscErrorCode DMGetFullDM(DM dm, DM *odm) 90941eb70e55SToby Isaac { 90951eb70e55SToby Isaac PetscSection section, newSection, gsection; 90961eb70e55SToby Isaac PetscSF sf; 90971eb70e55SToby Isaac PetscBool hasConstraints, ghasConstraints; 90981eb70e55SToby Isaac PetscErrorCode ierr; 90991eb70e55SToby Isaac 91001eb70e55SToby Isaac PetscFunctionBegin; 91011eb70e55SToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 91021eb70e55SToby Isaac PetscValidPointer(odm,2); 91031eb70e55SToby Isaac ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr); 91041eb70e55SToby Isaac ierr = PetscSectionHasConstraints(section, &hasConstraints);CHKERRQ(ierr); 91051eb70e55SToby Isaac ierr = MPI_Allreduce(&hasConstraints, &ghasConstraints, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject) dm));CHKERRMPI(ierr); 91061eb70e55SToby Isaac if (!ghasConstraints) { 91071eb70e55SToby Isaac ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 91081eb70e55SToby Isaac *odm = dm; 91091eb70e55SToby Isaac PetscFunctionReturn(0); 91101eb70e55SToby Isaac } 91111eb70e55SToby Isaac ierr = DMClone(dm, odm);CHKERRQ(ierr); 91121eb70e55SToby Isaac ierr = DMCopyFields(dm, *odm);CHKERRQ(ierr); 91131eb70e55SToby Isaac ierr = DMGetLocalSection(*odm, &newSection);CHKERRQ(ierr); 91141eb70e55SToby Isaac ierr = DMGetPointSF(*odm, &sf);CHKERRQ(ierr); 91151eb70e55SToby Isaac ierr = PetscSectionCreateGlobalSection(newSection, sf, PETSC_TRUE, PETSC_FALSE, &gsection);CHKERRQ(ierr); 91161eb70e55SToby Isaac ierr = DMSetGlobalSection(*odm, gsection);CHKERRQ(ierr); 91171eb70e55SToby Isaac ierr = PetscSectionDestroy(&gsection);CHKERRQ(ierr); 91181eb70e55SToby Isaac PetscFunctionReturn(0); 91191eb70e55SToby Isaac } 91201eb70e55SToby Isaac 91211eb70e55SToby Isaac static PetscErrorCode DMCreateAffineInterpolationCorrection_Plex(DM dmc, DM dmf, Vec *shift) 91221eb70e55SToby Isaac { 91231eb70e55SToby Isaac DM dmco, dmfo; 91241eb70e55SToby Isaac Mat interpo; 91251eb70e55SToby Isaac Vec rscale; 91261eb70e55SToby Isaac Vec cglobalo, clocal; 91271eb70e55SToby Isaac Vec fglobal, fglobalo, flocal; 91281eb70e55SToby Isaac PetscBool regular; 91291eb70e55SToby Isaac PetscErrorCode ierr; 91301eb70e55SToby Isaac 91311eb70e55SToby Isaac PetscFunctionBegin; 91321eb70e55SToby Isaac ierr = DMGetFullDM(dmc, &dmco);CHKERRQ(ierr); 91331eb70e55SToby Isaac ierr = DMGetFullDM(dmf, &dmfo);CHKERRQ(ierr); 91341eb70e55SToby Isaac ierr = DMSetCoarseDM(dmfo, dmco);CHKERRQ(ierr); 91351eb70e55SToby Isaac ierr = DMPlexGetRegularRefinement(dmf, ®ular);CHKERRQ(ierr); 91361eb70e55SToby Isaac ierr = DMPlexSetRegularRefinement(dmfo, regular);CHKERRQ(ierr); 91371eb70e55SToby Isaac ierr = DMCreateInterpolation(dmco, dmfo, &interpo, &rscale);CHKERRQ(ierr); 91381eb70e55SToby Isaac ierr = DMCreateGlobalVector(dmco, &cglobalo);CHKERRQ(ierr); 91391eb70e55SToby Isaac ierr = DMCreateLocalVector(dmc, &clocal);CHKERRQ(ierr); 91401eb70e55SToby Isaac ierr = VecSet(cglobalo, 0.);CHKERRQ(ierr); 91411eb70e55SToby Isaac ierr = VecSet(clocal, 0.);CHKERRQ(ierr); 91421eb70e55SToby Isaac ierr = DMCreateGlobalVector(dmf, &fglobal);CHKERRQ(ierr); 91431eb70e55SToby Isaac ierr = DMCreateGlobalVector(dmfo, &fglobalo);CHKERRQ(ierr); 91441eb70e55SToby Isaac ierr = DMCreateLocalVector(dmf, &flocal);CHKERRQ(ierr); 91451eb70e55SToby Isaac ierr = VecSet(fglobal, 0.);CHKERRQ(ierr); 91461eb70e55SToby Isaac ierr = VecSet(fglobalo, 0.);CHKERRQ(ierr); 91471eb70e55SToby Isaac ierr = VecSet(flocal, 0.);CHKERRQ(ierr); 91481eb70e55SToby Isaac ierr = DMPlexInsertBoundaryValues(dmc, PETSC_TRUE, clocal, 0., NULL, NULL, NULL);CHKERRQ(ierr); 91491eb70e55SToby Isaac ierr = DMLocalToGlobalBegin(dmco, clocal, INSERT_VALUES, cglobalo);CHKERRQ(ierr); 91501eb70e55SToby Isaac ierr = DMLocalToGlobalEnd(dmco, clocal, INSERT_VALUES, cglobalo);CHKERRQ(ierr); 91511eb70e55SToby Isaac ierr = MatMult(interpo, cglobalo, fglobalo);CHKERRQ(ierr); 91521eb70e55SToby Isaac ierr = DMGlobalToLocalBegin(dmfo, fglobalo, INSERT_VALUES, flocal);CHKERRQ(ierr); 91531eb70e55SToby Isaac ierr = DMGlobalToLocalEnd(dmfo, fglobalo, INSERT_VALUES, flocal);CHKERRQ(ierr); 91541eb70e55SToby Isaac ierr = DMLocalToGlobalBegin(dmf, flocal, INSERT_VALUES, fglobal);CHKERRQ(ierr); 91551eb70e55SToby Isaac ierr = DMLocalToGlobalEnd(dmf, flocal, INSERT_VALUES, fglobal);CHKERRQ(ierr); 91561eb70e55SToby Isaac *shift = fglobal; 91571eb70e55SToby Isaac ierr = VecDestroy(&flocal);CHKERRQ(ierr); 91581eb70e55SToby Isaac ierr = VecDestroy(&fglobalo);CHKERRQ(ierr); 91591eb70e55SToby Isaac ierr = VecDestroy(&clocal);CHKERRQ(ierr); 91601eb70e55SToby Isaac ierr = VecDestroy(&cglobalo);CHKERRQ(ierr); 91611eb70e55SToby Isaac ierr = VecDestroy(&rscale);CHKERRQ(ierr); 91621eb70e55SToby Isaac ierr = MatDestroy(&interpo);CHKERRQ(ierr); 91631eb70e55SToby Isaac ierr = DMDestroy(&dmfo);CHKERRQ(ierr); 91641eb70e55SToby Isaac ierr = DMDestroy(&dmco);CHKERRQ(ierr); 91651eb70e55SToby Isaac PetscFunctionReturn(0); 91661eb70e55SToby Isaac } 91671eb70e55SToby Isaac 91681eb70e55SToby Isaac PETSC_INTERN PetscErrorCode DMInterpolateSolution_Plex(DM coarse, DM fine, Mat interp, Vec coarseSol, Vec fineSol) 91691eb70e55SToby Isaac { 91701eb70e55SToby Isaac PetscObject shifto; 91711eb70e55SToby Isaac Vec shift; 91721eb70e55SToby Isaac 91731eb70e55SToby Isaac PetscErrorCode ierr; 91741eb70e55SToby Isaac 91751eb70e55SToby Isaac PetscFunctionBegin; 91761eb70e55SToby Isaac if (!interp) { 91771eb70e55SToby Isaac Vec rscale; 91781eb70e55SToby Isaac 91791eb70e55SToby Isaac ierr = DMCreateInterpolation(coarse, fine, &interp, &rscale);CHKERRQ(ierr); 91801eb70e55SToby Isaac ierr = VecDestroy(&rscale);CHKERRQ(ierr); 91811eb70e55SToby Isaac } else { 91821eb70e55SToby Isaac ierr = PetscObjectReference((PetscObject)interp);CHKERRQ(ierr); 91831eb70e55SToby Isaac } 91841eb70e55SToby Isaac ierr = PetscObjectQuery((PetscObject)interp, "_DMInterpolateSolution_Plex_Vec", &shifto);CHKERRQ(ierr); 91851eb70e55SToby Isaac if (!shifto) { 91861eb70e55SToby Isaac ierr = DMCreateAffineInterpolationCorrection_Plex(coarse, fine, &shift);CHKERRQ(ierr); 91871eb70e55SToby Isaac ierr = PetscObjectCompose((PetscObject)interp, "_DMInterpolateSolution_Plex_Vec", (PetscObject) shift);CHKERRQ(ierr); 91881eb70e55SToby Isaac shifto = (PetscObject) shift; 91891eb70e55SToby Isaac ierr = VecDestroy(&shift);CHKERRQ(ierr); 91901eb70e55SToby Isaac } 91911eb70e55SToby Isaac shift = (Vec) shifto; 91921eb70e55SToby Isaac ierr = MatInterpolate(interp, coarseSol, fineSol);CHKERRQ(ierr); 91931eb70e55SToby Isaac ierr = VecAXPY(fineSol, 1.0, shift);CHKERRQ(ierr); 91941eb70e55SToby Isaac ierr = MatDestroy(&interp);CHKERRQ(ierr); 91951eb70e55SToby Isaac PetscFunctionReturn(0); 91961eb70e55SToby Isaac } 91971eb70e55SToby Isaac 9198bceba477SMatthew G. Knepley /* Pointwise interpolation 9199bceba477SMatthew G. Knepley Just code FEM for now 9200bceba477SMatthew G. Knepley u^f = I u^c 92014ca5e9f5SMatthew G. Knepley sum_k u^f_k phi^f_k = I sum_j u^c_j phi^c_j 92024ca5e9f5SMatthew G. Knepley u^f_i = sum_j psi^f_i I phi^c_j u^c_j 92034ca5e9f5SMatthew G. Knepley I_{ij} = psi^f_i phi^c_j 9204bceba477SMatthew G. Knepley */ 9205bceba477SMatthew G. Knepley PetscErrorCode DMCreateInterpolation_Plex(DM dmCoarse, DM dmFine, Mat *interpolation, Vec *scaling) 9206bceba477SMatthew G. Knepley { 9207bceba477SMatthew G. Knepley PetscSection gsc, gsf; 9208bceba477SMatthew G. Knepley PetscInt m, n; 9209a063dac3SMatthew G. Knepley void *ctx; 921068132eb9SMatthew G. Knepley DM cdm; 9211cf51de39SMatthew G. Knepley PetscBool regular, ismatis, isRefined = dmCoarse->data == dmFine->data ? PETSC_FALSE : PETSC_TRUE; 9212bceba477SMatthew G. Knepley PetscErrorCode ierr; 9213bceba477SMatthew G. Knepley 9214bceba477SMatthew G. Knepley PetscFunctionBegin; 9215e87a4003SBarry Smith ierr = DMGetGlobalSection(dmFine, &gsf);CHKERRQ(ierr); 9216bceba477SMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(gsf, &m);CHKERRQ(ierr); 9217e87a4003SBarry Smith ierr = DMGetGlobalSection(dmCoarse, &gsc);CHKERRQ(ierr); 9218bceba477SMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(gsc, &n);CHKERRQ(ierr); 921968132eb9SMatthew G. Knepley 9220fd194bc8SStefano Zampini ierr = PetscStrcmp(dmCoarse->mattype, MATIS, &ismatis);CHKERRQ(ierr); 9221bceba477SMatthew G. Knepley ierr = MatCreate(PetscObjectComm((PetscObject) dmCoarse), interpolation);CHKERRQ(ierr); 9222bceba477SMatthew G. Knepley ierr = MatSetSizes(*interpolation, m, n, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 9223fd194bc8SStefano Zampini ierr = MatSetType(*interpolation, ismatis ? MATAIJ : dmCoarse->mattype);CHKERRQ(ierr); 9224a063dac3SMatthew G. Knepley ierr = DMGetApplicationContext(dmFine, &ctx);CHKERRQ(ierr); 922568132eb9SMatthew G. Knepley 9226a8fb8f29SToby Isaac ierr = DMGetCoarseDM(dmFine, &cdm);CHKERRQ(ierr); 922768132eb9SMatthew G. Knepley ierr = DMPlexGetRegularRefinement(dmFine, ®ular);CHKERRQ(ierr); 9228cf51de39SMatthew G. Knepley if (!isRefined || (regular && cdm == dmCoarse)) {ierr = DMPlexComputeInterpolatorNested(dmCoarse, dmFine, isRefined, *interpolation, ctx);CHKERRQ(ierr);} 922968132eb9SMatthew G. Knepley else {ierr = DMPlexComputeInterpolatorGeneral(dmCoarse, dmFine, *interpolation, ctx);CHKERRQ(ierr);} 923068132eb9SMatthew G. Knepley ierr = MatViewFromOptions(*interpolation, NULL, "-interp_mat_view");CHKERRQ(ierr); 92314db47ee9SStefano Zampini if (scaling) { 92325d1c2e58SMatthew G. Knepley /* Use naive scaling */ 92335d1c2e58SMatthew G. Knepley ierr = DMCreateInterpolationScale(dmCoarse, dmFine, *interpolation, scaling);CHKERRQ(ierr); 92344db47ee9SStefano Zampini } 9235a063dac3SMatthew G. Knepley PetscFunctionReturn(0); 9236a063dac3SMatthew G. Knepley } 9237bceba477SMatthew G. Knepley 92386dbf9973SLawrence Mitchell PetscErrorCode DMCreateInjection_Plex(DM dmCoarse, DM dmFine, Mat *mat) 9239a063dac3SMatthew G. Knepley { 924090748bafSMatthew G. Knepley PetscErrorCode ierr; 92416dbf9973SLawrence Mitchell VecScatter ctx; 924290748bafSMatthew G. Knepley 9243a063dac3SMatthew G. Knepley PetscFunctionBegin; 92446dbf9973SLawrence Mitchell ierr = DMPlexComputeInjectorFEM(dmCoarse, dmFine, &ctx, NULL);CHKERRQ(ierr); 92456dbf9973SLawrence Mitchell ierr = MatCreateScatter(PetscObjectComm((PetscObject)ctx), ctx, mat);CHKERRQ(ierr); 92466dbf9973SLawrence Mitchell ierr = VecScatterDestroy(&ctx);CHKERRQ(ierr); 9247bceba477SMatthew G. Knepley PetscFunctionReturn(0); 9248bceba477SMatthew G. Knepley } 9249bceba477SMatthew G. Knepley 92503e9753d6SMatthew G. Knepley static void g0_identity_private(PetscInt dim, PetscInt Nf, PetscInt NfAux, 92513e9753d6SMatthew G. Knepley const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 92523e9753d6SMatthew G. Knepley const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 92533e9753d6SMatthew G. Knepley PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]) 92543e9753d6SMatthew G. Knepley { 925500635df3SMatthew G. Knepley const PetscInt Nc = uOff[1] - uOff[0]; 925600635df3SMatthew G. Knepley PetscInt c; 925700635df3SMatthew G. Knepley for (c = 0; c < Nc; ++c) g0[c*Nc+c] = 1.0; 92583e9753d6SMatthew G. Knepley } 92593e9753d6SMatthew G. Knepley 9260b4937a87SMatthew G. Knepley PetscErrorCode DMCreateMassMatrixLumped_Plex(DM dm, Vec *mass) 9261b4937a87SMatthew G. Knepley { 9262b4937a87SMatthew G. Knepley DM dmc; 9263b4937a87SMatthew G. Knepley PetscDS ds; 9264b4937a87SMatthew G. Knepley Vec ones, locmass; 9265b4937a87SMatthew G. Knepley IS cellIS; 9266b4937a87SMatthew G. Knepley PetscFormKey key; 9267b4937a87SMatthew G. Knepley PetscInt depth; 9268b4937a87SMatthew G. Knepley PetscErrorCode ierr; 9269b4937a87SMatthew G. Knepley 9270b4937a87SMatthew G. Knepley PetscFunctionBegin; 9271b4937a87SMatthew G. Knepley ierr = DMClone(dm, &dmc);CHKERRQ(ierr); 9272b4937a87SMatthew G. Knepley ierr = DMCopyDisc(dm, dmc);CHKERRQ(ierr); 9273b4937a87SMatthew G. Knepley ierr = DMGetDS(dmc, &ds);CHKERRQ(ierr); 9274b4937a87SMatthew G. Knepley ierr = PetscDSSetJacobian(ds, 0, 0, g0_identity_private, NULL, NULL, NULL);CHKERRQ(ierr); 9275b4937a87SMatthew G. Knepley ierr = DMCreateGlobalVector(dmc, mass);CHKERRQ(ierr); 9276b4937a87SMatthew G. Knepley ierr = DMGetLocalVector(dmc, &ones);CHKERRQ(ierr); 9277b4937a87SMatthew G. Knepley ierr = DMGetLocalVector(dmc, &locmass);CHKERRQ(ierr); 9278b4937a87SMatthew G. Knepley ierr = DMPlexGetDepth(dmc, &depth);CHKERRQ(ierr); 9279b4937a87SMatthew G. Knepley ierr = DMGetStratumIS(dmc, "depth", depth, &cellIS);CHKERRQ(ierr); 9280b4937a87SMatthew G. Knepley ierr = VecSet(locmass, 0.0);CHKERRQ(ierr); 9281b4937a87SMatthew G. Knepley ierr = VecSet(ones, 1.0);CHKERRQ(ierr); 9282b4937a87SMatthew G. Knepley key.label = NULL; 9283b4937a87SMatthew G. Knepley key.value = 0; 9284b4937a87SMatthew G. Knepley key.field = 0; 9285b4937a87SMatthew G. Knepley key.part = 0; 9286b4937a87SMatthew G. Knepley ierr = DMPlexComputeJacobian_Action_Internal(dmc, key, cellIS, 0.0, 0.0, ones, NULL, ones, locmass, NULL);CHKERRQ(ierr); 9287b4937a87SMatthew G. Knepley ierr = ISDestroy(&cellIS);CHKERRQ(ierr); 9288b4937a87SMatthew G. Knepley ierr = VecSet(*mass, 0.0);CHKERRQ(ierr); 9289b4937a87SMatthew G. Knepley ierr = DMLocalToGlobalBegin(dmc, locmass, ADD_VALUES, *mass);CHKERRQ(ierr); 9290b4937a87SMatthew G. Knepley ierr = DMLocalToGlobalEnd(dmc, locmass, ADD_VALUES, *mass);CHKERRQ(ierr); 9291b4937a87SMatthew G. Knepley ierr = DMRestoreLocalVector(dmc, &ones);CHKERRQ(ierr); 9292b4937a87SMatthew G. Knepley ierr = DMRestoreLocalVector(dmc, &locmass);CHKERRQ(ierr); 9293b4937a87SMatthew G. Knepley ierr = DMDestroy(&dmc);CHKERRQ(ierr); 9294b4937a87SMatthew G. Knepley PetscFunctionReturn(0); 9295b4937a87SMatthew G. Knepley } 9296b4937a87SMatthew G. Knepley 9297bd041c0cSMatthew G. Knepley PetscErrorCode DMCreateMassMatrix_Plex(DM dmCoarse, DM dmFine, Mat *mass) 9298bd041c0cSMatthew G. Knepley { 9299bd041c0cSMatthew G. Knepley PetscSection gsc, gsf; 9300bd041c0cSMatthew G. Knepley PetscInt m, n; 9301bd041c0cSMatthew G. Knepley void *ctx; 9302bd041c0cSMatthew G. Knepley DM cdm; 9303bd041c0cSMatthew G. Knepley PetscBool regular; 9304bd041c0cSMatthew G. Knepley PetscErrorCode ierr; 9305bd041c0cSMatthew G. Knepley 9306bd041c0cSMatthew G. Knepley PetscFunctionBegin; 93073e9753d6SMatthew G. Knepley if (dmFine == dmCoarse) { 93083e9753d6SMatthew G. Knepley DM dmc; 93093e9753d6SMatthew G. Knepley PetscDS ds; 9310b4937a87SMatthew G. Knepley PetscWeakForm wf; 93113e9753d6SMatthew G. Knepley Vec u; 93123e9753d6SMatthew G. Knepley IS cellIS; 931306ad1575SMatthew G. Knepley PetscFormKey key; 93143e9753d6SMatthew G. Knepley PetscInt depth; 93153e9753d6SMatthew G. Knepley 93163e9753d6SMatthew G. Knepley ierr = DMClone(dmFine, &dmc);CHKERRQ(ierr); 93173e9753d6SMatthew G. Knepley ierr = DMCopyDisc(dmFine, dmc);CHKERRQ(ierr); 93183e9753d6SMatthew G. Knepley ierr = DMGetDS(dmc, &ds);CHKERRQ(ierr); 9319b4937a87SMatthew G. Knepley ierr = PetscDSGetWeakForm(ds, &wf);CHKERRQ(ierr); 9320b4937a87SMatthew G. Knepley ierr = PetscWeakFormClear(wf);CHKERRQ(ierr); 93213e9753d6SMatthew G. Knepley ierr = PetscDSSetJacobian(ds, 0, 0, g0_identity_private, NULL, NULL, NULL);CHKERRQ(ierr); 93223e9753d6SMatthew G. Knepley ierr = DMCreateMatrix(dmc, mass);CHKERRQ(ierr); 93233e9753d6SMatthew G. Knepley ierr = DMGetGlobalVector(dmc, &u);CHKERRQ(ierr); 93243e9753d6SMatthew G. Knepley ierr = DMPlexGetDepth(dmc, &depth);CHKERRQ(ierr); 93253e9753d6SMatthew G. Knepley ierr = DMGetStratumIS(dmc, "depth", depth, &cellIS);CHKERRQ(ierr); 93263e9753d6SMatthew G. Knepley ierr = MatZeroEntries(*mass);CHKERRQ(ierr); 93276528b96dSMatthew G. Knepley key.label = NULL; 93286528b96dSMatthew G. Knepley key.value = 0; 93296528b96dSMatthew G. Knepley key.field = 0; 933006ad1575SMatthew G. Knepley key.part = 0; 93316528b96dSMatthew G. Knepley ierr = DMPlexComputeJacobian_Internal(dmc, key, cellIS, 0.0, 0.0, u, NULL, *mass, *mass, NULL);CHKERRQ(ierr); 93323e9753d6SMatthew G. Knepley ierr = ISDestroy(&cellIS);CHKERRQ(ierr); 93333e9753d6SMatthew G. Knepley ierr = DMRestoreGlobalVector(dmc, &u);CHKERRQ(ierr); 93343e9753d6SMatthew G. Knepley ierr = DMDestroy(&dmc);CHKERRQ(ierr); 93353e9753d6SMatthew G. Knepley } else { 9336e87a4003SBarry Smith ierr = DMGetGlobalSection(dmFine, &gsf);CHKERRQ(ierr); 9337bd041c0cSMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(gsf, &m);CHKERRQ(ierr); 9338e87a4003SBarry Smith ierr = DMGetGlobalSection(dmCoarse, &gsc);CHKERRQ(ierr); 9339bd041c0cSMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(gsc, &n);CHKERRQ(ierr); 9340bd041c0cSMatthew G. Knepley 9341bd041c0cSMatthew G. Knepley ierr = MatCreate(PetscObjectComm((PetscObject) dmCoarse), mass);CHKERRQ(ierr); 9342bd041c0cSMatthew G. Knepley ierr = MatSetSizes(*mass, m, n, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 9343bd041c0cSMatthew G. Knepley ierr = MatSetType(*mass, dmCoarse->mattype);CHKERRQ(ierr); 9344bd041c0cSMatthew G. Knepley ierr = DMGetApplicationContext(dmFine, &ctx);CHKERRQ(ierr); 9345bd041c0cSMatthew G. Knepley 9346bd041c0cSMatthew G. Knepley ierr = DMGetCoarseDM(dmFine, &cdm);CHKERRQ(ierr); 9347bd041c0cSMatthew G. Knepley ierr = DMPlexGetRegularRefinement(dmFine, ®ular);CHKERRQ(ierr); 9348bd041c0cSMatthew G. Knepley if (regular && cdm == dmCoarse) {ierr = DMPlexComputeMassMatrixNested(dmCoarse, dmFine, *mass, ctx);CHKERRQ(ierr);} 9349bd041c0cSMatthew G. Knepley else {ierr = DMPlexComputeMassMatrixGeneral(dmCoarse, dmFine, *mass, ctx);CHKERRQ(ierr);} 93503e9753d6SMatthew G. Knepley } 9351bd041c0cSMatthew G. Knepley ierr = MatViewFromOptions(*mass, NULL, "-mass_mat_view");CHKERRQ(ierr); 9352bd041c0cSMatthew G. Knepley PetscFunctionReturn(0); 9353bd041c0cSMatthew G. Knepley } 9354bd041c0cSMatthew G. Knepley 93550aef6b92SMatthew G. Knepley /*@ 93560aef6b92SMatthew G. Knepley DMPlexGetRegularRefinement - Get the flag indicating that this mesh was obtained by regular refinement from its coarse mesh 93570aef6b92SMatthew G. Knepley 93580aef6b92SMatthew G. Knepley Input Parameter: 93590aef6b92SMatthew G. Knepley . dm - The DMPlex object 93600aef6b92SMatthew G. Knepley 93610aef6b92SMatthew G. Knepley Output Parameter: 93620aef6b92SMatthew G. Knepley . regular - The flag 93630aef6b92SMatthew G. Knepley 93640aef6b92SMatthew G. Knepley Level: intermediate 93650aef6b92SMatthew G. Knepley 93660aef6b92SMatthew G. Knepley .seealso: DMPlexSetRegularRefinement() 93670aef6b92SMatthew G. Knepley @*/ 93680aef6b92SMatthew G. Knepley PetscErrorCode DMPlexGetRegularRefinement(DM dm, PetscBool *regular) 93690aef6b92SMatthew G. Knepley { 93700aef6b92SMatthew G. Knepley PetscFunctionBegin; 93710aef6b92SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 93720aef6b92SMatthew G. Knepley PetscValidPointer(regular, 2); 93730aef6b92SMatthew G. Knepley *regular = ((DM_Plex *) dm->data)->regularRefinement; 93740aef6b92SMatthew G. Knepley PetscFunctionReturn(0); 93750aef6b92SMatthew G. Knepley } 93760aef6b92SMatthew G. Knepley 93770aef6b92SMatthew G. Knepley /*@ 93780aef6b92SMatthew G. Knepley DMPlexSetRegularRefinement - Set the flag indicating that this mesh was obtained by regular refinement from its coarse mesh 93790aef6b92SMatthew G. Knepley 93800aef6b92SMatthew G. Knepley Input Parameters: 93810aef6b92SMatthew G. Knepley + dm - The DMPlex object 93820aef6b92SMatthew G. Knepley - regular - The flag 93830aef6b92SMatthew G. Knepley 93840aef6b92SMatthew G. Knepley Level: intermediate 93850aef6b92SMatthew G. Knepley 93860aef6b92SMatthew G. Knepley .seealso: DMPlexGetRegularRefinement() 93870aef6b92SMatthew G. Knepley @*/ 93880aef6b92SMatthew G. Knepley PetscErrorCode DMPlexSetRegularRefinement(DM dm, PetscBool regular) 93890aef6b92SMatthew G. Knepley { 93900aef6b92SMatthew G. Knepley PetscFunctionBegin; 93910aef6b92SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 93920aef6b92SMatthew G. Knepley ((DM_Plex *) dm->data)->regularRefinement = regular; 93930aef6b92SMatthew G. Knepley PetscFunctionReturn(0); 93940aef6b92SMatthew G. Knepley } 93950aef6b92SMatthew G. Knepley 9396f7c74593SToby Isaac /* anchors */ 9397a68b90caSToby Isaac /*@ 9398f7c74593SToby Isaac DMPlexGetAnchors - Get the layout of the anchor (point-to-point) constraints. Typically, the user will not have to 9399f7c74593SToby Isaac call DMPlexGetAnchors() directly: if there are anchors, then DMPlexGetAnchors() is called during DMGetConstraints(). 9400a68b90caSToby Isaac 9401e228b242SToby Isaac not collective 9402a68b90caSToby Isaac 9403f899ff85SJose E. Roman Input Parameter: 9404a68b90caSToby Isaac . dm - The DMPlex object 9405a68b90caSToby Isaac 9406a68b90caSToby Isaac Output Parameters: 9407a68b90caSToby Isaac + anchorSection - If not NULL, set to the section describing which points anchor the constrained points. 9408a68b90caSToby Isaac - anchorIS - If not NULL, set to the list of anchors indexed by anchorSection 9409a68b90caSToby Isaac 9410a68b90caSToby Isaac Level: intermediate 9411a68b90caSToby Isaac 9412f7c74593SToby Isaac .seealso: DMPlexSetAnchors(), DMGetConstraints(), DMSetConstraints() 9413a68b90caSToby Isaac @*/ 9414a17985deSToby Isaac PetscErrorCode DMPlexGetAnchors(DM dm, PetscSection *anchorSection, IS *anchorIS) 9415a68b90caSToby Isaac { 9416a68b90caSToby Isaac DM_Plex *plex = (DM_Plex *)dm->data; 941741e6d900SToby Isaac PetscErrorCode ierr; 9418a68b90caSToby Isaac 9419a68b90caSToby Isaac PetscFunctionBegin; 9420a68b90caSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 942141e6d900SToby Isaac if (!plex->anchorSection && !plex->anchorIS && plex->createanchors) {ierr = (*plex->createanchors)(dm);CHKERRQ(ierr);} 9422a68b90caSToby Isaac if (anchorSection) *anchorSection = plex->anchorSection; 9423a68b90caSToby Isaac if (anchorIS) *anchorIS = plex->anchorIS; 9424a68b90caSToby Isaac PetscFunctionReturn(0); 9425a68b90caSToby Isaac } 9426a68b90caSToby Isaac 9427a68b90caSToby Isaac /*@ 9428f7c74593SToby Isaac DMPlexSetAnchors - Set the layout of the local anchor (point-to-point) constraints. Unlike boundary conditions, 9429f7c74593SToby Isaac when a point's degrees of freedom in a section are constrained to an outside value, the anchor constraints set a 9430a68b90caSToby Isaac point's degrees of freedom to be a linear combination of other points' degrees of freedom. 9431a68b90caSToby Isaac 9432a17985deSToby Isaac After specifying the layout of constraints with DMPlexSetAnchors(), one specifies the constraints by calling 9433f7c74593SToby Isaac DMGetConstraints() and filling in the entries in the constraint matrix. 9434a68b90caSToby Isaac 9435e228b242SToby Isaac collective on dm 9436a68b90caSToby Isaac 9437a68b90caSToby Isaac Input Parameters: 9438a68b90caSToby Isaac + dm - The DMPlex object 9439e228b242SToby 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). 9440e228b242SToby Isaac - anchorIS - The list of all anchor points. Must have a local communicator (PETSC_COMM_SELF or derivative). 9441a68b90caSToby Isaac 9442a68b90caSToby Isaac The reference counts of anchorSection and anchorIS are incremented. 9443a68b90caSToby Isaac 9444a68b90caSToby Isaac Level: intermediate 9445a68b90caSToby Isaac 9446f7c74593SToby Isaac .seealso: DMPlexGetAnchors(), DMGetConstraints(), DMSetConstraints() 9447a68b90caSToby Isaac @*/ 9448a17985deSToby Isaac PetscErrorCode DMPlexSetAnchors(DM dm, PetscSection anchorSection, IS anchorIS) 9449a68b90caSToby Isaac { 9450a68b90caSToby Isaac DM_Plex *plex = (DM_Plex *)dm->data; 9451e228b242SToby Isaac PetscMPIInt result; 9452a68b90caSToby Isaac PetscErrorCode ierr; 9453a68b90caSToby Isaac 9454a68b90caSToby Isaac PetscFunctionBegin; 9455a68b90caSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9456e228b242SToby Isaac if (anchorSection) { 9457e228b242SToby Isaac PetscValidHeaderSpecific(anchorSection,PETSC_SECTION_CLASSID,2); 9458ffc4695bSBarry Smith ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)anchorSection),&result);CHKERRMPI(ierr); 94592c71b3e2SJacob Faibussowitsch PetscCheckFalse(result != MPI_CONGRUENT && result != MPI_IDENT,PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"anchor section must have local communicator"); 9460e228b242SToby Isaac } 9461e228b242SToby Isaac if (anchorIS) { 9462e228b242SToby Isaac PetscValidHeaderSpecific(anchorIS,IS_CLASSID,3); 9463ffc4695bSBarry Smith ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)anchorIS),&result);CHKERRMPI(ierr); 94642c71b3e2SJacob Faibussowitsch PetscCheckFalse(result != MPI_CONGRUENT && result != MPI_IDENT,PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"anchor IS must have local communicator"); 9465e228b242SToby Isaac } 9466a68b90caSToby Isaac 9467a68b90caSToby Isaac ierr = PetscObjectReference((PetscObject)anchorSection);CHKERRQ(ierr); 9468a68b90caSToby Isaac ierr = PetscSectionDestroy(&plex->anchorSection);CHKERRQ(ierr); 9469a68b90caSToby Isaac plex->anchorSection = anchorSection; 9470a68b90caSToby Isaac 9471a68b90caSToby Isaac ierr = PetscObjectReference((PetscObject)anchorIS);CHKERRQ(ierr); 9472a68b90caSToby Isaac ierr = ISDestroy(&plex->anchorIS);CHKERRQ(ierr); 9473a68b90caSToby Isaac plex->anchorIS = anchorIS; 9474a68b90caSToby Isaac 9475cf9c20a2SJed Brown if (PetscUnlikelyDebug(anchorIS && anchorSection)) { 9476a68b90caSToby Isaac PetscInt size, a, pStart, pEnd; 9477a68b90caSToby Isaac const PetscInt *anchors; 9478a68b90caSToby Isaac 9479a68b90caSToby Isaac ierr = PetscSectionGetChart(anchorSection,&pStart,&pEnd);CHKERRQ(ierr); 9480a68b90caSToby Isaac ierr = ISGetLocalSize(anchorIS,&size);CHKERRQ(ierr); 9481a68b90caSToby Isaac ierr = ISGetIndices(anchorIS,&anchors);CHKERRQ(ierr); 9482a68b90caSToby Isaac for (a = 0; a < size; a++) { 9483a68b90caSToby Isaac PetscInt p; 9484a68b90caSToby Isaac 9485a68b90caSToby Isaac p = anchors[a]; 9486a68b90caSToby Isaac if (p >= pStart && p < pEnd) { 9487a68b90caSToby Isaac PetscInt dof; 9488a68b90caSToby Isaac 9489a68b90caSToby Isaac ierr = PetscSectionGetDof(anchorSection,p,&dof);CHKERRQ(ierr); 9490a68b90caSToby Isaac if (dof) { 9491a68b90caSToby Isaac PetscErrorCode ierr2; 9492a68b90caSToby Isaac 9493a68b90caSToby Isaac ierr2 = ISRestoreIndices(anchorIS,&anchors);CHKERRQ(ierr2); 949498921bdaSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Point %D cannot be constrained and an anchor",p); 9495a68b90caSToby Isaac } 9496a68b90caSToby Isaac } 9497a68b90caSToby Isaac } 9498a68b90caSToby Isaac ierr = ISRestoreIndices(anchorIS,&anchors);CHKERRQ(ierr); 9499a68b90caSToby Isaac } 9500f7c74593SToby Isaac /* reset the generic constraints */ 9501f7c74593SToby Isaac ierr = DMSetDefaultConstraints(dm,NULL,NULL);CHKERRQ(ierr); 9502a68b90caSToby Isaac PetscFunctionReturn(0); 9503a68b90caSToby Isaac } 9504a68b90caSToby Isaac 9505f7c74593SToby Isaac static PetscErrorCode DMPlexCreateConstraintSection_Anchors(DM dm, PetscSection section, PetscSection *cSec) 9506a68b90caSToby Isaac { 9507f7c74593SToby Isaac PetscSection anchorSection; 95086995de1eSToby Isaac PetscInt pStart, pEnd, sStart, sEnd, p, dof, numFields, f; 9509a68b90caSToby Isaac PetscErrorCode ierr; 9510a68b90caSToby Isaac 9511a68b90caSToby Isaac PetscFunctionBegin; 9512a68b90caSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9513a17985deSToby Isaac ierr = DMPlexGetAnchors(dm,&anchorSection,NULL);CHKERRQ(ierr); 9514e228b242SToby Isaac ierr = PetscSectionCreate(PETSC_COMM_SELF,cSec);CHKERRQ(ierr); 9515a68b90caSToby Isaac ierr = PetscSectionGetNumFields(section,&numFields);CHKERRQ(ierr); 95166995de1eSToby Isaac if (numFields) { 9517719ab38cSToby Isaac PetscInt f; 9518a68b90caSToby Isaac ierr = PetscSectionSetNumFields(*cSec,numFields);CHKERRQ(ierr); 9519719ab38cSToby Isaac 9520719ab38cSToby Isaac for (f = 0; f < numFields; f++) { 9521719ab38cSToby Isaac PetscInt numComp; 9522719ab38cSToby Isaac 9523719ab38cSToby Isaac ierr = PetscSectionGetFieldComponents(section,f,&numComp);CHKERRQ(ierr); 9524719ab38cSToby Isaac ierr = PetscSectionSetFieldComponents(*cSec,f,numComp);CHKERRQ(ierr); 9525719ab38cSToby Isaac } 95266995de1eSToby Isaac } 9527a68b90caSToby Isaac ierr = PetscSectionGetChart(anchorSection,&pStart,&pEnd);CHKERRQ(ierr); 95286995de1eSToby Isaac ierr = PetscSectionGetChart(section,&sStart,&sEnd);CHKERRQ(ierr); 95296995de1eSToby Isaac pStart = PetscMax(pStart,sStart); 95306995de1eSToby Isaac pEnd = PetscMin(pEnd,sEnd); 95316995de1eSToby Isaac pEnd = PetscMax(pStart,pEnd); 9532a68b90caSToby Isaac ierr = PetscSectionSetChart(*cSec,pStart,pEnd);CHKERRQ(ierr); 9533a68b90caSToby Isaac for (p = pStart; p < pEnd; p++) { 9534a68b90caSToby Isaac ierr = PetscSectionGetDof(anchorSection,p,&dof);CHKERRQ(ierr); 9535a68b90caSToby Isaac if (dof) { 9536a68b90caSToby Isaac ierr = PetscSectionGetDof(section,p,&dof);CHKERRQ(ierr); 9537a68b90caSToby Isaac ierr = PetscSectionSetDof(*cSec,p,dof);CHKERRQ(ierr); 9538a68b90caSToby Isaac for (f = 0; f < numFields; f++) { 9539a68b90caSToby Isaac ierr = PetscSectionGetFieldDof(section,p,f,&dof);CHKERRQ(ierr); 9540a68b90caSToby Isaac ierr = PetscSectionSetFieldDof(*cSec,p,f,dof);CHKERRQ(ierr); 9541a68b90caSToby Isaac } 9542a68b90caSToby Isaac } 9543a68b90caSToby Isaac } 9544a68b90caSToby Isaac ierr = PetscSectionSetUp(*cSec);CHKERRQ(ierr); 9545ae65431dSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) *cSec, "Constraint Section");CHKERRQ(ierr); 9546a68b90caSToby Isaac PetscFunctionReturn(0); 9547a68b90caSToby Isaac } 9548a68b90caSToby Isaac 9549f7c74593SToby Isaac static PetscErrorCode DMPlexCreateConstraintMatrix_Anchors(DM dm, PetscSection section, PetscSection cSec, Mat *cMat) 9550a68b90caSToby Isaac { 9551f7c74593SToby Isaac PetscSection aSec; 9552ae65431dSMatthew G. Knepley PetscInt pStart, pEnd, p, sStart, sEnd, dof, aDof, aOff, off, nnz, annz, m, n, q, a, offset, *i, *j; 95530ac89760SToby Isaac const PetscInt *anchors; 95540ac89760SToby Isaac PetscInt numFields, f; 955566ad2231SToby Isaac IS aIS; 95560ac89760SToby Isaac PetscErrorCode ierr; 9557e19f7ee6SMark Adams MatType mtype; 9558e19f7ee6SMark Adams PetscBool iscuda,iskokkos; 95590ac89760SToby Isaac 95600ac89760SToby Isaac PetscFunctionBegin; 95610ac89760SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 95620ac89760SToby Isaac ierr = PetscSectionGetStorageSize(cSec, &m);CHKERRQ(ierr); 95630ac89760SToby Isaac ierr = PetscSectionGetStorageSize(section, &n);CHKERRQ(ierr); 95640ac89760SToby Isaac ierr = MatCreate(PETSC_COMM_SELF,cMat);CHKERRQ(ierr); 95650ac89760SToby Isaac ierr = MatSetSizes(*cMat,m,n,m,n);CHKERRQ(ierr); 9566e19f7ee6SMark Adams ierr = PetscStrcmp(dm->mattype,MATSEQAIJCUSPARSE,&iscuda);CHKERRQ(ierr); 9567e19f7ee6SMark Adams if (!iscuda) { ierr = PetscStrcmp(dm->mattype,MATMPIAIJCUSPARSE,&iscuda);CHKERRQ(ierr); } 9568e19f7ee6SMark Adams ierr = PetscStrcmp(dm->mattype,MATSEQAIJKOKKOS,&iskokkos);CHKERRQ(ierr); 9569e19f7ee6SMark Adams if (!iskokkos) { ierr = PetscStrcmp(dm->mattype,MATMPIAIJKOKKOS,&iskokkos);CHKERRQ(ierr); } 9570e19f7ee6SMark Adams if (iscuda) mtype = MATSEQAIJCUSPARSE; 9571e19f7ee6SMark Adams else if (iskokkos) mtype = MATSEQAIJKOKKOS; 9572e19f7ee6SMark Adams else mtype = MATSEQAIJ; 9573e19f7ee6SMark Adams ierr = MatSetType(*cMat,mtype);CHKERRQ(ierr); 9574a17985deSToby Isaac ierr = DMPlexGetAnchors(dm,&aSec,&aIS);CHKERRQ(ierr); 957566ad2231SToby Isaac ierr = ISGetIndices(aIS,&anchors);CHKERRQ(ierr); 95766995de1eSToby Isaac /* cSec will be a subset of aSec and section */ 95776995de1eSToby Isaac ierr = PetscSectionGetChart(cSec,&pStart,&pEnd);CHKERRQ(ierr); 9578ae65431dSMatthew G. Knepley ierr = PetscSectionGetChart(section,&sStart,&sEnd);CHKERRQ(ierr); 95790ac89760SToby Isaac ierr = PetscMalloc1(m+1,&i);CHKERRQ(ierr); 95800ac89760SToby Isaac i[0] = 0; 95810ac89760SToby Isaac ierr = PetscSectionGetNumFields(section,&numFields);CHKERRQ(ierr); 95820ac89760SToby Isaac for (p = pStart; p < pEnd; p++) { 9583f19733c5SToby Isaac PetscInt rDof, rOff, r; 9584f19733c5SToby Isaac 9585f19733c5SToby Isaac ierr = PetscSectionGetDof(aSec,p,&rDof);CHKERRQ(ierr); 9586f19733c5SToby Isaac if (!rDof) continue; 9587f19733c5SToby Isaac ierr = PetscSectionGetOffset(aSec,p,&rOff);CHKERRQ(ierr); 95880ac89760SToby Isaac if (numFields) { 95890ac89760SToby Isaac for (f = 0; f < numFields; f++) { 95900ac89760SToby Isaac annz = 0; 9591f19733c5SToby Isaac for (r = 0; r < rDof; r++) { 9592f19733c5SToby Isaac a = anchors[rOff + r]; 9593ae65431dSMatthew G. Knepley if (a < sStart || a >= sEnd) continue; 95940ac89760SToby Isaac ierr = PetscSectionGetFieldDof(section,a,f,&aDof);CHKERRQ(ierr); 95950ac89760SToby Isaac annz += aDof; 95960ac89760SToby Isaac } 95970ac89760SToby Isaac ierr = PetscSectionGetFieldDof(cSec,p,f,&dof);CHKERRQ(ierr); 95980ac89760SToby Isaac ierr = PetscSectionGetFieldOffset(cSec,p,f,&off);CHKERRQ(ierr); 95990ac89760SToby Isaac for (q = 0; q < dof; q++) { 96000ac89760SToby Isaac i[off + q + 1] = i[off + q] + annz; 96010ac89760SToby Isaac } 96020ac89760SToby Isaac } 96032f7452b8SBarry Smith } else { 96040ac89760SToby Isaac annz = 0; 9605326b8f31SMatthew G. Knepley ierr = PetscSectionGetDof(cSec,p,&dof);CHKERRQ(ierr); 96060ac89760SToby Isaac for (q = 0; q < dof; q++) { 9607ae65431dSMatthew G. Knepley a = anchors[rOff + q]; 9608ae65431dSMatthew G. Knepley if (a < sStart || a >= sEnd) continue; 96090ac89760SToby Isaac ierr = PetscSectionGetDof(section,a,&aDof);CHKERRQ(ierr); 96100ac89760SToby Isaac annz += aDof; 96110ac89760SToby Isaac } 96120ac89760SToby Isaac ierr = PetscSectionGetDof(cSec,p,&dof);CHKERRQ(ierr); 96130ac89760SToby Isaac ierr = PetscSectionGetOffset(cSec,p,&off);CHKERRQ(ierr); 96140ac89760SToby Isaac for (q = 0; q < dof; q++) { 96150ac89760SToby Isaac i[off + q + 1] = i[off + q] + annz; 96160ac89760SToby Isaac } 96170ac89760SToby Isaac } 96180ac89760SToby Isaac } 96190ac89760SToby Isaac nnz = i[m]; 96200ac89760SToby Isaac ierr = PetscMalloc1(nnz,&j);CHKERRQ(ierr); 96210ac89760SToby Isaac offset = 0; 96220ac89760SToby Isaac for (p = pStart; p < pEnd; p++) { 96230ac89760SToby Isaac if (numFields) { 96240ac89760SToby Isaac for (f = 0; f < numFields; f++) { 96250ac89760SToby Isaac ierr = PetscSectionGetFieldDof(cSec,p,f,&dof);CHKERRQ(ierr); 96260ac89760SToby Isaac for (q = 0; q < dof; q++) { 96270ac89760SToby Isaac PetscInt rDof, rOff, r; 96280ac89760SToby Isaac ierr = PetscSectionGetDof(aSec,p,&rDof);CHKERRQ(ierr); 96290ac89760SToby Isaac ierr = PetscSectionGetOffset(aSec,p,&rOff);CHKERRQ(ierr); 96300ac89760SToby Isaac for (r = 0; r < rDof; r++) { 96310ac89760SToby Isaac PetscInt s; 96320ac89760SToby Isaac 96330ac89760SToby Isaac a = anchors[rOff + r]; 9634ae65431dSMatthew G. Knepley if (a < sStart || a >= sEnd) continue; 96350ac89760SToby Isaac ierr = PetscSectionGetFieldDof(section,a,f,&aDof);CHKERRQ(ierr); 96360ac89760SToby Isaac ierr = PetscSectionGetFieldOffset(section,a,f,&aOff);CHKERRQ(ierr); 96370ac89760SToby Isaac for (s = 0; s < aDof; s++) { 96380ac89760SToby Isaac j[offset++] = aOff + s; 96390ac89760SToby Isaac } 96400ac89760SToby Isaac } 96410ac89760SToby Isaac } 96420ac89760SToby Isaac } 96432f7452b8SBarry Smith } else { 96440ac89760SToby Isaac ierr = PetscSectionGetDof(cSec,p,&dof);CHKERRQ(ierr); 96450ac89760SToby Isaac for (q = 0; q < dof; q++) { 96460ac89760SToby Isaac PetscInt rDof, rOff, r; 96470ac89760SToby Isaac ierr = PetscSectionGetDof(aSec,p,&rDof);CHKERRQ(ierr); 96480ac89760SToby Isaac ierr = PetscSectionGetOffset(aSec,p,&rOff);CHKERRQ(ierr); 96490ac89760SToby Isaac for (r = 0; r < rDof; r++) { 96500ac89760SToby Isaac PetscInt s; 96510ac89760SToby Isaac 96520ac89760SToby Isaac a = anchors[rOff + r]; 9653ae65431dSMatthew G. Knepley if (a < sStart || a >= sEnd) continue; 96540ac89760SToby Isaac ierr = PetscSectionGetDof(section,a,&aDof);CHKERRQ(ierr); 96550ac89760SToby Isaac ierr = PetscSectionGetOffset(section,a,&aOff);CHKERRQ(ierr); 96560ac89760SToby Isaac for (s = 0; s < aDof; s++) { 96570ac89760SToby Isaac j[offset++] = aOff + s; 96580ac89760SToby Isaac } 96590ac89760SToby Isaac } 96600ac89760SToby Isaac } 96610ac89760SToby Isaac } 96620ac89760SToby Isaac } 96630ac89760SToby Isaac ierr = MatSeqAIJSetPreallocationCSR(*cMat,i,j,NULL);CHKERRQ(ierr); 966425570a81SToby Isaac ierr = PetscFree(i);CHKERRQ(ierr); 966525570a81SToby Isaac ierr = PetscFree(j);CHKERRQ(ierr); 966666ad2231SToby Isaac ierr = ISRestoreIndices(aIS,&anchors);CHKERRQ(ierr); 96670ac89760SToby Isaac PetscFunctionReturn(0); 96680ac89760SToby Isaac } 96690ac89760SToby Isaac 967066ad2231SToby Isaac PetscErrorCode DMCreateDefaultConstraints_Plex(DM dm) 967166ad2231SToby Isaac { 9672f7c74593SToby Isaac DM_Plex *plex = (DM_Plex *)dm->data; 9673f7c74593SToby Isaac PetscSection anchorSection, section, cSec; 967466ad2231SToby Isaac Mat cMat; 967566ad2231SToby Isaac PetscErrorCode ierr; 967666ad2231SToby Isaac 967766ad2231SToby Isaac PetscFunctionBegin; 967866ad2231SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9679a17985deSToby Isaac ierr = DMPlexGetAnchors(dm,&anchorSection,NULL);CHKERRQ(ierr); 968066ad2231SToby Isaac if (anchorSection) { 968144a7f3ddSMatthew G. Knepley PetscInt Nf; 9682e228b242SToby Isaac 968392fd8e1eSJed Brown ierr = DMGetLocalSection(dm,§ion);CHKERRQ(ierr); 9684f7c74593SToby Isaac ierr = DMPlexCreateConstraintSection_Anchors(dm,section,&cSec);CHKERRQ(ierr); 9685f7c74593SToby Isaac ierr = DMPlexCreateConstraintMatrix_Anchors(dm,section,cSec,&cMat);CHKERRQ(ierr); 968644a7f3ddSMatthew G. Knepley ierr = DMGetNumFields(dm,&Nf);CHKERRQ(ierr); 968744a7f3ddSMatthew G. Knepley if (Nf && plex->computeanchormatrix) {ierr = (*plex->computeanchormatrix)(dm,section,cSec,cMat);CHKERRQ(ierr);} 968866ad2231SToby Isaac ierr = DMSetDefaultConstraints(dm,cSec,cMat);CHKERRQ(ierr); 968966ad2231SToby Isaac ierr = PetscSectionDestroy(&cSec);CHKERRQ(ierr); 969066ad2231SToby Isaac ierr = MatDestroy(&cMat);CHKERRQ(ierr); 969166ad2231SToby Isaac } 969266ad2231SToby Isaac PetscFunctionReturn(0); 969366ad2231SToby Isaac } 9694a93c429eSMatthew G. Knepley 9695a93c429eSMatthew G. Knepley PetscErrorCode DMCreateSubDomainDM_Plex(DM dm, DMLabel label, PetscInt value, IS *is, DM *subdm) 9696a93c429eSMatthew G. Knepley { 9697a93c429eSMatthew G. Knepley IS subis; 9698a93c429eSMatthew G. Knepley PetscSection section, subsection; 9699a93c429eSMatthew G. Knepley PetscErrorCode ierr; 9700a93c429eSMatthew G. Knepley 9701a93c429eSMatthew G. Knepley PetscFunctionBegin; 970292fd8e1eSJed Brown ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr); 97032c71b3e2SJacob Faibussowitsch PetscCheckFalse(!section,PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Must set default section for DM before splitting subdomain"); 97042c71b3e2SJacob Faibussowitsch PetscCheckFalse(!subdm,PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Must set output subDM for splitting subdomain"); 9705a93c429eSMatthew G. Knepley /* Create subdomain */ 9706a93c429eSMatthew G. Knepley ierr = DMPlexFilter(dm, label, value, subdm);CHKERRQ(ierr); 9707a93c429eSMatthew G. Knepley /* Create submodel */ 970897d8846cSMatthew Knepley ierr = DMPlexGetSubpointIS(*subdm, &subis);CHKERRQ(ierr); 9709a93c429eSMatthew G. Knepley ierr = PetscSectionCreateSubmeshSection(section, subis, &subsection);CHKERRQ(ierr); 971092fd8e1eSJed Brown ierr = DMSetLocalSection(*subdm, subsection);CHKERRQ(ierr); 9711a93c429eSMatthew G. Knepley ierr = PetscSectionDestroy(&subsection);CHKERRQ(ierr); 9712e5e52638SMatthew G. Knepley ierr = DMCopyDisc(dm, *subdm);CHKERRQ(ierr); 9713a93c429eSMatthew G. Knepley /* Create map from submodel to global model */ 9714a93c429eSMatthew G. Knepley if (is) { 9715a93c429eSMatthew G. Knepley PetscSection sectionGlobal, subsectionGlobal; 9716a93c429eSMatthew G. Knepley IS spIS; 9717a93c429eSMatthew G. Knepley const PetscInt *spmap; 9718a93c429eSMatthew G. Knepley PetscInt *subIndices; 9719a93c429eSMatthew G. Knepley PetscInt subSize = 0, subOff = 0, pStart, pEnd, p; 9720a93c429eSMatthew G. Knepley PetscInt Nf, f, bs = -1, bsLocal[2], bsMinMax[2]; 9721a93c429eSMatthew G. Knepley 972297d8846cSMatthew Knepley ierr = DMPlexGetSubpointIS(*subdm, &spIS);CHKERRQ(ierr); 9723a93c429eSMatthew G. Knepley ierr = ISGetIndices(spIS, &spmap);CHKERRQ(ierr); 9724a93c429eSMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &Nf);CHKERRQ(ierr); 97256f0eb057SJed Brown ierr = DMGetGlobalSection(dm, §ionGlobal);CHKERRQ(ierr); 97266f0eb057SJed Brown ierr = DMGetGlobalSection(*subdm, &subsectionGlobal);CHKERRQ(ierr); 9727a93c429eSMatthew G. Knepley ierr = PetscSectionGetChart(subsection, &pStart, &pEnd);CHKERRQ(ierr); 9728a93c429eSMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 9729a93c429eSMatthew G. Knepley PetscInt gdof, pSubSize = 0; 9730a93c429eSMatthew G. Knepley 9731a93c429eSMatthew G. Knepley ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr); 9732a93c429eSMatthew G. Knepley if (gdof > 0) { 9733a93c429eSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 9734a93c429eSMatthew G. Knepley PetscInt fdof, fcdof; 9735a93c429eSMatthew G. Knepley 9736a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldDof(subsection, p, f, &fdof);CHKERRQ(ierr); 9737a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldConstraintDof(subsection, p, f, &fcdof);CHKERRQ(ierr); 9738a93c429eSMatthew G. Knepley pSubSize += fdof-fcdof; 9739a93c429eSMatthew G. Knepley } 9740a93c429eSMatthew G. Knepley subSize += pSubSize; 9741a93c429eSMatthew G. Knepley if (pSubSize) { 9742a93c429eSMatthew G. Knepley if (bs < 0) { 9743a93c429eSMatthew G. Knepley bs = pSubSize; 9744a93c429eSMatthew G. Knepley } else if (bs != pSubSize) { 9745a93c429eSMatthew G. Knepley /* Layout does not admit a pointwise block size */ 9746a93c429eSMatthew G. Knepley bs = 1; 9747a93c429eSMatthew G. Knepley } 9748a93c429eSMatthew G. Knepley } 9749a93c429eSMatthew G. Knepley } 9750a93c429eSMatthew G. Knepley } 9751a93c429eSMatthew G. Knepley /* Must have same blocksize on all procs (some might have no points) */ 9752a93c429eSMatthew G. Knepley bsLocal[0] = bs < 0 ? PETSC_MAX_INT : bs; bsLocal[1] = bs; 9753a93c429eSMatthew G. Knepley ierr = PetscGlobalMinMaxInt(PetscObjectComm((PetscObject) dm), bsLocal, bsMinMax);CHKERRQ(ierr); 9754a93c429eSMatthew G. Knepley if (bsMinMax[0] != bsMinMax[1]) {bs = 1;} 9755a93c429eSMatthew G. Knepley else {bs = bsMinMax[0];} 9756a93c429eSMatthew G. Knepley ierr = PetscMalloc1(subSize, &subIndices);CHKERRQ(ierr); 9757a93c429eSMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 9758a93c429eSMatthew G. Knepley PetscInt gdof, goff; 9759a93c429eSMatthew G. Knepley 9760a93c429eSMatthew G. Knepley ierr = PetscSectionGetDof(subsectionGlobal, p, &gdof);CHKERRQ(ierr); 9761a93c429eSMatthew G. Knepley if (gdof > 0) { 9762a93c429eSMatthew G. Knepley const PetscInt point = spmap[p]; 9763a93c429eSMatthew G. Knepley 9764a93c429eSMatthew G. Knepley ierr = PetscSectionGetOffset(sectionGlobal, point, &goff);CHKERRQ(ierr); 9765a93c429eSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 9766a93c429eSMatthew G. Knepley PetscInt fdof, fcdof, fc, f2, poff = 0; 9767a93c429eSMatthew G. Knepley 9768a93c429eSMatthew G. Knepley /* Can get rid of this loop by storing field information in the global section */ 9769a93c429eSMatthew G. Knepley for (f2 = 0; f2 < f; ++f2) { 9770a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, p, f2, &fdof);CHKERRQ(ierr); 9771a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldConstraintDof(section, p, f2, &fcdof);CHKERRQ(ierr); 9772a93c429eSMatthew G. Knepley poff += fdof-fcdof; 9773a93c429eSMatthew G. Knepley } 9774a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr); 9775a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr); 9776a93c429eSMatthew G. Knepley for (fc = 0; fc < fdof-fcdof; ++fc, ++subOff) { 9777a93c429eSMatthew G. Knepley subIndices[subOff] = goff+poff+fc; 9778a93c429eSMatthew G. Knepley } 9779a93c429eSMatthew G. Knepley } 9780a93c429eSMatthew G. Knepley } 9781a93c429eSMatthew G. Knepley } 9782a93c429eSMatthew G. Knepley ierr = ISRestoreIndices(spIS, &spmap);CHKERRQ(ierr); 9783a93c429eSMatthew G. Knepley ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), subSize, subIndices, PETSC_OWN_POINTER, is);CHKERRQ(ierr); 9784a93c429eSMatthew G. Knepley if (bs > 1) { 9785a93c429eSMatthew G. Knepley /* We need to check that the block size does not come from non-contiguous fields */ 9786a93c429eSMatthew G. Knepley PetscInt i, j, set = 1; 9787a93c429eSMatthew G. Knepley for (i = 0; i < subSize; i += bs) { 9788a93c429eSMatthew G. Knepley for (j = 0; j < bs; ++j) { 9789a93c429eSMatthew G. Knepley if (subIndices[i+j] != subIndices[i]+j) {set = 0; break;} 9790a93c429eSMatthew G. Knepley } 9791a93c429eSMatthew G. Knepley } 9792a93c429eSMatthew G. Knepley if (set) {ierr = ISSetBlockSize(*is, bs);CHKERRQ(ierr);} 9793a93c429eSMatthew G. Knepley } 9794a93c429eSMatthew G. Knepley /* Attach nullspace */ 9795a93c429eSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 9796a93c429eSMatthew G. Knepley (*subdm)->nullspaceConstructors[f] = dm->nullspaceConstructors[f]; 9797a93c429eSMatthew G. Knepley if ((*subdm)->nullspaceConstructors[f]) break; 9798a93c429eSMatthew G. Knepley } 9799a93c429eSMatthew G. Knepley if (f < Nf) { 9800a93c429eSMatthew G. Knepley MatNullSpace nullSpace; 98018cda7954SMatthew G. Knepley ierr = (*(*subdm)->nullspaceConstructors[f])(*subdm, f, f, &nullSpace);CHKERRQ(ierr); 98026823f3c5SBlaise Bourdin 9803a93c429eSMatthew G. Knepley ierr = PetscObjectCompose((PetscObject) *is, "nullspace", (PetscObject) nullSpace);CHKERRQ(ierr); 9804a93c429eSMatthew G. Knepley ierr = MatNullSpaceDestroy(&nullSpace);CHKERRQ(ierr); 9805a93c429eSMatthew G. Knepley } 9806a93c429eSMatthew G. Knepley } 9807a93c429eSMatthew G. Knepley PetscFunctionReturn(0); 9808a93c429eSMatthew G. Knepley } 9809c0f0dcc3SMatthew G. Knepley 9810c0f0dcc3SMatthew G. Knepley /*@ 9811c0f0dcc3SMatthew G. Knepley DMPlexMonitorThroughput - Report the cell throughput of FE integration 9812c0f0dcc3SMatthew G. Knepley 9813c0f0dcc3SMatthew G. Knepley Input Parameter: 9814c0f0dcc3SMatthew G. Knepley - dm - The DM 9815c0f0dcc3SMatthew G. Knepley 9816c0f0dcc3SMatthew G. Knepley Level: developer 9817c0f0dcc3SMatthew G. Knepley 9818c0f0dcc3SMatthew G. Knepley Options Database Keys: 9819c0f0dcc3SMatthew G. Knepley . -dm_plex_monitor_throughput - Activate the monitor 9820c0f0dcc3SMatthew G. Knepley 9821c0f0dcc3SMatthew G. Knepley .seealso: DMSetFromOptions(), DMPlexCreate() 9822c0f0dcc3SMatthew G. Knepley @*/ 9823c0f0dcc3SMatthew G. Knepley PetscErrorCode DMPlexMonitorThroughput(DM dm, void *dummy) 9824c0f0dcc3SMatthew G. Knepley { 9825e5ed2c37SJose E. Roman #if defined(PETSC_USE_LOG) 9826c0f0dcc3SMatthew G. Knepley PetscStageLog stageLog; 9827c0f0dcc3SMatthew G. Knepley PetscLogEvent event; 9828c0f0dcc3SMatthew G. Knepley PetscLogStage stage; 9829c0f0dcc3SMatthew G. Knepley PetscEventPerfInfo eventInfo; 9830c0f0dcc3SMatthew G. Knepley PetscReal cellRate, flopRate; 9831c0f0dcc3SMatthew G. Knepley PetscInt cStart, cEnd, Nf, N; 9832c0f0dcc3SMatthew G. Knepley const char *name; 9833c0f0dcc3SMatthew G. Knepley PetscErrorCode ierr; 9834e5ed2c37SJose E. Roman #endif 9835c0f0dcc3SMatthew G. Knepley 9836c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 9837c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9838c0f0dcc3SMatthew G. Knepley #if defined(PETSC_USE_LOG) 9839c0f0dcc3SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) dm, &name);CHKERRQ(ierr); 9840c0f0dcc3SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 9841c0f0dcc3SMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 9842c0f0dcc3SMatthew G. Knepley ierr = PetscLogGetStageLog(&stageLog);CHKERRQ(ierr); 9843c0f0dcc3SMatthew G. Knepley ierr = PetscStageLogGetCurrent(stageLog, &stage);CHKERRQ(ierr); 9844c0f0dcc3SMatthew G. Knepley ierr = PetscLogEventGetId("DMPlexResidualFE", &event);CHKERRQ(ierr); 9845c0f0dcc3SMatthew G. Knepley ierr = PetscLogEventGetPerfInfo(stage, event, &eventInfo);CHKERRQ(ierr); 9846c0f0dcc3SMatthew G. Knepley N = (cEnd - cStart)*Nf*eventInfo.count; 9847c0f0dcc3SMatthew G. Knepley flopRate = eventInfo.flops/eventInfo.time; 9848c0f0dcc3SMatthew G. Knepley cellRate = N/eventInfo.time; 9849fae64647SBarry 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); 9850c0f0dcc3SMatthew G. Knepley #else 9851c0f0dcc3SMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Plex Throughput Monitor is not supported if logging is turned off. Reconfigure using --with-log."); 9852c0f0dcc3SMatthew G. Knepley #endif 9853c0f0dcc3SMatthew G. Knepley PetscFunctionReturn(0); 9854c0f0dcc3SMatthew G. Knepley } 9855