#include /* Get new PetscMatStashSpace into the existing space */ PetscErrorCode PetscMatStashSpaceGet(PetscInt bs2, PetscInt n, PetscMatStashSpace *space) { PetscMatStashSpace a; PetscFunctionBegin; if (!n) PetscFunctionReturn(PETSC_SUCCESS); PetscCall(PetscMalloc(sizeof(struct _MatStashSpace), &a)); PetscCall(PetscMalloc3(n * bs2, &a->space_head, n, &a->idx, n, &a->idy)); a->val = a->space_head; a->local_remaining = n; a->local_used = 0; a->total_space_size = 0; a->next = NULL; if (*space) { (*space)->next = a; a->total_space_size = (*space)->total_space_size; } a->total_space_size += n; *space = a; PetscFunctionReturn(PETSC_SUCCESS); } /* Copy the values in space into arrays val, idx and idy. Then destroy space */ PetscErrorCode PetscMatStashSpaceContiguous(PetscInt bs2, PetscMatStashSpace *space, PetscScalar *val, PetscInt *idx, PetscInt *idy) { PetscMatStashSpace a; PetscFunctionBegin; while (*space) { a = (*space)->next; PetscCall(PetscArraycpy(val, (*space)->val, (*space)->local_used * bs2)); val += bs2 * (*space)->local_used; PetscCall(PetscArraycpy(idx, (*space)->idx, (*space)->local_used)); idx += (*space)->local_used; PetscCall(PetscArraycpy(idy, (*space)->idy, (*space)->local_used)); idy += (*space)->local_used; PetscCall(PetscFree3((*space)->space_head, (*space)->idx, (*space)->idy)); PetscCall(PetscFree(*space)); *space = a; } PetscFunctionReturn(PETSC_SUCCESS); } PetscErrorCode PetscMatStashSpaceDestroy(PetscMatStashSpace *space) { PetscMatStashSpace a; PetscFunctionBegin; while (*space) { a = (*space)->next; PetscCall(PetscFree3((*space)->space_head, (*space)->idx, (*space)->idy)); PetscCall(PetscFree(*space)); *space = a; } *space = NULL; PetscFunctionReturn(PETSC_SUCCESS); }