|
gimme-alpha 0.1
|
00001 /* 00002 ** process-args.c 00003 ** 00004 ** Made by (Johnny Q. Hacker) 00005 ** Login <solarion@borkborkbork> 00006 ** 00007 00008 00009 Copyright (C) 2008 Joseph Pingenot 00010 00011 This program is free software: you can redistribute it and/or modify 00012 it under the terms of the GNU Affero General Public License as published by 00013 the Free Software Foundation, either version 3 of the License, or 00014 (at your option) any later version. 00015 00016 This program is distributed in the hope that it will be useful, 00017 but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 GNU Affero General Public License for more details. 00020 00021 You should have received a copy of the GNU Affero General Public License 00022 along with this program. If not, see <http://www.gnu.org/licenses/>. 00023 00024 ** Started on Thu Sep 25 14:59:20 2008 Johnny Q. Hacker 00025 ** Last update Wed Oct 1 09:22:25 2008 Johnny Q. Hacker 00026 */ 00027 00028 #include <glib.h> 00029 #include <stdlib.h> 00030 #include <stdio.h> 00031 #include <gio/gio.h> 00032 #include <gimmeprogs/process-args.h> 00033 #include <gimmeprogs/argdefaults.h> 00034 #include <libcommon/gimme_alpha_types.h> 00035 00036 extern void program_print_version(FILE* f); 00037 extern void libpostproccalx_print_version(FILE* f); 00038 extern void libnextnano_print_version(FILE* f); 00039 extern void libmodeling_print_version(FILE* f); 00040 extern void libcommon_print_version(FILE* f); 00041 00042 void do_print_version() { 00043 program_print_version(stdout); 00044 libpostproccalx_print_version(stdout); 00045 libnextnano_print_version(stdout); 00046 libmodeling_print_version(stdout); 00047 libcommon_print_version(stdout); 00048 } 00049 00050 /*Should be threadsafe here; we don't need multiple threads processing args!*/ 00051 /*Ep set to an InSb well*/ 00052 static struct args processed_args = {.base_dirs=NULL, .input_gfile=NULL, .no_interface_term=0, .no_efield_term=0, .separate_terms=0, .interfaces=NULL, .instrument_efield_alpha=0, .no_print_integration_error=0, .request_integration_abs_error=REQUESTED_QAG_PRECISION_ABSOLUTE, .request_integration_rel_error=REQUESTED_QAG_PRECISION_RELATIVE, .avg_hh_lh=3, .no_integrate=FALSE, .Ep=23.3, .del_psi2=FALSE, .ifaces_sequences=NULL}; 00053 00054 struct args* process_args(int argc, char* argv[]) { 00055 gchar **interfaces = NULL; 00056 gboolean print_version = FALSE; 00057 gboolean no_avg_hh = FALSE; 00058 gboolean no_avg_lh = FALSE; 00059 int errored=0; 00060 gchar **base_dir_names = NULL; 00061 gchar **sequences = NULL; 00062 GOptionEntry options[] = { 00063 { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_FILENAME_ARRAY, &base_dir_names, "", NULL }, 00064 { "separate", 's', 0, G_OPTION_ARG_NONE, &(processed_args.separate_terms), "Print the alpha terms separately", NULL }, 00065 { "no-interface", 'I', 0, G_OPTION_ARG_NONE, &(processed_args.no_efield_term), "Do not calculate the interface term", NULL }, 00066 { "instrument_efield", 'f', 0, G_OPTION_ARG_NONE, &(processed_args.instrument_efield_alpha), "Instrument the electric field term in the Rashba coefficient, and writes out the alpha_efield_instrumentation_data.pdata file in the current working directory", NULL }, 00067 { "no-electric-field", 'E', 0, G_OPTION_ARG_NONE, &(processed_args.no_interface_term), "Do not calculate the electric field term", NULL }, 00068 { "no-print-integration-error", 'a', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_NONE, &(processed_args.no_print_integration_error), "Do not print estimation of integration error", NULL }, 00069 { "integration-abs-error", 'R', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_DOUBLE, &(processed_args.request_integration_abs_error), "Requested absolute integration error", NULL}, 00070 { "integration-rel-error", 'r', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_DOUBLE, &(processed_args.request_integration_rel_error), "Requested relative integration error", NULL}, 00071 { "version", 'v', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_NONE, &print_version, "Print version information about this program", NULL }, 00072 { "no-hh-in-average", 'H', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_NONE, &no_avg_hh, "Do not use the heavy hole in the averaging of heavy and light holes", NULL }, 00073 { "no-lh-in-average", 'h', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_NONE, &no_avg_lh, "Do not use the light hole in the averaging of heavy and light holes", NULL }, 00074 { "no_integrate", 'N', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_NONE, &(processed_args.no_integrate), "do not perform the electric field integration (for dumping if calling gsl_integration_foo dies catastrophically)", NULL }, 00075 { "Ep", 'p', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_DOUBLE, &(processed_args.Ep), "Ep of the well material", NULL}, 00076 { "method2", '2', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_NONE, &(processed_args.del_psi2), "Use the \"Del |psi|^2\" method to calculate alpha, instead of the default, \"Del Bandterms\" method.", NULL}, 00077 { NULL } 00078 }; 00079 GOptionEntry deprecated_opts[] = { 00080 { "interface", 'i', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_STRING_ARRAY, &interfaces, "Location of discrete interfaces", NULL }, 00081 { "iface-sequence", 'q', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_STRING_ARRAY, &sequences, "Discritized sequence of interfces (from:to), inclusive (i.e. -5:5 means that the materials are continuously varied from -5nm to 5nm)", NULL }, 00082 { NULL } 00083 }; 00084 GOptionContext *ctx; 00085 GOptionGroup *deprecated_group; 00086 ctx = g_option_context_new("- computes the Rashba spin-orbit parameter from the output of a nextnano well calculation."); 00087 deprecated_group = g_option_group_new("deprecated", ARGDEFAULT_DEPRECATED_GROUP_HELPINFO, "Show help about deprecated options", NULL, NULL); 00088 00089 g_option_group_add_entries(deprecated_group, deprecated_opts); 00090 00091 g_option_context_add_main_entries(ctx, options, "Options"); 00092 g_option_context_add_group(ctx, deprecated_group); 00093 00094 //fprintf(stderr, "process_args: about to process args.\n"); 00095 00096 g_option_context_parse(ctx, &argc, &argv, NULL); 00097 00098 if(print_version){ 00099 do_print_version(); 00100 return NULL; 00101 } 00102 if(no_avg_hh) { 00103 processed_args.avg_hh_lh &= (~2); 00104 } 00105 if(no_avg_lh) { 00106 processed_args.avg_hh_lh &= (~1); 00107 } 00108 if(no_avg_hh && no_avg_lh) { 00109 fprintf(stderr, "ERROR: cannot remove BOTH HH and LH from the averaging!\n"); 00110 errored=1; 00111 } 00112 00113 if((processed_args.no_interface_term) && (processed_args.no_efield_term)) { 00114 fprintf(stderr, "ERROR: if you don't want an interface term and you don't want an electric field term, i.e. you don't want any of the Rashba terms, why are you running this program?!\n"); 00115 errored=1; 00116 } 00117 00118 //fprintf(stderr, "process_args: processed args.\n"); 00119 00120 gchar* htext = g_option_context_get_help(ctx, FALSE, NULL); 00121 00122 double *d; 00123 if(interfaces != NULL) { 00124 for(int i=0; interfaces[i] != 0; i++) { 00125 if(unlikely((d = string_to_data(interfaces[i], DOUBLE_TYPE)) == NULL)) { 00126 fprintf(stderr, "ERROR: failed to convert an interface argument (%s) into double-precision number!\n", interfaces[i]); 00127 errored=1; 00128 break; 00129 } 00130 processed_args.interfaces = g_list_append(processed_args.interfaces, d); 00131 } 00132 } 00133 00134 gchar** numbers; 00135 if(sequences != NULL) { 00136 for(int i=0; sequences[i] !=0; i++) { 00137 numbers = g_strsplit(sequences[0], ":", -1); 00138 if(numbers[2] != NULL) { 00139 fprintf(stderr, "ERROR: failed to convert sequence argument (%s) into two double-precision numbers: too many numbers (should be in the form a:b)\n", sequences[i]); 00140 g_strfreev(numbers); 00141 errored=1; 00142 break; 00143 } 00144 if(unlikely((d = string_to_data_x2(numbers[0], numbers[1], DOUBLE_TYPE)) == NULL)) { 00145 fprintf(stderr, "ERROR: failed to convert one of two interface sequence range strings (%s, %s) into double-precision number!\n", numbers[0], numbers[1]); 00146 g_strfreev(numbers); 00147 errored=1; 00148 break; 00149 } 00150 processed_args.ifaces_sequences = g_list_append(processed_args.ifaces_sequences, d); 00151 g_strfreev(numbers); 00152 } 00153 } 00154 00155 //fprintf(stderr, "got help.\n"); 00156 00157 g_option_context_free(ctx); 00158 00159 /*Check to make sure what we want is there.*/ 00160 GFile *bn; 00161 if(base_dir_names != NULL) { 00162 for(int i = 0; base_dir_names[i] != NULL; i++) { 00163 bn = g_file_new_for_commandline_arg(base_dir_names[i]); 00164 processed_args.base_dirs = g_list_append(processed_args.base_dirs, bn); 00165 } 00166 } 00167 if(processed_args.base_dirs == NULL) { 00168 fprintf(stderr, "ERROR: you MUST give at least one base directory\n"); 00169 errored=1; 00170 } 00171 00172 if(errored){ 00173 int errored=0; 00174 printf("%s", htext); 00175 printf("**run with --version for version and compilation information**\n"); 00176 return NULL; 00177 } 00178 00179 return &processed_args; 00180 }