#include "grompp.h"
+#include <array>
#include <cerrno>
#include <climits>
#include <cmath>
#include "gromacs/utility/listoflists.h"
#include "gromacs/utility/logger.h"
#include "gromacs/utility/loggerbuilder.h"
-#include "gromacs/utility/mdmodulenotification.h"
+#include "gromacs/utility/mdmodulesnotifiers.h"
#include "gromacs/utility/smalloc.h"
#include "gromacs/utility/snprintf.h"
InteractionOfType::InteractionOfType(gmx::ArrayRef<const int> atoms,
gmx::ArrayRef<const real> params,
const std::string& name) :
- atoms_(atoms.begin(), atoms.end()),
- interactionTypeName_(name)
+ atoms_(atoms.begin(), atoms.end()), interactionTypeName_(name)
{
GMX_RELEASE_ASSERT(
params.size() <= forceParam_.size(),
gmx::formatString("Cannot have more parameters than the maximum number possible (%d)", MAXFORCEPARAM)
.c_str());
- auto forceParamIt = forceParam_.begin();
+ std::array<real, MAXFORCEPARAM>::iterator forceParamIt = forceParam_.begin();
for (const auto param : params)
{
*forceParamIt++ = param;
/*! \brief Checks if the Verlet buffer and constraint accuracy is sufficient for decoupled dynamic modes.
*
- * When decoupled modes are present and the accuray in insufficient,
+ * When decoupled modes are present and the accuracy in insufficient,
* this routine issues a warning if the accuracy is insufficient.
*/
static void checkDecoupledModeAccuracy(const gmx_mtop_t* mtop, const t_inputrec* ir, warninp* wi)
{ efEDR, "-e", nullptr, ffOPTRD },
/* This group is needed by the VMD viewer as the start configuration for IMD sessions: */
{ efGRO, "-imd", "imdgroup", ffOPTWR },
- { efTRN, "-ref", "rotref", ffOPTRW | ffALLOW_MISSING } };
+ { efTRN, "-ref", "rotref", ffOPTRW | ffALLOW_MISSING },
+ /* This group is needed by the QMMM MDModule: */
+ { efQMI, "-qmi", nullptr, ffOPTRD } };
#define NFILE asize(fnm)
/* Command line options */
}
GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR
- // Now that the MdModules have their options assigned from get_ir, subscribe
+ // Now that the MDModules have their options assigned from get_ir, subscribe
// to eventual notifications during pre-processing their data
mdModules.subscribeToPreProcessingNotifications();
+ // Notify MDModules of existing logger
+ mdModules.notifiers().preProcessingNotifier_.notify(logger);
+
+ // Notify MDModules of existing warninp
+ mdModules.notifiers().preProcessingNotifier_.notify(wi);
+
+ // Notify QMMM MDModule of external QM input file command-line option
+ {
+ gmx::QMInputFileName qmInputFileName = { ftp2bSet(efQMI, NFILE, fnm), ftp2fn(efQMI, NFILE, fnm) };
+ mdModules.notifiers().preProcessingNotifier_.notify(qmInputFileName);
+ }
if (bVerbose)
{
.asParagraph()
.appendTextFormatted("checking input for internal consistency...");
}
- check_ir(mdparin, mdModules.notifier(), ir, opts, wi);
+ check_ir(mdparin, mdModules.notifiers(), ir, opts, wi);
if (ir->ld_seed == -1)
{
/* check masses */
check_mol(&sys, wi);
+ if (haveFepPerturbedMassesInSettles(sys))
+ {
+ warning_error(wi,
+ "SETTLE is not implemented for atoms whose mass is perturbed. "
+ "You might instead use normal constraints.");
+ }
+
checkForUnboundAtoms(&sys, bVerbose, wi, logger);
if (EI_DYNAMICS(ir->eI) && ir->eI != IntegrationAlgorithm::BD)
{
GMX_LOG(logger.info).asParagraph().appendTextFormatted("initialising group options...");
}
- do_index(mdparin, ftp2fn_null(efNDX, NFILE, fnm), &sys, bVerbose, mdModules.notifier(), ir, wi);
+ do_index(mdparin, ftp2fn_null(efNDX, NFILE, fnm), &sys, bVerbose, mdModules.notifiers(), ir, wi);
+
+ // Notify topology to MdModules for pre-processing after all indexes were built
+ mdModules.notifiers().preProcessingNotifier_.notify(&sys);
if (ir->cutoff_scheme == CutoffScheme::Verlet && ir->verletbuf_tol > 0)
{
{
/* Calculate the optimal grid dimensions */
matrix scaledBox;
- EwaldBoxZScaler boxScaler(*ir);
+ EwaldBoxZScaler boxScaler(inputrecPbcXY2Walls(ir), ir->wall_ewald_zfac);
boxScaler.scaleBox(state.box, scaledBox);
if (ir->nkx > 0 && ir->nky > 0 && ir->nkz > 0)
if (ir->bPull)
{
- pull = set_pull_init(ir,
- sys,
- state.x.rvec_array(),
- state.box,
- state.lambda[FreeEnergyPerturbationCouplingType::Mass],
- wi);
+ pull = set_pull_init(
+ ir, sys, state.x, state.box, state.lambda[FreeEnergyPerturbationCouplingType::Mass], wi);
}
/* Modules that supply external potential for pull coordinates
ir->pbcType,
compressibility,
&ir->opts,
- ir->efep != FreeEnergyPerturbationType::No
- ? ir->fepvals->all_lambda[static_cast<int>(FreeEnergyPerturbationCouplingType::Fep)]
- [ir->fepvals->init_fep_state]
- : 0,
+ ir->efep != FreeEnergyPerturbationType::No ? ir->fepvals->all_lambda[static_cast<int>(
+ FreeEnergyPerturbationCouplingType::Fep)][ir->fepvals->init_fep_state]
+ : 0,
sys,
wi);
}
}
}
+ // Hand over box and coordiantes to MdModules before they evaluate their final parameters
+ {
+ gmx::CoordinatesAndBoxPreprocessed coordinatesAndBoxPreprocessed;
+ coordinatesAndBoxPreprocessed.coordinates_ = state.x.arrayRefWithPadding();
+ copy_mat(state.box, coordinatesAndBoxPreprocessed.box_);
+ coordinatesAndBoxPreprocessed.pbc_ = ir->pbcType;
+ mdModules.notifiers().preProcessingNotifier_.notify(coordinatesAndBoxPreprocessed);
+ }
+
// Add the md modules internal parameters that are not mdp options
// e.g., atom indices
{
gmx::KeyValueTreeBuilder internalParameterBuilder;
- mdModules.notifier().preProcessingNotifications_.notify(internalParameterBuilder.rootObject());
+ mdModules.notifiers().preProcessingNotifier_.notify(internalParameterBuilder.rootObject());
ir->internalParameters =
std::make_unique<gmx::KeyValueTreeObject>(internalParameterBuilder.build());
}