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; }
static void initialize(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; int nbuf, mpierr, nx1gh, nx2gh, nx3gh; float kwv, kpara, kperp; char donedrive = 0; /* ----------------------------------------------------------- * Variables within this block are stored globally, and used * within preprocessor macros. Don't create variables with * these names within your function if you are going to use * OFST(), KCOMP(), or KWVM() within the function! */ /* Get local grid size */ nx1 = (ie-is+1); nx2 = (je-js+1); nx3 = (ke-ks+1); /* Get global grid size */ gnx1 = pD->ide - pD->ids + 1; gnx2 = pD->jde - pD->jds + 1; gnx3 = pD->kde - pD->kds + 1; /* Get extents of local FFT grid in global coordinates */ gis=is+pGrid->idisp; gie=ie+pGrid->idisp; gjs=js+pGrid->jdisp; gje=je+pGrid->jdisp; gks=ks+pGrid->kdisp; gke=ke+pGrid->kdisp; /* ----------------------------------------------------------- */ /* Get size of arrays with ghost cells */ nx1gh = nx1 + 2*nghost; nx2gh = nx2 + 2*nghost; nx3gh = nx3 + 2*nghost; /* Get input parameters */ /* interval for generating new driving spectrum; also interval for * driving when IMPULSIVE_DRIVING is used */ dtdrive = par_getd("problem","dtdrive"); #ifdef MHD /* magnetic field strength */ beta = par_getd("problem","beta"); /* beta = isothermal pressure/magnetic pressure */ B0 = sqrt(2.0*Iso_csound2*rhobar/beta); #endif /* MHD */ /* energy injection rate */ dedt = par_getd("problem","dedt"); /* parameters for spectrum */ ispect = par_geti("problem","ispect"); if (ispect == 1) { expo = par_getd("problem","expo"); } else if (ispect == 2) { kpeak = par_getd("problem","kpeak")*2.0*PI; } else { ath_error("Invalid value for ispect\n"); } /* Cutoff wavenumbers of spectrum */ klow = par_getd("problem","klow"); /* in integer units */ khigh = par_getd("problem","khigh"); /* in integer units */ dkx = 2.0*PI/(pGrid->dx1*gnx1); /* convert k from integer */ /* Driven or decaying */ idrive = par_geti("problem","idrive"); if ((idrive < 0) || (idrive > 1)) ath_error("Invalid value for idrive\n"); /* If restarting with decaying turbulence, no driving necessary. */ if ((idrive == 1) && (pGrid->nstep > 0)) { donedrive = 1; } if (donedrive == 0) { /* Allocate memory for components of velocity perturbation */ if ((dv1=(Real***)calloc_3d_array(nx3gh,nx2gh,nx1gh,sizeof(Real)))==NULL) { ath_error("[problem]: Error allocating memory for vel pert\n"); } if ((dv2=(Real***)calloc_3d_array(nx3gh,nx2gh,nx1gh,sizeof(Real)))==NULL) { ath_error("[problem]: Error allocating memory for vel pert\n"); } if ((dv3=(Real***)calloc_3d_array(nx3gh,nx2gh,nx1gh,sizeof(Real)))==NULL) { ath_error("[problem]: Error allocating memory for vel pert\n"); } } /* Initialize the FFT plan */ plan = ath_3d_fft_quick_plan(pGrid, pD, NULL, ATH_FFT_BACKWARD); /* Allocate memory for FFTs */ if (donedrive == 0) { fv1 = ath_3d_fft_malloc(plan); fv2 = ath_3d_fft_malloc(plan); fv3 = ath_3d_fft_malloc(plan); } /* Enroll outputs */ dump_history_enroll(hst_dEk,"<dE_K>"); dump_history_enroll(hst_dEb,"<dE_B>"); return; }