1*c4762a1bSJed Brown static char help[] = "Test sequential FFTW interface \n\n"; 2*c4762a1bSJed Brown 3*c4762a1bSJed Brown /* 4*c4762a1bSJed Brown Compiling the code: 5*c4762a1bSJed Brown This code uses the complex numbers version of PETSc, so configure 6*c4762a1bSJed Brown must be run to enable this 7*c4762a1bSJed Brown 8*c4762a1bSJed Brown */ 9*c4762a1bSJed Brown 10*c4762a1bSJed Brown #include <petscmat.h> 11*c4762a1bSJed Brown int main(int argc,char **args) 12*c4762a1bSJed Brown { 13*c4762a1bSJed Brown typedef enum {RANDOM, CONSTANT, TANH, NUM_FUNCS} FuncType; 14*c4762a1bSJed Brown const char *funcNames[NUM_FUNCS] = {"random", "constant", "tanh"}; 15*c4762a1bSJed Brown Mat A; 16*c4762a1bSJed Brown PetscMPIInt size; 17*c4762a1bSJed Brown PetscInt n = 10,N,ndim=4,dim[4],DIM,i; 18*c4762a1bSJed Brown Vec x,y,z; 19*c4762a1bSJed Brown PetscScalar s; 20*c4762a1bSJed Brown PetscRandom rdm; 21*c4762a1bSJed Brown PetscReal enorm, tol = PETSC_SMALL; 22*c4762a1bSJed Brown PetscInt func; 23*c4762a1bSJed Brown FuncType function = RANDOM; 24*c4762a1bSJed Brown PetscBool view = PETSC_FALSE; 25*c4762a1bSJed Brown PetscErrorCode ierr; 26*c4762a1bSJed Brown 27*c4762a1bSJed Brown ierr = PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr; 28*c4762a1bSJed Brown ierr = MPI_Comm_size(PETSC_COMM_WORLD, &size);CHKERRQ(ierr); 29*c4762a1bSJed Brown if (size != 1) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP, "This is a uniprocessor example only!"); 30*c4762a1bSJed Brown ierr = PetscOptionsBegin(PETSC_COMM_WORLD, NULL, "FFTW Options", "ex112");CHKERRQ(ierr); 31*c4762a1bSJed Brown ierr = PetscOptionsEList("-function", "Function type", "ex112", funcNames, NUM_FUNCS, funcNames[function], &func, NULL);CHKERRQ(ierr); 32*c4762a1bSJed Brown ierr = PetscOptionsBool("-vec_view_draw", "View the functions", "ex112", view, &view, NULL);CHKERRQ(ierr); 33*c4762a1bSJed Brown function = (FuncType) func; 34*c4762a1bSJed Brown ierr = PetscOptionsEnd();CHKERRQ(ierr); 35*c4762a1bSJed Brown 36*c4762a1bSJed Brown for (DIM = 0; DIM < ndim; DIM++) { 37*c4762a1bSJed Brown dim[DIM] = n; /* size of transformation in DIM-dimension */ 38*c4762a1bSJed Brown } 39*c4762a1bSJed Brown ierr = PetscRandomCreate(PETSC_COMM_SELF, &rdm);CHKERRQ(ierr); 40*c4762a1bSJed Brown ierr = PetscRandomSetFromOptions(rdm);CHKERRQ(ierr); 41*c4762a1bSJed Brown 42*c4762a1bSJed Brown for (DIM = 1; DIM < 5; DIM++) { 43*c4762a1bSJed Brown for (i = 0, N = 1; i < DIM; i++) N *= dim[i]; 44*c4762a1bSJed Brown ierr = PetscPrintf(PETSC_COMM_SELF, "\n %d-D: FFTW on vector of size %d \n",DIM,N);CHKERRQ(ierr); 45*c4762a1bSJed Brown 46*c4762a1bSJed Brown /* create FFTW object */ 47*c4762a1bSJed Brown ierr = MatCreateFFT(PETSC_COMM_SELF,DIM,dim,MATFFTW,&A);CHKERRQ(ierr); 48*c4762a1bSJed Brown 49*c4762a1bSJed Brown /* create vectors of length N=n^DIM */ 50*c4762a1bSJed Brown ierr = MatCreateVecs(A,&x,&y);CHKERRQ(ierr); 51*c4762a1bSJed Brown ierr = MatCreateVecs(A,&z,NULL);CHKERRQ(ierr); 52*c4762a1bSJed Brown ierr = PetscObjectSetName((PetscObject) x, "Real space vector");CHKERRQ(ierr); 53*c4762a1bSJed Brown ierr = PetscObjectSetName((PetscObject) y, "Frequency space vector");CHKERRQ(ierr); 54*c4762a1bSJed Brown ierr = PetscObjectSetName((PetscObject) z, "Reconstructed vector");CHKERRQ(ierr); 55*c4762a1bSJed Brown 56*c4762a1bSJed Brown /* set values of space vector x */ 57*c4762a1bSJed Brown if (function == RANDOM) { 58*c4762a1bSJed Brown ierr = VecSetRandom(x, rdm);CHKERRQ(ierr); 59*c4762a1bSJed Brown } else if (function == CONSTANT) { 60*c4762a1bSJed Brown ierr = VecSet(x, 1.0);CHKERRQ(ierr); 61*c4762a1bSJed Brown } else if (function == TANH) { 62*c4762a1bSJed Brown PetscScalar *a; 63*c4762a1bSJed Brown ierr = VecGetArray(x, &a);CHKERRQ(ierr); 64*c4762a1bSJed Brown for (i = 0; i < N; ++i) { 65*c4762a1bSJed Brown a[i] = tanh((i - N/2.0)*(10.0/N)); 66*c4762a1bSJed Brown } 67*c4762a1bSJed Brown ierr = VecRestoreArray(x, &a);CHKERRQ(ierr); 68*c4762a1bSJed Brown } 69*c4762a1bSJed Brown if (view) {ierr = VecView(x, PETSC_VIEWER_DRAW_WORLD);CHKERRQ(ierr);} 70*c4762a1bSJed Brown 71*c4762a1bSJed Brown /* apply FFTW_FORWARD and FFTW_BACKWARD several times on same x, y, and z */ 72*c4762a1bSJed Brown for (i=0; i<3; i++) { 73*c4762a1bSJed Brown ierr = MatMult(A,x,y);CHKERRQ(ierr); 74*c4762a1bSJed Brown if (view && i == 0) {ierr = VecView(y, PETSC_VIEWER_DRAW_WORLD);CHKERRQ(ierr);} 75*c4762a1bSJed Brown ierr = MatMultTranspose(A,y,z);CHKERRQ(ierr); 76*c4762a1bSJed Brown 77*c4762a1bSJed Brown /* compare x and z. FFTW computes an unnormalized DFT, thus z = N*x */ 78*c4762a1bSJed Brown s = 1.0/(PetscReal)N; 79*c4762a1bSJed Brown ierr = VecScale(z,s);CHKERRQ(ierr); 80*c4762a1bSJed Brown if (view && i == 0) {ierr = VecView(z, PETSC_VIEWER_DRAW_WORLD);CHKERRQ(ierr);} 81*c4762a1bSJed Brown ierr = VecAXPY(z,-1.0,x);CHKERRQ(ierr); 82*c4762a1bSJed Brown ierr = VecNorm(z,NORM_1,&enorm);CHKERRQ(ierr); 83*c4762a1bSJed Brown if (enorm > tol) { 84*c4762a1bSJed Brown ierr = PetscPrintf(PETSC_COMM_SELF," Error norm of |x - z| %g\n",(double)enorm);CHKERRQ(ierr); 85*c4762a1bSJed Brown } 86*c4762a1bSJed Brown } 87*c4762a1bSJed Brown 88*c4762a1bSJed Brown /* apply FFTW_FORWARD and FFTW_BACKWARD several times on different x */ 89*c4762a1bSJed Brown for (i=0; i<3; i++) { 90*c4762a1bSJed Brown ierr = VecDestroy(&x);CHKERRQ(ierr); 91*c4762a1bSJed Brown ierr = VecCreateSeq(PETSC_COMM_SELF,N,&x);CHKERRQ(ierr); 92*c4762a1bSJed Brown ierr = VecSetRandom(x, rdm);CHKERRQ(ierr); 93*c4762a1bSJed Brown 94*c4762a1bSJed Brown ierr = MatMult(A,x,y);CHKERRQ(ierr); 95*c4762a1bSJed Brown ierr = MatMultTranspose(A,y,z);CHKERRQ(ierr); 96*c4762a1bSJed Brown 97*c4762a1bSJed Brown /* compare x and z. FFTW computes an unnormalized DFT, thus z = N*x */ 98*c4762a1bSJed Brown s = 1.0/(PetscReal)N; 99*c4762a1bSJed Brown ierr = VecScale(z,s);CHKERRQ(ierr); 100*c4762a1bSJed Brown if (view && i == 0) {ierr = VecView(z, PETSC_VIEWER_DRAW_WORLD);CHKERRQ(ierr);} 101*c4762a1bSJed Brown ierr = VecAXPY(z,-1.0,x);CHKERRQ(ierr); 102*c4762a1bSJed Brown ierr = VecNorm(z,NORM_1,&enorm);CHKERRQ(ierr); 103*c4762a1bSJed Brown if (enorm > tol) { 104*c4762a1bSJed Brown ierr = PetscPrintf(PETSC_COMM_SELF," Error norm of new |x - z| %g\n",(double)enorm);CHKERRQ(ierr); 105*c4762a1bSJed Brown } 106*c4762a1bSJed Brown } 107*c4762a1bSJed Brown 108*c4762a1bSJed Brown /* free spaces */ 109*c4762a1bSJed Brown ierr = VecDestroy(&x);CHKERRQ(ierr); 110*c4762a1bSJed Brown ierr = VecDestroy(&y);CHKERRQ(ierr); 111*c4762a1bSJed Brown ierr = VecDestroy(&z);CHKERRQ(ierr); 112*c4762a1bSJed Brown ierr = MatDestroy(&A);CHKERRQ(ierr); 113*c4762a1bSJed Brown } 114*c4762a1bSJed Brown ierr = PetscRandomDestroy(&rdm);CHKERRQ(ierr); 115*c4762a1bSJed Brown ierr = PetscFinalize(); 116*c4762a1bSJed Brown return ierr; 117*c4762a1bSJed Brown } 118*c4762a1bSJed Brown 119*c4762a1bSJed Brown 120*c4762a1bSJed Brown /*TEST 121*c4762a1bSJed Brown 122*c4762a1bSJed Brown build: 123*c4762a1bSJed Brown requires: fftw complex 124*c4762a1bSJed Brown 125*c4762a1bSJed Brown test: 126*c4762a1bSJed Brown args: -mat_fftw_plannerflags FFTW_ESTIMATE 127*c4762a1bSJed Brown output_file: output/ex112.out 128*c4762a1bSJed Brown 129*c4762a1bSJed Brown test: 130*c4762a1bSJed Brown suffix: 2 131*c4762a1bSJed Brown args: -mat_fftw_plannerflags FFTW_MEASURE 132*c4762a1bSJed Brown output_file: output/ex112.out 133*c4762a1bSJed Brown requires: !define(PETSC_USE_CXXCOMPLEX) 134*c4762a1bSJed Brown 135*c4762a1bSJed Brown test: 136*c4762a1bSJed Brown suffix: 3 137*c4762a1bSJed Brown args: -mat_fftw_plannerflags FFTW_PATIENT 138*c4762a1bSJed Brown output_file: output/ex112.out 139*c4762a1bSJed Brown 140*c4762a1bSJed Brown test: 141*c4762a1bSJed Brown suffix: 4 142*c4762a1bSJed Brown args: -mat_fftw_plannerflags FFTW_EXHAUSTIVE 143*c4762a1bSJed Brown output_file: output/ex112.out 144*c4762a1bSJed Brown 145*c4762a1bSJed Brown TEST*/ 146