/*@C DMDAVecGetArrayDOF - Returns a multiple dimension array that shares data with the underlying vector and is indexed using the global dimensions. Logically collective Input Parameter: + da - the distributed array - vec - the vector, either a vector the same size as one obtained with DMCreateGlobalVector() or DMCreateLocalVector() Output Parameter: . array - the array Notes: Call DMDAVecRestoreArrayDOF() once you have finished accessing the vector entries. In C, the indexing is "backwards" from what expects: array[k][j][i][DOF] NOT array[i][j][k][DOF]! In Fortran 90 you do not need a version of DMDAVecRestoreArrayDOF() just use DMDAVecRestoreArrayF90() and declare your array with one higher dimension, see src/dm/examples/tutorials/ex11f90.F Level: intermediate .keywords: distributed array, get, corners, nodes, local indices, coordinates .seealso: DMDAGetGhostCorners(), DMDAGetCorners(), VecGetArray(), VecRestoreArray(), DMDAVecRestoreArray(), DMDAVecGetArray(), DMDAVecRestoreArrayDOF() @*/ PetscErrorCode DMDAVecGetArrayDOF(DM da,Vec vec,void *array) { PetscErrorCode ierr; PetscInt xs,ys,zs,xm,ym,zm,gxs,gys,gzs,gxm,gym,gzm,N,dim,dof; PetscFunctionBegin; ierr = DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr); ierr = DMDAGetGhostCorners(da,&gxs,&gys,&gzs,&gxm,&gym,&gzm);CHKERRQ(ierr); ierr = DMDAGetInfo(da,&dim,0,0,0,0,0,0,&dof,0,0,0,0,0);CHKERRQ(ierr); /* Handle case where user passes in global vector as opposed to local */ ierr = VecGetLocalSize(vec,&N);CHKERRQ(ierr); if (N == xm*ym*zm*dof) { gxm = xm; gym = ym; gzm = zm; gxs = xs; gys = ys; gzs = zs; } else if (N != gxm*gym*gzm*dof) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Vector local size %D is not compatible with DMDA local sizes %D %D\n",N,xm*ym*zm*dof,gxm*gym*gzm*dof); if (dim == 1) { ierr = VecGetArray2d(vec,gxm,dof,gxs,0,(PetscScalar***)array);CHKERRQ(ierr); } else if (dim == 2) { ierr = VecGetArray3d(vec,gym,gxm,dof,gys,gxs,0,(PetscScalar****)array);CHKERRQ(ierr); } else if (dim == 3) { ierr = VecGetArray4d(vec,gzm,gym,gxm,dof,gzs,gys,gxs,0,(PetscScalar*****)array);CHKERRQ(ierr); } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,"DMDA dimension not 1, 2, or 3, it is %D\n",dim); PetscFunctionReturn(0); }
inline PetscErrorCode FFTPaddedGreenCube(PetscInt dim[]) { PetscInt slap1,slap2,slap,m1,m2,m3,m,mm,N; PetscReal scale; PetscScalar ***xa; PetscInt Istart,Iend,nLocalSlaps,nEntriesPerSlap; PetscErrorCode ierr; PetscBool flg = PETSC_FALSE; PetscFunctionBegin; N = Scat3DS.NumParticlePerSide; //Create RealSpaceCube of size dim: VecGetOwnershipRange(RealSpaceCube,&Istart,&Iend); VecGetLocalSize(RealSpaceCube,&nLocalSlaps); nEntriesPerSlap = dim[0]*dim[1]; nLocalSlaps = nLocalSlaps/nEntriesPerSlap; if((Istart>=0) && (Iend>0)) { slap1 = Istart/nEntriesPerSlap; slap2 = Iend/nEntriesPerSlap; } else { slap1 = ceil(dim[2]/(PetscReal)size)*rank; slap2 = slap1 + nLocalSlaps; cout<<"\nIstart = "<<Istart<<"\nIend = "<<Iend<<"\nslap1 = "<<slap1<<"\nslap2 = "<<slap2<<"\nslap2-slap1 = "<<slap2-slap1<<"\nnLocalSlaps = "<<nLocalSlaps<<"\n"; } ierr = VecGetArray3d(RealSpaceCube,dim[0],dim[1],nLocalSlaps,0,0,slap1,&xa);CHKERRQ(ierr); //Copy Green cube of size NxNxN: slap = (N>slap2)?(slap2):(N); for(m3=slap1;m3<slap;m3++) { for(m2=0;m2<N;m2++) { for(m1=0;m1<N;m1++) { xa[m1][m2][m3] = Scat3DS.Green3DF(m1,m2,m3); } } } if(rank==0) xa[0][0][0] = 1; //Pad the Green cube to have size dim=pow(2*N-2,3) for convolution: slap = (N>slap2)?(slap2):(N); for(m3=slap1;m3<slap;m3++) { for(m2=0;m2<N;m2++) { for(m1=N;m1<dim[0];m1++) { xa[m1][m2][m3] = Scat3DS.Green3DF(2*N-m1-2,m2,m3); } } } slap = (N>slap2)?(slap2):(N); for(m3=slap1;m3<slap;m3++) { for(m2=N;m2<dim[1];m2++) { for(m1=0;m1<N;m1++) { xa[m1][m2][m3] = Scat3DS.Green3DF(m1,2*N-m2-2,m3); } for(m1=N;m1<dim[0];m1++) { m = 2*N-m1-2; xa[m1][m2][m3] = Scat3DS.Green3DF(m,2*N-m2-2,m3); } } } slap = (N>slap1)?(N):(slap1); for(m3=slap;m3<slap2;m3++) { for(m2=0;m2<N;m2++) { for(m1=0;m1<N;m1++) { xa[m1][m2][m3] = Scat3DS.Green3DF(m1,m2,2*N-m3-2); } for(m1=N;m1<dim[0];m1++) { m = 2*N-m1-2; xa[m1][m2][m3] = Scat3DS.Green3DF(m,m2,2*N-m3-2); } } for(m2=N;m2<dim[1];m2++) { mm = 2*N-m2-2; for(m1=0;m1<N;m1++) { xa[m1][m2][m3] = Scat3DS.Green3DF(m1,mm,2*N-m3-2); } for(m1=N;m1<dim[0];m1++) { m = 2*N-m1-2; xa[m1][m2][m3] = Scat3DS.Green3DF(m,mm,2*N-m3-2); } } } ierr = VecRestoreArray3d(RealSpaceCube,dim[0],dim[1],nLocalSlaps,0,0,slap1,&xa);CHKERRQ(ierr); flg = PETSC_FALSE; ierr = PetscOptionsGetBool(PETSC_NULL,"-view_Green",&flg,PETSC_NULL);CHKERRQ(ierr); if (flg) { ierr = PetscPrintf(PETSC_COMM_WORLD,"\nPadded Green cube:\n");CHKERRQ(ierr); ierr = VecView(RealSpaceCube,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); //VecView3D(RealSpaceCube,dim[0]); } // Apply FFTW_FORWARD for the Green cube: fftwf_execute(fplan); //FFTW computes an unnormalized DFT, need to scale: scale = dim[0]*dim[1]*dim[2]; scale = 1.0/(PetscReal)scale; ierr = VecScale(RealSpaceCube,scale);CHKERRQ(ierr); flg = PETSC_FALSE; ierr = PetscOptionsGetBool(PETSC_NULL,"-view_GreenFFT",&flg,PETSC_NULL);CHKERRQ(ierr); if (flg) { ierr = PetscPrintf(PETSC_COMM_WORLD,"\nFFT of padded Green cube:\n");CHKERRQ(ierr); ierr = VecView(RealSpaceCube,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); //VecView3D(RealSpaceCube,dim[0]); } PetscFunctionReturn(0); }