|
gimme-alpha 0.1
|
00001 /* 00002 ** gimme-alpha.c 00003 ** 00004 ** Made by (Johnny Q. Hacker) 00005 ** Login <solarion@borkborkbork> 00006 ** 00007 00008 Copyright (C) 2008 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 the 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 00023 ** Started on Fri Sep 26 16:27:45 2008 Johnny Q. Hacker 00024 ** Last update Wed Jun 17 15:07:42 2009 Johnny Q. Hacker 00025 */ 00026 00027 #include <stdio.h> 00028 #include <stdlib.h> 00029 #include <glib-2.0/glib.h> 00030 #include <gio/gio.h> 00031 #include <math.h> 00032 #include <libcommon/gimme_alpha_types.h> 00033 #include "process-args.h" 00034 #include <libnextnano/read_nextnano_inputfile.h> 00035 #include <libnextnano/read_nextnano_effectivemass_output.h> 00036 #include <libnextnano/read_nextnano_bandstructure.h> 00037 #include <libnextnano/read_nextnano_8x8kp_output.h> 00038 #include <libcommon/gimme-alpha_structs.h> 00039 #include <libpostproccalx/alpha_calc.h> 00040 #include <libmodeling/wavefunction.h> 00041 00042 ___malloc double* new_double(double val) { 00043 double* v = malloc(sizeof(double)); 00044 if(unlikely(v == NULL)) return v; 00045 *v = val; 00046 return v; 00047 } 00048 00049 void point_hash_print(GHashTable *t) { 00050 double *v; 00051 if(t == NULL) { 00052 fprintf(stderr, "\tPoint hash does not exist!\n"); 00053 return; 00054 } 00055 GList *keys = g_hash_table_get_keys(t); 00056 if(keys == NULL) { 00057 fprintf(stderr, "\tPoint hash is empty.\n"); 00058 return; 00059 } 00060 for(GList *k = keys; k != NULL; k=g_list_next(k)) { 00061 fprintf(stderr, "\t%s=", (char*)(k->data)); 00062 v = g_hash_table_lookup(t, k); 00063 if(v == NULL) { 00064 fprintf(stderr, "%s\n", "[NULL]"); 00065 }else{ 00066 fprintf(stderr, "%g\n", *v); 00067 } 00068 } 00069 g_list_free(keys); 00070 } 00071 00072 void print_value_double(gpointer data, gpointer private) { 00073 printf((char*)private, *(double*)data); 00074 } 00075 00076 int main(int argc, char* argv[]) { 00077 g_type_init(); 00078 GFile* pwd = g_file_new_for_commandline_arg("."); 00079 struct args *arg = process_args(argc, argv); 00080 if(arg == NULL) exit(2); 00081 GList *bdl; 00082 char *interror_title = ""; 00083 if(!(arg->no_print_integration_error)) { 00084 interror_title="\tintegration error(eV m)"; 00085 } 00086 if(arg->separate_terms) { 00087 printf("#directory\ttotal(eV m)\tinterface(eV m)\tefield(eV m)%s\n", interror_title); 00088 } 00089 for(bdl = arg->base_dirs; bdl != NULL; bdl = g_list_next(bdl)) { 00090 GFile *bd = bdl->data; 00091 GError *err = NULL; 00092 //fprintf(stderr, "back in gimme-alpha; about to get the gfile\n"); 00093 GFile *keywords = g_file_get_child(bd, "keywords.in"); 00094 //fprintf(stderr, "back in gimme-alpha; got the gfile\n"); 00095 /* 00096 GFileInputStream *kwds_istream = g_file_read(keywords, NULL, &err); 00097 if(err != NULL) { 00098 fprintf(stderr, "Got error opening keywords file in %s: %s\n", arg->dir, err->message); 00099 exit(3); 00100 } 00101 GHashTable *kwds = read_nextnano_inputfile(G_INPUT_STREAM(db_istream), &err); 00102 */ 00103 GFile *database = g_file_get_child(bd, "database.in"); 00104 GFileInputStream *db_istream = g_file_read(database, NULL, &err); 00105 if(err != NULL) { 00106 gchar *fn = g_file_get_uri(bd); 00107 fprintf(stderr, "Got error opening database file %s: %s\n", fn, err->message); 00108 g_free(fn); 00109 exit(1); 00110 } 00111 GHashTable *db = read_nextnano_dbfile(G_INPUT_STREAM(db_istream), &err); 00112 /* 00113 fprintf(stderr, "Database:\n"); 00114 print_stringy_inputfile(db); 00115 */ 00116 GFile *input_file = g_file_get_child(bd, "input_file1.in"); 00117 GFileInputStream *input_istream = g_file_read(input_file, NULL, &err); 00118 if(err != NULL) { 00119 gchar *fn = g_file_get_uri(bd); 00120 fprintf(stderr, "Got error opening input file %s: %s\n", fn, err->message); 00121 g_free(fn); 00122 exit(1); 00123 } 00124 GHashTable *ifile = read_nextnano_inputfile_stringy(G_INPUT_STREAM(input_istream), &err); 00125 struct mstar_wavefunction_1d *wf = read_effectivemass_complex_wavefunction2(CB, 1, 1, 1, NEU, 1, 1, bd, ifile, &err); 00126 if(unlikely((wf == NULL) || (err != NULL))) { 00127 fprintf(stderr, "Got error opening nextnano input file: %s\n", (err == NULL)?"[internal wavefunction conversion failure; is likely a change in nextnano wavefunction output format]":err->message); 00128 exit(1); 00129 } 00130 double *pot_x, *pot_band; 00131 int pot_n; 00132 pot_band = read_nextnano_bandstructure_file(POTENTIAL_FILE, bd, ifile, &err, &pot_x, &pot_n); 00133 struct potential pot = {.x = pot_x, .N = pot_n, .potential=pot_band}; 00134 int hh_n; 00135 double *hh_x, *hh_band; 00136 hh_band = read_nextnano_bandstructure_file(HH_FILE, bd, ifile, &err, &hh_x, &hh_n); 00137 struct band hh_b = {.x = hh_x, .N = hh_n, .bandedge=hh_band}; 00138 int lh_n; 00139 double *lh_x, *lh_band; 00140 lh_band = read_nextnano_bandstructure_file(LH_FILE, bd, ifile, &err, &lh_x, &lh_n); 00141 struct band lh_b = {.x = lh_x, .N = lh_n, .bandedge=lh_band}; 00142 if(!(arg->avg_hh_lh & 1)){ 00143 /*don't average the heavy and light holes; use just the heavy hole 00144 ("don't use the light hole")*/ 00145 for(int l=0; l<lh_b.N; l++) { 00146 lh_b.bandedge[l] = hh_b.bandedge[l]; 00147 } 00148 } 00149 if(!(arg->avg_hh_lh & 2)) { 00150 /*don't average the heavy and light holes; use just the light hole 00151 ("don't use the heavy hole") 00152 */ 00153 for(int l=0; l<hh_b.N; l++) { 00154 hh_b.bandedge[l] = lh_b.bandedge[l]; 00155 } 00156 } 00157 int so_n; 00158 double *so_x, *so_band; 00159 so_band = read_nextnano_bandstructure_file(SO_FILE, bd, ifile, &err, &so_x, &so_n); 00160 struct band so_b = {.x = so_x, .N = so_n, .bandedge=so_band}; 00161 int cb_n; 00162 double *cb_x, *cb_band; 00163 cb_band = read_nextnano_bandstructure_file(CB_FILE, bd, ifile, &err, &cb_x, &cb_n); 00164 struct band cb_b = {.x = cb_x, .N = cb_n, .bandedge=cb_band}; 00165 00166 /*for(int i=0; i<cb_n; i++) printf("%g\t%g\n", cb_x[i], cb_band[i]); 00167 fprintf(stderr, "Interfaces found at:"); 00168 for(GList *l=g_list_first(arg->interfaces); l!= NULL; l=g_list_next(l)) fprintf(stderr, "%g ", *((double*)(l->data))); 00169 fprintf(stderr, "\n"); 00170 */ 00171 00172 double alpha_efield=0.0; 00173 double integration_error=0; 00174 double alpha_interface=0.0; 00175 double alpha=0.0; 00176 struct alpha_integrand_verificator vf; 00177 struct alpha_integrand_verificator_2 vf2; 00178 struct alpha_integrand_verificator *vfp = NULL; 00179 struct alpha_integrand_verificator_2 *vfp2 = NULL; 00180 if(arg->del_psi2) { 00181 if(arg->instrument_efield_alpha) vfp2 = &vf2; 00182 alpha = alpha_from_del_psi2_nostrain(wf, &hh_b, &lh_b, &so_b, &cb_b, &pot, vfp2, &integration_error, arg->request_integration_abs_error, arg->request_integration_rel_error, arg->no_integrate, arg->Ep); 00183 }else{ 00184 if(!(arg->no_interface_term)) { 00185 /*Add all of the x points in the CB list if they're within an interface sequene.*/ 00186 GList *l; 00187 /*Note that this is a "shallow copy" i.e. data points to the exact same thing. Is OK; we just want to access it, not copy the data. We'll free the list again when we're done (but, not the data pointed to by l->data!!)*/ 00188 GList *ifaces = g_list_copy(arg->interfaces); 00189 GList *new_ifaces = NULL; 00190 for(int i=0; i<(cb_b.N-1); i++) { 00191 for(l=arg->ifaces_sequences; l!=NULL; l=l->next) { 00192 if((cb_b.x[i] >= ((double*)(l->data))[0]) && (cb_b.x[i] <= ((double*)(l->data))[1])) { 00193 /*Just like before, we only care about accessing the data; we don't really want to make a separate copy of it.*/ 00194 //fprintf(stderr, "iface: %g-> (%g:%g)\n", cb_b.x[i], ((double*)(l->data))[0], ((double*)(l->data))[1]); 00195 new_ifaces = g_list_prepend(new_ifaces, new_double((cb_b.x[i] + cb_b.x[i])/2)); 00196 ifaces = g_list_append(ifaces, new_ifaces->data); 00197 }else{ 00198 //fprintf(stderr, "!iface: %g (%g:%g)\n", cb_b.x[i], ((double*)(l->data))[0], ((double*)(l->data))[1]); 00199 } 00200 } 00201 } 00202 alpha_interface=alpha_interface_term_mstar_nostrain(wf, &hh_b, &lh_b, &so_b, &cb_b, &pot, ifaces, arg->Ep); 00203 /*Make sure to free the interstitial storage*/ 00204 for(GList *ll = new_ifaces; ll!=NULL; ll=ll->next) free(ll->data); 00205 g_list_free(new_ifaces); 00206 g_list_free(ifaces); 00207 } 00208 if(!(arg->no_efield_term)) { 00209 if(arg->instrument_efield_alpha) vfp = &vf; 00210 alpha_efield = alpha_electric_term_mstar_nostrain(wf, &hh_b, &lh_b, &so_b, &cb_b, &pot, vfp, &integration_error, arg->request_integration_abs_error, arg->request_integration_rel_error, arg->no_integrate, arg->Ep); 00211 } 00212 } 00213 if((vfp != NULL) || (vfp2 != NULL)) { 00214 fprintf(stderr, "Writing integration debug output.\n"); 00215 GFile *instfile; 00216 if(vfp != NULL) { 00217 instfile = g_file_new_for_commandline_arg("./alpha_efield_instrumentation_data.pdata"); 00218 alpha_write_verificator_data(instfile, vfp); 00219 } 00220 if(vfp2 != NULL) { 00221 instfile = g_file_new_for_commandline_arg("./alpha_method2_instrumentation_data.pdata"); 00222 alpha_write_verificator2_data(instfile, vfp2); 00223 } 00224 } 00225 char interror_string[512]; 00226 interror_string[0] = '\0'; 00227 if(!(arg->no_print_integration_error)) { 00228 interror_title="\tintegration error(eV m)"; 00229 snprintf(interror_string, 512, "\t%g", integration_error); 00230 interror_string[511] = '\0'; 00231 } 00232 gchar* fn = g_file_get_uri(bd); 00233 if(arg->del_psi2) { 00234 printf("%s\t%g", fn, alpha); 00235 }else{ 00236 printf("%s\t%g", fn, alpha_interface + alpha_efield); 00237 } 00238 g_free(fn); 00239 if((!(arg->del_psi2)) && (arg->separate_terms)) { 00240 printf("\t%g\t%g%s\n", alpha_interface, alpha_efield, interror_string); 00241 }else{ 00242 printf("%s\n", interror_string); 00243 } 00244 } 00245 return 0; 00246 }