struct ath_3d_fft_plan *ath_3d_fft_create_plan(DomainS *pD, int gnx3, int gnx2, int gnx1, int gks, int gke, int gjs, int gje, int gis, int gie, ath_fft_data *data, int al, ath_fft_direction dir) { int nbuf, tmp; struct ath_3d_fft_plan *ath_plan; if ((dir != ATH_FFT_FORWARD) && (dir != ATH_FFT_BACKWARD)) { ath_error("Invalid Athena FFT direction.\n"); } /* Allocate memory for the plan */ ath_plan = (struct ath_3d_fft_plan *)malloc(sizeof(struct ath_3d_fft_plan)); if (ath_plan == NULL) { ath_error("[ath_3d_fft_plan] Couldn't malloc for FFT plan.\n"); } /* Set forward/backward FFT */ ath_plan->dir = dir; /* Set element count (for easy malloc and memset) */ ath_plan->cnt = (gke-gks+1)*(gje-gjs+1)*(gie-gis+1); ath_plan->gcnt = gnx3*gnx2*gnx1; tmp = (al==0 ? 1 : 0); if (data != NULL) tmp = 0; /* If data == NULL, then allocate something (temporarily if tmp=1) */ if (data == NULL) data = (ath_fft_data *)ath_3d_fft_malloc(ath_plan); if (data == NULL) ath_error("[ath_3d_fft_plan] Couln't malloc for FFT plan data.\n"); /* Create the plan */ #ifdef FFT_BLOCK_DECOMP /* Block decomp library plans don't care if forward or backward */ ath_plan->plan = fft_3d_create_plan(pD->Comm_Domain, gnx3, gnx2, gnx1, gks, gke, gjs, gje, gis, gie, gks, gke, gjs, gje, gis, gie, 0, 0, &nbuf); #else /* FFT_BLOCK_DECOMP */ if (dir == ATH_FFT_FORWARD) { ath_plan->plan = fftw_plan_dft_3d(gnx1, gnx2, gnx3, data, data, FFTW_FORWARD, FFTW_MEASURE); } else { ath_plan->plan = fftw_plan_dft_3d(gnx1, gnx2, gnx3, data, data, FFTW_BACKWARD, FFTW_MEASURE); } #endif /* FFT_BLOCK_DECOMP */ if (tmp) ath_3d_fft_free(data); return ath_plan; }
void problem(Grid *pGrid, Domain *pD) { int i, is=pGrid->is, ie = pGrid->ie; int j, js=pGrid->js, je = pGrid->je; int k, ks=pGrid->ks, ke = pGrid->ke; rseed = (pGrid->my_id+1); initialize(pGrid, pD); tdrive = 0.0; /* Initialize uniform density and momenta */ for (k=ks-nghost; k<=ke+nghost; k++) { for (j=js-nghost; j<=je+nghost; j++) { for (i=is-nghost; i<=ie+nghost; i++) { pGrid->U[k][j][i].d = rhobar; pGrid->U[k][j][i].M1 = 0.0; pGrid->U[k][j][i].M2 = 0.0; pGrid->U[k][j][i].M3 = 0.0; } } } #ifdef MHD /* Initialize uniform magnetic field */ for (k=ks-nghost; k<=ke+nghost; k++) { for (j=js-nghost; j<=je+nghost; j++) { for (i=is-nghost; i<=ie+nghost; i++) { pGrid->U[k][j][i].B1c = B0; pGrid->U[k][j][i].B2c = 0.0; pGrid->U[k][j][i].B3c = 0.0; pGrid->B1i[k][j][i] = B0; pGrid->B2i[k][j][i] = 0.0; pGrid->B3i[k][j][i] = 0.0; } } } #endif /* MHD */ /* Set the initial perturbations. Note that we're putting in too much * energy this time. This is okay since we're only interested in the * saturated state. */ generate(); perturb(pGrid, dtdrive); /* If decaying turbulence, no longer need the driving memory */ if (idrive == 1) { ath_pout(0,"De-allocating driving memory.\n"); /* Free Athena-style arrays */ free_3d_array(dv1); free_3d_array(dv2); free_3d_array(dv3); /* Free FFTW-style arrays */ ath_3d_fft_free(fv1); ath_3d_fft_free(fv2); ath_3d_fft_free(fv3); } return; }