4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
11 * Copyright (c) 1991-2001, University of Groningen, The Netherlands
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * If you want to redistribute modifications, please consider that
18 * scientific software is very special. Version control is crucial -
19 * bugs must be traceable. We will be happy to consider code for
20 * inclusion in the official distribution, but derived work must not
21 * be called official GROMACS. Details are found in the README & COPYING
22 * files - if they are missing, get the official version at www.gromacs.org.
24 * To help us fund GROMACS development, we humbly ask that you cite
25 * the papers on the package - you can find them in the top README file.
27 * For more info, check our website at http://www.gromacs.org
30 * Getting the Right Output Means no Artefacts in Calculating Stuff
32 static char *SRCID_mdatom_c
= "$Id$";
38 #define ALMOST_ZERO 1e-30
40 t_mdatoms
*atoms2md(FILE *fp
,t_atoms
*atoms
,ivec nFreeze
[],
41 bool bBD
,real delta_t
,real fric
,real tau_t
[],
42 bool bPert
,bool bFree
)
51 snew(md
->massA
,md
->nr
);
52 snew(md
->massB
,md
->nr
);
53 snew(md
->massT
,md
->nr
);
54 snew(md
->invmass
,md
->nr
);
55 snew(md
->chargeA
,md
->nr
);
56 snew(md
->chargeB
,md
->nr
);
57 snew(md
->chargeT
,md
->nr
);
58 snew(md
->resnr
,md
->nr
);
59 snew(md
->typeA
,md
->nr
);
60 snew(md
->typeB
,md
->nr
);
61 snew(md
->ptype
,md
->nr
);
63 snew(md
->cENER
,md
->nr
);
64 snew(md
->cACC
,md
->nr
);
65 snew(md
->cFREEZE
,md
->nr
);
66 snew(md
->cXTC
,md
->nr
);
67 snew(md
->cVCM
,md
->nr
);
68 snew(md
->cORF
,md
->nr
);
69 snew(md
->bPerturbed
,md
->nr
);
76 for(i
=0; (i
<md
->nr
); i
++) {
78 /* Make the mass proportional to the friction coefficient for BD.
79 * This is necessary for the constraint algorithms.
82 md
->massA
[i
] = fric
*delta_t
;
83 md
->massB
[i
] = fric
*delta_t
;
85 fac
= delta_t
/tau_t
[atoms
->atom
[i
].grpnr
[egcTC
]];
86 md
->massA
[i
] = atoms
->atom
[i
].m
*fac
;
87 md
->massB
[i
] = atoms
->atom
[i
].mB
*fac
;
90 md
->massA
[i
] = atoms
->atom
[i
].m
;
91 md
->massB
[i
] = atoms
->atom
[i
].mB
;
93 md
->massT
[i
] = md
->massA
[i
];
94 md
->chargeA
[i
] = atoms
->atom
[i
].q
;
95 md
->chargeB
[i
] = atoms
->atom
[i
].qB
;
96 md
->resnr
[i
] = atoms
->atom
[i
].resnr
;
97 md
->typeA
[i
] = atoms
->atom
[i
].type
;
98 md
->typeB
[i
] = atoms
->atom
[i
].typeB
;
99 md
->ptype
[i
] = atoms
->atom
[i
].ptype
;
100 md
->cTC
[i
] = atoms
->atom
[i
].grpnr
[egcTC
];
101 md
->cENER
[i
] = atoms
->atom
[i
].grpnr
[egcENER
];
102 md
->cACC
[i
] = atoms
->atom
[i
].grpnr
[egcACC
];
103 md
->cFREEZE
[i
] = atoms
->atom
[i
].grpnr
[egcFREEZE
];
104 md
->cXTC
[i
] = atoms
->atom
[i
].grpnr
[egcXTC
];
105 md
->cVCM
[i
] = atoms
->atom
[i
].grpnr
[egcVCM
];
106 md
->cORF
[i
] = atoms
->atom
[i
].grpnr
[egcORFIT
];
107 if (md
->massA
[i
] != 0.0) {
110 if (nFreeze
[g
][XX
] && nFreeze
[g
][YY
] && nFreeze
[g
][ZZ
])
111 /* Set the mass of completely frozen particles to ALMOST_ZERO iso 0
112 to avoid div by zero in lincs or shake.
113 Note that constraints can still move a partially frozen particle. */
114 md
->invmass
[i
] = ALMOST_ZERO
;
115 else if (md
->massT
[i
] == 0)
118 md
->invmass
[i
] = 1.0/md
->massT
[i
];
121 md
->bPerturbed
[i
] = PERTURBED(atoms
->atom
[i
]);
122 if (md
->bPerturbed
[i
])
126 md
->cU1
[i
] = atoms
->atom
[i
].grpnr
[egcUser1
];
127 md
->cU2
[i
] = atoms
->atom
[i
].grpnr
[egcUser2
];
137 fprintf(fp
,"There are %d atoms for free energy perturbation\n",np
);
142 void md2atoms(t_mdatoms
*md
,t_atoms
*atoms
,bool bFree
)
146 snew(atoms
->atom
,md
->nr
);
147 for(i
=0; (i
<md
->nr
); i
++) {
148 atoms
->atom
[i
].m
= md
->massT
[i
];
149 atoms
->atom
[i
].q
= md
->chargeT
[i
];
150 atoms
->atom
[i
].resnr
= md
->resnr
[i
];
151 atoms
->atom
[i
].type
= md
->typeA
[i
];
152 atoms
->atom
[i
].ptype
= md
->ptype
[i
];
153 atoms
->atom
[i
].grpnr
[egcTC
] = md
->cTC
[i
];
154 atoms
->atom
[i
].grpnr
[egcENER
] = md
->cENER
[i
];
155 atoms
->atom
[i
].grpnr
[egcACC
] = md
->cACC
[i
];
156 atoms
->atom
[i
].grpnr
[egcFREEZE
] = md
->cFREEZE
[i
];
157 atoms
->atom
[i
].grpnr
[egcVCM
] = md
->cVCM
[i
];
158 atoms
->atom
[i
].grpnr
[egcXTC
] = md
->cXTC
[i
];
159 atoms
->atom
[i
].grpnr
[egcORFIT
] = md
->cORF
[i
];
161 atoms
->atom
[i
].grpnr
[egcUser1
] = md
->cU1
[i
];
162 atoms
->atom
[i
].grpnr
[egcUser2
] = md
->cU2
[i
];
190 void init_mdatoms(t_mdatoms
*md
,real lambda
,bool bFirst
)
200 /* Only do this loop the first time, or when lambda has changed.
201 * One could also check whether there is any perturbed atom at all,
202 * but if you don't have perturbed atoms, it does not make sense to modify lambda.
203 * In principle this has to be parallellized, although it would mean extra
204 * communication. Basically only the charges are used on other nodes...
206 if (bFirst
|| (lambda0
!= lambda
)) {
207 for(i
=0; (i
<end
); i
++) {
208 if (md
->bPerturbed
[i
] || bFirst
) {
209 md
->massT
[i
]=L1
*md
->massA
[i
]+lambda
*md
->massB
[i
];
210 if (md
->invmass
[i
] > 1.1*ALMOST_ZERO
)
211 md
->invmass
[i
]=1.0/md
->massT
[i
];
212 md
->chargeT
[i
]=L1
*md
->chargeA
[i
]+lambda
*md
->chargeB
[i
];