| 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 | */
 | 
|---|
| 20 | int 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;   // 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,j;        // 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-1], &temperatures[counter-1]);
 | 
|---|
| 70 |     counter++;
 | 
|---|
| 71 |   }
 | 
|---|
| 72 |         // for debugging only: print read values
 | 
|---|
| 73 |         //for(i=0;i<(counter-1);i++) {
 | 
|---|
| 74 |         //      printf("%lg\t%lg\n",time_steps[i],temperatures[i]);
 | 
|---|
| 75 |         //}
 | 
|---|
| 76 |   
 | 
|---|
| 77 |   // discretely integrate over desired frequency range
 | 
|---|
| 78 |         frequency = freq_start;
 | 
|---|
| 79 |         for(j=0;j<(counter-1);j++) {
 | 
|---|
| 80 |                 result = iresult = 0.;
 | 
|---|
| 81 |                 for(i=0;i<(counter-1);i++) {
 | 
|---|
| 82 |                         result += temperatures[i] * cos(frequency * time_steps[i]*gauge);
 | 
|---|
| 83 |                         iresult += temperatures[i] * sin(frequency * time_steps[i]*gauge);
 | 
|---|
| 84 |                 }
 | 
|---|
| 85 |     // NOTE: It is by definition freq over 2*pi, however as the temperature curve counts double (there are two
 | 
|---|
| 86 |     // standstills, one at the perihel one at the aphel!) we insert this factor to make the plots automatically
 | 
|---|
| 87 |     // have the correct frequency! 
 | 
|---|
| 88 |                 printf("%lg\t%lg\t%lg\n",frequency/(2.*2.*M_PI),result/(counter-1),iresult/(counter-1));
 | 
|---|
| 89 |                 frequency += freq_step;
 | 
|---|
| 90 |         }
 | 
|---|
| 91 | 
 | 
|---|
| 92 |         // dis'alloc and end
 | 
|---|
| 93 |         exit(0);
 | 
|---|
| 94 | }
 | 
|---|