extern "C" {
#endif
+GMX_LIBGMX_EXPORT
void init_disres(FILE *fplog,const gmx_mtop_t *mtop,
- t_inputrec *ir,const t_commrec *cr,gmx_bool bPartDecomp,
- t_fcdata *fcd,t_state *state);
+ t_inputrec *ir,const t_commrec *cr,gmx_bool bPartDecomp,
+ t_fcdata *fcd,t_state *state, gmx_bool bIsREMD);
/* Initiate *fcd data, must be called once, nbonds is the number
* of iatoms in the ilist of the idef struct.
* When time averaging is used, the history is initialized in state,
* unless it was read before from a checkpoint file.
+ * The implementation of distance restraints with -multi
+ * must differ according to whether REMD is active.
*/
+GMX_LIBGMX_EXPORT
void calc_disres_R_6(const gmx_multisim_t *ms,
int nfa,const t_iatom *fa,const t_iparams ip[],
const rvec *x,const t_pbc *pbc,
{
fprintf(fplog,"Found GMX_DISRE_ENSEMBLE_SIZE set to %d systems per ensemble\n",dd->nsystems);
}
- check_multi_int(fplog,cr->ms,dd->nsystems,
- "the number of systems per ensemble",
- FALSE);
+ /* This check is only valid on MASTER(cr), so probably
+ * ensemble-averaged distance restraints are broken on more
+ * than one processor per simulation system. */
+ if (MASTER(cr))
+ {
+ check_multi_int(fplog,cr->ms,dd->nsystems,
- "the number of systems per ensemble");
++ "the number of systems per ensemble",
++ FALSE);
+ }
+ gmx_bcast_sim(sizeof(int), &dd->nsystems, cr);
+
- if (dd->nsystems <= 0 || cr->ms->nsim % dd->nsystems != 0)
+ /* We use to allow any value of nsystems which was a divisor
+ * of ms->nsim. But this required an extra communicator which
+ * was stored in t_fcdata. This pulled in mpi.h in nearly all C files.
+ */
+ if (!(cr->ms->nsim == 1 || cr->ms->nsim == dd->nsystems))
{
- gmx_fatal(FARGS,"The number of systems %d is not divisible by the number of systems per ensemble %d\n",cr->ms->nsim,dd->nsystems);
+ gmx_fatal(FARGS,"GMX_DISRE_ENSEMBLE_SIZE (%d) is not equal to 1 or the number of systems (option -multi) %d",dd->nsystems,cr->ms->nsim);
}
-
- /* Split the inter-master communicator into different ensembles */
- MPI_Comm_split(cr->ms->mpi_comm_masters,
- cr->ms->sim/dd->nsystems,
- cr->ms->sim,
- &dd->mpi_comm_ensemble);
if (fplog)
{
fprintf(fplog,"Our ensemble consists of systems:");
if (fplog) {
fprintf(fplog,"There are %d distance restraints involving %d atom pairs\n",dd->nres,dd->npair);
}
- if (cr && cr->ms)
+ /* Have to avoid g_disre de-referencing cr blindly, mdrun not
+ * doing consistency checks for ensemble-averaged distance
+ * restraints when that's not happening, and only doing those
+ * checks from appropriate processes (since check_multi_int is
+ * too broken to check whether the communication will
+ * succeed...) */
+ if (cr && cr->ms && dd->nsystems > 1 && MASTER(cr))
{
check_multi_int(fplog,cr->ms,fcd->disres.nres,
- "the number of distance restraints");
+ "the number of distance restraints",
+ FALSE);
}
please_cite(fplog,"Tropp80a");
please_cite(fplog,"Torda89a");