Beispiel #1
0
void init_KidaVortex(struct Field fldi) {
	double a = param.vortex_a;
	double b = param.vortex_b;
	
	int i,j,k;
	
	double w0, x, y;
	double chi;
	
	chi = b / a;
	w0 = 1.0/chi*(chi + 1.0)/(chi-1.0);			// According to Kida!
	
	for(i = 0 ; i < NX/NPROC ; i++) {
		x = - param.lx / 2 + (param.lx * (i + rank * NX / NPROC)) / NX;
		for(j = 0 ; j < NY ; j++) {
			y = - param.ly / 2 + (param.ly * j) / NY;
#ifdef WITH_2D
			if(x * x / (a * a) + y * y / (b * b) < 1) {
					// we are in the vortex
					wr1[j + (NY+2) * i] = -w0;
			}
			else {
				wr1[j + (NY+2) * i] = 0.0;
			}
#else
			for(k = 0 ; k < NZ ; k++) {
				if(x * x / (a * a) + y * y / (b * b) < 1) {
					// we are in the vortex
					wr1[k + j*(NZ+2) + (NZ+2) * NY * i] = -w0;
				}
				else {
					wr1[k + j*(NZ+2) + (NZ+2) * NY * i] = 0.0;
				}
			}
#endif
		}
	}
	
	// transform
	gfft_r2c(wr1);
	
	for(i = 0 ; i < NTOTAL_COMPLEX ; i++) {
		fldi.vx[ i ] +=  I * ky[i] * w1[i] * ik2t[i];
		fldi.vy[ i ] += -I * kxt[i] * w1[i] * ik2t[i];
	}
	
	// done
	return;
}
Beispiel #2
0
void init_Bench(struct Field fldi) {
	const double a = 0.3;
	const double b = 0.4;
	
	int i,j,k;
	
	double w0, x, y;
	double chi;
	
	chi = b / a;
	w0 = 1.0/chi*(chi + 1)/(chi-1.0);			// According to Kida!
	
	for(i = 0 ; i < NX/NPROC ; i++) {
		x = - param.lx / 2. + (param.lx * (i + rank * NX / NPROC)) / NX;
		for(j = 0 ; j < NY ; j++) {
			y = - param.ly / 2. + (param.ly * j) / NY;
			for(k = 0 ; k < NZ ; k++) {
				if(x * x / (a * a) + y * y / (b * b) < 1) {
					// we are in the vortex
					wr1[k + j*(NZ+2) + (NZ+2) * NY * i] = -w0;
				}
				else {
					wr1[k + j*(NZ+2) + (NZ+2) * NY * i] = 0.0;
				}
			}
		}
	}
	
	// transform
	gfft_r2c(wr1);
	
	for(i = 0 ; i < NTOTAL_COMPLEX ; i++) {
		fldi.vx[ i ] +=  I * ky[i] * w1[i] * ik2t[i];
		fldi.vy[ i ] += -I * kxt[i] * w1[i] * ik2t[i];
	}
	
	// Brake vertical symmetry
	if(rank==0) {
		fldi.vx[1] = 1000.0 / NTOTAL;
		fldi.vy[1] = 1000.0 / NTOTAL;
#ifdef MHD
		fldi.bx[1] = 1000.0 / NTOTAL;
		fldi.by[1] = 1000.0 / NTOTAL;
#endif
	}
	// done
	return;
}
void u_iii_forcing(struct Field fldi, double dt) {
	double *x, *y, *z;		 	
	int i,j,k;

	x = (double *) fftw_malloc( sizeof(double complex) * NTOTAL_COMPLEX);
	if (x == NULL) ERROR_HANDLER( ERROR_CRITICAL, "No memory for x allocation");
	
	y = (double *) fftw_malloc( sizeof(double complex) * NTOTAL_COMPLEX);
	if (y == NULL) ERROR_HANDLER( ERROR_CRITICAL, "No memory for y allocation");
	
	z = (double *) fftw_malloc( sizeof(double complex) * NTOTAL_COMPLEX);
	if (z == NULL) ERROR_HANDLER( ERROR_CRITICAL, "No memory for z allocation");

	// Initialize the arrays
	
	for(i = 0 ; i < NX/NPROC ; i++) {
		for(j = 0 ; j < NY ; j++) {
			for(k = 0 ; k < NZ ; k++) {
				x[k + (NZ + 2) * j + (NZ + 2) * NY * i] = - param.lx / 2 + (param.lx * (i + rank * NX / NPROC)) / NX;
				y[k + (NZ + 2) * j + (NZ + 2) * NY * i] = - param.ly / 2 + (param.ly * j ) / NY;
				z[k + (NZ + 2) * j + (NZ + 2) * NY * i] = - param.lz / 2 + (param.lz * k ) / NZ;
			}
		}
	}
	
	// Initialize the extra points (k=NZ and k=NZ+1) to zero to prevent stupid things from happening...
	for(i = 0 ; i < NX/NPROC ; i++) {
		for(j = 0 ; j < NY ; j++) {
			for(k = NZ ; k < NZ + 2 ; k++) {
				x[k + (NZ + 2) * j + (NZ + 2) * NY * i] = 0.0;
				y[k + (NZ + 2) * j + (NZ + 2) * NY * i] = 0.0;
				z[k + (NZ + 2) * j + (NZ + 2) * NY * i] = 0.0;

			}
		}
	}
	
	// Init work array to zero
	for(i = 0 ; i < NX/NPROC ; i++) {
		for(j = 0 ; j < NY ; j++) {
			for(k = 0 ; k < NZ + 2 ; k++) {
				wr4[k + (NZ + 2) * j + (NZ + 2) * NY * i] = 0.0;
				wr5[k + (NZ + 2) * j + (NZ + 2) * NY * i] = 0.0;
				wr6[k + (NZ + 2) * j + (NZ + 2) * NY * i] = 0.0;
   			}
		}
   }

    /*******************************************************************
	** This part can be modified              **************************
	********************************************************************/
	
	// The velocity field vx,vy,vz is stored in wr1,wr2,wr3
   	for(i = 0 ; i < 2*NTOTAL_COMPLEX ; i++) {
     
        wr4[i] = param.modified_ABC_flow_D*(
                    cos(x[i]/param.modified_ABC_flow_m)*(
                        param.modified_ABC_flow_A*param.modified_ABC_flow_kz*sin(z[i] /(double) param.modified_ABC_flow_kz ) +
                        param.modified_ABC_flow_C*param.modified_ABC_flow_ky*cos(y[i] /(double) param.modified_ABC_flow_ky)
                    ) + 
                    sin(x[i]/param.modified_ABC_flow_m)/param.modified_ABC_flow_m*(
                        0
                    )                                         
                ); 
        wr5[i] = param.modified_ABC_flow_D*(
                    cos(x[i]/param.modified_ABC_flow_m)*(
                        param.modified_ABC_flow_B*param.modified_ABC_flow_kx*sin(x[i] /(double) param.modified_ABC_flow_kx ) +
                        param.modified_ABC_flow_A*param.modified_ABC_flow_kz*cos(z[i] /(double) param.modified_ABC_flow_kz)
                    ) + 
                    sin(x[i]/param.modified_ABC_flow_m)/param.modified_ABC_flow_m*(
                        param.modified_ABC_flow_B*cos(x[i] /(double) param.modified_ABC_flow_kx) + 
                        param.modified_ABC_flow_C*sin(y[i] /(double) param.modified_ABC_flow_ky)
                    )                                         
                );
        wr6[i] = param.modified_ABC_flow_D*(
                    cos(x[i]/param.modified_ABC_flow_m)*(
                        param.modified_ABC_flow_C*param.modified_ABC_flow_ky*sin(y[i] /(double) param.modified_ABC_flow_ky ) +
                        param.modified_ABC_flow_B*param.modified_ABC_flow_kx*cos(x[i] /(double) param.modified_ABC_flow_kx)
                    ) + 
                    sin(x[i]/param.modified_ABC_flow_m)/param.modified_ABC_flow_m*(
                        -param.modified_ABC_flow_A*cos(z[i] /(double) param.modified_ABC_flow_kz) + 
                        -param.modified_ABC_flow_B*sin(x[i] /(double) param.modified_ABC_flow_kx)
                    )                                         
                );
    }
    gfft_r2c(wr4);
	gfft_r2c(wr5);
    gfft_r2c(wr6);
	
    for(i = 0 ; i < NTOTAL_COMPLEX ; i++) {
		w4[i] = w4[i] * mask[i];
		w5[i] = w5[i] * mask[i];
		w6[i] = w6[i] * mask[i];
    }   

	for( i = 0; i < NX_COMPLEX/NPROC; i++) {
		for( j = 0; j < NY_COMPLEX; j++) {
			for( k = 0; k < NZ_COMPLEX; k++) {
				fldi.vx[ IDX3D ] +=  w4[ IDX3D ] * (1 - exp(-nu*k2t[IDX3D]*dt)) ;
				fldi.vy[ IDX3D ] +=  w5[ IDX3D ] * (1 - exp(-nu*k2t[IDX3D]*dt)) ;
				fldi.vz[ IDX3D ] +=  w6[ IDX3D ] * (1 - exp(-nu*k2t[IDX3D]*dt)) ;
			}
		}
	}

#ifdef U_III_FORCING_EXTRA
    gfft_c2r_t(w4);
	gfft_c2r_t(w5);
	gfft_c2r_t(w6);

#ifdef _OPENMP
	#pragma omp parallel for private(i) schedule(static)	
#endif
	for( i = 0 ; i < 2*NTOTAL_COMPLEX ; i++) {
		wr10[i] = wr4[i] * wr4[i] / ((double) NTOTAL*NTOTAL);
		wr11[i] = wr5[i] * wr5[i] / ((double) NTOTAL*NTOTAL);
#ifndef WITH_2D
		wr12[i] = wr6[i] * wr6[i] / ((double) NTOTAL*NTOTAL);
#endif
		wr7[i] = wr4[i] * wr5[i] / ((double) NTOTAL*NTOTAL);
		wr8[i] = wr4[i] * wr6[i] / ((double) NTOTAL*NTOTAL);
		wr9[i] = wr5[i] * wr6[i] / ((double) NTOTAL*NTOTAL);
	}
	
	gfft_r2c_t(wr10);
	gfft_r2c_t(wr11);
#ifndef WITH_2D
	gfft_r2c_t(wr12);
#endif
	gfft_r2c_t(wr7);
	gfft_r2c_t(wr8);
	gfft_r2c_t(wr9);

#ifdef _OPENMP
	#pragma omp parallel for private(i) schedule(static)	
#endif
	for( i = 0 ; i < NTOTAL_COMPLEX ; i++) {
		fldi.vx[i] +=  I * mask[i] / (nu * k2t) * (1 - exp(-nu*k2t[IDX3D]*dt)) * (
					kxt[i] * w10[i] + ky[i] * w7[i] + kz[i] * w8[i] );
		fldi.vy[i] +=  I * mask[i] / (nu * k2t) * (1 - exp(-nu*k2t[IDX3D]*dt)) * (
					kxt[i] * w7[i] + ky[i] * w11[i] + kz[i] * w9[i] );
		fldi.vz[i] +=  I * mask[i] / (nu * k2t) * (1 - exp(-nu*k2t[IDX3D]*dt)) * (
					kxt[i] * w8[i] + ky[i] * w9[i] + kz[i] * w12[i] );	// since kz=0 in 2D, kz*w6 gives 0, even if w6 is some random array
	}

#endif

	projector(fldi.vx,fldi.vy,fldi.vz);	
	return;
}
Beispiel #4
0
void init_SpatialStructure(struct Field fldi) {
	double *x,*y,*z;
	int i,j,k;
	
	/*******************************************************************
	** This part does not need to be modified **************************
	********************************************************************/
	// Allocate coordinate arrays
	x = (double *) fftw_malloc( sizeof(double complex) * NTOTAL_COMPLEX);
	if (x == NULL) ERROR_HANDLER( ERROR_CRITICAL, "No memory for x allocation");
	
	y = (double *) fftw_malloc( sizeof(double complex) * NTOTAL_COMPLEX);
	if (y == NULL) ERROR_HANDLER( ERROR_CRITICAL, "No memory for y allocation");
	
	z = (double *) fftw_malloc( sizeof(double complex) * NTOTAL_COMPLEX);
	if (z == NULL) ERROR_HANDLER( ERROR_CRITICAL, "No memory for z allocation");

	// Initialize the arrays
	
	for(i = 0 ; i < NX/NPROC ; i++) {
		for(j = 0 ; j < NY ; j++) {
			for(k = 0 ; k < NZ ; k++) {
				x[k + (NZ + 2) * j + (NZ + 2) * NY * i] = - param.lx / 2 + (param.lx * (i + rank * NX / NPROC)) / NX;
				y[k + (NZ + 2) * j + (NZ + 2) * NY * i] = - param.ly / 2 + (param.ly * j ) / NY;
				z[k + (NZ + 2) * j + (NZ + 2) * NY * i] = - param.lz / 2 + (param.lz * k ) / NZ;
			}
		}
	}
	
	// Initialize the extra points (k=NZ and k=NZ+1) to zero to prevent stupid things from happening...
	for(i = 0 ; i < NX/NPROC ; i++) {
		for(j = 0 ; j < NY ; j++) {
			for(k = NZ ; k < NZ + 2 ; k++) {
				x[k + (NZ + 2) * j + (NZ + 2) * NY * i] = 0.0;
				y[k + (NZ + 2) * j + (NZ + 2) * NY * i] = 0.0;
				z[k + (NZ + 2) * j + (NZ + 2) * NY * i] = 0.0;
			}
		}
	}
	
	// Init work array to zero
	for(i = 0 ; i < NX/NPROC ; i++) {
		for(j = 0 ; j < NY ; j++) {
			for(k = 0 ; k < NZ + 2 ; k++) {
				wr1[k + (NZ + 2) * j + (NZ + 2) * NY * i] = 0.0;
				wr2[k + (NZ + 2) * j + (NZ + 2) * NY * i] = 0.0;
				wr3[k + (NZ + 2) * j + (NZ + 2) * NY * i] = 0.0;
				wr4[k + (NZ + 2) * j + (NZ + 2) * NY * i] = 0.0;
				wr5[k + (NZ + 2) * j + (NZ + 2) * NY * i] = 0.0;
				wr6[k + (NZ + 2) * j + (NZ + 2) * NY * i] = 0.0;
			}
		}
	}
	
	/*******************************************************************
	** This part can be modified              **************************
	********************************************************************/
	
	// The velocity field vx,vy,vz is stored in wr1,wr2,wr3
	// The magnetic field bx,by,bz is stored in wr4,wr5,wr6 (ignored if MHD is not set)
	
	for(i = 0 ; i < 2*NTOTAL_COMPLEX ; i++) {
		// Example: init a flux tube in the x direction+a vertical displacement
	  //	wr4[i] = exp(-(y[i]*y[i]+z[i]*z[i])*20.0);
	  //	wr3[i] = 0.5*cos(x[i] * 2.0 * M_PI);

		// Example: twisted flux tube + vertical displacement
		wr4[i] = exp(-(y[i]*y[i]+z[i]*z[i])/(0.2*0.2));
		wr5[i] = fabs(z[i])*1.0*wr4[i];
		wr6[i] = -fabs(y[i])*1.0*wr4[i];
		wr3[i] = 0.5*cos(x[i] * 2.0 * M_PI);
		if (i==3*NY*(NZ+2)) fprintf(stderr," %d %e",i,x[i]);
	}
	
	/*******************************************************************
	** This part does not need to be modified **************************
	********************************************************************/
	// Fourier transform everything
	gfft_r2c(wr1);
	gfft_r2c(wr2);
	gfft_r2c(wr3);
	gfft_r2c(wr4);
	gfft_r2c(wr5);
	gfft_r2c(wr6);
	
	// Transfer data in the relevant array (including dealiasing mask)
	for(i = 0 ; i < NTOTAL_COMPLEX ; i++) {
		fldi.vx[i] += w1[i] * mask[i];
		fldi.vy[i] += w2[i] * mask[i];
		fldi.vz[i] += w3[i] * mask[i];
#ifdef MHD
		fldi.bx[i] += w4[i] * mask[i];
		fldi.by[i] += w5[i] * mask[i];
		fldi.bz[i] += w6[i] * mask[i];
#endif
	}
	
	// free memory
	fftw_free(x);
	fftw_free(y);
	fftw_free(z);
	
	//done
	return;
}