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_dum_parm_c
= "$Id$";
51 static void enter_bonded(int nratoms
, int *nrbonded
, t_mybonded
**bondeds
,
56 srenew(*bondeds
, *nrbonded
+1);
58 /* copy atom numbers */
59 for(j
=0; j
<nratoms
; j
++)
60 (*bondeds
)[*nrbonded
].a
[j
] = param
.a
[j
];
62 (*bondeds
)[*nrbonded
].c
= param
.C0
;
67 static void get_bondeds(int nrat
, t_iatom atoms
[],
69 int *nrbond
, t_mybonded
**bonds
,
70 int *nrang
, t_mybonded
**angles
,
71 int *nridih
, t_mybonded
**idihs
)
74 int nra
,nrd
,tp
,nrcheck
;
80 fprintf(debug
,"getting bondeds for %u (nr=%d):",atoms
[0]+1,nrat
);
82 fprintf(debug
," %u",atoms
[k
]+1);
85 for(ftype
=0; (ftype
<F_NRE
); ftype
++) {
86 if (interaction_function
[ftype
].flags
& (IF_BTYPE
| IF_CONSTRAINT
))
87 /* this is a bond or a constraint */
89 else if ( interaction_function
[ftype
].flags
& IF_ATYPE
)
90 /* this is an angle */
95 /* this is an improper dihedral */
105 for(i
=0; (i
<plist
[ftype
].nr
); i
++) {
106 /* now we have something, check includes one of atoms[*] */
108 for(j
=0; j
<nrcheck
&& !bCheck
; j
++)
109 for(k
=0; k
<nrat
; k
++)
110 bCheck
= bCheck
|| (plist
[ftype
].param
[i
].a
[j
]==atoms
[k
]);
113 /* abuse nrcheck to see if we're adding bond, angle or idih */
116 enter_bonded(nrcheck
,nrbond
,bonds
, plist
[ftype
].param
[i
]);
119 enter_bonded(nrcheck
,nrang
, angles
,plist
[ftype
].param
[i
]);
122 enter_bonded(nrcheck
,nridih
,idihs
, plist
[ftype
].param
[i
]);
130 static void print_bad(FILE *fp
,
131 int nrbond
, t_mybonded
*bonds
,
132 int nrang
, t_mybonded
*angles
,
133 int nridih
, t_mybonded
*idihs
)
138 fprintf(fp
,"bonds:");
139 for(i
=0; i
<nrbond
; i
++)
140 fprintf(fp
," %u-%u (%g)",
141 bonds
[i
].AI
+1, bonds
[i
].AJ
+1, bonds
[i
].c
);
145 fprintf(fp
,"angles:");
146 for(i
=0; i
<nrang
; i
++)
147 fprintf(fp
," %u-%u-%u (%g)",
148 angles
[i
].AI
+1, angles
[i
].AJ
+1,
149 angles
[i
].AK
+1, angles
[i
].c
);
153 fprintf(fp
,"idihs:");
154 for(i
=0; i
<nridih
; i
++)
155 fprintf(fp
," %u-%u-%u-%u (%g)",
156 idihs
[i
].AI
+1, idihs
[i
].AJ
+1,
157 idihs
[i
].AK
+1, idihs
[i
].AL
+1, idihs
[i
].c
);
162 static void print_param(FILE *fp
, int ftype
, int i
, t_param
*param
)
165 static int prev_ftype
= NOTSET
;
166 static int prev_i
= NOTSET
;
169 if ( (ftype
!=prev_ftype
) || (i
!=prev_i
) ) {
174 fprintf(fp
,"(%d) plist[%s].param[%d]",
175 pass
,interaction_function
[ftype
].name
,i
);
176 for(j
=0; j
<NRFP(ftype
); j
++)
177 fprintf(fp
,".c[%d]=%g ",j
,param
->c
[j
]);
182 static real
get_bond_length(int nrbond
, t_mybonded bonds
[],
183 t_iatom ai
, t_iatom aj
)
189 for (i
=0; i
< nrbond
&& (bondlen
==NOTSET
); i
++) {
190 /* check both ways */
191 if ( ( (ai
== bonds
[i
].AI
) && (aj
== bonds
[i
].AJ
) ) ||
192 ( (ai
== bonds
[i
].AJ
) && (aj
== bonds
[i
].AI
) ) )
193 bondlen
= bonds
[i
].c
; /* note: bonds[i].c might be NOTSET */
198 static real
get_angle(int nrang
, t_mybonded angles
[],
199 t_iatom ai
, t_iatom aj
, t_iatom ak
)
205 for (i
=0; i
< nrang
&& (angle
==NOTSET
); i
++) {
206 /* check both ways */
207 if ( ( (ai
==angles
[i
].AI
) && (aj
==angles
[i
].AJ
) && (ak
==angles
[i
].AK
) ) ||
208 ( (ai
==angles
[i
].AK
) && (aj
==angles
[i
].AJ
) && (ak
==angles
[i
].AI
) ) )
209 angle
= DEG2RAD
*angles
[i
].c
;
214 static bool calc_dum3_param(t_atomtype
*atype
,
215 t_param
*param
, t_atoms
*at
,
216 int nrbond
, t_mybonded
*bonds
,
217 int nrang
, t_mybonded
*angles
)
219 /* i = dummy atom | ,k
220 * j = 1st bonded heavy atom | i-j
221 * k,l = 2nd bonded atoms | `l
225 real bjk
,bjl
,a
=-1,b
=-1;
226 /* check if this is part of a NH3 or CH3 group,
227 * i.e. if atom k and l are dummy masses (MNH3 or MCH3) */
231 fprintf(debug
,"atom %u type %s ",
232 param
->a
[i
]+1,type2nm(at
->atom
[param
->a
[i
]].type
,atype
));
236 ( (strcasecmp(type2nm(at
->atom
[param
->AK
].type
,atype
),"MNH3")==0) &&
237 (strcasecmp(type2nm(at
->atom
[param
->AL
].type
,atype
),"MNH3")==0) ) ||
238 ( (strcasecmp(type2nm(at
->atom
[param
->AK
].type
,atype
),"MCH3")==0) &&
239 (strcasecmp(type2nm(at
->atom
[param
->AL
].type
,atype
),"MCH3")==0) );
241 bjk
= get_bond_length(nrbond
, bonds
, param
->AJ
, param
->AK
);
242 bjl
= get_bond_length(nrbond
, bonds
, param
->AJ
, param
->AL
);
243 bError
= (bjk
==NOTSET
) || (bjl
==NOTSET
);
245 /* now we get some XH3 group specific construction */
246 /* note: we call the heavy atom 'C' and the X atom 'N' */
247 real bMM
,bCM
,bCN
,bNH
,aCNH
,dH
,rH
,dM
,rM
;
250 /* check if bonds from heavy atom (j) to dummy masses (k,l) are equal: */
251 bError
= bError
|| (bjk
!=bjl
);
253 /* the X atom (C or N) in the XH3 group is the first after the masses: */
254 aN
= max(param
->AK
,param
->AL
)+1;
256 /* get common bonds */
257 bMM
= get_bond_length(nrbond
, bonds
, param
->AK
, param
->AL
);
259 bCN
= get_bond_length(nrbond
, bonds
, param
->AJ
, aN
);
260 bError
= bError
|| (bMM
==NOTSET
) || (bCN
==NOTSET
);
262 /* calculate common things */
264 dM
= sqrt( sqr(bCM
) - sqr(rM
) );
266 /* are we dealing with the X atom? */
267 if ( param
->AI
== aN
) {
268 /* this is trivial */
269 a
= b
= 0.5 * bCN
/dM
;
272 /* get other bondlengths and angles: */
273 bNH
= get_bond_length(nrbond
, bonds
, aN
, param
->AI
);
274 aCNH
= get_angle (nrang
, angles
, param
->AJ
, aN
, param
->AI
);
275 bError
= bError
|| (bNH
==NOTSET
) || (aCNH
==NOTSET
);
278 dH
= bCN
- bNH
* cos(aCNH
);
279 rH
= bNH
* sin(aCNH
);
281 a
= 0.5 * ( dH
/dM
+ rH
/rM
);
282 b
= 0.5 * ( dH
/dM
- rH
/rM
);
285 fatal_error(0,"calc_dum3_param not implemented for the general case "
286 "(atom %d)",param
->AI
+1);
292 fprintf(debug
,"params for dummy3 %u: %g %g\n",
293 param
->AI
+1,param
->C0
,param
->C1
);
298 static bool calc_dum3fd_param(t_param
*param
,
299 int nrbond
, t_mybonded
*bonds
,
300 int nrang
, t_mybonded
*angles
)
302 /* i = dummy atom | ,k
303 * j = 1st bonded heavy atom | i-j
304 * k,l = 2nd bonded atoms | `l
308 real bij
,bjk
,bjl
,aijk
,aijl
,rk
,rl
;
310 bij
= get_bond_length(nrbond
, bonds
, param
->AI
, param
->AJ
);
311 bjk
= get_bond_length(nrbond
, bonds
, param
->AJ
, param
->AK
);
312 bjl
= get_bond_length(nrbond
, bonds
, param
->AJ
, param
->AL
);
313 aijk
= get_angle (nrang
, angles
, param
->AI
, param
->AJ
, param
->AK
);
314 aijl
= get_angle (nrang
, angles
, param
->AI
, param
->AJ
, param
->AL
);
315 bError
= (bij
==NOTSET
) || (bjk
==NOTSET
) || (bjl
==NOTSET
) ||
316 (aijk
==NOTSET
) || (aijl
==NOTSET
);
318 rk
= bjk
* sin(aijk
);
319 rl
= bjl
* sin(aijl
);
320 param
->C0
= rk
/ (rk
+ rl
);
321 param
->C1
= -bij
; /* 'bond'-length for fixed distance dummy */
324 fprintf(debug
,"params for dummy3fd %u: %g %g\n",
325 param
->AI
+1,param
->C0
,param
->C1
);
329 static bool calc_dum3fad_param(t_param
*param
,
330 int nrbond
, t_mybonded
*bonds
,
331 int nrang
, t_mybonded
*angles
)
334 * j = 1st bonded heavy atom | i-j
335 * k = 2nd bonded heavy atom | `k-l
336 * l = 3d bonded heavy atom |
339 bool bSwapParity
,bError
;
342 bSwapParity
= ( param
->C1
== -1 );
344 bij
= get_bond_length(nrbond
, bonds
, param
->AI
, param
->AJ
);
345 aijk
= get_angle (nrang
, angles
, param
->AI
, param
->AJ
, param
->AK
);
346 bError
= (bij
==NOTSET
) || (aijk
==NOTSET
);
348 param
->C1
= bij
; /* 'bond'-length for fixed distance dummy */
349 param
->C0
= RAD2DEG
*aijk
; /* 'bond'-angle for fixed angle dummy */
352 param
->C0
= 360 - param
->C0
;
355 fprintf(debug
,"params for dummy3fad %u: %g %g\n",
356 param
->AI
+1,param
->C0
,param
->C1
);
360 static bool calc_dum3out_param(t_atomtype
*atype
,
361 t_param
*param
, t_atoms
*at
,
362 int nrbond
, t_mybonded
*bonds
,
363 int nrang
, t_mybonded
*angles
)
365 /* i = dummy atom | ,k
366 * j = 1st bonded heavy atom | i-j
367 * k,l = 2nd bonded atoms | `l
368 * NOTE: i is out of the j-k-l plane!
371 bool bXH3
,bError
,bSwapParity
;
372 real bij
,bjk
,bjl
,aijk
,aijl
,akjl
,pijk
,pijl
,a
,b
,c
;
374 /* check if this is part of a NH3 or CH3 group,
375 * i.e. if atom k and l are dummy masses (MNH3 or MCH3) */
379 fprintf(debug
,"atom %u type %s ",
380 param
->a
[i
]+1,type2nm(at
->atom
[param
->a
[i
]].type
,atype
));
384 ( (strcasecmp(type2nm(at
->atom
[param
->AK
].type
,atype
),"MNH3")==0) &&
385 (strcasecmp(type2nm(at
->atom
[param
->AL
].type
,atype
),"MNH3")==0) ) ||
386 ( (strcasecmp(type2nm(at
->atom
[param
->AK
].type
,atype
),"MCH3")==0) &&
387 (strcasecmp(type2nm(at
->atom
[param
->AL
].type
,atype
),"MCH3")==0) );
389 /* check if construction parity must be swapped */
390 bSwapParity
= ( param
->C1
== -1 );
392 bjk
= get_bond_length(nrbond
, bonds
, param
->AJ
, param
->AK
);
393 bjl
= get_bond_length(nrbond
, bonds
, param
->AJ
, param
->AL
);
394 bError
= (bjk
==NOTSET
) || (bjl
==NOTSET
);
396 /* now we get some XH3 group specific construction */
397 /* note: we call the heavy atom 'C' and the X atom 'N' */
398 real bMM
,bCM
,bCN
,bNH
,aCNH
,dH
,rH
,rHx
,rHy
,dM
,rM
;
401 /* check if bonds from heavy atom (j) to dummy masses (k,l) are equal: */
402 bError
= bError
|| (bjk
!=bjl
);
404 /* the X atom (C or N) in the XH3 group is the first after the masses: */
405 aN
= max(param
->AK
,param
->AL
)+1;
407 /* get all bondlengths and angles: */
408 bMM
= get_bond_length(nrbond
, bonds
, param
->AK
, param
->AL
);
410 bCN
= get_bond_length(nrbond
, bonds
, param
->AJ
, aN
);
411 bNH
= get_bond_length(nrbond
, bonds
, aN
, param
->AI
);
412 aCNH
= get_angle (nrang
, angles
, param
->AJ
, aN
, param
->AI
);
414 (bMM
==NOTSET
) || (bCN
==NOTSET
) || (bNH
==NOTSET
) || (aCNH
==NOTSET
);
417 dH
= bCN
- bNH
* cos(aCNH
);
418 rH
= bNH
* sin(aCNH
);
419 /* we assume the H's are symmetrically distributed */
420 rHx
= rH
*cos(DEG2RAD
*30);
421 rHy
= rH
*sin(DEG2RAD
*30);
423 dM
= sqrt( sqr(bCM
) - sqr(rM
) );
424 a
= 0.5*( (dH
/dM
) - (rHy
/rM
) );
425 b
= 0.5*( (dH
/dM
) + (rHy
/rM
) );
429 /* this is the general construction */
431 bij
= get_bond_length(nrbond
, bonds
, param
->AI
, param
->AJ
);
432 aijk
= get_angle (nrang
, angles
, param
->AI
, param
->AJ
, param
->AK
);
433 aijl
= get_angle (nrang
, angles
, param
->AI
, param
->AJ
, param
->AL
);
434 akjl
= get_angle (nrang
, angles
, param
->AK
, param
->AJ
, param
->AL
);
436 (bij
==NOTSET
) || (aijk
==NOTSET
) || (aijl
==NOTSET
) || (akjl
==NOTSET
);
438 pijk
= cos(aijk
)*bij
;
439 pijl
= cos(aijl
)*bij
;
440 a
= ( pijk
+ (pijk
*cos(akjl
)-pijl
) * cos(akjl
) / sqr(sin(akjl
)) ) / bjk
;
441 b
= ( pijl
+ (pijl
*cos(akjl
)-pijk
) * cos(akjl
) / sqr(sin(akjl
)) ) / bjl
;
442 c
= - sqrt( sqr(bij
) -
443 ( sqr(pijk
) - 2*pijk
*pijl
*cos(akjl
) + sqr(pijl
) )
445 / ( bjk
*bjl
*sin(akjl
) );
455 fprintf(debug
,"params for dummy3out %u: %g %g %g\n",
456 param
->AI
+1,param
->C0
,param
->C1
,param
->C2
);
460 static bool calc_dum4fd_param(t_param
*param
,
461 int nrbond
, t_mybonded
*bonds
,
462 int nrang
, t_mybonded
*angles
)
464 /* i = dummy atom | ,k
465 * j = 1st bonded heavy atom | i-j-m
466 * k,l,m = 2nd bonded atoms | `l
470 real bij
,bjk
,bjl
,bjm
,aijk
,aijl
,aijm
,akjm
,akjl
;
471 real pk
,pl
,pm
,cosakl
,cosakm
,sinakl
,sinakm
,cl
,cm
;
473 bij
= get_bond_length(nrbond
, bonds
, param
->AI
, param
->AJ
);
474 bjk
= get_bond_length(nrbond
, bonds
, param
->AJ
, param
->AK
);
475 bjl
= get_bond_length(nrbond
, bonds
, param
->AJ
, param
->AL
);
476 bjm
= get_bond_length(nrbond
, bonds
, param
->AJ
, param
->AM
);
477 aijk
= get_angle (nrang
, angles
, param
->AI
, param
->AJ
, param
->AK
);
478 aijl
= get_angle (nrang
, angles
, param
->AI
, param
->AJ
, param
->AL
);
479 aijm
= get_angle (nrang
, angles
, param
->AI
, param
->AJ
, param
->AM
);
480 akjm
= get_angle (nrang
, angles
, param
->AK
, param
->AJ
, param
->AM
);
481 akjl
= get_angle (nrang
, angles
, param
->AK
, param
->AJ
, param
->AL
);
482 bError
= (bij
==NOTSET
) || (bjk
==NOTSET
) || (bjl
==NOTSET
) || (bjm
==NOTSET
) ||
483 (aijk
==NOTSET
) || (aijl
==NOTSET
) || (aijm
==NOTSET
) || (akjm
==NOTSET
) ||
489 cosakl
= (cos(akjl
) - cos(aijk
)*cos(aijl
)) / (sin(aijk
)*sin(aijl
));
490 cosakm
= (cos(akjm
) - cos(aijk
)*cos(aijm
)) / (sin(aijk
)*sin(aijm
));
491 if ( cosakl
< -1 || cosakl
> 1 || cosakm
< -1 || cosakm
> 1 )
492 fatal_error(0,"invalid construction in calc_dum4fd for atom %u: "
493 "cosakl=%g cosakm=%g\n",param
->AI
+1,cosakl
,cosakm
);
494 sinakl
= sqrt(1-sqr(cosakl
));
495 sinakm
= sqrt(1-sqr(cosakm
));
497 /* note: there is a '+' because of the way the sines are calculated */
498 cl
= -pk
/ ( pl
*cosakl
- pk
+ pl
*sinakl
*(pm
*cosakm
-pk
)/(pm
*sinakm
) );
499 cm
= -pk
/ ( pm
*cosakm
- pk
+ pm
*sinakm
*(pl
*cosakl
-pk
)/(pl
*sinakl
) );
505 fprintf(debug
,"params for dummy4fd %u: %g %g %g\n",
506 param
->AI
+1,param
->C0
,param
->C1
,param
->C2
);
511 int set_dummies(bool bVerbose
, t_atoms
*atoms
, t_atomtype atype
,
515 int ndum
,nrbond
,nrang
,nridih
,nrset
;
516 bool bFirst
,bSet
,bERROR
;
525 fprintf(debug
, "\nCalculating parameters for dummy atoms\n");
526 for(ftype
=0; (ftype
<F_NRE
); ftype
++)
527 if (interaction_function
[ftype
].flags
& IF_DUMMY
) {
529 ndum
+=plist
[ftype
].nr
;
530 for(i
=0; (i
<plist
[ftype
].nr
); i
++) {
531 /* check if all parameters are set */
533 for(j
=0; j
<NRFP(ftype
) && bSet
; j
++)
534 bSet
= plist
[ftype
].param
[i
].c
[j
]!=NOTSET
;
537 fprintf(debug
,"bSet=%s ",bool_names
[bSet
]);
538 print_param(debug
,ftype
,i
,&plist
[ftype
].param
[i
]);
541 if (bVerbose
&& bFirst
) {
542 fprintf(stderr
,"Calculating parameters for dummy atoms\n");
546 nrbond
=nrang
=nridih
=0;
551 /* now set the dummy parameters: */
552 get_bondeds(NRAL(ftype
), plist
[ftype
].param
[i
].a
, plist
,
553 &nrbond
, &bonds
, &nrang
, &angles
, &nridih
, &idihs
);
555 fprintf(debug
, "Found %d bonds, %d angles and %d idihs "
556 "for dummy atom %u (%s)\n",nrbond
,nrang
,nridih
,
557 plist
[ftype
].param
[i
].AI
+1,
558 interaction_function
[ftype
].longname
);
559 print_bad(debug
, nrbond
, bonds
, nrang
, angles
, nridih
, idihs
);
564 calc_dum3_param(&atype
, &(plist
[ftype
].param
[i
]), atoms
,
565 nrbond
, bonds
, nrang
, angles
);
569 calc_dum3fd_param(&(plist
[ftype
].param
[i
]),
570 nrbond
, bonds
, nrang
, angles
);
574 calc_dum3fad_param(&(plist
[ftype
].param
[i
]),
575 nrbond
, bonds
, nrang
, angles
);
579 calc_dum3out_param(&atype
, &(plist
[ftype
].param
[i
]), atoms
,
580 nrbond
, bonds
, nrang
, angles
);
584 calc_dum4fd_param(&(plist
[ftype
].param
[i
]),
585 nrbond
, bonds
, nrang
, angles
);
588 fatal_error(0,"Automatic parameter generation not supported "
590 interaction_function
[ftype
].longname
,
591 plist
[ftype
].param
[i
].AI
+1);
594 fatal_error(0,"Automatic parameter generation not supported "
595 "for %s atom %d for this bonding configuration",
596 interaction_function
[ftype
].longname
,
597 plist
[ftype
].param
[i
].AI
+1);
603 if (debug
&& plist
[ftype
].nr
)
604 fprintf(stderr
,"Calculated parameters for %d out of %d %s atoms\n",
605 nrset
,plist
[ftype
].nr
,interaction_function
[ftype
].longname
);
611 void set_dummies_ptype(bool bVerbose
, t_idef
*idef
, t_atoms
*atoms
)
618 fprintf(stderr
,"Setting particle type to Dummy for dummy atoms\n");
620 fprintf(stderr
,"checking %d functypes\n",F_NRE
);
621 for(ftype
=0; (ftype
<F_NRE
); ftype
++) {
622 if (interaction_function
[ftype
].flags
& IF_DUMMY
) {
623 nra
= interaction_function
[ftype
].nratoms
;
624 nrd
= idef
->il
[ftype
].nr
;
625 ia
= idef
->il
[ftype
].iatoms
;
628 fprintf(stderr
,"doing %d %s dummies\n",
629 (nrd
/ (nra
+1)),interaction_function
[ftype
].longname
);
631 for(i
=0; (i
<nrd
); ) {
633 assert(ftype
== idef
->functype
[tp
]);
637 atoms
->atom
[adum
].ptype
=eptDummy
;
651 static void check_dum_constraints(t_params
*plist
,
652 int cftype
, int dummy_type
[])
659 ps
= &(plist
[cftype
]);
660 for(i
=0; (i
<ps
->nr
); i
++)
662 atom
= ps
->param
[i
].a
[k
];
663 if (dummy_type
[atom
]!=NOTSET
) {
665 "ERROR: Cannot have constraint (%u-%u) with dummy atom (%u)\n",
666 ps
->param
[i
].AI
+1, ps
->param
[i
].AJ
+1, atom
+1);
671 fatal_error(0,"There were %d dummy atoms involved in constraints",n
);
674 static void clean_dum_bonds(t_params
*plist
, t_pindex pindex
[],
675 int cftype
, int dummy_type
[])
677 int ftype
,i
,j
,parnr
,k
,l
,m
,n
,ndum
,nOut
,kept_i
,dumnral
,dumtype
;
678 atom_id atom
,oatom
,constr
,at1
,at2
;
679 atom_id dumatoms
[MAXATOMLIST
];
680 bool bKeep
,bRemove
,bUsed
,bPresent
,bThisFD
,bThisOUT
,bAllFD
,bFirstTwo
;
683 ps
= &(plist
[cftype
]);
687 for(i
=0; (i
<ps
->nr
); i
++) { /* for all bonds in the plist */
691 /* check if all dummies are constructed from the same atoms */
694 fprintf(debug
,"constr %u %u:",ps
->param
[i
].AI
+1,ps
->param
[i
].AJ
+1);
695 for(k
=0; (k
<2) && !bKeep
&& !bRemove
; k
++) {
696 /* for all atoms in the bond */
697 atom
= ps
->param
[i
].a
[k
];
698 if (dummy_type
[atom
]!=NOTSET
) {
700 fprintf(debug
," d%d[%d: %d %d %d]",k
,atom
+1,
701 plist
[pindex
[atom
].ftype
].param
[pindex
[atom
].parnr
].AJ
+1,
702 plist
[pindex
[atom
].ftype
].param
[pindex
[atom
].parnr
].AK
+1,
703 plist
[pindex
[atom
].ftype
].param
[pindex
[atom
].parnr
].AL
+1);
706 bThisFD
= ( (pindex
[atom
].ftype
== F_DUMMY3FD
) ||
707 (pindex
[atom
].ftype
== F_DUMMY3FAD
) ||
708 (pindex
[atom
].ftype
== F_DUMMY4FD
) );
709 bThisOUT
= ( (pindex
[atom
].ftype
== F_DUMMY3OUT
) &&
710 (interaction_function
[cftype
].flags
& IF_CONSTRAINT
) );
711 bAllFD
= bAllFD
&& bThisFD
;
712 if (bThisFD
|| bThisOUT
) {
713 if(debug
)fprintf(debug
," %s",bThisOUT
?"out":"fd");
714 oatom
= ps
->param
[i
].a
[1-k
]; /* the other atom */
715 if ( dummy_type
[oatom
]==NOTSET
&&
716 oatom
==plist
[pindex
[atom
].ftype
].param
[pindex
[atom
].parnr
].AJ
){
717 /* if the other atom isn't a dummy, and it is AI */
721 if(debug
)fprintf(debug
," D-AI");
726 /* if this is the first dummy we encounter then
727 store construction atoms */
728 dumnral
=NRAL(pindex
[atom
].ftype
)-1;
729 for(m
=0; (m
<dumnral
); m
++)
731 plist
[pindex
[atom
].ftype
].param
[pindex
[atom
].parnr
].a
[m
+1];
733 /* if it is not the first then
734 check if this dummy is constructed from the same atoms */
735 if (dumnral
== NRAL(pindex
[atom
].ftype
)-1 )
736 for(m
=0; (m
<dumnral
) && !bKeep
; m
++) {
739 plist
[pindex
[atom
].ftype
].param
[pindex
[atom
].parnr
].a
[m
+1];
740 for(n
=0; (n
<dumnral
) && !bPresent
; n
++)
741 if (constr
== dumatoms
[n
])
745 if(debug
)fprintf(debug
," !present");
750 if(debug
)fprintf(debug
," !same#at");
760 /* if we have no dummies in this bond, keep it */
762 if (debug
)fprintf(debug
," no dum");
766 /* check if all non-dummy atoms are used in construction: */
768 for(k
=0; (k
<2) && !bKeep
; k
++) { /* for all atoms in the bond */
769 atom
= ps
->param
[i
].a
[k
];
770 if (dummy_type
[atom
]==NOTSET
) {
772 for(m
=0; (m
<dumnral
) && !bUsed
; m
++)
773 if (atom
== dumatoms
[m
]) {
775 bFirstTwo
= bFirstTwo
&& m
<2;
779 if(debug
)fprintf(debug
," !used");
784 if ( ! ( bAllFD
&& bFirstTwo
) )
785 /* check if all constructing atoms are constrained together */
786 for (m
=0; m
<dumnral
&& !bKeep
; m
++) { /* all constr. atoms */
788 at2
= dumatoms
[(m
+1) % dumnral
];
790 for (ftype
=0; ftype
<F_NRE
; ftype
++)
791 if ( interaction_function
[ftype
].flags
& IF_CONSTRAINT
)
792 for (j
=0; (j
<plist
[ftype
].nr
) && !bPresent
; j
++)
793 /* all constraints until one matches */
794 bPresent
= ( ( (plist
[ftype
].param
[j
].AI
== at1
) &&
795 (plist
[ftype
].param
[j
].AJ
== at2
) ) ||
796 ( (plist
[ftype
].param
[j
].AI
== at2
) &&
797 (plist
[ftype
].param
[j
].AJ
== at1
) ) );
800 if(debug
)fprintf(debug
," !bonded");
806 if(debug
)fprintf(debug
," keeping");
807 /* now copy the bond to the new array */
808 memcpy(&(ps
->param
[kept_i
]),
809 &(ps
->param
[i
]),(size_t)sizeof(ps
->param
[0]));
812 if(debug
)fprintf(debug
,"\n");
815 if (ps
->nr
!= kept_i
)
816 fprintf(stderr
,"Removed %4d %15ss with dummy atoms, %5d left\n",
817 ps
->nr
-kept_i
, interaction_function
[cftype
].longname
, kept_i
);
819 fprintf(stderr
,"Warning: removed %d %ss with dummy with %s construction\n"
820 " This dummy construction does not guarantee constant "
822 " If the constructions were generated by pdb2gmx ignore "
824 nOut
, interaction_function
[cftype
].longname
,
825 interaction_function
[F_DUMMY3OUT
].longname
);
829 static void clean_dum_angles(t_params
*plist
, t_pindex pindex
[],
830 int cftype
, int dummy_type
[])
832 int ftype
,i
,j
,parnr
,k
,l
,m
,n
,ndum
,kept_i
,dumnral
,dumtype
;
833 atom_id atom
,constr
,at1
,at2
;
834 atom_id dumatoms
[MAXATOMLIST
];
835 bool bKeep
,bUsed
,bPresent
,bAll3FAD
,bFirstTwo
;
838 ps
= &(plist
[cftype
]);
841 for(i
=0; (i
<ps
->nr
); i
++) { /* for all angles in the plist */
844 /* check if all dummies are constructed from the same atoms */
846 for(k
=0; (k
<3) && !bKeep
; k
++) { /* for all atoms in the angle */
847 atom
= ps
->param
[i
].a
[k
];
848 if (dummy_type
[atom
]!=NOTSET
) {
850 bAll3FAD
= bAll3FAD
&& (pindex
[atom
].ftype
== F_DUMMY3FAD
);
852 /* store construction atoms of first dummy */
853 dumnral
=NRAL(pindex
[atom
].ftype
)-1;
854 for(m
=0; (m
<dumnral
); m
++)
856 plist
[pindex
[atom
].ftype
].param
[pindex
[atom
].parnr
].a
[m
+1];
858 /* check if this dummy is constructed from the same atoms */
859 if (dumnral
== NRAL(pindex
[atom
].ftype
)-1 )
860 for(m
=0; (m
<dumnral
) && !bKeep
; m
++) {
863 plist
[pindex
[atom
].ftype
].param
[pindex
[atom
].parnr
].a
[m
+1];
864 for(n
=0; (n
<dumnral
) && !bPresent
; n
++)
865 if (constr
== dumatoms
[n
])
875 /* keep all angles with no dummies in them or
876 with dummies with more than 3 constr. atoms */
877 if ( ndum
== 0 && dumnral
> 3 )
880 /* check if all non-dummy atoms are used in construction: */
882 for(k
=0; (k
<3) && !bKeep
; k
++) { /* for all atoms in the angle */
883 atom
= ps
->param
[i
].a
[k
];
884 if (dummy_type
[atom
]==NOTSET
) {
886 for(m
=0; (m
<dumnral
) && !bUsed
; m
++)
887 if (atom
== dumatoms
[m
]) {
889 bFirstTwo
= bFirstTwo
&& m
<2;
896 if ( ! ( bAll3FAD
&& bFirstTwo
) )
897 /* check if all constructing atoms are constrained together */
898 for (m
=0; m
<dumnral
&& !bKeep
; m
++) { /* all constr. atoms */
900 at2
= dumatoms
[(m
+1) % dumnral
];
902 for (ftype
=0; ftype
<F_NRE
; ftype
++)
903 if ( interaction_function
[ftype
].flags
& IF_CONSTRAINT
)
904 for (j
=0; (j
<plist
[ftype
].nr
) && !bPresent
; j
++)
905 /* all constraints until one matches */
906 bPresent
= ( ( (plist
[ftype
].param
[j
].AI
== at1
) &&
907 (plist
[ftype
].param
[j
].AJ
== at2
) ) ||
908 ( (plist
[ftype
].param
[j
].AI
== at2
) &&
909 (plist
[ftype
].param
[j
].AJ
== at1
) ) );
915 /* now copy the angle to the new array */
916 memcpy(&(ps
->param
[kept_i
]),
917 &(ps
->param
[i
]),(size_t)sizeof(ps
->param
[0]));
922 if (ps
->nr
!= kept_i
)
923 fprintf(stderr
,"Removed %4d %15ss with dummy atoms, %5d left\n",
924 ps
->nr
-kept_i
, interaction_function
[cftype
].longname
, kept_i
);
928 static void clean_dum_dihs(t_params
*plist
, t_pindex pindex
[],
929 int cftype
, int dummy_type
[])
931 int ftype
,i
,parnr
,k
,l
,m
,n
,ndum
,kept_i
,dumnral
;
934 bool bKeep
,bUsed
,bPresent
;
937 ps
= &(plist
[cftype
]);
941 for(i
=0; (i
<ps
->nr
); i
++) { /* for all dihedrals in the plist */
943 /* check if all dummies are constructed from the same atoms */
945 for(k
=0; (k
<4) && !bKeep
; k
++) { /* for all atoms in the dihedral */
946 atom
= ps
->param
[i
].a
[k
];
947 if (dummy_type
[atom
]!=NOTSET
) {
950 /* store construction atoms of first dummy */
951 dumnral
=NRAL(pindex
[atom
].ftype
)-1;
952 for(m
=0; (m
<dumnral
); m
++)
954 plist
[pindex
[atom
].ftype
].param
[pindex
[atom
].parnr
].a
[m
+1];
956 fprintf(debug
,"dih w. dum: %u %u %u %u\n",
957 ps
->param
[i
].AI
+1,ps
->param
[i
].AJ
+1,
958 ps
->param
[i
].AK
+1,ps
->param
[i
].AL
+1);
959 fprintf(debug
,"dum %u from: %u %u %u\n",
960 atom
+1,dumatoms
[0]+1,dumatoms
[1]+1,dumatoms
[2]+1);
963 /* check if this dummy is constructed from the same atoms */
964 if (dumnral
== NRAL(pindex
[atom
].ftype
)-1 )
965 for(m
=0; (m
<dumnral
) && !bKeep
; m
++) {
968 plist
[pindex
[atom
].ftype
].param
[pindex
[atom
].parnr
].a
[m
+1];
969 for(n
=0; (n
<dumnral
) && !bPresent
; n
++)
970 if (constr
== dumatoms
[n
])
978 /* keep all dihedrals with no dummies in them */
982 /* check if all atoms in dihedral are either dummies, or used in
983 construction of dummies. If so, keep it, if not throw away: */
984 for(k
=0; (k
<4) && !bKeep
; k
++) { /* for all atoms in the dihedral */
985 atom
= ps
->param
[i
].a
[k
];
986 if (dummy_type
[atom
]==NOTSET
) {
988 for(m
=0; (m
<dumnral
) && !bUsed
; m
++)
989 if (atom
== dumatoms
[m
])
993 if (debug
) fprintf(debug
,"unused atom in dih: %u\n",atom
+1);
999 memcpy(&(ps
->param
[kept_i
]),
1000 &(ps
->param
[i
]),(size_t)sizeof(ps
->param
[0]));
1005 if (ps
->nr
!= kept_i
)
1006 fprintf(stderr
,"Removed %4d %15ss with dummy atoms, %5d left\n",
1007 ps
->nr
-kept_i
, interaction_function
[cftype
].longname
, kept_i
);
1011 void clean_dum_bondeds(t_params
*plist
, int natoms
, bool bRmDumBds
)
1013 int i
,k
,ndum
,ftype
,parnr
;
1017 pindex
=0; /* avoid warnings */
1018 /* make dummy_type array */
1019 snew(dummy_type
,natoms
);
1020 for(i
=0; i
<natoms
; i
++)
1021 dummy_type
[i
]=NOTSET
;
1023 for(ftype
=0; ftype
<F_NRE
; ftype
++)
1024 if (interaction_function
[ftype
].flags
& IF_DUMMY
) {
1025 ndum
+=plist
[ftype
].nr
;
1026 for(i
=0; i
<plist
[ftype
].nr
; i
++)
1027 if ( dummy_type
[plist
[ftype
].param
[i
].AI
] == NOTSET
)
1028 dummy_type
[plist
[ftype
].param
[i
].AI
]=ftype
;
1030 fatal_error(0,"multiple dummy constructions for atom %d",
1031 plist
[ftype
].param
[i
].AI
+1);
1034 /* the rest only if we have dummies: */
1036 fprintf(stderr
,"Cleaning up constraints %swith dummy particles\n",
1037 bRmDumBds
?"and constant bonded interactions ":"");
1038 snew(pindex
,natoms
);
1039 for(ftype
=0; ftype
<F_NRE
; ftype
++)
1040 if (interaction_function
[ftype
].flags
& IF_DUMMY
)
1041 for (parnr
=0; (parnr
<plist
[ftype
].nr
); parnr
++) {
1042 k
=plist
[ftype
].param
[parnr
].AI
;
1043 pindex
[k
].ftype
=ftype
;
1044 pindex
[k
].parnr
=parnr
;
1048 for(i
=0; i
<natoms
; i
++)
1049 fprintf(debug
,"atom %d dummy_type %s\n",i
,
1050 dummy_type
[i
]==NOTSET
? "NOTSET" :
1051 interaction_function
[dummy_type
[i
]].name
);
1053 /* remove things with dummy atoms */
1054 for(ftype
=0; ftype
<F_NRE
; ftype
++)
1055 if ( ( ( interaction_function
[ftype
].flags
& IF_BOND
) && bRmDumBds
) ||
1056 ( interaction_function
[ftype
].flags
& IF_CONSTRAINT
) ) {
1057 if (interaction_function
[ftype
].flags
& (IF_BTYPE
| IF_CONSTRAINT
) )
1058 clean_dum_bonds (plist
, pindex
, ftype
, dummy_type
);
1059 else if (interaction_function
[ftype
].flags
& IF_ATYPE
)
1060 clean_dum_angles(plist
, pindex
, ftype
, dummy_type
);
1061 else if ( (ftype
==F_PDIHS
) || (ftype
==F_IDIHS
) )
1062 clean_dum_dihs (plist
, pindex
, ftype
, dummy_type
);
1064 /* check if we have constraints left with dummy atoms in them */
1065 for(ftype
=0; ftype
<F_NRE
; ftype
++)
1066 if (interaction_function
[ftype
].flags
& IF_CONSTRAINT
)
1067 check_dum_constraints(plist
, ftype
, dummy_type
);