gimme-alpha 0.1

read_nextnano_bandstructure.c

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