k-dot-p 0.1

hamiltonian_cartesian_effective_mass.h++

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