gimme-alpha 0.1

gimme-density.c

Go to the documentation of this file.
00001 /*
00002 ** gimme-density.c
00003 ** 
00004 ** Made by (Johnny Q. Hacker)
00005 ** Login   <solarion@borkborkbork>
00006 ** 
00007     Copyright (C) 2009 Joseph Pingenot
00008 
00009     This program is free software: you can redistribute it and/or modify
00010     it under the terms of the GNU Affero General Public License as published by
00011     the Free Software Foundation, either version 3 of the License, or
00012     (at your option) any later version.
00013 
00014     This program is distributed in the hope that it will be useful,
00015     but WITHOUT ANY WARRANTY; without even the implied warranty of
00016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017     GNU Affero General Public License for more details.
00018 
00019     You should have received a copy of the GNU Affero General Public License
00020     along with this program.  If not, see <http://www.gnu.org/licenses/>.
00021 
00022 ** Started on  Fri Feb 27 15:03:31 2009 Johnny Q. Hacker
00023 ** Last update Sun May 12 01:17:25 2002 Speed Blue
00024 */
00025 
00026 #include <stdio.h>
00027 #include <glib.h>
00028 #include <gio/gio.h>
00029 #include <stdlib.h>
00030 #include <math.h>
00031 #include <gimmeprogs/process-gimme-density-args.h>
00032 #include <libnextnano/read_nextnano_inputfile.h>
00033 #include <libnextnano/read_nextnano_density.h>
00034 #include <gimmeprogs/argdefaults.h>
00035 #include <libcommon/density.h>
00036 
00037 struct integrand_range {
00038   double xmin, xmax;
00039 };
00040 
00041 /*Faster, if you're not gonna worry about roundoff*/
00042 static gint coordinate_density_sorter(gconstpointer a, gconstpointer b) {
00043   double *c;
00044   double *d;
00045   if((c=g_hash_table_lookup((GHashTable*)a, "x")) == NULL) {
00046     if((d=g_hash_table_lookup((GHashTable*)b, "x")) == NULL) return 0;
00047     return -1;
00048   }else if((d=g_hash_table_lookup((GHashTable*)b, "x")) == NULL) {
00049     return 1;
00050   }
00051   if(*c < *d) return -1;
00052   if(*c > *d) return 1;
00053   return 0;
00054 }
00055 
00056 /*Slower, but gets the answer right if you have roundoff*/
00057 static gint approx_coordinate_density_sorter(gconstpointer a, gconstpointer b) {
00058   double *c;
00059   double *d;
00060   if((c=g_hash_table_lookup((GHashTable*)a, "x")) == NULL) {
00061     if((d=g_hash_table_lookup((GHashTable*)b, "x")) == NULL) return 0;
00062     return -1;
00063   }else if((d=g_hash_table_lookup((GHashTable*)b, "x")) == NULL) {
00064     return 1;
00065   }
00066   //fprintf(stderr, "got x values c=%g(%p) and d=%g(%p) (a=%p,b=%p)\n", *c, c, *d, d, a, b);
00067   if(fabs(*c - *d) < fabs(CLOSE_ENOUGH*(*c))) return 0;
00068   if(*c < *d) return -1;
00069   if(*c > *d) return 1;
00070   return 0;
00071 }
00072 
00073 int main (int argc, char* argv[]) {
00074   g_type_init();
00075   GError *err = NULL;
00076   struct gimme_density_args* arg = process_gimme_density_args(argc, argv);
00077   if(arg == NULL) exit(2);
00078   GList *l = NULL;
00079   struct integrand_range *s;
00080   if(arg->material != NULL) {
00081     printf("MATERIAL-SPECIFIED RANGES NOT IMPLEMENTED YET\n");
00082     exit(1);
00083   }else{
00084     s = (struct integrand_range*)malloc(sizeof(struct integrand_range));
00085     s->xmin = arg->xmin;
00086     s->xmax = arg->xmax;
00087     l = g_list_append(l, s);
00088   }
00089   /*Read in the density information*/
00090   //printf("Got xmin=%g xmax=%g\n", ((struct integrand_range*)(l->data))->xmin, ((struct integrand_range*)(l->data))->xmax);
00091 
00092   GFile *keywords = g_file_get_child(arg->base_dir, "keywords.in");
00093   GFile *database = g_file_get_child(arg->base_dir, "database.in");
00094   GFileInputStream *db_istream = g_file_read(database, NULL, &err);
00095   if(err != NULL) {
00096     fprintf(stderr, "Got error opening database file %s: %s\n", arg->dir, err->message);
00097     exit(1);
00098   }
00099   GHashTable *db = read_nextnano_dbfile(G_INPUT_STREAM(db_istream), &err);
00100   if(err != NULL) {
00101     fprintf(stderr, "Got error reading database file %s: %s\n", arg->dir, err->message);
00102     exit(1);
00103   }
00104   GFile *input_file = g_file_get_child(arg->base_dir, "input_file1.in");
00105   GFileInputStream *input_istream = g_file_read(input_file, NULL, &err);
00106   if(err != NULL) {
00107     fprintf(stderr, "Got error opening input file %s: %s\n", arg->dir, err->message);
00108     exit(1);
00109   }
00110   GHashTable *ifile_hash = read_nextnano_inputfile_stringy(G_INPUT_STREAM(input_istream), &err);
00111 
00112   GList *density_func = read_nextnano_density_el(arg->base_dir, ifile_hash);
00113   if(density_func == NULL) {
00114     fprintf(stderr, "ERROR: error reading in the density function.\n");
00115     exit(4);
00116   }
00117   /*Ensure that we're ordered by point*/
00118   density_func = g_list_sort(density_func, approx_coordinate_density_sorter);
00119   int len = g_list_length(density_func);
00120   struct density_point *dp;
00121   if((dp = (struct density_point*)malloc(len*sizeof(struct density_point))) == NULL) {
00122     fprintf(stderr, "ERROR: failed to allocate enough memory to store the density information\n");
00123     exit(5);
00124   }
00125   int i;
00126   GList *density_pt;
00127   double *v;
00128   for(i=0, density_pt=density_func; i<len; i++, density_pt = g_list_next(density_pt)) {
00129     if(unlikely((v = g_hash_table_lookup((GHashTable*)(density_pt->data), "x")) == NULL)) {
00130       fprintf(stderr, "INTERNAL ERROR: a density function point's x coordinate was NULL!\n");
00131     }
00132     dp[i].x = *v;
00133       if(unlikely((v = g_hash_table_lookup((GHashTable*)(density_pt->data), "total")) == NULL)) {
00134       fprintf(stderr, "INTERNAL ERROR: a density function point's total density was NULL!\n");
00135     }
00136     dp[i].rho = *v;
00137   }
00138   /*
00139   printf("#x\trho\n");
00140   for(i=0; i<len; i++) {
00141     printf("%g\t%g\n", dp[i].x, dp[i].rho);
00142   }
00143   printf("GSL:%g\n", get_density_within_range(
00144   */
00145   printf("%ge11 (cm^-2)\n", get_density_within_range(
00146             ((struct integrand_range*)l->data)->xmin, 
00147             ((struct integrand_range*)l->data)->xmax, 
00148             dp, 
00149             len, 0));
00150   /*
00151   printf("const interpolation: %g\n", get_density_within_range(
00152             ((struct integrand_range*)l->data)->xmin, 
00153             ((struct integrand_range*)l->data)->xmax, 
00154             dp, 
00155             len, 1));
00156   printf("summation: %g\n", get_density_within_range(
00157             ((struct integrand_range*)l->data)->xmin, 
00158             ((struct integrand_range*)l->data)->xmax, 
00159             dp, 
00160             len, 2));
00161   */
00162   return 0;
00163 }
 All Classes Files Functions Variables Enumerations Enumerator Defines