source: util/src/VibrAlyzer.c@ 1f4209

Last change on this file since 1f4209 was 1f4209, checked in by Frederik Heber <heber@…>, 17 years ago

util now has a src dir too which was necessary due to Makefile.am problems

  • Property mode set to 100644
File size: 4.3 KB
Line 
1/* Molecular Vibrations Analyser - VibrAlyzer
2 *
3 * This programme fourier transforms input from ESPACK (temperature output)
4 * in order to make the automated retrieval of vibrational frequencies possible.
5*/
6
7#include <stdio.h>
8#include <stdlib.h>
9#include <math.h>
10
11/** Main routine.
12 * The routine needs a file name to be read as the temperature file, and also
13 * a frequency range (start and steps). Standard one-dimensional fourier-trans-
14 * formation via a simple discrete integration over the given values from the
15 * file is performed and the result returned on stdout.
16 * \param argc parameter count
17 * \param **argv array of parameter (array of chars)
18 * \return error code
19*/
20int main(int argc, char **argv)
21{
22 FILE *temperature_file; // file with temperature values
23 double *time_steps, *temperatures; // contain data value pairs
24 int counter; // keeps track of data pairs array size
25 double freq_start, freq_step, freq_end; // frequency start and step width (end determined by number of points in temp.file)
26 char *filename; // filename of temp.file
27 char line[255]; // line buffer for parsing the temperature file
28 int i; // runtime variable
29 double result, iresult; // temporary result value for fourier transformation
30 double frequency; // current frequency during dumb O(N^2) integration
31 double gauge; // conversion to atomic units for time axis
32
33 // Check for needed arguments
34 if (argc < 4) {
35 printf("Molecular Vibrations Analyser - VibrAlyzer\n\n");
36 printf("Usage: %s <time gauge> <freq.step> <temperature file>\n", argv[0]);
37 printf("\t<time gauge>\tConversion factor from step count to atomic time\n");
38 printf("\t<freq.start>\tstart of frequency for fourier transform in atomic units\n");
39 printf("\t<freq.step>\tstep width of frequency for fourier transform in atomic units\n");
40 printf("\t<temperature file>\tfile with (time step, temperature)-pairs\n");
41 exit(1);
42 } else {
43 gauge = atof(argv[1]);
44 freq_start = atof(argv[2]);
45 freq_step = atof(argv[3]);
46 filename = argv[4];
47 }
48
49 // read in file into buffer array
50 temperature_file=fopen(filename, "r");
51 if (temperature_file == NULL) { // check whether file could be opened
52 printf("Could not open temperature file named '%s'!\n", filename);
53 exit(255);
54 }
55 // check number of pairs
56 counter=0;
57 while (fgets(line,255, temperature_file)) {
58 sscanf(line,"%lg %lg", &result, &iresult);
59 counter++;
60 }
61 // ... allocate ...
62 time_steps = malloc(counter*sizeof(double));
63 temperatures = malloc(counter*sizeof(double));
64 fclose(temperature_file);
65 // ... and parse in
66 temperature_file=fopen(filename, "r");
67 counter=0;
68 while (fgets(line,255, temperature_file)) {
69 sscanf(line,"%lg %lg", &time_steps[counter], &temperatures[counter]);
70 //fprintf(stderr, "%lg\t%lg\n", time_steps[counter], temperatures[counter]);
71 counter++;
72 }
73 // auto-set good values for start and step based on step range
74 if ((freq_start == -1) || (freq_step == -1)) {
75 // we cannot detect frequencies above twice a time step and not below half the time range
76 freq_start = 1./(fabs(time_steps[counter-1] - time_steps[0])*gauge);
77 freq_step = ( 1./(fabs(time_steps[1] - time_steps[0])*gauge) - 1./(fabs(time_steps[counter-1] - time_steps[0])*gauge) )/counter;
78 fprintf(stderr, "Using %lg and frequency start and %lg as step size.\n", freq_start/(2.*2.*M_PI), freq_step/(2.*2.*M_PI));
79 } else {
80 freq_start *= (2.*2.*M_PI);
81 freq_step *= (2.*2.*M_PI);
82 }
83
84 // for debugging only: print read values
85 //for(i=0;i<(counter-1);i++) {
86 // printf("%lg\t%lg\n",time_steps[i],temperatures[i]);
87 //}
88
89 printf("#frequency(a.u.)\tcos\tsin");
90 // discretely integrate over desired frequency range
91 freq_end = freq_start+freq_step*counter-1;
92 for(frequency = freq_start;frequency < freq_end;frequency += freq_step) {
93 result = iresult = 0.;
94 for(i=0;i<(counter-1);i++) {
95 result += temperatures[i] * cos(frequency * time_steps[i]*gauge);
96 iresult += temperatures[i] * sin(frequency * time_steps[i]*gauge);
97 }
98 // NOTE: It is by definition freq over 2*pi, however as the temperature curve counts double (there are two
99 // standstills, one at the perihel one at the aphel!) we insert this factor to make the plots automatically
100 // have the correct frequency!
101 printf("%lg\t%lg\t%lg\n",frequency/(2.*2.*M_PI),result/(counter-1),iresult/(counter-1));
102 }
103
104 // dis'alloc and end
105 exit(0);
106}
Note: See TracBrowser for help on using the repository browser.