Merge release-4-6 into master
[alexxy/gromacs.git] / src / gromacs / gmxlib / copyrite.c
1 /*
2  *
3  *                This source code is part of
4  *
5  *                 G   R   O   M   A   C   S
6  *
7  *          GROningen MAchine for Chemical Simulations
8  *
9  *                        VERSION 3.2.0
10  * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
11  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
12  * Copyright (c) 2001-2004, The GROMACS development team,
13  * check out http://www.gromacs.org for more information.
14
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License
17  * as published by the Free Software Foundation; either version 2
18  * of the License, or (at your option) any later version.
19  *
20  * If you want to redistribute modifications, please consider that
21  * scientific software is very special. Version control is crucial -
22  * bugs must be traceable. We will be happy to consider code for
23  * inclusion in the official distribution, but derived work must not
24  * be called official GROMACS. Details are found in the README & COPYING
25  * files - if they are missing, get the official version at www.gromacs.org.
26  *
27  * To help us fund GROMACS development, we humbly ask that you cite
28  * the papers on the package - you can find them in the top README file.
29  *
30  * For more info, check our website at http://www.gromacs.org
31  *
32  * And Hey:
33  * GROningen Mixture of Alchemy and Childrens' Stories
34  */
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
38
39 #ifdef GMX_THREAD_MPI
40 #include <thread_mpi.h>
41 #endif
42
43 #ifdef HAVE_LIBMKL
44 #include <mkl.h>
45 #endif
46 #ifdef GMX_FFT_FFTW3
47 #include <fftw3.h>
48 #endif
49
50 /* This file is completely threadsafe - keep it that way! */
51
52 #include <string.h>
53 #include <ctype.h>
54 #include "sysstuff.h"
55 #include "smalloc.h"
56 #include "string2.h"
57 #include "macros.h"
58 #include <time.h>
59 #include "random.h"
60 #include "statutil.h"
61 #include "copyrite.h"
62 #include "strdb.h"
63 #include "futil.h"
64 #include "vec.h"
65 #include "buildinfo.h"
66 #include "gmx_cpuid.h"
67
68 static void pr_two(FILE *out, int c, int i)
69 {
70     if (i < 10)
71     {
72         fprintf(out, "%c0%1d", c, i);
73     }
74     else
75     {
76         fprintf(out, "%c%2d", c, i);
77     }
78 }
79
80 void pr_difftime(FILE *out, double dt)
81 {
82     int        ndays, nhours, nmins, nsecs;
83     gmx_bool   bPrint, bPrinted;
84
85     ndays    = dt/(24*3600);
86     dt       = dt-24*3600*ndays;
87     nhours   = dt/3600;
88     dt       = dt-3600*nhours;
89     nmins    = dt/60;
90     dt       = dt-nmins*60;
91     nsecs    = dt;
92     bPrint   = (ndays > 0);
93     bPrinted = bPrint;
94     if (bPrint)
95     {
96         fprintf(out, "%d", ndays);
97     }
98     bPrint = bPrint || (nhours > 0);
99     if (bPrint)
100     {
101         if (bPrinted)
102         {
103             pr_two(out, 'd', nhours);
104         }
105         else
106         {
107             fprintf(out, "%d", nhours);
108         }
109     }
110     bPrinted = bPrinted || bPrint;
111     bPrint   = bPrint || (nmins > 0);
112     if (bPrint)
113     {
114         if (bPrinted)
115         {
116             pr_two(out, 'h', nmins);
117         }
118         else
119         {
120             fprintf(out, "%d", nmins);
121         }
122     }
123     bPrinted = bPrinted || bPrint;
124     if (bPrinted)
125     {
126         pr_two(out, ':', nsecs);
127     }
128     else
129     {
130         fprintf(out, "%ds", nsecs);
131     }
132     fprintf(out, "\n");
133 }
134
135
136 gmx_bool be_cool(void)
137 {
138     /* Yes, it is bad to check the environment variable every call,
139      * but we dont call this routine often, and it avoids using
140      * a mutex for locking the variable...
141      */
142 #ifdef GMX_COOL_QUOTES
143     return (getenv("GMX_NO_QUOTES") == NULL);
144 #else
145     /*be uncool*/
146     return FALSE;
147 #endif
148 }
149
150 void space(FILE *out, int n)
151 {
152     fprintf(out, "%*s", n, "");
153 }
154
155 static void sp_print(FILE *out, const char *s)
156 {
157     int slen;
158
159     slen = strlen(s);
160     space(out, (80-slen)/2);
161     fprintf(out, "%s\n", s);
162 }
163
164 static void ster_print(FILE *out, const char *s)
165 {
166     int  slen;
167     char buf[128];
168
169     snprintf(buf, 128, ":-)  %s  (-:", s);
170     slen = strlen(buf);
171     space(out, (80-slen)/2);
172     fprintf(out, "%s\n", buf);
173 }
174
175
176 static void pukeit(const char *db, const char *defstring, char *retstring,
177                    int retsize, int *cqnum)
178 {
179     FILE  *fp;
180     char **help;
181     int    i, nhlp;
182     int    seed;
183
184     if (be_cool() && ((fp = low_libopen(db, FALSE)) != NULL))
185     {
186         nhlp = fget_lines(fp, &help);
187         /* for libraries we can use the low-level close routines */
188         ffclose(fp);
189         seed   = time(NULL);
190         *cqnum = nhlp*rando(&seed);
191         if (strlen(help[*cqnum]) >= STRLEN)
192         {
193             help[*cqnum][STRLEN-1] = '\0';
194         }
195         strncpy(retstring, help[*cqnum], retsize);
196         for (i = 0; (i < nhlp); i++)
197         {
198             sfree(help[i]);
199         }
200         sfree(help);
201     }
202     else
203     {
204         strncpy(retstring, defstring, retsize);
205     }
206 }
207
208 void bromacs(char *retstring, int retsize)
209 {
210     int dum;
211
212     pukeit("bromacs.dat",
213            "Groningen Machine for Chemical Simulation",
214            retstring, retsize, &dum);
215 }
216
217 void cool_quote(char *retstring, int retsize, int *cqnum)
218 {
219     char *tmpstr;
220     char *s, *ptr;
221     int   tmpcq, *p;
222
223     if (cqnum != NULL)
224     {
225         p = cqnum;
226     }
227     else
228     {
229         p = &tmpcq;
230     }
231
232     /* protect audience from explicit lyrics */
233     snew(tmpstr, retsize+1);
234     pukeit("gurgle.dat", "Thanx for Using GROMACS - Have a Nice Day",
235            tmpstr, retsize-2, p);
236
237     if ((ptr = strchr(tmpstr, '_')) != NULL)
238     {
239         *ptr = '\0';
240         ptr++;
241         sprintf(retstring, "\"%s\" %s", tmpstr, ptr);
242     }
243     else
244     {
245         strcpy(retstring, tmpstr);
246     }
247     sfree(tmpstr);
248 }
249
250 void CopyRight(FILE *out, const char *szProgram)
251 {
252     static const char * CopyrightText[] = {
253         "Written by Emile Apol, Rossen Apostolov, Herman J.C. Berendsen,",
254         "Aldert van Buuren, Pär Bjelkmar, Rudi van Drunen, Anton Feenstra, ",
255         "Gerrit Groenhof, Peter Kasson, Per Larsson, Pieter Meulenhoff, ",
256         "Teemu Murtola, Szilard Pall, Sander Pronk, Roland Schulz, ",
257         "Michael Shirts, Alfons Sijbers, Peter Tieleman,\n",
258         "Berk Hess, David van der Spoel, and Erik Lindahl.\n",
259         "Copyright (c) 1991-2000, University of Groningen, The Netherlands.",
260         "Copyright (c) 2001-2010, The GROMACS development team at",
261         "Uppsala University & The Royal Institute of Technology, Sweden.",
262         "check out http://www.gromacs.org for more information.\n"
263     };
264
265     static const char * LicenseText[] = {
266         "This program is free software; you can redistribute it and/or",
267         "modify it under the terms of the GNU Lesser General Public License",
268         "as published by the Free Software Foundation; either version 2.1",
269         "of the License, or (at your option) any later version."
270     };
271
272     /* Dont change szProgram arbitrarily - it must be argv[0], i.e. the
273      * name of a file. Otherwise, we won't be able to find the library dir.
274      */
275 #define NCR (int)asize(CopyrightText)
276 /* TODO: Is this exception still needed? */
277 #ifdef GMX_FAHCORE
278 #define NLICENSE 0 /*FAH has an exception permission from GPL to allow digital signatures in Gromacs*/
279 #else
280 #define NLICENSE (int)asize(LicenseText)
281 #endif
282
283     char buf[256], tmpstr[1024];
284     int  i;
285
286 #ifdef GMX_FAHCORE
287     set_program_name("Gromacs");
288 #else
289     set_program_name(szProgram);
290 #endif
291
292     ster_print(out, "G  R  O  M  A  C  S");
293     fprintf(out, "\n");
294
295     bromacs(tmpstr, 1023);
296     sp_print(out, tmpstr);
297     fprintf(out, "\n");
298
299     ster_print(out, GromacsVersion());
300     fprintf(out, "\n");
301
302     /* fprintf(out,"\n");*/
303
304     /* sp_print(out,"PLEASE NOTE: THIS IS A BETA VERSION\n");
305
306        fprintf(out,"\n"); */
307
308     for (i = 0; (i < NCR); i++)
309     {
310         sp_print(out, CopyrightText[i]);
311     }
312     for (i = 0; (i < NLICENSE); i++)
313     {
314         sp_print(out, LicenseText[i]);
315     }
316
317     fprintf(out, "\n");
318
319     snprintf(buf, 256, "%s", Program());
320 #ifdef GMX_DOUBLE
321     strcat(buf, " (double precision)");
322 #endif
323     ster_print(out, buf);
324     fprintf(out, "\n");
325 }
326
327
328 void thanx(FILE *fp)
329 {
330     char cq[1024];
331     int  cqnum;
332
333     /* protect the audience from suggestive discussions */
334     cool_quote(cq, 1023, &cqnum);
335
336     if (be_cool())
337     {
338         fprintf(fp, "\ngcq#%d: %s\n\n", cqnum, cq);
339     }
340     else
341     {
342         fprintf(fp, "\n%s\n\n", cq);
343     }
344 }
345
346 typedef struct {
347     const char *key;
348     const char *author;
349     const char *title;
350     const char *journal;
351     int         volume, year;
352     const char *pages;
353 } t_citerec;
354
355 void please_cite(FILE *fp, const char *key)
356 {
357     static const t_citerec citedb[] = {
358         { "Allen1987a",
359           "M. P. Allen and D. J. Tildesley",
360           "Computer simulation of liquids",
361           "Oxford Science Publications",
362           1, 1987, "1" },
363         { "Berendsen95a",
364           "H. J. C. Berendsen, D. van der Spoel and R. van Drunen",
365           "GROMACS: A message-passing parallel molecular dynamics implementation",
366           "Comp. Phys. Comm.",
367           91, 1995, "43-56" },
368         { "Berendsen84a",
369           "H. J. C. Berendsen, J. P. M. Postma, A. DiNola and J. R. Haak",
370           "Molecular dynamics with coupling to an external bath",
371           "J. Chem. Phys.",
372           81, 1984, "3684-3690" },
373         { "Ryckaert77a",
374           "J. P. Ryckaert and G. Ciccotti and H. J. C. Berendsen",
375           "Numerical Integration of the Cartesian Equations of Motion of a System with Constraints; Molecular Dynamics of n-Alkanes",
376           "J. Comp. Phys.",
377           23, 1977, "327-341" },
378         { "Miyamoto92a",
379           "S. Miyamoto and P. A. Kollman",
380           "SETTLE: An Analytical Version of the SHAKE and RATTLE Algorithms for Rigid Water Models",
381           "J. Comp. Chem.",
382           13, 1992, "952-962" },
383         { "Cromer1968a",
384           "D. T. Cromer & J. B. Mann",
385           "X-ray scattering factors computed from numerical Hartree-Fock wave functions",
386           "Acta Cryst. A",
387           24, 1968, "321" },
388         { "Barth95a",
389           "E. Barth and K. Kuczera and B. Leimkuhler and R. D. Skeel",
390           "Algorithms for Constrained Molecular Dynamics",
391           "J. Comp. Chem.",
392           16, 1995, "1192-1209" },
393         { "Essmann95a",
394           "U. Essmann, L. Perera, M. L. Berkowitz, T. Darden, H. Lee and L. G. Pedersen ",
395           "A smooth particle mesh Ewald method",
396           "J. Chem. Phys.",
397           103, 1995, "8577-8592" },
398         { "Torda89a",
399           "A. E. Torda and R. M. Scheek and W. F. van Gunsteren",
400           "Time-dependent distance restraints in molecular dynamics simulations",
401           "Chem. Phys. Lett.",
402           157, 1989, "289-294" },
403         { "Tironi95a",
404           "I. G. Tironi and R. Sperb and P. E. Smith and W. F. van Gunsteren",
405           "Generalized reaction field method for molecular dynamics simulations",
406           "J. Chem. Phys",
407           102, 1995, "5451-5459" },
408         { "Hess97a",
409           "B. Hess and H. Bekker and H. J. C. Berendsen and J. G. E. M. Fraaije",
410           "LINCS: A Linear Constraint Solver for molecular simulations",
411           "J. Comp. Chem.",
412           18, 1997, "1463-1472" },
413         { "Hess2008a",
414           "B. Hess",
415           "P-LINCS: A Parallel Linear Constraint Solver for molecular simulation",
416           "J. Chem. Theory Comput.",
417           4, 2008, "116-122" },
418         { "Hess2008b",
419           "B. Hess and C. Kutzner and D. van der Spoel and E. Lindahl",
420           "GROMACS 4: Algorithms for highly efficient, load-balanced, and scalable molecular simulation",
421           "J. Chem. Theory Comput.",
422           4, 2008, "435-447" },
423         { "Hub2010",
424           "J. S. Hub, B. L. de Groot and D. van der Spoel",
425           "g_wham - A free weighted histogram analysis implementation including robust error and autocorrelation estimates",
426           "J. Chem. Theory Comput.",
427           6, 2010, "3713-3720"},
428         { "In-Chul99a",
429           "Y. In-Chul and M. L. Berkowitz",
430           "Ewald summation for systems with slab geometry",
431           "J. Chem. Phys.",
432           111, 1999, "3155-3162" },
433         { "DeGroot97a",
434           "B. L. de Groot and D. M. F. van Aalten and R. M. Scheek and A. Amadei and G. Vriend and H. J. C. Berendsen",
435           "Prediction of Protein Conformational Freedom From Distance Constrains",
436           "Proteins",
437           29, 1997, "240-251" },
438         { "Spoel98a",
439           "D. van der Spoel and P. J. van Maaren and H. J. C. Berendsen",
440           "A systematic study of water models for molecular simulation. Derivation of models optimized for use with a reaction-field.",
441           "J. Chem. Phys.",
442           108, 1998, "10220-10230" },
443         { "Wishart98a",
444           "D. S. Wishart and A. M. Nip",
445           "Protein Chemical Shift Analysis: A Practical Guide",
446           "Biochem. Cell Biol.",
447           76, 1998, "153-163" },
448         { "Maiorov95",
449           "V. N. Maiorov and G. M. Crippen",
450           "Size-Independent Comparison of Protein Three-Dimensional Structures",
451           "PROTEINS: Struct. Funct. Gen.",
452           22, 1995, "273-283" },
453         { "Feenstra99",
454           "K. A. Feenstra and B. Hess and H. J. C. Berendsen",
455           "Improving Efficiency of Large Time-scale Molecular Dynamics Simulations of Hydrogen-rich Systems",
456           "J. Comput. Chem.",
457           20, 1999, "786-798" },
458         { "Timneanu2004a",
459           "N. Timneanu and C. Caleman and J. Hajdu and D. van der Spoel",
460           "Auger Electron Cascades in Water and Ice",
461           "Chem. Phys.",
462           299, 2004, "277-283" },
463         { "Pascal2011a",
464           "T. A. Pascal and S. T. Lin and W. A. Goddard III",
465           "Thermodynamics of liquids: standard molar entropies and heat capacities of common solvents from 2PT molecular dynamics",
466           "Phys. Chem. Chem. Phys.",
467           13, 2011, "169-181" },
468         { "Caleman2011b",
469           "C. Caleman and P. J. van Maaren and M. Hong and J. S. Hub and L. T. da Costa and D. van der Spoel",
470           "Force Field Benchmark of Organic Liquids: Density, Enthalpy of Vaporization, Heat Capacities, Surface Tension, Isothermal Compressibility, Volumetric Expansion Coefficient, and Dielectric Constant",
471           "J. Chem. Theo. Comp.",
472           8, 2012, "61" },
473         { "Lindahl2001a",
474           "E. Lindahl and B. Hess and D. van der Spoel",
475           "GROMACS 3.0: A package for molecular simulation and trajectory analysis",
476           "J. Mol. Mod.",
477           7, 2001, "306-317" },
478         { "Wang2001a",
479           "J. Wang and W. Wang and S. Huo and M. Lee and P. A. Kollman",
480           "Solvation model based on weighted solvent accessible surface area",
481           "J. Phys. Chem. B",
482           105, 2001, "5055-5067" },
483         { "Eisenberg86a",
484           "D. Eisenberg and A. D. McLachlan",
485           "Solvation energy in protein folding and binding",
486           "Nature",
487           319, 1986, "199-203" },
488         { "Eisenhaber95",
489           "Frank Eisenhaber and Philip Lijnzaad and Patrick Argos and Chris Sander and Michael Scharf",
490           "The Double Cube Lattice Method: Efficient Approaches to Numerical Integration of Surface Area and Volume and to Dot Surface Contouring of Molecular Assemblies",
491           "J. Comp. Chem.",
492           16, 1995, "273-284" },
493         { "Hess2002",
494           "B. Hess, H. Saint-Martin and H.J.C. Berendsen",
495           "Flexible constraints: an adiabatic treatment of quantum degrees of freedom, with application to the flexible and polarizable MCDHO model for water",
496           "J. Chem. Phys.",
497           116, 2002, "9602-9610" },
498         { "Hetenyi2002b",
499           "Csaba Hetenyi and David van der Spoel",
500           "Efficient docking of peptides to proteins without prior knowledge of the binding site.",
501           "Prot. Sci.",
502           11, 2002, "1729-1737" },
503         { "Hess2003",
504           "B. Hess and R.M. Scheek",
505           "Orientation restraints in molecular dynamics simulations using time and ensemble averaging",
506           "J. Magn. Res.",
507           164, 2003, "19-27" },
508         { "Rappe1991a",
509           "A. K. Rappe and W. A. Goddard III",
510           "Charge Equillibration for Molecular Dynamics Simulations",
511           "J. Phys. Chem.",
512           95, 1991, "3358-3363" },
513         { "Mu2005a",
514           "Y. Mu, P. H. Nguyen and G. Stock",
515           "Energy landscape of a small peptide revelaed by dihedral angle principal component analysis",
516           "Prot. Struct. Funct. Bioinf.",
517           58, 2005, "45-52" },
518         { "Okabe2001a",
519           "T. Okabe and M. Kawata and Y. Okamoto and M. Mikami",
520           "Replica-exchange {M}onte {C}arlo method for the isobaric-isothermal ensemble",
521           "Chem. Phys. Lett.",
522           335, 2001, "435-439" },
523         { "Hukushima96a",
524           "K. Hukushima and K. Nemoto",
525           "Exchange Monte Carlo Method and Application to Spin Glass Simulations",
526           "J. Phys. Soc. Jpn.",
527           65, 1996, "1604-1608" },
528         { "Tropp80a",
529           "J. Tropp",
530           "Dipolar Relaxation and Nuclear Overhauser effects in nonrigid molecules: The effect of fluctuating internuclear distances",
531           "J. Chem. Phys.",
532           72, 1980, "6035-6043" },
533         { "Bultinck2002a",
534           "P. Bultinck and W. Langenaeker and P. Lahorte and F. De Proft and P. Geerlings and M. Waroquier and J. P. Tollenaere",
535           "The electronegativity equalization method I: Parametrization and validation for atomic charge calculations",
536           "J. Phys. Chem. A",
537           106, 2002, "7887-7894" },
538         { "Yang2006b",
539           "Q. Y. Yang and K. A. Sharp",
540           "Atomic charge parameters for the finite difference Poisson-Boltzmann method using electronegativity neutralization",
541           "J. Chem. Theory Comput.",
542           2, 2006, "1152-1167" },
543         { "Spoel2005a",
544           "D. van der Spoel, E. Lindahl, B. Hess, G. Groenhof, A. E. Mark and H. J. C. Berendsen",
545           "GROMACS: Fast, Flexible and Free",
546           "J. Comp. Chem.",
547           26, 2005, "1701-1719" },
548         { "Spoel2006b",
549           "D. van der Spoel, P. J. van Maaren, P. Larsson and N. Timneanu",
550           "Thermodynamics of hydrogen bonding in hydrophilic and hydrophobic media",
551           "J. Phys. Chem. B",
552           110, 2006, "4393-4398" },
553         { "Spoel2006d",
554           "D. van der Spoel and M. M. Seibert",
555           "Protein folding kinetics and thermodynamics from atomistic simulations",
556           "Phys. Rev. Letters",
557           96, 2006, "238102" },
558         { "Palmer94a",
559           "B. J. Palmer",
560           "Transverse-current autocorrelation-function calculations of the shear viscosity for molecular liquids",
561           "Phys. Rev. E",
562           49, 1994, "359-366" },
563         { "Bussi2007a",
564           "G. Bussi, D. Donadio and M. Parrinello",
565           "Canonical sampling through velocity rescaling",
566           "J. Chem. Phys.",
567           126, 2007, "014101" },
568         { "Hub2006",
569           "J. S. Hub and B. L. de Groot",
570           "Does CO2 permeate through Aquaporin-1?",
571           "Biophys. J.",
572           91, 2006, "842-848" },
573         { "Hub2008",
574           "J. S. Hub and B. L. de Groot",
575           "Mechanism of selectivity in aquaporins and aquaglyceroporins",
576           "PNAS",
577           105, 2008, "1198-1203" },
578         { "Friedrich2009",
579           "M. S. Friedrichs, P. Eastman, V. Vaidyanathan, M. Houston, S. LeGrand, A. L. Beberg, D. L. Ensign, C. M. Bruns, and V. S. Pande",
580           "Accelerating Molecular Dynamic Simulation on Graphics Processing Units",
581           "J. Comp. Chem.",
582           30, 2009, "864-872" },
583         { "Engin2010",
584           "O. Engin, A. Villa, M. Sayar and B. Hess",
585           "Driving Forces for Adsorption of Amphiphilic Peptides to Air-Water Interface",
586           "J. Phys. Chem. B",
587           114, 2010, "11093" },
588         { "Fritsch12",
589           "S. Fritsch, C. Junghans and K. Kremer",
590           "Adaptive molecular simulation study on structure formation of toluene around C60 using Gromacs",
591           "J. Chem. Theo. Comp.",
592           8, 2012, "398" },
593         { "Junghans10",
594           "C. Junghans and S. Poblete",
595           "A reference implementation of the adaptive resolution scheme in ESPResSo",
596           "Comp. Phys. Comm.",
597           181, 2010, "1449" },
598         { "Wang2010",
599           "H. Wang, F. Dommert, C.Holm",
600           "Optimizing working parameters of the smooth particle mesh Ewald algorithm in terms of accuracy and efficiency",
601           "J. Chem. Phys. B",
602           133, 2010, "034117" },
603         { "Sugita1999a",
604           "Y. Sugita, Y. Okamoto",
605           "Replica-exchange molecular dynamics method for protein folding",
606           "Chem. Phys. Lett.",
607           314, 1999, "141-151" },
608         { "Kutzner2011",
609           "C. Kutzner and J. Czub and H. Grubmuller",
610           "Keep it Flexible: Driving Macromolecular Rotary Motions in Atomistic Simulations with GROMACS",
611           "J. Chem. Theory Comput.",
612           7, 2011, "1381-1393" },
613         { "Hoefling2011",
614           "M. Hoefling, N. Lima, D. Haenni, C.A.M. Seidel, B. Schuler, H. Grubmuller",
615           "Structural Heterogeneity and Quantitative FRET Efficiency Distributions of Polyprolines through a Hybrid Atomistic Simulation and Monte Carlo Approach",
616           "PLoS ONE",
617           6, 2011, "e19791" },
618         { "Hockney1988",
619           "R. W. Hockney and J. W. Eastwood",
620           "Computer simulation using particles",
621           "IOP, Bristol",
622           1, 1988, "1" },
623         { "Ballenegger2012",
624           "V. Ballenegger, J.J. Cerda, and C. Holm",
625           "How to Convert SPME to P3M: Influence Functions and Error Estimates",
626           "J. Chem. Theory Comput.",
627           8, 2012, "936-947" },
628         { "Garmay2012",
629           "Garmay Yu, Shvetsov A, Karelov D, Lebedev D, Radulescu A, Petukhov M, Isaev-Ivanov V",
630           "Correlated motion of protein subdomains and large-scale conformational flexibility of RecA protein filament",
631           "Journal of Physics: Conference Series",
632           340, 2012, "012094" }
633     };
634 #define NSTR (int)asize(citedb)
635
636     int   j, index;
637     char *author;
638     char *title;
639 #define LINE_WIDTH 79
640
641     if (fp == NULL)
642     {
643         return;
644     }
645
646     for (index = 0; (index < NSTR) && (strcmp(citedb[index].key, key) != 0); index++)
647     {
648         ;
649     }
650
651     fprintf(fp, "\n++++ PLEASE READ AND CITE THE FOLLOWING REFERENCE ++++\n");
652     if (index < NSTR)
653     {
654         /* Insert newlines */
655         author = wrap_lines(citedb[index].author, LINE_WIDTH, 0, FALSE);
656         title  = wrap_lines(citedb[index].title, LINE_WIDTH, 0, FALSE);
657         fprintf(fp, "%s\n%s\n%s %d (%d) pp. %s\n",
658                 author, title, citedb[index].journal,
659                 citedb[index].volume, citedb[index].year,
660                 citedb[index].pages);
661         sfree(author);
662         sfree(title);
663     }
664     else
665     {
666         fprintf(fp, "Entry %s not found in citation database\n", key);
667     }
668     fprintf(fp, "-------- -------- --- Thank You --- -------- --------\n\n");
669     fflush(fp);
670 }
671
672 #ifdef GMX_GIT_VERSION_INFO
673 /* Version information generated at compile time. */
674 #include "gromacs/utility/gitversion.h"
675 #else
676 /* Fall back to statically defined version. */
677 static const char _gmx_ver_string[] = "VERSION " VERSION;
678 #endif
679
680 const char *GromacsVersion()
681 {
682     return _gmx_ver_string;
683 }
684
685 void gmx_print_version_info_gpu(FILE *fp);
686
687 void gmx_print_version_info(FILE *fp)
688 {
689     fprintf(fp, "Gromacs version:    %s\n", _gmx_ver_string);
690 #ifdef GMX_GIT_VERSION_INFO
691     fprintf(fp, "GIT SHA1 hash:      %s\n", _gmx_full_git_hash);
692     /* Only print out the branch information if present.
693      * The generating script checks whether the branch point actually
694      * coincides with the hash reported above, and produces an empty string
695      * in such cases. */
696     if (_gmx_central_base_hash[0] != 0)
697     {
698         fprintf(fp, "Branched from:      %s\n", _gmx_central_base_hash);
699     }
700 #endif
701
702 #ifdef GMX_DOUBLE
703     fprintf(fp, "Precision:          double\n");
704 #else
705     fprintf(fp, "Precision:          single\n");
706 #endif
707     fprintf(fp, "Memory model:       %lu bit\n", 8*sizeof(void *));
708
709 #ifdef GMX_THREAD_MPI
710     fprintf(fp, "MPI library:        thread_mpi\n");
711 #elif defined(GMX_MPI)
712     fprintf(fp, "MPI library:        MPI\n");
713 #else
714     fprintf(fp, "MPI library:        none\n");
715 #endif
716 #ifdef GMX_OPENMP
717     fprintf(fp, "OpenMP support:     enabled\n");
718 #else
719     fprintf(fp, "OpenMP support:     disabled\n");
720 #endif
721 #ifdef GMX_GPU
722     fprintf(fp, "GPU support:        enabled\n");
723 #else
724     fprintf(fp, "GPU support:        disabled\n");
725 #endif
726     /* A preprocessor trick to avoid duplicating logic from vec.h */
727 #define gmx_stringify2(x) #x
728 #define gmx_stringify(x) gmx_stringify2(x)
729     fprintf(fp, "invsqrt routine:    %s\n", gmx_stringify(gmx_invsqrt(x)));
730     fprintf(fp, "CPU acceleration:   %s\n", GMX_CPU_ACCELERATION_STRING);
731
732     /* TODO: Would be nicer to wrap this in a gmx_fft_version() call, but
733      * since that is currently in mdlib, can wait for master. */
734 #ifdef GMX_FFT_FFTPACK
735     fprintf(fp, "FFT library:        fftpack (built-in)\n");
736 #elif defined(GMX_FFT_FFTW3) && defined(GMX_NATIVE_WINDOWS)
737     fprintf(fp, "FFT library:        %s\n", "fftw3");
738 #elif defined(GMX_FFT_FFTW3) && defined(GMX_DOUBLE)
739     fprintf(fp, "FFT library:        %s\n", fftw_version);
740 #elif defined(GMX_FFT_FFTW3)
741     fprintf(fp, "FFT library:        %s\n", fftwf_version);
742 #elif defined(GMX_FFT_MKL)
743     fprintf(fp, "FFT library:        MKL\n");
744 #else
745     fprintf(fp, "FFT library:        unknown\n");
746 #endif
747 #ifdef GMX_LARGEFILES
748     fprintf(fp, "Large file support: enabled\n");
749 #else
750     fprintf(fp, "Large file support: disabled\n");
751 #endif
752 #ifdef HAVE_RDTSCP
753     fprintf(fp, "RDTSCP usage:       enabled\n");
754 #else
755     fprintf(fp, "RDTSCP usage:       disabled\n");
756 #endif
757
758     fprintf(fp, "Built on:           %s\n", BUILD_TIME);
759     fprintf(fp, "Built by:           %s\n", BUILD_USER);
760     fprintf(fp, "Build OS/arch:      %s\n", BUILD_HOST);
761     fprintf(fp, "Build CPU vendor:   %s\n", BUILD_CPU_VENDOR);
762     fprintf(fp, "Build CPU brand:    %s\n", BUILD_CPU_BRAND);
763     fprintf(fp, "Build CPU family:   %d   Model: %d   Stepping: %d\n",
764             BUILD_CPU_FAMILY, BUILD_CPU_MODEL, BUILD_CPU_STEPPING);
765     /* TODO: The below strings can be quite long, so it would be nice to wrap
766      * them. Can wait for later, as the master branch has ready code to do all
767      * that. */
768     fprintf(fp, "Build CPU features: %s\n", BUILD_CPU_FEATURES);
769     fprintf(fp, "C compiler:         %s\n", BUILD_C_COMPILER);
770     fprintf(fp, "C compiler flags:   %s\n", BUILD_CFLAGS);
771     if (BUILD_CXX_COMPILER[0] != '\0')
772     {
773         fprintf(fp, "C++ compiler:       %s\n", BUILD_CXX_COMPILER);
774         fprintf(fp, "C++ compiler flags: %s\n", BUILD_CXXFLAGS);
775     }
776 #ifdef HAVE_LIBMKL
777     /* MKL might be used for LAPACK/BLAS even if FFTs use FFTW, so keep it separate */
778     fprintf(fp, "Linked with Intel MKL version %s.%s.%s.\n",
779             __INTEL_MKL__, __INTEL_MKL_MINOR__, __INTEL_MKL_UPDATE__);
780 #endif
781 #ifdef GMX_GPU
782     gmx_print_version_info_gpu(fp);
783 #endif
784
785 }