xref: /petsc/src/dm/impls/plex/pointqueue.c (revision 5becb6a3a7fe6fe66ca978502f4679a4b24b29fc)
1 #include <petsc/private/dmpleximpl.h>   /*I      "petscdmplex.h"   I*/
2 
3 PetscErrorCode DMPlexPointQueueCreate(PetscInt size, DMPlexPointQueue *queue)
4 {
5   DMPlexPointQueue q;
6 
7   PetscFunctionBegin;
8   PetscCheck(size >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Queue size %" PetscInt_FMT" must be non-negative", size);
9   PetscCall(PetscCalloc1(1, &q));
10   q->size = size;
11   PetscCall(PetscMalloc1(q->size, &q->points));
12   q->num   = 0;
13   q->front = 0;
14   q->back  = q->size-1;
15   *queue = q;
16   PetscFunctionReturn(0);
17 }
18 
19 PetscErrorCode DMPlexPointQueueDestroy(DMPlexPointQueue *queue)
20 {
21   DMPlexPointQueue q = *queue;
22 
23   PetscFunctionBegin;
24   PetscCall(PetscFree(q->points));
25   PetscCall(PetscFree(q));
26   *queue = NULL;
27   PetscFunctionReturn(0);
28 }
29 
30 PetscErrorCode DMPlexPointQueueEnsureSize(DMPlexPointQueue queue)
31 {
32   PetscFunctionBegin;
33   if (queue->num < queue->size) PetscFunctionReturn(0);
34   queue->size *= 2;
35   PetscCall(PetscRealloc(queue->size * sizeof(PetscInt), &queue->points));
36   PetscFunctionReturn(0);
37 }
38 
39 PetscErrorCode DMPlexPointQueueEnqueue(DMPlexPointQueue queue, PetscInt p)
40 {
41   PetscFunctionBegin;
42   PetscCall(DMPlexPointQueueEnsureSize(queue));
43   queue->back = (queue->back + 1) % queue->size;
44   queue->points[queue->back] = p;
45   ++queue->num;
46   PetscFunctionReturn(0);
47 }
48 
49 PetscErrorCode DMPlexPointQueueDequeue(DMPlexPointQueue queue, PetscInt *p)
50 {
51   PetscFunctionBegin;
52   PetscCheck(queue->num, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cannot dequeue from an empty queue");
53   *p = queue->points[queue->front];
54   queue->front = (queue->front + 1) % queue->size;
55   --queue->num;
56   PetscFunctionReturn(0);
57 }
58 
59 PetscErrorCode DMPlexPointQueueFront(DMPlexPointQueue queue, PetscInt *p)
60 {
61   PetscFunctionBegin;
62   PetscCheck(queue->num, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cannot get the front of an empty queue");
63   *p = queue->points[queue->front];
64   PetscFunctionReturn(0);
65 }
66 
67 PetscErrorCode DMPlexPointQueueBack(DMPlexPointQueue queue, PetscInt *p)
68 {
69   PetscFunctionBegin;
70   PetscCheck(queue->num, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cannot get the back of an empty queue");
71   *p = queue->points[queue->back];
72   PetscFunctionReturn(0);
73 }
74 
75 PetscBool DMPlexPointQueueEmpty(DMPlexPointQueue queue)
76 {
77   if (!queue->num) return PETSC_TRUE;
78   return PETSC_FALSE;
79 }
80 
81 PetscErrorCode DMPlexPointQueueEmptyCollective(PetscObject obj, DMPlexPointQueue queue, PetscBool *empty)
82 {
83   PetscFunctionBeginHot;
84   *empty = DMPlexPointQueueEmpty(queue);
85   PetscCallMPI(MPI_Allreduce(MPI_IN_PLACE, empty, 1, MPIU_BOOL, MPI_LAND, PetscObjectComm(obj)));
86   PetscFunctionReturn(0);
87 }
88