1 /* 2 Code for manipulating distributed regular arrays in parallel. 3 */ 4 5 #include <petsc/private/dmdaimpl.h> /*I "petscdmda.h" I*/ 6 7 /* 8 DMLocalToLocalCreate_DA - Creates the local to local scatter 9 10 Collective 11 12 Input Parameter: 13 . da - the distributed array 14 15 */ 16 PetscErrorCode DMLocalToLocalCreate_DA(DM da) 17 { 18 PetscInt *idx, left, j, count, up, down, i, bottom, top, k, dim = da->dim; 19 DM_DA *dd = (DM_DA *)da->data; 20 21 PetscFunctionBegin; 22 PetscValidHeaderSpecific(da, DM_CLASSID, 1); 23 24 if (dd->ltol) PetscFunctionReturn(PETSC_SUCCESS); 25 /* 26 We simply remap the values in the from part of 27 global to local to read from an array with the ghost values 28 rather then from the plain array. 29 */ 30 PetscCall(VecScatterCopy(dd->gtol, &dd->ltol)); 31 if (dim == 1) { 32 left = dd->xs - dd->Xs; 33 PetscCall(PetscMalloc1(dd->xe - dd->xs, &idx)); 34 for (j = 0; j < dd->xe - dd->xs; j++) idx[j] = left + j; 35 } else if (dim == 2) { 36 left = dd->xs - dd->Xs; 37 down = dd->ys - dd->Ys; 38 up = down + dd->ye - dd->ys; 39 PetscCall(PetscMalloc1((dd->xe - dd->xs) * (up - down), &idx)); 40 count = 0; 41 for (i = down; i < up; i++) { 42 for (j = 0; j < dd->xe - dd->xs; j++) idx[count++] = left + i * (dd->Xe - dd->Xs) + j; 43 } 44 } else if (dim == 3) { 45 left = dd->xs - dd->Xs; 46 bottom = dd->ys - dd->Ys; 47 top = bottom + dd->ye - dd->ys; 48 down = dd->zs - dd->Zs; 49 up = down + dd->ze - dd->zs; 50 count = (dd->xe - dd->xs) * (top - bottom) * (up - down); 51 PetscCall(PetscMalloc1(count, &idx)); 52 count = 0; 53 for (i = down; i < up; i++) { 54 for (j = bottom; j < top; j++) { 55 for (k = 0; k < dd->xe - dd->xs; k++) idx[count++] = (left + j * (dd->Xe - dd->Xs)) + i * (dd->Xe - dd->Xs) * (dd->Ye - dd->Ys) + k; 56 } 57 } 58 } else SETERRQ(PetscObjectComm((PetscObject)da), PETSC_ERR_ARG_CORRUPT, "DMDA has invalid dimension %" PetscInt_FMT, dim); 59 60 PetscCall(VecScatterRemap(dd->ltol, idx, NULL)); 61 PetscCall(PetscFree(idx)); 62 PetscFunctionReturn(PETSC_SUCCESS); 63 } 64 65 PetscErrorCode DMLocalToLocalBegin_DA(DM da, Vec g, InsertMode mode, Vec l) 66 { 67 DM_DA *dd = (DM_DA *)da->data; 68 69 PetscFunctionBegin; 70 PetscValidHeaderSpecific(da, DM_CLASSID, 1); 71 if (!dd->ltol) PetscCall(DMLocalToLocalCreate_DA(da)); 72 PetscCall(VecScatterBegin(dd->ltol, g, l, mode, SCATTER_FORWARD)); 73 PetscFunctionReturn(PETSC_SUCCESS); 74 } 75 76 PetscErrorCode DMLocalToLocalEnd_DA(DM da, Vec g, InsertMode mode, Vec l) 77 { 78 DM_DA *dd = (DM_DA *)da->data; 79 80 PetscFunctionBegin; 81 PetscValidHeaderSpecific(da, DM_CLASSID, 1); 82 PetscValidHeaderSpecific(g, VEC_CLASSID, 2); 83 PetscCall(VecScatterEnd(dd->ltol, g, l, mode, SCATTER_FORWARD)); 84 PetscFunctionReturn(PETSC_SUCCESS); 85 } 86