|
funkalicious 0.1
|
00001 /**Gets the composition of a dotcode wavefunction 00002 00003 00004 Copyright (C) 2011 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 #ifdef OPENMP 00021 #include <omp.h> 00022 #endif 00023 #include <stdio.h> 00024 #include <glib-2.0/glib.h> 00025 #include <gio/gio.h> 00026 #include <math.h> 00027 #include <libpostproc/lp_wavefunction.h> 00028 #include <libdotcode/dotcode_wavefunction.h> 00029 #include <libdotcode/wavefunction_simple_operations.h> 00030 #include <libdotcode/dotcode_data.h> 00031 #include <libpostproc/unit_conversion.h> 00032 00033 static void get_x(double x, double y, double z, double* re, double* im, void* privdat) { 00034 *re = x; 00035 *im = 0; 00036 } 00037 static void get_y(double x, double y, double z, double* re, double* im, void* privdat) { 00038 *re = y; 00039 *im = 0; 00040 } 00041 static void get_z(double x, double y, double z, double* re, double* im, void* privdat) { 00042 *re = z; 00043 *im = 0; 00044 } 00045 00046 static void get_sigma_x(double x, double y, double z, double* re, double* im, void* privdat) { 00047 *re = (x - *(double*)privdat)*(x - *(double*)privdat); 00048 *im = 0; 00049 } 00050 static void get_sigma_y(double x, double y, double z, double* re, double* im, void* privdat) { 00051 *re = (y - *(double*)privdat)*(y - *(double*)privdat); 00052 *im = 0; 00053 } 00054 static void get_sigma_z(double x, double y, double z, double* re, double* im, void* privdat) { 00055 *re = (z - *(double*)privdat)*(z - *(double*)privdat); 00056 *im = 0; 00057 } 00058 00059 static void get_x_110(double x, double y, double z, double* re, double* im, void* privdat) { 00060 *re = 1/sqrt(2)*(x+y); 00061 *im = 0; 00062 } 00063 static void get_y_110(double x, double y, double z, double* re, double* im, void* privdat) { 00064 *re = 1/sqrt(2)*(y-x); 00065 *im = 0; 00066 } 00067 00068 static void get_sigma_x_110(double x, double y, double z, double* re, double* im, void* privdat) { 00069 double x_110 = 1/sqrt(2)*(x+y); 00070 *re = (x_110 - *(double*)privdat)*(x_110 - *(double*)privdat); 00071 *im = 0; 00072 } 00073 static void get_sigma_y_110(double x, double y, double z, double* re, double* im, void* privdat) { 00074 double y_110 = 1/sqrt(2)*(y-x); 00075 *re = (y_110 - *(double*)privdat)*(y_110 - *(double*)privdat); 00076 *im = 0; 00077 } 00078 00079 int main(int argc, char** argv) { 00080 g_type_init(); 00081 gboolean basis_110 = TRUE; 00082 printf("#file\t<x>(nm)\t<y>(nm)\t<z>(nm)\tsigma_x(nm)\tsigma_y(nm)\tsigma_z(nm)\n"); 00083 for(int wfn=1; wfn<argc; ++wfn) { 00084 GList* l=NULL; 00085 GFile* f = g_file_new_for_commandline_arg(argv[wfn]); 00086 struct wavefunction wf = {.file=f, .charge=1, .N={0, 0, 0}, .dx={0, 0, 0}, .bands=0, .storage=NULL}; 00087 l = g_list_append(l, &wf); 00088 GError *e = NULL; 00089 load_wavefunctions(l, &e); 00090 if(e == NULL) { 00091 printf("%s", argv[wfn]); 00092 double im = 0; 00093 double avg_x=0; 00094 double avg_y=0; 00095 double avg_z=0; 00096 double sigma_x=0; 00097 double sigma_y=0; 00098 double sigma_z=0; 00099 dotcode_wavefunction_integrate_sum_parallel(&wf, basis_110?get_x_110:get_x, &wf, &avg_x, &im, NULL); 00100 if(fabs(im) >= 1e-8) { 00101 fprintf(stderr, "ERROR getting <x>: imaginary part was non-zero!\n"); 00102 return 1; 00103 } 00104 dotcode_wavefunction_integrate_sum_parallel(&wf, basis_110?get_y_110:get_y, &wf, &avg_y, &im, NULL); 00105 if(fabs(im) >= 1e-8) { 00106 fprintf(stderr, "ERROR getting <y>: imaginary part was non-zero!\n"); 00107 return 1; 00108 } 00109 dotcode_wavefunction_integrate_sum_parallel(&wf, get_z, &wf, &avg_z, &im, NULL); 00110 if(fabs(im) >= 1e-8) { 00111 fprintf(stderr, "ERROR getting <z>: imaginary part was non-zero!\n"); 00112 return 1; 00113 } 00114 #ifdef OPENMP 00115 int N_threads=omp_get_max_threads(); 00116 #else 00117 int N_threads=1; 00118 #endif 00119 void* callback_data[N_threads]; 00120 /*Since the callback data is only read, we can have one copy for all threads*/ 00121 for(int i=0; i<N_threads; ++i) callback_data[i] = &avg_x; 00122 dotcode_wavefunction_integrate_sum_parallel(&wf, basis_110?get_sigma_x_110:get_sigma_x, &wf, &sigma_x, &im, callback_data); 00123 if(fabs(im) >= 1e-8) { 00124 fprintf(stderr, "ERROR getting sigma_x: imaginary part was non-zero!\n"); 00125 return 1; 00126 } 00127 for(int i=0; i<N_threads; ++i) callback_data[i] = &avg_y; 00128 dotcode_wavefunction_integrate_sum_parallel(&wf, basis_110?get_sigma_y_110:get_sigma_y, &wf, &sigma_y, &im, callback_data); 00129 if(fabs(im) >= 1e-8) { 00130 fprintf(stderr, "ERROR getting sigma_y: imaginary part was non-zero!\n"); 00131 return 1; 00132 } 00133 for(int i=0; i<N_threads; ++i) callback_data[i] = &avg_z; 00134 dotcode_wavefunction_integrate_sum_parallel(&wf, get_sigma_z, &wf, &sigma_z, &im, callback_data); 00135 if(fabs(im) >= 1e-8) { 00136 fprintf(stderr, "ERROR getting sigma_z: imaginary part was non-zero!\n"); 00137 return 1; 00138 } 00139 sigma_x = sqrt(sigma_x); 00140 sigma_y = sqrt(sigma_y); 00141 sigma_z = sqrt(sigma_z); 00142 printf("\t%g\t%g\t%g\t%g\t%g\t%g\n", bohr_to_nm(avg_x), bohr_to_nm(avg_y), bohr_to_nm(avg_z), bohr_to_nm(sigma_x), bohr_to_nm(sigma_y), bohr_to_nm(sigma_z)); 00143 00144 dotcode_wavefunction_free_resources(&wf); 00145 }else{ 00146 fprintf(stderr, "ERROR loading wavefunction (%s): %s", argv[wfn], e->message); 00147 } 00148 g_list_free(l); 00149 if(e != NULL) g_error_free(e); 00150 } 00151 return 0; 00152 }