funkalicious 0.1

wavefunction_simple_operations.c

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