k-dot-p 0.1

hamiltonian_cartesian_8band.h++

Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines