|
funkalicious 0.1
|
00001 /**Performs very simple operations on dotcode wavefunctions. 00002 00003 Copyright (C) 2011 Joseph Pingenot 00004 00005 This program is free software: you can redistribute it and/or modify 00006 it under the terms of the GNU Affero General Public License as published by 00007 the Free Software Foundation, either version 3 of the License, or 00008 (at your option) any later version. 00009 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU Affero General Public License for more details. 00014 00015 You should have received a copy of the GNU Affero General Public License 00016 along with this program. If not, see <http://www.gnu.org/licenses/>. 00017 00018 */ 00019 00020 #ifdef OPENMP 00021 #include <omp.h> 00022 #endif 00023 00024 #include <math.h> 00025 #include <libdotcode/wavefunction_simple_operations.h> 00026 00027 double dotcode_wavefunction_get_percentage_in_band(const struct wavefunction* wf, int band) { 00028 struct density* d = dotcode_wavefunction_get_density_in_band(wf, band); 00029 if(d == NULL) return nan("NaN"); 00030 /*d contains an implicit dx*dy*dz; remove this.*/ 00031 //density_mul_by_const(d, 1.0/(wf->dx[0]*wf->dx[1]*wf->dx[1])); 00032 //double val = density_integrate_spline(NULL, NULL, NULL, 1e-16, 1e-10, d, NULL, NULL); 00033 double val = density_integrate_sum_parallel(d, NULL, NULL); 00034 free_density(d); 00035 return val; 00036 } 00037 00038 void dotcode_wavefunction_integrate_sum(const struct wavefunction* b, void (*f)(double x, double y, double z, double* re, double* im, void* privdat), const struct wavefunction* a, double* value_re, double* value_im, void* privdat) { 00039 double f_re, f_im, re, im; 00040 int x, y, z, band; 00041 double sum_re = 0; 00042 double sum_im = 0; 00043 for(z=0; z<a->N[2]; ++z) { 00044 for(y=0; y<a->N[1]; ++y) { 00045 for(x=0; x<a->N[0]; ++x) { 00046 for(band=0; band<a->bands; ++band) { 00047 if(f != NULL) { 00048 f((x-a->N[0]/2)*a->dx[0], (y-a->N[1]/2)*a->dx[1], (z-a->N[2]/2)*a->dx[2], &f_re, &f_im, privdat); 00049 re = f_re * *get_wavefunction_storage_c_(x, y, z, 0, band, a) 00050 + f_im * *get_wavefunction_storage_c_(x, y, z, 1, band, a); 00051 im = f_re * *get_wavefunction_storage_c_(x, y, z, 1, band, a) 00052 - f_im * *get_wavefunction_storage_c_(x, y, z, 0, band, a); 00053 }else{ 00054 re = *get_wavefunction_storage_c_(x, y, z, 0, band, a); 00055 im = *get_wavefunction_storage_c_(x, y, z, 1, band, a); 00056 } 00057 sum_re += *get_wavefunction_storage_c_(x, y, z, 0, band, b) * re 00058 + *get_wavefunction_storage_c_(x, y, z, 1, band, b) * im; 00059 sum_im += *get_wavefunction_storage_c_(x, y, z, 0, band, b) * im 00060 - *get_wavefunction_storage_c_(x, y, z, 1, band, b) * re; 00061 } 00062 } 00063 } 00064 } 00065 *value_re = sum_re; 00066 *value_im = sum_im; 00067 } 00068 void dotcode_wavefunction_integrate_sum_1(const struct wavefunction* b, void (*f)(double x, double y, double z, double* re, double* im, void* privdat), const struct wavefunction* a, double* value, void* privdat) { 00069 dotcode_wavefunction_integrate_sum(b, f, a, &value[0], &value[1], privdat); 00070 } 00071 00072 void dotcode_wavefunction_integrate_sum_parallel(const struct wavefunction* b, void (*f)(double x, double y, double z, double* re, double* im, void* privdat), const struct wavefunction* a, double* value_re, double* value_im, void** privdat) { 00073 double f_re, f_im, re, im; 00074 int x, y, z, band; 00075 double sum_re = 0; 00076 double sum_im = 0; 00077 #ifdef OPENMP 00078 #pragma omp parallel for private(x, y, z, band, f_re, f_im, re, im) reduction(+:sum_re,sum_im) 00079 #endif 00080 for(z=0; z<a->N[2]; ++z) { 00081 for(y=0; y<a->N[1]; ++y) { 00082 for(x=0; x<a->N[0]; ++x) { 00083 for(band=0; band<a->bands; ++band) { 00084 if(f != NULL) { 00085 if(privdat != NULL) { 00086 f((x-a->N[0]/2)*a->dx[0], (y-a->N[1]/2)*a->dx[1], (z-a->N[2]/2)*a->dx[2], &f_re, &f_im, privdat[ 00087 #ifdef OPENMP 00088 omp_get_thread_num() 00089 #else 00090 0 00091 #endif 00092 ]); 00093 }else{ 00094 f((x-a->N[0]/2)*a->dx[0], (y-a->N[1]/2)*a->dx[1], (z-a->N[2]/2)*a->dx[2], &f_re, &f_im, NULL); 00095 } 00096 re = f_re * *get_wavefunction_storage_c_(x, y, z, 0, band, a) 00097 + f_im * *get_wavefunction_storage_c_(x, y, z, 1, band, a); 00098 im = f_re * *get_wavefunction_storage_c_(x, y, z, 1, band, a) 00099 - f_im * *get_wavefunction_storage_c_(x, y, z, 0, band, a); 00100 }else{ 00101 re = *get_wavefunction_storage_c_(x, y, z, 0, band, a); 00102 im = *get_wavefunction_storage_c_(x, y, z, 1, band, a); 00103 } 00104 sum_re += *get_wavefunction_storage_c_(x, y, z, 0, band, b) * re 00105 + *get_wavefunction_storage_c_(x, y, z, 1, band, b) * im; 00106 sum_im += *get_wavefunction_storage_c_(x, y, z, 0, band, b) * im 00107 - *get_wavefunction_storage_c_(x, y, z, 1, band, b) * re; 00108 } 00109 } 00110 } 00111 } 00112 *value_re = sum_re; 00113 *value_im = sum_im; 00114 } 00115 void dotcode_wavefunction_integrate_sum_parallel_1(const struct wavefunction* b, void (*f)(double x, double y, double z, double* re, double* im, void* privdat), const struct wavefunction* a, double* value, void** privdat) { 00116 dotcode_wavefunction_integrate_sum_parallel(b, f, a, &value[0], &value[1], privdat); 00117 }