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