1af0996ceSBarry Smith #include <petsc/private/dmpleximpl.h> /*I "petscdmplex.h" I*/ 2d9917b9dSMatthew G. Knepley 3d9917b9dSMatthew G. Knepley /*@ 4d9917b9dSMatthew G. Knepley DMPlexCreateClosureIndex - Calculate an index for the given PetscSection for the closure operation on the DM 5d9917b9dSMatthew G. Knepley 6d9917b9dSMatthew G. Knepley Not collective 7d9917b9dSMatthew G. Knepley 8d9917b9dSMatthew G. Knepley Input Parameters: 9d9917b9dSMatthew G. Knepley + dm - The DM 10*3e03ebd8SStefano Zampini - section - The section describing the layout in the local vector, or NULL to use the default section 11d9917b9dSMatthew G. Knepley 12d9917b9dSMatthew G. Knepley Note: 13d9917b9dSMatthew G. Knepley This should greatly improve the performance of the closure operations, at the cost of additional memory. 14d9917b9dSMatthew G. Knepley 15d9917b9dSMatthew G. Knepley Level: intermediate 16d9917b9dSMatthew G. Knepley 17d9917b9dSMatthew G. Knepley .seealso DMPlexVecGetClosure(), DMPlexVecRestoreClosure(), DMPlexVecSetClosure(), DMPlexMatSetClosure() 18d9917b9dSMatthew G. Knepley @*/ 19d9917b9dSMatthew G. Knepley PetscErrorCode DMPlexCreateClosureIndex(DM dm, PetscSection section) 20d9917b9dSMatthew G. Knepley { 21d9917b9dSMatthew G. Knepley PetscSection closureSection; 22d9917b9dSMatthew G. Knepley IS closureIS; 23d9917b9dSMatthew G. Knepley PetscInt *clPoints; 24d9917b9dSMatthew G. Knepley PetscInt pStart, pEnd, sStart, sEnd, point, clSize; 25d9917b9dSMatthew G. Knepley PetscErrorCode ierr; 26d9917b9dSMatthew G. Knepley 27d9917b9dSMatthew G. Knepley PetscFunctionBegin; 28d9917b9dSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 2992fd8e1eSJed Brown if (!section) {ierr = DMGetLocalSection(dm, §ion);CHKERRQ(ierr);} 301e0781a8SMatthew G. Knepley PetscValidHeaderSpecific(section, PETSC_SECTION_CLASSID, 2); 31d9917b9dSMatthew G. Knepley ierr = PetscSectionGetChart(section, &sStart, &sEnd);CHKERRQ(ierr); 32d9917b9dSMatthew G. Knepley ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 33d9917b9dSMatthew G. Knepley ierr = PetscSectionCreate(PetscObjectComm((PetscObject) section), &closureSection);CHKERRQ(ierr); 34d9917b9dSMatthew G. Knepley ierr = PetscSectionSetChart(closureSection, pStart, pEnd);CHKERRQ(ierr); 35d9917b9dSMatthew G. Knepley for (point = pStart; point < pEnd; ++point) { 36d9917b9dSMatthew G. Knepley PetscInt *points = NULL, numPoints, p, dof, cldof = 0; 37d9917b9dSMatthew G. Knepley 38d9917b9dSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, point, PETSC_TRUE, &numPoints, &points);CHKERRQ(ierr); 39d9917b9dSMatthew G. Knepley for (p = 0; p < numPoints*2; p += 2) { 40d9917b9dSMatthew G. Knepley if ((points[p] >= sStart) && (points[p] < sEnd)) { 41d9917b9dSMatthew G. Knepley ierr = PetscSectionGetDof(section, points[p], &dof);CHKERRQ(ierr); 42d9917b9dSMatthew G. Knepley if (dof) cldof += 2; 43d9917b9dSMatthew G. Knepley } 44d9917b9dSMatthew G. Knepley } 45d9917b9dSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, point, PETSC_TRUE, &numPoints, &points);CHKERRQ(ierr); 46d9917b9dSMatthew G. Knepley ierr = PetscSectionSetDof(closureSection, point, cldof);CHKERRQ(ierr); 47d9917b9dSMatthew G. Knepley } 48d9917b9dSMatthew G. Knepley ierr = PetscSectionSetUp(closureSection);CHKERRQ(ierr); 49d9917b9dSMatthew G. Knepley ierr = PetscSectionGetStorageSize(closureSection, &clSize);CHKERRQ(ierr); 50d9917b9dSMatthew G. Knepley ierr = PetscMalloc1(clSize, &clPoints);CHKERRQ(ierr); 51d9917b9dSMatthew G. Knepley for (point = pStart; point < pEnd; ++point) { 52d9917b9dSMatthew G. Knepley PetscInt *points = NULL, numPoints, p, q, dof, cldof, cloff; 53d9917b9dSMatthew G. Knepley 54d9917b9dSMatthew G. Knepley ierr = PetscSectionGetDof(closureSection, point, &cldof);CHKERRQ(ierr); 55d9917b9dSMatthew G. Knepley ierr = PetscSectionGetOffset(closureSection, point, &cloff);CHKERRQ(ierr); 56d9917b9dSMatthew G. Knepley ierr = DMPlexGetTransitiveClosure(dm, point, PETSC_TRUE, &numPoints, &points);CHKERRQ(ierr); 57d9917b9dSMatthew G. Knepley for (p = 0, q = 0; p < numPoints*2; p += 2) { 58d9917b9dSMatthew G. Knepley if ((points[p] >= sStart) && (points[p] < sEnd)) { 59d9917b9dSMatthew G. Knepley ierr = PetscSectionGetDof(section, points[p], &dof);CHKERRQ(ierr); 60d9917b9dSMatthew G. Knepley if (dof) { 61d9917b9dSMatthew G. Knepley clPoints[cloff+q*2] = points[p]; 62d9917b9dSMatthew G. Knepley clPoints[cloff+q*2+1] = points[p+1]; 63d9917b9dSMatthew G. Knepley ++q; 64d9917b9dSMatthew G. Knepley } 65d9917b9dSMatthew G. Knepley } 66d9917b9dSMatthew G. Knepley } 67d9917b9dSMatthew G. Knepley ierr = DMPlexRestoreTransitiveClosure(dm, point, PETSC_TRUE, &numPoints, &points);CHKERRQ(ierr); 68*3e03ebd8SStefano Zampini if (q*2 != cldof) SETERRQ2(PetscObjectComm((PetscObject) dm), PETSC_ERR_PLIB, "Invalid size for closure %D should be %D", q*2, cldof); 69d9917b9dSMatthew G. Knepley } 70d9917b9dSMatthew G. Knepley ierr = ISCreateGeneral(PETSC_COMM_SELF, clSize, clPoints, PETSC_OWN_POINTER, &closureIS);CHKERRQ(ierr); 71302440fdSBarry Smith ierr = PetscSectionSetClosureIndex(section, (PetscObject) dm, closureSection, closureIS);CHKERRQ(ierr); 72*3e03ebd8SStefano Zampini ierr = PetscSectionDestroy(&closureSection);CHKERRQ(ierr); 73*3e03ebd8SStefano Zampini ierr = ISDestroy(&closureIS);CHKERRQ(ierr); 74d9917b9dSMatthew G. Knepley PetscFunctionReturn(0); 75d9917b9dSMatthew G. Knepley } 76