4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
12 * Copyright (c) 1991-1999
13 * BIOSON Research Institute, Dept. of Biophysical Chemistry
14 * University of Groningen, The Netherlands
17 * GROMACS: A message-passing parallel molecular dynamics implementation
18 * H.J.C. Berendsen, D. van der Spoel and R. van Drunen
19 * Comp. Phys. Comm. 91, 43-56 (1995)
21 * Also check out our WWW page:
22 * http://md.chem.rug.nl/~gmx
27 * GRowing Old MAkes el Chrono Sweat
29 static char *SRCID_g_rdf_c
= "$Id$";
48 int main(int argc
,char *argv
[])
50 static char *desc
[] = {
51 "g_rdf calculates radial distribution functions in different ways.",
52 "The normal method is around a (set of) particle(s), the other method",
53 "is around the center of mass of a set of particles.[PAR]",
54 "If a run input file is supplied ([TT]-s[tt]), exclusions defined",
55 "in that file are taken into account when calculating the rdf.",
56 "The option [TT]-cut[tt] is meant as an alternative way to avoid",
57 "intramolecular peaks in the rdf plot.",
58 "It is however better to supply a run input file with a higher number of",
59 "exclusions. For eg. benzene a topology with nrexcl set to 5",
60 "would eliminate all intramolecular contributions to the rdf.",
61 "Note that all atoms in the selected groups are used, also the ones",
62 "that don't have Lennard-Jones interactions."
64 static bool bCM
=FALSE
;
65 static real cutoff
=0, binwidth
=0.005;
67 { "-bin", FALSE
, etREAL
, {&binwidth
},
69 { "-com", FALSE
, etBOOL
, {&bCM
},
70 "RDF with respect to the center of mass of first group" },
71 { "-cut", FALSE
, etREAL
, {&cutoff
},
72 "Shortest distance (nm) to be considered"},
79 char outf1
[STRLEN
],outf2
[STRLEN
];
81 int natoms
,i
,j
,k
,nbin
,j0
,j1
,n
;
83 unsigned long int sum
;
84 real t
,boxmin
,hbox
,hbox2
,cut2
,r
,r2
,invbinw
,normfac
;
85 real segvol
,spherevol
,prev_spherevol
;
91 atom_id
*index
[3],ix
,jx
,**pairs
;
95 { efTRX
, "-f", NULL
, ffREAD
},
96 { efTPS
, NULL
, NULL
, ffOPTRD
},
97 { efNDX
, NULL
, NULL
, ffOPTRD
},
98 { efXVG
, NULL
, "rdf", ffWRITE
},
100 #define NFILE asize(fnm)
102 CopyRight(stderr
,argv
[0]);
103 parse_common_args(&argc
,argv
,PCA_CAN_VIEW
| PCA_CAN_TIME
,TRUE
,
104 NFILE
,fnm
,NPA
,pa
,asize(desc
),desc
,0,NULL
);
106 fnTPS
= ftp2fn_null(efTPS
,NFILE
,fnm
);
107 fnNDX
= ftp2fn_null(efNDX
,NFILE
,fnm
);
108 if (!fnTPS
&& !fnNDX
)
109 fatal_error(0,"Neither index file nor topology file specified\n"
114 bTop
=read_tps_conf(fnTPS
,title
,&top
,&x
,NULL
,box
,TRUE
);
117 /* get exclusions from topology */
118 excl
=&(top
.atoms
.excl
);
123 get_index(&top
.atoms
,fnNDX
,2,isize
,index
,grpname
);
125 rd_index(fnNDX
,2,isize
,index
,grpname
);
127 natoms
=read_first_x(&status
,ftp2fn(efTRX
,NFILE
,fnm
),&t
,&x
,box
);
129 fatal_error(0,"Could not read coordinates from statusfile\n");
131 /* check with topology */
132 if ( natoms
> top
.atoms
.nr
)
133 fatal_error(0,"Trajectory (%d atoms) does not match topology (%d atoms)",
134 natoms
,top
.atoms
.nr
);
135 /* check with index groups */
137 for (j
=0; j
<isize
[i
]; j
++)
138 if ( index
[i
][j
] >= natoms
)
139 fatal_error(0,"Atom index (%d) in index group %s (%d atoms) larger "
140 "than number of atoms in trajectory (%d atoms)",
141 index
[i
][j
],grpname
[i
],isize
[i
],natoms
);
144 /* move index[0] to index[2] and make 'dummy' index[0] */
146 snew(index
[2],isize
[2]);
147 for(i
=0; i
<isize
[0]; i
++)
148 index
[2][i
]=index
[0][i
];
151 srenew(index
[0],isize
[0]);
152 /* make space for center of mass */
156 /* initialize some handy things */
157 boxmin
= min( norm(box
[XX
]), min( norm(box
[YY
]), norm(box
[ZZ
]) ) );
159 nbin
= (int)(hbox
/ binwidth
) + 1;
160 invbinw
= 1.0 / binwidth
;
164 /* this is THE array */
167 /* make pairlist array for groups and exclusions */
168 snew(pairs
,isize
[0]);
169 snew(npairs
,isize
[0]);
170 for(i
=0; i
<isize
[0]; i
++)
171 snew(pairs
[i
], isize
[1]);
173 for( i
= 0; i
< isize
[0]; i
++) {
175 for( j
= 0; j
< natoms
; j
++)
179 for( j
= excl
->index
[ix
]; j
< excl
->index
[ix
+1]; j
++)
180 bExcl
[excl
->a
[j
]]=TRUE
;
182 for( j
= 0; j
< isize
[1]; j
++) {
188 srenew(pairs
[i
],npairs
[i
]);
193 /* Must init pbc every step because of pressure coupling */
195 rm_pbc(&top
.idef
,natoms
,box
,x
,x
);
198 /* calculate centre of mass */
200 for(i
=0; (i
< isize
[2]); i
++) {
202 rvec_inc(xcom
,x
[ix
]);
204 /* store it in the first 'group' */
205 for(j
=0; (j
<DIM
); j
++)
206 x
[index
[0][0]][j
] = xcom
[j
] / isize
[2];
209 for(i
=0; i
< isize
[0]; i
++) {
211 for(j
=0; j
< npairs
[i
]; j
++) {
213 pbc_dx(x
[ix
],x
[jx
],dx
);
215 if ( r2
<= hbox2
&& r2
> cut2
)
216 count
[(int)(sqrt(r2
)*invbinw
)]++;
219 } while (read_next_x(status
,&t
,natoms
,x
,box
));
220 fprintf(stderr
,"\n");
226 /* Calculate volume of sphere segments */
227 snew(inv_segvol
,nbin
);
229 for(i
=0; (i
<nbin
); i
++) {
231 spherevol
=(4.0/3.0)*M_PI
*r
*r
*r
;
232 segvol
=spherevol
-prev_spherevol
;
233 inv_segvol
[i
]=1.0/segvol
;
234 prev_spherevol
=spherevol
;
237 /* Calculate normalization factor and totals */
239 for(i
=0; i
<nbin
; i
++)
242 normfac
= (4.0/3.0)*M_PI
* r
*r
*r
/ sum
;
244 fp
=xvgropen(ftp2fn(efXVG
,NFILE
,fnm
),"Radial Distribution","r","");
245 fprintf(fp
,"@ subtitle \"%s-%s\"\n",grpname
[0],grpname
[1]);
247 for(i
= 0; i
< nbin
; i
++) {
249 fprintf(fp
, "%10g %10g %10g\n", (i
+0.5)*binwidth
,
250 count
[i
]*inv_segvol
[i
]*normfac
, (real
)sum
*normfac
);
254 xvgr_file(ftp2fn(efXVG
,NFILE
,fnm
),NULL
);