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(PETSC_SUCCESS); 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(PETSC_SUCCESS); 28 } 29 30 PetscErrorCode DMPlexPointQueueEnsureSize(DMPlexPointQueue queue) 31 { 32 PetscFunctionBegin; 33 if (queue->num < queue->size) PetscFunctionReturn(PETSC_SUCCESS); 34 queue->size *= 2; 35 PetscCall(PetscRealloc(queue->size * sizeof(PetscInt), &queue->points)); 36 PetscFunctionReturn(PETSC_SUCCESS); 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(PETSC_SUCCESS); 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(PETSC_SUCCESS); 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(PETSC_SUCCESS); 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(PETSC_SUCCESS); 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(PETSC_SUCCESS); 87 } 88