#include /*I "petscdmplex.h" I*/ PetscErrorCode DMPlexPointQueueCreate(PetscInt size, DMPlexPointQueue *queue) { DMPlexPointQueue q; PetscFunctionBegin; PetscCheck(size >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Queue size %" PetscInt_FMT " must be non-negative", size); PetscCall(PetscCalloc1(1, &q)); q->size = size; PetscCall(PetscMalloc1(q->size, &q->points)); q->num = 0; q->front = 0; q->back = q->size - 1; *queue = q; PetscFunctionReturn(PETSC_SUCCESS); } PetscErrorCode DMPlexPointQueueDestroy(DMPlexPointQueue *queue) { DMPlexPointQueue q = *queue; PetscFunctionBegin; PetscCall(PetscFree(q->points)); PetscCall(PetscFree(q)); *queue = NULL; PetscFunctionReturn(PETSC_SUCCESS); } PetscErrorCode DMPlexPointQueueEnsureSize(DMPlexPointQueue queue) { PetscFunctionBegin; if (queue->num < queue->size) PetscFunctionReturn(PETSC_SUCCESS); queue->size *= 2; PetscCall(PetscRealloc(queue->size * sizeof(PetscInt), &queue->points)); PetscFunctionReturn(PETSC_SUCCESS); } PetscErrorCode DMPlexPointQueueEnqueue(DMPlexPointQueue queue, PetscInt p) { PetscFunctionBegin; PetscCall(DMPlexPointQueueEnsureSize(queue)); queue->back = (queue->back + 1) % queue->size; queue->points[queue->back] = p; ++queue->num; PetscFunctionReturn(PETSC_SUCCESS); } PetscErrorCode DMPlexPointQueueDequeue(DMPlexPointQueue queue, PetscInt *p) { PetscFunctionBegin; PetscCheck(queue->num, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cannot dequeue from an empty queue"); *p = queue->points[queue->front]; queue->front = (queue->front + 1) % queue->size; --queue->num; PetscFunctionReturn(PETSC_SUCCESS); } PetscErrorCode DMPlexPointQueueFront(DMPlexPointQueue queue, PetscInt *p) { PetscFunctionBegin; PetscCheck(queue->num, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cannot get the front of an empty queue"); *p = queue->points[queue->front]; PetscFunctionReturn(PETSC_SUCCESS); } PetscErrorCode DMPlexPointQueueBack(DMPlexPointQueue queue, PetscInt *p) { PetscFunctionBegin; PetscCheck(queue->num, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cannot get the back of an empty queue"); *p = queue->points[queue->back]; PetscFunctionReturn(PETSC_SUCCESS); } PetscBool DMPlexPointQueueEmpty(DMPlexPointQueue queue) { if (!queue->num) return PETSC_TRUE; return PETSC_FALSE; } PetscErrorCode DMPlexPointQueueEmptyCollective(PetscObject obj, DMPlexPointQueue queue, PetscBool *empty) { PetscFunctionBeginHot; *empty = DMPlexPointQueueEmpty(queue); PetscCallMPI(MPIU_Allreduce(MPI_IN_PLACE, empty, 1, MPI_C_BOOL, MPI_LAND, PetscObjectComm(obj))); PetscFunctionReturn(PETSC_SUCCESS); }