xref: /petsc/src/dm/impls/da/daltol.c (revision b45d2f2cb7e031d9c0de5873eca80614ca7b863b)
147c6ae99SBarry Smith 
247c6ae99SBarry Smith /*
347c6ae99SBarry Smith   Code for manipulating distributed regular arrays in parallel.
447c6ae99SBarry Smith */
547c6ae99SBarry Smith 
6*b45d2f2cSJed Brown #include <petsc-private/daimpl.h>    /*I   "petscdmda.h"   I*/
747c6ae99SBarry Smith 
847c6ae99SBarry Smith #undef __FUNCT__
99a42bb27SBarry Smith #define __FUNCT__ "DMDALocalToLocalCreate"
1047c6ae99SBarry Smith /*
119a42bb27SBarry Smith    DMDALocalToLocalCreate - Creates the local to local scatter
1247c6ae99SBarry Smith 
13aa219208SBarry Smith    Collective on DMDA
1447c6ae99SBarry Smith 
1547c6ae99SBarry Smith    Input Parameter:
1647c6ae99SBarry Smith .  da - the distributed array
1747c6ae99SBarry Smith 
1847c6ae99SBarry Smith */
197087cfbeSBarry Smith PetscErrorCode  DMDALocalToLocalCreate(DM da)
2047c6ae99SBarry Smith {
2147c6ae99SBarry Smith   PetscErrorCode ierr;
2247c6ae99SBarry Smith   PetscInt       *idx,left,j,count,up,down,i,bottom,top,k;
2347c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
2447c6ae99SBarry Smith 
2547c6ae99SBarry Smith   PetscFunctionBegin;
2647c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
2747c6ae99SBarry Smith 
2847c6ae99SBarry Smith   if (dd->ltol) PetscFunctionReturn(0);
2947c6ae99SBarry Smith   /*
3047c6ae99SBarry Smith      We simply remap the values in the from part of
3147c6ae99SBarry Smith      global to local to read from an array with the ghost values
3247c6ae99SBarry Smith      rather then from the plain array.
3347c6ae99SBarry Smith   */
3447c6ae99SBarry Smith   ierr = VecScatterCopy(dd->gtol,&dd->ltol);CHKERRQ(ierr);
3547c6ae99SBarry Smith   ierr = PetscLogObjectParent(da,dd->ltol);CHKERRQ(ierr);
3647c6ae99SBarry Smith   if (dd->dim == 1) {
3747c6ae99SBarry Smith     left = dd->xs - dd->Xs;
3847c6ae99SBarry Smith     ierr = PetscMalloc((dd->xe-dd->xs)*sizeof(PetscInt),&idx);CHKERRQ(ierr);
3947c6ae99SBarry Smith     for (j=0; j<dd->xe-dd->xs; j++) {
4047c6ae99SBarry Smith       idx[j] = left + j;
4147c6ae99SBarry Smith     }
4247c6ae99SBarry Smith   } else if (dd->dim == 2) {
4347c6ae99SBarry Smith     left  = dd->xs - dd->Xs; down  = dd->ys - dd->Ys; up    = down + dd->ye-dd->ys;
4447c6ae99SBarry Smith     ierr = PetscMalloc((dd->xe-dd->xs)*(up - down)*sizeof(PetscInt),&idx);CHKERRQ(ierr);
4547c6ae99SBarry Smith     count = 0;
4647c6ae99SBarry Smith     for (i=down; i<up; i++) {
4747c6ae99SBarry Smith       for (j=0; j<dd->xe-dd->xs; j++) {
4847c6ae99SBarry Smith 	idx[count++] = left + i*(dd->Xe-dd->Xs) + j;
4947c6ae99SBarry Smith       }
5047c6ae99SBarry Smith     }
5147c6ae99SBarry Smith   } else if (dd->dim == 3) {
5247c6ae99SBarry Smith     left   = dd->xs - dd->Xs;
5347c6ae99SBarry Smith     bottom = dd->ys - dd->Ys; top = bottom + dd->ye-dd->ys ;
5447c6ae99SBarry Smith     down   = dd->zs - dd->Zs; up  = down + dd->ze-dd->zs;
5547c6ae99SBarry Smith     count  = (dd->xe-dd->xs)*(top-bottom)*(up-down);
5647c6ae99SBarry Smith     ierr = PetscMalloc(count*sizeof(PetscInt),&idx);CHKERRQ(ierr);
5747c6ae99SBarry Smith     count  = 0;
5847c6ae99SBarry Smith     for (i=down; i<up; i++) {
5947c6ae99SBarry Smith       for (j=bottom; j<top; j++) {
6047c6ae99SBarry Smith 	for (k=0; k<dd->xe-dd->xs; k++) {
6147c6ae99SBarry Smith 	  idx[count++] = (left+j*(dd->Xe-dd->Xs))+i*(dd->Xe-dd->Xs)*(dd->Ye-dd->Ys) + k;
6247c6ae99SBarry Smith 	}
6347c6ae99SBarry Smith       }
6447c6ae99SBarry Smith     }
65aa219208SBarry Smith   } else SETERRQ1(((PetscObject)da)->comm,PETSC_ERR_ARG_CORRUPT,"DMDA has invalid dimension %D",dd->dim);
6647c6ae99SBarry Smith 
6747c6ae99SBarry Smith   ierr = VecScatterRemap(dd->ltol,idx,PETSC_NULL);CHKERRQ(ierr);
6847c6ae99SBarry Smith   ierr = PetscFree(idx);CHKERRQ(ierr);
6947c6ae99SBarry Smith   PetscFunctionReturn(0);
7047c6ae99SBarry Smith }
7147c6ae99SBarry Smith 
7247c6ae99SBarry Smith #undef __FUNCT__
73aa219208SBarry Smith #define __FUNCT__ "DMDALocalToLocalBegin"
7447c6ae99SBarry Smith /*@
75aa219208SBarry Smith    DMDALocalToLocalBegin - Maps from a local vector (including ghost points
7647c6ae99SBarry Smith    that contain irrelevant values) to another local vector where the ghost
77aa219208SBarry Smith    points in the second are set correctly. Must be followed by DMDALocalToLocalEnd().
7847c6ae99SBarry Smith 
79aa219208SBarry Smith    Neighbor-wise Collective on DMDA and Vec
8047c6ae99SBarry Smith 
8147c6ae99SBarry Smith    Input Parameters:
8247c6ae99SBarry Smith +  da - the distributed array context
8347c6ae99SBarry Smith .  g - the original local vector
8447c6ae99SBarry Smith -  mode - one of INSERT_VALUES or ADD_VALUES
8547c6ae99SBarry Smith 
8647c6ae99SBarry Smith    Output Parameter:
8747c6ae99SBarry Smith .  l  - the local vector with correct ghost values
8847c6ae99SBarry Smith 
8947c6ae99SBarry Smith    Level: intermediate
9047c6ae99SBarry Smith 
9147c6ae99SBarry Smith    Notes:
9247c6ae99SBarry Smith    The local vectors used here need not be the same as those
93564755cdSBarry Smith    obtained from DMCreateLocalVector(), BUT they
9447c6ae99SBarry Smith    must have the same parallel data layout; they could, for example, be
95aa219208SBarry Smith    obtained with VecDuplicate() from the DMDA originating vectors.
9647c6ae99SBarry Smith 
9747c6ae99SBarry Smith .keywords: distributed array, local-to-local, begin
9847c6ae99SBarry Smith 
99aa219208SBarry Smith .seealso: DMDALocalToLocalEnd(), DMLocalToGlobalBegin()
10047c6ae99SBarry Smith @*/
1017087cfbeSBarry Smith PetscErrorCode  DMDALocalToLocalBegin(DM da,Vec g,InsertMode mode,Vec l)
10247c6ae99SBarry Smith {
10347c6ae99SBarry Smith   PetscErrorCode ierr;
10447c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
10547c6ae99SBarry Smith 
10647c6ae99SBarry Smith   PetscFunctionBegin;
10747c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
10847c6ae99SBarry Smith   if (!dd->ltol) {
1099a42bb27SBarry Smith     ierr = DMDALocalToLocalCreate(da);CHKERRQ(ierr);
11047c6ae99SBarry Smith   }
11147c6ae99SBarry Smith   ierr = VecScatterBegin(dd->ltol,g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr);
11247c6ae99SBarry Smith   PetscFunctionReturn(0);
11347c6ae99SBarry Smith }
11447c6ae99SBarry Smith 
11547c6ae99SBarry Smith #undef __FUNCT__
116aa219208SBarry Smith #define __FUNCT__ "DMDALocalToLocalEnd"
11747c6ae99SBarry Smith /*@
118aa219208SBarry Smith    DMDALocalToLocalEnd - Maps from a local vector (including ghost points
11947c6ae99SBarry Smith    that contain irrelevant values) to another local vector where the ghost
12047c6ae99SBarry Smith    points in the second are set correctly.  Must be preceeded by
121aa219208SBarry Smith    DMDALocalToLocalBegin().
12247c6ae99SBarry Smith 
123aa219208SBarry Smith    Neighbor-wise Collective on DMDA and Vec
12447c6ae99SBarry Smith 
12547c6ae99SBarry Smith    Input Parameters:
12647c6ae99SBarry Smith +  da - the distributed array context
12747c6ae99SBarry Smith .  g - the original local vector
12847c6ae99SBarry Smith -  mode - one of INSERT_VALUES or ADD_VALUES
12947c6ae99SBarry Smith 
13047c6ae99SBarry Smith    Output Parameter:
13147c6ae99SBarry Smith .  l  - the local vector with correct ghost values
13247c6ae99SBarry Smith 
13347c6ae99SBarry Smith    Level: intermediate
13447c6ae99SBarry Smith 
13547c6ae99SBarry Smith    Note:
13647c6ae99SBarry Smith    The local vectors used here need not be the same as those
137564755cdSBarry Smith    obtained from DMCreateLocalVector(), BUT they
13847c6ae99SBarry Smith    must have the same parallel data layout; they could, for example, be
139aa219208SBarry Smith    obtained with VecDuplicate() from the DMDA originating vectors.
14047c6ae99SBarry Smith 
14147c6ae99SBarry Smith .keywords: distributed array, local-to-local, end
14247c6ae99SBarry Smith 
143aa219208SBarry Smith .seealso: DMDALocalToLocalBegin(), DMLocalToGlobalBegin()
14447c6ae99SBarry Smith @*/
1457087cfbeSBarry Smith PetscErrorCode  DMDALocalToLocalEnd(DM da,Vec g,InsertMode mode,Vec l)
14647c6ae99SBarry Smith {
14747c6ae99SBarry Smith   PetscErrorCode ierr;
14847c6ae99SBarry Smith   DM_DA          *dd = (DM_DA*)da->data;
14947c6ae99SBarry Smith 
15047c6ae99SBarry Smith   PetscFunctionBegin;
15147c6ae99SBarry Smith   PetscValidHeaderSpecific(da,DM_CLASSID,1);
15247c6ae99SBarry Smith   PetscValidHeaderSpecific(g,VEC_CLASSID,2);
15347c6ae99SBarry Smith   PetscValidHeaderSpecific(g,VEC_CLASSID,4);
15447c6ae99SBarry Smith   ierr = VecScatterEnd(dd->ltol,g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr);
15547c6ae99SBarry Smith   PetscFunctionReturn(0);
15647c6ae99SBarry Smith }
15747c6ae99SBarry Smith 
158