};
const char *esa_names[esaNR+1] = {
- "Ace-approx", "None", "Still", NULL
+ "Ace-approximation", "None", "Still", NULL
};
const char *ewt_names[ewtNR+1] = {
"distance", "direction", "cylinder", "position", "direction_periodic", NULL
};
+const char *erotg_names[erotgNR+1] = {
+ "iso", "iso-pf", "pm", "pm-pf", "rm", "rm-pf", "rm2", "rm2-pf", "flex", "flex-t", "flex2", "flex2-t", NULL
+};
+
+const char *erotg_fitnames[erotgFitNR+1] = {
+ "rmsd", "norm", NULL
+};
+
const char *eQMmethod_names[eQMmethodNR+1] = {
"AM1", "PM3", "RHF",
"UHF", "DFT", "B3LYP", "MP2", "CASSCF","B3LYPLAN",
pgutil.c
readir.c
readpull.c
+ readrot.c
resall.c
sorting.c
specbond.c
set(MDRUN_SOURCES
gctio.c ionize.c runner.c
do_gct.c repl_ex.c xutils.c
- md.c mdrun.c genalg.c md_openmm.c)
+ md.c mdrun.c genalg.c membed.c
+ md_openmm.c)
add_library(gmxpreprocess ${GMXPREPROCESS_SOURCES})
target_link_libraries(gmxpreprocess md)
else()
add_definitions( -DOPENMM_PLUGIN_DIR="" )
endif()
- add_library(openmm_api_wrapper openmm_wrapper.cpp)
- target_link_libraries(openmm_api_wrapper gmx gmx_gpu_utils ${OpenMM_LIBRARIES})
- # remove_definitions( -DOPENMM_PLUGIN_DIR="${OpenMM_PLUGIN_DIR}" ) # TODO where should this go?!
+ add_library(openmm_api_wrapper STATIC openmm_wrapper.cpp)
+ target_link_libraries(openmm_api_wrapper gmx_gpu_utils ${OpenMM_LIBRARIES})
set(GMX_OPENMM_LIBRARIES openmm_api_wrapper gmx_gpu_utils ${OpenMM_LIBRARIES})
- install(TARGETS openmm_api_wrapper DESTINATION ${LIB_INSTALL_DIR})
endif(GMX_OPENMM)
if(GMX_FAHCORE)
add_executable(mdrun ${MDRUN_SOURCES})
target_link_libraries(mdrun ${GMX_EXTRA_LIBRARIES} ${GMX_OPENMM_LIBRARIES})
- # set binary name to mdrun-gpu
- if(GMX_OPENMM)
- set(_mdrun_exec_name "mdrun-gpu")
- else()
- set(_mdrun_exec_name "mdrun${GMX_BINARY_SUFFIX}")
- endif()
- set_target_properties(mdrun PROPERTIES OUTPUT_NAME "${_mdrun_exec_name}")
+ set_target_properties(mdrun PROPERTIES OUTPUT_NAME "mdrun${GMX_BINARY_SUFFIX}")
# this is to circumvent the following MSVC error:
# warning LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs
RUNTIME DESTINATION ${BIN_INSTALL_DIR})
- get_target_property(MDRUN_PATH mdrun LOCATION)
+ # if we build shared gromacs libs, when installing throught the install-mdrun target
+ # these libs need to be installed as well
+ if(BUILD_SHARED_LIBS)
+ # in MDRUN_LIBS we store the libraries MDRUN links against (NOTE: hardcoded!!!)
+ set(MDRUN_LIBS gmxpreprocess md gmx)
+
+ # generate install-libXXX custom target for each shared lib that mdrun links against
+ foreach(_lib ${MDRUN_LIBS})
+ # double-check that the type is SHARED
+ get_target_property(_type ${_lib} TYPE)
+ if(NOT ${_type} STREQUAL "SHARED_LIBRARY")
+ message(FATAL_ERROR " Internal error: library ${_lib} is not shared so it's not supposed to be processed for installing")
+ endif()
+
+ # figure out the path and filename under which the lib will be installed
+ # (libname with pre- and suffix)
+ get_target_property(_lib_path ${_lib} LOCATION)
+ string(REGEX REPLACE "/" ";" _lib_fname ${_lib_path})
+ list(REVERSE _lib_fname)
+ list(GET _lib_fname 0 _lib_fname)
+
+ # create custom target for copying each library to the install location
+ # TODO: need to fix this to have the .so.6 form
+ add_custom_target(install-${_lib}
+ COMMAND ${CMAKE_COMMAND} -E copy
+ "${_lib_path}" "${LIB_INSTALL_DIR}/${_lib_fname}.${SOVERSION}"
+ COMMAND ${CMAKE_COMMAND} -E create_symlink
+ "${_lib_fname}.${SOVERSION}" "${LIB_INSTALL_DIR}/${_lib_fname}"
+ COMMENT "Installing library ${_lib}")
+ add_dependencies(install-${_lib} ${_lib})
+
+ # gather the custom target names in a string
+ # set(_lib_install_targets "${_lib_install_targets} install-lib${_lib}")
+ list(APPEND _lib_install_targets "install-${_lib}")
+ endforeach(_lib)
+ endif(BUILD_SHARED_LIBS)
+
+ get_target_property(_mdrun_path mdrun LOCATION)
add_custom_target(install-mdrun
- COMMAND ${CMAKE_COMMAND} -E copy "${MDRUN_PATH}"
- "${CMAKE_INSTALL_PREFIX}/bin/${_mdrun_exec_name}"
- DEPENDS mdrun
- COMMENT "Installing mdrun")
+ COMMAND ${CMAKE_COMMAND} -E copy "${_mdrun_path}"
+ "${BIN_INSTALL_DIR}/${_mdrun_exec_name}"
+ COMMENT "Installing mdrun")
+ add_dependencies(install-mdrun mdrun ${_lib_install_targets})
endif(GMX_FAHCORE)
pdb2top.c \
pgutil.c pgutil.h \
readir.c readir.h \
-readpull.c \
+readpull.c readrot.c \
resall.c \
sorting.c sorting.h \
specbond.c specbond.h \
g_x2top_SOURCES = g_x2top.c nm2type.c g_x2top.h
mdrun_SOURCES = \
- gctio.c gmx_membed.c gmx_membed.h \
+ gctio.c membed.c membed.h \
ionize.c ionize.h xmdrun.h \
do_gct.c repl_ex.c repl_ex.h \
xutils.c runner.c md.c mdrun.c \
}
}
+ static void check_bonds_timestep(gmx_mtop_t *mtop,double dt,warninp_t wi)
+ {
+ /* This check is not intended to ensure accurate integration,
+ * rather it is to signal mistakes in the mdp settings.
+ * A common mistake is to forget to turn on constraints
+ * for MD after energy minimization with flexible bonds.
+ * This check can also detect too large time steps for flexible water
+ * models, but such errors will often be masked by the constraints
+ * mdp options, which turns flexible water into water with bond constraints,
+ * but without an angle constraint. Unfortunately such incorrect use
+ * of water models can not easily be detected without checking
+ * for specific model names.
+ *
+ * The stability limit of leap-frog or velocity verlet is 4.44 steps
+ * per oscillational period.
+ * But accurate bonds distributions are lost far before that limit.
+ * To allow relatively common schemes (although not common with Gromacs)
+ * of dt=1 fs without constraints and dt=2 fs with only H-bond constraints
+ * we set the note limit to 10.
+ */
+ int min_steps_warn=5;
+ int min_steps_note=10;
+ t_iparams *ip;
+ int molt;
+ gmx_moltype_t *moltype,*w_moltype;
+ t_atom *atom;
+ t_ilist *ilist,*ilb,*ilc,*ils;
+ int ftype;
+ int i,a1,a2,w_a1,w_a2,j;
+ real twopi2,limit2,fc,re,m1,m2,period2,w_period2;
+ gmx_bool bFound,bWater,bWarn;
+ char warn_buf[STRLEN];
+
+ ip = mtop->ffparams.iparams;
+
+ twopi2 = sqr(2*M_PI);
+
+ limit2 = sqr(min_steps_note*dt);
+
+ w_a1 = w_a2 = -1;
+ w_period2 = -1.0;
+
+ w_moltype = NULL;
+ for(molt=0; molt<mtop->nmoltype; molt++)
+ {
+ moltype = &mtop->moltype[molt];
+ atom = moltype->atoms.atom;
+ ilist = moltype->ilist;
+ ilc = &ilist[F_CONSTR];
+ ils = &ilist[F_SETTLE];
+ for(ftype=0; ftype<F_NRE; ftype++)
+ {
+ if (!(ftype == F_BONDS || ftype == F_G96BONDS || ftype == F_HARMONIC))
+ {
+ continue;
+ }
+
+ ilb = &ilist[ftype];
+ for(i=0; i<ilb->nr; i+=3)
+ {
+ fc = ip[ilb->iatoms[i]].harmonic.krA;
+ re = ip[ilb->iatoms[i]].harmonic.rA;
+ if (ftype == F_G96BONDS)
+ {
+ /* Convert squared sqaure fc to harmonic fc */
+ fc = 2*fc*re;
+ }
+ a1 = ilb->iatoms[i+1];
+ a2 = ilb->iatoms[i+2];
+ m1 = atom[a1].m;
+ m2 = atom[a2].m;
+ if (fc > 0 && m1 > 0 && m2 > 0)
+ {
+ period2 = twopi2*m1*m2/((m1 + m2)*fc);
+ }
+ else
+ {
+ period2 = GMX_FLOAT_MAX;
+ }
+ if (debug)
+ {
+ fprintf(debug,"fc %g m1 %g m2 %g period %g\n",
+ fc,m1,m2,sqrt(period2));
+ }
+ if (period2 < limit2)
+ {
+ bFound = FALSE;
+ for(j=0; j<ilc->nr; j+=3)
+ {
+ if ((ilc->iatoms[j+1] == a1 && ilc->iatoms[j+2] == a2) ||
+ (ilc->iatoms[j+1] == a2 && ilc->iatoms[j+2] == a1))
+ {
+ bFound = TRUE;
+ }
+ }
+ for(j=0; j<ils->nr; j+=2)
+ {
+ if ((a1 >= ils->iatoms[j+1] && a1 < ils->iatoms[j+1]+3) &&
+ (a2 >= ils->iatoms[j+1] && a2 < ils->iatoms[j+1]+3))
+ {
+ bFound = TRUE;
+ }
+ }
+ if (!bFound &&
+ (w_moltype == NULL || period2 < w_period2))
+ {
+ w_moltype = moltype;
+ w_a1 = a1;
+ w_a2 = a2;
+ w_period2 = period2;
+ }
+ }
+ }
+ }
+ }
+
+ if (w_moltype != NULL)
+ {
+ bWarn = (w_period2 < sqr(min_steps_warn*dt));
+ /* A check that would recognize most water models */
+ bWater = ((*w_moltype->atoms.atomname[0])[0] == 'O' &&
+ w_moltype->atoms.nr <= 5);
+ sprintf(warn_buf,"The bond in molecule-type %s between atoms %d %s and %d %s has an estimated oscillational period of %.1e ps, which is less than %d times the time step of %.1e ps.\n"
+ "%s",
+ *w_moltype->name,
+ w_a1+1,*w_moltype->atoms.atomname[w_a1],
+ w_a2+1,*w_moltype->atoms.atomname[w_a2],
+ sqrt(w_period2),bWarn ? min_steps_warn : min_steps_note,dt,
+ bWater ?
+ "Maybe you asked for fexible water." :
+ "Maybe you forgot to change the constraints mdp option.");
+ if (bWarn)
+ {
+ warning(wi,warn_buf);
+ }
+ else
+ {
+ warning_note(wi,warn_buf);
+ }
+ }
+ }
+
static void check_vel(gmx_mtop_t *mtop,rvec v[])
{
gmx_mtop_atomloop_all_t aloop;
char warn_buf[STRLEN];
t_filenm fnm[] = {
- { efMDP, NULL, NULL, ffOPTRD },
+ { efMDP, NULL, NULL, ffREAD },
{ efMDP, "-po", "mdout", ffWRITE },
{ efSTX, "-c", NULL, ffREAD },
{ efSTX, "-r", NULL, ffOPTRD },
{ efTOP, "-pp", "processed", ffOPTWR },
{ efTPX, "-o", NULL, ffWRITE },
{ efTRN, "-t", NULL, ffOPTRD },
- { efEDR, "-e", NULL, ffOPTRD }
+ { efEDR, "-e", NULL, ffOPTRD },
+ { efTRN, "-ref","rotref", ffOPTRW }
};
#define NFILE asize(fnm)
check_cg_sizes(ftp2fn(efTOP,NFILE,fnm),&sys->moltype[i].cgs,wi);
}
+ if (EI_DYNAMICS(ir->eI) && ir->eI != eiBD)
+ {
+ check_bonds_timestep(sys,ir->delta_t,wi);
+ }
+
check_warning_error(wi,FARGS);
if (bVerbose)
if (ir->ePull != epullNO)
set_pull_init(ir,sys,state.x,state.box,oenv,opts->pull_start);
+
+ if (ir->bRot)
+ set_reference_positions(ir->rot,sys,state.x,state.box,opt2fn("-ref",NFILE,fnm),wi);
/* reset_multinr(sys); */
wall_atomtype[STRLEN],wall_density[STRLEN],deform[STRLEN],QMMM[STRLEN];
static char foreign_lambda[STRLEN];
static char **pull_grp;
+static char **rot_grp;
static char anneal[STRLEN],anneal_npoints[STRLEN],
anneal_time[STRLEN],anneal_temp[STRLEN];
static char QMmethod[STRLEN],QMbasis[STRLEN],QMcharge[STRLEN],QMmult[STRLEN],
snew(ir->pull,1);
pull_grp = read_pullparams(&ninp,&inp,ir->pull,&opts->pull_start,wi);
}
+
+ /* Enforced rotation */
+ CCTYPE("ENFORCED ROTATION");
+ CTYPE("Enforced rotation: No or Yes");
+ EETYPE("rotation", ir->bRot, yesno_names);
+ if (ir->bRot) {
+ snew(ir->rot,1);
+ rot_grp = read_rotparams(&ninp,&inp,ir->rot,wi);
+ }
/* Refinement */
CCTYPE("NMR refinement stuff");
if (ir->ePull != epullNO) {
make_pull_groups(ir->pull,pull_grp,grps,gnames);
}
+
+ if (ir->bRot) {
+ make_rotation_groups(ir->rot,rot_grp,grps,gnames);
+ }
nacc = str_nelem(acc,MAXPTR,ptr1);
nacg = str_nelem(accgrps,MAXPTR,ptr2);
* not be zero at the cut-off.
*/
if (EVDW_IS_ZERO_AT_CUTOFF(ir->vdwtype) &&
- rvdw1 + rvdw2 > ir->rlistlong - ir->rvdw)
+ rvdw1 + rvdw2 > ir->rlist - ir->rvdw)
{
- sprintf(warn_buf,"The sum of the two largest charge group radii (%f) is larger than %s (%f) - rvdw (%f)\n",
+ sprintf(warn_buf,"The sum of the two largest charge group radii (%f) is larger than rlist (%f) - rvdw (%f)\n",
rvdw1+rvdw2,
- ir->rlistlong > ir->rlist ? "rlistlong" : "rlist",
ir->rlist,ir->rvdw);
if (ir_NVE(ir))
{
#include "mdrun.h"
#include "network.h"
#include "pull.h"
++#include "pull_rotation.h"
#include "names.h"
#include "disre.h"
#include "orires.h"
#include "sighandler.h"
#include "tpxio.h"
#include "txtdump.h"
- #include "pull_rotation.h"
- #include "gmx_membed.h"
+ #include "membed.h"
+
#include "md_openmm.h"
#ifdef GMX_LIB_MPI
/* PME, if used, is done on all nodes with 1D decomposition */
cr->npmenodes = 0;
cr->duty = (DUTY_PP | DUTY_PME);
- npme_major = cr->nnodes;
+ npme_major = 1;
npme_minor = 1;
+ if (!EI_TPI(inputrec->eI))
+ {
+ npme_major = cr->nnodes;
+ }
if (inputrec->ePBC == epbcSCREW)
{
init_pull(fplog,inputrec,nfile,fnm,mtop,cr,oenv,
EI_DYNAMICS(inputrec->eI) && MASTER(cr),Flags);
}
+
+ if (inputrec->bRot)
+ {
+ /* Initialize enforced rotation code */
+ init_rot(fplog,inputrec,nfile,fnm,cr,state->x,state->box,mtop,oenv,
+ bVerbose,Flags);
+ }
constr = init_constraints(fplog,mtop,inputrec,ed,state,cr);
{
finish_pull(fplog,inputrec->pull);
}
+
+ if (inputrec->bRot)
+ {
+ finish_rot(fplog,inputrec->rot);
+ }
+
}
else
{
md->bEInd[i]=FALSE;
}
- for(i=0; i<F_NRE; i++) {
+ #ifndef GMX_OPENMM
+ for(i=0; i<F_NRE; i++)
+ {
md->bEner[i] = FALSE;
if (i == F_LJ)
md->bEner[i] = !bBHAM;
else if (i == F_CONNBONDS)
md->bEner[i] = FALSE;
else if (i == F_COM_PULL)
- md->bEner[i] = (ir->ePull == epullUMBRELLA || ir->ePull == epullCONST_F);
+ md->bEner[i] = (ir->ePull == epullUMBRELLA || ir->ePull == epullCONST_F || ir->bRot);
else if (i == F_ECONSERVED)
md->bEner[i] = ((ir->etc == etcNOSEHOOVER || ir->etc == etcVRESCALE) &&
(ir->epc == epcNO || ir->epc==epcMTTK));
else
md->bEner[i] = (gmx_mtop_ftype_count(mtop,i) > 0);
}
+ #else
+ /* OpenMM always produces only the following 4 energy terms */
+ md->bEner[F_EPOT] = TRUE;
+ md->bEner[F_EKIN] = TRUE;
+ md->bEner[F_ETOT] = TRUE;
+ md->bEner[F_TEMP] = TRUE;
+ #endif
md->f_nre=0;
for(i=0; i<F_NRE; i++)
#include <config.h>
#endif
+
+ #include <time.h>
+ #ifdef HAVE_SYS_TIME_H
+ #include <sys/time.h>
+ #endif
+
+
+
#include "statutil.h"
#include "typedefs.h"
#include "smalloc.h"
* not on mdrun command line options! */
static gmx_bool tpr_triggers_file(const char *opt)
{
- if ( (0 == strcmp(opt, "-pf"))
+ if ( (0 == strcmp(opt, "-ro"))
+ || (0 == strcmp(opt, "-ra"))
+ || (0 == strcmp(opt, "-rt"))
+ || (0 == strcmp(opt, "-rs"))
+ || (0 == strcmp(opt, "-pf"))
|| (0 == strcmp(opt, "-px")) )
return TRUE;
else
{ efXVG, "-runav", "runaver", ffOPTWR },
{ efXVG, "-px", "pullx", ffOPTWR },
{ efXVG, "-pf", "pullf", ffOPTWR },
+ { efXVG, "-ro", "rotation", ffOPTWR },
+ { efLOG, "-ra", "rotangles",ffOPTWR },
+ { efLOG, "-rs", "rotslabs", ffOPTWR },
+ { efLOG, "-rt", "rottorque",ffOPTWR },
{ efMTX, "-mtx", "nm", ffOPTWR },
{ efNDX, "-dn", "dipole", ffOPTWR },
/* Output files that are deleted after each benchmark run */
{ efXVG, "-brunav", "benchrnav",ffOPTWR },
{ efXVG, "-bpx", "benchpx", ffOPTWR },
{ efXVG, "-bpf", "benchpf", ffOPTWR },
+ { efXVG, "-bro", "benchrot", ffOPTWR },
+ { efLOG, "-bra", "benchrota",ffOPTWR },
+ { efLOG, "-brs", "benchrots",ffOPTWR },
+ { efLOG, "-brt", "benchrott",ffOPTWR },
{ efMTX, "-bmtx", "benchn", ffOPTWR },
{ efNDX, "-bdn", "bench", ffOPTWR }
};