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
, gmx_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 (gmx_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 (gmx_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
,DIR_SEPARATOR
)) != 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 gmx_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 /* We need to open the output file before opening the input file,
543 * because cpp_open_file can change the current working directory.
546 out
= gmx_fio_fopen(outfile
,"w");
551 /* open input file */
552 status
= cpp_open_file(infile
,&handle
,cpp_opts(define
,include
,infile
,wi
));
554 gmx_fatal(FARGS
,cpp_error(&handle
,status
));
556 /* some local variables */
557 DS_Init(&DS
); /* directive stack */
558 nmol
= 0; /* no molecules yet... */
559 d
= d_invalid
; /* first thing should be a directive */
560 nbparam
= NULL
; /* The temporary non-bonded matrix */
561 pair
= NULL
; /* The temporary pair interaction matrix */
562 block2
= NULL
; /* the extra exclusions */
564 *reppow
= 12.0; /* Default value for repulsion power */
568 /* Init the number of CMAP torsion angles and grid spacing */
569 plist
->grid_spacing
= 0;
572 bWarn_copy_A_B
= bFEP
;
574 batype
= init_bond_atomtype();
575 /* parse the actual file */
576 bReadDefaults
= FALSE
;
578 bReadMolType
= FALSE
;
582 status
= cpp_read_line(&handle
,STRLEN
,line
);
583 done
= (status
== eCPP_EOF
);
585 if (status
!= eCPP_OK
)
586 gmx_fatal(FARGS
,cpp_error(&handle
,status
));
588 fprintf(out
,"%s\n",line
);
590 set_warning_line(wi
,cpp_cur_file(&handle
),cpp_cur_linenr(&handle
));
592 pline
= strdup(line
);
594 /* Strip trailing '\' from pline, if it exists */
596 if ((sl
> 0) && (pline
[sl
-1] == CONTINUE
)) {
600 /* build one long line from several fragments - necessary for CMAP */
601 while (continuing(line
))
603 status
= cpp_read_line(&handle
,STRLEN
,line
);
604 set_warning_line(wi
,cpp_cur_file(&handle
),cpp_cur_linenr(&handle
));
606 /* Since we depend on the '\' being present to continue to read, we copy line
607 * to a tmp string, strip the '\' from that string, and cat it to pline
609 tmp_line
=strdup(line
);
611 sl
= strlen(tmp_line
);
612 if ((sl
> 0) && (tmp_line
[sl
-1] == CONTINUE
)) {
613 tmp_line
[sl
-1] = ' ';
616 done
= (status
== eCPP_EOF
);
618 if (status
!= eCPP_OK
)
619 gmx_fatal(FARGS
,cpp_error(&handle
,status
));
621 fprintf(out
,"%s\n",line
);
624 srenew(pline
,strlen(pline
)+strlen(tmp_line
)+1);
625 strcat(pline
,tmp_line
);
629 /* skip trailing and leading spaces and comment text */
630 strip_comment (pline
);
633 /* if there is something left... */
634 if ((int)strlen(pline
) > 0) {
635 if (pline
[0] == OPENDIR
) {
636 /* A directive on this line: copy the directive
637 * without the brackets into dirstr, then
638 * skip spaces and tabs on either side of directive
640 dirstr
= strdup((pline
+1));
641 if ((dummy2
= strchr (dirstr
,CLOSEDIR
)) != NULL
)
645 if ((newd
= str2dir(dirstr
)) == d_invalid
) {
646 sprintf(errbuf
,"Invalid directive %s",dirstr
);
647 warning_error(wi
,errbuf
);
650 /* Directive found */
652 fprintf(debug
,"found directive '%s'\n",dir2str(newd
));
653 if (DS_Check_Order (DS
,newd
)) {
658 /* we should print here which directives should have
659 been present, and which actually are */
660 gmx_fatal(FARGS
,"%s\nInvalid order for directive %s",
661 cpp_error(&handle
,eCPP_SYNTAX
),dir2str(newd
));
667 else if (d
!= d_invalid
) {
668 /* Not a directive, just a plain string
669 * use a gigantic switch to decode,
670 * if there is a valid directive!
675 gmx_fatal(FARGS
,"%s\nFound a second defaults directive.\n",
676 cpp_error(&handle
,eCPP_SYNTAX
));
677 bReadDefaults
= TRUE
;
678 nscan
= sscanf(pline
,"%s%s%s%lf%lf%lf",
679 nb_str
,comb_str
,genpairs
,&fLJ
,&fQQ
,&fPOW
);
687 get_nbparm(nb_str
,comb_str
,&nb_funct
,&comb
,wi
);
688 *combination_rule
= comb
;
690 bGenPairs
= (gmx_strncasecmp(genpairs
,"Y",1) == 0);
691 if (nb_funct
!= eNBF_LJ
&& bGenPairs
) {
692 gmx_fatal(FARGS
,"Generating pair parameters is only supported with LJ non-bonded interactions");
702 nb_funct
= ifunc_index(d_nonbond_params
,nb_funct
);
706 push_at(symtab
,atype
,batype
,pline
,nb_funct
,
707 &nbparam
,bGenPairs
? &pair
: NULL
,wi
);
711 push_bt(d
,plist
,2,NULL
,batype
,pline
,wi
);
713 case d_constrainttypes
:
714 push_bt(d
,plist
,2,NULL
,batype
,pline
,wi
);
718 push_nbt(d
,pair
,atype
,pline
,F_LJ14
,wi
);
720 push_bt(d
,plist
,2,atype
,NULL
,pline
,wi
);
723 push_bt(d
,plist
,3,NULL
,batype
,pline
,wi
);
725 case d_dihedraltypes
:
726 /* Special routine that can read both 2 and 4 atom dihedral definitions. */
727 push_dihedraltype(d
,plist
,batype
,pline
,wi
);
730 case d_nonbond_params
:
731 push_nbt(d
,nbparam
,atype
,pline
,nb_funct
,wi
);
736 srenew(block,nblock);
737 srenew(blockinfo,nblock);
738 blk0=&(block[nblock-1]);
739 bi0=&(blockinfo[nblock-1]);
742 push_molt(symtab,bi0,pline);
746 case d_implicit_genborn_params
:
747 push_gb_params(atype
,pline
,wi
);
750 case d_implicit_surface_params
:
751 gmx_fatal(FARGS
,"Implicit surface directive not supported yet.");
755 push_cmaptype(d
, plist
, 5, atype
, batype
,pline
,wi
);
758 case d_moleculetype
: {
761 if (opts
->couple_moltype
!= NULL
&&
762 (opts
->couple_lam0
== ecouplamNONE
||
763 opts
->couple_lam0
== ecouplamQ
||
764 opts
->couple_lam1
== ecouplamNONE
||
765 opts
->couple_lam1
== ecouplamQ
))
767 dcatt
= add_atomtype_decoupled(symtab
,atype
,
768 &nbparam
,bGenPairs
?&pair
:NULL
);
770 ntype
= get_atomtype_ntypes(atype
);
771 ncombs
= (ntype
*(ntype
+1))/2;
772 generate_nbparams(comb
,nb_funct
,&(plist
[nb_funct
]),atype
,wi
);
773 ncopy
= copy_nbparams(nbparam
,nb_funct
,&(plist
[nb_funct
]),
775 fprintf(stderr
,"Generated %d of the %d non-bonded parameter combinations\n",ncombs
-ncopy
,ncombs
);
776 free_nbparam(nbparam
,ntype
);
778 gen_pairs(&(plist
[nb_funct
]),&(plist
[F_LJ14
]),fudgeLJ
,comb
,bVerbose
);
779 ncopy
= copy_nbparams(pair
,nb_funct
,&(plist
[F_LJ14
]),
781 fprintf(stderr
,"Generated %d of the %d 1-4 parameter combinations\n",ncombs
-ncopy
,ncombs
);
782 free_nbparam(pair
,ntype
);
784 /* Copy GBSA parameters to atomtype array? */
789 push_molt(symtab
,&nmol
,molinfo
,pline
,wi
);
792 mi0
=&((*molinfo
)[nmol
-1]);
796 push_atom(symtab
,&(mi0
->cgs
),&(mi0
->atoms
),atype
,pline
,&lastcg
,wi
);
800 push_bond(d
,plist
,mi0
->plist
,&(mi0
->atoms
),atype
,pline
,FALSE
,
801 bGenPairs
,*fudgeQQ
,bZero
,&bWarn_copy_A_B
,wi
);
811 case d_position_restraints
:
812 case d_angle_restraints
:
813 case d_angle_restraints_z
:
814 case d_distance_restraints
:
815 case d_orientation_restraints
:
816 case d_dihedral_restraints
:
819 case d_water_polarization
:
820 case d_thole_polarization
:
821 push_bond(d
,plist
,mi0
->plist
,&(mi0
->atoms
),atype
,pline
,TRUE
,
822 bGenPairs
,*fudgeQQ
,bZero
,&bWarn_copy_A_B
,wi
);
825 push_cmap(d
,plist
,mi0
->plist
,&(mi0
->atoms
),atype
,pline
,
830 push_vsitesn(d
,plist
,mi0
->plist
,&(mi0
->atoms
),atype
,pline
,wi
);
833 if (!block2
[nmol
-1].nr
)
834 init_block2(&(block2
[nmol
-1]),mi0
->atoms
.nr
);
835 push_excl(pline
,&(block2
[nmol
-1]));
839 title
=put_symtab(symtab
,pline
);
845 push_mol(nmol
,*molinfo
,pline
,&whichmol
,&nrcopies
,wi
);
846 mi0
=&((*molinfo
)[whichmol
]);
847 srenew(molb
,nmolb
+1);
848 molb
[nmolb
].type
= whichmol
;
849 molb
[nmolb
].nmol
= nrcopies
;
852 bCouple
= (opts
->couple_moltype
!= NULL
&&
853 (gmx_strcasecmp("system" ,opts
->couple_moltype
) == 0 ||
854 gmx_strcasecmp(*(mi0
->name
),opts
->couple_moltype
) == 0));
856 nmol_couple
+= nrcopies
;
859 if (mi0
->atoms
.nr
== 0) {
860 gmx_fatal(FARGS
,"Molecule type '%s' contains no atoms",
864 "Excluding %d bonded neighbours molecule type '%s'\n",
865 mi0
->nrexcl
,*mi0
->name
);
866 sum_q(&mi0
->atoms
,nrcopies
,&qt
,&qBt
);
867 if (!mi0
->bProcessed
)
870 generate_excl(mi0
->nrexcl
,
875 merge_excl(&(mi0
->excls
),&(block2
[whichmol
]));
876 done_block2(&(block2
[whichmol
]));
877 make_shake(mi0
->plist
,&mi0
->atoms
,atype
,opts
->nshake
);
881 /* nnb contains information about first,2nd,3rd bonded neighbors.
882 * Use this to generate GB 1-2,1-3,1-4 interactions when necessary.
886 generate_gb_exclusion_interactions(mi0
,atype
,&nnb
);
893 convert_moltype_couple(mi0
,dcatt
,*fudgeQQ
,
894 opts
->couple_lam0
,opts
->couple_lam1
,
896 nb_funct
,&(plist
[nb_funct
]));
898 stupid_fill_block(&mi0
->mols
,mi0
->atoms
.nr
,TRUE
);
899 mi0
->bProcessed
=TRUE
;
904 fprintf (stderr
,"case: %d\n",d
);
913 status
= cpp_close_file(&handle
);
914 if (status
!= eCPP_OK
)
915 gmx_fatal(FARGS
,cpp_error(&handle
,status
));
919 if (opts
->couple_moltype
) {
920 if (nmol_couple
== 0) {
921 gmx_fatal(FARGS
,"Did not find any molecules of type '%s' for coupling",
922 opts
->couple_moltype
);
924 fprintf(stderr
,"Coupling %d copies of molecule type '%s'\n",
925 nmol_couple
,opts
->couple_moltype
);
928 /* this is not very clean, but fixes core dump on empty system name */
930 title
=put_symtab(symtab
,"");
931 if (fabs(qt
) > 1e-4) {
932 sprintf(warn_buf
,"System has non-zero total charge: %e\n\n",qt
);
933 warning_note(wi
,warn_buf
);
935 if (fabs(qBt
) > 1e-4 && qBt
!= qt
) {
936 sprintf(warn_buf
,"State B has non-zero total charge: %e\n\n",qBt
);
937 warning_note(wi
,warn_buf
);
940 for(i
=0; i
<nmol
; i
++)
941 done_block2(&(block2
[i
]));
944 done_bond_atomtype(&batype
);
954 char **do_top(gmx_bool bVerbose
,
956 const char *topppfile
,
961 int *combination_rule
,
962 double *repulsion_power
,
964 gpp_atomtype_t atype
,
969 gmx_molblock_t
**molblock
,
973 /* Tmpfile might contain a long path */
988 printf("processing topology...\n");
990 title
= read_topol(topfile
,tmpfile
,opts
->define
,opts
->include
,
991 symtab
,atype
,nrmols
,molinfo
,
992 plist
,combination_rule
,repulsion_power
,
993 opts
,fudgeQQ
,nmolblock
,molblock
,
994 ir
->efep
!=efepNO
,bGenborn
,bZero
,bVerbose
,
996 if ((*combination_rule
!= eCOMB_GEOMETRIC
) &&
997 (ir
->vdwtype
== evdwUSER
))
999 warning(wi
,"Using sigma/epsilon based combination rules with"
1000 " user supplied potential function may produce unwanted"
1008 static void generate_qmexcl_moltype(gmx_moltype_t
*molt
,unsigned char *grpnr
,
1011 /* This routine expects molt->ilist to be of size F_NRE and ordered. */
1013 /* generates the exclusions between the individual QM atoms, as
1014 * these interactions should be handled by the QM subroutines and
1015 * not by the gromacs routines
1018 i
,j
,l
,k
=0,jmax
,qm_max
=0,qm_nr
=0,nratoms
=0,link_nr
=0,link_max
=0;
1020 *qm_arr
=NULL
,*link_arr
=NULL
,a1
,a2
,a3
,a4
,ftype
=0;
1026 *bQMMM
,*blink
,bexcl
;
1028 /* First we search and select the QM atoms in an qm_arr array that
1029 * we use to create the exclusions.
1031 * we take the possibility into account that a user has defined more
1032 * than one QM group:
1034 * for that we also need to do this an ugly work-about just in case
1035 * the QM group contains the entire system...
1037 fprintf(stderr
,"excluding classical QM-QM interactions...\n");
1039 jmax
= ir
->opts
.ngQM
;
1041 /* we first search for all the QM atoms and put them in an array
1043 for(j
=0;j
<jmax
;j
++){
1044 for(i
=0;i
<molt
->atoms
.nr
;i
++){
1047 srenew(qm_arr
,qm_max
);
1049 if ((grpnr
? grpnr
[i
] : 0) == j
){
1050 qm_arr
[qm_nr
++] = i
;
1054 /* bQMMM[..] is an array containin TRUE/FALSE for atoms that are
1055 * QM/not QM. We first set all elements to false. Afterwards we use
1056 * the qm_arr to change the elements corresponding to the QM atoms
1059 snew(bQMMM
,molt
->atoms
.nr
);
1060 for (i
=0;i
<molt
->atoms
.nr
;i
++)
1062 for (i
=0;i
<qm_nr
;i
++)
1063 bQMMM
[qm_arr
[i
]]=TRUE
;
1065 /* We remove all bonded interactions (i.e. bonds,
1066 * angles, dihedrals, 1-4's), involving the QM atoms. The way they
1067 * are removed is as follows: if the interaction invloves 2 atoms,
1068 * it is removed if both atoms are QMatoms. If it involves 3 atoms,
1069 * it is removed if at least two of the atoms are QM atoms, if the
1070 * interaction involves 4 atoms, it is removed if there are at least
1071 * 2 QM atoms. Since this routine is called once before any forces
1072 * are computed, the top->idef.il[N].iatom[] array (see idef.h) can
1073 * be rewritten at this poitn without any problem. 25-9-2002 */
1075 /* first check weter we already have CONNBONDS: */
1076 if (molt
->ilist
[F_CONNBONDS
].nr
!= 0){
1077 fprintf(stderr
,"nr. of CONNBONDS present already: %d\n",
1078 molt
->ilist
[F_CONNBONDS
].nr
/3);
1079 ftype
= molt
->ilist
[F_CONNBONDS
].iatoms
[0];
1080 k
= molt
->ilist
[F_CONNBONDS
].nr
;
1082 /* now we delete all bonded interactions, except the ones describing
1083 * a chemical bond. These are converted to CONNBONDS
1085 for (i
=0;i
<F_LJ
;i
++){
1088 nratoms
= interaction_function
[i
].nratoms
;
1090 while (j
<molt
->ilist
[i
].nr
){
1094 a1
= molt
->ilist
[i
].iatoms
[j
+1];
1095 a2
= molt
->ilist
[i
].iatoms
[j
+2];
1096 bexcl
= (bQMMM
[a1
] && bQMMM
[a2
]);
1097 /* a bonded beteen two QM atoms will be copied to the
1098 * CONNBONDS list, for reasons mentioned above
1100 if(bexcl
&& i
<F_ANGLES
){
1101 srenew(molt
->ilist
[F_CONNBONDS
].iatoms
,k
+3);
1102 molt
->ilist
[F_CONNBONDS
].nr
+= 3;
1103 molt
->ilist
[F_CONNBONDS
].iatoms
[k
++] = ftype
;
1104 molt
->ilist
[F_CONNBONDS
].iatoms
[k
++] = a1
;
1105 molt
->ilist
[F_CONNBONDS
].iatoms
[k
++] = a2
;
1109 a1
= molt
->ilist
[i
].iatoms
[j
+1];
1110 a2
= molt
->ilist
[i
].iatoms
[j
+2];
1111 a3
= molt
->ilist
[i
].iatoms
[j
+3];
1112 bexcl
= ((bQMMM
[a1
] && bQMMM
[a2
]) ||
1113 (bQMMM
[a1
] && bQMMM
[a3
]) ||
1114 (bQMMM
[a2
] && bQMMM
[a3
]));
1117 a1
= molt
->ilist
[i
].iatoms
[j
+1];
1118 a2
= molt
->ilist
[i
].iatoms
[j
+2];
1119 a3
= molt
->ilist
[i
].iatoms
[j
+3];
1120 a4
= molt
->ilist
[i
].iatoms
[j
+4];
1121 bexcl
= ((bQMMM
[a1
] && bQMMM
[a2
] && bQMMM
[a3
]) ||
1122 (bQMMM
[a1
] && bQMMM
[a2
] && bQMMM
[a4
]) ||
1123 (bQMMM
[a1
] && bQMMM
[a3
] && bQMMM
[a4
]) ||
1124 (bQMMM
[a2
] && bQMMM
[a3
] && bQMMM
[a4
]));
1127 gmx_fatal(FARGS
,"no such bonded interactions with %d atoms\n",nratoms
);
1130 /* since the interaction involves QM atoms, these should be
1131 * removed from the MM ilist
1133 molt
->ilist
[i
].nr
-= (nratoms
+1);
1134 for (l
=j
;l
<molt
->ilist
[i
].nr
;l
++)
1135 molt
->ilist
[i
].iatoms
[l
] = molt
->ilist
[i
].iatoms
[l
+(nratoms
+1)];
1137 j
+= nratoms
+1; /* the +1 is for the functype */
1141 /* Now, we search for atoms bonded to a QM atom because we also want
1142 * to exclude their nonbonded interactions with the QM atoms. The
1143 * reason for this is that this interaction is accounted for in the
1144 * linkatoms interaction with the QMatoms and would be counted
1147 for(i
=0;i
<F_NRE
;i
++){
1150 while(j
<molt
->ilist
[i
].nr
){
1151 a1
= molt
->ilist
[i
].iatoms
[j
+1];
1152 a2
= molt
->ilist
[i
].iatoms
[j
+2];
1153 if((bQMMM
[a1
] && !bQMMM
[a2
])||(!bQMMM
[a1
] && bQMMM
[a2
])){
1154 if(link_nr
>=link_max
){
1156 srenew(link_arr
,link_max
);
1159 link_arr
[link_nr
++] = a2
;
1161 link_arr
[link_nr
++] = a1
;
1168 snew(blink
,molt
->atoms
.nr
);
1169 for (i
=0;i
<molt
->atoms
.nr
;i
++)
1171 for (i
=0;i
<link_nr
;i
++)
1172 blink
[link_arr
[i
]]=TRUE
;
1173 /* creating the exclusion block for the QM atoms. Each QM atom has
1174 * as excluded elements all the other QMatoms (and itself).
1176 qmexcl
.nr
= molt
->atoms
.nr
;
1177 qmexcl
.nra
= qm_nr
*(qm_nr
+link_nr
)+link_nr
*qm_nr
;
1178 snew(qmexcl
.index
,qmexcl
.nr
+1);
1179 snew(qmexcl
.a
,qmexcl
.nra
);
1181 for(i
=0;i
<qmexcl
.nr
;i
++){
1184 for(k
=0;k
<qm_nr
;k
++){
1185 qmexcl
.a
[k
+j
] = qm_arr
[k
];
1187 for(k
=0;k
<link_nr
;k
++){
1188 qmexcl
.a
[qm_nr
+k
+j
] = link_arr
[k
];
1193 for(k
=0;k
<qm_nr
;k
++){
1194 qmexcl
.a
[k
+j
] = qm_arr
[k
];
1199 qmexcl
.index
[qmexcl
.nr
]=j
;
1201 /* and merging with the exclusions already present in sys.
1204 init_block2(&qmexcl2
,molt
->atoms
.nr
);
1205 b_to_b2(&qmexcl
, &qmexcl2
);
1206 merge_excl(&(molt
->excls
),&qmexcl2
);
1207 done_block2(&qmexcl2
);
1209 /* Finally, we also need to get rid of the pair interactions of the
1210 * classical atom bonded to the boundary QM atoms with the QMatoms,
1211 * as this interaction is already accounted for by the QM, so also
1212 * here we run the risk of double counting! We proceed in a similar
1213 * way as we did above for the other bonded interactions: */
1214 for (i
=F_LJ14
;i
<F_COUL14
;i
++){
1215 nratoms
= interaction_function
[i
].nratoms
;
1217 while (j
<molt
->ilist
[i
].nr
){
1219 a1
= molt
->ilist
[i
].iatoms
[j
+1];
1220 a2
= molt
->ilist
[i
].iatoms
[j
+2];
1221 bexcl
= ((bQMMM
[a1
] && bQMMM
[a2
])||
1222 (blink
[a1
] && bQMMM
[a2
])||
1223 (bQMMM
[a1
] && blink
[a2
]));
1225 /* since the interaction involves QM atoms, these should be
1226 * removed from the MM ilist
1228 molt
->ilist
[i
].nr
-= (nratoms
+1);
1229 for (k
=j
;k
<molt
->ilist
[i
].nr
;k
++)
1230 molt
->ilist
[i
].iatoms
[k
] = molt
->ilist
[i
].iatoms
[k
+(nratoms
+1)];
1232 j
+= nratoms
+1; /* the +1 is for the functype */
1241 } /* generate_qmexcl */
1243 void generate_qmexcl(gmx_mtop_t
*sys
,t_inputrec
*ir
)
1245 /* This routine expects molt->molt[m].ilist to be of size F_NRE and ordered.
1248 unsigned char *grpnr
;
1249 int mb
,mol
,nat_mol
,i
;
1250 gmx_molblock_t
*molb
;
1253 grpnr
= sys
->groups
.grpnr
[egcQMMM
];
1255 for(mb
=0; mb
<sys
->nmolblock
; mb
++) {
1256 molb
= &sys
->molblock
[mb
];
1257 nat_mol
= sys
->moltype
[molb
->type
].atoms
.nr
;
1258 for(mol
=0; mol
<molb
->nmol
; mol
++) {
1260 for(i
=0; i
<nat_mol
; i
++) {
1261 if ((grpnr
? grpnr
[i
] : 0) < ir
->opts
.ngQM
) {
1266 if (molb
->nmol
> 1) {
1267 /* We need to split this molblock */
1269 /* Split the molblock at this molecule */
1271 srenew(sys
->molblock
,sys
->nmolblock
);
1272 for(i
=mb
; i
<sys
->nmolblock
-1; i
++) {
1273 sys
->molblock
[i
+1] = sys
->molblock
[i
];
1275 sys
->molblock
[mb
].nmol
= mol
;
1276 sys
->molblock
[mb
+1].nmol
-= mol
;
1278 molb
= &sys
->molblock
[mb
];
1280 if (molb
->nmol
> 1) {
1281 /* Split the molblock after this molecule */
1283 srenew(sys
->molblock
,sys
->nmolblock
);
1284 for(i
=mb
; i
<sys
->nmolblock
-1; i
++) {
1285 sys
->molblock
[i
+1] = sys
->molblock
[i
];
1287 sys
->molblock
[mb
].nmol
= 1;
1288 sys
->molblock
[mb
+1].nmol
-= 1;
1291 /* Add a moltype for the QMMM molecule */
1293 srenew(sys
->moltype
,sys
->nmoltype
);
1294 /* Copy the moltype struct */
1295 sys
->moltype
[sys
->nmoltype
-1] = sys
->moltype
[molb
->type
];
1296 /* Copy the exclusions to a new array, since this is the only
1297 * thing that needs to be modified for QMMM.
1299 copy_blocka(&sys
->moltype
[molb
->type
].excls
,
1300 &sys
->moltype
[sys
->nmoltype
-1].excls
);
1301 /* Set the molecule type for the QMMM molblock */
1302 molb
->type
= sys
->nmoltype
- 1;
1305 generate_qmexcl_moltype(&sys
->moltype
[molb
->type
],grpnr
,ir
);