2297ec1e0676db827ac512f5888dcff88a30528c
[alexxy/gromacs.git] / src / gromacs / mdlib / update.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  * Copyright (c) 2013, 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 #ifdef HAVE_CONFIG_H
38 #include <config.h>
39 #endif
40
41
42 #include <stdio.h>
43 #include <math.h>
44
45 #include "types/commrec.h"
46 #include "sysstuff.h"
47 #include "smalloc.h"
48 #include "typedefs.h"
49 #include "nrnb.h"
50 #include "physics.h"
51 #include "macros.h"
52 #include "vec.h"
53 #include "main.h"
54 #include "update.h"
55 #include "gmx_random.h"
56 #include "mshift.h"
57 #include "tgroup.h"
58 #include "force.h"
59 #include "names.h"
60 #include "txtdump.h"
61 #include "mdrun.h"
62 #include "constr.h"
63 #include "edsam.h"
64 #include "pull.h"
65 #include "disre.h"
66 #include "orires.h"
67 #include "gmx_omp_nthreads.h"
68
69 #include "gromacs/fileio/confio.h"
70 #include "gromacs/fileio/futil.h"
71 #include "gromacs/timing/wallcycle.h"
72 #include "gromacs/utility/gmxomp.h"
73
74 /*For debugging, start at v(-dt/2) for velolcity verlet -- uncomment next line */
75 /*#define STARTFROMDT2*/
76
77 typedef struct {
78     double gdt;
79     double eph;
80     double emh;
81     double em;
82     double b;
83     double c;
84     double d;
85 } gmx_sd_const_t;
86
87 typedef struct {
88     real V;
89     real X;
90     real Yv;
91     real Yx;
92 } gmx_sd_sigma_t;
93
94 typedef struct {
95     /* The random state for ngaussrand threads.
96      * Normal thermostats need just 1 random number generator,
97      * but SD and BD with OpenMP parallelization need 1 for each thread.
98      */
99     int             ngaussrand;
100     gmx_rng_t      *gaussrand;
101     /* BD stuff */
102     real           *bd_rf;
103     /* SD stuff */
104     gmx_sd_const_t *sdc;
105     gmx_sd_sigma_t *sdsig;
106     rvec           *sd_V;
107     int             sd_V_nalloc;
108     /* andersen temperature control stuff */
109     gmx_bool       *randomize_group;
110     real           *boltzfac;
111 } gmx_stochd_t;
112
113 typedef struct gmx_update
114 {
115     gmx_stochd_t *sd;
116     /* xprime for constraint algorithms */
117     rvec         *xp;
118     int           xp_nalloc;
119
120     /* variable size arrays for andersen */
121     gmx_bool *randatom;
122     int      *randatom_list;
123     gmx_bool  randatom_list_init;
124
125     /* Variables for the deform algorithm */
126     gmx_int64_t     deformref_step;
127     matrix          deformref_box;
128 } t_gmx_update;
129
130
131 static void do_update_md(int start, int nrend, double dt,
132                          t_grp_tcstat *tcstat,
133                          double nh_vxi[],
134                          gmx_bool bNEMD, t_grp_acc *gstat, rvec accel[],
135                          ivec nFreeze[],
136                          real invmass[],
137                          unsigned short ptype[], unsigned short cFREEZE[],
138                          unsigned short cACC[], unsigned short cTC[],
139                          rvec x[], rvec xprime[], rvec v[],
140                          rvec f[], matrix M,
141                          gmx_bool bNH, gmx_bool bPR)
142 {
143     double imass, w_dt;
144     int    gf = 0, ga = 0, gt = 0;
145     rvec   vrel;
146     real   vn, vv, va, vb, vnrel;
147     real   lg, vxi = 0, u;
148     int    n, d;
149
150     if (bNH || bPR)
151     {
152         /* Update with coupling to extended ensembles, used for
153          * Nose-Hoover and Parrinello-Rahman coupling
154          * Nose-Hoover uses the reversible leap-frog integrator from
155          * Holian et al. Phys Rev E 52(3) : 2338, 1995
156          */
157         for (n = start; n < nrend; n++)
158         {
159             imass = invmass[n];
160             if (cFREEZE)
161             {
162                 gf   = cFREEZE[n];
163             }
164             if (cACC)
165             {
166                 ga   = cACC[n];
167             }
168             if (cTC)
169             {
170                 gt   = cTC[n];
171             }
172             lg   = tcstat[gt].lambda;
173             if (bNH)
174             {
175                 vxi   = nh_vxi[gt];
176             }
177             rvec_sub(v[n], gstat[ga].u, vrel);
178
179             for (d = 0; d < DIM; d++)
180             {
181                 if ((ptype[n] != eptVSite) && (ptype[n] != eptShell) && !nFreeze[gf][d])
182                 {
183                     vnrel = (lg*vrel[d] + dt*(imass*f[n][d] - 0.5*vxi*vrel[d]
184                                               - iprod(M[d], vrel)))/(1 + 0.5*vxi*dt);
185                     /* do not scale the mean velocities u */
186                     vn             = gstat[ga].u[d] + accel[ga][d]*dt + vnrel;
187                     v[n][d]        = vn;
188                     xprime[n][d]   = x[n][d]+vn*dt;
189                 }
190                 else
191                 {
192                     v[n][d]        = 0.0;
193                     xprime[n][d]   = x[n][d];
194                 }
195             }
196         }
197     }
198     else if (cFREEZE != NULL ||
199              nFreeze[0][XX] || nFreeze[0][YY] || nFreeze[0][ZZ] ||
200              bNEMD)
201     {
202         /* Update with Berendsen/v-rescale coupling and freeze or NEMD */
203         for (n = start; n < nrend; n++)
204         {
205             w_dt = invmass[n]*dt;
206             if (cFREEZE)
207             {
208                 gf   = cFREEZE[n];
209             }
210             if (cACC)
211             {
212                 ga   = cACC[n];
213             }
214             if (cTC)
215             {
216                 gt   = cTC[n];
217             }
218             lg   = tcstat[gt].lambda;
219
220             for (d = 0; d < DIM; d++)
221             {
222                 vn             = v[n][d];
223                 if ((ptype[n] != eptVSite) && (ptype[n] != eptShell) && !nFreeze[gf][d])
224                 {
225                     vv             = lg*vn + f[n][d]*w_dt;
226
227                     /* do not scale the mean velocities u */
228                     u              = gstat[ga].u[d];
229                     va             = vv + accel[ga][d]*dt;
230                     vb             = va + (1.0-lg)*u;
231                     v[n][d]        = vb;
232                     xprime[n][d]   = x[n][d]+vb*dt;
233                 }
234                 else
235                 {
236                     v[n][d]        = 0.0;
237                     xprime[n][d]   = x[n][d];
238                 }
239             }
240         }
241     }
242     else
243     {
244         /* Plain update with Berendsen/v-rescale coupling */
245         for (n = start; n < nrend; n++)
246         {
247             if ((ptype[n] != eptVSite) && (ptype[n] != eptShell))
248             {
249                 w_dt = invmass[n]*dt;
250                 if (cTC)
251                 {
252                     gt = cTC[n];
253                 }
254                 lg = tcstat[gt].lambda;
255
256                 for (d = 0; d < DIM; d++)
257                 {
258                     vn           = lg*v[n][d] + f[n][d]*w_dt;
259                     v[n][d]      = vn;
260                     xprime[n][d] = x[n][d] + vn*dt;
261                 }
262             }
263             else
264             {
265                 for (d = 0; d < DIM; d++)
266                 {
267                     v[n][d]        = 0.0;
268                     xprime[n][d]   = x[n][d];
269                 }
270             }
271         }
272     }
273 }
274
275 static void do_update_vv_vel(int start, int nrend, double dt,
276                              rvec accel[], ivec nFreeze[], real invmass[],
277                              unsigned short ptype[], unsigned short cFREEZE[],
278                              unsigned short cACC[], rvec v[], rvec f[],
279                              gmx_bool bExtended, real veta, real alpha)
280 {
281     double imass, w_dt;
282     int    gf = 0, ga = 0;
283     rvec   vrel;
284     real   u, vn, vv, va, vb, vnrel;
285     int    n, d;
286     double g, mv1, mv2;
287
288     if (bExtended)
289     {
290         g        = 0.25*dt*veta*alpha;
291         mv1      = exp(-g);
292         mv2      = series_sinhx(g);
293     }
294     else
295     {
296         mv1      = 1.0;
297         mv2      = 1.0;
298     }
299     for (n = start; n < nrend; n++)
300     {
301         w_dt = invmass[n]*dt;
302         if (cFREEZE)
303         {
304             gf   = cFREEZE[n];
305         }
306         if (cACC)
307         {
308             ga   = cACC[n];
309         }
310
311         for (d = 0; d < DIM; d++)
312         {
313             if ((ptype[n] != eptVSite) && (ptype[n] != eptShell) && !nFreeze[gf][d])
314             {
315                 v[n][d]             = mv1*(mv1*v[n][d] + 0.5*(w_dt*mv2*f[n][d]))+0.5*accel[ga][d]*dt;
316             }
317             else
318             {
319                 v[n][d]        = 0.0;
320             }
321         }
322     }
323 } /* do_update_vv_vel */
324
325 static void do_update_vv_pos(int start, int nrend, double dt,
326                              ivec nFreeze[],
327                              unsigned short ptype[], unsigned short cFREEZE[],
328                              rvec x[], rvec xprime[], rvec v[],
329                              gmx_bool bExtended, real veta)
330 {
331     double imass, w_dt;
332     int    gf = 0;
333     int    n, d;
334     double g, mr1, mr2;
335
336     /* Would it make more sense if Parrinello-Rahman was put here? */
337     if (bExtended)
338     {
339         g        = 0.5*dt*veta;
340         mr1      = exp(g);
341         mr2      = series_sinhx(g);
342     }
343     else
344     {
345         mr1      = 1.0;
346         mr2      = 1.0;
347     }
348
349     for (n = start; n < nrend; n++)
350     {
351
352         if (cFREEZE)
353         {
354             gf   = cFREEZE[n];
355         }
356
357         for (d = 0; d < DIM; d++)
358         {
359             if ((ptype[n] != eptVSite) && (ptype[n] != eptShell) && !nFreeze[gf][d])
360             {
361                 xprime[n][d]   = mr1*(mr1*x[n][d]+mr2*dt*v[n][d]);
362             }
363             else
364             {
365                 xprime[n][d]   = x[n][d];
366             }
367         }
368     }
369 } /* do_update_vv_pos */
370
371 static void do_update_visc(int start, int nrend, double dt,
372                            t_grp_tcstat *tcstat,
373                            double nh_vxi[],
374                            real invmass[],
375                            unsigned short ptype[], unsigned short cTC[],
376                            rvec x[], rvec xprime[], rvec v[],
377                            rvec f[], matrix M, matrix box, real
378                            cos_accel, real vcos,
379                            gmx_bool bNH, gmx_bool bPR)
380 {
381     double imass, w_dt;
382     int    gt = 0;
383     real   vn, vc;
384     real   lg, vxi = 0, vv;
385     real   fac, cosz;
386     rvec   vrel;
387     int    n, d;
388
389     fac = 2*M_PI/(box[ZZ][ZZ]);
390
391     if (bNH || bPR)
392     {
393         /* Update with coupling to extended ensembles, used for
394          * Nose-Hoover and Parrinello-Rahman coupling
395          */
396         for (n = start; n < nrend; n++)
397         {
398             imass = invmass[n];
399             if (cTC)
400             {
401                 gt   = cTC[n];
402             }
403             lg   = tcstat[gt].lambda;
404             cosz = cos(fac*x[n][ZZ]);
405
406             copy_rvec(v[n], vrel);
407
408             vc            = cosz*vcos;
409             vrel[XX]     -= vc;
410             if (bNH)
411             {
412                 vxi        = nh_vxi[gt];
413             }
414             for (d = 0; d < DIM; d++)
415             {
416                 vn             = v[n][d];
417
418                 if ((ptype[n] != eptVSite) && (ptype[n] != eptShell))
419                 {
420                     vn  = (lg*vrel[d] + dt*(imass*f[n][d] - 0.5*vxi*vrel[d]
421                                             - iprod(M[d], vrel)))/(1 + 0.5*vxi*dt);
422                     if (d == XX)
423                     {
424                         vn += vc + dt*cosz*cos_accel;
425                     }
426                     v[n][d]        = vn;
427                     xprime[n][d]   = x[n][d]+vn*dt;
428                 }
429                 else
430                 {
431                     xprime[n][d]   = x[n][d];
432                 }
433             }
434         }
435     }
436     else
437     {
438         /* Classic version of update, used with berendsen coupling */
439         for (n = start; n < nrend; n++)
440         {
441             w_dt = invmass[n]*dt;
442             if (cTC)
443             {
444                 gt   = cTC[n];
445             }
446             lg   = tcstat[gt].lambda;
447             cosz = cos(fac*x[n][ZZ]);
448
449             for (d = 0; d < DIM; d++)
450             {
451                 vn             = v[n][d];
452
453                 if ((ptype[n] != eptVSite) && (ptype[n] != eptShell))
454                 {
455                     if (d == XX)
456                     {
457                         vc           = cosz*vcos;
458                         /* Do not scale the cosine velocity profile */
459                         vv           = vc + lg*(vn - vc + f[n][d]*w_dt);
460                         /* Add the cosine accelaration profile */
461                         vv          += dt*cosz*cos_accel;
462                     }
463                     else
464                     {
465                         vv           = lg*(vn + f[n][d]*w_dt);
466                     }
467                     v[n][d]        = vv;
468                     xprime[n][d]   = x[n][d]+vv*dt;
469                 }
470                 else
471                 {
472                     v[n][d]        = 0.0;
473                     xprime[n][d]   = x[n][d];
474                 }
475             }
476         }
477     }
478 }
479
480 /* Allocates and initializes sd->gaussrand[i] for i=1, i<sd->ngaussrand,
481  * Using seeds generated from sd->gaussrand[0].
482  */
483 static void init_multiple_gaussrand(gmx_stochd_t *sd)
484 {
485     int           ngr, i;
486     unsigned int *seed;
487
488     ngr = sd->ngaussrand;
489     snew(seed, ngr);
490
491     for (i = 1; i < ngr; i++)
492     {
493         seed[i] = gmx_rng_uniform_uint32(sd->gaussrand[0]);
494     }
495
496     if (ngr != gmx_omp_nthreads_get(emntUpdate))
497     {
498         gmx_incons("The number of Gaussian number generators should be equal to gmx_omp_nthreads_get(emntUpdate)");
499     }
500
501 #pragma omp parallel num_threads(gmx_omp_nthreads_get(emntUpdate))
502     {
503         int th;
504
505         th = gmx_omp_get_thread_num();
506         if (th > 0)
507         {
508             /* Initialize on each thread to get memory allocated thread-local */
509             sd->gaussrand[th] = gmx_rng_init(seed[th]);
510         }
511     }
512
513     sfree(seed);
514 }
515
516 static gmx_stochd_t *init_stochd(t_inputrec *ir, int nthreads)
517 {
518     gmx_stochd_t   *sd;
519     gmx_sd_const_t *sdc;
520     int             ngtc, n, th;
521     real            y;
522
523     snew(sd, 1);
524
525     /* Initiate random number generator for langevin type dynamics,
526      * for BD, SD or velocity rescaling temperature coupling.
527      */
528     if (ir->eI == eiBD || EI_SD(ir->eI))
529     {
530         sd->ngaussrand = nthreads;
531     }
532     else
533     {
534         sd->ngaussrand = 1;
535     }
536     snew(sd->gaussrand, sd->ngaussrand);
537
538     /* Initialize the first random generator */
539     sd->gaussrand[0] = gmx_rng_init(ir->ld_seed);
540
541     if (sd->ngaussrand > 1)
542     {
543         /* Initialize the rest of the random number generators,
544          * using the first one to generate seeds.
545          */
546         init_multiple_gaussrand(sd);
547     }
548
549     ngtc = ir->opts.ngtc;
550
551     if (ir->eI == eiBD)
552     {
553         snew(sd->bd_rf, ngtc);
554     }
555     else if (EI_SD(ir->eI))
556     {
557         snew(sd->sdc, ngtc);
558         snew(sd->sdsig, ngtc);
559
560         sdc = sd->sdc;
561         for (n = 0; n < ngtc; n++)
562         {
563             if (ir->opts.tau_t[n] > 0)
564             {
565                 sdc[n].gdt = ir->delta_t/ir->opts.tau_t[n];
566                 sdc[n].eph = exp(sdc[n].gdt/2);
567                 sdc[n].emh = exp(-sdc[n].gdt/2);
568                 sdc[n].em  = exp(-sdc[n].gdt);
569             }
570             else
571             {
572                 /* No friction and noise on this group */
573                 sdc[n].gdt = 0;
574                 sdc[n].eph = 1;
575                 sdc[n].emh = 1;
576                 sdc[n].em  = 1;
577             }
578             if (sdc[n].gdt >= 0.05)
579             {
580                 sdc[n].b = sdc[n].gdt*(sdc[n].eph*sdc[n].eph - 1)
581                     - 4*(sdc[n].eph - 1)*(sdc[n].eph - 1);
582                 sdc[n].c = sdc[n].gdt - 3 + 4*sdc[n].emh - sdc[n].em;
583                 sdc[n].d = 2 - sdc[n].eph - sdc[n].emh;
584             }
585             else
586             {
587                 y = sdc[n].gdt/2;
588                 /* Seventh order expansions for small y */
589                 sdc[n].b = y*y*y*y*(1/3.0+y*(1/3.0+y*(17/90.0+y*7/9.0)));
590                 sdc[n].c = y*y*y*(2/3.0+y*(-1/2.0+y*(7/30.0+y*(-1/12.0+y*31/1260.0))));
591                 sdc[n].d = y*y*(-1+y*y*(-1/12.0-y*y/360.0));
592             }
593             if (debug)
594             {
595                 fprintf(debug, "SD const tc-grp %d: b %g  c %g  d %g\n",
596                         n, sdc[n].b, sdc[n].c, sdc[n].d);
597             }
598         }
599     }
600     else if (ETC_ANDERSEN(ir->etc))
601     {
602         int        ngtc;
603         t_grpopts *opts;
604         real       reft;
605
606         opts = &ir->opts;
607         ngtc = opts->ngtc;
608
609         snew(sd->randomize_group, ngtc);
610         snew(sd->boltzfac, ngtc);
611
612         /* for now, assume that all groups, if randomized, are randomized at the same rate, i.e. tau_t is the same. */
613         /* since constraint groups don't necessarily match up with temperature groups! This is checked in readir.c */
614
615         for (n = 0; n < ngtc; n++)
616         {
617             reft = max(0.0, opts->ref_t[n]);
618             if ((opts->tau_t[n] > 0) && (reft > 0))  /* tau_t or ref_t = 0 means that no randomization is done */
619             {
620                 sd->randomize_group[n] = TRUE;
621                 sd->boltzfac[n]        = BOLTZ*opts->ref_t[n];
622             }
623             else
624             {
625                 sd->randomize_group[n] = FALSE;
626             }
627         }
628     }
629     return sd;
630 }
631
632 void get_stochd_state(gmx_update_t upd, t_state *state)
633 {
634     /* Note that we only get the state of the first random generator,
635      * even if there are multiple. This avoids repetition.
636      */
637     gmx_rng_get_state(upd->sd->gaussrand[0], state->ld_rng, state->ld_rngi);
638 }
639
640 void set_stochd_state(gmx_update_t upd, t_state *state)
641 {
642     gmx_stochd_t *sd;
643     int           i;
644
645     sd = upd->sd;
646
647     gmx_rng_set_state(sd->gaussrand[0], state->ld_rng, state->ld_rngi[0]);
648
649     if (sd->ngaussrand > 1)
650     {
651         /* We only end up here with SD or BD with OpenMP.
652          * Destroy and reinitialize the rest of the random number generators,
653          * using seeds generated from the first one.
654          * Although this doesn't recover the previous state,
655          * it at least avoids repetition, which is most important.
656          * Exaclty restoring states with all MPI+OpenMP setups is difficult
657          * and as the integrator is random to start with, doesn't gain us much.
658          */
659         for (i = 1; i < sd->ngaussrand; i++)
660         {
661             gmx_rng_destroy(sd->gaussrand[i]);
662         }
663
664         init_multiple_gaussrand(sd);
665     }
666 }
667
668 gmx_update_t init_update(t_inputrec *ir)
669 {
670     t_gmx_update *upd;
671
672     snew(upd, 1);
673
674     if (ir->eI == eiBD || EI_SD(ir->eI) || ir->etc == etcVRESCALE || ETC_ANDERSEN(ir->etc))
675     {
676         upd->sd = init_stochd(ir, gmx_omp_nthreads_get(emntUpdate));
677     }
678
679     upd->xp                 = NULL;
680     upd->xp_nalloc          = 0;
681     upd->randatom           = NULL;
682     upd->randatom_list      = NULL;
683     upd->randatom_list_init = FALSE; /* we have not yet cleared the data structure at this point */
684
685     return upd;
686 }
687
688 static void do_update_sd1(gmx_stochd_t *sd,
689                           gmx_rng_t gaussrand,
690                           int start, int nrend, double dt,
691                           rvec accel[], ivec nFreeze[],
692                           real invmass[], unsigned short ptype[],
693                           unsigned short cFREEZE[], unsigned short cACC[],
694                           unsigned short cTC[],
695                           rvec x[], rvec xprime[], rvec v[], rvec f[],
696                           int ngtc, real tau_t[], real ref_t[])
697 {
698     gmx_sd_const_t *sdc;
699     gmx_sd_sigma_t *sig;
700     real            kT;
701     int             gf = 0, ga = 0, gt = 0;
702     real            ism, sd_V;
703     int             n, d;
704
705     sdc = sd->sdc;
706     sig = sd->sdsig;
707
708     for (n = 0; n < ngtc; n++)
709     {
710         kT = BOLTZ*ref_t[n];
711         /* The mass is encounted for later, since this differs per atom */
712         sig[n].V  = sqrt(kT*(1 - sdc[n].em*sdc[n].em));
713     }
714
715     for (n = start; n < nrend; n++)
716     {
717         ism = sqrt(invmass[n]);
718         if (cFREEZE)
719         {
720             gf  = cFREEZE[n];
721         }
722         if (cACC)
723         {
724             ga  = cACC[n];
725         }
726         if (cTC)
727         {
728             gt  = cTC[n];
729         }
730
731         for (d = 0; d < DIM; d++)
732         {
733             if ((ptype[n] != eptVSite) && (ptype[n] != eptShell) && !nFreeze[gf][d])
734             {
735                 sd_V = ism*sig[gt].V*gmx_rng_gaussian_table(gaussrand);
736
737                 v[n][d] = v[n][d]*sdc[gt].em
738                     + (invmass[n]*f[n][d] + accel[ga][d])*tau_t[gt]*(1 - sdc[gt].em)
739                     + sd_V;
740
741                 xprime[n][d] = x[n][d] + v[n][d]*dt;
742             }
743             else
744             {
745                 v[n][d]      = 0.0;
746                 xprime[n][d] = x[n][d];
747             }
748         }
749     }
750 }
751
752 static void check_sd2_work_data_allocation(gmx_stochd_t *sd, int nrend)
753 {
754     if (nrend > sd->sd_V_nalloc)
755     {
756         sd->sd_V_nalloc = over_alloc_dd(nrend);
757         srenew(sd->sd_V, sd->sd_V_nalloc);
758     }
759 }
760
761 static void do_update_sd2_Tconsts(gmx_stochd_t *sd,
762                                   int           ngtc,
763                                   const real    tau_t[],
764                                   const real    ref_t[])
765 {
766     /* This is separated from the update below, because it is single threaded */
767     gmx_sd_const_t *sdc;
768     gmx_sd_sigma_t *sig;
769     int             gt;
770     real            kT;
771
772     sdc = sd->sdc;
773     sig = sd->sdsig;
774
775     for (gt = 0; gt < ngtc; gt++)
776     {
777         kT = BOLTZ*ref_t[gt];
778         /* The mass is encounted for later, since this differs per atom */
779         sig[gt].V  = sqrt(kT*(1-sdc[gt].em));
780         sig[gt].X  = sqrt(kT*sqr(tau_t[gt])*sdc[gt].c);
781         sig[gt].Yv = sqrt(kT*sdc[gt].b/sdc[gt].c);
782         sig[gt].Yx = sqrt(kT*sqr(tau_t[gt])*sdc[gt].b/(1-sdc[gt].em));
783     }
784 }
785
786 static void do_update_sd2(gmx_stochd_t *sd,
787                           gmx_rng_t gaussrand,
788                           gmx_bool bInitStep,
789                           int start, int nrend,
790                           rvec accel[], ivec nFreeze[],
791                           real invmass[], unsigned short ptype[],
792                           unsigned short cFREEZE[], unsigned short cACC[],
793                           unsigned short cTC[],
794                           rvec x[], rvec xprime[], rvec v[], rvec f[],
795                           rvec sd_X[],
796                           const real tau_t[],
797                           gmx_bool bFirstHalf)
798 {
799     gmx_sd_const_t *sdc;
800     gmx_sd_sigma_t *sig;
801     /* The random part of the velocity update, generated in the first
802      * half of the update, needs to be remembered for the second half.
803      */
804     rvec  *sd_V;
805     real   kT;
806     int    gf = 0, ga = 0, gt = 0;
807     real   vn = 0, Vmh, Xmh;
808     real   ism;
809     int    n, d;
810
811     sdc  = sd->sdc;
812     sig  = sd->sdsig;
813     sd_V = sd->sd_V;
814
815     for (n = start; n < nrend; n++)
816     {
817         ism = sqrt(invmass[n]);
818         if (cFREEZE)
819         {
820             gf  = cFREEZE[n];
821         }
822         if (cACC)
823         {
824             ga  = cACC[n];
825         }
826         if (cTC)
827         {
828             gt  = cTC[n];
829         }
830
831         for (d = 0; d < DIM; d++)
832         {
833             if (bFirstHalf)
834             {
835                 vn             = v[n][d];
836             }
837             if ((ptype[n] != eptVSite) && (ptype[n] != eptShell) && !nFreeze[gf][d])
838             {
839                 if (bFirstHalf)
840                 {
841                     if (bInitStep)
842                     {
843                         sd_X[n][d] = ism*sig[gt].X*gmx_rng_gaussian_table(gaussrand);
844                     }
845                     Vmh = sd_X[n][d]*sdc[gt].d/(tau_t[gt]*sdc[gt].c)
846                         + ism*sig[gt].Yv*gmx_rng_gaussian_table(gaussrand);
847                     sd_V[n][d] = ism*sig[gt].V*gmx_rng_gaussian_table(gaussrand);
848
849                     v[n][d] = vn*sdc[gt].em
850                         + (invmass[n]*f[n][d] + accel[ga][d])*tau_t[gt]*(1 - sdc[gt].em)
851                         + sd_V[n][d] - sdc[gt].em*Vmh;
852
853                     xprime[n][d] = x[n][d] + v[n][d]*tau_t[gt]*(sdc[gt].eph - sdc[gt].emh);
854                 }
855                 else
856                 {
857
858                     /* Correct the velocities for the constraints.
859                      * This operation introduces some inaccuracy,
860                      * since the velocity is determined from differences in coordinates.
861                      */
862                     v[n][d] =
863                         (xprime[n][d] - x[n][d])/(tau_t[gt]*(sdc[gt].eph - sdc[gt].emh));
864
865                     Xmh = sd_V[n][d]*tau_t[gt]*sdc[gt].d/(sdc[gt].em-1)
866                         + ism*sig[gt].Yx*gmx_rng_gaussian_table(gaussrand);
867                     sd_X[n][d] = ism*sig[gt].X*gmx_rng_gaussian_table(gaussrand);
868
869                     xprime[n][d] += sd_X[n][d] - Xmh;
870
871                 }
872             }
873             else
874             {
875                 if (bFirstHalf)
876                 {
877                     v[n][d]        = 0.0;
878                     xprime[n][d]   = x[n][d];
879                 }
880             }
881         }
882     }
883 }
884
885 static void do_update_bd_Tconsts(double dt, real friction_coefficient,
886                                  int ngtc, const real ref_t[],
887                                  real *rf)
888 {
889     /* This is separated from the update below, because it is single threaded */
890     int gt;
891
892     if (friction_coefficient != 0)
893     {
894         for (gt = 0; gt < ngtc; gt++)
895         {
896             rf[gt] = sqrt(2.0*BOLTZ*ref_t[gt]/(friction_coefficient*dt));
897         }
898     }
899     else
900     {
901         for (gt = 0; gt < ngtc; gt++)
902         {
903             rf[gt] = sqrt(2.0*BOLTZ*ref_t[gt]);
904         }
905     }
906 }
907
908 static void do_update_bd(int start, int nrend, double dt,
909                          ivec nFreeze[],
910                          real invmass[], unsigned short ptype[],
911                          unsigned short cFREEZE[], unsigned short cTC[],
912                          rvec x[], rvec xprime[], rvec v[],
913                          rvec f[], real friction_coefficient,
914                          real *rf, gmx_rng_t gaussrand)
915 {
916     /* note -- these appear to be full step velocities . . .  */
917     int    gf = 0, gt = 0;
918     real   vn;
919     real   invfr = 0;
920     int    n, d;
921
922     if (friction_coefficient != 0)
923     {
924         invfr = 1.0/friction_coefficient;
925     }
926
927     for (n = start; (n < nrend); n++)
928     {
929         if (cFREEZE)
930         {
931             gf = cFREEZE[n];
932         }
933         if (cTC)
934         {
935             gt = cTC[n];
936         }
937         for (d = 0; (d < DIM); d++)
938         {
939             if ((ptype[n] != eptVSite) && (ptype[n] != eptShell) && !nFreeze[gf][d])
940             {
941                 if (friction_coefficient != 0)
942                 {
943                     vn = invfr*f[n][d] + rf[gt]*gmx_rng_gaussian_table(gaussrand);
944                 }
945                 else
946                 {
947                     /* NOTE: invmass = 2/(mass*friction_constant*dt) */
948                     vn = 0.5*invmass[n]*f[n][d]*dt
949                         + sqrt(0.5*invmass[n])*rf[gt]*gmx_rng_gaussian_table(gaussrand);
950                 }
951
952                 v[n][d]      = vn;
953                 xprime[n][d] = x[n][d]+vn*dt;
954             }
955             else
956             {
957                 v[n][d]      = 0.0;
958                 xprime[n][d] = x[n][d];
959             }
960         }
961     }
962 }
963
964 static void dump_it_all(FILE gmx_unused *fp, const char gmx_unused *title,
965                         int gmx_unused natoms, rvec gmx_unused x[], rvec gmx_unused xp[],
966                         rvec gmx_unused v[], rvec gmx_unused f[])
967 {
968 #ifdef DEBUG
969     if (fp)
970     {
971         fprintf(fp, "%s\n", title);
972         pr_rvecs(fp, 0, "x", x, natoms);
973         pr_rvecs(fp, 0, "xp", xp, natoms);
974         pr_rvecs(fp, 0, "v", v, natoms);
975         pr_rvecs(fp, 0, "f", f, natoms);
976     }
977 #endif
978 }
979
980 static void calc_ke_part_normal(rvec v[], t_grpopts *opts, t_mdatoms *md,
981                                 gmx_ekindata_t *ekind, t_nrnb *nrnb, gmx_bool bEkinAveVel,
982                                 gmx_bool bSaveEkinOld)
983 {
984     int           g;
985     t_grp_tcstat *tcstat  = ekind->tcstat;
986     t_grp_acc    *grpstat = ekind->grpstat;
987     int           nthread, thread;
988
989     /* three main: VV with AveVel, vv with AveEkin, leap with AveEkin.  Leap with AveVel is also
990        an option, but not supported now.  Additionally, if we are doing iterations.
991        bEkinAveVel: If TRUE, we sum into ekin, if FALSE, into ekinh.
992        bSavEkinOld: If TRUE (in the case of iteration = bIterate is TRUE), we don't copy over the ekinh_old.
993        If FALSE, we overrwrite it.
994      */
995
996     /* group velocities are calculated in update_ekindata and
997      * accumulated in acumulate_groups.
998      * Now the partial global and groups ekin.
999      */
1000     for (g = 0; (g < opts->ngtc); g++)
1001     {
1002
1003         if (!bSaveEkinOld)
1004         {
1005             copy_mat(tcstat[g].ekinh, tcstat[g].ekinh_old);
1006         }
1007         if (bEkinAveVel)
1008         {
1009             clear_mat(tcstat[g].ekinf);
1010         }
1011         else
1012         {
1013             clear_mat(tcstat[g].ekinh);
1014         }
1015         if (bEkinAveVel)
1016         {
1017             tcstat[g].ekinscalef_nhc = 1.0; /* need to clear this -- logic is complicated! */
1018         }
1019     }
1020     ekind->dekindl_old = ekind->dekindl;
1021
1022     nthread = gmx_omp_nthreads_get(emntUpdate);
1023
1024 #pragma omp parallel for num_threads(nthread) schedule(static)
1025     for (thread = 0; thread < nthread; thread++)
1026     {
1027         int     start_t, end_t, n;
1028         int     ga, gt;
1029         rvec    v_corrt;
1030         real    hm;
1031         int     d, m;
1032         matrix *ekin_sum;
1033         real   *dekindl_sum;
1034
1035         start_t = md->start + ((thread+0)*md->homenr)/nthread;
1036         end_t   = md->start + ((thread+1)*md->homenr)/nthread;
1037
1038         ekin_sum    = ekind->ekin_work[thread];
1039         dekindl_sum = ekind->dekindl_work[thread];
1040
1041         for (gt = 0; gt < opts->ngtc; gt++)
1042         {
1043             clear_mat(ekin_sum[gt]);
1044         }
1045         *dekindl_sum = 0.0;
1046
1047         ga = 0;
1048         gt = 0;
1049         for (n = start_t; n < end_t; n++)
1050         {
1051             if (md->cACC)
1052             {
1053                 ga = md->cACC[n];
1054             }
1055             if (md->cTC)
1056             {
1057                 gt = md->cTC[n];
1058             }
1059             hm   = 0.5*md->massT[n];
1060
1061             for (d = 0; (d < DIM); d++)
1062             {
1063                 v_corrt[d]  = v[n][d]  - grpstat[ga].u[d];
1064             }
1065             for (d = 0; (d < DIM); d++)
1066             {
1067                 for (m = 0; (m < DIM); m++)
1068                 {
1069                     /* if we're computing a full step velocity, v_corrt[d] has v(t).  Otherwise, v(t+dt/2) */
1070                     ekin_sum[gt][m][d] += hm*v_corrt[m]*v_corrt[d];
1071                 }
1072             }
1073             if (md->nMassPerturbed && md->bPerturbed[n])
1074             {
1075                 *dekindl_sum +=
1076                     0.5*(md->massB[n] - md->massA[n])*iprod(v_corrt, v_corrt);
1077             }
1078         }
1079     }
1080
1081     ekind->dekindl = 0;
1082     for (thread = 0; thread < nthread; thread++)
1083     {
1084         for (g = 0; g < opts->ngtc; g++)
1085         {
1086             if (bEkinAveVel)
1087             {
1088                 m_add(tcstat[g].ekinf, ekind->ekin_work[thread][g],
1089                       tcstat[g].ekinf);
1090             }
1091             else
1092             {
1093                 m_add(tcstat[g].ekinh, ekind->ekin_work[thread][g],
1094                       tcstat[g].ekinh);
1095             }
1096         }
1097
1098         ekind->dekindl += *ekind->dekindl_work[thread];
1099     }
1100
1101     inc_nrnb(nrnb, eNR_EKIN, md->homenr);
1102 }
1103
1104 static void calc_ke_part_visc(matrix box, rvec x[], rvec v[],
1105                               t_grpopts *opts, t_mdatoms *md,
1106                               gmx_ekindata_t *ekind,
1107                               t_nrnb *nrnb, gmx_bool bEkinAveVel)
1108 {
1109     int           start = md->start, homenr = md->homenr;
1110     int           g, d, n, m, gt = 0;
1111     rvec          v_corrt;
1112     real          hm;
1113     t_grp_tcstat *tcstat = ekind->tcstat;
1114     t_cos_acc    *cosacc = &(ekind->cosacc);
1115     real          dekindl;
1116     real          fac, cosz;
1117     double        mvcos;
1118
1119     for (g = 0; g < opts->ngtc; g++)
1120     {
1121         copy_mat(ekind->tcstat[g].ekinh, ekind->tcstat[g].ekinh_old);
1122         clear_mat(ekind->tcstat[g].ekinh);
1123     }
1124     ekind->dekindl_old = ekind->dekindl;
1125
1126     fac     = 2*M_PI/box[ZZ][ZZ];
1127     mvcos   = 0;
1128     dekindl = 0;
1129     for (n = start; n < start+homenr; n++)
1130     {
1131         if (md->cTC)
1132         {
1133             gt = md->cTC[n];
1134         }
1135         hm   = 0.5*md->massT[n];
1136
1137         /* Note that the times of x and v differ by half a step */
1138         /* MRS -- would have to be changed for VV */
1139         cosz         = cos(fac*x[n][ZZ]);
1140         /* Calculate the amplitude of the new velocity profile */
1141         mvcos       += 2*cosz*md->massT[n]*v[n][XX];
1142
1143         copy_rvec(v[n], v_corrt);
1144         /* Subtract the profile for the kinetic energy */
1145         v_corrt[XX] -= cosz*cosacc->vcos;
1146         for (d = 0; (d < DIM); d++)
1147         {
1148             for (m = 0; (m < DIM); m++)
1149             {
1150                 /* if we're computing a full step velocity, v_corrt[d] has v(t).  Otherwise, v(t+dt/2) */
1151                 if (bEkinAveVel)
1152                 {
1153                     tcstat[gt].ekinf[m][d] += hm*v_corrt[m]*v_corrt[d];
1154                 }
1155                 else
1156                 {
1157                     tcstat[gt].ekinh[m][d] += hm*v_corrt[m]*v_corrt[d];
1158                 }
1159             }
1160         }
1161         if (md->nPerturbed && md->bPerturbed[n])
1162         {
1163             dekindl += 0.5*(md->massB[n] - md->massA[n])*iprod(v_corrt, v_corrt);
1164         }
1165     }
1166     ekind->dekindl = dekindl;
1167     cosacc->mvcos  = mvcos;
1168
1169     inc_nrnb(nrnb, eNR_EKIN, homenr);
1170 }
1171
1172 void calc_ke_part(t_state *state, t_grpopts *opts, t_mdatoms *md,
1173                   gmx_ekindata_t *ekind, t_nrnb *nrnb, gmx_bool bEkinAveVel, gmx_bool bSaveEkinOld)
1174 {
1175     if (ekind->cosacc.cos_accel == 0)
1176     {
1177         calc_ke_part_normal(state->v, opts, md, ekind, nrnb, bEkinAveVel, bSaveEkinOld);
1178     }
1179     else
1180     {
1181         calc_ke_part_visc(state->box, state->x, state->v, opts, md, ekind, nrnb, bEkinAveVel);
1182     }
1183 }
1184
1185 extern void init_ekinstate(ekinstate_t *ekinstate, const t_inputrec *ir)
1186 {
1187     ekinstate->ekin_n = ir->opts.ngtc;
1188     snew(ekinstate->ekinh, ekinstate->ekin_n);
1189     snew(ekinstate->ekinf, ekinstate->ekin_n);
1190     snew(ekinstate->ekinh_old, ekinstate->ekin_n);
1191     snew(ekinstate->ekinscalef_nhc, ekinstate->ekin_n);
1192     snew(ekinstate->ekinscaleh_nhc, ekinstate->ekin_n);
1193     snew(ekinstate->vscale_nhc, ekinstate->ekin_n);
1194     ekinstate->dekindl = 0;
1195     ekinstate->mvcos   = 0;
1196 }
1197
1198 void update_ekinstate(ekinstate_t *ekinstate, gmx_ekindata_t *ekind)
1199 {
1200     int i;
1201
1202     for (i = 0; i < ekinstate->ekin_n; i++)
1203     {
1204         copy_mat(ekind->tcstat[i].ekinh, ekinstate->ekinh[i]);
1205         copy_mat(ekind->tcstat[i].ekinf, ekinstate->ekinf[i]);
1206         copy_mat(ekind->tcstat[i].ekinh_old, ekinstate->ekinh_old[i]);
1207         ekinstate->ekinscalef_nhc[i] = ekind->tcstat[i].ekinscalef_nhc;
1208         ekinstate->ekinscaleh_nhc[i] = ekind->tcstat[i].ekinscaleh_nhc;
1209         ekinstate->vscale_nhc[i]     = ekind->tcstat[i].vscale_nhc;
1210     }
1211
1212     copy_mat(ekind->ekin, ekinstate->ekin_total);
1213     ekinstate->dekindl = ekind->dekindl;
1214     ekinstate->mvcos   = ekind->cosacc.mvcos;
1215
1216 }
1217
1218 void restore_ekinstate_from_state(t_commrec *cr,
1219                                   gmx_ekindata_t *ekind, ekinstate_t *ekinstate)
1220 {
1221     int i, n;
1222
1223     if (MASTER(cr))
1224     {
1225         for (i = 0; i < ekinstate->ekin_n; i++)
1226         {
1227             copy_mat(ekinstate->ekinh[i], ekind->tcstat[i].ekinh);
1228             copy_mat(ekinstate->ekinf[i], ekind->tcstat[i].ekinf);
1229             copy_mat(ekinstate->ekinh_old[i], ekind->tcstat[i].ekinh_old);
1230             ekind->tcstat[i].ekinscalef_nhc = ekinstate->ekinscalef_nhc[i];
1231             ekind->tcstat[i].ekinscaleh_nhc = ekinstate->ekinscaleh_nhc[i];
1232             ekind->tcstat[i].vscale_nhc     = ekinstate->vscale_nhc[i];
1233         }
1234
1235         copy_mat(ekinstate->ekin_total, ekind->ekin);
1236
1237         ekind->dekindl      = ekinstate->dekindl;
1238         ekind->cosacc.mvcos = ekinstate->mvcos;
1239         n                   = ekinstate->ekin_n;
1240     }
1241
1242     if (PAR(cr))
1243     {
1244         gmx_bcast(sizeof(n), &n, cr);
1245         for (i = 0; i < n; i++)
1246         {
1247             gmx_bcast(DIM*DIM*sizeof(ekind->tcstat[i].ekinh[0][0]),
1248                       ekind->tcstat[i].ekinh[0], cr);
1249             gmx_bcast(DIM*DIM*sizeof(ekind->tcstat[i].ekinf[0][0]),
1250                       ekind->tcstat[i].ekinf[0], cr);
1251             gmx_bcast(DIM*DIM*sizeof(ekind->tcstat[i].ekinh_old[0][0]),
1252                       ekind->tcstat[i].ekinh_old[0], cr);
1253
1254             gmx_bcast(sizeof(ekind->tcstat[i].ekinscalef_nhc),
1255                       &(ekind->tcstat[i].ekinscalef_nhc), cr);
1256             gmx_bcast(sizeof(ekind->tcstat[i].ekinscaleh_nhc),
1257                       &(ekind->tcstat[i].ekinscaleh_nhc), cr);
1258             gmx_bcast(sizeof(ekind->tcstat[i].vscale_nhc),
1259                       &(ekind->tcstat[i].vscale_nhc), cr);
1260         }
1261         gmx_bcast(DIM*DIM*sizeof(ekind->ekin[0][0]),
1262                   ekind->ekin[0], cr);
1263
1264         gmx_bcast(sizeof(ekind->dekindl), &ekind->dekindl, cr);
1265         gmx_bcast(sizeof(ekind->cosacc.mvcos), &ekind->cosacc.mvcos, cr);
1266     }
1267 }
1268
1269 void set_deform_reference_box(gmx_update_t upd, gmx_int64_t step, matrix box)
1270 {
1271     upd->deformref_step = step;
1272     copy_mat(box, upd->deformref_box);
1273 }
1274
1275 static void deform(gmx_update_t upd,
1276                    int start, int homenr, rvec x[], matrix box, matrix *scale_tot,
1277                    const t_inputrec *ir, gmx_int64_t step)
1278 {
1279     matrix bnew, invbox, mu;
1280     real   elapsed_time;
1281     int    i, j;
1282
1283     elapsed_time = (step + 1 - upd->deformref_step)*ir->delta_t;
1284     copy_mat(box, bnew);
1285     for (i = 0; i < DIM; i++)
1286     {
1287         for (j = 0; j < DIM; j++)
1288         {
1289             if (ir->deform[i][j] != 0)
1290             {
1291                 bnew[i][j] =
1292                     upd->deformref_box[i][j] + elapsed_time*ir->deform[i][j];
1293             }
1294         }
1295     }
1296     /* We correct the off-diagonal elements,
1297      * which can grow indefinitely during shearing,
1298      * so the shifts do not get messed up.
1299      */
1300     for (i = 1; i < DIM; i++)
1301     {
1302         for (j = i-1; j >= 0; j--)
1303         {
1304             while (bnew[i][j] - box[i][j] > 0.5*bnew[j][j])
1305             {
1306                 rvec_dec(bnew[i], bnew[j]);
1307             }
1308             while (bnew[i][j] - box[i][j] < -0.5*bnew[j][j])
1309             {
1310                 rvec_inc(bnew[i], bnew[j]);
1311             }
1312         }
1313     }
1314     m_inv_ur0(box, invbox);
1315     copy_mat(bnew, box);
1316     mmul_ur0(box, invbox, mu);
1317
1318     for (i = start; i < start+homenr; i++)
1319     {
1320         x[i][XX] = mu[XX][XX]*x[i][XX]+mu[YY][XX]*x[i][YY]+mu[ZZ][XX]*x[i][ZZ];
1321         x[i][YY] = mu[YY][YY]*x[i][YY]+mu[ZZ][YY]*x[i][ZZ];
1322         x[i][ZZ] = mu[ZZ][ZZ]*x[i][ZZ];
1323     }
1324     if (*scale_tot)
1325     {
1326         /* The transposes of the scaling matrices are stored,
1327          * so we need to do matrix multiplication in the inverse order.
1328          */
1329         mmul_ur0(*scale_tot, mu, *scale_tot);
1330     }
1331 }
1332
1333 static void combine_forces(int nstcalclr,
1334                            gmx_constr_t constr,
1335                            t_inputrec *ir, t_mdatoms *md, t_idef *idef,
1336                            t_commrec *cr,
1337                            gmx_int64_t step,
1338                            t_state *state, gmx_bool bMolPBC,
1339                            int start, int nrend,
1340                            rvec f[], rvec f_lr[],
1341                            t_nrnb *nrnb)
1342 {
1343     int  i, d, nm1;
1344
1345     /* f contains the short-range forces + the long range forces
1346      * which are stored separately in f_lr.
1347      */
1348
1349     if (constr != NULL && !(ir->eConstrAlg == econtSHAKE && ir->epc == epcNO))
1350     {
1351         /* We need to constrain the LR forces separately,
1352          * because due to the different pre-factor for the SR and LR
1353          * forces in the update algorithm, we can not determine
1354          * the constraint force for the coordinate constraining.
1355          * Constrain only the additional LR part of the force.
1356          */
1357         /* MRS -- need to make sure this works with trotter integration -- the constraint calls may not be right.*/
1358         constrain(NULL, FALSE, FALSE, constr, idef, ir, NULL, cr, step, 0, md,
1359                   state->x, f_lr, f_lr, bMolPBC, state->box, state->lambda[efptBONDED], NULL,
1360                   NULL, NULL, nrnb, econqForce, ir->epc == epcMTTK, state->veta, state->veta);
1361     }
1362
1363     /* Add nstcalclr-1 times the LR force to the sum of both forces
1364      * and store the result in forces_lr.
1365      */
1366     nm1 = nstcalclr - 1;
1367     for (i = start; i < nrend; i++)
1368     {
1369         for (d = 0; d < DIM; d++)
1370         {
1371             f_lr[i][d] = f[i][d] + nm1*f_lr[i][d];
1372         }
1373     }
1374 }
1375
1376 void update_tcouple(gmx_int64_t       step,
1377                     t_inputrec       *inputrec,
1378                     t_state          *state,
1379                     gmx_ekindata_t   *ekind,
1380                     gmx_update_t      upd,
1381                     t_extmass        *MassQ,
1382                     t_mdatoms        *md)
1383
1384 {
1385     gmx_bool   bTCouple = FALSE;
1386     real       dttc;
1387     int        i, start, end, homenr, offset;
1388
1389     /* if using vv with trotter decomposition methods, we do this elsewhere in the code */
1390     if (inputrec->etc != etcNO &&
1391         !(IR_NVT_TROTTER(inputrec) || IR_NPT_TROTTER(inputrec) || IR_NPH_TROTTER(inputrec)))
1392     {
1393         /* We should only couple after a step where energies were determined (for leapfrog versions)
1394            or the step energies are determined, for velocity verlet versions */
1395
1396         if (EI_VV(inputrec->eI))
1397         {
1398             offset = 0;
1399         }
1400         else
1401         {
1402             offset = 1;
1403         }
1404         bTCouple = (inputrec->nsttcouple == 1 ||
1405                     do_per_step(step+inputrec->nsttcouple-offset,
1406                                 inputrec->nsttcouple));
1407     }
1408
1409     if (bTCouple)
1410     {
1411         dttc = inputrec->nsttcouple*inputrec->delta_t;
1412
1413         switch (inputrec->etc)
1414         {
1415             case etcNO:
1416                 break;
1417             case etcBERENDSEN:
1418                 berendsen_tcoupl(inputrec, ekind, dttc);
1419                 break;
1420             case etcNOSEHOOVER:
1421                 nosehoover_tcoupl(&(inputrec->opts), ekind, dttc,
1422                                   state->nosehoover_xi, state->nosehoover_vxi, MassQ);
1423                 break;
1424             case etcVRESCALE:
1425                 vrescale_tcoupl(inputrec, ekind, dttc,
1426                                 state->therm_integral, upd->sd->gaussrand[0]);
1427                 break;
1428         }
1429         /* rescale in place here */
1430         if (EI_VV(inputrec->eI))
1431         {
1432             rescale_velocities(ekind, md, md->start, md->start+md->homenr, state->v);
1433         }
1434     }
1435     else
1436     {
1437         /* Set the T scaling lambda to 1 to have no scaling */
1438         for (i = 0; (i < inputrec->opts.ngtc); i++)
1439         {
1440             ekind->tcstat[i].lambda = 1.0;
1441         }
1442     }
1443 }
1444
1445 void update_pcouple(FILE             *fplog,
1446                     gmx_int64_t       step,
1447                     t_inputrec       *inputrec,
1448                     t_state          *state,
1449                     matrix            pcoupl_mu,
1450                     matrix            M,
1451                     gmx_bool          bInitStep)
1452 {
1453     gmx_bool   bPCouple = FALSE;
1454     real       dtpc     = 0;
1455     int        i;
1456
1457     /* if using Trotter pressure, we do this in coupling.c, so we leave it false. */
1458     if (inputrec->epc != epcNO && (!(IR_NPT_TROTTER(inputrec) || IR_NPH_TROTTER(inputrec))))
1459     {
1460         /* We should only couple after a step where energies were determined */
1461         bPCouple = (inputrec->nstpcouple == 1 ||
1462                     do_per_step(step+inputrec->nstpcouple-1,
1463                                 inputrec->nstpcouple));
1464     }
1465
1466     clear_mat(pcoupl_mu);
1467     for (i = 0; i < DIM; i++)
1468     {
1469         pcoupl_mu[i][i] = 1.0;
1470     }
1471
1472     clear_mat(M);
1473
1474     if (bPCouple)
1475     {
1476         dtpc = inputrec->nstpcouple*inputrec->delta_t;
1477
1478         switch (inputrec->epc)
1479         {
1480             /* We can always pcoupl, even if we did not sum the energies
1481              * the previous step, since state->pres_prev is only updated
1482              * when the energies have been summed.
1483              */
1484             case (epcNO):
1485                 break;
1486             case (epcBERENDSEN):
1487                 if (!bInitStep)
1488                 {
1489                     berendsen_pcoupl(fplog, step, inputrec, dtpc, state->pres_prev, state->box,
1490                                      pcoupl_mu);
1491                 }
1492                 break;
1493             case (epcPARRINELLORAHMAN):
1494                 parrinellorahman_pcoupl(fplog, step, inputrec, dtpc, state->pres_prev,
1495                                         state->box, state->box_rel, state->boxv,
1496                                         M, pcoupl_mu, bInitStep);
1497                 break;
1498             default:
1499                 break;
1500         }
1501     }
1502 }
1503
1504 static rvec *get_xprime(const t_state *state, gmx_update_t upd)
1505 {
1506     if (state->nalloc > upd->xp_nalloc)
1507     {
1508         upd->xp_nalloc = state->nalloc;
1509         srenew(upd->xp, upd->xp_nalloc);
1510     }
1511
1512     return upd->xp;
1513 }
1514
1515 void update_constraints(FILE             *fplog,
1516                         gmx_int64_t       step,
1517                         real             *dvdlambda, /* the contribution to be added to the bonded interactions */
1518                         t_inputrec       *inputrec,  /* input record and box stuff      */
1519                         gmx_ekindata_t   *ekind,
1520                         t_mdatoms        *md,
1521                         t_state          *state,
1522                         gmx_bool          bMolPBC,
1523                         t_graph          *graph,
1524                         rvec              force[],   /* forces on home particles */
1525                         t_idef           *idef,
1526                         tensor            vir_part,
1527                         t_commrec        *cr,
1528                         t_nrnb           *nrnb,
1529                         gmx_wallcycle_t   wcycle,
1530                         gmx_update_t      upd,
1531                         gmx_constr_t      constr,
1532                         gmx_bool          bFirstHalf,
1533                         gmx_bool          bCalcVir,
1534                         real              vetanew)
1535 {
1536     gmx_bool             bExtended, bLastStep, bLog = FALSE, bEner = FALSE, bDoConstr = FALSE;
1537     double               dt;
1538     real                 dt_1;
1539     int                  start, homenr, nrend, i, n, m, g, d;
1540     tensor               vir_con;
1541     rvec                *vbuf, *xprime = NULL;
1542     int                  nth, th;
1543
1544     if (constr)
1545     {
1546         bDoConstr = TRUE;
1547     }
1548     if (bFirstHalf && !EI_VV(inputrec->eI))
1549     {
1550         bDoConstr = FALSE;
1551     }
1552
1553     /* for now, SD update is here -- though it really seems like it
1554        should be reformulated as a velocity verlet method, since it has two parts */
1555
1556     start  = md->start;
1557     homenr = md->homenr;
1558     nrend  = start+homenr;
1559
1560     dt   = inputrec->delta_t;
1561     dt_1 = 1.0/dt;
1562
1563     /*
1564      *  Steps (7C, 8C)
1565      *  APPLY CONSTRAINTS:
1566      *  BLOCK SHAKE
1567
1568      * When doing PR pressure coupling we have to constrain the
1569      * bonds in each iteration. If we are only using Nose-Hoover tcoupling
1570      * it is enough to do this once though, since the relative velocities
1571      * after this will be normal to the bond vector
1572      */
1573
1574     if (bDoConstr)
1575     {
1576         /* clear out constraints before applying */
1577         clear_mat(vir_part);
1578
1579         xprime = get_xprime(state, upd);
1580
1581         bLastStep = (step == inputrec->init_step+inputrec->nsteps);
1582         bLog      = (do_per_step(step, inputrec->nstlog) || bLastStep || (step < 0));
1583         bEner     = (do_per_step(step, inputrec->nstenergy) || bLastStep);
1584         /* Constrain the coordinates xprime */
1585         wallcycle_start(wcycle, ewcCONSTR);
1586         if (EI_VV(inputrec->eI) && bFirstHalf)
1587         {
1588             constrain(NULL, bLog, bEner, constr, idef,
1589                       inputrec, ekind, cr, step, 1, md,
1590                       state->x, state->v, state->v,
1591                       bMolPBC, state->box,
1592                       state->lambda[efptBONDED], dvdlambda,
1593                       NULL, bCalcVir ? &vir_con : NULL, nrnb, econqVeloc,
1594                       inputrec->epc == epcMTTK, state->veta, vetanew);
1595         }
1596         else
1597         {
1598             constrain(NULL, bLog, bEner, constr, idef,
1599                       inputrec, ekind, cr, step, 1, md,
1600                       state->x, xprime, NULL,
1601                       bMolPBC, state->box,
1602                       state->lambda[efptBONDED], dvdlambda,
1603                       state->v, bCalcVir ? &vir_con : NULL, nrnb, econqCoord,
1604                       inputrec->epc == epcMTTK, state->veta, state->veta);
1605         }
1606         wallcycle_stop(wcycle, ewcCONSTR);
1607
1608         where();
1609
1610         dump_it_all(fplog, "After Shake",
1611                     state->natoms, state->x, xprime, state->v, force);
1612
1613         if (bCalcVir)
1614         {
1615             if (inputrec->eI == eiSD2)
1616             {
1617                 /* A correction factor eph is needed for the SD constraint force */
1618                 /* Here we can, unfortunately, not have proper corrections
1619                  * for different friction constants, so we use the first one.
1620                  */
1621                 for (i = 0; i < DIM; i++)
1622                 {
1623                     for (m = 0; m < DIM; m++)
1624                     {
1625                         vir_part[i][m] += upd->sd->sdc[0].eph*vir_con[i][m];
1626                     }
1627                 }
1628             }
1629             else
1630             {
1631                 m_add(vir_part, vir_con, vir_part);
1632             }
1633             if (debug)
1634             {
1635                 pr_rvecs(debug, 0, "constraint virial", vir_part, DIM);
1636             }
1637         }
1638     }
1639
1640     where();
1641     if ((inputrec->eI == eiSD2) && !(bFirstHalf))
1642     {
1643         xprime = get_xprime(state, upd);
1644
1645         nth = gmx_omp_nthreads_get(emntUpdate);
1646
1647 #pragma omp parallel for num_threads(nth) schedule(static)
1648         for (th = 0; th < nth; th++)
1649         {
1650             int start_th, end_th;
1651
1652             start_th = start + ((nrend-start)* th   )/nth;
1653             end_th   = start + ((nrend-start)*(th+1))/nth;
1654
1655             /* The second part of the SD integration */
1656             do_update_sd2(upd->sd, upd->sd->gaussrand[th],
1657                           FALSE, start_th, end_th,
1658                           inputrec->opts.acc, inputrec->opts.nFreeze,
1659                           md->invmass, md->ptype,
1660                           md->cFREEZE, md->cACC, md->cTC,
1661                           state->x, xprime, state->v, force, state->sd_X,
1662                           inputrec->opts.tau_t,
1663                           FALSE);
1664         }
1665         inc_nrnb(nrnb, eNR_UPDATE, homenr);
1666
1667         if (bDoConstr)
1668         {
1669             /* Constrain the coordinates xprime */
1670             wallcycle_start(wcycle, ewcCONSTR);
1671             constrain(NULL, bLog, bEner, constr, idef,
1672                       inputrec, NULL, cr, step, 1, md,
1673                       state->x, xprime, NULL,
1674                       bMolPBC, state->box,
1675                       state->lambda[efptBONDED], dvdlambda,
1676                       NULL, NULL, nrnb, econqCoord, FALSE, 0, 0);
1677             wallcycle_stop(wcycle, ewcCONSTR);
1678         }
1679     }
1680
1681     /* We must always unshift after updating coordinates; if we did not shake
1682        x was shifted in do_force */
1683
1684     if (!(bFirstHalf)) /* in the first half of vv, no shift. */
1685     {
1686         if (graph && (graph->nnodes > 0))
1687         {
1688             unshift_x(graph, state->box, state->x, upd->xp);
1689             if (TRICLINIC(state->box))
1690             {
1691                 inc_nrnb(nrnb, eNR_SHIFTX, 2*graph->nnodes);
1692             }
1693             else
1694             {
1695                 inc_nrnb(nrnb, eNR_SHIFTX, graph->nnodes);
1696             }
1697         }
1698         else
1699         {
1700 #pragma omp parallel for num_threads(gmx_omp_nthreads_get(emntUpdate)) schedule(static)
1701             for (i = start; i < nrend; i++)
1702             {
1703                 copy_rvec(upd->xp[i], state->x[i]);
1704             }
1705         }
1706
1707         dump_it_all(fplog, "After unshift",
1708                     state->natoms, state->x, upd->xp, state->v, force);
1709     }
1710 /* ############# END the update of velocities and positions ######### */
1711 }
1712
1713 void update_box(FILE             *fplog,
1714                 gmx_int64_t       step,
1715                 t_inputrec       *inputrec,  /* input record and box stuff      */
1716                 t_mdatoms        *md,
1717                 t_state          *state,
1718                 rvec              force[],   /* forces on home particles */
1719                 matrix           *scale_tot,
1720                 matrix            pcoupl_mu,
1721                 t_nrnb           *nrnb,
1722                 gmx_update_t      upd)
1723 {
1724     gmx_bool             bExtended, bLastStep, bLog = FALSE, bEner = FALSE;
1725     double               dt;
1726     real                 dt_1;
1727     int                  start, homenr, nrend, i, n, m, g;
1728     tensor               vir_con;
1729
1730     start  = md->start;
1731     homenr = md->homenr;
1732     nrend  = start+homenr;
1733
1734     bExtended =
1735         (inputrec->etc == etcNOSEHOOVER) ||
1736         (inputrec->epc == epcPARRINELLORAHMAN) ||
1737         (inputrec->epc == epcMTTK);
1738
1739     dt = inputrec->delta_t;
1740
1741     where();
1742
1743     /* now update boxes */
1744     switch (inputrec->epc)
1745     {
1746         case (epcNO):
1747             break;
1748         case (epcBERENDSEN):
1749             berendsen_pscale(inputrec, pcoupl_mu, state->box, state->box_rel,
1750                              start, homenr, state->x, md->cFREEZE, nrnb);
1751             break;
1752         case (epcPARRINELLORAHMAN):
1753             /* The box velocities were updated in do_pr_pcoupl in the update
1754              * iteration, but we dont change the box vectors until we get here
1755              * since we need to be able to shift/unshift above.
1756              */
1757             for (i = 0; i < DIM; i++)
1758             {
1759                 for (m = 0; m <= i; m++)
1760                 {
1761                     state->box[i][m] += dt*state->boxv[i][m];
1762                 }
1763             }
1764             preserve_box_shape(inputrec, state->box_rel, state->box);
1765
1766             /* Scale the coordinates */
1767             for (n = start; (n < start+homenr); n++)
1768             {
1769                 tmvmul_ur0(pcoupl_mu, state->x[n], state->x[n]);
1770             }
1771             break;
1772         case (epcMTTK):
1773             switch (inputrec->epct)
1774             {
1775                 case (epctISOTROPIC):
1776                     /* DIM * eta = ln V.  so DIM*eta_new = DIM*eta_old + DIM*dt*veta =>
1777                        ln V_new = ln V_old + 3*dt*veta => V_new = V_old*exp(3*dt*veta) =>
1778                        Side length scales as exp(veta*dt) */
1779
1780                     msmul(state->box, exp(state->veta*dt), state->box);
1781
1782                     /* Relate veta to boxv.  veta = d(eta)/dT = (1/DIM)*1/V dV/dT.
1783                        o               If we assume isotropic scaling, and box length scaling
1784                        factor L, then V = L^DIM (det(M)).  So dV/dt = DIM
1785                        L^(DIM-1) dL/dt det(M), and veta = (1/L) dL/dt.  The
1786                        determinant of B is L^DIM det(M), and the determinant
1787                        of dB/dt is (dL/dT)^DIM det (M).  veta will be
1788                        (det(dB/dT)/det(B))^(1/3).  Then since M =
1789                        B_new*(vol_new)^(1/3), dB/dT_new = (veta_new)*B(new). */
1790
1791                     msmul(state->box, state->veta, state->boxv);
1792                     break;
1793                 default:
1794                     break;
1795             }
1796             break;
1797         default:
1798             break;
1799     }
1800
1801     if ((!(IR_NPT_TROTTER(inputrec) || IR_NPH_TROTTER(inputrec))) && scale_tot)
1802     {
1803         /* The transposes of the scaling matrices are stored,
1804          * therefore we need to reverse the order in the multiplication.
1805          */
1806         mmul_ur0(*scale_tot, pcoupl_mu, *scale_tot);
1807     }
1808
1809     if (DEFORM(*inputrec))
1810     {
1811         deform(upd, start, homenr, state->x, state->box, scale_tot, inputrec, step);
1812     }
1813     where();
1814     dump_it_all(fplog, "After update",
1815                 state->natoms, state->x, upd->xp, state->v, force);
1816 }
1817
1818 void update_coords(FILE             *fplog,
1819                    gmx_int64_t       step,
1820                    t_inputrec       *inputrec,  /* input record and box stuff   */
1821                    t_mdatoms        *md,
1822                    t_state          *state,
1823                    gmx_bool          bMolPBC,
1824                    rvec             *f,    /* forces on home particles */
1825                    gmx_bool          bDoLR,
1826                    rvec             *f_lr,
1827                    t_fcdata         *fcd,
1828                    gmx_ekindata_t   *ekind,
1829                    matrix            M,
1830                    gmx_update_t      upd,
1831                    gmx_bool          bInitStep,
1832                    int               UpdatePart,
1833                    t_commrec        *cr, /* these shouldn't be here -- need to think about it */
1834                    t_nrnb           *nrnb,
1835                    gmx_constr_t      constr,
1836                    t_idef           *idef)
1837 {
1838     gmx_bool          bNH, bPR, bLastStep, bLog = FALSE, bEner = FALSE;
1839     double            dt, alpha;
1840     real             *imass, *imassin;
1841     rvec             *force;
1842     real              dt_1;
1843     int               start, homenr, nrend, i, j, d, n, m, g;
1844     int               blen0, blen1, iatom, jatom, nshake, nsettle, nconstr, nexpand;
1845     int              *icom = NULL;
1846     tensor            vir_con;
1847     rvec             *vcom, *xcom, *vall, *xall, *xin, *vin, *forcein, *fall, *xpall, *xprimein, *xprime;
1848     int               nth, th;
1849
1850     /* Running the velocity half does nothing except for velocity verlet */
1851     if ((UpdatePart == etrtVELOCITY1 || UpdatePart == etrtVELOCITY2) &&
1852         !EI_VV(inputrec->eI))
1853     {
1854         gmx_incons("update_coords called for velocity without VV integrator");
1855     }
1856
1857     start  = md->start;
1858     homenr = md->homenr;
1859     nrend  = start+homenr;
1860
1861     xprime = get_xprime(state, upd);
1862
1863     dt   = inputrec->delta_t;
1864     dt_1 = 1.0/dt;
1865
1866     /* We need to update the NMR restraint history when time averaging is used */
1867     if (state->flags & (1<<estDISRE_RM3TAV))
1868     {
1869         update_disres_history(fcd, &state->hist);
1870     }
1871     if (state->flags & (1<<estORIRE_DTAV))
1872     {
1873         update_orires_history(fcd, &state->hist);
1874     }
1875
1876
1877     bNH = inputrec->etc == etcNOSEHOOVER;
1878     bPR = ((inputrec->epc == epcPARRINELLORAHMAN) || (inputrec->epc == epcMTTK));
1879
1880     if (bDoLR && inputrec->nstcalclr > 1 && !EI_VV(inputrec->eI))  /* get this working with VV? */
1881     {
1882         /* Store the total force + nstcalclr-1 times the LR force
1883          * in forces_lr, so it can be used in a normal update algorithm
1884          * to produce twin time stepping.
1885          */
1886         /* is this correct in the new construction? MRS */
1887         combine_forces(inputrec->nstcalclr, constr, inputrec, md, idef, cr,
1888                        step, state, bMolPBC,
1889                        start, nrend, f, f_lr, nrnb);
1890         force = f_lr;
1891     }
1892     else
1893     {
1894         force = f;
1895     }
1896
1897     /* ############# START The update of velocities and positions ######### */
1898     where();
1899     dump_it_all(fplog, "Before update",
1900                 state->natoms, state->x, xprime, state->v, force);
1901
1902     if (inputrec->eI == eiSD2)
1903     {
1904         check_sd2_work_data_allocation(upd->sd, nrend);
1905
1906         do_update_sd2_Tconsts(upd->sd,
1907                               inputrec->opts.ngtc,
1908                               inputrec->opts.tau_t,
1909                               inputrec->opts.ref_t);
1910     }
1911     if (inputrec->eI == eiBD)
1912     {
1913         do_update_bd_Tconsts(dt, inputrec->bd_fric,
1914                              inputrec->opts.ngtc, inputrec->opts.ref_t,
1915                              upd->sd->bd_rf);
1916     }
1917
1918     nth = gmx_omp_nthreads_get(emntUpdate);
1919
1920 #pragma omp parallel for num_threads(nth) schedule(static) private(alpha)
1921     for (th = 0; th < nth; th++)
1922     {
1923         int start_th, end_th;
1924
1925         start_th = start + ((nrend-start)* th   )/nth;
1926         end_th   = start + ((nrend-start)*(th+1))/nth;
1927
1928         switch (inputrec->eI)
1929         {
1930             case (eiMD):
1931                 if (ekind->cosacc.cos_accel == 0)
1932                 {
1933                     do_update_md(start_th, end_th, dt,
1934                                  ekind->tcstat, state->nosehoover_vxi,
1935                                  ekind->bNEMD, ekind->grpstat, inputrec->opts.acc,
1936                                  inputrec->opts.nFreeze,
1937                                  md->invmass, md->ptype,
1938                                  md->cFREEZE, md->cACC, md->cTC,
1939                                  state->x, xprime, state->v, force, M,
1940                                  bNH, bPR);
1941                 }
1942                 else
1943                 {
1944                     do_update_visc(start_th, end_th, dt,
1945                                    ekind->tcstat, state->nosehoover_vxi,
1946                                    md->invmass, md->ptype,
1947                                    md->cTC, state->x, xprime, state->v, force, M,
1948                                    state->box,
1949                                    ekind->cosacc.cos_accel,
1950                                    ekind->cosacc.vcos,
1951                                    bNH, bPR);
1952                 }
1953                 break;
1954             case (eiSD1):
1955                 do_update_sd1(upd->sd, upd->sd->gaussrand[th],
1956                               start_th, end_th, dt,
1957                               inputrec->opts.acc, inputrec->opts.nFreeze,
1958                               md->invmass, md->ptype,
1959                               md->cFREEZE, md->cACC, md->cTC,
1960                               state->x, xprime, state->v, force,
1961                               inputrec->opts.ngtc, inputrec->opts.tau_t, inputrec->opts.ref_t);
1962                 break;
1963             case (eiSD2):
1964                 /* The SD update is done in 2 parts, because an extra constraint step
1965                  * is needed
1966                  */
1967                 do_update_sd2(upd->sd, upd->sd->gaussrand[th],
1968                               bInitStep, start_th, end_th,
1969                               inputrec->opts.acc, inputrec->opts.nFreeze,
1970                               md->invmass, md->ptype,
1971                               md->cFREEZE, md->cACC, md->cTC,
1972                               state->x, xprime, state->v, force, state->sd_X,
1973                               inputrec->opts.tau_t,
1974                               TRUE);
1975                 break;
1976             case (eiBD):
1977                 do_update_bd(start_th, end_th, dt,
1978                              inputrec->opts.nFreeze, md->invmass, md->ptype,
1979                              md->cFREEZE, md->cTC,
1980                              state->x, xprime, state->v, force,
1981                              inputrec->bd_fric,
1982                              upd->sd->bd_rf, upd->sd->gaussrand[th]);
1983                 break;
1984             case (eiVV):
1985             case (eiVVAK):
1986                 alpha = 1.0 + DIM/((double)inputrec->opts.nrdf[0]); /* assuming barostat coupled to group 0. */
1987                 switch (UpdatePart)
1988                 {
1989                     case etrtVELOCITY1:
1990                     case etrtVELOCITY2:
1991                         do_update_vv_vel(start_th, end_th, dt,
1992                                          inputrec->opts.acc, inputrec->opts.nFreeze,
1993                                          md->invmass, md->ptype,
1994                                          md->cFREEZE, md->cACC,
1995                                          state->v, force,
1996                                          (bNH || bPR), state->veta, alpha);
1997                         break;
1998                     case etrtPOSITION:
1999                         do_update_vv_pos(start_th, end_th, dt,
2000                                          inputrec->opts.nFreeze,
2001                                          md->ptype, md->cFREEZE,
2002                                          state->x, xprime, state->v,
2003                                          (bNH || bPR), state->veta);
2004                         break;
2005                 }
2006                 break;
2007             default:
2008                 gmx_fatal(FARGS, "Don't know how to update coordinates");
2009                 break;
2010         }
2011     }
2012
2013 }
2014
2015
2016 void correct_ekin(FILE *log, int start, int end, rvec v[], rvec vcm, real mass[],
2017                   real tmass, tensor ekin)
2018 {
2019     /*
2020      * This is a debugging routine. It should not be called for production code
2021      *
2022      * The kinetic energy should calculated according to:
2023      *   Ekin = 1/2 m (v-vcm)^2
2024      * However the correction is not always applied, since vcm may not be
2025      * known in time and we compute
2026      *   Ekin' = 1/2 m v^2 instead
2027      * This can be corrected afterwards by computing
2028      *   Ekin = Ekin' + 1/2 m ( -2 v vcm + vcm^2)
2029      * or in hsorthand:
2030      *   Ekin = Ekin' - m v vcm + 1/2 m vcm^2
2031      */
2032     int    i, j, k;
2033     real   m, tm;
2034     rvec   hvcm, mv;
2035     tensor dekin;
2036
2037     /* Local particles */
2038     clear_rvec(mv);
2039
2040     /* Processor dependent part. */
2041     tm = 0;
2042     for (i = start; (i < end); i++)
2043     {
2044         m      = mass[i];
2045         tm    += m;
2046         for (j = 0; (j < DIM); j++)
2047         {
2048             mv[j] += m*v[i][j];
2049         }
2050     }
2051     /* Shortcut */
2052     svmul(1/tmass, vcm, vcm);
2053     svmul(0.5, vcm, hvcm);
2054     clear_mat(dekin);
2055     for (j = 0; (j < DIM); j++)
2056     {
2057         for (k = 0; (k < DIM); k++)
2058         {
2059             dekin[j][k] += vcm[k]*(tm*hvcm[j]-mv[j]);
2060         }
2061     }
2062     pr_rvecs(log, 0, "dekin", dekin, DIM);
2063     pr_rvecs(log, 0, " ekin", ekin, DIM);
2064     fprintf(log, "dekin = %g, ekin = %g  vcm = (%8.4f %8.4f %8.4f)\n",
2065             trace(dekin), trace(ekin), vcm[XX], vcm[YY], vcm[ZZ]);
2066     fprintf(log, "mv = (%8.4f %8.4f %8.4f)\n",
2067             mv[XX], mv[YY], mv[ZZ]);
2068 }
2069
2070 extern gmx_bool update_randomize_velocities(t_inputrec *ir, gmx_int64_t step, t_mdatoms *md, t_state *state, gmx_update_t upd, t_idef *idef, gmx_constr_t constr)
2071 {
2072
2073     int  i;
2074     real rate = (ir->delta_t)/ir->opts.tau_t[0];
2075     /* proceed with andersen if 1) it's fixed probability per
2076        particle andersen or 2) it's massive andersen and it's tau_t/dt */
2077     if ((ir->etc == etcANDERSEN) || do_per_step(step, (int)(1.0/rate)))
2078     {
2079         srenew(upd->randatom, state->nalloc);
2080         srenew(upd->randatom_list, state->nalloc);
2081         if (upd->randatom_list_init == FALSE)
2082         {
2083             for (i = 0; i < state->nalloc; i++)
2084             {
2085                 upd->randatom[i]      = FALSE;
2086                 upd->randatom_list[i] = 0;
2087             }
2088             upd->randatom_list_init = TRUE;
2089         }
2090         andersen_tcoupl(ir, md, state, upd->sd->gaussrand[0], rate,
2091                         (ir->etc == etcANDERSEN) ? idef : NULL,
2092                         constr ? get_nblocks(constr) : 0,
2093                         constr ? get_sblock(constr) : NULL,
2094                         upd->randatom, upd->randatom_list,
2095                         upd->sd->randomize_group, upd->sd->boltzfac);
2096         return TRUE;
2097     }
2098     return FALSE;
2099 }