Revised wording in pdb2gmx.c, hopefully clearer now.
[gromacs/rigid-bodies.git] / src / gmxlib / chargegroup.c
blobc2f8e3fbc030e7e77c70ad6044cd448100363af5
1 /* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
3 *
4 * This source code is part of
5 *
6 * G R O M A C S
7 *
8 * GROningen MAchine for Chemical Simulations
9 *
10 * VERSION 3.2.0
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
33 * And Hey:
34 * GROningen Mixture of Alchemy and Childrens' Stories
36 #ifdef HAVE_CONFIG_H
37 #include <config.h>
38 #endif
40 #include <math.h>
41 #include "sysstuff.h"
42 #include "typedefs.h"
43 #include "vec.h"
44 #include "pbc.h"
45 #include "smalloc.h"
46 #include "gmx_fatal.h"
47 #include "chargegroup.h"
50 void calc_chargegroup_radii(const gmx_mtop_t *mtop,rvec *x,
51 real *rvdw1,real *rvdw2,
52 real *rcoul1,real *rcoul2)
54 real r2v1,r2v2,r2c1,r2c2,r2;
55 int ntype,i,j,mb,m,cg,a_mol,a0,a1,a;
56 gmx_bool *bLJ;
57 gmx_molblock_t *molb;
58 gmx_moltype_t *molt;
59 t_block *cgs;
60 t_atom *atom;
61 rvec cen;
63 r2v1 = 0;
64 r2v2 = 0;
65 r2c1 = 0;
66 r2c2 = 0;
68 ntype = mtop->ffparams.atnr;
69 snew(bLJ,ntype);
70 for(i=0; i<ntype; i++)
72 bLJ[i] = FALSE;
73 for(j=0; j<ntype; j++)
75 if (mtop->ffparams.iparams[i*ntype+j].lj.c6 != 0 ||
76 mtop->ffparams.iparams[i*ntype+j].lj.c12 != 0)
78 bLJ[i] = TRUE;
83 a_mol = 0;
84 for(mb=0; mb<mtop->nmolblock; mb++)
86 molb = &mtop->molblock[mb];
87 molt = &mtop->moltype[molb->type];
88 cgs = &molt->cgs;
89 atom = molt->atoms.atom;
90 for(m=0; m<molb->nmol; m++)
92 for(cg=0; cg<cgs->nr; cg++)
94 a0 = cgs->index[cg];
95 a1 = cgs->index[cg+1];
96 if (a1 - a0 > 1)
98 clear_rvec(cen);
99 for(a=a0; a<a1; a++)
101 rvec_inc(cen,x[a_mol+a]);
103 svmul(1.0/(a1-a0),cen,cen);
104 for(a=a0; a<a1; a++)
106 r2 = distance2(cen,x[a_mol+a]);
107 if (r2 > r2v2 && (bLJ[atom[a].type ] ||
108 bLJ[atom[a].typeB]))
110 if (r2 > r2v1)
112 r2v2 = r2v1;
113 r2v1 = r2;
115 else
117 r2v2 = r2;
120 if (r2 > r2c2 &&
121 (atom[a].q != 0 || atom[a].qB != 0))
123 if (r2 > r2c1)
125 r2c2 = r2c1;
126 r2c1 = r2;
128 else
130 r2c2 = r2;
136 a_mol += molb->natoms_mol;
140 sfree(bLJ);
142 *rvdw1 = sqrt(r2v1);
143 *rvdw2 = sqrt(r2v2);
144 *rcoul1 = sqrt(r2c1);
145 *rcoul2 = sqrt(r2c2);
148 void calc_cgcm(FILE *fplog,int cg0,int cg1,t_block *cgs,
149 rvec pos[],rvec cg_cm[])
151 int icg,k,k0,k1,d;
152 rvec cg;
153 real nrcg,inv_ncg;
154 atom_id *cgindex;
156 #ifdef DEBUG
157 fprintf(fplog,"Calculating centre of geometry for charge groups %d to %d\n",
158 cg0,cg1);
159 #endif
160 cgindex = cgs->index;
162 /* Compute the center of geometry for all charge groups */
163 for(icg=cg0; (icg<cg1); icg++) {
164 k0 = cgindex[icg];
165 k1 = cgindex[icg+1];
166 nrcg = k1-k0;
167 if (nrcg == 1) {
168 copy_rvec(pos[k0],cg_cm[icg]);
170 else {
171 inv_ncg = 1.0/nrcg;
173 clear_rvec(cg);
174 for(k=k0; (k<k1); k++) {
175 for(d=0; (d<DIM); d++)
176 cg[d] += pos[k][d];
178 for(d=0; (d<DIM); d++)
179 cg_cm[icg][d] = inv_ncg*cg[d];
184 void put_charge_groups_in_box(FILE *fplog,int cg0,int cg1,
185 int ePBC,matrix box,t_block *cgs,
186 rvec pos[],rvec cg_cm[])
189 int npbcdim,icg,k,k0,k1,d,e;
190 rvec cg;
191 real nrcg,inv_ncg;
192 atom_id *cgindex;
193 gmx_bool bTric;
195 if (ePBC == epbcNONE)
196 gmx_incons("Calling put_charge_groups_in_box for a system without PBC");
198 #ifdef DEBUG
199 fprintf(fplog,"Putting cgs %d to %d in box\n",cg0,cg1);
200 #endif
201 cgindex = cgs->index;
203 if (ePBC == epbcXY)
204 npbcdim = 2;
205 else
206 npbcdim = 3;
208 bTric = TRICLINIC(box);
210 for(icg=cg0; (icg<cg1); icg++) {
211 /* First compute the center of geometry for this charge group */
212 k0 = cgindex[icg];
213 k1 = cgindex[icg+1];
214 nrcg = k1-k0;
216 if (nrcg == 1) {
217 copy_rvec(pos[k0],cg_cm[icg]);
218 } else {
219 inv_ncg = 1.0/nrcg;
221 clear_rvec(cg);
222 for(k=k0; (k<k1); k++) {
223 for(d=0; d<DIM; d++)
224 cg[d] += pos[k][d];
226 for(d=0; d<DIM; d++)
227 cg_cm[icg][d] = inv_ncg*cg[d];
229 /* Now check pbc for this cg */
230 if (bTric) {
231 for(d=npbcdim-1; d>=0; d--) {
232 while(cg_cm[icg][d] < 0) {
233 for(e=d; e>=0; e--) {
234 cg_cm[icg][e] += box[d][e];
235 for(k=k0; (k<k1); k++)
236 pos[k][e] += box[d][e];
239 while(cg_cm[icg][d] >= box[d][d]) {
240 for(e=d; e>=0; e--) {
241 cg_cm[icg][e] -= box[d][e];
242 for(k=k0; (k<k1); k++)
243 pos[k][e] -= box[d][e];
247 } else {
248 for(d=0; d<npbcdim; d++) {
249 while(cg_cm[icg][d] < 0) {
250 cg_cm[icg][d] += box[d][d];
251 for(k=k0; (k<k1); k++)
252 pos[k][d] += box[d][d];
254 while(cg_cm[icg][d] >= box[d][d]) {
255 cg_cm[icg][d] -= box[d][d];
256 for(k=k0; (k<k1); k++)
257 pos[k][d] -= box[d][d];
261 #ifdef DEBUG_PBC
262 for(d=0; (d<npbcdim); d++) {
263 if ((cg_cm[icg][d] < 0) || (cg_cm[icg][d] >= box[d][d]))
264 gmx_fatal(FARGS,"cg_cm[%d] = %15f %15f %15f\n"
265 "box = %15f %15f %15f\n",
266 icg,cg_cm[icg][XX],cg_cm[icg][YY],cg_cm[icg][ZZ],
267 box[XX][XX],box[YY][YY],box[ZZ][ZZ]);
269 #endif