2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5 * Copyright (c) 2001-2004, The GROMACS development team,
6 * check out http://www.gromacs.org for more information.
7 * Copyright (c) 2012,2013, by the GROMACS development team, led by
8 * David van der Spoel, Berk Hess, Erik Lindahl, and including many
9 * others, as listed in the AUTHORS file in the top-level source
10 * directory and at http://www.gromacs.org.
12 * GROMACS is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 2.1
15 * of the License, or (at your option) any later version.
17 * GROMACS is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with GROMACS; if not, see
24 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
25 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 * If you want to redistribute modifications to GROMACS, please
28 * consider that scientific software is very special. Version
29 * control is crucial - bugs must be traceable. We will be happy to
30 * consider code for inclusion in the official distribution, but
31 * derived work must not be called official GROMACS. Details are found
32 * in the README & COPYING files - if they are missing, get the
33 * official version at http://www.gromacs.org.
35 * To help us fund GROMACS development, we humbly ask that you cite
36 * the research papers on the package. Check out http://www.gromacs.org.
46 #include "types/commrec.h"
57 #include "gmx_random.h"
71 #include "gmx_wallcycle.h"
72 #include "gmx_omp_nthreads.h"
75 /*For debugging, start at v(-dt/2) for velolcity verlet -- uncomment next line */
76 /*#define STARTFROMDT2*/
96 /* The random state for ngaussrand threads.
97 * Normal thermostats need just 1 random number generator,
98 * but SD and BD with OpenMP parallelization need 1 for each thread.
101 gmx_rng_t
*gaussrand
;
106 gmx_sd_sigma_t
*sdsig
;
109 /* andersen temperature control stuff */
110 gmx_bool
*randomize_group
;
114 typedef struct gmx_update
117 /* xprime for constraint algorithms */
121 /* variable size arrays for andersen */
124 gmx_bool randatom_list_init
;
126 /* Variables for the deform algorithm */
127 gmx_large_int_t deformref_step
;
128 matrix deformref_box
;
132 static void do_update_md(int start
, int nrend
, double dt
,
133 t_grp_tcstat
*tcstat
,
135 gmx_bool bNEMD
, t_grp_acc
*gstat
, rvec accel
[],
138 unsigned short ptype
[], unsigned short cFREEZE
[],
139 unsigned short cACC
[], unsigned short cTC
[],
140 rvec x
[], rvec xprime
[], rvec v
[],
142 gmx_bool bNH
, gmx_bool bPR
)
145 int gf
= 0, ga
= 0, gt
= 0;
147 real vn
, vv
, va
, vb
, vnrel
;
153 /* Update with coupling to extended ensembles, used for
154 * Nose-Hoover and Parrinello-Rahman coupling
155 * Nose-Hoover uses the reversible leap-frog integrator from
156 * Holian et al. Phys Rev E 52(3) : 2338, 1995
158 for (n
= start
; n
< nrend
; n
++)
173 lg
= tcstat
[gt
].lambda
;
178 rvec_sub(v
[n
], gstat
[ga
].u
, vrel
);
180 for (d
= 0; d
< DIM
; d
++)
182 if ((ptype
[n
] != eptVSite
) && (ptype
[n
] != eptShell
) && !nFreeze
[gf
][d
])
184 vnrel
= (lg
*vrel
[d
] + dt
*(imass
*f
[n
][d
] - 0.5*vxi
*vrel
[d
]
185 - iprod(M
[d
], vrel
)))/(1 + 0.5*vxi
*dt
);
186 /* do not scale the mean velocities u */
187 vn
= gstat
[ga
].u
[d
] + accel
[ga
][d
]*dt
+ vnrel
;
189 xprime
[n
][d
] = x
[n
][d
]+vn
*dt
;
194 xprime
[n
][d
] = x
[n
][d
];
199 else if (cFREEZE
!= NULL
||
200 nFreeze
[0][XX
] || nFreeze
[0][YY
] || nFreeze
[0][ZZ
] ||
203 /* Update with Berendsen/v-rescale coupling and freeze or NEMD */
204 for (n
= start
; n
< nrend
; n
++)
206 w_dt
= invmass
[n
]*dt
;
219 lg
= tcstat
[gt
].lambda
;
221 for (d
= 0; d
< DIM
; d
++)
224 if ((ptype
[n
] != eptVSite
) && (ptype
[n
] != eptShell
) && !nFreeze
[gf
][d
])
226 vv
= lg
*vn
+ f
[n
][d
]*w_dt
;
228 /* do not scale the mean velocities u */
230 va
= vv
+ accel
[ga
][d
]*dt
;
231 vb
= va
+ (1.0-lg
)*u
;
233 xprime
[n
][d
] = x
[n
][d
]+vb
*dt
;
238 xprime
[n
][d
] = x
[n
][d
];
245 /* Plain update with Berendsen/v-rescale coupling */
246 for (n
= start
; n
< nrend
; n
++)
248 if ((ptype
[n
] != eptVSite
) && (ptype
[n
] != eptShell
))
250 w_dt
= invmass
[n
]*dt
;
255 lg
= tcstat
[gt
].lambda
;
257 for (d
= 0; d
< DIM
; d
++)
259 vn
= lg
*v
[n
][d
] + f
[n
][d
]*w_dt
;
261 xprime
[n
][d
] = x
[n
][d
] + vn
*dt
;
266 for (d
= 0; d
< DIM
; d
++)
269 xprime
[n
][d
] = x
[n
][d
];
276 static void do_update_vv_vel(int start
, int nrend
, double dt
,
277 t_grp_tcstat
*tcstat
, t_grp_acc
*gstat
,
278 rvec accel
[], ivec nFreeze
[], real invmass
[],
279 unsigned short ptype
[], unsigned short cFREEZE
[],
280 unsigned short cACC
[], rvec v
[], rvec f
[],
281 gmx_bool bExtended
, real veta
, real alpha
)
286 real u
, vn
, vv
, va
, vb
, vnrel
;
292 g
= 0.25*dt
*veta
*alpha
;
294 mv2
= series_sinhx(g
);
301 for (n
= start
; n
< nrend
; n
++)
303 w_dt
= invmass
[n
]*dt
;
313 for (d
= 0; d
< DIM
; d
++)
315 if ((ptype
[n
] != eptVSite
) && (ptype
[n
] != eptShell
) && !nFreeze
[gf
][d
])
317 v
[n
][d
] = mv1
*(mv1
*v
[n
][d
] + 0.5*(w_dt
*mv2
*f
[n
][d
]))+0.5*accel
[ga
][d
]*dt
;
325 } /* do_update_vv_vel */
327 static void do_update_vv_pos(int start
, int nrend
, double dt
,
328 t_grp_tcstat
*tcstat
, t_grp_acc
*gstat
,
329 rvec accel
[], ivec nFreeze
[], real invmass
[],
330 unsigned short ptype
[], unsigned short cFREEZE
[],
331 rvec x
[], rvec xprime
[], rvec v
[],
332 rvec f
[], gmx_bool bExtended
, real veta
, real alpha
)
339 /* Would it make more sense if Parrinello-Rahman was put here? */
344 mr2
= series_sinhx(g
);
352 for (n
= start
; n
< nrend
; n
++)
360 for (d
= 0; d
< DIM
; d
++)
362 if ((ptype
[n
] != eptVSite
) && (ptype
[n
] != eptShell
) && !nFreeze
[gf
][d
])
364 xprime
[n
][d
] = mr1
*(mr1
*x
[n
][d
]+mr2
*dt
*v
[n
][d
]);
368 xprime
[n
][d
] = x
[n
][d
];
372 } /* do_update_vv_pos */
374 static void do_update_visc(int start
, int nrend
, double dt
,
375 t_grp_tcstat
*tcstat
,
378 unsigned short ptype
[], unsigned short cTC
[],
379 rvec x
[], rvec xprime
[], rvec v
[],
380 rvec f
[], matrix M
, matrix box
, real
381 cos_accel
, real vcos
,
382 gmx_bool bNH
, gmx_bool bPR
)
387 real lg
, vxi
= 0, vv
;
392 fac
= 2*M_PI
/(box
[ZZ
][ZZ
]);
396 /* Update with coupling to extended ensembles, used for
397 * Nose-Hoover and Parrinello-Rahman coupling
399 for (n
= start
; n
< nrend
; n
++)
406 lg
= tcstat
[gt
].lambda
;
407 cosz
= cos(fac
*x
[n
][ZZ
]);
409 copy_rvec(v
[n
], vrel
);
417 for (d
= 0; d
< DIM
; d
++)
421 if ((ptype
[n
] != eptVSite
) && (ptype
[n
] != eptShell
))
423 vn
= (lg
*vrel
[d
] + dt
*(imass
*f
[n
][d
] - 0.5*vxi
*vrel
[d
]
424 - iprod(M
[d
], vrel
)))/(1 + 0.5*vxi
*dt
);
427 vn
+= vc
+ dt
*cosz
*cos_accel
;
430 xprime
[n
][d
] = x
[n
][d
]+vn
*dt
;
434 xprime
[n
][d
] = x
[n
][d
];
441 /* Classic version of update, used with berendsen coupling */
442 for (n
= start
; n
< nrend
; n
++)
444 w_dt
= invmass
[n
]*dt
;
449 lg
= tcstat
[gt
].lambda
;
450 cosz
= cos(fac
*x
[n
][ZZ
]);
452 for (d
= 0; d
< DIM
; d
++)
456 if ((ptype
[n
] != eptVSite
) && (ptype
[n
] != eptShell
))
461 /* Do not scale the cosine velocity profile */
462 vv
= vc
+ lg
*(vn
- vc
+ f
[n
][d
]*w_dt
);
463 /* Add the cosine accelaration profile */
464 vv
+= dt
*cosz
*cos_accel
;
468 vv
= lg
*(vn
+ f
[n
][d
]*w_dt
);
471 xprime
[n
][d
] = x
[n
][d
]+vv
*dt
;
476 xprime
[n
][d
] = x
[n
][d
];
483 /* Allocates and initializes sd->gaussrand[i] for i=1, i<sd->ngaussrand,
484 * Using seeds generated from sd->gaussrand[0].
486 static void init_multiple_gaussrand(gmx_stochd_t
*sd
)
491 ngr
= sd
->ngaussrand
;
494 for (i
= 1; i
< ngr
; i
++)
496 seed
[i
] = gmx_rng_uniform_uint32(sd
->gaussrand
[0]);
499 #pragma omp parallel num_threads(ngr)
503 th
= gmx_omp_get_thread_num();
506 /* Initialize on each thread to have thread-local memory alloced */
507 sd
->gaussrand
[th
] = gmx_rng_init(seed
[th
]);
514 static gmx_stochd_t
*init_stochd(FILE *fplog
, t_inputrec
*ir
, int nthreads
)
523 /* Initiate random number generator for langevin type dynamics,
524 * for BD, SD or velocity rescaling temperature coupling.
526 if (ir
->eI
== eiBD
|| EI_SD(ir
->eI
))
528 sd
->ngaussrand
= nthreads
;
534 snew(sd
->gaussrand
, sd
->ngaussrand
);
536 /* Initialize the first random generator */
537 sd
->gaussrand
[0] = gmx_rng_init(ir
->ld_seed
);
539 if (sd
->ngaussrand
> 1)
541 /* Initialize the rest of the random number generators,
542 * using the first one to generate seeds.
544 init_multiple_gaussrand(sd
);
547 ngtc
= ir
->opts
.ngtc
;
551 snew(sd
->bd_rf
, ngtc
);
553 else if (EI_SD(ir
->eI
))
556 snew(sd
->sdsig
, ngtc
);
559 for (n
= 0; n
< ngtc
; n
++)
561 if (ir
->opts
.tau_t
[n
] > 0)
563 sdc
[n
].gdt
= ir
->delta_t
/ir
->opts
.tau_t
[n
];
564 sdc
[n
].eph
= exp(sdc
[n
].gdt
/2);
565 sdc
[n
].emh
= exp(-sdc
[n
].gdt
/2);
566 sdc
[n
].em
= exp(-sdc
[n
].gdt
);
570 /* No friction and noise on this group */
576 if (sdc
[n
].gdt
>= 0.05)
578 sdc
[n
].b
= sdc
[n
].gdt
*(sdc
[n
].eph
*sdc
[n
].eph
- 1)
579 - 4*(sdc
[n
].eph
- 1)*(sdc
[n
].eph
- 1);
580 sdc
[n
].c
= sdc
[n
].gdt
- 3 + 4*sdc
[n
].emh
- sdc
[n
].em
;
581 sdc
[n
].d
= 2 - sdc
[n
].eph
- sdc
[n
].emh
;
586 /* Seventh order expansions for small y */
587 sdc
[n
].b
= y
*y
*y
*y
*(1/3.0+y
*(1/3.0+y
*(17/90.0+y
*7/9.0)));
588 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))));
589 sdc
[n
].d
= y
*y
*(-1+y
*y
*(-1/12.0-y
*y
/360.0));
593 fprintf(debug
, "SD const tc-grp %d: b %g c %g d %g\n",
594 n
, sdc
[n
].b
, sdc
[n
].c
, sdc
[n
].d
);
598 else if (ETC_ANDERSEN(ir
->etc
))
607 snew(sd
->randomize_group
, ngtc
);
608 snew(sd
->boltzfac
, ngtc
);
610 /* for now, assume that all groups, if randomized, are randomized at the same rate, i.e. tau_t is the same. */
611 /* since constraint groups don't necessarily match up with temperature groups! This is checked in readir.c */
613 for (n
= 0; n
< ngtc
; n
++)
615 reft
= max(0.0, opts
->ref_t
[n
]);
616 if ((opts
->tau_t
[n
] > 0) && (reft
> 0)) /* tau_t or ref_t = 0 means that no randomization is done */
618 sd
->randomize_group
[n
] = TRUE
;
619 sd
->boltzfac
[n
] = BOLTZ
*opts
->ref_t
[n
];
623 sd
->randomize_group
[n
] = FALSE
;
630 void get_stochd_state(gmx_update_t upd
, t_state
*state
)
632 /* Note that we only get the state of the first random generator,
633 * even if there are multiple. This avoids repetition.
635 gmx_rng_get_state(upd
->sd
->gaussrand
[0], state
->ld_rng
, state
->ld_rngi
);
638 void set_stochd_state(gmx_update_t upd
, t_state
*state
)
645 gmx_rng_set_state(sd
->gaussrand
[0], state
->ld_rng
, state
->ld_rngi
[0]);
647 if (sd
->ngaussrand
> 1)
649 /* We only end up here with SD or BD with OpenMP.
650 * Destroy and reinitialize the rest of the random number generators,
651 * using seeds generated from the first one.
652 * Although this doesn't recover the previous state,
653 * it at least avoids repetition, which is most important.
654 * Exaclty restoring states with all MPI+OpenMP setups is difficult
655 * and as the integrator is random to start with, doesn't gain us much.
657 for (i
= 1; i
< sd
->ngaussrand
; i
++)
659 gmx_rng_destroy(sd
->gaussrand
[i
]);
662 init_multiple_gaussrand(sd
);
666 gmx_update_t
init_update(FILE *fplog
, t_inputrec
*ir
)
672 if (ir
->eI
== eiBD
|| EI_SD(ir
->eI
) || ir
->etc
== etcVRESCALE
|| ETC_ANDERSEN(ir
->etc
))
674 upd
->sd
= init_stochd(fplog
, ir
, gmx_omp_nthreads_get(emntUpdate
));
679 upd
->randatom
= NULL
;
680 upd
->randatom_list
= NULL
;
681 upd
->randatom_list_init
= FALSE
; /* we have not yet cleared the data structure at this point */
686 static void do_update_sd1(gmx_stochd_t
*sd
,
688 int start
, int nrend
, double dt
,
689 rvec accel
[], ivec nFreeze
[],
690 real invmass
[], unsigned short ptype
[],
691 unsigned short cFREEZE
[], unsigned short cACC
[],
692 unsigned short cTC
[],
693 rvec x
[], rvec xprime
[], rvec v
[], rvec f
[],
695 int ngtc
, real tau_t
[], real ref_t
[])
700 int gf
= 0, ga
= 0, gt
= 0;
707 for (n
= 0; n
< ngtc
; n
++)
710 /* The mass is encounted for later, since this differs per atom */
711 sig
[n
].V
= sqrt(kT
*(1 - sdc
[n
].em
*sdc
[n
].em
));
714 for (n
= start
; n
< nrend
; n
++)
716 ism
= sqrt(invmass
[n
]);
730 for (d
= 0; d
< DIM
; d
++)
732 if ((ptype
[n
] != eptVSite
) && (ptype
[n
] != eptShell
) && !nFreeze
[gf
][d
])
734 sd_V
= ism
*sig
[gt
].V
*gmx_rng_gaussian_table(gaussrand
);
736 v
[n
][d
] = v
[n
][d
]*sdc
[gt
].em
737 + (invmass
[n
]*f
[n
][d
] + accel
[ga
][d
])*tau_t
[gt
]*(1 - sdc
[gt
].em
)
740 xprime
[n
][d
] = x
[n
][d
] + v
[n
][d
]*dt
;
745 xprime
[n
][d
] = x
[n
][d
];
751 static void check_sd2_work_data_allocation(gmx_stochd_t
*sd
, int nrend
)
753 if (nrend
> sd
->sd_V_nalloc
)
755 sd
->sd_V_nalloc
= over_alloc_dd(nrend
);
756 srenew(sd
->sd_V
, sd
->sd_V_nalloc
);
760 static void do_update_sd2(gmx_stochd_t
*sd
,
763 int start
, int nrend
,
764 rvec accel
[], ivec nFreeze
[],
765 real invmass
[], unsigned short ptype
[],
766 unsigned short cFREEZE
[], unsigned short cACC
[],
767 unsigned short cTC
[],
768 rvec x
[], rvec xprime
[], rvec v
[], rvec f
[],
770 int ngtc
, real tau_t
[], real ref_t
[],
775 /* The random part of the velocity update, generated in the first
776 * half of the update, needs to be remembered for the second half.
780 int gf
= 0, ga
= 0, gt
= 0;
781 real vn
= 0, Vmh
, Xmh
;
791 for (n
= 0; n
< ngtc
; n
++)
794 /* The mass is encounted for later, since this differs per atom */
795 sig
[n
].V
= sqrt(kT
*(1-sdc
[n
].em
));
796 sig
[n
].X
= sqrt(kT
*sqr(tau_t
[n
])*sdc
[n
].c
);
797 sig
[n
].Yv
= sqrt(kT
*sdc
[n
].b
/sdc
[n
].c
);
798 sig
[n
].Yx
= sqrt(kT
*sqr(tau_t
[n
])*sdc
[n
].b
/(1-sdc
[n
].em
));
802 for (n
= start
; n
< nrend
; n
++)
804 ism
= sqrt(invmass
[n
]);
818 for (d
= 0; d
< DIM
; d
++)
824 if ((ptype
[n
] != eptVSite
) && (ptype
[n
] != eptShell
) && !nFreeze
[gf
][d
])
830 sd_X
[n
][d
] = ism
*sig
[gt
].X
*gmx_rng_gaussian_table(gaussrand
);
832 Vmh
= sd_X
[n
][d
]*sdc
[gt
].d
/(tau_t
[gt
]*sdc
[gt
].c
)
833 + ism
*sig
[gt
].Yv
*gmx_rng_gaussian_table(gaussrand
);
834 sd_V
[n
][d
] = ism
*sig
[gt
].V
*gmx_rng_gaussian_table(gaussrand
);
836 v
[n
][d
] = vn
*sdc
[gt
].em
837 + (invmass
[n
]*f
[n
][d
] + accel
[ga
][d
])*tau_t
[gt
]*(1 - sdc
[gt
].em
)
838 + sd_V
[n
][d
] - sdc
[gt
].em
*Vmh
;
840 xprime
[n
][d
] = x
[n
][d
] + v
[n
][d
]*tau_t
[gt
]*(sdc
[gt
].eph
- sdc
[gt
].emh
);
845 /* Correct the velocities for the constraints.
846 * This operation introduces some inaccuracy,
847 * since the velocity is determined from differences in coordinates.
850 (xprime
[n
][d
] - x
[n
][d
])/(tau_t
[gt
]*(sdc
[gt
].eph
- sdc
[gt
].emh
));
852 Xmh
= sd_V
[n
][d
]*tau_t
[gt
]*sdc
[gt
].d
/(sdc
[gt
].em
-1)
853 + ism
*sig
[gt
].Yx
*gmx_rng_gaussian_table(gaussrand
);
854 sd_X
[n
][d
] = ism
*sig
[gt
].X
*gmx_rng_gaussian_table(gaussrand
);
856 xprime
[n
][d
] += sd_X
[n
][d
] - Xmh
;
865 xprime
[n
][d
] = x
[n
][d
];
872 static void do_update_bd(int start
, int nrend
, double dt
,
874 real invmass
[], unsigned short ptype
[],
875 unsigned short cFREEZE
[], unsigned short cTC
[],
876 rvec x
[], rvec xprime
[], rvec v
[],
877 rvec f
[], real friction_coefficient
,
878 int ngtc
, real tau_t
[], real ref_t
[],
879 real
*rf
, gmx_rng_t gaussrand
)
881 /* note -- these appear to be full step velocities . . . */
887 if (friction_coefficient
!= 0)
889 invfr
= 1.0/friction_coefficient
;
890 for (n
= 0; n
< ngtc
; n
++)
892 rf
[n
] = sqrt(2.0*BOLTZ
*ref_t
[n
]/(friction_coefficient
*dt
));
897 for (n
= 0; n
< ngtc
; n
++)
899 rf
[n
] = sqrt(2.0*BOLTZ
*ref_t
[n
]);
902 for (n
= start
; (n
< nrend
); n
++)
912 for (d
= 0; (d
< DIM
); d
++)
914 if ((ptype
[n
] != eptVSite
) && (ptype
[n
] != eptShell
) && !nFreeze
[gf
][d
])
916 if (friction_coefficient
!= 0)
918 vn
= invfr
*f
[n
][d
] + rf
[gt
]*gmx_rng_gaussian_table(gaussrand
);
922 /* NOTE: invmass = 2/(mass*friction_constant*dt) */
923 vn
= 0.5*invmass
[n
]*f
[n
][d
]*dt
924 + sqrt(0.5*invmass
[n
])*rf
[gt
]*gmx_rng_gaussian_table(gaussrand
);
928 xprime
[n
][d
] = x
[n
][d
]+vn
*dt
;
933 xprime
[n
][d
] = x
[n
][d
];
939 static void dump_it_all(FILE *fp
, const char *title
,
940 int natoms
, rvec x
[], rvec xp
[], rvec v
[], rvec f
[])
945 fprintf(fp
, "%s\n", title
);
946 pr_rvecs(fp
, 0, "x", x
, natoms
);
947 pr_rvecs(fp
, 0, "xp", xp
, natoms
);
948 pr_rvecs(fp
, 0, "v", v
, natoms
);
949 pr_rvecs(fp
, 0, "f", f
, natoms
);
954 static void calc_ke_part_normal(rvec v
[], t_grpopts
*opts
, t_mdatoms
*md
,
955 gmx_ekindata_t
*ekind
, t_nrnb
*nrnb
, gmx_bool bEkinAveVel
,
956 gmx_bool bSaveEkinOld
)
959 t_grp_tcstat
*tcstat
= ekind
->tcstat
;
960 t_grp_acc
*grpstat
= ekind
->grpstat
;
963 /* three main: VV with AveVel, vv with AveEkin, leap with AveEkin. Leap with AveVel is also
964 an option, but not supported now. Additionally, if we are doing iterations.
965 bEkinAveVel: If TRUE, we sum into ekin, if FALSE, into ekinh.
966 bSavEkinOld: If TRUE (in the case of iteration = bIterate is TRUE), we don't copy over the ekinh_old.
967 If FALSE, we overrwrite it.
970 /* group velocities are calculated in update_ekindata and
971 * accumulated in acumulate_groups.
972 * Now the partial global and groups ekin.
974 for (g
= 0; (g
< opts
->ngtc
); g
++)
979 copy_mat(tcstat
[g
].ekinh
, tcstat
[g
].ekinh_old
);
983 clear_mat(tcstat
[g
].ekinf
);
987 clear_mat(tcstat
[g
].ekinh
);
991 tcstat
[g
].ekinscalef_nhc
= 1.0; /* need to clear this -- logic is complicated! */
994 ekind
->dekindl_old
= ekind
->dekindl
;
996 nthread
= gmx_omp_nthreads_get(emntUpdate
);
998 #pragma omp parallel for num_threads(nthread) schedule(static)
999 for (thread
= 0; thread
< nthread
; thread
++)
1001 int start_t
, end_t
, n
;
1009 start_t
= md
->start
+ ((thread
+0)*md
->homenr
)/nthread
;
1010 end_t
= md
->start
+ ((thread
+1)*md
->homenr
)/nthread
;
1012 ekin_sum
= ekind
->ekin_work
[thread
];
1013 dekindl_sum
= ekind
->dekindl_work
[thread
];
1015 for (gt
= 0; gt
< opts
->ngtc
; gt
++)
1017 clear_mat(ekin_sum
[gt
]);
1023 for (n
= start_t
; n
< end_t
; n
++)
1033 hm
= 0.5*md
->massT
[n
];
1035 for (d
= 0; (d
< DIM
); d
++)
1037 v_corrt
[d
] = v
[n
][d
] - grpstat
[ga
].u
[d
];
1039 for (d
= 0; (d
< DIM
); d
++)
1041 for (m
= 0; (m
< DIM
); m
++)
1043 /* if we're computing a full step velocity, v_corrt[d] has v(t). Otherwise, v(t+dt/2) */
1044 ekin_sum
[gt
][m
][d
] += hm
*v_corrt
[m
]*v_corrt
[d
];
1047 if (md
->nMassPerturbed
&& md
->bPerturbed
[n
])
1050 0.5*(md
->massB
[n
] - md
->massA
[n
])*iprod(v_corrt
, v_corrt
);
1056 for (thread
= 0; thread
< nthread
; thread
++)
1058 for (g
= 0; g
< opts
->ngtc
; g
++)
1062 m_add(tcstat
[g
].ekinf
, ekind
->ekin_work
[thread
][g
],
1067 m_add(tcstat
[g
].ekinh
, ekind
->ekin_work
[thread
][g
],
1072 ekind
->dekindl
+= *ekind
->dekindl_work
[thread
];
1075 inc_nrnb(nrnb
, eNR_EKIN
, md
->homenr
);
1078 static void calc_ke_part_visc(matrix box
, rvec x
[], rvec v
[],
1079 t_grpopts
*opts
, t_mdatoms
*md
,
1080 gmx_ekindata_t
*ekind
,
1081 t_nrnb
*nrnb
, gmx_bool bEkinAveVel
, gmx_bool bSaveEkinOld
)
1083 int start
= md
->start
, homenr
= md
->homenr
;
1084 int g
, d
, n
, m
, gt
= 0;
1087 t_grp_tcstat
*tcstat
= ekind
->tcstat
;
1088 t_cos_acc
*cosacc
= &(ekind
->cosacc
);
1093 for (g
= 0; g
< opts
->ngtc
; g
++)
1095 copy_mat(ekind
->tcstat
[g
].ekinh
, ekind
->tcstat
[g
].ekinh_old
);
1096 clear_mat(ekind
->tcstat
[g
].ekinh
);
1098 ekind
->dekindl_old
= ekind
->dekindl
;
1100 fac
= 2*M_PI
/box
[ZZ
][ZZ
];
1103 for (n
= start
; n
< start
+homenr
; n
++)
1109 hm
= 0.5*md
->massT
[n
];
1111 /* Note that the times of x and v differ by half a step */
1112 /* MRS -- would have to be changed for VV */
1113 cosz
= cos(fac
*x
[n
][ZZ
]);
1114 /* Calculate the amplitude of the new velocity profile */
1115 mvcos
+= 2*cosz
*md
->massT
[n
]*v
[n
][XX
];
1117 copy_rvec(v
[n
], v_corrt
);
1118 /* Subtract the profile for the kinetic energy */
1119 v_corrt
[XX
] -= cosz
*cosacc
->vcos
;
1120 for (d
= 0; (d
< DIM
); d
++)
1122 for (m
= 0; (m
< DIM
); m
++)
1124 /* if we're computing a full step velocity, v_corrt[d] has v(t). Otherwise, v(t+dt/2) */
1127 tcstat
[gt
].ekinf
[m
][d
] += hm
*v_corrt
[m
]*v_corrt
[d
];
1131 tcstat
[gt
].ekinh
[m
][d
] += hm
*v_corrt
[m
]*v_corrt
[d
];
1135 if (md
->nPerturbed
&& md
->bPerturbed
[n
])
1137 dekindl
+= 0.5*(md
->massB
[n
] - md
->massA
[n
])*iprod(v_corrt
, v_corrt
);
1140 ekind
->dekindl
= dekindl
;
1141 cosacc
->mvcos
= mvcos
;
1143 inc_nrnb(nrnb
, eNR_EKIN
, homenr
);
1146 void calc_ke_part(t_state
*state
, t_grpopts
*opts
, t_mdatoms
*md
,
1147 gmx_ekindata_t
*ekind
, t_nrnb
*nrnb
, gmx_bool bEkinAveVel
, gmx_bool bSaveEkinOld
)
1149 if (ekind
->cosacc
.cos_accel
== 0)
1151 calc_ke_part_normal(state
->v
, opts
, md
, ekind
, nrnb
, bEkinAveVel
, bSaveEkinOld
);
1155 calc_ke_part_visc(state
->box
, state
->x
, state
->v
, opts
, md
, ekind
, nrnb
, bEkinAveVel
, bSaveEkinOld
);
1159 extern void init_ekinstate(ekinstate_t
*ekinstate
, const t_inputrec
*ir
)
1161 ekinstate
->ekin_n
= ir
->opts
.ngtc
;
1162 snew(ekinstate
->ekinh
, ekinstate
->ekin_n
);
1163 snew(ekinstate
->ekinf
, ekinstate
->ekin_n
);
1164 snew(ekinstate
->ekinh_old
, ekinstate
->ekin_n
);
1165 snew(ekinstate
->ekinscalef_nhc
, ekinstate
->ekin_n
);
1166 snew(ekinstate
->ekinscaleh_nhc
, ekinstate
->ekin_n
);
1167 snew(ekinstate
->vscale_nhc
, ekinstate
->ekin_n
);
1168 ekinstate
->dekindl
= 0;
1169 ekinstate
->mvcos
= 0;
1172 void update_ekinstate(ekinstate_t
*ekinstate
, gmx_ekindata_t
*ekind
)
1176 for (i
= 0; i
< ekinstate
->ekin_n
; i
++)
1178 copy_mat(ekind
->tcstat
[i
].ekinh
, ekinstate
->ekinh
[i
]);
1179 copy_mat(ekind
->tcstat
[i
].ekinf
, ekinstate
->ekinf
[i
]);
1180 copy_mat(ekind
->tcstat
[i
].ekinh_old
, ekinstate
->ekinh_old
[i
]);
1181 ekinstate
->ekinscalef_nhc
[i
] = ekind
->tcstat
[i
].ekinscalef_nhc
;
1182 ekinstate
->ekinscaleh_nhc
[i
] = ekind
->tcstat
[i
].ekinscaleh_nhc
;
1183 ekinstate
->vscale_nhc
[i
] = ekind
->tcstat
[i
].vscale_nhc
;
1186 copy_mat(ekind
->ekin
, ekinstate
->ekin_total
);
1187 ekinstate
->dekindl
= ekind
->dekindl
;
1188 ekinstate
->mvcos
= ekind
->cosacc
.mvcos
;
1192 void restore_ekinstate_from_state(t_commrec
*cr
,
1193 gmx_ekindata_t
*ekind
, ekinstate_t
*ekinstate
)
1199 for (i
= 0; i
< ekinstate
->ekin_n
; i
++)
1201 copy_mat(ekinstate
->ekinh
[i
], ekind
->tcstat
[i
].ekinh
);
1202 copy_mat(ekinstate
->ekinf
[i
], ekind
->tcstat
[i
].ekinf
);
1203 copy_mat(ekinstate
->ekinh_old
[i
], ekind
->tcstat
[i
].ekinh_old
);
1204 ekind
->tcstat
[i
].ekinscalef_nhc
= ekinstate
->ekinscalef_nhc
[i
];
1205 ekind
->tcstat
[i
].ekinscaleh_nhc
= ekinstate
->ekinscaleh_nhc
[i
];
1206 ekind
->tcstat
[i
].vscale_nhc
= ekinstate
->vscale_nhc
[i
];
1209 copy_mat(ekinstate
->ekin_total
, ekind
->ekin
);
1211 ekind
->dekindl
= ekinstate
->dekindl
;
1212 ekind
->cosacc
.mvcos
= ekinstate
->mvcos
;
1213 n
= ekinstate
->ekin_n
;
1218 gmx_bcast(sizeof(n
), &n
, cr
);
1219 for (i
= 0; i
< n
; i
++)
1221 gmx_bcast(DIM
*DIM
*sizeof(ekind
->tcstat
[i
].ekinh
[0][0]),
1222 ekind
->tcstat
[i
].ekinh
[0], cr
);
1223 gmx_bcast(DIM
*DIM
*sizeof(ekind
->tcstat
[i
].ekinf
[0][0]),
1224 ekind
->tcstat
[i
].ekinf
[0], cr
);
1225 gmx_bcast(DIM
*DIM
*sizeof(ekind
->tcstat
[i
].ekinh_old
[0][0]),
1226 ekind
->tcstat
[i
].ekinh_old
[0], cr
);
1228 gmx_bcast(sizeof(ekind
->tcstat
[i
].ekinscalef_nhc
),
1229 &(ekind
->tcstat
[i
].ekinscalef_nhc
), cr
);
1230 gmx_bcast(sizeof(ekind
->tcstat
[i
].ekinscaleh_nhc
),
1231 &(ekind
->tcstat
[i
].ekinscaleh_nhc
), cr
);
1232 gmx_bcast(sizeof(ekind
->tcstat
[i
].vscale_nhc
),
1233 &(ekind
->tcstat
[i
].vscale_nhc
), cr
);
1235 gmx_bcast(DIM
*DIM
*sizeof(ekind
->ekin
[0][0]),
1236 ekind
->ekin
[0], cr
);
1238 gmx_bcast(sizeof(ekind
->dekindl
), &ekind
->dekindl
, cr
);
1239 gmx_bcast(sizeof(ekind
->cosacc
.mvcos
), &ekind
->cosacc
.mvcos
, cr
);
1243 void set_deform_reference_box(gmx_update_t upd
, gmx_large_int_t step
, matrix box
)
1245 upd
->deformref_step
= step
;
1246 copy_mat(box
, upd
->deformref_box
);
1249 static void deform(gmx_update_t upd
,
1250 int start
, int homenr
, rvec x
[], matrix box
, matrix
*scale_tot
,
1251 const t_inputrec
*ir
, gmx_large_int_t step
)
1253 matrix bnew
, invbox
, mu
;
1257 elapsed_time
= (step
+ 1 - upd
->deformref_step
)*ir
->delta_t
;
1258 copy_mat(box
, bnew
);
1259 for (i
= 0; i
< DIM
; i
++)
1261 for (j
= 0; j
< DIM
; j
++)
1263 if (ir
->deform
[i
][j
] != 0)
1266 upd
->deformref_box
[i
][j
] + elapsed_time
*ir
->deform
[i
][j
];
1270 /* We correct the off-diagonal elements,
1271 * which can grow indefinitely during shearing,
1272 * so the shifts do not get messed up.
1274 for (i
= 1; i
< DIM
; i
++)
1276 for (j
= i
-1; j
>= 0; j
--)
1278 while (bnew
[i
][j
] - box
[i
][j
] > 0.5*bnew
[j
][j
])
1280 rvec_dec(bnew
[i
], bnew
[j
]);
1282 while (bnew
[i
][j
] - box
[i
][j
] < -0.5*bnew
[j
][j
])
1284 rvec_inc(bnew
[i
], bnew
[j
]);
1288 m_inv_ur0(box
, invbox
);
1289 copy_mat(bnew
, box
);
1290 mmul_ur0(box
, invbox
, mu
);
1292 for (i
= start
; i
< start
+homenr
; i
++)
1294 x
[i
][XX
] = mu
[XX
][XX
]*x
[i
][XX
]+mu
[YY
][XX
]*x
[i
][YY
]+mu
[ZZ
][XX
]*x
[i
][ZZ
];
1295 x
[i
][YY
] = mu
[YY
][YY
]*x
[i
][YY
]+mu
[ZZ
][YY
]*x
[i
][ZZ
];
1296 x
[i
][ZZ
] = mu
[ZZ
][ZZ
]*x
[i
][ZZ
];
1300 /* The transposes of the scaling matrices are stored,
1301 * so we need to do matrix multiplication in the inverse order.
1303 mmul_ur0(*scale_tot
, mu
, *scale_tot
);
1307 static void combine_forces(int nstcalclr
,
1308 gmx_constr_t constr
,
1309 t_inputrec
*ir
, t_mdatoms
*md
, t_idef
*idef
,
1311 gmx_large_int_t step
,
1312 t_state
*state
, gmx_bool bMolPBC
,
1313 int start
, int nrend
,
1314 rvec f
[], rvec f_lr
[],
1319 /* f contains the short-range forces + the long range forces
1320 * which are stored separately in f_lr.
1323 if (constr
!= NULL
&& !(ir
->eConstrAlg
== econtSHAKE
&& ir
->epc
== epcNO
))
1325 /* We need to constrain the LR forces separately,
1326 * because due to the different pre-factor for the SR and LR
1327 * forces in the update algorithm, we can not determine
1328 * the constraint force for the coordinate constraining.
1329 * Constrain only the additional LR part of the force.
1331 /* MRS -- need to make sure this works with trotter integration -- the constraint calls may not be right.*/
1332 constrain(NULL
, FALSE
, FALSE
, constr
, idef
, ir
, NULL
, cr
, step
, 0, md
,
1333 state
->x
, f_lr
, f_lr
, bMolPBC
, state
->box
, state
->lambda
[efptBONDED
], NULL
,
1334 NULL
, NULL
, nrnb
, econqForce
, ir
->epc
== epcMTTK
, state
->veta
, state
->veta
);
1337 /* Add nstcalclr-1 times the LR force to the sum of both forces
1338 * and store the result in forces_lr.
1340 nm1
= nstcalclr
- 1;
1341 for (i
= start
; i
< nrend
; i
++)
1343 for (d
= 0; d
< DIM
; d
++)
1345 f_lr
[i
][d
] = f
[i
][d
] + nm1
*f_lr
[i
][d
];
1350 void update_tcouple(FILE *fplog
,
1351 gmx_large_int_t step
,
1352 t_inputrec
*inputrec
,
1354 gmx_ekindata_t
*ekind
,
1355 gmx_wallcycle_t wcycle
,
1361 gmx_bool bTCouple
= FALSE
;
1363 int i
, start
, end
, homenr
, offset
;
1365 /* if using vv with trotter decomposition methods, we do this elsewhere in the code */
1366 if (inputrec
->etc
!= etcNO
&&
1367 !(IR_NVT_TROTTER(inputrec
) || IR_NPT_TROTTER(inputrec
) || IR_NPH_TROTTER(inputrec
)))
1369 /* We should only couple after a step where energies were determined (for leapfrog versions)
1370 or the step energies are determined, for velocity verlet versions */
1372 if (EI_VV(inputrec
->eI
))
1380 bTCouple
= (inputrec
->nsttcouple
== 1 ||
1381 do_per_step(step
+inputrec
->nsttcouple
-offset
,
1382 inputrec
->nsttcouple
));
1387 dttc
= inputrec
->nsttcouple
*inputrec
->delta_t
;
1389 switch (inputrec
->etc
)
1394 berendsen_tcoupl(inputrec
, ekind
, dttc
);
1397 nosehoover_tcoupl(&(inputrec
->opts
), ekind
, dttc
,
1398 state
->nosehoover_xi
, state
->nosehoover_vxi
, MassQ
);
1401 vrescale_tcoupl(inputrec
, ekind
, dttc
,
1402 state
->therm_integral
, upd
->sd
->gaussrand
[0]);
1405 /* rescale in place here */
1406 if (EI_VV(inputrec
->eI
))
1408 rescale_velocities(ekind
, md
, md
->start
, md
->start
+md
->homenr
, state
->v
);
1413 /* Set the T scaling lambda to 1 to have no scaling */
1414 for (i
= 0; (i
< inputrec
->opts
.ngtc
); i
++)
1416 ekind
->tcstat
[i
].lambda
= 1.0;
1421 void update_pcouple(FILE *fplog
,
1422 gmx_large_int_t step
,
1423 t_inputrec
*inputrec
,
1427 gmx_wallcycle_t wcycle
,
1431 gmx_bool bPCouple
= FALSE
;
1435 /* if using Trotter pressure, we do this in coupling.c, so we leave it false. */
1436 if (inputrec
->epc
!= epcNO
&& (!(IR_NPT_TROTTER(inputrec
) || IR_NPH_TROTTER(inputrec
))))
1438 /* We should only couple after a step where energies were determined */
1439 bPCouple
= (inputrec
->nstpcouple
== 1 ||
1440 do_per_step(step
+inputrec
->nstpcouple
-1,
1441 inputrec
->nstpcouple
));
1444 clear_mat(pcoupl_mu
);
1445 for (i
= 0; i
< DIM
; i
++)
1447 pcoupl_mu
[i
][i
] = 1.0;
1454 dtpc
= inputrec
->nstpcouple
*inputrec
->delta_t
;
1456 switch (inputrec
->epc
)
1458 /* We can always pcoupl, even if we did not sum the energies
1459 * the previous step, since state->pres_prev is only updated
1460 * when the energies have been summed.
1464 case (epcBERENDSEN
):
1467 berendsen_pcoupl(fplog
, step
, inputrec
, dtpc
, state
->pres_prev
, state
->box
,
1471 case (epcPARRINELLORAHMAN
):
1472 parrinellorahman_pcoupl(fplog
, step
, inputrec
, dtpc
, state
->pres_prev
,
1473 state
->box
, state
->box_rel
, state
->boxv
,
1474 M
, pcoupl_mu
, bInitStep
);
1482 static rvec
*get_xprime(const t_state
*state
, gmx_update_t upd
)
1484 if (state
->nalloc
> upd
->xp_nalloc
)
1486 upd
->xp_nalloc
= state
->nalloc
;
1487 srenew(upd
->xp
, upd
->xp_nalloc
);
1493 void update_constraints(FILE *fplog
,
1494 gmx_large_int_t step
,
1495 real
*dvdlambda
, /* the contribution to be added to the bonded interactions */
1496 t_inputrec
*inputrec
, /* input record and box stuff */
1497 gmx_ekindata_t
*ekind
,
1502 rvec force
[], /* forces on home particles */
1505 tensor vir
, /* tensors for virial and ekin, needed for computing */
1508 gmx_wallcycle_t wcycle
,
1510 gmx_constr_t constr
,
1512 gmx_bool bFirstHalf
,
1516 gmx_bool bExtended
, bLastStep
, bLog
= FALSE
, bEner
= FALSE
, bDoConstr
= FALSE
;
1519 int start
, homenr
, nrend
, i
, n
, m
, g
, d
;
1521 rvec
*vbuf
, *xprime
= NULL
;
1528 if (bFirstHalf
&& !EI_VV(inputrec
->eI
))
1533 /* for now, SD update is here -- though it really seems like it
1534 should be reformulated as a velocity verlet method, since it has two parts */
1537 homenr
= md
->homenr
;
1538 nrend
= start
+homenr
;
1540 dt
= inputrec
->delta_t
;
1545 * APPLY CONSTRAINTS:
1548 * When doing PR pressure coupling we have to constrain the
1549 * bonds in each iteration. If we are only using Nose-Hoover tcoupling
1550 * it is enough to do this once though, since the relative velocities
1551 * after this will be normal to the bond vector
1556 /* clear out constraints before applying */
1557 clear_mat(vir_part
);
1559 xprime
= get_xprime(state
, upd
);
1561 bLastStep
= (step
== inputrec
->init_step
+inputrec
->nsteps
);
1562 bLog
= (do_per_step(step
, inputrec
->nstlog
) || bLastStep
|| (step
< 0));
1563 bEner
= (do_per_step(step
, inputrec
->nstenergy
) || bLastStep
);
1564 /* Constrain the coordinates xprime */
1565 wallcycle_start(wcycle
, ewcCONSTR
);
1566 if (EI_VV(inputrec
->eI
) && bFirstHalf
)
1568 constrain(NULL
, bLog
, bEner
, constr
, idef
,
1569 inputrec
, ekind
, cr
, step
, 1, md
,
1570 state
->x
, state
->v
, state
->v
,
1571 bMolPBC
, state
->box
,
1572 state
->lambda
[efptBONDED
], dvdlambda
,
1573 NULL
, bCalcVir
? &vir_con
: NULL
, nrnb
, econqVeloc
,
1574 inputrec
->epc
== epcMTTK
, state
->veta
, vetanew
);
1578 constrain(NULL
, bLog
, bEner
, constr
, idef
,
1579 inputrec
, ekind
, cr
, step
, 1, md
,
1580 state
->x
, xprime
, NULL
,
1581 bMolPBC
, state
->box
,
1582 state
->lambda
[efptBONDED
], dvdlambda
,
1583 state
->v
, bCalcVir
? &vir_con
: NULL
, nrnb
, econqCoord
,
1584 inputrec
->epc
== epcMTTK
, state
->veta
, state
->veta
);
1586 wallcycle_stop(wcycle
, ewcCONSTR
);
1590 dump_it_all(fplog
, "After Shake",
1591 state
->natoms
, state
->x
, xprime
, state
->v
, force
);
1595 if (inputrec
->eI
== eiSD2
)
1597 /* A correction factor eph is needed for the SD constraint force */
1598 /* Here we can, unfortunately, not have proper corrections
1599 * for different friction constants, so we use the first one.
1601 for (i
= 0; i
< DIM
; i
++)
1603 for (m
= 0; m
< DIM
; m
++)
1605 vir_part
[i
][m
] += upd
->sd
->sdc
[0].eph
*vir_con
[i
][m
];
1611 m_add(vir_part
, vir_con
, vir_part
);
1615 pr_rvecs(debug
, 0, "constraint virial", vir_part
, DIM
);
1621 if ((inputrec
->eI
== eiSD2
) && !(bFirstHalf
))
1623 xprime
= get_xprime(state
, upd
);
1625 nth
= gmx_omp_nthreads_get(emntUpdate
);
1627 #pragma omp parallel for num_threads(nth) schedule(static)
1628 for (th
= 0; th
< nth
; th
++)
1630 int start_th
, end_th
;
1632 start_th
= start
+ ((nrend
-start
)* th
)/nth
;
1633 end_th
= start
+ ((nrend
-start
)*(th
+1))/nth
;
1635 /* The second part of the SD integration */
1636 do_update_sd2(upd
->sd
, upd
->sd
->gaussrand
[th
],
1637 FALSE
, start_th
, end_th
,
1638 inputrec
->opts
.acc
, inputrec
->opts
.nFreeze
,
1639 md
->invmass
, md
->ptype
,
1640 md
->cFREEZE
, md
->cACC
, md
->cTC
,
1641 state
->x
, xprime
, state
->v
, force
, state
->sd_X
,
1642 inputrec
->opts
.ngtc
, inputrec
->opts
.tau_t
,
1643 inputrec
->opts
.ref_t
, FALSE
);
1645 inc_nrnb(nrnb
, eNR_UPDATE
, homenr
);
1649 /* Constrain the coordinates xprime */
1650 wallcycle_start(wcycle
, ewcCONSTR
);
1651 constrain(NULL
, bLog
, bEner
, constr
, idef
,
1652 inputrec
, NULL
, cr
, step
, 1, md
,
1653 state
->x
, xprime
, NULL
,
1654 bMolPBC
, state
->box
,
1655 state
->lambda
[efptBONDED
], dvdlambda
,
1656 NULL
, NULL
, nrnb
, econqCoord
, FALSE
, 0, 0);
1657 wallcycle_stop(wcycle
, ewcCONSTR
);
1661 /* We must always unshift after updating coordinates; if we did not shake
1662 x was shifted in do_force */
1664 if (!(bFirstHalf
)) /* in the first half of vv, no shift. */
1666 if (graph
&& (graph
->nnodes
> 0))
1668 unshift_x(graph
, state
->box
, state
->x
, upd
->xp
);
1669 if (TRICLINIC(state
->box
))
1671 inc_nrnb(nrnb
, eNR_SHIFTX
, 2*graph
->nnodes
);
1675 inc_nrnb(nrnb
, eNR_SHIFTX
, graph
->nnodes
);
1680 #pragma omp parallel for num_threads(gmx_omp_nthreads_get(emntUpdate)) schedule(static)
1681 for (i
= start
; i
< nrend
; i
++)
1683 copy_rvec(upd
->xp
[i
], state
->x
[i
]);
1687 dump_it_all(fplog
, "After unshift",
1688 state
->natoms
, state
->x
, upd
->xp
, state
->v
, force
);
1690 /* ############# END the update of velocities and positions ######### */
1693 void update_box(FILE *fplog
,
1694 gmx_large_int_t step
,
1695 t_inputrec
*inputrec
, /* input record and box stuff */
1699 rvec force
[], /* forces on home particles */
1703 gmx_wallcycle_t wcycle
,
1706 gmx_bool bFirstHalf
)
1708 gmx_bool bExtended
, bLastStep
, bLog
= FALSE
, bEner
= FALSE
;
1711 int start
, homenr
, nrend
, i
, n
, m
, g
;
1715 homenr
= md
->homenr
;
1716 nrend
= start
+homenr
;
1719 (inputrec
->etc
== etcNOSEHOOVER
) ||
1720 (inputrec
->epc
== epcPARRINELLORAHMAN
) ||
1721 (inputrec
->epc
== epcMTTK
);
1723 dt
= inputrec
->delta_t
;
1727 /* now update boxes */
1728 switch (inputrec
->epc
)
1732 case (epcBERENDSEN
):
1733 berendsen_pscale(inputrec
, pcoupl_mu
, state
->box
, state
->box_rel
,
1734 start
, homenr
, state
->x
, md
->cFREEZE
, nrnb
);
1736 case (epcPARRINELLORAHMAN
):
1737 /* The box velocities were updated in do_pr_pcoupl in the update
1738 * iteration, but we dont change the box vectors until we get here
1739 * since we need to be able to shift/unshift above.
1741 for (i
= 0; i
< DIM
; i
++)
1743 for (m
= 0; m
<= i
; m
++)
1745 state
->box
[i
][m
] += dt
*state
->boxv
[i
][m
];
1748 preserve_box_shape(inputrec
, state
->box_rel
, state
->box
);
1750 /* Scale the coordinates */
1751 for (n
= start
; (n
< start
+homenr
); n
++)
1753 tmvmul_ur0(pcoupl_mu
, state
->x
[n
], state
->x
[n
]);
1757 switch (inputrec
->epct
)
1759 case (epctISOTROPIC
):
1760 /* DIM * eta = ln V. so DIM*eta_new = DIM*eta_old + DIM*dt*veta =>
1761 ln V_new = ln V_old + 3*dt*veta => V_new = V_old*exp(3*dt*veta) =>
1762 Side length scales as exp(veta*dt) */
1764 msmul(state
->box
, exp(state
->veta
*dt
), state
->box
);
1766 /* Relate veta to boxv. veta = d(eta)/dT = (1/DIM)*1/V dV/dT.
1767 o If we assume isotropic scaling, and box length scaling
1768 factor L, then V = L^DIM (det(M)). So dV/dt = DIM
1769 L^(DIM-1) dL/dt det(M), and veta = (1/L) dL/dt. The
1770 determinant of B is L^DIM det(M), and the determinant
1771 of dB/dt is (dL/dT)^DIM det (M). veta will be
1772 (det(dB/dT)/det(B))^(1/3). Then since M =
1773 B_new*(vol_new)^(1/3), dB/dT_new = (veta_new)*B(new). */
1775 msmul(state
->box
, state
->veta
, state
->boxv
);
1785 if ((!(IR_NPT_TROTTER(inputrec
) || IR_NPH_TROTTER(inputrec
))) && scale_tot
)
1787 /* The transposes of the scaling matrices are stored,
1788 * therefore we need to reverse the order in the multiplication.
1790 mmul_ur0(*scale_tot
, pcoupl_mu
, *scale_tot
);
1793 if (DEFORM(*inputrec
))
1795 deform(upd
, start
, homenr
, state
->x
, state
->box
, scale_tot
, inputrec
, step
);
1798 dump_it_all(fplog
, "After update",
1799 state
->natoms
, state
->x
, upd
->xp
, state
->v
, force
);
1802 void update_coords(FILE *fplog
,
1803 gmx_large_int_t step
,
1804 t_inputrec
*inputrec
, /* input record and box stuff */
1808 rvec
*f
, /* forces on home particles */
1812 gmx_ekindata_t
*ekind
,
1814 gmx_wallcycle_t wcycle
,
1818 t_commrec
*cr
, /* these shouldn't be here -- need to think about it */
1820 gmx_constr_t constr
,
1823 gmx_bool bNH
, bPR
, bLastStep
, bLog
= FALSE
, bEner
= FALSE
;
1825 real
*imass
, *imassin
;
1828 int start
, homenr
, nrend
, i
, j
, d
, n
, m
, g
;
1829 int blen0
, blen1
, iatom
, jatom
, nshake
, nsettle
, nconstr
, nexpand
;
1832 rvec
*vcom
, *xcom
, *vall
, *xall
, *xin
, *vin
, *forcein
, *fall
, *xpall
, *xprimein
, *xprime
;
1835 /* Running the velocity half does nothing except for velocity verlet */
1836 if ((UpdatePart
== etrtVELOCITY1
|| UpdatePart
== etrtVELOCITY2
) &&
1837 !EI_VV(inputrec
->eI
))
1839 gmx_incons("update_coords called for velocity without VV integrator");
1843 homenr
= md
->homenr
;
1844 nrend
= start
+homenr
;
1846 xprime
= get_xprime(state
, upd
);
1848 dt
= inputrec
->delta_t
;
1851 /* We need to update the NMR restraint history when time averaging is used */
1852 if (state
->flags
& (1<<estDISRE_RM3TAV
))
1854 update_disres_history(fcd
, &state
->hist
);
1856 if (state
->flags
& (1<<estORIRE_DTAV
))
1858 update_orires_history(fcd
, &state
->hist
);
1862 bNH
= inputrec
->etc
== etcNOSEHOOVER
;
1863 bPR
= ((inputrec
->epc
== epcPARRINELLORAHMAN
) || (inputrec
->epc
== epcMTTK
));
1865 if (bDoLR
&& inputrec
->nstcalclr
> 1 && !EI_VV(inputrec
->eI
)) /* get this working with VV? */
1867 /* Store the total force + nstcalclr-1 times the LR force
1868 * in forces_lr, so it can be used in a normal update algorithm
1869 * to produce twin time stepping.
1871 /* is this correct in the new construction? MRS */
1872 combine_forces(inputrec
->nstcalclr
, constr
, inputrec
, md
, idef
, cr
,
1873 step
, state
, bMolPBC
,
1874 start
, nrend
, f
, f_lr
, nrnb
);
1882 /* ############# START The update of velocities and positions ######### */
1884 dump_it_all(fplog
, "Before update",
1885 state
->natoms
, state
->x
, xprime
, state
->v
, force
);
1887 if (EI_RANDOM(inputrec
->eI
))
1889 /* We still need to take care of generating random seeds properly
1890 * when multi-threading.
1896 nth
= gmx_omp_nthreads_get(emntUpdate
);
1899 if (inputrec
->eI
== eiSD2
)
1901 check_sd2_work_data_allocation(upd
->sd
, nrend
);
1904 #pragma omp parallel for num_threads(nth) schedule(static) private(alpha)
1905 for (th
= 0; th
< nth
; th
++)
1907 int start_th
, end_th
;
1909 start_th
= start
+ ((nrend
-start
)* th
)/nth
;
1910 end_th
= start
+ ((nrend
-start
)*(th
+1))/nth
;
1912 switch (inputrec
->eI
)
1915 if (ekind
->cosacc
.cos_accel
== 0)
1917 do_update_md(start_th
, end_th
, dt
,
1918 ekind
->tcstat
, state
->nosehoover_vxi
,
1919 ekind
->bNEMD
, ekind
->grpstat
, inputrec
->opts
.acc
,
1920 inputrec
->opts
.nFreeze
,
1921 md
->invmass
, md
->ptype
,
1922 md
->cFREEZE
, md
->cACC
, md
->cTC
,
1923 state
->x
, xprime
, state
->v
, force
, M
,
1928 do_update_visc(start_th
, end_th
, dt
,
1929 ekind
->tcstat
, state
->nosehoover_vxi
,
1930 md
->invmass
, md
->ptype
,
1931 md
->cTC
, state
->x
, xprime
, state
->v
, force
, M
,
1933 ekind
->cosacc
.cos_accel
,
1939 do_update_sd1(upd
->sd
, upd
->sd
->gaussrand
[th
],
1940 start_th
, end_th
, dt
,
1941 inputrec
->opts
.acc
, inputrec
->opts
.nFreeze
,
1942 md
->invmass
, md
->ptype
,
1943 md
->cFREEZE
, md
->cACC
, md
->cTC
,
1944 state
->x
, xprime
, state
->v
, force
, state
->sd_X
,
1945 inputrec
->opts
.ngtc
, inputrec
->opts
.tau_t
, inputrec
->opts
.ref_t
);
1948 /* The SD update is done in 2 parts, because an extra constraint step
1951 do_update_sd2(upd
->sd
, upd
->sd
->gaussrand
[th
],
1952 bInitStep
, start_th
, end_th
,
1953 inputrec
->opts
.acc
, inputrec
->opts
.nFreeze
,
1954 md
->invmass
, md
->ptype
,
1955 md
->cFREEZE
, md
->cACC
, md
->cTC
,
1956 state
->x
, xprime
, state
->v
, force
, state
->sd_X
,
1957 inputrec
->opts
.ngtc
, inputrec
->opts
.tau_t
, inputrec
->opts
.ref_t
,
1961 do_update_bd(start_th
, end_th
, dt
,
1962 inputrec
->opts
.nFreeze
, md
->invmass
, md
->ptype
,
1963 md
->cFREEZE
, md
->cTC
,
1964 state
->x
, xprime
, state
->v
, force
,
1966 inputrec
->opts
.ngtc
, inputrec
->opts
.tau_t
, inputrec
->opts
.ref_t
,
1967 upd
->sd
->bd_rf
, upd
->sd
->gaussrand
[th
]);
1971 alpha
= 1.0 + DIM
/((double)inputrec
->opts
.nrdf
[0]); /* assuming barostat coupled to group 0. */
1976 do_update_vv_vel(start_th
, end_th
, dt
,
1977 ekind
->tcstat
, ekind
->grpstat
,
1978 inputrec
->opts
.acc
, inputrec
->opts
.nFreeze
,
1979 md
->invmass
, md
->ptype
,
1980 md
->cFREEZE
, md
->cACC
,
1982 (bNH
|| bPR
), state
->veta
, alpha
);
1985 do_update_vv_pos(start_th
, end_th
, dt
,
1986 ekind
->tcstat
, ekind
->grpstat
,
1987 inputrec
->opts
.acc
, inputrec
->opts
.nFreeze
,
1988 md
->invmass
, md
->ptype
, md
->cFREEZE
,
1989 state
->x
, xprime
, state
->v
, force
,
1990 (bNH
|| bPR
), state
->veta
, alpha
);
1995 gmx_fatal(FARGS
, "Don't know how to update coordinates");
2003 void correct_ekin(FILE *log
, int start
, int end
, rvec v
[], rvec vcm
, real mass
[],
2004 real tmass
, tensor ekin
)
2007 * This is a debugging routine. It should not be called for production code
2009 * The kinetic energy should calculated according to:
2010 * Ekin = 1/2 m (v-vcm)^2
2011 * However the correction is not always applied, since vcm may not be
2012 * known in time and we compute
2013 * Ekin' = 1/2 m v^2 instead
2014 * This can be corrected afterwards by computing
2015 * Ekin = Ekin' + 1/2 m ( -2 v vcm + vcm^2)
2017 * Ekin = Ekin' - m v vcm + 1/2 m vcm^2
2024 /* Local particles */
2027 /* Processor dependent part. */
2029 for (i
= start
; (i
< end
); i
++)
2033 for (j
= 0; (j
< DIM
); j
++)
2039 svmul(1/tmass
, vcm
, vcm
);
2040 svmul(0.5, vcm
, hvcm
);
2042 for (j
= 0; (j
< DIM
); j
++)
2044 for (k
= 0; (k
< DIM
); k
++)
2046 dekin
[j
][k
] += vcm
[k
]*(tm
*hvcm
[j
]-mv
[j
]);
2049 pr_rvecs(log
, 0, "dekin", dekin
, DIM
);
2050 pr_rvecs(log
, 0, " ekin", ekin
, DIM
);
2051 fprintf(log
, "dekin = %g, ekin = %g vcm = (%8.4f %8.4f %8.4f)\n",
2052 trace(dekin
), trace(ekin
), vcm
[XX
], vcm
[YY
], vcm
[ZZ
]);
2053 fprintf(log
, "mv = (%8.4f %8.4f %8.4f)\n",
2054 mv
[XX
], mv
[YY
], mv
[ZZ
]);
2057 extern gmx_bool
update_randomize_velocities(t_inputrec
*ir
, gmx_large_int_t step
, t_mdatoms
*md
, t_state
*state
, gmx_update_t upd
, t_idef
*idef
, gmx_constr_t constr
)
2061 real rate
= (ir
->delta_t
)/ir
->opts
.tau_t
[0];
2062 /* proceed with andersen if 1) it's fixed probability per
2063 particle andersen or 2) it's massive andersen and it's tau_t/dt */
2064 if ((ir
->etc
== etcANDERSEN
) || do_per_step(step
, (int)(1.0/rate
)))
2066 srenew(upd
->randatom
, state
->nalloc
);
2067 srenew(upd
->randatom_list
, state
->nalloc
);
2068 if (upd
->randatom_list_init
== FALSE
)
2070 for (i
= 0; i
< state
->nalloc
; i
++)
2072 upd
->randatom
[i
] = FALSE
;
2073 upd
->randatom_list
[i
] = 0;
2075 upd
->randatom_list_init
= TRUE
;
2077 andersen_tcoupl(ir
, md
, state
, upd
->sd
->gaussrand
[0], rate
,
2078 (ir
->etc
== etcANDERSEN
) ? idef
: NULL
,
2079 constr
? get_nblocks(constr
) : 0,
2080 constr
? get_sblock(constr
) : NULL
,
2081 upd
->randatom
, upd
->randatom_list
,
2082 upd
->sd
->randomize_group
, upd
->sd
->boltzfac
);