17d0a6c19SBarry Smith 247c6ae99SBarry Smith /* 347c6ae99SBarry Smith Code for manipulating distributed regular 1d arrays in parallel. 447c6ae99SBarry Smith This file was created by Peter Mell 6/30/95 547c6ae99SBarry Smith */ 647c6ae99SBarry Smith 7af0996ceSBarry Smith #include <petsc/private/dmdaimpl.h> /*I "petscdmda.h" I*/ 847c6ae99SBarry Smith 99804daf3SBarry Smith #include <petscdraw.h> 10e0877f53SBarry Smith static PetscErrorCode DMView_DA_1d(DM da,PetscViewer viewer) 1147c6ae99SBarry Smith { 1247c6ae99SBarry Smith PetscMPIInt rank; 13c9493c35SStefano Zampini PetscBool iascii,isdraw,isglvis,isbinary; 1447c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 159a42bb27SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 169a42bb27SBarry Smith PetscBool ismatlab; 179a42bb27SBarry Smith #endif 1847c6ae99SBarry Smith 1947c6ae99SBarry Smith PetscFunctionBegin; 20*9566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)da),&rank)); 2147c6ae99SBarry Smith 22*9566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii)); 23*9566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw)); 24*9566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERGLVIS,&isglvis)); 25*9566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary)); 269a42bb27SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 27*9566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERMATLAB,&ismatlab)); 289a42bb27SBarry Smith #endif 2947c6ae99SBarry Smith if (iascii) { 3047c6ae99SBarry Smith PetscViewerFormat format; 3147c6ae99SBarry Smith 32*9566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 3376a8abe0SBarry Smith if (format == PETSC_VIEWER_LOAD_BALANCE) { 3476a8abe0SBarry Smith PetscInt i,nmax = 0,nmin = PETSC_MAX_INT,navg = 0,*nz,nzlocal; 3576a8abe0SBarry Smith DMDALocalInfo info; 3676a8abe0SBarry Smith PetscMPIInt size; 37*9566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)da),&size)); 38*9566063dSJacob Faibussowitsch PetscCall(DMDAGetLocalInfo(da,&info)); 3976a8abe0SBarry Smith nzlocal = info.xm; 40*9566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size,&nz)); 41*9566063dSJacob Faibussowitsch PetscCallMPI(MPI_Allgather(&nzlocal,1,MPIU_INT,nz,1,MPIU_INT,PetscObjectComm((PetscObject)da))); 4276a8abe0SBarry Smith for (i=0; i<(PetscInt)size; i++) { 4376a8abe0SBarry Smith nmax = PetscMax(nmax,nz[i]); 4476a8abe0SBarry Smith nmin = PetscMin(nmin,nz[i]); 4576a8abe0SBarry Smith navg += nz[i]; 4676a8abe0SBarry Smith } 47*9566063dSJacob Faibussowitsch PetscCall(PetscFree(nz)); 4876a8abe0SBarry Smith navg = navg/size; 49*9566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Load Balance - Grid Points: Min %D avg %D max %D\n",nmin,navg,nmax)); 5076a8abe0SBarry Smith PetscFunctionReturn(0); 5176a8abe0SBarry Smith } 528ec8862eSJed Brown if (format != PETSC_VIEWER_ASCII_VTK_DEPRECATED && format != PETSC_VIEWER_ASCII_VTK_CELL_DEPRECATED && format != PETSC_VIEWER_ASCII_GLVIS) { 53aa219208SBarry Smith DMDALocalInfo info; 54*9566063dSJacob Faibussowitsch PetscCall(DMDAGetLocalInfo(da,&info)); 55*9566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushSynchronized(viewer)); 56*9566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISynchronizedPrintf(viewer,"Processor [%d] M %D m %D w %D s %D\n",rank,dd->M,dd->m,dd->w,dd->s)); 57*9566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISynchronizedPrintf(viewer,"X range of indices: %D %D\n",info.xs,info.xs+info.xm)); 58*9566063dSJacob Faibussowitsch PetscCall(PetscViewerFlush(viewer)); 59*9566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopSynchronized(viewer)); 608135c375SStefano Zampini } else if (format == PETSC_VIEWER_ASCII_GLVIS) { 61*9566063dSJacob Faibussowitsch PetscCall(DMView_DA_GLVis(da,viewer)); 629a42bb27SBarry Smith } else { 63*9566063dSJacob Faibussowitsch PetscCall(DMView_DA_VTK(da, viewer)); 6447c6ae99SBarry Smith } 6547c6ae99SBarry Smith } else if (isdraw) { 6647c6ae99SBarry Smith PetscDraw draw; 6747c6ae99SBarry Smith double ymin = -1,ymax = 1,xmin = -1,xmax = dd->M,x; 6847c6ae99SBarry Smith PetscInt base; 6947c6ae99SBarry Smith char node[10]; 7047c6ae99SBarry Smith PetscBool isnull; 715f80ce2aSJacob Faibussowitsch PetscErrorCode ierr; 7247c6ae99SBarry Smith 73*9566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDraw(viewer,0,&draw)); 74*9566063dSJacob Faibussowitsch PetscCall(PetscDrawIsNull(draw,&isnull)); 755b399a63SLisandro Dalcin if (isnull) PetscFunctionReturn(0); 765b399a63SLisandro Dalcin 77*9566063dSJacob Faibussowitsch PetscCall(PetscDrawCheckResizedWindow(draw)); 78*9566063dSJacob Faibussowitsch PetscCall(PetscDrawClear(draw)); 79*9566063dSJacob Faibussowitsch PetscCall(PetscDrawSetCoordinates(draw,xmin,ymin,xmax,ymax)); 8047c6ae99SBarry Smith 81*9566063dSJacob Faibussowitsch ierr = PetscDrawCollectiveBegin(draw);PetscCall(ierr); 8247c6ae99SBarry Smith /* first processor draws all node lines */ 83dd400576SPatrick Sanan if (rank == 0) { 8447c6ae99SBarry Smith PetscInt xmin_tmp; 8547c6ae99SBarry Smith ymin = 0.0; ymax = 0.3; 8647c6ae99SBarry Smith for (xmin_tmp=0; xmin_tmp < dd->M; xmin_tmp++) { 87*9566063dSJacob Faibussowitsch PetscCall(PetscDrawLine(draw,(double)xmin_tmp,ymin,(double)xmin_tmp,ymax,PETSC_DRAW_BLACK)); 8847c6ae99SBarry Smith } 8947c6ae99SBarry Smith xmin = 0.0; xmax = dd->M - 1; 90*9566063dSJacob Faibussowitsch PetscCall(PetscDrawLine(draw,xmin,ymin,xmax,ymin,PETSC_DRAW_BLACK)); 91*9566063dSJacob Faibussowitsch PetscCall(PetscDrawLine(draw,xmin,ymax,xmax,ymax,PETSC_DRAW_BLACK)); 9247c6ae99SBarry Smith } 93*9566063dSJacob Faibussowitsch ierr = PetscDrawCollectiveEnd(draw);PetscCall(ierr); 94*9566063dSJacob Faibussowitsch PetscCall(PetscDrawFlush(draw)); 95*9566063dSJacob Faibussowitsch PetscCall(PetscDrawPause(draw)); 9647c6ae99SBarry Smith 97*9566063dSJacob Faibussowitsch ierr = PetscDrawCollectiveBegin(draw);PetscCall(ierr); 9847c6ae99SBarry Smith /* draw my box */ 9947c6ae99SBarry Smith ymin = 0; ymax = 0.3; xmin = dd->xs / dd->w; xmax = (dd->xe / dd->w) - 1; 100*9566063dSJacob Faibussowitsch PetscCall(PetscDrawLine(draw,xmin,ymin,xmax,ymin,PETSC_DRAW_RED)); 101*9566063dSJacob Faibussowitsch PetscCall(PetscDrawLine(draw,xmin,ymin,xmin,ymax,PETSC_DRAW_RED)); 102*9566063dSJacob Faibussowitsch PetscCall(PetscDrawLine(draw,xmin,ymax,xmax,ymax,PETSC_DRAW_RED)); 103*9566063dSJacob Faibussowitsch PetscCall(PetscDrawLine(draw,xmax,ymin,xmax,ymax,PETSC_DRAW_RED)); 10447c6ae99SBarry Smith /* Put in index numbers */ 10547c6ae99SBarry Smith base = dd->base / dd->w; 10647c6ae99SBarry Smith for (x=xmin; x<=xmax; x++) { 107*9566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(node,sizeof(node),"%d",(int)base++)); 108*9566063dSJacob Faibussowitsch PetscCall(PetscDrawString(draw,x,ymin,PETSC_DRAW_RED,node)); 10947c6ae99SBarry Smith } 110*9566063dSJacob Faibussowitsch ierr = PetscDrawCollectiveEnd(draw);PetscCall(ierr); 111*9566063dSJacob Faibussowitsch PetscCall(PetscDrawFlush(draw)); 112*9566063dSJacob Faibussowitsch PetscCall(PetscDrawPause(draw)); 113*9566063dSJacob Faibussowitsch PetscCall(PetscDrawSave(draw)); 114c9493c35SStefano Zampini } else if (isglvis) { 115*9566063dSJacob Faibussowitsch PetscCall(DMView_DA_GLVis(da,viewer)); 1169a42bb27SBarry Smith } else if (isbinary) { 117*9566063dSJacob Faibussowitsch PetscCall(DMView_DA_Binary(da,viewer)); 1189a42bb27SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 1199a42bb27SBarry Smith } else if (ismatlab) { 120*9566063dSJacob Faibussowitsch PetscCall(DMView_DA_Matlab(da,viewer)); 1219a42bb27SBarry Smith #endif 12211aeaf0aSBarry Smith } 12347c6ae99SBarry Smith PetscFunctionReturn(0); 12447c6ae99SBarry Smith } 12547c6ae99SBarry Smith 1267087cfbeSBarry Smith PetscErrorCode DMSetUp_DA_1D(DM da) 12747c6ae99SBarry Smith { 12847c6ae99SBarry Smith DM_DA *dd = (DM_DA*)da->data; 12947c6ae99SBarry Smith const PetscInt M = dd->M; 13047c6ae99SBarry Smith const PetscInt dof = dd->w; 13147c6ae99SBarry Smith const PetscInt s = dd->s; 13245b6f7e9SBarry Smith const PetscInt sDist = s; /* stencil distance in points */ 13347c6ae99SBarry Smith const PetscInt *lx = dd->lx; 134bff4a2f0SMatthew G. Knepley DMBoundaryType bx = dd->bx; 13547c6ae99SBarry Smith MPI_Comm comm; 13647c6ae99SBarry Smith Vec local, global; 137bd1fc5aeSBarry Smith VecScatter gtol; 13847c6ae99SBarry Smith IS to, from; 13947c6ae99SBarry Smith PetscBool flg1 = PETSC_FALSE, flg2 = PETSC_FALSE; 14047c6ae99SBarry Smith PetscMPIInt rank, size; 141bd1fc5aeSBarry Smith PetscInt i,*idx,nn,left,xs,xe,x,Xs,Xe,start,m,IXs,IXe; 14247c6ae99SBarry Smith 14347c6ae99SBarry Smith PetscFunctionBegin; 144*9566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject) da, &comm)); 145*9566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm,&size)); 146*9566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm,&rank)); 14747c6ae99SBarry Smith 1487d310018SBarry Smith dd->p = 1; 1497d310018SBarry Smith dd->n = 1; 15047c6ae99SBarry Smith dd->m = size; 15147c6ae99SBarry Smith m = dd->m; 15247c6ae99SBarry Smith 15347c6ae99SBarry Smith if (s > 0) { 15447c6ae99SBarry Smith /* if not communicating data then should be ok to have nothing on some processes */ 1557a8be351SBarry Smith PetscCheck(M >= m,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"More processes than data points! %D %D",m,M); 1567a8be351SBarry Smith PetscCheck((M-1) >= s || size <= 1,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Array is too small for stencil! %D %D",M-1,s); 15747c6ae99SBarry Smith } 15847c6ae99SBarry Smith 15947c6ae99SBarry Smith /* 16047c6ae99SBarry Smith Determine locally owned region 16147c6ae99SBarry Smith xs is the first local node number, x is the number of local nodes 16247c6ae99SBarry Smith */ 16347c6ae99SBarry Smith if (!lx) { 164*9566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m, &dd->lx)); 165*9566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(((PetscObject)da)->options,((PetscObject)da)->prefix,"-da_partition_blockcomm",&flg1,NULL)); 166*9566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(((PetscObject)da)->options,((PetscObject)da)->prefix,"-da_partition_nodes_at_end",&flg2,NULL)); 16747c6ae99SBarry Smith if (flg1) { /* Block Comm type Distribution */ 16847c6ae99SBarry Smith xs = rank*M/m; 16947c6ae99SBarry Smith x = (rank + 1)*M/m - xs; 17047c6ae99SBarry Smith } else if (flg2) { /* The odd nodes are evenly distributed across last nodes */ 17147c6ae99SBarry Smith x = (M + rank)/m; 1728865f1eaSKarl Rupp if (M/m == x) xs = rank*x; 1738865f1eaSKarl Rupp else xs = rank*(x-1) + (M+rank)%(x*m); 17447c6ae99SBarry Smith } else { /* The odd nodes are evenly distributed across the first k nodes */ 17547c6ae99SBarry Smith /* Regular PETSc Distribution */ 17647c6ae99SBarry Smith x = M/m + ((M % m) > rank); 1778865f1eaSKarl Rupp if (rank >= (M % m)) xs = (rank * (PetscInt)(M/m) + M % m); 1788865f1eaSKarl Rupp else xs = rank * (PetscInt)(M/m) + rank; 17947c6ae99SBarry Smith } 180*9566063dSJacob Faibussowitsch PetscCallMPI(MPI_Allgather(&xs,1,MPIU_INT,dd->lx,1,MPIU_INT,comm)); 181fe16a2e9SBarry Smith for (i=0; i<m-1; i++) dd->lx[i] = dd->lx[i+1] - dd->lx[i]; 182fe16a2e9SBarry Smith dd->lx[m-1] = M - dd->lx[m-1]; 18347c6ae99SBarry Smith } else { 18447c6ae99SBarry Smith x = lx[rank]; 18547c6ae99SBarry Smith xs = 0; 1868865f1eaSKarl Rupp for (i=0; i<rank; i++) xs += lx[i]; 18747c6ae99SBarry Smith /* verify that data user provided is consistent */ 18847c6ae99SBarry Smith left = xs; 1898865f1eaSKarl Rupp for (i=rank; i<size; i++) left += lx[i]; 1907a8be351SBarry Smith PetscCheck(left == M,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Sum of lx across processors not equal to M %D %D",left,M); 19147c6ae99SBarry Smith } 19247c6ae99SBarry Smith 193bcea557cSEthan Coon /* 194bcea557cSEthan Coon check if the scatter requires more than one process neighbor or wraps around 195bcea557cSEthan Coon the domain more than once 196bcea557cSEthan Coon */ 1977a8be351SBarry Smith PetscCheck((x >= s) || ((M <= 1) && (bx != DM_BOUNDARY_PERIODIC)),PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local x-width of domain x %D is smaller than stencil width s %D",x,s); 198bcea557cSEthan Coon 19947c6ae99SBarry Smith xe = xs + x; 20047c6ae99SBarry Smith 20188661749SPeter Brune /* determine ghost region (Xs) and region scattered into (IXs) */ 202d9c9ebe5SPeter Brune if (xs-sDist > 0) { 203d9c9ebe5SPeter Brune Xs = xs - sDist; 204d9c9ebe5SPeter Brune IXs = xs - sDist; 20588661749SPeter Brune } else { 2068865f1eaSKarl Rupp if (bx) Xs = xs - sDist; 2078865f1eaSKarl Rupp else Xs = 0; 20888661749SPeter Brune IXs = 0; 20988661749SPeter Brune } 21045b6f7e9SBarry Smith if (xe+sDist <= M) { 211d9c9ebe5SPeter Brune Xe = xe + sDist; 212d9c9ebe5SPeter Brune IXe = xe + sDist; 21388661749SPeter Brune } else { 2148865f1eaSKarl Rupp if (bx) Xe = xe + sDist; 21545b6f7e9SBarry Smith else Xe = M; 21645b6f7e9SBarry Smith IXe = M; 21747c6ae99SBarry Smith } 21847c6ae99SBarry Smith 219bff4a2f0SMatthew G. Knepley if (bx == DM_BOUNDARY_PERIODIC || bx == DM_BOUNDARY_MIRROR) { 220d9c9ebe5SPeter Brune Xs = xs - sDist; 221d9c9ebe5SPeter Brune Xe = xe + sDist; 222d9c9ebe5SPeter Brune IXs = xs - sDist; 223d9c9ebe5SPeter Brune IXe = xe + sDist; 224ce00eea3SSatish Balay } 225ce00eea3SSatish Balay 22647c6ae99SBarry Smith /* allocate the base parallel and sequential vectors */ 22745b6f7e9SBarry Smith dd->Nlocal = dof*x; 228*9566063dSJacob Faibussowitsch PetscCall(VecCreateMPIWithArray(comm,dof,dd->Nlocal,PETSC_DECIDE,NULL,&global)); 22945b6f7e9SBarry Smith dd->nlocal = dof*(Xe-Xs); 230*9566063dSJacob Faibussowitsch PetscCall(VecCreateSeqWithArray(PETSC_COMM_SELF,dof,dd->nlocal,NULL,&local)); 23147c6ae99SBarry Smith 232*9566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(global,&start,NULL)); 23347c6ae99SBarry Smith 23447c6ae99SBarry Smith /* Create Global to Local Vector Scatter Context */ 23547c6ae99SBarry Smith /* global to local must retrieve ghost points */ 236*9566063dSJacob Faibussowitsch PetscCall(ISCreateStride(comm,dof*(IXe-IXs),dof*(IXs-Xs),1,&to)); 23747c6ae99SBarry Smith 238*9566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(x+2*sDist,&idx)); 239*9566063dSJacob Faibussowitsch PetscCall(PetscLogObjectMemory((PetscObject)da,(x+2*(sDist))*sizeof(PetscInt))); 24047c6ae99SBarry Smith 2418865f1eaSKarl Rupp for (i=0; i<IXs-Xs; i++) idx[i] = -1; /* prepend with -1s if needed for ghosted case*/ 24247c6ae99SBarry Smith 243ce00eea3SSatish Balay nn = IXs-Xs; 244bff4a2f0SMatthew G. Knepley if (bx == DM_BOUNDARY_PERIODIC) { /* Handle all cases with periodic first */ 245d9c9ebe5SPeter Brune for (i=0; i<sDist; i++) { /* Left ghost points */ 2468865f1eaSKarl Rupp if ((xs-sDist+i)>=0) idx[nn++] = xs-sDist+i; 24745b6f7e9SBarry Smith else idx[nn++] = M+(xs-sDist+i); 24847c6ae99SBarry Smith } 24947c6ae99SBarry Smith 2508865f1eaSKarl Rupp for (i=0; i<x; i++) idx [nn++] = xs + i; /* Non-ghost points */ 25147c6ae99SBarry Smith 252d9c9ebe5SPeter Brune for (i=0; i<sDist; i++) { /* Right ghost points */ 25345b6f7e9SBarry Smith if ((xe+i)<M) idx [nn++] = xe+i; 25445b6f7e9SBarry Smith else idx [nn++] = (xe+i) - M; 25547c6ae99SBarry Smith } 256bff4a2f0SMatthew G. Knepley } else if (bx == DM_BOUNDARY_MIRROR) { /* Handle all cases with periodic first */ 25745b6f7e9SBarry Smith for (i=0; i<(sDist); i++) { /* Left ghost points */ 25845b6f7e9SBarry Smith if ((xs-sDist+i)>=0) idx[nn++] = xs-sDist+i; 25945b6f7e9SBarry Smith else idx[nn++] = sDist - i; 26005900f5bSBarry Smith } 26105900f5bSBarry Smith 2628865f1eaSKarl Rupp for (i=0; i<x; i++) idx [nn++] = xs + i; /* Non-ghost points */ 26305900f5bSBarry Smith 26445b6f7e9SBarry Smith for (i=0; i<(sDist); i++) { /* Right ghost points */ 265662a7babSBarry Smith if ((xe+i)<M) idx[nn++] = xe+i; 266288e7d53SBarry Smith else idx[nn++] = M - (i + 2); 26705900f5bSBarry Smith } 26805900f5bSBarry Smith } else { /* Now do all cases with no periodicity */ 2698865f1eaSKarl Rupp if (0 <= xs-sDist) { 2708865f1eaSKarl Rupp for (i=0; i<sDist; i++) idx[nn++] = xs - sDist + i; 2718865f1eaSKarl Rupp } else { 2728865f1eaSKarl Rupp for (i=0; i<xs; i++) idx[nn++] = i; 2738865f1eaSKarl Rupp } 27447c6ae99SBarry Smith 2758865f1eaSKarl Rupp for (i=0; i<x; i++) idx [nn++] = xs + i; 27647c6ae99SBarry Smith 27745b6f7e9SBarry Smith if ((xe+sDist)<=M) { 2788865f1eaSKarl Rupp for (i=0; i<sDist; i++) idx[nn++]=xe+i; 2798865f1eaSKarl Rupp } else { 28045b6f7e9SBarry Smith for (i=xe; i<M; i++) idx[nn++]=i; 2818865f1eaSKarl Rupp } 28247c6ae99SBarry Smith } 28347c6ae99SBarry Smith 284*9566063dSJacob Faibussowitsch PetscCall(ISCreateBlock(comm,dof,nn-IXs+Xs,&idx[IXs-Xs],PETSC_USE_POINTER,&from)); 285*9566063dSJacob Faibussowitsch PetscCall(VecScatterCreate(global,from,local,to,>ol)); 286*9566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParent((PetscObject)da,(PetscObject)gtol)); 287*9566063dSJacob Faibussowitsch PetscCall(ISDestroy(&to)); 288*9566063dSJacob Faibussowitsch PetscCall(ISDestroy(&from)); 289*9566063dSJacob Faibussowitsch PetscCall(VecDestroy(&local)); 290*9566063dSJacob Faibussowitsch PetscCall(VecDestroy(&global)); 29147c6ae99SBarry Smith 292d6e23781SBarry Smith dd->xs = dof*xs; dd->xe = dof*xe; dd->ys = 0; dd->ye = 1; dd->zs = 0; dd->ze = 1; 293d6e23781SBarry Smith dd->Xs = dof*Xs; dd->Xe = dof*Xe; dd->Ys = 0; dd->Ye = 1; dd->Zs = 0; dd->Ze = 1; 29447c6ae99SBarry Smith 29547c6ae99SBarry Smith dd->gtol = gtol; 296d6e23781SBarry Smith dd->base = dof*xs; 2979a42bb27SBarry Smith da->ops->view = DMView_DA_1d; 29847c6ae99SBarry Smith 29947c6ae99SBarry Smith /* 30047c6ae99SBarry Smith Set the local to global ordering in the global vector, this allows use 30147c6ae99SBarry Smith of VecSetValuesLocal(). 30247c6ae99SBarry Smith */ 3038865f1eaSKarl Rupp for (i=0; i<Xe-IXe; i++) idx[nn++] = -1; /* pad with -1s if needed for ghosted case*/ 304ce00eea3SSatish Balay 305*9566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingCreate(comm,dof,nn,idx,PETSC_OWN_POINTER,&da->ltogmap)); 306*9566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParent((PetscObject)da,(PetscObject)da->ltogmap)); 30747c6ae99SBarry Smith 30847c6ae99SBarry Smith PetscFunctionReturn(0); 30947c6ae99SBarry Smith } 310d7bf68aeSBarry Smith 31147c6ae99SBarry Smith /*@C 312aa219208SBarry Smith DMDACreate1d - Creates an object that will manage the communication of one-dimensional 31347c6ae99SBarry Smith regular array data that is distributed across some processors. 31447c6ae99SBarry Smith 315d083f849SBarry Smith Collective 31647c6ae99SBarry Smith 31747c6ae99SBarry Smith Input Parameters: 31847c6ae99SBarry Smith + comm - MPI communicator 3191321219cSEthan Coon . bx - type of ghost cells at the boundary the array should have, if any. Use 320bff4a2f0SMatthew G. Knepley DM_BOUNDARY_NONE, DM_BOUNDARY_GHOSTED, or DM_BOUNDARY_PERIODIC. 321e43dc8daSBarry Smith . M - global dimension of the array (that is the number of grid points) 32247c6ae99SBarry Smith from the command line with -da_grid_x <M>) 32347c6ae99SBarry Smith . dof - number of degrees of freedom per node 32447c6ae99SBarry Smith . s - stencil width 32547c6ae99SBarry Smith - lx - array containing number of nodes in the X direction on each processor, 3260298fd71SBarry Smith or NULL. If non-null, must be of length as the number of processes in the MPI_Comm. 327e43dc8daSBarry Smith The sum of these entries must equal M 32847c6ae99SBarry Smith 32947c6ae99SBarry Smith Output Parameter: 33047c6ae99SBarry Smith . da - the resulting distributed array object 33147c6ae99SBarry Smith 33247c6ae99SBarry Smith Options Database Key: 333706a11cbSBarry Smith + -dm_view - Calls DMView() at the conclusion of DMDACreate1d() 334e43dc8daSBarry Smith . -da_grid_x <nx> - number of grid points in x direction 335e0f5d30fSBarry Smith . -da_refine_x <rx> - refinement factor 336e43dc8daSBarry Smith - -da_refine <n> - refine the DMDA n times before creating it 33747c6ae99SBarry Smith 33847c6ae99SBarry Smith Level: beginner 33947c6ae99SBarry Smith 34047c6ae99SBarry Smith Notes: 341aa219208SBarry Smith The array data itself is NOT stored in the DMDA, it is stored in Vec objects; 342564755cdSBarry Smith The appropriate vector objects can be obtained with calls to DMCreateGlobalVector() 343564755cdSBarry Smith and DMCreateLocalVector() and calls to VecDuplicate() if more are needed. 34447c6ae99SBarry Smith 345897f7067SBarry Smith You must call DMSetUp() after this call before using this DM. 346897f7067SBarry Smith 347897f7067SBarry Smith If you wish to use the options database to change values in the DMDA call DMSetFromOptions() after this call 348897f7067SBarry Smith but before DMSetUp(). 349897f7067SBarry Smith 350aa219208SBarry Smith .seealso: DMDestroy(), DMView(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(), DMDASetRefinementFactor(), 35199f0b487SRichard Tran Mills DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMLocalToLocalBegin(), DMLocalToLocalEnd(), DMDAGetRefinementFactor(), 3523bd220d7SPatrick Sanan DMDAGetInfo(), DMCreateGlobalVector(), DMCreateLocalVector(), DMDACreateNaturalVector(), DMLoad(), DMDAGetOwnershipRanges(), 3533bd220d7SPatrick Sanan DMStagCreate1d() 35447c6ae99SBarry Smith 35547c6ae99SBarry Smith @*/ 356bff4a2f0SMatthew G. Knepley PetscErrorCode DMDACreate1d(MPI_Comm comm, DMBoundaryType bx, PetscInt M, PetscInt dof, PetscInt s, const PetscInt lx[], DM *da) 35747c6ae99SBarry Smith { 35847c6ae99SBarry Smith PetscMPIInt size; 35947c6ae99SBarry Smith 36047c6ae99SBarry Smith PetscFunctionBegin; 361*9566063dSJacob Faibussowitsch PetscCall(DMDACreate(comm, da)); 362*9566063dSJacob Faibussowitsch PetscCall(DMSetDimension(*da, 1)); 363*9566063dSJacob Faibussowitsch PetscCall(DMDASetSizes(*da, M, 1, 1)); 364*9566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 365*9566063dSJacob Faibussowitsch PetscCall(DMDASetNumProcs(*da, size, PETSC_DECIDE, PETSC_DECIDE)); 366*9566063dSJacob Faibussowitsch PetscCall(DMDASetBoundaryType(*da, bx, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE)); 367*9566063dSJacob Faibussowitsch PetscCall(DMDASetDof(*da, dof)); 368*9566063dSJacob Faibussowitsch PetscCall(DMDASetStencilWidth(*da, s)); 369*9566063dSJacob Faibussowitsch PetscCall(DMDASetOwnershipRanges(*da, lx, NULL, NULL)); 37047c6ae99SBarry Smith PetscFunctionReturn(0); 37147c6ae99SBarry Smith } 372