|
k-dot-p 0.1
|
00001 /* 00002 *An 8-band Hamiltonian on a Cartesian grid. 00003 00004 Copyright (C) 2010 Joseph Pingenot 00005 00006 This program is free software: you can redistribute it and/or modify 00007 it under the terms of the GNU Affero General Public License as published by 00008 the Free Software Foundation, either version 3 of the License, or 00009 (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU Affero General Public License for more details. 00015 00016 You should have received a copy of the GNU Affero General Public License 00017 along with this program. If not, see <http://www.gnu.org/licenses/>. 00018 00019 */ 00020 00021 #ifndef ___HAMILTONIAN_8BAND_CARTESIAN_HXX___ 00022 #define ___HAMILTONIAN_8BAND_CARTESIAN_HXX___ 00023 00024 #include <libkdotp/hamiltonians.h++> 00025 #include <libmodelxx/generic_structure.h++> 00026 #include <libmodelxx/cartesian_grid.h++> 00027 #include <liblapackwrap/lapackwrap_complex_double.h> 00028 #include <glib.h> 00029 00030 namespace kdotp { 00031 namespace libkdotp { 00032 namespace hamiltonian { 00033 00034 /**\note CS = conduction band S-state 00035 *VH is valence heavy hole 00036 *VL is valence light hole 00037 *VO is valence split-off 00038 *_P is plus (+ 1/2 or 3/2 depending on state) 00039 *_M is minus (- 1/2 or 3/2 depending on state) 00040 */ 00041 enum cartesian_8terms { 00042 CS_P = 0, 00043 CS_M, 00044 VH_P, 00045 VL_P, 00046 VL_M, 00047 VH_M, 00048 VO_P, 00049 VO_M 00050 }; 00051 00052 struct parameters_8band_nostrain { 00053 /**\var conduction band edge with applied potential*/ 00054 double Ec; 00055 /**\var valence band energy with applied potential*/ 00056 double Ev; 00057 /**\var Split-off band energy with applied potential*/ 00058 double Eso; 00059 /**\var inverse of *reduced* effective mass*/ 00060 double oo_mstar; 00061 /**\var *reduced* Luttinger parameters*/ 00062 double gamma1; 00063 double gamma2; 00064 double gamma3; 00065 /**inter-band coupling parameter*/ 00066 double P; 00067 }; 00068 00069 class cartesian_8band { 00070 public: 00071 /**Sets up the effective mass Hamiltonian for later calculations 00072 *\param struc the generic structure to be set up for calculating 00073 *\param bc the boundary conditions on the calculation 00074 */ 00075 /*For Hardwall BC with only one neighbor, or for storing the tridiagonal matrix from periodic BCs or more than one neighbor*/ 00076 double* upper_diagonal; 00077 double* diagonal; 00078 /**For periodic boundary conditions 00079 *\note that the matrix here is column-major, for compatibility with ACML 00080 *\note that this is also used for banded matrices; use banded_index to get the index. 00081 */ 00082 llw_complex_double* matrix; 00083 /*For periodic multi-neighbor hardwall BCs, we need Q to get the eigenstates back in the original basis.*/ 00084 llw_complex_double* Q; 00085 /*Number of grid sites*/ 00086 unsigned int L; 00087 /*Boundary condition being used*/ 00088 enum boundary_condition bc; 00089 /*If true, use second neighbor in differentiation, else use first.*/ 00090 bool second_neighbor; 00091 /*Number of neighbors (if we need to up this in the future)*/ 00092 int n_neighbors; 00093 /*Array containing the 8band parameters at each point.*/ 00094 struct parameters_8band_nostrain *params; 00095 00096 /**Converts row column into matrix array address 00097 *\note for 8-band: we have 8 bands for each row and column address, so 00098 * the final row and coumn is (row*8 + band) and (col*8+band). 00099 */ 00100 inline int get_matrix_index(unsigned int row, unsigned int col, unsigned short band) {return (8*col+band) + (row*8+band)*L;} 00101 /**Converts an upper subdiagonal and index into an index into the array 00102 *\note that the 0 subdiagonal is the diagonal 00103 */ 00104 inline int get_array_index(unsigned int row, unsigned int col, unsigned short band) { 00105 /*Addresses are (kd+1+i-j), j 00106 *i = row index 00107 *j = column index 00108 *row index = n_neighbors + 1 + i - j - 1 (start at 0 in C) 00109 *row index = n_neighbors + (i - j) 00110 *i, i+n (n-th column of 1st superdiag) -> 00111 * j = i+n => row index = n_neighbors - n 00112 * col index = i + n 00113 *there are n_neighbors + 1 rows. 00114 **\note update for 8-band: 00115 * For each neighbor, we have 8 bands 00116 * n_neighbors -> n_neighbors*8 00117 * 00118 */ 00119 return n_neighbors*8 + ((row*8+band) - (col*8+band)) + ((n_neighbors+1)*8)*(col*8+band); 00120 //return (n_neighbors - subdiagonal) + i*(n_neighbors+1); 00121 } 00122 00123 double* get_eigenvectors_double(double eVmin, double eVmax, double** evals, int *n_eigs, GError **err) { 00124 return get_eigenvectors('V', eVmin, eVmax, 0, 0, evals, n_eigs, err); 00125 } 00126 double* get_eigenvectors_int(int imin, int imax, double** evals, int *n_eigs, GError **err) { 00127 return get_eigenvectors('I', 0, 0, imin, imax, evals, n_eigs, err); 00128 } 00129 double* get_eigenvectors(char VoI, double eVmin, double eVmax, int imin, int imax, double**evals, int *n_eigs, GError **err); 00130 cartesian_8band(struct libmodelxx::structure::generic_structure *gs, boundary_condition bc_, bool second_neighbor_); 00131 ~cartesian_8band(); 00132 private: 00133 cartesian_8band() {} 00134 cartesian_8band operator=(const cartesian_8band& em) {return *this;} 00135 }; 00136 00137 00138 } 00139 } 00140 } 00141 00142 #endif