1 /* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
11 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
12 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
13 * Copyright (c) 2001-2004, The GROMACS development team,
14 * check out http://www.gromacs.org for more information.
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
21 * If you want to redistribute modifications, please consider that
22 * scientific software is very special. Version control is crucial -
23 * bugs must be traceable. We will be happy to consider code for
24 * inclusion in the official distribution, but derived work must not
25 * be called official GROMACS. Details are found in the README & COPYING
26 * files - if they are missing, get the official version at www.gromacs.org.
28 * To help us fund GROMACS development, we humbly ask that you cite
29 * the papers on the package - you can find them in the top README file.
31 * For more info, check our website at http://www.gromacs.org
34 * GROwing Monsters And Cloning Shrimps
36 /* This file is completely threadsafe - keep it that way! */
46 #include "gmx_fatal.h"
54 static real
rms_ener(t_energy
*e
,int nsteps
)
56 return sqrt(e
->eav
/nsteps
);
68 int get_ebin_space(t_ebin
*eb
,int nener
,const char *enm
[],const char *unit
)
76 srenew(eb
->e
,eb
->nener
);
77 srenew(eb
->e_sim
,eb
->nener
);
78 srenew(eb
->enm
,eb
->nener
);
79 for(i
=index
; (i
<eb
->nener
); i
++)
86 eb
->e_sim
[i
].esum
= 0;
87 eb
->enm
[i
].name
= strdup(enm
[i
-index
]);
90 eb
->enm
[i
].unit
= strdup(unit
);
94 /* Determine the unit from the longname.
95 * These units should have been defined in ifunc.c
96 * But even better would be if all interactions functions
97 * return energies and all non-interaction function
98 * entries would be removed from the ifunc array.
101 for(f
=0; f
<F_NRE
; f
++)
103 if (strcmp(eb
->enm
[i
].name
,
104 interaction_function
[f
].longname
) == 0)
106 /* Only the terms in this list are not energies */
108 case F_DISRESVIOL
: u
= unit_length
; break;
109 case F_ORIRESDEV
: u
= "obs"; break;
110 case F_TEMP
: u
= unit_temp_K
; break;
111 case F_VTEMP
: u
= unit_temp_K
; break;
113 case F_PRES
: u
= unit_pres_bar
; break;
117 eb
->enm
[i
].unit
= strdup(u
);
124 void add_ebin(t_ebin
*eb
,int index
,int nener
,real ener
[],bool bSum
)
127 double e
,sum
,sigma
,invmm
,diff
;
130 if ((index
+nener
> eb
->nener
) || (index
< 0))
132 gmx_fatal(FARGS
,"%s-%d: Energies out of range: index=%d nener=%d maxener=%d",
133 __FILE__
,__LINE__
,index
,nener
,eb
->nener
);
136 eg
= &(eb
->e
[index
]);
138 for(i
=0; (i
<nener
); i
++)
145 egs
= &(eb
->e_sim
[index
]);
151 for(i
=0; (i
<nener
); i
++)
154 eg
[i
].esum
= ener
[i
];
155 egs
[i
].esum
+= ener
[i
];
160 invmm
= (1.0/(double)m
)/((double)m
+1.0);
162 for(i
=0; (i
<nener
); i
++)
164 /* Value for this component */
167 /* first update sigma, then sum */
168 diff
= eg
[i
].esum
- m
*e
;
169 eg
[i
].eav
+= diff
*diff
*invmm
;
177 void ebin_increase_count(t_ebin
*eb
,bool bSum
)
189 void reset_ebin_sums(t_ebin
*eb
)
193 /* The actual sums are cleared when the next frame is stored */
196 void pr_ebin(FILE *fp
,t_ebin
*eb
,int index
,int nener
,int nperline
,
197 int prmode
,bool bPrHead
)
208 gmx_fatal(FARGS
,"Invalid index in pr_ebin: %d",index
);
216 nener
= index
+ nener
;
218 for(i
=index
; (i
<nener
) && rc
>=0; ) {
222 for(j
=0; (j
<nperline
) && (i
<nener
) && rc
>=0; j
++,i
++)
224 if (strncmp(eb
->enm
[i
].name
,"Pres",4) == 0)
226 /* Print the pressure unit to avoid confusion */
227 sprintf(buf
,"%s (%s)",eb
->enm
[i
].name
,unit_pres_bar
);
228 rc
= fprintf(fp
,"%15s",buf
);
232 rc
= fprintf(fp
,"%15s",eb
->enm
[i
].name
);
238 rc
= fprintf(fp
,"\n");
243 for(j
=0; (j
<nperline
) && (i
<nener
) && rc
>=0; j
++,i
++)
246 case eprNORMAL
: ee
= eb
->e
[i
].e
; break;
247 case eprAVER
: ee
= eb
->e_sim
[i
].esum
/eb
->nsum_sim
; break;
248 default: gmx_fatal(FARGS
,"Invalid print mode %d in pr_ebin",prmode
);
251 rc
= fprintf(fp
," %12.5e",ee
);
255 rc
= fprintf(fp
,"\n");
260 gmx_fatal(FARGS
,"Cannot write to logfile; maybe you are out of quota?");
265 int main(int argc
,char *argv
[])
274 char *ce
[NE
],*ct
[NT
],*cs
[NS
];
275 real e
[NE
],t
[NT
],s
[NS
];
279 for(i
=0; (i
<NE
); i
++) {
281 sprintf(buf
,"e%d",i
);
284 ie
=get_ebin_space(eb
,NE
,ce
);
285 add_ebin(eb
,ie
,NE
,e
,0);
286 for(i
=0; (i
<NS
); i
++) {
288 sprintf(buf
,"s%d",i
);
291 is
=get_ebin_space(eb
,NS
,cs
);
292 add_ebin(eb
,is
,NS
,s
,0);
293 for(i
=0; (i
<NT
); i
++) {
295 sprintf(buf
,"t%d",i
);
298 it
=get_ebin_space(eb
,NT
,ct
);
299 add_ebin(eb
,it
,NT
,t
,0);
302 pr_ebin(stdout
,eb
,0,-1,5,eprNORMAL
,1);
304 printf("Average:\n");
305 pr_ebin(stdout
,eb
,ie
,NE
,5,eprAVER
,1);
306 pr_ebin(stdout
,eb
,is
,NS
,3,eprAVER
,1);
307 pr_ebin(stdout
,eb
,it
,NT
,4,eprAVER
,1);