⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fdtd_1d_eh_pml_loss.cpp

📁 fdtd 3D xyzPML MPI OpenMP
💻 CPP
字号:
#include "FDTD_1D_EH_PML_LOSS.h"
#include "run_enviroment.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CFDTD_1D_EH_PML_LOSS::CFDTD_1D_EH_PML_LOSS(void)
{
	E_1D   = NULL;
	//F_1 = NULL;
	F_2 = NULL;
	H_1D   = NULL;

	K_F_a = NULL;
	K_F_b = NULL;
	K_H_a = NULL;
	K_H_b = NULL;

	pi = 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679;
	//permittivity of free space 
	eps_0 = 8.8541878176203898505365630317107502606083701665994498081024171524053950954599821142852891607182008932e-12; // [F/m]
	//permeability of free space 
    mu_0  = 1.2566370614359172953850573533118011536788677597500423283899778369231265625144835994512139301368468271e-6;  // [H_1D/m]

	num_threads = 1;
}

CFDTD_1D_EH_PML_LOSS::~CFDTD_1D_EH_PML_LOSS(void)
{
	Free_Mem();
}

///////////////////////////////////////////////////////////////////////////////////////
//Initialize the nr of threads
///////////////////////////////////////////////////////////////////////////////////////
#ifdef _OPENMP
	void CFDTD_1D_EH_PML_LOSS::Init_nr_THR(int nr_threads)
	{
		num_threads = nr_threads;
	}
#endif

///////////////////////////////////////////////////////////////////////////////////////
//Initialize the class parameters
///////////////////////////////////////////////////////////////////////////////////////
bool CFDTD_1D_EH_PML_LOSS::Init(long N, long n_pml, double d_t, double D, double Eps_r, 
								double Mu_r, double Sigma)
{
	n = N;
	dt = d_t;
	d = D;
	inv_d = 1.0/d;
	n_PML = n_pml;

	n_TS_a = n_PML+10;

	//some usefull constants
	n_PML_MIN_1 = n_PML - 1;
	n_MIN_n_PML_MIN_1 = n - n_PML - 1;
	n_MIN_1 = n - 1;
	n_MIN_n_PML = n - n_PML;

	eps_r = Eps_r;
	mu_r = Mu_r;
	sigma = Sigma;

	beta = sqrt(eps_0*eps_r*mu_0*mu_r);
	eta  = sqrt( mu_0*mu_r/(eps_0*eps_r) );

	E_1D = (double *)calloc(n,sizeof(double));
	if (!E_1D)
	{
		return false;
	}

	/*F_1 = (double *)calloc(n_PML,sizeof(double));
	if (!F_1)
	{
		Free_Mem();
		return false;
	}*/

	F_2 = (double *)calloc(n_PML,sizeof(double));
	if (!F_2)
	{
		Free_Mem();
		return false;
	}

	K_F_a = (double *)calloc(n_PML,sizeof(double));
	if (!K_F_a)
	{
		Free_Mem();
		return false;
	}

	K_F_b = (double *)calloc(n_PML,sizeof(double));
	if (!K_F_b)
	{
		Free_Mem();
		return false;
	}

	H_1D = (double *)calloc(n_MIN_1,sizeof(double));
	if (!H_1D)
	{
		Free_Mem();
		return false;
	}

	K_H_a = (double *)calloc(n_PML,sizeof(double));
	if (!K_H_a)
	{
		Free_Mem();
		return false;
	}

 	K_H_b = (double *)calloc(n_PML,sizeof(double));
	if (!K_H_b)
	{
		Free_Mem();
		return false;
	}

	K_E_a = ( 2.0*eps_r*eps_0 - sigma*dt )/( 2.0*eps_r*eps_0 + sigma*dt );
	K_E_b =  2.0*dt/( 2.0*eps_r*eps_0 + sigma*dt )*inv_d;

	K_H = dt*inv_d/(mu_0*mu_r);
	
	return true;
}

