|
gimme-alpha 0.1
|
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 }