include(gmxGetGmockTupleWorkaround)
get_gmock_tuple_workaround(GMOCK_COMPILE_DEFINITIONS)
-set(GMOCK_COMPILE_DEFINITIONS "_GNU_SOURCE=1;${GMOCK_COMPILE_DEFINITIONS}")
-set(GMOCK_COMPILE_DEFINITIONS ${GMOCK_COMPILE_DEFINITIONS} PARENT_SCOPE)
# GTest/GMock suggest linking with pthreads when available for thread safety
set(CMAKE_THREAD_PREFER_PTHREAD 1)
endif()
add_library(gmock STATIC ${UNITTEST_TARGET_OPTIONS} ${GMOCK_SOURCES} ${GTEST_SOURCES})
-set_property(TARGET gmock APPEND PROPERTY COMPILE_DEFINITIONS "${GMOCK_COMPILE_DEFINITIONS};GTEST_CAN_STREAM_RESULTS=0")
+set_property(TARGET gmock APPEND PROPERTY COMPILE_DEFINITIONS
- "_GNU_SOURCE=1;${GMOCK_COMPILE_DEFINITIONS}")
++ "_GNU_SOURCE=1;${GMOCK_COMPILE_DEFINITIONS};GTEST_CAN_STREAM_RESULTS=0")
set(GMOCK_LIBRARIES gmock ${PTHREADS_LIBRARIES} PARENT_SCOPE)
set(GTEST_LIBRARIES ${GMOCK_LIBRARIES} PARENT_SCOPE)
set(GMOCK_INCLUDE_DIRS ${GMOCK_INCLUDE_DIRS} PARENT_SCOPE)
set(GTEST_INCLUDE_DIRS ${GTEST_INCLUDE_DIRS} PARENT_SCOPE)
+set(GMOCK_COMPILE_DEFINITIONS ${GMOCK_COMPILE_DEFINITIONS} PARENT_SCOPE)
* To help us fund GROMACS development, we humbly ask that you cite
* the research papers on the package. Check out http://www.gromacs.org.
*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
+#include "gmxpre.h"
-#include <string.h>
#include <math.h>
+#include <stdlib.h>
+#include <string.h>
-#include "copyrite.h"
-#include "macros.h"
-#include "sysstuff.h"
-#include "gromacs/utility/smalloc.h"
-#include "typedefs.h"
+#include "gromacs/commandline/pargs.h"
+#include "gromacs/fileio/confio.h"
#include "gromacs/fileio/gmxfio.h"
+#include "gromacs/fileio/pdbio.h"
+#include "gromacs/fileio/tngio_for_tools.h"
#include "gromacs/fileio/tpxio.h"
-#include "gromacs/fileio/trxio.h"
#include "gromacs/fileio/trnio.h"
-#include "gromacs/fileio/tngio_for_tools.h"
-#include "gromacs/commandline/pargs.h"
-#include "gromacs/fileio/futil.h"
-#include "gromacs/fileio/pdbio.h"
-#include "gromacs/fileio/confio.h"
-#include "names.h"
-#include "index.h"
-#include "vec.h"
+#include "gromacs/fileio/trxio.h"
#include "gromacs/fileio/xtcio.h"
-#include "rmpbc.h"
-#include "pbc.h"
-#include "viewit.h"
-#include "xvgr.h"
-#include "gmx_ana.h"
-
+#include "gromacs/fileio/xvgr.h"
+#include "gromacs/gmxana/gmx_ana.h"
+#include "gromacs/legacyheaders/copyrite.h"
+#include "gromacs/legacyheaders/macros.h"
+#include "gromacs/legacyheaders/names.h"
+#include "gromacs/legacyheaders/typedefs.h"
+#include "gromacs/legacyheaders/viewit.h"
#include "gromacs/math/do_fit.h"
-#include "gmx_fatal.h"
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
+#include "gromacs/math/vec.h"
+#include "gromacs/pbcutil/pbc.h"
+#include "gromacs/pbcutil/rmpbc.h"
+#include "gromacs/topology/index.h"
+#include "gromacs/topology/topology.h"
+#include "gromacs/utility/fatalerror.h"
+#include "gromacs/utility/futil.h"
+#include "gromacs/utility/smalloc.h"
enum {
euSel, euRect, euTric, euCompact, euNR
{
if (debug)
{
- fprintf(debug, "\nShifting position of residue %d (atoms %u-%u) "
+ fprintf(debug, "\nShifting position of residue %d (atoms %d-%d) "
"by %g,%g,%g\n", atom[res_start].resind+1,
res_start+1, res_end+1, shift[XX], shift[YY], shift[ZZ]);
}
void check_trn(const char *fn)
{
- if ((fn2ftp(fn) != efTRJ) && (fn2ftp(fn) != efTRR))
+ if (fn2ftp(fn) != efTRR)
{
gmx_fatal(FARGS, "%s is not a trajectory file, exiting\n", fn);
}
}
-#ifndef GMX_NATIVE_WINDOWS
void do_trunc(const char *fn, real t0)
{
t_fileio *in;
gmx_fatal(FARGS, "You forgot to set the truncation time");
}
- /* Check whether this is a .trj file */
+ /* Check whether this is a .trr file */
check_trn(fn);
in = open_trn(fn, "r");
{
fprintf(stderr, "Once again, I'm gonna DO this...\n");
close_trn(in);
- if (0 != truncate(fn, fpos))
+ if (0 != gmx_truncate(fn, fpos))
{
gmx_fatal(FARGS, "Error truncating file %s", fn);
}
}
}
}
-#endif
/*! \brief Read a full molecular topology if useful and available.
*
"[PAR]",
"The following formats are supported for input and output:",
- "[TT].xtc[tt], [TT].trr[tt], [TT].trj[tt], [TT].gro[tt], [TT].g96[tt]",
+ "[TT].xtc[tt], [TT].trr[tt], [TT].gro[tt], [TT].g96[tt]",
"and [TT].pdb[tt].",
"The file formats are detected from the file extension.",
"The precision of [TT].xtc[tt] and [TT].gro[tt] output is taken from the",
"input file for [TT].xtc[tt], [TT].gro[tt] and [TT].pdb[tt],",
"and from the [TT]-ndec[tt] option for other input formats. The precision",
"is always taken from [TT]-ndec[tt], when this option is set.",
- "All other formats have fixed precision. [TT].trr[tt] and [TT].trj[tt]",
+ "All other formats have fixed precision. [TT].trr[tt]",
"output can be single or double precision, depending on the precision",
"of the [THISMODULE] binary.",
"Note that velocities are only supported in",
- "[TT].trr[tt], [TT].trj[tt], [TT].gro[tt] and [TT].g96[tt] files.[PAR]",
+ "[TT].trr[tt], [TT].gro[tt] and [TT].g96[tt] files.[PAR]",
"Option [TT]-sep[tt] can be used to write every frame to a separate",
"[TT].gro, .g96[tt] or [TT].pdb[tt] file. By default, all frames all written to one file.",
"can reduce the number of frames while using low-pass frequency",
"filtering, this reduces aliasing of high frequency motions.[PAR]",
- "Using [TT]-trunc[tt] [THISMODULE] can truncate [TT].trj[tt] in place, i.e.",
+ "Using [TT]-trunc[tt] [THISMODULE] can truncate [TT].trr[tt] in place, i.e.",
"without copying the file. This is useful when a run has crashed",
"during disk I/O (i.e. full disk), or when two contiguous",
"trajectories must be concatenated without having double frames.[PAR]",
{ &bVels }, "Read and write velocities if possible" },
{ "-force", FALSE, etBOOL,
{ &bForce }, "Read and write forces if possible" },
-#ifndef GMX_NATIVE_WINDOWS
{ "-trunc", FALSE, etTIME,
{ &ttrunc },
"Truncate input trajectory file after this time (%t)" },
-#endif
{ "-exec", FALSE, etSTR,
{ &exec_command },
"Execute command for every output frame with the "
if (!parse_common_args(&argc, argv,
PCA_CAN_BEGIN | PCA_CAN_END | PCA_CAN_VIEW |
- PCA_TIME_UNIT | PCA_BE_NICE,
+ PCA_TIME_UNIT,
NFILE, fnm, NPA, pa, asize(desc), desc,
0, NULL, &oenv))
{
if (ttrunc != -1)
{
-#ifndef GMX_NATIVE_WINDOWS
do_trunc(in_file, ttrunc);
-#endif
}
else
{
{
/* check if velocities are possible in input and output files */
ftpin = fn2ftp(in_file);
- bVels = (ftp == efTRR || ftp == efTRJ || ftp == efGRO ||
+ bVels = (ftp == efTRR || ftp == efGRO ||
ftp == efG96 || ftp == efTNG)
- && (ftpin == efTRR || ftpin == efTRJ || ftpin == efGRO ||
+ && (ftpin == efTRR || ftpin == efGRO ||
ftpin == efG96 || ftpin == efTNG || ftpin == efCPT);
}
if (bSeparate || bSplit)
{
gmx_fatal(FARGS, "Output file name '%s' does not contain a '.'", out_file);
}
- outf_base = strdup(out_file);
+ outf_base = gmx_strdup(out_file);
outf_base[outf_ext - out_file] = '\0';
}
useatoms.nr = nout;
}
/* select what to read */
- if (ftp == efTRR || ftp == efTRJ)
+ if (ftp == efTRR)
{
flags = TRX_READ_X;
}
break;
case efXTC:
case efTRR:
- case efTRJ:
out = NULL;
if (!bSplit && !bSubTraj)
{
write_tng_frame(trxout, &frout);
// TODO when trjconv behaves better: work how to read and write lambda
break;
- case efTRJ:
case efTRR:
case efXTC:
if (bSplitHere)
}
write_g96_conf(out, &frout, -1, NULL);
}
- if (bSeparate)
+ if (bSeparate || bSplitHere)
{
gmx_ffclose(out);
out = NULL;
char c[255];
sprintf(c, "%s %d", exec_command, file_nr-1);
/*fprintf(stderr,"Executing '%s'\n",c);*/
-#ifdef GMX_NO_SYSTEM
- printf("Warning-- No calls to system(3) supported on this platform.");
- printf("Warning-- Skipping execution of 'system(\"%s\")'.", c);
-#else
if (0 != system(c))
{
gmx_fatal(FARGS, "Error executing command: %s", c);
}
-#endif
}
outframe++;
}
/* The source code in this file should be thread-safe.
Please keep it that way. */
+#include "gmxpre.h"
+#include "gromacs/legacyheaders/checkpoint.h"
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
+#include "config.h"
+#include <errno.h>
+#include <stdlib.h>
#include <string.h>
-#include <time.h>
-
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
+#include <fcntl.h>
#ifdef GMX_NATIVE_WINDOWS
-/* _chsize_s */
#include <io.h>
#include <sys/locking.h>
#endif
-#include "copyrite.h"
-#include "names.h"
-#include "typedefs.h"
-#include "types/commrec.h"
-#include "gromacs/utility/smalloc.h"
-#include "txtdump.h"
-#include "vec.h"
-#include "network.h"
-#include "checkpoint.h"
-#include "main.h"
-#include "gromacs/utility/cstringutil.h"
-#include <fcntl.h>
-
+#include "buildinfo.h"
#include "gromacs/fileio/filenm.h"
-#include "gromacs/fileio/futil.h"
#include "gromacs/fileio/gmxfio.h"
-#include "gromacs/fileio/xdrf.h"
#include "gromacs/fileio/xdr_datatype.h"
+#include "gromacs/fileio/xdrf.h"
+#include "gromacs/legacyheaders/copyrite.h"
+#include "gromacs/legacyheaders/names.h"
+#include "gromacs/legacyheaders/network.h"
+#include "gromacs/legacyheaders/txtdump.h"
+#include "gromacs/legacyheaders/typedefs.h"
+#include "gromacs/legacyheaders/types/commrec.h"
+#include "gromacs/math/vec.h"
#include "gromacs/utility/baseversion.h"
-#include "gmx_fatal.h"
-
-#include "buildinfo.h"
+#include "gromacs/utility/cstringutil.h"
+#include "gromacs/utility/fatalerror.h"
+#include "gromacs/utility/futil.h"
+#include "gromacs/utility/smalloc.h"
+#include "gromacs/utility/sysinfo.h"
#ifdef GMX_FAHCORE
#include "corewrap.h"
"accumulated_plus", "accumulated_minus", "accumulated_plus_2", "accumulated_minus_2", "Tij", "Tij_empirical"
};
-#ifdef GMX_NATIVE_WINDOWS
-static int
-gmx_wintruncate(const char *filename, __int64 size)
-{
-#ifdef GMX_FAHCORE
- /*we do this elsewhere*/
- return 0;
-#else
- FILE *fp;
- int rc;
-
- fp = fopen(filename, "rb+");
-
- if (fp == NULL)
- {
- return -1;
- }
-
-#ifdef _MSC_VER
- return _chsize_s( fileno(fp), size);
-#else
- return _chsize( fileno(fp), size);
-#endif
-#endif
-}
-#endif
-
-
enum {
ecprREAL, ecprRVEC, ecprMATRIX
};
{
if (dtc == xdr_datatype_double)
{
+ /* cppcheck-suppress invalidPointerCast
+ * Only executed if real is anyhow double */
vd = (double *)vp;
}
else
static int do_cpte_real(XDR *xd, int cptp, int ecpt, int sflags,
real *r, FILE *list)
{
- int n;
-
return do_cpte_reals_low(xd, cptp, ecpt, sflags, 1, NULL, &r, list, ecprREAL);
}
bool_t res = 0;
int dtc = xdr_datatype_int;
int *vp, *va = NULL;
- int nf, dt, i;
+ int nf, dt;
nf = n;
res = xdr_int(xd, &nf);
bool_t res = 0;
int dtc = xdr_datatype_double;
double *vp, *va = NULL;
- int nf, dt, i;
+ int nf, dt;
nf = n;
res = xdr_int(xd, &nf);
static int do_cpte_rvecs(XDR *xd, int cptp, int ecpt, int sflags,
int n, rvec **v, FILE *list)
{
- int n3;
-
return do_cpte_reals_low(xd, cptp, ecpt, sflags,
n*DIM, NULL, (real **)v, list, ecprRVEC);
}
matrix v, FILE *list)
{
real *vr;
- real ret;
+ int ret;
vr = (real *)&(v[0][0]);
ret = do_cpte_reals_low(xd, cptp, ecpt, sflags,
int n, real **v, FILE *list)
{
int i;
- real *vr;
- real ret, reti;
+ int ret, reti;
char name[CPTSTRLEN];
ret = 0;
}
for (i = 0; i < n; i++)
{
- reti = 0;
- vr = v[i];
reti = do_cpte_reals_low(xd, cptp, ecpt, sflags, n, NULL, &(v[i]), NULL, ecprREAL);
if (list && reti == 0)
{
sprintf(name, "%s[%d]", st_names(cptp, ecpt), i);
pr_reals(list, 0, name, v[i], n);
}
- if (reti == 0)
+ if (reti != 0)
{
- ret = 0;
+ ret = reti;
}
}
return ret;
bool_t res = 0;
int magic;
int idum = 0;
- int i;
char *fhost;
if (bRead)
{
enerhist->ener_sum_sim[i] = enerhist->ener_sum[i];
}
- fflags |= (1<<eenhENERGY_SUM_SIM);
}
if ( (fflags & (1<<eenhENERGY_NSUM)) &&
{
/* Assume we have an old file format and copy nsum to nsteps */
enerhist->nsteps = enerhist->nsum;
- fflags |= (1<<eenhENERGY_NSTEPS);
}
if ( (fflags & (1<<eenhENERGY_NSUM_SIM)) &&
!(fflags & (1<<eenhENERGY_NSTEPS_SIM)))
{
/* Assume we have an old file format and copy nsum to nsteps */
enerhist->nsteps_sim = enerhist->nsum_sim;
- fflags |= (1<<eenhENERGY_NSTEPS_SIM);
}
return ret;
static int do_cpt_EDstate(XDR *xd, gmx_bool bRead,
edsamstate_t *EDstate, FILE *list)
{
- int i, j;
+ int i;
int ret = 0;
char buf[STRLEN];
gmx_file_position_t **p_outputfiles, int *nfiles,
FILE *list, int file_version)
{
- int i, j;
+ int i;
gmx_off_t offset;
gmx_off_t mask = 0xFFFFFFFFL;
int offset_high, offset_low;
int double_prec;
char *fprog;
char *fntemp; /* the temporary checkpoint file name */
- time_t now;
char timebuf[STRLEN];
- int nppnodes, npmenodes, flag_64bit;
+ int nppnodes, npmenodes;
char buf[1024], suffix[5+STEPSTRSIZE], sbuf[STEPSTRSIZE];
gmx_file_position_t *outputfiles;
int noutputfiles;
char *ftime;
- int flags_eks, flags_enh, flags_dfh, i;
+ int flags_eks, flags_enh, flags_dfh;
t_fileio *ret;
if (DOMAINDECOMP(cr))
snew(fntemp, strlen(fn));
strcpy(fntemp, fn);
#endif
- time(&now);
- gmx_ctime_r(&now, timebuf, STRLEN);
+ gmx_format_current_time(timebuf, STRLEN);
if (fplog)
{
*/
int gmx_major, gmx_minor;
int cpt_major, cpt_minor;
- sscanf(gmx_version(), "VERSION %d.%d", &gmx_major, &gmx_minor);
- sscanf(version, "VERSION %d.%d", &cpt_major, &cpt_minor);
+ sscanf(gmx_version(), "VERSION %5d.%5d", &gmx_major, &gmx_minor);
+ sscanf(version, "VERSION %5d.%5d", &cpt_major, &cpt_minor);
version_differs = (gmx_major != cpt_major || gmx_minor != cpt_minor);
}
int file_version;
char *version, *btime, *buser, *bhost, *fprog, *ftime;
int double_prec;
- char filename[STRLEN], buf[STEPSTRSIZE];
- int nppnodes, eIntegrator_f, nppnodes_f, npmenodes_f;
+ char buf[STEPSTRSIZE];
+ int eIntegrator_f, nppnodes_f, npmenodes_f;
ivec dd_nc_f;
int natoms, ngtc, nnhpres, nhchainlength, nlambda, fflags, flags_eks, flags_enh, flags_dfh;
int d;
if (!PAR(cr))
{
- nppnodes = 1;
cr->npmenodes = 0;
}
else if (cr->nnodes == nppnodes_f + npmenodes_f)
{
cr->npmenodes = npmenodes_f;
}
- nppnodes = cr->nnodes - cr->npmenodes;
+ int nppnodes = cr->nnodes - cr->npmenodes;
if (nppnodes == nppnodes_f)
{
for (d = 0; d < DIM; d++)
}
}
}
- else
- {
- /* The number of PP nodes has not been set yet */
- nppnodes = -1;
- }
if (fflags != state->flags)
{
cp_error();
}
- ret = do_cpt_swapstate(gmx_fio_getxdr(fp), TRUE, &state->swapstate, NULL);
+ ret = do_cpt_EDstate(gmx_fio_getxdr(fp), TRUE, &state->edsamstate, NULL);
if (ret)
{
cp_error();
}
- ret = do_cpt_EDstate(gmx_fio_getxdr(fp), TRUE, &state->edsamstate, NULL);
+ ret = do_cpt_swapstate(gmx_fio_getxdr(fp), TRUE, &state->swapstate, NULL);
if (ret)
{
cp_error();
if (i != 0) /*log file is already seeked to correct position */
{
-#ifdef GMX_NATIVE_WINDOWS
- rc = gmx_wintruncate(outputfiles[i].filename, outputfiles[i].offset);
-#else
- rc = truncate(outputfiles[i].filename, outputfiles[i].offset);
-#endif
+#if !defined(GMX_NATIVE_WINDOWS) || !defined(GMX_FAHCORE)
+ /* For FAHCORE, we do this elsewhere*/
+ rc = gmx_truncate(outputfiles[i].filename, outputfiles[i].offset);
if (rc != 0)
{
gmx_fatal(FARGS, "Truncation of file %s failed. Cannot do appending because of this failure.", outputfiles[i].filename);
}
+#endif
}
}
}
ivec dd_nc;
t_state state;
int flags_eks, flags_enh, flags_dfh;
- int indent;
- int i, j;
int ret;
gmx_file_position_t *outputfiles;
int nfiles;
* To help us fund GROMACS development, we humbly ask that you cite
* the research papers on the package. Check out http://www.gromacs.org.
*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
+#include "gmxpre.h"
+
+#include "calc_verletbuf.h"
#include <assert.h>
+#include <math.h>
+#include <stdlib.h>
#include <sys/types.h>
-#include <math.h>
-#include "typedefs.h"
-#include "physics.h"
+
+#include "gromacs/ewald/ewald-util.h"
+#include "gromacs/legacyheaders/macros.h"
+#include "gromacs/legacyheaders/typedefs.h"
+#include "gromacs/math/units.h"
+#include "gromacs/math/vec.h"
+#include "gromacs/mdlib/nbnxn_consts.h"
+#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/smalloc.h"
-#include "gmx_fatal.h"
-#include "macros.h"
-#include "vec.h"
-#include "coulomb.h"
-#include "calc_verletbuf.h"
-#include "../mdlib/nbnxn_consts.h"
#ifdef GMX_NBNXN_SIMD
/* The include below sets the SIMD instruction type (precision+width)
for (i = 0; i < il->nr; i += 1+NRAL(ft))
{
const t_iparams *ip;
- real cam[5] = {0}, inv_mass, m_aj;
- int a1, j, aj, coeff;
- real cam[5], inv_mass, coeff, m_aj;
++ real cam[5] = {0}, inv_mass, coeff, m_aj;
+ int a1, j, aj;
ip = &ffparams->iparams[il->iatoms[i]];
case F_VSITEN:
/* Exact */
inv_mass = 0;
- for (j = 0; j < 3*ip->vsiten.n; j += 3)
+ for (j = 0; j < 3*ffparams->iparams[il->iatoms[i]].vsiten.n; j += 3)
{
aj = il->iatoms[i+j+2];
- coeff = ip[il->iatoms[i+j]].vsiten.a;
+ coeff = ffparams->iparams[il->iatoms[i+j]].vsiten.a;
if (moltype->atoms.atom[aj].ptype == eptVSite)
{
m_aj = vsite_m[aj];
add_at(&att, &natt, &prop[a], nmol);
}
+ /* cppcheck-suppress uninitvar Fixed in cppcheck 1.65 */
sfree(vsite_m);
sfree(prop);
}
* To help us fund GROMACS development, we humbly ask that you cite
* the research papers on the package. Check out http://www.gromacs.org.
*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
+#include "gmxpre.h"
+
+#include "gromacs/legacyheaders/sim_util.h"
+
+#include "config.h"
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-
-#include "typedefs.h"
-#include "gromacs/utility/cstringutil.h"
-#include "gromacs/utility/smalloc.h"
-#include "names.h"
-#include "txtdump.h"
-#include "pbc.h"
-#include "chargegroup.h"
-#include "vec.h"
-#include "nrnb.h"
-#include "mshift.h"
-#include "mdrun.h"
-#include "sim_util.h"
-#include "update.h"
-#include "physics.h"
-#include "main.h"
-#include "mdatoms.h"
-#include "force.h"
-#include "bondf.h"
-#include "pme.h"
-#include "disre.h"
-#include "orires.h"
-#include "network.h"
-#include "calcmu.h"
-#include "constr.h"
-#include "xvgr.h"
-#include "copyrite.h"
-#include "domdec.h"
-#include "genborn.h"
-#include "nbnxn_atomdata.h"
-#include "nbnxn_search.h"
-#include "nbnxn_kernels/nbnxn_kernel_ref.h"
-#include "nbnxn_kernels/simd_4xn/nbnxn_kernel_simd_4xn.h"
-#include "nbnxn_kernels/simd_2xnn/nbnxn_kernel_simd_2xnn.h"
-#include "nbnxn_kernels/nbnxn_kernel_gpu_ref.h"
-#include "nonbonded.h"
-#include "../gmxlib/nonbonded/nb_kernel.h"
-#include "../gmxlib/nonbonded/nb_free_energy.h"
-#include "gromacs/timing/wallcycle.h"
-#include "gromacs/timing/walltime_accounting.h"
-#include "gromacs/utility/gmxmpi.h"
#include "gromacs/essentialdynamics/edsam.h"
+#include "gromacs/ewald/pme.h"
+#include "gromacs/gmxlib/nonbonded/nb_free_energy.h"
+#include "gromacs/gmxlib/nonbonded/nb_kernel.h"
+#include "gromacs/imd/imd.h"
+#include "gromacs/legacyheaders/calcmu.h"
+#include "gromacs/legacyheaders/chargegroup.h"
+#include "gromacs/legacyheaders/constr.h"
+#include "gromacs/legacyheaders/copyrite.h"
+#include "gromacs/legacyheaders/disre.h"
+#include "gromacs/legacyheaders/domdec.h"
+#include "gromacs/legacyheaders/force.h"
+#include "gromacs/legacyheaders/genborn.h"
+#include "gromacs/legacyheaders/gmx_omp_nthreads.h"
+#include "gromacs/legacyheaders/mdatoms.h"
+#include "gromacs/legacyheaders/mdrun.h"
+#include "gromacs/legacyheaders/names.h"
+#include "gromacs/legacyheaders/network.h"
+#include "gromacs/legacyheaders/nonbonded.h"
+#include "gromacs/legacyheaders/nrnb.h"
+#include "gromacs/legacyheaders/orires.h"
+#include "gromacs/legacyheaders/qmmm.h"
+#include "gromacs/legacyheaders/txtdump.h"
+#include "gromacs/legacyheaders/typedefs.h"
+#include "gromacs/legacyheaders/update.h"
+#include "gromacs/legacyheaders/types/commrec.h"
+#include "gromacs/listed-forces/bonded.h"
+#include "gromacs/math/units.h"
+#include "gromacs/math/vec.h"
+#include "gromacs/mdlib/nb_verlet.h"
+#include "gromacs/mdlib/nbnxn_atomdata.h"
+#include "gromacs/mdlib/nbnxn_search.h"
+#include "gromacs/mdlib/nbnxn_cuda/nbnxn_cuda.h"
+#include "gromacs/mdlib/nbnxn_cuda/nbnxn_cuda_data_mgmt.h"
+#include "gromacs/mdlib/nbnxn_kernels/nbnxn_kernel_gpu_ref.h"
+#include "gromacs/mdlib/nbnxn_kernels/nbnxn_kernel_ref.h"
+#include "gromacs/mdlib/nbnxn_kernels/simd_2xnn/nbnxn_kernel_simd_2xnn.h"
+#include "gromacs/mdlib/nbnxn_kernels/simd_4xn/nbnxn_kernel_simd_4xn.h"
+#include "gromacs/pbcutil/ishift.h"
+#include "gromacs/pbcutil/mshift.h"
+#include "gromacs/pbcutil/pbc.h"
#include "gromacs/pulling/pull.h"
#include "gromacs/pulling/pull_rotation.h"
-#include "gromacs/imd/imd.h"
-#include "adress.h"
-#include "qmmm.h"
-
-#include "gmx_omp_nthreads.h"
+#include "gromacs/timing/wallcycle.h"
+#include "gromacs/timing/walltime_accounting.h"
+#include "gromacs/utility/cstringutil.h"
+#include "gromacs/utility/gmxmpi.h"
+#include "gromacs/utility/smalloc.h"
+#include "gromacs/utility/sysinfo.h"
-#include "nbnxn_cuda_data_mgmt.h"
-#include "nbnxn_cuda/nbnxn_cuda.h"
+#include "adress.h"
void print_time(FILE *out,
gmx_walltime_accounting_t walltime_accounting,
tensor vir_part, t_graph *graph, matrix box,
t_nrnb *nrnb, const t_forcerec *fr, int ePBC)
{
- int i, j;
- tensor virtest;
+ int i;
/* The short-range virial from surrounding boxes */
clear_mat(vir_part);
}
}
-static void posres_wrapper(FILE *fplog,
- int flags,
- gmx_bool bSepDVDL,
+static void posres_wrapper(int flags,
t_inputrec *ir,
t_nrnb *nrnb,
gmx_localtop_t *top,
ir->ePBC == epbcNONE ? NULL : &pbc,
lambda[efptRESTRAINT], &dvdl,
fr->rc_scaling, fr->ePBC, fr->posres_com, fr->posres_comB);
- if (bSepDVDL)
- {
- gmx_print_sepdvdl(fplog, interaction_function[F_POSRES].longname, v, dvdl);
- }
enerd->term[F_POSRES] += v;
/* If just the force constant changes, the FEP term is linear,
* but if k changes, it is not.
{
for (i = 0; i < enerd->n_lambda; i++)
{
- real dvdl_dum, lambda_dum;
+ real lambda_dum;
lambda_dum = (i == 0 ? lambda[efptRESTRAINT] : ir->fepvals->all_lambda[efptRESTRAINT][i-1]);
v = posres(top->idef.il[F_POSRES].nr, top->idef.il[F_POSRES].iatoms,
inc_nrnb(nrnb, eNR_FBPOSRES, top->idef.il[F_FBPOSRES].nr/2);
}
-static void pull_potential_wrapper(FILE *fplog,
- gmx_bool bSepDVDL,
- t_commrec *cr,
+static void pull_potential_wrapper(t_commrec *cr,
t_inputrec *ir,
matrix box, rvec x[],
rvec f[],
enerd->term[F_COM_PULL] +=
pull_potential(ir->ePull, ir->pull, mdatoms, &pbc,
cr, t, lambda[efptRESTRAINT], x, f, vir_force, &dvdl);
- if (bSepDVDL)
- {
- gmx_print_sepdvdl(fplog, "Com pull", enerd->term[F_COM_PULL], dvdl);
- }
enerd->dvdl_lin[efptRESTRAINT] += dvdl;
wallcycle_stop(wcycle, ewcPULLPOT);
}
-static void pme_receive_force_ener(FILE *fplog,
- gmx_bool bSepDVDL,
- t_commrec *cr,
+static void pme_receive_force_ener(t_commrec *cr,
gmx_wallcycle_t wcycle,
gmx_enerdata_t *enerd,
t_forcerec *fr)
{
- real e_q, e_lj, v, dvdl_q, dvdl_lj;
+ real e_q, e_lj, dvdl_q, dvdl_lj;
float cycles_ppdpme, cycles_seppme;
cycles_ppdpme = wallcycle_stop(wcycle, ewcPPDURINGPME);
gmx_pme_receive_f(cr, fr->f_novirsum, fr->vir_el_recip, &e_q,
fr->vir_lj_recip, &e_lj, &dvdl_q, &dvdl_lj,
&cycles_seppme);
- if (bSepDVDL)
- {
- gmx_print_sepdvdl(fplog, "Electrostatic PME mesh", e_q, dvdl_q);
- gmx_print_sepdvdl(fplog, "Lennard-Jones PME mesh", e_lj, dvdl_lj);
- }
enerd->term[F_COUL_RECIP] += e_q;
enerd->term[F_LJ_RECIP] += e_lj;
enerd->dvdl_lin[efptCOUL] += dvdl_q;
t_nrnb *nrnb,
gmx_wallcycle_t wcycle)
{
- int nnbl, kernel_type, enr_nbnxn_kernel_ljc, enr_nbnxn_kernel_lj;
- char *env;
+ int enr_nbnxn_kernel_ljc, enr_nbnxn_kernel_lj;
nonbonded_verlet_group_t *nbvg;
gmx_bool bCUDA;
wallcycle_sub_stop(wcycle, ewcsNONBONDED);
}
+gmx_bool use_GPU(const nonbonded_verlet_t *nbv)
+{
+ return nbv != NULL && nbv->bUseGPU;
+}
+
void do_force_cutsVERLET(FILE *fplog, t_commrec *cr,
t_inputrec *inputrec,
gmx_int64_t step, t_nrnb *nrnb, gmx_wallcycle_t wcycle,
gmx_bool bBornRadii,
int flags)
{
- int cg0, cg1, i, j;
+ int cg1, i, j;
int start, homenr;
- int nb_kernel_type;
double mu[2*DIM];
- gmx_bool bSepDVDL, bStateChanged, bNS, bFillGrid, bCalcCGCM, bBS;
+ gmx_bool bStateChanged, bNS, bFillGrid, bCalcCGCM;
gmx_bool bDoLongRange, bDoForces, bSepLRF, bUseGPU, bUseOrEmulGPU;
gmx_bool bDiffKernels = FALSE;
- matrix boxs;
rvec vzero, box_diag;
- real e, v, dvdl;
float cycles_pme, cycles_force, cycles_wait_gpu;
nonbonded_verlet_t *nbv;
cycles_force = 0;
cycles_wait_gpu = 0;
nbv = fr->nbv;
- nb_kernel_type = fr->nbv->grp[0].kernel_type;
start = 0;
homenr = mdatoms->homenr;
- bSepDVDL = (fr->bSepDVDL && do_per_step(step, inputrec->nstlog));
-
clear_mat(vir_force);
- cg0 = 0;
if (DOMAINDECOMP(cr))
{
cg1 = cr->dd->ncg_tot;
#ifdef GMX_MPI
if (!(cr->duty & DUTY_PME))
{
+ gmx_bool bBS;
+ matrix boxs;
+
/* Send particle coordinates to the pme nodes.
* Since this is only implemented for domain decomposition
* and domain decomposition does not use the graph,
}
/* We calculate the non-bonded forces, when done on the CPU, here.
- * We do this before calling do_force_lowlevel, as in there bondeds
- * forces are calculated before PME, which does communication.
- * With this order, non-bonded and bonded force calculation imbalance
- * can be balanced out by the domain decomposition load balancing.
+ * We do this before calling do_force_lowlevel, because in that
+ * function, the listed forces are calculated before PME, which
+ * does communication. With this order, non-bonded and listed
+ * force calculation imbalance can be balanced out by the domain
+ * decomposition load balancing.
*/
if (!bUseOrEmulGPU)
update_QMMMrec(cr, fr, x, mdatoms, box, top);
}
- if ((flags & GMX_FORCE_BONDED) && top->idef.il[F_POSRES].nr > 0)
+ if ((flags & GMX_FORCE_LISTED) && top->idef.il[F_POSRES].nr > 0)
{
- posres_wrapper(fplog, flags, bSepDVDL, inputrec, nrnb, top, box, x,
+ posres_wrapper(flags, inputrec, nrnb, top, box, x,
enerd, lambda, fr);
}
- if ((flags & GMX_FORCE_BONDED) && top->idef.il[F_FBPOSRES].nr > 0)
+ if ((flags & GMX_FORCE_LISTED) && top->idef.il[F_FBPOSRES].nr > 0)
{
fbposres_wrapper(inputrec, nrnb, top, box, x, enerd, fr);
}
/* Compute the bonded and non-bonded energies and optionally forces */
- do_force_lowlevel(fplog, step, fr, inputrec, &(top->idef),
+ do_force_lowlevel(fr, inputrec, &(top->idef),
cr, nrnb, wcycle, mdatoms,
x, hist, f, bSepLRF ? fr->f_twin : f, enerd, fcd, top, fr->born,
- &(top->atomtypes), bBornRadii, box,
+ bBornRadii, box,
inputrec->fepvals, lambda, graph, &(top->excls), fr->mu_tot,
flags, &cycles_pme);
/* Communicate the forces */
wallcycle_start(wcycle, ewcMOVEF);
dd_move_f(cr->dd, f, fr->fshift);
- /* Do we need to communicate the separate force array
- * for terms that do not contribute to the single sum virial?
- * Position restraints and electric fields do not introduce
- * inter-cg forces, only full electrostatics methods do.
- * When we do not calculate the virial, fr->f_novirsum = f,
- * so we have already communicated these forces.
- */
- if (EEL_FULL(fr->eeltype) && cr->dd->n_intercg_excl &&
- (flags & GMX_FORCE_VIRIAL))
- {
- dd_move_f(cr->dd, fr->f_novirsum, NULL);
- }
if (bSepLRF)
{
/* We should not update the shift forces here,
}
/* If we have NoVirSum forces, but we do not calculate the virial,
- * we sum fr->f_novirum=f later.
+ * we sum fr->f_novirsum=f later.
*/
if (vsite && !(fr->bF_NoVirSum && !(flags & GMX_FORCE_VIRIAL)))
{
/* Since the COM pulling is always done mass-weighted, no forces are
* applied to vsites and this call can be done after vsite spreading.
*/
- pull_potential_wrapper(fplog, bSepDVDL, cr, inputrec, box, x,
+ pull_potential_wrapper(cr, inputrec, box, x,
f, vir_force, mdatoms, enerd, lambda, t,
wcycle);
}
/* In case of node-splitting, the PP nodes receive the long-range
* forces, virial and energy from the PME nodes here.
*/
- pme_receive_force_ener(fplog, bSepDVDL, cr, wcycle, enerd, fr);
+ pme_receive_force_ener(cr, wcycle, enerd, fr);
}
if (bDoForces)
int cg0, cg1, i, j;
int start, homenr;
double mu[2*DIM];
- gmx_bool bSepDVDL, bStateChanged, bNS, bFillGrid, bCalcCGCM, bBS;
- gmx_bool bDoLongRangeNS, bDoForces, bDoPotential, bSepLRF;
+ gmx_bool bStateChanged, bNS, bFillGrid, bCalcCGCM;
+ gmx_bool bDoLongRangeNS, bDoForces, bSepLRF;
gmx_bool bDoAdressWF;
- matrix boxs;
- rvec vzero, box_diag;
- real e, v, dvdlambda[efptNR];
t_pbc pbc;
float cycles_pme, cycles_force;
start = 0;
homenr = mdatoms->homenr;
- bSepDVDL = (fr->bSepDVDL && do_per_step(step, inputrec->nstlog));
-
clear_mat(vir_force);
cg0 = 0;
bFillGrid = (bNS && bStateChanged);
bCalcCGCM = (bFillGrid && !DOMAINDECOMP(cr));
bDoForces = (flags & GMX_FORCE_FORCES);
- bDoPotential = (flags & GMX_FORCE_ENERGY);
bSepLRF = ((inputrec->nstcalclr > 1) && bDoForces &&
(flags & GMX_FORCE_SEPLRF) && (flags & GMX_FORCE_DO_LR));
#ifdef GMX_MPI
if (!(cr->duty & DUTY_PME))
{
+ gmx_bool bBS;
+ matrix boxs;
+
/* Send particle coordinates to the pme nodes.
* Since this is only implemented for domain decomposition
* and domain decomposition does not use the graph,
update_QMMMrec(cr, fr, x, mdatoms, box, top);
}
- if ((flags & GMX_FORCE_BONDED) && top->idef.il[F_POSRES].nr > 0)
+ if ((flags & GMX_FORCE_LISTED) && top->idef.il[F_POSRES].nr > 0)
{
- posres_wrapper(fplog, flags, bSepDVDL, inputrec, nrnb, top, box, x,
+ posres_wrapper(flags, inputrec, nrnb, top, box, x,
enerd, lambda, fr);
}
- if ((flags & GMX_FORCE_BONDED) && top->idef.il[F_FBPOSRES].nr > 0)
+ if ((flags & GMX_FORCE_LISTED) && top->idef.il[F_FBPOSRES].nr > 0)
{
fbposres_wrapper(inputrec, nrnb, top, box, x, enerd, fr);
}
/* Compute the bonded and non-bonded energies and optionally forces */
- do_force_lowlevel(fplog, step, fr, inputrec, &(top->idef),
+ do_force_lowlevel(fr, inputrec, &(top->idef),
cr, nrnb, wcycle, mdatoms,
x, hist, f, bSepLRF ? fr->f_twin : f, enerd, fcd, top, fr->born,
- &(top->atomtypes), bBornRadii, box,
+ bBornRadii, box,
inputrec->fepvals, lambda,
graph, &(top->excls), fr->mu_tot,
flags,
}
/* If we have NoVirSum forces, but we do not calculate the virial,
- * we sum fr->f_novirum=f later.
+ * we sum fr->f_novirsum=f later.
*/
if (vsite && !(fr->bF_NoVirSum && !(flags & GMX_FORCE_VIRIAL)))
{
if (inputrec->ePull == epullUMBRELLA || inputrec->ePull == epullCONST_F)
{
- pull_potential_wrapper(fplog, bSepDVDL, cr, inputrec, box, x,
+ pull_potential_wrapper(cr, inputrec, box, x,
f, vir_force, mdatoms, enerd, lambda, t,
wcycle);
}
/* In case of node-splitting, the PP nodes receive the long-range
* forces, virial and energy from the PME nodes here.
*/
- pme_receive_force_ener(fplog, bSepDVDL, cr, wcycle, enerd, fr);
+ pme_receive_force_ener(cr, wcycle, enerd, fr);
}
if (bDoForces)
double invscale, invscale2, invscale3;
double r, ea, eb, ec, pa, pb, pc, pd;
double y0, f, g, h;
- int ri, offset, tabfactor;
+ int ri, offset;
+ double tabfactor;
invscale = 1.0/scale;
invscale2 = invscale*invscale;
void calc_enervirdiff(FILE *fplog, int eDispCorr, t_forcerec *fr)
{
- double eners[2], virs[2], enersum, virsum, y0, f, g, h;
- double r0, r1, r, rc3, rc9, ea, eb, ec, pa, pb, pc, pd;
- double invscale, invscale2, invscale3;
- int ri0, ri1, ri, i, offstart, offset;
- real scale, *vdwtab, tabfactor, tmp;
+ double eners[2], virs[2], enersum, virsum;
+ double r0, rc3, rc9;
+ int ri0, ri1, i;
+ real scale, *vdwtab;
fr->enershiftsix = 0;
fr->enershifttwelve = 0;
vdwtab = fr->nblists[0].table_vdw.data;
/* Round the cut-offs to exact table values for precision */
- ri0 = floor(fr->rvdw_switch*scale);
- ri1 = ceil(fr->rvdw*scale);
+ ri0 = static_cast<int>(floor(fr->rvdw_switch*scale));
+ ri1 = static_cast<int>(ceil(fr->rvdw*scale));
/* The code below has some support for handling force-switching, i.e.
* when the force (instead of potential) is switched over a limited
ri0 = (fr->vdw_modifier == eintmodPOTSHIFT) ? ri1 : ri0;
r0 = ri0/scale;
- r1 = ri1/scale;
rc3 = r0*r0*r0;
rc9 = rc3*rc3*rc3;
}
}
-void calc_dispcorr(FILE *fplog, t_inputrec *ir, t_forcerec *fr,
- gmx_int64_t step, int natoms,
+void calc_dispcorr(t_inputrec *ir, t_forcerec *fr,
+ int natoms,
matrix box, real lambda, tensor pres, tensor virial,
real *prescorr, real *enercorr, real *dvdlcorr)
{
}
}
- if (fr->bSepDVDL && do_per_step(step, ir->nstlog))
- {
- gmx_print_sepdvdl(fplog, "Dispersion correction", *enercorr, dvdlambda);
- }
if (fr->efep != efepNO)
{
*dvdlcorr += dvdlambda;
t_inputrec *inputrec,
t_nrnb nrnb[], gmx_wallcycle_t wcycle,
gmx_walltime_accounting_t walltime_accounting,
- wallclock_gpu_t *gputimes,
+ nonbonded_verlet_t *nbv,
gmx_bool bWriteStat)
{
- int i, j;
t_nrnb *nrnb_tot = NULL;
- real delta_t;
- double nbfs, mflop;
+ double delta_t = 0;
+ double nbfs = 0, mflop = 0;
double elapsed_time,
elapsed_time_over_all_ranks,
elapsed_time_over_all_threads,
if (SIMMASTER(cr))
{
+ wallclock_gpu_t* gputimes = use_GPU(nbv) ?
+ nbnxn_cuda_get_timings(nbv->cu_nbv) : NULL;
wallcycle_print(fplog, cr->nnodes, cr->npmenodes,
elapsed_time_over_all_ranks,
wcycle, gputimes);
{
delta_t = inputrec->delta_t;
}
- else
- {
- delta_t = 0;
- }
if (fplog)
{
gmx_bool *bSimAnn, t_vcm **vcm, unsigned long Flags,
gmx_wallcycle_t wcycle)
{
- int i, j, n;
- real tmpt, mod;
+ int i;
/* Initial values */
*t = *t0 = ir->init_t;
* The grid implementation could still be optimized in several different ways:
* - Triclinic grid cells are not the most efficient shape, but make PBC
* handling easier.
- * - Precalculating the required PBC shift for a pair of cells outside the
- * inner loop. After this is done, it should be quite straightforward to
- * move to rectangular cells.
* - Pruning grid cells from the search list if they are completely outside
* the sphere that is being considered.
* - A better heuristic could be added for falling back to simple loops for a
* \author Teemu Murtola <teemu.murtola@gmail.com>
* \ingroup module_selection
*/
-#include "gromacs/selection/nbsearch.h"
+#include "gmxpre.h"
-#include <math.h>
+#include "nbsearch.h"
+
+#include <cmath>
+#include <cstring>
#include <algorithm>
#include <vector>
#include "thread_mpi/mutex.h"
-#include "gromacs/legacyheaders/typedefs.h"
-#include "gromacs/legacyheaders/pbc.h"
-#include "gromacs/legacyheaders/vec.h"
-
+#include "gromacs/legacyheaders/names.h"
+#include "gromacs/math/vec.h"
+#include "gromacs/pbcutil/pbc.h"
#include "gromacs/selection/position.h"
+#include "gromacs/topology/block.h"
#include "gromacs/utility/arrayref.h"
+#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/smalloc.h"
+#include "gromacs/utility/stringutil.h"
namespace gmx
{
* Initializes the search with a given box and reference positions.
*
* \param[in] mode Search mode to use.
+ * \param[in] bXY Whether to use 2D searching.
+ * \param[in] excls Exclusions.
* \param[in] pbc PBC information.
* \param[in] positions Set of reference positions.
*/
void init(AnalysisNeighborhood::SearchMode mode,
+ bool bXY,
+ const t_blocka *excls,
const t_pbc *pbc,
const AnalysisNeighborhoodPositions &positions);
PairSearchImplPointer getPairSearch();
* \param[in] pbc Information about the box.
* \returns false if grid search is not suitable.
*/
- bool initGridCells(const t_pbc *pbc);
+ bool initGridCells(const t_pbc &pbc);
/*! \brief
* Sets ua a search grid for a given box.
*
* \param[in] pbc Information about the box.
* \returns false if grid search is not suitable.
*/
- bool initGrid(const t_pbc *pbc);
+ bool initGrid(const t_pbc &pbc);
/*! \brief
* Maps a point into a grid cell.
*
* \param[in] i Index to add.
*/
void addToGridCell(const ivec cell, int i);
+ /*! \brief
+ * Calculates the index of a neighboring grid cell.
+ *
+ * \param[in] sourceCell Location of the source cell.
+ * \param[in] index Index of the neighbor to calculate.
+ * \param[out] shift Shift to apply to get the periodic distance
+ * for distances between the cells.
+ * \returns Grid cell index of the neighboring cell.
+ */
+ int getNeighboringCell(const ivec sourceCell, int index, rvec shift) const;
//! Whether to try grid searching.
bool bTryGrid_;
real cutoff_;
//! The cutoff squared.
real cutoff2_;
+ //! Whether to do searching in XY plane only.
+ bool bXY_;
//! Number of reference points for the current frame.
int nref_;
//! Reference point positions.
const rvec *xref_;
- //! Reference position ids (NULL if not available).
- const int *refid_;
+ //! Reference position exclusion IDs.
+ const int *refExclusionIds_;
+ //! Exclusions.
+ const t_blocka *excls_;
//! PBC data.
- t_pbc *pbc_;
-
- //! Number of excluded reference positions for current test particle.
- int nexcl_;
- //! Exclusions for current test particle.
- int *excl_;
+ t_pbc pbc_;
//! Whether grid searching is actually used for the current positions.
bool bGrid_;
explicit AnalysisNeighborhoodPairSearchImpl(const AnalysisNeighborhoodSearchImpl &search)
: search_(search)
{
+ testExclusionIds_ = NULL;
+ nexcl_ = 0;
+ excl_ = NULL;
clear_rvec(xtest_);
clear_ivec(testcell_);
reset(-1);
const AnalysisNeighborhoodSearchImpl &search_;
//! Reference to the test positions.
ConstArrayRef<rvec> testPositions_;
+ //! Reference to the test exclusion indices.
+ const int *testExclusionIds_;
+ //! Number of excluded reference positions for current test particle.
+ int nexcl_;
+ //! Exclusions for current test particle.
+ const int *excl_;
//! Index of the currently active test position in \p testPositions_.
int testIndex_;
//! Stores test position during a pair loop.
rvec xtest_;
//! Stores the previous returned position during a pair loop.
int previ_;
+ //! Stores the pair distance corresponding to previ_;
+ real prevr2_;
//! Stores the current exclusion index during loops.
int exclind_;
//! Stores the test particle cell index during loops.
bTryGrid_ = false;
}
cutoff2_ = sqr(cutoff_);
+ bXY_ = false;
- nref_ = 0;
- xref_ = NULL;
- refid_ = NULL;
- pbc_ = NULL;
-
- nexcl_ = 0;
- excl_ = NULL;
+ nref_ = 0;
+ xref_ = NULL;
+ refExclusionIds_ = NULL;
+ std::memset(&pbc_, 0, sizeof(pbc_));
bGrid_ = false;
}
}
-bool AnalysisNeighborhoodSearchImpl::initGridCells(const t_pbc *pbc)
+bool AnalysisNeighborhoodSearchImpl::initGridCells(const t_pbc &pbc)
{
const real targetsize =
- pow(pbc->box[XX][XX] * pbc->box[YY][YY] * pbc->box[ZZ][ZZ]
+ pow(pbc.box[XX][XX] * pbc.box[YY][YY] * pbc.box[ZZ][ZZ]
* 10 / nref_, static_cast<real>(1./3.));
int cellCount = 1;
for (int dd = 0; dd < DIM; ++dd)
{
- ncelldim_[dd] = static_cast<int>(pbc->box[dd][dd] / targetsize);
+ ncelldim_[dd] = static_cast<int>(pbc.box[dd][dd] / targetsize);
cellCount *= ncelldim_[dd];
if (ncelldim_[dd] < 3)
{
return true;
}
-bool AnalysisNeighborhoodSearchImpl::initGrid(const t_pbc *pbc)
+bool AnalysisNeighborhoodSearchImpl::initGrid(const t_pbc &pbc)
{
/* TODO: This check could be improved. */
- if (0.5*pbc->max_cutoff2 < cutoff2_)
+ if (0.5*pbc.max_cutoff2 < cutoff2_)
{
return false;
}
return false;
}
- bTric_ = TRICLINIC(pbc->box);
+ bTric_ = TRICLINIC(pbc.box);
if (bTric_)
{
for (int dd = 0; dd < DIM; ++dd)
{
- svmul(1.0 / ncelldim_[dd], pbc->box[dd], cellbox_[dd]);
+ svmul(1.0 / ncelldim_[dd], pbc.box[dd], cellbox_[dd]);
}
m_inv_ur0(cellbox_, recipcell_);
}
{
for (int dd = 0; dd < DIM; ++dd)
{
- cellbox_[dd][dd] = pbc->box[dd][dd] / ncelldim_[dd];
+ cellbox_[dd][dd] = pbc.box[dd][dd] / ncelldim_[dd];
recipcell_[dd][dd] = 1.0 / cellbox_[dd][dd];
}
}
while (cellIndex < 0)
{
cellIndex += cellCount;
- rvec_add(xtmp, pbc_->box[dd], xtmp);
+ rvec_add(xtmp, pbc_.box[dd], xtmp);
}
while (cellIndex >= cellCount)
{
cellIndex -= cellCount;
- rvec_sub(xtmp, pbc_->box[dd], xtmp);
+ rvec_sub(xtmp, pbc_.box[dd], xtmp);
}
cell[dd] = cellIndex;
}
while (cellIndex < 0)
{
cellIndex += cellCount;
- xtmp[dd] += pbc_->box[dd][dd];
+ xtmp[dd] += pbc_.box[dd][dd];
}
while (cellIndex >= cellCount)
{
cellIndex -= cellCount;
- xtmp[dd] -= pbc_->box[dd][dd];
+ xtmp[dd] -= pbc_.box[dd][dd];
}
cell[dd] = cellIndex;
}
cells_[ci].push_back(i);
}
+int AnalysisNeighborhoodSearchImpl::getNeighboringCell(
+ const ivec sourceCell, int index, rvec shift) const
+{
+ ivec cell;
+ ivec_add(sourceCell, gnboffs_[index], cell);
+
+ // TODO: Consider unifying with the similar shifting code in
+ // mapPointToGridCell().
+ clear_rvec(shift);
+ for (int d = 0; d < DIM; ++d)
+ {
+ const int cellCount = ncelldim_[d];
+ if (cell[d] < 0)
+ {
+ cell[d] += cellCount;
+ rvec_add(shift, pbc_.box[d], shift);
+ }
+ else if (cell[d] >= cellCount)
+ {
+ cell[d] -= cellCount;
+ rvec_sub(shift, pbc_.box[d], shift);
+ }
+ }
+
+ return getGridCellIndex(cell);
+}
+
void AnalysisNeighborhoodSearchImpl::init(
AnalysisNeighborhood::SearchMode mode,
+ bool bXY,
+ const t_blocka *excls,
const t_pbc *pbc,
const AnalysisNeighborhoodPositions &positions)
{
GMX_RELEASE_ASSERT(positions.index_ == -1,
"Individual indexed positions not supported as reference");
- pbc_ = const_cast<t_pbc *>(pbc);
+ bXY_ = bXY;
+ if (bXY_ && pbc->ePBC != epbcNONE)
+ {
+ if (pbc->ePBC != epbcXY && pbc->ePBC != epbcXYZ)
+ {
+ std::string message =
+ formatString("Computations in the XY plane are not supported with PBC type '%s'",
+ EPBC(pbc->ePBC));
+ GMX_THROW(NotImplementedError(message));
+ }
+ if (std::fabs(pbc->box[ZZ][XX]) > GMX_REAL_EPS*pbc->box[ZZ][ZZ] ||
+ std::fabs(pbc->box[ZZ][YY]) > GMX_REAL_EPS*pbc->box[ZZ][ZZ])
+ {
+ GMX_THROW(NotImplementedError("Computations in the XY plane are not supported when the last box vector is not parallel to the Z axis"));
+ }
+ set_pbc(&pbc_, epbcXY, const_cast<rvec *>(pbc->box));
+ }
+ else if (pbc != NULL)
+ {
+ pbc_ = *pbc;
+ }
+ else
+ {
+ pbc_.ePBC = epbcNONE;
+ }
nref_ = positions.count_;
// TODO: Consider whether it would be possible to support grid searching in
// more cases.
if (mode == AnalysisNeighborhood::eSearchMode_Simple
- || pbc_ == NULL || pbc_->ePBC != epbcXYZ)
+ || pbc_.ePBC != epbcXYZ)
{
bGrid_ = false;
}
{
xref_ = positions.x_;
}
- // TODO: Once exclusions are supported, this may need to be initialized.
- refid_ = NULL;
-}
-
-#if 0
-/*! \brief
- * Sets the exclusions for the next neighborhood search.
- *
- * \param[in,out] d Neighborhood search data structure.
- * \param[in] nexcl Number of reference positions to exclude from next
- * search.
- * \param[in] excl Indices of reference positions to exclude.
- *
- * The set exclusions remain in effect until the next call of this function.
- */
-void
-gmx_ana_nbsearch_set_excl(gmx_ana_nbsearch_t *d, int nexcl, int excl[])
-{
-
- d->nexcl = nexcl;
- d->excl = excl;
+ excls_ = excls;
+ refExclusionIds_ = NULL;
+ if (excls != NULL)
+ {
+ // TODO: Check that the IDs are ascending, or remove the limitation.
+ refExclusionIds_ = positions.exclusionIds_;
+ GMX_RELEASE_ASSERT(refExclusionIds_ != NULL,
+ "Exclusion IDs must be set for reference positions "
+ "when exclusions are enabled");
+ }
}
-#endif
/********************************************************************
* AnalysisNeighborhoodPairSearchImpl
testIndex_ = testIndex;
if (testIndex_ >= 0 && testIndex_ < static_cast<int>(testPositions_.size()))
{
- copy_rvec(testPositions_[testIndex_], xtest_);
if (search_.bGrid_)
{
search_.mapPointToGridCell(testPositions_[testIndex], testcell_, xtest_);
{
copy_rvec(testPositions_[testIndex_], xtest_);
}
+ if (search_.excls_ != NULL)
+ {
+ const int exclIndex = testExclusionIds_[testIndex];
+ if (exclIndex < search_.excls_->nr)
+ {
+ const int startIndex = search_.excls_->index[exclIndex];
+ nexcl_ = search_.excls_->index[exclIndex + 1] - startIndex;
+ excl_ = &search_.excls_->a[startIndex];
+ }
+ else
+ {
+ nexcl_ = 0;
+ excl_ = NULL;
+ }
+ }
}
previ_ = -1;
+ prevr2_ = 0.0;
exclind_ = 0;
prevnbi_ = 0;
prevcai_ = -1;
bool AnalysisNeighborhoodPairSearchImpl::isExcluded(int j)
{
- if (exclind_ < search_.nexcl_)
+ if (exclind_ < nexcl_)
{
- if (search_.refid_)
+ const int refId = search_.refExclusionIds_[j];
+ while (exclind_ < nexcl_ && excl_[exclind_] < refId)
{
- while (exclind_ < search_.nexcl_
- && search_.excl_[exclind_] < search_.refid_[j])
- {
- ++exclind_;
- }
- if (exclind_ < search_.nexcl_
- && search_.refid_[j] == search_.excl_[exclind_])
- {
- ++exclind_;
- return true;
- }
+ ++exclind_;
}
- else
+ if (exclind_ < nexcl_ && refId == excl_[exclind_])
{
- while (search_.bGrid_ && exclind_ < search_.nexcl_
- && search_.excl_[exclind_] < j)
- {
- ++exclind_;
- }
- if (search_.excl_[exclind_] == j)
- {
- ++exclind_;
- return true;
- }
+ ++exclind_;
+ return true;
}
}
return false;
void AnalysisNeighborhoodPairSearchImpl::startSearch(
const AnalysisNeighborhoodPositions &positions)
{
+ testExclusionIds_ = positions.exclusionIds_;
+ GMX_RELEASE_ASSERT(search_.excls_ == NULL || testExclusionIds_ != NULL,
+ "Exclusion IDs must be set when exclusions are enabled");
if (positions.index_ < 0)
{
testPositions_ = constArrayRefFromArray<rvec>(positions.x_, positions.count_);
{
if (search_.bGrid_)
{
+ GMX_RELEASE_ASSERT(!search_.bXY_, "Grid-based XY searches not implemented");
+
int nbi = prevnbi_;
int cai = prevcai_ + 1;
for (; nbi < search_.ngridnb_; ++nbi)
{
- ivec cell;
-
- ivec_add(testcell_, search_.gnboffs_[nbi], cell);
- cell[XX] = (cell[XX] + search_.ncelldim_[XX]) % search_.ncelldim_[XX];
- cell[YY] = (cell[YY] + search_.ncelldim_[YY]) % search_.ncelldim_[YY];
- cell[ZZ] = (cell[ZZ] + search_.ncelldim_[ZZ]) % search_.ncelldim_[ZZ];
-
- const int ci = search_.getGridCellIndex(cell);
+ rvec shift;
+ const int ci = search_.getNeighboringCell(testcell_, nbi, shift);
const int cellSize = static_cast<int>(search_.cells_[ci].size());
- /* TODO: Calculate the required PBC shift outside the inner loop */
for (; cai < cellSize; ++cai)
{
const int i = search_.cells_[ci][cai];
continue;
}
rvec dx;
- pbc_dx_aiuc(search_.pbc_, xtest_, search_.xref_[i], dx);
+ rvec_sub(xtest_, search_.xref_[i], dx);
+ rvec_add(dx, shift, dx);
const real r2 = norm2(dx);
if (r2 <= search_.cutoff2_)
{
prevnbi_ = nbi;
prevcai_ = cai;
previ_ = i;
+ prevr2_ = r2;
return true;
}
}
continue;
}
rvec dx;
- if (search_.pbc_)
+ if (search_.pbc_.ePBC != epbcNONE)
{
- pbc_dx(search_.pbc_, xtest_, search_.xref_[i], dx);
+ pbc_dx(&search_.pbc_, xtest_, search_.xref_[i], dx);
}
else
{
rvec_sub(xtest_, search_.xref_[i], dx);
}
- const real r2 = norm2(dx);
+ const real r2
+ = search_.bXY_
+ ? dx[XX]*dx[XX] + dx[YY]*dx[YY]
+ : norm2(dx);
if (r2 <= search_.cutoff2_)
{
if (action(i, r2))
{
- previ_ = i;
+ previ_ = i;
+ prevr2_ = r2;
return true;
}
}
}
else
{
- *pair = AnalysisNeighborhoodPair(previ_, testIndex_);
+ *pair = AnalysisNeighborhoodPair(previ_, testIndex_, prevr2_);
}
}
typedef AnalysisNeighborhoodSearch::ImplPointer SearchImplPointer;
typedef std::vector<SearchImplPointer> SearchList;
- Impl() : cutoff_(0), mode_(eSearchMode_Automatic)
+ Impl() : cutoff_(0), excls_(NULL), mode_(eSearchMode_Automatic), bXY_(false)
{
}
~Impl()
tMPI::mutex createSearchMutex_;
SearchList searchList_;
real cutoff_;
+ const t_blocka *excls_;
SearchMode mode_;
+ bool bXY_;
};
AnalysisNeighborhood::Impl::SearchImplPointer
impl_->cutoff_ = cutoff;
}
+void AnalysisNeighborhood::setXYMode(bool bXY)
+{
+ impl_->bXY_ = bXY;
+}
+
+void AnalysisNeighborhood::setTopologyExclusions(const t_blocka *excls)
+{
+ GMX_RELEASE_ASSERT(impl_->searchList_.empty(),
+ "Changing the exclusions after initSearch() not currently supported");
+ impl_->excls_ = excls;
+}
+
void AnalysisNeighborhood::setMode(SearchMode mode)
{
impl_->mode_ = mode;
const AnalysisNeighborhoodPositions &positions)
{
Impl::SearchImplPointer search(impl_->getSearch());
- search->init(mode(), pbc, positions);
+ search->init(mode(), impl_->bXY_, impl_->excls_, pbc, positions);
return AnalysisNeighborhoodSearch(search);
}
int closestPoint = -1;
MindistAction action(&closestPoint, &minDist2);
(void)pairSearch.searchNext(action);
- return AnalysisNeighborhoodPair(closestPoint, 0);
+ return AnalysisNeighborhoodPair(closestPoint, 0, minDist2);
}
AnalysisNeighborhoodPairSearch