1 /* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
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
34 * Gallium Rubidium Oxygen Manganese Argon Carbon Silicon
41 #include <sys/types.h>
58 #include "gmx_fatal.h"
60 #include "vsite_parm.h"
66 #include "gpp_nextnb.h"
70 #include "gpp_bond_atomtype.h"
73 #define CPPMARK '#' /* mark from cpp */
74 #define OPENDIR '[' /* starting sign for directive */
75 #define CLOSEDIR ']' /* ending sign for directive */
78 printf("line: %d, maxavail: %d\n",__LINE__,maxavail()); \
81 static void free_nbparam(t_nbparam
**param
,int nr
)
90 static int copy_nbparams(t_nbparam
**param
,int ftype
,t_params
*plist
,int nr
)
100 if (param
[i
][j
].bSet
) {
101 for(f
=0; f
<nrfp
; f
++) {
102 plist
->param
[nr
*i
+j
].c
[f
] = param
[i
][j
].c
[f
];
103 plist
->param
[nr
*j
+i
].c
[f
] = param
[i
][j
].c
[f
];
111 static void gen_pairs(t_params
*nbs
,t_params
*pairs
,real fudge
, int comb
, bool bVerbose
)
113 int i
,j
,ntp
,nrfp
,nrfpA
,nrfpB
,nnn
;
118 nrfpA
= interaction_function
[F_LJ14
].nrfpA
;
119 nrfpB
= interaction_function
[F_LJ14
].nrfpB
;
122 if ((nrfp
!= nrfpA
) || (nrfpA
!= nrfpB
))
123 gmx_incons("Number of force parameters in gen_pairs wrong");
125 fprintf(stderr
,"Generating 1-4 interactions: fudge = %g\n",fudge
);
127 fprintf(debug
,"Fudge factor for 1-4 interactions: %g\n",fudge
);
128 fprintf(debug
,"Holy Cow! there are %d types\n",ntp
);
130 snew(pairs
->param
,pairs
->nr
);
131 for(i
=0; (i
<ntp
); i
++) {
133 pairs
->param
[i
].a
[0] = i
/ nnn
;
134 pairs
->param
[i
].a
[1] = i
% nnn
;
135 /* Copy normal and FEP parameters and multiply by fudge factor */
139 for(j
=0; (j
<nrfp
); j
++) {
140 /* If we are using sigma/epsilon values, only the epsilon values
141 * should be scaled, but not sigma.
142 * The sigma values have even indices 0,2, etc.
144 if ((comb
== eCOMB_ARITHMETIC
|| comb
== eCOMB_GEOM_SIG_EPS
) && (j
%2==0))
149 pairs
->param
[i
].c
[j
]=scaling
*nbs
->param
[i
].c
[j
];
150 pairs
->param
[i
].c
[nrfp
+j
]=scaling
*nbs
->param
[i
].c
[j
];
155 double check_mol(gmx_mtop_t
*mtop
,warninp_t wi
)
163 /* Check mass and charge */
166 for(mb
=0; mb
<mtop
->nmoltype
; mb
++) {
167 atoms
= &mtop
->moltype
[mtop
->molblock
[mb
].type
].atoms
;
168 nmol
= mtop
->molblock
[mb
].nmol
;
169 for (i
=0; (i
<atoms
->nr
); i
++) {
170 q
+= nmol
*atoms
->atom
[i
].q
;
171 m
= atoms
->atom
[i
].m
;
172 pt
= atoms
->atom
[i
].ptype
;
173 /* If the particle is an atom or a nucleus it must have a mass,
174 * else, if it is a shell, a vsite or a bondshell it can have mass zero
176 if ((m
<= 0.0) && ((pt
== eptAtom
) || (pt
== eptNucleus
))) {
177 ri
= atoms
->atom
[i
].resind
;
178 sprintf(buf
,"atom %s (Res %s-%d) has mass %g\n",
179 *(atoms
->atomname
[i
]),
180 *(atoms
->resinfo
[ri
].name
),
181 atoms
->resinfo
[ri
].nr
,
183 warning_error(wi
,buf
);
185 if ((m
!=0) && (pt
== eptVSite
)) {
186 ri
= atoms
->atom
[i
].resind
;
187 sprintf(buf
,"virtual site %s (Res %s-%d) has non-zero mass %g\n"
188 " Check your topology.\n",
189 *(atoms
->atomname
[i
]),
190 *(atoms
->resinfo
[ri
].name
),
191 atoms
->resinfo
[ri
].nr
,
193 warning_error(wi
,buf
);
194 /* The following statements make LINCS break! */
195 /* atoms->atom[i].m=0; */
202 static void sum_q(t_atoms
*atoms
,int n
,double *qt
,double *qBt
)
210 for (i
=0; i
<atoms
->nr
; i
++)
212 qmolA
+= atoms
->atom
[i
].q
;
213 qmolB
+= atoms
->atom
[i
].qB
;
215 /* Unfortunately an absolute comparison,
216 * but this avoids unnecessary warnings and gmx-users mails.
218 if (fabs(qmolA
) >= 1e-6 || fabs(qmolB
) >= 1e-6)
225 static void get_nbparm(char *nb_str
,char *comb_str
,int *nb
,int *comb
,
229 char warn_buf
[STRLEN
];
232 for(i
=1; (i
<eNBF_NR
); i
++)
233 if (strcasecmp(nb_str
,enbf_names
[i
]) == 0)
236 *nb
= strtol(nb_str
,NULL
,10);
237 if ((*nb
< 1) || (*nb
>= eNBF_NR
)) {
238 sprintf(warn_buf
,"Invalid nonbond function selector '%s' using %s",
239 nb_str
,enbf_names
[1]);
240 warning_error(wi
,warn_buf
);
244 for(i
=1; (i
<eCOMB_NR
); i
++)
245 if (strcasecmp(comb_str
,ecomb_names
[i
]) == 0)
248 *comb
= strtol(comb_str
,NULL
,10);
249 if ((*comb
< 1) || (*comb
>= eCOMB_NR
)) {
250 sprintf(warn_buf
,"Invalid combination rule selector '%s' using %s",
251 comb_str
,ecomb_names
[1]);
252 warning_error(wi
,warn_buf
);
257 static char ** cpp_opts(const char *define
,const char *include
,
263 const char *cppadds
[2];
264 char **cppopts
= NULL
;
265 const char *option
[2] = { "-D","-I" };
266 const char *nopt
[2] = { "define", "include" };
270 char warn_buf
[STRLEN
];
273 cppadds
[1] = include
;
274 for(n
=0; (n
<2); n
++) {
277 while(*ptr
!= '\0') {
278 while((*ptr
!= '\0') && isspace(*ptr
))
281 while((*rptr
!= '\0') && !isspace(*rptr
))
286 strncpy(buf
,ptr
,len
);
287 if (strstr(ptr
,option
[n
]) != ptr
) {
288 set_warning_line(wi
,"mdp file",-1);
289 sprintf(warn_buf
,"Malformed %s option %s",nopt
[n
],buf
);
290 warning(wi
,warn_buf
);
293 srenew(cppopts
,++ncppopts
);
294 cppopts
[ncppopts
-1] = strdup(buf
);
302 if ((rptr
=strrchr(infile
,'/')) != NULL
) {
303 buf
= strdup(infile
);
304 buf
[(int)(rptr
-infile
)] = '\0';
305 srenew(cppopts
,++ncppopts
);
306 snew(cppopts
[ncppopts
-1],strlen(buf
)+4);
307 sprintf(cppopts
[ncppopts
-1],"-I%s",buf
);
310 srenew(cppopts
,++ncppopts
);
311 cppopts
[ncppopts
-1] = NULL
;
318 find_gb_bondlength(t_params
*plist
,int ai
,int aj
, real
*length
)
325 for(i
=0;i
<F_NRE
&& !found
;i
++)
329 for(j
=0;j
<plist
[i
].nr
; j
++)
331 a1
=plist
[i
].param
[j
].a
[0];
332 a2
=plist
[i
].param
[j
].a
[1];
334 if( (a1
==ai
&& a2
==aj
) || (a1
==aj
&& a2
==ai
))
336 /* Equilibrium bond distance */
337 *length
=plist
[i
].param
[j
].c
[0];
350 find_gb_anglelength(t_params
*plist
,int ai
,int ak
, real
*length
)
355 int status
,status1
,status2
;
359 for(i
=0;i
<F_NRE
&& !found
;i
++)
363 for(j
=0;j
<plist
[i
].nr
; j
++)
365 a1
=plist
[i
].param
[j
].a
[0];
366 a2
=plist
[i
].param
[j
].a
[1];
367 a3
=plist
[i
].param
[j
].a
[2];
369 /* We dont care what the middle atom is, but use it below */
370 if( (a1
==ai
&& a3
==ak
) || (a1
==ak
&& a3
==ai
) )
372 /* Equilibrium bond distance */
373 a123
= plist
[i
].param
[j
].c
[0];
374 /* Use middle atom to find reference distances r12 and r23 */
375 status1
= find_gb_bondlength(plist
,a1
,a2
,&r12
);
376 status2
= find_gb_bondlength(plist
,a2
,a3
,&r23
);
378 if(status1
==0 && status2
==0)
380 /* cosine theorem to get r13 */
381 *length
=sqrt(r12
*r12
+r23
*r23
-(2*r12
*r23
*cos(a123
/RAD2DEG
)));
394 generate_gb_exclusion_interactions(t_molinfo
*mi
,gpp_atomtype_t atype
,t_nextnb
*nnb
)
396 int i
,j
,k
,n
,ai
,aj
,ti
,tj
;
402 real radiusi
,radiusj
;
403 real gb_radiusi
,gb_radiusj
;
404 real param_c2
,param_c4
;
410 for(n
=1;n
<=nnb
->nrex
;n
++)
425 /* Put all higher-order exclusions into 1,4 list so we dont miss them */
432 for(ai
=0;ai
<nnb
->nr
;ai
++)
434 ti
= at
->atom
[ai
].type
;
435 radiusi
= get_atomtype_radius(ti
,atype
);
436 gb_radiusi
= get_atomtype_gb_radius(ti
,atype
);
438 for(j
=0;j
<nnb
->nrexcl
[ai
][n
];j
++)
440 aj
= nnb
->a
[ai
][n
][j
];
442 /* Only add the interactions once */
445 tj
= at
->atom
[aj
].type
;
446 radiusj
= get_atomtype_radius(tj
,atype
);
447 gb_radiusj
= get_atomtype_gb_radius(tj
,atype
);
449 /* There is an exclusion of type "ftype" between atoms ai and aj */
453 /* Reference distance, not used for 1-4 interactions */
457 if(find_gb_bondlength(plist
,ai
,aj
,&distance
)!=0)
459 gmx_fatal(FARGS
,"Cannot find bond length for atoms %d-%d",ai
,aj
);
463 if(find_gb_anglelength(plist
,ai
,aj
,&distance
)!=0)
465 gmx_fatal(FARGS
,"Cannot find length for atoms %d-%d involved in angle",ai
,aj
);
472 /* Assign GB parameters */
474 param
.c
[0] = radiusi
+radiusj
;
475 /* Reference distance distance */
476 param
.c
[1] = distance
;
477 /* Still parameter */
478 param
.c
[2] = param_c2
;
480 param
.c
[3] = gb_radiusi
+gb_radiusj
;
482 param
.c
[4] = param_c4
;
484 /* Add it to the parameter list */
485 add_param_to_list(&plist
[ftype
],¶m
);
496 static char **read_topol(const char *infile
,const char *outfile
,
497 const char *define
,const char *include
,
499 gpp_atomtype_t atype
,
503 int *combination_rule
,
508 gmx_molblock_t
**molblock
,
516 int i
,sl
,nb_funct
,comb
;
517 char *pline
=NULL
,**title
=NULL
;
518 char line
[STRLEN
],errbuf
[256],comb_str
[256],nb_str
[256];
520 char *dirstr
,*dummy2
;
521 int nrcopies
,nmol
,nmolb
=0,nscan
,ncombs
,ncopy
;
523 gmx_molblock_t
*molb
=NULL
;
524 t_topology
*block
=NULL
;
528 t_nbparam
**nbparam
,**pair
;
530 real fudgeLJ
=-1; /* Multiplication factor to generate 1-4 from LJ */
531 bool bReadDefaults
,bReadMolType
,bGenPairs
,bWarn_copy_A_B
;
532 double qt
=0,qBt
=0; /* total charge */
533 t_bond_atomtype batype
;
535 int dcatt
=-1,nmol_couple
;
536 /* File handling variables */
540 char warn_buf
[STRLEN
];
542 /* open input and output file */
543 status
= cpp_open_file(infile
,&handle
,cpp_opts(define
,include
,infile
,wi
));
545 gmx_fatal(FARGS
,cpp_error(&handle
,status
));
547 out
= gmx_fio_fopen(outfile
,"w");
550 /* some local variables */
551 DS_Init(&DS
); /* directive stack */
552 nmol
= 0; /* no molecules yet... */
553 d
= d_invalid
; /* first thing should be a directive */
554 nbparam
= NULL
; /* The temporary non-bonded matrix */
555 pair
= NULL
; /* The temporary pair interaction matrix */
556 block2
= NULL
; /* the extra exclusions */
558 *reppow
= 12.0; /* Default value for repulsion power */
562 /* Init the number of CMAP torsion angles and grid spacing */
563 plist
->grid_spacing
= 0;
566 bWarn_copy_A_B
= bFEP
;
568 batype
= init_bond_atomtype();
569 /* parse the actual file */
570 bReadDefaults
= FALSE
;
572 bReadMolType
= FALSE
;
576 status
= cpp_read_line(&handle
,STRLEN
,line
);
577 done
= (status
== eCPP_EOF
);
579 if (status
!= eCPP_OK
)
580 gmx_fatal(FARGS
,cpp_error(&handle
,status
));
582 fprintf(out
,"%s\n",line
);
584 set_warning_line(wi
,cpp_cur_file(&handle
),cpp_cur_linenr(&handle
));
586 pline
= strdup(line
);
588 /* Strip trailing '\' from pline, if it exists */
590 if ((sl
> 0) && (pline
[sl
-1] == CONTINUE
)) {
594 /* build one long line from several fragments - necessary for CMAP */
595 while (continuing(line
))
597 status
= cpp_read_line(&handle
,STRLEN
,line
);
598 set_warning_line(wi
,cpp_cur_file(&handle
),cpp_cur_linenr(&handle
));
600 /* Since we depend on the '\' being present to continue to read, we copy line
601 * to a tmp string, strip the '\' from that string, and cat it to pline
603 tmp_line
=strdup(line
);
605 sl
= strlen(tmp_line
);
606 if ((sl
> 0) && (tmp_line
[sl
-1] == CONTINUE
)) {
607 tmp_line
[sl
-1] = ' ';
610 done
= (status
== eCPP_EOF
);
612 if (status
!= eCPP_OK
)
613 gmx_fatal(FARGS
,cpp_error(&handle
,status
));
615 fprintf(out
,"%s\n",line
);
618 srenew(pline
,strlen(pline
)+strlen(tmp_line
)+1);
619 strcat(pline
,tmp_line
);
623 /* skip trailing and leading spaces and comment text */
624 strip_comment (pline
);
627 /* if there is something left... */
628 if ((int)strlen(pline
) > 0) {
629 if (pline
[0] == OPENDIR
) {
630 /* A directive on this line: copy the directive
631 * without the brackets into dirstr, then
632 * skip spaces and tabs on either side of directive
634 dirstr
= strdup((pline
+1));
635 if ((dummy2
= strchr (dirstr
,CLOSEDIR
)) != NULL
)
639 if ((newd
= str2dir(dirstr
)) == d_invalid
) {
640 sprintf(errbuf
,"Invalid directive %s",dirstr
);
641 warning_error(wi
,errbuf
);
644 /* Directive found */
646 fprintf(debug
,"found directive '%s'\n",dir2str(newd
));
647 if (DS_Check_Order (DS
,newd
)) {
652 /* we should print here which directives should have
653 been present, and which actually are */
654 gmx_fatal(FARGS
,"%s\nInvalid order for directive %s",
655 cpp_error(&handle
,eCPP_SYNTAX
),dir2str(newd
));
661 else if (d
!= d_invalid
) {
662 /* Not a directive, just a plain string
663 * use a gigantic switch to decode,
664 * if there is a valid directive!
669 gmx_fatal(FARGS
,"%s\nFound a second defaults directive.\n",
670 cpp_error(&handle
,eCPP_SYNTAX
));
671 bReadDefaults
= TRUE
;
672 nscan
= sscanf(pline
,"%s%s%s%lf%lf%lf",
673 nb_str
,comb_str
,genpairs
,&fLJ
,&fQQ
,&fPOW
);
681 get_nbparm(nb_str
,comb_str
,&nb_funct
,&comb
,wi
);
682 *combination_rule
= comb
;
684 bGenPairs
= (strncasecmp(genpairs
,"Y",1) == 0);
685 if (nb_funct
!= eNBF_LJ
&& bGenPairs
) {
686 gmx_fatal(FARGS
,"Generating pair parameters is only supported with LJ non-bonded interactions");
696 nb_funct
= ifunc_index(d_nonbond_params
,nb_funct
);
700 push_at(symtab
,atype
,batype
,pline
,nb_funct
,
701 &nbparam
,bGenPairs
? &pair
: NULL
,wi
);
705 push_bt(d
,plist
,2,NULL
,batype
,pline
,wi
);
707 case d_constrainttypes
:
708 push_bt(d
,plist
,2,NULL
,batype
,pline
,wi
);
712 push_nbt(d
,pair
,atype
,pline
,F_LJ14
,wi
);
714 push_bt(d
,plist
,2,atype
,NULL
,pline
,wi
);
717 push_bt(d
,plist
,3,NULL
,batype
,pline
,wi
);
719 case d_dihedraltypes
:
720 /* Special routine that can read both 2 and 4 atom dihedral definitions. */
721 push_dihedraltype(d
,plist
,batype
,pline
,wi
);
724 case d_nonbond_params
:
725 push_nbt(d
,nbparam
,atype
,pline
,nb_funct
,wi
);
730 srenew(block,nblock);
731 srenew(blockinfo,nblock);
732 blk0=&(block[nblock-1]);
733 bi0=&(blockinfo[nblock-1]);
736 push_molt(symtab,bi0,pline);
740 case d_implicit_genborn_params
:
741 push_gb_params(atype
,pline
,wi
);
744 case d_implicit_surface_params
:
745 gmx_fatal(FARGS
,"Implicit surface directive not supported yet.");
749 push_cmaptype(d
, plist
, 5, atype
, batype
,pline
,wi
);
752 case d_moleculetype
: {
755 if (opts
->couple_moltype
!= NULL
&&
756 (opts
->couple_lam0
== ecouplamNONE
||
757 opts
->couple_lam0
== ecouplamQ
||
758 opts
->couple_lam1
== ecouplamNONE
||
759 opts
->couple_lam1
== ecouplamQ
))
761 dcatt
= add_atomtype_decoupled(symtab
,atype
,
762 &nbparam
,bGenPairs
?&pair
:NULL
);
764 ntype
= get_atomtype_ntypes(atype
);
765 ncombs
= (ntype
*(ntype
+1))/2;
766 generate_nbparams(comb
,nb_funct
,&(plist
[nb_funct
]),atype
,wi
);
767 ncopy
= copy_nbparams(nbparam
,nb_funct
,&(plist
[nb_funct
]),
769 fprintf(stderr
,"Generated %d of the %d non-bonded parameter combinations\n",ncombs
-ncopy
,ncombs
);
770 free_nbparam(nbparam
,ntype
);
772 gen_pairs(&(plist
[nb_funct
]),&(plist
[F_LJ14
]),fudgeLJ
,comb
,bVerbose
);
773 ncopy
= copy_nbparams(pair
,nb_funct
,&(plist
[F_LJ14
]),
775 fprintf(stderr
,"Generated %d of the %d 1-4 parameter combinations\n",ncombs
-ncopy
,ncombs
);
776 free_nbparam(pair
,ntype
);
778 /* Copy GBSA parameters to atomtype array? */
783 push_molt(symtab
,&nmol
,molinfo
,pline
,wi
);
786 mi0
=&((*molinfo
)[nmol
-1]);
790 push_atom(symtab
,&(mi0
->cgs
),&(mi0
->atoms
),atype
,pline
,&lastcg
,wi
);
794 push_bond(d
,plist
,mi0
->plist
,&(mi0
->atoms
),atype
,pline
,FALSE
,
795 bGenPairs
,*fudgeQQ
,bZero
,&bWarn_copy_A_B
,wi
);
805 case d_position_restraints
:
806 case d_angle_restraints
:
807 case d_angle_restraints_z
:
808 case d_distance_restraints
:
809 case d_orientation_restraints
:
810 case d_dihedral_restraints
:
813 case d_water_polarization
:
814 case d_thole_polarization
:
815 push_bond(d
,plist
,mi0
->plist
,&(mi0
->atoms
),atype
,pline
,TRUE
,
816 bGenPairs
,*fudgeQQ
,bZero
,&bWarn_copy_A_B
,wi
);
819 push_cmap(d
,plist
,mi0
->plist
,&(mi0
->atoms
),atype
,pline
,
824 push_vsitesn(d
,plist
,mi0
->plist
,&(mi0
->atoms
),atype
,pline
,wi
);
827 if (!block2
[nmol
-1].nr
)
828 init_block2(&(block2
[nmol
-1]),mi0
->atoms
.nr
);
829 push_excl(pline
,&(block2
[nmol
-1]));
833 title
=put_symtab(symtab
,pline
);
839 push_mol(nmol
,*molinfo
,pline
,&whichmol
,&nrcopies
,wi
);
840 mi0
=&((*molinfo
)[whichmol
]);
841 srenew(molb
,nmolb
+1);
842 molb
[nmolb
].type
= whichmol
;
843 molb
[nmolb
].nmol
= nrcopies
;
846 bCouple
= (opts
->couple_moltype
!= NULL
&&
847 (strcmp("system" ,opts
->couple_moltype
) == 0 ||
848 strcmp(*(mi0
->name
),opts
->couple_moltype
) == 0));
850 nmol_couple
+= nrcopies
;
853 if (mi0
->atoms
.nr
== 0) {
854 gmx_fatal(FARGS
,"Molecule type '%s' contains no atoms",
858 "Excluding %d bonded neighbours molecule type '%s'\n",
859 mi0
->nrexcl
,*mi0
->name
);
860 sum_q(&mi0
->atoms
,nrcopies
,&qt
,&qBt
);
861 if (!mi0
->bProcessed
)
864 generate_excl(mi0
->nrexcl
,
869 merge_excl(&(mi0
->excls
),&(block2
[whichmol
]));
870 done_block2(&(block2
[whichmol
]));
871 make_shake(mi0
->plist
,&mi0
->atoms
,atype
,opts
->nshake
);
875 /* nnb contains information about first,2nd,3rd bonded neighbors.
876 * Use this to generate GB 1-2,1-3,1-4 interactions when necessary.
880 generate_gb_exclusion_interactions(mi0
,atype
,&nnb
);
887 convert_moltype_couple(mi0
,dcatt
,*fudgeQQ
,
888 opts
->couple_lam0
,opts
->couple_lam1
,
890 nb_funct
,&(plist
[nb_funct
]));
892 stupid_fill_block(&mi0
->mols
,mi0
->atoms
.nr
,TRUE
);
893 mi0
->bProcessed
=TRUE
;
898 fprintf (stderr
,"case: %d\n",d
);
907 status
= cpp_close_file(&handle
);
908 if (status
!= eCPP_OK
)
909 gmx_fatal(FARGS
,cpp_error(&handle
,status
));
913 if (opts
->couple_moltype
) {
914 if (nmol_couple
== 0) {
915 gmx_fatal(FARGS
,"Did not find any molecules of type '%s' for coupling",
916 opts
->couple_moltype
);
918 fprintf(stderr
,"Coupling %d copies of molecule type '%s'\n",
919 nmol_couple
,opts
->couple_moltype
);
922 /* this is not very clean, but fixes core dump on empty system name */
924 title
=put_symtab(symtab
,"");
925 if (fabs(qt
) > 1e-4) {
926 sprintf(warn_buf
,"System has non-zero total charge: %e\n\n",qt
);
927 warning_note(wi
,warn_buf
);
929 if (fabs(qBt
) > 1e-4 && qBt
!= qt
) {
930 sprintf(warn_buf
,"State B has non-zero total charge: %e\n\n",qBt
);
931 warning_note(wi
,warn_buf
);
934 for(i
=0; i
<nmol
; i
++)
935 done_block2(&(block2
[i
]));
938 done_bond_atomtype(&batype
);
948 char **do_top(bool bVerbose
,
950 const char *topppfile
,
955 int *combination_rule
,
956 double *repulsion_power
,
958 gpp_atomtype_t atype
,
963 gmx_molblock_t
**molblock
,
967 /* Tmpfile might contain a long path */
982 printf("processing topology...\n");
984 title
= read_topol(topfile
,tmpfile
,opts
->define
,opts
->include
,
985 symtab
,atype
,nrmols
,molinfo
,
986 plist
,combination_rule
,repulsion_power
,
987 opts
,fudgeQQ
,nmolblock
,molblock
,
988 ir
->efep
!=efepNO
,bGenborn
,bZero
,bVerbose
,
990 if ((*combination_rule
!= eCOMB_GEOMETRIC
) &&
991 (ir
->vdwtype
== evdwUSER
))
993 warning(wi
,"Using sigma/epsilon based combination rules with"
994 " user supplied potential function may produce unwanted"
1002 static void generate_qmexcl_moltype(gmx_moltype_t
*molt
,unsigned char *grpnr
,
1005 /* This routine expects molt->ilist to be of size F_NRE and ordered. */
1007 /* generates the exclusions between the individual QM atoms, as
1008 * these interactions should be handled by the QM subroutines and
1009 * not by the gromacs routines
1012 i
,j
,l
,k
=0,jmax
,qm_max
=0,qm_nr
=0,nratoms
=0,link_nr
=0,link_max
=0;
1014 *qm_arr
=NULL
,*link_arr
=NULL
,a1
,a2
,a3
,a4
,ftype
=0;
1020 *bQMMM
,*blink
,bexcl
;
1022 /* First we search and select the QM atoms in an qm_arr array that
1023 * we use to create the exclusions.
1025 * we take the possibility into account that a user has defined more
1026 * than one QM group:
1028 * for that we also need to do this an ugly work-about just in case
1029 * the QM group contains the entire system...
1031 fprintf(stderr
,"excluding classical QM-QM interactions...\n");
1033 jmax
= ir
->opts
.ngQM
;
1035 /* we first search for all the QM atoms and put them in an array
1037 for(j
=0;j
<jmax
;j
++){
1038 for(i
=0;i
<molt
->atoms
.nr
;i
++){
1041 srenew(qm_arr
,qm_max
);
1043 if ((grpnr
? grpnr
[i
] : 0) == j
){
1044 qm_arr
[qm_nr
++] = i
;
1048 /* bQMMM[..] is an array containin TRUE/FALSE for atoms that are
1049 * QM/not QM. We first set all elements to false. Afterwards we use
1050 * the qm_arr to change the elements corresponding to the QM atoms
1053 snew(bQMMM
,molt
->atoms
.nr
);
1054 for (i
=0;i
<molt
->atoms
.nr
;i
++)
1056 for (i
=0;i
<qm_nr
;i
++)
1057 bQMMM
[qm_arr
[i
]]=TRUE
;
1059 /* We remove all bonded interactions (i.e. bonds,
1060 * angles, dihedrals, 1-4's), involving the QM atoms. The way they
1061 * are removed is as follows: if the interaction invloves 2 atoms,
1062 * it is removed if both atoms are QMatoms. If it involves 3 atoms,
1063 * it is removed if at least two of the atoms are QM atoms, if the
1064 * interaction involves 4 atoms, it is removed if there are at least
1065 * 2 QM atoms. Since this routine is called once before any forces
1066 * are computed, the top->idef.il[N].iatom[] array (see idef.h) can
1067 * be rewritten at this poitn without any problem. 25-9-2002 */
1069 /* first check weter we already have CONNBONDS: */
1070 if (molt
->ilist
[F_CONNBONDS
].nr
!= 0){
1071 fprintf(stderr
,"nr. of CONNBONDS present already: %d\n",
1072 molt
->ilist
[F_CONNBONDS
].nr
/3);
1073 ftype
= molt
->ilist
[F_CONNBONDS
].iatoms
[0];
1074 k
= molt
->ilist
[F_CONNBONDS
].nr
;
1076 /* now we delete all bonded interactions, except the ones describing
1077 * a chemical bond. These are converted to CONNBONDS
1079 for (i
=0;i
<F_LJ
;i
++){
1082 nratoms
= interaction_function
[i
].nratoms
;
1084 while (j
<molt
->ilist
[i
].nr
){
1088 a1
= molt
->ilist
[i
].iatoms
[j
+1];
1089 a2
= molt
->ilist
[i
].iatoms
[j
+2];
1090 bexcl
= (bQMMM
[a1
] && bQMMM
[a2
]);
1091 /* a bonded beteen two QM atoms will be copied to the
1092 * CONNBONDS list, for reasons mentioned above
1094 if(bexcl
&& i
<F_ANGLES
){
1095 srenew(molt
->ilist
[F_CONNBONDS
].iatoms
,k
+3);
1096 molt
->ilist
[F_CONNBONDS
].nr
+= 3;
1097 molt
->ilist
[F_CONNBONDS
].iatoms
[k
++] = ftype
;
1098 molt
->ilist
[F_CONNBONDS
].iatoms
[k
++] = a1
;
1099 molt
->ilist
[F_CONNBONDS
].iatoms
[k
++] = a2
;
1103 a1
= molt
->ilist
[i
].iatoms
[j
+1];
1104 a2
= molt
->ilist
[i
].iatoms
[j
+2];
1105 a3
= molt
->ilist
[i
].iatoms
[j
+3];
1106 bexcl
= ((bQMMM
[a1
] && bQMMM
[a2
]) ||
1107 (bQMMM
[a1
] && bQMMM
[a3
]) ||
1108 (bQMMM
[a2
] && bQMMM
[a3
]));
1111 a1
= molt
->ilist
[i
].iatoms
[j
+1];
1112 a2
= molt
->ilist
[i
].iatoms
[j
+2];
1113 a3
= molt
->ilist
[i
].iatoms
[j
+3];
1114 a4
= molt
->ilist
[i
].iatoms
[j
+4];
1115 bexcl
= ((bQMMM
[a1
] && bQMMM
[a2
] && bQMMM
[a3
]) ||
1116 (bQMMM
[a1
] && bQMMM
[a2
] && bQMMM
[a4
]) ||
1117 (bQMMM
[a1
] && bQMMM
[a3
] && bQMMM
[a4
]) ||
1118 (bQMMM
[a2
] && bQMMM
[a3
] && bQMMM
[a4
]));
1121 gmx_fatal(FARGS
,"no such bonded interactions with %d atoms\n",nratoms
);
1124 /* since the interaction involves QM atoms, these should be
1125 * removed from the MM ilist
1127 molt
->ilist
[i
].nr
-= (nratoms
+1);
1128 for (l
=j
;l
<molt
->ilist
[i
].nr
;l
++)
1129 molt
->ilist
[i
].iatoms
[l
] = molt
->ilist
[i
].iatoms
[l
+(nratoms
+1)];
1131 j
+= nratoms
+1; /* the +1 is for the functype */
1135 /* Now, we search for atoms bonded to a QM atom because we also want
1136 * to exclude their nonbonded interactions with the QM atoms. The
1137 * reason for this is that this interaction is accounted for in the
1138 * linkatoms interaction with the QMatoms and would be counted
1141 for(i
=0;i
<F_NRE
;i
++){
1144 while(j
<molt
->ilist
[i
].nr
){
1145 a1
= molt
->ilist
[i
].iatoms
[j
+1];
1146 a2
= molt
->ilist
[i
].iatoms
[j
+2];
1147 if((bQMMM
[a1
] && !bQMMM
[a2
])||(!bQMMM
[a1
] && bQMMM
[a2
])){
1148 if(link_nr
>=link_max
){
1150 srenew(link_arr
,link_max
);
1153 link_arr
[link_nr
++] = a2
;
1155 link_arr
[link_nr
++] = a1
;
1162 snew(blink
,molt
->atoms
.nr
);
1163 for (i
=0;i
<molt
->atoms
.nr
;i
++)
1165 for (i
=0;i
<link_nr
;i
++)
1166 blink
[link_arr
[i
]]=TRUE
;
1167 /* creating the exclusion block for the QM atoms. Each QM atom has
1168 * as excluded elements all the other QMatoms (and itself).
1170 qmexcl
.nr
= molt
->atoms
.nr
;
1171 qmexcl
.nra
= qm_nr
*(qm_nr
+link_nr
)+link_nr
*qm_nr
;
1172 snew(qmexcl
.index
,qmexcl
.nr
+1);
1173 snew(qmexcl
.a
,qmexcl
.nra
);
1175 for(i
=0;i
<qmexcl
.nr
;i
++){
1178 for(k
=0;k
<qm_nr
;k
++){
1179 qmexcl
.a
[k
+j
] = qm_arr
[k
];
1181 for(k
=0;k
<link_nr
;k
++){
1182 qmexcl
.a
[qm_nr
+k
+j
] = link_arr
[k
];
1187 for(k
=0;k
<qm_nr
;k
++){
1188 qmexcl
.a
[k
+j
] = qm_arr
[k
];
1193 qmexcl
.index
[qmexcl
.nr
]=j
;
1195 /* and merging with the exclusions already present in sys.
1198 init_block2(&qmexcl2
,molt
->atoms
.nr
);
1199 b_to_b2(&qmexcl
, &qmexcl2
);
1200 merge_excl(&(molt
->excls
),&qmexcl2
);
1201 done_block2(&qmexcl2
);
1203 /* Finally, we also need to get rid of the pair interactions of the
1204 * classical atom bonded to the boundary QM atoms with the QMatoms,
1205 * as this interaction is already accounted for by the QM, so also
1206 * here we run the risk of double counting! We proceed in a similar
1207 * way as we did above for the other bonded interactions: */
1208 for (i
=F_LJ14
;i
<F_COUL14
;i
++){
1209 nratoms
= interaction_function
[i
].nratoms
;
1211 while (j
<molt
->ilist
[i
].nr
){
1213 a1
= molt
->ilist
[i
].iatoms
[j
+1];
1214 a2
= molt
->ilist
[i
].iatoms
[j
+2];
1215 bexcl
= ((bQMMM
[a1
] && bQMMM
[a2
])||
1216 (blink
[a1
] && bQMMM
[a2
])||
1217 (bQMMM
[a1
] && blink
[a2
]));
1219 /* since the interaction involves QM atoms, these should be
1220 * removed from the MM ilist
1222 molt
->ilist
[i
].nr
-= (nratoms
+1);
1223 for (k
=j
;k
<molt
->ilist
[i
].nr
;k
++)
1224 molt
->ilist
[i
].iatoms
[k
] = molt
->ilist
[i
].iatoms
[k
+(nratoms
+1)];
1226 j
+= nratoms
+1; /* the +1 is for the functype */
1235 } /* generate_qmexcl */
1237 void generate_qmexcl(gmx_mtop_t
*sys
,t_inputrec
*ir
)
1239 /* This routine expects molt->molt[m].ilist to be of size F_NRE and ordered.
1242 unsigned char *grpnr
;
1243 int mb
,mol
,nat_mol
,i
;
1244 gmx_molblock_t
*molb
;
1247 grpnr
= sys
->groups
.grpnr
[egcQMMM
];
1249 for(mb
=0; mb
<sys
->nmolblock
; mb
++) {
1250 molb
= &sys
->molblock
[mb
];
1251 nat_mol
= sys
->moltype
[molb
->type
].atoms
.nr
;
1252 for(mol
=0; mol
<molb
->nmol
; mol
++) {
1254 for(i
=0; i
<nat_mol
; i
++) {
1255 if ((grpnr
? grpnr
[i
] : 0) < ir
->opts
.ngQM
) {
1260 if (molb
->nmol
> 1) {
1261 /* We need to split this molblock */
1263 /* Split the molblock at this molecule */
1265 srenew(sys
->molblock
,sys
->nmolblock
);
1266 for(i
=mb
; i
<sys
->nmolblock
-1; i
++) {
1267 sys
->molblock
[i
+1] = sys
->molblock
[i
];
1269 sys
->molblock
[mb
].nmol
= mol
;
1270 sys
->molblock
[mb
+1].nmol
-= mol
;
1272 molb
= &sys
->molblock
[mb
];
1274 if (molb
->nmol
> 1) {
1275 /* Split the molblock after this molecule */
1277 srenew(sys
->molblock
,sys
->nmolblock
);
1278 for(i
=mb
; i
<sys
->nmolblock
-1; i
++) {
1279 sys
->molblock
[i
+1] = sys
->molblock
[i
];
1281 sys
->molblock
[mb
].nmol
= 1;
1282 sys
->molblock
[mb
+1].nmol
-= 1;
1285 /* Add a moltype for the QMMM molecule */
1287 srenew(sys
->moltype
,sys
->nmoltype
);
1288 /* Copy the moltype struct */
1289 sys
->moltype
[sys
->nmoltype
-1] = sys
->moltype
[molb
->type
];
1290 /* Copy the exclusions to a new array, since this is the only
1291 * thing that needs to be modified for QMMM.
1293 copy_blocka(&sys
->moltype
[molb
->type
].excls
,
1294 &sys
->moltype
[sys
->nmoltype
-1].excls
);
1295 /* Set the molecule type for the QMMM molblock */
1296 molb
->type
= sys
->nmoltype
- 1;
1299 generate_qmexcl_moltype(&sys
->moltype
[molb
->type
],grpnr
,ir
);