43283e1025d2468ed213e1fe6303b22842278807
[alexxy/gromacs.git] / src / gromacs / gmxlib / inputrec.c
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5  * Copyright (c) 2001-2010, The GROMACS development team.
6  * Copyright (c) 2012,2014, 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.
10  *
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.
15  *
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.
20  *
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.
25  *
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.
33  *
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.
36  */
37 #include "gmxpre.h"
38
39 #include "config.h"
40
41
42 #include "gromacs/legacyheaders/typedefs.h"
43 #include "gromacs/legacyheaders/macros.h"
44 #include "gromacs/legacyheaders/inputrec.h"
45 #include "gromacs/utility/fatalerror.h"
46
47
48 /* The minimum number of integration steps required for reasonably accurate
49  * integration of first and second order coupling algorithms.
50  */
51 const int nstmin_berendsen_tcouple =  5;
52 const int nstmin_berendsen_pcouple = 10;
53 const int nstmin_harmonic          = 20;
54
55 static int nst_wanted(const t_inputrec *ir)
56 {
57     if (ir->nstlist > 0)
58     {
59         return ir->nstlist;
60     }
61     else
62     {
63         return 10;
64     }
65 }
66
67 int ir_optimal_nstcalcenergy(const t_inputrec *ir)
68 {
69     return nst_wanted(ir);
70 }
71
72 int tcouple_min_integration_steps(int etc)
73 {
74     int n;
75
76     switch (etc)
77     {
78         case etcNO:
79             n = 0;
80             break;
81         case etcBERENDSEN:
82         case etcYES:
83             n = nstmin_berendsen_tcouple;
84             break;
85         case etcVRESCALE:
86             /* V-rescale supports instantaneous rescaling */
87             n = 0;
88             break;
89         case etcNOSEHOOVER:
90             n = nstmin_harmonic;
91             break;
92         case etcANDERSEN:
93         case etcANDERSENMASSIVE:
94             n = 1;
95             break;
96         default:
97             gmx_incons("Unknown etc value");
98             n = 0;
99     }
100
101     return n;
102 }
103
104 int ir_optimal_nsttcouple(const t_inputrec *ir)
105 {
106     int  nmin, nwanted, n;
107     real tau_min;
108     int  g;
109
110     nmin = tcouple_min_integration_steps(ir->etc);
111
112     nwanted = nst_wanted(ir);
113
114     tau_min = 1e20;
115     if (ir->etc != etcNO)
116     {
117         for (g = 0; g < ir->opts.ngtc; g++)
118         {
119             if (ir->opts.tau_t[g] > 0)
120             {
121                 tau_min = min(tau_min, ir->opts.tau_t[g]);
122             }
123         }
124     }
125
126     if (nmin == 0 || ir->delta_t*nwanted <= tau_min)
127     {
128         n = nwanted;
129     }
130     else
131     {
132         n = (int)(tau_min/(ir->delta_t*nmin) + 0.001);
133         if (n < 1)
134         {
135             n = 1;
136         }
137         while (nwanted % n != 0)
138         {
139             n--;
140         }
141     }
142
143     return n;
144 }
145
146 int pcouple_min_integration_steps(int epc)
147 {
148     int n;
149
150     switch (epc)
151     {
152         case epcNO:
153             n = 0;
154             break;
155         case etcBERENDSEN:
156         case epcISOTROPIC:
157             n = nstmin_berendsen_pcouple;
158             break;
159         case epcPARRINELLORAHMAN:
160         case epcMTTK:
161             n = nstmin_harmonic;
162             break;
163         default:
164             gmx_incons("Unknown epc value");
165             n = 0;
166     }
167
168     return n;
169 }
170
171 int ir_optimal_nstpcouple(const t_inputrec *ir)
172 {
173     int  nmin, nwanted, n;
174
175     nmin = pcouple_min_integration_steps(ir->epc);
176
177     nwanted = nst_wanted(ir);
178
179     if (nmin == 0 || ir->delta_t*nwanted <= ir->tau_p)
180     {
181         n = nwanted;
182     }
183     else
184     {
185         n = (int)(ir->tau_p/(ir->delta_t*nmin) + 0.001);
186         if (n < 1)
187         {
188             n = 1;
189         }
190         while (nwanted % n != 0)
191         {
192             n--;
193         }
194     }
195
196     return n;
197 }
198
199 gmx_bool ir_coulomb_switched(const t_inputrec *ir)
200 {
201     return (ir->coulombtype == eelSWITCH ||
202             ir->coulombtype == eelSHIFT ||
203             ir->coulombtype == eelENCADSHIFT ||
204             ir->coulombtype == eelPMESWITCH ||
205             ir->coulombtype == eelPMEUSERSWITCH ||
206             ir->coulomb_modifier == eintmodPOTSWITCH ||
207             ir->coulomb_modifier == eintmodFORCESWITCH);
208 }
209
210 gmx_bool ir_coulomb_is_zero_at_cutoff(const t_inputrec *ir)
211 {
212     return (ir->cutoff_scheme == ecutsVERLET ||
213             ir_coulomb_switched(ir) || ir->coulomb_modifier != eintmodNONE ||
214             ir->coulombtype == eelRF_ZERO);
215 }
216
217 gmx_bool ir_coulomb_might_be_zero_at_cutoff(const t_inputrec *ir)
218 {
219     return (ir_coulomb_is_zero_at_cutoff(ir) || ir->coulombtype == eelUSER || ir->coulombtype == eelPMEUSER);
220 }
221
222 gmx_bool ir_vdw_switched(const t_inputrec *ir)
223 {
224     return (ir->vdwtype == evdwSWITCH ||
225             ir->vdwtype == evdwSHIFT ||
226             ir->vdwtype == evdwENCADSHIFT ||
227             ir->vdw_modifier == eintmodPOTSWITCH ||
228             ir->vdw_modifier == eintmodFORCESWITCH);
229 }
230
231 gmx_bool ir_vdw_is_zero_at_cutoff(const t_inputrec *ir)
232 {
233     return (ir->cutoff_scheme == ecutsVERLET ||
234             ir_vdw_switched(ir) || ir->vdw_modifier != eintmodNONE);
235 }
236
237 gmx_bool ir_vdw_might_be_zero_at_cutoff(const t_inputrec *ir)
238 {
239     return (ir_vdw_is_zero_at_cutoff(ir) || ir->vdwtype == evdwUSER);
240 }