1af0996ceSBarry Smith #include <petsc/private/dmpleximpl.h> /*I "petscdmplex.h" I*/ 2af0996ceSBarry Smith #include <petsc/private/isimpl.h> 3e5c6e791SKarl Rupp #include <petsc/private/vecimpl.h> 48135c375SStefano Zampini #include <petsc/private/glvisvecimpl.h> 50c312b8eSJed Brown #include <petscsf.h> 6e228b242SToby Isaac #include <petscds.h> 7e412dcbdSMatthew G. Knepley #include <petscdraw.h> 8f19dbd58SToby Isaac #include <petscdmfield.h> 9552f7358SJed Brown 10552f7358SJed Brown /* Logging support */ 11cadf77a0SMark Adams 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; 12552f7358SJed Brown 135a576424SJed Brown PETSC_EXTERN PetscErrorCode VecView_MPI(Vec, PetscViewer); 14552f7358SJed Brown 15e5337592SStefano Zampini /*@ 169318fe57SMatthew G. Knepley DMPlexIsSimplex - Is the first cell in this mesh a simplex? 179318fe57SMatthew G. Knepley 189318fe57SMatthew G. Knepley Input Parameter: 199318fe57SMatthew G. Knepley . dm - The DMPlex object 209318fe57SMatthew G. Knepley 219318fe57SMatthew G. Knepley Output Parameter: 229318fe57SMatthew G. Knepley . simplex - Flag checking for a simplex 239318fe57SMatthew G. Knepley 249318fe57SMatthew 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. 259318fe57SMatthew G. Knepley If the mesh has no cells, this returns PETSC_FALSE. 269318fe57SMatthew G. Knepley 279318fe57SMatthew G. Knepley Level: intermediate 289318fe57SMatthew G. Knepley 299318fe57SMatthew G. Knepley .seealso DMPlexGetSimplexOrBoxCells(), DMPlexGetCellType(), DMPlexGetHeightStratum(), DMPolytopeTypeGetNumVertices() 309318fe57SMatthew G. Knepley @*/ 319318fe57SMatthew G. Knepley PetscErrorCode DMPlexIsSimplex(DM dm, PetscBool *simplex) 329318fe57SMatthew G. Knepley { 339318fe57SMatthew G. Knepley DMPolytopeType ct; 349318fe57SMatthew G. Knepley PetscInt cStart, cEnd; 359318fe57SMatthew G. Knepley PetscErrorCode ierr; 369318fe57SMatthew G. Knepley 379318fe57SMatthew G. Knepley PetscFunctionBegin; 389318fe57SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 399318fe57SMatthew G. Knepley if (cEnd <= cStart) {*simplex = PETSC_FALSE; PetscFunctionReturn(0);} 409318fe57SMatthew G. Knepley ierr = DMPlexGetCellType(dm, cStart, &ct);CHKERRQ(ierr); 419318fe57SMatthew G. Knepley *simplex = DMPolytopeTypeGetNumVertices(ct) == DMPolytopeTypeGetDim(ct)+1 ? PETSC_TRUE : PETSC_FALSE; 429318fe57SMatthew G. Knepley PetscFunctionReturn(0); 439318fe57SMatthew G. Knepley } 449318fe57SMatthew G. Knepley 459318fe57SMatthew G. Knepley /*@ 46412e9a14SMatthew G. Knepley DMPlexGetSimplexOrBoxCells - Get the range of cells which are neither prisms nor ghost FV cells 47e5337592SStefano Zampini 48412e9a14SMatthew G. Knepley Input Parameter: 49412e9a14SMatthew G. Knepley + dm - The DMPlex object 50412e9a14SMatthew G. Knepley - height - The cell height in the Plex, 0 is the default 51e5337592SStefano Zampini 52e5337592SStefano Zampini Output Parameters: 53412e9a14SMatthew G. Knepley + cStart - The first "normal" cell 54412e9a14SMatthew G. Knepley - cEnd - The upper bound on "normal"" cells 55e5337592SStefano Zampini 56412e9a14SMatthew 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. 57e5337592SStefano Zampini 58412e9a14SMatthew G. Knepley Level: developer 59e5337592SStefano Zampini 608065b584SMatthew Knepley .seealso DMPlexConstructGhostCells(), DMPlexGetGhostCellStratum() 61e5337592SStefano Zampini @*/ 62412e9a14SMatthew G. Knepley PetscErrorCode DMPlexGetSimplexOrBoxCells(DM dm, PetscInt height, PetscInt *cStart, PetscInt *cEnd) 63e5337592SStefano Zampini { 64412e9a14SMatthew G. Knepley DMPolytopeType ct = DM_POLYTOPE_UNKNOWN; 65412e9a14SMatthew G. Knepley PetscInt cS, cE, c; 66e5337592SStefano Zampini PetscErrorCode ierr; 67e5337592SStefano Zampini 68e5337592SStefano Zampini PetscFunctionBegin; 69412e9a14SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, PetscMax(height, 0), &cS, &cE);CHKERRQ(ierr); 70412e9a14SMatthew G. Knepley for (c = cS; c < cE; ++c) { 71412e9a14SMatthew G. Knepley DMPolytopeType cct; 72412e9a14SMatthew G. Knepley 73412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, c, &cct);CHKERRQ(ierr); 74412e9a14SMatthew G. Knepley if ((PetscInt) cct < 0) break; 75412e9a14SMatthew G. Knepley switch (cct) { 76ba2698f1SMatthew G. Knepley case DM_POLYTOPE_POINT: 77ba2698f1SMatthew G. Knepley case DM_POLYTOPE_SEGMENT: 78ba2698f1SMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 79ba2698f1SMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 80ba2698f1SMatthew G. Knepley case DM_POLYTOPE_TETRAHEDRON: 81ba2698f1SMatthew G. Knepley case DM_POLYTOPE_HEXAHEDRON: 82412e9a14SMatthew G. Knepley ct = cct; 83e5337592SStefano Zampini break; 84412e9a14SMatthew G. Knepley default: break; 85e5337592SStefano Zampini } 86412e9a14SMatthew G. Knepley if (ct != DM_POLYTOPE_UNKNOWN) break; 87e5337592SStefano Zampini } 88412e9a14SMatthew G. Knepley if (ct != DM_POLYTOPE_UNKNOWN) { 89412e9a14SMatthew G. Knepley DMLabel ctLabel; 90412e9a14SMatthew G. Knepley 91412e9a14SMatthew G. Knepley ierr = DMPlexGetCellTypeLabel(dm, &ctLabel);CHKERRQ(ierr); 92412e9a14SMatthew G. Knepley ierr = DMLabelGetStratumBounds(ctLabel, ct, &cS, &cE);CHKERRQ(ierr); 93e5337592SStefano Zampini } 94412e9a14SMatthew G. Knepley if (cStart) *cStart = cS; 95412e9a14SMatthew G. Knepley if (cEnd) *cEnd = cE; 96e5337592SStefano Zampini PetscFunctionReturn(0); 97e5337592SStefano Zampini } 98e5337592SStefano Zampini 997afe7537SMatthew G. Knepley PetscErrorCode DMPlexGetFieldType_Internal(DM dm, PetscSection section, PetscInt field, PetscInt *sStart, PetscInt *sEnd, PetscViewerVTKFieldType *ft) 1007e42fee7SMatthew G. Knepley { 101412e9a14SMatthew G. Knepley PetscInt cdim, pStart, pEnd, vStart, vEnd, cStart, cEnd; 102a99a26bcSAdrian Croucher PetscInt vcdof[2] = {0,0}, globalvcdof[2]; 1037e42fee7SMatthew G. Knepley PetscErrorCode ierr; 1047e42fee7SMatthew G. Knepley 1057e42fee7SMatthew G. Knepley PetscFunctionBegin; 106e630c359SToby Isaac *ft = PETSC_VTK_INVALID; 107f094498dSMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &cdim);CHKERRQ(ierr); 1087e42fee7SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 109412e9a14SMatthew G. Knepley ierr = DMPlexGetSimplexOrBoxCells(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 1107e42fee7SMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 1117e42fee7SMatthew G. Knepley if (field >= 0) { 112a99a26bcSAdrian Croucher if ((vStart >= pStart) && (vStart < pEnd)) {ierr = PetscSectionGetFieldDof(section, vStart, field, &vcdof[0]);CHKERRQ(ierr);} 113a99a26bcSAdrian Croucher if ((cStart >= pStart) && (cStart < pEnd)) {ierr = PetscSectionGetFieldDof(section, cStart, field, &vcdof[1]);CHKERRQ(ierr);} 1147e42fee7SMatthew G. Knepley } else { 115a99a26bcSAdrian Croucher if ((vStart >= pStart) && (vStart < pEnd)) {ierr = PetscSectionGetDof(section, vStart, &vcdof[0]);CHKERRQ(ierr);} 116a99a26bcSAdrian Croucher if ((cStart >= pStart) && (cStart < pEnd)) {ierr = PetscSectionGetDof(section, cStart, &vcdof[1]);CHKERRQ(ierr);} 1177e42fee7SMatthew G. Knepley } 118ffc4695bSBarry Smith ierr = MPI_Allreduce(vcdof, globalvcdof, 2, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject)dm));CHKERRMPI(ierr); 119a99a26bcSAdrian Croucher if (globalvcdof[0]) { 1207e42fee7SMatthew G. Knepley *sStart = vStart; 1217e42fee7SMatthew G. Knepley *sEnd = vEnd; 122f094498dSMatthew G. Knepley if (globalvcdof[0] == cdim) *ft = PETSC_VTK_POINT_VECTOR_FIELD; 1237e42fee7SMatthew G. Knepley else *ft = PETSC_VTK_POINT_FIELD; 124a99a26bcSAdrian Croucher } else if (globalvcdof[1]) { 1257e42fee7SMatthew G. Knepley *sStart = cStart; 1267e42fee7SMatthew G. Knepley *sEnd = cEnd; 127f094498dSMatthew G. Knepley if (globalvcdof[1] == cdim) *ft = PETSC_VTK_CELL_VECTOR_FIELD; 1287e42fee7SMatthew G. Knepley else *ft = PETSC_VTK_CELL_FIELD; 129e630c359SToby Isaac } else { 130e630c359SToby Isaac if (field >= 0) { 131e630c359SToby Isaac const char *fieldname; 132e630c359SToby Isaac 133e630c359SToby Isaac ierr = PetscSectionGetFieldName(section, field, &fieldname);CHKERRQ(ierr); 134e630c359SToby Isaac ierr = PetscInfo2((PetscObject) dm, "Could not classify VTK output type of section field %D \"%s\"\n", field, fieldname);CHKERRQ(ierr); 135e630c359SToby Isaac } else { 1366823f3c5SBlaise Bourdin ierr = PetscInfo((PetscObject) dm, "Could not classify VTK output type of section\"%s\"\n");CHKERRQ(ierr); 137e630c359SToby Isaac } 138e630c359SToby Isaac } 1397e42fee7SMatthew G. Knepley PetscFunctionReturn(0); 1407e42fee7SMatthew G. Knepley } 1417e42fee7SMatthew G. Knepley 1427cd05799SMatthew G. Knepley static PetscErrorCode VecView_Plex_Local_Draw(Vec v, PetscViewer viewer) 143e412dcbdSMatthew G. Knepley { 144e412dcbdSMatthew G. Knepley DM dm; 145d1df6f1dSMatthew G. Knepley PetscSection s; 146e412dcbdSMatthew G. Knepley PetscDraw draw, popup; 147e412dcbdSMatthew G. Knepley DM cdm; 148e412dcbdSMatthew G. Knepley PetscSection coordSection; 149e412dcbdSMatthew G. Knepley Vec coordinates; 150e412dcbdSMatthew G. Knepley const PetscScalar *coords, *array; 151e412dcbdSMatthew G. Knepley PetscReal bound[4] = {PETSC_MAX_REAL, PETSC_MAX_REAL, PETSC_MIN_REAL, PETSC_MIN_REAL}; 152339e3443SMatthew G. Knepley PetscReal vbound[2], time; 153339e3443SMatthew G. Knepley PetscBool isnull, flg; 154d1df6f1dSMatthew G. Knepley PetscInt dim, Nf, f, Nc, comp, vStart, vEnd, cStart, cEnd, c, N, level, step, w = 0; 155e412dcbdSMatthew G. Knepley const char *name; 156339e3443SMatthew G. Knepley char title[PETSC_MAX_PATH_LEN]; 157e412dcbdSMatthew G. Knepley PetscErrorCode ierr; 158e412dcbdSMatthew G. Knepley 159e412dcbdSMatthew G. Knepley PetscFunctionBegin; 160d1df6f1dSMatthew G. Knepley ierr = PetscViewerDrawGetDraw(viewer, 0, &draw);CHKERRQ(ierr); 161d1df6f1dSMatthew G. Knepley ierr = PetscDrawIsNull(draw, &isnull);CHKERRQ(ierr); 162d1df6f1dSMatthew G. Knepley if (isnull) PetscFunctionReturn(0); 163d1df6f1dSMatthew G. Knepley 164e412dcbdSMatthew G. Knepley ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 165e412dcbdSMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dim);CHKERRQ(ierr); 1668135c375SStefano Zampini if (dim != 2) SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Cannot draw meshes of dimension %D. Use PETSCVIEWERGLVIS", dim); 16792fd8e1eSJed Brown ierr = DMGetLocalSection(dm, &s);CHKERRQ(ierr); 168d1df6f1dSMatthew G. Knepley ierr = PetscSectionGetNumFields(s, &Nf);CHKERRQ(ierr); 169e412dcbdSMatthew G. Knepley ierr = DMGetCoarsenLevel(dm, &level);CHKERRQ(ierr); 170e412dcbdSMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 17192fd8e1eSJed Brown ierr = DMGetLocalSection(cdm, &coordSection);CHKERRQ(ierr); 172e412dcbdSMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 173e412dcbdSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 174e412dcbdSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 175e412dcbdSMatthew G. Knepley 176e412dcbdSMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) v, &name);CHKERRQ(ierr); 177339e3443SMatthew G. Knepley ierr = DMGetOutputSequenceNumber(dm, &step, &time);CHKERRQ(ierr); 178e412dcbdSMatthew G. Knepley 179e412dcbdSMatthew G. Knepley ierr = VecGetLocalSize(coordinates, &N);CHKERRQ(ierr); 180e412dcbdSMatthew G. Knepley ierr = VecGetArrayRead(coordinates, &coords);CHKERRQ(ierr); 181e412dcbdSMatthew G. Knepley for (c = 0; c < N; c += dim) { 1820c81f2a8SMatthew G. Knepley bound[0] = PetscMin(bound[0], PetscRealPart(coords[c])); bound[2] = PetscMax(bound[2], PetscRealPart(coords[c])); 1830c81f2a8SMatthew G. Knepley bound[1] = PetscMin(bound[1], PetscRealPart(coords[c+1])); bound[3] = PetscMax(bound[3], PetscRealPart(coords[c+1])); 184e412dcbdSMatthew G. Knepley } 185e412dcbdSMatthew G. Knepley ierr = VecRestoreArrayRead(coordinates, &coords);CHKERRQ(ierr); 186e412dcbdSMatthew G. Knepley ierr = PetscDrawClear(draw);CHKERRQ(ierr); 187e412dcbdSMatthew G. Knepley 188d1df6f1dSMatthew G. Knepley /* Could implement something like DMDASelectFields() */ 189d1df6f1dSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 190d1df6f1dSMatthew G. Knepley DM fdm = dm; 191d1df6f1dSMatthew G. Knepley Vec fv = v; 192d1df6f1dSMatthew G. Knepley IS fis; 193d1df6f1dSMatthew G. Knepley char prefix[PETSC_MAX_PATH_LEN]; 194d1df6f1dSMatthew G. Knepley const char *fname; 195d1df6f1dSMatthew G. Knepley 196d1df6f1dSMatthew G. Knepley ierr = PetscSectionGetFieldComponents(s, f, &Nc);CHKERRQ(ierr); 197d1df6f1dSMatthew G. Knepley ierr = PetscSectionGetFieldName(s, f, &fname);CHKERRQ(ierr); 198d1df6f1dSMatthew G. Knepley 199a126751eSBarry Smith if (v->hdr.prefix) {ierr = PetscStrncpy(prefix, v->hdr.prefix,sizeof(prefix));CHKERRQ(ierr);} 200d1df6f1dSMatthew G. Knepley else {prefix[0] = '\0';} 201d1df6f1dSMatthew G. Knepley if (Nf > 1) { 202d1df6f1dSMatthew G. Knepley ierr = DMCreateSubDM(dm, 1, &f, &fis, &fdm);CHKERRQ(ierr); 203d1df6f1dSMatthew G. Knepley ierr = VecGetSubVector(v, fis, &fv);CHKERRQ(ierr); 204a126751eSBarry Smith ierr = PetscStrlcat(prefix, fname,sizeof(prefix));CHKERRQ(ierr); 205a126751eSBarry Smith ierr = PetscStrlcat(prefix, "_",sizeof(prefix));CHKERRQ(ierr); 206d1df6f1dSMatthew G. Knepley } 207d1df6f1dSMatthew G. Knepley for (comp = 0; comp < Nc; ++comp, ++w) { 208d1df6f1dSMatthew G. Knepley PetscInt nmax = 2; 209d1df6f1dSMatthew G. Knepley 210d1df6f1dSMatthew G. Knepley ierr = PetscViewerDrawGetDraw(viewer, w, &draw);CHKERRQ(ierr); 211d1df6f1dSMatthew G. Knepley if (Nc > 1) {ierr = PetscSNPrintf(title, sizeof(title), "%s:%s_%D Step: %D Time: %.4g", name, fname, comp, step, time);CHKERRQ(ierr);} 212d1df6f1dSMatthew G. Knepley else {ierr = PetscSNPrintf(title, sizeof(title), "%s:%s Step: %D Time: %.4g", name, fname, step, time);CHKERRQ(ierr);} 213d1df6f1dSMatthew G. Knepley ierr = PetscDrawSetTitle(draw, title);CHKERRQ(ierr); 214d1df6f1dSMatthew G. Knepley 215d1df6f1dSMatthew G. Knepley /* TODO Get max and min only for this component */ 216d1df6f1dSMatthew G. Knepley ierr = PetscOptionsGetRealArray(NULL, prefix, "-vec_view_bounds", vbound, &nmax, &flg);CHKERRQ(ierr); 217339e3443SMatthew G. Knepley if (!flg) { 218d1df6f1dSMatthew G. Knepley ierr = VecMin(fv, NULL, &vbound[0]);CHKERRQ(ierr); 219d1df6f1dSMatthew G. Knepley ierr = VecMax(fv, NULL, &vbound[1]);CHKERRQ(ierr); 220d1df6f1dSMatthew G. Knepley if (vbound[1] <= vbound[0]) vbound[1] = vbound[0] + 1.0; 221339e3443SMatthew G. Knepley } 222e412dcbdSMatthew G. Knepley ierr = PetscDrawGetPopup(draw, &popup);CHKERRQ(ierr); 223339e3443SMatthew G. Knepley ierr = PetscDrawScalePopup(popup, vbound[0], vbound[1]);CHKERRQ(ierr); 224d1df6f1dSMatthew G. Knepley ierr = PetscDrawSetCoordinates(draw, bound[0], bound[1], bound[2], bound[3]);CHKERRQ(ierr); 225e412dcbdSMatthew G. Knepley 226d1df6f1dSMatthew G. Knepley ierr = VecGetArrayRead(fv, &array);CHKERRQ(ierr); 227e412dcbdSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 22899a2f7bcSMatthew G. Knepley PetscScalar *coords = NULL, *a = NULL; 229e56f9228SJed Brown PetscInt numCoords, color[4] = {-1,-1,-1,-1}; 230e412dcbdSMatthew G. Knepley 231d1df6f1dSMatthew G. Knepley ierr = DMPlexPointLocalRead(fdm, c, array, &a);CHKERRQ(ierr); 232339e3443SMatthew G. Knepley if (a) { 233d1df6f1dSMatthew G. Knepley color[0] = PetscDrawRealToColor(PetscRealPart(a[comp]), vbound[0], vbound[1]); 234339e3443SMatthew G. Knepley color[1] = color[2] = color[3] = color[0]; 235339e3443SMatthew G. Knepley } else { 236339e3443SMatthew G. Knepley PetscScalar *vals = NULL; 237339e3443SMatthew G. Knepley PetscInt numVals, va; 238339e3443SMatthew G. Knepley 239d1df6f1dSMatthew G. Knepley ierr = DMPlexVecGetClosure(fdm, NULL, fv, c, &numVals, &vals);CHKERRQ(ierr); 240d1df6f1dSMatthew 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); 241d1df6f1dSMatthew G. Knepley switch (numVals/Nc) { 242d1df6f1dSMatthew G. Knepley case 3: /* P1 Triangle */ 243d1df6f1dSMatthew G. Knepley case 4: /* P1 Quadrangle */ 244d1df6f1dSMatthew G. Knepley for (va = 0; va < numVals/Nc; ++va) color[va] = PetscDrawRealToColor(PetscRealPart(vals[va*Nc+comp]), vbound[0], vbound[1]); 245339e3443SMatthew G. Knepley break; 246d1df6f1dSMatthew G. Knepley case 6: /* P2 Triangle */ 247d1df6f1dSMatthew G. Knepley case 8: /* P2 Quadrangle */ 248d1df6f1dSMatthew 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]); 249d1df6f1dSMatthew G. Knepley break; 250d1df6f1dSMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Number of values for cell closure %D cannot be handled", numVals/Nc); 251339e3443SMatthew G. Knepley } 252d1df6f1dSMatthew G. Knepley ierr = DMPlexVecRestoreClosure(fdm, NULL, fv, c, &numVals, &vals);CHKERRQ(ierr); 253339e3443SMatthew G. Knepley } 254e412dcbdSMatthew G. Knepley ierr = DMPlexVecGetClosure(dm, coordSection, coordinates, c, &numCoords, &coords);CHKERRQ(ierr); 255e412dcbdSMatthew G. Knepley switch (numCoords) { 256e412dcbdSMatthew G. Knepley case 6: 257*9edc3542SMatthew Knepley case 12: /* Localized triangle */ 258339e3443SMatthew 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); 259e412dcbdSMatthew G. Knepley break; 260e412dcbdSMatthew G. Knepley case 8: 261*9edc3542SMatthew Knepley case 16: /* Localized quadrilateral */ 262339e3443SMatthew G. Knepley ierr = PetscDrawTriangle(draw, PetscRealPart(coords[0]), PetscRealPart(coords[1]), PetscRealPart(coords[2]), PetscRealPart(coords[3]), PetscRealPart(coords[4]), PetscRealPart(coords[5]), color[0], color[1], color[2]);CHKERRQ(ierr); 263339e3443SMatthew 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); 264e412dcbdSMatthew G. Knepley break; 265e412dcbdSMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot draw cells with %D coordinates", numCoords); 266e412dcbdSMatthew G. Knepley } 267e412dcbdSMatthew G. Knepley ierr = DMPlexVecRestoreClosure(dm, coordSection, coordinates, c, &numCoords, &coords);CHKERRQ(ierr); 268e412dcbdSMatthew G. Knepley } 269d1df6f1dSMatthew G. Knepley ierr = VecRestoreArrayRead(fv, &array);CHKERRQ(ierr); 270e412dcbdSMatthew G. Knepley ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 271e412dcbdSMatthew G. Knepley ierr = PetscDrawPause(draw);CHKERRQ(ierr); 272e412dcbdSMatthew G. Knepley ierr = PetscDrawSave(draw);CHKERRQ(ierr); 273d1df6f1dSMatthew G. Knepley } 274d1df6f1dSMatthew G. Knepley if (Nf > 1) { 275d1df6f1dSMatthew G. Knepley ierr = VecRestoreSubVector(v, fis, &fv);CHKERRQ(ierr); 276d1df6f1dSMatthew G. Knepley ierr = ISDestroy(&fis);CHKERRQ(ierr); 277d1df6f1dSMatthew G. Knepley ierr = DMDestroy(&fdm);CHKERRQ(ierr); 278d1df6f1dSMatthew G. Knepley } 279d1df6f1dSMatthew G. Knepley } 280e412dcbdSMatthew G. Knepley PetscFunctionReturn(0); 281e412dcbdSMatthew G. Knepley } 282e412dcbdSMatthew G. Knepley 283684b87d9SLisandro Dalcin static PetscErrorCode VecView_Plex_Local_VTK(Vec v, PetscViewer viewer) 284684b87d9SLisandro Dalcin { 285684b87d9SLisandro Dalcin DM dm; 286684b87d9SLisandro Dalcin Vec locv; 287684b87d9SLisandro Dalcin const char *name; 288684b87d9SLisandro Dalcin PetscSection section; 289684b87d9SLisandro Dalcin PetscInt pStart, pEnd; 290e630c359SToby Isaac PetscInt numFields; 291684b87d9SLisandro Dalcin PetscViewerVTKFieldType ft; 292684b87d9SLisandro Dalcin PetscErrorCode ierr; 293684b87d9SLisandro Dalcin 294684b87d9SLisandro Dalcin PetscFunctionBegin; 295684b87d9SLisandro Dalcin ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 296684b87d9SLisandro Dalcin ierr = DMCreateLocalVector(dm, &locv);CHKERRQ(ierr); /* VTK viewer requires exclusive ownership of the vector */ 297684b87d9SLisandro Dalcin ierr = PetscObjectGetName((PetscObject) v, &name);CHKERRQ(ierr); 298684b87d9SLisandro Dalcin ierr = PetscObjectSetName((PetscObject) locv, name);CHKERRQ(ierr); 299684b87d9SLisandro Dalcin ierr = VecCopy(v, locv);CHKERRQ(ierr); 30092fd8e1eSJed Brown ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr); 301e630c359SToby Isaac ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 302e630c359SToby Isaac if (!numFields) { 303684b87d9SLisandro Dalcin ierr = DMPlexGetFieldType_Internal(dm, section, PETSC_DETERMINE, &pStart, &pEnd, &ft);CHKERRQ(ierr); 304e630c359SToby Isaac ierr = PetscViewerVTKAddField(viewer, (PetscObject) dm, DMPlexVTKWriteAll, PETSC_DEFAULT, ft, PETSC_TRUE,(PetscObject) locv);CHKERRQ(ierr); 305e630c359SToby Isaac } else { 306e630c359SToby Isaac PetscInt f; 307e630c359SToby Isaac 308e630c359SToby Isaac for (f = 0; f < numFields; f++) { 309e630c359SToby Isaac ierr = DMPlexGetFieldType_Internal(dm, section, f, &pStart, &pEnd, &ft);CHKERRQ(ierr); 310e630c359SToby Isaac if (ft == PETSC_VTK_INVALID) continue; 311e630c359SToby Isaac ierr = PetscObjectReference((PetscObject)locv);CHKERRQ(ierr); 312e630c359SToby Isaac ierr = PetscViewerVTKAddField(viewer, (PetscObject) dm, DMPlexVTKWriteAll, f, ft, PETSC_TRUE,(PetscObject) locv);CHKERRQ(ierr); 313e630c359SToby Isaac } 314e630c359SToby Isaac ierr = VecDestroy(&locv);CHKERRQ(ierr); 315e630c359SToby Isaac } 316684b87d9SLisandro Dalcin PetscFunctionReturn(0); 317684b87d9SLisandro Dalcin } 318684b87d9SLisandro Dalcin 319552f7358SJed Brown PetscErrorCode VecView_Plex_Local(Vec v, PetscViewer viewer) 320552f7358SJed Brown { 321552f7358SJed Brown DM dm; 322684b87d9SLisandro Dalcin PetscBool isvtk, ishdf5, isdraw, isglvis; 323552f7358SJed Brown PetscErrorCode ierr; 324552f7358SJed Brown 325552f7358SJed Brown PetscFunctionBegin; 326552f7358SJed Brown ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 32782f516ccSBarry Smith if (!dm) SETERRQ(PetscObjectComm((PetscObject)v), PETSC_ERR_ARG_WRONG, "Vector not generated from a DM"); 328552f7358SJed Brown ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERVTK, &isvtk);CHKERRQ(ierr); 329b136c2c9SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 330f13a32a3SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERDRAW, &isdraw);CHKERRQ(ierr); 3318135c375SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERGLVIS, &isglvis);CHKERRQ(ierr); 332684b87d9SLisandro Dalcin if (isvtk || ishdf5 || isdraw || isglvis) { 333684b87d9SLisandro Dalcin PetscInt i,numFields; 334684b87d9SLisandro Dalcin PetscObject fe; 335ef31f671SMatthew G. Knepley PetscBool fem = PETSC_FALSE; 336684b87d9SLisandro Dalcin Vec locv = v; 337684b87d9SLisandro Dalcin const char *name; 338684b87d9SLisandro Dalcin PetscInt step; 339684b87d9SLisandro Dalcin PetscReal time; 340ef31f671SMatthew G. Knepley 341ef31f671SMatthew G. Knepley ierr = DMGetNumFields(dm, &numFields);CHKERRQ(ierr); 342684b87d9SLisandro Dalcin for (i=0; i<numFields; i++) { 34344a7f3ddSMatthew G. Knepley ierr = DMGetField(dm, i, NULL, &fe);CHKERRQ(ierr); 344684b87d9SLisandro Dalcin if (fe->classid == PETSCFE_CLASSID) { fem = PETSC_TRUE; break; } 345ef31f671SMatthew G. Knepley } 346684b87d9SLisandro Dalcin if (fem) { 347798534f6SMatthew G. Knepley PetscObject isZero; 348798534f6SMatthew G. Knepley 349684b87d9SLisandro Dalcin ierr = DMGetLocalVector(dm, &locv);CHKERRQ(ierr); 350684b87d9SLisandro Dalcin ierr = PetscObjectGetName((PetscObject) v, &name);CHKERRQ(ierr); 351684b87d9SLisandro Dalcin ierr = PetscObjectSetName((PetscObject) locv, name);CHKERRQ(ierr); 352798534f6SMatthew G. Knepley ierr = PetscObjectQuery((PetscObject) v, "__Vec_bc_zero__", &isZero);CHKERRQ(ierr); 353798534f6SMatthew G. Knepley ierr = PetscObjectCompose((PetscObject) locv, "__Vec_bc_zero__", isZero);CHKERRQ(ierr); 354684b87d9SLisandro Dalcin ierr = VecCopy(v, locv);CHKERRQ(ierr); 355684b87d9SLisandro Dalcin ierr = DMGetOutputSequenceNumber(dm, NULL, &time);CHKERRQ(ierr); 356684b87d9SLisandro Dalcin ierr = DMPlexInsertBoundaryValues(dm, PETSC_TRUE, locv, time, NULL, NULL, NULL);CHKERRQ(ierr); 357ef31f671SMatthew G. Knepley } 358552f7358SJed Brown if (isvtk) { 359684b87d9SLisandro Dalcin ierr = VecView_Plex_Local_VTK(locv, viewer);CHKERRQ(ierr); 360b136c2c9SMatthew G. Knepley } else if (ishdf5) { 361b136c2c9SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 362684b87d9SLisandro Dalcin ierr = VecView_Plex_Local_HDF5_Internal(locv, viewer);CHKERRQ(ierr); 363b136c2c9SMatthew G. Knepley #else 364b136c2c9SMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 365b136c2c9SMatthew G. Knepley #endif 366f13a32a3SMatthew G. Knepley } else if (isdraw) { 367684b87d9SLisandro Dalcin ierr = VecView_Plex_Local_Draw(locv, viewer);CHKERRQ(ierr); 368684b87d9SLisandro Dalcin } else if (isglvis) { 369684b87d9SLisandro Dalcin ierr = DMGetOutputSequenceNumber(dm, &step, NULL);CHKERRQ(ierr); 370684b87d9SLisandro Dalcin ierr = PetscViewerGLVisSetSnapId(viewer, step);CHKERRQ(ierr); 371684b87d9SLisandro Dalcin ierr = VecView_GLVis(locv, viewer);CHKERRQ(ierr); 372684b87d9SLisandro Dalcin } 373798534f6SMatthew G. Knepley if (fem) { 374798534f6SMatthew G. Knepley ierr = PetscObjectCompose((PetscObject) locv, "__Vec_bc_zero__", NULL);CHKERRQ(ierr); 375798534f6SMatthew G. Knepley ierr = DMRestoreLocalVector(dm, &locv);CHKERRQ(ierr); 376798534f6SMatthew G. Knepley } 377552f7358SJed Brown } else { 378684b87d9SLisandro Dalcin PetscBool isseq; 379684b87d9SLisandro Dalcin 380684b87d9SLisandro Dalcin ierr = PetscObjectTypeCompare((PetscObject) v, VECSEQ, &isseq);CHKERRQ(ierr); 38155f2e967SMatthew G. Knepley if (isseq) {ierr = VecView_Seq(v, viewer);CHKERRQ(ierr);} 38255f2e967SMatthew G. Knepley else {ierr = VecView_MPI(v, viewer);CHKERRQ(ierr);} 383552f7358SJed Brown } 384552f7358SJed Brown PetscFunctionReturn(0); 385552f7358SJed Brown } 386552f7358SJed Brown 387552f7358SJed Brown PetscErrorCode VecView_Plex(Vec v, PetscViewer viewer) 388552f7358SJed Brown { 389552f7358SJed Brown DM dm; 3906823f3c5SBlaise Bourdin PetscBool isvtk, ishdf5, isdraw, isglvis, isexodusii; 391552f7358SJed Brown PetscErrorCode ierr; 392552f7358SJed Brown 393552f7358SJed Brown PetscFunctionBegin; 394552f7358SJed Brown ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 39582f516ccSBarry Smith if (!dm) SETERRQ(PetscObjectComm((PetscObject)v), PETSC_ERR_ARG_WRONG, "Vector not generated from a DM"); 396552f7358SJed Brown ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERVTK, &isvtk);CHKERRQ(ierr); 39733c3e6b4SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 398e412dcbdSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERDRAW, &isdraw);CHKERRQ(ierr); 3998135c375SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERGLVIS, &isglvis);CHKERRQ(ierr); 4006823f3c5SBlaise Bourdin ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWEREXODUSII, &isexodusii);CHKERRQ(ierr); 401684b87d9SLisandro Dalcin if (isvtk || isdraw || isglvis) { 402552f7358SJed Brown Vec locv; 403798534f6SMatthew G. Knepley PetscObject isZero; 404552f7358SJed Brown const char *name; 405552f7358SJed Brown 406c8dd51e9SBarry Smith ierr = DMGetLocalVector(dm, &locv);CHKERRQ(ierr); 407552f7358SJed Brown ierr = PetscObjectGetName((PetscObject) v, &name);CHKERRQ(ierr); 408552f7358SJed Brown ierr = PetscObjectSetName((PetscObject) locv, name);CHKERRQ(ierr); 409552f7358SJed Brown ierr = DMGlobalToLocalBegin(dm, v, INSERT_VALUES, locv);CHKERRQ(ierr); 410552f7358SJed Brown ierr = DMGlobalToLocalEnd(dm, v, INSERT_VALUES, locv);CHKERRQ(ierr); 411798534f6SMatthew G. Knepley ierr = PetscObjectQuery((PetscObject) v, "__Vec_bc_zero__", &isZero);CHKERRQ(ierr); 412798534f6SMatthew G. Knepley ierr = PetscObjectCompose((PetscObject) locv, "__Vec_bc_zero__", isZero);CHKERRQ(ierr); 413552f7358SJed Brown ierr = VecView_Plex_Local(locv, viewer);CHKERRQ(ierr); 414798534f6SMatthew G. Knepley ierr = PetscObjectCompose((PetscObject) locv, "__Vec_bc_zero__", NULL);CHKERRQ(ierr); 415c8dd51e9SBarry Smith ierr = DMRestoreLocalVector(dm, &locv);CHKERRQ(ierr); 416b136c2c9SMatthew G. Knepley } else if (ishdf5) { 417b136c2c9SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 41839d25373SMatthew G. Knepley ierr = VecView_Plex_HDF5_Internal(v, viewer);CHKERRQ(ierr); 419b136c2c9SMatthew G. Knepley #else 420b136c2c9SMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 421b136c2c9SMatthew G. Knepley #endif 4226823f3c5SBlaise Bourdin } else if (isexodusii) { 4236823f3c5SBlaise Bourdin #if defined(PETSC_HAVE_EXODUSII) 4246823f3c5SBlaise Bourdin ierr = VecView_PlexExodusII_Internal(v, viewer);CHKERRQ(ierr); 4256823f3c5SBlaise Bourdin #else 4266823f3c5SBlaise Bourdin SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "ExodusII not supported in this build.\nPlease reconfigure using --download-exodusii"); 4276823f3c5SBlaise Bourdin #endif 428552f7358SJed Brown } else { 429684b87d9SLisandro Dalcin PetscBool isseq; 430684b87d9SLisandro Dalcin 431684b87d9SLisandro Dalcin ierr = PetscObjectTypeCompare((PetscObject) v, VECSEQ, &isseq);CHKERRQ(ierr); 43255f2e967SMatthew G. Knepley if (isseq) {ierr = VecView_Seq(v, viewer);CHKERRQ(ierr);} 43355f2e967SMatthew G. Knepley else {ierr = VecView_MPI(v, viewer);CHKERRQ(ierr);} 434552f7358SJed Brown } 435552f7358SJed Brown PetscFunctionReturn(0); 436552f7358SJed Brown } 437552f7358SJed Brown 438d930f514SMatthew G. Knepley PetscErrorCode VecView_Plex_Native(Vec originalv, PetscViewer viewer) 439d930f514SMatthew G. Knepley { 440d930f514SMatthew G. Knepley DM dm; 441d930f514SMatthew G. Knepley MPI_Comm comm; 442d930f514SMatthew G. Knepley PetscViewerFormat format; 443d930f514SMatthew G. Knepley Vec v; 444d930f514SMatthew G. Knepley PetscBool isvtk, ishdf5; 445d930f514SMatthew G. Knepley PetscErrorCode ierr; 446d930f514SMatthew G. Knepley 447d930f514SMatthew G. Knepley PetscFunctionBegin; 448d930f514SMatthew G. Knepley ierr = VecGetDM(originalv, &dm);CHKERRQ(ierr); 449d930f514SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject) originalv, &comm);CHKERRQ(ierr); 4502c4c0c81SMatthew G. Knepley if (!dm) SETERRQ(comm, PETSC_ERR_ARG_WRONG, "Vector not generated from a DM"); 451d930f514SMatthew G. Knepley ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 452d930f514SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 453d930f514SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERVTK, &isvtk);CHKERRQ(ierr); 454d930f514SMatthew G. Knepley if (format == PETSC_VIEWER_NATIVE) { 455a8ad634aSStefano Zampini /* Natural ordering is the common case for DMDA, NATIVE means plain vector, for PLEX is the opposite */ 456a8ad634aSStefano Zampini /* this need a better fix */ 457a8ad634aSStefano Zampini if (dm->useNatural) { 458a8ad634aSStefano Zampini if (dm->sfNatural) { 459d930f514SMatthew G. Knepley const char *vecname; 460d930f514SMatthew G. Knepley PetscInt n, nroots; 461d930f514SMatthew G. Knepley 462ca43db0aSBarry Smith ierr = VecGetLocalSize(originalv, &n);CHKERRQ(ierr); 463d930f514SMatthew G. Knepley ierr = PetscSFGetGraph(dm->sfNatural, &nroots, NULL, NULL, NULL);CHKERRQ(ierr); 464d930f514SMatthew G. Knepley if (n == nroots) { 465d930f514SMatthew G. Knepley ierr = DMGetGlobalVector(dm, &v);CHKERRQ(ierr); 466d930f514SMatthew G. Knepley ierr = DMPlexGlobalToNaturalBegin(dm, originalv, v);CHKERRQ(ierr); 467d930f514SMatthew G. Knepley ierr = DMPlexGlobalToNaturalEnd(dm, originalv, v);CHKERRQ(ierr); 468d930f514SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) originalv, &vecname);CHKERRQ(ierr); 469d930f514SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) v, vecname);CHKERRQ(ierr); 470d930f514SMatthew G. Knepley } else SETERRQ(comm, PETSC_ERR_ARG_WRONG, "DM global to natural SF only handles global vectors"); 471d930f514SMatthew G. Knepley } else SETERRQ(comm, PETSC_ERR_ARG_WRONGSTATE, "DM global to natural SF was not created"); 472a8ad634aSStefano Zampini } else v = originalv; 473a8ad634aSStefano Zampini } else v = originalv; 474a8ad634aSStefano Zampini 475d930f514SMatthew G. Knepley if (ishdf5) { 476d930f514SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 47739d25373SMatthew G. Knepley ierr = VecView_Plex_HDF5_Native_Internal(v, viewer);CHKERRQ(ierr); 478d930f514SMatthew G. Knepley #else 479d930f514SMatthew G. Knepley SETERRQ(comm, PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 480d930f514SMatthew G. Knepley #endif 481d930f514SMatthew G. Knepley } else if (isvtk) { 482d930f514SMatthew G. Knepley SETERRQ(comm, PETSC_ERR_SUP, "VTK format does not support viewing in natural order. Please switch to HDF5."); 483d930f514SMatthew G. Knepley } else { 484d930f514SMatthew G. Knepley PetscBool isseq; 485d930f514SMatthew G. Knepley 486d930f514SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) v, VECSEQ, &isseq);CHKERRQ(ierr); 487d930f514SMatthew G. Knepley if (isseq) {ierr = VecView_Seq(v, viewer);CHKERRQ(ierr);} 488d930f514SMatthew G. Knepley else {ierr = VecView_MPI(v, viewer);CHKERRQ(ierr);} 489d930f514SMatthew G. Knepley } 490a8ad634aSStefano Zampini if (v != originalv) {ierr = DMRestoreGlobalVector(dm, &v);CHKERRQ(ierr);} 491d930f514SMatthew G. Knepley PetscFunctionReturn(0); 492d930f514SMatthew G. Knepley } 493d930f514SMatthew G. Knepley 4942c40f234SMatthew G. Knepley PetscErrorCode VecLoad_Plex_Local(Vec v, PetscViewer viewer) 4952c40f234SMatthew G. Knepley { 4962c40f234SMatthew G. Knepley DM dm; 4972c40f234SMatthew G. Knepley PetscBool ishdf5; 4982c40f234SMatthew G. Knepley PetscErrorCode ierr; 4992c40f234SMatthew G. Knepley 5002c40f234SMatthew G. Knepley PetscFunctionBegin; 5012c40f234SMatthew G. Knepley ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 5022c40f234SMatthew G. Knepley if (!dm) SETERRQ(PetscObjectComm((PetscObject)v), PETSC_ERR_ARG_WRONG, "Vector not generated from a DM"); 5032c40f234SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 5042c40f234SMatthew G. Knepley if (ishdf5) { 5052c40f234SMatthew G. Knepley DM dmBC; 5062c40f234SMatthew G. Knepley Vec gv; 5072c40f234SMatthew G. Knepley const char *name; 5082c40f234SMatthew G. Knepley 5092c40f234SMatthew G. Knepley ierr = DMGetOutputDM(dm, &dmBC);CHKERRQ(ierr); 5102c40f234SMatthew G. Knepley ierr = DMGetGlobalVector(dmBC, &gv);CHKERRQ(ierr); 5112c40f234SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) v, &name);CHKERRQ(ierr); 5122c40f234SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) gv, name);CHKERRQ(ierr); 5132c40f234SMatthew G. Knepley ierr = VecLoad_Default(gv, viewer);CHKERRQ(ierr); 5142c40f234SMatthew G. Knepley ierr = DMGlobalToLocalBegin(dmBC, gv, INSERT_VALUES, v);CHKERRQ(ierr); 5152c40f234SMatthew G. Knepley ierr = DMGlobalToLocalEnd(dmBC, gv, INSERT_VALUES, v);CHKERRQ(ierr); 5162c40f234SMatthew G. Knepley ierr = DMRestoreGlobalVector(dmBC, &gv);CHKERRQ(ierr); 5172c40f234SMatthew G. Knepley } else { 5182c40f234SMatthew G. Knepley ierr = VecLoad_Default(v, viewer);CHKERRQ(ierr); 5192c40f234SMatthew G. Knepley } 5202c40f234SMatthew G. Knepley PetscFunctionReturn(0); 5212c40f234SMatthew G. Knepley } 5222c40f234SMatthew G. Knepley 5232c40f234SMatthew G. Knepley PetscErrorCode VecLoad_Plex(Vec v, PetscViewer viewer) 5242c40f234SMatthew G. Knepley { 5252c40f234SMatthew G. Knepley DM dm; 5266823f3c5SBlaise Bourdin PetscBool ishdf5,isexodusii; 5272c40f234SMatthew G. Knepley PetscErrorCode ierr; 5282c40f234SMatthew G. Knepley 5292c40f234SMatthew G. Knepley PetscFunctionBegin; 5302c40f234SMatthew G. Knepley ierr = VecGetDM(v, &dm);CHKERRQ(ierr); 5312c40f234SMatthew G. Knepley if (!dm) SETERRQ(PetscObjectComm((PetscObject)v), PETSC_ERR_ARG_WRONG, "Vector not generated from a DM"); 5322c40f234SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 5336823f3c5SBlaise Bourdin ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWEREXODUSII, &isexodusii);CHKERRQ(ierr); 5342c40f234SMatthew G. Knepley if (ishdf5) { 535878b459fSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 53639d25373SMatthew G. Knepley ierr = VecLoad_Plex_HDF5_Internal(v, viewer);CHKERRQ(ierr); 537b136c2c9SMatthew G. Knepley #else 538b136c2c9SMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 539878b459fSMatthew G. Knepley #endif 5406823f3c5SBlaise Bourdin } else if (isexodusii) { 5416823f3c5SBlaise Bourdin #if defined(PETSC_HAVE_EXODUSII) 5426823f3c5SBlaise Bourdin ierr = VecLoad_PlexExodusII_Internal(v, viewer);CHKERRQ(ierr); 5436823f3c5SBlaise Bourdin #else 5446823f3c5SBlaise Bourdin SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "ExodusII not supported in this build.\nPlease reconfigure using --download-exodusii"); 5456823f3c5SBlaise Bourdin #endif 5462c40f234SMatthew G. Knepley } else { 5472c40f234SMatthew G. Knepley ierr = VecLoad_Default(v, viewer);CHKERRQ(ierr); 548552f7358SJed Brown } 549552f7358SJed Brown PetscFunctionReturn(0); 550552f7358SJed Brown } 551552f7358SJed Brown 552d930f514SMatthew G. Knepley PetscErrorCode VecLoad_Plex_Native(Vec originalv, PetscViewer viewer) 553d930f514SMatthew G. Knepley { 554d930f514SMatthew G. Knepley DM dm; 555d930f514SMatthew G. Knepley PetscViewerFormat format; 556d930f514SMatthew G. Knepley PetscBool ishdf5; 557d930f514SMatthew G. Knepley PetscErrorCode ierr; 558d930f514SMatthew G. Knepley 559d930f514SMatthew G. Knepley PetscFunctionBegin; 560d930f514SMatthew G. Knepley ierr = VecGetDM(originalv, &dm);CHKERRQ(ierr); 561d930f514SMatthew G. Knepley if (!dm) SETERRQ(PetscObjectComm((PetscObject) originalv), PETSC_ERR_ARG_WRONG, "Vector not generated from a DM"); 562d930f514SMatthew G. Knepley ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 563d930f514SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 564d930f514SMatthew G. Knepley if (format == PETSC_VIEWER_NATIVE) { 565a8ad634aSStefano Zampini if (dm->useNatural) { 566d930f514SMatthew G. Knepley if (dm->sfNatural) { 567d930f514SMatthew G. Knepley if (ishdf5) { 568d930f514SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 569d930f514SMatthew G. Knepley Vec v; 570d930f514SMatthew G. Knepley const char *vecname; 571d930f514SMatthew G. Knepley 572d930f514SMatthew G. Knepley ierr = DMGetGlobalVector(dm, &v);CHKERRQ(ierr); 573d930f514SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) originalv, &vecname);CHKERRQ(ierr); 574d930f514SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) v, vecname);CHKERRQ(ierr); 57539d25373SMatthew G. Knepley ierr = VecLoad_Plex_HDF5_Native_Internal(v, viewer);CHKERRQ(ierr); 576d930f514SMatthew G. Knepley ierr = DMPlexNaturalToGlobalBegin(dm, v, originalv);CHKERRQ(ierr); 577d930f514SMatthew G. Knepley ierr = DMPlexNaturalToGlobalEnd(dm, v, originalv);CHKERRQ(ierr); 578d930f514SMatthew G. Knepley ierr = DMRestoreGlobalVector(dm, &v);CHKERRQ(ierr); 579d930f514SMatthew G. Knepley #else 580d930f514SMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 581d930f514SMatthew G. Knepley #endif 582d930f514SMatthew G. Knepley } else SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Reading in natural order is not supported for anything but HDF5."); 583d930f514SMatthew G. Knepley } 584a8ad634aSStefano Zampini } else { 585a8ad634aSStefano Zampini ierr = VecLoad_Default(originalv, viewer);CHKERRQ(ierr); 586a8ad634aSStefano Zampini } 587d930f514SMatthew G. Knepley } 588d930f514SMatthew G. Knepley PetscFunctionReturn(0); 589d930f514SMatthew G. Knepley } 590d930f514SMatthew G. Knepley 5917cd05799SMatthew G. Knepley PETSC_UNUSED static PetscErrorCode DMPlexView_Ascii_Geometry(DM dm, PetscViewer viewer) 592731e8ddeSMatthew G. Knepley { 593731e8ddeSMatthew G. Knepley PetscSection coordSection; 594731e8ddeSMatthew G. Knepley Vec coordinates; 595ba2698f1SMatthew G. Knepley DMLabel depthLabel, celltypeLabel; 596731e8ddeSMatthew G. Knepley const char *name[4]; 597731e8ddeSMatthew G. Knepley const PetscScalar *a; 598731e8ddeSMatthew G. Knepley PetscInt dim, pStart, pEnd, cStart, cEnd, c; 599731e8ddeSMatthew G. Knepley PetscErrorCode ierr; 600731e8ddeSMatthew G. Knepley 601731e8ddeSMatthew G. Knepley PetscFunctionBegin; 602731e8ddeSMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 603731e8ddeSMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 604731e8ddeSMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 605731e8ddeSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &depthLabel);CHKERRQ(ierr); 606ba2698f1SMatthew G. Knepley ierr = DMPlexGetCellTypeLabel(dm, &celltypeLabel);CHKERRQ(ierr); 607731e8ddeSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 608731e8ddeSMatthew G. Knepley ierr = PetscSectionGetChart(coordSection, &pStart, &pEnd);CHKERRQ(ierr); 609731e8ddeSMatthew G. Knepley ierr = VecGetArrayRead(coordinates, &a);CHKERRQ(ierr); 610731e8ddeSMatthew G. Knepley name[0] = "vertex"; 611731e8ddeSMatthew G. Knepley name[1] = "edge"; 612731e8ddeSMatthew G. Knepley name[dim-1] = "face"; 613731e8ddeSMatthew G. Knepley name[dim] = "cell"; 614731e8ddeSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 615731e8ddeSMatthew G. Knepley PetscInt *closure = NULL; 616ba2698f1SMatthew G. Knepley PetscInt closureSize, cl, ct; 617731e8ddeSMatthew G. Knepley 618ba2698f1SMatthew G. Knepley ierr = DMLabelGetValue(celltypeLabel, c, &ct);CHKERRQ(ierr); 619ba2698f1SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "Geometry for cell %D polytope type %s:\n", c, DMPolytopeTypes[ct]);CHKERRQ(ierr); 620731e8ddeSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 621731e8ddeSMatthew G. Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 622731e8ddeSMatthew G. Knepley for (cl = 0; cl < closureSize*2; cl += 2) { 623731e8ddeSMatthew G. Knepley PetscInt point = closure[cl], depth, dof, off, d, p; 624731e8ddeSMatthew G. Knepley 625731e8ddeSMatthew G. Knepley if ((point < pStart) || (point >= pEnd)) continue; 626731e8ddeSMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, point, &dof);CHKERRQ(ierr); 627731e8ddeSMatthew G. Knepley if (!dof) continue; 628731e8ddeSMatthew G. Knepley ierr = DMLabelGetValue(depthLabel, point, &depth);CHKERRQ(ierr); 629731e8ddeSMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, point, &off);CHKERRQ(ierr); 630f347f43bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer, "%s %D coords:", name[depth], point);CHKERRQ(ierr); 631731e8ddeSMatthew G. Knepley for (p = 0; p < dof/dim; ++p) { 632731e8ddeSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " (");CHKERRQ(ierr); 633731e8ddeSMatthew G. Knepley for (d = 0; d < dim; ++d) { 634731e8ddeSMatthew G. Knepley if (d > 0) {ierr = PetscViewerASCIIPrintf(viewer, ", ");CHKERRQ(ierr);} 635087ef6b2SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "%g", (double) PetscRealPart(a[off+p*dim+d]));CHKERRQ(ierr); 636731e8ddeSMatthew G. Knepley } 637731e8ddeSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, ")");CHKERRQ(ierr); 638731e8ddeSMatthew G. Knepley } 639731e8ddeSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "\n");CHKERRQ(ierr); 640731e8ddeSMatthew G. Knepley } 641731e8ddeSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 642731e8ddeSMatthew G. Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 643731e8ddeSMatthew G. Knepley } 644731e8ddeSMatthew G. Knepley ierr = VecRestoreArrayRead(coordinates, &a);CHKERRQ(ierr); 645731e8ddeSMatthew G. Knepley PetscFunctionReturn(0); 646731e8ddeSMatthew G. Knepley } 647731e8ddeSMatthew G. Knepley 6487cd05799SMatthew G. Knepley static PetscErrorCode DMPlexView_Ascii(DM dm, PetscViewer viewer) 649552f7358SJed Brown { 650552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 651552f7358SJed Brown DM cdm; 652552f7358SJed Brown PetscSection coordSection; 653552f7358SJed Brown Vec coordinates; 654552f7358SJed Brown PetscViewerFormat format; 655552f7358SJed Brown PetscErrorCode ierr; 656552f7358SJed Brown 657552f7358SJed Brown PetscFunctionBegin; 658552f7358SJed Brown ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 65992fd8e1eSJed Brown ierr = DMGetLocalSection(cdm, &coordSection);CHKERRQ(ierr); 660552f7358SJed Brown ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 661552f7358SJed Brown ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 662552f7358SJed Brown if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 663552f7358SJed Brown const char *name; 664f73eea6eSMatthew G. Knepley PetscInt dim, cellHeight, maxConeSize, maxSupportSize; 6659318fe57SMatthew G. Knepley PetscInt pStart, pEnd, p, numLabels, l; 666552f7358SJed Brown PetscMPIInt rank, size; 667552f7358SJed Brown 668ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank);CHKERRMPI(ierr); 669ffc4695bSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)dm), &size);CHKERRMPI(ierr); 670552f7358SJed Brown ierr = PetscObjectGetName((PetscObject) dm, &name);CHKERRQ(ierr); 671552f7358SJed Brown ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 672552f7358SJed Brown ierr = DMPlexGetMaxSizes(dm, &maxConeSize, &maxSupportSize);CHKERRQ(ierr); 673f73eea6eSMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 674f73eea6eSMatthew G. Knepley ierr = DMPlexGetVTKCellHeight(dm, &cellHeight);CHKERRQ(ierr); 675f73eea6eSMatthew G. Knepley if (name) {ierr = PetscViewerASCIIPrintf(viewer, "%s in %D dimension%s:\n", name, dim, dim == 1 ? "" : "s");CHKERRQ(ierr);} 676f73eea6eSMatthew G. Knepley else {ierr = PetscViewerASCIIPrintf(viewer, "Mesh in %D dimension%s:\n", dim, dim == 1 ? "" : "s");CHKERRQ(ierr);} 677f73eea6eSMatthew G. Knepley if (cellHeight) {ierr = PetscViewerASCIIPrintf(viewer, " Cells are at height %D\n", cellHeight);CHKERRQ(ierr);} 678e9cb465cSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "Supports:\n", name);CHKERRQ(ierr); 6794d4c343aSBarry Smith ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 680e9cb465cSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "[%d] Max support size: %D\n", rank, maxSupportSize);CHKERRQ(ierr); 681552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 682552f7358SJed Brown PetscInt dof, off, s; 683552f7358SJed Brown 684552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, &dof);CHKERRQ(ierr); 685552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, p, &off);CHKERRQ(ierr); 686552f7358SJed Brown for (s = off; s < off+dof; ++s) { 687e4b003c7SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer, "[%d]: %D ----> %D\n", rank, p, mesh->supports[s]);CHKERRQ(ierr); 688552f7358SJed Brown } 689552f7358SJed Brown } 690552f7358SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 691e9cb465cSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "Cones:\n", name);CHKERRQ(ierr); 692e9cb465cSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "[%d] Max cone size: %D\n", rank, maxConeSize);CHKERRQ(ierr); 693552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 694552f7358SJed Brown PetscInt dof, off, c; 695552f7358SJed Brown 696552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 697552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 698552f7358SJed Brown for (c = off; c < off+dof; ++c) { 699e4b003c7SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer, "[%d]: %D <---- %D (%D)\n", rank, p, mesh->cones[c], mesh->coneOrientations[c]);CHKERRQ(ierr); 700552f7358SJed Brown } 701552f7358SJed Brown } 702552f7358SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 7034d4c343aSBarry Smith ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); 7043d2e540fSStefano Zampini if (coordSection && coordinates) { 70580180ce3SStefano Zampini ierr = PetscSectionVecView(coordSection, coordinates, viewer);CHKERRQ(ierr); 7063d2e540fSStefano Zampini } 7079318fe57SMatthew G. Knepley ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 7089318fe57SMatthew G. Knepley if (numLabels) {ierr = PetscViewerASCIIPrintf(viewer, "Labels:\n");CHKERRQ(ierr);} 7099318fe57SMatthew G. Knepley for (l = 0; l < numLabels; ++l) { 7109318fe57SMatthew G. Knepley DMLabel label; 7119318fe57SMatthew G. Knepley PetscBool isdepth; 7129318fe57SMatthew G. Knepley const char *name; 7139318fe57SMatthew G. Knepley 7149318fe57SMatthew G. Knepley ierr = DMGetLabelName(dm, l, &name);CHKERRQ(ierr); 7159318fe57SMatthew G. Knepley ierr = PetscStrcmp(name, "depth", &isdepth);CHKERRQ(ierr); 7169318fe57SMatthew G. Knepley if (isdepth) continue; 7179318fe57SMatthew G. Knepley ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 7189318fe57SMatthew G. Knepley ierr = DMLabelView(label, viewer);CHKERRQ(ierr); 7199318fe57SMatthew G. Knepley } 720552f7358SJed Brown if (size > 1) { 721552f7358SJed Brown PetscSF sf; 722552f7358SJed Brown 723552f7358SJed Brown ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 724552f7358SJed Brown ierr = PetscSFView(sf, viewer);CHKERRQ(ierr); 725552f7358SJed Brown } 726552f7358SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 727552f7358SJed Brown } else if (format == PETSC_VIEWER_ASCII_LATEX) { 7280588280cSMatthew G. Knepley const char *name, *color; 7290588280cSMatthew G. Knepley const char *defcolors[3] = {"gray", "orange", "green"}; 7300588280cSMatthew G. Knepley const char *deflcolors[4] = {"blue", "cyan", "red", "magenta"}; 731fe1cc32dSStefano Zampini char lname[PETSC_MAX_PATH_LEN]; 732552f7358SJed Brown PetscReal scale = 2.0; 73378081901SStefano Zampini PetscReal tikzscale = 1.0; 7340588280cSMatthew G. Knepley PetscBool useNumbers = PETSC_TRUE, useLabels, useColors; 7350588280cSMatthew G. Knepley double tcoords[3]; 736552f7358SJed Brown PetscScalar *coords; 7370588280cSMatthew G. Knepley PetscInt numLabels, l, numColors, numLColors, dim, depth, cStart, cEnd, c, vStart, vEnd, v, eStart = 0, eEnd = 0, e, p; 738552f7358SJed Brown PetscMPIInt rank, size; 7390588280cSMatthew G. Knepley char **names, **colors, **lcolors; 740fe1cc32dSStefano Zampini PetscBool plotEdges, flg, lflg; 741fe1cc32dSStefano Zampini PetscBT wp = NULL; 742fe1cc32dSStefano Zampini PetscInt pEnd, pStart; 743552f7358SJed Brown 7440588280cSMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 745552f7358SJed Brown ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 746c58f1c22SToby Isaac ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 7470588280cSMatthew G. Knepley numLabels = PetscMax(numLabels, 10); 7480588280cSMatthew G. Knepley numColors = 10; 7490588280cSMatthew G. Knepley numLColors = 10; 7500588280cSMatthew G. Knepley ierr = PetscCalloc3(numLabels, &names, numColors, &colors, numLColors, &lcolors);CHKERRQ(ierr); 751c5929fdfSBarry Smith ierr = PetscOptionsGetReal(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_scale", &scale, NULL);CHKERRQ(ierr); 75278081901SStefano Zampini ierr = PetscOptionsGetReal(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_tikzscale", &tikzscale, NULL);CHKERRQ(ierr); 753c5929fdfSBarry Smith ierr = PetscOptionsGetBool(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_numbers", &useNumbers, NULL);CHKERRQ(ierr); 754c5929fdfSBarry Smith ierr = PetscOptionsGetStringArray(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_labels", names, &numLabels, &useLabels);CHKERRQ(ierr); 7550588280cSMatthew G. Knepley if (!useLabels) numLabels = 0; 756c5929fdfSBarry Smith ierr = PetscOptionsGetStringArray(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_colors", colors, &numColors, &useColors);CHKERRQ(ierr); 7570588280cSMatthew G. Knepley if (!useColors) { 7580588280cSMatthew G. Knepley numColors = 3; 7590588280cSMatthew G. Knepley for (c = 0; c < numColors; ++c) {ierr = PetscStrallocpy(defcolors[c], &colors[c]);CHKERRQ(ierr);} 7600588280cSMatthew G. Knepley } 761c5929fdfSBarry Smith ierr = PetscOptionsGetStringArray(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_lcolors", lcolors, &numLColors, &useColors);CHKERRQ(ierr); 7620588280cSMatthew G. Knepley if (!useColors) { 7630588280cSMatthew G. Knepley numLColors = 4; 7640588280cSMatthew G. Knepley for (c = 0; c < numLColors; ++c) {ierr = PetscStrallocpy(deflcolors[c], &lcolors[c]);CHKERRQ(ierr);} 7650588280cSMatthew G. Knepley } 766589a23caSBarry Smith ierr = PetscOptionsGetString(((PetscObject) viewer)->options, ((PetscObject) viewer)->prefix, "-dm_plex_view_label_filter", lname, sizeof(lname), &lflg);CHKERRQ(ierr); 767202fd40aSStefano Zampini plotEdges = (PetscBool)(depth > 1 && useNumbers && dim < 3); 768202fd40aSStefano Zampini ierr = PetscOptionsGetBool(((PetscObject) viewer)->options,((PetscObject) viewer)->prefix, "-dm_plex_view_edges", &plotEdges, &flg);CHKERRQ(ierr); 769202fd40aSStefano Zampini if (flg && plotEdges && depth < dim) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Mesh must be interpolated"); 770202fd40aSStefano Zampini if (depth < dim) plotEdges = PETSC_FALSE; 771fe1cc32dSStefano Zampini 772fe1cc32dSStefano Zampini /* filter points with labelvalue != labeldefaultvalue */ 773fe1cc32dSStefano Zampini ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 774fe1cc32dSStefano Zampini if (lflg) { 775fe1cc32dSStefano Zampini DMLabel lbl; 776fe1cc32dSStefano Zampini 777fe1cc32dSStefano Zampini ierr = DMGetLabel(dm, lname, &lbl);CHKERRQ(ierr); 778fe1cc32dSStefano Zampini if (lbl) { 779fe1cc32dSStefano Zampini PetscInt val, defval; 780fe1cc32dSStefano Zampini 781fe1cc32dSStefano Zampini ierr = DMLabelGetDefaultValue(lbl, &defval);CHKERRQ(ierr); 782fe1cc32dSStefano Zampini ierr = PetscBTCreate(pEnd-pStart, &wp);CHKERRQ(ierr); 783fe1cc32dSStefano Zampini for (c = pStart; c < pEnd; c++) { 784fe1cc32dSStefano Zampini PetscInt *closure = NULL; 785fe1cc32dSStefano Zampini PetscInt closureSize; 786fe1cc32dSStefano Zampini 787fe1cc32dSStefano Zampini ierr = DMLabelGetValue(lbl, c, &val);CHKERRQ(ierr); 788fe1cc32dSStefano Zampini if (val == defval) continue; 789fe1cc32dSStefano Zampini 790fe1cc32dSStefano Zampini ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 791fe1cc32dSStefano Zampini for (p = 0; p < closureSize*2; p += 2) { 792fe1cc32dSStefano Zampini ierr = PetscBTSet(wp, closure[p] - pStart);CHKERRQ(ierr); 793fe1cc32dSStefano Zampini } 794fe1cc32dSStefano Zampini ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 795fe1cc32dSStefano Zampini } 796fe1cc32dSStefano Zampini } 797fe1cc32dSStefano Zampini } 798fe1cc32dSStefano Zampini 799ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank);CHKERRMPI(ierr); 800ffc4695bSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)dm), &size);CHKERRMPI(ierr); 801552f7358SJed Brown ierr = PetscObjectGetName((PetscObject) dm, &name);CHKERRQ(ierr); 802770b213bSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, "\ 8030588280cSMatthew G. Knepley \\documentclass[tikz]{standalone}\n\n\ 804552f7358SJed Brown \\usepackage{pgflibraryshapes}\n\ 805552f7358SJed Brown \\usetikzlibrary{backgrounds}\n\ 806552f7358SJed Brown \\usetikzlibrary{arrows}\n\ 8070588280cSMatthew G. Knepley \\begin{document}\n");CHKERRQ(ierr); 8080588280cSMatthew G. Knepley if (size > 1) { 809f738dd31SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "%s for process ", name);CHKERRQ(ierr); 810770b213bSMatthew G Knepley for (p = 0; p < size; ++p) { 811770b213bSMatthew G Knepley if (p > 0 && p == size-1) { 812770b213bSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, ", and ", colors[p%numColors], p);CHKERRQ(ierr); 813770b213bSMatthew G Knepley } else if (p > 0) { 814770b213bSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, ", ", colors[p%numColors], p);CHKERRQ(ierr); 815770b213bSMatthew G Knepley } 816770b213bSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, "{\\textcolor{%s}%D}", colors[p%numColors], p);CHKERRQ(ierr); 817770b213bSMatthew G Knepley } 8180588280cSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, ".\n\n\n");CHKERRQ(ierr); 8190588280cSMatthew G. Knepley } 820087ef6b2SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "\\begin{tikzpicture}[scale = %g,font=\\fontsize{8}{8}\\selectfont]\n", (double) tikzscale);CHKERRQ(ierr); 821fe1cc32dSStefano Zampini 822552f7358SJed Brown /* Plot vertices */ 823552f7358SJed Brown ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 824552f7358SJed Brown ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 8254d4c343aSBarry Smith ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 826552f7358SJed Brown for (v = vStart; v < vEnd; ++v) { 827552f7358SJed Brown PetscInt off, dof, d; 8280588280cSMatthew G. Knepley PetscBool isLabeled = PETSC_FALSE; 829552f7358SJed Brown 830fe1cc32dSStefano Zampini if (wp && !PetscBTLookup(wp,v - pStart)) continue; 831552f7358SJed Brown ierr = PetscSectionGetDof(coordSection, v, &dof);CHKERRQ(ierr); 832552f7358SJed Brown ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 8330588280cSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "\\path (");CHKERRQ(ierr); 834f6dae198SJed Brown if (PetscUnlikely(dof > 3)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"coordSection vertex %D has dof %D > 3",v,dof); 8350588280cSMatthew G. Knepley for (d = 0; d < dof; ++d) { 8360588280cSMatthew G. Knepley tcoords[d] = (double) (scale*PetscRealPart(coords[off+d])); 837c068d9bbSLisandro Dalcin tcoords[d] = PetscAbs(tcoords[d]) < 1e-10 ? 0.0 : tcoords[d]; 8380588280cSMatthew G. Knepley } 8390588280cSMatthew G. Knepley /* Rotate coordinates since PGF makes z point out of the page instead of up */ 8400588280cSMatthew G. Knepley if (dim == 3) {PetscReal tmp = tcoords[1]; tcoords[1] = tcoords[2]; tcoords[2] = -tmp;} 841552f7358SJed Brown for (d = 0; d < dof; ++d) { 842552f7358SJed Brown if (d > 0) {ierr = PetscViewerASCIISynchronizedPrintf(viewer, ",");CHKERRQ(ierr);} 843087ef6b2SMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "%g", (double) tcoords[d]);CHKERRQ(ierr); 844552f7358SJed Brown } 8450588280cSMatthew G. Knepley color = colors[rank%numColors]; 8460588280cSMatthew G. Knepley for (l = 0; l < numLabels; ++l) { 8470588280cSMatthew G. Knepley PetscInt val; 848c58f1c22SToby Isaac ierr = DMGetLabelValue(dm, names[l], v, &val);CHKERRQ(ierr); 8490588280cSMatthew G. Knepley if (val >= 0) {color = lcolors[l%numLColors]; isLabeled = PETSC_TRUE; break;} 8500588280cSMatthew G. Knepley } 8510588280cSMatthew G. Knepley if (useNumbers) { 852e4b003c7SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer, ") node(%D_%d) [draw,shape=circle,color=%s] {%D};\n", v, rank, color, v);CHKERRQ(ierr); 8530588280cSMatthew G. Knepley } else { 854e4b003c7SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer, ") node(%D_%d) [fill,inner sep=%dpt,shape=circle,color=%s] {};\n", v, rank, !isLabeled ? 1 : 2, color);CHKERRQ(ierr); 8550588280cSMatthew G. Knepley } 856552f7358SJed Brown } 857552f7358SJed Brown ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 858552f7358SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 859846a3e8bSMatthew G. Knepley /* Plot cells */ 860846a3e8bSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 86178081901SStefano Zampini ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 862846a3e8bSMatthew G. Knepley if (dim == 3 || !useNumbers) { 863846a3e8bSMatthew G. Knepley for (e = eStart; e < eEnd; ++e) { 864846a3e8bSMatthew G. Knepley const PetscInt *cone; 865846a3e8bSMatthew G. Knepley 866fe1cc32dSStefano Zampini if (wp && !PetscBTLookup(wp,e - pStart)) continue; 867846a3e8bSMatthew G. Knepley color = colors[rank%numColors]; 868846a3e8bSMatthew G. Knepley for (l = 0; l < numLabels; ++l) { 869846a3e8bSMatthew G. Knepley PetscInt val; 870846a3e8bSMatthew G. Knepley ierr = DMGetLabelValue(dm, names[l], e, &val);CHKERRQ(ierr); 871846a3e8bSMatthew G. Knepley if (val >= 0) {color = lcolors[l%numLColors]; break;} 872846a3e8bSMatthew G. Knepley } 873846a3e8bSMatthew G. Knepley ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 874846a3e8bSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "\\draw[color=%s] (%D_%d) -- (%D_%d);\n", color, cone[0], rank, cone[1], rank);CHKERRQ(ierr); 875846a3e8bSMatthew G. Knepley } 876846a3e8bSMatthew G. Knepley } else { 877846a3e8bSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 878846a3e8bSMatthew G. Knepley PetscInt *closure = NULL; 879846a3e8bSMatthew G. Knepley PetscInt closureSize, firstPoint = -1; 880846a3e8bSMatthew G. Knepley 881fe1cc32dSStefano Zampini if (wp && !PetscBTLookup(wp,c - pStart)) continue; 882846a3e8bSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 883846a3e8bSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "\\draw[color=%s] ", colors[rank%numColors]);CHKERRQ(ierr); 884846a3e8bSMatthew G. Knepley for (p = 0; p < closureSize*2; p += 2) { 885846a3e8bSMatthew G. Knepley const PetscInt point = closure[p]; 886846a3e8bSMatthew G. Knepley 887846a3e8bSMatthew G. Knepley if ((point < vStart) || (point >= vEnd)) continue; 888846a3e8bSMatthew G. Knepley if (firstPoint >= 0) {ierr = PetscViewerASCIISynchronizedPrintf(viewer, " -- ");CHKERRQ(ierr);} 889846a3e8bSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "(%D_%d)", point, rank);CHKERRQ(ierr); 890846a3e8bSMatthew G. Knepley if (firstPoint < 0) firstPoint = point; 891846a3e8bSMatthew G. Knepley } 892846a3e8bSMatthew G. Knepley /* Why doesn't this work? ierr = PetscViewerASCIISynchronizedPrintf(viewer, " -- cycle;\n");CHKERRQ(ierr); */ 893846a3e8bSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, " -- (%D_%d);\n", firstPoint, rank);CHKERRQ(ierr); 894846a3e8bSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 895846a3e8bSMatthew G. Knepley } 896846a3e8bSMatthew G. Knepley } 897846a3e8bSMatthew G. Knepley ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 898846a3e8bSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 899846a3e8bSMatthew G. Knepley double ccoords[3] = {0.0, 0.0, 0.0}; 900846a3e8bSMatthew G. Knepley PetscBool isLabeled = PETSC_FALSE; 901846a3e8bSMatthew G. Knepley PetscInt *closure = NULL; 902846a3e8bSMatthew G. Knepley PetscInt closureSize, dof, d, n = 0; 903846a3e8bSMatthew G. Knepley 904fe1cc32dSStefano Zampini if (wp && !PetscBTLookup(wp,c - pStart)) continue; 905846a3e8bSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 906846a3e8bSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "\\path (");CHKERRQ(ierr); 907846a3e8bSMatthew G. Knepley for (p = 0; p < closureSize*2; p += 2) { 908846a3e8bSMatthew G. Knepley const PetscInt point = closure[p]; 909846a3e8bSMatthew G. Knepley PetscInt off; 910846a3e8bSMatthew G. Knepley 911846a3e8bSMatthew G. Knepley if ((point < vStart) || (point >= vEnd)) continue; 912846a3e8bSMatthew G. Knepley ierr = PetscSectionGetDof(coordSection, point, &dof);CHKERRQ(ierr); 913846a3e8bSMatthew G. Knepley ierr = PetscSectionGetOffset(coordSection, point, &off);CHKERRQ(ierr); 914846a3e8bSMatthew G. Knepley for (d = 0; d < dof; ++d) { 915846a3e8bSMatthew G. Knepley tcoords[d] = (double) (scale*PetscRealPart(coords[off+d])); 916846a3e8bSMatthew G. Knepley tcoords[d] = PetscAbs(tcoords[d]) < 1e-10 ? 0.0 : tcoords[d]; 917846a3e8bSMatthew G. Knepley } 918846a3e8bSMatthew G. Knepley /* Rotate coordinates since PGF makes z point out of the page instead of up */ 919846a3e8bSMatthew G. Knepley if (dof == 3) {PetscReal tmp = tcoords[1]; tcoords[1] = tcoords[2]; tcoords[2] = -tmp;} 920846a3e8bSMatthew G. Knepley for (d = 0; d < dof; ++d) {ccoords[d] += tcoords[d];} 921846a3e8bSMatthew G. Knepley ++n; 922846a3e8bSMatthew G. Knepley } 923846a3e8bSMatthew G. Knepley for (d = 0; d < dof; ++d) {ccoords[d] /= n;} 924846a3e8bSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 925846a3e8bSMatthew G. Knepley for (d = 0; d < dof; ++d) { 926846a3e8bSMatthew G. Knepley if (d > 0) {ierr = PetscViewerASCIISynchronizedPrintf(viewer, ",");CHKERRQ(ierr);} 927087ef6b2SMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, "%g", (double) ccoords[d]);CHKERRQ(ierr); 928846a3e8bSMatthew G. Knepley } 929846a3e8bSMatthew G. Knepley color = colors[rank%numColors]; 930846a3e8bSMatthew G. Knepley for (l = 0; l < numLabels; ++l) { 931846a3e8bSMatthew G. Knepley PetscInt val; 932846a3e8bSMatthew G. Knepley ierr = DMGetLabelValue(dm, names[l], c, &val);CHKERRQ(ierr); 933846a3e8bSMatthew G. Knepley if (val >= 0) {color = lcolors[l%numLColors]; isLabeled = PETSC_TRUE; break;} 934846a3e8bSMatthew G. Knepley } 935846a3e8bSMatthew G. Knepley if (useNumbers) { 936846a3e8bSMatthew G. Knepley ierr = PetscViewerASCIISynchronizedPrintf(viewer, ") node(%D_%d) [draw,shape=circle,color=%s] {%D};\n", c, rank, color, c);CHKERRQ(ierr); 937846a3e8bSMatthew G. Knepley } else { 938846a3e8bSMatthew 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); 939846a3e8bSMatthew G. Knepley } 940846a3e8bSMatthew G. Knepley } 941846a3e8bSMatthew G. Knepley ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 942552f7358SJed Brown /* Plot edges */ 943202fd40aSStefano Zampini if (plotEdges) { 944552f7358SJed Brown ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 945552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, "\\path\n");CHKERRQ(ierr); 946552f7358SJed Brown for (e = eStart; e < eEnd; ++e) { 947552f7358SJed Brown const PetscInt *cone; 948552f7358SJed Brown PetscInt coneSize, offA, offB, dof, d; 949552f7358SJed Brown 950fe1cc32dSStefano Zampini if (wp && !PetscBTLookup(wp,e - pStart)) continue; 951552f7358SJed Brown ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr); 952f347f43bSBarry Smith if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %D cone should have two vertices, not %D", e, coneSize); 953552f7358SJed Brown ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 954552f7358SJed Brown ierr = PetscSectionGetDof(coordSection, cone[0], &dof);CHKERRQ(ierr); 955552f7358SJed Brown ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr); 956552f7358SJed Brown ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr); 957552f7358SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer, "(");CHKERRQ(ierr); 958552f7358SJed Brown for (d = 0; d < dof; ++d) { 959202fd40aSStefano Zampini tcoords[d] = (double) (0.5*scale*PetscRealPart(coords[offA+d]+coords[offB+d])); 960c068d9bbSLisandro Dalcin tcoords[d] = PetscAbs(tcoords[d]) < 1e-10 ? 0.0 : tcoords[d]; 961552f7358SJed Brown } 9620588280cSMatthew G. Knepley /* Rotate coordinates since PGF makes z point out of the page instead of up */ 9630588280cSMatthew G. Knepley if (dim == 3) {PetscReal tmp = tcoords[1]; tcoords[1] = tcoords[2]; tcoords[2] = -tmp;} 9640588280cSMatthew G. Knepley for (d = 0; d < dof; ++d) { 9650588280cSMatthew G. Knepley if (d > 0) {ierr = PetscViewerASCIISynchronizedPrintf(viewer, ",");CHKERRQ(ierr);} 966f347f43bSBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer, "%g", (double)tcoords[d]);CHKERRQ(ierr); 9670588280cSMatthew G. Knepley } 9680588280cSMatthew G. Knepley color = colors[rank%numColors]; 9690588280cSMatthew G. Knepley for (l = 0; l < numLabels; ++l) { 9700588280cSMatthew G. Knepley PetscInt val; 971c58f1c22SToby Isaac ierr = DMGetLabelValue(dm, names[l], v, &val);CHKERRQ(ierr); 9720750fff4SMatthew G. Knepley if (val >= 0) {color = lcolors[l%numLColors]; break;} 9730588280cSMatthew G. Knepley } 974e4b003c7SBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer, ") node(%D_%d) [draw,shape=circle,color=%s] {%D} --\n", e, rank, color, e);CHKERRQ(ierr); 975552f7358SJed Brown } 976552f7358SJed Brown ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 977552f7358SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 978552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, "(0,0);\n");CHKERRQ(ierr); 9790588280cSMatthew G. Knepley } 980552f7358SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 9814d4c343aSBarry Smith ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); 9820588280cSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "\\end{tikzpicture}\n");CHKERRQ(ierr); 983770b213bSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, "\\end{document}\n", name);CHKERRQ(ierr); 9840588280cSMatthew G. Knepley for (l = 0; l < numLabels; ++l) {ierr = PetscFree(names[l]);CHKERRQ(ierr);} 9850588280cSMatthew G. Knepley for (c = 0; c < numColors; ++c) {ierr = PetscFree(colors[c]);CHKERRQ(ierr);} 9860588280cSMatthew G. Knepley for (c = 0; c < numLColors; ++c) {ierr = PetscFree(lcolors[c]);CHKERRQ(ierr);} 9870588280cSMatthew G. Knepley ierr = PetscFree3(names, colors, lcolors);CHKERRQ(ierr); 988fe1cc32dSStefano Zampini ierr = PetscBTDestroy(&wp);CHKERRQ(ierr); 9890f7d6e4aSStefano Zampini } else if (format == PETSC_VIEWER_LOAD_BALANCE) { 9900f7d6e4aSStefano Zampini Vec cown,acown; 9910f7d6e4aSStefano Zampini VecScatter sct; 9920f7d6e4aSStefano Zampini ISLocalToGlobalMapping g2l; 9930f7d6e4aSStefano Zampini IS gid,acis; 9940f7d6e4aSStefano Zampini MPI_Comm comm,ncomm = MPI_COMM_NULL; 9950f7d6e4aSStefano Zampini MPI_Group ggroup,ngroup; 9960f7d6e4aSStefano Zampini PetscScalar *array,nid; 9970f7d6e4aSStefano Zampini const PetscInt *idxs; 9980f7d6e4aSStefano Zampini PetscInt *idxs2,*start,*adjacency,*work; 9990f7d6e4aSStefano Zampini PetscInt64 lm[3],gm[3]; 10000f7d6e4aSStefano Zampini PetscInt i,c,cStart,cEnd,cum,numVertices,ect,ectn,cellHeight; 10010f7d6e4aSStefano Zampini PetscMPIInt d1,d2,rank; 10020f7d6e4aSStefano Zampini 10030f7d6e4aSStefano Zampini ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 1004ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 1005b674149eSJunchao Zhang #if defined(PETSC_HAVE_MPI_PROCESS_SHARED_MEMORY) 1006ffc4695bSBarry Smith ierr = MPI_Comm_split_type(comm,MPI_COMM_TYPE_SHARED,rank,MPI_INFO_NULL,&ncomm);CHKERRMPI(ierr); 10070f7d6e4aSStefano Zampini #endif 10080f7d6e4aSStefano Zampini if (ncomm != MPI_COMM_NULL) { 1009ffc4695bSBarry Smith ierr = MPI_Comm_group(comm,&ggroup);CHKERRMPI(ierr); 1010ffc4695bSBarry Smith ierr = MPI_Comm_group(ncomm,&ngroup);CHKERRMPI(ierr); 10110f7d6e4aSStefano Zampini d1 = 0; 1012ffc4695bSBarry Smith ierr = MPI_Group_translate_ranks(ngroup,1,&d1,ggroup,&d2);CHKERRMPI(ierr); 10130f7d6e4aSStefano Zampini nid = d2; 1014ffc4695bSBarry Smith ierr = MPI_Group_free(&ggroup);CHKERRMPI(ierr); 1015ffc4695bSBarry Smith ierr = MPI_Group_free(&ngroup);CHKERRMPI(ierr); 1016ffc4695bSBarry Smith ierr = MPI_Comm_free(&ncomm);CHKERRMPI(ierr); 10170f7d6e4aSStefano Zampini } else nid = 0.0; 10180f7d6e4aSStefano Zampini 10190f7d6e4aSStefano Zampini /* Get connectivity */ 10200f7d6e4aSStefano Zampini ierr = DMPlexGetVTKCellHeight(dm,&cellHeight);CHKERRQ(ierr); 10210f7d6e4aSStefano Zampini ierr = DMPlexCreatePartitionerGraph(dm,cellHeight,&numVertices,&start,&adjacency,&gid);CHKERRQ(ierr); 10220f7d6e4aSStefano Zampini 10230f7d6e4aSStefano Zampini /* filter overlapped local cells */ 10240f7d6e4aSStefano Zampini ierr = DMPlexGetHeightStratum(dm,cellHeight,&cStart,&cEnd);CHKERRQ(ierr); 10250f7d6e4aSStefano Zampini ierr = ISGetIndices(gid,&idxs);CHKERRQ(ierr); 10260f7d6e4aSStefano Zampini ierr = ISGetLocalSize(gid,&cum);CHKERRQ(ierr); 10270f7d6e4aSStefano Zampini ierr = PetscMalloc1(cum,&idxs2);CHKERRQ(ierr); 10280f7d6e4aSStefano Zampini for (c = cStart, cum = 0; c < cEnd; c++) { 10290f7d6e4aSStefano Zampini if (idxs[c-cStart] < 0) continue; 10300f7d6e4aSStefano Zampini idxs2[cum++] = idxs[c-cStart]; 10310f7d6e4aSStefano Zampini } 10320f7d6e4aSStefano Zampini ierr = ISRestoreIndices(gid,&idxs);CHKERRQ(ierr); 10330f7d6e4aSStefano Zampini if (numVertices != cum) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected %D != %D",numVertices,cum); 10340f7d6e4aSStefano Zampini ierr = ISDestroy(&gid);CHKERRQ(ierr); 10350f7d6e4aSStefano Zampini ierr = ISCreateGeneral(comm,numVertices,idxs2,PETSC_OWN_POINTER,&gid);CHKERRQ(ierr); 10360f7d6e4aSStefano Zampini 10370f7d6e4aSStefano Zampini /* support for node-aware cell locality */ 10380f7d6e4aSStefano Zampini ierr = ISCreateGeneral(comm,start[numVertices],adjacency,PETSC_USE_POINTER,&acis);CHKERRQ(ierr); 10390f7d6e4aSStefano Zampini ierr = VecCreateSeq(PETSC_COMM_SELF,start[numVertices],&acown);CHKERRQ(ierr); 10400f7d6e4aSStefano Zampini ierr = VecCreateMPI(comm,numVertices,PETSC_DECIDE,&cown);CHKERRQ(ierr); 10410f7d6e4aSStefano Zampini ierr = VecGetArray(cown,&array);CHKERRQ(ierr); 10420f7d6e4aSStefano Zampini for (c = 0; c < numVertices; c++) array[c] = nid; 10430f7d6e4aSStefano Zampini ierr = VecRestoreArray(cown,&array);CHKERRQ(ierr); 10440f7d6e4aSStefano Zampini ierr = VecScatterCreate(cown,acis,acown,NULL,&sct);CHKERRQ(ierr); 10450f7d6e4aSStefano Zampini ierr = VecScatterBegin(sct,cown,acown,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 10460f7d6e4aSStefano Zampini ierr = VecScatterEnd(sct,cown,acown,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 10470f7d6e4aSStefano Zampini ierr = ISDestroy(&acis);CHKERRQ(ierr); 10480f7d6e4aSStefano Zampini ierr = VecScatterDestroy(&sct);CHKERRQ(ierr); 10490f7d6e4aSStefano Zampini ierr = VecDestroy(&cown);CHKERRQ(ierr); 10500f7d6e4aSStefano Zampini 10510f7d6e4aSStefano Zampini /* compute edgeCut */ 10520f7d6e4aSStefano Zampini for (c = 0, cum = 0; c < numVertices; c++) cum = PetscMax(cum,start[c+1]-start[c]); 10530f7d6e4aSStefano Zampini ierr = PetscMalloc1(cum,&work);CHKERRQ(ierr); 10540f7d6e4aSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(gid,&g2l);CHKERRQ(ierr); 10550f7d6e4aSStefano Zampini ierr = ISLocalToGlobalMappingSetType(g2l,ISLOCALTOGLOBALMAPPINGHASH);CHKERRQ(ierr); 10560f7d6e4aSStefano Zampini ierr = ISDestroy(&gid);CHKERRQ(ierr); 10570f7d6e4aSStefano Zampini ierr = VecGetArray(acown,&array);CHKERRQ(ierr); 10580f7d6e4aSStefano Zampini for (c = 0, ect = 0, ectn = 0; c < numVertices; c++) { 10590f7d6e4aSStefano Zampini PetscInt totl; 10600f7d6e4aSStefano Zampini 10610f7d6e4aSStefano Zampini totl = start[c+1]-start[c]; 10620f7d6e4aSStefano Zampini ierr = ISGlobalToLocalMappingApply(g2l,IS_GTOLM_MASK,totl,adjacency+start[c],NULL,work);CHKERRQ(ierr); 10630f7d6e4aSStefano Zampini for (i = 0; i < totl; i++) { 10640f7d6e4aSStefano Zampini if (work[i] < 0) { 10650f7d6e4aSStefano Zampini ect += 1; 10660f7d6e4aSStefano Zampini ectn += (array[i + start[c]] != nid) ? 0 : 1; 10670f7d6e4aSStefano Zampini } 10680f7d6e4aSStefano Zampini } 10690f7d6e4aSStefano Zampini } 10700f7d6e4aSStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 10710f7d6e4aSStefano Zampini ierr = VecRestoreArray(acown,&array);CHKERRQ(ierr); 10720f7d6e4aSStefano Zampini lm[0] = numVertices > 0 ? numVertices : PETSC_MAX_INT; 10730f7d6e4aSStefano Zampini lm[1] = -numVertices; 1074820f2d46SBarry Smith ierr = MPIU_Allreduce(lm,gm,2,MPIU_INT64,MPI_MIN,comm);CHKERRMPI(ierr); 10750f7d6e4aSStefano 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); 10760f7d6e4aSStefano Zampini lm[0] = ect; /* edgeCut */ 10770f7d6e4aSStefano Zampini lm[1] = ectn; /* node-aware edgeCut */ 10780f7d6e4aSStefano Zampini lm[2] = numVertices > 0 ? 0 : 1; /* empty processes */ 1079820f2d46SBarry Smith ierr = MPIU_Allreduce(lm,gm,3,MPIU_INT64,MPI_SUM,comm);CHKERRMPI(ierr); 10800f7d6e4aSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer,", empty %D)\n",(PetscInt)gm[2]);CHKERRQ(ierr); 1081b674149eSJunchao Zhang #if defined(PETSC_HAVE_MPI_PROCESS_SHARED_MEMORY) 10820f7d6e4aSStefano 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); 10830f7d6e4aSStefano Zampini #else 10840f7d6e4aSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," Edge Cut: %D (on node %.3f)\n",(PetscInt)(gm[0]/2),0.0);CHKERRQ(ierr); 10850f7d6e4aSStefano Zampini #endif 10860f7d6e4aSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&g2l);CHKERRQ(ierr); 10870f7d6e4aSStefano Zampini ierr = PetscFree(start);CHKERRQ(ierr); 10880f7d6e4aSStefano Zampini ierr = PetscFree(adjacency);CHKERRQ(ierr); 10890f7d6e4aSStefano Zampini ierr = VecDestroy(&acown);CHKERRQ(ierr); 1090552f7358SJed Brown } else { 1091412e9a14SMatthew G. Knepley const char *name; 1092d80ece95SMatthew G. Knepley PetscInt *sizes, *hybsizes, *ghostsizes; 1093412e9a14SMatthew G. Knepley PetscInt locDepth, depth, cellHeight, dim, d; 1094d80ece95SMatthew G. Knepley PetscInt pStart, pEnd, p, gcStart, gcEnd, gcNum; 1095a57dd577SMatthew G Knepley PetscInt numLabels, l; 10969318fe57SMatthew G. Knepley DMPolytopeType ct0 = DM_POLYTOPE_UNKNOWN; 1097412e9a14SMatthew G. Knepley MPI_Comm comm; 1098412e9a14SMatthew G. Knepley PetscMPIInt size, rank; 1099552f7358SJed Brown 110082f516ccSBarry Smith ierr = PetscObjectGetComm((PetscObject) dm, &comm);CHKERRQ(ierr); 1101ffc4695bSBarry Smith ierr = MPI_Comm_size(comm, &size);CHKERRMPI(ierr); 1102ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 1103c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 1104f73eea6eSMatthew G. Knepley ierr = DMPlexGetVTKCellHeight(dm, &cellHeight);CHKERRQ(ierr); 11055f64d76eSMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) dm, &name);CHKERRQ(ierr); 1106f73eea6eSMatthew G. Knepley if (name) {ierr = PetscViewerASCIIPrintf(viewer, "%s in %D dimension%s:\n", name, dim, dim == 1 ? "" : "s");CHKERRQ(ierr);} 1107f73eea6eSMatthew G. Knepley else {ierr = PetscViewerASCIIPrintf(viewer, "Mesh in %D dimension%s:\n", dim, dim == 1 ? "" : "s");CHKERRQ(ierr);} 1108f73eea6eSMatthew G. Knepley if (cellHeight) {ierr = PetscViewerASCIIPrintf(viewer, " Cells are at height %D\n", cellHeight);CHKERRQ(ierr);} 1109552f7358SJed Brown ierr = DMPlexGetDepth(dm, &locDepth);CHKERRQ(ierr); 1110820f2d46SBarry Smith ierr = MPIU_Allreduce(&locDepth, &depth, 1, MPIU_INT, MPI_MAX, comm);CHKERRMPI(ierr); 1111d80ece95SMatthew G. Knepley ierr = DMPlexGetGhostCellStratum(dm, &gcStart, &gcEnd);CHKERRQ(ierr); 1112d80ece95SMatthew G. Knepley gcNum = gcEnd - gcStart; 1113d80ece95SMatthew G. Knepley ierr = PetscCalloc3(size,&sizes,size,&hybsizes,size,&ghostsizes);CHKERRQ(ierr); 1114412e9a14SMatthew G. Knepley for (d = 0; d <= depth; d++) { 1115412e9a14SMatthew G. Knepley PetscInt Nc[2] = {0, 0}, ict; 1116412e9a14SMatthew G. Knepley 1117552f7358SJed Brown ierr = DMPlexGetDepthStratum(dm, d, &pStart, &pEnd);CHKERRQ(ierr); 11189318fe57SMatthew G. Knepley if (pStart < pEnd) {ierr = DMPlexGetCellType(dm, pStart, &ct0);CHKERRQ(ierr);} 1119412e9a14SMatthew G. Knepley ict = ct0; 1120ffc4695bSBarry Smith ierr = MPI_Bcast(&ict, 1, MPIU_INT, 0, comm);CHKERRMPI(ierr); 1121412e9a14SMatthew G. Knepley ct0 = (DMPolytopeType) ict; 1122412e9a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 1123412e9a14SMatthew G. Knepley DMPolytopeType ct; 1124412e9a14SMatthew G. Knepley 1125412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr); 1126412e9a14SMatthew G. Knepley if (ct == ct0) ++Nc[0]; 1127412e9a14SMatthew G. Knepley else ++Nc[1]; 1128412e9a14SMatthew G. Knepley } 1129ffc4695bSBarry Smith ierr = MPI_Gather(&Nc[0], 1, MPIU_INT, sizes, 1, MPIU_INT, 0, comm);CHKERRMPI(ierr); 1130ffc4695bSBarry Smith ierr = MPI_Gather(&Nc[1], 1, MPIU_INT, hybsizes, 1, MPIU_INT, 0, comm);CHKERRMPI(ierr); 1131ffc4695bSBarry Smith if (d == depth) {ierr = MPI_Gather(&gcNum, 1, MPIU_INT, ghostsizes, 1, MPIU_INT, 0, comm);CHKERRMPI(ierr);} 1132412e9a14SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " %D-cells:", (depth == 1) && d ? dim : d);CHKERRQ(ierr); 1133834065abSMatthew G. Knepley for (p = 0; p < size; ++p) { 1134cbb7f117SMark Adams if (!rank) { 1135412e9a14SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " %D", sizes[p]+hybsizes[p]);CHKERRQ(ierr); 1136412e9a14SMatthew G. Knepley if (hybsizes[p] > 0) {ierr = PetscViewerASCIIPrintf(viewer, " (%D)", hybsizes[p]);CHKERRQ(ierr);} 1137412e9a14SMatthew G. Knepley if (ghostsizes[p] > 0) {ierr = PetscViewerASCIIPrintf(viewer, " [%D]", ghostsizes[p]);CHKERRQ(ierr);} 1138834065abSMatthew G. Knepley } 1139cbb7f117SMark Adams } 1140552f7358SJed Brown ierr = PetscViewerASCIIPrintf(viewer, "\n");CHKERRQ(ierr); 1141552f7358SJed Brown } 1142d80ece95SMatthew G. Knepley ierr = PetscFree3(sizes,hybsizes,ghostsizes);CHKERRQ(ierr); 11439318fe57SMatthew G. Knepley { 11449318fe57SMatthew G. Knepley const PetscReal *maxCell; 11459318fe57SMatthew G. Knepley const PetscReal *L; 11469318fe57SMatthew G. Knepley const DMBoundaryType *bd; 11479318fe57SMatthew G. Knepley PetscBool per, localized; 11489318fe57SMatthew G. Knepley 11499318fe57SMatthew G. Knepley ierr = DMGetPeriodicity(dm, &per, &maxCell, &L, &bd);CHKERRQ(ierr); 11509318fe57SMatthew G. Knepley ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 11519318fe57SMatthew G. Knepley if (per) { 11529318fe57SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "Periodic mesh (");CHKERRQ(ierr); 11539318fe57SMatthew G. Knepley ierr = PetscViewerASCIIUseTabs(viewer, PETSC_FALSE);CHKERRQ(ierr); 11549318fe57SMatthew G. Knepley for (d = 0; d < dim; ++d) { 11559318fe57SMatthew G. Knepley if (bd && d > 0) {ierr = PetscViewerASCIIPrintf(viewer, ", ");CHKERRQ(ierr);} 11569318fe57SMatthew G. Knepley if (bd) {ierr = PetscViewerASCIIPrintf(viewer, "%s", DMBoundaryTypes[bd[d]]);CHKERRQ(ierr);} 11579318fe57SMatthew G. Knepley } 11589318fe57SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, ") coordinates %s\n", localized ? "localized" : "not localized");CHKERRQ(ierr); 11599318fe57SMatthew G. Knepley ierr = PetscViewerASCIIUseTabs(viewer, PETSC_TRUE);CHKERRQ(ierr); 11609318fe57SMatthew G. Knepley } 11619318fe57SMatthew G. Knepley } 1162c58f1c22SToby Isaac ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 1163a57dd577SMatthew G Knepley if (numLabels) {ierr = PetscViewerASCIIPrintf(viewer, "Labels:\n");CHKERRQ(ierr);} 1164a57dd577SMatthew G Knepley for (l = 0; l < numLabels; ++l) { 1165a57dd577SMatthew G Knepley DMLabel label; 1166a57dd577SMatthew G Knepley const char *name; 1167a57dd577SMatthew G Knepley IS valueIS; 1168a57dd577SMatthew G Knepley const PetscInt *values; 1169a57dd577SMatthew G Knepley PetscInt numValues, v; 1170a57dd577SMatthew G Knepley 1171c58f1c22SToby Isaac ierr = DMGetLabelName(dm, l, &name);CHKERRQ(ierr); 1172c58f1c22SToby Isaac ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 1173a57dd577SMatthew G Knepley ierr = DMLabelGetNumValues(label, &numValues);CHKERRQ(ierr); 1174d72f73ffSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " %s: %D strata with value/size (", name, numValues);CHKERRQ(ierr); 1175a57dd577SMatthew G Knepley ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 1176a57dd577SMatthew G Knepley ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 1177120dea56SMatthew G. Knepley ierr = PetscViewerASCIIUseTabs(viewer, PETSC_FALSE);CHKERRQ(ierr); 1178a57dd577SMatthew G Knepley for (v = 0; v < numValues; ++v) { 1179a57dd577SMatthew G Knepley PetscInt size; 1180a57dd577SMatthew G Knepley 1181a57dd577SMatthew G Knepley ierr = DMLabelGetStratumSize(label, values[v], &size);CHKERRQ(ierr); 1182a57dd577SMatthew G Knepley if (v > 0) {ierr = PetscViewerASCIIPrintf(viewer, ", ");CHKERRQ(ierr);} 1183d72f73ffSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, "%D (%D)", values[v], size);CHKERRQ(ierr); 1184a57dd577SMatthew G Knepley } 1185a57dd577SMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, ")\n");CHKERRQ(ierr); 1186120dea56SMatthew G. Knepley ierr = PetscViewerASCIIUseTabs(viewer, PETSC_TRUE);CHKERRQ(ierr); 1187a57dd577SMatthew G Knepley ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 11884d41221fSMatthew G Knepley ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 1189a57dd577SMatthew G Knepley } 119034aa8a36SMatthew G. Knepley /* If no fields are specified, people do not want to see adjacency */ 119134aa8a36SMatthew G. Knepley if (dm->Nf) { 119234aa8a36SMatthew G. Knepley PetscInt f; 119334aa8a36SMatthew G. Knepley 119434aa8a36SMatthew G. Knepley for (f = 0; f < dm->Nf; ++f) { 119534aa8a36SMatthew G. Knepley const char *name; 119634aa8a36SMatthew G. Knepley 119734aa8a36SMatthew G. Knepley ierr = PetscObjectGetName(dm->fields[f].disc, &name);CHKERRQ(ierr); 119834aa8a36SMatthew G. Knepley if (numLabels) {ierr = PetscViewerASCIIPrintf(viewer, "Field %s:\n", name);CHKERRQ(ierr);} 119934aa8a36SMatthew G. Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 120034aa8a36SMatthew G. Knepley if (dm->fields[f].label) {ierr = DMLabelView(dm->fields[f].label, viewer);CHKERRQ(ierr);} 120134aa8a36SMatthew G. Knepley if (dm->fields[f].adjacency[0]) { 120234aa8a36SMatthew G. Knepley if (dm->fields[f].adjacency[1]) {ierr = PetscViewerASCIIPrintf(viewer, "adjacency FVM++\n");CHKERRQ(ierr);} 1203ed59e46eSMatthew G. Knepley else {ierr = PetscViewerASCIIPrintf(viewer, "adjacency FVM\n");CHKERRQ(ierr);} 120434aa8a36SMatthew G. Knepley } else { 120534aa8a36SMatthew G. Knepley if (dm->fields[f].adjacency[1]) {ierr = PetscViewerASCIIPrintf(viewer, "adjacency FEM\n");CHKERRQ(ierr);} 120634aa8a36SMatthew G. Knepley else {ierr = PetscViewerASCIIPrintf(viewer, "adjacency FUNKY\n");CHKERRQ(ierr);} 120734aa8a36SMatthew G. Knepley } 120834aa8a36SMatthew G. Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 120934aa8a36SMatthew G. Knepley } 121034aa8a36SMatthew G. Knepley } 1211a8fb8f29SToby Isaac ierr = DMGetCoarseDM(dm, &cdm);CHKERRQ(ierr); 12128e7ff633SMatthew G. Knepley if (cdm) { 12138e7ff633SMatthew G. Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 12148e7ff633SMatthew G. Knepley ierr = DMPlexView_Ascii(cdm, viewer);CHKERRQ(ierr); 12158e7ff633SMatthew G. Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 12168e7ff633SMatthew G. Knepley } 1217552f7358SJed Brown } 1218552f7358SJed Brown PetscFunctionReturn(0); 1219552f7358SJed Brown } 1220552f7358SJed Brown 1221e5c487bfSMatthew G. Knepley static PetscErrorCode DMPlexDrawCell(DM dm, PetscDraw draw, PetscInt cell, const PetscScalar coords[]) 1222e5c487bfSMatthew G. Knepley { 1223e5c487bfSMatthew G. Knepley DMPolytopeType ct; 1224e5c487bfSMatthew G. Knepley PetscMPIInt rank; 1225e5c487bfSMatthew G. Knepley PetscErrorCode ierr; 1226e5c487bfSMatthew G. Knepley 1227e5c487bfSMatthew G. Knepley PetscFunctionBegin; 1228ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject) dm), &rank);CHKERRMPI(ierr); 1229e5c487bfSMatthew G. Knepley ierr = DMPlexGetCellType(dm, cell, &ct);CHKERRQ(ierr); 1230e5c487bfSMatthew G. Knepley switch (ct) { 1231e5c487bfSMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 1232e5c487bfSMatthew G. Knepley ierr = PetscDrawTriangle(draw, PetscRealPart(coords[0]), PetscRealPart(coords[1]), PetscRealPart(coords[2]), PetscRealPart(coords[3]), PetscRealPart(coords[4]), PetscRealPart(coords[5]), 1233e5c487bfSMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2, 1234e5c487bfSMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2, 1235e5c487bfSMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2);CHKERRQ(ierr); 1236e5c487bfSMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[0]), PetscRealPart(coords[1]), PetscRealPart(coords[2]), PetscRealPart(coords[3]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 1237e5c487bfSMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[2]), PetscRealPart(coords[3]), PetscRealPart(coords[4]), PetscRealPart(coords[5]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 1238e5c487bfSMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[4]), PetscRealPart(coords[5]), PetscRealPart(coords[0]), PetscRealPart(coords[1]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 1239e5c487bfSMatthew G. Knepley break; 1240e5c487bfSMatthew G. Knepley case DM_POLYTOPE_QUADRILATERAL: 1241e5c487bfSMatthew G. Knepley ierr = PetscDrawTriangle(draw, PetscRealPart(coords[0]), PetscRealPart(coords[1]), PetscRealPart(coords[2]), PetscRealPart(coords[3]), PetscRealPart(coords[4]), PetscRealPart(coords[5]), 1242e5c487bfSMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2, 1243e5c487bfSMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2, 1244e5c487bfSMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2);CHKERRQ(ierr); 1245e5c487bfSMatthew G. Knepley ierr = PetscDrawTriangle(draw, PetscRealPart(coords[0]), PetscRealPart(coords[1]), PetscRealPart(coords[4]), PetscRealPart(coords[5]), PetscRealPart(coords[6]), PetscRealPart(coords[7]), 1246e5c487bfSMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2, 1247e5c487bfSMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2, 1248e5c487bfSMatthew G. Knepley PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2);CHKERRQ(ierr); 1249e5c487bfSMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[0]), PetscRealPart(coords[1]), PetscRealPart(coords[2]), PetscRealPart(coords[3]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 1250e5c487bfSMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[2]), PetscRealPart(coords[3]), PetscRealPart(coords[4]), PetscRealPart(coords[5]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 1251e5c487bfSMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[4]), PetscRealPart(coords[5]), PetscRealPart(coords[6]), PetscRealPart(coords[7]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 1252e5c487bfSMatthew G. Knepley ierr = PetscDrawLine(draw, PetscRealPart(coords[6]), PetscRealPart(coords[7]), PetscRealPart(coords[0]), PetscRealPart(coords[1]), PETSC_DRAW_BLACK);CHKERRQ(ierr); 1253e5c487bfSMatthew G. Knepley break; 1254e5c487bfSMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot draw cells of type %s", DMPolytopeTypes[ct]); 1255e5c487bfSMatthew G. Knepley } 1256e5c487bfSMatthew G. Knepley PetscFunctionReturn(0); 1257e5c487bfSMatthew G. Knepley } 1258e5c487bfSMatthew G. Knepley 1259e5c487bfSMatthew G. Knepley static PetscErrorCode DMPlexDrawCellHighOrder(DM dm, PetscDraw draw, PetscInt cell, const PetscScalar coords[], PetscInt edgeDiv, PetscReal refCoords[], PetscReal edgeCoords[]) 1260e5c487bfSMatthew G. Knepley { 1261e5c487bfSMatthew G. Knepley DMPolytopeType ct; 1262e5c487bfSMatthew G. Knepley PetscReal centroid[2] = {0., 0.}; 1263e5c487bfSMatthew G. Knepley PetscMPIInt rank; 1264e5c487bfSMatthew G. Knepley PetscInt fillColor, v, e, d; 1265e5c487bfSMatthew G. Knepley PetscErrorCode ierr; 1266e5c487bfSMatthew G. Knepley 1267e5c487bfSMatthew G. Knepley PetscFunctionBegin; 1268ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject) dm), &rank);CHKERRMPI(ierr); 1269e5c487bfSMatthew G. Knepley ierr = DMPlexGetCellType(dm, cell, &ct);CHKERRQ(ierr); 1270e5c487bfSMatthew G. Knepley fillColor = PETSC_DRAW_WHITE + rank % (PETSC_DRAW_BASIC_COLORS-2) + 2; 1271e5c487bfSMatthew G. Knepley switch (ct) { 1272e5c487bfSMatthew G. Knepley case DM_POLYTOPE_TRIANGLE: 1273e5c487bfSMatthew G. Knepley { 1274e5c487bfSMatthew G. Knepley PetscReal refVertices[6] = {-1., -1., 1., -1., -1., 1.}; 1275e5c487bfSMatthew G. Knepley 1276e5c487bfSMatthew G. Knepley for (v = 0; v < 3; ++v) {centroid[0] += PetscRealPart(coords[v*2+0])/3.;centroid[1] += PetscRealPart(coords[v*2+1])/3.;} 1277e5c487bfSMatthew G. Knepley for (e = 0; e < 3; ++e) { 1278e5c487bfSMatthew G. Knepley refCoords[0] = refVertices[e*2+0]; 1279e5c487bfSMatthew G. Knepley refCoords[1] = refVertices[e*2+1]; 1280e5c487bfSMatthew G. Knepley for (d = 1; d <= edgeDiv; ++d) { 1281e5c487bfSMatthew G. Knepley refCoords[d*2+0] = refCoords[0] + (refVertices[(e+1)%3 * 2 + 0] - refCoords[0])*d/edgeDiv; 1282e5c487bfSMatthew G. Knepley refCoords[d*2+1] = refCoords[1] + (refVertices[(e+1)%3 * 2 + 1] - refCoords[1])*d/edgeDiv; 1283e5c487bfSMatthew G. Knepley } 1284e5c487bfSMatthew G. Knepley ierr = DMPlexReferenceToCoordinates(dm, cell, edgeDiv+1, refCoords, edgeCoords);CHKERRQ(ierr); 1285e5c487bfSMatthew G. Knepley for (d = 0; d < edgeDiv; ++d) { 1286e5c487bfSMatthew 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); 1287e5c487bfSMatthew 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); 1288e5c487bfSMatthew G. Knepley } 1289e5c487bfSMatthew G. Knepley } 1290e5c487bfSMatthew G. Knepley } 1291e5c487bfSMatthew G. Knepley break; 1292e5c487bfSMatthew G. Knepley default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot draw cells of type %s", DMPolytopeTypes[ct]); 1293e5c487bfSMatthew G. Knepley } 1294e5c487bfSMatthew G. Knepley PetscFunctionReturn(0); 1295e5c487bfSMatthew G. Knepley } 1296e5c487bfSMatthew G. Knepley 12977cd05799SMatthew G. Knepley static PetscErrorCode DMPlexView_Draw(DM dm, PetscViewer viewer) 1298e412dcbdSMatthew G. Knepley { 1299e412dcbdSMatthew G. Knepley PetscDraw draw; 1300e412dcbdSMatthew G. Knepley DM cdm; 1301e412dcbdSMatthew G. Knepley PetscSection coordSection; 1302e412dcbdSMatthew G. Knepley Vec coordinates; 1303e412dcbdSMatthew G. Knepley const PetscScalar *coords; 130429494db1SLisandro Dalcin PetscReal xyl[2],xyr[2],bound[4] = {PETSC_MAX_REAL, PETSC_MAX_REAL, PETSC_MIN_REAL, PETSC_MIN_REAL}; 1305e5c487bfSMatthew G. Knepley PetscReal *refCoords, *edgeCoords; 1306e5c487bfSMatthew G. Knepley PetscBool isnull, drawAffine = PETSC_TRUE; 1307e5c487bfSMatthew G. Knepley PetscInt dim, vStart, vEnd, cStart, cEnd, c, N, edgeDiv = 4; 1308e412dcbdSMatthew G. Knepley PetscErrorCode ierr; 1309e412dcbdSMatthew G. Knepley 1310e412dcbdSMatthew G. Knepley PetscFunctionBegin; 1311e412dcbdSMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dim);CHKERRQ(ierr); 1312e412dcbdSMatthew G. Knepley if (dim != 2) SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Cannot draw meshes of dimension %D", dim); 1313e5c487bfSMatthew G. Knepley ierr = PetscOptionsGetBool(((PetscObject) dm)->options, ((PetscObject) dm)->prefix, "-dm_view_draw_affine", &drawAffine, NULL);CHKERRQ(ierr); 1314e5c487bfSMatthew G. Knepley if (!drawAffine) {ierr = PetscMalloc2((edgeDiv+1)*dim, &refCoords, (edgeDiv+1)*dim, &edgeCoords);CHKERRQ(ierr);} 1315e412dcbdSMatthew G. Knepley ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr); 131692fd8e1eSJed Brown ierr = DMGetLocalSection(cdm, &coordSection);CHKERRQ(ierr); 1317e412dcbdSMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 1318e412dcbdSMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 1319e412dcbdSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 1320e412dcbdSMatthew G. Knepley 1321e412dcbdSMatthew G. Knepley ierr = PetscViewerDrawGetDraw(viewer, 0, &draw);CHKERRQ(ierr); 1322e412dcbdSMatthew G. Knepley ierr = PetscDrawIsNull(draw, &isnull);CHKERRQ(ierr); 1323e412dcbdSMatthew G. Knepley if (isnull) PetscFunctionReturn(0); 1324e412dcbdSMatthew G. Knepley ierr = PetscDrawSetTitle(draw, "Mesh");CHKERRQ(ierr); 1325e412dcbdSMatthew G. Knepley 1326e412dcbdSMatthew G. Knepley ierr = VecGetLocalSize(coordinates, &N);CHKERRQ(ierr); 1327e412dcbdSMatthew G. Knepley ierr = VecGetArrayRead(coordinates, &coords);CHKERRQ(ierr); 1328e412dcbdSMatthew G. Knepley for (c = 0; c < N; c += dim) { 13290c81f2a8SMatthew G. Knepley bound[0] = PetscMin(bound[0], PetscRealPart(coords[c])); bound[2] = PetscMax(bound[2], PetscRealPart(coords[c])); 13300c81f2a8SMatthew G. Knepley bound[1] = PetscMin(bound[1], PetscRealPart(coords[c+1])); bound[3] = PetscMax(bound[3], PetscRealPart(coords[c+1])); 1331e412dcbdSMatthew G. Knepley } 1332e412dcbdSMatthew G. Knepley ierr = VecRestoreArrayRead(coordinates, &coords);CHKERRQ(ierr); 1333820f2d46SBarry Smith ierr = MPIU_Allreduce(&bound[0],xyl,2,MPIU_REAL,MPIU_MIN,PetscObjectComm((PetscObject)dm));CHKERRMPI(ierr); 1334820f2d46SBarry Smith ierr = MPIU_Allreduce(&bound[2],xyr,2,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)dm));CHKERRMPI(ierr); 133529494db1SLisandro Dalcin ierr = PetscDrawSetCoordinates(draw, xyl[0], xyl[1], xyr[0], xyr[1]);CHKERRQ(ierr); 1336e412dcbdSMatthew G. Knepley ierr = PetscDrawClear(draw);CHKERRQ(ierr); 1337e412dcbdSMatthew G. Knepley 1338cf3064d3SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 1339cf3064d3SMatthew G. Knepley PetscScalar *coords = NULL; 1340ba2698f1SMatthew G. Knepley PetscInt numCoords; 1341cf3064d3SMatthew G. Knepley 1342e5c487bfSMatthew G. Knepley ierr = DMPlexVecGetClosureAtDepth_Internal(dm, coordSection, coordinates, c, 0, &numCoords, &coords);CHKERRQ(ierr); 1343e5c487bfSMatthew G. Knepley if (drawAffine) { 1344e5c487bfSMatthew G. Knepley ierr = DMPlexDrawCell(dm, draw, c, coords);CHKERRQ(ierr); 1345e5c487bfSMatthew G. Knepley } else { 1346e5c487bfSMatthew G. Knepley ierr = DMPlexDrawCellHighOrder(dm, draw, c, coords, edgeDiv, refCoords, edgeCoords);CHKERRQ(ierr); 1347cf3064d3SMatthew G. Knepley } 1348cf3064d3SMatthew G. Knepley ierr = DMPlexVecRestoreClosure(dm, coordSection, coordinates, c, &numCoords, &coords);CHKERRQ(ierr); 1349cf3064d3SMatthew G. Knepley } 1350e5c487bfSMatthew G. Knepley if (!drawAffine) {ierr = PetscFree2(refCoords, edgeCoords);CHKERRQ(ierr);} 1351e412dcbdSMatthew G. Knepley ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 1352e412dcbdSMatthew G. Knepley ierr = PetscDrawPause(draw);CHKERRQ(ierr); 1353e412dcbdSMatthew G. Knepley ierr = PetscDrawSave(draw);CHKERRQ(ierr); 1354e412dcbdSMatthew G. Knepley PetscFunctionReturn(0); 1355e412dcbdSMatthew G. Knepley } 1356e412dcbdSMatthew G. Knepley 13571e50132fSMatthew G. Knepley #if defined(PETSC_HAVE_EXODUSII) 13581e50132fSMatthew G. Knepley #include <exodusII.h> 13596823f3c5SBlaise Bourdin #include <petscviewerexodusii.h> 13601e50132fSMatthew G. Knepley #endif 13611e50132fSMatthew G. Knepley 1362552f7358SJed Brown PetscErrorCode DMView_Plex(DM dm, PetscViewer viewer) 1363552f7358SJed Brown { 13641e50132fSMatthew G. Knepley PetscBool iascii, ishdf5, isvtk, isdraw, flg, isglvis, isexodus; 1365002a2709SMatthew G. Knepley char name[PETSC_MAX_PATH_LEN]; 1366552f7358SJed Brown PetscErrorCode ierr; 1367552f7358SJed Brown 1368552f7358SJed Brown PetscFunctionBegin; 1369552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1370552f7358SJed Brown PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1371552f7358SJed Brown ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 1372fcf6c8fdSToby Isaac ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERVTK, &isvtk);CHKERRQ(ierr); 1373c6ccd67eSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 1374e412dcbdSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERDRAW, &isdraw);CHKERRQ(ierr); 13758135c375SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERGLVIS, &isglvis);CHKERRQ(ierr); 13761e50132fSMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWEREXODUSII, &isexodus);CHKERRQ(ierr); 1377552f7358SJed Brown if (iascii) { 13788135c375SStefano Zampini PetscViewerFormat format; 13798135c375SStefano Zampini ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 13808135c375SStefano Zampini if (format == PETSC_VIEWER_ASCII_GLVIS) { 13818135c375SStefano Zampini ierr = DMPlexView_GLVis(dm, viewer);CHKERRQ(ierr); 13828135c375SStefano Zampini } else { 1383552f7358SJed Brown ierr = DMPlexView_Ascii(dm, viewer);CHKERRQ(ierr); 13848135c375SStefano Zampini } 1385c6ccd67eSMatthew G. Knepley } else if (ishdf5) { 1386c6ccd67eSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 138739d25373SMatthew G. Knepley ierr = DMPlexView_HDF5_Internal(dm, viewer);CHKERRQ(ierr); 1388c6ccd67eSMatthew G. Knepley #else 1389c6ccd67eSMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 1390552f7358SJed Brown #endif 1391e412dcbdSMatthew G. Knepley } else if (isvtk) { 1392fcf6c8fdSToby Isaac ierr = DMPlexVTKWriteAll((PetscObject) dm,viewer);CHKERRQ(ierr); 1393e412dcbdSMatthew G. Knepley } else if (isdraw) { 1394e412dcbdSMatthew G. Knepley ierr = DMPlexView_Draw(dm, viewer);CHKERRQ(ierr); 13958135c375SStefano Zampini } else if (isglvis) { 13968135c375SStefano Zampini ierr = DMPlexView_GLVis(dm, viewer);CHKERRQ(ierr); 13971e50132fSMatthew G. Knepley #if defined(PETSC_HAVE_EXODUSII) 13981e50132fSMatthew G. Knepley } else if (isexodus) { 13996823f3c5SBlaise Bourdin /* 14006823f3c5SBlaise Bourdin exodusII requires that all sets be part of exactly one cell set. 14016823f3c5SBlaise Bourdin If the dm does not have a "Cell Sets" label defined, we create one 14026823f3c5SBlaise Bourdin with ID 1, containig all cells. 14036823f3c5SBlaise Bourdin Note that if the Cell Sets label is defined but does not cover all cells, 14046823f3c5SBlaise Bourdin we may still have a problem. This should probably be checked here or in the viewer; 14056823f3c5SBlaise Bourdin */ 14066823f3c5SBlaise Bourdin PetscInt numCS; 14076823f3c5SBlaise Bourdin ierr = DMGetLabelSize(dm,"Cell Sets",&numCS);CHKERRQ(ierr); 14086823f3c5SBlaise Bourdin if (!numCS) { 14091e50132fSMatthew G. Knepley PetscInt cStart, cEnd, c; 14101e50132fSMatthew G. Knepley ierr = DMCreateLabel(dm, "Cell Sets");CHKERRQ(ierr); 14111e50132fSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 14121e50132fSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) {ierr = DMSetLabelValue(dm, "Cell Sets", c, 1);CHKERRQ(ierr);} 14136823f3c5SBlaise Bourdin } 14146823f3c5SBlaise Bourdin ierr = DMView_PlexExodusII(dm, viewer);CHKERRQ(ierr); 14151e50132fSMatthew G. Knepley #endif 141662201deeSVaclav Hapla } else { 1417a94aea51SVaclav Hapla SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Viewer type %s not yet supported for DMPlex writing", ((PetscObject)viewer)->type_name); 1418fcf6c8fdSToby Isaac } 1419cb3ba0daSMatthew G. Knepley /* Optionally view the partition */ 1420cb3ba0daSMatthew G. Knepley ierr = PetscOptionsHasName(((PetscObject) dm)->options, ((PetscObject) dm)->prefix, "-dm_partition_view", &flg);CHKERRQ(ierr); 1421cb3ba0daSMatthew G. Knepley if (flg) { 1422cb3ba0daSMatthew G. Knepley Vec ranks; 1423cb3ba0daSMatthew G. Knepley ierr = DMPlexCreateRankField(dm, &ranks);CHKERRQ(ierr); 1424cb3ba0daSMatthew G. Knepley ierr = VecView(ranks, viewer);CHKERRQ(ierr); 1425cb3ba0daSMatthew G. Knepley ierr = VecDestroy(&ranks);CHKERRQ(ierr); 1426cb3ba0daSMatthew G. Knepley } 1427002a2709SMatthew G. Knepley /* Optionally view a label */ 1428589a23caSBarry Smith ierr = PetscOptionsGetString(((PetscObject) dm)->options, ((PetscObject) dm)->prefix, "-dm_label_view", name, sizeof(name), &flg);CHKERRQ(ierr); 1429002a2709SMatthew G. Knepley if (flg) { 1430002a2709SMatthew G. Knepley DMLabel label; 1431002a2709SMatthew G. Knepley Vec val; 1432002a2709SMatthew G. Knepley 1433002a2709SMatthew G. Knepley ierr = DMGetLabel(dm, name, &label);CHKERRQ(ierr); 1434002a2709SMatthew 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); 1435002a2709SMatthew G. Knepley ierr = DMPlexCreateLabelField(dm, label, &val);CHKERRQ(ierr); 1436002a2709SMatthew G. Knepley ierr = VecView(val, viewer);CHKERRQ(ierr); 1437002a2709SMatthew G. Knepley ierr = VecDestroy(&val);CHKERRQ(ierr); 1438002a2709SMatthew G. Knepley } 1439552f7358SJed Brown PetscFunctionReturn(0); 1440552f7358SJed Brown } 1441552f7358SJed Brown 14427f96f51bSksagiyam /*@ 14437f96f51bSksagiyam DMPlexTopologyView - Saves a DMPlex topology into a file 14447f96f51bSksagiyam 14457f96f51bSksagiyam Collective on DM 14467f96f51bSksagiyam 14477f96f51bSksagiyam Input Parameters: 14487f96f51bSksagiyam + dm - The DM whose topology is to be saved 14497f96f51bSksagiyam - viewer - The PetscViewer for saving 14507f96f51bSksagiyam 14517f96f51bSksagiyam Level: advanced 14527f96f51bSksagiyam 14537f96f51bSksagiyam .seealso: DMView(), DMPlexCoordinatesView(), DMPlexLabelsView(), DMPlexTopologyLoad() 14547f96f51bSksagiyam @*/ 14557f96f51bSksagiyam PetscErrorCode DMPlexTopologyView(DM dm, PetscViewer viewer) 14567f96f51bSksagiyam { 14577f96f51bSksagiyam PetscBool ishdf5; 14587f96f51bSksagiyam PetscErrorCode ierr; 14597f96f51bSksagiyam 14607f96f51bSksagiyam PetscFunctionBegin; 14617f96f51bSksagiyam PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 14627f96f51bSksagiyam PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 14637f96f51bSksagiyam ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 14647f96f51bSksagiyam if (ishdf5) { 14657f96f51bSksagiyam #if defined(PETSC_HAVE_HDF5) 14667f96f51bSksagiyam PetscViewerFormat format; 14677f96f51bSksagiyam ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 14687f96f51bSksagiyam if (format == PETSC_VIEWER_HDF5_PETSC || format == PETSC_VIEWER_DEFAULT || format == PETSC_VIEWER_NATIVE) { 14697f96f51bSksagiyam IS globalPointNumbering; 14707f96f51bSksagiyam 14717f96f51bSksagiyam ierr = DMPlexCreatePointNumbering(dm, &globalPointNumbering);CHKERRQ(ierr); 14727f96f51bSksagiyam ierr = DMPlexTopologyView_HDF5_Internal(dm, globalPointNumbering, viewer);CHKERRQ(ierr); 14737f96f51bSksagiyam ierr = ISDestroy(&globalPointNumbering);CHKERRQ(ierr); 14747f96f51bSksagiyam } else SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "PetscViewerFormat %s not supported for HDF5 output.", PetscViewerFormats[format]); 14757f96f51bSksagiyam #else 14767f96f51bSksagiyam SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 14777f96f51bSksagiyam #endif 14787f96f51bSksagiyam } 14797f96f51bSksagiyam PetscFunctionReturn(0); 14807f96f51bSksagiyam } 14817f96f51bSksagiyam 148277b8e257Sksagiyam /*@ 148377b8e257Sksagiyam DMPlexCoordinatesView - Saves DMPlex coordinates into a file 148477b8e257Sksagiyam 148577b8e257Sksagiyam Collective on DM 148677b8e257Sksagiyam 148777b8e257Sksagiyam Input Parameters: 148877b8e257Sksagiyam + dm - The DM whose coordinates are to be saved 148977b8e257Sksagiyam - viewer - The PetscViewer for saving 149077b8e257Sksagiyam 149177b8e257Sksagiyam Level: advanced 149277b8e257Sksagiyam 149377b8e257Sksagiyam .seealso: DMView(), DMPlexTopologyView(), DMPlexLabelsView(), DMPlexCoordinatesLoad() 149477b8e257Sksagiyam @*/ 149577b8e257Sksagiyam PetscErrorCode DMPlexCoordinatesView(DM dm, PetscViewer viewer) 149677b8e257Sksagiyam { 149777b8e257Sksagiyam PetscBool ishdf5; 149877b8e257Sksagiyam PetscErrorCode ierr; 149977b8e257Sksagiyam 150077b8e257Sksagiyam PetscFunctionBegin; 150177b8e257Sksagiyam PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 150277b8e257Sksagiyam PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 150377b8e257Sksagiyam ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 150477b8e257Sksagiyam if (ishdf5) { 150577b8e257Sksagiyam #if defined(PETSC_HAVE_HDF5) 150677b8e257Sksagiyam PetscViewerFormat format; 150777b8e257Sksagiyam ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 150877b8e257Sksagiyam if (format == PETSC_VIEWER_HDF5_PETSC || format == PETSC_VIEWER_DEFAULT || format == PETSC_VIEWER_NATIVE) { 150977b8e257Sksagiyam ierr = DMPlexCoordinatesView_HDF5_Internal(dm, viewer);CHKERRQ(ierr); 151077b8e257Sksagiyam } else SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "PetscViewerFormat %s not supported for HDF5 input.", PetscViewerFormats[format]); 151177b8e257Sksagiyam #else 151277b8e257Sksagiyam SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 151377b8e257Sksagiyam #endif 151477b8e257Sksagiyam } 151577b8e257Sksagiyam PetscFunctionReturn(0); 151677b8e257Sksagiyam } 151777b8e257Sksagiyam 1518bd6565f1Sksagiyam /*@ 1519bd6565f1Sksagiyam DMPlexLabelsView - Saves DMPlex labels into a file 1520bd6565f1Sksagiyam 1521bd6565f1Sksagiyam Collective on DM 1522bd6565f1Sksagiyam 1523bd6565f1Sksagiyam Input Parameters: 1524bd6565f1Sksagiyam + dm - The DM whose labels are to be saved 1525bd6565f1Sksagiyam - viewer - The PetscViewer for saving 1526bd6565f1Sksagiyam 1527bd6565f1Sksagiyam Level: advanced 1528bd6565f1Sksagiyam 1529bd6565f1Sksagiyam .seealso: DMView(), DMPlexTopologyView(), DMPlexCoordinatesView(), DMPlexLabelsLoad() 1530bd6565f1Sksagiyam @*/ 1531bd6565f1Sksagiyam PetscErrorCode DMPlexLabelsView(DM dm, PetscViewer viewer) 1532bd6565f1Sksagiyam { 1533bd6565f1Sksagiyam PetscBool ishdf5; 1534bd6565f1Sksagiyam PetscErrorCode ierr; 1535bd6565f1Sksagiyam 1536bd6565f1Sksagiyam PetscFunctionBegin; 1537bd6565f1Sksagiyam PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1538bd6565f1Sksagiyam PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1539bd6565f1Sksagiyam ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 1540bd6565f1Sksagiyam if (ishdf5) { 1541bd6565f1Sksagiyam #if defined(PETSC_HAVE_HDF5) 1542bd6565f1Sksagiyam IS globalPointNumbering; 1543bd6565f1Sksagiyam PetscViewerFormat format; 1544bd6565f1Sksagiyam 1545bd6565f1Sksagiyam ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 1546bd6565f1Sksagiyam if (format == PETSC_VIEWER_HDF5_PETSC || format == PETSC_VIEWER_DEFAULT || format == PETSC_VIEWER_NATIVE) { 1547bd6565f1Sksagiyam ierr = DMPlexCreatePointNumbering(dm, &globalPointNumbering);CHKERRQ(ierr); 1548bd6565f1Sksagiyam ierr = DMPlexLabelsView_HDF5_Internal(dm, globalPointNumbering, viewer);CHKERRQ(ierr); 1549bd6565f1Sksagiyam ierr = ISDestroy(&globalPointNumbering);CHKERRQ(ierr); 1550bd6565f1Sksagiyam } else SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "PetscViewerFormat %s not supported for HDF5 input.", PetscViewerFormats[format]); 1551bd6565f1Sksagiyam #else 1552bd6565f1Sksagiyam SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 1553bd6565f1Sksagiyam #endif 1554bd6565f1Sksagiyam } 1555bd6565f1Sksagiyam PetscFunctionReturn(0); 1556bd6565f1Sksagiyam } 1557bd6565f1Sksagiyam 1558021affd3Sksagiyam /*@ 1559021affd3Sksagiyam DMPlexSectionView - Saves a section associated with a DMPlex 1560021affd3Sksagiyam 1561021affd3Sksagiyam Collective on DM 1562021affd3Sksagiyam 1563021affd3Sksagiyam Input Parameters: 1564021affd3Sksagiyam + dm - The DM that contains the topology on which the section to be saved is defined 1565021affd3Sksagiyam . viewer - The PetscViewer for saving 1566021affd3Sksagiyam - sectiondm - The DM that contains the section to be saved 1567021affd3Sksagiyam 1568021affd3Sksagiyam Level: advanced 1569021affd3Sksagiyam 1570021affd3Sksagiyam Notes: 1571021affd3Sksagiyam 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. 1572021affd3Sksagiyam 1573021affd3Sksagiyam 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. 1574021affd3Sksagiyam 1575021affd3Sksagiyam .seealso: DMView(), DMPlexTopologyView(), DMPlexCoordinatesView(), DMPlexLabelsView(), DMPlexGlobalVectorView(), DMPlexLocalVectorView(), PetscSectionView(), DMPlexSectionLoad() 1576021affd3Sksagiyam @*/ 1577021affd3Sksagiyam PetscErrorCode DMPlexSectionView(DM dm, PetscViewer viewer, DM sectiondm) 1578021affd3Sksagiyam { 1579021affd3Sksagiyam PetscBool ishdf5; 1580021affd3Sksagiyam PetscErrorCode ierr; 1581021affd3Sksagiyam 1582021affd3Sksagiyam PetscFunctionBegin; 1583021affd3Sksagiyam PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1584021affd3Sksagiyam PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1585021affd3Sksagiyam PetscValidHeaderSpecific(sectiondm, DM_CLASSID, 3); 1586021affd3Sksagiyam ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5);CHKERRQ(ierr); 1587021affd3Sksagiyam if (ishdf5) { 1588021affd3Sksagiyam #if defined(PETSC_HAVE_HDF5) 1589021affd3Sksagiyam ierr = DMPlexSectionView_HDF5_Internal(dm, viewer, sectiondm);CHKERRQ(ierr); 1590021affd3Sksagiyam #else 1591021affd3Sksagiyam SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 1592021affd3Sksagiyam #endif 1593021affd3Sksagiyam } 1594021affd3Sksagiyam PetscFunctionReturn(0); 1595021affd3Sksagiyam } 1596021affd3Sksagiyam 15973e97647fSksagiyam /*@ 15983e97647fSksagiyam DMPlexGlobalVectorView - Saves a global vector 15993e97647fSksagiyam 16003e97647fSksagiyam Collective on DM 16013e97647fSksagiyam 16023e97647fSksagiyam Input Parameters: 16033e97647fSksagiyam + dm - The DM that represents the topology 16043e97647fSksagiyam . viewer - The PetscViewer to save data with 16053e97647fSksagiyam . sectiondm - The DM that contains the global section on which vec is defined 16063e97647fSksagiyam - vec - The global vector to be saved 16073e97647fSksagiyam 16083e97647fSksagiyam Level: advanced 16093e97647fSksagiyam 16103e97647fSksagiyam Notes: 16113e97647fSksagiyam 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. 16123e97647fSksagiyam 16133e97647fSksagiyam Typical calling sequence 16143e97647fSksagiyam $ DMCreate(PETSC_COMM_WORLD, &dm); 16153e97647fSksagiyam $ DMSetType(dm, DMPLEX); 16163e97647fSksagiyam $ PetscObjectSetName((PetscObject)dm, "topologydm_name"); 16173e97647fSksagiyam $ DMClone(dm, §iondm); 16183e97647fSksagiyam $ PetscObjectSetName((PetscObject)sectiondm, "sectiondm_name"); 16193e97647fSksagiyam $ PetscSectionCreate(PETSC_COMM_WORLD, §ion); 16203e97647fSksagiyam $ DMPlexGetChart(sectiondm, &pStart, &pEnd); 16213e97647fSksagiyam $ PetscSectionSetChart(section, pStart, pEnd); 16223e97647fSksagiyam $ PetscSectionSetUp(section); 16233e97647fSksagiyam $ DMSetLocalSection(sectiondm, section); 16243e97647fSksagiyam $ PetscSectionDestroy(§ion); 16253e97647fSksagiyam $ DMGetGlobalVector(sectiondm, &vec); 16263e97647fSksagiyam $ PetscObjectSetName((PetscObject)vec, "vec_name"); 16273e97647fSksagiyam $ DMPlexTopologyView(dm, viewer); 16283e97647fSksagiyam $ DMPlexSectionView(dm, viewer, sectiondm); 16293e97647fSksagiyam $ DMPlexGlobalVectorView(dm, viewer, sectiondm, vec); 16303e97647fSksagiyam $ DMRestoreGlobalVector(sectiondm, &vec); 16313e97647fSksagiyam $ DMDestroy(§iondm); 16323e97647fSksagiyam $ DMDestroy(&dm); 16333e97647fSksagiyam 16343e97647fSksagiyam .seealso: DMPlexTopologyView(), DMPlexSectionView(), DMPlexLocalVectorView(), DMPlexGlobalVectorLoad(), DMPlexLocalVectorLoad() 16353e97647fSksagiyam @*/ 16363e97647fSksagiyam PetscErrorCode DMPlexGlobalVectorView(DM dm, PetscViewer viewer, DM sectiondm, Vec vec) 16373e97647fSksagiyam { 16383e97647fSksagiyam PetscBool ishdf5; 16393e97647fSksagiyam PetscErrorCode ierr; 16403e97647fSksagiyam 16413e97647fSksagiyam PetscFunctionBegin; 16423e97647fSksagiyam PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 16433e97647fSksagiyam PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 16443e97647fSksagiyam PetscValidHeaderSpecific(sectiondm, DM_CLASSID, 3); 16453e97647fSksagiyam PetscValidHeaderSpecific(vec, VEC_CLASSID, 4); 16463e97647fSksagiyam /* Check consistency */ 16473e97647fSksagiyam { 16483e97647fSksagiyam PetscSection section; 16493e97647fSksagiyam PetscBool includesConstraints; 16503e97647fSksagiyam PetscInt m, m1; 16513e97647fSksagiyam 16523e97647fSksagiyam ierr = VecGetLocalSize(vec, &m1);CHKERRQ(ierr); 16533e97647fSksagiyam ierr = DMGetGlobalSection(sectiondm, §ion);CHKERRQ(ierr); 16543e97647fSksagiyam ierr = PetscSectionGetIncludesConstraints(section, &includesConstraints);CHKERRQ(ierr); 16553e97647fSksagiyam if (includesConstraints) {ierr = PetscSectionGetStorageSize(section, &m);CHKERRQ(ierr);} 16563e97647fSksagiyam else {ierr = PetscSectionGetConstrainedStorageSize(section, &m);CHKERRQ(ierr);} 16573e97647fSksagiyam if (m1 != m) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Global vector size (%D) != global section storage size (%D)", m1, m); 16583e97647fSksagiyam } 16593e97647fSksagiyam ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 16603e97647fSksagiyam if (ishdf5) { 16613e97647fSksagiyam #if defined(PETSC_HAVE_HDF5) 16623e97647fSksagiyam ierr = DMPlexGlobalVectorView_HDF5_Internal(dm, viewer, sectiondm, vec);CHKERRQ(ierr); 16633e97647fSksagiyam #else 16643e97647fSksagiyam SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 16653e97647fSksagiyam #endif 16663e97647fSksagiyam } 16673e97647fSksagiyam PetscFunctionReturn(0); 16683e97647fSksagiyam } 16693e97647fSksagiyam 16703e97647fSksagiyam /*@ 16713e97647fSksagiyam DMPlexLocalVectorView - Saves a local vector 16723e97647fSksagiyam 16733e97647fSksagiyam Collective on DM 16743e97647fSksagiyam 16753e97647fSksagiyam Input Parameters: 16763e97647fSksagiyam + dm - The DM that represents the topology 16773e97647fSksagiyam . viewer - The PetscViewer to save data with 16783e97647fSksagiyam . sectiondm - The DM that contains the local section on which vec is defined; may be the same as dm 16793e97647fSksagiyam - vec - The local vector to be saved 16803e97647fSksagiyam 16813e97647fSksagiyam Level: advanced 16823e97647fSksagiyam 16833e97647fSksagiyam Notes: 16843e97647fSksagiyam 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. 16853e97647fSksagiyam 16863e97647fSksagiyam Typical calling sequence 16873e97647fSksagiyam $ DMCreate(PETSC_COMM_WORLD, &dm); 16883e97647fSksagiyam $ DMSetType(dm, DMPLEX); 16893e97647fSksagiyam $ PetscObjectSetName((PetscObject)dm, "topologydm_name"); 16903e97647fSksagiyam $ DMClone(dm, §iondm); 16913e97647fSksagiyam $ PetscObjectSetName((PetscObject)sectiondm, "sectiondm_name"); 16923e97647fSksagiyam $ PetscSectionCreate(PETSC_COMM_WORLD, §ion); 16933e97647fSksagiyam $ DMPlexGetChart(sectiondm, &pStart, &pEnd); 16943e97647fSksagiyam $ PetscSectionSetChart(section, pStart, pEnd); 16953e97647fSksagiyam $ PetscSectionSetUp(section); 16963e97647fSksagiyam $ DMSetLocalSection(sectiondm, section); 16973e97647fSksagiyam $ DMGetLocalVector(sectiondm, &vec); 16983e97647fSksagiyam $ PetscObjectSetName((PetscObject)vec, "vec_name"); 16993e97647fSksagiyam $ DMPlexTopologyView(dm, viewer); 17003e97647fSksagiyam $ DMPlexSectionView(dm, viewer, sectiondm); 17013e97647fSksagiyam $ DMPlexLocalVectorView(dm, viewer, sectiondm, vec); 17023e97647fSksagiyam $ DMRestoreLocalVector(sectiondm, &vec); 17033e97647fSksagiyam $ DMDestroy(§iondm); 17043e97647fSksagiyam $ DMDestroy(&dm); 17053e97647fSksagiyam 17063e97647fSksagiyam .seealso: DMPlexTopologyView(), DMPlexSectionView(), DMPlexGlobalVectorView(), DMPlexGlobalVectorLoad(), DMPlexLocalVectorLoad() 17073e97647fSksagiyam @*/ 17083e97647fSksagiyam PetscErrorCode DMPlexLocalVectorView(DM dm, PetscViewer viewer, DM sectiondm, Vec vec) 17093e97647fSksagiyam { 17103e97647fSksagiyam PetscBool ishdf5; 17113e97647fSksagiyam PetscErrorCode ierr; 17123e97647fSksagiyam 17133e97647fSksagiyam PetscFunctionBegin; 17143e97647fSksagiyam PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 17153e97647fSksagiyam PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 17163e97647fSksagiyam PetscValidHeaderSpecific(sectiondm, DM_CLASSID, 3); 17173e97647fSksagiyam PetscValidHeaderSpecific(vec, VEC_CLASSID, 4); 17183e97647fSksagiyam /* Check consistency */ 17193e97647fSksagiyam { 17203e97647fSksagiyam PetscSection section; 17213e97647fSksagiyam PetscBool includesConstraints; 17223e97647fSksagiyam PetscInt m, m1; 17233e97647fSksagiyam 17243e97647fSksagiyam ierr = VecGetLocalSize(vec, &m1);CHKERRQ(ierr); 17253e97647fSksagiyam ierr = DMGetLocalSection(sectiondm, §ion);CHKERRQ(ierr); 17263e97647fSksagiyam ierr = PetscSectionGetIncludesConstraints(section, &includesConstraints);CHKERRQ(ierr); 17273e97647fSksagiyam if (includesConstraints) {ierr = PetscSectionGetStorageSize(section, &m);CHKERRQ(ierr);} 17283e97647fSksagiyam else {ierr = PetscSectionGetConstrainedStorageSize(section, &m);CHKERRQ(ierr);} 17293e97647fSksagiyam if (m1 != m) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Local vector size (%D) != local section storage size (%D)", m1, m); 17303e97647fSksagiyam } 17313e97647fSksagiyam ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 17323e97647fSksagiyam if (ishdf5) { 17333e97647fSksagiyam #if defined(PETSC_HAVE_HDF5) 17343e97647fSksagiyam ierr = DMPlexLocalVectorView_HDF5_Internal(dm, viewer, sectiondm, vec);CHKERRQ(ierr); 17353e97647fSksagiyam #else 17363e97647fSksagiyam SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 17373e97647fSksagiyam #endif 17383e97647fSksagiyam } 17393e97647fSksagiyam PetscFunctionReturn(0); 17403e97647fSksagiyam } 17413e97647fSksagiyam 17422c40f234SMatthew G. Knepley PetscErrorCode DMLoad_Plex(DM dm, PetscViewer viewer) 17432c40f234SMatthew G. Knepley { 1744d4f5a9a0SVaclav Hapla PetscBool ishdf5; 17452c40f234SMatthew G. Knepley PetscErrorCode ierr; 17462c40f234SMatthew G. Knepley 17472c40f234SMatthew G. Knepley PetscFunctionBegin; 17482c40f234SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 17492c40f234SMatthew G. Knepley PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 17502c40f234SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 1751d4f5a9a0SVaclav Hapla if (ishdf5) { 17522c40f234SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 17539c48423bSVaclav Hapla PetscViewerFormat format; 17549c48423bSVaclav Hapla ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 17559c48423bSVaclav Hapla if (format == PETSC_VIEWER_HDF5_XDMF || format == PETSC_VIEWER_HDF5_VIZ) { 17569c48423bSVaclav Hapla ierr = DMPlexLoad_HDF5_Xdmf_Internal(dm, viewer);CHKERRQ(ierr); 1757509517efSVaclav Hapla } else if (format == PETSC_VIEWER_HDF5_PETSC || format == PETSC_VIEWER_DEFAULT || format == PETSC_VIEWER_NATIVE) { 175839d25373SMatthew G. Knepley ierr = DMPlexLoad_HDF5_Internal(dm, viewer);CHKERRQ(ierr); 1759509517efSVaclav Hapla } else SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "PetscViewerFormat %s not supported for HDF5 input.", PetscViewerFormats[format]); 1760b458e8f1SJose E. Roman PetscFunctionReturn(0); 17612c40f234SMatthew G. Knepley #else 17622c40f234SMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 1763552f7358SJed Brown #endif 1764b458e8f1SJose E. Roman } else SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Viewer type %s not yet supported for DMPlex loading", ((PetscObject)viewer)->type_name); 1765552f7358SJed Brown } 1766552f7358SJed Brown 1767ea8e1828Sksagiyam /*@ 1768ea8e1828Sksagiyam DMPlexTopologyLoad - Loads a topology into a DMPlex 1769ea8e1828Sksagiyam 1770ea8e1828Sksagiyam Collective on DM 1771ea8e1828Sksagiyam 1772ea8e1828Sksagiyam Input Parameters: 1773ea8e1828Sksagiyam + dm - The DM into which the topology is loaded 1774ea8e1828Sksagiyam - viewer - The PetscViewer for the saved topology 1775ea8e1828Sksagiyam 1776dec9e869Sksagiyam Output Parameters: 1777f84dd6b4Sksagiyam . 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 1778dec9e869Sksagiyam 1779ea8e1828Sksagiyam Level: advanced 1780ea8e1828Sksagiyam 1781b08ad5deSksagiyam .seealso: DMLoad(), DMPlexCoordinatesLoad(), DMPlexLabelsLoad(), DMView(), PetscViewerHDF5Open(), PetscViewerPushFormat() 1782ea8e1828Sksagiyam @*/ 1783f84dd6b4Sksagiyam PetscErrorCode DMPlexTopologyLoad(DM dm, PetscViewer viewer, PetscSF *globalToLocalPointSF) 1784ea8e1828Sksagiyam { 1785ea8e1828Sksagiyam PetscBool ishdf5; 1786ea8e1828Sksagiyam PetscErrorCode ierr; 1787ea8e1828Sksagiyam 1788ea8e1828Sksagiyam PetscFunctionBegin; 1789ea8e1828Sksagiyam PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1790ea8e1828Sksagiyam PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1791f84dd6b4Sksagiyam if (globalToLocalPointSF) PetscValidPointer(globalToLocalPointSF, 3); 1792ea8e1828Sksagiyam ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 1793ea8e1828Sksagiyam if (ishdf5) { 1794ea8e1828Sksagiyam #if defined(PETSC_HAVE_HDF5) 1795ea8e1828Sksagiyam PetscViewerFormat format; 1796ea8e1828Sksagiyam ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 1797ea8e1828Sksagiyam if (format == PETSC_VIEWER_HDF5_PETSC || format == PETSC_VIEWER_DEFAULT || format == PETSC_VIEWER_NATIVE) { 1798f84dd6b4Sksagiyam ierr = DMPlexTopologyLoad_HDF5_Internal(dm, viewer, globalToLocalPointSF);CHKERRQ(ierr); 1799ea8e1828Sksagiyam } else SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "PetscViewerFormat %s not supported for HDF5 input.", PetscViewerFormats[format]); 1800ea8e1828Sksagiyam #else 1801ea8e1828Sksagiyam SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 1802ea8e1828Sksagiyam #endif 1803ea8e1828Sksagiyam } 1804ea8e1828Sksagiyam PetscFunctionReturn(0); 1805ea8e1828Sksagiyam } 1806ea8e1828Sksagiyam 18073e701f1cSksagiyam /*@ 18083e701f1cSksagiyam DMPlexCoordinatesLoad - Loads coordinates into a DMPlex 18093e701f1cSksagiyam 18103e701f1cSksagiyam Collective on DM 18113e701f1cSksagiyam 18123e701f1cSksagiyam Input Parameters: 18133e701f1cSksagiyam + dm - The DM into which the coordinates are loaded 18143e701f1cSksagiyam - viewer - The PetscViewer for the saved coordinates 18153e701f1cSksagiyam 18163e701f1cSksagiyam Level: advanced 18173e701f1cSksagiyam 1818b08ad5deSksagiyam .seealso: DMLoad(), DMPlexTopologyLoad(), DMPlexLabelsLoad(), DMView(), PetscViewerHDF5Open(), PetscViewerPushFormat() 18193e701f1cSksagiyam @*/ 18203e701f1cSksagiyam PetscErrorCode DMPlexCoordinatesLoad(DM dm, PetscViewer viewer) 18213e701f1cSksagiyam { 18223e701f1cSksagiyam PetscBool ishdf5; 18233e701f1cSksagiyam PetscErrorCode ierr; 18243e701f1cSksagiyam 18253e701f1cSksagiyam PetscFunctionBegin; 18263e701f1cSksagiyam PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 18273e701f1cSksagiyam PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 18283e701f1cSksagiyam ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 18293e701f1cSksagiyam if (ishdf5) { 18303e701f1cSksagiyam #if defined(PETSC_HAVE_HDF5) 18313e701f1cSksagiyam PetscViewerFormat format; 18323e701f1cSksagiyam ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 18333e701f1cSksagiyam if (format == PETSC_VIEWER_HDF5_PETSC || format == PETSC_VIEWER_DEFAULT || format == PETSC_VIEWER_NATIVE) { 18343e701f1cSksagiyam ierr = DMPlexCoordinatesLoad_HDF5_Internal(dm, viewer);CHKERRQ(ierr); 18353e701f1cSksagiyam } else SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "PetscViewerFormat %s not supported for HDF5 input.", PetscViewerFormats[format]); 18363e701f1cSksagiyam #else 18373e701f1cSksagiyam SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 18383e701f1cSksagiyam #endif 18393e701f1cSksagiyam } 18403e701f1cSksagiyam PetscFunctionReturn(0); 18413e701f1cSksagiyam } 18423e701f1cSksagiyam 1843b08ad5deSksagiyam /*@ 1844b08ad5deSksagiyam DMPlexLabelsLoad - Loads labels into a DMPlex 1845b08ad5deSksagiyam 1846b08ad5deSksagiyam Collective on DM 1847b08ad5deSksagiyam 1848b08ad5deSksagiyam Input Parameters: 1849b08ad5deSksagiyam + dm - The DM into which the labels are loaded 1850b08ad5deSksagiyam - viewer - The PetscViewer for the saved labels 1851b08ad5deSksagiyam 1852b08ad5deSksagiyam Level: advanced 1853b08ad5deSksagiyam 1854b08ad5deSksagiyam .seealso: DMLoad(), DMPlexTopologyLoad(), DMPlexCoordinatesLoad(), DMView(), PetscViewerHDF5Open(), PetscViewerPushFormat() 1855b08ad5deSksagiyam @*/ 1856b08ad5deSksagiyam PetscErrorCode DMPlexLabelsLoad(DM dm, PetscViewer viewer) 1857b08ad5deSksagiyam { 1858b08ad5deSksagiyam PetscBool ishdf5; 1859b08ad5deSksagiyam PetscErrorCode ierr; 1860b08ad5deSksagiyam 1861b08ad5deSksagiyam PetscFunctionBegin; 1862b08ad5deSksagiyam PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1863b08ad5deSksagiyam PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1864b08ad5deSksagiyam ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 1865b08ad5deSksagiyam if (ishdf5) { 1866b08ad5deSksagiyam #if defined(PETSC_HAVE_HDF5) 1867b08ad5deSksagiyam PetscViewerFormat format; 1868b08ad5deSksagiyam 1869b08ad5deSksagiyam ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 1870b08ad5deSksagiyam if (format == PETSC_VIEWER_HDF5_PETSC || format == PETSC_VIEWER_DEFAULT || format == PETSC_VIEWER_NATIVE) { 1871b08ad5deSksagiyam ierr = DMPlexLabelsLoad_HDF5_Internal(dm, viewer);CHKERRQ(ierr); 1872b08ad5deSksagiyam } else SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "PetscViewerFormat %s not supported for HDF5 input.", PetscViewerFormats[format]); 1873b08ad5deSksagiyam #else 1874b08ad5deSksagiyam SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 1875b08ad5deSksagiyam #endif 1876b08ad5deSksagiyam } 1877b08ad5deSksagiyam PetscFunctionReturn(0); 1878b08ad5deSksagiyam } 1879b08ad5deSksagiyam 1880f84dd6b4Sksagiyam /*@ 1881f84dd6b4Sksagiyam DMPlexSectionLoad - Loads section into a DMPlex 1882f84dd6b4Sksagiyam 1883f84dd6b4Sksagiyam Collective on DM 1884f84dd6b4Sksagiyam 1885f84dd6b4Sksagiyam Input Parameters: 1886f84dd6b4Sksagiyam + dm - The DM that represents the topology 1887f84dd6b4Sksagiyam . viewer - The PetscViewer that represents the on-disk section (sectionA) 1888f84dd6b4Sksagiyam . sectiondm - The DM into which the on-disk section (sectionA) is migrated 1889f84dd6b4Sksagiyam - globalToLocalPointSF - The SF returned by DMPlexTopologyLoad() when loading dm from viewer 1890f84dd6b4Sksagiyam 1891f84dd6b4Sksagiyam Output Parameters 1892f84dd6b4Sksagiyam + 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) 1893f84dd6b4Sksagiyam - 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) 1894f84dd6b4Sksagiyam 1895f84dd6b4Sksagiyam Level: advanced 1896f84dd6b4Sksagiyam 1897f84dd6b4Sksagiyam Notes: 1898f84dd6b4Sksagiyam 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. 1899f84dd6b4Sksagiyam 1900f84dd6b4Sksagiyam 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. 1901f84dd6b4Sksagiyam 1902f84dd6b4Sksagiyam 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. 1903f84dd6b4Sksagiyam 1904f84dd6b4Sksagiyam Example using 2 processes: 1905f84dd6b4Sksagiyam $ NX (number of points on dm): 4 1906f84dd6b4Sksagiyam $ sectionA : the on-disk section 1907f84dd6b4Sksagiyam $ vecA : a vector associated with sectionA 1908f84dd6b4Sksagiyam $ sectionB : sectiondm's local section constructed in this function 1909f84dd6b4Sksagiyam $ vecB (local) : a vector associated with sectiondm's local section 1910f84dd6b4Sksagiyam $ vecB (global) : a vector associated with sectiondm's global section 1911f84dd6b4Sksagiyam $ 1912f84dd6b4Sksagiyam $ rank 0 rank 1 1913f84dd6b4Sksagiyam $ vecA (global) : [.0 .4 .1 | .2 .3] <- to be loaded in DMPlexGlobalVectorLoad() or DMPlexLocalVectorLoad() 1914f84dd6b4Sksagiyam $ sectionA->atlasOff : 0 2 | 1 <- loaded in PetscSectionLoad() 1915f84dd6b4Sksagiyam $ sectionA->atlasDof : 1 3 | 1 <- loaded in PetscSectionLoad() 1916f84dd6b4Sksagiyam $ sectionA's global point numbers: 0 2 | 3 <- loaded in DMPlexSectionLoad() 1917f84dd6b4Sksagiyam $ [0, NX) : 0 1 | 2 3 <- conceptual partition used in globalToLocalPointSF 1918f84dd6b4Sksagiyam $ sectionB's global point numbers: 0 1 3 | 3 2 <- associated with [0, NX) by globalToLocalPointSF 1919f84dd6b4Sksagiyam $ sectionB->atlasDof : 1 0 1 | 1 3 1920f84dd6b4Sksagiyam $ sectionB->atlasOff (no perm) : 0 1 1 | 0 1 1921f84dd6b4Sksagiyam $ vecB (local) : [.0 .4] | [.4 .1 .2 .3] <- to be constructed by calling DMPlexLocalVectorLoad() with localDofSF 1922f84dd6b4Sksagiyam $ vecB (global) : [.0 .4 | .1 .2 .3] <- to be constructed by calling DMPlexGlobalVectorLoad() with globalDofSF 1923f84dd6b4Sksagiyam $ 1924f84dd6b4Sksagiyam $ where "|" represents a partition of loaded data, and global point 3 is assumed to be owned by rank 0. 1925f84dd6b4Sksagiyam 1926f84dd6b4Sksagiyam .seealso: DMLoad(), DMPlexTopologyLoad(), DMPlexCoordinatesLoad(), DMPlexLabelsLoad(), DMPlexGlobalVectorLoad(), DMPlexLocalVectorLoad(), PetscSectionLoad(), DMPlexSectionView() 1927f84dd6b4Sksagiyam @*/ 1928f84dd6b4Sksagiyam PetscErrorCode DMPlexSectionLoad(DM dm, PetscViewer viewer, DM sectiondm, PetscSF globalToLocalPointSF, PetscSF *globalDofSF, PetscSF *localDofSF) 1929f84dd6b4Sksagiyam { 1930f84dd6b4Sksagiyam PetscBool ishdf5; 1931f84dd6b4Sksagiyam PetscErrorCode ierr; 1932f84dd6b4Sksagiyam 1933f84dd6b4Sksagiyam PetscFunctionBegin; 1934f84dd6b4Sksagiyam PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1935f84dd6b4Sksagiyam PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1936f84dd6b4Sksagiyam PetscValidHeaderSpecific(sectiondm, DM_CLASSID, 3); 1937f84dd6b4Sksagiyam PetscValidHeaderSpecific(globalToLocalPointSF, PETSCSF_CLASSID, 4); 1938f84dd6b4Sksagiyam if (globalDofSF) PetscValidPointer(globalDofSF, 5); 1939f84dd6b4Sksagiyam if (localDofSF) PetscValidPointer(localDofSF, 6); 1940f84dd6b4Sksagiyam ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5);CHKERRQ(ierr); 1941f84dd6b4Sksagiyam if (ishdf5) { 1942f84dd6b4Sksagiyam #if defined(PETSC_HAVE_HDF5) 1943f84dd6b4Sksagiyam ierr = DMPlexSectionLoad_HDF5_Internal(dm, viewer, sectiondm, globalToLocalPointSF, globalDofSF, localDofSF);CHKERRQ(ierr); 1944f84dd6b4Sksagiyam #else 1945f84dd6b4Sksagiyam SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 1946f84dd6b4Sksagiyam #endif 1947f84dd6b4Sksagiyam } 1948f84dd6b4Sksagiyam PetscFunctionReturn(0); 1949f84dd6b4Sksagiyam } 1950f84dd6b4Sksagiyam 19518be3dfe1Sksagiyam /*@ 19528be3dfe1Sksagiyam DMPlexGlobalVectorLoad - Loads on-disk vector data into a global vector 19538be3dfe1Sksagiyam 19548be3dfe1Sksagiyam Collective on DM 19558be3dfe1Sksagiyam 19568be3dfe1Sksagiyam Input Parameters: 19578be3dfe1Sksagiyam + dm - The DM that represents the topology 19588be3dfe1Sksagiyam . viewer - The PetscViewer that represents the on-disk vector data 19598be3dfe1Sksagiyam . sectiondm - The DM that contains the global section on which vec is defined 19608be3dfe1Sksagiyam . sf - The SF that migrates the on-disk vector data into vec 19618be3dfe1Sksagiyam - vec - The global vector to set values of 19628be3dfe1Sksagiyam 19638be3dfe1Sksagiyam Level: advanced 19648be3dfe1Sksagiyam 19658be3dfe1Sksagiyam Notes: 19668be3dfe1Sksagiyam 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. 19678be3dfe1Sksagiyam 19688be3dfe1Sksagiyam Typical calling sequence 19698be3dfe1Sksagiyam $ DMCreate(PETSC_COMM_WORLD, &dm); 19708be3dfe1Sksagiyam $ DMSetType(dm, DMPLEX); 19718be3dfe1Sksagiyam $ PetscObjectSetName((PetscObject)dm, "topologydm_name"); 19728be3dfe1Sksagiyam $ DMPlexTopologyLoad(dm, viewer, &sfX); 19738be3dfe1Sksagiyam $ DMClone(dm, §iondm); 19748be3dfe1Sksagiyam $ PetscObjectSetName((PetscObject)sectiondm, "sectiondm_name"); 19758be3dfe1Sksagiyam $ DMPlexSectionLoad(dm, viewer, sectiondm, sfX, &gsf, NULL); 19768be3dfe1Sksagiyam $ DMGetGlobalVector(sectiondm, &vec); 19778be3dfe1Sksagiyam $ PetscObjectSetName((PetscObject)vec, "vec_name"); 19788be3dfe1Sksagiyam $ DMPlexGlobalVectorLoad(dm, viewer, sectiondm, gsf, vec); 19798be3dfe1Sksagiyam $ DMRestoreGlobalVector(sectiondm, &vec); 19808be3dfe1Sksagiyam $ PetscSFDestroy(&gsf); 19818be3dfe1Sksagiyam $ PetscSFDestroy(&sfX); 19828be3dfe1Sksagiyam $ DMDestroy(§iondm); 19838be3dfe1Sksagiyam $ DMDestroy(&dm); 19848be3dfe1Sksagiyam 19858be3dfe1Sksagiyam .seealso: DMPlexTopologyLoad(), DMPlexSectionLoad(), DMPlexLocalVectorLoad(), DMPlexGlobalVectorView(), DMPlexLocalVectorView() 19868be3dfe1Sksagiyam @*/ 19878be3dfe1Sksagiyam PetscErrorCode DMPlexGlobalVectorLoad(DM dm, PetscViewer viewer, DM sectiondm, PetscSF sf, Vec vec) 19888be3dfe1Sksagiyam { 19898be3dfe1Sksagiyam PetscBool ishdf5; 19908be3dfe1Sksagiyam PetscErrorCode ierr; 19918be3dfe1Sksagiyam 19928be3dfe1Sksagiyam PetscFunctionBegin; 19938be3dfe1Sksagiyam PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 19948be3dfe1Sksagiyam PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 19958be3dfe1Sksagiyam PetscValidHeaderSpecific(sectiondm, DM_CLASSID, 3); 19968be3dfe1Sksagiyam PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 4); 19978be3dfe1Sksagiyam PetscValidHeaderSpecific(vec, VEC_CLASSID, 5); 19988be3dfe1Sksagiyam /* Check consistency */ 19998be3dfe1Sksagiyam { 20008be3dfe1Sksagiyam PetscSection section; 20018be3dfe1Sksagiyam PetscBool includesConstraints; 20028be3dfe1Sksagiyam PetscInt m, m1; 20038be3dfe1Sksagiyam 20048be3dfe1Sksagiyam ierr = VecGetLocalSize(vec, &m1);CHKERRQ(ierr); 20058be3dfe1Sksagiyam ierr = DMGetGlobalSection(sectiondm, §ion);CHKERRQ(ierr); 20068be3dfe1Sksagiyam ierr = PetscSectionGetIncludesConstraints(section, &includesConstraints);CHKERRQ(ierr); 20078be3dfe1Sksagiyam if (includesConstraints) {ierr = PetscSectionGetStorageSize(section, &m);CHKERRQ(ierr);} 20088be3dfe1Sksagiyam else {ierr = PetscSectionGetConstrainedStorageSize(section, &m);CHKERRQ(ierr);} 20098be3dfe1Sksagiyam if (m1 != m) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Global vector size (%D) != global section storage size (%D)", m1, m); 20108be3dfe1Sksagiyam } 20118be3dfe1Sksagiyam ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5);CHKERRQ(ierr); 20128be3dfe1Sksagiyam if (ishdf5) { 20138be3dfe1Sksagiyam #if defined(PETSC_HAVE_HDF5) 20148be3dfe1Sksagiyam ierr = DMPlexVecLoad_HDF5_Internal(dm, viewer, sectiondm, sf, vec);CHKERRQ(ierr); 20158be3dfe1Sksagiyam #else 20168be3dfe1Sksagiyam SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 20178be3dfe1Sksagiyam #endif 20188be3dfe1Sksagiyam } 20198be3dfe1Sksagiyam PetscFunctionReturn(0); 20208be3dfe1Sksagiyam } 20218be3dfe1Sksagiyam 20228be3dfe1Sksagiyam /*@ 20238be3dfe1Sksagiyam DMPlexLocalVectorLoad - Loads on-disk vector data into a local vector 20248be3dfe1Sksagiyam 20258be3dfe1Sksagiyam Collective on DM 20268be3dfe1Sksagiyam 20278be3dfe1Sksagiyam Input Parameters: 20288be3dfe1Sksagiyam + dm - The DM that represents the topology 20298be3dfe1Sksagiyam . viewer - The PetscViewer that represents the on-disk vector data 20308be3dfe1Sksagiyam . sectiondm - The DM that contains the local section on which vec is defined 20318be3dfe1Sksagiyam . sf - The SF that migrates the on-disk vector data into vec 20328be3dfe1Sksagiyam - vec - The local vector to set values of 20338be3dfe1Sksagiyam 20348be3dfe1Sksagiyam Level: advanced 20358be3dfe1Sksagiyam 20368be3dfe1Sksagiyam Notes: 20378be3dfe1Sksagiyam 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. 20388be3dfe1Sksagiyam 20398be3dfe1Sksagiyam Typical calling sequence 20408be3dfe1Sksagiyam $ DMCreate(PETSC_COMM_WORLD, &dm); 20418be3dfe1Sksagiyam $ DMSetType(dm, DMPLEX); 20428be3dfe1Sksagiyam $ PetscObjectSetName((PetscObject)dm, "topologydm_name"); 20438be3dfe1Sksagiyam $ DMPlexTopologyLoad(dm, viewer, &sfX); 20448be3dfe1Sksagiyam $ DMClone(dm, §iondm); 20458be3dfe1Sksagiyam $ PetscObjectSetName((PetscObject)sectiondm, "sectiondm_name"); 20468be3dfe1Sksagiyam $ DMPlexSectionLoad(dm, viewer, sectiondm, sfX, NULL, &lsf); 20478be3dfe1Sksagiyam $ DMGetLocalVector(sectiondm, &vec); 20488be3dfe1Sksagiyam $ PetscObjectSetName((PetscObject)vec, "vec_name"); 20498be3dfe1Sksagiyam $ DMPlexLocalVectorLoad(dm, viewer, sectiondm, lsf, vec); 20508be3dfe1Sksagiyam $ DMRestoreLocalVector(sectiondm, &vec); 20518be3dfe1Sksagiyam $ PetscSFDestroy(&lsf); 20528be3dfe1Sksagiyam $ PetscSFDestroy(&sfX); 20538be3dfe1Sksagiyam $ DMDestroy(§iondm); 20548be3dfe1Sksagiyam $ DMDestroy(&dm); 20558be3dfe1Sksagiyam 20568be3dfe1Sksagiyam .seealso: DMPlexTopologyLoad(), DMPlexSectionLoad(), DMPlexGlobalVectorLoad(), DMPlexGlobalVectorView(), DMPlexLocalVectorView() 20578be3dfe1Sksagiyam @*/ 20588be3dfe1Sksagiyam PetscErrorCode DMPlexLocalVectorLoad(DM dm, PetscViewer viewer, DM sectiondm, PetscSF sf, Vec vec) 20598be3dfe1Sksagiyam { 20608be3dfe1Sksagiyam PetscBool ishdf5; 20618be3dfe1Sksagiyam PetscErrorCode ierr; 20628be3dfe1Sksagiyam 20638be3dfe1Sksagiyam PetscFunctionBegin; 20648be3dfe1Sksagiyam PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 20658be3dfe1Sksagiyam PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 20668be3dfe1Sksagiyam PetscValidHeaderSpecific(sectiondm, DM_CLASSID, 3); 20678be3dfe1Sksagiyam PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 4); 20688be3dfe1Sksagiyam PetscValidHeaderSpecific(vec, VEC_CLASSID, 5); 20698be3dfe1Sksagiyam /* Check consistency */ 20708be3dfe1Sksagiyam { 20718be3dfe1Sksagiyam PetscSection section; 20728be3dfe1Sksagiyam PetscBool includesConstraints; 20738be3dfe1Sksagiyam PetscInt m, m1; 20748be3dfe1Sksagiyam 20758be3dfe1Sksagiyam ierr = VecGetLocalSize(vec, &m1);CHKERRQ(ierr); 20768be3dfe1Sksagiyam ierr = DMGetLocalSection(sectiondm, §ion);CHKERRQ(ierr); 20778be3dfe1Sksagiyam ierr = PetscSectionGetIncludesConstraints(section, &includesConstraints);CHKERRQ(ierr); 20788be3dfe1Sksagiyam if (includesConstraints) {ierr = PetscSectionGetStorageSize(section, &m);CHKERRQ(ierr);} 20798be3dfe1Sksagiyam else {ierr = PetscSectionGetConstrainedStorageSize(section, &m);CHKERRQ(ierr);} 20808be3dfe1Sksagiyam if (m1 != m) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Local vector size (%D) != local section storage size (%D)", m1, m); 20818be3dfe1Sksagiyam } 20828be3dfe1Sksagiyam ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5);CHKERRQ(ierr); 20838be3dfe1Sksagiyam if (ishdf5) { 20848be3dfe1Sksagiyam #if defined(PETSC_HAVE_HDF5) 20858be3dfe1Sksagiyam ierr = DMPlexVecLoad_HDF5_Internal(dm, viewer, sectiondm, sf, vec);CHKERRQ(ierr); 20868be3dfe1Sksagiyam #else 20878be3dfe1Sksagiyam SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 20888be3dfe1Sksagiyam #endif 20898be3dfe1Sksagiyam } 20908be3dfe1Sksagiyam PetscFunctionReturn(0); 20918be3dfe1Sksagiyam } 20928be3dfe1Sksagiyam 2093552f7358SJed Brown PetscErrorCode DMDestroy_Plex(DM dm) 2094552f7358SJed Brown { 2095552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2096552f7358SJed Brown PetscErrorCode ierr; 2097552f7358SJed Brown 2098552f7358SJed Brown PetscFunctionBegin; 20998135c375SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)dm,"DMSetUpGLVisViewer_C",NULL);CHKERRQ(ierr); 21008135c375SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)dm,"DMPlexInsertBoundaryValues_C", NULL);CHKERRQ(ierr); 210128d58a37SPierre Jolivet ierr = PetscObjectComposeFunction((PetscObject)dm,"DMCreateNeumannOverlap_C", NULL);CHKERRQ(ierr); 21021eb70e55SToby Isaac ierr = PetscObjectComposeFunction((PetscObject)dm,"DMInterpolateSolution_C", NULL);CHKERRQ(ierr); 21030d644c17SKarl Rupp if (--mesh->refct > 0) PetscFunctionReturn(0); 2104552f7358SJed Brown ierr = PetscSectionDestroy(&mesh->coneSection);CHKERRQ(ierr); 2105552f7358SJed Brown ierr = PetscFree(mesh->cones);CHKERRQ(ierr); 2106552f7358SJed Brown ierr = PetscFree(mesh->coneOrientations);CHKERRQ(ierr); 2107552f7358SJed Brown ierr = PetscSectionDestroy(&mesh->supportSection);CHKERRQ(ierr); 2108be36d101SStefano Zampini ierr = PetscSectionDestroy(&mesh->subdomainSection);CHKERRQ(ierr); 2109552f7358SJed Brown ierr = PetscFree(mesh->supports);CHKERRQ(ierr); 2110552f7358SJed Brown ierr = PetscFree(mesh->facesTmp);CHKERRQ(ierr); 2111d9deefdfSMatthew G. Knepley ierr = PetscFree(mesh->tetgenOpts);CHKERRQ(ierr); 2112d9deefdfSMatthew G. Knepley ierr = PetscFree(mesh->triangleOpts);CHKERRQ(ierr); 211377623264SMatthew G. Knepley ierr = PetscPartitionerDestroy(&mesh->partitioner);CHKERRQ(ierr); 2114a89082eeSMatthew G Knepley ierr = DMLabelDestroy(&mesh->subpointMap);CHKERRQ(ierr); 211597d8846cSMatthew Knepley ierr = ISDestroy(&mesh->subpointIS);CHKERRQ(ierr); 2116552f7358SJed Brown ierr = ISDestroy(&mesh->globalVertexNumbers);CHKERRQ(ierr); 2117552f7358SJed Brown ierr = ISDestroy(&mesh->globalCellNumbers);CHKERRQ(ierr); 2118a68b90caSToby Isaac ierr = PetscSectionDestroy(&mesh->anchorSection);CHKERRQ(ierr); 2119a68b90caSToby Isaac ierr = ISDestroy(&mesh->anchorIS);CHKERRQ(ierr); 2120d961a43aSToby Isaac ierr = PetscSectionDestroy(&mesh->parentSection);CHKERRQ(ierr); 2121d961a43aSToby Isaac ierr = PetscFree(mesh->parents);CHKERRQ(ierr); 2122d961a43aSToby Isaac ierr = PetscFree(mesh->childIDs);CHKERRQ(ierr); 2123d961a43aSToby Isaac ierr = PetscSectionDestroy(&mesh->childSection);CHKERRQ(ierr); 2124d961a43aSToby Isaac ierr = PetscFree(mesh->children);CHKERRQ(ierr); 2125d6a7ad0dSToby Isaac ierr = DMDestroy(&mesh->referenceTree);CHKERRQ(ierr); 2126fec49543SMatthew G. Knepley ierr = PetscGridHashDestroy(&mesh->lbox);CHKERRQ(ierr); 21270a19bb7dSprj- ierr = PetscFree(mesh->neighbors);CHKERRQ(ierr); 2128552f7358SJed Brown /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */ 2129552f7358SJed Brown ierr = PetscFree(mesh);CHKERRQ(ierr); 2130552f7358SJed Brown PetscFunctionReturn(0); 2131552f7358SJed Brown } 2132552f7358SJed Brown 2133b412c318SBarry Smith PetscErrorCode DMCreateMatrix_Plex(DM dm, Mat *J) 2134552f7358SJed Brown { 21358d1174e4SMatthew G. Knepley PetscSection sectionGlobal; 2136acd755d7SMatthew G. Knepley PetscInt bs = -1, mbs; 2137552f7358SJed Brown PetscInt localSize; 2138837628f4SStefano Zampini PetscBool isShell, isBlock, isSeqBlock, isMPIBlock, isSymBlock, isSymSeqBlock, isSymMPIBlock, isMatIS; 2139552f7358SJed Brown PetscErrorCode ierr; 2140b412c318SBarry Smith MatType mtype; 21411428887cSShri Abhyankar ISLocalToGlobalMapping ltog; 2142552f7358SJed Brown 2143552f7358SJed Brown PetscFunctionBegin; 2144607a6623SBarry Smith ierr = MatInitializePackage();CHKERRQ(ierr); 2145b412c318SBarry Smith mtype = dm->mattype; 2146e87a4003SBarry Smith ierr = DMGetGlobalSection(dm, §ionGlobal);CHKERRQ(ierr); 2147552f7358SJed Brown /* ierr = PetscSectionGetStorageSize(sectionGlobal, &localSize);CHKERRQ(ierr); */ 2148552f7358SJed Brown ierr = PetscSectionGetConstrainedStorageSize(sectionGlobal, &localSize);CHKERRQ(ierr); 214982f516ccSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)dm), J);CHKERRQ(ierr); 2150552f7358SJed Brown ierr = MatSetSizes(*J, localSize, localSize, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 2151552f7358SJed Brown ierr = MatSetType(*J, mtype);CHKERRQ(ierr); 2152552f7358SJed Brown ierr = MatSetFromOptions(*J);CHKERRQ(ierr); 2153acd755d7SMatthew G. Knepley ierr = MatGetBlockSize(*J, &mbs);CHKERRQ(ierr); 2154acd755d7SMatthew G. Knepley if (mbs > 1) bs = mbs; 2155552f7358SJed Brown ierr = PetscStrcmp(mtype, MATSHELL, &isShell);CHKERRQ(ierr); 2156552f7358SJed Brown ierr = PetscStrcmp(mtype, MATBAIJ, &isBlock);CHKERRQ(ierr); 2157552f7358SJed Brown ierr = PetscStrcmp(mtype, MATSEQBAIJ, &isSeqBlock);CHKERRQ(ierr); 2158552f7358SJed Brown ierr = PetscStrcmp(mtype, MATMPIBAIJ, &isMPIBlock);CHKERRQ(ierr); 2159552f7358SJed Brown ierr = PetscStrcmp(mtype, MATSBAIJ, &isSymBlock);CHKERRQ(ierr); 2160552f7358SJed Brown ierr = PetscStrcmp(mtype, MATSEQSBAIJ, &isSymSeqBlock);CHKERRQ(ierr); 2161552f7358SJed Brown ierr = PetscStrcmp(mtype, MATMPISBAIJ, &isSymMPIBlock);CHKERRQ(ierr); 2162837628f4SStefano Zampini ierr = PetscStrcmp(mtype, MATIS, &isMatIS);CHKERRQ(ierr); 2163552f7358SJed Brown if (!isShell) { 2164be36d101SStefano Zampini PetscSection subSection; 2165837628f4SStefano Zampini PetscBool fillMatrix = (PetscBool)(!dm->prealloc_only && !isMatIS); 21660be3e97aSMatthew G. Knepley PetscInt *dnz, *onz, *dnzu, *onzu, bsLocal[2], bsMinMax[2], *ltogidx, lsize; 2167fad22124SMatthew G Knepley PetscInt pStart, pEnd, p, dof, cdof; 2168552f7358SJed Brown 216900140cc3SStefano Zampini /* Set localtoglobalmapping on the matrix for MatSetValuesLocal() to work (it also creates the local matrices in case of MATIS) */ 2170be36d101SStefano Zampini if (isMatIS) { /* need a different l2g map than the one computed by DMGetLocalToGlobalMapping */ 2171be36d101SStefano Zampini PetscSection section; 2172be36d101SStefano Zampini PetscInt size; 2173be36d101SStefano Zampini 217492fd8e1eSJed Brown ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr); 2175be36d101SStefano Zampini ierr = PetscSectionGetStorageSize(section, &size);CHKERRQ(ierr); 2176be36d101SStefano Zampini ierr = PetscMalloc1(size,<ogidx);CHKERRQ(ierr); 2177be36d101SStefano Zampini ierr = DMPlexGetSubdomainSection(dm, &subSection);CHKERRQ(ierr); 2178be36d101SStefano Zampini } else { 217900140cc3SStefano Zampini ierr = DMGetLocalToGlobalMapping(dm,<og);CHKERRQ(ierr); 2180be36d101SStefano Zampini } 2181552f7358SJed Brown ierr = PetscSectionGetChart(sectionGlobal, &pStart, &pEnd);CHKERRQ(ierr); 2182be36d101SStefano Zampini for (p = pStart, lsize = 0; p < pEnd; ++p) { 2183a9d99c84SMatthew G. Knepley PetscInt bdof; 2184a9d99c84SMatthew G. Knepley 2185552f7358SJed Brown ierr = PetscSectionGetDof(sectionGlobal, p, &dof);CHKERRQ(ierr); 2186fad22124SMatthew G Knepley ierr = PetscSectionGetConstraintDof(sectionGlobal, p, &cdof);CHKERRQ(ierr); 21871d17a0a3SMatthew G. Knepley dof = dof < 0 ? -(dof+1) : dof; 21881d17a0a3SMatthew G. Knepley bdof = cdof && (dof-cdof) ? 1 : dof; 21891d17a0a3SMatthew G. Knepley if (dof) { 21901d17a0a3SMatthew G. Knepley if (bs < 0) {bs = bdof;} 2191be36d101SStefano Zampini else if (bs != bdof) {bs = 1; if (!isMatIS) break;} 2192be36d101SStefano Zampini } 2193be36d101SStefano Zampini if (isMatIS) { 2194be36d101SStefano Zampini PetscInt loff,c,off; 2195be36d101SStefano Zampini ierr = PetscSectionGetOffset(subSection, p, &loff);CHKERRQ(ierr); 2196be36d101SStefano Zampini ierr = PetscSectionGetOffset(sectionGlobal, p, &off);CHKERRQ(ierr); 2197be36d101SStefano Zampini for (c = 0; c < dof-cdof; ++c, ++lsize) ltogidx[loff+c] = off > -1 ? off+c : -(off+1)+c; 2198552f7358SJed Brown } 21992a28c762SMatthew G Knepley } 22002a28c762SMatthew G Knepley /* Must have same blocksize on all procs (some might have no points) */ 22010be3e97aSMatthew G. Knepley bsLocal[0] = bs < 0 ? PETSC_MAX_INT : bs; bsLocal[1] = bs; 22020be3e97aSMatthew G. Knepley ierr = PetscGlobalMinMaxInt(PetscObjectComm((PetscObject) dm), bsLocal, bsMinMax);CHKERRQ(ierr); 22030be3e97aSMatthew G. Knepley if (bsMinMax[0] != bsMinMax[1]) {bs = 1;} 22040be3e97aSMatthew G. Knepley else {bs = bsMinMax[0];} 22056fd5c86aSStefano Zampini bs = PetscMax(1,bs); 22066fd5c86aSStefano Zampini if (isMatIS) { /* Must reduce indices by blocksize */ 22074fa26246SMatthew G. Knepley PetscInt l; 22086fd5c86aSStefano Zampini 22096fd5c86aSStefano Zampini lsize = lsize/bs; 22106fd5c86aSStefano Zampini if (bs > 1) for (l = 0; l < lsize; ++l) ltogidx[l] = ltogidx[l*bs]/bs; 22114fa26246SMatthew G. Knepley ierr = ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)dm), bs, lsize, ltogidx, PETSC_OWN_POINTER, <og);CHKERRQ(ierr); 2212be36d101SStefano Zampini } 2213be36d101SStefano Zampini ierr = MatSetLocalToGlobalMapping(*J,ltog,ltog);CHKERRQ(ierr); 2214be36d101SStefano Zampini if (isMatIS) { 2215be36d101SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(<og);CHKERRQ(ierr); 2216be36d101SStefano Zampini } 22171795a4d1SJed Brown ierr = PetscCalloc4(localSize/bs, &dnz, localSize/bs, &onz, localSize/bs, &dnzu, localSize/bs, &onzu);CHKERRQ(ierr); 22188d1174e4SMatthew G. Knepley ierr = DMPlexPreallocateOperator(dm, bs, dnz, onz, dnzu, onzu, *J, fillMatrix);CHKERRQ(ierr); 2219552f7358SJed Brown ierr = PetscFree4(dnz, onz, dnzu, onzu);CHKERRQ(ierr); 2220552f7358SJed Brown } 2221b1f74addSMatthew G. Knepley ierr = MatSetDM(*J, dm);CHKERRQ(ierr); 2222552f7358SJed Brown PetscFunctionReturn(0); 2223552f7358SJed Brown } 2224552f7358SJed Brown 22257cd05799SMatthew G. Knepley /*@ 2226a8f00d21SMatthew G. Knepley DMPlexGetSubdomainSection - Returns the section associated with the subdomain 2227be36d101SStefano Zampini 2228be36d101SStefano Zampini Not collective 2229be36d101SStefano Zampini 2230be36d101SStefano Zampini Input Parameter: 2231be36d101SStefano Zampini . mesh - The DMPlex 2232be36d101SStefano Zampini 2233be36d101SStefano Zampini Output Parameters: 2234be36d101SStefano Zampini . subsection - The subdomain section 2235be36d101SStefano Zampini 2236be36d101SStefano Zampini Level: developer 2237be36d101SStefano Zampini 2238be36d101SStefano Zampini .seealso: 22397cd05799SMatthew G. Knepley @*/ 2240be36d101SStefano Zampini PetscErrorCode DMPlexGetSubdomainSection(DM dm, PetscSection *subsection) 2241be36d101SStefano Zampini { 2242be36d101SStefano Zampini DM_Plex *mesh = (DM_Plex*) dm->data; 2243be36d101SStefano Zampini PetscErrorCode ierr; 2244be36d101SStefano Zampini 2245be36d101SStefano Zampini PetscFunctionBegin; 2246be36d101SStefano Zampini PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2247be36d101SStefano Zampini if (!mesh->subdomainSection) { 2248be36d101SStefano Zampini PetscSection section; 2249be36d101SStefano Zampini PetscSF sf; 2250be36d101SStefano Zampini 2251be36d101SStefano Zampini ierr = PetscSFCreate(PETSC_COMM_SELF,&sf);CHKERRQ(ierr); 225292fd8e1eSJed Brown ierr = DMGetLocalSection(dm,§ion);CHKERRQ(ierr); 2253be36d101SStefano Zampini ierr = PetscSectionCreateGlobalSection(section,sf,PETSC_FALSE,PETSC_TRUE,&mesh->subdomainSection);CHKERRQ(ierr); 2254be36d101SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 2255be36d101SStefano Zampini } 2256be36d101SStefano Zampini *subsection = mesh->subdomainSection; 2257be36d101SStefano Zampini PetscFunctionReturn(0); 2258be36d101SStefano Zampini } 2259be36d101SStefano Zampini 2260552f7358SJed Brown /*@ 2261552f7358SJed Brown DMPlexGetChart - Return the interval for all mesh points [pStart, pEnd) 2262552f7358SJed Brown 2263552f7358SJed Brown Not collective 2264552f7358SJed Brown 2265552f7358SJed Brown Input Parameter: 2266552f7358SJed Brown . mesh - The DMPlex 2267552f7358SJed Brown 2268552f7358SJed Brown Output Parameters: 2269552f7358SJed Brown + pStart - The first mesh point 2270552f7358SJed Brown - pEnd - The upper bound for mesh points 2271552f7358SJed Brown 2272552f7358SJed Brown Level: beginner 2273552f7358SJed Brown 2274552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetChart() 2275552f7358SJed Brown @*/ 2276552f7358SJed Brown PetscErrorCode DMPlexGetChart(DM dm, PetscInt *pStart, PetscInt *pEnd) 2277552f7358SJed Brown { 2278552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2279552f7358SJed Brown PetscErrorCode ierr; 2280552f7358SJed Brown 2281552f7358SJed Brown PetscFunctionBegin; 2282552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2283552f7358SJed Brown ierr = PetscSectionGetChart(mesh->coneSection, pStart, pEnd);CHKERRQ(ierr); 2284552f7358SJed Brown PetscFunctionReturn(0); 2285552f7358SJed Brown } 2286552f7358SJed Brown 2287552f7358SJed Brown /*@ 2288552f7358SJed Brown DMPlexSetChart - Set the interval for all mesh points [pStart, pEnd) 2289552f7358SJed Brown 2290552f7358SJed Brown Not collective 2291552f7358SJed Brown 2292552f7358SJed Brown Input Parameters: 2293552f7358SJed Brown + mesh - The DMPlex 2294552f7358SJed Brown . pStart - The first mesh point 2295552f7358SJed Brown - pEnd - The upper bound for mesh points 2296552f7358SJed Brown 2297552f7358SJed Brown Output Parameters: 2298552f7358SJed Brown 2299552f7358SJed Brown Level: beginner 2300552f7358SJed Brown 2301552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetChart() 2302552f7358SJed Brown @*/ 2303552f7358SJed Brown PetscErrorCode DMPlexSetChart(DM dm, PetscInt pStart, PetscInt pEnd) 2304552f7358SJed Brown { 2305552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2306552f7358SJed Brown PetscErrorCode ierr; 2307552f7358SJed Brown 2308552f7358SJed Brown PetscFunctionBegin; 2309552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2310552f7358SJed Brown ierr = PetscSectionSetChart(mesh->coneSection, pStart, pEnd);CHKERRQ(ierr); 2311552f7358SJed Brown ierr = PetscSectionSetChart(mesh->supportSection, pStart, pEnd);CHKERRQ(ierr); 2312552f7358SJed Brown PetscFunctionReturn(0); 2313552f7358SJed Brown } 2314552f7358SJed Brown 2315552f7358SJed Brown /*@ 2316eaf898f9SPatrick Sanan DMPlexGetConeSize - Return the number of in-edges for this point in the DAG 2317552f7358SJed Brown 2318552f7358SJed Brown Not collective 2319552f7358SJed Brown 2320552f7358SJed Brown Input Parameters: 2321552f7358SJed Brown + mesh - The DMPlex 2322eaf898f9SPatrick Sanan - p - The point, which must lie in the chart set with DMPlexSetChart() 2323552f7358SJed Brown 2324552f7358SJed Brown Output Parameter: 2325552f7358SJed Brown . size - The cone size for point p 2326552f7358SJed Brown 2327552f7358SJed Brown Level: beginner 2328552f7358SJed Brown 2329552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetConeSize(), DMPlexSetChart() 2330552f7358SJed Brown @*/ 2331552f7358SJed Brown PetscErrorCode DMPlexGetConeSize(DM dm, PetscInt p, PetscInt *size) 2332552f7358SJed Brown { 2333552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2334552f7358SJed Brown PetscErrorCode ierr; 2335552f7358SJed Brown 2336552f7358SJed Brown PetscFunctionBegin; 2337552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2338552f7358SJed Brown PetscValidPointer(size, 3); 2339552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, size);CHKERRQ(ierr); 2340552f7358SJed Brown PetscFunctionReturn(0); 2341552f7358SJed Brown } 2342552f7358SJed Brown 2343552f7358SJed Brown /*@ 2344eaf898f9SPatrick Sanan DMPlexSetConeSize - Set the number of in-edges for this point in the DAG 2345552f7358SJed Brown 2346552f7358SJed Brown Not collective 2347552f7358SJed Brown 2348552f7358SJed Brown Input Parameters: 2349552f7358SJed Brown + mesh - The DMPlex 2350eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 2351552f7358SJed Brown - size - The cone size for point p 2352552f7358SJed Brown 2353552f7358SJed Brown Output Parameter: 2354552f7358SJed Brown 2355552f7358SJed Brown Note: 2356552f7358SJed Brown This should be called after DMPlexSetChart(). 2357552f7358SJed Brown 2358552f7358SJed Brown Level: beginner 2359552f7358SJed Brown 2360552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetConeSize(), DMPlexSetChart() 2361552f7358SJed Brown @*/ 2362552f7358SJed Brown PetscErrorCode DMPlexSetConeSize(DM dm, PetscInt p, PetscInt size) 2363552f7358SJed Brown { 2364552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2365552f7358SJed Brown PetscErrorCode ierr; 2366552f7358SJed Brown 2367552f7358SJed Brown PetscFunctionBegin; 2368552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2369552f7358SJed Brown ierr = PetscSectionSetDof(mesh->coneSection, p, size);CHKERRQ(ierr); 23700d644c17SKarl Rupp 2371552f7358SJed Brown mesh->maxConeSize = PetscMax(mesh->maxConeSize, size); 2372552f7358SJed Brown PetscFunctionReturn(0); 2373552f7358SJed Brown } 2374552f7358SJed Brown 2375f5a469b9SMatthew G. Knepley /*@ 2376eaf898f9SPatrick Sanan DMPlexAddConeSize - Add the given number of in-edges to this point in the DAG 2377f5a469b9SMatthew G. Knepley 2378f5a469b9SMatthew G. Knepley Not collective 2379f5a469b9SMatthew G. Knepley 2380f5a469b9SMatthew G. Knepley Input Parameters: 2381f5a469b9SMatthew G. Knepley + mesh - The DMPlex 2382eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 2383f5a469b9SMatthew G. Knepley - size - The additional cone size for point p 2384f5a469b9SMatthew G. Knepley 2385f5a469b9SMatthew G. Knepley Output Parameter: 2386f5a469b9SMatthew G. Knepley 2387f5a469b9SMatthew G. Knepley Note: 2388f5a469b9SMatthew G. Knepley This should be called after DMPlexSetChart(). 2389f5a469b9SMatthew G. Knepley 2390f5a469b9SMatthew G. Knepley Level: beginner 2391f5a469b9SMatthew G. Knepley 2392f5a469b9SMatthew G. Knepley .seealso: DMPlexCreate(), DMPlexSetConeSize(), DMPlexGetConeSize(), DMPlexSetChart() 2393f5a469b9SMatthew G. Knepley @*/ 2394f5a469b9SMatthew G. Knepley PetscErrorCode DMPlexAddConeSize(DM dm, PetscInt p, PetscInt size) 2395f5a469b9SMatthew G. Knepley { 2396f5a469b9SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 2397f5a469b9SMatthew G. Knepley PetscInt csize; 2398f5a469b9SMatthew G. Knepley PetscErrorCode ierr; 2399f5a469b9SMatthew G. Knepley 2400f5a469b9SMatthew G. Knepley PetscFunctionBegin; 2401f5a469b9SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2402f5a469b9SMatthew G. Knepley ierr = PetscSectionAddDof(mesh->coneSection, p, size);CHKERRQ(ierr); 2403f5a469b9SMatthew G. Knepley ierr = PetscSectionGetDof(mesh->coneSection, p, &csize);CHKERRQ(ierr); 2404f5a469b9SMatthew G. Knepley 2405f5a469b9SMatthew G. Knepley mesh->maxConeSize = PetscMax(mesh->maxConeSize, csize); 2406f5a469b9SMatthew G. Knepley PetscFunctionReturn(0); 2407f5a469b9SMatthew G. Knepley } 2408f5a469b9SMatthew G. Knepley 2409552f7358SJed Brown /*@C 2410eaf898f9SPatrick Sanan DMPlexGetCone - Return the points on the in-edges for this point in the DAG 2411552f7358SJed Brown 2412552f7358SJed Brown Not collective 2413552f7358SJed Brown 2414552f7358SJed Brown Input Parameters: 2415833c876bSVaclav Hapla + dm - The DMPlex 2416eaf898f9SPatrick Sanan - p - The point, which must lie in the chart set with DMPlexSetChart() 2417552f7358SJed Brown 2418552f7358SJed Brown Output Parameter: 2419552f7358SJed Brown . cone - An array of points which are on the in-edges for point p 2420552f7358SJed Brown 2421552f7358SJed Brown Level: beginner 2422552f7358SJed Brown 24233813dfbdSMatthew G Knepley Fortran Notes: 24243813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 24253813dfbdSMatthew G Knepley include petsc.h90 in your code. 2426922102d1SVaclav Hapla You must also call DMPlexRestoreCone() after you finish using the returned array. 2427922102d1SVaclav Hapla DMPlexRestoreCone() is not needed/available in C. 24283813dfbdSMatthew G Knepley 2429e45f02b0SMatthew G. Knepley .seealso: DMPlexGetConeSize(), DMPlexSetCone(), DMPlexGetConeTuple(), DMPlexSetChart() 2430552f7358SJed Brown @*/ 2431552f7358SJed Brown PetscErrorCode DMPlexGetCone(DM dm, PetscInt p, const PetscInt *cone[]) 2432552f7358SJed Brown { 2433552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2434552f7358SJed Brown PetscInt off; 2435552f7358SJed Brown PetscErrorCode ierr; 2436552f7358SJed Brown 2437552f7358SJed Brown PetscFunctionBegin; 2438552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2439552f7358SJed Brown PetscValidPointer(cone, 3); 2440552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 2441552f7358SJed Brown *cone = &mesh->cones[off]; 2442552f7358SJed Brown PetscFunctionReturn(0); 2443552f7358SJed Brown } 2444552f7358SJed Brown 24450ce7577fSVaclav Hapla /*@C 24460ce7577fSVaclav Hapla DMPlexGetConeTuple - Return the points on the in-edges of several points in the DAG 24470ce7577fSVaclav Hapla 24480ce7577fSVaclav Hapla Not collective 24490ce7577fSVaclav Hapla 24500ce7577fSVaclav Hapla Input Parameters: 24510ce7577fSVaclav Hapla + dm - The DMPlex 24520ce7577fSVaclav Hapla - p - The IS of points, which must lie in the chart set with DMPlexSetChart() 24530ce7577fSVaclav Hapla 24540ce7577fSVaclav Hapla Output Parameter: 24550ce7577fSVaclav Hapla + pConesSection - PetscSection describing the layout of pCones 24560ce7577fSVaclav Hapla - pCones - An array of points which are on the in-edges for the point set p 24570ce7577fSVaclav Hapla 24580ce7577fSVaclav Hapla Level: intermediate 24590ce7577fSVaclav Hapla 2460d4636a37SVaclav Hapla .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexGetConeRecursive(), DMPlexSetChart() 24610ce7577fSVaclav Hapla @*/ 24620ce7577fSVaclav Hapla PetscErrorCode DMPlexGetConeTuple(DM dm, IS p, PetscSection *pConesSection, IS *pCones) 24630ce7577fSVaclav Hapla { 24640ce7577fSVaclav Hapla PetscSection cs, newcs; 24650ce7577fSVaclav Hapla PetscInt *cones; 24660ce7577fSVaclav Hapla PetscInt *newarr=NULL; 24670ce7577fSVaclav Hapla PetscInt n; 24680ce7577fSVaclav Hapla PetscErrorCode ierr; 24690ce7577fSVaclav Hapla 24700ce7577fSVaclav Hapla PetscFunctionBegin; 24710ce7577fSVaclav Hapla ierr = DMPlexGetCones(dm, &cones);CHKERRQ(ierr); 24720ce7577fSVaclav Hapla ierr = DMPlexGetConeSection(dm, &cs);CHKERRQ(ierr); 24730ce7577fSVaclav Hapla ierr = PetscSectionExtractDofsFromArray(cs, MPIU_INT, cones, p, &newcs, pCones ? ((void**)&newarr) : NULL);CHKERRQ(ierr); 24740ce7577fSVaclav Hapla if (pConesSection) *pConesSection = newcs; 24750ce7577fSVaclav Hapla if (pCones) { 24760ce7577fSVaclav Hapla ierr = PetscSectionGetStorageSize(newcs, &n);CHKERRQ(ierr); 24770ce7577fSVaclav Hapla ierr = ISCreateGeneral(PetscObjectComm((PetscObject)p), n, newarr, PETSC_OWN_POINTER, pCones);CHKERRQ(ierr); 24780ce7577fSVaclav Hapla } 24790ce7577fSVaclav Hapla PetscFunctionReturn(0); 24800ce7577fSVaclav Hapla } 24810ce7577fSVaclav Hapla 2482af9eab45SVaclav Hapla /*@ 2483af9eab45SVaclav Hapla DMPlexGetConeRecursiveVertices - Expand each given point into its cone points and do that recursively until we end up just with vertices. 2484d4636a37SVaclav Hapla 2485d4636a37SVaclav Hapla Not collective 2486d4636a37SVaclav Hapla 2487d4636a37SVaclav Hapla Input Parameters: 2488d4636a37SVaclav Hapla + dm - The DMPlex 2489af9eab45SVaclav Hapla - points - The IS of points, which must lie in the chart set with DMPlexSetChart() 2490d4636a37SVaclav Hapla 2491d4636a37SVaclav Hapla Output Parameter: 2492af9eab45SVaclav Hapla . expandedPoints - An array of vertices recursively expanded from input points 2493d4636a37SVaclav Hapla 2494d4636a37SVaclav Hapla Level: advanced 2495d4636a37SVaclav Hapla 2496af9eab45SVaclav Hapla Notes: 2497af9eab45SVaclav Hapla Like DMPlexGetConeRecursive but returns only the 0-depth IS (i.e. vertices only) and no sections. 2498af9eab45SVaclav Hapla There is no corresponding Restore function, just call ISDestroy() on the returned IS to deallocate. 2499af9eab45SVaclav Hapla 2500af9eab45SVaclav Hapla .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexGetConeTuple(), DMPlexGetConeRecursive(), DMPlexRestoreConeRecursive(), DMPlexGetDepth() 2501d4636a37SVaclav Hapla @*/ 2502af9eab45SVaclav Hapla PetscErrorCode DMPlexGetConeRecursiveVertices(DM dm, IS points, IS *expandedPoints) 2503d4636a37SVaclav Hapla { 2504af9eab45SVaclav Hapla IS *expandedPointsAll; 2505af9eab45SVaclav Hapla PetscInt depth; 2506d4636a37SVaclav Hapla PetscErrorCode ierr; 2507d4636a37SVaclav Hapla 2508d4636a37SVaclav Hapla PetscFunctionBegin; 2509af9eab45SVaclav Hapla PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2510af9eab45SVaclav Hapla PetscValidHeaderSpecific(points, IS_CLASSID, 2); 2511af9eab45SVaclav Hapla PetscValidPointer(expandedPoints, 3); 2512af9eab45SVaclav Hapla ierr = DMPlexGetConeRecursive(dm, points, &depth, &expandedPointsAll, NULL);CHKERRQ(ierr); 2513af9eab45SVaclav Hapla *expandedPoints = expandedPointsAll[0]; 25141e1ea65dSPierre Jolivet ierr = PetscObjectReference((PetscObject)expandedPointsAll[0]);CHKERRQ(ierr); 2515af9eab45SVaclav Hapla ierr = DMPlexRestoreConeRecursive(dm, points, &depth, &expandedPointsAll, NULL);CHKERRQ(ierr); 2516af9eab45SVaclav Hapla PetscFunctionReturn(0); 2517af9eab45SVaclav Hapla } 2518af9eab45SVaclav Hapla 2519af9eab45SVaclav Hapla /*@ 2520af9eab45SVaclav 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). 2521af9eab45SVaclav Hapla 2522af9eab45SVaclav Hapla Not collective 2523af9eab45SVaclav Hapla 2524af9eab45SVaclav Hapla Input Parameters: 2525af9eab45SVaclav Hapla + dm - The DMPlex 2526af9eab45SVaclav Hapla - points - The IS of points, which must lie in the chart set with DMPlexSetChart() 2527af9eab45SVaclav Hapla 2528af9eab45SVaclav Hapla Output Parameter: 2529af9eab45SVaclav Hapla + depth - (optional) Size of the output arrays, equal to DMPlex depth, returned by DMPlexGetDepth() 2530af9eab45SVaclav Hapla . expandedPoints - (optional) An array of index sets with recursively expanded cones 2531af9eab45SVaclav Hapla - sections - (optional) An array of sections which describe mappings from points to their cone points 2532af9eab45SVaclav Hapla 2533af9eab45SVaclav Hapla Level: advanced 2534af9eab45SVaclav Hapla 2535af9eab45SVaclav Hapla Notes: 2536af9eab45SVaclav Hapla Like DMPlexGetConeTuple() but recursive. 2537af9eab45SVaclav Hapla 2538af9eab45SVaclav 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. 2539af9eab45SVaclav Hapla For example, for d=0 it contains only vertices, for d=1 it can contain vertices and edges, etc. 2540af9eab45SVaclav Hapla 2541af9eab45SVaclav 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: 2542af9eab45SVaclav Hapla (1) DAG points in expandedPoints[d+1] with depth d+1 to their cone points in expandedPoints[d]; 2543af9eab45SVaclav Hapla (2) DAG points in expandedPoints[d+1] with depth in [0,d] to the same points in expandedPoints[d]. 2544af9eab45SVaclav Hapla 2545af9eab45SVaclav Hapla .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexGetConeTuple(), DMPlexRestoreConeRecursive(), DMPlexGetConeRecursiveVertices(), DMPlexGetDepth() 2546af9eab45SVaclav Hapla @*/ 2547af9eab45SVaclav Hapla PetscErrorCode DMPlexGetConeRecursive(DM dm, IS points, PetscInt *depth, IS *expandedPoints[], PetscSection *sections[]) 2548af9eab45SVaclav Hapla { 2549af9eab45SVaclav Hapla const PetscInt *arr0=NULL, *cone=NULL; 2550af9eab45SVaclav Hapla PetscInt *arr=NULL, *newarr=NULL; 2551af9eab45SVaclav Hapla PetscInt d, depth_, i, n, newn, cn, co, start, end; 2552af9eab45SVaclav Hapla IS *expandedPoints_; 2553af9eab45SVaclav Hapla PetscSection *sections_; 2554af9eab45SVaclav Hapla PetscErrorCode ierr; 2555af9eab45SVaclav Hapla 2556af9eab45SVaclav Hapla PetscFunctionBegin; 2557af9eab45SVaclav Hapla PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2558af9eab45SVaclav Hapla PetscValidHeaderSpecific(points, IS_CLASSID, 2); 2559af9eab45SVaclav Hapla if (depth) PetscValidIntPointer(depth, 3); 2560af9eab45SVaclav Hapla if (expandedPoints) PetscValidPointer(expandedPoints, 4); 2561af9eab45SVaclav Hapla if (sections) PetscValidPointer(sections, 5); 2562af9eab45SVaclav Hapla ierr = ISGetLocalSize(points, &n);CHKERRQ(ierr); 2563af9eab45SVaclav Hapla ierr = ISGetIndices(points, &arr0);CHKERRQ(ierr); 2564af9eab45SVaclav Hapla ierr = DMPlexGetDepth(dm, &depth_);CHKERRQ(ierr); 2565af9eab45SVaclav Hapla ierr = PetscCalloc1(depth_, &expandedPoints_);CHKERRQ(ierr); 2566af9eab45SVaclav Hapla ierr = PetscCalloc1(depth_, §ions_);CHKERRQ(ierr); 2567af9eab45SVaclav Hapla arr = (PetscInt*) arr0; /* this is ok because first generation of arr is not modified */ 2568af9eab45SVaclav Hapla for (d=depth_-1; d>=0; d--) { 2569af9eab45SVaclav Hapla ierr = PetscSectionCreate(PETSC_COMM_SELF, §ions_[d]);CHKERRQ(ierr); 2570af9eab45SVaclav Hapla ierr = PetscSectionSetChart(sections_[d], 0, n);CHKERRQ(ierr); 2571af9eab45SVaclav Hapla for (i=0; i<n; i++) { 2572af9eab45SVaclav Hapla ierr = DMPlexGetDepthStratum(dm, d+1, &start, &end);CHKERRQ(ierr); 2573af9eab45SVaclav Hapla if (arr[i] >= start && arr[i] < end) { 2574af9eab45SVaclav Hapla ierr = DMPlexGetConeSize(dm, arr[i], &cn);CHKERRQ(ierr); 2575af9eab45SVaclav Hapla ierr = PetscSectionSetDof(sections_[d], i, cn);CHKERRQ(ierr); 2576af9eab45SVaclav Hapla } else { 2577af9eab45SVaclav Hapla ierr = PetscSectionSetDof(sections_[d], i, 1);CHKERRQ(ierr); 2578af9eab45SVaclav Hapla } 2579af9eab45SVaclav Hapla } 2580af9eab45SVaclav Hapla ierr = PetscSectionSetUp(sections_[d]);CHKERRQ(ierr); 2581af9eab45SVaclav Hapla ierr = PetscSectionGetStorageSize(sections_[d], &newn);CHKERRQ(ierr); 2582af9eab45SVaclav Hapla ierr = PetscMalloc1(newn, &newarr);CHKERRQ(ierr); 2583af9eab45SVaclav Hapla for (i=0; i<n; i++) { 2584af9eab45SVaclav Hapla ierr = PetscSectionGetDof(sections_[d], i, &cn);CHKERRQ(ierr); 2585af9eab45SVaclav Hapla ierr = PetscSectionGetOffset(sections_[d], i, &co);CHKERRQ(ierr); 2586af9eab45SVaclav Hapla if (cn > 1) { 2587af9eab45SVaclav Hapla ierr = DMPlexGetCone(dm, arr[i], &cone);CHKERRQ(ierr); 2588af9eab45SVaclav Hapla ierr = PetscMemcpy(&newarr[co], cone, cn*sizeof(PetscInt));CHKERRQ(ierr); 2589af9eab45SVaclav Hapla } else { 2590af9eab45SVaclav Hapla newarr[co] = arr[i]; 2591af9eab45SVaclav Hapla } 2592af9eab45SVaclav Hapla } 2593af9eab45SVaclav Hapla ierr = ISCreateGeneral(PETSC_COMM_SELF, newn, newarr, PETSC_OWN_POINTER, &expandedPoints_[d]);CHKERRQ(ierr); 2594af9eab45SVaclav Hapla arr = newarr; 2595af9eab45SVaclav Hapla n = newn; 2596af9eab45SVaclav Hapla } 2597ba2698f1SMatthew G. Knepley ierr = ISRestoreIndices(points, &arr0);CHKERRQ(ierr); 2598af9eab45SVaclav Hapla *depth = depth_; 2599af9eab45SVaclav Hapla if (expandedPoints) *expandedPoints = expandedPoints_; 2600af9eab45SVaclav Hapla else { 2601af9eab45SVaclav Hapla for (d=0; d<depth_; d++) {ierr = ISDestroy(&expandedPoints_[d]);CHKERRQ(ierr);} 2602af9eab45SVaclav Hapla ierr = PetscFree(expandedPoints_);CHKERRQ(ierr); 2603af9eab45SVaclav Hapla } 2604af9eab45SVaclav Hapla if (sections) *sections = sections_; 2605af9eab45SVaclav Hapla else { 2606af9eab45SVaclav Hapla for (d=0; d<depth_; d++) {ierr = PetscSectionDestroy(§ions_[d]);CHKERRQ(ierr);} 2607af9eab45SVaclav Hapla ierr = PetscFree(sections_);CHKERRQ(ierr); 2608af9eab45SVaclav Hapla } 2609af9eab45SVaclav Hapla PetscFunctionReturn(0); 2610af9eab45SVaclav Hapla } 2611af9eab45SVaclav Hapla 2612af9eab45SVaclav Hapla /*@ 2613af9eab45SVaclav Hapla DMPlexRestoreConeRecursive - Deallocates arrays created by DMPlexGetConeRecursive 2614af9eab45SVaclav Hapla 2615af9eab45SVaclav Hapla Not collective 2616af9eab45SVaclav Hapla 2617af9eab45SVaclav Hapla Input Parameters: 2618af9eab45SVaclav Hapla + dm - The DMPlex 2619af9eab45SVaclav Hapla - points - The IS of points, which must lie in the chart set with DMPlexSetChart() 2620af9eab45SVaclav Hapla 2621af9eab45SVaclav Hapla Output Parameter: 2622af9eab45SVaclav Hapla + depth - (optional) Size of the output arrays, equal to DMPlex depth, returned by DMPlexGetDepth() 2623af9eab45SVaclav Hapla . expandedPoints - (optional) An array of recursively expanded cones 2624af9eab45SVaclav Hapla - sections - (optional) An array of sections which describe mappings from points to their cone points 2625af9eab45SVaclav Hapla 2626af9eab45SVaclav Hapla Level: advanced 2627af9eab45SVaclav Hapla 2628af9eab45SVaclav Hapla Notes: 2629af9eab45SVaclav Hapla See DMPlexGetConeRecursive() for details. 2630af9eab45SVaclav Hapla 2631af9eab45SVaclav Hapla .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexGetConeTuple(), DMPlexGetConeRecursive(), DMPlexGetConeRecursiveVertices(), DMPlexGetDepth() 2632af9eab45SVaclav Hapla @*/ 2633af9eab45SVaclav Hapla PetscErrorCode DMPlexRestoreConeRecursive(DM dm, IS points, PetscInt *depth, IS *expandedPoints[], PetscSection *sections[]) 2634af9eab45SVaclav Hapla { 2635af9eab45SVaclav Hapla PetscInt d, depth_; 2636af9eab45SVaclav Hapla PetscErrorCode ierr; 2637af9eab45SVaclav Hapla 2638af9eab45SVaclav Hapla PetscFunctionBegin; 2639af9eab45SVaclav Hapla ierr = DMPlexGetDepth(dm, &depth_);CHKERRQ(ierr); 2640af9eab45SVaclav Hapla if (depth && *depth != depth_) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "depth changed since last call to DMPlexGetConeRecursive"); 2641af9eab45SVaclav Hapla if (depth) *depth = 0; 2642af9eab45SVaclav Hapla if (expandedPoints) { 2643af9eab45SVaclav Hapla for (d=0; d<depth_; d++) {ierr = ISDestroy(&((*expandedPoints)[d]));CHKERRQ(ierr);} 2644af9eab45SVaclav Hapla ierr = PetscFree(*expandedPoints);CHKERRQ(ierr); 2645af9eab45SVaclav Hapla } 2646af9eab45SVaclav Hapla if (sections) { 2647af9eab45SVaclav Hapla for (d=0; d<depth_; d++) {ierr = PetscSectionDestroy(&((*sections)[d]));CHKERRQ(ierr);} 2648af9eab45SVaclav Hapla ierr = PetscFree(*sections);CHKERRQ(ierr); 2649af9eab45SVaclav Hapla } 2650d4636a37SVaclav Hapla PetscFunctionReturn(0); 2651d4636a37SVaclav Hapla } 2652d4636a37SVaclav Hapla 2653552f7358SJed Brown /*@ 265492371b87SBarry 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 2655552f7358SJed Brown 2656552f7358SJed Brown Not collective 2657552f7358SJed Brown 2658552f7358SJed Brown Input Parameters: 2659552f7358SJed Brown + mesh - The DMPlex 2660eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 2661552f7358SJed Brown - cone - An array of points which are on the in-edges for point p 2662552f7358SJed Brown 2663552f7358SJed Brown Output Parameter: 2664552f7358SJed Brown 2665552f7358SJed Brown Note: 2666552f7358SJed Brown This should be called after all calls to DMPlexSetConeSize() and DMSetUp(). 2667552f7358SJed Brown 266892371b87SBarry Smith Developer Note: Why not call this DMPlexSetCover() 266992371b87SBarry Smith 2670552f7358SJed Brown Level: beginner 2671552f7358SJed Brown 267292371b87SBarry Smith .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexSetChart(), DMPlexSetConeSize(), DMSetUp(), DMPlexSetSupport(), DMPlexSetSupportSize() 2673552f7358SJed Brown @*/ 2674552f7358SJed Brown PetscErrorCode DMPlexSetCone(DM dm, PetscInt p, const PetscInt cone[]) 2675552f7358SJed Brown { 2676552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2677552f7358SJed Brown PetscInt pStart, pEnd; 2678552f7358SJed Brown PetscInt dof, off, c; 2679552f7358SJed Brown PetscErrorCode ierr; 2680552f7358SJed Brown 2681552f7358SJed Brown PetscFunctionBegin; 2682552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2683552f7358SJed Brown ierr = PetscSectionGetChart(mesh->coneSection, &pStart, &pEnd);CHKERRQ(ierr); 2684552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 2685552f7358SJed Brown if (dof) PetscValidPointer(cone, 3); 2686552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 268782f516ccSBarry 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); 2688552f7358SJed Brown for (c = 0; c < dof; ++c) { 268982f516ccSBarry 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); 2690552f7358SJed Brown mesh->cones[off+c] = cone[c]; 2691552f7358SJed Brown } 2692552f7358SJed Brown PetscFunctionReturn(0); 2693552f7358SJed Brown } 2694552f7358SJed Brown 2695552f7358SJed Brown /*@C 2696eaf898f9SPatrick Sanan DMPlexGetConeOrientation - Return the orientations on the in-edges for this point in the DAG 2697552f7358SJed Brown 2698552f7358SJed Brown Not collective 2699552f7358SJed Brown 2700552f7358SJed Brown Input Parameters: 2701552f7358SJed Brown + mesh - The DMPlex 2702eaf898f9SPatrick Sanan - p - The point, which must lie in the chart set with DMPlexSetChart() 2703552f7358SJed Brown 2704552f7358SJed Brown Output Parameter: 2705552f7358SJed Brown . coneOrientation - An array of orientations which are on the in-edges for point p. An orientation is an 2706552f7358SJed Brown integer giving the prescription for cone traversal. If it is negative, the cone is 2707552f7358SJed Brown traversed in the opposite direction. Its value 'o', or if negative '-(o+1)', gives 2708552f7358SJed Brown the index of the cone point on which to start. 2709552f7358SJed Brown 2710552f7358SJed Brown Level: beginner 2711552f7358SJed Brown 27123813dfbdSMatthew G Knepley Fortran Notes: 27133813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 27143813dfbdSMatthew G Knepley include petsc.h90 in your code. 27153b12b3d8SVaclav Hapla You must also call DMPlexRestoreConeOrientation() after you finish using the returned array. 2716922102d1SVaclav Hapla DMPlexRestoreConeOrientation() is not needed/available in C. 27173813dfbdSMatthew G Knepley 2718552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexSetCone(), DMPlexSetChart() 2719552f7358SJed Brown @*/ 2720552f7358SJed Brown PetscErrorCode DMPlexGetConeOrientation(DM dm, PetscInt p, const PetscInt *coneOrientation[]) 2721552f7358SJed Brown { 2722552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2723552f7358SJed Brown PetscInt off; 2724552f7358SJed Brown PetscErrorCode ierr; 2725552f7358SJed Brown 2726552f7358SJed Brown PetscFunctionBegin; 2727552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 272876bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 2729552f7358SJed Brown PetscInt dof; 2730552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 2731552f7358SJed Brown if (dof) PetscValidPointer(coneOrientation, 3); 2732552f7358SJed Brown } 2733552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 27340d644c17SKarl Rupp 2735552f7358SJed Brown *coneOrientation = &mesh->coneOrientations[off]; 2736552f7358SJed Brown PetscFunctionReturn(0); 2737552f7358SJed Brown } 2738552f7358SJed Brown 2739552f7358SJed Brown /*@ 2740eaf898f9SPatrick Sanan DMPlexSetConeOrientation - Set the orientations on the in-edges for this point in the DAG 2741552f7358SJed Brown 2742552f7358SJed Brown Not collective 2743552f7358SJed Brown 2744552f7358SJed Brown Input Parameters: 2745552f7358SJed Brown + mesh - The DMPlex 2746eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 2747552f7358SJed Brown - coneOrientation - An array of orientations which are on the in-edges for point p. An orientation is an 2748552f7358SJed Brown integer giving the prescription for cone traversal. If it is negative, the cone is 2749552f7358SJed Brown traversed in the opposite direction. Its value 'o', or if negative '-(o+1)', gives 2750552f7358SJed Brown the index of the cone point on which to start. 2751552f7358SJed Brown 2752552f7358SJed Brown Output Parameter: 2753552f7358SJed Brown 2754552f7358SJed Brown Note: 2755552f7358SJed Brown This should be called after all calls to DMPlexSetConeSize() and DMSetUp(). 2756552f7358SJed Brown 2757552f7358SJed Brown Level: beginner 2758552f7358SJed Brown 2759552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetConeOrientation(), DMPlexSetCone(), DMPlexSetChart(), DMPlexSetConeSize(), DMSetUp() 2760552f7358SJed Brown @*/ 2761552f7358SJed Brown PetscErrorCode DMPlexSetConeOrientation(DM dm, PetscInt p, const PetscInt coneOrientation[]) 2762552f7358SJed Brown { 2763552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2764552f7358SJed Brown PetscInt pStart, pEnd; 2765552f7358SJed Brown PetscInt dof, off, c; 2766552f7358SJed Brown PetscErrorCode ierr; 2767552f7358SJed Brown 2768552f7358SJed Brown PetscFunctionBegin; 2769552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2770552f7358SJed Brown ierr = PetscSectionGetChart(mesh->coneSection, &pStart, &pEnd);CHKERRQ(ierr); 2771552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 2772552f7358SJed Brown if (dof) PetscValidPointer(coneOrientation, 3); 2773552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 277482f516ccSBarry 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); 2775552f7358SJed Brown for (c = 0; c < dof; ++c) { 2776552f7358SJed Brown PetscInt cdof, o = coneOrientation[c]; 2777552f7358SJed Brown 2778552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, mesh->cones[off+c], &cdof);CHKERRQ(ierr); 277982f516ccSBarry 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); 2780552f7358SJed Brown mesh->coneOrientations[off+c] = o; 2781552f7358SJed Brown } 2782552f7358SJed Brown PetscFunctionReturn(0); 2783552f7358SJed Brown } 2784552f7358SJed Brown 27857cd05799SMatthew G. Knepley /*@ 2786eaf898f9SPatrick Sanan DMPlexInsertCone - Insert a point into the in-edges for the point p in the DAG 27877cd05799SMatthew G. Knepley 27887cd05799SMatthew G. Knepley Not collective 27897cd05799SMatthew G. Knepley 27907cd05799SMatthew G. Knepley Input Parameters: 27917cd05799SMatthew G. Knepley + mesh - The DMPlex 2792eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 27937cd05799SMatthew G. Knepley . conePos - The local index in the cone where the point should be put 27947cd05799SMatthew G. Knepley - conePoint - The mesh point to insert 27957cd05799SMatthew G. Knepley 27967cd05799SMatthew G. Knepley Level: beginner 27977cd05799SMatthew G. Knepley 27987cd05799SMatthew G. Knepley .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexSetChart(), DMPlexSetConeSize(), DMSetUp() 27997cd05799SMatthew G. Knepley @*/ 2800552f7358SJed Brown PetscErrorCode DMPlexInsertCone(DM dm, PetscInt p, PetscInt conePos, PetscInt conePoint) 2801552f7358SJed Brown { 2802552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2803552f7358SJed Brown PetscInt pStart, pEnd; 2804552f7358SJed Brown PetscInt dof, off; 2805552f7358SJed Brown PetscErrorCode ierr; 2806552f7358SJed Brown 2807552f7358SJed Brown PetscFunctionBegin; 2808552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2809552f7358SJed Brown ierr = PetscSectionGetChart(mesh->coneSection, &pStart, &pEnd);CHKERRQ(ierr); 281082f516ccSBarry 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); 281182f516ccSBarry 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); 281277c88f5bSMatthew G Knepley ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 281377c88f5bSMatthew G Knepley ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 281477c88f5bSMatthew 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); 2815552f7358SJed Brown mesh->cones[off+conePos] = conePoint; 2816552f7358SJed Brown PetscFunctionReturn(0); 2817552f7358SJed Brown } 2818552f7358SJed Brown 28197cd05799SMatthew G. Knepley /*@ 2820eaf898f9SPatrick Sanan DMPlexInsertConeOrientation - Insert a point orientation for the in-edge for the point p in the DAG 28217cd05799SMatthew G. Knepley 28227cd05799SMatthew G. Knepley Not collective 28237cd05799SMatthew G. Knepley 28247cd05799SMatthew G. Knepley Input Parameters: 28257cd05799SMatthew G. Knepley + mesh - The DMPlex 2826eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 28277cd05799SMatthew G. Knepley . conePos - The local index in the cone where the point should be put 28287cd05799SMatthew G. Knepley - coneOrientation - The point orientation to insert 28297cd05799SMatthew G. Knepley 28307cd05799SMatthew G. Knepley Level: beginner 28317cd05799SMatthew G. Knepley 28327cd05799SMatthew G. Knepley .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexSetChart(), DMPlexSetConeSize(), DMSetUp() 28337cd05799SMatthew G. Knepley @*/ 283477c88f5bSMatthew G Knepley PetscErrorCode DMPlexInsertConeOrientation(DM dm, PetscInt p, PetscInt conePos, PetscInt coneOrientation) 283577c88f5bSMatthew G Knepley { 283677c88f5bSMatthew G Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 283777c88f5bSMatthew G Knepley PetscInt pStart, pEnd; 283877c88f5bSMatthew G Knepley PetscInt dof, off; 283977c88f5bSMatthew G Knepley PetscErrorCode ierr; 284077c88f5bSMatthew G Knepley 284177c88f5bSMatthew G Knepley PetscFunctionBegin; 284277c88f5bSMatthew G Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 284377c88f5bSMatthew G Knepley ierr = PetscSectionGetChart(mesh->coneSection, &pStart, &pEnd);CHKERRQ(ierr); 284477c88f5bSMatthew 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); 284577c88f5bSMatthew G Knepley ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 284677c88f5bSMatthew G Knepley ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 284777c88f5bSMatthew 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); 284877c88f5bSMatthew G Knepley mesh->coneOrientations[off+conePos] = coneOrientation; 284977c88f5bSMatthew G Knepley PetscFunctionReturn(0); 285077c88f5bSMatthew G Knepley } 285177c88f5bSMatthew G Knepley 2852552f7358SJed Brown /*@ 2853eaf898f9SPatrick Sanan DMPlexGetSupportSize - Return the number of out-edges for this point in the DAG 2854552f7358SJed Brown 2855552f7358SJed Brown Not collective 2856552f7358SJed Brown 2857552f7358SJed Brown Input Parameters: 2858552f7358SJed Brown + mesh - The DMPlex 2859eaf898f9SPatrick Sanan - p - The point, which must lie in the chart set with DMPlexSetChart() 2860552f7358SJed Brown 2861552f7358SJed Brown Output Parameter: 2862552f7358SJed Brown . size - The support size for point p 2863552f7358SJed Brown 2864552f7358SJed Brown Level: beginner 2865552f7358SJed Brown 2866552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetConeSize(), DMPlexSetChart(), DMPlexGetConeSize() 2867552f7358SJed Brown @*/ 2868552f7358SJed Brown PetscErrorCode DMPlexGetSupportSize(DM dm, PetscInt p, PetscInt *size) 2869552f7358SJed Brown { 2870552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2871552f7358SJed Brown PetscErrorCode ierr; 2872552f7358SJed Brown 2873552f7358SJed Brown PetscFunctionBegin; 2874552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2875552f7358SJed Brown PetscValidPointer(size, 3); 2876552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, size);CHKERRQ(ierr); 2877552f7358SJed Brown PetscFunctionReturn(0); 2878552f7358SJed Brown } 2879552f7358SJed Brown 2880552f7358SJed Brown /*@ 2881eaf898f9SPatrick Sanan DMPlexSetSupportSize - Set the number of out-edges for this point in the DAG 2882552f7358SJed Brown 2883552f7358SJed Brown Not collective 2884552f7358SJed Brown 2885552f7358SJed Brown Input Parameters: 2886552f7358SJed Brown + mesh - The DMPlex 2887eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 2888552f7358SJed Brown - size - The support size for point p 2889552f7358SJed Brown 2890552f7358SJed Brown Output Parameter: 2891552f7358SJed Brown 2892552f7358SJed Brown Note: 2893552f7358SJed Brown This should be called after DMPlexSetChart(). 2894552f7358SJed Brown 2895552f7358SJed Brown Level: beginner 2896552f7358SJed Brown 2897552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexGetSupportSize(), DMPlexSetChart() 2898552f7358SJed Brown @*/ 2899552f7358SJed Brown PetscErrorCode DMPlexSetSupportSize(DM dm, PetscInt p, PetscInt size) 2900552f7358SJed Brown { 2901552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2902552f7358SJed Brown PetscErrorCode ierr; 2903552f7358SJed Brown 2904552f7358SJed Brown PetscFunctionBegin; 2905552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2906552f7358SJed Brown ierr = PetscSectionSetDof(mesh->supportSection, p, size);CHKERRQ(ierr); 29070d644c17SKarl Rupp 2908552f7358SJed Brown mesh->maxSupportSize = PetscMax(mesh->maxSupportSize, size); 2909552f7358SJed Brown PetscFunctionReturn(0); 2910552f7358SJed Brown } 2911552f7358SJed Brown 2912552f7358SJed Brown /*@C 2913eaf898f9SPatrick Sanan DMPlexGetSupport - Return the points on the out-edges for this point in the DAG 2914552f7358SJed Brown 2915552f7358SJed Brown Not collective 2916552f7358SJed Brown 2917552f7358SJed Brown Input Parameters: 2918552f7358SJed Brown + mesh - The DMPlex 2919eaf898f9SPatrick Sanan - p - The point, which must lie in the chart set with DMPlexSetChart() 2920552f7358SJed Brown 2921552f7358SJed Brown Output Parameter: 2922552f7358SJed Brown . support - An array of points which are on the out-edges for point p 2923552f7358SJed Brown 2924552f7358SJed Brown Level: beginner 2925552f7358SJed Brown 29263813dfbdSMatthew G Knepley Fortran Notes: 29273813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 29283813dfbdSMatthew G Knepley include petsc.h90 in your code. 29293b12b3d8SVaclav Hapla You must also call DMPlexRestoreSupport() after you finish using the returned array. 2930922102d1SVaclav Hapla DMPlexRestoreSupport() is not needed/available in C. 29313813dfbdSMatthew G Knepley 2932e45f02b0SMatthew G. Knepley .seealso: DMPlexGetSupportSize(), DMPlexSetSupport(), DMPlexGetCone(), DMPlexSetChart() 2933552f7358SJed Brown @*/ 2934552f7358SJed Brown PetscErrorCode DMPlexGetSupport(DM dm, PetscInt p, const PetscInt *support[]) 2935552f7358SJed Brown { 2936552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2937552f7358SJed Brown PetscInt off; 2938552f7358SJed Brown PetscErrorCode ierr; 2939552f7358SJed Brown 2940552f7358SJed Brown PetscFunctionBegin; 2941552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2942552f7358SJed Brown PetscValidPointer(support, 3); 2943552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, p, &off);CHKERRQ(ierr); 2944552f7358SJed Brown *support = &mesh->supports[off]; 2945552f7358SJed Brown PetscFunctionReturn(0); 2946552f7358SJed Brown } 2947552f7358SJed Brown 2948552f7358SJed Brown /*@ 294992371b87SBarry 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 2950552f7358SJed Brown 2951552f7358SJed Brown Not collective 2952552f7358SJed Brown 2953552f7358SJed Brown Input Parameters: 2954552f7358SJed Brown + mesh - The DMPlex 2955eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 295692371b87SBarry Smith - support - An array of points which are on the out-edges for point p 2957552f7358SJed Brown 2958552f7358SJed Brown Output Parameter: 2959552f7358SJed Brown 2960552f7358SJed Brown Note: 2961552f7358SJed Brown This should be called after all calls to DMPlexSetSupportSize() and DMSetUp(). 2962552f7358SJed Brown 2963552f7358SJed Brown Level: beginner 2964552f7358SJed Brown 296592371b87SBarry Smith .seealso: DMPlexSetCone(), DMPlexSetConeSize(), DMPlexCreate(), DMPlexGetSupport(), DMPlexSetChart(), DMPlexSetSupportSize(), DMSetUp() 2966552f7358SJed Brown @*/ 2967552f7358SJed Brown PetscErrorCode DMPlexSetSupport(DM dm, PetscInt p, const PetscInt support[]) 2968552f7358SJed Brown { 2969552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 2970552f7358SJed Brown PetscInt pStart, pEnd; 2971552f7358SJed Brown PetscInt dof, off, c; 2972552f7358SJed Brown PetscErrorCode ierr; 2973552f7358SJed Brown 2974552f7358SJed Brown PetscFunctionBegin; 2975552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2976552f7358SJed Brown ierr = PetscSectionGetChart(mesh->supportSection, &pStart, &pEnd);CHKERRQ(ierr); 2977552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, &dof);CHKERRQ(ierr); 2978552f7358SJed Brown if (dof) PetscValidPointer(support, 3); 2979552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, p, &off);CHKERRQ(ierr); 298082f516ccSBarry 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); 2981552f7358SJed Brown for (c = 0; c < dof; ++c) { 298282f516ccSBarry 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); 2983552f7358SJed Brown mesh->supports[off+c] = support[c]; 2984552f7358SJed Brown } 2985552f7358SJed Brown PetscFunctionReturn(0); 2986552f7358SJed Brown } 2987552f7358SJed Brown 29887cd05799SMatthew G. Knepley /*@ 2989eaf898f9SPatrick Sanan DMPlexInsertSupport - Insert a point into the out-edges for the point p in the DAG 29907cd05799SMatthew G. Knepley 29917cd05799SMatthew G. Knepley Not collective 29927cd05799SMatthew G. Knepley 29937cd05799SMatthew G. Knepley Input Parameters: 29947cd05799SMatthew G. Knepley + mesh - The DMPlex 2995eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 29967cd05799SMatthew G. Knepley . supportPos - The local index in the cone where the point should be put 29977cd05799SMatthew G. Knepley - supportPoint - The mesh point to insert 29987cd05799SMatthew G. Knepley 29997cd05799SMatthew G. Knepley Level: beginner 30007cd05799SMatthew G. Knepley 30017cd05799SMatthew G. Knepley .seealso: DMPlexCreate(), DMPlexGetCone(), DMPlexSetChart(), DMPlexSetConeSize(), DMSetUp() 30027cd05799SMatthew G. Knepley @*/ 3003552f7358SJed Brown PetscErrorCode DMPlexInsertSupport(DM dm, PetscInt p, PetscInt supportPos, PetscInt supportPoint) 3004552f7358SJed Brown { 3005552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3006552f7358SJed Brown PetscInt pStart, pEnd; 3007552f7358SJed Brown PetscInt dof, off; 3008552f7358SJed Brown PetscErrorCode ierr; 3009552f7358SJed Brown 3010552f7358SJed Brown PetscFunctionBegin; 3011552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3012552f7358SJed Brown ierr = PetscSectionGetChart(mesh->supportSection, &pStart, &pEnd);CHKERRQ(ierr); 3013552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, &dof);CHKERRQ(ierr); 3014552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, p, &off);CHKERRQ(ierr); 301582f516ccSBarry 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); 301682f516ccSBarry 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); 301782f516ccSBarry 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); 3018552f7358SJed Brown mesh->supports[off+supportPos] = supportPoint; 3019552f7358SJed Brown PetscFunctionReturn(0); 3020552f7358SJed Brown } 3021552f7358SJed Brown 3022552f7358SJed Brown /*@C 3023eaf898f9SPatrick Sanan DMPlexGetTransitiveClosure - Return the points on the transitive closure of the in-edges or out-edges for this point in the DAG 3024552f7358SJed Brown 3025552f7358SJed Brown Not collective 3026552f7358SJed Brown 3027552f7358SJed Brown Input Parameters: 3028552f7358SJed Brown + mesh - The DMPlex 3029eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 3030552f7358SJed Brown . useCone - PETSC_TRUE for in-edges, otherwise use out-edges 30310298fd71SBarry Smith - points - If points is NULL on input, internal storage will be returned, otherwise the provided array is used 3032552f7358SJed Brown 3033552f7358SJed Brown Output Parameters: 3034552f7358SJed Brown + numPoints - The number of points in the closure, so points[] is of size 2*numPoints 3035552f7358SJed Brown - points - The points and point orientations, interleaved as pairs [p0, o0, p1, o1, ...] 3036552f7358SJed Brown 3037552f7358SJed Brown Note: 30380298fd71SBarry Smith If using internal storage (points is NULL on input), each call overwrites the last output. 3039552f7358SJed Brown 30403813dfbdSMatthew G Knepley Fortran Notes: 30413813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 30423813dfbdSMatthew G Knepley include petsc.h90 in your code. 30433813dfbdSMatthew G Knepley 30443813dfbdSMatthew G Knepley The numPoints argument is not present in the Fortran 90 binding since it is internal to the array. 30453813dfbdSMatthew G Knepley 3046552f7358SJed Brown Level: beginner 3047552f7358SJed Brown 3048552f7358SJed Brown .seealso: DMPlexRestoreTransitiveClosure(), DMPlexCreate(), DMPlexSetCone(), DMPlexSetChart(), DMPlexGetCone() 3049552f7358SJed Brown @*/ 3050552f7358SJed Brown PetscErrorCode DMPlexGetTransitiveClosure(DM dm, PetscInt p, PetscBool useCone, PetscInt *numPoints, PetscInt *points[]) 3051552f7358SJed Brown { 3052552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3053552f7358SJed Brown PetscInt *closure, *fifo; 30540298fd71SBarry Smith const PetscInt *tmp = NULL, *tmpO = NULL; 3055552f7358SJed Brown PetscInt tmpSize, t; 3056552f7358SJed Brown PetscInt depth = 0, maxSize; 3057552f7358SJed Brown PetscInt closureSize = 2, fifoSize = 0, fifoStart = 0; 3058552f7358SJed Brown PetscErrorCode ierr; 3059552f7358SJed Brown 3060552f7358SJed Brown PetscFunctionBegin; 3061552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3062552f7358SJed Brown ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 3063552f7358SJed Brown /* This is only 1-level */ 3064552f7358SJed Brown if (useCone) { 3065552f7358SJed Brown ierr = DMPlexGetConeSize(dm, p, &tmpSize);CHKERRQ(ierr); 3066552f7358SJed Brown ierr = DMPlexGetCone(dm, p, &tmp);CHKERRQ(ierr); 3067552f7358SJed Brown ierr = DMPlexGetConeOrientation(dm, p, &tmpO);CHKERRQ(ierr); 3068552f7358SJed Brown } else { 3069552f7358SJed Brown ierr = DMPlexGetSupportSize(dm, p, &tmpSize);CHKERRQ(ierr); 3070552f7358SJed Brown ierr = DMPlexGetSupport(dm, p, &tmp);CHKERRQ(ierr); 3071552f7358SJed Brown } 3072bfbcdd7aSMatthew G. Knepley if (depth == 1) { 3073bfbcdd7aSMatthew G. Knepley if (*points) { 3074bfbcdd7aSMatthew G. Knepley closure = *points; 3075bfbcdd7aSMatthew G. Knepley } else { 3076bfbcdd7aSMatthew G. Knepley maxSize = 2*(PetscMax(mesh->maxConeSize, mesh->maxSupportSize)+1); 307769291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &closure);CHKERRQ(ierr); 3078bfbcdd7aSMatthew G. Knepley } 3079bfbcdd7aSMatthew G. Knepley closure[0] = p; closure[1] = 0; 3080bfbcdd7aSMatthew G. Knepley for (t = 0; t < tmpSize; ++t, closureSize += 2) { 3081bfbcdd7aSMatthew G. Knepley closure[closureSize] = tmp[t]; 3082bfbcdd7aSMatthew G. Knepley closure[closureSize+1] = tmpO ? tmpO[t] : 0; 3083bfbcdd7aSMatthew G. Knepley } 3084bfbcdd7aSMatthew G. Knepley if (numPoints) *numPoints = closureSize/2; 3085bfbcdd7aSMatthew G. Knepley if (points) *points = closure; 3086bfbcdd7aSMatthew G. Knepley PetscFunctionReturn(0); 3087bfbcdd7aSMatthew G. Knepley } 308824c766afSToby Isaac { 308924c766afSToby Isaac PetscInt c, coneSeries, s,supportSeries; 309024c766afSToby Isaac 309124c766afSToby Isaac c = mesh->maxConeSize; 309224c766afSToby Isaac coneSeries = (c > 1) ? ((PetscPowInt(c,depth+1)-1)/(c-1)) : depth+1; 309324c766afSToby Isaac s = mesh->maxSupportSize; 309424c766afSToby Isaac supportSeries = (s > 1) ? ((PetscPowInt(s,depth+1)-1)/(s-1)) : depth+1; 309524c766afSToby Isaac maxSize = 2*PetscMax(coneSeries,supportSeries); 309624c766afSToby Isaac } 309769291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &fifo);CHKERRQ(ierr); 3098bfbcdd7aSMatthew G. Knepley if (*points) { 3099bfbcdd7aSMatthew G. Knepley closure = *points; 3100bfbcdd7aSMatthew G. Knepley } else { 310169291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &closure);CHKERRQ(ierr); 3102bfbcdd7aSMatthew G. Knepley } 3103bfbcdd7aSMatthew G. Knepley closure[0] = p; closure[1] = 0; 3104552f7358SJed Brown for (t = 0; t < tmpSize; ++t, closureSize += 2, fifoSize += 2) { 3105552f7358SJed Brown const PetscInt cp = tmp[t]; 3106552f7358SJed Brown const PetscInt co = tmpO ? tmpO[t] : 0; 3107552f7358SJed Brown 3108552f7358SJed Brown closure[closureSize] = cp; 3109552f7358SJed Brown closure[closureSize+1] = co; 3110552f7358SJed Brown fifo[fifoSize] = cp; 3111552f7358SJed Brown fifo[fifoSize+1] = co; 3112552f7358SJed Brown } 3113bfbcdd7aSMatthew G. Knepley /* Should kick out early when depth is reached, rather than checking all vertices for empty cones */ 3114552f7358SJed Brown while (fifoSize - fifoStart) { 3115552f7358SJed Brown const PetscInt q = fifo[fifoStart]; 3116552f7358SJed Brown const PetscInt o = fifo[fifoStart+1]; 3117552f7358SJed Brown const PetscInt rev = o >= 0 ? 0 : 1; 3118552f7358SJed Brown const PetscInt off = rev ? -(o+1) : o; 3119552f7358SJed Brown 3120552f7358SJed Brown if (useCone) { 3121552f7358SJed Brown ierr = DMPlexGetConeSize(dm, q, &tmpSize);CHKERRQ(ierr); 3122552f7358SJed Brown ierr = DMPlexGetCone(dm, q, &tmp);CHKERRQ(ierr); 3123552f7358SJed Brown ierr = DMPlexGetConeOrientation(dm, q, &tmpO);CHKERRQ(ierr); 3124552f7358SJed Brown } else { 3125552f7358SJed Brown ierr = DMPlexGetSupportSize(dm, q, &tmpSize);CHKERRQ(ierr); 3126552f7358SJed Brown ierr = DMPlexGetSupport(dm, q, &tmp);CHKERRQ(ierr); 31270298fd71SBarry Smith tmpO = NULL; 3128552f7358SJed Brown } 3129552f7358SJed Brown for (t = 0; t < tmpSize; ++t) { 3130552f7358SJed Brown const PetscInt i = ((rev ? tmpSize-t : t) + off)%tmpSize; 3131552f7358SJed Brown const PetscInt cp = tmp[i]; 31322e1b13c2SMatthew G. Knepley /* Must propogate orientation: When we reverse orientation, we both reverse the direction of iteration and start at the other end of the chain. */ 31332e1b13c2SMatthew G. Knepley /* HACK: It is worse to get the size here, than to change the interpretation of -(*+1) 31342e1b13c2SMatthew G. Knepley const PetscInt co = tmpO ? (rev ? -(tmpO[i]+1) : tmpO[i]) : 0; */ 31352e1b13c2SMatthew G. Knepley PetscInt co = tmpO ? tmpO[i] : 0; 3136552f7358SJed Brown PetscInt c; 3137552f7358SJed Brown 31382e1b13c2SMatthew G. Knepley if (rev) { 31392e1b13c2SMatthew G. Knepley PetscInt childSize, coff; 31402e1b13c2SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, cp, &childSize);CHKERRQ(ierr); 31412e1b13c2SMatthew G. Knepley coff = tmpO[i] < 0 ? -(tmpO[i]+1) : tmpO[i]; 31422e1b13c2SMatthew G. Knepley co = childSize ? -(((coff+childSize-1)%childSize)+1) : 0; 31432e1b13c2SMatthew G. Knepley } 3144552f7358SJed Brown /* Check for duplicate */ 3145552f7358SJed Brown for (c = 0; c < closureSize; c += 2) { 3146552f7358SJed Brown if (closure[c] == cp) break; 3147552f7358SJed Brown } 3148552f7358SJed Brown if (c == closureSize) { 3149552f7358SJed Brown closure[closureSize] = cp; 3150552f7358SJed Brown closure[closureSize+1] = co; 3151552f7358SJed Brown fifo[fifoSize] = cp; 3152552f7358SJed Brown fifo[fifoSize+1] = co; 3153552f7358SJed Brown closureSize += 2; 3154552f7358SJed Brown fifoSize += 2; 3155552f7358SJed Brown } 3156552f7358SJed Brown } 3157552f7358SJed Brown fifoStart += 2; 3158552f7358SJed Brown } 3159552f7358SJed Brown if (numPoints) *numPoints = closureSize/2; 3160552f7358SJed Brown if (points) *points = closure; 316169291d52SBarry Smith ierr = DMRestoreWorkArray(dm, maxSize, MPIU_INT, &fifo);CHKERRQ(ierr); 3162552f7358SJed Brown PetscFunctionReturn(0); 3163552f7358SJed Brown } 3164552f7358SJed Brown 31659bf0dad6SMatthew G. Knepley /*@C 3166eaf898f9SPatrick Sanan DMPlexGetTransitiveClosure_Internal - Return the points on the transitive closure of the in-edges or out-edges for this point in the DAG with a specified initial orientation 31679bf0dad6SMatthew G. Knepley 31689bf0dad6SMatthew G. Knepley Not collective 31699bf0dad6SMatthew G. Knepley 31709bf0dad6SMatthew G. Knepley Input Parameters: 31719bf0dad6SMatthew G. Knepley + mesh - The DMPlex 3172eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 31739bf0dad6SMatthew G. Knepley . orientation - The orientation of the point 31749bf0dad6SMatthew G. Knepley . useCone - PETSC_TRUE for in-edges, otherwise use out-edges 31759bf0dad6SMatthew G. Knepley - points - If points is NULL on input, internal storage will be returned, otherwise the provided array is used 31769bf0dad6SMatthew G. Knepley 31779bf0dad6SMatthew G. Knepley Output Parameters: 31789bf0dad6SMatthew G. Knepley + numPoints - The number of points in the closure, so points[] is of size 2*numPoints 31799bf0dad6SMatthew G. Knepley - points - The points and point orientations, interleaved as pairs [p0, o0, p1, o1, ...] 31809bf0dad6SMatthew G. Knepley 31819bf0dad6SMatthew G. Knepley Note: 31829bf0dad6SMatthew G. Knepley If using internal storage (points is NULL on input), each call overwrites the last output. 31839bf0dad6SMatthew G. Knepley 31849bf0dad6SMatthew G. Knepley Fortran Notes: 31859bf0dad6SMatthew G. Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 31869bf0dad6SMatthew G. Knepley include petsc.h90 in your code. 31879bf0dad6SMatthew G. Knepley 31889bf0dad6SMatthew G. Knepley The numPoints argument is not present in the Fortran 90 binding since it is internal to the array. 31899bf0dad6SMatthew G. Knepley 31909bf0dad6SMatthew G. Knepley Level: beginner 31919bf0dad6SMatthew G. Knepley 31929bf0dad6SMatthew G. Knepley .seealso: DMPlexRestoreTransitiveClosure(), DMPlexCreate(), DMPlexSetCone(), DMPlexSetChart(), DMPlexGetCone() 31939bf0dad6SMatthew G. Knepley @*/ 31949bf0dad6SMatthew G. Knepley PetscErrorCode DMPlexGetTransitiveClosure_Internal(DM dm, PetscInt p, PetscInt ornt, PetscBool useCone, PetscInt *numPoints, PetscInt *points[]) 31959bf0dad6SMatthew G. Knepley { 31969bf0dad6SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 31979bf0dad6SMatthew G. Knepley PetscInt *closure, *fifo; 31989bf0dad6SMatthew G. Knepley const PetscInt *tmp = NULL, *tmpO = NULL; 31999bf0dad6SMatthew G. Knepley PetscInt tmpSize, t; 32009bf0dad6SMatthew G. Knepley PetscInt depth = 0, maxSize; 32019bf0dad6SMatthew G. Knepley PetscInt closureSize = 2, fifoSize = 0, fifoStart = 0; 32029bf0dad6SMatthew G. Knepley PetscErrorCode ierr; 32039bf0dad6SMatthew G. Knepley 32049bf0dad6SMatthew G. Knepley PetscFunctionBegin; 32059bf0dad6SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 32069bf0dad6SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 32079bf0dad6SMatthew G. Knepley /* This is only 1-level */ 32089bf0dad6SMatthew G. Knepley if (useCone) { 32099bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, p, &tmpSize);CHKERRQ(ierr); 32109bf0dad6SMatthew G. Knepley ierr = DMPlexGetCone(dm, p, &tmp);CHKERRQ(ierr); 32119bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, p, &tmpO);CHKERRQ(ierr); 32129bf0dad6SMatthew G. Knepley } else { 32139bf0dad6SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, p, &tmpSize);CHKERRQ(ierr); 32149bf0dad6SMatthew G. Knepley ierr = DMPlexGetSupport(dm, p, &tmp);CHKERRQ(ierr); 32159bf0dad6SMatthew G. Knepley } 32169bf0dad6SMatthew G. Knepley if (depth == 1) { 32179bf0dad6SMatthew G. Knepley if (*points) { 32189bf0dad6SMatthew G. Knepley closure = *points; 32199bf0dad6SMatthew G. Knepley } else { 32209bf0dad6SMatthew G. Knepley maxSize = 2*(PetscMax(mesh->maxConeSize, mesh->maxSupportSize)+1); 322169291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &closure);CHKERRQ(ierr); 32229bf0dad6SMatthew G. Knepley } 32239bf0dad6SMatthew G. Knepley closure[0] = p; closure[1] = ornt; 32249bf0dad6SMatthew G. Knepley for (t = 0; t < tmpSize; ++t, closureSize += 2) { 32259bf0dad6SMatthew G. Knepley const PetscInt i = ornt >= 0 ? (t+ornt)%tmpSize : (-(ornt+1) + tmpSize-t)%tmpSize; 32269bf0dad6SMatthew G. Knepley closure[closureSize] = tmp[i]; 32279bf0dad6SMatthew G. Knepley closure[closureSize+1] = tmpO ? tmpO[i] : 0; 32289bf0dad6SMatthew G. Knepley } 32299bf0dad6SMatthew G. Knepley if (numPoints) *numPoints = closureSize/2; 32309bf0dad6SMatthew G. Knepley if (points) *points = closure; 32319bf0dad6SMatthew G. Knepley PetscFunctionReturn(0); 32329bf0dad6SMatthew G. Knepley } 323324c766afSToby Isaac { 323424c766afSToby Isaac PetscInt c, coneSeries, s,supportSeries; 323524c766afSToby Isaac 323624c766afSToby Isaac c = mesh->maxConeSize; 323724c766afSToby Isaac coneSeries = (c > 1) ? ((PetscPowInt(c,depth+1)-1)/(c-1)) : depth+1; 323824c766afSToby Isaac s = mesh->maxSupportSize; 323924c766afSToby Isaac supportSeries = (s > 1) ? ((PetscPowInt(s,depth+1)-1)/(s-1)) : depth+1; 324024c766afSToby Isaac maxSize = 2*PetscMax(coneSeries,supportSeries); 324124c766afSToby Isaac } 324269291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &fifo);CHKERRQ(ierr); 32439bf0dad6SMatthew G. Knepley if (*points) { 32449bf0dad6SMatthew G. Knepley closure = *points; 32459bf0dad6SMatthew G. Knepley } else { 324669291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &closure);CHKERRQ(ierr); 32479bf0dad6SMatthew G. Knepley } 32489bf0dad6SMatthew G. Knepley closure[0] = p; closure[1] = ornt; 32499bf0dad6SMatthew G. Knepley for (t = 0; t < tmpSize; ++t, closureSize += 2, fifoSize += 2) { 32509bf0dad6SMatthew G. Knepley const PetscInt i = ornt >= 0 ? (t+ornt)%tmpSize : (-(ornt+1) + tmpSize-t)%tmpSize; 32519bf0dad6SMatthew G. Knepley const PetscInt cp = tmp[i]; 32529bf0dad6SMatthew G. Knepley PetscInt co = tmpO ? tmpO[i] : 0; 32539bf0dad6SMatthew G. Knepley 32549bf0dad6SMatthew G. Knepley if (ornt < 0) { 32559bf0dad6SMatthew G. Knepley PetscInt childSize, coff; 32569bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, cp, &childSize);CHKERRQ(ierr); 325786b63641SMatthew G. Knepley coff = co < 0 ? -(tmpO[i]+1) : tmpO[i]; 32589bf0dad6SMatthew G. Knepley co = childSize ? -(((coff+childSize-1)%childSize)+1) : 0; 32599bf0dad6SMatthew G. Knepley } 32609bf0dad6SMatthew G. Knepley closure[closureSize] = cp; 32619bf0dad6SMatthew G. Knepley closure[closureSize+1] = co; 32629bf0dad6SMatthew G. Knepley fifo[fifoSize] = cp; 32639bf0dad6SMatthew G. Knepley fifo[fifoSize+1] = co; 32649bf0dad6SMatthew G. Knepley } 32659bf0dad6SMatthew G. Knepley /* Should kick out early when depth is reached, rather than checking all vertices for empty cones */ 32669bf0dad6SMatthew G. Knepley while (fifoSize - fifoStart) { 32679bf0dad6SMatthew G. Knepley const PetscInt q = fifo[fifoStart]; 32689bf0dad6SMatthew G. Knepley const PetscInt o = fifo[fifoStart+1]; 32699bf0dad6SMatthew G. Knepley const PetscInt rev = o >= 0 ? 0 : 1; 32709bf0dad6SMatthew G. Knepley const PetscInt off = rev ? -(o+1) : o; 32719bf0dad6SMatthew G. Knepley 32729bf0dad6SMatthew G. Knepley if (useCone) { 32739bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, q, &tmpSize);CHKERRQ(ierr); 32749bf0dad6SMatthew G. Knepley ierr = DMPlexGetCone(dm, q, &tmp);CHKERRQ(ierr); 32759bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, q, &tmpO);CHKERRQ(ierr); 32769bf0dad6SMatthew G. Knepley } else { 32779bf0dad6SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, q, &tmpSize);CHKERRQ(ierr); 32789bf0dad6SMatthew G. Knepley ierr = DMPlexGetSupport(dm, q, &tmp);CHKERRQ(ierr); 32799bf0dad6SMatthew G. Knepley tmpO = NULL; 32809bf0dad6SMatthew G. Knepley } 32819bf0dad6SMatthew G. Knepley for (t = 0; t < tmpSize; ++t) { 32829bf0dad6SMatthew G. Knepley const PetscInt i = ((rev ? tmpSize-t : t) + off)%tmpSize; 32839bf0dad6SMatthew G. Knepley const PetscInt cp = tmp[i]; 32849bf0dad6SMatthew G. Knepley /* Must propogate orientation: When we reverse orientation, we both reverse the direction of iteration and start at the other end of the chain. */ 32859bf0dad6SMatthew G. Knepley /* HACK: It is worse to get the size here, than to change the interpretation of -(*+1) 32869bf0dad6SMatthew G. Knepley const PetscInt co = tmpO ? (rev ? -(tmpO[i]+1) : tmpO[i]) : 0; */ 32879bf0dad6SMatthew G. Knepley PetscInt co = tmpO ? tmpO[i] : 0; 32889bf0dad6SMatthew G. Knepley PetscInt c; 32899bf0dad6SMatthew G. Knepley 32909bf0dad6SMatthew G. Knepley if (rev) { 32919bf0dad6SMatthew G. Knepley PetscInt childSize, coff; 32929bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, cp, &childSize);CHKERRQ(ierr); 32939bf0dad6SMatthew G. Knepley coff = tmpO[i] < 0 ? -(tmpO[i]+1) : tmpO[i]; 32949bf0dad6SMatthew G. Knepley co = childSize ? -(((coff+childSize-1)%childSize)+1) : 0; 32959bf0dad6SMatthew G. Knepley } 32969bf0dad6SMatthew G. Knepley /* Check for duplicate */ 32979bf0dad6SMatthew G. Knepley for (c = 0; c < closureSize; c += 2) { 32989bf0dad6SMatthew G. Knepley if (closure[c] == cp) break; 32999bf0dad6SMatthew G. Knepley } 33009bf0dad6SMatthew G. Knepley if (c == closureSize) { 33019bf0dad6SMatthew G. Knepley closure[closureSize] = cp; 33029bf0dad6SMatthew G. Knepley closure[closureSize+1] = co; 33039bf0dad6SMatthew G. Knepley fifo[fifoSize] = cp; 33049bf0dad6SMatthew G. Knepley fifo[fifoSize+1] = co; 33059bf0dad6SMatthew G. Knepley closureSize += 2; 33069bf0dad6SMatthew G. Knepley fifoSize += 2; 33079bf0dad6SMatthew G. Knepley } 33089bf0dad6SMatthew G. Knepley } 33099bf0dad6SMatthew G. Knepley fifoStart += 2; 33109bf0dad6SMatthew G. Knepley } 33119bf0dad6SMatthew G. Knepley if (numPoints) *numPoints = closureSize/2; 33129bf0dad6SMatthew G. Knepley if (points) *points = closure; 331369291d52SBarry Smith ierr = DMRestoreWorkArray(dm, maxSize, MPIU_INT, &fifo);CHKERRQ(ierr); 33149bf0dad6SMatthew G. Knepley PetscFunctionReturn(0); 33159bf0dad6SMatthew G. Knepley } 33169bf0dad6SMatthew G. Knepley 3317552f7358SJed Brown /*@C 3318eaf898f9SPatrick Sanan DMPlexRestoreTransitiveClosure - Restore the array of points on the transitive closure of the in-edges or out-edges for this point in the DAG 3319552f7358SJed Brown 3320552f7358SJed Brown Not collective 3321552f7358SJed Brown 3322552f7358SJed Brown Input Parameters: 3323552f7358SJed Brown + mesh - The DMPlex 3324eaf898f9SPatrick Sanan . p - The point, which must lie in the chart set with DMPlexSetChart() 3325552f7358SJed Brown . useCone - PETSC_TRUE for in-edges, otherwise use out-edges 3326e5c84f05SJed Brown . numPoints - The number of points in the closure, so points[] is of size 2*numPoints, zeroed on exit 3327e5c84f05SJed Brown - points - The points and point orientations, interleaved as pairs [p0, o0, p1, o1, ...], zeroed on exit 3328552f7358SJed Brown 3329552f7358SJed Brown Note: 33300298fd71SBarry Smith If not using internal storage (points is not NULL on input), this call is unnecessary 3331552f7358SJed Brown 33323813dfbdSMatthew G Knepley Fortran Notes: 33333813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 33343813dfbdSMatthew G Knepley include petsc.h90 in your code. 33353813dfbdSMatthew G Knepley 33363813dfbdSMatthew G Knepley The numPoints argument is not present in the Fortran 90 binding since it is internal to the array. 33373813dfbdSMatthew G Knepley 3338552f7358SJed Brown Level: beginner 3339552f7358SJed Brown 3340552f7358SJed Brown .seealso: DMPlexGetTransitiveClosure(), DMPlexCreate(), DMPlexSetCone(), DMPlexSetChart(), DMPlexGetCone() 3341552f7358SJed Brown @*/ 3342552f7358SJed Brown PetscErrorCode DMPlexRestoreTransitiveClosure(DM dm, PetscInt p, PetscBool useCone, PetscInt *numPoints, PetscInt *points[]) 3343552f7358SJed Brown { 3344552f7358SJed Brown PetscErrorCode ierr; 3345552f7358SJed Brown 3346552f7358SJed Brown PetscFunctionBegin; 3347552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3348e5c84f05SJed Brown if (numPoints) PetscValidIntPointer(numPoints,4); 3349e5c84f05SJed Brown if (points) PetscValidPointer(points,5); 335069291d52SBarry Smith ierr = DMRestoreWorkArray(dm, 0, MPIU_INT, points);CHKERRQ(ierr); 33514ff43b2cSJed Brown if (numPoints) *numPoints = 0; 3352552f7358SJed Brown PetscFunctionReturn(0); 3353552f7358SJed Brown } 3354552f7358SJed Brown 3355552f7358SJed Brown /*@ 3356eaf898f9SPatrick Sanan DMPlexGetMaxSizes - Return the maximum number of in-edges (cone) and out-edges (support) for any point in the DAG 3357552f7358SJed Brown 3358552f7358SJed Brown Not collective 3359552f7358SJed Brown 3360552f7358SJed Brown Input Parameter: 3361552f7358SJed Brown . mesh - The DMPlex 3362552f7358SJed Brown 3363552f7358SJed Brown Output Parameters: 3364552f7358SJed Brown + maxConeSize - The maximum number of in-edges 3365552f7358SJed Brown - maxSupportSize - The maximum number of out-edges 3366552f7358SJed Brown 3367552f7358SJed Brown Level: beginner 3368552f7358SJed Brown 3369552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetConeSize(), DMPlexSetChart() 3370552f7358SJed Brown @*/ 3371552f7358SJed Brown PetscErrorCode DMPlexGetMaxSizes(DM dm, PetscInt *maxConeSize, PetscInt *maxSupportSize) 3372552f7358SJed Brown { 3373552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3374552f7358SJed Brown 3375552f7358SJed Brown PetscFunctionBegin; 3376552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3377552f7358SJed Brown if (maxConeSize) *maxConeSize = mesh->maxConeSize; 3378552f7358SJed Brown if (maxSupportSize) *maxSupportSize = mesh->maxSupportSize; 3379552f7358SJed Brown PetscFunctionReturn(0); 3380552f7358SJed Brown } 3381552f7358SJed Brown 3382552f7358SJed Brown PetscErrorCode DMSetUp_Plex(DM dm) 3383552f7358SJed Brown { 3384552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3385552f7358SJed Brown PetscInt size; 3386552f7358SJed Brown PetscErrorCode ierr; 3387552f7358SJed Brown 3388552f7358SJed Brown PetscFunctionBegin; 3389552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3390552f7358SJed Brown ierr = PetscSectionSetUp(mesh->coneSection);CHKERRQ(ierr); 3391552f7358SJed Brown ierr = PetscSectionGetStorageSize(mesh->coneSection, &size);CHKERRQ(ierr); 33921795a4d1SJed Brown ierr = PetscMalloc1(size, &mesh->cones);CHKERRQ(ierr); 33931795a4d1SJed Brown ierr = PetscCalloc1(size, &mesh->coneOrientations);CHKERRQ(ierr); 3394ef1259faSMatthew G. Knepley ierr = PetscLogObjectMemory((PetscObject) dm, size*2*sizeof(PetscInt));CHKERRQ(ierr); 3395552f7358SJed Brown if (mesh->maxSupportSize) { 3396552f7358SJed Brown ierr = PetscSectionSetUp(mesh->supportSection);CHKERRQ(ierr); 3397552f7358SJed Brown ierr = PetscSectionGetStorageSize(mesh->supportSection, &size);CHKERRQ(ierr); 33981795a4d1SJed Brown ierr = PetscMalloc1(size, &mesh->supports);CHKERRQ(ierr); 3399ef1259faSMatthew G. Knepley ierr = PetscLogObjectMemory((PetscObject) dm, size*sizeof(PetscInt));CHKERRQ(ierr); 3400552f7358SJed Brown } 3401552f7358SJed Brown PetscFunctionReturn(0); 3402552f7358SJed Brown } 3403552f7358SJed Brown 3404276c5506SMatthew G. Knepley PetscErrorCode DMCreateSubDM_Plex(DM dm, PetscInt numFields, const PetscInt fields[], IS *is, DM *subdm) 3405552f7358SJed Brown { 3406552f7358SJed Brown PetscErrorCode ierr; 3407552f7358SJed Brown 3408552f7358SJed Brown PetscFunctionBegin; 34094d9407bcSMatthew G. Knepley if (subdm) {ierr = DMClone(dm, subdm);CHKERRQ(ierr);} 3410792b654fSMatthew G. Knepley ierr = DMCreateSectionSubDM(dm, numFields, fields, is, subdm);CHKERRQ(ierr); 3411c2939958SSatish Balay if (subdm) {(*subdm)->useNatural = dm->useNatural;} 3412736995cdSBlaise Bourdin if (dm->useNatural && dm->sfMigration) { 3413f94b4a02SBlaise Bourdin PetscSF sfMigrationInv,sfNatural; 3414f94b4a02SBlaise Bourdin PetscSection section, sectionSeq; 3415f94b4a02SBlaise Bourdin 34163dcd263cSBlaise Bourdin (*subdm)->sfMigration = dm->sfMigration; 34173dcd263cSBlaise Bourdin ierr = PetscObjectReference((PetscObject) dm->sfMigration);CHKERRQ(ierr); 3418c3b366b1Sprj- ierr = DMGetLocalSection((*subdm), §ion);CHKERRQ(ierr); 3419f94b4a02SBlaise Bourdin ierr = PetscSFCreateInverseSF((*subdm)->sfMigration, &sfMigrationInv);CHKERRQ(ierr); 3420f94b4a02SBlaise Bourdin ierr = PetscSectionCreate(PetscObjectComm((PetscObject) (*subdm)), §ionSeq);CHKERRQ(ierr); 3421f94b4a02SBlaise Bourdin ierr = PetscSFDistributeSection(sfMigrationInv, section, NULL, sectionSeq);CHKERRQ(ierr); 3422f94b4a02SBlaise Bourdin 3423f94b4a02SBlaise Bourdin ierr = DMPlexCreateGlobalToNaturalSF(*subdm, sectionSeq, (*subdm)->sfMigration, &sfNatural);CHKERRQ(ierr); 3424c40e9495SBlaise Bourdin (*subdm)->sfNatural = sfNatural; 3425f94b4a02SBlaise Bourdin ierr = PetscSectionDestroy(§ionSeq);CHKERRQ(ierr); 3426f94b4a02SBlaise Bourdin ierr = PetscSFDestroy(&sfMigrationInv);CHKERRQ(ierr); 3427f94b4a02SBlaise Bourdin } 3428552f7358SJed Brown PetscFunctionReturn(0); 3429552f7358SJed Brown } 3430552f7358SJed Brown 34312adcc780SMatthew G. Knepley PetscErrorCode DMCreateSuperDM_Plex(DM dms[], PetscInt len, IS **is, DM *superdm) 34322adcc780SMatthew G. Knepley { 34332adcc780SMatthew G. Knepley PetscErrorCode ierr; 34343dcd263cSBlaise Bourdin PetscInt i = 0; 34352adcc780SMatthew G. Knepley 34362adcc780SMatthew G. Knepley PetscFunctionBegin; 3437435bcee1SStefano Zampini ierr = DMClone(dms[0], superdm);CHKERRQ(ierr); 3438792b654fSMatthew G. Knepley ierr = DMCreateSectionSuperDM(dms, len, is, superdm);CHKERRQ(ierr); 3439c40e9495SBlaise Bourdin (*superdm)->useNatural = PETSC_FALSE; 34403dcd263cSBlaise Bourdin for (i = 0; i < len; i++) { 34413dcd263cSBlaise Bourdin if (dms[i]->useNatural && dms[i]->sfMigration) { 34423dcd263cSBlaise Bourdin PetscSF sfMigrationInv,sfNatural; 34433dcd263cSBlaise Bourdin PetscSection section, sectionSeq; 34443dcd263cSBlaise Bourdin 34453dcd263cSBlaise Bourdin (*superdm)->sfMigration = dms[i]->sfMigration; 34463dcd263cSBlaise Bourdin ierr = PetscObjectReference((PetscObject) dms[i]->sfMigration);CHKERRQ(ierr); 3447c40e9495SBlaise Bourdin (*superdm)->useNatural = PETSC_TRUE; 344892fd8e1eSJed Brown ierr = DMGetLocalSection((*superdm), §ion);CHKERRQ(ierr); 34493dcd263cSBlaise Bourdin ierr = PetscSFCreateInverseSF((*superdm)->sfMigration, &sfMigrationInv);CHKERRQ(ierr); 34503dcd263cSBlaise Bourdin ierr = PetscSectionCreate(PetscObjectComm((PetscObject) (*superdm)), §ionSeq);CHKERRQ(ierr); 34513dcd263cSBlaise Bourdin ierr = PetscSFDistributeSection(sfMigrationInv, section, NULL, sectionSeq);CHKERRQ(ierr); 34523dcd263cSBlaise Bourdin 34533dcd263cSBlaise Bourdin ierr = DMPlexCreateGlobalToNaturalSF(*superdm, sectionSeq, (*superdm)->sfMigration, &sfNatural);CHKERRQ(ierr); 3454c40e9495SBlaise Bourdin (*superdm)->sfNatural = sfNatural; 34553dcd263cSBlaise Bourdin ierr = PetscSectionDestroy(§ionSeq);CHKERRQ(ierr); 34563dcd263cSBlaise Bourdin ierr = PetscSFDestroy(&sfMigrationInv);CHKERRQ(ierr); 34573dcd263cSBlaise Bourdin break; 34583dcd263cSBlaise Bourdin } 34593dcd263cSBlaise Bourdin } 34602adcc780SMatthew G. Knepley PetscFunctionReturn(0); 34612adcc780SMatthew G. Knepley } 34622adcc780SMatthew G. Knepley 3463552f7358SJed Brown /*@ 3464eaf898f9SPatrick Sanan DMPlexSymmetrize - Create support (out-edge) information from cone (in-edge) information 3465552f7358SJed Brown 3466552f7358SJed Brown Not collective 3467552f7358SJed Brown 3468552f7358SJed Brown Input Parameter: 3469552f7358SJed Brown . mesh - The DMPlex 3470552f7358SJed Brown 3471552f7358SJed Brown Output Parameter: 3472552f7358SJed Brown 3473552f7358SJed Brown Note: 3474552f7358SJed Brown This should be called after all calls to DMPlexSetCone() 3475552f7358SJed Brown 3476552f7358SJed Brown Level: beginner 3477552f7358SJed Brown 3478552f7358SJed Brown .seealso: DMPlexCreate(), DMPlexSetChart(), DMPlexSetConeSize(), DMPlexSetCone() 3479552f7358SJed Brown @*/ 3480552f7358SJed Brown PetscErrorCode DMPlexSymmetrize(DM dm) 3481552f7358SJed Brown { 3482552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3483552f7358SJed Brown PetscInt *offsets; 3484552f7358SJed Brown PetscInt supportSize; 3485552f7358SJed Brown PetscInt pStart, pEnd, p; 3486552f7358SJed Brown PetscErrorCode ierr; 3487552f7358SJed Brown 3488552f7358SJed Brown PetscFunctionBegin; 3489552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 349082f516ccSBarry Smith if (mesh->supports) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "Supports were already setup in this DMPlex"); 349130b0ce1bSStefano Zampini ierr = PetscLogEventBegin(DMPLEX_Symmetrize,dm,0,0,0);CHKERRQ(ierr); 3492552f7358SJed Brown /* Calculate support sizes */ 3493552f7358SJed Brown ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 3494552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 3495552f7358SJed Brown PetscInt dof, off, c; 3496552f7358SJed Brown 3497552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 3498552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 3499552f7358SJed Brown for (c = off; c < off+dof; ++c) { 3500552f7358SJed Brown ierr = PetscSectionAddDof(mesh->supportSection, mesh->cones[c], 1);CHKERRQ(ierr); 3501552f7358SJed Brown } 3502552f7358SJed Brown } 3503552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 3504552f7358SJed Brown PetscInt dof; 3505552f7358SJed Brown 3506552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, p, &dof);CHKERRQ(ierr); 35070d644c17SKarl Rupp 3508552f7358SJed Brown mesh->maxSupportSize = PetscMax(mesh->maxSupportSize, dof); 3509552f7358SJed Brown } 3510552f7358SJed Brown ierr = PetscSectionSetUp(mesh->supportSection);CHKERRQ(ierr); 3511552f7358SJed Brown /* Calculate supports */ 3512552f7358SJed Brown ierr = PetscSectionGetStorageSize(mesh->supportSection, &supportSize);CHKERRQ(ierr); 35131795a4d1SJed Brown ierr = PetscMalloc1(supportSize, &mesh->supports);CHKERRQ(ierr); 35141795a4d1SJed Brown ierr = PetscCalloc1(pEnd - pStart, &offsets);CHKERRQ(ierr); 3515552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 3516552f7358SJed Brown PetscInt dof, off, c; 3517552f7358SJed Brown 3518552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, p, &dof);CHKERRQ(ierr); 3519552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, p, &off);CHKERRQ(ierr); 3520552f7358SJed Brown for (c = off; c < off+dof; ++c) { 3521552f7358SJed Brown const PetscInt q = mesh->cones[c]; 3522552f7358SJed Brown PetscInt offS; 3523552f7358SJed Brown 3524552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, q, &offS);CHKERRQ(ierr); 35250d644c17SKarl Rupp 3526552f7358SJed Brown mesh->supports[offS+offsets[q]] = p; 3527552f7358SJed Brown ++offsets[q]; 3528552f7358SJed Brown } 3529552f7358SJed Brown } 3530552f7358SJed Brown ierr = PetscFree(offsets);CHKERRQ(ierr); 353130b0ce1bSStefano Zampini ierr = PetscLogEventEnd(DMPLEX_Symmetrize,dm,0,0,0);CHKERRQ(ierr); 3532552f7358SJed Brown PetscFunctionReturn(0); 3533552f7358SJed Brown } 3534552f7358SJed Brown 3535277ea44aSLisandro Dalcin static PetscErrorCode DMPlexCreateDepthStratum(DM dm, DMLabel label, PetscInt depth, PetscInt pStart, PetscInt pEnd) 3536277ea44aSLisandro Dalcin { 3537277ea44aSLisandro Dalcin IS stratumIS; 3538277ea44aSLisandro Dalcin PetscErrorCode ierr; 3539277ea44aSLisandro Dalcin 3540277ea44aSLisandro Dalcin PetscFunctionBegin; 3541277ea44aSLisandro Dalcin if (pStart >= pEnd) PetscFunctionReturn(0); 354276bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 3543277ea44aSLisandro Dalcin PetscInt qStart, qEnd, numLevels, level; 3544277ea44aSLisandro Dalcin PetscBool overlap = PETSC_FALSE; 3545277ea44aSLisandro Dalcin ierr = DMLabelGetNumValues(label, &numLevels);CHKERRQ(ierr); 3546277ea44aSLisandro Dalcin for (level = 0; level < numLevels; level++) { 3547277ea44aSLisandro Dalcin ierr = DMLabelGetStratumBounds(label, level, &qStart, &qEnd);CHKERRQ(ierr); 3548277ea44aSLisandro Dalcin if ((pStart >= qStart && pStart < qEnd) || (pEnd > qStart && pEnd <= qEnd)) {overlap = PETSC_TRUE; break;} 3549277ea44aSLisandro Dalcin } 3550277ea44aSLisandro 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); 3551277ea44aSLisandro Dalcin } 3552277ea44aSLisandro Dalcin ierr = ISCreateStride(PETSC_COMM_SELF, pEnd-pStart, pStart, 1, &stratumIS);CHKERRQ(ierr); 3553277ea44aSLisandro Dalcin ierr = DMLabelSetStratumIS(label, depth, stratumIS);CHKERRQ(ierr); 3554277ea44aSLisandro Dalcin ierr = ISDestroy(&stratumIS);CHKERRQ(ierr); 3555277ea44aSLisandro Dalcin PetscFunctionReturn(0); 3556277ea44aSLisandro Dalcin } 3557277ea44aSLisandro Dalcin 3558552f7358SJed Brown /*@ 3559a8d69d7bSBarry Smith DMPlexStratify - The DAG for most topologies is a graded poset (https://en.wikipedia.org/wiki/Graded_poset), and 35606dd80730SBarry Smith can be illustrated by a Hasse Diagram (https://en.wikipedia.org/wiki/Hasse_diagram). The strata group all points of the 3561552f7358SJed Brown same grade, and this function calculates the strata. This grade can be seen as the height (or depth) of the point in 3562552f7358SJed Brown the DAG. 3563552f7358SJed Brown 3564bf4602e4SToby Isaac Collective on dm 3565552f7358SJed Brown 3566552f7358SJed Brown Input Parameter: 3567552f7358SJed Brown . mesh - The DMPlex 3568552f7358SJed Brown 3569552f7358SJed Brown Output Parameter: 3570552f7358SJed Brown 3571552f7358SJed Brown Notes: 3572b1bb481bSMatthew Knepley Concretely, DMPlexStratify() creates a new label named "depth" containing the depth in the DAG of each point. For cell-vertex 3573b1bb481bSMatthew 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 3574b1bb481bSMatthew Knepley until cells have depth equal to the dimension of the mesh. The depth label can be accessed through DMPlexGetDepthLabel() or DMPlexGetDepthStratum(), or 3575c58f1c22SToby Isaac manually via DMGetLabel(). The height is defined implicitly by height = maxDimension - depth, and can be accessed 3576150b719bSJed Brown via DMPlexGetHeightStratum(). For example, cells have height 0 and faces have height 1. 3577552f7358SJed Brown 3578b1bb481bSMatthew Knepley The depth of a point is calculated by executing a breadth-first search (BFS) on the DAG. This could produce surprising results 3579b1bb481bSMatthew Knepley if run on a partially interpolated mesh, meaning one that had some edges and faces, but not others. For example, suppose that 3580b1bb481bSMatthew 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 3581b1bb481bSMatthew Knepley to interpolate only that one (e0), so that 3582b1bb481bSMatthew Knepley $ cone(c0) = {e0, v2} 3583b1bb481bSMatthew Knepley $ cone(e0) = {v0, v1} 3584b1bb481bSMatthew Knepley If DMPlexStratify() is run on this mesh, it will give depths 3585b1bb481bSMatthew Knepley $ depth 0 = {v0, v1, v2} 3586b1bb481bSMatthew Knepley $ depth 1 = {e0, c0} 3587b1bb481bSMatthew Knepley where the triangle has been given depth 1, instead of 2, because it is reachable from vertex v2. 3588b1bb481bSMatthew Knepley 3589150b719bSJed Brown DMPlexStratify() should be called after all calls to DMPlexSymmetrize() 3590552f7358SJed Brown 3591552f7358SJed Brown Level: beginner 3592552f7358SJed Brown 3593ba2698f1SMatthew G. Knepley .seealso: DMPlexCreate(), DMPlexSymmetrize(), DMPlexComputeCellTypes() 3594552f7358SJed Brown @*/ 3595552f7358SJed Brown PetscErrorCode DMPlexStratify(DM dm) 3596552f7358SJed Brown { 3597df0420ecSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 3598aa50250dSMatthew G. Knepley DMLabel label; 3599552f7358SJed Brown PetscInt pStart, pEnd, p; 3600552f7358SJed Brown PetscInt numRoots = 0, numLeaves = 0; 3601552f7358SJed Brown PetscErrorCode ierr; 3602552f7358SJed Brown 3603552f7358SJed Brown PetscFunctionBegin; 3604552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3605552f7358SJed Brown ierr = PetscLogEventBegin(DMPLEX_Stratify,dm,0,0,0);CHKERRQ(ierr); 3606277ea44aSLisandro Dalcin 3607277ea44aSLisandro Dalcin /* Create depth label */ 3608aa50250dSMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 3609c58f1c22SToby Isaac ierr = DMCreateLabel(dm, "depth");CHKERRQ(ierr); 3610aa50250dSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 3611277ea44aSLisandro Dalcin 3612277ea44aSLisandro Dalcin { 3613552f7358SJed Brown /* Initialize roots and count leaves */ 3614277ea44aSLisandro Dalcin PetscInt sMin = PETSC_MAX_INT; 3615277ea44aSLisandro Dalcin PetscInt sMax = PETSC_MIN_INT; 3616552f7358SJed Brown PetscInt coneSize, supportSize; 3617552f7358SJed Brown 3618277ea44aSLisandro Dalcin for (p = pStart; p < pEnd; ++p) { 3619552f7358SJed Brown ierr = DMPlexGetConeSize(dm, p, &coneSize);CHKERRQ(ierr); 3620552f7358SJed Brown ierr = DMPlexGetSupportSize(dm, p, &supportSize);CHKERRQ(ierr); 3621552f7358SJed Brown if (!coneSize && supportSize) { 3622277ea44aSLisandro Dalcin sMin = PetscMin(p, sMin); 3623277ea44aSLisandro Dalcin sMax = PetscMax(p, sMax); 3624552f7358SJed Brown ++numRoots; 3625552f7358SJed Brown } else if (!supportSize && coneSize) { 3626552f7358SJed Brown ++numLeaves; 3627552f7358SJed Brown } else if (!supportSize && !coneSize) { 3628552f7358SJed Brown /* Isolated points */ 3629277ea44aSLisandro Dalcin sMin = PetscMin(p, sMin); 3630277ea44aSLisandro Dalcin sMax = PetscMax(p, sMax); 3631552f7358SJed Brown } 3632552f7358SJed Brown } 3633277ea44aSLisandro Dalcin ierr = DMPlexCreateDepthStratum(dm, label, 0, sMin, sMax+1);CHKERRQ(ierr); 3634277ea44aSLisandro Dalcin } 3635277ea44aSLisandro Dalcin 3636552f7358SJed Brown if (numRoots + numLeaves == (pEnd - pStart)) { 3637277ea44aSLisandro Dalcin PetscInt sMin = PETSC_MAX_INT; 3638277ea44aSLisandro Dalcin PetscInt sMax = PETSC_MIN_INT; 3639552f7358SJed Brown PetscInt coneSize, supportSize; 3640552f7358SJed Brown 3641277ea44aSLisandro Dalcin for (p = pStart; p < pEnd; ++p) { 3642552f7358SJed Brown ierr = DMPlexGetConeSize(dm, p, &coneSize);CHKERRQ(ierr); 3643552f7358SJed Brown ierr = DMPlexGetSupportSize(dm, p, &supportSize);CHKERRQ(ierr); 3644552f7358SJed Brown if (!supportSize && coneSize) { 3645277ea44aSLisandro Dalcin sMin = PetscMin(p, sMin); 3646277ea44aSLisandro Dalcin sMax = PetscMax(p, sMax); 3647552f7358SJed Brown } 3648552f7358SJed Brown } 3649277ea44aSLisandro Dalcin ierr = DMPlexCreateDepthStratum(dm, label, 1, sMin, sMax+1);CHKERRQ(ierr); 3650552f7358SJed Brown } else { 3651277ea44aSLisandro Dalcin PetscInt level = 0; 3652277ea44aSLisandro Dalcin PetscInt qStart, qEnd, q; 3653552f7358SJed Brown 3654277ea44aSLisandro Dalcin ierr = DMLabelGetStratumBounds(label, level, &qStart, &qEnd);CHKERRQ(ierr); 3655277ea44aSLisandro Dalcin while (qEnd > qStart) { 3656277ea44aSLisandro Dalcin PetscInt sMin = PETSC_MAX_INT; 3657277ea44aSLisandro Dalcin PetscInt sMax = PETSC_MIN_INT; 365874ef644bSMatthew G. Knepley 3659277ea44aSLisandro Dalcin for (q = qStart; q < qEnd; ++q) { 366074ef644bSMatthew G. Knepley const PetscInt *support; 366174ef644bSMatthew G. Knepley PetscInt supportSize, s; 366274ef644bSMatthew G. Knepley 3663277ea44aSLisandro Dalcin ierr = DMPlexGetSupportSize(dm, q, &supportSize);CHKERRQ(ierr); 3664277ea44aSLisandro Dalcin ierr = DMPlexGetSupport(dm, q, &support);CHKERRQ(ierr); 366574ef644bSMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 3666277ea44aSLisandro Dalcin sMin = PetscMin(support[s], sMin); 3667277ea44aSLisandro Dalcin sMax = PetscMax(support[s], sMax); 3668552f7358SJed Brown } 3669552f7358SJed Brown } 3670277ea44aSLisandro Dalcin ierr = DMLabelGetNumValues(label, &level);CHKERRQ(ierr); 3671277ea44aSLisandro Dalcin ierr = DMPlexCreateDepthStratum(dm, label, level, sMin, sMax+1);CHKERRQ(ierr); 3672277ea44aSLisandro Dalcin ierr = DMLabelGetStratumBounds(label, level, &qStart, &qEnd);CHKERRQ(ierr); 367374ef644bSMatthew G. Knepley } 367474ef644bSMatthew G. Knepley } 3675bf4602e4SToby Isaac { /* just in case there is an empty process */ 3676bf4602e4SToby Isaac PetscInt numValues, maxValues = 0, v; 3677bf4602e4SToby Isaac 3678bf4602e4SToby Isaac ierr = DMLabelGetNumValues(label, &numValues);CHKERRQ(ierr); 3679ffc4695bSBarry Smith ierr = MPI_Allreduce(&numValues,&maxValues,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)dm));CHKERRMPI(ierr); 3680bf4602e4SToby Isaac for (v = numValues; v < maxValues; v++) { 3681367003a6SStefano Zampini ierr = DMLabelAddStratum(label, v);CHKERRQ(ierr); 3682bf4602e4SToby Isaac } 3683bf4602e4SToby Isaac } 3684d67d17b1SMatthew G. Knepley ierr = PetscObjectStateGet((PetscObject) label, &mesh->depthState);CHKERRQ(ierr); 3685552f7358SJed Brown ierr = PetscLogEventEnd(DMPLEX_Stratify,dm,0,0,0);CHKERRQ(ierr); 3686552f7358SJed Brown PetscFunctionReturn(0); 3687552f7358SJed Brown } 3688552f7358SJed Brown 3689412e9a14SMatthew G. Knepley PetscErrorCode DMPlexComputeCellType_Internal(DM dm, PetscInt p, PetscInt pdepth, DMPolytopeType *pt) 3690ba2698f1SMatthew G. Knepley { 3691412e9a14SMatthew G. Knepley DMPolytopeType ct = DM_POLYTOPE_UNKNOWN; 3692412e9a14SMatthew G. Knepley PetscInt dim, depth, pheight, coneSize; 3693ba2698f1SMatthew G. Knepley PetscErrorCode ierr; 3694ba2698f1SMatthew G. Knepley 3695412e9a14SMatthew G. Knepley PetscFunctionBeginHot; 3696ba2698f1SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 3697ba2698f1SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 3698ba2698f1SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, p, &coneSize);CHKERRQ(ierr); 3699ba2698f1SMatthew G. Knepley pheight = depth - pdepth; 3700ba2698f1SMatthew G. Knepley if (depth <= 1) { 3701ba2698f1SMatthew G. Knepley switch (pdepth) { 3702ba2698f1SMatthew G. Knepley case 0: ct = DM_POLYTOPE_POINT;break; 3703ba2698f1SMatthew G. Knepley case 1: 3704ba2698f1SMatthew G. Knepley switch (coneSize) { 3705ba2698f1SMatthew G. Knepley case 2: ct = DM_POLYTOPE_SEGMENT;break; 3706ba2698f1SMatthew G. Knepley case 3: ct = DM_POLYTOPE_TRIANGLE;break; 3707ba2698f1SMatthew G. Knepley case 4: 3708ba2698f1SMatthew G. Knepley switch (dim) { 3709ba2698f1SMatthew G. Knepley case 2: ct = DM_POLYTOPE_QUADRILATERAL;break; 3710ba2698f1SMatthew G. Knepley case 3: ct = DM_POLYTOPE_TETRAHEDRON;break; 3711ba2698f1SMatthew G. Knepley default: break; 3712ba2698f1SMatthew G. Knepley } 3713ba2698f1SMatthew G. Knepley break; 3714da9060c4SMatthew G. Knepley case 5: ct = DM_POLYTOPE_PYRAMID;break; 3715ba2698f1SMatthew G. Knepley case 6: ct = DM_POLYTOPE_TRI_PRISM_TENSOR;break; 3716ba2698f1SMatthew G. Knepley case 8: ct = DM_POLYTOPE_HEXAHEDRON;break; 3717ba2698f1SMatthew G. Knepley default: break; 3718ba2698f1SMatthew G. Knepley } 3719ba2698f1SMatthew G. Knepley } 3720ba2698f1SMatthew G. Knepley } else { 3721ba2698f1SMatthew G. Knepley if (pdepth == 0) { 3722ba2698f1SMatthew G. Knepley ct = DM_POLYTOPE_POINT; 3723ba2698f1SMatthew G. Knepley } else if (pheight == 0) { 3724ba2698f1SMatthew G. Knepley switch (dim) { 3725ba2698f1SMatthew G. Knepley case 1: 3726ba2698f1SMatthew G. Knepley switch (coneSize) { 3727ba2698f1SMatthew G. Knepley case 2: ct = DM_POLYTOPE_SEGMENT;break; 3728ba2698f1SMatthew G. Knepley default: break; 3729ba2698f1SMatthew G. Knepley } 3730ba2698f1SMatthew G. Knepley break; 3731ba2698f1SMatthew G. Knepley case 2: 3732ba2698f1SMatthew G. Knepley switch (coneSize) { 3733ba2698f1SMatthew G. Knepley case 3: ct = DM_POLYTOPE_TRIANGLE;break; 3734ba2698f1SMatthew G. Knepley case 4: ct = DM_POLYTOPE_QUADRILATERAL;break; 3735ba2698f1SMatthew G. Knepley default: break; 3736ba2698f1SMatthew G. Knepley } 3737ba2698f1SMatthew G. Knepley break; 3738ba2698f1SMatthew G. Knepley case 3: 3739ba2698f1SMatthew G. Knepley switch (coneSize) { 3740ba2698f1SMatthew G. Knepley case 4: ct = DM_POLYTOPE_TETRAHEDRON;break; 3741da9060c4SMatthew G. Knepley case 5: 3742da9060c4SMatthew G. Knepley { 3743da9060c4SMatthew G. Knepley const PetscInt *cone; 3744da9060c4SMatthew G. Knepley PetscInt faceConeSize; 3745da9060c4SMatthew G. Knepley 3746da9060c4SMatthew G. Knepley ierr = DMPlexGetCone(dm, p, &cone);CHKERRQ(ierr); 3747da9060c4SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, cone[0], &faceConeSize);CHKERRQ(ierr); 3748da9060c4SMatthew G. Knepley switch (faceConeSize) { 3749da9060c4SMatthew G. Knepley case 3: ct = DM_POLYTOPE_TRI_PRISM_TENSOR;break; 3750da9060c4SMatthew G. Knepley case 4: ct = DM_POLYTOPE_PYRAMID;break; 3751da9060c4SMatthew G. Knepley } 3752da9060c4SMatthew G. Knepley } 3753da9060c4SMatthew G. Knepley break; 3754ba2698f1SMatthew G. Knepley case 6: ct = DM_POLYTOPE_HEXAHEDRON;break; 3755ba2698f1SMatthew G. Knepley default: break; 3756ba2698f1SMatthew G. Knepley } 3757ba2698f1SMatthew G. Knepley break; 3758ba2698f1SMatthew G. Knepley default: break; 3759ba2698f1SMatthew G. Knepley } 3760ba2698f1SMatthew G. Knepley } else if (pheight > 0) { 3761ba2698f1SMatthew G. Knepley switch (coneSize) { 3762ba2698f1SMatthew G. Knepley case 2: ct = DM_POLYTOPE_SEGMENT;break; 3763ba2698f1SMatthew G. Knepley case 3: ct = DM_POLYTOPE_TRIANGLE;break; 3764ba2698f1SMatthew G. Knepley case 4: ct = DM_POLYTOPE_QUADRILATERAL;break; 3765ba2698f1SMatthew G. Knepley default: break; 3766ba2698f1SMatthew G. Knepley } 3767ba2698f1SMatthew G. Knepley } 3768ba2698f1SMatthew G. Knepley } 3769412e9a14SMatthew G. Knepley *pt = ct; 3770412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 3771ba2698f1SMatthew G. Knepley } 3772412e9a14SMatthew G. Knepley 3773412e9a14SMatthew G. Knepley /*@ 3774412e9a14SMatthew G. Knepley DMPlexComputeCellTypes - Infer the polytope type of every cell using its dimension and cone size. 3775412e9a14SMatthew G. Knepley 3776412e9a14SMatthew G. Knepley Collective on dm 3777412e9a14SMatthew G. Knepley 3778412e9a14SMatthew G. Knepley Input Parameter: 3779412e9a14SMatthew G. Knepley . mesh - The DMPlex 3780412e9a14SMatthew G. Knepley 3781412e9a14SMatthew G. Knepley DMPlexComputeCellTypes() should be called after all calls to DMPlexSymmetrize() and DMPlexStratify() 3782412e9a14SMatthew G. Knepley 3783412e9a14SMatthew G. Knepley Level: developer 3784412e9a14SMatthew G. Knepley 3785412e9a14SMatthew G. Knepley Note: This function is normally called automatically by Plex when a cell type is requested. It creates an 3786412e9a14SMatthew G. Knepley internal DMLabel named "celltype" which can be directly accessed using DMGetLabel(). A user may disable 3787412e9a14SMatthew G. Knepley automatic creation by creating the label manually, using DMCreateLabel(dm, "celltype"). 3788412e9a14SMatthew G. Knepley 3789412e9a14SMatthew G. Knepley .seealso: DMPlexCreate(), DMPlexSymmetrize(), DMPlexStratify(), DMGetLabel(), DMCreateLabel() 3790412e9a14SMatthew G. Knepley @*/ 3791412e9a14SMatthew G. Knepley PetscErrorCode DMPlexComputeCellTypes(DM dm) 3792412e9a14SMatthew G. Knepley { 3793412e9a14SMatthew G. Knepley DM_Plex *mesh; 3794412e9a14SMatthew G. Knepley DMLabel ctLabel; 3795412e9a14SMatthew G. Knepley PetscInt pStart, pEnd, p; 3796412e9a14SMatthew G. Knepley PetscErrorCode ierr; 3797412e9a14SMatthew G. Knepley 3798412e9a14SMatthew G. Knepley PetscFunctionBegin; 3799412e9a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3800412e9a14SMatthew G. Knepley mesh = (DM_Plex *) dm->data; 3801412e9a14SMatthew G. Knepley ierr = DMCreateLabel(dm, "celltype");CHKERRQ(ierr); 3802412e9a14SMatthew G. Knepley ierr = DMPlexGetCellTypeLabel(dm, &ctLabel);CHKERRQ(ierr); 3803412e9a14SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 3804412e9a14SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 3805327c2912SStefano Zampini DMPolytopeType ct = DM_POLYTOPE_UNKNOWN; 3806412e9a14SMatthew G. Knepley PetscInt pdepth; 3807412e9a14SMatthew G. Knepley 3808412e9a14SMatthew G. Knepley ierr = DMPlexGetPointDepth(dm, p, &pdepth);CHKERRQ(ierr); 3809412e9a14SMatthew G. Knepley ierr = DMPlexComputeCellType_Internal(dm, p, pdepth, &ct);CHKERRQ(ierr); 3810412e9a14SMatthew G. Knepley if (ct == DM_POLYTOPE_UNKNOWN) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "Point %D is screwed up", p); 3811412e9a14SMatthew G. Knepley ierr = DMLabelSetValue(ctLabel, p, ct);CHKERRQ(ierr); 3812412e9a14SMatthew G. Knepley } 3813412e9a14SMatthew G. Knepley ierr = PetscObjectStateGet((PetscObject) ctLabel, &mesh->celltypeState);CHKERRQ(ierr); 3814412e9a14SMatthew G. Knepley ierr = PetscObjectViewFromOptions((PetscObject) ctLabel, NULL, "-dm_plex_celltypes_view");CHKERRQ(ierr); 3815ba2698f1SMatthew G. Knepley PetscFunctionReturn(0); 3816ba2698f1SMatthew G. Knepley } 3817ba2698f1SMatthew G. Knepley 3818552f7358SJed Brown /*@C 3819552f7358SJed Brown DMPlexGetJoin - Get an array for the join of the set of points 3820552f7358SJed Brown 3821552f7358SJed Brown Not Collective 3822552f7358SJed Brown 3823552f7358SJed Brown Input Parameters: 3824552f7358SJed Brown + dm - The DMPlex object 3825552f7358SJed Brown . numPoints - The number of input points for the join 3826552f7358SJed Brown - points - The input points 3827552f7358SJed Brown 3828552f7358SJed Brown Output Parameters: 3829552f7358SJed Brown + numCoveredPoints - The number of points in the join 3830552f7358SJed Brown - coveredPoints - The points in the join 3831552f7358SJed Brown 3832552f7358SJed Brown Level: intermediate 3833552f7358SJed Brown 3834552f7358SJed Brown Note: Currently, this is restricted to a single level join 3835552f7358SJed Brown 38363813dfbdSMatthew G Knepley Fortran Notes: 38373813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 38383813dfbdSMatthew G Knepley include petsc.h90 in your code. 38393813dfbdSMatthew G Knepley 38403813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 38413813dfbdSMatthew G Knepley 3842552f7358SJed Brown .seealso: DMPlexRestoreJoin(), DMPlexGetMeet() 3843552f7358SJed Brown @*/ 3844552f7358SJed Brown PetscErrorCode DMPlexGetJoin(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 3845552f7358SJed Brown { 3846552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3847552f7358SJed Brown PetscInt *join[2]; 3848552f7358SJed Brown PetscInt joinSize, i = 0; 3849552f7358SJed Brown PetscInt dof, off, p, c, m; 3850552f7358SJed Brown PetscErrorCode ierr; 3851552f7358SJed Brown 3852552f7358SJed Brown PetscFunctionBegin; 3853552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 385448bb261cSVaclav Hapla PetscValidIntPointer(points, 3); 385548bb261cSVaclav Hapla PetscValidIntPointer(numCoveredPoints, 4); 385648bb261cSVaclav Hapla PetscValidPointer(coveredPoints, 5); 385769291d52SBarry Smith ierr = DMGetWorkArray(dm, mesh->maxSupportSize, MPIU_INT, &join[0]);CHKERRQ(ierr); 385869291d52SBarry Smith ierr = DMGetWorkArray(dm, mesh->maxSupportSize, MPIU_INT, &join[1]);CHKERRQ(ierr); 3859552f7358SJed Brown /* Copy in support of first point */ 3860552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, points[0], &dof);CHKERRQ(ierr); 3861552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, points[0], &off);CHKERRQ(ierr); 3862552f7358SJed Brown for (joinSize = 0; joinSize < dof; ++joinSize) { 3863552f7358SJed Brown join[i][joinSize] = mesh->supports[off+joinSize]; 3864552f7358SJed Brown } 3865552f7358SJed Brown /* Check each successive support */ 3866552f7358SJed Brown for (p = 1; p < numPoints; ++p) { 3867552f7358SJed Brown PetscInt newJoinSize = 0; 3868552f7358SJed Brown 3869552f7358SJed Brown ierr = PetscSectionGetDof(mesh->supportSection, points[p], &dof);CHKERRQ(ierr); 3870552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->supportSection, points[p], &off);CHKERRQ(ierr); 3871552f7358SJed Brown for (c = 0; c < dof; ++c) { 3872552f7358SJed Brown const PetscInt point = mesh->supports[off+c]; 3873552f7358SJed Brown 3874552f7358SJed Brown for (m = 0; m < joinSize; ++m) { 3875552f7358SJed Brown if (point == join[i][m]) { 3876552f7358SJed Brown join[1-i][newJoinSize++] = point; 3877552f7358SJed Brown break; 3878552f7358SJed Brown } 3879552f7358SJed Brown } 3880552f7358SJed Brown } 3881552f7358SJed Brown joinSize = newJoinSize; 3882552f7358SJed Brown i = 1-i; 3883552f7358SJed Brown } 3884552f7358SJed Brown *numCoveredPoints = joinSize; 3885552f7358SJed Brown *coveredPoints = join[i]; 388669291d52SBarry Smith ierr = DMRestoreWorkArray(dm, mesh->maxSupportSize, MPIU_INT, &join[1-i]);CHKERRQ(ierr); 3887552f7358SJed Brown PetscFunctionReturn(0); 3888552f7358SJed Brown } 3889552f7358SJed Brown 3890552f7358SJed Brown /*@C 3891552f7358SJed Brown DMPlexRestoreJoin - Restore an array for the join of the set of points 3892552f7358SJed Brown 3893552f7358SJed Brown Not Collective 3894552f7358SJed Brown 3895552f7358SJed Brown Input Parameters: 3896552f7358SJed Brown + dm - The DMPlex object 3897552f7358SJed Brown . numPoints - The number of input points for the join 3898552f7358SJed Brown - points - The input points 3899552f7358SJed Brown 3900552f7358SJed Brown Output Parameters: 3901552f7358SJed Brown + numCoveredPoints - The number of points in the join 3902552f7358SJed Brown - coveredPoints - The points in the join 3903552f7358SJed Brown 39043813dfbdSMatthew G Knepley Fortran Notes: 39053813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 39063813dfbdSMatthew G Knepley include petsc.h90 in your code. 39073813dfbdSMatthew G Knepley 39083813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 39093813dfbdSMatthew G Knepley 3910552f7358SJed Brown Level: intermediate 3911552f7358SJed Brown 3912552f7358SJed Brown .seealso: DMPlexGetJoin(), DMPlexGetFullJoin(), DMPlexGetMeet() 3913552f7358SJed Brown @*/ 3914552f7358SJed Brown PetscErrorCode DMPlexRestoreJoin(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 3915552f7358SJed Brown { 3916552f7358SJed Brown PetscErrorCode ierr; 3917552f7358SJed Brown 3918552f7358SJed Brown PetscFunctionBegin; 3919552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 3920d7902bd2SMatthew G. Knepley if (points) PetscValidIntPointer(points,3); 3921d7902bd2SMatthew G. Knepley if (numCoveredPoints) PetscValidIntPointer(numCoveredPoints,4); 3922d7902bd2SMatthew G. Knepley PetscValidPointer(coveredPoints, 5); 392369291d52SBarry Smith ierr = DMRestoreWorkArray(dm, 0, MPIU_INT, (void*) coveredPoints);CHKERRQ(ierr); 3924d7902bd2SMatthew G. Knepley if (numCoveredPoints) *numCoveredPoints = 0; 3925552f7358SJed Brown PetscFunctionReturn(0); 3926552f7358SJed Brown } 3927552f7358SJed Brown 3928552f7358SJed Brown /*@C 3929552f7358SJed Brown DMPlexGetFullJoin - Get an array for the join of the set of points 3930552f7358SJed Brown 3931552f7358SJed Brown Not Collective 3932552f7358SJed Brown 3933552f7358SJed Brown Input Parameters: 3934552f7358SJed Brown + dm - The DMPlex object 3935552f7358SJed Brown . numPoints - The number of input points for the join 3936552f7358SJed Brown - points - The input points 3937552f7358SJed Brown 3938552f7358SJed Brown Output Parameters: 3939552f7358SJed Brown + numCoveredPoints - The number of points in the join 3940552f7358SJed Brown - coveredPoints - The points in the join 3941552f7358SJed Brown 39423813dfbdSMatthew G Knepley Fortran Notes: 39433813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 39443813dfbdSMatthew G Knepley include petsc.h90 in your code. 39453813dfbdSMatthew G Knepley 39463813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 39473813dfbdSMatthew G Knepley 3948552f7358SJed Brown Level: intermediate 3949552f7358SJed Brown 3950552f7358SJed Brown .seealso: DMPlexGetJoin(), DMPlexRestoreJoin(), DMPlexGetMeet() 3951552f7358SJed Brown @*/ 3952552f7358SJed Brown PetscErrorCode DMPlexGetFullJoin(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 3953552f7358SJed Brown { 3954552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 3955552f7358SJed Brown PetscInt *offsets, **closures; 3956552f7358SJed Brown PetscInt *join[2]; 3957552f7358SJed Brown PetscInt depth = 0, maxSize, joinSize = 0, i = 0; 395824c766afSToby Isaac PetscInt p, d, c, m, ms; 3959552f7358SJed Brown PetscErrorCode ierr; 3960552f7358SJed Brown 3961552f7358SJed Brown PetscFunctionBegin; 3962552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 396348bb261cSVaclav Hapla PetscValidIntPointer(points, 3); 396448bb261cSVaclav Hapla PetscValidIntPointer(numCoveredPoints, 4); 396548bb261cSVaclav Hapla PetscValidPointer(coveredPoints, 5); 3966552f7358SJed Brown 3967552f7358SJed Brown ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 39681795a4d1SJed Brown ierr = PetscCalloc1(numPoints, &closures);CHKERRQ(ierr); 396969291d52SBarry Smith ierr = DMGetWorkArray(dm, numPoints*(depth+2), MPIU_INT, &offsets);CHKERRQ(ierr); 397024c766afSToby Isaac ms = mesh->maxSupportSize; 397124c766afSToby Isaac maxSize = (ms > 1) ? ((PetscPowInt(ms,depth+1)-1)/(ms-1)) : depth + 1; 397269291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &join[0]);CHKERRQ(ierr); 397369291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &join[1]);CHKERRQ(ierr); 3974552f7358SJed Brown 3975552f7358SJed Brown for (p = 0; p < numPoints; ++p) { 3976552f7358SJed Brown PetscInt closureSize; 3977552f7358SJed Brown 3978552f7358SJed Brown ierr = DMPlexGetTransitiveClosure(dm, points[p], PETSC_FALSE, &closureSize, &closures[p]);CHKERRQ(ierr); 39790d644c17SKarl Rupp 3980552f7358SJed Brown offsets[p*(depth+2)+0] = 0; 3981552f7358SJed Brown for (d = 0; d < depth+1; ++d) { 3982552f7358SJed Brown PetscInt pStart, pEnd, i; 3983552f7358SJed Brown 3984552f7358SJed Brown ierr = DMPlexGetDepthStratum(dm, d, &pStart, &pEnd);CHKERRQ(ierr); 3985552f7358SJed Brown for (i = offsets[p*(depth+2)+d]; i < closureSize; ++i) { 3986552f7358SJed Brown if ((pStart > closures[p][i*2]) || (pEnd <= closures[p][i*2])) { 3987552f7358SJed Brown offsets[p*(depth+2)+d+1] = i; 3988552f7358SJed Brown break; 3989552f7358SJed Brown } 3990552f7358SJed Brown } 3991552f7358SJed Brown if (i == closureSize) offsets[p*(depth+2)+d+1] = i; 3992552f7358SJed Brown } 399382f516ccSBarry 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); 3994552f7358SJed Brown } 3995552f7358SJed Brown for (d = 0; d < depth+1; ++d) { 3996552f7358SJed Brown PetscInt dof; 3997552f7358SJed Brown 3998552f7358SJed Brown /* Copy in support of first point */ 3999552f7358SJed Brown dof = offsets[d+1] - offsets[d]; 4000552f7358SJed Brown for (joinSize = 0; joinSize < dof; ++joinSize) { 4001552f7358SJed Brown join[i][joinSize] = closures[0][(offsets[d]+joinSize)*2]; 4002552f7358SJed Brown } 4003552f7358SJed Brown /* Check each successive cone */ 4004552f7358SJed Brown for (p = 1; p < numPoints && joinSize; ++p) { 4005552f7358SJed Brown PetscInt newJoinSize = 0; 4006552f7358SJed Brown 4007552f7358SJed Brown dof = offsets[p*(depth+2)+d+1] - offsets[p*(depth+2)+d]; 4008552f7358SJed Brown for (c = 0; c < dof; ++c) { 4009552f7358SJed Brown const PetscInt point = closures[p][(offsets[p*(depth+2)+d]+c)*2]; 4010552f7358SJed Brown 4011552f7358SJed Brown for (m = 0; m < joinSize; ++m) { 4012552f7358SJed Brown if (point == join[i][m]) { 4013552f7358SJed Brown join[1-i][newJoinSize++] = point; 4014552f7358SJed Brown break; 4015552f7358SJed Brown } 4016552f7358SJed Brown } 4017552f7358SJed Brown } 4018552f7358SJed Brown joinSize = newJoinSize; 4019552f7358SJed Brown i = 1-i; 4020552f7358SJed Brown } 4021552f7358SJed Brown if (joinSize) break; 4022552f7358SJed Brown } 4023552f7358SJed Brown *numCoveredPoints = joinSize; 4024552f7358SJed Brown *coveredPoints = join[i]; 4025552f7358SJed Brown for (p = 0; p < numPoints; ++p) { 40260298fd71SBarry Smith ierr = DMPlexRestoreTransitiveClosure(dm, points[p], PETSC_FALSE, NULL, &closures[p]);CHKERRQ(ierr); 4027552f7358SJed Brown } 4028552f7358SJed Brown ierr = PetscFree(closures);CHKERRQ(ierr); 402969291d52SBarry Smith ierr = DMRestoreWorkArray(dm, numPoints*(depth+2), MPIU_INT, &offsets);CHKERRQ(ierr); 403069291d52SBarry Smith ierr = DMRestoreWorkArray(dm, mesh->maxSupportSize, MPIU_INT, &join[1-i]);CHKERRQ(ierr); 4031552f7358SJed Brown PetscFunctionReturn(0); 4032552f7358SJed Brown } 4033552f7358SJed Brown 4034552f7358SJed Brown /*@C 4035552f7358SJed Brown DMPlexGetMeet - Get an array for the meet of the set of points 4036552f7358SJed Brown 4037552f7358SJed Brown Not Collective 4038552f7358SJed Brown 4039552f7358SJed Brown Input Parameters: 4040552f7358SJed Brown + dm - The DMPlex object 4041552f7358SJed Brown . numPoints - The number of input points for the meet 4042552f7358SJed Brown - points - The input points 4043552f7358SJed Brown 4044552f7358SJed Brown Output Parameters: 4045552f7358SJed Brown + numCoveredPoints - The number of points in the meet 4046552f7358SJed Brown - coveredPoints - The points in the meet 4047552f7358SJed Brown 4048552f7358SJed Brown Level: intermediate 4049552f7358SJed Brown 4050552f7358SJed Brown Note: Currently, this is restricted to a single level meet 4051552f7358SJed Brown 40523813dfbdSMatthew G Knepley Fortran Notes: 40533813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 40543813dfbdSMatthew G Knepley include petsc.h90 in your code. 40553813dfbdSMatthew G Knepley 40563813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 40573813dfbdSMatthew G Knepley 4058552f7358SJed Brown .seealso: DMPlexRestoreMeet(), DMPlexGetJoin() 4059552f7358SJed Brown @*/ 4060552f7358SJed Brown PetscErrorCode DMPlexGetMeet(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveringPoints, const PetscInt **coveringPoints) 4061552f7358SJed Brown { 4062552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 4063552f7358SJed Brown PetscInt *meet[2]; 4064552f7358SJed Brown PetscInt meetSize, i = 0; 4065552f7358SJed Brown PetscInt dof, off, p, c, m; 4066552f7358SJed Brown PetscErrorCode ierr; 4067552f7358SJed Brown 4068552f7358SJed Brown PetscFunctionBegin; 4069552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4070064a246eSJacob Faibussowitsch PetscValidPointer(points, 3); 4071064a246eSJacob Faibussowitsch PetscValidPointer(numCoveringPoints, 4); 4072064a246eSJacob Faibussowitsch PetscValidPointer(coveringPoints, 5); 407369291d52SBarry Smith ierr = DMGetWorkArray(dm, mesh->maxConeSize, MPIU_INT, &meet[0]);CHKERRQ(ierr); 407469291d52SBarry Smith ierr = DMGetWorkArray(dm, mesh->maxConeSize, MPIU_INT, &meet[1]);CHKERRQ(ierr); 4075552f7358SJed Brown /* Copy in cone of first point */ 4076552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, points[0], &dof);CHKERRQ(ierr); 4077552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, points[0], &off);CHKERRQ(ierr); 4078552f7358SJed Brown for (meetSize = 0; meetSize < dof; ++meetSize) { 4079552f7358SJed Brown meet[i][meetSize] = mesh->cones[off+meetSize]; 4080552f7358SJed Brown } 4081552f7358SJed Brown /* Check each successive cone */ 4082552f7358SJed Brown for (p = 1; p < numPoints; ++p) { 4083552f7358SJed Brown PetscInt newMeetSize = 0; 4084552f7358SJed Brown 4085552f7358SJed Brown ierr = PetscSectionGetDof(mesh->coneSection, points[p], &dof);CHKERRQ(ierr); 4086552f7358SJed Brown ierr = PetscSectionGetOffset(mesh->coneSection, points[p], &off);CHKERRQ(ierr); 4087552f7358SJed Brown for (c = 0; c < dof; ++c) { 4088552f7358SJed Brown const PetscInt point = mesh->cones[off+c]; 4089552f7358SJed Brown 4090552f7358SJed Brown for (m = 0; m < meetSize; ++m) { 4091552f7358SJed Brown if (point == meet[i][m]) { 4092552f7358SJed Brown meet[1-i][newMeetSize++] = point; 4093552f7358SJed Brown break; 4094552f7358SJed Brown } 4095552f7358SJed Brown } 4096552f7358SJed Brown } 4097552f7358SJed Brown meetSize = newMeetSize; 4098552f7358SJed Brown i = 1-i; 4099552f7358SJed Brown } 4100552f7358SJed Brown *numCoveringPoints = meetSize; 4101552f7358SJed Brown *coveringPoints = meet[i]; 410269291d52SBarry Smith ierr = DMRestoreWorkArray(dm, mesh->maxConeSize, MPIU_INT, &meet[1-i]);CHKERRQ(ierr); 4103552f7358SJed Brown PetscFunctionReturn(0); 4104552f7358SJed Brown } 4105552f7358SJed Brown 4106552f7358SJed Brown /*@C 4107552f7358SJed Brown DMPlexRestoreMeet - Restore an array for the meet of the set of points 4108552f7358SJed Brown 4109552f7358SJed Brown Not Collective 4110552f7358SJed Brown 4111552f7358SJed Brown Input Parameters: 4112552f7358SJed Brown + dm - The DMPlex object 4113552f7358SJed Brown . numPoints - The number of input points for the meet 4114552f7358SJed Brown - points - The input points 4115552f7358SJed Brown 4116552f7358SJed Brown Output Parameters: 4117552f7358SJed Brown + numCoveredPoints - The number of points in the meet 4118552f7358SJed Brown - coveredPoints - The points in the meet 4119552f7358SJed Brown 4120552f7358SJed Brown Level: intermediate 4121552f7358SJed Brown 41223813dfbdSMatthew G Knepley Fortran Notes: 41233813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 41243813dfbdSMatthew G Knepley include petsc.h90 in your code. 41253813dfbdSMatthew G Knepley 41263813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 41273813dfbdSMatthew G Knepley 4128552f7358SJed Brown .seealso: DMPlexGetMeet(), DMPlexGetFullMeet(), DMPlexGetJoin() 4129552f7358SJed Brown @*/ 4130552f7358SJed Brown PetscErrorCode DMPlexRestoreMeet(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 4131552f7358SJed Brown { 4132552f7358SJed Brown PetscErrorCode ierr; 4133552f7358SJed Brown 4134552f7358SJed Brown PetscFunctionBegin; 4135552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4136d7902bd2SMatthew G. Knepley if (points) PetscValidIntPointer(points,3); 4137d7902bd2SMatthew G. Knepley if (numCoveredPoints) PetscValidIntPointer(numCoveredPoints,4); 4138d7902bd2SMatthew G. Knepley PetscValidPointer(coveredPoints,5); 413969291d52SBarry Smith ierr = DMRestoreWorkArray(dm, 0, MPIU_INT, (void*) coveredPoints);CHKERRQ(ierr); 4140d7902bd2SMatthew G. Knepley if (numCoveredPoints) *numCoveredPoints = 0; 4141552f7358SJed Brown PetscFunctionReturn(0); 4142552f7358SJed Brown } 4143552f7358SJed Brown 4144552f7358SJed Brown /*@C 4145552f7358SJed Brown DMPlexGetFullMeet - Get an array for the meet of the set of points 4146552f7358SJed Brown 4147552f7358SJed Brown Not Collective 4148552f7358SJed Brown 4149552f7358SJed Brown Input Parameters: 4150552f7358SJed Brown + dm - The DMPlex object 4151552f7358SJed Brown . numPoints - The number of input points for the meet 4152552f7358SJed Brown - points - The input points 4153552f7358SJed Brown 4154552f7358SJed Brown Output Parameters: 4155552f7358SJed Brown + numCoveredPoints - The number of points in the meet 4156552f7358SJed Brown - coveredPoints - The points in the meet 4157552f7358SJed Brown 4158552f7358SJed Brown Level: intermediate 4159552f7358SJed Brown 41603813dfbdSMatthew G Knepley Fortran Notes: 41613813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 41623813dfbdSMatthew G Knepley include petsc.h90 in your code. 41633813dfbdSMatthew G Knepley 41643813dfbdSMatthew G Knepley The numCoveredPoints argument is not present in the Fortran 90 binding since it is internal to the array. 41653813dfbdSMatthew G Knepley 4166552f7358SJed Brown .seealso: DMPlexGetMeet(), DMPlexRestoreMeet(), DMPlexGetJoin() 4167552f7358SJed Brown @*/ 4168552f7358SJed Brown PetscErrorCode DMPlexGetFullMeet(DM dm, PetscInt numPoints, const PetscInt points[], PetscInt *numCoveredPoints, const PetscInt **coveredPoints) 4169552f7358SJed Brown { 4170552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 4171552f7358SJed Brown PetscInt *offsets, **closures; 4172552f7358SJed Brown PetscInt *meet[2]; 4173552f7358SJed Brown PetscInt height = 0, maxSize, meetSize = 0, i = 0; 417424c766afSToby Isaac PetscInt p, h, c, m, mc; 4175552f7358SJed Brown PetscErrorCode ierr; 4176552f7358SJed Brown 4177552f7358SJed Brown PetscFunctionBegin; 4178552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4179064a246eSJacob Faibussowitsch PetscValidPointer(points, 3); 4180064a246eSJacob Faibussowitsch PetscValidPointer(numCoveredPoints, 4); 4181064a246eSJacob Faibussowitsch PetscValidPointer(coveredPoints, 5); 4182552f7358SJed Brown 4183552f7358SJed Brown ierr = DMPlexGetDepth(dm, &height);CHKERRQ(ierr); 4184785e854fSJed Brown ierr = PetscMalloc1(numPoints, &closures);CHKERRQ(ierr); 418569291d52SBarry Smith ierr = DMGetWorkArray(dm, numPoints*(height+2), MPIU_INT, &offsets);CHKERRQ(ierr); 418624c766afSToby Isaac mc = mesh->maxConeSize; 418724c766afSToby Isaac maxSize = (mc > 1) ? ((PetscPowInt(mc,height+1)-1)/(mc-1)) : height + 1; 418869291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &meet[0]);CHKERRQ(ierr); 418969291d52SBarry Smith ierr = DMGetWorkArray(dm, maxSize, MPIU_INT, &meet[1]);CHKERRQ(ierr); 4190552f7358SJed Brown 4191552f7358SJed Brown for (p = 0; p < numPoints; ++p) { 4192552f7358SJed Brown PetscInt closureSize; 4193552f7358SJed Brown 4194552f7358SJed Brown ierr = DMPlexGetTransitiveClosure(dm, points[p], PETSC_TRUE, &closureSize, &closures[p]);CHKERRQ(ierr); 41950d644c17SKarl Rupp 4196552f7358SJed Brown offsets[p*(height+2)+0] = 0; 4197552f7358SJed Brown for (h = 0; h < height+1; ++h) { 4198552f7358SJed Brown PetscInt pStart, pEnd, i; 4199552f7358SJed Brown 4200552f7358SJed Brown ierr = DMPlexGetHeightStratum(dm, h, &pStart, &pEnd);CHKERRQ(ierr); 4201552f7358SJed Brown for (i = offsets[p*(height+2)+h]; i < closureSize; ++i) { 4202552f7358SJed Brown if ((pStart > closures[p][i*2]) || (pEnd <= closures[p][i*2])) { 4203552f7358SJed Brown offsets[p*(height+2)+h+1] = i; 4204552f7358SJed Brown break; 4205552f7358SJed Brown } 4206552f7358SJed Brown } 4207552f7358SJed Brown if (i == closureSize) offsets[p*(height+2)+h+1] = i; 4208552f7358SJed Brown } 420982f516ccSBarry 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); 4210552f7358SJed Brown } 4211552f7358SJed Brown for (h = 0; h < height+1; ++h) { 4212552f7358SJed Brown PetscInt dof; 4213552f7358SJed Brown 4214552f7358SJed Brown /* Copy in cone of first point */ 4215552f7358SJed Brown dof = offsets[h+1] - offsets[h]; 4216552f7358SJed Brown for (meetSize = 0; meetSize < dof; ++meetSize) { 4217552f7358SJed Brown meet[i][meetSize] = closures[0][(offsets[h]+meetSize)*2]; 4218552f7358SJed Brown } 4219552f7358SJed Brown /* Check each successive cone */ 4220552f7358SJed Brown for (p = 1; p < numPoints && meetSize; ++p) { 4221552f7358SJed Brown PetscInt newMeetSize = 0; 4222552f7358SJed Brown 4223552f7358SJed Brown dof = offsets[p*(height+2)+h+1] - offsets[p*(height+2)+h]; 4224552f7358SJed Brown for (c = 0; c < dof; ++c) { 4225552f7358SJed Brown const PetscInt point = closures[p][(offsets[p*(height+2)+h]+c)*2]; 4226552f7358SJed Brown 4227552f7358SJed Brown for (m = 0; m < meetSize; ++m) { 4228552f7358SJed Brown if (point == meet[i][m]) { 4229552f7358SJed Brown meet[1-i][newMeetSize++] = point; 4230552f7358SJed Brown break; 4231552f7358SJed Brown } 4232552f7358SJed Brown } 4233552f7358SJed Brown } 4234552f7358SJed Brown meetSize = newMeetSize; 4235552f7358SJed Brown i = 1-i; 4236552f7358SJed Brown } 4237552f7358SJed Brown if (meetSize) break; 4238552f7358SJed Brown } 4239552f7358SJed Brown *numCoveredPoints = meetSize; 4240552f7358SJed Brown *coveredPoints = meet[i]; 4241552f7358SJed Brown for (p = 0; p < numPoints; ++p) { 42420298fd71SBarry Smith ierr = DMPlexRestoreTransitiveClosure(dm, points[p], PETSC_TRUE, NULL, &closures[p]);CHKERRQ(ierr); 4243552f7358SJed Brown } 4244552f7358SJed Brown ierr = PetscFree(closures);CHKERRQ(ierr); 424569291d52SBarry Smith ierr = DMRestoreWorkArray(dm, numPoints*(height+2), MPIU_INT, &offsets);CHKERRQ(ierr); 424669291d52SBarry Smith ierr = DMRestoreWorkArray(dm, mesh->maxConeSize, MPIU_INT, &meet[1-i]);CHKERRQ(ierr); 4247552f7358SJed Brown PetscFunctionReturn(0); 4248552f7358SJed Brown } 4249552f7358SJed Brown 42504e3744c5SMatthew G. Knepley /*@C 42514e3744c5SMatthew G. Knepley DMPlexEqual - Determine if two DMs have the same topology 42524e3744c5SMatthew G. Knepley 42534e3744c5SMatthew G. Knepley Not Collective 42544e3744c5SMatthew G. Knepley 42554e3744c5SMatthew G. Knepley Input Parameters: 42564e3744c5SMatthew G. Knepley + dmA - A DMPlex object 42574e3744c5SMatthew G. Knepley - dmB - A DMPlex object 42584e3744c5SMatthew G. Knepley 42594e3744c5SMatthew G. Knepley Output Parameters: 42604e3744c5SMatthew G. Knepley . equal - PETSC_TRUE if the topologies are identical 42614e3744c5SMatthew G. Knepley 42624e3744c5SMatthew G. Knepley Level: intermediate 42634e3744c5SMatthew G. Knepley 42644e3744c5SMatthew G. Knepley Notes: 42654e3744c5SMatthew G. Knepley We are not solving graph isomorphism, so we do not permutation. 42664e3744c5SMatthew G. Knepley 42674e3744c5SMatthew G. Knepley .seealso: DMPlexGetCone() 42684e3744c5SMatthew G. Knepley @*/ 42694e3744c5SMatthew G. Knepley PetscErrorCode DMPlexEqual(DM dmA, DM dmB, PetscBool *equal) 42704e3744c5SMatthew G. Knepley { 42714e3744c5SMatthew G. Knepley PetscInt depth, depthB, pStart, pEnd, pStartB, pEndB, p; 42724e3744c5SMatthew G. Knepley PetscErrorCode ierr; 42734e3744c5SMatthew G. Knepley 42744e3744c5SMatthew G. Knepley PetscFunctionBegin; 42754e3744c5SMatthew G. Knepley PetscValidHeaderSpecific(dmA, DM_CLASSID, 1); 42764e3744c5SMatthew G. Knepley PetscValidHeaderSpecific(dmB, DM_CLASSID, 2); 42774e3744c5SMatthew G. Knepley PetscValidPointer(equal, 3); 42784e3744c5SMatthew G. Knepley 42794e3744c5SMatthew G. Knepley *equal = PETSC_FALSE; 42804e3744c5SMatthew G. Knepley ierr = DMPlexGetDepth(dmA, &depth);CHKERRQ(ierr); 42814e3744c5SMatthew G. Knepley ierr = DMPlexGetDepth(dmB, &depthB);CHKERRQ(ierr); 42824e3744c5SMatthew G. Knepley if (depth != depthB) PetscFunctionReturn(0); 42834e3744c5SMatthew G. Knepley ierr = DMPlexGetChart(dmA, &pStart, &pEnd);CHKERRQ(ierr); 42844e3744c5SMatthew G. Knepley ierr = DMPlexGetChart(dmB, &pStartB, &pEndB);CHKERRQ(ierr); 42854e3744c5SMatthew G. Knepley if ((pStart != pStartB) || (pEnd != pEndB)) PetscFunctionReturn(0); 42864e3744c5SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 42874e3744c5SMatthew G. Knepley const PetscInt *cone, *coneB, *ornt, *orntB, *support, *supportB; 42884e3744c5SMatthew G. Knepley PetscInt coneSize, coneSizeB, c, supportSize, supportSizeB, s; 42894e3744c5SMatthew G. Knepley 42904e3744c5SMatthew G. Knepley ierr = DMPlexGetConeSize(dmA, p, &coneSize);CHKERRQ(ierr); 42914e3744c5SMatthew G. Knepley ierr = DMPlexGetCone(dmA, p, &cone);CHKERRQ(ierr); 42924e3744c5SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dmA, p, &ornt);CHKERRQ(ierr); 42934e3744c5SMatthew G. Knepley ierr = DMPlexGetConeSize(dmB, p, &coneSizeB);CHKERRQ(ierr); 42944e3744c5SMatthew G. Knepley ierr = DMPlexGetCone(dmB, p, &coneB);CHKERRQ(ierr); 42954e3744c5SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dmB, p, &orntB);CHKERRQ(ierr); 42964e3744c5SMatthew G. Knepley if (coneSize != coneSizeB) PetscFunctionReturn(0); 42974e3744c5SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 42984e3744c5SMatthew G. Knepley if (cone[c] != coneB[c]) PetscFunctionReturn(0); 42994e3744c5SMatthew G. Knepley if (ornt[c] != orntB[c]) PetscFunctionReturn(0); 43004e3744c5SMatthew G. Knepley } 43014e3744c5SMatthew G. Knepley ierr = DMPlexGetSupportSize(dmA, p, &supportSize);CHKERRQ(ierr); 43024e3744c5SMatthew G. Knepley ierr = DMPlexGetSupport(dmA, p, &support);CHKERRQ(ierr); 43034e3744c5SMatthew G. Knepley ierr = DMPlexGetSupportSize(dmB, p, &supportSizeB);CHKERRQ(ierr); 43044e3744c5SMatthew G. Knepley ierr = DMPlexGetSupport(dmB, p, &supportB);CHKERRQ(ierr); 43054e3744c5SMatthew G. Knepley if (supportSize != supportSizeB) PetscFunctionReturn(0); 43064e3744c5SMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 43074e3744c5SMatthew G. Knepley if (support[s] != supportB[s]) PetscFunctionReturn(0); 43084e3744c5SMatthew G. Knepley } 43094e3744c5SMatthew G. Knepley } 43104e3744c5SMatthew G. Knepley *equal = PETSC_TRUE; 43114e3744c5SMatthew G. Knepley PetscFunctionReturn(0); 43124e3744c5SMatthew G. Knepley } 43134e3744c5SMatthew G. Knepley 43147cd05799SMatthew G. Knepley /*@C 43157cd05799SMatthew G. Knepley DMPlexGetNumFaceVertices - Returns the number of vertices on a face 43167cd05799SMatthew G. Knepley 43177cd05799SMatthew G. Knepley Not Collective 43187cd05799SMatthew G. Knepley 43197cd05799SMatthew G. Knepley Input Parameters: 43207cd05799SMatthew G. Knepley + dm - The DMPlex 43217cd05799SMatthew G. Knepley . cellDim - The cell dimension 43227cd05799SMatthew G. Knepley - numCorners - The number of vertices on a cell 43237cd05799SMatthew G. Knepley 43247cd05799SMatthew G. Knepley Output Parameters: 43257cd05799SMatthew G. Knepley . numFaceVertices - The number of vertices on a face 43267cd05799SMatthew G. Knepley 43277cd05799SMatthew G. Knepley Level: developer 43287cd05799SMatthew G. Knepley 43297cd05799SMatthew G. Knepley Notes: 43307cd05799SMatthew G. Knepley Of course this can only work for a restricted set of symmetric shapes 43317cd05799SMatthew G. Knepley 43327cd05799SMatthew G. Knepley .seealso: DMPlexGetCone() 43337cd05799SMatthew G. Knepley @*/ 433418ad9376SMatthew G. Knepley PetscErrorCode DMPlexGetNumFaceVertices(DM dm, PetscInt cellDim, PetscInt numCorners, PetscInt *numFaceVertices) 4335a6dfd86eSKarl Rupp { 433682f516ccSBarry Smith MPI_Comm comm; 4337552f7358SJed Brown PetscErrorCode ierr; 4338552f7358SJed Brown 4339552f7358SJed Brown PetscFunctionBegin; 434082f516ccSBarry Smith ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); 4341064a246eSJacob Faibussowitsch PetscValidPointer(numFaceVertices,4); 4342552f7358SJed Brown switch (cellDim) { 4343552f7358SJed Brown case 0: 4344552f7358SJed Brown *numFaceVertices = 0; 4345552f7358SJed Brown break; 4346552f7358SJed Brown case 1: 4347552f7358SJed Brown *numFaceVertices = 1; 4348552f7358SJed Brown break; 4349552f7358SJed Brown case 2: 4350552f7358SJed Brown switch (numCorners) { 435119436ca2SJed Brown case 3: /* triangle */ 435219436ca2SJed Brown *numFaceVertices = 2; /* Edge has 2 vertices */ 4353552f7358SJed Brown break; 435419436ca2SJed Brown case 4: /* quadrilateral */ 435519436ca2SJed Brown *numFaceVertices = 2; /* Edge has 2 vertices */ 4356552f7358SJed Brown break; 435719436ca2SJed Brown case 6: /* quadratic triangle, tri and quad cohesive Lagrange cells */ 435819436ca2SJed Brown *numFaceVertices = 3; /* Edge has 3 vertices */ 4359552f7358SJed Brown break; 436019436ca2SJed Brown case 9: /* quadratic quadrilateral, quadratic quad cohesive Lagrange cells */ 436119436ca2SJed Brown *numFaceVertices = 3; /* Edge has 3 vertices */ 4362552f7358SJed Brown break; 4363552f7358SJed Brown default: 4364f347f43bSBarry Smith SETERRQ2(comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid number of face corners %D for dimension %D", numCorners, cellDim); 4365552f7358SJed Brown } 4366552f7358SJed Brown break; 4367552f7358SJed Brown case 3: 4368552f7358SJed Brown switch (numCorners) { 436919436ca2SJed Brown case 4: /* tetradehdron */ 437019436ca2SJed Brown *numFaceVertices = 3; /* Face has 3 vertices */ 4371552f7358SJed Brown break; 437219436ca2SJed Brown case 6: /* tet cohesive cells */ 437319436ca2SJed Brown *numFaceVertices = 4; /* Face has 4 vertices */ 4374552f7358SJed Brown break; 437519436ca2SJed Brown case 8: /* hexahedron */ 437619436ca2SJed Brown *numFaceVertices = 4; /* Face has 4 vertices */ 4377552f7358SJed Brown break; 437819436ca2SJed Brown case 9: /* tet cohesive Lagrange cells */ 437919436ca2SJed Brown *numFaceVertices = 6; /* Face has 6 vertices */ 4380552f7358SJed Brown break; 438119436ca2SJed Brown case 10: /* quadratic tetrahedron */ 438219436ca2SJed Brown *numFaceVertices = 6; /* Face has 6 vertices */ 4383552f7358SJed Brown break; 438419436ca2SJed Brown case 12: /* hex cohesive Lagrange cells */ 438519436ca2SJed Brown *numFaceVertices = 6; /* Face has 6 vertices */ 4386552f7358SJed Brown break; 438719436ca2SJed Brown case 18: /* quadratic tet cohesive Lagrange cells */ 438819436ca2SJed Brown *numFaceVertices = 6; /* Face has 6 vertices */ 4389552f7358SJed Brown break; 439019436ca2SJed Brown case 27: /* quadratic hexahedron, quadratic hex cohesive Lagrange cells */ 439119436ca2SJed Brown *numFaceVertices = 9; /* Face has 9 vertices */ 4392552f7358SJed Brown break; 4393552f7358SJed Brown default: 4394f347f43bSBarry Smith SETERRQ2(comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid number of face corners %D for dimension %D", numCorners, cellDim); 4395552f7358SJed Brown } 4396552f7358SJed Brown break; 4397552f7358SJed Brown default: 4398f347f43bSBarry Smith SETERRQ1(comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid cell dimension %D", cellDim); 4399552f7358SJed Brown } 4400552f7358SJed Brown PetscFunctionReturn(0); 4401552f7358SJed Brown } 4402552f7358SJed Brown 4403552f7358SJed Brown /*@ 4404aa50250dSMatthew G. Knepley DMPlexGetDepthLabel - Get the DMLabel recording the depth of each point 4405552f7358SJed Brown 4406552f7358SJed Brown Not Collective 4407552f7358SJed Brown 4408aa50250dSMatthew G. Knepley Input Parameter: 4409552f7358SJed Brown . dm - The DMPlex object 4410552f7358SJed Brown 4411aa50250dSMatthew G. Knepley Output Parameter: 4412aa50250dSMatthew G. Knepley . depthLabel - The DMLabel recording point depth 4413552f7358SJed Brown 4414552f7358SJed Brown Level: developer 4415552f7358SJed Brown 4416dc287ab2SVaclav Hapla .seealso: DMPlexGetDepth(), DMPlexGetHeightStratum(), DMPlexGetDepthStratum(), DMPlexGetPointDepth(), 4417aa50250dSMatthew G. Knepley @*/ 4418aa50250dSMatthew G. Knepley PetscErrorCode DMPlexGetDepthLabel(DM dm, DMLabel *depthLabel) 4419aa50250dSMatthew G. Knepley { 4420aa50250dSMatthew G. Knepley PetscFunctionBegin; 4421aa50250dSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4422aa50250dSMatthew G. Knepley PetscValidPointer(depthLabel, 2); 4423c58f1c22SToby Isaac *depthLabel = dm->depthLabel; 4424aa50250dSMatthew G. Knepley PetscFunctionReturn(0); 4425aa50250dSMatthew G. Knepley } 4426aa50250dSMatthew G. Knepley 4427aa50250dSMatthew G. Knepley /*@ 4428aa50250dSMatthew G. Knepley DMPlexGetDepth - Get the depth of the DAG representing this mesh 4429aa50250dSMatthew G. Knepley 4430aa50250dSMatthew G. Knepley Not Collective 4431aa50250dSMatthew G. Knepley 4432aa50250dSMatthew G. Knepley Input Parameter: 4433aa50250dSMatthew G. Knepley . dm - The DMPlex object 4434aa50250dSMatthew G. Knepley 4435aa50250dSMatthew G. Knepley Output Parameter: 4436aa50250dSMatthew G. Knepley . depth - The number of strata (breadth first levels) in the DAG 4437aa50250dSMatthew G. Knepley 4438aa50250dSMatthew G. Knepley Level: developer 4439552f7358SJed Brown 4440b1bb481bSMatthew Knepley Notes: 4441b1bb481bSMatthew Knepley This returns maximum of point depths over all points, i.e. maximum value of the label returned by DMPlexGetDepthLabel(). 4442dc287ab2SVaclav Hapla The point depth is described more in detail in DMPlexGetDepthStratum(). 4443dc287ab2SVaclav Hapla An empty mesh gives -1. 4444b1bb481bSMatthew Knepley 4445dc287ab2SVaclav Hapla .seealso: DMPlexGetDepthLabel(), DMPlexGetDepthStratum(), DMPlexGetPointDepth(), DMPlexSymmetrize() 4446552f7358SJed Brown @*/ 4447552f7358SJed Brown PetscErrorCode DMPlexGetDepth(DM dm, PetscInt *depth) 4448552f7358SJed Brown { 4449aa50250dSMatthew G. Knepley DMLabel label; 4450aa50250dSMatthew G. Knepley PetscInt d = 0; 4451552f7358SJed Brown PetscErrorCode ierr; 4452552f7358SJed Brown 4453552f7358SJed Brown PetscFunctionBegin; 4454552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4455552f7358SJed Brown PetscValidPointer(depth, 2); 4456aa50250dSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 4457aa50250dSMatthew G. Knepley if (label) {ierr = DMLabelGetNumValues(label, &d);CHKERRQ(ierr);} 4458552f7358SJed Brown *depth = d-1; 4459552f7358SJed Brown PetscFunctionReturn(0); 4460552f7358SJed Brown } 4461552f7358SJed Brown 4462552f7358SJed Brown /*@ 4463552f7358SJed Brown DMPlexGetDepthStratum - Get the bounds [start, end) for all points at a certain depth. 4464552f7358SJed Brown 4465552f7358SJed Brown Not Collective 4466552f7358SJed Brown 4467552f7358SJed Brown Input Parameters: 4468552f7358SJed Brown + dm - The DMPlex object 4469552f7358SJed Brown - stratumValue - The requested depth 4470552f7358SJed Brown 4471552f7358SJed Brown Output Parameters: 4472552f7358SJed Brown + start - The first point at this depth 4473552f7358SJed Brown - end - One beyond the last point at this depth 4474552f7358SJed Brown 4475647867b2SJed Brown Notes: 4476647867b2SJed Brown Depth indexing is related to topological dimension. Depth stratum 0 contains the lowest topological dimension points, 4477647867b2SJed Brown often "vertices". If the mesh is "interpolated" (see DMPlexInterpolate()), then depth stratum 1 contains the next 4478647867b2SJed Brown higher dimension, e.g., "edges". 4479647867b2SJed Brown 4480552f7358SJed Brown Level: developer 4481552f7358SJed Brown 4482dc287ab2SVaclav Hapla .seealso: DMPlexGetHeightStratum(), DMPlexGetDepth(), DMPlexGetDepthLabel(), DMPlexGetPointDepth(), DMPlexSymmetrize(), DMPlexInterpolate() 4483552f7358SJed Brown @*/ 44840adebc6cSBarry Smith PetscErrorCode DMPlexGetDepthStratum(DM dm, PetscInt stratumValue, PetscInt *start, PetscInt *end) 44850adebc6cSBarry Smith { 4486aa50250dSMatthew G. Knepley DMLabel label; 448763d1a920SMatthew G. Knepley PetscInt pStart, pEnd; 4488552f7358SJed Brown PetscErrorCode ierr; 4489552f7358SJed Brown 4490552f7358SJed Brown PetscFunctionBegin; 4491552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 449263d1a920SMatthew G. Knepley if (start) {PetscValidPointer(start, 3); *start = 0;} 449363d1a920SMatthew G. Knepley if (end) {PetscValidPointer(end, 4); *end = 0;} 4494552f7358SJed Brown ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 44950d644c17SKarl Rupp if (pStart == pEnd) PetscFunctionReturn(0); 449663d1a920SMatthew G. Knepley if (stratumValue < 0) { 449763d1a920SMatthew G. Knepley if (start) *start = pStart; 449863d1a920SMatthew G. Knepley if (end) *end = pEnd; 449963d1a920SMatthew G. Knepley PetscFunctionReturn(0); 4500552f7358SJed Brown } 4501aa50250dSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 450263d1a920SMatthew G. Knepley if (!label) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "No label named depth was found"); 450363d1a920SMatthew G. Knepley ierr = DMLabelGetStratumBounds(label, stratumValue, start, end);CHKERRQ(ierr); 4504552f7358SJed Brown PetscFunctionReturn(0); 4505552f7358SJed Brown } 4506552f7358SJed Brown 4507552f7358SJed Brown /*@ 4508552f7358SJed Brown DMPlexGetHeightStratum - Get the bounds [start, end) for all points at a certain height. 4509552f7358SJed Brown 4510552f7358SJed Brown Not Collective 4511552f7358SJed Brown 4512552f7358SJed Brown Input Parameters: 4513552f7358SJed Brown + dm - The DMPlex object 4514552f7358SJed Brown - stratumValue - The requested height 4515552f7358SJed Brown 4516552f7358SJed Brown Output Parameters: 4517552f7358SJed Brown + start - The first point at this height 4518552f7358SJed Brown - end - One beyond the last point at this height 4519552f7358SJed Brown 4520647867b2SJed Brown Notes: 4521647867b2SJed Brown Height indexing is related to topological codimension. Height stratum 0 contains the highest topological dimension 4522647867b2SJed Brown points, often called "cells" or "elements". If the mesh is "interpolated" (see DMPlexInterpolate()), then height 4523647867b2SJed Brown stratum 1 contains the boundary of these "cells", often called "faces" or "facets". 4524647867b2SJed Brown 4525552f7358SJed Brown Level: developer 4526552f7358SJed Brown 45273dc9a465SVaclav Hapla .seealso: DMPlexGetDepthStratum(), DMPlexGetDepth(), DMPlexGetPointHeight() 4528552f7358SJed Brown @*/ 45290adebc6cSBarry Smith PetscErrorCode DMPlexGetHeightStratum(DM dm, PetscInt stratumValue, PetscInt *start, PetscInt *end) 45300adebc6cSBarry Smith { 4531aa50250dSMatthew G. Knepley DMLabel label; 453263d1a920SMatthew G. Knepley PetscInt depth, pStart, pEnd; 4533552f7358SJed Brown PetscErrorCode ierr; 4534552f7358SJed Brown 4535552f7358SJed Brown PetscFunctionBegin; 4536552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 453763d1a920SMatthew G. Knepley if (start) {PetscValidPointer(start, 3); *start = 0;} 453863d1a920SMatthew G. Knepley if (end) {PetscValidPointer(end, 4); *end = 0;} 4539552f7358SJed Brown ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 45400d644c17SKarl Rupp if (pStart == pEnd) PetscFunctionReturn(0); 454163d1a920SMatthew G. Knepley if (stratumValue < 0) { 454263d1a920SMatthew G. Knepley if (start) *start = pStart; 454363d1a920SMatthew G. Knepley if (end) *end = pEnd; 454463d1a920SMatthew G. Knepley PetscFunctionReturn(0); 4545552f7358SJed Brown } 4546aa50250dSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 454713903a91SSatish Balay if (!label) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "No label named depth was found"); 454863d1a920SMatthew G. Knepley ierr = DMLabelGetNumValues(label, &depth);CHKERRQ(ierr); 454963d1a920SMatthew G. Knepley ierr = DMLabelGetStratumBounds(label, depth-1-stratumValue, start, end);CHKERRQ(ierr); 4550552f7358SJed Brown PetscFunctionReturn(0); 4551552f7358SJed Brown } 4552552f7358SJed Brown 4553ba2698f1SMatthew G. Knepley /*@ 4554ba2698f1SMatthew G. Knepley DMPlexGetPointDepth - Get the depth of a given point 4555ba2698f1SMatthew G. Knepley 4556ba2698f1SMatthew G. Knepley Not Collective 4557ba2698f1SMatthew G. Knepley 4558ba2698f1SMatthew G. Knepley Input Parameter: 4559ba2698f1SMatthew G. Knepley + dm - The DMPlex object 4560ba2698f1SMatthew G. Knepley - point - The point 4561ba2698f1SMatthew G. Knepley 4562ba2698f1SMatthew G. Knepley Output Parameter: 4563ba2698f1SMatthew G. Knepley . depth - The depth of the point 4564ba2698f1SMatthew G. Knepley 4565ba2698f1SMatthew G. Knepley Level: intermediate 4566ba2698f1SMatthew G. Knepley 45673dc9a465SVaclav Hapla .seealso: DMPlexGetCellType(), DMPlexGetDepthLabel(), DMPlexGetDepth(), DMPlexGetPointHeight() 4568ba2698f1SMatthew G. Knepley @*/ 4569ba2698f1SMatthew G. Knepley PetscErrorCode DMPlexGetPointDepth(DM dm, PetscInt point, PetscInt *depth) 4570ba2698f1SMatthew G. Knepley { 4571ba2698f1SMatthew G. Knepley PetscErrorCode ierr; 4572ba2698f1SMatthew G. Knepley 4573ba2698f1SMatthew G. Knepley PetscFunctionBegin; 4574ba2698f1SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 457540a2aa30SMatthew G. Knepley PetscValidIntPointer(depth, 3); 4576ba2698f1SMatthew G. Knepley ierr = DMLabelGetValue(dm->depthLabel, point, depth);CHKERRQ(ierr); 4577ba2698f1SMatthew G. Knepley PetscFunctionReturn(0); 4578ba2698f1SMatthew G. Knepley } 4579ba2698f1SMatthew G. Knepley 4580ba2698f1SMatthew G. Knepley /*@ 45810c0a32dcSVaclav Hapla DMPlexGetPointHeight - Get the height of a given point 45820c0a32dcSVaclav Hapla 45830c0a32dcSVaclav Hapla Not Collective 45840c0a32dcSVaclav Hapla 45850c0a32dcSVaclav Hapla Input Parameter: 45860c0a32dcSVaclav Hapla + dm - The DMPlex object 45870c0a32dcSVaclav Hapla - point - The point 45880c0a32dcSVaclav Hapla 45890c0a32dcSVaclav Hapla Output Parameter: 45900c0a32dcSVaclav Hapla . height - The height of the point 45910c0a32dcSVaclav Hapla 45920c0a32dcSVaclav Hapla Level: intermediate 45930c0a32dcSVaclav Hapla 45943dc9a465SVaclav Hapla .seealso: DMPlexGetCellType(), DMPlexGetDepthLabel(), DMPlexGetDepth(), DMPlexGetPointDepth() 45950c0a32dcSVaclav Hapla @*/ 45960c0a32dcSVaclav Hapla PetscErrorCode DMPlexGetPointHeight(DM dm, PetscInt point, PetscInt *height) 45970c0a32dcSVaclav Hapla { 45980c0a32dcSVaclav Hapla PetscInt n, pDepth; 45990c0a32dcSVaclav Hapla PetscErrorCode ierr; 46000c0a32dcSVaclav Hapla 46010c0a32dcSVaclav Hapla PetscFunctionBegin; 46020c0a32dcSVaclav Hapla PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 46030c0a32dcSVaclav Hapla PetscValidIntPointer(height, 3); 46040c0a32dcSVaclav Hapla ierr = DMLabelGetNumValues(dm->depthLabel, &n);CHKERRQ(ierr); 46050c0a32dcSVaclav Hapla ierr = DMLabelGetValue(dm->depthLabel, point, &pDepth);CHKERRQ(ierr); 46060c0a32dcSVaclav Hapla *height = n - 1 - pDepth; /* DAG depth is n-1 */ 46070c0a32dcSVaclav Hapla PetscFunctionReturn(0); 46080c0a32dcSVaclav Hapla } 46090c0a32dcSVaclav Hapla 46100c0a32dcSVaclav Hapla /*@ 4611ba2698f1SMatthew G. Knepley DMPlexGetCellTypeLabel - Get the DMLabel recording the polytope type of each cell 4612ba2698f1SMatthew G. Knepley 4613ba2698f1SMatthew G. Knepley Not Collective 4614ba2698f1SMatthew G. Knepley 4615ba2698f1SMatthew G. Knepley Input Parameter: 4616ba2698f1SMatthew G. Knepley . dm - The DMPlex object 4617ba2698f1SMatthew G. Knepley 4618ba2698f1SMatthew G. Knepley Output Parameter: 4619ba2698f1SMatthew G. Knepley . celltypeLabel - The DMLabel recording cell polytope type 4620ba2698f1SMatthew G. Knepley 4621412e9a14SMatthew G. Knepley Note: This function will trigger automatica computation of cell types. This can be disabled by calling 4622412e9a14SMatthew G. Knepley DMCreateLabel(dm, "celltype") beforehand. 4623412e9a14SMatthew G. Knepley 4624ba2698f1SMatthew G. Knepley Level: developer 4625ba2698f1SMatthew G. Knepley 4626dc287ab2SVaclav Hapla .seealso: DMPlexGetCellType(), DMPlexGetDepthLabel(), DMCreateLabel() 4627ba2698f1SMatthew G. Knepley @*/ 4628ba2698f1SMatthew G. Knepley PetscErrorCode DMPlexGetCellTypeLabel(DM dm, DMLabel *celltypeLabel) 4629ba2698f1SMatthew G. Knepley { 4630ba2698f1SMatthew G. Knepley PetscErrorCode ierr; 4631ba2698f1SMatthew G. Knepley 4632ba2698f1SMatthew G. Knepley PetscFunctionBegin; 4633ba2698f1SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4634ba2698f1SMatthew G. Knepley PetscValidPointer(celltypeLabel, 2); 4635ba2698f1SMatthew G. Knepley if (!dm->celltypeLabel) {ierr = DMPlexComputeCellTypes(dm);CHKERRQ(ierr);} 4636ba2698f1SMatthew G. Knepley *celltypeLabel = dm->celltypeLabel; 4637ba2698f1SMatthew G. Knepley PetscFunctionReturn(0); 4638ba2698f1SMatthew G. Knepley } 4639ba2698f1SMatthew G. Knepley 4640ba2698f1SMatthew G. Knepley /*@ 4641ba2698f1SMatthew G. Knepley DMPlexGetCellType - Get the polytope type of a given cell 4642ba2698f1SMatthew G. Knepley 4643ba2698f1SMatthew G. Knepley Not Collective 4644ba2698f1SMatthew G. Knepley 4645ba2698f1SMatthew G. Knepley Input Parameter: 4646ba2698f1SMatthew G. Knepley + dm - The DMPlex object 4647ba2698f1SMatthew G. Knepley - cell - The cell 4648ba2698f1SMatthew G. Knepley 4649ba2698f1SMatthew G. Knepley Output Parameter: 4650ba2698f1SMatthew G. Knepley . celltype - The polytope type of the cell 4651ba2698f1SMatthew G. Knepley 4652ba2698f1SMatthew G. Knepley Level: intermediate 4653ba2698f1SMatthew G. Knepley 4654ba2698f1SMatthew G. Knepley .seealso: DMPlexGetCellTypeLabel(), DMPlexGetDepthLabel(), DMPlexGetDepth() 4655ba2698f1SMatthew G. Knepley @*/ 4656ba2698f1SMatthew G. Knepley PetscErrorCode DMPlexGetCellType(DM dm, PetscInt cell, DMPolytopeType *celltype) 4657ba2698f1SMatthew G. Knepley { 4658ba2698f1SMatthew G. Knepley DMLabel label; 4659ba2698f1SMatthew G. Knepley PetscInt ct; 4660ba2698f1SMatthew G. Knepley PetscErrorCode ierr; 4661ba2698f1SMatthew G. Knepley 4662ba2698f1SMatthew G. Knepley PetscFunctionBegin; 4663ba2698f1SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4664ba2698f1SMatthew G. Knepley PetscValidPointer(celltype, 3); 4665ba2698f1SMatthew G. Knepley ierr = DMPlexGetCellTypeLabel(dm, &label);CHKERRQ(ierr); 4666ba2698f1SMatthew G. Knepley ierr = DMLabelGetValue(label, cell, &ct);CHKERRQ(ierr); 46674a7ee7d0SMatthew G. Knepley if (ct < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Cell %D has not been assigned a cell type", cell); 4668ba2698f1SMatthew G. Knepley *celltype = (DMPolytopeType) ct; 4669ba2698f1SMatthew G. Knepley PetscFunctionReturn(0); 4670ba2698f1SMatthew G. Knepley } 4671ba2698f1SMatthew G. Knepley 4672412e9a14SMatthew G. Knepley /*@ 4673412e9a14SMatthew G. Knepley DMPlexSetCellType - Set the polytope type of a given cell 4674412e9a14SMatthew G. Knepley 4675412e9a14SMatthew G. Knepley Not Collective 4676412e9a14SMatthew G. Knepley 4677412e9a14SMatthew G. Knepley Input Parameters: 4678412e9a14SMatthew G. Knepley + dm - The DMPlex object 4679412e9a14SMatthew G. Knepley . cell - The cell 4680412e9a14SMatthew G. Knepley - celltype - The polytope type of the cell 4681412e9a14SMatthew G. Knepley 4682412e9a14SMatthew G. Knepley Note: By default, cell types will be automatically computed using DMPlexComputeCellTypes() before this function 4683412e9a14SMatthew G. Knepley is executed. This function will override the computed type. However, if automatic classification will not succeed 4684412e9a14SMatthew G. Knepley and a user wants to manually specify all types, the classification must be disabled by calling 4685412e9a14SMatthew G. Knepley DMCreaateLabel(dm, "celltype") before getting or setting any cell types. 4686412e9a14SMatthew G. Knepley 4687412e9a14SMatthew G. Knepley Level: advanced 4688412e9a14SMatthew G. Knepley 4689412e9a14SMatthew G. Knepley .seealso: DMPlexGetCellTypeLabel(), DMPlexGetDepthLabel(), DMPlexGetDepth(), DMPlexComputeCellTypes(), DMCreateLabel() 4690412e9a14SMatthew G. Knepley @*/ 4691412e9a14SMatthew G. Knepley PetscErrorCode DMPlexSetCellType(DM dm, PetscInt cell, DMPolytopeType celltype) 4692412e9a14SMatthew G. Knepley { 4693412e9a14SMatthew G. Knepley DMLabel label; 4694412e9a14SMatthew G. Knepley PetscErrorCode ierr; 4695412e9a14SMatthew G. Knepley 4696412e9a14SMatthew G. Knepley PetscFunctionBegin; 4697412e9a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4698412e9a14SMatthew G. Knepley ierr = DMPlexGetCellTypeLabel(dm, &label);CHKERRQ(ierr); 4699412e9a14SMatthew G. Knepley ierr = DMLabelSetValue(label, cell, celltype);CHKERRQ(ierr); 4700412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 4701412e9a14SMatthew G. Knepley } 4702412e9a14SMatthew G. Knepley 47030adebc6cSBarry Smith PetscErrorCode DMCreateCoordinateDM_Plex(DM dm, DM *cdm) 47040adebc6cSBarry Smith { 4705efe440bfSMatthew G. Knepley PetscSection section, s; 4706efe440bfSMatthew G. Knepley Mat m; 47073e922f36SToby Isaac PetscInt maxHeight; 4708552f7358SJed Brown PetscErrorCode ierr; 4709552f7358SJed Brown 4710552f7358SJed Brown PetscFunctionBegin; 471138221697SMatthew G. Knepley ierr = DMClone(dm, cdm);CHKERRQ(ierr); 47123e922f36SToby Isaac ierr = DMPlexGetMaxProjectionHeight(dm, &maxHeight);CHKERRQ(ierr); 47133e922f36SToby Isaac ierr = DMPlexSetMaxProjectionHeight(*cdm, maxHeight);CHKERRQ(ierr); 471482f516ccSBarry Smith ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), §ion);CHKERRQ(ierr); 471592fd8e1eSJed Brown ierr = DMSetLocalSection(*cdm, section);CHKERRQ(ierr); 47161d799100SJed Brown ierr = PetscSectionDestroy(§ion);CHKERRQ(ierr); 4717efe440bfSMatthew G. Knepley ierr = PetscSectionCreate(PETSC_COMM_SELF, &s);CHKERRQ(ierr); 4718efe440bfSMatthew G. Knepley ierr = MatCreate(PETSC_COMM_SELF, &m);CHKERRQ(ierr); 4719efe440bfSMatthew G. Knepley ierr = DMSetDefaultConstraints(*cdm, s, m);CHKERRQ(ierr); 4720efe440bfSMatthew G. Knepley ierr = PetscSectionDestroy(&s);CHKERRQ(ierr); 4721efe440bfSMatthew G. Knepley ierr = MatDestroy(&m);CHKERRQ(ierr); 47228f4c458bSMatthew G. Knepley 47238f4c458bSMatthew G. Knepley ierr = DMSetNumFields(*cdm, 1);CHKERRQ(ierr); 47248f4c458bSMatthew G. Knepley ierr = DMCreateDS(*cdm);CHKERRQ(ierr); 4725552f7358SJed Brown PetscFunctionReturn(0); 4726552f7358SJed Brown } 4727552f7358SJed Brown 4728f19dbd58SToby Isaac PetscErrorCode DMCreateCoordinateField_Plex(DM dm, DMField *field) 4729f19dbd58SToby Isaac { 4730f19dbd58SToby Isaac Vec coordsLocal; 4731f19dbd58SToby Isaac DM coordsDM; 4732f19dbd58SToby Isaac PetscErrorCode ierr; 4733f19dbd58SToby Isaac 4734f19dbd58SToby Isaac PetscFunctionBegin; 4735f19dbd58SToby Isaac *field = NULL; 4736f19dbd58SToby Isaac ierr = DMGetCoordinatesLocal(dm,&coordsLocal);CHKERRQ(ierr); 4737f19dbd58SToby Isaac ierr = DMGetCoordinateDM(dm,&coordsDM);CHKERRQ(ierr); 4738f19dbd58SToby Isaac if (coordsLocal && coordsDM) { 4739f19dbd58SToby Isaac ierr = DMFieldCreateDS(coordsDM, 0, coordsLocal, field);CHKERRQ(ierr); 4740f19dbd58SToby Isaac } 4741f19dbd58SToby Isaac PetscFunctionReturn(0); 4742f19dbd58SToby Isaac } 4743f19dbd58SToby Isaac 47447cd05799SMatthew G. Knepley /*@C 47457cd05799SMatthew G. Knepley DMPlexGetConeSection - Return a section which describes the layout of cone data 47467cd05799SMatthew G. Knepley 47477cd05799SMatthew G. Knepley Not Collective 47487cd05799SMatthew G. Knepley 47497cd05799SMatthew G. Knepley Input Parameters: 47507cd05799SMatthew G. Knepley . dm - The DMPlex object 47517cd05799SMatthew G. Knepley 47527cd05799SMatthew G. Knepley Output Parameter: 47537cd05799SMatthew G. Knepley . section - The PetscSection object 47547cd05799SMatthew G. Knepley 47557cd05799SMatthew G. Knepley Level: developer 47567cd05799SMatthew G. Knepley 47577cd05799SMatthew G. Knepley .seealso: DMPlexGetSupportSection(), DMPlexGetCones(), DMPlexGetConeOrientations() 47587cd05799SMatthew G. Knepley @*/ 47590adebc6cSBarry Smith PetscErrorCode DMPlexGetConeSection(DM dm, PetscSection *section) 47600adebc6cSBarry Smith { 4761552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 4762552f7358SJed Brown 4763552f7358SJed Brown PetscFunctionBegin; 4764552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4765552f7358SJed Brown if (section) *section = mesh->coneSection; 4766552f7358SJed Brown PetscFunctionReturn(0); 4767552f7358SJed Brown } 4768552f7358SJed Brown 47697cd05799SMatthew G. Knepley /*@C 47707cd05799SMatthew G. Knepley DMPlexGetSupportSection - Return a section which describes the layout of support data 47717cd05799SMatthew G. Knepley 47727cd05799SMatthew G. Knepley Not Collective 47737cd05799SMatthew G. Knepley 47747cd05799SMatthew G. Knepley Input Parameters: 47757cd05799SMatthew G. Knepley . dm - The DMPlex object 47767cd05799SMatthew G. Knepley 47777cd05799SMatthew G. Knepley Output Parameter: 47787cd05799SMatthew G. Knepley . section - The PetscSection object 47797cd05799SMatthew G. Knepley 47807cd05799SMatthew G. Knepley Level: developer 47817cd05799SMatthew G. Knepley 47827cd05799SMatthew G. Knepley .seealso: DMPlexGetConeSection() 47837cd05799SMatthew G. Knepley @*/ 47848cb4d582SMatthew G. Knepley PetscErrorCode DMPlexGetSupportSection(DM dm, PetscSection *section) 47858cb4d582SMatthew G. Knepley { 47868cb4d582SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 47878cb4d582SMatthew G. Knepley 47888cb4d582SMatthew G. Knepley PetscFunctionBegin; 47898cb4d582SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 47908cb4d582SMatthew G. Knepley if (section) *section = mesh->supportSection; 47918cb4d582SMatthew G. Knepley PetscFunctionReturn(0); 47928cb4d582SMatthew G. Knepley } 47938cb4d582SMatthew G. Knepley 47947cd05799SMatthew G. Knepley /*@C 47957cd05799SMatthew G. Knepley DMPlexGetCones - Return cone data 47967cd05799SMatthew G. Knepley 47977cd05799SMatthew G. Knepley Not Collective 47987cd05799SMatthew G. Knepley 47997cd05799SMatthew G. Knepley Input Parameters: 48007cd05799SMatthew G. Knepley . dm - The DMPlex object 48017cd05799SMatthew G. Knepley 48027cd05799SMatthew G. Knepley Output Parameter: 48037cd05799SMatthew G. Knepley . cones - The cone for each point 48047cd05799SMatthew G. Knepley 48057cd05799SMatthew G. Knepley Level: developer 48067cd05799SMatthew G. Knepley 48077cd05799SMatthew G. Knepley .seealso: DMPlexGetConeSection() 48087cd05799SMatthew G. Knepley @*/ 4809a6dfd86eSKarl Rupp PetscErrorCode DMPlexGetCones(DM dm, PetscInt *cones[]) 4810a6dfd86eSKarl Rupp { 4811552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 4812552f7358SJed Brown 4813552f7358SJed Brown PetscFunctionBegin; 4814552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4815552f7358SJed Brown if (cones) *cones = mesh->cones; 4816552f7358SJed Brown PetscFunctionReturn(0); 4817552f7358SJed Brown } 4818552f7358SJed Brown 48197cd05799SMatthew G. Knepley /*@C 48207cd05799SMatthew G. Knepley DMPlexGetConeOrientations - Return cone orientation data 48217cd05799SMatthew G. Knepley 48227cd05799SMatthew G. Knepley Not Collective 48237cd05799SMatthew G. Knepley 48247cd05799SMatthew G. Knepley Input Parameters: 48257cd05799SMatthew G. Knepley . dm - The DMPlex object 48267cd05799SMatthew G. Knepley 48277cd05799SMatthew G. Knepley Output Parameter: 48287cd05799SMatthew G. Knepley . coneOrientations - The cone orientation for each point 48297cd05799SMatthew G. Knepley 48307cd05799SMatthew G. Knepley Level: developer 48317cd05799SMatthew G. Knepley 48327cd05799SMatthew G. Knepley .seealso: DMPlexGetConeSection() 48337cd05799SMatthew G. Knepley @*/ 4834a6dfd86eSKarl Rupp PetscErrorCode DMPlexGetConeOrientations(DM dm, PetscInt *coneOrientations[]) 4835a6dfd86eSKarl Rupp { 4836552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 4837552f7358SJed Brown 4838552f7358SJed Brown PetscFunctionBegin; 4839552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 4840552f7358SJed Brown if (coneOrientations) *coneOrientations = mesh->coneOrientations; 4841552f7358SJed Brown PetscFunctionReturn(0); 4842552f7358SJed Brown } 4843552f7358SJed Brown 4844552f7358SJed Brown /******************************** FEM Support **********************************/ 4845552f7358SJed Brown 48469e8305c2SJed Brown /* 48479e8305c2SJed Brown Returns number of components and tensor degree for the field. For interpolated meshes, line should be a point 48489e8305c2SJed Brown representing a line in the section. 48499e8305c2SJed Brown */ 48509e8305c2SJed Brown static PetscErrorCode PetscSectionFieldGetTensorDegree_Private(PetscSection section,PetscInt field,PetscInt line,PetscBool vertexchart,PetscInt *Nc,PetscInt *k) 48519e8305c2SJed Brown { 48529e8305c2SJed Brown PetscErrorCode ierr; 48539e8305c2SJed Brown 48549e8305c2SJed Brown PetscFunctionBeginHot; 48559e8305c2SJed Brown ierr = PetscSectionGetFieldComponents(section, field, Nc);CHKERRQ(ierr); 4856a433471fSStefano Zampini if (line < 0) { 4857a433471fSStefano Zampini *k = 0; 4858a433471fSStefano Zampini *Nc = 0; 4859a433471fSStefano Zampini } else if (vertexchart) { /* If we only have a vertex chart, we must have degree k=1 */ 48609e8305c2SJed Brown *k = 1; 48619e8305c2SJed Brown } else { /* Assume the full interpolated mesh is in the chart; lines in particular */ 48629e8305c2SJed Brown /* An order k SEM disc has k-1 dofs on an edge */ 48639e8305c2SJed Brown ierr = PetscSectionGetFieldDof(section, line, field, k);CHKERRQ(ierr); 48649e8305c2SJed Brown *k = *k / *Nc + 1; 48659e8305c2SJed Brown } 48669e8305c2SJed Brown PetscFunctionReturn(0); 48679e8305c2SJed Brown } 48689e8305c2SJed Brown 4869a4355906SMatthew Knepley /*@ 4870bc1eb3faSJed Brown 4871bc1eb3faSJed Brown DMPlexSetClosurePermutationTensor - Create a permutation from the default (BFS) point ordering in the closure, to a 4872bc1eb3faSJed Brown lexicographic ordering over the tensor product cell (i.e., line, quad, hex, etc.), and set this permutation in the 48731bb6d2a8SBarry Smith section provided (or the section of the DM). 4874a4355906SMatthew Knepley 4875a4355906SMatthew Knepley Input Parameters: 4876a4355906SMatthew Knepley + dm - The DM 4877a4355906SMatthew Knepley . point - Either a cell (highest dim point) or an edge (dim 1 point), or PETSC_DETERMINE 4878a4355906SMatthew Knepley - section - The PetscSection to reorder, or NULL for the default section 4879a4355906SMatthew Knepley 4880a4355906SMatthew Knepley Note: The point is used to determine the number of dofs/field on an edge. For SEM, this is related to the polynomial 4881a4355906SMatthew Knepley degree of the basis. 4882a4355906SMatthew Knepley 4883bc1eb3faSJed Brown Example: 4884bc1eb3faSJed Brown A typical interpolated single-quad mesh might order points as 4885bc1eb3faSJed Brown .vb 4886bc1eb3faSJed Brown [c0, v1, v2, v3, v4, e5, e6, e7, e8] 4887bc1eb3faSJed Brown 4888bc1eb3faSJed Brown v4 -- e6 -- v3 4889bc1eb3faSJed Brown | | 4890bc1eb3faSJed Brown e7 c0 e8 4891bc1eb3faSJed Brown | | 4892bc1eb3faSJed Brown v1 -- e5 -- v2 4893bc1eb3faSJed Brown .ve 4894bc1eb3faSJed Brown 4895bc1eb3faSJed Brown (There is no significance to the ordering described here.) The default section for a Q3 quad might typically assign 4896bc1eb3faSJed Brown dofs in the order of points, e.g., 4897bc1eb3faSJed Brown .vb 4898bc1eb3faSJed Brown c0 -> [0,1,2,3] 4899bc1eb3faSJed Brown v1 -> [4] 4900bc1eb3faSJed Brown ... 4901bc1eb3faSJed Brown e5 -> [8, 9] 4902bc1eb3faSJed Brown .ve 4903bc1eb3faSJed Brown 4904bc1eb3faSJed Brown which corresponds to the dofs 4905bc1eb3faSJed Brown .vb 4906bc1eb3faSJed Brown 6 10 11 7 4907bc1eb3faSJed Brown 13 2 3 15 4908bc1eb3faSJed Brown 12 0 1 14 4909bc1eb3faSJed Brown 4 8 9 5 4910bc1eb3faSJed Brown .ve 4911bc1eb3faSJed Brown 4912bc1eb3faSJed Brown The closure in BFS ordering works through height strata (cells, edges, vertices) to produce the ordering 4913bc1eb3faSJed Brown .vb 4914bc1eb3faSJed Brown 0 1 2 3 8 9 14 15 11 10 13 12 4 5 7 6 4915bc1eb3faSJed Brown .ve 4916bc1eb3faSJed Brown 4917bc1eb3faSJed Brown After calling DMPlexSetClosurePermutationTensor(), the closure will be ordered lexicographically, 4918bc1eb3faSJed Brown .vb 4919bc1eb3faSJed Brown 4 8 9 5 12 0 1 14 13 2 3 15 6 10 11 7 4920bc1eb3faSJed Brown .ve 4921bc1eb3faSJed Brown 4922a4355906SMatthew Knepley Level: developer 4923a4355906SMatthew Knepley 49249df75925SJed Brown .seealso: DMGetLocalSection(), PetscSectionSetClosurePermutation(), DMSetGlobalSection() 4925a4355906SMatthew Knepley @*/ 4926bc1eb3faSJed Brown PetscErrorCode DMPlexSetClosurePermutationTensor(DM dm, PetscInt point, PetscSection section) 49273194fc30SMatthew G. Knepley { 49287391a63aSMatthew G. Knepley DMLabel label; 4929bb197d40SJed Brown PetscInt dim, depth = -1, eStart = -1, Nf; 49309e8305c2SJed Brown PetscBool vertexchart; 49313194fc30SMatthew G. Knepley PetscErrorCode ierr; 49323194fc30SMatthew G. Knepley 49333194fc30SMatthew G. Knepley PetscFunctionBegin; 49343194fc30SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 4935a433471fSStefano Zampini if (dim < 1) PetscFunctionReturn(0); 4936a433471fSStefano Zampini if (point < 0) { 4937a433471fSStefano Zampini PetscInt sStart,sEnd; 4938a433471fSStefano Zampini 4939a433471fSStefano Zampini ierr = DMPlexGetDepthStratum(dm, 1, &sStart, &sEnd);CHKERRQ(ierr); 4940a433471fSStefano Zampini point = sEnd-sStart ? sStart : point; 4941a433471fSStefano Zampini } 49427391a63aSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &label);CHKERRQ(ierr); 4943a433471fSStefano Zampini if (point >= 0) { ierr = DMLabelGetValue(label, point, &depth);CHKERRQ(ierr); } 4944a433471fSStefano Zampini if (!section) {ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr);} 49457391a63aSMatthew G. Knepley if (depth == 1) {eStart = point;} 49467391a63aSMatthew G. Knepley else if (depth == dim) { 49477391a63aSMatthew G. Knepley const PetscInt *cone; 49487391a63aSMatthew G. Knepley 49497391a63aSMatthew G. Knepley ierr = DMPlexGetCone(dm, point, &cone);CHKERRQ(ierr); 4950d4e6627bSStefano Zampini if (dim == 2) eStart = cone[0]; 4951d4e6627bSStefano Zampini else if (dim == 3) { 4952d4e6627bSStefano Zampini const PetscInt *cone2; 4953d4e6627bSStefano Zampini ierr = DMPlexGetCone(dm, cone[0], &cone2);CHKERRQ(ierr); 4954d4e6627bSStefano Zampini eStart = cone2[0]; 4955d4e6627bSStefano 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); 4956a433471fSStefano 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); 49579e8305c2SJed Brown { /* Determine whether the chart covers all points or just vertices. */ 49589e8305c2SJed Brown PetscInt pStart,pEnd,cStart,cEnd; 49599e8305c2SJed Brown ierr = DMPlexGetDepthStratum(dm,0,&pStart,&pEnd);CHKERRQ(ierr); 49609e8305c2SJed Brown ierr = PetscSectionGetChart(section,&cStart,&cEnd);CHKERRQ(ierr); 49619e8305c2SJed Brown if (pStart == cStart && pEnd == cEnd) vertexchart = PETSC_TRUE; /* Just vertices */ 49629e8305c2SJed Brown else vertexchart = PETSC_FALSE; /* Assume all interpolated points are in chart */ 49639e8305c2SJed Brown } 49643194fc30SMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &Nf);CHKERRQ(ierr); 4965bb197d40SJed Brown for (PetscInt d=1; d<=dim; d++) { 4966bb197d40SJed Brown PetscInt k, f, Nc, c, i, j, size = 0, offset = 0, foffset = 0; 4967bb197d40SJed Brown PetscInt *perm; 4968bb197d40SJed Brown 49693194fc30SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 49709e8305c2SJed Brown ierr = PetscSectionFieldGetTensorDegree_Private(section,f,eStart,vertexchart,&Nc,&k);CHKERRQ(ierr); 4971bb197d40SJed Brown size += PetscPowInt(k+1, d)*Nc; 49723194fc30SMatthew G. Knepley } 49733194fc30SMatthew G. Knepley ierr = PetscMalloc1(size, &perm);CHKERRQ(ierr); 49743194fc30SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 4975bb197d40SJed Brown switch (d) { 4976babf31e0SJed Brown case 1: 49779e8305c2SJed Brown ierr = PetscSectionFieldGetTensorDegree_Private(section,f,eStart,vertexchart,&Nc,&k);CHKERRQ(ierr); 4978babf31e0SJed Brown /* 4979babf31e0SJed Brown Original ordering is [ edge of length k-1; vtx0; vtx1 ] 4980babf31e0SJed Brown We want [ vtx0; edge of length k-1; vtx1 ] 4981babf31e0SJed Brown */ 4982babf31e0SJed Brown for (c=0; c<Nc; c++,offset++) perm[offset] = (k-1)*Nc + c + foffset; 4983babf31e0SJed Brown for (i=0; i<k-1; i++) for (c=0; c<Nc; c++,offset++) perm[offset] = i*Nc + c + foffset; 4984babf31e0SJed Brown for (c=0; c<Nc; c++,offset++) perm[offset] = k*Nc + c + foffset; 4985babf31e0SJed Brown foffset = offset; 4986babf31e0SJed Brown break; 498789eabcffSMatthew G. Knepley case 2: 49883194fc30SMatthew 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} */ 49899e8305c2SJed Brown ierr = PetscSectionFieldGetTensorDegree_Private(section,f,eStart,vertexchart,&Nc,&k);CHKERRQ(ierr); 49903194fc30SMatthew G. Knepley /* The SEM order is 49913194fc30SMatthew G. Knepley 49923194fc30SMatthew G. Knepley v_lb, {e_b}, v_rb, 499389eabcffSMatthew G. Knepley e^{(k-1)-i}_l, {f^{i*(k-1)}}, e^i_r, 49943194fc30SMatthew G. Knepley v_lt, reverse {e_t}, v_rt 49953194fc30SMatthew G. Knepley */ 49963194fc30SMatthew G. Knepley { 49973194fc30SMatthew G. Knepley const PetscInt of = 0; 49983194fc30SMatthew G. Knepley const PetscInt oeb = of + PetscSqr(k-1); 49993194fc30SMatthew G. Knepley const PetscInt oer = oeb + (k-1); 50003194fc30SMatthew G. Knepley const PetscInt oet = oer + (k-1); 50013194fc30SMatthew G. Knepley const PetscInt oel = oet + (k-1); 50023194fc30SMatthew G. Knepley const PetscInt ovlb = oel + (k-1); 50033194fc30SMatthew G. Knepley const PetscInt ovrb = ovlb + 1; 50043194fc30SMatthew G. Knepley const PetscInt ovrt = ovrb + 1; 50053194fc30SMatthew G. Knepley const PetscInt ovlt = ovrt + 1; 50063194fc30SMatthew G. Knepley PetscInt o; 50073194fc30SMatthew G. Knepley 50083194fc30SMatthew G. Knepley /* bottom */ 50093194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovlb*Nc + c + foffset; 50103194fc30SMatthew G. Knepley for (o = oeb; o < oer; ++o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 50113194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovrb*Nc + c + foffset; 50123194fc30SMatthew G. Knepley /* middle */ 50133194fc30SMatthew G. Knepley for (i = 0; i < k-1; ++i) { 50143194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oel+(k-2)-i)*Nc + c + foffset; 50153194fc30SMatthew 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; 50163194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oer+i)*Nc + c + foffset; 50173194fc30SMatthew G. Knepley } 50183194fc30SMatthew G. Knepley /* top */ 50193194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovlt*Nc + c + foffset; 50203194fc30SMatthew G. Knepley for (o = oel-1; o >= oet; --o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 50213194fc30SMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovrt*Nc + c + foffset; 50223194fc30SMatthew G. Knepley foffset = offset; 50233194fc30SMatthew G. Knepley } 502489eabcffSMatthew G. Knepley break; 502589eabcffSMatthew G. Knepley case 3: 502689eabcffSMatthew G. Knepley /* The original hex closure is 502789eabcffSMatthew G. Knepley 502889eabcffSMatthew G. Knepley {c, 502989eabcffSMatthew G. Knepley f_b, f_t, f_f, f_b, f_r, f_l, 503089eabcffSMatthew 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, 503189eabcffSMatthew G. Knepley v_blf, v_blb, v_brb, v_brf, v_tlf, v_trf, v_trb, v_tlb} 503289eabcffSMatthew G. Knepley */ 50339e8305c2SJed Brown ierr = PetscSectionFieldGetTensorDegree_Private(section,f,eStart,vertexchart,&Nc,&k);CHKERRQ(ierr); 503489eabcffSMatthew G. Knepley /* The SEM order is 503589eabcffSMatthew G. Knepley Bottom Slice 503689eabcffSMatthew G. Knepley v_blf, {e^{(k-1)-n}_bf}, v_brf, 503789eabcffSMatthew G. Knepley e^{i}_bl, f^{n*(k-1)+(k-1)-i}_b, e^{(k-1)-i}_br, 503889eabcffSMatthew G. Knepley v_blb, {e_bb}, v_brb, 503989eabcffSMatthew G. Knepley 504089eabcffSMatthew G. Knepley Middle Slice (j) 504189eabcffSMatthew G. Knepley {e^{(k-1)-j}_lf}, {f^{j*(k-1)+n}_f}, e^j_rf, 504289eabcffSMatthew G. Knepley f^{i*(k-1)+j}_l, {c^{(j*(k-1) + i)*(k-1)+n}_t}, f^{j*(k-1)+i}_r, 504389eabcffSMatthew G. Knepley e^j_lb, {f^{j*(k-1)+(k-1)-n}_b}, e^{(k-1)-j}_rb, 504489eabcffSMatthew G. Knepley 504589eabcffSMatthew G. Knepley Top Slice 504689eabcffSMatthew G. Knepley v_tlf, {e_tf}, v_trf, 504789eabcffSMatthew G. Knepley e^{(k-1)-i}_tl, {f^{i*(k-1)}_t}, e^{i}_tr, 504889eabcffSMatthew G. Knepley v_tlb, {e^{(k-1)-n}_tb}, v_trb, 504989eabcffSMatthew G. Knepley */ 505089eabcffSMatthew G. Knepley { 505189eabcffSMatthew G. Knepley const PetscInt oc = 0; 505289eabcffSMatthew G. Knepley const PetscInt ofb = oc + PetscSqr(k-1)*(k-1); 505389eabcffSMatthew G. Knepley const PetscInt oft = ofb + PetscSqr(k-1); 505489eabcffSMatthew G. Knepley const PetscInt off = oft + PetscSqr(k-1); 505589eabcffSMatthew G. Knepley const PetscInt ofk = off + PetscSqr(k-1); 505689eabcffSMatthew G. Knepley const PetscInt ofr = ofk + PetscSqr(k-1); 505789eabcffSMatthew G. Knepley const PetscInt ofl = ofr + PetscSqr(k-1); 505889eabcffSMatthew G. Knepley const PetscInt oebl = ofl + PetscSqr(k-1); 505989eabcffSMatthew G. Knepley const PetscInt oebb = oebl + (k-1); 506089eabcffSMatthew G. Knepley const PetscInt oebr = oebb + (k-1); 506189eabcffSMatthew G. Knepley const PetscInt oebf = oebr + (k-1); 506289eabcffSMatthew G. Knepley const PetscInt oetf = oebf + (k-1); 506389eabcffSMatthew G. Knepley const PetscInt oetr = oetf + (k-1); 506489eabcffSMatthew G. Knepley const PetscInt oetb = oetr + (k-1); 506589eabcffSMatthew G. Knepley const PetscInt oetl = oetb + (k-1); 506689eabcffSMatthew G. Knepley const PetscInt oerf = oetl + (k-1); 506789eabcffSMatthew G. Knepley const PetscInt oelf = oerf + (k-1); 506889eabcffSMatthew G. Knepley const PetscInt oelb = oelf + (k-1); 506989eabcffSMatthew G. Knepley const PetscInt oerb = oelb + (k-1); 507089eabcffSMatthew G. Knepley const PetscInt ovblf = oerb + (k-1); 507189eabcffSMatthew G. Knepley const PetscInt ovblb = ovblf + 1; 507289eabcffSMatthew G. Knepley const PetscInt ovbrb = ovblb + 1; 507389eabcffSMatthew G. Knepley const PetscInt ovbrf = ovbrb + 1; 507489eabcffSMatthew G. Knepley const PetscInt ovtlf = ovbrf + 1; 507589eabcffSMatthew G. Knepley const PetscInt ovtrf = ovtlf + 1; 507689eabcffSMatthew G. Knepley const PetscInt ovtrb = ovtrf + 1; 507789eabcffSMatthew G. Knepley const PetscInt ovtlb = ovtrb + 1; 507889eabcffSMatthew G. Knepley PetscInt o, n; 507989eabcffSMatthew G. Knepley 508089eabcffSMatthew G. Knepley /* Bottom Slice */ 508189eabcffSMatthew G. Knepley /* bottom */ 508289eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovblf*Nc + c + foffset; 508389eabcffSMatthew G. Knepley for (o = oetf-1; o >= oebf; --o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 508489eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovbrf*Nc + c + foffset; 508589eabcffSMatthew G. Knepley /* middle */ 508689eabcffSMatthew G. Knepley for (i = 0; i < k-1; ++i) { 508789eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oebl+i)*Nc + c + foffset; 5088316b7f87SMax 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;} 508989eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oebr+(k-2)-i)*Nc + c + foffset; 50903194fc30SMatthew G. Knepley } 509189eabcffSMatthew G. Knepley /* top */ 509289eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovblb*Nc + c + foffset; 509389eabcffSMatthew G. Knepley for (o = oebb; o < oebr; ++o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 509489eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovbrb*Nc + c + foffset; 509589eabcffSMatthew G. Knepley 509689eabcffSMatthew G. Knepley /* Middle Slice */ 509789eabcffSMatthew G. Knepley for (j = 0; j < k-1; ++j) { 509889eabcffSMatthew G. Knepley /* bottom */ 509989eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oelf+(k-2)-j)*Nc + c + foffset; 510089eabcffSMatthew 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; 510189eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oerf+j)*Nc + c + foffset; 510289eabcffSMatthew G. Knepley /* middle */ 510389eabcffSMatthew G. Knepley for (i = 0; i < k-1; ++i) { 510489eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (ofl+i*(k-1)+j)*Nc + c + foffset; 510589eabcffSMatthew 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; 510689eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (ofr+j*(k-1)+i)*Nc + c + foffset; 510789eabcffSMatthew G. Knepley } 510889eabcffSMatthew G. Knepley /* top */ 510989eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oelb+j)*Nc + c + foffset; 511089eabcffSMatthew 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; 511189eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oerb+(k-2)-j)*Nc + c + foffset; 511289eabcffSMatthew G. Knepley } 511389eabcffSMatthew G. Knepley 511489eabcffSMatthew G. Knepley /* Top Slice */ 511589eabcffSMatthew G. Knepley /* bottom */ 511689eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovtlf*Nc + c + foffset; 511789eabcffSMatthew G. Knepley for (o = oetf; o < oetr; ++o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 511889eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovtrf*Nc + c + foffset; 511989eabcffSMatthew G. Knepley /* middle */ 512089eabcffSMatthew G. Knepley for (i = 0; i < k-1; ++i) { 512189eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oetl+(k-2)-i)*Nc + c + foffset; 512289eabcffSMatthew 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; 512389eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = (oetr+i)*Nc + c + foffset; 512489eabcffSMatthew G. Knepley } 512589eabcffSMatthew G. Knepley /* top */ 512689eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovtlb*Nc + c + foffset; 512789eabcffSMatthew G. Knepley for (o = oetl-1; o >= oetb; --o) for (c = 0; c < Nc; ++c, ++offset) perm[offset] = o*Nc + c + foffset; 512889eabcffSMatthew G. Knepley for (c = 0; c < Nc; ++c, ++offset) perm[offset] = ovtrb*Nc + c + foffset; 512989eabcffSMatthew G. Knepley 513089eabcffSMatthew G. Knepley foffset = offset; 513189eabcffSMatthew G. Knepley } 513289eabcffSMatthew G. Knepley break; 5133bb197d40SJed Brown default: SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "No spectral ordering for dimension %D", d); 513489eabcffSMatthew G. Knepley } 513589eabcffSMatthew G. Knepley } 513689eabcffSMatthew G. Knepley if (offset != size) SETERRQ2(PetscObjectComm((PetscObject) dm), PETSC_ERR_PLIB, "Number of permutation entries %D != %D", offset, size); 51373194fc30SMatthew G. Knepley /* Check permutation */ 51383194fc30SMatthew G. Knepley { 51393194fc30SMatthew G. Knepley PetscInt *check; 51403194fc30SMatthew G. Knepley 51413194fc30SMatthew G. Knepley ierr = PetscMalloc1(size, &check);CHKERRQ(ierr); 51423194fc30SMatthew 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]);} 51433194fc30SMatthew G. Knepley for (i = 0; i < size; ++i) check[perm[i]] = i; 51443194fc30SMatthew G. Knepley for (i = 0; i < size; ++i) {if (check[i] < 0) SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_PLIB, "Missing permutation index %D", i);} 51453194fc30SMatthew G. Knepley ierr = PetscFree(check);CHKERRQ(ierr); 51463194fc30SMatthew G. Knepley } 5147bb197d40SJed Brown ierr = PetscSectionSetClosurePermutation_Internal(section, (PetscObject) dm, d, size, PETSC_OWN_POINTER, perm);CHKERRQ(ierr); 5148bb197d40SJed Brown } 51493194fc30SMatthew G. Knepley PetscFunctionReturn(0); 51503194fc30SMatthew G. Knepley } 51513194fc30SMatthew G. Knepley 5152e071409bSToby Isaac PetscErrorCode DMPlexGetPointDualSpaceFEM(DM dm, PetscInt point, PetscInt field, PetscDualSpace *dspace) 5153e071409bSToby Isaac { 5154e071409bSToby Isaac PetscDS prob; 5155e071409bSToby Isaac PetscInt depth, Nf, h; 5156e071409bSToby Isaac DMLabel label; 5157e071409bSToby Isaac PetscErrorCode ierr; 5158e071409bSToby Isaac 5159e071409bSToby Isaac PetscFunctionBeginHot; 5160e5e52638SMatthew G. Knepley ierr = DMGetDS(dm, &prob);CHKERRQ(ierr); 5161e071409bSToby Isaac Nf = prob->Nf; 5162e071409bSToby Isaac label = dm->depthLabel; 5163e071409bSToby Isaac *dspace = NULL; 5164e071409bSToby Isaac if (field < Nf) { 5165e071409bSToby Isaac PetscObject disc = prob->disc[field]; 5166e071409bSToby Isaac 5167e071409bSToby Isaac if (disc->classid == PETSCFE_CLASSID) { 5168e071409bSToby Isaac PetscDualSpace dsp; 5169e071409bSToby Isaac 5170e071409bSToby Isaac ierr = PetscFEGetDualSpace((PetscFE)disc,&dsp);CHKERRQ(ierr); 5171e071409bSToby Isaac ierr = DMLabelGetNumValues(label,&depth);CHKERRQ(ierr); 5172e071409bSToby Isaac ierr = DMLabelGetValue(label,point,&h);CHKERRQ(ierr); 5173e071409bSToby Isaac h = depth - 1 - h; 5174e071409bSToby Isaac if (h) { 5175e071409bSToby Isaac ierr = PetscDualSpaceGetHeightSubspace(dsp,h,dspace);CHKERRQ(ierr); 5176e071409bSToby Isaac } else { 5177e071409bSToby Isaac *dspace = dsp; 5178e071409bSToby Isaac } 5179e071409bSToby Isaac } 5180e071409bSToby Isaac } 5181e071409bSToby Isaac PetscFunctionReturn(0); 5182e071409bSToby Isaac } 5183e071409bSToby Isaac 51841a271a75SMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode DMPlexVecGetClosure_Depth1_Static(DM dm, PetscSection section, Vec v, PetscInt point, PetscInt *csize, PetscScalar *values[]) 5185a6dfd86eSKarl Rupp { 5186552f7358SJed Brown PetscScalar *array, *vArray; 5187d9917b9dSMatthew G. Knepley const PetscInt *cone, *coneO; 51881a271a75SMatthew G. Knepley PetscInt pStart, pEnd, p, numPoints, size = 0, offset = 0; 5189552f7358SJed Brown PetscErrorCode ierr; 5190552f7358SJed Brown 51911b406b76SMatthew G. Knepley PetscFunctionBeginHot; 51922a3aaacfSMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 51935a1bb5cfSMatthew G. Knepley ierr = DMPlexGetConeSize(dm, point, &numPoints);CHKERRQ(ierr); 51945a1bb5cfSMatthew G. Knepley ierr = DMPlexGetCone(dm, point, &cone);CHKERRQ(ierr); 51955a1bb5cfSMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, point, &coneO);CHKERRQ(ierr); 51963f7cbbe7SMatthew G. Knepley if (!values || !*values) { 51979df71ca4SMatthew G. Knepley if ((point >= pStart) && (point < pEnd)) { 51989df71ca4SMatthew G. Knepley PetscInt dof; 5199d9917b9dSMatthew G. Knepley 52009df71ca4SMatthew G. Knepley ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 52019df71ca4SMatthew G. Knepley size += dof; 52029df71ca4SMatthew G. Knepley } 52039df71ca4SMatthew G. Knepley for (p = 0; p < numPoints; ++p) { 52049df71ca4SMatthew G. Knepley const PetscInt cp = cone[p]; 52052a3aaacfSMatthew G. Knepley PetscInt dof; 52065a1bb5cfSMatthew G. Knepley 52075a1bb5cfSMatthew G. Knepley if ((cp < pStart) || (cp >= pEnd)) continue; 52082a3aaacfSMatthew G. Knepley ierr = PetscSectionGetDof(section, cp, &dof);CHKERRQ(ierr); 52095a1bb5cfSMatthew G. Knepley size += dof; 52105a1bb5cfSMatthew G. Knepley } 52113f7cbbe7SMatthew G. Knepley if (!values) { 52123f7cbbe7SMatthew G. Knepley if (csize) *csize = size; 52133f7cbbe7SMatthew G. Knepley PetscFunctionReturn(0); 52143f7cbbe7SMatthew G. Knepley } 521569291d52SBarry Smith ierr = DMGetWorkArray(dm, size, MPIU_SCALAR, &array);CHKERRQ(ierr); 5216982e9ed1SMatthew G. Knepley } else { 5217982e9ed1SMatthew G. Knepley array = *values; 5218982e9ed1SMatthew G. Knepley } 52199df71ca4SMatthew G. Knepley size = 0; 52205a1bb5cfSMatthew G. Knepley ierr = VecGetArray(v, &vArray);CHKERRQ(ierr); 52219df71ca4SMatthew G. Knepley if ((point >= pStart) && (point < pEnd)) { 52229df71ca4SMatthew G. Knepley PetscInt dof, off, d; 52239df71ca4SMatthew G. Knepley PetscScalar *varr; 5224d9917b9dSMatthew G. Knepley 52259df71ca4SMatthew G. Knepley ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 52269df71ca4SMatthew G. Knepley ierr = PetscSectionGetOffset(section, point, &off);CHKERRQ(ierr); 52279df71ca4SMatthew G. Knepley varr = &vArray[off]; 52281a271a75SMatthew G. Knepley for (d = 0; d < dof; ++d, ++offset) { 52291a271a75SMatthew G. Knepley array[offset] = varr[d]; 52309df71ca4SMatthew G. Knepley } 52319df71ca4SMatthew G. Knepley size += dof; 52329df71ca4SMatthew G. Knepley } 52339df71ca4SMatthew G. Knepley for (p = 0; p < numPoints; ++p) { 52349df71ca4SMatthew G. Knepley const PetscInt cp = cone[p]; 52359df71ca4SMatthew G. Knepley PetscInt o = coneO[p]; 52365a1bb5cfSMatthew G. Knepley PetscInt dof, off, d; 52375a1bb5cfSMatthew G. Knepley PetscScalar *varr; 52385a1bb5cfSMatthew G. Knepley 523952ed52e8SMatthew G. Knepley if ((cp < pStart) || (cp >= pEnd)) continue; 52405a1bb5cfSMatthew G. Knepley ierr = PetscSectionGetDof(section, cp, &dof);CHKERRQ(ierr); 52415a1bb5cfSMatthew G. Knepley ierr = PetscSectionGetOffset(section, cp, &off);CHKERRQ(ierr); 52425a1bb5cfSMatthew G. Knepley varr = &vArray[off]; 52435a1bb5cfSMatthew G. Knepley if (o >= 0) { 52441a271a75SMatthew G. Knepley for (d = 0; d < dof; ++d, ++offset) { 52451a271a75SMatthew G. Knepley array[offset] = varr[d]; 52465a1bb5cfSMatthew G. Knepley } 52475a1bb5cfSMatthew G. Knepley } else { 52481a271a75SMatthew G. Knepley for (d = dof-1; d >= 0; --d, ++offset) { 52491a271a75SMatthew G. Knepley array[offset] = varr[d]; 52505a1bb5cfSMatthew G. Knepley } 52515a1bb5cfSMatthew G. Knepley } 52529df71ca4SMatthew G. Knepley size += dof; 52535a1bb5cfSMatthew G. Knepley } 52545a1bb5cfSMatthew G. Knepley ierr = VecRestoreArray(v, &vArray);CHKERRQ(ierr); 52559df71ca4SMatthew G. Knepley if (!*values) { 52565a1bb5cfSMatthew G. Knepley if (csize) *csize = size; 52575a1bb5cfSMatthew G. Knepley *values = array; 52589df71ca4SMatthew G. Knepley } else { 52598ccfff9cSToby Isaac if (size > *csize) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Size of input array %D < actual size %D", *csize, size); 52608c312ff3SMatthew G. Knepley *csize = size; 52619df71ca4SMatthew G. Knepley } 52625a1bb5cfSMatthew G. Knepley PetscFunctionReturn(0); 52635a1bb5cfSMatthew G. Knepley } 5264d9917b9dSMatthew G. Knepley 526527f02ce8SMatthew G. Knepley /* Compress out points not in the section */ 526627f02ce8SMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode CompressPoints_Private(PetscSection section, PetscInt *numPoints, PetscInt points[]) 526727f02ce8SMatthew G. Knepley { 526827f02ce8SMatthew G. Knepley const PetscInt np = *numPoints; 526927f02ce8SMatthew G. Knepley PetscInt pStart, pEnd, p, q; 527027f02ce8SMatthew G. Knepley PetscErrorCode ierr; 527127f02ce8SMatthew G. Knepley 527227f02ce8SMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 527327f02ce8SMatthew G. Knepley for (p = 0, q = 0; p < np; ++p) { 527427f02ce8SMatthew G. Knepley const PetscInt r = points[p*2]; 527527f02ce8SMatthew G. Knepley if ((r >= pStart) && (r < pEnd)) { 527627f02ce8SMatthew G. Knepley points[q*2] = r; 527727f02ce8SMatthew G. Knepley points[q*2+1] = points[p*2+1]; 527827f02ce8SMatthew G. Knepley ++q; 527927f02ce8SMatthew G. Knepley } 528027f02ce8SMatthew G. Knepley } 528127f02ce8SMatthew G. Knepley *numPoints = q; 528227f02ce8SMatthew G. Knepley return 0; 528327f02ce8SMatthew G. Knepley } 528427f02ce8SMatthew G. Knepley 528527f02ce8SMatthew G. Knepley static PetscErrorCode DMPlexTransitiveClosure_Hybrid_Internal(DM dm, PetscInt point, PetscInt np, PetscInt *numPoints, PetscInt **points) 528627f02ce8SMatthew G. Knepley { 528727f02ce8SMatthew G. Knepley const PetscInt *cone, *ornt; 528827f02ce8SMatthew G. Knepley PetscInt *pts, *closure = NULL; 528927f02ce8SMatthew G. Knepley PetscInt dim, coneSize, c, d, clSize, cl; 529027f02ce8SMatthew G. Knepley PetscErrorCode ierr; 529127f02ce8SMatthew G. Knepley 529227f02ce8SMatthew G. Knepley PetscFunctionBeginHot; 529327f02ce8SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 529427f02ce8SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, point, &coneSize);CHKERRQ(ierr); 529527f02ce8SMatthew G. Knepley ierr = DMPlexGetCone(dm, point, &cone);CHKERRQ(ierr); 529627f02ce8SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, point, &ornt);CHKERRQ(ierr); 529727f02ce8SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, cone[0], PETSC_TRUE, &clSize, &closure);CHKERRQ(ierr); 529827f02ce8SMatthew G. Knepley ierr = DMGetWorkArray(dm, np*2, MPIU_INT, &pts);CHKERRQ(ierr); 529927f02ce8SMatthew G. Knepley c = 0; 530027f02ce8SMatthew G. Knepley pts[c*2+0] = point; 530127f02ce8SMatthew G. Knepley pts[c*2+1] = 0; 530227f02ce8SMatthew G. Knepley ++c; 530327f02ce8SMatthew G. Knepley for (cl = 0; cl < clSize*2; cl += 2, ++c) {pts[c*2+0] = closure[cl]; pts[c*2+1] = closure[cl+1];} 530427f02ce8SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, cone[1], PETSC_TRUE, &clSize, &closure);CHKERRQ(ierr); 530527f02ce8SMatthew G. Knepley for (cl = 0; cl < clSize*2; cl += 2, ++c) {pts[c*2+0] = closure[cl]; pts[c*2+1] = closure[cl+1];} 530627f02ce8SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, cone[0], PETSC_TRUE, &clSize, &closure);CHKERRQ(ierr); 530727f02ce8SMatthew G. Knepley if (dim >= 2) { 530827f02ce8SMatthew G. Knepley for (d = 2; d < coneSize; ++d, ++c) {pts[c*2+0] = cone[d]; pts[c*2+1] = ornt[d];} 530927f02ce8SMatthew G. Knepley } 531027f02ce8SMatthew G. Knepley if (dim >= 3) { 531127f02ce8SMatthew G. Knepley for (d = 2; d < coneSize; ++d) { 531227f02ce8SMatthew G. Knepley const PetscInt fpoint = cone[d]; 531327f02ce8SMatthew G. Knepley const PetscInt *fcone; 531427f02ce8SMatthew G. Knepley PetscInt fconeSize, fc, i; 531527f02ce8SMatthew G. Knepley 531627f02ce8SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, fpoint, &fconeSize);CHKERRQ(ierr); 531727f02ce8SMatthew G. Knepley ierr = DMPlexGetCone(dm, fpoint, &fcone);CHKERRQ(ierr); 531827f02ce8SMatthew G. Knepley for (fc = 0; fc < fconeSize; ++fc) { 531927f02ce8SMatthew G. Knepley for (i = 0; i < c; ++i) if (pts[i*2] == fcone[fc]) break; 532027f02ce8SMatthew G. Knepley if (i == c) {pts[c*2+0] = fcone[fc]; pts[c*2+1] = 0; ++c;} 532127f02ce8SMatthew G. Knepley } 532227f02ce8SMatthew G. Knepley } 532327f02ce8SMatthew G. Knepley } 532427f02ce8SMatthew G. Knepley if (c != np) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid closure for hybrid point %D, size %D != %D", point, c, np); 532527f02ce8SMatthew G. Knepley *numPoints = np; 532627f02ce8SMatthew G. Knepley *points = pts; 532727f02ce8SMatthew G. Knepley PetscFunctionReturn(0); 532827f02ce8SMatthew G. Knepley } 532927f02ce8SMatthew G. Knepley 533097529cf3SJed Brown /* Compressed closure does not apply closure permutation */ 53311dc59d61SMatthew G. Knepley PetscErrorCode DMPlexGetCompressedClosure(DM dm, PetscSection section, PetscInt point, PetscInt *numPoints, PetscInt **points, PetscSection *clSec, IS *clPoints, const PetscInt **clp) 5332923c78e0SToby Isaac { 533327f02ce8SMatthew G. Knepley const PetscInt *cla = NULL; 5334923c78e0SToby Isaac PetscInt np, *pts = NULL; 5335923c78e0SToby Isaac PetscErrorCode ierr; 5336923c78e0SToby Isaac 5337923c78e0SToby Isaac PetscFunctionBeginHot; 5338923c78e0SToby Isaac ierr = PetscSectionGetClosureIndex(section, (PetscObject) dm, clSec, clPoints);CHKERRQ(ierr); 533927f02ce8SMatthew G. Knepley if (*clPoints) { 5340923c78e0SToby Isaac PetscInt dof, off; 5341923c78e0SToby Isaac 5342923c78e0SToby Isaac ierr = PetscSectionGetDof(*clSec, point, &dof);CHKERRQ(ierr); 5343923c78e0SToby Isaac ierr = PetscSectionGetOffset(*clSec, point, &off);CHKERRQ(ierr); 5344923c78e0SToby Isaac ierr = ISGetIndices(*clPoints, &cla);CHKERRQ(ierr); 5345923c78e0SToby Isaac np = dof/2; 5346923c78e0SToby Isaac pts = (PetscInt *) &cla[off]; 534727f02ce8SMatthew G. Knepley } else { 5348665f567fSMatthew G. Knepley DMPolytopeType ct; 5349665f567fSMatthew G. Knepley 535027f02ce8SMatthew G. Knepley /* Do not make the label if it does not exist */ 535127f02ce8SMatthew G. Knepley if (!dm->celltypeLabel) {ct = DM_POLYTOPE_POINT;} 535227f02ce8SMatthew G. Knepley else {ierr = DMPlexGetCellType(dm, point, &ct);CHKERRQ(ierr);} 535327f02ce8SMatthew G. Knepley switch (ct) { 535427f02ce8SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 535527f02ce8SMatthew G. Knepley ierr = DMPlexTransitiveClosure_Hybrid_Internal(dm, point, 9, &np, &pts);CHKERRQ(ierr); 535627f02ce8SMatthew G. Knepley break; 535727f02ce8SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 535827f02ce8SMatthew G. Knepley ierr = DMPlexTransitiveClosure_Hybrid_Internal(dm, point, 21, &np, &pts);CHKERRQ(ierr); 535927f02ce8SMatthew G. Knepley break; 536027f02ce8SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 536127f02ce8SMatthew G. Knepley ierr = DMPlexTransitiveClosure_Hybrid_Internal(dm, point, 27, &np, &pts);CHKERRQ(ierr); 536227f02ce8SMatthew G. Knepley break; 536327f02ce8SMatthew G. Knepley default: 536427f02ce8SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, point, PETSC_TRUE, &np, &pts);CHKERRQ(ierr); 536527f02ce8SMatthew G. Knepley } 536627f02ce8SMatthew G. Knepley ierr = CompressPoints_Private(section, &np, pts);CHKERRQ(ierr); 5367923c78e0SToby Isaac } 5368923c78e0SToby Isaac *numPoints = np; 5369923c78e0SToby Isaac *points = pts; 5370923c78e0SToby Isaac *clp = cla; 5371923c78e0SToby Isaac PetscFunctionReturn(0); 5372923c78e0SToby Isaac } 5373923c78e0SToby Isaac 53741dc59d61SMatthew G. Knepley PetscErrorCode DMPlexRestoreCompressedClosure(DM dm, PetscSection section, PetscInt point, PetscInt *numPoints, PetscInt **points, PetscSection *clSec, IS *clPoints, const PetscInt **clp) 5375923c78e0SToby Isaac { 5376923c78e0SToby Isaac PetscErrorCode ierr; 5377923c78e0SToby Isaac 5378923c78e0SToby Isaac PetscFunctionBeginHot; 5379923c78e0SToby Isaac if (!*clPoints) { 5380923c78e0SToby Isaac ierr = DMPlexRestoreTransitiveClosure(dm, point, PETSC_TRUE, numPoints, points);CHKERRQ(ierr); 5381923c78e0SToby Isaac } else { 5382923c78e0SToby Isaac ierr = ISRestoreIndices(*clPoints, clp);CHKERRQ(ierr); 5383923c78e0SToby Isaac } 5384923c78e0SToby Isaac *numPoints = 0; 5385923c78e0SToby Isaac *points = NULL; 5386923c78e0SToby Isaac *clSec = NULL; 5387923c78e0SToby Isaac *clPoints = NULL; 5388923c78e0SToby Isaac *clp = NULL; 5389923c78e0SToby Isaac PetscFunctionReturn(0); 5390923c78e0SToby Isaac } 5391923c78e0SToby Isaac 539297e99dd9SToby 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[]) 53931a271a75SMatthew G. Knepley { 53941a271a75SMatthew G. Knepley PetscInt offset = 0, p; 539597e99dd9SToby Isaac const PetscInt **perms = NULL; 539697e99dd9SToby Isaac const PetscScalar **flips = NULL; 53971a271a75SMatthew G. Knepley PetscErrorCode ierr; 53981a271a75SMatthew G. Knepley 53991a271a75SMatthew G. Knepley PetscFunctionBeginHot; 5400fe02ba77SJed Brown *size = 0; 540197e99dd9SToby Isaac ierr = PetscSectionGetPointSyms(section,numPoints,points,&perms,&flips);CHKERRQ(ierr); 540297e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 540397e99dd9SToby Isaac const PetscInt point = points[2*p]; 540497e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 540597e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 54061a271a75SMatthew G. Knepley PetscInt dof, off, d; 54071a271a75SMatthew G. Knepley const PetscScalar *varr; 54081a271a75SMatthew G. Knepley 54091a271a75SMatthew G. Knepley ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 54101a271a75SMatthew G. Knepley ierr = PetscSectionGetOffset(section, point, &off);CHKERRQ(ierr); 54111a271a75SMatthew G. Knepley varr = &vArray[off]; 541297e99dd9SToby Isaac if (clperm) { 541397e99dd9SToby Isaac if (perm) { 541497e99dd9SToby Isaac for (d = 0; d < dof; d++) array[clperm[offset + perm[d]]] = varr[d]; 54151a271a75SMatthew G. Knepley } else { 541697e99dd9SToby Isaac for (d = 0; d < dof; d++) array[clperm[offset + d ]] = varr[d]; 541797e99dd9SToby Isaac } 541897e99dd9SToby Isaac if (flip) { 541997e99dd9SToby Isaac for (d = 0; d < dof; d++) array[clperm[offset + d ]] *= flip[d]; 542097e99dd9SToby Isaac } 542197e99dd9SToby Isaac } else { 542297e99dd9SToby Isaac if (perm) { 542397e99dd9SToby Isaac for (d = 0; d < dof; d++) array[offset + perm[d]] = varr[d]; 542497e99dd9SToby Isaac } else { 542597e99dd9SToby Isaac for (d = 0; d < dof; d++) array[offset + d ] = varr[d]; 542697e99dd9SToby Isaac } 542797e99dd9SToby Isaac if (flip) { 542897e99dd9SToby Isaac for (d = 0; d < dof; d++) array[offset + d ] *= flip[d]; 54291a271a75SMatthew G. Knepley } 54301a271a75SMatthew G. Knepley } 543197e99dd9SToby Isaac offset += dof; 543297e99dd9SToby Isaac } 543397e99dd9SToby Isaac ierr = PetscSectionRestorePointSyms(section,numPoints,points,&perms,&flips);CHKERRQ(ierr); 54341a271a75SMatthew G. Knepley *size = offset; 54351a271a75SMatthew G. Knepley PetscFunctionReturn(0); 54361a271a75SMatthew G. Knepley } 54371a271a75SMatthew G. Knepley 543897e99dd9SToby 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[]) 54391a271a75SMatthew G. Knepley { 54401a271a75SMatthew G. Knepley PetscInt offset = 0, f; 54411a271a75SMatthew G. Knepley PetscErrorCode ierr; 54421a271a75SMatthew G. Knepley 54431a271a75SMatthew G. Knepley PetscFunctionBeginHot; 5444fe02ba77SJed Brown *size = 0; 54451a271a75SMatthew G. Knepley for (f = 0; f < numFields; ++f) { 544697e99dd9SToby Isaac PetscInt p; 544797e99dd9SToby Isaac const PetscInt **perms = NULL; 544897e99dd9SToby Isaac const PetscScalar **flips = NULL; 54491a271a75SMatthew G. Knepley 545097e99dd9SToby Isaac ierr = PetscSectionGetFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 545197e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 545297e99dd9SToby Isaac const PetscInt point = points[2*p]; 545397e99dd9SToby Isaac PetscInt fdof, foff, b; 54541a271a75SMatthew G. Knepley const PetscScalar *varr; 545597e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 545697e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 54571a271a75SMatthew G. Knepley 54581a271a75SMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 54591a271a75SMatthew G. Knepley ierr = PetscSectionGetFieldOffset(section, point, f, &foff);CHKERRQ(ierr); 54601a271a75SMatthew G. Knepley varr = &vArray[foff]; 546197e99dd9SToby Isaac if (clperm) { 546297e99dd9SToby Isaac if (perm) {for (b = 0; b < fdof; b++) {array[clperm[offset + perm[b]]] = varr[b];}} 546397e99dd9SToby Isaac else {for (b = 0; b < fdof; b++) {array[clperm[offset + b ]] = varr[b];}} 546497e99dd9SToby Isaac if (flip) {for (b = 0; b < fdof; b++) {array[clperm[offset + b ]] *= flip[b];}} 54651a271a75SMatthew G. Knepley } else { 546697e99dd9SToby Isaac if (perm) {for (b = 0; b < fdof; b++) {array[offset + perm[b]] = varr[b];}} 546797e99dd9SToby Isaac else {for (b = 0; b < fdof; b++) {array[offset + b ] = varr[b];}} 546897e99dd9SToby Isaac if (flip) {for (b = 0; b < fdof; b++) {array[offset + b ] *= flip[b];}} 54691a271a75SMatthew G. Knepley } 547097e99dd9SToby Isaac offset += fdof; 54711a271a75SMatthew G. Knepley } 547297e99dd9SToby Isaac ierr = PetscSectionRestoreFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 54731a271a75SMatthew G. Knepley } 54741a271a75SMatthew G. Knepley *size = offset; 54751a271a75SMatthew G. Knepley PetscFunctionReturn(0); 54761a271a75SMatthew G. Knepley } 54771a271a75SMatthew G. Knepley 5478552f7358SJed Brown /*@C 5479552f7358SJed Brown DMPlexVecGetClosure - Get an array of the values on the closure of 'point' 5480552f7358SJed Brown 5481552f7358SJed Brown Not collective 5482552f7358SJed Brown 5483552f7358SJed Brown Input Parameters: 5484552f7358SJed Brown + dm - The DM 5485552f7358SJed Brown . section - The section describing the layout in v, or NULL to use the default section 5486552f7358SJed Brown . v - The local vector 548722c1ee49SMatthew G. Knepley . point - The point in the DM 548822c1ee49SMatthew G. Knepley . csize - The size of the input values array, or NULL 548922c1ee49SMatthew G. Knepley - values - An array to use for the values, or NULL to have it allocated automatically 5490552f7358SJed Brown 5491552f7358SJed Brown Output Parameters: 549222c1ee49SMatthew G. Knepley + csize - The number of values in the closure 549322c1ee49SMatthew G. Knepley - values - The array of values. If the user provided NULL, it is a borrowed array and should not be freed 549422c1ee49SMatthew G. Knepley 549522c1ee49SMatthew G. Knepley $ Note that DMPlexVecGetClosure/DMPlexVecRestoreClosure only allocates the values array if it set to NULL in the 549622c1ee49SMatthew G. Knepley $ calling function. This is because DMPlexVecGetClosure() is typically called in the inner loop of a Vec or Mat 549722c1ee49SMatthew G. Knepley $ assembly function, and a user may already have allocated storage for this operation. 549822c1ee49SMatthew G. Knepley $ 549922c1ee49SMatthew G. Knepley $ A typical use could be 550022c1ee49SMatthew G. Knepley $ 550122c1ee49SMatthew G. Knepley $ values = NULL; 550222c1ee49SMatthew G. Knepley $ ierr = DMPlexVecGetClosure(dm, NULL, v, p, &clSize, &values);CHKERRQ(ierr); 550322c1ee49SMatthew G. Knepley $ for (cl = 0; cl < clSize; ++cl) { 550422c1ee49SMatthew G. Knepley $ <Compute on closure> 550522c1ee49SMatthew G. Knepley $ } 550622c1ee49SMatthew G. Knepley $ ierr = DMPlexVecRestoreClosure(dm, NULL, v, p, &clSize, &values);CHKERRQ(ierr); 550722c1ee49SMatthew G. Knepley $ 550822c1ee49SMatthew G. Knepley $ or 550922c1ee49SMatthew G. Knepley $ 551022c1ee49SMatthew G. Knepley $ PetscMalloc1(clMaxSize, &values); 551122c1ee49SMatthew G. Knepley $ for (p = pStart; p < pEnd; ++p) { 551222c1ee49SMatthew G. Knepley $ clSize = clMaxSize; 551322c1ee49SMatthew G. Knepley $ ierr = DMPlexVecGetClosure(dm, NULL, v, p, &clSize, &values);CHKERRQ(ierr); 551422c1ee49SMatthew G. Knepley $ for (cl = 0; cl < clSize; ++cl) { 551522c1ee49SMatthew G. Knepley $ <Compute on closure> 551622c1ee49SMatthew G. Knepley $ } 551722c1ee49SMatthew G. Knepley $ } 551822c1ee49SMatthew G. Knepley $ PetscFree(values); 5519552f7358SJed Brown 5520552f7358SJed Brown Fortran Notes: 5521552f7358SJed Brown Since it returns an array, this routine is only available in Fortran 90, and you must 5522552f7358SJed Brown include petsc.h90 in your code. 5523552f7358SJed Brown 5524552f7358SJed Brown The csize argument is not present in the Fortran 90 binding since it is internal to the array. 5525552f7358SJed Brown 5526552f7358SJed Brown Level: intermediate 5527552f7358SJed Brown 5528552f7358SJed Brown .seealso DMPlexVecRestoreClosure(), DMPlexVecSetClosure(), DMPlexMatSetClosure() 5529552f7358SJed Brown @*/ 5530552f7358SJed Brown PetscErrorCode DMPlexVecGetClosure(DM dm, PetscSection section, Vec v, PetscInt point, PetscInt *csize, PetscScalar *values[]) 5531552f7358SJed Brown { 5532552f7358SJed Brown PetscSection clSection; 5533d9917b9dSMatthew G. Knepley IS clPoints; 5534552f7358SJed Brown PetscInt *points = NULL; 5535c459fbc1SJed Brown const PetscInt *clp, *perm; 5536c459fbc1SJed Brown PetscInt depth, numFields, numPoints, asize; 5537552f7358SJed Brown PetscErrorCode ierr; 5538552f7358SJed Brown 5539d9917b9dSMatthew G. Knepley PetscFunctionBeginHot; 5540552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 554192fd8e1eSJed Brown if (!section) {ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr);} 55421a271a75SMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 55431a271a75SMatthew G. Knepley PetscValidHeaderSpecific(v, VEC_CLASSID, 3); 5544552f7358SJed Brown ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 5545552f7358SJed Brown ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 5546552f7358SJed Brown if (depth == 1 && numFields < 2) { 55471a271a75SMatthew G. Knepley ierr = DMPlexVecGetClosure_Depth1_Static(dm, section, v, point, csize, values);CHKERRQ(ierr); 5548552f7358SJed Brown PetscFunctionReturn(0); 5549552f7358SJed Brown } 55501a271a75SMatthew G. Knepley /* Get points */ 5551923c78e0SToby Isaac ierr = DMPlexGetCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 5552c459fbc1SJed Brown /* Get sizes */ 5553c459fbc1SJed Brown asize = 0; 5554c459fbc1SJed Brown for (PetscInt p = 0; p < numPoints*2; p += 2) { 5555c459fbc1SJed Brown PetscInt dof; 5556552f7358SJed Brown ierr = PetscSectionGetDof(section, points[p], &dof);CHKERRQ(ierr); 55571a271a75SMatthew G. Knepley asize += dof; 5558552f7358SJed Brown } 5559c459fbc1SJed Brown if (values) { 5560c459fbc1SJed Brown const PetscScalar *vArray; 5561c459fbc1SJed Brown PetscInt size; 5562c459fbc1SJed Brown 5563c459fbc1SJed Brown if (*values) { 5564c459fbc1SJed 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); 5565c459fbc1SJed Brown } else {ierr = DMGetWorkArray(dm, asize, MPIU_SCALAR, values);CHKERRQ(ierr);} 5566c459fbc1SJed Brown ierr = PetscSectionGetClosureInversePermutation_Internal(section, (PetscObject) dm, depth, asize, &perm);CHKERRQ(ierr); 55678a84db2dSMatthew G. Knepley ierr = VecGetArrayRead(v, &vArray);CHKERRQ(ierr); 55681a271a75SMatthew G. Knepley /* Get values */ 5569c459fbc1SJed Brown if (numFields > 0) {ierr = DMPlexVecGetClosure_Fields_Static(dm, section, numPoints, points, numFields, perm, vArray, &size, *values);CHKERRQ(ierr);} 5570c459fbc1SJed Brown else {ierr = DMPlexVecGetClosure_Static(dm, section, numPoints, points, perm, vArray, &size, *values);CHKERRQ(ierr);} 5571c459fbc1SJed Brown if (PetscUnlikely(asize != size)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Section size %D does not match Vec closure size %D", asize, size); 55721a271a75SMatthew G. Knepley /* Cleanup array */ 55738a84db2dSMatthew G. Knepley ierr = VecRestoreArrayRead(v, &vArray);CHKERRQ(ierr); 5574d0f6b257SMatthew G. Knepley } 5575c459fbc1SJed Brown if (csize) *csize = asize; 5576c459fbc1SJed Brown /* Cleanup points */ 5577c459fbc1SJed Brown ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 5578552f7358SJed Brown PetscFunctionReturn(0); 5579552f7358SJed Brown } 5580552f7358SJed Brown 5581e5c487bfSMatthew G. Knepley PetscErrorCode DMPlexVecGetClosureAtDepth_Internal(DM dm, PetscSection section, Vec v, PetscInt point, PetscInt depth, PetscInt *csize, PetscScalar *values[]) 5582e5c487bfSMatthew G. Knepley { 5583e5c487bfSMatthew G. Knepley DMLabel depthLabel; 5584e5c487bfSMatthew G. Knepley PetscSection clSection; 5585e5c487bfSMatthew G. Knepley IS clPoints; 5586e5c487bfSMatthew G. Knepley PetscScalar *array; 5587e5c487bfSMatthew G. Knepley const PetscScalar *vArray; 5588e5c487bfSMatthew G. Knepley PetscInt *points = NULL; 5589c459fbc1SJed Brown const PetscInt *clp, *perm = NULL; 5590c459fbc1SJed Brown PetscInt mdepth, numFields, numPoints, Np = 0, p, clsize, size; 5591e5c487bfSMatthew G. Knepley PetscErrorCode ierr; 5592e5c487bfSMatthew G. Knepley 5593e5c487bfSMatthew G. Knepley PetscFunctionBeginHot; 5594e5c487bfSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5595e5c487bfSMatthew G. Knepley if (!section) {ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr);} 5596e5c487bfSMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 5597e5c487bfSMatthew G. Knepley PetscValidHeaderSpecific(v, VEC_CLASSID, 3); 5598e5c487bfSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &mdepth);CHKERRQ(ierr); 5599e5c487bfSMatthew G. Knepley ierr = DMPlexGetDepthLabel(dm, &depthLabel);CHKERRQ(ierr); 5600e5c487bfSMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 5601e5c487bfSMatthew G. Knepley if (mdepth == 1 && numFields < 2) { 5602e5c487bfSMatthew G. Knepley ierr = DMPlexVecGetClosure_Depth1_Static(dm, section, v, point, csize, values);CHKERRQ(ierr); 5603e5c487bfSMatthew G. Knepley PetscFunctionReturn(0); 5604e5c487bfSMatthew G. Knepley } 5605e5c487bfSMatthew G. Knepley /* Get points */ 5606e5c487bfSMatthew G. Knepley ierr = DMPlexGetCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 5607c459fbc1SJed Brown for (clsize=0,p=0; p<Np; p++) { 5608c459fbc1SJed Brown PetscInt dof; 5609c459fbc1SJed Brown ierr = PetscSectionGetDof(section, points[2*p], &dof);CHKERRQ(ierr); 5610c459fbc1SJed Brown clsize += dof; 5611c459fbc1SJed Brown } 5612c459fbc1SJed Brown ierr = PetscSectionGetClosureInversePermutation_Internal(section, (PetscObject) dm, depth, clsize, &perm);CHKERRQ(ierr); 5613e5c487bfSMatthew G. Knepley /* Filter points */ 5614e5c487bfSMatthew G. Knepley for (p = 0; p < numPoints*2; p += 2) { 5615e5c487bfSMatthew G. Knepley PetscInt dep; 5616e5c487bfSMatthew G. Knepley 5617e5c487bfSMatthew G. Knepley ierr = DMLabelGetValue(depthLabel, points[p], &dep);CHKERRQ(ierr); 5618e5c487bfSMatthew G. Knepley if (dep != depth) continue; 5619e5c487bfSMatthew G. Knepley points[Np*2+0] = points[p]; 5620e5c487bfSMatthew G. Knepley points[Np*2+1] = points[p+1]; 5621e5c487bfSMatthew G. Knepley ++Np; 5622e5c487bfSMatthew G. Knepley } 5623e5c487bfSMatthew G. Knepley /* Get array */ 5624e5c487bfSMatthew G. Knepley if (!values || !*values) { 5625e5c487bfSMatthew G. Knepley PetscInt asize = 0, dof; 5626e5c487bfSMatthew G. Knepley 5627e5c487bfSMatthew G. Knepley for (p = 0; p < Np*2; p += 2) { 5628e5c487bfSMatthew G. Knepley ierr = PetscSectionGetDof(section, points[p], &dof);CHKERRQ(ierr); 5629e5c487bfSMatthew G. Knepley asize += dof; 5630e5c487bfSMatthew G. Knepley } 5631e5c487bfSMatthew G. Knepley if (!values) { 5632e5c487bfSMatthew G. Knepley ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 5633e5c487bfSMatthew G. Knepley if (csize) *csize = asize; 5634e5c487bfSMatthew G. Knepley PetscFunctionReturn(0); 5635e5c487bfSMatthew G. Knepley } 5636e5c487bfSMatthew G. Knepley ierr = DMGetWorkArray(dm, asize, MPIU_SCALAR, &array);CHKERRQ(ierr); 5637e5c487bfSMatthew G. Knepley } else { 5638e5c487bfSMatthew G. Knepley array = *values; 5639e5c487bfSMatthew G. Knepley } 5640e5c487bfSMatthew G. Knepley ierr = VecGetArrayRead(v, &vArray);CHKERRQ(ierr); 5641e5c487bfSMatthew G. Knepley /* Get values */ 5642e5c487bfSMatthew G. Knepley if (numFields > 0) {ierr = DMPlexVecGetClosure_Fields_Static(dm, section, Np, points, numFields, perm, vArray, &size, array);CHKERRQ(ierr);} 5643e5c487bfSMatthew G. Knepley else {ierr = DMPlexVecGetClosure_Static(dm, section, Np, points, perm, vArray, &size, array);CHKERRQ(ierr);} 5644e5c487bfSMatthew G. Knepley /* Cleanup points */ 5645e5c487bfSMatthew G. Knepley ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 5646e5c487bfSMatthew G. Knepley /* Cleanup array */ 5647e5c487bfSMatthew G. Knepley ierr = VecRestoreArrayRead(v, &vArray);CHKERRQ(ierr); 5648e5c487bfSMatthew G. Knepley if (!*values) { 5649e5c487bfSMatthew G. Knepley if (csize) *csize = size; 5650e5c487bfSMatthew G. Knepley *values = array; 5651e5c487bfSMatthew G. Knepley } else { 5652e5c487bfSMatthew G. Knepley if (size > *csize) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Size of input array %D < actual size %D", *csize, size); 5653e5c487bfSMatthew G. Knepley *csize = size; 5654e5c487bfSMatthew G. Knepley } 5655e5c487bfSMatthew G. Knepley PetscFunctionReturn(0); 5656e5c487bfSMatthew G. Knepley } 5657e5c487bfSMatthew G. Knepley 5658552f7358SJed Brown /*@C 5659552f7358SJed Brown DMPlexVecRestoreClosure - Restore the array of the values on the closure of 'point' 5660552f7358SJed Brown 5661552f7358SJed Brown Not collective 5662552f7358SJed Brown 5663552f7358SJed Brown Input Parameters: 5664552f7358SJed Brown + dm - The DM 56650298fd71SBarry Smith . section - The section describing the layout in v, or NULL to use the default section 5666552f7358SJed Brown . v - The local vector 5667eaf898f9SPatrick Sanan . point - The point in the DM 56680298fd71SBarry Smith . csize - The number of values in the closure, or NULL 5669552f7358SJed Brown - values - The array of values, which is a borrowed array and should not be freed 5670552f7358SJed Brown 567122c1ee49SMatthew 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() 567222c1ee49SMatthew G. Knepley 56733813dfbdSMatthew G Knepley Fortran Notes: 56743813dfbdSMatthew G Knepley Since it returns an array, this routine is only available in Fortran 90, and you must 56753813dfbdSMatthew G Knepley include petsc.h90 in your code. 56763813dfbdSMatthew G Knepley 56773813dfbdSMatthew G Knepley The csize argument is not present in the Fortran 90 binding since it is internal to the array. 56783813dfbdSMatthew G Knepley 5679552f7358SJed Brown Level: intermediate 5680552f7358SJed Brown 5681552f7358SJed Brown .seealso DMPlexVecGetClosure(), DMPlexVecSetClosure(), DMPlexMatSetClosure() 5682552f7358SJed Brown @*/ 56837c1f9639SMatthew G Knepley PetscErrorCode DMPlexVecRestoreClosure(DM dm, PetscSection section, Vec v, PetscInt point, PetscInt *csize, PetscScalar *values[]) 5684a6dfd86eSKarl Rupp { 5685552f7358SJed Brown PetscInt size = 0; 5686552f7358SJed Brown PetscErrorCode ierr; 5687552f7358SJed Brown 5688552f7358SJed Brown PetscFunctionBegin; 5689552f7358SJed Brown /* Should work without recalculating size */ 569069291d52SBarry Smith ierr = DMRestoreWorkArray(dm, size, MPIU_SCALAR, (void*) values);CHKERRQ(ierr); 5691c9fdaa05SMatthew G. Knepley *values = NULL; 5692552f7358SJed Brown PetscFunctionReturn(0); 5693552f7358SJed Brown } 5694552f7358SJed Brown 5695552f7358SJed Brown PETSC_STATIC_INLINE void add (PetscScalar *x, PetscScalar y) {*x += y;} 5696552f7358SJed Brown PETSC_STATIC_INLINE void insert(PetscScalar *x, PetscScalar y) {*x = y;} 5697552f7358SJed Brown 569897e99dd9SToby 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[]) 5699552f7358SJed Brown { 5700552f7358SJed Brown PetscInt cdof; /* The number of constraints on this point */ 5701552f7358SJed Brown const PetscInt *cdofs; /* The indices of the constrained dofs on this point */ 5702552f7358SJed Brown PetscScalar *a; 5703552f7358SJed Brown PetscInt off, cind = 0, k; 5704552f7358SJed Brown PetscErrorCode ierr; 5705552f7358SJed Brown 5706552f7358SJed Brown PetscFunctionBegin; 5707552f7358SJed Brown ierr = PetscSectionGetConstraintDof(section, point, &cdof);CHKERRQ(ierr); 5708552f7358SJed Brown ierr = PetscSectionGetOffset(section, point, &off);CHKERRQ(ierr); 5709552f7358SJed Brown a = &array[off]; 5710552f7358SJed Brown if (!cdof || setBC) { 571197e99dd9SToby Isaac if (clperm) { 571297e99dd9SToby Isaac if (perm) {for (k = 0; k < dof; ++k) {fuse(&a[k], values[clperm[offset+perm[k]]] * (flip ? flip[perm[k]] : 1.));}} 571397e99dd9SToby Isaac else {for (k = 0; k < dof; ++k) {fuse(&a[k], values[clperm[offset+ k ]] * (flip ? flip[ k ] : 1.));}} 5714552f7358SJed Brown } else { 571597e99dd9SToby Isaac if (perm) {for (k = 0; k < dof; ++k) {fuse(&a[k], values[offset+perm[k]] * (flip ? flip[perm[k]] : 1.));}} 571697e99dd9SToby Isaac else {for (k = 0; k < dof; ++k) {fuse(&a[k], values[offset+ k ] * (flip ? flip[ k ] : 1.));}} 5717552f7358SJed Brown } 5718552f7358SJed Brown } else { 5719552f7358SJed Brown ierr = PetscSectionGetConstraintIndices(section, point, &cdofs);CHKERRQ(ierr); 572097e99dd9SToby Isaac if (clperm) { 572197e99dd9SToby Isaac if (perm) {for (k = 0; k < dof; ++k) { 5722552f7358SJed Brown if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 572397e99dd9SToby Isaac fuse(&a[k], values[clperm[offset+perm[k]]] * (flip ? flip[perm[k]] : 1.)); 5724552f7358SJed Brown } 5725552f7358SJed Brown } else { 5726552f7358SJed Brown for (k = 0; k < dof; ++k) { 5727552f7358SJed Brown if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 572897e99dd9SToby Isaac fuse(&a[k], values[clperm[offset+ k ]] * (flip ? flip[ k ] : 1.)); 572997e99dd9SToby Isaac } 573097e99dd9SToby Isaac } 573197e99dd9SToby Isaac } else { 573297e99dd9SToby Isaac if (perm) { 573397e99dd9SToby Isaac for (k = 0; k < dof; ++k) { 573497e99dd9SToby Isaac if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 573597e99dd9SToby Isaac fuse(&a[k], values[offset+perm[k]] * (flip ? flip[perm[k]] : 1.)); 573697e99dd9SToby Isaac } 573797e99dd9SToby Isaac } else { 573897e99dd9SToby Isaac for (k = 0; k < dof; ++k) { 573997e99dd9SToby Isaac if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 574097e99dd9SToby Isaac fuse(&a[k], values[offset+ k ] * (flip ? flip[ k ] : 1.)); 574197e99dd9SToby Isaac } 5742552f7358SJed Brown } 5743552f7358SJed Brown } 5744552f7358SJed Brown } 5745552f7358SJed Brown PetscFunctionReturn(0); 5746552f7358SJed Brown } 5747552f7358SJed Brown 574897e99dd9SToby 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[]) 5749a5e93ea8SMatthew G. Knepley { 5750a5e93ea8SMatthew G. Knepley PetscInt cdof; /* The number of constraints on this point */ 5751a5e93ea8SMatthew G. Knepley const PetscInt *cdofs; /* The indices of the constrained dofs on this point */ 5752a5e93ea8SMatthew G. Knepley PetscScalar *a; 5753a5e93ea8SMatthew G. Knepley PetscInt off, cind = 0, k; 5754a5e93ea8SMatthew G. Knepley PetscErrorCode ierr; 5755a5e93ea8SMatthew G. Knepley 5756a5e93ea8SMatthew G. Knepley PetscFunctionBegin; 5757a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(section, point, &cdof);CHKERRQ(ierr); 5758a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetOffset(section, point, &off);CHKERRQ(ierr); 5759a5e93ea8SMatthew G. Knepley a = &array[off]; 5760a5e93ea8SMatthew G. Knepley if (cdof) { 5761a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetConstraintIndices(section, point, &cdofs);CHKERRQ(ierr); 576297e99dd9SToby Isaac if (clperm) { 576397e99dd9SToby Isaac if (perm) { 5764a5e93ea8SMatthew G. Knepley for (k = 0; k < dof; ++k) { 5765a5e93ea8SMatthew G. Knepley if ((cind < cdof) && (k == cdofs[cind])) { 576697e99dd9SToby Isaac fuse(&a[k], values[clperm[offset+perm[k]]] * (flip ? flip[perm[k]] : 1.)); 576797e99dd9SToby Isaac cind++; 5768a5e93ea8SMatthew G. Knepley } 5769a5e93ea8SMatthew G. Knepley } 5770a5e93ea8SMatthew G. Knepley } else { 5771a5e93ea8SMatthew G. Knepley for (k = 0; k < dof; ++k) { 5772a5e93ea8SMatthew G. Knepley if ((cind < cdof) && (k == cdofs[cind])) { 577397e99dd9SToby Isaac fuse(&a[k], values[clperm[offset+ k ]] * (flip ? flip[ k ] : 1.)); 577497e99dd9SToby Isaac cind++; 577597e99dd9SToby Isaac } 577697e99dd9SToby Isaac } 577797e99dd9SToby Isaac } 577897e99dd9SToby Isaac } else { 577997e99dd9SToby Isaac if (perm) { 578097e99dd9SToby Isaac for (k = 0; k < dof; ++k) { 578197e99dd9SToby Isaac if ((cind < cdof) && (k == cdofs[cind])) { 578297e99dd9SToby Isaac fuse(&a[k], values[offset+perm[k]] * (flip ? flip[perm[k]] : 1.)); 578397e99dd9SToby Isaac cind++; 578497e99dd9SToby Isaac } 578597e99dd9SToby Isaac } 578697e99dd9SToby Isaac } else { 578797e99dd9SToby Isaac for (k = 0; k < dof; ++k) { 578897e99dd9SToby Isaac if ((cind < cdof) && (k == cdofs[cind])) { 578997e99dd9SToby Isaac fuse(&a[k], values[offset+ k ] * (flip ? flip[ k ] : 1.)); 579097e99dd9SToby Isaac cind++; 579197e99dd9SToby Isaac } 5792a5e93ea8SMatthew G. Knepley } 5793a5e93ea8SMatthew G. Knepley } 5794a5e93ea8SMatthew G. Knepley } 5795a5e93ea8SMatthew G. Knepley } 5796a5e93ea8SMatthew G. Knepley PetscFunctionReturn(0); 5797a5e93ea8SMatthew G. Knepley } 5798a5e93ea8SMatthew G. Knepley 579997e99dd9SToby 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[]) 5800a6dfd86eSKarl Rupp { 5801552f7358SJed Brown PetscScalar *a; 58021a271a75SMatthew G. Knepley PetscInt fdof, foff, fcdof, foffset = *offset; 58031a271a75SMatthew G. Knepley const PetscInt *fcdofs; /* The indices of the constrained dofs for field f on this point */ 580497e99dd9SToby Isaac PetscInt cind = 0, b; 5805552f7358SJed Brown PetscErrorCode ierr; 5806552f7358SJed Brown 5807552f7358SJed Brown PetscFunctionBegin; 5808552f7358SJed Brown ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 5809552f7358SJed Brown ierr = PetscSectionGetFieldConstraintDof(section, point, f, &fcdof);CHKERRQ(ierr); 58101a271a75SMatthew G. Knepley ierr = PetscSectionGetFieldOffset(section, point, f, &foff);CHKERRQ(ierr); 58111a271a75SMatthew G. Knepley a = &array[foff]; 5812552f7358SJed Brown if (!fcdof || setBC) { 581397e99dd9SToby Isaac if (clperm) { 581497e99dd9SToby Isaac if (perm) {for (b = 0; b < fdof; b++) {fuse(&a[b], values[clperm[foffset+perm[b]]] * (flip ? flip[perm[b]] : 1.));}} 581597e99dd9SToby Isaac else {for (b = 0; b < fdof; b++) {fuse(&a[b], values[clperm[foffset+ b ]] * (flip ? flip[ b ] : 1.));}} 5816552f7358SJed Brown } else { 581797e99dd9SToby Isaac if (perm) {for (b = 0; b < fdof; b++) {fuse(&a[b], values[foffset+perm[b]] * (flip ? flip[perm[b]] : 1.));}} 581897e99dd9SToby Isaac else {for (b = 0; b < fdof; b++) {fuse(&a[b], values[foffset+ b ] * (flip ? flip[ b ] : 1.));}} 5819552f7358SJed Brown } 5820552f7358SJed Brown } else { 5821552f7358SJed Brown ierr = PetscSectionGetFieldConstraintIndices(section, point, f, &fcdofs);CHKERRQ(ierr); 582297e99dd9SToby Isaac if (clperm) { 582397e99dd9SToby Isaac if (perm) { 582497e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 582597e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; continue;} 582697e99dd9SToby Isaac fuse(&a[b], values[clperm[foffset+perm[b]]] * (flip ? flip[perm[b]] : 1.)); 5827552f7358SJed Brown } 5828552f7358SJed Brown } else { 582997e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 583097e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; continue;} 583197e99dd9SToby Isaac fuse(&a[b], values[clperm[foffset+ b ]] * (flip ? flip[ b ] : 1.)); 583297e99dd9SToby Isaac } 583397e99dd9SToby Isaac } 583497e99dd9SToby Isaac } else { 583597e99dd9SToby Isaac if (perm) { 583697e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 583797e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; continue;} 583897e99dd9SToby Isaac fuse(&a[b], values[foffset+perm[b]] * (flip ? flip[perm[b]] : 1.)); 583997e99dd9SToby Isaac } 584097e99dd9SToby Isaac } else { 584197e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 584297e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; continue;} 584397e99dd9SToby Isaac fuse(&a[b], values[foffset+ b ] * (flip ? flip[ b ] : 1.)); 5844552f7358SJed Brown } 5845552f7358SJed Brown } 5846552f7358SJed Brown } 5847552f7358SJed Brown } 58481a271a75SMatthew G. Knepley *offset += fdof; 5849552f7358SJed Brown PetscFunctionReturn(0); 5850552f7358SJed Brown } 5851552f7358SJed Brown 5852ba322698SMatthew 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[]) 5853a5e93ea8SMatthew G. Knepley { 5854a5e93ea8SMatthew G. Knepley PetscScalar *a; 58551a271a75SMatthew G. Knepley PetscInt fdof, foff, fcdof, foffset = *offset; 58561a271a75SMatthew G. Knepley const PetscInt *fcdofs; /* The indices of the constrained dofs for field f on this point */ 58575da9d227SMatthew G. Knepley PetscInt Nc, cind = 0, ncind = 0, b; 5858ba322698SMatthew G. Knepley PetscBool ncSet, fcSet; 5859a5e93ea8SMatthew G. Knepley PetscErrorCode ierr; 5860a5e93ea8SMatthew G. Knepley 5861a5e93ea8SMatthew G. Knepley PetscFunctionBegin; 58625da9d227SMatthew G. Knepley ierr = PetscSectionGetFieldComponents(section, f, &Nc);CHKERRQ(ierr); 5863a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 5864a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetFieldConstraintDof(section, point, f, &fcdof);CHKERRQ(ierr); 58651a271a75SMatthew G. Knepley ierr = PetscSectionGetFieldOffset(section, point, f, &foff);CHKERRQ(ierr); 58661a271a75SMatthew G. Knepley a = &array[foff]; 5867a5e93ea8SMatthew G. Knepley if (fcdof) { 5868ba322698SMatthew G. Knepley /* We just override fcdof and fcdofs with Ncc and comps */ 5869a5e93ea8SMatthew G. Knepley ierr = PetscSectionGetFieldConstraintIndices(section, point, f, &fcdofs);CHKERRQ(ierr); 587097e99dd9SToby Isaac if (clperm) { 587197e99dd9SToby Isaac if (perm) { 5872ba322698SMatthew G. Knepley if (comps) { 5873ba322698SMatthew G. Knepley for (b = 0; b < fdof; b++) { 5874ba322698SMatthew G. Knepley ncSet = fcSet = PETSC_FALSE; 58755da9d227SMatthew G. Knepley if (b%Nc == comps[ncind]) {ncind = (ncind+1)%Ncc; ncSet = PETSC_TRUE;} 5876ba322698SMatthew G. Knepley if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; fcSet = PETSC_TRUE;} 5877ba322698SMatthew G. Knepley if (ncSet && fcSet) {fuse(&a[b], values[clperm[foffset+perm[b]]] * (flip ? flip[perm[b]] : 1.));} 5878ba322698SMatthew G. Knepley } 5879ba322698SMatthew G. Knepley } else { 588097e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 588197e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) { 588297e99dd9SToby Isaac fuse(&a[b], values[clperm[foffset+perm[b]]] * (flip ? flip[perm[b]] : 1.)); 5883a5e93ea8SMatthew G. Knepley ++cind; 5884a5e93ea8SMatthew G. Knepley } 5885a5e93ea8SMatthew G. Knepley } 5886ba322698SMatthew G. Knepley } 5887ba322698SMatthew G. Knepley } else { 5888ba322698SMatthew G. Knepley if (comps) { 5889ba322698SMatthew G. Knepley for (b = 0; b < fdof; b++) { 5890ba322698SMatthew G. Knepley ncSet = fcSet = PETSC_FALSE; 58915da9d227SMatthew G. Knepley if (b%Nc == comps[ncind]) {ncind = (ncind+1)%Ncc; ncSet = PETSC_TRUE;} 5892ba322698SMatthew G. Knepley if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; fcSet = PETSC_TRUE;} 5893ba322698SMatthew G. Knepley if (ncSet && fcSet) {fuse(&a[b], values[clperm[foffset+ b ]] * (flip ? flip[ b ] : 1.));} 5894ba322698SMatthew G. Knepley } 5895a5e93ea8SMatthew G. Knepley } else { 589697e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 589797e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) { 589897e99dd9SToby Isaac fuse(&a[b], values[clperm[foffset+ b ]] * (flip ? flip[ b ] : 1.)); 589997e99dd9SToby Isaac ++cind; 590097e99dd9SToby Isaac } 590197e99dd9SToby Isaac } 590297e99dd9SToby Isaac } 5903ba322698SMatthew G. Knepley } 590497e99dd9SToby Isaac } else { 590597e99dd9SToby Isaac if (perm) { 5906ba322698SMatthew G. Knepley if (comps) { 5907ba322698SMatthew G. Knepley for (b = 0; b < fdof; b++) { 5908ba322698SMatthew G. Knepley ncSet = fcSet = PETSC_FALSE; 59095da9d227SMatthew G. Knepley if (b%Nc == comps[ncind]) {ncind = (ncind+1)%Ncc; ncSet = PETSC_TRUE;} 5910ba322698SMatthew G. Knepley if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; fcSet = PETSC_TRUE;} 5911ba322698SMatthew G. Knepley if (ncSet && fcSet) {fuse(&a[b], values[foffset+perm[b]] * (flip ? flip[perm[b]] : 1.));} 5912ba322698SMatthew G. Knepley } 5913ba322698SMatthew G. Knepley } else { 591497e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 591597e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) { 591697e99dd9SToby Isaac fuse(&a[b], values[foffset+perm[b]] * (flip ? flip[perm[b]] : 1.)); 591797e99dd9SToby Isaac ++cind; 591897e99dd9SToby Isaac } 591997e99dd9SToby Isaac } 5920ba322698SMatthew G. Knepley } 5921ba322698SMatthew G. Knepley } else { 5922ba322698SMatthew G. Knepley if (comps) { 5923ba322698SMatthew G. Knepley for (b = 0; b < fdof; b++) { 5924ba322698SMatthew G. Knepley ncSet = fcSet = PETSC_FALSE; 59255da9d227SMatthew G. Knepley if (b%Nc == comps[ncind]) {ncind = (ncind+1)%Ncc; ncSet = PETSC_TRUE;} 5926ba322698SMatthew G. Knepley if ((cind < fcdof) && (b == fcdofs[cind])) {++cind; fcSet = PETSC_TRUE;} 5927ba322698SMatthew G. Knepley if (ncSet && fcSet) {fuse(&a[b], values[foffset+ b ] * (flip ? flip[ b ] : 1.));} 5928ba322698SMatthew G. Knepley } 592997e99dd9SToby Isaac } else { 593097e99dd9SToby Isaac for (b = 0; b < fdof; b++) { 593197e99dd9SToby Isaac if ((cind < fcdof) && (b == fcdofs[cind])) { 593297e99dd9SToby Isaac fuse(&a[b], values[foffset+ b ] * (flip ? flip[ b ] : 1.)); 5933a5e93ea8SMatthew G. Knepley ++cind; 5934a5e93ea8SMatthew G. Knepley } 5935a5e93ea8SMatthew G. Knepley } 5936a5e93ea8SMatthew G. Knepley } 5937a5e93ea8SMatthew G. Knepley } 5938a5e93ea8SMatthew G. Knepley } 5939ba322698SMatthew G. Knepley } 59401a271a75SMatthew G. Knepley *offset += fdof; 5941a5e93ea8SMatthew G. Knepley PetscFunctionReturn(0); 5942a5e93ea8SMatthew G. Knepley } 5943a5e93ea8SMatthew G. Knepley 59448f3be42fSMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode DMPlexVecSetClosure_Depth1_Static(DM dm, PetscSection section, Vec v, PetscInt point, const PetscScalar values[], InsertMode mode) 5945a6dfd86eSKarl Rupp { 5946552f7358SJed Brown PetscScalar *array; 59471b406b76SMatthew G. Knepley const PetscInt *cone, *coneO; 59481b406b76SMatthew G. Knepley PetscInt pStart, pEnd, p, numPoints, off, dof; 5949552f7358SJed Brown PetscErrorCode ierr; 5950552f7358SJed Brown 59511b406b76SMatthew G. Knepley PetscFunctionBeginHot; 5952b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetChart(section, &pStart, &pEnd);CHKERRQ(ierr); 5953b6ebb6e6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, point, &numPoints);CHKERRQ(ierr); 5954b6ebb6e6SMatthew G. Knepley ierr = DMPlexGetCone(dm, point, &cone);CHKERRQ(ierr); 5955b6ebb6e6SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, point, &coneO);CHKERRQ(ierr); 5956b6ebb6e6SMatthew G. Knepley ierr = VecGetArray(v, &array);CHKERRQ(ierr); 5957b6ebb6e6SMatthew G. Knepley for (p = 0, off = 0; p <= numPoints; ++p, off += dof) { 5958b6ebb6e6SMatthew G. Knepley const PetscInt cp = !p ? point : cone[p-1]; 5959b6ebb6e6SMatthew G. Knepley const PetscInt o = !p ? 0 : coneO[p-1]; 5960b6ebb6e6SMatthew G. Knepley 5961b6ebb6e6SMatthew G. Knepley if ((cp < pStart) || (cp >= pEnd)) {dof = 0; continue;} 5962b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetDof(section, cp, &dof);CHKERRQ(ierr); 5963b6ebb6e6SMatthew G. Knepley /* ADD_VALUES */ 5964b6ebb6e6SMatthew G. Knepley { 5965b6ebb6e6SMatthew G. Knepley const PetscInt *cdofs; /* The indices of the constrained dofs on this point */ 5966b6ebb6e6SMatthew G. Knepley PetscScalar *a; 5967b6ebb6e6SMatthew G. Knepley PetscInt cdof, coff, cind = 0, k; 5968b6ebb6e6SMatthew G. Knepley 5969b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetConstraintDof(section, cp, &cdof);CHKERRQ(ierr); 5970b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetOffset(section, cp, &coff);CHKERRQ(ierr); 5971b6ebb6e6SMatthew G. Knepley a = &array[coff]; 5972b6ebb6e6SMatthew G. Knepley if (!cdof) { 5973b6ebb6e6SMatthew G. Knepley if (o >= 0) { 5974b6ebb6e6SMatthew G. Knepley for (k = 0; k < dof; ++k) { 5975b6ebb6e6SMatthew G. Knepley a[k] += values[off+k]; 5976b6ebb6e6SMatthew G. Knepley } 5977b6ebb6e6SMatthew G. Knepley } else { 5978b6ebb6e6SMatthew G. Knepley for (k = 0; k < dof; ++k) { 5979b6ebb6e6SMatthew G. Knepley a[k] += values[off+dof-k-1]; 5980b6ebb6e6SMatthew G. Knepley } 5981b6ebb6e6SMatthew G. Knepley } 5982b6ebb6e6SMatthew G. Knepley } else { 5983b6ebb6e6SMatthew G. Knepley ierr = PetscSectionGetConstraintIndices(section, cp, &cdofs);CHKERRQ(ierr); 5984b6ebb6e6SMatthew G. Knepley if (o >= 0) { 5985b6ebb6e6SMatthew G. Knepley for (k = 0; k < dof; ++k) { 5986b6ebb6e6SMatthew G. Knepley if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 5987b6ebb6e6SMatthew G. Knepley a[k] += values[off+k]; 5988b6ebb6e6SMatthew G. Knepley } 5989b6ebb6e6SMatthew G. Knepley } else { 5990b6ebb6e6SMatthew G. Knepley for (k = 0; k < dof; ++k) { 5991b6ebb6e6SMatthew G. Knepley if ((cind < cdof) && (k == cdofs[cind])) {++cind; continue;} 5992b6ebb6e6SMatthew G. Knepley a[k] += values[off+dof-k-1]; 5993b6ebb6e6SMatthew G. Knepley } 5994b6ebb6e6SMatthew G. Knepley } 5995b6ebb6e6SMatthew G. Knepley } 5996b6ebb6e6SMatthew G. Knepley } 5997b6ebb6e6SMatthew G. Knepley } 5998b6ebb6e6SMatthew G. Knepley ierr = VecRestoreArray(v, &array);CHKERRQ(ierr); 5999b6ebb6e6SMatthew G. Knepley PetscFunctionReturn(0); 6000b6ebb6e6SMatthew G. Knepley } 60011b406b76SMatthew G. Knepley 60021b406b76SMatthew G. Knepley /*@C 60031b406b76SMatthew G. Knepley DMPlexVecSetClosure - Set an array of the values on the closure of 'point' 60041b406b76SMatthew G. Knepley 60051b406b76SMatthew G. Knepley Not collective 60061b406b76SMatthew G. Knepley 60071b406b76SMatthew G. Knepley Input Parameters: 60081b406b76SMatthew G. Knepley + dm - The DM 60091b406b76SMatthew G. Knepley . section - The section describing the layout in v, or NULL to use the default section 60101b406b76SMatthew G. Knepley . v - The local vector 6011eaf898f9SPatrick Sanan . point - The point in the DM 60121b406b76SMatthew G. Knepley . values - The array of values 601322c1ee49SMatthew 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, 601422c1ee49SMatthew G. Knepley where INSERT_ALL_VALUES and ADD_ALL_VALUES also overwrite boundary conditions. 60151b406b76SMatthew G. Knepley 60161b406b76SMatthew G. Knepley Fortran Notes: 60171b406b76SMatthew G. Knepley This routine is only available in Fortran 90, and you must include petsc.h90 in your code. 60181b406b76SMatthew G. Knepley 60191b406b76SMatthew G. Knepley Level: intermediate 60201b406b76SMatthew G. Knepley 60211b406b76SMatthew G. Knepley .seealso DMPlexVecGetClosure(), DMPlexMatSetClosure() 60221b406b76SMatthew G. Knepley @*/ 60231b406b76SMatthew G. Knepley PetscErrorCode DMPlexVecSetClosure(DM dm, PetscSection section, Vec v, PetscInt point, const PetscScalar values[], InsertMode mode) 60241b406b76SMatthew G. Knepley { 60251b406b76SMatthew G. Knepley PetscSection clSection; 60261b406b76SMatthew G. Knepley IS clPoints; 60271b406b76SMatthew G. Knepley PetscScalar *array; 60281b406b76SMatthew G. Knepley PetscInt *points = NULL; 602927f02ce8SMatthew G. Knepley const PetscInt *clp, *clperm = NULL; 6030c459fbc1SJed Brown PetscInt depth, numFields, numPoints, p, clsize; 60311b406b76SMatthew G. Knepley PetscErrorCode ierr; 60321b406b76SMatthew G. Knepley 60331a271a75SMatthew G. Knepley PetscFunctionBeginHot; 60341b406b76SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 603592fd8e1eSJed Brown if (!section) {ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr);} 60361a271a75SMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 60371a271a75SMatthew G. Knepley PetscValidHeaderSpecific(v, VEC_CLASSID, 3); 60381b406b76SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 60391b406b76SMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 60401b406b76SMatthew G. Knepley if (depth == 1 && numFields < 2 && mode == ADD_VALUES) { 60418f3be42fSMatthew G. Knepley ierr = DMPlexVecSetClosure_Depth1_Static(dm, section, v, point, values, mode);CHKERRQ(ierr); 60421b406b76SMatthew G. Knepley PetscFunctionReturn(0); 60431b406b76SMatthew G. Knepley } 60441a271a75SMatthew G. Knepley /* Get points */ 6045923c78e0SToby Isaac ierr = DMPlexGetCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 6046c459fbc1SJed Brown for (clsize=0,p=0; p<numPoints; p++) { 6047c459fbc1SJed Brown PetscInt dof; 6048c459fbc1SJed Brown ierr = PetscSectionGetDof(section, points[2*p], &dof);CHKERRQ(ierr); 6049c459fbc1SJed Brown clsize += dof; 6050c459fbc1SJed Brown } 6051c459fbc1SJed Brown ierr = PetscSectionGetClosureInversePermutation_Internal(section, (PetscObject) dm, depth, clsize, &clperm);CHKERRQ(ierr); 60521a271a75SMatthew G. Knepley /* Get array */ 6053552f7358SJed Brown ierr = VecGetArray(v, &array);CHKERRQ(ierr); 60541a271a75SMatthew G. Knepley /* Get values */ 6055ef90cfe2SMatthew G. Knepley if (numFields > 0) { 605697e99dd9SToby Isaac PetscInt offset = 0, f; 6057552f7358SJed Brown for (f = 0; f < numFields; ++f) { 605897e99dd9SToby Isaac const PetscInt **perms = NULL; 605997e99dd9SToby Isaac const PetscScalar **flips = NULL; 606097e99dd9SToby Isaac 606197e99dd9SToby Isaac ierr = PetscSectionGetFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 6062552f7358SJed Brown switch (mode) { 6063552f7358SJed Brown case INSERT_VALUES: 606497e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 606597e99dd9SToby Isaac const PetscInt point = points[2*p]; 606697e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 606797e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 606897e99dd9SToby Isaac updatePointFields_private(section, point, perm, flip, f, insert, PETSC_FALSE, clperm, values, &offset, array); 6069552f7358SJed Brown } break; 6070552f7358SJed Brown case INSERT_ALL_VALUES: 607197e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 607297e99dd9SToby Isaac const PetscInt point = points[2*p]; 607397e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 607497e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 607597e99dd9SToby Isaac updatePointFields_private(section, point, perm, flip, f, insert, PETSC_TRUE, clperm, values, &offset, array); 6076552f7358SJed Brown } break; 6077a5e93ea8SMatthew G. Knepley case INSERT_BC_VALUES: 607897e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 607997e99dd9SToby Isaac const PetscInt point = points[2*p]; 608097e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 608197e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 6082ba322698SMatthew G. Knepley updatePointFieldsBC_private(section, point, perm, flip, f, -1, NULL, insert, clperm, values, &offset, array); 6083a5e93ea8SMatthew G. Knepley } break; 6084552f7358SJed Brown case ADD_VALUES: 608597e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 608697e99dd9SToby Isaac const PetscInt point = points[2*p]; 608797e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 608897e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 608997e99dd9SToby Isaac updatePointFields_private(section, point, perm, flip, f, add, PETSC_FALSE, clperm, values, &offset, array); 6090552f7358SJed Brown } break; 6091552f7358SJed Brown case ADD_ALL_VALUES: 609297e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 609397e99dd9SToby Isaac const PetscInt point = points[2*p]; 609497e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 609597e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 609697e99dd9SToby Isaac updatePointFields_private(section, point, perm, flip, f, add, PETSC_TRUE, clperm, values, &offset, array); 6097552f7358SJed Brown } break; 6098304ab55fSMatthew G. Knepley case ADD_BC_VALUES: 609997e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 610097e99dd9SToby Isaac const PetscInt point = points[2*p]; 610197e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 610297e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 6103ba322698SMatthew G. Knepley updatePointFieldsBC_private(section, point, perm, flip, f, -1, NULL, add, clperm, values, &offset, array); 6104304ab55fSMatthew G. Knepley } break; 6105552f7358SJed Brown default: 6106f347f43bSBarry Smith SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insert mode %d", mode); 6107552f7358SJed Brown } 610897e99dd9SToby Isaac ierr = PetscSectionRestoreFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 61091a271a75SMatthew G. Knepley } 6110552f7358SJed Brown } else { 61111a271a75SMatthew G. Knepley PetscInt dof, off; 611297e99dd9SToby Isaac const PetscInt **perms = NULL; 611397e99dd9SToby Isaac const PetscScalar **flips = NULL; 61141a271a75SMatthew G. Knepley 611597e99dd9SToby Isaac ierr = PetscSectionGetPointSyms(section,numPoints,points,&perms,&flips);CHKERRQ(ierr); 6116552f7358SJed Brown switch (mode) { 6117552f7358SJed Brown case INSERT_VALUES: 611897e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 611997e99dd9SToby Isaac const PetscInt point = points[2*p]; 612097e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 612197e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 612297e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 612397e99dd9SToby Isaac updatePoint_private(section, point, dof, insert, PETSC_FALSE, perm, flip, clperm, values, off, array); 6124552f7358SJed Brown } break; 6125552f7358SJed Brown case INSERT_ALL_VALUES: 612697e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 612797e99dd9SToby Isaac const PetscInt point = points[2*p]; 612897e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 612997e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 613097e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 613197e99dd9SToby Isaac updatePoint_private(section, point, dof, insert, PETSC_TRUE, perm, flip, clperm, values, off, array); 6132552f7358SJed Brown } break; 6133a5e93ea8SMatthew G. Knepley case INSERT_BC_VALUES: 613497e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 613597e99dd9SToby Isaac const PetscInt point = points[2*p]; 613697e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 613797e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 613897e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 613997e99dd9SToby Isaac updatePointBC_private(section, point, dof, insert, perm, flip, clperm, values, off, array); 6140a5e93ea8SMatthew G. Knepley } break; 6141552f7358SJed Brown case ADD_VALUES: 614297e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 614397e99dd9SToby Isaac const PetscInt point = points[2*p]; 614497e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 614597e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 614697e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 614797e99dd9SToby Isaac updatePoint_private(section, point, dof, add, PETSC_FALSE, perm, flip, clperm, values, off, array); 6148552f7358SJed Brown } break; 6149552f7358SJed Brown case ADD_ALL_VALUES: 615097e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 615197e99dd9SToby Isaac const PetscInt point = points[2*p]; 615297e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 615397e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 615497e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 615597e99dd9SToby Isaac updatePoint_private(section, point, dof, add, PETSC_TRUE, perm, flip, clperm, values, off, array); 6156552f7358SJed Brown } break; 6157304ab55fSMatthew G. Knepley case ADD_BC_VALUES: 615897e99dd9SToby Isaac for (p = 0, off = 0; p < numPoints; p++, off += dof) { 615997e99dd9SToby Isaac const PetscInt point = points[2*p]; 616097e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 616197e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 616297e99dd9SToby Isaac ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 616397e99dd9SToby Isaac updatePointBC_private(section, point, dof, add, perm, flip, clperm, values, off, array); 6164304ab55fSMatthew G. Knepley } break; 6165552f7358SJed Brown default: 6166f347f43bSBarry Smith SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insert mode %d", mode); 6167552f7358SJed Brown } 616897e99dd9SToby Isaac ierr = PetscSectionRestorePointSyms(section,numPoints,points,&perms,&flips);CHKERRQ(ierr); 6169552f7358SJed Brown } 61701a271a75SMatthew G. Knepley /* Cleanup points */ 6171923c78e0SToby Isaac ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 61721a271a75SMatthew G. Knepley /* Cleanup array */ 6173552f7358SJed Brown ierr = VecRestoreArray(v, &array);CHKERRQ(ierr); 6174552f7358SJed Brown PetscFunctionReturn(0); 6175552f7358SJed Brown } 6176552f7358SJed Brown 61775f790a90SMatthew G. Knepley /* Check whether the given point is in the label. If not, update the offset to skip this point */ 61785f790a90SMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode CheckPoint_Private(DMLabel label, PetscInt labelId, PetscSection section, PetscInt point, PetscInt f, PetscInt *offset) 61795f790a90SMatthew G. Knepley { 61805f790a90SMatthew G. Knepley PetscFunctionBegin; 61815f790a90SMatthew G. Knepley if (label) { 61825f790a90SMatthew G. Knepley PetscInt val, fdof; 61835f790a90SMatthew G. Knepley PetscErrorCode ierr; 61845f790a90SMatthew G. Knepley 61855f790a90SMatthew G. Knepley /* There is a problem with this: 61865f790a90SMatthew 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 61875f790a90SMatthew 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. 61885f790a90SMatthew G. Knepley Thus I am only going to check val != -1, not val != labelId 61895f790a90SMatthew G. Knepley */ 61905f790a90SMatthew G. Knepley ierr = DMLabelGetValue(label, point, &val);CHKERRQ(ierr); 61915f790a90SMatthew G. Knepley if (val < 0) { 61925f790a90SMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 61935f790a90SMatthew G. Knepley *offset += fdof; 61945f790a90SMatthew G. Knepley PetscFunctionReturn(1); 61955f790a90SMatthew G. Knepley } 61965f790a90SMatthew G. Knepley } 61975f790a90SMatthew G. Knepley PetscFunctionReturn(0); 61985f790a90SMatthew G. Knepley } 61995f790a90SMatthew G. Knepley 620097529cf3SJed Brown /* Unlike DMPlexVecSetClosure(), this uses plex-native closure permutation, not a user-specified permutation such as DMPlexSetClosurePermutationTensor(). */ 62015f790a90SMatthew 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) 6202e07394fbSMatthew G. Knepley { 6203e07394fbSMatthew G. Knepley PetscSection clSection; 6204e07394fbSMatthew G. Knepley IS clPoints; 6205e07394fbSMatthew G. Knepley PetscScalar *array; 6206e07394fbSMatthew G. Knepley PetscInt *points = NULL; 620797529cf3SJed Brown const PetscInt *clp; 6208e07394fbSMatthew G. Knepley PetscInt numFields, numPoints, p; 620997e99dd9SToby Isaac PetscInt offset = 0, f; 6210e07394fbSMatthew G. Knepley PetscErrorCode ierr; 6211e07394fbSMatthew G. Knepley 6212e07394fbSMatthew G. Knepley PetscFunctionBeginHot; 6213e07394fbSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 621492fd8e1eSJed Brown if (!section) {ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr);} 6215e07394fbSMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 6216e07394fbSMatthew G. Knepley PetscValidHeaderSpecific(v, VEC_CLASSID, 3); 6217e07394fbSMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 6218e07394fbSMatthew G. Knepley /* Get points */ 6219923c78e0SToby Isaac ierr = DMPlexGetCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 6220e07394fbSMatthew G. Knepley /* Get array */ 6221e07394fbSMatthew G. Knepley ierr = VecGetArray(v, &array);CHKERRQ(ierr); 6222e07394fbSMatthew G. Knepley /* Get values */ 6223e07394fbSMatthew G. Knepley for (f = 0; f < numFields; ++f) { 622497e99dd9SToby Isaac const PetscInt **perms = NULL; 622597e99dd9SToby Isaac const PetscScalar **flips = NULL; 622697e99dd9SToby Isaac 6227e07394fbSMatthew G. Knepley if (!fieldActive[f]) { 6228e07394fbSMatthew G. Knepley for (p = 0; p < numPoints*2; p += 2) { 6229e07394fbSMatthew G. Knepley PetscInt fdof; 6230e07394fbSMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, points[p], f, &fdof);CHKERRQ(ierr); 6231e07394fbSMatthew G. Knepley offset += fdof; 6232e07394fbSMatthew G. Knepley } 6233e07394fbSMatthew G. Knepley continue; 6234e07394fbSMatthew G. Knepley } 623597e99dd9SToby Isaac ierr = PetscSectionGetFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 6236e07394fbSMatthew G. Knepley switch (mode) { 6237e07394fbSMatthew G. Knepley case INSERT_VALUES: 623897e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 623997e99dd9SToby Isaac const PetscInt point = points[2*p]; 624097e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 624197e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 62425f790a90SMatthew G. Knepley ierr = CheckPoint_Private(label, labelId, section, point, f, &offset); if (ierr) continue; 624397529cf3SJed Brown updatePointFields_private(section, point, perm, flip, f, insert, PETSC_FALSE, NULL, values, &offset, array); 6244e07394fbSMatthew G. Knepley } break; 6245e07394fbSMatthew G. Knepley case INSERT_ALL_VALUES: 624697e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 624797e99dd9SToby Isaac const PetscInt point = points[2*p]; 624897e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 624997e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 62505f790a90SMatthew G. Knepley ierr = CheckPoint_Private(label, labelId, section, point, f, &offset); if (ierr) continue; 625197529cf3SJed Brown updatePointFields_private(section, point, perm, flip, f, insert, PETSC_TRUE, NULL, values, &offset, array); 6252e07394fbSMatthew G. Knepley } break; 6253e07394fbSMatthew G. Knepley case INSERT_BC_VALUES: 625497e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 625597e99dd9SToby Isaac const PetscInt point = points[2*p]; 625697e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 625797e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 62585f790a90SMatthew G. Knepley ierr = CheckPoint_Private(label, labelId, section, point, f, &offset); if (ierr) continue; 625997529cf3SJed Brown updatePointFieldsBC_private(section, point, perm, flip, f, Ncc, comps, insert, NULL, values, &offset, array); 6260e07394fbSMatthew G. Knepley } break; 6261e07394fbSMatthew G. Knepley case ADD_VALUES: 626297e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 626397e99dd9SToby Isaac const PetscInt point = points[2*p]; 626497e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 626597e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 62665f790a90SMatthew G. Knepley ierr = CheckPoint_Private(label, labelId, section, point, f, &offset); if (ierr) continue; 626797529cf3SJed Brown updatePointFields_private(section, point, perm, flip, f, add, PETSC_FALSE, NULL, values, &offset, array); 6268e07394fbSMatthew G. Knepley } break; 6269e07394fbSMatthew G. Knepley case ADD_ALL_VALUES: 627097e99dd9SToby Isaac for (p = 0; p < numPoints; p++) { 627197e99dd9SToby Isaac const PetscInt point = points[2*p]; 627297e99dd9SToby Isaac const PetscInt *perm = perms ? perms[p] : NULL; 627397e99dd9SToby Isaac const PetscScalar *flip = flips ? flips[p] : NULL; 62745f790a90SMatthew G. Knepley ierr = CheckPoint_Private(label, labelId, section, point, f, &offset); if (ierr) continue; 627597529cf3SJed Brown updatePointFields_private(section, point, perm, flip, f, add, PETSC_TRUE, NULL, values, &offset, array); 6276e07394fbSMatthew G. Knepley } break; 6277e07394fbSMatthew G. Knepley default: 6278f347f43bSBarry Smith SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_OUTOFRANGE, "Invalid insert mode %d", mode); 6279e07394fbSMatthew G. Knepley } 628097e99dd9SToby Isaac ierr = PetscSectionRestoreFieldPointSyms(section,f,numPoints,points,&perms,&flips);CHKERRQ(ierr); 6281e07394fbSMatthew G. Knepley } 6282e07394fbSMatthew G. Knepley /* Cleanup points */ 6283923c78e0SToby Isaac ierr = DMPlexRestoreCompressedClosure(dm,section,point,&numPoints,&points,&clSection,&clPoints,&clp);CHKERRQ(ierr); 6284e07394fbSMatthew G. Knepley /* Cleanup array */ 6285e07394fbSMatthew G. Knepley ierr = VecRestoreArray(v, &array);CHKERRQ(ierr); 6286e07394fbSMatthew G. Knepley PetscFunctionReturn(0); 6287e07394fbSMatthew G. Knepley } 6288e07394fbSMatthew G. Knepley 62897cd05799SMatthew G. Knepley static PetscErrorCode DMPlexPrintMatSetValues(PetscViewer viewer, Mat A, PetscInt point, PetscInt numRIndices, const PetscInt rindices[], PetscInt numCIndices, const PetscInt cindices[], const PetscScalar values[]) 6290552f7358SJed Brown { 6291552f7358SJed Brown PetscMPIInt rank; 6292552f7358SJed Brown PetscInt i, j; 6293552f7358SJed Brown PetscErrorCode ierr; 6294552f7358SJed Brown 6295552f7358SJed Brown PetscFunctionBegin; 6296ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)A), &rank);CHKERRMPI(ierr); 6297eaf898f9SPatrick Sanan ierr = PetscViewerASCIIPrintf(viewer, "[%d]mat for point %D\n", rank, point);CHKERRQ(ierr); 6298e4b003c7SBarry Smith for (i = 0; i < numRIndices; i++) {ierr = PetscViewerASCIIPrintf(viewer, "[%d]mat row indices[%D] = %D\n", rank, i, rindices[i]);CHKERRQ(ierr);} 6299e4b003c7SBarry Smith for (i = 0; i < numCIndices; i++) {ierr = PetscViewerASCIIPrintf(viewer, "[%d]mat col indices[%D] = %D\n", rank, i, cindices[i]);CHKERRQ(ierr);} 6300b0ecff45SMatthew G. Knepley numCIndices = numCIndices ? numCIndices : numRIndices; 6301557cf195SMatthew G. Knepley if (!values) PetscFunctionReturn(0); 6302b0ecff45SMatthew G. Knepley for (i = 0; i < numRIndices; i++) { 6303e4b003c7SBarry Smith ierr = PetscViewerASCIIPrintf(viewer, "[%d]", rank);CHKERRQ(ierr); 6304b0ecff45SMatthew G. Knepley for (j = 0; j < numCIndices; j++) { 6305519f805aSKarl Rupp #if defined(PETSC_USE_COMPLEX) 63067eba1a17SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " (%g,%g)", (double)PetscRealPart(values[i*numCIndices+j]), (double)PetscImaginaryPart(values[i*numCIndices+j]));CHKERRQ(ierr); 6307552f7358SJed Brown #else 6308b0ecff45SMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer, " %g", (double)values[i*numCIndices+j]);CHKERRQ(ierr); 6309552f7358SJed Brown #endif 6310552f7358SJed Brown } 631177a6746dSMatthew G Knepley ierr = PetscViewerASCIIPrintf(viewer, "\n");CHKERRQ(ierr); 6312552f7358SJed Brown } 6313552f7358SJed Brown PetscFunctionReturn(0); 6314552f7358SJed Brown } 6315552f7358SJed Brown 631605586334SMatthew G. Knepley /* 631705586334SMatthew G. Knepley DMPlexGetIndicesPoint_Internal - Add the indices for dofs on a point to an index array 631805586334SMatthew G. Knepley 631905586334SMatthew G. Knepley Input Parameters: 632005586334SMatthew G. Knepley + section - The section for this data layout 632136fa2b79SJed Brown . islocal - Is the section (and thus indices being requested) local or global? 632205586334SMatthew G. Knepley . point - The point contributing dofs with these indices 632305586334SMatthew G. Knepley . off - The global offset of this point 632405586334SMatthew G. Knepley . loff - The local offset of each field 632505586334SMatthew G. Knepley . setBC - The flag determining whether to include indices of bounsary values 632605586334SMatthew G. Knepley . perm - A permutation of the dofs on this point, or NULL 632705586334SMatthew G. Knepley - indperm - A permutation of the entire indices array, or NULL 632805586334SMatthew G. Knepley 632905586334SMatthew G. Knepley Output Parameter: 633005586334SMatthew G. Knepley . indices - Indices for dofs on this point 633105586334SMatthew G. Knepley 633205586334SMatthew G. Knepley Level: developer 633305586334SMatthew G. Knepley 633405586334SMatthew G. Knepley Note: The indices could be local or global, depending on the value of 'off'. 633505586334SMatthew G. Knepley */ 633636fa2b79SJed Brown PetscErrorCode DMPlexGetIndicesPoint_Internal(PetscSection section, PetscBool islocal,PetscInt point, PetscInt off, PetscInt *loff, PetscBool setBC, const PetscInt perm[], const PetscInt indperm[], PetscInt indices[]) 6337a6dfd86eSKarl Rupp { 6338e6ccafaeSMatthew G Knepley PetscInt dof; /* The number of unknowns on this point */ 6339552f7358SJed Brown PetscInt cdof; /* The number of constraints on this point */ 6340552f7358SJed Brown const PetscInt *cdofs; /* The indices of the constrained dofs on this point */ 6341552f7358SJed Brown PetscInt cind = 0, k; 6342552f7358SJed Brown PetscErrorCode ierr; 6343552f7358SJed Brown 6344552f7358SJed Brown PetscFunctionBegin; 634536fa2b79SJed Brown if (!islocal && setBC) SETERRQ(PetscObjectComm((PetscObject)section),PETSC_ERR_ARG_INCOMP,"setBC incompatible with global indices; use a local section or disable setBC"); 6346552f7358SJed Brown ierr = PetscSectionGetDof(section, point, &dof);CHKERRQ(ierr); 6347552f7358SJed Brown ierr = PetscSectionGetConstraintDof(section, point, &cdof);CHKERRQ(ierr); 6348552f7358SJed Brown if (!cdof || setBC) { 634905586334SMatthew G. Knepley for (k = 0; k < dof; ++k) { 635005586334SMatthew G. Knepley const PetscInt preind = perm ? *loff+perm[k] : *loff+k; 635105586334SMatthew G. Knepley const PetscInt ind = indperm ? indperm[preind] : preind; 635205586334SMatthew G. Knepley 635305586334SMatthew G. Knepley indices[ind] = off + k; 6354552f7358SJed Brown } 6355552f7358SJed Brown } else { 6356552f7358SJed Brown ierr = PetscSectionGetConstraintIndices(section, point, &cdofs);CHKERRQ(ierr); 63574acb8e1eSToby Isaac for (k = 0; k < dof; ++k) { 635805586334SMatthew G. Knepley const PetscInt preind = perm ? *loff+perm[k] : *loff+k; 635905586334SMatthew G. Knepley const PetscInt ind = indperm ? indperm[preind] : preind; 636005586334SMatthew G. Knepley 63614acb8e1eSToby Isaac if ((cind < cdof) && (k == cdofs[cind])) { 63624acb8e1eSToby Isaac /* Insert check for returning constrained indices */ 636305586334SMatthew G. Knepley indices[ind] = -(off+k+1); 63644acb8e1eSToby Isaac ++cind; 63654acb8e1eSToby Isaac } else { 636636fa2b79SJed Brown indices[ind] = off + k - (islocal ? 0 : cind); 6367552f7358SJed Brown } 6368552f7358SJed Brown } 6369552f7358SJed Brown } 6370e6ccafaeSMatthew G Knepley *loff += dof; 6371552f7358SJed Brown PetscFunctionReturn(0); 6372552f7358SJed Brown } 6373552f7358SJed Brown 63747e29afd2SMatthew G. Knepley /* 637536fa2b79SJed Brown DMPlexGetIndicesPointFields_Internal - gets section indices for a point in its canonical ordering. 63767e29afd2SMatthew G. Knepley 637736fa2b79SJed Brown Input Parameters: 637836fa2b79SJed Brown + section - a section (global or local) 637936fa2b79SJed Brown - islocal - PETSC_TRUE if requesting local indices (i.e., section is local); PETSC_FALSE for global 638036fa2b79SJed Brown . point - point within section 638136fa2b79SJed Brown . off - The offset of this point in the (local or global) indexed space - should match islocal and (usually) the section 638236fa2b79SJed Brown . foffs - array of length numFields containing the offset in canonical point ordering (the location in indices) of each field 638336fa2b79SJed Brown . setBC - identify constrained (boundary condition) points via involution. 638436fa2b79SJed Brown . perms - perms[f][permsoff][:] is a permutation of dofs within each field 638536fa2b79SJed Brown . permsoff - offset 638636fa2b79SJed Brown - indperm - index permutation 638736fa2b79SJed Brown 638836fa2b79SJed Brown Output Parameter: 638936fa2b79SJed Brown . foffs - each entry is incremented by the number of (unconstrained if setBC=FALSE) dofs in that field 639036fa2b79SJed Brown . indices - array to hold indices (as defined by section) of each dof associated with point 639136fa2b79SJed Brown 639236fa2b79SJed Brown Notes: 639336fa2b79SJed Brown If section is local and setBC=true, there is no distinction between constrained and unconstrained dofs. 639436fa2b79SJed Brown If section is local and setBC=false, the indices for constrained points are the involution -(i+1) of their position 639536fa2b79SJed Brown in the local vector. 639636fa2b79SJed Brown 639736fa2b79SJed Brown If section is global and setBC=false, the indices for constrained points are negative (and their value is not 639836fa2b79SJed Brown significant). It is invalid to call with a global section and setBC=true. 639936fa2b79SJed Brown 640036fa2b79SJed Brown Developer Note: 640136fa2b79SJed Brown The section is only used for field layout, so islocal is technically a statement about the offset (off). At some point 640236fa2b79SJed Brown in the future, global sections may have fields set, in which case we could pass the global section and obtain the 640336fa2b79SJed Brown offset could be obtained from the section instead of passing it explicitly as we do now. 640436fa2b79SJed Brown 640536fa2b79SJed Brown Example: 640636fa2b79SJed Brown Suppose a point contains one field with three components, and for which the unconstrained indices are {10, 11, 12}. 640736fa2b79SJed Brown When the middle component is constrained, we get the array {10, -12, 12} for (islocal=TRUE, setBC=FALSE). 640836fa2b79SJed Brown Note that -12 is the involution of 11, so the user can involute negative indices to recover local indices. 640936fa2b79SJed 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. 641036fa2b79SJed Brown 641136fa2b79SJed Brown Level: developer 64127e29afd2SMatthew G. Knepley */ 641336fa2b79SJed 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[]) 6414a6dfd86eSKarl Rupp { 6415552f7358SJed Brown PetscInt numFields, foff, f; 6416552f7358SJed Brown PetscErrorCode ierr; 6417552f7358SJed Brown 6418552f7358SJed Brown PetscFunctionBegin; 641936fa2b79SJed Brown if (!islocal && setBC) SETERRQ(PetscObjectComm((PetscObject)section),PETSC_ERR_ARG_INCOMP,"setBC incompatible with global indices; use a local section or disable setBC"); 6420552f7358SJed Brown ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 6421552f7358SJed Brown for (f = 0, foff = 0; f < numFields; ++f) { 64224acb8e1eSToby Isaac PetscInt fdof, cfdof; 6423552f7358SJed Brown const PetscInt *fcdofs; /* The indices of the constrained dofs for field f on this point */ 64244acb8e1eSToby Isaac PetscInt cind = 0, b; 64254acb8e1eSToby Isaac const PetscInt *perm = (perms && perms[f]) ? perms[f][permsoff] : NULL; 6426552f7358SJed Brown 6427552f7358SJed Brown ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 6428552f7358SJed Brown ierr = PetscSectionGetFieldConstraintDof(section, point, f, &cfdof);CHKERRQ(ierr); 6429552f7358SJed Brown if (!cfdof || setBC) { 643005586334SMatthew G. Knepley for (b = 0; b < fdof; ++b) { 643105586334SMatthew G. Knepley const PetscInt preind = perm ? foffs[f]+perm[b] : foffs[f]+b; 643205586334SMatthew G. Knepley const PetscInt ind = indperm ? indperm[preind] : preind; 643305586334SMatthew G. Knepley 643405586334SMatthew G. Knepley indices[ind] = off+foff+b; 643505586334SMatthew G. Knepley } 6436552f7358SJed Brown } else { 6437552f7358SJed Brown ierr = PetscSectionGetFieldConstraintIndices(section, point, f, &fcdofs);CHKERRQ(ierr); 643805586334SMatthew G. Knepley for (b = 0; b < fdof; ++b) { 643905586334SMatthew G. Knepley const PetscInt preind = perm ? foffs[f]+perm[b] : foffs[f]+b; 644005586334SMatthew G. Knepley const PetscInt ind = indperm ? indperm[preind] : preind; 644105586334SMatthew G. Knepley 64424acb8e1eSToby Isaac if ((cind < cfdof) && (b == fcdofs[cind])) { 644305586334SMatthew G. Knepley indices[ind] = -(off+foff+b+1); 6444552f7358SJed Brown ++cind; 6445552f7358SJed Brown } else { 644636fa2b79SJed Brown indices[ind] = off + foff + b - (islocal ? 0 : cind); 6447552f7358SJed Brown } 6448552f7358SJed Brown } 6449552f7358SJed Brown } 645036fa2b79SJed Brown foff += (setBC || islocal ? fdof : (fdof - cfdof)); 6451552f7358SJed Brown foffs[f] += fdof; 6452552f7358SJed Brown } 6453552f7358SJed Brown PetscFunctionReturn(0); 6454552f7358SJed Brown } 6455552f7358SJed Brown 64567e29afd2SMatthew G. Knepley /* 64577e29afd2SMatthew G. Knepley This version believes the globalSection offsets for each field, rather than just the point offset 64587e29afd2SMatthew G. Knepley 64597e29afd2SMatthew G. Knepley . foffs - The offset into 'indices' for each field, since it is segregated by field 6460645102dcSJed Brown 6461645102dcSJed Brown Notes: 6462645102dcSJed Brown The semantics of this function relate to that of setBC=FALSE in DMPlexGetIndicesPointFields_Internal. 6463645102dcSJed Brown Since this function uses global indices, setBC=TRUE would be invalid, so no such argument exists. 64647e29afd2SMatthew G. Knepley */ 6465645102dcSJed Brown static PetscErrorCode DMPlexGetIndicesPointFieldsSplit_Internal(PetscSection section, PetscSection globalSection, PetscInt point, PetscInt foffs[], const PetscInt ***perms, PetscInt permsoff, const PetscInt indperm[], PetscInt indices[]) 64667e29afd2SMatthew G. Knepley { 64677e29afd2SMatthew G. Knepley PetscInt numFields, foff, f; 64687e29afd2SMatthew G. Knepley PetscErrorCode ierr; 64697e29afd2SMatthew G. Knepley 64707e29afd2SMatthew G. Knepley PetscFunctionBegin; 64717e29afd2SMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 64727e29afd2SMatthew G. Knepley for (f = 0; f < numFields; ++f) { 64737e29afd2SMatthew G. Knepley PetscInt fdof, cfdof; 64747e29afd2SMatthew G. Knepley const PetscInt *fcdofs; /* The indices of the constrained dofs for field f on this point */ 64757e29afd2SMatthew G. Knepley PetscInt cind = 0, b; 64767e29afd2SMatthew G. Knepley const PetscInt *perm = (perms && perms[f]) ? perms[f][permsoff] : NULL; 64777e29afd2SMatthew G. Knepley 64787e29afd2SMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, point, f, &fdof);CHKERRQ(ierr); 64797e29afd2SMatthew G. Knepley ierr = PetscSectionGetFieldConstraintDof(section, point, f, &cfdof);CHKERRQ(ierr); 64807e29afd2SMatthew G. Knepley ierr = PetscSectionGetFieldOffset(globalSection, point, f, &foff);CHKERRQ(ierr); 6481645102dcSJed Brown if (!cfdof) { 648205586334SMatthew G. Knepley for (b = 0; b < fdof; ++b) { 648305586334SMatthew G. Knepley const PetscInt preind = perm ? foffs[f]+perm[b] : foffs[f]+b; 648405586334SMatthew G. Knepley const PetscInt ind = indperm ? indperm[preind] : preind; 648505586334SMatthew G. Knepley 648605586334SMatthew G. Knepley indices[ind] = foff+b; 648705586334SMatthew G. Knepley } 64887e29afd2SMatthew G. Knepley } else { 64897e29afd2SMatthew G. Knepley ierr = PetscSectionGetFieldConstraintIndices(section, point, f, &fcdofs);CHKERRQ(ierr); 649005586334SMatthew G. Knepley for (b = 0; b < fdof; ++b) { 649105586334SMatthew G. Knepley const PetscInt preind = perm ? foffs[f]+perm[b] : foffs[f]+b; 649205586334SMatthew G. Knepley const PetscInt ind = indperm ? indperm[preind] : preind; 649305586334SMatthew G. Knepley 64947e29afd2SMatthew G. Knepley if ((cind < cfdof) && (b == fcdofs[cind])) { 649505586334SMatthew G. Knepley indices[ind] = -(foff+b+1); 64967e29afd2SMatthew G. Knepley ++cind; 64977e29afd2SMatthew G. Knepley } else { 649805586334SMatthew G. Knepley indices[ind] = foff+b-cind; 64997e29afd2SMatthew G. Knepley } 65007e29afd2SMatthew G. Knepley } 65017e29afd2SMatthew G. Knepley } 65027e29afd2SMatthew G. Knepley foffs[f] += fdof; 65037e29afd2SMatthew G. Knepley } 65047e29afd2SMatthew G. Knepley PetscFunctionReturn(0); 65057e29afd2SMatthew G. Knepley } 65067e29afd2SMatthew G. Knepley 65074acb8e1eSToby 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) 6508d3d1a6afSToby Isaac { 6509d3d1a6afSToby Isaac Mat cMat; 6510d3d1a6afSToby Isaac PetscSection aSec, cSec; 6511d3d1a6afSToby Isaac IS aIS; 6512d3d1a6afSToby Isaac PetscInt aStart = -1, aEnd = -1; 6513d3d1a6afSToby Isaac const PetscInt *anchors; 6514e17c06e0SMatthew G. Knepley PetscInt numFields, f, p, q, newP = 0; 6515d3d1a6afSToby Isaac PetscInt newNumPoints = 0, newNumIndices = 0; 6516d3d1a6afSToby Isaac PetscInt *newPoints, *indices, *newIndices; 6517d3d1a6afSToby Isaac PetscInt maxAnchor, maxDof; 6518d3d1a6afSToby Isaac PetscInt newOffsets[32]; 6519d3d1a6afSToby Isaac PetscInt *pointMatOffsets[32]; 6520d3d1a6afSToby Isaac PetscInt *newPointOffsets[32]; 6521d3d1a6afSToby Isaac PetscScalar *pointMat[32]; 65226ecaa68aSToby Isaac PetscScalar *newValues=NULL,*tmpValues; 6523d3d1a6afSToby Isaac PetscBool anyConstrained = PETSC_FALSE; 6524d3d1a6afSToby Isaac PetscErrorCode ierr; 6525d3d1a6afSToby Isaac 6526d3d1a6afSToby Isaac PetscFunctionBegin; 6527d3d1a6afSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6528d3d1a6afSToby Isaac PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 6529d3d1a6afSToby Isaac ierr = PetscSectionGetNumFields(section, &numFields);CHKERRQ(ierr); 6530d3d1a6afSToby Isaac 6531a17985deSToby Isaac ierr = DMPlexGetAnchors(dm,&aSec,&aIS);CHKERRQ(ierr); 6532d3d1a6afSToby Isaac /* if there are point-to-point constraints */ 6533d3d1a6afSToby Isaac if (aSec) { 6534580bdb30SBarry Smith ierr = PetscArrayzero(newOffsets, 32);CHKERRQ(ierr); 6535d3d1a6afSToby Isaac ierr = ISGetIndices(aIS,&anchors);CHKERRQ(ierr); 6536d3d1a6afSToby Isaac ierr = PetscSectionGetChart(aSec,&aStart,&aEnd);CHKERRQ(ierr); 6537d3d1a6afSToby Isaac /* figure out how many points are going to be in the new element matrix 6538d3d1a6afSToby Isaac * (we allow double counting, because it's all just going to be summed 6539d3d1a6afSToby Isaac * into the global matrix anyway) */ 6540d3d1a6afSToby Isaac for (p = 0; p < 2*numPoints; p+=2) { 6541d3d1a6afSToby Isaac PetscInt b = points[p]; 65424b2f2278SToby Isaac PetscInt bDof = 0, bSecDof; 6543d3d1a6afSToby Isaac 65444b2f2278SToby Isaac ierr = PetscSectionGetDof(section,b,&bSecDof);CHKERRQ(ierr); 65454b2f2278SToby Isaac if (!bSecDof) { 65464b2f2278SToby Isaac continue; 65474b2f2278SToby Isaac } 6548d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 6549d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec,b,&bDof);CHKERRQ(ierr); 6550d3d1a6afSToby Isaac } 6551d3d1a6afSToby Isaac if (bDof) { 6552d3d1a6afSToby Isaac /* this point is constrained */ 6553d3d1a6afSToby Isaac /* it is going to be replaced by its anchors */ 6554d3d1a6afSToby Isaac PetscInt bOff, q; 6555d3d1a6afSToby Isaac 6556d3d1a6afSToby Isaac anyConstrained = PETSC_TRUE; 6557d3d1a6afSToby Isaac newNumPoints += bDof; 6558d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(aSec,b,&bOff);CHKERRQ(ierr); 6559d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 6560d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q]; 6561d3d1a6afSToby Isaac PetscInt aDof; 6562d3d1a6afSToby Isaac 6563d3d1a6afSToby Isaac ierr = PetscSectionGetDof(section,a,&aDof);CHKERRQ(ierr); 6564d3d1a6afSToby Isaac newNumIndices += aDof; 6565d3d1a6afSToby Isaac for (f = 0; f < numFields; ++f) { 6566d3d1a6afSToby Isaac PetscInt fDof; 6567d3d1a6afSToby Isaac 6568d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, a, f, &fDof);CHKERRQ(ierr); 6569d3d1a6afSToby Isaac newOffsets[f+1] += fDof; 6570d3d1a6afSToby Isaac } 6571d3d1a6afSToby Isaac } 6572d3d1a6afSToby Isaac } 6573d3d1a6afSToby Isaac else { 6574d3d1a6afSToby Isaac /* this point is not constrained */ 6575d3d1a6afSToby Isaac newNumPoints++; 65764b2f2278SToby Isaac newNumIndices += bSecDof; 6577d3d1a6afSToby Isaac for (f = 0; f < numFields; ++f) { 6578d3d1a6afSToby Isaac PetscInt fDof; 6579d3d1a6afSToby Isaac 6580d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, b, f, &fDof);CHKERRQ(ierr); 6581d3d1a6afSToby Isaac newOffsets[f+1] += fDof; 6582d3d1a6afSToby Isaac } 6583d3d1a6afSToby Isaac } 6584d3d1a6afSToby Isaac } 6585d3d1a6afSToby Isaac } 6586d3d1a6afSToby Isaac if (!anyConstrained) { 658772b80496SMatthew G. Knepley if (outNumPoints) *outNumPoints = 0; 658872b80496SMatthew G. Knepley if (outNumIndices) *outNumIndices = 0; 658972b80496SMatthew G. Knepley if (outPoints) *outPoints = NULL; 659072b80496SMatthew G. Knepley if (outValues) *outValues = NULL; 659172b80496SMatthew G. Knepley if (aSec) {ierr = ISRestoreIndices(aIS,&anchors);CHKERRQ(ierr);} 6592d3d1a6afSToby Isaac PetscFunctionReturn(0); 6593d3d1a6afSToby Isaac } 6594d3d1a6afSToby Isaac 65956ecaa68aSToby Isaac if (outNumPoints) *outNumPoints = newNumPoints; 65966ecaa68aSToby Isaac if (outNumIndices) *outNumIndices = newNumIndices; 65976ecaa68aSToby Isaac 6598f13f9184SToby Isaac for (f = 0; f < numFields; ++f) newOffsets[f+1] += newOffsets[f]; 6599d3d1a6afSToby Isaac 66006ecaa68aSToby Isaac if (!outPoints && !outValues) { 66016ecaa68aSToby Isaac if (offsets) { 66026ecaa68aSToby Isaac for (f = 0; f <= numFields; f++) { 66036ecaa68aSToby Isaac offsets[f] = newOffsets[f]; 66046ecaa68aSToby Isaac } 66056ecaa68aSToby Isaac } 66066ecaa68aSToby Isaac if (aSec) {ierr = ISRestoreIndices(aIS,&anchors);CHKERRQ(ierr);} 66076ecaa68aSToby Isaac PetscFunctionReturn(0); 66086ecaa68aSToby Isaac } 66096ecaa68aSToby Isaac 6610f347f43bSBarry Smith if (numFields && newOffsets[numFields] != newNumIndices) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", newOffsets[numFields], newNumIndices); 6611d3d1a6afSToby Isaac 6612f7c74593SToby Isaac ierr = DMGetDefaultConstraints(dm, &cSec, &cMat);CHKERRQ(ierr); 6613d3d1a6afSToby Isaac 6614d3d1a6afSToby Isaac /* workspaces */ 6615d3d1a6afSToby Isaac if (numFields) { 6616d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 661769291d52SBarry Smith ierr = DMGetWorkArray(dm,numPoints+1,MPIU_INT,&pointMatOffsets[f]);CHKERRQ(ierr); 661869291d52SBarry Smith ierr = DMGetWorkArray(dm,numPoints+1,MPIU_INT,&newPointOffsets[f]);CHKERRQ(ierr); 6619d3d1a6afSToby Isaac } 6620d3d1a6afSToby Isaac } 6621d3d1a6afSToby Isaac else { 662269291d52SBarry Smith ierr = DMGetWorkArray(dm,numPoints+1,MPIU_INT,&pointMatOffsets[0]);CHKERRQ(ierr); 662369291d52SBarry Smith ierr = DMGetWorkArray(dm,numPoints,MPIU_INT,&newPointOffsets[0]);CHKERRQ(ierr); 6624d3d1a6afSToby Isaac } 6625d3d1a6afSToby Isaac 6626d3d1a6afSToby Isaac /* get workspaces for the point-to-point matrices */ 6627d3d1a6afSToby Isaac if (numFields) { 66284b2f2278SToby Isaac PetscInt totalOffset, totalMatOffset; 66294b2f2278SToby Isaac 6630d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 6631d3d1a6afSToby Isaac PetscInt b = points[2*p]; 66324b2f2278SToby Isaac PetscInt bDof = 0, bSecDof; 6633d3d1a6afSToby Isaac 66344b2f2278SToby Isaac ierr = PetscSectionGetDof(section,b,&bSecDof);CHKERRQ(ierr); 66354b2f2278SToby Isaac if (!bSecDof) { 66364b2f2278SToby Isaac for (f = 0; f < numFields; f++) { 66374b2f2278SToby Isaac newPointOffsets[f][p + 1] = 0; 66384b2f2278SToby Isaac pointMatOffsets[f][p + 1] = 0; 66394b2f2278SToby Isaac } 66404b2f2278SToby Isaac continue; 66414b2f2278SToby Isaac } 6642d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 6643d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec, b, &bDof);CHKERRQ(ierr); 6644d3d1a6afSToby Isaac } 6645d3d1a6afSToby Isaac if (bDof) { 6646d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 6647d3d1a6afSToby Isaac PetscInt fDof, q, bOff, allFDof = 0; 6648d3d1a6afSToby Isaac 6649d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, b, f, &fDof);CHKERRQ(ierr); 6650d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(aSec, b, &bOff);CHKERRQ(ierr); 6651d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 6652d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q]; 6653d3d1a6afSToby Isaac PetscInt aFDof; 6654d3d1a6afSToby Isaac 6655d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, a, f, &aFDof);CHKERRQ(ierr); 6656d3d1a6afSToby Isaac allFDof += aFDof; 6657d3d1a6afSToby Isaac } 6658d3d1a6afSToby Isaac newPointOffsets[f][p+1] = allFDof; 6659d3d1a6afSToby Isaac pointMatOffsets[f][p+1] = fDof * allFDof; 6660d3d1a6afSToby Isaac } 6661d3d1a6afSToby Isaac } 6662d3d1a6afSToby Isaac else { 6663d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 6664d3d1a6afSToby Isaac PetscInt fDof; 6665d3d1a6afSToby Isaac 6666d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section, b, f, &fDof);CHKERRQ(ierr); 6667d3d1a6afSToby Isaac newPointOffsets[f][p+1] = fDof; 6668d3d1a6afSToby Isaac pointMatOffsets[f][p+1] = 0; 6669d3d1a6afSToby Isaac } 6670d3d1a6afSToby Isaac } 6671d3d1a6afSToby Isaac } 66724b2f2278SToby Isaac for (f = 0, totalOffset = 0, totalMatOffset = 0; f < numFields; f++) { 66734b2f2278SToby Isaac newPointOffsets[f][0] = totalOffset; 66744b2f2278SToby Isaac pointMatOffsets[f][0] = totalMatOffset; 6675d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 6676d3d1a6afSToby Isaac newPointOffsets[f][p+1] += newPointOffsets[f][p]; 6677d3d1a6afSToby Isaac pointMatOffsets[f][p+1] += pointMatOffsets[f][p]; 6678d3d1a6afSToby Isaac } 667919f70fd5SToby Isaac totalOffset = newPointOffsets[f][numPoints]; 668019f70fd5SToby Isaac totalMatOffset = pointMatOffsets[f][numPoints]; 668169291d52SBarry Smith ierr = DMGetWorkArray(dm,pointMatOffsets[f][numPoints],MPIU_SCALAR,&pointMat[f]);CHKERRQ(ierr); 6682d3d1a6afSToby Isaac } 6683d3d1a6afSToby Isaac } 6684d3d1a6afSToby Isaac else { 6685d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 6686d3d1a6afSToby Isaac PetscInt b = points[2*p]; 66874b2f2278SToby Isaac PetscInt bDof = 0, bSecDof; 6688d3d1a6afSToby Isaac 66894b2f2278SToby Isaac ierr = PetscSectionGetDof(section,b,&bSecDof);CHKERRQ(ierr); 66904b2f2278SToby Isaac if (!bSecDof) { 66914b2f2278SToby Isaac newPointOffsets[0][p + 1] = 0; 66924b2f2278SToby Isaac pointMatOffsets[0][p + 1] = 0; 66934b2f2278SToby Isaac continue; 66944b2f2278SToby Isaac } 6695d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 6696d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec, b, &bDof);CHKERRQ(ierr); 6697d3d1a6afSToby Isaac } 6698d3d1a6afSToby Isaac if (bDof) { 66994b2f2278SToby Isaac PetscInt bOff, q, allDof = 0; 6700d3d1a6afSToby Isaac 6701d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(aSec, b, &bOff);CHKERRQ(ierr); 6702d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 6703d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q], aDof; 6704d3d1a6afSToby Isaac 6705d3d1a6afSToby Isaac ierr = PetscSectionGetDof(section, a, &aDof);CHKERRQ(ierr); 6706d3d1a6afSToby Isaac allDof += aDof; 6707d3d1a6afSToby Isaac } 6708d3d1a6afSToby Isaac newPointOffsets[0][p+1] = allDof; 67094b2f2278SToby Isaac pointMatOffsets[0][p+1] = bSecDof * allDof; 6710d3d1a6afSToby Isaac } 6711d3d1a6afSToby Isaac else { 67124b2f2278SToby Isaac newPointOffsets[0][p+1] = bSecDof; 6713d3d1a6afSToby Isaac pointMatOffsets[0][p+1] = 0; 6714d3d1a6afSToby Isaac } 6715d3d1a6afSToby Isaac } 6716d3d1a6afSToby Isaac newPointOffsets[0][0] = 0; 6717d3d1a6afSToby Isaac pointMatOffsets[0][0] = 0; 6718d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 6719d3d1a6afSToby Isaac newPointOffsets[0][p+1] += newPointOffsets[0][p]; 6720d3d1a6afSToby Isaac pointMatOffsets[0][p+1] += pointMatOffsets[0][p]; 6721d3d1a6afSToby Isaac } 672269291d52SBarry Smith ierr = DMGetWorkArray(dm,pointMatOffsets[0][numPoints],MPIU_SCALAR,&pointMat[0]);CHKERRQ(ierr); 6723d3d1a6afSToby Isaac } 6724d3d1a6afSToby Isaac 67256ecaa68aSToby Isaac /* output arrays */ 672669291d52SBarry Smith ierr = DMGetWorkArray(dm,2*newNumPoints,MPIU_INT,&newPoints);CHKERRQ(ierr); 67276ecaa68aSToby Isaac 6728d3d1a6afSToby Isaac /* get the point-to-point matrices; construct newPoints */ 6729d3d1a6afSToby Isaac ierr = PetscSectionGetMaxDof(aSec, &maxAnchor);CHKERRQ(ierr); 6730d3d1a6afSToby Isaac ierr = PetscSectionGetMaxDof(section, &maxDof);CHKERRQ(ierr); 673169291d52SBarry Smith ierr = DMGetWorkArray(dm,maxDof,MPIU_INT,&indices);CHKERRQ(ierr); 673269291d52SBarry Smith ierr = DMGetWorkArray(dm,maxAnchor*maxDof,MPIU_INT,&newIndices);CHKERRQ(ierr); 6733d3d1a6afSToby Isaac if (numFields) { 6734d3d1a6afSToby Isaac for (p = 0, newP = 0; p < numPoints; p++) { 6735d3d1a6afSToby Isaac PetscInt b = points[2*p]; 6736d3d1a6afSToby Isaac PetscInt o = points[2*p+1]; 67374b2f2278SToby Isaac PetscInt bDof = 0, bSecDof; 6738d3d1a6afSToby Isaac 67394b2f2278SToby Isaac ierr = PetscSectionGetDof(section, b, &bSecDof);CHKERRQ(ierr); 67404b2f2278SToby Isaac if (!bSecDof) { 67414b2f2278SToby Isaac continue; 67424b2f2278SToby Isaac } 6743d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 6744d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec, b, &bDof);CHKERRQ(ierr); 6745d3d1a6afSToby Isaac } 6746d3d1a6afSToby Isaac if (bDof) { 6747d3d1a6afSToby Isaac PetscInt fStart[32], fEnd[32], fAnchorStart[32], fAnchorEnd[32], bOff, q; 6748d3d1a6afSToby Isaac 6749d3d1a6afSToby Isaac fStart[0] = 0; 6750d3d1a6afSToby Isaac fEnd[0] = 0; 6751d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 6752d3d1a6afSToby Isaac PetscInt fDof; 6753d3d1a6afSToby Isaac 6754d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(cSec, b, f, &fDof);CHKERRQ(ierr); 6755d3d1a6afSToby Isaac fStart[f+1] = fStart[f] + fDof; 6756d3d1a6afSToby Isaac fEnd[f+1] = fStart[f+1]; 6757d3d1a6afSToby Isaac } 6758d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(cSec, b, &bOff);CHKERRQ(ierr); 675936fa2b79SJed Brown ierr = DMPlexGetIndicesPointFields_Internal(cSec, PETSC_TRUE, b, bOff, fEnd, PETSC_TRUE, perms, p, NULL, indices);CHKERRQ(ierr); 6760d3d1a6afSToby Isaac 6761d3d1a6afSToby Isaac fAnchorStart[0] = 0; 6762d3d1a6afSToby Isaac fAnchorEnd[0] = 0; 6763d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 6764d3d1a6afSToby Isaac PetscInt fDof = newPointOffsets[f][p + 1] - newPointOffsets[f][p]; 6765d3d1a6afSToby Isaac 6766d3d1a6afSToby Isaac fAnchorStart[f+1] = fAnchorStart[f] + fDof; 6767d3d1a6afSToby Isaac fAnchorEnd[f+1] = fAnchorStart[f + 1]; 6768d3d1a6afSToby Isaac } 6769d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(aSec, b, &bOff);CHKERRQ(ierr); 6770d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 6771d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q], aOff; 6772d3d1a6afSToby Isaac 6773d3d1a6afSToby 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 */ 6774d3d1a6afSToby Isaac newPoints[2*(newP + q)] = a; 6775d3d1a6afSToby Isaac newPoints[2*(newP + q) + 1] = 0; 6776302440fdSBarry Smith ierr = PetscSectionGetOffset(section, a, &aOff);CHKERRQ(ierr); 677736fa2b79SJed Brown ierr = DMPlexGetIndicesPointFields_Internal(section, PETSC_TRUE, a, aOff, fAnchorEnd, PETSC_TRUE, NULL, -1, NULL, newIndices);CHKERRQ(ierr); 6778d3d1a6afSToby Isaac } 6779d3d1a6afSToby Isaac newP += bDof; 6780d3d1a6afSToby Isaac 67816ecaa68aSToby Isaac if (outValues) { 6782d3d1a6afSToby Isaac /* get the point-to-point submatrix */ 6783d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 6784d3d1a6afSToby 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); 6785d3d1a6afSToby Isaac } 6786d3d1a6afSToby Isaac } 67876ecaa68aSToby Isaac } 6788d3d1a6afSToby Isaac else { 6789d3d1a6afSToby Isaac newPoints[2 * newP] = b; 6790d3d1a6afSToby Isaac newPoints[2 * newP + 1] = o; 6791d3d1a6afSToby Isaac newP++; 6792d3d1a6afSToby Isaac } 6793d3d1a6afSToby Isaac } 6794d3d1a6afSToby Isaac } else { 6795d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 6796d3d1a6afSToby Isaac PetscInt b = points[2*p]; 6797d3d1a6afSToby Isaac PetscInt o = points[2*p+1]; 67984b2f2278SToby Isaac PetscInt bDof = 0, bSecDof; 6799d3d1a6afSToby Isaac 68004b2f2278SToby Isaac ierr = PetscSectionGetDof(section, b, &bSecDof);CHKERRQ(ierr); 68014b2f2278SToby Isaac if (!bSecDof) { 68024b2f2278SToby Isaac continue; 68034b2f2278SToby Isaac } 6804d3d1a6afSToby Isaac if (b >= aStart && b < aEnd) { 6805d3d1a6afSToby Isaac ierr = PetscSectionGetDof(aSec, b, &bDof);CHKERRQ(ierr); 6806d3d1a6afSToby Isaac } 6807d3d1a6afSToby Isaac if (bDof) { 6808d3d1a6afSToby Isaac PetscInt bEnd = 0, bAnchorEnd = 0, bOff; 6809d3d1a6afSToby Isaac 6810d3d1a6afSToby Isaac ierr = PetscSectionGetOffset(cSec, b, &bOff);CHKERRQ(ierr); 681136fa2b79SJed Brown ierr = DMPlexGetIndicesPoint_Internal(cSec, PETSC_TRUE, b, bOff, &bEnd, PETSC_TRUE, (perms && perms[0]) ? perms[0][p] : NULL, NULL, indices);CHKERRQ(ierr); 6812d3d1a6afSToby Isaac 6813d3d1a6afSToby Isaac ierr = PetscSectionGetOffset (aSec, b, &bOff);CHKERRQ(ierr); 6814d3d1a6afSToby Isaac for (q = 0; q < bDof; q++) { 6815d3d1a6afSToby Isaac PetscInt a = anchors[bOff + q], aOff; 6816d3d1a6afSToby Isaac 6817d3d1a6afSToby 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 */ 6818d3d1a6afSToby Isaac 6819d3d1a6afSToby Isaac newPoints[2*(newP + q)] = a; 6820d3d1a6afSToby Isaac newPoints[2*(newP + q) + 1] = 0; 6821302440fdSBarry Smith ierr = PetscSectionGetOffset(section, a, &aOff);CHKERRQ(ierr); 682236fa2b79SJed Brown ierr = DMPlexGetIndicesPoint_Internal(section, PETSC_TRUE, a, aOff, &bAnchorEnd, PETSC_TRUE, NULL, NULL, newIndices);CHKERRQ(ierr); 6823d3d1a6afSToby Isaac } 6824d3d1a6afSToby Isaac newP += bDof; 6825d3d1a6afSToby Isaac 6826d3d1a6afSToby Isaac /* get the point-to-point submatrix */ 68276ecaa68aSToby Isaac if (outValues) { 6828d3d1a6afSToby Isaac ierr = MatGetValues(cMat,bEnd,indices,bAnchorEnd,newIndices,pointMat[0] + pointMatOffsets[0][p]);CHKERRQ(ierr); 6829d3d1a6afSToby Isaac } 68306ecaa68aSToby Isaac } 6831d3d1a6afSToby Isaac else { 6832d3d1a6afSToby Isaac newPoints[2 * newP] = b; 6833d3d1a6afSToby Isaac newPoints[2 * newP + 1] = o; 6834d3d1a6afSToby Isaac newP++; 6835d3d1a6afSToby Isaac } 6836d3d1a6afSToby Isaac } 6837d3d1a6afSToby Isaac } 6838d3d1a6afSToby Isaac 68396ecaa68aSToby Isaac if (outValues) { 684069291d52SBarry Smith ierr = DMGetWorkArray(dm,newNumIndices*numIndices,MPIU_SCALAR,&tmpValues);CHKERRQ(ierr); 6841580bdb30SBarry Smith ierr = PetscArrayzero(tmpValues,newNumIndices*numIndices);CHKERRQ(ierr); 6842d3d1a6afSToby Isaac /* multiply constraints on the right */ 6843d3d1a6afSToby Isaac if (numFields) { 6844d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 6845d3d1a6afSToby Isaac PetscInt oldOff = offsets[f]; 6846d3d1a6afSToby Isaac 6847d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 6848d3d1a6afSToby Isaac PetscInt cStart = newPointOffsets[f][p]; 6849d3d1a6afSToby Isaac PetscInt b = points[2 * p]; 6850d3d1a6afSToby Isaac PetscInt c, r, k; 6851d3d1a6afSToby Isaac PetscInt dof; 6852d3d1a6afSToby Isaac 6853d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section,b,f,&dof);CHKERRQ(ierr); 68544b2f2278SToby Isaac if (!dof) { 68554b2f2278SToby Isaac continue; 68564b2f2278SToby Isaac } 6857d3d1a6afSToby Isaac if (pointMatOffsets[f][p] < pointMatOffsets[f][p + 1]) { 6858d3d1a6afSToby Isaac PetscInt nCols = newPointOffsets[f][p+1]-cStart; 6859d3d1a6afSToby Isaac const PetscScalar *mat = pointMat[f] + pointMatOffsets[f][p]; 6860d3d1a6afSToby Isaac 6861d3d1a6afSToby Isaac for (r = 0; r < numIndices; r++) { 6862d3d1a6afSToby Isaac for (c = 0; c < nCols; c++) { 6863d3d1a6afSToby Isaac for (k = 0; k < dof; k++) { 68644acb8e1eSToby Isaac tmpValues[r * newNumIndices + cStart + c] += values[r * numIndices + oldOff + k] * mat[k * nCols + c]; 6865d3d1a6afSToby Isaac } 6866d3d1a6afSToby Isaac } 6867d3d1a6afSToby Isaac } 6868d3d1a6afSToby Isaac } 6869d3d1a6afSToby Isaac else { 6870d3d1a6afSToby Isaac /* copy this column as is */ 6871d3d1a6afSToby Isaac for (r = 0; r < numIndices; r++) { 6872d3d1a6afSToby Isaac for (c = 0; c < dof; c++) { 6873d3d1a6afSToby Isaac tmpValues[r * newNumIndices + cStart + c] = values[r * numIndices + oldOff + c]; 6874d3d1a6afSToby Isaac } 6875d3d1a6afSToby Isaac } 6876d3d1a6afSToby Isaac } 6877d3d1a6afSToby Isaac oldOff += dof; 6878d3d1a6afSToby Isaac } 6879d3d1a6afSToby Isaac } 6880d3d1a6afSToby Isaac } 6881d3d1a6afSToby Isaac else { 6882d3d1a6afSToby Isaac PetscInt oldOff = 0; 6883d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 6884d3d1a6afSToby Isaac PetscInt cStart = newPointOffsets[0][p]; 6885d3d1a6afSToby Isaac PetscInt b = points[2 * p]; 6886d3d1a6afSToby Isaac PetscInt c, r, k; 6887d3d1a6afSToby Isaac PetscInt dof; 6888d3d1a6afSToby Isaac 6889d3d1a6afSToby Isaac ierr = PetscSectionGetDof(section,b,&dof);CHKERRQ(ierr); 68904b2f2278SToby Isaac if (!dof) { 68914b2f2278SToby Isaac continue; 68924b2f2278SToby Isaac } 6893d3d1a6afSToby Isaac if (pointMatOffsets[0][p] < pointMatOffsets[0][p + 1]) { 6894d3d1a6afSToby Isaac PetscInt nCols = newPointOffsets[0][p+1]-cStart; 6895d3d1a6afSToby Isaac const PetscScalar *mat = pointMat[0] + pointMatOffsets[0][p]; 6896d3d1a6afSToby Isaac 6897d3d1a6afSToby Isaac for (r = 0; r < numIndices; r++) { 6898d3d1a6afSToby Isaac for (c = 0; c < nCols; c++) { 6899d3d1a6afSToby Isaac for (k = 0; k < dof; k++) { 6900d3d1a6afSToby Isaac tmpValues[r * newNumIndices + cStart + c] += mat[k * nCols + c] * values[r * numIndices + oldOff + k]; 6901d3d1a6afSToby Isaac } 6902d3d1a6afSToby Isaac } 6903d3d1a6afSToby Isaac } 6904d3d1a6afSToby Isaac } 6905d3d1a6afSToby Isaac else { 6906d3d1a6afSToby Isaac /* copy this column as is */ 6907d3d1a6afSToby Isaac for (r = 0; r < numIndices; r++) { 6908d3d1a6afSToby Isaac for (c = 0; c < dof; c++) { 6909d3d1a6afSToby Isaac tmpValues[r * newNumIndices + cStart + c] = values[r * numIndices + oldOff + c]; 6910d3d1a6afSToby Isaac } 6911d3d1a6afSToby Isaac } 6912d3d1a6afSToby Isaac } 6913d3d1a6afSToby Isaac oldOff += dof; 6914d3d1a6afSToby Isaac } 6915d3d1a6afSToby Isaac } 6916d3d1a6afSToby Isaac 69176ecaa68aSToby Isaac if (multiplyLeft) { 691869291d52SBarry Smith ierr = DMGetWorkArray(dm,newNumIndices*newNumIndices,MPIU_SCALAR,&newValues);CHKERRQ(ierr); 6919580bdb30SBarry Smith ierr = PetscArrayzero(newValues,newNumIndices*newNumIndices);CHKERRQ(ierr); 6920d3d1a6afSToby Isaac /* multiply constraints transpose on the left */ 6921d3d1a6afSToby Isaac if (numFields) { 6922d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 6923d3d1a6afSToby Isaac PetscInt oldOff = offsets[f]; 6924d3d1a6afSToby Isaac 6925d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 6926d3d1a6afSToby Isaac PetscInt rStart = newPointOffsets[f][p]; 6927d3d1a6afSToby Isaac PetscInt b = points[2 * p]; 6928d3d1a6afSToby Isaac PetscInt c, r, k; 6929d3d1a6afSToby Isaac PetscInt dof; 6930d3d1a6afSToby Isaac 6931d3d1a6afSToby Isaac ierr = PetscSectionGetFieldDof(section,b,f,&dof);CHKERRQ(ierr); 6932d3d1a6afSToby Isaac if (pointMatOffsets[f][p] < pointMatOffsets[f][p + 1]) { 6933d3d1a6afSToby Isaac PetscInt nRows = newPointOffsets[f][p+1]-rStart; 6934d3d1a6afSToby Isaac const PetscScalar *PETSC_RESTRICT mat = pointMat[f] + pointMatOffsets[f][p]; 6935d3d1a6afSToby Isaac 6936d3d1a6afSToby Isaac for (r = 0; r < nRows; r++) { 6937d3d1a6afSToby Isaac for (c = 0; c < newNumIndices; c++) { 6938d3d1a6afSToby Isaac for (k = 0; k < dof; k++) { 6939d3d1a6afSToby Isaac newValues[(rStart + r) * newNumIndices + c] += mat[k * nRows + r] * tmpValues[(oldOff + k) * newNumIndices + c]; 6940d3d1a6afSToby Isaac } 6941d3d1a6afSToby Isaac } 6942d3d1a6afSToby Isaac } 6943d3d1a6afSToby Isaac } 6944d3d1a6afSToby Isaac else { 6945d3d1a6afSToby Isaac /* copy this row as is */ 6946d3d1a6afSToby Isaac for (r = 0; r < dof; r++) { 6947d3d1a6afSToby Isaac for (c = 0; c < newNumIndices; c++) { 6948d3d1a6afSToby Isaac newValues[(rStart + r) * newNumIndices + c] = tmpValues[(oldOff + r) * newNumIndices + c]; 6949d3d1a6afSToby Isaac } 6950d3d1a6afSToby Isaac } 6951d3d1a6afSToby Isaac } 6952d3d1a6afSToby Isaac oldOff += dof; 6953d3d1a6afSToby Isaac } 6954d3d1a6afSToby Isaac } 6955d3d1a6afSToby Isaac } 6956d3d1a6afSToby Isaac else { 6957d3d1a6afSToby Isaac PetscInt oldOff = 0; 6958d3d1a6afSToby Isaac 6959d3d1a6afSToby Isaac for (p = 0; p < numPoints; p++) { 6960d3d1a6afSToby Isaac PetscInt rStart = newPointOffsets[0][p]; 6961d3d1a6afSToby Isaac PetscInt b = points[2 * p]; 6962d3d1a6afSToby Isaac PetscInt c, r, k; 6963d3d1a6afSToby Isaac PetscInt dof; 6964d3d1a6afSToby Isaac 6965d3d1a6afSToby Isaac ierr = PetscSectionGetDof(section,b,&dof);CHKERRQ(ierr); 6966d3d1a6afSToby Isaac if (pointMatOffsets[0][p] < pointMatOffsets[0][p + 1]) { 6967d3d1a6afSToby Isaac PetscInt nRows = newPointOffsets[0][p+1]-rStart; 6968d3d1a6afSToby Isaac const PetscScalar *PETSC_RESTRICT mat = pointMat[0] + pointMatOffsets[0][p]; 6969d3d1a6afSToby Isaac 6970d3d1a6afSToby Isaac for (r = 0; r < nRows; r++) { 6971d3d1a6afSToby Isaac for (c = 0; c < newNumIndices; c++) { 6972d3d1a6afSToby Isaac for (k = 0; k < dof; k++) { 6973d3d1a6afSToby Isaac newValues[(rStart + r) * newNumIndices + c] += mat[k * nRows + r] * tmpValues[(oldOff + k) * newNumIndices + c]; 6974d3d1a6afSToby Isaac } 6975d3d1a6afSToby Isaac } 6976d3d1a6afSToby Isaac } 6977d3d1a6afSToby Isaac } 6978d3d1a6afSToby Isaac else { 6979d3d1a6afSToby Isaac /* copy this row as is */ 69809fc93327SToby Isaac for (r = 0; r < dof; r++) { 6981d3d1a6afSToby Isaac for (c = 0; c < newNumIndices; c++) { 6982d3d1a6afSToby Isaac newValues[(rStart + r) * newNumIndices + c] = tmpValues[(oldOff + r) * newNumIndices + c]; 6983d3d1a6afSToby Isaac } 6984d3d1a6afSToby Isaac } 6985d3d1a6afSToby Isaac } 6986d3d1a6afSToby Isaac oldOff += dof; 6987d3d1a6afSToby Isaac } 6988d3d1a6afSToby Isaac } 6989d3d1a6afSToby Isaac 699069291d52SBarry Smith ierr = DMRestoreWorkArray(dm,newNumIndices*numIndices,MPIU_SCALAR,&tmpValues);CHKERRQ(ierr); 69916ecaa68aSToby Isaac } 69926ecaa68aSToby Isaac else { 69936ecaa68aSToby Isaac newValues = tmpValues; 69946ecaa68aSToby Isaac } 69956ecaa68aSToby Isaac } 69966ecaa68aSToby Isaac 6997d3d1a6afSToby Isaac /* clean up */ 699869291d52SBarry Smith ierr = DMRestoreWorkArray(dm,maxDof,MPIU_INT,&indices);CHKERRQ(ierr); 699969291d52SBarry Smith ierr = DMRestoreWorkArray(dm,maxAnchor*maxDof,MPIU_INT,&newIndices);CHKERRQ(ierr); 70006ecaa68aSToby Isaac 7001d3d1a6afSToby Isaac if (numFields) { 7002d3d1a6afSToby Isaac for (f = 0; f < numFields; f++) { 700369291d52SBarry Smith ierr = DMRestoreWorkArray(dm,pointMatOffsets[f][numPoints],MPIU_SCALAR,&pointMat[f]);CHKERRQ(ierr); 700469291d52SBarry Smith ierr = DMRestoreWorkArray(dm,numPoints+1,MPIU_INT,&pointMatOffsets[f]);CHKERRQ(ierr); 700569291d52SBarry Smith ierr = DMRestoreWorkArray(dm,numPoints+1,MPIU_INT,&newPointOffsets[f]);CHKERRQ(ierr); 7006d3d1a6afSToby Isaac } 7007d3d1a6afSToby Isaac } 7008d3d1a6afSToby Isaac else { 700969291d52SBarry Smith ierr = DMRestoreWorkArray(dm,pointMatOffsets[0][numPoints],MPIU_SCALAR,&pointMat[0]);CHKERRQ(ierr); 701069291d52SBarry Smith ierr = DMRestoreWorkArray(dm,numPoints+1,MPIU_INT,&pointMatOffsets[0]);CHKERRQ(ierr); 701169291d52SBarry Smith ierr = DMRestoreWorkArray(dm,numPoints+1,MPIU_INT,&newPointOffsets[0]);CHKERRQ(ierr); 7012d3d1a6afSToby Isaac } 7013d3d1a6afSToby Isaac ierr = ISRestoreIndices(aIS,&anchors);CHKERRQ(ierr); 7014d3d1a6afSToby Isaac 7015d3d1a6afSToby Isaac /* output */ 70166ecaa68aSToby Isaac if (outPoints) { 7017d3d1a6afSToby Isaac *outPoints = newPoints; 70186ecaa68aSToby Isaac } 70196ecaa68aSToby Isaac else { 702069291d52SBarry Smith ierr = DMRestoreWorkArray(dm,2*newNumPoints,MPIU_INT,&newPoints);CHKERRQ(ierr); 70216ecaa68aSToby Isaac } 702231620726SToby Isaac if (outValues) { 7023d3d1a6afSToby Isaac *outValues = newValues; 70246ecaa68aSToby Isaac } 70256ecaa68aSToby Isaac for (f = 0; f <= numFields; f++) { 7026d3d1a6afSToby Isaac offsets[f] = newOffsets[f]; 7027d3d1a6afSToby Isaac } 7028d3d1a6afSToby Isaac PetscFunctionReturn(0); 7029d3d1a6afSToby Isaac } 7030d3d1a6afSToby Isaac 70314a1e0b3eSMatthew G. Knepley /*@C 703271f0bbf9SMatthew G. Knepley DMPlexGetClosureIndices - Gets the global dof indices associated with the closure of the given point within the provided sections. 70337cd05799SMatthew G. Knepley 70347cd05799SMatthew G. Knepley Not collective 70357cd05799SMatthew G. Knepley 70367cd05799SMatthew G. Knepley Input Parameters: 70377cd05799SMatthew G. Knepley + dm - The DM 703871f0bbf9SMatthew G. Knepley . section - The PetscSection describing the points (a local section) 703971f0bbf9SMatthew G. Knepley . idxSection - The PetscSection from which to obtain indices (may be local or global) 704071f0bbf9SMatthew G. Knepley . point - The point defining the closure 704171f0bbf9SMatthew G. Knepley - useClPerm - Use the closure point permutation if available 70427cd05799SMatthew G. Knepley 704371f0bbf9SMatthew G. Knepley Output Parameters: 704471f0bbf9SMatthew G. Knepley + numIndices - The number of dof indices in the closure of point with the input sections 704571f0bbf9SMatthew G. Knepley . indices - The dof indices 704671f0bbf9SMatthew G. Knepley . outOffsets - Array to write the field offsets into, or NULL 704771f0bbf9SMatthew G. Knepley - values - The input values, which may be modified if sign flips are induced by the point symmetries, or NULL 70487cd05799SMatthew G. Knepley 704936fa2b79SJed Brown Notes: 705036fa2b79SJed Brown Must call DMPlexRestoreClosureIndices() to free allocated memory 705136fa2b79SJed Brown 705236fa2b79SJed Brown If idxSection is global, any constrained dofs (see DMAddBoundary(), for example) will get negative indices. The value 705336fa2b79SJed Brown of those indices is not significant. If idxSection is local, the constrained dofs will yield the involution -(idx+1) 705436fa2b79SJed Brown of their index in a local vector. A caller who does not wish to distinguish those points may recover the nonnegative 705536fa2b79SJed Brown indices via involution, -(-(idx+1)+1)==idx. Local indices are provided when idxSection == section, otherwise global 705636fa2b79SJed Brown indices (with the above semantics) are implied. 70577cd05799SMatthew G. Knepley 70587cd05799SMatthew G. Knepley Level: advanced 70597cd05799SMatthew G. Knepley 706036fa2b79SJed Brown .seealso DMPlexRestoreClosureIndices(), DMPlexVecGetClosure(), DMPlexMatSetClosure(), DMGetLocalSection(), DMGetGlobalSection() 70614a1e0b3eSMatthew G. Knepley @*/ 706271f0bbf9SMatthew G. Knepley PetscErrorCode DMPlexGetClosureIndices(DM dm, PetscSection section, PetscSection idxSection, PetscInt point, PetscBool useClPerm, 706371f0bbf9SMatthew G. Knepley PetscInt *numIndices, PetscInt *indices[], PetscInt outOffsets[], PetscScalar *values[]) 70647773e69fSMatthew G. Knepley { 706571f0bbf9SMatthew G. Knepley /* Closure ordering */ 70667773e69fSMatthew G. Knepley PetscSection clSection; 70677773e69fSMatthew G. Knepley IS clPoints; 706871f0bbf9SMatthew G. Knepley const PetscInt *clp; 706971f0bbf9SMatthew G. Knepley PetscInt *points; 707071f0bbf9SMatthew G. Knepley const PetscInt *clperm = NULL; 707171f0bbf9SMatthew G. Knepley /* Dof permutation and sign flips */ 70724acb8e1eSToby Isaac const PetscInt **perms[32] = {NULL}; 707371f0bbf9SMatthew G. Knepley const PetscScalar **flips[32] = {NULL}; 707471f0bbf9SMatthew G. Knepley PetscScalar *valCopy = NULL; 707571f0bbf9SMatthew G. Knepley /* Hanging node constraints */ 707671f0bbf9SMatthew G. Knepley PetscInt *pointsC = NULL; 707771f0bbf9SMatthew G. Knepley PetscScalar *valuesC = NULL; 707871f0bbf9SMatthew G. Knepley PetscInt NclC, NiC; 707971f0bbf9SMatthew G. Knepley 708071f0bbf9SMatthew G. Knepley PetscInt *idx; 708171f0bbf9SMatthew G. Knepley PetscInt Nf, Ncl, Ni = 0, offsets[32], p, f; 708271f0bbf9SMatthew G. Knepley PetscBool isLocal = (section == idxSection) ? PETSC_TRUE : PETSC_FALSE; 70837773e69fSMatthew G. Knepley PetscErrorCode ierr; 70847773e69fSMatthew G. Knepley 708571f0bbf9SMatthew G. Knepley PetscFunctionBeginHot; 70867773e69fSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 70877773e69fSMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 708836fa2b79SJed Brown PetscValidHeaderSpecific(idxSection, PETSC_SECTION_CLASSID, 3); 708971f0bbf9SMatthew G. Knepley if (numIndices) PetscValidPointer(numIndices, 6); 709071f0bbf9SMatthew G. Knepley if (indices) PetscValidPointer(indices, 7); 709171f0bbf9SMatthew G. Knepley if (outOffsets) PetscValidPointer(outOffsets, 8); 709271f0bbf9SMatthew G. Knepley if (values) PetscValidPointer(values, 9); 70937773e69fSMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &Nf);CHKERRQ(ierr); 70947773e69fSMatthew G. Knepley if (Nf > 31) SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Number of fields %D limited to 31", Nf); 7095580bdb30SBarry Smith ierr = PetscArrayzero(offsets, 32);CHKERRQ(ierr); 709671f0bbf9SMatthew G. Knepley /* 1) Get points in closure */ 709771f0bbf9SMatthew G. Knepley ierr = DMPlexGetCompressedClosure(dm, section, point, &Ncl, &points, &clSection, &clPoints, &clp);CHKERRQ(ierr); 7098c459fbc1SJed Brown if (useClPerm) { 7099c459fbc1SJed Brown PetscInt depth, clsize; 7100c459fbc1SJed Brown ierr = DMPlexGetPointDepth(dm, point, &depth);CHKERRQ(ierr); 7101c459fbc1SJed Brown for (clsize=0,p=0; p<Ncl; p++) { 7102c459fbc1SJed Brown PetscInt dof; 7103c459fbc1SJed Brown ierr = PetscSectionGetDof(section, points[2*p], &dof);CHKERRQ(ierr); 7104c459fbc1SJed Brown clsize += dof; 7105c459fbc1SJed Brown } 7106c459fbc1SJed Brown ierr = PetscSectionGetClosureInversePermutation_Internal(section, (PetscObject) dm, depth, clsize, &clperm);CHKERRQ(ierr); 7107c459fbc1SJed Brown } 710871f0bbf9SMatthew G. Knepley /* 2) Get number of indices on these points and field offsets from section */ 710971f0bbf9SMatthew G. Knepley for (p = 0; p < Ncl*2; p += 2) { 71107773e69fSMatthew G. Knepley PetscInt dof, fdof; 71117773e69fSMatthew G. Knepley 71127773e69fSMatthew G. Knepley ierr = PetscSectionGetDof(section, points[p], &dof);CHKERRQ(ierr); 71137773e69fSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 71147773e69fSMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, points[p], f, &fdof);CHKERRQ(ierr); 71157773e69fSMatthew G. Knepley offsets[f+1] += fdof; 71167773e69fSMatthew G. Knepley } 711771f0bbf9SMatthew G. Knepley Ni += dof; 71187773e69fSMatthew G. Knepley } 71197773e69fSMatthew G. Knepley for (f = 1; f < Nf; ++f) offsets[f+1] += offsets[f]; 712071f0bbf9SMatthew 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); 712171f0bbf9SMatthew G. Knepley /* 3) Get symmetries and sign flips. Apply sign flips to values if passed in (only works for square values matrix) */ 712271f0bbf9SMatthew G. Knepley for (f = 0; f < PetscMax(1, Nf); ++f) { 712371f0bbf9SMatthew G. Knepley if (Nf) {ierr = PetscSectionGetFieldPointSyms(section, f, Ncl, points, &perms[f], &flips[f]);CHKERRQ(ierr);} 712471f0bbf9SMatthew G. Knepley else {ierr = PetscSectionGetPointSyms(section, Ncl, points, &perms[f], &flips[f]);CHKERRQ(ierr);} 712571f0bbf9SMatthew G. Knepley /* may need to apply sign changes to the element matrix */ 712671f0bbf9SMatthew G. Knepley if (values && flips[f]) { 712771f0bbf9SMatthew G. Knepley PetscInt foffset = offsets[f]; 71286ecaa68aSToby Isaac 712971f0bbf9SMatthew G. Knepley for (p = 0; p < Ncl; ++p) { 713071f0bbf9SMatthew G. Knepley PetscInt pnt = points[2*p], fdof; 713171f0bbf9SMatthew G. Knepley const PetscScalar *flip = flips[f] ? flips[f][p] : NULL; 713271f0bbf9SMatthew G. Knepley 713371f0bbf9SMatthew G. Knepley if (!Nf) {ierr = PetscSectionGetDof(section, pnt, &fdof);CHKERRQ(ierr);} 713471f0bbf9SMatthew G. Knepley else {ierr = PetscSectionGetFieldDof(section, pnt, f, &fdof);CHKERRQ(ierr);} 713571f0bbf9SMatthew G. Knepley if (flip) { 713671f0bbf9SMatthew G. Knepley PetscInt i, j, k; 713771f0bbf9SMatthew G. Knepley 713871f0bbf9SMatthew G. Knepley if (!valCopy) { 713971f0bbf9SMatthew G. Knepley ierr = DMGetWorkArray(dm, Ni*Ni, MPIU_SCALAR, &valCopy);CHKERRQ(ierr); 714071f0bbf9SMatthew G. Knepley for (j = 0; j < Ni * Ni; ++j) valCopy[j] = (*values)[j]; 714171f0bbf9SMatthew G. Knepley *values = valCopy; 714271f0bbf9SMatthew G. Knepley } 714371f0bbf9SMatthew G. Knepley for (i = 0; i < fdof; ++i) { 714471f0bbf9SMatthew G. Knepley PetscScalar fval = flip[i]; 714571f0bbf9SMatthew G. Knepley 714671f0bbf9SMatthew G. Knepley for (k = 0; k < Ni; ++k) { 714771f0bbf9SMatthew G. Knepley valCopy[Ni * (foffset + i) + k] *= fval; 714871f0bbf9SMatthew G. Knepley valCopy[Ni * k + (foffset + i)] *= fval; 71496ecaa68aSToby Isaac } 71506ecaa68aSToby Isaac } 715171f0bbf9SMatthew G. Knepley } 715271f0bbf9SMatthew G. Knepley foffset += fdof; 715371f0bbf9SMatthew G. Knepley } 715471f0bbf9SMatthew G. Knepley } 715571f0bbf9SMatthew G. Knepley } 715671f0bbf9SMatthew G. Knepley /* 4) Apply hanging node constraints. Get new symmetries and replace all storage with constrained storage */ 715771f0bbf9SMatthew G. Knepley ierr = DMPlexAnchorsModifyMat(dm, section, Ncl, Ni, points, perms, values ? *values : NULL, &NclC, &NiC, &pointsC, values ? &valuesC : NULL, offsets, PETSC_TRUE);CHKERRQ(ierr); 715871f0bbf9SMatthew G. Knepley if (NclC) { 715971f0bbf9SMatthew G. Knepley if (valCopy) {ierr = DMRestoreWorkArray(dm, Ni*Ni, MPIU_SCALAR, &valCopy);CHKERRQ(ierr);} 716071f0bbf9SMatthew G. Knepley for (f = 0; f < PetscMax(1, Nf); ++f) { 716171f0bbf9SMatthew G. Knepley if (Nf) {ierr = PetscSectionRestoreFieldPointSyms(section, f, Ncl, points, &perms[f], &flips[f]);CHKERRQ(ierr);} 716271f0bbf9SMatthew G. Knepley else {ierr = PetscSectionRestorePointSyms(section, Ncl, points, &perms[f], &flips[f]);CHKERRQ(ierr);} 716371f0bbf9SMatthew G. Knepley } 716471f0bbf9SMatthew G. Knepley for (f = 0; f < PetscMax(1, Nf); ++f) { 716571f0bbf9SMatthew G. Knepley if (Nf) {ierr = PetscSectionGetFieldPointSyms(section, f, NclC, pointsC, &perms[f], &flips[f]);CHKERRQ(ierr);} 716671f0bbf9SMatthew G. Knepley else {ierr = PetscSectionGetPointSyms(section, NclC, pointsC, &perms[f], &flips[f]);CHKERRQ(ierr);} 716771f0bbf9SMatthew G. Knepley } 716871f0bbf9SMatthew G. Knepley ierr = DMPlexRestoreCompressedClosure(dm, section, point, &Ncl, &points, &clSection, &clPoints, &clp);CHKERRQ(ierr); 716971f0bbf9SMatthew G. Knepley Ncl = NclC; 717071f0bbf9SMatthew G. Knepley Ni = NiC; 717171f0bbf9SMatthew G. Knepley points = pointsC; 717271f0bbf9SMatthew G. Knepley if (values) *values = valuesC; 717371f0bbf9SMatthew G. Knepley } 717471f0bbf9SMatthew G. Knepley /* 5) Calculate indices */ 717571f0bbf9SMatthew G. Knepley ierr = DMGetWorkArray(dm, Ni, MPIU_INT, &idx);CHKERRQ(ierr); 717671f0bbf9SMatthew G. Knepley if (Nf) { 717771f0bbf9SMatthew G. Knepley PetscInt idxOff; 717871f0bbf9SMatthew G. Knepley PetscBool useFieldOffsets; 717971f0bbf9SMatthew G. Knepley 718071f0bbf9SMatthew G. Knepley if (outOffsets) {for (f = 0; f <= Nf; f++) outOffsets[f] = offsets[f];} 718171f0bbf9SMatthew G. Knepley ierr = PetscSectionGetUseFieldOffsets(idxSection, &useFieldOffsets);CHKERRQ(ierr); 718271f0bbf9SMatthew G. Knepley if (useFieldOffsets) { 718371f0bbf9SMatthew G. Knepley for (p = 0; p < Ncl; ++p) { 718471f0bbf9SMatthew G. Knepley const PetscInt pnt = points[p*2]; 718571f0bbf9SMatthew G. Knepley 718671f0bbf9SMatthew G. Knepley ierr = DMPlexGetIndicesPointFieldsSplit_Internal(section, idxSection, pnt, offsets, perms, p, clperm, idx);CHKERRQ(ierr); 71877773e69fSMatthew G. Knepley } 71887773e69fSMatthew G. Knepley } else { 718971f0bbf9SMatthew G. Knepley for (p = 0; p < Ncl; ++p) { 719071f0bbf9SMatthew G. Knepley const PetscInt pnt = points[p*2]; 719171f0bbf9SMatthew G. Knepley 719271f0bbf9SMatthew G. Knepley ierr = PetscSectionGetOffset(idxSection, pnt, &idxOff);CHKERRQ(ierr); 719371f0bbf9SMatthew G. Knepley /* Note that we pass a local section even though we're using global offsets. This is because global sections do 719471f0bbf9SMatthew G. Knepley * not (at the time of this writing) have fields set. They probably should, in which case we would pass the 719571f0bbf9SMatthew G. Knepley * global section. */ 719671f0bbf9SMatthew G. Knepley ierr = DMPlexGetIndicesPointFields_Internal(section, isLocal, pnt, idxOff < 0 ? -(idxOff+1) : idxOff, offsets, PETSC_FALSE, perms, p, clperm, idx);CHKERRQ(ierr); 719771f0bbf9SMatthew G. Knepley } 719871f0bbf9SMatthew G. Knepley } 719971f0bbf9SMatthew G. Knepley } else { 720071f0bbf9SMatthew G. Knepley PetscInt off = 0, idxOff; 720171f0bbf9SMatthew G. Knepley 720271f0bbf9SMatthew G. Knepley for (p = 0; p < Ncl; ++p) { 720371f0bbf9SMatthew G. Knepley const PetscInt pnt = points[p*2]; 72044acb8e1eSToby Isaac const PetscInt *perm = perms[0] ? perms[0][p] : NULL; 72054acb8e1eSToby Isaac 720671f0bbf9SMatthew G. Knepley ierr = PetscSectionGetOffset(idxSection, pnt, &idxOff);CHKERRQ(ierr); 720771f0bbf9SMatthew G. Knepley /* Note that we pass a local section even though we're using global offsets. This is because global sections do 720871f0bbf9SMatthew G. Knepley * not (at the time of this writing) have fields set. They probably should, in which case we would pass the global section. */ 720971f0bbf9SMatthew G. Knepley ierr = DMPlexGetIndicesPoint_Internal(section, isLocal, pnt, idxOff < 0 ? -(idxOff+1) : idxOff, &off, PETSC_FALSE, perm, clperm, idx);CHKERRQ(ierr); 72107773e69fSMatthew G. Knepley } 72117773e69fSMatthew G. Knepley } 721271f0bbf9SMatthew G. Knepley /* 6) Cleanup */ 721371f0bbf9SMatthew G. Knepley for (f = 0; f < PetscMax(1, Nf); ++f) { 721471f0bbf9SMatthew G. Knepley if (Nf) {ierr = PetscSectionRestoreFieldPointSyms(section, f, Ncl, points, &perms[f], &flips[f]);CHKERRQ(ierr);} 721571f0bbf9SMatthew G. Knepley else {ierr = PetscSectionRestorePointSyms(section, Ncl, points, &perms[f], &flips[f]);CHKERRQ(ierr);} 72164acb8e1eSToby Isaac } 721771f0bbf9SMatthew G. Knepley if (NclC) { 721871f0bbf9SMatthew G. Knepley ierr = DMRestoreWorkArray(dm, NclC*2, MPIU_INT, &pointsC);CHKERRQ(ierr); 72197773e69fSMatthew G. Knepley } else { 722071f0bbf9SMatthew G. Knepley ierr = DMPlexRestoreCompressedClosure(dm, section, point, &Ncl, &points, &clSection, &clPoints, &clp);CHKERRQ(ierr); 72217773e69fSMatthew G. Knepley } 722271f0bbf9SMatthew G. Knepley 722371f0bbf9SMatthew G. Knepley if (numIndices) *numIndices = Ni; 722471f0bbf9SMatthew G. Knepley if (indices) *indices = idx; 72257773e69fSMatthew G. Knepley PetscFunctionReturn(0); 72267773e69fSMatthew G. Knepley } 72277773e69fSMatthew G. Knepley 72287cd05799SMatthew G. Knepley /*@C 722971f0bbf9SMatthew G. Knepley DMPlexRestoreClosureIndices - Restores the global dof indices associated with the closure of the given point within the provided sections. 72307cd05799SMatthew G. Knepley 72317cd05799SMatthew G. Knepley Not collective 72327cd05799SMatthew G. Knepley 72337cd05799SMatthew G. Knepley Input Parameters: 72347cd05799SMatthew G. Knepley + dm - The DM 723571f0bbf9SMatthew G. Knepley . section - The PetscSection describing the points (a local section) 723671f0bbf9SMatthew G. Knepley . idxSection - The PetscSection from which to obtain indices (may be local or global) 723771f0bbf9SMatthew G. Knepley . point - The point defining the closure 723871f0bbf9SMatthew G. Knepley - useClPerm - Use the closure point permutation if available 723971f0bbf9SMatthew G. Knepley 724071f0bbf9SMatthew G. Knepley Output Parameters: 724171f0bbf9SMatthew G. Knepley + numIndices - The number of dof indices in the closure of point with the input sections 724271f0bbf9SMatthew G. Knepley . indices - The dof indices 724371f0bbf9SMatthew G. Knepley . outOffsets - Array to write the field offsets into, or NULL 724471f0bbf9SMatthew G. Knepley - values - The input values, which may be modified if sign flips are induced by the point symmetries, or NULL 724571f0bbf9SMatthew G. Knepley 724671f0bbf9SMatthew G. Knepley Notes: 724771f0bbf9SMatthew G. Knepley If values were modified, the user is responsible for calling DMRestoreWorkArray(dm, 0, MPIU_SCALAR, &values). 724871f0bbf9SMatthew G. Knepley 724971f0bbf9SMatthew G. Knepley If idxSection is global, any constrained dofs (see DMAddBoundary(), for example) will get negative indices. The value 725071f0bbf9SMatthew G. Knepley of those indices is not significant. If idxSection is local, the constrained dofs will yield the involution -(idx+1) 725171f0bbf9SMatthew G. Knepley of their index in a local vector. A caller who does not wish to distinguish those points may recover the nonnegative 725271f0bbf9SMatthew G. Knepley indices via involution, -(-(idx+1)+1)==idx. Local indices are provided when idxSection == section, otherwise global 725371f0bbf9SMatthew G. Knepley indices (with the above semantics) are implied. 72547cd05799SMatthew G. Knepley 72557cd05799SMatthew G. Knepley Level: advanced 72567cd05799SMatthew G. Knepley 725771f0bbf9SMatthew G. Knepley .seealso DMPlexGetClosureIndices(), DMPlexVecGetClosure(), DMPlexMatSetClosure(), DMGetLocalSection(), DMGetGlobalSection() 72587cd05799SMatthew G. Knepley @*/ 725971f0bbf9SMatthew G. Knepley PetscErrorCode DMPlexRestoreClosureIndices(DM dm, PetscSection section, PetscSection idxSection, PetscInt point, PetscBool useClPerm, 726071f0bbf9SMatthew G. Knepley PetscInt *numIndices, PetscInt *indices[], PetscInt outOffsets[], PetscScalar *values[]) 72617773e69fSMatthew G. Knepley { 72627773e69fSMatthew G. Knepley PetscErrorCode ierr; 72637773e69fSMatthew G. Knepley 72647773e69fSMatthew G. Knepley PetscFunctionBegin; 72657773e69fSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7266064a246eSJacob Faibussowitsch PetscValidPointer(indices, 7); 726769291d52SBarry Smith ierr = DMRestoreWorkArray(dm, 0, MPIU_INT, indices);CHKERRQ(ierr); 72687773e69fSMatthew G. Knepley PetscFunctionReturn(0); 72697773e69fSMatthew G. Knepley } 72707773e69fSMatthew G. Knepley 72717f5d1fdeSMatthew G. Knepley /*@C 72727f5d1fdeSMatthew G. Knepley DMPlexMatSetClosure - Set an array of the values on the closure of 'point' 72737f5d1fdeSMatthew G. Knepley 72747f5d1fdeSMatthew G. Knepley Not collective 72757f5d1fdeSMatthew G. Knepley 72767f5d1fdeSMatthew G. Knepley Input Parameters: 72777f5d1fdeSMatthew G. Knepley + dm - The DM 7278ebd6d717SJed Brown . section - The section describing the layout in v, or NULL to use the default section 7279ebd6d717SJed Brown . globalSection - The section describing the layout in v, or NULL to use the default global section 72807f5d1fdeSMatthew G. Knepley . A - The matrix 7281eaf898f9SPatrick Sanan . point - The point in the DM 72827f5d1fdeSMatthew G. Knepley . values - The array of values 72837f5d1fdeSMatthew G. Knepley - mode - The insert mode, where INSERT_ALL_VALUES and ADD_ALL_VALUES also overwrite boundary conditions 72847f5d1fdeSMatthew G. Knepley 72857f5d1fdeSMatthew G. Knepley Fortran Notes: 72867f5d1fdeSMatthew G. Knepley This routine is only available in Fortran 90, and you must include petsc.h90 in your code. 72877f5d1fdeSMatthew G. Knepley 72887f5d1fdeSMatthew G. Knepley Level: intermediate 72897f5d1fdeSMatthew G. Knepley 72904a1e0b3eSMatthew G. Knepley .seealso DMPlexMatSetClosureGeneral(), DMPlexVecGetClosure(), DMPlexVecSetClosure() 72917f5d1fdeSMatthew G. Knepley @*/ 72927c1f9639SMatthew G Knepley PetscErrorCode DMPlexMatSetClosure(DM dm, PetscSection section, PetscSection globalSection, Mat A, PetscInt point, const PetscScalar values[], InsertMode mode) 7293552f7358SJed Brown { 7294552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 7295552f7358SJed Brown PetscInt *indices; 729671f0bbf9SMatthew G. Knepley PetscInt numIndices; 729771f0bbf9SMatthew G. Knepley const PetscScalar *valuesOrig = values; 7298552f7358SJed Brown PetscErrorCode ierr; 7299552f7358SJed Brown 7300552f7358SJed Brown PetscFunctionBegin; 7301552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 730292fd8e1eSJed Brown if (!section) {ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr);} 73033dc93601SMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 7304e87a4003SBarry Smith if (!globalSection) {ierr = DMGetGlobalSection(dm, &globalSection);CHKERRQ(ierr);} 73053dc93601SMatthew G. Knepley PetscValidHeaderSpecific(globalSection, PETSC_SECTION_CLASSID, 3); 73063dc93601SMatthew G. Knepley PetscValidHeaderSpecific(A, MAT_CLASSID, 4); 7307552f7358SJed Brown 730871f0bbf9SMatthew G. Knepley ierr = DMPlexGetClosureIndices(dm, section, globalSection, point, PETSC_TRUE, &numIndices, &indices, NULL, (PetscScalar **) &values);CHKERRQ(ierr); 73090d644c17SKarl Rupp 7310b0ecff45SMatthew G. Knepley if (mesh->printSetValues) {ierr = DMPlexPrintMatSetValues(PETSC_VIEWER_STDOUT_SELF, A, point, numIndices, indices, 0, NULL, values);CHKERRQ(ierr);} 73114a1e0b3eSMatthew G. Knepley ierr = MatSetValues(A, numIndices, indices, numIndices, indices, values, mode); 7312552f7358SJed Brown if (ierr) { 7313552f7358SJed Brown PetscMPIInt rank; 7314552f7358SJed Brown PetscErrorCode ierr2; 7315552f7358SJed Brown 731655b25c41SPierre Jolivet ierr2 = MPI_Comm_rank(PetscObjectComm((PetscObject)A), &rank);CHKERRMPI(ierr2); 7317e4b003c7SBarry Smith ierr2 = (*PetscErrorPrintf)("[%d]ERROR in DMPlexMatSetClosure\n", rank);CHKERRQ(ierr2); 7318b0ecff45SMatthew G. Knepley ierr2 = DMPlexPrintMatSetValues(PETSC_VIEWER_STDERR_SELF, A, point, numIndices, indices, 0, NULL, values);CHKERRQ(ierr2); 731971f0bbf9SMatthew G. Knepley ierr2 = DMPlexRestoreClosureIndices(dm, section, globalSection, point, PETSC_TRUE, &numIndices, &indices, NULL, (PetscScalar **) &values);CHKERRQ(ierr2); 732071f0bbf9SMatthew G. Knepley if (values != valuesOrig) {ierr2 = DMRestoreWorkArray(dm, 0, MPIU_SCALAR, &values);CHKERRQ(ierr2);} 7321552f7358SJed Brown CHKERRQ(ierr); 7322552f7358SJed Brown } 73234a1e0b3eSMatthew G. Knepley if (mesh->printFEM > 1) { 73244a1e0b3eSMatthew G. Knepley PetscInt i; 73254a1e0b3eSMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " Indices:");CHKERRQ(ierr); 73264a1e0b3eSMatthew G. Knepley for (i = 0; i < numIndices; ++i) {ierr = PetscPrintf(PETSC_COMM_SELF, " %D", indices[i]);CHKERRQ(ierr);} 73274a1e0b3eSMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 73284a1e0b3eSMatthew G. Knepley } 732971f0bbf9SMatthew G. Knepley 733071f0bbf9SMatthew G. Knepley ierr = DMPlexRestoreClosureIndices(dm, section, globalSection, point, PETSC_TRUE, &numIndices, &indices, NULL, (PetscScalar **) &values);CHKERRQ(ierr); 733171f0bbf9SMatthew G. Knepley if (values != valuesOrig) {ierr = DMRestoreWorkArray(dm, 0, MPIU_SCALAR, &values);CHKERRQ(ierr);} 733271f0bbf9SMatthew G. Knepley PetscFunctionReturn(0); 73334acb8e1eSToby Isaac } 733471f0bbf9SMatthew G. Knepley 73354a1e0b3eSMatthew G. Knepley /*@C 73364a1e0b3eSMatthew G. Knepley DMPlexMatSetClosure - Set an array of the values on the closure of 'point' using a different row and column section 73374a1e0b3eSMatthew G. Knepley 73384a1e0b3eSMatthew G. Knepley Not collective 73394a1e0b3eSMatthew G. Knepley 73404a1e0b3eSMatthew G. Knepley Input Parameters: 73414a1e0b3eSMatthew G. Knepley + dmRow - The DM for the row fields 73424a1e0b3eSMatthew G. Knepley . sectionRow - The section describing the layout, or NULL to use the default section in dmRow 73434a1e0b3eSMatthew G. Knepley . globalSectionRow - The section describing the layout, or NULL to use the default global section in dmRow 73444a1e0b3eSMatthew G. Knepley . dmCol - The DM for the column fields 73454a1e0b3eSMatthew G. Knepley . sectionCol - The section describing the layout, or NULL to use the default section in dmCol 73464a1e0b3eSMatthew G. Knepley . globalSectionCol - The section describing the layout, or NULL to use the default global section in dmCol 73474a1e0b3eSMatthew G. Knepley . A - The matrix 73484a1e0b3eSMatthew G. Knepley . point - The point in the DMs 73494a1e0b3eSMatthew G. Knepley . values - The array of values 73504a1e0b3eSMatthew G. Knepley - mode - The insert mode, where INSERT_ALL_VALUES and ADD_ALL_VALUES also overwrite boundary conditions 73514a1e0b3eSMatthew G. Knepley 73524a1e0b3eSMatthew G. Knepley Level: intermediate 73534a1e0b3eSMatthew G. Knepley 73544a1e0b3eSMatthew G. Knepley .seealso DMPlexMatSetClosure(), DMPlexVecGetClosure(), DMPlexVecSetClosure() 73554a1e0b3eSMatthew G. Knepley @*/ 735671f0bbf9SMatthew 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) 735771f0bbf9SMatthew G. Knepley { 735871f0bbf9SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dmRow->data; 735971f0bbf9SMatthew G. Knepley PetscInt *indicesRow, *indicesCol; 736071f0bbf9SMatthew G. Knepley PetscInt numIndicesRow, numIndicesCol; 736171f0bbf9SMatthew G. Knepley const PetscScalar *valuesOrig = values; 736271f0bbf9SMatthew G. Knepley PetscErrorCode ierr; 736371f0bbf9SMatthew G. Knepley 736471f0bbf9SMatthew G. Knepley PetscFunctionBegin; 736571f0bbf9SMatthew G. Knepley PetscValidHeaderSpecific(dmRow, DM_CLASSID, 1); 736671f0bbf9SMatthew G. Knepley if (!sectionRow) {ierr = DMGetLocalSection(dmRow, §ionRow);CHKERRQ(ierr);} 736771f0bbf9SMatthew G. Knepley PetscValidHeaderSpecific(sectionRow, PETSC_SECTION_CLASSID, 2); 736871f0bbf9SMatthew G. Knepley if (!globalSectionRow) {ierr = DMGetGlobalSection(dmRow, &globalSectionRow);CHKERRQ(ierr);} 736971f0bbf9SMatthew G. Knepley PetscValidHeaderSpecific(globalSectionRow, PETSC_SECTION_CLASSID, 3); 737071f0bbf9SMatthew G. Knepley PetscValidHeaderSpecific(dmCol, DM_CLASSID, 4); 737171f0bbf9SMatthew G. Knepley if (!sectionCol) {ierr = DMGetLocalSection(dmCol, §ionCol);CHKERRQ(ierr);} 737271f0bbf9SMatthew G. Knepley PetscValidHeaderSpecific(sectionCol, PETSC_SECTION_CLASSID, 5); 737371f0bbf9SMatthew G. Knepley if (!globalSectionCol) {ierr = DMGetGlobalSection(dmCol, &globalSectionCol);CHKERRQ(ierr);} 737471f0bbf9SMatthew G. Knepley PetscValidHeaderSpecific(globalSectionCol, PETSC_SECTION_CLASSID, 6); 737571f0bbf9SMatthew G. Knepley PetscValidHeaderSpecific(A, MAT_CLASSID, 7); 737671f0bbf9SMatthew G. Knepley 737771f0bbf9SMatthew G. Knepley ierr = DMPlexGetClosureIndices(dmRow, sectionRow, globalSectionRow, point, PETSC_TRUE, &numIndicesRow, &indicesRow, NULL, (PetscScalar **) &values);CHKERRQ(ierr); 737871f0bbf9SMatthew G. Knepley ierr = DMPlexGetClosureIndices(dmCol, sectionCol, globalSectionCol, point, PETSC_TRUE, &numIndicesCol, &indicesCol, NULL, (PetscScalar **) &values);CHKERRQ(ierr); 737971f0bbf9SMatthew G. Knepley 738071f0bbf9SMatthew G. Knepley if (mesh->printSetValues) {ierr = DMPlexPrintMatSetValues(PETSC_VIEWER_STDOUT_SELF, A, point, numIndicesRow, indicesRow, numIndicesCol, indicesCol, values);CHKERRQ(ierr);} 73814a1e0b3eSMatthew G. Knepley ierr = MatSetValues(A, numIndicesRow, indicesRow, numIndicesCol, indicesCol, values, mode); 738271f0bbf9SMatthew G. Knepley if (ierr) { 738371f0bbf9SMatthew G. Knepley PetscMPIInt rank; 738471f0bbf9SMatthew G. Knepley PetscErrorCode ierr2; 738571f0bbf9SMatthew G. Knepley 738655b25c41SPierre Jolivet ierr2 = MPI_Comm_rank(PetscObjectComm((PetscObject)A), &rank);CHKERRMPI(ierr2); 738771f0bbf9SMatthew G. Knepley ierr2 = (*PetscErrorPrintf)("[%d]ERROR in DMPlexMatSetClosure\n", rank);CHKERRQ(ierr2); 738871f0bbf9SMatthew G. Knepley ierr2 = DMPlexPrintMatSetValues(PETSC_VIEWER_STDERR_SELF, A, point, numIndicesRow, indicesRow, numIndicesCol, indicesCol, values);CHKERRQ(ierr2); 738971f0bbf9SMatthew G. Knepley ierr2 = DMPlexRestoreClosureIndices(dmRow, sectionRow, globalSectionRow, point, PETSC_TRUE, &numIndicesRow, &indicesRow, NULL, (PetscScalar **) &values);CHKERRQ(ierr2); 739071f0bbf9SMatthew G. Knepley ierr2 = DMPlexRestoreClosureIndices(dmCol, sectionCol, globalSectionCol, point, PETSC_TRUE, &numIndicesCol, &indicesRow, NULL, (PetscScalar **) &values);CHKERRQ(ierr2); 739171f0bbf9SMatthew G. Knepley if (values != valuesOrig) {ierr2 = DMRestoreWorkArray(dmRow, 0, MPIU_SCALAR, &values);CHKERRQ(ierr2);} 739271f0bbf9SMatthew G. Knepley CHKERRQ(ierr); 7393d3d1a6afSToby Isaac } 739471f0bbf9SMatthew G. Knepley 739571f0bbf9SMatthew G. Knepley ierr = DMPlexRestoreClosureIndices(dmRow, sectionRow, globalSectionRow, point, PETSC_TRUE, &numIndicesRow, &indicesRow, NULL, (PetscScalar **) &values);CHKERRQ(ierr); 739671f0bbf9SMatthew G. Knepley ierr = DMPlexRestoreClosureIndices(dmCol, sectionCol, globalSectionCol, point, PETSC_TRUE, &numIndicesCol, &indicesCol, NULL, (PetscScalar **) &values);CHKERRQ(ierr); 739771f0bbf9SMatthew G. Knepley if (values != valuesOrig) {ierr = DMRestoreWorkArray(dmRow, 0, MPIU_SCALAR, &values);CHKERRQ(ierr);} 7398552f7358SJed Brown PetscFunctionReturn(0); 7399552f7358SJed Brown } 7400552f7358SJed Brown 7401de41b84cSMatthew 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) 7402de41b84cSMatthew G. Knepley { 7403de41b84cSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dmf->data; 7404de41b84cSMatthew G. Knepley PetscInt *fpoints = NULL, *ftotpoints = NULL; 7405de41b84cSMatthew G. Knepley PetscInt *cpoints = NULL; 7406de41b84cSMatthew G. Knepley PetscInt *findices, *cindices; 740717c0192bSMatthew G. Knepley const PetscInt *fclperm = NULL, *cclperm = NULL; /* Closure permutations cannot work here */ 7408de41b84cSMatthew G. Knepley PetscInt foffsets[32], coffsets[32]; 7409412e9a14SMatthew G. Knepley DMPolytopeType ct; 74104ca5e9f5SMatthew G. Knepley PetscInt numFields, numSubcells, maxFPoints, numFPoints, numCPoints, numFIndices, numCIndices, dof, off, globalOff, pStart, pEnd, p, q, r, s, f; 7411de41b84cSMatthew G. Knepley PetscErrorCode ierr; 7412de41b84cSMatthew G. Knepley 7413de41b84cSMatthew G. Knepley PetscFunctionBegin; 7414de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(dmf, DM_CLASSID, 1); 7415de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(dmc, DM_CLASSID, 4); 741692fd8e1eSJed Brown if (!fsection) {ierr = DMGetLocalSection(dmf, &fsection);CHKERRQ(ierr);} 7417de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(fsection, PETSC_SECTION_CLASSID, 2); 741892fd8e1eSJed Brown if (!csection) {ierr = DMGetLocalSection(dmc, &csection);CHKERRQ(ierr);} 7419de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(csection, PETSC_SECTION_CLASSID, 5); 7420e87a4003SBarry Smith if (!globalFSection) {ierr = DMGetGlobalSection(dmf, &globalFSection);CHKERRQ(ierr);} 7421de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(globalFSection, PETSC_SECTION_CLASSID, 3); 7422e87a4003SBarry Smith if (!globalCSection) {ierr = DMGetGlobalSection(dmc, &globalCSection);CHKERRQ(ierr);} 7423de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(globalCSection, PETSC_SECTION_CLASSID, 6); 7424de41b84cSMatthew G. Knepley PetscValidHeaderSpecific(A, MAT_CLASSID, 7); 7425de41b84cSMatthew G. Knepley ierr = PetscSectionGetNumFields(fsection, &numFields);CHKERRQ(ierr); 7426de41b84cSMatthew G. Knepley if (numFields > 31) SETERRQ1(PetscObjectComm((PetscObject)dmf), PETSC_ERR_ARG_OUTOFRANGE, "Number of fields %D limited to 31", numFields); 7427580bdb30SBarry Smith ierr = PetscArrayzero(foffsets, 32);CHKERRQ(ierr); 7428580bdb30SBarry Smith ierr = PetscArrayzero(coffsets, 32);CHKERRQ(ierr); 7429de41b84cSMatthew G. Knepley /* Column indices */ 7430de41b84cSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dmc, point, PETSC_TRUE, &numCPoints, &cpoints);CHKERRQ(ierr); 74314ca5e9f5SMatthew G. Knepley maxFPoints = numCPoints; 7432de41b84cSMatthew G. Knepley /* Compress out points not in the section */ 7433de41b84cSMatthew G. Knepley /* TODO: Squeeze out points with 0 dof as well */ 7434de41b84cSMatthew G. Knepley ierr = PetscSectionGetChart(csection, &pStart, &pEnd);CHKERRQ(ierr); 7435de41b84cSMatthew G. Knepley for (p = 0, q = 0; p < numCPoints*2; p += 2) { 7436de41b84cSMatthew G. Knepley if ((cpoints[p] >= pStart) && (cpoints[p] < pEnd)) { 7437de41b84cSMatthew G. Knepley cpoints[q*2] = cpoints[p]; 7438de41b84cSMatthew G. Knepley cpoints[q*2+1] = cpoints[p+1]; 7439de41b84cSMatthew G. Knepley ++q; 7440de41b84cSMatthew G. Knepley } 7441de41b84cSMatthew G. Knepley } 7442de41b84cSMatthew G. Knepley numCPoints = q; 7443de41b84cSMatthew G. Knepley for (p = 0, numCIndices = 0; p < numCPoints*2; p += 2) { 7444de41b84cSMatthew G. Knepley PetscInt fdof; 7445de41b84cSMatthew G. Knepley 7446de41b84cSMatthew G. Knepley ierr = PetscSectionGetDof(csection, cpoints[p], &dof);CHKERRQ(ierr); 74474ca5e9f5SMatthew G. Knepley if (!dof) continue; 7448de41b84cSMatthew G. Knepley for (f = 0; f < numFields; ++f) { 7449de41b84cSMatthew G. Knepley ierr = PetscSectionGetFieldDof(csection, cpoints[p], f, &fdof);CHKERRQ(ierr); 7450de41b84cSMatthew G. Knepley coffsets[f+1] += fdof; 7451de41b84cSMatthew G. Knepley } 7452de41b84cSMatthew G. Knepley numCIndices += dof; 7453de41b84cSMatthew G. Knepley } 7454de41b84cSMatthew G. Knepley for (f = 1; f < numFields; ++f) coffsets[f+1] += coffsets[f]; 7455de41b84cSMatthew G. Knepley /* Row indices */ 7456412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dmc, point, &ct);CHKERRQ(ierr); 7457412e9a14SMatthew G. Knepley { 7458412e9a14SMatthew G. Knepley DMPlexCellRefiner cr; 7459412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerCreate(dmc, &cr);CHKERRQ(ierr); 7460412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetAffineTransforms(cr, ct, &numSubcells, NULL, NULL, NULL);CHKERRQ(ierr); 7461412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerDestroy(&cr);CHKERRQ(ierr); 7462412e9a14SMatthew G. Knepley } 746369291d52SBarry Smith ierr = DMGetWorkArray(dmf, maxFPoints*2*numSubcells, MPIU_INT, &ftotpoints);CHKERRQ(ierr); 7464de41b84cSMatthew G. Knepley for (r = 0, q = 0; r < numSubcells; ++r) { 7465de41b84cSMatthew G. Knepley /* TODO Map from coarse to fine cells */ 7466de41b84cSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dmf, point*numSubcells + r, PETSC_TRUE, &numFPoints, &fpoints);CHKERRQ(ierr); 7467de41b84cSMatthew G. Knepley /* Compress out points not in the section */ 7468de41b84cSMatthew G. Knepley ierr = PetscSectionGetChart(fsection, &pStart, &pEnd);CHKERRQ(ierr); 7469de41b84cSMatthew G. Knepley for (p = 0; p < numFPoints*2; p += 2) { 7470de41b84cSMatthew G. Knepley if ((fpoints[p] >= pStart) && (fpoints[p] < pEnd)) { 74714ca5e9f5SMatthew G. Knepley ierr = PetscSectionGetDof(fsection, fpoints[p], &dof);CHKERRQ(ierr); 74724ca5e9f5SMatthew G. Knepley if (!dof) continue; 74734ca5e9f5SMatthew G. Knepley for (s = 0; s < q; ++s) if (fpoints[p] == ftotpoints[s*2]) break; 74744ca5e9f5SMatthew G. Knepley if (s < q) continue; 7475de41b84cSMatthew G. Knepley ftotpoints[q*2] = fpoints[p]; 7476de41b84cSMatthew G. Knepley ftotpoints[q*2+1] = fpoints[p+1]; 7477de41b84cSMatthew G. Knepley ++q; 7478de41b84cSMatthew G. Knepley } 7479de41b84cSMatthew G. Knepley } 7480de41b84cSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dmf, point, PETSC_TRUE, &numFPoints, &fpoints);CHKERRQ(ierr); 7481de41b84cSMatthew G. Knepley } 7482de41b84cSMatthew G. Knepley numFPoints = q; 7483de41b84cSMatthew G. Knepley for (p = 0, numFIndices = 0; p < numFPoints*2; p += 2) { 7484de41b84cSMatthew G. Knepley PetscInt fdof; 7485de41b84cSMatthew G. Knepley 7486de41b84cSMatthew G. Knepley ierr = PetscSectionGetDof(fsection, ftotpoints[p], &dof);CHKERRQ(ierr); 74874ca5e9f5SMatthew G. Knepley if (!dof) continue; 7488de41b84cSMatthew G. Knepley for (f = 0; f < numFields; ++f) { 7489de41b84cSMatthew G. Knepley ierr = PetscSectionGetFieldDof(fsection, ftotpoints[p], f, &fdof);CHKERRQ(ierr); 7490de41b84cSMatthew G. Knepley foffsets[f+1] += fdof; 7491de41b84cSMatthew G. Knepley } 7492de41b84cSMatthew G. Knepley numFIndices += dof; 7493de41b84cSMatthew G. Knepley } 7494de41b84cSMatthew G. Knepley for (f = 1; f < numFields; ++f) foffsets[f+1] += foffsets[f]; 7495de41b84cSMatthew G. Knepley 74968ccfff9cSToby Isaac if (numFields && foffsets[numFields] != numFIndices) SETERRQ2(PetscObjectComm((PetscObject)dmf), PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", foffsets[numFields], numFIndices); 74978ccfff9cSToby Isaac if (numFields && coffsets[numFields] != numCIndices) SETERRQ2(PetscObjectComm((PetscObject)dmc), PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", coffsets[numFields], numCIndices); 749869291d52SBarry Smith ierr = DMGetWorkArray(dmf, numFIndices, MPIU_INT, &findices);CHKERRQ(ierr); 749969291d52SBarry Smith ierr = DMGetWorkArray(dmc, numCIndices, MPIU_INT, &cindices);CHKERRQ(ierr); 7500de41b84cSMatthew G. Knepley if (numFields) { 75014acb8e1eSToby Isaac const PetscInt **permsF[32] = {NULL}; 75024acb8e1eSToby Isaac const PetscInt **permsC[32] = {NULL}; 75034acb8e1eSToby Isaac 75044acb8e1eSToby Isaac for (f = 0; f < numFields; f++) { 75054acb8e1eSToby Isaac ierr = PetscSectionGetFieldPointSyms(fsection,f,numFPoints,ftotpoints,&permsF[f],NULL);CHKERRQ(ierr); 75064acb8e1eSToby Isaac ierr = PetscSectionGetFieldPointSyms(csection,f,numCPoints,cpoints,&permsC[f],NULL);CHKERRQ(ierr); 7507de41b84cSMatthew G. Knepley } 75084acb8e1eSToby Isaac for (p = 0; p < numFPoints; p++) { 75094acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalFSection, ftotpoints[2*p], &globalOff);CHKERRQ(ierr); 751036fa2b79SJed Brown ierr = DMPlexGetIndicesPointFields_Internal(fsection, PETSC_FALSE, ftotpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, foffsets, PETSC_FALSE, permsF, p, fclperm, findices);CHKERRQ(ierr); 75114acb8e1eSToby Isaac } 75124acb8e1eSToby Isaac for (p = 0; p < numCPoints; p++) { 75134acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalCSection, cpoints[2*p], &globalOff);CHKERRQ(ierr); 751436fa2b79SJed Brown ierr = DMPlexGetIndicesPointFields_Internal(csection, PETSC_FALSE, cpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, coffsets, PETSC_FALSE, permsC, p, cclperm, cindices);CHKERRQ(ierr); 75154acb8e1eSToby Isaac } 75164acb8e1eSToby Isaac for (f = 0; f < numFields; f++) { 75174acb8e1eSToby Isaac ierr = PetscSectionRestoreFieldPointSyms(fsection,f,numFPoints,ftotpoints,&permsF[f],NULL);CHKERRQ(ierr); 75184acb8e1eSToby Isaac ierr = PetscSectionRestoreFieldPointSyms(csection,f,numCPoints,cpoints,&permsC[f],NULL);CHKERRQ(ierr); 7519de41b84cSMatthew G. Knepley } 7520de41b84cSMatthew G. Knepley } else { 75214acb8e1eSToby Isaac const PetscInt **permsF = NULL; 75224acb8e1eSToby Isaac const PetscInt **permsC = NULL; 75234acb8e1eSToby Isaac 75244acb8e1eSToby Isaac ierr = PetscSectionGetPointSyms(fsection,numFPoints,ftotpoints,&permsF,NULL);CHKERRQ(ierr); 75254acb8e1eSToby Isaac ierr = PetscSectionGetPointSyms(csection,numCPoints,cpoints,&permsC,NULL);CHKERRQ(ierr); 75264acb8e1eSToby Isaac for (p = 0, off = 0; p < numFPoints; p++) { 75274acb8e1eSToby Isaac const PetscInt *perm = permsF ? permsF[p] : NULL; 75284acb8e1eSToby Isaac 75294acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalFSection, ftotpoints[2*p], &globalOff);CHKERRQ(ierr); 753036fa2b79SJed Brown ierr = DMPlexGetIndicesPoint_Internal(fsection, PETSC_FALSE, ftotpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, perm, fclperm, findices);CHKERRQ(ierr); 7531de41b84cSMatthew G. Knepley } 75324acb8e1eSToby Isaac for (p = 0, off = 0; p < numCPoints; p++) { 75334acb8e1eSToby Isaac const PetscInt *perm = permsC ? permsC[p] : NULL; 75344acb8e1eSToby Isaac 75354acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalCSection, cpoints[2*p], &globalOff);CHKERRQ(ierr); 753636fa2b79SJed Brown ierr = DMPlexGetIndicesPoint_Internal(csection, PETSC_FALSE, cpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, perm, cclperm, cindices);CHKERRQ(ierr); 7537de41b84cSMatthew G. Knepley } 75384acb8e1eSToby Isaac ierr = PetscSectionRestorePointSyms(fsection,numFPoints,ftotpoints,&permsF,NULL);CHKERRQ(ierr); 75394acb8e1eSToby Isaac ierr = PetscSectionRestorePointSyms(csection,numCPoints,cpoints,&permsC,NULL);CHKERRQ(ierr); 7540de41b84cSMatthew G. Knepley } 7541de41b84cSMatthew G. Knepley if (mesh->printSetValues) {ierr = DMPlexPrintMatSetValues(PETSC_VIEWER_STDOUT_SELF, A, point, numFIndices, findices, numCIndices, cindices, values);CHKERRQ(ierr);} 75424acb8e1eSToby Isaac /* TODO: flips */ 7543de41b84cSMatthew G. Knepley ierr = MatSetValues(A, numFIndices, findices, numCIndices, cindices, values, mode); 7544de41b84cSMatthew G. Knepley if (ierr) { 7545de41b84cSMatthew G. Knepley PetscMPIInt rank; 7546de41b84cSMatthew G. Knepley PetscErrorCode ierr2; 7547de41b84cSMatthew G. Knepley 754855b25c41SPierre Jolivet ierr2 = MPI_Comm_rank(PetscObjectComm((PetscObject)A), &rank);CHKERRMPI(ierr2); 7549e4b003c7SBarry Smith ierr2 = (*PetscErrorPrintf)("[%d]ERROR in DMPlexMatSetClosure\n", rank);CHKERRQ(ierr2); 7550de41b84cSMatthew G. Knepley ierr2 = DMPlexPrintMatSetValues(PETSC_VIEWER_STDERR_SELF, A, point, numFIndices, findices, numCIndices, cindices, values);CHKERRQ(ierr2); 755169291d52SBarry Smith ierr2 = DMRestoreWorkArray(dmf, numFIndices, MPIU_INT, &findices);CHKERRQ(ierr2); 755269291d52SBarry Smith ierr2 = DMRestoreWorkArray(dmc, numCIndices, MPIU_INT, &cindices);CHKERRQ(ierr2); 7553de41b84cSMatthew G. Knepley CHKERRQ(ierr); 7554de41b84cSMatthew G. Knepley } 755569291d52SBarry Smith ierr = DMRestoreWorkArray(dmf, numCPoints*2*4, MPIU_INT, &ftotpoints);CHKERRQ(ierr); 7556de41b84cSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dmc, point, PETSC_TRUE, &numCPoints, &cpoints);CHKERRQ(ierr); 755769291d52SBarry Smith ierr = DMRestoreWorkArray(dmf, numFIndices, MPIU_INT, &findices);CHKERRQ(ierr); 755869291d52SBarry Smith ierr = DMRestoreWorkArray(dmc, numCIndices, MPIU_INT, &cindices);CHKERRQ(ierr); 7559de41b84cSMatthew G. Knepley PetscFunctionReturn(0); 7560de41b84cSMatthew G. Knepley } 7561de41b84cSMatthew G. Knepley 75627c927364SMatthew G. Knepley PetscErrorCode DMPlexMatGetClosureIndicesRefined(DM dmf, PetscSection fsection, PetscSection globalFSection, DM dmc, PetscSection csection, PetscSection globalCSection, PetscInt point, PetscInt cindices[], PetscInt findices[]) 75637c927364SMatthew G. Knepley { 75647c927364SMatthew G. Knepley PetscInt *fpoints = NULL, *ftotpoints = NULL; 75657c927364SMatthew G. Knepley PetscInt *cpoints = NULL; 75667c927364SMatthew G. Knepley PetscInt foffsets[32], coffsets[32]; 756717c0192bSMatthew G. Knepley const PetscInt *fclperm = NULL, *cclperm = NULL; /* Closure permutations cannot work here */ 7568412e9a14SMatthew G. Knepley DMPolytopeType ct; 75697c927364SMatthew G. Knepley PetscInt numFields, numSubcells, maxFPoints, numFPoints, numCPoints, numFIndices, numCIndices, dof, off, globalOff, pStart, pEnd, p, q, r, s, f; 75707c927364SMatthew G. Knepley PetscErrorCode ierr; 75717c927364SMatthew G. Knepley 75727c927364SMatthew G. Knepley PetscFunctionBegin; 75737c927364SMatthew G. Knepley PetscValidHeaderSpecific(dmf, DM_CLASSID, 1); 75747c927364SMatthew G. Knepley PetscValidHeaderSpecific(dmc, DM_CLASSID, 4); 757592fd8e1eSJed Brown if (!fsection) {ierr = DMGetLocalSection(dmf, &fsection);CHKERRQ(ierr);} 75767c927364SMatthew G. Knepley PetscValidHeaderSpecific(fsection, PETSC_SECTION_CLASSID, 2); 757792fd8e1eSJed Brown if (!csection) {ierr = DMGetLocalSection(dmc, &csection);CHKERRQ(ierr);} 75787c927364SMatthew G. Knepley PetscValidHeaderSpecific(csection, PETSC_SECTION_CLASSID, 5); 7579e87a4003SBarry Smith if (!globalFSection) {ierr = DMGetGlobalSection(dmf, &globalFSection);CHKERRQ(ierr);} 75807c927364SMatthew G. Knepley PetscValidHeaderSpecific(globalFSection, PETSC_SECTION_CLASSID, 3); 7581e87a4003SBarry Smith if (!globalCSection) {ierr = DMGetGlobalSection(dmc, &globalCSection);CHKERRQ(ierr);} 75827c927364SMatthew G. Knepley PetscValidHeaderSpecific(globalCSection, PETSC_SECTION_CLASSID, 6); 75837c927364SMatthew G. Knepley ierr = PetscSectionGetNumFields(fsection, &numFields);CHKERRQ(ierr); 75847c927364SMatthew G. Knepley if (numFields > 31) SETERRQ1(PetscObjectComm((PetscObject)dmf), PETSC_ERR_ARG_OUTOFRANGE, "Number of fields %D limited to 31", numFields); 7585580bdb30SBarry Smith ierr = PetscArrayzero(foffsets, 32);CHKERRQ(ierr); 7586580bdb30SBarry Smith ierr = PetscArrayzero(coffsets, 32);CHKERRQ(ierr); 75877c927364SMatthew G. Knepley /* Column indices */ 75887c927364SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dmc, point, PETSC_TRUE, &numCPoints, &cpoints);CHKERRQ(ierr); 75897c927364SMatthew G. Knepley maxFPoints = numCPoints; 75907c927364SMatthew G. Knepley /* Compress out points not in the section */ 75917c927364SMatthew G. Knepley /* TODO: Squeeze out points with 0 dof as well */ 75927c927364SMatthew G. Knepley ierr = PetscSectionGetChart(csection, &pStart, &pEnd);CHKERRQ(ierr); 75937c927364SMatthew G. Knepley for (p = 0, q = 0; p < numCPoints*2; p += 2) { 75947c927364SMatthew G. Knepley if ((cpoints[p] >= pStart) && (cpoints[p] < pEnd)) { 75957c927364SMatthew G. Knepley cpoints[q*2] = cpoints[p]; 75967c927364SMatthew G. Knepley cpoints[q*2+1] = cpoints[p+1]; 75977c927364SMatthew G. Knepley ++q; 75987c927364SMatthew G. Knepley } 75997c927364SMatthew G. Knepley } 76007c927364SMatthew G. Knepley numCPoints = q; 76017c927364SMatthew G. Knepley for (p = 0, numCIndices = 0; p < numCPoints*2; p += 2) { 76027c927364SMatthew G. Knepley PetscInt fdof; 76037c927364SMatthew G. Knepley 76047c927364SMatthew G. Knepley ierr = PetscSectionGetDof(csection, cpoints[p], &dof);CHKERRQ(ierr); 76057c927364SMatthew G. Knepley if (!dof) continue; 76067c927364SMatthew G. Knepley for (f = 0; f < numFields; ++f) { 76077c927364SMatthew G. Knepley ierr = PetscSectionGetFieldDof(csection, cpoints[p], f, &fdof);CHKERRQ(ierr); 76087c927364SMatthew G. Knepley coffsets[f+1] += fdof; 76097c927364SMatthew G. Knepley } 76107c927364SMatthew G. Knepley numCIndices += dof; 76117c927364SMatthew G. Knepley } 76127c927364SMatthew G. Knepley for (f = 1; f < numFields; ++f) coffsets[f+1] += coffsets[f]; 76137c927364SMatthew G. Knepley /* Row indices */ 7614412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dmc, point, &ct);CHKERRQ(ierr); 7615412e9a14SMatthew G. Knepley { 7616412e9a14SMatthew G. Knepley DMPlexCellRefiner cr; 7617412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerCreate(dmc, &cr);CHKERRQ(ierr); 7618412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerGetAffineTransforms(cr, ct, &numSubcells, NULL, NULL, NULL);CHKERRQ(ierr); 7619412e9a14SMatthew G. Knepley ierr = DMPlexCellRefinerDestroy(&cr);CHKERRQ(ierr); 7620412e9a14SMatthew G. Knepley } 762169291d52SBarry Smith ierr = DMGetWorkArray(dmf, maxFPoints*2*numSubcells, MPIU_INT, &ftotpoints);CHKERRQ(ierr); 76227c927364SMatthew G. Knepley for (r = 0, q = 0; r < numSubcells; ++r) { 76237c927364SMatthew G. Knepley /* TODO Map from coarse to fine cells */ 76247c927364SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dmf, point*numSubcells + r, PETSC_TRUE, &numFPoints, &fpoints);CHKERRQ(ierr); 76257c927364SMatthew G. Knepley /* Compress out points not in the section */ 76267c927364SMatthew G. Knepley ierr = PetscSectionGetChart(fsection, &pStart, &pEnd);CHKERRQ(ierr); 76277c927364SMatthew G. Knepley for (p = 0; p < numFPoints*2; p += 2) { 76287c927364SMatthew G. Knepley if ((fpoints[p] >= pStart) && (fpoints[p] < pEnd)) { 76297c927364SMatthew G. Knepley ierr = PetscSectionGetDof(fsection, fpoints[p], &dof);CHKERRQ(ierr); 76307c927364SMatthew G. Knepley if (!dof) continue; 76317c927364SMatthew G. Knepley for (s = 0; s < q; ++s) if (fpoints[p] == ftotpoints[s*2]) break; 76327c927364SMatthew G. Knepley if (s < q) continue; 76337c927364SMatthew G. Knepley ftotpoints[q*2] = fpoints[p]; 76347c927364SMatthew G. Knepley ftotpoints[q*2+1] = fpoints[p+1]; 76357c927364SMatthew G. Knepley ++q; 76367c927364SMatthew G. Knepley } 76377c927364SMatthew G. Knepley } 76387c927364SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dmf, point, PETSC_TRUE, &numFPoints, &fpoints);CHKERRQ(ierr); 76397c927364SMatthew G. Knepley } 76407c927364SMatthew G. Knepley numFPoints = q; 76417c927364SMatthew G. Knepley for (p = 0, numFIndices = 0; p < numFPoints*2; p += 2) { 76427c927364SMatthew G. Knepley PetscInt fdof; 76437c927364SMatthew G. Knepley 76447c927364SMatthew G. Knepley ierr = PetscSectionGetDof(fsection, ftotpoints[p], &dof);CHKERRQ(ierr); 76457c927364SMatthew G. Knepley if (!dof) continue; 76467c927364SMatthew G. Knepley for (f = 0; f < numFields; ++f) { 76477c927364SMatthew G. Knepley ierr = PetscSectionGetFieldDof(fsection, ftotpoints[p], f, &fdof);CHKERRQ(ierr); 76487c927364SMatthew G. Knepley foffsets[f+1] += fdof; 76497c927364SMatthew G. Knepley } 76507c927364SMatthew G. Knepley numFIndices += dof; 76517c927364SMatthew G. Knepley } 76527c927364SMatthew G. Knepley for (f = 1; f < numFields; ++f) foffsets[f+1] += foffsets[f]; 76537c927364SMatthew G. Knepley 76548ccfff9cSToby Isaac if (numFields && foffsets[numFields] != numFIndices) SETERRQ2(PetscObjectComm((PetscObject)dmf), PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", foffsets[numFields], numFIndices); 76558ccfff9cSToby Isaac if (numFields && coffsets[numFields] != numCIndices) SETERRQ2(PetscObjectComm((PetscObject)dmc), PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", coffsets[numFields], numCIndices); 76567c927364SMatthew G. Knepley if (numFields) { 76574acb8e1eSToby Isaac const PetscInt **permsF[32] = {NULL}; 76584acb8e1eSToby Isaac const PetscInt **permsC[32] = {NULL}; 76594acb8e1eSToby Isaac 76604acb8e1eSToby Isaac for (f = 0; f < numFields; f++) { 76614acb8e1eSToby Isaac ierr = PetscSectionGetFieldPointSyms(fsection,f,numFPoints,ftotpoints,&permsF[f],NULL);CHKERRQ(ierr); 76624acb8e1eSToby Isaac ierr = PetscSectionGetFieldPointSyms(csection,f,numCPoints,cpoints,&permsC[f],NULL);CHKERRQ(ierr); 76637c927364SMatthew G. Knepley } 76644acb8e1eSToby Isaac for (p = 0; p < numFPoints; p++) { 76654acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalFSection, ftotpoints[2*p], &globalOff);CHKERRQ(ierr); 766636fa2b79SJed Brown ierr = DMPlexGetIndicesPointFields_Internal(fsection, PETSC_FALSE, ftotpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, foffsets, PETSC_FALSE, permsF, p, fclperm, findices);CHKERRQ(ierr); 76674acb8e1eSToby Isaac } 76684acb8e1eSToby Isaac for (p = 0; p < numCPoints; p++) { 76694acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalCSection, cpoints[2*p], &globalOff);CHKERRQ(ierr); 767036fa2b79SJed Brown ierr = DMPlexGetIndicesPointFields_Internal(csection, PETSC_FALSE, cpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, coffsets, PETSC_FALSE, permsC, p, cclperm, cindices);CHKERRQ(ierr); 76714acb8e1eSToby Isaac } 76724acb8e1eSToby Isaac for (f = 0; f < numFields; f++) { 76734acb8e1eSToby Isaac ierr = PetscSectionRestoreFieldPointSyms(fsection,f,numFPoints,ftotpoints,&permsF[f],NULL);CHKERRQ(ierr); 76744acb8e1eSToby Isaac ierr = PetscSectionRestoreFieldPointSyms(csection,f,numCPoints,cpoints,&permsC[f],NULL);CHKERRQ(ierr); 76757c927364SMatthew G. Knepley } 76767c927364SMatthew G. Knepley } else { 76774acb8e1eSToby Isaac const PetscInt **permsF = NULL; 76784acb8e1eSToby Isaac const PetscInt **permsC = NULL; 76794acb8e1eSToby Isaac 76804acb8e1eSToby Isaac ierr = PetscSectionGetPointSyms(fsection,numFPoints,ftotpoints,&permsF,NULL);CHKERRQ(ierr); 76814acb8e1eSToby Isaac ierr = PetscSectionGetPointSyms(csection,numCPoints,cpoints,&permsC,NULL);CHKERRQ(ierr); 76824acb8e1eSToby Isaac for (p = 0, off = 0; p < numFPoints; p++) { 76834acb8e1eSToby Isaac const PetscInt *perm = permsF ? permsF[p] : NULL; 76844acb8e1eSToby Isaac 76854acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalFSection, ftotpoints[2*p], &globalOff);CHKERRQ(ierr); 768636fa2b79SJed Brown ierr = DMPlexGetIndicesPoint_Internal(fsection, PETSC_FALSE, ftotpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, perm, fclperm, findices);CHKERRQ(ierr); 76877c927364SMatthew G. Knepley } 76884acb8e1eSToby Isaac for (p = 0, off = 0; p < numCPoints; p++) { 76894acb8e1eSToby Isaac const PetscInt *perm = permsC ? permsC[p] : NULL; 76904acb8e1eSToby Isaac 76914acb8e1eSToby Isaac ierr = PetscSectionGetOffset(globalCSection, cpoints[2*p], &globalOff);CHKERRQ(ierr); 769236fa2b79SJed Brown ierr = DMPlexGetIndicesPoint_Internal(csection, PETSC_FALSE, cpoints[2*p], globalOff < 0 ? -(globalOff+1) : globalOff, &off, PETSC_FALSE, perm, cclperm, cindices);CHKERRQ(ierr); 76937c927364SMatthew G. Knepley } 76944acb8e1eSToby Isaac ierr = PetscSectionRestorePointSyms(fsection,numFPoints,ftotpoints,&permsF,NULL);CHKERRQ(ierr); 76954acb8e1eSToby Isaac ierr = PetscSectionRestorePointSyms(csection,numCPoints,cpoints,&permsC,NULL);CHKERRQ(ierr); 76967c927364SMatthew G. Knepley } 769769291d52SBarry Smith ierr = DMRestoreWorkArray(dmf, numCPoints*2*4, MPIU_INT, &ftotpoints);CHKERRQ(ierr); 76987c927364SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dmc, point, PETSC_TRUE, &numCPoints, &cpoints);CHKERRQ(ierr); 76997c927364SMatthew G. Knepley PetscFunctionReturn(0); 77007c927364SMatthew G. Knepley } 77017c927364SMatthew G. Knepley 77027cd05799SMatthew G. Knepley /*@C 77037cd05799SMatthew G. Knepley DMPlexGetVTKCellHeight - Returns the height in the DAG used to determine which points are cells (normally 0) 77047cd05799SMatthew G. Knepley 77057cd05799SMatthew G. Knepley Input Parameter: 77067cd05799SMatthew G. Knepley . dm - The DMPlex object 77077cd05799SMatthew G. Knepley 77087cd05799SMatthew G. Knepley Output Parameter: 77097cd05799SMatthew G. Knepley . cellHeight - The height of a cell 77107cd05799SMatthew G. Knepley 77117cd05799SMatthew G. Knepley Level: developer 77127cd05799SMatthew G. Knepley 77137cd05799SMatthew G. Knepley .seealso DMPlexSetVTKCellHeight() 77147cd05799SMatthew G. Knepley @*/ 7715552f7358SJed Brown PetscErrorCode DMPlexGetVTKCellHeight(DM dm, PetscInt *cellHeight) 7716552f7358SJed Brown { 7717552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 7718552f7358SJed Brown 7719552f7358SJed Brown PetscFunctionBegin; 7720552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7721552f7358SJed Brown PetscValidPointer(cellHeight, 2); 7722552f7358SJed Brown *cellHeight = mesh->vtkCellHeight; 7723552f7358SJed Brown PetscFunctionReturn(0); 7724552f7358SJed Brown } 7725552f7358SJed Brown 77267cd05799SMatthew G. Knepley /*@C 77277cd05799SMatthew G. Knepley DMPlexSetVTKCellHeight - Sets the height in the DAG used to determine which points are cells (normally 0) 77287cd05799SMatthew G. Knepley 77297cd05799SMatthew G. Knepley Input Parameters: 77307cd05799SMatthew G. Knepley + dm - The DMPlex object 77317cd05799SMatthew G. Knepley - cellHeight - The height of a cell 77327cd05799SMatthew G. Knepley 77337cd05799SMatthew G. Knepley Level: developer 77347cd05799SMatthew G. Knepley 77357cd05799SMatthew G. Knepley .seealso DMPlexGetVTKCellHeight() 77367cd05799SMatthew G. Knepley @*/ 7737552f7358SJed Brown PetscErrorCode DMPlexSetVTKCellHeight(DM dm, PetscInt cellHeight) 7738552f7358SJed Brown { 7739552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 7740552f7358SJed Brown 7741552f7358SJed Brown PetscFunctionBegin; 7742552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7743552f7358SJed Brown mesh->vtkCellHeight = cellHeight; 7744552f7358SJed Brown PetscFunctionReturn(0); 7745552f7358SJed Brown } 7746552f7358SJed Brown 7747e6139122SMatthew G. Knepley /*@ 7748e6139122SMatthew G. Knepley DMPlexGetGhostCellStratum - Get the range of cells which are used to enforce FV boundary conditions 7749e6139122SMatthew G. Knepley 7750e6139122SMatthew G. Knepley Input Parameter: 7751e6139122SMatthew G. Knepley . dm - The DMPlex object 7752e6139122SMatthew G. Knepley 7753e6139122SMatthew G. Knepley Output Parameters: 77542a9f31c0SMatthew G. Knepley + gcStart - The first ghost cell, or NULL 77552a9f31c0SMatthew G. Knepley - gcEnd - The upper bound on ghost cells, or NULL 7756e6139122SMatthew G. Knepley 77572a9f31c0SMatthew G. Knepley Level: advanced 7758e6139122SMatthew G. Knepley 77598065b584SMatthew Knepley .seealso DMPlexConstructGhostCells(), DMPlexGetGhostCellStratum() 7760e6139122SMatthew G. Knepley @*/ 7761e6139122SMatthew G. Knepley PetscErrorCode DMPlexGetGhostCellStratum(DM dm, PetscInt *gcStart, PetscInt *gcEnd) 7762e6139122SMatthew G. Knepley { 7763412e9a14SMatthew G. Knepley DMLabel ctLabel; 7764e6139122SMatthew G. Knepley PetscErrorCode ierr; 7765e6139122SMatthew G. Knepley 7766e6139122SMatthew G. Knepley PetscFunctionBegin; 7767e6139122SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7768412e9a14SMatthew G. Knepley ierr = DMPlexGetCellTypeLabel(dm, &ctLabel);CHKERRQ(ierr); 7769412e9a14SMatthew G. Knepley ierr = DMLabelGetStratumBounds(ctLabel, DM_POLYTOPE_FV_GHOST, gcStart, gcEnd);CHKERRQ(ierr); 7770e6139122SMatthew G. Knepley PetscFunctionReturn(0); 7771e6139122SMatthew G. Knepley } 7772e6139122SMatthew G. Knepley 7773552f7358SJed Brown /* We can easily have a form that takes an IS instead */ 77749886b8cfSStefano Zampini PetscErrorCode DMPlexCreateNumbering_Plex(DM dm, PetscInt pStart, PetscInt pEnd, PetscInt shift, PetscInt *globalSize, PetscSF sf, IS *numbering) 7775552f7358SJed Brown { 7776552f7358SJed Brown PetscSection section, globalSection; 7777552f7358SJed Brown PetscInt *numbers, p; 7778552f7358SJed Brown PetscErrorCode ierr; 7779552f7358SJed Brown 7780552f7358SJed Brown PetscFunctionBegin; 778182f516ccSBarry Smith ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), §ion);CHKERRQ(ierr); 7782552f7358SJed Brown ierr = PetscSectionSetChart(section, pStart, pEnd);CHKERRQ(ierr); 7783552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 7784552f7358SJed Brown ierr = PetscSectionSetDof(section, p, 1);CHKERRQ(ierr); 7785552f7358SJed Brown } 7786552f7358SJed Brown ierr = PetscSectionSetUp(section);CHKERRQ(ierr); 778715b58121SMatthew G. Knepley ierr = PetscSectionCreateGlobalSection(section, sf, PETSC_FALSE, PETSC_FALSE, &globalSection);CHKERRQ(ierr); 7788854ce69bSBarry Smith ierr = PetscMalloc1(pEnd - pStart, &numbers);CHKERRQ(ierr); 7789552f7358SJed Brown for (p = pStart; p < pEnd; ++p) { 7790552f7358SJed Brown ierr = PetscSectionGetOffset(globalSection, p, &numbers[p-pStart]);CHKERRQ(ierr); 7791ef48cebcSMatthew G. Knepley if (numbers[p-pStart] < 0) numbers[p-pStart] -= shift; 7792ef48cebcSMatthew G. Knepley else numbers[p-pStart] += shift; 7793552f7358SJed Brown } 779482f516ccSBarry Smith ierr = ISCreateGeneral(PetscObjectComm((PetscObject) dm), pEnd - pStart, numbers, PETSC_OWN_POINTER, numbering);CHKERRQ(ierr); 7795ef48cebcSMatthew G. Knepley if (globalSize) { 7796ef48cebcSMatthew G. Knepley PetscLayout layout; 7797ef48cebcSMatthew G. Knepley ierr = PetscSectionGetPointLayout(PetscObjectComm((PetscObject) dm), globalSection, &layout);CHKERRQ(ierr); 7798ef48cebcSMatthew G. Knepley ierr = PetscLayoutGetSize(layout, globalSize);CHKERRQ(ierr); 7799ef48cebcSMatthew G. Knepley ierr = PetscLayoutDestroy(&layout);CHKERRQ(ierr); 7800ef48cebcSMatthew G. Knepley } 7801552f7358SJed Brown ierr = PetscSectionDestroy(§ion);CHKERRQ(ierr); 7802552f7358SJed Brown ierr = PetscSectionDestroy(&globalSection);CHKERRQ(ierr); 7803552f7358SJed Brown PetscFunctionReturn(0); 7804552f7358SJed Brown } 7805552f7358SJed Brown 780681ed3555SMatthew G. Knepley PetscErrorCode DMPlexCreateCellNumbering_Internal(DM dm, PetscBool includeHybrid, IS *globalCellNumbers) 7807552f7358SJed Brown { 7808412e9a14SMatthew G. Knepley PetscInt cellHeight, cStart, cEnd; 7809552f7358SJed Brown PetscErrorCode ierr; 7810552f7358SJed Brown 7811552f7358SJed Brown PetscFunctionBegin; 7812552f7358SJed Brown ierr = DMPlexGetVTKCellHeight(dm, &cellHeight);CHKERRQ(ierr); 7813412e9a14SMatthew G. Knepley if (includeHybrid) {ierr = DMPlexGetHeightStratum(dm, cellHeight, &cStart, &cEnd);CHKERRQ(ierr);} 7814412e9a14SMatthew G. Knepley else {ierr = DMPlexGetSimplexOrBoxCells(dm, cellHeight, &cStart, &cEnd);CHKERRQ(ierr);} 78159886b8cfSStefano Zampini ierr = DMPlexCreateNumbering_Plex(dm, cStart, cEnd, 0, NULL, dm->sf, globalCellNumbers);CHKERRQ(ierr); 781681ed3555SMatthew G. Knepley PetscFunctionReturn(0); 7817552f7358SJed Brown } 781881ed3555SMatthew G. Knepley 78198dab3259SMatthew G. Knepley /*@ 78207cd05799SMatthew G. Knepley DMPlexGetCellNumbering - Get a global cell numbering for all cells on this process 78217cd05799SMatthew G. Knepley 78227cd05799SMatthew G. Knepley Input Parameter: 78237cd05799SMatthew G. Knepley . dm - The DMPlex object 78247cd05799SMatthew G. Knepley 78257cd05799SMatthew G. Knepley Output Parameter: 78267cd05799SMatthew G. Knepley . globalCellNumbers - Global cell numbers for all cells on this process 78277cd05799SMatthew G. Knepley 78287cd05799SMatthew G. Knepley Level: developer 78297cd05799SMatthew G. Knepley 78307cd05799SMatthew G. Knepley .seealso DMPlexGetVertexNumbering() 78317cd05799SMatthew G. Knepley @*/ 783281ed3555SMatthew G. Knepley PetscErrorCode DMPlexGetCellNumbering(DM dm, IS *globalCellNumbers) 783381ed3555SMatthew G. Knepley { 783481ed3555SMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 783581ed3555SMatthew G. Knepley PetscErrorCode ierr; 783681ed3555SMatthew G. Knepley 783781ed3555SMatthew G. Knepley PetscFunctionBegin; 783881ed3555SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 783981ed3555SMatthew G. Knepley if (!mesh->globalCellNumbers) {ierr = DMPlexCreateCellNumbering_Internal(dm, PETSC_FALSE, &mesh->globalCellNumbers);CHKERRQ(ierr);} 7840552f7358SJed Brown *globalCellNumbers = mesh->globalCellNumbers; 7841552f7358SJed Brown PetscFunctionReturn(0); 7842552f7358SJed Brown } 7843552f7358SJed Brown 784481ed3555SMatthew G. Knepley PetscErrorCode DMPlexCreateVertexNumbering_Internal(DM dm, PetscBool includeHybrid, IS *globalVertexNumbers) 784581ed3555SMatthew G. Knepley { 7846412e9a14SMatthew G. Knepley PetscInt vStart, vEnd; 784781ed3555SMatthew G. Knepley PetscErrorCode ierr; 784881ed3555SMatthew G. Knepley 784981ed3555SMatthew G. Knepley PetscFunctionBegin; 785081ed3555SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 785181ed3555SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 78529886b8cfSStefano Zampini ierr = DMPlexCreateNumbering_Plex(dm, vStart, vEnd, 0, NULL, dm->sf, globalVertexNumbers);CHKERRQ(ierr); 785381ed3555SMatthew G. Knepley PetscFunctionReturn(0); 785481ed3555SMatthew G. Knepley } 785581ed3555SMatthew G. Knepley 78568dab3259SMatthew G. Knepley /*@ 78576aa51ba9SJacob Faibussowitsch DMPlexGetVertexNumbering - Get a global vertex numbering for all vertices on this process 78587cd05799SMatthew G. Knepley 78597cd05799SMatthew G. Knepley Input Parameter: 78607cd05799SMatthew G. Knepley . dm - The DMPlex object 78617cd05799SMatthew G. Knepley 78627cd05799SMatthew G. Knepley Output Parameter: 78637cd05799SMatthew G. Knepley . globalVertexNumbers - Global vertex numbers for all vertices on this process 78647cd05799SMatthew G. Knepley 78657cd05799SMatthew G. Knepley Level: developer 78667cd05799SMatthew G. Knepley 78677cd05799SMatthew G. Knepley .seealso DMPlexGetCellNumbering() 78687cd05799SMatthew G. Knepley @*/ 7869552f7358SJed Brown PetscErrorCode DMPlexGetVertexNumbering(DM dm, IS *globalVertexNumbers) 7870552f7358SJed Brown { 7871552f7358SJed Brown DM_Plex *mesh = (DM_Plex*) dm->data; 7872552f7358SJed Brown PetscErrorCode ierr; 7873552f7358SJed Brown 7874552f7358SJed Brown PetscFunctionBegin; 7875552f7358SJed Brown PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 787681ed3555SMatthew G. Knepley if (!mesh->globalVertexNumbers) {ierr = DMPlexCreateVertexNumbering_Internal(dm, PETSC_FALSE, &mesh->globalVertexNumbers);CHKERRQ(ierr);} 7877552f7358SJed Brown *globalVertexNumbers = mesh->globalVertexNumbers; 7878552f7358SJed Brown PetscFunctionReturn(0); 7879552f7358SJed Brown } 7880552f7358SJed Brown 78818dab3259SMatthew G. Knepley /*@ 78827cd05799SMatthew G. Knepley DMPlexCreatePointNumbering - Create a global numbering for all points on this process 78837cd05799SMatthew G. Knepley 78847cd05799SMatthew G. Knepley Input Parameter: 78857cd05799SMatthew G. Knepley . dm - The DMPlex object 78867cd05799SMatthew G. Knepley 78877cd05799SMatthew G. Knepley Output Parameter: 78887cd05799SMatthew G. Knepley . globalPointNumbers - Global numbers for all points on this process 78897cd05799SMatthew G. Knepley 78907cd05799SMatthew G. Knepley Level: developer 78917cd05799SMatthew G. Knepley 78927cd05799SMatthew G. Knepley .seealso DMPlexGetCellNumbering() 78937cd05799SMatthew G. Knepley @*/ 7894ef48cebcSMatthew G. Knepley PetscErrorCode DMPlexCreatePointNumbering(DM dm, IS *globalPointNumbers) 7895ef48cebcSMatthew G. Knepley { 7896ef48cebcSMatthew G. Knepley IS nums[4]; 7897862913ffSStefano Zampini PetscInt depths[4], gdepths[4], starts[4]; 7898ef48cebcSMatthew G. Knepley PetscInt depth, d, shift = 0; 7899ef48cebcSMatthew G. Knepley PetscErrorCode ierr; 7900ef48cebcSMatthew G. Knepley 7901ef48cebcSMatthew G. Knepley PetscFunctionBegin; 7902ef48cebcSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7903ef48cebcSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 79048abc87a0SMichael Lange /* For unstratified meshes use dim instead of depth */ 79058abc87a0SMichael Lange if (depth < 0) {ierr = DMGetDimension(dm, &depth);CHKERRQ(ierr);} 7906862913ffSStefano Zampini for (d = 0; d <= depth; ++d) { 7907862913ffSStefano Zampini PetscInt end; 7908862913ffSStefano Zampini 7909862913ffSStefano Zampini depths[d] = depth-d; 7910862913ffSStefano Zampini ierr = DMPlexGetDepthStratum(dm, depths[d], &starts[d], &end);CHKERRQ(ierr); 7911862913ffSStefano Zampini if (!(starts[d]-end)) { starts[d] = depths[d] = -1; } 7912862913ffSStefano Zampini } 7913862913ffSStefano Zampini ierr = PetscSortIntWithArray(depth+1, starts, depths);CHKERRQ(ierr); 7914820f2d46SBarry Smith ierr = MPIU_Allreduce(depths, gdepths, depth+1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject) dm));CHKERRMPI(ierr); 7915862913ffSStefano Zampini for (d = 0; d <= depth; ++d) { 7916862913ffSStefano 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]); 7917862913ffSStefano Zampini } 7918ef48cebcSMatthew G. Knepley for (d = 0; d <= depth; ++d) { 7919ef48cebcSMatthew G. Knepley PetscInt pStart, pEnd, gsize; 7920ef48cebcSMatthew G. Knepley 7921862913ffSStefano Zampini ierr = DMPlexGetDepthStratum(dm, gdepths[d], &pStart, &pEnd);CHKERRQ(ierr); 79229886b8cfSStefano Zampini ierr = DMPlexCreateNumbering_Plex(dm, pStart, pEnd, shift, &gsize, dm->sf, &nums[d]);CHKERRQ(ierr); 7923ef48cebcSMatthew G. Knepley shift += gsize; 7924ef48cebcSMatthew G. Knepley } 7925302440fdSBarry Smith ierr = ISConcatenate(PetscObjectComm((PetscObject) dm), depth+1, nums, globalPointNumbers);CHKERRQ(ierr); 7926ef48cebcSMatthew G. Knepley for (d = 0; d <= depth; ++d) {ierr = ISDestroy(&nums[d]);CHKERRQ(ierr);} 7927ef48cebcSMatthew G. Knepley PetscFunctionReturn(0); 7928ef48cebcSMatthew G. Knepley } 7929ef48cebcSMatthew G. Knepley 793008a22f4bSMatthew G. Knepley /*@ 793108a22f4bSMatthew G. Knepley DMPlexCreateRankField - Create a cell field whose value is the rank of the owner 793208a22f4bSMatthew G. Knepley 793308a22f4bSMatthew G. Knepley Input Parameter: 793408a22f4bSMatthew G. Knepley . dm - The DMPlex object 793508a22f4bSMatthew G. Knepley 793608a22f4bSMatthew G. Knepley Output Parameter: 793708a22f4bSMatthew G. Knepley . ranks - The rank field 793808a22f4bSMatthew G. Knepley 793908a22f4bSMatthew G. Knepley Options Database Keys: 794008a22f4bSMatthew G. Knepley . -dm_partition_view - Adds the rank field into the DM output from -dm_view using the same viewer 794108a22f4bSMatthew G. Knepley 794208a22f4bSMatthew G. Knepley Level: intermediate 794308a22f4bSMatthew G. Knepley 794408a22f4bSMatthew G. Knepley .seealso: DMView() 794508a22f4bSMatthew G. Knepley @*/ 794608a22f4bSMatthew G. Knepley PetscErrorCode DMPlexCreateRankField(DM dm, Vec *ranks) 794708a22f4bSMatthew G. Knepley { 794808a22f4bSMatthew G. Knepley DM rdm; 794908a22f4bSMatthew G. Knepley PetscFE fe; 795008a22f4bSMatthew G. Knepley PetscScalar *r; 795108a22f4bSMatthew G. Knepley PetscMPIInt rank; 7952a55f9a55SMatthew G. Knepley DMPolytopeType ct; 795308a22f4bSMatthew G. Knepley PetscInt dim, cStart, cEnd, c; 7954a55f9a55SMatthew G. Knepley PetscBool simplex; 795508a22f4bSMatthew G. Knepley PetscErrorCode ierr; 795608a22f4bSMatthew G. Knepley 795708a22f4bSMatthew G. Knepley PetscFunctionBeginUser; 7958f95ace6aSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7959f95ace6aSMatthew G. Knepley PetscValidPointer(ranks, 2); 7960ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject) dm), &rank);CHKERRMPI(ierr); 796108a22f4bSMatthew G. Knepley ierr = DMClone(dm, &rdm);CHKERRQ(ierr); 796208a22f4bSMatthew G. Knepley ierr = DMGetDimension(rdm, &dim);CHKERRQ(ierr); 7963a55f9a55SMatthew G. Knepley ierr = DMPlexGetHeightStratum(rdm, 0, &cStart, &cEnd);CHKERRQ(ierr); 7964a55f9a55SMatthew G. Knepley ierr = DMPlexGetCellType(dm, cStart, &ct);CHKERRQ(ierr); 7965a55f9a55SMatthew G. Knepley simplex = DMPolytopeTypeGetNumVertices(ct) == DMPolytopeTypeGetDim(ct)+1 ? PETSC_TRUE : PETSC_FALSE; 7966a55f9a55SMatthew G. Knepley ierr = PetscFECreateDefault(PETSC_COMM_SELF, dim, 1, simplex, "PETSc___rank_", -1, &fe);CHKERRQ(ierr); 796708a22f4bSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) fe, "rank");CHKERRQ(ierr); 7968e5e52638SMatthew G. Knepley ierr = DMSetField(rdm, 0, NULL, (PetscObject) fe);CHKERRQ(ierr); 796908a22f4bSMatthew G. Knepley ierr = PetscFEDestroy(&fe);CHKERRQ(ierr); 7970e5e52638SMatthew G. Knepley ierr = DMCreateDS(rdm);CHKERRQ(ierr); 797108a22f4bSMatthew G. Knepley ierr = DMCreateGlobalVector(rdm, ranks);CHKERRQ(ierr); 797208a22f4bSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) *ranks, "partition");CHKERRQ(ierr); 797308a22f4bSMatthew G. Knepley ierr = VecGetArray(*ranks, &r);CHKERRQ(ierr); 797408a22f4bSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 797508a22f4bSMatthew G. Knepley PetscScalar *lr; 797608a22f4bSMatthew G. Knepley 797708a22f4bSMatthew G. Knepley ierr = DMPlexPointGlobalRef(rdm, c, r, &lr);CHKERRQ(ierr); 797871f09efeSPierre Jolivet if (lr) *lr = rank; 797908a22f4bSMatthew G. Knepley } 798008a22f4bSMatthew G. Knepley ierr = VecRestoreArray(*ranks, &r);CHKERRQ(ierr); 798108a22f4bSMatthew G. Knepley ierr = DMDestroy(&rdm);CHKERRQ(ierr); 798208a22f4bSMatthew G. Knepley PetscFunctionReturn(0); 798308a22f4bSMatthew G. Knepley } 798408a22f4bSMatthew G. Knepley 7985ca8062c8SMatthew G. Knepley /*@ 798618e14f0cSMatthew G. Knepley DMPlexCreateLabelField - Create a cell field whose value is the label value for that cell 798718e14f0cSMatthew G. Knepley 798818e14f0cSMatthew G. Knepley Input Parameters: 798918e14f0cSMatthew G. Knepley + dm - The DMPlex 799018e14f0cSMatthew G. Knepley - label - The DMLabel 799118e14f0cSMatthew G. Knepley 799218e14f0cSMatthew G. Knepley Output Parameter: 799318e14f0cSMatthew G. Knepley . val - The label value field 799418e14f0cSMatthew G. Knepley 799518e14f0cSMatthew G. Knepley Options Database Keys: 799618e14f0cSMatthew G. Knepley . -dm_label_view - Adds the label value field into the DM output from -dm_view using the same viewer 799718e14f0cSMatthew G. Knepley 799818e14f0cSMatthew G. Knepley Level: intermediate 799918e14f0cSMatthew G. Knepley 800018e14f0cSMatthew G. Knepley .seealso: DMView() 800118e14f0cSMatthew G. Knepley @*/ 800218e14f0cSMatthew G. Knepley PetscErrorCode DMPlexCreateLabelField(DM dm, DMLabel label, Vec *val) 800318e14f0cSMatthew G. Knepley { 800418e14f0cSMatthew G. Knepley DM rdm; 800518e14f0cSMatthew G. Knepley PetscFE fe; 800618e14f0cSMatthew G. Knepley PetscScalar *v; 800718e14f0cSMatthew G. Knepley PetscInt dim, cStart, cEnd, c; 800818e14f0cSMatthew G. Knepley PetscErrorCode ierr; 800918e14f0cSMatthew G. Knepley 801018e14f0cSMatthew G. Knepley PetscFunctionBeginUser; 801118e14f0cSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 801218e14f0cSMatthew G. Knepley PetscValidPointer(label, 2); 801318e14f0cSMatthew G. Knepley PetscValidPointer(val, 3); 801418e14f0cSMatthew G. Knepley ierr = DMClone(dm, &rdm);CHKERRQ(ierr); 801518e14f0cSMatthew G. Knepley ierr = DMGetDimension(rdm, &dim);CHKERRQ(ierr); 801618e14f0cSMatthew G. Knepley ierr = PetscFECreateDefault(PetscObjectComm((PetscObject) rdm), dim, 1, PETSC_TRUE, "PETSc___label_value_", -1, &fe);CHKERRQ(ierr); 801718e14f0cSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) fe, "label_value");CHKERRQ(ierr); 8018e5e52638SMatthew G. Knepley ierr = DMSetField(rdm, 0, NULL, (PetscObject) fe);CHKERRQ(ierr); 801918e14f0cSMatthew G. Knepley ierr = PetscFEDestroy(&fe);CHKERRQ(ierr); 8020e5e52638SMatthew G. Knepley ierr = DMCreateDS(rdm);CHKERRQ(ierr); 802118e14f0cSMatthew G. Knepley ierr = DMPlexGetHeightStratum(rdm, 0, &cStart, &cEnd);CHKERRQ(ierr); 802218e14f0cSMatthew G. Knepley ierr = DMCreateGlobalVector(rdm, val);CHKERRQ(ierr); 8023effbd7cbSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) *val, "label_value");CHKERRQ(ierr); 802418e14f0cSMatthew G. Knepley ierr = VecGetArray(*val, &v);CHKERRQ(ierr); 802518e14f0cSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 802618e14f0cSMatthew G. Knepley PetscScalar *lv; 802718e14f0cSMatthew G. Knepley PetscInt cval; 802818e14f0cSMatthew G. Knepley 802918e14f0cSMatthew G. Knepley ierr = DMPlexPointGlobalRef(rdm, c, v, &lv);CHKERRQ(ierr); 803018e14f0cSMatthew G. Knepley ierr = DMLabelGetValue(label, c, &cval);CHKERRQ(ierr); 803118e14f0cSMatthew G. Knepley *lv = cval; 803218e14f0cSMatthew G. Knepley } 803318e14f0cSMatthew G. Knepley ierr = VecRestoreArray(*val, &v);CHKERRQ(ierr); 803418e14f0cSMatthew G. Knepley ierr = DMDestroy(&rdm);CHKERRQ(ierr); 803518e14f0cSMatthew G. Knepley PetscFunctionReturn(0); 803618e14f0cSMatthew G. Knepley } 803718e14f0cSMatthew G. Knepley 803818e14f0cSMatthew G. Knepley /*@ 8039ca8062c8SMatthew G. Knepley DMPlexCheckSymmetry - Check that the adjacency information in the mesh is symmetric. 8040ca8062c8SMatthew G. Knepley 804169916449SMatthew G. Knepley Input Parameter: 804269916449SMatthew G. Knepley . dm - The DMPlex object 8043ca8062c8SMatthew G. Knepley 804495eb5ee5SVaclav Hapla Notes: 804595eb5ee5SVaclav Hapla This is a useful diagnostic when creating meshes programmatically. 804695eb5ee5SVaclav Hapla 804795eb5ee5SVaclav Hapla For the complete list of DMPlexCheck* functions, see DMSetFromOptions(). 8048ca8062c8SMatthew G. Knepley 8049ca8062c8SMatthew G. Knepley Level: developer 8050ca8062c8SMatthew G. Knepley 805195eb5ee5SVaclav Hapla .seealso: DMCreate(), DMSetFromOptions() 8052ca8062c8SMatthew G. Knepley @*/ 8053ca8062c8SMatthew G. Knepley PetscErrorCode DMPlexCheckSymmetry(DM dm) 8054ca8062c8SMatthew G. Knepley { 8055ca8062c8SMatthew G. Knepley PetscSection coneSection, supportSection; 8056ca8062c8SMatthew G. Knepley const PetscInt *cone, *support; 8057ca8062c8SMatthew G. Knepley PetscInt coneSize, c, supportSize, s; 805857beb4faSStefano Zampini PetscInt pStart, pEnd, p, pp, csize, ssize; 805957beb4faSStefano Zampini PetscBool storagecheck = PETSC_TRUE; 8060ca8062c8SMatthew G. Knepley PetscErrorCode ierr; 8061ca8062c8SMatthew G. Knepley 8062ca8062c8SMatthew G. Knepley PetscFunctionBegin; 8063ca8062c8SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8064412e9a14SMatthew G. Knepley ierr = DMViewFromOptions(dm, NULL, "-sym_dm_view");CHKERRQ(ierr); 8065ca8062c8SMatthew G. Knepley ierr = DMPlexGetConeSection(dm, &coneSection);CHKERRQ(ierr); 8066ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupportSection(dm, &supportSection);CHKERRQ(ierr); 8067ca8062c8SMatthew G. Knepley /* Check that point p is found in the support of its cone points, and vice versa */ 8068ca8062c8SMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 8069ca8062c8SMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 8070ca8062c8SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, p, &coneSize);CHKERRQ(ierr); 8071ca8062c8SMatthew G. Knepley ierr = DMPlexGetCone(dm, p, &cone);CHKERRQ(ierr); 8072ca8062c8SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 807342e66dfaSMatthew G. Knepley PetscBool dup = PETSC_FALSE; 807442e66dfaSMatthew G. Knepley PetscInt d; 807542e66dfaSMatthew G. Knepley for (d = c-1; d >= 0; --d) { 807642e66dfaSMatthew G. Knepley if (cone[c] == cone[d]) {dup = PETSC_TRUE; break;} 807742e66dfaSMatthew G. Knepley } 8078ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, cone[c], &supportSize);CHKERRQ(ierr); 8079ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupport(dm, cone[c], &support);CHKERRQ(ierr); 8080ca8062c8SMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 8081ca8062c8SMatthew G. Knepley if (support[s] == p) break; 8082ca8062c8SMatthew G. Knepley } 808342e66dfaSMatthew G. Knepley if ((s >= supportSize) || (dup && (support[s+1] != p))) { 80848ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "p: %D cone: ", p);CHKERRQ(ierr); 8085ca8062c8SMatthew G. Knepley for (s = 0; s < coneSize; ++s) { 80868ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "%D, ", cone[s]);CHKERRQ(ierr); 8087ca8062c8SMatthew G. Knepley } 8088302440fdSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 80898ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "p: %D support: ", cone[c]);CHKERRQ(ierr); 8090ca8062c8SMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 80918ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "%D, ", support[s]);CHKERRQ(ierr); 8092ca8062c8SMatthew G. Knepley } 8093302440fdSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 80948ccfff9cSToby 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]); 80958ccfff9cSToby Isaac else SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D not found in support of cone point %D", p, cone[c]); 8096ca8062c8SMatthew G. Knepley } 809742e66dfaSMatthew G. Knepley } 809857beb4faSStefano Zampini ierr = DMPlexGetTreeParent(dm, p, &pp, NULL);CHKERRQ(ierr); 809957beb4faSStefano Zampini if (p != pp) { storagecheck = PETSC_FALSE; continue; } 8100ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupportSize(dm, p, &supportSize);CHKERRQ(ierr); 8101ca8062c8SMatthew G. Knepley ierr = DMPlexGetSupport(dm, p, &support);CHKERRQ(ierr); 8102ca8062c8SMatthew G. Knepley for (s = 0; s < supportSize; ++s) { 8103ca8062c8SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 8104ca8062c8SMatthew G. Knepley ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 8105ca8062c8SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 810657beb4faSStefano Zampini ierr = DMPlexGetTreeParent(dm, cone[c], &pp, NULL);CHKERRQ(ierr); 810757beb4faSStefano Zampini if (cone[c] != pp) { c = 0; break; } 8108ca8062c8SMatthew G. Knepley if (cone[c] == p) break; 8109ca8062c8SMatthew G. Knepley } 8110ca8062c8SMatthew G. Knepley if (c >= coneSize) { 81118ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "p: %D support: ", p);CHKERRQ(ierr); 8112ca8062c8SMatthew G. Knepley for (c = 0; c < supportSize; ++c) { 81138ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "%D, ", support[c]);CHKERRQ(ierr); 8114ca8062c8SMatthew G. Knepley } 8115302440fdSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 81168ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "p: %D cone: ", support[s]);CHKERRQ(ierr); 8117ca8062c8SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 81188ccfff9cSToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "%D, ", cone[c]);CHKERRQ(ierr); 8119ca8062c8SMatthew G. Knepley } 8120302440fdSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 81218ccfff9cSToby Isaac SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D not found in cone of support point %D", p, support[s]); 8122ca8062c8SMatthew G. Knepley } 8123ca8062c8SMatthew G. Knepley } 8124ca8062c8SMatthew G. Knepley } 812557beb4faSStefano Zampini if (storagecheck) { 8126ca8062c8SMatthew G. Knepley ierr = PetscSectionGetStorageSize(coneSection, &csize);CHKERRQ(ierr); 8127ca8062c8SMatthew G. Knepley ierr = PetscSectionGetStorageSize(supportSection, &ssize);CHKERRQ(ierr); 81288ccfff9cSToby Isaac if (csize != ssize) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Total cone size %D != Total support size %D", csize, ssize); 812957beb4faSStefano Zampini } 8130ca8062c8SMatthew G. Knepley PetscFunctionReturn(0); 8131ca8062c8SMatthew G. Knepley } 8132ca8062c8SMatthew G. Knepley 8133412e9a14SMatthew G. Knepley /* 8134412e9a14SMatthew 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. 8135412e9a14SMatthew G. Knepley */ 8136412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellUnsplitVertices_Private(DM dm, PetscInt c, DMPolytopeType ct, PetscInt *unsplit) 8137412e9a14SMatthew G. Knepley { 8138412e9a14SMatthew G. Knepley DMPolytopeType cct; 8139412e9a14SMatthew G. Knepley PetscInt ptpoints[4]; 8140412e9a14SMatthew G. Knepley const PetscInt *cone, *ccone, *ptcone; 8141412e9a14SMatthew G. Knepley PetscInt coneSize, cp, cconeSize, ccp, npt = 0, pt; 8142412e9a14SMatthew G. Knepley PetscErrorCode ierr; 8143412e9a14SMatthew G. Knepley 8144412e9a14SMatthew G. Knepley PetscFunctionBegin; 8145412e9a14SMatthew G. Knepley *unsplit = 0; 8146412e9a14SMatthew G. Knepley switch (ct) { 8147412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 8148412e9a14SMatthew G. Knepley ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 8149412e9a14SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, c, &coneSize);CHKERRQ(ierr); 8150412e9a14SMatthew G. Knepley for (cp = 0; cp < coneSize; ++cp) { 8151412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, cone[cp], &cct);CHKERRQ(ierr); 8152412e9a14SMatthew G. Knepley if (cct == DM_POLYTOPE_POINT_PRISM_TENSOR) ptpoints[npt++] = cone[cp]; 8153412e9a14SMatthew G. Knepley } 8154412e9a14SMatthew G. Knepley break; 8155412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 8156412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 8157412e9a14SMatthew G. Knepley ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 8158412e9a14SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, c, &coneSize);CHKERRQ(ierr); 8159412e9a14SMatthew G. Knepley for (cp = 0; cp < coneSize; ++cp) { 8160412e9a14SMatthew G. Knepley ierr = DMPlexGetCone(dm, cone[cp], &ccone);CHKERRQ(ierr); 8161412e9a14SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, cone[cp], &cconeSize);CHKERRQ(ierr); 8162412e9a14SMatthew G. Knepley for (ccp = 0; ccp < cconeSize; ++ccp) { 8163412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, ccone[ccp], &cct);CHKERRQ(ierr); 8164412e9a14SMatthew G. Knepley if (cct == DM_POLYTOPE_POINT_PRISM_TENSOR) { 8165412e9a14SMatthew G. Knepley PetscInt p; 8166412e9a14SMatthew G. Knepley for (p = 0; p < npt; ++p) if (ptpoints[p] == ccone[ccp]) break; 8167412e9a14SMatthew G. Knepley if (p == npt) ptpoints[npt++] = ccone[ccp]; 8168412e9a14SMatthew G. Knepley } 8169412e9a14SMatthew G. Knepley } 8170412e9a14SMatthew G. Knepley } 8171412e9a14SMatthew G. Knepley break; 8172412e9a14SMatthew G. Knepley default: break; 8173412e9a14SMatthew G. Knepley } 8174412e9a14SMatthew G. Knepley for (pt = 0; pt < npt; ++pt) { 8175412e9a14SMatthew G. Knepley ierr = DMPlexGetCone(dm, ptpoints[pt], &ptcone);CHKERRQ(ierr); 8176412e9a14SMatthew G. Knepley if (ptcone[0] == ptcone[1]) ++(*unsplit); 8177412e9a14SMatthew G. Knepley } 8178412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 8179412e9a14SMatthew G. Knepley } 8180412e9a14SMatthew G. Knepley 8181ca8062c8SMatthew G. Knepley /*@ 8182ca8062c8SMatthew G. Knepley DMPlexCheckSkeleton - Check that each cell has the correct number of vertices 8183ca8062c8SMatthew G. Knepley 8184ca8062c8SMatthew G. Knepley Input Parameters: 8185ca8062c8SMatthew G. Knepley + dm - The DMPlex object 818658723a97SMatthew G. Knepley - cellHeight - Normally 0 8187ca8062c8SMatthew G. Knepley 818895eb5ee5SVaclav Hapla Notes: 818995eb5ee5SVaclav Hapla This is a useful diagnostic when creating meshes programmatically. 819025c50c26SVaclav Hapla Currently applicable only to homogeneous simplex or tensor meshes. 8191ca8062c8SMatthew G. Knepley 819295eb5ee5SVaclav Hapla For the complete list of DMPlexCheck* functions, see DMSetFromOptions(). 819395eb5ee5SVaclav Hapla 8194ca8062c8SMatthew G. Knepley Level: developer 8195ca8062c8SMatthew G. Knepley 819695eb5ee5SVaclav Hapla .seealso: DMCreate(), DMSetFromOptions() 8197ca8062c8SMatthew G. Knepley @*/ 819825c50c26SVaclav Hapla PetscErrorCode DMPlexCheckSkeleton(DM dm, PetscInt cellHeight) 8199ca8062c8SMatthew G. Knepley { 8200412e9a14SMatthew G. Knepley DMPlexInterpolatedFlag interp; 8201412e9a14SMatthew G. Knepley DMPolytopeType ct; 8202412e9a14SMatthew G. Knepley PetscInt vStart, vEnd, cStart, cEnd, c; 8203ca8062c8SMatthew G. Knepley PetscErrorCode ierr; 8204ca8062c8SMatthew G. Knepley 8205ca8062c8SMatthew G. Knepley PetscFunctionBegin; 8206ca8062c8SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8207412e9a14SMatthew G. Knepley ierr = DMPlexIsInterpolated(dm, &interp);CHKERRQ(ierr); 820825c50c26SVaclav Hapla ierr = DMPlexGetHeightStratum(dm, cellHeight, &cStart, &cEnd);CHKERRQ(ierr); 820958723a97SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 8210412e9a14SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 8211412e9a14SMatthew G. Knepley PetscInt *closure = NULL; 8212412e9a14SMatthew G. Knepley PetscInt coneSize, closureSize, cl, Nv = 0; 821358723a97SMatthew G. Knepley 8214412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, c, &ct);CHKERRQ(ierr); 8215412e9a14SMatthew G. Knepley if ((PetscInt) ct < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cell %D has no cell type", c); 8216412e9a14SMatthew G. Knepley if (ct == DM_POLYTOPE_UNKNOWN) continue; 8217412e9a14SMatthew G. Knepley if (interp == DMPLEX_INTERPOLATED_FULL) { 8218412e9a14SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, c, &coneSize);CHKERRQ(ierr); 8219d4961f80SStefano 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)); 8220412e9a14SMatthew G. Knepley } 822158723a97SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 822258723a97SMatthew G. Knepley for (cl = 0; cl < closureSize*2; cl += 2) { 822358723a97SMatthew G. Knepley const PetscInt p = closure[cl]; 8224412e9a14SMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) ++Nv; 822558723a97SMatthew G. Knepley } 822658723a97SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 8227412e9a14SMatthew G. Knepley /* Special Case: Tensor faces with identified vertices */ 8228412e9a14SMatthew G. Knepley if (Nv < DMPolytopeTypeGetNumVertices(ct)) { 8229412e9a14SMatthew G. Knepley PetscInt unsplit; 823042363296SMatthew G. Knepley 8231412e9a14SMatthew G. Knepley ierr = DMPlexCellUnsplitVertices_Private(dm, c, ct, &unsplit);CHKERRQ(ierr); 8232412e9a14SMatthew G. Knepley if (Nv + unsplit == DMPolytopeTypeGetNumVertices(ct)) continue; 823342363296SMatthew G. Knepley } 8234d4961f80SStefano 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)); 823542363296SMatthew G. Knepley } 8236ca8062c8SMatthew G. Knepley PetscFunctionReturn(0); 8237ca8062c8SMatthew G. Knepley } 82389bf0dad6SMatthew G. Knepley 82399bf0dad6SMatthew G. Knepley /*@ 82409bf0dad6SMatthew 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 82419bf0dad6SMatthew G. Knepley 8242899ea2b8SJacob Faibussowitsch Not Collective 8243899ea2b8SJacob Faibussowitsch 82449bf0dad6SMatthew G. Knepley Input Parameters: 82459bf0dad6SMatthew G. Knepley + dm - The DMPlex object 82469bf0dad6SMatthew G. Knepley - cellHeight - Normally 0 82479bf0dad6SMatthew G. Knepley 824845da879fSVaclav Hapla Notes: 824945da879fSVaclav Hapla This is a useful diagnostic when creating meshes programmatically. 825045da879fSVaclav Hapla This routine is only relevant for meshes that are fully interpolated across all ranks. 825145da879fSVaclav Hapla It will error out if a partially interpolated mesh is given on some rank. 825245da879fSVaclav Hapla It will do nothing for locally uninterpolated mesh (as there is nothing to check). 82539bf0dad6SMatthew G. Knepley 825495eb5ee5SVaclav Hapla For the complete list of DMPlexCheck* functions, see DMSetFromOptions(). 825595eb5ee5SVaclav Hapla 82569bf0dad6SMatthew G. Knepley Level: developer 82579bf0dad6SMatthew G. Knepley 825895eb5ee5SVaclav Hapla .seealso: DMCreate(), DMPlexGetVTKCellHeight(), DMSetFromOptions() 82599bf0dad6SMatthew G. Knepley @*/ 826025c50c26SVaclav Hapla PetscErrorCode DMPlexCheckFaces(DM dm, PetscInt cellHeight) 82619bf0dad6SMatthew G. Knepley { 8262ab91121cSMatthew G. Knepley PetscInt dim, depth, vStart, vEnd, cStart, cEnd, c, h; 82639bf0dad6SMatthew G. Knepley PetscErrorCode ierr; 8264899ea2b8SJacob Faibussowitsch DMPlexInterpolatedFlag interpEnum; 82659bf0dad6SMatthew G. Knepley 82669bf0dad6SMatthew G. Knepley PetscFunctionBegin; 82679bf0dad6SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8268899ea2b8SJacob Faibussowitsch ierr = DMPlexIsInterpolated(dm, &interpEnum);CHKERRQ(ierr); 826945da879fSVaclav Hapla if (interpEnum == DMPLEX_INTERPOLATED_NONE) PetscFunctionReturn(0); 827045da879fSVaclav Hapla if (interpEnum == DMPLEX_INTERPOLATED_PARTIAL) { 8271899ea2b8SJacob Faibussowitsch PetscMPIInt rank; 8272899ea2b8SJacob Faibussowitsch MPI_Comm comm; 8273899ea2b8SJacob Faibussowitsch 8274899ea2b8SJacob Faibussowitsch ierr = PetscObjectGetComm((PetscObject) dm, &comm);CHKERRQ(ierr); 8275ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 827645da879fSVaclav Hapla SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "Mesh is only partially interpolated on rank %d, this is currently not supported", rank); 8277899ea2b8SJacob Faibussowitsch } 8278899ea2b8SJacob Faibussowitsch 8279c73cfb54SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 8280ab91121cSMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 82819bf0dad6SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 8282ab91121cSMatthew G. Knepley for (h = cellHeight; h < PetscMin(depth, dim); ++h) { 82833554e41dSMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, h, &cStart, &cEnd);CHKERRQ(ierr); 82843554e41dSMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 8285412e9a14SMatthew G. Knepley const PetscInt *cone, *ornt, *faceSizes, *faces; 8286412e9a14SMatthew G. Knepley const DMPolytopeType *faceTypes; 8287ba2698f1SMatthew G. Knepley DMPolytopeType ct; 8288412e9a14SMatthew G. Knepley PetscInt numFaces, coneSize, f; 8289412e9a14SMatthew G. Knepley PetscInt *closure = NULL, closureSize, cl, numCorners = 0, fOff = 0, unsplit; 82909bf0dad6SMatthew G. Knepley 8291ba2698f1SMatthew G. Knepley ierr = DMPlexGetCellType(dm, c, &ct);CHKERRQ(ierr); 8292412e9a14SMatthew G. Knepley ierr = DMPlexCellUnsplitVertices_Private(dm, c, ct, &unsplit);CHKERRQ(ierr); 8293412e9a14SMatthew G. Knepley if (unsplit) continue; 82949bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, c, &coneSize);CHKERRQ(ierr); 82959bf0dad6SMatthew G. Knepley ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 82969bf0dad6SMatthew G. Knepley ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 82979bf0dad6SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 82989bf0dad6SMatthew G. Knepley for (cl = 0; cl < closureSize*2; cl += 2) { 82999bf0dad6SMatthew G. Knepley const PetscInt p = closure[cl]; 83009bf0dad6SMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) closure[numCorners++] = p; 83019bf0dad6SMatthew G. Knepley } 8302412e9a14SMatthew G. Knepley ierr = DMPlexGetRawFaces_Internal(dm, ct, closure, &numFaces, &faceTypes, &faceSizes, &faces);CHKERRQ(ierr); 8303d4961f80SStefano 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); 83049bf0dad6SMatthew G. Knepley for (f = 0; f < numFaces; ++f) { 8305d4961f80SStefano Zampini DMPolytopeType fct; 83069bf0dad6SMatthew G. Knepley PetscInt *fclosure = NULL, fclosureSize, cl, fnumCorners = 0, v; 83079bf0dad6SMatthew G. Knepley 8308d4961f80SStefano Zampini ierr = DMPlexGetCellType(dm, cone[f], &fct);CHKERRQ(ierr); 83099bf0dad6SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure_Internal(dm, cone[f], ornt[f], PETSC_TRUE, &fclosureSize, &fclosure);CHKERRQ(ierr); 83109bf0dad6SMatthew G. Knepley for (cl = 0; cl < fclosureSize*2; cl += 2) { 83119bf0dad6SMatthew G. Knepley const PetscInt p = fclosure[cl]; 83129bf0dad6SMatthew G. Knepley if ((p >= vStart) && (p < vEnd)) fclosure[fnumCorners++] = p; 83139bf0dad6SMatthew G. Knepley } 8314d4961f80SStefano 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]); 83159bf0dad6SMatthew G. Knepley for (v = 0; v < fnumCorners; ++v) { 8316d4961f80SStefano Zampini if (fclosure[v] != faces[fOff+v]) SETERRQ8(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Face %D of type %s (cone idx %d) of cell %D of type %s vertex %D, %D != %D", cone[f], DMPolytopeTypes[fct], f, c, DMPolytopeTypes[ct], v, fclosure[v], faces[fOff+v]); 83179bf0dad6SMatthew G. Knepley } 83189bf0dad6SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, cone[f], PETSC_TRUE, &fclosureSize, &fclosure);CHKERRQ(ierr); 8319412e9a14SMatthew G. Knepley fOff += faceSizes[f]; 83209bf0dad6SMatthew G. Knepley } 8321412e9a14SMatthew G. Knepley ierr = DMPlexRestoreRawFaces_Internal(dm, ct, closure, &numFaces, &faceTypes, &faceSizes, &faces);CHKERRQ(ierr); 83229bf0dad6SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &closure);CHKERRQ(ierr); 83239bf0dad6SMatthew G. Knepley } 83243554e41dSMatthew G. Knepley } 8325552f7358SJed Brown PetscFunctionReturn(0); 8326552f7358SJed Brown } 83273913d7c8SMatthew G. Knepley 8328bb6a34a8SMatthew G. Knepley /*@ 8329bb6a34a8SMatthew G. Knepley DMPlexCheckGeometry - Check the geometry of mesh cells 8330bb6a34a8SMatthew G. Knepley 8331bb6a34a8SMatthew G. Knepley Input Parameter: 8332bb6a34a8SMatthew G. Knepley . dm - The DMPlex object 8333bb6a34a8SMatthew G. Knepley 833495eb5ee5SVaclav Hapla Notes: 833595eb5ee5SVaclav Hapla This is a useful diagnostic when creating meshes programmatically. 833695eb5ee5SVaclav Hapla 833795eb5ee5SVaclav Hapla For the complete list of DMPlexCheck* functions, see DMSetFromOptions(). 8338bb6a34a8SMatthew G. Knepley 8339bb6a34a8SMatthew G. Knepley Level: developer 8340bb6a34a8SMatthew G. Knepley 834195eb5ee5SVaclav Hapla .seealso: DMCreate(), DMSetFromOptions() 8342bb6a34a8SMatthew G. Knepley @*/ 8343bb6a34a8SMatthew G. Knepley PetscErrorCode DMPlexCheckGeometry(DM dm) 8344bb6a34a8SMatthew G. Knepley { 8345a2a9e04cSMatthew G. Knepley Vec coordinates; 8346bb6a34a8SMatthew G. Knepley PetscReal detJ, J[9], refVol = 1.0; 8347bb6a34a8SMatthew G. Knepley PetscReal vol; 8348412e9a14SMatthew G. Knepley PetscBool periodic; 834951a74b61SMatthew G. Knepley PetscInt dim, depth, dE, d, cStart, cEnd, c; 8350bb6a34a8SMatthew G. Knepley PetscErrorCode ierr; 8351bb6a34a8SMatthew G. Knepley 8352bb6a34a8SMatthew G. Knepley PetscFunctionBegin; 8353bb6a34a8SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 835451a74b61SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dE);CHKERRQ(ierr); 835551a74b61SMatthew G. Knepley if (dim != dE) PetscFunctionReturn(0); 8356bb6a34a8SMatthew G. Knepley ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 8357412e9a14SMatthew G. Knepley ierr = DMGetPeriodicity(dm, &periodic, NULL, NULL, NULL);CHKERRQ(ierr); 8358bb6a34a8SMatthew G. Knepley for (d = 0; d < dim; ++d) refVol *= 2.0; 8359bb6a34a8SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 8360a2a9e04cSMatthew G. Knepley /* Make sure local coordinates are created, because that step is collective */ 8361a2a9e04cSMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 8362412e9a14SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 8363412e9a14SMatthew G. Knepley DMPolytopeType ct; 8364412e9a14SMatthew G. Knepley PetscInt unsplit; 8365412e9a14SMatthew G. Knepley PetscBool ignoreZeroVol = PETSC_FALSE; 8366412e9a14SMatthew G. Knepley 8367412e9a14SMatthew G. Knepley ierr = DMPlexGetCellType(dm, c, &ct);CHKERRQ(ierr); 8368412e9a14SMatthew G. Knepley switch (ct) { 8369412e9a14SMatthew G. Knepley case DM_POLYTOPE_SEG_PRISM_TENSOR: 8370412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 8371412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 8372412e9a14SMatthew G. Knepley ignoreZeroVol = PETSC_TRUE; break; 8373412e9a14SMatthew G. Knepley default: break; 8374412e9a14SMatthew G. Knepley } 8375412e9a14SMatthew G. Knepley switch (ct) { 8376412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM: 8377412e9a14SMatthew G. Knepley case DM_POLYTOPE_TRI_PRISM_TENSOR: 8378412e9a14SMatthew G. Knepley case DM_POLYTOPE_QUAD_PRISM_TENSOR: 8379a2a9e04cSMatthew G. Knepley case DM_POLYTOPE_PYRAMID: 8380412e9a14SMatthew G. Knepley continue; 8381412e9a14SMatthew G. Knepley default: break; 8382412e9a14SMatthew G. Knepley } 8383412e9a14SMatthew G. Knepley ierr = DMPlexCellUnsplitVertices_Private(dm, c, ct, &unsplit);CHKERRQ(ierr); 8384412e9a14SMatthew G. Knepley if (unsplit) continue; 8385bb6a34a8SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFEM(dm, c, NULL, NULL, J, NULL, &detJ);CHKERRQ(ierr); 8386d4961f80SStefano 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); 8387bb6a34a8SMatthew G. Knepley ierr = PetscInfo2(dm, "Cell %D FEM Volume %g\n", c, (double) detJ*refVol);CHKERRQ(ierr); 8388412e9a14SMatthew G. Knepley if (depth > 1 && !periodic) { 8389bb6a34a8SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFVM(dm, c, &vol, NULL, NULL);CHKERRQ(ierr); 8390d4961f80SStefano 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); 8391bb6a34a8SMatthew G. Knepley ierr = PetscInfo2(dm, "Cell %D FVM Volume %g\n", c, (double) vol);CHKERRQ(ierr); 8392bb6a34a8SMatthew G. Knepley } 8393bb6a34a8SMatthew G. Knepley } 8394bb6a34a8SMatthew G. Knepley PetscFunctionReturn(0); 8395bb6a34a8SMatthew G. Knepley } 8396bb6a34a8SMatthew G. Knepley 839703da9461SVaclav Hapla /*@ 8398e83a0d2dSVaclav Hapla DMPlexCheckPointSF - Check that several necessary conditions are met for the point SF of this plex. 839903da9461SVaclav Hapla 840003da9461SVaclav Hapla Input Parameters: 840103da9461SVaclav Hapla . dm - The DMPlex object 840203da9461SVaclav Hapla 8403e83a0d2dSVaclav Hapla Notes: 8404e83a0d2dSVaclav Hapla This is mainly intended for debugging/testing purposes. 84058918e3e2SVaclav Hapla It currently checks only meshes with no partition overlapping. 840603da9461SVaclav Hapla 840795eb5ee5SVaclav Hapla For the complete list of DMPlexCheck* functions, see DMSetFromOptions(). 840895eb5ee5SVaclav Hapla 840903da9461SVaclav Hapla Level: developer 841003da9461SVaclav Hapla 841195eb5ee5SVaclav Hapla .seealso: DMGetPointSF(), DMSetFromOptions() 841203da9461SVaclav Hapla @*/ 841303da9461SVaclav Hapla PetscErrorCode DMPlexCheckPointSF(DM dm) 841403da9461SVaclav Hapla { 8415f0cfc026SVaclav Hapla PetscSF pointSF; 8416f5869d18SMatthew G. Knepley PetscInt cellHeight, cStart, cEnd, l, nleaves, nroots, overlap; 8417f5869d18SMatthew G. Knepley const PetscInt *locals, *rootdegree; 8418f0cfc026SVaclav Hapla PetscBool distributed; 841903da9461SVaclav Hapla PetscErrorCode ierr; 842003da9461SVaclav Hapla 842103da9461SVaclav Hapla PetscFunctionBegin; 842203da9461SVaclav Hapla PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8423f0cfc026SVaclav Hapla ierr = DMGetPointSF(dm, &pointSF);CHKERRQ(ierr); 8424f0cfc026SVaclav Hapla ierr = DMPlexIsDistributed(dm, &distributed);CHKERRQ(ierr); 8425f0cfc026SVaclav Hapla if (!distributed) PetscFunctionReturn(0); 8426f0cfc026SVaclav Hapla ierr = DMPlexGetOverlap(dm, &overlap);CHKERRQ(ierr); 8427f0cfc026SVaclav Hapla if (overlap) { 84281e1ea65dSPierre Jolivet ierr = PetscPrintf(PetscObjectComm((PetscObject)dm), "Warning: DMPlexCheckPointSF() is currently not implemented for meshes with partition overlapping");CHKERRQ(ierr); 84298918e3e2SVaclav Hapla PetscFunctionReturn(0); 84308918e3e2SVaclav Hapla } 8431f0cfc026SVaclav Hapla if (!pointSF) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "This DMPlex is distributed but does not have PointSF attached"); 8432f0cfc026SVaclav Hapla ierr = PetscSFGetGraph(pointSF, &nroots, &nleaves, &locals, NULL);CHKERRQ(ierr); 8433f0cfc026SVaclav Hapla if (nroots < 0) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONGSTATE, "This DMPlex is distributed but its PointSF has no graph set"); 8434f5869d18SMatthew G. Knepley ierr = PetscSFComputeDegreeBegin(pointSF, &rootdegree);CHKERRQ(ierr); 8435f5869d18SMatthew G. Knepley ierr = PetscSFComputeDegreeEnd(pointSF, &rootdegree);CHKERRQ(ierr); 843603da9461SVaclav Hapla 8437ece87651SVaclav Hapla /* 1) check there are no faces in 2D, cells in 3D, in interface */ 8438f5869d18SMatthew G. Knepley ierr = DMPlexGetVTKCellHeight(dm, &cellHeight);CHKERRQ(ierr); 8439f5869d18SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, cellHeight, &cStart, &cEnd);CHKERRQ(ierr); 8440f5869d18SMatthew G. Knepley for (l = 0; l < nleaves; ++l) { 8441f5869d18SMatthew G. Knepley const PetscInt point = locals[l]; 8442f5869d18SMatthew G. Knepley 8443f5869d18SMatthew G. Knepley if (point >= cStart && point < cEnd) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point SF contains %D which is a cell", point); 844403da9461SVaclav Hapla } 8445ece87651SVaclav Hapla 8446f5869d18SMatthew G. Knepley /* 2) if some point is in interface, then all its cone points must be also in interface (either as leaves or roots) */ 8447f5869d18SMatthew G. Knepley for (l = 0; l < nleaves; ++l) { 8448f5869d18SMatthew G. Knepley const PetscInt point = locals[l]; 8449f5869d18SMatthew G. Knepley const PetscInt *cone; 8450f5869d18SMatthew G. Knepley PetscInt coneSize, c, idx; 8451f5869d18SMatthew G. Knepley 8452f5869d18SMatthew G. Knepley ierr = DMPlexGetConeSize(dm, point, &coneSize);CHKERRQ(ierr); 8453f5869d18SMatthew G. Knepley ierr = DMPlexGetCone(dm, point, &cone);CHKERRQ(ierr); 8454f5869d18SMatthew G. Knepley for (c = 0; c < coneSize; ++c) { 8455f5869d18SMatthew G. Knepley if (!rootdegree[cone[c]]) { 8456f5869d18SMatthew G. Knepley ierr = PetscFindInt(cone[c], nleaves, locals, &idx);CHKERRQ(ierr); 8457f5869d18SMatthew 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]); 8458f5869d18SMatthew G. Knepley } 8459f5869d18SMatthew G. Knepley } 8460ece87651SVaclav Hapla } 846103da9461SVaclav Hapla PetscFunctionReturn(0); 846203da9461SVaclav Hapla } 846303da9461SVaclav Hapla 8464068a5610SStefano Zampini typedef struct cell_stats 8465068a5610SStefano Zampini { 8466068a5610SStefano Zampini PetscReal min, max, sum, squaresum; 8467068a5610SStefano Zampini PetscInt count; 8468068a5610SStefano Zampini } cell_stats_t; 8469068a5610SStefano Zampini 847025befc3bSSatish Balay static void MPIAPI cell_stats_reduce(void *a, void *b, int * len, MPI_Datatype *datatype) 8471068a5610SStefano Zampini { 8472068a5610SStefano Zampini PetscInt i, N = *len; 8473068a5610SStefano Zampini 8474068a5610SStefano Zampini for (i = 0; i < N; i++) { 8475068a5610SStefano Zampini cell_stats_t *A = (cell_stats_t *) a; 8476068a5610SStefano Zampini cell_stats_t *B = (cell_stats_t *) b; 8477068a5610SStefano Zampini 8478068a5610SStefano Zampini B->min = PetscMin(A->min,B->min); 8479068a5610SStefano Zampini B->max = PetscMax(A->max,B->max); 8480068a5610SStefano Zampini B->sum += A->sum; 8481068a5610SStefano Zampini B->squaresum += A->squaresum; 8482068a5610SStefano Zampini B->count += A->count; 8483068a5610SStefano Zampini } 8484068a5610SStefano Zampini } 8485068a5610SStefano Zampini 8486068a5610SStefano Zampini /*@ 848743fa8764SMatthew G. Knepley DMPlexCheckCellShape - Checks the Jacobian of the mapping from reference to real cells and computes some minimal statistics. 8488068a5610SStefano Zampini 84898261a58bSMatthew G. Knepley Collective on dm 84908261a58bSMatthew G. Knepley 8491068a5610SStefano Zampini Input Parameters: 8492068a5610SStefano Zampini + dm - The DMPlex object 849343fa8764SMatthew G. Knepley . output - If true, statistics will be displayed on stdout 849443fa8764SMatthew G. Knepley - condLimit - Display all cells above this condition number, or PETSC_DETERMINE for no cell output 8495068a5610SStefano Zampini 849695eb5ee5SVaclav Hapla Notes: 849795eb5ee5SVaclav Hapla This is mainly intended for debugging/testing purposes. 849895eb5ee5SVaclav Hapla 849995eb5ee5SVaclav Hapla For the complete list of DMPlexCheck* functions, see DMSetFromOptions(). 8500068a5610SStefano Zampini 8501068a5610SStefano Zampini Level: developer 8502068a5610SStefano Zampini 8503f108dbd7SJacob Faibussowitsch .seealso: DMSetFromOptions(), DMPlexComputeOrthogonalQuality() 8504068a5610SStefano Zampini @*/ 850543fa8764SMatthew G. Knepley PetscErrorCode DMPlexCheckCellShape(DM dm, PetscBool output, PetscReal condLimit) 8506068a5610SStefano Zampini { 8507068a5610SStefano Zampini DM dmCoarse; 850843fa8764SMatthew G. Knepley cell_stats_t stats, globalStats; 850943fa8764SMatthew G. Knepley MPI_Comm comm = PetscObjectComm((PetscObject)dm); 851043fa8764SMatthew G. Knepley PetscReal *J, *invJ, min = 0, max = 0, mean = 0, stdev = 0; 851143fa8764SMatthew G. Knepley PetscReal limit = condLimit > 0 ? condLimit : PETSC_MAX_REAL; 8512412e9a14SMatthew G. Knepley PetscInt cdim, cStart, cEnd, c, eStart, eEnd, count = 0; 851343fa8764SMatthew G. Knepley PetscMPIInt rank,size; 8514068a5610SStefano Zampini PetscErrorCode ierr; 8515068a5610SStefano Zampini 8516068a5610SStefano Zampini PetscFunctionBegin; 8517068a5610SStefano Zampini PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8518068a5610SStefano Zampini stats.min = PETSC_MAX_REAL; 8519068a5610SStefano Zampini stats.max = PETSC_MIN_REAL; 8520068a5610SStefano Zampini stats.sum = stats.squaresum = 0.; 8521068a5610SStefano Zampini stats.count = 0; 8522068a5610SStefano Zampini 8523ffc4695bSBarry Smith ierr = MPI_Comm_size(comm, &size);CHKERRMPI(ierr); 8524ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 852543fa8764SMatthew G. Knepley ierr = DMGetCoordinateDim(dm,&cdim);CHKERRQ(ierr); 852643fa8764SMatthew G. Knepley ierr = PetscMalloc2(PetscSqr(cdim), &J, PetscSqr(cdim), &invJ);CHKERRQ(ierr); 8527412e9a14SMatthew G. Knepley ierr = DMPlexGetSimplexOrBoxCells(dm,0,&cStart,&cEnd);CHKERRQ(ierr); 852843fa8764SMatthew G. Knepley ierr = DMPlexGetDepthStratum(dm,1,&eStart,&eEnd);CHKERRQ(ierr); 8529412e9a14SMatthew G. Knepley for (c = cStart; c < cEnd; c++) { 8530068a5610SStefano Zampini PetscInt i; 8531068a5610SStefano Zampini PetscReal frobJ = 0., frobInvJ = 0., cond2, cond, detJ; 8532068a5610SStefano Zampini 8533068a5610SStefano Zampini ierr = DMPlexComputeCellGeometryAffineFEM(dm,c,NULL,J,invJ,&detJ);CHKERRQ(ierr); 8534068a5610SStefano Zampini if (detJ < 0.0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Mesh cell %D is inverted", c); 853543fa8764SMatthew G. Knepley for (i = 0; i < PetscSqr(cdim); ++i) { 8536068a5610SStefano Zampini frobJ += J[i] * J[i]; 8537068a5610SStefano Zampini frobInvJ += invJ[i] * invJ[i]; 8538068a5610SStefano Zampini } 8539068a5610SStefano Zampini cond2 = frobJ * frobInvJ; 8540068a5610SStefano Zampini cond = PetscSqrtReal(cond2); 8541068a5610SStefano Zampini 8542068a5610SStefano Zampini stats.min = PetscMin(stats.min,cond); 8543068a5610SStefano Zampini stats.max = PetscMax(stats.max,cond); 8544068a5610SStefano Zampini stats.sum += cond; 8545068a5610SStefano Zampini stats.squaresum += cond2; 8546068a5610SStefano Zampini stats.count++; 85478261a58bSMatthew G. Knepley if (output && cond > limit) { 854843fa8764SMatthew G. Knepley PetscSection coordSection; 854943fa8764SMatthew G. Knepley Vec coordsLocal; 855043fa8764SMatthew G. Knepley PetscScalar *coords = NULL; 855143fa8764SMatthew G. Knepley PetscInt Nv, d, clSize, cl, *closure = NULL; 855243fa8764SMatthew G. Knepley 855343fa8764SMatthew G. Knepley ierr = DMGetCoordinatesLocal(dm, &coordsLocal);CHKERRQ(ierr); 855443fa8764SMatthew G. Knepley ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 855543fa8764SMatthew G. Knepley ierr = DMPlexVecGetClosure(dm, coordSection, coordsLocal, c, &Nv, &coords);CHKERRQ(ierr); 8556087ef6b2SMatthew G. Knepley ierr = PetscSynchronizedPrintf(comm, "[%d] Cell %D cond %g\n", rank, c, (double) cond);CHKERRQ(ierr); 855743fa8764SMatthew G. Knepley for (i = 0; i < Nv/cdim; ++i) { 855843fa8764SMatthew G. Knepley ierr = PetscSynchronizedPrintf(comm, " Vertex %D: (", i);CHKERRQ(ierr); 855943fa8764SMatthew G. Knepley for (d = 0; d < cdim; ++d) { 856043fa8764SMatthew G. Knepley if (d > 0) {ierr = PetscSynchronizedPrintf(comm, ", ");CHKERRQ(ierr);} 856148afe810SSatish Balay ierr = PetscSynchronizedPrintf(comm, "%g", (double) PetscRealPart(coords[i*cdim+d]));CHKERRQ(ierr); 856243fa8764SMatthew G. Knepley } 856343fa8764SMatthew G. Knepley ierr = PetscSynchronizedPrintf(comm, ")\n");CHKERRQ(ierr); 856443fa8764SMatthew G. Knepley } 856543fa8764SMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &clSize, &closure);CHKERRQ(ierr); 856643fa8764SMatthew G. Knepley for (cl = 0; cl < clSize*2; cl += 2) { 856743fa8764SMatthew G. Knepley const PetscInt edge = closure[cl]; 856843fa8764SMatthew G. Knepley 856943fa8764SMatthew G. Knepley if ((edge >= eStart) && (edge < eEnd)) { 857043fa8764SMatthew G. Knepley PetscReal len; 857143fa8764SMatthew G. Knepley 857243fa8764SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFVM(dm, edge, &len, NULL, NULL);CHKERRQ(ierr); 8573087ef6b2SMatthew G. Knepley ierr = PetscSynchronizedPrintf(comm, " Edge %D: length %g\n", edge, (double) len);CHKERRQ(ierr); 857443fa8764SMatthew G. Knepley } 857543fa8764SMatthew G. Knepley } 857643fa8764SMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &clSize, &closure);CHKERRQ(ierr); 857743fa8764SMatthew G. Knepley ierr = DMPlexVecRestoreClosure(dm, coordSection, coordsLocal, c, &Nv, &coords);CHKERRQ(ierr); 857843fa8764SMatthew G. Knepley } 8579068a5610SStefano Zampini } 85808261a58bSMatthew G. Knepley if (output) {ierr = PetscSynchronizedFlush(comm, NULL);CHKERRQ(ierr);} 8581068a5610SStefano Zampini 8582068a5610SStefano Zampini if (size > 1) { 8583068a5610SStefano Zampini PetscMPIInt blockLengths[2] = {4,1}; 8584068a5610SStefano Zampini MPI_Aint blockOffsets[2] = {offsetof(cell_stats_t,min),offsetof(cell_stats_t,count)}; 8585068a5610SStefano Zampini MPI_Datatype blockTypes[2] = {MPIU_REAL,MPIU_INT}, statType; 8586068a5610SStefano Zampini MPI_Op statReduce; 8587068a5610SStefano Zampini 8588ffc4695bSBarry Smith ierr = MPI_Type_create_struct(2,blockLengths,blockOffsets,blockTypes,&statType);CHKERRMPI(ierr); 8589ffc4695bSBarry Smith ierr = MPI_Type_commit(&statType);CHKERRMPI(ierr); 8590ffc4695bSBarry Smith ierr = MPI_Op_create(cell_stats_reduce, PETSC_TRUE, &statReduce);CHKERRMPI(ierr); 8591ffc4695bSBarry Smith ierr = MPI_Reduce(&stats,&globalStats,1,statType,statReduce,0,comm);CHKERRMPI(ierr); 8592ffc4695bSBarry Smith ierr = MPI_Op_free(&statReduce);CHKERRMPI(ierr); 8593ffc4695bSBarry Smith ierr = MPI_Type_free(&statType);CHKERRMPI(ierr); 8594068a5610SStefano Zampini } else { 8595580bdb30SBarry Smith ierr = PetscArraycpy(&globalStats,&stats,1);CHKERRQ(ierr); 8596068a5610SStefano Zampini } 8597068a5610SStefano Zampini if (!rank) { 8598068a5610SStefano Zampini count = globalStats.count; 8599068a5610SStefano Zampini min = globalStats.min; 8600068a5610SStefano Zampini max = globalStats.max; 8601068a5610SStefano Zampini mean = globalStats.sum / globalStats.count; 8602068a5610SStefano Zampini stdev = globalStats.count > 1 ? PetscSqrtReal(PetscMax((globalStats.squaresum - globalStats.count * mean * mean) / (globalStats.count - 1),0)) : 0.0; 8603068a5610SStefano Zampini } 8604068a5610SStefano Zampini 8605068a5610SStefano Zampini if (output) { 8606068a5610SStefano 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); 8607068a5610SStefano Zampini } 8608068a5610SStefano Zampini ierr = PetscFree2(J,invJ);CHKERRQ(ierr); 8609068a5610SStefano Zampini 8610068a5610SStefano Zampini ierr = DMGetCoarseDM(dm,&dmCoarse);CHKERRQ(ierr); 8611068a5610SStefano Zampini if (dmCoarse) { 8612068a5610SStefano Zampini PetscBool isplex; 8613068a5610SStefano Zampini 8614068a5610SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)dmCoarse,DMPLEX,&isplex);CHKERRQ(ierr); 8615068a5610SStefano Zampini if (isplex) { 861643fa8764SMatthew G. Knepley ierr = DMPlexCheckCellShape(dmCoarse,output,condLimit);CHKERRQ(ierr); 8617068a5610SStefano Zampini } 8618068a5610SStefano Zampini } 8619068a5610SStefano Zampini PetscFunctionReturn(0); 8620068a5610SStefano Zampini } 8621068a5610SStefano Zampini 8622f108dbd7SJacob Faibussowitsch /*@ 8623f108dbd7SJacob Faibussowitsch DMPlexComputeOrthogonalQuality - Compute cell-wise orthogonal quality mesh statistic. Optionally tags all cells with 8624f108dbd7SJacob Faibussowitsch orthogonal quality below given tolerance. 8625f108dbd7SJacob Faibussowitsch 86266ed19f2fSJacob Faibussowitsch Collective on dm 8627f108dbd7SJacob Faibussowitsch 8628f108dbd7SJacob Faibussowitsch Input Parameters: 8629f108dbd7SJacob Faibussowitsch + dm - The DMPlex object 8630f108dbd7SJacob Faibussowitsch . fv - Optional PetscFV object for pre-computed cell/face centroid information 8631f108dbd7SJacob Faibussowitsch - atol - [0, 1] Absolute tolerance for tagging cells. 8632f108dbd7SJacob Faibussowitsch 8633f108dbd7SJacob Faibussowitsch Output Parameters: 8634f108dbd7SJacob Faibussowitsch + OrthQual - Vec containing orthogonal quality per cell 8635f108dbd7SJacob Faibussowitsch - OrthQualLabel - DMLabel tagging cells below atol with DM_ADAPT_REFINE 8636f108dbd7SJacob Faibussowitsch 8637f108dbd7SJacob Faibussowitsch Options Database Keys: 8638f108dbd7SJacob Faibussowitsch + -dm_plex_orthogonal_quality_label_view - view OrthQualLabel if label is requested. Currently only PETSCVIEWERASCII is 8639f108dbd7SJacob Faibussowitsch supported. 8640f108dbd7SJacob Faibussowitsch - -dm_plex_orthogonal_quality_vec_view - view OrthQual vector. 8641f108dbd7SJacob Faibussowitsch 8642f108dbd7SJacob Faibussowitsch Notes: 8643f108dbd7SJacob Faibussowitsch Orthogonal quality is given by the following formula: 8644f108dbd7SJacob Faibussowitsch 8645f108dbd7SJacob Faibussowitsch \min \left[ \frac{A_i \cdot f_i}{\|A_i\| \|f_i\|} , \frac{A_i \cdot c_i}{\|A_i\| \|c_i\|} \right] 8646f108dbd7SJacob Faibussowitsch 8647f108dbd7SJacob 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 8648f108dbd7SJacob Faibussowitsch is the vector from the current cells centroid to the centroid of its i'th neighbor (which shares a face with the 8649f108dbd7SJacob Faibussowitsch current cell). This computes the vector similarity between each cell face and its corresponding neighbor centroid by 8650f108dbd7SJacob Faibussowitsch calculating the cosine of the angle between these vectors. 8651f108dbd7SJacob Faibussowitsch 8652f108dbd7SJacob Faibussowitsch Orthogonal quality ranges from 1 (best) to 0 (worst). 8653f108dbd7SJacob Faibussowitsch 8654f108dbd7SJacob Faibussowitsch This routine is mainly useful for FVM, however is not restricted to only FVM. The PetscFV object is optionally used to check for 8655f108dbd7SJacob Faibussowitsch pre-computed FVM cell data, but if it is not passed in then this data will be computed. 8656f108dbd7SJacob Faibussowitsch 8657f108dbd7SJacob Faibussowitsch Cells are tagged if they have an orthogonal quality less than or equal to the absolute tolerance. 8658f108dbd7SJacob Faibussowitsch 8659f108dbd7SJacob Faibussowitsch Level: intermediate 8660f108dbd7SJacob Faibussowitsch 8661f108dbd7SJacob Faibussowitsch .seealso: DMPlexCheckCellShape(), DMCreateLabel() 8662f108dbd7SJacob Faibussowitsch @*/ 8663f108dbd7SJacob Faibussowitsch PetscErrorCode DMPlexComputeOrthogonalQuality(DM dm, PetscFV fv, PetscReal atol, Vec *OrthQual, DMLabel *OrthQualLabel) 8664f108dbd7SJacob Faibussowitsch { 86656ed19f2fSJacob Faibussowitsch PetscInt nc, cellHeight, cStart, cEnd, cell, cellIter = 0; 86666ed19f2fSJacob Faibussowitsch PetscInt *idx; 86676ed19f2fSJacob Faibussowitsch PetscScalar *oqVals; 8668f108dbd7SJacob Faibussowitsch const PetscScalar *cellGeomArr, *faceGeomArr; 86696ed19f2fSJacob Faibussowitsch PetscReal *ci, *fi, *Ai; 8670f108dbd7SJacob Faibussowitsch MPI_Comm comm; 8671f108dbd7SJacob Faibussowitsch Vec cellgeom, facegeom; 8672f108dbd7SJacob Faibussowitsch DM dmFace, dmCell; 8673f108dbd7SJacob Faibussowitsch IS glob; 8674f108dbd7SJacob Faibussowitsch ISLocalToGlobalMapping ltog; 8675f108dbd7SJacob Faibussowitsch PetscViewer vwr; 8676f108dbd7SJacob Faibussowitsch PetscErrorCode ierr; 8677f108dbd7SJacob Faibussowitsch 8678f108dbd7SJacob Faibussowitsch PetscFunctionBegin; 8679f108dbd7SJacob Faibussowitsch PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 86806ed19f2fSJacob Faibussowitsch if (fv) {PetscValidHeaderSpecific(fv, PETSCFV_CLASSID, 2);} 8681f108dbd7SJacob Faibussowitsch PetscValidPointer(OrthQual, 4); 86826ed19f2fSJacob 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); 8683f108dbd7SJacob Faibussowitsch ierr = PetscObjectGetComm((PetscObject) dm, &comm);CHKERRQ(ierr); 8684f108dbd7SJacob Faibussowitsch ierr = DMGetDimension(dm, &nc);CHKERRQ(ierr); 86856ed19f2fSJacob Faibussowitsch if (nc < 2) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "DM must have dimension >= 2 (current %D)", nc); 86866ed19f2fSJacob Faibussowitsch { 86876ed19f2fSJacob Faibussowitsch DMPlexInterpolatedFlag interpFlag; 86886ed19f2fSJacob Faibussowitsch 8689f108dbd7SJacob Faibussowitsch ierr = DMPlexIsInterpolated(dm, &interpFlag);CHKERRQ(ierr); 8690f108dbd7SJacob Faibussowitsch if (interpFlag != DMPLEX_INTERPOLATED_FULL) { 8691f108dbd7SJacob Faibussowitsch PetscMPIInt rank; 8692f108dbd7SJacob Faibussowitsch 8693ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 8694f108dbd7SJacob Faibussowitsch SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "DM must be fully interpolated, DM on rank %d is not fully interpolated", rank); 8695f108dbd7SJacob Faibussowitsch } 86966ed19f2fSJacob Faibussowitsch } 8697f108dbd7SJacob Faibussowitsch if (OrthQualLabel) { 8698f108dbd7SJacob Faibussowitsch PetscValidPointer(OrthQualLabel, 5); 8699f108dbd7SJacob Faibussowitsch ierr = DMCreateLabel(dm, "Orthogonal_Quality");CHKERRQ(ierr); 8700f108dbd7SJacob Faibussowitsch ierr = DMGetLabel(dm, "Orthogonal_Quality", OrthQualLabel);CHKERRQ(ierr); 87016ed19f2fSJacob Faibussowitsch } else {*OrthQualLabel = NULL;} 8702f108dbd7SJacob Faibussowitsch ierr = DMPlexGetVTKCellHeight(dm, &cellHeight);CHKERRQ(ierr); 8703f108dbd7SJacob Faibussowitsch ierr = DMPlexGetHeightStratum(dm, cellHeight, &cStart, &cEnd);CHKERRQ(ierr); 8704f108dbd7SJacob Faibussowitsch ierr = DMPlexCreateCellNumbering_Internal(dm, PETSC_TRUE, &glob);CHKERRQ(ierr); 8705f108dbd7SJacob Faibussowitsch ierr = ISLocalToGlobalMappingCreateIS(glob, <og);CHKERRQ(ierr); 8706f108dbd7SJacob Faibussowitsch ierr = ISLocalToGlobalMappingSetType(ltog, ISLOCALTOGLOBALMAPPINGHASH);CHKERRQ(ierr); 8707f108dbd7SJacob Faibussowitsch ierr = VecCreate(comm, OrthQual);CHKERRQ(ierr); 8708f108dbd7SJacob Faibussowitsch ierr = VecSetType(*OrthQual, VECSTANDARD);CHKERRQ(ierr); 8709f108dbd7SJacob Faibussowitsch ierr = VecSetSizes(*OrthQual, cEnd-cStart, PETSC_DETERMINE);CHKERRQ(ierr); 8710f108dbd7SJacob Faibussowitsch ierr = VecSetLocalToGlobalMapping(*OrthQual, ltog);CHKERRQ(ierr); 8711f108dbd7SJacob Faibussowitsch ierr = VecSetUp(*OrthQual);CHKERRQ(ierr); 8712f108dbd7SJacob Faibussowitsch ierr = ISDestroy(&glob);CHKERRQ(ierr); 8713f108dbd7SJacob Faibussowitsch ierr = ISLocalToGlobalMappingDestroy(<og);CHKERRQ(ierr); 8714f108dbd7SJacob Faibussowitsch ierr = DMPlexGetDataFVM(dm, fv, &cellgeom, &facegeom, NULL);CHKERRQ(ierr); 8715f108dbd7SJacob Faibussowitsch ierr = VecGetArrayRead(cellgeom, &cellGeomArr);CHKERRQ(ierr); 8716f108dbd7SJacob Faibussowitsch ierr = VecGetArrayRead(facegeom, &faceGeomArr);CHKERRQ(ierr); 8717f108dbd7SJacob Faibussowitsch ierr = VecGetDM(cellgeom, &dmCell);CHKERRQ(ierr); 8718f108dbd7SJacob Faibussowitsch ierr = VecGetDM(facegeom, &dmFace);CHKERRQ(ierr); 87196ed19f2fSJacob Faibussowitsch ierr = PetscMalloc5(cEnd-cStart, &idx, cEnd-cStart, &oqVals, nc, &ci, nc, &fi, nc, &Ai);CHKERRQ(ierr); 87206ed19f2fSJacob Faibussowitsch for (cell = cStart; cell < cEnd; cellIter++,cell++) { 87216ed19f2fSJacob Faibussowitsch PetscInt cellneigh, cellneighiter = 0, adjSize = PETSC_DETERMINE; 8722f108dbd7SJacob Faibussowitsch PetscInt cellarr[2], *adj = NULL; 8723f108dbd7SJacob Faibussowitsch PetscScalar *cArr, *fArr; 8724898cd552SSatish Balay PetscReal minvalc = 1.0, minvalf = 1.0; 8725f108dbd7SJacob Faibussowitsch PetscFVCellGeom *cg; 8726f108dbd7SJacob Faibussowitsch 87276ed19f2fSJacob Faibussowitsch idx[cellIter] = cell-cStart; 8728f108dbd7SJacob Faibussowitsch cellarr[0] = cell; 8729f108dbd7SJacob Faibussowitsch /* Make indexing into cellGeom easier */ 8730f108dbd7SJacob Faibussowitsch ierr = DMPlexPointLocalRead(dmCell, cell, cellGeomArr, &cg);CHKERRQ(ierr); 8731f108dbd7SJacob Faibussowitsch ierr = DMPlexGetAdjacency_Internal(dm, cell, PETSC_TRUE, PETSC_FALSE, PETSC_FALSE, &adjSize, &adj);CHKERRQ(ierr); 8732f108dbd7SJacob Faibussowitsch /* Technically 1 too big, but easier than fiddling with empty adjacency array */ 8733f108dbd7SJacob Faibussowitsch ierr = PetscCalloc2(adjSize, &cArr, adjSize, &fArr);CHKERRQ(ierr); 87346ed19f2fSJacob Faibussowitsch for (cellneigh = 0; cellneigh < adjSize; cellneighiter++,cellneigh++) { 87356ed19f2fSJacob Faibussowitsch PetscInt i; 87366ed19f2fSJacob Faibussowitsch const PetscInt neigh = adj[cellneigh]; 8737f108dbd7SJacob Faibussowitsch PetscReal normci = 0, normfi = 0, normai = 0; 8738f108dbd7SJacob Faibussowitsch PetscFVCellGeom *cgneigh; 8739f108dbd7SJacob Faibussowitsch PetscFVFaceGeom *fg; 8740f108dbd7SJacob Faibussowitsch 8741f108dbd7SJacob Faibussowitsch /* Don't count ourselves in the neighbor list */ 8742f108dbd7SJacob Faibussowitsch if (neigh == cell) continue; 8743f108dbd7SJacob Faibussowitsch ierr = DMPlexPointLocalRead(dmCell, neigh, cellGeomArr, &cgneigh);CHKERRQ(ierr); 8744f108dbd7SJacob Faibussowitsch cellarr[1] = neigh; 87456ed19f2fSJacob Faibussowitsch { 87466ed19f2fSJacob Faibussowitsch PetscInt numcovpts; 87476ed19f2fSJacob Faibussowitsch const PetscInt *covpts; 87486ed19f2fSJacob Faibussowitsch 8749f108dbd7SJacob Faibussowitsch ierr = DMPlexGetMeet(dm, 2, cellarr, &numcovpts, &covpts);CHKERRQ(ierr); 8750f108dbd7SJacob Faibussowitsch ierr = DMPlexPointLocalRead(dmFace, covpts[0], faceGeomArr, &fg);CHKERRQ(ierr); 8751f108dbd7SJacob Faibussowitsch ierr = DMPlexRestoreMeet(dm, 2, cellarr, &numcovpts, &covpts);CHKERRQ(ierr); 87526ed19f2fSJacob Faibussowitsch } 8753f108dbd7SJacob Faibussowitsch 8754f108dbd7SJacob Faibussowitsch /* Compute c_i, f_i and their norms */ 8755f108dbd7SJacob Faibussowitsch for (i = 0; i < nc; i++) { 8756f108dbd7SJacob Faibussowitsch ci[i] = cgneigh->centroid[i] - cg->centroid[i]; 8757f108dbd7SJacob Faibussowitsch fi[i] = fg->centroid[i] - cg->centroid[i]; 8758f108dbd7SJacob Faibussowitsch Ai[i] = fg->normal[i]; 8759addd1e01SJunchao Zhang normci += PetscPowReal(ci[i], 2); 8760addd1e01SJunchao Zhang normfi += PetscPowReal(fi[i], 2); 8761addd1e01SJunchao Zhang normai += PetscPowReal(Ai[i], 2); 8762f108dbd7SJacob Faibussowitsch } 8763addd1e01SJunchao Zhang normci = PetscSqrtReal(normci); 8764addd1e01SJunchao Zhang normfi = PetscSqrtReal(normfi); 8765addd1e01SJunchao Zhang normai = PetscSqrtReal(normai); 8766f108dbd7SJacob Faibussowitsch 8767f108dbd7SJacob Faibussowitsch /* Normalize and compute for each face-cell-normal pair */ 8768f108dbd7SJacob Faibussowitsch for (i = 0; i < nc; i++) { 8769f108dbd7SJacob Faibussowitsch ci[i] = ci[i]/normci; 8770f108dbd7SJacob Faibussowitsch fi[i] = fi[i]/normfi; 8771f108dbd7SJacob Faibussowitsch Ai[i] = Ai[i]/normai; 8772f108dbd7SJacob Faibussowitsch /* PetscAbs because I don't know if normals are guaranteed to point out */ 8773f108dbd7SJacob Faibussowitsch cArr[cellneighiter] += PetscAbs(Ai[i]*ci[i]); 8774f108dbd7SJacob Faibussowitsch fArr[cellneighiter] += PetscAbs(Ai[i]*fi[i]); 8775f108dbd7SJacob Faibussowitsch } 8776f108dbd7SJacob Faibussowitsch if (PetscRealPart(cArr[cellneighiter]) < minvalc) { 8777f108dbd7SJacob Faibussowitsch minvalc = PetscRealPart(cArr[cellneighiter]); 8778f108dbd7SJacob Faibussowitsch } 8779f108dbd7SJacob Faibussowitsch if (PetscRealPart(fArr[cellneighiter]) < minvalf) { 8780f108dbd7SJacob Faibussowitsch minvalf = PetscRealPart(fArr[cellneighiter]); 8781f108dbd7SJacob Faibussowitsch } 8782f108dbd7SJacob Faibussowitsch } 8783f108dbd7SJacob Faibussowitsch ierr = PetscFree(adj);CHKERRQ(ierr); 8784f108dbd7SJacob Faibussowitsch ierr = PetscFree2(cArr, fArr);CHKERRQ(ierr); 8785f108dbd7SJacob Faibussowitsch /* Defer to cell if they're equal */ 87866ed19f2fSJacob Faibussowitsch oqVals[cellIter] = PetscMin(minvalf, minvalc); 8787f108dbd7SJacob Faibussowitsch if (OrthQualLabel) { 87886ed19f2fSJacob Faibussowitsch if (PetscRealPart(oqVals[cellIter]) <= atol) {ierr = DMLabelSetValue(*OrthQualLabel, cell, DM_ADAPT_REFINE);CHKERRQ(ierr);} 8789f108dbd7SJacob Faibussowitsch } 8790f108dbd7SJacob Faibussowitsch } 87916ed19f2fSJacob Faibussowitsch ierr = VecSetValuesLocal(*OrthQual, cEnd-cStart, idx, oqVals, INSERT_VALUES);CHKERRQ(ierr); 8792f108dbd7SJacob Faibussowitsch ierr = VecAssemblyBegin(*OrthQual);CHKERRQ(ierr); 8793f108dbd7SJacob Faibussowitsch ierr = VecAssemblyEnd(*OrthQual);CHKERRQ(ierr); 8794f108dbd7SJacob Faibussowitsch ierr = VecRestoreArrayRead(cellgeom, &cellGeomArr);CHKERRQ(ierr); 8795f108dbd7SJacob Faibussowitsch ierr = VecRestoreArrayRead(facegeom, &faceGeomArr);CHKERRQ(ierr); 8796f108dbd7SJacob Faibussowitsch ierr = PetscOptionsGetViewer(comm, NULL, NULL, "-dm_plex_orthogonal_quality_label_view", &vwr, NULL, NULL);CHKERRQ(ierr); 8797f108dbd7SJacob Faibussowitsch if (OrthQualLabel) { 87986ed19f2fSJacob Faibussowitsch if (vwr) {ierr = DMLabelView(*OrthQualLabel, vwr);CHKERRQ(ierr);} 8799f108dbd7SJacob Faibussowitsch } 88006ed19f2fSJacob Faibussowitsch ierr = PetscFree5(idx, oqVals, ci, fi, Ai);CHKERRQ(ierr); 8801f108dbd7SJacob Faibussowitsch ierr = PetscViewerDestroy(&vwr);CHKERRQ(ierr); 8802f108dbd7SJacob Faibussowitsch ierr = VecViewFromOptions(*OrthQual, NULL, "-dm_plex_orthogonal_quality_vec_view");CHKERRQ(ierr); 8803f108dbd7SJacob Faibussowitsch PetscFunctionReturn(0); 8804f108dbd7SJacob Faibussowitsch } 8805f108dbd7SJacob Faibussowitsch 88061eb70e55SToby Isaac /* this is here insead of DMGetOutputDM because output DM still has constraints in the local indices that affect 88071eb70e55SToby Isaac * interpolator construction */ 88081eb70e55SToby Isaac static PetscErrorCode DMGetFullDM(DM dm, DM *odm) 88091eb70e55SToby Isaac { 88101eb70e55SToby Isaac PetscSection section, newSection, gsection; 88111eb70e55SToby Isaac PetscSF sf; 88121eb70e55SToby Isaac PetscBool hasConstraints, ghasConstraints; 88131eb70e55SToby Isaac PetscErrorCode ierr; 88141eb70e55SToby Isaac 88151eb70e55SToby Isaac PetscFunctionBegin; 88161eb70e55SToby Isaac PetscValidHeaderSpecific(dm,DM_CLASSID,1); 88171eb70e55SToby Isaac PetscValidPointer(odm,2); 88181eb70e55SToby Isaac ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr); 88191eb70e55SToby Isaac ierr = PetscSectionHasConstraints(section, &hasConstraints);CHKERRQ(ierr); 88201eb70e55SToby Isaac ierr = MPI_Allreduce(&hasConstraints, &ghasConstraints, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject) dm));CHKERRMPI(ierr); 88211eb70e55SToby Isaac if (!ghasConstraints) { 88221eb70e55SToby Isaac ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 88231eb70e55SToby Isaac *odm = dm; 88241eb70e55SToby Isaac PetscFunctionReturn(0); 88251eb70e55SToby Isaac } 88261eb70e55SToby Isaac ierr = DMClone(dm, odm);CHKERRQ(ierr); 88271eb70e55SToby Isaac ierr = DMCopyFields(dm, *odm);CHKERRQ(ierr); 88281eb70e55SToby Isaac ierr = DMGetLocalSection(*odm, &newSection);CHKERRQ(ierr); 88291eb70e55SToby Isaac ierr = DMGetPointSF(*odm, &sf);CHKERRQ(ierr); 88301eb70e55SToby Isaac ierr = PetscSectionCreateGlobalSection(newSection, sf, PETSC_TRUE, PETSC_FALSE, &gsection);CHKERRQ(ierr); 88311eb70e55SToby Isaac ierr = DMSetGlobalSection(*odm, gsection);CHKERRQ(ierr); 88321eb70e55SToby Isaac ierr = PetscSectionDestroy(&gsection);CHKERRQ(ierr); 88331eb70e55SToby Isaac PetscFunctionReturn(0); 88341eb70e55SToby Isaac } 88351eb70e55SToby Isaac 88361eb70e55SToby Isaac static PetscErrorCode DMCreateAffineInterpolationCorrection_Plex(DM dmc, DM dmf, Vec *shift) 88371eb70e55SToby Isaac { 88381eb70e55SToby Isaac DM dmco, dmfo; 88391eb70e55SToby Isaac Mat interpo; 88401eb70e55SToby Isaac Vec rscale; 88411eb70e55SToby Isaac Vec cglobalo, clocal; 88421eb70e55SToby Isaac Vec fglobal, fglobalo, flocal; 88431eb70e55SToby Isaac PetscBool regular; 88441eb70e55SToby Isaac PetscErrorCode ierr; 88451eb70e55SToby Isaac 88461eb70e55SToby Isaac PetscFunctionBegin; 88471eb70e55SToby Isaac ierr = DMGetFullDM(dmc, &dmco);CHKERRQ(ierr); 88481eb70e55SToby Isaac ierr = DMGetFullDM(dmf, &dmfo);CHKERRQ(ierr); 88491eb70e55SToby Isaac ierr = DMSetCoarseDM(dmfo, dmco);CHKERRQ(ierr); 88501eb70e55SToby Isaac ierr = DMPlexGetRegularRefinement(dmf, ®ular);CHKERRQ(ierr); 88511eb70e55SToby Isaac ierr = DMPlexSetRegularRefinement(dmfo, regular);CHKERRQ(ierr); 88521eb70e55SToby Isaac ierr = DMCreateInterpolation(dmco, dmfo, &interpo, &rscale);CHKERRQ(ierr); 88531eb70e55SToby Isaac ierr = DMCreateGlobalVector(dmco, &cglobalo);CHKERRQ(ierr); 88541eb70e55SToby Isaac ierr = DMCreateLocalVector(dmc, &clocal);CHKERRQ(ierr); 88551eb70e55SToby Isaac ierr = VecSet(cglobalo, 0.);CHKERRQ(ierr); 88561eb70e55SToby Isaac ierr = VecSet(clocal, 0.);CHKERRQ(ierr); 88571eb70e55SToby Isaac ierr = DMCreateGlobalVector(dmf, &fglobal);CHKERRQ(ierr); 88581eb70e55SToby Isaac ierr = DMCreateGlobalVector(dmfo, &fglobalo);CHKERRQ(ierr); 88591eb70e55SToby Isaac ierr = DMCreateLocalVector(dmf, &flocal);CHKERRQ(ierr); 88601eb70e55SToby Isaac ierr = VecSet(fglobal, 0.);CHKERRQ(ierr); 88611eb70e55SToby Isaac ierr = VecSet(fglobalo, 0.);CHKERRQ(ierr); 88621eb70e55SToby Isaac ierr = VecSet(flocal, 0.);CHKERRQ(ierr); 88631eb70e55SToby Isaac ierr = DMPlexInsertBoundaryValues(dmc, PETSC_TRUE, clocal, 0., NULL, NULL, NULL);CHKERRQ(ierr); 88641eb70e55SToby Isaac ierr = DMLocalToGlobalBegin(dmco, clocal, INSERT_VALUES, cglobalo);CHKERRQ(ierr); 88651eb70e55SToby Isaac ierr = DMLocalToGlobalEnd(dmco, clocal, INSERT_VALUES, cglobalo);CHKERRQ(ierr); 88661eb70e55SToby Isaac ierr = MatMult(interpo, cglobalo, fglobalo);CHKERRQ(ierr); 88671eb70e55SToby Isaac ierr = DMGlobalToLocalBegin(dmfo, fglobalo, INSERT_VALUES, flocal);CHKERRQ(ierr); 88681eb70e55SToby Isaac ierr = DMGlobalToLocalEnd(dmfo, fglobalo, INSERT_VALUES, flocal);CHKERRQ(ierr); 88691eb70e55SToby Isaac ierr = DMLocalToGlobalBegin(dmf, flocal, INSERT_VALUES, fglobal);CHKERRQ(ierr); 88701eb70e55SToby Isaac ierr = DMLocalToGlobalEnd(dmf, flocal, INSERT_VALUES, fglobal);CHKERRQ(ierr); 88711eb70e55SToby Isaac *shift = fglobal; 88721eb70e55SToby Isaac ierr = VecDestroy(&flocal);CHKERRQ(ierr); 88731eb70e55SToby Isaac ierr = VecDestroy(&fglobalo);CHKERRQ(ierr); 88741eb70e55SToby Isaac ierr = VecDestroy(&clocal);CHKERRQ(ierr); 88751eb70e55SToby Isaac ierr = VecDestroy(&cglobalo);CHKERRQ(ierr); 88761eb70e55SToby Isaac ierr = VecDestroy(&rscale);CHKERRQ(ierr); 88771eb70e55SToby Isaac ierr = MatDestroy(&interpo);CHKERRQ(ierr); 88781eb70e55SToby Isaac ierr = DMDestroy(&dmfo);CHKERRQ(ierr); 88791eb70e55SToby Isaac ierr = DMDestroy(&dmco);CHKERRQ(ierr); 88801eb70e55SToby Isaac PetscFunctionReturn(0); 88811eb70e55SToby Isaac } 88821eb70e55SToby Isaac 88831eb70e55SToby Isaac PETSC_INTERN PetscErrorCode DMInterpolateSolution_Plex(DM coarse, DM fine, Mat interp, Vec coarseSol, Vec fineSol) 88841eb70e55SToby Isaac { 88851eb70e55SToby Isaac PetscObject shifto; 88861eb70e55SToby Isaac Vec shift; 88871eb70e55SToby Isaac 88881eb70e55SToby Isaac PetscErrorCode ierr; 88891eb70e55SToby Isaac 88901eb70e55SToby Isaac PetscFunctionBegin; 88911eb70e55SToby Isaac if (!interp) { 88921eb70e55SToby Isaac Vec rscale; 88931eb70e55SToby Isaac 88941eb70e55SToby Isaac ierr = DMCreateInterpolation(coarse, fine, &interp, &rscale);CHKERRQ(ierr); 88951eb70e55SToby Isaac ierr = VecDestroy(&rscale);CHKERRQ(ierr); 88961eb70e55SToby Isaac } else { 88971eb70e55SToby Isaac ierr = PetscObjectReference((PetscObject)interp);CHKERRQ(ierr); 88981eb70e55SToby Isaac } 88991eb70e55SToby Isaac ierr = PetscObjectQuery((PetscObject)interp, "_DMInterpolateSolution_Plex_Vec", &shifto);CHKERRQ(ierr); 89001eb70e55SToby Isaac if (!shifto) { 89011eb70e55SToby Isaac ierr = DMCreateAffineInterpolationCorrection_Plex(coarse, fine, &shift);CHKERRQ(ierr); 89021eb70e55SToby Isaac ierr = PetscObjectCompose((PetscObject)interp, "_DMInterpolateSolution_Plex_Vec", (PetscObject) shift);CHKERRQ(ierr); 89031eb70e55SToby Isaac shifto = (PetscObject) shift; 89041eb70e55SToby Isaac ierr = VecDestroy(&shift);CHKERRQ(ierr); 89051eb70e55SToby Isaac } 89061eb70e55SToby Isaac shift = (Vec) shifto; 89071eb70e55SToby Isaac ierr = MatInterpolate(interp, coarseSol, fineSol);CHKERRQ(ierr); 89081eb70e55SToby Isaac ierr = VecAXPY(fineSol, 1.0, shift);CHKERRQ(ierr); 89091eb70e55SToby Isaac ierr = MatDestroy(&interp);CHKERRQ(ierr); 89101eb70e55SToby Isaac PetscFunctionReturn(0); 89111eb70e55SToby Isaac } 89121eb70e55SToby Isaac 8913bceba477SMatthew G. Knepley /* Pointwise interpolation 8914bceba477SMatthew G. Knepley Just code FEM for now 8915bceba477SMatthew G. Knepley u^f = I u^c 89164ca5e9f5SMatthew G. Knepley sum_k u^f_k phi^f_k = I sum_j u^c_j phi^c_j 89174ca5e9f5SMatthew G. Knepley u^f_i = sum_j psi^f_i I phi^c_j u^c_j 89184ca5e9f5SMatthew G. Knepley I_{ij} = psi^f_i phi^c_j 8919bceba477SMatthew G. Knepley */ 8920bceba477SMatthew G. Knepley PetscErrorCode DMCreateInterpolation_Plex(DM dmCoarse, DM dmFine, Mat *interpolation, Vec *scaling) 8921bceba477SMatthew G. Knepley { 8922bceba477SMatthew G. Knepley PetscSection gsc, gsf; 8923bceba477SMatthew G. Knepley PetscInt m, n; 8924a063dac3SMatthew G. Knepley void *ctx; 892568132eb9SMatthew G. Knepley DM cdm; 8926cf51de39SMatthew G. Knepley PetscBool regular, ismatis, isRefined = dmCoarse->data == dmFine->data ? PETSC_FALSE : PETSC_TRUE; 8927bceba477SMatthew G. Knepley PetscErrorCode ierr; 8928bceba477SMatthew G. Knepley 8929bceba477SMatthew G. Knepley PetscFunctionBegin; 8930e87a4003SBarry Smith ierr = DMGetGlobalSection(dmFine, &gsf);CHKERRQ(ierr); 8931bceba477SMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(gsf, &m);CHKERRQ(ierr); 8932e87a4003SBarry Smith ierr = DMGetGlobalSection(dmCoarse, &gsc);CHKERRQ(ierr); 8933bceba477SMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(gsc, &n);CHKERRQ(ierr); 893468132eb9SMatthew G. Knepley 8935fd194bc8SStefano Zampini ierr = PetscStrcmp(dmCoarse->mattype, MATIS, &ismatis);CHKERRQ(ierr); 8936bceba477SMatthew G. Knepley ierr = MatCreate(PetscObjectComm((PetscObject) dmCoarse), interpolation);CHKERRQ(ierr); 8937bceba477SMatthew G. Knepley ierr = MatSetSizes(*interpolation, m, n, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 8938fd194bc8SStefano Zampini ierr = MatSetType(*interpolation, ismatis ? MATAIJ : dmCoarse->mattype);CHKERRQ(ierr); 8939a063dac3SMatthew G. Knepley ierr = DMGetApplicationContext(dmFine, &ctx);CHKERRQ(ierr); 894068132eb9SMatthew G. Knepley 8941a8fb8f29SToby Isaac ierr = DMGetCoarseDM(dmFine, &cdm);CHKERRQ(ierr); 894268132eb9SMatthew G. Knepley ierr = DMPlexGetRegularRefinement(dmFine, ®ular);CHKERRQ(ierr); 8943cf51de39SMatthew G. Knepley if (!isRefined || (regular && cdm == dmCoarse)) {ierr = DMPlexComputeInterpolatorNested(dmCoarse, dmFine, isRefined, *interpolation, ctx);CHKERRQ(ierr);} 894468132eb9SMatthew G. Knepley else {ierr = DMPlexComputeInterpolatorGeneral(dmCoarse, dmFine, *interpolation, ctx);CHKERRQ(ierr);} 894568132eb9SMatthew G. Knepley ierr = MatViewFromOptions(*interpolation, NULL, "-interp_mat_view");CHKERRQ(ierr); 89464db47ee9SStefano Zampini if (scaling) { 89475d1c2e58SMatthew G. Knepley /* Use naive scaling */ 89485d1c2e58SMatthew G. Knepley ierr = DMCreateInterpolationScale(dmCoarse, dmFine, *interpolation, scaling);CHKERRQ(ierr); 89494db47ee9SStefano Zampini } 8950a063dac3SMatthew G. Knepley PetscFunctionReturn(0); 8951a063dac3SMatthew G. Knepley } 8952bceba477SMatthew G. Knepley 89536dbf9973SLawrence Mitchell PetscErrorCode DMCreateInjection_Plex(DM dmCoarse, DM dmFine, Mat *mat) 8954a063dac3SMatthew G. Knepley { 895590748bafSMatthew G. Knepley PetscErrorCode ierr; 89566dbf9973SLawrence Mitchell VecScatter ctx; 895790748bafSMatthew G. Knepley 8958a063dac3SMatthew G. Knepley PetscFunctionBegin; 89596dbf9973SLawrence Mitchell ierr = DMPlexComputeInjectorFEM(dmCoarse, dmFine, &ctx, NULL);CHKERRQ(ierr); 89606dbf9973SLawrence Mitchell ierr = MatCreateScatter(PetscObjectComm((PetscObject)ctx), ctx, mat);CHKERRQ(ierr); 89616dbf9973SLawrence Mitchell ierr = VecScatterDestroy(&ctx);CHKERRQ(ierr); 8962bceba477SMatthew G. Knepley PetscFunctionReturn(0); 8963bceba477SMatthew G. Knepley } 8964bceba477SMatthew G. Knepley 89653e9753d6SMatthew G. Knepley static void g0_identity_private(PetscInt dim, PetscInt Nf, PetscInt NfAux, 89663e9753d6SMatthew G. Knepley const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 89673e9753d6SMatthew G. Knepley const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 89683e9753d6SMatthew G. Knepley PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]) 89693e9753d6SMatthew G. Knepley { 89703e9753d6SMatthew G. Knepley g0[0] = 1.0; 89713e9753d6SMatthew G. Knepley } 89723e9753d6SMatthew G. Knepley 8973bd041c0cSMatthew G. Knepley PetscErrorCode DMCreateMassMatrix_Plex(DM dmCoarse, DM dmFine, Mat *mass) 8974bd041c0cSMatthew G. Knepley { 8975bd041c0cSMatthew G. Knepley PetscSection gsc, gsf; 8976bd041c0cSMatthew G. Knepley PetscInt m, n; 8977bd041c0cSMatthew G. Knepley void *ctx; 8978bd041c0cSMatthew G. Knepley DM cdm; 8979bd041c0cSMatthew G. Knepley PetscBool regular; 8980bd041c0cSMatthew G. Knepley PetscErrorCode ierr; 8981bd041c0cSMatthew G. Knepley 8982bd041c0cSMatthew G. Knepley PetscFunctionBegin; 89833e9753d6SMatthew G. Knepley if (dmFine == dmCoarse) { 89843e9753d6SMatthew G. Knepley DM dmc; 89853e9753d6SMatthew G. Knepley PetscDS ds; 89863e9753d6SMatthew G. Knepley Vec u; 89873e9753d6SMatthew G. Knepley IS cellIS; 898806ad1575SMatthew G. Knepley PetscFormKey key; 89893e9753d6SMatthew G. Knepley PetscInt depth; 89903e9753d6SMatthew G. Knepley 89913e9753d6SMatthew G. Knepley ierr = DMClone(dmFine, &dmc);CHKERRQ(ierr); 89923e9753d6SMatthew G. Knepley ierr = DMCopyDisc(dmFine, dmc);CHKERRQ(ierr); 89933e9753d6SMatthew G. Knepley ierr = DMGetDS(dmc, &ds);CHKERRQ(ierr); 89943e9753d6SMatthew G. Knepley ierr = PetscDSSetJacobian(ds, 0, 0, g0_identity_private, NULL, NULL, NULL);CHKERRQ(ierr); 89953e9753d6SMatthew G. Knepley ierr = DMCreateMatrix(dmc, mass);CHKERRQ(ierr); 89963e9753d6SMatthew G. Knepley ierr = DMGetGlobalVector(dmc, &u);CHKERRQ(ierr); 89973e9753d6SMatthew G. Knepley ierr = DMPlexGetDepth(dmc, &depth);CHKERRQ(ierr); 89983e9753d6SMatthew G. Knepley ierr = DMGetStratumIS(dmc, "depth", depth, &cellIS);CHKERRQ(ierr); 89993e9753d6SMatthew G. Knepley ierr = MatZeroEntries(*mass);CHKERRQ(ierr); 90006528b96dSMatthew G. Knepley key.label = NULL; 90016528b96dSMatthew G. Knepley key.value = 0; 90026528b96dSMatthew G. Knepley key.field = 0; 900306ad1575SMatthew G. Knepley key.part = 0; 90046528b96dSMatthew G. Knepley ierr = DMPlexComputeJacobian_Internal(dmc, key, cellIS, 0.0, 0.0, u, NULL, *mass, *mass, NULL);CHKERRQ(ierr); 90053e9753d6SMatthew G. Knepley ierr = ISDestroy(&cellIS);CHKERRQ(ierr); 90063e9753d6SMatthew G. Knepley ierr = DMRestoreGlobalVector(dmc, &u);CHKERRQ(ierr); 90073e9753d6SMatthew G. Knepley ierr = DMDestroy(&dmc);CHKERRQ(ierr); 90083e9753d6SMatthew G. Knepley } else { 9009e87a4003SBarry Smith ierr = DMGetGlobalSection(dmFine, &gsf);CHKERRQ(ierr); 9010bd041c0cSMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(gsf, &m);CHKERRQ(ierr); 9011e87a4003SBarry Smith ierr = DMGetGlobalSection(dmCoarse, &gsc);CHKERRQ(ierr); 9012bd041c0cSMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(gsc, &n);CHKERRQ(ierr); 9013bd041c0cSMatthew G. Knepley 9014bd041c0cSMatthew G. Knepley ierr = MatCreate(PetscObjectComm((PetscObject) dmCoarse), mass);CHKERRQ(ierr); 9015bd041c0cSMatthew G. Knepley ierr = MatSetSizes(*mass, m, n, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 9016bd041c0cSMatthew G. Knepley ierr = MatSetType(*mass, dmCoarse->mattype);CHKERRQ(ierr); 9017bd041c0cSMatthew G. Knepley ierr = DMGetApplicationContext(dmFine, &ctx);CHKERRQ(ierr); 9018bd041c0cSMatthew G. Knepley 9019bd041c0cSMatthew G. Knepley ierr = DMGetCoarseDM(dmFine, &cdm);CHKERRQ(ierr); 9020bd041c0cSMatthew G. Knepley ierr = DMPlexGetRegularRefinement(dmFine, ®ular);CHKERRQ(ierr); 9021bd041c0cSMatthew G. Knepley if (regular && cdm == dmCoarse) {ierr = DMPlexComputeMassMatrixNested(dmCoarse, dmFine, *mass, ctx);CHKERRQ(ierr);} 9022bd041c0cSMatthew G. Knepley else {ierr = DMPlexComputeMassMatrixGeneral(dmCoarse, dmFine, *mass, ctx);CHKERRQ(ierr);} 90233e9753d6SMatthew G. Knepley } 9024bd041c0cSMatthew G. Knepley ierr = MatViewFromOptions(*mass, NULL, "-mass_mat_view");CHKERRQ(ierr); 9025bd041c0cSMatthew G. Knepley PetscFunctionReturn(0); 9026bd041c0cSMatthew G. Knepley } 9027bd041c0cSMatthew G. Knepley 90280aef6b92SMatthew G. Knepley /*@ 90290aef6b92SMatthew G. Knepley DMPlexGetRegularRefinement - Get the flag indicating that this mesh was obtained by regular refinement from its coarse mesh 90300aef6b92SMatthew G. Knepley 90310aef6b92SMatthew G. Knepley Input Parameter: 90320aef6b92SMatthew G. Knepley . dm - The DMPlex object 90330aef6b92SMatthew G. Knepley 90340aef6b92SMatthew G. Knepley Output Parameter: 90350aef6b92SMatthew G. Knepley . regular - The flag 90360aef6b92SMatthew G. Knepley 90370aef6b92SMatthew G. Knepley Level: intermediate 90380aef6b92SMatthew G. Knepley 90390aef6b92SMatthew G. Knepley .seealso: DMPlexSetRegularRefinement() 90400aef6b92SMatthew G. Knepley @*/ 90410aef6b92SMatthew G. Knepley PetscErrorCode DMPlexGetRegularRefinement(DM dm, PetscBool *regular) 90420aef6b92SMatthew G. Knepley { 90430aef6b92SMatthew G. Knepley PetscFunctionBegin; 90440aef6b92SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 90450aef6b92SMatthew G. Knepley PetscValidPointer(regular, 2); 90460aef6b92SMatthew G. Knepley *regular = ((DM_Plex *) dm->data)->regularRefinement; 90470aef6b92SMatthew G. Knepley PetscFunctionReturn(0); 90480aef6b92SMatthew G. Knepley } 90490aef6b92SMatthew G. Knepley 90500aef6b92SMatthew G. Knepley /*@ 90510aef6b92SMatthew G. Knepley DMPlexSetRegularRefinement - Set the flag indicating that this mesh was obtained by regular refinement from its coarse mesh 90520aef6b92SMatthew G. Knepley 90530aef6b92SMatthew G. Knepley Input Parameters: 90540aef6b92SMatthew G. Knepley + dm - The DMPlex object 90550aef6b92SMatthew G. Knepley - regular - The flag 90560aef6b92SMatthew G. Knepley 90570aef6b92SMatthew G. Knepley Level: intermediate 90580aef6b92SMatthew G. Knepley 90590aef6b92SMatthew G. Knepley .seealso: DMPlexGetRegularRefinement() 90600aef6b92SMatthew G. Knepley @*/ 90610aef6b92SMatthew G. Knepley PetscErrorCode DMPlexSetRegularRefinement(DM dm, PetscBool regular) 90620aef6b92SMatthew G. Knepley { 90630aef6b92SMatthew G. Knepley PetscFunctionBegin; 90640aef6b92SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 90650aef6b92SMatthew G. Knepley ((DM_Plex *) dm->data)->regularRefinement = regular; 90660aef6b92SMatthew G. Knepley PetscFunctionReturn(0); 90670aef6b92SMatthew G. Knepley } 90680aef6b92SMatthew G. Knepley 9069412e9a14SMatthew G. Knepley /*@ 9070412e9a14SMatthew G. Knepley DMPlexGetCellRefinerType - Get the strategy for refining a cell 9071412e9a14SMatthew G. Knepley 9072412e9a14SMatthew G. Knepley Input Parameter: 9073412e9a14SMatthew G. Knepley . dm - The DMPlex object 9074412e9a14SMatthew G. Knepley 9075412e9a14SMatthew G. Knepley Output Parameter: 9076412e9a14SMatthew G. Knepley . cr - The strategy number 9077412e9a14SMatthew G. Knepley 9078412e9a14SMatthew G. Knepley Level: intermediate 9079412e9a14SMatthew G. Knepley 9080412e9a14SMatthew G. Knepley .seealso: DMPlexSetCellRefinerType(), DMPlexSetRegularRefinement() 9081412e9a14SMatthew G. Knepley @*/ 9082412e9a14SMatthew G. Knepley PetscErrorCode DMPlexGetCellRefinerType(DM dm, DMPlexCellRefinerType *cr) 9083412e9a14SMatthew G. Knepley { 9084412e9a14SMatthew G. Knepley PetscFunctionBegin; 9085412e9a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9086412e9a14SMatthew G. Knepley PetscValidPointer(cr, 2); 9087412e9a14SMatthew G. Knepley *cr = ((DM_Plex *) dm->data)->cellRefiner; 9088412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 9089412e9a14SMatthew G. Knepley } 9090412e9a14SMatthew G. Knepley 9091412e9a14SMatthew G. Knepley /*@ 9092412e9a14SMatthew G. Knepley DMPlexSetCellRefinerType - Set the strategy for refining a cell 9093412e9a14SMatthew G. Knepley 9094412e9a14SMatthew G. Knepley Input Parameters: 9095412e9a14SMatthew G. Knepley + dm - The DMPlex object 9096412e9a14SMatthew G. Knepley - cr - The strategy number 9097412e9a14SMatthew G. Knepley 9098412e9a14SMatthew G. Knepley Level: intermediate 9099412e9a14SMatthew G. Knepley 9100412e9a14SMatthew G. Knepley .seealso: DMPlexGetCellRefinerType(), DMPlexGetRegularRefinement() 9101412e9a14SMatthew G. Knepley @*/ 9102412e9a14SMatthew G. Knepley PetscErrorCode DMPlexSetCellRefinerType(DM dm, DMPlexCellRefinerType cr) 9103412e9a14SMatthew G. Knepley { 9104412e9a14SMatthew G. Knepley PetscFunctionBegin; 9105412e9a14SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9106412e9a14SMatthew G. Knepley ((DM_Plex *) dm->data)->cellRefiner = cr; 9107412e9a14SMatthew G. Knepley PetscFunctionReturn(0); 9108412e9a14SMatthew G. Knepley } 9109412e9a14SMatthew G. Knepley 9110f7c74593SToby Isaac /* anchors */ 9111a68b90caSToby Isaac /*@ 9112f7c74593SToby Isaac DMPlexGetAnchors - Get the layout of the anchor (point-to-point) constraints. Typically, the user will not have to 9113f7c74593SToby Isaac call DMPlexGetAnchors() directly: if there are anchors, then DMPlexGetAnchors() is called during DMGetConstraints(). 9114a68b90caSToby Isaac 9115e228b242SToby Isaac not collective 9116a68b90caSToby Isaac 9117a68b90caSToby Isaac Input Parameters: 9118a68b90caSToby Isaac . dm - The DMPlex object 9119a68b90caSToby Isaac 9120a68b90caSToby Isaac Output Parameters: 9121a68b90caSToby Isaac + anchorSection - If not NULL, set to the section describing which points anchor the constrained points. 9122a68b90caSToby Isaac - anchorIS - If not NULL, set to the list of anchors indexed by anchorSection 9123a68b90caSToby Isaac 9124a68b90caSToby Isaac Level: intermediate 9125a68b90caSToby Isaac 9126f7c74593SToby Isaac .seealso: DMPlexSetAnchors(), DMGetConstraints(), DMSetConstraints() 9127a68b90caSToby Isaac @*/ 9128a17985deSToby Isaac PetscErrorCode DMPlexGetAnchors(DM dm, PetscSection *anchorSection, IS *anchorIS) 9129a68b90caSToby Isaac { 9130a68b90caSToby Isaac DM_Plex *plex = (DM_Plex *)dm->data; 913141e6d900SToby Isaac PetscErrorCode ierr; 9132a68b90caSToby Isaac 9133a68b90caSToby Isaac PetscFunctionBegin; 9134a68b90caSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 913541e6d900SToby Isaac if (!plex->anchorSection && !plex->anchorIS && plex->createanchors) {ierr = (*plex->createanchors)(dm);CHKERRQ(ierr);} 9136a68b90caSToby Isaac if (anchorSection) *anchorSection = plex->anchorSection; 9137a68b90caSToby Isaac if (anchorIS) *anchorIS = plex->anchorIS; 9138a68b90caSToby Isaac PetscFunctionReturn(0); 9139a68b90caSToby Isaac } 9140a68b90caSToby Isaac 9141a68b90caSToby Isaac /*@ 9142f7c74593SToby Isaac DMPlexSetAnchors - Set the layout of the local anchor (point-to-point) constraints. Unlike boundary conditions, 9143f7c74593SToby Isaac when a point's degrees of freedom in a section are constrained to an outside value, the anchor constraints set a 9144a68b90caSToby Isaac point's degrees of freedom to be a linear combination of other points' degrees of freedom. 9145a68b90caSToby Isaac 9146a17985deSToby Isaac After specifying the layout of constraints with DMPlexSetAnchors(), one specifies the constraints by calling 9147f7c74593SToby Isaac DMGetConstraints() and filling in the entries in the constraint matrix. 9148a68b90caSToby Isaac 9149e228b242SToby Isaac collective on dm 9150a68b90caSToby Isaac 9151a68b90caSToby Isaac Input Parameters: 9152a68b90caSToby Isaac + dm - The DMPlex object 9153e228b242SToby 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). 9154e228b242SToby Isaac - anchorIS - The list of all anchor points. Must have a local communicator (PETSC_COMM_SELF or derivative). 9155a68b90caSToby Isaac 9156a68b90caSToby Isaac The reference counts of anchorSection and anchorIS are incremented. 9157a68b90caSToby Isaac 9158a68b90caSToby Isaac Level: intermediate 9159a68b90caSToby Isaac 9160f7c74593SToby Isaac .seealso: DMPlexGetAnchors(), DMGetConstraints(), DMSetConstraints() 9161a68b90caSToby Isaac @*/ 9162a17985deSToby Isaac PetscErrorCode DMPlexSetAnchors(DM dm, PetscSection anchorSection, IS anchorIS) 9163a68b90caSToby Isaac { 9164a68b90caSToby Isaac DM_Plex *plex = (DM_Plex *)dm->data; 9165e228b242SToby Isaac PetscMPIInt result; 9166a68b90caSToby Isaac PetscErrorCode ierr; 9167a68b90caSToby Isaac 9168a68b90caSToby Isaac PetscFunctionBegin; 9169a68b90caSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9170e228b242SToby Isaac if (anchorSection) { 9171e228b242SToby Isaac PetscValidHeaderSpecific(anchorSection,PETSC_SECTION_CLASSID,2); 9172ffc4695bSBarry Smith ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)anchorSection),&result);CHKERRMPI(ierr); 9173f6a3d38cSToby Isaac if (result != MPI_CONGRUENT && result != MPI_IDENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"anchor section must have local communicator"); 9174e228b242SToby Isaac } 9175e228b242SToby Isaac if (anchorIS) { 9176e228b242SToby Isaac PetscValidHeaderSpecific(anchorIS,IS_CLASSID,3); 9177ffc4695bSBarry Smith ierr = MPI_Comm_compare(PETSC_COMM_SELF,PetscObjectComm((PetscObject)anchorIS),&result);CHKERRMPI(ierr); 9178f6a3d38cSToby Isaac if (result != MPI_CONGRUENT && result != MPI_IDENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"anchor IS must have local communicator"); 9179e228b242SToby Isaac } 9180a68b90caSToby Isaac 9181a68b90caSToby Isaac ierr = PetscObjectReference((PetscObject)anchorSection);CHKERRQ(ierr); 9182a68b90caSToby Isaac ierr = PetscSectionDestroy(&plex->anchorSection);CHKERRQ(ierr); 9183a68b90caSToby Isaac plex->anchorSection = anchorSection; 9184a68b90caSToby Isaac 9185a68b90caSToby Isaac ierr = PetscObjectReference((PetscObject)anchorIS);CHKERRQ(ierr); 9186a68b90caSToby Isaac ierr = ISDestroy(&plex->anchorIS);CHKERRQ(ierr); 9187a68b90caSToby Isaac plex->anchorIS = anchorIS; 9188a68b90caSToby Isaac 9189cf9c20a2SJed Brown if (PetscUnlikelyDebug(anchorIS && anchorSection)) { 9190a68b90caSToby Isaac PetscInt size, a, pStart, pEnd; 9191a68b90caSToby Isaac const PetscInt *anchors; 9192a68b90caSToby Isaac 9193a68b90caSToby Isaac ierr = PetscSectionGetChart(anchorSection,&pStart,&pEnd);CHKERRQ(ierr); 9194a68b90caSToby Isaac ierr = ISGetLocalSize(anchorIS,&size);CHKERRQ(ierr); 9195a68b90caSToby Isaac ierr = ISGetIndices(anchorIS,&anchors);CHKERRQ(ierr); 9196a68b90caSToby Isaac for (a = 0; a < size; a++) { 9197a68b90caSToby Isaac PetscInt p; 9198a68b90caSToby Isaac 9199a68b90caSToby Isaac p = anchors[a]; 9200a68b90caSToby Isaac if (p >= pStart && p < pEnd) { 9201a68b90caSToby Isaac PetscInt dof; 9202a68b90caSToby Isaac 9203a68b90caSToby Isaac ierr = PetscSectionGetDof(anchorSection,p,&dof);CHKERRQ(ierr); 9204a68b90caSToby Isaac if (dof) { 9205a68b90caSToby Isaac PetscErrorCode ierr2; 9206a68b90caSToby Isaac 9207a68b90caSToby Isaac ierr2 = ISRestoreIndices(anchorIS,&anchors);CHKERRQ(ierr2); 92088ccfff9cSToby Isaac SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Point %D cannot be constrained and an anchor",p); 9209a68b90caSToby Isaac } 9210a68b90caSToby Isaac } 9211a68b90caSToby Isaac } 9212a68b90caSToby Isaac ierr = ISRestoreIndices(anchorIS,&anchors);CHKERRQ(ierr); 9213a68b90caSToby Isaac } 9214f7c74593SToby Isaac /* reset the generic constraints */ 9215f7c74593SToby Isaac ierr = DMSetDefaultConstraints(dm,NULL,NULL);CHKERRQ(ierr); 9216a68b90caSToby Isaac PetscFunctionReturn(0); 9217a68b90caSToby Isaac } 9218a68b90caSToby Isaac 9219f7c74593SToby Isaac static PetscErrorCode DMPlexCreateConstraintSection_Anchors(DM dm, PetscSection section, PetscSection *cSec) 9220a68b90caSToby Isaac { 9221f7c74593SToby Isaac PetscSection anchorSection; 92226995de1eSToby Isaac PetscInt pStart, pEnd, sStart, sEnd, p, dof, numFields, f; 9223a68b90caSToby Isaac PetscErrorCode ierr; 9224a68b90caSToby Isaac 9225a68b90caSToby Isaac PetscFunctionBegin; 9226a68b90caSToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9227a17985deSToby Isaac ierr = DMPlexGetAnchors(dm,&anchorSection,NULL);CHKERRQ(ierr); 9228e228b242SToby Isaac ierr = PetscSectionCreate(PETSC_COMM_SELF,cSec);CHKERRQ(ierr); 9229a68b90caSToby Isaac ierr = PetscSectionGetNumFields(section,&numFields);CHKERRQ(ierr); 92306995de1eSToby Isaac if (numFields) { 9231719ab38cSToby Isaac PetscInt f; 9232a68b90caSToby Isaac ierr = PetscSectionSetNumFields(*cSec,numFields);CHKERRQ(ierr); 9233719ab38cSToby Isaac 9234719ab38cSToby Isaac for (f = 0; f < numFields; f++) { 9235719ab38cSToby Isaac PetscInt numComp; 9236719ab38cSToby Isaac 9237719ab38cSToby Isaac ierr = PetscSectionGetFieldComponents(section,f,&numComp);CHKERRQ(ierr); 9238719ab38cSToby Isaac ierr = PetscSectionSetFieldComponents(*cSec,f,numComp);CHKERRQ(ierr); 9239719ab38cSToby Isaac } 92406995de1eSToby Isaac } 9241a68b90caSToby Isaac ierr = PetscSectionGetChart(anchorSection,&pStart,&pEnd);CHKERRQ(ierr); 92426995de1eSToby Isaac ierr = PetscSectionGetChart(section,&sStart,&sEnd);CHKERRQ(ierr); 92436995de1eSToby Isaac pStart = PetscMax(pStart,sStart); 92446995de1eSToby Isaac pEnd = PetscMin(pEnd,sEnd); 92456995de1eSToby Isaac pEnd = PetscMax(pStart,pEnd); 9246a68b90caSToby Isaac ierr = PetscSectionSetChart(*cSec,pStart,pEnd);CHKERRQ(ierr); 9247a68b90caSToby Isaac for (p = pStart; p < pEnd; p++) { 9248a68b90caSToby Isaac ierr = PetscSectionGetDof(anchorSection,p,&dof);CHKERRQ(ierr); 9249a68b90caSToby Isaac if (dof) { 9250a68b90caSToby Isaac ierr = PetscSectionGetDof(section,p,&dof);CHKERRQ(ierr); 9251a68b90caSToby Isaac ierr = PetscSectionSetDof(*cSec,p,dof);CHKERRQ(ierr); 9252a68b90caSToby Isaac for (f = 0; f < numFields; f++) { 9253a68b90caSToby Isaac ierr = PetscSectionGetFieldDof(section,p,f,&dof);CHKERRQ(ierr); 9254a68b90caSToby Isaac ierr = PetscSectionSetFieldDof(*cSec,p,f,dof);CHKERRQ(ierr); 9255a68b90caSToby Isaac } 9256a68b90caSToby Isaac } 9257a68b90caSToby Isaac } 9258a68b90caSToby Isaac ierr = PetscSectionSetUp(*cSec);CHKERRQ(ierr); 9259ae65431dSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) *cSec, "Constraint Section");CHKERRQ(ierr); 9260a68b90caSToby Isaac PetscFunctionReturn(0); 9261a68b90caSToby Isaac } 9262a68b90caSToby Isaac 9263f7c74593SToby Isaac static PetscErrorCode DMPlexCreateConstraintMatrix_Anchors(DM dm, PetscSection section, PetscSection cSec, Mat *cMat) 9264a68b90caSToby Isaac { 9265f7c74593SToby Isaac PetscSection aSec; 9266ae65431dSMatthew G. Knepley PetscInt pStart, pEnd, p, sStart, sEnd, dof, aDof, aOff, off, nnz, annz, m, n, q, a, offset, *i, *j; 92670ac89760SToby Isaac const PetscInt *anchors; 92680ac89760SToby Isaac PetscInt numFields, f; 926966ad2231SToby Isaac IS aIS; 92700ac89760SToby Isaac PetscErrorCode ierr; 9271e19f7ee6SMark Adams MatType mtype; 9272e19f7ee6SMark Adams PetscBool iscuda,iskokkos; 92730ac89760SToby Isaac 92740ac89760SToby Isaac PetscFunctionBegin; 92750ac89760SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 92760ac89760SToby Isaac ierr = PetscSectionGetStorageSize(cSec, &m);CHKERRQ(ierr); 92770ac89760SToby Isaac ierr = PetscSectionGetStorageSize(section, &n);CHKERRQ(ierr); 92780ac89760SToby Isaac ierr = MatCreate(PETSC_COMM_SELF,cMat);CHKERRQ(ierr); 92790ac89760SToby Isaac ierr = MatSetSizes(*cMat,m,n,m,n);CHKERRQ(ierr); 9280e19f7ee6SMark Adams ierr = PetscStrcmp(dm->mattype,MATSEQAIJCUSPARSE,&iscuda);CHKERRQ(ierr); 9281e19f7ee6SMark Adams if (!iscuda) { ierr = PetscStrcmp(dm->mattype,MATMPIAIJCUSPARSE,&iscuda);CHKERRQ(ierr); } 9282e19f7ee6SMark Adams ierr = PetscStrcmp(dm->mattype,MATSEQAIJKOKKOS,&iskokkos);CHKERRQ(ierr); 9283e19f7ee6SMark Adams if (!iskokkos) { ierr = PetscStrcmp(dm->mattype,MATMPIAIJKOKKOS,&iskokkos);CHKERRQ(ierr); } 9284e19f7ee6SMark Adams if (iscuda) mtype = MATSEQAIJCUSPARSE; 9285e19f7ee6SMark Adams else if (iskokkos) mtype = MATSEQAIJKOKKOS; 9286e19f7ee6SMark Adams else mtype = MATSEQAIJ; 9287e19f7ee6SMark Adams ierr = MatSetType(*cMat,mtype);CHKERRQ(ierr); 9288a17985deSToby Isaac ierr = DMPlexGetAnchors(dm,&aSec,&aIS);CHKERRQ(ierr); 928966ad2231SToby Isaac ierr = ISGetIndices(aIS,&anchors);CHKERRQ(ierr); 92906995de1eSToby Isaac /* cSec will be a subset of aSec and section */ 92916995de1eSToby Isaac ierr = PetscSectionGetChart(cSec,&pStart,&pEnd);CHKERRQ(ierr); 9292ae65431dSMatthew G. Knepley ierr = PetscSectionGetChart(section,&sStart,&sEnd);CHKERRQ(ierr); 92930ac89760SToby Isaac ierr = PetscMalloc1(m+1,&i);CHKERRQ(ierr); 92940ac89760SToby Isaac i[0] = 0; 92950ac89760SToby Isaac ierr = PetscSectionGetNumFields(section,&numFields);CHKERRQ(ierr); 92960ac89760SToby Isaac for (p = pStart; p < pEnd; p++) { 9297f19733c5SToby Isaac PetscInt rDof, rOff, r; 9298f19733c5SToby Isaac 9299f19733c5SToby Isaac ierr = PetscSectionGetDof(aSec,p,&rDof);CHKERRQ(ierr); 9300f19733c5SToby Isaac if (!rDof) continue; 9301f19733c5SToby Isaac ierr = PetscSectionGetOffset(aSec,p,&rOff);CHKERRQ(ierr); 93020ac89760SToby Isaac if (numFields) { 93030ac89760SToby Isaac for (f = 0; f < numFields; f++) { 93040ac89760SToby Isaac annz = 0; 9305f19733c5SToby Isaac for (r = 0; r < rDof; r++) { 9306f19733c5SToby Isaac a = anchors[rOff + r]; 9307ae65431dSMatthew G. Knepley if (a < sStart || a >= sEnd) continue; 93080ac89760SToby Isaac ierr = PetscSectionGetFieldDof(section,a,f,&aDof);CHKERRQ(ierr); 93090ac89760SToby Isaac annz += aDof; 93100ac89760SToby Isaac } 93110ac89760SToby Isaac ierr = PetscSectionGetFieldDof(cSec,p,f,&dof);CHKERRQ(ierr); 93120ac89760SToby Isaac ierr = PetscSectionGetFieldOffset(cSec,p,f,&off);CHKERRQ(ierr); 93130ac89760SToby Isaac for (q = 0; q < dof; q++) { 93140ac89760SToby Isaac i[off + q + 1] = i[off + q] + annz; 93150ac89760SToby Isaac } 93160ac89760SToby Isaac } 93170ac89760SToby Isaac } 93180ac89760SToby Isaac else { 93190ac89760SToby Isaac annz = 0; 9320326b8f31SMatthew G. Knepley ierr = PetscSectionGetDof(cSec,p,&dof);CHKERRQ(ierr); 93210ac89760SToby Isaac for (q = 0; q < dof; q++) { 9322ae65431dSMatthew G. Knepley a = anchors[rOff + q]; 9323ae65431dSMatthew G. Knepley if (a < sStart || a >= sEnd) continue; 93240ac89760SToby Isaac ierr = PetscSectionGetDof(section,a,&aDof);CHKERRQ(ierr); 93250ac89760SToby Isaac annz += aDof; 93260ac89760SToby Isaac } 93270ac89760SToby Isaac ierr = PetscSectionGetDof(cSec,p,&dof);CHKERRQ(ierr); 93280ac89760SToby Isaac ierr = PetscSectionGetOffset(cSec,p,&off);CHKERRQ(ierr); 93290ac89760SToby Isaac for (q = 0; q < dof; q++) { 93300ac89760SToby Isaac i[off + q + 1] = i[off + q] + annz; 93310ac89760SToby Isaac } 93320ac89760SToby Isaac } 93330ac89760SToby Isaac } 93340ac89760SToby Isaac nnz = i[m]; 93350ac89760SToby Isaac ierr = PetscMalloc1(nnz,&j);CHKERRQ(ierr); 93360ac89760SToby Isaac offset = 0; 93370ac89760SToby Isaac for (p = pStart; p < pEnd; p++) { 93380ac89760SToby Isaac if (numFields) { 93390ac89760SToby Isaac for (f = 0; f < numFields; f++) { 93400ac89760SToby Isaac ierr = PetscSectionGetFieldDof(cSec,p,f,&dof);CHKERRQ(ierr); 93410ac89760SToby Isaac for (q = 0; q < dof; q++) { 93420ac89760SToby Isaac PetscInt rDof, rOff, r; 93430ac89760SToby Isaac ierr = PetscSectionGetDof(aSec,p,&rDof);CHKERRQ(ierr); 93440ac89760SToby Isaac ierr = PetscSectionGetOffset(aSec,p,&rOff);CHKERRQ(ierr); 93450ac89760SToby Isaac for (r = 0; r < rDof; r++) { 93460ac89760SToby Isaac PetscInt s; 93470ac89760SToby Isaac 93480ac89760SToby Isaac a = anchors[rOff + r]; 9349ae65431dSMatthew G. Knepley if (a < sStart || a >= sEnd) continue; 93500ac89760SToby Isaac ierr = PetscSectionGetFieldDof(section,a,f,&aDof);CHKERRQ(ierr); 93510ac89760SToby Isaac ierr = PetscSectionGetFieldOffset(section,a,f,&aOff);CHKERRQ(ierr); 93520ac89760SToby Isaac for (s = 0; s < aDof; s++) { 93530ac89760SToby Isaac j[offset++] = aOff + s; 93540ac89760SToby Isaac } 93550ac89760SToby Isaac } 93560ac89760SToby Isaac } 93570ac89760SToby Isaac } 93580ac89760SToby Isaac } 93590ac89760SToby Isaac else { 93600ac89760SToby Isaac ierr = PetscSectionGetDof(cSec,p,&dof);CHKERRQ(ierr); 93610ac89760SToby Isaac for (q = 0; q < dof; q++) { 93620ac89760SToby Isaac PetscInt rDof, rOff, r; 93630ac89760SToby Isaac ierr = PetscSectionGetDof(aSec,p,&rDof);CHKERRQ(ierr); 93640ac89760SToby Isaac ierr = PetscSectionGetOffset(aSec,p,&rOff);CHKERRQ(ierr); 93650ac89760SToby Isaac for (r = 0; r < rDof; r++) { 93660ac89760SToby Isaac PetscInt s; 93670ac89760SToby Isaac 93680ac89760SToby Isaac a = anchors[rOff + r]; 9369ae65431dSMatthew G. Knepley if (a < sStart || a >= sEnd) continue; 93700ac89760SToby Isaac ierr = PetscSectionGetDof(section,a,&aDof);CHKERRQ(ierr); 93710ac89760SToby Isaac ierr = PetscSectionGetOffset(section,a,&aOff);CHKERRQ(ierr); 93720ac89760SToby Isaac for (s = 0; s < aDof; s++) { 93730ac89760SToby Isaac j[offset++] = aOff + s; 93740ac89760SToby Isaac } 93750ac89760SToby Isaac } 93760ac89760SToby Isaac } 93770ac89760SToby Isaac } 93780ac89760SToby Isaac } 93790ac89760SToby Isaac ierr = MatSeqAIJSetPreallocationCSR(*cMat,i,j,NULL);CHKERRQ(ierr); 938025570a81SToby Isaac ierr = PetscFree(i);CHKERRQ(ierr); 938125570a81SToby Isaac ierr = PetscFree(j);CHKERRQ(ierr); 938266ad2231SToby Isaac ierr = ISRestoreIndices(aIS,&anchors);CHKERRQ(ierr); 93830ac89760SToby Isaac PetscFunctionReturn(0); 93840ac89760SToby Isaac } 93850ac89760SToby Isaac 938666ad2231SToby Isaac PetscErrorCode DMCreateDefaultConstraints_Plex(DM dm) 938766ad2231SToby Isaac { 9388f7c74593SToby Isaac DM_Plex *plex = (DM_Plex *)dm->data; 9389f7c74593SToby Isaac PetscSection anchorSection, section, cSec; 939066ad2231SToby Isaac Mat cMat; 939166ad2231SToby Isaac PetscErrorCode ierr; 939266ad2231SToby Isaac 939366ad2231SToby Isaac PetscFunctionBegin; 939466ad2231SToby Isaac PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9395a17985deSToby Isaac ierr = DMPlexGetAnchors(dm,&anchorSection,NULL);CHKERRQ(ierr); 939666ad2231SToby Isaac if (anchorSection) { 939744a7f3ddSMatthew G. Knepley PetscInt Nf; 9398e228b242SToby Isaac 939992fd8e1eSJed Brown ierr = DMGetLocalSection(dm,§ion);CHKERRQ(ierr); 9400f7c74593SToby Isaac ierr = DMPlexCreateConstraintSection_Anchors(dm,section,&cSec);CHKERRQ(ierr); 9401f7c74593SToby Isaac ierr = DMPlexCreateConstraintMatrix_Anchors(dm,section,cSec,&cMat);CHKERRQ(ierr); 940244a7f3ddSMatthew G. Knepley ierr = DMGetNumFields(dm,&Nf);CHKERRQ(ierr); 940344a7f3ddSMatthew G. Knepley if (Nf && plex->computeanchormatrix) {ierr = (*plex->computeanchormatrix)(dm,section,cSec,cMat);CHKERRQ(ierr);} 940466ad2231SToby Isaac ierr = DMSetDefaultConstraints(dm,cSec,cMat);CHKERRQ(ierr); 940566ad2231SToby Isaac ierr = PetscSectionDestroy(&cSec);CHKERRQ(ierr); 940666ad2231SToby Isaac ierr = MatDestroy(&cMat);CHKERRQ(ierr); 940766ad2231SToby Isaac } 940866ad2231SToby Isaac PetscFunctionReturn(0); 940966ad2231SToby Isaac } 9410a93c429eSMatthew G. Knepley 9411a93c429eSMatthew G. Knepley PetscErrorCode DMCreateSubDomainDM_Plex(DM dm, DMLabel label, PetscInt value, IS *is, DM *subdm) 9412a93c429eSMatthew G. Knepley { 9413a93c429eSMatthew G. Knepley IS subis; 9414a93c429eSMatthew G. Knepley PetscSection section, subsection; 9415a93c429eSMatthew G. Knepley PetscErrorCode ierr; 9416a93c429eSMatthew G. Knepley 9417a93c429eSMatthew G. Knepley PetscFunctionBegin; 941892fd8e1eSJed Brown ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr); 9419a93c429eSMatthew G. Knepley if (!section) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Must set default section for DM before splitting subdomain"); 9420a93c429eSMatthew G. Knepley if (!subdm) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Must set output subDM for splitting subdomain"); 9421a93c429eSMatthew G. Knepley /* Create subdomain */ 9422a93c429eSMatthew G. Knepley ierr = DMPlexFilter(dm, label, value, subdm);CHKERRQ(ierr); 9423a93c429eSMatthew G. Knepley /* Create submodel */ 942497d8846cSMatthew Knepley ierr = DMPlexGetSubpointIS(*subdm, &subis);CHKERRQ(ierr); 9425a93c429eSMatthew G. Knepley ierr = PetscSectionCreateSubmeshSection(section, subis, &subsection);CHKERRQ(ierr); 942692fd8e1eSJed Brown ierr = DMSetLocalSection(*subdm, subsection);CHKERRQ(ierr); 9427a93c429eSMatthew G. Knepley ierr = PetscSectionDestroy(&subsection);CHKERRQ(ierr); 9428e5e52638SMatthew G. Knepley ierr = DMCopyDisc(dm, *subdm);CHKERRQ(ierr); 9429a93c429eSMatthew G. Knepley /* Create map from submodel to global model */ 9430a93c429eSMatthew G. Knepley if (is) { 9431a93c429eSMatthew G. Knepley PetscSection sectionGlobal, subsectionGlobal; 9432a93c429eSMatthew G. Knepley IS spIS; 9433a93c429eSMatthew G. Knepley const PetscInt *spmap; 9434a93c429eSMatthew G. Knepley PetscInt *subIndices; 9435a93c429eSMatthew G. Knepley PetscInt subSize = 0, subOff = 0, pStart, pEnd, p; 9436a93c429eSMatthew G. Knepley PetscInt Nf, f, bs = -1, bsLocal[2], bsMinMax[2]; 9437a93c429eSMatthew G. Knepley 943897d8846cSMatthew Knepley ierr = DMPlexGetSubpointIS(*subdm, &spIS);CHKERRQ(ierr); 9439a93c429eSMatthew G. Knepley ierr = ISGetIndices(spIS, &spmap);CHKERRQ(ierr); 9440a93c429eSMatthew G. Knepley ierr = PetscSectionGetNumFields(section, &Nf);CHKERRQ(ierr); 94416f0eb057SJed Brown ierr = DMGetGlobalSection(dm, §ionGlobal);CHKERRQ(ierr); 94426f0eb057SJed Brown ierr = DMGetGlobalSection(*subdm, &subsectionGlobal);CHKERRQ(ierr); 9443a93c429eSMatthew G. Knepley ierr = PetscSectionGetChart(subsection, &pStart, &pEnd);CHKERRQ(ierr); 9444a93c429eSMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 9445a93c429eSMatthew G. Knepley PetscInt gdof, pSubSize = 0; 9446a93c429eSMatthew G. Knepley 9447a93c429eSMatthew G. Knepley ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr); 9448a93c429eSMatthew G. Knepley if (gdof > 0) { 9449a93c429eSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 9450a93c429eSMatthew G. Knepley PetscInt fdof, fcdof; 9451a93c429eSMatthew G. Knepley 9452a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldDof(subsection, p, f, &fdof);CHKERRQ(ierr); 9453a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldConstraintDof(subsection, p, f, &fcdof);CHKERRQ(ierr); 9454a93c429eSMatthew G. Knepley pSubSize += fdof-fcdof; 9455a93c429eSMatthew G. Knepley } 9456a93c429eSMatthew G. Knepley subSize += pSubSize; 9457a93c429eSMatthew G. Knepley if (pSubSize) { 9458a93c429eSMatthew G. Knepley if (bs < 0) { 9459a93c429eSMatthew G. Knepley bs = pSubSize; 9460a93c429eSMatthew G. Knepley } else if (bs != pSubSize) { 9461a93c429eSMatthew G. Knepley /* Layout does not admit a pointwise block size */ 9462a93c429eSMatthew G. Knepley bs = 1; 9463a93c429eSMatthew G. Knepley } 9464a93c429eSMatthew G. Knepley } 9465a93c429eSMatthew G. Knepley } 9466a93c429eSMatthew G. Knepley } 9467a93c429eSMatthew G. Knepley /* Must have same blocksize on all procs (some might have no points) */ 9468a93c429eSMatthew G. Knepley bsLocal[0] = bs < 0 ? PETSC_MAX_INT : bs; bsLocal[1] = bs; 9469a93c429eSMatthew G. Knepley ierr = PetscGlobalMinMaxInt(PetscObjectComm((PetscObject) dm), bsLocal, bsMinMax);CHKERRQ(ierr); 9470a93c429eSMatthew G. Knepley if (bsMinMax[0] != bsMinMax[1]) {bs = 1;} 9471a93c429eSMatthew G. Knepley else {bs = bsMinMax[0];} 9472a93c429eSMatthew G. Knepley ierr = PetscMalloc1(subSize, &subIndices);CHKERRQ(ierr); 9473a93c429eSMatthew G. Knepley for (p = pStart; p < pEnd; ++p) { 9474a93c429eSMatthew G. Knepley PetscInt gdof, goff; 9475a93c429eSMatthew G. Knepley 9476a93c429eSMatthew G. Knepley ierr = PetscSectionGetDof(subsectionGlobal, p, &gdof);CHKERRQ(ierr); 9477a93c429eSMatthew G. Knepley if (gdof > 0) { 9478a93c429eSMatthew G. Knepley const PetscInt point = spmap[p]; 9479a93c429eSMatthew G. Knepley 9480a93c429eSMatthew G. Knepley ierr = PetscSectionGetOffset(sectionGlobal, point, &goff);CHKERRQ(ierr); 9481a93c429eSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 9482a93c429eSMatthew G. Knepley PetscInt fdof, fcdof, fc, f2, poff = 0; 9483a93c429eSMatthew G. Knepley 9484a93c429eSMatthew G. Knepley /* Can get rid of this loop by storing field information in the global section */ 9485a93c429eSMatthew G. Knepley for (f2 = 0; f2 < f; ++f2) { 9486a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, p, f2, &fdof);CHKERRQ(ierr); 9487a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldConstraintDof(section, p, f2, &fcdof);CHKERRQ(ierr); 9488a93c429eSMatthew G. Knepley poff += fdof-fcdof; 9489a93c429eSMatthew G. Knepley } 9490a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldDof(section, p, f, &fdof);CHKERRQ(ierr); 9491a93c429eSMatthew G. Knepley ierr = PetscSectionGetFieldConstraintDof(section, p, f, &fcdof);CHKERRQ(ierr); 9492a93c429eSMatthew G. Knepley for (fc = 0; fc < fdof-fcdof; ++fc, ++subOff) { 9493a93c429eSMatthew G. Knepley subIndices[subOff] = goff+poff+fc; 9494a93c429eSMatthew G. Knepley } 9495a93c429eSMatthew G. Knepley } 9496a93c429eSMatthew G. Knepley } 9497a93c429eSMatthew G. Knepley } 9498a93c429eSMatthew G. Knepley ierr = ISRestoreIndices(spIS, &spmap);CHKERRQ(ierr); 9499a93c429eSMatthew G. Knepley ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), subSize, subIndices, PETSC_OWN_POINTER, is);CHKERRQ(ierr); 9500a93c429eSMatthew G. Knepley if (bs > 1) { 9501a93c429eSMatthew G. Knepley /* We need to check that the block size does not come from non-contiguous fields */ 9502a93c429eSMatthew G. Knepley PetscInt i, j, set = 1; 9503a93c429eSMatthew G. Knepley for (i = 0; i < subSize; i += bs) { 9504a93c429eSMatthew G. Knepley for (j = 0; j < bs; ++j) { 9505a93c429eSMatthew G. Knepley if (subIndices[i+j] != subIndices[i]+j) {set = 0; break;} 9506a93c429eSMatthew G. Knepley } 9507a93c429eSMatthew G. Knepley } 9508a93c429eSMatthew G. Knepley if (set) {ierr = ISSetBlockSize(*is, bs);CHKERRQ(ierr);} 9509a93c429eSMatthew G. Knepley } 9510a93c429eSMatthew G. Knepley /* Attach nullspace */ 9511a93c429eSMatthew G. Knepley for (f = 0; f < Nf; ++f) { 9512a93c429eSMatthew G. Knepley (*subdm)->nullspaceConstructors[f] = dm->nullspaceConstructors[f]; 9513a93c429eSMatthew G. Knepley if ((*subdm)->nullspaceConstructors[f]) break; 9514a93c429eSMatthew G. Knepley } 9515a93c429eSMatthew G. Knepley if (f < Nf) { 9516a93c429eSMatthew G. Knepley MatNullSpace nullSpace; 95178cda7954SMatthew G. Knepley ierr = (*(*subdm)->nullspaceConstructors[f])(*subdm, f, f, &nullSpace);CHKERRQ(ierr); 95186823f3c5SBlaise Bourdin 9519a93c429eSMatthew G. Knepley ierr = PetscObjectCompose((PetscObject) *is, "nullspace", (PetscObject) nullSpace);CHKERRQ(ierr); 9520a93c429eSMatthew G. Knepley ierr = MatNullSpaceDestroy(&nullSpace);CHKERRQ(ierr); 9521a93c429eSMatthew G. Knepley } 9522a93c429eSMatthew G. Knepley } 9523a93c429eSMatthew G. Knepley PetscFunctionReturn(0); 9524a93c429eSMatthew G. Knepley } 9525c0f0dcc3SMatthew G. Knepley 9526c0f0dcc3SMatthew G. Knepley /*@ 9527c0f0dcc3SMatthew G. Knepley DMPlexMonitorThroughput - Report the cell throughput of FE integration 9528c0f0dcc3SMatthew G. Knepley 9529c0f0dcc3SMatthew G. Knepley Input Parameter: 9530c0f0dcc3SMatthew G. Knepley - dm - The DM 9531c0f0dcc3SMatthew G. Knepley 9532c0f0dcc3SMatthew G. Knepley Level: developer 9533c0f0dcc3SMatthew G. Knepley 9534c0f0dcc3SMatthew G. Knepley Options Database Keys: 9535c0f0dcc3SMatthew G. Knepley . -dm_plex_monitor_throughput - Activate the monitor 9536c0f0dcc3SMatthew G. Knepley 9537c0f0dcc3SMatthew G. Knepley .seealso: DMSetFromOptions(), DMPlexCreate() 9538c0f0dcc3SMatthew G. Knepley @*/ 9539c0f0dcc3SMatthew G. Knepley PetscErrorCode DMPlexMonitorThroughput(DM dm, void *dummy) 9540c0f0dcc3SMatthew G. Knepley { 9541e5ed2c37SJose E. Roman #if defined(PETSC_USE_LOG) 9542c0f0dcc3SMatthew G. Knepley PetscStageLog stageLog; 9543c0f0dcc3SMatthew G. Knepley PetscLogEvent event; 9544c0f0dcc3SMatthew G. Knepley PetscLogStage stage; 9545c0f0dcc3SMatthew G. Knepley PetscEventPerfInfo eventInfo; 9546c0f0dcc3SMatthew G. Knepley PetscReal cellRate, flopRate; 9547c0f0dcc3SMatthew G. Knepley PetscInt cStart, cEnd, Nf, N; 9548c0f0dcc3SMatthew G. Knepley const char *name; 9549c0f0dcc3SMatthew G. Knepley PetscErrorCode ierr; 9550e5ed2c37SJose E. Roman #endif 9551c0f0dcc3SMatthew G. Knepley 9552c0f0dcc3SMatthew G. Knepley PetscFunctionBegin; 9553c0f0dcc3SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 9554c0f0dcc3SMatthew G. Knepley #if defined(PETSC_USE_LOG) 9555c0f0dcc3SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) dm, &name);CHKERRQ(ierr); 9556c0f0dcc3SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 9557c0f0dcc3SMatthew G. Knepley ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 9558c0f0dcc3SMatthew G. Knepley ierr = PetscLogGetStageLog(&stageLog);CHKERRQ(ierr); 9559c0f0dcc3SMatthew G. Knepley ierr = PetscStageLogGetCurrent(stageLog, &stage);CHKERRQ(ierr); 9560c0f0dcc3SMatthew G. Knepley ierr = PetscLogEventGetId("DMPlexResidualFE", &event);CHKERRQ(ierr); 9561c0f0dcc3SMatthew G. Knepley ierr = PetscLogEventGetPerfInfo(stage, event, &eventInfo);CHKERRQ(ierr); 9562c0f0dcc3SMatthew G. Knepley N = (cEnd - cStart)*Nf*eventInfo.count; 9563c0f0dcc3SMatthew G. Knepley flopRate = eventInfo.flops/eventInfo.time; 9564c0f0dcc3SMatthew G. Knepley cellRate = N/eventInfo.time; 9565fae64647SBarry 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); 9566c0f0dcc3SMatthew G. Knepley #else 9567c0f0dcc3SMatthew G. Knepley SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Plex Throughput Monitor is not supported if logging is turned off. Reconfigure using --with-log."); 9568c0f0dcc3SMatthew G. Knepley #endif 9569c0f0dcc3SMatthew G. Knepley PetscFunctionReturn(0); 9570c0f0dcc3SMatthew G. Knepley } 9571