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

📄 fdtd_3d_xyzpml_threads_decomp.cpp

📁 利用c++语言写的三维FDTD
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/////////////////////////////////////////////////////////////
//set as follows:
//MALLOCMULTIHEAP=true - to allow the use of multiple heaps of free memory, 
//                       rather than just one - threads
/////////////////////////////////////////////////////////////
#include <pthread.h>  //for threads
#include <unistd.h>   //for getwd()
#include <sys/stat.h> //for mkdir()
#include <errno.h>    //for error handling

#include <stdio.h>
#include <math.h>
#include <ctime>
#include <malloc.h>

#include "Matrix.h"
#include "Load_Save_File_Data.h"
#include "fdtd_3d_alloc.h"
#include "fdtd_3d.h"
#include "Thread_Calc.h"
#include "Init_Thread_Calc_Data.h"
#include "FDTD_1D_EH_PML_LOSS.h"
#include "Alloc_Save_Load_Field_Thread.h"
#include "fdtd_3d_free.h"
#include "generate_report.h"

#include <iostream>
using std::cout;
using std::endl;
using std::fixed;

extern int errno;//error handling

//#define eval_W; //comment out if the energy is not evaluated

#include "read_input_file.h"

int main(int argc, char* argv[])
{
	///////////////////////////////////////////////////////
	//initialization to read from file the input data
	///////////////////////////////////////////////////////
	char *file_name = NULL;
	file_name = (char *) calloc(512,sizeof(char));
	if (!file_name)
	{
		cout << "Memory allocation problem - *file_name" << endl;
		return 1;
	}
		
	if (argc > 1)
	{
		strcpy(file_name,argv[1]);
	}
	else
	{
		strcpy(file_name,"Input_Data.txt");
	}
	
	Input_Data *Inp_D = NULL;
	Inp_D = (Input_Data *) calloc(1,sizeof(Input_Data));

	Inp_D->Path_Load_Workspace_Data = NULL;
	Inp_D->path_name_CoordPointSource = NULL;
	Inp_D->path_name_Index = NULL;
	Inp_D->path_name_MatParam = NULL;
	Inp_D->path_name_ParamPointSource = NULL;
	Inp_D->path_name_Wigner_Cell = NULL;
    
	if (readFile_fdtd_data(Inp_D,file_name))
	{
		cout << "Error reading Input_Data.dat" << endl;
		return 1;
	}
	else
	{
		cout << "Input file: " << file_name << " loaded succesfull" << endl;
	}
	///////////////////////////////////////////////////////

	int rc; //for error handling
	
	//to measure the program performance
	//for Unix
	double time_start, time_end, el_time;
	struct timeval tv;
	struct timezone tz;

	gettimeofday(&tv, &tz);
	time_start = (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0;

	errno = 0;   //set errno to  zero

	///////////////////////////////////////////////////////////////////////////////////////
	//some usefull constants
	///////////////////////////////////////////////////////////////////////////////////////
	double pi = 180.0*atan(1.0)/45.0;
	//permittivity of free space 
	double eps_0 = 8.8541878176203898505365630317107502606083701665994498081024171524053950954599821142852891607182008932e-12; // [F/m]
	//permeability of free space 
    double mu_0  = 1.2566370614359172953850573533118011536788677597500423283899778369231265625144835994512139301368468271e-6;  // [H/m]
	//the speed of the light in the vacuum
	double speed_c = 1.0/sqrt(eps_0*mu_0); // [m/s]
	///////////////////////////////////////////////////////////////////////////////////////

	///////////////////////////////////////////////////////////////////////////////////////
	//the parameters of the photonic crystal
	///////////////////////////////////////////////////////////////////////////////////////
	long nx = Inp_D->nx; //total number of cells in x direction
	long ny = Inp_D->ny; //total number of cells in y direction
	long nz = Inp_D->nz;  //total number of cells in z direction
	
	cout << "nx = " << nx << endl;
	cout << "ny = " << ny << endl;
	cout << "nz = " << nz << endl;
		
	//division of the Total Field Zone - for computing with threads
	long nr_DIV_x = Inp_D->nr_DIV_x;
	long nr_DIV_y = Inp_D->nr_DIV_y;
	long nr_DIV_z = Inp_D->nr_DIV_z;
	long nr_DIV_xORyORz = nr_DIV_x*nr_DIV_y*nr_DIV_z;
	long nr_Threads = 26 + nr_DIV_xORyORz;//total nr of threads (27 cells)
	cout << "Nr. of computing threads = " << nr_Threads << endl;

	//division for Data Save
	long Save_nr_DIV_x = Inp_D->Save_nr_DIV_x;
	long Save_nr_DIV_y = Inp_D->Save_nr_DIV_y;
	long Save_nr_DIV_z = Inp_D->Save_nr_DIV_z;
	cout << "Nr. of data saving threads = " << 3*Save_nr_DIV_x*Save_nr_DIV_y + 
		                                       3*Save_nr_DIV_y*Save_nr_DIV_z +
						                       3*Save_nr_DIV_x*Save_nr_DIV_z << endl;
	
	long nPML_x_1 = Inp_D->nPML_x_1; //[cells] the size of PML-1 zone in x
	long nPML_x_2 = Inp_D->nPML_x_2; //[cells] the size of PML-2 zone in x
	long nPML_y_1 = Inp_D->nPML_y_1; //[cells] the size of PML-1 zone in y
	long nPML_y_2 = Inp_D->nPML_y_2; //[cells] the size of PML-2 zone in y
	long nPML_z_1 = Inp_D->nPML_z_1; //[cells] the size of PML-1 zone in z
	long nPML_z_2 = Inp_D->nPML_z_2; //[cells] the size of PML-2 zone in z

	double dx = Inp_D->dx;
	double dy = Inp_D->dy;
	double dz = Inp_D->dz;
	
	//copute the time steep according to the Courant limit
	double dt = ( 1.0/speed_c/sqrt(1.0/(dx*dx)+1.0/(dy*dy)+1.0/(dz*dz)) )*0.9;
	cout << "dt = " << dt << endl;
	
	long num_iter = Inp_D->num_iter; //the number of FDTD iterations
	double limit_time = Inp_D->limit_time;//[s] 23:30 the running time, 
	                          //after it saves out all workspace data in binary

	int load_workspace_data = Inp_D->load_workspace_data; //1 - load the workspace data and continue computations
	
	int jel_limit_time = 0;

	//save out slices of the field components
	int save_field = Inp_D->save_field; //to save data - Ex, Ey, Ez, Hx, Hy, Hz slices
	long nr_Save, saveFROMinst, saveTOinst;
	long n_x_a, n_x_b, n_y_a, n_y_b, n_z_a, n_z_b; //specify the saved data 
	if (save_field == 1)
	{
	    nr_Save = Inp_D->nr_Save;
		saveFROMinst = Inp_D->saveFROMinst; //from
		saveTOinst   = Inp_D->saveTOinst;//to
		
		//specify the saving area 
		n_x_a = Inp_D->n_x_a;
		n_x_b = Inp_D->n_x_b;
		n_y_a = Inp_D->n_y_a;
		n_y_b = Inp_D->n_y_b;
		n_z_a = Inp_D->n_z_a;
		n_z_b = Inp_D->n_z_b;
	}

	//average over a rectangular volume
	long nx_a_av, nx_b_av, ny_a_av, ny_b_av, nz_a_av, nz_b_av;
	long Vol_av;
	if (Inp_D->aver_field_volume == 1)
	{
		nx_a_av = Inp_D->nx_a_av; nx_b_av = Inp_D->nx_b_av; 
		ny_a_av = Inp_D->ny_a_av; ny_b_av = Inp_D->ny_b_av; 
		nz_a_av = Inp_D->nz_a_av; nz_b_av = Inp_D->nz_b_av; 

		Vol_av = (nx_b_av - nx_a_av + 1)*(ny_b_av - ny_a_av + 1)*(nz_b_av - nz_a_av + 1);
	}
	
	//fourier transform in a rectangular volume
	long nx_a_f, nx_b_f, ny_a_f, ny_b_f, nz_a_f, nz_b_f;
	double frec_1, frec_2;
	long n_frec, n_f_Points, start_fourier;
	if (Inp_D->fourier_transf_vol == 1) 
	{
		//compute the Fourier transform in this volume
		nx_a_f = Inp_D->nx_a_f; nx_b_f = Inp_D->nx_b_f; 
		ny_a_f = Inp_D->ny_a_f; ny_b_f = Inp_D->ny_b_f; 
		nz_a_f = Inp_D->nz_a_f; nz_b_f = Inp_D->nz_b_f; 
		//the total nr of points
		n_f_Points = (nx_b_f - nx_a_f + 1)*(ny_b_f - ny_a_f + 1)*(nz_b_f - nz_a_f + 1);
		//between these frequencies
		frec_1 = Inp_D->frec_1;
		frec_2 = Inp_D->frec_2;
		n_frec = Inp_D->n_frec; //nr of frequencies
		start_fourier = Inp_D->start_fourier;
	}

	///////////////////////////////////////////////////////////////////////////////////////
	//the electromagnetic energy
	///////////////////////////////////////////////////////////////////////////////////////
	#ifdef eval_W
		//division - for computing with threads
		long nr_W_DIV_x = Inp_D->nr_W_DIV_x;
		long nr_W_DIV_y = Inp_D->nr_W_DIV_y;
		long nr_W_DIV_z = Inp_D->nr_W_DIV_z;

		long nr_Threads_W = nr_W_DIV_x*nr_W_DIV_y*nr_W_DIV_z;

		//defines the volume where the energy will be computed
		long nx_W_a = Inp_D->nx_W_a,  nx_W_b = Inp_D->nx_W_b; 
		long ny_W_a = Inp_D->ny_W_a,  ny_W_b = Inp_D->ny_W_b; 
		long nz_W_a = Inp_D->nz_W_a,  nz_W_b = Inp_D->nz_W_b;

		//the size of W
		long nx_W = nx_W_b - nx_W_a;
		long ny_W = ny_W_b - ny_W_a;
		long nz_W = nz_W_b - nz_W_a;
		
		double Vol = nx_W*ny_W*nz_W*dx*dy*dz;
		double Surf_xz = nx_W*nz_W*dx*dz;

		//compute the energy between the instants
		long eval_W_FROMinst = Inp_D->eval_W_FROMinst;
		long eval_W_TOinst   = Inp_D->eval_W_TOinst;

		//the average of the energy in the specified volume
		long n_W_atl = eval_W_TOinst - eval_W_FROMinst;
		long iter_W = 0;

		//save slices from W
		int save_W = Inp_D->save_W; //to save W
		long nr_W_Save = Inp_D->nr_W_Save; //to save at
		long save_W_FROMinst = Inp_D->save_W_FROMinst; //>= eval_W_FROMinst
		long save_W_TOinst   = Inp_D->save_W_TOinst; //<= eval_W_TOinst
		//defines the volume where the energy will be saved
		//take into consideration nx_W_a, nx_W_b, ... nz_W_b
		long n_x_W_a = Inp_D->n_x_W_a,    n_x_W_b = Inp_D->n_x_W_b; 
		long n_y_W_a = Inp_D->n_y_W_a,    n_y_W_b = Inp_D->n_y_W_b; 
		long n_z_W_a = Inp_D->n_z_W_a,    n_z_W_b = Inp_D->n_z_W_b;

		//division - for saving W with threads
		long Save_nr_W_DIV_x = Inp_D->Save_nr_W_DIV_x;
		long Save_nr_W_DIV_y = Inp_D->Save_nr_W_DIV_y;
		long Save_nr_W_DIV_z = Inp_D->Save_nr_W_DIV_z;
	#endif

	///////////////////////////////////////////////////////////////////////////////////////
	//the excitation
	///////////////////////////////////////////////////////////////////////////////////////
	int source_type = Inp_D->source_type;       // 1- Gauss; 2- Sin; 3- Gauss-Sin

	int jel_plane_wave = Inp_D->jel_plane_wave; //the type of the excitation 0 - point  source
	                                            //                           1 - plane wave
	int pt_source_Ez, pt_source_Hz;//specify the polarization
	int switch_off_time;
	double const_alfa;
		
	long n_Coord;
	long **Coord_ptSource = NULL;
	double **Param_Source = NULL;
	
	double X0, tw, t0, omega, phase, teta, phi, gamma;
	long n_TS_xa, n_TS_xb, n_TS_ya, n_TS_yb,n_TS_za, n_TS_zb;
	long n_TS = 0;

	long i;

	switch (jel_plane_wave)
	{
		case 0:
			if (Inp_D->readFile_Param_Pt_Source == 1)
			{
				/////////////////////////////////////////////////???????????????
				cout << "not implemented yet" << endl;
				return 1;
			}
			else
			{
				n_Coord = 1;
				Coord_ptSource = Init_Matrix_2D<long >(n_Coord,3);
				if (!Coord_ptSource)
				{
					cout << "Memory allocation problem - **Coord_ptSource" << endl;
					return -1;
				}

				Coord_ptSource[0][0] = nx/2+2;//175;//nx/2+2;//125;
				Coord_ptSource[0][1] = ny/2+3;//835;//522;//30
				Coord_ptSource[0][2] = nz/2;

				if (source_type == 1 || source_type == 2)
				{
					Param_Source = Init_Matrix_2D<double>(n_Coord,3);
				}
				else
				{
					Param_Source = Init_Matrix_2D<double>(n_Coord,5);
				}
				if (!Param_Source)
				{
					cout << "Memory allocation problem - **Param_Source" << endl;
					return -1;
				}
				
				X0 = Inp_D->X0; //amplituide
				switch ( Inp_D->source_type)
				{
					case 1: //Gaussian source
						tw = Inp_D->tw;
						t0 = Inp_D->t0;
						break;
					case 2: //Sin source
						omega      = Inp_D->omega;
						phase      = Inp_D->phase;
						const_alfa = Inp_D->const_alfa;
						break;
					case 3://Gaussian-Sin source
						tw    = Inp_D->tw;
						t0    = Inp_D->t0;
						omega = Inp_D->omega;

⌨️ 快捷键说明

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