3 * This source code is part of
7 * GROningen MAchine for Chemical Simulations
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.
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.
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.
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.
30 * For more info, check our website at http://www.gromacs.org
33 * Green Red Orange Magenta Azure Cyan Skyblue
47 #include "gmx_fatal.h"
62 int gmx_nmens(int argc
,char *argv
[])
64 const char *desc
[] = {
65 "[TT]g_nmens[tt] generates an ensemble around an average structure",
66 "in a subspace which is defined by a set of normal modes (eigenvectors).",
67 "The eigenvectors are assumed to be mass-weighted.",
68 "The position along each eigenvector is randomly taken from a Gaussian",
69 "distribution with variance kT/eigenvalue.[PAR]",
70 "By default the starting eigenvector is set to 7, since the first six",
71 "normal modes are the translational and rotational degrees of freedom."
73 static int nstruct
=100,first
=7,last
=-1,seed
=-1;
74 static real temp
=300.0;
76 { "-temp", FALSE
, etREAL
, {&temp
},
77 "Temperature in Kelvin" },
78 { "-seed", FALSE
, etINT
, {&seed
},
79 "Random seed, -1 generates a seed from time and pid" },
80 { "-num", FALSE
, etINT
, {&nstruct
},
81 "Number of structures to generate" },
82 { "-first", FALSE
, etINT
, {&first
},
83 "First eigenvector to use (-1 is select)" },
84 { "-last", FALSE
, etINT
, {&last
},
85 "Last eigenvector to use (-1 is till the last)" }
94 rvec
*xtop
,*xref
,*xav
,*xout1
,*xout2
;
95 gmx_bool bDMR
,bDMA
,bFit
;
99 real
*eigval
,totmass
,*invsqrtm
,t
,disp
;
101 char *grpname
,title
[STRLEN
];
102 const char *indexfile
;
104 int nout
,*iout
,noutvec
,*outvec
;
106 real rfac
,invfr
,rhalf
,jr
;
111 const unsigned long im
= 0xffff;
112 const unsigned long ia
= 1093;
113 const unsigned long ic
= 18257;
117 { efTRN
, "-v", "eigenvec", ffREAD
},
118 { efXVG
, "-e", "eigenval", ffREAD
},
119 { efTPS
, NULL
, NULL
, ffREAD
},
120 { efNDX
, NULL
, NULL
, ffOPTRD
},
121 { efTRO
, "-o", "ensemble", ffWRITE
}
123 #define NFILE asize(fnm)
125 CopyRight(stderr
,argv
[0]);
126 parse_common_args(&argc
,argv
,PCA_BE_NICE
,
127 NFILE
,fnm
,NPA
,pa
,asize(desc
),desc
,0,NULL
,&oenv
);
129 indexfile
=ftp2fn_null(efNDX
,NFILE
,fnm
);
131 read_eigenvectors(opt2fn("-v",NFILE
,fnm
),&natoms
,&bFit
,
132 &xref
,&bDMR
,&xav
,&bDMA
,&nvec
,&eignr
,&eigvec
,&eigval
);
134 read_tps_conf(ftp2fn(efTPS
,NFILE
,fnm
),title
,&top
,&ePBC
,&xtop
,NULL
,box
,bDMA
);
137 printf("\nSelect an index group of %d elements that corresponds to the eigenvectors\n",natoms
);
138 get_index(atoms
,indexfile
,1,&i
,&index
,&grpname
);
140 gmx_fatal(FARGS
,"you selected a group with %d elements instead of %d",
144 snew(invsqrtm
,natoms
);
146 for(i
=0; (i
<natoms
); i
++)
147 invsqrtm
[i
] = gmx_invsqrt(atoms
->atom
[index
[i
]].m
);
149 for(i
=0; (i
<natoms
); i
++)
157 /* make an index from first to last */
160 for(i
=0; i
<nout
; i
++)
165 printf("Select eigenvectors for output, end your selection with 0\n");
171 if(1 != scanf("%d",&iout
[nout
]))
173 gmx_fatal(FARGS
,"Error reading user input");
176 } while (iout
[nout
]>=0);
180 /* make an index of the eigenvectors which are present */
183 for(i
=0; i
<nout
; i
++)
186 while ((j
<nvec
) && (eignr
[j
]!=iout
[i
]))
188 if ((j
<nvec
) && (eignr
[j
]==iout
[i
]))
191 iout
[noutvec
] = iout
[i
];
196 fprintf(stderr
,"%d eigenvectors selected for output\n",noutvec
);
200 fprintf(stderr
,"Using seed %d and a temperature of %g K\n",seed
,temp
);
203 snew(xout2
,atoms
->nr
);
204 out
=open_trx(ftp2fn(efTRO
,NFILE
,fnm
),"w");
205 jran
= (unsigned long)((real
)im
*rando(&seed
));
206 for(s
=0; s
<nstruct
; s
++) {
207 for(i
=0; i
<natoms
; i
++)
208 copy_rvec(xav
[i
],xout1
[i
]);
209 for(j
=0; j
<noutvec
; j
++) {
211 /* (r-0.5) n times: var_n = n * var_1 = n/12
212 n=4: var_n = 1/3, so multiply with 3 */
214 rfac
= sqrt(3.0 * BOLTZ
*temp
/eigval
[iout
[j
]]);
216 rfac
= rfac
/(real
)im
;
218 jran
= (jran
*ia
+ic
) & im
;
220 jran
= (jran
*ia
+ic
) & im
;
222 jran
= (jran
*ia
+ic
) & im
;
224 jran
= (jran
*ia
+ic
) & im
;
226 disp
= rfac
* jr
- rhalf
;
228 for(i
=0; i
<natoms
; i
++)
230 xout1
[i
][d
] += disp
*eigvec
[v
][i
][d
]*invsqrtm
[i
];
232 for(i
=0; i
<natoms
; i
++)
233 copy_rvec(xout1
[i
],xout2
[index
[i
]]);
235 write_trx(out
,natoms
,index
,atoms
,0,t
,box
,xout2
,NULL
,NULL
);
236 fprintf(stderr
,"\rGenerated %d structures",s
+1);
238 fprintf(stderr
,"\n");