static char help[] = "A test of PETSc-FFTW cohoperation \n\n"; #include #include #include #include #include /* user-defined functions */ PetscErrorCode InitialConditions(DM,Vec,PetscScalar*,PetscInt,PetscScalar); int main(int argc,char **args) { PetscErrorCode ierr; PetscMPIInt rank,size; PetscInt N0=pow(2,10),N1=N0,N=N0*N1; ptrdiff_t alloc_local,local_no,local_o_start; Vec u,ux,uy; Vec u_out; PetscViewer viewer; PetscScalar Lx = 5.; PetscScalar *ptr_u,*ptr_ux,*ptr_uy; fftw_complex *uhat,*uhat_x,*uhat_y; fftw_plan fplan_u,bplan_x,bplan_y; DM da; ierr = PetscInitialize(&argc,&args,(char*)0,help);CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD, &size);CHKERRQ(ierr); ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank);CHKERRQ(ierr); ierr = DMDACreate2d(PETSC_COMM_WORLD,DM_BOUNDARY_PERIODIC,DM_BOUNDARY_PERIODIC,DMDA_STENCIL_STAR,N0,N1,size,1,1,1,NULL,NULL,&da);CHKERRQ(ierr); ierr = DMDASetUniformCoordinates(da,0.,Lx*2.*PETSC_PI,0.,Lx*2.*PETSC_PI,0.,0.);CHKERRQ(ierr); fftw_mpi_init(); alloc_local = fftw_mpi_local_size_2d(N0,N1,PETSC_COMM_WORLD,&local_no,&local_o_start); PetscPrintf(PETSC_COMM_SELF,"alloc_local: %d\n",(PetscInt)alloc_local); PetscPrintf(PETSC_COMM_SELF,"local_no: %d\n",(PetscInt)local_no); PetscPrintf(PETSC_COMM_SELF,"local_o_start: %d\n",(PetscInt)local_o_start); // uhat is the Fourier transform of u uhat = fftw_alloc_complex(alloc_local); // Fourier transform of the x-derivative of u: uhat_x = fftw_alloc_complex(alloc_local); // Fourier transform of the y-derivative of u: uhat_y = fftw_alloc_complex(alloc_local); // allocate a real array for u ierr = PetscMalloc1(alloc_local*sizeof(double),&ptr_u);CHKERRQ(ierr); ierr = VecCreateMPIWithArray(PETSC_COMM_WORLD,1,alloc_local,N,(const PetscScalar*)ptr_u,&u);CHKERRQ(ierr); // allocate a real array for ux, the x-derivative of u ierr = PetscMalloc1(alloc_local*sizeof(double),&ptr_ux);CHKERRQ(ierr); ierr = VecCreateMPIWithArray(PETSC_COMM_WORLD,1,alloc_local,N,(const PetscScalar*)ptr_ux,&ux);CHKERRQ(ierr); // allocate a real array for uy, the y-derivative of u ierr = PetscMalloc1(alloc_local*sizeof(double),&ptr_uy);CHKERRQ(ierr); ierr = VecCreateMPIWithArray(PETSC_COMM_WORLD,1,alloc_local,N,(const PetscScalar*)ptr_uy,&uy);CHKERRQ(ierr); // u_out is used for output only DMCreateGlobalVector(da,&u_out); ierr = InitialConditions(da,u_out,ptr_u,N0,Lx);CHKERRQ(ierr); //ierr = VecCopy(u_out,u);CHKERRQ(ierr); /* now computing x derivative */ // fplan_u is the Fourier transform of u -> uhat fplan_u = fftw_mpi_plan_dft_2d(N0,N1,ptr_u,uhat,PETSC_COMM_WORLD,FFTW_FORWARD,FFTW_ESTIMATE|FFTW_PRESERVE_INPUT); // fplan_u is the inverse Fourier transform of uhat_x -> ux bplan_x = fftw_mpi_plan_dft_2d(N0,N1,uhat_x,(fftw_complex*)ptr_ux,PETSC_COMM_WORLD,FFTW_BACKWARD,FFTW_ESTIMATE); // fplan_u is the inverse Fourier transform of uhat_y -> uy bplan_y = fftw_mpi_plan_dft_2d(N0,N1,uhat_y,(fftw_complex*)ptr_uy,PETSC_COMM_WORLD,FFTW_BACKWARD,FFTW_ESTIMATE); fftw_execute(fplan_u); // renormalize uhat for (unsigned int j=0;j