|
gimme-alpha 0.1
|
00001 /* 00002 ** read_nextnano_bandstructure.c 00003 ** 00004 ** Made by (Johnny Q. Hacker) 00005 ** Login <solarion@borkborkbork> 00006 ** 00007 ** Started on Tue Oct 28 15:06:45 2008 Johnny Q. Hacker 00008 ** Last update Sun May 12 01:17:25 2002 Speed Blue 00009 */ 00010 00011 #include <unistd.h> 00012 #include <stdio.h> 00013 #include <glib.h> 00014 #include <gio/gio.h> 00015 #include <math.h> 00016 #include <stdlib.h> 00017 #include <libnextnano/read_nextnano_bandstructure.h> 00018 #include <libcommon/textfile_common.h> 00019 #include <libcommon/gcc_hints.h> 00020 00021 #define CLOSE_ENOUGH 1e-8 00022 00023 /*Faster, if you're not gonna worry about roundoff*/ 00024 static gint coordinate_density_sorter(gconstpointer a, gconstpointer b) { 00025 double *c; 00026 double *d; 00027 if((c=g_hash_table_lookup((GHashTable*)a, "x")) == NULL) { 00028 if((d=g_hash_table_lookup((GHashTable*)b, "x")) == NULL) return 0; 00029 return -1; 00030 }else if((d=g_hash_table_lookup((GHashTable*)b, "x")) == NULL) { 00031 return 1; 00032 } 00033 if(*c < *d) return -1; 00034 if(*c > *d) return 1; 00035 return 0; 00036 } 00037 /*Slower, but gets the answer right if you have roundoff*/ 00038 static gint approx_coordinate_density_sorter(gconstpointer a, gconstpointer b) { 00039 double *c; 00040 double *d; 00041 if((c=g_hash_table_lookup((GHashTable*)a, "x")) == NULL) { 00042 if((d=g_hash_table_lookup((GHashTable*)b, "x")) == NULL) return 0; 00043 return -1; 00044 }else if((d=g_hash_table_lookup((GHashTable*)b, "x")) == NULL) { 00045 return 1; 00046 } 00047 //fprintf(stderr, "got x values c=%g(%p) and d=%g(%p) (a=%p,b=%p)\n", *c, c, *d, d, a, b); 00048 if(fabs(*c - *d) < fabs(CLOSE_ENOUGH*(*c))) return 0; 00049 if(*c < *d) return -1; 00050 if(*c > *d) return 1; 00051 return 0; 00052 } 00053 00054 double* read_nextnano_bandstructure_file(enum bandstructure_file f, GFile *base_dir, GHashTable *infile, GError **err, double **x, int *N) { 00055 gchar* filename; 00056 switch (f) { 00057 case CB_FILE: filename = "cb1D_001.dat"; break; 00058 case CB_L_FILE: filename = "cb1D_002.dat"; break; 00059 case CB_X_FILE: filename = "cb1D_003.dat"; break; 00060 case HH_FILE: filename = "vb1D_001.dat"; break; 00061 case LH_FILE: filename = "vb1D_002.dat"; break; 00062 case SO_FILE: filename = "vb1D_003.dat"; break; 00063 case POTENTIAL_FILE: filename = "potential1D.dat"; break; 00064 default: 00065 fprintf(stderr, "ERROR in read_nextnano_bandstructure_file: unknown band type %d\n", f); 00066 return NULL; 00067 } 00068 GList *chunk; 00069 GHashTable *kv_set; 00070 GList *values; 00071 chunk = g_hash_table_lookup(infile, "output-bandstructure"); 00072 g_assert(chunk != NULL); 00073 kv_set = g_list_first(chunk)->data; 00074 g_assert(kv_set != NULL); 00075 values = g_list_first(g_hash_table_lookup(kv_set, "destination-directory")); 00076 GFile *bandstructure_dir = g_file_get_child(base_dir, values->data); 00077 GFile *band_file = g_file_get_child(bandstructure_dir, filename); 00078 GFileInputStream *istream = g_file_read(band_file, NULL, err); 00079 if((*err) != NULL) { 00080 fprintf(stderr, "Error: unable to open potential file.\n"); 00081 return NULL; 00082 } 00083 GList *titles = g_list_append(NULL, "x"); 00084 titles = g_list_append(titles, "energy"); 00085 GList *result = read_titled_whitespaced_data((GInputStream*)istream, err, &titles, '!', DOUBLE_TYPE); 00086 g_input_stream_close((GInputStream*)istream, NULL, err); 00087 00088 /*Now allocate and move the list info into a band structure file.*/ 00089 double *data; 00090 *N = g_list_length(result); 00091 if(unlikely((data = (double*)malloc((*N)*sizeof(double))) == NULL)) { 00092 fprintf(stderr, "ERROR in read_nextnano_bandstructure_file: failed to allocate storage for data\n"); 00093 return NULL; 00094 } 00095 if(unlikely(((*x) = (double*)malloc((*N)*sizeof(double))) == NULL)) { 00096 fprintf(stderr, "ERROR in read_nextnano_bandstructure_file: failed to allocate storage for data\n"); 00097 free(data); 00098 return NULL; 00099 } 00100 /*sort the data by coordinate*/ 00101 result = g_list_sort(result, approx_coordinate_density_sorter); 00102 GList* point; 00103 double *v; 00104 int i; 00105 for(i=0, point=result; i<(*N); i++, point = g_list_next(point)) { 00106 if(unlikely((v = g_hash_table_lookup((GHashTable*)(point->data), "x")) == NULL)) { 00107 fprintf(stderr, "INTERNAL ERROR: a density function point's x coordinate was NULL!\n"); 00108 } 00109 (*x)[i] = *v; 00110 if(unlikely((v = g_hash_table_lookup((GHashTable*)(point->data), "energy")) == NULL)) { 00111 fprintf(stderr, "INTERNAL ERROR: a density function point's total density was NULL!\n"); 00112 } 00113 data[i] = *v; 00114 } 00115 00116 return data; 00117 }