|
k-dot-p 0.1
|
00001 /* 00002 ** hamiltonian_cartesian_effective_mass.h++ 00003 ** 00004 ** Made by Johnny Q. Hacker 00005 ** Login <solarion@nathan> 00006 ** 00007 00008 Copyright (C) 2009 Joseph Pingenot 00009 00010 This program is free software: you can redistribute it and/or modify 00011 it under the terms of the GNU Affero General Public License as published by 00012 nnthe Free Software Foundation, either version 3 of the License, or 00013 (at your option) any later version. 00014 00015 This program is distributed in the hope that it will be useful, 00016 but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 GNU Affero General Public License for more details. 00019 00020 You should have received a copy of the GNU Affero General Public License 00021 along with this program. If not, see <http://www.gnu.org/licenses/>. 00022 ** Started on Fri Jul 3 06:18:08 2009 Johnny Q. Hacker 00023 // Last update Thu Oct 1 15:42:57 2009 Johnny Q. Hacker 00024 */ 00025 00026 00027 #ifndef HAMILTONIAN_EFFECTIVE_MASS_HXX_ 00028 #define HAMILTONIAN_EFFECTIVE_MASS_HXX_ 00029 00030 #include <libkdotp/hamiltonians.h++> 00031 #include <libmodelxx/generic_structure.h++> 00032 #include <libmodelxx/cartesian_grid.h++> 00033 #include <glib.h> 00034 00035 namespace kdotp { 00036 namespace libkdotp { 00037 namespace hamiltonian { 00038 00039 struct effective_mass_properties { 00040 /**One over mstar*/ 00041 double ooms; 00042 /**Electrostatic potential at this point*/ 00043 double potential; 00044 /**Conduction band at the gamma point at this point*/ 00045 double Ec; 00046 /**Electrostatic dielectric constant*/ 00047 double epsilon; 00048 }; 00049 00050 enum effective_mass_parameter { 00051 OOMSTAR, 00052 MSTAR, 00053 POTENTIAL, 00054 TOTAL_POTENTIAL, 00055 EC, 00056 EPSILON 00057 }; 00058 00059 class cartesian_effective_mass { 00060 public: 00061 /**Sets up the effective mass Hamiltonian for later calculations 00062 *\param struc the generic structure to be set up for calculating 00063 *\param bc the boundary conditions on the calculation 00064 */ 00065 /*For Hardwall BC with only one neighbor, or for storing the tridiagonal matrix from periodic BCs or more than one neighbor*/ 00066 double* upper_diagonal; 00067 double* diagonal; 00068 /**For periodic boundary conditions 00069 *\note that the matrix here is column-major, for compatibility with ACML 00070 *\note that this is also used for banded matrices; use banded_index to get the index. 00071 */ 00072 double* matrix; 00073 /**For periodic multi-neighbor hardwall BCs, we need Q to get the eigenstates back in the original basis.*/ 00074 double* Q; 00075 /**Number of grid sites*/ 00076 unsigned int L; 00077 /**Grid spacing*/ 00078 double dx; 00079 /**Boundary condition being used*/ 00080 enum boundary_condition bc; 00081 /**If true, use second neighbor in differentiation, else use first.*/ 00082 bool second_neighbor; 00083 /**Number of neighbors (if we need to up this in the future)*/ 00084 int n_neighbors; 00085 /**Array containing a second potential to apply (e.g. self-consistent)*/ 00086 double *internal_potential; 00087 /**Material parameters*/ 00088 struct effective_mass_properties* properties; 00089 /**Converts row column into matrix array address*/ 00090 inline int get_matrix_index(unsigned int row, unsigned int col) {return col + row*L;} 00091 /**Converts an upper subdiagonal and index into an index into the array 00092 *\note that the 0 subdiagonal is the diagonal 00093 */ 00094 inline int get_array_index(unsigned int row, unsigned int col) { 00095 /*Addresses are (kd+1+i-j), j 00096 *i = row index 00097 *j = column index 00098 *row index = n_neighbors + 1 + i - j - 1 (start at 0 in C) 00099 *row index = n_neighbors + (i - j) 00100 *i, i+n (n-th column of 1st superdiag) -> 00101 * j = i+n => row index = n_neighbors - n 00102 * col index = i + n 00103 *there are n_neighbors + 1 rows. 00104 */ 00105 return n_neighbors + (row - col) + (n_neighbors+1)*col; 00106 //return (n_neighbors - subdiagonal) + i*(n_neighbors+1); 00107 } 00108 00109 /**This sets the matrices to their new values.*/ 00110 void set_up_matrix(); 00111 /**Call this if only the internal potential was set.*/ 00112 void update_matrix_with_internal_potential(double* old_potential); 00113 /**Replaces the internal_potential array and then calls update_matrix_with_internal_potential()*/ 00114 void replace_internal_potential(double* new_potential); 00115 double* get_eigenvectors_double(double eVmin, double eVmax, double** evals, int *n_eigs, GError **err) { 00116 return get_eigenvectors('V', eVmin, eVmax, 0, 0, evals, n_eigs, err); 00117 } 00118 double* get_eigenvectors_int(int imin, int imax, double** evals, int *n_eigs, GError **err) { 00119 return get_eigenvectors('I', 0, 0, imin, imax, evals, n_eigs, err); 00120 } 00121 double* get_eigenvectors(char VoI, double eVmin, double eVmax, int imin, int imax, double**evals, int *n_eigs, GError **err); 00122 /**Gets a parameter across the structure 00123 *\param p the effective mass parameter 00124 *\param function array to store the function in 00125 *\return Error code: 00126 * 1 if the parameter was invalid 00127 * 0 success 00128 */ 00129 int get_parameter_function(int p, double* function) { 00130 for(unsigned int i=0; i<L; i++) { 00131 switch(p) { 00132 case OOMSTAR: 00133 function[i] = properties[i].ooms; 00134 break; 00135 case MSTAR: 00136 function[i] = 1.0/properties[i].ooms; 00137 break; 00138 case POTENTIAL: 00139 function[i] = properties[i].potential; 00140 break; 00141 case TOTAL_POTENTIAL: 00142 function[i] = properties[i].potential + internal_potential[i]; 00143 //fprintf(stderr, "total_potential@%u: %g = extern (%g) + intern (%g)\n", i, function[i], properties[i].potential, internal_potential[i]); 00144 break; 00145 case EC: 00146 function[i] = properties[i].Ec; 00147 break; 00148 case EPSILON: 00149 function[i] = properties[i].epsilon; 00150 break; 00151 default: 00152 return 1; 00153 } 00154 } 00155 return 0; 00156 } 00157 cartesian_effective_mass(struct libmodelxx::structure::generic_structure *gs, boundary_condition bc_, bool second_neighbor_); 00158 ~cartesian_effective_mass(); 00159 libmodelxx::grid::cartesian_grid<libmodelxx::structure::material*,1,1>* matgrid; 00160 libmodelxx::grid::cartesian_grid<double,1,1>* potgrid; 00161 private: 00162 cartesian_effective_mass() {} 00163 cartesian_effective_mass operator=(const cartesian_effective_mass& em) {return *this;} 00164 }; 00165 00166 } 00167 } 00168 } 00169 00170 00171 #endif