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 */ 12*02f7d72cSksagiyam 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); 135e630c359SToby Isaac ierr = PetscInfo2((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); 1678135c375SStefano Zampini if (dim != 2) SETERRQ1(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); 241d1df6f1dSMatthew G. Knepley if (numVals % Nc) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "The number of components %D does not divide the number of values in the closure %D", Nc, numVals); 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; 251d1df6f1dSMatthew G. Knepley default: SETERRQ1(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; 266e412dcbdSMatthew G. Knepley default: SETERRQ1(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); 32882f516ccSBarry Smith if (!dm) SETERRQ(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); 39682f516ccSBarry Smith if (!dm) SETERRQ(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); 4512c4c0c81SMatthew G. Knepley if (!dm) SETERRQ(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); 5032c40f234SMatthew G. Knepley if (!dm) SETERRQ(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); 5322c40f234SMatthew G. Knepley if (!dm) SETERRQ(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); 562d930f514SMatthew G. Knepley if (!dm) SETERRQ(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: 66719ad8254SMatthew G. Knepley if (dim != 2) SETERRQ1(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: 67219ad8254SMatthew G. Knepley if (dim != 3) SETERRQ1(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: 67819ad8254SMatthew G. Knepley if (dim != 3) SETERRQ1(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); 75519ad8254SMatthew G. Knepley if (Nf != 1) SETERRQ1(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); 830b7f6ffafSMatthew G. Knepley if (flg && n != dim+1) SETERRQ2(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); 832b7f6ffafSMatthew G. Knepley if (flg && n != dim+1) SETERRQ2(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); 848202fd40aSStefano Zampini if (flg && plotEdges && depth < dim) SETERRQ(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); 932f6dae198SJed Brown if (PetscUnlikely(dof > 3)) SETERRQ2(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); 970b7f6ffafSMatthew G. Knepley if (coneSize != 2) SETERRQ2(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); 1056b7f6ffafSMatthew G. Knepley if (ne != 1) SETERRQ2(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); 12040f7d6e4aSStefano Zampini if (numVertices != cum) SETERRQ2(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; 1266a57dd577SMatthew G Knepley PetscInt numLabels, l; 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; 1284d80ece95SMatthew G. Knepley ierr = PetscCalloc3(size,&sizes,size,&hybsizes,size,&ghostsizes);CHKERRQ(ierr); 1285412e9a14SMatthew G. Knepley for (d = 0; d <= depth; d++) { 1286412e9a14SMatthew G. Knepley PetscInt Nc[2] = {0, 0}, ict; 1287412e9a14SMatthew G. Knepley 1288552f7358SJed Brown ierr = DMPlexGetDepthStratum(dm, d, &pStart, &pEnd);CHKERRQ(ierr); 12899318fe57SMatthew G. Knepley if (pStart < pEnd) {ierr = DMPlexGetCellType(dm, pStart, &ct0);CHKERRQ(ierr);} 1290412e9a14SMatthew G. Knepley ict = ct0; 1291ffc4695bSBarry Smith ierr = MPI_Bcast(&ict, 1, MPIU_INT, 0, comm);CHKERRMPI(ierr); 1292412e9a14SMatthew G. Knepley ct0 = (DMPolytopeType) ict; 1293412e9a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 1294412e9a14SMatthew G. Knepley DMPolytopeType ct; 1295412e9a14SMatthew G. Knepley 1296412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 1297412e9a14SMatthew G. Knepley if (ct == ct0) ++Nc[0]; 1298412e9a14SMatthew G. Knepley else ++Nc[1]; 1299412e9a14SMatthew G. Knepley } 1300ffc4695bSBarry Smith ierr = MPI_Gather(&Nc[0], 1, MPIU_INT, sizes, 1, MPIU_INT, 0, comm);CHKERRMPI(ierr); 1301ffc4695bSBarry Smith ierr = MPI_Gather(&Nc[1], 1, MPIU_INT, hybsizes, 1, MPIU_INT, 0, comm);CHKERRMPI(ierr); 1302ffc4695bSBarry Smith if (d == depth) {ierr = MPI_Gather(&gcNum, 1, MPIU_INT, ghostsizes, 1, MPIU_INT, 0, comm);CHKERRMPI(ierr);} 1303412e9a14SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " %D-cells:", (depth == 1) && d ? dim : d);CHKERRQ(ierr); 1304834065abSMatthew G. Knepley for (p = 0; p < size; ++p) { 1305dd400576SPatrick Sanan if (rank == 0) { 1306412e9a14SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " %D", sizes[p]+hybsizes[p]);CHKERRQ(ierr); 1307412e9a14SMatthew G. Knepley if (hybsizes[p] > 0) {ierr = PetscViewerASCIIPrintf(viewer, " (%D)", hybsizes[p]);CHKERRQ(ierr);} 1308412e9a14SMatthew G. Knepley if (ghostsizes[p] > 0) {ierr = PetscViewerASCIIPrintf(viewer, " [%D]", ghostsizes[p]);CHKERRQ(ierr);} 1309834065abSMatthew G. Knepley } 1310cbb7f117SMark Adams } 1311552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, "\n");CHKERRQ(ierr); 1312552f7358SJed Brown } 1313d80ece95SMatthew G. Knepley ierr = PetscFree3(sizes,hybsizes,ghostsizes);CHKERRQ(ierr); 13149318fe57SMatthew G. Knepley { 13159318fe57SMatthew G. Knepley const PetscReal *maxCell; 13169318fe57SMatthew G. Knepley const PetscReal *L; 13179318fe57SMatthew G. Knepley const DMBoundaryType *bd; 13189318fe57SMatthew G. Knepley PetscBool per, localized; 13199318fe57SMatthew G. Knepley 13209318fe57SMatthew G. Knepley ierr = DMGetPeriodicity(dm, &per, &maxCell, &L, &bd);CHKERRQ(ierr); 13219318fe57SMatthew G. Knepley ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 13229318fe57SMatthew G. Knepley if (per) { 13239318fe57SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "Periodic mesh (");CHKERRQ(ierr); 13249318fe57SMatthew G. Knepley ierr = PetscViewerASCIIUseTabs(viewer, PETSC_FALSE);CHKERRQ(ierr); 13259318fe57SMatthew G. Knepley for (d = 0; d < dim; ++d) { 13269318fe57SMatthew G. Knepley if (bd && d > 0) {ierr = PetscViewerASCIIPrintf(viewer, ", ");CHKERRQ(ierr);} 13279318fe57SMatthew G. Knepley if (bd) {ierr = PetscViewerASCIIPrintf(viewer, "%s", DMBoundaryTypes[bd[d]]);CHKERRQ(ierr);} 13289318fe57SMatthew G. Knepley } 13299318fe57SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, ") coordinates %s\n", localized ? "localized" : "not localized");CHKERRQ(ierr); 13309318fe57SMatthew G. Knepley ierr = PetscViewerASCIIUseTabs(viewer, PETSC_TRUE);CHKERRQ(ierr); 13319318fe57SMatthew G. Knepley } 13329318fe57SMatthew G. Knepley } 1333c58f1c22SToby Isaac ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 1334a57dd577SMatthew G Knepley if (numLabels) {ierr = PetscViewerASCIIPrintf(viewer, "Labels:\n");CHKERRQ(ierr);} 1335a57dd577SMatthew G Knepley for (l = 0; l < numLabels; ++l) { 1336a57dd577SMatthew G Knepley DMLabel label; 1337a57dd577SMatthew G Knepley const char *name; 1338a57dd577SMatthew G Knepley IS valueIS; 1339a57dd577SMatthew G Knepley const PetscInt *values; 1340a57dd577SMatthew G Knepley PetscInt numValues, v; 1341a57dd577SMatthew G Knepley 1342c58f1c22SToby Isaac ierr = DMGetLabelName(dm, l, &name);CHKERRQ(ierr); 1343c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 1344a57dd577SMatthew G Knepley ierr = DMLabelGetNumValues(label, &numValues);CHKERRQ(ierr); 1345d72f73ffSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " %s: %D strata with value/size (", name, numValues);CHKERRQ(ierr); 1346a57dd577SMatthew G Knepley ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 1347a57dd577SMatthew G Knepley ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 1348120dea56SMatthew G. Knepley ierr = PetscViewerASCIIUseTabs(viewer, PETSC_FALSE);CHKERRQ(ierr); 1349a57dd577SMatthew G Knepley for (v = 0; v < numValues; ++v) { 1350a57dd577SMatthew G Knepley PetscInt size; 1351a57dd577SMatthew G Knepley 1352a57dd577SMatthew G Knepley ierr = DMLabelGetStratumSize(label, values[v], &size);CHKERRQ(ierr); 1353a57dd577SMatthew G Knepley if (v > 0) {ierr = PetscViewerASCIIPrintf(viewer, ", ");CHKERRQ(ierr);} 1354d72f73ffSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "%D (%D)", values[v], size);CHKERRQ(ierr); 1355a57dd577SMatthew G Knepley } 1356a57dd577SMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, ")\n");CHKERRQ(ierr); 1357120dea56SMatthew G. Knepley ierr = PetscViewerASCIIUseTabs(viewer, PETSC_TRUE);CHKERRQ(ierr); 1358a57dd577SMatthew G Knepley ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 13594d41221fSMatthew G Knepley ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 1360a57dd577SMatthew G Knepley } 1361c1cad2e7SMatthew G. Knepley { 1362c1cad2e7SMatthew G. Knepley char **labelNames; 1363c1cad2e7SMatthew G. Knepley PetscInt Nl = numLabels; 1364c1cad2e7SMatthew G. Knepley PetscBool flg; 1365c1cad2e7SMatthew G. Knepley 1366c1cad2e7SMatthew G. Knepley ierr = PetscMalloc1(Nl, &labelNames);CHKERRQ(ierr); 1367c1cad2e7SMatthew G. Knepley ierr = PetscOptionsGetStringArray(((PetscObject) dm)->options, ((PetscObject) dm)->prefix, "-dm_plex_view_labels", labelNames, &Nl, &flg);CHKERRQ(ierr); 1368c1cad2e7SMatthew G. Knepley for (l = 0; l < Nl; ++l) { 1369c1cad2e7SMatthew G. Knepley DMLabel label; 1370c1cad2e7SMatthew G. Knepley 1371c1cad2e7SMatthew G. Knepley ierr = DMHasLabel(dm, labelNames[l], &flg);CHKERRQ(ierr); 1372c1cad2e7SMatthew G. Knepley if (flg) { 1373c1cad2e7SMatthew G. Knepley ierr = DMGetLabel(dm, labelNames[l], &label);CHKERRQ(ierr); 1374c1cad2e7SMatthew G. Knepley ierr = DMLabelView(label, viewer);CHKERRQ(ierr); 1375c1cad2e7SMatthew G. Knepley } 1376c1cad2e7SMatthew G. Knepley ierr = PetscFree(labelNames[l]);CHKERRQ(ierr); 1377c1cad2e7SMatthew G. Knepley } 1378c1cad2e7SMatthew G. Knepley ierr = PetscFree(labelNames);CHKERRQ(ierr); 1379c1cad2e7SMatthew G. Knepley } 138034aa8a36SMatthew G. Knepley /* If no fields are specified, people do not want to see adjacency */ 138134aa8a36SMatthew G. Knepley if (dm->Nf) { 138234aa8a36SMatthew G. Knepley PetscInt f; 138334aa8a36SMatthew G. Knepley 138434aa8a36SMatthew G. Knepley for (f = 0; f < dm->Nf; ++f) { 138534aa8a36SMatthew G. Knepley const char *name; 138634aa8a36SMatthew G. Knepley 138734aa8a36SMatthew G. Knepley ierr = PetscObjectGetName(dm->fields[f].disc, &name);CHKERRQ(ierr); 138834aa8a36SMatthew G. Knepley if (numLabels) {ierr = PetscViewerASCIIPrintf(viewer, "Field %s:\n", name);CHKERRQ(ierr);} 138934aa8a36SMatthew G. Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 139034aa8a36SMatthew G. Knepley if (dm->fields[f].label) {ierr = DMLabelView(dm->fields[f].label, viewer);CHKERRQ(ierr);} 139134aa8a36SMatthew G. Knepley if (dm->fields[f].adjacency[0]) { 139234aa8a36SMatthew G. Knepley if (dm->fields[f].adjacency[1]) {ierr = PetscViewerASCIIPrintf(viewer, "adjacency FVM++\n");CHKERRQ(ierr);} 1393ed59e46eSMatthew G. Knepley else {ierr = PetscViewerASCIIPrintf(viewer, "adjacency FVM\n");CHKERRQ(ierr);} 139434aa8a36SMatthew G. Knepley } else { 139534aa8a36SMatthew G. Knepley if (dm->fields[f].adjacency[1]) {ierr = PetscViewerASCIIPrintf(viewer, "adjacency FEM\n");CHKERRQ(ierr);} 139634aa8a36SMatthew G. Knepley else {ierr = PetscViewerASCIIPrintf(viewer, "adjacency FUNKY\n");CHKERRQ(ierr);} 139734aa8a36SMatthew G. Knepley } 139834aa8a36SMatthew G. Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 139934aa8a36SMatthew G. Knepley } 140034aa8a36SMatthew G. Knepley } 1401a8fb8f29SToby Isaac ierr = DMGetCoarseDM(dm, &cdm);CHKERRQ(ierr); 14028e7ff633SMatthew G. Knepley if (cdm) { 14038e7ff633SMatthew G. Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 14048e7ff633SMatthew G. Knepley ierr = DMPlexView_Ascii(cdm, viewer);CHKERRQ(ierr); 14058e7ff633SMatthew G. Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 14068e7ff633SMatthew G. Knepley } 1407552f7358SJed Brown } 1408552f7358SJed Brown PetscFunctionReturn(0); 1409552f7358SJed Brown } 1410552f7358SJed Brown 1411e5c487bfSMatthew G. Knepley static PetscErrorCode DMPlexDrawCell(DM dm, PetscDraw draw, PetscInt cell, const PetscScalar coords[]) 1412e5c487bfSMatthew G. Knepley { 1413e5c487bfSMatthew G. Knepley DMPolytopeType ct; 1414e5c487bfSMatthew G. Knepley PetscMPIInt rank; 1415a12d352dSMatthew G. Knepley PetscInt cdim; 1416e5c487bfSMatthew G. Knepley PetscErrorCode ierr; 1417e5c487bfSMatthew G. Knepley 1418e5c487bfSMatthew G. Knepley PetscFunctionBegin; 1419ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject) dm), &rank);CHKERRMPI(ierr); 1420e5c487bfSMatthew G. Knepley ierr = DMPlexGetCellType(dm, cell, &ct);CHKERRQ(ierr); 1421a12d352dSMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr); 1422e5c487bfSMatthew G. Knepley switch (ct) { 1423a12d352dSMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 1424a12d352dSMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 1425a12d352dSMatthew G. Knepley switch (cdim) { 1426a12d352dSMatthew G. Knepley case 1: 1427a12d352dSMatthew G. Knepley { 1428a12d352dSMatthew G. Knepley const PetscReal y = 0.5; /* TODO Put it in the middle of the viewport */ 1429a12d352dSMatthew G. Knepley const PetscReal dy = 0.05; /* TODO Make it a fraction of the total length */ 1430a12d352dSMatthew G. Knepley 1431a12d352dSMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[0]), y, PetscRealPart(coords[1]), y, PETSC_DRAW_BLACK);CHKERRQ(ierr); 1432a12d352dSMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[0]), y+dy, PetscRealPart(coords[0]), y-dy, PETSC_DRAW_BLACK);CHKERRQ(ierr); 1433a12d352dSMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[1]), y+dy, PetscRealPart(coords[1]), y-dy, PETSC_DRAW_BLACK);CHKERRQ(ierr); 1434a12d352dSMatthew G. Knepley } 1435a12d352dSMatthew G. Knepley break; 1436a12d352dSMatthew G. Knepley case 2: 1437a12d352dSMatthew G. Knepley { 1438a12d352dSMatthew G. Knepley const PetscReal dx = (PetscRealPart(coords[3]) - PetscRealPart(coords[1])); 1439a12d352dSMatthew G. Knepley const PetscReal dy = (PetscRealPart(coords[2]) - PetscRealPart(coords[0])); 1440a12d352dSMatthew G. Knepley const PetscReal l = 0.1/PetscSqrtReal(dx*dx + dy*dy); 1441a12d352dSMatthew G. Knepley 1442a12d352dSMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[0]), PetscRealPart(coords[1]), PetscRealPart(coords[2]), PetscRealPart(coords[3]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 1443a12d352dSMatthew 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); 1444a12d352dSMatthew 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); 1445a12d352dSMatthew G. Knepley } 1446a12d352dSMatthew G. Knepley break; 1447a12d352dSMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot draw cells of dimension %D", cdim); 1448a12d352dSMatthew G. Knepley } 1449a12d352dSMatthew G. Knepley break; 1450e5c487bfSMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 1451e5c487bfSMatthew G. Knepley ierr = PetscDrawTriangle(draw, PetscRealPart(coords[0]), PetscRealPart(coords[1]), PetscRealPart(coords[2]), PetscRealPart(coords[3]), PetscRealPart(coords[4]), PetscRealPart(coords[5]), 1452e5c487bfSMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2, 1453e5c487bfSMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2, 1454e5c487bfSMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2);CHKERRQ(ierr); 1455e5c487bfSMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[0]), PetscRealPart(coords[1]), PetscRealPart(coords[2]), PetscRealPart(coords[3]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 1456e5c487bfSMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[2]), PetscRealPart(coords[3]), PetscRealPart(coords[4]), PetscRealPart(coords[5]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 1457e5c487bfSMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[4]), PetscRealPart(coords[5]), PetscRealPart(coords[0]), PetscRealPart(coords[1]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 1458e5c487bfSMatthew G. Knepley break; 1459e5c487bfSMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 1460e5c487bfSMatthew G. Knepley ierr = PetscDrawTriangle(draw, PetscRealPart(coords[0]), PetscRealPart(coords[1]), PetscRealPart(coords[2]), PetscRealPart(coords[3]), PetscRealPart(coords[4]), PetscRealPart(coords[5]), 1461e5c487bfSMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2, 1462e5c487bfSMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2, 1463e5c487bfSMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2);CHKERRQ(ierr); 1464e5c487bfSMatthew G. Knepley ierr = PetscDrawTriangle(draw, PetscRealPart(coords[0]), PetscRealPart(coords[1]), PetscRealPart(coords[4]), PetscRealPart(coords[5]), PetscRealPart(coords[6]), PetscRealPart(coords[7]), 1465e5c487bfSMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2, 1466e5c487bfSMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2, 1467e5c487bfSMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2);CHKERRQ(ierr); 1468e5c487bfSMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[0]), PetscRealPart(coords[1]), PetscRealPart(coords[2]), PetscRealPart(coords[3]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 1469e5c487bfSMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[2]), PetscRealPart(coords[3]), PetscRealPart(coords[4]), PetscRealPart(coords[5]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 1470e5c487bfSMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[4]), PetscRealPart(coords[5]), PetscRealPart(coords[6]), PetscRealPart(coords[7]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 1471e5c487bfSMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[6]), PetscRealPart(coords[7]), PetscRealPart(coords[0]), PetscRealPart(coords[1]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 1472e5c487bfSMatthew G. Knepley break; 1473e5c487bfSMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot draw cells of type %s", DMPolytopeTypes[ct]); 1474e5c487bfSMatthew G. Knepley } 1475e5c487bfSMatthew G. Knepley PetscFunctionReturn(0); 1476e5c487bfSMatthew G. Knepley } 1477e5c487bfSMatthew G. Knepley 1478e5c487bfSMatthew G. Knepley static PetscErrorCode DMPlexDrawCellHighOrder(DM dm, PetscDraw draw, PetscInt cell, const PetscScalar coords[], PetscInt edgeDiv, PetscReal refCoords[], PetscReal edgeCoords[]) 1479e5c487bfSMatthew G. Knepley { 1480e5c487bfSMatthew G. Knepley DMPolytopeType ct; 1481e5c487bfSMatthew G. Knepley PetscReal centroid[2] = {0., 0.}; 1482e5c487bfSMatthew G. Knepley PetscMPIInt rank; 1483e5c487bfSMatthew G. Knepley PetscInt fillColor, v, e, d; 1484e5c487bfSMatthew G. Knepley PetscErrorCode ierr; 1485e5c487bfSMatthew G. Knepley 1486e5c487bfSMatthew G. Knepley PetscFunctionBegin; 1487ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject) dm), &rank);CHKERRMPI(ierr); 1488e5c487bfSMatthew G. Knepley ierr = DMPlexGetCellType(dm, cell, &ct);CHKERRQ(ierr); 1489e5c487bfSMatthew G. Knepley fillColor = PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2; 1490e5c487bfSMatthew G. Knepley switch (ct) { 1491e5c487bfSMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 1492e5c487bfSMatthew G. Knepley { 1493e5c487bfSMatthew G. Knepley PetscReal refVertices[6] = {-1., -1., 1., -1., -1., 1.}; 1494e5c487bfSMatthew G. Knepley 1495e5c487bfSMatthew G. Knepley for (v = 0; v < 3; ++v) {centroid[0] += PetscRealPart(coords[v*2+0])/3.;centroid[1] += PetscRealPart(coords[v*2+1])/3.;} 1496e5c487bfSMatthew G. Knepley for (e = 0; e < 3; ++e) { 1497e5c487bfSMatthew G. Knepley refCoords[0] = refVertices[e*2+0]; 1498e5c487bfSMatthew G. Knepley refCoords[1] = refVertices[e*2+1]; 1499e5c487bfSMatthew G. Knepley for (d = 1; d <= edgeDiv; ++d) { 1500e5c487bfSMatthew G. Knepley refCoords[d*2+0] = refCoords[0] + (refVertices[(e+1)%3 * 2 + 0] - refCoords[0])*d/edgeDiv; 1501e5c487bfSMatthew G. Knepley refCoords[d*2+1] = refCoords[1] + (refVertices[(e+1)%3 * 2 + 1] - refCoords[1])*d/edgeDiv; 1502e5c487bfSMatthew G. Knepley } 1503e5c487bfSMatthew G. Knepley ierr = DMPlexReferenceToCoordinates(dm, cell, edgeDiv+1, refCoords, edgeCoords);CHKERRQ(ierr); 1504e5c487bfSMatthew G. Knepley for (d = 0; d < edgeDiv; ++d) { 1505e5c487bfSMatthew 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); 1506e5c487bfSMatthew 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); 1507e5c487bfSMatthew G. Knepley } 1508e5c487bfSMatthew G. Knepley } 1509e5c487bfSMatthew G. Knepley } 1510e5c487bfSMatthew G. Knepley break; 1511e5c487bfSMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot draw cells of type %s", DMPolytopeTypes[ct]); 1512e5c487bfSMatthew G. Knepley } 1513e5c487bfSMatthew G. Knepley PetscFunctionReturn(0); 1514e5c487bfSMatthew G. Knepley } 1515e5c487bfSMatthew G. Knepley 15167cd05799SMatthew G. Knepley static PetscErrorCode DMPlexView_Draw(DM dm, PetscViewer viewer) 1517e412dcbdSMatthew G. Knepley { 1518e412dcbdSMatthew G. Knepley PetscDraw draw; 1519e412dcbdSMatthew G. Knepley DM cdm; 1520e412dcbdSMatthew G. Knepley PetscSection coordSection; 1521e412dcbdSMatthew G. Knepley Vec coordinates; 1522e412dcbdSMatthew G. Knepley const PetscScalar *coords; 152329494db1SLisandro Dalcin PetscReal xyl[2],xyr[2],bound[4] = {PETSC_MAX_REAL, PETSC_MAX_REAL, PETSC_MIN_REAL, PETSC_MIN_REAL}; 1524e5c487bfSMatthew G. Knepley PetscReal *refCoords, *edgeCoords; 1525e5c487bfSMatthew G. Knepley PetscBool isnull, drawAffine = PETSC_TRUE; 1526e5c487bfSMatthew G. Knepley PetscInt dim, vStart, vEnd, cStart, cEnd, c, N, edgeDiv = 4; 1527e412dcbdSMatthew G. Knepley PetscErrorCode ierr; 1528e412dcbdSMatthew G. Knepley 1529e412dcbdSMatthew G. Knepley PetscFunctionBegin; 1530e412dcbdSMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dim);CHKERRQ(ierr); 1531a12d352dSMatthew G. Knepley if (dim > 2) SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Cannot draw meshes of dimension %D", dim); 1532e5c487bfSMatthew G. Knepley ierr = PetscOptionsGetBool(((PetscObject) dm)->options, ((PetscObject) dm)->prefix, "-dm_view_draw_affine", &drawAffine, NULL);CHKERRQ(ierr); 1533e5c487bfSMatthew G. Knepley if (!drawAffine) {ierr = PetscMalloc2((edgeDiv+1)*dim, &refCoords, (edgeDiv+1)*dim, &edgeCoords);CHKERRQ(ierr);} 1534e412dcbdSMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 153592fd8e1eSJed Brown ierr = DMGetLocalSection(cdm, &coordSection);CHKERRQ(ierr); 1536e412dcbdSMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 1537e412dcbdSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 1538e412dcbdSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 1539e412dcbdSMatthew G. Knepley 1540e412dcbdSMatthew G. Knepley ierr = PetscViewerDrawGetDraw(viewer, 0, &draw);CHKERRQ(ierr); 1541e412dcbdSMatthew G. Knepley ierr = PetscDrawIsNull(draw, &isnull);CHKERRQ(ierr); 1542e412dcbdSMatthew G. Knepley if (isnull) PetscFunctionReturn(0); 1543e412dcbdSMatthew G. Knepley ierr = PetscDrawSetTitle(draw, "Mesh");CHKERRQ(ierr); 1544e412dcbdSMatthew G. Knepley 1545e412dcbdSMatthew G. Knepley ierr = VecGetLocalSize(coordinates, &N);CHKERRQ(ierr); 1546e412dcbdSMatthew G. Knepley ierr = VecGetArrayRead(coordinates, &coords);CHKERRQ(ierr); 1547e412dcbdSMatthew G. Knepley for (c = 0; c < N; c += dim) { 15480c81f2a8SMatthew G. Knepley bound[0] = PetscMin(bound[0], PetscRealPart(coords[c])); bound[2] = PetscMax(bound[2], PetscRealPart(coords[c])); 15490c81f2a8SMatthew G. Knepley bound[1] = PetscMin(bound[1], PetscRealPart(coords[c+1])); bound[3] = PetscMax(bound[3], PetscRealPart(coords[c+1])); 1550e412dcbdSMatthew G. Knepley } 1551e412dcbdSMatthew G. Knepley ierr = VecRestoreArrayRead(coordinates, &coords);CHKERRQ(ierr); 1552820f2d46SBarry Smith ierr = MPIU_Allreduce(&bound[0],xyl,2,MPIU_REAL,MPIU_MIN,PetscObjectComm((PetscObject)dm));CHKERRMPI(ierr); 1553820f2d46SBarry Smith ierr = MPIU_Allreduce(&bound[2],xyr,2,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)dm));CHKERRMPI(ierr); 155429494db1SLisandro Dalcin ierr = PetscDrawSetCoordinates(draw, xyl[0], xyl[1], xyr[0], xyr[1]);CHKERRQ(ierr); 1555e412dcbdSMatthew G. Knepley ierr = PetscDrawClear(draw);CHKERRQ(ierr); 1556e412dcbdSMatthew G. Knepley 1557cf3064d3SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 1558cf3064d3SMatthew G. Knepley PetscScalar *coords = NULL; 1559ba2698f1SMatthew G. Knepley PetscInt numCoords; 1560cf3064d3SMatthew G. Knepley 1561e5c487bfSMatthew G. Knepley ierr = DMPlexVecGetClosureAtDepth_Internal(dm, coordSection, coordinates, c, 0, &numCoords, &coords);CHKERRQ(ierr); 1562e5c487bfSMatthew G. Knepley if (drawAffine) { 1563e5c487bfSMatthew G. Knepley ierr = DMPlexDrawCell(dm, draw, c, coords);CHKERRQ(ierr); 1564e5c487bfSMatthew G. Knepley } else { 1565e5c487bfSMatthew G. Knepley ierr = DMPlexDrawCellHighOrder(dm, draw, c, coords, edgeDiv, refCoords, edgeCoords);CHKERRQ(ierr); 1566cf3064d3SMatthew G. Knepley } 1567cf3064d3SMatthew G. Knepley ierr = DMPlexVecRestoreClosure(dm, coordSection, coordinates, c, &numCoords, &coords);CHKERRQ(ierr); 1568cf3064d3SMatthew G. Knepley } 1569e5c487bfSMatthew G. Knepley if (!drawAffine) {ierr = PetscFree2(refCoords, edgeCoords);CHKERRQ(ierr);} 1570e412dcbdSMatthew G. Knepley ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 1571e412dcbdSMatthew G. Knepley ierr = PetscDrawPause(draw);CHKERRQ(ierr); 1572e412dcbdSMatthew G. Knepley ierr = PetscDrawSave(draw);CHKERRQ(ierr); 1573e412dcbdSMatthew G. Knepley PetscFunctionReturn(0); 1574e412dcbdSMatthew G. Knepley } 1575e412dcbdSMatthew G. Knepley 15761e50132fSMatthew G. Knepley #if defined(PETSC_HAVE_EXODUSII) 15771e50132fSMatthew G. Knepley #include <exodusII.h> 15786823f3c5SBlaise Bourdin #include <petscviewerexodusii.h> 15791e50132fSMatthew G. Knepley #endif 15801e50132fSMatthew G. Knepley 1581552f7358SJed Brown PetscErrorCode DMView_Plex(DM dm, PetscViewer viewer) 1582552f7358SJed Brown { 15831e50132fSMatthew G. Knepley PetscBool iascii, ishdf5, isvtk, isdraw, flg, isglvis, isexodus; 1584002a2709SMatthew G. Knepley char name[PETSC_MAX_PATH_LEN]; 1585552f7358SJed Brown PetscErrorCode ierr; 1586552f7358SJed Brown 1587552f7358SJed Brown PetscFunctionBegin; 1588552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1589552f7358SJed Brown PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1590552f7358SJed Brown ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 1591fcf6c8fdSToby Isaac ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERVTK, &isvtk);CHKERRQ(ierr); 1592c6ccd67eSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 1593e412dcbdSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERDRAW, &isdraw);CHKERRQ(ierr); 15948135c375SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERGLVIS, &isglvis);CHKERRQ(ierr); 15951e50132fSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWEREXODUSII, &isexodus);CHKERRQ(ierr); 1596552f7358SJed Brown if (iascii) { 15978135c375SStefano Zampini PetscViewerFormat format; 15988135c375SStefano Zampini ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 15998135c375SStefano Zampini if (format == PETSC_VIEWER_ASCII_GLVIS) { 16008135c375SStefano Zampini ierr = DMPlexView_GLVis(dm, viewer);CHKERRQ(ierr); 16018135c375SStefano Zampini } else { 1602552f7358SJed Brown ierr = DMPlexView_Ascii(dm, viewer);CHKERRQ(ierr); 16038135c375SStefano Zampini } 1604c6ccd67eSMatthew G. Knepley } else if (ishdf5) { 1605c6ccd67eSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 160639d25373SMatthew G. Knepley ierr = DMPlexView_HDF5_Internal(dm, viewer);CHKERRQ(ierr); 1607c6ccd67eSMatthew G. Knepley #else 1608c6ccd67eSMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 1609552f7358SJed Brown #endif 1610e412dcbdSMatthew G. Knepley } else if (isvtk) { 1611fcf6c8fdSToby Isaac ierr = DMPlexVTKWriteAll((PetscObject) dm,viewer);CHKERRQ(ierr); 1612e412dcbdSMatthew G. Knepley } else if (isdraw) { 1613e412dcbdSMatthew G. Knepley ierr = DMPlexView_Draw(dm, viewer);CHKERRQ(ierr); 16148135c375SStefano Zampini } else if (isglvis) { 16158135c375SStefano Zampini ierr = DMPlexView_GLVis(dm, viewer);CHKERRQ(ierr); 16161e50132fSMatthew G. Knepley #if defined(PETSC_HAVE_EXODUSII) 16171e50132fSMatthew G. Knepley } else if (isexodus) { 16186823f3c5SBlaise Bourdin /* 16196823f3c5SBlaise Bourdin exodusII requires that all sets be part of exactly one cell set. 16206823f3c5SBlaise Bourdin If the dm does not have a "Cell Sets" label defined, we create one 16216823f3c5SBlaise Bourdin with ID 1, containig all cells. 16226823f3c5SBlaise Bourdin Note that if the Cell Sets label is defined but does not cover all cells, 16236823f3c5SBlaise Bourdin we may still have a problem. This should probably be checked here or in the viewer; 16246823f3c5SBlaise Bourdin */ 16256823f3c5SBlaise Bourdin PetscInt numCS; 16266823f3c5SBlaise Bourdin ierr = DMGetLabelSize(dm,"Cell Sets",&numCS);CHKERRQ(ierr); 16276823f3c5SBlaise Bourdin if (!numCS) { 16281e50132fSMatthew G. Knepley PetscInt cStart, cEnd, c; 16291e50132fSMatthew G. Knepley ierr = DMCreateLabel(dm, "Cell Sets");CHKERRQ(ierr); 16301e50132fSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 16311e50132fSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) {ierr = DMSetLabelValue(dm, "Cell Sets", c, 1);CHKERRQ(ierr);} 16326823f3c5SBlaise Bourdin } 16336823f3c5SBlaise Bourdin ierr = DMView_PlexExodusII(dm, viewer);CHKERRQ(ierr); 16341e50132fSMatthew G. Knepley #endif 163562201deeSVaclav Hapla } else { 1636a94aea51SVaclav Hapla SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Viewer type %s not yet supported for DMPlex writing", ((PetscObject)viewer)->type_name); 1637fcf6c8fdSToby Isaac } 1638cb3ba0daSMatthew G. Knepley /* Optionally view the partition */ 1639cb3ba0daSMatthew G. Knepley ierr = PetscOptionsHasName(((PetscObject) dm)->options, ((PetscObject) dm)->prefix, "-dm_partition_view", &flg);CHKERRQ(ierr); 1640cb3ba0daSMatthew G. Knepley if (flg) { 1641cb3ba0daSMatthew G. Knepley Vec ranks; 1642cb3ba0daSMatthew G. Knepley ierr = DMPlexCreateRankField(dm, &ranks);CHKERRQ(ierr); 1643cb3ba0daSMatthew G. Knepley ierr = VecView(ranks, viewer);CHKERRQ(ierr); 1644cb3ba0daSMatthew G. Knepley ierr = VecDestroy(&ranks);CHKERRQ(ierr); 1645cb3ba0daSMatthew G. Knepley } 1646002a2709SMatthew G. Knepley /* Optionally view a label */ 1647589a23caSBarry Smith ierr = PetscOptionsGetString(((PetscObject) dm)->options, ((PetscObject) dm)->prefix, "-dm_label_view", name, sizeof(name), &flg);CHKERRQ(ierr); 1648002a2709SMatthew G. Knepley if (flg) { 1649002a2709SMatthew G. Knepley DMLabel label; 1650002a2709SMatthew G. Knepley Vec val; 1651002a2709SMatthew G. Knepley 1652002a2709SMatthew G. Knepley ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 1653002a2709SMatthew G. Knepley if (!label) SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Label %s provided to -dm_label_view does not exist in this DM", name); 1654002a2709SMatthew G. Knepley ierr = DMPlexCreateLabelField(dm, label, &val);CHKERRQ(ierr); 1655002a2709SMatthew G. Knepley ierr = VecView(val, viewer);CHKERRQ(ierr); 1656002a2709SMatthew G. Knepley ierr = VecDestroy(&val);CHKERRQ(ierr); 1657002a2709SMatthew G. Knepley } 1658552f7358SJed Brown PetscFunctionReturn(0); 1659552f7358SJed Brown } 1660552f7358SJed Brown 16617f96f51bSksagiyam /*@ 16627f96f51bSksagiyam DMPlexTopologyView - Saves a DMPlex topology into a file 16637f96f51bSksagiyam 16647f96f51bSksagiyam Collective on DM 16657f96f51bSksagiyam 16667f96f51bSksagiyam Input Parameters: 16677f96f51bSksagiyam + dm - The DM whose topology is to be saved 16687f96f51bSksagiyam - viewer - The PetscViewer for saving 16697f96f51bSksagiyam 16707f96f51bSksagiyam Level: advanced 16717f96f51bSksagiyam 16727f96f51bSksagiyam .seealso: DMView(), DMPlexCoordinatesView(), DMPlexLabelsView(), DMPlexTopologyLoad() 16737f96f51bSksagiyam @*/ 16747f96f51bSksagiyam PetscErrorCode DMPlexTopologyView(DM dm, PetscViewer viewer) 16757f96f51bSksagiyam { 16767f96f51bSksagiyam PetscBool ishdf5; 16777f96f51bSksagiyam PetscErrorCode ierr; 16787f96f51bSksagiyam 16797f96f51bSksagiyam PetscFunctionBegin; 16807f96f51bSksagiyam PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 16817f96f51bSksagiyam PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 16827f96f51bSksagiyam ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 1683*02f7d72cSksagiyam ierr = PetscLogEventBegin(DMPLEX_TopologyView,viewer,0,0,0);CHKERRQ(ierr); 16847f96f51bSksagiyam if (ishdf5) { 16857f96f51bSksagiyam #if defined(PETSC_HAVE_HDF5) 16867f96f51bSksagiyam PetscViewerFormat format; 16877f96f51bSksagiyam ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 16887f96f51bSksagiyam if (format == PETSC_VIEWER_HDF5_PETSC || format == PETSC_VIEWER_DEFAULT || format == PETSC_VIEWER_NATIVE) { 16897f96f51bSksagiyam IS globalPointNumbering; 16907f96f51bSksagiyam 16917f96f51bSksagiyam ierr = DMPlexCreatePointNumbering(dm, &globalPointNumbering);CHKERRQ(ierr); 16927f96f51bSksagiyam ierr = DMPlexTopologyView_HDF5_Internal(dm, globalPointNumbering, viewer);CHKERRQ(ierr); 16937f96f51bSksagiyam ierr = ISDestroy(&globalPointNumbering);CHKERRQ(ierr); 16947f96f51bSksagiyam } else SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "PetscViewerFormat %s not supported for HDF5 output.", PetscViewerFormats[format]); 16957f96f51bSksagiyam #else 16967f96f51bSksagiyam SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 16977f96f51bSksagiyam #endif 16987f96f51bSksagiyam } 1699*02f7d72cSksagiyam ierr = PetscLogEventEnd(DMPLEX_TopologyView,viewer,0,0,0);CHKERRQ(ierr); 17007f96f51bSksagiyam PetscFunctionReturn(0); 17017f96f51bSksagiyam } 17027f96f51bSksagiyam 170377b8e257Sksagiyam /*@ 170477b8e257Sksagiyam DMPlexCoordinatesView - Saves DMPlex coordinates into a file 170577b8e257Sksagiyam 170677b8e257Sksagiyam Collective on DM 170777b8e257Sksagiyam 170877b8e257Sksagiyam Input Parameters: 170977b8e257Sksagiyam + dm - The DM whose coordinates are to be saved 171077b8e257Sksagiyam - viewer - The PetscViewer for saving 171177b8e257Sksagiyam 171277b8e257Sksagiyam Level: advanced 171377b8e257Sksagiyam 171477b8e257Sksagiyam .seealso: DMView(), DMPlexTopologyView(), DMPlexLabelsView(), DMPlexCoordinatesLoad() 171577b8e257Sksagiyam @*/ 171677b8e257Sksagiyam PetscErrorCode DMPlexCoordinatesView(DM dm, PetscViewer viewer) 171777b8e257Sksagiyam { 171877b8e257Sksagiyam PetscBool ishdf5; 171977b8e257Sksagiyam PetscErrorCode ierr; 172077b8e257Sksagiyam 172177b8e257Sksagiyam PetscFunctionBegin; 172277b8e257Sksagiyam PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 172377b8e257Sksagiyam PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 172477b8e257Sksagiyam ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 1725*02f7d72cSksagiyam ierr = PetscLogEventBegin(DMPLEX_CoordinatesView,viewer,0,0,0);CHKERRQ(ierr); 172677b8e257Sksagiyam if (ishdf5) { 172777b8e257Sksagiyam #if defined(PETSC_HAVE_HDF5) 172877b8e257Sksagiyam PetscViewerFormat format; 172977b8e257Sksagiyam ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 173077b8e257Sksagiyam if (format == PETSC_VIEWER_HDF5_PETSC || format == PETSC_VIEWER_DEFAULT || format == PETSC_VIEWER_NATIVE) { 173177b8e257Sksagiyam ierr = DMPlexCoordinatesView_HDF5_Internal(dm, viewer);CHKERRQ(ierr); 173277b8e257Sksagiyam } else SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "PetscViewerFormat %s not supported for HDF5 input.", PetscViewerFormats[format]); 173377b8e257Sksagiyam #else 173477b8e257Sksagiyam SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 173577b8e257Sksagiyam #endif 173677b8e257Sksagiyam } 1737*02f7d72cSksagiyam ierr = PetscLogEventEnd(DMPLEX_CoordinatesView,viewer,0,0,0);CHKERRQ(ierr); 173877b8e257Sksagiyam PetscFunctionReturn(0); 173977b8e257Sksagiyam } 174077b8e257Sksagiyam 1741bd6565f1Sksagiyam /*@ 1742bd6565f1Sksagiyam DMPlexLabelsView - Saves DMPlex labels into a file 1743bd6565f1Sksagiyam 1744bd6565f1Sksagiyam Collective on DM 1745bd6565f1Sksagiyam 1746bd6565f1Sksagiyam Input Parameters: 1747bd6565f1Sksagiyam + dm - The DM whose labels are to be saved 1748bd6565f1Sksagiyam - viewer - The PetscViewer for saving 1749bd6565f1Sksagiyam 1750bd6565f1Sksagiyam Level: advanced 1751bd6565f1Sksagiyam 1752bd6565f1Sksagiyam .seealso: DMView(), DMPlexTopologyView(), DMPlexCoordinatesView(), DMPlexLabelsLoad() 1753bd6565f1Sksagiyam @*/ 1754bd6565f1Sksagiyam PetscErrorCode DMPlexLabelsView(DM dm, PetscViewer viewer) 1755bd6565f1Sksagiyam { 1756bd6565f1Sksagiyam PetscBool ishdf5; 1757bd6565f1Sksagiyam PetscErrorCode ierr; 1758bd6565f1Sksagiyam 1759bd6565f1Sksagiyam PetscFunctionBegin; 1760bd6565f1Sksagiyam PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1761bd6565f1Sksagiyam PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1762bd6565f1Sksagiyam ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 1763*02f7d72cSksagiyam ierr = PetscLogEventBegin(DMPLEX_LabelsView,viewer,0,0,0);CHKERRQ(ierr); 1764bd6565f1Sksagiyam if (ishdf5) { 1765bd6565f1Sksagiyam #if defined(PETSC_HAVE_HDF5) 1766bd6565f1Sksagiyam IS globalPointNumbering; 1767bd6565f1Sksagiyam PetscViewerFormat format; 1768bd6565f1Sksagiyam 1769bd6565f1Sksagiyam ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 1770bd6565f1Sksagiyam if (format == PETSC_VIEWER_HDF5_PETSC || format == PETSC_VIEWER_DEFAULT || format == PETSC_VIEWER_NATIVE) { 1771bd6565f1Sksagiyam ierr = DMPlexCreatePointNumbering(dm, &globalPointNumbering);CHKERRQ(ierr); 1772bd6565f1Sksagiyam ierr = DMPlexLabelsView_HDF5_Internal(dm, globalPointNumbering, viewer);CHKERRQ(ierr); 1773bd6565f1Sksagiyam ierr = ISDestroy(&globalPointNumbering);CHKERRQ(ierr); 1774bd6565f1Sksagiyam } else SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "PetscViewerFormat %s not supported for HDF5 input.", PetscViewerFormats[format]); 1775bd6565f1Sksagiyam #else 1776bd6565f1Sksagiyam SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 1777bd6565f1Sksagiyam #endif 1778bd6565f1Sksagiyam } 1779*02f7d72cSksagiyam ierr = PetscLogEventEnd(DMPLEX_LabelsView,viewer,0,0,0);CHKERRQ(ierr); 1780bd6565f1Sksagiyam PetscFunctionReturn(0); 1781bd6565f1Sksagiyam } 1782bd6565f1Sksagiyam 1783021affd3Sksagiyam /*@ 1784021affd3Sksagiyam DMPlexSectionView - Saves a section associated with a DMPlex 1785021affd3Sksagiyam 1786021affd3Sksagiyam Collective on DM 1787021affd3Sksagiyam 1788021affd3Sksagiyam Input Parameters: 1789021affd3Sksagiyam + dm - The DM that contains the topology on which the section to be saved is defined 1790021affd3Sksagiyam . viewer - The PetscViewer for saving 1791021affd3Sksagiyam - sectiondm - The DM that contains the section to be saved 1792021affd3Sksagiyam 1793021affd3Sksagiyam Level: advanced 1794021affd3Sksagiyam 1795021affd3Sksagiyam Notes: 1796021affd3Sksagiyam 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. 1797021affd3Sksagiyam 1798021affd3Sksagiyam 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. 1799021affd3Sksagiyam 1800021affd3Sksagiyam .seealso: DMView(), DMPlexTopologyView(), DMPlexCoordinatesView(), DMPlexLabelsView(), DMPlexGlobalVectorView(), DMPlexLocalVectorView(), PetscSectionView(), DMPlexSectionLoad() 1801021affd3Sksagiyam @*/ 1802021affd3Sksagiyam PetscErrorCode DMPlexSectionView(DM dm, PetscViewer viewer, DM sectiondm) 1803021affd3Sksagiyam { 1804021affd3Sksagiyam PetscBool ishdf5; 1805021affd3Sksagiyam PetscErrorCode ierr; 1806021affd3Sksagiyam 1807021affd3Sksagiyam PetscFunctionBegin; 1808021affd3Sksagiyam PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1809021affd3Sksagiyam PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1810021affd3Sksagiyam PetscValidHeaderSpecific(sectiondm, DM_CLASSID, 3); 1811021affd3Sksagiyam ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5);CHKERRQ(ierr); 1812*02f7d72cSksagiyam ierr = PetscLogEventBegin(DMPLEX_SectionView,viewer,0,0,0);CHKERRQ(ierr); 1813021affd3Sksagiyam if (ishdf5) { 1814021affd3Sksagiyam #if defined(PETSC_HAVE_HDF5) 1815021affd3Sksagiyam ierr = DMPlexSectionView_HDF5_Internal(dm, viewer, sectiondm);CHKERRQ(ierr); 1816021affd3Sksagiyam #else 1817021affd3Sksagiyam SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 1818021affd3Sksagiyam #endif 1819021affd3Sksagiyam } 1820*02f7d72cSksagiyam ierr = PetscLogEventEnd(DMPLEX_SectionView,viewer,0,0,0);CHKERRQ(ierr); 1821021affd3Sksagiyam PetscFunctionReturn(0); 1822021affd3Sksagiyam } 1823021affd3Sksagiyam 18243e97647fSksagiyam /*@ 18253e97647fSksagiyam DMPlexGlobalVectorView - Saves a global vector 18263e97647fSksagiyam 18273e97647fSksagiyam Collective on DM 18283e97647fSksagiyam 18293e97647fSksagiyam Input Parameters: 18303e97647fSksagiyam + dm - The DM that represents the topology 18313e97647fSksagiyam . viewer - The PetscViewer to save data with 18323e97647fSksagiyam . sectiondm - The DM that contains the global section on which vec is defined 18333e97647fSksagiyam - vec - The global vector to be saved 18343e97647fSksagiyam 18353e97647fSksagiyam Level: advanced 18363e97647fSksagiyam 18373e97647fSksagiyam Notes: 18383e97647fSksagiyam 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. 18393e97647fSksagiyam 18403e97647fSksagiyam Typical calling sequence 18413e97647fSksagiyam $ DMCreate(PETSC_COMM_WORLD, &dm); 18423e97647fSksagiyam $ DMSetType(dm, DMPLEX); 18433e97647fSksagiyam $ PetscObjectSetName((PetscObject)dm, "topologydm_name"); 18443e97647fSksagiyam $ DMClone(dm, §iondm); 18453e97647fSksagiyam $ PetscObjectSetName((PetscObject)sectiondm, "sectiondm_name"); 18463e97647fSksagiyam $ PetscSectionCreate(PETSC_COMM_WORLD, §ion); 18473e97647fSksagiyam $ DMPlexGetChart(sectiondm, &pStart, &pEnd); 18483e97647fSksagiyam $ PetscSectionSetChart(section, pStart, pEnd); 18493e97647fSksagiyam $ PetscSectionSetUp(section); 18503e97647fSksagiyam $ DMSetLocalSection(sectiondm, section); 18513e97647fSksagiyam $ PetscSectionDestroy(§ion); 18523e97647fSksagiyam $ DMGetGlobalVector(sectiondm, &vec); 18533e97647fSksagiyam $ PetscObjectSetName((PetscObject)vec, "vec_name"); 18543e97647fSksagiyam $ DMPlexTopologyView(dm, viewer); 18553e97647fSksagiyam $ DMPlexSectionView(dm, viewer, sectiondm); 18563e97647fSksagiyam $ DMPlexGlobalVectorView(dm, viewer, sectiondm, vec); 18573e97647fSksagiyam $ DMRestoreGlobalVector(sectiondm, &vec); 18583e97647fSksagiyam $ DMDestroy(§iondm); 18593e97647fSksagiyam $ DMDestroy(&dm); 18603e97647fSksagiyam 18613e97647fSksagiyam .seealso: DMPlexTopologyView(), DMPlexSectionView(), DMPlexLocalVectorView(), DMPlexGlobalVectorLoad(), DMPlexLocalVectorLoad() 18623e97647fSksagiyam @*/ 18633e97647fSksagiyam PetscErrorCode DMPlexGlobalVectorView(DM dm, PetscViewer viewer, DM sectiondm, Vec vec) 18643e97647fSksagiyam { 18653e97647fSksagiyam PetscBool ishdf5; 18663e97647fSksagiyam PetscErrorCode ierr; 18673e97647fSksagiyam 18683e97647fSksagiyam PetscFunctionBegin; 18693e97647fSksagiyam PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 18703e97647fSksagiyam PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 18713e97647fSksagiyam PetscValidHeaderSpecific(sectiondm, DM_CLASSID, 3); 18723e97647fSksagiyam PetscValidHeaderSpecific(vec, VEC_CLASSID, 4); 18733e97647fSksagiyam /* Check consistency */ 18743e97647fSksagiyam { 18753e97647fSksagiyam PetscSection section; 18763e97647fSksagiyam PetscBool includesConstraints; 18773e97647fSksagiyam PetscInt m, m1; 18783e97647fSksagiyam 18793e97647fSksagiyam ierr = VecGetLocalSize(vec, &m1);CHKERRQ(ierr); 18803e97647fSksagiyam ierr = DMGetGlobalSection(sectiondm, §ion);CHKERRQ(ierr); 18813e97647fSksagiyam ierr = PetscSectionGetIncludesConstraints(section, &includesConstraints);CHKERRQ(ierr); 18823e97647fSksagiyam if (includesConstraints) {ierr = PetscSectionGetStorageSize(section, &m);CHKERRQ(ierr);} 18833e97647fSksagiyam else {ierr = PetscSectionGetConstrainedStorageSize(section, &m);CHKERRQ(ierr);} 18843e97647fSksagiyam if (m1 != m) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Global vector size (%D) != global section storage size (%D)", m1, m); 18853e97647fSksagiyam } 18863e97647fSksagiyam ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 1887*02f7d72cSksagiyam ierr = PetscLogEventBegin(DMPLEX_GlobalVectorView,viewer,0,0,0);CHKERRQ(ierr); 18883e97647fSksagiyam if (ishdf5) { 18893e97647fSksagiyam #if defined(PETSC_HAVE_HDF5) 18903e97647fSksagiyam ierr = DMPlexGlobalVectorView_HDF5_Internal(dm, viewer, sectiondm, vec);CHKERRQ(ierr); 18913e97647fSksagiyam #else 18923e97647fSksagiyam SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 18933e97647fSksagiyam #endif 18943e97647fSksagiyam } 1895*02f7d72cSksagiyam ierr = PetscLogEventEnd(DMPLEX_GlobalVectorView,viewer,0,0,0);CHKERRQ(ierr); 18963e97647fSksagiyam PetscFunctionReturn(0); 18973e97647fSksagiyam } 18983e97647fSksagiyam 18993e97647fSksagiyam /*@ 19003e97647fSksagiyam DMPlexLocalVectorView - Saves a local vector 19013e97647fSksagiyam 19023e97647fSksagiyam Collective on DM 19033e97647fSksagiyam 19043e97647fSksagiyam Input Parameters: 19053e97647fSksagiyam + dm - The DM that represents the topology 19063e97647fSksagiyam . viewer - The PetscViewer to save data with 19073e97647fSksagiyam . sectiondm - The DM that contains the local section on which vec is defined; may be the same as dm 19083e97647fSksagiyam - vec - The local vector to be saved 19093e97647fSksagiyam 19103e97647fSksagiyam Level: advanced 19113e97647fSksagiyam 19123e97647fSksagiyam Notes: 19133e97647fSksagiyam 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. 19143e97647fSksagiyam 19153e97647fSksagiyam Typical calling sequence 19163e97647fSksagiyam $ DMCreate(PETSC_COMM_WORLD, &dm); 19173e97647fSksagiyam $ DMSetType(dm, DMPLEX); 19183e97647fSksagiyam $ PetscObjectSetName((PetscObject)dm, "topologydm_name"); 19193e97647fSksagiyam $ DMClone(dm, §iondm); 19203e97647fSksagiyam $ PetscObjectSetName((PetscObject)sectiondm, "sectiondm_name"); 19213e97647fSksagiyam $ PetscSectionCreate(PETSC_COMM_WORLD, §ion); 19223e97647fSksagiyam $ DMPlexGetChart(sectiondm, &pStart, &pEnd); 19233e97647fSksagiyam $ PetscSectionSetChart(section, pStart, pEnd); 19243e97647fSksagiyam $ PetscSectionSetUp(section); 19253e97647fSksagiyam $ DMSetLocalSection(sectiondm, section); 19263e97647fSksagiyam $ DMGetLocalVector(sectiondm, &vec); 19273e97647fSksagiyam $ PetscObjectSetName((PetscObject)vec, "vec_name"); 19283e97647fSksagiyam $ DMPlexTopologyView(dm, viewer); 19293e97647fSksagiyam $ DMPlexSectionView(dm, viewer, sectiondm); 19303e97647fSksagiyam $ DMPlexLocalVectorView(dm, viewer, sectiondm, vec); 19313e97647fSksagiyam $ DMRestoreLocalVector(sectiondm, &vec); 19323e97647fSksagiyam $ DMDestroy(§iondm); 19333e97647fSksagiyam $ DMDestroy(&dm); 19343e97647fSksagiyam 19353e97647fSksagiyam .seealso: DMPlexTopologyView(), DMPlexSectionView(), DMPlexGlobalVectorView(), DMPlexGlobalVectorLoad(), DMPlexLocalVectorLoad() 19363e97647fSksagiyam @*/ 19373e97647fSksagiyam PetscErrorCode DMPlexLocalVectorView(DM dm, PetscViewer viewer, DM sectiondm, Vec vec) 19383e97647fSksagiyam { 19393e97647fSksagiyam PetscBool ishdf5; 19403e97647fSksagiyam PetscErrorCode ierr; 19413e97647fSksagiyam 19423e97647fSksagiyam PetscFunctionBegin; 19433e97647fSksagiyam PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 19443e97647fSksagiyam PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 19453e97647fSksagiyam PetscValidHeaderSpecific(sectiondm, DM_CLASSID, 3); 19463e97647fSksagiyam PetscValidHeaderSpecific(vec, VEC_CLASSID, 4); 19473e97647fSksagiyam /* Check consistency */ 19483e97647fSksagiyam { 19493e97647fSksagiyam PetscSection section; 19503e97647fSksagiyam PetscBool includesConstraints; 19513e97647fSksagiyam PetscInt m, m1; 19523e97647fSksagiyam 19533e97647fSksagiyam ierr = VecGetLocalSize(vec, &m1);CHKERRQ(ierr); 19543e97647fSksagiyam ierr = DMGetLocalSection(sectiondm, §ion);CHKERRQ(ierr); 19553e97647fSksagiyam ierr = PetscSectionGetIncludesConstraints(section, &includesConstraints);CHKERRQ(ierr); 19563e97647fSksagiyam if (includesConstraints) {ierr = PetscSectionGetStorageSize(section, &m);CHKERRQ(ierr);} 19573e97647fSksagiyam else {ierr = PetscSectionGetConstrainedStorageSize(section, &m);CHKERRQ(ierr);} 19583e97647fSksagiyam if (m1 != m) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Local vector size (%D) != local section storage size (%D)", m1, m); 19593e97647fSksagiyam } 19603e97647fSksagiyam ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 1961*02f7d72cSksagiyam ierr = PetscLogEventBegin(DMPLEX_LocalVectorView,viewer,0,0,0);CHKERRQ(ierr); 19623e97647fSksagiyam if (ishdf5) { 19633e97647fSksagiyam #if defined(PETSC_HAVE_HDF5) 19643e97647fSksagiyam ierr = DMPlexLocalVectorView_HDF5_Internal(dm, viewer, sectiondm, vec);CHKERRQ(ierr); 19653e97647fSksagiyam #else 19663e97647fSksagiyam SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 19673e97647fSksagiyam #endif 19683e97647fSksagiyam } 1969*02f7d72cSksagiyam ierr = PetscLogEventEnd(DMPLEX_LocalVectorView,viewer,0,0,0);CHKERRQ(ierr); 19703e97647fSksagiyam PetscFunctionReturn(0); 19713e97647fSksagiyam } 19723e97647fSksagiyam 19732c40f234SMatthew G. Knepley PetscErrorCode DMLoad_Plex(DM dm, PetscViewer viewer) 19742c40f234SMatthew G. Knepley { 1975d4f5a9a0SVaclav Hapla PetscBool ishdf5; 19762c40f234SMatthew G. Knepley PetscErrorCode ierr; 19772c40f234SMatthew G. Knepley 19782c40f234SMatthew G. Knepley PetscFunctionBegin; 19792c40f234SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 19802c40f234SMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 19812c40f234SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 1982d4f5a9a0SVaclav Hapla if (ishdf5) { 19832c40f234SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 19849c48423bSVaclav Hapla PetscViewerFormat format; 19859c48423bSVaclav Hapla ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 19869c48423bSVaclav Hapla if (format == PETSC_VIEWER_HDF5_XDMF || format == PETSC_VIEWER_HDF5_VIZ) { 19879c48423bSVaclav Hapla ierr = DMPlexLoad_HDF5_Xdmf_Internal(dm, viewer);CHKERRQ(ierr); 1988509517efSVaclav Hapla } else if (format == PETSC_VIEWER_HDF5_PETSC || format == PETSC_VIEWER_DEFAULT || format == PETSC_VIEWER_NATIVE) { 198939d25373SMatthew G. Knepley ierr = DMPlexLoad_HDF5_Internal(dm, viewer);CHKERRQ(ierr); 1990509517efSVaclav Hapla } else SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "PetscViewerFormat %s not supported for HDF5 input.", PetscViewerFormats[format]); 1991b458e8f1SJose E. Roman PetscFunctionReturn(0); 19922c40f234SMatthew G. Knepley #else 19932c40f234SMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 1994552f7358SJed Brown #endif 1995b458e8f1SJose E. Roman } else SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Viewer type %s not yet supported for DMPlex loading", ((PetscObject)viewer)->type_name); 1996552f7358SJed Brown } 1997552f7358SJed Brown 1998ea8e1828Sksagiyam /*@ 1999ea8e1828Sksagiyam DMPlexTopologyLoad - Loads a topology into a DMPlex 2000ea8e1828Sksagiyam 2001ea8e1828Sksagiyam Collective on DM 2002ea8e1828Sksagiyam 2003ea8e1828Sksagiyam Input Parameters: 2004ea8e1828Sksagiyam + dm - The DM into which the topology is loaded 2005ea8e1828Sksagiyam - viewer - The PetscViewer for the saved topology 2006ea8e1828Sksagiyam 2007dec9e869Sksagiyam Output Parameters: 2008f84dd6b4Sksagiyam . 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 2009dec9e869Sksagiyam 2010ea8e1828Sksagiyam Level: advanced 2011ea8e1828Sksagiyam 2012b08ad5deSksagiyam .seealso: DMLoad(), DMPlexCoordinatesLoad(), DMPlexLabelsLoad(), DMView(), PetscViewerHDF5Open(), PetscViewerPushFormat() 2013ea8e1828Sksagiyam @*/ 2014f84dd6b4Sksagiyam PetscErrorCode DMPlexTopologyLoad(DM dm, PetscViewer viewer, PetscSF *globalToLocalPointSF) 2015ea8e1828Sksagiyam { 2016ea8e1828Sksagiyam PetscBool ishdf5; 2017ea8e1828Sksagiyam PetscErrorCode ierr; 2018ea8e1828Sksagiyam 2019ea8e1828Sksagiyam PetscFunctionBegin; 2020ea8e1828Sksagiyam PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2021ea8e1828Sksagiyam PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 2022f84dd6b4Sksagiyam if (globalToLocalPointSF) PetscValidPointer(globalToLocalPointSF, 3); 2023ea8e1828Sksagiyam ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 2024*02f7d72cSksagiyam ierr = PetscLogEventBegin(DMPLEX_TopologyLoad,viewer,0,0,0);CHKERRQ(ierr); 2025ea8e1828Sksagiyam if (ishdf5) { 2026ea8e1828Sksagiyam #if defined(PETSC_HAVE_HDF5) 2027ea8e1828Sksagiyam PetscViewerFormat format; 2028ea8e1828Sksagiyam ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 2029ea8e1828Sksagiyam if (format == PETSC_VIEWER_HDF5_PETSC || format == PETSC_VIEWER_DEFAULT || format == PETSC_VIEWER_NATIVE) { 2030f84dd6b4Sksagiyam ierr = DMPlexTopologyLoad_HDF5_Internal(dm, viewer, globalToLocalPointSF);CHKERRQ(ierr); 2031ea8e1828Sksagiyam } else SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "PetscViewerFormat %s not supported for HDF5 input.", PetscViewerFormats[format]); 2032ea8e1828Sksagiyam #else 2033ea8e1828Sksagiyam SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 2034ea8e1828Sksagiyam #endif 2035ea8e1828Sksagiyam } 2036*02f7d72cSksagiyam ierr = PetscLogEventEnd(DMPLEX_TopologyLoad,viewer,0,0,0);CHKERRQ(ierr); 2037ea8e1828Sksagiyam PetscFunctionReturn(0); 2038ea8e1828Sksagiyam } 2039ea8e1828Sksagiyam 20403e701f1cSksagiyam /*@ 20413e701f1cSksagiyam DMPlexCoordinatesLoad - Loads coordinates into a DMPlex 20423e701f1cSksagiyam 20433e701f1cSksagiyam Collective on DM 20443e701f1cSksagiyam 20453e701f1cSksagiyam Input Parameters: 20463e701f1cSksagiyam + dm - The DM into which the coordinates are loaded 2047c9ad657eSksagiyam . viewer - The PetscViewer for the saved coordinates 2048c9ad657eSksagiyam - globalToLocalPointSF - The SF returned by DMPlexTopologyLoad() when loading dm from viewer 20493e701f1cSksagiyam 20503e701f1cSksagiyam Level: advanced 20513e701f1cSksagiyam 2052b08ad5deSksagiyam .seealso: DMLoad(), DMPlexTopologyLoad(), DMPlexLabelsLoad(), DMView(), PetscViewerHDF5Open(), PetscViewerPushFormat() 20533e701f1cSksagiyam @*/ 2054c9ad657eSksagiyam PetscErrorCode DMPlexCoordinatesLoad(DM dm, PetscViewer viewer, PetscSF globalToLocalPointSF) 20553e701f1cSksagiyam { 20563e701f1cSksagiyam PetscBool ishdf5; 20573e701f1cSksagiyam PetscErrorCode ierr; 20583e701f1cSksagiyam 20593e701f1cSksagiyam PetscFunctionBegin; 20603e701f1cSksagiyam PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 20613e701f1cSksagiyam PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 2062c9ad657eSksagiyam PetscValidHeaderSpecific(globalToLocalPointSF, PETSCSF_CLASSID, 3); 20633e701f1cSksagiyam ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 2064*02f7d72cSksagiyam ierr = PetscLogEventBegin(DMPLEX_CoordinatesLoad,viewer,0,0,0);CHKERRQ(ierr); 20653e701f1cSksagiyam if (ishdf5) { 20663e701f1cSksagiyam #if defined(PETSC_HAVE_HDF5) 20673e701f1cSksagiyam PetscViewerFormat format; 20683e701f1cSksagiyam ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 20693e701f1cSksagiyam if (format == PETSC_VIEWER_HDF5_PETSC || format == PETSC_VIEWER_DEFAULT || format == PETSC_VIEWER_NATIVE) { 2070c9ad657eSksagiyam ierr = DMPlexCoordinatesLoad_HDF5_Internal(dm, viewer, globalToLocalPointSF);CHKERRQ(ierr); 20713e701f1cSksagiyam } else SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "PetscViewerFormat %s not supported for HDF5 input.", PetscViewerFormats[format]); 20723e701f1cSksagiyam #else 20733e701f1cSksagiyam SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 20743e701f1cSksagiyam #endif 20753e701f1cSksagiyam } 2076*02f7d72cSksagiyam ierr = PetscLogEventEnd(DMPLEX_CoordinatesLoad,viewer,0,0,0);CHKERRQ(ierr); 20773e701f1cSksagiyam PetscFunctionReturn(0); 20783e701f1cSksagiyam } 20793e701f1cSksagiyam 2080b08ad5deSksagiyam /*@ 2081b08ad5deSksagiyam DMPlexLabelsLoad - Loads labels into a DMPlex 2082b08ad5deSksagiyam 2083b08ad5deSksagiyam Collective on DM 2084b08ad5deSksagiyam 2085b08ad5deSksagiyam Input Parameters: 2086b08ad5deSksagiyam + dm - The DM into which the labels are loaded 2087b08ad5deSksagiyam - viewer - The PetscViewer for the saved labels 2088b08ad5deSksagiyam 2089b08ad5deSksagiyam Level: advanced 2090b08ad5deSksagiyam 2091b08ad5deSksagiyam .seealso: DMLoad(), DMPlexTopologyLoad(), DMPlexCoordinatesLoad(), DMView(), PetscViewerHDF5Open(), PetscViewerPushFormat() 2092b08ad5deSksagiyam @*/ 2093b08ad5deSksagiyam PetscErrorCode DMPlexLabelsLoad(DM dm, PetscViewer viewer) 2094b08ad5deSksagiyam { 2095b08ad5deSksagiyam PetscBool ishdf5; 2096b08ad5deSksagiyam PetscErrorCode ierr; 2097b08ad5deSksagiyam 2098b08ad5deSksagiyam PetscFunctionBegin; 2099b08ad5deSksagiyam PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2100b08ad5deSksagiyam PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 2101b08ad5deSksagiyam ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 2102*02f7d72cSksagiyam ierr = PetscLogEventBegin(DMPLEX_LabelsLoad,viewer,0,0,0);CHKERRQ(ierr); 2103b08ad5deSksagiyam if (ishdf5) { 2104b08ad5deSksagiyam #if defined(PETSC_HAVE_HDF5) 2105b08ad5deSksagiyam PetscViewerFormat format; 2106b08ad5deSksagiyam 2107b08ad5deSksagiyam ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 2108b08ad5deSksagiyam if (format == PETSC_VIEWER_HDF5_PETSC || format == PETSC_VIEWER_DEFAULT || format == PETSC_VIEWER_NATIVE) { 2109b08ad5deSksagiyam ierr = DMPlexLabelsLoad_HDF5_Internal(dm, viewer);CHKERRQ(ierr); 2110b08ad5deSksagiyam } else SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "PetscViewerFormat %s not supported for HDF5 input.", PetscViewerFormats[format]); 2111b08ad5deSksagiyam #else 2112b08ad5deSksagiyam SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 2113b08ad5deSksagiyam #endif 2114b08ad5deSksagiyam } 2115*02f7d72cSksagiyam ierr = PetscLogEventEnd(DMPLEX_LabelsLoad,viewer,0,0,0);CHKERRQ(ierr); 2116b08ad5deSksagiyam PetscFunctionReturn(0); 2117b08ad5deSksagiyam } 2118b08ad5deSksagiyam 2119f84dd6b4Sksagiyam /*@ 2120f84dd6b4Sksagiyam DMPlexSectionLoad - Loads section into a DMPlex 2121f84dd6b4Sksagiyam 2122f84dd6b4Sksagiyam Collective on DM 2123f84dd6b4Sksagiyam 2124f84dd6b4Sksagiyam Input Parameters: 2125f84dd6b4Sksagiyam + dm - The DM that represents the topology 2126f84dd6b4Sksagiyam . viewer - The PetscViewer that represents the on-disk section (sectionA) 2127f84dd6b4Sksagiyam . sectiondm - The DM into which the on-disk section (sectionA) is migrated 2128f84dd6b4Sksagiyam - globalToLocalPointSF - The SF returned by DMPlexTopologyLoad() when loading dm from viewer 2129f84dd6b4Sksagiyam 2130f84dd6b4Sksagiyam Output Parameters 2131f84dd6b4Sksagiyam + 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) 2132f84dd6b4Sksagiyam - 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) 2133f84dd6b4Sksagiyam 2134f84dd6b4Sksagiyam Level: advanced 2135f84dd6b4Sksagiyam 2136f84dd6b4Sksagiyam Notes: 2137f84dd6b4Sksagiyam 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. 2138f84dd6b4Sksagiyam 2139f84dd6b4Sksagiyam 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. 2140f84dd6b4Sksagiyam 2141f84dd6b4Sksagiyam 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. 2142f84dd6b4Sksagiyam 2143f84dd6b4Sksagiyam Example using 2 processes: 2144f84dd6b4Sksagiyam $ NX (number of points on dm): 4 2145f84dd6b4Sksagiyam $ sectionA : the on-disk section 2146f84dd6b4Sksagiyam $ vecA : a vector associated with sectionA 2147f84dd6b4Sksagiyam $ sectionB : sectiondm's local section constructed in this function 2148f84dd6b4Sksagiyam $ vecB (local) : a vector associated with sectiondm's local section 2149f84dd6b4Sksagiyam $ vecB (global) : a vector associated with sectiondm's global section 2150f84dd6b4Sksagiyam $ 2151f84dd6b4Sksagiyam $ rank 0 rank 1 2152f84dd6b4Sksagiyam $ vecA (global) : [.0 .4 .1 | .2 .3] <- to be loaded in DMPlexGlobalVectorLoad() or DMPlexLocalVectorLoad() 2153f84dd6b4Sksagiyam $ sectionA->atlasOff : 0 2 | 1 <- loaded in PetscSectionLoad() 2154f84dd6b4Sksagiyam $ sectionA->atlasDof : 1 3 | 1 <- loaded in PetscSectionLoad() 2155f84dd6b4Sksagiyam $ sectionA's global point numbers: 0 2 | 3 <- loaded in DMPlexSectionLoad() 2156f84dd6b4Sksagiyam $ [0, NX) : 0 1 | 2 3 <- conceptual partition used in globalToLocalPointSF 2157f84dd6b4Sksagiyam $ sectionB's global point numbers: 0 1 3 | 3 2 <- associated with [0, NX) by globalToLocalPointSF 2158f84dd6b4Sksagiyam $ sectionB->atlasDof : 1 0 1 | 1 3 2159f84dd6b4Sksagiyam $ sectionB->atlasOff (no perm) : 0 1 1 | 0 1 2160f84dd6b4Sksagiyam $ vecB (local) : [.0 .4] | [.4 .1 .2 .3] <- to be constructed by calling DMPlexLocalVectorLoad() with localDofSF 2161f84dd6b4Sksagiyam $ vecB (global) : [.0 .4 | .1 .2 .3] <- to be constructed by calling DMPlexGlobalVectorLoad() with globalDofSF 2162f84dd6b4Sksagiyam $ 2163f84dd6b4Sksagiyam $ where "|" represents a partition of loaded data, and global point 3 is assumed to be owned by rank 0. 2164f84dd6b4Sksagiyam 2165f84dd6b4Sksagiyam .seealso: DMLoad(), DMPlexTopologyLoad(), DMPlexCoordinatesLoad(), DMPlexLabelsLoad(), DMPlexGlobalVectorLoad(), DMPlexLocalVectorLoad(), PetscSectionLoad(), DMPlexSectionView() 2166f84dd6b4Sksagiyam @*/ 2167f84dd6b4Sksagiyam PetscErrorCode DMPlexSectionLoad(DM dm, PetscViewer viewer, DM sectiondm, PetscSF globalToLocalPointSF, PetscSF *globalDofSF, PetscSF *localDofSF) 2168f84dd6b4Sksagiyam { 2169f84dd6b4Sksagiyam PetscBool ishdf5; 2170f84dd6b4Sksagiyam PetscErrorCode ierr; 2171f84dd6b4Sksagiyam 2172f84dd6b4Sksagiyam PetscFunctionBegin; 2173f84dd6b4Sksagiyam PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2174f84dd6b4Sksagiyam PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 2175f84dd6b4Sksagiyam PetscValidHeaderSpecific(sectiondm, DM_CLASSID, 3); 2176f84dd6b4Sksagiyam PetscValidHeaderSpecific(globalToLocalPointSF, PETSCSF_CLASSID, 4); 2177f84dd6b4Sksagiyam if (globalDofSF) PetscValidPointer(globalDofSF, 5); 2178f84dd6b4Sksagiyam if (localDofSF) PetscValidPointer(localDofSF, 6); 2179f84dd6b4Sksagiyam ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5);CHKERRQ(ierr); 2180*02f7d72cSksagiyam ierr = PetscLogEventBegin(DMPLEX_SectionLoad,viewer,0,0,0);CHKERRQ(ierr); 2181f84dd6b4Sksagiyam if (ishdf5) { 2182f84dd6b4Sksagiyam #if defined(PETSC_HAVE_HDF5) 2183f84dd6b4Sksagiyam ierr = DMPlexSectionLoad_HDF5_Internal(dm, viewer, sectiondm, globalToLocalPointSF, globalDofSF, localDofSF);CHKERRQ(ierr); 2184f84dd6b4Sksagiyam #else 2185f84dd6b4Sksagiyam SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 2186f84dd6b4Sksagiyam #endif 2187f84dd6b4Sksagiyam } 2188*02f7d72cSksagiyam ierr = PetscLogEventEnd(DMPLEX_SectionLoad,viewer,0,0,0);CHKERRQ(ierr); 2189f84dd6b4Sksagiyam PetscFunctionReturn(0); 2190f84dd6b4Sksagiyam } 2191f84dd6b4Sksagiyam 21928be3dfe1Sksagiyam /*@ 21938be3dfe1Sksagiyam DMPlexGlobalVectorLoad - Loads on-disk vector data into a global vector 21948be3dfe1Sksagiyam 21958be3dfe1Sksagiyam Collective on DM 21968be3dfe1Sksagiyam 21978be3dfe1Sksagiyam Input Parameters: 21988be3dfe1Sksagiyam + dm - The DM that represents the topology 21998be3dfe1Sksagiyam . viewer - The PetscViewer that represents the on-disk vector data 22008be3dfe1Sksagiyam . sectiondm - The DM that contains the global section on which vec is defined 22018be3dfe1Sksagiyam . sf - The SF that migrates the on-disk vector data into vec 22028be3dfe1Sksagiyam - vec - The global vector to set values of 22038be3dfe1Sksagiyam 22048be3dfe1Sksagiyam Level: advanced 22058be3dfe1Sksagiyam 22068be3dfe1Sksagiyam Notes: 22078be3dfe1Sksagiyam 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. 22088be3dfe1Sksagiyam 22098be3dfe1Sksagiyam Typical calling sequence 22108be3dfe1Sksagiyam $ DMCreate(PETSC_COMM_WORLD, &dm); 22118be3dfe1Sksagiyam $ DMSetType(dm, DMPLEX); 22128be3dfe1Sksagiyam $ PetscObjectSetName((PetscObject)dm, "topologydm_name"); 22138be3dfe1Sksagiyam $ DMPlexTopologyLoad(dm, viewer, &sfX); 22148be3dfe1Sksagiyam $ DMClone(dm, §iondm); 22158be3dfe1Sksagiyam $ PetscObjectSetName((PetscObject)sectiondm, "sectiondm_name"); 22168be3dfe1Sksagiyam $ DMPlexSectionLoad(dm, viewer, sectiondm, sfX, &gsf, NULL); 22178be3dfe1Sksagiyam $ DMGetGlobalVector(sectiondm, &vec); 22188be3dfe1Sksagiyam $ PetscObjectSetName((PetscObject)vec, "vec_name"); 22198be3dfe1Sksagiyam $ DMPlexGlobalVectorLoad(dm, viewer, sectiondm, gsf, vec); 22208be3dfe1Sksagiyam $ DMRestoreGlobalVector(sectiondm, &vec); 22218be3dfe1Sksagiyam $ PetscSFDestroy(&gsf); 22228be3dfe1Sksagiyam $ PetscSFDestroy(&sfX); 22238be3dfe1Sksagiyam $ DMDestroy(§iondm); 22248be3dfe1Sksagiyam $ DMDestroy(&dm); 22258be3dfe1Sksagiyam 22268be3dfe1Sksagiyam .seealso: DMPlexTopologyLoad(), DMPlexSectionLoad(), DMPlexLocalVectorLoad(), DMPlexGlobalVectorView(), DMPlexLocalVectorView() 22278be3dfe1Sksagiyam @*/ 22288be3dfe1Sksagiyam PetscErrorCode DMPlexGlobalVectorLoad(DM dm, PetscViewer viewer, DM sectiondm, PetscSF sf, Vec vec) 22298be3dfe1Sksagiyam { 22308be3dfe1Sksagiyam PetscBool ishdf5; 22318be3dfe1Sksagiyam PetscErrorCode ierr; 22328be3dfe1Sksagiyam 22338be3dfe1Sksagiyam PetscFunctionBegin; 22348be3dfe1Sksagiyam PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 22358be3dfe1Sksagiyam PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 22368be3dfe1Sksagiyam PetscValidHeaderSpecific(sectiondm, DM_CLASSID, 3); 22378be3dfe1Sksagiyam PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 4); 22388be3dfe1Sksagiyam PetscValidHeaderSpecific(vec, VEC_CLASSID, 5); 22398be3dfe1Sksagiyam /* Check consistency */ 22408be3dfe1Sksagiyam { 22418be3dfe1Sksagiyam PetscSection section; 22428be3dfe1Sksagiyam PetscBool includesConstraints; 22438be3dfe1Sksagiyam PetscInt m, m1; 22448be3dfe1Sksagiyam 22458be3dfe1Sksagiyam ierr = VecGetLocalSize(vec, &m1);CHKERRQ(ierr); 22468be3dfe1Sksagiyam ierr = DMGetGlobalSection(sectiondm, §ion);CHKERRQ(ierr); 22478be3dfe1Sksagiyam ierr = PetscSectionGetIncludesConstraints(section, &includesConstraints);CHKERRQ(ierr); 22488be3dfe1Sksagiyam if (includesConstraints) {ierr = PetscSectionGetStorageSize(section, &m);CHKERRQ(ierr);} 22498be3dfe1Sksagiyam else {ierr = PetscSectionGetConstrainedStorageSize(section, &m);CHKERRQ(ierr);} 22508be3dfe1Sksagiyam if (m1 != m) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Global vector size (%D) != global section storage size (%D)", m1, m); 22518be3dfe1Sksagiyam } 22528be3dfe1Sksagiyam ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5);CHKERRQ(ierr); 2253*02f7d72cSksagiyam ierr = PetscLogEventBegin(DMPLEX_GlobalVectorLoad,viewer,0,0,0);CHKERRQ(ierr); 22548be3dfe1Sksagiyam if (ishdf5) { 22558be3dfe1Sksagiyam #if defined(PETSC_HAVE_HDF5) 22568be3dfe1Sksagiyam ierr = DMPlexVecLoad_HDF5_Internal(dm, viewer, sectiondm, sf, vec);CHKERRQ(ierr); 22578be3dfe1Sksagiyam #else 22588be3dfe1Sksagiyam SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 22598be3dfe1Sksagiyam #endif 22608be3dfe1Sksagiyam } 2261*02f7d72cSksagiyam ierr = PetscLogEventEnd(DMPLEX_GlobalVectorLoad,viewer,0,0,0);CHKERRQ(ierr); 22628be3dfe1Sksagiyam PetscFunctionReturn(0); 22638be3dfe1Sksagiyam } 22648be3dfe1Sksagiyam 22658be3dfe1Sksagiyam /*@ 22668be3dfe1Sksagiyam DMPlexLocalVectorLoad - Loads on-disk vector data into a local vector 22678be3dfe1Sksagiyam 22688be3dfe1Sksagiyam Collective on DM 22698be3dfe1Sksagiyam 22708be3dfe1Sksagiyam Input Parameters: 22718be3dfe1Sksagiyam + dm - The DM that represents the topology 22728be3dfe1Sksagiyam . viewer - The PetscViewer that represents the on-disk vector data 22738be3dfe1Sksagiyam . sectiondm - The DM that contains the local section on which vec is defined 22748be3dfe1Sksagiyam . sf - The SF that migrates the on-disk vector data into vec 22758be3dfe1Sksagiyam - vec - The local vector to set values of 22768be3dfe1Sksagiyam 22778be3dfe1Sksagiyam Level: advanced 22788be3dfe1Sksagiyam 22798be3dfe1Sksagiyam Notes: 22808be3dfe1Sksagiyam 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. 22818be3dfe1Sksagiyam 22828be3dfe1Sksagiyam Typical calling sequence 22838be3dfe1Sksagiyam $ DMCreate(PETSC_COMM_WORLD, &dm); 22848be3dfe1Sksagiyam $ DMSetType(dm, DMPLEX); 22858be3dfe1Sksagiyam $ PetscObjectSetName((PetscObject)dm, "topologydm_name"); 22868be3dfe1Sksagiyam $ DMPlexTopologyLoad(dm, viewer, &sfX); 22878be3dfe1Sksagiyam $ DMClone(dm, §iondm); 22888be3dfe1Sksagiyam $ PetscObjectSetName((PetscObject)sectiondm, "sectiondm_name"); 22898be3dfe1Sksagiyam $ DMPlexSectionLoad(dm, viewer, sectiondm, sfX, NULL, &lsf); 22908be3dfe1Sksagiyam $ DMGetLocalVector(sectiondm, &vec); 22918be3dfe1Sksagiyam $ PetscObjectSetName((PetscObject)vec, "vec_name"); 22928be3dfe1Sksagiyam $ DMPlexLocalVectorLoad(dm, viewer, sectiondm, lsf, vec); 22938be3dfe1Sksagiyam $ DMRestoreLocalVector(sectiondm, &vec); 22948be3dfe1Sksagiyam $ PetscSFDestroy(&lsf); 22958be3dfe1Sksagiyam $ PetscSFDestroy(&sfX); 22968be3dfe1Sksagiyam $ DMDestroy(§iondm); 22978be3dfe1Sksagiyam $ DMDestroy(&dm); 22988be3dfe1Sksagiyam 22998be3dfe1Sksagiyam .seealso: DMPlexTopologyLoad(), DMPlexSectionLoad(), DMPlexGlobalVectorLoad(), DMPlexGlobalVectorView(), DMPlexLocalVectorView() 23008be3dfe1Sksagiyam @*/ 23018be3dfe1Sksagiyam PetscErrorCode DMPlexLocalVectorLoad(DM dm, PetscViewer viewer, DM sectiondm, PetscSF sf, Vec vec) 23028be3dfe1Sksagiyam { 23038be3dfe1Sksagiyam PetscBool ishdf5; 23048be3dfe1Sksagiyam PetscErrorCode ierr; 23058be3dfe1Sksagiyam 23068be3dfe1Sksagiyam PetscFunctionBegin; 23078be3dfe1Sksagiyam PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 23088be3dfe1Sksagiyam PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 23098be3dfe1Sksagiyam PetscValidHeaderSpecific(sectiondm, DM_CLASSID, 3); 23108be3dfe1Sksagiyam PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 4); 23118be3dfe1Sksagiyam PetscValidHeaderSpecific(vec, VEC_CLASSID, 5); 23128be3dfe1Sksagiyam /* Check consistency */ 23138be3dfe1Sksagiyam { 23148be3dfe1Sksagiyam PetscSection section; 23158be3dfe1Sksagiyam PetscBool includesConstraints; 23168be3dfe1Sksagiyam PetscInt m, m1; 23178be3dfe1Sksagiyam 23188be3dfe1Sksagiyam ierr = VecGetLocalSize(vec, &m1);CHKERRQ(ierr); 23198be3dfe1Sksagiyam ierr = DMGetLocalSection(sectiondm, §ion);CHKERRQ(ierr); 23208be3dfe1Sksagiyam ierr = PetscSectionGetIncludesConstraints(section, &includesConstraints);CHKERRQ(ierr); 23218be3dfe1Sksagiyam if (includesConstraints) {ierr = PetscSectionGetStorageSize(section, &m);CHKERRQ(ierr);} 23228be3dfe1Sksagiyam else {ierr = PetscSectionGetConstrainedStorageSize(section, &m);CHKERRQ(ierr);} 23238be3dfe1Sksagiyam if (m1 != m) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Local vector size (%D) != local section storage size (%D)", m1, m); 23248be3dfe1Sksagiyam } 23258be3dfe1Sksagiyam ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5);CHKERRQ(ierr); 2326*02f7d72cSksagiyam ierr = PetscLogEventBegin(DMPLEX_LocalVectorLoad,viewer,0,0,0);CHKERRQ(ierr); 23278be3dfe1Sksagiyam if (ishdf5) { 23288be3dfe1Sksagiyam #if defined(PETSC_HAVE_HDF5) 23298be3dfe1Sksagiyam ierr = DMPlexVecLoad_HDF5_Internal(dm, viewer, sectiondm, sf, vec);CHKERRQ(ierr); 23308be3dfe1Sksagiyam #else 23318be3dfe1Sksagiyam SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 23328be3dfe1Sksagiyam #endif 23338be3dfe1Sksagiyam } 2334*02f7d72cSksagiyam ierr = PetscLogEventEnd(DMPLEX_LocalVectorLoad,viewer,0,0,0);CHKERRQ(ierr); 23358be3dfe1Sksagiyam PetscFunctionReturn(0); 23368be3dfe1Sksagiyam } 23378be3dfe1Sksagiyam 2338552f7358SJed Brown PetscErrorCode DMDestroy_Plex(DM dm) 2339552f7358SJed Brown { 2340552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2341552f7358SJed Brown PetscErrorCode ierr; 2342552f7358SJed Brown 2343552f7358SJed Brown PetscFunctionBegin; 23448135c375SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)dm,"DMSetUpGLVisViewer_C",NULL);CHKERRQ(ierr); 23458135c375SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)dm,"DMPlexInsertBoundaryValues_C", NULL);CHKERRQ(ierr); 234628d58a37SPierre Jolivet ierr = PetscObjectComposeFunction((PetscObject)dm,"DMCreateNeumannOverlap_C", NULL);CHKERRQ(ierr); 23471eb70e55SToby Isaac ierr = PetscObjectComposeFunction((PetscObject)dm,"DMInterpolateSolution_C", NULL);CHKERRQ(ierr); 23480d644c17SKarl Rupp if (--mesh->refct > 0) PetscFunctionReturn(0); 2349552f7358SJed Brown ierr = PetscSectionDestroy(&mesh->coneSection);CHKERRQ(ierr); 2350552f7358SJed Brown ierr = PetscFree(mesh->cones);CHKERRQ(ierr); 2351552f7358SJed Brown ierr = PetscFree(mesh->coneOrientations);CHKERRQ(ierr); 2352552f7358SJed Brown ierr = PetscSectionDestroy(&mesh->supportSection);CHKERRQ(ierr); 2353be36d101SStefano Zampini ierr = PetscSectionDestroy(&mesh->subdomainSection);CHKERRQ(ierr); 2354552f7358SJed Brown ierr = PetscFree(mesh->supports);CHKERRQ(ierr); 2355552f7358SJed Brown ierr = PetscFree(mesh->facesTmp);CHKERRQ(ierr); 2356d9deefdfSMatthew G. Knepley ierr = PetscFree(mesh->tetgenOpts);CHKERRQ(ierr); 2357d9deefdfSMatthew G. Knepley ierr = PetscFree(mesh->triangleOpts);CHKERRQ(ierr); 2358012bc364SMatthew G. Knepley ierr = PetscFree(mesh->transformType);CHKERRQ(ierr); 235977623264SMatthew G. Knepley ierr = PetscPartitionerDestroy(&mesh->partitioner);CHKERRQ(ierr); 2360a89082eeSMatthew G Knepley ierr = DMLabelDestroy(&mesh->subpointMap);CHKERRQ(ierr); 236197d8846cSMatthew Knepley ierr = ISDestroy(&mesh->subpointIS);CHKERRQ(ierr); 2362552f7358SJed Brown ierr = ISDestroy(&mesh->globalVertexNumbers);CHKERRQ(ierr); 2363552f7358SJed Brown ierr = ISDestroy(&mesh->globalCellNumbers);CHKERRQ(ierr); 2364a68b90caSToby Isaac ierr = PetscSectionDestroy(&mesh->anchorSection);CHKERRQ(ierr); 2365a68b90caSToby Isaac ierr = ISDestroy(&mesh->anchorIS);CHKERRQ(ierr); 2366d961a43aSToby Isaac ierr = PetscSectionDestroy(&mesh->parentSection);CHKERRQ(ierr); 2367d961a43aSToby Isaac ierr = PetscFree(mesh->parents);CHKERRQ(ierr); 2368d961a43aSToby Isaac ierr = PetscFree(mesh->childIDs);CHKERRQ(ierr); 2369d961a43aSToby Isaac ierr = PetscSectionDestroy(&mesh->childSection);CHKERRQ(ierr); 2370d961a43aSToby Isaac ierr = PetscFree(mesh->children);CHKERRQ(ierr); 2371d6a7ad0dSToby Isaac ierr = DMDestroy(&mesh->referenceTree);CHKERRQ(ierr); 2372fec49543SMatthew G. Knepley ierr = PetscGridHashDestroy(&mesh->lbox);CHKERRQ(ierr); 23730a19bb7dSprj- ierr = PetscFree(mesh->neighbors);CHKERRQ(ierr); 237431b70465SJoe Wallwork if (mesh->metricCtx) { ierr = PetscFree(mesh->metricCtx);CHKERRQ(ierr); } 2375552f7358SJed Brown /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */ 2376552f7358SJed Brown ierr = PetscFree(mesh);CHKERRQ(ierr); 2377552f7358SJed Brown PetscFunctionReturn(0); 2378552f7358SJed Brown } 2379552f7358SJed Brown 2380b412c318SBarry Smith PetscErrorCode DMCreateMatrix_Plex(DM dm, Mat *J) 2381552f7358SJed Brown { 23828d1174e4SMatthew G. Knepley PetscSection sectionGlobal; 2383acd755d7SMatthew G. Knepley PetscInt bs = -1, mbs; 2384552f7358SJed Brown PetscInt localSize; 2385837628f4SStefano Zampini PetscBool isShell, isBlock, isSeqBlock, isMPIBlock, isSymBlock, isSymSeqBlock, isSymMPIBlock, isMatIS; 2386552f7358SJed Brown PetscErrorCode ierr; 2387b412c318SBarry Smith MatType mtype; 23881428887cSShri Abhyankar ISLocalToGlobalMapping ltog; 2389552f7358SJed Brown 2390552f7358SJed Brown PetscFunctionBegin; 2391607a6623SBarry Smith ierr = MatInitializePackage();CHKERRQ(ierr); 2392b412c318SBarry Smith mtype = dm->mattype; 2393e87a4003SBarry Smith ierr = DMGetGlobalSection(dm, §ionGlobal);CHKERRQ(ierr); 2394552f7358SJed Brown /* ierr = PetscSectionGetStorageSize(sectionGlobal, &localSize);CHKERRQ(ierr); */ 2395552f7358SJed Brown ierr = PetscSectionGetConstrainedStorageSize(sectionGlobal, &localSize);CHKERRQ(ierr); 239682f516ccSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)dm), J);CHKERRQ(ierr); 2397552f7358SJed Brown ierr = MatSetSizes(*J, localSize, localSize, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 2398552f7358SJed Brown ierr = MatSetType(*J, mtype);CHKERRQ(ierr); 2399552f7358SJed Brown ierr = MatSetFromOptions(*J);CHKERRQ(ierr); 2400acd755d7SMatthew G. Knepley ierr = MatGetBlockSize(*J, &mbs);CHKERRQ(ierr); 2401acd755d7SMatthew G. Knepley if (mbs > 1) bs = mbs; 2402552f7358SJed Brown ierr = PetscStrcmp(mtype, MATSHELL, &isShell);CHKERRQ(ierr); 2403552f7358SJed Brown ierr = PetscStrcmp(mtype, MATBAIJ, &isBlock);CHKERRQ(ierr); 2404552f7358SJed Brown ierr = PetscStrcmp(mtype, MATSEQBAIJ, &isSeqBlock);CHKERRQ(ierr); 2405552f7358SJed Brown ierr = PetscStrcmp(mtype, MATMPIBAIJ, &isMPIBlock);CHKERRQ(ierr); 2406552f7358SJed Brown ierr = PetscStrcmp(mtype, MATSBAIJ, &isSymBlock);CHKERRQ(ierr); 2407552f7358SJed Brown ierr = PetscStrcmp(mtype, MATSEQSBAIJ, &isSymSeqBlock);CHKERRQ(ierr); 2408552f7358SJed Brown ierr = PetscStrcmp(mtype, MATMPISBAIJ, &isSymMPIBlock);CHKERRQ(ierr); 2409837628f4SStefano Zampini ierr = PetscStrcmp(mtype, MATIS, &isMatIS);CHKERRQ(ierr); 2410552f7358SJed Brown if (!isShell) { 2411be36d101SStefano Zampini PetscSection subSection; 2412837628f4SStefano Zampini PetscBool fillMatrix = (PetscBool)(!dm->prealloc_only && !isMatIS); 24130be3e97aSMatthew G. Knepley PetscInt *dnz, *onz, *dnzu, *onzu, bsLocal[2], bsMinMax[2], *ltogidx, lsize; 2414fad22124SMatthew G Knepley PetscInt pStart, pEnd, p, dof, cdof; 2415552f7358SJed Brown 241600140cc3SStefano Zampini /* Set localtoglobalmapping on the matrix for MatSetValuesLocal() to work (it also creates the local matrices in case of MATIS) */ 2417be36d101SStefano Zampini if (isMatIS) { /* need a different l2g map than the one computed by DMGetLocalToGlobalMapping */ 2418be36d101SStefano Zampini PetscSection section; 2419be36d101SStefano Zampini PetscInt size; 2420be36d101SStefano Zampini 242192fd8e1eSJed Brown ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr); 2422be36d101SStefano Zampini ierr = PetscSectionGetStorageSize(section, &size);CHKERRQ(ierr); 2423be36d101SStefano Zampini ierr = PetscMalloc1(size,<ogidx);CHKERRQ(ierr); 2424be36d101SStefano Zampini ierr = DMPlexGetSubdomainSection(dm, &subSection);CHKERRQ(ierr); 2425be36d101SStefano Zampini } else { 242600140cc3SStefano Zampini ierr = DMGetLocalToGlobalMapping(dm,<og);CHKERRQ(ierr); 2427be36d101SStefano Zampini } 2428552f7358SJed Brown ierr = PetscSectionGetChart(sectionGlobal, &pStart, &pEnd);CHKERRQ(ierr); 2429be36d101SStefano Zampini for (p = pStart, lsize = 0; p < pEnd; ++p) { 2430a9d99c84SMatthew G. Knepley PetscInt bdof; 2431a9d99c84SMatthew G. Knepley 2432552f7358SJed Brown ierr = PetscSectionGetDof(sectionGlobal, p, &dof);CHKERRQ(ierr); 2433fad22124SMatthew G Knepley ierr = PetscSectionGetConstraintDof(sectionGlobal, p, &cdof);CHKERRQ(ierr); 24341d17a0a3SMatthew G. Knepley dof = dof < 0 ? -(dof+1) : dof; 24351d17a0a3SMatthew G. Knepley bdof = cdof && (dof-cdof) ? 1 : dof; 24361d17a0a3SMatthew G. Knepley if (dof) { 24371d17a0a3SMatthew G. Knepley if (bs < 0) {bs = bdof;} 2438be36d101SStefano Zampini else if (bs != bdof) {bs = 1; if (!isMatIS) break;} 2439be36d101SStefano Zampini } 2440be36d101SStefano Zampini if (isMatIS) { 2441be36d101SStefano Zampini PetscInt loff,c,off; 2442be36d101SStefano Zampini ierr = PetscSectionGetOffset(subSection, p, &loff);CHKERRQ(ierr); 2443be36d101SStefano Zampini ierr = PetscSectionGetOffset(sectionGlobal, p, &off);CHKERRQ(ierr); 2444be36d101SStefano Zampini for (c = 0; c < dof-cdof; ++c, ++lsize) ltogidx[loff+c] = off > -1 ? off+c : -(off+1)+c; 2445552f7358SJed Brown } 24462a28c762SMatthew G Knepley } 24472a28c762SMatthew G Knepley /* Must have same blocksize on all procs (some might have no points) */ 24480be3e97aSMatthew G. Knepley bsLocal[0] = bs < 0 ? PETSC_MAX_INT : bs; bsLocal[1] = bs; 24490be3e97aSMatthew G. Knepley ierr = PetscGlobalMinMaxInt(PetscObjectComm((PetscObject) dm), bsLocal, bsMinMax);CHKERRQ(ierr); 24500be3e97aSMatthew G. Knepley if (bsMinMax[0] != bsMinMax[1]) {bs = 1;} 24510be3e97aSMatthew G. Knepley else {bs = bsMinMax[0];} 24526fd5c86aSStefano Zampini bs = PetscMax(1,bs); 24536fd5c86aSStefano Zampini if (isMatIS) { /* Must reduce indices by blocksize */ 24544fa26246SMatthew G. Knepley PetscInt l; 24556fd5c86aSStefano Zampini 24566fd5c86aSStefano Zampini lsize = lsize/bs; 24576fd5c86aSStefano Zampini if (bs > 1) for (l = 0; l < lsize; ++l) ltogidx[l] = ltogidx[l*bs]/bs; 24584fa26246SMatthew G. Knepley ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)dm), bs, lsize, ltogidx, PETSC_OWN_POINTER, <og);CHKERRQ(ierr); 2459be36d101SStefano Zampini } 2460be36d101SStefano Zampini ierr = MatSetLocalToGlobalMapping(*J,ltog,ltog);CHKERRQ(ierr); 2461be36d101SStefano Zampini if (isMatIS) { 2462be36d101SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(<og);CHKERRQ(ierr); 2463be36d101SStefano Zampini } 24641795a4d1SJed Brown ierr = PetscCalloc4(localSize/bs, &dnz, localSize/bs, &onz, localSize/bs, &dnzu, localSize/bs, &onzu);CHKERRQ(ierr); 24658d1174e4SMatthew G. Knepley ierr = DMPlexPreallocateOperator(dm, bs, dnz, onz, dnzu, onzu, *J, fillMatrix);CHKERRQ(ierr); 2466552f7358SJed Brown ierr = PetscFree4(dnz, onz, dnzu, onzu);CHKERRQ(ierr); 2467552f7358SJed Brown } 2468b1f74addSMatthew G. Knepley ierr = MatSetDM(*J, dm);CHKERRQ(ierr); 2469552f7358SJed Brown PetscFunctionReturn(0); 2470552f7358SJed Brown } 2471552f7358SJed Brown 24727cd05799SMatthew G. Knepley /*@ 2473a8f00d21SMatthew G. Knepley DMPlexGetSubdomainSection - Returns the section associated with the subdomain 2474be36d101SStefano Zampini 2475be36d101SStefano Zampini Not collective 2476be36d101SStefano Zampini 2477be36d101SStefano Zampini Input Parameter: 2478be36d101SStefano Zampini . mesh - The DMPlex 2479be36d101SStefano Zampini 2480be36d101SStefano Zampini Output Parameters: 2481be36d101SStefano Zampini . subsection - The subdomain section 2482be36d101SStefano Zampini 2483be36d101SStefano Zampini Level: developer 2484be36d101SStefano Zampini 2485be36d101SStefano Zampini .seealso: 24867cd05799SMatthew G. Knepley @*/ 2487be36d101SStefano Zampini PetscErrorCode DMPlexGetSubdomainSection(DM dm, PetscSection *subsection) 2488be36d101SStefano Zampini { 2489be36d101SStefano Zampini DM_Plex *mesh = (DM_Plex*) dm->data; 2490be36d101SStefano Zampini PetscErrorCode ierr; 2491be36d101SStefano Zampini 2492be36d101SStefano Zampini PetscFunctionBegin; 2493be36d101SStefano Zampini PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2494be36d101SStefano Zampini if (!mesh->subdomainSection) { 2495be36d101SStefano Zampini PetscSection section; 2496be36d101SStefano Zampini PetscSF sf; 2497be36d101SStefano Zampini 2498be36d101SStefano Zampini ierr = PetscSFCreate(PETSC_COMM_SELF,&sf);CHKERRQ(ierr); 249992fd8e1eSJed Brown ierr = DMGetLocalSection(dm,§ion);CHKERRQ(ierr); 2500be36d101SStefano Zampini ierr = PetscSectionCreateGlobalSection(section,sf,PETSC_FALSE,PETSC_TRUE,&mesh->subdomainSection);CHKERRQ(ierr); 2501be36d101SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 2502be36d101SStefano Zampini } 2503be36d101SStefano Zampini *subsection = mesh->subdomainSection; 2504be36d101SStefano Zampini PetscFunctionReturn(0); 2505be36d101SStefano Zampini } 2506be36d101SStefano Zampini 2507552f7358SJed Brown /*@ 2508552f7358SJed Brown DMPlexGetChart - Return the interval for all mesh points [pStart, pEnd) 2509552f7358SJed Brown 2510552f7358SJed Brown Not collective 2511552f7358SJed Brown 2512552f7358SJed Brown Input Parameter: 2513552f7358SJed Brown . mesh - The DMPlex 2514552f7358SJed Brown 2515552f7358SJed Brown Output Parameters: 2516552f7358SJed Brown + pStart - The first mesh point 2517552f7358SJed Brown - pEnd - The upper bound for mesh points 2518552f7358SJed Brown 2519552f7358SJed Brown Level: beginner 2520552f7358SJed Brown 2521552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetChart() 2522552f7358SJed Brown @*/ 2523552f7358SJed Brown PetscErrorCode DMPlexGetChart(DM dm, PetscInt *pStart, PetscInt *pEnd) 2524552f7358SJed Brown { 2525552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2526552f7358SJed Brown PetscErrorCode ierr; 2527552f7358SJed Brown 2528552f7358SJed Brown PetscFunctionBegin; 2529552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2530552f7358SJed Brown ierr = PetscSectionGetChart(mesh->coneSection, pStart, pEnd);CHKERRQ(ierr); 2531552f7358SJed Brown PetscFunctionReturn(0); 2532552f7358SJed Brown } 2533552f7358SJed Brown 2534552f7358SJed Brown /*@ 2535552f7358SJed Brown DMPlexSetChart - Set the interval for all mesh points [pStart, pEnd) 2536552f7358SJed Brown 2537552f7358SJed Brown Not collective 2538552f7358SJed Brown 2539552f7358SJed Brown Input Parameters: 2540552f7358SJed Brown + mesh - The DMPlex 2541552f7358SJed Brown . pStart - The first mesh point 2542552f7358SJed Brown - pEnd - The upper bound for mesh points 2543552f7358SJed Brown 2544552f7358SJed Brown Output Parameters: 2545552f7358SJed Brown 2546552f7358SJed Brown Level: beginner 2547552f7358SJed Brown 2548552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetChart() 2549552f7358SJed Brown @*/ 2550552f7358SJed Brown PetscErrorCode DMPlexSetChart(DM dm, PetscInt pStart, PetscInt pEnd) 2551552f7358SJed Brown { 2552552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2553552f7358SJed Brown PetscErrorCode ierr; 2554552f7358SJed Brown 2555552f7358SJed Brown PetscFunctionBegin; 2556552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2557552f7358SJed Brown ierr = PetscSectionSetChart(mesh->coneSection, pStart, pEnd);CHKERRQ(ierr); 2558552f7358SJed Brown ierr = PetscSectionSetChart(mesh->supportSection, pStart, pEnd);CHKERRQ(ierr); 2559552f7358SJed Brown PetscFunctionReturn(0); 2560552f7358SJed Brown } 2561552f7358SJed Brown 2562552f7358SJed Brown /*@ 2563eaf898f9SPatrick Sanan DMPlexGetConeSize - Return the number of in-edges for this point in the DAG 2564552f7358SJed Brown 2565552f7358SJed Brown Not collective 2566552f7358SJed Brown 2567552f7358SJed Brown Input Parameters: 2568552f7358SJed Brown + mesh - The DMPlex 2569eaf898f9SPatrick Sanan - p - The point, which must lie in the chart set with DMPlexSetChart() 2570552f7358SJed Brown 2571552f7358SJed Brown Output Parameter: 2572552f7358SJed Brown . size - The cone size for point p 2573552f7358SJed Brown 2574552f7358SJed Brown Level: beginner 2575552f7358SJed Brown 2576552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetConeSize(), DMPlexSetChart() 2577552f7358SJed Brown @*/ 2578552f7358SJed Brown PetscErrorCode DMPlexGetConeSize(DM dm, PetscInt p, PetscInt *size) 2579552f7358SJed Brown { 2580552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2581552f7358SJed Brown PetscErrorCode ierr; 2582552f7358SJed Brown 2583552f7358SJed Brown PetscFunctionBegin; 2584552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2585552f7358SJed Brown PetscValidPointer(size, 3); 2586552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, size);CHKERRQ(ierr); 2587552f7358SJed Brown PetscFunctionReturn(0); 2588552f7358SJed Brown } 2589552f7358SJed Brown 2590552f7358SJed Brown /*@ 2591eaf898f9SPatrick Sanan DMPlexSetConeSize - Set the number of in-edges for this point in the DAG 2592552f7358SJed Brown 2593552f7358SJed Brown Not collective 2594552f7358SJed Brown 2595552f7358SJed Brown Input Parameters: 2596552f7358SJed Brown + mesh - The DMPlex 2597eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 2598552f7358SJed Brown - size - The cone size for point p 2599552f7358SJed Brown 2600552f7358SJed Brown Output Parameter: 2601552f7358SJed Brown 2602552f7358SJed Brown Note: 2603552f7358SJed Brown This should be called after DMPlexSetChart(). 2604552f7358SJed Brown 2605552f7358SJed Brown Level: beginner 2606552f7358SJed Brown 2607552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetConeSize(), DMPlexSetChart() 2608552f7358SJed Brown @*/ 2609552f7358SJed Brown PetscErrorCode DMPlexSetConeSize(DM dm, PetscInt p, PetscInt size) 2610552f7358SJed Brown { 2611552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2612552f7358SJed Brown PetscErrorCode ierr; 2613552f7358SJed Brown 2614552f7358SJed Brown PetscFunctionBegin; 2615552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2616552f7358SJed Brown ierr = PetscSectionSetDof(mesh->coneSection, p, size);CHKERRQ(ierr); 26170d644c17SKarl Rupp 2618552f7358SJed Brown mesh->maxConeSize = PetscMax(mesh->maxConeSize, size); 2619552f7358SJed Brown PetscFunctionReturn(0); 2620552f7358SJed Brown } 2621552f7358SJed Brown 2622f5a469b9SMatthew G. Knepley /*@ 2623eaf898f9SPatrick Sanan DMPlexAddConeSize - Add the given number of in-edges to this point in the DAG 2624f5a469b9SMatthew G. Knepley 2625f5a469b9SMatthew G. Knepley Not collective 2626f5a469b9SMatthew G. Knepley 2627f5a469b9SMatthew G. Knepley Input Parameters: 2628f5a469b9SMatthew G. Knepley + mesh - The DMPlex 2629eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 2630f5a469b9SMatthew G. Knepley - size - The additional cone size for point p 2631f5a469b9SMatthew G. Knepley 2632f5a469b9SMatthew G. Knepley Output Parameter: 2633f5a469b9SMatthew G. Knepley 2634f5a469b9SMatthew G. Knepley Note: 2635f5a469b9SMatthew G. Knepley This should be called after DMPlexSetChart(). 2636f5a469b9SMatthew G. Knepley 2637f5a469b9SMatthew G. Knepley Level: beginner 2638f5a469b9SMatthew G. Knepley 2639f5a469b9SMatthew G. Knepley .seealso: DMPlexCreate(), DMPlexSetConeSize(), DMPlexGetConeSize(), DMPlexSetChart() 2640f5a469b9SMatthew G. Knepley @*/ 2641f5a469b9SMatthew G. Knepley PetscErrorCode DMPlexAddConeSize(DM dm, PetscInt p, PetscInt size) 2642f5a469b9SMatthew G. Knepley { 2643f5a469b9SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 2644f5a469b9SMatthew G. Knepley PetscInt csize; 2645f5a469b9SMatthew G. Knepley PetscErrorCode ierr; 2646f5a469b9SMatthew G. Knepley 2647f5a469b9SMatthew G. Knepley PetscFunctionBegin; 2648f5a469b9SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2649f5a469b9SMatthew G. Knepley ierr = PetscSectionAddDof(mesh->coneSection, p, size);CHKERRQ(ierr); 2650f5a469b9SMatthew G. Knepley ierr = PetscSectionGetDof(mesh->coneSection, p, &csize);CHKERRQ(ierr); 2651f5a469b9SMatthew G. Knepley 2652f5a469b9SMatthew G. Knepley mesh->maxConeSize = PetscMax(mesh->maxConeSize, csize); 2653f5a469b9SMatthew G. Knepley PetscFunctionReturn(0); 2654f5a469b9SMatthew G. Knepley } 2655f5a469b9SMatthew G. Knepley 2656552f7358SJed Brown /*@C 2657eaf898f9SPatrick Sanan DMPlexGetCone - Return the points on the in-edges for this point in the DAG 2658552f7358SJed Brown 2659552f7358SJed Brown Not collective 2660552f7358SJed Brown 2661552f7358SJed Brown Input Parameters: 2662833c876bSVaclav Hapla + dm - The DMPlex 2663eaf898f9SPatrick Sanan - p - The point, which must lie in the chart set with DMPlexSetChart() 2664552f7358SJed Brown 2665552f7358SJed Brown Output Parameter: 2666552f7358SJed Brown . cone - An array of points which are on the in-edges for point p 2667552f7358SJed Brown 2668552f7358SJed Brown Level: beginner 2669552f7358SJed Brown 26703813dfbdSMatthew G Knepley Fortran Notes: 26713813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 26723813dfbdSMatthew G Knepley include petsc.h90 in your code. 2673922102d1SVaclav Hapla You must also call DMPlexRestoreCone() after you finish using the returned array. 2674922102d1SVaclav Hapla DMPlexRestoreCone() is not needed/available in C. 26753813dfbdSMatthew G Knepley 2676e45f02b0SMatthew G. Knepley .seealso: DMPlexGetConeSize(), DMPlexSetCone(), DMPlexGetConeTuple(), DMPlexSetChart() 2677552f7358SJed Brown @*/ 2678552f7358SJed Brown PetscErrorCode DMPlexGetCone(DM dm, PetscInt p, const PetscInt *cone[]) 2679552f7358SJed Brown { 2680552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2681552f7358SJed Brown PetscInt off; 2682552f7358SJed Brown PetscErrorCode ierr; 2683552f7358SJed Brown 2684552f7358SJed Brown PetscFunctionBegin; 2685552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2686552f7358SJed Brown PetscValidPointer(cone, 3); 2687552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 2688552f7358SJed Brown *cone = &mesh->cones[off]; 2689552f7358SJed Brown PetscFunctionReturn(0); 2690552f7358SJed Brown } 2691552f7358SJed Brown 26920ce7577fSVaclav Hapla /*@C 26930ce7577fSVaclav Hapla DMPlexGetConeTuple - Return the points on the in-edges of several points in the DAG 26940ce7577fSVaclav Hapla 26950ce7577fSVaclav Hapla Not collective 26960ce7577fSVaclav Hapla 26970ce7577fSVaclav Hapla Input Parameters: 26980ce7577fSVaclav Hapla + dm - The DMPlex 26990ce7577fSVaclav Hapla - p - The IS of points, which must lie in the chart set with DMPlexSetChart() 27000ce7577fSVaclav Hapla 2701d8d19677SJose E. Roman Output Parameters: 27020ce7577fSVaclav Hapla + pConesSection - PetscSection describing the layout of pCones 27030ce7577fSVaclav Hapla - pCones - An array of points which are on the in-edges for the point set p 27040ce7577fSVaclav Hapla 27050ce7577fSVaclav Hapla Level: intermediate 27060ce7577fSVaclav Hapla 2707d4636a37SVaclav Hapla .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexGetConeRecursive(), DMPlexSetChart() 27080ce7577fSVaclav Hapla @*/ 27090ce7577fSVaclav Hapla PetscErrorCode DMPlexGetConeTuple(DM dm, IS p, PetscSection *pConesSection, IS *pCones) 27100ce7577fSVaclav Hapla { 27110ce7577fSVaclav Hapla PetscSection cs, newcs; 27120ce7577fSVaclav Hapla PetscInt *cones; 27130ce7577fSVaclav Hapla PetscInt *newarr=NULL; 27140ce7577fSVaclav Hapla PetscInt n; 27150ce7577fSVaclav Hapla PetscErrorCode ierr; 27160ce7577fSVaclav Hapla 27170ce7577fSVaclav Hapla PetscFunctionBegin; 27180ce7577fSVaclav Hapla ierr = DMPlexGetCones(dm, &cones);CHKERRQ(ierr); 27190ce7577fSVaclav Hapla ierr = DMPlexGetConeSection(dm, &cs);CHKERRQ(ierr); 27200ce7577fSVaclav Hapla ierr = PetscSectionExtractDofsFromArray(cs, MPIU_INT, cones, p, &newcs, pCones ? ((void**)&newarr) : NULL);CHKERRQ(ierr); 27210ce7577fSVaclav Hapla if (pConesSection) *pConesSection = newcs; 27220ce7577fSVaclav Hapla if (pCones) { 27230ce7577fSVaclav Hapla ierr = PetscSectionGetStorageSize(newcs, &n);CHKERRQ(ierr); 27240ce7577fSVaclav Hapla ierr = ISCreateGeneral(PetscObjectComm((PetscObject)p), n, newarr, PETSC_OWN_POINTER, pCones);CHKERRQ(ierr); 27250ce7577fSVaclav Hapla } 27260ce7577fSVaclav Hapla PetscFunctionReturn(0); 27270ce7577fSVaclav Hapla } 27280ce7577fSVaclav Hapla 2729af9eab45SVaclav Hapla /*@ 2730af9eab45SVaclav Hapla DMPlexGetConeRecursiveVertices - Expand each given point into its cone points and do that recursively until we end up just with vertices. 2731d4636a37SVaclav Hapla 2732d4636a37SVaclav Hapla Not collective 2733d4636a37SVaclav Hapla 2734d4636a37SVaclav Hapla Input Parameters: 2735d4636a37SVaclav Hapla + dm - The DMPlex 2736af9eab45SVaclav Hapla - points - The IS of points, which must lie in the chart set with DMPlexSetChart() 2737d4636a37SVaclav Hapla 2738d4636a37SVaclav Hapla Output Parameter: 2739af9eab45SVaclav Hapla . expandedPoints - An array of vertices recursively expanded from input points 2740d4636a37SVaclav Hapla 2741d4636a37SVaclav Hapla Level: advanced 2742d4636a37SVaclav Hapla 2743af9eab45SVaclav Hapla Notes: 2744af9eab45SVaclav Hapla Like DMPlexGetConeRecursive but returns only the 0-depth IS (i.e. vertices only) and no sections. 2745af9eab45SVaclav Hapla There is no corresponding Restore function, just call ISDestroy() on the returned IS to deallocate. 2746af9eab45SVaclav Hapla 2747af9eab45SVaclav Hapla .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexGetConeTuple(), DMPlexGetConeRecursive(), DMPlexRestoreConeRecursive(), DMPlexGetDepth() 2748d4636a37SVaclav Hapla @*/ 2749af9eab45SVaclav Hapla PetscErrorCode DMPlexGetConeRecursiveVertices(DM dm, IS points, IS *expandedPoints) 2750d4636a37SVaclav Hapla { 2751af9eab45SVaclav Hapla IS *expandedPointsAll; 2752af9eab45SVaclav Hapla PetscInt depth; 2753d4636a37SVaclav Hapla PetscErrorCode ierr; 2754d4636a37SVaclav Hapla 2755d4636a37SVaclav Hapla PetscFunctionBegin; 2756af9eab45SVaclav Hapla PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2757af9eab45SVaclav Hapla PetscValidHeaderSpecific(points, IS_CLASSID, 2); 2758af9eab45SVaclav Hapla PetscValidPointer(expandedPoints, 3); 2759af9eab45SVaclav Hapla ierr = DMPlexGetConeRecursive(dm, points, &depth, &expandedPointsAll, NULL);CHKERRQ(ierr); 2760af9eab45SVaclav Hapla *expandedPoints = expandedPointsAll[0]; 27611e1ea65dSPierre Jolivet ierr = PetscObjectReference((PetscObject)expandedPointsAll[0]);CHKERRQ(ierr); 2762af9eab45SVaclav Hapla ierr = DMPlexRestoreConeRecursive(dm, points, &depth, &expandedPointsAll, NULL);CHKERRQ(ierr); 2763af9eab45SVaclav Hapla PetscFunctionReturn(0); 2764af9eab45SVaclav Hapla } 2765af9eab45SVaclav Hapla 2766af9eab45SVaclav Hapla /*@ 2767af9eab45SVaclav 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). 2768af9eab45SVaclav Hapla 2769af9eab45SVaclav Hapla Not collective 2770af9eab45SVaclav Hapla 2771af9eab45SVaclav Hapla Input Parameters: 2772af9eab45SVaclav Hapla + dm - The DMPlex 2773af9eab45SVaclav Hapla - points - The IS of points, which must lie in the chart set with DMPlexSetChart() 2774af9eab45SVaclav Hapla 2775d8d19677SJose E. Roman Output Parameters: 2776af9eab45SVaclav Hapla + depth - (optional) Size of the output arrays, equal to DMPlex depth, returned by DMPlexGetDepth() 2777af9eab45SVaclav Hapla . expandedPoints - (optional) An array of index sets with recursively expanded cones 2778af9eab45SVaclav Hapla - sections - (optional) An array of sections which describe mappings from points to their cone points 2779af9eab45SVaclav Hapla 2780af9eab45SVaclav Hapla Level: advanced 2781af9eab45SVaclav Hapla 2782af9eab45SVaclav Hapla Notes: 2783af9eab45SVaclav Hapla Like DMPlexGetConeTuple() but recursive. 2784af9eab45SVaclav Hapla 2785af9eab45SVaclav 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. 2786af9eab45SVaclav Hapla For example, for d=0 it contains only vertices, for d=1 it can contain vertices and edges, etc. 2787af9eab45SVaclav Hapla 2788af9eab45SVaclav 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: 2789af9eab45SVaclav Hapla (1) DAG points in expandedPoints[d+1] with depth d+1 to their cone points in expandedPoints[d]; 2790af9eab45SVaclav Hapla (2) DAG points in expandedPoints[d+1] with depth in [0,d] to the same points in expandedPoints[d]. 2791af9eab45SVaclav Hapla 2792af9eab45SVaclav Hapla .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexGetConeTuple(), DMPlexRestoreConeRecursive(), DMPlexGetConeRecursiveVertices(), DMPlexGetDepth() 2793af9eab45SVaclav Hapla @*/ 2794af9eab45SVaclav Hapla PetscErrorCode DMPlexGetConeRecursive(DM dm, IS points, PetscInt *depth, IS *expandedPoints[], PetscSection *sections[]) 2795af9eab45SVaclav Hapla { 2796af9eab45SVaclav Hapla const PetscInt *arr0=NULL, *cone=NULL; 2797af9eab45SVaclav Hapla PetscInt *arr=NULL, *newarr=NULL; 2798af9eab45SVaclav Hapla PetscInt d, depth_, i, n, newn, cn, co, start, end; 2799af9eab45SVaclav Hapla IS *expandedPoints_; 2800af9eab45SVaclav Hapla PetscSection *sections_; 2801af9eab45SVaclav Hapla PetscErrorCode ierr; 2802af9eab45SVaclav Hapla 2803af9eab45SVaclav Hapla PetscFunctionBegin; 2804af9eab45SVaclav Hapla PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2805af9eab45SVaclav Hapla PetscValidHeaderSpecific(points, IS_CLASSID, 2); 2806af9eab45SVaclav Hapla if (depth) PetscValidIntPointer(depth, 3); 2807af9eab45SVaclav Hapla if (expandedPoints) PetscValidPointer(expandedPoints, 4); 2808af9eab45SVaclav Hapla if (sections) PetscValidPointer(sections, 5); 2809af9eab45SVaclav Hapla ierr = ISGetLocalSize(points, &n);CHKERRQ(ierr); 2810af9eab45SVaclav Hapla ierr = ISGetIndices(points, &arr0);CHKERRQ(ierr); 2811af9eab45SVaclav Hapla ierr = DMPlexGetDepth(dm, &depth_);CHKERRQ(ierr); 2812af9eab45SVaclav Hapla ierr = PetscCalloc1(depth_, &expandedPoints_);CHKERRQ(ierr); 2813af9eab45SVaclav Hapla ierr = PetscCalloc1(depth_, §ions_);CHKERRQ(ierr); 2814af9eab45SVaclav Hapla arr = (PetscInt*) arr0; /* this is ok because first generation of arr is not modified */ 2815af9eab45SVaclav Hapla for (d=depth_-1; d>=0; d--) { 2816af9eab45SVaclav Hapla ierr = PetscSectionCreate(PETSC_COMM_SELF, §ions_[d]);CHKERRQ(ierr); 2817af9eab45SVaclav Hapla ierr = PetscSectionSetChart(sections_[d], 0, n);CHKERRQ(ierr); 2818af9eab45SVaclav Hapla for (i=0; i<n; i++) { 2819af9eab45SVaclav Hapla ierr = DMPlexGetDepthStratum(dm, d+1, &start, &end);CHKERRQ(ierr); 2820af9eab45SVaclav Hapla if (arr[i] >= start && arr[i] < end) { 2821af9eab45SVaclav Hapla ierr = DMPlexGetConeSize(dm, arr[i], &cn);CHKERRQ(ierr); 2822af9eab45SVaclav Hapla ierr = PetscSectionSetDof(sections_[d], i, cn);CHKERRQ(ierr); 2823af9eab45SVaclav Hapla } else { 2824af9eab45SVaclav Hapla ierr = PetscSectionSetDof(sections_[d], i, 1);CHKERRQ(ierr); 2825af9eab45SVaclav Hapla } 2826af9eab45SVaclav Hapla } 2827af9eab45SVaclav Hapla ierr = PetscSectionSetUp(sections_[d]);CHKERRQ(ierr); 2828af9eab45SVaclav Hapla ierr = PetscSectionGetStorageSize(sections_[d], &newn);CHKERRQ(ierr); 2829af9eab45SVaclav Hapla ierr = PetscMalloc1(newn, &newarr);CHKERRQ(ierr); 2830af9eab45SVaclav Hapla for (i=0; i<n; i++) { 2831af9eab45SVaclav Hapla ierr = PetscSectionGetDof(sections_[d], i, &cn);CHKERRQ(ierr); 2832af9eab45SVaclav Hapla ierr = PetscSectionGetOffset(sections_[d], i, &co);CHKERRQ(ierr); 2833af9eab45SVaclav Hapla if (cn > 1) { 2834af9eab45SVaclav Hapla ierr = DMPlexGetCone(dm, arr[i], &cone);CHKERRQ(ierr); 2835af9eab45SVaclav Hapla ierr = PetscMemcpy(&newarr[co], cone, cn*sizeof(PetscInt));CHKERRQ(ierr); 2836af9eab45SVaclav Hapla } else { 2837af9eab45SVaclav Hapla newarr[co] = arr[i]; 2838af9eab45SVaclav Hapla } 2839af9eab45SVaclav Hapla } 2840af9eab45SVaclav Hapla ierr = ISCreateGeneral(PETSC_COMM_SELF, newn, newarr, PETSC_OWN_POINTER, &expandedPoints_[d]);CHKERRQ(ierr); 2841af9eab45SVaclav Hapla arr = newarr; 2842af9eab45SVaclav Hapla n = newn; 2843af9eab45SVaclav Hapla } 2844ba2698f1SMatthew G. Knepley ierr = ISRestoreIndices(points, &arr0);CHKERRQ(ierr); 2845af9eab45SVaclav Hapla *depth = depth_; 2846af9eab45SVaclav Hapla if (expandedPoints) *expandedPoints = expandedPoints_; 2847af9eab45SVaclav Hapla else { 2848af9eab45SVaclav Hapla for (d=0; d<depth_; d++) {ierr = ISDestroy(&expandedPoints_[d]);CHKERRQ(ierr);} 2849af9eab45SVaclav Hapla ierr = PetscFree(expandedPoints_);CHKERRQ(ierr); 2850af9eab45SVaclav Hapla } 2851af9eab45SVaclav Hapla if (sections) *sections = sections_; 2852af9eab45SVaclav Hapla else { 2853af9eab45SVaclav Hapla for (d=0; d<depth_; d++) {ierr = PetscSectionDestroy(§ions_[d]);CHKERRQ(ierr);} 2854af9eab45SVaclav Hapla ierr = PetscFree(sections_);CHKERRQ(ierr); 2855af9eab45SVaclav Hapla } 2856af9eab45SVaclav Hapla PetscFunctionReturn(0); 2857af9eab45SVaclav Hapla } 2858af9eab45SVaclav Hapla 2859af9eab45SVaclav Hapla /*@ 2860af9eab45SVaclav Hapla DMPlexRestoreConeRecursive - Deallocates arrays created by DMPlexGetConeRecursive 2861af9eab45SVaclav Hapla 2862af9eab45SVaclav Hapla Not collective 2863af9eab45SVaclav Hapla 2864af9eab45SVaclav Hapla Input Parameters: 2865af9eab45SVaclav Hapla + dm - The DMPlex 2866af9eab45SVaclav Hapla - points - The IS of points, which must lie in the chart set with DMPlexSetChart() 2867af9eab45SVaclav Hapla 2868d8d19677SJose E. Roman Output Parameters: 2869af9eab45SVaclav Hapla + depth - (optional) Size of the output arrays, equal to DMPlex depth, returned by DMPlexGetDepth() 2870af9eab45SVaclav Hapla . expandedPoints - (optional) An array of recursively expanded cones 2871af9eab45SVaclav Hapla - sections - (optional) An array of sections which describe mappings from points to their cone points 2872af9eab45SVaclav Hapla 2873af9eab45SVaclav Hapla Level: advanced 2874af9eab45SVaclav Hapla 2875af9eab45SVaclav Hapla Notes: 2876af9eab45SVaclav Hapla See DMPlexGetConeRecursive() for details. 2877af9eab45SVaclav Hapla 2878af9eab45SVaclav Hapla .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexGetConeTuple(), DMPlexGetConeRecursive(), DMPlexGetConeRecursiveVertices(), DMPlexGetDepth() 2879af9eab45SVaclav Hapla @*/ 2880af9eab45SVaclav Hapla PetscErrorCode DMPlexRestoreConeRecursive(DM dm, IS points, PetscInt *depth, IS *expandedPoints[], PetscSection *sections[]) 2881af9eab45SVaclav Hapla { 2882af9eab45SVaclav Hapla PetscInt d, depth_; 2883af9eab45SVaclav Hapla PetscErrorCode ierr; 2884af9eab45SVaclav Hapla 2885af9eab45SVaclav Hapla PetscFunctionBegin; 2886af9eab45SVaclav Hapla ierr = DMPlexGetDepth(dm, &depth_);CHKERRQ(ierr); 2887af9eab45SVaclav Hapla if (depth && *depth != depth_) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "depth changed since last call to DMPlexGetConeRecursive"); 2888af9eab45SVaclav Hapla if (depth) *depth = 0; 2889af9eab45SVaclav Hapla if (expandedPoints) { 2890af9eab45SVaclav Hapla for (d=0; d<depth_; d++) {ierr = ISDestroy(&((*expandedPoints)[d]));CHKERRQ(ierr);} 2891af9eab45SVaclav Hapla ierr = PetscFree(*expandedPoints);CHKERRQ(ierr); 2892af9eab45SVaclav Hapla } 2893af9eab45SVaclav Hapla if (sections) { 2894af9eab45SVaclav Hapla for (d=0; d<depth_; d++) {ierr = PetscSectionDestroy(&((*sections)[d]));CHKERRQ(ierr);} 2895af9eab45SVaclav Hapla ierr = PetscFree(*sections);CHKERRQ(ierr); 2896af9eab45SVaclav Hapla } 2897d4636a37SVaclav Hapla PetscFunctionReturn(0); 2898d4636a37SVaclav Hapla } 2899d4636a37SVaclav Hapla 2900552f7358SJed Brown /*@ 290192371b87SBarry 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 2902552f7358SJed Brown 2903552f7358SJed Brown Not collective 2904552f7358SJed Brown 2905552f7358SJed Brown Input Parameters: 2906552f7358SJed Brown + mesh - The DMPlex 2907eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 2908552f7358SJed Brown - cone - An array of points which are on the in-edges for point p 2909552f7358SJed Brown 2910552f7358SJed Brown Output Parameter: 2911552f7358SJed Brown 2912552f7358SJed Brown Note: 2913552f7358SJed Brown This should be called after all calls to DMPlexSetConeSize() and DMSetUp(). 2914552f7358SJed Brown 2915552f7358SJed Brown Level: beginner 2916552f7358SJed Brown 291792371b87SBarry Smith .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexSetChart(), DMPlexSetConeSize(), DMSetUp(), DMPlexSetSupport(), DMPlexSetSupportSize() 2918552f7358SJed Brown @*/ 2919552f7358SJed Brown PetscErrorCode DMPlexSetCone(DM dm, PetscInt p, const PetscInt cone[]) 2920552f7358SJed Brown { 2921552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2922552f7358SJed Brown PetscInt pStart, pEnd; 2923552f7358SJed Brown PetscInt dof, off, c; 2924552f7358SJed Brown PetscErrorCode ierr; 2925552f7358SJed Brown 2926552f7358SJed Brown PetscFunctionBegin; 2927552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2928552f7358SJed Brown ierr = PetscSectionGetChart(mesh->coneSection, &pStart, &pEnd);CHKERRQ(ierr); 2929552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 2930552f7358SJed Brown if (dof) PetscValidPointer(cone, 3); 2931552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 293282f516ccSBarry Smith if ((p < pStart) || (p >= pEnd)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Mesh point %D is not in the valid range [%D, %D)", p, pStart, pEnd); 2933552f7358SJed Brown for (c = 0; c < dof; ++c) { 293482f516ccSBarry Smith if ((cone[c] < pStart) || (cone[c] >= pEnd)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cone point %D is not in the valid range [%D, %D)", cone[c], pStart, pEnd); 2935552f7358SJed Brown mesh->cones[off+c] = cone[c]; 2936552f7358SJed Brown } 2937552f7358SJed Brown PetscFunctionReturn(0); 2938552f7358SJed Brown } 2939552f7358SJed Brown 2940552f7358SJed Brown /*@C 2941eaf898f9SPatrick Sanan DMPlexGetConeOrientation - Return the orientations on the in-edges for this point in the DAG 2942552f7358SJed Brown 2943552f7358SJed Brown Not collective 2944552f7358SJed Brown 2945552f7358SJed Brown Input Parameters: 2946552f7358SJed Brown + mesh - The DMPlex 2947eaf898f9SPatrick Sanan - p - The point, which must lie in the chart set with DMPlexSetChart() 2948552f7358SJed Brown 2949552f7358SJed Brown Output Parameter: 2950552f7358SJed Brown . coneOrientation - An array of orientations which are on the in-edges for point p. An orientation is an 2951b5a892a1SMatthew G. Knepley integer giving the prescription for cone traversal. 2952552f7358SJed Brown 2953552f7358SJed Brown Level: beginner 2954552f7358SJed Brown 2955b5a892a1SMatthew G. Knepley Notes: 2956b5a892a1SMatthew G. Knepley The number indexes the symmetry transformations for the cell type (see manual). Orientation 0 is always 2957b5a892a1SMatthew G. Knepley the identity transformation. Negative orientation indicates reflection so that -(o+1) is the reflection 2958b5a892a1SMatthew G. Knepley of o, however it is not necessarily the inverse. To get the inverse, use DMPolytopeTypeComposeOrientationInv() 2959b5a892a1SMatthew G. Knepley with the identity. 2960b5a892a1SMatthew G. Knepley 29613813dfbdSMatthew G Knepley Fortran Notes: 29623813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 29633813dfbdSMatthew G Knepley include petsc.h90 in your code. 29643b12b3d8SVaclav Hapla You must also call DMPlexRestoreConeOrientation() after you finish using the returned array. 2965922102d1SVaclav Hapla DMPlexRestoreConeOrientation() is not needed/available in C. 29663813dfbdSMatthew G Knepley 2967b5a892a1SMatthew G. Knepley .seealso: DMPolytopeTypeComposeOrientation(), DMPolytopeTypeComposeOrientationInv(), DMPlexCreate(), DMPlexGetCone(), DMPlexSetCone(), DMPlexSetChart() 2968552f7358SJed Brown @*/ 2969552f7358SJed Brown PetscErrorCode DMPlexGetConeOrientation(DM dm, PetscInt p, const PetscInt *coneOrientation[]) 2970552f7358SJed Brown { 2971552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2972552f7358SJed Brown PetscInt off; 2973552f7358SJed Brown PetscErrorCode ierr; 2974552f7358SJed Brown 2975552f7358SJed Brown PetscFunctionBegin; 2976552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 297776bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 2978552f7358SJed Brown PetscInt dof; 2979552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 2980552f7358SJed Brown if (dof) PetscValidPointer(coneOrientation, 3); 2981552f7358SJed Brown } 2982552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 29830d644c17SKarl Rupp 2984552f7358SJed Brown *coneOrientation = &mesh->coneOrientations[off]; 2985552f7358SJed Brown PetscFunctionReturn(0); 2986552f7358SJed Brown } 2987552f7358SJed Brown 2988552f7358SJed Brown /*@ 2989eaf898f9SPatrick Sanan DMPlexSetConeOrientation - Set the orientations on the in-edges for this point in the DAG 2990552f7358SJed Brown 2991552f7358SJed Brown Not collective 2992552f7358SJed Brown 2993552f7358SJed Brown Input Parameters: 2994552f7358SJed Brown + mesh - The DMPlex 2995eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 2996b5a892a1SMatthew G. Knepley - coneOrientation - An array of orientations 2997552f7358SJed Brown Output Parameter: 2998552f7358SJed Brown 2999b5a892a1SMatthew G. Knepley Notes: 3000552f7358SJed Brown This should be called after all calls to DMPlexSetConeSize() and DMSetUp(). 3001552f7358SJed Brown 3002b5a892a1SMatthew G. Knepley The meaning of coneOrientation is detailed in DMPlexGetConeOrientation(). 3003b5a892a1SMatthew G. Knepley 3004552f7358SJed Brown Level: beginner 3005552f7358SJed Brown 3006552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetConeOrientation(), DMPlexSetCone(), DMPlexSetChart(), DMPlexSetConeSize(), DMSetUp() 3007552f7358SJed Brown @*/ 3008552f7358SJed Brown PetscErrorCode DMPlexSetConeOrientation(DM dm, PetscInt p, const PetscInt coneOrientation[]) 3009552f7358SJed Brown { 3010552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3011552f7358SJed Brown PetscInt pStart, pEnd; 3012552f7358SJed Brown PetscInt dof, off, c; 3013552f7358SJed Brown PetscErrorCode ierr; 3014552f7358SJed Brown 3015552f7358SJed Brown PetscFunctionBegin; 3016552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3017552f7358SJed Brown ierr = PetscSectionGetChart(mesh->coneSection, &pStart, &pEnd);CHKERRQ(ierr); 3018552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 3019552f7358SJed Brown if (dof) PetscValidPointer(coneOrientation, 3); 3020552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 302182f516ccSBarry Smith if ((p < pStart) || (p >= pEnd)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Mesh point %D is not in the valid range [%D, %D)", p, pStart, pEnd); 3022552f7358SJed Brown for (c = 0; c < dof; ++c) { 3023552f7358SJed Brown PetscInt cdof, o = coneOrientation[c]; 3024552f7358SJed Brown 3025552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, mesh->cones[off+c], &cdof);CHKERRQ(ierr); 302682f516ccSBarry Smith if (o && ((o < -(cdof+1)) || (o >= cdof))) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cone orientation %D is not in the valid range [%D. %D)", o, -(cdof+1), cdof); 3027552f7358SJed Brown mesh->coneOrientations[off+c] = o; 3028552f7358SJed Brown } 3029552f7358SJed Brown PetscFunctionReturn(0); 3030552f7358SJed Brown } 3031552f7358SJed Brown 30327cd05799SMatthew G. Knepley /*@ 3033eaf898f9SPatrick Sanan DMPlexInsertCone - Insert a point into the in-edges for the point p in the DAG 30347cd05799SMatthew G. Knepley 30357cd05799SMatthew G. Knepley Not collective 30367cd05799SMatthew G. Knepley 30377cd05799SMatthew G. Knepley Input Parameters: 30387cd05799SMatthew G. Knepley + mesh - The DMPlex 3039eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 30407cd05799SMatthew G. Knepley . conePos - The local index in the cone where the point should be put 30417cd05799SMatthew G. Knepley - conePoint - The mesh point to insert 30427cd05799SMatthew G. Knepley 30437cd05799SMatthew G. Knepley Level: beginner 30447cd05799SMatthew G. Knepley 30457cd05799SMatthew G. Knepley .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexSetChart(), DMPlexSetConeSize(), DMSetUp() 30467cd05799SMatthew G. Knepley @*/ 3047552f7358SJed Brown PetscErrorCode DMPlexInsertCone(DM dm, PetscInt p, PetscInt conePos, PetscInt conePoint) 3048552f7358SJed Brown { 3049552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3050552f7358SJed Brown PetscInt pStart, pEnd; 3051552f7358SJed Brown PetscInt dof, off; 3052552f7358SJed Brown PetscErrorCode ierr; 3053552f7358SJed Brown 3054552f7358SJed Brown PetscFunctionBegin; 3055552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3056552f7358SJed Brown ierr = PetscSectionGetChart(mesh->coneSection, &pStart, &pEnd);CHKERRQ(ierr); 305782f516ccSBarry Smith if ((p < pStart) || (p >= pEnd)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Mesh point %D is not in the valid range [%D, %D)", p, pStart, pEnd); 305882f516ccSBarry Smith if ((conePoint < pStart) || (conePoint >= pEnd)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cone point %D is not in the valid range [%D, %D)", conePoint, pStart, pEnd); 305977c88f5bSMatthew G Knepley ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 306077c88f5bSMatthew G Knepley ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 306177c88f5bSMatthew G Knepley if ((conePos < 0) || (conePos >= dof)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cone position %D of point %D is not in the valid range [0, %D)", conePos, p, dof); 3062552f7358SJed Brown mesh->cones[off+conePos] = conePoint; 3063552f7358SJed Brown PetscFunctionReturn(0); 3064552f7358SJed Brown } 3065552f7358SJed Brown 30667cd05799SMatthew G. Knepley /*@ 3067eaf898f9SPatrick Sanan DMPlexInsertConeOrientation - Insert a point orientation for the in-edge for the point p in the DAG 30687cd05799SMatthew G. Knepley 30697cd05799SMatthew G. Knepley Not collective 30707cd05799SMatthew G. Knepley 30717cd05799SMatthew G. Knepley Input Parameters: 30727cd05799SMatthew G. Knepley + mesh - The DMPlex 3073eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 30747cd05799SMatthew G. Knepley . conePos - The local index in the cone where the point should be put 30757cd05799SMatthew G. Knepley - coneOrientation - The point orientation to insert 30767cd05799SMatthew G. Knepley 30777cd05799SMatthew G. Knepley Level: beginner 30787cd05799SMatthew G. Knepley 3079b5a892a1SMatthew G. Knepley Notes: 3080b5a892a1SMatthew G. Knepley The meaning of coneOrientation values is detailed in DMPlexGetConeOrientation(). 3081b5a892a1SMatthew G. Knepley 30827cd05799SMatthew G. Knepley .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexSetChart(), DMPlexSetConeSize(), DMSetUp() 30837cd05799SMatthew G. Knepley @*/ 308477c88f5bSMatthew G Knepley PetscErrorCode DMPlexInsertConeOrientation(DM dm, PetscInt p, PetscInt conePos, PetscInt coneOrientation) 308577c88f5bSMatthew G Knepley { 308677c88f5bSMatthew G Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 308777c88f5bSMatthew G Knepley PetscInt pStart, pEnd; 308877c88f5bSMatthew G Knepley PetscInt dof, off; 308977c88f5bSMatthew G Knepley PetscErrorCode ierr; 309077c88f5bSMatthew G Knepley 309177c88f5bSMatthew G Knepley PetscFunctionBegin; 309277c88f5bSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 309377c88f5bSMatthew G Knepley ierr = PetscSectionGetChart(mesh->coneSection, &pStart, &pEnd);CHKERRQ(ierr); 309477c88f5bSMatthew G Knepley if ((p < pStart) || (p >= pEnd)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Mesh point %D is not in the valid range [%D, %D)", p, pStart, pEnd); 309577c88f5bSMatthew G Knepley ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 309677c88f5bSMatthew G Knepley ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 309777c88f5bSMatthew G Knepley if ((conePos < 0) || (conePos >= dof)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Cone position %D of point %D is not in the valid range [0, %D)", conePos, p, dof); 309877c88f5bSMatthew G Knepley mesh->coneOrientations[off+conePos] = coneOrientation; 309977c88f5bSMatthew G Knepley PetscFunctionReturn(0); 310077c88f5bSMatthew G Knepley } 310177c88f5bSMatthew G Knepley 3102552f7358SJed Brown /*@ 3103eaf898f9SPatrick Sanan DMPlexGetSupportSize - Return the number of out-edges for this point in the DAG 3104552f7358SJed Brown 3105552f7358SJed Brown Not collective 3106552f7358SJed Brown 3107552f7358SJed Brown Input Parameters: 3108552f7358SJed Brown + mesh - The DMPlex 3109eaf898f9SPatrick Sanan - p - The point, which must lie in the chart set with DMPlexSetChart() 3110552f7358SJed Brown 3111552f7358SJed Brown Output Parameter: 3112552f7358SJed Brown . size - The support size for point p 3113552f7358SJed Brown 3114552f7358SJed Brown Level: beginner 3115552f7358SJed Brown 3116552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetConeSize(), DMPlexSetChart(), DMPlexGetConeSize() 3117552f7358SJed Brown @*/ 3118552f7358SJed Brown PetscErrorCode DMPlexGetSupportSize(DM dm, PetscInt p, PetscInt *size) 3119552f7358SJed Brown { 3120552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3121552f7358SJed Brown PetscErrorCode ierr; 3122552f7358SJed Brown 3123552f7358SJed Brown PetscFunctionBegin; 3124552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3125552f7358SJed Brown PetscValidPointer(size, 3); 3126552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, size);CHKERRQ(ierr); 3127552f7358SJed Brown PetscFunctionReturn(0); 3128552f7358SJed Brown } 3129552f7358SJed Brown 3130552f7358SJed Brown /*@ 3131eaf898f9SPatrick Sanan DMPlexSetSupportSize - Set the number of out-edges for this point in the DAG 3132552f7358SJed Brown 3133552f7358SJed Brown Not collective 3134552f7358SJed Brown 3135552f7358SJed Brown Input Parameters: 3136552f7358SJed Brown + mesh - The DMPlex 3137eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 3138552f7358SJed Brown - size - The support size for point p 3139552f7358SJed Brown 3140552f7358SJed Brown Output Parameter: 3141552f7358SJed Brown 3142552f7358SJed Brown Note: 3143552f7358SJed Brown This should be called after DMPlexSetChart(). 3144552f7358SJed Brown 3145552f7358SJed Brown Level: beginner 3146552f7358SJed Brown 3147552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetSupportSize(), DMPlexSetChart() 3148552f7358SJed Brown @*/ 3149552f7358SJed Brown PetscErrorCode DMPlexSetSupportSize(DM dm, PetscInt p, PetscInt size) 3150552f7358SJed Brown { 3151552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3152552f7358SJed Brown PetscErrorCode ierr; 3153552f7358SJed Brown 3154552f7358SJed Brown PetscFunctionBegin; 3155552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3156552f7358SJed Brown ierr = PetscSectionSetDof(mesh->supportSection, p, size);CHKERRQ(ierr); 31570d644c17SKarl Rupp 3158552f7358SJed Brown mesh->maxSupportSize = PetscMax(mesh->maxSupportSize, size); 3159552f7358SJed Brown PetscFunctionReturn(0); 3160552f7358SJed Brown } 3161552f7358SJed Brown 3162552f7358SJed Brown /*@C 3163eaf898f9SPatrick Sanan DMPlexGetSupport - Return the points on the out-edges for this point in the DAG 3164552f7358SJed Brown 3165552f7358SJed Brown Not collective 3166552f7358SJed Brown 3167552f7358SJed Brown Input Parameters: 3168552f7358SJed Brown + mesh - The DMPlex 3169eaf898f9SPatrick Sanan - p - The point, which must lie in the chart set with DMPlexSetChart() 3170552f7358SJed Brown 3171552f7358SJed Brown Output Parameter: 3172552f7358SJed Brown . support - An array of points which are on the out-edges for point p 3173552f7358SJed Brown 3174552f7358SJed Brown Level: beginner 3175552f7358SJed Brown 31763813dfbdSMatthew G Knepley Fortran Notes: 31773813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 31783813dfbdSMatthew G Knepley include petsc.h90 in your code. 31793b12b3d8SVaclav Hapla You must also call DMPlexRestoreSupport() after you finish using the returned array. 3180922102d1SVaclav Hapla DMPlexRestoreSupport() is not needed/available in C. 31813813dfbdSMatthew G Knepley 3182e45f02b0SMatthew G. Knepley .seealso: DMPlexGetSupportSize(), DMPlexSetSupport(), DMPlexGetCone(), DMPlexSetChart() 3183552f7358SJed Brown @*/ 3184552f7358SJed Brown PetscErrorCode DMPlexGetSupport(DM dm, PetscInt p, const PetscInt *support[]) 3185552f7358SJed Brown { 3186552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3187552f7358SJed Brown PetscInt off; 3188552f7358SJed Brown PetscErrorCode ierr; 3189552f7358SJed Brown 3190552f7358SJed Brown PetscFunctionBegin; 3191552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3192552f7358SJed Brown PetscValidPointer(support, 3); 3193552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, p, &off);CHKERRQ(ierr); 3194552f7358SJed Brown *support = &mesh->supports[off]; 3195552f7358SJed Brown PetscFunctionReturn(0); 3196552f7358SJed Brown } 3197552f7358SJed Brown 3198552f7358SJed Brown /*@ 319992371b87SBarry 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 3200552f7358SJed Brown 3201552f7358SJed Brown Not collective 3202552f7358SJed Brown 3203552f7358SJed Brown Input Parameters: 3204552f7358SJed Brown + mesh - The DMPlex 3205eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 320692371b87SBarry Smith - support - An array of points which are on the out-edges for point p 3207552f7358SJed Brown 3208552f7358SJed Brown Output Parameter: 3209552f7358SJed Brown 3210552f7358SJed Brown Note: 3211552f7358SJed Brown This should be called after all calls to DMPlexSetSupportSize() and DMSetUp(). 3212552f7358SJed Brown 3213552f7358SJed Brown Level: beginner 3214552f7358SJed Brown 321592371b87SBarry Smith .seealso: DMPlexSetCone(), DMPlexSetConeSize(), DMPlexCreate(), DMPlexGetSupport(), DMPlexSetChart(), DMPlexSetSupportSize(), DMSetUp() 3216552f7358SJed Brown @*/ 3217552f7358SJed Brown PetscErrorCode DMPlexSetSupport(DM dm, PetscInt p, const PetscInt support[]) 3218552f7358SJed Brown { 3219552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3220552f7358SJed Brown PetscInt pStart, pEnd; 3221552f7358SJed Brown PetscInt dof, off, c; 3222552f7358SJed Brown PetscErrorCode ierr; 3223552f7358SJed Brown 3224552f7358SJed Brown PetscFunctionBegin; 3225552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3226552f7358SJed Brown ierr = PetscSectionGetChart(mesh->supportSection, &pStart, &pEnd);CHKERRQ(ierr); 3227552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, &dof);CHKERRQ(ierr); 3228552f7358SJed Brown if (dof) PetscValidPointer(support, 3); 3229552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, p, &off);CHKERRQ(ierr); 323082f516ccSBarry Smith if ((p < pStart) || (p >= pEnd)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Mesh point %D is not in the valid range [%D, %D)", p, pStart, pEnd); 3231552f7358SJed Brown for (c = 0; c < dof; ++c) { 323282f516ccSBarry Smith if ((support[c] < pStart) || (support[c] >= pEnd)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Support point %D is not in the valid range [%D, %D)", support[c], pStart, pEnd); 3233552f7358SJed Brown mesh->supports[off+c] = support[c]; 3234552f7358SJed Brown } 3235552f7358SJed Brown PetscFunctionReturn(0); 3236552f7358SJed Brown } 3237552f7358SJed Brown 32387cd05799SMatthew G. Knepley /*@ 3239eaf898f9SPatrick Sanan DMPlexInsertSupport - Insert a point into the out-edges for the point p in the DAG 32407cd05799SMatthew G. Knepley 32417cd05799SMatthew G. Knepley Not collective 32427cd05799SMatthew G. Knepley 32437cd05799SMatthew G. Knepley Input Parameters: 32447cd05799SMatthew G. Knepley + mesh - The DMPlex 3245eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 32467cd05799SMatthew G. Knepley . supportPos - The local index in the cone where the point should be put 32477cd05799SMatthew G. Knepley - supportPoint - The mesh point to insert 32487cd05799SMatthew G. Knepley 32497cd05799SMatthew G. Knepley Level: beginner 32507cd05799SMatthew G. Knepley 32517cd05799SMatthew G. Knepley .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexSetChart(), DMPlexSetConeSize(), DMSetUp() 32527cd05799SMatthew G. Knepley @*/ 3253552f7358SJed Brown PetscErrorCode DMPlexInsertSupport(DM dm, PetscInt p, PetscInt supportPos, PetscInt supportPoint) 3254552f7358SJed Brown { 3255552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3256552f7358SJed Brown PetscInt pStart, pEnd; 3257552f7358SJed Brown PetscInt dof, off; 3258552f7358SJed Brown PetscErrorCode ierr; 3259552f7358SJed Brown 3260552f7358SJed Brown PetscFunctionBegin; 3261552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3262552f7358SJed Brown ierr = PetscSectionGetChart(mesh->supportSection, &pStart, &pEnd);CHKERRQ(ierr); 3263552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, &dof);CHKERRQ(ierr); 3264552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, p, &off);CHKERRQ(ierr); 326582f516ccSBarry Smith if ((p < pStart) || (p >= pEnd)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Mesh point %D is not in the valid range [%D, %D)", p, pStart, pEnd); 326682f516ccSBarry Smith if ((supportPoint < pStart) || (supportPoint >= pEnd)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Support point %D is not in the valid range [%D, %D)", supportPoint, pStart, pEnd); 326782f516ccSBarry Smith if (supportPos >= dof) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Support position %D of point %D is not in the valid range [0, %D)", supportPos, p, dof); 3268552f7358SJed Brown mesh->supports[off+supportPos] = supportPoint; 3269552f7358SJed Brown PetscFunctionReturn(0); 3270552f7358SJed Brown } 3271552f7358SJed Brown 3272b5a892a1SMatthew G. Knepley /* Converts an orientation o in the current numbering to the previous scheme used in Plex */ 3273b5a892a1SMatthew G. Knepley PetscInt DMPolytopeConvertNewOrientation_Internal(DMPolytopeType ct, PetscInt o) 3274b5a892a1SMatthew G. Knepley { 3275b5a892a1SMatthew G. Knepley switch (ct) { 3276b5a892a1SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 3277b5a892a1SMatthew G. Knepley if (o == -1) return -2; 3278b5a892a1SMatthew G. Knepley break; 3279b5a892a1SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 3280b5a892a1SMatthew G. Knepley if (o == -3) return -1; 3281b5a892a1SMatthew G. Knepley if (o == -2) return -3; 3282b5a892a1SMatthew G. Knepley if (o == -1) return -2; 3283b5a892a1SMatthew G. Knepley break; 3284b5a892a1SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 3285b5a892a1SMatthew G. Knepley if (o == -4) return -2; 3286b5a892a1SMatthew G. Knepley if (o == -3) return -1; 3287b5a892a1SMatthew G. Knepley if (o == -2) return -4; 3288b5a892a1SMatthew G. Knepley if (o == -1) return -3; 3289b5a892a1SMatthew G. Knepley break; 3290b5a892a1SMatthew G. Knepley default: return o; 3291b5a892a1SMatthew G. Knepley } 3292b5a892a1SMatthew G. Knepley return o; 3293b5a892a1SMatthew G. Knepley } 3294b5a892a1SMatthew G. Knepley 3295b5a892a1SMatthew G. Knepley /* Converts an orientation o in the previous scheme used in Plex to the current numbering */ 3296b5a892a1SMatthew G. Knepley PetscInt DMPolytopeConvertOldOrientation_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 == -2) || (o == 1)) return -1; 3301b5a892a1SMatthew G. Knepley if (o == -1) return 0; 3302b5a892a1SMatthew G. Knepley break; 3303b5a892a1SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 3304b5a892a1SMatthew G. Knepley if (o == -3) return -2; 3305b5a892a1SMatthew G. Knepley if (o == -2) return -1; 3306b5a892a1SMatthew G. Knepley if (o == -1) return -3; 3307b5a892a1SMatthew G. Knepley break; 3308b5a892a1SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 3309b5a892a1SMatthew G. Knepley if (o == -4) return -2; 3310b5a892a1SMatthew G. Knepley if (o == -3) return -1; 3311b5a892a1SMatthew G. Knepley if (o == -2) return -4; 3312b5a892a1SMatthew G. Knepley if (o == -1) return -3; 3313b5a892a1SMatthew G. Knepley break; 3314b5a892a1SMatthew G. Knepley default: return o; 3315b5a892a1SMatthew G. Knepley } 3316b5a892a1SMatthew G. Knepley return o; 3317b5a892a1SMatthew G. Knepley } 3318b5a892a1SMatthew G. Knepley 3319b5a892a1SMatthew G. Knepley /* Takes in a mesh whose orientations are in the previous scheme and converts them all to the current numbering */ 3320b5a892a1SMatthew G. Knepley PetscErrorCode DMPlexConvertOldOrientations_Internal(DM dm) 3321b5a892a1SMatthew G. Knepley { 3322b5a892a1SMatthew G. Knepley PetscInt pStart, pEnd, p; 3323b5a892a1SMatthew G. Knepley PetscErrorCode ierr; 3324b5a892a1SMatthew G. Knepley 3325b5a892a1SMatthew G. Knepley PetscFunctionBegin; 3326b5a892a1SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 3327b5a892a1SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 3328b5a892a1SMatthew G. Knepley const PetscInt *cone, *ornt; 3329b5a892a1SMatthew G. Knepley PetscInt coneSize, c; 3330b5a892a1SMatthew G. Knepley 3331b5a892a1SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, p, &coneSize);CHKERRQ(ierr); 3332b5a892a1SMatthew G. Knepley ierr = DMPlexGetCone(dm, p, &cone);CHKERRQ(ierr); 3333b5a892a1SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, p, &ornt);CHKERRQ(ierr); 3334b5a892a1SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 3335b5a892a1SMatthew G. Knepley DMPolytopeType ct; 3336b5a892a1SMatthew G. Knepley const PetscInt o = ornt[c]; 3337b5a892a1SMatthew G. Knepley 3338b5a892a1SMatthew G. Knepley ierr = DMPlexGetCellType(dm, cone[c], &ct);CHKERRQ(ierr); 3339b5a892a1SMatthew G. Knepley switch (ct) { 3340b5a892a1SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 3341b5a892a1SMatthew G. Knepley if ((o == -2) || (o == 1)) {ierr = DMPlexInsertConeOrientation(dm, p, c, -1);CHKERRQ(ierr);} 3342b5a892a1SMatthew G. Knepley if (o == -1) {ierr = DMPlexInsertConeOrientation(dm, p, c, 0);CHKERRQ(ierr);} 3343b5a892a1SMatthew G. Knepley break; 3344b5a892a1SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 3345b5a892a1SMatthew G. Knepley if (o == -3) {ierr = DMPlexInsertConeOrientation(dm, p, c, -2);CHKERRQ(ierr);} 3346b5a892a1SMatthew G. Knepley if (o == -2) {ierr = DMPlexInsertConeOrientation(dm, p, c, -1);CHKERRQ(ierr);} 3347b5a892a1SMatthew G. Knepley if (o == -1) {ierr = DMPlexInsertConeOrientation(dm, p, c, -3);CHKERRQ(ierr);} 3348b5a892a1SMatthew G. Knepley break; 3349b5a892a1SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 3350b5a892a1SMatthew G. Knepley if (o == -4) {ierr = DMPlexInsertConeOrientation(dm, p, c, -2);CHKERRQ(ierr);} 3351b5a892a1SMatthew G. Knepley if (o == -3) {ierr = DMPlexInsertConeOrientation(dm, p, c, -1);CHKERRQ(ierr);} 3352b5a892a1SMatthew G. Knepley if (o == -2) {ierr = DMPlexInsertConeOrientation(dm, p, c, -4);CHKERRQ(ierr);} 3353b5a892a1SMatthew G. Knepley if (o == -1) {ierr = DMPlexInsertConeOrientation(dm, p, c, -3);CHKERRQ(ierr);} 3354b5a892a1SMatthew G. Knepley break; 3355b5a892a1SMatthew G. Knepley default: break; 3356b5a892a1SMatthew G. Knepley } 3357b5a892a1SMatthew G. Knepley } 3358b5a892a1SMatthew G. Knepley } 3359b5a892a1SMatthew G. Knepley PetscFunctionReturn(0); 3360b5a892a1SMatthew G. Knepley } 3361b5a892a1SMatthew G. Knepley 3362012bc364SMatthew G. Knepley static PetscErrorCode DMPlexGetTransitiveClosure_Depth1_Private(DM dm, PetscInt p, PetscInt ornt, PetscBool useCone, PetscInt *numPoints, PetscInt *points[]) 3363b5a892a1SMatthew G. Knepley { 3364b5a892a1SMatthew G. Knepley DMPolytopeType ct = DM_POLYTOPE_UNKNOWN; 3365b5a892a1SMatthew G. Knepley PetscInt *closure; 3366b5a892a1SMatthew G. Knepley const PetscInt *tmp = NULL, *tmpO = NULL; 3367b5a892a1SMatthew G. Knepley PetscInt off = 0, tmpSize, t; 3368b5a892a1SMatthew G. Knepley PetscErrorCode ierr; 3369b5a892a1SMatthew G. Knepley 3370b5a892a1SMatthew G. Knepley PetscFunctionBeginHot; 3371b5a892a1SMatthew G. Knepley if (ornt) { 3372b5a892a1SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 3373b5a892a1SMatthew G. Knepley if (ct == DM_POLYTOPE_FV_GHOST || ct == DM_POLYTOPE_INTERIOR_GHOST || ct == DM_POLYTOPE_UNKNOWN) ct = DM_POLYTOPE_UNKNOWN; 3374b5a892a1SMatthew G. Knepley } 3375b5a892a1SMatthew G. Knepley if (*points) { 3376b5a892a1SMatthew G. Knepley closure = *points; 3377b5a892a1SMatthew G. Knepley } else { 3378b5a892a1SMatthew G. Knepley PetscInt maxConeSize, maxSupportSize; 3379b5a892a1SMatthew G. Knepley ierr = DMPlexGetMaxSizes(dm, &maxConeSize, &maxSupportSize);CHKERRQ(ierr); 3380b5a892a1SMatthew G. Knepley ierr = DMGetWorkArray(dm, 2*(PetscMax(maxConeSize, maxSupportSize)+1), MPIU_INT, &closure);CHKERRQ(ierr); 3381b5a892a1SMatthew G. Knepley } 3382b5a892a1SMatthew G. Knepley if (useCone) { 3383b5a892a1SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, p, &tmpSize);CHKERRQ(ierr); 3384b5a892a1SMatthew G. Knepley ierr = DMPlexGetCone(dm, p, &tmp);CHKERRQ(ierr); 3385b5a892a1SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, p, &tmpO);CHKERRQ(ierr); 3386b5a892a1SMatthew G. Knepley } else { 3387b5a892a1SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, p, &tmpSize);CHKERRQ(ierr); 3388b5a892a1SMatthew G. Knepley ierr = DMPlexGetSupport(dm, p, &tmp);CHKERRQ(ierr); 3389b5a892a1SMatthew G. Knepley } 3390b5a892a1SMatthew G. Knepley if (ct == DM_POLYTOPE_UNKNOWN) { 3391b5a892a1SMatthew G. Knepley closure[off++] = p; 3392b5a892a1SMatthew G. Knepley closure[off++] = 0; 3393b5a892a1SMatthew G. Knepley for (t = 0; t < tmpSize; ++t) { 3394b5a892a1SMatthew G. Knepley closure[off++] = tmp[t]; 3395b5a892a1SMatthew G. Knepley closure[off++] = tmpO ? tmpO[t] : 0; 3396b5a892a1SMatthew G. Knepley } 3397b5a892a1SMatthew G. Knepley } else { 3398b5a892a1SMatthew G. Knepley const PetscInt *arr = DMPolytopeTypeGetArrangment(ct, ornt);CHKERRQ(ierr); 3399b5a892a1SMatthew G. Knepley 3400b5a892a1SMatthew G. Knepley /* We assume that cells with a valid type have faces with a valid type */ 3401b5a892a1SMatthew G. Knepley closure[off++] = p; 3402b5a892a1SMatthew G. Knepley closure[off++] = ornt; 3403b5a892a1SMatthew G. Knepley for (t = 0; t < tmpSize; ++t) { 3404b5a892a1SMatthew G. Knepley DMPolytopeType ft; 3405b5a892a1SMatthew G. Knepley 3406b5a892a1SMatthew G. Knepley ierr = DMPlexGetCellType(dm, tmp[t], &ft);CHKERRQ(ierr); 3407b5a892a1SMatthew G. Knepley closure[off++] = tmp[arr[t]]; 3408b5a892a1SMatthew G. Knepley closure[off++] = tmpO ? DMPolytopeTypeComposeOrientation(ft, ornt, tmpO[t]) : 0; 3409b5a892a1SMatthew G. Knepley } 3410b5a892a1SMatthew G. Knepley } 3411b5a892a1SMatthew G. Knepley if (numPoints) *numPoints = tmpSize+1; 3412b5a892a1SMatthew G. Knepley if (points) *points = closure; 3413b5a892a1SMatthew G. Knepley PetscFunctionReturn(0); 3414b5a892a1SMatthew G. Knepley } 3415b5a892a1SMatthew G. Knepley 3416b5a892a1SMatthew G. Knepley /* We need a special tensor verison becasue we want to allow duplicate points in the endcaps for hybrid cells */ 3417b5a892a1SMatthew G. Knepley static PetscErrorCode DMPlexTransitiveClosure_Tensor_Internal(DM dm, PetscInt point, DMPolytopeType ct, PetscInt o, PetscBool useCone, PetscInt *numPoints, PetscInt **points) 3418b5a892a1SMatthew G. Knepley { 3419b5a892a1SMatthew G. Knepley const PetscInt *arr = DMPolytopeTypeGetArrangment(ct, o); 3420b5a892a1SMatthew G. Knepley const PetscInt *cone, *ornt; 3421b5a892a1SMatthew G. Knepley PetscInt *pts, *closure = NULL; 3422b5a892a1SMatthew G. Knepley DMPolytopeType ft; 3423b5a892a1SMatthew G. Knepley PetscInt maxConeSize, maxSupportSize, coneSeries, supportSeries, maxSize; 3424b5a892a1SMatthew G. Knepley PetscInt dim, coneSize, c, d, clSize, cl; 3425b5a892a1SMatthew G. Knepley PetscErrorCode ierr; 3426b5a892a1SMatthew G. Knepley 3427b5a892a1SMatthew G. Knepley PetscFunctionBeginHot; 3428b5a892a1SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 3429b5a892a1SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, point, &coneSize);CHKERRQ(ierr); 3430b5a892a1SMatthew G. Knepley ierr = DMPlexGetCone(dm, point, &cone);CHKERRQ(ierr); 3431b5a892a1SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, point, &ornt);CHKERRQ(ierr); 3432b5a892a1SMatthew G. Knepley ierr = DMPlexGetMaxSizes(dm, &maxConeSize, &maxSupportSize);CHKERRQ(ierr); 3433b5a892a1SMatthew G. Knepley coneSeries = (maxConeSize > 1) ? ((PetscPowInt(maxConeSize, dim+1)-1)/(maxConeSize-1)) : dim+1; 3434b5a892a1SMatthew G. Knepley supportSeries = (maxSupportSize > 1) ? ((PetscPowInt(maxSupportSize, dim+1)-1)/(maxSupportSize-1)) : dim+1; 3435b5a892a1SMatthew G. Knepley maxSize = PetscMax(coneSeries, supportSeries); 3436b5a892a1SMatthew G. Knepley if (*points) {pts = *points;} 3437b5a892a1SMatthew G. Knepley else {ierr = DMGetWorkArray(dm, 2*maxSize, MPIU_INT, &pts);CHKERRQ(ierr);} 3438b5a892a1SMatthew G. Knepley c = 0; 3439b5a892a1SMatthew G. Knepley pts[c++] = point; 3440b5a892a1SMatthew G. Knepley pts[c++] = o; 3441b5a892a1SMatthew G. Knepley ierr = DMPlexGetCellType(dm, cone[arr[0*2+0]], &ft);CHKERRQ(ierr); 3442b5a892a1SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure_Internal(dm, cone[arr[0*2+0]], DMPolytopeTypeComposeOrientation(ft, arr[0*2+1], ornt[0]), useCone, &clSize, &closure);CHKERRQ(ierr); 3443b5a892a1SMatthew G. Knepley for (cl = 0; cl < clSize*2; cl += 2) {pts[c++] = closure[cl]; pts[c++] = closure[cl+1];} 3444b5a892a1SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure_Internal(dm, cone[arr[1*2+0]], DMPolytopeTypeComposeOrientation(ft, arr[1*2+1], ornt[1]), useCone, &clSize, &closure);CHKERRQ(ierr); 3445b5a892a1SMatthew G. Knepley for (cl = 0; cl < clSize*2; cl += 2) {pts[c++] = closure[cl]; pts[c++] = closure[cl+1];} 3446b5a892a1SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, cone[0], useCone, &clSize, &closure);CHKERRQ(ierr); 3447b5a892a1SMatthew G. Knepley for (d = 2; d < coneSize; ++d) { 3448b5a892a1SMatthew G. Knepley ierr = DMPlexGetCellType(dm, cone[arr[d*2+0]], &ft);CHKERRQ(ierr); 3449b5a892a1SMatthew G. Knepley pts[c++] = cone[arr[d*2+0]]; 3450b5a892a1SMatthew G. Knepley pts[c++] = DMPolytopeTypeComposeOrientation(ft, arr[d*2+1], ornt[d]); 3451b5a892a1SMatthew G. Knepley } 3452b5a892a1SMatthew G. Knepley if (dim >= 3) { 3453b5a892a1SMatthew G. Knepley for (d = 2; d < coneSize; ++d) { 3454b5a892a1SMatthew G. Knepley const PetscInt fpoint = cone[arr[d*2+0]]; 3455b5a892a1SMatthew G. Knepley const PetscInt *fcone, *fornt; 3456b5a892a1SMatthew G. Knepley PetscInt fconeSize, fc, i; 3457b5a892a1SMatthew G. Knepley 3458b5a892a1SMatthew G. Knepley ierr = DMPlexGetCellType(dm, fpoint, &ft);CHKERRQ(ierr); 3459b5a892a1SMatthew G. Knepley const PetscInt *farr = DMPolytopeTypeGetArrangment(ft, DMPolytopeTypeComposeOrientation(ft, arr[d*2+1], ornt[d])); 3460b5a892a1SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, fpoint, &fconeSize);CHKERRQ(ierr); 3461b5a892a1SMatthew G. Knepley ierr = DMPlexGetCone(dm, fpoint, &fcone);CHKERRQ(ierr); 3462b5a892a1SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, fpoint, &fornt);CHKERRQ(ierr); 3463b5a892a1SMatthew G. Knepley for (fc = 0; fc < fconeSize; ++fc) { 3464b5a892a1SMatthew G. Knepley const PetscInt cp = fcone[farr[fc*2+0]]; 3465b5a892a1SMatthew G. Knepley const PetscInt co = farr[fc*2+1]; 3466b5a892a1SMatthew G. Knepley 3467b5a892a1SMatthew G. Knepley for (i = 0; i < c; i += 2) if (pts[i] == cp) break; 3468b5a892a1SMatthew G. Knepley if (i == c) { 3469b5a892a1SMatthew G. Knepley ierr = DMPlexGetCellType(dm, cp, &ft);CHKERRQ(ierr); 3470b5a892a1SMatthew G. Knepley pts[c++] = cp; 3471b5a892a1SMatthew G. Knepley pts[c++] = DMPolytopeTypeComposeOrientation(ft, co, fornt[farr[fc*2+0]]); 3472b5a892a1SMatthew G. Knepley } 3473b5a892a1SMatthew G. Knepley } 3474b5a892a1SMatthew G. Knepley } 3475b5a892a1SMatthew G. Knepley } 3476b5a892a1SMatthew G. Knepley *numPoints = c/2; 3477b5a892a1SMatthew G. Knepley *points = pts; 3478b5a892a1SMatthew G. Knepley PetscFunctionReturn(0); 3479b5a892a1SMatthew G. Knepley } 3480b5a892a1SMatthew G. Knepley 3481b5a892a1SMatthew G. Knepley PetscErrorCode DMPlexGetTransitiveClosure_Internal(DM dm, PetscInt p, PetscInt ornt, PetscBool useCone, PetscInt *numPoints, PetscInt *points[]) 3482b5a892a1SMatthew G. Knepley { 3483b5a892a1SMatthew G. Knepley DMPolytopeType ct; 3484b5a892a1SMatthew G. Knepley PetscInt *closure, *fifo; 3485b5a892a1SMatthew G. Knepley PetscInt closureSize = 0, fifoStart = 0, fifoSize = 0; 3486b5a892a1SMatthew G. Knepley PetscInt maxConeSize, maxSupportSize, coneSeries, supportSeries; 3487b5a892a1SMatthew G. Knepley PetscInt depth, maxSize; 3488b5a892a1SMatthew G. Knepley PetscErrorCode ierr; 3489b5a892a1SMatthew G. Knepley 3490b5a892a1SMatthew G. Knepley PetscFunctionBeginHot; 3491b5a892a1SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 3492b5a892a1SMatthew G. Knepley if (depth == 1) { 3493012bc364SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure_Depth1_Private(dm, p, ornt, useCone, numPoints, points);CHKERRQ(ierr); 3494b5a892a1SMatthew G. Knepley PetscFunctionReturn(0); 3495b5a892a1SMatthew G. Knepley } 3496b5a892a1SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 3497b5a892a1SMatthew G. Knepley if (ct == DM_POLYTOPE_FV_GHOST || ct == DM_POLYTOPE_INTERIOR_GHOST || ct == DM_POLYTOPE_UNKNOWN) ct = DM_POLYTOPE_UNKNOWN; 3498b5a892a1SMatthew G. Knepley if (ct == DM_POLYTOPE_SEG_PRISM_TENSOR || ct == DM_POLYTOPE_TRI_PRISM_TENSOR || ct == DM_POLYTOPE_QUAD_PRISM_TENSOR) { 3499b5a892a1SMatthew G. Knepley ierr = DMPlexTransitiveClosure_Tensor_Internal(dm, p, ct, ornt, useCone, numPoints, points);CHKERRQ(ierr); 3500b5a892a1SMatthew G. Knepley PetscFunctionReturn(0); 3501b5a892a1SMatthew G. Knepley } 3502b5a892a1SMatthew G. Knepley ierr = DMPlexGetMaxSizes(dm, &maxConeSize, &maxSupportSize);CHKERRQ(ierr); 3503b5a892a1SMatthew G. Knepley coneSeries = (maxConeSize > 1) ? ((PetscPowInt(maxConeSize, depth+1)-1)/(maxConeSize-1)) : depth+1; 3504b5a892a1SMatthew G. Knepley supportSeries = (maxSupportSize > 1) ? ((PetscPowInt(maxSupportSize, depth+1)-1)/(maxSupportSize-1)) : depth+1; 3505b5a892a1SMatthew G. Knepley maxSize = PetscMax(coneSeries, supportSeries); 3506b5a892a1SMatthew G. Knepley ierr = DMGetWorkArray(dm, 3*maxSize, MPIU_INT, &fifo);CHKERRQ(ierr); 3507b5a892a1SMatthew G. Knepley if (*points) {closure = *points;} 3508b5a892a1SMatthew G. Knepley else {ierr = DMGetWorkArray(dm, 2*maxSize, MPIU_INT, &closure);CHKERRQ(ierr);} 3509b5a892a1SMatthew G. Knepley closure[closureSize++] = p; 3510b5a892a1SMatthew G. Knepley closure[closureSize++] = ornt; 3511b5a892a1SMatthew G. Knepley fifo[fifoSize++] = p; 3512b5a892a1SMatthew G. Knepley fifo[fifoSize++] = ornt; 3513b5a892a1SMatthew G. Knepley fifo[fifoSize++] = ct; 3514b5a892a1SMatthew G. Knepley /* Should kick out early when depth is reached, rather than checking all vertices for empty cones */ 3515b5a892a1SMatthew G. Knepley while (fifoSize - fifoStart) { 3516b5a892a1SMatthew G. Knepley const PetscInt q = fifo[fifoStart++]; 3517b5a892a1SMatthew G. Knepley const PetscInt o = fifo[fifoStart++]; 3518b5a892a1SMatthew G. Knepley const DMPolytopeType qt = (DMPolytopeType) fifo[fifoStart++]; 3519b5a892a1SMatthew G. Knepley const PetscInt *qarr = DMPolytopeTypeGetArrangment(qt, o); 3520b5a892a1SMatthew G. Knepley const PetscInt *tmp, *tmpO; 3521b5a892a1SMatthew G. Knepley PetscInt tmpSize, t; 3522b5a892a1SMatthew G. Knepley 3523b5a892a1SMatthew G. Knepley if (PetscDefined(USE_DEBUG)) { 3524b5a892a1SMatthew G. Knepley PetscInt nO = DMPolytopeTypeGetNumArrangments(qt)/2; 3525b5a892a1SMatthew G. Knepley if (o && (o >= nO || o < -nO)) SETERRQ5(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid orientation %D not in [%D,%D) for %s %D", o, -nO, nO, DMPolytopeTypes[qt], q); 3526b5a892a1SMatthew G. Knepley } 3527b5a892a1SMatthew G. Knepley if (useCone) { 3528b5a892a1SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, q, &tmpSize);CHKERRQ(ierr); 3529b5a892a1SMatthew G. Knepley ierr = DMPlexGetCone(dm, q, &tmp);CHKERRQ(ierr); 3530b5a892a1SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, q, &tmpO);CHKERRQ(ierr); 3531b5a892a1SMatthew G. Knepley } else { 3532b5a892a1SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, q, &tmpSize);CHKERRQ(ierr); 3533b5a892a1SMatthew G. Knepley ierr = DMPlexGetSupport(dm, q, &tmp);CHKERRQ(ierr); 3534b5a892a1SMatthew G. Knepley tmpO = NULL; 3535b5a892a1SMatthew G. Knepley } 3536b5a892a1SMatthew G. Knepley for (t = 0; t < tmpSize; ++t) { 3537b5a892a1SMatthew G. Knepley const PetscInt ip = useCone && qarr ? qarr[t*2] : t; 3538b5a892a1SMatthew G. Knepley const PetscInt io = useCone && qarr ? qarr[t*2+1] : 0; 3539b5a892a1SMatthew G. Knepley const PetscInt cp = tmp[ip]; 3540b5a892a1SMatthew G. Knepley ierr = DMPlexGetCellType(dm, cp, &ct);CHKERRQ(ierr); 3541b5a892a1SMatthew G. Knepley const PetscInt co = tmpO ? DMPolytopeTypeComposeOrientation(ct, io, tmpO[ip]) : 0; 3542b5a892a1SMatthew G. Knepley PetscInt c; 3543b5a892a1SMatthew G. Knepley 3544b5a892a1SMatthew G. Knepley /* Check for duplicate */ 3545b5a892a1SMatthew G. Knepley for (c = 0; c < closureSize; c += 2) { 3546b5a892a1SMatthew G. Knepley if (closure[c] == cp) break; 3547b5a892a1SMatthew G. Knepley } 3548b5a892a1SMatthew G. Knepley if (c == closureSize) { 3549b5a892a1SMatthew G. Knepley closure[closureSize++] = cp; 3550b5a892a1SMatthew G. Knepley closure[closureSize++] = co; 3551b5a892a1SMatthew G. Knepley fifo[fifoSize++] = cp; 3552b5a892a1SMatthew G. Knepley fifo[fifoSize++] = co; 3553b5a892a1SMatthew G. Knepley fifo[fifoSize++] = ct; 3554b5a892a1SMatthew G. Knepley } 3555b5a892a1SMatthew G. Knepley } 3556b5a892a1SMatthew G. Knepley } 3557b5a892a1SMatthew G. Knepley ierr = DMRestoreWorkArray(dm, 3*maxSize, MPIU_INT, &fifo);CHKERRQ(ierr); 3558b5a892a1SMatthew G. Knepley if (numPoints) *numPoints = closureSize/2; 3559b5a892a1SMatthew G. Knepley if (points) *points = closure; 3560b5a892a1SMatthew G. Knepley PetscFunctionReturn(0); 3561b5a892a1SMatthew G. Knepley } 3562b5a892a1SMatthew G. Knepley 3563552f7358SJed Brown /*@C 3564eaf898f9SPatrick Sanan DMPlexGetTransitiveClosure - Return the points on the transitive closure of the in-edges or out-edges for this point in the DAG 3565552f7358SJed Brown 3566552f7358SJed Brown Not collective 3567552f7358SJed Brown 3568552f7358SJed Brown Input Parameters: 3569b5a892a1SMatthew G. Knepley + dm - The DMPlex 3570b5a892a1SMatthew G. Knepley . p - The mesh point 35716b867d5aSJose E. Roman - useCone - PETSC_TRUE for the closure, otherwise return the star 3572552f7358SJed Brown 35736b867d5aSJose E. Roman Input/Output Parameter: 35746b867d5aSJose E. Roman . points - The points and point orientations, interleaved as pairs [p0, o0, p1, o1, ...]; 35756b867d5aSJose E. Roman if NULL on input, internal storage will be returned, otherwise the provided array is used 35766b867d5aSJose E. Roman 35776b867d5aSJose E. Roman Output Parameter: 35786b867d5aSJose E. Roman . numPoints - The number of points in the closure, so points[] is of size 2*numPoints 3579552f7358SJed Brown 3580552f7358SJed Brown Note: 35810298fd71SBarry Smith If using internal storage (points is NULL on input), each call overwrites the last output. 3582552f7358SJed Brown 35833813dfbdSMatthew G Knepley Fortran Notes: 3584b5a892a1SMatthew G. Knepley Since it returns an array, this routine is only available in Fortran 90, and you must include petsc.h90 in your code. 35853813dfbdSMatthew G Knepley 35863813dfbdSMatthew G Knepley The numPoints argument is not present in the Fortran 90 binding since it is internal to the array. 35873813dfbdSMatthew G Knepley 3588552f7358SJed Brown Level: beginner 3589552f7358SJed Brown 3590552f7358SJed Brown .seealso: DMPlexRestoreTransitiveClosure(), DMPlexCreate(), DMPlexSetCone(), DMPlexSetChart(), DMPlexGetCone() 3591552f7358SJed Brown @*/ 3592552f7358SJed Brown PetscErrorCode DMPlexGetTransitiveClosure(DM dm, PetscInt p, PetscBool useCone, PetscInt *numPoints, PetscInt *points[]) 3593552f7358SJed Brown { 3594552f7358SJed Brown PetscErrorCode ierr; 3595552f7358SJed Brown 3596b5a892a1SMatthew G. Knepley PetscFunctionBeginHot; 3597552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3598b5a892a1SMatthew G. Knepley if (numPoints) PetscValidIntPointer(numPoints, 4); 3599b5a892a1SMatthew G. Knepley if (points) PetscValidPointer(points, 5); 3600b5a892a1SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure_Internal(dm, p, 0, useCone, numPoints, points);CHKERRQ(ierr); 36019bf0dad6SMatthew G. Knepley PetscFunctionReturn(0); 36029bf0dad6SMatthew G. Knepley } 36039bf0dad6SMatthew G. Knepley 3604552f7358SJed Brown /*@C 3605eaf898f9SPatrick Sanan DMPlexRestoreTransitiveClosure - Restore the array of points on the transitive closure of the in-edges or out-edges for this point in the DAG 3606552f7358SJed Brown 3607552f7358SJed Brown Not collective 3608552f7358SJed Brown 3609552f7358SJed Brown Input Parameters: 3610b5a892a1SMatthew G. Knepley + dm - The DMPlex 3611b5a892a1SMatthew G. Knepley . p - The mesh point 3612b5a892a1SMatthew G. Knepley . useCone - PETSC_TRUE for the closure, otherwise return the star 3613b5a892a1SMatthew G. Knepley . numPoints - The number of points in the closure, so points[] is of size 2*numPoints 3614b5a892a1SMatthew G. Knepley - points - The points and point orientations, interleaved as pairs [p0, o0, p1, o1, ...] 3615552f7358SJed Brown 3616552f7358SJed Brown Note: 36170298fd71SBarry Smith If not using internal storage (points is not NULL on input), this call is unnecessary 3618552f7358SJed Brown 36193813dfbdSMatthew G Knepley Fortran Notes: 3620b5a892a1SMatthew G. Knepley Since it returns an array, this routine is only available in Fortran 90, and you must include petsc.h90 in your code. 36213813dfbdSMatthew G Knepley 36223813dfbdSMatthew G Knepley The numPoints argument is not present in the Fortran 90 binding since it is internal to the array. 36233813dfbdSMatthew G Knepley 3624552f7358SJed Brown Level: beginner 3625552f7358SJed Brown 3626552f7358SJed Brown .seealso: DMPlexGetTransitiveClosure(), DMPlexCreate(), DMPlexSetCone(), DMPlexSetChart(), DMPlexGetCone() 3627552f7358SJed Brown @*/ 3628552f7358SJed Brown PetscErrorCode DMPlexRestoreTransitiveClosure(DM dm, PetscInt p, PetscBool useCone, PetscInt *numPoints, PetscInt *points[]) 3629552f7358SJed Brown { 3630552f7358SJed Brown PetscErrorCode ierr; 3631552f7358SJed Brown 3632b5a892a1SMatthew G. Knepley PetscFunctionBeginHot; 3633552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 36344ff43b2cSJed Brown if (numPoints) *numPoints = 0; 3635b5a892a1SMatthew G. Knepley ierr = DMRestoreWorkArray(dm, 0, MPIU_INT, points);CHKERRQ(ierr); 3636552f7358SJed Brown PetscFunctionReturn(0); 3637552f7358SJed Brown } 3638552f7358SJed Brown 3639552f7358SJed Brown /*@ 3640eaf898f9SPatrick Sanan DMPlexGetMaxSizes - Return the maximum number of in-edges (cone) and out-edges (support) for any point in the DAG 3641552f7358SJed Brown 3642552f7358SJed Brown Not collective 3643552f7358SJed Brown 3644552f7358SJed Brown Input Parameter: 3645552f7358SJed Brown . mesh - The DMPlex 3646552f7358SJed Brown 3647552f7358SJed Brown Output Parameters: 3648552f7358SJed Brown + maxConeSize - The maximum number of in-edges 3649552f7358SJed Brown - maxSupportSize - The maximum number of out-edges 3650552f7358SJed Brown 3651552f7358SJed Brown Level: beginner 3652552f7358SJed Brown 3653552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetConeSize(), DMPlexSetChart() 3654552f7358SJed Brown @*/ 3655552f7358SJed Brown PetscErrorCode DMPlexGetMaxSizes(DM dm, PetscInt *maxConeSize, PetscInt *maxSupportSize) 3656552f7358SJed Brown { 3657552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3658552f7358SJed Brown 3659552f7358SJed Brown PetscFunctionBegin; 3660552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3661552f7358SJed Brown if (maxConeSize) *maxConeSize = mesh->maxConeSize; 3662552f7358SJed Brown if (maxSupportSize) *maxSupportSize = mesh->maxSupportSize; 3663552f7358SJed Brown PetscFunctionReturn(0); 3664552f7358SJed Brown } 3665552f7358SJed Brown 3666552f7358SJed Brown PetscErrorCode DMSetUp_Plex(DM dm) 3667552f7358SJed Brown { 3668552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3669552f7358SJed Brown PetscInt size; 3670552f7358SJed Brown PetscErrorCode ierr; 3671552f7358SJed Brown 3672552f7358SJed Brown PetscFunctionBegin; 3673552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3674552f7358SJed Brown ierr = PetscSectionSetUp(mesh->coneSection);CHKERRQ(ierr); 3675552f7358SJed Brown ierr = PetscSectionGetStorageSize(mesh->coneSection, &size);CHKERRQ(ierr); 36761795a4d1SJed Brown ierr = PetscMalloc1(size, &mesh->cones);CHKERRQ(ierr); 36771795a4d1SJed Brown ierr = PetscCalloc1(size, &mesh->coneOrientations);CHKERRQ(ierr); 3678ef1259faSMatthew G. Knepley ierr = PetscLogObjectMemory((PetscObject) dm, size*2*sizeof(PetscInt));CHKERRQ(ierr); 3679552f7358SJed Brown if (mesh->maxSupportSize) { 3680552f7358SJed Brown ierr = PetscSectionSetUp(mesh->supportSection);CHKERRQ(ierr); 3681552f7358SJed Brown ierr = PetscSectionGetStorageSize(mesh->supportSection, &size);CHKERRQ(ierr); 36821795a4d1SJed Brown ierr = PetscMalloc1(size, &mesh->supports);CHKERRQ(ierr); 3683ef1259faSMatthew G. Knepley ierr = PetscLogObjectMemory((PetscObject) dm, size*sizeof(PetscInt));CHKERRQ(ierr); 3684552f7358SJed Brown } 3685552f7358SJed Brown PetscFunctionReturn(0); 3686552f7358SJed Brown } 3687552f7358SJed Brown 3688276c5506SMatthew G. Knepley PetscErrorCode DMCreateSubDM_Plex(DM dm, PetscInt numFields, const PetscInt fields[], IS *is, DM *subdm) 3689552f7358SJed Brown { 3690552f7358SJed Brown PetscErrorCode ierr; 3691552f7358SJed Brown 3692552f7358SJed Brown PetscFunctionBegin; 36934d9407bcSMatthew G. Knepley if (subdm) {ierr = DMClone(dm, subdm);CHKERRQ(ierr);} 3694792b654fSMatthew G. Knepley ierr = DMCreateSectionSubDM(dm, numFields, fields, is, subdm);CHKERRQ(ierr); 3695c2939958SSatish Balay if (subdm) {(*subdm)->useNatural = dm->useNatural;} 3696736995cdSBlaise Bourdin if (dm->useNatural && dm->sfMigration) { 3697f94b4a02SBlaise Bourdin PetscSF sfMigrationInv,sfNatural; 3698f94b4a02SBlaise Bourdin PetscSection section, sectionSeq; 3699f94b4a02SBlaise Bourdin 37003dcd263cSBlaise Bourdin (*subdm)->sfMigration = dm->sfMigration; 37013dcd263cSBlaise Bourdin ierr = PetscObjectReference((PetscObject) dm->sfMigration);CHKERRQ(ierr); 3702c3b366b1Sprj- ierr = DMGetLocalSection((*subdm), §ion);CHKERRQ(ierr); 3703f94b4a02SBlaise Bourdin ierr = PetscSFCreateInverseSF((*subdm)->sfMigration, &sfMigrationInv);CHKERRQ(ierr); 3704f94b4a02SBlaise Bourdin ierr = PetscSectionCreate(PetscObjectComm((PetscObject) (*subdm)), §ionSeq);CHKERRQ(ierr); 3705f94b4a02SBlaise Bourdin ierr = PetscSFDistributeSection(sfMigrationInv, section, NULL, sectionSeq);CHKERRQ(ierr); 3706f94b4a02SBlaise Bourdin 3707f94b4a02SBlaise Bourdin ierr = DMPlexCreateGlobalToNaturalSF(*subdm, sectionSeq, (*subdm)->sfMigration, &sfNatural);CHKERRQ(ierr); 3708c40e9495SBlaise Bourdin (*subdm)->sfNatural = sfNatural; 3709f94b4a02SBlaise Bourdin ierr = PetscSectionDestroy(§ionSeq);CHKERRQ(ierr); 3710f94b4a02SBlaise Bourdin ierr = PetscSFDestroy(&sfMigrationInv);CHKERRQ(ierr); 3711f94b4a02SBlaise Bourdin } 3712552f7358SJed Brown PetscFunctionReturn(0); 3713552f7358SJed Brown } 3714552f7358SJed Brown 37152adcc780SMatthew G. Knepley PetscErrorCode DMCreateSuperDM_Plex(DM dms[], PetscInt len, IS **is, DM *superdm) 37162adcc780SMatthew G. Knepley { 37172adcc780SMatthew G. Knepley PetscErrorCode ierr; 37183dcd263cSBlaise Bourdin PetscInt i = 0; 37192adcc780SMatthew G. Knepley 37202adcc780SMatthew G. Knepley PetscFunctionBegin; 3721435bcee1SStefano Zampini ierr = DMClone(dms[0], superdm);CHKERRQ(ierr); 3722792b654fSMatthew G. Knepley ierr = DMCreateSectionSuperDM(dms, len, is, superdm);CHKERRQ(ierr); 3723c40e9495SBlaise Bourdin (*superdm)->useNatural = PETSC_FALSE; 37243dcd263cSBlaise Bourdin for (i = 0; i < len; i++) { 37253dcd263cSBlaise Bourdin if (dms[i]->useNatural && dms[i]->sfMigration) { 37263dcd263cSBlaise Bourdin PetscSF sfMigrationInv,sfNatural; 37273dcd263cSBlaise Bourdin PetscSection section, sectionSeq; 37283dcd263cSBlaise Bourdin 37293dcd263cSBlaise Bourdin (*superdm)->sfMigration = dms[i]->sfMigration; 37303dcd263cSBlaise Bourdin ierr = PetscObjectReference((PetscObject) dms[i]->sfMigration);CHKERRQ(ierr); 3731c40e9495SBlaise Bourdin (*superdm)->useNatural = PETSC_TRUE; 373292fd8e1eSJed Brown ierr = DMGetLocalSection((*superdm), §ion);CHKERRQ(ierr); 37333dcd263cSBlaise Bourdin ierr = PetscSFCreateInverseSF((*superdm)->sfMigration, &sfMigrationInv);CHKERRQ(ierr); 37343dcd263cSBlaise Bourdin ierr = PetscSectionCreate(PetscObjectComm((PetscObject) (*superdm)), §ionSeq);CHKERRQ(ierr); 37353dcd263cSBlaise Bourdin ierr = PetscSFDistributeSection(sfMigrationInv, section, NULL, sectionSeq);CHKERRQ(ierr); 37363dcd263cSBlaise Bourdin 37373dcd263cSBlaise Bourdin ierr = DMPlexCreateGlobalToNaturalSF(*superdm, sectionSeq, (*superdm)->sfMigration, &sfNatural);CHKERRQ(ierr); 3738c40e9495SBlaise Bourdin (*superdm)->sfNatural = sfNatural; 37393dcd263cSBlaise Bourdin ierr = PetscSectionDestroy(§ionSeq);CHKERRQ(ierr); 37403dcd263cSBlaise Bourdin ierr = PetscSFDestroy(&sfMigrationInv);CHKERRQ(ierr); 37413dcd263cSBlaise Bourdin break; 37423dcd263cSBlaise Bourdin } 37433dcd263cSBlaise Bourdin } 37442adcc780SMatthew G. Knepley PetscFunctionReturn(0); 37452adcc780SMatthew G. Knepley } 37462adcc780SMatthew G. Knepley 3747552f7358SJed Brown /*@ 3748eaf898f9SPatrick Sanan DMPlexSymmetrize - Create support (out-edge) information from cone (in-edge) information 3749552f7358SJed Brown 3750552f7358SJed Brown Not collective 3751552f7358SJed Brown 3752552f7358SJed Brown Input Parameter: 3753552f7358SJed Brown . mesh - The DMPlex 3754552f7358SJed Brown 3755552f7358SJed Brown Output Parameter: 3756552f7358SJed Brown 3757552f7358SJed Brown Note: 3758552f7358SJed Brown This should be called after all calls to DMPlexSetCone() 3759552f7358SJed Brown 3760552f7358SJed Brown Level: beginner 3761552f7358SJed Brown 3762552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetChart(), DMPlexSetConeSize(), DMPlexSetCone() 3763552f7358SJed Brown @*/ 3764552f7358SJed Brown PetscErrorCode DMPlexSymmetrize(DM dm) 3765552f7358SJed Brown { 3766552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3767552f7358SJed Brown PetscInt *offsets; 3768552f7358SJed Brown PetscInt supportSize; 3769552f7358SJed Brown PetscInt pStart, pEnd, p; 3770552f7358SJed Brown PetscErrorCode ierr; 3771552f7358SJed Brown 3772552f7358SJed Brown PetscFunctionBegin; 3773552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 377482f516ccSBarry Smith if (mesh->supports) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Supports were already setup in this DMPlex"); 377530b0ce1bSStefano Zampini ierr = PetscLogEventBegin(DMPLEX_Symmetrize,dm,0,0,0);CHKERRQ(ierr); 3776552f7358SJed Brown /* Calculate support sizes */ 3777552f7358SJed Brown ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 3778552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 3779552f7358SJed Brown PetscInt dof, off, c; 3780552f7358SJed Brown 3781552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 3782552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 3783552f7358SJed Brown for (c = off; c < off+dof; ++c) { 3784552f7358SJed Brown ierr = PetscSectionAddDof(mesh->supportSection, mesh->cones[c], 1);CHKERRQ(ierr); 3785552f7358SJed Brown } 3786552f7358SJed Brown } 3787552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 3788552f7358SJed Brown PetscInt dof; 3789552f7358SJed Brown 3790552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, &dof);CHKERRQ(ierr); 37910d644c17SKarl Rupp 3792552f7358SJed Brown mesh->maxSupportSize = PetscMax(mesh->maxSupportSize, dof); 3793552f7358SJed Brown } 3794552f7358SJed Brown ierr = PetscSectionSetUp(mesh->supportSection);CHKERRQ(ierr); 3795552f7358SJed Brown /* Calculate supports */ 3796552f7358SJed Brown ierr = PetscSectionGetStorageSize(mesh->supportSection, &supportSize);CHKERRQ(ierr); 37971795a4d1SJed Brown ierr = PetscMalloc1(supportSize, &mesh->supports);CHKERRQ(ierr); 37981795a4d1SJed Brown ierr = PetscCalloc1(pEnd - pStart, &offsets);CHKERRQ(ierr); 3799552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 3800552f7358SJed Brown PetscInt dof, off, c; 3801552f7358SJed Brown 3802552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 3803552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 3804552f7358SJed Brown for (c = off; c < off+dof; ++c) { 3805552f7358SJed Brown const PetscInt q = mesh->cones[c]; 3806552f7358SJed Brown PetscInt offS; 3807552f7358SJed Brown 3808552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, q, &offS);CHKERRQ(ierr); 38090d644c17SKarl Rupp 3810552f7358SJed Brown mesh->supports[offS+offsets[q]] = p; 3811552f7358SJed Brown ++offsets[q]; 3812552f7358SJed Brown } 3813552f7358SJed Brown } 3814552f7358SJed Brown ierr = PetscFree(offsets);CHKERRQ(ierr); 381530b0ce1bSStefano Zampini ierr = PetscLogEventEnd(DMPLEX_Symmetrize,dm,0,0,0);CHKERRQ(ierr); 3816552f7358SJed Brown PetscFunctionReturn(0); 3817552f7358SJed Brown } 3818552f7358SJed Brown 3819277ea44aSLisandro Dalcin static PetscErrorCode DMPlexCreateDepthStratum(DM dm, DMLabel label, PetscInt depth, PetscInt pStart, PetscInt pEnd) 3820277ea44aSLisandro Dalcin { 3821277ea44aSLisandro Dalcin IS stratumIS; 3822277ea44aSLisandro Dalcin PetscErrorCode ierr; 3823277ea44aSLisandro Dalcin 3824277ea44aSLisandro Dalcin PetscFunctionBegin; 3825277ea44aSLisandro Dalcin if (pStart >= pEnd) PetscFunctionReturn(0); 382676bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 3827277ea44aSLisandro Dalcin PetscInt qStart, qEnd, numLevels, level; 3828277ea44aSLisandro Dalcin PetscBool overlap = PETSC_FALSE; 3829277ea44aSLisandro Dalcin ierr = DMLabelGetNumValues(label, &numLevels);CHKERRQ(ierr); 3830277ea44aSLisandro Dalcin for (level = 0; level < numLevels; level++) { 3831277ea44aSLisandro Dalcin ierr = DMLabelGetStratumBounds(label, level, &qStart, &qEnd);CHKERRQ(ierr); 3832277ea44aSLisandro Dalcin if ((pStart >= qStart && pStart < qEnd) || (pEnd > qStart && pEnd <= qEnd)) {overlap = PETSC_TRUE; break;} 3833277ea44aSLisandro Dalcin } 3834277ea44aSLisandro Dalcin if (overlap) SETERRQ6(PETSC_COMM_SELF, PETSC_ERR_PLIB, "New depth %D range [%D,%D) overlaps with depth %D range [%D,%D)", depth, pStart, pEnd, level, qStart, qEnd); 3835277ea44aSLisandro Dalcin } 3836277ea44aSLisandro Dalcin ierr = ISCreateStride(PETSC_COMM_SELF, pEnd-pStart, pStart, 1, &stratumIS);CHKERRQ(ierr); 3837277ea44aSLisandro Dalcin ierr = DMLabelSetStratumIS(label, depth, stratumIS);CHKERRQ(ierr); 3838277ea44aSLisandro Dalcin ierr = ISDestroy(&stratumIS);CHKERRQ(ierr); 3839277ea44aSLisandro Dalcin PetscFunctionReturn(0); 3840277ea44aSLisandro Dalcin } 3841277ea44aSLisandro Dalcin 3842552f7358SJed Brown /*@ 3843a8d69d7bSBarry Smith DMPlexStratify - The DAG for most topologies is a graded poset (https://en.wikipedia.org/wiki/Graded_poset), and 38446dd80730SBarry Smith can be illustrated by a Hasse Diagram (https://en.wikipedia.org/wiki/Hasse_diagram). The strata group all points of the 3845552f7358SJed Brown same grade, and this function calculates the strata. This grade can be seen as the height (or depth) of the point in 3846552f7358SJed Brown the DAG. 3847552f7358SJed Brown 3848bf4602e4SToby Isaac Collective on dm 3849552f7358SJed Brown 3850552f7358SJed Brown Input Parameter: 3851552f7358SJed Brown . mesh - The DMPlex 3852552f7358SJed Brown 3853552f7358SJed Brown Output Parameter: 3854552f7358SJed Brown 3855552f7358SJed Brown Notes: 3856b1bb481bSMatthew Knepley Concretely, DMPlexStratify() creates a new label named "depth" containing the depth in the DAG of each point. For cell-vertex 3857b1bb481bSMatthew 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 3858b1bb481bSMatthew Knepley until cells have depth equal to the dimension of the mesh. The depth label can be accessed through DMPlexGetDepthLabel() or DMPlexGetDepthStratum(), or 3859c58f1c22SToby Isaac manually via DMGetLabel(). The height is defined implicitly by height = maxDimension - depth, and can be accessed 3860150b719bSJed Brown via DMPlexGetHeightStratum(). For example, cells have height 0 and faces have height 1. 3861552f7358SJed Brown 3862b1bb481bSMatthew Knepley The depth of a point is calculated by executing a breadth-first search (BFS) on the DAG. This could produce surprising results 3863b1bb481bSMatthew Knepley if run on a partially interpolated mesh, meaning one that had some edges and faces, but not others. For example, suppose that 3864b1bb481bSMatthew 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 3865b1bb481bSMatthew Knepley to interpolate only that one (e0), so that 3866b1bb481bSMatthew Knepley $ cone(c0) = {e0, v2} 3867b1bb481bSMatthew Knepley $ cone(e0) = {v0, v1} 3868b1bb481bSMatthew Knepley If DMPlexStratify() is run on this mesh, it will give depths 3869b1bb481bSMatthew Knepley $ depth 0 = {v0, v1, v2} 3870b1bb481bSMatthew Knepley $ depth 1 = {e0, c0} 3871b1bb481bSMatthew Knepley where the triangle has been given depth 1, instead of 2, because it is reachable from vertex v2. 3872b1bb481bSMatthew Knepley 3873150b719bSJed Brown DMPlexStratify() should be called after all calls to DMPlexSymmetrize() 3874552f7358SJed Brown 3875552f7358SJed Brown Level: beginner 3876552f7358SJed Brown 3877ba2698f1SMatthew G. Knepley .seealso: DMPlexCreate(), DMPlexSymmetrize(), DMPlexComputeCellTypes() 3878552f7358SJed Brown @*/ 3879552f7358SJed Brown PetscErrorCode DMPlexStratify(DM dm) 3880552f7358SJed Brown { 3881df0420ecSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 3882aa50250dSMatthew G. Knepley DMLabel label; 3883552f7358SJed Brown PetscInt pStart, pEnd, p; 3884552f7358SJed Brown PetscInt numRoots = 0, numLeaves = 0; 3885552f7358SJed Brown PetscErrorCode ierr; 3886552f7358SJed Brown 3887552f7358SJed Brown PetscFunctionBegin; 3888552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3889552f7358SJed Brown ierr = PetscLogEventBegin(DMPLEX_Stratify,dm,0,0,0);CHKERRQ(ierr); 3890277ea44aSLisandro Dalcin 3891277ea44aSLisandro Dalcin /* Create depth label */ 3892aa50250dSMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 3893c58f1c22SToby Isaac ierr = DMCreateLabel(dm, "depth");CHKERRQ(ierr); 3894aa50250dSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 3895277ea44aSLisandro Dalcin 3896277ea44aSLisandro Dalcin { 3897552f7358SJed Brown /* Initialize roots and count leaves */ 3898277ea44aSLisandro Dalcin PetscInt sMin = PETSC_MAX_INT; 3899277ea44aSLisandro Dalcin PetscInt sMax = PETSC_MIN_INT; 3900552f7358SJed Brown PetscInt coneSize, supportSize; 3901552f7358SJed Brown 3902277ea44aSLisandro Dalcin for (p = pStart; p < pEnd; ++p) { 3903552f7358SJed Brown ierr = DMPlexGetConeSize(dm, p, &coneSize);CHKERRQ(ierr); 3904552f7358SJed Brown ierr = DMPlexGetSupportSize(dm, p, &supportSize);CHKERRQ(ierr); 3905552f7358SJed Brown if (!coneSize && supportSize) { 3906277ea44aSLisandro Dalcin sMin = PetscMin(p, sMin); 3907277ea44aSLisandro Dalcin sMax = PetscMax(p, sMax); 3908552f7358SJed Brown ++numRoots; 3909552f7358SJed Brown } else if (!supportSize && coneSize) { 3910552f7358SJed Brown ++numLeaves; 3911552f7358SJed Brown } else if (!supportSize && !coneSize) { 3912552f7358SJed Brown /* Isolated points */ 3913277ea44aSLisandro Dalcin sMin = PetscMin(p, sMin); 3914277ea44aSLisandro Dalcin sMax = PetscMax(p, sMax); 3915552f7358SJed Brown } 3916552f7358SJed Brown } 3917277ea44aSLisandro Dalcin ierr = DMPlexCreateDepthStratum(dm, label, 0, sMin, sMax+1);CHKERRQ(ierr); 3918277ea44aSLisandro Dalcin } 3919277ea44aSLisandro Dalcin 3920552f7358SJed Brown if (numRoots + numLeaves == (pEnd - pStart)) { 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 (!supportSize && coneSize) { 3929277ea44aSLisandro Dalcin sMin = PetscMin(p, sMin); 3930277ea44aSLisandro Dalcin sMax = PetscMax(p, sMax); 3931552f7358SJed Brown } 3932552f7358SJed Brown } 3933277ea44aSLisandro Dalcin ierr = DMPlexCreateDepthStratum(dm, label, 1, sMin, sMax+1);CHKERRQ(ierr); 3934552f7358SJed Brown } else { 3935277ea44aSLisandro Dalcin PetscInt level = 0; 3936277ea44aSLisandro Dalcin PetscInt qStart, qEnd, q; 3937552f7358SJed Brown 3938277ea44aSLisandro Dalcin ierr = DMLabelGetStratumBounds(label, level, &qStart, &qEnd);CHKERRQ(ierr); 3939277ea44aSLisandro Dalcin while (qEnd > qStart) { 3940277ea44aSLisandro Dalcin PetscInt sMin = PETSC_MAX_INT; 3941277ea44aSLisandro Dalcin PetscInt sMax = PETSC_MIN_INT; 394274ef644bSMatthew G. Knepley 3943277ea44aSLisandro Dalcin for (q = qStart; q < qEnd; ++q) { 394474ef644bSMatthew G. Knepley const PetscInt *support; 394574ef644bSMatthew G. Knepley PetscInt supportSize, s; 394674ef644bSMatthew G. Knepley 3947277ea44aSLisandro Dalcin ierr = DMPlexGetSupportSize(dm, q, &supportSize);CHKERRQ(ierr); 3948277ea44aSLisandro Dalcin ierr = DMPlexGetSupport(dm, q, &support);CHKERRQ(ierr); 394974ef644bSMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 3950277ea44aSLisandro Dalcin sMin = PetscMin(support[s], sMin); 3951277ea44aSLisandro Dalcin sMax = PetscMax(support[s], sMax); 3952552f7358SJed Brown } 3953552f7358SJed Brown } 3954277ea44aSLisandro Dalcin ierr = DMLabelGetNumValues(label, &level);CHKERRQ(ierr); 3955277ea44aSLisandro Dalcin ierr = DMPlexCreateDepthStratum(dm, label, level, sMin, sMax+1);CHKERRQ(ierr); 3956277ea44aSLisandro Dalcin ierr = DMLabelGetStratumBounds(label, level, &qStart, &qEnd);CHKERRQ(ierr); 395774ef644bSMatthew G. Knepley } 395874ef644bSMatthew G. Knepley } 3959bf4602e4SToby Isaac { /* just in case there is an empty process */ 3960bf4602e4SToby Isaac PetscInt numValues, maxValues = 0, v; 3961bf4602e4SToby Isaac 3962bf4602e4SToby Isaac ierr = DMLabelGetNumValues(label, &numValues);CHKERRQ(ierr); 3963ffc4695bSBarry Smith ierr = MPI_Allreduce(&numValues,&maxValues,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)dm));CHKERRMPI(ierr); 3964bf4602e4SToby Isaac for (v = numValues; v < maxValues; v++) { 3965367003a6SStefano Zampini ierr = DMLabelAddStratum(label, v);CHKERRQ(ierr); 3966bf4602e4SToby Isaac } 3967bf4602e4SToby Isaac } 3968d67d17b1SMatthew G. Knepley ierr = PetscObjectStateGet((PetscObject) label, &mesh->depthState);CHKERRQ(ierr); 3969552f7358SJed Brown ierr = PetscLogEventEnd(DMPLEX_Stratify,dm,0,0,0);CHKERRQ(ierr); 3970552f7358SJed Brown PetscFunctionReturn(0); 3971552f7358SJed Brown } 3972552f7358SJed Brown 3973412e9a14SMatthew G. Knepley PetscErrorCode DMPlexComputeCellType_Internal(DM dm, PetscInt p, PetscInt pdepth, DMPolytopeType *pt) 3974ba2698f1SMatthew G. Knepley { 3975412e9a14SMatthew G. Knepley DMPolytopeType ct = DM_POLYTOPE_UNKNOWN; 3976412e9a14SMatthew G. Knepley PetscInt dim, depth, pheight, coneSize; 3977ba2698f1SMatthew G. Knepley PetscErrorCode ierr; 3978ba2698f1SMatthew G. Knepley 3979412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 3980ba2698f1SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 3981ba2698f1SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 3982ba2698f1SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, p, &coneSize);CHKERRQ(ierr); 3983ba2698f1SMatthew G. Knepley pheight = depth - pdepth; 3984ba2698f1SMatthew G. Knepley if (depth <= 1) { 3985ba2698f1SMatthew G. Knepley switch (pdepth) { 3986ba2698f1SMatthew G. Knepley case 0: ct = DM_POLYTOPE_POINT;break; 3987ba2698f1SMatthew G. Knepley case 1: 3988ba2698f1SMatthew G. Knepley switch (coneSize) { 3989ba2698f1SMatthew G. Knepley case 2: ct = DM_POLYTOPE_SEGMENT;break; 3990ba2698f1SMatthew G. Knepley case 3: ct = DM_POLYTOPE_TRIANGLE;break; 3991ba2698f1SMatthew G. Knepley case 4: 3992ba2698f1SMatthew G. Knepley switch (dim) { 3993ba2698f1SMatthew G. Knepley case 2: ct = DM_POLYTOPE_QUADRILATERAL;break; 3994ba2698f1SMatthew G. Knepley case 3: ct = DM_POLYTOPE_TETRAHEDRON;break; 3995ba2698f1SMatthew G. Knepley default: break; 3996ba2698f1SMatthew G. Knepley } 3997ba2698f1SMatthew G. Knepley break; 3998da9060c4SMatthew G. Knepley case 5: ct = DM_POLYTOPE_PYRAMID;break; 3999ba2698f1SMatthew G. Knepley case 6: ct = DM_POLYTOPE_TRI_PRISM_TENSOR;break; 4000ba2698f1SMatthew G. Knepley case 8: ct = DM_POLYTOPE_HEXAHEDRON;break; 4001ba2698f1SMatthew G. Knepley default: break; 4002ba2698f1SMatthew G. Knepley } 4003ba2698f1SMatthew G. Knepley } 4004ba2698f1SMatthew G. Knepley } else { 4005ba2698f1SMatthew G. Knepley if (pdepth == 0) { 4006ba2698f1SMatthew G. Knepley ct = DM_POLYTOPE_POINT; 4007ba2698f1SMatthew G. Knepley } else if (pheight == 0) { 4008ba2698f1SMatthew G. Knepley switch (dim) { 4009ba2698f1SMatthew G. Knepley case 1: 4010ba2698f1SMatthew G. Knepley switch (coneSize) { 4011ba2698f1SMatthew G. Knepley case 2: ct = DM_POLYTOPE_SEGMENT;break; 4012ba2698f1SMatthew G. Knepley default: break; 4013ba2698f1SMatthew G. Knepley } 4014ba2698f1SMatthew G. Knepley break; 4015ba2698f1SMatthew G. Knepley case 2: 4016ba2698f1SMatthew G. Knepley switch (coneSize) { 4017ba2698f1SMatthew G. Knepley case 3: ct = DM_POLYTOPE_TRIANGLE;break; 4018ba2698f1SMatthew G. Knepley case 4: ct = DM_POLYTOPE_QUADRILATERAL;break; 4019ba2698f1SMatthew G. Knepley default: break; 4020ba2698f1SMatthew G. Knepley } 4021ba2698f1SMatthew G. Knepley break; 4022ba2698f1SMatthew G. Knepley case 3: 4023ba2698f1SMatthew G. Knepley switch (coneSize) { 4024ba2698f1SMatthew G. Knepley case 4: ct = DM_POLYTOPE_TETRAHEDRON;break; 4025da9060c4SMatthew G. Knepley case 5: 4026da9060c4SMatthew G. Knepley { 4027da9060c4SMatthew G. Knepley const PetscInt *cone; 4028da9060c4SMatthew G. Knepley PetscInt faceConeSize; 4029da9060c4SMatthew G. Knepley 4030da9060c4SMatthew G. Knepley ierr = DMPlexGetCone(dm, p, &cone);CHKERRQ(ierr); 4031da9060c4SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, cone[0], &faceConeSize);CHKERRQ(ierr); 4032da9060c4SMatthew G. Knepley switch (faceConeSize) { 4033da9060c4SMatthew G. Knepley case 3: ct = DM_POLYTOPE_TRI_PRISM_TENSOR;break; 4034da9060c4SMatthew G. Knepley case 4: ct = DM_POLYTOPE_PYRAMID;break; 4035da9060c4SMatthew G. Knepley } 4036da9060c4SMatthew G. Knepley } 4037da9060c4SMatthew G. Knepley break; 4038ba2698f1SMatthew G. Knepley case 6: ct = DM_POLYTOPE_HEXAHEDRON;break; 4039ba2698f1SMatthew G. Knepley default: break; 4040ba2698f1SMatthew G. Knepley } 4041ba2698f1SMatthew G. Knepley break; 4042ba2698f1SMatthew G. Knepley default: break; 4043ba2698f1SMatthew G. Knepley } 4044ba2698f1SMatthew G. Knepley } else if (pheight > 0) { 4045ba2698f1SMatthew G. Knepley switch (coneSize) { 4046ba2698f1SMatthew G. Knepley case 2: ct = DM_POLYTOPE_SEGMENT;break; 4047ba2698f1SMatthew G. Knepley case 3: ct = DM_POLYTOPE_TRIANGLE;break; 4048ba2698f1SMatthew G. Knepley case 4: ct = DM_POLYTOPE_QUADRILATERAL;break; 4049ba2698f1SMatthew G. Knepley default: break; 4050ba2698f1SMatthew G. Knepley } 4051ba2698f1SMatthew G. Knepley } 4052ba2698f1SMatthew G. Knepley } 4053412e9a14SMatthew G. Knepley *pt = ct; 4054412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 4055ba2698f1SMatthew G. Knepley } 4056412e9a14SMatthew G. Knepley 4057412e9a14SMatthew G. Knepley /*@ 4058412e9a14SMatthew G. Knepley DMPlexComputeCellTypes - Infer the polytope type of every cell using its dimension and cone size. 4059412e9a14SMatthew G. Knepley 4060412e9a14SMatthew G. Knepley Collective on dm 4061412e9a14SMatthew G. Knepley 4062412e9a14SMatthew G. Knepley Input Parameter: 4063412e9a14SMatthew G. Knepley . mesh - The DMPlex 4064412e9a14SMatthew G. Knepley 4065412e9a14SMatthew G. Knepley DMPlexComputeCellTypes() should be called after all calls to DMPlexSymmetrize() and DMPlexStratify() 4066412e9a14SMatthew G. Knepley 4067412e9a14SMatthew G. Knepley Level: developer 4068412e9a14SMatthew G. Knepley 4069412e9a14SMatthew G. Knepley Note: This function is normally called automatically by Plex when a cell type is requested. It creates an 4070412e9a14SMatthew G. Knepley internal DMLabel named "celltype" which can be directly accessed using DMGetLabel(). A user may disable 4071412e9a14SMatthew G. Knepley automatic creation by creating the label manually, using DMCreateLabel(dm, "celltype"). 4072412e9a14SMatthew G. Knepley 4073412e9a14SMatthew G. Knepley .seealso: DMPlexCreate(), DMPlexSymmetrize(), DMPlexStratify(), DMGetLabel(), DMCreateLabel() 4074412e9a14SMatthew G. Knepley @*/ 4075412e9a14SMatthew G. Knepley PetscErrorCode DMPlexComputeCellTypes(DM dm) 4076412e9a14SMatthew G. Knepley { 4077412e9a14SMatthew G. Knepley DM_Plex *mesh; 4078412e9a14SMatthew G. Knepley DMLabel ctLabel; 4079412e9a14SMatthew G. Knepley PetscInt pStart, pEnd, p; 4080412e9a14SMatthew G. Knepley PetscErrorCode ierr; 4081412e9a14SMatthew G. Knepley 4082412e9a14SMatthew G. Knepley PetscFunctionBegin; 4083412e9a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4084412e9a14SMatthew G. Knepley mesh = (DM_Plex *) dm->data; 4085412e9a14SMatthew G. Knepley ierr = DMCreateLabel(dm, "celltype");CHKERRQ(ierr); 4086412e9a14SMatthew G. Knepley ierr = DMPlexGetCellTypeLabel(dm, &ctLabel);CHKERRQ(ierr); 4087412e9a14SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 4088412e9a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 4089327c2912SStefano Zampini DMPolytopeType ct = DM_POLYTOPE_UNKNOWN; 4090412e9a14SMatthew G. Knepley PetscInt pdepth; 4091412e9a14SMatthew G. Knepley 4092412e9a14SMatthew G. Knepley ierr = DMPlexGetPointDepth(dm, p, &pdepth);CHKERRQ(ierr); 4093412e9a14SMatthew G. Knepley ierr = DMPlexComputeCellType_Internal(dm, p, pdepth, &ct);CHKERRQ(ierr); 4094412e9a14SMatthew G. Knepley if (ct == DM_POLYTOPE_UNKNOWN) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "Point %D is screwed up", p); 4095412e9a14SMatthew G. Knepley ierr = DMLabelSetValue(ctLabel, p, ct);CHKERRQ(ierr); 4096412e9a14SMatthew G. Knepley } 4097412e9a14SMatthew G. Knepley ierr = PetscObjectStateGet((PetscObject) ctLabel, &mesh->celltypeState);CHKERRQ(ierr); 4098412e9a14SMatthew G. Knepley ierr = PetscObjectViewFromOptions((PetscObject) ctLabel, NULL, "-dm_plex_celltypes_view");CHKERRQ(ierr); 4099ba2698f1SMatthew G. Knepley PetscFunctionReturn(0); 4100ba2698f1SMatthew G. Knepley } 4101ba2698f1SMatthew G. Knepley 4102552f7358SJed Brown /*@C 4103552f7358SJed Brown DMPlexGetJoin - Get an array for the join of the set of points 4104552f7358SJed Brown 4105552f7358SJed Brown Not Collective 4106552f7358SJed Brown 4107552f7358SJed Brown Input Parameters: 4108552f7358SJed Brown + dm - The DMPlex object 4109552f7358SJed Brown . numPoints - The number of input points for the join 4110552f7358SJed Brown - points - The input points 4111552f7358SJed Brown 4112552f7358SJed Brown Output Parameters: 4113552f7358SJed Brown + numCoveredPoints - The number of points in the join 4114552f7358SJed Brown - coveredPoints - The points in the join 4115552f7358SJed Brown 4116552f7358SJed Brown Level: intermediate 4117552f7358SJed Brown 4118552f7358SJed Brown Note: Currently, this is restricted to a single level join 4119552f7358SJed Brown 41203813dfbdSMatthew G Knepley Fortran Notes: 41213813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 41223813dfbdSMatthew G Knepley include petsc.h90 in your code. 41233813dfbdSMatthew G Knepley 41243813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 41253813dfbdSMatthew G Knepley 4126552f7358SJed Brown .seealso: DMPlexRestoreJoin(), DMPlexGetMeet() 4127552f7358SJed Brown @*/ 4128552f7358SJed Brown PetscErrorCode DMPlexGetJoin(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 4129552f7358SJed Brown { 4130552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 4131552f7358SJed Brown PetscInt *join[2]; 4132552f7358SJed Brown PetscInt joinSize, i = 0; 4133552f7358SJed Brown PetscInt dof, off, p, c, m; 4134552f7358SJed Brown PetscErrorCode ierr; 4135552f7358SJed Brown 4136552f7358SJed Brown PetscFunctionBegin; 4137552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 413848bb261cSVaclav Hapla PetscValidIntPointer(points, 3); 413948bb261cSVaclav Hapla PetscValidIntPointer(numCoveredPoints, 4); 414048bb261cSVaclav Hapla PetscValidPointer(coveredPoints, 5); 414169291d52SBarry Smith ierr = DMGetWorkArray(dm, mesh->maxSupportSize, MPIU_INT, &join[0]);CHKERRQ(ierr); 414269291d52SBarry Smith ierr = DMGetWorkArray(dm, mesh->maxSupportSize, MPIU_INT, &join[1]);CHKERRQ(ierr); 4143552f7358SJed Brown /* Copy in support of first point */ 4144552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, points[0], &dof);CHKERRQ(ierr); 4145552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, points[0], &off);CHKERRQ(ierr); 4146552f7358SJed Brown for (joinSize = 0; joinSize < dof; ++joinSize) { 4147552f7358SJed Brown join[i][joinSize] = mesh->supports[off+joinSize]; 4148552f7358SJed Brown } 4149552f7358SJed Brown /* Check each successive support */ 4150552f7358SJed Brown for (p = 1; p < numPoints; ++p) { 4151552f7358SJed Brown PetscInt newJoinSize = 0; 4152552f7358SJed Brown 4153552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, points[p], &dof);CHKERRQ(ierr); 4154552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, points[p], &off);CHKERRQ(ierr); 4155552f7358SJed Brown for (c = 0; c < dof; ++c) { 4156552f7358SJed Brown const PetscInt point = mesh->supports[off+c]; 4157552f7358SJed Brown 4158552f7358SJed Brown for (m = 0; m < joinSize; ++m) { 4159552f7358SJed Brown if (point == join[i][m]) { 4160552f7358SJed Brown join[1-i][newJoinSize++] = point; 4161552f7358SJed Brown break; 4162552f7358SJed Brown } 4163552f7358SJed Brown } 4164552f7358SJed Brown } 4165552f7358SJed Brown joinSize = newJoinSize; 4166552f7358SJed Brown i = 1-i; 4167552f7358SJed Brown } 4168552f7358SJed Brown *numCoveredPoints = joinSize; 4169552f7358SJed Brown *coveredPoints = join[i]; 417069291d52SBarry Smith ierr = DMRestoreWorkArray(dm, mesh->maxSupportSize, MPIU_INT, &join[1-i]);CHKERRQ(ierr); 4171552f7358SJed Brown PetscFunctionReturn(0); 4172552f7358SJed Brown } 4173552f7358SJed Brown 4174552f7358SJed Brown /*@C 4175552f7358SJed Brown DMPlexRestoreJoin - Restore an array for the join of the set of points 4176552f7358SJed Brown 4177552f7358SJed Brown Not Collective 4178552f7358SJed Brown 4179552f7358SJed Brown Input Parameters: 4180552f7358SJed Brown + dm - The DMPlex object 4181552f7358SJed Brown . numPoints - The number of input points for the join 4182552f7358SJed Brown - points - The input points 4183552f7358SJed Brown 4184552f7358SJed Brown Output Parameters: 4185552f7358SJed Brown + numCoveredPoints - The number of points in the join 4186552f7358SJed Brown - coveredPoints - The points in the join 4187552f7358SJed Brown 41883813dfbdSMatthew G Knepley Fortran Notes: 41893813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 41903813dfbdSMatthew G Knepley include petsc.h90 in your code. 41913813dfbdSMatthew G Knepley 41923813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 41933813dfbdSMatthew G Knepley 4194552f7358SJed Brown Level: intermediate 4195552f7358SJed Brown 4196552f7358SJed Brown .seealso: DMPlexGetJoin(), DMPlexGetFullJoin(), DMPlexGetMeet() 4197552f7358SJed Brown @*/ 4198552f7358SJed Brown PetscErrorCode DMPlexRestoreJoin(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 4199552f7358SJed Brown { 4200552f7358SJed Brown PetscErrorCode ierr; 4201552f7358SJed Brown 4202552f7358SJed Brown PetscFunctionBegin; 4203552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4204d7902bd2SMatthew G. Knepley if (points) PetscValidIntPointer(points,3); 4205d7902bd2SMatthew G. Knepley if (numCoveredPoints) PetscValidIntPointer(numCoveredPoints,4); 4206d7902bd2SMatthew G. Knepley PetscValidPointer(coveredPoints, 5); 420769291d52SBarry Smith ierr = DMRestoreWorkArray(dm, 0, MPIU_INT, (void*) coveredPoints);CHKERRQ(ierr); 4208d7902bd2SMatthew G. Knepley if (numCoveredPoints) *numCoveredPoints = 0; 4209552f7358SJed Brown PetscFunctionReturn(0); 4210552f7358SJed Brown } 4211552f7358SJed Brown 4212552f7358SJed Brown /*@C 4213552f7358SJed Brown DMPlexGetFullJoin - Get an array for the join of the set of points 4214552f7358SJed Brown 4215552f7358SJed Brown Not Collective 4216552f7358SJed Brown 4217552f7358SJed Brown Input Parameters: 4218552f7358SJed Brown + dm - The DMPlex object 4219552f7358SJed Brown . numPoints - The number of input points for the join 4220552f7358SJed Brown - points - The input points 4221552f7358SJed Brown 4222552f7358SJed Brown Output Parameters: 4223552f7358SJed Brown + numCoveredPoints - The number of points in the join 4224552f7358SJed Brown - coveredPoints - The points in the join 4225552f7358SJed Brown 42263813dfbdSMatthew G Knepley Fortran Notes: 42273813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 42283813dfbdSMatthew G Knepley include petsc.h90 in your code. 42293813dfbdSMatthew G Knepley 42303813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 42313813dfbdSMatthew G Knepley 4232552f7358SJed Brown Level: intermediate 4233552f7358SJed Brown 4234552f7358SJed Brown .seealso: DMPlexGetJoin(), DMPlexRestoreJoin(), DMPlexGetMeet() 4235552f7358SJed Brown @*/ 4236552f7358SJed Brown PetscErrorCode DMPlexGetFullJoin(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 4237552f7358SJed Brown { 4238552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 4239552f7358SJed Brown PetscInt *offsets, **closures; 4240552f7358SJed Brown PetscInt *join[2]; 4241552f7358SJed Brown PetscInt depth = 0, maxSize, joinSize = 0, i = 0; 424224c766afSToby Isaac PetscInt p, d, c, m, ms; 4243552f7358SJed Brown PetscErrorCode ierr; 4244552f7358SJed Brown 4245552f7358SJed Brown PetscFunctionBegin; 4246552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 424748bb261cSVaclav Hapla PetscValidIntPointer(points, 3); 424848bb261cSVaclav Hapla PetscValidIntPointer(numCoveredPoints, 4); 424948bb261cSVaclav Hapla PetscValidPointer(coveredPoints, 5); 4250552f7358SJed Brown 4251552f7358SJed Brown ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 42521795a4d1SJed Brown ierr = PetscCalloc1(numPoints, &closures);CHKERRQ(ierr); 425369291d52SBarry Smith ierr = DMGetWorkArray(dm, numPoints*(depth+2), MPIU_INT, &offsets);CHKERRQ(ierr); 425424c766afSToby Isaac ms = mesh->maxSupportSize; 425524c766afSToby Isaac maxSize = (ms > 1) ? ((PetscPowInt(ms,depth+1)-1)/(ms-1)) : depth + 1; 425669291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &join[0]);CHKERRQ(ierr); 425769291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &join[1]);CHKERRQ(ierr); 4258552f7358SJed Brown 4259552f7358SJed Brown for (p = 0; p < numPoints; ++p) { 4260552f7358SJed Brown PetscInt closureSize; 4261552f7358SJed Brown 4262552f7358SJed Brown ierr = DMPlexGetTransitiveClosure(dm, points[p], PETSC_FALSE, &closureSize, &closures[p]);CHKERRQ(ierr); 42630d644c17SKarl Rupp 4264552f7358SJed Brown offsets[p*(depth+2)+0] = 0; 4265552f7358SJed Brown for (d = 0; d < depth+1; ++d) { 4266552f7358SJed Brown PetscInt pStart, pEnd, i; 4267552f7358SJed Brown 4268552f7358SJed Brown ierr = DMPlexGetDepthStratum(dm, d, &pStart, &pEnd);CHKERRQ(ierr); 4269552f7358SJed Brown for (i = offsets[p*(depth+2)+d]; i < closureSize; ++i) { 4270552f7358SJed Brown if ((pStart > closures[p][i*2]) || (pEnd <= closures[p][i*2])) { 4271552f7358SJed Brown offsets[p*(depth+2)+d+1] = i; 4272552f7358SJed Brown break; 4273552f7358SJed Brown } 4274552f7358SJed Brown } 4275552f7358SJed Brown if (i == closureSize) offsets[p*(depth+2)+d+1] = i; 4276552f7358SJed Brown } 427782f516ccSBarry Smith if (offsets[p*(depth+2)+depth+1] != closureSize) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Total size of closure %D should be %D", offsets[p*(depth+2)+depth+1], closureSize); 4278552f7358SJed Brown } 4279552f7358SJed Brown for (d = 0; d < depth+1; ++d) { 4280552f7358SJed Brown PetscInt dof; 4281552f7358SJed Brown 4282552f7358SJed Brown /* Copy in support of first point */ 4283552f7358SJed Brown dof = offsets[d+1] - offsets[d]; 4284552f7358SJed Brown for (joinSize = 0; joinSize < dof; ++joinSize) { 4285552f7358SJed Brown join[i][joinSize] = closures[0][(offsets[d]+joinSize)*2]; 4286552f7358SJed Brown } 4287552f7358SJed Brown /* Check each successive cone */ 4288552f7358SJed Brown for (p = 1; p < numPoints && joinSize; ++p) { 4289552f7358SJed Brown PetscInt newJoinSize = 0; 4290552f7358SJed Brown 4291552f7358SJed Brown dof = offsets[p*(depth+2)+d+1] - offsets[p*(depth+2)+d]; 4292552f7358SJed Brown for (c = 0; c < dof; ++c) { 4293552f7358SJed Brown const PetscInt point = closures[p][(offsets[p*(depth+2)+d]+c)*2]; 4294552f7358SJed Brown 4295552f7358SJed Brown for (m = 0; m < joinSize; ++m) { 4296552f7358SJed Brown if (point == join[i][m]) { 4297552f7358SJed Brown join[1-i][newJoinSize++] = point; 4298552f7358SJed Brown break; 4299552f7358SJed Brown } 4300552f7358SJed Brown } 4301552f7358SJed Brown } 4302552f7358SJed Brown joinSize = newJoinSize; 4303552f7358SJed Brown i = 1-i; 4304552f7358SJed Brown } 4305552f7358SJed Brown if (joinSize) break; 4306552f7358SJed Brown } 4307552f7358SJed Brown *numCoveredPoints = joinSize; 4308552f7358SJed Brown *coveredPoints = join[i]; 4309552f7358SJed Brown for (p = 0; p < numPoints; ++p) { 43100298fd71SBarry Smith ierr = DMPlexRestoreTransitiveClosure(dm, points[p], PETSC_FALSE, NULL, &closures[p]);CHKERRQ(ierr); 4311552f7358SJed Brown } 4312552f7358SJed Brown ierr = PetscFree(closures);CHKERRQ(ierr); 431369291d52SBarry Smith ierr = DMRestoreWorkArray(dm, numPoints*(depth+2), MPIU_INT, &offsets);CHKERRQ(ierr); 431469291d52SBarry Smith ierr = DMRestoreWorkArray(dm, mesh->maxSupportSize, MPIU_INT, &join[1-i]);CHKERRQ(ierr); 4315552f7358SJed Brown PetscFunctionReturn(0); 4316552f7358SJed Brown } 4317552f7358SJed Brown 4318552f7358SJed Brown /*@C 4319552f7358SJed Brown DMPlexGetMeet - Get an array for the meet of the set of points 4320552f7358SJed Brown 4321552f7358SJed Brown Not Collective 4322552f7358SJed Brown 4323552f7358SJed Brown Input Parameters: 4324552f7358SJed Brown + dm - The DMPlex object 4325552f7358SJed Brown . numPoints - The number of input points for the meet 4326552f7358SJed Brown - points - The input points 4327552f7358SJed Brown 4328552f7358SJed Brown Output Parameters: 4329552f7358SJed Brown + numCoveredPoints - The number of points in the meet 4330552f7358SJed Brown - coveredPoints - The points in the meet 4331552f7358SJed Brown 4332552f7358SJed Brown Level: intermediate 4333552f7358SJed Brown 4334552f7358SJed Brown Note: Currently, this is restricted to a single level meet 4335552f7358SJed Brown 43363813dfbdSMatthew G Knepley Fortran Notes: 43373813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 43383813dfbdSMatthew G Knepley include petsc.h90 in your code. 43393813dfbdSMatthew G Knepley 43403813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 43413813dfbdSMatthew G Knepley 4342552f7358SJed Brown .seealso: DMPlexRestoreMeet(), DMPlexGetJoin() 4343552f7358SJed Brown @*/ 4344552f7358SJed Brown PetscErrorCode DMPlexGetMeet(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveringPoints, const PetscInt **coveringPoints) 4345552f7358SJed Brown { 4346552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 4347552f7358SJed Brown PetscInt *meet[2]; 4348552f7358SJed Brown PetscInt meetSize, i = 0; 4349552f7358SJed Brown PetscInt dof, off, p, c, m; 4350552f7358SJed Brown PetscErrorCode ierr; 4351552f7358SJed Brown 4352552f7358SJed Brown PetscFunctionBegin; 4353552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4354064a246eSJacob Faibussowitsch PetscValidPointer(points, 3); 4355064a246eSJacob Faibussowitsch PetscValidPointer(numCoveringPoints, 4); 4356064a246eSJacob Faibussowitsch PetscValidPointer(coveringPoints, 5); 435769291d52SBarry Smith ierr = DMGetWorkArray(dm, mesh->maxConeSize, MPIU_INT, &meet[0]);CHKERRQ(ierr); 435869291d52SBarry Smith ierr = DMGetWorkArray(dm, mesh->maxConeSize, MPIU_INT, &meet[1]);CHKERRQ(ierr); 4359552f7358SJed Brown /* Copy in cone of first point */ 4360552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, points[0], &dof);CHKERRQ(ierr); 4361552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, points[0], &off);CHKERRQ(ierr); 4362552f7358SJed Brown for (meetSize = 0; meetSize < dof; ++meetSize) { 4363552f7358SJed Brown meet[i][meetSize] = mesh->cones[off+meetSize]; 4364552f7358SJed Brown } 4365552f7358SJed Brown /* Check each successive cone */ 4366552f7358SJed Brown for (p = 1; p < numPoints; ++p) { 4367552f7358SJed Brown PetscInt newMeetSize = 0; 4368552f7358SJed Brown 4369552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, points[p], &dof);CHKERRQ(ierr); 4370552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, points[p], &off);CHKERRQ(ierr); 4371552f7358SJed Brown for (c = 0; c < dof; ++c) { 4372552f7358SJed Brown const PetscInt point = mesh->cones[off+c]; 4373552f7358SJed Brown 4374552f7358SJed Brown for (m = 0; m < meetSize; ++m) { 4375552f7358SJed Brown if (point == meet[i][m]) { 4376552f7358SJed Brown meet[1-i][newMeetSize++] = point; 4377552f7358SJed Brown break; 4378552f7358SJed Brown } 4379552f7358SJed Brown } 4380552f7358SJed Brown } 4381552f7358SJed Brown meetSize = newMeetSize; 4382552f7358SJed Brown i = 1-i; 4383552f7358SJed Brown } 4384552f7358SJed Brown *numCoveringPoints = meetSize; 4385552f7358SJed Brown *coveringPoints = meet[i]; 438669291d52SBarry Smith ierr = DMRestoreWorkArray(dm, mesh->maxConeSize, MPIU_INT, &meet[1-i]);CHKERRQ(ierr); 4387552f7358SJed Brown PetscFunctionReturn(0); 4388552f7358SJed Brown } 4389552f7358SJed Brown 4390552f7358SJed Brown /*@C 4391552f7358SJed Brown DMPlexRestoreMeet - Restore an array for the meet of the set of points 4392552f7358SJed Brown 4393552f7358SJed Brown Not Collective 4394552f7358SJed Brown 4395552f7358SJed Brown Input Parameters: 4396552f7358SJed Brown + dm - The DMPlex object 4397552f7358SJed Brown . numPoints - The number of input points for the meet 4398552f7358SJed Brown - points - The input points 4399552f7358SJed Brown 4400552f7358SJed Brown Output Parameters: 4401552f7358SJed Brown + numCoveredPoints - The number of points in the meet 4402552f7358SJed Brown - coveredPoints - The points in the meet 4403552f7358SJed Brown 4404552f7358SJed Brown Level: intermediate 4405552f7358SJed Brown 44063813dfbdSMatthew G Knepley Fortran Notes: 44073813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 44083813dfbdSMatthew G Knepley include petsc.h90 in your code. 44093813dfbdSMatthew G Knepley 44103813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 44113813dfbdSMatthew G Knepley 4412552f7358SJed Brown .seealso: DMPlexGetMeet(), DMPlexGetFullMeet(), DMPlexGetJoin() 4413552f7358SJed Brown @*/ 4414552f7358SJed Brown PetscErrorCode DMPlexRestoreMeet(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 4415552f7358SJed Brown { 4416552f7358SJed Brown PetscErrorCode ierr; 4417552f7358SJed Brown 4418552f7358SJed Brown PetscFunctionBegin; 4419552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4420d7902bd2SMatthew G. Knepley if (points) PetscValidIntPointer(points,3); 4421d7902bd2SMatthew G. Knepley if (numCoveredPoints) PetscValidIntPointer(numCoveredPoints,4); 4422d7902bd2SMatthew G. Knepley PetscValidPointer(coveredPoints,5); 442369291d52SBarry Smith ierr = DMRestoreWorkArray(dm, 0, MPIU_INT, (void*) coveredPoints);CHKERRQ(ierr); 4424d7902bd2SMatthew G. Knepley if (numCoveredPoints) *numCoveredPoints = 0; 4425552f7358SJed Brown PetscFunctionReturn(0); 4426552f7358SJed Brown } 4427552f7358SJed Brown 4428552f7358SJed Brown /*@C 4429552f7358SJed Brown DMPlexGetFullMeet - Get an array for the meet of the set of points 4430552f7358SJed Brown 4431552f7358SJed Brown Not Collective 4432552f7358SJed Brown 4433552f7358SJed Brown Input Parameters: 4434552f7358SJed Brown + dm - The DMPlex object 4435552f7358SJed Brown . numPoints - The number of input points for the meet 4436552f7358SJed Brown - points - The input points 4437552f7358SJed Brown 4438552f7358SJed Brown Output Parameters: 4439552f7358SJed Brown + numCoveredPoints - The number of points in the meet 4440552f7358SJed Brown - coveredPoints - The points in the meet 4441552f7358SJed Brown 4442552f7358SJed Brown Level: intermediate 4443552f7358SJed Brown 44443813dfbdSMatthew G Knepley Fortran Notes: 44453813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 44463813dfbdSMatthew G Knepley include petsc.h90 in your code. 44473813dfbdSMatthew G Knepley 44483813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 44493813dfbdSMatthew G Knepley 4450552f7358SJed Brown .seealso: DMPlexGetMeet(), DMPlexRestoreMeet(), DMPlexGetJoin() 4451552f7358SJed Brown @*/ 4452552f7358SJed Brown PetscErrorCode DMPlexGetFullMeet(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 4453552f7358SJed Brown { 4454552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 4455552f7358SJed Brown PetscInt *offsets, **closures; 4456552f7358SJed Brown PetscInt *meet[2]; 4457552f7358SJed Brown PetscInt height = 0, maxSize, meetSize = 0, i = 0; 445824c766afSToby Isaac PetscInt p, h, c, m, mc; 4459552f7358SJed Brown PetscErrorCode ierr; 4460552f7358SJed Brown 4461552f7358SJed Brown PetscFunctionBegin; 4462552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4463064a246eSJacob Faibussowitsch PetscValidPointer(points, 3); 4464064a246eSJacob Faibussowitsch PetscValidPointer(numCoveredPoints, 4); 4465064a246eSJacob Faibussowitsch PetscValidPointer(coveredPoints, 5); 4466552f7358SJed Brown 4467552f7358SJed Brown ierr = DMPlexGetDepth(dm, &height);CHKERRQ(ierr); 4468785e854fSJed Brown ierr = PetscMalloc1(numPoints, &closures);CHKERRQ(ierr); 446969291d52SBarry Smith ierr = DMGetWorkArray(dm, numPoints*(height+2), MPIU_INT, &offsets);CHKERRQ(ierr); 447024c766afSToby Isaac mc = mesh->maxConeSize; 447124c766afSToby Isaac maxSize = (mc > 1) ? ((PetscPowInt(mc,height+1)-1)/(mc-1)) : height + 1; 447269291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &meet[0]);CHKERRQ(ierr); 447369291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &meet[1]);CHKERRQ(ierr); 4474552f7358SJed Brown 4475552f7358SJed Brown for (p = 0; p < numPoints; ++p) { 4476552f7358SJed Brown PetscInt closureSize; 4477552f7358SJed Brown 4478552f7358SJed Brown ierr = DMPlexGetTransitiveClosure(dm, points[p], PETSC_TRUE, &closureSize, &closures[p]);CHKERRQ(ierr); 44790d644c17SKarl Rupp 4480552f7358SJed Brown offsets[p*(height+2)+0] = 0; 4481552f7358SJed Brown for (h = 0; h < height+1; ++h) { 4482552f7358SJed Brown PetscInt pStart, pEnd, i; 4483552f7358SJed Brown 4484552f7358SJed Brown ierr = DMPlexGetHeightStratum(dm, h, &pStart, &pEnd);CHKERRQ(ierr); 4485552f7358SJed Brown for (i = offsets[p*(height+2)+h]; i < closureSize; ++i) { 4486552f7358SJed Brown if ((pStart > closures[p][i*2]) || (pEnd <= closures[p][i*2])) { 4487552f7358SJed Brown offsets[p*(height+2)+h+1] = i; 4488552f7358SJed Brown break; 4489552f7358SJed Brown } 4490552f7358SJed Brown } 4491552f7358SJed Brown if (i == closureSize) offsets[p*(height+2)+h+1] = i; 4492552f7358SJed Brown } 449382f516ccSBarry Smith if (offsets[p*(height+2)+height+1] != closureSize) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Total size of closure %D should be %D", offsets[p*(height+2)+height+1], closureSize); 4494552f7358SJed Brown } 4495552f7358SJed Brown for (h = 0; h < height+1; ++h) { 4496552f7358SJed Brown PetscInt dof; 4497552f7358SJed Brown 4498552f7358SJed Brown /* Copy in cone of first point */ 4499552f7358SJed Brown dof = offsets[h+1] - offsets[h]; 4500552f7358SJed Brown for (meetSize = 0; meetSize < dof; ++meetSize) { 4501552f7358SJed Brown meet[i][meetSize] = closures[0][(offsets[h]+meetSize)*2]; 4502552f7358SJed Brown } 4503552f7358SJed Brown /* Check each successive cone */ 4504552f7358SJed Brown for (p = 1; p < numPoints && meetSize; ++p) { 4505552f7358SJed Brown PetscInt newMeetSize = 0; 4506552f7358SJed Brown 4507552f7358SJed Brown dof = offsets[p*(height+2)+h+1] - offsets[p*(height+2)+h]; 4508552f7358SJed Brown for (c = 0; c < dof; ++c) { 4509552f7358SJed Brown const PetscInt point = closures[p][(offsets[p*(height+2)+h]+c)*2]; 4510552f7358SJed Brown 4511552f7358SJed Brown for (m = 0; m < meetSize; ++m) { 4512552f7358SJed Brown if (point == meet[i][m]) { 4513552f7358SJed Brown meet[1-i][newMeetSize++] = point; 4514552f7358SJed Brown break; 4515552f7358SJed Brown } 4516552f7358SJed Brown } 4517552f7358SJed Brown } 4518552f7358SJed Brown meetSize = newMeetSize; 4519552f7358SJed Brown i = 1-i; 4520552f7358SJed Brown } 4521552f7358SJed Brown if (meetSize) break; 4522552f7358SJed Brown } 4523552f7358SJed Brown *numCoveredPoints = meetSize; 4524552f7358SJed Brown *coveredPoints = meet[i]; 4525552f7358SJed Brown for (p = 0; p < numPoints; ++p) { 45260298fd71SBarry Smith ierr = DMPlexRestoreTransitiveClosure(dm, points[p], PETSC_TRUE, NULL, &closures[p]);CHKERRQ(ierr); 4527552f7358SJed Brown } 4528552f7358SJed Brown ierr = PetscFree(closures);CHKERRQ(ierr); 452969291d52SBarry Smith ierr = DMRestoreWorkArray(dm, numPoints*(height+2), MPIU_INT, &offsets);CHKERRQ(ierr); 453069291d52SBarry Smith ierr = DMRestoreWorkArray(dm, mesh->maxConeSize, MPIU_INT, &meet[1-i]);CHKERRQ(ierr); 4531552f7358SJed Brown PetscFunctionReturn(0); 4532552f7358SJed Brown } 4533552f7358SJed Brown 45344e3744c5SMatthew G. Knepley /*@C 45354e3744c5SMatthew G. Knepley DMPlexEqual - Determine if two DMs have the same topology 45364e3744c5SMatthew G. Knepley 45374e3744c5SMatthew G. Knepley Not Collective 45384e3744c5SMatthew G. Knepley 45394e3744c5SMatthew G. Knepley Input Parameters: 45404e3744c5SMatthew G. Knepley + dmA - A DMPlex object 45414e3744c5SMatthew G. Knepley - dmB - A DMPlex object 45424e3744c5SMatthew G. Knepley 45434e3744c5SMatthew G. Knepley Output Parameters: 45444e3744c5SMatthew G. Knepley . equal - PETSC_TRUE if the topologies are identical 45454e3744c5SMatthew G. Knepley 45464e3744c5SMatthew G. Knepley Level: intermediate 45474e3744c5SMatthew G. Knepley 45484e3744c5SMatthew G. Knepley Notes: 45494e3744c5SMatthew G. Knepley We are not solving graph isomorphism, so we do not permutation. 45504e3744c5SMatthew G. Knepley 45514e3744c5SMatthew G. Knepley .seealso: DMPlexGetCone() 45524e3744c5SMatthew G. Knepley @*/ 45534e3744c5SMatthew G. Knepley PetscErrorCode DMPlexEqual(DM dmA, DM dmB, PetscBool *equal) 45544e3744c5SMatthew G. Knepley { 45554e3744c5SMatthew G. Knepley PetscInt depth, depthB, pStart, pEnd, pStartB, pEndB, p; 45564e3744c5SMatthew G. Knepley PetscErrorCode ierr; 45574e3744c5SMatthew G. Knepley 45584e3744c5SMatthew G. Knepley PetscFunctionBegin; 45594e3744c5SMatthew G. Knepley PetscValidHeaderSpecific(dmA, DM_CLASSID, 1); 45604e3744c5SMatthew G. Knepley PetscValidHeaderSpecific(dmB, DM_CLASSID, 2); 45614e3744c5SMatthew G. Knepley PetscValidPointer(equal, 3); 45624e3744c5SMatthew G. Knepley 45634e3744c5SMatthew G. Knepley *equal = PETSC_FALSE; 45644e3744c5SMatthew G. Knepley ierr = DMPlexGetDepth(dmA, &depth);CHKERRQ(ierr); 45654e3744c5SMatthew G. Knepley ierr = DMPlexGetDepth(dmB, &depthB);CHKERRQ(ierr); 45664e3744c5SMatthew G. Knepley if (depth != depthB) PetscFunctionReturn(0); 45674e3744c5SMatthew G. Knepley ierr = DMPlexGetChart(dmA, &pStart, &pEnd);CHKERRQ(ierr); 45684e3744c5SMatthew G. Knepley ierr = DMPlexGetChart(dmB, &pStartB, &pEndB);CHKERRQ(ierr); 45694e3744c5SMatthew G. Knepley if ((pStart != pStartB) || (pEnd != pEndB)) PetscFunctionReturn(0); 45704e3744c5SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 45714e3744c5SMatthew G. Knepley const PetscInt *cone, *coneB, *ornt, *orntB, *support, *supportB; 45724e3744c5SMatthew G. Knepley PetscInt coneSize, coneSizeB, c, supportSize, supportSizeB, s; 45734e3744c5SMatthew G. Knepley 45744e3744c5SMatthew G. Knepley ierr = DMPlexGetConeSize(dmA, p, &coneSize);CHKERRQ(ierr); 45754e3744c5SMatthew G. Knepley ierr = DMPlexGetCone(dmA, p, &cone);CHKERRQ(ierr); 45764e3744c5SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dmA, p, &ornt);CHKERRQ(ierr); 45774e3744c5SMatthew G. Knepley ierr = DMPlexGetConeSize(dmB, p, &coneSizeB);CHKERRQ(ierr); 45784e3744c5SMatthew G. Knepley ierr = DMPlexGetCone(dmB, p, &coneB);CHKERRQ(ierr); 45794e3744c5SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dmB, p, &orntB);CHKERRQ(ierr); 45804e3744c5SMatthew G. Knepley if (coneSize != coneSizeB) PetscFunctionReturn(0); 45814e3744c5SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 45824e3744c5SMatthew G. Knepley if (cone[c] != coneB[c]) PetscFunctionReturn(0); 45834e3744c5SMatthew G. Knepley if (ornt[c] != orntB[c]) PetscFunctionReturn(0); 45844e3744c5SMatthew G. Knepley } 45854e3744c5SMatthew G. Knepley ierr = DMPlexGetSupportSize(dmA, p, &supportSize);CHKERRQ(ierr); 45864e3744c5SMatthew G. Knepley ierr = DMPlexGetSupport(dmA, p, &support);CHKERRQ(ierr); 45874e3744c5SMatthew G. Knepley ierr = DMPlexGetSupportSize(dmB, p, &supportSizeB);CHKERRQ(ierr); 45884e3744c5SMatthew G. Knepley ierr = DMPlexGetSupport(dmB, p, &supportB);CHKERRQ(ierr); 45894e3744c5SMatthew G. Knepley if (supportSize != supportSizeB) PetscFunctionReturn(0); 45904e3744c5SMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 45914e3744c5SMatthew G. Knepley if (support[s] != supportB[s]) PetscFunctionReturn(0); 45924e3744c5SMatthew G. Knepley } 45934e3744c5SMatthew G. Knepley } 45944e3744c5SMatthew G. Knepley *equal = PETSC_TRUE; 45954e3744c5SMatthew G. Knepley PetscFunctionReturn(0); 45964e3744c5SMatthew G. Knepley } 45974e3744c5SMatthew G. Knepley 45987cd05799SMatthew G. Knepley /*@C 45997cd05799SMatthew G. Knepley DMPlexGetNumFaceVertices - Returns the number of vertices on a face 46007cd05799SMatthew G. Knepley 46017cd05799SMatthew G. Knepley Not Collective 46027cd05799SMatthew G. Knepley 46037cd05799SMatthew G. Knepley Input Parameters: 46047cd05799SMatthew G. Knepley + dm - The DMPlex 46057cd05799SMatthew G. Knepley . cellDim - The cell dimension 46067cd05799SMatthew G. Knepley - numCorners - The number of vertices on a cell 46077cd05799SMatthew G. Knepley 46087cd05799SMatthew G. Knepley Output Parameters: 46097cd05799SMatthew G. Knepley . numFaceVertices - The number of vertices on a face 46107cd05799SMatthew G. Knepley 46117cd05799SMatthew G. Knepley Level: developer 46127cd05799SMatthew G. Knepley 46137cd05799SMatthew G. Knepley Notes: 46147cd05799SMatthew G. Knepley Of course this can only work for a restricted set of symmetric shapes 46157cd05799SMatthew G. Knepley 46167cd05799SMatthew G. Knepley .seealso: DMPlexGetCone() 46177cd05799SMatthew G. Knepley @*/ 461818ad9376SMatthew G. Knepley PetscErrorCode DMPlexGetNumFaceVertices(DM dm, PetscInt cellDim, PetscInt numCorners, PetscInt *numFaceVertices) 4619a6dfd86eSKarl Rupp { 462082f516ccSBarry Smith MPI_Comm comm; 4621552f7358SJed Brown PetscErrorCode ierr; 4622552f7358SJed Brown 4623552f7358SJed Brown PetscFunctionBegin; 462482f516ccSBarry Smith ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 4625064a246eSJacob Faibussowitsch PetscValidPointer(numFaceVertices,4); 4626552f7358SJed Brown switch (cellDim) { 4627552f7358SJed Brown case 0: 4628552f7358SJed Brown *numFaceVertices = 0; 4629552f7358SJed Brown break; 4630552f7358SJed Brown case 1: 4631552f7358SJed Brown *numFaceVertices = 1; 4632552f7358SJed Brown break; 4633552f7358SJed Brown case 2: 4634552f7358SJed Brown switch (numCorners) { 463519436ca2SJed Brown case 3: /* triangle */ 463619436ca2SJed Brown *numFaceVertices = 2; /* Edge has 2 vertices */ 4637552f7358SJed Brown break; 463819436ca2SJed Brown case 4: /* quadrilateral */ 463919436ca2SJed Brown *numFaceVertices = 2; /* Edge has 2 vertices */ 4640552f7358SJed Brown break; 464119436ca2SJed Brown case 6: /* quadratic triangle, tri and quad cohesive Lagrange cells */ 464219436ca2SJed Brown *numFaceVertices = 3; /* Edge has 3 vertices */ 4643552f7358SJed Brown break; 464419436ca2SJed Brown case 9: /* quadratic quadrilateral, quadratic quad cohesive Lagrange cells */ 464519436ca2SJed Brown *numFaceVertices = 3; /* Edge has 3 vertices */ 4646552f7358SJed Brown break; 4647552f7358SJed Brown default: 4648f347f43bSBarry Smith SETERRQ2(comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid number of face corners %D for dimension %D", numCorners, cellDim); 4649552f7358SJed Brown } 4650552f7358SJed Brown break; 4651552f7358SJed Brown case 3: 4652552f7358SJed Brown switch (numCorners) { 465319436ca2SJed Brown case 4: /* tetradehdron */ 465419436ca2SJed Brown *numFaceVertices = 3; /* Face has 3 vertices */ 4655552f7358SJed Brown break; 465619436ca2SJed Brown case 6: /* tet cohesive cells */ 465719436ca2SJed Brown *numFaceVertices = 4; /* Face has 4 vertices */ 4658552f7358SJed Brown break; 465919436ca2SJed Brown case 8: /* hexahedron */ 466019436ca2SJed Brown *numFaceVertices = 4; /* Face has 4 vertices */ 4661552f7358SJed Brown break; 466219436ca2SJed Brown case 9: /* tet cohesive Lagrange cells */ 466319436ca2SJed Brown *numFaceVertices = 6; /* Face has 6 vertices */ 4664552f7358SJed Brown break; 466519436ca2SJed Brown case 10: /* quadratic tetrahedron */ 466619436ca2SJed Brown *numFaceVertices = 6; /* Face has 6 vertices */ 4667552f7358SJed Brown break; 466819436ca2SJed Brown case 12: /* hex cohesive Lagrange cells */ 466919436ca2SJed Brown *numFaceVertices = 6; /* Face has 6 vertices */ 4670552f7358SJed Brown break; 467119436ca2SJed Brown case 18: /* quadratic tet cohesive Lagrange cells */ 467219436ca2SJed Brown *numFaceVertices = 6; /* Face has 6 vertices */ 4673552f7358SJed Brown break; 467419436ca2SJed Brown case 27: /* quadratic hexahedron, quadratic hex cohesive Lagrange cells */ 467519436ca2SJed Brown *numFaceVertices = 9; /* Face has 9 vertices */ 4676552f7358SJed Brown break; 4677552f7358SJed Brown default: 4678f347f43bSBarry Smith SETERRQ2(comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid number of face corners %D for dimension %D", numCorners, cellDim); 4679552f7358SJed Brown } 4680552f7358SJed Brown break; 4681552f7358SJed Brown default: 4682f347f43bSBarry Smith SETERRQ1(comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid cell dimension %D", cellDim); 4683552f7358SJed Brown } 4684552f7358SJed Brown PetscFunctionReturn(0); 4685552f7358SJed Brown } 4686552f7358SJed Brown 4687552f7358SJed Brown /*@ 4688aa50250dSMatthew G. Knepley DMPlexGetDepthLabel - Get the DMLabel recording the depth of each point 4689552f7358SJed Brown 4690552f7358SJed Brown Not Collective 4691552f7358SJed Brown 4692aa50250dSMatthew G. Knepley Input Parameter: 4693552f7358SJed Brown . dm - The DMPlex object 4694552f7358SJed Brown 4695aa50250dSMatthew G. Knepley Output Parameter: 4696aa50250dSMatthew G. Knepley . depthLabel - The DMLabel recording point depth 4697552f7358SJed Brown 4698552f7358SJed Brown Level: developer 4699552f7358SJed Brown 4700dc287ab2SVaclav Hapla .seealso: DMPlexGetDepth(), DMPlexGetHeightStratum(), DMPlexGetDepthStratum(), DMPlexGetPointDepth(), 4701aa50250dSMatthew G. Knepley @*/ 4702aa50250dSMatthew G. Knepley PetscErrorCode DMPlexGetDepthLabel(DM dm, DMLabel *depthLabel) 4703aa50250dSMatthew G. Knepley { 4704aa50250dSMatthew G. Knepley PetscFunctionBegin; 4705aa50250dSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4706aa50250dSMatthew G. Knepley PetscValidPointer(depthLabel, 2); 4707c58f1c22SToby Isaac *depthLabel = dm->depthLabel; 4708aa50250dSMatthew G. Knepley PetscFunctionReturn(0); 4709aa50250dSMatthew G. Knepley } 4710aa50250dSMatthew G. Knepley 4711aa50250dSMatthew G. Knepley /*@ 4712aa50250dSMatthew G. Knepley DMPlexGetDepth - Get the depth of the DAG representing this mesh 4713aa50250dSMatthew G. Knepley 4714aa50250dSMatthew G. Knepley Not Collective 4715aa50250dSMatthew G. Knepley 4716aa50250dSMatthew G. Knepley Input Parameter: 4717aa50250dSMatthew G. Knepley . dm - The DMPlex object 4718aa50250dSMatthew G. Knepley 4719aa50250dSMatthew G. Knepley Output Parameter: 4720aa50250dSMatthew G. Knepley . depth - The number of strata (breadth first levels) in the DAG 4721aa50250dSMatthew G. Knepley 4722aa50250dSMatthew G. Knepley Level: developer 4723552f7358SJed Brown 4724b1bb481bSMatthew Knepley Notes: 4725b1bb481bSMatthew Knepley This returns maximum of point depths over all points, i.e. maximum value of the label returned by DMPlexGetDepthLabel(). 4726dc287ab2SVaclav Hapla The point depth is described more in detail in DMPlexGetDepthStratum(). 4727dc287ab2SVaclav Hapla An empty mesh gives -1. 4728b1bb481bSMatthew Knepley 4729dc287ab2SVaclav Hapla .seealso: DMPlexGetDepthLabel(), DMPlexGetDepthStratum(), DMPlexGetPointDepth(), DMPlexSymmetrize() 4730552f7358SJed Brown @*/ 4731552f7358SJed Brown PetscErrorCode DMPlexGetDepth(DM dm, PetscInt *depth) 4732552f7358SJed Brown { 4733aa50250dSMatthew G. Knepley DMLabel label; 4734aa50250dSMatthew G. Knepley PetscInt d = 0; 4735552f7358SJed Brown PetscErrorCode ierr; 4736552f7358SJed Brown 4737552f7358SJed Brown PetscFunctionBegin; 4738552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4739552f7358SJed Brown PetscValidPointer(depth, 2); 4740aa50250dSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 4741aa50250dSMatthew G. Knepley if (label) {ierr = DMLabelGetNumValues(label, &d);CHKERRQ(ierr);} 4742552f7358SJed Brown *depth = d-1; 4743552f7358SJed Brown PetscFunctionReturn(0); 4744552f7358SJed Brown } 4745552f7358SJed Brown 4746552f7358SJed Brown /*@ 4747552f7358SJed Brown DMPlexGetDepthStratum - Get the bounds [start, end) for all points at a certain depth. 4748552f7358SJed Brown 4749552f7358SJed Brown Not Collective 4750552f7358SJed Brown 4751552f7358SJed Brown Input Parameters: 4752552f7358SJed Brown + dm - The DMPlex object 4753552f7358SJed Brown - stratumValue - The requested depth 4754552f7358SJed Brown 4755552f7358SJed Brown Output Parameters: 4756552f7358SJed Brown + start - The first point at this depth 4757552f7358SJed Brown - end - One beyond the last point at this depth 4758552f7358SJed Brown 4759647867b2SJed Brown Notes: 4760647867b2SJed Brown Depth indexing is related to topological dimension. Depth stratum 0 contains the lowest topological dimension points, 4761647867b2SJed Brown often "vertices". If the mesh is "interpolated" (see DMPlexInterpolate()), then depth stratum 1 contains the next 4762647867b2SJed Brown higher dimension, e.g., "edges". 4763647867b2SJed Brown 4764552f7358SJed Brown Level: developer 4765552f7358SJed Brown 4766dc287ab2SVaclav Hapla .seealso: DMPlexGetHeightStratum(), DMPlexGetDepth(), DMPlexGetDepthLabel(), DMPlexGetPointDepth(), DMPlexSymmetrize(), DMPlexInterpolate() 4767552f7358SJed Brown @*/ 47680adebc6cSBarry Smith PetscErrorCode DMPlexGetDepthStratum(DM dm, PetscInt stratumValue, PetscInt *start, PetscInt *end) 47690adebc6cSBarry Smith { 4770aa50250dSMatthew G. Knepley DMLabel label; 477163d1a920SMatthew G. Knepley PetscInt pStart, pEnd; 4772552f7358SJed Brown PetscErrorCode ierr; 4773552f7358SJed Brown 4774552f7358SJed Brown PetscFunctionBegin; 4775552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 477663d1a920SMatthew G. Knepley if (start) {PetscValidPointer(start, 3); *start = 0;} 477763d1a920SMatthew G. Knepley if (end) {PetscValidPointer(end, 4); *end = 0;} 4778552f7358SJed Brown ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 47790d644c17SKarl Rupp if (pStart == pEnd) PetscFunctionReturn(0); 478063d1a920SMatthew G. Knepley if (stratumValue < 0) { 478163d1a920SMatthew G. Knepley if (start) *start = pStart; 478263d1a920SMatthew G. Knepley if (end) *end = pEnd; 478363d1a920SMatthew G. Knepley PetscFunctionReturn(0); 4784552f7358SJed Brown } 4785aa50250dSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 478663d1a920SMatthew G. Knepley if (!label) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "No label named depth was found"); 478763d1a920SMatthew G. Knepley ierr = DMLabelGetStratumBounds(label, stratumValue, start, end);CHKERRQ(ierr); 4788552f7358SJed Brown PetscFunctionReturn(0); 4789552f7358SJed Brown } 4790552f7358SJed Brown 4791552f7358SJed Brown /*@ 4792552f7358SJed Brown DMPlexGetHeightStratum - Get the bounds [start, end) for all points at a certain height. 4793552f7358SJed Brown 4794552f7358SJed Brown Not Collective 4795552f7358SJed Brown 4796552f7358SJed Brown Input Parameters: 4797552f7358SJed Brown + dm - The DMPlex object 4798552f7358SJed Brown - stratumValue - The requested height 4799552f7358SJed Brown 4800552f7358SJed Brown Output Parameters: 4801552f7358SJed Brown + start - The first point at this height 4802552f7358SJed Brown - end - One beyond the last point at this height 4803552f7358SJed Brown 4804647867b2SJed Brown Notes: 4805647867b2SJed Brown Height indexing is related to topological codimension. Height stratum 0 contains the highest topological dimension 4806647867b2SJed Brown points, often called "cells" or "elements". If the mesh is "interpolated" (see DMPlexInterpolate()), then height 4807647867b2SJed Brown stratum 1 contains the boundary of these "cells", often called "faces" or "facets". 4808647867b2SJed Brown 4809552f7358SJed Brown Level: developer 4810552f7358SJed Brown 48113dc9a465SVaclav Hapla .seealso: DMPlexGetDepthStratum(), DMPlexGetDepth(), DMPlexGetPointHeight() 4812552f7358SJed Brown @*/ 48130adebc6cSBarry Smith PetscErrorCode DMPlexGetHeightStratum(DM dm, PetscInt stratumValue, PetscInt *start, PetscInt *end) 48140adebc6cSBarry Smith { 4815aa50250dSMatthew G. Knepley DMLabel label; 481663d1a920SMatthew G. Knepley PetscInt depth, pStart, pEnd; 4817552f7358SJed Brown PetscErrorCode ierr; 4818552f7358SJed Brown 4819552f7358SJed Brown PetscFunctionBegin; 4820552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 482163d1a920SMatthew G. Knepley if (start) {PetscValidPointer(start, 3); *start = 0;} 482263d1a920SMatthew G. Knepley if (end) {PetscValidPointer(end, 4); *end = 0;} 4823552f7358SJed Brown ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 48240d644c17SKarl Rupp if (pStart == pEnd) PetscFunctionReturn(0); 482563d1a920SMatthew G. Knepley if (stratumValue < 0) { 482663d1a920SMatthew G. Knepley if (start) *start = pStart; 482763d1a920SMatthew G. Knepley if (end) *end = pEnd; 482863d1a920SMatthew G. Knepley PetscFunctionReturn(0); 4829552f7358SJed Brown } 4830aa50250dSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 483113903a91SSatish Balay if (!label) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "No label named depth was found"); 483263d1a920SMatthew G. Knepley ierr = DMLabelGetNumValues(label, &depth);CHKERRQ(ierr); 483363d1a920SMatthew G. Knepley ierr = DMLabelGetStratumBounds(label, depth-1-stratumValue, start, end);CHKERRQ(ierr); 4834552f7358SJed Brown PetscFunctionReturn(0); 4835552f7358SJed Brown } 4836552f7358SJed Brown 4837ba2698f1SMatthew G. Knepley /*@ 4838ba2698f1SMatthew G. Knepley DMPlexGetPointDepth - Get the depth of a given point 4839ba2698f1SMatthew G. Knepley 4840ba2698f1SMatthew G. Knepley Not Collective 4841ba2698f1SMatthew G. Knepley 4842d8d19677SJose E. Roman Input Parameters: 4843ba2698f1SMatthew G. Knepley + dm - The DMPlex object 4844ba2698f1SMatthew G. Knepley - point - The point 4845ba2698f1SMatthew G. Knepley 4846ba2698f1SMatthew G. Knepley Output Parameter: 4847ba2698f1SMatthew G. Knepley . depth - The depth of the point 4848ba2698f1SMatthew G. Knepley 4849ba2698f1SMatthew G. Knepley Level: intermediate 4850ba2698f1SMatthew G. Knepley 48513dc9a465SVaclav Hapla .seealso: DMPlexGetCellType(), DMPlexGetDepthLabel(), DMPlexGetDepth(), DMPlexGetPointHeight() 4852ba2698f1SMatthew G. Knepley @*/ 4853ba2698f1SMatthew G. Knepley PetscErrorCode DMPlexGetPointDepth(DM dm, PetscInt point, PetscInt *depth) 4854ba2698f1SMatthew G. Knepley { 4855ba2698f1SMatthew G. Knepley PetscErrorCode ierr; 4856ba2698f1SMatthew G. Knepley 4857ba2698f1SMatthew G. Knepley PetscFunctionBegin; 4858ba2698f1SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 485940a2aa30SMatthew G. Knepley PetscValidIntPointer(depth, 3); 4860ba2698f1SMatthew G. Knepley ierr = DMLabelGetValue(dm->depthLabel, point, depth);CHKERRQ(ierr); 4861ba2698f1SMatthew G. Knepley PetscFunctionReturn(0); 4862ba2698f1SMatthew G. Knepley } 4863ba2698f1SMatthew G. Knepley 4864ba2698f1SMatthew G. Knepley /*@ 48650c0a32dcSVaclav Hapla DMPlexGetPointHeight - Get the height of a given point 48660c0a32dcSVaclav Hapla 48670c0a32dcSVaclav Hapla Not Collective 48680c0a32dcSVaclav Hapla 4869d8d19677SJose E. Roman Input Parameters: 48700c0a32dcSVaclav Hapla + dm - The DMPlex object 48710c0a32dcSVaclav Hapla - point - The point 48720c0a32dcSVaclav Hapla 48730c0a32dcSVaclav Hapla Output Parameter: 48740c0a32dcSVaclav Hapla . height - The height of the point 48750c0a32dcSVaclav Hapla 48760c0a32dcSVaclav Hapla Level: intermediate 48770c0a32dcSVaclav Hapla 48783dc9a465SVaclav Hapla .seealso: DMPlexGetCellType(), DMPlexGetDepthLabel(), DMPlexGetDepth(), DMPlexGetPointDepth() 48790c0a32dcSVaclav Hapla @*/ 48800c0a32dcSVaclav Hapla PetscErrorCode DMPlexGetPointHeight(DM dm, PetscInt point, PetscInt *height) 48810c0a32dcSVaclav Hapla { 48820c0a32dcSVaclav Hapla PetscInt n, pDepth; 48830c0a32dcSVaclav Hapla PetscErrorCode ierr; 48840c0a32dcSVaclav Hapla 48850c0a32dcSVaclav Hapla PetscFunctionBegin; 48860c0a32dcSVaclav Hapla PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 48870c0a32dcSVaclav Hapla PetscValidIntPointer(height, 3); 48880c0a32dcSVaclav Hapla ierr = DMLabelGetNumValues(dm->depthLabel, &n);CHKERRQ(ierr); 48890c0a32dcSVaclav Hapla ierr = DMLabelGetValue(dm->depthLabel, point, &pDepth);CHKERRQ(ierr); 48900c0a32dcSVaclav Hapla *height = n - 1 - pDepth; /* DAG depth is n-1 */ 48910c0a32dcSVaclav Hapla PetscFunctionReturn(0); 48920c0a32dcSVaclav Hapla } 48930c0a32dcSVaclav Hapla 48940c0a32dcSVaclav Hapla /*@ 4895ba2698f1SMatthew G. Knepley DMPlexGetCellTypeLabel - Get the DMLabel recording the polytope type of each cell 4896ba2698f1SMatthew G. Knepley 4897ba2698f1SMatthew G. Knepley Not Collective 4898ba2698f1SMatthew G. Knepley 4899ba2698f1SMatthew G. Knepley Input Parameter: 4900ba2698f1SMatthew G. Knepley . dm - The DMPlex object 4901ba2698f1SMatthew G. Knepley 4902ba2698f1SMatthew G. Knepley Output Parameter: 4903ba2698f1SMatthew G. Knepley . celltypeLabel - The DMLabel recording cell polytope type 4904ba2698f1SMatthew G. Knepley 4905412e9a14SMatthew G. Knepley Note: This function will trigger automatica computation of cell types. This can be disabled by calling 4906412e9a14SMatthew G. Knepley DMCreateLabel(dm, "celltype") beforehand. 4907412e9a14SMatthew G. Knepley 4908ba2698f1SMatthew G. Knepley Level: developer 4909ba2698f1SMatthew G. Knepley 4910dc287ab2SVaclav Hapla .seealso: DMPlexGetCellType(), DMPlexGetDepthLabel(), DMCreateLabel() 4911ba2698f1SMatthew G. Knepley @*/ 4912ba2698f1SMatthew G. Knepley PetscErrorCode DMPlexGetCellTypeLabel(DM dm, DMLabel *celltypeLabel) 4913ba2698f1SMatthew G. Knepley { 4914ba2698f1SMatthew G. Knepley PetscErrorCode ierr; 4915ba2698f1SMatthew G. Knepley 4916ba2698f1SMatthew G. Knepley PetscFunctionBegin; 4917ba2698f1SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4918ba2698f1SMatthew G. Knepley PetscValidPointer(celltypeLabel, 2); 4919ba2698f1SMatthew G. Knepley if (!dm->celltypeLabel) {ierr = DMPlexComputeCellTypes(dm);CHKERRQ(ierr);} 4920ba2698f1SMatthew G. Knepley *celltypeLabel = dm->celltypeLabel; 4921ba2698f1SMatthew G. Knepley PetscFunctionReturn(0); 4922ba2698f1SMatthew G. Knepley } 4923ba2698f1SMatthew G. Knepley 4924ba2698f1SMatthew G. Knepley /*@ 4925ba2698f1SMatthew G. Knepley DMPlexGetCellType - Get the polytope type of a given cell 4926ba2698f1SMatthew G. Knepley 4927ba2698f1SMatthew G. Knepley Not Collective 4928ba2698f1SMatthew G. Knepley 4929d8d19677SJose E. Roman Input Parameters: 4930ba2698f1SMatthew G. Knepley + dm - The DMPlex object 4931ba2698f1SMatthew G. Knepley - cell - The cell 4932ba2698f1SMatthew G. Knepley 4933ba2698f1SMatthew G. Knepley Output Parameter: 4934ba2698f1SMatthew G. Knepley . celltype - The polytope type of the cell 4935ba2698f1SMatthew G. Knepley 4936ba2698f1SMatthew G. Knepley Level: intermediate 4937ba2698f1SMatthew G. Knepley 4938ba2698f1SMatthew G. Knepley .seealso: DMPlexGetCellTypeLabel(), DMPlexGetDepthLabel(), DMPlexGetDepth() 4939ba2698f1SMatthew G. Knepley @*/ 4940ba2698f1SMatthew G. Knepley PetscErrorCode DMPlexGetCellType(DM dm, PetscInt cell, DMPolytopeType *celltype) 4941ba2698f1SMatthew G. Knepley { 4942ba2698f1SMatthew G. Knepley DMLabel label; 4943ba2698f1SMatthew G. Knepley PetscInt ct; 4944ba2698f1SMatthew G. Knepley PetscErrorCode ierr; 4945ba2698f1SMatthew G. Knepley 4946ba2698f1SMatthew G. Knepley PetscFunctionBegin; 4947ba2698f1SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4948ba2698f1SMatthew G. Knepley PetscValidPointer(celltype, 3); 4949ba2698f1SMatthew G. Knepley ierr = DMPlexGetCellTypeLabel(dm, &label);CHKERRQ(ierr); 4950ba2698f1SMatthew G. Knepley ierr = DMLabelGetValue(label, cell, &ct);CHKERRQ(ierr); 49514a7ee7d0SMatthew G. Knepley if (ct < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Cell %D has not been assigned a cell type", cell); 4952ba2698f1SMatthew G. Knepley *celltype = (DMPolytopeType) ct; 4953ba2698f1SMatthew G. Knepley PetscFunctionReturn(0); 4954ba2698f1SMatthew G. Knepley } 4955ba2698f1SMatthew G. Knepley 4956412e9a14SMatthew G. Knepley /*@ 4957412e9a14SMatthew G. Knepley DMPlexSetCellType - Set the polytope type of a given cell 4958412e9a14SMatthew G. Knepley 4959412e9a14SMatthew G. Knepley Not Collective 4960412e9a14SMatthew G. Knepley 4961412e9a14SMatthew G. Knepley Input Parameters: 4962412e9a14SMatthew G. Knepley + dm - The DMPlex object 4963412e9a14SMatthew G. Knepley . cell - The cell 4964412e9a14SMatthew G. Knepley - celltype - The polytope type of the cell 4965412e9a14SMatthew G. Knepley 4966412e9a14SMatthew G. Knepley Note: By default, cell types will be automatically computed using DMPlexComputeCellTypes() before this function 4967412e9a14SMatthew G. Knepley is executed. This function will override the computed type. However, if automatic classification will not succeed 4968412e9a14SMatthew G. Knepley and a user wants to manually specify all types, the classification must be disabled by calling 4969412e9a14SMatthew G. Knepley DMCreaateLabel(dm, "celltype") before getting or setting any cell types. 4970412e9a14SMatthew G. Knepley 4971412e9a14SMatthew G. Knepley Level: advanced 4972412e9a14SMatthew G. Knepley 4973412e9a14SMatthew G. Knepley .seealso: DMPlexGetCellTypeLabel(), DMPlexGetDepthLabel(), DMPlexGetDepth(), DMPlexComputeCellTypes(), DMCreateLabel() 4974412e9a14SMatthew G. Knepley @*/ 4975412e9a14SMatthew G. Knepley PetscErrorCode DMPlexSetCellType(DM dm, PetscInt cell, DMPolytopeType celltype) 4976412e9a14SMatthew G. Knepley { 4977412e9a14SMatthew G. Knepley DMLabel label; 4978412e9a14SMatthew G. Knepley PetscErrorCode ierr; 4979412e9a14SMatthew G. Knepley 4980412e9a14SMatthew G. Knepley PetscFunctionBegin; 4981412e9a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4982412e9a14SMatthew G. Knepley ierr = DMPlexGetCellTypeLabel(dm, &label);CHKERRQ(ierr); 4983412e9a14SMatthew G. Knepley ierr = DMLabelSetValue(label, cell, celltype);CHKERRQ(ierr); 4984412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 4985412e9a14SMatthew G. Knepley } 4986412e9a14SMatthew G. Knepley 49870adebc6cSBarry Smith PetscErrorCode DMCreateCoordinateDM_Plex(DM dm, DM *cdm) 49880adebc6cSBarry Smith { 4989efe440bfSMatthew G. Knepley PetscSection section, s; 4990efe440bfSMatthew G. Knepley Mat m; 49913e922f36SToby Isaac PetscInt maxHeight; 4992552f7358SJed Brown PetscErrorCode ierr; 4993552f7358SJed Brown 4994552f7358SJed Brown PetscFunctionBegin; 499538221697SMatthew G. Knepley ierr = DMClone(dm, cdm);CHKERRQ(ierr); 49963e922f36SToby Isaac ierr = DMPlexGetMaxProjectionHeight(dm, &maxHeight);CHKERRQ(ierr); 49973e922f36SToby Isaac ierr = DMPlexSetMaxProjectionHeight(*cdm, maxHeight);CHKERRQ(ierr); 499882f516ccSBarry Smith ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), §ion);CHKERRQ(ierr); 499992fd8e1eSJed Brown ierr = DMSetLocalSection(*cdm, section);CHKERRQ(ierr); 50001d799100SJed Brown ierr = PetscSectionDestroy(§ion);CHKERRQ(ierr); 5001efe440bfSMatthew G. Knepley ierr = PetscSectionCreate(PETSC_COMM_SELF, &s);CHKERRQ(ierr); 5002efe440bfSMatthew G. Knepley ierr = MatCreate(PETSC_COMM_SELF, &m);CHKERRQ(ierr); 5003efe440bfSMatthew G. Knepley ierr = DMSetDefaultConstraints(*cdm, s, m);CHKERRQ(ierr); 5004efe440bfSMatthew G. Knepley ierr = PetscSectionDestroy(&s);CHKERRQ(ierr); 5005efe440bfSMatthew G. Knepley ierr = MatDestroy(&m);CHKERRQ(ierr); 50068f4c458bSMatthew G. Knepley 50078f4c458bSMatthew G. Knepley ierr = DMSetNumFields(*cdm, 1);CHKERRQ(ierr); 50088f4c458bSMatthew G. Knepley ierr = DMCreateDS(*cdm);CHKERRQ(ierr); 5009552f7358SJed Brown PetscFunctionReturn(0); 5010552f7358SJed Brown } 5011552f7358SJed Brown 5012f19dbd58SToby Isaac PetscErrorCode DMCreateCoordinateField_Plex(DM dm, DMField *field) 5013f19dbd58SToby Isaac { 5014f19dbd58SToby Isaac Vec coordsLocal; 5015f19dbd58SToby Isaac DM coordsDM; 5016f19dbd58SToby Isaac PetscErrorCode ierr; 5017f19dbd58SToby Isaac 5018f19dbd58SToby Isaac PetscFunctionBegin; 5019f19dbd58SToby Isaac *field = NULL; 5020f19dbd58SToby Isaac ierr = DMGetCoordinatesLocal(dm,&coordsLocal);CHKERRQ(ierr); 5021f19dbd58SToby Isaac ierr = DMGetCoordinateDM(dm,&coordsDM);CHKERRQ(ierr); 5022f19dbd58SToby Isaac if (coordsLocal && coordsDM) { 5023f19dbd58SToby Isaac ierr = DMFieldCreateDS(coordsDM, 0, coordsLocal, field);CHKERRQ(ierr); 5024f19dbd58SToby Isaac } 5025f19dbd58SToby Isaac PetscFunctionReturn(0); 5026f19dbd58SToby Isaac } 5027f19dbd58SToby Isaac 50287cd05799SMatthew G. Knepley /*@C 50297cd05799SMatthew G. Knepley DMPlexGetConeSection - Return a section which describes the layout of cone data 50307cd05799SMatthew G. Knepley 50317cd05799SMatthew G. Knepley Not Collective 50327cd05799SMatthew G. Knepley 50337cd05799SMatthew G. Knepley Input Parameters: 50347cd05799SMatthew G. Knepley . dm - The DMPlex object 50357cd05799SMatthew G. Knepley 50367cd05799SMatthew G. Knepley Output Parameter: 50377cd05799SMatthew G. Knepley . section - The PetscSection object 50387cd05799SMatthew G. Knepley 50397cd05799SMatthew G. Knepley Level: developer 50407cd05799SMatthew G. Knepley 50417cd05799SMatthew G. Knepley .seealso: DMPlexGetSupportSection(), DMPlexGetCones(), DMPlexGetConeOrientations() 50427cd05799SMatthew G. Knepley @*/ 50430adebc6cSBarry Smith PetscErrorCode DMPlexGetConeSection(DM dm, PetscSection *section) 50440adebc6cSBarry Smith { 5045552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 5046552f7358SJed Brown 5047552f7358SJed Brown PetscFunctionBegin; 5048552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5049552f7358SJed Brown if (section) *section = mesh->coneSection; 5050552f7358SJed Brown PetscFunctionReturn(0); 5051552f7358SJed Brown } 5052552f7358SJed Brown 50537cd05799SMatthew G. Knepley /*@C 50547cd05799SMatthew G. Knepley DMPlexGetSupportSection - Return a section which describes the layout of support data 50557cd05799SMatthew G. Knepley 50567cd05799SMatthew G. Knepley Not Collective 50577cd05799SMatthew G. Knepley 50587cd05799SMatthew G. Knepley Input Parameters: 50597cd05799SMatthew G. Knepley . dm - The DMPlex object 50607cd05799SMatthew G. Knepley 50617cd05799SMatthew G. Knepley Output Parameter: 50627cd05799SMatthew G. Knepley . section - The PetscSection object 50637cd05799SMatthew G. Knepley 50647cd05799SMatthew G. Knepley Level: developer 50657cd05799SMatthew G. Knepley 50667cd05799SMatthew G. Knepley .seealso: DMPlexGetConeSection() 50677cd05799SMatthew G. Knepley @*/ 50688cb4d582SMatthew G. Knepley PetscErrorCode DMPlexGetSupportSection(DM dm, PetscSection *section) 50698cb4d582SMatthew G. Knepley { 50708cb4d582SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 50718cb4d582SMatthew G. Knepley 50728cb4d582SMatthew G. Knepley PetscFunctionBegin; 50738cb4d582SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 50748cb4d582SMatthew G. Knepley if (section) *section = mesh->supportSection; 50758cb4d582SMatthew G. Knepley PetscFunctionReturn(0); 50768cb4d582SMatthew G. Knepley } 50778cb4d582SMatthew G. Knepley 50787cd05799SMatthew G. Knepley /*@C 50797cd05799SMatthew G. Knepley DMPlexGetCones - Return cone data 50807cd05799SMatthew G. Knepley 50817cd05799SMatthew G. Knepley Not Collective 50827cd05799SMatthew G. Knepley 50837cd05799SMatthew G. Knepley Input Parameters: 50847cd05799SMatthew G. Knepley . dm - The DMPlex object 50857cd05799SMatthew G. Knepley 50867cd05799SMatthew G. Knepley Output Parameter: 50877cd05799SMatthew G. Knepley . cones - The cone for each point 50887cd05799SMatthew G. Knepley 50897cd05799SMatthew G. Knepley Level: developer 50907cd05799SMatthew G. Knepley 50917cd05799SMatthew G. Knepley .seealso: DMPlexGetConeSection() 50927cd05799SMatthew G. Knepley @*/ 5093a6dfd86eSKarl Rupp PetscErrorCode DMPlexGetCones(DM dm, PetscInt *cones[]) 5094a6dfd86eSKarl Rupp { 5095552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 5096552f7358SJed Brown 5097552f7358SJed Brown PetscFunctionBegin; 5098552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5099552f7358SJed Brown if (cones) *cones = mesh->cones; 5100552f7358SJed Brown PetscFunctionReturn(0); 5101552f7358SJed Brown } 5102552f7358SJed Brown 51037cd05799SMatthew G. Knepley /*@C 51047cd05799SMatthew G. Knepley DMPlexGetConeOrientations - Return cone orientation data 51057cd05799SMatthew G. Knepley 51067cd05799SMatthew G. Knepley Not Collective 51077cd05799SMatthew G. Knepley 51087cd05799SMatthew G. Knepley Input Parameters: 51097cd05799SMatthew G. Knepley . dm - The DMPlex object 51107cd05799SMatthew G. Knepley 51117cd05799SMatthew G. Knepley Output Parameter: 5112b5a892a1SMatthew G. Knepley . coneOrientations - The array of cone orientations for all points 51137cd05799SMatthew G. Knepley 51147cd05799SMatthew G. Knepley Level: developer 51157cd05799SMatthew G. Knepley 5116b5a892a1SMatthew G. Knepley Notes: 5117b5a892a1SMatthew G. Knepley The PetscSection returned by DMPlexGetConeSection() partitions coneOrientations into cone orientations of particular points as returned by DMPlexGetConeOrientation(). 5118b5a892a1SMatthew G. Knepley 5119b5a892a1SMatthew G. Knepley The meaning of coneOrientations values is detailed in DMPlexGetConeOrientation(). 5120b5a892a1SMatthew G. Knepley 5121b5a892a1SMatthew G. Knepley .seealso: DMPlexGetConeSection(), DMPlexGetConeOrientation() 51227cd05799SMatthew G. Knepley @*/ 5123a6dfd86eSKarl Rupp PetscErrorCode DMPlexGetConeOrientations(DM dm, PetscInt *coneOrientations[]) 5124a6dfd86eSKarl Rupp { 5125552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 5126552f7358SJed Brown 5127552f7358SJed Brown PetscFunctionBegin; 5128552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5129552f7358SJed Brown if (coneOrientations) *coneOrientations = mesh->coneOrientations; 5130552f7358SJed Brown PetscFunctionReturn(0); 5131552f7358SJed Brown } 5132552f7358SJed Brown 5133552f7358SJed Brown /******************************** FEM Support **********************************/ 5134552f7358SJed Brown 51359e8305c2SJed Brown /* 51369e8305c2SJed Brown Returns number of components and tensor degree for the field. For interpolated meshes, line should be a point 51379e8305c2SJed Brown representing a line in the section. 51389e8305c2SJed Brown */ 51399e8305c2SJed Brown static PetscErrorCode PetscSectionFieldGetTensorDegree_Private(PetscSection section,PetscInt field,PetscInt line,PetscBool vertexchart,PetscInt *Nc,PetscInt *k) 51409e8305c2SJed Brown { 51419e8305c2SJed Brown PetscErrorCode ierr; 51429e8305c2SJed Brown 51439e8305c2SJed Brown PetscFunctionBeginHot; 51449e8305c2SJed Brown ierr = PetscSectionGetFieldComponents(section, field, Nc);CHKERRQ(ierr); 5145a433471fSStefano Zampini if (line < 0) { 5146a433471fSStefano Zampini *k = 0; 5147a433471fSStefano Zampini *Nc = 0; 5148a433471fSStefano Zampini } else if (vertexchart) { /* If we only have a vertex chart, we must have degree k=1 */ 51499e8305c2SJed Brown *k = 1; 51509e8305c2SJed Brown } else { /* Assume the full interpolated mesh is in the chart; lines in particular */ 51519e8305c2SJed Brown /* An order k SEM disc has k-1 dofs on an edge */ 51529e8305c2SJed Brown ierr = PetscSectionGetFieldDof(section, line, field, k);CHKERRQ(ierr); 51539e8305c2SJed Brown *k = *k / *Nc + 1; 51549e8305c2SJed Brown } 51559e8305c2SJed Brown PetscFunctionReturn(0); 51569e8305c2SJed Brown } 51579e8305c2SJed Brown 5158a4355906SMatthew Knepley /*@ 5159bc1eb3faSJed Brown 5160bc1eb3faSJed Brown DMPlexSetClosurePermutationTensor - Create a permutation from the default (BFS) point ordering in the closure, to a 5161bc1eb3faSJed Brown lexicographic ordering over the tensor product cell (i.e., line, quad, hex, etc.), and set this permutation in the 51621bb6d2a8SBarry Smith section provided (or the section of the DM). 5163a4355906SMatthew Knepley 5164a4355906SMatthew Knepley Input Parameters: 5165a4355906SMatthew Knepley + dm - The DM 5166a4355906SMatthew Knepley . point - Either a cell (highest dim point) or an edge (dim 1 point), or PETSC_DETERMINE 5167a4355906SMatthew Knepley - section - The PetscSection to reorder, or NULL for the default section 5168a4355906SMatthew Knepley 5169a4355906SMatthew Knepley Note: The point is used to determine the number of dofs/field on an edge. For SEM, this is related to the polynomial 5170a4355906SMatthew Knepley degree of the basis. 5171a4355906SMatthew Knepley 5172bc1eb3faSJed Brown Example: 5173bc1eb3faSJed Brown A typical interpolated single-quad mesh might order points as 5174bc1eb3faSJed Brown .vb 5175bc1eb3faSJed Brown [c0, v1, v2, v3, v4, e5, e6, e7, e8] 5176bc1eb3faSJed Brown 5177bc1eb3faSJed Brown v4 -- e6 -- v3 5178bc1eb3faSJed Brown | | 5179bc1eb3faSJed Brown e7 c0 e8 5180bc1eb3faSJed Brown | | 5181bc1eb3faSJed Brown v1 -- e5 -- v2 5182bc1eb3faSJed Brown .ve 5183bc1eb3faSJed Brown 5184bc1eb3faSJed Brown (There is no significance to the ordering described here.) The default section for a Q3 quad might typically assign 5185bc1eb3faSJed Brown dofs in the order of points, e.g., 5186bc1eb3faSJed Brown .vb 5187bc1eb3faSJed Brown c0 -> [0,1,2,3] 5188bc1eb3faSJed Brown v1 -> [4] 5189bc1eb3faSJed Brown ... 5190bc1eb3faSJed Brown e5 -> [8, 9] 5191bc1eb3faSJed Brown .ve 5192bc1eb3faSJed Brown 5193bc1eb3faSJed Brown which corresponds to the dofs 5194bc1eb3faSJed Brown .vb 5195bc1eb3faSJed Brown 6 10 11 7 5196bc1eb3faSJed Brown 13 2 3 15 5197bc1eb3faSJed Brown 12 0 1 14 5198bc1eb3faSJed Brown 4 8 9 5 5199bc1eb3faSJed Brown .ve 5200bc1eb3faSJed Brown 5201bc1eb3faSJed Brown The closure in BFS ordering works through height strata (cells, edges, vertices) to produce the ordering 5202bc1eb3faSJed Brown .vb 5203bc1eb3faSJed Brown 0 1 2 3 8 9 14 15 11 10 13 12 4 5 7 6 5204bc1eb3faSJed Brown .ve 5205bc1eb3faSJed Brown 5206bc1eb3faSJed Brown After calling DMPlexSetClosurePermutationTensor(), the closure will be ordered lexicographically, 5207bc1eb3faSJed Brown .vb 5208bc1eb3faSJed Brown 4 8 9 5 12 0 1 14 13 2 3 15 6 10 11 7 5209bc1eb3faSJed Brown .ve 5210bc1eb3faSJed Brown 5211a4355906SMatthew Knepley Level: developer 5212a4355906SMatthew Knepley 52139df75925SJed Brown .seealso: DMGetLocalSection(), PetscSectionSetClosurePermutation(), DMSetGlobalSection() 5214a4355906SMatthew Knepley @*/ 5215bc1eb3faSJed Brown PetscErrorCode DMPlexSetClosurePermutationTensor(DM dm, PetscInt point, PetscSection section) 52163194fc30SMatthew G. Knepley { 52177391a63aSMatthew G. Knepley DMLabel label; 5218bb197d40SJed Brown PetscInt dim, depth = -1, eStart = -1, Nf; 52199e8305c2SJed Brown PetscBool vertexchart; 52203194fc30SMatthew G. Knepley PetscErrorCode ierr; 52213194fc30SMatthew G. Knepley 52223194fc30SMatthew G. Knepley PetscFunctionBegin; 52233194fc30SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 5224a433471fSStefano Zampini if (dim < 1) PetscFunctionReturn(0); 5225a433471fSStefano Zampini if (point < 0) { 5226a433471fSStefano Zampini PetscInt sStart,sEnd; 5227a433471fSStefano Zampini 5228a433471fSStefano Zampini ierr = DMPlexGetDepthStratum(dm, 1, &sStart, &sEnd);CHKERRQ(ierr); 5229a433471fSStefano Zampini point = sEnd-sStart ? sStart : point; 5230a433471fSStefano Zampini } 52317391a63aSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 5232a433471fSStefano Zampini if (point >= 0) { ierr = DMLabelGetValue(label, point, &depth);CHKERRQ(ierr); } 5233a433471fSStefano Zampini if (!section) {ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr);} 52347391a63aSMatthew G. Knepley if (depth == 1) {eStart = point;} 52357391a63aSMatthew G. Knepley else if (depth == dim) { 52367391a63aSMatthew G. Knepley const PetscInt *cone; 52377391a63aSMatthew G. Knepley 52387391a63aSMatthew G. Knepley ierr = DMPlexGetCone(dm, point, &cone);CHKERRQ(ierr); 5239d4e6627bSStefano Zampini if (dim == 2) eStart = cone[0]; 5240d4e6627bSStefano Zampini else if (dim == 3) { 5241d4e6627bSStefano Zampini const PetscInt *cone2; 5242d4e6627bSStefano Zampini ierr = DMPlexGetCone(dm, cone[0], &cone2);CHKERRQ(ierr); 5243d4e6627bSStefano Zampini eStart = cone2[0]; 5244d4e6627bSStefano Zampini } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Point %D of depth %D cannot be used to bootstrap spectral ordering for dim %D", point, depth, dim); 5245a433471fSStefano Zampini } else if (depth >= 0) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Point %D of depth %D cannot be used to bootstrap spectral ordering for dim %D", point, depth, dim); 52469e8305c2SJed Brown { /* Determine whether the chart covers all points or just vertices. */ 52479e8305c2SJed Brown PetscInt pStart,pEnd,cStart,cEnd; 52489e8305c2SJed Brown ierr = DMPlexGetDepthStratum(dm,0,&pStart,&pEnd);CHKERRQ(ierr); 52499e8305c2SJed Brown ierr = PetscSectionGetChart(section,&cStart,&cEnd);CHKERRQ(ierr); 52509e8305c2SJed Brown if (pStart == cStart && pEnd == cEnd) vertexchart = PETSC_TRUE; /* Just vertices */ 52519e8305c2SJed Brown else vertexchart = PETSC_FALSE; /* Assume all interpolated points are in chart */ 52529e8305c2SJed Brown } 52533194fc30SMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &Nf);CHKERRQ(ierr); 5254bb197d40SJed Brown for (PetscInt d=1; d<=dim; d++) { 5255bb197d40SJed Brown PetscInt k, f, Nc, c, i, j, size = 0, offset = 0, foffset = 0; 5256bb197d40SJed Brown PetscInt *perm; 5257bb197d40SJed Brown 52583194fc30SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 52599e8305c2SJed Brown ierr = PetscSectionFieldGetTensorDegree_Private(section,f,eStart,vertexchart,&Nc,&k);CHKERRQ(ierr); 5260bb197d40SJed Brown size += PetscPowInt(k+1, d)*Nc; 52613194fc30SMatthew G. Knepley } 52623194fc30SMatthew G. Knepley ierr = PetscMalloc1(size, &perm);CHKERRQ(ierr); 52633194fc30SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 5264bb197d40SJed Brown switch (d) { 5265babf31e0SJed Brown case 1: 52669e8305c2SJed Brown ierr = PetscSectionFieldGetTensorDegree_Private(section,f,eStart,vertexchart,&Nc,&k);CHKERRQ(ierr); 5267babf31e0SJed Brown /* 5268babf31e0SJed Brown Original ordering is [ edge of length k-1; vtx0; vtx1 ] 5269babf31e0SJed Brown We want [ vtx0; edge of length k-1; vtx1 ] 5270babf31e0SJed Brown */ 5271babf31e0SJed Brown for (c=0; c<Nc; c++,offset++) perm[offset] = (k-1)*Nc + c + foffset; 5272babf31e0SJed Brown for (i=0; i<k-1; i++) for (c=0; c<Nc; c++,offset++) perm[offset] = i*Nc + c + foffset; 5273babf31e0SJed Brown for (c=0; c<Nc; c++,offset++) perm[offset] = k*Nc + c + foffset; 5274babf31e0SJed Brown foffset = offset; 5275babf31e0SJed Brown break; 527689eabcffSMatthew G. Knepley case 2: 52773194fc30SMatthew 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} */ 52789e8305c2SJed Brown ierr = PetscSectionFieldGetTensorDegree_Private(section,f,eStart,vertexchart,&Nc,&k);CHKERRQ(ierr); 52793194fc30SMatthew G. Knepley /* The SEM order is 52803194fc30SMatthew G. Knepley 52813194fc30SMatthew G. Knepley v_lb, {e_b}, v_rb, 528289eabcffSMatthew G. Knepley e^{(k-1)-i}_l, {f^{i*(k-1)}}, e^i_r, 52833194fc30SMatthew G. Knepley v_lt, reverse {e_t}, v_rt 52843194fc30SMatthew G. Knepley */ 52853194fc30SMatthew G. Knepley { 52863194fc30SMatthew G. Knepley const PetscInt of = 0; 52873194fc30SMatthew G. Knepley const PetscInt oeb = of + PetscSqr(k-1); 52883194fc30SMatthew G. Knepley const PetscInt oer = oeb + (k-1); 52893194fc30SMatthew G. Knepley const PetscInt oet = oer + (k-1); 52903194fc30SMatthew G. Knepley const PetscInt oel = oet + (k-1); 52913194fc30SMatthew G. Knepley const PetscInt ovlb = oel + (k-1); 52923194fc30SMatthew G. Knepley const PetscInt ovrb = ovlb + 1; 52933194fc30SMatthew G. Knepley const PetscInt ovrt = ovrb + 1; 52943194fc30SMatthew G. Knepley const PetscInt ovlt = ovrt + 1; 52953194fc30SMatthew G. Knepley PetscInt o; 52963194fc30SMatthew G. Knepley 52973194fc30SMatthew G. Knepley /* bottom */ 52983194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovlb*Nc + c + foffset; 52993194fc30SMatthew G. Knepley for (o = oeb; o < oer; ++o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 53003194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovrb*Nc + c + foffset; 53013194fc30SMatthew G. Knepley /* middle */ 53023194fc30SMatthew G. Knepley for (i = 0; i < k-1; ++i) { 53033194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oel+(k-2)-i)*Nc + c + foffset; 53043194fc30SMatthew 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; 53053194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oer+i)*Nc + c + foffset; 53063194fc30SMatthew G. Knepley } 53073194fc30SMatthew G. Knepley /* top */ 53083194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovlt*Nc + c + foffset; 53093194fc30SMatthew G. Knepley for (o = oel-1; o >= oet; --o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 53103194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovrt*Nc + c + foffset; 53113194fc30SMatthew G. Knepley foffset = offset; 53123194fc30SMatthew G. Knepley } 531389eabcffSMatthew G. Knepley break; 531489eabcffSMatthew G. Knepley case 3: 531589eabcffSMatthew G. Knepley /* The original hex closure is 531689eabcffSMatthew G. Knepley 531789eabcffSMatthew G. Knepley {c, 531889eabcffSMatthew G. Knepley f_b, f_t, f_f, f_b, f_r, f_l, 531989eabcffSMatthew 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, 532089eabcffSMatthew G. Knepley v_blf, v_blb, v_brb, v_brf, v_tlf, v_trf, v_trb, v_tlb} 532189eabcffSMatthew G. Knepley */ 53229e8305c2SJed Brown ierr = PetscSectionFieldGetTensorDegree_Private(section,f,eStart,vertexchart,&Nc,&k);CHKERRQ(ierr); 532389eabcffSMatthew G. Knepley /* The SEM order is 532489eabcffSMatthew G. Knepley Bottom Slice 532589eabcffSMatthew G. Knepley v_blf, {e^{(k-1)-n}_bf}, v_brf, 532689eabcffSMatthew G. Knepley e^{i}_bl, f^{n*(k-1)+(k-1)-i}_b, e^{(k-1)-i}_br, 532789eabcffSMatthew G. Knepley v_blb, {e_bb}, v_brb, 532889eabcffSMatthew G. Knepley 532989eabcffSMatthew G. Knepley Middle Slice (j) 533089eabcffSMatthew G. Knepley {e^{(k-1)-j}_lf}, {f^{j*(k-1)+n}_f}, e^j_rf, 533189eabcffSMatthew G. Knepley f^{i*(k-1)+j}_l, {c^{(j*(k-1) + i)*(k-1)+n}_t}, f^{j*(k-1)+i}_r, 533289eabcffSMatthew G. Knepley e^j_lb, {f^{j*(k-1)+(k-1)-n}_b}, e^{(k-1)-j}_rb, 533389eabcffSMatthew G. Knepley 533489eabcffSMatthew G. Knepley Top Slice 533589eabcffSMatthew G. Knepley v_tlf, {e_tf}, v_trf, 533689eabcffSMatthew G. Knepley e^{(k-1)-i}_tl, {f^{i*(k-1)}_t}, e^{i}_tr, 533789eabcffSMatthew G. Knepley v_tlb, {e^{(k-1)-n}_tb}, v_trb, 533889eabcffSMatthew G. Knepley */ 533989eabcffSMatthew G. Knepley { 534089eabcffSMatthew G. Knepley const PetscInt oc = 0; 534189eabcffSMatthew G. Knepley const PetscInt ofb = oc + PetscSqr(k-1)*(k-1); 534289eabcffSMatthew G. Knepley const PetscInt oft = ofb + PetscSqr(k-1); 534389eabcffSMatthew G. Knepley const PetscInt off = oft + PetscSqr(k-1); 534489eabcffSMatthew G. Knepley const PetscInt ofk = off + PetscSqr(k-1); 534589eabcffSMatthew G. Knepley const PetscInt ofr = ofk + PetscSqr(k-1); 534689eabcffSMatthew G. Knepley const PetscInt ofl = ofr + PetscSqr(k-1); 534789eabcffSMatthew G. Knepley const PetscInt oebl = ofl + PetscSqr(k-1); 534889eabcffSMatthew G. Knepley const PetscInt oebb = oebl + (k-1); 534989eabcffSMatthew G. Knepley const PetscInt oebr = oebb + (k-1); 535089eabcffSMatthew G. Knepley const PetscInt oebf = oebr + (k-1); 535189eabcffSMatthew G. Knepley const PetscInt oetf = oebf + (k-1); 535289eabcffSMatthew G. Knepley const PetscInt oetr = oetf + (k-1); 535389eabcffSMatthew G. Knepley const PetscInt oetb = oetr + (k-1); 535489eabcffSMatthew G. Knepley const PetscInt oetl = oetb + (k-1); 535589eabcffSMatthew G. Knepley const PetscInt oerf = oetl + (k-1); 535689eabcffSMatthew G. Knepley const PetscInt oelf = oerf + (k-1); 535789eabcffSMatthew G. Knepley const PetscInt oelb = oelf + (k-1); 535889eabcffSMatthew G. Knepley const PetscInt oerb = oelb + (k-1); 535989eabcffSMatthew G. Knepley const PetscInt ovblf = oerb + (k-1); 536089eabcffSMatthew G. Knepley const PetscInt ovblb = ovblf + 1; 536189eabcffSMatthew G. Knepley const PetscInt ovbrb = ovblb + 1; 536289eabcffSMatthew G. Knepley const PetscInt ovbrf = ovbrb + 1; 536389eabcffSMatthew G. Knepley const PetscInt ovtlf = ovbrf + 1; 536489eabcffSMatthew G. Knepley const PetscInt ovtrf = ovtlf + 1; 536589eabcffSMatthew G. Knepley const PetscInt ovtrb = ovtrf + 1; 536689eabcffSMatthew G. Knepley const PetscInt ovtlb = ovtrb + 1; 536789eabcffSMatthew G. Knepley PetscInt o, n; 536889eabcffSMatthew G. Knepley 536989eabcffSMatthew G. Knepley /* Bottom Slice */ 537089eabcffSMatthew G. Knepley /* bottom */ 537189eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovblf*Nc + c + foffset; 537289eabcffSMatthew G. Knepley for (o = oetf-1; o >= oebf; --o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 537389eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovbrf*Nc + c + foffset; 537489eabcffSMatthew G. Knepley /* middle */ 537589eabcffSMatthew G. Knepley for (i = 0; i < k-1; ++i) { 537689eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oebl+i)*Nc + c + foffset; 5377316b7f87SMax 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;} 537889eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oebr+(k-2)-i)*Nc + c + foffset; 53793194fc30SMatthew G. Knepley } 538089eabcffSMatthew G. Knepley /* top */ 538189eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovblb*Nc + c + foffset; 538289eabcffSMatthew G. Knepley for (o = oebb; o < oebr; ++o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 538389eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovbrb*Nc + c + foffset; 538489eabcffSMatthew G. Knepley 538589eabcffSMatthew G. Knepley /* Middle Slice */ 538689eabcffSMatthew G. Knepley for (j = 0; j < k-1; ++j) { 538789eabcffSMatthew G. Knepley /* bottom */ 538889eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oelf+(k-2)-j)*Nc + c + foffset; 538989eabcffSMatthew 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; 539089eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oerf+j)*Nc + c + foffset; 539189eabcffSMatthew G. Knepley /* middle */ 539289eabcffSMatthew G. Knepley for (i = 0; i < k-1; ++i) { 539389eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (ofl+i*(k-1)+j)*Nc + c + foffset; 539489eabcffSMatthew 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; 539589eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (ofr+j*(k-1)+i)*Nc + c + foffset; 539689eabcffSMatthew G. Knepley } 539789eabcffSMatthew G. Knepley /* top */ 539889eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oelb+j)*Nc + c + foffset; 539989eabcffSMatthew 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; 540089eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oerb+(k-2)-j)*Nc + c + foffset; 540189eabcffSMatthew G. Knepley } 540289eabcffSMatthew G. Knepley 540389eabcffSMatthew G. Knepley /* Top Slice */ 540489eabcffSMatthew G. Knepley /* bottom */ 540589eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovtlf*Nc + c + foffset; 540689eabcffSMatthew G. Knepley for (o = oetf; o < oetr; ++o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 540789eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovtrf*Nc + c + foffset; 540889eabcffSMatthew G. Knepley /* middle */ 540989eabcffSMatthew G. Knepley for (i = 0; i < k-1; ++i) { 541089eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oetl+(k-2)-i)*Nc + c + foffset; 541189eabcffSMatthew 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; 541289eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oetr+i)*Nc + c + foffset; 541389eabcffSMatthew G. Knepley } 541489eabcffSMatthew G. Knepley /* top */ 541589eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovtlb*Nc + c + foffset; 541689eabcffSMatthew G. Knepley for (o = oetl-1; o >= oetb; --o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 541789eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovtrb*Nc + c + foffset; 541889eabcffSMatthew G. Knepley 541989eabcffSMatthew G. Knepley foffset = offset; 542089eabcffSMatthew G. Knepley } 542189eabcffSMatthew G. Knepley break; 5422bb197d40SJed Brown default: SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "No spectral ordering for dimension %D", d); 542389eabcffSMatthew G. Knepley } 542489eabcffSMatthew G. Knepley } 542589eabcffSMatthew G. Knepley if (offset != size) SETERRQ2(PetscObjectComm((PetscObject) dm), PETSC_ERR_PLIB, "Number of permutation entries %D != %D", offset, size); 54263194fc30SMatthew G. Knepley /* Check permutation */ 54273194fc30SMatthew G. Knepley { 54283194fc30SMatthew G. Knepley PetscInt *check; 54293194fc30SMatthew G. Knepley 54303194fc30SMatthew G. Knepley ierr = PetscMalloc1(size, &check);CHKERRQ(ierr); 54313194fc30SMatthew G. Knepley for (i = 0; i < size; ++i) {check[i] = -1; if (perm[i] < 0 || perm[i] >= size) SETERRQ2(PetscObjectComm((PetscObject) dm), PETSC_ERR_PLIB, "Invalid permutation index p[%D] = %D", i, perm[i]);} 54323194fc30SMatthew G. Knepley for (i = 0; i < size; ++i) check[perm[i]] = i; 54333194fc30SMatthew G. Knepley for (i = 0; i < size; ++i) {if (check[i] < 0) SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_PLIB, "Missing permutation index %D", i);} 54343194fc30SMatthew G. Knepley ierr = PetscFree(check);CHKERRQ(ierr); 54353194fc30SMatthew G. Knepley } 5436bb197d40SJed Brown ierr = PetscSectionSetClosurePermutation_Internal(section, (PetscObject) dm, d, size, PETSC_OWN_POINTER, perm);CHKERRQ(ierr); 5437bb197d40SJed Brown } 54383194fc30SMatthew G. Knepley PetscFunctionReturn(0); 54393194fc30SMatthew G. Knepley } 54403194fc30SMatthew G. Knepley 5441e071409bSToby Isaac PetscErrorCode DMPlexGetPointDualSpaceFEM(DM dm, PetscInt point, PetscInt field, PetscDualSpace *dspace) 5442e071409bSToby Isaac { 5443e071409bSToby Isaac PetscDS prob; 5444e071409bSToby Isaac PetscInt depth, Nf, h; 5445e071409bSToby Isaac DMLabel label; 5446e071409bSToby Isaac PetscErrorCode ierr; 5447e071409bSToby Isaac 5448e071409bSToby Isaac PetscFunctionBeginHot; 5449e5e52638SMatthew G. Knepley ierr = DMGetDS(dm, &prob);CHKERRQ(ierr); 5450e071409bSToby Isaac Nf = prob->Nf; 5451e071409bSToby Isaac label = dm->depthLabel; 5452e071409bSToby Isaac *dspace = NULL; 5453e071409bSToby Isaac if (field < Nf) { 5454e071409bSToby Isaac PetscObject disc = prob->disc[field]; 5455e071409bSToby Isaac 5456e071409bSToby Isaac if (disc->classid == PETSCFE_CLASSID) { 5457e071409bSToby Isaac PetscDualSpace dsp; 5458e071409bSToby Isaac 5459e071409bSToby Isaac ierr = PetscFEGetDualSpace((PetscFE)disc,&dsp);CHKERRQ(ierr); 5460e071409bSToby Isaac ierr = DMLabelGetNumValues(label,&depth);CHKERRQ(ierr); 5461e071409bSToby Isaac ierr = DMLabelGetValue(label,point,&h);CHKERRQ(ierr); 5462e071409bSToby Isaac h = depth - 1 - h; 5463e071409bSToby Isaac if (h) { 5464e071409bSToby Isaac ierr = PetscDualSpaceGetHeightSubspace(dsp,h,dspace);CHKERRQ(ierr); 5465e071409bSToby Isaac } else { 5466e071409bSToby Isaac *dspace = dsp; 5467e071409bSToby Isaac } 5468e071409bSToby Isaac } 5469e071409bSToby Isaac } 5470e071409bSToby Isaac PetscFunctionReturn(0); 5471e071409bSToby Isaac } 5472e071409bSToby Isaac 54731a271a75SMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode DMPlexVecGetClosure_Depth1_Static(DM dm, PetscSection section, Vec v, PetscInt point, PetscInt *csize, PetscScalar *values[]) 5474a6dfd86eSKarl Rupp { 5475552f7358SJed Brown PetscScalar *array, *vArray; 5476d9917b9dSMatthew G. Knepley const PetscInt *cone, *coneO; 54771a271a75SMatthew G. Knepley PetscInt pStart, pEnd, p, numPoints, size = 0, offset = 0; 5478552f7358SJed Brown PetscErrorCode ierr; 5479552f7358SJed Brown 54801b406b76SMatthew G. Knepley PetscFunctionBeginHot; 54812a3aaacfSMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 54825a1bb5cfSMatthew G. Knepley ierr = DMPlexGetConeSize(dm, point, &numPoints);CHKERRQ(ierr); 54835a1bb5cfSMatthew G. Knepley ierr = DMPlexGetCone(dm, point, &cone);CHKERRQ(ierr); 54845a1bb5cfSMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, point, &coneO);CHKERRQ(ierr); 54853f7cbbe7SMatthew G. Knepley if (!values || !*values) { 54869df71ca4SMatthew G. Knepley if ((point >= pStart) && (point < pEnd)) { 54879df71ca4SMatthew G. Knepley PetscInt dof; 5488d9917b9dSMatthew G. Knepley 54899df71ca4SMatthew G. Knepley ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 54909df71ca4SMatthew G. Knepley size += dof; 54919df71ca4SMatthew G. Knepley } 54929df71ca4SMatthew G. Knepley for (p = 0; p < numPoints; ++p) { 54939df71ca4SMatthew G. Knepley const PetscInt cp = cone[p]; 54942a3aaacfSMatthew G. Knepley PetscInt dof; 54955a1bb5cfSMatthew G. Knepley 54965a1bb5cfSMatthew G. Knepley if ((cp < pStart) || (cp >= pEnd)) continue; 54972a3aaacfSMatthew G. Knepley ierr = PetscSectionGetDof(section, cp, &dof);CHKERRQ(ierr); 54985a1bb5cfSMatthew G. Knepley size += dof; 54995a1bb5cfSMatthew G. Knepley } 55003f7cbbe7SMatthew G. Knepley if (!values) { 55013f7cbbe7SMatthew G. Knepley if (csize) *csize = size; 55023f7cbbe7SMatthew G. Knepley PetscFunctionReturn(0); 55033f7cbbe7SMatthew G. Knepley } 550469291d52SBarry Smith ierr = DMGetWorkArray(dm, size, MPIU_SCALAR, &array);CHKERRQ(ierr); 5505982e9ed1SMatthew G. Knepley } else { 5506982e9ed1SMatthew G. Knepley array = *values; 5507982e9ed1SMatthew G. Knepley } 55089df71ca4SMatthew G. Knepley size = 0; 55095a1bb5cfSMatthew G. Knepley ierr = VecGetArray(v, &vArray);CHKERRQ(ierr); 55109df71ca4SMatthew G. Knepley if ((point >= pStart) && (point < pEnd)) { 55119df71ca4SMatthew G. Knepley PetscInt dof, off, d; 55129df71ca4SMatthew G. Knepley PetscScalar *varr; 5513d9917b9dSMatthew G. Knepley 55149df71ca4SMatthew G. Knepley ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 55159df71ca4SMatthew G. Knepley ierr = PetscSectionGetOffset(section, point, &off);CHKERRQ(ierr); 55169df71ca4SMatthew G. Knepley varr = &vArray[off]; 55171a271a75SMatthew G. Knepley for (d = 0; d < dof; ++d, ++offset) { 55181a271a75SMatthew G. Knepley array[offset] = varr[d]; 55199df71ca4SMatthew G. Knepley } 55209df71ca4SMatthew G. Knepley size += dof; 55219df71ca4SMatthew G. Knepley } 55229df71ca4SMatthew G. Knepley for (p = 0; p < numPoints; ++p) { 55239df71ca4SMatthew G. Knepley const PetscInt cp = cone[p]; 55249df71ca4SMatthew G. Knepley PetscInt o = coneO[p]; 55255a1bb5cfSMatthew G. Knepley PetscInt dof, off, d; 55265a1bb5cfSMatthew G. Knepley PetscScalar *varr; 55275a1bb5cfSMatthew G. Knepley 552852ed52e8SMatthew G. Knepley if ((cp < pStart) || (cp >= pEnd)) continue; 55295a1bb5cfSMatthew G. Knepley ierr = PetscSectionGetDof(section, cp, &dof);CHKERRQ(ierr); 55305a1bb5cfSMatthew G. Knepley ierr = PetscSectionGetOffset(section, cp, &off);CHKERRQ(ierr); 55315a1bb5cfSMatthew G. Knepley varr = &vArray[off]; 55325a1bb5cfSMatthew G. Knepley if (o >= 0) { 55331a271a75SMatthew G. Knepley for (d = 0; d < dof; ++d, ++offset) { 55341a271a75SMatthew G. Knepley array[offset] = varr[d]; 55355a1bb5cfSMatthew G. Knepley } 55365a1bb5cfSMatthew G. Knepley } else { 55371a271a75SMatthew G. Knepley for (d = dof-1; d >= 0; --d, ++offset) { 55381a271a75SMatthew G. Knepley array[offset] = varr[d]; 55395a1bb5cfSMatthew G. Knepley } 55405a1bb5cfSMatthew G. Knepley } 55419df71ca4SMatthew G. Knepley size += dof; 55425a1bb5cfSMatthew G. Knepley } 55435a1bb5cfSMatthew G. Knepley ierr = VecRestoreArray(v, &vArray);CHKERRQ(ierr); 55449df71ca4SMatthew G. Knepley if (!*values) { 55455a1bb5cfSMatthew G. Knepley if (csize) *csize = size; 55465a1bb5cfSMatthew G. Knepley *values = array; 55479df71ca4SMatthew G. Knepley } else { 55488ccfff9cSToby Isaac if (size > *csize) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Size of input array %D < actual size %D", *csize, size); 55498c312ff3SMatthew G. Knepley *csize = size; 55509df71ca4SMatthew G. Knepley } 55515a1bb5cfSMatthew G. Knepley PetscFunctionReturn(0); 55525a1bb5cfSMatthew G. Knepley } 5553d9917b9dSMatthew G. Knepley 555427f02ce8SMatthew G. Knepley /* Compress out points not in the section */ 555527f02ce8SMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode CompressPoints_Private(PetscSection section, PetscInt *numPoints, PetscInt points[]) 555627f02ce8SMatthew G. Knepley { 555727f02ce8SMatthew G. Knepley const PetscInt np = *numPoints; 555827f02ce8SMatthew G. Knepley PetscInt pStart, pEnd, p, q; 555927f02ce8SMatthew G. Knepley PetscErrorCode ierr; 556027f02ce8SMatthew G. Knepley 556127f02ce8SMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 556227f02ce8SMatthew G. Knepley for (p = 0, q = 0; p < np; ++p) { 556327f02ce8SMatthew G. Knepley const PetscInt r = points[p*2]; 556427f02ce8SMatthew G. Knepley if ((r >= pStart) && (r < pEnd)) { 556527f02ce8SMatthew G. Knepley points[q*2] = r; 556627f02ce8SMatthew G. Knepley points[q*2+1] = points[p*2+1]; 556727f02ce8SMatthew G. Knepley ++q; 556827f02ce8SMatthew G. Knepley } 556927f02ce8SMatthew G. Knepley } 557027f02ce8SMatthew G. Knepley *numPoints = q; 557127f02ce8SMatthew G. Knepley return 0; 557227f02ce8SMatthew G. Knepley } 557327f02ce8SMatthew G. Knepley 557497529cf3SJed Brown /* Compressed closure does not apply closure permutation */ 55751dc59d61SMatthew G. Knepley PetscErrorCode DMPlexGetCompressedClosure(DM dm, PetscSection section, PetscInt point, PetscInt *numPoints, PetscInt **points, PetscSection *clSec, IS *clPoints, const PetscInt **clp) 5576923c78e0SToby Isaac { 557727f02ce8SMatthew G. Knepley const PetscInt *cla = NULL; 5578923c78e0SToby Isaac PetscInt np, *pts = NULL; 5579923c78e0SToby Isaac PetscErrorCode ierr; 5580923c78e0SToby Isaac 5581923c78e0SToby Isaac PetscFunctionBeginHot; 5582923c78e0SToby Isaac ierr = PetscSectionGetClosureIndex(section, (PetscObject) dm, clSec, clPoints);CHKERRQ(ierr); 558327f02ce8SMatthew G. Knepley if (*clPoints) { 5584923c78e0SToby Isaac PetscInt dof, off; 5585923c78e0SToby Isaac 5586923c78e0SToby Isaac ierr = PetscSectionGetDof(*clSec, point, &dof);CHKERRQ(ierr); 5587923c78e0SToby Isaac ierr = PetscSectionGetOffset(*clSec, point, &off);CHKERRQ(ierr); 5588923c78e0SToby Isaac ierr = ISGetIndices(*clPoints, &cla);CHKERRQ(ierr); 5589923c78e0SToby Isaac np = dof/2; 5590923c78e0SToby Isaac pts = (PetscInt *) &cla[off]; 559127f02ce8SMatthew G. Knepley } else { 559227f02ce8SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, point, PETSC_TRUE, &np, &pts);CHKERRQ(ierr); 559327f02ce8SMatthew G. Knepley ierr = CompressPoints_Private(section, &np, pts);CHKERRQ(ierr); 5594923c78e0SToby Isaac } 5595923c78e0SToby Isaac *numPoints = np; 5596923c78e0SToby Isaac *points = pts; 5597923c78e0SToby Isaac *clp = cla; 5598923c78e0SToby Isaac PetscFunctionReturn(0); 5599923c78e0SToby Isaac } 5600923c78e0SToby Isaac 56011dc59d61SMatthew G. Knepley PetscErrorCode DMPlexRestoreCompressedClosure(DM dm, PetscSection section, PetscInt point, PetscInt *numPoints, PetscInt **points, PetscSection *clSec, IS *clPoints, const PetscInt **clp) 5602923c78e0SToby Isaac { 5603923c78e0SToby Isaac PetscErrorCode ierr; 5604923c78e0SToby Isaac 5605923c78e0SToby Isaac PetscFunctionBeginHot; 5606923c78e0SToby Isaac if (!*clPoints) { 5607923c78e0SToby Isaac ierr = DMPlexRestoreTransitiveClosure(dm, point, PETSC_TRUE, numPoints, points);CHKERRQ(ierr); 5608923c78e0SToby Isaac } else { 5609923c78e0SToby Isaac ierr = ISRestoreIndices(*clPoints, clp);CHKERRQ(ierr); 5610923c78e0SToby Isaac } 5611923c78e0SToby Isaac *numPoints = 0; 5612923c78e0SToby Isaac *points = NULL; 5613923c78e0SToby Isaac *clSec = NULL; 5614923c78e0SToby Isaac *clPoints = NULL; 5615923c78e0SToby Isaac *clp = NULL; 5616923c78e0SToby Isaac PetscFunctionReturn(0); 5617923c78e0SToby Isaac } 5618923c78e0SToby Isaac 561997e99dd9SToby Isaac PETSC_STATIC_INLINE PetscErrorCode DMPlexVecGetClosure_Static(DM dm, PetscSection section, PetscInt numPoints, const PetscInt points[], const PetscInt clperm[], const PetscScalar vArray[], PetscInt *size, PetscScalar array[]) 56201a271a75SMatthew G. Knepley { 56211a271a75SMatthew G. Knepley PetscInt offset = 0, p; 562297e99dd9SToby Isaac const PetscInt **perms = NULL; 562397e99dd9SToby Isaac const PetscScalar **flips = NULL; 56241a271a75SMatthew G. Knepley PetscErrorCode ierr; 56251a271a75SMatthew G. Knepley 56261a271a75SMatthew G. Knepley PetscFunctionBeginHot; 5627fe02ba77SJed Brown *size = 0; 562897e99dd9SToby Isaac ierr = PetscSectionGetPointSyms(section,numPoints,points,&perms,&flips);CHKERRQ(ierr); 562997e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 563097e99dd9SToby Isaac const PetscInt point = points[2*p]; 563197e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 563297e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 56331a271a75SMatthew G. Knepley PetscInt dof, off, d; 56341a271a75SMatthew G. Knepley const PetscScalar *varr; 56351a271a75SMatthew G. Knepley 56361a271a75SMatthew G. Knepley ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 56371a271a75SMatthew G. Knepley ierr = PetscSectionGetOffset(section, point, &off);CHKERRQ(ierr); 56381a271a75SMatthew G. Knepley varr = &vArray[off]; 563997e99dd9SToby Isaac if (clperm) { 564097e99dd9SToby Isaac if (perm) { 564197e99dd9SToby Isaac for (d = 0; d < dof; d++) array[clperm[offset + perm[d]]] = varr[d]; 56421a271a75SMatthew G. Knepley } else { 564397e99dd9SToby Isaac for (d = 0; d < dof; d++) array[clperm[offset + d ]] = varr[d]; 564497e99dd9SToby Isaac } 564597e99dd9SToby Isaac if (flip) { 564697e99dd9SToby Isaac for (d = 0; d < dof; d++) array[clperm[offset + d ]] *= flip[d]; 564797e99dd9SToby Isaac } 564897e99dd9SToby Isaac } else { 564997e99dd9SToby Isaac if (perm) { 565097e99dd9SToby Isaac for (d = 0; d < dof; d++) array[offset + perm[d]] = varr[d]; 565197e99dd9SToby Isaac } else { 565297e99dd9SToby Isaac for (d = 0; d < dof; d++) array[offset + d ] = varr[d]; 565397e99dd9SToby Isaac } 565497e99dd9SToby Isaac if (flip) { 565597e99dd9SToby Isaac for (d = 0; d < dof; d++) array[offset + d ] *= flip[d]; 56561a271a75SMatthew G. Knepley } 56571a271a75SMatthew G. Knepley } 565897e99dd9SToby Isaac offset += dof; 565997e99dd9SToby Isaac } 566097e99dd9SToby Isaac ierr = PetscSectionRestorePointSyms(section,numPoints,points,&perms,&flips);CHKERRQ(ierr); 56611a271a75SMatthew G. Knepley *size = offset; 56621a271a75SMatthew G. Knepley PetscFunctionReturn(0); 56631a271a75SMatthew G. Knepley } 56641a271a75SMatthew G. Knepley 566597e99dd9SToby Isaac PETSC_STATIC_INLINE PetscErrorCode DMPlexVecGetClosure_Fields_Static(DM dm, PetscSection section, PetscInt numPoints, const PetscInt points[], PetscInt numFields, const PetscInt clperm[], const PetscScalar vArray[], PetscInt *size, PetscScalar array[]) 56661a271a75SMatthew G. Knepley { 56671a271a75SMatthew G. Knepley PetscInt offset = 0, f; 56681a271a75SMatthew G. Knepley PetscErrorCode ierr; 56691a271a75SMatthew G. Knepley 56701a271a75SMatthew G. Knepley PetscFunctionBeginHot; 5671fe02ba77SJed Brown *size = 0; 56721a271a75SMatthew G. Knepley for (f = 0; f < numFields; ++f) { 567397e99dd9SToby Isaac PetscInt p; 567497e99dd9SToby Isaac const PetscInt **perms = NULL; 567597e99dd9SToby Isaac const PetscScalar **flips = NULL; 56761a271a75SMatthew G. Knepley 567797e99dd9SToby Isaac ierr = PetscSectionGetFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 567897e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 567997e99dd9SToby Isaac const PetscInt point = points[2*p]; 568097e99dd9SToby Isaac PetscInt fdof, foff, b; 56811a271a75SMatthew G. Knepley const PetscScalar *varr; 568297e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 568397e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 56841a271a75SMatthew G. Knepley 56851a271a75SMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 56861a271a75SMatthew G. Knepley ierr = PetscSectionGetFieldOffset(section, point, f, &foff);CHKERRQ(ierr); 56871a271a75SMatthew G. Knepley varr = &vArray[foff]; 568897e99dd9SToby Isaac if (clperm) { 568997e99dd9SToby Isaac if (perm) {for (b = 0; b < fdof; b++) {array[clperm[offset + perm[b]]] = varr[b];}} 569097e99dd9SToby Isaac else {for (b = 0; b < fdof; b++) {array[clperm[offset + b ]] = varr[b];}} 569197e99dd9SToby Isaac if (flip) {for (b = 0; b < fdof; b++) {array[clperm[offset + b ]] *= flip[b];}} 56921a271a75SMatthew G. Knepley } else { 569397e99dd9SToby Isaac if (perm) {for (b = 0; b < fdof; b++) {array[offset + perm[b]] = varr[b];}} 569497e99dd9SToby Isaac else {for (b = 0; b < fdof; b++) {array[offset + b ] = varr[b];}} 569597e99dd9SToby Isaac if (flip) {for (b = 0; b < fdof; b++) {array[offset + b ] *= flip[b];}} 56961a271a75SMatthew G. Knepley } 569797e99dd9SToby Isaac offset += fdof; 56981a271a75SMatthew G. Knepley } 569997e99dd9SToby Isaac ierr = PetscSectionRestoreFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 57001a271a75SMatthew G. Knepley } 57011a271a75SMatthew G. Knepley *size = offset; 57021a271a75SMatthew G. Knepley PetscFunctionReturn(0); 57031a271a75SMatthew G. Knepley } 57041a271a75SMatthew G. Knepley 5705552f7358SJed Brown /*@C 5706552f7358SJed Brown DMPlexVecGetClosure - Get an array of the values on the closure of 'point' 5707552f7358SJed Brown 5708552f7358SJed Brown Not collective 5709552f7358SJed Brown 5710552f7358SJed Brown Input Parameters: 5711552f7358SJed Brown + dm - The DM 5712552f7358SJed Brown . section - The section describing the layout in v, or NULL to use the default section 5713552f7358SJed Brown . v - The local vector 57146b867d5aSJose E. Roman - point - The point in the DM 5715552f7358SJed Brown 57166b867d5aSJose E. Roman Input/Output Parameters: 57176b867d5aSJose E. Roman + csize - The size of the input values array, or NULL; on output the number of values in the closure 57186b867d5aSJose E. Roman - values - An array to use for the values, or NULL to have it allocated automatically; 57196b867d5aSJose E. Roman if the user provided NULL, it is a borrowed array and should not be freed 572022c1ee49SMatthew G. Knepley 572122c1ee49SMatthew G. Knepley $ Note that DMPlexVecGetClosure/DMPlexVecRestoreClosure only allocates the values array if it set to NULL in the 572222c1ee49SMatthew G. Knepley $ calling function. This is because DMPlexVecGetClosure() is typically called in the inner loop of a Vec or Mat 572322c1ee49SMatthew G. Knepley $ assembly function, and a user may already have allocated storage for this operation. 572422c1ee49SMatthew G. Knepley $ 572522c1ee49SMatthew G. Knepley $ A typical use could be 572622c1ee49SMatthew G. Knepley $ 572722c1ee49SMatthew G. Knepley $ values = NULL; 572822c1ee49SMatthew G. Knepley $ ierr = DMPlexVecGetClosure(dm, NULL, v, p, &clSize, &values);CHKERRQ(ierr); 572922c1ee49SMatthew G. Knepley $ for (cl = 0; cl < clSize; ++cl) { 573022c1ee49SMatthew G. Knepley $ <Compute on closure> 573122c1ee49SMatthew G. Knepley $ } 573222c1ee49SMatthew G. Knepley $ ierr = DMPlexVecRestoreClosure(dm, NULL, v, p, &clSize, &values);CHKERRQ(ierr); 573322c1ee49SMatthew G. Knepley $ 573422c1ee49SMatthew G. Knepley $ or 573522c1ee49SMatthew G. Knepley $ 573622c1ee49SMatthew G. Knepley $ PetscMalloc1(clMaxSize, &values); 573722c1ee49SMatthew G. Knepley $ for (p = pStart; p < pEnd; ++p) { 573822c1ee49SMatthew G. Knepley $ clSize = clMaxSize; 573922c1ee49SMatthew G. Knepley $ ierr = DMPlexVecGetClosure(dm, NULL, v, p, &clSize, &values);CHKERRQ(ierr); 574022c1ee49SMatthew G. Knepley $ for (cl = 0; cl < clSize; ++cl) { 574122c1ee49SMatthew G. Knepley $ <Compute on closure> 574222c1ee49SMatthew G. Knepley $ } 574322c1ee49SMatthew G. Knepley $ } 574422c1ee49SMatthew G. Knepley $ PetscFree(values); 5745552f7358SJed Brown 5746552f7358SJed Brown Fortran Notes: 5747552f7358SJed Brown Since it returns an array, this routine is only available in Fortran 90, and you must 5748552f7358SJed Brown include petsc.h90 in your code. 5749552f7358SJed Brown 5750552f7358SJed Brown The csize argument is not present in the Fortran 90 binding since it is internal to the array. 5751552f7358SJed Brown 5752552f7358SJed Brown Level: intermediate 5753552f7358SJed Brown 5754552f7358SJed Brown .seealso DMPlexVecRestoreClosure(), DMPlexVecSetClosure(), DMPlexMatSetClosure() 5755552f7358SJed Brown @*/ 5756552f7358SJed Brown PetscErrorCode DMPlexVecGetClosure(DM dm, PetscSection section, Vec v, PetscInt point, PetscInt *csize, PetscScalar *values[]) 5757552f7358SJed Brown { 5758552f7358SJed Brown PetscSection clSection; 5759d9917b9dSMatthew G. Knepley IS clPoints; 5760552f7358SJed Brown PetscInt *points = NULL; 5761c459fbc1SJed Brown const PetscInt *clp, *perm; 5762c459fbc1SJed Brown PetscInt depth, numFields, numPoints, asize; 5763552f7358SJed Brown PetscErrorCode ierr; 5764552f7358SJed Brown 5765d9917b9dSMatthew G. Knepley PetscFunctionBeginHot; 5766552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 576792fd8e1eSJed Brown if (!section) {ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr);} 57681a271a75SMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 57691a271a75SMatthew G. Knepley PetscValidHeaderSpecific(v, VEC_CLASSID, 3); 5770552f7358SJed Brown ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 5771552f7358SJed Brown ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 5772552f7358SJed Brown if (depth == 1 && numFields < 2) { 57731a271a75SMatthew G. Knepley ierr = DMPlexVecGetClosure_Depth1_Static(dm, section, v, point, csize, values);CHKERRQ(ierr); 5774552f7358SJed Brown PetscFunctionReturn(0); 5775552f7358SJed Brown } 57761a271a75SMatthew G. Knepley /* Get points */ 5777923c78e0SToby Isaac ierr = DMPlexGetCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 5778c459fbc1SJed Brown /* Get sizes */ 5779c459fbc1SJed Brown asize = 0; 5780c459fbc1SJed Brown for (PetscInt p = 0; p < numPoints*2; p += 2) { 5781c459fbc1SJed Brown PetscInt dof; 5782552f7358SJed Brown ierr = PetscSectionGetDof(section, points[p], &dof);CHKERRQ(ierr); 57831a271a75SMatthew G. Knepley asize += dof; 5784552f7358SJed Brown } 5785c459fbc1SJed Brown if (values) { 5786c459fbc1SJed Brown const PetscScalar *vArray; 5787c459fbc1SJed Brown PetscInt size; 5788c459fbc1SJed Brown 5789c459fbc1SJed Brown if (*values) { 5790c459fbc1SJed Brown if (PetscUnlikely(*csize < asize)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Provided array size %D not sufficient to hold closure size %D", *csize, asize); 5791c459fbc1SJed Brown } else {ierr = DMGetWorkArray(dm, asize, MPIU_SCALAR, values);CHKERRQ(ierr);} 5792c459fbc1SJed Brown ierr = PetscSectionGetClosureInversePermutation_Internal(section, (PetscObject) dm, depth, asize, &perm);CHKERRQ(ierr); 57938a84db2dSMatthew G. Knepley ierr = VecGetArrayRead(v, &vArray);CHKERRQ(ierr); 57941a271a75SMatthew G. Knepley /* Get values */ 5795c459fbc1SJed Brown if (numFields > 0) {ierr = DMPlexVecGetClosure_Fields_Static(dm, section, numPoints, points, numFields, perm, vArray, &size, *values);CHKERRQ(ierr);} 5796c459fbc1SJed Brown else {ierr = DMPlexVecGetClosure_Static(dm, section, numPoints, points, perm, vArray, &size, *values);CHKERRQ(ierr);} 5797c459fbc1SJed Brown if (PetscUnlikely(asize != size)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Section size %D does not match Vec closure size %D", asize, size); 57981a271a75SMatthew G. Knepley /* Cleanup array */ 57998a84db2dSMatthew G. Knepley ierr = VecRestoreArrayRead(v, &vArray);CHKERRQ(ierr); 5800d0f6b257SMatthew G. Knepley } 5801c459fbc1SJed Brown if (csize) *csize = asize; 5802c459fbc1SJed Brown /* Cleanup points */ 5803c459fbc1SJed Brown ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 5804552f7358SJed Brown PetscFunctionReturn(0); 5805552f7358SJed Brown } 5806552f7358SJed Brown 5807e5c487bfSMatthew G. Knepley PetscErrorCode DMPlexVecGetClosureAtDepth_Internal(DM dm, PetscSection section, Vec v, PetscInt point, PetscInt depth, PetscInt *csize, PetscScalar *values[]) 5808e5c487bfSMatthew G. Knepley { 5809e5c487bfSMatthew G. Knepley DMLabel depthLabel; 5810e5c487bfSMatthew G. Knepley PetscSection clSection; 5811e5c487bfSMatthew G. Knepley IS clPoints; 5812e5c487bfSMatthew G. Knepley PetscScalar *array; 5813e5c487bfSMatthew G. Knepley const PetscScalar *vArray; 5814e5c487bfSMatthew G. Knepley PetscInt *points = NULL; 5815c459fbc1SJed Brown const PetscInt *clp, *perm = NULL; 5816c459fbc1SJed Brown PetscInt mdepth, numFields, numPoints, Np = 0, p, clsize, size; 5817e5c487bfSMatthew G. Knepley PetscErrorCode ierr; 5818e5c487bfSMatthew G. Knepley 5819e5c487bfSMatthew G. Knepley PetscFunctionBeginHot; 5820e5c487bfSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5821e5c487bfSMatthew G. Knepley if (!section) {ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr);} 5822e5c487bfSMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 5823e5c487bfSMatthew G. Knepley PetscValidHeaderSpecific(v, VEC_CLASSID, 3); 5824e5c487bfSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &mdepth);CHKERRQ(ierr); 5825e5c487bfSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &depthLabel);CHKERRQ(ierr); 5826e5c487bfSMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 5827e5c487bfSMatthew G. Knepley if (mdepth == 1 && numFields < 2) { 5828e5c487bfSMatthew G. Knepley ierr = DMPlexVecGetClosure_Depth1_Static(dm, section, v, point, csize, values);CHKERRQ(ierr); 5829e5c487bfSMatthew G. Knepley PetscFunctionReturn(0); 5830e5c487bfSMatthew G. Knepley } 5831e5c487bfSMatthew G. Knepley /* Get points */ 5832e5c487bfSMatthew G. Knepley ierr = DMPlexGetCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 5833c459fbc1SJed Brown for (clsize=0,p=0; p<Np; p++) { 5834c459fbc1SJed Brown PetscInt dof; 5835c459fbc1SJed Brown ierr = PetscSectionGetDof(section, points[2*p], &dof);CHKERRQ(ierr); 5836c459fbc1SJed Brown clsize += dof; 5837c459fbc1SJed Brown } 5838c459fbc1SJed Brown ierr = PetscSectionGetClosureInversePermutation_Internal(section, (PetscObject) dm, depth, clsize, &perm);CHKERRQ(ierr); 5839e5c487bfSMatthew G. Knepley /* Filter points */ 5840e5c487bfSMatthew G. Knepley for (p = 0; p < numPoints*2; p += 2) { 5841e5c487bfSMatthew G. Knepley PetscInt dep; 5842e5c487bfSMatthew G. Knepley 5843e5c487bfSMatthew G. Knepley ierr = DMLabelGetValue(depthLabel, points[p], &dep);CHKERRQ(ierr); 5844e5c487bfSMatthew G. Knepley if (dep != depth) continue; 5845e5c487bfSMatthew G. Knepley points[Np*2+0] = points[p]; 5846e5c487bfSMatthew G. Knepley points[Np*2+1] = points[p+1]; 5847e5c487bfSMatthew G. Knepley ++Np; 5848e5c487bfSMatthew G. Knepley } 5849e5c487bfSMatthew G. Knepley /* Get array */ 5850e5c487bfSMatthew G. Knepley if (!values || !*values) { 5851e5c487bfSMatthew G. Knepley PetscInt asize = 0, dof; 5852e5c487bfSMatthew G. Knepley 5853e5c487bfSMatthew G. Knepley for (p = 0; p < Np*2; p += 2) { 5854e5c487bfSMatthew G. Knepley ierr = PetscSectionGetDof(section, points[p], &dof);CHKERRQ(ierr); 5855e5c487bfSMatthew G. Knepley asize += dof; 5856e5c487bfSMatthew G. Knepley } 5857e5c487bfSMatthew G. Knepley if (!values) { 5858e5c487bfSMatthew G. Knepley ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 5859e5c487bfSMatthew G. Knepley if (csize) *csize = asize; 5860e5c487bfSMatthew G. Knepley PetscFunctionReturn(0); 5861e5c487bfSMatthew G. Knepley } 5862e5c487bfSMatthew G. Knepley ierr = DMGetWorkArray(dm, asize, MPIU_SCALAR, &array);CHKERRQ(ierr); 5863e5c487bfSMatthew G. Knepley } else { 5864e5c487bfSMatthew G. Knepley array = *values; 5865e5c487bfSMatthew G. Knepley } 5866e5c487bfSMatthew G. Knepley ierr = VecGetArrayRead(v, &vArray);CHKERRQ(ierr); 5867e5c487bfSMatthew G. Knepley /* Get values */ 5868e5c487bfSMatthew G. Knepley if (numFields > 0) {ierr = DMPlexVecGetClosure_Fields_Static(dm, section, Np, points, numFields, perm, vArray, &size, array);CHKERRQ(ierr);} 5869e5c487bfSMatthew G. Knepley else {ierr = DMPlexVecGetClosure_Static(dm, section, Np, points, perm, vArray, &size, array);CHKERRQ(ierr);} 5870e5c487bfSMatthew G. Knepley /* Cleanup points */ 5871e5c487bfSMatthew G. Knepley ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 5872e5c487bfSMatthew G. Knepley /* Cleanup array */ 5873e5c487bfSMatthew G. Knepley ierr = VecRestoreArrayRead(v, &vArray);CHKERRQ(ierr); 5874e5c487bfSMatthew G. Knepley if (!*values) { 5875e5c487bfSMatthew G. Knepley if (csize) *csize = size; 5876e5c487bfSMatthew G. Knepley *values = array; 5877e5c487bfSMatthew G. Knepley } else { 5878e5c487bfSMatthew G. Knepley if (size > *csize) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Size of input array %D < actual size %D", *csize, size); 5879e5c487bfSMatthew G. Knepley *csize = size; 5880e5c487bfSMatthew G. Knepley } 5881e5c487bfSMatthew G. Knepley PetscFunctionReturn(0); 5882e5c487bfSMatthew G. Knepley } 5883e5c487bfSMatthew G. Knepley 5884552f7358SJed Brown /*@C 5885552f7358SJed Brown DMPlexVecRestoreClosure - Restore the array of the values on the closure of 'point' 5886552f7358SJed Brown 5887552f7358SJed Brown Not collective 5888552f7358SJed Brown 5889552f7358SJed Brown Input Parameters: 5890552f7358SJed Brown + dm - The DM 58910298fd71SBarry Smith . section - The section describing the layout in v, or NULL to use the default section 5892552f7358SJed Brown . v - The local vector 5893eaf898f9SPatrick Sanan . point - The point in the DM 58940298fd71SBarry Smith . csize - The number of values in the closure, or NULL 5895552f7358SJed Brown - values - The array of values, which is a borrowed array and should not be freed 5896552f7358SJed Brown 589722c1ee49SMatthew 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() 589822c1ee49SMatthew G. Knepley 58993813dfbdSMatthew G Knepley Fortran Notes: 59003813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 59013813dfbdSMatthew G Knepley include petsc.h90 in your code. 59023813dfbdSMatthew G Knepley 59033813dfbdSMatthew G Knepley The csize argument is not present in the Fortran 90 binding since it is internal to the array. 59043813dfbdSMatthew G Knepley 5905552f7358SJed Brown Level: intermediate 5906552f7358SJed Brown 5907552f7358SJed Brown .seealso DMPlexVecGetClosure(), DMPlexVecSetClosure(), DMPlexMatSetClosure() 5908552f7358SJed Brown @*/ 59097c1f9639SMatthew G Knepley PetscErrorCode DMPlexVecRestoreClosure(DM dm, PetscSection section, Vec v, PetscInt point, PetscInt *csize, PetscScalar *values[]) 5910a6dfd86eSKarl Rupp { 5911552f7358SJed Brown PetscInt size = 0; 5912552f7358SJed Brown PetscErrorCode ierr; 5913552f7358SJed Brown 5914552f7358SJed Brown PetscFunctionBegin; 5915552f7358SJed Brown /* Should work without recalculating size */ 591669291d52SBarry Smith ierr = DMRestoreWorkArray(dm, size, MPIU_SCALAR, (void*) values);CHKERRQ(ierr); 5917c9fdaa05SMatthew G. Knepley *values = NULL; 5918552f7358SJed Brown PetscFunctionReturn(0); 5919552f7358SJed Brown } 5920552f7358SJed Brown 5921552f7358SJed Brown PETSC_STATIC_INLINE void add (PetscScalar *x, PetscScalar y) {*x += y;} 5922552f7358SJed Brown PETSC_STATIC_INLINE void insert(PetscScalar *x, PetscScalar y) {*x = y;} 5923552f7358SJed Brown 592497e99dd9SToby Isaac PETSC_STATIC_INLINE PetscErrorCode updatePoint_private(PetscSection section, PetscInt point, PetscInt dof, void (*fuse)(PetscScalar*, PetscScalar), PetscBool setBC, const PetscInt perm[], const PetscScalar flip[], const PetscInt clperm[], const PetscScalar values[], PetscInt offset, PetscScalar array[]) 5925552f7358SJed Brown { 5926552f7358SJed Brown PetscInt cdof; /* The number of constraints on this point */ 5927552f7358SJed Brown const PetscInt *cdofs; /* The indices of the constrained dofs on this point */ 5928552f7358SJed Brown PetscScalar *a; 5929552f7358SJed Brown PetscInt off, cind = 0, k; 5930552f7358SJed Brown PetscErrorCode ierr; 5931552f7358SJed Brown 5932552f7358SJed Brown PetscFunctionBegin; 5933552f7358SJed Brown ierr = PetscSectionGetConstraintDof(section, point, &cdof);CHKERRQ(ierr); 5934552f7358SJed Brown ierr = PetscSectionGetOffset(section, point, &off);CHKERRQ(ierr); 5935552f7358SJed Brown a = &array[off]; 5936552f7358SJed Brown if (!cdof || setBC) { 593797e99dd9SToby Isaac if (clperm) { 593897e99dd9SToby Isaac if (perm) {for (k = 0; k < dof; ++k) {fuse(&a[k], values[clperm[offset+perm[k]]] * (flip ? flip[perm[k]] : 1.));}} 593997e99dd9SToby Isaac else {for (k = 0; k < dof; ++k) {fuse(&a[k], values[clperm[offset+ k ]] * (flip ? flip[ k ] : 1.));}} 5940552f7358SJed Brown } else { 594197e99dd9SToby Isaac if (perm) {for (k = 0; k < dof; ++k) {fuse(&a[k], values[offset+perm[k]] * (flip ? flip[perm[k]] : 1.));}} 594297e99dd9SToby Isaac else {for (k = 0; k < dof; ++k) {fuse(&a[k], values[offset+ k ] * (flip ? flip[ k ] : 1.));}} 5943552f7358SJed Brown } 5944552f7358SJed Brown } else { 5945552f7358SJed Brown ierr = PetscSectionGetConstraintIndices(section, point, &cdofs);CHKERRQ(ierr); 594697e99dd9SToby Isaac if (clperm) { 594797e99dd9SToby Isaac if (perm) {for (k = 0; k < dof; ++k) { 5948552f7358SJed Brown if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 594997e99dd9SToby Isaac fuse(&a[k], values[clperm[offset+perm[k]]] * (flip ? flip[perm[k]] : 1.)); 5950552f7358SJed Brown } 5951552f7358SJed Brown } else { 5952552f7358SJed Brown for (k = 0; k < dof; ++k) { 5953552f7358SJed Brown if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 595497e99dd9SToby Isaac fuse(&a[k], values[clperm[offset+ k ]] * (flip ? flip[ k ] : 1.)); 595597e99dd9SToby Isaac } 595697e99dd9SToby Isaac } 595797e99dd9SToby Isaac } else { 595897e99dd9SToby Isaac if (perm) { 595997e99dd9SToby Isaac for (k = 0; k < dof; ++k) { 596097e99dd9SToby Isaac if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 596197e99dd9SToby Isaac fuse(&a[k], values[offset+perm[k]] * (flip ? flip[perm[k]] : 1.)); 596297e99dd9SToby Isaac } 596397e99dd9SToby Isaac } else { 596497e99dd9SToby Isaac for (k = 0; k < dof; ++k) { 596597e99dd9SToby Isaac if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 596697e99dd9SToby Isaac fuse(&a[k], values[offset+ k ] * (flip ? flip[ k ] : 1.)); 596797e99dd9SToby Isaac } 5968552f7358SJed Brown } 5969552f7358SJed Brown } 5970552f7358SJed Brown } 5971552f7358SJed Brown PetscFunctionReturn(0); 5972552f7358SJed Brown } 5973552f7358SJed Brown 597497e99dd9SToby Isaac PETSC_STATIC_INLINE PetscErrorCode updatePointBC_private(PetscSection section, PetscInt point, PetscInt dof, void (*fuse)(PetscScalar*, PetscScalar), const PetscInt perm[], const PetscScalar flip[], const PetscInt clperm[], const PetscScalar values[], PetscInt offset, PetscScalar array[]) 5975a5e93ea8SMatthew G. Knepley { 5976a5e93ea8SMatthew G. Knepley PetscInt cdof; /* The number of constraints on this point */ 5977a5e93ea8SMatthew G. Knepley const PetscInt *cdofs; /* The indices of the constrained dofs on this point */ 5978a5e93ea8SMatthew G. Knepley PetscScalar *a; 5979a5e93ea8SMatthew G. Knepley PetscInt off, cind = 0, k; 5980a5e93ea8SMatthew G. Knepley PetscErrorCode ierr; 5981a5e93ea8SMatthew G. Knepley 5982a5e93ea8SMatthew G. Knepley PetscFunctionBegin; 5983a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(section, point, &cdof);CHKERRQ(ierr); 5984a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetOffset(section, point, &off);CHKERRQ(ierr); 5985a5e93ea8SMatthew G. Knepley a = &array[off]; 5986a5e93ea8SMatthew G. Knepley if (cdof) { 5987a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetConstraintIndices(section, point, &cdofs);CHKERRQ(ierr); 598897e99dd9SToby Isaac if (clperm) { 598997e99dd9SToby Isaac if (perm) { 5990a5e93ea8SMatthew G. Knepley for (k = 0; k < dof; ++k) { 5991a5e93ea8SMatthew G. Knepley if ((cind < cdof) && (k == cdofs[cind])) { 599297e99dd9SToby Isaac fuse(&a[k], values[clperm[offset+perm[k]]] * (flip ? flip[perm[k]] : 1.)); 599397e99dd9SToby Isaac cind++; 5994a5e93ea8SMatthew G. Knepley } 5995a5e93ea8SMatthew G. Knepley } 5996a5e93ea8SMatthew G. Knepley } else { 5997a5e93ea8SMatthew G. Knepley for (k = 0; k < dof; ++k) { 5998a5e93ea8SMatthew G. Knepley if ((cind < cdof) && (k == cdofs[cind])) { 599997e99dd9SToby Isaac fuse(&a[k], values[clperm[offset+ k ]] * (flip ? flip[ k ] : 1.)); 600097e99dd9SToby Isaac cind++; 600197e99dd9SToby Isaac } 600297e99dd9SToby Isaac } 600397e99dd9SToby Isaac } 600497e99dd9SToby Isaac } else { 600597e99dd9SToby Isaac if (perm) { 600697e99dd9SToby Isaac for (k = 0; k < dof; ++k) { 600797e99dd9SToby Isaac if ((cind < cdof) && (k == cdofs[cind])) { 600897e99dd9SToby Isaac fuse(&a[k], values[offset+perm[k]] * (flip ? flip[perm[k]] : 1.)); 600997e99dd9SToby Isaac cind++; 601097e99dd9SToby Isaac } 601197e99dd9SToby Isaac } 601297e99dd9SToby Isaac } else { 601397e99dd9SToby Isaac for (k = 0; k < dof; ++k) { 601497e99dd9SToby Isaac if ((cind < cdof) && (k == cdofs[cind])) { 601597e99dd9SToby Isaac fuse(&a[k], values[offset+ k ] * (flip ? flip[ k ] : 1.)); 601697e99dd9SToby Isaac cind++; 601797e99dd9SToby Isaac } 6018a5e93ea8SMatthew G. Knepley } 6019a5e93ea8SMatthew G. Knepley } 6020a5e93ea8SMatthew G. Knepley } 6021a5e93ea8SMatthew G. Knepley } 6022a5e93ea8SMatthew G. Knepley PetscFunctionReturn(0); 6023a5e93ea8SMatthew G. Knepley } 6024a5e93ea8SMatthew G. Knepley 602597e99dd9SToby Isaac PETSC_STATIC_INLINE PetscErrorCode updatePointFields_private(PetscSection section, PetscInt point, const PetscInt *perm, const PetscScalar *flip, PetscInt f, void (*fuse)(PetscScalar*, PetscScalar), PetscBool setBC, const PetscInt clperm[], const PetscScalar values[], PetscInt *offset, PetscScalar array[]) 6026a6dfd86eSKarl Rupp { 6027552f7358SJed Brown PetscScalar *a; 60281a271a75SMatthew G. Knepley PetscInt fdof, foff, fcdof, foffset = *offset; 60291a271a75SMatthew G. Knepley const PetscInt *fcdofs; /* The indices of the constrained dofs for field f on this point */ 603097e99dd9SToby Isaac PetscInt cind = 0, b; 6031552f7358SJed Brown PetscErrorCode ierr; 6032552f7358SJed Brown 6033552f7358SJed Brown PetscFunctionBegin; 6034552f7358SJed Brown ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 6035552f7358SJed Brown ierr = PetscSectionGetFieldConstraintDof(section, point, f, &fcdof);CHKERRQ(ierr); 60361a271a75SMatthew G. Knepley ierr = PetscSectionGetFieldOffset(section, point, f, &foff);CHKERRQ(ierr); 60371a271a75SMatthew G. Knepley a = &array[foff]; 6038552f7358SJed Brown if (!fcdof || setBC) { 603997e99dd9SToby Isaac if (clperm) { 604097e99dd9SToby Isaac if (perm) {for (b = 0; b < fdof; b++) {fuse(&a[b], values[clperm[foffset+perm[b]]] * (flip ? flip[perm[b]] : 1.));}} 604197e99dd9SToby Isaac else {for (b = 0; b < fdof; b++) {fuse(&a[b], values[clperm[foffset+ b ]] * (flip ? flip[ b ] : 1.));}} 6042552f7358SJed Brown } else { 604397e99dd9SToby Isaac if (perm) {for (b = 0; b < fdof; b++) {fuse(&a[b], values[foffset+perm[b]] * (flip ? flip[perm[b]] : 1.));}} 604497e99dd9SToby Isaac else {for (b = 0; b < fdof; b++) {fuse(&a[b], values[foffset+ b ] * (flip ? flip[ b ] : 1.));}} 6045552f7358SJed Brown } 6046552f7358SJed Brown } else { 6047552f7358SJed Brown ierr = PetscSectionGetFieldConstraintIndices(section, point, f, &fcdofs);CHKERRQ(ierr); 604897e99dd9SToby Isaac if (clperm) { 604997e99dd9SToby Isaac if (perm) { 605097e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 605197e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; continue;} 605297e99dd9SToby Isaac fuse(&a[b], values[clperm[foffset+perm[b]]] * (flip ? flip[perm[b]] : 1.)); 6053552f7358SJed Brown } 6054552f7358SJed Brown } else { 605597e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 605697e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; continue;} 605797e99dd9SToby Isaac fuse(&a[b], values[clperm[foffset+ b ]] * (flip ? flip[ b ] : 1.)); 605897e99dd9SToby Isaac } 605997e99dd9SToby Isaac } 606097e99dd9SToby Isaac } else { 606197e99dd9SToby Isaac if (perm) { 606297e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 606397e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; continue;} 606497e99dd9SToby Isaac fuse(&a[b], values[foffset+perm[b]] * (flip ? flip[perm[b]] : 1.)); 606597e99dd9SToby Isaac } 606697e99dd9SToby Isaac } else { 606797e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 606897e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; continue;} 606997e99dd9SToby Isaac fuse(&a[b], values[foffset+ b ] * (flip ? flip[ b ] : 1.)); 6070552f7358SJed Brown } 6071552f7358SJed Brown } 6072552f7358SJed Brown } 6073552f7358SJed Brown } 60741a271a75SMatthew G. Knepley *offset += fdof; 6075552f7358SJed Brown PetscFunctionReturn(0); 6076552f7358SJed Brown } 6077552f7358SJed Brown 6078ba322698SMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode updatePointFieldsBC_private(PetscSection section, PetscInt point, const PetscInt perm[], const PetscScalar flip[], PetscInt f, PetscInt Ncc, const PetscInt comps[], void (*fuse)(PetscScalar*, PetscScalar), const PetscInt clperm[], const PetscScalar values[], PetscInt *offset, PetscScalar array[]) 6079a5e93ea8SMatthew G. Knepley { 6080a5e93ea8SMatthew G. Knepley PetscScalar *a; 60811a271a75SMatthew G. Knepley PetscInt fdof, foff, fcdof, foffset = *offset; 60821a271a75SMatthew G. Knepley const PetscInt *fcdofs; /* The indices of the constrained dofs for field f on this point */ 60835da9d227SMatthew G. Knepley PetscInt Nc, cind = 0, ncind = 0, b; 6084ba322698SMatthew G. Knepley PetscBool ncSet, fcSet; 6085a5e93ea8SMatthew G. Knepley PetscErrorCode ierr; 6086a5e93ea8SMatthew G. Knepley 6087a5e93ea8SMatthew G. Knepley PetscFunctionBegin; 60885da9d227SMatthew G. Knepley ierr = PetscSectionGetFieldComponents(section, f, &Nc);CHKERRQ(ierr); 6089a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 6090a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetFieldConstraintDof(section, point, f, &fcdof);CHKERRQ(ierr); 60911a271a75SMatthew G. Knepley ierr = PetscSectionGetFieldOffset(section, point, f, &foff);CHKERRQ(ierr); 60921a271a75SMatthew G. Knepley a = &array[foff]; 6093a5e93ea8SMatthew G. Knepley if (fcdof) { 6094ba322698SMatthew G. Knepley /* We just override fcdof and fcdofs with Ncc and comps */ 6095a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetFieldConstraintIndices(section, point, f, &fcdofs);CHKERRQ(ierr); 609697e99dd9SToby Isaac if (clperm) { 609797e99dd9SToby Isaac if (perm) { 6098ba322698SMatthew G. Knepley if (comps) { 6099ba322698SMatthew G. Knepley for (b = 0; b < fdof; b++) { 6100ba322698SMatthew G. Knepley ncSet = fcSet = PETSC_FALSE; 61015da9d227SMatthew G. Knepley if (b%Nc == comps[ncind]) {ncind = (ncind+1)%Ncc; ncSet = PETSC_TRUE;} 6102ba322698SMatthew G. Knepley if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; fcSet = PETSC_TRUE;} 6103ba322698SMatthew G. Knepley if (ncSet && fcSet) {fuse(&a[b], values[clperm[foffset+perm[b]]] * (flip ? flip[perm[b]] : 1.));} 6104ba322698SMatthew G. Knepley } 6105ba322698SMatthew G. Knepley } else { 610697e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 610797e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) { 610897e99dd9SToby Isaac fuse(&a[b], values[clperm[foffset+perm[b]]] * (flip ? flip[perm[b]] : 1.)); 6109a5e93ea8SMatthew G. Knepley ++cind; 6110a5e93ea8SMatthew G. Knepley } 6111a5e93ea8SMatthew G. Knepley } 6112ba322698SMatthew G. Knepley } 6113ba322698SMatthew G. Knepley } else { 6114ba322698SMatthew G. Knepley if (comps) { 6115ba322698SMatthew G. Knepley for (b = 0; b < fdof; b++) { 6116ba322698SMatthew G. Knepley ncSet = fcSet = PETSC_FALSE; 61175da9d227SMatthew G. Knepley if (b%Nc == comps[ncind]) {ncind = (ncind+1)%Ncc; ncSet = PETSC_TRUE;} 6118ba322698SMatthew G. Knepley if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; fcSet = PETSC_TRUE;} 6119ba322698SMatthew G. Knepley if (ncSet && fcSet) {fuse(&a[b], values[clperm[foffset+ b ]] * (flip ? flip[ b ] : 1.));} 6120ba322698SMatthew G. Knepley } 6121a5e93ea8SMatthew G. Knepley } else { 612297e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 612397e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) { 612497e99dd9SToby Isaac fuse(&a[b], values[clperm[foffset+ b ]] * (flip ? flip[ b ] : 1.)); 612597e99dd9SToby Isaac ++cind; 612697e99dd9SToby Isaac } 612797e99dd9SToby Isaac } 612897e99dd9SToby Isaac } 6129ba322698SMatthew G. Knepley } 613097e99dd9SToby Isaac } else { 613197e99dd9SToby Isaac if (perm) { 6132ba322698SMatthew G. Knepley if (comps) { 6133ba322698SMatthew G. Knepley for (b = 0; b < fdof; b++) { 6134ba322698SMatthew G. Knepley ncSet = fcSet = PETSC_FALSE; 61355da9d227SMatthew G. Knepley if (b%Nc == comps[ncind]) {ncind = (ncind+1)%Ncc; ncSet = PETSC_TRUE;} 6136ba322698SMatthew G. Knepley if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; fcSet = PETSC_TRUE;} 6137ba322698SMatthew G. Knepley if (ncSet && fcSet) {fuse(&a[b], values[foffset+perm[b]] * (flip ? flip[perm[b]] : 1.));} 6138ba322698SMatthew G. Knepley } 6139ba322698SMatthew G. Knepley } else { 614097e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 614197e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) { 614297e99dd9SToby Isaac fuse(&a[b], values[foffset+perm[b]] * (flip ? flip[perm[b]] : 1.)); 614397e99dd9SToby Isaac ++cind; 614497e99dd9SToby Isaac } 614597e99dd9SToby Isaac } 6146ba322698SMatthew G. Knepley } 6147ba322698SMatthew G. Knepley } else { 6148ba322698SMatthew G. Knepley if (comps) { 6149ba322698SMatthew G. Knepley for (b = 0; b < fdof; b++) { 6150ba322698SMatthew G. Knepley ncSet = fcSet = PETSC_FALSE; 61515da9d227SMatthew G. Knepley if (b%Nc == comps[ncind]) {ncind = (ncind+1)%Ncc; ncSet = PETSC_TRUE;} 6152ba322698SMatthew G. Knepley if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; fcSet = PETSC_TRUE;} 6153ba322698SMatthew G. Knepley if (ncSet && fcSet) {fuse(&a[b], values[foffset+ b ] * (flip ? flip[ b ] : 1.));} 6154ba322698SMatthew G. Knepley } 615597e99dd9SToby Isaac } else { 615697e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 615797e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) { 615897e99dd9SToby Isaac fuse(&a[b], values[foffset+ b ] * (flip ? flip[ b ] : 1.)); 6159a5e93ea8SMatthew G. Knepley ++cind; 6160a5e93ea8SMatthew G. Knepley } 6161a5e93ea8SMatthew G. Knepley } 6162a5e93ea8SMatthew G. Knepley } 6163a5e93ea8SMatthew G. Knepley } 6164a5e93ea8SMatthew G. Knepley } 6165ba322698SMatthew G. Knepley } 61661a271a75SMatthew G. Knepley *offset += fdof; 6167a5e93ea8SMatthew G. Knepley PetscFunctionReturn(0); 6168a5e93ea8SMatthew G. Knepley } 6169a5e93ea8SMatthew G. Knepley 61708f3be42fSMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode DMPlexVecSetClosure_Depth1_Static(DM dm, PetscSection section, Vec v, PetscInt point, const PetscScalar values[], InsertMode mode) 6171a6dfd86eSKarl Rupp { 6172552f7358SJed Brown PetscScalar *array; 61731b406b76SMatthew G. Knepley const PetscInt *cone, *coneO; 61741b406b76SMatthew G. Knepley PetscInt pStart, pEnd, p, numPoints, off, dof; 6175552f7358SJed Brown PetscErrorCode ierr; 6176552f7358SJed Brown 61771b406b76SMatthew G. Knepley PetscFunctionBeginHot; 6178b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 6179b6ebb6e6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, point, &numPoints);CHKERRQ(ierr); 6180b6ebb6e6SMatthew G. Knepley ierr = DMPlexGetCone(dm, point, &cone);CHKERRQ(ierr); 6181b6ebb6e6SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, point, &coneO);CHKERRQ(ierr); 6182b6ebb6e6SMatthew G. Knepley ierr = VecGetArray(v, &array);CHKERRQ(ierr); 6183b6ebb6e6SMatthew G. Knepley for (p = 0, off = 0; p <= numPoints; ++p, off += dof) { 6184b6ebb6e6SMatthew G. Knepley const PetscInt cp = !p ? point : cone[p-1]; 6185b6ebb6e6SMatthew G. Knepley const PetscInt o = !p ? 0 : coneO[p-1]; 6186b6ebb6e6SMatthew G. Knepley 6187b6ebb6e6SMatthew G. Knepley if ((cp < pStart) || (cp >= pEnd)) {dof = 0; continue;} 6188b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetDof(section, cp, &dof);CHKERRQ(ierr); 6189b6ebb6e6SMatthew G. Knepley /* ADD_VALUES */ 6190b6ebb6e6SMatthew G. Knepley { 6191b6ebb6e6SMatthew G. Knepley const PetscInt *cdofs; /* The indices of the constrained dofs on this point */ 6192b6ebb6e6SMatthew G. Knepley PetscScalar *a; 6193b6ebb6e6SMatthew G. Knepley PetscInt cdof, coff, cind = 0, k; 6194b6ebb6e6SMatthew G. Knepley 6195b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(section, cp, &cdof);CHKERRQ(ierr); 6196b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetOffset(section, cp, &coff);CHKERRQ(ierr); 6197b6ebb6e6SMatthew G. Knepley a = &array[coff]; 6198b6ebb6e6SMatthew G. Knepley if (!cdof) { 6199b6ebb6e6SMatthew G. Knepley if (o >= 0) { 6200b6ebb6e6SMatthew G. Knepley for (k = 0; k < dof; ++k) { 6201b6ebb6e6SMatthew G. Knepley a[k] += values[off+k]; 6202b6ebb6e6SMatthew G. Knepley } 6203b6ebb6e6SMatthew G. Knepley } else { 6204b6ebb6e6SMatthew G. Knepley for (k = 0; k < dof; ++k) { 6205b6ebb6e6SMatthew G. Knepley a[k] += values[off+dof-k-1]; 6206b6ebb6e6SMatthew G. Knepley } 6207b6ebb6e6SMatthew G. Knepley } 6208b6ebb6e6SMatthew G. Knepley } else { 6209b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetConstraintIndices(section, cp, &cdofs);CHKERRQ(ierr); 6210b6ebb6e6SMatthew G. Knepley if (o >= 0) { 6211b6ebb6e6SMatthew G. Knepley for (k = 0; k < dof; ++k) { 6212b6ebb6e6SMatthew G. Knepley if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 6213b6ebb6e6SMatthew G. Knepley a[k] += values[off+k]; 6214b6ebb6e6SMatthew G. Knepley } 6215b6ebb6e6SMatthew G. Knepley } else { 6216b6ebb6e6SMatthew G. Knepley for (k = 0; k < dof; ++k) { 6217b6ebb6e6SMatthew G. Knepley if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 6218b6ebb6e6SMatthew G. Knepley a[k] += values[off+dof-k-1]; 6219b6ebb6e6SMatthew G. Knepley } 6220b6ebb6e6SMatthew G. Knepley } 6221b6ebb6e6SMatthew G. Knepley } 6222b6ebb6e6SMatthew G. Knepley } 6223b6ebb6e6SMatthew G. Knepley } 6224b6ebb6e6SMatthew G. Knepley ierr = VecRestoreArray(v, &array);CHKERRQ(ierr); 6225b6ebb6e6SMatthew G. Knepley PetscFunctionReturn(0); 6226b6ebb6e6SMatthew G. Knepley } 62271b406b76SMatthew G. Knepley 62281b406b76SMatthew G. Knepley /*@C 62291b406b76SMatthew G. Knepley DMPlexVecSetClosure - Set an array of the values on the closure of 'point' 62301b406b76SMatthew G. Knepley 62311b406b76SMatthew G. Knepley Not collective 62321b406b76SMatthew G. Knepley 62331b406b76SMatthew G. Knepley Input Parameters: 62341b406b76SMatthew G. Knepley + dm - The DM 62351b406b76SMatthew G. Knepley . section - The section describing the layout in v, or NULL to use the default section 62361b406b76SMatthew G. Knepley . v - The local vector 6237eaf898f9SPatrick Sanan . point - The point in the DM 62381b406b76SMatthew G. Knepley . values - The array of values 623922c1ee49SMatthew 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, 624022c1ee49SMatthew G. Knepley where INSERT_ALL_VALUES and ADD_ALL_VALUES also overwrite boundary conditions. 62411b406b76SMatthew G. Knepley 62421b406b76SMatthew G. Knepley Fortran Notes: 62431b406b76SMatthew G. Knepley This routine is only available in Fortran 90, and you must include petsc.h90 in your code. 62441b406b76SMatthew G. Knepley 62451b406b76SMatthew G. Knepley Level: intermediate 62461b406b76SMatthew G. Knepley 62471b406b76SMatthew G. Knepley .seealso DMPlexVecGetClosure(), DMPlexMatSetClosure() 62481b406b76SMatthew G. Knepley @*/ 62491b406b76SMatthew G. Knepley PetscErrorCode DMPlexVecSetClosure(DM dm, PetscSection section, Vec v, PetscInt point, const PetscScalar values[], InsertMode mode) 62501b406b76SMatthew G. Knepley { 62511b406b76SMatthew G. Knepley PetscSection clSection; 62521b406b76SMatthew G. Knepley IS clPoints; 62531b406b76SMatthew G. Knepley PetscScalar *array; 62541b406b76SMatthew G. Knepley PetscInt *points = NULL; 625527f02ce8SMatthew G. Knepley const PetscInt *clp, *clperm = NULL; 6256c459fbc1SJed Brown PetscInt depth, numFields, numPoints, p, clsize; 62571b406b76SMatthew G. Knepley PetscErrorCode ierr; 62581b406b76SMatthew G. Knepley 62591a271a75SMatthew G. Knepley PetscFunctionBeginHot; 62601b406b76SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 626192fd8e1eSJed Brown if (!section) {ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr);} 62621a271a75SMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 62631a271a75SMatthew G. Knepley PetscValidHeaderSpecific(v, VEC_CLASSID, 3); 62641b406b76SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 62651b406b76SMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 62661b406b76SMatthew G. Knepley if (depth == 1 && numFields < 2 && mode == ADD_VALUES) { 62678f3be42fSMatthew G. Knepley ierr = DMPlexVecSetClosure_Depth1_Static(dm, section, v, point, values, mode);CHKERRQ(ierr); 62681b406b76SMatthew G. Knepley PetscFunctionReturn(0); 62691b406b76SMatthew G. Knepley } 62701a271a75SMatthew G. Knepley /* Get points */ 6271923c78e0SToby Isaac ierr = DMPlexGetCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 6272c459fbc1SJed Brown for (clsize=0,p=0; p<numPoints; p++) { 6273c459fbc1SJed Brown PetscInt dof; 6274c459fbc1SJed Brown ierr = PetscSectionGetDof(section, points[2*p], &dof);CHKERRQ(ierr); 6275c459fbc1SJed Brown clsize += dof; 6276c459fbc1SJed Brown } 6277c459fbc1SJed Brown ierr = PetscSectionGetClosureInversePermutation_Internal(section, (PetscObject) dm, depth, clsize, &clperm);CHKERRQ(ierr); 62781a271a75SMatthew G. Knepley /* Get array */ 6279552f7358SJed Brown ierr = VecGetArray(v, &array);CHKERRQ(ierr); 62801a271a75SMatthew G. Knepley /* Get values */ 6281ef90cfe2SMatthew G. Knepley if (numFields > 0) { 628297e99dd9SToby Isaac PetscInt offset = 0, f; 6283552f7358SJed Brown for (f = 0; f < numFields; ++f) { 628497e99dd9SToby Isaac const PetscInt **perms = NULL; 628597e99dd9SToby Isaac const PetscScalar **flips = NULL; 628697e99dd9SToby Isaac 628797e99dd9SToby Isaac ierr = PetscSectionGetFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 6288552f7358SJed Brown switch (mode) { 6289552f7358SJed Brown case INSERT_VALUES: 629097e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 629197e99dd9SToby Isaac const PetscInt point = points[2*p]; 629297e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 629397e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 629497e99dd9SToby Isaac updatePointFields_private(section, point, perm, flip, f, insert, PETSC_FALSE, clperm, values, &offset, array); 6295552f7358SJed Brown } break; 6296552f7358SJed Brown case INSERT_ALL_VALUES: 629797e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 629897e99dd9SToby Isaac const PetscInt point = points[2*p]; 629997e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 630097e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 630197e99dd9SToby Isaac updatePointFields_private(section, point, perm, flip, f, insert, PETSC_TRUE, clperm, values, &offset, array); 6302552f7358SJed Brown } break; 6303a5e93ea8SMatthew G. Knepley case INSERT_BC_VALUES: 630497e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 630597e99dd9SToby Isaac const PetscInt point = points[2*p]; 630697e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 630797e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 6308ba322698SMatthew G. Knepley updatePointFieldsBC_private(section, point, perm, flip, f, -1, NULL, insert, clperm, values, &offset, array); 6309a5e93ea8SMatthew G. Knepley } break; 6310552f7358SJed Brown case ADD_VALUES: 631197e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 631297e99dd9SToby Isaac const PetscInt point = points[2*p]; 631397e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 631497e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 631597e99dd9SToby Isaac updatePointFields_private(section, point, perm, flip, f, add, PETSC_FALSE, clperm, values, &offset, array); 6316552f7358SJed Brown } break; 6317552f7358SJed Brown case ADD_ALL_VALUES: 631897e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 631997e99dd9SToby Isaac const PetscInt point = points[2*p]; 632097e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 632197e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 632297e99dd9SToby Isaac updatePointFields_private(section, point, perm, flip, f, add, PETSC_TRUE, clperm, values, &offset, array); 6323552f7358SJed Brown } break; 6324304ab55fSMatthew G. Knepley case ADD_BC_VALUES: 632597e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 632697e99dd9SToby Isaac const PetscInt point = points[2*p]; 632797e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 632897e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 6329ba322698SMatthew G. Knepley updatePointFieldsBC_private(section, point, perm, flip, f, -1, NULL, add, clperm, values, &offset, array); 6330304ab55fSMatthew G. Knepley } break; 6331552f7358SJed Brown default: 6332f347f43bSBarry Smith SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insert mode %d", mode); 6333552f7358SJed Brown } 633497e99dd9SToby Isaac ierr = PetscSectionRestoreFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 63351a271a75SMatthew G. Knepley } 6336552f7358SJed Brown } else { 63371a271a75SMatthew G. Knepley PetscInt dof, off; 633897e99dd9SToby Isaac const PetscInt **perms = NULL; 633997e99dd9SToby Isaac const PetscScalar **flips = NULL; 63401a271a75SMatthew G. Knepley 634197e99dd9SToby Isaac ierr = PetscSectionGetPointSyms(section,numPoints,points,&perms,&flips);CHKERRQ(ierr); 6342552f7358SJed Brown switch (mode) { 6343552f7358SJed Brown case INSERT_VALUES: 634497e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 634597e99dd9SToby Isaac const PetscInt point = points[2*p]; 634697e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 634797e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 634897e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 634997e99dd9SToby Isaac updatePoint_private(section, point, dof, insert, PETSC_FALSE, perm, flip, clperm, values, off, array); 6350552f7358SJed Brown } break; 6351552f7358SJed Brown case INSERT_ALL_VALUES: 635297e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 635397e99dd9SToby Isaac const PetscInt point = points[2*p]; 635497e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 635597e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 635697e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 635797e99dd9SToby Isaac updatePoint_private(section, point, dof, insert, PETSC_TRUE, perm, flip, clperm, values, off, array); 6358552f7358SJed Brown } break; 6359a5e93ea8SMatthew G. Knepley case INSERT_BC_VALUES: 636097e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 636197e99dd9SToby Isaac const PetscInt point = points[2*p]; 636297e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 636397e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 636497e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 636597e99dd9SToby Isaac updatePointBC_private(section, point, dof, insert, perm, flip, clperm, values, off, array); 6366a5e93ea8SMatthew G. Knepley } break; 6367552f7358SJed Brown case ADD_VALUES: 636897e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 636997e99dd9SToby Isaac const PetscInt point = points[2*p]; 637097e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 637197e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 637297e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 637397e99dd9SToby Isaac updatePoint_private(section, point, dof, add, PETSC_FALSE, perm, flip, clperm, values, off, array); 6374552f7358SJed Brown } break; 6375552f7358SJed Brown case ADD_ALL_VALUES: 637697e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 637797e99dd9SToby Isaac const PetscInt point = points[2*p]; 637897e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 637997e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 638097e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 638197e99dd9SToby Isaac updatePoint_private(section, point, dof, add, PETSC_TRUE, perm, flip, clperm, values, off, array); 6382552f7358SJed Brown } break; 6383304ab55fSMatthew G. Knepley case ADD_BC_VALUES: 638497e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 638597e99dd9SToby Isaac const PetscInt point = points[2*p]; 638697e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 638797e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 638897e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 638997e99dd9SToby Isaac updatePointBC_private(section, point, dof, add, perm, flip, clperm, values, off, array); 6390304ab55fSMatthew G. Knepley } break; 6391552f7358SJed Brown default: 6392f347f43bSBarry Smith SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insert mode %d", mode); 6393552f7358SJed Brown } 639497e99dd9SToby Isaac ierr = PetscSectionRestorePointSyms(section,numPoints,points,&perms,&flips);CHKERRQ(ierr); 6395552f7358SJed Brown } 63961a271a75SMatthew G. Knepley /* Cleanup points */ 6397923c78e0SToby Isaac ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 63981a271a75SMatthew G. Knepley /* Cleanup array */ 6399552f7358SJed Brown ierr = VecRestoreArray(v, &array);CHKERRQ(ierr); 6400552f7358SJed Brown PetscFunctionReturn(0); 6401552f7358SJed Brown } 6402552f7358SJed Brown 64035f790a90SMatthew G. Knepley /* Check whether the given point is in the label. If not, update the offset to skip this point */ 64045f790a90SMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode CheckPoint_Private(DMLabel label, PetscInt labelId, PetscSection section, PetscInt point, PetscInt f, PetscInt *offset) 64055f790a90SMatthew G. Knepley { 64065f790a90SMatthew G. Knepley PetscFunctionBegin; 64075f790a90SMatthew G. Knepley if (label) { 64085f790a90SMatthew G. Knepley PetscInt val, fdof; 64095f790a90SMatthew G. Knepley PetscErrorCode ierr; 64105f790a90SMatthew G. Knepley 64115f790a90SMatthew G. Knepley /* There is a problem with this: 64125f790a90SMatthew 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 64135f790a90SMatthew 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. 64145f790a90SMatthew G. Knepley Thus I am only going to check val != -1, not val != labelId 64155f790a90SMatthew G. Knepley */ 64165f790a90SMatthew G. Knepley ierr = DMLabelGetValue(label, point, &val);CHKERRQ(ierr); 64175f790a90SMatthew G. Knepley if (val < 0) { 64185f790a90SMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 64195f790a90SMatthew G. Knepley *offset += fdof; 64205f790a90SMatthew G. Knepley PetscFunctionReturn(1); 64215f790a90SMatthew G. Knepley } 64225f790a90SMatthew G. Knepley } 64235f790a90SMatthew G. Knepley PetscFunctionReturn(0); 64245f790a90SMatthew G. Knepley } 64255f790a90SMatthew G. Knepley 642697529cf3SJed Brown /* Unlike DMPlexVecSetClosure(), this uses plex-native closure permutation, not a user-specified permutation such as DMPlexSetClosurePermutationTensor(). */ 64275f790a90SMatthew 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) 6428e07394fbSMatthew G. Knepley { 6429e07394fbSMatthew G. Knepley PetscSection clSection; 6430e07394fbSMatthew G. Knepley IS clPoints; 6431e07394fbSMatthew G. Knepley PetscScalar *array; 6432e07394fbSMatthew G. Knepley PetscInt *points = NULL; 643397529cf3SJed Brown const PetscInt *clp; 6434e07394fbSMatthew G. Knepley PetscInt numFields, numPoints, p; 643597e99dd9SToby Isaac PetscInt offset = 0, f; 6436e07394fbSMatthew G. Knepley PetscErrorCode ierr; 6437e07394fbSMatthew G. Knepley 6438e07394fbSMatthew G. Knepley PetscFunctionBeginHot; 6439e07394fbSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 644092fd8e1eSJed Brown if (!section) {ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr);} 6441e07394fbSMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 6442e07394fbSMatthew G. Knepley PetscValidHeaderSpecific(v, VEC_CLASSID, 3); 6443e07394fbSMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 6444e07394fbSMatthew G. Knepley /* Get points */ 6445923c78e0SToby Isaac ierr = DMPlexGetCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 6446e07394fbSMatthew G. Knepley /* Get array */ 6447e07394fbSMatthew G. Knepley ierr = VecGetArray(v, &array);CHKERRQ(ierr); 6448e07394fbSMatthew G. Knepley /* Get values */ 6449e07394fbSMatthew G. Knepley for (f = 0; f < numFields; ++f) { 645097e99dd9SToby Isaac const PetscInt **perms = NULL; 645197e99dd9SToby Isaac const PetscScalar **flips = NULL; 645297e99dd9SToby Isaac 6453e07394fbSMatthew G. Knepley if (!fieldActive[f]) { 6454e07394fbSMatthew G. Knepley for (p = 0; p < numPoints*2; p += 2) { 6455e07394fbSMatthew G. Knepley PetscInt fdof; 6456e07394fbSMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, points[p], f, &fdof);CHKERRQ(ierr); 6457e07394fbSMatthew G. Knepley offset += fdof; 6458e07394fbSMatthew G. Knepley } 6459e07394fbSMatthew G. Knepley continue; 6460e07394fbSMatthew G. Knepley } 646197e99dd9SToby Isaac ierr = PetscSectionGetFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 6462e07394fbSMatthew G. Knepley switch (mode) { 6463e07394fbSMatthew G. Knepley case INSERT_VALUES: 646497e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 646597e99dd9SToby Isaac const PetscInt point = points[2*p]; 646697e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 646797e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 64685f790a90SMatthew G. Knepley ierr = CheckPoint_Private(label, labelId, section, point, f, &offset); if (ierr) continue; 646997529cf3SJed Brown updatePointFields_private(section, point, perm, flip, f, insert, PETSC_FALSE, NULL, values, &offset, array); 6470e07394fbSMatthew G. Knepley } break; 6471e07394fbSMatthew G. Knepley case INSERT_ALL_VALUES: 647297e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 647397e99dd9SToby Isaac const PetscInt point = points[2*p]; 647497e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 647597e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 64765f790a90SMatthew G. Knepley ierr = CheckPoint_Private(label, labelId, section, point, f, &offset); if (ierr) continue; 647797529cf3SJed Brown updatePointFields_private(section, point, perm, flip, f, insert, PETSC_TRUE, NULL, values, &offset, array); 6478e07394fbSMatthew G. Knepley } break; 6479e07394fbSMatthew G. Knepley case INSERT_BC_VALUES: 648097e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 648197e99dd9SToby Isaac const PetscInt point = points[2*p]; 648297e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 648397e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 64845f790a90SMatthew G. Knepley ierr = CheckPoint_Private(label, labelId, section, point, f, &offset); if (ierr) continue; 648597529cf3SJed Brown updatePointFieldsBC_private(section, point, perm, flip, f, Ncc, comps, insert, NULL, values, &offset, array); 6486e07394fbSMatthew G. Knepley } break; 6487e07394fbSMatthew G. Knepley case ADD_VALUES: 648897e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 648997e99dd9SToby Isaac const PetscInt point = points[2*p]; 649097e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 649197e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 64925f790a90SMatthew G. Knepley ierr = CheckPoint_Private(label, labelId, section, point, f, &offset); if (ierr) continue; 649397529cf3SJed Brown updatePointFields_private(section, point, perm, flip, f, add, PETSC_FALSE, NULL, values, &offset, array); 6494e07394fbSMatthew G. Knepley } break; 6495e07394fbSMatthew G. Knepley case ADD_ALL_VALUES: 649697e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 649797e99dd9SToby Isaac const PetscInt point = points[2*p]; 649897e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 649997e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 65005f790a90SMatthew G. Knepley ierr = CheckPoint_Private(label, labelId, section, point, f, &offset); if (ierr) continue; 650197529cf3SJed Brown updatePointFields_private(section, point, perm, flip, f, add, PETSC_TRUE, NULL, values, &offset, array); 6502e07394fbSMatthew G. Knepley } break; 6503e07394fbSMatthew G. Knepley default: 6504f347f43bSBarry Smith SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insert mode %d", mode); 6505e07394fbSMatthew G. Knepley } 650697e99dd9SToby Isaac ierr = PetscSectionRestoreFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 6507e07394fbSMatthew G. Knepley } 6508e07394fbSMatthew G. Knepley /* Cleanup points */ 6509923c78e0SToby Isaac ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 6510e07394fbSMatthew G. Knepley /* Cleanup array */ 6511e07394fbSMatthew G. Knepley ierr = VecRestoreArray(v, &array);CHKERRQ(ierr); 6512e07394fbSMatthew G. Knepley PetscFunctionReturn(0); 6513e07394fbSMatthew G. Knepley } 6514e07394fbSMatthew G. Knepley 65157cd05799SMatthew G. Knepley static PetscErrorCode DMPlexPrintMatSetValues(PetscViewer viewer, Mat A, PetscInt point, PetscInt numRIndices, const PetscInt rindices[], PetscInt numCIndices, const PetscInt cindices[], const PetscScalar values[]) 6516552f7358SJed Brown { 6517552f7358SJed Brown PetscMPIInt rank; 6518552f7358SJed Brown PetscInt i, j; 6519552f7358SJed Brown PetscErrorCode ierr; 6520552f7358SJed Brown 6521552f7358SJed Brown PetscFunctionBegin; 6522ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)A), &rank);CHKERRMPI(ierr); 6523eaf898f9SPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer, "[%d]mat for point %D\n", rank, point);CHKERRQ(ierr); 6524e4b003c7SBarry Smith for (i = 0; i < numRIndices; i++) {ierr = PetscViewerASCIIPrintf(viewer, "[%d]mat row indices[%D] = %D\n", rank, i, rindices[i]);CHKERRQ(ierr);} 6525e4b003c7SBarry Smith for (i = 0; i < numCIndices; i++) {ierr = PetscViewerASCIIPrintf(viewer, "[%d]mat col indices[%D] = %D\n", rank, i, cindices[i]);CHKERRQ(ierr);} 6526b0ecff45SMatthew G. Knepley numCIndices = numCIndices ? numCIndices : numRIndices; 6527557cf195SMatthew G. Knepley if (!values) PetscFunctionReturn(0); 6528b0ecff45SMatthew G. Knepley for (i = 0; i < numRIndices; i++) { 6529e4b003c7SBarry Smith ierr = PetscViewerASCIIPrintf(viewer, "[%d]", rank);CHKERRQ(ierr); 6530b0ecff45SMatthew G. Knepley for (j = 0; j < numCIndices; j++) { 6531519f805aSKarl Rupp #if defined(PETSC_USE_COMPLEX) 65327eba1a17SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " (%g,%g)", (double)PetscRealPart(values[i*numCIndices+j]), (double)PetscImaginaryPart(values[i*numCIndices+j]));CHKERRQ(ierr); 6533552f7358SJed Brown #else 6534b0ecff45SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " %g", (double)values[i*numCIndices+j]);CHKERRQ(ierr); 6535552f7358SJed Brown #endif 6536552f7358SJed Brown } 653777a6746dSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, "\n");CHKERRQ(ierr); 6538552f7358SJed Brown } 6539552f7358SJed Brown PetscFunctionReturn(0); 6540552f7358SJed Brown } 6541552f7358SJed Brown 654205586334SMatthew G. Knepley /* 654305586334SMatthew G. Knepley DMPlexGetIndicesPoint_Internal - Add the indices for dofs on a point to an index array 654405586334SMatthew G. Knepley 654505586334SMatthew G. Knepley Input Parameters: 654605586334SMatthew G. Knepley + section - The section for this data layout 654736fa2b79SJed Brown . islocal - Is the section (and thus indices being requested) local or global? 654805586334SMatthew G. Knepley . point - The point contributing dofs with these indices 654905586334SMatthew G. Knepley . off - The global offset of this point 655005586334SMatthew G. Knepley . loff - The local offset of each field 6551a5b23f4aSJose E. Roman . setBC - The flag determining whether to include indices of boundary values 655205586334SMatthew G. Knepley . perm - A permutation of the dofs on this point, or NULL 655305586334SMatthew G. Knepley - indperm - A permutation of the entire indices array, or NULL 655405586334SMatthew G. Knepley 655505586334SMatthew G. Knepley Output Parameter: 655605586334SMatthew G. Knepley . indices - Indices for dofs on this point 655705586334SMatthew G. Knepley 655805586334SMatthew G. Knepley Level: developer 655905586334SMatthew G. Knepley 656005586334SMatthew G. Knepley Note: The indices could be local or global, depending on the value of 'off'. 656105586334SMatthew G. Knepley */ 656236fa2b79SJed Brown PetscErrorCode DMPlexGetIndicesPoint_Internal(PetscSection section, PetscBool islocal,PetscInt point, PetscInt off, PetscInt *loff, PetscBool setBC, const PetscInt perm[], const PetscInt indperm[], PetscInt indices[]) 6563a6dfd86eSKarl Rupp { 6564e6ccafaeSMatthew G Knepley PetscInt dof; /* The number of unknowns on this point */ 6565552f7358SJed Brown PetscInt cdof; /* The number of constraints on this point */ 6566552f7358SJed Brown const PetscInt *cdofs; /* The indices of the constrained dofs on this point */ 6567552f7358SJed Brown PetscInt cind = 0, k; 6568552f7358SJed Brown PetscErrorCode ierr; 6569552f7358SJed Brown 6570552f7358SJed Brown PetscFunctionBegin; 657136fa2b79SJed Brown if (!islocal && setBC) SETERRQ(PetscObjectComm((PetscObject)section),PETSC_ERR_ARG_INCOMP,"setBC incompatible with global indices; use a local section or disable setBC"); 6572552f7358SJed Brown ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 6573552f7358SJed Brown ierr = PetscSectionGetConstraintDof(section, point, &cdof);CHKERRQ(ierr); 6574552f7358SJed Brown if (!cdof || setBC) { 657505586334SMatthew G. Knepley for (k = 0; k < dof; ++k) { 657605586334SMatthew G. Knepley const PetscInt preind = perm ? *loff+perm[k] : *loff+k; 657705586334SMatthew G. Knepley const PetscInt ind = indperm ? indperm[preind] : preind; 657805586334SMatthew G. Knepley 657905586334SMatthew G. Knepley indices[ind] = off + k; 6580552f7358SJed Brown } 6581552f7358SJed Brown } else { 6582552f7358SJed Brown ierr = PetscSectionGetConstraintIndices(section, point, &cdofs);CHKERRQ(ierr); 65834acb8e1eSToby Isaac for (k = 0; k < dof; ++k) { 658405586334SMatthew G. Knepley const PetscInt preind = perm ? *loff+perm[k] : *loff+k; 658505586334SMatthew G. Knepley const PetscInt ind = indperm ? indperm[preind] : preind; 658605586334SMatthew G. Knepley 65874acb8e1eSToby Isaac if ((cind < cdof) && (k == cdofs[cind])) { 65884acb8e1eSToby Isaac /* Insert check for returning constrained indices */ 658905586334SMatthew G. Knepley indices[ind] = -(off+k+1); 65904acb8e1eSToby Isaac ++cind; 65914acb8e1eSToby Isaac } else { 659236fa2b79SJed Brown indices[ind] = off + k - (islocal ? 0 : cind); 6593552f7358SJed Brown } 6594552f7358SJed Brown } 6595552f7358SJed Brown } 6596e6ccafaeSMatthew G Knepley *loff += dof; 6597552f7358SJed Brown PetscFunctionReturn(0); 6598552f7358SJed Brown } 6599552f7358SJed Brown 66007e29afd2SMatthew G. Knepley /* 660136fa2b79SJed Brown DMPlexGetIndicesPointFields_Internal - gets section indices for a point in its canonical ordering. 66027e29afd2SMatthew G. Knepley 660336fa2b79SJed Brown Input Parameters: 660436fa2b79SJed Brown + section - a section (global or local) 660536fa2b79SJed Brown - islocal - PETSC_TRUE if requesting local indices (i.e., section is local); PETSC_FALSE for global 660636fa2b79SJed Brown . point - point within section 660736fa2b79SJed Brown . off - The offset of this point in the (local or global) indexed space - should match islocal and (usually) the section 660836fa2b79SJed Brown . foffs - array of length numFields containing the offset in canonical point ordering (the location in indices) of each field 660936fa2b79SJed Brown . setBC - identify constrained (boundary condition) points via involution. 661036fa2b79SJed Brown . perms - perms[f][permsoff][:] is a permutation of dofs within each field 661136fa2b79SJed Brown . permsoff - offset 661236fa2b79SJed Brown - indperm - index permutation 661336fa2b79SJed Brown 661436fa2b79SJed Brown Output Parameter: 661536fa2b79SJed Brown . foffs - each entry is incremented by the number of (unconstrained if setBC=FALSE) dofs in that field 661636fa2b79SJed Brown . indices - array to hold indices (as defined by section) of each dof associated with point 661736fa2b79SJed Brown 661836fa2b79SJed Brown Notes: 661936fa2b79SJed Brown If section is local and setBC=true, there is no distinction between constrained and unconstrained dofs. 662036fa2b79SJed Brown If section is local and setBC=false, the indices for constrained points are the involution -(i+1) of their position 662136fa2b79SJed Brown in the local vector. 662236fa2b79SJed Brown 662336fa2b79SJed Brown If section is global and setBC=false, the indices for constrained points are negative (and their value is not 662436fa2b79SJed Brown significant). It is invalid to call with a global section and setBC=true. 662536fa2b79SJed Brown 662636fa2b79SJed Brown Developer Note: 662736fa2b79SJed Brown The section is only used for field layout, so islocal is technically a statement about the offset (off). At some point 662836fa2b79SJed Brown in the future, global sections may have fields set, in which case we could pass the global section and obtain the 662936fa2b79SJed Brown offset could be obtained from the section instead of passing it explicitly as we do now. 663036fa2b79SJed Brown 663136fa2b79SJed Brown Example: 663236fa2b79SJed Brown Suppose a point contains one field with three components, and for which the unconstrained indices are {10, 11, 12}. 663336fa2b79SJed Brown When the middle component is constrained, we get the array {10, -12, 12} for (islocal=TRUE, setBC=FALSE). 663436fa2b79SJed Brown Note that -12 is the involution of 11, so the user can involute negative indices to recover local indices. 663536fa2b79SJed 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. 663636fa2b79SJed Brown 663736fa2b79SJed Brown Level: developer 66387e29afd2SMatthew G. Knepley */ 663936fa2b79SJed 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[]) 6640a6dfd86eSKarl Rupp { 6641552f7358SJed Brown PetscInt numFields, foff, f; 6642552f7358SJed Brown PetscErrorCode ierr; 6643552f7358SJed Brown 6644552f7358SJed Brown PetscFunctionBegin; 664536fa2b79SJed Brown if (!islocal && setBC) SETERRQ(PetscObjectComm((PetscObject)section),PETSC_ERR_ARG_INCOMP,"setBC incompatible with global indices; use a local section or disable setBC"); 6646552f7358SJed Brown ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 6647552f7358SJed Brown for (f = 0, foff = 0; f < numFields; ++f) { 66484acb8e1eSToby Isaac PetscInt fdof, cfdof; 6649552f7358SJed Brown const PetscInt *fcdofs; /* The indices of the constrained dofs for field f on this point */ 66504acb8e1eSToby Isaac PetscInt cind = 0, b; 66514acb8e1eSToby Isaac const PetscInt *perm = (perms && perms[f]) ? perms[f][permsoff] : NULL; 6652552f7358SJed Brown 6653552f7358SJed Brown ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 6654552f7358SJed Brown ierr = PetscSectionGetFieldConstraintDof(section, point, f, &cfdof);CHKERRQ(ierr); 6655552f7358SJed Brown if (!cfdof || setBC) { 665605586334SMatthew G. Knepley for (b = 0; b < fdof; ++b) { 665705586334SMatthew G. Knepley const PetscInt preind = perm ? foffs[f]+perm[b] : foffs[f]+b; 665805586334SMatthew G. Knepley const PetscInt ind = indperm ? indperm[preind] : preind; 665905586334SMatthew G. Knepley 666005586334SMatthew G. Knepley indices[ind] = off+foff+b; 666105586334SMatthew G. Knepley } 6662552f7358SJed Brown } else { 6663552f7358SJed Brown ierr = PetscSectionGetFieldConstraintIndices(section, point, f, &fcdofs);CHKERRQ(ierr); 666405586334SMatthew G. Knepley for (b = 0; b < fdof; ++b) { 666505586334SMatthew G. Knepley const PetscInt preind = perm ? foffs[f]+perm[b] : foffs[f]+b; 666605586334SMatthew G. Knepley const PetscInt ind = indperm ? indperm[preind] : preind; 666705586334SMatthew G. Knepley 66684acb8e1eSToby Isaac if ((cind < cfdof) && (b == fcdofs[cind])) { 666905586334SMatthew G. Knepley indices[ind] = -(off+foff+b+1); 6670552f7358SJed Brown ++cind; 6671552f7358SJed Brown } else { 667236fa2b79SJed Brown indices[ind] = off + foff + b - (islocal ? 0 : cind); 6673552f7358SJed Brown } 6674552f7358SJed Brown } 6675552f7358SJed Brown } 667636fa2b79SJed Brown foff += (setBC || islocal ? fdof : (fdof - cfdof)); 6677552f7358SJed Brown foffs[f] += fdof; 6678552f7358SJed Brown } 6679552f7358SJed Brown PetscFunctionReturn(0); 6680552f7358SJed Brown } 6681552f7358SJed Brown 66827e29afd2SMatthew G. Knepley /* 66837e29afd2SMatthew G. Knepley This version believes the globalSection offsets for each field, rather than just the point offset 66847e29afd2SMatthew G. Knepley 66857e29afd2SMatthew G. Knepley . foffs - The offset into 'indices' for each field, since it is segregated by field 6686645102dcSJed Brown 6687645102dcSJed Brown Notes: 6688645102dcSJed Brown The semantics of this function relate to that of setBC=FALSE in DMPlexGetIndicesPointFields_Internal. 6689645102dcSJed Brown Since this function uses global indices, setBC=TRUE would be invalid, so no such argument exists. 66907e29afd2SMatthew G. Knepley */ 6691645102dcSJed Brown static PetscErrorCode DMPlexGetIndicesPointFieldsSplit_Internal(PetscSection section, PetscSection globalSection, PetscInt point, PetscInt foffs[], const PetscInt ***perms, PetscInt permsoff, const PetscInt indperm[], PetscInt indices[]) 66927e29afd2SMatthew G. Knepley { 66937e29afd2SMatthew G. Knepley PetscInt numFields, foff, f; 66947e29afd2SMatthew G. Knepley PetscErrorCode ierr; 66957e29afd2SMatthew G. Knepley 66967e29afd2SMatthew G. Knepley PetscFunctionBegin; 66977e29afd2SMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 66987e29afd2SMatthew G. Knepley for (f = 0; f < numFields; ++f) { 66997e29afd2SMatthew G. Knepley PetscInt fdof, cfdof; 67007e29afd2SMatthew G. Knepley const PetscInt *fcdofs; /* The indices of the constrained dofs for field f on this point */ 67017e29afd2SMatthew G. Knepley PetscInt cind = 0, b; 67027e29afd2SMatthew G. Knepley const PetscInt *perm = (perms && perms[f]) ? perms[f][permsoff] : NULL; 67037e29afd2SMatthew G. Knepley 67047e29afd2SMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 67057e29afd2SMatthew G. Knepley ierr = PetscSectionGetFieldConstraintDof(section, point, f, &cfdof);CHKERRQ(ierr); 67067e29afd2SMatthew G. Knepley ierr = PetscSectionGetFieldOffset(globalSection, point, f, &foff);CHKERRQ(ierr); 6707645102dcSJed Brown if (!cfdof) { 670805586334SMatthew G. Knepley for (b = 0; b < fdof; ++b) { 670905586334SMatthew G. Knepley const PetscInt preind = perm ? foffs[f]+perm[b] : foffs[f]+b; 671005586334SMatthew G. Knepley const PetscInt ind = indperm ? indperm[preind] : preind; 671105586334SMatthew G. Knepley 671205586334SMatthew G. Knepley indices[ind] = foff+b; 671305586334SMatthew G. Knepley } 67147e29afd2SMatthew G. Knepley } else { 67157e29afd2SMatthew G. Knepley ierr = PetscSectionGetFieldConstraintIndices(section, point, f, &fcdofs);CHKERRQ(ierr); 671605586334SMatthew G. Knepley for (b = 0; b < fdof; ++b) { 671705586334SMatthew G. Knepley const PetscInt preind = perm ? foffs[f]+perm[b] : foffs[f]+b; 671805586334SMatthew G. Knepley const PetscInt ind = indperm ? indperm[preind] : preind; 671905586334SMatthew G. Knepley 67207e29afd2SMatthew G. Knepley if ((cind < cfdof) && (b == fcdofs[cind])) { 672105586334SMatthew G. Knepley indices[ind] = -(foff+b+1); 67227e29afd2SMatthew G. Knepley ++cind; 67237e29afd2SMatthew G. Knepley } else { 672405586334SMatthew G. Knepley indices[ind] = foff+b-cind; 67257e29afd2SMatthew G. Knepley } 67267e29afd2SMatthew G. Knepley } 67277e29afd2SMatthew G. Knepley } 67287e29afd2SMatthew G. Knepley foffs[f] += fdof; 67297e29afd2SMatthew G. Knepley } 67307e29afd2SMatthew G. Knepley PetscFunctionReturn(0); 67317e29afd2SMatthew G. Knepley } 67327e29afd2SMatthew G. Knepley 67334acb8e1eSToby 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) 6734d3d1a6afSToby Isaac { 6735d3d1a6afSToby Isaac Mat cMat; 6736d3d1a6afSToby Isaac PetscSection aSec, cSec; 6737d3d1a6afSToby Isaac IS aIS; 6738d3d1a6afSToby Isaac PetscInt aStart = -1, aEnd = -1; 6739d3d1a6afSToby Isaac const PetscInt *anchors; 6740e17c06e0SMatthew G. Knepley PetscInt numFields, f, p, q, newP = 0; 6741d3d1a6afSToby Isaac PetscInt newNumPoints = 0, newNumIndices = 0; 6742d3d1a6afSToby Isaac PetscInt *newPoints, *indices, *newIndices; 6743d3d1a6afSToby Isaac PetscInt maxAnchor, maxDof; 6744d3d1a6afSToby Isaac PetscInt newOffsets[32]; 6745d3d1a6afSToby Isaac PetscInt *pointMatOffsets[32]; 6746d3d1a6afSToby Isaac PetscInt *newPointOffsets[32]; 6747d3d1a6afSToby Isaac PetscScalar *pointMat[32]; 67486ecaa68aSToby Isaac PetscScalar *newValues=NULL,*tmpValues; 6749d3d1a6afSToby Isaac PetscBool anyConstrained = PETSC_FALSE; 6750d3d1a6afSToby Isaac PetscErrorCode ierr; 6751d3d1a6afSToby Isaac 6752d3d1a6afSToby Isaac PetscFunctionBegin; 6753d3d1a6afSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6754d3d1a6afSToby Isaac PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 6755d3d1a6afSToby Isaac ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 6756d3d1a6afSToby Isaac 6757a17985deSToby Isaac ierr = DMPlexGetAnchors(dm,&aSec,&aIS);CHKERRQ(ierr); 6758d3d1a6afSToby Isaac /* if there are point-to-point constraints */ 6759d3d1a6afSToby Isaac if (aSec) { 6760580bdb30SBarry Smith ierr = PetscArrayzero(newOffsets, 32);CHKERRQ(ierr); 6761d3d1a6afSToby Isaac ierr = ISGetIndices(aIS,&anchors);CHKERRQ(ierr); 6762d3d1a6afSToby Isaac ierr = PetscSectionGetChart(aSec,&aStart,&aEnd);CHKERRQ(ierr); 6763d3d1a6afSToby Isaac /* figure out how many points are going to be in the new element matrix 6764d3d1a6afSToby Isaac * (we allow double counting, because it's all just going to be summed 6765d3d1a6afSToby Isaac * into the global matrix anyway) */ 6766d3d1a6afSToby Isaac for (p = 0; p < 2*numPoints; p+=2) { 6767d3d1a6afSToby Isaac PetscInt b = points[p]; 67684b2f2278SToby Isaac PetscInt bDof = 0, bSecDof; 6769d3d1a6afSToby Isaac 67704b2f2278SToby Isaac ierr = PetscSectionGetDof(section,b,&bSecDof);CHKERRQ(ierr); 67714b2f2278SToby Isaac if (!bSecDof) { 67724b2f2278SToby Isaac continue; 67734b2f2278SToby Isaac } 6774d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 6775d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec,b,&bDof);CHKERRQ(ierr); 6776d3d1a6afSToby Isaac } 6777d3d1a6afSToby Isaac if (bDof) { 6778d3d1a6afSToby Isaac /* this point is constrained */ 6779d3d1a6afSToby Isaac /* it is going to be replaced by its anchors */ 6780d3d1a6afSToby Isaac PetscInt bOff, q; 6781d3d1a6afSToby Isaac 6782d3d1a6afSToby Isaac anyConstrained = PETSC_TRUE; 6783d3d1a6afSToby Isaac newNumPoints += bDof; 6784d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(aSec,b,&bOff);CHKERRQ(ierr); 6785d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 6786d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q]; 6787d3d1a6afSToby Isaac PetscInt aDof; 6788d3d1a6afSToby Isaac 6789d3d1a6afSToby Isaac ierr = PetscSectionGetDof(section,a,&aDof);CHKERRQ(ierr); 6790d3d1a6afSToby Isaac newNumIndices += aDof; 6791d3d1a6afSToby Isaac for (f = 0; f < numFields; ++f) { 6792d3d1a6afSToby Isaac PetscInt fDof; 6793d3d1a6afSToby Isaac 6794d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, a, f, &fDof);CHKERRQ(ierr); 6795d3d1a6afSToby Isaac newOffsets[f+1] += fDof; 6796d3d1a6afSToby Isaac } 6797d3d1a6afSToby Isaac } 6798d3d1a6afSToby Isaac } 6799d3d1a6afSToby Isaac else { 6800d3d1a6afSToby Isaac /* this point is not constrained */ 6801d3d1a6afSToby Isaac newNumPoints++; 68024b2f2278SToby Isaac newNumIndices += bSecDof; 6803d3d1a6afSToby Isaac for (f = 0; f < numFields; ++f) { 6804d3d1a6afSToby Isaac PetscInt fDof; 6805d3d1a6afSToby Isaac 6806d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, b, f, &fDof);CHKERRQ(ierr); 6807d3d1a6afSToby Isaac newOffsets[f+1] += fDof; 6808d3d1a6afSToby Isaac } 6809d3d1a6afSToby Isaac } 6810d3d1a6afSToby Isaac } 6811d3d1a6afSToby Isaac } 6812d3d1a6afSToby Isaac if (!anyConstrained) { 681372b80496SMatthew G. Knepley if (outNumPoints) *outNumPoints = 0; 681472b80496SMatthew G. Knepley if (outNumIndices) *outNumIndices = 0; 681572b80496SMatthew G. Knepley if (outPoints) *outPoints = NULL; 681672b80496SMatthew G. Knepley if (outValues) *outValues = NULL; 681772b80496SMatthew G. Knepley if (aSec) {ierr = ISRestoreIndices(aIS,&anchors);CHKERRQ(ierr);} 6818d3d1a6afSToby Isaac PetscFunctionReturn(0); 6819d3d1a6afSToby Isaac } 6820d3d1a6afSToby Isaac 68216ecaa68aSToby Isaac if (outNumPoints) *outNumPoints = newNumPoints; 68226ecaa68aSToby Isaac if (outNumIndices) *outNumIndices = newNumIndices; 68236ecaa68aSToby Isaac 6824f13f9184SToby Isaac for (f = 0; f < numFields; ++f) newOffsets[f+1] += newOffsets[f]; 6825d3d1a6afSToby Isaac 68266ecaa68aSToby Isaac if (!outPoints && !outValues) { 68276ecaa68aSToby Isaac if (offsets) { 68286ecaa68aSToby Isaac for (f = 0; f <= numFields; f++) { 68296ecaa68aSToby Isaac offsets[f] = newOffsets[f]; 68306ecaa68aSToby Isaac } 68316ecaa68aSToby Isaac } 68326ecaa68aSToby Isaac if (aSec) {ierr = ISRestoreIndices(aIS,&anchors);CHKERRQ(ierr);} 68336ecaa68aSToby Isaac PetscFunctionReturn(0); 68346ecaa68aSToby Isaac } 68356ecaa68aSToby Isaac 6836f347f43bSBarry Smith if (numFields && newOffsets[numFields] != newNumIndices) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", newOffsets[numFields], newNumIndices); 6837d3d1a6afSToby Isaac 6838f7c74593SToby Isaac ierr = DMGetDefaultConstraints(dm, &cSec, &cMat);CHKERRQ(ierr); 6839d3d1a6afSToby Isaac 6840d3d1a6afSToby Isaac /* workspaces */ 6841d3d1a6afSToby Isaac if (numFields) { 6842d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 684369291d52SBarry Smith ierr = DMGetWorkArray(dm,numPoints+1,MPIU_INT,&pointMatOffsets[f]);CHKERRQ(ierr); 684469291d52SBarry Smith ierr = DMGetWorkArray(dm,numPoints+1,MPIU_INT,&newPointOffsets[f]);CHKERRQ(ierr); 6845d3d1a6afSToby Isaac } 6846d3d1a6afSToby Isaac } 6847d3d1a6afSToby Isaac else { 684869291d52SBarry Smith ierr = DMGetWorkArray(dm,numPoints+1,MPIU_INT,&pointMatOffsets[0]);CHKERRQ(ierr); 684969291d52SBarry Smith ierr = DMGetWorkArray(dm,numPoints,MPIU_INT,&newPointOffsets[0]);CHKERRQ(ierr); 6850d3d1a6afSToby Isaac } 6851d3d1a6afSToby Isaac 6852d3d1a6afSToby Isaac /* get workspaces for the point-to-point matrices */ 6853d3d1a6afSToby Isaac if (numFields) { 68544b2f2278SToby Isaac PetscInt totalOffset, totalMatOffset; 68554b2f2278SToby Isaac 6856d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 6857d3d1a6afSToby Isaac PetscInt b = points[2*p]; 68584b2f2278SToby Isaac PetscInt bDof = 0, bSecDof; 6859d3d1a6afSToby Isaac 68604b2f2278SToby Isaac ierr = PetscSectionGetDof(section,b,&bSecDof);CHKERRQ(ierr); 68614b2f2278SToby Isaac if (!bSecDof) { 68624b2f2278SToby Isaac for (f = 0; f < numFields; f++) { 68634b2f2278SToby Isaac newPointOffsets[f][p + 1] = 0; 68644b2f2278SToby Isaac pointMatOffsets[f][p + 1] = 0; 68654b2f2278SToby Isaac } 68664b2f2278SToby Isaac continue; 68674b2f2278SToby Isaac } 6868d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 6869d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec, b, &bDof);CHKERRQ(ierr); 6870d3d1a6afSToby Isaac } 6871d3d1a6afSToby Isaac if (bDof) { 6872d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 6873d3d1a6afSToby Isaac PetscInt fDof, q, bOff, allFDof = 0; 6874d3d1a6afSToby Isaac 6875d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, b, f, &fDof);CHKERRQ(ierr); 6876d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(aSec, b, &bOff);CHKERRQ(ierr); 6877d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 6878d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q]; 6879d3d1a6afSToby Isaac PetscInt aFDof; 6880d3d1a6afSToby Isaac 6881d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, a, f, &aFDof);CHKERRQ(ierr); 6882d3d1a6afSToby Isaac allFDof += aFDof; 6883d3d1a6afSToby Isaac } 6884d3d1a6afSToby Isaac newPointOffsets[f][p+1] = allFDof; 6885d3d1a6afSToby Isaac pointMatOffsets[f][p+1] = fDof * allFDof; 6886d3d1a6afSToby Isaac } 6887d3d1a6afSToby Isaac } 6888d3d1a6afSToby Isaac else { 6889d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 6890d3d1a6afSToby Isaac PetscInt fDof; 6891d3d1a6afSToby Isaac 6892d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, b, f, &fDof);CHKERRQ(ierr); 6893d3d1a6afSToby Isaac newPointOffsets[f][p+1] = fDof; 6894d3d1a6afSToby Isaac pointMatOffsets[f][p+1] = 0; 6895d3d1a6afSToby Isaac } 6896d3d1a6afSToby Isaac } 6897d3d1a6afSToby Isaac } 68984b2f2278SToby Isaac for (f = 0, totalOffset = 0, totalMatOffset = 0; f < numFields; f++) { 68994b2f2278SToby Isaac newPointOffsets[f][0] = totalOffset; 69004b2f2278SToby Isaac pointMatOffsets[f][0] = totalMatOffset; 6901d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 6902d3d1a6afSToby Isaac newPointOffsets[f][p+1] += newPointOffsets[f][p]; 6903d3d1a6afSToby Isaac pointMatOffsets[f][p+1] += pointMatOffsets[f][p]; 6904d3d1a6afSToby Isaac } 690519f70fd5SToby Isaac totalOffset = newPointOffsets[f][numPoints]; 690619f70fd5SToby Isaac totalMatOffset = pointMatOffsets[f][numPoints]; 690769291d52SBarry Smith ierr = DMGetWorkArray(dm,pointMatOffsets[f][numPoints],MPIU_SCALAR,&pointMat[f]);CHKERRQ(ierr); 6908d3d1a6afSToby Isaac } 6909d3d1a6afSToby Isaac } 6910d3d1a6afSToby Isaac else { 6911d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 6912d3d1a6afSToby Isaac PetscInt b = points[2*p]; 69134b2f2278SToby Isaac PetscInt bDof = 0, bSecDof; 6914d3d1a6afSToby Isaac 69154b2f2278SToby Isaac ierr = PetscSectionGetDof(section,b,&bSecDof);CHKERRQ(ierr); 69164b2f2278SToby Isaac if (!bSecDof) { 69174b2f2278SToby Isaac newPointOffsets[0][p + 1] = 0; 69184b2f2278SToby Isaac pointMatOffsets[0][p + 1] = 0; 69194b2f2278SToby Isaac continue; 69204b2f2278SToby Isaac } 6921d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 6922d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec, b, &bDof);CHKERRQ(ierr); 6923d3d1a6afSToby Isaac } 6924d3d1a6afSToby Isaac if (bDof) { 69254b2f2278SToby Isaac PetscInt bOff, q, allDof = 0; 6926d3d1a6afSToby Isaac 6927d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(aSec, b, &bOff);CHKERRQ(ierr); 6928d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 6929d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q], aDof; 6930d3d1a6afSToby Isaac 6931d3d1a6afSToby Isaac ierr = PetscSectionGetDof(section, a, &aDof);CHKERRQ(ierr); 6932d3d1a6afSToby Isaac allDof += aDof; 6933d3d1a6afSToby Isaac } 6934d3d1a6afSToby Isaac newPointOffsets[0][p+1] = allDof; 69354b2f2278SToby Isaac pointMatOffsets[0][p+1] = bSecDof * allDof; 6936d3d1a6afSToby Isaac } 6937d3d1a6afSToby Isaac else { 69384b2f2278SToby Isaac newPointOffsets[0][p+1] = bSecDof; 6939d3d1a6afSToby Isaac pointMatOffsets[0][p+1] = 0; 6940d3d1a6afSToby Isaac } 6941d3d1a6afSToby Isaac } 6942d3d1a6afSToby Isaac newPointOffsets[0][0] = 0; 6943d3d1a6afSToby Isaac pointMatOffsets[0][0] = 0; 6944d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 6945d3d1a6afSToby Isaac newPointOffsets[0][p+1] += newPointOffsets[0][p]; 6946d3d1a6afSToby Isaac pointMatOffsets[0][p+1] += pointMatOffsets[0][p]; 6947d3d1a6afSToby Isaac } 694869291d52SBarry Smith ierr = DMGetWorkArray(dm,pointMatOffsets[0][numPoints],MPIU_SCALAR,&pointMat[0]);CHKERRQ(ierr); 6949d3d1a6afSToby Isaac } 6950d3d1a6afSToby Isaac 69516ecaa68aSToby Isaac /* output arrays */ 695269291d52SBarry Smith ierr = DMGetWorkArray(dm,2*newNumPoints,MPIU_INT,&newPoints);CHKERRQ(ierr); 69536ecaa68aSToby Isaac 6954d3d1a6afSToby Isaac /* get the point-to-point matrices; construct newPoints */ 6955d3d1a6afSToby Isaac ierr = PetscSectionGetMaxDof(aSec, &maxAnchor);CHKERRQ(ierr); 6956d3d1a6afSToby Isaac ierr = PetscSectionGetMaxDof(section, &maxDof);CHKERRQ(ierr); 695769291d52SBarry Smith ierr = DMGetWorkArray(dm,maxDof,MPIU_INT,&indices);CHKERRQ(ierr); 695869291d52SBarry Smith ierr = DMGetWorkArray(dm,maxAnchor*maxDof,MPIU_INT,&newIndices);CHKERRQ(ierr); 6959d3d1a6afSToby Isaac if (numFields) { 6960d3d1a6afSToby Isaac for (p = 0, newP = 0; p < numPoints; p++) { 6961d3d1a6afSToby Isaac PetscInt b = points[2*p]; 6962d3d1a6afSToby Isaac PetscInt o = points[2*p+1]; 69634b2f2278SToby Isaac PetscInt bDof = 0, bSecDof; 6964d3d1a6afSToby Isaac 69654b2f2278SToby Isaac ierr = PetscSectionGetDof(section, b, &bSecDof);CHKERRQ(ierr); 69664b2f2278SToby Isaac if (!bSecDof) { 69674b2f2278SToby Isaac continue; 69684b2f2278SToby Isaac } 6969d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 6970d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec, b, &bDof);CHKERRQ(ierr); 6971d3d1a6afSToby Isaac } 6972d3d1a6afSToby Isaac if (bDof) { 6973d3d1a6afSToby Isaac PetscInt fStart[32], fEnd[32], fAnchorStart[32], fAnchorEnd[32], bOff, q; 6974d3d1a6afSToby Isaac 6975d3d1a6afSToby Isaac fStart[0] = 0; 6976d3d1a6afSToby Isaac fEnd[0] = 0; 6977d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 6978d3d1a6afSToby Isaac PetscInt fDof; 6979d3d1a6afSToby Isaac 6980d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(cSec, b, f, &fDof);CHKERRQ(ierr); 6981d3d1a6afSToby Isaac fStart[f+1] = fStart[f] + fDof; 6982d3d1a6afSToby Isaac fEnd[f+1] = fStart[f+1]; 6983d3d1a6afSToby Isaac } 6984d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(cSec, b, &bOff);CHKERRQ(ierr); 698536fa2b79SJed Brown ierr = DMPlexGetIndicesPointFields_Internal(cSec, PETSC_TRUE, b, bOff, fEnd, PETSC_TRUE, perms, p, NULL, indices);CHKERRQ(ierr); 6986d3d1a6afSToby Isaac 6987d3d1a6afSToby Isaac fAnchorStart[0] = 0; 6988d3d1a6afSToby Isaac fAnchorEnd[0] = 0; 6989d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 6990d3d1a6afSToby Isaac PetscInt fDof = newPointOffsets[f][p + 1] - newPointOffsets[f][p]; 6991d3d1a6afSToby Isaac 6992d3d1a6afSToby Isaac fAnchorStart[f+1] = fAnchorStart[f] + fDof; 6993d3d1a6afSToby Isaac fAnchorEnd[f+1] = fAnchorStart[f + 1]; 6994d3d1a6afSToby Isaac } 6995d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(aSec, b, &bOff);CHKERRQ(ierr); 6996d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 6997d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q], aOff; 6998d3d1a6afSToby Isaac 6999d3d1a6afSToby 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 */ 7000d3d1a6afSToby Isaac newPoints[2*(newP + q)] = a; 7001d3d1a6afSToby Isaac newPoints[2*(newP + q) + 1] = 0; 7002302440fdSBarry Smith ierr = PetscSectionGetOffset(section, a, &aOff);CHKERRQ(ierr); 700336fa2b79SJed Brown ierr = DMPlexGetIndicesPointFields_Internal(section, PETSC_TRUE, a, aOff, fAnchorEnd, PETSC_TRUE, NULL, -1, NULL, newIndices);CHKERRQ(ierr); 7004d3d1a6afSToby Isaac } 7005d3d1a6afSToby Isaac newP += bDof; 7006d3d1a6afSToby Isaac 70076ecaa68aSToby Isaac if (outValues) { 7008d3d1a6afSToby Isaac /* get the point-to-point submatrix */ 7009d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 7010d3d1a6afSToby 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); 7011d3d1a6afSToby Isaac } 7012d3d1a6afSToby Isaac } 70136ecaa68aSToby Isaac } 7014d3d1a6afSToby Isaac else { 7015d3d1a6afSToby Isaac newPoints[2 * newP] = b; 7016d3d1a6afSToby Isaac newPoints[2 * newP + 1] = o; 7017d3d1a6afSToby Isaac newP++; 7018d3d1a6afSToby Isaac } 7019d3d1a6afSToby Isaac } 7020d3d1a6afSToby Isaac } else { 7021d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 7022d3d1a6afSToby Isaac PetscInt b = points[2*p]; 7023d3d1a6afSToby Isaac PetscInt o = points[2*p+1]; 70244b2f2278SToby Isaac PetscInt bDof = 0, bSecDof; 7025d3d1a6afSToby Isaac 70264b2f2278SToby Isaac ierr = PetscSectionGetDof(section, b, &bSecDof);CHKERRQ(ierr); 70274b2f2278SToby Isaac if (!bSecDof) { 70284b2f2278SToby Isaac continue; 70294b2f2278SToby Isaac } 7030d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 7031d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec, b, &bDof);CHKERRQ(ierr); 7032d3d1a6afSToby Isaac } 7033d3d1a6afSToby Isaac if (bDof) { 7034d3d1a6afSToby Isaac PetscInt bEnd = 0, bAnchorEnd = 0, bOff; 7035d3d1a6afSToby Isaac 7036d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(cSec, b, &bOff);CHKERRQ(ierr); 703736fa2b79SJed Brown ierr = DMPlexGetIndicesPoint_Internal(cSec, PETSC_TRUE, b, bOff, &bEnd, PETSC_TRUE, (perms && perms[0]) ? perms[0][p] : NULL, NULL, indices);CHKERRQ(ierr); 7038d3d1a6afSToby Isaac 7039d3d1a6afSToby Isaac ierr = PetscSectionGetOffset (aSec, b, &bOff);CHKERRQ(ierr); 7040d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 7041d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q], aOff; 7042d3d1a6afSToby Isaac 7043d3d1a6afSToby 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 */ 7044d3d1a6afSToby Isaac 7045d3d1a6afSToby Isaac newPoints[2*(newP + q)] = a; 7046d3d1a6afSToby Isaac newPoints[2*(newP + q) + 1] = 0; 7047302440fdSBarry Smith ierr = PetscSectionGetOffset(section, a, &aOff);CHKERRQ(ierr); 704836fa2b79SJed Brown ierr = DMPlexGetIndicesPoint_Internal(section, PETSC_TRUE, a, aOff, &bAnchorEnd, PETSC_TRUE, NULL, NULL, newIndices);CHKERRQ(ierr); 7049d3d1a6afSToby Isaac } 7050d3d1a6afSToby Isaac newP += bDof; 7051d3d1a6afSToby Isaac 7052d3d1a6afSToby Isaac /* get the point-to-point submatrix */ 70536ecaa68aSToby Isaac if (outValues) { 7054d3d1a6afSToby Isaac ierr = MatGetValues(cMat,bEnd,indices,bAnchorEnd,newIndices,pointMat[0] + pointMatOffsets[0][p]);CHKERRQ(ierr); 7055d3d1a6afSToby Isaac } 70566ecaa68aSToby Isaac } 7057d3d1a6afSToby Isaac else { 7058d3d1a6afSToby Isaac newPoints[2 * newP] = b; 7059d3d1a6afSToby Isaac newPoints[2 * newP + 1] = o; 7060d3d1a6afSToby Isaac newP++; 7061d3d1a6afSToby Isaac } 7062d3d1a6afSToby Isaac } 7063d3d1a6afSToby Isaac } 7064d3d1a6afSToby Isaac 70656ecaa68aSToby Isaac if (outValues) { 706669291d52SBarry Smith ierr = DMGetWorkArray(dm,newNumIndices*numIndices,MPIU_SCALAR,&tmpValues);CHKERRQ(ierr); 7067580bdb30SBarry Smith ierr = PetscArrayzero(tmpValues,newNumIndices*numIndices);CHKERRQ(ierr); 7068d3d1a6afSToby Isaac /* multiply constraints on the right */ 7069d3d1a6afSToby Isaac if (numFields) { 7070d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 7071d3d1a6afSToby Isaac PetscInt oldOff = offsets[f]; 7072d3d1a6afSToby Isaac 7073d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 7074d3d1a6afSToby Isaac PetscInt cStart = newPointOffsets[f][p]; 7075d3d1a6afSToby Isaac PetscInt b = points[2 * p]; 7076d3d1a6afSToby Isaac PetscInt c, r, k; 7077d3d1a6afSToby Isaac PetscInt dof; 7078d3d1a6afSToby Isaac 7079d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section,b,f,&dof);CHKERRQ(ierr); 70804b2f2278SToby Isaac if (!dof) { 70814b2f2278SToby Isaac continue; 70824b2f2278SToby Isaac } 7083d3d1a6afSToby Isaac if (pointMatOffsets[f][p] < pointMatOffsets[f][p + 1]) { 7084d3d1a6afSToby Isaac PetscInt nCols = newPointOffsets[f][p+1]-cStart; 7085d3d1a6afSToby Isaac const PetscScalar *mat = pointMat[f] + pointMatOffsets[f][p]; 7086d3d1a6afSToby Isaac 7087d3d1a6afSToby Isaac for (r = 0; r < numIndices; r++) { 7088d3d1a6afSToby Isaac for (c = 0; c < nCols; c++) { 7089d3d1a6afSToby Isaac for (k = 0; k < dof; k++) { 70904acb8e1eSToby Isaac tmpValues[r * newNumIndices + cStart + c] += values[r * numIndices + oldOff + k] * mat[k * nCols + c]; 7091d3d1a6afSToby Isaac } 7092d3d1a6afSToby Isaac } 7093d3d1a6afSToby Isaac } 7094d3d1a6afSToby Isaac } 7095d3d1a6afSToby Isaac else { 7096d3d1a6afSToby Isaac /* copy this column as is */ 7097d3d1a6afSToby Isaac for (r = 0; r < numIndices; r++) { 7098d3d1a6afSToby Isaac for (c = 0; c < dof; c++) { 7099d3d1a6afSToby Isaac tmpValues[r * newNumIndices + cStart + c] = values[r * numIndices + oldOff + c]; 7100d3d1a6afSToby Isaac } 7101d3d1a6afSToby Isaac } 7102d3d1a6afSToby Isaac } 7103d3d1a6afSToby Isaac oldOff += dof; 7104d3d1a6afSToby Isaac } 7105d3d1a6afSToby Isaac } 7106d3d1a6afSToby Isaac } 7107d3d1a6afSToby Isaac else { 7108d3d1a6afSToby Isaac PetscInt oldOff = 0; 7109d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 7110d3d1a6afSToby Isaac PetscInt cStart = newPointOffsets[0][p]; 7111d3d1a6afSToby Isaac PetscInt b = points[2 * p]; 7112d3d1a6afSToby Isaac PetscInt c, r, k; 7113d3d1a6afSToby Isaac PetscInt dof; 7114d3d1a6afSToby Isaac 7115d3d1a6afSToby Isaac ierr = PetscSectionGetDof(section,b,&dof);CHKERRQ(ierr); 71164b2f2278SToby Isaac if (!dof) { 71174b2f2278SToby Isaac continue; 71184b2f2278SToby Isaac } 7119d3d1a6afSToby Isaac if (pointMatOffsets[0][p] < pointMatOffsets[0][p + 1]) { 7120d3d1a6afSToby Isaac PetscInt nCols = newPointOffsets[0][p+1]-cStart; 7121d3d1a6afSToby Isaac const PetscScalar *mat = pointMat[0] + pointMatOffsets[0][p]; 7122d3d1a6afSToby Isaac 7123d3d1a6afSToby Isaac for (r = 0; r < numIndices; r++) { 7124d3d1a6afSToby Isaac for (c = 0; c < nCols; c++) { 7125d3d1a6afSToby Isaac for (k = 0; k < dof; k++) { 7126d3d1a6afSToby Isaac tmpValues[r * newNumIndices + cStart + c] += mat[k * nCols + c] * values[r * numIndices + oldOff + k]; 7127d3d1a6afSToby Isaac } 7128d3d1a6afSToby Isaac } 7129d3d1a6afSToby Isaac } 7130d3d1a6afSToby Isaac } 7131d3d1a6afSToby Isaac else { 7132d3d1a6afSToby Isaac /* copy this column as is */ 7133d3d1a6afSToby Isaac for (r = 0; r < numIndices; r++) { 7134d3d1a6afSToby Isaac for (c = 0; c < dof; c++) { 7135d3d1a6afSToby Isaac tmpValues[r * newNumIndices + cStart + c] = values[r * numIndices + oldOff + c]; 7136d3d1a6afSToby Isaac } 7137d3d1a6afSToby Isaac } 7138d3d1a6afSToby Isaac } 7139d3d1a6afSToby Isaac oldOff += dof; 7140d3d1a6afSToby Isaac } 7141d3d1a6afSToby Isaac } 7142d3d1a6afSToby Isaac 71436ecaa68aSToby Isaac if (multiplyLeft) { 714469291d52SBarry Smith ierr = DMGetWorkArray(dm,newNumIndices*newNumIndices,MPIU_SCALAR,&newValues);CHKERRQ(ierr); 7145580bdb30SBarry Smith ierr = PetscArrayzero(newValues,newNumIndices*newNumIndices);CHKERRQ(ierr); 7146d3d1a6afSToby Isaac /* multiply constraints transpose on the left */ 7147d3d1a6afSToby Isaac if (numFields) { 7148d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 7149d3d1a6afSToby Isaac PetscInt oldOff = offsets[f]; 7150d3d1a6afSToby Isaac 7151d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 7152d3d1a6afSToby Isaac PetscInt rStart = newPointOffsets[f][p]; 7153d3d1a6afSToby Isaac PetscInt b = points[2 * p]; 7154d3d1a6afSToby Isaac PetscInt c, r, k; 7155d3d1a6afSToby Isaac PetscInt dof; 7156d3d1a6afSToby Isaac 7157d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section,b,f,&dof);CHKERRQ(ierr); 7158d3d1a6afSToby Isaac if (pointMatOffsets[f][p] < pointMatOffsets[f][p + 1]) { 7159d3d1a6afSToby Isaac PetscInt nRows = newPointOffsets[f][p+1]-rStart; 7160d3d1a6afSToby Isaac const PetscScalar *PETSC_RESTRICT mat = pointMat[f] + pointMatOffsets[f][p]; 7161d3d1a6afSToby Isaac 7162d3d1a6afSToby Isaac for (r = 0; r < nRows; r++) { 7163d3d1a6afSToby Isaac for (c = 0; c < newNumIndices; c++) { 7164d3d1a6afSToby Isaac for (k = 0; k < dof; k++) { 7165d3d1a6afSToby Isaac newValues[(rStart + r) * newNumIndices + c] += mat[k * nRows + r] * tmpValues[(oldOff + k) * newNumIndices + c]; 7166d3d1a6afSToby Isaac } 7167d3d1a6afSToby Isaac } 7168d3d1a6afSToby Isaac } 7169d3d1a6afSToby Isaac } 7170d3d1a6afSToby Isaac else { 7171d3d1a6afSToby Isaac /* copy this row as is */ 7172d3d1a6afSToby Isaac for (r = 0; r < dof; r++) { 7173d3d1a6afSToby Isaac for (c = 0; c < newNumIndices; c++) { 7174d3d1a6afSToby Isaac newValues[(rStart + r) * newNumIndices + c] = tmpValues[(oldOff + r) * newNumIndices + c]; 7175d3d1a6afSToby Isaac } 7176d3d1a6afSToby Isaac } 7177d3d1a6afSToby Isaac } 7178d3d1a6afSToby Isaac oldOff += dof; 7179d3d1a6afSToby Isaac } 7180d3d1a6afSToby Isaac } 7181d3d1a6afSToby Isaac } 7182d3d1a6afSToby Isaac else { 7183d3d1a6afSToby Isaac PetscInt oldOff = 0; 7184d3d1a6afSToby Isaac 7185d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 7186d3d1a6afSToby Isaac PetscInt rStart = newPointOffsets[0][p]; 7187d3d1a6afSToby Isaac PetscInt b = points[2 * p]; 7188d3d1a6afSToby Isaac PetscInt c, r, k; 7189d3d1a6afSToby Isaac PetscInt dof; 7190d3d1a6afSToby Isaac 7191d3d1a6afSToby Isaac ierr = PetscSectionGetDof(section,b,&dof);CHKERRQ(ierr); 7192d3d1a6afSToby Isaac if (pointMatOffsets[0][p] < pointMatOffsets[0][p + 1]) { 7193d3d1a6afSToby Isaac PetscInt nRows = newPointOffsets[0][p+1]-rStart; 7194d3d1a6afSToby Isaac const PetscScalar *PETSC_RESTRICT mat = pointMat[0] + pointMatOffsets[0][p]; 7195d3d1a6afSToby Isaac 7196d3d1a6afSToby Isaac for (r = 0; r < nRows; r++) { 7197d3d1a6afSToby Isaac for (c = 0; c < newNumIndices; c++) { 7198d3d1a6afSToby Isaac for (k = 0; k < dof; k++) { 7199d3d1a6afSToby Isaac newValues[(rStart + r) * newNumIndices + c] += mat[k * nRows + r] * tmpValues[(oldOff + k) * newNumIndices + c]; 7200d3d1a6afSToby Isaac } 7201d3d1a6afSToby Isaac } 7202d3d1a6afSToby Isaac } 7203d3d1a6afSToby Isaac } 7204d3d1a6afSToby Isaac else { 7205d3d1a6afSToby Isaac /* copy this row as is */ 72069fc93327SToby Isaac for (r = 0; r < dof; r++) { 7207d3d1a6afSToby Isaac for (c = 0; c < newNumIndices; c++) { 7208d3d1a6afSToby Isaac newValues[(rStart + r) * newNumIndices + c] = tmpValues[(oldOff + r) * newNumIndices + c]; 7209d3d1a6afSToby Isaac } 7210d3d1a6afSToby Isaac } 7211d3d1a6afSToby Isaac } 7212d3d1a6afSToby Isaac oldOff += dof; 7213d3d1a6afSToby Isaac } 7214d3d1a6afSToby Isaac } 7215d3d1a6afSToby Isaac 721669291d52SBarry Smith ierr = DMRestoreWorkArray(dm,newNumIndices*numIndices,MPIU_SCALAR,&tmpValues);CHKERRQ(ierr); 72176ecaa68aSToby Isaac } 72186ecaa68aSToby Isaac else { 72196ecaa68aSToby Isaac newValues = tmpValues; 72206ecaa68aSToby Isaac } 72216ecaa68aSToby Isaac } 72226ecaa68aSToby Isaac 7223d3d1a6afSToby Isaac /* clean up */ 722469291d52SBarry Smith ierr = DMRestoreWorkArray(dm,maxDof,MPIU_INT,&indices);CHKERRQ(ierr); 722569291d52SBarry Smith ierr = DMRestoreWorkArray(dm,maxAnchor*maxDof,MPIU_INT,&newIndices);CHKERRQ(ierr); 72266ecaa68aSToby Isaac 7227d3d1a6afSToby Isaac if (numFields) { 7228d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 722969291d52SBarry Smith ierr = DMRestoreWorkArray(dm,pointMatOffsets[f][numPoints],MPIU_SCALAR,&pointMat[f]);CHKERRQ(ierr); 723069291d52SBarry Smith ierr = DMRestoreWorkArray(dm,numPoints+1,MPIU_INT,&pointMatOffsets[f]);CHKERRQ(ierr); 723169291d52SBarry Smith ierr = DMRestoreWorkArray(dm,numPoints+1,MPIU_INT,&newPointOffsets[f]);CHKERRQ(ierr); 7232d3d1a6afSToby Isaac } 7233d3d1a6afSToby Isaac } 7234d3d1a6afSToby Isaac else { 723569291d52SBarry Smith ierr = DMRestoreWorkArray(dm,pointMatOffsets[0][numPoints],MPIU_SCALAR,&pointMat[0]);CHKERRQ(ierr); 723669291d52SBarry Smith ierr = DMRestoreWorkArray(dm,numPoints+1,MPIU_INT,&pointMatOffsets[0]);CHKERRQ(ierr); 723769291d52SBarry Smith ierr = DMRestoreWorkArray(dm,numPoints+1,MPIU_INT,&newPointOffsets[0]);CHKERRQ(ierr); 7238d3d1a6afSToby Isaac } 7239d3d1a6afSToby Isaac ierr = ISRestoreIndices(aIS,&anchors);CHKERRQ(ierr); 7240d3d1a6afSToby Isaac 7241d3d1a6afSToby Isaac /* output */ 72426ecaa68aSToby Isaac if (outPoints) { 7243d3d1a6afSToby Isaac *outPoints = newPoints; 72446ecaa68aSToby Isaac } 72456ecaa68aSToby Isaac else { 724669291d52SBarry Smith ierr = DMRestoreWorkArray(dm,2*newNumPoints,MPIU_INT,&newPoints);CHKERRQ(ierr); 72476ecaa68aSToby Isaac } 724831620726SToby Isaac if (outValues) { 7249d3d1a6afSToby Isaac *outValues = newValues; 72506ecaa68aSToby Isaac } 72516ecaa68aSToby Isaac for (f = 0; f <= numFields; f++) { 7252d3d1a6afSToby Isaac offsets[f] = newOffsets[f]; 7253d3d1a6afSToby Isaac } 7254d3d1a6afSToby Isaac PetscFunctionReturn(0); 7255d3d1a6afSToby Isaac } 7256d3d1a6afSToby Isaac 72574a1e0b3eSMatthew G. Knepley /*@C 725871f0bbf9SMatthew G. Knepley DMPlexGetClosureIndices - Gets the global dof indices associated with the closure of the given point within the provided sections. 72597cd05799SMatthew G. Knepley 72607cd05799SMatthew G. Knepley Not collective 72617cd05799SMatthew G. Knepley 72627cd05799SMatthew G. Knepley Input Parameters: 72637cd05799SMatthew G. Knepley + dm - The DM 726471f0bbf9SMatthew G. Knepley . section - The PetscSection describing the points (a local section) 726571f0bbf9SMatthew G. Knepley . idxSection - The PetscSection from which to obtain indices (may be local or global) 726671f0bbf9SMatthew G. Knepley . point - The point defining the closure 726771f0bbf9SMatthew G. Knepley - useClPerm - Use the closure point permutation if available 72687cd05799SMatthew G. Knepley 726971f0bbf9SMatthew G. Knepley Output Parameters: 727071f0bbf9SMatthew G. Knepley + numIndices - The number of dof indices in the closure of point with the input sections 727171f0bbf9SMatthew G. Knepley . indices - The dof indices 727271f0bbf9SMatthew G. Knepley . outOffsets - Array to write the field offsets into, or NULL 727371f0bbf9SMatthew G. Knepley - values - The input values, which may be modified if sign flips are induced by the point symmetries, or NULL 72747cd05799SMatthew G. Knepley 727536fa2b79SJed Brown Notes: 727636fa2b79SJed Brown Must call DMPlexRestoreClosureIndices() to free allocated memory 727736fa2b79SJed Brown 727836fa2b79SJed Brown If idxSection is global, any constrained dofs (see DMAddBoundary(), for example) will get negative indices. The value 727936fa2b79SJed Brown of those indices is not significant. If idxSection is local, the constrained dofs will yield the involution -(idx+1) 728036fa2b79SJed Brown of their index in a local vector. A caller who does not wish to distinguish those points may recover the nonnegative 728136fa2b79SJed Brown indices via involution, -(-(idx+1)+1)==idx. Local indices are provided when idxSection == section, otherwise global 728236fa2b79SJed Brown indices (with the above semantics) are implied. 72837cd05799SMatthew G. Knepley 72847cd05799SMatthew G. Knepley Level: advanced 72857cd05799SMatthew G. Knepley 728636fa2b79SJed Brown .seealso DMPlexRestoreClosureIndices(), DMPlexVecGetClosure(), DMPlexMatSetClosure(), DMGetLocalSection(), DMGetGlobalSection() 72874a1e0b3eSMatthew G. Knepley @*/ 728871f0bbf9SMatthew G. Knepley PetscErrorCode DMPlexGetClosureIndices(DM dm, PetscSection section, PetscSection idxSection, PetscInt point, PetscBool useClPerm, 728971f0bbf9SMatthew G. Knepley PetscInt *numIndices, PetscInt *indices[], PetscInt outOffsets[], PetscScalar *values[]) 72907773e69fSMatthew G. Knepley { 729171f0bbf9SMatthew G. Knepley /* Closure ordering */ 72927773e69fSMatthew G. Knepley PetscSection clSection; 72937773e69fSMatthew G. Knepley IS clPoints; 729471f0bbf9SMatthew G. Knepley const PetscInt *clp; 729571f0bbf9SMatthew G. Knepley PetscInt *points; 729671f0bbf9SMatthew G. Knepley const PetscInt *clperm = NULL; 729771f0bbf9SMatthew G. Knepley /* Dof permutation and sign flips */ 72984acb8e1eSToby Isaac const PetscInt **perms[32] = {NULL}; 729971f0bbf9SMatthew G. Knepley const PetscScalar **flips[32] = {NULL}; 730071f0bbf9SMatthew G. Knepley PetscScalar *valCopy = NULL; 730171f0bbf9SMatthew G. Knepley /* Hanging node constraints */ 730271f0bbf9SMatthew G. Knepley PetscInt *pointsC = NULL; 730371f0bbf9SMatthew G. Knepley PetscScalar *valuesC = NULL; 730471f0bbf9SMatthew G. Knepley PetscInt NclC, NiC; 730571f0bbf9SMatthew G. Knepley 730671f0bbf9SMatthew G. Knepley PetscInt *idx; 730771f0bbf9SMatthew G. Knepley PetscInt Nf, Ncl, Ni = 0, offsets[32], p, f; 730871f0bbf9SMatthew G. Knepley PetscBool isLocal = (section == idxSection) ? PETSC_TRUE : PETSC_FALSE; 73097773e69fSMatthew G. Knepley PetscErrorCode ierr; 73107773e69fSMatthew G. Knepley 731171f0bbf9SMatthew G. Knepley PetscFunctionBeginHot; 73127773e69fSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 73137773e69fSMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 731436fa2b79SJed Brown PetscValidHeaderSpecific(idxSection, PETSC_SECTION_CLASSID, 3); 731571f0bbf9SMatthew G. Knepley if (numIndices) PetscValidPointer(numIndices, 6); 731671f0bbf9SMatthew G. Knepley if (indices) PetscValidPointer(indices, 7); 731771f0bbf9SMatthew G. Knepley if (outOffsets) PetscValidPointer(outOffsets, 8); 731871f0bbf9SMatthew G. Knepley if (values) PetscValidPointer(values, 9); 73197773e69fSMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &Nf);CHKERRQ(ierr); 73207773e69fSMatthew G. Knepley if (Nf > 31) SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Number of fields %D limited to 31", Nf); 7321580bdb30SBarry Smith ierr = PetscArrayzero(offsets, 32);CHKERRQ(ierr); 732271f0bbf9SMatthew G. Knepley /* 1) Get points in closure */ 732371f0bbf9SMatthew G. Knepley ierr = DMPlexGetCompressedClosure(dm, section, point, &Ncl, &points, &clSection, &clPoints, &clp);CHKERRQ(ierr); 7324c459fbc1SJed Brown if (useClPerm) { 7325c459fbc1SJed Brown PetscInt depth, clsize; 7326c459fbc1SJed Brown ierr = DMPlexGetPointDepth(dm, point, &depth);CHKERRQ(ierr); 7327c459fbc1SJed Brown for (clsize=0,p=0; p<Ncl; p++) { 7328c459fbc1SJed Brown PetscInt dof; 7329c459fbc1SJed Brown ierr = PetscSectionGetDof(section, points[2*p], &dof);CHKERRQ(ierr); 7330c459fbc1SJed Brown clsize += dof; 7331c459fbc1SJed Brown } 7332c459fbc1SJed Brown ierr = PetscSectionGetClosureInversePermutation_Internal(section, (PetscObject) dm, depth, clsize, &clperm);CHKERRQ(ierr); 7333c459fbc1SJed Brown } 733471f0bbf9SMatthew G. Knepley /* 2) Get number of indices on these points and field offsets from section */ 733571f0bbf9SMatthew G. Knepley for (p = 0; p < Ncl*2; p += 2) { 73367773e69fSMatthew G. Knepley PetscInt dof, fdof; 73377773e69fSMatthew G. Knepley 73387773e69fSMatthew G. Knepley ierr = PetscSectionGetDof(section, points[p], &dof);CHKERRQ(ierr); 73397773e69fSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 73407773e69fSMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, points[p], f, &fdof);CHKERRQ(ierr); 73417773e69fSMatthew G. Knepley offsets[f+1] += fdof; 73427773e69fSMatthew G. Knepley } 734371f0bbf9SMatthew G. Knepley Ni += dof; 73447773e69fSMatthew G. Knepley } 73457773e69fSMatthew G. Knepley for (f = 1; f < Nf; ++f) offsets[f+1] += offsets[f]; 734671f0bbf9SMatthew G. Knepley if (Nf && offsets[Nf] != Ni) SETERRQ2(PetscObjectComm((PetscObject) dm), PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", offsets[Nf], Ni); 734771f0bbf9SMatthew G. Knepley /* 3) Get symmetries and sign flips. Apply sign flips to values if passed in (only works for square values matrix) */ 734871f0bbf9SMatthew G. Knepley for (f = 0; f < PetscMax(1, Nf); ++f) { 734971f0bbf9SMatthew G. Knepley if (Nf) {ierr = PetscSectionGetFieldPointSyms(section, f, Ncl, points, &perms[f], &flips[f]);CHKERRQ(ierr);} 735071f0bbf9SMatthew G. Knepley else {ierr = PetscSectionGetPointSyms(section, Ncl, points, &perms[f], &flips[f]);CHKERRQ(ierr);} 735171f0bbf9SMatthew G. Knepley /* may need to apply sign changes to the element matrix */ 735271f0bbf9SMatthew G. Knepley if (values && flips[f]) { 735371f0bbf9SMatthew G. Knepley PetscInt foffset = offsets[f]; 73546ecaa68aSToby Isaac 735571f0bbf9SMatthew G. Knepley for (p = 0; p < Ncl; ++p) { 735671f0bbf9SMatthew G. Knepley PetscInt pnt = points[2*p], fdof; 735771f0bbf9SMatthew G. Knepley const PetscScalar *flip = flips[f] ? flips[f][p] : NULL; 735871f0bbf9SMatthew G. Knepley 735971f0bbf9SMatthew G. Knepley if (!Nf) {ierr = PetscSectionGetDof(section, pnt, &fdof);CHKERRQ(ierr);} 736071f0bbf9SMatthew G. Knepley else {ierr = PetscSectionGetFieldDof(section, pnt, f, &fdof);CHKERRQ(ierr);} 736171f0bbf9SMatthew G. Knepley if (flip) { 736271f0bbf9SMatthew G. Knepley PetscInt i, j, k; 736371f0bbf9SMatthew G. Knepley 736471f0bbf9SMatthew G. Knepley if (!valCopy) { 736571f0bbf9SMatthew G. Knepley ierr = DMGetWorkArray(dm, Ni*Ni, MPIU_SCALAR, &valCopy);CHKERRQ(ierr); 736671f0bbf9SMatthew G. Knepley for (j = 0; j < Ni * Ni; ++j) valCopy[j] = (*values)[j]; 736771f0bbf9SMatthew G. Knepley *values = valCopy; 736871f0bbf9SMatthew G. Knepley } 736971f0bbf9SMatthew G. Knepley for (i = 0; i < fdof; ++i) { 737071f0bbf9SMatthew G. Knepley PetscScalar fval = flip[i]; 737171f0bbf9SMatthew G. Knepley 737271f0bbf9SMatthew G. Knepley for (k = 0; k < Ni; ++k) { 737371f0bbf9SMatthew G. Knepley valCopy[Ni * (foffset + i) + k] *= fval; 737471f0bbf9SMatthew G. Knepley valCopy[Ni * k + (foffset + i)] *= fval; 73756ecaa68aSToby Isaac } 73766ecaa68aSToby Isaac } 737771f0bbf9SMatthew G. Knepley } 737871f0bbf9SMatthew G. Knepley foffset += fdof; 737971f0bbf9SMatthew G. Knepley } 738071f0bbf9SMatthew G. Knepley } 738171f0bbf9SMatthew G. Knepley } 738271f0bbf9SMatthew G. Knepley /* 4) Apply hanging node constraints. Get new symmetries and replace all storage with constrained storage */ 738371f0bbf9SMatthew G. Knepley ierr = DMPlexAnchorsModifyMat(dm, section, Ncl, Ni, points, perms, values ? *values : NULL, &NclC, &NiC, &pointsC, values ? &valuesC : NULL, offsets, PETSC_TRUE);CHKERRQ(ierr); 738471f0bbf9SMatthew G. Knepley if (NclC) { 738571f0bbf9SMatthew G. Knepley if (valCopy) {ierr = DMRestoreWorkArray(dm, Ni*Ni, MPIU_SCALAR, &valCopy);CHKERRQ(ierr);} 738671f0bbf9SMatthew G. Knepley for (f = 0; f < PetscMax(1, Nf); ++f) { 738771f0bbf9SMatthew G. Knepley if (Nf) {ierr = PetscSectionRestoreFieldPointSyms(section, f, Ncl, points, &perms[f], &flips[f]);CHKERRQ(ierr);} 738871f0bbf9SMatthew G. Knepley else {ierr = PetscSectionRestorePointSyms(section, Ncl, points, &perms[f], &flips[f]);CHKERRQ(ierr);} 738971f0bbf9SMatthew G. Knepley } 739071f0bbf9SMatthew G. Knepley for (f = 0; f < PetscMax(1, Nf); ++f) { 739171f0bbf9SMatthew G. Knepley if (Nf) {ierr = PetscSectionGetFieldPointSyms(section, f, NclC, pointsC, &perms[f], &flips[f]);CHKERRQ(ierr);} 739271f0bbf9SMatthew G. Knepley else {ierr = PetscSectionGetPointSyms(section, NclC, pointsC, &perms[f], &flips[f]);CHKERRQ(ierr);} 739371f0bbf9SMatthew G. Knepley } 739471f0bbf9SMatthew G. Knepley ierr = DMPlexRestoreCompressedClosure(dm, section, point, &Ncl, &points, &clSection, &clPoints, &clp);CHKERRQ(ierr); 739571f0bbf9SMatthew G. Knepley Ncl = NclC; 739671f0bbf9SMatthew G. Knepley Ni = NiC; 739771f0bbf9SMatthew G. Knepley points = pointsC; 739871f0bbf9SMatthew G. Knepley if (values) *values = valuesC; 739971f0bbf9SMatthew G. Knepley } 740071f0bbf9SMatthew G. Knepley /* 5) Calculate indices */ 740171f0bbf9SMatthew G. Knepley ierr = DMGetWorkArray(dm, Ni, MPIU_INT, &idx);CHKERRQ(ierr); 740271f0bbf9SMatthew G. Knepley if (Nf) { 740371f0bbf9SMatthew G. Knepley PetscInt idxOff; 740471f0bbf9SMatthew G. Knepley PetscBool useFieldOffsets; 740571f0bbf9SMatthew G. Knepley 740671f0bbf9SMatthew G. Knepley if (outOffsets) {for (f = 0; f <= Nf; f++) outOffsets[f] = offsets[f];} 740771f0bbf9SMatthew G. Knepley ierr = PetscSectionGetUseFieldOffsets(idxSection, &useFieldOffsets);CHKERRQ(ierr); 740871f0bbf9SMatthew G. Knepley if (useFieldOffsets) { 740971f0bbf9SMatthew G. Knepley for (p = 0; p < Ncl; ++p) { 741071f0bbf9SMatthew G. Knepley const PetscInt pnt = points[p*2]; 741171f0bbf9SMatthew G. Knepley 741271f0bbf9SMatthew G. Knepley ierr = DMPlexGetIndicesPointFieldsSplit_Internal(section, idxSection, pnt, offsets, perms, p, clperm, idx);CHKERRQ(ierr); 74137773e69fSMatthew G. Knepley } 74147773e69fSMatthew G. Knepley } else { 741571f0bbf9SMatthew G. Knepley for (p = 0; p < Ncl; ++p) { 741671f0bbf9SMatthew G. Knepley const PetscInt pnt = points[p*2]; 741771f0bbf9SMatthew G. Knepley 741871f0bbf9SMatthew G. Knepley ierr = PetscSectionGetOffset(idxSection, pnt, &idxOff);CHKERRQ(ierr); 741971f0bbf9SMatthew G. Knepley /* Note that we pass a local section even though we're using global offsets. This is because global sections do 742071f0bbf9SMatthew G. Knepley * not (at the time of this writing) have fields set. They probably should, in which case we would pass the 742171f0bbf9SMatthew G. Knepley * global section. */ 742271f0bbf9SMatthew G. Knepley ierr = DMPlexGetIndicesPointFields_Internal(section, isLocal, pnt, idxOff < 0 ? -(idxOff+1) : idxOff, offsets, PETSC_FALSE, perms, p, clperm, idx);CHKERRQ(ierr); 742371f0bbf9SMatthew G. Knepley } 742471f0bbf9SMatthew G. Knepley } 742571f0bbf9SMatthew G. Knepley } else { 742671f0bbf9SMatthew G. Knepley PetscInt off = 0, idxOff; 742771f0bbf9SMatthew G. Knepley 742871f0bbf9SMatthew G. Knepley for (p = 0; p < Ncl; ++p) { 742971f0bbf9SMatthew G. Knepley const PetscInt pnt = points[p*2]; 74304acb8e1eSToby Isaac const PetscInt *perm = perms[0] ? perms[0][p] : NULL; 74314acb8e1eSToby Isaac 743271f0bbf9SMatthew G. Knepley ierr = PetscSectionGetOffset(idxSection, pnt, &idxOff);CHKERRQ(ierr); 743371f0bbf9SMatthew G. Knepley /* Note that we pass a local section even though we're using global offsets. This is because global sections do 743471f0bbf9SMatthew G. Knepley * not (at the time of this writing) have fields set. They probably should, in which case we would pass the global section. */ 743571f0bbf9SMatthew G. Knepley ierr = DMPlexGetIndicesPoint_Internal(section, isLocal, pnt, idxOff < 0 ? -(idxOff+1) : idxOff, &off, PETSC_FALSE, perm, clperm, idx);CHKERRQ(ierr); 74367773e69fSMatthew G. Knepley } 74377773e69fSMatthew G. Knepley } 743871f0bbf9SMatthew G. Knepley /* 6) Cleanup */ 743971f0bbf9SMatthew G. Knepley for (f = 0; f < PetscMax(1, Nf); ++f) { 744071f0bbf9SMatthew G. Knepley if (Nf) {ierr = PetscSectionRestoreFieldPointSyms(section, f, Ncl, points, &perms[f], &flips[f]);CHKERRQ(ierr);} 744171f0bbf9SMatthew G. Knepley else {ierr = PetscSectionRestorePointSyms(section, Ncl, points, &perms[f], &flips[f]);CHKERRQ(ierr);} 74424acb8e1eSToby Isaac } 744371f0bbf9SMatthew G. Knepley if (NclC) { 744471f0bbf9SMatthew G. Knepley ierr = DMRestoreWorkArray(dm, NclC*2, MPIU_INT, &pointsC);CHKERRQ(ierr); 74457773e69fSMatthew G. Knepley } else { 744671f0bbf9SMatthew G. Knepley ierr = DMPlexRestoreCompressedClosure(dm, section, point, &Ncl, &points, &clSection, &clPoints, &clp);CHKERRQ(ierr); 74477773e69fSMatthew G. Knepley } 744871f0bbf9SMatthew G. Knepley 744971f0bbf9SMatthew G. Knepley if (numIndices) *numIndices = Ni; 745071f0bbf9SMatthew G. Knepley if (indices) *indices = idx; 74517773e69fSMatthew G. Knepley PetscFunctionReturn(0); 74527773e69fSMatthew G. Knepley } 74537773e69fSMatthew G. Knepley 74547cd05799SMatthew G. Knepley /*@C 745571f0bbf9SMatthew G. Knepley DMPlexRestoreClosureIndices - Restores the global dof indices associated with the closure of the given point within the provided sections. 74567cd05799SMatthew G. Knepley 74577cd05799SMatthew G. Knepley Not collective 74587cd05799SMatthew G. Knepley 74597cd05799SMatthew G. Knepley Input Parameters: 74607cd05799SMatthew G. Knepley + dm - The DM 746171f0bbf9SMatthew G. Knepley . section - The PetscSection describing the points (a local section) 746271f0bbf9SMatthew G. Knepley . idxSection - The PetscSection from which to obtain indices (may be local or global) 746371f0bbf9SMatthew G. Knepley . point - The point defining the closure 746471f0bbf9SMatthew G. Knepley - useClPerm - Use the closure point permutation if available 746571f0bbf9SMatthew G. Knepley 746671f0bbf9SMatthew G. Knepley Output Parameters: 746771f0bbf9SMatthew G. Knepley + numIndices - The number of dof indices in the closure of point with the input sections 746871f0bbf9SMatthew G. Knepley . indices - The dof indices 746971f0bbf9SMatthew G. Knepley . outOffsets - Array to write the field offsets into, or NULL 747071f0bbf9SMatthew G. Knepley - values - The input values, which may be modified if sign flips are induced by the point symmetries, or NULL 747171f0bbf9SMatthew G. Knepley 747271f0bbf9SMatthew G. Knepley Notes: 747371f0bbf9SMatthew G. Knepley If values were modified, the user is responsible for calling DMRestoreWorkArray(dm, 0, MPIU_SCALAR, &values). 747471f0bbf9SMatthew G. Knepley 747571f0bbf9SMatthew G. Knepley If idxSection is global, any constrained dofs (see DMAddBoundary(), for example) will get negative indices. The value 747671f0bbf9SMatthew G. Knepley of those indices is not significant. If idxSection is local, the constrained dofs will yield the involution -(idx+1) 747771f0bbf9SMatthew G. Knepley of their index in a local vector. A caller who does not wish to distinguish those points may recover the nonnegative 747871f0bbf9SMatthew G. Knepley indices via involution, -(-(idx+1)+1)==idx. Local indices are provided when idxSection == section, otherwise global 747971f0bbf9SMatthew G. Knepley indices (with the above semantics) are implied. 74807cd05799SMatthew G. Knepley 74817cd05799SMatthew G. Knepley Level: advanced 74827cd05799SMatthew G. Knepley 748371f0bbf9SMatthew G. Knepley .seealso DMPlexGetClosureIndices(), DMPlexVecGetClosure(), DMPlexMatSetClosure(), DMGetLocalSection(), DMGetGlobalSection() 74847cd05799SMatthew G. Knepley @*/ 748571f0bbf9SMatthew G. Knepley PetscErrorCode DMPlexRestoreClosureIndices(DM dm, PetscSection section, PetscSection idxSection, PetscInt point, PetscBool useClPerm, 748671f0bbf9SMatthew G. Knepley PetscInt *numIndices, PetscInt *indices[], PetscInt outOffsets[], PetscScalar *values[]) 74877773e69fSMatthew G. Knepley { 74887773e69fSMatthew G. Knepley PetscErrorCode ierr; 74897773e69fSMatthew G. Knepley 74907773e69fSMatthew G. Knepley PetscFunctionBegin; 74917773e69fSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7492064a246eSJacob Faibussowitsch PetscValidPointer(indices, 7); 749369291d52SBarry Smith ierr = DMRestoreWorkArray(dm, 0, MPIU_INT, indices);CHKERRQ(ierr); 74947773e69fSMatthew G. Knepley PetscFunctionReturn(0); 74957773e69fSMatthew G. Knepley } 74967773e69fSMatthew G. Knepley 74977f5d1fdeSMatthew G. Knepley /*@C 74987f5d1fdeSMatthew G. Knepley DMPlexMatSetClosure - Set an array of the values on the closure of 'point' 74997f5d1fdeSMatthew G. Knepley 75007f5d1fdeSMatthew G. Knepley Not collective 75017f5d1fdeSMatthew G. Knepley 75027f5d1fdeSMatthew G. Knepley Input Parameters: 75037f5d1fdeSMatthew G. Knepley + dm - The DM 7504ebd6d717SJed Brown . section - The section describing the layout in v, or NULL to use the default section 7505ebd6d717SJed Brown . globalSection - The section describing the layout in v, or NULL to use the default global section 75067f5d1fdeSMatthew G. Knepley . A - The matrix 7507eaf898f9SPatrick Sanan . point - The point in the DM 75087f5d1fdeSMatthew G. Knepley . values - The array of values 75097f5d1fdeSMatthew G. Knepley - mode - The insert mode, where INSERT_ALL_VALUES and ADD_ALL_VALUES also overwrite boundary conditions 75107f5d1fdeSMatthew G. Knepley 75117f5d1fdeSMatthew G. Knepley Fortran Notes: 75127f5d1fdeSMatthew G. Knepley This routine is only available in Fortran 90, and you must include petsc.h90 in your code. 75137f5d1fdeSMatthew G. Knepley 75147f5d1fdeSMatthew G. Knepley Level: intermediate 75157f5d1fdeSMatthew G. Knepley 75164a1e0b3eSMatthew G. Knepley .seealso DMPlexMatSetClosureGeneral(), DMPlexVecGetClosure(), DMPlexVecSetClosure() 75177f5d1fdeSMatthew G. Knepley @*/ 75187c1f9639SMatthew G Knepley PetscErrorCode DMPlexMatSetClosure(DM dm, PetscSection section, PetscSection globalSection, Mat A, PetscInt point, const PetscScalar values[], InsertMode mode) 7519552f7358SJed Brown { 7520552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 7521552f7358SJed Brown PetscInt *indices; 752271f0bbf9SMatthew G. Knepley PetscInt numIndices; 752371f0bbf9SMatthew G. Knepley const PetscScalar *valuesOrig = values; 7524552f7358SJed Brown PetscErrorCode ierr; 7525552f7358SJed Brown 7526552f7358SJed Brown PetscFunctionBegin; 7527552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 752892fd8e1eSJed Brown if (!section) {ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr);} 75293dc93601SMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 7530e87a4003SBarry Smith if (!globalSection) {ierr = DMGetGlobalSection(dm, &globalSection);CHKERRQ(ierr);} 75313dc93601SMatthew G. Knepley PetscValidHeaderSpecific(globalSection, PETSC_SECTION_CLASSID, 3); 75323dc93601SMatthew G. Knepley PetscValidHeaderSpecific(A, MAT_CLASSID, 4); 7533552f7358SJed Brown 753471f0bbf9SMatthew G. Knepley ierr = DMPlexGetClosureIndices(dm, section, globalSection, point, PETSC_TRUE, &numIndices, &indices, NULL, (PetscScalar **) &values);CHKERRQ(ierr); 75350d644c17SKarl Rupp 7536b0ecff45SMatthew G. Knepley if (mesh->printSetValues) {ierr = DMPlexPrintMatSetValues(PETSC_VIEWER_STDOUT_SELF, A, point, numIndices, indices, 0, NULL, values);CHKERRQ(ierr);} 75374a1e0b3eSMatthew G. Knepley ierr = MatSetValues(A, numIndices, indices, numIndices, indices, values, mode); 7538552f7358SJed Brown if (ierr) { 7539552f7358SJed Brown PetscMPIInt rank; 7540552f7358SJed Brown PetscErrorCode ierr2; 7541552f7358SJed Brown 754255b25c41SPierre Jolivet ierr2 = MPI_Comm_rank(PetscObjectComm((PetscObject)A), &rank);CHKERRMPI(ierr2); 7543e4b003c7SBarry Smith ierr2 = (*PetscErrorPrintf)("[%d]ERROR in DMPlexMatSetClosure\n", rank);CHKERRQ(ierr2); 7544b0ecff45SMatthew G. Knepley ierr2 = DMPlexPrintMatSetValues(PETSC_VIEWER_STDERR_SELF, A, point, numIndices, indices, 0, NULL, values);CHKERRQ(ierr2); 754571f0bbf9SMatthew G. Knepley ierr2 = DMPlexRestoreClosureIndices(dm, section, globalSection, point, PETSC_TRUE, &numIndices, &indices, NULL, (PetscScalar **) &values);CHKERRQ(ierr2); 754671f0bbf9SMatthew G. Knepley if (values != valuesOrig) {ierr2 = DMRestoreWorkArray(dm, 0, MPIU_SCALAR, &values);CHKERRQ(ierr2);} 7547c3e24edfSBarry Smith SETERRQ(PetscObjectComm((PetscObject)dm),ierr,"Not possible to set matrix values"); 7548552f7358SJed Brown } 75494a1e0b3eSMatthew G. Knepley if (mesh->printFEM > 1) { 75504a1e0b3eSMatthew G. Knepley PetscInt i; 75514a1e0b3eSMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " Indices:");CHKERRQ(ierr); 75524a1e0b3eSMatthew G. Knepley for (i = 0; i < numIndices; ++i) {ierr = PetscPrintf(PETSC_COMM_SELF, " %D", indices[i]);CHKERRQ(ierr);} 75534a1e0b3eSMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 75544a1e0b3eSMatthew G. Knepley } 755571f0bbf9SMatthew G. Knepley 755671f0bbf9SMatthew G. Knepley ierr = DMPlexRestoreClosureIndices(dm, section, globalSection, point, PETSC_TRUE, &numIndices, &indices, NULL, (PetscScalar **) &values);CHKERRQ(ierr); 755771f0bbf9SMatthew G. Knepley if (values != valuesOrig) {ierr = DMRestoreWorkArray(dm, 0, MPIU_SCALAR, &values);CHKERRQ(ierr);} 755871f0bbf9SMatthew G. Knepley PetscFunctionReturn(0); 75594acb8e1eSToby Isaac } 756071f0bbf9SMatthew G. Knepley 75614a1e0b3eSMatthew G. Knepley /*@C 75624a1e0b3eSMatthew G. Knepley DMPlexMatSetClosure - Set an array of the values on the closure of 'point' using a different row and column section 75634a1e0b3eSMatthew G. Knepley 75644a1e0b3eSMatthew G. Knepley Not collective 75654a1e0b3eSMatthew G. Knepley 75664a1e0b3eSMatthew G. Knepley Input Parameters: 75674a1e0b3eSMatthew G. Knepley + dmRow - The DM for the row fields 75684a1e0b3eSMatthew G. Knepley . sectionRow - The section describing the layout, or NULL to use the default section in dmRow 75694a1e0b3eSMatthew G. Knepley . globalSectionRow - The section describing the layout, or NULL to use the default global section in dmRow 75704a1e0b3eSMatthew G. Knepley . dmCol - The DM for the column fields 75714a1e0b3eSMatthew G. Knepley . sectionCol - The section describing the layout, or NULL to use the default section in dmCol 75724a1e0b3eSMatthew G. Knepley . globalSectionCol - The section describing the layout, or NULL to use the default global section in dmCol 75734a1e0b3eSMatthew G. Knepley . A - The matrix 75744a1e0b3eSMatthew G. Knepley . point - The point in the DMs 75754a1e0b3eSMatthew G. Knepley . values - The array of values 75764a1e0b3eSMatthew G. Knepley - mode - The insert mode, where INSERT_ALL_VALUES and ADD_ALL_VALUES also overwrite boundary conditions 75774a1e0b3eSMatthew G. Knepley 75784a1e0b3eSMatthew G. Knepley Level: intermediate 75794a1e0b3eSMatthew G. Knepley 75804a1e0b3eSMatthew G. Knepley .seealso DMPlexMatSetClosure(), DMPlexVecGetClosure(), DMPlexVecSetClosure() 75814a1e0b3eSMatthew G. Knepley @*/ 758271f0bbf9SMatthew 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) 758371f0bbf9SMatthew G. Knepley { 758471f0bbf9SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dmRow->data; 758571f0bbf9SMatthew G. Knepley PetscInt *indicesRow, *indicesCol; 758671f0bbf9SMatthew G. Knepley PetscInt numIndicesRow, numIndicesCol; 758771f0bbf9SMatthew G. Knepley const PetscScalar *valuesOrig = values; 758871f0bbf9SMatthew G. Knepley PetscErrorCode ierr; 758971f0bbf9SMatthew G. Knepley 759071f0bbf9SMatthew G. Knepley PetscFunctionBegin; 759171f0bbf9SMatthew G. Knepley PetscValidHeaderSpecific(dmRow, DM_CLASSID, 1); 759271f0bbf9SMatthew G. Knepley if (!sectionRow) {ierr = DMGetLocalSection(dmRow, §ionRow);CHKERRQ(ierr);} 759371f0bbf9SMatthew G. Knepley PetscValidHeaderSpecific(sectionRow, PETSC_SECTION_CLASSID, 2); 759471f0bbf9SMatthew G. Knepley if (!globalSectionRow) {ierr = DMGetGlobalSection(dmRow, &globalSectionRow);CHKERRQ(ierr);} 759571f0bbf9SMatthew G. Knepley PetscValidHeaderSpecific(globalSectionRow, PETSC_SECTION_CLASSID, 3); 759671f0bbf9SMatthew G. Knepley PetscValidHeaderSpecific(dmCol, DM_CLASSID, 4); 759771f0bbf9SMatthew G. Knepley if (!sectionCol) {ierr = DMGetLocalSection(dmCol, §ionCol);CHKERRQ(ierr);} 759871f0bbf9SMatthew G. Knepley PetscValidHeaderSpecific(sectionCol, PETSC_SECTION_CLASSID, 5); 759971f0bbf9SMatthew G. Knepley if (!globalSectionCol) {ierr = DMGetGlobalSection(dmCol, &globalSectionCol);CHKERRQ(ierr);} 760071f0bbf9SMatthew G. Knepley PetscValidHeaderSpecific(globalSectionCol, PETSC_SECTION_CLASSID, 6); 760171f0bbf9SMatthew G. Knepley PetscValidHeaderSpecific(A, MAT_CLASSID, 7); 760271f0bbf9SMatthew G. Knepley 760371f0bbf9SMatthew G. Knepley ierr = DMPlexGetClosureIndices(dmRow, sectionRow, globalSectionRow, point, PETSC_TRUE, &numIndicesRow, &indicesRow, NULL, (PetscScalar **) &values);CHKERRQ(ierr); 760471f0bbf9SMatthew G. Knepley ierr = DMPlexGetClosureIndices(dmCol, sectionCol, globalSectionCol, point, PETSC_TRUE, &numIndicesCol, &indicesCol, NULL, (PetscScalar **) &values);CHKERRQ(ierr); 760571f0bbf9SMatthew G. Knepley 760671f0bbf9SMatthew G. Knepley if (mesh->printSetValues) {ierr = DMPlexPrintMatSetValues(PETSC_VIEWER_STDOUT_SELF, A, point, numIndicesRow, indicesRow, numIndicesCol, indicesCol, values);CHKERRQ(ierr);} 76074a1e0b3eSMatthew G. Knepley ierr = MatSetValues(A, numIndicesRow, indicesRow, numIndicesCol, indicesCol, values, mode); 760871f0bbf9SMatthew G. Knepley if (ierr) { 760971f0bbf9SMatthew G. Knepley PetscMPIInt rank; 761071f0bbf9SMatthew G. Knepley PetscErrorCode ierr2; 761171f0bbf9SMatthew G. Knepley 761255b25c41SPierre Jolivet ierr2 = MPI_Comm_rank(PetscObjectComm((PetscObject)A), &rank);CHKERRMPI(ierr2); 761371f0bbf9SMatthew G. Knepley ierr2 = (*PetscErrorPrintf)("[%d]ERROR in DMPlexMatSetClosure\n", rank);CHKERRQ(ierr2); 761471f0bbf9SMatthew G. Knepley ierr2 = DMPlexPrintMatSetValues(PETSC_VIEWER_STDERR_SELF, A, point, numIndicesRow, indicesRow, numIndicesCol, indicesCol, values);CHKERRQ(ierr2); 761571f0bbf9SMatthew G. Knepley ierr2 = DMPlexRestoreClosureIndices(dmRow, sectionRow, globalSectionRow, point, PETSC_TRUE, &numIndicesRow, &indicesRow, NULL, (PetscScalar **) &values);CHKERRQ(ierr2); 761671f0bbf9SMatthew G. Knepley ierr2 = DMPlexRestoreClosureIndices(dmCol, sectionCol, globalSectionCol, point, PETSC_TRUE, &numIndicesCol, &indicesRow, NULL, (PetscScalar **) &values);CHKERRQ(ierr2); 761771f0bbf9SMatthew G. Knepley if (values != valuesOrig) {ierr2 = DMRestoreWorkArray(dmRow, 0, MPIU_SCALAR, &values);CHKERRQ(ierr2);} 761871f0bbf9SMatthew G. Knepley CHKERRQ(ierr); 7619d3d1a6afSToby Isaac } 762071f0bbf9SMatthew G. Knepley 762171f0bbf9SMatthew G. Knepley ierr = DMPlexRestoreClosureIndices(dmRow, sectionRow, globalSectionRow, point, PETSC_TRUE, &numIndicesRow, &indicesRow, NULL, (PetscScalar **) &values);CHKERRQ(ierr); 762271f0bbf9SMatthew G. Knepley ierr = DMPlexRestoreClosureIndices(dmCol, sectionCol, globalSectionCol, point, PETSC_TRUE, &numIndicesCol, &indicesCol, NULL, (PetscScalar **) &values);CHKERRQ(ierr); 762371f0bbf9SMatthew G. Knepley if (values != valuesOrig) {ierr = DMRestoreWorkArray(dmRow, 0, MPIU_SCALAR, &values);CHKERRQ(ierr);} 7624552f7358SJed Brown PetscFunctionReturn(0); 7625552f7358SJed Brown } 7626552f7358SJed Brown 7627de41b84cSMatthew 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) 7628de41b84cSMatthew G. Knepley { 7629de41b84cSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dmf->data; 7630de41b84cSMatthew G. Knepley PetscInt *fpoints = NULL, *ftotpoints = NULL; 7631de41b84cSMatthew G. Knepley PetscInt *cpoints = NULL; 7632de41b84cSMatthew G. Knepley PetscInt *findices, *cindices; 763317c0192bSMatthew G. Knepley const PetscInt *fclperm = NULL, *cclperm = NULL; /* Closure permutations cannot work here */ 7634de41b84cSMatthew G. Knepley PetscInt foffsets[32], coffsets[32]; 7635412e9a14SMatthew G. Knepley DMPolytopeType ct; 76364ca5e9f5SMatthew G. Knepley PetscInt numFields, numSubcells, maxFPoints, numFPoints, numCPoints, numFIndices, numCIndices, dof, off, globalOff, pStart, pEnd, p, q, r, s, f; 7637de41b84cSMatthew G. Knepley PetscErrorCode ierr; 7638de41b84cSMatthew G. Knepley 7639de41b84cSMatthew G. Knepley PetscFunctionBegin; 7640de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(dmf, DM_CLASSID, 1); 7641de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(dmc, DM_CLASSID, 4); 764292fd8e1eSJed Brown if (!fsection) {ierr = DMGetLocalSection(dmf, &fsection);CHKERRQ(ierr);} 7643de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(fsection, PETSC_SECTION_CLASSID, 2); 764492fd8e1eSJed Brown if (!csection) {ierr = DMGetLocalSection(dmc, &csection);CHKERRQ(ierr);} 7645de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(csection, PETSC_SECTION_CLASSID, 5); 7646e87a4003SBarry Smith if (!globalFSection) {ierr = DMGetGlobalSection(dmf, &globalFSection);CHKERRQ(ierr);} 7647de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(globalFSection, PETSC_SECTION_CLASSID, 3); 7648e87a4003SBarry Smith if (!globalCSection) {ierr = DMGetGlobalSection(dmc, &globalCSection);CHKERRQ(ierr);} 7649de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(globalCSection, PETSC_SECTION_CLASSID, 6); 7650de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(A, MAT_CLASSID, 7); 7651de41b84cSMatthew G. Knepley ierr = PetscSectionGetNumFields(fsection, &numFields);CHKERRQ(ierr); 7652de41b84cSMatthew G. Knepley if (numFields > 31) SETERRQ1(PetscObjectComm((PetscObject)dmf), PETSC_ERR_ARG_OUTOFRANGE, "Number of fields %D limited to 31", numFields); 7653580bdb30SBarry Smith ierr = PetscArrayzero(foffsets, 32);CHKERRQ(ierr); 7654580bdb30SBarry Smith ierr = PetscArrayzero(coffsets, 32);CHKERRQ(ierr); 7655de41b84cSMatthew G. Knepley /* Column indices */ 7656de41b84cSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dmc, point, PETSC_TRUE, &numCPoints, &cpoints);CHKERRQ(ierr); 76574ca5e9f5SMatthew G. Knepley maxFPoints = numCPoints; 7658de41b84cSMatthew G. Knepley /* Compress out points not in the section */ 7659de41b84cSMatthew G. Knepley /* TODO: Squeeze out points with 0 dof as well */ 7660de41b84cSMatthew G. Knepley ierr = PetscSectionGetChart(csection, &pStart, &pEnd);CHKERRQ(ierr); 7661de41b84cSMatthew G. Knepley for (p = 0, q = 0; p < numCPoints*2; p += 2) { 7662de41b84cSMatthew G. Knepley if ((cpoints[p] >= pStart) && (cpoints[p] < pEnd)) { 7663de41b84cSMatthew G. Knepley cpoints[q*2] = cpoints[p]; 7664de41b84cSMatthew G. Knepley cpoints[q*2+1] = cpoints[p+1]; 7665de41b84cSMatthew G. Knepley ++q; 7666de41b84cSMatthew G. Knepley } 7667de41b84cSMatthew G. Knepley } 7668de41b84cSMatthew G. Knepley numCPoints = q; 7669de41b84cSMatthew G. Knepley for (p = 0, numCIndices = 0; p < numCPoints*2; p += 2) { 7670de41b84cSMatthew G. Knepley PetscInt fdof; 7671de41b84cSMatthew G. Knepley 7672de41b84cSMatthew G. Knepley ierr = PetscSectionGetDof(csection, cpoints[p], &dof);CHKERRQ(ierr); 76734ca5e9f5SMatthew G. Knepley if (!dof) continue; 7674de41b84cSMatthew G. Knepley for (f = 0; f < numFields; ++f) { 7675de41b84cSMatthew G. Knepley ierr = PetscSectionGetFieldDof(csection, cpoints[p], f, &fdof);CHKERRQ(ierr); 7676de41b84cSMatthew G. Knepley coffsets[f+1] += fdof; 7677de41b84cSMatthew G. Knepley } 7678de41b84cSMatthew G. Knepley numCIndices += dof; 7679de41b84cSMatthew G. Knepley } 7680de41b84cSMatthew G. Knepley for (f = 1; f < numFields; ++f) coffsets[f+1] += coffsets[f]; 7681de41b84cSMatthew G. Knepley /* Row indices */ 7682412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dmc, point, &ct);CHKERRQ(ierr); 7683412e9a14SMatthew G. Knepley { 7684012bc364SMatthew G. Knepley DMPlexTransform tr; 7685012bc364SMatthew G. Knepley DMPolytopeType *rct; 7686012bc364SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt, Nt; 7687012bc364SMatthew G. Knepley 7688012bc364SMatthew G. Knepley ierr = DMPlexTransformCreate(PETSC_COMM_SELF, &tr);CHKERRQ(ierr); 7689012bc364SMatthew G. Knepley ierr = DMPlexTransformSetType(tr, DMPLEXREFINEREGULAR);CHKERRQ(ierr); 7690012bc364SMatthew G. Knepley ierr = DMPlexTransformCellTransform(tr, ct, point, NULL, &Nt, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 7691012bc364SMatthew G. Knepley numSubcells = rsize[Nt-1]; 7692012bc364SMatthew G. Knepley ierr = DMPlexTransformDestroy(&tr);CHKERRQ(ierr); 7693412e9a14SMatthew G. Knepley } 769469291d52SBarry Smith ierr = DMGetWorkArray(dmf, maxFPoints*2*numSubcells, MPIU_INT, &ftotpoints);CHKERRQ(ierr); 7695de41b84cSMatthew G. Knepley for (r = 0, q = 0; r < numSubcells; ++r) { 7696de41b84cSMatthew G. Knepley /* TODO Map from coarse to fine cells */ 7697de41b84cSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dmf, point*numSubcells + r, PETSC_TRUE, &numFPoints, &fpoints);CHKERRQ(ierr); 7698de41b84cSMatthew G. Knepley /* Compress out points not in the section */ 7699de41b84cSMatthew G. Knepley ierr = PetscSectionGetChart(fsection, &pStart, &pEnd);CHKERRQ(ierr); 7700de41b84cSMatthew G. Knepley for (p = 0; p < numFPoints*2; p += 2) { 7701de41b84cSMatthew G. Knepley if ((fpoints[p] >= pStart) && (fpoints[p] < pEnd)) { 77024ca5e9f5SMatthew G. Knepley ierr = PetscSectionGetDof(fsection, fpoints[p], &dof);CHKERRQ(ierr); 77034ca5e9f5SMatthew G. Knepley if (!dof) continue; 77044ca5e9f5SMatthew G. Knepley for (s = 0; s < q; ++s) if (fpoints[p] == ftotpoints[s*2]) break; 77054ca5e9f5SMatthew G. Knepley if (s < q) continue; 7706de41b84cSMatthew G. Knepley ftotpoints[q*2] = fpoints[p]; 7707de41b84cSMatthew G. Knepley ftotpoints[q*2+1] = fpoints[p+1]; 7708de41b84cSMatthew G. Knepley ++q; 7709de41b84cSMatthew G. Knepley } 7710de41b84cSMatthew G. Knepley } 7711de41b84cSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dmf, point, PETSC_TRUE, &numFPoints, &fpoints);CHKERRQ(ierr); 7712de41b84cSMatthew G. Knepley } 7713de41b84cSMatthew G. Knepley numFPoints = q; 7714de41b84cSMatthew G. Knepley for (p = 0, numFIndices = 0; p < numFPoints*2; p += 2) { 7715de41b84cSMatthew G. Knepley PetscInt fdof; 7716de41b84cSMatthew G. Knepley 7717de41b84cSMatthew G. Knepley ierr = PetscSectionGetDof(fsection, ftotpoints[p], &dof);CHKERRQ(ierr); 77184ca5e9f5SMatthew G. Knepley if (!dof) continue; 7719de41b84cSMatthew G. Knepley for (f = 0; f < numFields; ++f) { 7720de41b84cSMatthew G. Knepley ierr = PetscSectionGetFieldDof(fsection, ftotpoints[p], f, &fdof);CHKERRQ(ierr); 7721de41b84cSMatthew G. Knepley foffsets[f+1] += fdof; 7722de41b84cSMatthew G. Knepley } 7723de41b84cSMatthew G. Knepley numFIndices += dof; 7724de41b84cSMatthew G. Knepley } 7725de41b84cSMatthew G. Knepley for (f = 1; f < numFields; ++f) foffsets[f+1] += foffsets[f]; 7726de41b84cSMatthew G. Knepley 77278ccfff9cSToby Isaac if (numFields && foffsets[numFields] != numFIndices) SETERRQ2(PetscObjectComm((PetscObject)dmf), PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", foffsets[numFields], numFIndices); 77288ccfff9cSToby Isaac if (numFields && coffsets[numFields] != numCIndices) SETERRQ2(PetscObjectComm((PetscObject)dmc), PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", coffsets[numFields], numCIndices); 772969291d52SBarry Smith ierr = DMGetWorkArray(dmf, numFIndices, MPIU_INT, &findices);CHKERRQ(ierr); 773069291d52SBarry Smith ierr = DMGetWorkArray(dmc, numCIndices, MPIU_INT, &cindices);CHKERRQ(ierr); 7731de41b84cSMatthew G. Knepley if (numFields) { 77324acb8e1eSToby Isaac const PetscInt **permsF[32] = {NULL}; 77334acb8e1eSToby Isaac const PetscInt **permsC[32] = {NULL}; 77344acb8e1eSToby Isaac 77354acb8e1eSToby Isaac for (f = 0; f < numFields; f++) { 77364acb8e1eSToby Isaac ierr = PetscSectionGetFieldPointSyms(fsection,f,numFPoints,ftotpoints,&permsF[f],NULL);CHKERRQ(ierr); 77374acb8e1eSToby Isaac ierr = PetscSectionGetFieldPointSyms(csection,f,numCPoints,cpoints,&permsC[f],NULL);CHKERRQ(ierr); 7738de41b84cSMatthew G. Knepley } 77394acb8e1eSToby Isaac for (p = 0; p < numFPoints; p++) { 77404acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalFSection, ftotpoints[2*p], &globalOff);CHKERRQ(ierr); 774136fa2b79SJed Brown ierr = DMPlexGetIndicesPointFields_Internal(fsection, PETSC_FALSE, ftotpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, foffsets, PETSC_FALSE, permsF, p, fclperm, findices);CHKERRQ(ierr); 77424acb8e1eSToby Isaac } 77434acb8e1eSToby Isaac for (p = 0; p < numCPoints; p++) { 77444acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalCSection, cpoints[2*p], &globalOff);CHKERRQ(ierr); 774536fa2b79SJed Brown ierr = DMPlexGetIndicesPointFields_Internal(csection, PETSC_FALSE, cpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, coffsets, PETSC_FALSE, permsC, p, cclperm, cindices);CHKERRQ(ierr); 77464acb8e1eSToby Isaac } 77474acb8e1eSToby Isaac for (f = 0; f < numFields; f++) { 77484acb8e1eSToby Isaac ierr = PetscSectionRestoreFieldPointSyms(fsection,f,numFPoints,ftotpoints,&permsF[f],NULL);CHKERRQ(ierr); 77494acb8e1eSToby Isaac ierr = PetscSectionRestoreFieldPointSyms(csection,f,numCPoints,cpoints,&permsC[f],NULL);CHKERRQ(ierr); 7750de41b84cSMatthew G. Knepley } 7751de41b84cSMatthew G. Knepley } else { 77524acb8e1eSToby Isaac const PetscInt **permsF = NULL; 77534acb8e1eSToby Isaac const PetscInt **permsC = NULL; 77544acb8e1eSToby Isaac 77554acb8e1eSToby Isaac ierr = PetscSectionGetPointSyms(fsection,numFPoints,ftotpoints,&permsF,NULL);CHKERRQ(ierr); 77564acb8e1eSToby Isaac ierr = PetscSectionGetPointSyms(csection,numCPoints,cpoints,&permsC,NULL);CHKERRQ(ierr); 77574acb8e1eSToby Isaac for (p = 0, off = 0; p < numFPoints; p++) { 77584acb8e1eSToby Isaac const PetscInt *perm = permsF ? permsF[p] : NULL; 77594acb8e1eSToby Isaac 77604acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalFSection, ftotpoints[2*p], &globalOff);CHKERRQ(ierr); 776136fa2b79SJed Brown ierr = DMPlexGetIndicesPoint_Internal(fsection, PETSC_FALSE, ftotpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, perm, fclperm, findices);CHKERRQ(ierr); 7762de41b84cSMatthew G. Knepley } 77634acb8e1eSToby Isaac for (p = 0, off = 0; p < numCPoints; p++) { 77644acb8e1eSToby Isaac const PetscInt *perm = permsC ? permsC[p] : NULL; 77654acb8e1eSToby Isaac 77664acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalCSection, cpoints[2*p], &globalOff);CHKERRQ(ierr); 776736fa2b79SJed Brown ierr = DMPlexGetIndicesPoint_Internal(csection, PETSC_FALSE, cpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, perm, cclperm, cindices);CHKERRQ(ierr); 7768de41b84cSMatthew G. Knepley } 77694acb8e1eSToby Isaac ierr = PetscSectionRestorePointSyms(fsection,numFPoints,ftotpoints,&permsF,NULL);CHKERRQ(ierr); 77704acb8e1eSToby Isaac ierr = PetscSectionRestorePointSyms(csection,numCPoints,cpoints,&permsC,NULL);CHKERRQ(ierr); 7771de41b84cSMatthew G. Knepley } 7772de41b84cSMatthew G. Knepley if (mesh->printSetValues) {ierr = DMPlexPrintMatSetValues(PETSC_VIEWER_STDOUT_SELF, A, point, numFIndices, findices, numCIndices, cindices, values);CHKERRQ(ierr);} 77734acb8e1eSToby Isaac /* TODO: flips */ 7774de41b84cSMatthew G. Knepley ierr = MatSetValues(A, numFIndices, findices, numCIndices, cindices, values, mode); 7775de41b84cSMatthew G. Knepley if (ierr) { 7776de41b84cSMatthew G. Knepley PetscMPIInt rank; 7777de41b84cSMatthew G. Knepley PetscErrorCode ierr2; 7778de41b84cSMatthew G. Knepley 777955b25c41SPierre Jolivet ierr2 = MPI_Comm_rank(PetscObjectComm((PetscObject)A), &rank);CHKERRMPI(ierr2); 7780e4b003c7SBarry Smith ierr2 = (*PetscErrorPrintf)("[%d]ERROR in DMPlexMatSetClosure\n", rank);CHKERRQ(ierr2); 7781de41b84cSMatthew G. Knepley ierr2 = DMPlexPrintMatSetValues(PETSC_VIEWER_STDERR_SELF, A, point, numFIndices, findices, numCIndices, cindices, values);CHKERRQ(ierr2); 778269291d52SBarry Smith ierr2 = DMRestoreWorkArray(dmf, numFIndices, MPIU_INT, &findices);CHKERRQ(ierr2); 778369291d52SBarry Smith ierr2 = DMRestoreWorkArray(dmc, numCIndices, MPIU_INT, &cindices);CHKERRQ(ierr2); 7784de41b84cSMatthew G. Knepley CHKERRQ(ierr); 7785de41b84cSMatthew G. Knepley } 778669291d52SBarry Smith ierr = DMRestoreWorkArray(dmf, numCPoints*2*4, MPIU_INT, &ftotpoints);CHKERRQ(ierr); 7787de41b84cSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dmc, point, PETSC_TRUE, &numCPoints, &cpoints);CHKERRQ(ierr); 778869291d52SBarry Smith ierr = DMRestoreWorkArray(dmf, numFIndices, MPIU_INT, &findices);CHKERRQ(ierr); 778969291d52SBarry Smith ierr = DMRestoreWorkArray(dmc, numCIndices, MPIU_INT, &cindices);CHKERRQ(ierr); 7790de41b84cSMatthew G. Knepley PetscFunctionReturn(0); 7791de41b84cSMatthew G. Knepley } 7792de41b84cSMatthew G. Knepley 77937c927364SMatthew G. Knepley PetscErrorCode DMPlexMatGetClosureIndicesRefined(DM dmf, PetscSection fsection, PetscSection globalFSection, DM dmc, PetscSection csection, PetscSection globalCSection, PetscInt point, PetscInt cindices[], PetscInt findices[]) 77947c927364SMatthew G. Knepley { 77957c927364SMatthew G. Knepley PetscInt *fpoints = NULL, *ftotpoints = NULL; 77967c927364SMatthew G. Knepley PetscInt *cpoints = NULL; 77977c927364SMatthew G. Knepley PetscInt foffsets[32], coffsets[32]; 779817c0192bSMatthew G. Knepley const PetscInt *fclperm = NULL, *cclperm = NULL; /* Closure permutations cannot work here */ 7799412e9a14SMatthew G. Knepley DMPolytopeType ct; 78007c927364SMatthew G. Knepley PetscInt numFields, numSubcells, maxFPoints, numFPoints, numCPoints, numFIndices, numCIndices, dof, off, globalOff, pStart, pEnd, p, q, r, s, f; 78017c927364SMatthew G. Knepley PetscErrorCode ierr; 78027c927364SMatthew G. Knepley 78037c927364SMatthew G. Knepley PetscFunctionBegin; 78047c927364SMatthew G. Knepley PetscValidHeaderSpecific(dmf, DM_CLASSID, 1); 78057c927364SMatthew G. Knepley PetscValidHeaderSpecific(dmc, DM_CLASSID, 4); 780692fd8e1eSJed Brown if (!fsection) {ierr = DMGetLocalSection(dmf, &fsection);CHKERRQ(ierr);} 78077c927364SMatthew G. Knepley PetscValidHeaderSpecific(fsection, PETSC_SECTION_CLASSID, 2); 780892fd8e1eSJed Brown if (!csection) {ierr = DMGetLocalSection(dmc, &csection);CHKERRQ(ierr);} 78097c927364SMatthew G. Knepley PetscValidHeaderSpecific(csection, PETSC_SECTION_CLASSID, 5); 7810e87a4003SBarry Smith if (!globalFSection) {ierr = DMGetGlobalSection(dmf, &globalFSection);CHKERRQ(ierr);} 78117c927364SMatthew G. Knepley PetscValidHeaderSpecific(globalFSection, PETSC_SECTION_CLASSID, 3); 7812e87a4003SBarry Smith if (!globalCSection) {ierr = DMGetGlobalSection(dmc, &globalCSection);CHKERRQ(ierr);} 78137c927364SMatthew G. Knepley PetscValidHeaderSpecific(globalCSection, PETSC_SECTION_CLASSID, 6); 78147c927364SMatthew G. Knepley ierr = PetscSectionGetNumFields(fsection, &numFields);CHKERRQ(ierr); 78157c927364SMatthew G. Knepley if (numFields > 31) SETERRQ1(PetscObjectComm((PetscObject)dmf), PETSC_ERR_ARG_OUTOFRANGE, "Number of fields %D limited to 31", numFields); 7816580bdb30SBarry Smith ierr = PetscArrayzero(foffsets, 32);CHKERRQ(ierr); 7817580bdb30SBarry Smith ierr = PetscArrayzero(coffsets, 32);CHKERRQ(ierr); 78187c927364SMatthew G. Knepley /* Column indices */ 78197c927364SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dmc, point, PETSC_TRUE, &numCPoints, &cpoints);CHKERRQ(ierr); 78207c927364SMatthew G. Knepley maxFPoints = numCPoints; 78217c927364SMatthew G. Knepley /* Compress out points not in the section */ 78227c927364SMatthew G. Knepley /* TODO: Squeeze out points with 0 dof as well */ 78237c927364SMatthew G. Knepley ierr = PetscSectionGetChart(csection, &pStart, &pEnd);CHKERRQ(ierr); 78247c927364SMatthew G. Knepley for (p = 0, q = 0; p < numCPoints*2; p += 2) { 78257c927364SMatthew G. Knepley if ((cpoints[p] >= pStart) && (cpoints[p] < pEnd)) { 78267c927364SMatthew G. Knepley cpoints[q*2] = cpoints[p]; 78277c927364SMatthew G. Knepley cpoints[q*2+1] = cpoints[p+1]; 78287c927364SMatthew G. Knepley ++q; 78297c927364SMatthew G. Knepley } 78307c927364SMatthew G. Knepley } 78317c927364SMatthew G. Knepley numCPoints = q; 78327c927364SMatthew G. Knepley for (p = 0, numCIndices = 0; p < numCPoints*2; p += 2) { 78337c927364SMatthew G. Knepley PetscInt fdof; 78347c927364SMatthew G. Knepley 78357c927364SMatthew G. Knepley ierr = PetscSectionGetDof(csection, cpoints[p], &dof);CHKERRQ(ierr); 78367c927364SMatthew G. Knepley if (!dof) continue; 78377c927364SMatthew G. Knepley for (f = 0; f < numFields; ++f) { 78387c927364SMatthew G. Knepley ierr = PetscSectionGetFieldDof(csection, cpoints[p], f, &fdof);CHKERRQ(ierr); 78397c927364SMatthew G. Knepley coffsets[f+1] += fdof; 78407c927364SMatthew G. Knepley } 78417c927364SMatthew G. Knepley numCIndices += dof; 78427c927364SMatthew G. Knepley } 78437c927364SMatthew G. Knepley for (f = 1; f < numFields; ++f) coffsets[f+1] += coffsets[f]; 78447c927364SMatthew G. Knepley /* Row indices */ 7845412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dmc, point, &ct);CHKERRQ(ierr); 7846412e9a14SMatthew G. Knepley { 7847012bc364SMatthew G. Knepley DMPlexTransform tr; 7848012bc364SMatthew G. Knepley DMPolytopeType *rct; 7849012bc364SMatthew G. Knepley PetscInt *rsize, *rcone, *rornt, Nt; 7850012bc364SMatthew G. Knepley 7851012bc364SMatthew G. Knepley ierr = DMPlexTransformCreate(PETSC_COMM_SELF, &tr);CHKERRQ(ierr); 7852012bc364SMatthew G. Knepley ierr = DMPlexTransformSetType(tr, DMPLEXREFINEREGULAR);CHKERRQ(ierr); 7853012bc364SMatthew G. Knepley ierr = DMPlexTransformCellTransform(tr, ct, point, NULL, &Nt, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr); 7854012bc364SMatthew G. Knepley numSubcells = rsize[Nt-1]; 7855012bc364SMatthew G. Knepley ierr = DMPlexTransformDestroy(&tr);CHKERRQ(ierr); 7856412e9a14SMatthew G. Knepley } 785769291d52SBarry Smith ierr = DMGetWorkArray(dmf, maxFPoints*2*numSubcells, MPIU_INT, &ftotpoints);CHKERRQ(ierr); 78587c927364SMatthew G. Knepley for (r = 0, q = 0; r < numSubcells; ++r) { 78597c927364SMatthew G. Knepley /* TODO Map from coarse to fine cells */ 78607c927364SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dmf, point*numSubcells + r, PETSC_TRUE, &numFPoints, &fpoints);CHKERRQ(ierr); 78617c927364SMatthew G. Knepley /* Compress out points not in the section */ 78627c927364SMatthew G. Knepley ierr = PetscSectionGetChart(fsection, &pStart, &pEnd);CHKERRQ(ierr); 78637c927364SMatthew G. Knepley for (p = 0; p < numFPoints*2; p += 2) { 78647c927364SMatthew G. Knepley if ((fpoints[p] >= pStart) && (fpoints[p] < pEnd)) { 78657c927364SMatthew G. Knepley ierr = PetscSectionGetDof(fsection, fpoints[p], &dof);CHKERRQ(ierr); 78667c927364SMatthew G. Knepley if (!dof) continue; 78677c927364SMatthew G. Knepley for (s = 0; s < q; ++s) if (fpoints[p] == ftotpoints[s*2]) break; 78687c927364SMatthew G. Knepley if (s < q) continue; 78697c927364SMatthew G. Knepley ftotpoints[q*2] = fpoints[p]; 78707c927364SMatthew G. Knepley ftotpoints[q*2+1] = fpoints[p+1]; 78717c927364SMatthew G. Knepley ++q; 78727c927364SMatthew G. Knepley } 78737c927364SMatthew G. Knepley } 78747c927364SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dmf, point, PETSC_TRUE, &numFPoints, &fpoints);CHKERRQ(ierr); 78757c927364SMatthew G. Knepley } 78767c927364SMatthew G. Knepley numFPoints = q; 78777c927364SMatthew G. Knepley for (p = 0, numFIndices = 0; p < numFPoints*2; p += 2) { 78787c927364SMatthew G. Knepley PetscInt fdof; 78797c927364SMatthew G. Knepley 78807c927364SMatthew G. Knepley ierr = PetscSectionGetDof(fsection, ftotpoints[p], &dof);CHKERRQ(ierr); 78817c927364SMatthew G. Knepley if (!dof) continue; 78827c927364SMatthew G. Knepley for (f = 0; f < numFields; ++f) { 78837c927364SMatthew G. Knepley ierr = PetscSectionGetFieldDof(fsection, ftotpoints[p], f, &fdof);CHKERRQ(ierr); 78847c927364SMatthew G. Knepley foffsets[f+1] += fdof; 78857c927364SMatthew G. Knepley } 78867c927364SMatthew G. Knepley numFIndices += dof; 78877c927364SMatthew G. Knepley } 78887c927364SMatthew G. Knepley for (f = 1; f < numFields; ++f) foffsets[f+1] += foffsets[f]; 78897c927364SMatthew G. Knepley 78908ccfff9cSToby Isaac if (numFields && foffsets[numFields] != numFIndices) SETERRQ2(PetscObjectComm((PetscObject)dmf), PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", foffsets[numFields], numFIndices); 78918ccfff9cSToby Isaac if (numFields && coffsets[numFields] != numCIndices) SETERRQ2(PetscObjectComm((PetscObject)dmc), PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", coffsets[numFields], numCIndices); 78927c927364SMatthew G. Knepley if (numFields) { 78934acb8e1eSToby Isaac const PetscInt **permsF[32] = {NULL}; 78944acb8e1eSToby Isaac const PetscInt **permsC[32] = {NULL}; 78954acb8e1eSToby Isaac 78964acb8e1eSToby Isaac for (f = 0; f < numFields; f++) { 78974acb8e1eSToby Isaac ierr = PetscSectionGetFieldPointSyms(fsection,f,numFPoints,ftotpoints,&permsF[f],NULL);CHKERRQ(ierr); 78984acb8e1eSToby Isaac ierr = PetscSectionGetFieldPointSyms(csection,f,numCPoints,cpoints,&permsC[f],NULL);CHKERRQ(ierr); 78997c927364SMatthew G. Knepley } 79004acb8e1eSToby Isaac for (p = 0; p < numFPoints; p++) { 79014acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalFSection, ftotpoints[2*p], &globalOff);CHKERRQ(ierr); 790236fa2b79SJed Brown ierr = DMPlexGetIndicesPointFields_Internal(fsection, PETSC_FALSE, ftotpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, foffsets, PETSC_FALSE, permsF, p, fclperm, findices);CHKERRQ(ierr); 79034acb8e1eSToby Isaac } 79044acb8e1eSToby Isaac for (p = 0; p < numCPoints; p++) { 79054acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalCSection, cpoints[2*p], &globalOff);CHKERRQ(ierr); 790636fa2b79SJed Brown ierr = DMPlexGetIndicesPointFields_Internal(csection, PETSC_FALSE, cpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, coffsets, PETSC_FALSE, permsC, p, cclperm, cindices);CHKERRQ(ierr); 79074acb8e1eSToby Isaac } 79084acb8e1eSToby Isaac for (f = 0; f < numFields; f++) { 79094acb8e1eSToby Isaac ierr = PetscSectionRestoreFieldPointSyms(fsection,f,numFPoints,ftotpoints,&permsF[f],NULL);CHKERRQ(ierr); 79104acb8e1eSToby Isaac ierr = PetscSectionRestoreFieldPointSyms(csection,f,numCPoints,cpoints,&permsC[f],NULL);CHKERRQ(ierr); 79117c927364SMatthew G. Knepley } 79127c927364SMatthew G. Knepley } else { 79134acb8e1eSToby Isaac const PetscInt **permsF = NULL; 79144acb8e1eSToby Isaac const PetscInt **permsC = NULL; 79154acb8e1eSToby Isaac 79164acb8e1eSToby Isaac ierr = PetscSectionGetPointSyms(fsection,numFPoints,ftotpoints,&permsF,NULL);CHKERRQ(ierr); 79174acb8e1eSToby Isaac ierr = PetscSectionGetPointSyms(csection,numCPoints,cpoints,&permsC,NULL);CHKERRQ(ierr); 79184acb8e1eSToby Isaac for (p = 0, off = 0; p < numFPoints; p++) { 79194acb8e1eSToby Isaac const PetscInt *perm = permsF ? permsF[p] : NULL; 79204acb8e1eSToby Isaac 79214acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalFSection, ftotpoints[2*p], &globalOff);CHKERRQ(ierr); 792236fa2b79SJed Brown ierr = DMPlexGetIndicesPoint_Internal(fsection, PETSC_FALSE, ftotpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, perm, fclperm, findices);CHKERRQ(ierr); 79237c927364SMatthew G. Knepley } 79244acb8e1eSToby Isaac for (p = 0, off = 0; p < numCPoints; p++) { 79254acb8e1eSToby Isaac const PetscInt *perm = permsC ? permsC[p] : NULL; 79264acb8e1eSToby Isaac 79274acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalCSection, cpoints[2*p], &globalOff);CHKERRQ(ierr); 792836fa2b79SJed Brown ierr = DMPlexGetIndicesPoint_Internal(csection, PETSC_FALSE, cpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, perm, cclperm, cindices);CHKERRQ(ierr); 79297c927364SMatthew G. Knepley } 79304acb8e1eSToby Isaac ierr = PetscSectionRestorePointSyms(fsection,numFPoints,ftotpoints,&permsF,NULL);CHKERRQ(ierr); 79314acb8e1eSToby Isaac ierr = PetscSectionRestorePointSyms(csection,numCPoints,cpoints,&permsC,NULL);CHKERRQ(ierr); 79327c927364SMatthew G. Knepley } 793369291d52SBarry Smith ierr = DMRestoreWorkArray(dmf, numCPoints*2*4, MPIU_INT, &ftotpoints);CHKERRQ(ierr); 79347c927364SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dmc, point, PETSC_TRUE, &numCPoints, &cpoints);CHKERRQ(ierr); 79357c927364SMatthew G. Knepley PetscFunctionReturn(0); 79367c927364SMatthew G. Knepley } 79377c927364SMatthew G. Knepley 79387cd05799SMatthew G. Knepley /*@C 79397cd05799SMatthew G. Knepley DMPlexGetVTKCellHeight - Returns the height in the DAG used to determine which points are cells (normally 0) 79407cd05799SMatthew G. Knepley 79417cd05799SMatthew G. Knepley Input Parameter: 79427cd05799SMatthew G. Knepley . dm - The DMPlex object 79437cd05799SMatthew G. Knepley 79447cd05799SMatthew G. Knepley Output Parameter: 79457cd05799SMatthew G. Knepley . cellHeight - The height of a cell 79467cd05799SMatthew G. Knepley 79477cd05799SMatthew G. Knepley Level: developer 79487cd05799SMatthew G. Knepley 79497cd05799SMatthew G. Knepley .seealso DMPlexSetVTKCellHeight() 79507cd05799SMatthew G. Knepley @*/ 7951552f7358SJed Brown PetscErrorCode DMPlexGetVTKCellHeight(DM dm, PetscInt *cellHeight) 7952552f7358SJed Brown { 7953552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 7954552f7358SJed Brown 7955552f7358SJed Brown PetscFunctionBegin; 7956552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7957552f7358SJed Brown PetscValidPointer(cellHeight, 2); 7958552f7358SJed Brown *cellHeight = mesh->vtkCellHeight; 7959552f7358SJed Brown PetscFunctionReturn(0); 7960552f7358SJed Brown } 7961552f7358SJed Brown 79627cd05799SMatthew G. Knepley /*@C 79637cd05799SMatthew G. Knepley DMPlexSetVTKCellHeight - Sets the height in the DAG used to determine which points are cells (normally 0) 79647cd05799SMatthew G. Knepley 79657cd05799SMatthew G. Knepley Input Parameters: 79667cd05799SMatthew G. Knepley + dm - The DMPlex object 79677cd05799SMatthew G. Knepley - cellHeight - The height of a cell 79687cd05799SMatthew G. Knepley 79697cd05799SMatthew G. Knepley Level: developer 79707cd05799SMatthew G. Knepley 79717cd05799SMatthew G. Knepley .seealso DMPlexGetVTKCellHeight() 79727cd05799SMatthew G. Knepley @*/ 7973552f7358SJed Brown PetscErrorCode DMPlexSetVTKCellHeight(DM dm, PetscInt cellHeight) 7974552f7358SJed Brown { 7975552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 7976552f7358SJed Brown 7977552f7358SJed Brown PetscFunctionBegin; 7978552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7979552f7358SJed Brown mesh->vtkCellHeight = cellHeight; 7980552f7358SJed Brown PetscFunctionReturn(0); 7981552f7358SJed Brown } 7982552f7358SJed Brown 7983e6139122SMatthew G. Knepley /*@ 7984e6139122SMatthew G. Knepley DMPlexGetGhostCellStratum - Get the range of cells which are used to enforce FV boundary conditions 7985e6139122SMatthew G. Knepley 7986e6139122SMatthew G. Knepley Input Parameter: 7987e6139122SMatthew G. Knepley . dm - The DMPlex object 7988e6139122SMatthew G. Knepley 7989e6139122SMatthew G. Knepley Output Parameters: 79902a9f31c0SMatthew G. Knepley + gcStart - The first ghost cell, or NULL 79912a9f31c0SMatthew G. Knepley - gcEnd - The upper bound on ghost cells, or NULL 7992e6139122SMatthew G. Knepley 79932a9f31c0SMatthew G. Knepley Level: advanced 7994e6139122SMatthew G. Knepley 79958065b584SMatthew Knepley .seealso DMPlexConstructGhostCells(), DMPlexGetGhostCellStratum() 7996e6139122SMatthew G. Knepley @*/ 7997e6139122SMatthew G. Knepley PetscErrorCode DMPlexGetGhostCellStratum(DM dm, PetscInt *gcStart, PetscInt *gcEnd) 7998e6139122SMatthew G. Knepley { 7999412e9a14SMatthew G. Knepley DMLabel ctLabel; 8000e6139122SMatthew G. Knepley PetscErrorCode ierr; 8001e6139122SMatthew G. Knepley 8002e6139122SMatthew G. Knepley PetscFunctionBegin; 8003e6139122SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8004412e9a14SMatthew G. Knepley ierr = DMPlexGetCellTypeLabel(dm, &ctLabel);CHKERRQ(ierr); 8005412e9a14SMatthew G. Knepley ierr = DMLabelGetStratumBounds(ctLabel, DM_POLYTOPE_FV_GHOST, gcStart, gcEnd);CHKERRQ(ierr); 8006e6139122SMatthew G. Knepley PetscFunctionReturn(0); 8007e6139122SMatthew G. Knepley } 8008e6139122SMatthew G. Knepley 8009552f7358SJed Brown /* We can easily have a form that takes an IS instead */ 80109886b8cfSStefano Zampini PetscErrorCode DMPlexCreateNumbering_Plex(DM dm, PetscInt pStart, PetscInt pEnd, PetscInt shift, PetscInt *globalSize, PetscSF sf, IS *numbering) 8011552f7358SJed Brown { 8012552f7358SJed Brown PetscSection section, globalSection; 8013552f7358SJed Brown PetscInt *numbers, p; 8014552f7358SJed Brown PetscErrorCode ierr; 8015552f7358SJed Brown 8016552f7358SJed Brown PetscFunctionBegin; 801782f516ccSBarry Smith ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), §ion);CHKERRQ(ierr); 8018552f7358SJed Brown ierr = PetscSectionSetChart(section, pStart, pEnd);CHKERRQ(ierr); 8019552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 8020552f7358SJed Brown ierr = PetscSectionSetDof(section, p, 1);CHKERRQ(ierr); 8021552f7358SJed Brown } 8022552f7358SJed Brown ierr = PetscSectionSetUp(section);CHKERRQ(ierr); 802315b58121SMatthew G. Knepley ierr = PetscSectionCreateGlobalSection(section, sf, PETSC_FALSE, PETSC_FALSE, &globalSection);CHKERRQ(ierr); 8024854ce69bSBarry Smith ierr = PetscMalloc1(pEnd - pStart, &numbers);CHKERRQ(ierr); 8025552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 8026552f7358SJed Brown ierr = PetscSectionGetOffset(globalSection, p, &numbers[p-pStart]);CHKERRQ(ierr); 8027ef48cebcSMatthew G. Knepley if (numbers[p-pStart] < 0) numbers[p-pStart] -= shift; 8028ef48cebcSMatthew G. Knepley else numbers[p-pStart] += shift; 8029552f7358SJed Brown } 803082f516ccSBarry Smith ierr = ISCreateGeneral(PetscObjectComm((PetscObject) dm), pEnd - pStart, numbers, PETSC_OWN_POINTER, numbering);CHKERRQ(ierr); 8031ef48cebcSMatthew G. Knepley if (globalSize) { 8032ef48cebcSMatthew G. Knepley PetscLayout layout; 8033ef48cebcSMatthew G. Knepley ierr = PetscSectionGetPointLayout(PetscObjectComm((PetscObject) dm), globalSection, &layout);CHKERRQ(ierr); 8034ef48cebcSMatthew G. Knepley ierr = PetscLayoutGetSize(layout, globalSize);CHKERRQ(ierr); 8035ef48cebcSMatthew G. Knepley ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr); 8036ef48cebcSMatthew G. Knepley } 8037552f7358SJed Brown ierr = PetscSectionDestroy(§ion);CHKERRQ(ierr); 8038552f7358SJed Brown ierr = PetscSectionDestroy(&globalSection);CHKERRQ(ierr); 8039552f7358SJed Brown PetscFunctionReturn(0); 8040552f7358SJed Brown } 8041552f7358SJed Brown 804281ed3555SMatthew G. Knepley PetscErrorCode DMPlexCreateCellNumbering_Internal(DM dm, PetscBool includeHybrid, IS *globalCellNumbers) 8043552f7358SJed Brown { 8044412e9a14SMatthew G. Knepley PetscInt cellHeight, cStart, cEnd; 8045552f7358SJed Brown PetscErrorCode ierr; 8046552f7358SJed Brown 8047552f7358SJed Brown PetscFunctionBegin; 8048552f7358SJed Brown ierr = DMPlexGetVTKCellHeight(dm, &cellHeight);CHKERRQ(ierr); 8049412e9a14SMatthew G. Knepley if (includeHybrid) {ierr = DMPlexGetHeightStratum(dm, cellHeight, &cStart, &cEnd);CHKERRQ(ierr);} 8050412e9a14SMatthew G. Knepley else {ierr = DMPlexGetSimplexOrBoxCells(dm, cellHeight, &cStart, &cEnd);CHKERRQ(ierr);} 80519886b8cfSStefano Zampini ierr = DMPlexCreateNumbering_Plex(dm, cStart, cEnd, 0, NULL, dm->sf, globalCellNumbers);CHKERRQ(ierr); 805281ed3555SMatthew G. Knepley PetscFunctionReturn(0); 8053552f7358SJed Brown } 805481ed3555SMatthew G. Knepley 80558dab3259SMatthew G. Knepley /*@ 80567cd05799SMatthew G. Knepley DMPlexGetCellNumbering - Get a global cell numbering for all cells on this process 80577cd05799SMatthew G. Knepley 80587cd05799SMatthew G. Knepley Input Parameter: 80597cd05799SMatthew G. Knepley . dm - The DMPlex object 80607cd05799SMatthew G. Knepley 80617cd05799SMatthew G. Knepley Output Parameter: 80627cd05799SMatthew G. Knepley . globalCellNumbers - Global cell numbers for all cells on this process 80637cd05799SMatthew G. Knepley 80647cd05799SMatthew G. Knepley Level: developer 80657cd05799SMatthew G. Knepley 80667cd05799SMatthew G. Knepley .seealso DMPlexGetVertexNumbering() 80677cd05799SMatthew G. Knepley @*/ 806881ed3555SMatthew G. Knepley PetscErrorCode DMPlexGetCellNumbering(DM dm, IS *globalCellNumbers) 806981ed3555SMatthew G. Knepley { 807081ed3555SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 807181ed3555SMatthew G. Knepley PetscErrorCode ierr; 807281ed3555SMatthew G. Knepley 807381ed3555SMatthew G. Knepley PetscFunctionBegin; 807481ed3555SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 807581ed3555SMatthew G. Knepley if (!mesh->globalCellNumbers) {ierr = DMPlexCreateCellNumbering_Internal(dm, PETSC_FALSE, &mesh->globalCellNumbers);CHKERRQ(ierr);} 8076552f7358SJed Brown *globalCellNumbers = mesh->globalCellNumbers; 8077552f7358SJed Brown PetscFunctionReturn(0); 8078552f7358SJed Brown } 8079552f7358SJed Brown 808081ed3555SMatthew G. Knepley PetscErrorCode DMPlexCreateVertexNumbering_Internal(DM dm, PetscBool includeHybrid, IS *globalVertexNumbers) 808181ed3555SMatthew G. Knepley { 8082412e9a14SMatthew G. Knepley PetscInt vStart, vEnd; 808381ed3555SMatthew G. Knepley PetscErrorCode ierr; 808481ed3555SMatthew G. Knepley 808581ed3555SMatthew G. Knepley PetscFunctionBegin; 808681ed3555SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 808781ed3555SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 80889886b8cfSStefano Zampini ierr = DMPlexCreateNumbering_Plex(dm, vStart, vEnd, 0, NULL, dm->sf, globalVertexNumbers);CHKERRQ(ierr); 808981ed3555SMatthew G. Knepley PetscFunctionReturn(0); 809081ed3555SMatthew G. Knepley } 809181ed3555SMatthew G. Knepley 80928dab3259SMatthew G. Knepley /*@ 80936aa51ba9SJacob Faibussowitsch DMPlexGetVertexNumbering - Get a global vertex numbering for all vertices on this process 80947cd05799SMatthew G. Knepley 80957cd05799SMatthew G. Knepley Input Parameter: 80967cd05799SMatthew G. Knepley . dm - The DMPlex object 80977cd05799SMatthew G. Knepley 80987cd05799SMatthew G. Knepley Output Parameter: 80997cd05799SMatthew G. Knepley . globalVertexNumbers - Global vertex numbers for all vertices on this process 81007cd05799SMatthew G. Knepley 81017cd05799SMatthew G. Knepley Level: developer 81027cd05799SMatthew G. Knepley 81037cd05799SMatthew G. Knepley .seealso DMPlexGetCellNumbering() 81047cd05799SMatthew G. Knepley @*/ 8105552f7358SJed Brown PetscErrorCode DMPlexGetVertexNumbering(DM dm, IS *globalVertexNumbers) 8106552f7358SJed Brown { 8107552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 8108552f7358SJed Brown PetscErrorCode ierr; 8109552f7358SJed Brown 8110552f7358SJed Brown PetscFunctionBegin; 8111552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 811281ed3555SMatthew G. Knepley if (!mesh->globalVertexNumbers) {ierr = DMPlexCreateVertexNumbering_Internal(dm, PETSC_FALSE, &mesh->globalVertexNumbers);CHKERRQ(ierr);} 8113552f7358SJed Brown *globalVertexNumbers = mesh->globalVertexNumbers; 8114552f7358SJed Brown PetscFunctionReturn(0); 8115552f7358SJed Brown } 8116552f7358SJed Brown 81178dab3259SMatthew G. Knepley /*@ 81187cd05799SMatthew G. Knepley DMPlexCreatePointNumbering - Create a global numbering for all points on this process 81197cd05799SMatthew G. Knepley 81207cd05799SMatthew G. Knepley Input Parameter: 81217cd05799SMatthew G. Knepley . dm - The DMPlex object 81227cd05799SMatthew G. Knepley 81237cd05799SMatthew G. Knepley Output Parameter: 81247cd05799SMatthew G. Knepley . globalPointNumbers - Global numbers for all points on this process 81257cd05799SMatthew G. Knepley 81267cd05799SMatthew G. Knepley Level: developer 81277cd05799SMatthew G. Knepley 81287cd05799SMatthew G. Knepley .seealso DMPlexGetCellNumbering() 81297cd05799SMatthew G. Knepley @*/ 8130ef48cebcSMatthew G. Knepley PetscErrorCode DMPlexCreatePointNumbering(DM dm, IS *globalPointNumbers) 8131ef48cebcSMatthew G. Knepley { 8132ef48cebcSMatthew G. Knepley IS nums[4]; 8133862913ffSStefano Zampini PetscInt depths[4], gdepths[4], starts[4]; 8134ef48cebcSMatthew G. Knepley PetscInt depth, d, shift = 0; 8135ef48cebcSMatthew G. Knepley PetscErrorCode ierr; 8136ef48cebcSMatthew G. Knepley 8137ef48cebcSMatthew G. Knepley PetscFunctionBegin; 8138ef48cebcSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8139ef48cebcSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 81408abc87a0SMichael Lange /* For unstratified meshes use dim instead of depth */ 81418abc87a0SMichael Lange if (depth < 0) {ierr = DMGetDimension(dm, &depth);CHKERRQ(ierr);} 8142862913ffSStefano Zampini for (d = 0; d <= depth; ++d) { 8143862913ffSStefano Zampini PetscInt end; 8144862913ffSStefano Zampini 8145862913ffSStefano Zampini depths[d] = depth-d; 8146862913ffSStefano Zampini ierr = DMPlexGetDepthStratum(dm, depths[d], &starts[d], &end);CHKERRQ(ierr); 8147862913ffSStefano Zampini if (!(starts[d]-end)) { starts[d] = depths[d] = -1; } 8148862913ffSStefano Zampini } 8149862913ffSStefano Zampini ierr = PetscSortIntWithArray(depth+1, starts, depths);CHKERRQ(ierr); 8150820f2d46SBarry Smith ierr = MPIU_Allreduce(depths, gdepths, depth+1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject) dm));CHKERRMPI(ierr); 8151862913ffSStefano Zampini for (d = 0; d <= depth; ++d) { 8152862913ffSStefano Zampini if (starts[d] >= 0 && depths[d] != gdepths[d]) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Expected depth %D, found %D",depths[d],gdepths[d]); 8153862913ffSStefano Zampini } 8154ef48cebcSMatthew G. Knepley for (d = 0; d <= depth; ++d) { 8155ef48cebcSMatthew G. Knepley PetscInt pStart, pEnd, gsize; 8156ef48cebcSMatthew G. Knepley 8157862913ffSStefano Zampini ierr = DMPlexGetDepthStratum(dm, gdepths[d], &pStart, &pEnd);CHKERRQ(ierr); 81589886b8cfSStefano Zampini ierr = DMPlexCreateNumbering_Plex(dm, pStart, pEnd, shift, &gsize, dm->sf, &nums[d]);CHKERRQ(ierr); 8159ef48cebcSMatthew G. Knepley shift += gsize; 8160ef48cebcSMatthew G. Knepley } 8161302440fdSBarry Smith ierr = ISConcatenate(PetscObjectComm((PetscObject) dm), depth+1, nums, globalPointNumbers);CHKERRQ(ierr); 8162ef48cebcSMatthew G. Knepley for (d = 0; d <= depth; ++d) {ierr = ISDestroy(&nums[d]);CHKERRQ(ierr);} 8163ef48cebcSMatthew G. Knepley PetscFunctionReturn(0); 8164ef48cebcSMatthew G. Knepley } 8165ef48cebcSMatthew G. Knepley 816608a22f4bSMatthew G. Knepley /*@ 816708a22f4bSMatthew G. Knepley DMPlexCreateRankField - Create a cell field whose value is the rank of the owner 816808a22f4bSMatthew G. Knepley 816908a22f4bSMatthew G. Knepley Input Parameter: 817008a22f4bSMatthew G. Knepley . dm - The DMPlex object 817108a22f4bSMatthew G. Knepley 817208a22f4bSMatthew G. Knepley Output Parameter: 817308a22f4bSMatthew G. Knepley . ranks - The rank field 817408a22f4bSMatthew G. Knepley 817508a22f4bSMatthew G. Knepley Options Database Keys: 817608a22f4bSMatthew G. Knepley . -dm_partition_view - Adds the rank field into the DM output from -dm_view using the same viewer 817708a22f4bSMatthew G. Knepley 817808a22f4bSMatthew G. Knepley Level: intermediate 817908a22f4bSMatthew G. Knepley 818008a22f4bSMatthew G. Knepley .seealso: DMView() 818108a22f4bSMatthew G. Knepley @*/ 818208a22f4bSMatthew G. Knepley PetscErrorCode DMPlexCreateRankField(DM dm, Vec *ranks) 818308a22f4bSMatthew G. Knepley { 818408a22f4bSMatthew G. Knepley DM rdm; 818508a22f4bSMatthew G. Knepley PetscFE fe; 818608a22f4bSMatthew G. Knepley PetscScalar *r; 818708a22f4bSMatthew G. Knepley PetscMPIInt rank; 8188a55f9a55SMatthew G. Knepley DMPolytopeType ct; 818908a22f4bSMatthew G. Knepley PetscInt dim, cStart, cEnd, c; 8190a55f9a55SMatthew G. Knepley PetscBool simplex; 819108a22f4bSMatthew G. Knepley PetscErrorCode ierr; 819208a22f4bSMatthew G. Knepley 819308a22f4bSMatthew G. Knepley PetscFunctionBeginUser; 8194f95ace6aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8195f95ace6aSMatthew G. Knepley PetscValidPointer(ranks, 2); 8196ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject) dm), &rank);CHKERRMPI(ierr); 819708a22f4bSMatthew G. Knepley ierr = DMClone(dm, &rdm);CHKERRQ(ierr); 819808a22f4bSMatthew G. Knepley ierr = DMGetDimension(rdm, &dim);CHKERRQ(ierr); 8199a55f9a55SMatthew G. Knepley ierr = DMPlexGetHeightStratum(rdm, 0, &cStart, &cEnd);CHKERRQ(ierr); 8200a55f9a55SMatthew G. Knepley ierr = DMPlexGetCellType(dm, cStart, &ct);CHKERRQ(ierr); 8201a55f9a55SMatthew G. Knepley simplex = DMPolytopeTypeGetNumVertices(ct) == DMPolytopeTypeGetDim(ct)+1 ? PETSC_TRUE : PETSC_FALSE; 8202a55f9a55SMatthew G. Knepley ierr = PetscFECreateDefault(PETSC_COMM_SELF, dim, 1, simplex, "PETSc___rank_", -1, &fe);CHKERRQ(ierr); 820308a22f4bSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) fe, "rank");CHKERRQ(ierr); 8204e5e52638SMatthew G. Knepley ierr = DMSetField(rdm, 0, NULL, (PetscObject) fe);CHKERRQ(ierr); 820508a22f4bSMatthew G. Knepley ierr = PetscFEDestroy(&fe);CHKERRQ(ierr); 8206e5e52638SMatthew G. Knepley ierr = DMCreateDS(rdm);CHKERRQ(ierr); 820708a22f4bSMatthew G. Knepley ierr = DMCreateGlobalVector(rdm, ranks);CHKERRQ(ierr); 820808a22f4bSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) *ranks, "partition");CHKERRQ(ierr); 820908a22f4bSMatthew G. Knepley ierr = VecGetArray(*ranks, &r);CHKERRQ(ierr); 821008a22f4bSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 821108a22f4bSMatthew G. Knepley PetscScalar *lr; 821208a22f4bSMatthew G. Knepley 821308a22f4bSMatthew G. Knepley ierr = DMPlexPointGlobalRef(rdm, c, r, &lr);CHKERRQ(ierr); 821471f09efeSPierre Jolivet if (lr) *lr = rank; 821508a22f4bSMatthew G. Knepley } 821608a22f4bSMatthew G. Knepley ierr = VecRestoreArray(*ranks, &r);CHKERRQ(ierr); 821708a22f4bSMatthew G. Knepley ierr = DMDestroy(&rdm);CHKERRQ(ierr); 821808a22f4bSMatthew G. Knepley PetscFunctionReturn(0); 821908a22f4bSMatthew G. Knepley } 822008a22f4bSMatthew G. Knepley 8221ca8062c8SMatthew G. Knepley /*@ 822218e14f0cSMatthew G. Knepley DMPlexCreateLabelField - Create a cell field whose value is the label value for that cell 822318e14f0cSMatthew G. Knepley 822418e14f0cSMatthew G. Knepley Input Parameters: 822518e14f0cSMatthew G. Knepley + dm - The DMPlex 822618e14f0cSMatthew G. Knepley - label - The DMLabel 822718e14f0cSMatthew G. Knepley 822818e14f0cSMatthew G. Knepley Output Parameter: 822918e14f0cSMatthew G. Knepley . val - The label value field 823018e14f0cSMatthew G. Knepley 823118e14f0cSMatthew G. Knepley Options Database Keys: 823218e14f0cSMatthew G. Knepley . -dm_label_view - Adds the label value field into the DM output from -dm_view using the same viewer 823318e14f0cSMatthew G. Knepley 823418e14f0cSMatthew G. Knepley Level: intermediate 823518e14f0cSMatthew G. Knepley 823618e14f0cSMatthew G. Knepley .seealso: DMView() 823718e14f0cSMatthew G. Knepley @*/ 823818e14f0cSMatthew G. Knepley PetscErrorCode DMPlexCreateLabelField(DM dm, DMLabel label, Vec *val) 823918e14f0cSMatthew G. Knepley { 824018e14f0cSMatthew G. Knepley DM rdm; 824118e14f0cSMatthew G. Knepley PetscFE fe; 824218e14f0cSMatthew G. Knepley PetscScalar *v; 824318e14f0cSMatthew G. Knepley PetscInt dim, cStart, cEnd, c; 824418e14f0cSMatthew G. Knepley PetscErrorCode ierr; 824518e14f0cSMatthew G. Knepley 824618e14f0cSMatthew G. Knepley PetscFunctionBeginUser; 824718e14f0cSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 824818e14f0cSMatthew G. Knepley PetscValidPointer(label, 2); 824918e14f0cSMatthew G. Knepley PetscValidPointer(val, 3); 825018e14f0cSMatthew G. Knepley ierr = DMClone(dm, &rdm);CHKERRQ(ierr); 825118e14f0cSMatthew G. Knepley ierr = DMGetDimension(rdm, &dim);CHKERRQ(ierr); 825218e14f0cSMatthew G. Knepley ierr = PetscFECreateDefault(PetscObjectComm((PetscObject) rdm), dim, 1, PETSC_TRUE, "PETSc___label_value_", -1, &fe);CHKERRQ(ierr); 825318e14f0cSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) fe, "label_value");CHKERRQ(ierr); 8254e5e52638SMatthew G. Knepley ierr = DMSetField(rdm, 0, NULL, (PetscObject) fe);CHKERRQ(ierr); 825518e14f0cSMatthew G. Knepley ierr = PetscFEDestroy(&fe);CHKERRQ(ierr); 8256e5e52638SMatthew G. Knepley ierr = DMCreateDS(rdm);CHKERRQ(ierr); 825718e14f0cSMatthew G. Knepley ierr = DMPlexGetHeightStratum(rdm, 0, &cStart, &cEnd);CHKERRQ(ierr); 825818e14f0cSMatthew G. Knepley ierr = DMCreateGlobalVector(rdm, val);CHKERRQ(ierr); 8259effbd7cbSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) *val, "label_value");CHKERRQ(ierr); 826018e14f0cSMatthew G. Knepley ierr = VecGetArray(*val, &v);CHKERRQ(ierr); 826118e14f0cSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 826218e14f0cSMatthew G. Knepley PetscScalar *lv; 826318e14f0cSMatthew G. Knepley PetscInt cval; 826418e14f0cSMatthew G. Knepley 826518e14f0cSMatthew G. Knepley ierr = DMPlexPointGlobalRef(rdm, c, v, &lv);CHKERRQ(ierr); 826618e14f0cSMatthew G. Knepley ierr = DMLabelGetValue(label, c, &cval);CHKERRQ(ierr); 826718e14f0cSMatthew G. Knepley *lv = cval; 826818e14f0cSMatthew G. Knepley } 826918e14f0cSMatthew G. Knepley ierr = VecRestoreArray(*val, &v);CHKERRQ(ierr); 827018e14f0cSMatthew G. Knepley ierr = DMDestroy(&rdm);CHKERRQ(ierr); 827118e14f0cSMatthew G. Knepley PetscFunctionReturn(0); 827218e14f0cSMatthew G. Knepley } 827318e14f0cSMatthew G. Knepley 827418e14f0cSMatthew G. Knepley /*@ 8275ca8062c8SMatthew G. Knepley DMPlexCheckSymmetry - Check that the adjacency information in the mesh is symmetric. 8276ca8062c8SMatthew G. Knepley 827769916449SMatthew G. Knepley Input Parameter: 827869916449SMatthew G. Knepley . dm - The DMPlex object 8279ca8062c8SMatthew G. Knepley 828095eb5ee5SVaclav Hapla Notes: 828195eb5ee5SVaclav Hapla This is a useful diagnostic when creating meshes programmatically. 828295eb5ee5SVaclav Hapla 828395eb5ee5SVaclav Hapla For the complete list of DMPlexCheck* functions, see DMSetFromOptions(). 8284ca8062c8SMatthew G. Knepley 8285ca8062c8SMatthew G. Knepley Level: developer 8286ca8062c8SMatthew G. Knepley 828795eb5ee5SVaclav Hapla .seealso: DMCreate(), DMSetFromOptions() 8288ca8062c8SMatthew G. Knepley @*/ 8289ca8062c8SMatthew G. Knepley PetscErrorCode DMPlexCheckSymmetry(DM dm) 8290ca8062c8SMatthew G. Knepley { 8291ca8062c8SMatthew G. Knepley PetscSection coneSection, supportSection; 8292ca8062c8SMatthew G. Knepley const PetscInt *cone, *support; 8293ca8062c8SMatthew G. Knepley PetscInt coneSize, c, supportSize, s; 829457beb4faSStefano Zampini PetscInt pStart, pEnd, p, pp, csize, ssize; 829557beb4faSStefano Zampini PetscBool storagecheck = PETSC_TRUE; 8296ca8062c8SMatthew G. Knepley PetscErrorCode ierr; 8297ca8062c8SMatthew G. Knepley 8298ca8062c8SMatthew G. Knepley PetscFunctionBegin; 8299ca8062c8SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8300412e9a14SMatthew G. Knepley ierr = DMViewFromOptions(dm, NULL, "-sym_dm_view");CHKERRQ(ierr); 8301ca8062c8SMatthew G. Knepley ierr = DMPlexGetConeSection(dm, &coneSection);CHKERRQ(ierr); 8302ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupportSection(dm, &supportSection);CHKERRQ(ierr); 8303ca8062c8SMatthew G. Knepley /* Check that point p is found in the support of its cone points, and vice versa */ 8304ca8062c8SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 8305ca8062c8SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 8306ca8062c8SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, p, &coneSize);CHKERRQ(ierr); 8307ca8062c8SMatthew G. Knepley ierr = DMPlexGetCone(dm, p, &cone);CHKERRQ(ierr); 8308ca8062c8SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 830942e66dfaSMatthew G. Knepley PetscBool dup = PETSC_FALSE; 831042e66dfaSMatthew G. Knepley PetscInt d; 831142e66dfaSMatthew G. Knepley for (d = c-1; d >= 0; --d) { 831242e66dfaSMatthew G. Knepley if (cone[c] == cone[d]) {dup = PETSC_TRUE; break;} 831342e66dfaSMatthew G. Knepley } 8314ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, cone[c], &supportSize);CHKERRQ(ierr); 8315ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupport(dm, cone[c], &support);CHKERRQ(ierr); 8316ca8062c8SMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 8317ca8062c8SMatthew G. Knepley if (support[s] == p) break; 8318ca8062c8SMatthew G. Knepley } 831942e66dfaSMatthew G. Knepley if ((s >= supportSize) || (dup && (support[s+1] != p))) { 83208ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "p: %D cone: ", p);CHKERRQ(ierr); 8321ca8062c8SMatthew G. Knepley for (s = 0; s < coneSize; ++s) { 83228ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "%D, ", cone[s]);CHKERRQ(ierr); 8323ca8062c8SMatthew G. Knepley } 8324302440fdSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 83258ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "p: %D support: ", cone[c]);CHKERRQ(ierr); 8326ca8062c8SMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 83278ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "%D, ", support[s]);CHKERRQ(ierr); 8328ca8062c8SMatthew G. Knepley } 8329302440fdSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 83308ccfff9cSToby Isaac if (dup) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D not repeatedly found in support of repeated cone point %D", p, cone[c]); 83318ccfff9cSToby Isaac else SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D not found in support of cone point %D", p, cone[c]); 8332ca8062c8SMatthew G. Knepley } 833342e66dfaSMatthew G. Knepley } 833457beb4faSStefano Zampini ierr = DMPlexGetTreeParent(dm, p, &pp, NULL);CHKERRQ(ierr); 833557beb4faSStefano Zampini if (p != pp) { storagecheck = PETSC_FALSE; continue; } 8336ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, p, &supportSize);CHKERRQ(ierr); 8337ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupport(dm, p, &support);CHKERRQ(ierr); 8338ca8062c8SMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 8339ca8062c8SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 8340ca8062c8SMatthew G. Knepley ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 8341ca8062c8SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 834257beb4faSStefano Zampini ierr = DMPlexGetTreeParent(dm, cone[c], &pp, NULL);CHKERRQ(ierr); 834357beb4faSStefano Zampini if (cone[c] != pp) { c = 0; break; } 8344ca8062c8SMatthew G. Knepley if (cone[c] == p) break; 8345ca8062c8SMatthew G. Knepley } 8346ca8062c8SMatthew G. Knepley if (c >= coneSize) { 83478ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "p: %D support: ", p);CHKERRQ(ierr); 8348ca8062c8SMatthew G. Knepley for (c = 0; c < supportSize; ++c) { 83498ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "%D, ", support[c]);CHKERRQ(ierr); 8350ca8062c8SMatthew G. Knepley } 8351302440fdSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 83528ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "p: %D cone: ", support[s]);CHKERRQ(ierr); 8353ca8062c8SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 83548ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "%D, ", cone[c]);CHKERRQ(ierr); 8355ca8062c8SMatthew G. Knepley } 8356302440fdSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 83578ccfff9cSToby Isaac SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D not found in cone of support point %D", p, support[s]); 8358ca8062c8SMatthew G. Knepley } 8359ca8062c8SMatthew G. Knepley } 8360ca8062c8SMatthew G. Knepley } 836157beb4faSStefano Zampini if (storagecheck) { 8362ca8062c8SMatthew G. Knepley ierr = PetscSectionGetStorageSize(coneSection, &csize);CHKERRQ(ierr); 8363ca8062c8SMatthew G. Knepley ierr = PetscSectionGetStorageSize(supportSection, &ssize);CHKERRQ(ierr); 83648ccfff9cSToby Isaac if (csize != ssize) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Total cone size %D != Total support size %D", csize, ssize); 836557beb4faSStefano Zampini } 8366ca8062c8SMatthew G. Knepley PetscFunctionReturn(0); 8367ca8062c8SMatthew G. Knepley } 8368ca8062c8SMatthew G. Knepley 8369412e9a14SMatthew G. Knepley /* 8370412e9a14SMatthew 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. 8371412e9a14SMatthew G. Knepley */ 8372412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellUnsplitVertices_Private(DM dm, PetscInt c, DMPolytopeType ct, PetscInt *unsplit) 8373412e9a14SMatthew G. Knepley { 8374412e9a14SMatthew G. Knepley DMPolytopeType cct; 8375412e9a14SMatthew G. Knepley PetscInt ptpoints[4]; 8376412e9a14SMatthew G. Knepley const PetscInt *cone, *ccone, *ptcone; 8377412e9a14SMatthew G. Knepley PetscInt coneSize, cp, cconeSize, ccp, npt = 0, pt; 8378412e9a14SMatthew G. Knepley PetscErrorCode ierr; 8379412e9a14SMatthew G. Knepley 8380412e9a14SMatthew G. Knepley PetscFunctionBegin; 8381412e9a14SMatthew G. Knepley *unsplit = 0; 8382412e9a14SMatthew G. Knepley switch (ct) { 8383b5a892a1SMatthew G. Knepley case DM_POLYTOPE_POINT_PRISM_TENSOR: 8384b5a892a1SMatthew G. Knepley ptpoints[npt++] = c; 8385b5a892a1SMatthew G. Knepley break; 8386412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 8387412e9a14SMatthew G. Knepley ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 8388412e9a14SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, c, &coneSize);CHKERRQ(ierr); 8389412e9a14SMatthew G. Knepley for (cp = 0; cp < coneSize; ++cp) { 8390412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, cone[cp], &cct);CHKERRQ(ierr); 8391412e9a14SMatthew G. Knepley if (cct == DM_POLYTOPE_POINT_PRISM_TENSOR) ptpoints[npt++] = cone[cp]; 8392412e9a14SMatthew G. Knepley } 8393412e9a14SMatthew G. Knepley break; 8394412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 8395412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 8396412e9a14SMatthew G. Knepley ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 8397412e9a14SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, c, &coneSize);CHKERRQ(ierr); 8398412e9a14SMatthew G. Knepley for (cp = 0; cp < coneSize; ++cp) { 8399412e9a14SMatthew G. Knepley ierr = DMPlexGetCone(dm, cone[cp], &ccone);CHKERRQ(ierr); 8400412e9a14SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, cone[cp], &cconeSize);CHKERRQ(ierr); 8401412e9a14SMatthew G. Knepley for (ccp = 0; ccp < cconeSize; ++ccp) { 8402412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, ccone[ccp], &cct);CHKERRQ(ierr); 8403412e9a14SMatthew G. Knepley if (cct == DM_POLYTOPE_POINT_PRISM_TENSOR) { 8404412e9a14SMatthew G. Knepley PetscInt p; 8405412e9a14SMatthew G. Knepley for (p = 0; p < npt; ++p) if (ptpoints[p] == ccone[ccp]) break; 8406412e9a14SMatthew G. Knepley if (p == npt) ptpoints[npt++] = ccone[ccp]; 8407412e9a14SMatthew G. Knepley } 8408412e9a14SMatthew G. Knepley } 8409412e9a14SMatthew G. Knepley } 8410412e9a14SMatthew G. Knepley break; 8411412e9a14SMatthew G. Knepley default: break; 8412412e9a14SMatthew G. Knepley } 8413412e9a14SMatthew G. Knepley for (pt = 0; pt < npt; ++pt) { 8414412e9a14SMatthew G. Knepley ierr = DMPlexGetCone(dm, ptpoints[pt], &ptcone);CHKERRQ(ierr); 8415412e9a14SMatthew G. Knepley if (ptcone[0] == ptcone[1]) ++(*unsplit); 8416412e9a14SMatthew G. Knepley } 8417412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 8418412e9a14SMatthew G. Knepley } 8419412e9a14SMatthew G. Knepley 8420ca8062c8SMatthew G. Knepley /*@ 8421ca8062c8SMatthew G. Knepley DMPlexCheckSkeleton - Check that each cell has the correct number of vertices 8422ca8062c8SMatthew G. Knepley 8423ca8062c8SMatthew G. Knepley Input Parameters: 8424ca8062c8SMatthew G. Knepley + dm - The DMPlex object 842558723a97SMatthew G. Knepley - cellHeight - Normally 0 8426ca8062c8SMatthew G. Knepley 842795eb5ee5SVaclav Hapla Notes: 842895eb5ee5SVaclav Hapla This is a useful diagnostic when creating meshes programmatically. 842925c50c26SVaclav Hapla Currently applicable only to homogeneous simplex or tensor meshes. 8430ca8062c8SMatthew G. Knepley 843195eb5ee5SVaclav Hapla For the complete list of DMPlexCheck* functions, see DMSetFromOptions(). 843295eb5ee5SVaclav Hapla 8433ca8062c8SMatthew G. Knepley Level: developer 8434ca8062c8SMatthew G. Knepley 843595eb5ee5SVaclav Hapla .seealso: DMCreate(), DMSetFromOptions() 8436ca8062c8SMatthew G. Knepley @*/ 843725c50c26SVaclav Hapla PetscErrorCode DMPlexCheckSkeleton(DM dm, PetscInt cellHeight) 8438ca8062c8SMatthew G. Knepley { 8439412e9a14SMatthew G. Knepley DMPlexInterpolatedFlag interp; 8440412e9a14SMatthew G. Knepley DMPolytopeType ct; 8441412e9a14SMatthew G. Knepley PetscInt vStart, vEnd, cStart, cEnd, c; 8442ca8062c8SMatthew G. Knepley PetscErrorCode ierr; 8443ca8062c8SMatthew G. Knepley 8444ca8062c8SMatthew G. Knepley PetscFunctionBegin; 8445ca8062c8SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8446412e9a14SMatthew G. Knepley ierr = DMPlexIsInterpolated(dm, &interp);CHKERRQ(ierr); 844725c50c26SVaclav Hapla ierr = DMPlexGetHeightStratum(dm, cellHeight, &cStart, &cEnd);CHKERRQ(ierr); 844858723a97SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 8449412e9a14SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 8450412e9a14SMatthew G. Knepley PetscInt *closure = NULL; 8451412e9a14SMatthew G. Knepley PetscInt coneSize, closureSize, cl, Nv = 0; 845258723a97SMatthew G. Knepley 8453412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, c, &ct);CHKERRQ(ierr); 8454412e9a14SMatthew G. Knepley if ((PetscInt) ct < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cell %D has no cell type", c); 8455412e9a14SMatthew G. Knepley if (ct == DM_POLYTOPE_UNKNOWN) continue; 8456412e9a14SMatthew G. Knepley if (interp == DMPLEX_INTERPOLATED_FULL) { 8457412e9a14SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, c, &coneSize);CHKERRQ(ierr); 8458d4961f80SStefano Zampini if (coneSize != DMPolytopeTypeGetConeSize(ct)) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cell %D of type %s has cone size %D != %D", c, DMPolytopeTypes[ct], coneSize, DMPolytopeTypeGetConeSize(ct)); 8459412e9a14SMatthew G. Knepley } 846058723a97SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 846158723a97SMatthew G. Knepley for (cl = 0; cl < closureSize*2; cl += 2) { 846258723a97SMatthew G. Knepley const PetscInt p = closure[cl]; 8463412e9a14SMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) ++Nv; 846458723a97SMatthew G. Knepley } 846558723a97SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 8466412e9a14SMatthew G. Knepley /* Special Case: Tensor faces with identified vertices */ 8467412e9a14SMatthew G. Knepley if (Nv < DMPolytopeTypeGetNumVertices(ct)) { 8468412e9a14SMatthew G. Knepley PetscInt unsplit; 846942363296SMatthew G. Knepley 8470412e9a14SMatthew G. Knepley ierr = DMPlexCellUnsplitVertices_Private(dm, c, ct, &unsplit);CHKERRQ(ierr); 8471412e9a14SMatthew G. Knepley if (Nv + unsplit == DMPolytopeTypeGetNumVertices(ct)) continue; 847242363296SMatthew G. Knepley } 8473d4961f80SStefano Zampini if (Nv != DMPolytopeTypeGetNumVertices(ct)) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cell %D of type %s has %D vertices != %D", c, DMPolytopeTypes[ct], Nv, DMPolytopeTypeGetNumVertices(ct)); 847442363296SMatthew G. Knepley } 8475ca8062c8SMatthew G. Knepley PetscFunctionReturn(0); 8476ca8062c8SMatthew G. Knepley } 84779bf0dad6SMatthew G. Knepley 84789bf0dad6SMatthew G. Knepley /*@ 84799bf0dad6SMatthew 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 84809bf0dad6SMatthew G. Knepley 8481899ea2b8SJacob Faibussowitsch Not Collective 8482899ea2b8SJacob Faibussowitsch 84839bf0dad6SMatthew G. Knepley Input Parameters: 84849bf0dad6SMatthew G. Knepley + dm - The DMPlex object 84859bf0dad6SMatthew G. Knepley - cellHeight - Normally 0 84869bf0dad6SMatthew G. Knepley 848745da879fSVaclav Hapla Notes: 848845da879fSVaclav Hapla This is a useful diagnostic when creating meshes programmatically. 848945da879fSVaclav Hapla This routine is only relevant for meshes that are fully interpolated across all ranks. 849045da879fSVaclav Hapla It will error out if a partially interpolated mesh is given on some rank. 849145da879fSVaclav Hapla It will do nothing for locally uninterpolated mesh (as there is nothing to check). 84929bf0dad6SMatthew G. Knepley 849395eb5ee5SVaclav Hapla For the complete list of DMPlexCheck* functions, see DMSetFromOptions(). 849495eb5ee5SVaclav Hapla 84959bf0dad6SMatthew G. Knepley Level: developer 84969bf0dad6SMatthew G. Knepley 849795eb5ee5SVaclav Hapla .seealso: DMCreate(), DMPlexGetVTKCellHeight(), DMSetFromOptions() 84989bf0dad6SMatthew G. Knepley @*/ 849925c50c26SVaclav Hapla PetscErrorCode DMPlexCheckFaces(DM dm, PetscInt cellHeight) 85009bf0dad6SMatthew G. Knepley { 8501ab91121cSMatthew G. Knepley PetscInt dim, depth, vStart, vEnd, cStart, cEnd, c, h; 85029bf0dad6SMatthew G. Knepley PetscErrorCode ierr; 8503899ea2b8SJacob Faibussowitsch DMPlexInterpolatedFlag interpEnum; 85049bf0dad6SMatthew G. Knepley 85059bf0dad6SMatthew G. Knepley PetscFunctionBegin; 85069bf0dad6SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8507899ea2b8SJacob Faibussowitsch ierr = DMPlexIsInterpolated(dm, &interpEnum);CHKERRQ(ierr); 850845da879fSVaclav Hapla if (interpEnum == DMPLEX_INTERPOLATED_NONE) PetscFunctionReturn(0); 850945da879fSVaclav Hapla if (interpEnum == DMPLEX_INTERPOLATED_PARTIAL) { 8510899ea2b8SJacob Faibussowitsch PetscMPIInt rank; 8511899ea2b8SJacob Faibussowitsch MPI_Comm comm; 8512899ea2b8SJacob Faibussowitsch 8513899ea2b8SJacob Faibussowitsch ierr = PetscObjectGetComm((PetscObject) dm, &comm);CHKERRQ(ierr); 8514ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 851545da879fSVaclav Hapla SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "Mesh is only partially interpolated on rank %d, this is currently not supported", rank); 8516899ea2b8SJacob Faibussowitsch } 8517899ea2b8SJacob Faibussowitsch 8518c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 8519ab91121cSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 85209bf0dad6SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 8521ab91121cSMatthew G. Knepley for (h = cellHeight; h < PetscMin(depth, dim); ++h) { 85223554e41dSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, h, &cStart, &cEnd);CHKERRQ(ierr); 85233554e41dSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 8524412e9a14SMatthew G. Knepley const PetscInt *cone, *ornt, *faceSizes, *faces; 8525412e9a14SMatthew G. Knepley const DMPolytopeType *faceTypes; 8526ba2698f1SMatthew G. Knepley DMPolytopeType ct; 8527412e9a14SMatthew G. Knepley PetscInt numFaces, coneSize, f; 8528412e9a14SMatthew G. Knepley PetscInt *closure = NULL, closureSize, cl, numCorners = 0, fOff = 0, unsplit; 85299bf0dad6SMatthew G. Knepley 8530ba2698f1SMatthew G. Knepley ierr = DMPlexGetCellType(dm, c, &ct);CHKERRQ(ierr); 8531412e9a14SMatthew G. Knepley ierr = DMPlexCellUnsplitVertices_Private(dm, c, ct, &unsplit);CHKERRQ(ierr); 8532412e9a14SMatthew G. Knepley if (unsplit) continue; 85339bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, c, &coneSize);CHKERRQ(ierr); 85349bf0dad6SMatthew G. Knepley ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 85359bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 85369bf0dad6SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 85379bf0dad6SMatthew G. Knepley for (cl = 0; cl < closureSize*2; cl += 2) { 85389bf0dad6SMatthew G. Knepley const PetscInt p = closure[cl]; 85399bf0dad6SMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) closure[numCorners++] = p; 85409bf0dad6SMatthew G. Knepley } 8541412e9a14SMatthew G. Knepley ierr = DMPlexGetRawFaces_Internal(dm, ct, closure, &numFaces, &faceTypes, &faceSizes, &faces);CHKERRQ(ierr); 8542d4961f80SStefano Zampini if (coneSize != numFaces) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cell %D of type %s has %D faces but should have %D", c, DMPolytopeTypes[ct], coneSize, numFaces); 85439bf0dad6SMatthew G. Knepley for (f = 0; f < numFaces; ++f) { 8544d4961f80SStefano Zampini DMPolytopeType fct; 85459bf0dad6SMatthew G. Knepley PetscInt *fclosure = NULL, fclosureSize, cl, fnumCorners = 0, v; 85469bf0dad6SMatthew G. Knepley 8547d4961f80SStefano Zampini ierr = DMPlexGetCellType(dm, cone[f], &fct);CHKERRQ(ierr); 85489bf0dad6SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure_Internal(dm, cone[f], ornt[f], PETSC_TRUE, &fclosureSize, &fclosure);CHKERRQ(ierr); 85499bf0dad6SMatthew G. Knepley for (cl = 0; cl < fclosureSize*2; cl += 2) { 85509bf0dad6SMatthew G. Knepley const PetscInt p = fclosure[cl]; 85519bf0dad6SMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) fclosure[fnumCorners++] = p; 85529bf0dad6SMatthew G. Knepley } 8553d4961f80SStefano Zampini if (fnumCorners != faceSizes[f]) SETERRQ7(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]); 85549bf0dad6SMatthew G. Knepley for (v = 0; v < fnumCorners; ++v) { 8555b5a892a1SMatthew G. Knepley if (fclosure[v] != faces[fOff+v]) { 8556b5a892a1SMatthew G. Knepley PetscInt v1; 8557b5a892a1SMatthew G. Knepley 8558b5a892a1SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, "face closure:");CHKERRQ(ierr); 8559b5a892a1SMatthew G. Knepley for (v1 = 0; v1 < fnumCorners; ++v1) {ierr = PetscPrintf(PETSC_COMM_SELF, " %D", fclosure[v1]);CHKERRQ(ierr);} 8560b5a892a1SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, "\ncell face:");CHKERRQ(ierr); 8561b5a892a1SMatthew G. Knepley for (v1 = 0; v1 < fnumCorners; ++v1) {ierr = PetscPrintf(PETSC_COMM_SELF, " %D", faces[fOff+v1]);CHKERRQ(ierr);} 8562b5a892a1SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 8563b5a892a1SMatthew G. Knepley SETERRQ9(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]); 8564b5a892a1SMatthew G. Knepley } 85659bf0dad6SMatthew G. Knepley } 85669bf0dad6SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, cone[f], PETSC_TRUE, &fclosureSize, &fclosure);CHKERRQ(ierr); 8567412e9a14SMatthew G. Knepley fOff += faceSizes[f]; 85689bf0dad6SMatthew G. Knepley } 8569412e9a14SMatthew G. Knepley ierr = DMPlexRestoreRawFaces_Internal(dm, ct, closure, &numFaces, &faceTypes, &faceSizes, &faces);CHKERRQ(ierr); 85709bf0dad6SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 85719bf0dad6SMatthew G. Knepley } 85723554e41dSMatthew G. Knepley } 8573552f7358SJed Brown PetscFunctionReturn(0); 8574552f7358SJed Brown } 85753913d7c8SMatthew G. Knepley 8576bb6a34a8SMatthew G. Knepley /*@ 8577bb6a34a8SMatthew G. Knepley DMPlexCheckGeometry - Check the geometry of mesh cells 8578bb6a34a8SMatthew G. Knepley 8579bb6a34a8SMatthew G. Knepley Input Parameter: 8580bb6a34a8SMatthew G. Knepley . dm - The DMPlex object 8581bb6a34a8SMatthew G. Knepley 858295eb5ee5SVaclav Hapla Notes: 858395eb5ee5SVaclav Hapla This is a useful diagnostic when creating meshes programmatically. 858495eb5ee5SVaclav Hapla 858595eb5ee5SVaclav Hapla For the complete list of DMPlexCheck* functions, see DMSetFromOptions(). 8586bb6a34a8SMatthew G. Knepley 8587bb6a34a8SMatthew G. Knepley Level: developer 8588bb6a34a8SMatthew G. Knepley 858995eb5ee5SVaclav Hapla .seealso: DMCreate(), DMSetFromOptions() 8590bb6a34a8SMatthew G. Knepley @*/ 8591bb6a34a8SMatthew G. Knepley PetscErrorCode DMPlexCheckGeometry(DM dm) 8592bb6a34a8SMatthew G. Knepley { 8593a2a9e04cSMatthew G. Knepley Vec coordinates; 8594bb6a34a8SMatthew G. Knepley PetscReal detJ, J[9], refVol = 1.0; 8595bb6a34a8SMatthew G. Knepley PetscReal vol; 8596412e9a14SMatthew G. Knepley PetscBool periodic; 859751a74b61SMatthew G. Knepley PetscInt dim, depth, dE, d, cStart, cEnd, c; 8598bb6a34a8SMatthew G. Knepley PetscErrorCode ierr; 8599bb6a34a8SMatthew G. Knepley 8600bb6a34a8SMatthew G. Knepley PetscFunctionBegin; 8601bb6a34a8SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 860251a74b61SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dE);CHKERRQ(ierr); 860351a74b61SMatthew G. Knepley if (dim != dE) PetscFunctionReturn(0); 8604bb6a34a8SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 8605412e9a14SMatthew G. Knepley ierr = DMGetPeriodicity(dm, &periodic, NULL, NULL, NULL);CHKERRQ(ierr); 8606bb6a34a8SMatthew G. Knepley for (d = 0; d < dim; ++d) refVol *= 2.0; 8607bb6a34a8SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 8608a2a9e04cSMatthew G. Knepley /* Make sure local coordinates are created, because that step is collective */ 8609a2a9e04cSMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 8610412e9a14SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 8611412e9a14SMatthew G. Knepley DMPolytopeType ct; 8612412e9a14SMatthew G. Knepley PetscInt unsplit; 8613412e9a14SMatthew G. Knepley PetscBool ignoreZeroVol = PETSC_FALSE; 8614412e9a14SMatthew G. Knepley 8615412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, c, &ct);CHKERRQ(ierr); 8616412e9a14SMatthew G. Knepley switch (ct) { 8617412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 8618412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 8619412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 8620412e9a14SMatthew G. Knepley ignoreZeroVol = PETSC_TRUE; break; 8621412e9a14SMatthew G. Knepley default: break; 8622412e9a14SMatthew G. Knepley } 8623412e9a14SMatthew G. Knepley switch (ct) { 8624412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: 8625412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 8626412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 8627a2a9e04cSMatthew G. Knepley case DM_POLYTOPE_PYRAMID: 8628412e9a14SMatthew G. Knepley continue; 8629412e9a14SMatthew G. Knepley default: break; 8630412e9a14SMatthew G. Knepley } 8631412e9a14SMatthew G. Knepley ierr = DMPlexCellUnsplitVertices_Private(dm, c, ct, &unsplit);CHKERRQ(ierr); 8632412e9a14SMatthew G. Knepley if (unsplit) continue; 8633bb6a34a8SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFEM(dm, c, NULL, NULL, J, NULL, &detJ);CHKERRQ(ierr); 8634d4961f80SStefano Zampini if (detJ < -PETSC_SMALL || (detJ <= 0.0 && !ignoreZeroVol)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Mesh cell %D of type %s is inverted, |J| = %g", c, DMPolytopeTypes[ct], (double) detJ); 8635bb6a34a8SMatthew G. Knepley ierr = PetscInfo2(dm, "Cell %D FEM Volume %g\n", c, (double) detJ*refVol);CHKERRQ(ierr); 8636412e9a14SMatthew G. Knepley if (depth > 1 && !periodic) { 8637bb6a34a8SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFVM(dm, c, &vol, NULL, NULL);CHKERRQ(ierr); 8638d4961f80SStefano Zampini if (vol < -PETSC_SMALL || (vol <= 0.0 && !ignoreZeroVol)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Mesh cell %D of type %s is inverted, vol = %g", c, DMPolytopeTypes[ct], (double) vol); 8639bb6a34a8SMatthew G. Knepley ierr = PetscInfo2(dm, "Cell %D FVM Volume %g\n", c, (double) vol);CHKERRQ(ierr); 8640bb6a34a8SMatthew G. Knepley } 8641bb6a34a8SMatthew G. Knepley } 8642bb6a34a8SMatthew G. Knepley PetscFunctionReturn(0); 8643bb6a34a8SMatthew G. Knepley } 8644bb6a34a8SMatthew G. Knepley 864503da9461SVaclav Hapla /*@ 8646e83a0d2dSVaclav Hapla DMPlexCheckPointSF - Check that several necessary conditions are met for the point SF of this plex. 864703da9461SVaclav Hapla 864803da9461SVaclav Hapla Input Parameters: 864903da9461SVaclav Hapla . dm - The DMPlex object 865003da9461SVaclav Hapla 8651e83a0d2dSVaclav Hapla Notes: 8652e83a0d2dSVaclav Hapla This is mainly intended for debugging/testing purposes. 86538918e3e2SVaclav Hapla It currently checks only meshes with no partition overlapping. 865403da9461SVaclav Hapla 865595eb5ee5SVaclav Hapla For the complete list of DMPlexCheck* functions, see DMSetFromOptions(). 865695eb5ee5SVaclav Hapla 865703da9461SVaclav Hapla Level: developer 865803da9461SVaclav Hapla 865995eb5ee5SVaclav Hapla .seealso: DMGetPointSF(), DMSetFromOptions() 866003da9461SVaclav Hapla @*/ 866103da9461SVaclav Hapla PetscErrorCode DMPlexCheckPointSF(DM dm) 866203da9461SVaclav Hapla { 8663f0cfc026SVaclav Hapla PetscSF pointSF; 8664f5869d18SMatthew G. Knepley PetscInt cellHeight, cStart, cEnd, l, nleaves, nroots, overlap; 8665f5869d18SMatthew G. Knepley const PetscInt *locals, *rootdegree; 8666f0cfc026SVaclav Hapla PetscBool distributed; 866703da9461SVaclav Hapla PetscErrorCode ierr; 866803da9461SVaclav Hapla 866903da9461SVaclav Hapla PetscFunctionBegin; 867003da9461SVaclav Hapla PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8671f0cfc026SVaclav Hapla ierr = DMGetPointSF(dm, &pointSF);CHKERRQ(ierr); 8672f0cfc026SVaclav Hapla ierr = DMPlexIsDistributed(dm, &distributed);CHKERRQ(ierr); 8673f0cfc026SVaclav Hapla if (!distributed) PetscFunctionReturn(0); 8674f0cfc026SVaclav Hapla ierr = DMPlexGetOverlap(dm, &overlap);CHKERRQ(ierr); 8675f0cfc026SVaclav Hapla if (overlap) { 86761e1ea65dSPierre Jolivet ierr = PetscPrintf(PetscObjectComm((PetscObject)dm), "Warning: DMPlexCheckPointSF() is currently not implemented for meshes with partition overlapping");CHKERRQ(ierr); 86778918e3e2SVaclav Hapla PetscFunctionReturn(0); 86788918e3e2SVaclav Hapla } 8679f0cfc026SVaclav Hapla if (!pointSF) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "This DMPlex is distributed but does not have PointSF attached"); 8680f0cfc026SVaclav Hapla ierr = PetscSFGetGraph(pointSF, &nroots, &nleaves, &locals, NULL);CHKERRQ(ierr); 8681f0cfc026SVaclav Hapla if (nroots < 0) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "This DMPlex is distributed but its PointSF has no graph set"); 8682f5869d18SMatthew G. Knepley ierr = PetscSFComputeDegreeBegin(pointSF, &rootdegree);CHKERRQ(ierr); 8683f5869d18SMatthew G. Knepley ierr = PetscSFComputeDegreeEnd(pointSF, &rootdegree);CHKERRQ(ierr); 868403da9461SVaclav Hapla 8685ece87651SVaclav Hapla /* 1) check there are no faces in 2D, cells in 3D, in interface */ 8686f5869d18SMatthew G. Knepley ierr = DMPlexGetVTKCellHeight(dm, &cellHeight);CHKERRQ(ierr); 8687f5869d18SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, cellHeight, &cStart, &cEnd);CHKERRQ(ierr); 8688f5869d18SMatthew G. Knepley for (l = 0; l < nleaves; ++l) { 8689f5869d18SMatthew G. Knepley const PetscInt point = locals[l]; 8690f5869d18SMatthew G. Knepley 8691f5869d18SMatthew G. Knepley if (point >= cStart && point < cEnd) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point SF contains %D which is a cell", point); 869203da9461SVaclav Hapla } 8693ece87651SVaclav Hapla 8694f5869d18SMatthew G. Knepley /* 2) if some point is in interface, then all its cone points must be also in interface (either as leaves or roots) */ 8695f5869d18SMatthew G. Knepley for (l = 0; l < nleaves; ++l) { 8696f5869d18SMatthew G. Knepley const PetscInt point = locals[l]; 8697f5869d18SMatthew G. Knepley const PetscInt *cone; 8698f5869d18SMatthew G. Knepley PetscInt coneSize, c, idx; 8699f5869d18SMatthew G. Knepley 8700f5869d18SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, point, &coneSize);CHKERRQ(ierr); 8701f5869d18SMatthew G. Knepley ierr = DMPlexGetCone(dm, point, &cone);CHKERRQ(ierr); 8702f5869d18SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 8703f5869d18SMatthew G. Knepley if (!rootdegree[cone[c]]) { 8704f5869d18SMatthew G. Knepley ierr = PetscFindInt(cone[c], nleaves, locals, &idx);CHKERRQ(ierr); 8705f5869d18SMatthew G. Knepley if (idx < 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point SF contains %D but not %D from its cone", point, cone[c]); 8706f5869d18SMatthew G. Knepley } 8707f5869d18SMatthew G. Knepley } 8708ece87651SVaclav Hapla } 870903da9461SVaclav Hapla PetscFunctionReturn(0); 871003da9461SVaclav Hapla } 871103da9461SVaclav Hapla 8712b5a892a1SMatthew G. Knepley PetscErrorCode DMPlexCheckAll_Internal(DM dm, PetscInt cellHeight) 8713b5a892a1SMatthew G. Knepley { 8714b5a892a1SMatthew G. Knepley PetscErrorCode ierr; 8715b5a892a1SMatthew G. Knepley 8716b5a892a1SMatthew G. Knepley PetscFunctionBegin; 8717b5a892a1SMatthew G. Knepley ierr = DMPlexCheckSymmetry(dm);CHKERRQ(ierr); 8718b5a892a1SMatthew G. Knepley ierr = DMPlexCheckSkeleton(dm, cellHeight);CHKERRQ(ierr); 8719b5a892a1SMatthew G. Knepley ierr = DMPlexCheckFaces(dm, cellHeight);CHKERRQ(ierr); 8720b5a892a1SMatthew G. Knepley ierr = DMPlexCheckGeometry(dm);CHKERRQ(ierr); 8721b5a892a1SMatthew G. Knepley ierr = DMPlexCheckPointSF(dm);CHKERRQ(ierr); 8722b5a892a1SMatthew G. Knepley ierr = DMPlexCheckInterfaceCones(dm);CHKERRQ(ierr); 8723b5a892a1SMatthew G. Knepley PetscFunctionReturn(0); 8724b5a892a1SMatthew G. Knepley } 8725b5a892a1SMatthew G. Knepley 8726068a5610SStefano Zampini typedef struct cell_stats 8727068a5610SStefano Zampini { 8728068a5610SStefano Zampini PetscReal min, max, sum, squaresum; 8729068a5610SStefano Zampini PetscInt count; 8730068a5610SStefano Zampini } cell_stats_t; 8731068a5610SStefano Zampini 873225befc3bSSatish Balay static void MPIAPI cell_stats_reduce(void *a, void *b, int * len, MPI_Datatype *datatype) 8733068a5610SStefano Zampini { 8734068a5610SStefano Zampini PetscInt i, N = *len; 8735068a5610SStefano Zampini 8736068a5610SStefano Zampini for (i = 0; i < N; i++) { 8737068a5610SStefano Zampini cell_stats_t *A = (cell_stats_t *) a; 8738068a5610SStefano Zampini cell_stats_t *B = (cell_stats_t *) b; 8739068a5610SStefano Zampini 8740068a5610SStefano Zampini B->min = PetscMin(A->min,B->min); 8741068a5610SStefano Zampini B->max = PetscMax(A->max,B->max); 8742068a5610SStefano Zampini B->sum += A->sum; 8743068a5610SStefano Zampini B->squaresum += A->squaresum; 8744068a5610SStefano Zampini B->count += A->count; 8745068a5610SStefano Zampini } 8746068a5610SStefano Zampini } 8747068a5610SStefano Zampini 8748068a5610SStefano Zampini /*@ 874943fa8764SMatthew G. Knepley DMPlexCheckCellShape - Checks the Jacobian of the mapping from reference to real cells and computes some minimal statistics. 8750068a5610SStefano Zampini 87518261a58bSMatthew G. Knepley Collective on dm 87528261a58bSMatthew G. Knepley 8753068a5610SStefano Zampini Input Parameters: 8754068a5610SStefano Zampini + dm - The DMPlex object 875543fa8764SMatthew G. Knepley . output - If true, statistics will be displayed on stdout 875643fa8764SMatthew G. Knepley - condLimit - Display all cells above this condition number, or PETSC_DETERMINE for no cell output 8757068a5610SStefano Zampini 875895eb5ee5SVaclav Hapla Notes: 875995eb5ee5SVaclav Hapla This is mainly intended for debugging/testing purposes. 876095eb5ee5SVaclav Hapla 876195eb5ee5SVaclav Hapla For the complete list of DMPlexCheck* functions, see DMSetFromOptions(). 8762068a5610SStefano Zampini 8763068a5610SStefano Zampini Level: developer 8764068a5610SStefano Zampini 8765f108dbd7SJacob Faibussowitsch .seealso: DMSetFromOptions(), DMPlexComputeOrthogonalQuality() 8766068a5610SStefano Zampini @*/ 876743fa8764SMatthew G. Knepley PetscErrorCode DMPlexCheckCellShape(DM dm, PetscBool output, PetscReal condLimit) 8768068a5610SStefano Zampini { 8769068a5610SStefano Zampini DM dmCoarse; 877043fa8764SMatthew G. Knepley cell_stats_t stats, globalStats; 877143fa8764SMatthew G. Knepley MPI_Comm comm = PetscObjectComm((PetscObject)dm); 877243fa8764SMatthew G. Knepley PetscReal *J, *invJ, min = 0, max = 0, mean = 0, stdev = 0; 877343fa8764SMatthew G. Knepley PetscReal limit = condLimit > 0 ? condLimit : PETSC_MAX_REAL; 8774412e9a14SMatthew G. Knepley PetscInt cdim, cStart, cEnd, c, eStart, eEnd, count = 0; 877543fa8764SMatthew G. Knepley PetscMPIInt rank,size; 8776068a5610SStefano Zampini PetscErrorCode ierr; 8777068a5610SStefano Zampini 8778068a5610SStefano Zampini PetscFunctionBegin; 8779068a5610SStefano Zampini PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8780068a5610SStefano Zampini stats.min = PETSC_MAX_REAL; 8781068a5610SStefano Zampini stats.max = PETSC_MIN_REAL; 8782068a5610SStefano Zampini stats.sum = stats.squaresum = 0.; 8783068a5610SStefano Zampini stats.count = 0; 8784068a5610SStefano Zampini 8785ffc4695bSBarry Smith ierr = MPI_Comm_size(comm, &size);CHKERRMPI(ierr); 8786ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 878743fa8764SMatthew G. Knepley ierr = DMGetCoordinateDim(dm,&cdim);CHKERRQ(ierr); 878843fa8764SMatthew G. Knepley ierr = PetscMalloc2(PetscSqr(cdim), &J, PetscSqr(cdim), &invJ);CHKERRQ(ierr); 8789412e9a14SMatthew G. Knepley ierr = DMPlexGetSimplexOrBoxCells(dm,0,&cStart,&cEnd);CHKERRQ(ierr); 879043fa8764SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm,1,&eStart,&eEnd);CHKERRQ(ierr); 8791412e9a14SMatthew G. Knepley for (c = cStart; c < cEnd; c++) { 8792068a5610SStefano Zampini PetscInt i; 8793068a5610SStefano Zampini PetscReal frobJ = 0., frobInvJ = 0., cond2, cond, detJ; 8794068a5610SStefano Zampini 8795068a5610SStefano Zampini ierr = DMPlexComputeCellGeometryAffineFEM(dm,c,NULL,J,invJ,&detJ);CHKERRQ(ierr); 8796068a5610SStefano Zampini if (detJ < 0.0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Mesh cell %D is inverted", c); 879743fa8764SMatthew G. Knepley for (i = 0; i < PetscSqr(cdim); ++i) { 8798068a5610SStefano Zampini frobJ += J[i] * J[i]; 8799068a5610SStefano Zampini frobInvJ += invJ[i] * invJ[i]; 8800068a5610SStefano Zampini } 8801068a5610SStefano Zampini cond2 = frobJ * frobInvJ; 8802068a5610SStefano Zampini cond = PetscSqrtReal(cond2); 8803068a5610SStefano Zampini 8804068a5610SStefano Zampini stats.min = PetscMin(stats.min,cond); 8805068a5610SStefano Zampini stats.max = PetscMax(stats.max,cond); 8806068a5610SStefano Zampini stats.sum += cond; 8807068a5610SStefano Zampini stats.squaresum += cond2; 8808068a5610SStefano Zampini stats.count++; 88098261a58bSMatthew G. Knepley if (output && cond > limit) { 881043fa8764SMatthew G. Knepley PetscSection coordSection; 881143fa8764SMatthew G. Knepley Vec coordsLocal; 881243fa8764SMatthew G. Knepley PetscScalar *coords = NULL; 881343fa8764SMatthew G. Knepley PetscInt Nv, d, clSize, cl, *closure = NULL; 881443fa8764SMatthew G. Knepley 881543fa8764SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordsLocal);CHKERRQ(ierr); 881643fa8764SMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 881743fa8764SMatthew G. Knepley ierr = DMPlexVecGetClosure(dm, coordSection, coordsLocal, c, &Nv, &coords);CHKERRQ(ierr); 8818087ef6b2SMatthew G. Knepley ierr = PetscSynchronizedPrintf(comm, "[%d] Cell %D cond %g\n", rank, c, (double) cond);CHKERRQ(ierr); 881943fa8764SMatthew G. Knepley for (i = 0; i < Nv/cdim; ++i) { 882043fa8764SMatthew G. Knepley ierr = PetscSynchronizedPrintf(comm, " Vertex %D: (", i);CHKERRQ(ierr); 882143fa8764SMatthew G. Knepley for (d = 0; d < cdim; ++d) { 882243fa8764SMatthew G. Knepley if (d > 0) {ierr = PetscSynchronizedPrintf(comm, ", ");CHKERRQ(ierr);} 882348afe810SSatish Balay ierr = PetscSynchronizedPrintf(comm, "%g", (double) PetscRealPart(coords[i*cdim+d]));CHKERRQ(ierr); 882443fa8764SMatthew G. Knepley } 882543fa8764SMatthew G. Knepley ierr = PetscSynchronizedPrintf(comm, ")\n");CHKERRQ(ierr); 882643fa8764SMatthew G. Knepley } 882743fa8764SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &clSize, &closure);CHKERRQ(ierr); 882843fa8764SMatthew G. Knepley for (cl = 0; cl < clSize*2; cl += 2) { 882943fa8764SMatthew G. Knepley const PetscInt edge = closure[cl]; 883043fa8764SMatthew G. Knepley 883143fa8764SMatthew G. Knepley if ((edge >= eStart) && (edge < eEnd)) { 883243fa8764SMatthew G. Knepley PetscReal len; 883343fa8764SMatthew G. Knepley 883443fa8764SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFVM(dm, edge, &len, NULL, NULL);CHKERRQ(ierr); 8835087ef6b2SMatthew G. Knepley ierr = PetscSynchronizedPrintf(comm, " Edge %D: length %g\n", edge, (double) len);CHKERRQ(ierr); 883643fa8764SMatthew G. Knepley } 883743fa8764SMatthew G. Knepley } 883843fa8764SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &clSize, &closure);CHKERRQ(ierr); 883943fa8764SMatthew G. Knepley ierr = DMPlexVecRestoreClosure(dm, coordSection, coordsLocal, c, &Nv, &coords);CHKERRQ(ierr); 884043fa8764SMatthew G. Knepley } 8841068a5610SStefano Zampini } 88428261a58bSMatthew G. Knepley if (output) {ierr = PetscSynchronizedFlush(comm, NULL);CHKERRQ(ierr);} 8843068a5610SStefano Zampini 8844068a5610SStefano Zampini if (size > 1) { 8845068a5610SStefano Zampini PetscMPIInt blockLengths[2] = {4,1}; 8846068a5610SStefano Zampini MPI_Aint blockOffsets[2] = {offsetof(cell_stats_t,min),offsetof(cell_stats_t,count)}; 8847068a5610SStefano Zampini MPI_Datatype blockTypes[2] = {MPIU_REAL,MPIU_INT}, statType; 8848068a5610SStefano Zampini MPI_Op statReduce; 8849068a5610SStefano Zampini 8850ffc4695bSBarry Smith ierr = MPI_Type_create_struct(2,blockLengths,blockOffsets,blockTypes,&statType);CHKERRMPI(ierr); 8851ffc4695bSBarry Smith ierr = MPI_Type_commit(&statType);CHKERRMPI(ierr); 8852ffc4695bSBarry Smith ierr = MPI_Op_create(cell_stats_reduce, PETSC_TRUE, &statReduce);CHKERRMPI(ierr); 8853ffc4695bSBarry Smith ierr = MPI_Reduce(&stats,&globalStats,1,statType,statReduce,0,comm);CHKERRMPI(ierr); 8854ffc4695bSBarry Smith ierr = MPI_Op_free(&statReduce);CHKERRMPI(ierr); 8855ffc4695bSBarry Smith ierr = MPI_Type_free(&statType);CHKERRMPI(ierr); 8856068a5610SStefano Zampini } else { 8857580bdb30SBarry Smith ierr = PetscArraycpy(&globalStats,&stats,1);CHKERRQ(ierr); 8858068a5610SStefano Zampini } 8859dd400576SPatrick Sanan if (rank == 0) { 8860068a5610SStefano Zampini count = globalStats.count; 8861068a5610SStefano Zampini min = globalStats.min; 8862068a5610SStefano Zampini max = globalStats.max; 8863068a5610SStefano Zampini mean = globalStats.sum / globalStats.count; 8864068a5610SStefano Zampini stdev = globalStats.count > 1 ? PetscSqrtReal(PetscMax((globalStats.squaresum - globalStats.count * mean * mean) / (globalStats.count - 1),0)) : 0.0; 8865068a5610SStefano Zampini } 8866068a5610SStefano Zampini 8867068a5610SStefano Zampini if (output) { 8868068a5610SStefano 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); 8869068a5610SStefano Zampini } 8870068a5610SStefano Zampini ierr = PetscFree2(J,invJ);CHKERRQ(ierr); 8871068a5610SStefano Zampini 8872068a5610SStefano Zampini ierr = DMGetCoarseDM(dm,&dmCoarse);CHKERRQ(ierr); 8873068a5610SStefano Zampini if (dmCoarse) { 8874068a5610SStefano Zampini PetscBool isplex; 8875068a5610SStefano Zampini 8876068a5610SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)dmCoarse,DMPLEX,&isplex);CHKERRQ(ierr); 8877068a5610SStefano Zampini if (isplex) { 887843fa8764SMatthew G. Knepley ierr = DMPlexCheckCellShape(dmCoarse,output,condLimit);CHKERRQ(ierr); 8879068a5610SStefano Zampini } 8880068a5610SStefano Zampini } 8881068a5610SStefano Zampini PetscFunctionReturn(0); 8882068a5610SStefano Zampini } 8883068a5610SStefano Zampini 8884f108dbd7SJacob Faibussowitsch /*@ 8885f108dbd7SJacob Faibussowitsch DMPlexComputeOrthogonalQuality - Compute cell-wise orthogonal quality mesh statistic. Optionally tags all cells with 8886f108dbd7SJacob Faibussowitsch orthogonal quality below given tolerance. 8887f108dbd7SJacob Faibussowitsch 88886ed19f2fSJacob Faibussowitsch Collective on dm 8889f108dbd7SJacob Faibussowitsch 8890f108dbd7SJacob Faibussowitsch Input Parameters: 8891f108dbd7SJacob Faibussowitsch + dm - The DMPlex object 8892f108dbd7SJacob Faibussowitsch . fv - Optional PetscFV object for pre-computed cell/face centroid information 8893f108dbd7SJacob Faibussowitsch - atol - [0, 1] Absolute tolerance for tagging cells. 8894f108dbd7SJacob Faibussowitsch 8895f108dbd7SJacob Faibussowitsch Output Parameters: 8896f108dbd7SJacob Faibussowitsch + OrthQual - Vec containing orthogonal quality per cell 8897f108dbd7SJacob Faibussowitsch - OrthQualLabel - DMLabel tagging cells below atol with DM_ADAPT_REFINE 8898f108dbd7SJacob Faibussowitsch 8899f108dbd7SJacob Faibussowitsch Options Database Keys: 8900f108dbd7SJacob Faibussowitsch + -dm_plex_orthogonal_quality_label_view - view OrthQualLabel if label is requested. Currently only PETSCVIEWERASCII is 8901f108dbd7SJacob Faibussowitsch supported. 8902f108dbd7SJacob Faibussowitsch - -dm_plex_orthogonal_quality_vec_view - view OrthQual vector. 8903f108dbd7SJacob Faibussowitsch 8904f108dbd7SJacob Faibussowitsch Notes: 8905f108dbd7SJacob Faibussowitsch Orthogonal quality is given by the following formula: 8906f108dbd7SJacob Faibussowitsch 8907f108dbd7SJacob Faibussowitsch \min \left[ \frac{A_i \cdot f_i}{\|A_i\| \|f_i\|} , \frac{A_i \cdot c_i}{\|A_i\| \|c_i\|} \right] 8908f108dbd7SJacob Faibussowitsch 8909f108dbd7SJacob 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 8910f108dbd7SJacob Faibussowitsch is the vector from the current cells centroid to the centroid of its i'th neighbor (which shares a face with the 8911f108dbd7SJacob Faibussowitsch current cell). This computes the vector similarity between each cell face and its corresponding neighbor centroid by 8912f108dbd7SJacob Faibussowitsch calculating the cosine of the angle between these vectors. 8913f108dbd7SJacob Faibussowitsch 8914f108dbd7SJacob Faibussowitsch Orthogonal quality ranges from 1 (best) to 0 (worst). 8915f108dbd7SJacob Faibussowitsch 8916f108dbd7SJacob Faibussowitsch This routine is mainly useful for FVM, however is not restricted to only FVM. The PetscFV object is optionally used to check for 8917f108dbd7SJacob Faibussowitsch pre-computed FVM cell data, but if it is not passed in then this data will be computed. 8918f108dbd7SJacob Faibussowitsch 8919f108dbd7SJacob Faibussowitsch Cells are tagged if they have an orthogonal quality less than or equal to the absolute tolerance. 8920f108dbd7SJacob Faibussowitsch 8921f108dbd7SJacob Faibussowitsch Level: intermediate 8922f108dbd7SJacob Faibussowitsch 8923f108dbd7SJacob Faibussowitsch .seealso: DMPlexCheckCellShape(), DMCreateLabel() 8924f108dbd7SJacob Faibussowitsch @*/ 8925f108dbd7SJacob Faibussowitsch PetscErrorCode DMPlexComputeOrthogonalQuality(DM dm, PetscFV fv, PetscReal atol, Vec *OrthQual, DMLabel *OrthQualLabel) 8926f108dbd7SJacob Faibussowitsch { 89276ed19f2fSJacob Faibussowitsch PetscInt nc, cellHeight, cStart, cEnd, cell, cellIter = 0; 89286ed19f2fSJacob Faibussowitsch PetscInt *idx; 89296ed19f2fSJacob Faibussowitsch PetscScalar *oqVals; 8930f108dbd7SJacob Faibussowitsch const PetscScalar *cellGeomArr, *faceGeomArr; 89316ed19f2fSJacob Faibussowitsch PetscReal *ci, *fi, *Ai; 8932f108dbd7SJacob Faibussowitsch MPI_Comm comm; 8933f108dbd7SJacob Faibussowitsch Vec cellgeom, facegeom; 8934f108dbd7SJacob Faibussowitsch DM dmFace, dmCell; 8935f108dbd7SJacob Faibussowitsch IS glob; 8936f108dbd7SJacob Faibussowitsch ISLocalToGlobalMapping ltog; 8937f108dbd7SJacob Faibussowitsch PetscViewer vwr; 8938f108dbd7SJacob Faibussowitsch PetscErrorCode ierr; 8939f108dbd7SJacob Faibussowitsch 8940f108dbd7SJacob Faibussowitsch PetscFunctionBegin; 8941f108dbd7SJacob Faibussowitsch PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 89426ed19f2fSJacob Faibussowitsch if (fv) {PetscValidHeaderSpecific(fv, PETSCFV_CLASSID, 2);} 8943f108dbd7SJacob Faibussowitsch PetscValidPointer(OrthQual, 4); 89446ed19f2fSJacob Faibussowitsch if (PetscUnlikelyDebug(atol < 0.0 || atol > 1.0)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %g not in [0,1]",(double)atol); 8945f108dbd7SJacob Faibussowitsch ierr = PetscObjectGetComm((PetscObject) dm, &comm);CHKERRQ(ierr); 8946f108dbd7SJacob Faibussowitsch ierr = DMGetDimension(dm, &nc);CHKERRQ(ierr); 89476ed19f2fSJacob Faibussowitsch if (nc < 2) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "DM must have dimension >= 2 (current %D)", nc); 89486ed19f2fSJacob Faibussowitsch { 89496ed19f2fSJacob Faibussowitsch DMPlexInterpolatedFlag interpFlag; 89506ed19f2fSJacob Faibussowitsch 8951f108dbd7SJacob Faibussowitsch ierr = DMPlexIsInterpolated(dm, &interpFlag);CHKERRQ(ierr); 8952f108dbd7SJacob Faibussowitsch if (interpFlag != DMPLEX_INTERPOLATED_FULL) { 8953f108dbd7SJacob Faibussowitsch PetscMPIInt rank; 8954f108dbd7SJacob Faibussowitsch 8955ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 8956f108dbd7SJacob Faibussowitsch SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "DM must be fully interpolated, DM on rank %d is not fully interpolated", rank); 8957f108dbd7SJacob Faibussowitsch } 89586ed19f2fSJacob Faibussowitsch } 8959f108dbd7SJacob Faibussowitsch if (OrthQualLabel) { 8960f108dbd7SJacob Faibussowitsch PetscValidPointer(OrthQualLabel, 5); 8961f108dbd7SJacob Faibussowitsch ierr = DMCreateLabel(dm, "Orthogonal_Quality");CHKERRQ(ierr); 8962f108dbd7SJacob Faibussowitsch ierr = DMGetLabel(dm, "Orthogonal_Quality", OrthQualLabel);CHKERRQ(ierr); 89636ed19f2fSJacob Faibussowitsch } else {*OrthQualLabel = NULL;} 8964f108dbd7SJacob Faibussowitsch ierr = DMPlexGetVTKCellHeight(dm, &cellHeight);CHKERRQ(ierr); 8965f108dbd7SJacob Faibussowitsch ierr = DMPlexGetHeightStratum(dm, cellHeight, &cStart, &cEnd);CHKERRQ(ierr); 8966f108dbd7SJacob Faibussowitsch ierr = DMPlexCreateCellNumbering_Internal(dm, PETSC_TRUE, &glob);CHKERRQ(ierr); 8967f108dbd7SJacob Faibussowitsch ierr = ISLocalToGlobalMappingCreateIS(glob, <og);CHKERRQ(ierr); 8968f108dbd7SJacob Faibussowitsch ierr = ISLocalToGlobalMappingSetType(ltog, ISLOCALTOGLOBALMAPPINGHASH);CHKERRQ(ierr); 8969f108dbd7SJacob Faibussowitsch ierr = VecCreate(comm, OrthQual);CHKERRQ(ierr); 8970f108dbd7SJacob Faibussowitsch ierr = VecSetType(*OrthQual, VECSTANDARD);CHKERRQ(ierr); 8971f108dbd7SJacob Faibussowitsch ierr = VecSetSizes(*OrthQual, cEnd-cStart, PETSC_DETERMINE);CHKERRQ(ierr); 8972f108dbd7SJacob Faibussowitsch ierr = VecSetLocalToGlobalMapping(*OrthQual, ltog);CHKERRQ(ierr); 8973f108dbd7SJacob Faibussowitsch ierr = VecSetUp(*OrthQual);CHKERRQ(ierr); 8974f108dbd7SJacob Faibussowitsch ierr = ISDestroy(&glob);CHKERRQ(ierr); 8975f108dbd7SJacob Faibussowitsch ierr = ISLocalToGlobalMappingDestroy(<og);CHKERRQ(ierr); 8976f108dbd7SJacob Faibussowitsch ierr = DMPlexGetDataFVM(dm, fv, &cellgeom, &facegeom, NULL);CHKERRQ(ierr); 8977f108dbd7SJacob Faibussowitsch ierr = VecGetArrayRead(cellgeom, &cellGeomArr);CHKERRQ(ierr); 8978f108dbd7SJacob Faibussowitsch ierr = VecGetArrayRead(facegeom, &faceGeomArr);CHKERRQ(ierr); 8979f108dbd7SJacob Faibussowitsch ierr = VecGetDM(cellgeom, &dmCell);CHKERRQ(ierr); 8980f108dbd7SJacob Faibussowitsch ierr = VecGetDM(facegeom, &dmFace);CHKERRQ(ierr); 89816ed19f2fSJacob Faibussowitsch ierr = PetscMalloc5(cEnd-cStart, &idx, cEnd-cStart, &oqVals, nc, &ci, nc, &fi, nc, &Ai);CHKERRQ(ierr); 89826ed19f2fSJacob Faibussowitsch for (cell = cStart; cell < cEnd; cellIter++,cell++) { 89836ed19f2fSJacob Faibussowitsch PetscInt cellneigh, cellneighiter = 0, adjSize = PETSC_DETERMINE; 8984f108dbd7SJacob Faibussowitsch PetscInt cellarr[2], *adj = NULL; 8985f108dbd7SJacob Faibussowitsch PetscScalar *cArr, *fArr; 8986898cd552SSatish Balay PetscReal minvalc = 1.0, minvalf = 1.0; 8987f108dbd7SJacob Faibussowitsch PetscFVCellGeom *cg; 8988f108dbd7SJacob Faibussowitsch 89896ed19f2fSJacob Faibussowitsch idx[cellIter] = cell-cStart; 8990f108dbd7SJacob Faibussowitsch cellarr[0] = cell; 8991f108dbd7SJacob Faibussowitsch /* Make indexing into cellGeom easier */ 8992f108dbd7SJacob Faibussowitsch ierr = DMPlexPointLocalRead(dmCell, cell, cellGeomArr, &cg);CHKERRQ(ierr); 8993f108dbd7SJacob Faibussowitsch ierr = DMPlexGetAdjacency_Internal(dm, cell, PETSC_TRUE, PETSC_FALSE, PETSC_FALSE, &adjSize, &adj);CHKERRQ(ierr); 8994f108dbd7SJacob Faibussowitsch /* Technically 1 too big, but easier than fiddling with empty adjacency array */ 8995f108dbd7SJacob Faibussowitsch ierr = PetscCalloc2(adjSize, &cArr, adjSize, &fArr);CHKERRQ(ierr); 89966ed19f2fSJacob Faibussowitsch for (cellneigh = 0; cellneigh < adjSize; cellneighiter++,cellneigh++) { 89976ed19f2fSJacob Faibussowitsch PetscInt i; 89986ed19f2fSJacob Faibussowitsch const PetscInt neigh = adj[cellneigh]; 8999f108dbd7SJacob Faibussowitsch PetscReal normci = 0, normfi = 0, normai = 0; 9000f108dbd7SJacob Faibussowitsch PetscFVCellGeom *cgneigh; 9001f108dbd7SJacob Faibussowitsch PetscFVFaceGeom *fg; 9002f108dbd7SJacob Faibussowitsch 9003f108dbd7SJacob Faibussowitsch /* Don't count ourselves in the neighbor list */ 9004f108dbd7SJacob Faibussowitsch if (neigh == cell) continue; 9005f108dbd7SJacob Faibussowitsch ierr = DMPlexPointLocalRead(dmCell, neigh, cellGeomArr, &cgneigh);CHKERRQ(ierr); 9006f108dbd7SJacob Faibussowitsch cellarr[1] = neigh; 90076ed19f2fSJacob Faibussowitsch { 90086ed19f2fSJacob Faibussowitsch PetscInt numcovpts; 90096ed19f2fSJacob Faibussowitsch const PetscInt *covpts; 90106ed19f2fSJacob Faibussowitsch 9011f108dbd7SJacob Faibussowitsch ierr = DMPlexGetMeet(dm, 2, cellarr, &numcovpts, &covpts);CHKERRQ(ierr); 9012f108dbd7SJacob Faibussowitsch ierr = DMPlexPointLocalRead(dmFace, covpts[0], faceGeomArr, &fg);CHKERRQ(ierr); 9013f108dbd7SJacob Faibussowitsch ierr = DMPlexRestoreMeet(dm, 2, cellarr, &numcovpts, &covpts);CHKERRQ(ierr); 90146ed19f2fSJacob Faibussowitsch } 9015f108dbd7SJacob Faibussowitsch 9016f108dbd7SJacob Faibussowitsch /* Compute c_i, f_i and their norms */ 9017f108dbd7SJacob Faibussowitsch for (i = 0; i < nc; i++) { 9018f108dbd7SJacob Faibussowitsch ci[i] = cgneigh->centroid[i] - cg->centroid[i]; 9019f108dbd7SJacob Faibussowitsch fi[i] = fg->centroid[i] - cg->centroid[i]; 9020f108dbd7SJacob Faibussowitsch Ai[i] = fg->normal[i]; 9021addd1e01SJunchao Zhang normci += PetscPowReal(ci[i], 2); 9022addd1e01SJunchao Zhang normfi += PetscPowReal(fi[i], 2); 9023addd1e01SJunchao Zhang normai += PetscPowReal(Ai[i], 2); 9024f108dbd7SJacob Faibussowitsch } 9025addd1e01SJunchao Zhang normci = PetscSqrtReal(normci); 9026addd1e01SJunchao Zhang normfi = PetscSqrtReal(normfi); 9027addd1e01SJunchao Zhang normai = PetscSqrtReal(normai); 9028f108dbd7SJacob Faibussowitsch 9029f108dbd7SJacob Faibussowitsch /* Normalize and compute for each face-cell-normal pair */ 9030f108dbd7SJacob Faibussowitsch for (i = 0; i < nc; i++) { 9031f108dbd7SJacob Faibussowitsch ci[i] = ci[i]/normci; 9032f108dbd7SJacob Faibussowitsch fi[i] = fi[i]/normfi; 9033f108dbd7SJacob Faibussowitsch Ai[i] = Ai[i]/normai; 9034f108dbd7SJacob Faibussowitsch /* PetscAbs because I don't know if normals are guaranteed to point out */ 9035f108dbd7SJacob Faibussowitsch cArr[cellneighiter] += PetscAbs(Ai[i]*ci[i]); 9036f108dbd7SJacob Faibussowitsch fArr[cellneighiter] += PetscAbs(Ai[i]*fi[i]); 9037f108dbd7SJacob Faibussowitsch } 9038f108dbd7SJacob Faibussowitsch if (PetscRealPart(cArr[cellneighiter]) < minvalc) { 9039f108dbd7SJacob Faibussowitsch minvalc = PetscRealPart(cArr[cellneighiter]); 9040f108dbd7SJacob Faibussowitsch } 9041f108dbd7SJacob Faibussowitsch if (PetscRealPart(fArr[cellneighiter]) < minvalf) { 9042f108dbd7SJacob Faibussowitsch minvalf = PetscRealPart(fArr[cellneighiter]); 9043f108dbd7SJacob Faibussowitsch } 9044f108dbd7SJacob Faibussowitsch } 9045f108dbd7SJacob Faibussowitsch ierr = PetscFree(adj);CHKERRQ(ierr); 9046f108dbd7SJacob Faibussowitsch ierr = PetscFree2(cArr, fArr);CHKERRQ(ierr); 9047f108dbd7SJacob Faibussowitsch /* Defer to cell if they're equal */ 90486ed19f2fSJacob Faibussowitsch oqVals[cellIter] = PetscMin(minvalf, minvalc); 9049f108dbd7SJacob Faibussowitsch if (OrthQualLabel) { 90506ed19f2fSJacob Faibussowitsch if (PetscRealPart(oqVals[cellIter]) <= atol) {ierr = DMLabelSetValue(*OrthQualLabel, cell, DM_ADAPT_REFINE);CHKERRQ(ierr);} 9051f108dbd7SJacob Faibussowitsch } 9052f108dbd7SJacob Faibussowitsch } 90536ed19f2fSJacob Faibussowitsch ierr = VecSetValuesLocal(*OrthQual, cEnd-cStart, idx, oqVals, INSERT_VALUES);CHKERRQ(ierr); 9054f108dbd7SJacob Faibussowitsch ierr = VecAssemblyBegin(*OrthQual);CHKERRQ(ierr); 9055f108dbd7SJacob Faibussowitsch ierr = VecAssemblyEnd(*OrthQual);CHKERRQ(ierr); 9056f108dbd7SJacob Faibussowitsch ierr = VecRestoreArrayRead(cellgeom, &cellGeomArr);CHKERRQ(ierr); 9057f108dbd7SJacob Faibussowitsch ierr = VecRestoreArrayRead(facegeom, &faceGeomArr);CHKERRQ(ierr); 9058f108dbd7SJacob Faibussowitsch ierr = PetscOptionsGetViewer(comm, NULL, NULL, "-dm_plex_orthogonal_quality_label_view", &vwr, NULL, NULL);CHKERRQ(ierr); 9059f108dbd7SJacob Faibussowitsch if (OrthQualLabel) { 90606ed19f2fSJacob Faibussowitsch if (vwr) {ierr = DMLabelView(*OrthQualLabel, vwr);CHKERRQ(ierr);} 9061f108dbd7SJacob Faibussowitsch } 90626ed19f2fSJacob Faibussowitsch ierr = PetscFree5(idx, oqVals, ci, fi, Ai);CHKERRQ(ierr); 9063f108dbd7SJacob Faibussowitsch ierr = PetscViewerDestroy(&vwr);CHKERRQ(ierr); 9064f108dbd7SJacob Faibussowitsch ierr = VecViewFromOptions(*OrthQual, NULL, "-dm_plex_orthogonal_quality_vec_view");CHKERRQ(ierr); 9065f108dbd7SJacob Faibussowitsch PetscFunctionReturn(0); 9066f108dbd7SJacob Faibussowitsch } 9067f108dbd7SJacob Faibussowitsch 90681eb70e55SToby Isaac /* this is here insead of DMGetOutputDM because output DM still has constraints in the local indices that affect 90691eb70e55SToby Isaac * interpolator construction */ 90701eb70e55SToby Isaac static PetscErrorCode DMGetFullDM(DM dm, DM *odm) 90711eb70e55SToby Isaac { 90721eb70e55SToby Isaac PetscSection section, newSection, gsection; 90731eb70e55SToby Isaac PetscSF sf; 90741eb70e55SToby Isaac PetscBool hasConstraints, ghasConstraints; 90751eb70e55SToby Isaac PetscErrorCode ierr; 90761eb70e55SToby Isaac 90771eb70e55SToby Isaac PetscFunctionBegin; 90781eb70e55SToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 90791eb70e55SToby Isaac PetscValidPointer(odm,2); 90801eb70e55SToby Isaac ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr); 90811eb70e55SToby Isaac ierr = PetscSectionHasConstraints(section, &hasConstraints);CHKERRQ(ierr); 90821eb70e55SToby Isaac ierr = MPI_Allreduce(&hasConstraints, &ghasConstraints, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject) dm));CHKERRMPI(ierr); 90831eb70e55SToby Isaac if (!ghasConstraints) { 90841eb70e55SToby Isaac ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 90851eb70e55SToby Isaac *odm = dm; 90861eb70e55SToby Isaac PetscFunctionReturn(0); 90871eb70e55SToby Isaac } 90881eb70e55SToby Isaac ierr = DMClone(dm, odm);CHKERRQ(ierr); 90891eb70e55SToby Isaac ierr = DMCopyFields(dm, *odm);CHKERRQ(ierr); 90901eb70e55SToby Isaac ierr = DMGetLocalSection(*odm, &newSection);CHKERRQ(ierr); 90911eb70e55SToby Isaac ierr = DMGetPointSF(*odm, &sf);CHKERRQ(ierr); 90921eb70e55SToby Isaac ierr = PetscSectionCreateGlobalSection(newSection, sf, PETSC_TRUE, PETSC_FALSE, &gsection);CHKERRQ(ierr); 90931eb70e55SToby Isaac ierr = DMSetGlobalSection(*odm, gsection);CHKERRQ(ierr); 90941eb70e55SToby Isaac ierr = PetscSectionDestroy(&gsection);CHKERRQ(ierr); 90951eb70e55SToby Isaac PetscFunctionReturn(0); 90961eb70e55SToby Isaac } 90971eb70e55SToby Isaac 90981eb70e55SToby Isaac static PetscErrorCode DMCreateAffineInterpolationCorrection_Plex(DM dmc, DM dmf, Vec *shift) 90991eb70e55SToby Isaac { 91001eb70e55SToby Isaac DM dmco, dmfo; 91011eb70e55SToby Isaac Mat interpo; 91021eb70e55SToby Isaac Vec rscale; 91031eb70e55SToby Isaac Vec cglobalo, clocal; 91041eb70e55SToby Isaac Vec fglobal, fglobalo, flocal; 91051eb70e55SToby Isaac PetscBool regular; 91061eb70e55SToby Isaac PetscErrorCode ierr; 91071eb70e55SToby Isaac 91081eb70e55SToby Isaac PetscFunctionBegin; 91091eb70e55SToby Isaac ierr = DMGetFullDM(dmc, &dmco);CHKERRQ(ierr); 91101eb70e55SToby Isaac ierr = DMGetFullDM(dmf, &dmfo);CHKERRQ(ierr); 91111eb70e55SToby Isaac ierr = DMSetCoarseDM(dmfo, dmco);CHKERRQ(ierr); 91121eb70e55SToby Isaac ierr = DMPlexGetRegularRefinement(dmf, ®ular);CHKERRQ(ierr); 91131eb70e55SToby Isaac ierr = DMPlexSetRegularRefinement(dmfo, regular);CHKERRQ(ierr); 91141eb70e55SToby Isaac ierr = DMCreateInterpolation(dmco, dmfo, &interpo, &rscale);CHKERRQ(ierr); 91151eb70e55SToby Isaac ierr = DMCreateGlobalVector(dmco, &cglobalo);CHKERRQ(ierr); 91161eb70e55SToby Isaac ierr = DMCreateLocalVector(dmc, &clocal);CHKERRQ(ierr); 91171eb70e55SToby Isaac ierr = VecSet(cglobalo, 0.);CHKERRQ(ierr); 91181eb70e55SToby Isaac ierr = VecSet(clocal, 0.);CHKERRQ(ierr); 91191eb70e55SToby Isaac ierr = DMCreateGlobalVector(dmf, &fglobal);CHKERRQ(ierr); 91201eb70e55SToby Isaac ierr = DMCreateGlobalVector(dmfo, &fglobalo);CHKERRQ(ierr); 91211eb70e55SToby Isaac ierr = DMCreateLocalVector(dmf, &flocal);CHKERRQ(ierr); 91221eb70e55SToby Isaac ierr = VecSet(fglobal, 0.);CHKERRQ(ierr); 91231eb70e55SToby Isaac ierr = VecSet(fglobalo, 0.);CHKERRQ(ierr); 91241eb70e55SToby Isaac ierr = VecSet(flocal, 0.);CHKERRQ(ierr); 91251eb70e55SToby Isaac ierr = DMPlexInsertBoundaryValues(dmc, PETSC_TRUE, clocal, 0., NULL, NULL, NULL);CHKERRQ(ierr); 91261eb70e55SToby Isaac ierr = DMLocalToGlobalBegin(dmco, clocal, INSERT_VALUES, cglobalo);CHKERRQ(ierr); 91271eb70e55SToby Isaac ierr = DMLocalToGlobalEnd(dmco, clocal, INSERT_VALUES, cglobalo);CHKERRQ(ierr); 91281eb70e55SToby Isaac ierr = MatMult(interpo, cglobalo, fglobalo);CHKERRQ(ierr); 91291eb70e55SToby Isaac ierr = DMGlobalToLocalBegin(dmfo, fglobalo, INSERT_VALUES, flocal);CHKERRQ(ierr); 91301eb70e55SToby Isaac ierr = DMGlobalToLocalEnd(dmfo, fglobalo, INSERT_VALUES, flocal);CHKERRQ(ierr); 91311eb70e55SToby Isaac ierr = DMLocalToGlobalBegin(dmf, flocal, INSERT_VALUES, fglobal);CHKERRQ(ierr); 91321eb70e55SToby Isaac ierr = DMLocalToGlobalEnd(dmf, flocal, INSERT_VALUES, fglobal);CHKERRQ(ierr); 91331eb70e55SToby Isaac *shift = fglobal; 91341eb70e55SToby Isaac ierr = VecDestroy(&flocal);CHKERRQ(ierr); 91351eb70e55SToby Isaac ierr = VecDestroy(&fglobalo);CHKERRQ(ierr); 91361eb70e55SToby Isaac ierr = VecDestroy(&clocal);CHKERRQ(ierr); 91371eb70e55SToby Isaac ierr = VecDestroy(&cglobalo);CHKERRQ(ierr); 91381eb70e55SToby Isaac ierr = VecDestroy(&rscale);CHKERRQ(ierr); 91391eb70e55SToby Isaac ierr = MatDestroy(&interpo);CHKERRQ(ierr); 91401eb70e55SToby Isaac ierr = DMDestroy(&dmfo);CHKERRQ(ierr); 91411eb70e55SToby Isaac ierr = DMDestroy(&dmco);CHKERRQ(ierr); 91421eb70e55SToby Isaac PetscFunctionReturn(0); 91431eb70e55SToby Isaac } 91441eb70e55SToby Isaac 91451eb70e55SToby Isaac PETSC_INTERN PetscErrorCode DMInterpolateSolution_Plex(DM coarse, DM fine, Mat interp, Vec coarseSol, Vec fineSol) 91461eb70e55SToby Isaac { 91471eb70e55SToby Isaac PetscObject shifto; 91481eb70e55SToby Isaac Vec shift; 91491eb70e55SToby Isaac 91501eb70e55SToby Isaac PetscErrorCode ierr; 91511eb70e55SToby Isaac 91521eb70e55SToby Isaac PetscFunctionBegin; 91531eb70e55SToby Isaac if (!interp) { 91541eb70e55SToby Isaac Vec rscale; 91551eb70e55SToby Isaac 91561eb70e55SToby Isaac ierr = DMCreateInterpolation(coarse, fine, &interp, &rscale);CHKERRQ(ierr); 91571eb70e55SToby Isaac ierr = VecDestroy(&rscale);CHKERRQ(ierr); 91581eb70e55SToby Isaac } else { 91591eb70e55SToby Isaac ierr = PetscObjectReference((PetscObject)interp);CHKERRQ(ierr); 91601eb70e55SToby Isaac } 91611eb70e55SToby Isaac ierr = PetscObjectQuery((PetscObject)interp, "_DMInterpolateSolution_Plex_Vec", &shifto);CHKERRQ(ierr); 91621eb70e55SToby Isaac if (!shifto) { 91631eb70e55SToby Isaac ierr = DMCreateAffineInterpolationCorrection_Plex(coarse, fine, &shift);CHKERRQ(ierr); 91641eb70e55SToby Isaac ierr = PetscObjectCompose((PetscObject)interp, "_DMInterpolateSolution_Plex_Vec", (PetscObject) shift);CHKERRQ(ierr); 91651eb70e55SToby Isaac shifto = (PetscObject) shift; 91661eb70e55SToby Isaac ierr = VecDestroy(&shift);CHKERRQ(ierr); 91671eb70e55SToby Isaac } 91681eb70e55SToby Isaac shift = (Vec) shifto; 91691eb70e55SToby Isaac ierr = MatInterpolate(interp, coarseSol, fineSol);CHKERRQ(ierr); 91701eb70e55SToby Isaac ierr = VecAXPY(fineSol, 1.0, shift);CHKERRQ(ierr); 91711eb70e55SToby Isaac ierr = MatDestroy(&interp);CHKERRQ(ierr); 91721eb70e55SToby Isaac PetscFunctionReturn(0); 91731eb70e55SToby Isaac } 91741eb70e55SToby Isaac 9175bceba477SMatthew G. Knepley /* Pointwise interpolation 9176bceba477SMatthew G. Knepley Just code FEM for now 9177bceba477SMatthew G. Knepley u^f = I u^c 91784ca5e9f5SMatthew G. Knepley sum_k u^f_k phi^f_k = I sum_j u^c_j phi^c_j 91794ca5e9f5SMatthew G. Knepley u^f_i = sum_j psi^f_i I phi^c_j u^c_j 91804ca5e9f5SMatthew G. Knepley I_{ij} = psi^f_i phi^c_j 9181bceba477SMatthew G. Knepley */ 9182bceba477SMatthew G. Knepley PetscErrorCode DMCreateInterpolation_Plex(DM dmCoarse, DM dmFine, Mat *interpolation, Vec *scaling) 9183bceba477SMatthew G. Knepley { 9184bceba477SMatthew G. Knepley PetscSection gsc, gsf; 9185bceba477SMatthew G. Knepley PetscInt m, n; 9186a063dac3SMatthew G. Knepley void *ctx; 918768132eb9SMatthew G. Knepley DM cdm; 9188cf51de39SMatthew G. Knepley PetscBool regular, ismatis, isRefined = dmCoarse->data == dmFine->data ? PETSC_FALSE : PETSC_TRUE; 9189bceba477SMatthew G. Knepley PetscErrorCode ierr; 9190bceba477SMatthew G. Knepley 9191bceba477SMatthew G. Knepley PetscFunctionBegin; 9192e87a4003SBarry Smith ierr = DMGetGlobalSection(dmFine, &gsf);CHKERRQ(ierr); 9193bceba477SMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(gsf, &m);CHKERRQ(ierr); 9194e87a4003SBarry Smith ierr = DMGetGlobalSection(dmCoarse, &gsc);CHKERRQ(ierr); 9195bceba477SMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(gsc, &n);CHKERRQ(ierr); 919668132eb9SMatthew G. Knepley 9197fd194bc8SStefano Zampini ierr = PetscStrcmp(dmCoarse->mattype, MATIS, &ismatis);CHKERRQ(ierr); 9198bceba477SMatthew G. Knepley ierr = MatCreate(PetscObjectComm((PetscObject) dmCoarse), interpolation);CHKERRQ(ierr); 9199bceba477SMatthew G. Knepley ierr = MatSetSizes(*interpolation, m, n, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 9200fd194bc8SStefano Zampini ierr = MatSetType(*interpolation, ismatis ? MATAIJ : dmCoarse->mattype);CHKERRQ(ierr); 9201a063dac3SMatthew G. Knepley ierr = DMGetApplicationContext(dmFine, &ctx);CHKERRQ(ierr); 920268132eb9SMatthew G. Knepley 9203a8fb8f29SToby Isaac ierr = DMGetCoarseDM(dmFine, &cdm);CHKERRQ(ierr); 920468132eb9SMatthew G. Knepley ierr = DMPlexGetRegularRefinement(dmFine, ®ular);CHKERRQ(ierr); 9205cf51de39SMatthew G. Knepley if (!isRefined || (regular && cdm == dmCoarse)) {ierr = DMPlexComputeInterpolatorNested(dmCoarse, dmFine, isRefined, *interpolation, ctx);CHKERRQ(ierr);} 920668132eb9SMatthew G. Knepley else {ierr = DMPlexComputeInterpolatorGeneral(dmCoarse, dmFine, *interpolation, ctx);CHKERRQ(ierr);} 920768132eb9SMatthew G. Knepley ierr = MatViewFromOptions(*interpolation, NULL, "-interp_mat_view");CHKERRQ(ierr); 92084db47ee9SStefano Zampini if (scaling) { 92095d1c2e58SMatthew G. Knepley /* Use naive scaling */ 92105d1c2e58SMatthew G. Knepley ierr = DMCreateInterpolationScale(dmCoarse, dmFine, *interpolation, scaling);CHKERRQ(ierr); 92114db47ee9SStefano Zampini } 9212a063dac3SMatthew G. Knepley PetscFunctionReturn(0); 9213a063dac3SMatthew G. Knepley } 9214bceba477SMatthew G. Knepley 92156dbf9973SLawrence Mitchell PetscErrorCode DMCreateInjection_Plex(DM dmCoarse, DM dmFine, Mat *mat) 9216a063dac3SMatthew G. Knepley { 921790748bafSMatthew G. Knepley PetscErrorCode ierr; 92186dbf9973SLawrence Mitchell VecScatter ctx; 921990748bafSMatthew G. Knepley 9220a063dac3SMatthew G. Knepley PetscFunctionBegin; 92216dbf9973SLawrence Mitchell ierr = DMPlexComputeInjectorFEM(dmCoarse, dmFine, &ctx, NULL);CHKERRQ(ierr); 92226dbf9973SLawrence Mitchell ierr = MatCreateScatter(PetscObjectComm((PetscObject)ctx), ctx, mat);CHKERRQ(ierr); 92236dbf9973SLawrence Mitchell ierr = VecScatterDestroy(&ctx);CHKERRQ(ierr); 9224bceba477SMatthew G. Knepley PetscFunctionReturn(0); 9225bceba477SMatthew G. Knepley } 9226bceba477SMatthew G. Knepley 92273e9753d6SMatthew G. Knepley static void g0_identity_private(PetscInt dim, PetscInt Nf, PetscInt NfAux, 92283e9753d6SMatthew G. Knepley const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 92293e9753d6SMatthew G. Knepley const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 92303e9753d6SMatthew G. Knepley PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]) 92313e9753d6SMatthew G. Knepley { 92323e9753d6SMatthew G. Knepley g0[0] = 1.0; 92333e9753d6SMatthew G. Knepley } 92343e9753d6SMatthew G. Knepley 9235bd041c0cSMatthew G. Knepley PetscErrorCode DMCreateMassMatrix_Plex(DM dmCoarse, DM dmFine, Mat *mass) 9236bd041c0cSMatthew G. Knepley { 9237bd041c0cSMatthew G. Knepley PetscSection gsc, gsf; 9238bd041c0cSMatthew G. Knepley PetscInt m, n; 9239bd041c0cSMatthew G. Knepley void *ctx; 9240bd041c0cSMatthew G. Knepley DM cdm; 9241bd041c0cSMatthew G. Knepley PetscBool regular; 9242bd041c0cSMatthew G. Knepley PetscErrorCode ierr; 9243bd041c0cSMatthew G. Knepley 9244bd041c0cSMatthew G. Knepley PetscFunctionBegin; 92453e9753d6SMatthew G. Knepley if (dmFine == dmCoarse) { 92463e9753d6SMatthew G. Knepley DM dmc; 92473e9753d6SMatthew G. Knepley PetscDS ds; 92483e9753d6SMatthew G. Knepley Vec u; 92493e9753d6SMatthew G. Knepley IS cellIS; 925006ad1575SMatthew G. Knepley PetscFormKey key; 92513e9753d6SMatthew G. Knepley PetscInt depth; 92523e9753d6SMatthew G. Knepley 92533e9753d6SMatthew G. Knepley ierr = DMClone(dmFine, &dmc);CHKERRQ(ierr); 92543e9753d6SMatthew G. Knepley ierr = DMCopyDisc(dmFine, dmc);CHKERRQ(ierr); 92553e9753d6SMatthew G. Knepley ierr = DMGetDS(dmc, &ds);CHKERRQ(ierr); 92563e9753d6SMatthew G. Knepley ierr = PetscDSSetJacobian(ds, 0, 0, g0_identity_private, NULL, NULL, NULL);CHKERRQ(ierr); 92573e9753d6SMatthew G. Knepley ierr = DMCreateMatrix(dmc, mass);CHKERRQ(ierr); 92583e9753d6SMatthew G. Knepley ierr = DMGetGlobalVector(dmc, &u);CHKERRQ(ierr); 92593e9753d6SMatthew G. Knepley ierr = DMPlexGetDepth(dmc, &depth);CHKERRQ(ierr); 92603e9753d6SMatthew G. Knepley ierr = DMGetStratumIS(dmc, "depth", depth, &cellIS);CHKERRQ(ierr); 92613e9753d6SMatthew G. Knepley ierr = MatZeroEntries(*mass);CHKERRQ(ierr); 92626528b96dSMatthew G. Knepley key.label = NULL; 92636528b96dSMatthew G. Knepley key.value = 0; 92646528b96dSMatthew G. Knepley key.field = 0; 926506ad1575SMatthew G. Knepley key.part = 0; 92666528b96dSMatthew G. Knepley ierr = DMPlexComputeJacobian_Internal(dmc, key, cellIS, 0.0, 0.0, u, NULL, *mass, *mass, NULL);CHKERRQ(ierr); 92673e9753d6SMatthew G. Knepley ierr = ISDestroy(&cellIS);CHKERRQ(ierr); 92683e9753d6SMatthew G. Knepley ierr = DMRestoreGlobalVector(dmc, &u);CHKERRQ(ierr); 92693e9753d6SMatthew G. Knepley ierr = DMDestroy(&dmc);CHKERRQ(ierr); 92703e9753d6SMatthew G. Knepley } else { 9271e87a4003SBarry Smith ierr = DMGetGlobalSection(dmFine, &gsf);CHKERRQ(ierr); 9272bd041c0cSMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(gsf, &m);CHKERRQ(ierr); 9273e87a4003SBarry Smith ierr = DMGetGlobalSection(dmCoarse, &gsc);CHKERRQ(ierr); 9274bd041c0cSMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(gsc, &n);CHKERRQ(ierr); 9275bd041c0cSMatthew G. Knepley 9276bd041c0cSMatthew G. Knepley ierr = MatCreate(PetscObjectComm((PetscObject) dmCoarse), mass);CHKERRQ(ierr); 9277bd041c0cSMatthew G. Knepley ierr = MatSetSizes(*mass, m, n, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 9278bd041c0cSMatthew G. Knepley ierr = MatSetType(*mass, dmCoarse->mattype);CHKERRQ(ierr); 9279bd041c0cSMatthew G. Knepley ierr = DMGetApplicationContext(dmFine, &ctx);CHKERRQ(ierr); 9280bd041c0cSMatthew G. Knepley 9281bd041c0cSMatthew G. Knepley ierr = DMGetCoarseDM(dmFine, &cdm);CHKERRQ(ierr); 9282bd041c0cSMatthew G. Knepley ierr = DMPlexGetRegularRefinement(dmFine, ®ular);CHKERRQ(ierr); 9283bd041c0cSMatthew G. Knepley if (regular && cdm == dmCoarse) {ierr = DMPlexComputeMassMatrixNested(dmCoarse, dmFine, *mass, ctx);CHKERRQ(ierr);} 9284bd041c0cSMatthew G. Knepley else {ierr = DMPlexComputeMassMatrixGeneral(dmCoarse, dmFine, *mass, ctx);CHKERRQ(ierr);} 92853e9753d6SMatthew G. Knepley } 9286bd041c0cSMatthew G. Knepley ierr = MatViewFromOptions(*mass, NULL, "-mass_mat_view");CHKERRQ(ierr); 9287bd041c0cSMatthew G. Knepley PetscFunctionReturn(0); 9288bd041c0cSMatthew G. Knepley } 9289bd041c0cSMatthew G. Knepley 92900aef6b92SMatthew G. Knepley /*@ 92910aef6b92SMatthew G. Knepley DMPlexGetRegularRefinement - Get the flag indicating that this mesh was obtained by regular refinement from its coarse mesh 92920aef6b92SMatthew G. Knepley 92930aef6b92SMatthew G. Knepley Input Parameter: 92940aef6b92SMatthew G. Knepley . dm - The DMPlex object 92950aef6b92SMatthew G. Knepley 92960aef6b92SMatthew G. Knepley Output Parameter: 92970aef6b92SMatthew G. Knepley . regular - The flag 92980aef6b92SMatthew G. Knepley 92990aef6b92SMatthew G. Knepley Level: intermediate 93000aef6b92SMatthew G. Knepley 93010aef6b92SMatthew G. Knepley .seealso: DMPlexSetRegularRefinement() 93020aef6b92SMatthew G. Knepley @*/ 93030aef6b92SMatthew G. Knepley PetscErrorCode DMPlexGetRegularRefinement(DM dm, PetscBool *regular) 93040aef6b92SMatthew G. Knepley { 93050aef6b92SMatthew G. Knepley PetscFunctionBegin; 93060aef6b92SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 93070aef6b92SMatthew G. Knepley PetscValidPointer(regular, 2); 93080aef6b92SMatthew G. Knepley *regular = ((DM_Plex *) dm->data)->regularRefinement; 93090aef6b92SMatthew G. Knepley PetscFunctionReturn(0); 93100aef6b92SMatthew G. Knepley } 93110aef6b92SMatthew G. Knepley 93120aef6b92SMatthew G. Knepley /*@ 93130aef6b92SMatthew G. Knepley DMPlexSetRegularRefinement - Set the flag indicating that this mesh was obtained by regular refinement from its coarse mesh 93140aef6b92SMatthew G. Knepley 93150aef6b92SMatthew G. Knepley Input Parameters: 93160aef6b92SMatthew G. Knepley + dm - The DMPlex object 93170aef6b92SMatthew G. Knepley - regular - The flag 93180aef6b92SMatthew G. Knepley 93190aef6b92SMatthew G. Knepley Level: intermediate 93200aef6b92SMatthew G. Knepley 93210aef6b92SMatthew G. Knepley .seealso: DMPlexGetRegularRefinement() 93220aef6b92SMatthew G. Knepley @*/ 93230aef6b92SMatthew G. Knepley PetscErrorCode DMPlexSetRegularRefinement(DM dm, PetscBool regular) 93240aef6b92SMatthew G. Knepley { 93250aef6b92SMatthew G. Knepley PetscFunctionBegin; 93260aef6b92SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 93270aef6b92SMatthew G. Knepley ((DM_Plex *) dm->data)->regularRefinement = regular; 93280aef6b92SMatthew G. Knepley PetscFunctionReturn(0); 93290aef6b92SMatthew G. Knepley } 93300aef6b92SMatthew G. Knepley 9331f7c74593SToby Isaac /* anchors */ 9332a68b90caSToby Isaac /*@ 9333f7c74593SToby Isaac DMPlexGetAnchors - Get the layout of the anchor (point-to-point) constraints. Typically, the user will not have to 9334f7c74593SToby Isaac call DMPlexGetAnchors() directly: if there are anchors, then DMPlexGetAnchors() is called during DMGetConstraints(). 9335a68b90caSToby Isaac 9336e228b242SToby Isaac not collective 9337a68b90caSToby Isaac 9338f899ff85SJose E. Roman Input Parameter: 9339a68b90caSToby Isaac . dm - The DMPlex object 9340a68b90caSToby Isaac 9341a68b90caSToby Isaac Output Parameters: 9342a68b90caSToby Isaac + anchorSection - If not NULL, set to the section describing which points anchor the constrained points. 9343a68b90caSToby Isaac - anchorIS - If not NULL, set to the list of anchors indexed by anchorSection 9344a68b90caSToby Isaac 9345a68b90caSToby Isaac Level: intermediate 9346a68b90caSToby Isaac 9347f7c74593SToby Isaac .seealso: DMPlexSetAnchors(), DMGetConstraints(), DMSetConstraints() 9348a68b90caSToby Isaac @*/ 9349a17985deSToby Isaac PetscErrorCode DMPlexGetAnchors(DM dm, PetscSection *anchorSection, IS *anchorIS) 9350a68b90caSToby Isaac { 9351a68b90caSToby Isaac DM_Plex *plex = (DM_Plex *)dm->data; 935241e6d900SToby Isaac PetscErrorCode ierr; 9353a68b90caSToby Isaac 9354a68b90caSToby Isaac PetscFunctionBegin; 9355a68b90caSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 935641e6d900SToby Isaac if (!plex->anchorSection && !plex->anchorIS && plex->createanchors) {ierr = (*plex->createanchors)(dm);CHKERRQ(ierr);} 9357a68b90caSToby Isaac if (anchorSection) *anchorSection = plex->anchorSection; 9358a68b90caSToby Isaac if (anchorIS) *anchorIS = plex->anchorIS; 9359a68b90caSToby Isaac PetscFunctionReturn(0); 9360a68b90caSToby Isaac } 9361a68b90caSToby Isaac 9362a68b90caSToby Isaac /*@ 9363f7c74593SToby Isaac DMPlexSetAnchors - Set the layout of the local anchor (point-to-point) constraints. Unlike boundary conditions, 9364f7c74593SToby Isaac when a point's degrees of freedom in a section are constrained to an outside value, the anchor constraints set a 9365a68b90caSToby Isaac point's degrees of freedom to be a linear combination of other points' degrees of freedom. 9366a68b90caSToby Isaac 9367a17985deSToby Isaac After specifying the layout of constraints with DMPlexSetAnchors(), one specifies the constraints by calling 9368f7c74593SToby Isaac DMGetConstraints() and filling in the entries in the constraint matrix. 9369a68b90caSToby Isaac 9370e228b242SToby Isaac collective on dm 9371a68b90caSToby Isaac 9372a68b90caSToby Isaac Input Parameters: 9373a68b90caSToby Isaac + dm - The DMPlex object 9374e228b242SToby 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). 9375e228b242SToby Isaac - anchorIS - The list of all anchor points. Must have a local communicator (PETSC_COMM_SELF or derivative). 9376a68b90caSToby Isaac 9377a68b90caSToby Isaac The reference counts of anchorSection and anchorIS are incremented. 9378a68b90caSToby Isaac 9379a68b90caSToby Isaac Level: intermediate 9380a68b90caSToby Isaac 9381f7c74593SToby Isaac .seealso: DMPlexGetAnchors(), DMGetConstraints(), DMSetConstraints() 9382a68b90caSToby Isaac @*/ 9383a17985deSToby Isaac PetscErrorCode DMPlexSetAnchors(DM dm, PetscSection anchorSection, IS anchorIS) 9384a68b90caSToby Isaac { 9385a68b90caSToby Isaac DM_Plex *plex = (DM_Plex *)dm->data; 9386e228b242SToby Isaac PetscMPIInt result; 9387a68b90caSToby Isaac PetscErrorCode ierr; 9388a68b90caSToby Isaac 9389a68b90caSToby Isaac PetscFunctionBegin; 9390a68b90caSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9391e228b242SToby Isaac if (anchorSection) { 9392e228b242SToby Isaac PetscValidHeaderSpecific(anchorSection,PETSC_SECTION_CLASSID,2); 9393ffc4695bSBarry Smith ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)anchorSection),&result);CHKERRMPI(ierr); 9394f6a3d38cSToby Isaac if (result != MPI_CONGRUENT && result != MPI_IDENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"anchor section must have local communicator"); 9395e228b242SToby Isaac } 9396e228b242SToby Isaac if (anchorIS) { 9397e228b242SToby Isaac PetscValidHeaderSpecific(anchorIS,IS_CLASSID,3); 9398ffc4695bSBarry Smith ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)anchorIS),&result);CHKERRMPI(ierr); 9399f6a3d38cSToby Isaac if (result != MPI_CONGRUENT && result != MPI_IDENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"anchor IS must have local communicator"); 9400e228b242SToby Isaac } 9401a68b90caSToby Isaac 9402a68b90caSToby Isaac ierr = PetscObjectReference((PetscObject)anchorSection);CHKERRQ(ierr); 9403a68b90caSToby Isaac ierr = PetscSectionDestroy(&plex->anchorSection);CHKERRQ(ierr); 9404a68b90caSToby Isaac plex->anchorSection = anchorSection; 9405a68b90caSToby Isaac 9406a68b90caSToby Isaac ierr = PetscObjectReference((PetscObject)anchorIS);CHKERRQ(ierr); 9407a68b90caSToby Isaac ierr = ISDestroy(&plex->anchorIS);CHKERRQ(ierr); 9408a68b90caSToby Isaac plex->anchorIS = anchorIS; 9409a68b90caSToby Isaac 9410cf9c20a2SJed Brown if (PetscUnlikelyDebug(anchorIS && anchorSection)) { 9411a68b90caSToby Isaac PetscInt size, a, pStart, pEnd; 9412a68b90caSToby Isaac const PetscInt *anchors; 9413a68b90caSToby Isaac 9414a68b90caSToby Isaac ierr = PetscSectionGetChart(anchorSection,&pStart,&pEnd);CHKERRQ(ierr); 9415a68b90caSToby Isaac ierr = ISGetLocalSize(anchorIS,&size);CHKERRQ(ierr); 9416a68b90caSToby Isaac ierr = ISGetIndices(anchorIS,&anchors);CHKERRQ(ierr); 9417a68b90caSToby Isaac for (a = 0; a < size; a++) { 9418a68b90caSToby Isaac PetscInt p; 9419a68b90caSToby Isaac 9420a68b90caSToby Isaac p = anchors[a]; 9421a68b90caSToby Isaac if (p >= pStart && p < pEnd) { 9422a68b90caSToby Isaac PetscInt dof; 9423a68b90caSToby Isaac 9424a68b90caSToby Isaac ierr = PetscSectionGetDof(anchorSection,p,&dof);CHKERRQ(ierr); 9425a68b90caSToby Isaac if (dof) { 9426a68b90caSToby Isaac PetscErrorCode ierr2; 9427a68b90caSToby Isaac 9428a68b90caSToby Isaac ierr2 = ISRestoreIndices(anchorIS,&anchors);CHKERRQ(ierr2); 94298ccfff9cSToby Isaac SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Point %D cannot be constrained and an anchor",p); 9430a68b90caSToby Isaac } 9431a68b90caSToby Isaac } 9432a68b90caSToby Isaac } 9433a68b90caSToby Isaac ierr = ISRestoreIndices(anchorIS,&anchors);CHKERRQ(ierr); 9434a68b90caSToby Isaac } 9435f7c74593SToby Isaac /* reset the generic constraints */ 9436f7c74593SToby Isaac ierr = DMSetDefaultConstraints(dm,NULL,NULL);CHKERRQ(ierr); 9437a68b90caSToby Isaac PetscFunctionReturn(0); 9438a68b90caSToby Isaac } 9439a68b90caSToby Isaac 9440f7c74593SToby Isaac static PetscErrorCode DMPlexCreateConstraintSection_Anchors(DM dm, PetscSection section, PetscSection *cSec) 9441a68b90caSToby Isaac { 9442f7c74593SToby Isaac PetscSection anchorSection; 94436995de1eSToby Isaac PetscInt pStart, pEnd, sStart, sEnd, p, dof, numFields, f; 9444a68b90caSToby Isaac PetscErrorCode ierr; 9445a68b90caSToby Isaac 9446a68b90caSToby Isaac PetscFunctionBegin; 9447a68b90caSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9448a17985deSToby Isaac ierr = DMPlexGetAnchors(dm,&anchorSection,NULL);CHKERRQ(ierr); 9449e228b242SToby Isaac ierr = PetscSectionCreate(PETSC_COMM_SELF,cSec);CHKERRQ(ierr); 9450a68b90caSToby Isaac ierr = PetscSectionGetNumFields(section,&numFields);CHKERRQ(ierr); 94516995de1eSToby Isaac if (numFields) { 9452719ab38cSToby Isaac PetscInt f; 9453a68b90caSToby Isaac ierr = PetscSectionSetNumFields(*cSec,numFields);CHKERRQ(ierr); 9454719ab38cSToby Isaac 9455719ab38cSToby Isaac for (f = 0; f < numFields; f++) { 9456719ab38cSToby Isaac PetscInt numComp; 9457719ab38cSToby Isaac 9458719ab38cSToby Isaac ierr = PetscSectionGetFieldComponents(section,f,&numComp);CHKERRQ(ierr); 9459719ab38cSToby Isaac ierr = PetscSectionSetFieldComponents(*cSec,f,numComp);CHKERRQ(ierr); 9460719ab38cSToby Isaac } 94616995de1eSToby Isaac } 9462a68b90caSToby Isaac ierr = PetscSectionGetChart(anchorSection,&pStart,&pEnd);CHKERRQ(ierr); 94636995de1eSToby Isaac ierr = PetscSectionGetChart(section,&sStart,&sEnd);CHKERRQ(ierr); 94646995de1eSToby Isaac pStart = PetscMax(pStart,sStart); 94656995de1eSToby Isaac pEnd = PetscMin(pEnd,sEnd); 94666995de1eSToby Isaac pEnd = PetscMax(pStart,pEnd); 9467a68b90caSToby Isaac ierr = PetscSectionSetChart(*cSec,pStart,pEnd);CHKERRQ(ierr); 9468a68b90caSToby Isaac for (p = pStart; p < pEnd; p++) { 9469a68b90caSToby Isaac ierr = PetscSectionGetDof(anchorSection,p,&dof);CHKERRQ(ierr); 9470a68b90caSToby Isaac if (dof) { 9471a68b90caSToby Isaac ierr = PetscSectionGetDof(section,p,&dof);CHKERRQ(ierr); 9472a68b90caSToby Isaac ierr = PetscSectionSetDof(*cSec,p,dof);CHKERRQ(ierr); 9473a68b90caSToby Isaac for (f = 0; f < numFields; f++) { 9474a68b90caSToby Isaac ierr = PetscSectionGetFieldDof(section,p,f,&dof);CHKERRQ(ierr); 9475a68b90caSToby Isaac ierr = PetscSectionSetFieldDof(*cSec,p,f,dof);CHKERRQ(ierr); 9476a68b90caSToby Isaac } 9477a68b90caSToby Isaac } 9478a68b90caSToby Isaac } 9479a68b90caSToby Isaac ierr = PetscSectionSetUp(*cSec);CHKERRQ(ierr); 9480ae65431dSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) *cSec, "Constraint Section");CHKERRQ(ierr); 9481a68b90caSToby Isaac PetscFunctionReturn(0); 9482a68b90caSToby Isaac } 9483a68b90caSToby Isaac 9484f7c74593SToby Isaac static PetscErrorCode DMPlexCreateConstraintMatrix_Anchors(DM dm, PetscSection section, PetscSection cSec, Mat *cMat) 9485a68b90caSToby Isaac { 9486f7c74593SToby Isaac PetscSection aSec; 9487ae65431dSMatthew G. Knepley PetscInt pStart, pEnd, p, sStart, sEnd, dof, aDof, aOff, off, nnz, annz, m, n, q, a, offset, *i, *j; 94880ac89760SToby Isaac const PetscInt *anchors; 94890ac89760SToby Isaac PetscInt numFields, f; 949066ad2231SToby Isaac IS aIS; 94910ac89760SToby Isaac PetscErrorCode ierr; 9492e19f7ee6SMark Adams MatType mtype; 9493e19f7ee6SMark Adams PetscBool iscuda,iskokkos; 94940ac89760SToby Isaac 94950ac89760SToby Isaac PetscFunctionBegin; 94960ac89760SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 94970ac89760SToby Isaac ierr = PetscSectionGetStorageSize(cSec, &m);CHKERRQ(ierr); 94980ac89760SToby Isaac ierr = PetscSectionGetStorageSize(section, &n);CHKERRQ(ierr); 94990ac89760SToby Isaac ierr = MatCreate(PETSC_COMM_SELF,cMat);CHKERRQ(ierr); 95000ac89760SToby Isaac ierr = MatSetSizes(*cMat,m,n,m,n);CHKERRQ(ierr); 9501e19f7ee6SMark Adams ierr = PetscStrcmp(dm->mattype,MATSEQAIJCUSPARSE,&iscuda);CHKERRQ(ierr); 9502e19f7ee6SMark Adams if (!iscuda) { ierr = PetscStrcmp(dm->mattype,MATMPIAIJCUSPARSE,&iscuda);CHKERRQ(ierr); } 9503e19f7ee6SMark Adams ierr = PetscStrcmp(dm->mattype,MATSEQAIJKOKKOS,&iskokkos);CHKERRQ(ierr); 9504e19f7ee6SMark Adams if (!iskokkos) { ierr = PetscStrcmp(dm->mattype,MATMPIAIJKOKKOS,&iskokkos);CHKERRQ(ierr); } 9505e19f7ee6SMark Adams if (iscuda) mtype = MATSEQAIJCUSPARSE; 9506e19f7ee6SMark Adams else if (iskokkos) mtype = MATSEQAIJKOKKOS; 9507e19f7ee6SMark Adams else mtype = MATSEQAIJ; 9508e19f7ee6SMark Adams ierr = MatSetType(*cMat,mtype);CHKERRQ(ierr); 9509a17985deSToby Isaac ierr = DMPlexGetAnchors(dm,&aSec,&aIS);CHKERRQ(ierr); 951066ad2231SToby Isaac ierr = ISGetIndices(aIS,&anchors);CHKERRQ(ierr); 95116995de1eSToby Isaac /* cSec will be a subset of aSec and section */ 95126995de1eSToby Isaac ierr = PetscSectionGetChart(cSec,&pStart,&pEnd);CHKERRQ(ierr); 9513ae65431dSMatthew G. Knepley ierr = PetscSectionGetChart(section,&sStart,&sEnd);CHKERRQ(ierr); 95140ac89760SToby Isaac ierr = PetscMalloc1(m+1,&i);CHKERRQ(ierr); 95150ac89760SToby Isaac i[0] = 0; 95160ac89760SToby Isaac ierr = PetscSectionGetNumFields(section,&numFields);CHKERRQ(ierr); 95170ac89760SToby Isaac for (p = pStart; p < pEnd; p++) { 9518f19733c5SToby Isaac PetscInt rDof, rOff, r; 9519f19733c5SToby Isaac 9520f19733c5SToby Isaac ierr = PetscSectionGetDof(aSec,p,&rDof);CHKERRQ(ierr); 9521f19733c5SToby Isaac if (!rDof) continue; 9522f19733c5SToby Isaac ierr = PetscSectionGetOffset(aSec,p,&rOff);CHKERRQ(ierr); 95230ac89760SToby Isaac if (numFields) { 95240ac89760SToby Isaac for (f = 0; f < numFields; f++) { 95250ac89760SToby Isaac annz = 0; 9526f19733c5SToby Isaac for (r = 0; r < rDof; r++) { 9527f19733c5SToby Isaac a = anchors[rOff + r]; 9528ae65431dSMatthew G. Knepley if (a < sStart || a >= sEnd) continue; 95290ac89760SToby Isaac ierr = PetscSectionGetFieldDof(section,a,f,&aDof);CHKERRQ(ierr); 95300ac89760SToby Isaac annz += aDof; 95310ac89760SToby Isaac } 95320ac89760SToby Isaac ierr = PetscSectionGetFieldDof(cSec,p,f,&dof);CHKERRQ(ierr); 95330ac89760SToby Isaac ierr = PetscSectionGetFieldOffset(cSec,p,f,&off);CHKERRQ(ierr); 95340ac89760SToby Isaac for (q = 0; q < dof; q++) { 95350ac89760SToby Isaac i[off + q + 1] = i[off + q] + annz; 95360ac89760SToby Isaac } 95370ac89760SToby Isaac } 95382f7452b8SBarry Smith } else { 95390ac89760SToby Isaac annz = 0; 9540326b8f31SMatthew G. Knepley ierr = PetscSectionGetDof(cSec,p,&dof);CHKERRQ(ierr); 95410ac89760SToby Isaac for (q = 0; q < dof; q++) { 9542ae65431dSMatthew G. Knepley a = anchors[rOff + q]; 9543ae65431dSMatthew G. Knepley if (a < sStart || a >= sEnd) continue; 95440ac89760SToby Isaac ierr = PetscSectionGetDof(section,a,&aDof);CHKERRQ(ierr); 95450ac89760SToby Isaac annz += aDof; 95460ac89760SToby Isaac } 95470ac89760SToby Isaac ierr = PetscSectionGetDof(cSec,p,&dof);CHKERRQ(ierr); 95480ac89760SToby Isaac ierr = PetscSectionGetOffset(cSec,p,&off);CHKERRQ(ierr); 95490ac89760SToby Isaac for (q = 0; q < dof; q++) { 95500ac89760SToby Isaac i[off + q + 1] = i[off + q] + annz; 95510ac89760SToby Isaac } 95520ac89760SToby Isaac } 95530ac89760SToby Isaac } 95540ac89760SToby Isaac nnz = i[m]; 95550ac89760SToby Isaac ierr = PetscMalloc1(nnz,&j);CHKERRQ(ierr); 95560ac89760SToby Isaac offset = 0; 95570ac89760SToby Isaac for (p = pStart; p < pEnd; p++) { 95580ac89760SToby Isaac if (numFields) { 95590ac89760SToby Isaac for (f = 0; f < numFields; f++) { 95600ac89760SToby Isaac ierr = PetscSectionGetFieldDof(cSec,p,f,&dof);CHKERRQ(ierr); 95610ac89760SToby Isaac for (q = 0; q < dof; q++) { 95620ac89760SToby Isaac PetscInt rDof, rOff, r; 95630ac89760SToby Isaac ierr = PetscSectionGetDof(aSec,p,&rDof);CHKERRQ(ierr); 95640ac89760SToby Isaac ierr = PetscSectionGetOffset(aSec,p,&rOff);CHKERRQ(ierr); 95650ac89760SToby Isaac for (r = 0; r < rDof; r++) { 95660ac89760SToby Isaac PetscInt s; 95670ac89760SToby Isaac 95680ac89760SToby Isaac a = anchors[rOff + r]; 9569ae65431dSMatthew G. Knepley if (a < sStart || a >= sEnd) continue; 95700ac89760SToby Isaac ierr = PetscSectionGetFieldDof(section,a,f,&aDof);CHKERRQ(ierr); 95710ac89760SToby Isaac ierr = PetscSectionGetFieldOffset(section,a,f,&aOff);CHKERRQ(ierr); 95720ac89760SToby Isaac for (s = 0; s < aDof; s++) { 95730ac89760SToby Isaac j[offset++] = aOff + s; 95740ac89760SToby Isaac } 95750ac89760SToby Isaac } 95760ac89760SToby Isaac } 95770ac89760SToby Isaac } 95782f7452b8SBarry Smith } else { 95790ac89760SToby Isaac ierr = PetscSectionGetDof(cSec,p,&dof);CHKERRQ(ierr); 95800ac89760SToby Isaac for (q = 0; q < dof; q++) { 95810ac89760SToby Isaac PetscInt rDof, rOff, r; 95820ac89760SToby Isaac ierr = PetscSectionGetDof(aSec,p,&rDof);CHKERRQ(ierr); 95830ac89760SToby Isaac ierr = PetscSectionGetOffset(aSec,p,&rOff);CHKERRQ(ierr); 95840ac89760SToby Isaac for (r = 0; r < rDof; r++) { 95850ac89760SToby Isaac PetscInt s; 95860ac89760SToby Isaac 95870ac89760SToby Isaac a = anchors[rOff + r]; 9588ae65431dSMatthew G. Knepley if (a < sStart || a >= sEnd) continue; 95890ac89760SToby Isaac ierr = PetscSectionGetDof(section,a,&aDof);CHKERRQ(ierr); 95900ac89760SToby Isaac ierr = PetscSectionGetOffset(section,a,&aOff);CHKERRQ(ierr); 95910ac89760SToby Isaac for (s = 0; s < aDof; s++) { 95920ac89760SToby Isaac j[offset++] = aOff + s; 95930ac89760SToby Isaac } 95940ac89760SToby Isaac } 95950ac89760SToby Isaac } 95960ac89760SToby Isaac } 95970ac89760SToby Isaac } 95980ac89760SToby Isaac ierr = MatSeqAIJSetPreallocationCSR(*cMat,i,j,NULL);CHKERRQ(ierr); 959925570a81SToby Isaac ierr = PetscFree(i);CHKERRQ(ierr); 960025570a81SToby Isaac ierr = PetscFree(j);CHKERRQ(ierr); 960166ad2231SToby Isaac ierr = ISRestoreIndices(aIS,&anchors);CHKERRQ(ierr); 96020ac89760SToby Isaac PetscFunctionReturn(0); 96030ac89760SToby Isaac } 96040ac89760SToby Isaac 960566ad2231SToby Isaac PetscErrorCode DMCreateDefaultConstraints_Plex(DM dm) 960666ad2231SToby Isaac { 9607f7c74593SToby Isaac DM_Plex *plex = (DM_Plex *)dm->data; 9608f7c74593SToby Isaac PetscSection anchorSection, section, cSec; 960966ad2231SToby Isaac Mat cMat; 961066ad2231SToby Isaac PetscErrorCode ierr; 961166ad2231SToby Isaac 961266ad2231SToby Isaac PetscFunctionBegin; 961366ad2231SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9614a17985deSToby Isaac ierr = DMPlexGetAnchors(dm,&anchorSection,NULL);CHKERRQ(ierr); 961566ad2231SToby Isaac if (anchorSection) { 961644a7f3ddSMatthew G. Knepley PetscInt Nf; 9617e228b242SToby Isaac 961892fd8e1eSJed Brown ierr = DMGetLocalSection(dm,§ion);CHKERRQ(ierr); 9619f7c74593SToby Isaac ierr = DMPlexCreateConstraintSection_Anchors(dm,section,&cSec);CHKERRQ(ierr); 9620f7c74593SToby Isaac ierr = DMPlexCreateConstraintMatrix_Anchors(dm,section,cSec,&cMat);CHKERRQ(ierr); 962144a7f3ddSMatthew G. Knepley ierr = DMGetNumFields(dm,&Nf);CHKERRQ(ierr); 962244a7f3ddSMatthew G. Knepley if (Nf && plex->computeanchormatrix) {ierr = (*plex->computeanchormatrix)(dm,section,cSec,cMat);CHKERRQ(ierr);} 962366ad2231SToby Isaac ierr = DMSetDefaultConstraints(dm,cSec,cMat);CHKERRQ(ierr); 962466ad2231SToby Isaac ierr = PetscSectionDestroy(&cSec);CHKERRQ(ierr); 962566ad2231SToby Isaac ierr = MatDestroy(&cMat);CHKERRQ(ierr); 962666ad2231SToby Isaac } 962766ad2231SToby Isaac PetscFunctionReturn(0); 962866ad2231SToby Isaac } 9629a93c429eSMatthew G. Knepley 9630a93c429eSMatthew G. Knepley PetscErrorCode DMCreateSubDomainDM_Plex(DM dm, DMLabel label, PetscInt value, IS *is, DM *subdm) 9631a93c429eSMatthew G. Knepley { 9632a93c429eSMatthew G. Knepley IS subis; 9633a93c429eSMatthew G. Knepley PetscSection section, subsection; 9634a93c429eSMatthew G. Knepley PetscErrorCode ierr; 9635a93c429eSMatthew G. Knepley 9636a93c429eSMatthew G. Knepley PetscFunctionBegin; 963792fd8e1eSJed Brown ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr); 9638a93c429eSMatthew G. Knepley if (!section) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Must set default section for DM before splitting subdomain"); 9639a93c429eSMatthew G. Knepley if (!subdm) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Must set output subDM for splitting subdomain"); 9640a93c429eSMatthew G. Knepley /* Create subdomain */ 9641a93c429eSMatthew G. Knepley ierr = DMPlexFilter(dm, label, value, subdm);CHKERRQ(ierr); 9642a93c429eSMatthew G. Knepley /* Create submodel */ 964397d8846cSMatthew Knepley ierr = DMPlexGetSubpointIS(*subdm, &subis);CHKERRQ(ierr); 9644a93c429eSMatthew G. Knepley ierr = PetscSectionCreateSubmeshSection(section, subis, &subsection);CHKERRQ(ierr); 964592fd8e1eSJed Brown ierr = DMSetLocalSection(*subdm, subsection);CHKERRQ(ierr); 9646a93c429eSMatthew G. Knepley ierr = PetscSectionDestroy(&subsection);CHKERRQ(ierr); 9647e5e52638SMatthew G. Knepley ierr = DMCopyDisc(dm, *subdm);CHKERRQ(ierr); 9648a93c429eSMatthew G. Knepley /* Create map from submodel to global model */ 9649a93c429eSMatthew G. Knepley if (is) { 9650a93c429eSMatthew G. Knepley PetscSection sectionGlobal, subsectionGlobal; 9651a93c429eSMatthew G. Knepley IS spIS; 9652a93c429eSMatthew G. Knepley const PetscInt *spmap; 9653a93c429eSMatthew G. Knepley PetscInt *subIndices; 9654a93c429eSMatthew G. Knepley PetscInt subSize = 0, subOff = 0, pStart, pEnd, p; 9655a93c429eSMatthew G. Knepley PetscInt Nf, f, bs = -1, bsLocal[2], bsMinMax[2]; 9656a93c429eSMatthew G. Knepley 965797d8846cSMatthew Knepley ierr = DMPlexGetSubpointIS(*subdm, &spIS);CHKERRQ(ierr); 9658a93c429eSMatthew G. Knepley ierr = ISGetIndices(spIS, &spmap);CHKERRQ(ierr); 9659a93c429eSMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &Nf);CHKERRQ(ierr); 96606f0eb057SJed Brown ierr = DMGetGlobalSection(dm, §ionGlobal);CHKERRQ(ierr); 96616f0eb057SJed Brown ierr = DMGetGlobalSection(*subdm, &subsectionGlobal);CHKERRQ(ierr); 9662a93c429eSMatthew G. Knepley ierr = PetscSectionGetChart(subsection, &pStart, &pEnd);CHKERRQ(ierr); 9663a93c429eSMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 9664a93c429eSMatthew G. Knepley PetscInt gdof, pSubSize = 0; 9665a93c429eSMatthew G. Knepley 9666a93c429eSMatthew G. Knepley ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr); 9667a93c429eSMatthew G. Knepley if (gdof > 0) { 9668a93c429eSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 9669a93c429eSMatthew G. Knepley PetscInt fdof, fcdof; 9670a93c429eSMatthew G. Knepley 9671a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldDof(subsection, p, f, &fdof);CHKERRQ(ierr); 9672a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldConstraintDof(subsection, p, f, &fcdof);CHKERRQ(ierr); 9673a93c429eSMatthew G. Knepley pSubSize += fdof-fcdof; 9674a93c429eSMatthew G. Knepley } 9675a93c429eSMatthew G. Knepley subSize += pSubSize; 9676a93c429eSMatthew G. Knepley if (pSubSize) { 9677a93c429eSMatthew G. Knepley if (bs < 0) { 9678a93c429eSMatthew G. Knepley bs = pSubSize; 9679a93c429eSMatthew G. Knepley } else if (bs != pSubSize) { 9680a93c429eSMatthew G. Knepley /* Layout does not admit a pointwise block size */ 9681a93c429eSMatthew G. Knepley bs = 1; 9682a93c429eSMatthew G. Knepley } 9683a93c429eSMatthew G. Knepley } 9684a93c429eSMatthew G. Knepley } 9685a93c429eSMatthew G. Knepley } 9686a93c429eSMatthew G. Knepley /* Must have same blocksize on all procs (some might have no points) */ 9687a93c429eSMatthew G. Knepley bsLocal[0] = bs < 0 ? PETSC_MAX_INT : bs; bsLocal[1] = bs; 9688a93c429eSMatthew G. Knepley ierr = PetscGlobalMinMaxInt(PetscObjectComm((PetscObject) dm), bsLocal, bsMinMax);CHKERRQ(ierr); 9689a93c429eSMatthew G. Knepley if (bsMinMax[0] != bsMinMax[1]) {bs = 1;} 9690a93c429eSMatthew G. Knepley else {bs = bsMinMax[0];} 9691a93c429eSMatthew G. Knepley ierr = PetscMalloc1(subSize, &subIndices);CHKERRQ(ierr); 9692a93c429eSMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 9693a93c429eSMatthew G. Knepley PetscInt gdof, goff; 9694a93c429eSMatthew G. Knepley 9695a93c429eSMatthew G. Knepley ierr = PetscSectionGetDof(subsectionGlobal, p, &gdof);CHKERRQ(ierr); 9696a93c429eSMatthew G. Knepley if (gdof > 0) { 9697a93c429eSMatthew G. Knepley const PetscInt point = spmap[p]; 9698a93c429eSMatthew G. Knepley 9699a93c429eSMatthew G. Knepley ierr = PetscSectionGetOffset(sectionGlobal, point, &goff);CHKERRQ(ierr); 9700a93c429eSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 9701a93c429eSMatthew G. Knepley PetscInt fdof, fcdof, fc, f2, poff = 0; 9702a93c429eSMatthew G. Knepley 9703a93c429eSMatthew G. Knepley /* Can get rid of this loop by storing field information in the global section */ 9704a93c429eSMatthew G. Knepley for (f2 = 0; f2 < f; ++f2) { 9705a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, p, f2, &fdof);CHKERRQ(ierr); 9706a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldConstraintDof(section, p, f2, &fcdof);CHKERRQ(ierr); 9707a93c429eSMatthew G. Knepley poff += fdof-fcdof; 9708a93c429eSMatthew G. Knepley } 9709a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr); 9710a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr); 9711a93c429eSMatthew G. Knepley for (fc = 0; fc < fdof-fcdof; ++fc, ++subOff) { 9712a93c429eSMatthew G. Knepley subIndices[subOff] = goff+poff+fc; 9713a93c429eSMatthew G. Knepley } 9714a93c429eSMatthew G. Knepley } 9715a93c429eSMatthew G. Knepley } 9716a93c429eSMatthew G. Knepley } 9717a93c429eSMatthew G. Knepley ierr = ISRestoreIndices(spIS, &spmap);CHKERRQ(ierr); 9718a93c429eSMatthew G. Knepley ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), subSize, subIndices, PETSC_OWN_POINTER, is);CHKERRQ(ierr); 9719a93c429eSMatthew G. Knepley if (bs > 1) { 9720a93c429eSMatthew G. Knepley /* We need to check that the block size does not come from non-contiguous fields */ 9721a93c429eSMatthew G. Knepley PetscInt i, j, set = 1; 9722a93c429eSMatthew G. Knepley for (i = 0; i < subSize; i += bs) { 9723a93c429eSMatthew G. Knepley for (j = 0; j < bs; ++j) { 9724a93c429eSMatthew G. Knepley if (subIndices[i+j] != subIndices[i]+j) {set = 0; break;} 9725a93c429eSMatthew G. Knepley } 9726a93c429eSMatthew G. Knepley } 9727a93c429eSMatthew G. Knepley if (set) {ierr = ISSetBlockSize(*is, bs);CHKERRQ(ierr);} 9728a93c429eSMatthew G. Knepley } 9729a93c429eSMatthew G. Knepley /* Attach nullspace */ 9730a93c429eSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 9731a93c429eSMatthew G. Knepley (*subdm)->nullspaceConstructors[f] = dm->nullspaceConstructors[f]; 9732a93c429eSMatthew G. Knepley if ((*subdm)->nullspaceConstructors[f]) break; 9733a93c429eSMatthew G. Knepley } 9734a93c429eSMatthew G. Knepley if (f < Nf) { 9735a93c429eSMatthew G. Knepley MatNullSpace nullSpace; 97368cda7954SMatthew G. Knepley ierr = (*(*subdm)->nullspaceConstructors[f])(*subdm, f, f, &nullSpace);CHKERRQ(ierr); 97376823f3c5SBlaise Bourdin 9738a93c429eSMatthew G. Knepley ierr = PetscObjectCompose((PetscObject) *is, "nullspace", (PetscObject) nullSpace);CHKERRQ(ierr); 9739a93c429eSMatthew G. Knepley ierr = MatNullSpaceDestroy(&nullSpace);CHKERRQ(ierr); 9740a93c429eSMatthew G. Knepley } 9741a93c429eSMatthew G. Knepley } 9742a93c429eSMatthew G. Knepley PetscFunctionReturn(0); 9743a93c429eSMatthew G. Knepley } 9744c0f0dcc3SMatthew G. Knepley 9745c0f0dcc3SMatthew G. Knepley /*@ 9746c0f0dcc3SMatthew G. Knepley DMPlexMonitorThroughput - Report the cell throughput of FE integration 9747c0f0dcc3SMatthew G. Knepley 9748c0f0dcc3SMatthew G. Knepley Input Parameter: 9749c0f0dcc3SMatthew G. Knepley - dm - The DM 9750c0f0dcc3SMatthew G. Knepley 9751c0f0dcc3SMatthew G. Knepley Level: developer 9752c0f0dcc3SMatthew G. Knepley 9753c0f0dcc3SMatthew G. Knepley Options Database Keys: 9754c0f0dcc3SMatthew G. Knepley . -dm_plex_monitor_throughput - Activate the monitor 9755c0f0dcc3SMatthew G. Knepley 9756c0f0dcc3SMatthew G. Knepley .seealso: DMSetFromOptions(), DMPlexCreate() 9757c0f0dcc3SMatthew G. Knepley @*/ 9758c0f0dcc3SMatthew G. Knepley PetscErrorCode DMPlexMonitorThroughput(DM dm, void *dummy) 9759c0f0dcc3SMatthew G. Knepley { 9760e5ed2c37SJose E. Roman #if defined(PETSC_USE_LOG) 9761c0f0dcc3SMatthew G. Knepley PetscStageLog stageLog; 9762c0f0dcc3SMatthew G. Knepley PetscLogEvent event; 9763c0f0dcc3SMatthew G. Knepley PetscLogStage stage; 9764c0f0dcc3SMatthew G. Knepley PetscEventPerfInfo eventInfo; 9765c0f0dcc3SMatthew G. Knepley PetscReal cellRate, flopRate; 9766c0f0dcc3SMatthew G. Knepley PetscInt cStart, cEnd, Nf, N; 9767c0f0dcc3SMatthew G. Knepley const char *name; 9768c0f0dcc3SMatthew G. Knepley PetscErrorCode ierr; 9769e5ed2c37SJose E. Roman #endif 9770c0f0dcc3SMatthew G. Knepley 9771c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 9772c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9773c0f0dcc3SMatthew G. Knepley #if defined(PETSC_USE_LOG) 9774c0f0dcc3SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) dm, &name);CHKERRQ(ierr); 9775c0f0dcc3SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 9776c0f0dcc3SMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 9777c0f0dcc3SMatthew G. Knepley ierr = PetscLogGetStageLog(&stageLog);CHKERRQ(ierr); 9778c0f0dcc3SMatthew G. Knepley ierr = PetscStageLogGetCurrent(stageLog, &stage);CHKERRQ(ierr); 9779c0f0dcc3SMatthew G. Knepley ierr = PetscLogEventGetId("DMPlexResidualFE", &event);CHKERRQ(ierr); 9780c0f0dcc3SMatthew G. Knepley ierr = PetscLogEventGetPerfInfo(stage, event, &eventInfo);CHKERRQ(ierr); 9781c0f0dcc3SMatthew G. Knepley N = (cEnd - cStart)*Nf*eventInfo.count; 9782c0f0dcc3SMatthew G. Knepley flopRate = eventInfo.flops/eventInfo.time; 9783c0f0dcc3SMatthew G. Knepley cellRate = N/eventInfo.time; 9784fae64647SBarry 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); 9785c0f0dcc3SMatthew G. Knepley #else 9786c0f0dcc3SMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Plex Throughput Monitor is not supported if logging is turned off. Reconfigure using --with-log."); 9787c0f0dcc3SMatthew G. Knepley #endif 9788c0f0dcc3SMatthew G. Knepley PetscFunctionReturn(0); 9789c0f0dcc3SMatthew G. Knepley } 9790