|
k-dot-p 0.1
|
00001 /* 00002 *Provides a nice class to house an effective mass wavefunction. 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 #include <libkdotp/wavefunction_cartesian_effective_mass.h++> 00022 #include <math.h> 00023 00024 namespace kdotp { 00025 namespace libkdotp { 00026 namespace wavefunction { 00027 00028 #define WAVEFUNCTION_CARTESIAN_EFFECTIVE_MASS_GERROR_DOMAIN 29 00029 00030 00031 cartesian_effective_mass::cartesian_effective_mass(double* eigenvector_block, unsigned int eigvec, double dx, unsigned int L, double energy) : E(energy), dx(dx), L(L) { 00032 wf = new double[L]; 00033 for(unsigned int i=0; i<L; i++) wf[i] = eigenvector_block[L*eigvec+i]; 00034 } 00035 00036 /*Although this is authoritative, it's probably faster to use L*eigvec+i directly, so the L*eigvec is pulled out of the loop*/ 00037 ___const unsigned int get_cartesian_effective_mass_block_index(unsigned int i, unsigned int eigvec, unsigned int L) { 00038 return L*eigvec + i; 00039 } 00040 00041 double get_average_with_cartesian_effective_mass_block(double* block, unsigned int eigvec, unsigned int L, double* func) { 00042 double avg = 0; 00043 for(unsigned int i=0; i<L; i++) avg += block[L*eigvec + i]*block[L*eigvec + i]*func[i]; 00044 return avg; 00045 } 00046 00047 /**Sets the points to the density from this wavefunction. 00048 *\param block the block of eigenvalues 00049 *\param eigvec which eigenvector to use in the block 00050 *\param L the number of points in each wave function in the block 00051 *\param dx inter-node spacing 00052 *\param density pre-allocated structure to store density in. 00053 *\return pointer to GError 00054 *\note the density has already been allocated! 00055 */ 00056 GError* init_density_1d_from_cartesian_effective_mass_block(double* block, unsigned int eigvec, unsigned int L, double dx, struct density_1d *density) { 00057 if(unlikely(density->N != L)) return g_error_new(WAVEFUNCTION_CARTESIAN_EFFECTIVE_MASS_GERROR_DOMAIN, 1, "::kdotp::libkdotp::wavefunction::wavefunction_cartesian_effective_mass.c++::init_density_1d_from_carteisan_effective_mass_block: allocated size of the density's storage (%u) and the number of points in the %u-th eigenvector (%u) don't agree!", density->N, eigvec, L); 00058 density->dx = dx; 00059 density->N = L; 00060 for(unsigned int i=0; i<L; i++) density->storage[i] = block[L*eigvec + i]*block[L*eigvec + i]; 00061 return NULL; 00062 } 00063 00064 double get_cartesian_effective_mass_block_max_delta(double* block1, unsigned vec1, double* block2, unsigned vec2, unsigned int L) { 00065 //fprintf(stderr, "In get_cartesian_effective_mass_block_max_delta:\n"); 00066 if((block1 == NULL) || (block2 == NULL)) return -1; 00067 double max_change = fabs(block1[L*vec1]*block1[L*vec1] - block2[L*vec2]*block2[L*vec2]); 00068 register double change; 00069 for(unsigned int i=1; i<L; i++) { 00070 change = fabs(block1[L*vec1+i]*block1[L*vec1+i] - block2[L*vec2+i]*block2[L*vec2+i]); 00071 //fprintf(stderr, "\t%u: change=%g maxchange=%g (%g-%g)\n", i, change, max_change, block1[L*vec1+i]*block1[L*vec1+i], block2[L*vec2+i]*block2[L*vec2+i]); 00072 if(change > max_change) max_change = change; 00073 } 00074 //fprintf(stderr, "\tmaxchange=%g\n", max_change); 00075 return fabs(max_change); 00076 } 00077 } 00078 } 00079 } 00080