1 /* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
11 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
12 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
13 * Copyright (c) 2001-2004, The GROMACS development team,
14 * check out http://www.gromacs.org for more information.
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
21 * If you want to redistribute modifications, please consider that
22 * scientific software is very special. Version control is crucial -
23 * bugs must be traceable. We will be happy to consider code for
24 * inclusion in the official distribution, but derived work must not
25 * be called official GROMACS. Details are found in the README & COPYING
26 * files - if they are missing, get the official version at www.gromacs.org.
28 * To help us fund GROMACS development, we humbly ask that you cite
29 * the papers on the package - you can find them in the top README file.
31 * For more info, check our website at http://www.gromacs.org
34 * GROningen Mixture of Alchemy and Childrens' Stories
44 #include "gmx_fatal.h"
67 #include "checkpoint.h"
71 typedef struct gmx_global_stat
78 gmx_global_stat_t
global_stat_init(t_inputrec
*ir
)
85 snew(gs
->itc0
,ir
->opts
.ngtc
);
86 snew(gs
->itc1
,ir
->opts
.ngtc
);
91 void global_stat_destroy(gmx_global_stat_t gs
)
99 static int filter_enerdterm(real
*afrom
, bool bToBuffer
, real
*ato
,
100 bool bTemp
, bool bPres
, bool bEner
) {
105 for (i
=0;i
<F_NRE
;i
++)
121 ato
[to
++] = afrom
[from
++];
129 ato
[to
++] = afrom
[from
++];
135 ato
[to
++] = afrom
[from
++];
144 void global_stat(FILE *fplog
,gmx_global_stat_t gs
,
145 t_commrec
*cr
,gmx_enerdata_t
*enerd
,
146 tensor fvir
,tensor svir
,rvec mu_tot
,
147 t_inputrec
*inputrec
,
148 gmx_ekindata_t
*ekind
,gmx_constr_t constr
,
151 gmx_mtop_t
*top_global
, t_state
*state_local
,
152 bool bSumEkinhOld
, int flags
)
153 /* instead of current system, booleans for summing virial, kinetic energy, and other terms */
157 int ie
=0,ifv
=0,isv
=0,irmsd
=0,imu
=0;
158 int idedl
=0,idvdll
=0,idvdlnl
=0,iepl
=0,icm
=0,imass
=0,ica
=0,inb
=0;
160 int icj
=-1,ici
=-1,icx
=-1;
162 real copyenerd
[F_NRE
];
164 real
*rmsd_data
=NULL
;
166 bool bVV
,bTemp
,bEner
,bPres
,bConstrVir
,bEkinAveVel
,bFirstIterate
,bReadEkin
;
168 bVV
= EI_VV(inputrec
->eI
);
169 bTemp
= flags
& CGLO_TEMPERATURE
;
170 bEner
= flags
& CGLO_ENERGY
;
171 bPres
= flags
& CGLO_PRESSURE
;
172 bConstrVir
= flags
& CGLO_CONSTRAINT
;
173 bFirstIterate
= flags
& CGLO_FIRSTITERATE
;
174 bEkinAveVel
= (inputrec
->eI
==eiVV
|| (inputrec
->eI
==eiVVAK
&& IR_NPT_TROTTER(inputrec
) && bPres
));
175 bReadEkin
= flags
& CGLO_READEKIN
;
183 /* This routine copies all the data to be summed to one big buffer
184 * using the t_bin struct.
187 /* First, we neeed to identify which enerd->term should be
188 communicated. Temperature and pressure terms should only be
189 communicated and summed when they need to be, to avoid repeating
190 the sums and overcounting. */
192 nener
= filter_enerdterm(enerd
->term
,TRUE
,copyenerd
,bTemp
,bPres
,bEner
);
194 /* First, the data that needs to be communicated with velocity verlet every time
195 This is just the constraint virial.*/
197 isv
= add_binr(rb
,DIM
*DIM
,svir
[0]);
201 /* We need the force virial and the kinetic energy for the first time through with velocity verlet */
206 for(j
=0; (j
<inputrec
->opts
.ngtc
); j
++)
210 itc0
[j
]=add_binr(rb
,DIM
*DIM
,ekind
->tcstat
[j
].ekinh_old
[0]);
212 if (bEkinAveVel
&& !bReadEkin
)
214 itc1
[j
]=add_binr(rb
,DIM
*DIM
,ekind
->tcstat
[j
].ekinf
[0]);
218 itc1
[j
]=add_binr(rb
,DIM
*DIM
,ekind
->tcstat
[j
].ekinh
[0]);
221 /* these probably need to be put into one of these categories */
223 idedl
= add_binr(rb
,1,&(ekind
->dekindl
));
225 ica
= add_binr(rb
,1,&(ekind
->cosacc
.mvcos
));
231 if ((bPres
|| !bVV
) && bFirstIterate
)
233 ifv
= add_binr(rb
,DIM
*DIM
,fvir
[0]);
242 ie
= add_binr(rb
,nener
,copyenerd
);
247 rmsd_data
= constr_rmsd_data(constr
);
250 irmsd
= add_binr(rb
,inputrec
->eI
==eiSD2
? 3 : 2,rmsd_data
);
253 if (!NEED_MUTOT(*inputrec
))
255 imu
= add_binr(rb
,DIM
,mu_tot
);
261 for(j
=0; (j
<egNR
); j
++)
263 inn
[j
]=add_binr(rb
,enerd
->grpp
.nener
,enerd
->grpp
.ener
[j
]);
266 if (inputrec
->efep
!= efepNO
)
268 idvdll
= add_bind(rb
,1,&enerd
->dvdl_lin
);
269 idvdlnl
= add_bind(rb
,1,&enerd
->dvdl_nonlin
);
270 if (enerd
->n_lambda
> 0)
272 iepl
= add_bind(rb
,enerd
->n_lambda
,enerd
->enerpart_lambda
);
279 icm
= add_binr(rb
,DIM
*vcm
->nr
,vcm
->group_p
[0]);
281 imass
= add_binr(rb
,vcm
->nr
,vcm
->group_mass
);
283 if (vcm
->mode
== ecmANGULAR
)
285 icj
= add_binr(rb
,DIM
*vcm
->nr
,vcm
->group_j
[0]);
287 icx
= add_binr(rb
,DIM
*vcm
->nr
,vcm
->group_x
[0]);
289 ici
= add_binr(rb
,DIM
*DIM
*vcm
->nr
,vcm
->group_i
[0][0]);
294 if (DOMAINDECOMP(cr
))
296 nb
= cr
->dd
->nbonded_local
;
297 inb
= add_bind(rb
,1,&nb
);
302 isig
= add_binr(rb
,nsig
,sig
);
305 /* Global sum it all */
308 fprintf(debug
,"Summing %d energies\n",rb
->maxreal
);
313 /* Extract all the data locally */
317 extract_binr(rb
,isv
,DIM
*DIM
,svir
[0]);
320 /* We need the force virial and the kinetic energy for the first time through with velocity verlet */
325 for(j
=0; (j
<inputrec
->opts
.ngtc
); j
++)
329 extract_binr(rb
,itc0
[j
],DIM
*DIM
,ekind
->tcstat
[j
].ekinh_old
[0]);
331 if (bEkinAveVel
&& !bReadEkin
) {
332 extract_binr(rb
,itc1
[j
],DIM
*DIM
,ekind
->tcstat
[j
].ekinf
[0]);
336 extract_binr(rb
,itc1
[j
],DIM
*DIM
,ekind
->tcstat
[j
].ekinh
[0]);
339 extract_binr(rb
,idedl
,1,&(ekind
->dekindl
));
340 extract_binr(rb
,ica
,1,&(ekind
->cosacc
.mvcos
));
344 if ((bPres
|| !bVV
) && bFirstIterate
)
346 extract_binr(rb
,ifv
,DIM
*DIM
,fvir
[0]);
353 extract_binr(rb
,ie
,nener
,copyenerd
);
356 extract_binr(rb
,irmsd
,inputrec
->eI
==eiSD2
? 3 : 2,rmsd_data
);
358 if (!NEED_MUTOT(*inputrec
))
360 extract_binr(rb
,imu
,DIM
,mu_tot
);
363 for(j
=0; (j
<egNR
); j
++)
365 extract_binr(rb
,inn
[j
],enerd
->grpp
.nener
,enerd
->grpp
.ener
[j
]);
367 if (inputrec
->efep
!= efepNO
)
369 extract_bind(rb
,idvdll
,1,&enerd
->dvdl_lin
);
370 extract_bind(rb
,idvdlnl
,1,&enerd
->dvdl_nonlin
);
371 if (enerd
->n_lambda
> 0)
373 extract_bind(rb
,iepl
,enerd
->n_lambda
,enerd
->enerpart_lambda
);
376 /* should this be here, or with ekin?*/
379 extract_binr(rb
,icm
,DIM
*vcm
->nr
,vcm
->group_p
[0]);
381 extract_binr(rb
,imass
,vcm
->nr
,vcm
->group_mass
);
383 if (vcm
->mode
== ecmANGULAR
)
385 extract_binr(rb
,icj
,DIM
*vcm
->nr
,vcm
->group_j
[0]);
387 extract_binr(rb
,icx
,DIM
*vcm
->nr
,vcm
->group_x
[0]);
389 extract_binr(rb
,ici
,DIM
*DIM
*vcm
->nr
,vcm
->group_i
[0][0]);
393 if (DOMAINDECOMP(cr
))
395 extract_bind(rb
,inb
,1,&nb
);
396 if ((int)(nb
+ 0.5) != cr
->dd
->nbonded_global
)
398 dd_print_missing_interactions(fplog
,cr
,(int)(nb
+ 0.5),top_global
,state_local
);
403 filter_enerdterm(copyenerd
,FALSE
,enerd
->term
,bTemp
,bPres
,bEner
);
404 /* Small hack for temp only - not entirely clear if still needed?*/
405 /* enerd->term[F_TEMP] /= (cr->nnodes - cr->npmenodes); */
411 extract_binr(rb
,isig
,nsig
,sig
);
416 int do_per_step(gmx_large_int_t step
,gmx_large_int_t nstep
)
419 return ((step
% nstep
)==0);
424 static void moveit(t_commrec
*cr
,
425 int left
,int right
,const char *s
,rvec xx
[])
430 move_rvecs(cr
,FALSE
,FALSE
,left
,right
,
431 xx
,NULL
,(cr
->nnodes
-cr
->npmenodes
)-1,NULL
);
434 gmx_mdoutf_t
*init_mdoutf(int nfile
,const t_filenm fnm
[],bool bAppendFiles
,
435 const t_commrec
*cr
,const t_inputrec
*ir
,
436 const output_env_t oenv
)
449 of
->eIntegrator
= ir
->eI
;
450 of
->simulation_part
= ir
->simulation_part
;
454 sprintf(filemode
, bAppendFiles
? "a+" : "w+");
458 of
->fp_trn
= open_trn(ftp2fn(efTRN
,nfile
,fnm
), filemode
);
460 if (ir
->nstxtcout
> 0 && !EI_ENERGY_MINIMIZATION(ir
->eI
))
462 of
->fp_xtc
= open_xtc(ftp2fn(efXTC
,nfile
,fnm
), filemode
);
463 of
->xtc_prec
= ir
->xtcprec
;
465 of
->fp_ene
= open_enx(ftp2fn(efEDR
,nfile
,fnm
), filemode
);
466 of
->fn_cpt
= opt2fn("-cpo",nfile
,fnm
);
468 if (ir
->efep
!= efepNO
&& ir
->nstdhdl
> 0 &&
469 !EI_ENERGY_MINIMIZATION(ir
->eI
))
473 of
->fp_dhdl
= gmx_fio_fopen(opt2fn("-dhdl",nfile
,fnm
),filemode
);
477 of
->fp_dhdl
= open_dhdl(opt2fn("-dhdl",nfile
,fnm
),ir
,oenv
);
481 if (ir
->ex
[XX
].n
|| ir
->ex
[YY
].n
|| ir
->ex
[ZZ
].n
)
485 of
->fp_dhdl
= gmx_fio_fopen(opt2fn("-field",nfile
,fnm
),
490 of
->fp_field
= xvgropen(opt2fn("-field",nfile
,fnm
),
491 "Applied electric field","Time (ps)",
500 void done_mdoutf(gmx_mdoutf_t
*of
)
502 if (of
->fp_ene
!= NULL
)
504 close_enx(of
->fp_ene
);
508 close_xtc(of
->fp_xtc
);
512 close_trn(of
->fp_trn
);
514 if (of
->fp_dhdl
!= NULL
)
516 gmx_fio_fclose(of
->fp_dhdl
);
518 if (of
->fp_field
!= NULL
)
520 gmx_fio_fclose(of
->fp_field
);
526 void write_traj(FILE *fplog
,t_commrec
*cr
,
529 gmx_mtop_t
*top_global
,
530 gmx_large_int_t step
,double t
,
531 t_state
*state_local
,t_state
*state_global
,
532 rvec
*f_local
,rvec
*f_global
,
533 int *n_xtc
,rvec
**x_xtc
)
536 gmx_groups_t
*groups
;
541 #define MX(xvf) moveit(cr,GMX_LEFT,GMX_RIGHT,#xvf,xvf)
543 /* MRS -- defining these variables is to manage the difference
544 * between half step and full step velocities, but there must be a better way . . . */
546 local_v
= state_local
->v
;
547 global_v
= state_global
->v
;
549 if (DOMAINDECOMP(cr
))
551 if (mdof_flags
& MDOF_CPT
)
553 dd_collect_state(cr
->dd
,state_local
,state_global
);
557 if (mdof_flags
& (MDOF_X
| MDOF_XTC
))
559 dd_collect_vec(cr
->dd
,state_local
,state_local
->x
,
562 if (mdof_flags
& MDOF_V
)
564 dd_collect_vec(cr
->dd
,state_local
,local_v
,
568 if (mdof_flags
& MDOF_F
)
570 dd_collect_vec(cr
->dd
,state_local
,f_local
,f_global
);
575 if (mdof_flags
& MDOF_CPT
)
577 /* All pointers in state_local are equal to state_global,
578 * but we need to copy the non-pointer entries.
580 state_global
->lambda
= state_local
->lambda
;
581 state_global
->veta
= state_local
->veta
;
582 state_global
->vol0
= state_local
->vol0
;
583 copy_mat(state_local
->box
,state_global
->box
);
584 copy_mat(state_local
->boxv
,state_global
->boxv
);
585 copy_mat(state_local
->svir_prev
,state_global
->svir_prev
);
586 copy_mat(state_local
->fvir_prev
,state_global
->fvir_prev
);
587 copy_mat(state_local
->pres_prev
,state_global
->pres_prev
);
591 /* Particle decomposition, collect the data on the master node */
592 if (mdof_flags
& MDOF_CPT
)
594 if (state_local
->flags
& (1<<estX
)) MX(state_global
->x
);
595 if (state_local
->flags
& (1<<estV
)) MX(state_global
->v
);
596 if (state_local
->flags
& (1<<estSDX
)) MX(state_global
->sd_X
);
597 if (state_global
->nrngi
> 1) {
598 if (state_local
->flags
& (1<<estLD_RNG
)) {
600 MPI_Gather(state_local
->ld_rng
,
601 state_local
->nrng
*sizeof(state_local
->ld_rng
[0]),MPI_BYTE
,
602 state_global
->ld_rng
,
603 state_local
->nrng
*sizeof(state_local
->ld_rng
[0]),MPI_BYTE
,
604 MASTERRANK(cr
),cr
->mpi_comm_mygroup
);
607 if (state_local
->flags
& (1<<estLD_RNGI
))
610 MPI_Gather(state_local
->ld_rngi
,
611 sizeof(state_local
->ld_rngi
[0]),MPI_BYTE
,
612 state_global
->ld_rngi
,
613 sizeof(state_local
->ld_rngi
[0]),MPI_BYTE
,
614 MASTERRANK(cr
),cr
->mpi_comm_mygroup
);
621 if (mdof_flags
& (MDOF_X
| MDOF_XTC
)) MX(state_global
->x
);
622 if (mdof_flags
& MDOF_V
) MX(global_v
);
624 if (mdof_flags
& MDOF_F
) MX(f_global
);
630 if (mdof_flags
& MDOF_CPT
)
632 write_checkpoint(of
->fn_cpt
,fplog
,cr
,of
->eIntegrator
,
633 of
->simulation_part
,step
,t
,state_global
);
636 if (mdof_flags
& (MDOF_X
| MDOF_V
| MDOF_F
))
638 fwrite_trn(of
->fp_trn
,step
,t
,state_local
->lambda
,
639 state_local
->box
,top_global
->natoms
,
640 (mdof_flags
& MDOF_X
) ? state_global
->x
: NULL
,
641 (mdof_flags
& MDOF_V
) ? global_v
: NULL
,
642 (mdof_flags
& MDOF_F
) ? f_global
: NULL
);
643 if (gmx_fio_flush(of
->fp_trn
) != 0)
645 gmx_file("Cannot write trajectory; maybe you are out of quota?");
647 gmx_fio_check_file_position(of
->fp_trn
);
649 if (mdof_flags
& MDOF_XTC
) {
650 groups
= &top_global
->groups
;
654 for(i
=0; (i
<top_global
->natoms
); i
++)
656 if (ggrpnr(groups
,egcXTC
,i
) == 0)
661 if (*n_xtc
!= top_global
->natoms
)
666 if (*n_xtc
== top_global
->natoms
)
668 xxtc
= state_global
->x
;
674 for(i
=0; (i
<top_global
->natoms
); i
++)
676 if (ggrpnr(groups
,egcXTC
,i
) == 0)
678 copy_rvec(state_global
->x
[i
],xxtc
[j
++]);
682 if (write_xtc(of
->fp_xtc
,*n_xtc
,step
,t
,
683 state_local
->box
,xxtc
,of
->xtc_prec
) == 0)
685 gmx_fatal(FARGS
,"XTC error - maybe you are out of quota?");
687 gmx_fio_check_file_position(of
->fp_xtc
);