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