/****************************************************************************** Module Name : utils.c Module Date : 02/26/2014 Module Auth : Yonggang Li, ygli@theory.issp.ac.cn Description : Contains some utility functions. Others : Error numbers in this file: 12000-12999. Refers to iradina and Corteo. Revision History: Date Rel Ver. Notes ******************************************************************************/ #include "utils.h" /*============================================================================= Function Name : handle_cmd_line_options Description : Handles all command line arguments. Returns a value > 0 in case the main program should not perform a simulation but something else: 1, 2 : nothing; 3 : conversion of material file to element files. Inputs : int argc - number of commonds; char* argv[] - commonds. Outputs : no. Notes : Function call: utils - int print_help_text(); fileio - int display_a_file (char* Filename). =============================================================================*/ int handle_cmd_line_options (int argc, char *argv[]) { int i = 0; int result = 0; while ((++i) < argc) { /* go through command line arguments */ if (strcmp (argv[i], "-h") == 0) { #ifdef MPI_PRALLEL /* MPI=============================================== */ if (my_node == ROOT) print_help_text (); /* MPI=============================================== */ #else print_help_text (); #endif return 1; /* so the main function knows not to proceed */ } if (strcmp (argv[i], "-l") == 0) { if (display_a_file ("license.txt") != 0) printf ("Error: cannot open license.txt\nSee: http://www.gnu.org/licenses/gpl.html\n."); return 2; /* so the main function knows not to proceed */ } /* option for alternative config file name */ if (strcmp (argv[i], "-c") == 0) { i++; if ((i 0 means much,\n"); printf (" < 0 means little\n"); printf (" -n NUMBER sets the maximum number of ions to be simulated to NUMBER.\n"); printf (" This option overrides the setting from the config file. \n"); printf (" -E NUMBER sets the energy of the ions.\n"); printf (" This option overrides the setting from the config file. \n"); printf (" -w wait for return key before exiting \n"); printf (" -m do not simulate, only estimate memory usage (roughly) \n"); printf (" -d print details for memory usage (only useful with -m option) \n"); printf (" -g ID generate status file while running \n"); /*printf(" -conv FILE Converts material based input files to element based input\n"); printf(" file. If the input file is combined, then the output file\n"); printf(" will also be combined and written to FILE. Otherwise, the\n"); printf(" elements are stored in FILE and '.e' is appended to the\n"); printf(" new composition file name.\n"); printf(" -convsep Should only be used with conv. Create separate elements for\n"); printf(" each material.\n"); */ return 0; } /*============================================================================= Function Name : make_int_array Description : Read comma-separated values from string and put them into the int array, which has #count entries. The int array must exist already. Inputs : char* values int count Outputs : int* i_array Notes : no. =============================================================================*/ int make_int_array (char *values, int count, int *i_array) { int i = 1; char *temp; temp = (char*) malloc (sizeof (char)*32); temp = strtok (values, ","); if (strlen(values) < 1) return -12009; /* for safety reasons */ sscanf (temp, "%i", &(i_array[0])); while (((temp=strtok(NULL,","))!=NULL) && (i z */ unit_conversion_factor = ((double) (1.0 / (cell_size_x * cell_size_y * cell_size_z * 1e-21))) / (((double) (num_of_ions)) / (ion_vx * target_size_y * target_size_z * 1e-14)); } else { unit_conversion_factor = 1.0; } return; } /*============================================================================= Function Name : get_leaving_direction Description : Get ions/target atoms leaving direction. Inputs : float vx, float vy, float vz Outputs : leaving_direction Notes : no. =============================================================================*/ int get_leaving_direction (double vx, double vy, double vz) { /* This is necessary. In some extremely rare cases, leaving direction is undefined otherwise --> crash! */ int leaving_direction = 0; if (vx >= 0 && vy >= 0 && vz >= 0) leaving_direction = 0; /* thin film */ if (vx >= 0 && vy < 0 && vz >= 0) leaving_direction = 1; if (vx >= 0 && vy < 0 && vz < 0) leaving_direction = 2; if (vx >= 0 && vy >= 0 && vz < 0) leaving_direction = 3; if (vx < 0 && vy >= 0 && vz >= 0) leaving_direction = 4; if (vx < 0 && vy < 0 && vz >= 0) leaving_direction = 5; if (vx < 0 && vy < 0 && vz < 0) leaving_direction = 6; if (vx < 0 && vy >= 0 && vz < 0) leaving_direction = 7; return leaving_direction; } /*============================================================================= Function Name : write_status_file Description : Create a file that hold status information on im3D. Can be used to monitor im3d's status from another program. Inputs : char* status_text int ion_number Outputs : no. Notes : no. =============================================================================*/ int write_status_file (char *status_text, int ion_number) { FILE *f_pointer; f_pointer = fopen ("ir_state.dat", "w"); if (f_pointer == NULL) { return -12010; } else { fprintf (f_pointer, "im3d %i.%i.%i\n", VERSION, SUBVERSION, SUBSUBVERSION); fprintf (f_pointer, "%s\n", start_id_string); fprintf (f_pointer, "%s\n", status_text); fprintf (f_pointer, "%i\n", ion_number); fclose (f_pointer); return 0; } } /*============================================================================= Function Name : ZBL_and_deri Description : Returns the largest float that is smaller than the fltInput the following code presumes a IEEE754-conform bit-representation of floats it further presumes that int and float have exactly the same bit-length! Inputs : loat* flt_input Outputs : float* flt_output Notes : no. =============================================================================*/ void get_float_one_bit_smaller (float *flt_input, float *flt_output) { int temp; temp = (*((int*) (flt_input))) - 1; (*flt_output) = *((float*) (&(temp))); } /*============================================================================= Function Name : ignoreline Description : Skip to end of line, including end of line character. Inputs : no. Outputs : no. Notes : Corteo: Adapted from corteoutil.c. =============================================================================*/ void ignore_line (FILE *ifp) { int iscan; iscan = fscanf (ifp, "%*[^\n]"); iscan = fscanf (ifp, "%*1[\n]"); if (iscan < 0) printf ("Error: ignore_line_fscanf."); } /*============================================================================= Function Name : d2f Description : Convert double to float while preventing underflow. Inputs : double val Outputs : double val Notes : Corteo: Adapted from corteoutil.c. =============================================================================*/ float d2f (double val) { if (val < 0.0) return -val>7)&0xFFFF] * sqrt_table_exp[((*(unsigned int *)&val)>>23)&0xFF]; } /*============================================================================= Function Name : inv_sqrt Description : 1/sqrt of val is the product of the 1/sqrt of its mantissa and 1/sqrt of its exponent. WARNING: approximate solution, precise to 0.0015%, use when precision is not critical. Inputs : float val Outputs : no. Notes : no. =============================================================================*/ float inv_sqrt (float val) { /* long to int for 32-bit to 64-bit */ if ((*(unsigned int *)&val) == 0) return 1.0f / val; // prevent division by 0 return inv_sqrt_table[((*(unsigned int *)&val)>>7)&0xFFFF] * inv_sqrt_table_exp[((*(unsigned int *)&val)>>23)&0xFF]; } /*============================================================================= Function Name : mat_mul Description : Multiply matrix: a[3*3] * b[3*3] = c[3*3]. Inputs : double a[][3], double b[][3] Outputs : double c[][3] Notes : no. =============================================================================*/ void mat_mul (double a[][3], double b[][3], double c[][3]) { int i, j, k; for (i=0; i<3; i++) { for (j=0; j<3; j++) { c[i][j] = 0; for (k=0; k<3; k++) c[i][j] += a[i][k] * b[k][j]; } } return; } /*============================================================================= Function Name : mat_mul Description : Multiply matrix: a[3*3] * b[3] = c[3]. Inputs : double a[][3], double b[][3] Outputs : double c[][3] Notes : no. =============================================================================*/ void mat_mul2 (double a[][3], double b[], double c[]) { int i, j; for (i=0; i<3; i++) { c[i] = 0; for (j=0; j<3; j++) { c[i] += a[i][j] * b[j]; /* b[i] -> b[j], 01/28/2015 */ } } return; } /*============================================================================= Function Name : dot_product Description : Inputs : double a[] double b[] Outputs : double c Notes : no. =============================================================================*/ double dot_product (double a[], double b[]) { double c = a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; return (c); } /*============================================================================= Function Name : cross_product Description : Inputs : double a[] double b[] Outputs : double c[] Notes : no. =============================================================================*/ void cross_product (double a[], double b[], double c[]) { c[0] = a[1] * b[2] - a[2] * b[1]; c[1] = a[2] * b[0] - a[0] * b[2]; c[2] = a[0] * b[1] - a[1] * b[0]; return; } /*============================================================================= Function Name : copy_int_array Description : Inputs : int a[], b[] int num_elements Outputs : double sum Notes : no. =============================================================================*/ int copy_int_array (int a[], int b[], int num_elements) { int i; for (i=0; i