Merge remote-tracking branch 'origin/release-4-6'
[alexxy/gromacs.git] / src / gromacs / mdlib / iteratedconstraints.c
1 /* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
2  *
3  * 
4  *                This source code is part of
5  * 
6  *                 G   R   O   M   A   C   S
7  * 
8  *          GROningen MAchine for Chemical Simulations
9  * 
10  *                        VERSION 3.2.0
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.
15
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.
20  * 
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.
27  * 
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.
30  * 
31  * For more info, check our website at http://www.gromacs.org
32  * 
33  * And Hey:
34  * Gallium Rubidium Oxygen Manganese Argon Carbon Silicon
35  */
36 #ifdef HAVE_CONFIG_H
37 #include <config.h>
38 #endif
39
40 #include "typedefs.h"
41 #include "gmx_fatal.h"
42 #include "mdrun.h"
43
44 #ifdef GMX_DOUBLE
45 #define CONVERGEITER  0.000000001
46 #define CLOSE_ENOUGH  0.000001000
47 #else
48 #define CONVERGEITER  0.0001
49 #define CLOSE_ENOUGH  0.0050
50 #endif
51
52 /* we want to keep track of the close calls.  If there are too many, there might be some other issues.
53    so we make sure that it's either less than some predetermined number, or if more than that number,
54    only some small fraction of the total. */
55 #define MAX_NUMBER_CLOSE        50
56 #define FRACTION_CLOSE       0.001
57   
58 /* maximum length of cyclic traps to check, emerging from limited numerical precision  */
59 #define CYCLEMAX            20
60
61 void gmx_iterate_init(gmx_iterate_t *iterate,gmx_bool bIterate)
62 {
63     int i;
64
65     iterate->iter_i = 0;
66     iterate->bIterate = bIterate;
67     iterate->num_close = 0;
68     for (i=0;i<MAXITERCONST+2;i++) 
69     {
70         iterate->allrelerr[i] = 0;
71     }
72 }
73
74 gmx_bool done_iterating(const t_commrec *cr,FILE *fplog, int nsteps, gmx_iterate_t *iterate, gmx_bool bFirstIterate, real fom, real *newf) 
75 {    
76     /* monitor convergence, and use a secant search to propose new
77        values.  
78                                                                   x_{i} - x_{i-1}
79        The secant method computes x_{i+1} = x_{i} - f(x_{i}) * ---------------------
80                                                                 f(x_{i}) - f(x_{i-1})
81        
82        The function we are trying to zero is fom-x, where fom is the
83        "figure of merit" which is the pressure (or the veta value) we
84        would get by putting in an old value of the pressure or veta into
85        the incrementor function for the step or half step.  I have
86        verified that this gives the same answer as self consistent
87        iteration, usually in many fewer steps, especially for small tau_p.
88        
89        We could possibly eliminate an iteration with proper use
90        of the value from the previous step, but that would take a bit
91        more bookkeeping, especially for veta, since tests indicate the
92        function of veta on the last step is not sufficiently close to
93        guarantee convergence this step. This is
94        good enough for now.  On my tests, I could use tau_p down to
95        0.02, which is smaller that would ever be necessary in
96        practice. Generally, 3-5 iterations will be sufficient */
97
98     real relerr,err,xmin;
99     char buf[256];
100     int i;
101     gmx_bool incycle;
102     
103     if (bFirstIterate) 
104     {
105         iterate->x = fom;
106         iterate->f = fom-iterate->x;
107         iterate->xprev = 0;
108         iterate->fprev = 0;
109         *newf = fom;
110     } 
111     else 
112     {
113         iterate->f = fom-iterate->x; /* we want to zero this difference */
114         if ((iterate->iter_i > 1) && (iterate->iter_i < MAXITERCONST)) 
115         {
116             if (iterate->f==iterate->fprev) 
117             {
118                 *newf = iterate->f;
119             } 
120             else 
121             {
122                 *newf = iterate->x - (iterate->x-iterate->xprev)*(iterate->f)/(iterate->f-iterate->fprev); 
123             }
124         } 
125         else 
126         {
127             /* just use self-consistent iteration the first step to initialize, or 
128                if it's not converging (which happens occasionally -- need to investigate why) */
129             *newf = fom; 
130         }
131     }
132     /* Consider a slight shortcut allowing us to exit one sooner -- we check the
133        difference between the closest of x and xprev to the new
134        value. To be 100% certain, we should check the difference between
135        the last result, and the previous result, or
136        
137        relerr = (fabs((x-xprev)/fom));
138        
139        but this is pretty much never necessary under typical conditions.
140        Checking numerically, it seems to lead to almost exactly the same
141        trajectories, but there are small differences out a few decimal
142        places in the pressure, and eventually in the v_eta, but it could
143        save an interation.
144        
145        if (fabs(*newf-x) < fabs(*newf - xprev)) { xmin = x;} else { xmin = xprev;}
146        relerr = (fabs((*newf-xmin) / *newf));
147     */
148     
149     err = fabs((iterate->f-iterate->fprev));
150     relerr = fabs(err/fom);
151
152     iterate->allrelerr[iterate->iter_i] = relerr;
153     
154     if (iterate->iter_i > 0) 
155     {
156         if (debug) 
157         {
158             fprintf(debug,"Iterating NPT constraints: %6i %20.12f%14.6g%20.12f\n",
159                     iterate->iter_i,fom,relerr,*newf);
160         }
161         
162         if ((relerr < CONVERGEITER) || (err < CONVERGEITER) || (fom==0) || ((iterate->x == iterate->xprev) && iterate->iter_i > 1))
163         {
164             iterate->bIterate = FALSE;
165             if (debug) 
166             {
167                 fprintf(debug,"Iterating NPT constraints: CONVERGED\n");
168             }
169             return TRUE;
170         }
171         if (iterate->iter_i > MAXITERCONST)
172         {
173             if (relerr < CLOSE_ENOUGH)
174             {
175                 incycle = FALSE;
176                 for (i=1;i<CYCLEMAX;i++) {
177                     if ((iterate->allrelerr[iterate->iter_i-(1+i)] == iterate->allrelerr[iterate->iter_i-1]) &&
178                         (iterate->allrelerr[iterate->iter_i-(1+i)] == iterate->allrelerr[iterate->iter_i-(1+2*i)])) {
179                         incycle = TRUE;
180                         if (debug) 
181                         {
182                             fprintf(debug,"Exiting from an NPT iterating cycle of length %d\n",i);
183                         }
184                         break;
185                     }
186                 }
187                 
188                 if (incycle) {
189                     /* step 1: trapped in a numerical attractor */
190                     /* we are trapped in a numerical attractor, and can't converge any more, and are close to the final result.
191                        Better to give up convergence here than have the simulation die.
192                     */
193                     iterate->num_close++;
194                     return TRUE;
195                 } 
196                 else 
197                 {
198                     /* Step #2: test if we are reasonably close for other reasons, then monitor the number.  If not, die */
199                     
200                     /* how many close calls have we had?  If less than a few, we're OK */
201                     if (iterate->num_close < MAX_NUMBER_CLOSE) 
202                     {
203                         sprintf(buf,"Slight numerical convergence deviation with NPT at step %d, relative error only %10.5g, likely not a problem, continuing\n",nsteps,relerr);
204                         md_print_warning(cr,fplog,buf);
205                         iterate->num_close++;
206                         return TRUE;
207                         /* if more than a few, check the total fraction.  If too high, die. */
208                     } else if (iterate->num_close/(double)nsteps > FRACTION_CLOSE) {
209                         gmx_fatal(FARGS,"Could not converge NPT constraints, too many exceptions (%d%%\n",iterate->num_close/(double)nsteps);
210                     } 
211                 }
212             }
213             else 
214             {
215                 gmx_fatal(FARGS,"Could not converge NPT constraints\n");
216             }
217         }
218     }
219     
220     iterate->xprev = iterate->x;
221     iterate->x = *newf;
222     iterate->fprev = iterate->f;
223     iterate->iter_i++;
224     
225     return FALSE;
226 }
227