├── User Files ├── bias_input.txt └── doping_profile.txt ├── Build ├── SMCv1_0_0.exe ├── SMCv1_0_1.exe ├── SMCv1_1_0.exe └── SMCv1_1_1.exe ├── doc └── Simple Monte Carlo Simulator Documentation.pdf ├── src ├── model.h ├── dev_prop_func.h ├── main.cpp ├── tools.h ├── functions.h ├── device.h ├── SMC.h ├── carrier.h ├── functions.cpp ├── SMC_class.cpp ├── histogram.h ├── carrier_class.cpp ├── dev_prop_func.cpp ├── tools_class.cpp ├── histogram_class.cpp ├── drift_velocity.cpp ├── device_class.cpp ├── ii_coef.cpp └── device_properties.cpp ├── NOTICE.txt ├── README.txt └── LICENSE.txt /User Files/bias_input.txt: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | 3 4 | 4 5 | -------------------------------------------------------------------------------- /User Files/doping_profile.txt: -------------------------------------------------------------------------------- 1 | 3e18,2 2 | -2e16,0.13 3 | -3e18,2 -------------------------------------------------------------------------------- /Build/SMCv1_0_0.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jdpetticrew/Simple-Monte-Carlo-Simulator/HEAD/Build/SMCv1_0_0.exe -------------------------------------------------------------------------------- /Build/SMCv1_0_1.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jdpetticrew/Simple-Monte-Carlo-Simulator/HEAD/Build/SMCv1_0_1.exe -------------------------------------------------------------------------------- /Build/SMCv1_1_0.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jdpetticrew/Simple-Monte-Carlo-Simulator/HEAD/Build/SMCv1_1_0.exe -------------------------------------------------------------------------------- /Build/SMCv1_1_1.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jdpetticrew/Simple-Monte-Carlo-Simulator/HEAD/Build/SMCv1_1_1.exe -------------------------------------------------------------------------------- /doc/Simple Monte Carlo Simulator Documentation.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jdpetticrew/Simple-Monte-Carlo-Simulator/HEAD/doc/Simple Monte Carlo Simulator Documentation.pdf -------------------------------------------------------------------------------- /src/model.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2017 Advanced Detector Centre, Department of Electronic and 2 | Electrical Engineering, University of Sheffield, UK. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License.*/ 15 | 16 | /* 17 | Contains the function prototypes for the three modes available in main.cpp 18 | 19 | Jonathan Petticrew, University of Sheffield, 2017. 20 | */ 21 | 22 | 23 | #ifndef MODEL_H 24 | #define MODEL_H 25 | 26 | // device_properties() is defined in device_properties.cpp 27 | void device_properties(int material); 28 | 29 | // drift_velocity() is defined in drift_velocity.cpp 30 | void drift_velocity(int material); 31 | 32 | // ii_coef() is defined in ii_coef.cpp 33 | void ii_coef(int material); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/dev_prop_func.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2017 Advanced Detector Centre, Department of Electronic and 2 | Electrical Engineering, University of Sheffield, UK. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License.*/ 15 | 16 | /* 17 | dev_prop_func.h contains the function prototypes for functions that are uniqe to the device_properties mode 18 | in device_properties.cpp 19 | 20 | functions are implimented in dev_prop_func.cpp 21 | 22 | Jonathan Petticrew, University of Sheffield, 2017. 23 | */ 24 | 25 | #ifndef DEV_PROP_FUNC_H 26 | #define DEV_PROP_FUNC_H 27 | 28 | //Counts the number of bias in the bias_input.txt 29 | int biascounter(); 30 | 31 | //Reads in User input for time slices 32 | int timesliceread(); 33 | 34 | //Reads in User input for injection condition 35 | int usDeviceread(); 36 | 37 | //Reads in user input for simulation time limit 38 | double simulationtimeread(); 39 | 40 | //Reads in user input for number of trials per voltage 41 | int trialsread(); 42 | 43 | //Does some post processing at the end of device_properties() 44 | void postprocess(double Vsim[],double simtime, int voltages); 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright 2017 Advanced Detector Centre, Department of Electronic and 2 | Electrical Engineering, University of Sheffield, UK. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License.*/ 15 | 16 | /* 17 | main.cpp contains the decleration of main for the Simple Monte Carlo Simulator. 18 | It requests material and mode inputs from the user before running the requested mode. 19 | Jonathan Petticrew, University of Sheffield, 2017. 20 | */ 21 | 22 | #include 23 | #include "model.h" 24 | #include 25 | int main(){ 26 | 27 | //request material from user 28 | int material; 29 | printf("Material: 1) Si, 2) GaAs, 3) InGaP\n"); 30 | scanf("%d",&material); 31 | 32 | //requests model from user 33 | int calc; 34 | printf("Mode: 1) Diode Properties, 2) Drift Velocity, 3) Impact Ionization Coefficients\n"); 35 | scanf("%d", &calc); 36 | 37 | //runs user specified model 38 | if (calc==1) device_properties(material); 39 | else if (calc==2) drift_velocity(material); 40 | else if (calc==3) ii_coef(material); 41 | 42 | int inputkey; 43 | printf("Press space to exit\n"); 44 | while((inputkey=_getch())==0); 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /src/tools.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2017 Advanced Detector Centre, Department of Electronic and 2 | Electrical Engineering, University of Sheffield, UK. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License.*/ 15 | 16 | /* 17 | tools.h contains the class definition of the tools class for the SMC 18 | The tools class calculates the scattering rates and probabilities for the SMC 19 | 20 | tools_class.cpp contains the class implimentation 21 | 22 | Jonathan Petticrew, University of Sheffield, 2017. 23 | */ 24 | #ifndef TOOLS_H 25 | #define TOOLS_H 26 | #include "SMC.h" 27 | 28 | 29 | const int PB_DIM2_SZ=20000; 30 | const int PB_DIM1_SZ=3; 31 | class tools { 32 | private: 33 | SMC *constants; 34 | double pb[PB_DIM1_SZ][PB_DIM2_SZ]; //array of probabilities 35 | double pb2[PB_DIM1_SZ][PB_DIM2_SZ]; //array of probabilities 36 | void e_rate(); 37 | void h_rate(); 38 | double rtotal; 39 | double rtotal2; 40 | double my_pow(double base, double exponent); 41 | public: 42 | tools(SMC *input); 43 | int scattering_probability(); 44 | double Get_rtotal(); 45 | double Get_rtotal2(); 46 | double Get_pb(int i, int j); 47 | double Get_pb2(int i, int j); 48 | }; 49 | #endif 50 | -------------------------------------------------------------------------------- /src/functions.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2017 Advanced Detector Centre, Department of Electronic and 2 | Electrical Engineering, University of Sheffield, UK. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License.*/ 15 | 16 | /* 17 | functions.h contains the function prototypes for the common functions used in all three modes 18 | function declerations in functions.cpp 19 | 20 | Jonathan Petticrew, University of Sheffield, 2017. 21 | */ 22 | 23 | #ifndef FUNC_H 24 | #define FUNC_H 25 | 26 | /* Random Generator Initilization*/ 27 | /* Period parameters */ 28 | #define Nr 624 29 | #define M 397 30 | #define MATRIX_A 0x9908b0df /* constant vector a */ 31 | #define UPPER_MASK 0x80000000 /* most significant w-r bits */ 32 | #define LOWER_MASK 0x7fffffff /* least significant r bits */ 33 | 34 | /* Tempering parameters */ 35 | #define TEMPERING_MASK_B 0x9d2c5680 36 | #define TEMPERING_MASK_C 0xefc60000 37 | #define TEMPERING_SHIFT_U(y) (y >> 11) 38 | #define TEMPERING_SHIFT_S(y) (y << 7) 39 | #define TEMPERING_SHIFT_T(y) (y << 15) 40 | #define TEMPERING_SHIFT_L(y) (y >> 18) 41 | 42 | 43 | static unsigned long mt[Nr]; 44 | static int mti = Nr+1; 45 | double _max(double x, double y); 46 | void sgenrand(unsigned long seed); 47 | double genrand(); 48 | #endif 49 | -------------------------------------------------------------------------------- /src/device.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2017 Advanced Detector Centre, Department of Electronic and 2 | Electrical Engineering, University of Sheffield, UK. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License.*/ 15 | 16 | /* 17 | device.h contains the class implimentation of the device class for the SMC. 18 | 19 | The device class contains a Poisson solver and a linear interpolater to claculate the 20 | electric field properties of semiconductor devices. 21 | 22 | device_class.cpp contains the class definition 23 | 24 | Jonathan Petticrew, University of Sheffield, 2017. 25 | */ 26 | 27 | #ifndef DEVICE_H 28 | #define DEVICE_H 29 | #include "SMC.h" 30 | 31 | class device { 32 | private: 33 | SMC *constants; 34 | int NumLayers; 35 | double Vbi; 36 | double width; 37 | double *efield_x; 38 | double *efield_e; 39 | double *N; 40 | double *w; 41 | int i_max; 42 | int i_min; 43 | double die; 44 | double q; 45 | double LinearInterpolate(double y1, double y2, double x1, double x2, double x); 46 | void read(); 47 | int depletionlookup(); 48 | public: 49 | device(SMC *con); 50 | double Efield_at_x(double xpos); //returns the Efield for a given position 51 | double Get_width(); 52 | double Get_xmin(); 53 | double Get_xmax(); 54 | void profiler(double voltage); 55 | }; 56 | #endif 57 | -------------------------------------------------------------------------------- /NOTICE.txt: -------------------------------------------------------------------------------- 1 | Simple Monte Carlo Simulator 2 | Copyright 2017 Advanced Detector Centre, Department of Elecronic and Electrical 3 | Engineering, University of Sheffield, UK. 4 | 5 | This product includes software developed at 6 | Advanced Detector Centre, 7 | Department of Electronic and Electrical Engineering, 8 | University of Sheffield, UK. 9 | 10 | This product uses the GaAs parameter set from 11 | S. A. Plimmer, J. P. R. David, D. S. Ong, and K. F. Li, (1999). A simple model for avalanche 12 | multiplication including deadspace effects. IEEE Transactions on Electron Devices, vol.46, 13 | no.4, pp.769-775. DOI: https://doi.org/10.1109/16.753712 14 | 15 | This product uses the InGaP parameter set from 16 | C. H. Tan, R. Ghin, J. P. R. David, G. J. Rees, and M. Hopkinson, ‘The effect of dead 17 | space on gain and excess noise in In0.48Ga0.52P p+ in+ diodes’, Semiconductor Science 18 | and technology, vol. 18, no. 8, p. 803, 2003. 19 | DOI: https://doi.org/10.1088/0268-1242/18/8/314 20 | 21 | This product uses the Si parameter set from 22 | X. Zhou, J. S. Ng, and C. H. Tan, ‘A simple Monte Carlo model for prediction of 23 | avalanche multiplication process in Silicon’,J. Inst., vol. 7, no. 08, p. P08006, 2012. 24 | DOI: https://doi.org/10.1088/1748-0221/7/08/P08006 25 | 26 | ________________________________________________________________________________________ 27 | 28 | This product includes software from the Gaussian Histogram Fitter (Apache 2.0) 29 | https://github.com/jdpetticrew/Gaussian-Histogram-Fitter 30 | 31 | The Gaussian Histogram Fitter includes the following in its NOTICE file: 32 | 33 | Gaussian Histogram Fitter 34 | Copyright 2017 Advanced Detector Centre, Department of Elecronic and Electrical 35 | Engineering, University of Sheffield, UK. 36 | 37 | This product includes software developed at 38 | Advanced Detector Centre, 39 | Department of Electronic and Electrical Engineering, 40 | University of Sheffield, UK. -------------------------------------------------------------------------------- /src/SMC.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2017 Advanced Detector Centre, Department of Electronic and 2 | Electrical Engineering, University of Sheffield, UK. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License.*/ 15 | 16 | /* 17 | SMC.h contains the class definition for the SMC Class 18 | The SMC class contains all the SMC parameters. 19 | 20 | SMC_class.cpp contains the implimentation 21 | 22 | Jonathan Petticrew, University of Sheffield, 2017. 23 | */ 24 | 25 | #ifndef SMC_H 26 | #define SMC_H 27 | class SMC { 28 | private: 29 | double q; 30 | double MAX_eV; // Maximum energy in electron volts 31 | double Emax; // Maximum energy in joules 32 | int NUMPOINTS; //number of points 33 | double hbar; 34 | double K; //boltzmann's constant 35 | double T; //temperature 36 | double hw; 37 | double N; 38 | double free_mass; 39 | double e_mass; 40 | double h_mass; 41 | double e_meanpath; 42 | double h_meanpath; 43 | double e_Eth; 44 | double h_Eth; 45 | double e_Cii; 46 | double h_Cii; 47 | double e_gamma; 48 | double h_gamma; 49 | double Vbi; 50 | double die; 51 | public: 52 | SMC(); 53 | double Get_N(); 54 | double Get_e_meanpath(); 55 | double Get_q(); 56 | double Get_e_Eth(); 57 | double Get_h_Eth(); 58 | double Get_hw(); 59 | double Get_e_mass(); 60 | double Get_h_mass(); 61 | double Get_e_Cii(); 62 | double Get_h_Cii(); 63 | double Get_e_gamma(); 64 | double Get_h_gamma(); 65 | double Get_h_meanpath(); 66 | int Get_NUMPOINTS(); 67 | double Get_hbar(); 68 | double Get_Emax(); 69 | double Get_permitivity(); 70 | double Get_Vbi(); 71 | void mat(int x); 72 | double Get_die(); 73 | }; 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /src/carrier.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2017 Advanced Detector Centre, Department of Electronic and 2 | Electrical Engineering, University of Sheffield, UK. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License.*/ 15 | 16 | /* 17 | carrier.h contains the class implimentation for the carrier class for the SMC 18 | The carrier class contains all the information about the carriers as they travel through the device 19 | 20 | carrer_class.cpp contains the class definition 21 | 22 | Jonathan Petticrew, University of Sheffield, 2017. 23 | */ 24 | 25 | #ifndef CARRIER_H 26 | #define CARRIER_H 27 | #define Array 1000000 // Statically allocated max number of electrons or holes to track. 28 | #include "SMC.h" 29 | class carrier { 30 | private: 31 | double position[Array]; 32 | double Egy[Array]; 33 | double kxy[Array]; 34 | double kz[Array]; 35 | int scattering[Array]; 36 | double time[Array]; 37 | double dt[Array]; 38 | double dx[Array]; 39 | int timearray[Array]; 40 | SMC *constants; 41 | double hmass; 42 | double emass; 43 | double hbar; 44 | public: 45 | carrier(SMC *con); 46 | ~carrier(); 47 | void Input_pos(int i, double input); 48 | void Input_scattering(int i, int input); 49 | void Input_Egy(int i, double input); 50 | void Input_kxy(int i, double input); 51 | void Input_kz(int i, double input); 52 | double Get_pos(int i); 53 | double Get_Egy(int i); 54 | double Get_kxy(int i); 55 | double Get_kz(int i); 56 | int Get_scattering(int i); 57 | void Input_time(int i, double input); 58 | double Get_time(int i); 59 | void Input_dt(int i, double input); 60 | double Get_dt(int i); 61 | void Input_dx(int i, double input); 62 | double Get_dx(int i); 63 | void reset(); 64 | void Input_timearray(int i, int input); 65 | int Get_timearray(int i); 66 | void scatter(int i, int j); 67 | void generation(int i, double z_pos, double Egy, double time, double dt, int timearray); 68 | }; 69 | #endif 70 | -------------------------------------------------------------------------------- /src/functions.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright 2017 Advanced Detector Centre, Department of Electronic and 2 | Electrical Engineering, University of Sheffield, UK. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License.*/ 15 | 16 | /* 17 | functions.cpp contains the function declerations for the common functions used in all three modes 18 | function prototypes in functions.h 19 | 20 | Jonathan Petticrew, University of Sheffield, 2017. 21 | */ 22 | #include "functions.h" 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | double _max(double x,double y) 29 | { 30 | if(x>y) return x; 31 | else return y; 32 | }; 33 | // seeds the random number generator 34 | void sgenrand(unsigned long seed) 35 | { 36 | int i; 37 | for (i=0; i>16; 41 | seed = 69069*seed+1;} 42 | mti=Nr; 43 | }; 44 | 45 | //calculates the next random number in the seeded mersenne twister. 46 | double genrand(){ //quite a lot of the parameters in this function are #defined in default_include.h 47 | double ans; 48 | unsigned long y; 49 | static unsigned long mag01[2] = {0x0, MATRIX_A}; 50 | if (mti >= Nr) //generate N words at one time 51 | { int kk; 52 | if (mti == Nr+1) sgenrand(4357); //sets initial seed 53 | for (kk=0; kk<(Nr-M); kk++) 54 | { y=(mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK); 55 | mt[kk] = mt[kk+M] ^ (y>>1) ^ mag01[y & 0x1];} 56 | for (; kk>1) ^ mag01[y & 0x1];} 59 | y=(mt[Nr-1] & UPPER_MASK) | (mt[0] & LOWER_MASK); 60 | mt[Nr-1]=mt[M-1]^(y>>1)^mag01[y &0x1]; 61 | mti=0;} 62 | y = mt[mti++]; 63 | y ^= TEMPERING_SHIFT_U (y); 64 | y ^= TEMPERING_SHIFT_S (y) & TEMPERING_MASK_B; 65 | y ^= TEMPERING_SHIFT_T (y) & TEMPERING_MASK_C; 66 | y ^= TEMPERING_SHIFT_L (y); 67 | ans= ( double )y * 2.3283064365386963e-10; 68 | while ((ans<=0)||(ans>=1)) ans=genrand(); 69 | return ans; 70 | }; 71 | -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | Simple Monte Carlo Simulator 2 | 3 | The Simple Monte Carlo Simulator is a standalone executable capable of simulating 4 | Avalanche Photodiode (APD) and Single Photon Avalanche Photodiode (SPAD) characteristics. 5 | Written in C++. 6 | 7 | ---------------------- 8 | Software Capabilities 9 | ---------------------- 10 | There are three main modes within the software with different capabilities. 11 | The three modes are "Diode Properties", "Drift Velocity" & "Impact Ionization Coefficients" 12 | 13 | Diode Properties Mode: 14 | Can produce the following characteristics of an input APD or SPAD structure. 15 | - Avalanche Gain/Multiplication Factor 16 | - Excess Noise Factor 17 | - Breakdown Probability 18 | - Mean Time to Breakdown 19 | 20 | 21 | Drift Velocity Mode: 22 | Can produce the following characteristics of a simulated material. 23 | - Electron Drift Velocity 24 | - Hole Drift Velocity 25 | 26 | Impact Ionization Mode: 27 | Can produce the following characteristics of a simulated material. 28 | - Electron Impact Ionization Coefficients (Alpha) 29 | - Hole Impact Ionization Coefficients (Beta) 30 | 31 | ---------------------- 32 | Material Capabilities 33 | ---------------------- 34 | 35 | Currently Simple Monte Carlo parameter sets have been implimented for the following materials: 36 | -Silicon 37 | -Gallium Arsenide 38 | -Indium Gallium Phosphide 39 | 40 | ---------------------- 41 | File Structure 42 | ---------------------- 43 | -doc 44 | Documentation on how to use the executables. 45 | -src 46 | Contains the Source Code 47 | -User Files 48 | Contains examples of input files required for diode properties mode. 49 | -Build 50 | Contains a compiled exe for each tagged version. 51 | 52 | ---------------------- 53 | Support/Issues 54 | ---------------------- 55 | 56 | If you encounter any issues with the Simple Monte Carlo Simulator please post an issue on the GitHub repository. 57 | 58 | ---------------------- 59 | Citations 60 | ---------------------- 61 | 62 | Please use the citation below if you use the Simple Monte Carlo Simulator, please aslo use the citation for 63 | the corresponding material parameter set(s). 64 | 65 | Petticrew, J.D., Dimler, S.J. & Ng, J.S., (2018). Simple Monte Carlo Simulator for Modelling Linear Mode 66 | and Geiger Mode Avalanche Photodiodes in C++ . Journal of Open Research Software . 6 ( 1 ) , p . 17 . 67 | DOI: http://doi.org/10.5334/jors.212 68 | 69 | 70 | Please use the following citations for the material parameter sets: 71 | 72 | Silicon 73 | X. Zhou, J. S. Ng, and C. H. Tan, ‘A simple Monte Carlo model for prediction of 74 | avalanche multiplication process in Silicon’,J. Inst., vol. 7, no. 08, p. P08006, 2012. 75 | DOI: https://doi.org/10.1088/1748-0221/7/08/P08006 76 | 77 | Indium Gallium Phosphide 78 | C. H. Tan, R. Ghin, J. P. R. David, G. J. Rees, and M. Hopkinson, ‘The effect of dead 79 | space on gain and excess noise in In0.48Ga0.52P p+in+ diodes’, Semiconductor Science 80 | and technology, vol. 18, no. 8, p. 803, 2003. 81 | DOI: https://doi.org/10.1088/0268-1242/18/8/314 82 | 83 | Gallium Arsenide 84 | S. A. Plimmer, J. P. R. David, D. S. Ong, and K. F. Li, (1999). A simple model for avalanche 85 | multiplication including deadspace effects. IEEE Transactions on Electron Devices, vol.46, 86 | no.4, pp.769-775. DOI: https://doi.org/10.1109/16.753712 87 | 88 | 89 | ---------------------- 90 | Licensing 91 | ---------------------- 92 | Please see the file LICENSE.txt 93 | Please see the file NOTICE.txt for any applicable notices. 94 | -------------------------------------------------------------------------------- /src/SMC_class.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright 2017 Advanced Detector Centre, Department of Electronic and 2 | Electrical Engineering, University of Sheffield, UK. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License.*/ 15 | 16 | /* 17 | SMC_class.cpp contains the class implimentation for the SMC Class 18 | The SMC class contains all the SMC parameters. 19 | 20 | SMC.h contains the definition 21 | Functions with Get_ are all getter functions. 22 | 23 | Jonathan Petticrew, University of Sheffield, 2017. 24 | */ 25 | #include "SMC.h" 26 | #include 27 | #include 28 | //Constructor sets non-material specific parameters 29 | SMC::SMC(){ 30 | q=1.6e-19; 31 | hbar=1.0545716818e-34; 32 | K=1.380622e-23; //boltzmann's constant 33 | T=300; 34 | free_mass=9.1093821545e-31; 35 | 36 | }; 37 | 38 | double SMC::Get_N(){ 39 | return N; 40 | }; 41 | 42 | double SMC::Get_e_meanpath(){ 43 | return e_meanpath; 44 | }; 45 | 46 | double SMC::Get_h_meanpath(){ 47 | return h_meanpath; 48 | }; 49 | 50 | double SMC::Get_q(){ 51 | return q; 52 | }; 53 | 54 | double SMC::Get_e_Eth(){ 55 | return e_Eth; 56 | }; 57 | 58 | double SMC::Get_h_Eth(){ 59 | return h_Eth; 60 | }; 61 | 62 | double SMC::Get_hw(){ 63 | return hw; 64 | }; 65 | 66 | double SMC::Get_e_mass(){ 67 | return e_mass; 68 | }; 69 | 70 | double SMC::Get_h_mass(){ 71 | return h_mass; 72 | }; 73 | 74 | double SMC::Get_e_Cii(){ 75 | return e_Cii; 76 | }; 77 | 78 | double SMC::Get_h_Cii(){ 79 | return h_Cii; 80 | }; 81 | 82 | double SMC::Get_e_gamma(){ 83 | return e_gamma; 84 | }; 85 | 86 | double SMC::Get_h_gamma(){ 87 | return h_gamma; 88 | }; 89 | 90 | int SMC::Get_NUMPOINTS(){ 91 | return NUMPOINTS; 92 | }; 93 | 94 | double SMC::Get_hbar(){ 95 | return hbar; 96 | }; 97 | 98 | double SMC::Get_Emax(){ 99 | return Emax; 100 | }; 101 | 102 | double SMC::Get_Vbi(){ 103 | return Vbi; 104 | }; 105 | 106 | double SMC::Get_die(){ 107 | return die; 108 | }; 109 | 110 | //Sets the material specific parameters 111 | void SMC::mat(int x){ 112 | 113 | if (x == 1) { // Silicon Parameters 114 | e_mass=(0.6*free_mass); 115 | h_mass=(0.9*free_mass); 116 | e_meanpath=98e-10; 117 | h_meanpath=68e-10; 118 | e_Eth=(1.2*q); 119 | h_Eth=(1.5*q); 120 | e_Cii=2e12; 121 | h_Cii=4.4e12; 122 | e_gamma=3.5; 123 | h_gamma=3.5; 124 | hw=(0.063*q); 125 | MAX_eV=6; 126 | Vbi=1; 127 | die=11.90; 128 | } 129 | else if (x == 2) {//GaAd 130 | e_mass=(0.5*free_mass); 131 | h_mass=(0.5*free_mass); 132 | e_meanpath=50.4e-10; 133 | h_meanpath=47.6e-10; 134 | e_Eth=(1.75*q); 135 | h_Eth=(1.75*q); 136 | e_Cii=40e12; 137 | h_Cii=30e12; 138 | e_gamma=4; 139 | h_gamma=4; 140 | hw=(0.029*q); 141 | MAX_eV=8.75; 142 | Vbi=1.2; 143 | die=12.9; 144 | } 145 | else if (x == 3) {//InGaP 146 | e_mass=(0.7*free_mass); 147 | h_mass=(0.7*free_mass); 148 | e_meanpath=55.7e-10; 149 | h_meanpath=58.2e-10; 150 | e_Eth=(2.11*q); 151 | h_Eth=(2.11*q); 152 | e_Cii=8e12; 153 | h_Cii=8e12; 154 | e_gamma=2.3; 155 | h_gamma=2.3; 156 | hw=(0.037*q); 157 | MAX_eV=6; 158 | Vbi=1.8; 159 | die=11.8; 160 | } 161 | 162 | Emax=MAX_eV*q; 163 | NUMPOINTS = (int)(MAX_eV*1000); 164 | N=(1/(exp(hw/(K*T))-1)); 165 | }; 166 | -------------------------------------------------------------------------------- /src/histogram.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2017 Advanced Detector Centre, Department of Electronic and 2 | Electrical Engineering, University of Sheffield, UK. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License.*/ 15 | 16 | /* 17 | histogram.h contains the class definition for the Gaussian Histogram Fitter 18 | See histogram_class.cpp for function declarations 19 | 1) histogram(double* data, int size); 20 | Pass the 1d data array and the number of elements it contains. 21 | The class will ask for a user input for histogram bin width and output the histgram data and fit to Hist.txt 22 | 2) histogram(double* data, int size, double binsize); 23 | Pass the 1d data array, the number of elements the array contains, and the histogram bin width. 24 | The class will output the histgram data and fit to Hist.txt 25 | 3) histogram(double* data, int size, char* fname); 26 | Pass the 1d data array, the number of elements the array contains, and a file name to output the data and fit. 27 | The class will ask for a user input for histogram bin width and output the fit and data to the passed file name. 28 | 4) histogram(double* data, int size, double binsize, char* fname); 29 | Pass the 1d data array, the number of elements the array contains, the histogram bin width, and a file name to output the data and fit. 30 | The class will utput the fit and data to the passed file name. 31 | 32 | Jonathan Petticrew, University of Sheffield, 2017. 33 | */ 34 | #ifndef HISTOGRAM_H 35 | #define HISTOGRAM_H 36 | 37 | class histogram { 38 | private: 39 | double* dataset; 40 | int size; 41 | double max; 42 | double min; 43 | double binsize; 44 | double* binEdges; 45 | double* binCenters; 46 | double* binValues; 47 | double mean; 48 | double meansquare; 49 | double sdev; //standard deviation 50 | //Gaussian in the form f(x) = a exp(-((x-b)/c)^2) 51 | double a; 52 | double b; 53 | double c; 54 | double FWHM; 55 | char* filename; 56 | int bins; 57 | int charstored; 58 | 59 | void binner(); //Bins the DataSet and calculates mean and standard deviation 60 | void fit(); //Fits Gaussian Probability Density Function in the form f(x) = a exp(-((x-b)/c)^2) 61 | void max_min(); //finds maximum and minimum in dataset 62 | void print(); //Prints Histogram Data to Hist.txt Used if no string is passed in constructor 63 | void print_custom(); //Prints Histogram Data to custom file 64 | public: 65 | histogram(double* data, int size); //constructor for histogram class Ask for Bin Size 66 | histogram(double* data, int size, double binsize); //constructor for histogram class passed Bin Size 67 | histogram(double* data, int size, char* fname); //constructor for histogram class Ask for Bin Size and passes string for printing Hist to file. 68 | histogram(double* data, int size, double binsize, char* fname); //constructor for histogram class passed Bin Size and passes string for printing Hist to file. 69 | ~histogram(); 70 | double Get_FWHM(){ 71 | return FWHM; 72 | }; //Returns Full-Width @ Half-Maximum 73 | double Get_Mean(){ 74 | return mean; 75 | }; //Returns Mean of Histogram 76 | double Get_SDev(){ 77 | return sdev; 78 | }; //Returns Standard Deviation of Histogram 79 | void show_fit(); // displays Probability Density function of gaussian 80 | }; 81 | #endif 82 | -------------------------------------------------------------------------------- /src/carrier_class.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright 2017 Advanced Detector Centre, Department of Electronic and 2 | Electrical Engineering, University of Sheffield, UK. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License.*/ 15 | 16 | /* 17 | carrier_class.cpp contains the class definition for the carrier class for the SMC 18 | The carrier class contains all the information about the carriers as they travel through the device 19 | 20 | carrer.h contains the class implimentation 21 | 22 | Jonathan Petticrew, University of Sheffield, 2017. 23 | */ 24 | 25 | #include "carrier.h" 26 | #include "functions.h" 27 | #include "math.h" 28 | //All these functions are for Get, Set and Zero. 29 | carrier::carrier(SMC *input) : constants(input){ 30 | int i; 31 | emass= constants->Get_e_mass(); 32 | hmass= constants->Get_h_mass(); 33 | hbar=constants->Get_hbar(); 34 | for(i=1; i<(Array+1); i++) 35 | { position[i]=0; 36 | Egy[i]=0; 37 | kxy[i]=0; 38 | kz[i]=0; 39 | scattering[i]=0; 40 | dt[i]=0; 41 | dx[i]=0; 42 | time[i]=0; 43 | timearray[i]=0;} 44 | }; 45 | void carrier::Input_pos(int i, double input){ 46 | position[i]=input; 47 | }; 48 | void carrier::Input_Egy(int i, double input){ 49 | Egy[i]=input; 50 | }; 51 | void carrier::Input_kxy(int i, double input){ 52 | kxy[i]=input; 53 | }; 54 | void carrier::Input_scattering(int i, int input){ 55 | scattering[i]=input; 56 | }; 57 | void carrier::Input_kz(int i, double input){ 58 | kz[i]=input; 59 | }; 60 | double carrier::Get_pos(int i){ 61 | return position[i]; 62 | }; 63 | double carrier::Get_Egy(int i){ 64 | return Egy[i]; 65 | }; 66 | double carrier::Get_kxy(int i){ 67 | return kxy[i]; 68 | }; 69 | double carrier::Get_kz(int i){ 70 | return kz[i]; 71 | }; 72 | int carrier::Get_scattering(int i){ 73 | return scattering[i]; 74 | }; 75 | carrier::~carrier(){ 76 | }; 77 | void carrier::Input_time(int i, double input){ 78 | time[i]=input; 79 | }; 80 | double carrier::Get_time(int i){ 81 | return time[i]; 82 | }; 83 | void carrier::Input_dt(int i, double input){ 84 | dt[i]=input; 85 | }; 86 | double carrier::Get_dt(int i){ 87 | return dt[i]; 88 | }; 89 | void carrier::Input_dx(int i, double input){ 90 | dx[i]=input; 91 | }; 92 | double carrier::Get_dx(int i){ 93 | return dx[i]; 94 | }; 95 | // Resets all the arrays to 0. 96 | void carrier::reset(){ 97 | int i; 98 | for(i=1; i<(Array+1); i++) 99 | { position[i]=0; 100 | Egy[i]=0; 101 | kxy[i]=0; 102 | kz[i]=0; 103 | scattering[i]=0; 104 | dt[i]=0; 105 | dx[i]=0; 106 | time[i]=0; 107 | timearray[i]=0;} 108 | }; 109 | void carrier::Input_timearray(int i, int input){ 110 | timearray[i]=input; 111 | }; 112 | int carrier::Get_timearray(int i){ 113 | return timearray[i]; 114 | }; 115 | 116 | //Calculates the new scattering direction and momenta 117 | void carrier::scatter(int i, int j){ 118 | double cos_theta,kf; 119 | if (j==0 ) kf=2*(emass)*Egy[i]/((hbar)*(hbar)); 120 | else kf=2*(hmass)*Egy[i]/((hbar)*(hbar)); 121 | if(kf>=0) { 122 | cos_theta=2*genrand()-1; 123 | kz[i]=cos_theta*sqrt(kf); 124 | kxy[i]=kf*(1-cos_theta*cos_theta); 125 | } 126 | }; 127 | //Generates a new carrier after an impact ionization event 128 | void carrier::generation(int i, double z_pos, double Energy, double timein, double dtin, int timearrayin){ 129 | position[i]=z_pos; 130 | Egy[i]=Energy; 131 | time[i]=timein; 132 | dt[i]=dtin; 133 | timearray[i]=timearrayin; 134 | }; 135 | -------------------------------------------------------------------------------- /src/dev_prop_func.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright 2017 Advanced Detector Centre, Department of Electronic and 2 | Electrical Engineering, University of Sheffield, UK. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License.*/ 15 | 16 | /* 17 | dev_prop_func.cpp contains the function definitions for functions that are uniqe to the device_properties mode 18 | in device_properties.cpp 19 | 20 | functions are prototypes in dev_prop_func.h 21 | Uses the class histogram in postprocess() 22 | Jonathan Petticrew, University of Sheffield, 2017. 23 | */ 24 | 25 | #include "dev_prop_func.h" 26 | #include "histogram.h" 27 | #include 28 | #include 29 | #include 30 | 31 | //Counts the Number of Bias in bias_input.txt 32 | int biascounter(){ 33 | double voltage; 34 | FILE *bias; 35 | if ((bias=fopen("bias_input.txt","r"))==NULL) 36 | { printf("Error: bias_input.txt can't be opened'\n");} 37 | int bias_count=0; 38 | while(fscanf(bias,"%lf",&voltage)>0) { 39 | bias_count++; 40 | } 41 | fclose(bias); 42 | return bias_count; 43 | }; 44 | 45 | //Reads in User inout 46 | int timesliceread(){ 47 | int timeslice; 48 | printf("How many divisions per transit time: \n"); 49 | scanf("%d",×lice); 50 | return timeslice; 51 | }; 52 | //Reads in User inout 53 | int usDeviceread(){ 54 | int usDevice; 55 | printf("1)Pure Electron, 2)Pure Hole:\n"); 56 | scanf("%d",&usDevice); 57 | return usDevice; 58 | }; 59 | //Reads in User inout 60 | double simulationtimeread(){ 61 | double simulationtime; 62 | printf("Simulation Time in ps:\n"); 63 | scanf("%lf",&simulationtime); 64 | simulationtime=simulationtime*1e-12; 65 | return simulationtime; 66 | }; 67 | //Reads in User inout 68 | int trialsread(){ 69 | int Ntrials; 70 | printf("Number of trials (Default=10000):\n"); 71 | scanf("%d", &Ntrials); 72 | return Ntrials; 73 | }; 74 | 75 | //Calculates Gain, Noise, Mean Time (using 0.1ps bin width) 76 | void postprocess(double Vsim[],double simtime, int voltages){ 77 | int numbins=(int)(simtime/0.1e-12); 78 | int i; 79 | double *G = new double[voltages]; 80 | double *F = new double[voltages]; 81 | double *T = new double[voltages]; 82 | FILE *results; 83 | results=fopen("Result_2.txt","w"); 84 | fprintf(results,"Voltage Gain Noise MeanTime(ps)\n"); 85 | for(i=0; i0) { 102 | //scanned=scanned/1.6e-19; 103 | TGain+=scanned; 104 | Gain2+=scanned*scanned; 105 | count++; 106 | } 107 | G[i]=TGain/count; 108 | mgain2=Gain2/count; 109 | F[i]=mgain2/(G[i]*G[i]); 110 | fclose(Mout); 111 | FILE *Tout; 112 | char nameT[]= "time_to_breakdown.txt"; 113 | int fileT_len = strlen(voltagetb) + strlen(nameT) + 1; 114 | char *fileT =new char[fileT_len]; 115 | snprintf(fileT,fileT_len,"%s%s",voltagetb,nameT); 116 | if((Tout=fopen(fileT,"r"))!=NULL) { 117 | count=0; 118 | int dump; 119 | double dump2; 120 | while(fscanf(Tout,"%d %lf\n",&dump,&dump2)>0) { 121 | count++; 122 | } 123 | if(count>0) { 124 | double *data = new double[count]; 125 | data = { 0 }; 126 | rewind(Tout); 127 | count=0; 128 | while(fscanf(Tout,"%d %lf\n",&dump,&dump2)>0) { 129 | data[count]=dump2/1e-12; 130 | count++; 131 | } 132 | fclose(Tout); 133 | delete[] data; 134 | char nameH[]="Hist.txt"; 135 | int fileH_len = strlen(voltagetb) + strlen(nameH) + 1; 136 | char *fileH = new char[fileH_len]; 137 | snprintf(fileH, fileH_len,"%s%s",voltagetb,nameH); 138 | histogram hist(data,count,0.1,fileH); 139 | delete[] fileH; 140 | T[i]=hist.Get_Mean(); 141 | fprintf(results,"%lf %lf %lf %lf\n",Vsim[i],G[i],F[i],T[i]); 142 | } 143 | else{ 144 | fclose(Tout); 145 | fprintf(results,"%lf %lf %lf --\n",Vsim[i],G[i],F[i]); 146 | } 147 | } 148 | else fprintf(results,"%lf %lf %lf --\n",Vsim[i],G[i],F[i]); 149 | delete[] fileT; 150 | } 151 | fclose(results); 152 | delete[] G,F,T; 153 | }; 154 | -------------------------------------------------------------------------------- /src/tools_class.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright 2017 Advanced Detector Centre, Department of Electronic and 2 | Electrical Engineering, University of Sheffield, UK. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License.*/ 15 | 16 | /* 17 | tools_class.cpp contains the class implimentation of the tools class for the SMC 18 | The tools class calculates the scattering rates and probabilities for the SMC 19 | 20 | tools.h contains the class definition 21 | 22 | Jonathan Petticrew, University of Sheffield, 2017. 23 | */ 24 | 25 | #include "tools.h" 26 | #include 27 | #include 28 | #include 29 | //Constructs and zeros the probability arrays 30 | tools::tools(SMC *input) : constants(input){ 31 | int i,j; 32 | for (i=0; iGet_NUMPOINTS(); 48 | rtotal=pb[0][x]+pb[1][x]+pb[2][x]; //rtotal is the total interaction rate for electrons at the Max energy declaired in class SMC 49 | rtotal2=pb2[0][x]+pb2[1][x]+pb2[2][x]; //rtotal 2 is similar for holes 50 | 51 | if ((fp_rate=fopen("scattering_rates.txt","w"))==NULL) 52 | { printf("Cannot oen file \"scattering_rates.txt\"\n"); 53 | ratefail=true;} 54 | if ((fp_pb=fopen("scattering_pb.txt","w"))==NULL) 55 | { printf("Cannot oen file \"scattering_pb.txt\"\n"); 56 | pbfail=true;} 57 | if(ratefail||pbfail) 58 | { printf("Output files could not be opened. Would you like to continue (y/n)\n"); 59 | do 60 | {inputkey=_getch();} 61 | while(inputkey!='y' && inputkey!='Y' && inputkey!='n' && inputkey!='N'); 62 | if (inputkey=='y' || inputkey=='Y') 63 | GoAhead=2; 64 | else GoAhead=0; } 65 | /****CHANGES THE RATES INTO PROBABILITIES****/ 66 | if (GoAhead) 67 | { for(j=0; j<=x; j++) 68 | { 69 | if(!ratefail) 70 | fprintf(fp_rate,"%f, %e, %e, %e, %e, %e, %e\n",j*0.001,pb[0][j],pb[1][j],pb[2][j],pb2[0][j],pb2[1][j],pb2[2][j]); 71 | pb[0][j]= pb[0][j]/rtotal; 72 | pb[1][j]=pb[0][j]+pb[1][j]/rtotal; 73 | pb[2][j]=pb[1][j]+pb[2][j]/rtotal; 74 | pb2[0][j]= pb2[0][j]/rtotal2; 75 | pb2[1][j]=pb2[0][j]+pb2[1][j]/rtotal2; 76 | pb2[2][j]=pb2[1][j]+pb2[2][j]/rtotal2; 77 | if(!pbfail) 78 | fprintf(fp_pb,"j=%d, %e, %e, %e, %e, %e, %e\n",j,pb[0][j],pb[1][j],pb[2][j],pb2[0][j],pb2[1][j],pb2[2][j]); 79 | }} 80 | if(!ratefail) fclose(fp_rate); 81 | if(!pbfail) fclose(fp_pb); 82 | return(GoAhead); 83 | // returns 0 for no output and user wants to quit 84 | //returns 1 if everything ok 85 | //returns 2 if no output but user wants to continue 86 | }; 87 | 88 | //calculates the electron scattering rates 89 | void tools::e_rate(){ 90 | int i; 91 | double n; 92 | double Egap; 93 | double x,x1; 94 | double e_para, e_para2; 95 | e_para=constants->Get_N()/(constants->Get_e_meanpath()*(2*constants->Get_N()+1)); 96 | e_para2=(constants->Get_N()+1)/(constants->Get_e_meanpath()*(2*constants->Get_N()+1)); 97 | int j = constants->Get_NUMPOINTS(); 98 | 99 | for (i=0; i<=j; i++) 100 | { n=i*constants->Get_q()*0.001; 101 | Egap=(n-constants->Get_e_Eth())/(constants->Get_e_Eth()); 102 | pb[0][i]=e_para*sqrt((2*(n+constants->Get_hw()))/constants->Get_e_mass());//rate of phonon absorption 103 | 104 | if (n>constants->Get_hw()) 105 | pb[1][i]=e_para2*sqrt((2*(n-constants->Get_hw()))/constants->Get_e_mass()); //rate of phonon emission 106 | else pb[1][i]=0; 107 | 108 | if (Egap>0) 109 | { x=my_pow(Egap,constants->Get_e_gamma()); 110 | x1=constants->Get_e_Cii(); 111 | pb[2][i]=x*constants->Get_e_Cii(); //rate of impact ionization 112 | } 113 | else pb[2][i]=0; } 114 | }; 115 | //calculates the hole scattering rates 116 | void tools::h_rate(){ 117 | int i; 118 | double n; 119 | double Egap; 120 | double h_para, h_para2; 121 | double x2,x1; 122 | h_para=constants->Get_N()/(constants->Get_h_meanpath()*(2*constants->Get_N()+1)); 123 | h_para2=(constants->Get_N()+1)/(constants->Get_h_meanpath()*(2*constants->Get_N()+1)); 124 | int x=constants->Get_NUMPOINTS(); 125 | for (i=0; i<=x; i++) 126 | { n=i*constants->Get_q()*0.001; 127 | Egap=(n-constants->Get_h_Eth())/(constants->Get_h_Eth()); 128 | pb2[0][i]=h_para*sqrt((2*(n+constants->Get_hw()))/constants->Get_h_mass());//rate of phonon absorption 129 | 130 | if (n>constants->Get_hw()) 131 | pb2[1][i]=h_para2*sqrt((2*(n-constants->Get_hw()))/constants->Get_h_mass()); //rate of phonon emission 132 | else pb2[1][i]=0; 133 | 134 | if (Egap>0) 135 | { x2=my_pow(Egap,constants->Get_h_gamma()); 136 | x1=constants->Get_h_Cii(); 137 | pb2[2][i]=x1*x2; //rate of impact ionization 138 | } 139 | else pb2[2][i]=0; } 140 | }; 141 | 142 | //Get scattering rate of electrons total 143 | double tools::Get_rtotal(){ 144 | return rtotal; 145 | }; 146 | //Pb get function electrons 147 | double tools::Get_pb(int i, int j){ 148 | return pb[i][j]; 149 | }; 150 | //Get scattering rate of holes total 151 | double tools::Get_rtotal2(){ 152 | return rtotal2; 153 | }; 154 | //Pb get function holes 155 | double tools::Get_pb2(int i, int j){ 156 | return pb2[i][j]; 157 | }; 158 | /*my_pow is used to fix a bug with the pow function in my compiler. My compiler TDM-GCC 4.9.2 has an over 159 | accuracy problem with the pow function, if the value is not stored straight away it might return a 160 | different value.*/ 161 | double tools::my_pow(double base, double exponent) 162 | { 163 | double output=pow(base,exponent); 164 | return output; 165 | }; 166 | -------------------------------------------------------------------------------- /src/histogram_class.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright 2017 Advanced Detector Centre, Department of Electronic and 2 | Electrical Engineering, University of Sheffield, UK. 3 | 4 | Modifications Copyright 2017, Advanced Detector Centre, Department of Electronic and 5 | Electrical Engineering, University of Sheffield, UK. 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License.*/ 18 | 19 | /* 20 | histogram_class.cpp contains the function declarations for the Gaussian Histogram Fitter 21 | See histogram.h for the class definition 22 | 1) histogram(double* data, int size); 23 | Pass the 1d data array and the number of elements it contains. 24 | The class will ask for a user input for histogram bin width and output the histgram data and fit to Hist.txt 25 | 2) histogram(double* data, int size, double binsize); 26 | Pass the 1d data array, the number of elements the array contains, and the histogram bin width. 27 | The class will output the histgram data and fit to Hist.txt 28 | 3) histogram(double* data, int size, char* fname); 29 | Pass the 1d data array, the number of elements the array contains, and a file name to output the data and fit. 30 | The class will ask for a user input for histogram bin width and output the fit and data to the passed file name. 31 | 4) histogram(double* data, int size, double binsize, char* fname); 32 | Pass the 1d data array, the number of elements the array contains, the histogram bin width, and a file name to output the data and fit. 33 | The class will utput the fit and data to the passed file name. 34 | 35 | Jonathan Petticrew, University of Sheffield, 2017. 36 | */ 37 | #include "histogram.h" 38 | #include 39 | #include 40 | #include 41 | 42 | //constructor for histogram class Ask for Bin Size 43 | histogram::histogram(double* data, int size) : size(size){ 44 | dataset = new double[size]; 45 | int i; 46 | for(i=0; imax) max=dataset[i]; 126 | else if(dataset[i]=binEdges[i] && dataset[j] 40 | #include 41 | 42 | void drift_velocity(int material){ 43 | SMC constants; //SMC parameter set 44 | constants.mat(material); //Tells SMC parameter set which material 45 | SMC *pointSMC = &constants; //Used to pass constants to other classes. 46 | double minEfield, maxEfield; 47 | printf(" Minimum Electric Field (kV/cm):\n"); 48 | scanf("%lf",&minEfield); 49 | printf(" Maximum Electric Field (kV/cm):\n"); 50 | scanf("%lf",&maxEfield); 51 | tools simulation(pointSMC); 52 | simulation.scattering_probability();//this function returns 0 if no output can be generated and the user wants to quit 53 | sgenrand(4358);//seeds the random number generator constant used to alow for comparison using different parameters. 54 | double Esim,Eloop,z_pos,kf,kxy,kz,cos_theta,Energy; 55 | int tn; 56 | int scat_e=0; 57 | FILE *epdf; 58 | FILE *hpdf; 59 | epdf=fopen("evelocity.txt","w"); 60 | hpdf=fopen("hvelocity.txt","w"); 61 | for(Esim=minEfield; Esim<=maxEfield; Esim+=1) { 62 | 63 | Eloop=Esim*1e5;//change elecric field from kV/cm to V/m. 64 | z_pos=0; 65 | Energy=0; 66 | kf=0; //Kf^2=Kx^2+Ky^2+Kz^2 67 | kxy=0; // combined momentum tangential to travel direction. 68 | kz=0; // z momentum (direction of travel) 69 | cos_theta=0; //scattering angle 70 | tn=0; 71 | double drift_t=0; 72 | double dE=0; 73 | int counter=0; 74 | double vtotal=0; 75 | //electrons 76 | for(counter=0; counter<1000000; counter++) { //loop for 1000000 scattering events 77 | if(scat_e==0) { 78 | double cos_theta; 79 | kf=2*constants.Get_e_mass()*Energy/(constants.Get_hbar()*constants.Get_hbar()); 80 | if(kf>=0) { 81 | cos_theta=2*genrand()-1; 82 | kz=cos_theta*sqrt(kf); 83 | kxy=kf*(1-cos_theta*cos_theta); 84 | } 85 | } 86 | //electron drift process starts 87 | double random1; 88 | random1=genrand(); 89 | drift_t= -log(random1)/(simulation.Get_rtotal()); 90 | kz+=(constants.Get_q()*drift_t*Eloop)/(constants.Get_hbar()); 91 | dE=((constants.Get_hbar()*constants.Get_hbar())/(2*constants.Get_e_mass()))*(kxy+kz*kz)-Energy; 92 | Energy=((constants.Get_hbar()*constants.Get_hbar())/(2*constants.Get_e_mass()))*(kxy+kz*kz); 93 | z_pos+=dE/(constants.Get_q()*Eloop); 94 | //electron drift process ends 95 | double velocity = dE/(constants.Get_q()*Eloop*drift_t); 96 | vtotal += (velocity); 97 | // electron scattering process starts 98 | double random2; 99 | int Eint; 100 | Eint=(int)floor(Energy*1000.0/constants.Get_q()+0.5); 101 | if (Energy>constants.Get_Emax()) { 102 | Eint= constants.Get_NUMPOINTS(); 103 | random2=simulation.Get_pb(2,constants.Get_NUMPOINTS()); 104 | } 105 | else if (Energy == constants.Get_Emax()) random2=simulation.Get_pb(2,constants.Get_NUMPOINTS()); 106 | else random2=genrand(); 107 | 108 | if(random2<=simulation.Get_pb(0,Eint)) //phonon absorption 109 | { Energy+=constants.Get_hw(); 110 | scat_e=0;} 111 | else if(random2<=simulation.Get_pb(1,Eint)) //phonon emission 112 | { Energy-=constants.Get_hw(); 113 | scat_e=0;} 114 | else if(random2<=simulation.Get_pb(2,Eint)) //impact ionization 115 | { Energy=(Energy-constants.Get_e_Eth())/3.0; 116 | tn++; 117 | scat_e=0; 118 | 119 | z_pos=0;} 120 | else if(random2>simulation.Get_pb(2,Eint)) //selfscattering 121 | { scat_e=1;} 122 | //electron scattering process ends 123 | 124 | } 125 | double vmean=vtotal/counter; 126 | fprintf(epdf,"%g %g\n", Esim, vmean); 127 | 128 | z_pos=0; 129 | Energy=0; 130 | kf=0; 131 | kxy=0; 132 | kz=0; 133 | cos_theta=0; 134 | tn=0; 135 | drift_t=0; 136 | dE=0; 137 | double vtotalh=0; 138 | //holes 139 | for(counter=0; counter<1000000; counter++) { 140 | if(scat_e==0) { 141 | double cos_theta; 142 | kf=2*constants.Get_h_mass()*Energy/(constants.Get_hbar()*constants.Get_hbar()); 143 | if(kf>=0) { 144 | cos_theta=2*genrand()-1; 145 | kz=cos_theta*sqrt(kf); 146 | kxy=kf*(1-cos_theta*cos_theta); 147 | } 148 | } 149 | //hole drift process starts 150 | double random11; 151 | random11=genrand(); 152 | drift_t= -log(random11)/simulation.Get_rtotal2(); 153 | kz-=((constants.Get_q()*drift_t*Eloop)/(constants.Get_hbar())); 154 | dE=((constants.Get_hbar()*constants.Get_hbar())/(2*constants.Get_h_mass()))*(kxy+kz*kz)-Energy; 155 | Energy=((constants.Get_hbar()*constants.Get_hbar())/(2*constants.Get_h_mass()))*(kxy+kz*kz); 156 | z_pos-=dE/(Eloop*constants.Get_q()); 157 | //hole drift process ends 158 | double velocity = dE/(Eloop*constants.Get_q()*drift_t); 159 | vtotalh+= (velocity); 160 | double random22; 161 | int Eint2; 162 | Eint2=(int)floor(Energy*1000.0/constants.Get_q()+0.5); 163 | if (Energy>constants.Get_Emax()) { 164 | Eint2= constants.Get_NUMPOINTS(); 165 | random22=simulation.Get_pb2(2,constants.Get_NUMPOINTS()); 166 | } 167 | else if (Energy == constants.Get_Emax()) random22=simulation.Get_pb2(2,constants.Get_NUMPOINTS()); 168 | else random22=genrand(); 169 | 170 | if(random22<=simulation.Get_pb2(0,Eint2)) //phonon absorption 171 | { Energy+=constants.Get_hw(); 172 | scat_e=0;} 173 | else if(random22<=simulation.Get_pb2(1,Eint2)) //phonon emission 174 | { Energy-=constants.Get_hw(); 175 | scat_e=0;} 176 | else if(random22<=simulation.Get_pb2(2,Eint2)) //impact ionization 177 | { Energy=(Energy-constants.Get_h_Eth())/3.0; 178 | tn++; 179 | scat_e=0; 180 | 181 | z_pos=0;} 182 | else if(random22>simulation.Get_pb2(2,Eint2)) //selfscattering 183 | { scat_e=1;} 184 | //electron scattering process ends 185 | 186 | } 187 | vmean=vtotalh/counter; 188 | fprintf(hpdf,"%g %g\n", Esim, vmean); 189 | 190 | } 191 | fclose(epdf); 192 | fclose(hpdf); 193 | } 194 | -------------------------------------------------------------------------------- /src/device_class.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright 2017 Advanced Detector Centre, Department of Electronic and 2 | Electrical Engineering, University of Sheffield, UK. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License.*/ 15 | 16 | /* 17 | device_class.cpp contains the class definition of the device class for the SMC. 18 | 19 | The device class contains a Poisson solver and a linear interpolater to claculate the 20 | electric field properties of semiconductor devices. 21 | 22 | device.cpp contains the class implimentation 23 | 24 | Jonathan Petticrew, University of Sheffield, 2017. 25 | */ 26 | 27 | #include "device.h" 28 | #include 29 | #include 30 | #include 31 | //Constructor, sets a few variables and calls read() to read in and populate the doping profile. 32 | //PUBLIC 33 | device::device(SMC *input) : constants(input){ 34 | q=constants->Get_q(); 35 | Vbi=constants->Get_Vbi(); 36 | double d1=constants->Get_die(); 37 | die=d1*8.85e-12; 38 | read(); 39 | }; 40 | 41 | //Efield_at_x returns the electric field to main for a given xposition inside 42 | //the electric field profile. If outside the electric field profile it will return 0. 43 | //PUBLIC 44 | double device::Efield_at_x(double xpos){ 45 | double Field; 46 | 47 | int i,j; 48 | for(i=i_min; i=efield_x[i]) 51 | { 52 | j=i+1; 53 | if(xpos0) { 98 | ++NumLayers; 99 | } 100 | fclose(doping); 101 | efield_x= new double[NumLayers+1]; 102 | efield_e=new double[NumLayers+1]; 103 | int i; 104 | for(i=0; i0) { 138 | pn=pn-1; 139 | } 140 | else { 141 | printf("ERROR, stepped back outside 1st region\n"); 142 | } 143 | } 144 | for(i=0; i<(NumLayers+1); i++) { 145 | efield_x[i]=0; 146 | efield_e[i]=0; 147 | } 148 | if (err==0) { 149 | efield_x[pn+1]=w[pn]; 150 | } else { 151 | efield_x[pn+1]=xold; 152 | } 153 | efield_e[pn+1]=efield_x[pn+1]*q*N[pn]/die; 154 | j=pn+1; 155 | depleted=0; 156 | err=0; 157 | while (depleted==0 && err==0) { 158 | ereg=efield_e[j]+q*N[j]*w[j]/die; 159 | if (ereg*efield_e[j]>0) { 160 | efield_e[j+1]=ereg; 161 | efield_x[j+1]=efield_x[j]+w[j]; 162 | j++; 163 | if (j>NumLayers-1) { 164 | err=1; 165 | xold=efield_x[pn+1]/2; 166 | } 167 | } 168 | else{ 169 | efield_e[j+1]=0; 170 | efield_x[j+1]=efield_x[j]+fabs((0-efield_e[j])/((efield_e[j]-ereg)/w[j])); 171 | depleted=1; 172 | } 173 | } 174 | 175 | if (err==0) { 176 | Vsum=0; 177 | for(i=0; ivoltage) { 196 | if (firstloop==0) { 197 | xold=xtest; 198 | xtest=xtest/2.0; 199 | firstloop=1; 200 | } else { 201 | xoldest=xold; 202 | xold=xtest; 203 | xtest=xold-fabs((xoldest-xold)/2); 204 | } 205 | } else { 206 | if (firstloop==0) { 207 | xold=xtest; 208 | xtest=3*xtest/2.0; 209 | firstloop=1; 210 | } else { 211 | xoldest=xold; 212 | xold=xtest; 213 | xtest=xold+fabs((xoldest-xold)/2); 214 | } 215 | } 216 | efield_x[pn+1]=xtest; 217 | efield_e[pn+1]=xtest*q*N[pn]/die; 218 | int j=pn+1; 219 | depleted=0; 220 | while (depleted==0) { 221 | ereg=efield_e[j]+q*N[j]*w[j]/die; 222 | if (ereg*efield_e[j]>0) { 223 | efield_e[j+1]=ereg; 224 | efield_x[j+1]=efield_x[j]+w[j]; 225 | j++; 226 | if (j>NumLayers) { 227 | printf("Error in field solver\n"); 228 | } 229 | } 230 | else{ 231 | efield_e[j+1]=0; 232 | efield_x[j+1]=efield_x[j]+fabs((0-efield_e[j])/((efield_e[j]-ereg)/w[j])); 233 | depleted=1; 234 | endpoint=j+1; 235 | } 236 | } 237 | Vsum=0; 238 | for(i=0; i-1; i--) { 258 | efield_x[i]=efield_x[pn]; 259 | } 260 | for(i=endpoint+1; i 39 | #include 40 | #include 41 | 42 | void ii_coef(int material){ 43 | SMC constants; //SMC parameter set 44 | constants.mat(material); //Tells SMC parameter set which material 45 | SMC *pointSMC = &constants; //Used to pass constants to other classes. 46 | double minEfield, maxEfield, stepEfield; 47 | printf(" Minimum Electric Field (kV/cm):\n"); 48 | scanf("%lf",&minEfield); 49 | printf(" Maximum Electric Field (kV/cm):\n"); 50 | scanf("%lf",&maxEfield); 51 | printf("Electric Field Step Size (kV/cm):\n"); 52 | scanf("%lf",&stepEfield); 53 | tools simulation(pointSMC); 54 | simulation.scattering_probability();//this function returns 0 if no output can be generated and the user wants to quit 55 | sgenrand(4358);//seeds the random number generator constant used to alow for comparison using different parameters. 56 | double Esim,Eloop,z_pos,kf,kxy,kz,cos_theta,Energy; 57 | int tn; 58 | int scat_e=0; 59 | FILE *about; 60 | about=fopen("alpha_beta.txt","w"); 61 | fprintf(about,"Efield (kV/cm), Alpha (1/m), Beta (1/m)\n"); 62 | 63 | /*** EFIELD LOOP STARTS HERE ***/ 64 | for(Esim=minEfield; Esim<=maxEfield; Esim+=stepEfield) { 65 | //Generate the output files for the electric field 66 | FILE *epdf; 67 | FILE *hpdf; 68 | char ename[] = "epdf.txt"; 69 | char hname[] = "hpdf.txt"; 70 | char Eprint[5]; 71 | snprintf(Eprint,sizeof(Eprint),"%g",Esim); 72 | int efile_len = strlen(ename) + strlen(Eprint) + 1; 73 | char* efile = new char[efile_len]; 74 | int hfile_len = strlen(hname) + strlen(Eprint) + 1; 75 | char* hfile = new char[hfile_len]; 76 | snprintf(efile,efile_len,"%s%s",Eprint,ename); 77 | snprintf(hfile,hfile_len,"%s%s",Eprint,hname); 78 | epdf=fopen(efile,"w"); 79 | hpdf=fopen(hfile,"w"); 80 | delete[] efile, hfile; 81 | //Reset variables to 0. 82 | Eloop=Esim*1e5; //change elecric field from kV/cm to V/m. 83 | z_pos=0; 84 | Energy=0; 85 | kf=0; //Kf^2=Kx^2+Ky^2+Kz^2 86 | kxy=0;// combined momentum tangential to travel direction. 87 | kz=0; // z momentum (direction of travel) 88 | cos_theta=0; //scattering angle 89 | tn=0; //impact ionization counter 90 | double drift_t=0; 91 | double dE=0; 92 | double alpha_distance=0; 93 | double beta_distance=0; 94 | 95 | //electrons 96 | while(tn<20000) { //loops for 20000 electron impact ionization events. 97 | if(scat_e==0) { 98 | double cos_theta; 99 | kf=2*constants.Get_e_mass()*Energy/(constants.Get_hbar()*constants.Get_hbar()); 100 | if(kf>=0) { 101 | cos_theta=2*genrand()-1; 102 | kz=cos_theta*sqrt(kf); 103 | kxy=kf*(1-cos_theta*cos_theta); 104 | } 105 | } 106 | //electron drift process starts 107 | double random1; 108 | random1=genrand(); 109 | drift_t= -log(random1)/(simulation.Get_rtotal()); 110 | kz+=(constants.Get_q()*drift_t*Eloop)/(constants.Get_hbar()); 111 | dE=((constants.Get_hbar()*constants.Get_hbar())/(2*constants.Get_e_mass()))*(kxy+kz*kz)-Energy; 112 | Energy=((constants.Get_hbar()*constants.Get_hbar())/(2*constants.Get_e_mass()))*(kxy+kz*kz); 113 | z_pos+=dE/(constants.Get_q()*Eloop); 114 | //electron drift process ends 115 | 116 | //electron scattering process starts 117 | double random2; 118 | int Eint; 119 | Eint=(int)floor(Energy*1000.0/constants.Get_q()+0.5); //bins energy to compare against probability curves from tools class. 120 | if (Energy>constants.Get_Emax()) { 121 | Eint= constants.Get_NUMPOINTS(); 122 | random2=simulation.Get_pb(2,constants.Get_NUMPOINTS()); 123 | } 124 | else if (Energy == constants.Get_Emax()) random2=simulation.Get_pb(2,constants.Get_NUMPOINTS()); 125 | else random2=genrand(); 126 | 127 | if(random2<=simulation.Get_pb(0,Eint)) //phonon absorption 128 | { Energy+=constants.Get_hw(); 129 | scat_e=0;} 130 | else if(random2<=simulation.Get_pb(1,Eint)) //phonon emission 131 | { Energy-=constants.Get_hw(); 132 | scat_e=0;} 133 | else if(random2<=simulation.Get_pb(2,Eint)) //impact ionization 134 | { Energy=(Energy-constants.Get_e_Eth())/3.0; 135 | tn++; 136 | scat_e=0; 137 | fprintf(epdf,"%d %e\n", tn, z_pos); 138 | alpha_distance+=z_pos; 139 | z_pos=0;} 140 | else if(random2>simulation.Get_pb(2,Eint)) //selfscattering 141 | { scat_e=1;} 142 | //electron scattering process ends 143 | 144 | } 145 | 146 | //reset variables to 0 147 | z_pos=0; 148 | Energy=0; 149 | kf=0; 150 | kxy=0; 151 | kz=0; 152 | cos_theta=0; 153 | tn=0; 154 | drift_t=0; 155 | dE=0; 156 | 157 | //holes 158 | while(tn<20000) {// loops for 20000 impact ionization events for holes. 159 | if(scat_e==0) { 160 | double cos_theta; 161 | kf=2*constants.Get_h_mass()*Energy/(constants.Get_hbar()*constants.Get_hbar()); 162 | if(kf>=0) { 163 | cos_theta=2*genrand()-1; 164 | kz=cos_theta*sqrt(kf); 165 | kxy=kf*(1-cos_theta*cos_theta); 166 | } 167 | } 168 | //hole drift process starts 169 | double random11; 170 | random11=genrand(); 171 | drift_t= -log(random11)/simulation.Get_rtotal2(); 172 | kz-=((constants.Get_q()*drift_t*Eloop)/(constants.Get_hbar())); 173 | dE=((constants.Get_hbar()*constants.Get_hbar())/(2*constants.Get_h_mass()))*(kxy+kz*kz)-Energy; 174 | Energy=((constants.Get_hbar()*constants.Get_hbar())/(2*constants.Get_h_mass()))*(kxy+kz*kz); 175 | z_pos-=dE/(Eloop*constants.Get_q()); 176 | //hole drift process ends 177 | 178 | // hole scattering process starts 179 | double random22; 180 | int Eint2; 181 | Eint2=(int)floor(Energy*1000.0/constants.Get_q()+0.5); 182 | if (Energy>constants.Get_Emax()) { 183 | Eint2= constants.Get_NUMPOINTS(); 184 | random22=simulation.Get_pb2(2,constants.Get_NUMPOINTS()); 185 | } 186 | else if (Energy == constants.Get_Emax()) random22=simulation.Get_pb2(2,constants.Get_NUMPOINTS()); 187 | else random22=genrand(); 188 | 189 | if(random22<=simulation.Get_pb2(0,Eint2)) //phonon absorption 190 | { Energy+=constants.Get_hw(); 191 | scat_e=0;} 192 | else if(random22<=simulation.Get_pb2(1,Eint2)) //phonon emission 193 | { Energy-=constants.Get_hw(); 194 | scat_e=0;} 195 | else if(random22<=simulation.Get_pb2(2,Eint2)) //impact ionization 196 | { Energy=(Energy-constants.Get_h_Eth())/3.0; 197 | tn++; 198 | scat_e=0; 199 | fprintf(hpdf,"%d %e\n", tn, -z_pos); 200 | beta_distance-=z_pos; 201 | z_pos=0;} 202 | else if(random22>simulation.Get_pb2(2,Eint2)) //selfscattering 203 | { scat_e=1;} 204 | //hole scattering process ends 205 | 206 | } 207 | 208 | fclose(epdf); 209 | fclose(hpdf); 210 | // convert distance travelled to alpha, beta and output to file. 211 | double alpha=tn/alpha_distance; 212 | double beta=tn/beta_distance; 213 | fprintf(about, "%lf %e %e\n", Esim, alpha, beta); 214 | } 215 | fclose(about); 216 | } 217 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. -------------------------------------------------------------------------------- /src/device_properties.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright 2017 Advanced Detector Centre, Department of Electronic and 2 | Electrical Engineering, University of Sheffield, UK. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License.*/ 15 | 16 | /* 17 | device_properties.cpp contains device_properties() which calculates the device properties for a given device in a given material. 18 | 19 | Takes user input for divisions per transit time, injection condition, simulation time and number of trials. 20 | Takes material input from main.cpp 21 | Reads in applied biasses from the user generated file bias_input.txt 22 | Uses the read in device structure from the user generated file doping_profile.txt contained in the device class. 23 | 24 | Uses the Classes SMC, Carrier, Device & tools. 25 | Also uses functions.h which contains common functions used in all three modes. 26 | Also uses dev_prop_func.h which contains functions unique to the device properties mode. 27 | 28 | Prototyped in model.h 29 | 30 | Calculates Gain, Excess Noise Factor, Breakdown Probability and Timing Statistics. 31 | 32 | Jonathan Petticrew, University of Sheffield, 2017. 33 | */ 34 | 35 | #include "model.h" 36 | #include "SMC.h" 37 | #include "device.h" 38 | #include "functions.h" 39 | #include "dev_prop_func.h" 40 | #include "tools.h" 41 | #include "carrier.h" 42 | #include 43 | #include 44 | #include 45 | 46 | void device_properties(int material){ 47 | FILE *userin; 48 | if ((userin=fopen("user_inputs.txt","w"))==NULL)//Opens and error checks 49 | { 50 | printf("Error: user_inputs.txt can't be opened'\n"); 51 | } 52 | if(material == 1) fprintf(userin,"Silicon\n"); 53 | else if(material == 2) fprintf(userin,"Gallium Arsenide\n"); 54 | else if(material ==3) fprintf(userin,"Indium Gallium Phosphide\n"); 55 | int timearray, Highest; 56 | double cumulative, voltage; 57 | SMC constants; //SMC parameter set 58 | constants.mat(material); // tell constants what material to use 59 | SMC *pointSMC = &constants; //Used to pass constants to other classes. 60 | device diode(pointSMC); // Device Class 61 | FILE *out; 62 | double BreakdownCurrent=1e-4; //define the current threshold for avalanche breakdown as 0.1mA 63 | if ((out=fopen("Result_1.txt","w"))==NULL)//Opens and error checks 64 | { printf("Error: Result_1.txt can't open\n");} 65 | 66 | //read in bias 67 | int bias_count=biascounter(); //counts number of voltages to be simulated 68 | FILE *bias; 69 | if ((bias=fopen("bias_input.txt","r"))==NULL)//Opens and error checks 70 | { 71 | printf("Error: bias.txt can't be opened'\n"); 72 | } 73 | 74 | double *V = new double[bias_count]; 75 | bias_count=0; 76 | while(fscanf(bias,"%lf",&voltage)>0) { 77 | V[bias_count]=voltage; 78 | bias_count++; 79 | } 80 | fclose(bias); 81 | 82 | int timeslice = timesliceread(); 83 | fprintf(userin,"Divisions Per Transit time: %d\n", timeslice); 84 | int usDevice = usDeviceread(); 85 | if (usDevice==1) fprintf(userin, "Pure Electron Simulation\n"); 86 | else if (usDevice==2) fprintf(userin, "Pure Hole Simulation\n"); 87 | double simulationtime = simulationtimeread(); 88 | fprintf(userin, "Simulation time limit: %g ps\n",simulationtime/1e-12); 89 | double Ntrials = trialsread(); 90 | fprintf(userin, "Numer of Trials: %lf\n",Ntrials); 91 | fclose(userin); 92 | tools simulation(pointSMC); 93 | simulation.scattering_probability();//this function returns 0 if no output can be generated and the user wants to quit 94 | sgenrand(835800);//seeds the random number generator constant used to alow for comparison using different parameters. 95 | int num; 96 | double Efield,npha,nph,nphe,nii,nsse,Energy,z_pos,dE,kf,kxy,kz,nssh; 97 | double drift_t; 98 | 99 | // create electron and hole classes, too large for stack so have been created with new. 100 | carrier* electron=new carrier(pointSMC); 101 | carrier* hole=new carrier(pointSMC); 102 | 103 | double breakdown, Pbreakdown, Vsim; 104 | /**** BEGIN SIMULATION LOOP VOLTAGE ****/ 105 | int bias_array=0; 106 | printf("%d %d \n", bias_count, bias_array); 107 | for(bias_array=0; bias_arrayInput_pos(1,diode.Get_xmin()+1e-10); 204 | hole->Input_pos(1,-1); 205 | prescent_carriers=1; 206 | } 207 | if (usDevice==2) { 208 | electron->Input_pos(1,(diode.Get_xmax()+1e-10)); 209 | hole->Input_pos(1,(diode.Get_xmax()-1e-10)); 210 | prescent_carriers=1; 211 | } 212 | //carrierlimit is a threshold to end the simulation early 213 | double carrierlimit=BreakdownCurrent*diode.Get_width()/(5*constants.Get_q()*1e5); 214 | 215 | /****TRACKS CARRIERS WHILE IN DIODE****/ 216 | while(prescent_carriers>0 && cut2==0) 217 | { /****LOOPS OVER ALL PAIRS ****/ 218 | for(pair=1; pair<=num_electron; pair++) 219 | { 220 | int flag=0; 221 | // ELECTRON PROCESS 222 | z_pos=electron->Get_pos(pair); 223 | time=electron->Get_time(pair); 224 | dt=electron->Get_dt(pair); 225 | dx=electron->Get_dx(pair); 226 | if(z_posGet_Egy(pair); 233 | if((electron->Get_scattering(pair)==0))//if not selfscattering scatters in random direction 234 | { electron->scatter(pair,0);} 235 | 236 | kxy=electron->Get_kxy(pair); 237 | kz=electron->Get_kz(pair); 238 | 239 | //electron drift process starts 240 | //drifts for a random time 241 | double random1; 242 | random1=genrand(); 243 | drift_t= -log(random1)/(simulation.Get_rtotal()); 244 | time+=drift_t; 245 | dt+=drift_t; 246 | 247 | //updates parameters based on random drift time 248 | Efield=diode.Efield_at_x(z_pos); 249 | kz+=(constants.Get_q()*drift_t*Efield)/(constants.Get_hbar()); 250 | dE=((constants.Get_hbar()*constants.Get_hbar())/(2*constants.Get_e_mass()))*(kxy+kz*kz)-Energy; 251 | Energy=((constants.Get_hbar()*constants.Get_hbar())/(2*constants.Get_e_mass()))*(kxy+kz*kz); 252 | z_pos+=dE/(constants.Get_q()*Efield); 253 | dx+=dE/(constants.Get_q()*Efield); 254 | if(time>cutofftime) { 255 | //cuts off electron and removes it from device if user spec. timelimit exceeded 256 | z_pos=diode.Get_xmax()+10; 257 | cutoff=1; 258 | } 259 | if(dt>=timestep) { 260 | //calc current if time since last calculated >timestep 261 | timearray=(int)floor(time/timestep); 262 | int previous; 263 | previous=electron->Get_timearray(pair); 264 | int test; 265 | for(test=(previous+1); test<(timearray+1); test++) { 266 | //Uses Ramos Theorem Here 267 | I[test]+=constants.Get_q()*dx/(dt*diode.Get_width()); 268 | Inum[test]+=constants.Get_q()*dx/(dt*diode.Get_width()); 269 | } 270 | electron->Input_timearray(pair,timearray); 271 | dt=0; 272 | dx=0; 273 | } 274 | electron->Input_time(pair,time); 275 | electron->Input_dt(pair,dt); 276 | electron->Input_dx(pair,dx); 277 | 278 | //electron drift process ends 279 | 280 | //update electron position and energy 281 | electron->Input_pos(pair,z_pos); 282 | electron->Input_Egy(pair,Energy); 283 | 284 | //electron scattering 285 | if(z_pos<0) z_pos=1e-10; 286 | if((z_pos<=diode.Get_xmax())) 287 | { //electron scattering process starts 288 | double random2; 289 | int Eint; 290 | Eint=(int)floor(Energy*1000.0/constants.Get_q()+0.5); 291 | if (Energy>constants.Get_Emax()) 292 | { Eint= constants.Get_NUMPOINTS(); 293 | random2=simulation.Get_pb(2,constants.Get_NUMPOINTS());} 294 | else if (Energy == constants.Get_Emax()) random2=simulation.Get_pb(2,constants.Get_NUMPOINTS()); 295 | else{ 296 | random2=genrand(); 297 | } 298 | 299 | if(random2<=simulation.Get_pb(0,Eint)) //phonon absorption 300 | { Energy+=constants.Get_hw(); 301 | npha++; 302 | nph++; 303 | electron->Input_scattering(pair,0);} 304 | else if(random2<=simulation.Get_pb(1,Eint)) //phonon emission 305 | { Energy-=constants.Get_hw(); 306 | nphe++; 307 | nph++; 308 | electron->Input_scattering(pair,0);} 309 | else if(random2<=simulation.Get_pb(2,Eint)) //impact ionization 310 | { 311 | Energy=(Energy-constants.Get_e_Eth())/3.0; 312 | num_electron++; 313 | electron->generation(num_electron,z_pos,Energy,time,0,(int)floor(time/timestep)); 314 | num_hole++; 315 | hole->generation(num_hole,z_pos,Energy,time,0,(int)floor(time/timestep)); 316 | tn++; 317 | nii++; 318 | prescent_carriers+=2; 319 | electron->Input_scattering(pair,0); 320 | } 321 | else if(random2>simulation.Get_pb(2,Eint)) //selfscattering 322 | { nsse++; 323 | electron->Input_scattering(pair,1); 324 | electron->Input_kxy(pair,kxy); 325 | electron->Input_kz(pair,kz);} 326 | //electron scattering process ends 327 | 328 | } 329 | else prescent_carriers--; 330 | 331 | electron->Input_Egy(pair,Energy); 332 | if(time>globaltime) flag--; } 333 | 334 | //HOLE PROCESS 335 | z_pos=hole->Get_pos(pair); 336 | time=hole->Get_time(pair); 337 | dt=hole->Get_dt(pair); 338 | dx=hole->Get_dx(pair); 339 | if(z_pos>diode.Get_xmax()) z_pos=diode.Get_xmax()-1e-10; 340 | if(z_pos>=diode.Get_xmin() && timeGet_Egy(pair); 342 | flag++; 343 | if((hole->Get_scattering(pair)==0)) 344 | { hole->scatter(pair,2);} 345 | 346 | kxy=hole->Get_kxy(pair); 347 | kz=hole->Get_kz(pair); 348 | 349 | 350 | //Hole drift starts here 351 | double random11; 352 | random11=genrand(); 353 | drift_t= -log(random11)/simulation.Get_rtotal2(); 354 | time+=drift_t; 355 | dt+=drift_t; 356 | Efield=diode.Efield_at_x(z_pos); 357 | kz-=((constants.Get_q()*drift_t*Efield)/(constants.Get_hbar())); 358 | dE=((constants.Get_hbar()*constants.Get_hbar())/(2*constants.Get_h_mass()))*(kxy+kz*kz)-Energy; 359 | Energy=((constants.Get_hbar()*constants.Get_hbar())/(2*constants.Get_h_mass()))*(kxy+kz*kz); 360 | z_pos-=dE/(Efield*constants.Get_q()); 361 | dx+=dE/(Efield*constants.Get_q()); 362 | if(time>cutofftime) { 363 | z_pos=diode.Get_xmin()-10; 364 | cutoff=1; 365 | } 366 | if(dt>=timestep) { 367 | timearray=(int)floor(time/timestep); 368 | int previous; 369 | previous=hole->Get_timearray(pair); 370 | int test; 371 | for(test=(previous+1); test<(timearray+1); test++) { 372 | I[test]+=constants.Get_q()*dx/(dt*diode.Get_width()); 373 | Inum[test]+=constants.Get_q()*dx/(dt*diode.Get_width()); 374 | } 375 | dt=0; 376 | dx=0; 377 | hole->Input_timearray(pair,timearray); 378 | } 379 | hole->Input_time(pair,time); 380 | hole->Input_dt(pair,dt); 381 | hole->Input_dx(pair,dx); 382 | 383 | //Hole drift finishes here 384 | hole->Input_pos(pair,z_pos); 385 | hole->Input_Egy(pair,Energy); 386 | 387 | 388 | if(z_pos>diode.Get_xmax()) z_pos=diode.Get_xmax()-1e-10; 389 | if(z_pos>=diode.Get_xmin()) 390 | { //Hole scattering starts here 391 | double random22; 392 | int Eint2; 393 | Eint2=(int)floor(Energy*1000.0/constants.Get_q()+0.5); 394 | if (Energy>constants.Get_Emax()) 395 | { Eint2=constants.Get_NUMPOINTS(); 396 | random22=simulation.Get_pb2(2,constants.Get_NUMPOINTS());} 397 | else if (Energy==constants.Get_Emax()) 398 | { random22=simulation.Get_pb2(2,constants.Get_NUMPOINTS());} 399 | else { 400 | random22=genrand(); 401 | } 402 | 403 | if(random22<=simulation.Get_pb2(0,Eint2)) //phonon absorption 404 | { 405 | Energy+=constants.Get_hw(); 406 | npha++; 407 | nph++; 408 | hole->Input_scattering(pair,0); 409 | } 410 | else if(random22<=simulation.Get_pb2(1,Eint2)) //phonon emission 411 | { 412 | Energy-=constants.Get_hw(); 413 | nphe++; 414 | nph++; 415 | hole->Input_scattering(pair,0); 416 | } 417 | else if(random22<=simulation.Get_pb2(2,Eint2)) //impact ionization 418 | { 419 | Energy=(Energy-constants.Get_h_Eth())/3.0; 420 | num_electron++; 421 | electron->generation(num_electron,z_pos,Energy,time,0,(int)floor(time/timestep)); 422 | num_hole++; 423 | hole->generation(num_hole,z_pos,Energy,time,0,(int)floor(time/timestep)); 424 | tn++; 425 | nii++; 426 | prescent_carriers+=2; 427 | hole->Input_scattering(pair,0); 428 | } 429 | else if(random22>simulation.Get_pb2(2,Eint2)) //selfscattering 430 | { 431 | nssh++; 432 | hole->Input_scattering(pair,1); 433 | hole->Input_kxy(pair,kxy); 434 | hole->Input_kz(pair,kz); 435 | } 436 | //hole scattering ends here 437 | 438 | } 439 | else prescent_carriers--; 440 | 441 | hole->Input_Egy(pair,Energy); 442 | if(time>globaltime) flag--; } 443 | Highest=(int)_max(Highest,pair); 444 | 445 | if(flag==0) { 446 | globaltime+=timestep; 447 | //This is where globaltime is incrimented 448 | } 449 | } 450 | int scan=0; 451 | int scanlimit=0; 452 | //scans current array to detect breakdown current and stops sim early 453 | if(pair>carrierlimit) { 454 | while(scan==0) { 455 | for(Iarray=0; IarrayBreakdownCurrent) { 457 | scan=1; 458 | cut2=1; 459 | } 460 | if(Iarray==CurrentArray-1) scan=1; 461 | } 462 | if(Inum[Iarray]==0) ++scanlimit; 463 | if(Inum[Iarray]!=0) scanlimit=0; 464 | if(scanlimit>50) scan=1; 465 | } 466 | } 467 | } 468 | gain+=tn/Ntrials; //accumilates average gain 469 | Ms+=(tn*tn/Ntrials); //accumilates average Ms, used to calculate noise 470 | cumulative+=tn; //tracks average gain so far in simulation 471 | double printer=cumulative/num; 472 | 473 | //reset carrier arrays to 0 after trial 474 | electron->reset(); 475 | hole->reset(); 476 | //checks for breakdown at end of sim 477 | for (Iarray=0; Iarray BreakdownCurrent) { 479 | breakdown++; 480 | fflush(counter); 481 | double tb = timestep*Iarray; 482 | fprintf(tbout,"%d %g\n",num,tb); 483 | fflush(tbout); 484 | break; 485 | } 486 | } 487 | 488 | //trapezium rule 489 | int arealimitnum=0; 490 | double totalareanum=0; 491 | double area,x1,x2,y1,y2; 492 | int i; 493 | for(i=0; i<(CurrentArray-1); i++) 494 | { 495 | y1=Inum[i]; 496 | x1=timestep*i; 497 | y2=Inum[i+1]; 498 | x2=timestep*(i+1); 499 | area=y1*(x2-x1)+0.5*(y2-y1)*(x2-x1); 500 | totalareanum+=area; 501 | } 502 | totalareanum=totalareanum/1.6e-19; 503 | fprintf(Mout, "%d %g %g\n",num, totalareanum, tn); 504 | fflush(Mout); 505 | double Pbprint=breakdown/num; 506 | if(!(num%100)) { 507 | if(cutoff==0) printf("Completed trial: %d Gain=%f Pb=%f . Max array index=%d\n",num,printer,Pbprint,Highest); 508 | if(cutoff==1) printf("Completed trial: %d Cutoff Pb=%f Max array index=%d\n",num,Pbprint,Highest); 509 | } 510 | } 511 | 512 | F=Ms/(gain*gain); 513 | Pbreakdown=breakdown/Ntrials; 514 | 515 | if(cutoff==0) { 516 | printf("V= %f M= %f, F= %f, Pb= %f \n",Vsim,gain,F,Pbreakdown); 517 | fprintf(out,"V= %f M= %f F= %f, Pb= %f \n",Vsim,gain,F,Pbreakdown); 518 | } 519 | else{ 520 | printf("V= %f M= cutoff, F= cutoff, Pb= %f \n",Vsim,Pbreakdown); 521 | fprintf(out,"V= %f M= cutoff F= cutoff, Pb= %f \n",Vsim,Pbreakdown); 522 | } 523 | fflush(out); 524 | fclose(tbout); 525 | if(breakdown==0) { 526 | FILE *Iout; 527 | char name[] = "current.txt"; 528 | char Vsimchar[8]; 529 | snprintf(Vsimchar, sizeof(Vsimchar),"%g", Vsim); 530 | int filespec_len = strlen(name) + strlen(Vsimchar) + 1; 531 | char *fileSpec=new char[filespec_len]; 532 | snprintf(fileSpec,filespec_len, "%s%s", Vsimchar, name); 533 | if ((Iout=fopen(fileSpec,"w"))==NULL) 534 | { 535 | printf("Error: current.txt\n"); 536 | } 537 | delete[] fileSpec; 538 | fprintf(Iout,"V= %f \n", Vsim); 539 | fprintf(Iout,"time step size in %e s\n",timestep); 540 | fprintf(Iout,"t I \n"); 541 | int Ioutprint =0; 542 | int i; 543 | for(i=0; i0 && Ioutprint <50) { 548 | fprintf(Iout,"%g %g \n",timeprint,current); 549 | Ioutprint=0; 550 | } 551 | else if(Ioutprint <50) { 552 | fprintf(Iout,"%g %g \n",timeprint,current); 553 | Ioutprint++; 554 | } 555 | } 556 | fflush(Iout); 557 | fclose(Iout); 558 | } 559 | delete [] I; 560 | delete [] Inum; 561 | fclose(counter); 562 | fclose(Mout); 563 | } 564 | electron->~carrier(); 565 | hole->~carrier(); 566 | delete electron; 567 | delete hole; 568 | fclose(out); 569 | postprocess(V, simulationtime, bias_count); 570 | delete[] V; 571 | } 572 | --------------------------------------------------------------------------------