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_addconf_c
= "$Id$";
41 static real box_margin
;
43 real
max_dist(rvec
*x
, real
*r
, int start
, int end
)
49 for(i
=start
; i
<end
; i
++)
50 for(j
=i
+1; j
<end
; j
++)
51 maxd
=max(maxd
,sqrt(distance2(x
[i
],x
[j
]))+0.5*(r
[i
]+r
[j
]));
56 void set_margin(t_atoms
*atoms
, rvec
*x
, real
*r
)
64 for(i
=0; i
< atoms
->nr
; i
++) {
65 if ( (i
+1 == atoms
->nr
) ||
66 (atoms
->atom
[i
+1].resnr
!= atoms
->atom
[i
].resnr
) ) {
67 d
=max_dist(x
,r
,start
,i
+1);
68 if (debug
&& d
>box_margin
)
69 fprintf(debug
,"getting margin from %s: %g\n",
70 *(atoms
->resname
[atoms
->atom
[i
].resnr
]),box_margin
);
71 box_margin
=max(box_margin
,d
);
78 bool in_box_plus_margin(rvec x
,matrix box
)
80 return ( x
[XX
]>=-box_margin
&& x
[XX
]<=box
[XX
][XX
]+box_margin
&&
81 x
[YY
]>=-box_margin
&& x
[YY
]<=box
[YY
][YY
]+box_margin
&&
82 x
[ZZ
]>=-box_margin
&& x
[ZZ
]<=box
[ZZ
][ZZ
]+box_margin
);
85 bool outside_box_minus_margin(rvec x
,matrix box
)
87 return ( x
[XX
]<box_margin
|| x
[XX
]>box
[XX
][XX
]-box_margin
||
88 x
[YY
]<box_margin
|| x
[YY
]>box
[YY
][YY
]-box_margin
||
89 x
[ZZ
]<box_margin
|| x
[ZZ
]>box
[ZZ
][ZZ
]-box_margin
);
92 int mark_remove_res(int at
, bool *remove
, int natoms
, t_atom
*atom
)
96 resnr
= atom
[at
].resnr
;
97 while( (at
> 0) && (resnr
==atom
[at
-1].resnr
) )
99 while( (at
< natoms
) && (resnr
==atom
[at
].resnr
) ) {
107 void add_conf(t_atoms
*atoms
, rvec
**x
, real
**r
, bool bSrenew
,
109 t_atoms
*atoms_solvt
, rvec
*x_solvt
, real
*r_solvt
,
112 int i
,j
,m
,prev
,resnr
,nresadd
,d
,k
;
117 if (atoms_solvt
->nr
<= 0) {
118 fprintf(stderr
,"WARNING: Nothing to add\n");
123 fprintf(stderr
,"Calculating Overlap...\n");
125 snew(remove
,atoms_solvt
->nr
);
128 /* set margin around box edges to largest solvent dimension */
129 set_margin(atoms_solvt
,x_solvt
,r_solvt
);
131 /* remove atoms that are far outside the box */
132 for(i
=0; i
<atoms_solvt
->nr
;i
++)
133 if ( !in_box_plus_margin(x_solvt
[i
],box
) )
134 i
=mark_remove_res(i
,remove
,atoms_solvt
->nr
,atoms_solvt
->atom
);
136 /* check solvent with solute */
137 for(i
=0; i
<atoms
->nr
; i
++) {
138 if ( bVerbose
&& ( (i
<10) || ((i
+1)%10) || (i
>atoms
->nr
-10) ) )
139 fprintf(stderr
,"\r%d out of %d atoms checked",i
+1,atoms
->nr
);
140 for(j
=0; j
<atoms_solvt
->nr
; j
++)
141 /* only check solvent that hasn't been marked for removal already */
143 pbc_dx((*x
)[i
],x_solvt
[j
],dx
);
144 if ( norm2(dx
) < sqr((*r
)[i
] + r_solvt
[j
]) )
145 j
=mark_remove_res(j
,remove
,atoms_solvt
->nr
,atoms_solvt
->atom
);
149 fprintf(stderr
,"\n");
151 /* check solvent with itself */
152 for(i
=0; i
<atoms_solvt
->nr
;i
++) {
153 if ( bVerbose
&& ( (i
<10) || !((i
+1)%10) || (i
>atoms_solvt
->nr
-10) ) )
154 fprintf(stderr
,"\rchecking atom %d out of %d",i
+1,atoms_solvt
->nr
);
156 /* check only atoms that haven't been marked for removal already and
157 are close to the box edges */
158 if ( !remove
[i
] && outside_box_minus_margin(x_solvt
[i
],box
) )
159 /* check with other border atoms,
160 only if not already removed and two different molecules (resnr) */
161 for(j
=i
+1; (j
<atoms_solvt
->nr
) && !remove
[i
]; j
++)
163 atoms_solvt
->atom
[i
].resnr
!= atoms_solvt
->atom
[j
].resnr
&&
164 outside_box_minus_margin(x_solvt
[j
],box
) ) {
165 pbc_dx(x_solvt
[i
],x_solvt
[j
],dx
);
166 if ( norm2(dx
) < sqr(r_solvt
[i
] + r_solvt
[j
]) )
167 j
=mark_remove_res(j
,remove
,atoms_solvt
->nr
,atoms_solvt
->atom
);
171 fprintf(stderr
,"\n");
173 /* count how many atoms will be added and make space */
175 for (i
=0; (i
<atoms_solvt
->nr
); i
++)
179 srenew(atoms
->resname
, atoms
->nres
+atoms_solvt
->nres
);
180 srenew(atoms
->atomname
, atoms
->nr
+j
);
181 srenew(atoms
->atom
, atoms
->nr
+j
);
182 srenew(*x
, atoms
->nr
+j
);
183 srenew(*r
, atoms
->nr
+j
);
186 /* add the selected atoms_solvt to atoms */
189 for (i
=0; (i
<atoms_solvt
->nr
); i
++)
191 if ( (prev
==NOTSET
) ||
192 (atoms_solvt
->atom
[i
].resnr
!= atoms_solvt
->atom
[prev
].resnr
) ) {
197 atoms
->atomname
[atoms
->nr
-1] = atoms_solvt
->atomname
[i
];
198 copy_rvec(x_solvt
[i
],(*x
)[atoms
->nr
-1]);
199 (*r
)[atoms
->nr
-1] = r_solvt
[i
];
200 atoms
->atom
[atoms
->nr
-1].resnr
= atoms
->nres
-1;
201 atoms
->resname
[atoms
->nres
-1] =
202 atoms_solvt
->resname
[atoms_solvt
->atom
[i
].resnr
];
206 srenew(atoms
->resname
, atoms
->nres
+nresadd
);
209 fprintf(stderr
,"Added %d molecules\n",nresadd
);
214 void orient_mol(t_atoms
*atoms
,char *indexnm
,rvec x
[], rvec
*v
)
217 atom_id
*index
,*simp
;
224 /* Make an index for principal component analysis */
225 fprintf(stderr
,"\nSelect group for orientation of molecule:\n");
226 get_index(atoms
,indexnm
,1,&isize
,&index
,&grpnames
);
227 snew(simp
,atoms
->nr
);
228 for(i
=0; (i
<atoms
->nr
); i
++) {
232 totmass
= sub_xcm(x
,atoms
->nr
,simp
,atoms
->atom
,xcm
,FALSE
);
233 principal_comp(isize
,index
,atoms
->atom
,x
,trans
,prcomp
);
235 /* Check whether this trans matrix mirrors the molecule */
236 if (det(trans
) < 0) {
238 fprintf(stderr
,"Mirroring rotation matrix in Z direction\n");
239 for(m
=0; (m
<DIM
); m
++)
240 trans
[ZZ
][m
] = -trans
[ZZ
][m
];
242 rotate_atoms(atoms
->nr
,simp
,x
,trans
);
245 pr_rvecs(stderr
,0,"Rot Matrix",trans
,DIM
);
246 fprintf(stderr
,"Det(trans) = %g\n",det(trans
));
248 /* print principal component data */
249 fprintf(stderr
,"Norm of principal axes before rotation: "
250 "(%.3f, %.3f, %.3f)\n",prcomp
[XX
],prcomp
[YY
],prcomp
[ZZ
]);
251 fprintf(stderr
,"Totmass = %g\n",totmass
);
252 principal_comp(isize
,index
,atoms
->atom
,x
,trans
,prcomp
);
253 rotate_atoms(atoms
->nr
,simp
,x
,trans
);
255 rotate_atoms(atoms
->nr
,simp
,v
,trans
);
256 pr_rvecs(stderr
,0,"Rot Matrix",trans
,DIM
);