///////////////////////////////////////////////////////////////////////////////////////
//Set the PML matrices
///////////////////////////////////////////////////////////////////////////////////////
void CFDTD_1D_EH_PML_LOSS::Init_PML_Param()
{
	long i;

	//PML parameters
	double ka_max = 2.0;
	double exponent = 4.0;

	double R_err = 1.0e-16;
	double eta = sqrt( mu_0*mu_r/(eps_0*eps_r) );

	double sigma_PML, sigma_max, ka_PML;
		
	sigma_max= -(exponent+1.0)*log(R_err)/(2.0*eta*n_PML*d);

	for (i = 0; i < n_PML; i++)
	{
		sigma_PML     = sigma_max*pow( (n_PML - i)/((double) n_PML) ,exponent);
		ka_PML        = 1.0 + (ka_max - 1.0)*pow( (n_PML-i)/((double) n_PML) ,exponent);

		K_F_a[i]      = (2.0*eps_0*ka_PML - sigma_PML*dt)/(2.0*eps_0*ka_PML + sigma_PML*dt);
		
		K_F_b[i]      = 2.0*eps_0/(2.0*eps_0*ka_PML + sigma_PML*dt);
		
		sigma_PML     = sigma_max*pow( (n_PML - i - 0.5)/n_PML ,exponent);
		ka_PML        = 1.0 + (ka_max - 1.0)*pow( (n_PML - i - 0.5)/n_PML ,exponent);

        K_H_a[i]      = (2.0*eps_0*ka_PML - sigma_PML*dt)/(2.0*eps_0*ka_PML + sigma_PML*dt);
		
		K_H_b[i]      = 2.0*eps_0*dt/( (2.0*eps_0*ka_PML + sigma_PML*dt)*d*mu_0*mu_r);
	}
}

///////////////////////////////////////////////////////////////////////////////////////
//Initialize a sinusoidal source
///////////////////////////////////////////////////////////////////////////////////////
void CFDTD_1D_EH_PML_LOSS::Init_Sin_Source(double E_0, double om, double Phase)
{
	E0 = E_0;
	omega = om;
	phase = Phase;

	alfa = 1.0*omega/(2.0*pi);

	Source_Type = 1;
}

///////////////////////////////////////////////////////////////////////////////////////
//Initialize  a Gaussian source
///////////////////////////////////////////////////////////////////////////////////////
void CFDTD_1D_EH_PML_LOSS::Init_Gauss_Source(double E_0, double t_0, double t_w)
{
	E0 = E_0;
	t0 = t_0;
	tw = t_w;
	
	Source_Type = 2;
}

///////////////////////////////////////////////////////////////////////////////////////
//Initialize a sinusoidal modulated Gaussian pulse
///////////////////////////////////////////////////////////////////////////////////////
void CFDTD_1D_EH_PML_LOSS::Init_GaussSin_Source(double E_0, double om, double Phase, double t_0, double t_w)
{
	E0 = E_0;
	omega = om;
	phase = Phase;
	t0 = t_0;
	tw = t_w;

	Source_Type = 3;
}

///////////////////////////////////////////////////////////////////////////////////////
//Calculate E_1D field
///////////////////////////////////////////////////////////////////////////////////////
void CFDTD_1D_EH_PML_LOSS::Calc_E(double time)
{
	long i, ii, ia;
	double Fz_r;

	/*for (i = 1; i < n_PML; i++)
	{
		Fz_r = F_1[i];
		
		F_1[i] = K_F_a[i]*F_1[i] + K_F_b[i]*( H_1D[i-1] - H_1D[i]);

		E_1D[i] = K_E_a*E_1D[i] + K_E_b*( F_1[i] - Fz_r );
	}*/

	#pragma omp parallel for shared(H_1D,K_E_a,K_E_b,E_1D,n_MIN_n_PML) private(i) num_threads(num_threads)
	for (i = 1; i < n_MIN_n_PML; i++)
	{
		E_1D[i] = K_E_a*E_1D[i] + K_E_b*( H_1D[i-1] - H_1D[i]);
	}

	ia = 0;
	ii = n_PML_MIN_1;
	for (i = n_MIN_n_PML; i < n_MIN_1; i++)
	{
		Fz_r = F_2[ia];
		
		F_2[ia] = K_F_a[ii]*F_2[ia] + K_F_b[ii]*( H_1D[i-1] - H_1D[i]);

		E_1D[i] = K_E_a*E_1D[i] + K_E_b*( F_2[ia] - Fz_r );
		
		ia++;
		ii--;
	}

	switch (Source_Type)
	{
		case 1:
			E_1D[0] = (1.0-exp(-alfa*time))*E0*cos(omega*time + phase);
			break;
		case 2:
			E_1D[0] = E0*exp( - (time - t0)*(time - t0)/(tw*tw) );
			break;
		case 3:
			E_1D[0] = E0*cos(omega*(time-t0) + phase)*exp( - (time - t0)*(time - t0)/(tw*tw) );
			break;
	}
}

