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;
}
Example #2
0
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;
}