147c6ae99SBarry Smith 247c6ae99SBarry Smith /* 347c6ae99SBarry Smith Code for manipulating distributed regular arrays in parallel. 447c6ae99SBarry Smith */ 547c6ae99SBarry Smith 6af0996ceSBarry Smith #include <petsc/private/dmdaimpl.h> /*I "petscdmda.h" I*/ 747c6ae99SBarry Smith 847c6ae99SBarry Smith /* 9d78e899eSRichard Tran Mills DMLocalToLocalCreate_DA - Creates the local to local scatter 1047c6ae99SBarry Smith 11d083f849SBarry Smith Collective on da 1247c6ae99SBarry Smith 1347c6ae99SBarry Smith Input Parameter: 1447c6ae99SBarry Smith . da - the distributed array 1547c6ae99SBarry Smith 1647c6ae99SBarry Smith */ 17d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToLocalCreate_DA(DM da) 18d71ae5a4SJacob Faibussowitsch { 19c73cfb54SMatthew G. Knepley PetscInt *idx, left, j, count, up, down, i, bottom, top, k, dim = da->dim; 2047c6ae99SBarry Smith DM_DA *dd = (DM_DA *)da->data; 2147c6ae99SBarry Smith 2247c6ae99SBarry Smith PetscFunctionBegin; 2347c6ae99SBarry Smith PetscValidHeaderSpecific(da, DM_CLASSID, 1); 2447c6ae99SBarry Smith 25*3ba16761SJacob Faibussowitsch if (dd->ltol) PetscFunctionReturn(PETSC_SUCCESS); 2647c6ae99SBarry Smith /* 2747c6ae99SBarry Smith We simply remap the values in the from part of 2847c6ae99SBarry Smith global to local to read from an array with the ghost values 2947c6ae99SBarry Smith rather then from the plain array. 3047c6ae99SBarry Smith */ 319566063dSJacob Faibussowitsch PetscCall(VecScatterCopy(dd->gtol, &dd->ltol)); 32c73cfb54SMatthew G. Knepley if (dim == 1) { 3347c6ae99SBarry Smith left = dd->xs - dd->Xs; 349566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(dd->xe - dd->xs, &idx)); 358865f1eaSKarl Rupp for (j = 0; j < dd->xe - dd->xs; j++) idx[j] = left + j; 36c73cfb54SMatthew G. Knepley } else if (dim == 2) { 379371c9d4SSatish Balay left = dd->xs - dd->Xs; 389371c9d4SSatish Balay down = dd->ys - dd->Ys; 399371c9d4SSatish Balay up = down + dd->ye - dd->ys; 409566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((dd->xe - dd->xs) * (up - down), &idx)); 4147c6ae99SBarry Smith count = 0; 4247c6ae99SBarry Smith for (i = down; i < up; i++) { 43ad540459SPierre Jolivet for (j = 0; j < dd->xe - dd->xs; j++) idx[count++] = left + i * (dd->Xe - dd->Xs) + j; 4447c6ae99SBarry Smith } 45c73cfb54SMatthew G. Knepley } else if (dim == 3) { 4647c6ae99SBarry Smith left = dd->xs - dd->Xs; 479371c9d4SSatish Balay bottom = dd->ys - dd->Ys; 489371c9d4SSatish Balay top = bottom + dd->ye - dd->ys; 499371c9d4SSatish Balay down = dd->zs - dd->Zs; 509371c9d4SSatish Balay up = down + dd->ze - dd->zs; 5147c6ae99SBarry Smith count = (dd->xe - dd->xs) * (top - bottom) * (up - down); 529566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(count, &idx)); 5347c6ae99SBarry Smith count = 0; 5447c6ae99SBarry Smith for (i = down; i < up; i++) { 5547c6ae99SBarry Smith for (j = bottom; j < top; j++) { 56ad540459SPierre Jolivet 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; 5747c6ae99SBarry Smith } 5847c6ae99SBarry Smith } 5963a3b9bcSJacob Faibussowitsch } else SETERRQ(PetscObjectComm((PetscObject)da), PETSC_ERR_ARG_CORRUPT, "DMDA has invalid dimension %" PetscInt_FMT, dim); 6047c6ae99SBarry Smith 619566063dSJacob Faibussowitsch PetscCall(VecScatterRemap(dd->ltol, idx, NULL)); 629566063dSJacob Faibussowitsch PetscCall(PetscFree(idx)); 63*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6447c6ae99SBarry Smith } 6547c6ae99SBarry Smith 66d78e899eSRichard Tran Mills /* 67d78e899eSRichard Tran Mills DMLocalToLocalBegin_DA - Maps from a local vector (including ghost points 6847c6ae99SBarry Smith that contain irrelevant values) to another local vector where the ghost 69d78e899eSRichard Tran Mills points in the second are set correctly. Must be followed by DMLocalToLocalEnd_DA(). 7047c6ae99SBarry Smith 71d083f849SBarry Smith Neighbor-wise Collective on da 7247c6ae99SBarry Smith 7347c6ae99SBarry Smith Input Parameters: 7447c6ae99SBarry Smith + da - the distributed array context 7547c6ae99SBarry Smith . g - the original local vector 7647c6ae99SBarry Smith - mode - one of INSERT_VALUES or ADD_VALUES 7747c6ae99SBarry Smith 7847c6ae99SBarry Smith Output Parameter: 7947c6ae99SBarry Smith . l - the local vector with correct ghost values 8047c6ae99SBarry Smith 8147c6ae99SBarry Smith Notes: 8247c6ae99SBarry Smith The local vectors used here need not be the same as those 83564755cdSBarry Smith obtained from DMCreateLocalVector(), BUT they 8447c6ae99SBarry Smith must have the same parallel data layout; they could, for example, be 85aa219208SBarry Smith obtained with VecDuplicate() from the DMDA originating vectors. 8647c6ae99SBarry Smith 87d78e899eSRichard Tran Mills */ 88d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToLocalBegin_DA(DM da, Vec g, InsertMode mode, Vec l) 89d71ae5a4SJacob Faibussowitsch { 9047c6ae99SBarry Smith DM_DA *dd = (DM_DA *)da->data; 9147c6ae99SBarry Smith 9247c6ae99SBarry Smith PetscFunctionBegin; 9347c6ae99SBarry Smith PetscValidHeaderSpecific(da, DM_CLASSID, 1); 9448a46eb9SPierre Jolivet if (!dd->ltol) PetscCall(DMLocalToLocalCreate_DA(da)); 959566063dSJacob Faibussowitsch PetscCall(VecScatterBegin(dd->ltol, g, l, mode, SCATTER_FORWARD)); 96*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9747c6ae99SBarry Smith } 9847c6ae99SBarry Smith 99d78e899eSRichard Tran Mills /* 100d78e899eSRichard Tran Mills DMLocalToLocalEnd_DA - Maps from a local vector (including ghost points 10147c6ae99SBarry Smith that contain irrelevant values) to another local vector where the ghost 102a5b23f4aSJose E. Roman points in the second are set correctly. Must be preceded by 103d78e899eSRichard Tran Mills DMLocalToLocalBegin_DA(). 10447c6ae99SBarry Smith 105d083f849SBarry Smith Neighbor-wise Collective on da 10647c6ae99SBarry Smith 10747c6ae99SBarry Smith Input Parameters: 10847c6ae99SBarry Smith + da - the distributed array context 10947c6ae99SBarry Smith . g - the original local vector 11047c6ae99SBarry Smith - mode - one of INSERT_VALUES or ADD_VALUES 11147c6ae99SBarry Smith 11247c6ae99SBarry Smith Output Parameter: 11347c6ae99SBarry Smith . l - the local vector with correct ghost values 11447c6ae99SBarry Smith 11547c6ae99SBarry Smith Note: 11647c6ae99SBarry Smith The local vectors used here need not be the same as those 117564755cdSBarry Smith obtained from DMCreateLocalVector(), BUT they 11847c6ae99SBarry Smith must have the same parallel data layout; they could, for example, be 119aa219208SBarry Smith obtained with VecDuplicate() from the DMDA originating vectors. 12047c6ae99SBarry Smith 121d78e899eSRichard Tran Mills */ 122d71ae5a4SJacob Faibussowitsch PetscErrorCode DMLocalToLocalEnd_DA(DM da, Vec g, InsertMode mode, Vec l) 123d71ae5a4SJacob Faibussowitsch { 12447c6ae99SBarry Smith DM_DA *dd = (DM_DA *)da->data; 12547c6ae99SBarry Smith 12647c6ae99SBarry Smith PetscFunctionBegin; 12747c6ae99SBarry Smith PetscValidHeaderSpecific(da, DM_CLASSID, 1); 12847c6ae99SBarry Smith PetscValidHeaderSpecific(g, VEC_CLASSID, 2); 1299566063dSJacob Faibussowitsch PetscCall(VecScatterEnd(dd->ltol, g, l, mode, SCATTER_FORWARD)); 130*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13147c6ae99SBarry Smith } 132