Merge branch 'release-4-5-patches' into release-4-6
[alexxy/gromacs.git] / src / gmxlib / disre.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-2004, The GROMACS development team,
6  * check out http://www.gromacs.org for more information.
7  * Copyright (c) 2012, by the GROMACS development team, led by
8  * David van der Spoel, Berk Hess, Erik Lindahl, and including many
9  * others, as listed in the AUTHORS file in the top-level source
10  * directory and at http://www.gromacs.org.
11  *
12  * GROMACS is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Lesser General Public License
14  * as published by the Free Software Foundation; either version 2.1
15  * of the License, or (at your option) any later version.
16  *
17  * GROMACS is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  * Lesser General Public License for more details.
21  *
22  * You should have received a copy of the GNU Lesser General Public
23  * License along with GROMACS; if not, see
24  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
26  *
27  * If you want to redistribute modifications to GROMACS, please
28  * consider that scientific software is very special. Version
29  * control is crucial - bugs must be traceable. We will be happy to
30  * consider code for inclusion in the official distribution, but
31  * derived work must not be called official GROMACS. Details are found
32  * in the README & COPYING files - if they are missing, get the
33  * official version at http://www.gromacs.org.
34  *
35  * To help us fund GROMACS development, we humbly ask that you cite
36  * the research papers on the package. Check out http://www.gromacs.org.
37  */
38 /* This file is completely threadsafe - keep it that way! */
39 #ifdef HAVE_CONFIG_H
40 #include <config.h>
41 #endif
42
43 #include <math.h>
44 #include "typedefs.h"
45 #include "sysstuff.h"
46 #include "smalloc.h"
47 #include "macros.h"
48 #include "vec.h"
49 #include "futil.h"
50 #include "xvgr.h"
51 #include "gmx_fatal.h"
52 #include "bondf.h"
53 #include "copyrite.h"
54 #include "disre.h"
55 #include "main.h"
56 #include "mtop_util.h"
57
58 void init_disres(FILE *fplog,const gmx_mtop_t *mtop,
59                  t_inputrec *ir,const t_commrec *cr,gmx_bool bPartDecomp,
60                  t_fcdata *fcd,t_state *state, gmx_bool bIsREMD)
61 {
62     int          fa,nmol,i,npair,np;
63     t_iparams    *ip;
64     t_disresdata *dd;
65     history_t    *hist;
66     gmx_mtop_ilistloop_t iloop;
67     t_ilist      *il;
68     char         *ptr;
69     
70     dd = &(fcd->disres);
71
72     if (gmx_mtop_ftype_count(mtop,F_DISRES) == 0)
73     {
74         dd->nres = 0;
75
76         return;
77     }
78     
79     if (fplog)
80     {
81         fprintf(fplog,"Initializing the distance restraints\n");
82     }
83     
84
85     if (ir->eDisre == edrEnsemble)
86     {
87         gmx_fatal(FARGS,"Sorry, distance restraints with ensemble averaging over multiple molecules in one system are not functional in this version of GROMACS");
88     }
89
90     dd->dr_weighting = ir->eDisreWeighting;
91     dd->dr_fc        = ir->dr_fc;
92     if (EI_DYNAMICS(ir->eI))
93     {
94         dd->dr_tau   = ir->dr_tau;
95     }
96     else
97     {
98         dd->dr_tau   = 0.0;
99     }
100     if (dd->dr_tau == 0.0)
101     {
102         dd->dr_bMixed = FALSE;
103         dd->ETerm = 0.0;
104     }
105     else
106     {
107         dd->dr_bMixed = ir->bDisreMixed;
108         dd->ETerm = exp(-(ir->delta_t/ir->dr_tau));
109     }
110     dd->ETerm1        = 1.0 - dd->ETerm;
111     
112     ip = mtop->ffparams.iparams;
113
114     dd->nres  = 0;
115     dd->npair = 0;
116     iloop = gmx_mtop_ilistloop_init(mtop);
117     while (gmx_mtop_ilistloop_next(iloop,&il,&nmol)) {
118         np = 0;
119         for(fa=0; fa<il[F_DISRES].nr; fa+=3)
120         {
121             np++;
122             npair = mtop->ffparams.iparams[il[F_DISRES].iatoms[fa]].disres.npair;
123             if (np == npair)
124             {
125                 dd->nres  += (ir->eDisre==edrEnsemble ? 1 : nmol)*npair;
126                 dd->npair += nmol*npair;
127                 np = 0;
128             }
129         }
130     }
131
132     if (cr && PAR(cr) && !bPartDecomp)
133     {
134         /* Temporary check, will be removed when disre is implemented with DD */
135         const char *notestr="NOTE: atoms involved in distance restraints should be within the longest cut-off distance, if this is not the case mdrun generates a fatal error, in that case use particle decomposition (mdrun option -pd)";
136         
137         if (MASTER(cr))
138             fprintf(stderr,"\n%s\n\n",notestr);
139         if (fplog)
140             fprintf(fplog,"%s\n",notestr);
141
142         if (dd->dr_tau != 0 || ir->eDisre == edrEnsemble || cr->ms != NULL ||
143             dd->nres != dd->npair)
144         {
145             gmx_fatal(FARGS,"Time or ensemble averaged or multiple pair distance restraints do not work (yet) with domain decomposition, use particle decomposition (mdrun option -pd)");
146         }
147         if (ir->nstdisreout != 0)
148         {
149             if (fplog)
150             {
151                 fprintf(fplog,"\nWARNING: Can not write distance restraint data to energy file with domain decomposition\n\n");
152             }
153             if (MASTER(cr))
154             {
155                 fprintf(stderr,"\nWARNING: Can not write distance restraint data to energy file with domain decomposition\n");
156             }
157             ir->nstdisreout = 0;
158         }
159     }
160
161     snew(dd->rt,dd->npair);
162     
163     if (dd->dr_tau != 0.0)
164     {
165         hist = &state->hist;
166         /* Set the "history lack" factor to 1 */
167         state->flags |= (1<<estDISRE_INITF);
168         hist->disre_initf = 1.0;
169         /* Allocate space for the r^-3 time averages */
170         state->flags |= (1<<estDISRE_RM3TAV);
171         hist->ndisrepairs = dd->npair;
172         snew(hist->disre_rm3tav,hist->ndisrepairs);
173     }
174     /* Allocate space for a copy of rm3tav,
175      * so we can call do_force without modifying the state.
176      */
177     snew(dd->rm3tav,dd->npair);
178
179     /* Allocate Rt_6 and Rtav_6 consecutively in memory so they can be
180      * averaged over the processors in one call (in calc_disre_R_6)
181      */
182     snew(dd->Rt_6,2*dd->nres);
183     dd->Rtav_6 = &(dd->Rt_6[dd->nres]);
184
185     ptr = getenv("GMX_DISRE_ENSEMBLE_SIZE");
186     if (cr && cr->ms != NULL && ptr != NULL && !bIsREMD)
187     {
188 #ifdef GMX_MPI
189         dd->nsystems = 0;
190         sscanf(ptr,"%d",&dd->nsystems);
191         if (fplog)
192         {
193             fprintf(fplog,"Found GMX_DISRE_ENSEMBLE_SIZE set to %d systems per ensemble\n",dd->nsystems);
194         }
195         /* This check is only valid on MASTER(cr), so probably
196          * ensemble-averaged distance restraints are broken on more
197          * than one processor per simulation system. */
198         if (MASTER(cr))
199         {
200             check_multi_int(fplog,cr->ms,dd->nsystems,
201                             "the number of systems per ensemble",
202                             FALSE);
203         }
204         gmx_bcast_sim(sizeof(int), &dd->nsystems, cr);
205
206         /* We use to allow any value of nsystems which was a divisor
207          * of ms->nsim. But this required an extra communicator which
208          * was stored in t_fcdata. This pulled in mpi.h in nearly all C files.
209          */
210         if (!(cr->ms->nsim == 1 || cr->ms->nsim == dd->nsystems))
211         {
212             gmx_fatal(FARGS,"GMX_DISRE_ENSEMBLE_SIZE (%d) is not equal to 1 or the number of systems (option -multi) %d",dd->nsystems,cr->ms->nsim);
213         }
214         if (fplog)
215         {
216             fprintf(fplog,"Our ensemble consists of systems:");
217             for(i=0; i<dd->nsystems; i++)
218             {
219                 fprintf(fplog," %d",
220                         (cr->ms->sim/dd->nsystems)*dd->nsystems+i);
221             }
222             fprintf(fplog,"\n");
223             }
224         snew(dd->Rtl_6,dd->nres);
225 #endif
226     }
227     else
228     {
229         dd->nsystems = 1;
230         dd->Rtl_6 = dd->Rt_6;
231     }
232     
233     if (dd->npair > 0)
234     {
235         if (fplog) {
236             fprintf(fplog,"There are %d distance restraints involving %d atom pairs\n",dd->nres,dd->npair);
237         }
238         /* Have to avoid g_disre de-referencing cr blindly, mdrun not
239          * doing consistency checks for ensemble-averaged distance
240          * restraints when that's not happening, and only doing those
241          * checks from appropriate processes (since check_multi_int is
242          * too broken to check whether the communication will
243          * succeed...) */
244         if (cr && cr->ms && dd->nsystems > 1 && MASTER(cr))
245         {
246             check_multi_int(fplog,cr->ms,fcd->disres.nres,
247                             "the number of distance restraints",
248                             FALSE);
249         }
250         please_cite(fplog,"Tropp80a");
251         please_cite(fplog,"Torda89a");
252     }
253 }
254
255 void calc_disres_R_6(const gmx_multisim_t *ms,
256                      int nfa,const t_iatom forceatoms[],const t_iparams ip[],
257                      const rvec x[],const t_pbc *pbc,
258                      t_fcdata *fcd,history_t *hist)
259 {
260     atom_id     ai,aj;
261     int         fa,res,i,pair,ki,kj,m;
262     int         type,npair,np;
263     rvec        dx;
264     real        *rt,*rm3tav,*Rtl_6,*Rt_6,*Rtav_6;
265     real        rt_1,rt_3,rt2;
266     ivec        it,jt,dt;
267     t_disresdata *dd;
268     real        ETerm,ETerm1,cf1=0,cf2=0,invn=0;
269     gmx_bool        bTav;
270
271     dd = &(fcd->disres);
272     bTav         = (dd->dr_tau != 0);
273     ETerm        = dd->ETerm;
274     ETerm1       = dd->ETerm1;
275     rt           = dd->rt;
276     rm3tav       = dd->rm3tav;
277     Rtl_6        = dd->Rtl_6;
278     Rt_6         = dd->Rt_6;
279     Rtav_6       = dd->Rtav_6;
280     
281     if (bTav)
282     {
283         /* scaling factor to smoothly turn on the restraint forces *
284          * when using time averaging                               */
285         dd->exp_min_t_tau = hist->disre_initf*ETerm;
286         
287         cf1 = dd->exp_min_t_tau;
288         cf2 = 1.0/(1.0 - dd->exp_min_t_tau);
289     }
290     
291     if (dd->nsystems > 1)
292     {
293         invn = 1.0/dd->nsystems;
294     }
295     
296     /* 'loop' over all atom pairs (pair_nr=fa/3) involved in restraints, *
297      * the total number of atoms pairs is nfa/3                          */
298     res = 0;
299     fa  = 0;
300     while (fa < nfa)
301     {
302         type  = forceatoms[fa];
303         npair = ip[type].disres.npair;
304         
305         Rtav_6[res] = 0.0;
306         Rt_6[res]   = 0.0;
307         
308         /* Loop over the atom pairs of 'this' restraint */
309         np = 0;
310         while (fa < nfa && np < npair)
311         {
312             pair = fa/3;
313             ai   = forceatoms[fa+1];
314             aj   = forceatoms[fa+2];
315             
316             if (pbc)
317             {
318                 pbc_dx_aiuc(pbc,x[ai],x[aj],dx);
319             }
320             else
321             {
322                 rvec_sub(x[ai],x[aj],dx);
323             }
324             rt2  = iprod(dx,dx);
325             rt_1 = gmx_invsqrt(rt2);
326             rt_3 = rt_1*rt_1*rt_1;
327             
328             rt[pair]         = sqrt(rt2);
329             if (bTav)
330             {
331                 /* Here we update rm3tav in t_fcdata using the data
332                  * in history_t.
333                  * Thus the results stay correct when this routine
334                  * is called multiple times.
335                  */
336                 rm3tav[pair] = cf2*((ETerm - cf1)*hist->disre_rm3tav[pair] +
337                                     ETerm1*rt_3);
338             }
339             else
340             {
341                 rm3tav[pair] = rt_3;
342             }
343
344             Rt_6[res]       += rt_3*rt_3;
345             Rtav_6[res]     += rm3tav[pair]*rm3tav[pair];
346
347             fa += 3;
348             np++;
349         }
350         if (dd->nsystems > 1)
351         {
352             Rtl_6[res]   = Rt_6[res];
353             Rt_6[res]   *= invn;
354             Rtav_6[res] *= invn;
355         }
356
357         res++;
358     }
359     
360 #ifdef GMX_MPI
361     if (dd->nsystems > 1)
362     {
363         gmx_sum_sim(2*dd->nres,Rt_6,ms);
364     }
365 #endif
366 }
367
368 real ta_disres(int nfa,const t_iatom forceatoms[],const t_iparams ip[],
369                const rvec x[],rvec f[],rvec fshift[],
370                const t_pbc *pbc,const t_graph *g,
371                real lambda,real *dvdlambda,
372                const t_mdatoms *md,t_fcdata *fcd,
373                int *global_atom_index)
374 {
375     const real sixth=1.0/6.0;
376     const real seven_three=7.0/3.0;
377     
378     atom_id     ai,aj;
379     int         fa,res,npair,p,pair,ki=CENTRAL,m;
380     int         type;
381     rvec        dx;
382     real        weight_rt_1;
383     real        smooth_fc,Rt,Rtav,rt2,*Rtl_6,*Rt_6,*Rtav_6;
384     real        k0,f_scal=0,fmax_scal,fk_scal,fij;
385     real        tav_viol,instant_viol,mixed_viol,violtot,vtot;
386     real        tav_viol_Rtav7,instant_viol_Rtav7;
387     real        up1,up2,low;
388     gmx_bool        bConservative,bMixed,bViolation;
389     ivec        it,jt,dt;
390     t_disresdata *dd;
391     int         dr_weighting;
392     gmx_bool        dr_bMixed;
393     
394     dd = &(fcd->disres);
395     dr_weighting = dd->dr_weighting;
396     dr_bMixed    = dd->dr_bMixed;
397     Rtl_6        = dd->Rtl_6;
398     Rt_6         = dd->Rt_6;
399     Rtav_6       = dd->Rtav_6;
400
401     tav_viol=instant_viol=mixed_viol=tav_viol_Rtav7=instant_viol_Rtav7=0;
402
403     smooth_fc = dd->dr_fc;
404     if (dd->dr_tau != 0)
405     {
406         /* scaling factor to smoothly turn on the restraint forces *
407          * when using time averaging                               */
408         smooth_fc *= (1.0 - dd->exp_min_t_tau); 
409     }
410     
411     violtot = 0;
412     vtot    = 0;
413     
414     /* 'loop' over all atom pairs (pair_nr=fa/3) involved in restraints, *
415      * the total number of atoms pairs is nfa/3                          */
416     res  = 0;
417     fa   = 0;
418     while (fa < nfa)
419     {
420         type  = forceatoms[fa];
421         /* Take action depending on restraint, calculate scalar force */
422         npair = ip[type].disres.npair;
423         up1   = ip[type].disres.up1;
424         up2   = ip[type].disres.up2;
425         low   = ip[type].disres.low;
426         k0    = smooth_fc*ip[type].disres.kfac;
427         
428         /* save some flops when there is only one pair */
429         if (ip[type].disres.type != 2)
430         {
431             bConservative = (dr_weighting == edrwConservative) && (npair > 1);
432             bMixed        = dr_bMixed;
433             Rt   = pow(Rt_6[res],-sixth);
434             Rtav = pow(Rtav_6[res],-sixth);
435         }
436         else
437         {
438             /* When rtype=2 use instantaneous not ensemble avereged distance */
439             bConservative = (npair > 1);
440             bMixed        = FALSE;
441             Rt   = pow(Rtl_6[res],-sixth);
442             Rtav = Rt;
443         }
444         
445         if (Rtav > up1)
446         {
447             bViolation = TRUE;
448             tav_viol = Rtav - up1;
449         }
450         else if (Rtav < low)
451         {
452             bViolation = TRUE;
453             tav_viol = Rtav - low;
454         }
455         else
456         {
457             bViolation = FALSE;
458         }
459         
460         if (bViolation)
461         {
462             /* NOTE:
463              * there is no real potential when time averaging is applied
464              */
465             vtot += 0.5*k0*sqr(tav_viol);
466             if (1/vtot == 0)
467             {
468                 printf("vtot is inf: %f\n",vtot);
469             }
470             if (!bMixed)
471             {
472                 f_scal   = -k0*tav_viol;
473                 violtot += fabs(tav_viol);
474             }
475             else
476             {
477                 if (Rt > up1)
478                 {
479                     if (tav_viol > 0)
480                     {
481                         instant_viol = Rt - up1;
482                     }
483                     else
484                     {
485                         bViolation = FALSE;
486                     }
487                 }
488                 else if (Rt < low)
489                 {
490                     if (tav_viol < 0)
491                     {
492                         instant_viol = Rt - low;
493                     }
494                     else
495                     {
496                         bViolation = FALSE;
497                     }
498                 }
499                 else
500                 {
501                     bViolation = FALSE;
502                 }
503                 if (bViolation)
504                 {
505                     mixed_viol = sqrt(tav_viol*instant_viol);
506                     f_scal     = -k0*mixed_viol;
507                     violtot   += mixed_viol;
508                 }
509             }
510         }
511
512         if (bViolation)
513         {
514             fmax_scal = -k0*(up2-up1);
515             /* Correct the force for the number of restraints */
516             if (bConservative)
517             {
518                 f_scal  = max(f_scal,fmax_scal);
519                 if (!bMixed)
520                 {
521                     f_scal *= Rtav/Rtav_6[res];
522                 }
523                 else
524                 {
525                     f_scal /= 2*mixed_viol;
526                     tav_viol_Rtav7     = tav_viol*Rtav/Rtav_6[res];
527                     instant_viol_Rtav7 = instant_viol*Rt/Rt_6[res];
528                 }
529             }
530             else
531             {
532                 f_scal /= (real)npair;
533                 f_scal  = max(f_scal,fmax_scal);
534             }    
535             
536             /* Exert the force ... */
537             
538             /* Loop over the atom pairs of 'this' restraint */
539             for(p=0; p<npair; p++)
540             {
541                 pair = fa/3;
542                 ai   = forceatoms[fa+1];
543                 aj   = forceatoms[fa+2];
544                 
545                 if (pbc)
546                 {
547                     ki = pbc_dx_aiuc(pbc,x[ai],x[aj],dx);
548                 }
549                 else
550                 {
551                     rvec_sub(x[ai],x[aj],dx);
552                 }
553                 rt2 = iprod(dx,dx);
554                 
555                 weight_rt_1 = gmx_invsqrt(rt2);
556                 
557                 if (bConservative)
558                 {
559                     if (!dr_bMixed)
560                     {
561                         weight_rt_1 *= pow(dd->rm3tav[pair],seven_three);
562                     }
563                     else
564                     {
565                         weight_rt_1 *= tav_viol_Rtav7*pow(dd->rm3tav[pair],seven_three)+
566                             instant_viol_Rtav7*pow(dd->rt[pair],-7);
567                     }
568                 }
569                 
570                 fk_scal  = f_scal*weight_rt_1;
571                 
572                 if (g)
573                 {
574                     ivec_sub(SHIFT_IVEC(g,ai),SHIFT_IVEC(g,aj),dt);
575                     ki=IVEC2IS(dt);
576                 }
577                 
578                 for(m=0; m<DIM; m++)
579                 {
580                     fij            = fk_scal*dx[m];
581                     
582                     f[ai][m]      += fij;
583                     f[aj][m]      -= fij;
584                     fshift[ki][m] += fij;
585                     fshift[CENTRAL][m] -= fij;
586                 }
587                 fa += 3;
588             }
589         }
590         else
591         {
592             /* No violation so force and potential contributions */
593             fa += 3*npair;
594         }
595         res++;
596     }
597     
598     dd->sumviol = violtot;
599     
600     /* Return energy */
601     return vtot;
602 }
603
604 void update_disres_history(t_fcdata *fcd,history_t *hist)
605 {
606     t_disresdata *dd;
607     int pair;
608     
609     dd = &(fcd->disres);
610     if (dd->dr_tau != 0)
611     {
612         /* Copy the new time averages that have been calculated
613          * in calc_disres_R_6.
614          */
615         hist->disre_initf = dd->exp_min_t_tau;
616         for(pair=0; pair<dd->npair; pair++)
617         {
618             hist->disre_rm3tav[pair] = dd->rm3tav[pair];
619         }
620     }
621 }