2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5 * Copyright (c) 2001-2008, The GROMACS development team.
6 * Copyright (c) 2013,2014,2015,2017,2018, by the GROMACS development team, led by
7 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
8 * and including many others, as listed in the AUTHORS file in the
9 * top-level source directory and at http://www.gromacs.org.
11 * GROMACS is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public License
13 * as published by the Free Software Foundation; either version 2.1
14 * of the License, or (at your option) any later version.
16 * GROMACS is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with GROMACS; if not, see
23 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
24 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 * If you want to redistribute modifications to GROMACS, please
27 * consider that scientific software is very special. Version
28 * control is crucial - bugs must be traceable. We will be happy to
29 * consider code for inclusion in the official distribution, but
30 * derived work must not be called official GROMACS. Details are found
31 * in the README & COPYING files - if they are missing, get the
32 * official version at http://www.gromacs.org.
34 * To help us fund GROMACS development, we humbly ask that you cite
35 * the research papers on the package. Check out http://www.gromacs.org.
43 #include "gromacs/topology/ifunc.h"
44 #include "gromacs/topology/topology.h"
45 #include "gromacs/utility/arrayref.h"
46 #include "gromacs/utility/fatalerror.h"
47 #include "gromacs/utility/smalloc.h"
49 static gmx_bool
ip_pert(int ftype
, const t_iparams
*ip
)
54 if (NRFPB(ftype
) == 0)
67 bPert
= (ip
->harmonic
.rA
!= ip
->harmonic
.rB
||
68 ip
->harmonic
.krA
!= ip
->harmonic
.krB
);
71 bPert
= (ip
->morse
.b0A
!= ip
->morse
.b0B
||
72 ip
->morse
.cbA
!= ip
->morse
.cbB
||
73 ip
->morse
.betaA
!= ip
->morse
.betaB
);
76 bPert
= (ip
->restraint
.lowA
!= ip
->restraint
.lowB
||
77 ip
->restraint
.up1A
!= ip
->restraint
.up1B
||
78 ip
->restraint
.up2A
!= ip
->restraint
.up2B
||
79 ip
->restraint
.kA
!= ip
->restraint
.kB
);
82 bPert
= (ip
->u_b
.thetaA
!= ip
->u_b
.thetaB
||
83 ip
->u_b
.kthetaA
!= ip
->u_b
.kthetaB
||
84 ip
->u_b
.r13A
!= ip
->u_b
.r13B
||
85 ip
->u_b
.kUBA
!= ip
->u_b
.kUBB
);
91 bPert
= (ip
->pdihs
.phiA
!= ip
->pdihs
.phiB
||
92 ip
->pdihs
.cpA
!= ip
->pdihs
.cpB
);
96 for (i
= 0; i
< NR_RBDIHS
; i
++)
98 if (ip
->rbdihs
.rbcA
[i
] != ip
->rbdihs
.rbcB
[i
])
108 bPert
= (ip
->tab
.kA
!= ip
->tab
.kB
);
112 for (i
= 0; i
< DIM
; i
++)
114 if (ip
->posres
.pos0A
[i
] != ip
->posres
.pos0B
[i
] ||
115 ip
->posres
.fcA
[i
] != ip
->posres
.fcB
[i
])
122 bPert
= ((ip
->dihres
.phiA
!= ip
->dihres
.phiB
) ||
123 (ip
->dihres
.dphiA
!= ip
->dihres
.dphiB
) ||
124 (ip
->dihres
.kfacA
!= ip
->dihres
.kfacB
));
127 bPert
= (ip
->lj14
.c6A
!= ip
->lj14
.c6B
||
128 ip
->lj14
.c12A
!= ip
->lj14
.c12B
);
136 gmx_fatal(FARGS
, "Function type %s does not support currentely free energy calculations",
137 interaction_function
[ftype
].longname
);
139 gmx_fatal(FARGS
, "Function type %s not implemented in ip_pert",
140 interaction_function
[ftype
].longname
);
146 static gmx_bool
ip_q_pert(int ftype
, const t_iatom
*ia
,
147 const t_iparams
*ip
, const real
*qA
, const real
*qB
)
149 /* 1-4 interactions do not have the charges stored in the iparams list,
150 * so we need a separate check for those.
152 return (ip_pert(ftype
, ip
+ia
[0]) ||
153 (ftype
== F_LJ14
&& (qA
[ia
[1]] != qB
[ia
[1]] ||
154 qA
[ia
[2]] != qB
[ia
[2]])));
157 gmx_bool
gmx_mtop_bondeds_free_energy(const gmx_mtop_t
*mtop
)
159 const gmx_ffparams_t
*ffparams
= &mtop
->ffparams
;
161 /* Loop over all the function types and compare the A/B parameters */
162 gmx_bool bPert
= FALSE
;
163 for (int i
= 0; i
< ffparams
->numTypes(); i
++)
165 int ftype
= ffparams
->functype
[i
];
166 if (interaction_function
[ftype
].flags
& IF_BOND
)
168 if (ip_pert(ftype
, &ffparams
->iparams
[i
]))
175 /* Check perturbed charges for 1-4 interactions */
176 for (const gmx_molblock_t
&molb
: mtop
->molblock
)
178 const t_atom
*atom
= mtop
->moltype
[molb
.type
].atoms
.atom
;
179 const InteractionList
&il
= mtop
->moltype
[molb
.type
].ilist
[F_LJ14
];
180 gmx::ArrayRef
<const int> ia
= il
.iatoms
;
181 for (int i
= 0; i
< il
.size(); i
+= 3)
183 if (atom
[ia
[i
+1]].q
!= atom
[ia
[i
+1]].qB
||
184 atom
[ia
[i
+2]].q
!= atom
[ia
[i
+2]].qB
)
194 void gmx_sort_ilist_fe(t_idef
*idef
, const real
*qA
, const real
*qB
)
196 int ftype
, nral
, i
, ic
, ib
, a
;
210 const t_iparams
*iparams
= idef
->iparams
;
212 for (ftype
= 0; ftype
< F_NRE
; ftype
++)
214 if (interaction_function
[ftype
].flags
& IF_BOND
)
216 ilist
= &idef
->il
[ftype
];
217 iatoms
= ilist
->iatoms
;
222 while (i
< ilist
->nr
)
224 /* Check if this interaction is perturbed */
225 if (ip_q_pert(ftype
, iatoms
+i
, iparams
, qA
, qB
))
227 /* Copy to the perturbed buffer */
228 if (ib
+ 1 + nral
> iabuf_nalloc
)
230 iabuf_nalloc
= over_alloc_large(ib
+1+nral
);
231 srenew(iabuf
, iabuf_nalloc
);
233 for (a
= 0; a
< 1+nral
; a
++)
235 iabuf
[ib
++] = iatoms
[i
++];
241 for (a
= 0; a
< 1+nral
; a
++)
243 iatoms
[ic
++] = iatoms
[i
++];
247 /* Now we now the number of non-perturbed interactions */
248 ilist
->nr_nonperturbed
= ic
;
250 /* Copy the buffer with perturbed interactions to the ilist */
251 for (a
= 0; a
< ib
; a
++)
253 iatoms
[ic
++] = iabuf
[a
];
258 fprintf(debug
, "%s non-pert %d pert %d\n",
259 interaction_function
[ftype
].longname
,
260 ilist
->nr_nonperturbed
,
261 ilist
->nr
-ilist
->nr_nonperturbed
);
268 idef
->ilsort
= ilsortFE_SORTED
;