///////////////////////////////////////////////////////////////////////////////////////
//Calculate H_1D field
///////////////////////////////////////////////////////////////////////////////////////
void CFDTD_1D_EH_PML_LOSS::Calc_H()
{
	long i, ii;

	/*for (i = 0; i < n_PML; i++)
	{
		H_1D[i] = K_H_a[i]*H_1D[i] + K_H_b[i]*( E_1D[i] - E_1D[i+1]);
	}*/

	#pragma omp parallel for shared(H_1D,K_H,E_1D,n_MIN_n_PML_MIN_1) private(i) num_threads(num_threads)
	for (i = 0; i < n_MIN_n_PML_MIN_1; i++)
	{
		H_1D[i] += K_H*( E_1D[i] - E_1D[i+1]);
	}

	ii = n_PML_MIN_1;
	for (i = n_MIN_n_PML_MIN_1; i < n_MIN_1; i++)
	{
		H_1D[i] = K_H_a[ii]*H_1D[i] + K_H_b[ii]*( E_1D[i] - E_1D[i+1] );
		ii--;
	}
}

///////////////////////////////////////////////////////////////////////////////////////
//Get the address of E_1D and H_1D
///////////////////////////////////////////////////////////////////////////////////////
void CFDTD_1D_EH_PML_LOSS::Get_Data(double *&e, double *&h)
{
	e = E_1D;
	h = H_1D;
}

///////////////////////////////////////////////////////////////////////////////////////
//Save out the workspace data - the possibility to continue computations
///////////////////////////////////////////////////////////////////////////////////////
int CFDTD_1D_EH_PML_LOSS::Save_FDTD_1D_Workspace(char *path)
{	
	char *path_name = NULL, *file_name = NULL;
	path_name =(char *) calloc(256,sizeof(char));
	file_name =(char *) calloc(256,sizeof(char));
	if (!path_name && !file_name)
	{
		if (path_name)
			free(path_name);
		if (file_name)
			free(file_name);
		return 1;
	}
	strcpy(path_name,path);
	strcat(path_name,"/data_fdtd_1D");

	//make directory to save F G E_1D
	#ifdef run_enviroment 
		CreateDirectory(path_name,0);
	#else
		mode_t Mode = S_IRWXU;
		mkdir(path_name,Mode);//for UNIX-AIX
	#endif

	//save F_2
	strcpy(file_name,path_name);
	strcat(file_name,"/F_1D");
	if (save_1D_binary(F_2, n_PML, 0, file_name))
	{
		free(path_name);
		free(file_name);
		return 2; //faild to save data
	}

	//save E_1D
	strcpy(file_name,path_name);
	strcat(file_name,"/E_1D");
	if (save_1D_binary(E_1D, n, 0, file_name))
	{
		free(path_name);
		free(file_name);
		return 2; //faild to save data
	}

	//save H_1D
	strcpy(file_name,path_name);
	strcat(file_name,"/H_1D");
	if(save_1D_binary(H_1D, n-1, 0, file_name))
	{
		free(path_name);
		free(file_name);
		return 2; //faild to save data
	}


	free(path_name);
	free(file_name);

	return 0;
}

int CFDTD_1D_EH_PML_LOSS::Load_FDTD_1D_Workspace(char *path)
{
	char *file_name = NULL;
	file_name =(char *) calloc(256,sizeof(char));
	if (!file_name)
	{
		return 1;
	}
	
	//load F2
	strcpy(file_name,path);
	strcat(file_name,"/F_1D_0.dat");
	if (load_1D_binary(F_2, n_PML, file_name))
	{
		free(file_name);
		return 2; //faild to load data
	}

	//load E_1D
	strcpy(file_name,path);
	strcat(file_name,"/E_1D_0.dat");
	if (load_1D_binary(E_1D, n, file_name))
	{
		free(file_name);
		return 2; //faild to load data
	}

	//load Hx_1D
	strcpy(file_name,path);
	strcat(file_name,"/H_1D_0.dat");
	if (load_1D_binary(H_1D, n-1, file_name))
	{
		free(file_name);
		return 2; //faild to load data
	}

	free(file_name);

	return 0;
}

///////////////////////////////////////////////////////////////////////////////////////
//Free the allocated memory
///////////////////////////////////////////////////////////////////////////////////////
void CFDTD_1D_EH_PML_LOSS::Free_Mem(void)
{
	if (E_1D)
	{
		free(E_1D);
		E_1D = NULL;
	}

	/*if (F_1)
	{
		free(F_1);
		F_1 = NULL;
	}*/

	if (F_2)
	{
		free(F_2);
		F_2 = NULL;
	}

	if (K_F_a)
	{
		free(K_F_a);
		K_F_a = NULL;
	}

	if (K_F_b)
	{
		free(K_F_b);
		K_F_b = NULL;
	}

	if (H_1D)
	{
		free(H_1D);
		H_1D = NULL;
	}

	if (K_H_a)
	{
		free(K_H_a);
		K_H_a = NULL;
	}

	if (K_H_b)
	{
		free(K_H_b);
		K_H_b = NULL;
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -