xref: /petsc/src/dm/impls/plex/plexindices.c (revision 3e03ebd80a77a3b91aa25c7873c7007780b9d0d1)
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, &section);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